Skip to content

Commit

Permalink
Merge branch 'feature/issue-1553' into release
Browse files Browse the repository at this point in the history
Closes #1553
  • Loading branch information
phw198 committed Oct 26, 2023
2 parents 04e369a + 156cc83 commit c75ce6c
Show file tree
Hide file tree
Showing 7 changed files with 783 additions and 295 deletions.
709 changes: 498 additions & 211 deletions src/OutlookGoogleCalendarSync/Forms/MainForm.Designer.cs

Large diffs are not rendered by default.

239 changes: 168 additions & 71 deletions src/OutlookGoogleCalendarSync/Forms/MainForm.cs

Large diffs are not rendered by default.

11 changes: 7 additions & 4 deletions src/OutlookGoogleCalendarSync/Forms/MainForm.resx
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,10 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="msProfileActions.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>142, 17</value>
<value>403, 17</value>
</metadata>
<metadata name="msCategories.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
<value>126, 17</value>
</metadata>
<data name="lGoogleAPIInstructions.Text" xml:space="preserve">
<value>To change the Client ID and secret, first disconnect your account
Expand All @@ -131,9 +131,12 @@ Obtain new values from the Google Developer Console.
You'll need to enable the Calendar API in your project:
</value>
</data>
<metadata name="msSettingsActions.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<metadata name="msColours.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="msSettingsActions.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>251, 17</value>
</metadata>
<data name="label21.Text" xml:space="preserve">
<value>On the "Google" tab, select the calendar you wish to synchronise.

Expand All @@ -160,7 +163,7 @@ or support further improvements,
any donations would be greatly appreciated!</value>
</data>
<metadata name="trayIcon.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>285, 17</value>
<value>546, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="trayIcon.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
Expand Down
20 changes: 20 additions & 0 deletions src/OutlookGoogleCalendarSync/GoogleOgcs/EventColour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,26 @@ public void Get() {
foreach (KeyValuePair<String, ColorDefinition> colour in colours.Calendar) {
calendarPalette.Add(new Palette(Palette.Type.Calendar, colour.Key, colour.Value.Background, OutlookOgcs.Categories.Map.RgbColour(colour.Value.Background)));
}
Forms.Main.Instance.miColourBuildPicker_Click(null, null);
}

/// <summary>
/// Build colour list from those downloaded from Google.
/// </summary>
/// <param name="clb">The checklistbox to populate with the colours.</param>
public void BuildPicker(System.Windows.Forms.CheckedListBox clb) {
clb.BeginUpdate();
clb.Items.Clear();
clb.Items.Add("<Default calendar colour>");
foreach (Palette colour in GoogleOgcs.Calendar.Instance.ColourPalette.eventPalette) {
clb.Items.Add(colour.Name);
}
foreach (String colour in Forms.Main.Instance.ActiveCalendarProfile.Colours) {
try {
clb.SetItemChecked(clb.Items.IndexOf(colour), true);
} catch { /* Colour "colour" no longer exists */ }
}
clb.EndUpdate();
}

