From 05d6d715a088bf1124b07ca70f1c33aefc845875 Mon Sep 17 00:00:00 2001
From: Patrick Simpson 
Date: Wed, 8 Nov 2017 11:44:11 +0200
Subject: [PATCH 1/6] Comment update
---
 src/AcaciaZPushPlugin/AcaciaZPushPlugin/ThisAddIn.cs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ThisAddIn.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ThisAddIn.cs
index ed8d511..e000b51 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ThisAddIn.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ThisAddIn.cs
@@ -156,8 +156,8 @@ namespace Acacia
                 foreach (Feature feature in Features)
                     feature.AfterStartup();
 
-                // Initial send receive
-                ThisAddIn.Instance.SendReceive();
+                // [KOE-148] Initial send receive
+                Instance.SendReceive();
             }
             catch (System.Exception e)
             {
From 4b868456b001eca519bc77d862ba71b48c4ab385 Mon Sep 17 00:00:00 2001
From: Patrick Simpson 
Date: Wed, 8 Nov 2017 11:44:36 +0200
Subject: [PATCH 2/6] [KOE-98] Added exclusions for configured and GAB folders
 to reminders query
---
 .../SharedFolders/FeatureSharedFolders.cs     |  12 +-
 .../Features/SharedFolders/RemindersQuery.cs  | 110 +++++++++++++-----
 .../AcaciaZPushPlugin/ZPush/ZPushTypes.cs     |  24 +++-
 3 files changed, 111 insertions(+), 35 deletions(-)
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/FeatureSharedFolders.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/FeatureSharedFolders.cs
index 4eeebf7..bcbfbed 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/FeatureSharedFolders.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/FeatureSharedFolders.cs
@@ -88,7 +88,7 @@ namespace Acacia.Features.SharedFolders
 
         private bool CanManageFolder(MenuItem b, IFolder folder)
         {
-            return folder.SyncId?.IsShared == true;
+            return folder.SyncId?.IsCustom == true;
         }
 
         private void ManageFolder(IFolder folder)
@@ -151,7 +151,7 @@ namespace Acacia.Features.SharedFolders
             // Check that we can get the id
             SyncId folderId = folder.SyncId;
             Logger.Instance.Trace(this, "GetSharedFolder1: {0}", folderId);
-            if (folderId == null || !folderId.IsShared)
+            if (folderId == null || !folderId.IsCustom)
                 return null;
 
             // Get the ZPush account
@@ -310,7 +310,7 @@ namespace Acacia.Features.SharedFolders
 
             public override bool IsApplicable(IFolder folder)
             {
-                if (folder.SyncId != null && folder.SyncId.IsShared)
+                if (folder.SyncId != null && folder.SyncId.IsCustom)
                     return true;
 
                 using (IFolder parent = folder.Parent)
@@ -354,7 +354,7 @@ namespace Acacia.Features.SharedFolders
         private void OnSharedFolderDiscovered(IFolder folder)
         {
             Logger.Instance.Trace(this, "Shared folder discovered: {0} - {1}", folder.Name, folder.SyncId);
-            if (folder.SyncId == null || !folder.SyncId.IsShared)
+            if (folder.SyncId == null || !folder.SyncId.IsCustom)
             {
                 Logger.Instance.Warning(this, "Local folder created in shared folder, deleting: {0} - {1}", folder.Name, folder.SyncId);
                 // This is a new, locally created folder. Warn and remove
@@ -376,7 +376,7 @@ namespace Acacia.Features.SharedFolders
 
         private void Folder_BeforeFolderMove(IFolder src, IFolder moveTo, ref bool cancel)
         {
-            if (src.SyncId?.IsShared == true || moveTo.SyncId?.IsShared == true)
+            if (src.SyncId?.IsCustom == true || moveTo.SyncId?.IsCustom == true)
             {
                 // Suppress any move of or into a shared folder
                 Logger.Instance.Warning(this, "Shared folder move: {0} - {1}", src.Name, moveTo.Name);
@@ -399,7 +399,7 @@ namespace Acacia.Features.SharedFolders
 
         private void CheckSharedFolderRename(IFolder folder)
         { 
-            if (folder.SyncId != null && folder.SyncId.IsShared)
+            if (folder.SyncId != null && folder.SyncId.IsCustom)
             {
                 string originalName = (string)folder.GetProperty(OutlookConstants.PR_ZPUSH_NAME);
                 // The folder.name property is sometimes cached, check against the MAPI property
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/RemindersQuery.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/RemindersQuery.cs
index dce9cf5..f6d4966 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/RemindersQuery.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/RemindersQuery.cs
@@ -17,7 +17,8 @@ namespace Acacia.Features.SharedFolders
         private readonly FeatureSharedFolders _feature;
         private readonly IFolder _folder;
         private SearchQuery _queryRoot;
-        private SearchQuery.Or _queryCustom;
+        private SearchQuery.Or _queryCustomShared;
+        private SearchQuery.Or _queryCustomConfigured;
         private bool _queryCustomModified;
 
         public RemindersQuery(FeatureSharedFolders feature, IStore store)
@@ -28,7 +29,7 @@ namespace Acacia.Features.SharedFolders
 
         public bool Open()
         {
-            if (_queryCustom != null)
+            if (_queryCustomShared != null && _queryCustomConfigured != null)
                 return true;
             try
             {
@@ -39,30 +40,34 @@ namespace Acacia.Features.SharedFolders
 
                 SearchQuery.And root = (SearchQuery.And)_queryRoot;
                 // TODO: more strict checking of query
-                if (root.Operands.Count == 3)
+                if (root.Operands.Count == 5)
                 {
-                    this._queryCustom = root.Operands.ElementAt(2) as SearchQuery.Or;
-                    if (this._queryCustom != null)
+                    this._queryCustomShared = root.Operands.ElementAt(2) as SearchQuery.Or;
+                    this._queryCustomConfigured = root.Operands.ElementAt(3) as SearchQuery.Or;
+                    if (this._queryCustomShared != null)
                     {
                         // TODO: check property test
                         return true;
                     }
                 }
+                else if (root.Operands.Count == 3)
+                {
+                    // KOE-98 introduced also checking of G and C prefixes, which are not yet present
+                    _queryCustomShared = root.Operands.ElementAt(2) as SearchQuery.Or;
+                }
 
                 // We have the root, but not the custom query. Create it.
                 Logger.Instance.Debug(this, "Creating custom query");
-                _queryCustom = new SearchQuery.Or();
-
-                // Add the prefix exclusion for shared folders
-                _queryCustom.Add(
-                    new SearchQuery.Not(
-                        new SearchQuery.PropertyContent(
-                            PROP_FOLDER, SearchQuery.ContentMatchOperation.Prefix, SearchQuery.ContentMatchModifiers.None, "S"
-                        )
+                if (_queryCustomShared == null)
+                    _queryCustomShared = AddCustomQuery(root, "S");
+                _queryCustomConfigured = AddCustomQuery(root, "C");
+                // Add the G (GAB) exclusion. Folders will never have a flag with this prefix, so it's simpler
+                root.Operands.Add(new SearchQuery.Not(
+                    new SearchQuery.PropertyContent(
+                        PROP_FOLDER, SearchQuery.ContentMatchOperation.Prefix, SearchQuery.ContentMatchModifiers.None, "G"
                     )
-                );
+                ));
 
-                root.Operands.Add(_queryCustom);
                 Logger.Instance.Debug(this, "Modified query:\n{0}", root.ToString());
                 // Store it
                 FolderQuery = root;
@@ -72,7 +77,24 @@ namespace Acacia.Features.SharedFolders
             {
                 Logger.Instance.Error(this, "Exception in Open: {0}", e);
             }
-            return _queryCustom != null;
+            return _queryCustomShared != null && _queryCustomConfigured != null;
+        }
+
+        private SearchQuery.Or AddCustomQuery(SearchQuery.And root, string prefix)
+        {
+            SearchQuery.Or custom = new SearchQuery.Or();
+
+            // Add the prefix exclusion
+            custom.Add(
+                new SearchQuery.Not(
+                    new SearchQuery.PropertyContent(
+                        PROP_FOLDER, SearchQuery.ContentMatchOperation.Prefix, SearchQuery.ContentMatchModifiers.None, prefix
+                    )
+                )
+            );
+
+            root.Operands.Add(custom);
+            return custom;
         }
 
         public string LogContextId
@@ -117,15 +139,28 @@ namespace Acacia.Features.SharedFolders
 
         public void UpdateReminders(SyncId folderId, bool wantReminders)
         {
-            Logger.Instance.Trace(this, "Setting reminders for folder {0}: {1}", wantReminders, folderId);
+            Logger.Instance.Trace(this, "Setting reminders for folder {0}: {1} ({2})", wantReminders, folderId, folderId?.Kind);
+            switch(folderId.Kind)
+            {
+                case SyncKind.Configured:
+                    UpdateReminders(_queryCustomConfigured, folderId, wantReminders);
+                    break;
+                case SyncKind.Shared:
+                    UpdateReminders(_queryCustomShared, folderId, wantReminders);
+                    break;
+            }
+        }
+
+        private void UpdateReminders(SearchQuery.Or query, SyncId folderId, bool wantReminders)
+        {
             string prefix = MakeFolderPrefix(folderId);
             if (prefix == null)
                 return;
 
             // Find existing
-            for (int i = 0; i < _queryCustom.Operands.Count;)
+            for (int i = 0; i < query.Operands.Count;)
             {
-                SearchQuery.PropertyContent element = _queryCustom.Operands[i] as SearchQuery.PropertyContent;
+                SearchQuery.PropertyContent element = query.Operands[i] as SearchQuery.PropertyContent;
                 if (element != null && prefix == (string)element.Content)
                 {
                     Logger.Instance.Trace(this, "Found at {0}: {1}", i, folderId);
@@ -134,7 +169,8 @@ namespace Acacia.Features.SharedFolders
                         return;
 
                     // Otherwise remove it. Still continue looking for others, just in case of duplicates
-                    _queryCustom.Operands.RemoveAt(i);
+                    query.Operands.RemoveAt(i);
+                    _queryCustomModified = true;
                 }
                 else ++i;
             }
@@ -143,7 +179,7 @@ namespace Acacia.Features.SharedFolders
             if (wantReminders)
             {
                 Logger.Instance.Trace(this, "Adding reminders for {0}", folderId);
-                _queryCustom.Operands.Add(new SearchQuery.PropertyContent(
+                query.Operands.Add(new SearchQuery.PropertyContent(
                     PROP_FOLDER, SearchQuery.ContentMatchOperation.Prefix, SearchQuery.ContentMatchModifiers.None, prefix
                 ));
                 _queryCustomModified = true;
@@ -152,19 +188,37 @@ namespace Acacia.Features.SharedFolders
 
         public void RemoveStaleReminders(IEnumerable wanted)
         {
-            // Collect the valid prefixes
-            HashSet prefixes = new HashSet();
+            // Group the valid prefixes on type
+            HashSet prefixesS = new HashSet();
+            HashSet prefixesC = new HashSet();
             foreach (SyncId id in wanted)
             {
                 string prefix = MakeFolderPrefix(id);
                 if (prefix != null)
-                    prefixes.Add(prefix);
+                {
+                    switch (id.Kind)
+                    {
+                        case SyncKind.Configured:
+                            prefixesC.Add(prefix);
+                            break;
+                        case SyncKind.Shared:
+                            prefixesS.Add(prefix);
+                            break;
+                    }
+                }
             }
 
+            // Update the queries
+            RemoveStaleReminders(prefixesS, _queryCustomShared);
+            RemoveStaleReminders(prefixesC, _queryCustomConfigured);
+        }
+
+        private void RemoveStaleReminders(ISet prefixes, SearchQuery.Or query)
+        { 
             // Remove all operands for which we do not want the prefix
-            for (int i = 0; i < _queryCustom.Operands.Count;)
+            for (int i = 0; i < query.Operands.Count;)
             {
-                SearchQuery.PropertyContent element = _queryCustom.Operands[i] as SearchQuery.PropertyContent;
+                SearchQuery.PropertyContent element = query.Operands[i] as SearchQuery.PropertyContent;
                 if (element != null)
                 {
                     string prefix = (string)element.Content;
@@ -175,7 +229,7 @@ namespace Acacia.Features.SharedFolders
                     }
 
                     Logger.Instance.Trace(this, "Unwanted prefix at {0}: {1}", i, prefix);
-                    _queryCustom.Operands.RemoveAt(i);
+                    query.Operands.RemoveAt(i);
                     _queryCustomModified = true;
                 }
                 else ++i;
@@ -186,7 +240,7 @@ namespace Acacia.Features.SharedFolders
         {
             // Sanity check. The check for shared folders also excludes any weird ids; e.g. if permissions are wrong,
             // this will not be a sync id, but a backend id.
-            if (folderId == null || !folderId.IsShared)
+            if (folderId == null || !folderId.IsCustom)
                 return null;
             return folderId.ToString() + ":";
         }
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushTypes.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushTypes.cs
index fbbeadc..a5bd0ad 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushTypes.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushTypes.cs
@@ -69,6 +69,14 @@ namespace Acacia.ZPush
         #endregion
     }
 
+    public enum SyncKind
+    {
+        Normal,
+        Shared,
+        Configured,
+        GAB
+    }
+
     public class SyncId : ZPushId
     {
         public static readonly SyncId NONE = new SyncId("0");
@@ -76,10 +84,24 @@ namespace Acacia.ZPush
         public SyncId(string id) : base(id) { }
         public SyncId(int id) : base(id) { }
 
+
+        public SyncKind Kind
+        {
+            get
+            {
+                if (_id.StartsWith("S"))
+                    return SyncKind.Shared;
+                if (_id.StartsWith("C"))
+                    return SyncKind.Configured;
+                if (_id.StartsWith("G"))
+                    return SyncKind.GAB;
+                return SyncKind.Normal;
+            }
+        }
         /// 
         /// Checks if this is a SyncId for a shared folders
         /// 
-        public bool IsShared { get { return _id.StartsWith("S") || _id.StartsWith("C") || _id.StartsWith("G"); } }
+        public bool IsCustom { get { return Kind != SyncKind.Normal; } }
 
         #region Standard overrides
 
From be5d6986541f899d859aecac35fc843969ad3ba8 Mon Sep 17 00:00:00 2001
From: Patrick Simpson 
Date: Wed, 8 Nov 2017 12:53:57 +0200
Subject: [PATCH 3/6] [KOE-139] Added tooltips and support for disabling tree
 nodes in shared folders dialog, to support configured folders
---
 .../AcaciaZPushPlugin/Controls/KTree.cs       | 25 +++++++------------
 .../AcaciaZPushPlugin/Controls/KTreeNode.cs   |  1 +
 .../Features/SharedFolders/FolderTreeNode.cs  |  3 +++
 .../SharedFolders/SharedFoldersDialog.cs      | 11 +++++++-
 .../SharedFolders/SharedFoldersDialog.resx    |  2 +-
 .../Features/SharedFolders/StoreTreeNode.cs   | 13 +++++++++-
 .../Properties/Resources.Designer.cs          | 10 ++++++++
 .../Properties/Resources.resx                 |  4 +++
 8 files changed, 50 insertions(+), 19 deletions(-)
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTree.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTree.cs
index a4b3d1d..cbcd617 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTree.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTree.cs
@@ -56,7 +56,7 @@ namespace Acacia.Controls
                 CheckStateChanged(this, new CheckStateChangedEventArgs(node));
             }
         }
-
+        private ToolTip toolTip;
         private KCheckManager _checkManager;
         [Browsable(false)]
         public KCheckManager CheckManager
@@ -181,6 +181,8 @@ namespace Acacia.Controls
             SetStyle(ControlStyles.Selectable, true);
             BackColor = SystemColors.Window;
 
+            toolTip = new ToolTip();
+
             _rootNodes = new KTreeNodes(this);
             SetupRenderer();
             InitScrollBars();
@@ -449,6 +451,12 @@ namespace Acacia.Controls
                 // Render new node
                 if (_highlightNode != null)
                     Rerender(_highlightNode);
+
+                // Update any tooltips
+                if (old?.ToolTip != null)
+                    toolTip.SetToolTip(this, null);
+                if (_highlightNode?.ToolTip != null)
+                    toolTip.SetToolTip(this, _highlightNode.ToolTip);
             }
         }
 
@@ -1147,20 +1155,5 @@ namespace Acacia.Controls
 
 
         #endregion
-
-        #region Winforms Autogenerated
-
-        private void InitializeComponent()
-        {
-            this.SuspendLayout();
-            // 
-            // KTree
-            // 
-            this.Name = "KTree";
-            this.ResumeLayout(false);
-        }
-
-        #endregion
-
     }
 }
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTreeNode.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTreeNode.cs
index 0d69747..83183b7 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTreeNode.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTreeNode.cs
@@ -64,6 +64,7 @@ namespace Acacia.Controls
 
         public int? ImageIndex { get; set; }
         public object Tag { get; set; }
+        public string ToolTip { get; set; }
 
         #endregion
 
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/FolderTreeNode.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/FolderTreeNode.cs
index 16c3230..f1efeda 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/FolderTreeNode.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/FolderTreeNode.cs
@@ -30,6 +30,7 @@ namespace Acacia.Features.SharedFolders
         private readonly StoreTreeNode _store;
         private readonly AvailableFolder _folder;
         private SharedFolder _share;
+        public bool IsReadOnly { get { return _store.IsReadOnly; } }
 
         public FolderTreeNode(StoreTreeNode store, AvailableFolder folder, SharedFolder share)
         {
@@ -39,6 +40,8 @@ namespace Acacia.Features.SharedFolders
 
             this.Text = folder.Name;
 
+            HasCheckBox = !IsReadOnly;
+
             // Image
             // TODO: clean this up
             int index = ((int)OutlookConstants.BASIC_SYNC_TYPES[(int)folder.Type]) - 1;
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.cs
index 9d0f93d..efce1de 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.cs
@@ -261,7 +261,8 @@ 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(),
+                                         false);
                 node.DirtyChanged += UserSharesChanged;
                 _userFolders.Add(user, node);
                 kTreeFolders.RootNodes.Add(node);
@@ -409,6 +410,7 @@ namespace Acacia.Features.SharedFolders
                 OptionSendAs = null;
                 OptionReminders = null;
                 OptionPermissions = null;
+                bool readOnly = false;
 
                 foreach (KTreeNode node in nodes)
                 {
@@ -421,6 +423,10 @@ namespace Acacia.Features.SharedFolders
                     if (!folderNode.IsShared)
                         continue;
 
+                    // Set all controls to read-only if any of the nodes is read-only
+                    if (folderNode.IsReadOnly)
+                        readOnly = true;
+
                     SharedFolder share = folderNode.SharedFolder;
                     AvailableFolder folder = folderNode.AvailableFolder;
 
@@ -497,6 +503,9 @@ namespace Acacia.Features.SharedFolders
                         checkReminders.ThreeState = true;
                     }
                 }
+
+                // Apply read-only state
+                _layoutOptions.Enabled = !readOnly;
             }
             finally
             {
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.resx b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.resx
index a3eb232..79c73f4 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.resx
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.resx
@@ -607,7 +607,7 @@
     2
   
   
-    <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="_labelName" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="textName" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="_labelSendAs" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="checkSendAs" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="_labelReminders" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="checkReminders" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="_labelPermissions" Row="3" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="labelPermissionsValue" Row="3" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,Percent,100" /><Rows Styles="AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0" /></TableLayoutSettings>
+    <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="_labelName" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="textName" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="_labelSendAs" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="checkSendAs" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="_labelReminders" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="checkReminders" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="_labelPermissions" Row="3" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="labelPermissionsValue" Row="3" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,Percent,100" /><Rows Styles="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 d7b57c3..4f8733f 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/StoreTreeNode.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/StoreTreeNode.cs
@@ -46,8 +46,11 @@ namespace Acacia.Features.SharedFolders
         private readonly GABHandler _gab;
         private readonly GABUser _user;
 
+        public readonly bool IsReadOnly;
+
         public StoreTreeNode(SharedFoldersManager folders, GABHandler gab, GABUser user, string text, 
-                             Dictionary currentFolders)
+                             Dictionary currentFolders,
+                             bool readOnly)
         :
         base(text)
         {
@@ -55,6 +58,7 @@ namespace Acacia.Features.SharedFolders
             this._feature = folders.Feature;
             this._gab = gab;
             this._user = user;
+            this.IsReadOnly = readOnly;
 
             // 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.
@@ -63,6 +67,7 @@ namespace Acacia.Features.SharedFolders
             ChildLoader = new UserFolderLoader(this, folders, user);
             ChildLoader.ReloadOnCloseOpen = true;
             HasCheckBox = false;
+            ApplyReadOnly(this, IsReadOnly);
 
             // TODO: better icons, better way of handling this
             ImageIndex = user == GABUser.USER_PUBLIC ? 0 : 11;
@@ -78,6 +83,11 @@ namespace Acacia.Features.SharedFolders
             Control = _reloader;
         }
 
+        private static void ApplyReadOnly(KTreeNode node, bool isReadOnly)
+        {
+            node.ToolTip = isReadOnly ? Properties.Resources.SharedFolders_Node_Readonly_ToolTip : null;
+        }
+
         public GABUser User
         {
             get { return ((UserFolderLoader)ChildLoader).User; }
@@ -264,6 +274,7 @@ namespace Acacia.Features.SharedFolders
                 // Create the tree node
                 SharedFolder share = rootNode.GetInitialShareState(folder);
                 FolderTreeNode child = new FolderTreeNode(rootNode, folder, share);
+                ApplyReadOnly(child, child.IsReadOnly);
 
                 // Add
                 children.Add(child);
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Properties/Resources.Designer.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Properties/Resources.Designer.cs
index 1e86f86..112e362 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Properties/Resources.Designer.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Properties/Resources.Designer.cs
@@ -1093,6 +1093,16 @@ namespace Acacia.Properties {
             }
         }
         
+        /// 
+        ///   Looks up a localized string similar to The folder has been configured by your system administrator and cannot be modified. 
+        ///Please contact your system administrator for any required changes..
+        /// 
+        internal static string SharedFolders_Node_Readonly_ToolTip {
+            get {
+                return ResourceManager.GetString("SharedFolders_Node_Readonly_ToolTip", resourceCulture);
+            }
+        }
+        
         /// 
         ///   Looks up a localized string similar to No shared folders are available or you do not have permissions to view the root of the inbox..
         /// 
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Properties/Resources.resx b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Properties/Resources.resx
index 0c60b45..a714232 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Properties/Resources.resx
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Properties/Resources.resx
@@ -520,4 +520,8 @@
   
     Shared folders
   
+  
+    The folder has been configured by your system administrator and cannot be modified. 
+Please contact your system administrator for any required changes.
+  
 
\ No newline at end of file
From 7404b15d7a69fea343d2791a870b776330560fc0 Mon Sep 17 00:00:00 2001
From: Patrick Simpson 
Date: Wed, 8 Nov 2017 13:26:01 +0200
Subject: [PATCH 4/6] [KOE-149] Setting displayName later in GAB syncing, to
 prevent Outlook from constructing its own version.
---
 .../AcaciaZPushPlugin/Features/GAB/GABHandler.cs                | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/GAB/GABHandler.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/GAB/GABHandler.cs
index aba773c..5e0372e 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/GAB/GABHandler.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/GAB/GABHandler.cs
@@ -515,11 +515,11 @@ namespace Acacia.Features.GAB
                 contact.CustomerID = id;
 
                 // Create the contact data
-                if (Get(value, "displayName") != null) contact.FullName = Get(value, "displayName");
                 if (Get(value, "givenName") != null) contact.FirstName = Get(value, "givenName");
                 if (Get(value, "initials") != null) contact.Initials = Get(value, "initials");
                 if (Get(value, "surname") != null) contact.LastName = Get(value, "surname");
                 if (Get(value, "title") != null) contact.JobTitle = Get(value, "title");
+                if (Get(value, "displayName") != null) contact.FullName = Get(value, "displayName");
 
                 if (Get(value, "smtpAddress") != null)
                 {
From b82e2ef8391c284e9287b91347aee894c1d67fa0 Mon Sep 17 00:00:00 2001
From: Patrick Simpson 
Date: Wed, 8 Nov 2017 14:39:52 +0200
Subject: [PATCH 5/6] [KOE-139] SharedFolderDialog now sets read-only flag on
 statically configured shared folders.
---
 .../AcaciaZPushPlugin/Controls/KTree.cs            |  2 +-
 .../AcaciaZPushPlugin/Controls/KTreeNode.cs        | 14 ++++++++++++++
 .../AcaciaZPushPlugin/Controls/KTreeRenderer.cs    |  8 +++++---
 .../Features/SharedFolders/FolderTreeNode.cs       |  6 ++++--
 .../Features/SharedFolders/SharedFoldersDialog.cs  |  3 +--
 .../Features/SharedFolders/StoreTreeNode.cs        |  5 ++---
 6 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTree.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTree.cs
index cbcd617..7425f32 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTree.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTree.cs
@@ -97,7 +97,7 @@ namespace Acacia.Controls
 
         private void ToggleCheck(KTreeNode node)
         {
-            if (_checkManager == null || node == null)
+            if (_checkManager == null || node == null || !node.CheckBoxEnabled)
                 return;
 
             if (!SelectedNodes.Contains(node) || SelectedNodes.Count == 1)
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTreeNode.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTreeNode.cs
index 83183b7..d0a19b9 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTreeNode.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTreeNode.cs
@@ -127,6 +127,20 @@ namespace Acacia.Controls
             }
         }
 
+        private bool _checkBoxEnabled = true;
+        public bool CheckBoxEnabled
+        {
+            get { return _checkBoxEnabled; }
+            set
+            {
+                if (_checkBoxEnabled != value)
+                {
+                    _checkBoxEnabled = value;
+                    Owner?.Rerender(this);
+                }
+            }
+        }
+
         private bool _isExpanded;
         public bool IsExpanded
         {
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTreeRenderer.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTreeRenderer.cs
index 21c274c..787b49e 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTreeRenderer.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KTreeRenderer.cs
@@ -132,7 +132,7 @@ namespace Acacia.Controls
             // Checkbox
             if (_tree.CheckManager != null && node.HasCheckBox)
             {
-                RenderCheckBox(graphics, node, dims.GetPartRect(KTreeNodeMeasurements.Part.CheckBox, true), highlight);
+                RenderCheckBox(graphics, node, dims.GetPartRect(KTreeNodeMeasurements.Part.CheckBox, true), highlight, node.CheckBoxEnabled);
             }
 
             // Images
@@ -159,10 +159,12 @@ namespace Acacia.Controls
         protected abstract void RenderNodeOutline(Graphics graphics, KTreeNode node, Rectangle rect, KTreeNodeMeasurements.Part? highlight);
         internal protected abstract void RenderNodeExpander(Graphics graphics, KTreeNode node, Rectangle rect, KTreeNodeMeasurements.Part? highlight);
 
-        protected virtual void RenderCheckBox(Graphics graphics, KTreeNode node, Rectangle rect, KTreeNodeMeasurements.Part? highlight)
+        protected virtual void RenderCheckBox(Graphics graphics, KTreeNode node, Rectangle rect, KTreeNodeMeasurements.Part? highlight, bool enabled)
         {
             int state = (int)node.CheckState * 4 + 1;
-            if (highlight != null && highlight.Value == KTreeNodeMeasurements.Part.CheckBox)
+            if (!enabled)
+                state += 3;
+            else if (highlight != null && highlight.Value == KTreeNodeMeasurements.Part.CheckBox)
                 state += 1;
 
             CheckBoxRenderer.DrawCheckBox(graphics, rect.Location, (CheckBoxState)state);
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/FolderTreeNode.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/FolderTreeNode.cs
index f1efeda..8f53e69 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/FolderTreeNode.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/FolderTreeNode.cs
@@ -30,7 +30,7 @@ namespace Acacia.Features.SharedFolders
         private readonly StoreTreeNode _store;
         private readonly AvailableFolder _folder;
         private SharedFolder _share;
-        public bool IsReadOnly { get { return _store.IsReadOnly; } }
+        public readonly bool IsReadOnly;
 
         public FolderTreeNode(StoreTreeNode store, AvailableFolder folder, SharedFolder share)
         {
@@ -40,7 +40,9 @@ namespace Acacia.Features.SharedFolders
 
             this.Text = folder.Name;
 
-            HasCheckBox = !IsReadOnly;
+            IsReadOnly = share?.SyncId?.Kind == SyncKind.Configured;
+            HasCheckBox = true;
+            CheckBoxEnabled = !IsReadOnly;
 
             // Image
             // TODO: clean this up
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.cs
index efce1de..444f876 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/SharedFoldersDialog.cs
@@ -261,8 +261,7 @@ namespace Acacia.Features.SharedFolders
 
                 // Add the node
                 node = new StoreTreeNode(_folders, gabLookup.GAB,
-                                         user, user.DisplayName, currentShares ?? new Dictionary(),
-                                         false);
+                                         user, user.DisplayName, currentShares ?? new Dictionary());
                 node.DirtyChanged += UserSharesChanged;
                 _userFolders.Add(user, node);
                 kTreeFolders.RootNodes.Add(node);
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/StoreTreeNode.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/StoreTreeNode.cs
index 4f8733f..a42b327 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/StoreTreeNode.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SharedFolders/StoreTreeNode.cs
@@ -49,8 +49,7 @@ namespace Acacia.Features.SharedFolders
         public readonly bool IsReadOnly;
 
         public StoreTreeNode(SharedFoldersManager folders, GABHandler gab, GABUser user, string text, 
-                             Dictionary currentFolders,
-                             bool readOnly)
+                             Dictionary currentFolders)
         :
         base(text)
         {
@@ -58,7 +57,7 @@ namespace Acacia.Features.SharedFolders
             this._feature = folders.Feature;
             this._gab = gab;
             this._user = user;
-            this.IsReadOnly = readOnly;
+            this.IsReadOnly = false;
 
             // 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.
From a9a24208882734f7f3b133d4b981e11c62b2a2c9 Mon Sep 17 00:00:00 2001
From: KOE_Export_Strings_Commit 
Date: Wed, 8 Nov 2017 12:42:24 +0100
Subject: [PATCH 6/6] Commit strings #237
---
 translations/KOE.pot  |  8 ++++++++
 translations/de.po    |  8 ++++++++
 translations/en.po    | 10 ++++++++++
 translations/fr.po    |  8 ++++++++
 translations/hu.po    |  8 ++++++++
 translations/it.po    |  8 ++++++++
 translations/nb.po    |  8 ++++++++
 translations/nl.po    | 16 +++++++++++-----
 translations/pt_br.po |  8 ++++++++
 9 files changed, 77 insertions(+), 5 deletions(-)
diff --git a/translations/KOE.pot b/translations/KOE.pot
index 816f726..ac07a09 100644
--- a/translations/KOE.pot
+++ b/translations/KOE.pot
@@ -1057,6 +1057,14 @@ msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\SharedFolders_LocalFolder_Tit
 msgid "Shared folders"
 msgstr ""
 
+#: AcaciaZPushPlugin\Properties\Resources\SharedFolders_Node_Readonly_ToolTip
+#, csharp-format
+msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\SharedFolders_Node_Readonly_ToolTip"
+msgid ""
+"The folder has been configured by your system administrator and cannot be modified. \n"
+"Please contact your system administrator for any required changes."
+msgstr ""
+
 #: AcaciaZPushPlugin\UI\ProgressDialog\labelMessage.Text
 #, csharp-format
 msgctxt "AcaciaZPushPlugin\\UI\\ProgressDialog\\labelMessage.Text"
diff --git a/translations/de.po b/translations/de.po
index f45bf8b..92e426d 100644
--- a/translations/de.po
+++ b/translations/de.po
@@ -1379,3 +1379,11 @@ msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\SharedFolders_LocalFolder_Tit
 msgid "Shared folders"
 msgstr ""
 
+#: AcaciaZPushPlugin\Properties\Resources\SharedFolders_Node_Readonly_ToolTip
+#, csharp-format
+msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\SharedFolders_Node_Readonly_ToolTip"
+msgid ""
+"The folder has been configured by your system administrator and cannot be modified. \n"
+"Please contact your system administrator for any required changes."
+msgstr ""
+
diff --git a/translations/en.po b/translations/en.po
index 78c9e13..2ba8772 100644
--- a/translations/en.po
+++ b/translations/en.po
@@ -1059,6 +1059,16 @@ msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\SharedFolders_LocalFolder_Tit
 msgid "Shared folders"
 msgstr "Shared folders"
 
+#: AcaciaZPushPlugin\Properties\Resources\SharedFolders_Node_Readonly_ToolTip
+#, csharp-format
+msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\SharedFolders_Node_Readonly_ToolTip"
+msgid ""
+"The folder has been configured by your system administrator and cannot be modified. \n"
+"Please contact your system administrator for any required changes."
+msgstr ""
+"The folder has been configured by your system administrator and cannot be modified. \n"
+"Please contact your system administrator for any required changes."
+
 #: AcaciaZPushPlugin\UI\ProgressDialog\labelMessage.Text
 #, csharp-format
 msgctxt "AcaciaZPushPlugin\\UI\\ProgressDialog\\labelMessage.Text"
diff --git a/translations/fr.po b/translations/fr.po
index 3315e54..b90fa9e 100644
--- a/translations/fr.po
+++ b/translations/fr.po
@@ -1377,3 +1377,11 @@ msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\SharedFolders_LocalFolder_Tit
 msgid "Shared folders"
 msgstr ""
 
+#: AcaciaZPushPlugin\Properties\Resources\SharedFolders_Node_Readonly_ToolTip
+#, csharp-format
+msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\SharedFolders_Node_Readonly_ToolTip"
+msgid ""
+"The folder has been configured by your system administrator and cannot be modified. \n"
+"Please contact your system administrator for any required changes."
+msgstr ""
+
diff --git a/translations/hu.po b/translations/hu.po
index ca11fdd..d5dd2cc 100644
--- a/translations/hu.po
+++ b/translations/hu.po
@@ -1380,3 +1380,11 @@ msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\SharedFolders_LocalFolder_Tit
 msgid "Shared folders"
 msgstr ""
 
+#: AcaciaZPushPlugin\Properties\Resources\SharedFolders_Node_Readonly_ToolTip
+#, csharp-format
+msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\SharedFolders_Node_Readonly_ToolTip"
+msgid ""
+"The folder has been configured by your system administrator and cannot be modified. \n"
+"Please contact your system administrator for any required changes."
+msgstr ""
+
diff --git a/translations/it.po b/translations/it.po
index bcefe08..4796625 100644
--- a/translations/it.po
+++ b/translations/it.po
@@ -1344,3 +1344,11 @@ msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\SharedFolders_LocalFolder_Tit
 msgid "Shared folders"
 msgstr ""
 
+#: AcaciaZPushPlugin\Properties\Resources\SharedFolders_Node_Readonly_ToolTip
+#, csharp-format
+msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\SharedFolders_Node_Readonly_ToolTip"
+msgid ""
+"The folder has been configured by your system administrator and cannot be modified. \n"
+"Please contact your system administrator for any required changes."
+msgstr ""
+
diff --git a/translations/nb.po b/translations/nb.po
index c884a1b..fa2983c 100644
--- a/translations/nb.po
+++ b/translations/nb.po
@@ -1132,3 +1132,11 @@ msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\SharedFolders_LocalFolder_Tit
 msgid "Shared folders"
 msgstr ""
 
+#: AcaciaZPushPlugin\Properties\Resources\SharedFolders_Node_Readonly_ToolTip
+#, csharp-format
+msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\SharedFolders_Node_Readonly_ToolTip"
+msgid ""
+"The folder has been configured by your system administrator and cannot be modified. \n"
+"Please contact your system administrator for any required changes."
+msgstr ""
+
diff --git a/translations/nl.po b/translations/nl.po
index 33bfeb2..3f209ab 100644
--- a/translations/nl.po
+++ b/translations/nl.po
@@ -4,8 +4,7 @@ msgstr ""
 "POT-Creation-Date: \n"
 "PO-Revision-Date: 2017-11-03 10:55+0000\n"
 "Last-Translator: Bob \n"
-"Language-Team: Dutch \n"
+"Language-Team: Dutch \n"
 "Language: nl\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=iso-8859-1\n"
@@ -1372,12 +1371,19 @@ msgstr "Kopieer filter"
 #, csharp-format
 msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\SharedFolders_LocalFolder_Body"
 msgid "Modifying shared folders locally is not supported. Please use the 'Shared Folders' dialog to modify these folders."
-msgstr ""
-"Het lokaal aanpassen van gedeelde mappen word niet ondersteund. Gebruik het "
-"venster 'Gedeelde Mappen' om deze mappen aan te passen."
+msgstr "Het lokaal aanpassen van gedeelde mappen word niet ondersteund. Gebruik het venster 'Gedeelde Mappen' om deze mappen aan te passen."
 
 #: AcaciaZPushPlugin\Properties\Resources\SharedFolders_LocalFolder_Title
 #, csharp-format
 msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\SharedFolders_LocalFolder_Title"
 msgid "Shared folders"
 msgstr "Gedeelde mappen"
+
+#: AcaciaZPushPlugin\Properties\Resources\SharedFolders_Node_Readonly_ToolTip
+#, csharp-format
+msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\SharedFolders_Node_Readonly_ToolTip"
+msgid ""
+"The folder has been configured by your system administrator and cannot be modified. \n"
+"Please contact your system administrator for any required changes."
+msgstr ""
+
diff --git a/translations/pt_br.po b/translations/pt_br.po
index 7b750e7..33f3bab 100644
--- a/translations/pt_br.po
+++ b/translations/pt_br.po
@@ -1134,3 +1134,11 @@ msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\SharedFolders_LocalFolder_Tit
 msgid "Shared folders"
 msgstr ""
 
+#: AcaciaZPushPlugin\Properties\Resources\SharedFolders_Node_Readonly_ToolTip
+#, csharp-format
+msgctxt "AcaciaZPushPlugin\\Properties\\Resources\\SharedFolders_Node_Readonly_ToolTip"
+msgid ""
+"The folder has been configured by your system administrator and cannot be modified. \n"
+"Please contact your system administrator for any required changes."
+msgstr ""
+