diff options
author | Damon Chaplin <damon@helixcode.com> | 2000-05-06 18:43:14 +0800 |
---|---|---|
committer | Damon Chaplin <damon@src.gnome.org> | 2000-05-06 18:43:14 +0800 |
commit | 10ee8953e2d461f3164cbc32784af1ab887aa0c7 (patch) | |
tree | e4604f9a32f3e0b569e566216d4d2a969734a23d | |
parent | 154973985a05b17e29e1588adccaee0c17dd11d5 (diff) | |
download | gsoc2013-evolution-10ee8953e2d461f3164cbc32784af1ab887aa0c7.tar.gz gsoc2013-evolution-10ee8953e2d461f3164cbc32784af1ab887aa0c7.tar.zst gsoc2013-evolution-10ee8953e2d461f3164cbc32784af1ab887aa0c7.zip |
added guint ref_count to iCalObject struct, and ical_object_ref/unref()
2000-05-06 Damon Chaplin <damon@helixcode.com>
* cal-util/calobj.[hc]: added guint ref_count to iCalObject struct,
and ical_object_ref/unref() functions. I've updated all the gui/
stuff to use ref_counts but I haven't touched the pcs/ stuff. Maybe
just using ical_object_destroy() is OK there.
* gui/gncal-todo.c:
* gui/calendar-commands.c:
* gui/eventedit.c:
* gui/e-week-view.c:
* gui/e-day-view.c: use refcounting for iCalObjects.
* gui/e-day-view-main-item.c:
* gui/e-day-view-top-item.c:
* gui/e-day-view.c: try not to ever draw outside the event, even when
the event is very small.
2000-05-05 Damon Chaplin <damon@helixcode.com>
* gui/e-day-view.c: don't allow recurring events to be resized or
dragged, and don't show the resize/drag cursors. Actually it may be
better to let the user do the resize/drag and then ask them what they
want to do - change the single occurrence or the entire series.
* gui/e-day-view-time-item.c (e_day_view_time_item_show_popup_menu):
use e_auto_kill_popup_menu_on_hide() to destroy the popup menu.
* gui/popup-menu.c: include e-gui-utils.h
svn path=/trunk/; revision=2823
-rw-r--r-- | calendar/ChangeLog | 30 | ||||
-rw-r--r-- | calendar/cal-util/calobj.c | 21 | ||||
-rw-r--r-- | calendar/cal-util/calobj.h | 11 | ||||
-rw-r--r-- | calendar/gui/calendar-commands.c | 18 | ||||
-rw-r--r-- | calendar/gui/e-day-view-main-item.c | 33 | ||||
-rw-r--r-- | calendar/gui/e-day-view-time-item.c | 6 | ||||
-rw-r--r-- | calendar/gui/e-day-view-top-item.c | 37 | ||||
-rw-r--r-- | calendar/gui/e-day-view.c | 159 | ||||
-rw-r--r-- | calendar/gui/e-week-view.c | 37 | ||||
-rw-r--r-- | calendar/gui/eventedit.c | 15 | ||||
-rw-r--r-- | calendar/gui/gncal-todo.c | 12 | ||||
-rw-r--r-- | calendar/gui/popup-menu.c | 3 |
12 files changed, 292 insertions, 90 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog index b5368b16a1..397b9c43d8 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,33 @@ +2000-05-06 Damon Chaplin <damon@helixcode.com> + + * cal-util/calobj.[hc]: added guint ref_count to iCalObject struct, + and ical_object_ref/unref() functions. I've updated all the gui/ + stuff to use ref_counts but I haven't touched the pcs/ stuff. Maybe + just using ical_object_destroy() is OK there. + + * gui/gncal-todo.c: + * gui/calendar-commands.c: + * gui/eventedit.c: + * gui/e-week-view.c: + * gui/e-day-view.c: use refcounting for iCalObjects. + + * gui/e-day-view-main-item.c: + * gui/e-day-view-top-item.c: + * gui/e-day-view.c: try not to ever draw outside the event, even when + the event is very small. + +2000-05-05 Damon Chaplin <damon@helixcode.com> + + * gui/e-day-view.c: don't allow recurring events to be resized or + dragged, and don't show the resize/drag cursors. Actually it may be + better to let the user do the resize/drag and then ask them what they + want to do - change the single occurrence or the entire series. + + * gui/e-day-view-time-item.c (e_day_view_time_item_show_popup_menu): + use e_auto_kill_popup_menu_on_hide() to destroy the popup menu. + + * gui/popup-menu.c: include e-gui-utils.h + 2000-05-04 Damon Chaplin <damon@helixcode.com> * gui/e-day-view.c (e_day_view_foreach_event_with_uid): for the long diff --git a/calendar/cal-util/calobj.c b/calendar/cal-util/calobj.c index cc9c1636c7..9691d31c11 100644 --- a/calendar/cal-util/calobj.c +++ b/calendar/cal-util/calobj.c @@ -66,6 +66,8 @@ ical_object_new (void) ico->pilot_id = 0; ico->pilot_status = ICAL_PILOT_SYNC_MOD; + ico->ref_count = 1; + return ico; } @@ -91,6 +93,23 @@ ical_new (char *comment, char *organizer, char *summary) return ico; } + +void +ical_object_ref (iCalObject *ico) +{ + ico->ref_count++; +} + + +void +ical_object_unref (iCalObject *ico) +{ + ico->ref_count--; + if (ico->ref_count == 0) + ical_object_destroy (ico); +} + + static void my_free (gpointer data, gpointer user_dat_ignored) { @@ -588,6 +607,8 @@ ical_object_create_from_vobject (VObject *o, const char *object_name) return 0; } + ical->ref_count = 1; + /* uid */ if (has (o, VCUniqueStringProp)){ ical->uid = g_strdup (str_val (vo)); diff --git a/calendar/cal-util/calobj.h b/calendar/cal-util/calobj.h index 25954b8098..e44b2ad7b1 100644 --- a/calendar/cal-util/calobj.h +++ b/calendar/cal-util/calobj.h @@ -221,6 +221,8 @@ typedef struct { /* Pilot */ iCalPilotState pilot_status; /* Status information */ guint32 pilot_id; /* Pilot ID */ + + guint ref_count; } iCalObject; /* The callback for the recurrence generator */ @@ -228,7 +230,16 @@ typedef int (*calendarfn) (iCalObject *, time_t, time_t, void *); iCalObject *ical_new (char *comment, char *organizer, char *summary); iCalObject *ical_object_new (void); + +/* iCalObjects are created with a refcount of 1. When it drops to 0 it is + destroyed with ical_object_destroy(). To maintain backwards compatability + ical_object_destroy() can still be used, though code which uses it should + not be mixed with code that uses refcounts. */ +void ical_object_ref (iCalObject *ico); +void ical_object_unref (iCalObject *ico); + void ical_object_destroy (iCalObject *ico); + iCalObject *ical_object_create_from_vobject (VObject *obj, const char *object_name); VObject *ical_object_to_vobject (iCalObject *ical); iCalObject *ical_object_duplicate (iCalObject *o); diff --git a/calendar/gui/calendar-commands.c b/calendar/gui/calendar-commands.c index 87d63140dd..22b716b97d 100644 --- a/calendar/gui/calendar-commands.c +++ b/calendar/gui/calendar-commands.c @@ -96,6 +96,10 @@ CalendarAlarm alarm_defaults[4] = { }; +static void calendar_iterate_free_cache_entry (gpointer key, + gpointer value, + gpointer user_data); + static void init_username (void) { @@ -863,12 +867,22 @@ calendar_iterate (GnomeCalendar *cal, g_list_free (cois); - /* Note that we don't need to free the hash keys since they are part - of the iCalObjects. */ + /* We need to unref all the iCalObjects in the cache now. The callback + function should have ref'd any of them it wants to keep. */ + g_hash_table_foreach (cache, calendar_iterate_free_cache_entry, NULL); + g_hash_table_destroy (cache); } +static void +calendar_iterate_free_cache_entry (gpointer key, + gpointer value, + gpointer user_data) +{ + ical_object_unref ((iCalObject*) value); +} + static gint calendar_object_compare_by_start (gconstpointer a, gconstpointer b) diff --git a/calendar/gui/e-day-view-main-item.c b/calendar/gui/e-day-view-main-item.c index 2ce8f9201f..629d2bd42c 100644 --- a/calendar/gui/e-day-view-main-item.c +++ b/calendar/gui/e-day-view-main-item.c @@ -447,6 +447,7 @@ e_day_view_main_item_draw_day_event (EDayViewMainItem *dvmitem, GdkGC *gc; iCalObject *ico; gint num_icons, icon_x, icon_y, icon_x_inc, icon_y_inc; + gint max_icon_w, max_icon_h; gboolean draw_reminder_icon, draw_recurrence_icon; day_view = dvmitem->day_view; @@ -475,20 +476,20 @@ e_day_view_main_item_draw_day_event (EDayViewMainItem *dvmitem, event_num); /* Fill in the white background. Note that for events in the first - column of the day, we might not want topaint over the vertical bar, + column of the day, we might not want to paint over the vertical bar, since that is used for multiple events. But then you can't see where the event in the first column finishes. */ #if 0 if (event->start_row_or_col == 0) gdk_draw_rectangle (drawable, style->white_gc, TRUE, item_x + E_DAY_VIEW_BAR_WIDTH, item_y + 1, - item_w - E_DAY_VIEW_BAR_WIDTH - 1, + MAX (item_w - E_DAY_VIEW_BAR_WIDTH - 1, 0), item_h - 2); else #endif gdk_draw_rectangle (drawable, style->white_gc, TRUE, item_x + 1, item_y + 1, - item_w - 2, item_h - 2); + MAX (item_w - 2, 0), item_h - 2); /* Draw the right edge of the vertical bar. */ gdk_draw_line (drawable, style->black_gc, @@ -520,7 +521,7 @@ e_day_view_main_item_draw_day_event (EDayViewMainItem *dvmitem, the colored bar so we don't have to worry about being 1 pixel out. */ gdk_draw_rectangle (drawable, style->black_gc, FALSE, - item_x, item_y, item_w - 1, item_h - 1); + item_x, item_y, MAX (item_w - 1, 0), item_h - 1); #if 0 /* Draw the horizontal bars above and beneath the event if it @@ -571,32 +572,46 @@ e_day_view_main_item_draw_day_event (EDayViewMainItem *dvmitem, } if (draw_reminder_icon) { + max_icon_w = item_x + item_w - icon_x + - E_DAY_VIEW_EVENT_BORDER_WIDTH; + max_icon_h = item_y + item_h - icon_y + - E_DAY_VIEW_EVENT_BORDER_HEIGHT; + gdk_gc_set_clip_origin (gc, icon_x, icon_y); gdk_gc_set_clip_mask (gc, day_view->reminder_mask); gdk_draw_pixmap (drawable, gc, day_view->reminder_icon, 0, 0, icon_x, icon_y, - E_DAY_VIEW_ICON_WIDTH, - E_DAY_VIEW_ICON_HEIGHT); + MIN (E_DAY_VIEW_ICON_WIDTH, + max_icon_w), + MIN (E_DAY_VIEW_ICON_HEIGHT, + max_icon_h)); icon_x += icon_x_inc; icon_y += icon_y_inc; } if (draw_recurrence_icon) { + max_icon_w = item_x + item_w - icon_x + - E_DAY_VIEW_EVENT_BORDER_WIDTH; + max_icon_h = item_y + item_h - icon_y + - E_DAY_VIEW_EVENT_BORDER_HEIGHT; + gdk_gc_set_clip_origin (gc, icon_x, icon_y); gdk_gc_set_clip_mask (gc, day_view->recurrence_mask); gdk_draw_pixmap (drawable, gc, day_view->recurrence_icon, 0, 0, icon_x, icon_y, - E_DAY_VIEW_ICON_WIDTH, - E_DAY_VIEW_ICON_HEIGHT); + MIN (E_DAY_VIEW_ICON_WIDTH, + max_icon_w), + MIN (E_DAY_VIEW_ICON_HEIGHT, + max_icon_h)); } gdk_gc_set_clip_mask (gc, NULL); } } -/* This is supposed to return the nearest item the the point and the distance. +/* This is supposed to return the nearest item to the point and the distance. Since we are the only item we just return ourself and 0 for the distance. This is needed so that we get button/motion events. */ static double diff --git a/calendar/gui/e-day-view-time-item.c b/calendar/gui/e-day-view-time-item.c index 149da55830..a3b1c35dd3 100644 --- a/calendar/gui/e-day-view-time-item.c +++ b/calendar/gui/e-day-view-time-item.c @@ -31,6 +31,7 @@ #include <gtk/gtkmenu.h> #include <gtk/gtkradiomenuitem.h> #include "e-day-view-time-item.h" +#include "../../e-util/e-gui-utils.h" /* The spacing between items in the time column. GRID_X_PAD is the space down @@ -369,6 +370,9 @@ e_day_view_time_item_show_popup_menu (EDayViewTimeItem *dvtmitem, menu = gtk_menu_new (); + /* Make sure the menu is destroyed when it disappears. */ + e_auto_kill_popup_menu_on_hide (GTK_MENU (menu)); + for (i = 0; i < num_divisions; i++) { sprintf (buffer, _("%02i minute divisions"), divisions[i]); item = gtk_radio_menu_item_new_with_label (group, buffer); @@ -389,8 +393,6 @@ e_day_view_time_item_show_popup_menu (EDayViewTimeItem *dvtmitem, gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, event->button.button, event->button.time); - - /* FIXME: Use e-util function to destroy menu when hidden. */ } diff --git a/calendar/gui/e-day-view-top-item.c b/calendar/gui/e-day-view-top-item.c index ac2d6bfb62..8e084f4d42 100644 --- a/calendar/gui/e-day-view-top-item.c +++ b/calendar/gui/e-day-view-top-item.c @@ -330,8 +330,9 @@ e_day_view_top_item_draw_long_event (EDayViewTopItem *dvtitem, gint text_x, icon_x, icon_y, icon_x_inc; iCalObject *ico; gchar buffer[16]; - gint hour, minute, offset, time_width; + gint hour, minute, offset, time_width, time_x, min_end_time_x; gboolean draw_start_triangle, draw_end_triangle; + GdkRectangle clip_rect; day_view = dvtitem->day_view; @@ -456,30 +457,50 @@ e_day_view_top_item_draw_long_event (EDayViewTopItem *dvtitem, /* Draw the start & end times, if necessary. Note that GtkLabel adds 1 to the ascent so we must do that to be level with it. */ + min_end_time_x = item_x + E_DAY_VIEW_LONG_EVENT_X_PAD - x; + if (event->start > day_view->day_starts[start_day]) { offset = day_view->first_hour_shown * 60 + day_view->first_minute_shown + event->start_minute; hour = offset / 60; minute = offset % 60; sprintf (buffer, "%02i:%02i", hour, minute); + + clip_rect.x = item_x - x; + clip_rect.y = item_y - y; + clip_rect.width = item_w - E_DAY_VIEW_LONG_EVENT_BORDER_WIDTH; + clip_rect.height = item_h; + gdk_gc_set_clip_rectangle (fg_gc, &clip_rect); + gdk_draw_string (drawable, font, fg_gc, - item_x + + E_DAY_VIEW_LONG_EVENT_X_PAD - x, + item_x + E_DAY_VIEW_LONG_EVENT_X_PAD - x, item_y + E_DAY_VIEW_LONG_EVENT_Y_PAD + font->ascent + 1 - y, buffer); + + gdk_gc_set_clip_rectangle (fg_gc, NULL); + + min_end_time_x += day_view->small_hour_widths[hour] + 2 + + day_view->max_minute_width + day_view->colon_width; } if (event->end < day_view->day_starts[end_day + 1]) { offset = day_view->first_hour_shown * 60 - + day_view->first_minute_shown + event->end_minute; + + day_view->first_minute_shown + + event->end_minute; hour = offset / 60; minute = offset % 60; - sprintf (buffer, "%02i:%02i", hour, minute); time_width = day_view->small_hour_widths[hour] + day_view->max_minute_width + day_view->colon_width; - gdk_draw_string (drawable, font, fg_gc, - item_x + item_w - E_DAY_VIEW_LONG_EVENT_X_PAD - time_width - E_DAY_VIEW_LONG_EVENT_TIME_X_PAD - x, - item_y + E_DAY_VIEW_LONG_EVENT_Y_PAD + font->ascent + 1 - y, - buffer); + time_x = item_x + item_w - E_DAY_VIEW_LONG_EVENT_X_PAD - time_width - E_DAY_VIEW_LONG_EVENT_TIME_X_PAD - x; + + if (time_x >= min_end_time_x) { + sprintf (buffer, "%02i:%02i", hour, minute); + gdk_draw_string (drawable, font, fg_gc, + time_x, + item_y + E_DAY_VIEW_LONG_EVENT_Y_PAD + + font->ascent + 1 - y, + buffer); + } } } diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c index 655afd73dc..9524f26807 100644 --- a/calendar/gui/e-day-view.c +++ b/calendar/gui/e-day-view.c @@ -1122,7 +1122,7 @@ e_day_view_update_event (EDayView *day_view, switch (status) { case CAL_OBJ_FIND_SUCCESS: - /* Fall through. */ + /* Do nothing. */ break; case CAL_OBJ_FIND_SYNTAX_ERROR: g_warning ("syntax error uid=%s\n", uid); @@ -1133,8 +1133,10 @@ e_day_view_update_event (EDayView *day_view, } /* We only care about events. */ - if (ico && ico->type != ICAL_EVENT) + if (ico && ico->type != ICAL_EVENT) { + ical_object_unref (ico); return; + } /* If the event already exists and the dates didn't change, we can update the event fairly easily without changing the events arrays @@ -1151,6 +1153,7 @@ e_day_view_update_event (EDayView *day_view, if (ical_object_compare_dates (event->ico, ico)) { g_print (" unchanged dates\n"); e_day_view_foreach_event_with_uid (day_view, uid, e_day_view_update_event_cb, ico); + ical_object_unref (ico); gtk_widget_queue_draw (day_view->top_canvas); gtk_widget_queue_draw (day_view->main_canvas); return; @@ -1168,6 +1171,7 @@ e_day_view_update_event (EDayView *day_view, g_print (" generating events\n"); ical_object_generate_events (ico, day_view->lower, day_view->upper, e_day_view_add_event, day_view); + ical_object_unref (ico); e_day_view_check_layout (day_view); @@ -1190,17 +1194,18 @@ e_day_view_update_event_cb (EDayView *day_view, g_print ("In e_day_view_update_event_cb day:%i event_num:%i\n", day, event_num); - /* FIXME: When do ico's get freed? */ if (day == E_DAY_VIEW_LONG_EVENT) { event = &g_array_index (day_view->long_events, EDayViewEvent, event_num); - event->ico = ico; } else { event = &g_array_index (day_view->events[day], EDayViewEvent, event_num); - event->ico = ico; } + ical_object_unref (event->ico); + event->ico = ico; + ical_object_ref (ico); + /* If we are editing an event which we have just created, we will get an update_event callback from the server. But we need to ignore it or we will lose the text the user has already typed in. */ @@ -1239,7 +1244,7 @@ e_day_view_foreach_event_with_uid (EDayView *day_view, event_num--) { event = &g_array_index (day_view->events[day], EDayViewEvent, event_num); - if (event->ico && event->ico->uid + if (event->ico->uid && !strcmp (uid, event->ico->uid)) { if (!(*callback) (day_view, day, event_num, data)) @@ -1253,7 +1258,7 @@ e_day_view_foreach_event_with_uid (EDayView *day_view, event_num--) { event = &g_array_index (day_view->long_events, EDayViewEvent, event_num); - if (event->ico && event->ico->uid + if (event->ico->uid && !strcmp (uid, event->ico->uid)) { if (!(*callback) (day_view, E_DAY_VIEW_LONG_EVENT, event_num, data)) @@ -1308,6 +1313,7 @@ e_day_view_remove_event_cb (EDayView *day_view, if (event->canvas_item) gtk_object_destroy (GTK_OBJECT (event->canvas_item)); + ical_object_unref (event->ico); if (day == E_DAY_VIEW_LONG_EVENT) { g_array_remove_index (day_view->long_events, event_num); @@ -1442,7 +1448,7 @@ e_day_view_find_event_from_uid (EDayView *day_view, event_num++) { event = &g_array_index (day_view->events[day], EDayViewEvent, event_num); - if (event->ico && event->ico->uid + if (event->ico->uid && !strcmp (uid, event->ico->uid)) { *day_return = day; *event_num_return = event_num; @@ -1455,7 +1461,7 @@ e_day_view_find_event_from_uid (EDayView *day_view, event_num++) { event = &g_array_index (day_view->long_events, EDayViewEvent, event_num); - if (event->ico && event->ico->uid + if (event->ico->uid && !strcmp (uid, event->ico->uid)) { *day_return = E_DAY_VIEW_LONG_EVENT; *event_num_return = event_num; @@ -2010,8 +2016,9 @@ e_day_view_on_long_event_click (EDayView *day_view, && E_TEXT (event->canvas_item)->editing) return; - if (pos == E_DAY_VIEW_POS_LEFT_EDGE - || pos == E_DAY_VIEW_POS_RIGHT_EDGE) { + if (!event->ico->recur + && (pos == E_DAY_VIEW_POS_LEFT_EDGE + || pos == E_DAY_VIEW_POS_RIGHT_EDGE)) { if (!e_day_view_find_long_event_days (day_view, event, &start_day, &end_day)) return; @@ -2081,8 +2088,9 @@ e_day_view_on_event_click (EDayView *day_view, && E_TEXT (event->canvas_item)->editing) return; - if (pos == E_DAY_VIEW_POS_TOP_EDGE - || pos == E_DAY_VIEW_POS_BOTTOM_EDGE) { + if (!event->ico->recur + && (pos == E_DAY_VIEW_POS_TOP_EDGE + || pos == E_DAY_VIEW_POS_BOTTOM_EDGE)) { /* Grab the keyboard focus, so the event being edited is saved and we can use the Escape key to abort the resize. */ if (!GTK_WIDGET_HAS_FOCUS (day_view)) @@ -2316,6 +2324,7 @@ e_day_view_on_new_appointment (GtkWidget *widget, gpointer data) e_day_view_get_selected_time_range (day_view, &ico->dtstart, &ico->dtend); event_editor = event_editor_new (day_view->calendar, ico); + ical_object_unref (ico); gtk_widget_show (event_editor); } @@ -2339,6 +2348,7 @@ e_day_view_on_edit_appointment (GtkWidget *widget, gpointer data) ico = ical_object_duplicate (event->ico); event_editor = event_editor_new (day_view->calendar, ico); + ical_object_unref (ico); gtk_widget_show (event_editor); } @@ -2408,6 +2418,8 @@ e_day_view_on_unrecur_appointment (GtkWidget *widget, gpointer data) gnome_calendar_object_changed (day_view->calendar, event->ico, CHANGE_ALL); gnome_calendar_add_object (day_view->calendar, ico); + + ical_object_unref (ico); } @@ -2496,6 +2508,7 @@ e_day_view_on_top_canvas_motion (GtkWidget *widget, GdkEventMotion *mevent, EDayView *day_view) { + EDayViewEvent *event = NULL; EDayViewPosition pos; gint event_x, event_y, scroll_x, scroll_y, canvas_x, canvas_y; gint day, event_num; @@ -2521,6 +2534,9 @@ e_day_view_on_top_canvas_motion (GtkWidget *widget, pos = e_day_view_convert_position_in_top_canvas (day_view, canvas_x, canvas_y, &day, &event_num); + if (event_num != -1) + event = &g_array_index (day_view->long_events, EDayViewEvent, + event_num); if (day_view->selection_drag_pos != E_DAY_VIEW_DRAG_NONE) { e_day_view_update_selection (day_view, -1, day); @@ -2533,12 +2549,24 @@ e_day_view_on_top_canvas_motion (GtkWidget *widget, } else if (day_view->pressed_event_day == E_DAY_VIEW_LONG_EVENT) { GtkTargetList *target_list; - if (abs (canvas_x - day_view->drag_event_x) > E_DAY_VIEW_DRAG_START_OFFSET - || abs (canvas_y - day_view->drag_event_y) > E_DAY_VIEW_DRAG_START_OFFSET) { + event = &g_array_index (day_view->long_events, EDayViewEvent, + day_view->pressed_event_num); + + if (!event->ico->recur + && (abs (canvas_x - day_view->drag_event_x) > E_DAY_VIEW_DRAG_START_OFFSET + || abs (canvas_y - day_view->drag_event_y) > E_DAY_VIEW_DRAG_START_OFFSET)) { day_view->drag_event_day = day_view->pressed_event_day; day_view->drag_event_num = day_view->pressed_event_num; day_view->pressed_event_day = -1; + /* Hide the horizontal bars. */ + if (day_view->resize_bars_event_day != -1) { + day_view->resize_bars_event_day = -1; + day_view->resize_bars_event_num = -1; + gnome_canvas_item_hide (day_view->main_canvas_top_resize_bar_item); + gnome_canvas_item_hide (day_view->main_canvas_bottom_resize_bar_item); + } + target_list = gtk_target_list_new (target_table, n_targets); gtk_drag_begin (widget, target_list, @@ -2548,14 +2576,19 @@ e_day_view_on_top_canvas_motion (GtkWidget *widget, } } else { cursor = day_view->normal_cursor; - switch (pos) { - case E_DAY_VIEW_POS_LEFT_EDGE: - case E_DAY_VIEW_POS_RIGHT_EDGE: - cursor = day_view->resize_width_cursor; - break; - default: - break; + + /* Recurring events can't be resized. */ + if (event && !event->ico->recur) { + switch (pos) { + case E_DAY_VIEW_POS_LEFT_EDGE: + case E_DAY_VIEW_POS_RIGHT_EDGE: + cursor = day_view->resize_width_cursor; + break; + default: + break; + } } + /* Only set the cursor if it is different to last one set. */ if (day_view->last_cursor_set_in_top_canvas != cursor) { day_view->last_cursor_set_in_top_canvas = cursor; @@ -2573,6 +2606,7 @@ e_day_view_on_main_canvas_motion (GtkWidget *widget, GdkEventMotion *mevent, EDayView *day_view) { + EDayViewEvent *event = NULL; EDayViewPosition pos; gint event_x, event_y, scroll_x, scroll_y, canvas_x, canvas_y; gint row, day, event_num; @@ -2601,6 +2635,9 @@ e_day_view_on_main_canvas_motion (GtkWidget *widget, canvas_x, canvas_y, &day, &row, &event_num); + if (event_num != -1) + event = &g_array_index (day_view->events[day], EDayViewEvent, + event_num); if (day_view->selection_drag_pos != E_DAY_VIEW_DRAG_NONE) { if (pos != E_DAY_VIEW_POS_OUTSIDE) { @@ -2614,15 +2651,27 @@ e_day_view_on_main_canvas_motion (GtkWidget *widget, e_day_view_check_auto_scroll (day_view, event_y); return TRUE; } - } else if (day_view->pressed_event_day != -1) { + } else if (day_view->pressed_event_day != -1 + && day_view->pressed_event_day != E_DAY_VIEW_LONG_EVENT) { GtkTargetList *target_list; - if (abs (canvas_x - day_view->drag_event_x) > E_DAY_VIEW_DRAG_START_OFFSET - || abs (canvas_y - day_view->drag_event_y) > E_DAY_VIEW_DRAG_START_OFFSET) { + event = &g_array_index (day_view->events[day_view->pressed_event_day], EDayViewEvent, day_view->pressed_event_num); + + if (!event->ico->recur + && (abs (canvas_x - day_view->drag_event_x) > E_DAY_VIEW_DRAG_START_OFFSET + || abs (canvas_y - day_view->drag_event_y) > E_DAY_VIEW_DRAG_START_OFFSET)) { day_view->drag_event_day = day_view->pressed_event_day; day_view->drag_event_num = day_view->pressed_event_num; day_view->pressed_event_day = -1; + /* Hide the horizontal bars. */ + if (day_view->resize_bars_event_day != -1) { + day_view->resize_bars_event_day = -1; + day_view->resize_bars_event_num = -1; + gnome_canvas_item_hide (day_view->main_canvas_top_resize_bar_item); + gnome_canvas_item_hide (day_view->main_canvas_bottom_resize_bar_item); + } + target_list = gtk_target_list_new (target_table, n_targets); gtk_drag_begin (widget, target_list, @@ -2632,17 +2681,22 @@ e_day_view_on_main_canvas_motion (GtkWidget *widget, } } else { cursor = day_view->normal_cursor; - switch (pos) { - case E_DAY_VIEW_POS_LEFT_EDGE: - cursor = day_view->move_cursor; - break; - case E_DAY_VIEW_POS_TOP_EDGE: - case E_DAY_VIEW_POS_BOTTOM_EDGE: - cursor = day_view->resize_height_cursor; - break; - default: - break; + + /* Recurring events can't be resized. */ + if (event && !event->ico->recur) { + switch (pos) { + case E_DAY_VIEW_POS_LEFT_EDGE: + cursor = day_view->move_cursor; + break; + case E_DAY_VIEW_POS_TOP_EDGE: + case E_DAY_VIEW_POS_BOTTOM_EDGE: + cursor = day_view->resize_height_cursor; + break; + default: + break; + } } + /* Only set the cursor if it is different to last one set. */ if (day_view->last_cursor_set_in_main_canvas != cursor) { day_view->last_cursor_set_in_main_canvas = cursor; @@ -2959,6 +3013,7 @@ e_day_view_free_event_array (EDayView *day_view, event = &g_array_index (array, EDayViewEvent, event_num); if (event->canvas_item) gtk_object_destroy (GTK_OBJECT (event->canvas_item)); + ical_object_unref (event->ico); } g_array_set_size (array, 0); @@ -2989,6 +3044,7 @@ e_day_view_add_event (iCalObject *ico, end_tm = *(localtime (&end)); event.ico = ico; + ical_object_ref (ico); event.start = start; event.end = end; event.canvas_item = NULL; @@ -3241,8 +3297,6 @@ e_day_view_reshape_long_event (EDayView *day_view, num_icons++; } - /* FIXME: Handle item_w & item_h <= 0. */ - if (!event->canvas_item) { event->canvas_item = gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (day_view->top_canvas)->root), @@ -3301,12 +3355,13 @@ e_day_view_reshape_long_event (EDayView *day_view, max_text_w -= time_width + E_DAY_VIEW_LONG_EVENT_TIME_X_PAD; text_w = MIN (width, max_text_w); - } - /* Now take out the space for the icons. */ - text_x += icons_width; - text_w -= icons_width; + /* Now take out the space for the icons. */ + text_x += icons_width; + text_w -= icons_width; + } + text_w = MAX (text_w, 0); gnome_canvas_item_set (event->canvas_item, "x", (gdouble) text_x, "y", (gdouble) item_y, @@ -3598,8 +3653,6 @@ e_day_view_reshape_day_event (EDayView *day_view, item_w -= icons_offset; } - /* FIXME: Handle item_w & item_h <= 0. */ - if (!event->canvas_item) { event->canvas_item = gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (day_view->main_canvas)->root), @@ -3618,6 +3671,7 @@ e_day_view_reshape_day_event (EDayView *day_view, event_num); } + item_w = MAX (item_w, 0); gnome_canvas_item_set (event->canvas_item, "x", (gdouble) item_x, "y", (gdouble) item_y, @@ -3804,6 +3858,8 @@ e_day_view_key_press (GtkWidget *widget, GdkEventKey *event) gnome_calendar_add_object (day_view->calendar, ico); + ical_object_unref (ico); + return TRUE; } @@ -4234,6 +4290,7 @@ e_day_view_get_event_position (EDayView *day_view, *item_x = day_view->day_offsets[day] + day_view->day_widths[day] * start_col / cols_in_row; *item_w = day_view->day_widths[day] * num_columns / cols_in_row - E_DAY_VIEW_GAP_WIDTH; + *item_w = MAX (*item_w, 0); *item_y = start_row * day_view->row_height; *item_h = (end_row - start_row + 1) * day_view->row_height; @@ -4277,6 +4334,7 @@ e_day_view_get_long_event_position (EDayView *day_view, *item_x = day_view->day_offsets[*start_day] + E_DAY_VIEW_BAR_WIDTH; *item_w = day_view->day_offsets[*end_day + 1] - *item_x - E_DAY_VIEW_GAP_WIDTH; + *item_w = MAX (*item_w, 0); *item_y = (event->start_row_or_col + 1) * day_view->top_row_height; *item_h = day_view->top_row_height - E_DAY_VIEW_TOP_CANVAS_Y_GAP; return TRUE; @@ -4284,7 +4342,8 @@ e_day_view_get_long_event_position (EDayView *day_view, /* Converts a position within the entire top canvas to a day & event and - a place within the event if appropriate. */ + a place within the event if appropriate. If event_num_return is NULL, it + simply returns the grid position without trying to find the event. */ static EDayViewPosition e_day_view_convert_position_in_top_canvas (EDayView *day_view, gint x, @@ -4296,6 +4355,10 @@ e_day_view_convert_position_in_top_canvas (EDayView *day_view, gint day, row, col; gint event_num, start_day, end_day, item_x, item_y, item_w, item_h; + *day_return = -1; + if (event_num_return) + *event_num_return = -1; + if (x < 0 || y < 0) return E_DAY_VIEW_POS_OUTSIDE; @@ -4355,7 +4418,8 @@ e_day_view_convert_position_in_top_canvas (EDayView *day_view, /* Converts a position within the entire main canvas to a day, row, event and - a place within the event if appropriate. */ + a place within the event if appropriate. If event_num_return is NULL, it + simply returns the grid position without trying to find the event. */ static EDayViewPosition e_day_view_convert_position_in_main_canvas (EDayView *day_view, gint x, @@ -4367,6 +4431,11 @@ e_day_view_convert_position_in_main_canvas (EDayView *day_view, gint day, row, col, event_num; gint item_x, item_y, item_w, item_h; + *day_return = -1; + *row_return = -1; + if (event_num_return) + *event_num_return = -1; + /* Check the position is inside the canvas, and determine the day and row. */ if (x < 0 || y < 0) diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c index bf01b66831..2c740d6df4 100644 --- a/calendar/gui/e-week-view.c +++ b/calendar/gui/e-week-view.c @@ -990,7 +990,7 @@ e_week_view_update_event (EWeekView *week_view, switch (status) { case CAL_OBJ_FIND_SUCCESS: - /* Fall through. */ + /* Do nothing. */ break; case CAL_OBJ_FIND_SYNTAX_ERROR: g_warning ("syntax error uid=%s\n", uid); @@ -1001,8 +1001,10 @@ e_week_view_update_event (EWeekView *week_view, } /* We only care about events. */ - if (ico && ico->type != ICAL_EVENT) + if (ico && ico->type != ICAL_EVENT) { + ical_object_unref (ico); return; + } /* If the event already exists and the dates didn't change, we can update the event fairly easily without changing the events arrays @@ -1015,6 +1017,7 @@ e_week_view_update_event (EWeekView *week_view, if (ical_object_compare_dates (event->ico, ico)) { g_print (" dates unchanged\n"); e_week_view_foreach_event_with_uid (week_view, uid, e_week_view_update_event_cb, ico); + ical_object_unref (ico); gtk_widget_queue_draw (week_view->main_canvas); return; } @@ -1034,6 +1037,7 @@ e_week_view_update_event (EWeekView *week_view, week_view->day_starts[num_days], e_week_view_add_event, week_view); + ical_object_unref (ico); e_week_view_check_layout (week_view); @@ -1055,8 +1059,8 @@ e_week_view_update_event_cb (EWeekView *week_view, ico = data; event = &g_array_index (week_view->events, EWeekViewEvent, event_num); - /* FIXME: When do ico's get freed? */ event->ico = ico; + ical_object_ref (ico); /* If we are editing an event which we have just created, we will get an update_event callback from the server. But we need to ignore it @@ -1102,7 +1106,7 @@ e_week_view_foreach_event_with_uid (EWeekView *week_view, event_num--) { event = &g_array_index (week_view->events, EWeekViewEvent, event_num); - if (event->ico && event->ico->uid + if (event->ico->uid && !strcmp (uid, event->ico->uid)) { if (!(*callback) (week_view, event_num, data)) return; @@ -1159,6 +1163,9 @@ e_week_view_remove_event_cb (EWeekView *week_view, span->background_item = NULL; } } + + ical_object_unref (event->ico); + g_array_remove_index (week_view->events, event_num); week_view->events_need_layout = TRUE; @@ -1527,19 +1534,16 @@ e_week_view_reload_events (EWeekView *week_view) static void e_week_view_free_events (EWeekView *week_view) { + EWeekViewEvent *event; EWeekViewEventSpan *span; - gint span_num; + gint event_num, span_num; - /* There is nothing to free in the event structs at present. */ -#if 0 for (event_num = 0; event_num < week_view->events->len; event_num++) { event = &g_array_index (week_view->events, EWeekViewEvent, event_num); - - if (event->canvas_item) - gtk_object_destroy (GTK_OBJECT (event->canvas_item)); + ical_object_unref (event->ico); } -#endif + g_array_set_size (week_view->events, 0); /* Destroy all the old canvas items. */ @@ -1591,6 +1595,7 @@ e_week_view_add_event (iCalObject *ico, end_tm = *(localtime (&end)); event.ico = ico; + ical_object_ref (event.ico); event.start = start; event.end = end; event.spans_index = 0; @@ -2252,6 +2257,7 @@ e_week_view_on_text_item_event (GnomeCanvasItem *item, g_print (" button release\n"); if (!E_TEXT (item)->editing) { g_print (" stopping signal\n"); + gtk_signal_emit_stop_by_name (GTK_OBJECT (item), "event"); @@ -2430,8 +2436,7 @@ e_week_view_find_event_from_uid (EWeekView *week_view, for (event_num = 0; event_num < num_events; event_num++) { event = &g_array_index (week_view->events, EWeekViewEvent, event_num); - if (event->ico && event->ico->uid - && !strcmp (uid, event->ico->uid)) { + if (event->ico->uid && !strcmp (uid, event->ico->uid)) { *event_num_return = event_num; return TRUE; } @@ -2536,6 +2541,8 @@ e_week_view_key_press (GtkWidget *widget, GdkEventKey *event) gnome_calendar_add_object (week_view->calendar, ico); + ical_object_unref (ico); + return TRUE; } @@ -2625,6 +2632,7 @@ e_week_view_on_new_appointment (GtkWidget *widget, gpointer data) ico->dtend = week_view->day_starts[week_view->selection_end_day + 1]; event_editor = event_editor_new (week_view->calendar, ico); + ical_object_unref (ico); gtk_widget_show (event_editor); } @@ -2650,6 +2658,7 @@ e_week_view_on_edit_appointment (GtkWidget *widget, gpointer data) ico = ical_object_duplicate (event->ico); event_editor = event_editor_new (week_view->calendar, ico); + ical_object_unref (ico); gtk_widget_show (event_editor); } @@ -2725,4 +2734,6 @@ e_week_view_on_unrecur_appointment (GtkWidget *widget, gpointer data) gnome_calendar_object_changed (week_view->calendar, event->ico, CHANGE_ALL); gnome_calendar_add_object (week_view->calendar, ico); + + ical_object_unref (ico); } diff --git a/calendar/gui/eventedit.c b/calendar/gui/eventedit.c index ae18f485fd..7ad4afb8cb 100644 --- a/calendar/gui/eventedit.c +++ b/calendar/gui/eventedit.c @@ -760,11 +760,10 @@ ee_ok (GtkWidget *widget, EventEditor *ee) static void ee_cancel (GtkWidget *widget, EventEditor *ee) { - if (ee->ical->new) { - ical_object_destroy (ee->ical); - ee->ical = NULL; - } - + if (ee->ical) { + ical_object_unref (ee->ical); + ee->ical = NULL; + } } static void @@ -1519,7 +1518,7 @@ event_editor_destroy (GtkObject *object) ee = EVENT_EDITOR (object); if (ee->ical) { - ical_object_destroy (ee->ical); + ical_object_unref (ee->ical); ee->ical = NULL; } } @@ -1539,7 +1538,9 @@ event_editor_new (GnomeCalendar *gcal, iCalObject *ical) if (ical == 0){ ical = ical_new ("", user_name, ""); ical->new = 1; - } + } else { + ical_object_ref (ical); + } if (ical->new){ gtk_window_set_title (GTK_WINDOW (ee), _("Create new appointment")); diff --git a/calendar/gui/gncal-todo.c b/calendar/gui/gncal-todo.c index e9ec433076..a7c54e6086 100644 --- a/calendar/gui/gncal-todo.c +++ b/calendar/gui/gncal-todo.c @@ -88,6 +88,8 @@ ok_button (GtkWidget *widget, GnomeDialog *dialog) } else gnome_calendar_object_changed (todo->calendar, ico, CHANGE_ALL); /* ok, summary only... */ + ical_object_unref (ico); + gtk_widget_destroy (GTK_WIDGET (dialog)); } @@ -100,8 +102,7 @@ cancel_button (GtkWidget *widget, GnomeDialog *dialog) ico->user_data = NULL; - if (ico->new) - ical_object_destroy (ico); + ical_object_unref (ico); gtk_widget_destroy (GTK_WIDGET (dialog)); @@ -227,6 +228,7 @@ simple_todo_editor (GncalTodo *todo, iCalObject *ico) ico->user_data = dialog; gtk_object_set_user_data (GTK_OBJECT (dialog), ico); + ical_object_ref (ico); gtk_object_set_data (GTK_OBJECT (dialog), "gncal_todo", todo); gtk_object_set_data (GTK_OBJECT (dialog), "summary_entry", entry); @@ -272,6 +274,7 @@ add_todo (GncalTodo *todo) ico->new = TRUE; simple_todo_editor (todo, ico); + ical_object_unref (ico); } static void @@ -762,7 +765,9 @@ insert_in_clist (GncalTodo *todo, iCalObject *ico) i = gtk_clist_append (todo->clist, text); - gtk_clist_set_row_data (todo->clist, i, ico); + gtk_clist_set_row_data_full (todo->clist, i, ico, + (GtkDestroyNotify) ical_object_unref); + ical_object_ref (ico); /* * determine if the task is overdue.. @@ -872,6 +877,7 @@ gncal_todo_update (GncalTodo *todo, iCalObject *ico, int flags) g_free (obj_string); insert_in_clist (todo, obj); + ical_object_unref (obj); g_free (uid); } g_list_free (uids); diff --git a/calendar/gui/popup-menu.c b/calendar/gui/popup-menu.c index 3b976a9033..a90c38d490 100644 --- a/calendar/gui/popup-menu.c +++ b/calendar/gui/popup-menu.c @@ -8,6 +8,7 @@ #include <config.h> #include <gnome.h> #include "popup-menu.h" +#include "../../e-util/e-gui-utils.h" void @@ -20,7 +21,7 @@ popup_menu (struct menu_item *items, int nitems, GdkEventButton *event) menu = gtk_menu_new (); /* Make sure the menu is destroyed when it disappears. */ - e_auto_kill_popup_menu_on_hide (menu); + e_auto_kill_popup_menu_on_hide (GTK_MENU (menu)); for (i = 0; i < nitems; i++) { if (items[i].text) { |