From aa5b963412d52fd3b983a84885e63ad3bdf10578 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Wed, 12 Apr 2017 20:47:37 -0300 Subject: [PATCH] view: rework active-date The current implementation is deficient in many ways, the worst one being the it relying on GObject semi-synchronous property emission. This issue was exposed by the Week view code, where the active date was updated, but delayed to reach the Week header and some events were being added ~before~ the active date changed. With this work, I was also able to figure out a bunch of code that relied on this (i.e. luck) to work. --- data/ui/week-view.ui | 2 - src/gcal-view.c | 24 ++++-- src/gcal-view.h | 5 ++ src/gcal-window.c | 148 ++++++++++++++++------------------- src/views/gcal-month-view.c | 69 +++++++++++----- src/views/gcal-week-grid.c | 55 +++---------- src/views/gcal-week-grid.h | 3 + src/views/gcal-week-header.c | 94 ++++++++-------------- src/views/gcal-week-header.h | 3 + src/views/gcal-week-view.c | 57 ++++++++++---- src/views/gcal-year-view.c | 94 +++++++++++++--------- 11 files changed, 295 insertions(+), 259 deletions(-) diff --git a/data/ui/week-view.ui b/data/ui/week-view.ui index 62d8754c..7540bcb8 100644 --- a/data/ui/week-view.ui +++ b/data/ui/week-view.ui @@ -9,7 +9,6 @@ True - @@ -37,7 +36,6 @@ True True True - diff --git a/src/gcal-view.c b/src/gcal-view.c index fae8a769..037bc052 100644 --- a/src/gcal-view.c +++ b/src/gcal-view.c @@ -75,24 +75,38 @@ gcal_view_default_init (GcalViewInterface *iface) G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER); } +/** + * gcal_view_set_date: + * @view: a #GcalView + * @date: an #icaltimetype + * + * Sets the date of @view. + */ void gcal_view_set_date (GcalView *view, icaltimetype *date) { g_return_if_fail (GCAL_IS_VIEW (view)); + g_return_if_fail (GCAL_VIEW_GET_IFACE (view)->set_date); - g_object_set (view, "active-date", date, NULL); + GCAL_VIEW_GET_IFACE (view)->set_date (view, date); } +/** + * gcal_view_get_date: + * @view: a #GcalView + * + * Retrieves the date of @view. + * + * Returns: (transfer none): an #icaltimetype. + */ icaltimetype* gcal_view_get_date (GcalView *view) { - icaltimetype *date; - g_return_val_if_fail (GCAL_IS_VIEW (view), NULL); + g_return_val_if_fail (GCAL_VIEW_GET_IFACE (view)->get_date, NULL); - g_object_get (view, "active-date", &date, NULL); - return date; + return GCAL_VIEW_GET_IFACE (view)->get_date (view); } /** diff --git a/src/gcal-view.h b/src/gcal-view.h index 8ec6e6c1..a1df2d27 100644 --- a/src/gcal-view.h +++ b/src/gcal-view.h @@ -42,6 +42,11 @@ struct _GcalViewInterface icaltimetype *start_span, icaltimetype *end_span); + icaltimetype* (*get_date) (GcalView *view); + + void (*set_date) (GcalView *view, + icaltimetype *date); + /* Marks related API */ void (*clear_marks) (GcalView *view); diff --git a/src/gcal-window.c b/src/gcal-window.c index 662d3d8e..89750c9f 100644 --- a/src/gcal-window.c +++ b/src/gcal-window.c @@ -268,7 +268,10 @@ update_active_date (GcalWindow *window, previous_date = window->active_date; window->active_date = new_date; - g_object_notify (G_OBJECT (window), "active-date"); + + gcal_view_set_date (GCAL_VIEW (window->views[GCAL_WINDOW_VIEW_WEEK]), new_date); + gcal_view_set_date (GCAL_VIEW (window->views[GCAL_WINDOW_VIEW_MONTH]), new_date); + gcal_view_set_date (GCAL_VIEW (window->views[GCAL_WINDOW_VIEW_YEAR]), new_date); /* year_view */ if (previous_date->year != new_date->year) @@ -1234,82 +1237,6 @@ schedule_open_edit_dialog_by_uuid (OpenEditDialogData *edit_dialog_data) return G_SOURCE_CONTINUE; } -static void -gcal_window_constructed (GObject *object) -{ - GcalWindow *window = GCAL_WINDOW (object); - - GtkBuilder *builder; - GMenuModel *winmenu; - - GSettings *helper_settings; - gchar *clock_format; - gboolean use_24h_format; - - GCAL_ENTRY; - - if (G_OBJECT_CLASS (gcal_window_parent_class)->constructed != NULL) - G_OBJECT_CLASS (gcal_window_parent_class)->constructed (object); - - helper_settings = g_settings_new ("org.gnome.desktop.interface"); - clock_format = g_settings_get_string (helper_settings, "clock-format"); - use_24h_format = (g_strcmp0 (clock_format, "24h") == 0); - g_free (clock_format); - g_object_unref (helper_settings); - - /* header_bar: menu */ - builder = gtk_builder_new (); - gtk_builder_add_from_resource (builder, - "/org/gnome/calendar/gtk/menus.ui", - NULL); - - winmenu = (GMenuModel *)gtk_builder_get_object (builder, "win-menu"); - gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (window->menu_button), - winmenu); - - g_object_unref (builder); - - window->views[GCAL_WINDOW_VIEW_WEEK] = window->week_view; - window->views[GCAL_WINDOW_VIEW_MONTH] = window->month_view; - window->views[GCAL_WINDOW_VIEW_YEAR] = window->year_view; - - gcal_edit_dialog_set_time_format (GCAL_EDIT_DIALOG (window->edit_dialog), use_24h_format); - - gcal_week_view_set_first_weekday (GCAL_WEEK_VIEW (window->views[GCAL_WINDOW_VIEW_WEEK]), get_first_weekday ()); - gcal_week_view_set_use_24h_format (GCAL_WEEK_VIEW (window->views[GCAL_WINDOW_VIEW_WEEK]), use_24h_format); - - gcal_month_view_set_first_weekday (GCAL_MONTH_VIEW (window->views[GCAL_WINDOW_VIEW_MONTH]), get_first_weekday ()); - gcal_month_view_set_use_24h_format (GCAL_MONTH_VIEW (window->views[GCAL_WINDOW_VIEW_MONTH]), use_24h_format); - - gcal_year_view_set_first_weekday (GCAL_YEAR_VIEW (window->views[GCAL_WINDOW_VIEW_YEAR]), get_first_weekday ()); - gcal_year_view_set_use_24h_format (GCAL_YEAR_VIEW (window->views[GCAL_WINDOW_VIEW_YEAR]), use_24h_format); - - /* search view */ - gcal_search_view_connect (GCAL_SEARCH_VIEW (window->search_view), window->manager); - gcal_search_view_set_time_format (GCAL_SEARCH_VIEW (window->search_view), use_24h_format); - - /* refresh timeout, first is fast */ - window->refresh_timeout_id = g_timeout_add (FAST_REFRESH_TIMEOUT, (GSourceFunc) refresh_sources, object); - - /* calendars popover */ - gtk_list_box_set_sort_func (GTK_LIST_BOX (window->calendar_listbox), (GtkListBoxSortFunc) calendar_listbox_sort_func, - object, NULL); - - if (!gcal_manager_get_loading (window->manager)) - { - GList *sources, *l; - - sources = gcal_manager_get_sources_connected (window->manager); - - for (l = sources; l != NULL; l = g_list_next (l)) - add_source (window->manager, l->data, is_source_enabled (l->data), object); - - g_list_free (sources); - } - - GCAL_EXIT; -} - static void gcal_window_finalize (GObject *object) { @@ -1380,6 +1307,19 @@ gcal_window_set_property (GObject *object, case PROP_MANAGER: if (g_set_object (&self->manager, g_value_get_object (value))) { + + if (!gcal_manager_get_loading (self->manager)) + { + GList *sources, *l; + + sources = gcal_manager_get_sources_connected (self->manager); + + for (l = sources; l != NULL; l = g_list_next (l)) + add_source (self->manager, l->data, is_source_enabled (l->data), self); + + g_list_free (sources); + } + g_signal_connect (self->manager, "source-added", G_CALLBACK (add_source), object); g_signal_connect (self->manager, "source-removed", G_CALLBACK (remove_source), object); g_signal_connect_swapped (self->manager, "source-enabled", G_CALLBACK (source_enabled), object); @@ -1487,7 +1427,6 @@ gcal_window_class_init(GcalWindowClass *klass) GtkWidgetClass *widget_class; object_class = G_OBJECT_CLASS (klass); - object_class->constructed = gcal_window_constructed; object_class->finalize = gcal_window_finalize; object_class->set_property = gcal_window_set_property; object_class->get_property = gcal_window_get_property; @@ -1523,7 +1462,6 @@ gcal_window_class_init(GcalWindowClass *klass) "Date", "The active/selected date", ICAL_TIME_TYPE, - G_PARAM_CONSTRUCT | G_PARAM_READWRITE)); g_object_class_install_property ( @@ -1597,6 +1535,12 @@ gcal_window_class_init(GcalWindowClass *klass) static void gcal_window_init (GcalWindow *self) { + GtkBuilder *builder; + GMenuModel *winmenu; + GSettings *helper_settings; + gchar *clock_format; + gboolean use_24h_format; + /* Setup actions */ g_action_map_add_action_entries (G_ACTION_MAP (self), actions, @@ -1609,6 +1553,52 @@ gcal_window_init (GcalWindow *self) g_object_bind_property (self, "application", self->source_dialog, "application", G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE); + helper_settings = g_settings_new ("org.gnome.desktop.interface"); + clock_format = g_settings_get_string (helper_settings, "clock-format"); + use_24h_format = (g_strcmp0 (clock_format, "24h") == 0); + g_free (clock_format); + g_object_unref (helper_settings); + + /* header_bar: menu */ + builder = gtk_builder_new (); + gtk_builder_add_from_resource (builder, + "/org/gnome/calendar/gtk/menus.ui", + NULL); + + winmenu = (GMenuModel *)gtk_builder_get_object (builder, "win-menu"); + gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (self->menu_button), + winmenu); + + g_object_unref (builder); + + self->views[GCAL_WINDOW_VIEW_WEEK] = self->week_view; + self->views[GCAL_WINDOW_VIEW_MONTH] = self->month_view; + self->views[GCAL_WINDOW_VIEW_YEAR] = self->year_view; + + gcal_edit_dialog_set_time_format (GCAL_EDIT_DIALOG (self->edit_dialog), use_24h_format); + + gcal_week_view_set_first_weekday (GCAL_WEEK_VIEW (self->views[GCAL_WINDOW_VIEW_WEEK]), get_first_weekday ()); + gcal_week_view_set_use_24h_format (GCAL_WEEK_VIEW (self->views[GCAL_WINDOW_VIEW_WEEK]), use_24h_format); + + gcal_month_view_set_first_weekday (GCAL_MONTH_VIEW (self->views[GCAL_WINDOW_VIEW_MONTH]), get_first_weekday ()); + gcal_month_view_set_use_24h_format (GCAL_MONTH_VIEW (self->views[GCAL_WINDOW_VIEW_MONTH]), use_24h_format); + + gcal_year_view_set_first_weekday (GCAL_YEAR_VIEW (self->views[GCAL_WINDOW_VIEW_YEAR]), get_first_weekday ()); + gcal_year_view_set_use_24h_format (GCAL_YEAR_VIEW (self->views[GCAL_WINDOW_VIEW_YEAR]), use_24h_format); + + /* search view */ + gcal_search_view_connect (GCAL_SEARCH_VIEW (self->search_view), self->manager); + gcal_search_view_set_time_format (GCAL_SEARCH_VIEW (self->search_view), use_24h_format); + + /* refresh timeout, first is fast */ + self->refresh_timeout_id = g_timeout_add (FAST_REFRESH_TIMEOUT, (GSourceFunc) refresh_sources, self); + + /* calendars popover */ + gtk_list_box_set_sort_func (GTK_LIST_BOX (self->calendar_listbox), + (GtkListBoxSortFunc) calendar_listbox_sort_func, + self, + NULL); + self->active_date = g_new0 (icaltimetype, 1); self->rtl = gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_RTL; } diff --git a/src/views/gcal-month-view.c b/src/views/gcal-month-view.c index 82841a0d..5758ad50 100644 --- a/src/views/gcal-month-view.c +++ b/src/views/gcal-month-view.c @@ -24,6 +24,7 @@ #define G_LOG_DOMAIN "GcalMonthView" +#include "gcal-debug.h" #include "gcal-month-view.h" #include "gcal-subscriber-view-private.h" #include "gcal-utils.h" @@ -914,6 +915,42 @@ add_new_event_button_cb (GtkWidget *button, } /* GcalView Interface API */ +static icaltimetype* +gcal_month_view_get_date (GcalView *view) +{ + GcalMonthView *self = GCAL_MONTH_VIEW (view); + + return self->date; +} + +static void +gcal_month_view_set_date (GcalView *view, + icaltimetype *date) +{ + GcalSubscriberViewPrivate *ppriv; + GcalMonthView *self; + + GCAL_ENTRY; + + self = GCAL_MONTH_VIEW (view); + ppriv = GCAL_SUBSCRIBER_VIEW (view)->priv; + + g_clear_pointer (&self->date, g_free); + + self->date = gcal_dup_icaltime (date); + self->days_delay = (time_day_of_week (1, self->date->month - 1, self->date->year) - self->first_weekday + 7) % 7; + self->keyboard_cell = self->days_delay + (self->date->day - 1); + + GCAL_TRACE_MSG ("new date: %s", icaltime_as_ical_string (*date)); + + cancel_selection (self); + + ppriv->children_changed = TRUE; + gtk_widget_queue_resize (GTK_WIDGET (view)); + + GCAL_EXIT; +} + static void gcal_month_view_clear_marks (GcalView *view) { @@ -939,6 +976,8 @@ gcal_month_view_get_children_by_uuid (GcalView *view, static void gcal_view_interface_init (GcalViewInterface *iface) { + iface->get_date = gcal_month_view_get_date; + iface->set_date = gcal_month_view_set_date; iface->clear_marks = gcal_month_view_clear_marks; iface->get_children_by_uuid = gcal_month_view_get_children_by_uuid; } @@ -949,29 +988,12 @@ gcal_month_view_set_property (GObject *object, const GValue *value, GParamSpec *pspec) { - GcalSubscriberViewPrivate *ppriv; - GcalMonthView *self; - - ppriv = GCAL_SUBSCRIBER_VIEW (object)->priv; - self = GCAL_MONTH_VIEW (object); - switch (property_id) { case PROP_DATE: - { - if (self->date != NULL) - g_free (self->date); + gcal_view_set_date (GCAL_VIEW (object), g_value_get_boxed (value)); + break; - self->date = g_value_dup_boxed (value); - self->days_delay = (time_day_of_week (1, self->date->month - 1, self->date->year) - self->first_weekday + 7) % 7; - self->keyboard_cell = self->days_delay + (self->date->day - 1); - - cancel_selection (GCAL_MONTH_VIEW (object)); - - ppriv->children_changed = TRUE; - gtk_widget_queue_resize (GTK_WIDGET (object)); - break; - } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -2063,15 +2085,22 @@ gcal_month_view_button_release (GtkWidget *widget, if (current_day >= self->days_delay && current_day < days) { + gboolean valid; + g_clear_pointer (&self->end_mark_cell, g_date_time_unref); self->keyboard_cell = current_day; self->end_mark_cell = g_date_time_new_local (self->date->year, self->date->month, current_day - self->days_delay + 1, 0, 0, 0); self->date->day = g_date_time_get_day_of_month (self->end_mark_cell); + + /* First, make sure to show the popover */ + valid = show_popover_for_position (GCAL_MONTH_VIEW (widget), x, y, released_indicator); + + /* Then update the active date */ g_object_notify (G_OBJECT (self), "active-date"); - return show_popover_for_position (GCAL_MONTH_VIEW (widget), x, y, released_indicator); + return valid; } else { diff --git a/src/views/gcal-week-grid.c b/src/views/gcal-week-grid.c index 59ec049f..004ad1f0 100644 --- a/src/views/gcal-week-grid.c +++ b/src/views/gcal-week-grid.c @@ -74,12 +74,6 @@ struct _GcalWeekGrid G_DEFINE_TYPE (GcalWeekGrid, gcal_week_grid, GTK_TYPE_CONTAINER); -enum -{ - PROP_0, - PROP_ACTIVE_DATE, - LAST_PROP -}; enum { @@ -88,7 +82,6 @@ enum }; static guint signals[LAST_SIGNAL] = { 0, }; -static GParamSpec* properties[LAST_PROP] = { NULL, }; /* ChildData methods */ static ChildData* @@ -311,17 +304,7 @@ gcal_week_grid_get_property (GObject *object, GValue *value, GParamSpec *pspec) { - GcalWeekGrid *self = GCAL_WEEK_GRID (object); - - switch (prop_id) - { - case PROP_ACTIVE_DATE: - g_value_set_boxed (value, self->active_date); - return; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } static void @@ -330,21 +313,7 @@ gcal_week_grid_set_property (GObject *object, const GValue *value, GParamSpec *pspec) { - GcalWeekGrid *self = GCAL_WEEK_GRID (object); - - switch (prop_id) - { - case PROP_ACTIVE_DATE: - g_clear_pointer (&self->active_date, g_free); - self->active_date = g_value_dup_boxed (value); - - gtk_widget_queue_resize (GTK_WIDGET (self)); - gtk_widget_queue_draw (GTK_WIDGET (self)); - return; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } static void @@ -1115,13 +1084,6 @@ gcal_week_grid_class_init (GcalWeekGridClass *klass) widget_class->drag_leave = gcal_week_grid_drag_leave; widget_class->drag_drop = gcal_week_grid_drag_drop; - properties[PROP_ACTIVE_DATE] = g_param_spec_boxed ("active-date", - "Date", - "The active selected date", - ICAL_TIME_TYPE, - G_PARAM_CONSTRUCT | G_PARAM_READWRITE); - - signals[EVENT_ACTIVATED] = g_signal_new ("event-activated", GCAL_TYPE_WEEK_GRID, G_SIGNAL_RUN_FIRST, @@ -1130,8 +1092,6 @@ gcal_week_grid_class_init (GcalWeekGridClass *klass) 1, GCAL_TYPE_EVENT_WIDGET); - g_object_class_install_properties (object_class, G_N_ELEMENTS (properties), properties); - gtk_widget_class_set_css_name (widget_class, "weekgrid"); } @@ -1290,3 +1250,14 @@ gcal_week_grid_clear_marks (GcalWeekGrid *self) gtk_widget_queue_draw (GTK_WIDGET (self)); } + +void +gcal_week_grid_set_date (GcalWeekGrid *self, + icaltimetype *date) +{ + g_clear_pointer (&self->active_date, g_free); + self->active_date = gcal_dup_icaltime (date); + + gtk_widget_queue_resize (GTK_WIDGET (self)); + gtk_widget_queue_draw (GTK_WIDGET (self)); +} diff --git a/src/views/gcal-week-grid.h b/src/views/gcal-week-grid.h index 99925082..2d519b32 100644 --- a/src/views/gcal-week-grid.h +++ b/src/views/gcal-week-grid.h @@ -51,6 +51,9 @@ GList* gcal_week_grid_get_children_by_uuid (GcalWeekGrid void gcal_week_grid_clear_marks (GcalWeekGrid *self); +void gcal_week_grid_set_date (GcalWeekGrid *self, + icaltimetype *date); + G_END_DECLS #endif /* GCAL_WEEK_GRID_H */ diff --git a/src/views/gcal-week-header.c b/src/views/gcal-week-header.c index 23e0a4f7..6cbcc731 100644 --- a/src/views/gcal-week-header.c +++ b/src/views/gcal-week-header.c @@ -84,12 +84,6 @@ typedef enum DOWN } MoveDirection; -enum -{ - PROP_0, - PROP_ACTIVE_DATE -}; - enum { EVENT_ACTIVATED, @@ -1060,17 +1054,7 @@ gcal_week_header_get_property (GObject *object, GValue *value, GParamSpec *pspec) { - GcalWeekHeader *self = GCAL_WEEK_HEADER (object); - - switch (prop_id) - { - case PROP_ACTIVE_DATE: - g_value_set_boxed (value, self->active_date); - return; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } static void @@ -1079,41 +1063,7 @@ gcal_week_header_set_property (GObject *object, const GValue *value, GParamSpec *pspec) { - GcalWeekHeader *self = GCAL_WEEK_HEADER (object); - icaltimetype *old_date, *new_date; - - switch (prop_id) - { - case PROP_ACTIVE_DATE: - old_date = self->active_date; - new_date = g_value_dup_boxed (value); - - /* - * If the active date changed, but we're still in the same week, - * there's no need to recalculate visible events. - */ - if (old_date && new_date && - old_date->year == new_date->year && - icaltime_week_number (*old_date) == icaltime_week_number (*new_date)) - { - g_free (new_date); - break; - } - - self->active_date = new_date; - - update_title (self); - gtk_widget_queue_draw (GTK_WIDGET (self)); - - if (old_date) - update_unchanged_events (self, self->active_date); - - g_clear_pointer (&old_date, g_free); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } static void @@ -1514,14 +1464,6 @@ gcal_week_header_class_init (GcalWeekHeaderClass *kclass) widget_class->drag_leave = gcal_week_header_drag_leave; widget_class->drag_drop = gcal_week_header_drag_drop; - g_object_class_install_property (object_class, - PROP_ACTIVE_DATE, - g_param_spec_boxed ("active-date", - "Date", - "The active selected date", - ICAL_TIME_TYPE, - G_PARAM_CONSTRUCT | G_PARAM_READWRITE)); - signals[EVENT_ACTIVATED] = g_signal_new ("event-activated", GCAL_TYPE_WEEK_HEADER, G_SIGNAL_RUN_FIRST, @@ -1787,3 +1729,35 @@ gcal_week_header_clear_marks (GcalWeekHeader *self) gtk_widget_queue_draw (GTK_WIDGET (self)); } + +void +gcal_week_header_set_date (GcalWeekHeader *self, + icaltimetype *date) +{ + icaltimetype *old_date, *new_date; + + old_date = self->active_date; + new_date = gcal_dup_icaltime (date); + + /* + * If the active date changed, but we're still in the same week, + * there's no need to recalculate visible events. + */ + if (old_date && new_date && + old_date->year == new_date->year && + icaltime_week_number (*old_date) == icaltime_week_number (*new_date)) + { + g_free (new_date); + return; + } + + self->active_date = new_date; + + update_title (self); + gtk_widget_queue_draw (GTK_WIDGET (self)); + + if (old_date) + update_unchanged_events (self, self->active_date); + + g_clear_pointer (&old_date, g_free); +} diff --git a/src/views/gcal-week-header.h b/src/views/gcal-week-header.h index fa866dc0..8c9d9046 100644 --- a/src/views/gcal-week-header.h +++ b/src/views/gcal-week-header.h @@ -53,6 +53,9 @@ GtkSizeGroup* gcal_week_header_get_sidebar_size_group (GcalWeekHeader void gcal_week_header_clear_marks (GcalWeekHeader *self); +void gcal_week_header_set_date (GcalWeekHeader *self, + icaltimetype *date); + G_END_DECLS #endif /* GCAL_WEEK_HEADER_H */ diff --git a/src/views/gcal-week-view.c b/src/views/gcal-week-view.c index b115919e..8d7fcb4c 100644 --- a/src/views/gcal-week-view.c +++ b/src/views/gcal-week-view.c @@ -162,6 +162,35 @@ schedule_position_scroll (GcalWeekView *self) self); } +/* GcalView implementation */ +static icaltimetype* +gcal_week_view_get_date (GcalView *view) +{ + GcalWeekView *self = GCAL_WEEK_VIEW (view); + + return self->date; +} + +static void +gcal_week_view_set_date (GcalView *view, + icaltimetype *date) +{ + GcalWeekView *self = GCAL_WEEK_VIEW (view); + + GCAL_ENTRY; + + g_clear_pointer (&self->date, g_free); + self->date = gcal_dup_icaltime (date); + + /* Propagate the new date */ + gcal_week_grid_set_date (GCAL_WEEK_GRID (self->week_grid), date); + gcal_week_header_set_date (GCAL_WEEK_HEADER (self->header), date); + + schedule_position_scroll (self); + + GCAL_EXIT; +} + static GList* gcal_week_view_get_children_by_uuid (GcalView *view, const gchar *uuid) @@ -185,6 +214,15 @@ gcal_week_view_clear_marks (GcalView *view) gcal_week_grid_clear_marks (GCAL_WEEK_GRID (self->week_grid)); } +static void +gcal_view_interface_init (GcalViewInterface *iface) +{ + iface->get_date = gcal_week_view_get_date; + iface->set_date = gcal_week_view_set_date; + iface->get_children_by_uuid = gcal_week_view_get_children_by_uuid; + iface->clear_marks = gcal_week_view_clear_marks; +} + static void update_hours_sidebar_size (GcalWeekView *self) { @@ -239,6 +277,8 @@ update_hours_sidebar_size (GcalWeekView *self) g_object_unref (layout); } + +/* ECalDataModelSubscriber implementation */ static void gcal_week_view_component_added (ECalDataModelSubscriber *subscriber, ECalClient *client, @@ -429,13 +469,6 @@ gcal_week_view_draw_hours (GcalWeekView *self, return FALSE; } -static void -gcal_view_interface_init (GcalViewInterface *iface) -{ - iface->get_children_by_uuid = gcal_week_view_get_children_by_uuid; - iface->clear_marks = gcal_week_view_clear_marks; -} - static void gcal_data_model_subscriber_interface_init (ECalDataModelSubscriberInterface *iface) { @@ -465,18 +498,10 @@ gcal_week_view_set_property (GObject *object, const GValue *value, GParamSpec *pspec) { - GcalWeekView *self; - - self = GCAL_WEEK_VIEW (object); - switch (property_id) { case PROP_DATE: - g_clear_pointer (&self->date, g_free); - self->date = g_value_dup_boxed (value); - - schedule_position_scroll (self); - + gcal_view_set_date (GCAL_VIEW (object), g_value_get_boxed (value)); break; default: diff --git a/src/views/gcal-year-view.c b/src/views/gcal-year-view.c index de5a2f33..68c6db33 100644 --- a/src/views/gcal-year-view.c +++ b/src/views/gcal-year-view.c @@ -19,6 +19,7 @@ #define G_LOG_DOMAIN "GcalYearView" +#include "gcal-debug.h" #include "gcal-year-view.h" #include "gcal-view.h" #include "gcal-utils.h" @@ -553,7 +554,7 @@ update_date (GcalYearView *year_view, needs_reset = TRUE; g_clear_pointer (&year_view->date, g_free); - year_view->date = new_date; + year_view->date = gcal_dup_icaltime (new_date); year_view->first_week_of_year = get_last_week_of_year_dmy (year_view->first_weekday, 1, G_DATE_JANUARY, year_view->date->year);; @@ -1541,6 +1542,62 @@ navigator_drag_leave_cb (GcalYearView *self, gtk_widget_queue_draw (navigator); } +/* GcalView implementation */ +static icaltimetype* +gcal_year_view_get_date (GcalView *view) +{ + GcalYearView *self = GCAL_YEAR_VIEW (view); + + return self->date; +} + +static void +gcal_year_view_set_date (GcalView *view, + icaltimetype *date) +{ + GCAL_ENTRY; + + update_date (GCAL_YEAR_VIEW (view), date); + + GCAL_EXIT; +} + +static GList* +gcal_year_view_get_children_by_uuid (GcalView *view, + const gchar *uuid) +{ + GcalYearView *year_view = GCAL_YEAR_VIEW (view); + GList *children, *l, *result = NULL; + + children = gtk_container_get_children (GTK_CONTAINER (year_view->events_sidebar)); + + for (l = children; l != NULL; l = g_list_next (l)) + { + GcalEventWidget *child_widget; + GcalEvent *event; + + child_widget = GCAL_EVENT_WIDGET (gtk_bin_get_child (GTK_BIN (l->data))); + event = gcal_event_widget_get_event (child_widget); + + + if (child_widget != NULL && g_strcmp0 (uuid, gcal_event_get_uid (event)) == 0) + result = g_list_append (result, child_widget); + } + + g_list_free (children); + + return result; +} + +static void +gcal_view_interface_init (GcalViewInterface *iface) +{ + /* FIXME: implement what's needed */ + iface->get_date = gcal_year_view_get_date; + iface->set_date = gcal_year_view_set_date; + iface->get_children_by_uuid = gcal_year_view_get_children_by_uuid; +} + static void gcal_year_view_finalize (GObject *object) { @@ -1597,7 +1654,7 @@ gcal_year_view_set_property (GObject *object, switch (prop_id) { case PROP_DATE: - update_date (self, g_value_dup_boxed (value)); + gcal_view_set_date (GCAL_VIEW (self), g_value_get_boxed (value)); break; case PROP_SHOW_WEEK_NUMBERS: @@ -1716,31 +1773,6 @@ gcal_year_view_direction_changed (GtkWidget *widget, year_view->k = 1; } -static GList* -gcal_year_view_get_children_by_uuid (GcalView *view, - const gchar *uuid) -{ - GcalYearView *year_view = GCAL_YEAR_VIEW (view); - GList *children, *l, *result = NULL; - - children = gtk_container_get_children (GTK_CONTAINER (year_view->events_sidebar)); - for (l = children; l != NULL; l = g_list_next (l)) - { - GcalEventWidget *child_widget; - GcalEvent *event; - - child_widget = GCAL_EVENT_WIDGET (gtk_bin_get_child (GTK_BIN (l->data))); - event = gcal_event_widget_get_event (child_widget); - - - if (child_widget != NULL && g_strcmp0 (uuid, gcal_event_get_uid (event)) == 0) - result = g_list_append (result, child_widget); - } - g_list_free (children); - - return result; -} - static void gcal_year_view_component_added (ECalDataModelSubscriber *subscriber, ECalClient *client, @@ -1780,7 +1812,6 @@ gcal_year_view_component_added (ECalDataModelSubscriber *subscriber, for (i = start_month; i <= end_month; i++) g_ptr_array_add (self->events[i], event); - update_selected_dates_from_button_data (self); update_sidebar (self); gtk_widget_queue_draw (GTK_WIDGET (self->navigator)); @@ -1985,13 +2016,6 @@ gcal_year_view_init (GcalYearView *self) GDK_ACTION_MOVE); } -static void -gcal_view_interface_init (GcalViewInterface *iface) -{ - /* FIXME: implement what's needed */ - iface->get_children_by_uuid = gcal_year_view_get_children_by_uuid; -} - static void gcal_data_model_subscriber_interface_init (ECalDataModelSubscriberInterface *iface) {