public HexQuickInfoSessionImpl(HexView hexView, HexCellPosition triggerPoint, bool trackMouse, HexIntellisensePresenterFactoryService intellisensePresenterFactoryService, Lazy <HexQuickInfoSourceProvider, VSUTIL.IOrderable>[] quickInfoSourceProviders) { if (hexView == null) { throw new ArgumentNullException(nameof(hexView)); } if (triggerPoint.IsDefault) { throw new ArgumentException(); } if (intellisensePresenterFactoryService == null) { throw new ArgumentNullException(nameof(intellisensePresenterFactoryService)); } if (quickInfoSourceProviders == null) { throw new ArgumentNullException(nameof(quickInfoSourceProviders)); } QuickInfoContent = new VSLI.BulkObservableCollection <object>(); HexView = hexView; TriggerPoint = triggerPoint; TrackMouse = trackMouse; this.intellisensePresenterFactoryService = intellisensePresenterFactoryService; this.quickInfoSourceProviders = quickInfoSourceProviders; HexView.Closed += HexView_Closed; }
public bool TryUpdate(HexCellPosition cellPosition, HexBufferLine line, HexCell cell) { if (cell == null) { return(false); } var oldBufferSpan = BufferSpan; Debug.Assert(cell.BufferSpan.Length <= Data.Length); BufferSpan = cell.BufferSpan; bool dataDifferent; if (oldBufferSpan != BufferSpan) { BufferSpan.Buffer.ReadBytes(BufferSpan.Start, TempData); dataDifferent = !CompareArrays(TempData, Data); if (dataDifferent) { Array.Copy(TempData, Data, Data.Length); } } else { dataDifferent = false; } return(dataDifferent); }
bool Intersects(HexBufferSpanSelection span, HexCellPosition point) { if (span.IsDefault) return false; if (point.BufferPosition.Buffer != span.BufferSpan.Buffer) return false; return span.BufferSpan.IntersectsWith(new HexSpan(point.BufferPosition, 0)); }
void InitializeState(HexViewUIState state) { if (IsValid(state)) { HexView.Options.SetOptionValue(DefaultHexViewOptions.ShowOffsetColumnId, state.ShowOffsetColumn); HexView.Options.SetOptionValue(DefaultHexViewOptions.ShowValuesColumnId, state.ShowValuesColumn); HexView.Options.SetOptionValue(DefaultHexViewOptions.ShowAsciiColumnId, state.ShowAsciiColumn); HexView.Options.SetOptionValue(DefaultHexViewOptions.StartPositionId, state.StartPosition); HexView.Options.SetOptionValue(DefaultHexViewOptions.EndPositionId, state.EndPosition); HexView.Options.SetOptionValue(DefaultHexViewOptions.BasePositionId, state.BasePosition); HexView.Options.SetOptionValue(DefaultHexViewOptions.UseRelativePositionsId, state.UseRelativePositions); HexView.Options.SetOptionValue(DefaultHexViewOptions.OffsetBitSizeId, state.OffsetBitSize); HexView.Options.SetOptionValue(DefaultHexViewOptions.HexValuesDisplayFormatId, state.HexValuesDisplayFormat); HexView.Options.SetOptionValue(DefaultHexViewOptions.BytesPerLineId, state.BytesPerLine); HexView.ViewportLeft = state.ViewportLeft; HexView.DisplayHexLineContainingBufferPosition(new HexBufferPoint(HexView.Buffer, state.TopLinePosition), state.TopLineVerticalDistance, VSTE.ViewRelativePosition.Top, null, null, DisplayHexLineOptions.CanRecreateBufferLines); var valuesPos = new HexCellPosition(HexColumnType.Values, new HexBufferPoint(HexView.Buffer, state.ValuesPosition), state.ValuesCellPosition); var asciiPos = new HexCellPosition(HexColumnType.Ascii, new HexBufferPoint(HexView.Buffer, state.AsciiPosition), 0); var newPos = new HexColumnPosition(state.ActiveColumn, valuesPos, asciiPos); // BufferLines could've been recreated, re-verify the new position if (HexView.BufferLines.IsValidPosition(newPos.ValuePosition.BufferPosition) && HexView.BufferLines.IsValidPosition(newPos.AsciiPosition.BufferPosition)) { HexView.Caret.MoveTo(newPos); } } else { HexView.Caret.MoveTo(HexView.BufferLines.BufferStart); } HexView.Selection.Clear(); }
void HexView_MouseHover(object sender, HexMouseHoverEventArgs e) { var posInfo = e.Line.GetLinePositionInfo(e.TextPosition); HexCellPosition triggerPoint; if (posInfo.IsAsciiCell && posInfo.Cell.HasData) triggerPoint = new HexCellPosition(HexColumnType.Ascii, posInfo.Cell.BufferStart, posInfo.CellPosition); else if (posInfo.IsValueCell && posInfo.Cell.HasData) triggerPoint = new HexCellPosition(HexColumnType.Values, hexView.BufferLines.GetValueBufferSpan(posInfo.Cell, posInfo.CellPosition).Start, posInfo.CellPosition); else if (posInfo.IsValueCellSeparator && posInfo.Cell.HasData) triggerPoint = new HexCellPosition(HexColumnType.Values, hexView.BufferLines.GetValueBufferSpan(posInfo.Cell, posInfo.Cell.TextSpan.Length - 1).Start, posInfo.Cell.TextSpan.Length - 1); else return; var sessions = quickInfoBroker.GetSessions(hexView); foreach (var session in sessions) { if (Intersects(session.ApplicableToSpan, triggerPoint)) return; if (session.HasInteractiveContent) { foreach (var o in session.QuickInfoContent) { var io = o as IHexInteractiveQuickInfoContent; if (io == null) continue; if (io.KeepQuickInfoOpen || io.IsMouseOverAggregated) return; } } } foreach (var session in sessions) session.Dismiss(); quickInfoBroker.TriggerQuickInfo(hexView, triggerPoint, trackMouse: true); }
public override HexQuickInfoSession TriggerQuickInfo(HexView hexView, HexCellPosition triggerPoint, bool trackMouse) { if (hexView == null) throw new ArgumentNullException(nameof(hexView)); if (triggerPoint.IsDefault) throw new ArgumentException(); var session = CreateQuickInfoSession(hexView, triggerPoint, trackMouse); session.Start(); return session.IsDismissed ? null : session; }
void HexView_MouseHover(object sender, HexMouseHoverEventArgs e) { var posInfo = e.Line.GetLinePositionInfo(e.TextPosition); HexCellPosition triggerPoint; if (posInfo.IsAsciiCell && posInfo.Cell !.HasData) { triggerPoint = new HexCellPosition(HexColumnType.Ascii, posInfo.Cell.BufferStart, posInfo.CellPosition); }
void SetPresentationSpan(HexBufferSpanSelection newValue, HexCellPosition triggerPoint) { // Make sure that the popup is shown in the right column newValue = new HexBufferSpanSelection(newValue.BufferSpan, HexSpanSelectionFlags.Cell | (triggerPoint.Column == HexColumnType.Values ? HexSpanSelectionFlags.Values : HexSpanSelectionFlags.Ascii)); if (!presentationSpan.Equals(newValue)) { presentationSpan = newValue; PresentationSpanChanged?.Invoke(this, EventArgs.Empty); } }
public override HexQuickInfoSession CreateQuickInfoSession(HexView hexView, HexCellPosition triggerPoint, bool trackMouse) { if (hexView == null) throw new ArgumentNullException(nameof(hexView)); if (triggerPoint.IsDefault) throw new ArgumentException(); var stack = intellisenseSessionStackMapService.Value.GetStackForHexView(hexView); var session = new HexQuickInfoSessionImpl(hexView, triggerPoint, trackMouse, intellisensePresenterFactoryService.Value, quickInfoSourceProviders); stack.PushSession(session); return session; }
bool Intersects(HexBufferSpanSelection span, HexCellPosition point) { if (span.IsDefault) { return(false); } if (point.BufferPosition.Buffer != span.BufferSpan.Buffer) { return(false); } return(span.BufferSpan.IntersectsWith(new HexSpan(point.BufferPosition, 0))); }
void HexView_MouseHover(object sender, HexMouseHoverEventArgs e) { var posInfo = e.Line.GetLinePositionInfo(e.TextPosition); HexCellPosition triggerPoint; if (posInfo.IsAsciiCell && posInfo.Cell.HasData) { triggerPoint = new HexCellPosition(HexColumnType.Ascii, posInfo.Cell.BufferStart, posInfo.CellPosition); } else if (posInfo.IsValueCell && posInfo.Cell.HasData) { triggerPoint = new HexCellPosition(HexColumnType.Values, hexView.BufferLines.GetValueBufferSpan(posInfo.Cell, posInfo.CellPosition).Start, posInfo.CellPosition); } else if (posInfo.IsValueCellSeparator && posInfo.Cell.HasData) { triggerPoint = new HexCellPosition(HexColumnType.Values, hexView.BufferLines.GetValueBufferSpan(posInfo.Cell, posInfo.Cell.CellSpan.Length - 1).Start, posInfo.Cell.CellSpan.Length - 1); } else { return; } var sessions = quickInfoBroker.GetSessions(hexView); foreach (var session in sessions) { if (Intersects(session.ApplicableToSpan, triggerPoint)) { return; } if (session.HasInteractiveContent) { foreach (var o in session.QuickInfoContent) { var io = o as IHexInteractiveQuickInfoContent; if (io == null) { continue; } if (io.KeepQuickInfoOpen || io.IsMouseOverAggregated) { return; } } } } foreach (var session in sessions) { session.Dismiss(); } quickInfoBroker.TriggerQuickInfo(hexView, triggerPoint, trackMouse: true); }
public override HexCaretPosition MoveTo(HexCellPosition position, HexMoveToFlags flags) { if (position.IsDefault) { throw new ArgumentException(); } if (!hexView.BufferLines.IsValidPosition(position.BufferPosition)) { throw new ArgumentOutOfRangeException(nameof(position)); } var colPos = CreateColumnPosition(position); return(MoveTo(colPos, flags)); }
public SavedValue(HexValuesDisplayFormat valuesFormat, int size, HexCellPosition cellPosition, HexBufferSpan cellBufferSpan) { ValuesFormat = valuesFormat; Data = new byte[size]; TempData = new byte[size]; BufferSpan = cellBufferSpan; Column = cellPosition.Column; // Note that BufferSpan.Length could be less than Data.Length if cell // byte size > 1 and there's not enough bytes at the end of the buffer // for the full cell. Debug.Assert(BufferSpan.Length <= Data.Length); BufferSpan.Buffer.ReadBytes(BufferSpan.Start, Data); }
public override HexQuickInfoSession?TriggerQuickInfo(HexView hexView, HexCellPosition triggerPoint, bool trackMouse) { if (hexView is null) { throw new ArgumentNullException(nameof(hexView)); } if (triggerPoint.IsDefault) { throw new ArgumentException(); } var session = CreateQuickInfoSession(hexView, triggerPoint, trackMouse); session.Start(); return(session.IsDismissed ? null : session); }
public override HexQuickInfoSession CreateQuickInfoSession(HexView hexView, HexCellPosition triggerPoint, bool trackMouse) { if (hexView is null) { throw new ArgumentNullException(nameof(hexView)); } if (triggerPoint.IsDefault) { throw new ArgumentException(); } var stack = intellisenseSessionStackMapService.Value.GetStackForHexView(hexView); var session = new HexQuickInfoSessionImpl(hexView, triggerPoint, trackMouse, intellisensePresenterFactoryService.Value, quickInfoSourceProviders); stack.PushSession(session); return(session); }
static bool CanReUse(HexCellPosition oldPos, HexCellPosition newPos, HexCell cell) { if (oldPos.IsDefault) { return(false); } if (oldPos.IsDefault != newPos.IsDefault) { return(false); } if (cell == null) { return(newPos.IsDefault); } return(cell.BufferSpan.Contains(oldPos.BufferPosition)); }
HexColumnPosition CreateColumnPosition(HexCellPosition position) { switch (position.Column) { case HexColumnType.Values: var asciiPosition = new HexCellPosition(HexColumnType.Ascii, position.BufferPosition, 0); return(new HexColumnPosition(position.Column, position, asciiPosition)); case HexColumnType.Ascii: var valuesPosition = CreateValuesCellPosition(position.BufferPosition); return(new HexColumnPosition(position.Column, valuesPosition, position)); case HexColumnType.Offset: default: throw new ArgumentOutOfRangeException(nameof(position)); } }
public HexQuickInfoSessionImpl(HexView hexView, HexCellPosition triggerPoint, bool trackMouse, HexIntellisensePresenterFactoryService intellisensePresenterFactoryService, Lazy<HexQuickInfoSourceProvider, VSUTIL.IOrderable>[] quickInfoSourceProviders) { if (hexView == null) throw new ArgumentNullException(nameof(hexView)); if (triggerPoint.IsDefault) throw new ArgumentException(); if (intellisensePresenterFactoryService == null) throw new ArgumentNullException(nameof(intellisensePresenterFactoryService)); if (quickInfoSourceProviders == null) throw new ArgumentNullException(nameof(quickInfoSourceProviders)); QuickInfoContent = new VSLI.BulkObservableCollection<object>(); HexView = hexView; TriggerPoint = triggerPoint; TrackMouse = trackMouse; this.intellisensePresenterFactoryService = intellisensePresenterFactoryService; this.quickInfoSourceProviders = quickInfoSourceProviders; HexView.Closed += HexView_Closed; }
HexCaretPosition MoveTo(HexViewLine hexLine, double xCoordinate, HexMoveToFlags flags, bool captureVerticalPosition) { if (hexLine == null) { throw new ArgumentNullException(nameof(hexLine)); } if (hexLine.BufferLine.LineProvider != hexView.BufferLines) { throw new ArgumentException(); } var linePosition = (flags & HexMoveToFlags.InsertionPosition) != 0 ? hexLine.GetInsertionLinePositionFromXCoordinate(xCoordinate) : hexLine.GetVirtualLinePositionFromXCoordinate(xCoordinate); var posInfo = hexLine.BufferLine.GetLinePositionInfo(linePosition); if (posInfo.IsValueCellSeparator) { var posInfo2 = hexLine.BufferLine.GetLinePositionInfo(hexLine.GetInsertionLinePositionFromXCoordinate(xCoordinate)); if (posInfo2.IsValueCell) { posInfo = posInfo2; } } var closestPos = hexLine.BufferLine.GetClosestCellPosition(posInfo, onlyVisibleCells: true); if (closestPos == null) { Debug.Assert(hexView.BufferLines.BufferSpan.Length == 0 || (!IsValuesCaretPresent && !IsAsciiCaretPresent)); closestPos = new HexCellPosition(currentPosition.ActiveColumn, hexLine.BufferStart, 0); } SetExplicitPosition(CreateColumnPosition(closestPos.Value)); if ((flags & HexMoveToFlags.CaptureHorizontalPosition) != 0) { SavePreferredXCoordinate(); } if (captureVerticalPosition) { SavePreferredYCoordinate(); } return(Position); }
HexCellPosition Filter(HexCellPosition position) => new HexCellPosition(position.Column, hexView.BufferLines.FilterAndVerify(position.BufferPosition), position.CellPosition);
HexColumnPosition GetUpdatedCaretPosition() { var bufferLines = hexView.BufferLines; if ((!IsValuesCaretPresent && !IsAsciiCaretPresent) || bufferLines.BufferSpan.Length == 0) { return(new HexColumnPosition(HexColumnType.Values, new HexCellPosition(HexColumnType.Values, hexView.BufferLines.BufferStart, 0), new HexCellPosition(HexColumnType.Ascii, hexView.BufferLines.BufferStart, 0))); } var activeColumn = currentPosition.ActiveColumn; var valuePosition = currentPosition.ValuePosition; var asciiPosition = currentPosition.AsciiPosition; // Use ASCII's buffer position since it's more accurate var bufferPosition = asciiPosition.BufferPosition; if (bufferPosition.IsDefault) { bufferPosition = valuePosition.BufferPosition; } if (bufferPosition.IsDefault) { bufferPosition = bufferLines.BufferStart; } if (bufferPosition < bufferLines.BufferStart) { bufferPosition = bufferLines.BufferStart; } else if (bufferPosition > bufferLines.BufferEnd) { bufferPosition = bufferLines.BufferEnd; } if (bufferPosition >= HexPosition.MaxEndPosition) { bufferPosition = new HexBufferPoint(bufferLines.Buffer, HexPosition.MaxEndPosition - 1); } var caretLine = bufferLines.GetLineFromPosition(bufferPosition); var valueCell = caretLine.ValueCells.GetCell(bufferPosition); var asciiCell = caretLine.AsciiCells.GetCell(bufferPosition); switch (activeColumn) { case HexColumnType.Values: if (valueCell == null) { activeColumn = HexColumnType.Ascii; } break; case HexColumnType.Ascii: if (asciiCell == null) { activeColumn = HexColumnType.Values; } break; case HexColumnType.Offset: default: throw new InvalidOperationException(); } HexCellPosition newValuePosition, newAsciiPosition; if (valueCell == null) { newValuePosition = new HexCellPosition(HexColumnType.Values, hexView.BufferLines.BufferStart, 0); } else { newValuePosition = new HexCellPosition(HexColumnType.Values, valueCell.BufferStart, 0); } if (asciiCell == null) { newAsciiPosition = new HexCellPosition(HexColumnType.Ascii, hexView.BufferLines.BufferStart, 0); } else { newAsciiPosition = new HexCellPosition(HexColumnType.Ascii, valueCell?.BufferStart ?? asciiCell.BufferStart, 0); } bool keepPositions = CanReUse(valuePosition, newValuePosition, valueCell) && CanReUse(asciiPosition, newAsciiPosition, asciiCell); if (keepPositions) { return(currentPosition); } return(new HexColumnPosition(activeColumn, newValuePosition, newAsciiPosition)); }
bool PasteValues(HexCellPosition cellPosition) { var data = ClipboardUtils.GetData(canBeEmpty: false); if (data == null) return false; return PasteData(cellPosition, data); }
bool InsertTextAscii(HexCellPosition cellPosition, string text) { if (text == null) throw new ArgumentNullException(nameof(text)); if (text.Length == 0) return true; var encoding = Options.TryGetEncoding(); Debug.Assert(encoding != null); if (encoding == null) return false; var bytes = encoding.GetBytes(text); using (var ed = HexView.Buffer.CreateEdit()) { if (!ed.Replace(cellPosition.BufferPosition, bytes)) return false; ed.Apply(); } var newPos = cellPosition.BufferPosition + bytes.LongLength; if (newPos > BufferLines.BufferEnd) newPos = BufferLines.BufferEnd; Caret.MoveTo(newPos); Caret.EnsureVisible(); Selection.Clear(); return true; }
/// <summary> /// Creates a quick info session /// </summary> /// <param name="hexView">Hex view</param> /// <param name="triggerPoint">Trigger point</param> /// <param name="trackMouse">true to track the mouse</param> /// <returns></returns> public abstract HexQuickInfoSession CreateQuickInfoSession(HexView hexView, HexCellPosition triggerPoint, bool trackMouse);
bool PasteData(HexCellPosition cellPosition, byte[] data) { var line = BufferLines.GetLineFromPosition(cellPosition.BufferPosition); var cells = cellPosition.Column == HexColumnType.Values ? line.ValueCells : line.AsciiCells; var cell = cells.GetCell(cellPosition.BufferPosition); if (cell == null) return false; var pos = cell.BufferStart; using (var ed = HexView.Buffer.CreateEdit()) { if (!ed.Replace(pos, data)) return false; ed.Apply(); } var newPos = pos + data.LongLength; if (newPos > BufferLines.BufferEnd) newPos = BufferLines.BufferEnd; Caret.MoveTo(newPos); Caret.EnsureVisible(); Selection.Clear(); return true; }
void InitializeState(HexViewUIState state) { if (IsValid(state)) { HexView.Options.SetOptionValue(DefaultHexViewOptions.ShowOffsetColumnId, state.ShowOffsetColumn); HexView.Options.SetOptionValue(DefaultHexViewOptions.ShowValuesColumnId, state.ShowValuesColumn); HexView.Options.SetOptionValue(DefaultHexViewOptions.ShowAsciiColumnId, state.ShowAsciiColumn); HexView.Options.SetOptionValue(DefaultHexViewOptions.StartPositionId, state.StartPosition); HexView.Options.SetOptionValue(DefaultHexViewOptions.EndPositionId, state.EndPosition); HexView.Options.SetOptionValue(DefaultHexViewOptions.BasePositionId, state.BasePosition); HexView.Options.SetOptionValue(DefaultHexViewOptions.UseRelativePositionsId, state.UseRelativePositions); HexView.Options.SetOptionValue(DefaultHexViewOptions.OffsetBitSizeId, state.OffsetBitSize); HexView.Options.SetOptionValue(DefaultHexViewOptions.HexValuesDisplayFormatId, state.HexValuesDisplayFormat); HexView.Options.SetOptionValue(DefaultHexViewOptions.BytesPerLineId, state.BytesPerLine); HexView.ViewportLeft = state.ViewportLeft; HexView.DisplayHexLineContainingBufferPosition(new HexBufferPoint(HexView.Buffer, state.TopLinePosition), state.TopLineVerticalDistance, VSTE.ViewRelativePosition.Top, null, null, DisplayHexLineOptions.CanRecreateBufferLines); var valuesPos = new HexCellPosition(HexColumnType.Values, new HexBufferPoint(HexView.Buffer, state.ValuesPosition), state.ValuesCellPosition); var asciiPos = new HexCellPosition(HexColumnType.Ascii, new HexBufferPoint(HexView.Buffer, state.AsciiPosition), 0); var newPos = new HexColumnPosition(state.ActiveColumn, valuesPos, asciiPos); // BufferLines could've been recreated, re-verify the new position if (HexView.BufferLines.IsValidPosition(newPos.ValuePosition.BufferPosition) && HexView.BufferLines.IsValidPosition(newPos.AsciiPosition.BufferPosition)) HexView.Caret.MoveTo(newPos); } else HexView.Caret.MoveTo(HexView.BufferLines.BufferStart); HexView.Selection.Clear(); }
/// <summary> /// Moves the caret to a new position /// </summary> /// <param name="position">Position</param> /// <param name="flags">Flags</param> /// <returns></returns> public abstract HexCaretPosition MoveTo(HexCellPosition position, HexMoveToFlags flags);
bool InsertTextValues(HexCellPosition cellPosition, string text) { if (text == null) throw new ArgumentNullException(nameof(text)); if (text.Length == 0) return true; if (text.Length != 1) return false; var bufferLines = BufferLines; if (!bufferLines.CanEditValueCell) return false; var line = bufferLines.GetLineFromPosition(cellPosition.BufferPosition); var cell = line.ValueCells.GetCell(cellPosition.BufferPosition); if (cell == null) return false; if ((uint)cellPosition.CellPosition >= (uint)cell.CellSpan.Length) return false; var newValue = bufferLines.EditValueCell(cell, cellPosition.CellPosition, text[0]); if (newValue == null) return false; using (var ed = HexView.Buffer.CreateEdit()) { if (!ed.Replace(newValue.Value.Position, newValue.Value.Data)) return false; ed.Apply(); } MoveToNextCharacter(false); return true; }
/// <summary> /// Moves the caret to a new position /// </summary> /// <param name="position">Position</param> /// <returns></returns> public HexCaretPosition MoveTo(HexCellPosition position) => MoveTo(position, HexMoveToFlags.CaptureHorizontalPosition);
/// <summary> /// Gets a text line position or null /// </summary> /// <param name="position">Position</param> /// <returns></returns> public int? GetLinePosition(HexCellPosition position) { if (position.IsDefault) throw new ArgumentException(); HexCellCollection collection; switch (position.Column) { case HexColumnType.Values: collection = ValueCells; break; case HexColumnType.Ascii: collection = AsciiCells; break; case HexColumnType.Offset: default: throw new ArgumentOutOfRangeException(nameof(position)); } var cell = collection.GetCell(position.BufferPosition); if (cell == null) return null; if (position.CellPosition >= cell.CellSpan.Length) return null; return cell.CellSpan.Start + position.CellPosition; }
bool PasteAscii(HexCellPosition cellPosition) { var text = ClipboardUtils.GetText(canBeEmpty: false); if (text == null) return false; return InsertTextAscii(cellPosition, text); }