Problem with folding in StyledTextCtrl

The following program is basically just a StyledTextCtrl with the folding functionality from the wxPython Demo.
The problem is when I hold control and shift and click on the first fold box in the margin, the bottom element doesn’t get folded.

If I get rid of the line with the hash symbol at the bottom of the class definition, then it works.
The reason I have those lines with a single hash symbol is that I like to have my folds spaced out a little bit, and if I don’t have them, any blank lines under a fold get folded away.

Any suggestions?

wxPython 2.8.7.1 (gtk2-unicode)
Ubuntu 8.04

···

import wx
import wx.stc as stc

class Folding_Text_Control(stc.StyledTextCtrl):
def init(self, parent):

    stc.StyledTextCtrl.__init__(self, parent)

    self.SetLexer(stc.STC_LEX_PYTHON)
   
    def folding_stuff():
        self.SetProperty("fold", "1")
       

        # Setup a margin to hold fold markers
        self.SetFoldFlags(16) # Draw a line under a folded sectino
        self.SetMarginType(2, stc.STC_MARGIN_SYMBOL)
        self.SetMarginMask(2, stc.STC_MASK_FOLDERS)

        self.SetMarginSensitive(2, True)
        self.SetMarginWidth(2, 24)
       
        def set_fold_symbols():
            self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN,
                              stc.STC_MARK_BOXMINUS, "white", "black")

            self.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_BOXPLUS,
                              "white", "black")
            self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_VLINE,

                              "white", "black")
            self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL,
                              stc.STC_MARK_LCORNER, "white", "black")

            self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND,
                              stc.STC_MARK_BOXPLUSCONNECTED, "white", "black")
            self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID,

                              stc.STC_MARK_BOXMINUSCONNECTED, "white",
                              "black")
            self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL,
                              stc.STC_MARK_TCORNER, "white", "black") #"#808080")

        set_fold_symbols()
    folding_stuff()
   
    self.Bind(stc.EVT_STC_MARGINCLICK, self.OnMarginClick)
#
def OnMarginClick(self, evt):
    # fold and unfold as needed

    if evt.GetMargin() == 2:
        if evt.GetShift() and evt.GetControl():
            self.FoldAll()
        else:
            lineClicked = self.LineFromPosition(evt.GetPosition())

            if self.GetFoldLevel(lineClicked) & stc.STC_FOLDLEVELHEADERFLAG:
                self.ToggleFold(lineClicked)                
#
def FoldAll(self):           
    lineCount = self.GetLineCount()

    expanding = False
   
    line_number = 0
  
    print "stc.STC_FOLDLEVELBASE: ", stc.STC_FOLDLEVELBASE
   
    while line_number < lineCount:
        level = self.GetFoldLevel(line_number)

        print line_number, \
              level & stc.STC_FOLDLEVELHEADERFLAG, \
              level & stc.STC_FOLDLEVELNUMBERMASK           
        if level & stc.STC_FOLDLEVELHEADERFLAG and \

           (level & stc.STC_FOLDLEVELNUMBERMASK) == stc.STC_FOLDLEVELBASE:
                           
            if expanding:
                self.SetFoldExpanded(line_number, True)
                line_number = self.Expand(line_number, True)

                line_number = line_number - 1
            else:
                lastChild = self.GetLastChild(line_number, -1)
                self.SetFoldExpanded(line_number, False)

                if lastChild > line_number:

                    self.HideLines(line_number+1, lastChild)

        line_number = line_number + 1
#
def Expand(self, line, doExpand, force=False, visLevels=0, level=-1):
    lastChild = self.GetLastChild(line, level)

    line = line + 1

    while line <= lastChild:
        if force:
            if visLevels > 0:
                self.ShowLines(line, line)
            else:
                self.HideLines(line, line)

        else:
            if doExpand:
                self.ShowLines(line, line)

        if level == -1:
            level = self.GetFoldLevel(line)

        if level & stc.STC_FOLDLEVELHEADERFLAG:

            if force:
                if visLevels > 1:
                    self.SetFoldExpanded(line, True)
                else:
                    self.SetFoldExpanded(line, False)

                line = self.Expand(line, doExpand, force, visLevels-1)

            else:
                if doExpand and self.GetFoldExpanded(line):
                    line = self.Expand(line, True, force, visLevels-1)

                else:
                    line = self.Expand(line, False, force, visLevels-1)
        else:
            line = line + 1

    return line
