[evolution] Calendar: Unify tooltip query in calendar views



commit e0ee9f867832a782e0047e4684c5834347cbb7a3
Author: Milan Crha <mcrha redhat com>
Date:   Tue Mar 29 12:36:56 2022 +0200

    Calendar: Unify tooltip query in calendar views
    
    Since the 'Year View' addition a new cal_comp_util_dup_tooltip() function
    had been added, which constructs a tooltip markup suitable for the GtkWidget,
    thus use that, instead of custom tooltip components with a lot of complicated
    code to manually handle the tooltip create and destroy.

 src/calendar/gui/comp-util.c               |  63 ++++-
 src/calendar/gui/e-calendar-view.c         | 434 -----------------------------
 src/calendar/gui/e-calendar-view.h         |  19 --
 src/calendar/gui/e-day-view.c              | 339 +++++++++-------------
 src/calendar/gui/e-memo-table.c            | 180 +-----------
 src/calendar/gui/e-task-table.c            | 234 +---------------
 src/calendar/gui/e-week-view.c             | 232 +++++----------
 src/modules/calendar/e-cal-shell-content.c |   2 -
 8 files changed, 282 insertions(+), 1221 deletions(-)
---
diff --git a/src/calendar/gui/comp-util.c b/src/calendar/gui/comp-util.c
index ce688e7111..4c1319d88c 100644
--- a/src/calendar/gui/comp-util.c
+++ b/src/calendar/gui/comp-util.c
@@ -124,7 +124,37 @@ cal_comp_util_compare_event_timezones (ECalComponent *comp,
        }
 
        if (!start_datetime || !end_datetime) {
-               retval = FALSE;
+               if (e_cal_component_get_vtype (comp) == E_CAL_COMPONENT_EVENT) {
+                       retval = FALSE;
+               } else if (start_datetime || end_datetime) {
+                       ECalComponentDateTime *dt = start_datetime ? start_datetime : end_datetime;
+
+                       retval = !e_cal_component_datetime_get_tzid (dt) ||
+                                cal_comp_util_tzid_equal (tzid, e_cal_component_datetime_get_tzid (dt));
+
+                       if (!retval) {
+                               ICalTimezone *dt_zone;
+
+                               if (!e_cal_client_get_timezone_sync (client, 
e_cal_component_datetime_get_tzid (dt), &dt_zone, NULL, NULL))
+                                       dt_zone = NULL;
+
+                               if (dt_zone) {
+                                       gint is_daylight = 0; /* Its value is ignored, but libical-glib 3.0.5 
API requires it */
+
+                                       offset1 = i_cal_timezone_get_utc_offset (dt_zone,
+                                               e_cal_component_datetime_get_value (dt),
+                                               &is_daylight);
+                                       offset2 = i_cal_timezone_get_utc_offset (zone,
+                                               e_cal_component_datetime_get_value (dt),
+                                               &is_daylight);
+
+                                       retval = offset1 == offset2;
+                               }
+                       }
+               } else {
+                       retval = TRUE;
+               }
+
                goto out;
        }
 
