[gnome-calendar/wip/gbsneto/dnd: 13/14] year-view: implement the ::drag-drop operation



commit 82c7918b151255b3442432462d933c8b08e214da
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Sat May 21 18:46:08 2016 -0300

    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.

 data/ui/year-view.ui |    1 +
 src/gcal-year-view.c |   78 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+), 0 deletions(-)
---
diff --git a/data/ui/year-view.ui b/data/ui/year-view.ui
index e863089..23b75e7 100644
--- a/data/ui/year-view.ui
+++ b/data/ui/year-view.ui
@@ -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>
diff --git a/src/gcal-year-view.c b/src/gcal-year-view.c
index e2dbee2..1e7a50c 100644
--- a/src/gcal-year-view.c
+++ b/src/gcal-year-view.c
@@ -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);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]