[gnome-calendar/wip/pandusonu/week-view: 52/60] week-header: implement merging of consecultive events
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-calendar/wip/pandusonu/week-view: 52/60] week-header: implement merging of consecultive events
- Date: Fri, 2 Dec 2016 01:52:52 +0000 (UTC)
commit 92ba507b9ee086b1718685f5e549fb4c7d6bddf4
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Sun Nov 6 19:28:25 2016 -0200
week-header: implement merging of consecultive events
When an event is placed in the same row consecultively, we must
guarantee that it's only one widget.
src/views/gcal-week-header.c | 268 +++++++++++++++++++++++++++++++++++++++---
1 files changed, 249 insertions(+), 19 deletions(-)
---
diff --git a/src/views/gcal-week-header.c b/src/views/gcal-week-header.c
index 2821b42..00974ce 100644
--- a/src/views/gcal-week-header.c
+++ b/src/views/gcal-week-header.c
@@ -185,6 +185,205 @@ add_event_to_weekday (GcalWeekHeader *self,
self->events[weekday] = l;
}
+static gint
+merge_events (GcalWeekHeader *self,
+ GtkWidget *event,
+ GtkWidget *to_be_removed)
+{
+ gint deleted_width, current_width;
+
+ /* Retrieve the current sizes */
+ gtk_container_child_get (GTK_CONTAINER (self->grid),
+ to_be_removed,
+ "width", &deleted_width,
+ NULL);
+
+ if (event == to_be_removed)
+ goto out;
+
+ gtk_container_child_get (GTK_CONTAINER (self->grid),
+ event,
+ "width", ¤t_width,
+ NULL);
+
+ gtk_widget_destroy (to_be_removed);
+
+ /* Update the event's size */
+ gtk_container_child_set (GTK_CONTAINER (self->grid),
+ event,
+ "width", current_width + deleted_width,
+ NULL);
+
+out:
+ return deleted_width;
+}
+
+static void
+check_mergeable_events (GcalWeekHeader *self)
+{
+ gint weekday;
+
+ /* We don't need to check the last column */
+ for (weekday = 0; weekday < 6; weekday++)
+ {
+ GList *events_at_weekday, *l;
+ gint index;
+
+ index = 0;
+ events_at_weekday = self->events[weekday];
+
+ for (l = events_at_weekday; l != NULL; l = l->next)
+ {
+ GcalEvent *current_event;
+ gint events_to_merge, i;
+
+ current_event = l->data;
+ events_to_merge = 0;
+
+ /* No need to continue if we're hiding the events */
+ if (!self->expanded && index > 3)
+ break;
+
+ /*
+ * Horizontally check if the next cells have the same event
+ * than the current cell.
+ */
+ for (i = 1; i < 7 - weekday; i++)
+ {
+ GcalEvent *next_event;
+
+ next_event = g_list_nth_data (self->events[weekday + 1], index);
+
+ if (next_event != current_event)
+ break;
+
+ events_to_merge++;
+ }
+
+ /* We found events to merge. Lets merge them */
+ i = 0;
+
+ while (events_to_merge > 0)
+ {
+ GtkWidget *current_widget, *to_be_removed;
+ gint removed_cells;
+
+ current_widget = gtk_grid_get_child_at (GTK_GRID (self->grid), weekday + i, index);
+ to_be_removed = gtk_grid_get_child_at (GTK_GRID (self->grid), weekday + i + 1, index);
+
+ /* First, remove the events from the cells */
+ removed_cells = merge_events (self, current_widget, to_be_removed);
+
+ events_to_merge -= removed_cells;
+ i += removed_cells;
+ }
+
+ index++;
+ }
+ }
+}
+
+static void
+split_event_widget_at_column (GcalWeekHeader *self,
+ GtkWidget *widget,
+ gint column)
+{
+ GDateTime *week_start, *column_date, *end_column_date;
+ GcalEvent *event;
+ gboolean create_before;
+ gboolean create_after;
+ gint left_attach;
+ gint top_attach;
+ gint new_width;
+ gint old_width;
+
+ week_start = get_start_of_week (self->active_date);
+ column_date = g_date_time_add_days (week_start, column);
+ end_column_date = g_date_time_add_days (column_date, 1);
+ event = gcal_event_widget_get_event (GCAL_EVENT_WIDGET (widget));
+
+ create_before = column > 0 && g_date_time_compare (gcal_event_get_date_start (event), column_date) < 0;
+ create_after = column < 6 && g_date_time_compare (gcal_event_get_date_end (event), end_column_date) >= 0;
+
+ gtk_container_child_get (GTK_CONTAINER (self->grid),
+ widget,
+ "top_attach", &top_attach,
+ "left_attach", &left_attach,
+ "width", &old_width,
+ NULL);
+
+
+ g_message (" - - - breaking event '%s'", gcal_event_get_summary (event));
+
+ if (create_before)
+ {
+ GtkWidget *widget_before;
+
+ g_message (" - - - - creating new widget before");
+
+ widget_before = gcal_event_widget_clone (GCAL_EVENT_WIDGET (widget));
+
+ gtk_grid_attach (GTK_GRID (self->grid),
+ widget_before,
+ left_attach,
+ top_attach,
+ column - left_attach,
+ 1);
+
+ new_width = old_width - column + left_attach;
+ old_width = new_width;
+ left_attach = column;
+
+ /* Update the current event position and size */
+ gtk_container_child_set (GTK_CONTAINER (self->grid),
+ widget,
+ "left_attach", left_attach,
+ "width", new_width,
+ NULL);
+
+ gtk_widget_show (widget_before);
+ }
+
+ /* Create a new widget after the current widget */
+ if (create_after)
+ {
+ GtkWidget *widget_after;
+
+ g_message (" - - - - creating new widget after");
+
+ widget_after = gcal_event_widget_clone (GCAL_EVENT_WIDGET (widget));
+ 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),
+ gcal_event_widget_get_date_end (GCAL_EVENT_WIDGET (widget)));
+
+ gtk_grid_attach (GTK_GRID (self->grid),
+ widget_after,
+ column + 1,
+ top_attach,
+ old_width - 1,
+ 1);
+
+ new_width = old_width - (column - left_attach + 1);
+
+ g_message (" - - - - placing new widget at (x: %d, y: %d, w: %d)",
+ column + 1,
+ top_attach,
+ new_width);
+
+ /* Only update the current widget's width */
+ gtk_container_child_set (GTK_CONTAINER (self->grid),
+ widget,
+ "width", new_width,
+ NULL);
+
+ gtk_widget_show (widget_after);
+ }
+
+ g_clear_pointer (&end_column_date, g_date_time_unref);
+ g_clear_pointer (&column_date, g_date_time_unref);
+ g_clear_pointer (&week_start, g_date_time_unref);
+}
+
static void
move_events_at_column (GcalWeekHeader *self,
gint column,
@@ -234,16 +433,22 @@ move_events_at_column (GcalWeekHeader *self,
*/
for (l = found_widgets; l != NULL; l = l->next)
{
- gint top_attach;
+ gint top_attach, left_attach, width;
/* Get the widget's current position... */
gtk_container_child_get (GTK_CONTAINER (self->grid),
l->data,
"top_attach", &top_attach,
+ "left_attach", &left_attach,
+ "width", &width,
NULL);
g_message (" - - - setting top_attach to %d", top_attach + 1);
+ /* If this is a multiday event, break it */
+ if (width > 1)
+ split_event_widget_at_column (self, l->data, column);
+
/* And move it to position + 1 */
gtk_container_child_set (GTK_CONTAINER (self->grid),
l->data,
@@ -251,6 +456,9 @@ move_events_at_column (GcalWeekHeader *self,
NULL);
}
+ /* Check if we eventually can merge events */
+ check_mergeable_events (self);
+
g_clear_pointer (&found_widgets, g_list_free);
}
@@ -260,7 +468,7 @@ add_event_to_grid (GcalWeekHeader *self,
gint start,
gint end)
{
- GDateTime *widget_start_dt, *widget_end_dt;
+ GDateTime *week_start, *week_end, *widget_end_dt;
GtkWidget *widget;
gint events_at_weekday;
gint position;
@@ -307,15 +515,15 @@ add_event_to_grid (GcalWeekHeader *self,
if (!gcal_event_is_multiday (event))
return;
+ week_start = get_start_of_week (self->active_date);
+ week_end = get_end_of_week (self->active_date);
+
/* Setup the event's start date */
- widget_start_dt = get_start_of_week (self->active_date);
- widget_end_dt = g_date_time_add_days (widget_start_dt, 1);
+ widget_end_dt = g_date_time_add_days (week_start, 1);
- gcal_event_widget_set_date_start (GCAL_EVENT_WIDGET (widget), widget_start_dt);
+ gcal_event_widget_set_date_start (GCAL_EVENT_WIDGET (widget), week_start);
gcal_event_widget_set_date_end (GCAL_EVENT_WIDGET (widget), widget_end_dt);
- g_clear_pointer (&widget_start_dt, g_date_time_unref);
-
/*
* In addition to moving the current column's events below, multiday
* events must also move the events from ~all~ the columns it spans
@@ -323,9 +531,11 @@ add_event_to_grid (GcalWeekHeader *self,
*/
for (i = start + 1; i <= end; i++)
{
+ GDateTime *new_widget_end_dt;
gint new_position;
events_at_weekday = g_list_length (self->events[i]);
+ new_widget_end_dt = g_date_time_add_days (widget_end_dt, 1);
/* Add the event to that day */
add_event_to_weekday (self, event, i);
@@ -333,7 +543,6 @@ add_event_to_grid (GcalWeekHeader *self,
g_message (" - - adding event to column %d", i);
g_message (" - - - there are %d events in this column", events_at_weekday);
-
/* Check the event position at this weekday */
new_position = g_list_index (self->events[i], event) + 1;
@@ -344,28 +553,49 @@ add_event_to_grid (GcalWeekHeader *self,
/* Add the event to the grid */
if (new_position == position)
{
- GDateTime *new_widget_end_dt;
-
- new_widget_end_dt = g_date_time_add_days (widget_end_dt, 1);
-
- /* Update the widget's end date */
- gcal_event_widget_set_date_end (GCAL_EVENT_WIDGET (widget), new_widget_end_dt);
-
gtk_container_child_set (GTK_CONTAINER (self->grid),
widget,
"width", i - start + 1,
NULL);
-
- g_clear_pointer (&widget_end_dt, g_date_time_unref);
- widget_end_dt = new_widget_end_dt;
}
else
{
- /* TODO: clone the widget */
+ GDateTime *cloned_widget_start_dt;
+ GtkWidget *cloned_widget;
+
+ cloned_widget_start_dt = g_date_time_add_days (week_start, i);
+ cloned_widget = gcal_event_widget_clone (GCAL_EVENT_WIDGET (widget));
+
+ g_message (" - - - - cloning event");
+
+ gtk_grid_attach (GTK_GRID (self->grid),
+ cloned_widget,
+ i,
+ new_position,
+ 1,
+ 1);
+
+ gcal_event_widget_set_date_start (GCAL_EVENT_WIDGET (cloned_widget), cloned_widget_start_dt);
+
+ /* From now on, let's modify this widget */
+ widget = cloned_widget;
+
+ g_clear_pointer (&cloned_widget_start_dt, g_date_time_unref);
}
+
+ /* Update the widget's end date */
+ gcal_event_widget_set_date_end (GCAL_EVENT_WIDGET (widget), new_widget_end_dt);
+
+ g_clear_pointer (&widget_end_dt, g_date_time_unref);
+
+ widget_end_dt = new_widget_end_dt;
}
gtk_widget_show (widget);
+
+ g_clear_pointer (&widget_end_dt, g_date_time_unref);
+ g_clear_pointer (&week_start, g_date_time_unref);
+ g_clear_pointer (&week_end, g_date_time_unref);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]