Merge remote-tracking branch 'origin/master'

This commit is contained in:
Weblate 2017-02-27 13:58:01 +01:00
commit bac6b37807
19 changed files with 749 additions and 73 deletions

View File

@ -275,6 +275,12 @@
<Compile Include="Features\SendAs\FeatureSendAs.cs" />
<Compile Include="Features\SharedFolders\FolderTreeNode.cs" />
<Compile Include="Features\Signatures\FeatureSignatures.cs" />
<Compile Include="Features\Signatures\SignaturesSettings.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Features\Signatures\SignaturesSettings.Designer.cs">
<DependentUpon>SignaturesSettings.cs</DependentUpon>
</Compile>
<Compile Include="GlobalOptions.cs" />
<Compile Include="Logging.cs" />
<Compile Include="Native\IOleWindow.cs" />
@ -549,6 +555,9 @@
<EmbeddedResource Include="Features\SharedFolders\SharedFoldersDialog.resx">
<DependentUpon>SharedFoldersDialog.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Features\Signatures\SignaturesSettings.resx">
<DependentUpon>SignaturesSettings.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>

View File

@ -301,6 +301,17 @@ namespace Acacia.Features.SharedFolders
textName.Text = value ?? "";
}
}
private bool? OptionTrackName
{
get { return textName.Visible ? !_labelName.Enabled : (bool?)null; }
set
{
if (value != null)
{
_labelName.Enabled = !value.Value;
}
}
}
private FolderTreeNode _optionNameNode;
private CheckState? OptionSendAs
@ -367,6 +378,7 @@ namespace Acacia.Features.SharedFolders
_optionSendAsInitial.Clear();
_optionPermissionNodes.Clear();
OptionName = null;
OptionTrackName = null;
OptionSendAs = null;
OptionPermissions = null;
@ -406,6 +418,7 @@ namespace Acacia.Features.SharedFolders
if (_optionNameNode != null && nodes.Length == 1)
{
OptionName = _optionNameNode.SharedFolder.Name;
OptionTrackName = _optionNameNode.SharedFolder.FlagUpdateShareName;
}
else
{
@ -461,6 +474,10 @@ namespace Acacia.Features.SharedFolders
if (_optionNameNode != null)
{
_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;
_optionNameNode.SharedFolder = _optionNameNode.SharedFolder.WithFlagUpdateShareName(track);
}
}

View File

@ -85,7 +85,7 @@ namespace Acacia.Features.SharedFolders
internal SharedFolder AddShare(AvailableFolder folder, SharedFolder state)
{
state = state ?? CreateDefaultShare(folder);
_currentShares[folder.BackendId] = state;
_currentShares[folder.BackendId] = state.PatchInformation(folder);
CheckDirty();
return state;
}
@ -98,10 +98,6 @@ namespace Acacia.Features.SharedFolders
if (folder.IsMailFolder)
share = share.WithFlagSendAsOwner(true);
// Default include the store name in root folders
if (folder.ParentId.IsNone)
share = share.WithName(folder.Name + " - " + folder.Store.UserName);
return share;
}
@ -118,6 +114,12 @@ namespace Acacia.Features.SharedFolders
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.FlagUpdateShareName)
state = state.WithName(folder.DefaultName);
}
return state;
}
return null;

View File

