private void treeView1_MouseClick(object sender, MouseEventArgs e) { if (e.Button != MouseButtons.Right) { return; } var node = treeView1.SelectedNode; if (node == null) { return; } clickedNode = node as CallStackEntry; var relativeMousePosition = treeView1.PointToClient(Cursor.Position); MenuItem menu = new MenuItem(clickedNode.Text); menu.Enabled = false; ContextMenu m = new ContextMenu(); m.MenuItems.Add(menu); m.MenuItems.Add(new MenuItem("Copy to &Clipboard", new EventHandler(MenuItem3_Click))); m.MenuItems.Add(new MenuItem("&Jump to", new EventHandler(MenuItem1_Click))); m.MenuItems.Add(new MenuItem("Set &Breakpoint", new EventHandler(MenuItem2_Click))); m.Show(treeView1, relativeMousePosition); }
/// <summary> /// Parses a managed exception message and outputs a data object with a separate message and callstack entries. /// </summary> /// <param name="message">Message to parse.</param> /// <returns>Parsed log message.</returns> public static ParsedLogEntry ParseExceptionMessage(string message) { Regex headerRegex = new Regex(@"Managed exception: (.*)\n"); var headerMatch = headerRegex.Match(message); if (!headerMatch.Success) { return(null); } Regex regex = new Regex(@" at (.*) \[.*\] in (.*):(\d*)"); var matches = regex.Matches(message); ParsedLogEntry newEntry = new ParsedLogEntry(); newEntry.callstack = new CallStackEntry[matches.Count]; for (int i = 0; i < matches.Count; i++) { CallStackEntry callstackEntry = new CallStackEntry(); callstackEntry.method = matches[i].Groups[1].Value; callstackEntry.file = matches[i].Groups[2].Value; int.TryParse(matches[i].Groups[3].Value, out callstackEntry.line); newEntry.callstack[i] = callstackEntry; } newEntry.message = headerMatch.Groups[1].Value; return(newEntry); }
/// <summary> /// Parses a log message and outputs a data object with a separate message and callstack entries. If the message /// is not a valid compiler message null is returned. /// </summary> /// <param name="message">Message to parse.</param> /// <returns>Parsed log message or null if not a valid compiler message.</returns> public static ParsedLogEntry ParseCompilerMessage(string message) { // Note: If modifying FormMessage method make sure to update this one as well to match the formattting // Check for error Regex regex = new Regex(@"Compiler error: (.*)\n\tin (.*)\[(.*):.*\]"); var match = regex.Match(message); // Check for warning if (!match.Success) { regex = new Regex(@"Compiler warning: (.*)\n\tin (.*)\[(.*):.*\]"); match = regex.Match(message); } // No match if (!match.Success) return null; ParsedLogEntry entry = new ParsedLogEntry(); entry.callstack = new CallStackEntry[1]; entry.message = match.Groups[1].Value; CallStackEntry callstackEntry = new CallStackEntry(); callstackEntry.method = ""; callstackEntry.file = match.Groups[2].Value; int.TryParse(match.Groups[3].Value, out callstackEntry.line); entry.callstack[0] = callstackEntry; return entry; }
/// <summary> /// Parses a log message and outputs a data object with a separate message and callstack entries. If the message /// is not a valid compiler message null is returned. /// </summary> /// <param name="message">Message to parse.</param> /// <returns>Parsed log message or null if not a valid compiler message.</returns> public static ParsedLogEntry ParseCompilerMessage(string message) { // Note: If modifying FormMessage method make sure to update this one as well to match the formattting // Check for error Regex regex = new Regex(@"Compiler error: (.*)\n\tin (.*)\[(.*):.*\]"); var match = regex.Match(message); // Check for warning if (!match.Success) { regex = new Regex(@"Compiler warning: (.*)\n\tin (.*)\[(.*):.*\]"); match = regex.Match(message); } // No match if (!match.Success) { return(null); } ParsedLogEntry entry = new ParsedLogEntry(); entry.callstack = new CallStackEntry[1]; entry.message = match.Groups[1].Value; CallStackEntry callstackEntry = new CallStackEntry(); callstackEntry.method = ""; callstackEntry.file = match.Groups[2].Value; int.TryParse(match.Groups[3].Value, out callstackEntry.line); entry.callstack[0] = callstackEntry; return(entry); }
/// <summary> /// Parses a log message and outputs a data object with a separate message and callstack entries. /// </summary> /// <param name="message">Message to parse.</param> /// <returns>Parsed log message.</returns> public static ParsedLogEntry ParseLogMessage(string message) { // Note: If you are modifying GetStackTrace method make sure to also update this one to match the formattting int firstMatchIdx = -1; Regex regex = new Regex(@"\tat (.*) in (.*), line (\d*), column .*, namespace .*"); var matches = regex.Matches(message); ParsedLogEntry newEntry = new ParsedLogEntry(); newEntry.callstack = new CallStackEntry[matches.Count]; for (int i = 0; i < matches.Count; i++) { CallStackEntry callstackEntry = new CallStackEntry(); callstackEntry.method = matches[i].Groups[1].Value; callstackEntry.file = matches[i].Groups[2].Value; int.TryParse(matches[i].Groups[3].Value, out callstackEntry.line); newEntry.callstack[i] = callstackEntry; if (firstMatchIdx == -1) { firstMatchIdx = matches[i].Index; } } if (firstMatchIdx != -1) { newEntry.message = message.Substring(0, firstMatchIdx); } else { newEntry.message = message; } return(newEntry); }
/// <summary> /// Updates the contents of the details panel according to the currently selected element. /// </summary> private void RefreshDetailsPanel() { detailsArea.Layout.Clear(); if (sSelectedElementIdx != -1) { GUILayoutX paddingX = detailsArea.Layout.AddLayoutX(); paddingX.AddSpace(5); GUILayoutY paddingY = paddingX.AddLayoutY(); paddingX.AddSpace(5); paddingY.AddSpace(5); GUILayoutY mainLayout = paddingY.AddLayoutY(); paddingY.AddSpace(5); ConsoleEntryData entry = filteredEntries[sSelectedElementIdx]; LocString message = new LocEdString(entry.message); GUILabel messageLabel = new GUILabel(message, EditorStyles.MultiLineLabel, GUIOption.FlexibleHeight()); mainLayout.AddElement(messageLabel); mainLayout.AddSpace(10); if (entry.callstack != null) { foreach (var call in entry.callstack) { string fileName = Path.GetFileName(call.file); string callMessage; if (string.IsNullOrEmpty(call.method)) { callMessage = "\tin " + fileName + ":" + call.line; } else { callMessage = "\t" + call.method + " in " + fileName + ":" + call.line; } GUIButton callBtn = new GUIButton(new LocEdString(callMessage)); mainLayout.AddElement(callBtn); CallStackEntry hoistedCall = call; callBtn.OnClick += () => { CodeEditor.OpenFile(hoistedCall.file, hoistedCall.line); }; } } mainLayout.AddFlexibleSpace(); } else { GUILayoutX centerX = detailsArea.Layout.AddLayoutX(); centerX.AddFlexibleSpace(); GUILayoutY centerY = centerX.AddLayoutY(); centerX.AddFlexibleSpace(); centerY.AddFlexibleSpace(); GUILabel nothingSelectedLbl = new GUILabel(new LocEdString("(No entry selected)")); centerY.AddElement(nothingSelectedLbl); centerY.AddFlexibleSpace(); } }
private void treeView1_MouseClick(object sender, MouseEventArgs e) { if (e.Button != MouseButtons.Right) return; var node = treeView1.SelectedNode; if (node == null) return; clickedNode = node as CallStackEntry; var relativeMousePosition = treeView1.PointToClient(Cursor.Position); MenuItem menu = new MenuItem(clickedNode.Text); menu.Enabled = false; ContextMenu m = new ContextMenu(); m.MenuItems.Add(menu); m.MenuItems.Add(new MenuItem("Copy to &Clipboard", new EventHandler(MenuItem3_Click))); m.MenuItems.Add(new MenuItem("&Jump to", new EventHandler(MenuItem1_Click))); m.MenuItems.Add(new MenuItem("Set &Breakpoint", new EventHandler(MenuItem2_Click))); m.Show(treeView1, relativeMousePosition); }