[KOE-168] Restored send-as editor in shared folder dialog

This commit is contained in:
Patrick Simpson 2018-04-04 15:06:09 +03:00
parent 81f0d0e3f2
commit 607e189b37
20 changed files with 471 additions and 148 deletions

View File

@ -1,7 +1,7 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14 # Visual Studio 14
VisualStudioVersion = 14.0.25123.0 VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AcaciaZPushPlugin", "AcaciaZPushPlugin\AcaciaZPushPlugin.csproj", "{1A7427A5-F814-4B07-98B2-C67D758B65D6}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AcaciaZPushPlugin", "AcaciaZPushPlugin\AcaciaZPushPlugin.csproj", "{1A7427A5-F814-4B07-98B2-C67D758B65D6}"
EndProject EndProject
@ -13,40 +13,56 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EASAccount", "EASAccount\EA
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64 Debug|x64 = Debug|x64
Debug|x86 = Debug|x86 Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64 Release|x64 = Release|x64
Release|x86 = Release|x86 Release|x86 = Release|x86
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1A7427A5-F814-4B07-98B2-C67D758B65D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1A7427A5-F814-4B07-98B2-C67D758B65D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1A7427A5-F814-4B07-98B2-C67D758B65D6}.Debug|x64.ActiveCfg = Debug|Any CPU {1A7427A5-F814-4B07-98B2-C67D758B65D6}.Debug|x64.ActiveCfg = Debug|Any CPU
{1A7427A5-F814-4B07-98B2-C67D758B65D6}.Debug|x64.Build.0 = Debug|Any CPU {1A7427A5-F814-4B07-98B2-C67D758B65D6}.Debug|x64.Build.0 = Debug|Any CPU
{1A7427A5-F814-4B07-98B2-C67D758B65D6}.Debug|x86.ActiveCfg = Debug|Any CPU {1A7427A5-F814-4B07-98B2-C67D758B65D6}.Debug|x86.ActiveCfg = Debug|Any CPU
{1A7427A5-F814-4B07-98B2-C67D758B65D6}.Debug|x86.Build.0 = Debug|Any CPU {1A7427A5-F814-4B07-98B2-C67D758B65D6}.Debug|x86.Build.0 = Debug|Any CPU
{1A7427A5-F814-4B07-98B2-C67D758B65D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1A7427A5-F814-4B07-98B2-C67D758B65D6}.Release|Any CPU.Build.0 = Release|Any CPU
{1A7427A5-F814-4B07-98B2-C67D758B65D6}.Release|x64.ActiveCfg = Release|Any CPU {1A7427A5-F814-4B07-98B2-C67D758B65D6}.Release|x64.ActiveCfg = Release|Any CPU
{1A7427A5-F814-4B07-98B2-C67D758B65D6}.Release|x64.Build.0 = Release|Any CPU {1A7427A5-F814-4B07-98B2-C67D758B65D6}.Release|x64.Build.0 = Release|Any CPU
{1A7427A5-F814-4B07-98B2-C67D758B65D6}.Release|x86.ActiveCfg = Release|Any CPU {1A7427A5-F814-4B07-98B2-C67D758B65D6}.Release|x86.ActiveCfg = Release|Any CPU
{1A7427A5-F814-4B07-98B2-C67D758B65D6}.Release|x86.Build.0 = Release|Any CPU {1A7427A5-F814-4B07-98B2-C67D758B65D6}.Release|x86.Build.0 = Release|Any CPU
{9258AD17-0A25-4669-A95C-93EC70882551}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9258AD17-0A25-4669-A95C-93EC70882551}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9258AD17-0A25-4669-A95C-93EC70882551}.Debug|x64.ActiveCfg = Debug|Any CPU {9258AD17-0A25-4669-A95C-93EC70882551}.Debug|x64.ActiveCfg = Debug|Any CPU
{9258AD17-0A25-4669-A95C-93EC70882551}.Debug|x64.Build.0 = Debug|Any CPU {9258AD17-0A25-4669-A95C-93EC70882551}.Debug|x64.Build.0 = Debug|Any CPU
{9258AD17-0A25-4669-A95C-93EC70882551}.Debug|x86.ActiveCfg = Debug|Any CPU {9258AD17-0A25-4669-A95C-93EC70882551}.Debug|x86.ActiveCfg = Debug|Any CPU
{9258AD17-0A25-4669-A95C-93EC70882551}.Debug|x86.Build.0 = Debug|Any CPU {9258AD17-0A25-4669-A95C-93EC70882551}.Debug|x86.Build.0 = Debug|Any CPU
{9258AD17-0A25-4669-A95C-93EC70882551}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9258AD17-0A25-4669-A95C-93EC70882551}.Release|Any CPU.Build.0 = Release|Any CPU
{9258AD17-0A25-4669-A95C-93EC70882551}.Release|x64.ActiveCfg = Release|Any CPU {9258AD17-0A25-4669-A95C-93EC70882551}.Release|x64.ActiveCfg = Release|Any CPU
{9258AD17-0A25-4669-A95C-93EC70882551}.Release|x64.Build.0 = Release|Any CPU {9258AD17-0A25-4669-A95C-93EC70882551}.Release|x64.Build.0 = Release|Any CPU
{9258AD17-0A25-4669-A95C-93EC70882551}.Release|x86.ActiveCfg = Release|Any CPU {9258AD17-0A25-4669-A95C-93EC70882551}.Release|x86.ActiveCfg = Release|Any CPU
{9258AD17-0A25-4669-A95C-93EC70882551}.Release|x86.Build.0 = Release|Any CPU {9258AD17-0A25-4669-A95C-93EC70882551}.Release|x86.Build.0 = Release|Any CPU
{222C4DA5-FA31-471A-B127-5E0C6AD2CB3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{222C4DA5-FA31-471A-B127-5E0C6AD2CB3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{222C4DA5-FA31-471A-B127-5E0C6AD2CB3C}.Debug|x64.ActiveCfg = Debug|Any CPU {222C4DA5-FA31-471A-B127-5E0C6AD2CB3C}.Debug|x64.ActiveCfg = Debug|Any CPU
{222C4DA5-FA31-471A-B127-5E0C6AD2CB3C}.Debug|x64.Build.0 = Debug|Any CPU {222C4DA5-FA31-471A-B127-5E0C6AD2CB3C}.Debug|x64.Build.0 = Debug|Any CPU
{222C4DA5-FA31-471A-B127-5E0C6AD2CB3C}.Debug|x86.ActiveCfg = Debug|Any CPU {222C4DA5-FA31-471A-B127-5E0C6AD2CB3C}.Debug|x86.ActiveCfg = Debug|Any CPU
{222C4DA5-FA31-471A-B127-5E0C6AD2CB3C}.Debug|x86.Build.0 = Debug|Any CPU {222C4DA5-FA31-471A-B127-5E0C6AD2CB3C}.Debug|x86.Build.0 = Debug|Any CPU
{222C4DA5-FA31-471A-B127-5E0C6AD2CB3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{222C4DA5-FA31-471A-B127-5E0C6AD2CB3C}.Release|Any CPU.Build.0 = Release|Any CPU
{222C4DA5-FA31-471A-B127-5E0C6AD2CB3C}.Release|x64.ActiveCfg = Release|Any CPU {222C4DA5-FA31-471A-B127-5E0C6AD2CB3C}.Release|x64.ActiveCfg = Release|Any CPU
{222C4DA5-FA31-471A-B127-5E0C6AD2CB3C}.Release|x64.Build.0 = Release|Any CPU {222C4DA5-FA31-471A-B127-5E0C6AD2CB3C}.Release|x64.Build.0 = Release|Any CPU
{222C4DA5-FA31-471A-B127-5E0C6AD2CB3C}.Release|x86.ActiveCfg = Release|Any CPU {222C4DA5-FA31-471A-B127-5E0C6AD2CB3C}.Release|x86.ActiveCfg = Release|Any CPU
{222C4DA5-FA31-471A-B127-5E0C6AD2CB3C}.Release|x86.Build.0 = Release|Any CPU {222C4DA5-FA31-471A-B127-5E0C6AD2CB3C}.Release|x86.Build.0 = Release|Any CPU
{437F3764-1E65-4AED-88FA-7C5B2F2FAF15}.Debug|Any CPU.ActiveCfg = Debug|Win32
{437F3764-1E65-4AED-88FA-7C5B2F2FAF15}.Debug|x64.ActiveCfg = Debug|x64 {437F3764-1E65-4AED-88FA-7C5B2F2FAF15}.Debug|x64.ActiveCfg = Debug|x64
{437F3764-1E65-4AED-88FA-7C5B2F2FAF15}.Debug|x64.Build.0 = Debug|x64 {437F3764-1E65-4AED-88FA-7C5B2F2FAF15}.Debug|x64.Build.0 = Debug|x64
{437F3764-1E65-4AED-88FA-7C5B2F2FAF15}.Debug|x86.ActiveCfg = Debug|Win32 {437F3764-1E65-4AED-88FA-7C5B2F2FAF15}.Debug|x86.ActiveCfg = Debug|Win32
{437F3764-1E65-4AED-88FA-7C5B2F2FAF15}.Debug|x86.Build.0 = Debug|Win32 {437F3764-1E65-4AED-88FA-7C5B2F2FAF15}.Debug|x86.Build.0 = Debug|Win32
{437F3764-1E65-4AED-88FA-7C5B2F2FAF15}.Release|Any CPU.ActiveCfg = Release|Win32
{437F3764-1E65-4AED-88FA-7C5B2F2FAF15}.Release|x64.ActiveCfg = Release|x64 {437F3764-1E65-4AED-88FA-7C5B2F2FAF15}.Release|x64.ActiveCfg = Release|x64
{437F3764-1E65-4AED-88FA-7C5B2F2FAF15}.Release|x64.Build.0 = Release|x64 {437F3764-1E65-4AED-88FA-7C5B2F2FAF15}.Release|x64.Build.0 = Release|x64
{437F3764-1E65-4AED-88FA-7C5B2F2FAF15}.Release|x86.ActiveCfg = Release|Win32 {437F3764-1E65-4AED-88FA-7C5B2F2FAF15}.Release|x86.ActiveCfg = Release|Win32

View File

@ -716,7 +716,7 @@
<ManifestKeyFile>AcaciaZPushPlugin_TemporaryKey.pfx</ManifestKeyFile> <ManifestKeyFile>AcaciaZPushPlugin_TemporaryKey.pfx</ManifestKeyFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<ManifestCertificateThumbprint>91DA5A4637DF29EDFBF913FB2B93606C114DE41E</ManifestCertificateThumbprint> <ManifestCertificateThumbprint>06D94ECE2D1D6491E3EC12981F3571DEA7A53421</ManifestCertificateThumbprint>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<SignAssembly>false</SignAssembly> <SignAssembly>false</SignAssembly>
@ -729,7 +729,7 @@
<ProjectExtensions> <ProjectExtensions>
<VisualStudio> <VisualStudio>
<FlavorProperties GUID="{BAA0C2D2-18E2-41B9-852F-F413020CAA33}"> <FlavorProperties GUID="{BAA0C2D2-18E2-41B9-852F-F413020CAA33}">
<ProjectProperties HostName="Outlook" HostPackage="{29A7B9D7-A7F1-4328-8EF0-6B2D1A56B2C1}" OfficeVersion="15.0" VstxVersion="4.0" ApplicationType="Outlook" Language="cs" TemplatesPath="" DebugInfoExeName="#Software\Microsoft\Office\16.0\Outlook\InstallRoot\Path#outlook.exe" AddItemTemplatesGuid="{A58A78EB-1C92-4DDD-80CF-E8BD872ABFC4}" /> <ProjectProperties HostName="Outlook" HostPackage="{29A7B9D7-A7F1-4328-8EF0-6B2D1A56B2C1}" OfficeVersion="16.0" VstxVersion="4.0" ApplicationType="Outlook" Language="cs" TemplatesPath="" DebugInfoExeName="#Software\Microsoft\Office\16.0\Outlook\InstallRoot\Path#outlook.exe" AddItemTemplatesGuid="{A58A78EB-1C92-4DDD-80CF-E8BD872ABFC4}" />
<Host Name="Outlook" GeneratedCodeNamespace="Acacia" IconIndex="0"> <Host Name="Outlook" GeneratedCodeNamespace="Acacia" IconIndex="0">
<HostItem Name="ThisAddIn" Code="ThisAddIn.cs" CanonicalName="AddIn" CanActivate="false" IconIndex="1" Blueprint="ThisAddIn.Designer.xml" GeneratedCode="ThisAddIn.Designer.cs" /> <HostItem Name="ThisAddIn" Code="ThisAddIn.cs" CanonicalName="AddIn" CanActivate="false" IconIndex="1" Blueprint="ThisAddIn.Designer.xml" GeneratedCode="ThisAddIn.Designer.cs" />
</Host> </Host>

View File

@ -180,7 +180,7 @@ namespace Acacia.Features.ReplyFlags
string id = (string)mail.GetProperty(OutlookConstants.PR_ZPUSH_MESSAGE_ID); string id = (string)mail.GetProperty(OutlookConstants.PR_ZPUSH_MESSAGE_ID);
using (IFolder folder = mail.Parent) using (IFolder folder = mail.Parent)
{ {
string folderId = (string)folder.GetProperty(OutlookConstants.PR_ZPUSH_FOLDER_ID); string folderId = (string)folder.GetProperty(OutlookConstants.PR_ZPUSH_SYNC_ID);
string value = ReplyFlags.VerbToExchange(verb) + "/" + id + "/" + folderId; string value = ReplyFlags.VerbToExchange(verb) + "/" + id + "/" + folderId;
Logger.Instance.Trace(this, "Reply header: {0}", value); Logger.Instance.Trace(this, "Reply header: {0}", value);
response.SetProperty(Constants.ZPUSH_REPLY_HEADER, value); response.SetProperty(Constants.ZPUSH_REPLY_HEADER, value);

View File

@ -1,4 +1,4 @@
/// Copyright 2017 Kopano b.v. /// Copyright 2018 Kopano b.v.
/// ///
/// This program is free software: you can redistribute it and/or modify /// This program is free software: you can redistribute it and/or modify
/// it under the terms of the GNU Affero General Public License, version 3, /// it under the terms of the GNU Affero General Public License, version 3,
@ -34,20 +34,12 @@ namespace Acacia.Features.SendAs
{ {
private FeatureSharedFolders _sharedFolders; private FeatureSharedFolders _sharedFolders;
#region Init
public FeatureSendAs() public FeatureSendAs()
{ {
} }
[AcaciaOption("Disables the \"Send As Owner\" feature. This feature allows sending as the owner of a shared folder, " +
"when responding to messages in that folder. Note that this feature requires SharedFolders to be " +
"enabled")]
public bool SendAsOwner
{
get { return GetOption(OPTION_SEND_AS_OWNER); }
set { SetOption(OPTION_SEND_AS_OWNER, value); }
}
private static readonly BoolOption OPTION_SEND_AS_OWNER = new BoolOption("SendAsOwner", true);
public override void Startup() public override void Startup()
{ {
if (MailEvents != null) if (MailEvents != null)
@ -69,48 +61,19 @@ namespace Acacia.Features.SendAs
} }
} }
private void MailEvents_Respond(IMailItem mail, IMailItem response) #endregion
#region Options
[AcaciaOption("Disables the \"Send As Owner\" feature. This feature allows sending as the owner of a shared folder, " +
"when responding to messages in that folder. Note that this feature requires SharedFolders to be " +
"enabled")]
public bool SendAsOwner
{ {
Logger.Instance.Trace(this, "Responding to mail, checking"); get { return GetOption(OPTION_SEND_AS_OWNER); }
using (IStore store = mail.GetStore()) set { SetOption(OPTION_SEND_AS_OWNER, value); }
{
ZPushAccount zpush = Watcher.Accounts.GetAccount(store);
Logger.Instance.Trace(this, "Checking ZPush: {0}", zpush);
if (zpush != null)
{
// Check if the containing folder is a shared folder
using (IFolder parent = mail.Parent)
{
Logger.Instance.Trace(this, "Checking, Parent folder: {0}", parent.Name);
SharedFolder shared = _sharedFolders.GetSharedFolder(parent);
if (shared != null)
Logger.Instance.Trace(this, "Checking, Shared folder: {0}, flags={1}", shared, shared?.Flags);
else
Logger.Instance.Trace(this, "Not a shared folder");
if (shared != null && shared.FlagSendAsOwner)
{
Logger.Instance.Trace(this, "Checking, Shared folder owner: {0}", shared.Store.UserName);
// It's a shared folder, use the owner as the sender if possible
using (IRecipient recip = FindSendAsSender(zpush, shared.Store))
{
if (recip != null && recip.IsResolved)
{
Logger.Instance.Trace(this, "Sending as: {0}", recip.Address);
using (IAddressEntry address = recip.GetAddressEntry())
{
response.SetSender(address);
}
}
else
{
Logger.Instance.Error(this, "Unable to resolve sender: {0}", shared.Store.UserName);
}
}
}
}
}
}
} }
private static readonly BoolOption OPTION_SEND_AS_OWNER = new BoolOption("SendAsOwner", true);
[AcaciaOption("Disables GAB look ups for senders. GAB lookups are required if a username exists on different accounts, " + [AcaciaOption("Disables GAB look ups for senders. GAB lookups are required if a username exists on different accounts, " +
"as in that case Outlook fails to determine the email address of the sender.")] "as in that case Outlook fails to determine the email address of the sender.")]
@ -130,65 +93,48 @@ namespace Acacia.Features.SendAs
} }
private static readonly BoolOption OPTION_RESOLVE_LOCAL = new BoolOption("ResolveLocal", false); private static readonly BoolOption OPTION_RESOLVE_LOCAL = new BoolOption("ResolveLocal", false);
internal IRecipient FindSendAsSender(ZPushAccount zpush, GABUser user) #endregion
#region Event handlers
/// <summary>
/// Responding event handler. Checks if a send-as address must be specified.
/// </summary>
/// <param name="mail"></param>
/// <param name="response"></param>
private void MailEvents_Respond(IMailItem mail, IMailItem response)
{ {
// First try a simple resolve, this will work if the username is unique Logger.Instance.Trace(this, "Responding to mail, checking");
if (ResolveLocal) using (IStore store = mail.GetStore())
{ {
IRecipient recip = ThisAddIn.Instance.ResolveRecipient(user.UserName); /*
if (recip != null) ZPushAccount zpush = Watcher.Accounts.GetAccount(store);
{ Logger.Instance.Trace(this, "Checking ZPush: {0}", zpush);
// If it's resolved, we're good. Otherwise dispose and continue if (zpush == null)
if (recip.IsResolved) return;
{
Logger.Instance.Trace(this, "Resolved send-as: {0}", recip.Name);
return recip;
}
else
{
Logger.Instance.Trace(this, "Unresolved send-as: {0}", user.UserName);
recip.Dispose();
}
}
}
// Search through GAB to find the user // Check if the containing folder is a shared folder
if (GABLookup) using (IFolder parent = mail.Parent)
{ using (IRecipient recip = FindSendAsSender(zpush, parent))
GABHandler handler = FeatureGAB.FindGABForAccount(zpush);
if (handler != null && handler.Contacts != null)
{ {
// Look for the email address. If found, use the account associated with the GAB if (recip == null || !recip.IsResolved)
using (ISearch<IContactItem> search = handler.Contacts.Search<IContactItem>()) return;
{
search.AddField("urn:schemas:contacts:customerid").SetOperation(SearchOperation.Equal, user.UserName);
using (IContactItem result = search.SearchOne())
{
Logger.Instance.Trace(this, "GAB Search for send-as {0}: {1}", zpush, result);
if (result != null)
{
// Try resolving by email
Logger.Instance.Trace(this, "Resolving send-as by email address {0}: {1}", user.UserName, result.Email1Address);
return ThisAddIn.Instance.ResolveRecipient(result.Email1Address);
}
}
}
}
else
{
Logger.Instance.Trace(this, "GAB handler not found for account: {0}", zpush);
}
Logger.Instance.Warning(this, "Unable to resolve send-as: {0}", user.UserName); // Set the sender
return null; Logger.Instance.Trace(this, "Sending as: {0}", recip.Address);
} using (IAddressEntry address = recip.GetAddressEntry())
else {
{ response.SetSender(address);
Logger.Instance.Warning(this, "Unable to resolve send-as and GABLookup disabled: {0}", user.UserName); }
return null; }*/
} }
} }
/// <summary>
/// Sending event handler. Sets the Z-Push header to allow it to determine the send-as sender.
/// </summary>
/// <param name="item"></param>
/// <param name="cancel"></param>
private void MailEvents_ItemSend(IMailItem item, ref bool cancel) private void MailEvents_ItemSend(IMailItem item, ref bool cancel)
{ {
using (IStore store = item.GetStore()) using (IStore store = item.GetStore())
@ -207,5 +153,41 @@ namespace Acacia.Features.SendAs
} }
} }
} }
#endregion
#region Address resolving
public string FindSendAsAddress(ZPushAccount zpush, GABUser user)
{
GABHandler handler = FeatureGAB.FindGABForAccount(zpush);
if (handler != null && handler.Contacts != null)
{
// Look for the email address. If found, use the account associated with the GAB
using (ISearch<IContactItem> search = handler.Contacts.Search<IContactItem>())
{
search.AddField("urn:schemas:contacts:customerid").SetOperation(SearchOperation.Equal, user.UserName);
using (IContactItem result = search.SearchOne())
{
Logger.Instance.Trace(this, "GAB Search for send-as {0}: {1}", zpush, result);
if (result != null)
{
// Try resolving by email
Logger.Instance.Trace(this, "Resolving send-as by email address {0}: {1}", user.UserName, result.Email1Address);
return result.Email1Address;
}
}
}
}
else
{
Logger.Instance.Warning(this, "GAB handler not found for account: {0}", zpush);
}
Logger.Instance.Warning(this, "Unable to resolve send-as: {0}", user.UserName);
return null;
}
#endregion
} }
} }