@ -17,6 +17,7 @@ using Acacia.Features.GAB;
/// Consult LICENSE file for details
using Acacia.Stubs;
using Acacia.Stubs.OutlookWrappers;
using Acacia.UI;
using Acacia.Utils;
using Acacia.ZPush;
using Acacia.ZPush.Connect;
@ -39,6 +40,15 @@ namespace Acacia.Features.Signatures
{
#region Debug options
[AcaciaOption("If set, the local signature is always set to the server signature. If not set, the local signature will be set " +
"only if it is unspecified. ")]
public bool AlwaysSetLocal
{
get { return GetOption(OPTION_ALWAYS_SET_LOCAL); }
set { SetOption(OPTION_ALWAYS_SET_LOCAL, value); }
}
private static readonly BoolOption OPTION_ALWAYS_SET_LOCAL = new BoolOption("AlwaysSetLocal", false);
[AcaciaOption("The format for local names of synchronised signatures, to prevent overwriting local signatures. May contain %account% and %name%.")]
public string SignatureLocalName
{
@ -59,6 +69,7 @@ namespace Acacia.Features.Signatures
{
_gab.SyncFinished += GAB_SyncFinished;
}
Watcher.Sync.AddTask(this, Name, Periodic_Sync);
}
private void Watcher_AccountDiscovered(ZPushAccount account)
@ -70,32 +81,76 @@ namespace Acacia.Features.Signatures
{
// TODO: make a helper to register for all zpush accounts with specific capabilities, best even
// the feature's capabilities
if (account.Confirmed == ZPushAccount.ConfirmationType.IsZPush &&
account.Capabilities.Has("signatures"))
if (account.Confirmed == ZPushAccount.ConfirmationType.IsZPush)
{
Logger.Instance.Trace(this, "Checking signature hash for account {0}: {1}", account, account.ServerSignaturesHash);
SyncSignatures(account, account.ServerSignaturesHash);
}
}
// Fetch signatures if there is a change
if (account.ServerSignaturesHash != account.Account.LocalSignaturesHash)
private void Periodic_Sync(ZPushConnection connection)
{
try
{
// TODO: merge this into ZPushAccount, allow periodic rechecking of Z-Push confirmation. That was other
// features can be updated too, e.g. OOF status. That's pretty easy to do, only need to check if
// no other features will break if the ConfirmedChanged event is raised multiple times
ActiveSync.SettingsOOF oof = connection.Execute(new ActiveSync.SettingsOOFGet());
SyncSignatures(connection.Account, oof.RawResponse.SignaturesHash);
}
catch(System.Exception e)
{
Logger.Instance.Error(this, "Error fetching signature hash: {0}", e);
}
}
internal void ResyncAll()
{
foreach(ZPushAccount account in Watcher.Accounts.GetAccounts())
{
if (account.Confirmed == ZPushAccount.ConfirmationType.IsZPush)
{
try
{
Logger.Instance.Debug(this, "Updating signatures: {0}", account);
FetchSignatures(account);
// Store updated hash
account.Account.LocalSignaturesHash = account.ServerSignaturesHash;
Logger.Instance.Debug(this, "Updated signatures: {0}", account);
}
catch (Exception e)
{
Logger.Instance.Error(this, "Error fetching signatures: {0}: {1}", account, e);
}
SyncSignatures(account, null);
}
}
}
/// <summary>
/// Syncs the signatures for the account.
/// </summary>
/// <param name="account">The account</param>
/// <param name="serverSignatureHash">The signature hash. If null, the hash will not be checked and a hard sync will be done.</param>
private void SyncSignatures(ZPushAccount account, string serverSignatureHash)
{
if (!account.Capabilities.Has("signatures"))
return;
// Check hash if needed
if (serverSignatureHash != null)
{
Logger.Instance.Trace(this, "Checking signature hash for account {0}: {1}", account, serverSignatureHash);
if (serverSignatureHash == account.Account.LocalSignaturesHash)
return;
}
// Fetch signatures if there is a change
try
{
Logger.Instance.Debug(this, "Updating signatures: {0}", account);
string hash = FetchSignatures(account);
// Store updated hash
account.Account.LocalSignaturesHash = hash;
Logger.Instance.Debug(this, "Updated signatures: {0}: {1}", account, hash);
}
catch (Exception e)
{
Logger.Instance.Error(this, "Error fetching signatures: {0}: {1}", account, e);
}
}
#region API
// Prevent field assignment warnings
#pragma warning disable 0649
@ -121,7 +176,12 @@ namespace Acacia.Features.Signatures
{
}
private void FetchSignatures(ZPushAccount account)
/// <summary>
/// Fetches the signatures for the account.
/// </summary>
/// <param name="account">The account.</param>
/// <returns>The signature hash</returns>
private string FetchSignatures(ZPushAccount account)
{
Logger.Instance.Debug(this, "Fetching signatures for account {0}", account);
using (ZPushConnection connection = account.Connect())
@ -141,17 +201,27 @@ namespace Acacia.Features.Signatures
}
// Set default signatures if available and none are set
if (!string.IsNullOrEmpty(result.new_message) && string.IsNullOrEmpty(account.Account.SignatureNewMessage))
if (!string.IsNullOrEmpty(result.new_message) && ShouldSetSignature(account.Account.SignatureNewMessage))
{
account.Account.SignatureNewMessage = fullNames[result.new_message];
}
if (!string.IsNullOrEmpty(result.replyforward_message) && string.IsNullOrEmpty(account.Account.SignatureReplyForwardMessage))
if (!string.IsNullOrEmpty(result.replyforward_message) && ShouldSetSignature(account.Account.SignatureReplyForwardMessage))
{
account.Account.SignatureReplyForwardMessage = fullNames[result.replyforward_message];
}
return result.hash;
}
}
private bool ShouldSetSignature(string currentSignature)
{
return string.IsNullOrEmpty(currentSignature) || AlwaysSetLocal;
}
#endregion
private string StoreSignature(ISignatures signatures, ZPushAccount account, Signature signatureInfo)
{
string name = GetSignatureName(signatures, account, signatureInfo.name);
@ -204,7 +274,7 @@ namespace Acacia.Features.Signatures
{
return SignatureLocalName.ReplaceStringTokens("%", "%", new Dictionary<string, string>
{
{ "account", account.DisplayName },
{ "account", account.Account.SmtpAddress },
{ "name", name }
});
}
@ -307,5 +377,14 @@ namespace Acacia.Features.Signatures
}
}
}
#region Settings
public override FeatureSettings GetSettings()
{
return new SignaturesSettings(this);
}
#endregion
}
}

