using System;
using Google.Contacts;
using Google.GData.Contacts;
using Google.GData.Extensions;
using Outlook = Microsoft.Office.Interop.Outlook;
namespace GoContactSyncMod
{
internal static class ContactSync
{
internal static DateTime outlookDateNone = new DateTime(4501, 1, 1);
private const string relSpouse = "spouse";
private const string relChild = "child";
private const string relManager = "manager";
private const string relAssistant = "assistant";
private const string relAnniversary = "anniversary";
private const string relHomePage = "home-page";
#region addresses
private static void SetAddress(ExtensionCollection<StructuredPostalAddress> destination, string address, string street, string city, string postcode, string pobox, string region, string country, string rel)
{
if (!string.IsNullOrEmpty(address))
{
var postalAddress = new StructuredPostalAddress
{
Street = street,
City = city,
Postcode = postcode,
Pobox = pobox,
Region = region,
Primary = destination.Count == 0,
Rel = rel
};
//By default Outlook is not setting Country in formatted string in case Windows is configured for the same country
//(Control Panel\Regional Settings). So set country in Google only if Outlook address has it
if (address.EndsWith("\r\n" + country))
{
postalAddress.Country = country;
}
destination.Add(postalAddress);
}
}
internal static void SetAddresses(Outlook.ContactItem master, Contact slave)
{
//validate if maybe at Google contact you have more postal addresses than Outlook can handle
var IsHomeCount = 0;
var IsWorkCount = 0;
var IsOtherCount = 0;
foreach (var address in slave.PostalAddresses)
{
switch (address.Rel)
{
case ContactsRelationships.IsHome:
IsHomeCount++;
break;
case ContactsRelationships.IsWork:
IsWorkCount++;
break;
case ContactsRelationships.IsOther:
IsOtherCount++;
break;
default:
Logger.Log($"Google contact \"{slave.Title}\" has custom address labeled \"{address.Label}\", this address is not synchronized with Outlook. Please update contact at Google and change label to standard one.", EventType.Warning);
break;
}
}
if (IsHomeCount > 1)
{
Logger.Log($"Google contact \"{slave.Title}\" has {IsHomeCount} home addresses, Outlook can have only 1 home address. You will loose information about additional home addresses.", EventType.Warning);
}
if (IsWorkCount > 1)
{
Logger.Log($"Google contact \"{slave.Title}\" has {IsWorkCount} business addresses, Outlook can have only 1 business address. You will loose information about additional business addresses.", EventType.Warning);
}
if (IsOtherCount > 1)
{
Logger.Log($"Google contact \"{slave.Title}\" has {IsOtherCount} other addresses, Outlook can have only 1 other address. You will loose information about additional other addresses.", EventType.Warning);
}
//clear only phone numbers synchronized with Outlook, this will prevent losing Google phones with custom labels
for (var i = slave.PostalAddresses.Count - 1; i >= 0; i--)
{
if (
(slave.PostalAddresses[i].Rel == ContactsRelationships.IsHome) ||
(slave.PostalAddresses[i].Rel == ContactsRelationships.IsWork) ||
(slave.PostalAddresses[i].Rel == ContactsRelationships.IsOther)
)
{
slave.PostalAddresses.RemoveAt(i);
}
};
SetAddress(slave.PostalAddresses,
master.HomeAddress,
master.HomeAddressStreet,
master.HomeAddressCity,
master.HomeAddressPostalCode,
master.HomeAddressPostOfficeBox,
master.HomeAddressState,
master.HomeAddressCountry,
ContactsRelationships.IsHome
);
SetAddress(slave.PostalAddresses,
master.BusinessAddress,
master.BusinessAddressStreet,
master.BusinessAddressCity,
master.BusinessAddressPostalCode,
master.BusinessAddressPostOfficeBox,
master.BusinessAddressState,
master.BusinessAddressCountry,
ContactsRelationships.IsWork
);
SetAddress(slave.PostalAddresses,
master.OtherAddress,
master.OtherAddressStreet,
master.OtherAddressCity,
master.OtherAddressPostalCode,
master.OtherAddressPostOfficeBox,
master.OtherAddressState,
master.OtherAddressCountry,
ContactsRelationships.IsOther
);
}
private static void SetAddress(StructuredPostalAddress address, Outlook.ContactItem destination)
{
if (address.Rel == ContactsRelationships.IsHome)
{
destination.HomeAddressStreet = address.Street;
destination.HomeAddressCity = address.City;
destination.HomeAddressPostalCode = address.Postcode;
destination.HomeAddressCountry = address.Country;
destination.HomeAddressState = address.Region;
destination.HomeAddressPostOfficeBox = address.Pobox;
//Workaround because of Google bug: If a contact was created on GOOGLE side, it uses the unstructured approach
//Therefore we need to check, if the structure was filled, if yes it resulted in a formatted string in the Address summary field
//If not, the formatted string is null => overwrite it with the formmatedAddress from Google
if (string.IsNullOrEmpty(destination.HomeAddress))
{
destination.HomeAddress = address.FormattedAddress;
}
//By default Outlook is not setting Country in formatted string in case Windows is configured for the same country
//(Control Panel\Regional Settings). So append country, but to be on safe side only if Google address has it
if (!string.IsNullOrEmpty(address.Country) &&
!string.IsNullOrEmpty(address.FormattedAddress) && address.FormattedAddress.EndsWith("\n" + address.Country) &&
!string.IsNullOrEmpty(destination.HomeAddress) && !destination.HomeAddress.EndsWith("\r\n" + address.Country))
{
destination.HomeAddress = destination.HomeAddress + "\r\n" + address.Country;
}
if (address.Primary)
{
destination.SelectedMailingAddress = Outlook.OlMailingAddress.olHome;
}
}
else if (address.Rel == ContactsRelationships.IsWork)
{
destination.BusinessAddressStreet = address.Street;
destination.BusinessAddressCity = address.City;
destination.BusinessAddressPostalCode = address.Postcode;
destination.BusinessAddressCountry = address.Country;
destination.BusinessAddressState = address.Region;
destination.BusinessAddressPostOfficeBox = address.Pobox;
//Workaround because of Google bug: If a contact was created on GOOGLE side, it uses the unstructured approach
//Therefore we need to check, if the structure was filled, if yes it resulted in a formatted string in the Address summary field
//If not, the formatted string is null => overwrite it with the formmatedAddress from Google
if (string.IsNullOrEmpty(destination.BusinessAddress))
{
destination.BusinessAddress = address.FormattedAddress;
}
//By default Outlook is not setting Country in formatted string in case Windows is configured for the same country
//(Control Panel\Regional Settings). So append country, but to be on safe side only if Google address has it
if (!string.IsNullOrEmpty(address.Country) &&
!string.IsNullOrEmpty(address.FormattedAddress) && address.FormattedAddress.EndsWith("\n" + address.Country) &&
!string.IsNullOrEmpty(destination.BusinessAddress) && !destination.BusinessAddress.EndsWith("\r\n" + address.Country))
{
destination.BusinessAddress = destination.BusinessAddress + "\r\n" + address.Country;
}
if (address.Primary)
{
destination.SelectedMailingAddress = Outlook.OlMailingAddress.olBusiness;
}
}
else if (address.Rel == ContactsRelationships.IsOther)
{
destination.OtherAddressStreet = address.Street;
destination.OtherAddressCity = address.City;
destination.OtherAddressPostalCode = address.Postcode;
destination.OtherAddressCountry = address.Country;
destination.OtherAddressState = address.Region;
destination.OtherAddressPostOfficeBox = address.Pobox;
//Workaround because of Google bug: If a contact was created on GOOGLE side, it uses the unstructured approach
//Therefore we need to check, if the structure was filled, if yes it resulted in a formatted string in the Address summary field
//If not, the formatted string is null => overwrite it with the formmatedAddress from Google
if (string.IsNullOrEmpty(destination.OtherAddress))
{
destination.OtherAddress = address.FormattedAddress;
}
//By default Outlook is not setting Country in formatted string in case Windows is configured for the same country
//(Control Panel\Regional Settings). So append country, but to be on safe side only if Google address has it
if (!string.IsNullOrEmpty(address.Country) &&
!string.IsNullOrEmpty(address.FormattedAddress) && address.FormattedAddress.EndsWith("\n" + address.Country) &&
!string.IsNullOrEmpty(destination.OtherAddress) && !destination.OtherAddress.EndsWith("\r\n" + address.Country))
{
destination.OtherAddress = destination.OtherAddress + "\r\n" + address.Country;
}
if (address.Primary)
{
destination.SelectedMailingAddress = Outlook.OlMailingAddress.olOther;
}
}
}
private static void SetAddresses(Contact master, Outlook.ContactItem slave)
{
//validate if maybe at Google contact you have more postal addresses than Outlook can handle
var IsHomeCount = 0;
var IsWorkCount = 0;
var IsOtherCount = 0;
foreach (var address in master.PostalAddresses)
{
switch (address.Rel)
{
case ContactsRelationships.IsHome:
IsHomeCount++;
break;
case ContactsRelationships.IsWork:
IsWorkCount++;
break;
case ContactsRelationships.IsOther:
IsOtherCount++;
break;
default:
Logger.Log($"Google contact \"{master.Title}\" has custom address number labeled \"{address.Label}\", this address is not synchronized with Outlook. Please update contact at Google and change label to standard one.", EventType.Warning);
break;
}
}
if (IsHomeCount > 1)
{
Logger.Log($"Google contact \"{master.Title}\" has {IsHomeCount} home addresses, Outlook can have only 1 home address. Please update contact at Google, otherwise you will loose information about additional home addresses.", EventType.Warning);
}
if (IsWorkCount > 1)
{
Logger.Log($"Google contact \"{master.Title}\" has {IsWorkCount} business addresses, Outlook can have only 1 business address. Please update contact at Google, otherwise you will loose information about additional business addresses.", EventType.Warning);
}
if (IsOtherCount > 1)
{
Logger.Log($"Google contact \"{master.Title}\" has {IsOtherCount} other addresses, Outlook can have only 1 other address. Please update contact at Google, otherwise you will loose information about additional other addresses.", EventType.Warning);
}
slave.HomeAddress = string.Empty;
slave.HomeAddressStreet = string.Empty;
slave.HomeAddressCity = string.Empty;
slave.HomeAddressPostalCode = string.Empty;
slave.HomeAddressCountry = string.Empty;
slave.HomeAddressState = string.Empty;
slave.HomeAddressPostOfficeBox = string.Empty;
slave.BusinessAddress = string.Empty;
slave.BusinessAddressStreet = string.Empty;
slave.BusinessAddressCity = string.Empty;
slave.BusinessAddressPostalCode = string.Empty;
slave.BusinessAddressCountry = string.Empty;
slave.BusinessAddressState = string.Empty;
slave.BusinessAddressPostOfficeBox = string.Empty;
slave.OtherAddress = string.Empty;
slave.OtherAddressStreet = string.Empty;
slave.OtherAddressCity = string.Empty;
slave.OtherAddressPostalCode = string.Empty;
slave.OtherAddressCountry = string.Empty;
slave.OtherAddressState = string.Empty;
slave.OtherAddressPostOfficeBox = string.Empty;
slave.SelectedMailingAddress = Outlook.OlMailingAddress.olNone;
foreach (var address in master.PostalAddresses)
{
SetAddress(address, slave);
}
}
#endregion
#region phones
private static void SetPhoneNumber(ExtensionCollection<PhoneNumber> phones, string number, string rel)
{
if (!string.IsNullOrWhiteSpace(number))
{
var phoneNumber = new PhoneNumber(number)
{
Primary = phones.Count == 0,
Rel = rel
};
phones.Add(phoneNumber);
}
}
internal static void SetPhoneNumbers(Outlook.ContactItem master, Contact slave)
{
//validate if maybe at Google contact you have more phones than Outlook can handle
var IsMainCount = 0;
var IsHomeCount = 0;
var IsWorkCount = 0;
var IsMobileCount = 0;
var IsWorkFaxCount = 0;
var IsHomeFaxCount = 0;
var IsPagerCount = 0;
var IsOtherCount = 0;
var IsCarCount = 0;
var IsAssistantCount = 0;
foreach (var phone in slave.Phonenumbers)
{
switch (phone.Rel)
{
case ContactsRelationships.IsMain:
IsMainCount++;
break;
case ContactsRelationships.IsHome:
IsHomeCount++;
break;
case ContactsRelationships.IsWork:
IsWorkCount++;
break;
case ContactsRelationships.IsMobile:
IsMobileCount++;
break;
case ContactsRelationships.IsWorkFax:
IsWorkFaxCount++;
break;
case ContactsRelationships.IsHomeFax:
IsHomeFaxCount++;
break;
case ContactsRelationships.IsPager:
IsPagerCount++;
break;
case ContactsRelationships.IsOther:
IsOtherCount++;
break;
case ContactsRelationships.IsCar:
IsCarCount++;
break;
case ContactsRelationships.IsAssistant:
IsAssistantCount++;
break;
default:
Logger.Log($"Google contact \"{master.Title}\" has custom phone number labeled \"{phone.Label}\", this phone number is not synchronized with Outlook. Please update contact at Google and change label to standard one.", EventType.Warning);
break;
}
}
if (IsMainCount > 1)
{
Logger.Log($"Google contact \"{slave.Title}\" has {IsMainCount} main phone numbers, Outlook can have only 1 main phone number. You will loose information about additional main phone numbers.", EventType.Warning);
}
if (IsHomeCount > 2)
{
Logger.Log($"Google contact \"{slave.Title}\" has {IsHomeCount} home phone numbers, Outlook can have only 2 home phone numbers. You will loose information about additional home phone numbers.", EventType.Warning);
}
if (IsWorkCount > 2)
{
Logger.Log($"Google contact \"{slave.Title}\" has {IsWorkCount} work phone numbers, Outlook can have only 2 work phone numbers. You will loose information about additional work phone numbers.", EventType.Warning);
}
if (IsMobileCount > 1)
{
Logger.Log($"Google contact \"{slave.Title}\" has {IsMobileCount} mobile phone numbers, Outlook can have only 1 mobile phone number. You will loose information about additional mobile phone numbers.", EventType.Warning);
}
if (IsWorkFaxCount > 1)
{
Logger.Log($"Google contact \"{slave.Title}\" has {IsWorkFaxCount} work fax phone numbers, Outlook can have only 1 work fax phone number. You will loose information about additional work fax phone numbers.", EventType.Warning);
}
if (IsHomeFaxCount > 1)
{
Logger.Log($"Google contact \"{slave.Title}\" has {IsHomeFaxCount} home fax phone numbers, Outlook can have only 1 home fax phone number. You will loose information about additional home fax phone numbers.", EventType.Warning);
}
if (IsPagerCount > 1)
{
Logger.Log($"Google contact \"{slave.Title}\" has {IsPagerCount} pager phone numbers, Outlook can have only 1 pager phone number. You will loose information about additional pager phone numbers.", EventType.Warning);
}
if (IsOtherCount > 1)
{
Logger.Log($"Google contact \"{slave.Title}\" has {IsOtherCount} other phone numbers, Outlook can have only 1 other phone number. You will loose information about additional other phone numbers.", EventType.Warning);
}
if (IsCarCount > 1)
{
Logger.Log($"Google contact \"{slave.Title}\" has {IsCarCount} car phone numbers, Outlook can have only 1 car phone number. You will loose information about additional car phone numbers.", EventType.Warning);
}
if (IsAssistantCount > 1)
{
Logger.Log($"Google contact \"{slave.Title}\" has {IsAssistantCount} assistant phone numbers, Outlook can have only 1 assistant phone number. You will loose information about additional assistant phone numbers.", EventType.Warning);
}
//clear only phone numbers synchronized with Outlook, this will prevent losing Google phones with custom labels
for (var i = slave.Phonenumbers.Count - 1; i >= 0; i--)
{
if (
(slave.Phonenumbers[i].Rel == ContactsRelationships.IsMain) ||
(slave.Phonenumbers[i].Rel == ContactsRelationships.IsMobile) ||
(slave.Phonenumbers[i].Rel == ContactsRelationships.IsHome) ||
(slave.Phonenumbers[i].Rel == ContactsRelationships.IsWork) ||
(slave.Phonenumbers[i].Rel == ContactsRelationships.IsHomeFax) ||
(slave.Phonenumbers[i].Rel == ContactsRelationships.IsWorkFax) ||
(slave.Phonenumbers[i].Rel == ContactsRelationships.IsOther) ||
(slave.Phonenumbers[i].Rel == ContactsRelationships.IsPager) ||
(slave.Phonenumbers[i].Rel == ContactsRelationships.IsCar) ||
(slave.Phonenumbers[i].Rel == ContactsRelationships.IsAssistant)
)
{
slave.Phonenumbers.RemoveAt(i);
}
};
SetPhoneNumber(slave.Phonenumbers, master.PrimaryTelephoneNumber, ContactsRelationships.IsMain);
SetPhoneNumber(slave.Phonenumbers, master.MobileTelephoneNumber, ContactsRelationships.IsMobile);
SetPhoneNumber(slave.Phonenumbers, master.HomeTelephoneNumber, ContactsRelationships.IsHome);
SetPhoneNumber(slave.Phonenumbers, master.Home2TelephoneNumber, ContactsRelationships.IsHome);
SetPhoneNumber(slave.Phonenumbers, master.BusinessTelephoneNumber, ContactsRelationships.IsWork);
SetPhoneNumber(slave.Phonenumbers, master.Business2TelephoneNumber, ContactsRelationships.IsWork);
SetPhoneNumber(slave.Phonenumbers, master.HomeFaxNumber, ContactsRelationships.IsHomeFax);
SetPhoneNumber(slave.Phonenumbers, master.BusinessFaxNumber, ContactsRelationships.IsWorkFax);
SetPhoneNumber(slave.Phonenumbers, master.OtherTelephoneNumber, ContactsRelationships.IsOther);
SetPhoneNumber(slave.Phonenumbers, master.PagerNumber, ContactsRelationships.IsPager);
SetPhoneNumber(slave.Phonenumbers, master.CarTelephoneNumber, ContactsRelationships.IsCar);
SetPhoneNumber(slave.Phonenumbers, master.AssistantTelephoneNumber, ContactsRelationships.IsAssistant);
}
private static void SetPhoneNumber(PhoneNumber phone, Outlook.ContactItem destination)
{
switch (phone.Rel)
{
case ContactsRelationships.IsMain:
destination.PrimaryTelephoneNumber = phone.Value;
break;
case ContactsRelationships.IsHome:
if (destination.HomeTelephoneNumber == null)
{
destination.HomeTelephoneNumber = phone.Value;
}
else
{
destination.Home2TelephoneNumber = phone.Value;
}
break;
case ContactsRelationships.IsWork:
if (destination.BusinessTelephoneNumber == null)
{
destination.BusinessTelephoneNumber = phone.Value;
}
else
{
destination.Business2TelephoneNumber = phone.Value;
}
break;
case ContactsRelationships.IsMobile:
destination.MobileTelephoneNumber = phone.Value;
break;
case ContactsRelationships.IsWorkFax:
destination.BusinessFaxNumber = phone.Value;
break;
case ContactsRelationships.IsHomeFax:
destination.HomeFaxNumber = phone.Value;
break;
case ContactsRelationships.IsPager:
destination.PagerNumber = phone.Value;
break;
case ContactsRelationships.IsOther:
destination.OtherTelephoneNumber = phone.Value;
break;
case ContactsRelationships.IsCar:
destination.CarTelephoneNumber = phone.Value;
break;
case ContactsRelationships.IsAssistant:
destination.AssistantTelephoneNumber = phone.Value;
break;
}
}
private static void SetPhoneNumbers(Contact master, Outlook.ContactItem slave)
{
slave.PrimaryTelephoneNumber = string.Empty;
slave.HomeTelephoneNumber = string.Empty;
slave.Home2TelephoneNumber = string.Empty;
slave.BusinessTelephoneNumber = string.Empty;
slave.Business2TelephoneNumber = string.Empty;
slave.MobileTelephoneNumber = string.Empty;
slave.BusinessFaxNumber = string.Empty;
slave.HomeFaxNumber = string.Empty;
slave.PagerNumber = string.Empty;
slave.OtherTelephoneNumber = string.Empty;
slave.CarTelephoneNumber = string.Empty;
slave.AssistantTelephoneNumber = string.Empty;
var IsMainCount = 0;
var IsHomeCount = 0;
var IsWorkCount = 0;
var IsMobileCount = 0;
var IsWorkFaxCount = 0;
var IsHomeFaxCount = 0;
var IsPagerCount = 0;
var IsOtherCount = 0;
var IsCarCount = 0;
var IsAssistantCount = 0;
foreach (var phone in master.Phonenumbers)
{
switch (phone.Rel)
{
case ContactsRelationships.IsMain:
IsMainCount++;
break;
case ContactsRelationships.IsHome:
IsHomeCount++;
break;
case ContactsRelationships.IsWork:
IsWorkCount++;
break;
case ContactsRelationships.IsMobile:
IsMobileCount++;
break;
case ContactsRelationships.IsWorkFax:
IsWorkFaxCount++;
break;
case ContactsRelationships.IsHomeFax:
IsHomeFaxCount++;
break;
case ContactsRelationships.IsPager:
IsPagerCount++;
break;
case ContactsRelationships.IsOther:
IsOtherCount++;
break;
case ContactsRelationships.IsCar:
IsCarCount++;
break;
case ContactsRelationships.IsAssistant:
IsAssistantCount++;
break;
default:
Logger.Log($"Google contact \"{master.Title}\" has custom phone number labeled \"{phone.Label}\", this phone number is not synchronized with Outlook. Please update contact at Google and change label to standard one.", EventType.Warning);
break;
}
}
if (IsMainCount > 1)
{
Logger.Log($"Google contact \"{master.Title}\" has {IsMainCount} main phone numbers, Outlook can have only 1 main phone number. Please update contact at Google, otherwise you will loose information about additional main phone numbers.", EventType.Warning);
}
if (IsHomeCount > 2)
{
Logger.Log($"Google contact \"{master.Title}\" has {IsHomeCount} home phone numbers, Outlook can have only 2 home phone numbers. Please update contact at Google, otherwise you will loose information about additional home phone numbers.", EventType.Warning);
}
if (IsWorkCount > 2)
{
Logger.Log($"Google contact \"{master.Title}\" has {IsWorkCount} work phone numbers, Outlook can have only 2 work phone numbers. Please update contact at Google, otherwise you will loose information about additional work phone numbers.", EventType.Warning);
}
if (IsMobileCount > 1)
{
Logger.Log($"Google contact \"{master.Title}\" has {IsMobileCount} mobile phone numbers, Outlook can have only 1 mobile phone number. Please update contact at Google, otherwise you will loose information about additional mobile phone numbers.", EventType.Warning);
}
if (IsWorkFaxCount > 1)
{
Logger.Log($"Google contact \"{master.Title}\" has {IsWorkFaxCount} work fax phone numbers, Outlook can have only 1 work fax phone number. Please update contact at Google, otherwise you will loose information about additional work fax phone numbers.", EventType.Warning);
}
if (IsHomeFaxCount > 1)
{
Logger.Log($"Google contact \"{master.Title}\" has {IsHomeFaxCount} home fax phone numbers, Outlook can have only 1 home fax phone number. Please update contact at Google, otherwise you will loose information about additional home fax phone numbers.", EventType.Warning);
}
if (IsPagerCount > 1)
{
Logger.Log($"Google contact \"{master.Title}\" has {IsPagerCount} pager phone numbers, Outlook can have only 1 pager phone number. Please update contact at Google, otherwise you will loose information about additional pager phone numbers.", EventType.Warning);
}
if (IsOtherCount > 1)
{
Logger.Log($"Google contact \"{master.Title}\" has {IsOtherCount} other phone numbers, Outlook can have only 1 other phone number. Please update contact at Google, otherwise you will loose information about additional other phone numbers.", EventType.Warning);
}
if (IsCarCount > 1)
{
Logger.Log($"Google contact \"{master.Title}\" has {IsCarCount} car phone numbers, Outlook can have only 1 car phone number. Please update contact at Google, otherwise you will loose information about additional car phone numbers.", EventType.Warning);
}
if (IsAssistantCount > 1)
{
Logger.Log($"Google contact \"{master.Title}\" has {IsAssistantCount} assistant phone numbers, Outlook can have only 1 assistant phone number. Please update contact at Google, otherwise you will loose information about additional assistant phone numbers.", EventType.Warning);
}
foreach (var phone in master.Phonenumbers)
{
SetPhoneNumber(phone, slave);
}
}
#endregion
#region emails
internal static void SetEmails(Contact master, Outlook.ContactItem slave)
{
if (master.Emails.Count > 3)
{
Logger.Log($"Google contact \"{master.Title}\" has {master.Emails.Count} emails, Outlook can have only 3 emails. Please update contact at Google, otherwise you will loose information about additional emails.", EventType.Warning);
}
if (master.Emails.Count > 0)
{
//only sync, if Email changed
if (slave.Email1Address != master.Emails[0].Address)
{
slave.Email1Address = master.Emails[0].Address;
}
//do not synchronize Gmail outlook label with Outlook email display name as
//in Google label typically has values like "Home", "Work" or "Other",
//but in Outlook email display name is typically set to Full Name
/*
if (!string.IsNullOrEmpty(master.Emails[0].Label) && slave.Email1DisplayName != master.Emails[0].Label)
{//Don't set it to null, because some Handys leave it empty and then Outlook automatically sets (overwrites it)
slave.Email1DisplayName = master.Emails[0].Label; //Unfortunatelly this doesn't work when the email is changes also, because Outlook automatically sets it to default value when the email is changed ==> Call this function again after the first save of Outlook
}
*/
}
else
{
slave.Email1Address = string.Empty;
slave.Email1DisplayName = string.Empty;
}
if (master.Emails.Count > 1)
{
//only sync, if Email changed
if (slave.Email2Address != master.Emails[1].Address)
{
slave.Email2Address = master.Emails[1].Address;
}
//do not synchronize Gmail outlook label with Outlook email display name as
//in Google label typically has values like "Home", "Work" or "Other",
//but in Outlook email display name is typically set to Full Name
/*
if (!string.IsNullOrEmpty(master.Emails[1].Label) && slave.Email2DisplayName != master.Emails[1].Label)
{//Don't set it to null, because some Handys leave it empty and then Outlook automatically sets (overwrites it)
slave.Email2DisplayName = master.Emails[1].Label; //Unfortunatelly this doesn't work when the email is changes also, because Outlook automatically sets it to default value when the email is changed ==> Call this function again after the first save of Outlook
}
*/
}
else
{
slave.Email2Address = string.Empty;
slave.Email2DisplayName = string.Empty;
}
if (master.Emails.Count > 2)
{
//only sync, if Email changed
if (slave.Email3Address != master.Emails[2].Address)
{
slave.Email3Address = master.Emails[2].Address;
}
//do not synchronize Gmail outlook label with Outlook email display name as
//in Google label typically has values like "Home", "Work" or "Other",
//but in Outlook email display name is typically set to Full Name
/*
if (!string.IsNullOrEmpty(master.Emails[2].Label) && slave.Email3DisplayName != master.Emails[2].Label)
{//Don't set it to null, because some Handys leave it empty and then Outlook automatically sets (overwrites it)
slave.Email3DisplayName = master.Emails[2].Label; //Unfortunatelly this doesn't work when the email is changes also, because Outlook automatically sets it to default value when the email is changed ==> Call this function again after the first save of Outlook
}
*/
}
else
{
slave.Email3Address = string.Empty;
slave.Email3DisplayName = string.Empty;
}
}
internal static void SetEmails(Outlook.ContactItem master, Contact slave)
{
var email1 = ContactPropertiesUtils.GetOutlookEmailAddress1(master);
var email2 = ContactPropertiesUtils.GetOutlookEmailAddress2(master);
var email3 = ContactPropertiesUtils.GetOutlookEmailAddress3(master);
var e1 = !string.IsNullOrWhiteSpace(email1);
var e2 = !string.IsNullOrWhiteSpace(email2);
var e3 = !string.IsNullOrWhiteSpace(email3);
if (!e1 && e2)
{
email1 = email2;
e1 = true;
email2 = string.Empty;
e2 = false;
}
if (!e1 && e3)
{
email1 = email3;
e1 = true;
email3 = string.Empty;
e3 = false;
}
if (!e2 && e3)
{
email2 = email3;
e2 = true;
email3 = string.Empty;
e3 = false;
}
if (e1)
{
AddEmail(slave, 0, email1, ContactsRelationships.IsWork);
}
else
{
RemoveEmail(slave, 0);
}
if (e2)
{
AddEmail(slave, 1, email2, ContactsRelationships.IsHome);
}
else
{
RemoveEmail(slave, 1);
}
if (e3)
{
AddEmail(slave, 2, email3, ContactsRelationships.IsOther);
}
else
{
RemoveEmail(slave, 2);
}
}
private static void RemoveEmail(Contact slave, int index)
{
if (slave.Emails.Count > 3)
{
Logger.Log($"Google contact \"{slave.Title}\" has {slave.Emails.Count} emails, Outlook can have only 3 emails. Additional Google emails will be deleted.", EventType.Warning);
}
//clear all emails above index
for (var i = slave.Emails.Count - 1; i >= index; i--)
{
slave.Emails.RemoveAt(i);
};
}
private static void AddEmail(Contact slave, int index, string email, string relationship)
{
if (slave.Emails.Count > index)
{
if (slave.Emails[index].Address != email)
{
slave.Emails[index].Address = email;
}
}
else
{
var e = new EMail(email)
{
Primary = slave.Emails.Count == 0,
Rel = relationship
};
slave.Emails.Add(e);
}
}
#endregion
public static void SetIMs(Outlook.ContactItem source, Contact destination)
{
destination.IMs.Clear();
if (!string.IsNullOrEmpty(source.IMAddress))
{
//IMAddress are expected to be in form of ([Protocol]: [Address]; [Protocol]: [Address])
var imsRaw = source.IMAddress.Split(';');
foreach (var imRaw in imsRaw)
{
var imDetails = imRaw.Trim().Split(':');
var im = new IMAddress();
if (imDetails.Length == 1)
{
im.Address = imDetails[0].Trim();
}
else
{
im.Protocol = imDetails[0].Trim();
im.Address = imDetails[1].Trim();
}
//Only add the im Address if not empty (to avoid Google exception "address" empty)
if (!string.IsNullOrEmpty(im.Address))
{
im.Primary = destination.IMs.Count == 0;
im.Rel = ContactsRelationships.IsHome;
destination.IMs.Add(im);
}
}
}
}
public static void SetCompanies(Outlook.ContactItem source, Contact destination)
{
destination.Organizations.Clear();
if (!string.IsNullOrEmpty(source.Companies))
{
//Companies are expected to be in form of "[Company]; [Company]".
var companiesRaw = source.Companies.Split(';');
foreach (var companyRaw in companiesRaw)
{
var company = new Organization
{
Name = (destination.Organizations.Count == 0) ? source.CompanyName : null,
Title = (destination.Organizations.Count == 0) ? source.JobTitle : null,
Department = (destination.Organizations.Count == 0) ? source.Department : null,
Primary = destination.Organizations.Count == 0,
Rel = ContactsRelationships.IsWork
};
destination.Organizations.Add(company);
}
}
if (destination.Organizations.Count == 0 && (!string.IsNullOrEmpty(source.CompanyName) || !string.IsNullOrEmpty(source.JobTitle) || !string.IsNullOrEmpty(source.Department)))
{
var company = new Organization
{
Name = source.CompanyName,
Title = source.JobTitle,
Department = source.Department,
Primary = true,
Rel = ContactsRelationships.IsWork
};
destination.Organizations.Add(company);
}
}
/// <summary>
/// Updates Google contact from Outlook (but without groups/categories)
/// </summary>
public static void UpdateContact(Outlook.ContactItem master, Contact slave, bool useFileAs)
{
#region Title/FileAs
slave.Title = null;
if (useFileAs)
{
if (!string.IsNullOrEmpty(master.FileAs))
{
slave.Title = master.FileAs;
}
else if (!string.IsNullOrEmpty(master.FullName))
{
slave.Title = master.FullName;
}
else if (!string.IsNullOrEmpty(master.CompanyName))
{
slave.Title = master.CompanyName;
}
else if (!string.IsNullOrEmpty(master.Email1Address))
{
slave.Title = master.Email1Address;
}
}
#endregion Title/FileAs
#region Name
var name = new Name
{
NamePrefix = master.Title,
GivenName = master.FirstName,
AdditionalName = master.MiddleName,
FamilyName = master.LastName,
NameSuffix = master.Suffix
};
//Use the Google's full name to save a unique identifier. When saving the FullName, it always overwrites the Google Title
if (!string.IsNullOrEmpty(master.FullName)) //Only if master.FullName has a value, i.e. not only a company or email contact
{
if (useFileAs)
{
name.FullName = master.FileAs;
}
else
{
name.FullName = OutlookContactInfo.GetTitleFirstLastAndSuffix(master);
if (!string.IsNullOrEmpty(name.FullName))
{
name.FullName = name.FullName.Trim().Replace(" ", " ");
}
}
}
slave.Name = name;
#endregion Name
#region Birthday
try
{
if (master.Birthday.Equals(outlookDateNone)) //earlier also || master.Birthday.Year < 1900
{
slave.ContactEntry.Birthday = null;
}
else
{
slave.ContactEntry.Birthday = master.Birthday.ToString("yyyy-MM-dd");
}
}
catch (Exception ex)
{
Logger.Log("Birthday couldn't be updated from Outlook to Google for '" + master.FileAs + "': " + ex.Message, EventType.Error);
}
#endregion Birthday
slave.ContactEntry.Nickname = master.NickName;
slave.Location = master.OfficeLocation;
//Categories are synced separately in Syncronizer.OverwriteContactGroups: slave.Categories = master.Categories;
slave.ContactEntry.Initials = master.Initials;
slave.Languages.Clear();
if (!string.IsNullOrEmpty(master.Language))
{
foreach (var language in master.Language.Split(';'))
{
var googleLanguage = new Language
{
Label = language
};
slave.Languages.Add(googleLanguage);
}
}
SetEmails(master, slave);
SetAddresses(master, slave);
SetPhoneNumbers(master, slave);
SetCompanies(master, slave);
SetIMs(master, slave);
#region anniversary
//First remove anniversary
foreach (var ev in slave.ContactEntry.Events)
{
if (ev.Relation != null && ev.Relation.Equals(relAnniversary))
{
slave.ContactEntry.Events.Remove(ev);
break;
}
}
try
{
//Then add it again if existing
if (!master.Anniversary.Equals(outlookDateNone)) //earlier also || master.Birthday.Year < 1900
{
var ev = new Event
{
Relation = relAnniversary,
When = new When
{
AllDay = true,
StartTime = master.Anniversary.Date
}
};
slave.ContactEntry.Events.Add(ev);
}
}
catch (Exception ex)
{
Logger.Log("Anniversary couldn't be updated from Outlook to Google for '" + master.FileAs + "': " + ex.Message, EventType.Error);
}
#endregion anniversary
#region relations (spouse, child, manager and assistant)
//First remove spouse, child, manager and assistant
for (var i = slave.ContactEntry.Relations.Count - 1; i >= 0; i--)
{
var rel = slave.ContactEntry.Relations[i];
if (rel.Rel != null && (rel.Rel.Equals(relSpouse) || rel.Rel.Equals(relChild) || rel.Rel.Equals(relManager) || rel.Rel.Equals(relAssistant)))
{
slave.ContactEntry.Relations.RemoveAt(i);
}
}
//Then add spouse again if existing
if (!string.IsNullOrEmpty(master.Spouse))
{
var rel = new Relation
{
Rel = relSpouse,
Value = master.Spouse
};
slave.ContactEntry.Relations.Add(rel);
}
//Then add children again if existing
if (!string.IsNullOrEmpty(master.Children))
{
var rel = new Relation
{
Rel = relChild,
Value = master.Children
};
slave.ContactEntry.Relations.Add(rel);
}
//Then add manager again if existing
if (!string.IsNullOrEmpty(master.ManagerName))
{
var rel = new Relation
{
Rel = relManager,
Value = master.ManagerName
};
slave.ContactEntry.Relations.Add(rel);
}
//Then add assistant again if existing
if (!string.IsNullOrEmpty(master.AssistantName))
{
var rel = new Relation
{
Rel = relAssistant,
Value = master.AssistantName
};
slave.ContactEntry.Relations.Add(rel);
}
#endregion relations (spouse, child, manager and assistant)
#region HomePage
slave.ContactEntry.Websites.Clear();
//Just copy the first URL, because Outlook only has 1
if (!string.IsNullOrEmpty(master.WebPage))
{
var url = new Website
{
Href = master.WebPage,
Rel = relHomePage,
Primary = true
};
slave.ContactEntry.Websites.Add(url);
}
#endregion HomePage
//CH - Fixed error with invalid xml being sent to google... This may need to be added to everything
//slave.Content = String.Format("<![CDATA[{0}]]>", master.Body);
//floriwan: Maybe better to just escape the XML instead of putting it in CDATA, because this causes a CDATA added to all my contacts
if (!string.IsNullOrEmpty(master.Body))
{
slave.Content = System.Security.SecurityElement.Escape(master.Body);
}
else
{
slave.Content = null;
}
}
private enum OutlookFileAsFormat { CannotDetect, CompanyAndFullName, Company, FullNameAndCompany, LastNameAndFirstName, FirstMiddleLastSuffix };
/// <summary>
/// Updates Outlook contact from Google (but without groups/categories)
/// </summary>
public static void UpdateContact(Contact master, Outlook.ContactItem slave, bool useFileAs)
{
//// if no email or number, contact will be updated at each sync
//if (master.Emails.Count == 0 && master.Phonenumbers.Count == 0)
// return;
#region DetectOutlookFileAsFormat
var fmt = OutlookFileAsFormat.CannotDetect;
if (!string.IsNullOrEmpty(slave.FileAs))
{
if (slave.CompanyAndFullName == slave.FileAs)
{
fmt = OutlookFileAsFormat.CompanyAndFullName;
}
else if (slave.FullNameAndCompany == slave.FileAs)
{
fmt = OutlookFileAsFormat.FullNameAndCompany;
}
else if (slave.CompanyName == slave.FileAs)
{
fmt = OutlookFileAsFormat.Company;
}
else if (slave.LastNameAndFirstName == slave.FileAs)
{
fmt = OutlookFileAsFormat.LastNameAndFirstName;
}
else if (slave.Subject == slave.FileAs)
{
fmt = OutlookFileAsFormat.FirstMiddleLastSuffix;
}
}
#endregion DetectOutlookFileAsFormat
#region Name
slave.Title = master.Name.NamePrefix;
slave.FirstName = master.Name.GivenName;
slave.MiddleName = master.Name.AdditionalName;
slave.LastName = master.Name.FamilyName;
slave.Suffix = master.Name.NameSuffix;
if (string.IsNullOrEmpty(slave.FullName)) //The Outlook fullName is automatically set, so don't assign it from Google, unless the structured properties were empty
{
slave.FullName = master.Name.FullName;
}
#endregion Name
#region Title/FileAs
if (fmt == OutlookFileAsFormat.CompanyAndFullName)
{
var s = string.Empty;
if (master.Organizations.Count > 0 && !string.IsNullOrEmpty(master.Organizations[0].Name))
{
s = master.Organizations[0].Name;
}
if (!string.IsNullOrEmpty(master.Name.FamilyName))
{
if (!string.IsNullOrEmpty(s))
{
s = s + "\r\n" + master.Name.FamilyName;
}
else
{
s = master.Name.FamilyName;
}
}
if (!string.IsNullOrEmpty(master.Name.GivenName))
{
if (!string.IsNullOrEmpty(s))
{
if (!string.IsNullOrEmpty(master.Name.FamilyName))
{
s = s + ", " + master.Name.GivenName;
}
else
{
s = s + "\r\n" + master.Name.GivenName;
}
}
else
{
s = master.Name.GivenName;
}
}
if (!string.IsNullOrEmpty(master.Name.AdditionalName))
{
if (!string.IsNullOrEmpty(s))
{
if (!string.IsNullOrEmpty(master.Name.GivenName))
{
s = s + " " + master.Name.AdditionalName;
}
else if (!string.IsNullOrEmpty(master.Name.FamilyName))
{
s = s + " " + master.Name.AdditionalName;
}
}
else
{
s = master.Name.AdditionalName;
}
}
slave.FileAs = s;
}
else if (fmt == OutlookFileAsFormat.Company)
{
if (master.Organizations.Count > 0 && !string.IsNullOrEmpty(master.Organizations[0].Name))
{
slave.FileAs = master.Organizations[0].Name;
}
}
else if (fmt == OutlookFileAsFormat.FullNameAndCompany)
{
var s = string.Empty;
if (!string.IsNullOrEmpty(master.Name.FamilyName))
{
s = master.Name.FamilyName;
}
if (!string.IsNullOrEmpty(master.Name.GivenName))
{
if (!string.IsNullOrEmpty(s))
{
s = s + ", " + master.Name.GivenName;
}
else
{
s = master.Name.GivenName;
}
}
if (!string.IsNullOrEmpty(master.Name.AdditionalName))
{
if (!string.IsNullOrEmpty(s))
{
if (!string.IsNullOrEmpty(master.Name.GivenName))
{
s = s + " " + master.Name.AdditionalName;
}
else if (!string.IsNullOrEmpty(master.Name.FamilyName))
{
s = s + " " + master.Name.AdditionalName;
}
}
else
{
s = master.Name.AdditionalName;
}
}
if (master.Organizations.Count > 0 && !string.IsNullOrEmpty(master.Organizations[0].Name))
{
if (!string.IsNullOrEmpty(s))
{
s = s + "\r\n" + master.Organizations[0].Name;
}
else
{
s = master.Organizations[0].Name;
}
}
slave.FileAs = s;
}
else if (fmt == OutlookFileAsFormat.LastNameAndFirstName)
{
var s = string.Empty;
if (!string.IsNullOrEmpty(master.Name.FamilyName))
{
s = master.Name.FamilyName;
}
if (!string.IsNullOrEmpty(master.Name.GivenName))
{
if (!string.IsNullOrEmpty(s))
{
s = s + ", " + master.Name.GivenName;
}
else
{
s = master.Name.GivenName;
}
}
if (!string.IsNullOrEmpty(master.Name.AdditionalName))
{
if (!string.IsNullOrEmpty(s))
{
if (!string.IsNullOrEmpty(master.Name.GivenName))
{
s = s + " " + master.Name.AdditionalName;
}
else if (!string.IsNullOrEmpty(master.Name.FamilyName))
{
s = s + " " + master.Name.AdditionalName;
}
}
else
{
s = master.Name.AdditionalName;
}
}
slave.FileAs = s;
}
else if (fmt == OutlookFileAsFormat.FirstMiddleLastSuffix)
{
var s = string.Empty;
if (!string.IsNullOrEmpty(master.Name.GivenName))
{
s = master.Name.GivenName;
}
if (!string.IsNullOrEmpty(master.Name.AdditionalName))
{
if (!string.IsNullOrEmpty(s))
{
s = s + " " + master.Name.AdditionalName;
}
else
{
s = master.Name.AdditionalName;
}
}
if (!string.IsNullOrEmpty(master.Name.FamilyName))
{
if (!string.IsNullOrEmpty(s))
{
s = s + " " + master.Name.FamilyName;
}
else
{
s = master.Name.FamilyName;
}
}
slave.FileAs = s;
}
else
{
if (string.IsNullOrEmpty(slave.FileAs) || useFileAs)
{
if (!string.IsNullOrEmpty(master.Name.FullName))
{
slave.FileAs = master.Name.FullName.Replace("\r\n", "\n").Replace("\n", "\r\n"); //Replace twice to not replace a \r\n by \r\r\n. This is necessary because \r\n are saved as \n only to google and \r\n is saved on Outlook side to separate the single parts of the FullName
}
else if (!string.IsNullOrEmpty(master.Title))
{
slave.FileAs = master.Title.Replace("\r\n", "\n").Replace("\n", "\r\n"); //Replace twice to not replace a \r\n by \r\r\n. This is necessary because \r\n are saved as \n only to google and \r\n is saved on Outlook side to separate the single parts of the FullName
}
else if (master.Organizations.Count > 0 && !string.IsNullOrEmpty(master.Organizations[0].Name))
{
slave.FileAs = master.Organizations[0].Name;
}
else if (master.Emails.Count > 0 && !string.IsNullOrEmpty(master.Emails[0].Address))
{
slave.FileAs = master.Emails[0].Address;
}
}
if (string.IsNullOrEmpty(slave.FileAs))
{
if (!string.IsNullOrEmpty(slave.Email1Address))
{
var emailAddress = ContactPropertiesUtils.GetOutlookEmailAddress1(slave);
Logger.Log("Google Contact '" + master.Summary + "' has neither name nor email address. Setting email address of Outlook contact: " + emailAddress, EventType.Warning);
master.Emails.Add(new EMail(emailAddress));
slave.FileAs = master.Emails[0].Address;
}
else
{
Logger.Log("Google Contact '" + master.Summary + "' has neither name nor email address. Cannot merge with Outlook contact: " + slave.FileAs, EventType.Error);
return;
}
}
}
#endregion Title/FileAs
#region birthday
try
{
if (DateTime.TryParse(master.ContactEntry.Birthday, out var birthday))
{
if (birthday != DateTime.MinValue)
{
if (!birthday.Date.Equals(slave.Birthday.Date)) //Only update if not already equal to avoid recreating the calendar item again and again
{
slave.Birthday = birthday.Date;
}
}
else
{
slave.Birthday = outlookDateNone;
}
}
else
{
slave.Birthday = outlookDateNone;
}
}
catch (Exception ex)
{
Logger.Log("Birthday (" + master.ContactEntry.Birthday + ") couldn't be updated from Google to Outlook for '" + slave.FileAs + "': " + ex.Message, EventType.Error);
}
#endregion birthday
slave.NickName = master.ContactEntry.Nickname;
slave.OfficeLocation = master.Location;
//Categories are synced separately in Syncronizer.OverwriteContactGroups: slave.Categories = master.Categories;
slave.Initials = master.ContactEntry.Initials;
if (master.Languages != null)
{
slave.Language = string.Empty;
foreach (var language in master.Languages)
{
slave.Language = language.Label + ";";
}
if (!string.IsNullOrEmpty(slave.Language))
{
slave.Language = slave.Language.TrimEnd(';');
}
}
SetEmails(master, slave);
SetPhoneNumbers(master, slave);
SetAddresses(master, slave);
#region companies
slave.Companies = string.Empty;
slave.CompanyName = string.Empty;
slave.JobTitle = string.Empty;
slave.Department = string.Empty;
foreach (var company in master.Organizations)
{
if (string.IsNullOrEmpty(company.Name) && string.IsNullOrEmpty(company.Title) && string.IsNullOrEmpty(company.Department))
{
continue;
}
if (company.Primary || company.Equals(master.Organizations[0]))
{//Per default copy the first company, but if there is a primary existing, use the primary
slave.CompanyName = company.Name;
slave.JobTitle = company.Title;
slave.Department = company.Department;
}
if (!string.IsNullOrEmpty(slave.Companies))
{
slave.Companies += "; ";
}
slave.Companies += company.Name;
}
#endregion companies
#region IM
slave.IMAddress = string.Empty;
foreach (var im in master.IMs)
{
if (!string.IsNullOrEmpty(slave.IMAddress))
{
slave.IMAddress += "; ";
}
if (!string.IsNullOrEmpty(im.Protocol) && !im.Protocol.Equals("None", StringComparison.InvariantCultureIgnoreCase))
{
slave.IMAddress += im.Protocol + ": " + im.Address;
}
else
{
slave.IMAddress += im.Address;
}
}
#endregion IM
#region anniversary
var found = false;
try
{
foreach (var ev in master.ContactEntry.Events)
{
if (ev.Relation != null && ev.Relation.Equals(relAnniversary))
{
if (!ev.When.StartTime.Date.Equals(slave.Anniversary.Date)) //Only update if not already equal to avoid recreating the calendar item again and again
{
slave.Anniversary = ev.When.StartTime.Date;
}
found = true;
break;
}
}
if (!found)
{
slave.Anniversary = outlookDateNone; //set to empty in the end
}
}
catch (Exception ex)
{
Logger.Log("Anniversary couldn't be updated from Google to Outlook for '" + slave.FileAs + "': " + ex.Message, EventType.Error);
}
#endregion anniversary
#region relations (spouse, child, manager, assistant)
slave.Children = string.Empty;
slave.Spouse = string.Empty;
slave.ManagerName = string.Empty;
slave.AssistantName = string.Empty;
foreach (var rel in master.ContactEntry.Relations)
{
if (rel.Rel != null && rel.Rel.Equals(relChild))
{
slave.Children = rel.Value;
}
else if (rel.Rel != null && rel.Rel.Equals(relSpouse))
{
slave.Spouse = rel.Value;
}
else if (rel.Rel != null && rel.Rel.Equals(relManager))
{
slave.ManagerName = rel.Value;
}
else if (rel.Rel != null && rel.Rel.Equals(relAssistant))
{
slave.AssistantName = rel.Value;
}
}
#endregion relations (spouse, child, manager, assistant)
slave.WebPage = string.Empty;
foreach (var website in master.ContactEntry.Websites)
{
if (website.Primary || website.Equals(master.ContactEntry.Websites[0]))
{//Per default copy the first website, but if there is a primary existing, use the primary
slave.WebPage = master.ContactEntry.Websites[0].Href;
}
}
try
{
string nonRTF;
if (slave.Body == null)
{
nonRTF = string.Empty;
}
else
{
if (slave.RTFBody != null)
{
nonRTF = Utilities.ConvertToText(slave.RTFBody as byte[]);
}
else
{
nonRTF = string.Empty;
}
}
if (!nonRTF.Equals(master.Content))
{
if (string.IsNullOrEmpty(nonRTF) || nonRTF.Equals(slave.Body))
{ //only update, if RTF text is same as plain text and is different between master and slave
slave.Body = master.Content;
}
else
{
if (!Synchronizer.SyncContactsForceRTF)
{
slave.Body = master.Content;
}
else
{
Logger.Log("Outlook contact notes body not updated, because it is RTF, otherwise it will overwrite it by plain text: " + slave.FileAs, EventType.Warning);
}
}
}
}
catch (Exception e)
{
Logger.Log(e, EventType.Debug);
Logger.Log("Error when converting RTF to plain text, updating Google Contact '" + slave.FileAs + "' notes to Outlook without RTF check: " + e.Message, EventType.Debug);
slave.Body = master.Content;
}
}
}
}