View File

@ -1,5 +1,6 @@
 
using Acacia.Features.SecondaryContacts; using Acacia.Features.SecondaryContacts;
using Acacia.Features.SendAs;
/// Copyright 2016 Kopano b.v. /// Copyright 2016 Kopano b.v.
/// ///
/// This program is free software: you can redistribute it and/or modify /// This program is free software: you can redistribute it and/or modify
@ -154,6 +155,11 @@ namespace Acacia.Features.SharedFolders
Dictionary<SyncId, SharedFolder> dict = shares.ToDictionary(x => x.SyncId); Dictionary<SyncId, SharedFolder> dict = shares.ToDictionary(x => x.SyncId);
Logger.Instance.Trace(this, "AdditionalFolders_Sync2: {0}", shares.Count); Logger.Instance.Trace(this, "AdditionalFolders_Sync2: {0}", shares.Count);
// Store any send-as properties
FeatureSendAs sendAs = ThisAddIn.Instance.GetFeature<FeatureSendAs>();
// TODO
//sendAs?.UpdateSendAsAddresses(connection.Account, shares);
// Store with the account // Store with the account
connection.Account.SetFeatureData(this, KEY_SHARES, dict); connection.Account.SetFeatureData(this, KEY_SHARES, dict);
} }
@ -191,7 +197,7 @@ namespace Acacia.Features.SharedFolders
public static bool IsSharedFolder(IFolder folder) public static bool IsSharedFolder(IFolder folder)
{ {
string id = (string)folder.GetProperty(OutlookConstants.PR_ZPUSH_FOLDER_ID); string id = (string)folder.GetProperty(OutlookConstants.PR_ZPUSH_SYNC_ID);
return id?.StartsWith("S") == true; return id?.StartsWith("S") == true;
} }
@ -454,6 +460,8 @@ namespace Acacia.Features.SharedFolders
#endregion #endregion
#region Shared stores
public void RemoveSharedStore(ZPushAccount account, GABUser shareUser) public void RemoveSharedStore(ZPushAccount account, GABUser shareUser)
{ {
// Find the store // Find the store
@ -485,5 +493,8 @@ namespace Acacia.Features.SharedFolders
Logger.Instance.Error(this, "Error removing shared store: {0}: {1}", share, e); Logger.Instance.Error(this, "Error removing shared store: {0}: {1}", share, e);
} }
} }
#endregion
} }
} }

