diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj
index 3d89561..45fe95a 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj
@@ -457,6 +457,7 @@
+
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/FeatureSharedFolders.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/FeatureSharedFolders.cs
index 9c2755e..7886259 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/FeatureSharedFolders.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/FeatureSharedFolders.cs
@@ -17,6 +17,7 @@ using Acacia.Features.SecondaryContacts;
using Acacia.Stubs;
using Acacia.UI;
using Acacia.UI.Outlook;
+using Acacia.Utils;
using Acacia.ZPush;
using Acacia.ZPush.API.SharedFolders;
using Acacia.ZPush.Connect;
@@ -56,6 +57,13 @@ namespace Acacia.Features.SharedFolders
}
private static readonly BoolOption OPTION_REMINDERS_KEEP_RUNNING = new BoolOption("RemindersKeepRunning", true);
+ [AcaciaOption("The format for local names of shared folders. May contain contact fields and %foldername%.")]
+ public string DefaultFolderNameFormat
+ {
+ get { return RegistryUtil.GetConfigValue("SharedFolders", "DefaultFolderNameFormat", "%foldername% - %username%"); }
+ set { RegistryUtil.SetConfigValue("SharedFolders", "DefaultFolderNameFormat", value, Microsoft.Win32.RegistryValueKind.String); }
+ }
+
#endregion
public override void Startup()
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/FolderTreeNode.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/FolderTreeNode.cs
index a20a1fa..16c3230 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/FolderTreeNode.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/FolderTreeNode.cs
@@ -58,6 +58,14 @@ namespace Acacia.Features.SharedFolders
base.OnCheckStateChanged();
}
+ public string DefaultName
+ {
+ get
+ {
+ return _store.DefaultNameForFolder(AvailableFolder);
+ }
+ }
+
public AvailableFolder AvailableFolder { get { return _folder; } }
public bool IsShared { get { return CheckState != System.Windows.Forms.CheckState.Unchecked; } }
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.cs
index a39422f..9d0f93d 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.cs
@@ -260,7 +260,8 @@ namespace Acacia.Features.SharedFolders
}
// Add the node
- node = new StoreTreeNode(_folders, user, user.DisplayName, currentShares ?? new Dictionary());
+ node = new StoreTreeNode(_folders, gabLookup.GAB,
+ user, user.DisplayName, currentShares ?? new Dictionary());
node.DirtyChanged += UserSharesChanged;
_userFolders.Add(user, node);
kTreeFolders.RootNodes.Add(node);
@@ -524,7 +525,7 @@ namespace Acacia.Features.SharedFolders
_optionNameNode.SharedFolder = _optionNameNode.SharedFolder.WithName(textName.Text);
// If the share name matches the folder name, track update
- bool track = _optionNameNode.SharedFolder.Name == _optionNameNode.AvailableFolder.DefaultName;
+ bool track = _optionNameNode.SharedFolder.Name == _optionNameNode.DefaultName;
_optionNameNode.SharedFolder = _optionNameNode.SharedFolder.WithFlagTrackShareName(track);
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersManager.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersManager.cs
index e87fc3e..adbe510 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersManager.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersManager.cs
@@ -41,6 +41,8 @@ namespace Acacia.Features.SharedFolders
_query.Dispose();
}
+ public FeatureSharedFolders Feature { get { return _feature; } }
+
#region API
///
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/StoreTreeNode.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/StoreTreeNode.cs
index 1b236c9..d0e3c39 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/StoreTreeNode.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/StoreTreeNode.cs
@@ -26,6 +26,7 @@ using System.Threading;
using Acacia.ZPush.API.SharedFolders;
using Acacia.ZPush.Connect;
using Acacia.Native;
+using Acacia.Features.GAB;
namespace Acacia.Features.SharedFolders
{
@@ -41,11 +42,19 @@ namespace Acacia.Features.SharedFolders
private readonly Dictionary _initialShares;
private readonly Dictionary _currentShares;
- public StoreTreeNode(SharedFoldersManager folders, GABUser user, string text, Dictionary currentFolders)
+ private readonly FeatureSharedFolders _feature;
+ private readonly GABHandler _gab;
+ private readonly GABUser _user;
+
+ public StoreTreeNode(SharedFoldersManager folders, GABHandler gab, GABUser user, string text,
+ Dictionary currentFolders)
:
base(text)
{
this._initialShares = currentFolders;
+ this._feature = folders.Feature;
+ this._gab = gab;
+ this._user = user;
// Create an empty current state. When loading the nodes, the shares will be added. This has the benefit of
// cleaning up automatically any obsolote shares.
@@ -92,7 +101,7 @@ namespace Acacia.Features.SharedFolders
private SharedFolder CreateDefaultShare(AvailableFolder folder)
{
- SharedFolder share = new SharedFolder(folder);
+ SharedFolder share = new SharedFolder(folder, DefaultNameForFolder(folder));
// Default send as for mail folders
if (folder.Type.IsMail())
@@ -109,16 +118,44 @@ namespace Acacia.Features.SharedFolders
}
}
+ internal string DefaultNameForFolder(AvailableFolder folder)
+ {
+ // Default include the store name in root folders
+ if (folder.ParentId.IsNone)
+ {
+ if (folder.DefaultName == null)
+ {
+ using (ContactStringReplacer replacer = ContactStringReplacer.FromGAB(_gab, _user))
+ {
+ replacer.TokenOpen = "%";
+ replacer.TokenClose = "%";
+ replacer.UnknownReplacer = (token) =>
+ {
+ if (token == "foldername")
+ return folder.Name;
+ return "";
+ };
+ folder.DefaultName = replacer.Replace(_feature.DefaultFolderNameFormat);
+ }
+ }
+ return folder.DefaultName;
+ }
+ else
+ {
+ return folder.Name;
+ }
+ }
+
private SharedFolder GetInitialShareState(AvailableFolder folder)
{
SharedFolder state;
if (_initialShares.TryGetValue(folder.BackendId, out state))
{
// If the folder has been renamed, update if we're tracing it.
- if (state.Name != folder.DefaultName)
+ if (state.Name != DefaultNameForFolder(folder))
{
if (state.FlagUpdateShareName)
- state = state.WithName(folder.DefaultName);
+ state = state.WithName(DefaultNameForFolder(folder));
}
return state;
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/Signatures/FeatureSignatures.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/Signatures/FeatureSignatures.cs
index ffdf610..e2c0576 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/Signatures/FeatureSignatures.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/Signatures/FeatureSignatures.cs
@@ -295,27 +295,16 @@ namespace Acacia.Features.Signatures
}
private void ReplacePlaceholders(GABHandler gab, params string[] signatures)
- {
- IContactItem us = null;
+ {
+ ContactStringReplacer replacer = null;
try
{
- IAccount account = gab.ActiveAccount.Account;
-
- // Look for the email address. If found, use the account associated with the GAB
- using (ISearch search = gab.Contacts.Search())
- {
- search.AddField("urn:schemas:contacts:customerid").SetOperation(SearchOperation.Equal, account.UserName);
- IItem result = search.SearchOne();
- us = result as IContactItem;
- if (result != null && result != us)
- result.Dispose();
- }
-
- if (us != null)
+ replacer = ContactStringReplacer.FindUs(gab);
+ if (replacer != null)
{
foreach (string signatureName in signatures)
{
- ReplacePlaceholders(gab.ActiveAccount, us, signatureName);
+ ReplacePlaceholders(replacer, signatureName);
}
}
}
@@ -325,12 +314,12 @@ namespace Acacia.Features.Signatures
}
finally
{
- if (us != null)
- us.Dispose();
+ if (replacer != null)
+ replacer.Dispose();
}
}
- private void ReplacePlaceholders(ZPushAccount account, IContactItem us, string signatureName)
+ private void ReplacePlaceholders(ContactStringReplacer replacer, string signatureName)
{
if (string.IsNullOrEmpty(signatureName))
return;
@@ -347,35 +336,7 @@ namespace Acacia.Features.Signatures
string template = signature.GetContentTemplate(format);
if (template != null)
{
- string replaced = template.ReplaceStringTokens("{%", "}", (token) =>
- {
- // TODO: generalise this
- if (token == "firstname") return us.FirstName ?? "";
- if (token == "initials") return us.Initials ?? "";
- if (token == "lastname") return us.LastName ?? "";
- if (token == "displayname") return us.FullName ?? "";
- if (token == "title") return us.JobTitle ?? "";
- if (token == "company") return us.CompanyName ?? "";
- // TODO if (token == "department") return us.;
- if (token == "office") return us.OfficeLocation ?? "";
- // if (token == "assistant") return us.;
- if (token == "phone") return us.BusinessTelephoneNumber ?? us.MobileTelephoneNumber ?? "";
- if (token == "primary_email") return us.Email1Address ?? "";
- if (token == "address") return us.BusinessAddress ?? "";
- if (token == "city") return us.BusinessAddressCity ?? "";
- if (token == "state") return us.BusinessAddressState ?? "";
- if (token == "zipcode") return us.BusinessAddressPostalCode ?? "";
- if (token == "country") return us.BusinessAddressState ?? "";
- if (token == "phone_business") return us.BusinessTelephoneNumber ?? "";
- // TODO if (token == "phone_business2") return us.BusinessTelephoneNumber;
- if (token == "phone_fax") return us.BusinessFaxNumber ?? "";
- // TODO if (token == "phone_assistant") return us.FirstName;
- if (token == "phone_home") return us.HomeTelephoneNumber ?? "";
- //if (token == "phone_home2") return us.HomeTelephoneNumber;
- if (token == "phone_mobile") return us.MobileTelephoneNumber ?? "";
- if (token == "phone_pager") return us.PagerNumber ?? "";
- return "";
- });
+ string replaced = replacer.Replace(template);
signature.SetContent(replaced, format);
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/API/SharedFolders/AvailableFolder.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/API/SharedFolders/AvailableFolder.cs
index 89daed6..5e3d779 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/API/SharedFolders/AvailableFolder.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/API/SharedFolders/AvailableFolder.cs
@@ -78,22 +78,15 @@ namespace Acacia.ZPush.API.SharedFolders
public string Name { get { return _data.displayname; } }
- public string DefaultName
- {
- get
- {
- // Default include the store name in root folders
- if (ParentId.IsNone)
- return Name + " - " + Store.UserName;
- else
- return Name;
- }
- }
-
public OutlookConstants.SyncType Type { get { return _data.type; } }
public GABUser Store { get; private set; }
+ ///
+ /// Cache for DefaultName, used by StoreTreeNode.
+ ///
+ public string DefaultName { get; set; }
+
#endregion
#region Tree structure
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/API/SharedFolders/SharedFolder.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/API/SharedFolders/SharedFolder.cs
index c74521a..c7fa0ca 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/API/SharedFolders/SharedFolder.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/API/SharedFolders/SharedFolder.cs
@@ -95,14 +95,14 @@ namespace Acacia.ZPush.API.SharedFolders
///
/// Creates an instances for the specified folder.
///
- public SharedFolder(AvailableFolder folder)
+ public SharedFolder(AvailableFolder folder, string name)
{
_data = new SoapData()
{
store = folder.Store.UserName,
folderid = folder.BackendId,
parentid = folder.ParentIdAsBackend,
- name = folder.DefaultName,
+ name = name,
type = OutlookConstants.USER_SYNC_TYPES[(int)folder.Type],
flags = folder.Type.IsMail() ? ShareFlags.SendAsOwner : ShareFlags.None
};
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ContactStringReplacer.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ContactStringReplacer.cs
new file mode 100644
index 0000000..1c4e6de
--- /dev/null
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ContactStringReplacer.cs
@@ -0,0 +1,127 @@
+using Acacia.Features.GAB;
+using Acacia.Stubs;
+using Acacia.Utils;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Acacia.ZPush
+{
+ ///
+ /// Replaces placeholders in a string with information from a contact.
+ ///
+ public class ContactStringReplacer
+ :
+ IDisposable
+ {
+ private readonly IContactItem _contact;
+
+ public string TokenOpen
+ {
+ get;
+ set;
+ }
+
+ public string TokenClose
+ {
+ get;
+ set;
+ }
+
+ public delegate string TokenReplacer(string token);
+
+ public TokenReplacer UnknownReplacer
+ {
+ get;
+ set;
+ }
+
+ public ContactStringReplacer(IContactItem contact)
+ {
+ this._contact = contact;
+ TokenOpen = "{%";
+ TokenClose = "}";
+ }
+
+ public static ContactStringReplacer FindUs(GABHandler gab)
+ {
+ // Look for the email address. If found, use the account associated with the GAB
+ using (ISearch search = gab.Contacts.Search())
+ {
+ IAccount account = gab.ActiveAccount.Account;
+
+ search.AddField("urn:schemas:contacts:customerid").SetOperation(SearchOperation.Equal, account.UserName);
+ IItem result = search.SearchOne();
+ IContactItem us = result as IContactItem;
+ if (result != null && result != us)
+ {
+ result.Dispose();
+ return null;
+ }
+
+ if (us == null)
+ return null;
+
+ return new ContactStringReplacer(us);
+ }
+ }
+
+ public static ContactStringReplacer FromGAB(GABHandler gab, GABUser user)
+ {
+ using (ISearch search = gab.Contacts.Search())
+ {
+ search.AddField("urn:schemas:contacts:customerid").SetOperation(SearchOperation.Equal, user.UserName);
+ IItem result = search.SearchOne();
+ IContactItem contact = result as IContactItem;
+ if (result != null && result != contact)
+ result.Dispose();
+
+ return new ContactStringReplacer(contact);
+ }
+
+ }
+
+ public void Dispose()
+ {
+ _contact.Dispose();
+ }
+
+ public string Replace(string template)
+ {
+ string replaced = template.ReplaceStringTokens(TokenOpen, TokenClose, (token) =>
+ {
+ if (token == "firstname") return _contact.FirstName ?? "";
+ if (token == "initials") return _contact.Initials ?? "";
+ if (token == "lastname") return _contact.LastName ?? "";
+ if (token == "displayname") return _contact.FullName ?? "";
+ if (token == "username") return _contact.CustomerID ?? "";
+ if (token == "title") return _contact.JobTitle ?? "";
+ if (token == "company") return _contact.CompanyName ?? "";
+ if (token == "office") return _contact.OfficeLocation ?? "";
+ if (token == "phone") return _contact.BusinessTelephoneNumber ?? _contact.MobileTelephoneNumber ?? "";
+ if (token == "primary_email") return _contact.Email1Address ?? "";
+ if (token == "address") return _contact.BusinessAddress ?? "";
+ if (token == "city") return _contact.BusinessAddressCity ?? "";
+ if (token == "state") return _contact.BusinessAddressState ?? "";
+ if (token == "zipcode") return _contact.BusinessAddressPostalCode ?? "";
+ if (token == "country") return _contact.BusinessAddressState ?? "";
+ if (token == "phone_business") return _contact.BusinessTelephoneNumber ?? "";
+ if (token == "phone_fax") return _contact.BusinessFaxNumber ?? "";
+ if (token == "phone_home") return _contact.HomeTelephoneNumber ?? "";
+ if (token == "phone_mobile") return _contact.MobileTelephoneNumber ?? "";
+ if (token == "phone_pager") return _contact.PagerNumber ?? "";
+ return GetUnknownToken(token);
+ });
+ return replaced;
+ }
+
+ private string GetUnknownToken(string token)
+ {
+ if (UnknownReplacer != null)
+ return UnknownReplacer(token);
+ return "";
+ }
+ }
+}