View File

@ -0,0 +1,79 @@
namespace Acacia.Features.Signatures
{
partial class SignaturesSettings
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SignaturesSettings));
this._layout = new System.Windows.Forms.TableLayoutPanel();
this.checkForceSet = new System.Windows.Forms.CheckBox();
this.buttonResync = new System.Windows.Forms.Button();
this._layout.SuspendLayout();
this.SuspendLayout();
//
// _layout
//
resources.ApplyResources(this._layout, "_layout");
this._layout.Controls.Add(this.checkForceSet, 0, 0);
this._layout.Controls.Add(this.buttonResync, 0, 1);
this._layout.Name = "_layout";
//
// checkForceSet
//
resources.ApplyResources(this.checkForceSet, "checkForceSet");
this.checkForceSet.Name = "checkForceSet";
this.checkForceSet.UseVisualStyleBackColor = true;
this.checkForceSet.CheckedChanged += new System.EventHandler(this.checkForceSet_CheckedChanged);
//
// buttonResync
//
resources.ApplyResources(this.buttonResync, "buttonResync");
this.buttonResync.Name = "buttonResync";
this.buttonResync.UseVisualStyleBackColor = true;
this.buttonResync.Click += new System.EventHandler(this.buttonResync_Click);
//
// SignaturesSettings
//
resources.ApplyResources(this, "$this");
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.Window;
this.Controls.Add(this._layout);
this.Name = "SignaturesSettings";
this._layout.ResumeLayout(false);
this._layout.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TableLayoutPanel _layout;
private System.Windows.Forms.CheckBox checkForceSet;
private System.Windows.Forms.Button buttonResync;
}
}

View File