View File

@ -45,11 +45,13 @@
this.textName = new System.Windows.Forms.TextBox(); this.textName = new System.Windows.Forms.TextBox();
this._labelSendAs = new System.Windows.Forms.Label(); this._labelSendAs = new System.Windows.Forms.Label();
this.checkSendAs = new System.Windows.Forms.CheckBox(); this.checkSendAs = new System.Windows.Forms.CheckBox();
this._labelSendAsAddress = new System.Windows.Forms.Label();
this.textSendAsAddress = new System.Windows.Forms.TextBox();
this._labelReminders = new System.Windows.Forms.Label(); this._labelReminders = new System.Windows.Forms.Label();
this.checkReminders = new System.Windows.Forms.CheckBox(); this.checkReminders = new System.Windows.Forms.CheckBox();
this._labelPermissions = new System.Windows.Forms.Label(); this._labelPermissions = new System.Windows.Forms.Label();
this.dialogButtons = new Acacia.Controls.KDialogButtons();
this._labelRestartRequired = new System.Windows.Forms.Label(); this._labelRestartRequired = new System.Windows.Forms.Label();
this.dialogButtons = new Acacia.Controls.KDialogButtons();
this._layout.SuspendLayout(); this._layout.SuspendLayout();
this._mainBusyHider.SuspendLayout(); this._mainBusyHider.SuspendLayout();
this._layoutMain.SuspendLayout(); this._layoutMain.SuspendLayout();
@ -137,14 +139,16 @@
resources.ApplyResources(this._layoutOptions, "_layoutOptions"); resources.ApplyResources(this._layoutOptions, "_layoutOptions");
this._layoutOptions.Controls.Add(this._labelWholeStore, 0, 0); this._layoutOptions.Controls.Add(this._labelWholeStore, 0, 0);
this._layoutOptions.Controls.Add(this.checkWholeStore, 1, 0); this._layoutOptions.Controls.Add(this.checkWholeStore, 1, 0);
this._layoutOptions.Controls.Add(this.labelPermissionsValue, 1, 4); this._layoutOptions.Controls.Add(this.labelPermissionsValue, 1, 5);
this._layoutOptions.Controls.Add(this._labelName, 0, 1); this._layoutOptions.Controls.Add(this._labelName, 0, 1);
this._layoutOptions.Controls.Add(this.textName, 1, 1); this._layoutOptions.Controls.Add(this.textName, 1, 1);
this._layoutOptions.Controls.Add(this._labelSendAs, 0, 2); this._layoutOptions.Controls.Add(this._labelSendAs, 0, 2);
this._layoutOptions.Controls.Add(this.checkSendAs, 1, 2); this._layoutOptions.Controls.Add(this.checkSendAs, 1, 2);
this._layoutOptions.Controls.Add(this._labelReminders, 0, 3); this._layoutOptions.Controls.Add(this._labelSendAsAddress, 0, 3);
this._layoutOptions.Controls.Add(this.checkReminders, 1, 3); this._layoutOptions.Controls.Add(this.textSendAsAddress, 1, 3);
this._layoutOptions.Controls.Add(this._labelPermissions, 0, 4); this._layoutOptions.Controls.Add(this._labelReminders, 0, 4);
this._layoutOptions.Controls.Add(this.checkReminders, 1, 4);
this._layoutOptions.Controls.Add(this._labelPermissions, 0, 5);
this._layoutOptions.Controls.Add(this._labelRestartRequired, 2, 0); this._layoutOptions.Controls.Add(this._labelRestartRequired, 2, 0);
this._layoutOptions.Name = "_layoutOptions"; this._layoutOptions.Name = "_layoutOptions";
// //
@ -192,6 +196,18 @@
this.checkSendAs.UseVisualStyleBackColor = true; this.checkSendAs.UseVisualStyleBackColor = true;
this.checkSendAs.CheckedChanged += new System.EventHandler(this.checkSendAs_CheckedChanged); this.checkSendAs.CheckedChanged += new System.EventHandler(this.checkSendAs_CheckedChanged);
// //
// _labelSendAsAddress
//
resources.ApplyResources(this._labelSendAsAddress, "_labelSendAsAddress");
this._labelSendAsAddress.Name = "_labelSendAsAddress";
//
// textSendAsAddress
//
this._layoutOptions.SetColumnSpan(this.textSendAsAddress, 2);
resources.ApplyResources(this.textSendAsAddress, "textSendAsAddress");
this.textSendAsAddress.Name = "textSendAsAddress";
this.textSendAsAddress.TextChanged += new System.EventHandler(this.textSendAsAddress_TextChanged);
//
// _labelReminders // _labelReminders
// //
resources.ApplyResources(this._labelReminders, "_labelReminders"); resources.ApplyResources(this._labelReminders, "_labelReminders");
@ -209,6 +225,11 @@
resources.ApplyResources(this._labelPermissions, "_labelPermissions"); resources.ApplyResources(this._labelPermissions, "_labelPermissions");
this._labelPermissions.Name = "_labelPermissions"; this._labelPermissions.Name = "_labelPermissions";
// //
// _labelRestartRequired
//
resources.ApplyResources(this._labelRestartRequired, "_labelRestartRequired");
this._labelRestartRequired.Name = "_labelRestartRequired";
//
// dialogButtons // dialogButtons
// //
resources.ApplyResources(this.dialogButtons, "dialogButtons"); resources.ApplyResources(this.dialogButtons, "dialogButtons");
@ -219,11 +240,6 @@
this.dialogButtons.Name = "dialogButtons"; this.dialogButtons.Name = "dialogButtons";
this.dialogButtons.Apply += new System.EventHandler(this.dialogButtons_Apply); this.dialogButtons.Apply += new System.EventHandler(this.dialogButtons_Apply);
// //
// _labelRestartRequired
//
resources.ApplyResources(this._labelRestartRequired, "_labelRestartRequired");
this._labelRestartRequired.Name = "_labelRestartRequired";
//
// SharedFoldersDialog // SharedFoldersDialog
// //
resources.ApplyResources(this, "$this"); resources.ApplyResources(this, "$this");
@ -270,5 +286,7 @@
private System.Windows.Forms.CheckBox checkWholeStore; private System.Windows.Forms.CheckBox checkWholeStore;
private System.Windows.Forms.Label labelPermissionsValue; private System.Windows.Forms.Label labelPermissionsValue;
private System.Windows.Forms.Label _labelRestartRequired; private System.Windows.Forms.Label _labelRestartRequired;
private System.Windows.Forms.Label _labelSendAsAddress;
private System.Windows.Forms.TextBox textSendAsAddress;
} }
} }

