From 6b4c3984d52cfbf88ae84ee0102f4aa0c17a2a62 Mon Sep 17 00:00:00 2001 From: JP Rosevear Date: Tue, 4 Mar 2003 19:52:37 +0000 Subject: If only the pipe wouldn't break. svn path=/trunk/; revision=20143 --- calendar/cal-util/cal-component.c | 114 ++- calendar/cal-util/cal-component.h | 6 + calendar/cal-util/cal-recur.c | 2 + calendar/cal-util/cal-util.c | 32 +- calendar/cal-util/cal-util.h | 10 + calendar/conduits/calendar/calendar-conduit.c | 166 ++-- calendar/conduits/todo/todo-conduit.c | 24 +- calendar/gui/calendar-model.c | 19 +- calendar/gui/comp-editor-factory.c | 15 +- calendar/gui/comp-util.c | 20 +- calendar/gui/comp-util.h | 3 +- calendar/gui/dialogs/Makefile.am | 2 + calendar/gui/dialogs/alarm-options.c | 194 +++- calendar/gui/dialogs/alarm-options.glade | 982 ++++++++++--------- calendar/gui/dialogs/alarm-options.h | 2 +- calendar/gui/dialogs/alarm-page.c | 242 ++--- calendar/gui/dialogs/alarm-page.glade | 936 +++++++++--------- calendar/gui/dialogs/cancel-comp.c | 5 +- calendar/gui/dialogs/cancel-comp.h | 3 +- calendar/gui/dialogs/comp-editor.c | 49 +- calendar/gui/dialogs/event-editor.c | 40 +- calendar/gui/dialogs/event-page.c | 14 +- calendar/gui/dialogs/event-page.glade | 1253 +++++++++++++------------ calendar/gui/dialogs/meeting-page.c | 15 +- calendar/gui/dialogs/meeting-page.h | 1 + calendar/gui/dialogs/recurrence-page.c | 68 +- calendar/gui/dialogs/send-comp.c | 5 +- calendar/gui/dialogs/send-comp.h | 3 +- calendar/gui/dialogs/task-details-page.c | 8 +- calendar/gui/dialogs/task-details-page.glade | 677 ++++++------- calendar/gui/dialogs/task-editor.c | 66 +- calendar/gui/e-calendar-table.c | 8 +- calendar/gui/e-day-view.c | 165 +++- calendar/gui/e-itip-control.c | 33 +- calendar/gui/e-itip-control.h | 3 + calendar/gui/e-meeting-attendee.c | 31 + calendar/gui/e-meeting-attendee.h | 10 + calendar/gui/e-meeting-model.c | 77 +- calendar/gui/e-tasks.c | 4 +- calendar/gui/e-week-view.c | 59 +- calendar/gui/gnome-cal.c | 9 +- calendar/gui/itip-bonobo-control.c | 40 +- calendar/gui/itip-utils.c | 26 +- calendar/gui/itip-utils.h | 2 +- calendar/gui/tag-calendar.c | 20 +- calendar/gui/tag-calendar.h | 4 +- calendar/idl/evolution-calendar.idl | 22 +- calendar/pcs/cal-backend-file.c | 75 +- calendar/pcs/cal-backend.c | 40 +- calendar/pcs/cal-backend.h | 19 +- calendar/pcs/cal.c | 74 +- 51 files changed, 3298 insertions(+), 2399 deletions(-) diff --git a/calendar/cal-util/cal-component.c b/calendar/cal-util/cal-component.c index a5300a9605..671af4a9ec 100644 --- a/calendar/cal-util/cal-component.c +++ b/calendar/cal-util/cal-component.c @@ -33,6 +33,21 @@ /* Extension property for alarm components so that we can reference them by UID */ #define EVOLUTION_ALARM_UID_PROPERTY "X-EVOLUTION-ALARM-UID" + +struct attendee { + icalproperty *prop; + icalparameter *cutype_param; + icalparameter *member_param; + icalparameter *role_param; + icalparameter *partstat_param; + icalparameter *rsvp_param; + icalparameter *delto_param; + icalparameter *delfrom_param; + icalparameter *sentby_param; + icalparameter *cn_param; + icalparameter *language_param; +}; + /* Private part of the CalComponent structure */ struct _CalComponentPrivate { /* The icalcomponent we wrap */ @@ -43,21 +58,6 @@ struct _CalComponentPrivate { icalproperty *uid; icalproperty *status; - - struct attendee { - icalproperty *prop; - icalparameter *cutype_param; - icalparameter *member_param; - icalparameter *role_param; - icalparameter *partstat_param; - icalparameter *rsvp_param; - icalparameter *delto_param; - icalparameter *delfrom_param; - icalparameter *sentby_param; - icalparameter *cn_param; - icalparameter *language_param; - }; - GSList *attendee_list; icalproperty *categories; @@ -174,6 +174,8 @@ struct _CalComponentAlarm { icalproperty *duration; icalproperty *repeat; icalproperty *trigger; + + GSList *attendee_list; }; @@ -469,7 +471,7 @@ cal_component_clone (CalComponent *comp) /* Scans an attendee property */ static void -scan_attendee (CalComponent *comp, GSList **attendee_list, icalproperty *prop) +scan_attendee (GSList **attendee_list, icalproperty *prop) { struct attendee *attendee; @@ -601,7 +603,7 @@ scan_property (CalComponent *comp, icalproperty *prop) break; case ICAL_ATTENDEE_PROPERTY: - scan_attendee (comp, &priv->attendee_list, prop); + scan_attendee (&priv->attendee_list, prop); break; case ICAL_CATEGORIES_PROPERTY: @@ -3593,6 +3595,19 @@ cal_component_has_simple_recurrence (CalComponent *comp) return simple; } +gboolean +cal_component_is_instance (CalComponent *comp) +{ + CalComponentPrivate *priv; + + g_return_val_if_fail (comp != NULL, FALSE); + g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE); + + priv = comp->priv; + + return !(priv->recur_id.recur_time.prop == NULL); +} + /** * cal_component_get_sequence: * @comp: A calendar component object. @@ -4019,15 +4034,12 @@ get_attendee_list (GSList *attendee_list, GSList **al) /* Sets a text list value */ static void -set_attendee_list (CalComponent *comp, +set_attendee_list (icalcomponent *icalcomp, GSList **attendee_list, GSList *al) { - CalComponentPrivate *priv; GSList *l; - priv = comp->priv; - /* Remove old attendees */ for (l = *attendee_list; l; l = l->next) { @@ -4036,7 +4048,7 @@ set_attendee_list (CalComponent *comp, attendee = l->data; g_assert (attendee->prop != NULL); - icalcomponent_remove_property (priv->icalcomp, attendee->prop); + icalcomponent_remove_property (icalcomp, attendee->prop); icalproperty_free (attendee->prop); g_free (attendee); } @@ -4056,7 +4068,7 @@ set_attendee_list (CalComponent *comp, attendee = g_new0 (struct attendee, 1); attendee->prop = icalproperty_new_attendee (a->value); - icalcomponent_add_property (priv->icalcomp, attendee->prop); + icalcomponent_add_property (icalcomp, attendee->prop); if (a->member) { attendee->member_param = icalparameter_new_member (a->member); @@ -4147,7 +4159,7 @@ cal_component_set_attendee_list (CalComponent *comp, GSList *attendee_list) priv = comp->priv; g_return_if_fail (priv->icalcomp != NULL); - set_attendee_list (comp, &priv->attendee_list, attendee_list); + set_attendee_list (priv->icalcomp, &priv->attendee_list, attendee_list); } gboolean @@ -4261,6 +4273,14 @@ cal_component_free_datetime (CalComponentDateTime *dt) g_free ((char*)dt->tzid); } +void +cal_component_free_range (CalComponentRange *range) +{ + g_return_if_fail (range != NULL); + + cal_component_free_datetime (&range->datetime); +} + /** * cal_component_free_exdate_list: * @exdate_list: List of #CalComponentDateTime structures. @@ -4618,6 +4638,10 @@ scan_alarm_property (CalComponentAlarm *alarm, icalproperty *prop) alarm->trigger = prop; break; + case ICAL_ATTENDEE_PROPERTY: + scan_attendee (&alarm->attendee_list, prop); + break; + case ICAL_X_PROPERTY: xname = icalproperty_get_x_name (prop); g_assert (xname != NULL); @@ -4651,7 +4675,8 @@ make_alarm (icalcomponent *subcomp) alarm->duration = NULL; alarm->repeat = NULL; alarm->trigger = NULL; - + alarm->attendee_list = NULL; + for (prop = icalcomponent_get_first_property (subcomp, ICAL_ANY_PROPERTY); prop; prop = icalcomponent_get_next_property (subcomp, ICAL_ANY_PROPERTY)) @@ -4804,7 +4829,8 @@ cal_component_alarm_new (void) alarm->duration = NULL; alarm->repeat = NULL; alarm->trigger = NULL; - + alarm->attendee_list = NULL; + return alarm; } @@ -4837,6 +4863,8 @@ cal_component_alarm_clone (CalComponentAlarm *alarm) void cal_component_alarm_free (CalComponentAlarm *alarm) { + GSList *l; + g_return_if_fail (alarm != NULL); g_assert (alarm->icalcomp != NULL); @@ -4854,6 +4882,11 @@ cal_component_alarm_free (CalComponentAlarm *alarm) alarm->repeat = NULL; alarm->trigger = NULL; + for (l = alarm->attendee_list; l != NULL; l = l->next) + g_free (l->data); + g_slist_free (alarm->attendee_list); + alarm->attendee_list = NULL; + g_free (alarm); } @@ -5318,6 +5351,35 @@ cal_component_alarm_set_trigger (CalComponentAlarm *alarm, CalAlarmTrigger trigg } } +void +cal_component_alarm_get_attendee_list (CalComponentAlarm *alarm, GSList **attendee_list) +{ + g_return_if_fail (alarm != NULL); + + get_attendee_list (alarm->attendee_list, attendee_list); +} + +void +cal_component_alarm_set_attendee_list (CalComponentAlarm *alarm, GSList *attendee_list) +{ + g_return_if_fail (alarm != NULL); + + set_attendee_list (alarm->icalcomp, &alarm->attendee_list, attendee_list); +} + +gboolean +cal_component_alarm_has_attendees (CalComponentAlarm *alarm) +{ + + g_return_val_if_fail (alarm != NULL, FALSE); + + if (g_slist_length (alarm->attendee_list) > 0) + return TRUE; + + return FALSE; +} + + /** * cal_component_alarm_get_icalcomponent * @alarm: An alarm. diff --git a/calendar/cal-util/cal-component.h b/calendar/cal-util/cal-component.h index dba2e5a179..f363099836 100644 --- a/calendar/cal-util/cal-component.h +++ b/calendar/cal-util/cal-component.h @@ -297,6 +297,7 @@ gboolean cal_component_has_rrules (CalComponent *comp); gboolean cal_component_has_recurrences (CalComponent *comp); gboolean cal_component_has_simple_recurrence (CalComponent *comp); +gboolean cal_component_is_instance (CalComponent *comp); void cal_component_get_sequence (CalComponent *comp, int **sequence); void cal_component_set_sequence (CalComponent *comp, int *sequence); @@ -327,6 +328,7 @@ gboolean cal_component_event_dates_match (CalComponent *comp1, CalComponent *com void cal_component_free_categories_list (GSList *categ_list); void cal_component_free_datetime (CalComponentDateTime *dt); +void cal_component_free_range (CalComponentRange *range); void cal_component_free_exdate_list (GSList *exdate_list); void cal_component_free_geo (struct icalgeotype *geo); void cal_component_free_icaltimetype (struct icaltimetype *t); @@ -434,6 +436,10 @@ void cal_component_alarm_set_repeat (CalComponentAlarm *alarm, CalAlarmRepeat re void cal_component_alarm_get_trigger (CalComponentAlarm *alarm, CalAlarmTrigger *trigger); void cal_component_alarm_set_trigger (CalComponentAlarm *alarm, CalAlarmTrigger trigger); +void cal_component_alarm_get_attendee_list (CalComponentAlarm *alarm, GSList **attendee_list); +void cal_component_alarm_set_attendee_list (CalComponentAlarm *alarm, GSList *attendee_list); +gboolean cal_component_alarm_has_attendees (CalComponentAlarm *alarm); + icalcomponent *cal_component_alarm_get_icalcomponent (CalComponentAlarm *alarm); diff --git a/calendar/cal-util/cal-recur.c b/calendar/cal-util/cal-recur.c index 214c642f45..123198676c 100644 --- a/calendar/cal-util/cal-recur.c +++ b/calendar/cal-util/cal-recur.c @@ -770,6 +770,8 @@ cal_recur_generate_instances_of_rule (CalComponent *comp, elem.data = prop; elem.next = NULL; rrules = &elem; + } else if (cal_component_is_instance (comp)) { + single_rule = FALSE; } else { single_rule = FALSE; diff --git a/calendar/cal-util/cal-util.c b/calendar/cal-util/cal-util.c index 9730bfdbc2..040e322cce 100644 --- a/calendar/cal-util/cal-util.c +++ b/calendar/cal-util/cal-util.c @@ -177,7 +177,8 @@ struct alarm_occurrence_data { GList *alarm_uids; time_t start; time_t end; - + CalAlarmAction *omit; + /* This is what we compute */ GSList *triggers; int n_triggers; @@ -213,20 +214,30 @@ add_alarm_occurrences_cb (CalComponent *comp, time_t start, time_t end, gpointer for (l = aod->alarm_uids; l; l = l->next) { const char *auid; CalComponentAlarm *alarm; + CalAlarmAction action; CalAlarmTrigger trigger; CalAlarmRepeat repeat; struct icaldurationtype *dur; time_t dur_time; time_t occur_time, trigger_time; - + int i; + auid = l->data; alarm = cal_component_get_alarm (comp, auid); g_assert (alarm != NULL); + cal_component_alarm_get_action (alarm, &action); cal_component_alarm_get_trigger (alarm, &trigger); cal_component_alarm_get_repeat (alarm, &repeat); cal_component_alarm_free (alarm); + for (i = 0; aod->omit[i] != -1; i++) { + if (aod->omit[i] == action) + break; + } + if (aod->omit[i] != -1) + continue; + if (trigger.type != CAL_ALARM_TRIGGER_RELATIVE_START && trigger.type != CAL_ALARM_TRIGGER_RELATIVE_END) continue; @@ -290,20 +301,30 @@ generate_absolute_triggers (CalComponent *comp, struct alarm_occurrence_data *ao for (l = aod->alarm_uids; l; l = l->next) { const char *auid; CalComponentAlarm *alarm; + CalAlarmAction action; CalAlarmRepeat repeat; CalAlarmTrigger trigger; time_t abs_time; time_t occur_start, occur_end; icaltimezone *zone; - + int i; + auid = l->data; alarm = cal_component_get_alarm (comp, auid); g_assert (alarm != NULL); + cal_component_alarm_get_action (alarm, &action); cal_component_alarm_get_trigger (alarm, &trigger); cal_component_alarm_get_repeat (alarm, &repeat); cal_component_alarm_free (alarm); + for (i = 0; aod->omit[i] != -1; i++) { + if (aod->omit[i] == action) + break; + } + if (aod->omit[i] != -1) + continue; + if (trigger.type != CAL_ALARM_TRIGGER_ABSOLUTE) continue; @@ -397,6 +418,7 @@ CalComponentAlarms * cal_util_generate_alarms_for_comp (CalComponent *comp, time_t start, time_t end, + CalAlarmAction *omit, CalRecurResolveTimezoneFn resolve_tzid, gpointer user_data, icaltimezone *default_timezone) @@ -415,6 +437,7 @@ cal_util_generate_alarms_for_comp (CalComponent *comp, aod.alarm_uids = alarm_uids; aod.start = start; aod.end = end; + aod.omit = omit; aod.triggers = NULL; aod.n_triggers = 0; @@ -459,6 +482,7 @@ int cal_util_generate_alarms_for_list (GList *comps, time_t start, time_t end, + CalAlarmAction *omit, GSList **comp_alarms, CalRecurResolveTimezoneFn resolve_tzid, gpointer user_data, @@ -474,7 +498,7 @@ cal_util_generate_alarms_for_list (GList *comps, CalComponentAlarms *alarms; comp = CAL_COMPONENT (l->data); - alarms = cal_util_generate_alarms_for_comp (comp, start, end, resolve_tzid, user_data, default_timezone); + alarms = cal_util_generate_alarms_for_comp (comp, start, end, omit, resolve_tzid, user_data, default_timezone); if (alarms) { *comp_alarms = g_slist_prepend (*comp_alarms, alarms); diff --git a/calendar/cal-util/cal-util.h b/calendar/cal-util/cal-util.h index a4d95a3e8c..bf43493f82 100644 --- a/calendar/cal-util/cal-util.h +++ b/calendar/cal-util/cal-util.h @@ -51,6 +51,14 @@ typedef enum { CALOBJ_TYPE_ANY = 0x07 } CalObjType; +/* Used for modifying objects */ +typedef enum { + CALOBJ_MOD_THIS = 1 << 0, + CALOBJ_MOD_THISANDPRIOR = 1 << 1, + CALOBJ_MOD_THISANDFUTURE = 1 << 2, + CALOBJ_MOD_ALL = 0x07 +} CalObjModType; + /* Used for mode stuff */ typedef enum { CAL_MODE_INVALID = -1, @@ -66,12 +74,14 @@ icalcomponent *cal_util_new_top_level (void); CalComponentAlarms *cal_util_generate_alarms_for_comp (CalComponent *comp, time_t start, time_t end, + CalAlarmAction *omit, CalRecurResolveTimezoneFn resolve_tzid, gpointer user_data, icaltimezone *default_timezone); int cal_util_generate_alarms_for_list (GList *comps, time_t start, time_t end, + CalAlarmAction *omit, GSList **comp_alarms, CalRecurResolveTimezoneFn resolve_tzid, gpointer user_data, diff --git a/calendar/conduits/calendar/calendar-conduit.c b/calendar/conduits/calendar/calendar-conduit.c index e6c4cc7279..b035d1775c 100644 --- a/calendar/conduits/calendar/calendar-conduit.c +++ b/calendar/conduits/calendar/calendar-conduit.c @@ -250,6 +250,7 @@ struct _ECalConduitContext { CalClient *client; icaltimezone *timezone; + CalComponent *default_comp; GList *uids; GList *changed; GHashTable *changed_hash; @@ -272,6 +273,7 @@ e_calendar_context_new (guint32 pilot_id) ctxt->dbi = NULL; ctxt->client = NULL; ctxt->timezone = NULL; + ctxt->default_comp = NULL; ctxt->uids = NULL; ctxt->changed = NULL; ctxt->changed_hash = NULL; @@ -305,7 +307,8 @@ e_calendar_context_destroy (ECalConduitContext *ctxt) if (ctxt->client != NULL) g_object_unref (ctxt->client); - + if (ctxt->default_comp != NULL) + gtk_object_unref (GTK_OBJECT (ctxt->default_comp)); if (ctxt->uids != NULL) cal_obj_uid_list_free (ctxt->uids); @@ -811,93 +814,95 @@ local_record_from_comp (ECalLocalRecord *local, CalComponent *comp, ECalConduitC /* Recurrence Rules */ local->appt->repeatType = repeatNone; - - if (cal_component_has_rrules (comp)) { - GSList *list; - struct icalrecurrencetype *recur; + + if (!cal_component_is_instance (comp)) { + if (cal_component_has_rrules (comp)) { + GSList *list; + struct icalrecurrencetype *recur; - cal_component_get_rrule_list (comp, &list); - recur = list->data; + cal_component_get_rrule_list (comp, &list); + recur = list->data; - switch (recur->freq) { - case ICAL_DAILY_RECURRENCE: - local->appt->repeatType = repeatDaily; - break; - case ICAL_WEEKLY_RECURRENCE: - local->appt->repeatType = repeatWeekly; - for (i = 0; i <= 7 && recur->by_day[i] != ICAL_RECURRENCE_ARRAY_MAX; i++) { - icalrecurrencetype_weekday wd; + switch (recur->freq) { + case ICAL_DAILY_RECURRENCE: + local->appt->repeatType = repeatDaily; + break; + case ICAL_WEEKLY_RECURRENCE: + local->appt->repeatType = repeatWeekly; + for (i = 0; i <= 7 && recur->by_day[i] != ICAL_RECURRENCE_ARRAY_MAX; i++) { + icalrecurrencetype_weekday wd; - wd = icalrecurrencetype_day_day_of_week (recur->by_day[i]); - local->appt->repeatDays[get_pilot_day (wd)] = 1; - } + wd = icalrecurrencetype_day_day_of_week (recur->by_day[i]); + local->appt->repeatDays[get_pilot_day (wd)] = 1; + } - break; - case ICAL_MONTHLY_RECURRENCE: - if (recur->by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { - local->appt->repeatType = repeatMonthlyByDate; break; - } + case ICAL_MONTHLY_RECURRENCE: + if (recur->by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { + local->appt->repeatType = repeatMonthlyByDate; + break; + } - /* FIX ME Not going to work with -ve by_day */ - local->appt->repeatType = repeatMonthlyByDay; - switch (icalrecurrencetype_day_position (recur->by_day[0])) { - case 1: - local->appt->repeatDay = dom1stSun; - break; - case 2: - local->appt->repeatDay = dom2ndSun; - break; - case 3: - local->appt->repeatDay = dom3rdSun; + /* FIX ME Not going to work with -ve by_day */ + local->appt->repeatType = repeatMonthlyByDay; + switch (icalrecurrencetype_day_position (recur->by_day[0])) { + case 1: + local->appt->repeatDay = dom1stSun; + break; + case 2: + local->appt->repeatDay = dom2ndSun; + break; + case 3: + local->appt->repeatDay = dom3rdSun; + break; + case 4: + local->appt->repeatDay = dom4thSun; + break; + case 5: + local->appt->repeatDay = domLastSun; + break; + } + local->appt->repeatDay += get_pilot_day (icalrecurrencetype_day_day_of_week (recur->by_day[0])); break; - case 4: - local->appt->repeatDay = dom4thSun; + case ICAL_YEARLY_RECURRENCE: + local->appt->repeatType = repeatYearly; break; - case 5: - local->appt->repeatDay = domLastSun; + default: break; } - local->appt->repeatDay += get_pilot_day (icalrecurrencetype_day_day_of_week (recur->by_day[0])); - break; - case ICAL_YEARLY_RECURRENCE: - local->appt->repeatType = repeatYearly; - break; - default: - break; - } - if (local->appt->repeatType != repeatNone) { - local->appt->repeatFrequency = recur->interval; - } + if (local->appt->repeatType != repeatNone) { + local->appt->repeatFrequency = recur->interval; + } - if (icaltime_is_null_time (recur->until)) { - local->appt->repeatForever = 1; - } else { - local->appt->repeatForever = 0; - icaltimezone_convert_time (&recur->until, + if (icaltime_is_null_time (recur->until)) { + local->appt->repeatForever = 1; + } else { + local->appt->repeatForever = 0; + icaltimezone_convert_time (&recur->until, + icaltimezone_get_utc_timezone (), + default_tz); + local->appt->repeatEnd = icaltimetype_to_tm (&recur->until); + } + + cal_component_free_recur_list (list); + } + + /* Exceptions */ + cal_component_get_exdate_list (comp, &edl); + local->appt->exceptions = g_slist_length (edl); + local->appt->exception = g_new0 (struct tm, local->appt->exceptions); + for (l = edl, i = 0; l != NULL; l = l->next, i++) { + CalComponentDateTime *dt = l->data; + + icaltimezone_convert_time (dt->value, icaltimezone_get_utc_timezone (), default_tz); - local->appt->repeatEnd = icaltimetype_to_tm (&recur->until); + *local->appt->exception = icaltimetype_to_tm (dt->value); } - - cal_component_free_recur_list (list); + cal_component_free_exdate_list (edl); } - - /* Exceptions */ - cal_component_get_exdate_list (comp, &edl); - local->appt->exceptions = g_slist_length (edl); - local->appt->exception = g_new0 (struct tm, local->appt->exceptions); - for (l = edl, i = 0; l != NULL; l = l->next, i++) { - CalComponentDateTime *dt = l->data; - - icaltimezone_convert_time (dt->value, - icaltimezone_get_utc_timezone (), - default_tz); - *local->appt->exception = icaltimetype_to_tm (dt->value); - } - cal_component_free_exdate_list (edl); - + /* Alarm */ local->appt->alarm = 0; if (cal_component_has_alarms (comp)) { @@ -1279,6 +1284,10 @@ pre_sync (GnomePilotConduit *conduit, if (ctxt->timezone) cal_client_set_default_timezone (ctxt->client, ctxt->timezone); + /* Get the default component */ + if (cal_client_get_default_object (ctxt->client, CALOBJ_TYPE_EVENT, &ctxt->default_comp) != CAL_CLIENT_GET_SUCCESS) + return -1; + /* Load the uid <--> pilot id mapping */ filename = map_name (ctxt); e_pilot_map_read (filename, &ctxt->map); @@ -1574,19 +1583,24 @@ add_record (GnomePilotConduitSyncAbs *conduit, ECalConduitContext *ctxt) { CalComponent *comp; - const char *uid; + char *uid; int retval = 0; g_return_val_if_fail (remote != NULL, -1); LOG ("add_record: adding %s to desktop\n", print_remote (remote)); - comp = comp_from_remote_record (conduit, remote, NULL, ctxt->timezone); - update_comp (conduit, comp, ctxt); + comp = comp_from_remote_record (conduit, remote, ctxt->default_comp, ctxt->timezone); + + /* Give it a new UID otherwise it will be the uid of the default comp */ + uid = cal_component_gen_uid (); + cal_component_set_uid (comp, uid); - cal_component_get_uid (comp, &uid); + update_comp (conduit, comp, ctxt); e_pilot_map_insert (ctxt->map, remote->ID, uid, FALSE); + g_free (uid); + g_object_unref (comp); return retval; diff --git a/calendar/conduits/todo/todo-conduit.c b/calendar/conduits/todo/todo-conduit.c index 1633a03d4c..18819b9b70 100644 --- a/calendar/conduits/todo/todo-conduit.c +++ b/calendar/conduits/todo/todo-conduit.c @@ -252,6 +252,7 @@ struct _EToDoConduitContext { CalClient *client; icaltimezone *timezone; + CalComponent *default_comp; GList *uids; GList *changed; GHashTable *changed_hash; @@ -270,6 +271,8 @@ e_todo_context_new (guint32 pilot_id) ctxt->gui = NULL; ctxt->ps = NULL; ctxt->client = NULL; + ctxt->timezone = NULL; + ctxt->default_comp = NULL; ctxt->uids = NULL; ctxt->changed_hash = NULL; ctxt->changed = NULL; @@ -304,6 +307,8 @@ e_todo_context_destroy (EToDoConduitContext *ctxt) if (ctxt->client != NULL) g_object_unref (ctxt->client); + if (ctxt->default_comp != NULL) + gtk_object_unref (GTK_OBJECT (ctxt->default_comp)); if (ctxt->uids != NULL) cal_obj_uid_list_free (ctxt->uids); @@ -885,6 +890,14 @@ pre_sync (GnomePilotConduit *conduit, return -1; LOG (" Using timezone: %s", icaltimezone_get_tzid (ctxt->timezone)); + /* Set the default timezone on the backend. */ + if (ctxt->timezone) + cal_client_set_default_timezone (ctxt->client, ctxt->timezone); + + /* Get the default component */ + if (cal_client_get_default_object (ctxt->client, CALOBJ_TYPE_TODO, &ctxt->default_comp) != CAL_CLIENT_GET_SUCCESS) + return -1; + /* Load the uid <--> pilot id map */ filename = map_name (ctxt); e_pilot_map_read (filename, &ctxt->map); @@ -1152,17 +1165,20 @@ add_record (GnomePilotConduitSyncAbs *conduit, EToDoConduitContext *ctxt) { CalComponent *comp; - const char *uid; + char *uid; int retval = 0; g_return_val_if_fail (remote != NULL, -1); LOG ("add_record: adding %s to desktop\n", print_remote (remote)); - comp = comp_from_remote_record (conduit, remote, NULL, ctxt->timezone); - update_comp (conduit, comp, ctxt); + comp = comp_from_remote_record (conduit, remote, ctxt->default_comp, ctxt->timezone); + + /* Give it a new UID otherwise it will be the uid of the default comp */ + uid = cal_component_gen_uid (); + cal_component_set_uid (comp, uid); - cal_component_get_uid (comp, &uid); + update_comp (conduit, comp, ctxt); e_pilot_map_insert (ctxt->map, remote->ID, uid, FALSE); g_object_unref (comp); diff --git a/calendar/gui/calendar-model.c b/calendar/gui/calendar-model.c index 05d402f139..b7ea5b5348 100644 --- a/calendar/gui/calendar-model.c +++ b/calendar/gui/calendar-model.c @@ -832,7 +832,7 @@ calendar_model_value_at (ETableModel *etm, int col, int row) if (cal_component_has_recurrences (comp)) return GINT_TO_POINTER (1); - if (itip_organizer_is_user (comp)) + if (itip_organizer_is_user (comp, priv->client)) return GINT_TO_POINTER (3); cal_component_get_attendee_list (comp, &attendees); @@ -1355,14 +1355,23 @@ calendar_model_append_row (ETableModel *etm, ETableModel *source, gint row) model = CALENDAR_MODEL (etm); priv = model->priv; + /* Guard against saving before the calendar is open */ + if (!(priv->client && cal_client_get_load_state (priv->client) == CAL_CLIENT_LOAD_LOADED)) + return; + /* FIXME: This should support other types of components, but for now it * is only used for the task list. */ - if (priv->new_comp_vtype == CAL_COMPONENT_EVENT) - comp = cal_comp_event_new_with_defaults (); - else { + switch (priv->new_comp_vtype) { + case CAL_COMPONENT_EVENT: + comp = cal_comp_event_new_with_defaults (priv->client); + break; + case CAL_COMPONENT_TODO: + comp = cal_comp_task_new_with_defaults (priv->client); + break; + default: comp = cal_component_new (); - cal_component_set_new_vtype (comp, priv->new_comp_vtype); + cal_component_set_new_vtype (comp, priv->new_comp_vtype); } set_categories (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_CATEGORIES, row)); diff --git a/calendar/gui/comp-editor-factory.c b/calendar/gui/comp-editor-factory.c index 3f1008d7ba..404b0ab5a6 100644 --- a/calendar/gui/comp-editor-factory.c +++ b/calendar/gui/comp-editor-factory.c @@ -301,7 +301,7 @@ edit_existing (OpenClient *oc, const char *uid) * type. */ static CalComponent * -get_default_event (gboolean all_day) +get_default_event (CalClient *client, gboolean all_day) { CalComponent *comp; struct icaltimetype itt; @@ -309,7 +309,7 @@ get_default_event (gboolean all_day) char *location; icaltimezone *zone; - comp = cal_comp_event_new_with_defaults (); + comp = cal_comp_event_new_with_defaults (client); location = calendar_config_get_timezone (); zone = icaltimezone_get_builtin_timezone (location); @@ -340,12 +340,11 @@ get_default_event (gboolean all_day) } static CalComponent * -get_default_task (void) +get_default_task (CalClient *client) { CalComponent *comp; - comp = cal_component_new (); - cal_component_set_new_vtype (comp, CAL_COMPONENT_TODO); + comp = cal_comp_task_new_with_defaults (client); return comp; } @@ -361,15 +360,15 @@ edit_new (OpenClient *oc, const GNOME_Evolution_Calendar_CompEditorFactory_CompE case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_EVENT: case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING: editor = COMP_EDITOR (event_editor_new (oc->client)); - comp = get_default_event (FALSE); + comp = get_default_event (oc->client, FALSE); break; case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_ALLDAY_EVENT: editor = COMP_EDITOR (event_editor_new (oc->client)); - comp = get_default_event (TRUE); + comp = get_default_event (oc->client, TRUE); break; case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO: editor = COMP_EDITOR (task_editor_new (oc->client)); - comp = get_default_task (); + comp = get_default_task (oc->client); break; default: g_assert_not_reached (); diff --git a/calendar/gui/comp-util.c b/calendar/gui/comp-util.c index df4817d70d..fc3496be67 100644 --- a/calendar/gui/comp-util.c +++ b/calendar/gui/comp-util.c @@ -258,7 +258,7 @@ cal_comp_is_on_server (CalComponent *comp, CalClient *client) * Return value: A newly-created calendar component. **/ CalComponent * -cal_comp_event_new_with_defaults (void) +cal_comp_event_new_with_defaults (CalClient *client) { CalComponent *comp; int interval; @@ -268,10 +268,9 @@ cal_comp_event_new_with_defaults (void) icalproperty *icalprop; CalAlarmTrigger trigger; - comp = cal_component_new (); - - cal_component_set_new_vtype (comp, CAL_COMPONENT_EVENT); - + if (cal_client_get_default_object (client, CALOBJ_TYPE_EVENT, &comp) != CAL_CLIENT_GET_SUCCESS) + return NULL; + if (!calendar_config_get_use_default_reminder ()) return comp; @@ -321,3 +320,14 @@ cal_comp_event_new_with_defaults (void) return comp; } + +CalComponent * +cal_comp_task_new_with_defaults (CalClient *client) +{ + CalComponent *comp; + + if (cal_client_get_default_object (client, CALOBJ_TYPE_TODO, &comp) != CAL_CLIENT_GET_SUCCESS) + return NULL; + + return comp; +} diff --git a/calendar/gui/comp-util.h b/calendar/gui/comp-util.h index de5e9d5336..c3326fbaa3 100644 --- a/calendar/gui/comp-util.h +++ b/calendar/gui/comp-util.h @@ -39,6 +39,7 @@ gboolean cal_comp_util_compare_event_timezones (CalComponent *comp, gboolean cal_comp_is_on_server (CalComponent *comp, CalClient *client); -CalComponent *cal_comp_event_new_with_defaults (void); +CalComponent *cal_comp_event_new_with_defaults (CalClient *client); +CalComponent *cal_comp_task_new_with_defaults (CalClient *client); #endif diff --git a/calendar/gui/dialogs/Makefile.am b/calendar/gui/dialogs/Makefile.am index dc44ea7be6..53ea88a9dc 100644 --- a/calendar/gui/dialogs/Makefile.am +++ b/calendar/gui/dialogs/Makefile.am @@ -62,6 +62,8 @@ libcal_dialogs_la_SOURCES = \ meeting-page.h \ recurrence-page.c \ recurrence-page.h \ + recur-comp.c \ + recur-comp.h \ save-comp.c \ save-comp.h \ schedule-page.c \ diff --git a/calendar/gui/dialogs/alarm-options.c b/calendar/gui/dialogs/alarm-options.c index 937d54eaca..50b5ebcfeb 100644 --- a/calendar/gui/dialogs/alarm-options.c +++ b/calendar/gui/dialogs/alarm-options.c @@ -29,7 +29,13 @@ #include #include #include +#include +#include +#include +#include #include +#include +#include "Evolution-Addressbook-SelectNames.h" #include "e-util/e-dialog-widgets.h" #include "alarm-options.h" @@ -50,6 +56,7 @@ typedef struct { GtkWidget *button_cancel; /* Alarm repeat widgets */ + gboolean repeat; GtkWidget *repeat_toggle; GtkWidget *repeat_group; GtkWidget *repeat_quantity; @@ -64,8 +71,14 @@ typedef struct { GtkWidget *aalarm_group; GtkWidget *aalarm_attach; - /* FIXME: Mail alarm widgets */ + /* Mail alarm widgets */ + const char *email; GtkWidget *malarm_group; + GtkWidget *malarm_address_group; + GtkWidget *malarm_addresses; + GtkWidget *malarm_addressbook; + GtkWidget *malarm_description; + GNOME_Evolution_Addressbook_SelectNames corba_select_names; /* Procedure alarm widgets */ GtkWidget *palarm_group; @@ -73,6 +86,9 @@ typedef struct { GtkWidget *palarm_args; } Dialog; +#define SELECT_NAMES_OAFID "OAFIID:GNOME_Evolution_Addressbook_SelectNames" +static const char *section_name = "Send To"; + /* Gets the widgets from the XML file and returns if they are all available. */ @@ -99,7 +115,10 @@ get_widgets (Dialog *dialog) dialog->aalarm_attach = GW ("aalarm-attach"); dialog->malarm_group = GW ("malarm-group"); - + dialog->malarm_address_group = GW ("malarm-address-group"); + dialog->malarm_addressbook = GW ("malarm-addressbook"); + dialog->malarm_description = GW ("malarm-description"); + dialog->palarm_group = GW ("palarm-group"); dialog->palarm_program = GW ("palarm-program"); dialog->palarm_args = GW ("palarm-args"); @@ -117,11 +136,63 @@ get_widgets (Dialog *dialog) && dialog->aalarm_group && dialog->aalarm_attach && dialog->malarm_group + && dialog->malarm_address_group + && dialog->malarm_addressbook + && dialog->malarm_description && dialog->palarm_group && dialog->palarm_program && dialog->palarm_args); } +static void +addressbook_clicked_cb (GtkWidget *widget, gpointer data) +{ + Dialog *dialog = data; + CORBA_Environment ev; + + CORBA_exception_init (&ev); + + GNOME_Evolution_Addressbook_SelectNames_activateDialog (dialog->corba_select_names, + section_name, &ev); + + CORBA_exception_free (&ev); +} + +static gboolean +setup_select_names (Dialog *dialog) +{ + Bonobo_Control corba_control; + CORBA_Environment ev; + + CORBA_exception_init (&ev); + + dialog->corba_select_names = bonobo_activation_activate_from_id (SELECT_NAMES_OAFID, 0, NULL, &ev); + if (BONOBO_EX (&ev)) + return FALSE; + + GNOME_Evolution_Addressbook_SelectNames_addSection (dialog->corba_select_names, + section_name, section_name, &ev); + if (BONOBO_EX (&ev)) + return FALSE; + + corba_control = GNOME_Evolution_Addressbook_SelectNames_getEntryBySection (dialog->corba_select_names, + section_name, &ev); + + if (BONOBO_EX (&ev)) + return FALSE; + + CORBA_exception_free (&ev); + + dialog->malarm_addresses = bonobo_widget_new_control_from_objref (corba_control, CORBA_OBJECT_NIL); + gtk_widget_show (dialog->malarm_addresses); + gtk_box_pack_end_defaults (GTK_BOX (dialog->malarm_address_group), dialog->malarm_addresses); + + gtk_signal_connect (GTK_OBJECT (dialog->malarm_addressbook), "clicked", + GTK_SIGNAL_FUNC (addressbook_clicked_cb), dialog); + + return TRUE; +} + /* Closes the dialog by terminating its main loop */ static void close_dialog (Dialog *dialog, gboolean canceled) @@ -243,7 +314,50 @@ alarm_to_dalarm_widgets (Dialog *dialog, CalComponentAlarm *alarm) static void alarm_to_malarm_widgets (Dialog *dialog, CalComponentAlarm *alarm) { - /* FIXME: nothing for now; we don't support mail alarms */ + CalComponentText description; + GSList *attendee_list, *l; + EDestination **destv; + int len, i; + + /* Recipients */ + cal_component_alarm_get_attendee_list (alarm, &attendee_list); + len = g_slist_length (attendee_list); + + if (len <= 0) { + destv = g_new0 (EDestination *, 2); + destv[0] = e_destination_new (); + e_destination_set_email (destv[0], dialog->email); + destv[1] = NULL; + len = 1; + } else { + destv = g_new0 (EDestination *, len + 1); + for (l = attendee_list, i = 0; l != NULL; l = l->next, i++) { + CalComponentAttendee *a = l->data; + EDestination *dest; + + dest = e_destination_new (); + if (a->cn != NULL && *a->cn) + e_destination_set_name (dest, a->cn); + if (a->value != NULL && *a->value) + e_destination_set_email (dest, a->value); + + destv[i] = dest; + } + destv[i] = NULL; + } + + bonobo_widget_set_property (BONOBO_WIDGET (dialog->malarm_addresses), + "destinations", e_destination_exportv (destv), NULL); + + for (i = 0; i < len; i++) + gtk_object_unref (GTK_OBJECT (destv[i])); + g_free (destv); + + cal_component_free_attendee_list (attendee_list); + + /* Description */ + cal_component_alarm_get_description (alarm, &description); + e_dialog_editable_set (dialog->malarm_description, description.value); } /* Fills the procedure alarm widgets with the values from the alarm component */ @@ -319,7 +433,8 @@ alarm_to_repeat_widgets (Dialog *dialog, CalComponentAlarm *alarm) /* Sensitivity */ - if (repeat.repetitions == 0) { + if (dialog->repeat || repeat.repetitions == 0) { + gtk_widget_set_sensitive (dialog->repeat_toggle, dialog->repeat); gtk_widget_set_sensitive (dialog->repeat_group, FALSE); e_dialog_toggle_set (dialog->repeat_toggle, FALSE); return; @@ -373,7 +488,7 @@ alarm_to_dialog (Dialog *dialog, CalComponentAlarm *alarm) break; case CAL_ALARM_EMAIL: - gtk_window_set_title (GTK_WINDOW (dialog->toplevel), _("Mail Alarm Options")); + gtk_window_set_title (GTK_WINDOW (dialog->toplevel), _("Email Alarm Options")); gtk_widget_hide (dialog->aalarm_group); gtk_widget_hide (dialog->dalarm_group); gtk_widget_show (dialog->malarm_group); @@ -491,7 +606,61 @@ dalarm_widgets_to_alarm (Dialog *dialog, CalComponentAlarm *alarm) static void malarm_widgets_to_alarm (Dialog *dialog, CalComponentAlarm *alarm) { - /* FIXME: nothing for now; we don't support mail alarms */ + char *str; + CalComponentText description; + GSList *attendee_list = NULL; + EDestination **destv; + icalcomponent *icalcomp; + icalproperty *icalprop; + int i; + + /* Attendees */ + bonobo_widget_get_property (BONOBO_WIDGET (dialog->malarm_addresses), "destinations", + &str, NULL); + destv = e_destination_importv (str); + g_free (str); + + for (i = 0; destv[i] != NULL; i++) { + EDestination *dest; + CalComponentAttendee *a; + + dest = destv[i]; + + a = g_new0 (CalComponentAttendee, 1); + a->value = e_destination_get_email (dest); + a->cn = e_destination_get_name (dest); + + attendee_list = g_slist_append (attendee_list, a); + } + + cal_component_alarm_set_attendee_list (alarm, attendee_list); + + cal_component_free_attendee_list (attendee_list); + e_destination_freev (destv); + + /* Description */ + str = e_dialog_editable_get (dialog->malarm_description); + description.value = str; + description.altrep = NULL; + + cal_component_alarm_set_description (alarm, &description); + g_free (str); + + /* remove the X-EVOLUTION-NEEDS-DESCRIPTION property, so that + * we don't re-set the alarm's description */ + icalcomp = cal_component_alarm_get_icalcomponent (alarm); + icalprop = icalcomponent_get_first_property(icalcomp, ICAL_X_PROPERTY); + while (icalprop) { + const char *x_name; + + x_name = icalproperty_get_x_name (icalprop); + if (!strcmp (x_name, "X-EVOLUTION-NEEDS-DESCRIPTION")) { + icalcomponent_remove_property (icalcomp, icalprop); + break; + } + + icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY); + } } /* Fills the procedure alarm data with the values from the widgets */ @@ -586,12 +755,14 @@ dialog_to_alarm (Dialog *dialog, CalComponentAlarm *alarm) * Return value: TRUE if the dialog could be created, FALSE otherwise. **/ gboolean -alarm_options_dialog_run (CalComponentAlarm *alarm) +alarm_options_dialog_run (CalComponentAlarm *alarm, const char *email, gboolean repeat) { Dialog dialog; g_return_val_if_fail (alarm != NULL, FALSE); + dialog.repeat = repeat; + dialog.email = email; dialog.xml = glade_xml_new (EVOLUTION_GLADEDIR "/alarm-options.glade", NULL, NULL); if (!dialog.xml) { g_message ("alarm_options_dialog_new(): Could not load the Glade XML file!"); @@ -599,10 +770,15 @@ alarm_options_dialog_run (CalComponentAlarm *alarm) } if (!get_widgets (&dialog)) { - g_object_unref((dialog.xml)); + g_object_unref(dialog.xml); return FALSE; } + if (!setup_select_names (&dialog)) { + g_object_unref (dialog.xml); + return FALSE; + } + init_widgets (&dialog); alarm_to_dialog (&dialog, alarm); @@ -614,7 +790,7 @@ alarm_options_dialog_run (CalComponentAlarm *alarm) dialog_to_alarm (&dialog, alarm); gtk_widget_destroy (dialog.toplevel); - g_object_unref((dialog.xml)); + g_object_unref(dialog.xml); return TRUE; } diff --git a/calendar/gui/dialogs/alarm-options.glade b/calendar/gui/dialogs/alarm-options.glade index 9c08926392..83f0af1f80 100644 --- a/calendar/gui/dialogs/alarm-options.glade +++ b/calendar/gui/dialogs/alarm-options.glade @@ -1,434 +1,556 @@ - + - - - - - GTK_WINDOW_DIALOG - yes - no - yes - GTK_WIN_POS_NONE - yes - - - - 4 - no - 4 - yes - - - - Alarm Repeat - 0 - GTK_SHADOW_ETCHED_IN - yes - - - - 4 - no - 4 - yes - - - - yes - yes - Repeat the alarm - no - yes - yes - - - 0 - no - no - - - - - - no - 4 - yes - - - - yes - 1 - 0 - no - GTK_UPDATE_ALWAYS - no - no - yes - 1 1 999 1 10 10 - - - 0 - yes - yes - - - - - - extra times every - GTK_JUSTIFY_CENTER - no - 0.5 - 0.5 - 0 - 0 - yes - - - 0 - no - no - - - - - - yes - 1 - 0 - no - GTK_UPDATE_ALWAYS - no - no - yes - 1 0 999 1 10 10 - - - 0 - yes - yes - - - - - - yes - 0 - yes - - - - yes - - - - minutes - yes - - - - - - hours - yes - - - - - - days - yes - - - - - - - 0 - no - no - - - - - 0 - no - no - - - - - - - 0 - no - no - - - - - - no - no - 4 - - - - Message to Display - GTK_JUSTIFY_CENTER - no - 0 - 0.5 - 0 - 0 - yes - - - 0 - no - no - - - - - - GTK_POLICY_NEVER - GTK_POLICY_AUTOMATIC - GTK_SHADOW_IN - yes - - - - yes - yes - - GTK_WRAP_WORD - yes - - - - - - GTK_UPDATE_CONTINUOUS - yes - - - - - - GTK_UPDATE_CONTINUOUS - yes - - - - - 0 - yes - yes - - - - - 0 - yes - yes - - - - - - no - no - 4 - - - - Play sound: - GTK_JUSTIFY_CENTER - no - 0.5 - 0.5 - 0 - 0 - yes - - - 0 - no - no - - - - - - no - no - yes - - - - yes - yes - - 0 - yes - yes - - - - - 0 - yes - yes - - - - - 0 - no - no - - - - - - no - Evolution does not yet support email notification for reminders. You will not be able to edit the options for this reminder. - GTK_JUSTIFY_CENTER - yes - 0.5 - 0.5 - 0 - 0 - - - 0 - no - no - - - - - - no - no - 4 - - - - Run program: - GTK_JUSTIFY_CENTER - no - 0.5 - 0.5 - 0 - 0 - yes - - - 0 - no - no - - - - - - yes - yes - - 0 - yes - yes - - - 0 - yes - yes - - - - - - With these arguments: - GTK_JUSTIFY_CENTER - no - 0.5 - 0.5 - 0 - 0 - yes - - - 0 - no - no - - - - - - yes - yes - - 0 - yes - yes - - - 0 - yes - yes - - - - - 0 - no - no - - - - - - GTK_BUTTONBOX_END - 30 - yes - - - - yes - yes - yes - GTK_RELIEF_NORMAL - yes - gtk-ok - yes - yes - - - - - - yes - yes - GTK_RELIEF_NORMAL - yes - gtk-cancel - yes - yes - - - - - 0 - no - no - - - - - + + + + + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + True + True + False + + + + 4 + True + False + 4 + + + + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + 4 + True + False + 4 + + + + True + True + True + Repeat the alarm + True + GTK_RELIEF_NORMAL + False + False + True + + + 0 + False + False + + + + + + True + False + 4 + + + + True + True + 1 + 0 + False + GTK_UPDATE_ALWAYS + False + False + 1 1 999 1 10 10 + + + 0 + True + True + + + + + + True + extra times every + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + True + 1 + 0 + False + GTK_UPDATE_ALWAYS + False + False + 1 0 999 1 10 10 + + + 0 + True + True + + + + + + True + True + 0 + + + + True + + + + True + minutes + True + + + + + + True + hours + True + + + + + + True + days + True + + + + + + + 0 + False + False + + + + + 0 + False + False + + + + + + + + True + Alarm Repeat + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + + + label_item + + + + + 0 + False + False + + + + + + False + 4 + + + + True + Message to Display + False + False + GTK_JUSTIFY_CENTER + False + False + 0 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + GTK_POLICY_NEVER + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + GTK_CORNER_TOP_LEFT + + + + True + True + True + GTK_JUSTIFY_LEFT + GTK_WRAP_WORD + True + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + 0 + True + True + + + + + 0 + True + True + + + + + + False + 4 + + + + True + Play sound: + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + 10 + False + False + + + + True + True + True + True + 0 + + True + * + False + + + + + 0 + True + True + + + + + 0 + False + False + + + + + + True + False + 4 + + + + True + False + 4 + + + + True + True + Send To: + True + GTK_RELIEF_NORMAL + + + 0 + False + False + + + + + + + + + 0 + True + True + + + + + + True + Message to Send + False + False + GTK_JUSTIFY_CENTER + False + False + 0 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + True + GTK_POLICY_NEVER + GTK_POLICY_AUTOMATIC + GTK_SHADOW_NONE + GTK_CORNER_TOP_LEFT + + + + True + True + True + GTK_JUSTIFY_LEFT + GTK_WRAP_WORD + True + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + 0 + True + True + + + + + 0 + False + False + + + + + + False + 4 + + + + True + Run program: + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + True + True + True + 0 + + True + * + False + + + 0 + True + True + + + + + + True + With these arguments: + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + True + True + True + 0 + + True + * + False + + + 0 + True + True + + + + + 0 + False + False + + + + + + True + GTK_BUTTONBOX_END + 30 + + + + True + True + True + True + gtk-ok + True + GTK_RELIEF_NORMAL + + + + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + + + + + 0 + False + False + + + + + + diff --git a/calendar/gui/dialogs/alarm-options.h b/calendar/gui/dialogs/alarm-options.h index 388b737541..1b4abb56d9 100644 --- a/calendar/gui/dialogs/alarm-options.h +++ b/calendar/gui/dialogs/alarm-options.h @@ -23,6 +23,6 @@ #include -gboolean alarm_options_dialog_run (CalComponentAlarm *alarm); +gboolean alarm_options_dialog_run (CalComponentAlarm *alarm, const char *email, gboolean repeat); #endif diff --git a/calendar/gui/dialogs/alarm-page.c b/calendar/gui/dialogs/alarm-page.c index 7c861c6add..b28e0dd0b3 100644 --- a/calendar/gui/dialogs/alarm-page.c +++ b/calendar/gui/dialogs/alarm-page.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -99,9 +100,17 @@ static const int action_map[] = { CAL_ALARM_DISPLAY, CAL_ALARM_AUDIO, CAL_ALARM_PROCEDURE, + CAL_ALARM_EMAIL, -1 }; +static const char *action_map_cap[] = { + "no-display-alarms", + "no-audio-alarms", + "no-procedure-alarms", + "no-email-alarms" +}; + static const int value_map[] = { MINUTES, HOURS, @@ -299,171 +308,20 @@ clear_widgets (AlarmPage *apage) e_alarm_list_clear (priv->list_store); } -/* Builds a string for the duration of the alarm. If the duration is zero, returns NULL. */ -static char * -get_alarm_duration_string (struct icaldurationtype *duration) -{ - GString *string = g_string_new (NULL); - char *ret; - gboolean have_something; - - have_something = FALSE; - - if (duration->days > 1) { - g_string_sprintf (string, _("%d days"), duration->days); - have_something = TRUE; - } else if (duration->days == 1) { - g_string_append (string, _("1 day")); - have_something = TRUE; - } - - if (duration->weeks > 1) { - g_string_sprintf (string, _("%d weeks"), duration->weeks); - have_something = TRUE; - } else if (duration->weeks == 1) { - g_string_append (string, _("1 week")); - have_something = TRUE; - } - - if (duration->hours > 1) { - g_string_sprintf (string, _("%d hours"), duration->hours); - have_something = TRUE; - } else if (duration->hours == 1) { - g_string_append (string, _("1 hour")); - have_something = TRUE; - } - - if (duration->minutes > 1) { - g_string_sprintf (string, _("%d minutes"), duration->minutes); - have_something = TRUE; - } else if (duration->minutes == 1) { - g_string_append (string, _("1 minute")); - have_something = TRUE; - } - - if (duration->seconds > 1) { - g_string_sprintf (string, _("%d seconds"), duration->seconds); - have_something = TRUE; - } else if (duration->seconds == 1) { - g_string_append (string, _("1 second")); - have_something = TRUE; - } - - if (have_something) { - ret = string->str; - g_string_free (string, FALSE); - return ret; - } else { - g_string_free (string, TRUE); - return NULL; - } -} - -static char * -get_alarm_string (CalComponentAlarm *alarm) +static void +sensitize_buttons (AlarmPage *apage) { - CalAlarmAction action; - CalAlarmTrigger trigger; - char string[256]; - char *base, *str = NULL, *dur; - - string [0] = '\0'; - - cal_component_alarm_get_action (alarm, &action); - cal_component_alarm_get_trigger (alarm, &trigger); - - switch (action) { - case CAL_ALARM_AUDIO: - base = _("Play a sound"); - break; - - case CAL_ALARM_DISPLAY: - base = _("Display a message"); - break; - - case CAL_ALARM_EMAIL: - base = _("Send an email"); - break; - - case CAL_ALARM_PROCEDURE: - base = _("Run a program"); - break; - - case CAL_ALARM_NONE: - case CAL_ALARM_UNKNOWN: - default: - base = _("Unknown action to be performed"); - break; - } - - /* FIXME: This does not look like it will localize correctly. */ - - switch (trigger.type) { - case CAL_ALARM_TRIGGER_RELATIVE_START: - dur = get_alarm_duration_string (&trigger.u.rel_duration); - - if (dur) { - if (trigger.u.rel_duration.is_neg) - str = g_strdup_printf (_("%s %s before the start of the appointment"), - base, dur); - else - str = g_strdup_printf (_("%s %s after the start of the appointment"), - base, dur); - - g_free (dur); - } else - str = g_strdup_printf (_("%s at the start of the appointment"), base); - - break; - - case CAL_ALARM_TRIGGER_RELATIVE_END: - dur = get_alarm_duration_string (&trigger.u.rel_duration); - - if (dur) { - if (trigger.u.rel_duration.is_neg) - str = g_strdup_printf (_("%s %s before the end of the appointment"), - base, dur); - else - str = g_strdup_printf (_("%s %s after the end of the appointment"), - base, dur); - - g_free (dur); - } else - str = g_strdup_printf (_("%s at the end of the appointment"), base); - - break; - - case CAL_ALARM_TRIGGER_ABSOLUTE: { - struct icaltimetype itt; - icaltimezone *utc_zone, *current_zone; - char *location; - struct tm tm; - char buf[256]; - - /* Absolute triggers come in UTC, so convert them to the local timezone */ - - itt = trigger.u.abs_time; - - utc_zone = icaltimezone_get_utc_timezone (); - location = calendar_config_get_timezone (); - current_zone = icaltimezone_get_builtin_timezone (location); - - tm = icaltimetype_to_tm_with_zone (&itt, utc_zone, current_zone); - - e_time_format_date_and_time (&tm, calendar_config_get_24_hour_format (), - FALSE, FALSE, buf, sizeof (buf)); - - str = g_strdup_printf (_("%s at %s"), base, buf); - - break; } - - case CAL_ALARM_TRIGGER_NONE: - default: - str = g_strdup_printf (_("%s for an unknown trigger type"), base); - break; - } + AlarmPagePrivate *priv; + CalClient *client; + GtkCList *clist; + + priv = apage->priv; + + client = COMP_EDITOR_PAGE (apage)->client; + clist = GTK_CLIST (priv->list); - return str; + gtk_widget_set_sensitive (priv->add, cal_client_get_one_alarm_only (client) && clist->rows > 0 ? FALSE : TRUE); + gtk_widget_set_sensitive (priv->delete, clist->rows > 0 ? TRUE : FALSE); } /* Appends an alarm to the list */ @@ -479,7 +337,8 @@ append_reminder (AlarmPage *apage, CalComponentAlarm *alarm) e_alarm_list_append (priv->list_store, &iter, alarm); gtk_tree_selection_select_iter (gtk_tree_view_get_selection (view), &iter); - gtk_widget_set_sensitive (priv->delete, TRUE); + + sensitize_buttons (apage); } /* fill_widgets handler for the alarm page */ @@ -488,10 +347,12 @@ alarm_page_fill_widgets (CompEditorPage *page, CalComponent *comp) { AlarmPage *apage; AlarmPagePrivate *priv; + GtkWidget *menu; CalComponentText text; GList *alarms, *l; CompEditorPageDates dates; - + int i; + apage = ALARM_PAGE (page); priv = apage->priv; @@ -533,6 +394,16 @@ alarm_page_fill_widgets (CompEditorPage *page, CalComponent *comp) out: + /* Alarm types */ + menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->action)); + for (i = 0, l = GTK_MENU_SHELL (menu)->children; action_map[i] != -1; i++, l = l->next) { + if (cal_client_get_static_capability (page->client, action_map_cap[i])) + gtk_widget_set_sensitive (l->data, FALSE); + else + gtk_widget_set_sensitive (l->data, TRUE); + } + + priv->updating = FALSE; } @@ -718,7 +589,8 @@ add_clicked_cb (GtkButton *button, gpointer data) AlarmPagePrivate *priv; CalComponentAlarm *alarm; CalAlarmTrigger trigger; - + CalAlarmAction action; + apage = ALARM_PAGE (data); priv = apage->priv; @@ -752,7 +624,24 @@ add_clicked_cb (GtkButton *button, gpointer data) } cal_component_alarm_set_trigger (alarm, trigger); - cal_component_alarm_set_action (alarm, e_dialog_option_menu_get (priv->action, action_map)); + action = e_dialog_option_menu_get (priv->action, action_map); + cal_component_alarm_set_action (alarm, action); + if (action == CAL_ALARM_EMAIL && !cal_component_alarm_has_attendees (alarm)) { + const char *email; + + email = cal_client_get_alarm_email_address (COMP_EDITOR_PAGE (apage)->client); + if (email != NULL) { + CalComponentAttendee *a; + GSList attendee_list; + + a = g_new0 (CalComponentAttendee, 1); + a->value = email; + attendee_list.data = a; + attendee_list.next = NULL; + cal_component_alarm_set_attendee_list (alarm, &attendee_list); + g_free (a); + } + } append_reminder (apage, alarm); } @@ -787,12 +676,10 @@ delete_clicked_cb (GtkButton *button, gpointer data) valid_iter = gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->list_store), &iter, path); } - if (valid_iter) { + if (valid_iter) gtk_tree_selection_select_iter (selection, &iter); - gtk_widget_set_sensitive (priv->delete, TRUE); - } - else - gtk_widget_set_sensitive (priv->delete, FALSE); + + sensitize_buttons (apage); gtk_tree_path_free (path); } @@ -803,14 +690,18 @@ button_options_clicked_cb (GtkWidget *widget, gpointer data) { AlarmPage *apage; AlarmPagePrivate *priv; - + gboolean repeat; + const char *email; + apage = ALARM_PAGE (data); priv = apage->priv; cal_component_alarm_set_action (priv->alarm, e_dialog_option_menu_get (priv->action, action_map)); - if (!alarm_options_dialog_run (priv->alarm)) + repeat = !cal_client_get_static_capability (COMP_EDITOR_PAGE (apage)->client, "no-alarm-repeat"); + email = cal_client_get_alarm_email_address (COMP_EDITOR_PAGE (apage)->client); + if (!alarm_options_dialog_run (priv->alarm, email, repeat)) g_message ("button_options_clicked_cb(): Could not create the alarm options dialog"); } @@ -830,8 +721,6 @@ init_widgets (AlarmPage *apage) g_signal_connect ((priv->delete), "clicked", G_CALLBACK (delete_clicked_cb), apage); - gtk_widget_set_sensitive (priv->delete, FALSE); - /* Connect the default signal handler to use to make sure we notify * upstream of changes to the widget values. */ @@ -859,6 +748,7 @@ init_widgets (AlarmPage *apage) gtk_tree_view_column_add_attribute (column, cell_renderer, "text", E_ALARM_LIST_COLUMN_DESCRIPTION); gtk_tree_view_append_column (GTK_TREE_VIEW (priv->list), column); + sensitize_buttons (apage); #if 0 /* If we want the alarm setup widgets to reflect the currently selected alarm, we * need to do something like this */ diff --git a/calendar/gui/dialogs/alarm-page.glade b/calendar/gui/dialogs/alarm-page.glade index 7de2ffe39e..cb4509abe2 100644 --- a/calendar/gui/dialogs/alarm-page.glade +++ b/calendar/gui/dialogs/alarm-page.glade @@ -1,454 +1,490 @@ - + - - no - window1 - GTK_WINDOW_TOPLEVEL - no - no - yes - GTK_WIN_POS_NONE - - - - 4 - no - 4 - yes - - - - Basics - 0 - GTK_SHADOW_ETCHED_IN - yes - - - - 4 - no - 2 - 2 - 2 - 2 - yes - - - - Summary: - GTK_JUSTIFY_CENTER - no - 0 - 0.5 - 0 - 0 - yes - - - 0 - 1 - 0 - 1 - 0 - 0 - fill - - - - - - - Date/Time: - GTK_JUSTIFY_CENTER - no - 0 - 0 - 0 - 0 - yes - - - 0 - 1 - 1 - 2 - 0 - 0 - fill - fill - - - - - - - GTK_JUSTIFY_LEFT - no - 0 - 0.5 - 4 - 0 - 10 - yes - - - 1 - 2 - 0 - 1 - 0 - 0 - expand|fill - - - - - - - - GTK_JUSTIFY_LEFT - no - 7.45058e-09 - 0.5 - 4 - 0 - 10 - yes - - - 1 - 2 - 1 - 2 - 0 - 0 - expand|fill - fill - - - - - - - 0 - no - yes - - - - - - Reminders - 0 - GTK_SHADOW_ETCHED_IN - yes - - - - 4 - no - 4 - yes - - - - no - 4 - yes - - - - yes - 0 - yes - - - - yes - - - - Display a message - yes - - - - - - Play a sound - yes - - - - - - Run a program - yes - - - - - - - 0 - no - no - - - - - - yes - 1 - 0 - yes - GTK_UPDATE_ALWAYS - no - no - yes - 1 0 999 1 10 10 - - - 0 - no - yes - - - - - - yes - 0 - yes - - - - yes - - - - minute(s) - yes - - - - - - hour(s) - yes - - - - - - day(s) - yes - - - - - - - 0 - no - no - - - - - - yes - 0 - yes - - - - yes - - - - before - yes - - - - - - after - yes - - - - - - - 0 - no - no - - - - - - yes - 0 - yes - - - - yes - - - - start of appointment - yes - - - - - - end of appointment - yes - - - - - - - 0 - no - no - - - - - - yes - _Options... - yes - yes - - - 0 - no - no - - - - - 0 - no - yes - - - - - - no - 0 - yes - - - - GTK_POLICY_NEVER - GTK_POLICY_AUTOMATIC - GTK_SHADOW_IN - yes - - - - yes - no - yes - - - - CList:title - label55 - GTK_JUSTIFY_CENTER - no - 0.5 - 0.5 - 0 - 0 - yes - - - - - - - - GTK_UPDATE_CONTINUOUS - yes - - - - - - GTK_UPDATE_CONTINUOUS - yes - - - - - 0 - yes - yes - - - - - - GTK_BUTTONBOX_START - 10 - yes - - - - yes - yes - _Add - yes - yes - - - - - - yes - yes - _Delete - yes - yes - - - - - 0 - no - no - - - - - 0 - yes - yes - - - - - - - 0 - yes - yes - - - - - + + + window1 + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + False + + + + 4 + True + False + 4 + + + + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + 4 + True + 2 + 2 + False + 2 + 2 + + + + True + Summary: + False + False + GTK_JUSTIFY_CENTER + False + False + 0 + 0.5 + 0 + 0 + + + 0 + 1 + 0 + 1 + fill + + + + + + + True + Date/Time: + False + False + GTK_JUSTIFY_CENTER + False + False + 0 + 0 + 0 + 0 + + + 0 + 1 + 1 + 2 + fill + fill + + + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 4 + 0 + + + 1 + 2 + 0 + 1 + + + + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 7.45058e-09 + 0.5 + 4 + 0 + + + 1 + 2 + 1 + 2 + fill + + + + + + + + True + Basics + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + + + label_item + + + + + 0 + False + True + + + + + + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + 4 + True + False + 4 + + + + True + False + 4 + + + + True + True + 0 + + + + True + + + + True + Display a message + True + + + + + + True + Play a sound + True + + + + + + True + Run a program + True + + + + + + True + Send an Email + True + + + + + + + 0 + False + False + + + + + + True + True + 1 + 0 + True + GTK_UPDATE_ALWAYS + False + False + 1 0 999 1 10 10 + + + 0 + False + True + + + + + + True + True + 0 + + + + True + + + + True + minute(s) + True + + + + + + True + hour(s) + True + + + + + + True + day(s) + True + + + + + + + 0 + False + False + + + + + + True + True + 0 + + + + True + + + + True + before + True + + + + + + True + after + True + + + + + + + 0 + False + False + + + + + + True + True + 0 + + + + True + + + + True + start of appointment + True + + + + + + True + end of appointment + True + + + + + + + 0 + False + False + + + + + + True + True + _Options... + True + GTK_RELIEF_NORMAL + + + 0 + False + False + + + + + 0 + False + True + + + + + + True + False + 0 + + + + True + GTK_POLICY_NEVER + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + GTK_CORNER_TOP_LEFT + + + + True + True + True + False + False + True + + + + + 0 + True + True + + + + + + True + GTK_BUTTONBOX_START + 10 + + + + True + True + True + _Add + True + GTK_RELIEF_NORMAL + + + + + + True + True + True + _Delete + True + GTK_RELIEF_NORMAL + + + + + 0 + False + False + + + + + 0 + True + True + + + + + + + + True + Reminders + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + + + label_item + + + + + 0 + True + True + + + + + + diff --git a/calendar/gui/dialogs/cancel-comp.c b/calendar/gui/dialogs/cancel-comp.c index a0e84b4421..442426fa5d 100644 --- a/calendar/gui/dialogs/cancel-comp.c +++ b/calendar/gui/dialogs/cancel-comp.c @@ -41,12 +41,15 @@ * Return value: TRUE if the user clicked Yes, FALSE otherwise. **/ gboolean -cancel_component_dialog (CalComponent *comp, gboolean deleting) +cancel_component_dialog (CalClient *client, CalComponent *comp, gboolean deleting) { GtkWidget *dialog; CalComponentVType vtype; char *str; + if (deleting && cal_client_get_save_schedules (client)) + return TRUE; + vtype = cal_component_get_vtype (comp); switch (vtype) { diff --git a/calendar/gui/dialogs/cancel-comp.h b/calendar/gui/dialogs/cancel-comp.h index b05d6a5cab..9c31a49fd8 100644 --- a/calendar/gui/dialogs/cancel-comp.h +++ b/calendar/gui/dialogs/cancel-comp.h @@ -22,8 +22,9 @@ #define CANCEL_COMP_H #include +#include #include -gboolean cancel_component_dialog (CalComponent *comp, gboolean deleting); +gboolean cancel_component_dialog (CalClient *client, CalComponent *comp, gboolean deleting); #endif diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c index 7d619380b7..af97707f9e 100644 --- a/calendar/gui/dialogs/comp-editor.c +++ b/calendar/gui/dialogs/comp-editor.c @@ -47,6 +47,7 @@ #include "send-comp.h" #include "changed-comp.h" #include "cancel-comp.h" +#include "recur-comp.h" #include "comp-editor.h" @@ -73,6 +74,8 @@ struct _CompEditorPrivate { gboolean changed; gboolean needs_send; + CalObjModType mod; + gboolean existing_org; gboolean user_org; @@ -227,6 +230,7 @@ comp_editor_init (CompEditor *editor) priv->pages = NULL; priv->changed = FALSE; priv->needs_send = FALSE; + priv->mod = CALOBJ_MOD_ALL; priv->existing_org = FALSE; priv->user_org = FALSE; priv->warned = FALSE; @@ -302,7 +306,7 @@ save_comp (CompEditor *editor) } /* If we are not the organizer, we don't update the sequence number */ - if (!cal_component_has_organizer (clone) || itip_organizer_is_user (clone)) + if (!cal_component_has_organizer (clone) || itip_organizer_is_user (clone, priv->client)) cal_component_commit_sequence (clone); else cal_component_abort_sequence (clone); @@ -312,7 +316,10 @@ save_comp (CompEditor *editor) priv->updating = TRUE; - result = cal_client_update_object (priv->client, priv->comp); + if (cal_component_is_instance (priv->comp)) + result = cal_client_update_object_with_mod (priv->client, priv->comp, priv->mod); + else + result = cal_client_update_object (priv->client, priv->comp); if (result != CAL_CLIENT_RESULT_SUCCESS) { GtkWidget *dlg; char *msg; @@ -359,8 +366,8 @@ save_comp_with_send (CompEditor *editor) if (!save_comp (editor)) return FALSE; - if (send && send_component_dialog (priv->comp, !priv->existing_org)) { - if (itip_organizer_is_user (priv->comp)) + if (send && send_component_dialog (priv->client, priv->comp, !priv->existing_org)) { + if (itip_organizer_is_user (priv->comp, priv->client)) return comp_editor_send_comp (editor, CAL_COMPONENT_METHOD_REQUEST); else return comp_editor_send_comp (editor, CAL_COMPONENT_METHOD_REPLY); @@ -396,6 +403,10 @@ prompt_to_save_changes (CompEditor *editor, gboolean send) switch (save_component_dialog (GTK_WINDOW (editor))) { case 0: /* Save */ + if (cal_component_is_instance (priv->comp)) + if (!recur_component_dialog (priv->comp, &priv->mod, GTK_WINDOW (editor))) + return FALSE; + if (send && save_comp_with_send (editor)) return TRUE; else if (!send && save_comp (editor)) @@ -919,9 +930,9 @@ real_edit_comp (CompEditor *editor, CalComponent *comp) if (comp) priv->comp = cal_component_clone (comp); - + priv->existing_org = cal_component_has_organizer (comp); - priv->user_org = itip_organizer_is_user (comp); + priv->user_org = itip_organizer_is_user (comp, priv->client); priv->warned = FALSE; set_title_from_comp (editor); @@ -1173,9 +1184,16 @@ static void save_cmd (GtkWidget *widget, gpointer data) { CompEditor *editor = COMP_EDITOR (data); + CompEditorPrivate *priv; + + priv = editor->priv; commit_all_fields (editor); + if (cal_component_is_instance (priv->comp)) + if (!recur_component_dialog (priv->comp, &priv->mod, GTK_WINDOW (editor))) + return; + save_comp_with_send (editor); } @@ -1183,9 +1201,16 @@ static void save_close_cmd (GtkWidget *widget, gpointer data) { CompEditor *editor = COMP_EDITOR (data); - + CompEditorPrivate *priv; + + priv = editor->priv; + commit_all_fields (editor); + if (cal_component_is_instance (priv->comp)) + if (!recur_component_dialog (priv->comp, &priv->mod, GTK_WINDOW (editor))) + return; + if (save_comp_with_send (editor)) close_dialog (editor); } @@ -1236,8 +1261,8 @@ delete_cmd (GtkWidget *widget, gpointer data) vtype = cal_component_get_vtype (priv->comp); if (delete_component_dialog (priv->comp, FALSE, 1, vtype, GTK_WIDGET (editor))) { - if (itip_organizer_is_user (priv->comp) - && cancel_component_dialog (priv->comp, TRUE)) + if (itip_organizer_is_user (priv->comp, priv->client) + && cancel_component_dialog (priv->client, priv->comp, TRUE)) itip_send_comp (CAL_COMPONENT_METHOD_CANCEL, priv->comp, priv->client, NULL); delete_comp (editor); @@ -1304,7 +1329,7 @@ page_changed_cb (GtkObject *obj, gpointer data) if (!priv->warned && priv->existing_org && !priv->user_org) { e_notice (NULL, GTK_MESSAGE_INFO, - _("Changes made to this item may be discarded if an update arrives via email")); + _("Changes made to this item may be discarded if an update arrives")); priv->warned = TRUE; } @@ -1328,7 +1353,7 @@ page_summary_changed_cb (GtkObject *obj, const char *summary, gpointer data) if (!priv->warned && priv->existing_org && !priv->user_org) { e_notice (NULL, GTK_MESSAGE_INFO, - _("Changes made to this item may be discarded if an update arrives via email")); + _("Changes made to this item may be discarded if an update arrives")); priv->warned = TRUE; } } @@ -1352,7 +1377,7 @@ page_dates_changed_cb (GtkObject *obj, if (!priv->warned && priv->existing_org && !priv->user_org) { e_notice (NULL, GTK_MESSAGE_INFO, - _("Changes made to this item may be discarded if an update arrives via email")); + _("Changes made to this item may be discarded if an update arrives")); priv->warned = TRUE; } } diff --git a/calendar/gui/dialogs/event-editor.c b/calendar/gui/dialogs/event-editor.c index cc89bd9683..4253ba8889 100644 --- a/calendar/gui/dialogs/event-editor.c +++ b/calendar/gui/dialogs/event-editor.c @@ -46,7 +46,7 @@ struct _EventEditorPrivate { SchedulePage *sched_page; EMeetingModel *model; - + gboolean meeting_shown; gboolean updating; }; @@ -257,6 +257,7 @@ event_editor_edit_comp (CompEditor *editor, CalComponent *comp) EventEditor *ee; EventEditorPrivate *priv; CalComponentOrganizer organizer; + CalClient *client; GSList *attendees = NULL; ee = EVENT_EDITOR (editor); @@ -267,12 +268,13 @@ event_editor_edit_comp (CompEditor *editor, CalComponent *comp) if (parent_class->edit_comp) parent_class->edit_comp (editor, comp); + client = comp_editor_get_cal_client (COMP_EDITOR (editor)); + /* Get meeting related stuff */ cal_component_get_organizer (comp, &organizer); cal_component_get_attendee_list (comp, &attendees); /* Clear things up */ - e_meeting_model_restricted_clear (priv->model); e_meeting_model_remove_all_attendees (priv->model); /* Set up the attendees */ @@ -282,6 +284,7 @@ event_editor_edit_comp (CompEditor *editor, CalComponent *comp) priv->meeting_shown = FALSE; } else { GSList *l; + int row; if (!priv->meeting_shown) { comp_editor_append_page (COMP_EDITOR (ee), @@ -297,39 +300,44 @@ event_editor_edit_comp (CompEditor *editor, CalComponent *comp) EMeetingAttendee *ia; ia = E_MEETING_ATTENDEE (e_meeting_attendee_new_from_cal_component_attendee (ca)); + if (!comp_editor_get_user_org (editor)) + e_meeting_attendee_set_edit_level (ia, E_MEETING_ATTENDEE_EDIT_NONE); e_meeting_model_add_attendee (priv->model, ia); - - g_object_unref((ia)); + + g_object_unref(ia); } - if (organizer.value != NULL) { + /* If we aren't the organizer we can still change our own status */ + if (!comp_editor_get_user_org (editor)) { EAccountList *accounts; EAccount *account; EIterator *it; - const char *strip; - int row; - - strip = itip_strip_mailto (organizer.value); accounts = itip_addresses_get (); for (it = e_list_get_iterator((EList *)accounts);e_iterator_is_valid(it);e_iterator_next(it)) { + EMeetingAttendee *ia; + account = (EAccount*)e_iterator_get(it); - if (e_meeting_model_find_attendee (priv->model, account->id->address, &row)) - e_meeting_model_restricted_add (priv->model, row); + ia = e_meeting_model_find_attendee (priv->model, account->id->address, &row); + if (ia != NULL) + e_meeting_attendee_set_edit_level (ia, E_MEETING_ATTENDEE_EDIT_STATUS); } g_object_unref(it); + } else if (cal_client_get_organizer_must_attend (client)) { + EMeetingAttendee *ia; + + ia = e_meeting_model_find_attendee (priv->model, organizer.value, &row); + if (ia != NULL) + e_meeting_attendee_set_edit_level (ia, E_MEETING_ATTENDEE_EDIT_NONE); } - if (comp_editor_get_user_org (editor)) - e_meeting_model_restricted_clear (priv->model); - priv->meeting_shown = TRUE; } cal_component_free_attendee_list (attendees); set_menu_sens (ee); - comp_editor_set_needs_send (COMP_EDITOR (ee), priv->meeting_shown && itip_organizer_is_user (comp)); + comp_editor_set_needs_send (COMP_EDITOR (ee), priv->meeting_shown && itip_organizer_is_user (comp, client)); priv->updating = FALSE; } @@ -469,7 +477,7 @@ cancel_meeting_cmd (GtkWidget *widget, gpointer data) CalComponent *comp; comp = comp_editor_get_current_comp (COMP_EDITOR (ee)); - if (cancel_component_dialog (comp, FALSE)) { + if (cancel_component_dialog (comp_editor_get_cal_client (COMP_EDITOR (ee)), comp, FALSE)) { comp_editor_send_comp (COMP_EDITOR (ee), CAL_COMPONENT_METHOD_CANCEL); comp_editor_delete_comp (COMP_EDITOR (ee)); } diff --git a/calendar/gui/dialogs/event-page.c b/calendar/gui/dialogs/event-page.c index e9bc511ece..a7e1655c5a 100644 --- a/calendar/gui/dialogs/event-page.c +++ b/calendar/gui/dialogs/event-page.c @@ -67,7 +67,8 @@ struct _EventPagePrivate { GtkWidget *classification_public; GtkWidget *classification_private; GtkWidget *classification_confidential; - + + GtkWidget *show_time_frame; GtkWidget *show_time_as_free; GtkWidget *show_time_as_busy; @@ -164,6 +165,7 @@ event_page_init (EventPage *epage) priv->classification_public = NULL; priv->classification_private = NULL; priv->classification_confidential = NULL; + priv->show_time_frame = NULL; priv->show_time_as_free = NULL; priv->show_time_as_busy = NULL; priv->contacts_btn = NULL; @@ -454,7 +456,7 @@ event_page_fill_widgets (CompEditorPage *page, CalComponent *comp) const char *location; const char *categories; GSList *l; - + g_return_if_fail (page->client != NULL); epage = EVENT_PAGE (page); @@ -539,8 +541,10 @@ event_page_fill_widgets (CompEditorPage *page, CalComponent *comp) transparency_map); break; } - - + if (cal_client_get_static_capability (page->client, "no-transparency")) + gtk_widget_hide (priv->show_time_frame); + else + gtk_widget_show (priv->show_time_frame); /* Categories */ cal_component_get_categories (comp, &categories); @@ -791,6 +795,7 @@ get_widgets (EventPage *epage) priv->classification_private = GW ("classification-private"); priv->classification_confidential = GW ("classification-confidential"); + priv->show_time_frame = GW ("show-time-frame"); priv->show_time_as_free = GW ("show-time-as-free"); priv->show_time_as_busy = GW ("show-time-as-busy"); @@ -813,6 +818,7 @@ get_widgets (EventPage *epage) && priv->classification_public && priv->classification_private && priv->classification_confidential + && priv->show_time_frame && priv->show_time_as_free && priv->show_time_as_busy && priv->contacts_btn diff --git a/calendar/gui/dialogs/event-page.glade b/calendar/gui/dialogs/event-page.glade index 590d744f4a..6693c8af65 100644 --- a/calendar/gui/dialogs/event-page.glade +++ b/calendar/gui/dialogs/event-page.glade @@ -1,599 +1,662 @@ - + - - no - window1 - GTK_WINDOW_TOPLEVEL - no - no - yes - GTK_WIN_POS_NONE - - - - 4 - no - 6 - yes - - - - no - 4 - 4 - 2 - 2 - yes - - - - Su_mmary: - GTK_JUSTIFY_CENTER - no - 7.45058e-09 - 0.5 - 0 - 0 - general-summary - yes - yes - - - 0 - 1 - 0 - 1 - 0 - 0 - fill - - - - - - - yes - yes - - 0 - yes - yes - - - 1 - 2 - 0 - 1 - 0 - 0 - expand|fill - - - - - - - L_ocation: - GTK_JUSTIFY_CENTER - no - 7.45058e-09 - 0.5 - 0 - 0 - location - yes - yes - - - 0 - 1 - 1 - 2 - 0 - 0 - fill - - - - - - - yes - yes - - 0 - yes - yes - - - 1 - 2 - 1 - 2 - 0 - 0 - expand|fill - - - - - - 0 - no - yes - - - - - - Date & Time - 0 - GTK_SHADOW_ETCHED_IN - yes - - - - 4 - no - 4 - 4 - 2 - 4 - yes - - - - _Start time: - GTK_JUSTIFY_CENTER - no - 0 - 0.5 - 0 - 0 - start-time - yes - yes - - - 0 - 1 - 0 - 1 - 0 - 0 - fill - - - - - - - _End time: - GTK_JUSTIFY_CENTER - no - 0 - 0.5 - 0 - 0 - end-time - yes - yes - - - 0 - 1 - 1 - 2 - 0 - 0 - fill - - - - - - - yes - make_date_edit - - - 0 - 0 - Tue, 16 May 2000 19:11:05 GMT - yes - - - 1 - 2 - 0 - 1 - 0 - 0 - - expand|fill - - - - - - yes - make_date_edit - 0 - 0 - Tue, 16 May 2000 19:11:10 GMT - yes - - - 1 - 2 - 1 - 2 - 0 - 0 - - expand|fill - - - - - - make_timezone_entry - 0 - 0 - Mon, 18 Jun 2001 23:51:40 GMT - yes - - - 2 - 3 - 1 - 2 - 0 - 0 - - fill - - - - - - make_timezone_entry - 0 - 0 - Mon, 18 Jun 2001 23:51:34 GMT - yes - - - 2 - 3 - 0 - 1 - 0 - 0 - fill - fill - - - - - - 1 - 7.45058e-09 - 0 - 0 - yes - - - - yes - A_ll day event - no - yes - yes - yes - - - - - 3 - 4 - 0 - 2 - 0 - 0 - expand|fill - fill - - - - - - - 0 - no - no - - - - - - GTK_POLICY_NEVER - GTK_POLICY_AUTOMATIC - GTK_SHADOW_IN - yes - - - - yes - yes - - GTK_WRAP_WORD - yes - - - - - - GTK_UPDATE_CONTINUOUS - yes - - - - - - GTK_UPDATE_CONTINUOUS - yes - - - - - 0 - yes - yes - - - - - - no - 4 - yes - - - - Classification - 0 - GTK_SHADOW_ETCHED_IN - yes - - - - 2 - no - 4 - yes - - - - yes - Pu_blic - yes - yes - yes - yes - - - 0 - yes - yes - - - - - - yes - Pri_vate - no - yes - yes - classification-public - yes - - - 0 - yes - yes - - - - - - yes - Con_fidential - no - yes - yes - classification-public - yes - - - 0 - yes - yes - - - - - - - 0 - no - yes - - - - - - Show Time As - 0 - GTK_SHADOW_ETCHED_IN - yes - - - - no - 4 - yes - - - - yes - F_ree - no - yes - yes - yes - - - 0 - yes - yes - - - - - - yes - B_usy - no - yes - yes - show-time-as-free - yes - - - 0 - yes - yes - - - - - - - 0 - no - yes - - - - - 0 - no - no - - - - - - no - 2 - yes - - - - yes - GTK_RELIEF_NORMAL - yes - - - - _Contacts... - GTK_JUSTIFY_CENTER - no - 0.5 - 0.5 - 4 - 0 - yes - yes - - - - - 0 - no - no - - - - - - yes - - - - - - - 0 - yes - yes - - - - - - yes - GTK_RELIEF_NORMAL - yes - - - - Ca_tegories... - GTK_JUSTIFY_CENTER - no - 0.5 - 0.5 - 4 - 0 - yes - yes - - - - - 0 - no - no - - - - - - yes - yes - - 0 - yes - yes - - - 0 - yes - yes - - - - - 0 - no - yes - - - - - + + + window1 + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + False + + + + 4 + True + False + 6 + + + + True + 2 + 2 + False + 4 + 4 + + + + True + Su_mmary: + True + False + GTK_JUSTIFY_CENTER + False + False + 7.45058e-09 + 0.5 + 0 + 0 + general-summary + + + 0 + 1 + 0 + 1 + fill + + + + + + + True + True + True + True + 0 + + True + * + False + + + 1 + 2 + 0 + 1 + + + + + + + True + L_ocation: + True + False + GTK_JUSTIFY_CENTER + False + False + 7.45058e-09 + 0.5 + 0 + 0 + location + + + 0 + 1 + 1 + 2 + fill + + + + + + + True + True + True + True + 0 + + True + * + False + + + 1 + 2 + 1 + 2 + + + + + + 0 + False + True + + + + + + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + 4 + True + 2 + 4 + False + 4 + 4 + + + + True + _Start time: + True + False + GTK_JUSTIFY_CENTER + False + False + 0 + 0.5 + 0 + 0 + start-time + + + 0 + 1 + 0 + 1 + fill + + + + + + + True + _End time: + True + False + GTK_JUSTIFY_CENTER + False + False + 0 + 0.5 + 0 + 0 + end-time + + + 0 + 1 + 1 + 2 + fill + + + + + + + True + True + make_date_edit + + + 0 + 0 + Tue, 16 May 2000 19:11:05 GMT + + + 1 + 2 + 0 + 1 + + + + + + + True + True + make_date_edit + 0 + 0 + Tue, 16 May 2000 19:11:10 GMT + + + 1 + 2 + 1 + 2 + + + + + + + True + make_timezone_entry + 0 + 0 + Mon, 18 Jun 2001 23:51:40 GMT + + + 2 + 3 + 1 + 2 + + fill + + + + + + True + make_timezone_entry + 0 + 0 + Mon, 18 Jun 2001 23:51:34 GMT + + + 2 + 3 + 0 + 1 + fill + fill + + + + + + True + 1 + 7.45058e-09 + 0 + 0 + + + + True + True + A_ll day event + True + GTK_RELIEF_NORMAL + False + False + True + + + + + 3 + 4 + 0 + 2 + fill + + + + + + + + True + Date & Time + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + + + label_item + + + + + 0 + False + False + + + + + + True + GTK_POLICY_NEVER + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + GTK_CORNER_TOP_LEFT + + + + True + True + True + GTK_JUSTIFY_LEFT + GTK_WRAP_WORD + True + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + 0 + True + True + + + + + + True + False + 4 + + + + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + 2 + True + False + 4 + + + + True + True + Pu_blic + True + GTK_RELIEF_NORMAL + True + False + True + + + 0 + True + True + + + + + + True + True + Pri_vate + True + GTK_RELIEF_NORMAL + False + False + True + classification-public + + + 0 + True + True + + + + + + True + True + Con_fidential + True + GTK_RELIEF_NORMAL + False + False + True + classification-public + + + 0 + True + True + + + + + + + + True + Classification + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + + + label_item + + + + + 0 + False + True + + + + + + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + True + False + 4 + + + + True + True + F_ree + True + GTK_RELIEF_NORMAL + False + False + True + + + 0 + True + True + + + + + + True + True + B_usy + True + GTK_RELIEF_NORMAL + False + False + True + show-time-as-free + + + 0 + True + True + + + + + + + + True + Show Time As + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + + + label_item + + + + + 0 + False + True + + + + + 0 + False + False + + + + + + True + False + 2 + + + + True + True + _Contacts... + True + GTK_RELIEF_NORMAL + + + + True + _Contacts... + True + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 4 + 0 + + + + + 0 + False + False + + + + + + True + + + + + + + 0 + True + True + + + + + + True + True + Ca_tegories... + True + GTK_RELIEF_NORMAL + + + + True + Ca_tegories... + True + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 4 + 0 + + + + + 0 + False + False + + + + + + True + True + True + True + 0 + + True + * + False + + + 0 + True + True + + + + + 0 + False + True + + + + + + diff --git a/calendar/gui/dialogs/meeting-page.c b/calendar/gui/dialogs/meeting-page.c index 7203792224..1e5abe9a10 100644 --- a/calendar/gui/dialogs/meeting-page.c +++ b/calendar/gui/dialogs/meeting-page.c @@ -333,8 +333,10 @@ meeting_page_fill_widgets (CompEditorPage *page, CalComponent *comp) gtk_widget_hide (priv->organizer_table); gtk_widget_show (priv->existing_organizer_table); - if (itip_organizer_is_user (comp)) { + if (itip_organizer_is_user (comp, page->client)) { gtk_widget_show (priv->invite); + if (cal_client_get_static_capability (page->client, "organizer-not-email-address")) + gtk_widget_hide (priv->existing_organizer_btn); e_meeting_model_etable_click_to_add (priv->model, TRUE); } else { gtk_widget_hide (priv->invite); @@ -661,20 +663,25 @@ right_click_cb (ETable *etable, gint row, gint col, GdkEvent *event, gpointer da MeetingPage *mpage = MEETING_PAGE (data); MeetingPagePrivate *priv; GtkMenu *menu; - int enable_mask = 0, hide_mask = 0, view_row; + EMeetingAttendee *ia; + int disable_mask = 0, hide_mask = 0, view_row; priv = mpage->priv; view_row = e_table_model_to_view_row (etable, row); priv->row = e_meeting_model_etable_view_to_model_row (etable, priv->model, view_row); - + + ia = e_meeting_model_find_attendee_at_row (priv->model, priv->row); + if (e_meeting_attendee_get_edit_level (ia) != E_MEETING_ATTENDEE_EDIT_FULL) + disable_mask = CAN_DELETE; + /* FIXME: if you enable Delegate, then change index to '1'. * (This has now been enabled). */ /* context_menu[1].pixmap_widget = gnome_stock_new_with_icon (GNOME_STOCK_MENU_TRASH); */ context_menu[1].pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_DELETE, GTK_ICON_SIZE_MENU); - menu = e_popup_menu_create (context_menu, enable_mask, hide_mask, data); + menu = e_popup_menu_create (context_menu, disable_mask, hide_mask, data); e_auto_kill_popup_menu_on_selection_done (menu); gtk_menu_popup (menu, NULL, NULL, NULL, NULL, diff --git a/calendar/gui/dialogs/meeting-page.h b/calendar/gui/dialogs/meeting-page.h index 80abae58da..2a209b586b 100644 --- a/calendar/gui/dialogs/meeting-page.h +++ b/calendar/gui/dialogs/meeting-page.h @@ -25,6 +25,7 @@ #define MEETING_PAGE_H #include "../e-meeting-model.h" +#include "../itip-utils.h" #include "comp-editor-page.h" G_BEGIN_DECLS diff --git a/calendar/gui/dialogs/recurrence-page.c b/calendar/gui/dialogs/recurrence-page.c index 6370326af9..1a7c5533fd 100644 --- a/calendar/gui/dialogs/recurrence-page.c +++ b/calendar/gui/dialogs/recurrence-page.c @@ -410,30 +410,6 @@ clear_widgets (RecurrencePage *rpage) e_date_time_list_clear (priv->exception_list_store); } -/* Builds a static string out of an exception date */ -static char * -get_exception_string (CalComponentDateTime *dt) -{ - static char buf[256]; - struct tm tmp_tm; - - tmp_tm.tm_year = dt->value->year - 1900; - tmp_tm.tm_mon = dt->value->month - 1; - tmp_tm.tm_mday = dt->value->day; - tmp_tm.tm_hour = dt->value->hour; - tmp_tm.tm_min = dt->value->minute; - tmp_tm.tm_sec = dt->value->second; - tmp_tm.tm_isdst = -1; - - tmp_tm.tm_wday = time_day_of_week (dt->value->day, - dt->value->month - 1, - dt->value->year); - - e_time_format_date_and_time (&tmp_tm, calendar_config_get_24_hour_format(), FALSE, FALSE, buf, sizeof (buf)); - - return buf; -} - /* Appends an exception date to the list */ static void append_exception (RecurrencePage *rpage, CalComponentDateTime *datetime) @@ -527,6 +503,12 @@ sensitize_recur_widgets (RecurrencePage *rpage) type = e_dialog_radio_get (priv->none, type_map); + /* We can't preview that well for instances right now */ + if (cal_component_is_instance (priv->comp)) + gtk_widget_set_sensitive (priv->preview_calendar, FALSE); + else + gtk_widget_set_sensitive (priv->preview_calendar, TRUE); + if (GTK_BIN (priv->custom_warning_bin)->child) gtk_widget_destroy (GTK_BIN (priv->custom_warning_bin)->child); @@ -821,7 +803,7 @@ fill_component (RecurrencePage *rpage, CalComponent *comp) if (!icaltime_is_valid_time (*dt->value)) { comp_editor_page_display_validation_error (COMP_EDITOR_PAGE (rpage), - _("Recurrent date is wrong"), + _("Recurrence date is invalid"), priv->exception_list); return FALSE; } @@ -848,13 +830,14 @@ preview_recur (RecurrencePage *rpage) CalComponent *comp; CalComponentDateTime cdt; GSList *l; - + icaltimezone *zone = NULL; + priv = rpage->priv; /* If our component has not been set yet through ::fill_widgets(), we * cannot preview the recurrence. */ - if (!priv->comp) + if (!priv->comp || cal_component_is_instance (priv->comp)) return; /* Create a scratch component with the start/end and @@ -865,6 +848,10 @@ preview_recur (RecurrencePage *rpage) cal_component_set_new_vtype (comp, CAL_COMPONENT_EVENT); cal_component_get_dtstart (priv->comp, &cdt); + if (cdt.tzid != NULL) { + if (cal_client_get_timezone (COMP_EDITOR_PAGE (rpage)->client, cdt.tzid, &zone) != CAL_CLIENT_GET_SUCCESS) + zone = icaltimezone_get_builtin_timezone_from_tzid (cdt.tzid); + } cal_component_set_dtstart (comp, &cdt); cal_component_free_datetime (&cdt); @@ -891,8 +878,8 @@ preview_recur (RecurrencePage *rpage) fill_component (rpage, comp); tag_calendar_by_comp (E_CALENDAR (priv->preview_calendar), comp, - COMP_EDITOR_PAGE (rpage)->client, TRUE, FALSE); - g_object_unref((comp)); + COMP_EDITOR_PAGE (rpage)->client, zone, TRUE, FALSE); + g_object_unref(comp); } /* Callback used when the recurrence weekday picker changes */ @@ -1924,19 +1911,18 @@ recurrence_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates) /* Update the weekday picker if necessary */ mask = get_start_weekday_mask (priv->comp); - if (mask == priv->weekday_blocked_day_mask) - return; - - priv->weekday_day_mask = priv->weekday_day_mask | mask; - priv->weekday_blocked_day_mask = mask; - - if (priv->weekday_picker != NULL) { - weekday_picker_set_days (WEEKDAY_PICKER (priv->weekday_picker), - priv->weekday_day_mask); - weekday_picker_set_blocked_days (WEEKDAY_PICKER (priv->weekday_picker), - priv->weekday_blocked_day_mask); + if (mask != priv->weekday_blocked_day_mask) { + priv->weekday_day_mask = priv->weekday_day_mask | mask; + priv->weekday_blocked_day_mask = mask; + + if (priv->weekday_picker != NULL) { + weekday_picker_set_days (WEEKDAY_PICKER (priv->weekday_picker), + priv->weekday_day_mask); + weekday_picker_set_blocked_days (WEEKDAY_PICKER (priv->weekday_picker), + priv->weekday_blocked_day_mask); + } } - + /* Make sure the preview gets updated. */ preview_recur (rpage); } diff --git a/calendar/gui/dialogs/send-comp.c b/calendar/gui/dialogs/send-comp.c index 01aeef99fd..65fc6bab96 100644 --- a/calendar/gui/dialogs/send-comp.c +++ b/calendar/gui/dialogs/send-comp.c @@ -41,12 +41,15 @@ * Return value: TRUE if the user clicked Yes, FALSE otherwise. **/ gboolean -send_component_dialog (CalComponent *comp, gboolean new) +send_component_dialog (CalClient *client, CalComponent *comp, gboolean new) { GtkWidget *dialog; CalComponentVType vtype; char *str; + if (cal_client_get_save_schedules (client)) + return FALSE; + vtype = cal_component_get_vtype (comp); switch (vtype) { diff --git a/calendar/gui/dialogs/send-comp.h b/calendar/gui/dialogs/send-comp.h index 9a77d8bd4e..d7e990e5b1 100644 --- a/calendar/gui/dialogs/send-comp.h +++ b/calendar/gui/dialogs/send-comp.h @@ -22,8 +22,9 @@ #define SEND_COMP_H #include +#include #include -gboolean send_component_dialog (CalComponent *comp, gboolean new); +gboolean send_component_dialog (CalClient *client, CalComponent *comp, gboolean new); #endif diff --git a/calendar/gui/dialogs/task-details-page.c b/calendar/gui/dialogs/task-details-page.c index 9dfea0dd05..629443dba2 100644 --- a/calendar/gui/dialogs/task-details-page.c +++ b/calendar/gui/dialogs/task-details-page.c @@ -64,7 +64,6 @@ struct _TaskDetailsPagePrivate { static const int status_map[] = { ICAL_STATUS_NONE, ICAL_STATUS_INPROCESS, - ICAL_STATUS_NEEDSACTION, ICAL_STATUS_COMPLETED, ICAL_STATUS_CANCELLED, -1 @@ -301,7 +300,7 @@ task_details_page_fill_widgets (CompEditorPage *page, CalComponent *comp) /* Status. */ cal_component_get_status (comp, &status); - if (status == ICAL_STATUS_NONE) { + if (status == ICAL_STATUS_NONE || status == ICAL_STATUS_NEEDSACTION) { /* Try to use the percent value. */ if (percent) { if (*percent == 100) @@ -541,7 +540,7 @@ date_changed_cb (EDateEdit *dedit, gpointer data) completed_tt = icaltime_null_time (); if (status == ICAL_STATUS_COMPLETED) { e_dialog_option_menu_set (priv->status, - ICAL_STATUS_NEEDSACTION, + ICAL_STATUS_NONE, status_map); e_dialog_spin_set (priv->percent_complete, 0); } @@ -580,9 +579,6 @@ status_changed (GtkMenu *menu, TaskDetailsPage *tdpage) e_dialog_spin_set (priv->percent_complete, 0); e_date_edit_set_time (E_DATE_EDIT (priv->completed_date), ctime); complete_date_changed (tdpage, 0, FALSE); - } else if (status == ICAL_STATUS_NEEDSACTION) { - e_date_edit_set_time (E_DATE_EDIT (priv->completed_date), ctime); - complete_date_changed (tdpage, 0, FALSE); } else if (status == ICAL_STATUS_INPROCESS) { e_dialog_spin_set (priv->percent_complete, 50); e_date_edit_set_time (E_DATE_EDIT (priv->completed_date), ctime); diff --git a/calendar/gui/dialogs/task-details-page.glade b/calendar/gui/dialogs/task-details-page.glade index 78352a8449..fba510499d 100644 --- a/calendar/gui/dialogs/task-details-page.glade +++ b/calendar/gui/dialogs/task-details-page.glade @@ -1,357 +1,382 @@ - + - - no - window1 - GTK_WINDOW_TOPLEVEL - no - no - yes - GTK_WIN_POS_NONE - - - 4 - no - 4 - yes + + window1 + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + False - - - Progress - 0 - GTK_SHADOW_ETCHED_IN - yes + + + 4 + True + False + 4 - - - no - 0 - yes + + + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN - - - 4 - no - 4 - yes + + + True + False + 0 - - - _Status: - GTK_JUSTIFY_CENTER - no - 0.5 - 0.5 - 0 - 0 - status - yes - yes - - - 0 - no - no - - + + + 4 + True + False + 4 - - - yes - 0 - yes + + + True + _Status: + True + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + status + + + 0 + False + False + + - - - yes + + + True + True + 0 - - - Not Started - yes - - + + + True - - - In Progress - yes - - + + + True + Not Started + True + + - - - Needs Action - yes - - + + + True + In Progress + True + + - - - Completed - yes - - + + + True + Completed + True + + - - - Cancelled - yes - - - - - - - 0 - no - no - - + + + True + Cancelled + True + + + + + + + 0 + False + False + + - - - _Priority: - GTK_JUSTIFY_CENTER - no - 0.5 - 0.5 - 0 - 0 - priority - yes - yes - - - 0 - no - no - - + + + True + _Priority: + True + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + priority + + + 0 + False + False + + - - - yes - 0 - yes + + + True + True + 0 - - - yes + + + True - - - High - yes - - + + + True + High + True + + - - - Normal - yes - - + + + True + Normal + True + + - - - Low - yes - - + + + True + Low + True + + - - - Undefined - yes - - - - - - - 0 - no - no - - + + + True + Undefined + True + + + + + + + 0 + False + False + + - - - % Complete - GTK_JUSTIFY_CENTER - no - 0.5 - 0.5 - 0 - 0 - yes - - - 0 - no - no - - + + + True + % Complete + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + - - - yes - 1 - 0 - no - GTK_UPDATE_ALWAYS - no - no - yes - 1 0 100 1 10 10 - - - 0 - yes - yes - - - - - 0 - yes - yes - - + + + True + True + 1 + 0 + False + GTK_UPDATE_ALWAYS + False + False + 1 0 100 1 10 10 + + + 0 + True + True + + + + + 0 + True + True + + - - - 4 - no - 2 - 4 - 1 - 2 - yes + + + 4 + True + 1 + 2 + False + 2 + 4 - - - Date Completed: - GTK_JUSTIFY_CENTER - no - 0 - 0.5 - 0 - 0 - yes - - - 0 - 1 - 0 - 1 - 0 - 0 - fill - - - + + + True + Date Completed: + False + False + GTK_JUSTIFY_CENTER + False + False + 0 + 0.5 + 0 + 0 + + + 0 + 1 + 0 + 1 + fill + + + - - - task_details_page_create_date_edit - 0 - 0 - Fri, 01 Jun 2001 18:58:51 GMT - yes - - - 1 - 2 - 0 - 1 - 0 - 0 - fill - fill - - - - - 0 - yes - yes - - - - - - - 0 - no - no - - + + + True + task_details_page_create_date_edit + 0 + 0 + Fri, 01 Jun 2001 18:58:51 GMT + + + 1 + 2 + 0 + 1 + fill + fill + + + + + 0 + True + True + + + + - - - 4 - no - 2 - 4 - 1 - 2 - yes + + + True + Progress + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + + + label_item + + + + + 0 + False + False + + - - - URL: - GTK_JUSTIFY_CENTER - no - 0 - 0.5 - 0 - 0 - yes - - - 0 - 1 - 0 - 1 - 0 - 0 - fill - - - + + + 4 + True + 1 + 2 + False + 2 + 4 + + + + True + URL: + False + False + GTK_JUSTIFY_CENTER + False + False + 0 + 0.5 + 0 + 0 + + + 0 + 1 + 0 + 1 + fill + + + + + + + True + e_url_entry_new + 0 + 0 + Fri, 08 Feb 2002 21:02:37 GMT + + + 1 + 2 + 0 + 1 + fill + + + + + 0 + False + True + + + + + - - - e_url_entry_new - 0 - 0 - Fri, 08 Feb 2002 21:02:37 GMT - yes - - - 1 - 2 - 0 - 1 - 0 - 0 - expand|fill - fill - - - - - 0 - no - yes - - - - - diff --git a/calendar/gui/dialogs/task-editor.c b/calendar/gui/dialogs/task-editor.c index 5b76c68c75..0b2aee9827 100644 --- a/calendar/gui/dialogs/task-editor.c +++ b/calendar/gui/dialogs/task-editor.c @@ -117,7 +117,8 @@ set_menu_sens (TaskEditor *te) user = comp_editor_get_user_org (COMP_EDITOR (te)); read_only = cal_client_is_read_only (comp_editor_get_cal_client (COMP_EDITOR (te))); - sens = priv->assignment_shown || read_only; + sens = cal_client_get_static_capability (comp_editor_get_cal_client (COMP_EDITOR (te)), "no-task-assignment") + || priv->assignment_shown || read_only; comp_editor_set_ui_prop (COMP_EDITOR (te), "/commands/ActionAssignTask", "sensitive", sens ? "0" : "1"); @@ -217,6 +218,7 @@ task_editor_edit_comp (CompEditor *editor, CalComponent *comp) TaskEditor *te; TaskEditorPrivate *priv; CalComponentOrganizer organizer; + CalClient *client; GSList *attendees = NULL; te = TASK_EDITOR (editor); @@ -227,12 +229,13 @@ task_editor_edit_comp (CompEditor *editor, CalComponent *comp) if (parent_class->edit_comp) parent_class->edit_comp (editor, comp); + client = comp_editor_get_cal_client (COMP_EDITOR (editor)); + /* Get meeting related stuff */ cal_component_get_organizer (comp, &organizer); cal_component_get_attendee_list (comp, &attendees); - + /* Clear things up */ - e_meeting_model_restricted_clear (priv->model); e_meeting_model_remove_all_attendees (priv->model); if (attendees == NULL) { @@ -240,7 +243,8 @@ task_editor_edit_comp (CompEditor *editor, CalComponent *comp) priv->assignment_shown = FALSE; } else { GSList *l; - + int row; + if (!priv->assignment_shown) comp_editor_append_page (COMP_EDITOR (te), COMP_EDITOR_PAGE (priv->meet_page), @@ -248,39 +252,47 @@ task_editor_edit_comp (CompEditor *editor, CalComponent *comp) for (l = attendees; l != NULL; l = l->next) { CalComponentAttendee *ca = l->data; - EMeetingAttendee *ia = E_MEETING_ATTENDEE (e_meeting_attendee_new_from_cal_component_attendee (ca)); - - e_meeting_model_add_attendee (priv->model, ia); - g_object_unref((ia)); + EMeetingAttendee *ia; + + ia = E_MEETING_ATTENDEE (e_meeting_attendee_new_from_cal_component_attendee (ca)); + if (!comp_editor_get_user_org (editor)) + e_meeting_attendee_set_edit_level (ia, E_MEETING_ATTENDEE_EDIT_NONE); + e_meeting_model_add_attendee (priv->model, ia); + + g_object_unref(ia); } - if (organizer.value != NULL) { - const char *strip; - int row; + /* If we aren't the organizer we can still change our own status */ + if (!comp_editor_get_user_org (editor)) { + EAccountList *accounts; + EAccount *account; EIterator *it; - - strip = itip_strip_mailto (organizer.value); - - for (it = e_list_get_iterator((EList *)itip_addresses_get ()); - e_iterator_is_valid(it); - e_iterator_next(it)) { - EAccount *a = (EAccount *)e_iterator_get(it); - - if (e_meeting_model_find_attendee (priv->model, a->id->address, &row)) - e_meeting_model_restricted_add (priv->model, row); - } + + accounts = itip_addresses_get (); + for (it = e_list_get_iterator((EList *)accounts);e_iterator_is_valid(it);e_iterator_next(it)) { + EMeetingAttendee *ia; + + account = (EAccount*)e_iterator_get(it); + + ia = e_meeting_model_find_attendee (priv->model, account->id->address, &row); + if (ia != NULL) + e_meeting_attendee_set_edit_level (ia, E_MEETING_ATTENDEE_EDIT_STATUS); + } g_object_unref(it); - } + } else if (cal_client_get_organizer_must_attend (client)) { + EMeetingAttendee *ia; - if (comp_editor_get_user_org (editor)) - e_meeting_model_restricted_clear (priv->model); + ia = e_meeting_model_find_attendee (priv->model, organizer.value, &row); + if (ia != NULL) + e_meeting_attendee_set_edit_level (ia, E_MEETING_ATTENDEE_EDIT_NONE); + } priv->assignment_shown = TRUE; } cal_component_free_attendee_list (attendees); set_menu_sens (te); - comp_editor_set_needs_send (COMP_EDITOR (te), priv->assignment_shown && itip_organizer_is_user (comp)); + comp_editor_set_needs_send (COMP_EDITOR (te), priv->assignment_shown && itip_organizer_is_user (comp, client)); priv->updating = FALSE; } @@ -414,7 +426,7 @@ cancel_task_cmd (GtkWidget *widget, gpointer data) CalComponent *comp; comp = comp_editor_get_current_comp (COMP_EDITOR (te)); - if (cancel_component_dialog (comp, FALSE)) { + if (cancel_component_dialog (comp_editor_get_cal_client (COMP_EDITOR (te)), comp, FALSE)) { comp_editor_send_comp (COMP_EDITOR (te), CAL_COMPONENT_METHOD_CANCEL); comp_editor_delete_comp (COMP_EDITOR (te)); } diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c index 500b6ef262..3ce9cee4bd 100644 --- a/calendar/gui/e-calendar-table.c +++ b/calendar/gui/e-calendar-table.c @@ -941,7 +941,8 @@ delete_cb (GtkWidget *menuitem, gpointer data) enum { MASK_SINGLE = 1 << 0, /* For commands that work on 1 task. */ MASK_MULTIPLE = 1 << 1, /* For commands for multiple tasks. */ - MASK_EDITABLE = 1 << 2 /* For commands disabled in read-only folders */ + MASK_EDITABLE = 1 << 2, /* For commands disabled in read-only folders */ + MASK_ASSIGNABLE = 1 << 3 /* For non-task assignable backends */ }; @@ -958,7 +959,7 @@ static EPopupMenu tasks_popup_menu [] = { E_POPUP_SEPARATOR, - E_POPUP_ITEM (N_("_Assign Task"), GTK_SIGNAL_FUNC (e_calendar_table_on_assign), MASK_SINGLE | MASK_EDITABLE), + E_POPUP_ITEM (N_("_Assign Task"), GTK_SIGNAL_FUNC (e_calendar_table_on_assign), MASK_SINGLE | MASK_EDITABLE | MASK_ASSIGNABLE), E_POPUP_ITEM (N_("_Forward as iCalendar"), GTK_SIGNAL_FUNC (e_calendar_table_on_forward), MASK_SINGLE), E_POPUP_ITEM (N_("_Mark as Complete"), GTK_SIGNAL_FUNC (mark_as_complete_cb), MASK_SINGLE | MASK_EDITABLE), E_POPUP_ITEM (N_("_Mark Selected Tasks as Complete"), GTK_SIGNAL_FUNC (mark_as_complete_cb), MASK_MULTIPLE | MASK_EDITABLE), @@ -994,6 +995,9 @@ e_calendar_table_on_right_click (ETable *table, if (cal_client_is_read_only (calendar_model_get_cal_client (e_calendar_table_get_model (cal_table)))) disable_mask |= MASK_EDITABLE; + if (cal_client_get_static_capability (calendar_model_get_cal_client (e_calendar_table_get_model (cal_table)), "no-task-assignment")) + disable_mask |= MASK_ASSIGNABLE; + e_popup_menu_run (tasks_popup_menu, (GdkEvent *) event, disable_mask, hide_mask, cal_table); diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c index 6aab8df592..9a1d70a14d 100644 --- a/calendar/gui/e-day-view.c +++ b/calendar/gui/e-day-view.c @@ -56,6 +56,7 @@ #include "dialogs/delete-comp.h" #include "dialogs/send-comp.h" #include "dialogs/cancel-comp.h" +#include "dialogs/recur-comp.h" #include "print.h" #include "comp-util.h" #include "itip-utils.h" @@ -3348,7 +3349,7 @@ e_day_view_on_long_event_click (EDayView *day_view, && E_TEXT (event->canvas_item)->editing) return; - if (!(cal_component_has_recurrences (event->comp)) + if ((cal_component_is_instance (event->comp) || !cal_component_has_recurrences (event->comp)) && (pos == E_DAY_VIEW_POS_LEFT_EDGE || pos == E_DAY_VIEW_POS_RIGHT_EDGE)) { gboolean destroyed; @@ -3434,7 +3435,7 @@ e_day_view_on_event_click (EDayView *day_view, && E_TEXT (event->canvas_item)->editing) return; - if (!(cal_component_has_recurrences (event->comp)) + if ((cal_component_is_instance (event->comp) || !cal_component_has_recurrences (event->comp)) && (pos == E_DAY_VIEW_POS_TOP_EDGE || pos == E_DAY_VIEW_POS_BOTTOM_EDGE)) { gboolean destroyed; @@ -3646,7 +3647,12 @@ enum { * To disable cut and copy for meetings the user is not the * organizer of */ - MASK_MEETING_ORGANIZER = 32 + MASK_MEETING_ORGANIZER = 32, + + /* + * To disable things not valid for instances + */ + MASK_INSTANCE = 64 }; static EPopupMenu main_items [] = { @@ -3712,7 +3718,7 @@ static EPopupMenu child_items [] = { E_POPUP_SEPARATOR, E_POPUP_ITEM (N_("_Delete"), GTK_SIGNAL_FUNC (e_day_view_on_delete_appointment), MASK_EDITABLE | MASK_SINGLE | MASK_EDITING), - E_POPUP_ITEM (N_("Make this Occurrence _Movable"), GTK_SIGNAL_FUNC (e_day_view_on_unrecur_appointment), MASK_EDITABLE | MASK_RECURRING | MASK_EDITING), + E_POPUP_ITEM (N_("Make this Occurrence _Movable"), GTK_SIGNAL_FUNC (e_day_view_on_unrecur_appointment), MASK_EDITABLE | MASK_RECURRING | MASK_EDITING | MASK_INSTANCE), E_POPUP_ITEM (N_("Delete this _Occurrence"), GTK_SIGNAL_FUNC (e_day_view_on_delete_occurrence), MASK_EDITABLE | MASK_RECURRING | MASK_EDITING), E_POPUP_ITEM (N_("Delete _All Occurrences"), GTK_SIGNAL_FUNC (e_day_view_on_delete_appointment), MASK_EDITABLE | MASK_RECURRING | MASK_EDITING), @@ -3776,10 +3782,13 @@ e_day_view_on_event_right_click (EDayView *day_view, else hide_mask |= MASK_RECURRING; + if (cal_component_is_instance (event->comp)) + hide_mask |= MASK_INSTANCE; + if (cal_component_has_organizer (event->comp)) { disable_mask |= MASK_MEETING; - if (!itip_organizer_is_user (event->comp)) + if (!itip_organizer_is_user (event->comp, day_view->client)) disable_mask |= MASK_MEETING_ORGANIZER; } } @@ -4079,6 +4088,16 @@ e_day_view_on_delete_occurrence (GtkWidget *widget, gpointer data) if (event == NULL) return; + if (cal_component_is_instance (event->comp)) { + const char *uid; + + cal_component_get_uid (event->comp, &uid); + if (cal_client_remove_object_with_mod (day_view->client, uid, CALOBJ_MOD_THIS) != CAL_CLIENT_RESULT_SUCCESS) + g_message ("e_day_view_on_delete_occurrence(): Could not update the object!"); + + return; + } + /* We must duplicate the CalComponent, or we won't know it has changed when we get the "update_event" callback. */ comp = cal_component_clone (event->comp); @@ -4101,8 +4120,8 @@ e_day_view_delete_event_internal (EDayView *day_view, EDayViewEvent *event) GTK_WIDGET (day_view))) { const char *uid; - if (itip_organizer_is_user (event->comp) - && cancel_component_dialog (event->comp, TRUE)) + if (itip_organizer_is_user (event->comp, day_view->client) + && cancel_component_dialog (day_view->client, event->comp, TRUE)) itip_send_comp (CAL_COMPONENT_METHOD_CANCEL, event->comp, day_view->client, NULL); cal_component_get_uid (event->comp, &uid); @@ -4179,8 +4198,8 @@ e_day_view_on_cut (GtkWidget *widget, gpointer data) e_day_view_on_copy (widget, data); - if (itip_organizer_is_user (event->comp) - && cancel_component_dialog (event->comp, TRUE)) + if (itip_organizer_is_user (event->comp, day_view->client) + && cancel_component_dialog (day_view->client, event->comp, TRUE)) itip_send_comp (CAL_COMPONENT_METHOD_CANCEL, event->comp, day_view->client, NULL); cal_component_get_uid (event->comp, &uid); @@ -4426,7 +4445,7 @@ e_day_view_on_top_canvas_motion (GtkWidget *widget, event = &g_array_index (day_view->long_events, EDayViewEvent, day_view->pressed_event_num); - if (!(cal_component_has_recurrences (event->comp)) + if ((cal_component_is_instance (event->comp) || !cal_component_has_recurrences (event->comp)) && (abs (canvas_x - day_view->drag_event_x) > E_DAY_VIEW_DRAG_START_OFFSET || abs (canvas_y - day_view->drag_event_y) @@ -4454,7 +4473,7 @@ e_day_view_on_top_canvas_motion (GtkWidget *widget, cursor = day_view->normal_cursor; /* Recurring events can't be resized. */ - if (event && !cal_component_has_recurrences (event->comp)) { + if (event && (cal_component_is_instance (event->comp) || !cal_component_has_recurrences (event->comp))) { switch (pos) { case E_DAY_VIEW_POS_LEFT_EDGE: case E_DAY_VIEW_POS_RIGHT_EDGE: @@ -4530,7 +4549,7 @@ e_day_view_on_main_canvas_motion (GtkWidget *widget, event = &g_array_index (day_view->events[day_view->pressed_event_day], EDayViewEvent, day_view->pressed_event_num); - if (!cal_component_has_recurrences (event->comp) + if ((cal_component_is_instance (event->comp) || !cal_component_has_recurrences (event->comp)) && (abs (canvas_x - day_view->drag_event_x) > E_DAY_VIEW_DRAG_START_OFFSET || abs (canvas_y - day_view->drag_event_y) @@ -4558,7 +4577,7 @@ e_day_view_on_main_canvas_motion (GtkWidget *widget, cursor = day_view->normal_cursor; /* Recurring events can't be resized. */ - if (event && !cal_component_has_recurrences (event->comp)) { + if (event && (cal_component_is_instance (event->comp) || !cal_component_has_recurrences (event->comp))) { switch (pos) { case E_DAY_VIEW_POS_LEFT_EDGE: cursor = day_view->move_cursor; @@ -4809,16 +4828,29 @@ e_day_view_finish_long_event_resize (EDayView *day_view) cal_component_set_dtend (comp, &date); } - gnome_canvas_item_hide (day_view->resize_long_event_rect_item); - - day_view->resize_drag_pos = E_DAY_VIEW_POS_NONE; - - if (cal_client_update_object (day_view->client, comp) == CAL_CLIENT_RESULT_SUCCESS) { - if (itip_organizer_is_user (comp) && send_component_dialog (comp, TRUE)) - itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, day_view->client, NULL); - } else { - g_message ("e_day_view_finish_long_event_resize(): Could not update the object!"); - } + if (cal_component_is_instance (comp)) { + CalObjModType mod; + + if (recur_component_dialog (comp, &mod, NULL)) { + if (cal_client_update_object_with_mod (day_view->client, comp, mod) == CAL_CLIENT_RESULT_SUCCESS) { + if (itip_organizer_is_user (comp, day_view->client) && send_component_dialog (day_view->client, comp, FALSE)) + itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, day_view->client, NULL); + } else { + g_message ("e_day_view_finish_resize(): Could not update the object!"); + } + } else { + gtk_widget_queue_draw (day_view->top_canvas); + } + } else if (cal_client_update_object (day_view->client, comp) == CAL_CLIENT_RESULT_SUCCESS) { + if (itip_organizer_is_user (comp, day_view->client) && send_component_dialog (day_view->client, comp, TRUE)) + itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, day_view->client, NULL); + } else { + g_message ("e_day_view_finish_long_event_resize(): Could not update the object!"); + } + + gnome_canvas_item_hide (day_view->resize_long_event_rect_item); + + day_view->resize_drag_pos = E_DAY_VIEW_POS_NONE; g_object_unref (comp); } @@ -4863,6 +4895,26 @@ e_day_view_finish_resize (EDayView *day_view) cal_component_set_dtend (comp, &date); } + if (cal_component_is_instance (comp)) { + CalObjModType mod; + + if (recur_component_dialog (comp, &mod, NULL)) { + if (cal_client_update_object_with_mod (day_view->client, comp, mod) == CAL_CLIENT_RESULT_SUCCESS) { + if (itip_organizer_is_user (comp, day_view->client) && send_component_dialog (day_view->client, comp, FALSE)) + itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, day_view->client, NULL); + } else { + g_message ("e_day_view_finish_resize(): Could not update the object!"); + } + } else { + gtk_widget_queue_draw (day_view->main_canvas); + } + } else if (cal_client_update_object (day_view->client, comp) == CAL_CLIENT_RESULT_SUCCESS) { + if (itip_organizer_is_user (comp, day_view->client) && send_component_dialog (day_view->client, comp, FALSE)) + itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, day_view->client, NULL); + } else { + g_message ("e_day_view_finish_resize(): Could not update the object!"); + } + gnome_canvas_item_hide (day_view->resize_rect_item); gnome_canvas_item_hide (day_view->resize_bar_item); @@ -4873,13 +4925,6 @@ e_day_view_finish_resize (EDayView *day_view) gnome_canvas_item_hide (day_view->main_canvas_bottom_resize_bar_item); day_view->resize_drag_pos = E_DAY_VIEW_POS_NONE; - - if (cal_client_update_object (day_view->client, comp) == CAL_CLIENT_RESULT_SUCCESS) { - if (itip_organizer_is_user (comp) && send_component_dialog (comp, FALSE)) - itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, day_view->client, NULL); - } else { - g_message ("e_day_view_finish_resize(): Could not update the object!"); - } g_object_unref (comp); } @@ -5526,6 +5571,9 @@ e_day_view_key_press (GtkWidget *widget, GdkEventKey *event) day_view = E_DAY_VIEW (widget); keyval = event->keyval; + if (!(day_view->client && cal_client_get_load_state (day_view->client) == CAL_CLIENT_LOAD_LOADED)) + return TRUE; + /* The Escape key aborts a resize operation. */ if (day_view->resize_drag_pos != E_DAY_VIEW_POS_NONE) { if (keyval == GDK_Escape) { @@ -5606,7 +5654,7 @@ e_day_view_key_press (GtkWidget *widget, GdkEventKey *event) /* Add a new event covering the selected range */ - comp = cal_comp_event_new_with_defaults (); + comp = cal_comp_event_new_with_defaults (day_view->client); e_day_view_get_selected_time_range (day_view, &dtstart, &dtend); @@ -6209,8 +6257,21 @@ e_day_view_on_editing_stopped (EDayView *day_view, summary.altrep = NULL; cal_component_set_summary (event->comp, &summary); - if (cal_client_update_object (day_view->client, event->comp) == CAL_CLIENT_RESULT_SUCCESS) { - if (itip_organizer_is_user (event->comp) && send_component_dialog (event->comp, FALSE)) + if (cal_component_is_instance (event->comp)) { + CalObjModType mod; + + if (recur_component_dialog (event->comp, &mod, NULL)) { + if (cal_client_update_object_with_mod (day_view->client, event->comp, mod) == CAL_CLIENT_RESULT_SUCCESS) { + if (itip_organizer_is_user (event->comp, day_view->client) + && send_component_dialog (day_view->client, event->comp, FALSE)) + itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, event->comp, + day_view->client, NULL); + } else { + g_message ("e_day_view_on_editing_stopped(): Could not update the object!"); + } + } + } else if (cal_client_update_object (day_view->client, event->comp) == CAL_CLIENT_RESULT_SUCCESS) { + if (itip_organizer_is_user (event->comp, day_view->client) && send_component_dialog (day_view->client, event->comp, FALSE)) itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, event->comp, day_view->client, NULL); } else { @@ -7298,9 +7359,23 @@ e_day_view_on_top_canvas_drag_data_received (GtkWidget *widget, if (event->canvas_item) gnome_canvas_item_show (event->canvas_item); - if (cal_client_update_object (day_view->client, comp) + if (cal_component_is_instance (comp)) { + CalObjModType mod; + + if (recur_component_dialog (comp, &mod, NULL)) { + if (cal_client_update_object_with_mod (day_view->client, comp, mod) == CAL_CLIENT_RESULT_SUCCESS) { + if (itip_organizer_is_user (comp, day_view->client) + && send_component_dialog (day_view->client, comp, FALSE)) + itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, + day_view->client, NULL); + } else { + g_message ("e_day_view_on_top_canvas_drag_data_received(): Could " + "not update the object!"); + } + } + } else if (cal_client_update_object (day_view->client, comp) == CAL_CLIENT_RESULT_SUCCESS) { - if (itip_organizer_is_user (comp) && send_component_dialog (comp, FALSE)) + if (itip_organizer_is_user (comp, day_view->client) && send_component_dialog (day_view->client, comp, FALSE)) itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, day_view->client, NULL); } else { @@ -7412,9 +7487,23 @@ e_day_view_on_main_canvas_drag_data_received (GtkWidget *widget, if (event->canvas_item) gnome_canvas_item_show (event->canvas_item); - if (cal_client_update_object (day_view->client, comp) + if (cal_component_is_instance (comp)) { + CalObjModType mod; + + if (recur_component_dialog (comp, &mod, NULL)) { + if (cal_client_update_object_with_mod (day_view->client, comp, mod) == CAL_CLIENT_RESULT_SUCCESS) { + if (itip_organizer_is_user (comp, day_view->client) + && send_component_dialog (day_view->client, comp, FALSE)) + itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, + day_view->client, NULL); + } else { + g_message ("e_day_view_on_top_canvas_drag_data_received(): Could " + "not update the object!"); + } + } + } else if (cal_client_update_object (day_view->client, comp) == CAL_CLIENT_RESULT_SUCCESS) { - if (itip_organizer_is_user (comp) && send_component_dialog (comp, FALSE)) + if (itip_organizer_is_user (comp, day_view->client) && send_component_dialog (day_view->client, comp, FALSE)) itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, day_view->client, NULL); } else { @@ -7606,7 +7695,7 @@ selection_received (GtkWidget *invisible, cal_client_update_object (day_view->client, comp); - if (itip_organizer_is_user (comp) && send_component_dialog (comp, TRUE)) + if (itip_organizer_is_user (comp, day_view->client) && send_component_dialog (day_view->client, comp, TRUE)) itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, day_view->client, NULL); g_object_unref (comp); diff --git a/calendar/gui/e-itip-control.c b/calendar/gui/e-itip-control.c index 945824797c..e5f3b83c67 100644 --- a/calendar/gui/e-itip-control.c +++ b/calendar/gui/e-itip-control.c @@ -82,6 +82,7 @@ struct _EItipControlPrivate { gchar *delegator_address; gchar *delegator_name; gchar *my_address; + gboolean view_only; }; /* HTML Strings */ @@ -302,6 +303,7 @@ init (EItipControl *itip) priv->delegator_address = NULL; priv->delegator_name = NULL; priv->my_address = NULL; + priv->view_only = FALSE; /* Html Widget */ priv->html = gtk_html_new (); @@ -1040,10 +1042,12 @@ write_html (EItipControl *itip, const gchar *itip_desc, const gchar *itip_title, gtk_html_write (GTK_HTML (priv->html), html_stream, HTML_SEP, strlen (HTML_SEP)); /* Options */ - if (options != NULL) { - const_html = ""; - gtk_html_write (GTK_HTML (priv->html), html_stream, const_html, strlen (const_html)); - gtk_html_write (GTK_HTML (priv->html), html_stream, options, strlen (options)); + if (!e_itip_control_get_view_only (itip)) { + if (options != NULL) { + const_html = ""; + gtk_html_write (GTK_HTML (priv->html), html_stream, const_html, strlen (const_html)); + gtk_html_write (GTK_HTML (priv->html), html_stream, options, strlen (options)); + } } const_html = ""; @@ -1646,6 +1650,27 @@ e_itip_control_get_from_address (EItipControl *itip) return priv->from_address; } +void +e_itip_control_set_view_only (EItipControl *itip, gboolean view_only) +{ + EItipControlPrivate *priv; + + priv = itip->priv; + + priv->view_only = view_only; +} + +gboolean +e_itip_control_get_view_only (EItipControl *itip) +{ + EItipControlPrivate *priv; + + priv = itip->priv; + + return priv->view_only; +} + + void e_itip_control_set_delegator_address (EItipControl *itip, const gchar *address) { diff --git a/calendar/gui/e-itip-control.h b/calendar/gui/e-itip-control.h index 8044e07397..12ddf7354e 100644 --- a/calendar/gui/e-itip-control.h +++ b/calendar/gui/e-itip-control.h @@ -62,6 +62,9 @@ gint e_itip_control_get_data_size (EItipControl *itip); void e_itip_control_set_from_address (EItipControl *itip, const gchar *address); const gchar *e_itip_control_get_from_address (EItipControl *itip); +void e_itip_control_set_view_only (EItipControl *itip, + gboolean view_only); +gboolean e_itip_control_get_view_only (EItipControl *itip); void e_itip_control_set_delegator_address (EItipControl *itip, const gchar *address); const gchar *e_itip_control_get_delegator_address (EItipControl *itip); diff --git a/calendar/gui/e-meeting-attendee.c b/calendar/gui/e-meeting-attendee.c index 5dc49022af..fd34147aef 100644 --- a/calendar/gui/e-meeting-attendee.c +++ b/calendar/gui/e-meeting-attendee.c @@ -47,6 +47,8 @@ struct _EMeetingAttendeePrivate { gchar *cn; gchar *language; + EMeetingAttendeeEditLevel edit_level; + gboolean has_calendar_info; GArray *busy_periods; @@ -143,6 +145,7 @@ init (EMeetingAttendee *ia) priv->cn = string_test (NULL); priv->language = string_test (NULL); + priv->edit_level = E_MEETING_ATTENDEE_EDIT_FULL; priv->has_calendar_info = FALSE; priv->busy_periods = g_array_new (FALSE, FALSE, sizeof (EMeetingFreeBusyPeriod)); @@ -591,6 +594,34 @@ e_meeting_attendee_get_atype (EMeetingAttendee *ia) return E_MEETING_ATTENDEE_OPTIONAL_PERSON; } + +EMeetingAttendeeEditLevel +e_meeting_attendee_get_edit_level (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + g_return_val_if_fail (ia != NULL, E_MEETING_ATTENDEE_EDIT_NONE); + g_return_val_if_fail (E_IS_MEETING_ATTENDEE (ia), E_MEETING_ATTENDEE_EDIT_NONE); + + priv = ia->priv; + + return priv->edit_level; +} + +void +e_meeting_attendee_set_edit_level (EMeetingAttendee *ia, EMeetingAttendeeEditLevel level) +{ + EMeetingAttendeePrivate *priv; + + g_return_if_fail (ia != NULL); + g_return_if_fail (E_IS_MEETING_ATTENDEE (ia)); + + priv = ia->priv; + + priv->edit_level = level; +} + + static gint compare_times (EMeetingTime *time1, EMeetingTime *time2) diff --git a/calendar/gui/e-meeting-attendee.h b/calendar/gui/e-meeting-attendee.h index 69f2ced837..cec3c076b0 100644 --- a/calendar/gui/e-meeting-attendee.h +++ b/calendar/gui/e-meeting-attendee.h @@ -58,6 +58,13 @@ typedef enum E_MEETING_ATTENDEE_RESOURCE } EMeetingAttendeeType; +typedef enum +{ + E_MEETING_ATTENDEE_EDIT_FULL, + E_MEETING_ATTENDEE_EDIT_STATUS, + E_MEETING_ATTENDEE_EDIT_NONE +} EMeetingAttendeeEditLevel; + struct _EMeetingAttendee { GtkObject parent; @@ -119,6 +126,9 @@ gboolean e_meeting_attendee_is_set_language (EMeetingAttendee *ia); EMeetingAttendeeType e_meeting_attendee_get_atype (EMeetingAttendee *ia); +EMeetingAttendeeEditLevel e_meeting_attendee_get_edit_level (EMeetingAttendee *ia); +void e_meeting_attendee_set_edit_level (EMeetingAttendee *ia, EMeetingAttendeeEditLevel level); + gboolean e_meeting_attendee_get_has_calendar_info (EMeetingAttendee *ia); void e_meeting_attendee_set_has_calendar_info (EMeetingAttendee *ia, gboolean has_calendar_info); diff --git a/calendar/gui/e-meeting-model.c b/calendar/gui/e-meeting-model.c index 9e8969ef17..2ab28a1fe4 100644 --- a/calendar/gui/e-meeting-model.c +++ b/calendar/gui/e-meeting-model.c @@ -486,30 +486,29 @@ is_cell_editable (ETableModel *etm, int col, int row) { EMeetingModel *im; EMeetingModelPrivate *priv; - GList *l; + EMeetingAttendee *ia; + EMeetingAttendeeEditLevel level; im = E_MEETING_MODEL (etm); priv = im->priv; - if (priv->edit_rows != NULL) { - if (col != E_MEETING_MODEL_STATUS_COL) - return FALSE; - - for (l = priv->edit_rows; l != NULL; l = l->next) { - if (GPOINTER_TO_INT (l->data) == row) - return TRUE; - } - + if (col == E_MEETING_MODEL_DELTO_COL + || col == E_MEETING_MODEL_DELFROM_COL) return FALSE; - } - switch (col) { - case E_MEETING_MODEL_DELTO_COL: - case E_MEETING_MODEL_DELFROM_COL: - return FALSE; + if (row == -1) + return TRUE; + + ia = g_ptr_array_index (priv->attendees, row); + level = e_meeting_attendee_get_edit_level (ia); - default: - break; + switch (level) { + case E_MEETING_ATTENDEE_EDIT_FULL: + return TRUE; + case E_MEETING_ATTENDEE_EDIT_STATUS: + return col == E_MEETING_MODEL_STATUS_COL; + case E_MEETING_ATTENDEE_EDIT_NONE: + return FALSE; } return TRUE; @@ -655,7 +654,6 @@ init (EMeetingModel *im) im->priv = priv; priv->attendees = g_ptr_array_new (); - priv->edit_rows = NULL; priv->without = E_TABLE_WITHOUT (e_table_without_new (E_TABLE_MODEL (im), g_str_hash, @@ -908,7 +906,7 @@ e_meeting_model_add_attendee_with_defaults (EMeetingModel *im) e_meeting_attendee_set_role (ia, text_to_role (str)); g_free (str); str = init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_RSVP_COL); - e_meeting_attendee_set_role (ia, text_to_boolean (str)); + e_meeting_attendee_set_rsvp (ia, text_to_boolean (str)); g_free (str); e_meeting_attendee_set_delto (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_DELTO_COL)); @@ -1036,47 +1034,6 @@ e_meeting_model_get_attendees (EMeetingModel *im) return priv->attendees; } -void -e_meeting_model_restricted_add (EMeetingModel *im, int row) -{ - EMeetingModelPrivate *priv; - - g_return_if_fail (im != NULL); - g_return_if_fail (E_IS_MEETING_MODEL (im)); - - priv = im->priv; - - priv->edit_rows = g_list_append (priv->edit_rows, GINT_TO_POINTER (row)); -} - -void -e_meeting_model_restricted_remove (EMeetingModel *im, int row) -{ - EMeetingModelPrivate *priv; - - g_return_if_fail (im != NULL); - g_return_if_fail (E_IS_MEETING_MODEL (im)); - - priv = im->priv; - - priv->edit_rows = g_list_remove (priv->edit_rows, GINT_TO_POINTER (row)); -} - -void -e_meeting_model_restricted_clear (EMeetingModel *im) -{ - EMeetingModelPrivate *priv; - - g_return_if_fail (im != NULL); - g_return_if_fail (E_IS_MEETING_MODEL (im)); - - priv = im->priv; - - if (priv->edit_rows) - g_list_free (priv->edit_rows); - priv->edit_rows = NULL; -} - static icaltimezone * find_zone (icalproperty *ip, icalcomponent *tz_top_level) { diff --git a/calendar/gui/e-tasks.c b/calendar/gui/e-tasks.c index 4ce3d32072..cc247c2d85 100644 --- a/calendar/gui/e-tasks.c +++ b/calendar/gui/e-tasks.c @@ -36,6 +36,7 @@ #include "cal-search-bar.h" #include "calendar-config.h" #include "calendar-component.h" +#include "comp-util.h" #include "misc.h" #include "e-tasks.h" @@ -520,8 +521,7 @@ e_tasks_new_task (ETasks *tasks) tedit = task_editor_new (priv->client); - comp = cal_component_new (); - cal_component_set_new_vtype (comp, CAL_COMPONENT_TODO); + comp = cal_comp_task_new_with_defaults (priv->client); category = cal_search_bar_get_category (CAL_SEARCH_BAR (priv->search_bar)); cal_component_set_categories (comp, category); diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c index ce64a2c8c7..4a1c44230c 100644 --- a/calendar/gui/e-week-view.c +++ b/calendar/gui/e-week-view.c @@ -53,6 +53,7 @@ #include "dialogs/delete-comp.h" #include "dialogs/send-comp.h" #include "dialogs/cancel-comp.h" +#include "dialogs/recur-comp.h" #include "comp-util.h" #include "itip-utils.h" #include "cal-util/timeutil.h" @@ -112,8 +113,6 @@ static gint e_week_view_focus_out (GtkWidget *widget, GdkEventFocus *event); static gint e_week_view_expose_event (GtkWidget *widget, GdkEventExpose *event); -static void e_week_view_draw (GtkWidget *widget, - GdkRectangle *area); static void e_week_view_draw_shadow (EWeekView *week_view); static gboolean e_week_view_on_button_press (GtkWidget *widget, @@ -3255,8 +3254,21 @@ e_week_view_on_editing_stopped (EWeekView *week_view, summary.altrep = NULL; cal_component_set_summary (event->comp, &summary); - if (cal_client_update_object (week_view->client, event->comp) == CAL_CLIENT_RESULT_SUCCESS) { - if (itip_organizer_is_user (event->comp) && send_component_dialog (event->comp, FALSE)) + if (cal_component_is_instance (event->comp)) { + CalObjModType mod; + + if (recur_component_dialog (event->comp, &mod, NULL)) { + if (cal_client_update_object_with_mod (week_view->client, event->comp, mod) == CAL_CLIENT_RESULT_SUCCESS) { + if (itip_organizer_is_user (event->comp, week_view->client) + && send_component_dialog (week_view->client, event->comp, FALSE)) + itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, event->comp, + week_view->client, NULL); + } else { + g_message ("e_week_view_on_editing_stopped(): Could not update the object!"); + } + } + } else if (cal_client_update_object (week_view->client, event->comp) == CAL_CLIENT_RESULT_SUCCESS) { + if (itip_organizer_is_user (event->comp, week_view->client) && send_component_dialog (week_view->client, event->comp, FALSE)) itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, event->comp, week_view->client, NULL); } else { @@ -3380,6 +3392,9 @@ e_week_view_key_press (GtkWidget *widget, GdkEventKey *event) week_view = E_WEEK_VIEW (widget); + if (cal_client_get_load_state (week_view->client) != CAL_CLIENT_LOAD_LOADED) + return TRUE; + /* The Escape key aborts a resize operation. */ #if 0 if (week_view->resize_drag_pos != E_WEEK_VIEW_POS_NONE) { @@ -3406,7 +3421,7 @@ e_week_view_key_press (GtkWidget *widget, GdkEventKey *event) initial_text = e_utf8_from_gtk_event_key (widget, event->keyval, event->string); /* Add a new event covering the selected range. */ - comp = cal_comp_event_new_with_defaults (); + comp = cal_comp_event_new_with_defaults (week_view->client); dtstart = week_view->day_starts[week_view->selection_start_day]; dtend = week_view->day_starts[week_view->selection_end_day + 1]; @@ -3482,7 +3497,12 @@ enum { * To disable cut and copy for meetings the user is not the * organizer of */ - MASK_MEETING_ORGANIZER = 32 + MASK_MEETING_ORGANIZER = 32, + + /* + * To disable things not valid for instances + */ + MASK_INSTANCE = 64 }; static EPopupMenu main_items [] = { @@ -3537,7 +3557,7 @@ static EPopupMenu child_items [] = { E_POPUP_SEPARATOR, E_POPUP_ITEM (N_("_Delete"), GTK_SIGNAL_FUNC (e_week_view_on_delete_appointment), MASK_EDITABLE | MASK_SINGLE | MASK_EDITING), - E_POPUP_ITEM (N_("Make this Occurrence _Movable"), GTK_SIGNAL_FUNC (e_week_view_on_unrecur_appointment), MASK_RECURRING | MASK_EDITING | MASK_EDITABLE), + E_POPUP_ITEM (N_("Make this Occurrence _Movable"), GTK_SIGNAL_FUNC (e_week_view_on_unrecur_appointment), MASK_RECURRING | MASK_EDITING | MASK_EDITABLE | MASK_INSTANCE), E_POPUP_ITEM (N_("Delete this _Occurrence"), GTK_SIGNAL_FUNC (e_week_view_on_delete_occurrence), MASK_RECURRING | MASK_EDITING | MASK_EDITABLE), E_POPUP_ITEM (N_("Delete _All Occurrences"), GTK_SIGNAL_FUNC (e_week_view_on_delete_appointment), MASK_RECURRING | MASK_EDITING | MASK_EDITABLE), @@ -3592,10 +3612,13 @@ e_week_view_show_popup_menu (EWeekView *week_view, else hide_mask |= MASK_RECURRING; + if (cal_component_is_instance (event->comp)) + hide_mask |= MASK_INSTANCE; + if (cal_component_has_organizer (event->comp)) { disable_mask |= MASK_MEETING; - if (!itip_organizer_is_user (event->comp)) + if (!itip_organizer_is_user (event->comp, week_view->client)) disable_mask |= MASK_MEETING_ORGANIZER; } } @@ -3865,6 +3888,16 @@ e_week_view_on_delete_occurrence (GtkWidget *widget, gpointer data) event = &g_array_index (week_view->events, EWeekViewEvent, week_view->popup_event_num); + if (cal_component_is_instance (event->comp)) { + const char *uid; + + cal_component_get_uid (event->comp, &uid); + if (cal_client_remove_object_with_mod (week_view->client, uid, CALOBJ_MOD_THIS) != CAL_CLIENT_RESULT_SUCCESS) + g_message ("e_week_view_on_delete_occurrence(): Could not update the object!"); + + return; + } + /* We must duplicate the CalComponent, or we won't know it has changed when we get the "update_event" callback. */ @@ -3893,8 +3926,8 @@ e_week_view_delete_event_internal (EWeekView *week_view, gint event_num) GTK_WIDGET (week_view))) { const char *uid; - if (itip_organizer_is_user (event->comp) - && cancel_component_dialog (event->comp, TRUE)) + if (itip_organizer_is_user (event->comp, week_view->client) + && cancel_component_dialog (week_view->client, event->comp, TRUE)) itip_send_comp (CAL_COMPONENT_METHOD_CANCEL, event->comp, week_view->client, NULL); cal_component_get_uid (event->comp, &uid); @@ -3952,8 +3985,8 @@ e_week_view_on_cut (GtkWidget *widget, gpointer data) event = &g_array_index (week_view->events, EWeekViewEvent, week_view->popup_event_num); - if (itip_organizer_is_user (event->comp) - && cancel_component_dialog (event->comp, TRUE)) + if (itip_organizer_is_user (event->comp, week_view->client) + && cancel_component_dialog (week_view->client, event->comp, TRUE)) itip_send_comp (CAL_COMPONENT_METHOD_CANCEL, event->comp, week_view->client, NULL); cal_component_get_uid (event->comp, &uid); @@ -4298,7 +4331,7 @@ selection_received (GtkWidget *invisible, cal_client_update_object (week_view->client, comp); - if (itip_organizer_is_user (comp) && send_component_dialog (comp, TRUE)) + if (itip_organizer_is_user (comp, week_view->client) && send_component_dialog (week_view->client, comp, TRUE)) itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, week_view->client, NULL); g_free (uid); diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c index e805d1323f..b892c0e6ef 100644 --- a/calendar/gui/gnome-cal.c +++ b/calendar/gui/gnome-cal.c @@ -303,8 +303,8 @@ dn_query_obj_updated_cb (CalQuery *query, const char *uid, return; } - tag_calendar_by_comp (priv->date_navigator, comp, priv->client, FALSE, - TRUE); + tag_calendar_by_comp (priv->date_navigator, comp, priv->client, NULL, + FALSE, TRUE); g_object_unref (comp); } @@ -2286,7 +2286,7 @@ gnome_calendar_new_appointment_for (GnomeCalendar *cal, else dt.tzid = icaltimezone_get_tzid (priv->zone); - comp = cal_comp_event_new_with_defaults (); + comp = cal_comp_event_new_with_defaults (priv->client); /* DTSTART, DTEND */ @@ -2368,8 +2368,7 @@ gnome_calendar_new_task (GnomeCalendar *gcal) tedit = task_editor_new (priv->task_pad_client); - comp = cal_component_new (); - cal_component_set_new_vtype (comp, CAL_COMPONENT_TODO); + comp = cal_comp_task_new_with_defaults (priv->client); category = cal_search_bar_get_category (CAL_SEARCH_BAR (priv->search_bar)); cal_component_set_categories (comp, category); diff --git a/calendar/gui/itip-bonobo-control.c b/calendar/gui/itip-bonobo-control.c index 910b84b57b..a1c88caf32 100644 --- a/calendar/gui/itip-bonobo-control.c +++ b/calendar/gui/itip-bonobo-control.c @@ -41,6 +41,7 @@ extern gchar *evolution_dir; enum E_ITIP_BONOBO_ARGS { FROM_ADDRESS_ARG_ID, + VIEW_ONLY_ARG_ID }; /* @@ -94,13 +95,31 @@ stream_read (Bonobo_Stream stream) /* * This function implements the Bonobo::PersistStream:load method. */ +typedef struct { + EItipControl *itip; + char *text; +} idle_data; + +static gboolean +set_data_idle_cb (gpointer data) +{ + idle_data *id = data; + + e_itip_control_set_data (id->itip, id->text); + gtk_object_unref (GTK_OBJECT (id->itip)); + g_free (id->text); + g_free (id); + + return FALSE; +} + static void pstream_load (BonoboPersistStream *ps, const Bonobo_Stream stream, Bonobo_Persist_ContentType type, void *data, CORBA_Environment *ev) { EItipControl *itip = data; - gchar *text; + idle_data *id; if (type && g_strcasecmp (type, "text/calendar") != 0 && g_strcasecmp (type, "text/x-calendar") != 0) { @@ -108,13 +127,16 @@ pstream_load (BonoboPersistStream *ps, const Bonobo_Stream stream, return; } - if ((text = stream_read (stream)) == NULL) { + id = g_new0 (idle_data, 1); + if ((id->text = stream_read (stream)) == NULL) { bonobo_exception_set (ev, ex_Bonobo_Persist_FileNotFound); + g_free (id); return; } - - e_itip_control_set_data (itip, text); - g_free (text); + gtk_object_ref (GTK_OBJECT (itip)); + id->itip = itip; + + g_idle_add (set_data_idle_cb, id); } /* * This function implements the Bonobo::PersistStream:save method. @@ -176,6 +198,9 @@ get_prop (BonoboPropertyBag *bag, case FROM_ADDRESS_ARG_ID: BONOBO_ARG_SET_STRING (arg, e_itip_control_get_from_address (itip)); break; + case VIEW_ONLY_ARG_ID: + BONOBO_ARG_SET_BOOLEAN (arg, e_itip_control_get_view_only (itip)); + break; } } @@ -192,6 +217,9 @@ set_prop ( BonoboPropertyBag *bag, case FROM_ADDRESS_ARG_ID: e_itip_control_set_from_address (itip, BONOBO_ARG_GET_STRING (arg)); break; + case VIEW_ONLY_ARG_ID: + e_itip_control_set_view_only (itip, BONOBO_ARG_GET_BOOLEAN (arg)); + break; } } @@ -212,6 +240,8 @@ itip_bonobo_control_new (void) prop_bag = bonobo_property_bag_new (get_prop, set_prop, itip); bonobo_property_bag_add (prop_bag, "from_address", FROM_ADDRESS_ARG_ID, BONOBO_ARG_STRING, NULL, "from_address", 0 ); + bonobo_property_bag_add (prop_bag, "view_only", VIEW_ONLY_ARG_ID, BONOBO_ARG_BOOLEAN, NULL, + "view_only", 0 ); bonobo_control_set_properties (control, bonobo_object_corba_objref (BONOBO_OBJECT (prop_bag)), NULL); bonobo_object_unref (BONOBO_OBJECT (prop_bag)); diff --git a/calendar/gui/itip-utils.c b/calendar/gui/itip-utils.c index d64b86ca9c..61298fd4ed 100644 --- a/calendar/gui/itip-utils.c +++ b/calendar/gui/itip-utils.c @@ -82,7 +82,7 @@ itip_addresses_get_default (void) } gboolean -itip_organizer_is_user (CalComponent *comp) +itip_organizer_is_user (CalComponent *comp, CalClient *client) { CalComponentOrganizer organizer; const char *strip; @@ -93,7 +93,19 @@ itip_organizer_is_user (CalComponent *comp) cal_component_get_organizer (comp, &organizer); if (organizer.value != NULL) { - strip = itip_strip_mailto (organizer.value); + + strip = itip_strip_mailto (organizer.value); + + if (cal_client_get_static_capability (client, "organizer-not-email-address")) { + const char *email; + + email = cal_client_get_email_address (client); + if (email && !g_strcasecmp (email, strip)) + return TRUE; + + return FALSE; + } + user_org = e_account_list_find(itip_addresses_get(), E_ACCOUNT_FIND_ID_ADDRESS, strip) != NULL; } @@ -585,7 +597,7 @@ comp_limit_attendees (CalComponent *comp) } static void -comp_sentby (CalComponent *comp) +comp_sentby (CalComponent *comp, CalClient *client) { CalComponentOrganizer organizer; @@ -605,7 +617,7 @@ comp_sentby (CalComponent *comp) return; } - if (!itip_organizer_is_user (comp) && !itip_sentby_is_user (comp)) { + if (!itip_organizer_is_user (comp, client) && !itip_sentby_is_user (comp)) { EAccount *a = itip_addresses_get_default (); organizer.value = g_strdup (organizer.value); @@ -764,14 +776,14 @@ comp_compliant (CalComponentItipMethod method, CalComponent *comp, CalClient *cl /* Comply with itip spec */ switch (method) { case CAL_COMPONENT_METHOD_PUBLISH: - comp_sentby (clone); + comp_sentby (clone, client); cal_component_set_attendee_list (clone, NULL); break; case CAL_COMPONENT_METHOD_REQUEST: - comp_sentby (clone); + comp_sentby (clone, client); break; case CAL_COMPONENT_METHOD_CANCEL: - comp_sentby (clone); + comp_sentby (clone, client); break; case CAL_COMPONENT_METHOD_REPLY: break; diff --git a/calendar/gui/itip-utils.h b/calendar/gui/itip-utils.h index 89ad445431..c73f11673c 100644 --- a/calendar/gui/itip-utils.h +++ b/calendar/gui/itip-utils.h @@ -23,7 +23,7 @@ typedef enum { EAccountList *itip_addresses_get (void); EAccount *itip_addresses_get_default (void); -gboolean itip_organizer_is_user (CalComponent *comp); +gboolean itip_organizer_is_user (CalComponent *comp, CalClient *client); gboolean itip_sentby_is_user (CalComponent *comp); const gchar *itip_strip_mailto (const gchar *address); diff --git a/calendar/gui/tag-calendar.c b/calendar/gui/tag-calendar.c index cda93a1d64..03e0b3dee4 100644 --- a/calendar/gui/tag-calendar.c +++ b/calendar/gui/tag-calendar.c @@ -43,7 +43,7 @@ struct calendar_tag_closure { * Returns FALSE if the calendar has no dates shown. */ static gboolean -prepare_tag (ECalendar *ecal, struct calendar_tag_closure *c, gboolean clear_first) +prepare_tag (ECalendar *ecal, struct calendar_tag_closure *c, icaltimezone *zone, gboolean clear_first) { gint start_year, start_month, start_day; gint end_year, end_month, end_day; @@ -72,10 +72,13 @@ prepare_tag (ECalendar *ecal, struct calendar_tag_closure *c, gboolean clear_fir c->calitem = ecal->calitem; - /* FIXME. It may be better if the timezone is passed in. */ - location = calendar_config_get_timezone (); - c->zone = icaltimezone_get_builtin_timezone (location); - + if (zone) { + c->zone = zone; + } else { + location = calendar_config_get_timezone (); + c->zone = icaltimezone_get_builtin_timezone (location); + } + c->start_time = icaltime_as_timet_with_zone (start_tt, c->zone); c->end_time = icaltime_as_timet_with_zone (end_tt, c->zone); @@ -138,7 +141,7 @@ tag_calendar_by_client (ECalendar *ecal, CalClient *client) if (cal_client_get_load_state (client) != CAL_CLIENT_LOAD_LOADED) return; - if (!prepare_tag (ecal, &c, TRUE)) + if (!prepare_tag (ecal, &c, NULL, TRUE)) return; c.skip_transparent_events = TRUE; @@ -192,7 +195,8 @@ resolve_tzid_cb (const char *tzid, gpointer data) * have been added to the calendar on the server yet. **/ void -tag_calendar_by_comp (ECalendar *ecal, CalComponent *comp, CalClient *client, gboolean clear_first, gboolean comp_is_on_server) +tag_calendar_by_comp (ECalendar *ecal, CalComponent *comp, CalClient *client, icaltimezone *display_zone, + gboolean clear_first, gboolean comp_is_on_server) { struct calendar_tag_closure c; @@ -205,7 +209,7 @@ tag_calendar_by_comp (ECalendar *ecal, CalComponent *comp, CalClient *client, gb if (!GTK_WIDGET_VISIBLE (ecal)) return; - if (!prepare_tag (ecal, &c, clear_first)) + if (!prepare_tag (ecal, &c, display_zone, clear_first)) return; c.skip_transparent_events = FALSE; diff --git a/calendar/gui/tag-calendar.h b/calendar/gui/tag-calendar.h index 32c7eb475c..dc146e9c9f 100644 --- a/calendar/gui/tag-calendar.h +++ b/calendar/gui/tag-calendar.h @@ -27,7 +27,7 @@ void tag_calendar_by_client (ECalendar *ecal, CalClient *client); void tag_calendar_by_comp (ECalendar *ecal, CalComponent *comp, - CalClient *client, gboolean clear_first, - gboolean comp_is_on_server); + CalClient *client, icaltimezone *display_zone, + gboolean clear_first, gboolean comp_is_on_server); #endif diff --git a/calendar/idl/evolution-calendar.idl b/calendar/idl/evolution-calendar.idl index c7abc2ca7e..87a8d76e96 100644 --- a/calendar/idl/evolution-calendar.idl +++ b/calendar/idl/evolution-calendar.idl @@ -48,6 +48,13 @@ module Calendar { const CalObjType TYPE_JOURNAL = 1 << 2; const CalObjType TYPE_ANY = 0x07; + /* Flags for getting UID sequences */ + typedef long CalObjModType; + const CalObjModType MOD_THIS = 1 << 0; + const CalObjModType MOD_THISANDPRIOR = 1 << 1; + const CalObjModType MOD_THISANDFUTURE = 1 << 2; + const CalObjModType MOD_ALL = 0x07; + /* Flags for getting URI sequences */ typedef long CalMode; const CalMode MODE_LOCAL = 1 << 0; @@ -70,7 +77,7 @@ module Calendar { /* Used to store a time_t */ typedef unsigned long Time_t; - + /* An instance of a calendar component that actually occurs. These are * "virtual" objects in that they are used to represent instances of * recurring events and alarms. "Real" objects just contain the @@ -139,18 +146,27 @@ module Calendar { /* Check write permissions for calendar */ boolean isReadOnly (); + + /* Information on how to schedule */ + string getStaticCapabilities (); /* Return the email address associated with this calendar, if any. */ string getEmailAddress () raises (NotFound); + string getAlarmEmailAddress () + raises (NotFound); + /* For going online/offline */ void setMode (in CalMode mode); /* Gets the number of components of the specified types */ long countObjects (in CalObjType type); + /* Get a default object of a given type */ + CalObj getDefaultObject (in CalObjType type); + /* Gets a component based on its URI */ CalObj getObject (in CalObjUID uid) raises (NotFound); @@ -208,11 +224,11 @@ module Calendar { * object after this call, and call getObject to get the * updated version. */ - void updateObjects (in CalObj calobj) + void updateObjects (in CalObj calobj, in CalObjModType mod) raises (InvalidObject, PermissionDenied); /* Removes a component */ - void removeObject (in CalObjUID uid) + void removeObject (in CalObjUID uid, in CalObjModType mod) raises (NotFound, PermissionDenied); /* Sends a component */ diff --git a/calendar/pcs/cal-backend-file.c b/calendar/pcs/cal-backend-file.c index a0d9453b3b..7310df2e4f 100644 --- a/calendar/pcs/cal-backend-file.c +++ b/calendar/pcs/cal-backend-file.c @@ -79,6 +79,8 @@ static void cal_backend_file_finalize (GObject *object); static const char *cal_backend_file_get_uri (CalBackend *backend); static gboolean cal_backend_file_is_read_only (CalBackend *backend); static const char *cal_backend_file_get_email_address (CalBackend *backend); +static const char *cal_backend_file_get_alarm_email_address (CalBackend *backend); +static const char *cal_backend_file_get_static_capabilities (CalBackend *backend); static CalBackendOpenStatus cal_backend_file_open (CalBackend *backend, const char *uristr, gboolean only_if_exists); @@ -91,6 +93,7 @@ static CalMode cal_backend_file_get_mode (CalBackend *backend); static void cal_backend_file_set_mode (CalBackend *backend, CalMode mode); static int cal_backend_file_get_n_objects (CalBackend *backend, CalObjType type); +static char *cal_backend_file_get_default_object (CalBackend *backend, CalObjType type); static CalComponent *cal_backend_file_get_object_component (CalBackend *backend, const char *uid); static char *cal_backend_file_get_timezone_object (CalBackend *backend, const char *tzid); static GList *cal_backend_file_get_uids (CalBackend *backend, CalObjType type); @@ -108,8 +111,9 @@ static GNOME_Evolution_Calendar_CalComponentAlarms *cal_backend_file_get_alarms_ time_t start, time_t end, gboolean *object_found); static CalBackendResult cal_backend_file_update_objects (CalBackend *backend, - const char *calobj); -static CalBackendResult cal_backend_file_remove_object (CalBackend *backend, const char *uid); + const char *calobj, + CalObjModType mod); +static CalBackendResult cal_backend_file_remove_object (CalBackend *backend, const char *uid, CalObjModType mod); static CalBackendSendResult cal_backend_file_send_object (CalBackend *backend, const char *calobj, gchar **new_calobj, @@ -175,12 +179,15 @@ cal_backend_file_class_init (CalBackendFileClass *class) backend_class->get_uri = cal_backend_file_get_uri; backend_class->is_read_only = cal_backend_file_is_read_only; backend_class->get_email_address = cal_backend_file_get_email_address; + backend_class->get_alarm_email_address = cal_backend_file_get_alarm_email_address; + backend_class->get_static_capabilities = cal_backend_file_get_static_capabilities; backend_class->open = cal_backend_file_open; backend_class->is_loaded = cal_backend_file_is_loaded; backend_class->get_query = cal_backend_file_get_query; backend_class->get_mode = cal_backend_file_get_mode; backend_class->set_mode = cal_backend_file_set_mode; backend_class->get_n_objects = cal_backend_file_get_n_objects; + backend_class->get_default_object = cal_backend_file_get_default_object; backend_class->get_object_component = cal_backend_file_get_object_component; backend_class->get_timezone_object = cal_backend_file_get_timezone_object; backend_class->get_uids = cal_backend_file_get_uids; @@ -237,7 +244,7 @@ save (CalBackendFile *cbfile) CalBackendFilePrivate *priv; GnomeVFSURI *uri, *backup_uri; GnomeVFSHandle *handle = NULL; - GnomeVFSResult result; + GnomeVFSResult result = GNOME_VFS_ERROR_BAD_FILE; GnomeVFSFileSize out; gchar *tmp, *backup_uristr; char *buf; @@ -433,6 +440,21 @@ cal_backend_file_get_email_address (CalBackend *backend) return NULL; } +static const char * +cal_backend_file_get_alarm_email_address (CalBackend *backend) +{ + /* A file backend has no particular email address associated + * with it (although that would be a useful feature some day). + */ + return NULL; +} + +static const char * +cal_backend_file_get_static_capabilities (CalBackend *backend) +{ + return "no-email-alarms"; +} + /* Idle handler; we save the calendar since it is dirty */ static gboolean save_idle (gpointer data) @@ -870,6 +892,40 @@ cal_backend_file_get_n_objects (CalBackend *backend, CalObjType type) return n; } +static char * +cal_backend_file_get_default_object (CalBackend *backend, CalObjType type) +{ + CalBackendFile *cbfile; + CalBackendFilePrivate *priv; + CalComponent *comp; + char *calobj; + + cbfile = CAL_BACKEND_FILE (backend); + priv = cbfile->priv; + + comp = cal_component_new (); + + switch (type) { + case CALOBJ_TYPE_EVENT: + cal_component_set_new_vtype (comp, CAL_COMPONENT_EVENT); + break; + case CALOBJ_TYPE_TODO: + cal_component_set_new_vtype (comp, CAL_COMPONENT_TODO); + break; + case CALOBJ_TYPE_JOURNAL: + cal_component_set_new_vtype (comp, CAL_COMPONENT_JOURNAL); + break; + default: + g_object_unref (comp); + return NULL; + } + + calobj = cal_component_get_as_string (comp); + g_object_unref (comp); + + return calobj; +} + /* Get_object_component handler for the file backend */ static CalComponent * cal_backend_file_get_object_component (CalBackend *backend, const char *uid) @@ -1393,6 +1449,8 @@ cal_backend_file_get_alarms_in_range (CalBackend *backend, GSList *comp_alarms; GSList *l; int i; + CalAlarmAction omit[] = {-1}; + GNOME_Evolution_Calendar_CalComponentAlarmsSeq *seq; cbfile = CAL_BACKEND_FILE (backend); @@ -1408,11 +1466,11 @@ cal_backend_file_get_alarms_in_range (CalBackend *backend, n_comp_alarms = 0; comp_alarms = NULL; - n_comp_alarms += cal_util_generate_alarms_for_list (priv->events, start, end, + n_comp_alarms += cal_util_generate_alarms_for_list (priv->events, start, end, omit, &comp_alarms, resolve_tzid, priv->icalcomp, priv->default_zone); - n_comp_alarms += cal_util_generate_alarms_for_list (priv->todos, start, end, + n_comp_alarms += cal_util_generate_alarms_for_list (priv->todos, start, end, omit, &comp_alarms, resolve_tzid, priv->icalcomp, priv->default_zone); @@ -1455,6 +1513,7 @@ cal_backend_file_get_alarms_for_object (CalBackend *backend, const char *uid, char *comp_str; GNOME_Evolution_Calendar_CalComponentAlarms *corba_alarms; CalComponentAlarms *alarms; + CalAlarmAction omit[] = {-1}; cbfile = CAL_BACKEND_FILE (backend); priv = cbfile->priv; @@ -1480,7 +1539,7 @@ cal_backend_file_get_alarms_for_object (CalBackend *backend, const char *uid, corba_alarms->calobj = CORBA_string_dup (comp_str); g_free (comp_str); - alarms = cal_util_generate_alarms_for_comp (comp, start, end, resolve_tzid, priv->icalcomp, priv->default_zone); + alarms = cal_util_generate_alarms_for_comp (comp, start, end, omit, resolve_tzid, priv->icalcomp, priv->default_zone); if (alarms) { cal_backend_util_fill_alarm_instances_seq (&corba_alarms->alarms, alarms->alarms); cal_component_alarms_free (alarms); @@ -1562,7 +1621,7 @@ cal_backend_file_cancel_object (CalBackendFile *cbfile, /* Update_objects handler for the file backend. */ static CalBackendResult -cal_backend_file_update_objects (CalBackend *backend, const char *calobj) +cal_backend_file_update_objects (CalBackend *backend, const char *calobj, CalObjModType mod) { CalBackendFile *cbfile; CalBackendFilePrivate *priv; @@ -1667,7 +1726,7 @@ cal_backend_file_update_objects (CalBackend *backend, const char *calobj) /* Remove_object handler for the file backend */ static CalBackendResult -cal_backend_file_remove_object (CalBackend *backend, const char *uid) +cal_backend_file_remove_object (CalBackend *backend, const char *uid, CalObjModType mod) { CalBackendFile *cbfile; CalBackendFilePrivate *priv; diff --git a/calendar/pcs/cal-backend.c b/calendar/pcs/cal-backend.c index f738399380..5e2074bad1 100644 --- a/calendar/pcs/cal-backend.c +++ b/calendar/pcs/cal-backend.c @@ -175,6 +175,8 @@ cal_backend_class_init (CalBackendClass *class) class->get_uri = NULL; class->get_email_address = NULL; + class->get_alarm_email_address = NULL; + class->get_static_capabilities = NULL; class->open = NULL; class->is_loaded = NULL; class->is_read_only = NULL; @@ -281,6 +283,26 @@ cal_backend_get_email_address (CalBackend *backend) return (* CLASS (backend)->get_email_address) (backend); } +const char * +cal_backend_get_alarm_email_address (CalBackend *backend) +{ + g_return_val_if_fail (backend != NULL, NULL); + g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); + + g_assert (CLASS (backend)->get_alarm_email_address != NULL); + return (* CLASS (backend)->get_alarm_email_address) (backend); +} + +const char * +cal_backend_get_static_capabilities (CalBackend *backend) +{ + g_return_val_if_fail (backend != NULL, NULL); + g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); + + g_assert (CLASS (backend)->get_static_capabilities != NULL); + return (* CLASS (backend)->get_static_capabilities) (backend); +} + /* Callback used when a Cal is destroyed */ static void cal_destroy_cb (gpointer data, GObject *where_cal_was) @@ -501,6 +523,16 @@ get_object (CalBackend *backend, const char *uid) return cal_component_get_as_string (comp); } +char * +cal_backend_get_default_object (CalBackend *backend, CalObjType type) +{ + g_return_val_if_fail (backend != NULL, NULL); + g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); + + g_assert (CLASS (backend)->get_default_object != NULL); + return (* CLASS (backend)->get_default_object) (backend, type); +} + /** * cal_backend_get_object: * @backend: A calendar backend. @@ -795,14 +827,14 @@ cal_backend_get_alarms_for_object (CalBackend *backend, const char *uid, * result of the operation. **/ CalBackendResult -cal_backend_update_objects (CalBackend *backend, const char *calobj) +cal_backend_update_objects (CalBackend *backend, const char *calobj, CalObjModType mod) { g_return_val_if_fail (backend != NULL, FALSE); g_return_val_if_fail (IS_CAL_BACKEND (backend), FALSE); g_return_val_if_fail (calobj != NULL, FALSE); g_assert (CLASS (backend)->update_objects != NULL); - return (* CLASS (backend)->update_objects) (backend, calobj); + return (* CLASS (backend)->update_objects) (backend, calobj, mod); } /** @@ -817,14 +849,14 @@ cal_backend_update_objects (CalBackend *backend, const char *calobj) * result of the operation. **/ CalBackendResult -cal_backend_remove_object (CalBackend *backend, const char *uid) +cal_backend_remove_object (CalBackend *backend, const char *uid, CalObjModType mod) { g_return_val_if_fail (backend != NULL, FALSE); g_return_val_if_fail (IS_CAL_BACKEND (backend), FALSE); g_return_val_if_fail (uid != NULL, FALSE); g_assert (CLASS (backend)->remove_object != NULL); - return (* CLASS (backend)->remove_object) (backend, uid); + return (* CLASS (backend)->remove_object) (backend, uid, mod); } CalBackendSendResult diff --git a/calendar/pcs/cal-backend.h b/calendar/pcs/cal-backend.h index b20e04bdb6..ee11354252 100644 --- a/calendar/pcs/cal-backend.h +++ b/calendar/pcs/cal-backend.h @@ -96,7 +96,10 @@ struct _CalBackendClass { const char *(* get_uri) (CalBackend *backend); const char *(* get_email_address) (CalBackend *backend); - + const char *(* get_alarm_email_address) (CalBackend *backend); + + const char *(* get_static_capabilities) (CalBackend *backend); + CalBackendOpenStatus (* open) (CalBackend *backend, const char *uristr, gboolean only_if_exists); @@ -113,6 +116,7 @@ struct _CalBackendClass { /* General object acquirement and information related virtual methods */ int (* get_n_objects) (CalBackend *backend, CalObjType type); + char *(* get_default_object) (CalBackend *backend, CalObjType type); char *(* get_object) (CalBackend *backend, const char *uid); CalComponent *(* get_object_component) (CalBackend *backend, const char *uid); char *(* get_timezone_object) (CalBackend *backend, const char *tzid); @@ -134,8 +138,8 @@ struct _CalBackendClass { time_t start, time_t end, gboolean *object_found); /* Object manipulation virtual methods */ - CalBackendResult (* update_objects) (CalBackend *backend, const char *calobj); - CalBackendResult (* remove_object) (CalBackend *backend, const char *uid); + CalBackendResult (* update_objects) (CalBackend *backend, const char *calobj, CalObjModType mod); + CalBackendResult (* remove_object) (CalBackend *backend, const char *uid, CalObjModType mod); CalBackendSendResult (* send_object) (CalBackend *backend, const char *calobj, char **new_calobj, GNOME_Evolution_Calendar_UserList **user_list, @@ -152,6 +156,9 @@ GType cal_backend_get_type (void); const char *cal_backend_get_uri (CalBackend *backend); const char *cal_backend_get_email_address (CalBackend *backend); +const char *cal_backend_get_alarm_email_address (CalBackend *backend); + +const char *cal_backend_get_static_capabilities (CalBackend *backend); void cal_backend_add_cal (CalBackend *backend, Cal *cal); @@ -171,6 +178,8 @@ void cal_backend_set_mode (CalBackend *backend, CalMode mode); int cal_backend_get_n_objects (CalBackend *backend, CalObjType type); +char *cal_backend_get_default_object (CalBackend *backend, CalObjType type); + char *cal_backend_get_object (CalBackend *backend, const char *uid); CalComponent *cal_backend_get_object_component (CalBackend *backend, const char *uid); @@ -200,9 +209,9 @@ GNOME_Evolution_Calendar_CalComponentAlarms *cal_backend_get_alarms_for_object ( CalBackendGetAlarmsForObjectResult *result); -CalBackendResult cal_backend_update_objects (CalBackend *backend, const char *calobj); +CalBackendResult cal_backend_update_objects (CalBackend *backend, const char *calobj, CalObjModType mod); -CalBackendResult cal_backend_remove_object (CalBackend *backend, const char *uid); +CalBackendResult cal_backend_remove_object (CalBackend *backend, const char *uid, CalObjModType mod); CalBackendSendResult cal_backend_send_object (CalBackend *backend, const char *calobj, char **new_calobj, GNOME_Evolution_Calendar_UserList **user_list, diff --git a/calendar/pcs/cal.c b/calendar/pcs/cal.c index 0d089b5096..8171af4922 100644 --- a/calendar/pcs/cal.c +++ b/calendar/pcs/cal.c @@ -101,6 +101,49 @@ impl_Cal_getEmailAddress (PortableServer_Servant servant, return str_email_address_copy; } + +/* Cal::get_alarm_email_address method */ +static CORBA_char * +impl_Cal_getAlarmEmailAddress (PortableServer_Servant servant, + CORBA_Environment *ev) +{ + Cal *cal; + CalPrivate *priv; + const char *str_email_address; + CORBA_char *str_email_address_copy; + + cal = CAL (bonobo_object_from_servant (servant)); + priv = cal->priv; + + str_email_address = cal_backend_get_alarm_email_address (priv->backend); + if (str_email_address == NULL) { + bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_NotFound); + return CORBA_OBJECT_NIL; + } + + str_email_address_copy = CORBA_string_dup (str_email_address); + + return str_email_address_copy; +} + +/* Cal::getSchedulingInformation method */ +static CORBA_char * +impl_Cal_getStaticCapabilities (PortableServer_Servant servant, + CORBA_Environment *ev) +{ + Cal *cal; + CalPrivate *priv; + const char *cap; + CORBA_char *cap_copy; + + cal = CAL (bonobo_object_from_servant (servant)); + priv = cal->priv; + + cap = cal_backend_get_static_capabilities (priv->backend); + cap_copy = CORBA_string_dup (cap == NULL ? "" : cap); + + return cap_copy; +} /* Converts a calendar object type from its CORBA representation to our own * representation. @@ -147,6 +190,27 @@ impl_Cal_countObjects (PortableServer_Servant servant, return n; } +static GNOME_Evolution_Calendar_CalObj +impl_Cal_getDefaultObject (PortableServer_Servant servant, + GNOME_Evolution_Calendar_CalObjType type, + CORBA_Environment *ev) +{ + Cal *cal; + CalPrivate *priv; + GNOME_Evolution_Calendar_CalObj calobj_copy; + char *calobj; + + + cal = CAL (bonobo_object_from_servant (servant)); + priv = cal->priv; + + calobj = cal_backend_get_default_object (priv->backend, type); + calobj_copy = CORBA_string_dup (calobj); + g_free (calobj); + + return calobj_copy; +} + /* Cal::getObject method */ static GNOME_Evolution_Calendar_CalObj impl_Cal_getObject (PortableServer_Servant servant, @@ -291,6 +355,7 @@ build_fb_seq (GList *obj_list) seq = GNOME_Evolution_Calendar_CalObjSeq__alloc (); CORBA_sequence_set_release (seq, TRUE); + seq->_maximum = n; seq->_length = n; seq->_buffer = CORBA_sequence_GNOME_Evolution_Calendar_CalObj_allocbuf (n); @@ -428,6 +493,7 @@ impl_Cal_getAlarmsForObject (PortableServer_Servant servant, static void impl_Cal_updateObjects (PortableServer_Servant servant, const CORBA_char *calobj, + const GNOME_Evolution_Calendar_CalObjModType mod, CORBA_Environment *ev) { Cal *cal; @@ -437,7 +503,7 @@ impl_Cal_updateObjects (PortableServer_Servant servant, cal = CAL (bonobo_object_from_servant (servant)); priv = cal->priv; - result = cal_backend_update_objects (priv->backend, calobj); + result = cal_backend_update_objects (priv->backend, calobj, mod); switch (result) { case CAL_BACKEND_RESULT_INVALID_OBJECT : bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject); @@ -457,6 +523,7 @@ impl_Cal_updateObjects (PortableServer_Servant servant, static void impl_Cal_removeObject (PortableServer_Servant servant, const CORBA_char *uid, + const GNOME_Evolution_Calendar_CalObjModType mod, CORBA_Environment *ev) { Cal *cal; @@ -466,7 +533,7 @@ impl_Cal_removeObject (PortableServer_Servant servant, cal = CAL (bonobo_object_from_servant (servant)); priv = cal->priv; - result = cal_backend_remove_object (priv->backend, uid); + result = cal_backend_remove_object (priv->backend, uid, mod); switch (result) { case CAL_BACKEND_RESULT_INVALID_OBJECT : bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject); @@ -749,8 +816,11 @@ cal_class_init (CalClass *klass) epv->_get_uri = impl_Cal_get_uri; epv->isReadOnly = impl_Cal_isReadOnly; epv->getEmailAddress = impl_Cal_getEmailAddress; + epv->getAlarmEmailAddress = impl_Cal_getAlarmEmailAddress; + epv->getStaticCapabilities = impl_Cal_getStaticCapabilities; epv->setMode = impl_Cal_setMode; epv->countObjects = impl_Cal_countObjects; + epv->getDefaultObject = impl_Cal_getDefaultObject; epv->getObject = impl_Cal_getObject; epv->setDefaultTimezone = impl_Cal_setDefaultTimezone; epv->getTimezoneObject = impl_Cal_getTimezoneObject; -- cgit v1.2.3