#

if ‘main’ == name:

from unit_tests import *

app = wx.App(redirect=False)

frame = wx.Frame(None, size=(710,800))
panel = wx.Panel(frame)
editor = Folding_Text_Control(panel)
sizer = wx.BoxSizer(wx.HORIZONTAL)

sizer.Add(editor, proportion=1, flag = wx.EXPAND)
panel.SetSizer(sizer)
frame.Show()

editor.SetText(open(__file__).read())
editor.EmptyUndoBuffer()

app.MainLoop()

Oops, the “from unit_tests import *” line shouldn’t be there. Just delete that line if you run the program.

···

On Fri, Aug 8, 2008 at 4:40 PM, Jesse Aldridge jessealdridge@gmail.com wrote:

The following program is basically just a StyledTextCtrl with the folding functionality from the wxPython Demo.

The problem is when I hold control and shift and click on the first fold box in the margin, the bottom element doesn’t get folded.

If I get rid of the line with the hash symbol at the bottom of the class definition, then it works.
The reason I have those lines with a single hash symbol is that I like to have my folds spaced out a little bit, and if I don’t have them, any blank lines under a fold get folded away.

Any suggestions?

wxPython 2.8.7.1 (gtk2-unicode)
Ubuntu 8.04


import wx
import wx.stc as stc

class Folding_Text_Control(stc.StyledTextCtrl):
def init(self, parent):

    stc.StyledTextCtrl.__init__(self, parent)

    self.SetLexer(stc.STC_LEX_PYTHON)
   
    def folding_stuff():
        self.SetProperty("fold", "1")
       


        # Setup a margin to hold fold markers
        self.SetFoldFlags(16) # Draw a line under a folded sectino
        self.SetMarginType(2, stc.STC_MARGIN_SYMBOL)
        self.SetMarginMask(2, stc.STC_MASK_FOLDERS)


        self.SetMarginSensitive(2, True)
        self.SetMarginWidth(2, 24)
       
        def set_fold_symbols():
            self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN,
                              stc.STC_MARK_BOXMINUS, "white", "black")


            self.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_BOXPLUS,
                              "white", "black")
            self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_VLINE,


                              "white", "black")
            self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL,
                              stc.STC_MARK_LCORNER, "white", "black")


            self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND,
                              stc.STC_MARK_BOXPLUSCONNECTED, "white", "black")
            self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID,


                              stc.STC_MARK_BOXMINUSCONNECTED, "white",
                              "black")
            self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL,
                              stc.STC_MARK_TCORNER, "white", "black") #"#808080")


        set_fold_symbols()
    folding_stuff()
   
    self.Bind(stc.EVT_STC_MARGINCLICK, self.OnMarginClick)
#
def OnMarginClick(self, evt):
    # fold and unfold as needed


    if evt.GetMargin() == 2:
        if evt.GetShift() and evt.GetControl():
            self.FoldAll()
        else:
            lineClicked = self.LineFromPosition(evt.GetPosition())



            if self.GetFoldLevel(lineClicked) & stc.STC_FOLDLEVELHEADERFLAG:
                self.ToggleFold(lineClicked)                
#
def FoldAll(self):           
    lineCount = self.GetLineCount()


    expanding = False
   
    line_number = 0
  
    print "stc.STC_FOLDLEVELBASE: ", stc.STC_FOLDLEVELBASE
   
    while line_number < lineCount:
        level = self.GetFoldLevel(line_number)


        print line_number, \
              level & stc.STC_FOLDLEVELHEADERFLAG, \
              level & stc.STC_FOLDLEVELNUMBERMASK           
        if level & stc.STC_FOLDLEVELHEADERFLAG and \


           (level & stc.STC_FOLDLEVELNUMBERMASK) == stc.STC_FOLDLEVELBASE:
                           
            if expanding:
                self.SetFoldExpanded(line_number, True)
                line_number = self.Expand(line_number, True)


                line_number = line_number - 1
            else:
                lastChild = self.GetLastChild(line_number, -1)
                self.SetFoldExpanded(line_number, False)

                if lastChild > line_number:


                    self.HideLines(line_number+1, lastChild)

        line_number = line_number + 1
