void AeHighlighter::blockModified(QTextBlock block, unsigned column, unsigned added, unsigned removed) { // We have to lock the mutex since a background thread may be // attempting to update the StyleVector pointer mutex_.lock(); for(int i = 0, N = styles_->value(block.blockNumber()).size(); i != N; ++i) { AeCodeDecoration& ts = (*styles_)[block.blockNumber()][i]; AeCodeDecoration::Extents extents = ts.extents(); // if the highlight begins after our cursor position, advance // or subtract it by the amount of characters changed if(extents.start >= column) extents.start += added - removed; // if the highlight ends before our cursor position, // leave it unchanged else if(extents.start + extents.length <= column) {} // otherwise, we're in the middle of it. extend it. The normal // highlighting algorithm will correct this later. else extents.length += added - removed; ts.move(extents); } mutex_.unlock(); // We've changed the colours so have to rehighlight this line rehighlightBlock(block); }
// Changing of the start delimiter of a "here documnet" doesn't invoke // highlightBlock() for the rest of it, hence the need for this slot. // I don't like its complex logic but it works. void Highlighter::docChanged (int pos, int, int) { QTextBlock block = qobject_cast< QTextDocument *>(parent())->findBlock (pos); TextBlockData *data = static_cast<TextBlockData *>(block.userData()); /* at start or end (state = 7 or 0 or < 6), or inside but previously at end (state = 6), or outside but previously at start (state = 0 or < 6): these are all states that we need to check */ if (data->isdelimiter()) { /******************************************************************* * It's important to know that this method is always called after * * highlightBlock. There are three possibilities: state = 0, 6, 7. * * Other values are, like 0, related to a block outside here-docs. * *******************************************************************/ /* when we're inside a here-doc, go up to its header */ if (block.userState() == hereDocBodyState) { while (block.isValid()) { block = block.previous(); if (block.userState() == hereDocHeaderState) break; } } /* when we're before, after or at end of a here-doc... */ if (block.userState() != hereDocHeaderState) { /* ... the header state of the next here-doc should be 7; so, go to it and then do as for state 7 below */ block = block.next(); while (block.isValid() && block.userState() != hereDocHeaderState) block = block.next(); } /* when this is a header (state = 7)... */ if (block.isValid()) { /* ... change the header state to 9 for this here-doc to be rehighlighted completely (for the highlighting downward 'wave' to go through it) */ delimState = hereDocTempState; rehighlightBlock (block); /* then reset its block states... */ resetHereDocStates (block); /* ... and also reset the global header state */ delimState = hereDocHeaderState; } /* now, the header states of some here-docs below this one may be 9; so, reset them */ block = block.next(); while (block.isValid()) { while (block.isValid() && block.userState() != hereDocTempState) block = block.next(); if (block.isValid()) { resetHereDocStates (block); block = block.next(); } } } }