public HexBufferLineImpl(HexBufferLineFormatter hexBufferLineFormatter, HexPosition lineNumber, ReadOnlyCollection<HexColumnType> columnOrder, HexBufferSpan bufferSpan, HexBytes hexBytes, string text, bool isOffsetColumnPresent, bool isValuesColumnPresent, bool isAsciiColumnPresent, HexPosition logicalOffset, HexCellCollection valueCells, HexCellCollection asciiCells, VST.Span offsetSpan, VST.Span fullValuesSpan, VST.Span visibleValuesSpan, VST.Span fullAsciiSpan, VST.Span visibleAsciiSpan) { if (hexBufferLineFormatter == null) throw new ArgumentNullException(nameof(hexBufferLineFormatter)); if (columnOrder == null) throw new ArgumentNullException(nameof(columnOrder)); if (bufferSpan.IsDefault) throw new ArgumentException(); if (hexBytes.IsDefault) throw new ArgumentException(); if (text == null) throw new ArgumentNullException(nameof(text)); if (valueCells.IsDefault) throw new ArgumentNullException(nameof(valueCells)); if (asciiCells.IsDefault) throw new ArgumentNullException(nameof(asciiCells)); LineProvider = hexBufferLineFormatter; LineNumber = lineNumber; ColumnOrder = columnOrder; BufferSpan = bufferSpan; HexBytes = hexBytes; Text = text; IsOffsetColumnPresent = isOffsetColumnPresent; IsValuesColumnPresent = isValuesColumnPresent; IsAsciiColumnPresent = isAsciiColumnPresent; LogicalOffset = logicalOffset; ValueCells = valueCells; AsciiCells = asciiCells; this.offsetSpan = offsetSpan; this.fullValuesSpan = fullValuesSpan; this.visibleValuesSpan = visibleValuesSpan; this.fullAsciiSpan = fullAsciiSpan; this.visibleAsciiSpan = visibleAsciiSpan; }
public override void EnsureSpanVisible(HexBufferLine line, VST.Span span, VSTE.EnsureSpanVisibleOptions options) { if (line == null) throw new ArgumentNullException(nameof(line)); if (line.Buffer != hexView.Buffer) throw new ArgumentException(); EnsureSpanVisibleCore(new HexLineSpan(line, span), options); }
/// <summary> /// Constructor /// </summary> /// <param name="line">Line</param> /// <param name="textSpan">Text span</param> public HexLineSpan(HexBufferLine line, VST.Span textSpan) { if (line == null) throw new ArgumentNullException(nameof(line)); BufferSpan = line.BufferSpan; SelectionFlags = null; TextSpan = textSpan; }
/// <summary> /// Constructor /// </summary> /// <param name="line">Line info</param> /// <param name="lineSpan">Line span to classify</param> public HexClassificationContext(HexBufferLine line, VST.Span lineSpan) { if (line == null) throw new ArgumentNullException(nameof(line)); if (!line.TextSpan.Contains(lineSpan)) throw new ArgumentOutOfRangeException(nameof(lineSpan)); Line = line; LineSpan = lineSpan; }
public void IsExternalEditMarker_RightTagWithWrongAttributes() { var array = new[] {"dog", "cat"}; foreach (var item in array) { var tag = new VsTextAdornmentTag {myAttributeId = item}; Assert.IsFalse(_adapter.IsExternalEditTag(tag)); } }
public HexLinePart(int index, int column, VST.Span span, TextRunProperties textRunProperties) { Debug.Assert(!span.IsEmpty); Debug.Assert(textRunProperties != null); Index = index; Column = column; Span = span; AdornmentElement = null; TextRunProperties = textRunProperties; }
/// <summary> /// Constructor /// </summary> /// <param name="groupIndex">Group index</param> /// <param name="fullSpan">Full span including a possible separator at the end of the span</param> /// <param name="span">Span without the separator at the end of the span</param> public HexGroupInformation(int groupIndex, VST.Span fullSpan, VST.Span span) { if (groupIndex < 0 || groupIndex > 1) throw new ArgumentOutOfRangeException(nameof(groupIndex)); if (!fullSpan.Contains(span)) throw new ArgumentOutOfRangeException(nameof(span)); GroupIndex = groupIndex; FullSpan = fullSpan; Span = span; }
public HexLinePart(int index, int column, VST.Span span, HexAdornmentElement adornmentElement, TextRunProperties textRunProperties) { Debug.Assert(adornmentElement != null); Debug.Assert(textRunProperties != null); Index = index; Column = column; Span = span; AdornmentElement = adornmentElement; TextRunProperties = textRunProperties; }
/// <summary> /// Constructor /// </summary> /// <param name="width">Width</param> /// <param name="topSpace">Top space</param> /// <param name="baseline">Base line</param> /// <param name="textHeight">Text height</param> /// <param name="bottomSpace">Bottom space</param> /// <param name="affinity">Affinity</param> /// <param name="identityTag">Identity tag</param> /// <param name="providerTag">Provider tag</param> public HexSpaceNegotiatingAdornmentTag(double width, double topSpace, double baseline, double textHeight, double bottomSpace, VST.PositionAffinity affinity, object identityTag, object providerTag) { Width = width; TopSpace = topSpace; Baseline = baseline; TextHeight = textHeight; BottomSpace = bottomSpace; Affinity = affinity; IdentityTag = identityTag; ProviderTag = providerTag; }
public void IsExternalEditMarker_SnippetTypesAreExternalEdits() { Create("cat", "dog", "tree"); var array = new[] {15, 16, 26}; foreach (var item in array) { var span = _textBuffer.GetLineRange(0).Extent.ToTextSpan(); var marker = MockObjectFactory.CreateVsTextLineMarker(span, item, _factory); Assert.IsTrue(_adapterRaw.IsExternalEditMarker(marker.Object)); } }
/// <summary> /// Constructor /// </summary> /// <param name="adornment">Adornment element</param> /// <param name="removalCallback">Called when the adornment is removed, may be null</param> /// <param name="topSpace">Top space or null to use the default value</param> /// <param name="baseline">Base line or null to use the default value</param> /// <param name="textHeight">Text height or null to use the default value</param> /// <param name="bottomSpace">Bottom space or null to use the default value</param> /// <param name="affinity">Position affinity or null to use the default value</param> public HexIntraTextAdornmentTag(UIElement adornment, VSTE.AdornmentRemovedCallback removalCallback, double? topSpace, double? baseline, double? textHeight, double? bottomSpace, VST.PositionAffinity? affinity) { if (adornment == null) throw new ArgumentNullException(nameof(adornment)); Adornment = adornment; RemovalCallback = removalCallback; TopSpace = topSpace; Baseline = baseline; TextHeight = textHeight; BottomSpace = bottomSpace; Affinity = affinity; }
public void IsExternalEditMarker_RightTagWithAttributes() { var array = new[] { ResharperExternalEditAdapter.ExternalEditAttribute1, ResharperExternalEditAdapter.ExternalEditAttribute2, ResharperExternalEditAdapter.ExternalEditAttribute3, }; foreach (var item in array) { var tag = new VsTextAdornmentTag {myAttributeId = item}; Assert.IsTrue(_adapter.IsExternalEditTag(tag)); } }
public HexLinePartsCollection(List<HexLinePart> lineParts, VST.Span lineSpan, string text) { if (lineParts == null) throw new ArgumentNullException(nameof(lineParts)); if (text == null) throw new ArgumentNullException(nameof(text)); Text = text; Span = lineSpan; LineParts = lineParts; if (lineParts.Count == 0) Length = 0; else { var last = lineParts[lineParts.Count - 1]; Length = last.Column + last.ColumnLength; } }
/// <summary> /// Updates a popup agent /// </summary> /// <param name="agent">Popup agent created by <see cref="CreatePopupAgent(HexLineSpan, VSTA.PopupStyles, UIElement)"/></param> /// <param name="line">Line</param> /// <param name="span">Line span</param> /// <param name="styles">New popup style</param> public void UpdatePopupAgent(HexSpaceReservationAgent agent, HexBufferLine line, VST.Span span, VSTA.PopupStyles styles) => UpdatePopupAgent(agent, new HexLineSpan(line, span), styles);
/// <summary> /// Constructor /// </summary> /// <param name="index">Cell index</param> /// <param name="groupIndex">Group index</param> /// <param name="bufferSpan">Buffer span or the default value if there's no data</param> /// <param name="textSpan">Span of the text. This span doesn't include any whitespace before and after the text.</param> /// <param name="cellSpan">Span of the cell, some of the span could be whitespace</param> /// <param name="separatorSpan">Span of the cell separator</param> /// <param name="fullSpan">Includes the whole cell and separator span</param> public HexCell(int index, int groupIndex, HexBufferSpan bufferSpan, VST.Span textSpan, VST.Span cellSpan, VST.Span separatorSpan, VST.Span fullSpan) { if (index < 0) throw new ArgumentOutOfRangeException(nameof(index)); if (groupIndex < 0 || groupIndex > 1) throw new ArgumentOutOfRangeException(nameof(groupIndex)); if (cellSpan.Length == 0) throw new ArgumentOutOfRangeException(nameof(cellSpan)); if (!fullSpan.Contains(cellSpan)) throw new ArgumentOutOfRangeException(nameof(cellSpan)); HasData = !bufferSpan.IsDefault; Index = index; GroupIndex = groupIndex; BufferSpan = bufferSpan; TextSpan = textSpan; CellSpan = cellSpan; SeparatorSpan = separatorSpan; FullSpan = fullSpan; }
/// <summary> /// Gets normalized text bounds /// </summary> /// <param name="lineSpan">Line span</param> /// <returns></returns> public abstract Collection<VSTF.TextBounds> GetNormalizedTextBounds(VST.Span lineSpan);
HexCell[] WriteAscii(HexBytes hexBytes, HexSpan visibleBytesSpan, out VST.Span fullSpan, out VST.Span visibleSpan) { Debug.Assert(showAscii); cellList.Clear(); int fullStart = CurrentTextIndex; int? visStart = null; int? visEnd = null; var pos = visibleBytesSpan.Start; int cellPos = 0; for (ulong i = 0; i < bytesPerLine; i++, pos++) { int groupIndex = (cellPos / groupSizeInBytes) & 1; HexBufferSpan bufferSpan; int cellStart = CurrentTextIndex; if (visibleBytesSpan.Contains(pos)) { if (visStart == null) visStart = CurrentTextIndex; long index = (long)(pos - visibleBytesSpan.Start).ToUInt64(); int b = hexBytes.TryReadByte(index); if (b < 0) stringBuilder.Append('?'); else if (b < 0x20 || b > 0x7E) stringBuilder.Append('.'); else stringBuilder.Append((char)b); bufferSpan = new HexBufferSpan(buffer, new HexSpan(pos, 1)); } else { if (visStart != null && visEnd == null) visEnd = CurrentTextIndex; stringBuilder.Append(' '); bufferSpan = default(HexBufferSpan); } var cellSpan = VST.Span.FromBounds(cellStart, CurrentTextIndex); var separatorSpan = new VST.Span(cellSpan.End, 0); cellList.Add(new HexCell((int)i, groupIndex, bufferSpan, cellSpan, cellSpan, separatorSpan, cellSpan)); cellPos++; } if ((ulong)fullStart + bytesPerLine != (ulong)CurrentTextIndex) throw new InvalidOperationException(); if (visStart != null && visEnd == null) visEnd = CurrentTextIndex; visibleSpan = visStart == null ? default(VST.Span) : VST.Span.FromBounds(visStart.Value, visEnd.Value); fullSpan = VST.Span.FromBounds(fullStart, CurrentTextIndex); if (AsciiSpan != fullSpan) throw new InvalidOperationException(); return cellList.ToArray(); }
HexCell[] WriteValues(HexBytes hexBytes, HexSpan visibleBytesSpan, out VST.Span fullSpan, out VST.Span visibleSpan) { Debug.Assert(showValues); cellList.Clear(); int fullStart = CurrentTextIndex; ulong cellCount = bytesPerLine / (ulong)valueFormatter.ByteCount; var flags = valuesLowerCaseHex ? HexValueFormatterFlags.LowerCaseHex : HexValueFormatterFlags.None; var pos = visibleBytesSpan.Start; var end = visibleBytesSpan.Start + bytesPerLine; int? visStart = null; int? visEnd = null; int cellPos = 0; for (ulong i = 0; i < cellCount; i++) { if (i != 0) stringBuilder.Append(' '); int groupIndex = (cellPos / groupSizeInBytes) & 1; HexBufferSpan bufferSpan; int cellStart = CurrentTextIndex; int spaces; if (visibleBytesSpan.Contains(pos)) { if (visStart == null) visStart = CurrentTextIndex; long valueIndex = (long)(pos - visibleBytesSpan.Start).ToUInt64(); spaces = valueFormatter.FormatValue(stringBuilder, hexBytes, valueIndex, flags); var endPos = HexPosition.Min(endPosition, pos + (ulong)valueFormatter.ByteCount); bufferSpan = new HexBufferSpan(new HexBufferPoint(buffer, pos), new HexBufferPoint(buffer, endPos)); } else { if (visStart != null && visEnd == null) visEnd = CurrentTextIndex; stringBuilder.Append(' ', valueFormatter.FormattedLength); spaces = valueFormatter.FormattedLength; bufferSpan = default(HexBufferSpan); } if (cellStart + valueFormatter.FormattedLength != CurrentTextIndex) throw new InvalidOperationException(); var textSpan = VST.Span.FromBounds(cellStart + spaces, CurrentTextIndex); var cellSpan = VST.Span.FromBounds(cellStart, CurrentTextIndex); VST.Span separatorSpan; if (i + 1 < cellCount) separatorSpan = new VST.Span(CurrentTextIndex, 1); else separatorSpan = new VST.Span(CurrentTextIndex, 0); var cellFullSpan = VST.Span.FromBounds(cellStart, separatorSpan.End); cellList.Add(new HexCell((int)i, groupIndex, bufferSpan, textSpan, cellSpan, separatorSpan, cellFullSpan)); pos += (ulong)valueFormatter.ByteCount; cellPos += valueFormatter.ByteCount; } if (pos != end) throw new InvalidOperationException(); if (visStart != null && visEnd == null) visEnd = CurrentTextIndex; visibleSpan = visStart == null ? default(VST.Span) : VST.Span.FromBounds(visStart.Value, visEnd.Value); fullSpan = VST.Span.FromBounds(fullStart, CurrentTextIndex); if (ValuesSpan != fullSpan) throw new InvalidOperationException(); return cellList.ToArray(); }
void WriteOffset(HexPosition logicalPosition, out VST.Span offsetSpan) { Debug.Assert(showOffset); int start = CurrentTextIndex; offsetFormatter.FormatOffset(stringBuilder, logicalPosition); offsetSpan = VST.Span.FromBounds(start, CurrentTextIndex); if (OffsetSpan != offsetSpan) throw new InvalidOperationException(); }
void CalculateColumnSpans(out VST.Span offsetSpan, out VST.Span valuesSpan, out VST.Span asciiSpan) { offsetSpan = default(VST.Span); valuesSpan = default(VST.Span); asciiSpan = default(VST.Span); bool needSep = false; int position = 0; foreach (var column in columnOrder) { switch (column) { case HexColumnType.Offset: if (showOffset) { if (needSep) position++; needSep = true; offsetSpan = new VST.Span(position, offsetFormatter.FormattedLength); position = offsetSpan.End; } break; case HexColumnType.Values: if (showValues) { if (needSep) position++; needSep = true; int cellCount = (int)(bytesPerLine / (ulong)valueFormatter.ByteCount); valuesSpan = new VST.Span(position, valueFormatter.FormattedLength * cellCount + cellCount - 1); position = valuesSpan.End; } break; case HexColumnType.Ascii: if (showAscii) { if (needSep) position++; needSep = true; asciiSpan = new VST.Span(position, (int)bytesPerLine); position = asciiSpan.End; } break; default: throw new InvalidOperationException(); } } if (position != CharsPerLine) throw new InvalidOperationException(); }
public override Geometry GetTextMarkerGeometry(WpfHexViewLine line, VST.Span span, bool clipToViewport, Thickness padding) => GetMarkerGeometry(line, span, clipToViewport, padding, false);
/// <summary> /// Scrolls a line into view /// </summary> /// <param name="line">Line</param> /// <param name="span">Line span</param> public void EnsureSpanVisible(HexBufferLine line, VST.Span span) => EnsureSpanVisible(line, span, VSTE.EnsureSpanVisibleOptions.None);
/// <summary> /// Gets a text marker geometry /// </summary> /// <param name="line">A line in this collection</param> /// <param name="span">Text span</param> /// <returns></returns> public abstract Geometry GetTextMarkerGeometry(WpfHexViewLine line, VST.Span span);
/// <summary> /// Gets a line marker geometry /// </summary> /// <param name="line">A line in this collection</param> /// <param name="span">Text span</param> /// <param name="clipToViewport">true to clip the geometry to the viewport</param> /// <param name="padding">Padding to use</param> /// <returns></returns> public abstract Geometry GetLineMarkerGeometry(WpfHexViewLine line, VST.Span span, bool clipToViewport, Thickness padding);
public override Geometry GetTextMarkerGeometry(WpfHexViewLine line, VST.Span span) => GetMarkerGeometry(line, span, false, HexMarkerHelper.TextMarkerPadding, false);
/// <summary> /// Scrolls a line into view /// </summary> /// <param name="line">Line</param> /// <param name="span">Line span</param> /// <param name="options">Options</param> public abstract void EnsureSpanVisible(HexBufferLine line, VST.Span span, VSTE.EnsureSpanVisibleOptions options);
/// <summary> /// Constructor /// </summary> /// <param name="textSpan">Text span</param> /// <param name="bufferSpan">Buffer span</param> public TextAndHexSpan(VST.Span textSpan, HexBufferSpan bufferSpan) { TextSpan = textSpan; BufferSpan = bufferSpan; }
/// <summary> /// Constructor /// </summary> /// <param name="adornment">Adornment element</param> /// <param name="removalCallback">Called when the adornment is removed, may be null</param> /// <param name="affinity">Position affinity or null to use the default value</param> public HexIntraTextAdornmentTag(UIElement adornment, VSTE.AdornmentRemovedCallback removalCallback, VST.PositionAffinity? affinity) : this(adornment, removalCallback, null, null, null, null, affinity) { }
IEnumerable<TextAndHexSpan> GetTextAndHexSpans(bool isColumnPresent, HexCellCollection collection, HexBufferSpan span, HexSpanSelectionFlags flags, VST.Span visibleSpan, VST.Span fullSpan) { if (span.IsDefault) throw new ArgumentException(); if (span.Buffer != Buffer) throw new ArgumentException(); if (!isColumnPresent) yield break; var overlapSpan = BufferSpan.Overlap(span); if (overlapSpan == null) yield break; if ((flags & (HexSpanSelectionFlags.Group0 | HexSpanSelectionFlags.Group1)) != 0) { bool group0 = (flags & HexSpanSelectionFlags.Group0) != 0; bool group1 = (flags & HexSpanSelectionFlags.Group1) != 0; IEnumerable<HexCell> cells; if ((flags & HexSpanSelectionFlags.AllCells) != 0) { cells = collection.GetCells(); overlapSpan = BufferSpan; } else if ((flags & HexSpanSelectionFlags.AllVisibleCells) != 0) { cells = collection.GetVisibleCells(); overlapSpan = BufferSpan; } else cells = collection.GetCells(overlapSpan.Value); HexCell firstCell = null; HexCell lastCell = null; foreach (var cell in cells) { if (!((cell.GroupIndex == 0 && group0) || (cell.GroupIndex == 1 && group1))) continue; if (firstCell == null) { firstCell = cell; lastCell = cell; } else if (lastCell.Index + 1 == cell.Index && lastCell.GroupIndex == cell.GroupIndex) lastCell = cell; else { yield return Create(collection, firstCell, lastCell, overlapSpan.Value); firstCell = lastCell = cell; } } if (firstCell != null) yield return Create(collection, firstCell, lastCell, overlapSpan.Value); yield break; } if ((flags & HexSpanSelectionFlags.AllVisibleCells) != 0) { yield return new TextAndHexSpan(visibleSpan, BufferSpan); yield break; } if ((flags & HexSpanSelectionFlags.AllCells) != 0) { yield return new TextAndHexSpan(fullSpan, BufferSpan); yield break; } if ((flags & HexSpanSelectionFlags.OneValue) != 0) { foreach (var cell in collection.GetCells(overlapSpan.Value)) { if (!cell.HasData) continue; var cellSpan = cell.GetSpan(flags); yield return new TextAndHexSpan(cellSpan, new HexBufferSpan(Buffer, cell.BufferSpan)); } } else { int textStart = int.MaxValue; int textEnd = int.MinValue; var posStart = HexPosition.MaxValue; var posEnd = HexPosition.MinValue; foreach (var cell in collection.GetCells(overlapSpan.Value)) { if (!cell.HasData) continue; var cellSpan = cell.GetSpan(flags); textStart = Math.Min(textStart, cellSpan.Start); textEnd = Math.Max(textEnd, cellSpan.End); posStart = HexPosition.Min(posStart, cell.BufferStart); posEnd = HexPosition.Max(posEnd, cell.BufferEnd); } if (textStart > textEnd || posStart > posEnd) yield break; yield return new TextAndHexSpan(VST.Span.FromBounds(textStart, textEnd), new HexBufferSpan(Buffer, HexSpan.FromBounds(posStart, posEnd))); } }
Geometry GetMarkerGeometry(WpfHexViewLine line, VST.Span span, bool clipToViewport, Thickness padding, bool isLineGeometry) { if (line == null) throw new ArgumentNullException(nameof(line)); if (!lines.Contains(line)) throw new ArgumentException(); bool createOutlinedPath = false; PathGeometry geo = null; var textBounds = line.GetNormalizedTextBounds(span); HexMarkerHelper.AddGeometries(hexView, textBounds, isLineGeometry, clipToViewport, padding, 0, ref geo, ref createOutlinedPath); if (createOutlinedPath) geo = geo.GetOutlinedPathGeometry(); if (geo != null && geo.CanFreeze) geo.Freeze(); return geo; }