mirror of
https://github.com/Kopano-dev/kopano-ol-extension.git
synced 2023-10-10 13:37:40 +02:00
[KOE-116] Added configuration of display names for shared folders
This commit is contained in:
parent
72803ef3cd
commit
09f006273e
@ -457,6 +457,7 @@
|
||||
<Compile Include="Utils\TasksBackground.cs" />
|
||||
<Compile Include="Utils\TasksMainThread.cs" />
|
||||
<Compile Include="Utils\TasksSynchronous.cs" />
|
||||
<Compile Include="ZPush\ContactStringReplacer.cs" />
|
||||
<Compile Include="ZPush\Delegates.cs" />
|
||||
<Compile Include="ZPush\FolderRegistration.cs" />
|
||||
<Compile Include="ZPush\GABUser.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()
|
||||
|
@ -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; } }
|
||||
|
@ -260,7 +260,8 @@ namespace Acacia.Features.SharedFolders
|
||||
}
|
||||
|
||||
// Add the node
|
||||
node = new StoreTreeNode(_folders, user, user.DisplayName, currentShares ?? new Dictionary<BackendId, SharedFolder>());
|
||||
node = new StoreTreeNode(_folders, gabLookup.GAB,
|
||||
user, user.DisplayName, currentShares ?? new Dictionary<BackendId, SharedFolder>());
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,8 @@ namespace Acacia.Features.SharedFolders
|
||||
_query.Dispose();
|
||||
}
|
||||
|
||||
public FeatureSharedFolders Feature { get { return _feature; } }
|
||||
|
||||
#region API
|
||||
|
||||
/// <summary>
|
||||
|
@ -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<BackendId, SharedFolder> _initialShares;
|
||||
private readonly Dictionary<BackendId, SharedFolder> _currentShares;
|
||||
|
||||
public StoreTreeNode(SharedFoldersManager folders, GABUser user, string text, Dictionary<BackendId, SharedFolder> currentFolders)
|
||||
private readonly FeatureSharedFolders _feature;
|
||||
private readonly GABHandler _gab;
|
||||
private readonly GABUser _user;
|
||||
|
||||
public StoreTreeNode(SharedFoldersManager folders, GABHandler gab, GABUser user, string text,
|
||||
Dictionary<BackendId, SharedFolder> 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;
|
||||
}
|
||||
|
@ -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<IContactItem> search = gab.Contacts.Search<IContactItem>())
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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; }
|
||||
|
||||
/// <summary>
|
||||
/// Cache for DefaultName, used by StoreTreeNode.
|
||||
/// </summary>
|
||||
public string DefaultName { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Tree structure
|
||||
|
@ -95,14 +95,14 @@ namespace Acacia.ZPush.API.SharedFolders
|
||||
/// <summary>
|
||||
/// Creates an instances for the specified folder.
|
||||
/// </summary>
|
||||
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
|
||||
};
|
||||
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Replaces placeholders in a string with information from a contact.
|
||||
/// </summary>
|
||||
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<IContactItem> search = gab.Contacts.Search<IContactItem>())
|
||||
{
|
||||
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<IContactItem> search = gab.Contacts.Search<IContactItem>())
|
||||
{
|
||||
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 "";
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user