year-view: implement the ::drag-drop operation

This magical commit finally implements the Drag and Drop
on Year view, enabling users to drop events from the sidebar
to the year navigator.
This commit is contained in:
Georges Basile Stavracas Neto
2016-05-21 18:54:47 -03:00
parent 44f5cbe607
commit 82c7918b15
2 changed files with 79 additions and 0 deletions
+1
View File
@@ -25,6 +25,7 @@
<signal name="button-release-event" handler="navigator_button_release_cb" object="GcalYearView" swapped="yes"/>
<signal name="motion-notify-event" handler="navigator_motion_notify_cb" object="GcalYearView" swapped="yes"/>
<signal name="drag-motion" handler="navigator_drag_motion_cb" object="GcalYearView" swapped="yes"/>
<signal name="drag-drop" handler="navigator_drag_drop_cb" object="GcalYearView" swapped="yes"/>
<style>
<class name="year-navigator"/>
</style>
+78
View File
@@ -1298,6 +1298,83 @@ navigator_drag_motion_cb (GcalYearView *self,
return retval;
}
static gboolean
navigator_drag_drop_cb (GcalYearView *self,
GdkDragContext *context,
gint x,
gint y,
guint time,
GtkWidget *navigator)
{
gint day, month, diff;
gboolean is_title;
if (calculate_day_month_for_coord (self, x, y, &day, &month, &is_title))
{
if (!is_title)
{
GcalEventWidget *event_widget;
GcalEvent *event;
GDateTime *start_dt, *end_dt;
GDateTime *drop_date;
event_widget = GCAL_EVENT_WIDGET (gtk_drag_get_source_widget (context));
event = gcal_event_widget_get_event (event_widget);
start_dt = gcal_event_get_date_start (event);
end_dt = gcal_event_get_date_end (event);
/*
* The difference is calculated in number of days. Here we have to
* use the start_dt's hour/minute/second since otherwise we may not
* calculate the difference correctly.
*/
drop_date = g_date_time_new_local (self->date->year,
month + 1,
day,
g_date_time_get_hour (start_dt),
g_date_time_get_minute (start_dt),
g_date_time_get_second (start_dt));
diff = g_date_time_difference (drop_date, start_dt) / G_TIME_SPAN_DAY;
if (diff != 0)
{
GDateTime *new_start;
new_start = g_date_time_add_days (start_dt, diff);
gcal_event_set_date_start (event, new_start);
/* The event may have a NULL end date, so we have to check it here */
if (end_dt)
{
GDateTime *new_end;
new_end = g_date_time_add_days (end_dt, diff);
gcal_event_set_date_end (event, new_start);
g_clear_pointer (&new_end, g_date_time_unref);
}
gcal_manager_update_event (self->manager, event);
g_clear_pointer (&new_start, g_date_time_unref);
}
g_clear_pointer (&drop_date, g_date_time_unref);
}
}
/* Cancel the DnD after the event is dropped */
self->selected_data->dnd_day = -1;
self->selected_data->dnd_month = -1;
gtk_drag_finish (context, TRUE, FALSE, time);
gtk_widget_queue_draw (navigator);
return TRUE;
}
static void
gcal_year_view_finalize (GObject *object)
{
@@ -1692,6 +1769,7 @@ gcal_year_view_class_init (GcalYearViewClass *klass)
gtk_widget_class_bind_template_callback (widget_class, draw_navigator);
gtk_widget_class_bind_template_callback (widget_class, navigator_button_press_cb);
gtk_widget_class_bind_template_callback (widget_class, navigator_button_release_cb);
gtk_widget_class_bind_template_callback (widget_class, navigator_drag_drop_cb);
gtk_widget_class_bind_template_callback (widget_class, navigator_drag_motion_cb);
gtk_widget_class_bind_template_callback (widget_class, navigator_motion_notify_cb);
gtk_widget_class_bind_template_callback (widget_class, add_event_clicked_cb);