PDA

View Full Version : Accessing the current QTextBlock in QSyntaxHighlighter



lorebett
10th December 2008, 19:57
Hi

the documentation for

QSyntaxHighlighter::setCurrentBlockUserData ( QTextBlockUserData * data )

says


you can ask the current QTextBlock (retrieved using the QTextCursor::block() function) if it has a user data object set

but I don't understand how to actually retrieve the current QTextBlock, since on what should I call QTextCursor::block()?

thanks in advance
Lorenzo

wysota
10th December 2008, 20:01
The text cursor is usually positioned somewhere in the text of QTextDocument. You can move it anywhere you want and you can query for the block it is in.

lorebett
11th December 2008, 00:24
The text cursor is usually positioned somewhere in the text of QTextDocument. You can move it anywhere you want and you can query for the block it is in.

OK, so if I have the position of the cursor I can get the block the cursor is in, but the problem is now: how can I get the current cursor position?

wysota
11th December 2008, 01:12
I take it that you want to do something with the highlighter... in that case use QSyntaxHighlighter::currentBlockUserData() and forget about the cursor.

lorebett
11th December 2008, 01:19
I take it that you want to do something with the highlighter... in that case use QSyntaxHighlighter::currentBlockUserData() and forget about the cursor.

I don't think that's enough: I need to access the user data of the previous block, because int previousBlockState () const is not enough... and to access the previous block user data I need to access the current block, and through the current block I can get access to the previous block by using QTextBlock::previous()...

wysota
11th December 2008, 08:47
Could you say why you need to access the previous block?

lorebett
11th December 2008, 13:31
Could you say why you need to access the previous block?

I'm trying to implement syntax highlighting through GNU Source-highlight (http://www.gnu.org/software/src-highlite/) and, in case I enter in a specific highlight state (say, e.g., comment state) I need to store such information in the current block's user data (and I can do this now), but I also need to inspect the previous block user data (to know whether we're inside a specific highlight state).

I don't see any way to access this since, also using TextEdit->cursor()->block() is not enough, since when QSyntaxHighlighter decides that many blocks need to be highlighted TextEdit->cursor()->block() only returns the block where the cursor is, and this is obviously not enough.

By the way, previousBlockState() is not enough for me, since I need to set specific user data

wysota
11th December 2008, 14:08
According to me all you need is the state of the previous block. When you highlight the previous block, you mark its state as "in comment" and then when the next block is being highlighted, you read that value and you know you're still in a comment. What extra data would you like to store, specifically?

lorebett
11th December 2008, 14:22
According to me all you need is the state of the previous block. When you highlight the previous block, you mark its state as "in comment" and then when the next block is being highlighted, you read that value and you know you're still in a comment. What extra data would you like to store, specifically?

I need to store also the stack information: GNU Source-highlight is powerful enough to handle nested highlighting states, using stacks, and only the (integer) state of the previous block is not enough

wysota
11th December 2008, 15:17
If it's only a "state" then that's enough. You can use each bit of the integer to mark a state, therefore you can mark a hierarchy of 32 states - for instance "1" means the paragraph is in state "1" and 9 marks it is in states "1" and "4". I doubt you'll ever have more stacks deeper than 32 levels.

If you can't live with that, simply create a structure which you will index by an integer ("state") that will return the real state associated with a given index.

lorebett
11th December 2008, 16:07
If it's only a "state" then that's enough. You can use each bit of the integer to mark a state, therefore you can mark a hierarchy of 32 states - for instance "1" means the paragraph is in state "1" and 9 marks it is in states "1" and "4". I doubt you'll ever have more stacks deeper than 32 levels.

If you can't live with that, simply create a structure which you will index by an integer ("state") that will return the real state associated with a given index.

No, I need actual objects: the stack contains references to state objects, so I need to store user data...

probably the idea of the structure might help

wysota
11th December 2008, 16:41
I have taken a look at GNU Source-highlight and I'm not sure if you should use it with QSyntaxHighlighter. Source-highlight generates html code, so why not simply run it and set its output as rich text of the document you want to highlight?

lorebett
11th December 2008, 19:00
I have taken a look at GNU Source-highlight and I'm not sure if you should use it with QSyntaxHighlighter. Source-highlight generates html code, so why not simply run it and set its output as rich text of the document you want to highlight?

I don't think this is feasible when editing a source: I'd have to re-highlight all the code at each modification, wouldn't I?

Moreover, source-highlight is more general (I'm turning it into a library at the moment), and thus I think it can be used also in other frameworks (for instance with QSyntaxHighlighter I'd use its regex engine and in particular the whole regex automaton generated from the language definition files).

wysota
11th December 2008, 20:12
I don't think this is feasible when editing a source: I'd have to re-highlight all the code at each modification, wouldn't I?
Yes, that's correct. But as you are using a very general highlighting mechanism it is possible that for some languages changing the state of current paragraph will change the state of previous paragraphs. How do you want to cope with that? From what I see this highlighter is meant to work on complete files, not parts of it, so you can't guarantee this won't happen. QSyntaxHighlighter only operates on a subset of possible situations - it is limited but in a sensible way. You are trying to work around those limitations which can result in breaking the mechanism. It might be easier to build your own from scratch without using QSyntaxHighlighter - after all this is a quite stupid class, it's not hard to write your own highlighting engine.

lorebett
11th December 2008, 20:22
Yes, that's correct. But as you are using a very general highlighting mechanism it is possible that for some languages changing the state of current paragraph will change the state of previous paragraphs. How do you want to cope with that? From what I see this highlighter is meant to work on complete files, not parts of it, so you can't guarantee this won't happen.

The executable source-highlight works on a complete file, but the code that it uses to highlight the file, operates on single lines, so its library can also operate on a single line, keeping track of the last highlighting state entered (and the user code can query this, store the stack, and set it back).

As for the situation you're describing, it is the QSyntaxHighlighter code itself that will take care of re-highlighting the previous paragraphs, if I didn't get it wrong, otherwise such situations couldn't be handled with QSyntaxHighlighter at all, am I wrong?


QSyntaxHighlighter only operates on a subset of possible situations - it is limited but in a sensible way. You are trying to work around those limitations which can result in breaking the mechanism. It might be easier to build your own from scratch without using QSyntaxHighlighter - after all this is a quite stupid class, it's not hard to write your own highlighting engine.

But it takes care of checking whether other parts of the file must be highlighted again (by relying on the current and previous state).

However, I'll try to implement what I meant now that I downloaded the source of Qt 4.4 and finally they added currentBlock() in QSyntaxHighlighter! :D

wysota
11th December 2008, 21:31
As for the situation you're describing, it is the QSyntaxHighlighter code itself that will take care of re-highlighting the previous paragraphs, if I didn't get it wrong, otherwise such situations couldn't be handled with QSyntaxHighlighter at all, am I wrong?
Either you are right and the whole document gets rehighlighted each time, or you are wrong and QSyntaxHighlighter is limited :)




But it takes care of checking whether other parts of the file must be highlighted again (by relying on the current and previous state).
So either it is enough to know the current and previous state or not...

lorebett
11th December 2008, 21:45
Either you are right and the whole document gets rehighlighted each time, or you are wrong and QSyntaxHighlighter is limited :)


could there be situations such the ones you described (i.e., the previous parts need to be re-highlighted)?



So either it is enough to know the current and previous state or not...

it is enough for the QSyntaxHighlighter strategy but it is not enough for the regexp engine with stacks of states