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