@ -0,0 +1,84 @@
/// Copyright 2016 Kopano b.v.
///
/// 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,
/// as published by the Free Software Foundation.
///
/// This program is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
/// GNU Affero General Public License for more details.
///
/// You should have received a copy of the GNU Affero General Public License
/// along with this program.If not, see<http://www.gnu.org/licenses/>.
///
/// Consult LICENSE file for details
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Acacia.ZPush;
using Acacia.UI;
namespace Acacia.Features.Signatures
{
public partial class SignaturesSettings : FeatureSettings
{
private readonly FeatureSignatures _feature;
public override Feature Feature
{
get
{
return _feature;
}
}
public SignaturesSettings(FeatureSignatures feature = null)
{
this._feature = feature;
InitializeComponent();
// Allow null feature for designer
if (feature != null)
{
checkForceSet.Checked = feature.AlwaysSetLocal;
}
}
override public void Apply()
{
}
private void CheckDirty()
{
Dirty = false;
}
private void buttonResync_Click(object sender, EventArgs e)
{
if (_feature != null)
{
ProgressDialog.Execute("SignaturesSync",
(ct) =>
{
_feature.ResyncAll();
return 0;
}
);
}
}
private void checkForceSet_CheckedChanged(object sender, EventArgs e)
{
if (_feature != null)
_feature.AlwaysSetLocal = checkForceSet.Checked;
}
}
}

View File

@ -0,0 +1,252 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="_layout.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="_layout.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
<value>GrowAndShrink</value>
</data>
<data name="_layout.ColumnCount" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="checkForceSet.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="checkForceSet.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="checkForceSet.Location" type="System.Drawing.Point, System.Drawing">
<value>4, 4</value>
</data>
<data name="checkForceSet.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>4, 4, 4, 4</value>
</data>
<data name="checkForceSet.Size" type="System.Drawing.Size, System.Drawing">
<value>152, 17</value>
</data>
<data name="checkForceSet.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="checkForceSet.Text" xml:space="preserve">
<value>Override local signatures</value>
</data>
<data name="&gt;&gt;checkForceSet.Name" xml:space="preserve">
<value>checkForceSet</value>
</data>
<data name="&gt;&gt;checkForceSet.Type" xml:space="preserve">
<value>System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;checkForceSet.Parent" xml:space="preserve">
<value>_layout</value>
</data>
<data name="&gt;&gt;checkForceSet.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="buttonResync.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="buttonResync.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 28</value>
</data>
<data name="buttonResync.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>8, 0, 8, 0</value>
</data>
<data name="buttonResync.Size" type="System.Drawing.Size, System.Drawing">
<value>154, 23</value>
</data>
<data name="buttonResync.TabIndex" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="buttonResync.Text" xml:space="preserve">
<value>Resynchronise signatures</value>
</data>
<data name="&gt;&gt;buttonResync.Name" xml:space="preserve">
<value>buttonResync</value>
</data>
<data name="&gt;&gt;buttonResync.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;buttonResync.Parent" xml:space="preserve">
<value>_layout</value>
</data>
<data name="&gt;&gt;buttonResync.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="_layout.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="_layout.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 0</value>
</data>
<data name="_layout.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>2, 2, 2, 2</value>
</data>
<data name="_layout.RowCount" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="_layout.Size" type="System.Drawing.Size, System.Drawing">
<value>160, 54</value>
</data>
<data name="_layout.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="&gt;&gt;_layout.Name" xml:space="preserve">
<value>_layout</value>
</data>
<data name="&gt;&gt;_layout.Type" xml:space="preserve">
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;_layout.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;_layout.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="_layout.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="checkForceSet" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="buttonResync" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="Percent,100,Absolute,20" /&gt;&lt;Rows Styles="AutoSize,0,AutoSize,0" /&gt;&lt;/TableLayoutSettings&gt;</value>
</data>
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
<value>6, 13</value>
</data>
<data name="$this.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="$this.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
<value>GrowAndShrink</value>
</data>
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>2, 2, 2, 2</value>
</data>
<data name="$this.Size" type="System.Drawing.Size, System.Drawing">
<value>160, 54</value>
</data>
<data name="&gt;&gt;$this.Name" xml:space="preserve">
<value>SignaturesSettings</value>
</data>
<data name="&gt;&gt;$this.Type" xml:space="preserve">
<value>Acacia.UI.FeatureSettings, Kopano, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null</value>
</data>
</root>

