PageRenderTime 53ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/source/JsParser.UI/UI/NavigationTreeView.cs

https://bitbucket.org/megaboich/jsparser
C# | 1026 lines | 858 code | 136 blank | 32 comment | 105 complexity | ee625033f443692dd0bbcb2d53a1b6b3 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Windows.Forms;
  5. using JsParser.Core.Code;
  6. using JsParser.UI.Helpers;
  7. using JsParser.Core.Parsers;
  8. using System.Runtime.InteropServices;
  9. using System.Security.Cryptography;
  10. using System.Text;
  11. using System.IO;
  12. using JsParser.UI.Properties;
  13. using System.Linq;
  14. using System.Threading;
  15. using System.Diagnostics;
  16. using JsParser.Core.Helpers;
  17. namespace JsParser.UI.UI
  18. {
  19. /// <summary>
  20. /// The tree for code.
  21. /// </summary>
  22. [ComVisibleAttribute(true)]
  23. public partial class NavigationTreeView : UserControl
  24. {
  25. private string _loadedDocName = string.Empty;
  26. private bool _canExpand = true;
  27. private MarksManager _marksManager = new MarksManager();
  28. private ExpandedNodesManager _expandedNodesManager = new ExpandedNodesManager();
  29. private List<TreeNode> _tempTreeNodes = new List<TreeNode>();
  30. private int _lastCodeLine = -1;
  31. private List<CodeNode> _functions;
  32. private int _lastActiveLine;
  33. private int _lastActiveColumn;
  34. private bool _treeRefreshing = false;
  35. private bool _userWantsUpdateSplitterPosition = false;
  36. private ColorTable _colorTable = ColorTable.Default;
  37. private Palette _palette = new Palette();
  38. private JSParserResult _lastParserResult;
  39. private ICodeProvider _codeProvider;
  40. private string _colorTableHash;
  41. private IUIThemeProvider _uiThemesProvider;
  42. /// <summary>
  43. /// Initializes a new instance of the <see cref="NavigationTreeView"/> class.
  44. /// </summary>
  45. public NavigationTreeView()
  46. {
  47. InitializeComponent();
  48. this.Disposed += OnDisposed;
  49. treeView1.Nodes.Clear();
  50. treeView1.LostFocus += LostFocusHandler;
  51. sortItemsAlphabeticallyToolStripMenuItem.Checked = Settings.SortingEnabled;
  52. showLineNumbersToolStripMenuItem.Checked = Settings.ShowLineNumbersEnabled;
  53. filterByMarksToolStripMenuItem.Checked = Settings.FilterByMarksEnabled;
  54. expandAllByDefaultToolStripMenuItem.Checked = Settings.AutoExpandAll;
  55. hideAnonymousFunctionsToolStripMenuItem.Checked = Settings.HideAnonymousFunctions;
  56. }
  57. public void InitColors(IUIThemeProvider uiThemeProvider)
  58. {
  59. _uiThemesProvider = uiThemeProvider;
  60. if (Settings.Default.UseVSColorTheme)
  61. {
  62. _colorTable = uiThemeProvider.Colors;
  63. }
  64. else
  65. {
  66. _colorTable = ColorTable.Default;
  67. }
  68. var colorHash = _colorTable.GetHash();
  69. if (_colorTableHash == colorHash)
  70. {
  71. return;
  72. }
  73. _colorTableHash = colorHash;
  74. BackColor = _colorTable.ControlBackground;
  75. ForeColor = _colorTable.ControlText;
  76. treeView1.BackColor = _colorTable.WindowBackground;
  77. treeView1.ForeColor = _colorTable.WindowText;
  78. lbTaskList.ForeColor = _colorTable.TabText;
  79. taskListDataGrid.BackColor = _colorTable.WindowBackground;
  80. taskListDataGrid.BackgroundColor = _colorTable.WindowBackground;
  81. taskListDataGrid.ForeColor = _colorTable.WindowText;
  82. taskListDataGrid.GridColor = _colorTable.GridLines;
  83. taskListDataGrid.RowsDefaultCellStyle.BackColor = _colorTable.WindowBackground;
  84. taskListDataGrid.RowsDefaultCellStyle.ForeColor = _colorTable.WindowText;
  85. toolStrip2.BackColor = _colorTable.MenuBackground;
  86. treeView1.Indent = Settings.Default.UseVSColorTheme ? 10 : 16;
  87. treeView1.DrawMode = Settings.Default.UseVSColorTheme
  88. ? TreeViewDrawMode.OwnerDrawAll
  89. : TreeViewDrawMode.OwnerDrawText;
  90. treeView1.ShowLines = !Settings.Default.UseVSColorTheme;
  91. }
  92. public void OnDisposed(object sender, EventArgs args)
  93. {
  94. _palette.Dispose();
  95. }
  96. /// <summary>
  97. /// Clears the tree and other UI.
  98. /// </summary>
  99. public void Clear()
  100. {
  101. _loadedDocName = string.Empty;
  102. treeView1.BeginUpdate();
  103. treeView1.Nodes.Clear();
  104. treeView1.EndUpdate();
  105. splitContainer1.Panel2Collapsed = true;
  106. _functions = new List<CodeNode>();
  107. OnResize(null);
  108. panelLinesNumbers.Refresh();
  109. btnErrorDiagnosis.Visible = false;
  110. btnErrorSeparator.Visible = false;
  111. lbTaskList.Text = " Task List";
  112. }
  113. /// <summary>
  114. /// Gets status of the tree.
  115. /// </summary>
  116. public bool TreeLoaded
  117. {
  118. get
  119. {
  120. return treeView1.Nodes.Count > 0;
  121. }
  122. }
  123. /// <summary>
  124. /// Settings instance
  125. /// </summary>
  126. public Settings Settings
  127. {
  128. get { return Settings.Default; }
  129. }
  130. /// <summary>
  131. /// Build the tree.
  132. /// </summary>
  133. public bool UpdateTree(JSParserResult result, ICodeProvider codeProvider)
  134. {
  135. if (result == null)
  136. {
  137. Clear();
  138. return false;
  139. }
  140. if(string.IsNullOrEmpty(result.FileName))
  141. {
  142. return false;
  143. }
  144. StatisticsManager.Instance.Statistics.Container = codeProvider.ContainerName;
  145. PerformNetworkActivity();
  146. _lastParserResult = result;
  147. _codeProvider = codeProvider;
  148. _loadedDocName = _lastParserResult.FileName;
  149. _expandedNodesManager.SetFile(_loadedDocName);
  150. _marksManager.SetFile(_loadedDocName);
  151. var isSort = Settings.SortingEnabled;
  152. var isHierarchy = true;
  153. _treeRefreshing = true;
  154. treeView1.BeginUpdate();
  155. treeView1.Nodes.Clear();
  156. _tempTreeNodes.Clear();
  157. _canExpand = true;
  158. var nodes = result.Nodes;
  159. if (result.Errors.Count > 0)
  160. {
  161. btnErrorDiagnosis.Visible = true;
  162. btnErrorSeparator.Visible = true;
  163. btnErrorDiagnosis.DropDownItems.Clear();
  164. result.Errors.ForEach(er =>
  165. {
  166. var item = btnErrorDiagnosis.DropDownItems.Add(er.Message.SplitWordsByCamelCase() + ".\r\nLine: " + er.StartLine, null, ErrorDiagnosisClick);
  167. item.Tag = er;
  168. });
  169. }
  170. else
  171. {
  172. btnErrorDiagnosis.Visible = false;
  173. btnErrorSeparator.Visible = false;
  174. }
  175. var tasksDataSource = new List<object>();
  176. if (result.TaskList.Count > 0)
  177. {
  178. lbTaskList.Text = string.Format(" Task List: {0} items", result.TaskList.Count);
  179. int i = 0;
  180. result.TaskList.ForEach(t =>
  181. {
  182. ++i;
  183. var item = new {
  184. No = i.ToString(),
  185. Desc = t.Description,
  186. Line = t.StartLine.ToString(),
  187. };
  188. tasksDataSource.Add(item);
  189. });
  190. splitContainer1.Panel2Collapsed = false;
  191. SetToDoSplitterPosition();
  192. }
  193. else
  194. {
  195. splitContainer1.Panel2Collapsed = true;
  196. tasksDataSource.Add(new {No = "", Desc="", Line="" }); //add fake row to workaround column sizing bug
  197. }
  198. taskListDataGrid.DataSource = tasksDataSource;
  199. taskListDataGrid.CurrentCell = null;
  200. _lastCodeLine = -1;
  201. _functions = new List<CodeNode>();
  202. FillNodes(nodes, treeView1.Nodes, 0, _functions);
  203. if (!isHierarchy)
  204. {
  205. if (isSort)
  206. {
  207. _tempTreeNodes.Sort((n1, n2) => string.Compare(n1.Text, n2.Text));
  208. }
  209. foreach (TreeNode node in _tempTreeNodes)
  210. {
  211. treeView1.Nodes.Add(node);
  212. }
  213. }
  214. if (filterByMarksToolStripMenuItem.Checked)
  215. {
  216. HideUnmarkedNodes(treeView1.Nodes);
  217. }
  218. treeView1.EndUpdate();
  219. _treeRefreshing = false;
  220. AdjustLineNumbersPanelSize();
  221. panelLinesNumbers.Refresh();
  222. return treeView1.Nodes.Count > 0;
  223. }
  224. public void RefreshTree()
  225. {
  226. if (_uiThemesProvider != null)
  227. {
  228. InitColors(_uiThemesProvider);
  229. }
  230. UpdateTree(_lastParserResult, _codeProvider);
  231. }
  232. private void PerformNetworkActivity()
  233. {
  234. StatisticsSender.Send();
  235. }
  236. private bool HideUnmarkedNodes(TreeNodeCollection nodes)
  237. {
  238. bool hasMarks = false;
  239. var nodess = nodes.Cast<CustomTreeNode>().ToArray();
  240. foreach (TreeNode tnode in nodess)
  241. {
  242. if (tnode == null)
  243. {
  244. continue;
  245. }
  246. CustomTreeNode node = (CustomTreeNode)tnode;
  247. if (!string.IsNullOrEmpty(node.Tags))
  248. {
  249. hasMarks = true;
  250. continue;
  251. }
  252. if (node.Nodes.Count > 0)
  253. {
  254. var hasChildMarks = HideUnmarkedNodes(node.Nodes);
  255. if (hasChildMarks)
  256. {
  257. hasMarks = true;
  258. }
  259. else
  260. {
  261. node.Remove();
  262. }
  263. }
  264. if (node.Nodes.Count == 0 && string.IsNullOrEmpty(node.Tags))
  265. {
  266. node.Remove();
  267. }
  268. }
  269. return hasMarks;
  270. }
  271. private int GetImageIndex(CodeNodeType nodeType)
  272. {
  273. switch (nodeType)
  274. {
  275. case CodeNodeType.Function:
  276. return -1;
  277. case CodeNodeType.AnonymousFunction:
  278. return 1;
  279. case CodeNodeType.Object:
  280. return 0;
  281. }
  282. return -1;
  283. }
  284. private void FillNodes(Hierarchy<CodeNode> source, TreeNodeCollection dest, int level, IList<CodeNode> functions)
  285. {
  286. if (!source.HasChildren)
  287. {
  288. return;
  289. }
  290. var isSort = Settings.SortingEnabled;
  291. var isHierarchy = true;
  292. var childrens = source.Children;
  293. if (isSort)
  294. {
  295. childrens.Sort((a1, a2) => string.Compare(a1.Item.Alias, a2.Item.Alias));
  296. }
  297. foreach (var item in childrens)
  298. {
  299. CodeNode node = item.Item;
  300. if (node.StartLine > _lastCodeLine)
  301. {
  302. _lastCodeLine = node.StartLine;
  303. }
  304. CustomTreeNode treeNode = new CustomTreeNode(node.Alias);
  305. treeNode.CodeNode = node;
  306. treeNode.ToolTipText = CommentTipFormatter.FormatPlainTextComment(node.Comment);
  307. treeNode.StateImageIndex = GetImageIndex(node.NodeType);
  308. _marksManager.RestoreMark(treeNode);
  309. if (isHierarchy)
  310. {
  311. dest.Add(treeNode);
  312. }
  313. else
  314. {
  315. _tempTreeNodes.Add(treeNode);
  316. }
  317. functions.Add(node);
  318. if (item.HasChildren)
  319. {
  320. FillNodes(item, treeNode.Nodes, level + 1, functions);
  321. }
  322. var isExpanded = _expandedNodesManager.IsNoteExpanded(treeNode);
  323. if (isExpanded.HasValue)
  324. {
  325. if (isExpanded.Value)
  326. {
  327. treeNode.Expand();
  328. }
  329. }
  330. else
  331. {
  332. if (Settings.AutoExpandAll)
  333. {
  334. treeNode.Expand();
  335. }
  336. }
  337. }
  338. }
  339. private void GotoSelected()
  340. {
  341. if (treeView1.SelectedNode != null)
  342. {
  343. CodeNode codeNode = ((CustomTreeNode)treeView1.SelectedNode).CodeNode;
  344. try
  345. {
  346. _codeProvider.SelectionMoveToLineAndOffset(codeNode.StartLine, codeNode.StartColumn + 1);
  347. _codeProvider.SetFocus();
  348. ++StatisticsManager.Instance.Statistics.NavigateFromFunctionsTreeCount;
  349. }
  350. catch { }
  351. }
  352. }
  353. private Image GetTagImage(char mark)
  354. {
  355. switch (mark)
  356. {
  357. case 'W':
  358. return JsParser.UI.Properties.Resources.flag_white;
  359. case 'B':
  360. return JsParser.UI.Properties.Resources.flag_blue;
  361. case 'G':
  362. return JsParser.UI.Properties.Resources.flag_green;
  363. case 'O':
  364. return JsParser.UI.Properties.Resources.flag_orange;
  365. case 'R':
  366. return JsParser.UI.Properties.Resources.flag_red;
  367. case '!':
  368. return JsParser.UI.Properties.Resources.Active;
  369. case 'S':
  370. default:
  371. return JsParser.UI.Properties.Resources.icon_favourites;
  372. }
  373. }
  374. public void Find()
  375. {
  376. if (_functions != null)
  377. {
  378. FindDialog fd = new FindDialog(_functions, FindCallBack);
  379. fd.ShowDialog();
  380. }
  381. }
  382. private bool FindCallBack(CodeNode codeNode)
  383. {
  384. try
  385. {
  386. var node = SearchNode(treeView1.Nodes, codeNode);
  387. if (node != null)
  388. {
  389. treeView1.SelectedNode = node;
  390. GotoSelected();
  391. }
  392. else
  393. {
  394. _codeProvider.SelectionMoveToLineAndOffset(codeNode.StartLine, codeNode.StartColumn + 1);
  395. _codeProvider.SetFocus();
  396. }
  397. }
  398. catch { }
  399. return true;
  400. }
  401. private bool ScanTreeView(Func<CustomTreeNode, bool> funcDelegate, TreeNodeCollection nodes, bool scanExpandedNodes = true)
  402. {
  403. bool continueScan = true;
  404. if (TreeLoaded)
  405. {
  406. foreach (CustomTreeNode node in nodes)
  407. {
  408. continueScan = funcDelegate(node);
  409. if (!continueScan)
  410. {
  411. return false;
  412. }
  413. if (node.IsExpanded || scanExpandedNodes)
  414. {
  415. if (node.Nodes.Count > 0)
  416. {
  417. continueScan = ScanTreeView(funcDelegate, node.Nodes, scanExpandedNodes);
  418. if (!continueScan)
  419. {
  420. return false;
  421. }
  422. }
  423. }
  424. }
  425. }
  426. return true;
  427. }
  428. private TreeNode SearchNode(TreeNodeCollection nodes, CodeNode cn)
  429. {
  430. foreach (CustomTreeNode node in nodes)
  431. {
  432. if (node.CodeNode == cn)
  433. {
  434. return node;
  435. }
  436. var inner = SearchNode(node.Nodes, cn);
  437. if (inner != null)
  438. {
  439. return inner;
  440. }
  441. }
  442. return null;
  443. }
  444. private void SaveSettings()
  445. {
  446. Settings.SortingEnabled = sortItemsAlphabeticallyToolStripMenuItem.Checked;
  447. Settings.ShowLineNumbersEnabled = showLineNumbersToolStripMenuItem.Checked;
  448. Settings.FilterByMarksEnabled = filterByMarksToolStripMenuItem.Checked;
  449. Settings.AutoExpandAll = expandAllByDefaultToolStripMenuItem.Checked;
  450. Settings.HideAnonymousFunctions = hideAnonymousFunctionsToolStripMenuItem.Checked;
  451. StatisticsManager.Instance.Statistics.UpdateStatisticsFromSettings();
  452. StatisticsManager.Instance.UpdateSettingsWithStatistics();
  453. Settings.Save();
  454. }
  455. private void AdjustLineNumbersPanelSize()
  456. {
  457. var tw = 0;
  458. using (var g = this.CreateGraphics())
  459. {
  460. tw = Convert.ToInt32(Math.Round(g.MeasureString(_lastCodeLine.ToString(), Font).Width)) + 2;
  461. }
  462. treeView1.Left = Settings.ShowLineNumbersEnabled ? tw : 0;
  463. treeView1.Top = 0;
  464. treeView1.Width = splitContainer1.Panel1.ClientSize.Width - treeView1.Left;
  465. treeView1.Height = splitContainer1.Panel1.ClientSize.Height - treeView1.Top;
  466. panelLinesNumbers.Left = 0;
  467. panelLinesNumbers.Width = tw;
  468. panelLinesNumbers.Top = 0;
  469. panelLinesNumbers.Height = splitContainer1.Panel1.ClientSize.Height;
  470. panelLinesNumbers.Visible = Settings.ShowLineNumbersEnabled;
  471. }
  472. #region Event handlers
  473. private void treeView1_KeyPress(object sender, KeyPressEventArgs e)
  474. {
  475. if (e.KeyChar == 13)
  476. {
  477. GotoSelected();
  478. }
  479. }
  480. private void treeView1_BeforeCollapse(object sender, TreeViewCancelEventArgs e)
  481. {
  482. if (!_canExpand)
  483. {
  484. e.Cancel = true;
  485. }
  486. }
  487. private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
  488. {
  489. if (!_canExpand)
  490. {
  491. e.Cancel = true;
  492. }
  493. }
  494. private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
  495. {
  496. _canExpand = !e.Node.Bounds.Contains(e.X, e.Y);
  497. treeView1.SelectedNode = e.Node;
  498. if (e.Button == MouseButtons.Right)
  499. {
  500. //Apply fonts and colors to menu items
  501. var nodeTags = ((CustomTreeNode)e.Node).Tags ?? string.Empty;
  502. resetLabelToolStripMenuItem.Enabled = !string.IsNullOrEmpty(nodeTags);
  503. var menuItems = new[] { contextMenuMarks0Item, contextMenuMarks1Item, contextMenuMarks2Item, contextMenuMarks3Item, contextMenuMarks4Item, contextMenuMarks5Item };
  504. var menuFonts = new[] { Settings.taggedFunction1Font, Settings.taggedFunction2Font, Settings.taggedFunction3Font, Settings.taggedFunction4Font, Settings.taggedFunction5Font, Settings.taggedFunction6Font };
  505. var menuColors = new[] { Settings.taggedFunction1Color, Settings.taggedFunction2Color, Settings.taggedFunction3Color, Settings.taggedFunction4Color, Settings.taggedFunction5Color, Settings.taggedFunction6Color };
  506. for (int i = 0; i < menuItems.Length; ++i)
  507. {
  508. menuItems[i].Font = menuFonts[i];
  509. menuItems[i].ForeColor = menuColors[i];
  510. menuItems[i].Checked = nodeTags.Contains((string)menuItems[i].Tag);
  511. }
  512. contextMenuStrip1.Show((Control)sender, e.X, e.Y);
  513. ++StatisticsManager.Instance.Statistics.TreeContextMenuExecutedCount;
  514. }
  515. }
  516. private void contextMenuMarks0Item_Click(object sender, EventArgs e)
  517. {
  518. var menuItem = (ToolStripMenuItem)sender;
  519. _marksManager.SetMark((string)menuItem.Tag, (CustomTreeNode)treeView1.SelectedNode);
  520. treeView1.Refresh();
  521. ++StatisticsManager.Instance.Statistics.SetMarkExecutedCount;
  522. }
  523. private void resetLabelToolStripMenuItem_Click(object sender, EventArgs e)
  524. {
  525. _marksManager.SetMark(null, (CustomTreeNode)treeView1.SelectedNode);
  526. treeView1.Refresh();
  527. }
  528. private void resetAllLabelsToolStripMenuItem_Click(object sender, EventArgs e)
  529. {
  530. _marksManager.ResetMarks();
  531. RefreshTree();
  532. }
  533. private void btnRefresh_Click(object sender, EventArgs e)
  534. {
  535. SaveSettings();
  536. RefreshTree();
  537. }
  538. private void treeView1_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
  539. {
  540. GotoSelected();
  541. }
  542. private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e)
  543. {
  544. var node = (CustomTreeNode)e.Node;
  545. //workaround for a bug when nodes draws twice - first attempt on zero boundaries
  546. if (node.Bounds.Width == 0 && node.Bounds.Height == 0)
  547. {
  548. return;
  549. }
  550. var tags = node.Tags;
  551. if (Settings.Default.UseVSColorTheme)
  552. {
  553. // Retrieve the node font. If the node font has not been set,
  554. // use the TreeView font.
  555. Font nodeFont = e.Node.NodeFont;
  556. if (nodeFont == null) nodeFont = ((TreeView)sender).Font;
  557. var hasExpand = (e.Node.Nodes != null && e.Node.Nodes.Count > 0);
  558. var hasImage = (e.Node.StateImageIndex >= 0);
  559. var hasTags = !string.IsNullOrEmpty(tags);
  560. var isSelected = ((e.State & TreeNodeStates.Selected) != 0);
  561. var tagsShift = 0;
  562. // Draw background
  563. var bgBrush = isSelected
  564. ? (treeView1.Focused)
  565. ? _palette.GetSolidBrush(_colorTable.HighlightBackground)
  566. : _palette.GetSolidBrush(_colorTable.HighlightInactiveBackground)
  567. : _palette.GetSolidBrush(_colorTable.WindowBackground);
  568. e.Graphics.FillRectangle(bgBrush, e.Graphics.VisibleClipBounds.Left, e.Bounds.Top, e.Graphics.VisibleClipBounds.Width, e.Bounds.Height);
  569. //Draw tags
  570. if (hasTags)
  571. {
  572. foreach (char mark in tags)
  573. {
  574. e.Graphics.DrawImageUnscaled(GetTagImage(mark), e.Node.Bounds.Left + tagsShift, e.Bounds.Top);
  575. tagsShift += 18;
  576. }
  577. }
  578. var nodeLeftShift = 0;
  579. // Draw image before node
  580. if (hasImage)
  581. {
  582. nodeLeftShift += 16;
  583. e.Graphics.DrawImageUnscaled(imageList1.Images[e.Node.StateImageIndex],
  584. Point.Subtract(e.Node.Bounds.Location, new Size(16, 0)));
  585. }
  586. // Draw + - sign before node
  587. if (hasExpand)
  588. {
  589. var img = e.Node.IsExpanded ? Resources.treeleaf_expanded : Resources.treeleaf_collapsed;
  590. e.Graphics.DrawImageUnscaled(img, e.Node.Bounds.Location.X - 11 - nodeLeftShift, e.Node.Bounds.Location.Y + 3, 9, 9);
  591. }
  592. var textColor = (e.Node.ForeColor.ToArgb() == 0)
  593. ? _colorTable.WindowText
  594. : e.Node.ForeColor;
  595. // Draw the node text.
  596. var textColorToUse = ((e.State & TreeNodeStates.Selected) != 0)
  597. ? (treeView1.Focused)
  598. ? _colorTable.HighlightText
  599. : _colorTable.HighlightInactiveText
  600. : textColor;
  601. var textBrush = _palette.GetSolidBrush(textColorToUse);
  602. TextRenderer.DrawText(e.Graphics, e.Node.Text, nodeFont,
  603. Point.Add(e.Node.Bounds.Location, new Size(2 + tagsShift, 0)),
  604. textColorToUse);
  605. /*
  606. e.Graphics.DrawString(e.Node.Text, nodeFont, textBrush,
  607. Point.Add(e.Node.Bounds.Location, new Size(2 + tagsShift, 0)));
  608. */
  609. e.DrawDefault = false;
  610. }
  611. else
  612. {
  613. //Draw tags
  614. if (!string.IsNullOrEmpty(tags))
  615. {
  616. var tagsShift = 2;
  617. foreach (char mark in tags)
  618. {
  619. e.Graphics.DrawImageUnscaled(GetTagImage(mark), e.Node.Bounds.Right + tagsShift, e.Bounds.Top);
  620. tagsShift += 18;
  621. }
  622. }
  623. e.DrawDefault = true;
  624. }
  625. }
  626. private void ErrorDiagnosisClick(object sender, EventArgs e)
  627. {
  628. var errorMessage = (ErrorMessage)((ToolStripItem)sender).Tag;
  629. try
  630. {
  631. _codeProvider.SelectionMoveToLineAndOffset(errorMessage.StartLine, errorMessage.StartColumn + 1);
  632. _codeProvider.SetFocus();
  633. ++StatisticsManager.Instance.Statistics.NavigateFromErrorListCount;
  634. }
  635. catch { }
  636. }
  637. private void taskListDataGrid_CellClick(object sender, DataGridViewCellEventArgs e)
  638. {
  639. var item = _lastParserResult.TaskList[e.RowIndex];
  640. try
  641. {
  642. _codeProvider.SelectionMoveToLineAndOffset(item.StartLine, item.StartColumn + 1);
  643. _codeProvider.SetFocus();
  644. ++StatisticsManager.Instance.Statistics.NavigateFromToDoListCount;
  645. }
  646. catch { }
  647. }
  648. private void showLineNumbersToolStripMenuItem_Click(object sender, EventArgs e)
  649. {
  650. SaveSettings();
  651. AdjustLineNumbersPanelSize();
  652. panelLinesNumbers.Refresh();
  653. ++StatisticsManager.Instance.Statistics.ToggleShowLineNumbersCount;
  654. StatisticsManager.Instance.Statistics.UpdateStatisticsFromSettings();
  655. }
  656. private void NavigationTreeView_Resize(object sender, EventArgs e)
  657. {
  658. splitContainer1.Left = 0;
  659. splitContainer1.Top = 27;
  660. splitContainer1.Width = this.ClientSize.Width;
  661. splitContainer1.Height = this.ClientSize.Height - 27;
  662. }
  663. private void splitContainer1_Panel1_Resize(object sender, EventArgs e)
  664. {
  665. AdjustLineNumbersPanelSize();
  666. }
  667. private void treeView1_OnScroll(object sender, CustomTreeView.ScrollEventArgs e)
  668. {
  669. if (e.ScrollType == CustomTreeView.ScrollType.Vertical)
  670. {
  671. panelLinesNumbers.Refresh();
  672. }
  673. }
  674. private void panelLinesNumbers_Paint(object sender, PaintEventArgs e)
  675. {
  676. e.Graphics.FillRectangle(_palette.GetSolidBrush(_colorTable.ControlBackground), panelLinesNumbers.ClientRectangle);
  677. if (Settings.ShowLineNumbersEnabled && treeView1.Nodes.Count > 0)
  678. {
  679. var gr = e.Graphics;
  680. ScanTreeView(node =>
  681. {
  682. int p = node.Bounds.Top + 2;
  683. if (p < 0)
  684. {
  685. return true;
  686. }
  687. if (p > panelLinesNumbers.Height)
  688. {
  689. return false; //This means stop scan anymore
  690. }
  691. var nodeHeight = node.Bounds.Height;
  692. var s = node.CodeNode.StartLine.ToString();
  693. gr.DrawString(s, Font, Brushes.Gray, new Rectangle(0, p, panelLinesNumbers.Width, nodeHeight));
  694. return true;
  695. }, treeView1.Nodes, false);
  696. }
  697. }
  698. private void toolFindButton_Click(object sender, EventArgs e)
  699. {
  700. Find();
  701. }
  702. private void LostFocusHandler(object sender, EventArgs e)
  703. {
  704. SaveSettings();
  705. }
  706. private void timer2_Tick_1(object sender, EventArgs e)
  707. {
  708. try
  709. {
  710. if (_codeProvider != null && Settings.TrackActiveItem)
  711. {
  712. int line;
  713. int column;
  714. _codeProvider.GetCursorPos(out line, out column);
  715. if (line >= 0 && (line != _lastActiveLine || column != _lastActiveColumn))
  716. {
  717. CustomTreeNode hightLightNode = null;
  718. ScanTreeView(node =>
  719. {
  720. bool sel = false;
  721. if (node.CodeNode.StartLine <= line && line <= node.CodeNode.EndLine)
  722. {
  723. if (node.CodeNode.StartLine == node.CodeNode.EndLine)
  724. {
  725. if (node.CodeNode.StartColumn <= column && column <= node.CodeNode.EndColumn)
  726. {
  727. sel = true;
  728. }
  729. }
  730. else
  731. {
  732. sel = true;
  733. }
  734. }
  735. if (sel)
  736. {
  737. if (hightLightNode != null && node.Level < hightLightNode.Level)
  738. {
  739. return true; //Skip parent nodes
  740. }
  741. hightLightNode = node;
  742. }
  743. return true;
  744. }, treeView1.Nodes);
  745. _lastActiveLine = line;
  746. _lastActiveColumn = column;
  747. if (hightLightNode != null && treeView1.SelectedNode != hightLightNode)
  748. {
  749. treeView1.SelectedNode = hightLightNode;
  750. }
  751. }
  752. }
  753. }
  754. catch { }
  755. }
  756. private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
  757. {
  758. SettingsForm sf = new SettingsForm(treeView1.Font);
  759. sf.ShowDialog();
  760. RefreshTree();
  761. ++StatisticsManager.Instance.Statistics.SettingsDialogShowedCount;
  762. StatisticsManager.Instance.Statistics.UpdateStatisticsFromSettings();
  763. }
  764. private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
  765. {
  766. panelLinesNumbers.Refresh();
  767. }
  768. private void showHierarhyToolStripMenuItem_Click(object sender, EventArgs e)
  769. {
  770. SaveSettings();
  771. RefreshTree();
  772. ++StatisticsManager.Instance.Statistics.ToggleHierachyOptionCount;
  773. StatisticsManager.Instance.Statistics.UpdateStatisticsFromSettings();
  774. }
  775. private void expandAllByDefaultToolStripMenuItem_Click(object sender, EventArgs e)
  776. {
  777. SaveSettings();
  778. RefreshTree();
  779. }
  780. private void expandAllToolStripMenuItem_Click(object sender, EventArgs e)
  781. {
  782. _treeRefreshing = true;
  783. treeView1.BeginUpdate();
  784. treeView1.ExpandAll();
  785. treeView1.EndUpdate();
  786. _treeRefreshing = false;
  787. panelLinesNumbers.Refresh();
  788. ++StatisticsManager.Instance.Statistics.ExpandAllCommandExecutedCount;
  789. }
  790. private void collapseAllNodesToolStripMenuItem_Click(object sender, EventArgs e)
  791. {
  792. _treeRefreshing = true;
  793. treeView1.BeginUpdate();
  794. treeView1.CollapseAll();
  795. treeView1.EndUpdate();
  796. _treeRefreshing = false;
  797. panelLinesNumbers.Refresh();
  798. ++StatisticsManager.Instance.Statistics.CollapseAllCommandExecutedCount;
  799. }
  800. private void treeView1_AfterExpand(object sender, TreeViewEventArgs e)
  801. {
  802. _expandedNodesManager.SetExpandedState((CustomTreeNode)e.Node);
  803. if (Settings.ShowLineNumbersEnabled && !_treeRefreshing)
  804. {
  805. panelLinesNumbers.Refresh();
  806. }
  807. }
  808. private void treeView1_AfterCollapse(object sender, TreeViewEventArgs e)
  809. {
  810. _expandedNodesManager.SetExpandedState((CustomTreeNode)e.Node);
  811. if (Settings.ShowLineNumbersEnabled && !_treeRefreshing)
  812. {
  813. panelLinesNumbers.Refresh();
  814. }
  815. }
  816. private void sortItemsAlphabeticallyToolStripMenuItem_Click(object sender, EventArgs e)
  817. {
  818. SaveSettings();
  819. RefreshTree();
  820. ++StatisticsManager.Instance.Statistics.SortingUsedCount;
  821. StatisticsManager.Instance.Statistics.UpdateStatisticsFromSettings();
  822. }
  823. private void filterByMarksToolStripMenuItem_Click(object sender, EventArgs e)
  824. {
  825. SaveSettings();
  826. RefreshTree();
  827. ++StatisticsManager.Instance.Statistics.FilterByMarksUsedCount;
  828. StatisticsManager.Instance.Statistics.UpdateStatisticsFromSettings();
  829. }
  830. private void hideAnonymousFunctionsToolStripMenuItem_Click(object sender, EventArgs e)
  831. {
  832. SaveSettings();
  833. RefreshTree();
  834. ++StatisticsManager.Instance.Statistics.HideAnonymousFunctionsUsedCount;
  835. StatisticsManager.Instance.Statistics.UpdateStatisticsFromSettings();
  836. toolTip1.Show("You must update active document (change\\save or switch to another) in order for the changes to take effect.", this, 10, -30, 4000);
  837. }
  838. private void UpdateToDoListToggleImage()
  839. {
  840. btnToDoListToggle.Image = Settings.ToDoListCollapsed
  841. ? JsParser.UI.Properties.Resources.navCollapseArrow
  842. : JsParser.UI.Properties.Resources.navExpandArrow;
  843. }
  844. private void UpdateToDoListSettings()
  845. {
  846. if (_userWantsUpdateSplitterPosition)
  847. {
  848. if (!Settings.ToDoListCollapsed)
  849. {
  850. Settings.ToDoListLastHeight = splitContainer1.Height - splitContainer1.SplitterDistance;
  851. }
  852. Settings.ToDoListCollapsed = (splitContainer1.Panel2.Height <= 25);
  853. }
  854. UpdateToDoListToggleImage();
  855. }
  856. private void SetToDoSplitterPosition()
  857. {
  858. if (!Settings.ToDoListCollapsed)
  859. {
  860. splitContainer1.SplitterDistance = Math.Max(100, splitContainer1.Height - Math.Max(100, Settings.ToDoListLastHeight));
  861. }
  862. else
  863. {
  864. splitContainer1.SplitterDistance = splitContainer1.Height;
  865. }
  866. UpdateToDoListToggleImage();
  867. }
  868. private void btnToDoListToggle_Click(object sender, EventArgs e)
  869. {
  870. _userWantsUpdateSplitterPosition = true;
  871. UpdateToDoListSettings(); //need to save old position
  872. Settings.ToDoListCollapsed = !Settings.ToDoListCollapsed; //update toggle flag
  873. SetToDoSplitterPosition(); //update ui
  874. }
  875. private void splitContainer1_SplitterMoved(object sender, SplitterEventArgs e)
  876. {
  877. UpdateToDoListSettings();
  878. _userWantsUpdateSplitterPosition = false;
  879. }
  880. private void splitContainer1_SplitterMoving(object sender, SplitterCancelEventArgs e)
  881. {
  882. _userWantsUpdateSplitterPosition = true;
  883. }
  884. #endregion
  885. private void taskListDataGrid_Leave(object sender, EventArgs e)
  886. {
  887. taskListDataGrid.CurrentCell = null;
  888. }
  889. }
  890. }