From 7773d7f973f0c0de957dcbfcd7ae5f7e943379b7 Mon Sep 17 00:00:00 2001 From: Patrick Simpson Date: Mon, 27 Feb 2017 12:36:04 +0100 Subject: [PATCH] [KOE-51] Added tracking of changed names. To this end, the flag "TrackShareName" (=2) has been added. If this is set, and the name does not match the original folder's name, the name will be updated. The flag is set automatically when shares are applied and the share name matches the original name. Note that this flag does not cause the apply button to become enabled, to prevent having changes on existing shares. --- .../SharedFolders/SharedFoldersDialog.cs | 17 +++++++++++ .../Features/SharedFolders/StoreTreeNode.cs | 12 ++++---- .../API/SharedFolders/AvailableFolder.cs | 14 +++++++++ .../ZPush/API/SharedFolders/SharedFolder.cs | 29 +++++++++++++++++-- .../ZPush/API/SharedFolders/Types.cs | 15 ++++++++++ .../ZPush/Connect/Soap/SoapSerializer.cs | 18 +++++++++++- .../ZPush/Connect/ZPushConnection.cs | 11 ++++--- 7 files changed, 103 insertions(+), 13 deletions(-) diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.cs index 193ded5..79c941b 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.cs @@ -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); } } diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/StoreTreeNode.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/StoreTreeNode.cs index e478ab0..088e5e0 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/StoreTreeNode.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/StoreTreeNode.cs @@ -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; diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/API/SharedFolders/AvailableFolder.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/API/SharedFolders/AvailableFolder.cs index aec344b..c3411a6 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/API/SharedFolders/AvailableFolder.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/API/SharedFolders/AvailableFolder.cs @@ -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; } diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/API/SharedFolders/SharedFolder.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/API/SharedFolders/SharedFolder.cs index b4e2235..3b15cc3 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/API/SharedFolders/SharedFolder.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/API/SharedFolders/SharedFolder.cs @@ -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; } + /// + /// Patches in any information that is available on AvailableFolder, but not SharedFolder. This is specifically the parent id. + /// + 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); } } /// /// 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)); } + /// + /// Returns a copy with the specified 'update share name' flag. + /// + public SharedFolder WithFlagUpdateShareName(bool value) + { + return WithFlags(value ? (_data.flags | ShareFlags.TrackShareName) : (_data.flags & ~ShareFlags.TrackShareName)); + } + #endregion #region Standard overrides diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/API/SharedFolders/Types.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/API/SharedFolders/Types.cs index e602ce3..b1b7ee0 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/API/SharedFolders/Types.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/API/SharedFolders/Types.cs @@ -29,7 +29,22 @@ namespace Acacia.ZPush.API.SharedFolders public enum ShareFlags { None = 0, + + /// + /// Mails from folders containing this flag will be sent as the owner of the share, not the user. + /// SendAsOwner = 1, + + /// + /// Folders with this flag will be renamed when the original folder is renamed. + /// + TrackShareName = 2, + + /// + /// 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. + /// + Mask_Apply = 1 } /// diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/Connect/Soap/SoapSerializer.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/Connect/Soap/SoapSerializer.cs index eff1718..e02f120 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/Connect/Soap/SoapSerializer.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/Connect/Soap/SoapSerializer.cs @@ -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}", 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()); diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/Connect/ZPushConnection.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/Connect/ZPushConnection.cs index 28ef6f2..e18a406 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/Connect/ZPushConnection.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/Connect/ZPushConnection.cs @@ -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); + } } } }