views: Implement GcalTimelineSubscriber

This commit is contained in:
Georges Basile Stavracas Neto
2020-04-01 21:06:51 -03:00
parent 6bcf1a3705
commit 9787f02e5b
3 changed files with 381 additions and 15 deletions
+129 -9
View File
@@ -28,6 +28,7 @@
#include "gcal-month-cell.h"
#include "gcal-month-popover.h"
#include "gcal-month-view.h"
#include "gcal-timeline-subscriber.h"
#include "gcal-utils.h"
#include "gcal-view.h"
@@ -143,13 +144,17 @@ static void on_month_cell_show_overflow_popover_cb (GcalMonthCell
GtkWidget *button,
GcalMonthView *self);
static void gcal_timeline_subscriber_interface_init (GcalTimelineSubscriberInterface *iface);
G_DEFINE_TYPE_WITH_CODE (GcalMonthView, gcal_month_view, GTK_TYPE_CONTAINER,
G_IMPLEMENT_INTERFACE (GCAL_TYPE_VIEW, gcal_view_interface_init)
G_IMPLEMENT_INTERFACE (E_TYPE_CAL_DATA_MODEL_SUBSCRIBER,
e_data_model_subscriber_interface_init)
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
gtk_buildable_interface_init));
gtk_buildable_interface_init)
G_IMPLEMENT_INTERFACE (GCAL_TYPE_TIMELINE_SUBSCRIBER,
gcal_timeline_subscriber_interface_init));
enum
{
@@ -1166,6 +1171,8 @@ gcal_month_view_set_date (GcalView *view,
update_header_labels (self);
update_month_cells (self);
gcal_timeline_subscriber_range_changed (GCAL_TIMELINE_SUBSCRIBER (view));
GCAL_EXIT;
}
@@ -1284,6 +1291,126 @@ gtk_buildable_interface_init (GtkBuildableIface *iface)
}
/*
* GcalTimelineSubscriber iface
*/
static GDateTime*
gcal_month_view_get_range_start (GcalTimelineSubscriber *subscriber)
{
GcalMonthView *self = GCAL_MONTH_VIEW (subscriber);
return g_date_time_new_local (g_date_time_get_year (self->date),
g_date_time_get_month (self->date),
1, 0, 0, 0);
}
static GDateTime*
gcal_month_view_get_range_end (GcalTimelineSubscriber *subscriber)
{
g_autoptr (GDateTime) month_start = NULL;
month_start = gcal_month_view_get_range_start (subscriber);
return g_date_time_add_months (month_start, 1);
}
static void
gcal_month_view_add_event (GcalTimelineSubscriber *subscriber,
GcalEvent *event)
{
GcalMonthView *self;
GcalCalendar *calendar;
GtkWidget *event_widget;
self = GCAL_MONTH_VIEW (subscriber);
calendar = gcal_event_get_calendar (event);
event_widget = gcal_event_widget_new (self->context, event);
gcal_event_widget_set_read_only (GCAL_EVENT_WIDGET (event_widget), gcal_calendar_is_read_only (calendar));
gtk_widget_show (event_widget);
gtk_container_add (GTK_CONTAINER (subscriber), event_widget);
self->pending_event_allocation = TRUE;
}
static void
gcal_month_view_update_event (GcalTimelineSubscriber *subscriber,
GcalEvent *event)
{
GcalMonthView *self;
GtkWidget *new_widget;
GList *l;
GCAL_ENTRY;
self = GCAL_MONTH_VIEW (subscriber);
l = g_hash_table_lookup (self->children, gcal_event_get_uid (event));
if (!l)
{
g_warning ("%s: Widget with uuid: %s not found in view: %s",
G_STRFUNC,
gcal_event_get_uid (event),
gtk_widget_get_name (GTK_WIDGET (subscriber)));
return;
}
/* Destroy the old event widget (split event widgets will be destroyed too) */
gtk_widget_destroy (l->data);
/* Create and add the new event widget */
new_widget = gcal_event_widget_new (self->context, event);
gtk_widget_show (new_widget);
gtk_container_add (GTK_CONTAINER (subscriber), new_widget);
self->pending_event_allocation = TRUE;
GCAL_EXIT;
}
static void
gcal_month_view_remove_event (GcalTimelineSubscriber *subscriber,
GcalEvent *event)
{
GcalMonthView *self;
const gchar *uuid;
GList *l;
GCAL_ENTRY;
self = GCAL_MONTH_VIEW (subscriber);
uuid = gcal_event_get_uid (event);
l = g_hash_table_lookup (self->children, uuid);
if (!l)
{
g_warning ("%s: Widget with uuid: %s not found in view: %s",
G_STRFUNC,
uuid,
gtk_widget_get_name (GTK_WIDGET (subscriber)));
GCAL_RETURN ();
}
gtk_widget_destroy (l->data);
self->pending_event_allocation = TRUE;
GCAL_EXIT;
}
static void
gcal_timeline_subscriber_interface_init (GcalTimelineSubscriberInterface *iface)
{
iface->get_range_start = gcal_month_view_get_range_start;
iface->get_range_end = gcal_month_view_get_range_end;
iface->add_event = gcal_month_view_add_event;
iface->update_event = gcal_month_view_update_event;
iface->remove_event = gcal_month_view_remove_event;
}
/*
* ECalDataModelSubscriber interface
*/
@@ -1296,7 +1423,6 @@ gcal_month_view_component_added (ECalDataModelSubscriber *subscriber,
g_autoptr (GcalEvent) event = NULL;
GcalMonthView *self;
GcalCalendar *calendar;
GtkWidget *event_widget;
GError *error;
GCAL_ENTRY;
@@ -1314,13 +1440,7 @@ gcal_month_view_component_added (ECalDataModelSubscriber *subscriber,
GCAL_RETURN ();
}
event_widget = gcal_event_widget_new (self->context, event);
gcal_event_widget_set_read_only (GCAL_EVENT_WIDGET (event_widget), e_client_is_readonly (E_CLIENT (client)));
gtk_widget_show (event_widget);
gtk_container_add (GTK_CONTAINER (subscriber), event_widget);
self->pending_event_allocation = TRUE;
gcal_month_view_add_event (GCAL_TIMELINE_SUBSCRIBER (self), event);
GCAL_EXIT;
}
+88 -5
View File
@@ -21,6 +21,7 @@
#include "gcal-debug.h"
#include "gcal-enums.h"
#include "gcal-event-widget.h"
#include "gcal-timeline-subscriber.h"
#include "gcal-utils.h"
#include "gcal-view.h"
#include "gcal-week-header.h"
@@ -63,6 +64,8 @@ static void gcal_view_interface_init (GcalViewInterf
static void gcal_data_model_subscriber_interface_init (ECalDataModelSubscriberInterface *iface);
static void gcal_timeline_subscriber_interface_init (GcalTimelineSubscriberInterface *iface);
enum
{
PROP_0,
@@ -75,7 +78,9 @@ enum
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));
gcal_data_model_subscriber_interface_init)
G_IMPLEMENT_INTERFACE (GCAL_TYPE_TIMELINE_SUBSCRIBER,
gcal_timeline_subscriber_interface_init));
/* Callbacks */
static void
@@ -198,6 +203,8 @@ gcal_week_view_set_date (GcalView *view,
schedule_position_scroll (self);
gcal_timeline_subscriber_range_changed (GCAL_TIMELINE_SUBSCRIBER (view));
GCAL_EXIT;
}
@@ -334,6 +341,85 @@ update_hours_sidebar_size (GcalWeekView *self)
g_object_unref (layout);
}
/*
* GcalTimelineSubscriber iface
*/
static GDateTime*
gcal_week_view_get_range_start (GcalTimelineSubscriber *subscriber)
{
GcalWeekView *self = GCAL_WEEK_VIEW (subscriber);
return gcal_date_time_get_start_of_week (self->date);
}
static GDateTime*
gcal_week_view_get_range_end (GcalTimelineSubscriber *subscriber)
{
GcalWeekView *self = GCAL_WEEK_VIEW (subscriber);
return gcal_date_time_get_end_of_week (self->date);
}
static void
gcal_week_view_add_event (GcalTimelineSubscriber *subscriber,
GcalEvent *event)
{
GcalWeekView *self = GCAL_WEEK_VIEW (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
gcal_week_grid_add_event (GCAL_WEEK_GRID (self->week_grid), event);
GCAL_EXIT;
}
static void
gcal_week_view_update_event (GcalTimelineSubscriber *subscriber,
GcalEvent *event)
{
GcalWeekView *self = GCAL_WEEK_VIEW (subscriber);
const gchar *event_id;
GCAL_ENTRY;
event_id = gcal_event_get_uid (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);
GCAL_EXIT;
}
static void
gcal_week_view_remove_event (GcalTimelineSubscriber *subscriber,
GcalEvent *event)
{
GcalWeekView *self = GCAL_WEEK_VIEW (subscriber);
const gchar *uuid = gcal_event_get_uid (event);
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_timeline_subscriber_interface_init (GcalTimelineSubscriberInterface *iface)
{
iface->get_range_start = gcal_week_view_get_range_start;
iface->get_range_end = gcal_week_view_get_range_end;
iface->add_event = gcal_week_view_add_event;
iface->update_event = gcal_week_view_update_event;
iface->remove_event = gcal_week_view_remove_event;
}
/* ECalDataModelSubscriber implementation */
static void
@@ -351,10 +437,7 @@ gcal_week_view_component_added (ECalDataModelSubscriber *subscriber,
e_client_get_source (E_CLIENT (client)));
event = gcal_event_new (calendar, comp, NULL);
if (gcal_event_is_multiday (event) || gcal_event_get_all_day (event))
gcal_week_header_add_event (GCAL_WEEK_HEADER (self->header), event);
else
gcal_week_grid_add_event (GCAL_WEEK_GRID (self->week_grid), event);
gcal_week_view_add_event (GCAL_TIMELINE_SUBSCRIBER (subscriber), event);
GCAL_EXIT;
}
+164 -1
View File
@@ -22,6 +22,7 @@
#include "gcal-clock.h"
#include "gcal-context.h"
#include "gcal-debug.h"
#include "gcal-timeline-subscriber.h"
#include "gcal-year-view.h"
#include "gcal-view.h"
#include "gcal-utils.h"
@@ -129,11 +130,15 @@ static void gcal_view_interface_init (GcalViewInterf
static void gcal_data_model_subscriber_interface_init (ECalDataModelSubscriberInterface *iface);
static void update_weather (GcalYearView *self);
static void gcal_timeline_subscriber_interface_init (GcalTimelineSubscriberInterface *iface);
G_DEFINE_TYPE_WITH_CODE (GcalYearView, gcal_year_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));
gcal_data_model_subscriber_interface_init)
G_IMPLEMENT_INTERFACE (GCAL_TYPE_TIMELINE_SUBSCRIBER,
gcal_timeline_subscriber_interface_init));
static gint
compare_events (GcalEventWidget *widget1,
@@ -1588,6 +1593,163 @@ navigator_drag_leave_cb (GcalYearView *self,
gtk_widget_queue_draw (navigator);
}
/*
* GcalTimelineSubscriber implementation
*/
static GDateTime*
gcal_year_view_get_range_start (GcalTimelineSubscriber *subscriber)
{
GcalYearView *self = GCAL_YEAR_VIEW (subscriber);
return g_date_time_new_local (g_date_time_get_year (self->date),
1, 1, 0, 0, 0);
}
static GDateTime*
gcal_year_view_get_range_end (GcalTimelineSubscriber *subscriber)
{
GcalYearView *self = GCAL_YEAR_VIEW (subscriber);
return g_date_time_new_local (g_date_time_get_year (self->date) + 1,
1, 1, 0, 0, 0);
}
static void
gcal_year_view_add_event (GcalTimelineSubscriber *subscriber,
GcalEvent *event)
{
GcalYearView *self;
GDateTime *event_start;
GDateTime *event_end;
guint start_month;
guint end_month;
guint i;
GCAL_ENTRY;
self = GCAL_YEAR_VIEW (subscriber);
g_debug ("Caching event '%s' in Year view", gcal_event_get_uid (event));
event_start = gcal_event_get_date_start (event);
event_end = gcal_event_get_date_end (event);
/* Calculate the start & end months */
start_month = g_date_time_get_month (event_start) - 1;
end_month = g_date_time_get_month (event_end) - 1;
if (g_date_time_get_year (event_start) < g_date_time_get_year (self->date))
start_month = 0;
if (g_date_time_get_year (event_end) > g_date_time_get_year (self->date))
end_month = 11;
/* Add the event to the cache */
for (i = start_month; i <= end_month; i++)
g_ptr_array_add (self->events[i], g_object_ref (event));
update_sidebar (self);
gtk_widget_queue_draw (GTK_WIDGET (self->navigator));
GCAL_EXIT;
}
static void
gcal_year_view_remove_event (GcalTimelineSubscriber *subscriber,
GcalEvent *event)
{
g_autoptr (GList) children = NULL;
GcalYearView *self;
GList *l;
const gchar *event_id;
guint n_children;
guint i;
GCAL_ENTRY;
self = GCAL_YEAR_VIEW (subscriber);
event_id = gcal_event_get_uid (event);
n_children = 0;
children = gtk_container_get_children (GTK_CONTAINER (self->events_sidebar));
for (l = children; l != NULL; l = g_list_next (l))
{
GcalEventWidget *child_widget;
GcalEvent *list_event;
child_widget = GCAL_EVENT_WIDGET (gtk_bin_get_child (GTK_BIN (l->data)));
list_event = gcal_event_widget_get_event (child_widget);
if (g_strcmp0 (event_id, gcal_event_get_uid (list_event)) == 0)
gtk_widget_destroy (GTK_WIDGET (l->data));
else
n_children++;
}
/*
* No children left visible, all the events were removed and now we have to show the
* 'No Events' placeholder.
*/
if (n_children == 0)
{
update_no_events_page (self);
gtk_stack_set_visible_child_name (GTK_STACK (self->navigator_stack), "no-events");
}
/* Also remove from the cached list of events */
for (i = 0; i < 12; i++)
{
GPtrArray *events;
guint j;
events = self->events[i];
for (j = 0; j < events->len; j++)
{
GcalEvent *cached_event;
cached_event = g_ptr_array_index (events, j);
if (!g_str_equal (gcal_event_get_uid (cached_event), event_id))
continue;
g_debug ("Removing event '%s' from Year view's cache", event_id);
g_ptr_array_remove (events, event);
}
}
gtk_widget_queue_draw (GTK_WIDGET (self->navigator));
GCAL_EXIT;
}
static void
gcal_year_view_update_event (GcalTimelineSubscriber *subscriber,
GcalEvent *event)
{
GCAL_ENTRY;
gcal_year_view_remove_event (subscriber, event);
gcal_year_view_add_event (subscriber, event);
GCAL_EXIT;
}
static void
gcal_timeline_subscriber_interface_init (GcalTimelineSubscriberInterface *iface)
{
iface->get_range_start = gcal_year_view_get_range_start;
iface->get_range_end = gcal_year_view_get_range_end;
iface->add_event = gcal_year_view_add_event;
iface->remove_event = gcal_year_view_remove_event;
iface->update_event = gcal_year_view_update_event;
}
/* GcalView implementation */
static GDateTime*
gcal_year_view_get_date (GcalView *view)
@@ -1604,6 +1766,7 @@ gcal_year_view_set_date (GcalView *view,
GCAL_ENTRY;
update_date (GCAL_YEAR_VIEW (view), date);
gcal_timeline_subscriber_range_changed (GCAL_TIMELINE_SUBSCRIBER (view));
GCAL_EXIT;
}