View File

@ -132,6 +132,15 @@ namespace Acacia.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Signatures.
/// </summary>
internal static string Feature_Signatures {
get {
return ResourceManager.GetString("Feature_Signatures", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Address Book for {0}.
/// </summary>
@ -1019,6 +1028,24 @@ namespace Acacia.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to The signatures are being synchronised..
/// </summary>
internal static string SignaturesSync_Label {
get {
return ResourceManager.GetString("SignaturesSync_Label", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Signatures.
/// </summary>
internal static string SignaturesSync_Title {
get {
return ResourceManager.GetString("SignaturesSync_Title", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to There is an error with the security certificate for server {0}. Do you want to allow the connection anyway?.
/// </summary>

View File

@ -445,4 +445,13 @@
<data name="AccountNoPassword_Title" xml:space="preserve">
<value>Password unavailable</value>
</data>
<data name="Feature_Signatures" xml:space="preserve">
<value>Signatures</value>
</data>
<data name="SignaturesSync_Label" xml:space="preserve">
<value>The signatures are being synchronised.</value>
</data>
<data name="SignaturesSync_Title" xml:space="preserve">
<value>Signatures</value>
</data>
</root>

View File

@ -50,7 +50,7 @@ namespace Acacia.Stubs.OutlookWrappers
private static string GetPath(string name, string suffix)
{
return Path.ChangeExtension(Path.Combine(BasePath, name), suffix);
return Path.Combine(BasePath, name) + "." + suffix;
}
public void Delete()

View File

@ -247,15 +247,17 @@ namespace Acacia.UI
if (_gab?.Contacts != null)
{
// Begin GAB lookup, search on full name or username
ISearch<IContactItem> search = _gab.Contacts.Search<IContactItem>();
search.AddField("urn:schemas:contacts:customerid").SetOperation(SearchOperation.Equal, username);
// Fetch the result, if any.
// TODO: make a SearchOne method?
List<GABUser> users = new List<GABUser>();
foreach (IContactItem result in search.Search(1))
using (ISearch<IContactItem> search = _gab.Contacts.Search<IContactItem>())
{
return new GABUser(result.FullName, result.CustomerID);
search.AddField("urn:schemas:contacts:customerid").SetOperation(SearchOperation.Equal, username);
// Fetch the result, if any.
List<GABUser> users = new List<GABUser>();
using (IContactItem result = search.SearchOne())
{
if (result != null)
return new GABUser(result.FullName, result.CustomerID);
}
}
}

View File

@ -126,14 +126,10 @@
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="buttonApply.Location" type="System.Drawing.Point, System.Drawing">
<value>358, 4</value>
</data>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="buttonApply.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>4, 4, 4, 4</value>
<value>269, 3</value>
</data>
<data name="buttonApply.Size" type="System.Drawing.Size, System.Drawing">
<value>100, 33</value>
<value>75, 27</value>
</data>
<data name="buttonApply.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
@ -157,13 +153,10 @@
<value>True</value>
</data>
<data name="buttonCancel.Location" type="System.Drawing.Point, System.Drawing">
<value>250, 4</value>
</data>
<data name="buttonCancel.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>4, 4, 4, 4</value>
<value>188, 3</value>
</data>
<data name="buttonCancel.Size" type="System.Drawing.Size, System.Drawing">
<value>100, 33</value>
<value>75, 27</value>
</data>
<data name="buttonCancel.TabIndex" type="System.Int32, mscorlib">
<value>1</value>
@ -187,13 +180,10 @@
<value>True</value>
</data>
<data name="buttonOK.Location" type="System.Drawing.Point, System.Drawing">
<value>142, 4</value>
</data>
<data name="buttonOK.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>4, 4, 4, 4</value>
<value>107, 3</value>
</data>
<data name="buttonOK.Size" type="System.Drawing.Size, System.Drawing">
<value>100, 33</value>
<value>75, 27</value>
</data>
<data name="buttonOK.TabIndex" type="System.Int32, mscorlib">
<value>2</value>
@ -213,6 +203,7 @@
<data name="&gt;&gt;buttonOK.ZOrder" xml:space="preserve">
<value>2</value>
</data>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="flowLayoutPanel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Bottom</value>
</data>
@ -220,16 +211,13 @@
<value>RightToLeft</value>
</data>
<data name="flowLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 394</value>
</data>
<data name="flowLayoutPanel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>4, 4, 4, 4</value>
<value>0, 374</value>
</data>
<data name="flowLayoutPanel1.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>0, 0, 7, 0</value>
<value>0, 0, 5, 0</value>
</data>
<data name="flowLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
<value>469, 37</value>
<value>352, 30</value>
</data>
<data name="flowLayoutPanel1.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
@ -250,16 +238,13 @@
<value>True</value>
</metadata>
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
<value>8, 16</value>
<value>6, 13</value>
</data>
<data name="$this.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
<value>469, 431</value>
</data>
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>4, 4, 4, 4</value>
<value>352, 404</value>
</data>
<data name="$this.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
<value>CenterParent</value>
@ -271,6 +256,6 @@
<value>SettingsDialog</value>
</data>
<data name="&gt;&gt;$this.Type" xml:space="preserve">
<value>System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>Acacia.UI.KopanoDialog, Kopano, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null</value>
</data>
</root>

View File

@ -73,9 +73,23 @@ namespace Acacia.ZPush.API.SharedFolders
public SyncId ServerId { get { return _data.ServerId; } }
public SyncId ParentId { get { return _data.ParentId; } }
public BackendId ParentIdAsBackend { get { return Parent?.BackendId ?? BackendId.NONE; } }
public BackendId BackendId { get { return _data.BackendId; } }
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; }

View File

@ -55,13 +55,16 @@ namespace Acacia.ZPush.API.SharedFolders
return false;
SoapData rhs = (SoapData)o;
// TODO: this isn't really a full equality test, as flags is masked. This is because Equals is only used
// to test if there are changes that need to be applied. It would be nicer to rename this, and
// equals in SharedFolder to something like NeedsApply.
return
store == rhs.store &&
folderid == rhs.folderid &&
parentid == rhs.parentid &&
name == rhs.name &&
type == rhs.type &&
flags == rhs.flags;
(flags & ShareFlags.Mask_Apply) == (rhs.flags & ShareFlags.Mask_Apply);
}
public override int GetHashCode()
@ -86,6 +89,17 @@ namespace Acacia.ZPush.API.SharedFolders
return _data;
}
/// <summary>
/// Patches in any information that is available on AvailableFolder, but not SharedFolder. This is specifically the parent id.
/// </summary>
public SharedFolder PatchInformation(AvailableFolder folder)
{
if (folder.ParentIdAsBackend != _data.parentid)
{
_data.parentid = folder.ParentIdAsBackend;
}
return this;
}
#endregion
@ -100,8 +114,8 @@ namespace Acacia.ZPush.API.SharedFolders
{
store = folder.Store.UserName,
folderid = folder.BackendId,
parentid = folder.Parent?.BackendId ?? BackendId.NONE,
name = folder.Name,
parentid = folder.ParentIdAsBackend,
name = folder.DefaultName,
type = OutlookConstants.USER_SYNC_TYPES[(int)folder.Type],
flags = folder.IsMailFolder ? ShareFlags.SendAsOwner : ShareFlags.None
};
@ -161,6 +175,7 @@ namespace Acacia.ZPush.API.SharedFolders
}
public bool FlagSendAsOwner { get { return Flags.HasFlag(ShareFlags.SendAsOwner); } }
public bool FlagUpdateShareName { get { return Flags.HasFlag(ShareFlags.TrackShareName); } }
/// <summary>
/// Returns a copy with the specified 'send as owner' flag.
@ -170,6 +185,14 @@ namespace Acacia.ZPush.API.SharedFolders
return WithFlags(value ? (_data.flags | ShareFlags.SendAsOwner) : (_data.flags & ~ShareFlags.SendAsOwner));
}
/// <summary>
/// Returns a copy with the specified 'update share name' flag.
/// </summary>
public SharedFolder WithFlagUpdateShareName(bool value)
{
return WithFlags(value ? (_data.flags | ShareFlags.TrackShareName) : (_data.flags & ~ShareFlags.TrackShareName));
}
#endregion
#region Standard overrides

View File

@ -29,7 +29,22 @@ namespace Acacia.ZPush.API.SharedFolders
public enum ShareFlags
{
None = 0,
/// <summary>
/// Mails from folders containing this flag will be sent as the owner of the share, not the user.
/// </summary>
SendAsOwner = 1,
/// <summary>
/// Folders with this flag will be renamed when the original folder is renamed.
/// </summary>
TrackShareName = 2,
/// <summary>
/// The mask indicating which flag changes cause an Apply to become needed. I.e. flags not in the mask
/// are updated only if other changes are made.
/// </summary>
Mask_Apply = 1
}
/// <summary>

View File

@ -169,7 +169,21 @@ namespace Acacia.ZPush.Connect.Soap
}
private class TypeHandlerInt : TypeHandler
{
public TypeHandlerInt() : base(SoapConstants.XMLNS_XSD, "int", typeof(long)) { }
public TypeHandlerInt() : base(SoapConstants.XMLNS_XSD, null, typeof(int)) { }
public override void Serialize(string name, object value, StringBuilder s)
{
s.Append(string.Format("<{0} xsi:type=\"xsd:int\">{1}</{0}>", name, value));
}
protected override object DeserializeContents(XmlNode node, Type expectedType)
{
return long.Parse(node.InnerText);
}
}
private class TypeHandlerLong : TypeHandler
{
public TypeHandlerLong() : base(SoapConstants.XMLNS_XSD, "int", typeof(long)) { }
public override void Serialize(string name, object value, StringBuilder s)
{
@ -439,6 +453,8 @@ namespace Acacia.ZPush.Connect.Soap
static SoapSerializer()
{
RegisterTypeHandler(new TypeHandlerBoolean());
// What is called an int in soap might actually be a long here.
RegisterTypeHandler(new TypeHandlerLong());
RegisterTypeHandler(new TypeHandlerInt());
RegisterTypeHandler(new TypeHandlerString());
RegisterTypeHandler(new TypeHandlerList());

View File

@ -130,11 +130,14 @@ namespace Acacia.ZPush.Connect
{
// Content
using (HttpContent content = request.GetContent())
using (HttpResponseMessage response = _client.PostAsync(url, content, _cancel ?? CancellationToken.None).Result)
using (HttpContent responseContent = response.Content)
{
Logger.Instance.Debug(this, "Response: {0}", responseContent.ReadAsStringAsync().Result);
return request.ParseResponse(responseContent.ReadAsStreamAsync().Result);
Logger.Instance.Trace(this, "Request: {0}", content.ReadAsStringAsync().Result);
using (HttpResponseMessage response = _client.PostAsync(url, content, _cancel ?? CancellationToken.None).Result)
using (HttpContent responseContent = response.Content)
{
Logger.Instance.Trace(this, "Response: {0}", responseContent.ReadAsStringAsync().Result);
return request.ParseResponse(responseContent.ReadAsStreamAsync().Result);
}
}
}
}

View File

@ -220,6 +220,18 @@ msgctxt "AcaciaZPushPlugin\\Features\\SharedFolders\\SharedFoldersDialog\\$this.
msgid "Shared Folders - {0}"
msgstr ""
#: AcaciaZPushPlugin\Features\Signatures\SignaturesSettings\checkForceSet.Text
#, csharp-format
msgctxt "AcaciaZPushPlugin\\Features\\Signatures\\SignaturesSettings\\checkForceSet.Text"
msgid "Override local signatures"
msgstr ""
#: AcaciaZPushPlugin\Features\Signatures\SignaturesSettings\buttonResync.Text
#, csharp-format
msgctxt "AcaciaZPushPlugin\\Features\\Signatures\\SignaturesSettings\\buttonResync.Text"
msgid "Resynchronise signatures"
msgstr ""
#: AcaciaZPushPlugin\Properties\Resources\OOFGet_Failed
#, csharp-format
msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\OOFGet_Failed"
@ -682,6 +694,24 @@ msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\AccountNoPassword_Title"
msgid "Password unavailable"
msgstr ""
#: AcaciaZPushPlugin\Properties\Resources\Feature_Signatures
#, csharp-format
msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\Feature_Signatures"
msgid "Signatures"
msgstr ""
#: AcaciaZPushPlugin\Properties\Resources\SignaturesSync_Label
#, csharp-format
msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\SignaturesSync_Label"
msgid "The signatures are being synchronised."
msgstr ""
#: AcaciaZPushPlugin\Properties\Resources\SignaturesSync_Title
#, csharp-format
msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\SignaturesSync_Title"
msgid "Signatures"
msgstr ""
#: AcaciaZPushPlugin\UI\ProgressDialog\labelMessage.Text
#, csharp-format
msgctxt "AcaciaZPushPlugin\\UI\\ProgressDialog\\labelMessage.Text"

View File

@ -220,6 +220,18 @@ msgctxt "AcaciaZPushPlugin\\Features\\SharedFolders\\SharedFoldersDialog\\$this.
msgid "Shared Folders - {0}"
msgstr "Shared Folders - {0}"
#: AcaciaZPushPlugin\Features\Signatures\SignaturesSettings\checkForceSet.Text
#, csharp-format
msgctxt "AcaciaZPushPlugin\\Features\\Signatures\\SignaturesSettings\\checkForceSet.Text"
msgid "Override local signatures"
msgstr "Override local signatures"
#: AcaciaZPushPlugin\Features\Signatures\SignaturesSettings\buttonResync.Text
#, csharp-format
msgctxt "AcaciaZPushPlugin\\Features\\Signatures\\SignaturesSettings\\buttonResync.Text"
msgid "Resynchronise signatures"
msgstr "Resynchronise signatures"
#: AcaciaZPushPlugin\Properties\Resources\OOFGet_Failed
#, csharp-format
msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\OOFGet_Failed"
@ -684,6 +696,24 @@ msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\AccountNoPassword_Title"
msgid "Password unavailable"
msgstr "Password unavailable"
#: AcaciaZPushPlugin\Properties\Resources\Feature_Signatures
#, csharp-format
msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\Feature_Signatures"
msgid "Signatures"
msgstr "Signatures"
#: AcaciaZPushPlugin\Properties\Resources\SignaturesSync_Label
#, csharp-format
msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\SignaturesSync_Label"
msgid "The signatures are being synchronised."
msgstr "The signatures are being synchronised."
#: AcaciaZPushPlugin\Properties\Resources\SignaturesSync_Title
#, csharp-format
msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\SignaturesSync_Title"
msgid "Signatures"
msgstr "Signatures"
#: AcaciaZPushPlugin\UI\ProgressDialog\labelMessage.Text
#, csharp-format
msgctxt "AcaciaZPushPlugin\\UI\\ProgressDialog\\labelMessage.Text"