PageRenderTime 46ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/src/NUnit/UiException/Controls/ErrorList.cs

#
C# | 263 lines | 197 code | 53 blank | 13 comment | 28 complexity | 9d85a6e0f791c7aa75cc66521c39dc18 MD5 | raw file
Possible License(s): GPL-2.0
  1. // ****************************************************************
  2. // This is free software licensed under the NUnit license. You may
  3. // obtain a copy of the license at http://nunit.org
  4. // ****************************************************************
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using System.Drawing;
  10. using System.Diagnostics;
  11. namespace NUnit.UiException.Controls
  12. {
  13. /// <summary>
  14. /// Displays a control which implements IStackTraceView.
  15. /// </summary>
  16. public class ErrorList :
  17. UserControl,
  18. IStackTraceView
  19. {
  20. public event EventHandler SelectedItemChanged;
  21. private ErrorListOrderPolicy _listOrder;
  22. private ErrorItemCollection _items;
  23. private ErrorItem _selection;
  24. private string _stackTrace;
  25. protected IErrorListRenderer _renderer;
  26. protected Graphics _workingGraphics;
  27. protected int _hoveredIndex;
  28. private Point _mouse;
  29. private bool _autoSelectFirstItem;
  30. /// <summary>
  31. /// Builds a new instance of ErrorList.
  32. /// </summary>
  33. public ErrorList() :
  34. this(new DefaultErrorListRenderer())
  35. {
  36. }
  37. /// <summary>
  38. /// Gives access to the item collection.
  39. /// </summary>
  40. public ErrorItemCollection Items
  41. {
  42. get { return (_items); }
  43. }
  44. #region IStackTraceView Members
  45. public bool AutoSelectFirstItem
  46. {
  47. get { return (_autoSelectFirstItem); }
  48. set { _autoSelectFirstItem = value; }
  49. }
  50. public string StackTrace
  51. {
  52. get { return (_stackTrace); }
  53. set
  54. {
  55. ErrorItem candidate;
  56. candidate = PopulateList(value);
  57. if (!String.IsNullOrEmpty(value) &&
  58. _items.Count == 0)
  59. _items.Add(new ErrorItem(null, "Fail to parse stack trace", -1));
  60. AutoScrollMinSize = _renderer.GetDocumentSize(_items, _workingGraphics);
  61. _hoveredIndex = -1;
  62. SelectedItem = (AutoSelectFirstItem ? candidate : null);
  63. Invalidate();
  64. return;
  65. }
  66. }
  67. public ErrorItem SelectedItem
  68. {
  69. get { return (_selection); }
  70. set
  71. {
  72. bool fireEvent;
  73. if (value != null &&
  74. (!_items.Contains(value) || !value.HasSourceAttachment))
  75. return;
  76. fireEvent = (_selection != value);
  77. _selection = value;
  78. if (fireEvent && SelectedItemChanged != null)
  79. SelectedItemChanged(this, new EventArgs());
  80. Invalidate();
  81. }
  82. }
  83. public ErrorListOrderPolicy ListOrderPolicy
  84. {
  85. get { return (_listOrder); }
  86. set
  87. {
  88. if (_listOrder == value)
  89. return;
  90. _listOrder = value;
  91. _items.Reverse();
  92. Invalidate();
  93. }
  94. }
  95. #endregion
  96. protected ErrorList(IErrorListRenderer renderer)
  97. {
  98. UiExceptionHelper.CheckNotNull(renderer, "display");
  99. SetStyle(ControlStyles.UserPaint, true);
  100. SetStyle(ControlStyles.AllPaintingInWmPaint, true);
  101. DoubleBuffered = true;
  102. _renderer = renderer;
  103. _items = new ErrorItemCollection();
  104. _stackTrace = null;
  105. _selection = null;
  106. _workingGraphics = CreateGraphics();
  107. _hoveredIndex = -1;
  108. _autoSelectFirstItem = false;
  109. _listOrder = ErrorListOrderPolicy.InitialOrder;
  110. return;
  111. }
  112. protected virtual void ItemEntered(int index)
  113. {
  114. Cursor = Cursors.Hand;
  115. }
  116. protected virtual void ItemLeaved(int index)
  117. {
  118. Cursor = Cursors.Default;
  119. }
  120. protected override void OnPaint(PaintEventArgs e)
  121. {
  122. Rectangle viewport;
  123. base.OnPaint(e);
  124. viewport = new Rectangle(-AutoScrollPosition.X, -AutoScrollPosition.Y,
  125. ClientRectangle.Width, ClientRectangle.Height);
  126. _renderer.DrawToGraphics(_items, _selection, e.Graphics, viewport);
  127. if (_hoveredIndex != -1)
  128. _renderer.DrawItem(_items[_hoveredIndex], _hoveredIndex, true,
  129. _items[_hoveredIndex] == _selection, e.Graphics, viewport);
  130. return;
  131. }
  132. protected override void OnMouseHover(EventArgs e)
  133. {
  134. base.OnMouseHover(e);
  135. Focus();
  136. }
  137. protected override void OnMouseDown(MouseEventArgs e)
  138. {
  139. base.OnMouseDown(e);
  140. _mouse = new Point(e.X, e.Y - AutoScrollPosition.Y);
  141. }
  142. protected override void OnMouseMove(MouseEventArgs e)
  143. {
  144. ErrorItem item;
  145. int itemIndex;
  146. base.OnMouseMove(e);
  147. item = _renderer.ItemAt(_items, _workingGraphics, new Point(e.X, e.Y - AutoScrollPosition.Y));
  148. itemIndex = -1;
  149. for (int i = 0; i < _items.Count; ++i)
  150. if (Object.ReferenceEquals(_items[i], item))
  151. {
  152. itemIndex = i;
  153. break;
  154. }
  155. if (itemIndex != _hoveredIndex)
  156. {
  157. if (_hoveredIndex != -1)
  158. ItemLeaved(_hoveredIndex);
  159. if (itemIndex != -1 && _items[itemIndex].HasSourceAttachment)
  160. {
  161. ItemEntered(itemIndex);
  162. _hoveredIndex = itemIndex;
  163. }
  164. else
  165. _hoveredIndex = -1;
  166. Invalidate();
  167. }
  168. return;
  169. }
  170. protected override void OnClick(EventArgs e)
  171. {
  172. base.OnClick(e);
  173. OnClick(_mouse);
  174. return;
  175. }
  176. protected override void OnFontChanged(EventArgs e)
  177. {
  178. this._renderer.Font = this.Font;
  179. base.OnFontChanged(e);
  180. }
  181. protected void OnClick(Point point)
  182. {
  183. SelectedItem = _renderer.ItemAt(_items, _workingGraphics, point);
  184. return;
  185. }
  186. protected override void OnSizeChanged(EventArgs e)
  187. {
  188. base.OnSizeChanged(e);
  189. Invalidate();
  190. }
  191. private ErrorItem PopulateList(string stackTrace)
  192. {
  193. StackTraceParser parser = new StackTraceParser();
  194. ErrorItem candidate;
  195. _stackTrace = stackTrace;
  196. parser.Parse(stackTrace);
  197. if (_listOrder == ErrorListOrderPolicy.ReverseOrder)
  198. parser.Items.Reverse();
  199. candidate = null;
  200. _items.Clear();
  201. foreach (ErrorItem item in parser.Items)
  202. {
  203. if (candidate == null && item.HasSourceAttachment)
  204. candidate = item;
  205. _items.Add(item);
  206. }
  207. return (candidate);
  208. }
  209. }
  210. }