/// <summary> /// Processes RecurrenceId events /// </summary> /// <param name="entry"></param> /// <param name="app"></param> /// <param name="evData"></param> private void ProcessRecurrenceId(CalendarEntry entry, Appointment app, VEventData evData) { if (evData.UidApps != null) { Appointment uidApp = null; foreach (Appointment uApp in evData.UidApps) { if (uApp.Recurrence != null) { if (uidApp == null) uidApp = uApp; uApp.Recurrence.SkippedRecurrences.Add(evData.RecIdDate); } } if (uidApp != null) { if (app.StartTime == DateTime.MinValue) app.StartTime = evData.RecIdDate; if (evData.Duration.TotalSeconds != 0) app.EndTime = app.StartTime.Add(evData.Duration); else if (app.EndTime == DateTime.MinValue) app.EndTime = app.StartTime.Add(uidApp.EndTime - uidApp.StartTime); if (app.StartTime > app.EndTime) { ReportError(entry, "DTSTART is greater than DTEND"); app.EndTime = app.StartTime.Add(uidApp.EndTime - uidApp.StartTime); } if ((evData.AppPropSet & AppProp.Description) == 0) app.Description = uidApp.Description; if ((evData.AppPropSet & AppProp.Summary) == 0) app.Subject = uidApp.Subject; if ((evData.AppPropSet & AppProp.XDnbCategoryColor) == 0) app.CategoryColor = uidApp.CategoryColor; if ((evData.AppPropSet & AppProp.XDnbDisplayTemplate) == 0) app.DisplayTemplate = uidApp.DisplayTemplate; if ((evData.AppPropSet & AppProp.XDnbImageAlign) == 0) app.ImageAlign = uidApp.ImageAlign; if ((evData.AppPropSet & AppProp.XDnbImageKey) == 0) app.ImageKey = uidApp.ImageKey; if ((evData.AppPropSet & AppProp.XDnbLocked) == 0) app.Locked = uidApp.Locked; if ((evData.AppPropSet & AppProp.XDnbStartTimeAction) == 0) app.StartTimeAction = uidApp.StartTimeAction; if ((evData.AppPropSet & AppProp.XDnbTimeMarkedAs) == 0) app.TimeMarkedAs = uidApp.TimeMarkedAs; if ((evData.AppPropSet & AppProp.XDnbTooltip) == 0) app.Tooltip = uidApp.Tooltip; Model.Appointments.Add(app); } } }
/// <summary> /// Processes Daily recurrences /// </summary> /// <param name="model"></param> /// <param name="app"></param> /// <param name="evData"></param> private void ProcessDailyRecurrence(CalendarModel model, Appointment app, VEventData evData) { AppointmentRecurrence recur = new AppointmentRecurrence(); recur.RecurrenceType = eRecurrencePatternType.Daily; recur.Daily.RepeatInterval = evData.RecurRule.Interval; switch (evData.RecurRule.ByDays) { case eDayOfWeekRecurrence.WeekDays: recur.Daily.RepeatOnDaysOfWeek = eDailyRecurrenceRepeat.WeekDays; break; case eDayOfWeekRecurrence.WeekendDays: recur.Daily.RepeatOnDaysOfWeek = eDailyRecurrenceRepeat.WeekendDays; break; } ProcessRecurrenceRange(app, recur, evData); app.Recurrence = recur; model.Appointments.Add(app); }
/// <summary> /// Processes Monthly recurrences /// </summary> /// <param name="model"></param> /// <param name="app"></param> /// <param name="evData"></param> private void ProcessMonthlyRecurrence(CalendarModel model, Appointment app, VEventData evData) { RRule rrule = evData.RecurRule; if (rrule.ByDays == eDayOfWeekRecurrence.None) { if (rrule.ByMonthDay != null) { foreach (int day in rrule.ByMonthDay) AddMonthlyByMonthDay(model, app, day, evData); } else { AddMonthlyByMonthDay(model, app, app.StartTime.Day, evData); } } else { for (int i = 0; i < rrule.ByDay.Length; i++) { eDayOfWeekRecurrence eday = ((eDayOfWeekRecurrence)(1 << i)); DayOfWeek dayOfWeek = GetRelativeDayOfWeek(eday); if ((rrule.ByDays & eday) != 0) { foreach (int byDay in rrule.ByDay[i]) AddMonthlyByDay(model, app, dayOfWeek, byDay, evData); } } } }
/// <summary> /// Processes Event components for the given OwnerKey /// </summary> /// <param name="ownerKey">Associated OwnerKey</param> private void ProcessVEvent(string ownerKey) { Appointment app = new Appointment(); app.OwnerKey = ownerKey; VEventData evData = new VEventData(); CalendarEntry entry = GetNextEntry(); while (entry != null) { PropertyToken tkn = (PropertyToken)GetToken(_properties, entry.Id); switch (tkn) { case PropertyToken.Begin: ComponentToken ctkn = (ComponentToken)GetToken(_components, entry.Value); switch (ctkn) { case ComponentToken.VAlarm: ProcessVAlarm(evData); break; default: ReportError(entry, "Unexpected \"BEGIN:" + entry.Value.ToUpper() + "\""); SkipComponent(ctkn); break; } break; case PropertyToken.Description: app.Description = ProcessDescription(entry, evData); break; case PropertyToken.DtEnd: app.EndTime = ProcessDate(entry, ref evData.IsDtEndValue); break; case PropertyToken.DtStart: app.StartTime = ProcessDate(entry, ref evData.IsDtStartValue); break; case PropertyToken.Duration: evData.Duration = ProcessDuration(entry, entry.Value); break; case PropertyToken.End: if ((ComponentToken)GetToken(_components, entry.Value) != ComponentToken.VEvent) ReportError(entry, "Expected \"END:VEVENT\""); ProcessVEventEnd(entry, app, evData); return; case PropertyToken.ExDate: ProcessExDate(entry, evData); break; case PropertyToken.RDate: evData.RecurDate = ProcessRDate(entry, evData.RecurDate); break; case PropertyToken.RecurrenceId: evData.RecIdDate = ProcessRecurrenceId(entry); break; case PropertyToken.RRule: evData.RecurRule = ProcessRRule(entry); break; case PropertyToken.Summary: app.Subject = ProcessSummary(entry, evData); break; case PropertyToken.Uid: evData.UidApps = ProcessUid(entry, app); break; case PropertyToken.XDnbCategoryColor: app.CategoryColor = ProcessXDnbCategoryColor(entry, evData); break; case PropertyToken.XDnbDisplayTemplate: app.DisplayTemplate = ProcessXDnbDisplayTemplate(entry, evData); break; case PropertyToken.XDnbImageAlign: app.ImageAlign = ProcessXDnbImageAlign(entry, evData); break; case PropertyToken.XDnbImageKey: app.ImageKey = ProcessXDnbImageKey(entry, evData); break; case PropertyToken.XDnbLocked: app.Locked = ProcessXDnbLocked(entry, evData); break; case PropertyToken.XDnbRecStartDate: evData.RecStartDate = ProcessXDnbRecStartDate(entry); break; case PropertyToken.XDnbStartTimeAction: app.StartTimeAction = ProcessXDnbStartTimeAction(entry, evData); break; case PropertyToken.XDnbTimeMarkedAs: app.TimeMarkedAs = ProcessXDnbTimeMarkedAs(entry, evData); break; case PropertyToken.XDnbTooltip: app.Tooltip = ProcessXDnbTooltip(entry, evData); break; } entry = GetNextEntry(); } ReportError(entry, "Expected \"END:VEVENT\""); }
/// <summary> /// ProcessEventEndEx /// </summary> /// <param name="model"></param> /// <param name="entry"></param> /// <param name="app"></param> /// <param name="evData"></param> private void ProcessEventEndEx(CalendarModel model, CalendarEntry entry, Appointment app, VEventData evData) { if (ValidateAppTime(entry, app, evData) == true) { if (evData.UidApps == null) { evData.UidApps = new List<Appointment>(); evData.UidApps.Add(app); } if (evData.RecurRule != null) { switch (evData.RecurRule.Freq) { case Frequency.Daily: ProcessDailyRecurrence(model, app, evData); break; case Frequency.Weekly: ProcessWeeklyRecurrence(model, app, evData); break; case Frequency.Monthly: ProcessMonthlyRecurrence(model, app, evData); break; case Frequency.Yearly: ProcessYearlyRecurrence(model, app, evData); break; } ProcessRDateRange(model, app, evData); } else { model.Appointments.Add(app); } ProcessVEventReminder(evData); } }
/// <summary> /// Processes DNB StartTimeAction entries /// </summary> /// <param name="entry"></param> /// <param name="evData"></param> /// <returns></returns> private eStartTimeAction ProcessXDnbStartTimeAction(CalendarEntry entry, VEventData evData) { evData.AppPropSet |= AppProp.XDnbStartTimeAction; return ((eStartTimeAction) GetEnumValue(typeof(eStartTimeAction), entry.Value)); }
/// <summary> /// Processes DNB ToolTip entries /// </summary> /// <param name="entry"></param> /// <param name="evData"></param> /// <returns></returns> private string ProcessXDnbTooltip(CalendarEntry entry, VEventData evData) { evData.AppPropSet |= AppProp.XDnbTooltip; return (entry.Value); }
/// <summary> /// GetLastPartDate /// </summary> /// <param name="part"></param> /// <param name="date"></param> /// <returns></returns> private DateTime GetLastPartDate(TimeZonePart part, DateTime date) { DateTime pdate = part.StartDate; if (part.Appc == null) { CalendarModel model = new CalendarModel(); Appointment app = new Appointment(); app.StartTime = part.StartDate.Date; app.EndTime = app.StartTime; VEventData evData = new VEventData(); evData.RecurRule = part.RecurRule; ProcessEventEndEx(model, null, app, evData); part.Appc = new AppointmentSubsetCollection(model, part.StartDate, date); } if (part.Appc.Count > 0) { foreach (Appointment app in part.Appc) { if (app.StartTime > pdate && app.StartTime <= date) pdate = app.StartTime; } } return (pdate); }
/// <summary> /// Processes event Description values /// </summary> /// <param name="entry"></param> /// <param name="evData"></param> /// <returns></returns> private string ProcessDescription(CalendarEntry entry, VEventData evData) { evData.AppPropSet |= AppProp.Description; return (entry.Value); }
/// <summary> /// Determines if the given date is a skippable ByDays date /// </summary> /// <param name="app"></param> /// <param name="date"></param> /// <param name="evData"></param> /// <returns></returns> private bool IsSkippableByDay(Appointment app, DateTime date, VEventData evData) { if (evData.RecurRule.ByDays != eDayOfWeekRecurrence.None) return (date.DayOfWeek == app.StartTime.DayOfWeek); return (true); }
/// <summary> /// ProcessRDateRange /// </summary> /// <param name="model"></param> /// <param name="app"></param> /// <param name="evData"></param> private void ProcessRDateRange( CalendarModel model, Appointment app, VEventData evData) { if (evData.RecurDate != null) { if (evData.RecurDate.DtRange != null) { foreach (DateRange range in evData.RecurDate.DtRange) { Appointment appRange = app.Copy(); appRange.StartTime = range.StartTime; appRange.EndTime = range.EndTime; model.Appointments.Add(appRange); } } } }
/// <summary> /// Determines if the given date is a skippable ByMonth date /// </summary> /// <param name="app"></param> /// <param name="date"></param> /// <param name="evData"></param> /// <returns></returns> private bool IsSkippableByMonth(Appointment app, DateTime date, VEventData evData) { if (evData.RecurRule.ByMonth != null) { if (date.Month != app.StartTime.Month) return (false); } return (true); }
/// <summary> /// Determines if the given date is a valid /// SkippedRecurrence date. /// </summary> /// <param name="app"></param> /// <param name="date"></param> /// <param name="evData"></param> /// <returns></returns> private bool IsSkippableDate(Appointment app, DateTime date, VEventData evData) { if (IsSkippableByMonth(app, date, evData) == false) return (false); if (IsSkippableByMonthDay(app, date, evData) == false) return (false); return (IsSkippableByDay(app, date, evData)); }
/// <summary> /// Processes Recurrence range values /// </summary> /// <param name="app"></param> /// <param name="recur"></param> /// <param name="evData"></param> private void ProcessRecurrenceRange( Appointment app, AppointmentRecurrence recur, VEventData evData) { recur.RecurrenceStartDate = (evData.RecStartDate != DateTime.MinValue) ? evData.RecStartDate : app.StartTime; if (evData.RecurRule.Count > 0) { recur.RangeLimitType = eRecurrenceRangeLimitType.RangeNumberOfOccurrences; recur.RangeNumberOfOccurrences = evData.RecurRule.Count - 1; } if (evData.RecurRule.Until != DateTime.MinValue) { recur.RangeLimitType = eRecurrenceRangeLimitType.RangeEndDate; recur.RangeEndDate = evData.RecurRule.Until; } if (evData.ExDates != null) { foreach (DateTime date in evData.ExDates) { if (date >= app.StartTime) { if (IsSkippableDate(app, date, evData) == true) recur.SkippedRecurrences.Add(date); } } } }
/// <summary> /// Processes DNB ImageKey entries /// </summary> /// <param name="entry"></param> /// <param name="evData"></param> /// <returns></returns> private string ProcessXDnbImageKey(CalendarEntry entry, VEventData evData) { evData.AppPropSet |= AppProp.XDnbImageKey; return (entry.Value); }
/// <summary> /// Processes event ExDate values /// </summary> /// <param name="entry"></param> /// <param name="evData"></param> private void ProcessExDate(CalendarEntry entry, VEventData evData) { List<DateTime> exDates = null; if (entry.Attributes.Count > 0) { foreach (AttributeData attr in entry.Attributes) { ParameterToken tkn = (ParameterToken) GetToken(_parameters, attr.Id); switch (tkn) { case ParameterToken.TzId: if (exDates != null) ReportError(entry, "Multiple EXDATE parameter types"); exDates = ProcessTzIdExDateTimeValues(attr.Value, entry, entry.Value); break; case ParameterToken.Value: if (exDates != null) ReportError(entry, "Multiple EXDATE parameter types"); switch ((ValueToken)GetToken(_values, attr.Value)) { case ValueToken.Date: exDates = ProcessExDateValues(entry); break; case ValueToken.DateTime: exDates = ProcessExDateTimeValues(entry, entry.Value); break; default: ReportError(entry, "Unrecognized ExDate attribute Value (" + attr.Id + "=" + attr.Value + ")"); break; } break; } } } if (exDates == null) exDates = ProcessExDateTimeValues(entry, entry.Value); UnionExDates(evData, exDates); }
/// <summary> /// Processes DNB Locked entries /// </summary> /// <param name="entry"></param> /// <param name="evData"></param> /// <returns></returns> private bool ProcessXDnbLocked(CalendarEntry entry, VEventData evData) { evData.AppPropSet |= AppProp.XDnbLocked; return (entry.Value.ToLower().Equals("true")); }
/// <summary> /// Combines the main evData exDates list with a secondary /// accumulated exDates list /// </summary> /// <param name="evData"></param> /// <param name="exDates"></param> private void UnionExDates(VEventData evData, List<DateTime> exDates) { if (evData.ExDates == null) { evData.ExDates = exDates; } else if (exDates != null) { foreach (DateTime date in exDates) { if (evData.ExDates.Contains(date) == false) evData.ExDates.Add(date); } } }
/// <summary> /// Processes DNB TimeMarkedAs entries /// </summary> /// <param name="entry"></param> /// <param name="evData"></param> /// <returns></returns> private string ProcessXDnbTimeMarkedAs(CalendarEntry entry, VEventData evData) { evData.AppPropSet |= AppProp.XDnbTimeMarkedAs; return (entry.Value); }
/// <summary> /// Processes Summary entries /// </summary> /// <param name="entry"></param> /// <param name="evData"></param> /// <returns></returns> private string ProcessSummary(CalendarEntry entry, VEventData evData) { evData.AppPropSet |= AppProp.Summary; return (entry.Value); }
/// <summary> /// Processes VToDo entries /// </summary> /// <param name="ownerKey"></param> private void ProcessVTodo(string ownerKey) { Appointment app = new Appointment(); app.OwnerKey = ownerKey; VEventData evData = new VEventData(); CalendarEntry entry = GetNextEntry(); while (entry != null) { PropertyToken tkn = (PropertyToken)GetToken(_properties, entry.Id); switch (tkn) { case PropertyToken.Begin: ComponentToken ctkn = (ComponentToken)GetToken(_components, entry.Value); switch (ctkn) { case ComponentToken.VAlarm: ProcessVAlarm(evData); break; default: ReportError(entry, "Unexpected \"BEGIN:" + entry.Value.ToUpper() + "\""); SkipComponent(ctkn); break; } break; case PropertyToken.Description: app.Description = entry.Value; break; case PropertyToken.DtEnd: case PropertyToken.Due: app.EndTime = ProcessDate(entry, ref evData.IsDtEndValue); break; case PropertyToken.DtStart: app.StartTime = ProcessDate(entry, ref evData.IsDtStartValue); break; case PropertyToken.Duration: evData.Duration = ProcessDuration(entry, entry.Value); break; case PropertyToken.End: if ((ComponentToken)GetToken(_components, entry.Value) != ComponentToken.VTodo) ReportError(entry, "Expected \"END:VTODO\""); ProcessVEventEnd(entry, app, evData); return; case PropertyToken.RDate: evData.RecurDate = ProcessRDate(entry, evData.RecurDate); break; case PropertyToken.RRule: evData.RecurRule = ProcessRRule(entry); break; case PropertyToken.Summary: app.Subject = entry.Value; break; } entry = GetNextEntry(); } ReportError(entry, "Expected \"END:VTODO\""); }
/// <summary> /// Processes VAlarm component entries /// </summary> /// <param name="evData"></param> private void ProcessVAlarm(VEventData evData) { VAlarm valarm = new VAlarm(); CalendarEntry entry = GetNextEntry(); while (entry != null) { PropertyToken tkn = (PropertyToken)GetToken(_properties, entry.Id); switch (tkn) { case PropertyToken.Description: valarm.Description = entry.Value; break; case PropertyToken.End: if ((ComponentToken)GetToken(_components, entry.Value) != ComponentToken.VAlarm) ReportError(entry, "Expected \"END:VALARM\""); if (evData.VAlarms == null) evData.VAlarms = new List<VAlarm>(); evData.VAlarms.Add(valarm); return; case PropertyToken.Trigger: ProcessTrigger(entry, valarm); break; } entry = GetNextEntry(); } ReportError(entry, "Expected \"END:VALARM\""); }
/// <summary> /// Processes Event termination /// </summary> /// <param name="entry"></param> /// <param name="app"></param> /// <param name="evData"></param> private void ProcessVEventEnd(CalendarEntry entry, Appointment app, VEventData evData) { if (evData.RecIdDate != DateTime.MinValue) ProcessRecurrenceId(entry, app, evData); else ProcessEventEndEx(Model, entry, app, evData); }
/// <summary> /// Processes DNB CategoryColor entries /// </summary> /// <param name="entry"></param> /// <param name="evData"></param> /// <returns></returns> private string ProcessXDnbCategoryColor(CalendarEntry entry, VEventData evData) { evData.AppPropSet |= AppProp.XDnbCategoryColor; return(entry.Value); }
private bool ValidateAppTime(CalendarEntry entry, Appointment app, VEventData evData) { if (app.StartTime == DateTime.MinValue) { ReportError(entry, "DTSTART not set"); return (false); } if (evData.Duration.TotalSeconds != 0) app.EndTime = app.StartTime.Add(evData.Duration); else if (app.EndTime == DateTime.MinValue) { app.EndTime = (evData.IsDtStartValue == true) ? app.StartTime.AddDays(1) : app.StartTime; } if (app.StartTime > app.EndTime) { ReportError(entry, "DTSTART is greater than DTEND"); return (false); } evData.StartTime = app.StartTime; evData.EndTime = app.EndTime; return (true); }
/// <summary> /// Processes DNB DisplayTemplate entries /// </summary> /// <param name="entry"></param> /// <param name="evData"></param> /// <returns></returns> private string ProcessXDnbDisplayTemplate(CalendarEntry entry, VEventData evData) { evData.AppPropSet |= AppProp.XDnbDisplayTemplate; return (entry.Value); }
/// <summary> /// Processes Weekly recurrences /// </summary> /// <param name="model"></param> /// <param name="app"></param> /// <param name="evData"></param> private void ProcessWeeklyRecurrence(CalendarModel model, Appointment app, VEventData evData) { AppointmentRecurrence recur = new AppointmentRecurrence(); recur.RecurrenceType = eRecurrencePatternType.Weekly; recur.Weekly.RepeatInterval = evData.RecurRule.Interval; recur.Weekly.RepeatOnDaysOfWeek = (evData.RecurRule.ByDays == eDayOfWeekRecurrence.None) ? GetRecurrenceDay(app.StartTime) : evData.RecurRule.ByDays; ProcessRecurrenceRange(app, recur, evData); app.Recurrence = recur; model.Appointments.Add(app); }
/// <summary> /// Processes DNB specific ImageAlign entries /// </summary> /// <param name="entry"></param> /// <param name="evData"></param> /// <returns></returns> private eImageContentAlignment ProcessXDnbImageAlign(CalendarEntry entry, VEventData evData) { evData.AppPropSet |= AppProp.XDnbImageAlign; return ((eImageContentAlignment) GetEnumValue(typeof(eImageContentAlignment), entry.Value)); }
private void AddMonthlyByDay(CalendarModel model, Appointment app, DayOfWeek dayOfWeek, int byDay, VEventData evData) { AppointmentRecurrence recur = new AppointmentRecurrence(); recur.RecurrenceType = eRecurrencePatternType.Monthly; recur.Monthly.RepeatInterval = evData.RecurRule.Interval; recur.Monthly.RelativeDayOfWeek = dayOfWeek; recur.Monthly.RepeatOnRelativeDayInMonth = GetRelativeDay(byDay); if (app.Recurrence != null) { app = app.Copy(); app.StartTime = evData.StartTime; app.EndTime = evData.EndTime; evData.UidApps.Add(app); } model.Appointments.Add(app); DateTime oldStartTime = app.StartTime; SetNewByDayAppStartTime(app, dayOfWeek, byDay); if (app.StartTime < oldStartTime) recur.SkippedRecurrences.Add(app.StartTime); ProcessRecurrenceRange(app, recur, evData); app.Recurrence = recur; }
/// <summary> /// Processes event reminders /// </summary> /// <param name="evData"></param> private void ProcessVEventReminder(VEventData evData) { if (evData.VAlarms != null) { foreach (VAlarm valarm in evData.VAlarms) { foreach (Appointment app in evData.UidApps) { if ((valarm.Rel == Related.Start && valarm.Duration.TotalSeconds == 0) || (valarm.Rel == Related.Date && valarm.Date.Add(valarm.Duration) == app.StartTime)) { app.StartTimeAction = eStartTimeAction.StartTimeReachedEvent; } else { string s = String.IsNullOrEmpty(valarm.Description) ? app.Description : valarm.Description; DateTime date = app.StartTime; switch (valarm.Rel) { case Related.End: date = app.EndTime; break; case Related.Date: date = valarm.Date; break; } date = date.Add(valarm.Duration); app.Reminders.Add(new Reminder(s, date)); } } } } }