diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KDataSource.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KDataSource.cs index 6c416c5..fc89f30 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KDataSource.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KDataSource.cs @@ -19,7 +19,6 @@ namespace Acacia.Controls public interface KDataSourceRaw { - System.Collections.IEnumerable Items { get; } System.Collections.IEnumerable FilteredItems { get; } KDataFilter Filter { get; set; } string GetItemText(object item); @@ -28,39 +27,30 @@ namespace Acacia.Controls abstract public class KDataSource : KDataSourceRaw { - /// - /// Returns all the items - /// - abstract public IEnumerable Items + private KDataFilter _filter; + + public KDataFilter Filter + { + get { return _filter; } + set + { + _filter = value; + UpdateFilter(); + } + } + + public bool HasFilter + { + get { return _filter?.FilterText != null; } + } + + abstract protected void UpdateFilter(); + + abstract public IEnumerable FilteredItems { get; } - public IEnumerable FilteredItems - { - get - { - if (string.IsNullOrWhiteSpace(Filter?.FilterText)) - return Items; - - return ApplyFilter(); - } - } - - private IEnumerable ApplyFilter() - { - foreach (T item in Items) - { - if (MatchesFilter(item)) - yield return item; - } - } - - virtual protected bool MatchesFilter(T item) - { - return GetItemText(item).StartsWith(Filter.FilterText); - } - abstract protected string GetItemText(T item); public string GetItemText(object item) @@ -68,18 +58,11 @@ namespace Acacia.Controls return GetItemText((T)item); } - public KDataFilter Filter - { - get; - set; - } - virtual public object NotFoundItem { get { return null; } } - IEnumerable KDataSourceRaw.Items { get{return Items;}} IEnumerable KDataSourceRaw.FilteredItems { get { return FilteredItems; } } } } diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/ISearch.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/ISearch.cs index efbdc90..47c0c6a 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/ISearch.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/ISearch.cs @@ -33,7 +33,9 @@ namespace Acacia.Stubs GreaterEqual, Equal, NotEqual, - Like + Like, + StartsWith, + StartsWithCI } public interface ISearchField @@ -61,6 +63,7 @@ namespace Acacia.Stubs public interface ISearch : ISearchQuery, IDisposable where ItemType : IItem { + void Sort(string field, bool descending); IEnumerable Search(int maxResults = int.MaxValue); diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/SearchWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/SearchWrapper.cs index 3262f2b..84b0b07 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/SearchWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/SearchWrapper.cs @@ -121,6 +121,12 @@ namespace Acacia.Stubs.OutlookWrappers case SearchOperation.Like: oper = "like"; break; + case SearchOperation.StartsWith: + oper = "startswith"; + break; + case SearchOperation.StartsWithCI: + oper = "ci_startswith"; + break; default: throw new NotImplementedException(); } @@ -150,7 +156,9 @@ namespace Acacia.Stubs.OutlookWrappers } } - private readonly List terms = new List(); + private readonly List _terms = new List(); + private string _sortField; + private bool _sortDescending; /// /// Constructor. @@ -160,17 +168,23 @@ namespace Acacia.Stubs.OutlookWrappers { } + public void Sort(string field, bool descending) + { + _sortField = field; + _sortDescending = descending; + } + public ISearchOperator AddOperator(SearchOperator oper) { SearchOperatorImpl so = new SearchOperatorImpl(oper); - terms.Add(so); + _terms.Add(so); return so; } public ISearchField AddField(string name, bool isUserField = false) { SearchField field = new SearchField(name, isUserField); - terms.Add(field); + _terms.Add(field); return field; } @@ -178,6 +192,11 @@ namespace Acacia.Stubs.OutlookWrappers { string filter = MakeFilter(); + if (_sortField != null) + { + _item.Sort(_sortField, _sortDescending); + } + int count = 0; object value = _item.Find(filter); while(value != null) @@ -222,7 +241,7 @@ namespace Acacia.Stubs.OutlookWrappers string filter = "@SQL="; bool first = true; - foreach(SearchTerm term in terms) + foreach(SearchTerm term in _terms) { if (first) first = false; diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/GABLookupControl.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/GABLookupControl.cs index c662c46..aebb683 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/GABLookupControl.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/GABLookupControl.cs @@ -43,29 +43,61 @@ namespace Acacia.UI private class GABDataSource : KDataSource { private readonly GABHandler _gab; - private readonly List _users; + public int Limit { get; set; } public GABDataSource(GABHandler gab) { this._gab = gab; - - _users = new List(); - foreach (IItem item in _gab.Contacts.Items.Sort("FullName", false)) - { - IContactItem contact = item as IContactItem; - // The check for customer id is to avoid groups created as contacts - if (contact != null && contact.CustomerID != null) - { - _users.Add(new GABUser(contact)); - } - } + Limit = 10; } - public override IEnumerable Items + protected override void UpdateFilter() + { + } + + public override IEnumerable FilteredItems { get { - return _users; + ISearch search = null; + try + { + IEnumerable items; + if (HasFilter) + { + search = _gab.Contacts.Search(); + search.Sort("FullName", false); + ISearchOperator terms = search.AddOperator(SearchOperator.Or); + terms.AddField("urn:schemas:contacts:cn").SetOperation(SearchOperation.Like, Filter.FilterText + "%"); + terms.AddField("urn:schemas:contacts:customerid").SetOperation(SearchOperation.Like, Filter.FilterText + "%"); + terms.AddField("urn:schemas:contacts:email1").SetOperation(SearchOperation.Like, Filter.FilterText + "%"); + items = search.Search(Limit); + } + else + { + items = _gab.Contacts.Items.Sort("FullName", false); + } + + int index = 0; + foreach (IItem item in items) + { + IContactItem contact = item as IContactItem; + // The check for customer id is to avoid groups created as contacts + if (contact != null && contact.CustomerID != null) + { + ++index; + if (index > Limit) + break; + + yield return new GABUser(contact); + } + } + } + finally + { + if (search != null) + search.Dispose(); + } } } @@ -85,15 +117,6 @@ namespace Acacia.UI return item.UserName; } - protected override bool MatchesFilter(GABUser item) - { - string s = Filter.FilterText.ToLower(); - return - item.FullName?.ToLower().StartsWith(s) == true || - item.UserName?.ToLower().StartsWith(s) == true || - item.EmailAddress?.ToLower().StartsWith(s) == true; - } - public override object NotFoundItem { get @@ -202,15 +225,19 @@ namespace Acacia.UI string s = username.ToLower(); if (DataSource != null) { - foreach(GABUser user in DataSource.Items) + using (ISearch search = _gab.Contacts.Search()) { - if ( - user.FullName?.ToLower().Equals(s) == true || - user.UserName?.ToLower().Equals(s) == true || - user.EmailAddress?.ToLower().Equals(s) == true - ) + search.Sort("FullName", false); + ISearchOperator terms = search.AddOperator(SearchOperator.Or); + terms.AddField("urn:schemas:contacts:cn").SetOperation(SearchOperation.Like, username); + terms.AddField("urn:schemas:contacts:customerid").SetOperation(SearchOperation.Like, username); + terms.AddField("urn:schemas:contacts:email1").SetOperation(SearchOperation.Like, username); + using (IContactItem contact = search.SearchOne()) { - return user; + if (contact != null) + { + return new GABUser(contact); + } } } }