PDA

View Full Version : QSyntaxHighlighter and faked currentParagraph()



mcostalba
4th March 2007, 09:34
Hello,

I'm porting an application to Qt4.2 from Qt3.

Application needs to highlight a given range of lines in a QTextEdit, as example from line 5 to line 12.

With Q3SyntaxHighlighter I use currentParagraph() inside highlightParagraph() to read current line and set highlight accordingly with setFormat().

Sadly, I cannot find a way to read current block number with the new QSyntaxHighlighter. So how can I know what is the block is currently passed to the highlightBlock() callback?

The best I have found is an ugly trick using block state. At the beginning of my reimplementation of highlightBlock() I write:

virtual void highlightBlock(const QString& p) {

// state is used to count paragraphs, staring from 0
setCurrentBlockState(previousBlockState() + 1);


and then I fake the current paragraph info with currentBlockState()

Is it correct? there is a better way?

Thanks
Marco

fullmetalcoder
4th March 2007, 09:51
Hello,

I'm porting an application to Qt4.2 from Qt3.

Application needs to highlight a given range of lines in a QTextEdit, as example from line 5 to line 12.

With Q3SyntaxHighlighter I use currentParagraph() inside highlightParagraph() to read current line and set highlight accordingly with setFormat().

Sadly, I cannot find a way to read current block number with the new QSyntaxHighlighter. So how can I know what is the block is currently passed to the highlightBlock() callback?

The best I have found is an ugly trick using block state. At the beginning of my reimplementation of highlightBlock() I write:



virtual void highlightBlock(const QString& p) {

// state is used to count paragraphs, staring from 0
setCurrentBlockState(previousBlockState() + 1);
}


and then I fake the current paragraph info with currentBlockState()

Is it correct? there is a better way?

The QSyntaxHighlighter provides no way to obtain the position of the currently highlighted text within the current document except a wild guess after iterating over the document content... All you can do is highlight the text passed to highlight block and set a block state.
If you want to maintain a line numbering inside the document structure (bad idea IMHO) your code above should work but it would cause a full re-highlighting each time a line is inserted or removed (not only a given range) or a single-line re-highlighting when a line is modified. Indeed, QSyntaxHighlighter uses the block state to determine whether highlighting need to be continued by comparing block states before and after highlighting. Alternatively you could use QTextBlockUserData to store your line numbering information and the block state to control the range of highlighting but this would unfortunately require to reimplement QSyntaxHighlighter... Sounds weird? Well QSyntaxHighlighter has been (IMO) very badly designed because it denies access to the current QTexBlock which is required to play with the userData()... If you're interested in a more flexible highlighter you should have a look at QCodeEdit (http://www.qtcentre.org/forum/f-qt-software-16/t-qcodeedit-3178.html) and particularly the QHighlighter/QHighlighterInterface classes which are basically a (client/server) copy (with some internal modifications though) of QSyntaxHighlighter and which pass a QTextBlock instead of a QString on highlighting.

mcostalba
4th March 2007, 10:30
Hello,

you suggest to use QTextBlockUserData:

"Alternatively you could use QTextBlockUserData to store your line numbering information and the block state to control the range of highlighting"

But how can I know line numbering? I miss a previousBlockUserData() method to get the user data of previous block and so infere line number of current block.

I would need to loop across all document blocks and create corresponding used data object _before_ and _outside_ my highlightBlock() reimplementation where I could just read the currentBlockUserData(). it does not seem easier nor faster.

Marco

P.S: Thanks for your QCodeEdit class, I will take a look although I suspect it's overkill for my needs. I just need to highlight chunks of a read-only document according to a range given in line numbers.

fullmetalcoder
4th March 2007, 10:34
I just need to highlight chunks of a read-only document according to a range given in line numbers.
That's a better description! ;)
If your document is read-only (and not modified by your app) you don't need any complex syntax highlighter class. Actually if there is really no modification (apart from the loading of your document) the thing you suggested with block state is enough because the document will be fully highlighted on opening and untouched afterward... :)

lorebett
11th December 2008, 00:36
Well QSyntaxHighlighter has been (IMO) very badly designed because it denies access to the current QTexBlock which is required to play with the userData().

I'm having the same problem trying to access the current QTextBlock, and I'm quite astonished QSyntaxHighlighter does not provide you the access to it... as it is, playing with userData() cannot be done...

however, if I'm not wrong, it looks like (by taking a look at the svn via web) that in 4.4 QSyntaxHighlighter provides currentBlock() method...