/// <summary> /// Resets the selection state of all selected nodes. /// </summary> public void ClearSelection() { selectionAnchor = selectionCaret = null; selectedNodes.ForEach(h => h.Node.ClearSelection()); selectedNodes.Clear(); OnSelectionChanged(); //Invalidate(); }
public void ReplaceSelectedNodesWithType(Type type) { Contract.Requires(type != null); Contract.Requires(type.IsSubclassOf(typeof(BaseNode))); var newSelected = new List <HotSpot>(selectedNodes.Count); foreach (var selected in selectedNodes.Where(s => !(s.Node is ClassNode))) { var node = Activator.CreateInstance(type) as BaseNode; node.Intialize(); if (selected.Node.ParentNode.ReplaceChildNode(selected.Node, node)) { node.IsSelected = true; var hotspot = new HotSpot { Address = node.ParentNode.Offset.Add(node.Offset), Node = node }; newSelected.Add(hotspot); if (selectionAnchor.Node == selected.Node) { selectionAnchor = hotspot; } if (selectionCaret.Node == selected.Node) { selectionCaret = hotspot; } } } if (newSelected.Count > 0) { selectedNodes.Clear(); selectedNodes.AddRange(newSelected); OnSelectionChanged(); } Invalidate(); }
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { if (editBox.Visible == false) // Only process keys if the edit field is not visible. { var key = keyData & Keys.KeyCode; var modifier = keyData & Keys.Modifiers; if (selectedNodes.Count > 0) { if (key == Keys.Delete) { RemoveSelectedNodes(); return(true); } else if (key == Keys.Menu) { selectedNodeContextMenuStrip.Show(this, 10, 10); return(true); } else if (modifier == Keys.Control && (key == Keys.C || key == Keys.V)) { if (key == Keys.C) { CopySelectedNodesToClipboard(); } else if (key == Keys.V) { PasteNodeFromClipboardToSelection(); } return(true); } else if (key == Keys.Down || key == Keys.Up) { HotSpot toSelect = null; if (key == Keys.Down) { toSelect = hotSpots .SkipUntil(h => h.Node == selectionCaret.Node) .Where(h => h.Type == HotSpotType.Select) .Where(h => h.Node.ParentNode == selectionCaret.Node.ParentNode) .FirstOrDefault(); } else { toSelect = hotSpots .TakeWhile(h => h.Node != selectionCaret.Node) .Where(h => h.Type == HotSpotType.Select) .Where(h => h.Node.ParentNode == selectionCaret.Node.ParentNode) .LastOrDefault(); } if (toSelect != null) { if (modifier != Keys.Shift) { selectionAnchor = selectionCaret = toSelect; } else { selectionCaret = toSelect; } var first = Utils.Min(selectionAnchor, selectionCaret, h => h.Node.Offset.ToInt32()); var last = first == selectionAnchor ? selectionCaret : selectionAnchor; ClearSelection(); var containerNode = toSelect.Node.ParentNode; foreach (var spot in containerNode.Nodes .SkipWhile(n => n != first.Node) .TakeUntil(n => n == last.Node) .Select(n => new HotSpot { Address = containerNode.Offset.Add(n.Offset), Node = n })) { spot.Node.IsSelected = true; selectedNodes.Add(spot); } OnSelectionChanged(); Invalidate(); return(true); } } } else if (key == Keys.Down || key == Keys.Up) { // If no node is selected, try to select the first one. var selection = hotSpots .Where(h => h.Type == HotSpotType.Select) .Where(h => !(h.Node is ClassNode)) .FirstOrDefault(); if (selection != null) { selectionAnchor = selectionCaret = selection; selection.Node.IsSelected = true; selectedNodes.Add(selection); OnSelectionChanged(); return(true); } } } return(base.ProcessCmdKey(ref msg, keyData)); }
protected override void OnMouseClick(MouseEventArgs e) { editBox.Visible = false; foreach (var hotSpot in hotSpots) { if (hotSpot.Rect.Contains(e.Location)) { try { var hitObject = hotSpot.Node; if (hotSpot.Type == HotSpotType.OpenClose) { hitObject.ToggleLevelOpen(hotSpot.Level); } else if (hotSpot.Type == HotSpotType.Click) { hitObject.Update(hotSpot); } else if (hotSpot.Type == HotSpotType.Select) { if (e.Button == MouseButtons.Left) { if (ModifierKeys == Keys.None) { ClearSelection(); hitObject.IsSelected = true; selectedNodes.Add(hotSpot); OnSelectionChanged(); selectionAnchor = selectionCaret = hotSpot; } else if (ModifierKeys == Keys.Control) { hitObject.IsSelected = !hitObject.IsSelected; if (hitObject.IsSelected) { selectedNodes.Add(hotSpot); } else { selectedNodes.Remove(selectedNodes.Where(c => c.Node == hitObject).FirstOrDefault()); } OnSelectionChanged(); } else if (ModifierKeys == Keys.Shift) { if (selectedNodes.Count > 0) { var selectedNode = selectedNodes[0].Node; if (hitObject.ParentNode != null && selectedNode.ParentNode != hitObject.ParentNode) { continue; } var first = Utils.Min(selectedNodes[0], hotSpot, h => h.Node.Offset.ToInt32()); var last = first == hotSpot ? selectedNodes[0] : hotSpot; ClearSelection(); var containerNode = selectedNode.ParentNode; foreach (var spot in containerNode.Nodes .SkipWhile(n => n != first.Node) .TakeUntil(n => n == last.Node) .Select(n => new HotSpot { Address = containerNode.Offset.Add(n.Offset), Node = n })) { spot.Node.IsSelected = true; selectedNodes.Add(spot); } OnSelectionChanged(); selectionAnchor = first; selectionCaret = last; } } } else if (e.Button == MouseButtons.Right) { // If there is only one selected node, select the node the user clicked at. if (selectedNodes.Count <= 1) { ClearSelection(); hitObject.IsSelected = true; selectedNodes.Add(hotSpot); OnSelectionChanged(); selectionAnchor = selectionCaret = hotSpot; } selectedNodeContextMenuStrip.Show(this, e.Location); } } else if (hotSpot.Type == HotSpotType.Drop) { selectedNodeContextMenuStrip.Show(this, e.Location); } else if (hotSpot.Type == HotSpotType.Delete) { RemoveSelectedNodes(); } else if (hotSpot.Type == HotSpotType.ChangeType) { var refNode = hitObject as BaseReferenceNode; if (refNode != null) { EventHandler changeInnerType = (sender2, e2) => { var classNode = (sender2 as TypeToolStripMenuItem)?.Tag as ClassNode; if (classNode == null) { return; } if (IsCycleFree(refNode.ParentNode as ClassNode, classNode)) { refNode.ChangeInnerNode(classNode); } }; var menu = new ContextMenuStrip(); menu.Items.AddRange( project.Classes .OrderBy(c => c.Name) .Select(c => { var b = new TypeToolStripMenuItem { Text = c.Name, Tag = c }; b.Click += changeInnerType; return(b); }) .ToArray() ); menu.Show(this, e.Location); } } } catch (Exception ex) { Program.Logger.Log(ex); } Invalidate(); } } base.OnMouseClick(e); }
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { if (editBox.Visible == false) // Only process keys if the edit field is not visible. { var key = keyData & Keys.KeyCode; var modifier = keyData & Keys.Modifiers; if (selectedNodes.Count > 0) { if (key == Keys.Menu) { ShowNodeContextMenu(new Point(10, 10)); return(true); } if ((key == Keys.Down || key == Keys.Up) && selectionCaret != null && selectionAnchor != null) { HotSpot toSelect; bool isAtEnd; var query = hotSpots .Where(h => h.Type == HotSpotType.Select) .Where(h => h.Node.GetParentContainer() == selectionCaret.Node.GetParentContainer()); if (key == Keys.Down) { var temp = query .SkipWhile(h => h.Node != selectionCaret.Node) .Skip(1) .ToList(); toSelect = temp.FirstOrDefault(); isAtEnd = toSelect != null && toSelect == temp.LastOrDefault(); } else { var temp = query .TakeWhile(h => h.Node != selectionCaret.Node) .ToList(); toSelect = temp.LastOrDefault(); isAtEnd = toSelect != null && toSelect == temp.FirstOrDefault(); } if (toSelect != null && !(toSelect.Node is ClassNode)) { if (modifier != Keys.Shift) { selectionAnchor = selectionCaret = toSelect; } else { selectionCaret = toSelect; } var first = Utils.Min(selectionAnchor, selectionCaret, h => h.Node.Offset); var last = first == selectionAnchor ? selectionCaret : selectionAnchor; selectedNodes.ForEach(h => h.Node.ClearSelection()); selectedNodes.Clear(); var containerNode = toSelect.Node.GetParentContainer(); foreach (var spot in containerNode.Nodes .SkipWhile(n => n != first.Node) .TakeWhileInclusive(n => n != last.Node) .Select(n => new HotSpot { Address = (IntPtr)(containerNode.Offset + n.Offset), Node = n, Process = toSelect.Process, Memory = toSelect.Memory, Level = toSelect.Level })) { spot.Node.IsSelected = true; selectedNodes.Add(spot); } OnSelectionChanged(); if (isAtEnd) { DoScroll(ScrollOrientation.VerticalScroll, key == Keys.Down ? 1 : -1); } Invalidate(); return(true); } } else if (key == Keys.Left || key == Keys.Right) { if (selectedNodes.Count == 1) { var selected = selectedNodes[0]; selected.Node.SetLevelOpen(selected.Level, key == Keys.Right); } } } else if (key == Keys.Down || key == Keys.Up) { // If no node is selected, try to select the first one. var selection = hotSpots .Where(h => h.Type == HotSpotType.Select) .WhereNot(h => h.Node is ClassNode) .FirstOrDefault(); if (selection != null) { selectionAnchor = selectionCaret = selection; selection.Node.IsSelected = true; selectedNodes.Add(selection); OnSelectionChanged(); return(true); } } } return(base.ProcessCmdKey(ref msg, keyData)); }
protected override void OnMouseClick(MouseEventArgs e) { Contract.Requires(e != null); var invalidate = false; foreach (var hotSpot in hotSpots) { if (hotSpot.Rect.Contains(e.Location)) { var hitObject = hotSpot.Node; if (hotSpot.Type == HotSpotType.OpenClose) { hitObject.ToggleLevelOpen(hotSpot.Level); invalidate = true; break; } if (hotSpot.Type == HotSpotType.Click) { hitObject.Update(hotSpot); invalidate = true; break; } if (hotSpot.Type == HotSpotType.Select) { if (e.Button == MouseButtons.Left) { if (ModifierKeys == Keys.None) { ClearSelection(); hitObject.IsSelected = true; selectedNodes.Add(hotSpot); OnSelectionChanged(); selectionAnchor = selectionCaret = hotSpot; } else if (ModifierKeys == Keys.Control) { hitObject.IsSelected = !hitObject.IsSelected; if (hitObject.IsSelected) { selectedNodes.Add(hotSpot); } else { selectedNodes.Remove(selectedNodes.FirstOrDefault(c => c.Node == hitObject)); } OnSelectionChanged(); } else if (ModifierKeys == Keys.Shift) { if (selectedNodes.Count > 0) { var selectedNode = selectedNodes[0].Node; if (hitObject.GetParentContainer() != null && selectedNode.GetParentContainer() != hitObject.GetParentContainer()) { continue; } if (hotSpot.Node is BaseContainerNode) { continue; } var first = Utils.Min(selectedNodes[0], hotSpot, h => h.Node.Offset); var last = first == hotSpot ? selectedNodes[0] : hotSpot; ClearSelection(); var containerNode = selectedNode.GetParentContainer(); foreach (var spot in containerNode.Nodes .SkipWhile(n => n != first.Node) .TakeWhileInclusive(n => n != last.Node) .Select(n => new HotSpot { Address = (IntPtr)(containerNode.Offset + n.Offset), Node = n, Process = first.Process, Memory = first.Memory, Level = first.Level })) { spot.Node.IsSelected = true; selectedNodes.Add(spot); } OnSelectionChanged(); selectionAnchor = first; selectionCaret = last; } } } else if (e.Button == MouseButtons.Right) { // If there is only one selected node, select the node the user clicked at. if (selectedNodes.Count <= 1) { ClearSelection(); hitObject.IsSelected = true; selectedNodes.Add(hotSpot); OnSelectionChanged(); selectionAnchor = selectionCaret = hotSpot; } ShowNodeContextMenu(e.Location); } invalidate = true; } else if (hotSpot.Type == HotSpotType.Context) { ShowNodeContextMenu(e.Location); break; } else if (hotSpot.Type == HotSpotType.Delete) { hotSpot.Node.GetParentContainer().RemoveNode(hotSpot.Node); invalidate = true; break; } else if (hotSpot.Type == HotSpotType.ChangeClassType || hotSpot.Type == HotSpotType.ChangeWrappedType || hotSpot.Type == HotSpotType.ChangeEnumType) { var handler = hotSpot.Type == HotSpotType.ChangeClassType ? ChangeClassTypeClick : hotSpot.Type == HotSpotType.ChangeWrappedType ? ChangeWrappedTypeClick : ChangeEnumTypeClick; handler?.Invoke(this, new NodeClickEventArgs(hitObject, hotSpot.Address, hotSpot.Memory, e.Button, e.Location)); break; } } } editBox.Visible = false; if (invalidate) { Invalidate(); } base.OnMouseClick(e); }
public void ReplaceSelectedNodesWithType(Type type) { Contract.Requires(type != null); Contract.Requires(type.IsSubclassOf(typeof(BaseNode))); var newSelected = new List <HotSpot>(selectedNodes.Count); // Group the selected nodes in continues selected blocks. foreach (var selectedPartition in PartitionSelectedNodes(selectedNodes.WhereNot(s => s.Node is ClassNode))) { foreach (var selected in selectedPartition) { var createdNodes = new List <BaseNode>(); if (selected.Node.ParentNode.ReplaceChildNode(selected.Node, type, ref createdNodes)) { var node = createdNodes.First(); node.IsSelected = true; var hotspot = new HotSpot { Memory = selected.Memory, Address = node.ParentNode.Offset.Add(node.Offset), Node = node }; newSelected.Add(hotspot); if (selectionAnchor.Node == selected.Node) { selectionAnchor = hotspot; } if (selectionCaret.Node == selected.Node) { selectionCaret = hotspot; } // If the block contains more than one node and the replaced node decomposed to more than one node replace the new nodes to. if (selectedPartition.Count > 1 && createdNodes.Count > 1) { newSelected.AddRange( RecursiveReplaceNodes(selected.Node.ParentNode, type, createdNodes.Skip(1)) .Select(n => new HotSpot { Memory = selected.Memory, Address = n.ParentNode.Offset.Add(n.Offset), Node = n, Level = selected.Level }) ); } } } } if (newSelected.Count > 0) { selectedNodes.Clear(); selectedNodes.AddRange(newSelected); OnSelectionChanged(); } Invalidate(); }