From 3736d8d320441c98805269e246954a89a2d40abf Mon Sep 17 00:00:00 2001 From: Patrick Simpson Date: Fri, 1 Dec 2017 12:22:22 +0200 Subject: [PATCH] [KOE-124] UI improvements --- .../SharedFoldersDialog.Designer.cs | 13 ++- .../SharedFolders/SharedFoldersDialog.cs | 90 ++++++++++++++----- .../SharedFolders/SharedFoldersDialog.resx | 40 +++++++-- .../Features/SharedFolders/StoreTreeNode.cs | 12 +-- .../AcaciaZPushPlugin/OutlookConstants.cs | 1 + .../AcaciaZPushPlugin/Stubs/IAccount.cs | 2 + .../Stubs/OutlookWrappers/AccountWrapper.cs | 8 ++ .../AcaciaZPushPlugin/ZPush/ZPushAccount.cs | 61 ++++++++++++- .../AcaciaZPushPlugin/ZPush/ZPushAccounts.cs | 2 +- 9 files changed, 192 insertions(+), 37 deletions(-) diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.Designer.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.Designer.cs index 40b4a14..2abd27a 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.Designer.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.Designer.cs @@ -49,6 +49,7 @@ this.checkReminders = new System.Windows.Forms.CheckBox(); this._labelPermissions = new System.Windows.Forms.Label(); this.dialogButtons = new Acacia.Controls.KDialogButtons(); + this._labelRestartRequired = new System.Windows.Forms.Label(); this._layout.SuspendLayout(); this._mainBusyHider.SuspendLayout(); this._layoutMain.SuspendLayout(); @@ -136,7 +137,7 @@ resources.ApplyResources(this._layoutOptions, "_layoutOptions"); this._layoutOptions.Controls.Add(this._labelWholeStore, 0, 0); this._layoutOptions.Controls.Add(this.checkWholeStore, 1, 0); - this._layoutOptions.Controls.Add(this.labelPermissionsValue, 0, 4); + this._layoutOptions.Controls.Add(this.labelPermissionsValue, 1, 4); this._layoutOptions.Controls.Add(this._labelName, 0, 1); this._layoutOptions.Controls.Add(this.textName, 1, 1); this._layoutOptions.Controls.Add(this._labelSendAs, 0, 2); @@ -144,6 +145,7 @@ this._layoutOptions.Controls.Add(this._labelReminders, 0, 3); this._layoutOptions.Controls.Add(this.checkReminders, 1, 3); this._layoutOptions.Controls.Add(this._labelPermissions, 0, 4); + this._layoutOptions.Controls.Add(this._labelRestartRequired, 2, 0); this._layoutOptions.Name = "_layoutOptions"; // // _labelWholeStore @@ -154,6 +156,7 @@ // checkWholeStore // resources.ApplyResources(this.checkWholeStore, "checkWholeStore"); + this.checkWholeStore.ForeColor = System.Drawing.SystemColors.ControlText; this.checkWholeStore.Name = "checkWholeStore"; this.checkWholeStore.UseVisualStyleBackColor = true; this.checkWholeStore.CheckedChanged += new System.EventHandler(this.checkWholeStore_CheckedChanged); @@ -161,6 +164,7 @@ // labelPermissionsValue // resources.ApplyResources(this.labelPermissionsValue, "labelPermissionsValue"); + this._layoutOptions.SetColumnSpan(this.labelPermissionsValue, 2); this.labelPermissionsValue.Name = "labelPermissionsValue"; // // _labelName @@ -170,6 +174,7 @@ // // textName // + this._layoutOptions.SetColumnSpan(this.textName, 2); resources.ApplyResources(this.textName, "textName"); this.textName.Name = "textName"; this.textName.TextChanged += new System.EventHandler(this.textName_TextChanged); @@ -214,6 +219,11 @@ this.dialogButtons.Name = "dialogButtons"; this.dialogButtons.Apply += new System.EventHandler(this.dialogButtons_Apply); // + // _labelRestartRequired + // + resources.ApplyResources(this._labelRestartRequired, "_labelRestartRequired"); + this._labelRestartRequired.Name = "_labelRestartRequired"; + // // SharedFoldersDialog // resources.ApplyResources(this, "$this"); @@ -259,5 +269,6 @@ private System.Windows.Forms.CheckBox checkReminders; private System.Windows.Forms.CheckBox checkWholeStore; private System.Windows.Forms.Label labelPermissionsValue; + private System.Windows.Forms.Label _labelRestartRequired; } } \ No newline at end of file diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.cs index 79a6ebf..5ce1c18 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.cs @@ -93,10 +93,17 @@ namespace Acacia.Features.SharedFolders private readonly ZPushAccount _account; private readonly SharedFoldersManager _folders; private readonly SyncId _initialSyncId; + private ZPushAccount _initialAccount; private SharedFolder _initialFolder; public SharedFoldersDialog(FeatureSharedFolders feature, ZPushAccount account, SyncId initial = null) { + // If this is a shared store, open the account it's a share for, with the request account as the initial + if (account.ShareFor != null) + { + _initialAccount = account; + account = account.ShareForAccount; + } this._account = account; this._folders = feature.Manage(account); this._initialSyncId = initial; @@ -142,6 +149,7 @@ namespace Acacia.Features.SharedFolders .New((ctx) => { // TODO: bind cancellation token to Cancel button + // Fetch current shares ICollection folders = _folders.GetCurrentShares(ctx.CancellationToken); @@ -175,12 +183,18 @@ namespace Acacia.Features.SharedFolders // Add public folders Dictionary publicShares; shares.TryGetValue(GABUser.USER_PUBLIC, out publicShares); - AddUserFolders(GABUser.USER_PUBLIC, publicShares, false); + AddUserFolders(GABUser.USER_PUBLIC, false, publicShares, false); + + // Add shared stores + foreach (ZPushAccount shared in _account.SharedAccounts) + { + AddUserFolders(new GABUser(shared.ShareUserName), true, null, false); + } // Add any users for which we have shared folders foreach (KeyValuePair> entry in shares.OrderBy(x => x.Key.DisplayName)) if (GABUser.USER_PUBLIC != entry.Key) - AddUserFolders(entry.Key, entry.Value, false); + AddUserFolders(entry.Key, false, entry.Value, false); } finally { @@ -206,6 +220,14 @@ namespace Acacia.Features.SharedFolders } SetInitialFocus(kTreeFolders); } + else if (_initialAccount != null) + { + StoreTreeNode node; + if (_userFolders.TryGetValue(new GABUser(_initialAccount.ShareUserName), out node)) + { + FocusNode(node, true); + } + } else { SetInitialFocus(gabLookup); @@ -237,6 +259,7 @@ namespace Acacia.Features.SharedFolders foreach (StoreTreeNode storeNode in _userFolders.Values) { + // Check modified folders if (storeNode.IsDirty) { ctx.AddBusy(1); @@ -245,6 +268,7 @@ namespace Acacia.Features.SharedFolders _folders.SetSharesForStore(storeNode.User, storeNode.CurrentShares, ctx.CancellationToken); } + // And modified stores if (storeNode.IsWholeStoreDirty) { state.stores.Add(storeNode); @@ -273,26 +297,44 @@ namespace Acacia.Features.SharedFolders if (state.stores.Count > 0) { - bool restart = MessageBox.Show(ThisAddIn.Instance.Window, - "Outlook will be restarted to open the new stores", - "Open stores", - MessageBoxButtons.OKCancel, - MessageBoxIcon.Information - ) == DialogResult.OK; + List add = new List(); - // Reset state. Also do this when restarting, to avoid warning message about unsaved changes - foreach (StoreTreeNode node in state.stores) - node.WantShare = node.IsShared; + // Remove any unshared store + foreach (StoreTreeNode store in state.stores) + { + if (store.WantShare) + { + add.Add(store); + continue; + } - if (!restart) - return; - // Restart - IRestarter restarter = ThisAddIn.Instance.Restarter(); - restarter.CloseWindows = true; - foreach (StoreTreeNode node in state.stores) - restarter.OpenShare(_account, node.User); - restarter.Restart(); + } + + // Check for any new stores + if (add.Count > 0) + { + bool restart = MessageBox.Show(ThisAddIn.Instance.Window, + "Outlook will be restarted to open the new stores", + "Open stores", + MessageBoxButtons.OKCancel, + MessageBoxIcon.Information + ) == DialogResult.OK; + + // Reset state. Also do this when restarting, to avoid warning message about unsaved changes + foreach (StoreTreeNode node in state.stores) + node.WantShare = node.IsShared; + + if (!restart) + return; + + // Restart + IRestarter restarter = ThisAddIn.Instance.Restarter(); + restarter.CloseWindows = true; + foreach (StoreTreeNode node in state.stores) + restarter.OpenShare(_account, node.User); + restarter.Restart(); + } } }, true) .OnError((x) => @@ -311,7 +353,7 @@ namespace Acacia.Features.SharedFolders private void buttonOpenUser_Click(object sender, EventArgs e) { - AddUserFolders(gabLookup.SelectedUser, null, true); + AddUserFolders(gabLookup.SelectedUser, false, null, true); } private void gabLookup_SelectedUserChanged(object source, GABLookupControl.SelectedUserEventArgs e) @@ -320,7 +362,7 @@ namespace Acacia.Features.SharedFolders if (e.IsChosen) { - AddUserFolders(e.SelectedUser, null, true); + AddUserFolders(e.SelectedUser, false, null, true); } } @@ -338,7 +380,7 @@ namespace Acacia.Features.SharedFolders private readonly Dictionary _userFolders = new Dictionary(); - private void AddUserFolders(GABUser user, Dictionary currentShares, bool select) + private void AddUserFolders(GABUser user, bool wholeStore, Dictionary currentShares, bool select) { if (user == null) return; @@ -355,7 +397,9 @@ namespace Acacia.Features.SharedFolders // Add the node node = new StoreTreeNode(_folders, gabLookup.GAB, - user, user.DisplayName, currentShares ?? new Dictionary()); + user, user.DisplayName, currentShares ?? new Dictionary(), + wholeStore); + if (wholeStore) node.DirtyChanged += UserSharesChanged; node.CheckStateChanged += WholeStoreShareChanged; _userFolders.Add(user, node); diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.resx b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.resx index 4949a8e..e7b1ae9 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.resx +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.resx @@ -307,7 +307,7 @@ GrowAndShrink - 2 + 3 True @@ -402,9 +402,6 @@ 8 - - Share as - MiddleLeft @@ -648,6 +645,39 @@ 9 + + Fill + + + 123, 0 + + + 322, 27 + + + 10 + + + (Requires restart) + + + MiddleLeft + + + False + + + _labelRestartRequired + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + _layoutOptions + + + 10 + Fill @@ -679,7 +709,7 @@ 2 - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="_labelWholeStore" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="checkWholeStore" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="labelPermissionsValue" Row="4" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="_labelName" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="textName" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="_labelSendAs" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="checkSendAs" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="_labelReminders" Row="3" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="checkReminders" Row="3" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="_labelPermissions" Row="4" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,Percent,100" /><Rows Styles="AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0" /></TableLayoutSettings> + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="_labelWholeStore" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="checkWholeStore" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="labelPermissionsValue" Row="4" RowSpan="1" Column="1" ColumnSpan="2" /><Control Name="_labelName" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="textName" Row="1" RowSpan="1" Column="1" ColumnSpan="2" /><Control Name="_labelSendAs" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="checkSendAs" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="_labelReminders" Row="3" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="checkReminders" Row="3" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="_labelPermissions" Row="4" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="_labelRestartRequired" Row="0" RowSpan="1" Column="2" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,AutoSize,0,Percent,100" /><Rows Styles="AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,Absolute,20" /></TableLayoutSettings> Fill diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/StoreTreeNode.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/StoreTreeNode.cs index d725be5..c09f0c0 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/StoreTreeNode.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/StoreTreeNode.cs @@ -47,9 +47,10 @@ namespace Acacia.Features.SharedFolders private readonly GABUser _user; public readonly bool IsReadOnly; + public readonly bool IsShared; public StoreTreeNode(SharedFoldersManager folders, GABHandler gab, GABUser user, string text, - Dictionary currentFolders) + Dictionary currentFolders, bool isShared) : base(text) { @@ -58,6 +59,7 @@ namespace Acacia.Features.SharedFolders this._gab = gab; this._user = user; this.IsReadOnly = false; + this.IsShared = isShared; // Create an empty current state. When loading the nodes, the shares will be added. This has the benefit of // cleaning up automatically any obsolote shares. @@ -80,6 +82,9 @@ namespace Acacia.Features.SharedFolders ChildLoader.Reload(); }; Control = _reloader; + + // Set up sharing + WantShare = isShared; } private static void ApplyReadOnly(KTreeNode node, bool isReadOnly) @@ -92,11 +97,6 @@ namespace Acacia.Features.SharedFolders get { return ((UserFolderLoader)ChildLoader).User; } } - public bool IsShared - { - get { return false; } - } - public bool WantShare { get diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/OutlookConstants.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/OutlookConstants.cs index c3bcfe8..2abe4ed 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/OutlookConstants.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/OutlookConstants.cs @@ -46,6 +46,7 @@ namespace Acacia public const string REG_VAL_CURRENT_SIGNATURE = "KOE Signature Digest"; public const string REG_VAL_NEXT_ACCOUNT_ID = "NextAccountID"; + public const string REG_VAL_KOE_SHARE_FOR = "KOE Share For"; #endregion diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IAccount.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IAccount.cs index d49b3fe..dd29666 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IAccount.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IAccount.cs @@ -72,5 +72,7 @@ namespace Acacia.Stubs get; set; } + + string ShareFor {get;} } } diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AccountWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AccountWrapper.cs index af219a9..36ef412 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AccountWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AccountWrapper.cs @@ -284,6 +284,14 @@ namespace Acacia.Stubs.OutlookWrappers } } + public string ShareFor + { + get + { + return RegistryUtil.GetValueString(_regPath, OutlookConstants.REG_VAL_KOE_SHARE_FOR, null); + } + } + #endregion } } diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushAccount.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushAccount.cs index 5325331..ac099a2 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushAccount.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushAccount.cs @@ -36,10 +36,12 @@ namespace Acacia.ZPush { #region Miscellaneous + private readonly ZPushAccounts _zPushAccounts; private readonly IAccount _account; - internal ZPushAccount(IAccount account) + internal ZPushAccount(ZPushAccounts zPushAccounts, IAccount account) { + this._zPushAccounts = zPushAccounts; this._account = account; } @@ -206,5 +208,62 @@ namespace Acacia.ZPush } #endregion + + #region Account sharing + + public string ShareFor + { + get { return Account.ShareFor; } + } + + public string ShareUserName + { + get + { + if (ShareFor == null) + return null; + int index = Account.UserName.IndexOf("+share+"); + if (index < 0) + return null; + + return Account.UserName.Substring(index + 7); + } + } + + [Browsable(false)] + public ZPushAccount ShareForAccount + { + get + { + if (Account.ShareFor == null) + return null; + + return _zPushAccounts.GetAccount(Account.ShareFor); + } + } + + [Browsable(false)] + public ZPushAccount[] SharedAccounts + { + get + { + if (ShareFor != null) + return new ZPushAccount[0]; + + List shares = new List(); + foreach (ZPushAccount account in _zPushAccounts.GetAccounts()) + { + if (account == this) + continue; + + if (account.ShareFor != null && account.ShareFor == this.Account.SmtpAddress) + shares.Add(account); + } + + return shares.ToArray(); + } + } + + #endregion } } diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushAccounts.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushAccounts.cs index 9b8f58c..3d5d9de 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushAccounts.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushAccounts.cs @@ -94,7 +94,7 @@ namespace Acacia.ZPush // Only EAS accounts can be zpush accounts if (account.AccountType == AccountType.EAS) { - ZPushAccount zpush = new ZPushAccount(account); + ZPushAccount zpush = new ZPushAccount(this, account); _accountsByStoreId.Add(account.StoreID, zpush); _accountsBySmtp.Add(account.SmtpAddress, zpush); Logger.Instance.Trace(this, "ZPush account: {0}", zpush);