#
def Expand(self, line, doExpand, force=False, visLevels=0, level=-1):
    lastChild = self.GetLastChild(line, level)


    line = line + 1

    while line <= lastChild:
        if force:
            if visLevels > 0:
                self.ShowLines(line, line)
            else:
                self.HideLines(line, line)


        else:
            if doExpand:
                self.ShowLines(line, line)

        if level == -1:
            level = self.GetFoldLevel(line)

        if level & stc.STC_FOLDLEVELHEADERFLAG:


            if force:
                if visLevels > 1:
                    self.SetFoldExpanded(line, True)
                else:
                    self.SetFoldExpanded(line, False)



                line = self.Expand(line, doExpand, force, visLevels-1)

            else:
                if doExpand and self.GetFoldExpanded(line):
                    line = self.Expand(line, True, force, visLevels-1)


                else:
                    line = self.Expand(line, False, force, visLevels-1)
        else:
            line = line + 1

    return line
#

if ‘main’ == name:

from unit_tests import *

app = wx.App(redirect=False)

frame = wx.Frame(None, size=(710,800))
panel = wx.Panel(frame)
editor = Folding_Text_Control(panel)
sizer = wx.BoxSizer(wx.HORIZONTAL)


sizer.Add(editor, proportion=1, flag = wx.EXPAND)
panel.SetSizer(sizer)
frame.Show()

editor.SetText(open(__file__).read())
editor.EmptyUndoBuffer()

app.MainLoop()

Jesse Aldridge wrote:

The following program is basically just a StyledTextCtrl with the folding functionality from the wxPython Demo.
The problem is when I hold control and shift and click on the first fold box in the margin, the bottom element doesn't get folded.
If I get rid of the line with the hash symbol at the bottom of the class definition, then it works.
The reason I have those lines with a single hash symbol is that I like to have my folds spaced out a little bit, and if I don't have them, any blank lines under a fold get folded away.
Any suggestions?

Weird... The FoldAll works for me on Windows, but not GTK. Maybe it has something to do with the line endings?

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

I made it work by modifying the FoldAll method.

def FoldAll(self):         
    fold_on = ["class ", "def ", "if ", "for ", "while ", "elif ", "else "]        

    def each_line_to_fold():       
        for lineNum, line in enumerate(self.GetText().split('\n')):                   
            for prefix in fold_on:
                if line.strip().startswith(prefix):

                    yield (lineNum, line)
   
    # find out if we are folding or unfolding
    expanding = False
    for lineNum, line in each_line_to_fold():
        expanding = not self.GetFoldExpanded(lineNum)

        break
   
    for lineNum, line in each_line_to_fold():           
        if expanding:
            self.SetFoldExpanded(lineNum, True)
            lineNum = self.Expand(lineNum, True)

            lineNum = lineNum - 1
        else:
            lastChild = self.GetLastChild(lineNum, -1)
            self.SetFoldExpanded(lineNum, False)

            if lastChild > lineNum:

                self.HideLines(lineNum+1, lastChild)
···

On Mon, Aug 11, 2008 at 2:24 PM, Robin Dunn robin@alldunn.com wrote:

Jesse Aldridge wrote:

The following program is basically just a StyledTextCtrl with the folding functionality from the wxPython Demo.

The problem is when I hold control and shift and click on the first fold box in the margin, the bottom element doesn’t get folded.

If I get rid of the line with the hash symbol at the bottom of the class definition, then it works.

The reason I have those lines with a single hash symbol is that I like to have my folds spaced out a little bit, and if I don’t have them, any blank lines under a fold get folded away.

Any suggestions?

Weird… The FoldAll works for me on Windows, but not GTK. Maybe it has something to do with the line endings?

Robin Dunn

Software Craftsman

http://wxPython.org Java give you jitters? Relax with wxPython!


wxpython-users mailing list

wxpython-users@lists.wxwidgets.org

http://lists.wxwidgets.org/mailman/listinfo/wxpython-users