py_ext/PythonEditor.py
changeset 738 413946c04c87
parent 734 5c42cafaee15
child 743 4645a3a398ad
equal deleted inserted replaced
737:7b421e080636 738:413946c04c87
     1 import  wx, wx.grid
     1 import wx
     2 import  wx.stc  as  stc
     2 import wx.grid
       
     3 import wx.stc  as  stc
     3 import keyword
     4 import keyword
     4 
     5 
     5 from util import opjimg
     6 from ConfTreeNodeEditor import ConfTreeNodeEditor
     6 
       
     7 from controls import EditorPanel
       
     8 
     7 
     9 if wx.Platform == '__WXMSW__':
     8 if wx.Platform == '__WXMSW__':
    10     faces = { 'times': 'Times New Roman',
     9     faces = { 'times': 'Times New Roman',
    11               'mono' : 'Courier New',
    10               'mono' : 'Courier New',
    12               'helv' : 'Arial',
    11               'helv' : 'Arial',
    53         else:
    52         else:
    54             return i + 1
    53             return i + 1
    55     else:
    54     else:
    56         return None
    55         return None
    57 
    56 
    58 class PythonEditor(EditorPanel):
    57 class PythonEditor(ConfTreeNodeEditor):
    59 
    58 
    60     fold_symbols = 3
    59     fold_symbols = 3
    61     
    60     
    62     def _init_Editor(self, prnt):
    61     def _init_ConfNodeEditor(self, prnt):
    63         self.Editor = stc.StyledTextCtrl(id=ID_PYTHONEDITOR, parent=prnt,
    62         self.ConfNodeEditor = stc.StyledTextCtrl(id=ID_PYTHONEDITOR, parent=prnt,
    64                  name="TextViewer", pos=wx.DefaultPosition, 
    63                  name="TextViewer", pos=wx.DefaultPosition, 
    65                  size=wx.DefaultSize, style=0)
    64                  size=wx.DefaultSize, style=0)
    66 
    65 
    67         self.Editor.CmdKeyAssign(ord('B'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
    66         self.ConfNodeEditor.CmdKeyAssign(ord('B'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
    68         self.Editor.CmdKeyAssign(ord('N'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
    67         self.ConfNodeEditor.CmdKeyAssign(ord('N'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
    69 
    68 
    70         self.Editor.SetLexer(stc.STC_LEX_PYTHON)
    69         self.ConfNodeEditor.SetLexer(stc.STC_LEX_PYTHON)
    71         self.Editor.SetKeyWords(0, " ".join(keyword.kwlist))
    70         self.ConfNodeEditor.SetKeyWords(0, " ".join(keyword.kwlist))
    72 
    71 
    73         self.Editor.SetProperty("fold", "1")
    72         self.ConfNodeEditor.SetProperty("fold", "1")
    74         self.Editor.SetProperty("tab.timmy.whinge.level", "1")
    73         self.ConfNodeEditor.SetProperty("tab.timmy.whinge.level", "1")
    75         self.Editor.SetMargins(0,0)
    74         self.ConfNodeEditor.SetMargins(0,0)
    76 
    75 
    77         self.Editor.SetViewWhiteSpace(False)
    76         self.ConfNodeEditor.SetViewWhiteSpace(False)
    78         
    77         
    79         self.Editor.SetEdgeMode(stc.STC_EDGE_BACKGROUND)
    78         self.ConfNodeEditor.SetEdgeMode(stc.STC_EDGE_BACKGROUND)
    80         self.Editor.SetEdgeColumn(78)
    79         self.ConfNodeEditor.SetEdgeColumn(78)
    81 
    80 
    82         # Set up the numbers in the margin for margin #1
    81         # Set up the numbers in the margin for margin #1
    83         self.Editor.SetMarginType(1, wx.stc.STC_MARGIN_NUMBER)
    82         self.ConfNodeEditor.SetMarginType(1, wx.stc.STC_MARGIN_NUMBER)
    84         # Reasonable value for, say, 4-5 digits using a mono font (40 pix)
    83         # Reasonable value for, say, 4-5 digits using a mono font (40 pix)
    85         self.Editor.SetMarginWidth(1, 40)
    84         self.ConfNodeEditor.SetMarginWidth(1, 40)
    86 
    85 
    87         # Setup a margin to hold fold markers
    86         # Setup a margin to hold fold markers
    88         self.Editor.SetMarginType(2, stc.STC_MARGIN_SYMBOL)
    87         self.ConfNodeEditor.SetMarginType(2, stc.STC_MARGIN_SYMBOL)
    89         self.Editor.SetMarginMask(2, stc.STC_MASK_FOLDERS)
    88         self.ConfNodeEditor.SetMarginMask(2, stc.STC_MASK_FOLDERS)
    90         self.Editor.SetMarginSensitive(2, True)
    89         self.ConfNodeEditor.SetMarginSensitive(2, True)
    91         self.Editor.SetMarginWidth(2, 12)
    90         self.ConfNodeEditor.SetMarginWidth(2, 12)
    92 
    91 
    93         if self.fold_symbols == 0:
    92         if self.fold_symbols == 0:
    94             # Arrow pointing right for contracted folders, arrow pointing down for expanded
    93             # Arrow pointing right for contracted folders, arrow pointing down for expanded
    95             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN,    stc.STC_MARK_ARROWDOWN, "black", "black")
    94             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN,    stc.STC_MARK_ARROWDOWN, "black", "black")
    96             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDER,        stc.STC_MARK_ARROW, "black", "black")
    95             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDER,        stc.STC_MARK_ARROW, "black", "black")
    97             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB,     stc.STC_MARK_EMPTY, "black", "black")
    96             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB,     stc.STC_MARK_EMPTY, "black", "black")
    98             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL,    stc.STC_MARK_EMPTY, "black", "black")
    97             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL,    stc.STC_MARK_EMPTY, "black", "black")
    99             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDEREND,     stc.STC_MARK_EMPTY,     "white", "black")
    98             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDEREND,     stc.STC_MARK_EMPTY,     "white", "black")
   100             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_EMPTY,     "white", "black")
    99             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_EMPTY,     "white", "black")
   101             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_EMPTY,     "white", "black")
   100             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_EMPTY,     "white", "black")
   102             
   101             
   103         elif self.fold_symbols == 1:
   102         elif self.fold_symbols == 1:
   104             # Plus for contracted folders, minus for expanded
   103             # Plus for contracted folders, minus for expanded
   105             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN,    stc.STC_MARK_MINUS, "white", "black")
   104             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN,    stc.STC_MARK_MINUS, "white", "black")
   106             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDER,        stc.STC_MARK_PLUS,  "white", "black")
   105             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDER,        stc.STC_MARK_PLUS,  "white", "black")
   107             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB,     stc.STC_MARK_EMPTY, "white", "black")
   106             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB,     stc.STC_MARK_EMPTY, "white", "black")
   108             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL,    stc.STC_MARK_EMPTY, "white", "black")
   107             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL,    stc.STC_MARK_EMPTY, "white", "black")
   109             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDEREND,     stc.STC_MARK_EMPTY, "white", "black")
   108             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDEREND,     stc.STC_MARK_EMPTY, "white", "black")
   110             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_EMPTY, "white", "black")
   109             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_EMPTY, "white", "black")
   111             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_EMPTY, "white", "black")
   110             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_EMPTY, "white", "black")
   112 
   111 
   113         elif self.fold_symbols == 2:
   112         elif self.fold_symbols == 2:
   114             # Like a flattened tree control using circular headers and curved joins
   113             # Like a flattened tree control using circular headers and curved joins
   115             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN,    stc.STC_MARK_CIRCLEMINUS,          "white", "#404040")
   114             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN,    stc.STC_MARK_CIRCLEMINUS,          "white", "#404040")
   116             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDER,        stc.STC_MARK_CIRCLEPLUS,           "white", "#404040")
   115             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDER,        stc.STC_MARK_CIRCLEPLUS,           "white", "#404040")
   117             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB,     stc.STC_MARK_VLINE,                "white", "#404040")
   116             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB,     stc.STC_MARK_VLINE,                "white", "#404040")
   118             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL,    stc.STC_MARK_LCORNERCURVE,         "white", "#404040")
   117             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL,    stc.STC_MARK_LCORNERCURVE,         "white", "#404040")
   119             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDEREND,     stc.STC_MARK_CIRCLEPLUSCONNECTED,  "white", "#404040")
   118             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDEREND,     stc.STC_MARK_CIRCLEPLUSCONNECTED,  "white", "#404040")
   120             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_CIRCLEMINUSCONNECTED, "white", "#404040")
   119             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_CIRCLEMINUSCONNECTED, "white", "#404040")
   121             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_TCORNERCURVE,         "white", "#404040")
   120             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_TCORNERCURVE,         "white", "#404040")
   122 
   121 
   123         elif self.fold_symbols == 3:
   122         elif self.fold_symbols == 3:
   124             # Like a flattened tree control using square headers
   123             # Like a flattened tree control using square headers
   125             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN,    stc.STC_MARK_BOXMINUS,          "white", "#808080")
   124             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN,    stc.STC_MARK_BOXMINUS,          "white", "#808080")
   126             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDER,        stc.STC_MARK_BOXPLUS,           "white", "#808080")
   125             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDER,        stc.STC_MARK_BOXPLUS,           "white", "#808080")
   127             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB,     stc.STC_MARK_VLINE,             "white", "#808080")
   126             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB,     stc.STC_MARK_VLINE,             "white", "#808080")
   128             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL,    stc.STC_MARK_LCORNER,           "white", "#808080")
   127             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL,    stc.STC_MARK_LCORNER,           "white", "#808080")
   129             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDEREND,     stc.STC_MARK_BOXPLUSCONNECTED,  "white", "#808080")
   128             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDEREND,     stc.STC_MARK_BOXPLUSCONNECTED,  "white", "#808080")
   130             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080")
   129             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080")
   131             self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_TCORNER,           "white", "#808080")
   130             self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_TCORNER,           "white", "#808080")
   132 
   131 
   133 
   132 
   134         self.Editor.Bind(stc.EVT_STC_UPDATEUI, self.OnUpdateUI)
   133         self.ConfNodeEditor.Bind(stc.EVT_STC_UPDATEUI, self.OnUpdateUI)
   135         self.Editor.Bind(stc.EVT_STC_MARGINCLICK, self.OnMarginClick)
   134         self.ConfNodeEditor.Bind(stc.EVT_STC_MARGINCLICK, self.OnMarginClick)
   136         self.Editor.Bind(wx.EVT_KEY_DOWN, self.OnKeyPressed)
   135         self.ConfNodeEditor.Bind(wx.EVT_KEY_DOWN, self.OnKeyPressed)
   137 
   136 
   138         # Global default style
   137         # Global default style
   139         if wx.Platform == '__WXMSW__':
   138         if wx.Platform == '__WXMSW__':
   140             self.Editor.StyleSetSpec(stc.STC_STYLE_DEFAULT, 'fore:#000000,back:#FFFFFF,face:Courier New')
   139             self.ConfNodeEditor.StyleSetSpec(stc.STC_STYLE_DEFAULT, 'fore:#000000,back:#FFFFFF,face:Courier New')
   141         elif wx.Platform == '__WXMAC__':
   140         elif wx.Platform == '__WXMAC__':
   142             # TODO: if this looks fine on Linux too, remove the Mac-specific case 
   141             # TODO: if this looks fine on Linux too, remove the Mac-specific case 
   143             # and use this whenever OS != MSW.
   142             # and use this whenever OS != MSW.
   144             self.Editor.StyleSetSpec(stc.STC_STYLE_DEFAULT, 'fore:#000000,back:#FFFFFF,face:Monaco')
   143             self.ConfNodeEditor.StyleSetSpec(stc.STC_STYLE_DEFAULT, 'fore:#000000,back:#FFFFFF,face:Monaco')
   145         else:
   144         else:
   146             defsize = wx.SystemSettings.GetFont(wx.SYS_ANSI_FIXED_FONT).GetPointSize()
   145             defsize = wx.SystemSettings.GetFont(wx.SYS_ANSI_FIXED_FONT).GetPointSize()
   147             self.Editor.StyleSetSpec(stc.STC_STYLE_DEFAULT, 'fore:#000000,back:#FFFFFF,face:Courier,size:%d'%defsize)
   146             self.ConfNodeEditor.StyleSetSpec(stc.STC_STYLE_DEFAULT, 'fore:#000000,back:#FFFFFF,face:Courier,size:%d'%defsize)
   148 
   147 
   149         # Clear styles and revert to default.
   148         # Clear styles and revert to default.
   150         self.Editor.StyleClearAll()
   149         self.ConfNodeEditor.StyleClearAll()
   151 
   150 
   152         # Following style specs only indicate differences from default.
   151         # Following style specs only indicate differences from default.
   153         # The rest remains unchanged.
   152         # The rest remains unchanged.
   154 
   153 
   155         # Line numbers in margin
   154         # Line numbers in margin
   156         self.Editor.StyleSetSpec(wx.stc.STC_STYLE_LINENUMBER,'fore:#000000,back:#99A9C2')    
   155         self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_STYLE_LINENUMBER,'fore:#000000,back:#99A9C2')    
   157         # Highlighted brace
   156         # Highlighted brace
   158         self.Editor.StyleSetSpec(wx.stc.STC_STYLE_BRACELIGHT,'fore:#00009D,back:#FFFF00')
   157         self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_STYLE_BRACELIGHT,'fore:#00009D,back:#FFFF00')
   159         # Unmatched brace
   158         # Unmatched brace
   160         self.Editor.StyleSetSpec(wx.stc.STC_STYLE_BRACEBAD,'fore:#00009D,back:#FF0000')
   159         self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_STYLE_BRACEBAD,'fore:#00009D,back:#FF0000')
   161         # Indentation guide
   160         # Indentation guide
   162         self.Editor.StyleSetSpec(wx.stc.STC_STYLE_INDENTGUIDE, "fore:#CDCDCD")
   161         self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_STYLE_INDENTGUIDE, "fore:#CDCDCD")
   163 
   162 
   164         # Python styles
   163         # Python styles
   165         self.Editor.StyleSetSpec(wx.stc.STC_P_DEFAULT, 'fore:#000000')
   164         self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_DEFAULT, 'fore:#000000')
   166         # Comments
   165         # Comments
   167         self.Editor.StyleSetSpec(wx.stc.STC_P_COMMENTLINE,  'fore:#008000,back:#F0FFF0')
   166         self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_COMMENTLINE,  'fore:#008000,back:#F0FFF0')
   168         self.Editor.StyleSetSpec(wx.stc.STC_P_COMMENTBLOCK, 'fore:#008000,back:#F0FFF0')
   167         self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_COMMENTBLOCK, 'fore:#008000,back:#F0FFF0')
   169         # Numbers
   168         # Numbers
   170         self.Editor.StyleSetSpec(wx.stc.STC_P_NUMBER, 'fore:#008080')
   169         self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_NUMBER, 'fore:#008080')
   171         # Strings and characters
   170         # Strings and characters
   172         self.Editor.StyleSetSpec(wx.stc.STC_P_STRING, 'fore:#800080')
   171         self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_STRING, 'fore:#800080')
   173         self.Editor.StyleSetSpec(wx.stc.STC_P_CHARACTER, 'fore:#800080')
   172         self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_CHARACTER, 'fore:#800080')
   174         # Keywords
   173         # Keywords
   175         self.Editor.StyleSetSpec(wx.stc.STC_P_WORD, 'fore:#000080,bold')
   174         self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_WORD, 'fore:#000080,bold')
   176         # Triple quotes
   175         # Triple quotes
   177         self.Editor.StyleSetSpec(wx.stc.STC_P_TRIPLE, 'fore:#800080,back:#FFFFEA')
   176         self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_TRIPLE, 'fore:#800080,back:#FFFFEA')
   178         self.Editor.StyleSetSpec(wx.stc.STC_P_TRIPLEDOUBLE, 'fore:#800080,back:#FFFFEA')
   177         self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_TRIPLEDOUBLE, 'fore:#800080,back:#FFFFEA')
   179         # Class names
   178         # Class names
   180         self.Editor.StyleSetSpec(wx.stc.STC_P_CLASSNAME, 'fore:#0000FF,bold')
   179         self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_CLASSNAME, 'fore:#0000FF,bold')
   181         # Function names
   180         # Function names
   182         self.Editor.StyleSetSpec(wx.stc.STC_P_DEFNAME, 'fore:#008080,bold')
   181         self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_DEFNAME, 'fore:#008080,bold')
   183         # Operators
   182         # Operators
   184         self.Editor.StyleSetSpec(wx.stc.STC_P_OPERATOR, 'fore:#800000,bold')
   183         self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_OPERATOR, 'fore:#800000,bold')
   185         # Identifiers. I leave this as not bold because everything seems
   184         # Identifiers. I leave this as not bold because everything seems
   186         # to be an identifier if it doesn't match the above criterae
   185         # to be an identifier if it doesn't match the above criterae
   187         self.Editor.StyleSetSpec(wx.stc.STC_P_IDENTIFIER, 'fore:#000000')
   186         self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_IDENTIFIER, 'fore:#000000')
   188 
   187 
   189         # Caret color
   188         # Caret color
   190         self.Editor.SetCaretForeground("BLUE")
   189         self.ConfNodeEditor.SetCaretForeground("BLUE")
   191         # Selection background
   190         # Selection background
   192         self.Editor.SetSelBackground(1, '#66CCFF')
   191         self.ConfNodeEditor.SetSelBackground(1, '#66CCFF')
   193 
   192 
   194         self.Editor.SetSelBackground(True, wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT))
   193         self.ConfNodeEditor.SetSelBackground(True, wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT))
   195         self.Editor.SetSelForeground(True, wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT))
   194         self.ConfNodeEditor.SetSelForeground(True, wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT))
   196         
   195         
   197         # register some images for use in the AutoComplete box.
   196         # register some images for use in the AutoComplete box.
   198         #self.RegisterImage(1, images.getSmilesBitmap())
   197         #self.RegisterImage(1, images.getSmilesBitmap())
   199         self.Editor.RegisterImage(1, 
   198         self.ConfNodeEditor.RegisterImage(1, 
   200             wx.ArtProvider.GetBitmap(wx.ART_DELETE, size=(16,16)))
   199             wx.ArtProvider.GetBitmap(wx.ART_DELETE, size=(16,16)))
   201         self.Editor.RegisterImage(2, 
   200         self.ConfNodeEditor.RegisterImage(2, 
   202             wx.ArtProvider.GetBitmap(wx.ART_NEW, size=(16,16)))
   201             wx.ArtProvider.GetBitmap(wx.ART_NEW, size=(16,16)))
   203         self.Editor.RegisterImage(3, 
   202         self.ConfNodeEditor.RegisterImage(3, 
   204             wx.ArtProvider.GetBitmap(wx.ART_COPY, size=(16,16)))
   203             wx.ArtProvider.GetBitmap(wx.ART_COPY, size=(16,16)))
   205 
   204 
   206         # Indentation and tab stuff
   205         # Indentation and tab stuff
   207         self.Editor.SetIndent(4)               # Proscribed indent size for wx
   206         self.ConfNodeEditor.SetIndent(4)               # Proscribed indent size for wx
   208         self.Editor.SetIndentationGuides(True) # Show indent guides
   207         self.ConfNodeEditor.SetIndentationGuides(True) # Show indent guides
   209         self.Editor.SetBackSpaceUnIndents(True)# Backspace unindents rather than delete 1 space
   208         self.ConfNodeEditor.SetBackSpaceUnIndents(True)# Backspace unindents rather than delete 1 space
   210         self.Editor.SetTabIndents(True)        # Tab key indents
   209         self.ConfNodeEditor.SetTabIndents(True)        # Tab key indents
   211         self.Editor.SetTabWidth(4)             # Proscribed tab size for wx
   210         self.ConfNodeEditor.SetTabWidth(4)             # Proscribed tab size for wx
   212         self.Editor.SetUseTabs(False)          # Use spaces rather than tabs, or
   211         self.ConfNodeEditor.SetUseTabs(False)          # Use spaces rather than tabs, or
   213                                         # TabTimmy will complain!    
   212                                         # TabTimmy will complain!    
   214         # White space
   213         # White space
   215         self.Editor.SetViewWhiteSpace(False)   # Don't view white space
   214         self.ConfNodeEditor.SetViewWhiteSpace(False)   # Don't view white space
   216 
   215 
   217         # EOL: Since we are loading/saving ourselves, and the
   216         # EOL: Since we are loading/saving ourselves, and the
   218         # strings will always have \n's in them, set the STC to
   217         # strings will always have \n's in them, set the STC to
   219         # edit them that way.            
   218         # edit them that way.            
   220         self.Editor.SetEOLMode(wx.stc.STC_EOL_LF)
   219         self.ConfNodeEditor.SetEOLMode(wx.stc.STC_EOL_LF)
   221         self.Editor.SetViewEOL(False)
   220         self.ConfNodeEditor.SetViewEOL(False)
   222         
   221         
   223         # No right-edge mode indicator
   222         # No right-edge mode indicator
   224         self.Editor.SetEdgeMode(stc.STC_EDGE_NONE)
   223         self.ConfNodeEditor.SetEdgeMode(stc.STC_EDGE_NONE)
   225         
   224         
   226         self.Editor.SetModEventMask(wx.stc.STC_MOD_BEFOREINSERT|wx.stc.STC_MOD_BEFOREDELETE)
   225         self.ConfNodeEditor.SetModEventMask(wx.stc.STC_MOD_BEFOREINSERT|wx.stc.STC_MOD_BEFOREDELETE)
   227 
   226 
   228         self.Editor.Bind(wx.stc.EVT_STC_DO_DROP, self.OnDoDrop, id=ID_PYTHONEDITOR)
   227         self.ConfNodeEditor.Bind(wx.stc.EVT_STC_DO_DROP, self.OnDoDrop, id=ID_PYTHONEDITOR)
   229         self.Editor.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
   228         self.ConfNodeEditor.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
   230         self.Editor.Bind(wx.stc.EVT_STC_MODIFIED, self.OnModification, id=ID_PYTHONEDITOR)
   229         self.ConfNodeEditor.Bind(wx.stc.EVT_STC_MODIFIED, self.OnModification, id=ID_PYTHONEDITOR)
   231 
   230 
   232 
   231 
   233     def __init__(self, parent, controler, window):
   232     def __init__(self, parent, controler, window):
   234         EditorPanel.__init__(self, parent, "", window, controler)
   233         ConfTreeNodeEditor.__init__(self, parent, "", controler, window)
   235         
   234         
   236         self.DisableEvents = False
   235         self.DisableEvents = False
   237         self.CurrentAction = None
   236         self.CurrentAction = None
   238         
       
   239         self.SetIcon(wx.Bitmap(opjimg("Cfile")))
       
   240     
       
   241     def __del__(self):
       
   242         self.Controler.OnCloseEditor(self)
       
   243     
       
   244     def GetTitle(self):
       
   245         fullname = self.Controler.CTNFullName()
       
   246         if not self.Controler.PythonIsSaved():
       
   247             return "~%s~" % fullname
       
   248         return fullname
       
   249     
   237     
   250     def GetBufferState(self):
   238     def GetBufferState(self):
   251         return self.Controler.GetBufferState()
   239         return self.Controler.GetBufferState()
   252         
   240         
   253     def Undo(self):
   241     def Undo(self):
   255         self.RefreshView()
   243         self.RefreshView()
   256             
   244             
   257     def Redo(self):
   245     def Redo(self):
   258         self.Controler.LoadNext()
   246         self.Controler.LoadNext()
   259         self.RefreshView()
   247         self.RefreshView()
   260     
       
   261     def HasNoModel(self):
       
   262         return False
       
   263     
   248     
   264     def OnModification(self, event):
   249     def OnModification(self, event):
   265         if not self.DisableEvents:
   250         if not self.DisableEvents:
   266             mod_type = event.GetModificationType()
   251             mod_type = event.GetModificationType()
   267             if not (mod_type&wx.stc.STC_PERFORMED_UNDO or mod_type&wx.stc.STC_PERFORMED_REDO):
   252             if not (mod_type&wx.stc.STC_PERFORMED_UNDO or mod_type&wx.stc.STC_PERFORMED_REDO):
   311             self.CurrentAction = None
   296             self.CurrentAction = None
   312 
   297 
   313     def RefreshView(self):
   298     def RefreshView(self):
   314         self.ResetBuffer()
   299         self.ResetBuffer()
   315         self.DisableEvents = True
   300         self.DisableEvents = True
   316         old_cursor_pos = self.Editor.GetCurrentPos()
   301         old_cursor_pos = self.ConfNodeEditor.GetCurrentPos()
   317         old_text = self.Editor.GetText()
   302         old_text = self.ConfNodeEditor.GetText()
   318         new_text = self.Controler.GetPythonCode()
   303         new_text = self.Controler.GetPythonCode()
   319         self.Editor.SetText(new_text)
   304         self.ConfNodeEditor.SetText(new_text)
   320         new_cursor_pos = GetCursorPos(old_text, new_text)
   305         new_cursor_pos = GetCursorPos(old_text, new_text)
   321         if new_cursor_pos != None:
   306         if new_cursor_pos != None:
   322             self.Editor.GotoPos(new_cursor_pos)
   307             self.ConfNodeEditor.GotoPos(new_cursor_pos)
   323         else:
   308         else:
   324             self.Editor.GotoPos(old_cursor_pos)
   309             self.ConfNodeEditor.GotoPos(old_cursor_pos)
   325         self.Editor.ScrollToColumn(0)
   310         self.ConfNodeEditor.ScrollToColumn(0)
   326         self.Editor.EmptyUndoBuffer()
   311         self.ConfNodeEditor.EmptyUndoBuffer()
   327         self.DisableEvents = False
   312         self.DisableEvents = False
   328         
   313         
   329         self.Editor.Colourise(0, -1)
   314         self.ConfNodeEditor.Colourise(0, -1)
   330 
   315 
   331     def RefreshModel(self):
   316     def RefreshModel(self):
   332         self.Controler.SetPythonCode(self.Editor.GetText())
   317         self.Controler.SetPythonCode(self.ConfNodeEditor.GetText())
   333 
   318 
   334     def OnKeyPressed(self, event):
   319     def OnKeyPressed(self, event):
   335         if self.Editor.CallTipActive():
   320         if self.ConfNodeEditor.CallTipActive():
   336             self.Editor.CallTipCancel()
   321             self.ConfNodeEditor.CallTipCancel()
   337         key = event.GetKeyCode()
   322         key = event.GetKeyCode()
   338 
   323 
   339         if key == 32 and event.ControlDown():
   324         if key == 32 and event.ControlDown():
   340             pos = self.Editor.GetCurrentPos()
   325             pos = self.ConfNodeEditor.GetCurrentPos()
   341 
   326 
   342             # Tips
       
   343             if event.ShiftDown():
       
   344                 pass
       
   345 ##                self.CallTipSetBackground("yellow")
       
   346 ##                self.CallTipShow(pos, 'lots of of text: blah, blah, blah\n\n'
       
   347 ##                                 'show some suff, maybe parameters..\n\n'
       
   348 ##                                 'fubar(param1, param2)')
       
   349             # Code completion
   327             # Code completion
   350             else:
   328             if not event.ShiftDown():
   351                 self.Editor.AutoCompSetIgnoreCase(False)  # so this needs to match
   329                 self.ConfNodeEditor.AutoCompSetIgnoreCase(False)  # so this needs to match
   352 
   330 
   353                 # Images are specified with a appended "?type"
   331                 # Images are specified with a appended "?type"
   354                 self.Editor.AutoCompShow(0, " ".join([word + "?1" for word in keyword.kwlist]))
   332                 self.ConfNodeEditor.AutoCompShow(0, " ".join([word + "?1" for word in keyword.kwlist]))
   355         else:
   333         else:
   356             event.Skip()
   334             event.Skip()
   357 
   335 
   358     def OnKillFocus(self, event):
   336     def OnKillFocus(self, event):
   359         self.Editor.AutoCompCancel()
   337         self.ConfNodeEditor.AutoCompCancel()
   360         event.Skip()
   338         event.Skip()
   361 
   339 
   362     def OnUpdateUI(self, evt):
   340     def OnUpdateUI(self, evt):
   363         # check for matching braces
   341         # check for matching braces
   364         braceAtCaret = -1
   342         braceAtCaret = -1
   365         braceOpposite = -1
   343         braceOpposite = -1
   366         charBefore = None
   344         charBefore = None
   367         caretPos = self.Editor.GetCurrentPos()
   345         caretPos = self.ConfNodeEditor.GetCurrentPos()
   368 
   346 
   369         if caretPos > 0:
   347         if caretPos > 0:
   370             charBefore = self.Editor.GetCharAt(caretPos - 1)
   348             charBefore = self.ConfNodeEditor.GetCharAt(caretPos - 1)
   371             styleBefore = self.Editor.GetStyleAt(caretPos - 1)
   349             styleBefore = self.ConfNodeEditor.GetStyleAt(caretPos - 1)
   372 
   350 
   373         # check before
   351         # check before
   374         if charBefore and chr(charBefore) in "[]{}()" and styleBefore == stc.STC_P_OPERATOR:
   352         if charBefore and chr(charBefore) in "[]{}()" and styleBefore == stc.STC_P_OPERATOR:
   375             braceAtCaret = caretPos - 1
   353             braceAtCaret = caretPos - 1
   376 
   354 
   377         # check after
   355         # check after
   378         if braceAtCaret < 0:
   356         if braceAtCaret < 0:
   379             charAfter = self.Editor.GetCharAt(caretPos)
   357             charAfter = self.ConfNodeEditor.GetCharAt(caretPos)
   380             styleAfter = self.Editor.GetStyleAt(caretPos)
   358             styleAfter = self.ConfNodeEditor.GetStyleAt(caretPos)
   381 
   359 
   382             if charAfter and chr(charAfter) in "[]{}()" and styleAfter == stc.STC_P_OPERATOR:
   360             if charAfter and chr(charAfter) in "[]{}()" and styleAfter == stc.STC_P_OPERATOR:
   383                 braceAtCaret = caretPos
   361                 braceAtCaret = caretPos
   384 
   362 
   385         if braceAtCaret >= 0:
   363         if braceAtCaret >= 0:
   386             braceOpposite = self.Editor.BraceMatch(braceAtCaret)
   364             braceOpposite = self.ConfNodeEditor.BraceMatch(braceAtCaret)
   387 
   365 
   388         if braceAtCaret != -1  and braceOpposite == -1:
   366         if braceAtCaret != -1  and braceOpposite == -1:
   389             self.Editor.BraceBadLight(braceAtCaret)
   367             self.ConfNodeEditor.BraceBadLight(braceAtCaret)
   390         else:
   368         else:
   391             self.Editor.BraceHighlight(braceAtCaret, braceOpposite)
   369             self.ConfNodeEditor.BraceHighlight(braceAtCaret, braceOpposite)
   392             #pt = self.Editor.PointFromPosition(braceOpposite)
       
   393             #self.Editor.Refresh(True, wxRect(pt.x, pt.y, 5,5))
       
   394             #print pt
       
   395             #self.Editor.Refresh(False)
       
   396 
       
   397 
   370 
   398     def OnMarginClick(self, evt):
   371     def OnMarginClick(self, evt):
   399         # fold and unfold as needed
   372         # fold and unfold as needed
   400         if evt.GetMargin() == 2:
   373         if evt.GetMargin() == 2:
   401             if evt.GetShift() and evt.GetControl():
   374             if evt.GetShift() and evt.GetControl():
   402                 self.FoldAll()
   375                 self.FoldAll()
   403             else:
   376             else:
   404                 lineClicked = self.Editor.LineFromPosition(evt.GetPosition())
   377                 lineClicked = self.ConfNodeEditor.LineFromPosition(evt.GetPosition())
   405 
   378 
   406                 if self.Editor.GetFoldLevel(lineClicked) & stc.STC_FOLDLEVELHEADERFLAG:
   379                 if self.ConfNodeEditor.GetFoldLevel(lineClicked) & stc.STC_FOLDLEVELHEADERFLAG:
   407                     if evt.GetShift():
   380                     if evt.GetShift():
   408                         self.Editor.SetFoldExpanded(lineClicked, True)
   381                         self.ConfNodeEditor.SetFoldExpanded(lineClicked, True)
   409                         self.Expand(lineClicked, True, True, 1)
   382                         self.Expand(lineClicked, True, True, 1)
   410                     elif evt.GetControl():
   383                     elif evt.GetControl():
   411                         if self.Editor.GetFoldExpanded(lineClicked):
   384                         if self.ConfNodeEditor.GetFoldExpanded(lineClicked):
   412                             self.Editor.SetFoldExpanded(lineClicked, False)
   385                             self.ConfNodeEditor.SetFoldExpanded(lineClicked, False)
   413                             self.Expand(lineClicked, False, True, 0)
   386                             self.Expand(lineClicked, False, True, 0)
   414                         else:
   387                         else:
   415                             self.Editor.SetFoldExpanded(lineClicked, True)
   388                             self.ConfNodeEditor.SetFoldExpanded(lineClicked, True)
   416                             self.Expand(lineClicked, True, True, 100)
   389                             self.Expand(lineClicked, True, True, 100)
   417                     else:
   390                     else:
   418                         self.Editor.ToggleFold(lineClicked)
   391                         self.ConfNodeEditor.ToggleFold(lineClicked)
   419 
   392 
   420 
   393 
   421     def FoldAll(self):
   394     def FoldAll(self):
   422         lineCount = self.Editor.GetLineCount()
   395         lineCount = self.ConfNodeEditor.GetLineCount()
   423         expanding = True
   396         expanding = True
   424 
   397 
   425         # find out if we are folding or unfolding
   398         # find out if we are folding or unfolding
   426         for lineNum in range(lineCount):
   399         for lineNum in range(lineCount):
   427             if self.Editor.GetFoldLevel(lineNum) & stc.STC_FOLDLEVELHEADERFLAG:
   400             if self.ConfNodeEditor.GetFoldLevel(lineNum) & stc.STC_FOLDLEVELHEADERFLAG:
   428                 expanding = not self.Editor.GetFoldExpanded(lineNum)
   401                 expanding = not self.ConfNodeEditor.GetFoldExpanded(lineNum)
   429                 break
   402                 break
   430 
   403 
   431         lineNum = 0
   404         lineNum = 0
   432 
   405 
   433         while lineNum < lineCount:
   406         while lineNum < lineCount:
   434             level = self.Editor.GetFoldLevel(lineNum)
   407             level = self.ConfNodeEditor.GetFoldLevel(lineNum)
   435             if level & stc.STC_FOLDLEVELHEADERFLAG and \
   408             if level & stc.STC_FOLDLEVELHEADERFLAG and \
   436                (level & stc.STC_FOLDLEVELNUMBERMASK) == stc.STC_FOLDLEVELBASE:
   409                (level & stc.STC_FOLDLEVELNUMBERMASK) == stc.STC_FOLDLEVELBASE:
   437 
   410 
   438                 if expanding:
   411                 if expanding:
   439                     self.Editor.SetFoldExpanded(lineNum, True)
   412                     self.ConfNodeEditor.SetFoldExpanded(lineNum, True)
   440                     lineNum = self.Expand(lineNum, True)
   413                     lineNum = self.Expand(lineNum, True)
   441                     lineNum = lineNum - 1
   414                     lineNum = lineNum - 1
   442                 else:
   415                 else:
   443                     lastChild = self.Editor.GetLastChild(lineNum, -1)
   416                     lastChild = self.ConfNodeEditor.GetLastChild(lineNum, -1)
   444                     self.Editor.SetFoldExpanded(lineNum, False)
   417                     self.ConfNodeEditor.SetFoldExpanded(lineNum, False)
   445 
   418 
   446                     if lastChild > lineNum:
   419                     if lastChild > lineNum:
   447                         self.Editor.HideLines(lineNum+1, lastChild)
   420                         self.ConfNodeEditor.HideLines(lineNum+1, lastChild)
   448 
   421 
   449             lineNum = lineNum + 1
   422             lineNum = lineNum + 1
   450 
   423 
   451 
   424 
   452 
   425 
   453     def Expand(self, line, doExpand, force=False, visLevels=0, level=-1):
   426     def Expand(self, line, doExpand, force=False, visLevels=0, level=-1):
   454         lastChild = self.Editor.GetLastChild(line, level)
   427         lastChild = self.ConfNodeEditor.GetLastChild(line, level)
   455         line = line + 1
   428         line = line + 1
   456 
   429 
   457         while line <= lastChild:
   430         while line <= lastChild:
   458             if force:
   431             if force:
   459                 if visLevels > 0:
   432                 if visLevels > 0:
   460                     self.Editor.ShowLines(line, line)
   433                     self.ConfNodeEditor.ShowLines(line, line)
   461                 else:
   434                 else:
   462                     self.Editor.HideLines(line, line)
   435                     self.ConfNodeEditor.HideLines(line, line)
   463             else:
   436             else:
   464                 if doExpand:
   437                 if doExpand:
   465                     self.Editor.ShowLines(line, line)
   438                     self.ConfNodeEditor.ShowLines(line, line)
   466 
   439 
   467             if level == -1:
   440             if level == -1:
   468                 level = self.Editor.GetFoldLevel(line)
   441                 level = self.ConfNodeEditor.GetFoldLevel(line)
   469 
   442 
   470             if level & stc.STC_FOLDLEVELHEADERFLAG:
   443             if level & stc.STC_FOLDLEVELHEADERFLAG:
   471                 if force:
   444                 if force:
   472                     if visLevels > 1:
   445                     if visLevels > 1:
   473                         self.Editor.SetFoldExpanded(line, True)
   446                         self.ConfNodeEditor.SetFoldExpanded(line, True)
   474                     else:
   447                     else:
   475                         self.Editor.SetFoldExpanded(line, False)
   448                         self.ConfNodeEditor.SetFoldExpanded(line, False)
   476 
   449 
   477                     line = self.Expand(line, doExpand, force, visLevels-1)
   450                     line = self.Expand(line, doExpand, force, visLevels-1)
   478 
   451 
   479                 else:
   452                 else:
   480                     if doExpand and self.Editor.GetFoldExpanded(line):
   453                     if doExpand and self.ConfNodeEditor.GetFoldExpanded(line):
   481                         line = self.Expand(line, True, force, visLevels-1)
   454                         line = self.Expand(line, True, force, visLevels-1)
   482                     else:
   455                     else:
   483                         line = self.Expand(line, False, force, visLevels-1)
   456                         line = self.Expand(line, False, force, visLevels-1)
   484             else:
   457             else:
   485                 line = line + 1
   458                 line = line + 1
   487         return line
   460         return line
   488 
   461 
   489     def Cut(self):
   462     def Cut(self):
   490         self.ResetBuffer()
   463         self.ResetBuffer()
   491         self.DisableEvents = True
   464         self.DisableEvents = True
   492         self.Editor.CmdKeyExecute(wx.stc.STC_CMD_CUT)
   465         self.ConfNodeEditor.CmdKeyExecute(wx.stc.STC_CMD_CUT)
   493         self.DisableEvents = False
   466         self.DisableEvents = False
   494         self.RefreshModel()
   467         self.RefreshModel()
   495         self.RefreshBuffer()
   468         self.RefreshBuffer()
   496     
   469     
   497     def Copy(self):
   470     def Copy(self):
   498         self.Editor.CmdKeyExecute(wx.stc.STC_CMD_COPY)
   471         self.ConfNodeEditor.CmdKeyExecute(wx.stc.STC_CMD_COPY)
   499     
   472     
   500     def Paste(self):
   473     def Paste(self):
   501         self.ResetBuffer()
   474         self.ResetBuffer()
   502         self.DisableEvents = True
   475         self.DisableEvents = True
   503         self.Editor.CmdKeyExecute(wx.stc.STC_CMD_PASTE)
   476         self.ConfNodeEditor.CmdKeyExecute(wx.stc.STC_CMD_PASTE)
   504         self.DisableEvents = False
   477         self.DisableEvents = False
   505         self.RefreshModel()
   478         self.RefreshModel()
   506         self.RefreshBuffer()
   479         self.RefreshBuffer()