Exemple #1
0
        private void buildOutlookPattern(Event ev, AppointmentItem ai, out RecurrencePattern oPattern)
        {
            if (ev.Recurrence == null)
            {
                oPattern = null; return;
            }

            Dictionary <String, String> ruleBook = explodeRrule(ev.Recurrence);

            if (ruleBook == null)
            {
                throw new ApplicationException("WARNING: The recurrence pattern is not compatible with Outlook. This event cannot be synced.");
            }
            log.Fine("Building Outlook recurrence pattern");
            oPattern = ai.GetRecurrencePattern();

            #region RECURRENCE PATTERN
            //RRULE:FREQ=WEEKLY;UNTIL=20150906T000000Z;BYDAY=SA

            switch (ruleBook["FREQ"])
            {
            case "DAILY": {
                oPattern.RecurrenceType = OlRecurrenceType.olRecursDaily;
                break;
            }

            case "WEEKLY": {
                oPattern.RecurrenceType = OlRecurrenceType.olRecursWeekly;
                // Need to work out dayMask from "BY" pattern
                // Eg "BYDAY=MO,TU,WE,TH,FR"
                OlDaysOfWeek dowMask = getDOWmask(ruleBook);
                if (dowMask != 0)
                {
                    oPattern.DayOfWeekMask = dowMask;
                }
                break;
            }

            case "MONTHLY": {
                oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthly;
                if (ruleBook.ContainsKey("BYSETPOS"))
                {
                    oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthNth;
                    int gInstance = Convert.ToInt16(ruleBook["BYSETPOS"]);
                    oPattern.Instance      = (gInstance == -1) ? 5 : gInstance;
                    oPattern.DayOfWeekMask = getDOWmask(ruleBook);
                    if (oPattern.DayOfWeekMask == (OlDaysOfWeek)127 && gInstance == -1 &&
                        (ev.Start.DateTime ?? DateTime.Parse(ev.Start.Date)).Day > 28)
                    {
                        //In Outlook this is simply a monthly recurring
                        oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthly;
                    }
                }
                if (ruleBook.ContainsKey("BYDAY"))
                {
                    if (ruleBook["BYDAY"].StartsWith("-1"))
                    {
                        oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthNth;
                        oPattern.Instance       = 5;
                        oPattern.DayOfWeekMask  = getDOWmask(ruleBook["BYDAY"].TrimStart("-1".ToCharArray()));
                    }
                    else if ("1,2,3,4".Contains(ruleBook["BYDAY"].Substring(0, 1)))
                    {
                        oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthNth;
                        oPattern.Instance       = Convert.ToInt16(ruleBook["BYDAY"].Substring(0, 1));
                        oPattern.DayOfWeekMask  = getDOWmask(ruleBook["BYDAY"].TrimStart(oPattern.Instance.ToString().ToCharArray()));
                    }
                }
                break;
            }

            case "YEARLY": {
                oPattern.RecurrenceType = OlRecurrenceType.olRecursYearly;
                //Google interval is years, Outlook is months
                if (ruleBook.ContainsKey("INTERVAL") && Convert.ToInt16(ruleBook["INTERVAL"]) > 1)
                {
                    oPattern.Interval = Convert.ToInt16(ruleBook["INTERVAL"]) * 12;
                }
                if (ruleBook.ContainsKey("BYSETPOS"))
                {
                    oPattern.RecurrenceType = OlRecurrenceType.olRecursYearNth;
                    int gInstance = Convert.ToInt16(ruleBook["BYSETPOS"]);
                    oPattern.Instance = (gInstance == -1) ? 5 : gInstance;

                    oPattern.DayOfWeekMask = getDOWmask(ruleBook);
                    if (ruleBook.ContainsKey("BYMONTH"))
                    {
                        oPattern.MonthOfYear = Convert.ToInt16(ruleBook["BYMONTH"]);
                    }
                }
                break;
            }
            }
            #endregion

            #region RANGE
            ai = OutlookOgcs.Calendar.Instance.IOutlook.WindowsTimeZone_set(ai, ev);
            oPattern.PatternStartDate = ev.Start.DateTime ?? DateTime.Parse(ev.Start.Date);
            if (ruleBook.ContainsKey("INTERVAL") && Convert.ToInt16(ruleBook["INTERVAL"]) > 1 && ruleBook["FREQ"] != "YEARLY")
            {
                oPattern.Interval = Convert.ToInt16(ruleBook["INTERVAL"]);
            }
            if (ruleBook.ContainsKey("COUNT"))
            {
                oPattern.Occurrences = Convert.ToInt16(ruleBook["COUNT"]);
            }
            if (ruleBook.ContainsKey("UNTIL"))
            {
                if (ruleBook["UNTIL"].StartsWith("4500"))
                {
                    log.Warn("Outlook can't handle end dates this far in the future. Converting to no end date.");
                    oPattern.NoEndDate = true;
                }
                else
                {
                    DateTime endDate;
                    if (ruleBook["UNTIL"].Length == 8 && !ruleBook["UNTIL"].EndsWith("Z"))
                    {
                        endDate = DateTime.ParseExact(ruleBook["UNTIL"], "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture).Date;
                    }
                    else
                    {
                        endDate = DateTime.ParseExact(ruleBook["UNTIL"], "yyyyMMddTHHmmssZ", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AdjustToUniversal);
                        endDate = endDate.AddHours(TimezoneDB.GetUtcOffset(ev.End.TimeZone)).Date;
                    }
                    if (endDate < oPattern.PatternStartDate)
                    {
                        log.Debug("PatternStartDate: " + oPattern.PatternStartDate.ToString("yyyyMMddHHmmss"));
                        log.Debug("PatternEndDate:   " + ruleBook["UNTIL"].ToString());
                        String summary = GoogleOgcs.Calendar.GetEventSummary(ev, onlyIfNotVerbose: true);
                        Forms.Main.Instance.Console.Update(summary + "The recurring Google event has an end date <i>before</i> the start date, which Outlook doesn't allow.<br/>" +
                                                           "The synced Outlook recurrence has been changed to a single occurrence.", Console.Markup.warning);
                        oPattern.Occurrences = 1;
                    }
                    else
                    {
                        oPattern.PatternEndDate = endDate;
                    }
                }
            }
            if (!ruleBook.ContainsKey("COUNT") && !ruleBook.ContainsKey("UNTIL"))
            {
                oPattern.NoEndDate = true;
            }
            #endregion
        }