@@ -2258,12 +2288,12 @@ cal_comp_util_dup_tooltip (ECalComponent *comp,
 
                if (t_end > t_start) {
                        tmp = e_cal_util_seconds_to_string (t_end - t_start);
-                       /* Translators: It will display "Time: ActualStartDateAndTime (DurationOfTheMeeting)" 
*/
-                       e_util_markup_append_escaped (tooltip, _("Time: %s (%s)"), tmp1, tmp);
+                       /* Translators: It will display "Start: ActualStartDateAndTime 
(DurationOfTheMeeting)" */
+                       e_util_markup_append_escaped (tooltip, _("Start: %s (%s)"), tmp1, tmp);
                        g_clear_pointer (&tmp, g_free);
                } else {
-                       /* Translators: It will display "Time: ActualStartDateAndTime" */
-                       e_util_markup_append_escaped (tooltip, _("Time: %s"), tmp1);
+                       /* Translators: It will display "Start: ActualStartDateAndTime" */
+                       e_util_markup_append_escaped (tooltip, _("Start: %s"), tmp1);
                }
 
                g_clear_pointer (&tmp1, g_free);
@@ -2282,6 +2312,7 @@ cal_comp_util_dup_tooltip (ECalComponent *comp,
 
        if (e_cal_component_get_vtype (comp) == E_CAL_COMPONENT_TODO) {
                ECalComponentDateTime *due;
+               ICalTime *completed;
 
                due = e_cal_component_get_due (comp);
 
@@ -2305,6 +2336,28 @@ cal_comp_util_dup_tooltip (ECalComponent *comp,
                }
 
                e_cal_component_datetime_free (due);
+
+               completed = e_cal_component_get_completed (comp);
+
+               if (completed) {
+                       gchar timestr[255] = { 0, };
+
+                       if (i_cal_time_is_utc (completed)) {
+                               zone = i_cal_timezone_get_utc_timezone ();
+                               i_cal_time_convert_timezone (completed, i_cal_timezone_get_utc_timezone (), 
default_zone);
+                               i_cal_time_set_timezone (completed, default_zone);
+                       }
+
+                       cal_comp_util_format_itt (completed, timestr, sizeof (timestr) - 1);
+
+                       if (*timestr) {
+                               g_string_append_c (tooltip, '\n');
+                               /* Translators: It's for a task completed date, it will display "Completed: 
DateAndTime" */
+                               e_util_markup_append_escaped (tooltip, _("Completed: %s"), timestr);
+                       }
+
+                       g_clear_object (&completed);
+               }
        }
 
        tmp = cal_comp_util_dup_attendees_status_info (comp, client, registry);
diff --git a/src/calendar/gui/e-calendar-view.c b/src/calendar/gui/e-calendar-view.c
index f81e7f2418..c9480a0507 100644
--- a/src/calendar/gui/e-calendar-view.c
+++ b/src/calendar/gui/e-calendar-view.c
@@ -443,16 +443,6 @@ calendar_view_dispose (GObject *object)
        G_OBJECT_CLASS (e_calendar_view_parent_class)->dispose (object);
 }
 
-static gboolean
-calendar_view_key_press_event_cb (GtkWidget *view,
-                                 GdkEvent *key_event,
-                                 gpointer user_data)
-{
-       e_calendar_view_destroy_tooltip (E_CALENDAR_VIEW (view));
-
-       return FALSE;
-}
-
 static void
 calendar_view_constructed (GObject *object)
 {
@@ -463,9 +453,6 @@ calendar_view_constructed (GObject *object)
         * the GType accurately.  See GInstanceInitFunc documentation
         * for details of the problem. */
        e_extensible_load_extensions (E_EXTENSIBLE (object));
-
-       g_signal_connect (object, "key-press-event",
-               G_CALLBACK (calendar_view_key_press_event_cb), NULL);
 }
 
 static void
@@ -1793,427 +1780,6 @@ e_calendar_view_edit_appointment (ECalendarView *cal_view,
        e_calendar_view_open_event_with_flags (cal_view, client, icomp, flags);
 }
 
-static gboolean
-tooltip_key_event (GtkWidget *tooltip,
-                  GdkEvent *key_event,
-                  ECalendarView *view)
-{
-       GtkWidget *widget;
-
-       widget = g_object_get_data (G_OBJECT (view), "tooltip-window");
-       if (widget == NULL)
-               return TRUE;
-
-       gtk_widget_destroy (widget);
-       g_object_set_data (G_OBJECT (view), "tooltip-window", NULL);
-
-       return FALSE;
-}
-
-static gchar *
-get_label (ICalTime *tt,
-          ICalTimezone *f_zone,
-          ICalTimezone *t_zone)
-{
-       struct tm tmp_tm;
-
-       tmp_tm = e_cal_util_icaltime_to_tm_with_zone (tt, f_zone, t_zone);
-
-       return e_datetime_format_format_tm ("calendar", "table", i_cal_time_is_date (tt) ? DTFormatKindDate : 
DTFormatKindDateTime, &tmp_tm);
-}
-
-void
-e_calendar_view_move_tip (GtkWidget *widget,
-                          gint x,
-                          gint y)
-{
-       GtkAllocation allocation;
-       GdkDisplay *display;
-       GdkScreen *screen;
-       GdkScreen *pointer_screen;
-       GdkRectangle monitor;
-       GdkDeviceManager *device_manager;
-       GdkDevice *pointer;
-       gint monitor_num, px, py;
-       gint w, h;
-
-       gtk_widget_get_allocation (widget, &allocation);
-       w = allocation.width;
-       h = allocation.height;
-
-       screen = gtk_widget_get_screen (widget);
-       display = gdk_screen_get_display (screen);
-       device_manager = gdk_display_get_device_manager (display);
-       pointer = gdk_device_manager_get_client_pointer (device_manager);
-
-       gdk_device_get_position (pointer, &pointer_screen, &px, &py);
-       if (pointer_screen != screen) {
-               px = x;
-               py = y;
-       }
-       monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
-       gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
-
-       x += E_CALENDAR_VIEW_TOOLTIP_OFFSET;
-
-       if ((x + w) > monitor.x + monitor.width)
-               x -= (x + w) - (monitor.x + monitor.width);
-       else if (x < monitor.x)
-               x = monitor.x;
-
-       if (x < monitor.x)
-               x = monitor.x;
-
-       y += E_CALENDAR_VIEW_TOOLTIP_OFFSET;
-
-       /* Place above the cursor only if it cannot fit below it and there's enough space above */
-
-       if (y + h > monitor.y + monitor.height && y - 2 * E_CALENDAR_VIEW_TOOLTIP_OFFSET - monitor.y > h)
-               y = y - h - 2 * E_CALENDAR_VIEW_TOOLTIP_OFFSET;
-
-       if (y < monitor.y)
-               y = monitor.y;
-
-       gtk_window_move (GTK_WINDOW (widget), x, y);
-       gtk_widget_show (widget);
-}
-
-void
-e_calendar_view_destroy_tooltip (ECalendarView *cal_view)
-{
-       GtkWidget *widget;
-       GObject *object;
-       guint timeout;
-
-       g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
-
-       object = G_OBJECT (cal_view);
-
-       timeout = GPOINTER_TO_UINT (g_object_get_data (object, "tooltip-timeout"));
-       if (timeout) {
-               g_source_remove (timeout);
-               g_object_set_data (object, "tooltip-timeout", NULL);
-       }
-
-       widget = g_object_get_data (object, "tooltip-window");
-       if (widget) {
-               gtk_widget_destroy (widget);
-               g_object_set_data (object, "tooltip-window", NULL);
-       }
-}
-
-/*
- * It is expected to show the tooltips in this below format
- *
- *     <B>SUBJECT OF THE MEETING</B>
- *     Organiser: NameOfTheUser<email ofuser com>
- *     Location: PlaceOfTheMeeting
- *     Time : DateAndTime (xx Minutes)
- *      Status: Accepted: X   Declined: Y   ...
- *      \n<description>
- */
-
-gboolean
-e_calendar_view_get_tooltips (const ECalendarViewEventData *data)
-{
-       GtkWidget *label, *box, *hbox, *ebox, *frame, *toplevel;
-       gchar *tmp, *tmp1 = NULL, *tmp2 = NULL;
-       ECalComponentOrganizer *organizer;
-       ECalComponentDateTime *dtstart, *dtend;
-       time_t t_start, t_end;
-       ECalendarViewEvent *pevent;
-       GtkWidget *widget;
-       GdkWindow *window;
-       GdkDisplay *display;
-       GdkSeat *seat;
-       GdkRGBA bg_rgba, fg_rgba;
-       ECalComponent *newcomp;
-       ICalTimezone *zone, *default_zone;
-       ECalModel *model;
-       ECalClient *client = NULL;
-       const gchar *description;
-
-       /* This function is a timeout callback. */
-
-       g_return_val_if_fail (data != NULL, FALSE);
-       g_return_val_if_fail (E_IS_CALENDAR_VIEW (data->cal_view), FALSE);
-
-       e_utils_get_theme_color (GTK_WIDGET (data->cal_view), "theme_selected_bg_color", 
E_UTILS_DEFAULT_THEME_SELECTED_BG_COLOR, &bg_rgba);
-       e_utils_get_theme_color (GTK_WIDGET (data->cal_view), "theme_selected_fg_color", 
E_UTILS_DEFAULT_THEME_SELECTED_FG_COLOR, &fg_rgba);
-
-       model = e_calendar_view_get_model (data->cal_view);
-
-       /* Delete any stray tooltip if left */
-       widget = g_object_get_data (
-               G_OBJECT (data->cal_view), "tooltip-window");
-       if (GTK_IS_WIDGET (widget))
-               gtk_widget_destroy (widget);
-
-       default_zone = e_calendar_view_get_timezone (data->cal_view);
-       pevent = data->get_view_event (data->cal_view, data->day, data->event_num);
-
-       if (!is_comp_data_valid (pevent))
-               return FALSE;
-
-       client = pevent->comp_data->client;
-
-       newcomp = e_cal_component_new_from_icalcomponent (i_cal_component_clone 
(pevent->comp_data->icalcomp));
-       if (!newcomp) {
-               g_warning ("couldn't update calendar component with modified data from backend\n");
-               return FALSE;
-       }
-
-       box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
-
-       tmp1 = e_calendar_view_dup_component_summary (pevent->comp_data->icalcomp);
-
-       if (!(tmp1 && *tmp1)) {
-               g_object_unref (newcomp);
-               gtk_widget_destroy (box);
-               g_free (tmp1);
-
-               return FALSE;
-       }
-
-       tmp = g_markup_printf_escaped ("<b>%s</b>", tmp1);
-       label = gtk_label_new (NULL);
-       gtk_label_set_line_wrap ((GtkLabel *) label, TRUE);
-       gtk_label_set_width_chars (GTK_LABEL (label), 20);
-       gtk_label_set_markup ((GtkLabel *) label, tmp);
-
-       g_free (tmp1);
-       tmp1 = NULL;
-
-       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-       gtk_box_pack_start ((GtkBox *) hbox, label, FALSE, FALSE, 0);
-       ebox = gtk_event_box_new ();
-       gtk_container_add ((GtkContainer *) ebox, hbox);
-       gtk_widget_override_background_color (ebox, GTK_STATE_FLAG_NORMAL, &bg_rgba);
-       gtk_widget_override_color (label, GTK_STATE_FLAG_NORMAL, &fg_rgba);
-
-       gtk_box_pack_start ((GtkBox *) box, ebox, FALSE, FALSE, 0);
-       g_free (tmp);
-
-       organizer = e_cal_component_get_organizer (newcomp);
-       if (organizer && e_cal_component_organizer_get_cn (organizer)) {
-               const gchar *email;
-
-               email = itip_strip_mailto (e_cal_component_organizer_get_value (organizer));
-
-               if (email) {
-                       /* To Translators: It will display "Organiser: NameOfTheUser <email ofuser com>" */
-                       tmp = g_strdup_printf (_("Organizer: %s <%s>"), e_cal_component_organizer_get_cn 
(organizer), email);
-               } else {
-                       /* With SunOne accounts, there may be no ':' in organiser.value*/
-                       tmp = g_strdup_printf (_("Organizer: %s"), e_cal_component_organizer_get_cn 
(organizer));
-               }
-
-               label = gtk_label_new (tmp);
-               hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-               gtk_box_pack_start ((GtkBox *) hbox, label, FALSE, FALSE, 0);
-               ebox = gtk_event_box_new ();
-               gtk_container_add ((GtkContainer *) ebox, hbox);
-               gtk_box_pack_start ((GtkBox *) box, ebox, FALSE, FALSE, 0);
-
-               g_free (tmp);
-       }
-
-       e_cal_component_organizer_free (organizer);
-
-       tmp1 = e_cal_component_get_location (newcomp);
-
-       if (tmp1) {
-               /* Translators: It will display "Location: PlaceOfTheMeeting" */
-               tmp = g_markup_printf_escaped (_("Location: %s"), tmp1);
-               label = gtk_label_new (NULL);
-               gtk_widget_set_halign (label, GTK_ALIGN_START);
-               gtk_misc_set_alignment ((GtkMisc *) label, 0.0, 0.0);
-               gtk_label_set_markup ((GtkLabel *) label, tmp);
-               gtk_label_set_line_wrap ((GtkLabel *) label, TRUE);
-               gtk_label_set_width_chars (GTK_LABEL (label), 20);
-               gtk_label_set_max_width_chars ((GtkLabel *) label, 80);
-               hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-               gtk_box_pack_start ((GtkBox *) hbox, label, FALSE, FALSE, 0);
-               ebox = gtk_event_box_new ();
-               gtk_container_add ((GtkContainer *) ebox, hbox);
-               gtk_box_pack_start ((GtkBox *) box, ebox, FALSE, FALSE, 0);
-               g_free (tmp);
-       }
-
-       g_free (tmp1);
-       tmp1 = NULL;
-
-       dtstart = e_cal_component_get_dtstart (newcomp);
-       dtend = e_cal_component_get_dtend (newcomp);
-
-       if (dtstart && e_cal_component_datetime_get_tzid (dtstart)) {
-               zone = i_cal_component_get_timezone (e_cal_component_get_icalcomponent (newcomp), 
e_cal_component_datetime_get_tzid (dtstart));
-               if (!zone &&
-                   !e_cal_client_get_timezone_sync (client, e_cal_component_datetime_get_tzid (dtstart), 
&zone, NULL, NULL))
-                       zone = NULL;
-
-               if (!zone)
-                       zone = default_zone;
-
-       } else {
-               zone = default_zone;
-       }
-
-       if (dtstart && e_cal_component_datetime_get_value (dtstart)) {
-               t_start = i_cal_time_as_timet_with_zone (e_cal_component_datetime_get_value (dtstart), zone);
-
-               if (dtend && e_cal_component_datetime_get_value (dtend)) {
-                       ICalTimezone *end_zone = default_zone;
-
-                       if (e_cal_component_datetime_get_tzid (dtend)) {
-                               end_zone = i_cal_component_get_timezone (e_cal_component_get_icalcomponent 
(newcomp), e_cal_component_datetime_get_tzid (dtend));
-                               if (!end_zone &&
-                                   !e_cal_client_get_timezone_sync (client, 
e_cal_component_datetime_get_tzid (dtend), &end_zone, NULL, NULL))
-                                       end_zone = NULL;
-
-                               if (!end_zone)
-                                       end_zone = default_zone;
-                       }
-
-                       t_end = i_cal_time_as_timet_with_zone (e_cal_component_datetime_get_value (dtend), 
end_zone);
-               } else
-                       t_end = t_start;
-
-               tmp1 = get_label (e_cal_component_datetime_get_value (dtstart), zone, default_zone);
-               tmp = calculate_time (t_start, t_end);
-
-               /* To Translators: It will display "Time: ActualStartDateAndTime (DurationOfTheMeeting)"*/
-               tmp2 = g_strdup_printf (_("Time: %s %s"), tmp1, tmp);
-               if (zone && !cal_comp_util_compare_event_timezones (newcomp, client, default_zone)) {
-                       g_free (tmp);
-                       g_free (tmp1);
-
-                       tmp1 = get_label (e_cal_component_datetime_get_value (dtstart), zone, zone);
-                       tmp = g_strconcat (tmp2, "\n\t[ ", tmp1, " ", i_cal_timezone_get_display_name (zone), 
" ]", NULL);
-               } else {
-                       g_free (tmp);
-                       tmp = tmp2;
-                       tmp2 = NULL;
-               }
-       } else {
-               tmp = NULL;
-       }
-
-       e_cal_component_datetime_free (dtstart);
-       e_cal_component_datetime_free (dtend);
-
-       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-       gtk_box_pack_start ((GtkBox *) hbox, gtk_label_new_with_mnemonic (tmp), FALSE, FALSE, 0);
-       ebox = gtk_event_box_new ();
-       gtk_container_add ((GtkContainer *) ebox, hbox);
-       gtk_box_pack_start ((GtkBox *) box, ebox, FALSE, FALSE, 0);
-
-       g_free (tmp);
-       g_free (tmp2);
-       g_free (tmp1);
-
-       tmp = e_cal_model_get_attendees_status_info (
-               model, newcomp, pevent->comp_data->client);
-       if (tmp) {
-               hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-               gtk_box_pack_start ((GtkBox *) hbox, gtk_label_new (tmp), FALSE, FALSE, 0);
-               ebox = gtk_event_box_new ();
-               gtk_container_add ((GtkContainer *) ebox, hbox);
-               gtk_box_pack_start ((GtkBox *) box, ebox, FALSE, FALSE, 0);
-
-               g_free (tmp);
-       }
-
-       tmp = cal_comp_util_get_attendee_comments (e_cal_component_get_icalcomponent (newcomp));
-       if (tmp) {
-               hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-               gtk_box_pack_start ((GtkBox *) hbox, gtk_label_new (tmp), FALSE, FALSE, 0);
-               ebox = gtk_event_box_new ();
-               gtk_container_add ((GtkContainer *) ebox, hbox);
-               gtk_box_pack_start ((GtkBox *) box, ebox, FALSE, FALSE, 0);
-
-               g_free (tmp);
-       }
-
-       description = i_cal_component_get_description (e_cal_component_get_icalcomponent (newcomp));
-       if (description && *description && g_utf8_validate (description, -1, NULL) &&
-           !g_str_equal (description, "\r") &&
-           !g_str_equal (description, "\n") &&
-           !g_str_equal (description, "\r\n")) {
-               #define MAX_TOOLTIP_DESCRIPTION_LEN 1024
-               glong len;
-
-               tmp = NULL;
-
-               len = g_utf8_strlen (description, -1);
-               if (len > MAX_TOOLTIP_DESCRIPTION_LEN) {
-                       GString *str;
-                       const gchar *end;
-
-                       end = g_utf8_offset_to_pointer (description, MAX_TOOLTIP_DESCRIPTION_LEN);
-                       str = g_string_new_len (description, end - description);
-                       g_string_append (str, _("…"));
-
-                       tmp = g_string_free (str, FALSE);
-               }
-
-               hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-               gtk_widget_set_margin_top (hbox, 12);
-               label = gtk_label_new (tmp ? tmp : description);
-               g_object_set (G_OBJECT (label),
-                       "wrap", TRUE,
-                       "width-chars", 80,
-                       "max-width-chars", 100,
-                       "xalign", 0.0,
-                       NULL);
-
-               gtk_box_pack_start ((GtkBox *) hbox, label, FALSE, FALSE, 0);
-               ebox = gtk_event_box_new ();
-               gtk_container_add ((GtkContainer *) ebox, hbox);
-               gtk_box_pack_start ((GtkBox *) box, ebox, FALSE, FALSE, 0);
-
-               g_free (tmp);
-       }
-
-       pevent->tooltip = gtk_window_new (GTK_WINDOW_POPUP);
-
-       toplevel = gtk_widget_get_toplevel (GTK_WIDGET (data->cal_view));
-       if (GTK_IS_WINDOW (toplevel)) {
-               gtk_window_group_add_window (gtk_window_get_group (GTK_WINDOW (toplevel)), GTK_WINDOW 
(pevent->tooltip));
-               gtk_window_set_transient_for (GTK_WINDOW (pevent->tooltip), GTK_WINDOW (toplevel));
-       }
-
-       frame = gtk_frame_new (NULL);
-       gtk_frame_set_shadow_type ((GtkFrame *) frame, GTK_SHADOW_IN);
-
-       gtk_window_set_type_hint (GTK_WINDOW (pevent->tooltip), GDK_WINDOW_TYPE_HINT_TOOLTIP);
-       gtk_window_move ((GtkWindow *) pevent->tooltip, pevent->x + E_CALENDAR_VIEW_TOOLTIP_OFFSET, pevent->y 
+ E_CALENDAR_VIEW_TOOLTIP_OFFSET);
-       gtk_container_add ((GtkContainer *) frame, box);
-       gtk_container_add ((GtkContainer *) pevent->tooltip, frame);
-
-       gtk_widget_show_all (pevent->tooltip);
-
-       e_calendar_view_move_tip (pevent->tooltip, pevent->x, pevent->y);
-
-       window = gtk_widget_get_window (pevent->tooltip);
-       display = gdk_window_get_display (window);
-       seat = gdk_display_get_default_seat (display);
-
-       /* Grab all keyboard devices.  A key press from
-        * any of them will dismiss the tooltip window. */
-       gdk_seat_grab (seat, window, GDK_SEAT_CAPABILITY_KEYBOARD, TRUE, NULL, NULL, NULL, NULL);
-
-       g_signal_connect (
-               pevent->tooltip, "key-press-event",
-               G_CALLBACK (tooltip_key_event), data->cal_view);
-       pevent->timeout = 0;
-
-       g_object_set_data (G_OBJECT (data->cal_view), "tooltip-window", pevent->tooltip);
-       g_object_unref (newcomp);
-
-       return FALSE;
-}
-
 static gboolean
 icomp_contains_category (ICalComponent *icomp,
                         const gchar *category)
diff --git a/src/calendar/gui/e-calendar-view.h b/src/calendar/gui/e-calendar-view.h
index 434d221b79..b3332ec8fe 100644
--- a/src/calendar/gui/e-calendar-view.h
+++ b/src/calendar/gui/e-calendar-view.h
@@ -49,8 +49,6 @@
 
 G_BEGIN_DECLS
 
-#define E_CALENDAR_VIEW_TOOLTIP_OFFSET 16
-
 typedef enum {
        E_CALENDAR_VIEW_POS_OUTSIDE,
        E_CALENDAR_VIEW_POS_NONE,
@@ -79,8 +77,6 @@ typedef enum {
        guint16 end_minute; \
        guint different_timezone : 1; \
        gboolean is_editable; \
-       GtkWidget *tooltip; \
-       gint    timeout; \
        GdkColor *color; \
        gint x,y;
 
@@ -113,15 +109,6 @@ struct _ECalendarView {
        ECalendarViewPrivate *priv;
 };
 
-typedef struct {
-       ECalendarViewEvent * (*get_view_event)  (ECalendarView *view,
-                                                gint day,
-                                                gint event_num);
-       ECalendarView *cal_view;
-       gint day;
-       gint event_num;
-} ECalendarViewEventData;
-
 typedef struct _ECalendarViewSelectionData {
        ECalClient *client;
        ICalComponent *icalcomp;
@@ -267,12 +254,6 @@ gchar *            e_calendar_view_get_description_text
 void           e_calendar_view_move_view_range (ECalendarView *cal_view,
                                                 ECalendarViewMoveType mode_type,
                                                 time_t exact_date);
-gboolean       e_calendar_view_get_tooltips    (const ECalendarViewEventData *data);
-
-void           e_calendar_view_move_tip        (GtkWidget *widget,
-                                                gint x,
-                                                gint y);
-void           e_calendar_view_destroy_tooltip (ECalendarView *cal_view);
 
 gchar *                e_calendar_view_dup_component_summary
                                                (ICalComponent *icomp);
diff --git a/src/calendar/gui/e-day-view.c b/src/calendar/gui/e-day-view.c
index 6b05dbe4e5..0c08867ad7 100644
--- a/src/calendar/gui/e-day-view.c
+++ b/src/calendar/gui/e-day-view.c
@@ -486,8 +486,6 @@ static void e_day_view_precalc_visible_time_range (ECalendarView *cal_view,
 static void e_day_view_queue_layout (EDayView *day_view);
 static void e_day_view_cancel_layout (EDayView *day_view);
 static gboolean e_day_view_layout_timeout_cb (gpointer data);
-static void tooltip_destroy (EDayView *day_view, GnomeCanvasItem *item);
-static EDayViewEvent *tooltip_get_view_event (EDayView *day_view, gint day, gint event_num);
 
 enum {
        PROP_0,
@@ -1970,6 +1968,121 @@ day_view_paste_text (ECalendarView *cal_view)
        }
 }
 
+static EDayViewEvent *
+e_day_view_get_event (EDayView *day_view,
+                     gint day,
+                     gint event_num)
+{
+       EDayViewEvent *pevent;
+
+       if (day == E_DAY_VIEW_LONG_EVENT) {
+               if (!is_array_index_in_bounds (day_view->long_events, event_num))
+                       return NULL;
+
+               pevent = &g_array_index (day_view->long_events, EDayViewEvent, event_num);
+       } else {
+               if (!is_array_index_in_bounds (day_view->events[day], event_num))
+                       return NULL;
+
+               pevent = &g_array_index (day_view->events[day], EDayViewEvent, event_num);
+       }
+
+       return pevent;
+}
+
+static gboolean
+e_day_view_query_tooltip (EDayView *day_view,
+                         gint day,
+                         gint event_num,
+                         GtkTooltip *tooltip)
+{
+       EDayViewEvent *event;
+       ECalComponent *new_comp;
+       ECalModel *model;
+       gchar *markup;
+
+       event = e_day_view_get_event (day_view, day, event_num);
+       if (!event || !event->comp_data)
+               return FALSE;
+
+       new_comp = e_cal_component_new_from_icalcomponent (i_cal_component_clone 
(event->comp_data->icalcomp));
+       if (!new_comp)
+               return FALSE;
+
+       model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view));
+
+       markup = cal_comp_util_dup_tooltip (new_comp, event->comp_data->client,
+               e_cal_model_get_registry (model),
+               e_cal_model_get_timezone (model));
+
+       gtk_tooltip_set_markup (tooltip, markup);
+
+       g_free (markup);
+       g_object_unref (new_comp);
+
+       return TRUE;
+}
+
+static gboolean
+e_day_view_top_canvas_query_tooltip_cb (GtkWidget *widget,
+                                       gint x,
+                                       gint y,
+                                       gboolean keyboard_mode,
+                                       GtkTooltip *tooltip,
+                                       gpointer user_data)
+{
+       EDayView *day_view = user_data;
+       ECalendarViewPosition pos;
+       gint day, event_num;
+
+       g_return_val_if_fail (E_IS_DAY_VIEW (day_view), FALSE);
+
+       if (keyboard_mode)
+               return FALSE;
+
+       y += gtk_adjustment_get_value (gtk_scrollable_get_vadjustment (GTK_SCROLLABLE 
(day_view->top_canvas)));
+
+       pos = e_day_view_convert_position_in_top_canvas (day_view, x, y, &day, &event_num);
+
+       if (pos == E_CALENDAR_VIEW_POS_OUTSIDE)
+               return FALSE;
+
+       if (pos == E_CALENDAR_VIEW_POS_NONE)
+               return FALSE;
+
+       return e_day_view_query_tooltip (day_view, E_DAY_VIEW_LONG_EVENT, event_num, tooltip);
+}
+
+static gboolean
+e_day_view_main_canvas_query_tooltip_cb (GtkWidget *widget,
+                                        gint x,
+                                        gint y,
+                                        gboolean keyboard_mode,
+                                        GtkTooltip *tooltip,
+                                        gpointer user_data)
+{
+       EDayView *day_view = user_data;
+       ECalendarViewPosition pos;
+       gint row, day, event_num;
+
+       g_return_val_if_fail (E_IS_DAY_VIEW (day_view), FALSE);
+
+       if (keyboard_mode)
+               return FALSE;
+
+       y += gtk_adjustment_get_value (gtk_scrollable_get_vadjustment (GTK_SCROLLABLE 
(day_view->main_canvas)));
+
+       pos = e_day_view_convert_position_in_main_canvas (day_view, x, y, &day, &row, &event_num);
+
+       if (pos == E_CALENDAR_VIEW_POS_OUTSIDE)
+               return FALSE;
+
+       if (pos == E_CALENDAR_VIEW_POS_NONE)
+               return FALSE;
+
+       return e_day_view_query_tooltip (day_view, day, event_num, tooltip);
+}
+
 static void
 e_day_view_class_init (EDayViewClass *class)
 {
@@ -2219,6 +2332,7 @@ e_day_view_init (EDayView *day_view)
         * disconnect signal handlers in dispose(). */
        widget = e_canvas_new ();
        gtk_box_pack_end (GTK_BOX (container), widget, TRUE, TRUE, 0);
+       gtk_widget_set_has_tooltip (widget, TRUE);
        day_view->top_canvas = g_object_ref (widget);
        gtk_widget_show (widget);
 
@@ -2272,6 +2386,9 @@ e_day_view_init (EDayView *day_view)
                G_CALLBACK (e_day_view_on_top_canvas_drag_data_received), day_view);
        day_view->priv->top_canvas_drag_data_received_handler_id = handler_id;
 
+       g_signal_connect_object (day_view->top_canvas, "query-tooltip",
+               G_CALLBACK (e_day_view_top_canvas_query_tooltip_cb), day_view, 0);
+
        canvas_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (day_view->top_dates_canvas)->root);
 
        day_view->top_dates_canvas_item =
@@ -2326,6 +2443,7 @@ e_day_view_init (EDayView *day_view)
                "vexpand", TRUE,
                "halign", GTK_ALIGN_FILL,
                "valign", GTK_ALIGN_FILL,
+               "has-tooltip", TRUE,
                NULL);
        day_view->main_canvas = g_object_ref (widget);
        gtk_widget_show (widget);