View File

@ -1,4 +1,4 @@
/// Copyright 2017 Kopano b.v. /// Copyright 2018 Kopano b.v.
/// ///
/// This program is free software: you can redistribute it and/or modify /// This program is free software: you can redistribute it and/or modify
/// it under the terms of the GNU Affero General Public License, version 3, /// it under the terms of the GNU Affero General Public License, version 3,
@ -16,6 +16,7 @@
using Acacia.Controls; using Acacia.Controls;
using Acacia.Features.GAB; using Acacia.Features.GAB;
using Acacia.Features.SendAs;
using Acacia.Stubs; using Acacia.Stubs;
using Acacia.UI; using Acacia.UI;
using Acacia.UI.Outlook; using Acacia.UI.Outlook;
@ -91,6 +92,7 @@ namespace Acacia.Features.SharedFolders
} }
private readonly FeatureSharedFolders _feature; private readonly FeatureSharedFolders _feature;
private readonly FeatureSendAs _featureSendAs;
private readonly ZPushAccount _account; private readonly ZPushAccount _account;
private readonly SharedFoldersManager _folders; private readonly SharedFoldersManager _folders;
private readonly SyncId _initialSyncId; private readonly SyncId _initialSyncId;
@ -107,6 +109,7 @@ namespace Acacia.Features.SharedFolders
} }
this._account = account; this._account = account;
this._feature = feature; this._feature = feature;
this._featureSendAs = ThisAddIn.Instance.GetFeature<FeatureSendAs>();
this._folders = feature.Manage(account); this._folders = feature.Manage(account);
this._initialSyncId = initial; this._initialSyncId = initial;
@ -410,9 +413,12 @@ namespace Acacia.Features.SharedFolders
user = gabLookup.LookupExact(user.UserName); user = gabLookup.LookupExact(user.UserName);
} }
string sendAsAddress = _featureSendAs?.FindSendAsAddress(_account, user);
// Add the node // Add the node
node = new StoreTreeNode(_folders, gabLookup.GAB, node = new StoreTreeNode(_folders, gabLookup.GAB,
user, user.DisplayName, currentShares ?? new Dictionary<BackendId, SharedFolder>(), user, sendAsAddress,
user.DisplayName, currentShares ?? new Dictionary<BackendId, SharedFolder>(),
wholeStore); wholeStore);
node.DirtyChanged += UserSharesChanged; node.DirtyChanged += UserSharesChanged;
node.CheckStateChanged += WholeStoreShareChanged; node.CheckStateChanged += WholeStoreShareChanged;
@ -499,6 +505,7 @@ namespace Acacia.Features.SharedFolders
set set
{ {
_labelSendAs.Visible = checkSendAs.Visible = value != null; _labelSendAs.Visible = checkSendAs.Visible = value != null;
_labelSendAsAddress.Visible = textSendAsAddress.Visible = _labelSendAs.Visible;
if (value != null) if (value != null)
checkSendAs.CheckState = value.Value; checkSendAs.CheckState = value.Value;
} }
@ -719,6 +726,9 @@ namespace Acacia.Features.SharedFolders
OptionSendAs = CheckState.Indeterminate; OptionSendAs = CheckState.Indeterminate;
checkSendAs.ThreeState = true; checkSendAs.ThreeState = true;
} }
TryInitSendAsAddress();
EnableSendAsAddress();
} }
// Reminders shown if any node supports it // Reminders shown if any node supports it
if (_optionRemindersNodes.Count > 0) if (_optionRemindersNodes.Count > 0)
@ -791,6 +801,9 @@ namespace Acacia.Features.SharedFolders
private void checkSendAs_CheckedChanged(object sender, EventArgs e) private void checkSendAs_CheckedChanged(object sender, EventArgs e)
{ {
// Hide the address unless it makes sense
EnableSendAsAddress();
for (int i = 0; i < _optionSendAsNodes.Count; ++i) for (int i = 0; i < _optionSendAsNodes.Count; ++i)
{ {
FolderTreeNode node = _optionSendAsNodes[i]; FolderTreeNode node = _optionSendAsNodes[i];
@ -805,16 +818,74 @@ namespace Acacia.Features.SharedFolders
if (node.SharedFolder.FlagSendAsOwner != sendAs) if (node.SharedFolder.FlagSendAsOwner != sendAs)
{ {
node.SharedFolder = node.SharedFolder.WithFlagSendAsOwner(sendAs); node.SharedFolder = node.SharedFolder.WithFlagSendAsOwner(sendAs);
if (sendAs)
{
TryInitSendAsAddress();
}
// Send-as is applied recursively // Send-as is applied recursively
foreach (FolderTreeNode desc in node.Descendants()) foreach (FolderTreeNode desc in node.Descendants())
{ {
desc.SharedFolder = desc.SharedFolder.WithFlagSendAsOwner(sendAs); if (desc.SharedFolder != null)
{
desc.SharedFolder = desc.SharedFolder.WithFlagSendAsOwner(sendAs);
}
} }
} }
} }
} }
private void TryInitSendAsAddress()
{
string email = null;
/*_featureSendAs?.FindSendAsAddress(_account, null,
_optionSendAsNodes[0].AvailableFolder.BackendId,
_optionSendAsNodes[0].AvailableFolder.Store;)*/
if (email != null)
{
textSendAsAddress.Text = email;
if (!string.IsNullOrEmpty(email) && _optionSendAsNodes[0].IsShared)
{
_optionSendAsNodes[0].SharedFolder.SendAsAddress = email;
}
}
else if (checkSendAs.Checked)
{
// TODO: resource string
MessageBox.Show("Unable to determine the email address for the folder. " +
"Send-as will only work if you specify the email address manually.",
"Shared Folders", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void EnableSendAsAddress()
{
// Hide unless there's only one selected, and send as is enabled
if (_optionSendAsNodes.Count == 1)
{
_labelSendAsAddress.Visible = textSendAsAddress.Visible = true;
_labelSendAsAddress.Enabled = textSendAsAddress.Enabled = OptionSendAs == CheckState.Checked;
}
else
{
_labelSendAsAddress.Visible = textSendAsAddress.Visible = false;
}
}
private void textSendAsAddress_TextChanged(object sender, EventArgs e)
{
for (int i = 0; i < _optionSendAsNodes.Count; ++i)
{
FolderTreeNode node = _optionSendAsNodes[i];
if (node.SharedFolder.SendAsAddress != textSendAsAddress.Text)
{
node.SharedFolder = node.SharedFolder.WithSendAsAddress(textSendAsAddress.Text);
}
}
}
private void checkReminders_CheckedChanged(object sender, EventArgs e) private void checkReminders_CheckedChanged(object sender, EventArgs e)
{ {
for (int i = 0; i < _optionRemindersNodes.Count; ++i) for (int i = 0; i < _optionRemindersNodes.Count; ++i)

View File

@ -283,7 +283,7 @@
<value>3, 38</value> <value>3, 38</value>
</data> </data>
<data name="kTreeFolders.Size" type="System.Drawing.Size, System.Drawing"> <data name="kTreeFolders.Size" type="System.Drawing.Size, System.Drawing">
<value>442, 250</value> <value>442, 224</value>
</data> </data>
<data name="kTreeFolders.TabIndex" type="System.Int32, mscorlib"> <data name="kTreeFolders.TabIndex" type="System.Int32, mscorlib">
<value>1</value> <value>1</value>
@ -394,7 +394,7 @@
<value>NoControl</value> <value>NoControl</value>
</data> </data>
<data name="labelPermissionsValue.Location" type="System.Drawing.Point, System.Drawing"> <data name="labelPermissionsValue.Location" type="System.Drawing.Point, System.Drawing">
<value>99, 107</value> <value>99, 133</value>
</data> </data>
<data name="labelPermissionsValue.Size" type="System.Drawing.Size, System.Drawing"> <data name="labelPermissionsValue.Size" type="System.Drawing.Size, System.Drawing">
<value>346, 20</value> <value>346, 20</value>
@ -543,6 +543,69 @@
<data name="&gt;&gt;checkSendAs.ZOrder" xml:space="preserve"> <data name="&gt;&gt;checkSendAs.ZOrder" xml:space="preserve">
<value>6</value> <value>6</value>
</data> </data>
<data name="_labelSendAsAddress.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="_labelSendAsAddress.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="_labelSendAsAddress.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
<value>NoControl</value>
</data>
<data name="_labelSendAsAddress.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 80</value>
</data>
<data name="_labelSendAsAddress.Size" type="System.Drawing.Size, System.Drawing">
<value>90, 26</value>
</data>
<data name="_labelSendAsAddress.TabIndex" type="System.Int32, mscorlib">
<value>11</value>
</data>
<data name="_labelSendAsAddress.Text" xml:space="preserve">
<value>Send-as address</value>
</data>
<data name="_labelSendAsAddress.TextAlign" type="System.Drawing.ContentAlignment, System.Drawing">
<value>MiddleLeft</value>
</data>
<data name="&gt;&gt;_labelSendAsAddress.Name" xml:space="preserve">
<value>_labelSendAsAddress</value>
</data>
<data name="&gt;&gt;_labelSendAsAddress.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;_labelSendAsAddress.Parent" xml:space="preserve">
<value>_layoutOptions</value>
</data>
<data name="&gt;&gt;_labelSendAsAddress.ZOrder" xml:space="preserve">
<value>7</value>
</data>
<data name="textSendAsAddress.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="textSendAsAddress.Location" type="System.Drawing.Point, System.Drawing">
<value>102, 83</value>
</data>
<data name="textSendAsAddress.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>6, 3, 3, 3</value>
</data>
<data name="textSendAsAddress.Size" type="System.Drawing.Size, System.Drawing">
<value>343, 20</value>
</data>
<data name="textSendAsAddress.TabIndex" type="System.Int32, mscorlib">
<value>12</value>
</data>
<data name="&gt;&gt;textSendAsAddress.Name" xml:space="preserve">
<value>textSendAsAddress</value>
</data>
<data name="&gt;&gt;textSendAsAddress.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;textSendAsAddress.Parent" xml:space="preserve">
<value>_layoutOptions</value>
</data>
<data name="&gt;&gt;textSendAsAddress.ZOrder" xml:space="preserve">
<value>8</value>
</data>
<data name="_labelReminders.AutoSize" type="System.Boolean, mscorlib"> <data name="_labelReminders.AutoSize" type="System.Boolean, mscorlib">
<value>True</value> <value>True</value>
</data> </data>
@ -550,7 +613,7 @@
<value>Fill</value> <value>Fill</value>
</data> </data>
<data name="_labelReminders.Location" type="System.Drawing.Point, System.Drawing"> <data name="_labelReminders.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 80</value> <value>3, 106</value>
</data> </data>
<data name="_labelReminders.Size" type="System.Drawing.Size, System.Drawing"> <data name="_labelReminders.Size" type="System.Drawing.Size, System.Drawing">
<value>90, 27</value> <value>90, 27</value>
@ -574,7 +637,7 @@
<value>_layoutOptions</value> <value>_layoutOptions</value>
</data> </data>
<data name="&gt;&gt;_labelReminders.ZOrder" xml:space="preserve"> <data name="&gt;&gt;_labelReminders.ZOrder" xml:space="preserve">
<value>7</value> <value>9</value>
</data> </data>
<data name="checkReminders.AutoSize" type="System.Boolean, mscorlib"> <data name="checkReminders.AutoSize" type="System.Boolean, mscorlib">
<value>True</value> <value>True</value>
@ -583,7 +646,7 @@
<value>Left</value> <value>Left</value>
</data> </data>
<data name="checkReminders.Location" type="System.Drawing.Point, System.Drawing"> <data name="checkReminders.Location" type="System.Drawing.Point, System.Drawing">
<value>102, 84</value> <value>102, 110</value>
</data> </data>
<data name="checkReminders.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms"> <data name="checkReminders.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>6, 4, 3, 3</value> <value>6, 4, 3, 3</value>
@ -607,7 +670,7 @@
<value>_layoutOptions</value> <value>_layoutOptions</value>
</data> </data>
<data name="&gt;&gt;checkReminders.ZOrder" xml:space="preserve"> <data name="&gt;&gt;checkReminders.ZOrder" xml:space="preserve">
<value>8</value> <value>10</value>
</data> </data>
<data name="_labelPermissions.AutoSize" type="System.Boolean, mscorlib"> <data name="_labelPermissions.AutoSize" type="System.Boolean, mscorlib">
<value>True</value> <value>True</value>
@ -616,7 +679,7 @@
<value>Fill</value> <value>Fill</value>
</data> </data>
<data name="_labelPermissions.Location" type="System.Drawing.Point, System.Drawing"> <data name="_labelPermissions.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 107</value> <value>3, 133</value>
</data> </data>
<data name="_labelPermissions.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms"> <data name="_labelPermissions.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>0, 4, 0, 3</value> <value>0, 4, 0, 3</value>
@ -643,7 +706,7 @@
<value>_layoutOptions</value> <value>_layoutOptions</value>
</data> </data>
<data name="&gt;&gt;_labelPermissions.ZOrder" xml:space="preserve"> <data name="&gt;&gt;_labelPermissions.ZOrder" xml:space="preserve">
<value>9</value> <value>11</value>
</data> </data>
<data name="_labelRestartRequired.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms"> <data name="_labelRestartRequired.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value> <value>Fill</value>
@ -676,22 +739,22 @@
<value>_layoutOptions</value> <value>_layoutOptions</value>
</data> </data>
<data name="&gt;&gt;_labelRestartRequired.ZOrder" xml:space="preserve"> <data name="&gt;&gt;_labelRestartRequired.ZOrder" xml:space="preserve">
<value>10</value> <value>12</value>
</data> </data>
<data name="_layoutOptions.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms"> <data name="_layoutOptions.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value> <value>Fill</value>
</data> </data>
<data name="_layoutOptions.Location" type="System.Drawing.Point, System.Drawing"> <data name="_layoutOptions.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 291</value> <value>0, 265</value>
</data> </data>
<data name="_layoutOptions.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms"> <data name="_layoutOptions.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>0, 0, 0, 0</value> <value>0, 0, 0, 0</value>
</data> </data>
<data name="_layoutOptions.RowCount" type="System.Int32, mscorlib"> <data name="_layoutOptions.RowCount" type="System.Int32, mscorlib">
<value>5</value> <value>6</value>
</data> </data>
<data name="_layoutOptions.Size" type="System.Drawing.Size, System.Drawing"> <data name="_layoutOptions.Size" type="System.Drawing.Size, System.Drawing">
<value>448, 127</value> <value>448, 153</value>
</data> </data>
<data name="_layoutOptions.TabIndex" type="System.Int32, mscorlib"> <data name="_layoutOptions.TabIndex" type="System.Int32, mscorlib">
<value>2</value> <value>2</value>
@ -709,7 +772,7 @@
<value>2</value> <value>2</value>
</data> </data>
<data name="_layoutOptions.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms"> <data name="_layoutOptions.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
<value>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="_labelWholeStore" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="checkWholeStore" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;Control Name="labelPermissionsValue" Row="4" RowSpan="1" Column="1" ColumnSpan="2" /&gt;&lt;Control Name="_labelName" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="textName" Row="1" RowSpan="1" Column="1" ColumnSpan="2" /&gt;&lt;Control Name="_labelSendAs" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="checkSendAs" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;Control Name="_labelReminders" Row="3" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="checkReminders" Row="3" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;Control Name="_labelPermissions" Row="4" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="_labelRestartRequired" Row="0" RowSpan="1" Column="2" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="AutoSize,0,AutoSize,0,Percent,100" /&gt;&lt;Rows Styles="AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,Absolute,20" /&gt;&lt;/TableLayoutSettings&gt;</value> <value>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="_labelWholeStore" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="checkWholeStore" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;Control Name="labelPermissionsValue" Row="5" RowSpan="1" Column="1" ColumnSpan="2" /&gt;&lt;Control Name="_labelName" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="textName" Row="1" RowSpan="1" Column="1" ColumnSpan="2" /&gt;&lt;Control Name="_labelSendAs" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="checkSendAs" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;Control Name="_labelSendAsAddress" Row="3" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="textSendAsAddress" Row="3" RowSpan="1" Column="1" ColumnSpan="2" /&gt;&lt;Control Name="_labelReminders" Row="4" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="checkReminders" Row="4" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;Control Name="_labelPermissions" Row="5" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="_labelRestartRequired" Row="0" RowSpan="1" Column="2" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="AutoSize,0,AutoSize,0,Percent,100" /&gt;&lt;Rows Styles="AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0" /&gt;&lt;/TableLayoutSettings&gt;</value>
</data> </data>
<data name="_layoutMain.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms"> <data name="_layoutMain.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value> <value>Fill</value>

View File

@ -47,6 +47,7 @@ namespace Acacia.Features.SharedFolders
} }
public FeatureSharedFolders Feature { get { return _feature; } } public FeatureSharedFolders Feature { get { return _feature; } }
public ZPushAccount Account { get { return _account; } }
#region API #region API
@ -57,6 +58,17 @@ namespace Acacia.Features.SharedFolders
{ {
// Make sure reminders are updated as soon as possible // Make sure reminders are updated as soon as possible
UpdateReminders(shares); UpdateReminders(shares);
// Store the send-as addresses
foreach (SharedFolder share in shares)
{
if (share.CanSendAs)
{
_account.SetSendAsAddress(share.BackendId, share.FlagSendAsOwner ? share.SendAsAddress : null);
}
}
// Update the shares
_api.SetCurrentShares(store, shares, cancel); _api.SetCurrentShares(store, shares, cancel);
// Commit changes // Commit changes

View File

@ -27,6 +27,8 @@ using Acacia.ZPush.API.SharedFolders;
using Acacia.ZPush.Connect; using Acacia.ZPush.Connect;
using Acacia.Native; using Acacia.Native;
using Acacia.Features.GAB; using Acacia.Features.GAB;
using Acacia.Features.SendAs;
using Acacia.Stubs;
namespace Acacia.Features.SharedFolders namespace Acacia.Features.SharedFolders
{ {
@ -43,8 +45,11 @@ namespace Acacia.Features.SharedFolders
private readonly Dictionary<BackendId, SharedFolder> _currentShares; private readonly Dictionary<BackendId, SharedFolder> _currentShares;
private readonly FeatureSharedFolders _feature; private readonly FeatureSharedFolders _feature;
private readonly FeatureSendAs _featureSendAs;
private readonly ZPushAccount _account;
private readonly GABHandler _gab; private readonly GABHandler _gab;
private readonly GABUser _user; private readonly GABUser _user;
private readonly string _sendAsAddress;
public readonly bool IsReadOnly; public readonly bool IsReadOnly;
@ -61,15 +66,22 @@ namespace Acacia.Features.SharedFolders
} }
} }
public StoreTreeNode(SharedFoldersManager folders, GABHandler gab, GABUser user, string text, public StoreTreeNode(SharedFoldersManager folders, GABHandler gab, GABUser user, string sendAsAddress, string text,
Dictionary<BackendId, SharedFolder> currentFolders, bool isShared) Dictionary<BackendId, SharedFolder> currentFolders, bool isShared)
: :
base(text) base(text)
{ {
this._initialShares = currentFolders; this._initialShares = currentFolders;
// Patch in send as address
foreach (SharedFolder share in _initialShares.Values)
if (share.SendAsAddress == null)
share.SendAsAddress = sendAsAddress;
this._feature = folders.Feature; this._feature = folders.Feature;
this._featureSendAs = ThisAddIn.Instance.GetFeature<FeatureSendAs>();
this._account = folders.Account;
this._gab = gab; this._gab = gab;
this._user = user; this._user = user;
this._sendAsAddress = sendAsAddress;
this.IsReadOnly = false; this.IsReadOnly = false;
this._isShared = isShared; this._isShared = isShared;
@ -155,11 +167,19 @@ namespace Acacia.Features.SharedFolders
private SharedFolder CreateDefaultShare(AvailableFolder folder) private SharedFolder CreateDefaultShare(AvailableFolder folder)
{ {
SharedFolder share = new SharedFolder(folder, DefaultNameForFolder(folder)); SharedFolder share = new SharedFolder(folder, DefaultNameForFolder(folder));
// Default send as for mail folders
if (folder.Type.IsMail())
share = share.WithFlagSendAsOwner(true);
// Default send as for mail folders if the address can be determined
/*using (IRecipient sendAs = _featureSendAs?.FindSendAsSender(_account, null, folder.BackendId, null, _sendAsAddress))
{
if (sendAs != null)
{
share = share.WithFlagSendAsOwner(true).WithSendAsAddress(sendAs.Address);
}
else
{
share = share.WithFlagSendAsOwner(false).WithSendAsAddress(null);
}
}*/
return share; return share;
} }
@ -218,6 +238,8 @@ namespace Acacia.Features.SharedFolders
if (state.FlagUpdateShareName) if (state.FlagUpdateShareName)
state = state.WithName(DefaultNameForFolder(folder)); state = state.WithName(DefaultNameForFolder(folder));
} }
state = state.WithSendAsAddress(_sendAsAddress);
return state; return state;
} }
return null; return null;

View File

@ -501,7 +501,7 @@ namespace Acacia.Features.SyncState
// Check the inbox folder // Check the inbox folder
using (IFolder inbox = account.Account.Store.GetDefaultFolder(DefaultFolder.Inbox)) using (IFolder inbox = account.Account.Store.GetDefaultFolder(DefaultFolder.Inbox))
{ {
string syncId = (string)inbox.GetProperty(OutlookConstants.PR_ZPUSH_SYNC_ID); string syncId = (string)inbox.GetProperty(OutlookConstants.PR_ZPUSH_BACKEND_ID);
// If it's syncing, it's not stalled // If it's syncing, it's not stalled
if (syncId != null && syncId != "0") if (syncId != null && syncId != "0")
@ -515,7 +515,7 @@ namespace Acacia.Features.SyncState
_syncStallLastSyncTime = sync.LastSyncTime; _syncStallLastSyncTime = sync.LastSyncTime;
// Get the sync state // Get the sync state
string folderId = (string)inbox.GetProperty(OutlookConstants.PR_ZPUSH_FOLDER_ID); string folderId = (string)inbox.GetProperty(OutlookConstants.PR_ZPUSH_SYNC_ID);
if (folderId != null) if (folderId != null)
{ {

View File

@ -146,8 +146,8 @@ namespace Acacia
#region EAS / ZPush #region EAS / ZPush
public const string PR_ZPUSH_SYNC_ID = PROP + "6A18" + PT_STRING8; public const string PR_ZPUSH_BACKEND_ID = PROP + "6A18" + PT_STRING8;
public const string PR_ZPUSH_FOLDER_ID = PROP + "6A19" + PT_STRING8; public const string PR_ZPUSH_SYNC_ID = PROP + "6A19" + PT_STRING8;
public const string PR_ZPUSH_MESSAGE_ID = PROP + "6B20" + PT_STRING8; public const string PR_ZPUSH_MESSAGE_ID = PROP + "6B20" + PT_STRING8;
public const string PR_ZPUSH_NAME = PROP + "6915" + PT_UNICODE; public const string PR_ZPUSH_NAME = PROP + "6915" + PT_UNICODE;

View File

@ -102,6 +102,7 @@ namespace Acacia.Stubs
ItemType ItemType { get; } ItemType ItemType { get; }
BackendId BackendId { get; }
SyncId SyncId { get; } SyncId SyncId { get; }
/// <summary> /// <summary>

View File

@ -158,7 +158,10 @@ namespace Acacia.Stubs.OutlookWrappers
{ {
get get
{ {
return RegistryUtil.GetValueString(_regPath, OutlookConstants.REG_VAL_EAS_DEVICEID, null); string devId = RegistryUtil.GetValueString(_regPath, OutlookConstants.REG_VAL_EAS_DEVICEID, null);
if (devId == null)
devId = RegistryUtil.GetValueString(_regPath, OutlookConstants.REG_VAL_EAS_DEVICEID, null);
return devId;
} }
} }
@ -265,6 +268,22 @@ namespace Acacia.Stubs.OutlookWrappers
}); });
} }
public string this[string index]
{
get
{
return RegistryUtil.GetValueString(_regPath, index, null);
}
set
{
if (value == null)
RegistryUtil.RemoveValue(_regPath, index);
else
RegistryUtil.SetValueString(_regPath, index, value);
}
}
#endregion #endregion
public string RegistryBaseKey { get { return _regPath; } } public string RegistryBaseKey { get { return _regPath; } }

