PDA

View Full Version : Find newline character in a QTextEdit / QPlainTextEdit



Fred
2nd January 2021, 11:02
I am currently trying unsuccessfully to find the newline character via the search in a QTextEdit / QPlainTextEdit, everything I have tried is not found. This concerns the search via QTextEdit->find() as well as QTextEdit->document()->find().

The only thing that works is the search via QRegularExpression("$"), but here you get the position of the end of line as a result and must be manually fixed as a workaround. Is there a way to find the newline character?

Here is an example of what I have tried so far and it does not work. As result everywhere -1 is thrown out, exept QRegularExpression( "$" ) that gives as selectionStart() / selectionEnd position 4.



QTextEdit *edit = new QTextEdit( this );
QPlainTextEdit *plainedit = new QPlainTextEdit( this );

QString Text = "Text\nwith\nnewlines\n\n";
edit->setText( Text );
plainedit->setPlainText( Text );

qDebug() << edit->document()->find( "\n" ).position();
qDebug() << edit->document()->find( "\r\n" ).position();
qDebug() << edit->document()->find( "\\x2029" ).position();
qDebug() << edit->document()->find( QRegExp( "\\x2029|\\r\\n|\\r|\\n" ) ).position();
qDebug() << edit->document()->find( QRegularExpression( "\\x2029|\\r\\n|\\r|\\n" ) ).position();
qDebug() << edit->document()->find( QRegularExpression( "\\R" ) ).position();

qDebug() << plainedit->document()->find( "\n" ).position();
qDebug() << plainedit->document()->find( "\r\n" ).position();
qDebug() << plainedit->document()->find( "\\x2029" ).position();
qDebug() << plainedit->document()->find( QRegExp( "\\x2029|\\r\\n|\\r|\\n" ) ).position();
qDebug() << plainedit->document()->find( QRegularExpression( "\\x2029|\\r\\n|\\r|\\n" ) ).position();
qDebug() << plainedit->document()->find( QRegularExpression( "\\R" ) ).position();

QTextCursor c = plainedit->document()->find( QRegularExpression( "$" ) );
qDebug() << c.hasSelection() << c.selectionStart() << c.selectionEnd();

d_stranz
2nd January 2021, 17:13
QTextEdit and QPlainTextEdit both store their contents as a QTextDocument. When you put text into QTextDocument that contains embedded newline characters, it is probable that these are stripped out and each segment converted into a QTextBlock. So searching for newlines doesn't work because they aren't there.

You can check this by asking the document for the blockCount(). You could also look at the result of characterAt() where you give it a known index of a newline in your input text.

You can retrieve something like the original text using QTextDocument::toPlainText() or QTextDocument::toRawText(), but see the comments for those methods regarding changes that could be made from the original input.

Fred
3rd January 2021, 10:00
Thanks for your answer! I have tried this with

for ( int i = 3; i <= 5; ++i ) { qDebug() << plainedit->document()->characterAt( i ); }
And get as output

't'
'\u2029'
'w'
As it looks the newline character is present. But of course it is quite possible that internally it works like you say. So I will have to make a workaround to solve the problem. Thanks for the answer anyway!

d_stranz
3rd January 2021, 16:37
So I will have to make a workaround to solve the problem.

What exactly -is- the problem? That is, why are you trying to find the newline characters in the first place? I presume you want to do this with text the user has typed into the editor, because if you are simply setting the text programmatically you already know where the newlines are.

If the text editor automatically creates a new QTextBlock every time the user enters a carriage return, then the blocks already define the locations of newlines.

I suspect that characterAt() is working off of the plain text / raw text, not off of the block-structured document. Try retrieving the plain text and/or raw text and step through those strings with the debugger to see if the newlines are there. If they are, then you just need to go one level deeper - plainedit->document()->toPlainText().indexOf( '\n' )

Fred
3rd January 2021, 19:05
I am working on a small text editor, search and replace are already implemented and work 100%. Only the search and replace of \n does not work, hence the question.