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.