Posted 9 years ago by Mick George - Software Engineer, CNC Software, Inc.
Version: 11.1.0540
Avatar
I have a custom margin that is used to set breakpoints, the user left clicks on the margin and a break point is added or removed as needed.

Each break point stores a TextSnapshotRange.StartOffset TextSnapshotRange.EndOffset TextSnapshotRange.StartPosition Text and line Number. OnDocumentTextChanged is implemented in my Custom Margin class to keep each break point properties in sync with the latest snapshot. The user can add/remove break points add or remove lines in the view and break points update and display as expected.

I also created a BreakPointTagger to draw a rectangle around a line of text that a break point has been added to. I have code that determines whether an adornment can be drawn shown below. The code below is working correctly in all cases except when the cursor is at the start of a line when the user presses the enter key.

BreakPointTagger.cs

// Loop through the snapshot ranges
foreach (TextSnapshotRange snapshotRange in snapshotRanges)
{
    // If the snapshot range is not zero-length...
    if (!snapshotRange.IsZeroLength)
    {
        // Get a snapshot reader
        ITextSnapshotReader reader = snapshotRange.Snapshot.GetReader(snapshotRange.StartOffset);

        // If not already at the start of a line, back up to the start
        if (!reader.IsAtSnapshotLineStart)
        {
            reader.GoToCurrentSnapshotLineStart();
        }

        // Read through the snapshot until the end of the target range is reached
        while ((!reader.IsAtSnapshotEnd) && (reader.Offset < snapshotRange.EndOffset))
        {
            // Save the start of the line offset
            int lineStartOffset = reader.Offset;

            // Go to the end of the line
            reader.GoToCurrentSnapshotLineEnd();

            // Save the end of the line offset
            int lineEndOffset = reader.Offset;

            // Query our breakpoint list to see if we have a breakpoint at this position
            DebuggerBreakPoint bp = this.debugpoints.FirstOrDefault(s => s.StartOffset == lineStartOffset && s.EndOffset == lineEndOffset);

            if (null != bp)
            {
                // Create a new tag from the breakpoint
                BreakPointTag tag = new BreakPointTag(bp);

                // Yield the tag
                yield return new TagSnapshotRange<BreakPointTag>(
                    TextSnapshotRange.FromSpan(snapshotRange.Snapshot, snapshotRange.StartOffset, snapshotRange.Text.Length), tag);
            }

            // Consume the newline
            reader.GoToNextSnapshotLineStart();
        }
    }
}
Break points enabled.

Lines added above existing break points:

Line added with cursor on a break point at the line start notice that the adornments are not drawn because the code check above fails.

I assume I am doing something and would appreciate any help you can give, thank you.

Comments (5)

Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Mick,

One possible thing is could you maybe want to do <= snapshotRange.EndOffset instead of < ? Not sure if that would help.

It's hard to say without debugging it. If that doesn't help, can you put together a new simple sample project that shows it happening and email that to us? The simpler the better, even if you hardcode your tag ranges. Please don't include .exe files in your ZIP and rename the .zip extension so it doesn't get spam blocked.

If you could do this quickly it would be appreciated as we are hoping to get a maintenance release out in the next couple days. If a fix is needed we'd like to get it in for that.


Actipro Software Support

Posted 9 years ago by Mick George - Software Engineer, CNC Software, Inc.
Avatar
I'll put together a simple project that replicates the problem and mail it to you ASAP, thanks.
Posted 9 years ago by Mick George - Software Engineer, CNC Software, Inc.
Avatar
A test project has been mailed, thank you.
Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Mick,

Thanks for the sample. The problem here is that the breakpoint objects you are using to track data are storing offsets but they aren't associated with a snapshot version so they become invalid once you make edits.

I did a quick test and got it all working in your sample. Basically change your DebuggerBreakPoint to accept an ITextVersionRange instead of two offsets. That is the lowest level way to track versioned offset ranges that can be translated to newer snapshots.

Then in OnCustomDrawLeftMouseDown, I added this to initialize the range:
var lineRange = line.SnapshotRange.ToVersionRange(TextRangeTrackingModes.Default);
DebuggerBreakPoint breakPoint = new DebuggerBreakPoint(result.Position, breakText, lineRange);
Back in your tagger, I altered it to this which translates the version range to a TextRange to compare to your current line values:
DebuggerBreakPoint bp = this.debugpoints.FirstOrDefault(s => s.LineRange.Translate(reader.Snapshot).TextRange.Equals(new TextRange(lineStartOffset, lineEndOffset)));
That's all I really changed I believe and it seems to work well. I noticed you had some other code that did some snapshot translation. I believe I commented it out so you may or may not need that now that your version range is being used and can translate itself.


Actipro Software Support

Posted 9 years ago by Mick George - Software Engineer, CNC Software, Inc.
Avatar
Thank you very much for your very fast response and solution to my problem, awesome service as always!
The latest build of this product (v2019.1 build 0683) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.