diff --git a/data/ui/week-view.ui b/data/ui/week-view.ui index 561e2ec1..f88ab8c1 100644 --- a/data/ui/week-view.ui +++ b/data/ui/week-view.ui @@ -10,6 +10,7 @@ True + @@ -37,6 +38,7 @@ True True + diff --git a/data/ui/window.ui b/data/ui/window.ui index ff2d9937..b6a89dd7 100644 --- a/data/ui/window.ui +++ b/data/ui/window.ui @@ -56,6 +56,7 @@ True + week diff --git a/src/views/gcal-week-grid.c b/src/views/gcal-week-grid.c index 0c39ea42..97bd3ff0 100644 --- a/src/views/gcal-week-grid.c +++ b/src/views/gcal-week-grid.c @@ -75,6 +75,13 @@ enum LAST_PROP }; +enum +{ + EVENT_ACTIVATED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0, }; static GParamSpec* properties[LAST_PROP] = { NULL, }; /* ChildData methods */ @@ -93,6 +100,30 @@ child_data_new (GtkWidget *widget, return data; } +/* Event activation methods */ +static void +on_event_widget_activated (GcalEventWidget *widget, + GcalWeekGrid *self) +{ + g_signal_emit (self, signals[EVENT_ACTIVATED], 0, widget); +} + + +static inline void +setup_event_widget (GcalWeekGrid *self, + GtkWidget *widget) +{ + g_signal_connect (widget, "activate", G_CALLBACK (on_event_widget_activated), self); +} + +static inline void +destroy_event_widget (GcalWeekGrid *self, + GtkWidget *widget) +{ + g_signal_handlers_disconnect_by_func (widget, on_event_widget_activated, self); + gtk_widget_destroy (widget); +} + /* Auxiliary methods */ static GDateTime* get_start_of_week (icaltimetype *date) @@ -624,6 +655,15 @@ gcal_week_grid_class_init (GcalWeekGridClass *klass) 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, + 0, NULL, NULL, NULL, + G_TYPE_NONE, + 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"); @@ -699,6 +739,7 @@ gcal_week_grid_add_event (GcalWeekGrid *self, end, child_data_new (widget, start, end)); + setup_event_widget (self, widget); gtk_widget_show (widget); gtk_container_add (GTK_CONTAINER (self), widget); @@ -733,9 +774,38 @@ gcal_week_grid_remove_event (GcalWeekGrid *self, get_event_range (self, event, &event_start, &event_end); gcal_range_tree_remove_range (self->events, data->start, data->end, data); - gtk_widget_destroy (data->widget); + destroy_event_widget (self, data->widget); g_free (data); } g_clear_pointer (&widgets, g_ptr_array_unref); } + +GList* +gcal_week_grid_get_children_by_uuid (GcalWeekGrid *self, + const gchar *uid) +{ + GPtrArray *widgets; + GList *result; + guint i; + + result = NULL; + widgets = gcal_range_tree_get_data_at_range (self->events, 0, MAX_MINUTES); + + for (i = 0; widgets && i < widgets->len; i++) + { + ChildData *data; + GcalEvent *event; + + data = g_ptr_array_index (widgets, i); + event = gcal_event_widget_get_event (GCAL_EVENT_WIDGET (data->widget)); + + if (g_strcmp0 (gcal_event_get_uid (event), uid) == 0) + result = g_list_prepend (result, data->widget); + + } + + g_clear_pointer (&widgets, g_ptr_array_unref); + + return result; +} diff --git a/src/views/gcal-week-grid.h b/src/views/gcal-week-grid.h index 65738eae..34eaa327 100644 --- a/src/views/gcal-week-grid.h +++ b/src/views/gcal-week-grid.h @@ -49,6 +49,9 @@ void gcal_week_grid_add_event (GcalWeekGrid void gcal_week_grid_remove_event (GcalWeekGrid *self, const gchar *uid); +GList* gcal_week_grid_get_children_by_uuid (GcalWeekGrid *self, + const gchar *uid); + 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 8bf5c094..ed7bf826 100644 --- a/src/views/gcal-week-header.c +++ b/src/views/gcal-week-header.c @@ -94,20 +94,52 @@ static void gcal_week_header_set_property (GObject *objec static void gcal_week_header_size_allocate (GtkWidget *widget, GtkAllocation *alloc); -enum -{ - PROP_0, - PROP_ACTIVE_DATE -}; - typedef enum { UP, DOWN } MoveDirection; +enum +{ + PROP_0, + PROP_ACTIVE_DATE +}; + +enum +{ + EVENT_ACTIVATED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0, }; + G_DEFINE_TYPE (GcalWeekHeader, gcal_week_header, GTK_TYPE_GRID); +/* Event activation methods */ +static void +on_event_widget_activated (GcalEventWidget *widget, + GcalWeekHeader *self) +{ + g_signal_emit (self, signals[EVENT_ACTIVATED], 0, widget); +} + + +static inline void +setup_event_widget (GcalWeekHeader *self, + GtkWidget *widget) +{ + g_signal_connect (widget, "activate", G_CALLBACK (on_event_widget_activated), self); +} + +static inline void +destroy_event_widget (GcalWeekHeader *self, + GtkWidget *widget) +{ + g_signal_handlers_disconnect_by_func (widget, on_event_widget_activated, self); + gtk_widget_destroy (widget); +} + /* Auxiliary methods */ static GcalEvent* get_event_by_uuid (GcalWeekHeader *self, @@ -307,7 +339,7 @@ merge_events (GcalWeekHeader *self, "width", ¤t_width, NULL); - gtk_widget_destroy (to_be_removed); + destroy_event_widget (self, to_be_removed); /* Update the event's size */ gtk_container_child_set (GTK_CONTAINER (self->grid), @@ -438,6 +470,8 @@ split_event_widget_at_column (GcalWeekHeader *self, widget_before = gcal_event_widget_clone (GCAL_EVENT_WIDGET (widget)); gcal_event_widget_set_date_end (GCAL_EVENT_WIDGET (widget_before), column_date); + setup_event_widget (self, widget_before); + gtk_grid_attach (GTK_GRID (self->grid), widget_before, left_attach, @@ -474,6 +508,8 @@ split_event_widget_at_column (GcalWeekHeader *self, gcal_event_widget_set_date_start (GCAL_EVENT_WIDGET (widget_after), end_column_date); gcal_event_widget_set_date_end (GCAL_EVENT_WIDGET (widget_after), event_end); + setup_event_widget (self, widget_after); + gtk_grid_attach (GTK_GRID (self->grid), widget_after, column + 1, @@ -580,6 +616,7 @@ add_event_to_grid (GcalWeekHeader *self, /* Add the event to the grid */ widget = gcal_event_widget_new (event); + setup_event_widget (self, widget); gtk_grid_attach (GTK_GRID (self->grid), widget, @@ -638,6 +675,7 @@ add_event_to_grid (GcalWeekHeader *self, cloned_widget_start_dt = g_date_time_add_days (week_start, i); cloned_widget = gcal_event_widget_clone (GCAL_EVENT_WIDGET (widget)); + setup_event_widget (self, cloned_widget); gtk_grid_attach (GTK_GRID (self->grid), cloned_widget, @@ -1170,6 +1208,14 @@ gcal_week_header_class_init (GcalWeekHeaderClass *kclass) 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, + 0, NULL, NULL, NULL, + G_TYPE_NONE, + 1, + GCAL_TYPE_EVENT_WIDGET); + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/calendar/week-header.ui"); gtk_widget_class_bind_template_child (widget_class, GcalWeekHeader, expand_button); @@ -1304,7 +1350,7 @@ gcal_week_header_remove_event (GcalWeekHeader *self, event = gcal_event_widget_get_event (child_widget); if (g_strcmp0 (uuid, gcal_event_get_uid (event)) == 0) - gtk_widget_destroy (l->data); + destroy_event_widget (self, l->data); } /* Remove from the weekday's GList */ @@ -1336,6 +1382,35 @@ gcal_week_header_remove_event (GcalWeekHeader *self, g_clear_pointer (&children, g_list_free); } +GList* +gcal_week_header_get_children_by_uuid (GcalWeekHeader *self, + const gchar *uuid) +{ + GList *children, *l, *result; + + result = NULL; + children = gtk_container_get_children (GTK_CONTAINER (self->grid)); + + for (l = children; l != NULL; l = l->next) + { + GcalEventWidget *child_widget; + GcalEvent *event; + + if (!GCAL_IS_EVENT_WIDGET (l->data)) + continue; + + child_widget = GCAL_EVENT_WIDGET (l->data); + event = gcal_event_widget_get_event (child_widget); + + if (g_strcmp0 (uuid, gcal_event_get_uid (event)) == 0) + result = g_list_prepend (result, l->data); + } + + g_list_free (children); + + return result; +} + void gcal_week_header_set_current_date (GcalWeekHeader *self, icaltimetype *current_date) diff --git a/src/views/gcal-week-header.h b/src/views/gcal-week-header.h index 732d1121..f11d3c01 100644 --- a/src/views/gcal-week-header.h +++ b/src/views/gcal-week-header.h @@ -49,6 +49,9 @@ void gcal_week_header_add_event (GcalWeekHeader void gcal_week_header_remove_event (GcalWeekHeader *self, const gchar *uuid); +GList* gcal_week_header_get_children_by_uuid (GcalWeekHeader *self, + const gchar *uuid); + GtkSizeGroup* gcal_week_header_get_sidebar_size_group (GcalWeekHeader *self); G_END_DECLS diff --git a/src/views/gcal-week-view.c b/src/views/gcal-week-view.c index 19fc1dcd..d04299ca 100644 --- a/src/views/gcal-week-view.c +++ b/src/views/gcal-week-view.c @@ -109,11 +109,27 @@ static void gcal_week_view_get_property (GObject static icaltimetype* gcal_week_view_get_final_date (GcalView *view); +enum +{ + EVENT_ACTIVATED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0, }; + G_DEFINE_TYPE_WITH_CODE (GcalWeekView, gcal_week_view, GTK_TYPE_BOX, G_IMPLEMENT_INTERFACE (GCAL_TYPE_VIEW, gcal_view_interface_init) G_IMPLEMENT_INTERFACE (E_TYPE_CAL_DATA_MODEL_SUBSCRIBER, gcal_data_model_subscriber_interface_init)); +/* Callbacks */ +static void +on_event_activated (GcalWeekView *self, + GtkWidget *widget) +{ + g_signal_emit (self, signals[EVENT_ACTIVATED], 0, widget); +} + /** * gcal_week_view_get_initial_date: * @@ -168,6 +184,20 @@ gcal_week_view_get_final_date (GcalView *view) return new_date; } +static GList* +gcal_week_view_get_children_by_uuid (GcalView *view, + const gchar *uuid) +{ + GcalWeekView *self; + GList *grid, *header; + + self = GCAL_WEEK_VIEW (view); + grid = gcal_week_grid_get_children_by_uuid (GCAL_WEEK_GRID (self->week_grid), uuid); + header = gcal_week_header_get_children_by_uuid (GCAL_WEEK_HEADER (self->header), uuid); + + return g_list_concat (grid, header); +} + static void update_hours_sidebar_size (GcalWeekView *self) { @@ -391,6 +421,14 @@ gcal_week_view_class_init (GcalWeekViewClass *klass) g_object_class_override_property (object_class, PROP_DATE, "active-date"); + signals[EVENT_ACTIVATED] = g_signal_new ("event-activated", + GCAL_TYPE_WEEK_VIEW, + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, + 1, + GCAL_TYPE_EVENT_WIDGET); + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/calendar/week-view.ui"); gtk_widget_class_bind_template_child (widget_class, GcalWeekView, header); @@ -398,6 +436,7 @@ gcal_week_view_class_init (GcalWeekViewClass *klass) gtk_widget_class_bind_template_child (widget_class, GcalWeekView, week_grid); gtk_widget_class_bind_template_callback (widget_class, gcal_week_view_draw_hours); + gtk_widget_class_bind_template_callback (widget_class, on_event_activated); gtk_widget_class_set_css_name (widget_class, "calendar-view"); } @@ -415,6 +454,7 @@ gcal_view_interface_init (GcalViewInterface *iface) { iface->get_initial_date = gcal_week_view_get_initial_date; iface->get_final_date = gcal_week_view_get_final_date; + iface->get_children_by_uuid = gcal_week_view_get_children_by_uuid; /* iface->clear_marks = gcal_week_view_clear_marks; */ } @@ -455,11 +495,9 @@ gcal_week_view_set_property (GObject *object, switch (property_id) { case PROP_DATE: - { - g_clear_pointer (&self->date, g_free); - self->date = g_value_dup_boxed (value); - break; - } + g_clear_pointer (&self->date, g_free); + self->date = g_value_dup_boxed (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);