diff --git a/src/OutlookGoogleCalendarSync/Forms/MainForm.cs b/src/OutlookGoogleCalendarSync/Forms/MainForm.cs index 3360172d..5bc1c982 100644 --- a/src/OutlookGoogleCalendarSync/Forms/MainForm.cs +++ b/src/OutlookGoogleCalendarSync/Forms/MainForm.cs @@ -1179,7 +1179,7 @@ private void ddMailboxName_SelectedIndexChanged(object sender, EventArgs e) { public void cbOutlookCalendar_SelectedIndexChanged(object sender, EventArgs e) { KeyValuePair calendar = (KeyValuePair)cbOutlookCalendars.SelectedItem; - OutlookOgcs.Calendar.Instance.UseOutlookCalendar = calendar.Value; + ActiveCalendarProfile.UseOutlookCalendar = new OutlookCalendarListEntry(calendar.Value); log.Warn("Outlook calendar selection changed to: " + ActiveCalendarProfile.UseOutlookCalendar.ToString()); } @@ -1263,14 +1263,20 @@ private void tbOutlookDateFormat_Leave(object sender, EventArgs e) { private void btTestOutlookFilter_Click(object sender, EventArgs e) { log.Debug("Testing the Outlook filter string."); - int filterCount = OutlookOgcs.Calendar.Instance.FilterCalendarEntries(this.ActiveCalendarProfile, OutlookOgcs.Calendar.Instance.UseOutlookCalendar.Items, false).Count(); - OutlookOgcs.Calendar.Disconnect(true); - String msg = "The format '" + tbOutlookDateFormat.Text + "' returns " + filterCount + " calendar items within the date range "; - msg += ActiveCalendarProfile.SyncStart.ToString(System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern); - msg += " and " + ActiveCalendarProfile.SyncEnd.ToString(System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern); - - log.Info(msg); - OgcsMessageBox.Show(msg, "Date-Time Format Results", MessageBoxButtons.OK, MessageBoxIcon.Information); + try { + MAPIFolder calendar = OutlookOgcs.Calendar.Instance.IOutlook.GetFolderByID(this.ActiveCalendarProfile.UseOutlookCalendar.Id+"1"); + int filterCount = OutlookOgcs.Calendar.Instance.FilterCalendarEntries(this.ActiveCalendarProfile, false).Count(); + OutlookOgcs.Calendar.Disconnect(true); + String msg = "The format '" + tbOutlookDateFormat.Text + "' returns " + filterCount + " calendar items within the date range "; + msg += ActiveCalendarProfile.SyncStart.ToString(System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern); + msg += " and " + ActiveCalendarProfile.SyncEnd.ToString(System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern); + + log.Info(msg); + OgcsMessageBox.Show(msg, "Date-Time Format Results", MessageBoxButtons.OK, MessageBoxIcon.Information); + } catch (System.Exception ex) { + OGCSexception.Analyse("Profile '" + Settings.Profile.Name(ActiveCalendarProfile) + "', calendar ID " + ActiveCalendarProfile.UseOutlookCalendar.Id, ex); + OgcsMessageBox.Show(ex.Message, "Unable to perform test", MessageBoxButtons.OK, MessageBoxIcon.Error); + } } private void urlDateFormats_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { diff --git a/src/OutlookGoogleCalendarSync/GoogleOgcs/CustomProperty.cs b/src/OutlookGoogleCalendarSync/GoogleOgcs/CustomProperty.cs index f07fea83..e740591c 100644 --- a/src/OutlookGoogleCalendarSync/GoogleOgcs/CustomProperty.cs +++ b/src/OutlookGoogleCalendarSync/GoogleOgcs/CustomProperty.cs @@ -141,7 +141,7 @@ private static String metadataIdKeyName(MetadataId id) { //For backward compatibility, always default to key names with no set number appended if (calendarKeys.Count == 0|| - (calendarKeys.Count == 1 && calendarKeys.ContainsKey(calendarKeyName)) && calendarKeys[calendarKeyName] == OutlookOgcs.Calendar.Instance.UseOutlookCalendar.EntryID) + (calendarKeys.Count == 1 && calendarKeys.ContainsKey(calendarKeyName)) && calendarKeys[calendarKeyName] == Sync.Engine.Calendar.Instance.Profile.UseOutlookCalendar.Id) { maxSet = -1; return returnVal; @@ -156,7 +156,7 @@ private static String metadataIdKeyName(MetadataId id) { if (matches[0].Groups[1].Value != "") appendedNos = Convert.ToInt16(matches[0].Groups[1].Value); if (appendedNos - maxSet == 1) maxSet = appendedNos; - if (kvp.Value == OutlookOgcs.Calendar.Instance.UseOutlookCalendar.EntryID) + if (kvp.Value == Sync.Engine.Calendar.Instance.Profile.UseOutlookCalendar.Id) returnSet = (matches[0].Groups[1].Value == "") ? "0" : matches[0].Groups[1].Value; } } @@ -198,9 +198,9 @@ public static Boolean Exists(Event ev, MetadataId searchId, out String searchKey int? keySet = getKeySet(ev, out maxSet); if (keySet.HasValue && keySet.Value != 0) searchKey += "-" + keySet.Value.ToString("D2"); if (searchId == MetadataId.oCalendarId) - return ev.ExtendedProperties.Private__.ContainsKey(searchKey) && ev.ExtendedProperties.Private__[searchKey] == OutlookOgcs.Calendar.Instance.UseOutlookCalendar.EntryID; + return ev.ExtendedProperties.Private__.ContainsKey(searchKey) && ev.ExtendedProperties.Private__[searchKey] == Sync.Engine.Calendar.Instance.Profile.UseOutlookCalendar.Id; else - return ev.ExtendedProperties.Private__.ContainsKey(searchKey) && Get(ev, MetadataId.oCalendarId) == OutlookOgcs.Calendar.Instance.UseOutlookCalendar.EntryID; + return ev.ExtendedProperties.Private__.ContainsKey(searchKey) && Get(ev, MetadataId.oCalendarId) == Sync.Engine.Calendar.Instance.Profile.UseOutlookCalendar.Id; } public static Boolean ExistsAny(Event ev) { @@ -214,7 +214,7 @@ public static Boolean ExistsAny(Event ev) { /// Add the Outlook appointment IDs into Google event. /// public static void AddOutlookIDs(ref Event ev, AppointmentItem ai) { - Add(ref ev, MetadataId.oCalendarId, OutlookOgcs.Calendar.Instance.UseOutlookCalendar.EntryID); + Add(ref ev, MetadataId.oCalendarId, Sync.Engine.Calendar.Instance.Profile.UseOutlookCalendar.Id); Add(ref ev, MetadataId.oEntryId, ai.EntryID); Add(ref ev, MetadataId.oGlobalApptId, OutlookOgcs.Calendar.Instance.IOutlook.GetGlobalApptID(ai)); CustomProperty.LogProperties(ev, log4net.Core.Level.Debug); diff --git a/src/OutlookGoogleCalendarSync/GoogleOgcs/GoogleCalendar.cs b/src/OutlookGoogleCalendarSync/GoogleOgcs/GoogleCalendar.cs index 0670115a..8849cff1 100644 --- a/src/OutlookGoogleCalendarSync/GoogleOgcs/GoogleCalendar.cs +++ b/src/OutlookGoogleCalendarSync/GoogleOgcs/GoogleCalendar.cs @@ -1216,7 +1216,7 @@ public void IdentifyEventDifferences( } } if (!foundMatch && profile.MergeItems && - GoogleOgcs.CustomProperty.Get(google[g], CustomProperty.MetadataId.oCalendarId) != OutlookOgcs.Calendar.Instance.UseOutlookCalendar.EntryID) + GoogleOgcs.CustomProperty.Get(google[g], CustomProperty.MetadataId.oCalendarId) != profile.UseOutlookCalendar.Id) google.Remove(google[g]); } else if (profile.MergeItems) { @@ -1278,7 +1278,7 @@ public static Boolean ItemIDsMatch(ref Event ev, AppointmentItem ai) { { log.Fine("Comparing Outlook CalendarID"); gCompareID = CustomProperty.Get(ev, CustomProperty.MetadataId.oCalendarId); - if (gCompareID == OutlookOgcs.Calendar.Instance.UseOutlookCalendar.EntryID) { + if (gCompareID == profile.UseOutlookCalendar.Id) { //But...if an appointment is copied within ones own calendar, the DATA part is the same (only the creation time changes)! //So now compare the Entry ID too. diff --git a/src/OutlookGoogleCalendarSync/OutlookOgcs/OutlookCalendar.cs b/src/OutlookGoogleCalendarSync/OutlookOgcs/OutlookCalendar.cs index 9e043adf..114f74e3 100644 --- a/src/OutlookGoogleCalendarSync/OutlookOgcs/OutlookCalendar.cs +++ b/src/OutlookGoogleCalendarSync/OutlookOgcs/OutlookCalendar.cs @@ -45,13 +45,6 @@ public static Calendar Instance { public static Boolean OOMsecurityInfo = false; private static List alreadyRedirectedToWikiForComError = new List(); public const String GlobalIdPattern = "040000008200E00074C5B7101A82E008"; - public MAPIFolder UseOutlookCalendar { - get { return IOutlook.UseOutlookCalendar(); } - set { - IOutlook.UseOutlookCalendar(value); - Forms.Main.Instance.ActiveCalendarProfile.UseOutlookCalendar = new OutlookCalendarListEntry(value); - } - } public Folders Folders { get { return IOutlook.Folders(); } } @@ -104,7 +97,7 @@ public static void Disconnect(Boolean onlyWhenNoGUI = false) { public List GetCalendarEntriesInRange(SettingsStore.Calendar profile, Boolean suppressAdvisories) { List filtered = new List(); try { - filtered = FilterCalendarEntries(profile, UseOutlookCalendar.Items, suppressAdvisories: suppressAdvisories); + filtered = FilterCalendarEntries(profile, suppressAdvisories: suppressAdvisories); } catch (System.Runtime.InteropServices.InvalidComObjectException ex) { if (OGCSexception.GetErrorCode(ex) == "0x80131527") { //COM object separated from underlying RCW log.Warn(ex.Message); @@ -120,18 +113,10 @@ public List GetCalendarEntriesInRange(SettingsStore.Calendar pr } throw; - } catch (System.NullReferenceException ex) { - if (Instance.UseOutlookCalendar == null) { - OGCSexception.LogAsFail(ref ex); - OGCSexception.Analyse(ex); - OutlookOgcs.Calendar.Instance.Reset(); - filtered = FilterCalendarEntries(profile, Instance.UseOutlookCalendar.Items, suppressAdvisories: suppressAdvisories); - } else throw; - } catch (System.ArgumentNullException ex) { OGCSexception.Analyse("It seems that Outlook has just been closed.", OGCSexception.LogAsFail(ex)); OutlookOgcs.Calendar.Instance.Reset(); - filtered = FilterCalendarEntries(profile, Instance.UseOutlookCalendar.Items, suppressAdvisories: suppressAdvisories); + filtered = FilterCalendarEntries(profile, suppressAdvisories: suppressAdvisories); } catch (System.Exception) { if (!suppressAdvisories) Forms.Main.Instance.Console.Update("Unable to access the Outlook calendar.", Console.Markup.error); @@ -140,16 +125,27 @@ public List GetCalendarEntriesInRange(SettingsStore.Calendar pr return filtered; } - public List FilterCalendarEntries(SettingsStore.Calendar profile, Items OutlookItems, Boolean filterBySettings = true, + public List FilterCalendarEntries(SettingsStore.Calendar profile, Boolean filterBySettings = true, Boolean noDateFilter = false, String extraFilter = "", Boolean suppressAdvisories = false) { //Filtering info @ https://msdn.microsoft.com/en-us/library/cc513841%28v=office.12%29.aspx List result = new List(); + Items OutlookItems = null; + + if (profile is null) + profile = Settings.Profile.InPlay(); + + try { + MAPIFolder thisUseOutlookCalendar = IOutlook.GetFolderByID(profile.UseOutlookCalendar.Id); + OutlookItems = thisUseOutlookCalendar.Items; + } catch { + log.Fail("Could not open '" + Settings.Profile.Name(profile) + "' profile calendar folder with ID " + profile.UseOutlookCalendar.Id); + throw; + } + if (OutlookItems != null) { log.Fine(OutlookItems.Count + " calendar items exist."); - if (profile is null) - profile = Settings.Profile.InPlay(); - + OutlookItems.Sort("[Start]", Type.Missing); OutlookItems.IncludeRecurrences = false; @@ -1265,7 +1261,7 @@ private static string exportToCSV(AppointmentItem ai) { csv.Append(ai.ReminderSet + ","); csv.Append(ai.ReminderMinutesBeforeStart.ToString() + ","); csv.Append(OutlookOgcs.Calendar.Instance.IOutlook.GetGlobalApptID(ai) + ","); - csv.Append(ai.EntryID + "," + OutlookOgcs.Calendar.instance.UseOutlookCalendar.EntryID + ","); + csv.Append(ai.EntryID + "," + Sync.Engine.Calendar.Instance.Profile.UseOutlookCalendar.Id + ","); csv.Append((CustomProperty.Get(ai, CustomProperty.MetadataId.gEventID) ?? "") + ","); csv.Append((CustomProperty.Get(ai, CustomProperty.MetadataId.gCalendarId) ?? "") + ","); csv.Append(CustomProperty.GetOGCSlastModified(ai).ToString() + ","); diff --git a/src/OutlookGoogleCalendarSync/OutlookOgcs/OutlookInterface.cs b/src/OutlookGoogleCalendarSync/OutlookOgcs/OutlookInterface.cs index 3e4114ec..cf1bec36 100644 --- a/src/OutlookGoogleCalendarSync/OutlookOgcs/OutlookInterface.cs +++ b/src/OutlookGoogleCalendarSync/OutlookOgcs/OutlookInterface.cs @@ -34,6 +34,7 @@ public interface Interface { /// The logic by which to perform filter /// Filtered items List FilterItems(Items outlookItems, String filter); + MAPIFolder GetFolderByID(String entryID); void GetAppointmentByID(String entryID, out AppointmentItem ai); } } diff --git a/src/OutlookGoogleCalendarSync/OutlookOgcs/OutlookNew.cs b/src/OutlookGoogleCalendarSync/OutlookOgcs/OutlookNew.cs index 7d78f47d..02bd1127 100644 --- a/src/OutlookGoogleCalendarSync/OutlookOgcs/OutlookNew.cs +++ b/src/OutlookGoogleCalendarSync/OutlookOgcs/OutlookNew.cs @@ -537,10 +537,24 @@ public List FilterItems(Items outlookItems, String filter) { return restrictedItems; } + public MAPIFolder GetFolderByID(String entryID) { + NameSpace ns = null; + try { + ns = oApp.GetNamespace("mapi"); + return ns.GetFolderFromID(entryID); + } finally { + ns = (NameSpace)OutlookOgcs.Calendar.ReleaseObject(ns); + } + } + public void GetAppointmentByID(String entryID, out AppointmentItem ai) { - NameSpace ns = oApp.GetNamespace("mapi"); - ai = ns.GetItemFromID(entryID) as AppointmentItem; - ns = (NameSpace)OutlookOgcs.Calendar.ReleaseObject(ns); + NameSpace ns = null; + try { + ns = oApp.GetNamespace("mapi"); + ai = ns.GetItemFromID(entryID) as AppointmentItem; + } finally { + ns = (NameSpace)OutlookOgcs.Calendar.ReleaseObject(ns); + } } public String GetRecipientEmail(Recipient recipient) { diff --git a/src/OutlookGoogleCalendarSync/OutlookOgcs/OutlookOld.cs b/src/OutlookGoogleCalendarSync/OutlookOgcs/OutlookOld.cs index 85d12d75..70578757 100644 --- a/src/OutlookGoogleCalendarSync/OutlookOgcs/OutlookOld.cs +++ b/src/OutlookGoogleCalendarSync/OutlookOgcs/OutlookOld.cs @@ -1,7 +1,6 @@ using Google.Apis.Calendar.v3.Data; using log4net; using Microsoft.Office.Interop.Outlook; -using NodaTime; using System; using System.Collections.Generic; using System.Linq; @@ -409,10 +408,24 @@ public List FilterItems(Items outlookItems, String filter) { return restrictedItems; } + public MAPIFolder GetFolderByID(String entryID) { + NameSpace ns = null; + try { + ns = oApp.GetNamespace("mapi"); + return ns.GetFolderFromID(entryID); + } finally { + ns = (NameSpace)OutlookOgcs.Calendar.ReleaseObject(ns); + } + } + public void GetAppointmentByID(String entryID, out AppointmentItem ai) { - NameSpace ns = oApp.GetNamespace("mapi"); - ai = ns.GetItemFromID(entryID) as AppointmentItem; - ns = (NameSpace)OutlookOgcs.Calendar.ReleaseObject(ns); + NameSpace ns = null; + try { + oApp.GetNamespace("mapi"); + ai = ns.GetItemFromID(entryID) as AppointmentItem; + } finally { + ns = (NameSpace)OutlookOgcs.Calendar.ReleaseObject(ns); + } } public String GetRecipientEmail(Recipient recipient) { diff --git a/src/OutlookGoogleCalendarSync/Program.cs b/src/OutlookGoogleCalendarSync/Program.cs index 9bd763a0..9a197783 100644 --- a/src/OutlookGoogleCalendarSync/Program.cs +++ b/src/OutlookGoogleCalendarSync/Program.cs @@ -558,7 +558,7 @@ public static Boolean CalledByProcess(String callingProcessNames) { return false; } - /*public static void StackTraceToString() { + public static void StackTraceToString() { try { String stackString = ""; List stackFrames = new System.Diagnostics.StackTrace().GetFrames().ToList(); @@ -567,6 +567,6 @@ public static Boolean CalledByProcess(String callingProcessNames) { } catch (System.Exception ex) { OGCSexception.Analyse(ex); } - }*/ + } } } diff --git a/src/OutlookGoogleCalendarSync/Properties/AssemblyInfo.cs b/src/OutlookGoogleCalendarSync/Properties/AssemblyInfo.cs index 6c0c1ed0..5ed597c7 100644 --- a/src/OutlookGoogleCalendarSync/Properties/AssemblyInfo.cs +++ b/src/OutlookGoogleCalendarSync/Properties/AssemblyInfo.cs @@ -28,6 +28,6 @@ // You can specify all the values or you can use the default the Revision and // Build Numbers by using the '*' as shown below: [assembly: AssemblyVersion("2.9.*")] -[assembly: AssemblyFileVersion("2.9.1.10")] +[assembly: AssemblyFileVersion("2.9.1.11")] [assembly: AssemblyMetadata("SquirrelAwareVersion", "1")] \ No newline at end of file diff --git a/src/OutlookGoogleCalendarSync/SettingsStore/Settings.cs b/src/OutlookGoogleCalendarSync/SettingsStore/Settings.cs index 869ddf43..cbc175d7 100644 --- a/src/OutlookGoogleCalendarSync/SettingsStore/Settings.cs +++ b/src/OutlookGoogleCalendarSync/SettingsStore/Settings.cs @@ -446,14 +446,21 @@ public static String Name(Object settingsStore) { /// /// Currently hard-coded to a Calendar profile public static SettingsStore.Calendar InPlay() { - SettingsStore.Calendar aProfile = null; + SettingsStore.Calendar aProfile; - if (Program.CalledByProcess("OnTick")) { + if (Program.CalledByProcess("manualSynchronize,updateGUIsettings,UpdateGUIsettings_Profile,miCatRefresh_Click," + + "GetMyGoogleCalendars_Click,btColourMap_Click,ColourPicker_Enter,ddGoogleColour_SelectedIndexChanged")) { + aProfile = Forms.Main.Instance.ActiveCalendarProfile; + log.Fine("Using profile Forms.Main.Instance.ActiveCalendarProfile"); + + } else if (Program.CalledByProcess("synchronize,OnTick")) { aProfile = Sync.Engine.Calendar.Instance.Profile; log.Fine("Using profile Sync.Engine.Calendar.Instance.Profile"); + } else { + Program.StackTraceToString(); + log.Error("Unknown profile being referenced."); aProfile = Forms.Main.Instance.ActiveCalendarProfile; - log.Fine("Using profile Forms.Main.Instance.ActiveCalendarProfile"); } return aProfile; } diff --git a/src/OutlookGoogleCalendarSync/Sync/Calendar.cs b/src/OutlookGoogleCalendarSync/Sync/Calendar.cs index 70cacd2c..314aec24 100644 --- a/src/OutlookGoogleCalendarSync/Sync/Calendar.cs +++ b/src/OutlookGoogleCalendarSync/Sync/Calendar.cs @@ -34,7 +34,7 @@ public Calendar() { Profile = Sync.Engine.Instance.ActiveProfile as SettingsStore.Calendar; } - public void StartSync(Boolean updateSyncSchedule = true) { + public void StartSync(Boolean manualIgnition, Boolean updateSyncSchedule = true) { Forms.Main mainFrm = Forms.Main.Instance; mainFrm.bSyncNow.Text = "Stop Sync"; mainFrm.NotificationTray.UpdateItem("sync", "&Stop Sync"); @@ -121,7 +121,7 @@ public void StartSync(Boolean updateSyncSchedule = true) { delegate (object o, DoWorkEventArgs args) { BackgroundWorker b = o as BackgroundWorker; try { - syncResult = synchronize(); + syncResult = manualIgnition ? manualSynchronize() : synchronize(); } catch (System.Exception ex) { String hResult = OGCSexception.GetErrorCode(ex); @@ -264,6 +264,11 @@ private void skipCorruptedItem(ref List outlookEntries, Appoint } } + private SyncResult manualSynchronize() { + //This function is just a shim to determine how the sync was triggered when looking at the call stack + return synchronize(); + } + private SyncResult synchronize() { Console console = Forms.Main.Instance.Console; console.Update("Finding Calendar Entries", Console.Markup.mag_right, newLine: false); diff --git a/src/OutlookGoogleCalendarSync/Sync/Engine.cs b/src/OutlookGoogleCalendarSync/Sync/Engine.cs index c9362750..335e1a2f 100644 --- a/src/OutlookGoogleCalendarSync/Sync/Engine.cs +++ b/src/OutlookGoogleCalendarSync/Sync/Engine.cs @@ -52,7 +52,7 @@ private void QueueTimer_Tick(object sender, EventArgs e) { queue.RemoveAt(0); log.Info("Scheduled sync started (" + job.RequestedBy + ") for profile: " + job.ProfileName); this.ActiveProfile = job.Profile; - Engine.Instance.Start(updateSyncSchedule: (job.RequestedBy == "AutoSyncTimer")); + Engine.Instance.Start(manualIgnition: false, updateSyncSchedule: (job.RequestedBy == "AutoSyncTimer")); } catch (System.Exception ex) { OGCSexception.Analyse("Scheduled sync encountered a problem.", ex, true); } @@ -147,7 +147,7 @@ public void Sync_Requested(object sender = null, EventArgs e = null) { ManualForceCompare = true; } this.ActiveProfile = Forms.Main.Instance.ActiveCalendarProfile; - Start(updateSyncSchedule: false); + Start(manualIgnition: true, updateSyncSchedule: false); } else if (Forms.Main.Instance.bSyncNow.Text == "Stop Sync") { GoogleOgcs.Calendar.Instance.Authenticator.CancelTokenSource.Cancel(); @@ -177,17 +177,17 @@ public void AbortSync() { bwSync.Dispose(); bwSync = null; } catch (System.Exception ex) { - OGCSexception.Analyse(ex); - } finally { + OGCSexception.Analyse(ex); + } finally { log.Warn("Sync thread forcefully aborted!"); - } - } + } + } - private void Start(Boolean updateSyncSchedule = true) { + private void Start(Boolean manualIgnition, Boolean updateSyncSchedule) { if (Settings.Profile.GetType(this.ActiveProfile) == Settings.Profile.Type.Calendar) { Forms.Main.Instance.NotificationTray.ShowBubbleInfo("Autosyncing calendars: " + (this.ActiveProfile as SettingsStore.Calendar).SyncDirection.Name + "..."); Sync.Engine.Calendar.Instance.Profile = this.ActiveProfile as SettingsStore.Calendar; - Sync.Engine.Calendar.Instance.StartSync(updateSyncSchedule); + Sync.Engine.Calendar.Instance.StartSync(manualIgnition, updateSyncSchedule); } }