External/Aga.Controls/Tree/IncrementalSearch.cs
author sl
Thu, 01 Jan 2015 23:35:49 +0100
changeset 405 5715aefd2bcc
permissions -rw-r--r--
SharpDisplay: Migrating to new robust client scheme.
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Text;
     4 using Aga.Controls.Tree.NodeControls;
     5 using System.ComponentModel;
     6 using System.Drawing;
     7 using System.Windows.Forms;
     8 
     9 namespace Aga.Controls.Tree
    10 {
    11 	internal class IncrementalSearch
    12 	{
    13 		private const int SearchTimeout = 300; //end of incremental search timeot in msec
    14 
    15 		private TreeViewAdv _tree;
    16 		private TreeNodeAdv _currentNode;
    17 		private string _searchString = "";
    18 		private DateTime _lastKeyPressed = DateTime.Now;
    19 
    20 		public IncrementalSearch(TreeViewAdv tree)
    21 		{
    22 			_tree = tree;
    23 		}
    24 
    25 		public void Search(Char value)
    26 		{
    27 			if (!Char.IsControl(value))
    28 			{
    29 				Char ch = Char.ToLowerInvariant(value);
    30 				DateTime dt = DateTime.Now;
    31 				TimeSpan ts = dt - _lastKeyPressed;
    32 				_lastKeyPressed = dt;
    33 				if (ts.TotalMilliseconds < SearchTimeout)
    34 				{
    35 					if (_searchString == value.ToString())
    36 						FirstCharSearch(ch);
    37 					else
    38 						ContinuousSearch(ch);
    39 				}
    40 				else
    41 				{
    42 					FirstCharSearch(ch);
    43 				}
    44 			}
    45 		}
    46 
    47 		private void ContinuousSearch(Char value)
    48 		{
    49 			if (value == ' ' && String.IsNullOrEmpty(_searchString))
    50 				return; //Ingnore leading space
    51 
    52 			_searchString += value;
    53 			DoContinuousSearch();
    54 		}
    55 
    56 		private void FirstCharSearch(Char value)
    57 		{
    58 			if (value == ' ')
    59 				return;
    60 
    61 			_searchString = value.ToString();
    62 			TreeNodeAdv node = null;
    63 			if (_tree.SelectedNode != null)
    64 				node = _tree.SelectedNode.NextVisibleNode;
    65 			if (node == null)
    66 				node = _tree.Root.NextVisibleNode;
    67 
    68 			if (node != null)
    69 				foreach (string label in IterateNodeLabels(node))
    70 				{
    71 					if (label.StartsWith(_searchString))
    72 					{
    73 						_tree.SelectedNode = _currentNode;
    74 						return;
    75 					}
    76 				}
    77 		}
    78 
    79 		public virtual void EndSearch()
    80 		{
    81 			_currentNode = null;
    82 			_searchString = "";
    83 		}
    84 
    85 		protected IEnumerable<string> IterateNodeLabels(TreeNodeAdv start)
    86 		{
    87 			_currentNode = start;
    88 			while(_currentNode != null)
    89 			{
    90 				foreach (string label in GetNodeLabels(_currentNode))
    91 					yield return label;
    92 
    93 				_currentNode = _currentNode.NextVisibleNode;
    94 				if (_currentNode == null)
    95 					_currentNode = _tree.Root;
    96 
    97 				if (start == _currentNode)
    98 					break;
    99 			} 
   100 		}
   101 
   102 		private IEnumerable<string> GetNodeLabels(TreeNodeAdv node)
   103 		{
   104 			foreach (NodeControl nc in _tree.NodeControls)
   105 			{
   106 				BindableControl bc = nc as BindableControl;
   107 				if (bc != null && bc.IncrementalSearchEnabled)
   108 				{
   109 					object obj = bc.GetValue(node);
   110 					if (obj != null)
   111 						yield return obj.ToString().ToLowerInvariant();
   112 				}
   113 			}
   114 		}
   115 
   116 		private bool DoContinuousSearch()
   117 		{
   118 			bool found = false;
   119 			if (!String.IsNullOrEmpty(_searchString))
   120 			{
   121 				TreeNodeAdv node = null;
   122 				if (_tree.SelectedNode != null)
   123 					node = _tree.SelectedNode;
   124 				if (node == null)
   125 					node = _tree.Root.NextVisibleNode;
   126 
   127 				if (!String.IsNullOrEmpty(_searchString))
   128 				{
   129 					foreach (string label in IterateNodeLabels(node))
   130 					{
   131 						if (label.StartsWith(_searchString))
   132 						{
   133 							found = true;
   134 							_tree.SelectedNode = _currentNode;
   135 							break;
   136 						}
   137 					}
   138 				}
   139 			}
   140 			return found;
   141 		}
   142 
   143 	}
   144 }