Opened 5 years ago

#15354 new bug

BTextView's _Refresh() results in line counts out of sync

Reported by: humdinger Owned by: nobody
Priority: normal Milestone: Unscheduled
Component: Kits/Interface Kit Version: R1/Development
Keywords: Cc:
Blocked By: Blocking:
Platform: All

Description

This is hrev53452.

To see the effect, open an email in Mail, select 3 lines, and press "Reply".

Each line should get a quote mark "> ". Instead we get a quote mark for each character, all in the first line. The relevant code is at https://git.haiku-os.org/haiku/tree/src/apps/mail/MailWindow.cpp#n2270:

fContentView->TextView()->SetText(text, finish - start);
free(text);

finish = fContentView->TextView()->CountLines();
for (int32 loop = 0; loop < finish; loop++) {
	fContentView->TextView()->GoToLine(loop);
	fContentView->TextView()->Insert((const char*)QUOTE);
}

The CountLines() and the GoToLine() apparently use the number of characters, not the number of lines.

Here's PulkoMandy's analysis:

[10:16] <PulkoMandy> apparently BTextView has a cache for the line offset (fLines array of offsets or something like that), my guess would be that this somehow gets out of sync when calling SetText in this case?

[10:18] <PulkoMandy> it seems there is a problem, yes

[10:19] <PulkoMandy> setting the text in BTextView eventually calls _Refresh which is in charge of recomputing everything. The input to this is offsets (in characters) for the start and end of the range to refresh

[10:20] <PulkoMandy> and it uses _LineAt to convert these to line offsets. Except it does this before calling _RecalculateLineBreaks, so it is doing so using the line offsets from the previous state of the text, before insert was called

And:

[10:25] <PulkoMandy> if my guess is correct, you could maybe workaround this by calling SetText twice with the same text

[10:25] <PulkoMandy> hopefully the second time it will do the right thing, and then CountLines will work

That workaround didn't help, though.

Change History (0)

Note: See TracTickets for help on using tickets.