/// <summary>
Expand Down
65 changes: 59 additions & 6 deletions src/OutlookGoogleCalendarSync/GoogleOgcs/GoogleCalendar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ public static Calendar Instance {
Authenticator = new GoogleOgcs.Authenticator()
};
instance.Authenticator.GetAuthenticated();
if (instance.Authenticator.Authenticated)
if (instance.Authenticator.Authenticated) {
instance.Authenticator.OgcsUserStatus();
else {
_ = instance.ColourPalette;
} else {
instance = null;
if (Forms.Main.Instance.Console.DocumentText.Contains("Authorisation to allow OGCS to manage your Google calendar was cancelled."))
throw new OperationCanceledException();
Expand All @@ -43,6 +44,9 @@ public Calendar() { }
private Boolean openedIssue1593 = false;
public GoogleOgcs.Authenticator Authenticator;

/// <summary>Google Events excluded through user config <Event.Id, Appt.EntryId></summary>
public Dictionary<String, String> ExcludedByColour { get; private set; }

private GoogleOgcs.EventColour colourPalette;

public static Boolean IsColourPaletteNull { get { return instance?.colourPalette == null; } }
Expand Down Expand Up @@ -272,6 +276,7 @@ public List<Event> GetCalendarEntriesInRange() {

public List<Event> GetCalendarEntriesInRange(DateTime from, DateTime to) {
List<Event> result = new List<Event>();
ExcludedByColour = new Dictionary<String, String>();
Events request = null;
String pageToken = null;
Int16 pageNum = 1;
Expand Down Expand Up @@ -347,6 +352,26 @@ public List<Event> GetCalendarEntriesInRange(DateTime from, DateTime to) {
List<Event> privacy = new();
List<Event> declined = new();
List<Event> goals = new();
List<Event> colour = new();

//Colours
if (profile.ColoursRestrictBy == SettingsStore.Calendar.RestrictBy.Include) {
colour = result.Where(ev => (profile.Colours.Count() == 0 || (String.IsNullOrEmpty(ev.ColorId) && !profile.Colours.Contains("<Default calendar colour>")) ||
!String.IsNullOrEmpty(ev.ColorId) && !profile.Colours.Contains(EventColour.Palette.GetColourName(ev.ColorId)))).ToList();

} else if (profile.ColoursRestrictBy == SettingsStore.Calendar.RestrictBy.Exclude) {
colour = result.Where(ev => (profile.Colours.Count() > 0 && (String.IsNullOrEmpty(ev.ColorId) && profile.Colours.Contains("<Default calendar colour>")) ||
!String.IsNullOrEmpty(ev.ColorId) && profile.Colours.Contains(EventColour.Palette.GetColourName(ev.ColorId)))).ToList();
}
if (colour.Count > 0) {
log.Debug(colour.Count + " Google items contain a colour that is filtered out.");
}
foreach (Event ev in colour) {
ExcludedByColour.Add(ev.Id, CustomProperty.Get(ev, CustomProperty.MetadataId.oEntryId));
}
result = result.Except(colour).ToList();

//Availability, Privacy
if (profile.SyncDirection.Id != Sync.Direction.OutlookToGoogle.Id) { //Sync direction means G->O will delete previously synced all-days
if (profile.ExcludeFree) {
availability = result.Where(ev => ev.Transparency == "transparent").ToList();
Expand Down Expand Up @@ -379,6 +404,7 @@ public List<Event> GetCalendarEntriesInRange(DateTime from, DateTime to) {
}
}

//Invitation
if (profile.ExcludeDeclinedInvites) {
declined = result.Where(ev => string.IsNullOrEmpty(ev.RecurringEventId) && ev.Attendees != null && ev.Attendees.Count(a => a.Self == true && a.ResponseStatus == "declined") == 1).ToList();
if (declined.Count > 0) {
Expand All @@ -387,6 +413,7 @@ public List<Event> GetCalendarEntriesInRange(DateTime from, DateTime to) {
}
}

//Goals
if ((IsDefaultCalendar() ?? true) && profile.ExcludeGoals) {
goals = result.Where(ev =>
!string.IsNullOrEmpty(ev.Description) && ev.Description.Contains("This event was added from Goals in Google Calendar.") &&
Expand Down Expand Up @@ -1070,7 +1097,7 @@ private Boolean deleteCalendarEntry(Event ev) {
if (OgcsMessageBox.Show("Delete " + eventSummary + "?", "Confirm Deletion From Google",
MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.No) {
doDelete = false;
if (Sync.Engine.Calendar.Instance.Profile.SyncDirection.Id == Sync.Direction.Bidirectional.Id && CustomProperty.ExistsAny(ev)) {
if (Sync.Engine.Calendar.Instance.Profile.SyncDirection.Id == Sync.Direction.Bidirectional.Id && CustomProperty.ExistAnyOutlookIDs(ev)) {
CustomProperty.RemoveOutlookIDs(ref ev);
UpdateCalendarEntry_save(ref ev);
}
Expand Down Expand Up @@ -1408,15 +1435,24 @@ public void IdentifyEventDifferences(
if (responseFiltered > 0) log.Info(responseFiltered + " Outlook items will not be created due to only syncing invites that have been responded to.");
}

if (google.Count > 0 && OutlookOgcs.Calendar.Instance.ExcludedByCategory.Count > 0 && profile.SyncDirection.Id == Sync.Direction.Bidirectional.Id && !profile.DeleteWhenCategoryExcluded) {
if (google.Count > 0 && OutlookOgcs.Calendar.Instance.ExcludedByCategory.Count > 0 && !profile.DeleteWhenCategoryExcluded) {
//Check if Google items to be deleted were filtered out from Outlook
for (int g = google.Count - 1; g >= 0; g--) {
if (CustomProperty.Exists(google[g], CustomProperty.MetadataId.oEntryId) &&
OutlookOgcs.Calendar.Instance.ExcludedByCategory.Contains(CustomProperty.Get(google[g], CustomProperty.MetadataId.oEntryId))) {
if (OutlookOgcs.Calendar.Instance.ExcludedByCategory.ContainsValue(google[g].Id) ||
OutlookOgcs.Calendar.Instance.ExcludedByCategory.ContainsKey(CustomProperty.Get(google[g], CustomProperty.MetadataId.oEntryId) ?? "")) {
google.Remove(google[g]);
}
}
}
if (outlook.Count > 0 && GoogleOgcs.Calendar.Instance.ExcludedByColour.Count > 0) {
//Check if Outlook items to be created were filtered out from Google
for (int o = outlook.Count - 1; o >= 0; o--) {
if (ExcludedByColour.ContainsValue(outlook[o].EntryID) ||
ExcludedByColour.ContainsKey(OutlookOgcs.CustomProperty.Get(outlook[o], OutlookOgcs.CustomProperty.MetadataId.gEventID) ?? "")) {
outlook.Remove(outlook[o]);
}
}
}

if (profile.DisableDelete) {
if (google.Count > 0) {
Expand Down Expand Up @@ -2202,6 +2238,23 @@ public static ApiException HandleAPIlimits(ref Google.GoogleApiException ex, Eve
return null;
}
}

/// <summary>
/// Build colour list from any saved in Settings, instead of downloading from Google.
/// </summary>
/// <param name="clb">The checklistbox to populate with the colours.</param>
public static void BuildOfflineColourPicker(System.Windows.Forms.CheckedListBox clb) {
if (IsInstanceNull || !Instance.Authenticator.Authenticated) {
clb.BeginUpdate();
clb.Items.Clear();
foreach (String colour in Forms.Main.Instance.ActiveCalendarProfile.Colours) {
clb.Items.Add(colour, true);
}
clb.EndUpdate();
} else {
Instance.ColourPalette.BuildPicker(clb);
}
}
#endregion

/// <summary>
Expand Down
25 changes: 22 additions & 3 deletions src/OutlookGoogleCalendarSync/OutlookOgcs/OutlookCalendar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ public enum Service {
}
public EphemeralProperties EphemeralProperties = new EphemeralProperties();

/// <summary>Outlook Event IDs excluded through user config</summary>
public List<String> ExcludedByCategory;
/// <summary>Outlook Appointment excluded through user config <Appt.EntryId, Event.Id></Appt.EntryId></summary>
public Dictionary<String, String> ExcludedByCategory { get; private set; }

public Calendar() {
InstanceConnect = true;
Expand Down Expand Up @@ -234,7 +234,7 @@ public List<AppointmentItem> FilterCalendarEntries(SettingsStore.Calendar profil
(profile.CategoriesRestrictBy == SettingsStore.Calendar.RestrictBy.Exclude && profile.Categories.Contains("<No category assigned>")));
} else throw;
}
if (filtered) { ExcludedByCategory.Add(ai.EntryID); continue; }
if (filtered) { ExcludedByCategory.Add(ai.EntryID, CustomProperty.Get(ai, CustomProperty.MetadataId.gEventID)); continue; }

//Availability, Privacy, Subject
if (profile.SyncDirection.Id != Sync.Direction.GoogleToOutlook.Id) { //Sync direction means O->G will delete previously synced excluded items
Expand Down Expand Up @@ -1484,6 +1484,25 @@ public static void IdentifyEventDifferences(
if (responseFiltered > 0) log.Info(responseFiltered + " Outlook items will not be deleted due to only syncing invites that have been responded to.");
}

if (outlook.Count > 0 && GoogleOgcs.Calendar.Instance.ExcludedByColour.Count > 0 && !profile.DeleteWhenColourExcluded) {
//Check if Outlook items to be deleted were filtered out from Google
for (int o = outlook.Count - 1; o >= 0; o--) {
if (GoogleOgcs.Calendar.Instance.ExcludedByColour.ContainsValue(outlook[o].EntryID) ||
GoogleOgcs.Calendar.Instance.ExcludedByColour.ContainsKey(CustomProperty.Get(outlook[o], CustomProperty.MetadataId.gEventID) ?? "")) {
outlook.Remove(outlook[o]);
}
}
}
if (google.Count > 0 && Instance.ExcludedByCategory.Count > 0) {
//Check if Google items to be created were filtered out from Outlook
for (int g = google.Count - 1; g >= 0; g--) {
if (Instance.ExcludedByCategory.ContainsValue(google[g].Id) ||
Instance.ExcludedByCategory.ContainsKey(GoogleOgcs.CustomProperty.Get(google[g], GoogleOgcs.CustomProperty.MetadataId.oEntryId) ?? "")) {
google.Remove(google[g]);
}
}
}

if (profile.DisableDelete) {
if (outlook.Count > 0) {
Forms.Main.Instance.Console.Update(outlook.Count + " Outlook items would have been deleted, but you have deletions disabled.", Console.Markup.warning);
Expand Down
9 changes: 9 additions & 0 deletions src/OutlookGoogleCalendarSync/SettingsStore/Calendar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ private void setDefaults() {
//Google
UseGoogleCalendar = new GoogleCalendarListEntry();
CloakEmail = true;
ColoursRestrictBy = RestrictBy.Exclude;
DeleteWhenColourExcluded = true;
Colours = new List<String>();
ExcludeDeclinedInvites = true;
ExcludeGoals = true;

Expand Down Expand Up @@ -129,6 +132,9 @@ [DataMember] public Boolean OutlookGalBlocked {
#region Google
[DataMember] public GoogleCalendarListEntry UseGoogleCalendar { get; set; }
[DataMember] public Boolean CloakEmail { get; set; }
[DataMember] public RestrictBy ColoursRestrictBy { get; set; }
[DataMember] public Boolean DeleteWhenColourExcluded { get; set; }
[DataMember] public List<string> Colours { get; set; }
[DataMember] public Boolean ExcludeDeclinedInvites { get; set; }
[DataMember] public Boolean ExcludeGoals { get; set; }
#endregion
Expand Down Expand Up @@ -277,6 +283,9 @@ public void LogSettings() {

log.Info("GOOGLE SETTINGS:-");
log.Info(" Calendar: " + (UseGoogleCalendar?.Id == null ? "" : UseGoogleCalendar.ToString(true)));
log.Info(" Colour Filter: " + ColoursRestrictBy.ToString());
log.Info(" Delete When Excluded:" + DeleteWhenColourExcluded);
log.Info(" Colours: " + String.Join(",", Colours.ToArray()));
log.Info(" Exclude Declined Invites: " + ExcludeDeclinedInvites);
log.Info(" Exclude Goals: " + ExcludeGoals);
log.Info(" Cloak Email: " + CloakEmail);
Expand Down

0 comments on commit c75ce6c

Please sign in to comment.