@@ -2386,6 +2504,9 @@ e_day_view_init (EDayView *day_view)
                G_CALLBACK (e_day_view_on_main_canvas_drag_data_received), day_view);
        day_view->priv->main_canvas_drag_data_received_handler_id = handler_id;
 
+       g_signal_connect_object (day_view->main_canvas, "query-tooltip",
+               G_CALLBACK (e_day_view_main_canvas_query_tooltip_cb), day_view, 0);
+
        canvas_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (day_view->main_canvas)->root);
 
        day_view->main_canvas_item =
@@ -3172,31 +3293,6 @@ e_day_view_foreach_event_with_uid (EDayView *day_view,
        }
 }
 
-static void
-e_day_view_maybe_destroy_event_tooltip (EDayView *day_view,
-                                       EDayViewEvent *event)
-{
-       GObject *object = G_OBJECT (day_view);
-
-       if (event->timeout > 0 && GPOINTER_TO_UINT (g_object_get_data (object, "tooltip-timeout")) == 
event->timeout) {
-               g_source_remove (event->timeout);
-               event->timeout = 0;
-
-               g_object_set_data (object, "tooltip-timeout", NULL);
-       } else {
-               event->timeout = 0;
-       }
-
-       if (event->tooltip && event->tooltip == g_object_get_data (object, "tooltip-window")) {
-               gtk_widget_destroy (event->tooltip);
-               event->tooltip = NULL;
-
-               g_object_set_data (object, "tooltip-window", NULL);
-       } else {
-               event->tooltip = NULL;
-       }
-}
-
 static gboolean
 e_day_view_remove_event_cb (EDayView *day_view,
                             gint day,
@@ -3236,8 +3332,6 @@ e_day_view_remove_event_cb (EDayView *day_view,
                day_view->popup_event_num--;
        }
 
-       e_day_view_maybe_destroy_event_tooltip (day_view, event);
-
        if (day_view->resize_bars_event_num >= event_num && day_view->resize_bars_event_day == day) {
                if (day_view->resize_bars_event_num == event_num) {
                        day_view->resize_bars_event_num = -1;
@@ -4457,8 +4551,6 @@ e_day_view_on_main_canvas_scroll (GtkWidget *widget,
                                   GdkEventScroll *scroll,
                                   EDayView *day_view)
 {
-       e_calendar_view_destroy_tooltip (E_CALENDAR_VIEW (day_view));
-
        switch (scroll->direction) {
        case GDK_SCROLL_UP:
                e_day_view_scroll (day_view, E_DAY_VIEW_WHEEL_MOUSE_STEP_SIZE);
@@ -4484,8 +4576,6 @@ e_day_view_on_top_canvas_scroll (GtkWidget *widget,
                                   GdkEventScroll *scroll,
                                   EDayView *day_view)
 {
-       e_calendar_view_destroy_tooltip (E_CALENDAR_VIEW (day_view));
-
        switch (scroll->direction) {
        case GDK_SCROLL_UP:
                e_day_view_top_scroll (day_view, E_DAY_VIEW_WHEEL_MOUSE_STEP_SIZE);
@@ -4511,13 +4601,6 @@ e_day_view_on_time_canvas_scroll (GtkWidget *widget,
                                   GdkEventScroll *scroll,
                                   EDayView *day_view)
 {
-       GtkWidget *tool_window = g_object_get_data ((GObject *) day_view, "tooltip-window");
-
-       if (tool_window) {
-               gtk_widget_destroy (tool_window);
-               g_object_set_data (G_OBJECT (day_view), "tooltip-window", NULL);
-       }
-
        switch (scroll->direction) {
        case GDK_SCROLL_UP:
                e_day_view_scroll (day_view, E_DAY_VIEW_WHEEL_MOUSE_STEP_SIZE);
@@ -4881,8 +4964,6 @@ e_day_view_show_popup_menu (EDayView *day_view,
                             gint day,
                             gint event_num)
 {
-       e_calendar_view_destroy_tooltip (E_CALENDAR_VIEW (day_view));
-
        e_day_view_set_popup_event (day_view, day, event_num);
 
        e_calendar_view_popup_event (E_CALENDAR_VIEW (day_view), button_event);
@@ -5749,13 +5830,9 @@ e_day_view_free_event_array (EDayView *day_view,
 
                if (is_comp_data_valid (event))
                        g_object_unref (event->comp_data);
-
-               e_day_view_maybe_destroy_event_tooltip (day_view, event);
        }
 
        g_array_set_size (array, 0);
-
-       e_calendar_view_destroy_tooltip (E_CALENDAR_VIEW (day_view));
 }
 
 /* This adds one event to the view, adding it to the appropriate array. */
@@ -5771,7 +5848,6 @@ e_day_view_add_event (ESourceRegistry *registry,
        EDayViewEvent event;
        gint day, offset;
        gint days_shown;
-       guint tooltip_timeout;
        ICalTime *start_tt, *end_tt;
        ICalTimezone *zone;
        AddEventData *add_event_data;
@@ -5793,12 +5869,6 @@ e_day_view_add_event (ESourceRegistry *registry,
        if (end != start || end < add_event_data->day_view->lower)
                g_return_if_fail (end > add_event_data->day_view->lower);
 
-       tooltip_timeout = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (add_event_data->day_view), 
"tooltip-timeout"));
-       if (tooltip_timeout) {
-               g_source_remove (tooltip_timeout);
-               g_object_set_data (G_OBJECT (add_event_data->day_view), "tooltip-timeout", NULL);
-       }
-
        zone = e_calendar_view_get_timezone (E_CALENDAR_VIEW (add_event_data->day_view));
        start_tt = i_cal_time_new_from_timet_with_zone (start, FALSE, zone);
        end_tt = i_cal_time_new_from_timet_with_zone (end, FALSE, zone);
@@ -5814,9 +5884,7 @@ e_day_view_add_event (ESourceRegistry *registry,
        }
 
        event.start = start;
-       event.tooltip = NULL;
        event.color = NULL;
-       event.timeout = -1;
        event.end = end;
        event.canvas_item = NULL;
        event.comp_data->instance_start = start;
@@ -7257,20 +7325,7 @@ e_day_view_start_editing_event (EDayView *day_view,
            && event_num == day_view->editing_event_num)
                return;
 
-       if (day == E_DAY_VIEW_LONG_EVENT) {
-               if (!is_array_index_in_bounds (day_view->long_events, event_num))
-                       return;
-
-               event = &g_array_index (day_view->long_events, EDayViewEvent,
-                                       event_num);
-       } else {
-               if (!is_array_index_in_bounds (day_view->events[day], event_num))
-                       return;
-
-               event = &g_array_index (day_view->events[day], EDayViewEvent,
-                                       event_num);
-       }
-
+       event = e_day_view_get_event (day_view, day, event_num);
        if (!is_comp_data_valid (event))
                return;
 
@@ -7348,18 +7403,7 @@ cancel_editing (EDayView *day_view)
        if (day == -1)
                return;
 
-       if (day == E_DAY_VIEW_LONG_EVENT) {
-               if (!is_array_index_in_bounds (day_view->long_events, event_num))
-                       return;
-
-               event = &g_array_index (day_view->long_events, EDayViewEvent, event_num);
-       } else {
-               if (!is_array_index_in_bounds (day_view->events[day], event_num))
-                       return;
-
-               event = &g_array_index (day_view->events[day], EDayViewEvent, event_num);
-       }
-
+       event = e_day_view_get_event (day_view, day, event_num);
        if (!is_comp_data_valid (event))
                return;
 
@@ -7375,64 +7419,6 @@ cancel_editing (EDayView *day_view)
        e_day_view_stop_editing_event (day_view);
 }
 
-static EDayViewEvent *
-tooltip_get_view_event (EDayView *day_view,
-                        gint day,
-                        gint event_num)
-{
-       EDayViewEvent *pevent;
-
-       if (day == E_DAY_VIEW_LONG_EVENT) {
-               if (!is_array_index_in_bounds (day_view->long_events, event_num))
-                       return  NULL;
-
-               pevent = &g_array_index (day_view->long_events, EDayViewEvent,
-                                       event_num);
-       } else {
-               if (!is_array_index_in_bounds (day_view->events[day], event_num))
-                       return NULL;
-
-               pevent = &g_array_index (day_view->events[day], EDayViewEvent,
-                                       event_num);
-       }
-
-       return pevent;
-}
-
-static void
-tooltip_destroy (EDayView *day_view,
-                 GnomeCanvasItem *item)
-{
-       e_calendar_view_destroy_tooltip (E_CALENDAR_VIEW (day_view));
-
-       if (item) {
-               EDayViewEvent *pevent;
-               gint event_num, day;
-
-               e_day_view_check_layout (day_view);
-
-               event_num = GPOINTER_TO_INT (g_object_get_data ((GObject *) item, "event-num"));
-               day = GPOINTER_TO_INT (g_object_get_data ((GObject *) item, "event-day"));
-               pevent = tooltip_get_view_event (day_view, day, event_num);
-               if (pevent) {
-                       pevent->tooltip = NULL;
-                       pevent->timeout = 0;
-               }
-       }
-}
-
-static void
-e_day_view_destroy_tooltip_timeout_data (gpointer ptr)
-{
-       ECalendarViewEventData *data = ptr;
-
-       if (data) {
-               g_object_set_data (G_OBJECT (data->cal_view), "tooltip-timeout", NULL);
-               g_object_unref (data->cal_view);
-               g_free (data);
-       }
-}
-
 static gboolean
 e_day_view_on_text_item_event (GnomeCanvasItem *item,
                                GdkEvent *event,
@@ -7440,7 +7426,6 @@ e_day_view_on_text_item_event (GnomeCanvasItem *item,
 {
        switch (event->type) {
        case GDK_KEY_PRESS:
-               tooltip_destroy (day_view, item);
                if (!E_TEXT (item)->preedit_len && event && (
                     event->key.keyval == GDK_KEY_Return ||
                     event->key.keyval == GDK_KEY_KP_Enter)) {
@@ -7483,14 +7468,12 @@ e_day_view_on_text_item_event (GnomeCanvasItem *item,
 
                if (day_view->drag_event_num != -1)
                        day_view->drag_event_num = -1;
-               tooltip_destroy (day_view, item);
                /* Only let the EText handle the event while editing. */
                if (!E_TEXT (item)->editing)
                        g_signal_stop_emission_by_name (item, "event");
                break;
 
        case GDK_BUTTON_PRESS:
-               tooltip_destroy (day_view, item);
                /* Only let the EText handle the event while editing. */
                if (!E_TEXT (item)->editing)
                        g_signal_stop_emission_by_name (item, "event");
@@ -7505,7 +7488,6 @@ e_day_view_on_text_item_event (GnomeCanvasItem *item,
        case GDK_ENTER_NOTIFY:
                {
                        EDayViewEvent *pevent;
-                       ECalendarViewEventData *data;
                        gint event_x, event_y, row, day, event_num;
                        ECalendarViewPosition pos;
                        gboolean main_canvas = TRUE;
@@ -7564,34 +7546,19 @@ e_day_view_on_text_item_event (GnomeCanvasItem *item,
                        if (day == -1 || event_num == -1)
                                break;
 
-                       pevent = tooltip_get_view_event (day_view, day, event_num);
+                       pevent = e_day_view_get_event (day_view, day, event_num);
                        if (!pevent)
                                break;
 
                        g_object_set_data (G_OBJECT (item), "event-num", GINT_TO_POINTER (event_num));
                        g_object_set_data (G_OBJECT (item), "event-day", GINT_TO_POINTER (day));
 
-                       e_calendar_view_destroy_tooltip (E_CALENDAR_VIEW (day_view));
-
-                       data = g_malloc (sizeof (ECalendarViewEventData));
                        pevent->x = ((GdkEventCrossing *) event)->x_root;
                        pevent->y = ((GdkEventCrossing *) event)->y_root;
-                       pevent->tooltip = NULL;
-
-                       data->cal_view = g_object_ref (E_CALENDAR_VIEW (day_view));
-                       data->day = day;
-                       data->event_num = event_num;
-                       data->get_view_event = (ECalendarViewEvent * (*)(ECalendarView *, int, gint)) 
tooltip_get_view_event;
-                       pevent->timeout = e_named_timeout_add_full (
-                               G_PRIORITY_DEFAULT, 500,
-                               (GSourceFunc) e_calendar_view_get_tooltips,
-                               data, e_day_view_destroy_tooltip_timeout_data);
-                       g_object_set_data (G_OBJECT (day_view), "tooltip-timeout", GUINT_TO_POINTER 
(pevent->timeout));
 
                return TRUE;
                }
        case GDK_LEAVE_NOTIFY:
-               tooltip_destroy (day_view, item);
                return TRUE;
        case GDK_MOTION_NOTIFY:
                {
@@ -7603,17 +7570,12 @@ e_day_view_on_text_item_event (GnomeCanvasItem *item,
                        event_num = GPOINTER_TO_INT (g_object_get_data ((GObject *) item, "event-num"));
                        day = GPOINTER_TO_INT (g_object_get_data ((GObject *) item, "event-day"));
 
-                       pevent = tooltip_get_view_event (day_view, day, event_num);
+                       pevent = e_day_view_get_event (day_view, day, event_num);
                        if (!pevent)
                                break;
 
                        pevent->x = ((GdkEventMotion *) event)->x_root;
                        pevent->y = ((GdkEventMotion *) event)->y_root;
-                       pevent->tooltip = (GtkWidget *) g_object_get_data (G_OBJECT (day_view), 
"tooltip-window");
-
-                       if (pevent->tooltip) {
-                               e_calendar_view_move_tip (pevent->tooltip, pevent->x, pevent->y);
-                       }
 
                        return TRUE;
                }
@@ -7959,20 +7921,7 @@ e_day_view_on_editing_stopped (EDayView *day_view,
        if (day == -1)
                return;
 
-       if (day == E_DAY_VIEW_LONG_EVENT) {
-               if (!is_array_index_in_bounds (day_view->long_events, event_num))
-                       return;
-
-               event = &g_array_index (day_view->long_events, EDayViewEvent,
-                                       event_num);
-       } else {
-               if (!is_array_index_in_bounds (day_view->events[day], event_num))
-                       return;
-
-               event = &g_array_index (day_view->events[day], EDayViewEvent,
-                                       event_num);
-
-       }
+       event = e_day_view_get_event (day_view, day, event_num);
 
        if (!is_comp_data_valid (event))
                return;
@@ -9054,19 +9003,10 @@ e_day_view_on_drag_begin (GtkWidget *widget,
 
        g_return_if_fail (event_num != -1);
 
-       if (day == E_DAY_VIEW_LONG_EVENT) {
-               if (!is_array_index_in_bounds (day_view->long_events, event_num))
-                       return;
+       event = e_day_view_get_event (day_view, day, event_num);
 
-               event = &g_array_index (day_view->long_events, EDayViewEvent,
-                                       event_num);
-       } else {
-               if (!is_array_index_in_bounds (day_view->events[day], event_num))
-                       return;
-
-               event = &g_array_index (day_view->events[day], EDayViewEvent,
-                                       event_num);
-       }
+       if (!event)
+               return;
 
        /* Hide the text item, since it will be shown in the special drag
         * items. */
@@ -9089,21 +9029,14 @@ e_day_view_on_drag_end (GtkWidget *widget,
        if (day == -1 || event_num == -1)
                return;
 
-       if (day == E_DAY_VIEW_LONG_EVENT) {
-               if (!is_array_index_in_bounds (day_view->long_events, event_num))
-                       return;
+       event = e_day_view_get_event (day_view, day, event_num);
+       if (!event)
+               return;
 
-               event = &g_array_index (day_view->long_events, EDayViewEvent,
-                                       event_num);
+       if (day == E_DAY_VIEW_LONG_EVENT)
                gtk_widget_queue_draw (day_view->top_canvas);
-       } else {
-               if (!is_array_index_in_bounds (day_view->events[day], event_num))
-                       return;
-
-               event = &g_array_index (day_view->events[day], EDayViewEvent,
-                                       event_num);
+       else
                gtk_widget_queue_draw (day_view->main_canvas);
-       }
 
        /* Show the text item again. */
        gnome_canvas_item_show (event->canvas_item);
diff --git a/src/calendar/gui/e-memo-table.c b/src/calendar/gui/e-memo-table.c
index 86fa2f3470..1817ea67dc 100644
--- a/src/calendar/gui/e-memo-table.c
+++ b/src/calendar/gui/e-memo-table.c
@@ -471,18 +471,9 @@ memo_table_query_tooltip (GtkWidget *widget,
        ECalModel *model;
        ECalModelComponent *comp_data;
        gint row = -1, col = -1, row_y = -1, row_height = -1;
-       GtkWidget *box, *l, *w;
-       GdkRGBA sel_bg, sel_fg, norm_bg, norm_text;
-       gchar *tmp, *summary;
-       GString *tmp2;
+       gchar *markup;
        ECalComponent *new_comp;
-       ECalComponentOrganizer *organizer;
-       ECalComponentDateTime *dtstart, *dtdue;
-       ICalTimezone *zone, *default_zone;
-       GSList *desc, *p;
-       gint len;
        ESelectionModel *esm;
-       struct tm tmp_tm;
 
        if (keyboard_mode)
                return FALSE;
@@ -511,172 +502,13 @@ memo_table_query_tooltip (GtkWidget *widget,
        if (!new_comp)
                return FALSE;
 
-       e_utils_get_theme_color (widget, "theme_selected_bg_color", E_UTILS_DEFAULT_THEME_SELECTED_BG_COLOR, 
&sel_bg);
-       e_utils_get_theme_color (widget, "theme_selected_fg_color", E_UTILS_DEFAULT_THEME_SELECTED_FG_COLOR, 
&sel_fg);
-       e_utils_get_theme_color (widget, "theme_bg_color", E_UTILS_DEFAULT_THEME_BG_COLOR, &norm_bg);
-       e_utils_get_theme_color (widget, "theme_text_color,theme_fg_color", E_UTILS_DEFAULT_THEME_TEXT_COLOR, 
&norm_text);
-
-       box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
-
-       summary = e_calendar_view_dup_component_summary (comp_data->icalcomp);
-       if (!(summary && *summary)) {
-               g_free (summary);
-               summary = g_strdup (_("* No Summary *"));
-       }
-
-       l = gtk_label_new (NULL);
-       tmp = g_markup_printf_escaped ("<b>%s</b>", summary);
-       gtk_label_set_line_wrap (GTK_LABEL (l), TRUE);
-       gtk_label_set_width_chars (GTK_LABEL (l), 20);
-       gtk_label_set_markup (GTK_LABEL (l), tmp);
-       gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5);
-       w = gtk_event_box_new ();
-
-       gtk_widget_override_background_color (w, GTK_STATE_FLAG_NORMAL, &sel_bg);
-       gtk_widget_override_color (l, GTK_STATE_FLAG_NORMAL, &sel_fg);
-       gtk_container_add (GTK_CONTAINER (w), l);
-       gtk_box_pack_start (GTK_BOX (box), w, TRUE, TRUE, 0);
-       g_free (tmp);
-
-       g_free (summary);
-
-       w = gtk_event_box_new ();
-       gtk_widget_override_background_color (w, GTK_STATE_FLAG_NORMAL, &norm_bg);
-
-       l = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
-       gtk_container_add (GTK_CONTAINER (w), l);
-       gtk_box_pack_start (GTK_BOX (box), w, FALSE, FALSE, 0);
-       w = l;
-
-       organizer = e_cal_component_get_organizer (new_comp);
-       if (organizer && e_cal_component_organizer_get_cn (organizer)) {
-               const gchar *email;
-
-               email = itip_strip_mailto (e_cal_component_organizer_get_value (organizer));
-
-               if (email) {
-                       tmp = g_strdup_printf (
-                               /* Translators: It will display
-                                * "Organizer: NameOfTheUser <email ofuser com>" */
-                               _("Organizer: %s <%s>"), e_cal_component_organizer_get_cn (organizer), email);
-               } else {
-                       /* With SunOne accounts, there may be no ':' in
-                        * organizer.value */
-                       tmp = g_strdup_printf (
-                               _("Organizer: %s"), e_cal_component_organizer_get_cn (organizer));
-               }
-
-               l = gtk_label_new (tmp);
-               gtk_label_set_line_wrap (GTK_LABEL (l), FALSE);
-               gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5);
-               gtk_box_pack_start (GTK_BOX (w), l, FALSE, FALSE, 0);
-               g_free (tmp);
-
-               gtk_widget_override_color (l, GTK_STATE_FLAG_NORMAL, &norm_text);
-       }
-
-       e_cal_component_organizer_free (organizer);
-
-       dtstart = e_cal_component_get_dtstart (new_comp);
-       dtdue = e_cal_component_get_due (new_comp);
-
-       default_zone = e_cal_model_get_timezone (model);
-
-       if (dtstart && e_cal_component_datetime_get_tzid (dtstart)) {
-               zone = i_cal_component_get_timezone (
-                       e_cal_component_get_icalcomponent (new_comp),
-                       e_cal_component_datetime_get_tzid (dtstart));
-               if (!zone) {
-                       if (!e_cal_client_get_timezone_sync (comp_data->client, 
e_cal_component_datetime_get_tzid (dtstart), &zone, NULL, NULL))
-                               zone = NULL;
-               }
-               if (!zone)
-                       zone = default_zone;
-       } else {
-               zone = NULL;
-       }
-
-       tmp2 = g_string_new ("");
-
-       if (dtstart && e_cal_component_datetime_get_value (dtstart)) {
-               gchar *str;
-
-               tmp_tm = e_cal_util_icaltime_to_tm_with_zone (e_cal_component_datetime_get_value (dtstart), 
zone, default_zone);
-               str = e_datetime_format_format_tm ("calendar", "table",
-                       i_cal_time_is_date (e_cal_component_datetime_get_value (dtstart)) ? DTFormatKindDate 
: DTFormatKindDateTime,
-                       &tmp_tm);
-
-               if (str && *str) {
-                       /* Translators: This is followed by an event's start date/time */
-                       g_string_append (tmp2, _("Start: "));
-                       g_string_append (tmp2, str);
-               }
-
-               g_free (str);
-       }
-
-       if (dtdue && e_cal_component_datetime_get_value (dtdue)) {
-               gchar *str;
-
-               tmp_tm = e_cal_util_icaltime_to_tm_with_zone (e_cal_component_datetime_get_value (dtdue), 
zone, default_zone);
-               str = e_datetime_format_format_tm ("calendar", "table",
-                       i_cal_time_is_date (e_cal_component_datetime_get_value (dtdue)) ? DTFormatKindDate : 
DTFormatKindDateTime,
-                       &tmp_tm);
-
-               if (str && *str) {
-                       if (tmp2->len)
-                               g_string_append (tmp2, "; ");
-
-                       /* Translators: This is followed by an event's due date/time */
-                       g_string_append (tmp2, _("Due: "));
-                       g_string_append (tmp2, str);
-               }
-
-               g_free (str);
-       }
-
-       if (tmp2->len) {
-               l = gtk_label_new (tmp2->str);
-               gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5);
-               gtk_box_pack_start (GTK_BOX (w), l, FALSE, FALSE, 0);
-
-               gtk_widget_override_color (l, GTK_STATE_FLAG_NORMAL, &norm_text);
-       }
-
-       e_cal_component_datetime_free (dtstart);
-       e_cal_component_datetime_free (dtdue);
-
-       g_string_set_size (tmp2, 0);
-       desc = e_cal_component_get_descriptions (new_comp);
-       for (len = 0, p = desc; p != NULL; p = p->next) {
-               ECalComponentText *text = p->data;
-
-               if (text && e_cal_component_text_get_value (text)) {
-                       const gchar *value = e_cal_component_text_get_value (text);
-                       len += strlen (value);
-                       g_string_append (tmp2, value);
-                       if (len > 1024) {
-                               g_string_set_size (tmp2, 1020);
-                               g_string_append (tmp2, _("…"));
-                               break;
-                       }
-               }
-       }
-       g_slist_free_full (desc, e_cal_component_text_free);
-
-       if (tmp2->len) {
-               l = gtk_label_new (tmp2->str);
-               gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5);
-               gtk_box_pack_start (GTK_BOX (w), l, FALSE, FALSE, 0);
-
-               gtk_widget_override_color (l, GTK_STATE_FLAG_NORMAL, &norm_text);
-       }
-
-       g_string_free (tmp2, TRUE);
+       markup = cal_comp_util_dup_tooltip (new_comp, comp_data->client,
+               e_cal_model_get_registry (model),
+               e_cal_model_get_timezone (model));
 
-       gtk_widget_show_all (box);
-       gtk_tooltip_set_custom (tooltip, box);
+       gtk_tooltip_set_markup (tooltip, markup);
 
+       g_free (markup);
        g_object_unref (new_comp);
 
        if (esm && esm->sorter && e_sorter_needs_sorting (esm->sorter))
diff --git a/src/calendar/gui/e-task-table.c b/src/calendar/gui/e-task-table.c
index 7876d492e1..f5c35d2bf2 100644
--- a/src/calendar/gui/e-task-table.c
+++ b/src/calendar/gui/e-task-table.c
@@ -654,18 +654,9 @@ task_table_query_tooltip (GtkWidget *widget,
        ECalModel *model;
        ECalModelComponent *comp_data;
        gint row = -1, col = -1, row_y = -1, row_height = -1;
-       GtkWidget *box, *l, *w;
-       GdkRGBA sel_bg, sel_fg, norm_bg, norm_text;
-       gchar *tmp, *summary, *str;
-       GString *tmp2;
+       gchar *markup;
        ECalComponent *new_comp;
-       ECalComponentOrganizer *organizer;
-       ECalComponentDateTime *dtstart, *dtdue;
-       ICalTimezone *zone, *default_zone;
-       GSList *desc, *p;
-       gint len;
        ESelectionModel *esm;
-       struct tm tmp_tm;
 
        if (keyboard_mode)
                return FALSE;
@@ -692,226 +683,13 @@ task_table_query_tooltip (GtkWidget *widget,
        if (!new_comp)
                return FALSE;
 
-       e_utils_get_theme_color (widget, "theme_selected_bg_color", E_UTILS_DEFAULT_THEME_SELECTED_BG_COLOR, 
&sel_bg);
-       e_utils_get_theme_color (widget, "theme_selected_fg_color", E_UTILS_DEFAULT_THEME_SELECTED_FG_COLOR, 
&sel_fg);
-       e_utils_get_theme_color (widget, "theme_bg_color", E_UTILS_DEFAULT_THEME_BG_COLOR, &norm_bg);
-       e_utils_get_theme_color (widget, "theme_text_color,theme_fg_color", E_UTILS_DEFAULT_THEME_TEXT_COLOR, 
&norm_text);
-
-       box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
-
-       summary = e_calendar_view_dup_component_summary (comp_data->icalcomp);
-       if (!(summary && *summary)) {
-               g_free (summary);
-               summary = g_strdup (_("* No Summary *"));
-       }
-
-       l = gtk_label_new (NULL);
-       tmp = g_markup_printf_escaped ("<b>%s</b>", summary);
-       gtk_label_set_line_wrap (GTK_LABEL (l), TRUE);
-       gtk_label_set_width_chars (GTK_LABEL (l), 20);
-       gtk_label_set_markup (GTK_LABEL (l), tmp);
-       gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5);
-       w = gtk_event_box_new ();
-
-       gtk_widget_override_background_color (w, GTK_STATE_FLAG_NORMAL, &sel_bg);
-       gtk_widget_override_color (l, GTK_STATE_FLAG_NORMAL, &sel_fg);
-       gtk_container_add (GTK_CONTAINER (w), l);
-       gtk_box_pack_start (GTK_BOX (box), w, TRUE, TRUE, 0);
-       g_free (tmp);
-
-       g_free (summary);
-
-       w = gtk_event_box_new ();
-       gtk_widget_override_background_color (w, GTK_STATE_FLAG_NORMAL, &norm_bg);
-
-       l = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
-       gtk_container_add (GTK_CONTAINER (w), l);
-       gtk_box_pack_start (GTK_BOX (box), w, FALSE, FALSE, 0);
-       w = l;
-
-       organizer = e_cal_component_get_organizer (new_comp);
-       if (organizer && e_cal_component_organizer_get_cn (organizer)) {
-               const gchar *email;
-
-               email = itip_strip_mailto (e_cal_component_organizer_get_value (organizer));
-
-               if (email) {
-                       /* To Translators: It will display
-                        * "Organizer: NameOfTheUser <email ofuser com>" */
-                       tmp = g_strdup_printf (_("Organizer: %s <%s>"), e_cal_component_organizer_get_cn 
(organizer), email);
-               } else {
-                       /* With SunOne accounts, there may be no ':' in
-                        * organizer.value. */
-                       tmp = g_strdup_printf (_("Organizer: %s"), e_cal_component_organizer_get_cn 
(organizer));
-               }
-
-               l = gtk_label_new (tmp);
-               gtk_label_set_line_wrap (GTK_LABEL (l), FALSE);
-               gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5);
-               gtk_box_pack_start (GTK_BOX (w), l, FALSE, FALSE, 0);
-               g_free (tmp);
-
-               gtk_widget_override_color (l, GTK_STATE_FLAG_NORMAL, &norm_text);
-       }
-
-       e_cal_component_organizer_free (organizer);
-
-       str = e_cal_component_get_location (new_comp);
-
-       if (str) {
-               /* Translators: It will display "Location: PlaceOfTheMeeting" */
-               tmp = g_markup_printf_escaped (_("Location: %s"), str);
-               l = gtk_label_new (NULL);
-               gtk_widget_set_halign (l, GTK_ALIGN_START);
-               gtk_misc_set_alignment ((GtkMisc *) l, 0.0, 0.0);
-               gtk_label_set_markup ((GtkLabel *) l, tmp);
-               gtk_label_set_line_wrap ((GtkLabel *) l, TRUE);
-               gtk_label_set_width_chars (GTK_LABEL (l), 20);
-               gtk_label_set_max_width_chars ((GtkLabel *) l, 80);
-               gtk_box_pack_start (GTK_BOX (w), l, FALSE, FALSE, 0);
-               g_free (tmp);
-               g_free (str);
-       }
-
-       dtstart = e_cal_component_get_dtstart (new_comp);
-       dtdue = e_cal_component_get_due (new_comp);
-
-       default_zone = e_cal_model_get_timezone (model);
-
-       if (dtstart && e_cal_component_datetime_get_tzid (dtstart)) {
-               zone = i_cal_component_get_timezone (
-                       e_cal_component_get_icalcomponent (new_comp),
-                       e_cal_component_datetime_get_tzid (dtstart));
-               if (!zone) {
-                       if (!e_cal_client_get_timezone_sync (comp_data->client, 
e_cal_component_datetime_get_tzid (dtstart), &zone, NULL, NULL))
-                               zone = NULL;
-               }
-               if (!zone)
-                       zone = default_zone;
-       } else {
-               zone = NULL;
-       }
-
-       tmp2 = g_string_new ("");
-
-       if (dtstart && e_cal_component_datetime_get_value (dtstart)) {
-               gchar *str;
-
-               tmp_tm = e_cal_util_icaltime_to_tm_with_zone (e_cal_component_datetime_get_value (dtstart), 
zone, default_zone);
-               str = e_datetime_format_format_tm ("calendar", "table",
-                       i_cal_time_is_date (e_cal_component_datetime_get_value (dtstart)) ? DTFormatKindDate 
: DTFormatKindDateTime,
-                       &tmp_tm);
-
-               if (str && *str) {
-                       g_string_append (tmp2, _("Start: "));
-                       g_string_append (tmp2, str);
-               }
-
-               g_free (str);
-       }
-
-       if (dtdue && e_cal_component_datetime_get_tzid (dtdue)) {
-               zone = i_cal_component_get_timezone (
-                       e_cal_component_get_icalcomponent (new_comp),
-                       e_cal_component_datetime_get_tzid (dtdue));
-               if (!zone) {
-                       if (!e_cal_client_get_timezone_sync (comp_data->client, 
e_cal_component_datetime_get_tzid (dtdue), &zone, NULL, NULL))
-                               zone = NULL;
-               }
-               if (!zone)
-                       zone = default_zone;
-       } else {
-               zone = NULL;
-       }
-
-       if (dtdue && e_cal_component_datetime_get_value (dtdue)) {
-               gchar *str;
-
-               tmp_tm = e_cal_util_icaltime_to_tm_with_zone (e_cal_component_datetime_get_value (dtdue), 
zone, default_zone);
-               str = e_datetime_format_format_tm ("calendar", "table",
-                       i_cal_time_is_date (e_cal_component_datetime_get_value (dtdue)) ? DTFormatKindDate : 
DTFormatKindDateTime,
-                       &tmp_tm);
-
-               if (str && *str) {
-                       if (tmp2->len)
-                               g_string_append (tmp2, "; ");
-
-                       g_string_append (tmp2, _("Due: "));
-                       g_string_append (tmp2, str);
-               }
-
-               g_free (str);
-       }
-
-       if (tmp2->len) {
-               l = gtk_label_new (tmp2->str);
-               gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5);
-               gtk_box_pack_start (GTK_BOX (w), l, FALSE, FALSE, 0);
-
-               gtk_widget_override_color (l, GTK_STATE_FLAG_NORMAL, &norm_text);
-       }
-
-       g_string_free (tmp2, TRUE);
-
-       e_cal_component_datetime_free (dtstart);
-       e_cal_component_datetime_free (dtdue);
-
-       tmp = e_cal_model_get_attendees_status_info (
-               model, new_comp, comp_data->client);
-       if (tmp) {
-               l = gtk_label_new (tmp);
-               gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5);
-               gtk_box_pack_start (GTK_BOX (w), l, FALSE, FALSE, 0);
-
-               g_free (tmp);
-               tmp = NULL;
-
-               gtk_widget_override_color (l, GTK_STATE_FLAG_NORMAL, &norm_text);
-       }
-
-       tmp = cal_comp_util_get_attendee_comments (e_cal_component_get_icalcomponent (new_comp));
-       if (tmp) {
-               l = gtk_label_new (tmp);
-               gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5);
-               gtk_box_pack_start (GTK_BOX (w), l, FALSE, FALSE, 0);
-               gtk_widget_override_color (l, GTK_STATE_FLAG_NORMAL, &norm_text);
-
-               g_free (tmp);
-               tmp = NULL;
-       }
-
-       tmp2 = g_string_new ("");
-       desc = e_cal_component_get_descriptions (new_comp);
-       for (len = 0, p = desc; p != NULL; p = p->next) {
-               ECalComponentText *text = p->data;
-
-               if (text && e_cal_component_text_get_value (text)) {
-                       len += strlen (e_cal_component_text_get_value (text));
-                       g_string_append (tmp2, e_cal_component_text_get_value (text));
-                       if (len > 1024) {
-                               g_string_set_size (tmp2, 1023);
-                               g_string_append (tmp2, _("…"));
-                               break;
-                       }
-               }
-       }
-       g_slist_free_full (desc, e_cal_component_text_free);
-
-       if (tmp2->len) {
-               l = gtk_label_new (tmp2->str);
-               gtk_label_set_line_wrap (GTK_LABEL (l), TRUE);
-               gtk_label_set_width_chars (GTK_LABEL (l), 20);
-               gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5);
-               gtk_box_pack_start (GTK_BOX (w), l, FALSE, FALSE, 0);
-
-               gtk_widget_override_color (l, GTK_STATE_FLAG_NORMAL, &norm_text);
-       }
-
-       g_string_free (tmp2, TRUE);
+       markup = cal_comp_util_dup_tooltip (new_comp, comp_data->client,
+               e_cal_model_get_registry (model),
+               e_cal_model_get_timezone (model));
 
-       gtk_widget_show_all (box);
-       gtk_tooltip_set_custom (tooltip, box);
+       gtk_tooltip_set_markup (tooltip, markup);
 
+       g_free (markup);
        g_object_unref (new_comp);
 
        if (esm && esm->sorter && e_sorter_needs_sorting (esm->sorter))
diff --git a/src/calendar/gui/e-week-view.c b/src/calendar/gui/e-week-view.c
index 9018d00ded..499fdad1a6 100644
--- a/src/calendar/gui/e-week-view.c
+++ b/src/calendar/gui/e-week-view.c
@@ -1600,6 +1600,71 @@ week_view_cursor_key_right (EWeekView *week_view)
        gtk_widget_queue_draw (week_view->main_canvas);
 }
 
+static EWeekViewEvent *
+e_week_view_get_event (EWeekView *week_view,
+                      gint day,
+                      gint event_num)
+{
+       EWeekViewEvent *pevent;
+
+       if (!is_array_index_in_bounds (week_view->events, event_num))
+               return NULL;
+
+       pevent = &g_array_index (week_view->events, EWeekViewEvent, event_num);
+
+       return pevent;
+}
+
+static gboolean
+e_week_view_query_tooltip_cb (GtkWidget *widget,
+                             gint x,
+                             gint y,
+                             gboolean keyboard_mode,
+                             GtkTooltip *tooltip,
+                             gpointer user_data)
+{
+       EWeekView *week_view = user_data;
+       EWeekViewEvent *event;
+       ECalComponent *new_comp;
+       ECalModel *model;
+       GnomeCanvasItem *item;
+       gchar *markup;
+       gint event_num = -1, span_num = -1;
+
+       g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), FALSE);
+
+       if (keyboard_mode)
+               return FALSE;
+
+       item = gnome_canvas_get_item_at (GNOME_CANVAS (widget), x, y);
+       if (!item || !e_week_view_find_event_from_item (week_view, item, &event_num, &span_num))
+               event_num = -1;
+
+       if (event_num == -1)
+               return FALSE;
+
+       event = e_week_view_get_event (week_view, -1, event_num);
+       if (!event || !event->comp_data)
+               return FALSE;
+
+       new_comp = e_cal_component_new_from_icalcomponent (i_cal_component_clone 
(event->comp_data->icalcomp));
+       if (!new_comp)
+               return FALSE;
+
+       model = e_calendar_view_get_model (E_CALENDAR_VIEW (week_view));
+
+       markup = cal_comp_util_dup_tooltip (new_comp, event->comp_data->client,
+               e_cal_model_get_registry (model),
+               e_cal_model_get_timezone (model));
+
+       gtk_tooltip_set_markup (tooltip, markup);
+
+       g_free (markup);
+       g_object_unref (new_comp);
+
+       return TRUE;
+}
+
 static void
 e_week_view_class_init (EWeekViewClass *class)
 {
@@ -1803,6 +1868,7 @@ e_week_view_init (EWeekView *week_view)
                "vexpand", TRUE,
                "halign", GTK_ALIGN_FILL,
                "valign", GTK_ALIGN_FILL,
+               "has-tooltip", TRUE,
                NULL);
        gtk_widget_show (week_view->main_canvas);
 
@@ -1827,6 +1893,9 @@ e_week_view_init (EWeekView *week_view)
        g_signal_connect (
                week_view->main_canvas, "motion_notify_event",
                G_CALLBACK (e_week_view_on_motion), week_view);
+       g_signal_connect_object (
+               week_view->main_canvas, "query-tooltip",
+               G_CALLBACK (e_week_view_query_tooltip_cb), week_view, 0);
 
        /* Create the buttons to jump to each days. */
        pixbuf = gdk_pixbuf_new_from_xpm_data ((const gchar **) jump_xpm);
@@ -2745,31 +2814,6 @@ e_week_view_foreach_event_with_uid (EWeekView *week_view,
        }
 }
 
-static void
-e_week_view_maybe_destroy_event_tooltip (EWeekView *week_view,
-                                        EWeekViewEvent *event)
-{
-       GObject *object = G_OBJECT (week_view);
-
-       if (event->timeout > 0 && GPOINTER_TO_UINT (g_object_get_data (object, "tooltip-timeout")) == 
event->timeout) {
-               g_source_remove (event->timeout);
-               event->timeout = 0;
-
-               g_object_set_data (object, "tooltip-timeout", NULL);
-       } else {
-               event->timeout = 0;
-       }
-
-       if (event->tooltip && event->tooltip == g_object_get_data (object, "tooltip-window")) {
-               gtk_widget_destroy (event->tooltip);
-               event->tooltip = NULL;
-
-               g_object_set_data (object, "tooltip-window", NULL);
-       } else {
-               event->tooltip = NULL;
-       }
-}
-
 static gboolean
 e_week_view_remove_event_cb (EWeekView *week_view,
                              gint event_num,
@@ -2784,8 +2828,6 @@ e_week_view_remove_event_cb (EWeekView *week_view,
 
        event = &g_array_index (week_view->events, EWeekViewEvent, event_num);
 
-       e_week_view_maybe_destroy_event_tooltip (week_view, event);
-
        /* If we were editing this event, set editing_event_num to -1 so
         * on_editing_stopped doesn't try to update the event. */
        if (week_view->editing_event_num == event_num) {
@@ -3129,8 +3171,6 @@ e_week_view_on_scroll (GtkWidget *widget,
        gdouble upper;
        gdouble value;
 
-       e_calendar_view_destroy_tooltip (E_CALENDAR_VIEW (week_view));
-
        range = GTK_RANGE (week_view->vscrollbar);
        adjustment = gtk_range_get_adjustment (range);
 
@@ -3311,8 +3351,6 @@ e_week_view_free_events (EWeekView *week_view)
                event = &g_array_index (week_view->events, EWeekViewEvent,
                                        event_num);
 
-               e_week_view_maybe_destroy_event_tooltip (week_view, event);
-
                if (is_comp_data_valid (event))
                        g_object_unref (event->comp_data);
        }
@@ -3347,8 +3385,6 @@ e_week_view_free_events (EWeekView *week_view)
 
        if (did_editing)
                g_object_notify (G_OBJECT (week_view), "is-editing");
-
-       e_calendar_view_destroy_tooltip (E_CALENDAR_VIEW (week_view));
 }
 
 /* This adds one event to the view, adding it to the appropriate array. */
@@ -3364,7 +3400,6 @@ e_week_view_add_event (ECalClient *client,
        AddEventData *add_event_data;
        EWeekViewEvent event;
        gint num_days;
-       guint tooltip_timeout;
        ICalTime *start_tt, *end_tt;
 
        add_event_data = data;
@@ -3378,12 +3413,6 @@ e_week_view_add_event (ECalClient *client,
        if (end != start || end < add_event_data->week_view->day_starts[0])
                g_return_if_fail (end > add_event_data->week_view->day_starts[0]);
 
-       tooltip_timeout = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (add_event_data->week_view), 
"tooltip-timeout"));
-       if (tooltip_timeout) {
-               g_source_remove (tooltip_timeout);
-               g_object_set_data (G_OBJECT (add_event_data->week_view), "tooltip-timeout", NULL);
-       }
-
        start_tt = i_cal_time_new_from_timet_with_zone (
                start, FALSE,
                e_calendar_view_get_timezone (E_CALENDAR_VIEW (add_event_data->week_view)));
@@ -3403,8 +3432,6 @@ e_week_view_add_event (ECalClient *client,
 
        event.start = start;
        event.end = end;
-       event.tooltip = NULL;
-       event.timeout = -1;
        event.color = NULL;
        event.spans_index = 0;
        event.num_spans = 0;
@@ -3589,67 +3616,10 @@ e_week_view_reshape_events (EWeekView *week_view)
        }
 }
 
-static EWeekViewEvent *
-tooltip_get_view_event (EWeekView *week_view,
-                        gint day,
-                        gint event_num)
-{
-       EWeekViewEvent *pevent;
-
-       if (!is_array_index_in_bounds (week_view->events, event_num))
-               return NULL;
-
-       pevent = &g_array_index (week_view->events, EWeekViewEvent, event_num);
-
-       return pevent;
-}
-
-static void
-tooltip_destroy (EWeekView *week_view,
-                 GnomeCanvasItem *item)
-{
-       gint event_num;
-       EWeekViewEvent *pevent;
-
-       e_week_view_check_layout (week_view);
-
-       e_calendar_view_destroy_tooltip (E_CALENDAR_VIEW (week_view));
-
-       event_num = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "event-num"));
-       pevent = tooltip_get_view_event (week_view, -1, event_num);
-
-       if (pevent) {
-               pevent->tooltip = NULL;
-               pevent->timeout = 0;
-       }
-}
-
 static gboolean
-e_week_view_handle_tooltip_timeout (gpointer user_data)
-{
-       ECalendarViewEventData *data = user_data;
-
-       g_return_val_if_fail (data != NULL, FALSE);
-
-       return e_calendar_view_get_tooltips (data);
-}
-
-static void
-e_week_view_destroy_tooltip_timeout_data (gpointer ptr)
-{
-       ECalendarViewEventData *data = ptr;
-
-       if (data) {
-               g_object_set_data ((GObject *) data->cal_view, "tooltip-timeout", NULL);
-               g_object_unref (data->cal_view);
-               g_free (data);
-       }
-}
-
-static gboolean
-tooltip_event_cb (GnomeCanvasItem *item,
-                  GdkEvent *event,
-                  EWeekView *view)
+background_item_event_cb (GnomeCanvasItem *item,
+                         GdkEvent *event,
+                         EWeekView *view)
 {
        gint event_num;
        guint event_button = 0;
@@ -3658,32 +3628,15 @@ tooltip_event_cb (GnomeCanvasItem *item,
        e_week_view_check_layout (view);
 
        event_num = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "event-num"));
-       pevent = tooltip_get_view_event (view, -1, event_num);
+       pevent = e_week_view_get_event (view, -1, event_num);
 
        switch (event->type) {
                case GDK_ENTER_NOTIFY:
                if (view->editing_event_num == -1) {
-                       ECalendarViewEventData *data;
-
                        g_return_val_if_fail (pevent != NULL, FALSE);
 
-                       e_calendar_view_destroy_tooltip (E_CALENDAR_VIEW (view));
-
-                       data = g_malloc (sizeof (ECalendarViewEventData));
-
                        pevent->x = ((GdkEventCrossing *) event)->x_root;
                        pevent->y = ((GdkEventCrossing *) event)->y_root;
-                       pevent->tooltip = NULL;
-
-                       data->cal_view = E_CALENDAR_VIEW (g_object_ref (view));
-                       data->day = -1;
-                       data->event_num = event_num;
-                       data->get_view_event = (ECalendarViewEvent * (*)(ECalendarView *, int, gint)) 
tooltip_get_view_event;
-                       pevent->timeout = e_named_timeout_add_full (
-                               G_PRIORITY_DEFAULT, 500,
-                               e_week_view_handle_tooltip_timeout,
-                               data, e_week_view_destroy_tooltip_timeout_data);
-                       g_object_set_data ((GObject *) view, "tooltip-timeout", GUINT_TO_POINTER 
(pevent->timeout));
 
                        return TRUE;
                } else {
@@ -3694,17 +3647,11 @@ tooltip_event_cb (GnomeCanvasItem *item,
 
                        pevent->x = ((GdkEventMotion *) event)->x_root;
                        pevent->y = ((GdkEventMotion *) event)->y_root;
-                       pevent->tooltip = (GtkWidget *) g_object_get_data (G_OBJECT (view), "tooltip-window");
-
-                       if (pevent->tooltip) {
-                               e_calendar_view_move_tip (pevent->tooltip, pevent->x, pevent->y);
-                       }
 
                        return TRUE;
                case GDK_LEAVE_NOTIFY:
                case GDK_KEY_PRESS:
                case GDK_BUTTON_PRESS:
-                       tooltip_destroy (view, item);
                        if (gdk_event_get_button (event, &event_button) && event_button == 1)
                                e_week_view_set_popup_event (view, event_num);
 
@@ -3863,7 +3810,7 @@ e_week_view_reshape_event_span (EWeekView *week_view,
        g_object_set_data ((GObject *) span->background_item, "event-num", GINT_TO_POINTER (event_num));
        g_signal_connect (
                span->background_item, "event",
-               G_CALLBACK (tooltip_event_cb), week_view);
+               G_CALLBACK (background_item_event_cb), week_view);
 
        gnome_canvas_item_set (
                span->background_item,
@@ -4243,11 +4190,10 @@ e_week_view_on_text_item_event (GnomeCanvasItem *item,
        e_week_view_check_layout (week_view);
 
        nevent = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "event-num"));
-       pevent = tooltip_get_view_event (week_view, -1, nevent);
+       pevent = e_week_view_get_event (week_view, -1, nevent);
 
        switch (gdk_event->type) {
        case GDK_KEY_PRESS:
-               tooltip_destroy (week_view, item);
                gdk_event_get_keyval (gdk_event, &event_keyval);
 
                if (!E_TEXT (item)->preedit_len && (event_keyval == GDK_KEY_Return || event_keyval == 
GDK_KEY_KP_Enter)) {
@@ -4294,7 +4240,6 @@ e_week_view_on_text_item_event (GnomeCanvasItem *item,
                g_signal_stop_emission_by_name (item, "event");
                return TRUE;
        case GDK_BUTTON_PRESS:
-               tooltip_destroy (week_view, item);
                if (!e_week_view_find_event_from_item (week_view, item,
                                                       &event_num, &span_num))
                        return FALSE;
@@ -4381,7 +4326,6 @@ e_week_view_on_text_item_event (GnomeCanvasItem *item,
                break;
        case GDK_ENTER_NOTIFY:
        {
-               ECalendarViewEventData *data;
                gint nspan;
 
                if (week_view->editing_event_num != -1
@@ -4390,35 +4334,18 @@ e_week_view_on_text_item_event (GnomeCanvasItem *item,
 
                g_object_set_data ((GObject *) item, "event-num", GINT_TO_POINTER (nevent));
 
-               pevent = tooltip_get_view_event (week_view, -1, nevent);
+               pevent = e_week_view_get_event (week_view, -1, nevent);
                g_return_val_if_fail (pevent != NULL, FALSE);
 
-               e_calendar_view_destroy_tooltip (E_CALENDAR_VIEW (week_view));
-
-               data = g_malloc (sizeof (ECalendarViewEventData));
-
                gdk_event_get_root_coords (
                        gdk_event, &event_x_root, &event_y_root);
 
                pevent->x = (gint) event_x_root;
                pevent->y = (gint) event_y_root;
-               pevent->tooltip = NULL;
-
-               data->cal_view = E_CALENDAR_VIEW (g_object_ref (week_view));
-               data->day = -1;
-               data->event_num = nevent;
-               data->get_view_event = (ECalendarViewEvent * (*)(ECalendarView *, int, gint)) 
tooltip_get_view_event;
-               pevent->timeout = e_named_timeout_add_full (
-                       G_PRIORITY_DEFAULT, 500,
-                       e_week_view_handle_tooltip_timeout,
-                       data, e_week_view_destroy_tooltip_timeout_data);
-               g_object_set_data ((GObject *) week_view, "tooltip-timeout", GUINT_TO_POINTER 
(pevent->timeout));
 
                return TRUE;
        }
        case GDK_LEAVE_NOTIFY:
-               tooltip_destroy (week_view, item);
-
                return FALSE;
        case GDK_MOTION_NOTIFY:
                g_return_val_if_fail (pevent != NULL, FALSE);
@@ -4428,11 +4355,6 @@ e_week_view_on_text_item_event (GnomeCanvasItem *item,
 
                pevent->x = (gint) event_x_root;
                pevent->y = (gint) event_y_root;
-               pevent->tooltip = (GtkWidget *) g_object_get_data (G_OBJECT (week_view), "tooltip-window");
-
-               if (pevent->tooltip) {
-                       e_calendar_view_move_tip (pevent->tooltip, pevent->x, pevent->y);
-               }
                return TRUE;
        case GDK_FOCUS_CHANGE:
                if (gdk_event->focus_change.in) {
@@ -5192,8 +5114,6 @@ e_week_view_show_popup_menu (EWeekView *week_view,
                              GdkEvent *button_event,
                              gint event_num)
 {
-       e_calendar_view_destroy_tooltip (E_CALENDAR_VIEW (week_view));
-
        e_week_view_set_popup_event (week_view, event_num);
 
        e_calendar_view_popup_event (E_CALENDAR_VIEW (week_view), button_event);
diff --git a/src/modules/calendar/e-cal-shell-content.c b/src/modules/calendar/e-cal-shell-content.c
index e8d159e80c..d9ab9fa2ed 100644
--- a/src/modules/calendar/e-cal-shell-content.c
+++ b/src/modules/calendar/e-cal-shell-content.c
@@ -2280,8 +2280,6 @@ e_cal_shell_content_set_current_view_id (ECalShellContent *cal_shell_content,
                        start_time = -1;
                        end_time = -1;
                }
-
-               e_calendar_view_destroy_tooltip (cal_view);
        }
 
        cal_shell_content->priv->previous_selected_start_time = start_time;


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