Toggle fold/unfold code region

Oct 30, 2009 at 2:22 AM

The "fold all/unfold all" code in the sample editor doesn't work for me. Sometimes it folds some sections/regions but left others alone. So I took the code from the SciTE project and just translate it to C# and it work out perfectly. Just though someone might be interested. Just copy the code into your Main form and call FoldUnfoldAll() to toggle between folding and unfolding.

 

private void FoldUnfoldAll() {
    ActiveDocument.Scintilla.NativeInterface.Colourise(0, -1);

    int maxLine = ActiveDocument.Scintilla.NativeInterface.GetLineCount();
    bool expanding = true;
    for (int lineSeek = 0; lineSeek < maxLine; lineSeek++) {
        if ((ActiveDocument.Scintilla.NativeInterface.GetFoldLevel(lineSeek) & ScintillaNet.Constants.SC_FOLDLEVELHEADERFLAG) > 0) {
            expanding = !ActiveDocument.Scintilla.NativeInterface.GetFoldExpanded(lineSeek);
            break;
        }
    }

    for (int line = 0; line < maxLine; line++) {
        uint level = ActiveDocument.Scintilla.NativeInterface.GetFoldLevel(line);
        if ((level & ScintillaNet.Constants.SC_FOLDLEVELHEADERFLAG) > 0 &&
            (ScintillaNet.Constants.SC_FOLDLEVELBASE == (level & ScintillaNet.Constants.SC_FOLDLEVELNUMBERMASK))
            ) {
            if (expanding) {
                ActiveDocument.Scintilla.NativeInterface.SetFoldExpanded(line, true);
                ExpandCollapseFold(ref line, true, false, 0, (int)level);
                line--;
            } else {
                int lineMaxSubord = ActiveDocument.Scintilla.NativeInterface.GetLastChild(line, -1);
                ActiveDocument.Scintilla.NativeInterface.SetFoldExpanded(line, false);
                if (lineMaxSubord > line) {
                    ActiveDocument.Scintilla.NativeInterface.HideLines(line + 1, lineMaxSubord);
                }
            }
        }
    }
}

private void ExpandCollapseFold(ref int line, bool doExpand, bool force, int visLevels, int level) {
    int lineMaxSubord = ActiveDocument.Scintilla.NativeInterface.GetLastChild(line, (int)(level & ScintillaNet.Constants.SC_FOLDLEVELNUMBERMASK));
    line++;

    while (line <= lineMaxSubord) {
        if (force) {
            if (visLevels > 0) {
                ActiveDocument.Scintilla.NativeInterface.ShowLines(line, line);
            } else {
                ActiveDocument.Scintilla.NativeInterface.HideLines(line, line);
            }
        } else {
            if (doExpand) {
                ActiveDocument.Scintilla.NativeInterface.ShowLines(line, line);
            }
        }

        int levelLine = level;
        if (levelLine == -1) {
            levelLine = (int)ActiveDocument.Scintilla.NativeInterface.GetFoldLevel(line);
        }

        if ((levelLine & ScintillaNet.Constants.SC_FOLDLEVELHEADERFLAG) > 0) {
            if (force) {
                if (visLevels > 1) {
                    ActiveDocument.Scintilla.NativeInterface.SetFoldExpanded(line, true);
                } else {
                    ActiveDocument.Scintilla.NativeInterface.SetFoldExpanded(line, false);
                }

                ExpandCollapseFold(ref line, doExpand, force, visLevels - 1, -1);
            } else {
                if (doExpand) {
                    if (!ActiveDocument.Scintilla.NativeInterface.GetFoldExpanded(line)) {
                        ActiveDocument.Scintilla.NativeInterface.SetFoldExpanded(line, true);
                    }
                    ExpandCollapseFold(ref line, true, force, visLevels - 1, -1);
                } else {
                    ExpandCollapseFold(ref line, false, force, visLevels - 1, -1);
                }
            }
        } else {
            line++;
        }
    }
}