[QScintilla] folding quirks

Phil Thompson phil at riverbankcomputing.com
Wed Feb 17 12:22:54 GMT 2010


On Tue, 16 Feb 2010 03:50:22 -0500, Jared Sutton <jpsutton at gmail.com>
wrote:
> Hi All,
> 
> For the last several years (spare time) I've been constructing a simple
> cross-platform code editor called QSciTE using Qt4 version of
Qscintilla2.
>  You can find it here, in case you're interested:
> 
> http://qscite.googlecode.com/
> 
> First off, thanks very much for making this library available to the
public
> under the GPL.  It has some wonderful functionality built-in.
> 
> I've been having some issues with code folding recently, which I believe
to
> have stemmed from at least one bug in Qscintilla.  I have a simple menu
> option to enable/disable code folding.  Whenever I turn folding off, I
want
> any lines that are currently folded to be unfolded automatically, since
it
> doesn't make a whole lot of sense to have folded code that can't easily
be
> unfolded.  Here's my toggleFolding() function which is directly connected
> to
> the menu option:
> 
> void MainWindow::toggleFolding() {
>   QsciteEditor * doc = getCurDoc();
>   QsciteEditor::FoldStyle state =
> static_cast<QsciteEditor::FoldStyle>((!doc->folding()) * 5);
> 
>   if (!state) {
>     // unfold all code before turning off folding
>     doc->foldAll(false);
>   }
> 
>   doc->setFolding(state);
> }
> 
> The QsciteEditor class is a child-class of Qscintilla, because I needed
to
> expose several functions for use with QtScript, and because I needed to
> catch some key-presses that I needed to process specially.  As you can
see,
> foldAll() is only getting called just before the folding is about to be
> turned off.  The  documentation for foldAll() states "If any lines are
> currently folded then they are all unfolded. Otherwise all lines are
> folded."  Now, my implementation does not take into account the
possibility
> that no lines were folded between the time that the folding was enabled
and
> disabled (which I'll expand on below), meaning that if foldAll() works as
> documented, I should expect to see all lines get folded before the
folding
> is disabled.  However, even when I fold one or more lines and then turn
off
> folding, I find that all lines are getting folded before folding gets
> disabled.  This seems like it's a problem with the foldAll()
> implementation.

It depends...

foldAll() can only deal with what a particular lexer has set in the way of
fold flags. I've found that lexers don't always exhibit consistent
behaviour - some are just wrong.

Both Scite and QScintilla will call foldAll() (or the Scite equivalent)
when you shift-control-click in the fold margin. I would compare the result
of doing this in Scite with the same lexer set and the same file being
edited. If the result is different then it's probably a QScintilla bug. If
it's not then it's likely to be a Scintilla bug or feature (ie. in the
particular lexer itself).

> This also brings up a few questions:
> 1. Shouldn't setFolding() automatically unfold all lines that are
currently
> folded before the FoldStyle is set to NoFoldStyle?  Does anyone expect to
> have lines folded after they disable folding?
> 2. If the person using QsciScintilla is expected to unfold all lines that
> were folded before turning folding off, how can he know what lines are
> folded?  As far as I can tell, that information is private, as are the
> functions/signals/slots that are responsible for changing a line's fold
> state.
>
> So, I see these issues in the end:
> 1. There appears to be a bug in the QsciScintilla:foldAll(bool) function.
>  It doesn't appear to function as documented.
> 2. In my opinion, QsciScintilla::setFolding() should either unfold
> everything when folding is turned off, or the appropriate member
> variables/functions/signals/slots should be changed from private to
> protected so that developers can deal with the situation without
resorting
> to hacking on Qscintilla directly.

How about an unfoldAll() method? (It's a shame that foldAll() was so badly
named.) That would allow it to be used separately from setFolding(), and
wouldn't change the behaviour of the latter for existing applications.
 
> For what it's worth, here's my development environment:
> Arch Linux
> KDEmod 4.4.0
> Qscintilla 2.4.2
> Qt 4.6.1
> 
> Thanks for any insight you may have.
> 
> Jared Sutton

Phil


More information about the QScintilla mailing list