View File

@ -119,8 +119,17 @@ namespace Acacia.Stubs.OutlookWrappers
{ {
get get
{ {
string folderId = (string)GetProperty(OutlookConstants.PR_ZPUSH_FOLDER_ID); string syncId = (string)GetProperty(OutlookConstants.PR_ZPUSH_SYNC_ID);
return folderId == null ? null : new SyncId(folderId); return syncId == null ? null : new SyncId(syncId);
}
}
public BackendId BackendId
{
get
{
string backendId = (string)GetProperty(OutlookConstants.PR_ZPUSH_BACKEND_ID);
return backendId == null ? null : new BackendId(backendId);
} }
} }

View File

@ -56,6 +56,29 @@ namespace Acacia.Utils
Registry.SetValue(keyPath, valueName, value); Registry.SetValue(keyPath, valueName, value);
} }
public static void RemoveValue(string keyPath, string valueName)
{
using (RegistryKey key = KeyFromPath(keyPath, true))
{
if (key != null)
{
key.DeleteValue(valueName, false);
}
}
}
private static RegistryKey KeyFromPath(string keyPath, bool writeable)
{
foreach (RegistryKey baseKey in new RegistryKey[] {Registry.CurrentUser, Registry.LocalMachine })
{
if (keyPath.StartsWith(baseKey.Name))
{
return baseKey.OpenSubKey(keyPath.Substring(baseKey.Name.Length + 1), writeable);
}
}
return null;
}
public static string RegToString(object o) public static string RegToString(object o)
{ {
if (o is byte[]) if (o is byte[])

View File

@ -163,7 +163,14 @@ namespace Acacia.ZPush.API.SharedFolders
{ {
SoapData newData = _data; SoapData newData = _data;
newData.flags = flags; newData.flags = flags;
return new SharedFolder(newData); SharedFolder clone = new SharedFolder(newData);
clone.SendAsAddress = SendAsAddress;
return clone;
}
public bool CanSendAs
{
get { return SyncType.IsMail(); }
} }
public bool FlagSendAsOwner { get { return Flags.HasFlag(ShareFlags.SendAsOwner); } } public bool FlagSendAsOwner { get { return Flags.HasFlag(ShareFlags.SendAsOwner); } }
@ -196,6 +203,23 @@ namespace Acacia.ZPush.API.SharedFolders
#endregion #endregion
#region Send as
public string SendAsAddress
{
get;
set;
}
public SharedFolder WithSendAsAddress(string sendAs)
{
SharedFolder clone = new SharedFolder(_data);
clone.SendAsAddress = sendAs;
return clone;
}
#endregion
#region Standard overrides #region Standard overrides
public override int GetHashCode() public override int GetHashCode()
@ -205,7 +229,17 @@ namespace Acacia.ZPush.API.SharedFolders
override public bool Equals(object o) override public bool Equals(object o)
{ {
return o is SharedFolder && _data.Equals(((SharedFolder)o)._data); SharedFolder rhs = o as SharedFolder;
if (rhs == null)
return false;
if (!_data.Equals(rhs._data))
return false;
if (!FlagSendAsOwner)
return true;
return Object.Equals(SendAsAddress, rhs.SendAsAddress);
} }
public override string ToString() public override string ToString()

View File

@ -387,5 +387,31 @@ namespace Acacia.ZPush
} }
#endregion #endregion
#region Send as
private const string PREFIX_SEND_AS = "KOE SendAs ";
public void SetSendAsAddress(BackendId id, string sendAsAddress)
{
RegistryUtil.SetValueString(Account.RegistryBaseKey, PREFIX_SEND_AS + id.ToString(), sendAsAddress);
}
public string GetSendAsAddress(BackendId id)
{
return RegistryUtil.GetValueString(Account.RegistryBaseKey, PREFIX_SEND_AS + id.ToString(), null);
}
public void SetSendAsAddress(SyncId id, string sendAsAddress)
{
RegistryUtil.SetValueString(Account.RegistryBaseKey, PREFIX_SEND_AS + id.ToString(), sendAsAddress);
}
public string GetSendAsAddress(SyncId id)
{
return RegistryUtil.GetValueString(Account.RegistryBaseKey, PREFIX_SEND_AS + id.ToString(), null);
}
#endregion
} }
} }

View File

@ -118,7 +118,23 @@ namespace Acacia.ZPush
{ {
public static readonly BackendId NONE = new BackendId("0"); public static readonly BackendId NONE = new BackendId("0");
public BackendId(string id) : base(id) { } public BackendId(string id)
:
base(StripSuffix(id))
{
}
private static string StripSuffix(string id)
{
// The backend id is of the format {id}num?. Strip off num if present
int index = id.IndexOf('}');
if (index >= 0 && index < id.Length)
{
id = id.Substring(0, index + 1);
}
return id;
}
public BackendId(int id) : base(id) { } public BackendId(int id) : base(id) { }
public BackendId(long id) : base(id.ToString()) { } public BackendId(long id) : base(id.ToString()) { }