1 #---------------------------------------------------------------------------- 
   2 # Name:         STCTextEditor.py 
   3 # Purpose:      Text Editor for wx.lib.pydocview tbat uses the Styled Text Control 
   5 # Author:       Peter Yared, Morgan Hua 
   9 # Copyright:    (c) 2003-2005 ActiveGrid, Inc. 
  10 # License:      wxWindows License 
  11 #---------------------------------------------------------------------------- 
  16 import wx
.lib
.multisash
 
  17 import wx
.lib
.pydocview
 
  24 #---------------------------------------------------------------------------- 
  26 #---------------------------------------------------------------------------- 
  29 VIEW_WHITESPACE_ID 
= wx
.NewId() 
  30 VIEW_EOL_ID 
= wx
.NewId() 
  31 VIEW_INDENTATION_GUIDES_ID 
= wx
.NewId() 
  32 VIEW_RIGHT_EDGE_ID 
= wx
.NewId() 
  33 VIEW_LINE_NUMBERS_ID 
= wx
.NewId() 
  35 ZOOM_NORMAL_ID 
= wx
.NewId() 
  36 ZOOM_IN_ID 
= wx
.NewId() 
  37 ZOOM_OUT_ID 
= wx
.NewId() 
  38 CHOOSE_FONT_ID 
= wx
.NewId() 
  39 WORD_WRAP_ID 
= wx
.NewId() 
  40 TEXT_STATUS_BAR_ID 
= wx
.NewId() 
  43 #---------------------------------------------------------------------------- 
  45 #---------------------------------------------------------------------------- 
  47 class TextDocument(wx
.lib
.docview
.Document
): 
  50     def OnSaveDocument(self
, filename
): 
  51         view 
= self
.GetFirstView() 
  52         docFile 
= file(self
._documentFile
, "w") 
  53         docFile
.write(view
.GetValue()) 
  56         self
.SetDocumentModificationDate() 
  57         self
.SetDocumentSaved(True) 
  61     def OnOpenDocument(self
, filename
): 
  62         view 
= self
.GetFirstView() 
  63         docFile 
= file(self
._documentFile
, 'r') 
  66         self
.SetFilename(filename
, True) 
  68         self
.SetDocumentModificationDate() 
  75         view 
= self
.GetFirstView() 
  77             return wx
.lib
.docview
.Document
.IsModified(self
) or view
.IsModified() 
  79             return wx
.lib
.docview
.Document
.IsModified(self
) 
  82     def Modify(self
, mod
): 
  83         view 
= self
.GetFirstView() 
  84         wx
.lib
.docview
.Document
.Modify(self
, mod
) 
  89     def OnCreateCommandProcessor(self
): 
  90         # Don't create a command processor, it has its own 
  93 # Use this to override MultiClient.Select to prevent yellow background. 
  94 def MultiClientSelectBGNotYellow(a
): 
  95         a
.GetParent().multiView
.UnSelect() 
  97         #a.SetBackgroundColour(wx.Colour(255,255,0)) # Yellow 
 100 class TextView(wx
.lib
.docview
.View
): 
 104     #---------------------------------------------------------------------------- 
 106     #---------------------------------------------------------------------------- 
 109         wx
.lib
.docview
.View
.__init
__(self
) 
 110         self
._textEditor 
= None 
 111         self
._markerCount 
= 0 
 112         self
._commandProcessor 
= None 
 113         self
._multiSash 
= None 
 116     def GetCtrlClass(self
): 
 121         # look for active one first 
 122         self
._textEditor 
= self
._GetActiveCtrl
(self
._multiSash
) 
 123         if self
._textEditor 
== None:  # it is possible none are active 
 124             # look for any existing one 
 125             self
._textEditor 
= self
._FindCtrl
(self
._multiSash
) 
 126         return self
._textEditor
 
 129 ##    def GetCtrls(self, parent = None): 
 130 ##        """ Walk through the MultiSash windows and find all Ctrls """ 
 132 ##        if isinstance(parent, self.GetCtrlClass()): 
 134 ##        if hasattr(parent, "GetChildren"): 
 135 ##            for child in parent.GetChildren(): 
 136 ##                controls = controls + self.GetCtrls(child) 
 140     def OnCreate(self
, doc
, flags
): 
 141         frame 
= wx
.GetApp().CreateDocumentFrame(self
, doc
, flags
, style 
= wx
.DEFAULT_FRAME_STYLE | wx
.NO_FULL_REPAINT_ON_RESIZE
) 
 142         wx
.lib
.multisash
.MultiClient
.Select 
= MultiClientSelectBGNotYellow
 
 143         self
._multiSash 
= wx
.lib
.multisash
.MultiSash(frame
, -1) 
 144         self
._multiSash
.SetDefaultChildClass(self
.GetCtrlClass()) # wxBug:  MultiSash instantiates the first TextCtrl with this call 
 145         self
._textEditor 
= self
.GetCtrl()  # wxBug: grab the TextCtrl from the MultiSash datastructure 
 146         self
._CreateSizer
(frame
) 
 153     def _GetActiveCtrl(self
, parent
): 
 154         """ Walk through the MultiSash windows and find the active Control """ 
 155         if isinstance(parent
, wx
.lib
.multisash
.MultiClient
) and parent
.selected
: 
 157         if hasattr(parent
, "GetChildren"): 
 158             for child 
in parent
.GetChildren(): 
 159                 found 
= self
._GetActiveCtrl
(child
) 
 165     def _FindCtrl(self
, parent
): 
 166         """ Walk through the MultiSash windows and find the first TextCtrl """ 
 167         if isinstance(parent
, self
.GetCtrlClass()): 
 169         if hasattr(parent
, "GetChildren"): 
 170             for child 
in parent
.GetChildren(): 
 171                 found 
= self
._FindCtrl
(child
) 
 177     def _CreateSizer(self
, frame
): 
 178         sizer 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
 179         sizer
.Add(self
._multiSash
, 1, wx
.EXPAND
) 
 180         frame
.SetSizer(sizer
) 
 181         frame
.SetAutoLayout(True) 
 184     def OnUpdate(self
, sender 
= None, hint 
= None): 
 185         if hint 
== "ViewStuff": 
 186             self
.GetCtrl().SetViewDefaults() 
 188             font
, color 
= self
.GetFontAndColorFromConfig() 
 189             self
.GetCtrl().SetFont(font
) 
 190             self
.GetCtrl().SetFontColor(color
) 
 193     def OnActivateView(self
, activate
, activeView
, deactiveView
): 
 194         if activate 
and self
.GetCtrl(): 
 195             # In MDI mode just calling set focus doesn't work and in SDI mode using CallAfter causes an endless loop 
 196             if self
.GetDocumentManager().GetFlags() & wx
.lib
.docview
.DOC_SDI
: 
 199                 wx
.CallAfter(self
.SetFocus
) 
 204             self
.GetCtrl().SetFocus() 
 207     def OnClose(self
, deleteWindow 
= True): 
 208         if not wx
.lib
.docview
.View
.OnClose(self
, deleteWindow
): 
 211         if deleteWindow 
and self
.GetFrame(): 
 212             self
.GetFrame().Destroy() 
 216     def ProcessEvent(self
, event
):         
 219             self
.GetCtrl().Undo() 
 221         elif id == wx
.ID_REDO
: 
 222             self
.GetCtrl().Redo() 
 224         elif id == wx
.ID_CUT
: 
 227         elif id == wx
.ID_COPY
: 
 228             self
.GetCtrl().Copy() 
 230         elif id == wx
.ID_PASTE
: 
 231             self
.GetCtrl().OnPaste() 
 233         elif id == wx
.ID_CLEAR
: 
 234             self
.GetCtrl().OnClear() 
 236         elif id == wx
.ID_SELECTALL
: 
 237             self
.GetCtrl().SetSelection(0, -1) 
 239         elif id == VIEW_WHITESPACE_ID
: 
 240             self
.GetCtrl().SetViewWhiteSpace(not self
.GetCtrl().GetViewWhiteSpace()) 
 242         elif id == VIEW_EOL_ID
: 
 243             self
.GetCtrl().SetViewEOL(not self
.GetCtrl().GetViewEOL()) 
 245         elif id == VIEW_INDENTATION_GUIDES_ID
: 
 246             self
.GetCtrl().SetViewIndentationGuides(not self
.GetCtrl().GetViewIndentationGuides()) 
 248         elif id == VIEW_RIGHT_EDGE_ID
: 
 249             self
.GetCtrl().SetViewRightEdge(not self
.GetCtrl().GetViewRightEdge()) 
 251         elif id == VIEW_LINE_NUMBERS_ID
: 
 252             self
.GetCtrl().SetViewLineNumbers(not self
.GetCtrl().GetViewLineNumbers()) 
 254         elif id == ZOOM_NORMAL_ID
: 
 255             self
.GetCtrl().SetZoom(0) 
 257         elif id == ZOOM_IN_ID
: 
 258             self
.GetCtrl().CmdKeyExecute(wx
.stc
.STC_CMD_ZOOMIN
) 
 260         elif id == ZOOM_OUT_ID
: 
 261             self
.GetCtrl().CmdKeyExecute(wx
.stc
.STC_CMD_ZOOMOUT
) 
 263         elif id == CHOOSE_FONT_ID
: 
 266         elif id == WORD_WRAP_ID
: 
 267             self
.GetCtrl().SetWordWrap(not self
.GetCtrl().GetWordWrap()) 
 269         elif id == FindService
.FindService
.FIND_ID
: 
 272         elif id == FindService
.FindService
.FIND_PREVIOUS_ID
: 
 273             self
.DoFind(forceFindPrevious 
= True) 
 275         elif id == FindService
.FindService
.FIND_NEXT_ID
: 
 276             self
.DoFind(forceFindNext 
= True) 
 278         elif id == FindService
.FindService
.REPLACE_ID
: 
 279             self
.OnFind(replace 
= True) 
 281         elif id == FindService
.FindService
.FINDONE_ID
: 
 284         elif id == FindService
.FindService
.REPLACEONE_ID
: 
 285             self
.DoFind(replace 
= True) 
 287         elif id == FindService
.FindService
.REPLACEALL_ID
: 
 288             self
.DoFind(replaceAll 
= True) 
 290         elif id == FindService
.FindService
.GOTO_LINE_ID
: 
 291             self
.OnGotoLine(event
) 
 294             return wx
.lib
.docview
.View
.ProcessEvent(self
, event
) 
 297     def ProcessUpdateUIEvent(self
, event
): 
 298         if not self
.GetCtrl(): 
 303              event
.Enable(self
.GetCtrl().CanUndo()) 
 304              event
.SetText(_("Undo") + '\t' + _('Ctrl+Z')) 
 306         elif id == wx
.ID_REDO
: 
 307             event
.Enable(self
.GetCtrl().CanRedo()) 
 308             event
.SetText(_("Redo") + '\t' + _('Ctrl+Y')) 
 310         elif (id == wx
.ID_CUT
 
 312         or id == wx
.ID_CLEAR
): 
 313             hasSelection 
= self
.GetCtrl().GetSelectionStart() != self
.GetCtrl().GetSelectionEnd() 
 314             event
.Enable(hasSelection
) 
 316         elif id == wx
.ID_PASTE
: 
 317             event
.Enable(self
.GetCtrl().CanPaste()) 
 319         elif id == wx
.ID_SELECTALL
: 
 320             hasText 
= self
.GetCtrl().GetTextLength() > 0 
 321             event
.Enable(hasText
) 
 326         elif id == VIEW_WHITESPACE_ID
: 
 327             hasText 
= self
.GetCtrl().GetTextLength() > 0 
 328             event
.Enable(hasText
) 
 329             event
.Check(self
.GetCtrl().GetViewWhiteSpace()) 
 331         elif id == VIEW_EOL_ID
: 
 332             hasText 
= self
.GetCtrl().GetTextLength() > 0 
 333             event
.Enable(hasText
) 
 334             event
.Check(self
.GetCtrl().GetViewEOL()) 
 336         elif id == VIEW_INDENTATION_GUIDES_ID
: 
 337             hasText 
= self
.GetCtrl().GetTextLength() > 0 
 338             event
.Enable(hasText
) 
 339             event
.Check(self
.GetCtrl().GetIndentationGuides()) 
 341         elif id == VIEW_RIGHT_EDGE_ID
: 
 342             hasText 
= self
.GetCtrl().GetTextLength() > 0 
 343             event
.Enable(hasText
) 
 344             event
.Check(self
.GetCtrl().GetViewRightEdge()) 
 346         elif id == VIEW_LINE_NUMBERS_ID
: 
 347             hasText 
= self
.GetCtrl().GetTextLength() > 0 
 348             event
.Enable(hasText
) 
 349             event
.Check(self
.GetCtrl().GetViewLineNumbers()) 
 354         elif id == ZOOM_NORMAL_ID
: 
 355             event
.Enable(self
.GetCtrl().GetZoom() != 0) 
 357         elif id == ZOOM_IN_ID
: 
 358             event
.Enable(self
.GetCtrl().GetZoom() < 20) 
 360         elif id == ZOOM_OUT_ID
: 
 361             event
.Enable(self
.GetCtrl().GetZoom() > -10) 
 363         elif id == CHOOSE_FONT_ID
: 
 366         elif id == WORD_WRAP_ID
: 
 367             event
.Enable(self
.GetCtrl().CanWordWrap()) 
 368             event
.Check(self
.GetCtrl().CanWordWrap() and self
.GetCtrl().GetWordWrap()) 
 370         elif id == FindService
.FindService
.FIND_ID
: 
 371             hasText 
= self
.GetCtrl().GetTextLength() > 0 
 372             event
.Enable(hasText
) 
 374         elif id == FindService
.FindService
.FIND_PREVIOUS_ID
: 
 375             hasText 
= self
.GetCtrl().GetTextLength() > 0 
 376             event
.Enable(hasText 
and 
 377                          self
._FindServiceHasString
() and 
 378                          self
.GetCtrl().GetSelection()[0] > 0) 
 380         elif id == FindService
.FindService
.FIND_NEXT_ID
: 
 381             hasText 
= self
.GetCtrl().GetTextLength() > 0 
 382             event
.Enable(hasText 
and 
 383                          self
._FindServiceHasString
() and 
 384                          self
.GetCtrl().GetSelection()[0] < self
.GetCtrl().GetLength()) 
 386         elif id == FindService
.FindService
.REPLACE_ID
: 
 387             hasText 
= self
.GetCtrl().GetTextLength() > 0 
 388             event
.Enable(hasText
) 
 390         elif id == FindService
.FindService
.GOTO_LINE_ID
: 
 393         elif id == TEXT_STATUS_BAR_ID
: 
 394             self
.OnUpdateStatusBar(event
) 
 397             return wx
.lib
.docview
.View
.ProcessUpdateUIEvent(self
, event
) 
 400     def _GetParentFrame(self
): 
 401         return wx
.GetTopLevelParent(self
.GetFrame()) 
 404     #---------------------------------------------------------------------------- 
 405     # Methods for TextDocument to call 
 406     #---------------------------------------------------------------------------- 
 408     def IsModified(self
): 
 409         if not self
.GetCtrl(): 
 411         return self
.GetCtrl().GetModify() 
 414     def SetModifyFalse(self
): 
 415         self
.GetCtrl().SetSavePoint() 
 420             return self
.GetCtrl().GetText() 
 425     def SetValue(self
, value
): 
 426         self
.GetCtrl().SetText(value
) 
 427         self
.GetCtrl().UpdateLineNumberMarginWidth() 
 428         self
.GetCtrl().EmptyUndoBuffer() 
 431     #---------------------------------------------------------------------------- 
 433     #---------------------------------------------------------------------------- 
 435     def OnUpdateStatusBar(self
, event
): 
 436         statusBar 
= self
._GetParentFrame
().GetStatusBar() 
 437         statusBar
.SetInsertMode(self
.GetCtrl().GetOvertype() == 0) 
 438         statusBar
.SetLineNumber(self
.GetCtrl().GetCurrentLine() + 1) 
 439         statusBar
.SetColumnNumber(self
.GetCtrl().GetColumn(self
.GetCtrl().GetCurrentPos()) + 1) 
 442     #---------------------------------------------------------------------------- 
 444     #---------------------------------------------------------------------------- 
 446     def OnChooseFont(self
): 
 448         data
.EnableEffects(True) 
 449         data
.SetInitialFont(self
.GetCtrl().GetFont()) 
 450         data
.SetColour(self
.GetCtrl().GetFontColor()) 
 451         fontDialog 
= wx
.FontDialog(self
.GetFrame(), data
) 
 452         if fontDialog
.ShowModal() == wx
.ID_OK
: 
 453             data 
= fontDialog
.GetFontData() 
 454             self
.GetCtrl().SetFont(data
.GetChosenFont()) 
 455             self
.GetCtrl().SetFontColor(data
.GetColour()) 
 456             self
.GetCtrl().UpdateStyles() 
 460     #---------------------------------------------------------------------------- 
 462     #---------------------------------------------------------------------------- 
 464     def OnFind(self
, replace 
= False): 
 465         findService 
= wx
.GetApp().GetService(FindService
.FindService
) 
 467             findService
.ShowFindReplaceDialog(findString 
= self
.GetCtrl().GetSelectedText(), replace 
= replace
) 
 470     def DoFind(self
, forceFindNext 
= False, forceFindPrevious 
= False, replace 
= False, replaceAll 
= False): 
 471         findService 
= wx
.GetApp().GetService(FindService
.FindService
) 
 474         findString 
= findService
.GetFindString() 
 475         if len(findString
) == 0: 
 477         replaceString 
= findService
.GetReplaceString() 
 478         flags 
= findService
.GetFlags() 
 479         startLoc
, endLoc 
= self
.GetCtrl().GetSelection() 
 481         wholeWord 
= flags 
& wx
.FR_WHOLEWORD 
> 0 
 482         matchCase 
= flags 
& wx
.FR_MATCHCASE 
> 0 
 483         regExp 
= flags 
& FindService
.FindService
.FR_REGEXP 
> 0 
 484         down 
= flags 
& wx
.FR_DOWN 
> 0 
 485         wrap 
= flags 
& FindService
.FindService
.FR_WRAP 
> 0 
 487         if forceFindPrevious
:   # this is from function keys, not dialog box 
 489             wrap 
= False        # user would want to know they're at the end of file 
 492             wrap 
= False        # user would want to know they're at the end of file 
 496         # On replace dialog operations, user is allowed to replace the currently highlighted text to determine if it should be replaced or not. 
 497         # Typically, it is the text from a previous find operation, but we must check to see if it isn't, user may have moved the cursor or selected some other text accidentally. 
 498         # If the text is a match, then replace it. 
 500             result
, start
, end
, replText 
= findService
.DoFind(findString
, replaceString
, self
.GetCtrl().GetSelectedText(), 0, 0, True, matchCase
, wholeWord
, regExp
, replace
) 
 502                 self
.GetCtrl().ReplaceSelection(replText
) 
 503                 self
.GetDocument().Modify(True) 
 504                 wx
.GetApp().GetTopWindow().PushStatusText(_("1 occurrence of \"%s\" replaced") % findString
) 
 506                     startLoc 
+= len(replText
)  # advance start location past replacement string to new text 
 508             elif result 
== FindService
.FIND_SYNTAXERROR
: 
 510                 wx
.GetApp().GetTopWindow().PushStatusText(_("Invalid regular expression \"%s\"") % findString
) 
 513             text 
= self
.GetCtrl().GetText() 
 515             # Find the next matching text occurance or if it is a ReplaceAll, replace all occurances 
 516             # Even if the user is Replacing, we should replace here, but only select the text and let the user replace it with the next Replace operation 
 517             result
, start
, end
, text 
= findService
.DoFind(findString
, replaceString
, text
, startLoc
, endLoc
, down
, matchCase
, wholeWord
, regExp
, False, replaceAll
, wrap
) 
 519                 self
.GetCtrl().SetTargetStart(0) 
 520                 self
.GetCtrl().SetTargetEnd(self
.GetCtrl().GetLength()) 
 521                 self
.GetCtrl().ReplaceTarget(text
)  # Doing a SetText causes a clear document to be shown when undoing, so using replacetarget instead 
 522                 self
.GetDocument().Modify(True) 
 524                     wx
.GetApp().GetTopWindow().PushStatusText(_("1 occurrence of \"%s\" replaced") % findString
) 
 526                     wx
.GetApp().GetTopWindow().PushStatusText(_("%i occurrences of \"%s\" replaced") % (result
, findString
)) 
 528                 self
.GetCtrl().SetSelection(start
, end
) 
 529                 self
.GetCtrl().EnsureVisible(self
.GetCtrl().LineFromPosition(end
))  # show bottom then scroll up to top 
 530                 self
.GetCtrl().EnsureVisible(self
.GetCtrl().LineFromPosition(start
)) # do this after ensuring bottom is visible 
 531                 wx
.GetApp().GetTopWindow().PushStatusText(_("Found \"%s\".") % findString
) 
 532             elif result 
== FindService
.FIND_SYNTAXERROR
: 
 533                 # Dialog for this case gets popped up by the FindService. 
 534                 wx
.GetApp().GetTopWindow().PushStatusText(_("Invalid regular expression \"%s\"") % findString
) 
 536                 wx
.MessageBox(_("Can't find \"%s\".") % findString
, "Find", 
 537                           wx
.OK | wx
.ICON_INFORMATION
) 
 540     def _FindServiceHasString(self
): 
 541         findService 
= wx
.GetApp().GetService(FindService
.FindService
) 
 542         if not findService 
or not findService
.GetFindString(): 
 547     def OnGotoLine(self
, event
): 
 548         findService 
= wx
.GetApp().GetService(FindService
.FindService
) 
 550             line 
= findService
.GetLineNumber(self
.GetDocumentManager().FindSuitableParent()) 
 553                 self
.GetCtrl().EnsureVisible(line
) 
 554                 self
.GetCtrl().GotoLine(line
) 
 557     def GotoLine(self
, lineNum
): 
 559             lineNum 
= lineNum 
- 1  # line numbering for editor is 0 based, we are 1 based. 
 560             self
.GetCtrl().EnsureVisibleEnforcePolicy(lineNum
) 
 561             self
.GetCtrl().GotoLine(lineNum
) 
 564     def SetSelection(self
, start
, end
): 
 565         self
.GetCtrl().SetSelection(start
, end
) 
 568     def EnsureVisible(self
, line
): 
 569         self
.GetCtrl().EnsureVisible(line
-1)  # line numbering for editor is 0 based, we are 1 based. 
 571     def EnsureVisibleEnforcePolicy(self
, line
): 
 572         self
.GetCtrl().EnsureVisibleEnforcePolicy(line
-1)  # line numbering for editor is 0 based, we are 1 based. 
 574     def LineFromPosition(self
, pos
): 
 575         return self
.GetCtrl().LineFromPosition(pos
)+1  # line numbering for editor is 0 based, we are 1 based. 
 578     def PositionFromLine(self
, line
): 
 579         return self
.GetCtrl().PositionFromLine(line
-1)  # line numbering for editor is 0 based, we are 1 based. 
 582     def GetLineEndPosition(self
, line
): 
 583         return self
.GetCtrl().GetLineEndPosition(line
-1)  # line numbering for editor is 0 based, we are 1 based. 
 586     def GetLine(self
, lineNum
): 
 587         return self
.GetCtrl().GetLine(lineNum
-1)  # line numbering for editor is 0 based, we are 1 based. 
 589     def MarkerDefine(self
): 
 590         """ This must be called after the texteditor is instantiated """ 
 591         self
.GetCtrl().MarkerDefine(TextView
.MARKER_NUM
, wx
.stc
.STC_MARK_CIRCLE
, wx
.BLACK
, wx
.BLUE
) 
 594     def MarkerToggle(self
, lineNum 
= -1, marker_index
=MARKER_NUM
, mask
=MARKER_MASK
): 
 596             lineNum 
= self
.GetCtrl().GetCurrentLine() 
 597         if self
.GetCtrl().MarkerGet(lineNum
) & mask
: 
 598             self
.GetCtrl().MarkerDelete(lineNum
, marker_index
) 
 599             self
._markerCount 
-= 1 
 601             self
.GetCtrl().MarkerAdd(lineNum
, marker_index
) 
 602             self
._markerCount 
+= 1 
 604     def MarkerAdd(self
, lineNum 
= -1, marker_index
=MARKER_NUM
, mask
=MARKER_MASK
): 
 606             lineNum 
= self
.GetCtrl().GetCurrentLine() 
 607         self
.GetCtrl().MarkerAdd(lineNum
, marker_index
) 
 608         self
._markerCount 
+= 1 
 611     def MarkerDelete(self
, lineNum 
= -1, marker_index
=MARKER_NUM
, mask
=MARKER_MASK
): 
 613             lineNum 
= self
.GetCtrl().GetCurrentLine() 
 614         if self
.GetCtrl().MarkerGet(lineNum
) & mask
: 
 615             self
.GetCtrl().MarkerDelete(lineNum
, marker_index
) 
 616             self
._markerCount 
-= 1 
 618     def MarkerDeleteAll(self
, marker_num
=MARKER_NUM
): 
 619         self
.GetCtrl().MarkerDeleteAll(marker_num
) 
 620         if marker_num 
== self
.MARKER_NUM
: 
 621             self
._markerCount 
= 0 
 624     def MarkerNext(self
, lineNum 
= -1): 
 626             lineNum 
= self
.GetCtrl().GetCurrentLine() + 1  # start search below current line 
 627         foundLine 
= self
.GetCtrl().MarkerNext(lineNum
, self
.MARKER_MASK
) 
 629             # wrap to top of file 
 630             foundLine 
= self
.GetCtrl().MarkerNext(0, self
.MARKER_MASK
) 
 632                 wx
.GetApp().GetTopWindow().PushStatusText(_("No markers")) 
 635         self
.GotoLine(foundLine 
+ 1) 
 638     def MarkerPrevious(self
, lineNum 
= -1): 
 640             lineNum 
= self
.GetCtrl().GetCurrentLine() - 1  # start search above current line 
 642                 lineNum 
= self
.GetCtrl().GetLineCount() 
 644         foundLine 
= self
.GetCtrl().MarkerPrevious(lineNum
, self
.MARKER_MASK
) 
 646             # wrap to bottom of file 
 647             foundLine 
= self
.GetCtrl().MarkerPrevious(self
.GetCtrl().GetLineCount(), self
.MARKER_MASK
) 
 649                 wx
.GetApp().GetTopWindow().PushStatusText(_("No markers")) 
 652         self
.GotoLine(foundLine 
+ 1) 
 655     def MarkerExists(self
, lineNum 
= -1, mask
=MARKER_MASK
): 
 657             lineNum 
= self
.GetCtrl().GetCurrentLine() 
 658         if self
.GetCtrl().MarkerGet(lineNum
) & mask
: 
 664     def GetMarkerCount(self
): 
 665         return self
._markerCount
 
 668 class TextService(wx
.lib
.pydocview
.DocService
): 
 672         wx
.lib
.pydocview
.DocService
.__init
__(self
) 
 675     def InstallControls(self
, frame
, menuBar 
= None, toolBar 
= None, statusBar 
= None, document 
= None): 
 676         if document 
and document
.GetDocumentTemplate().GetDocumentType() != TextDocument
: 
 678         if not document 
and wx
.GetApp().GetDocumentManager().GetFlags() & wx
.lib
.docview
.DOC_SDI
: 
 681         statusBar 
= TextStatusBar(frame
, TEXT_STATUS_BAR_ID
) 
 682         frame
.SetStatusBar(statusBar
) 
 683         wx
.EVT_UPDATE_UI(frame
, TEXT_STATUS_BAR_ID
, frame
.ProcessUpdateUIEvent
) 
 685         viewMenu 
= menuBar
.GetMenu(menuBar
.FindMenu(_("&View"))) 
 687         viewMenu
.AppendSeparator() 
 689         textMenu
.AppendCheckItem(VIEW_WHITESPACE_ID
, _("&Whitespace"), _("Shows or hides whitespace")) 
 690         wx
.EVT_MENU(frame
, VIEW_WHITESPACE_ID
, frame
.ProcessEvent
) 
 691         wx
.EVT_UPDATE_UI(frame
, VIEW_WHITESPACE_ID
, frame
.ProcessUpdateUIEvent
) 
 692         textMenu
.AppendCheckItem(VIEW_EOL_ID
, _("&End of Line Markers"), _("Shows or hides indicators at the end of each line")) 
 693         wx
.EVT_MENU(frame
, VIEW_EOL_ID
, frame
.ProcessEvent
) 
 694         wx
.EVT_UPDATE_UI(frame
, VIEW_EOL_ID
, frame
.ProcessUpdateUIEvent
) 
 695         textMenu
.AppendCheckItem(VIEW_INDENTATION_GUIDES_ID
, _("&Indentation Guides"), _("Shows or hides indentations")) 
 696         wx
.EVT_MENU(frame
, VIEW_INDENTATION_GUIDES_ID
, frame
.ProcessEvent
) 
 697         wx
.EVT_UPDATE_UI(frame
, VIEW_INDENTATION_GUIDES_ID
, frame
.ProcessUpdateUIEvent
) 
 698         textMenu
.AppendCheckItem(VIEW_RIGHT_EDGE_ID
, _("&Right Edge"), _("Shows or hides the right edge marker")) 
 699         wx
.EVT_MENU(frame
, VIEW_RIGHT_EDGE_ID
, frame
.ProcessEvent
) 
 700         wx
.EVT_UPDATE_UI(frame
, VIEW_RIGHT_EDGE_ID
, frame
.ProcessUpdateUIEvent
) 
 701         textMenu
.AppendCheckItem(VIEW_LINE_NUMBERS_ID
, _("&Line Numbers"), _("Shows or hides the line numbers")) 
 702         wx
.EVT_MENU(frame
, VIEW_LINE_NUMBERS_ID
, frame
.ProcessEvent
) 
 703         wx
.EVT_UPDATE_UI(frame
, VIEW_LINE_NUMBERS_ID
, frame
.ProcessUpdateUIEvent
) 
 705         viewMenu
.AppendMenu(TEXT_ID
, _("&Text"), textMenu
) 
 706         wx
.EVT_UPDATE_UI(frame
, TEXT_ID
, frame
.ProcessUpdateUIEvent
) 
 708         isWindows 
= (wx
.Platform 
== '__WXMSW__') 
 711         zoomMenu
.Append(ZOOM_NORMAL_ID
, _("Normal Size"), _("Sets the document to its normal size")) 
 712         wx
.EVT_MENU(frame
, ZOOM_NORMAL_ID
, frame
.ProcessEvent
) 
 713         wx
.EVT_UPDATE_UI(frame
, ZOOM_NORMAL_ID
, frame
.ProcessUpdateUIEvent
) 
 715             zoomMenu
.Append(ZOOM_IN_ID
, _("Zoom In\tCtrl+Page Up"), _("Zooms the document to a larger size")) 
 717             zoomMenu
.Append(ZOOM_IN_ID
, _("Zoom In"), _("Zooms the document to a larger size")) 
 718         wx
.EVT_MENU(frame
, ZOOM_IN_ID
, frame
.ProcessEvent
) 
 719         wx
.EVT_UPDATE_UI(frame
, ZOOM_IN_ID
, frame
.ProcessUpdateUIEvent
) 
 721             zoomMenu
.Append(ZOOM_OUT_ID
, _("Zoom Out\tCtrl+Page Down"), _("Zooms the document to a smaller size")) 
 723             zoomMenu
.Append(ZOOM_OUT_ID
, _("Zoom Out"), _("Zooms the document to a smaller size")) 
 724         wx
.EVT_MENU(frame
, ZOOM_OUT_ID
, frame
.ProcessEvent
) 
 725         wx
.EVT_UPDATE_UI(frame
, ZOOM_OUT_ID
, frame
.ProcessUpdateUIEvent
) 
 727         viewMenu
.AppendMenu(ZOOM_ID
, _("&Zoom"), zoomMenu
) 
 728         wx
.EVT_UPDATE_UI(frame
, ZOOM_ID
, frame
.ProcessUpdateUIEvent
) 
 730         formatMenuIndex 
= menuBar
.FindMenu(_("&Format")) 
 731         if formatMenuIndex 
> -1: 
 732             formatMenu 
= menuBar
.GetMenu(formatMenuIndex
) 
 734             formatMenu 
= wx
.Menu() 
 735         if not menuBar
.FindItemById(CHOOSE_FONT_ID
): 
 736             formatMenu
.Append(CHOOSE_FONT_ID
, _("&Font..."), _("Sets the font to use")) 
 737             wx
.EVT_MENU(frame
, CHOOSE_FONT_ID
, frame
.ProcessEvent
) 
 738             wx
.EVT_UPDATE_UI(frame
, CHOOSE_FONT_ID
, frame
.ProcessUpdateUIEvent
) 
 739         if not menuBar
.FindItemById(WORD_WRAP_ID
): 
 740             formatMenu
.AppendCheckItem(WORD_WRAP_ID
, _("Word Wrap"), _("Wraps text horizontally when checked")) 
 741             wx
.EVT_MENU(frame
, WORD_WRAP_ID
, frame
.ProcessEvent
) 
 742             wx
.EVT_UPDATE_UI(frame
, WORD_WRAP_ID
, frame
.ProcessUpdateUIEvent
) 
 743         if formatMenuIndex 
== -1: 
 744             viewMenuIndex 
= menuBar
.FindMenu(_("&View")) 
 745             menuBar
.Insert(viewMenuIndex 
+ 1, formatMenu
, _("&Format")) 
 747         # wxBug: wxToolBar::GetToolPos doesn't exist, need it to find cut tool and then insert find in front of it. 
 748         toolBar
.AddSeparator() 
 749         toolBar
.AddTool(ZOOM_IN_ID
, getZoomInBitmap(), shortHelpString 
= _("Zoom In"), longHelpString 
= _("Zooms the document to a larger size")) 
 750         toolBar
.AddTool(ZOOM_OUT_ID
, getZoomOutBitmap(), shortHelpString 
= _("Zoom Out"), longHelpString 
= _("Zooms the document to a smaller size")) 
 754     def ProcessUpdateUIEvent(self
, event
): 
 757         or id == VIEW_WHITESPACE_ID
 
 759         or id == VIEW_INDENTATION_GUIDES_ID
 
 760         or id == VIEW_RIGHT_EDGE_ID
 
 761         or id == VIEW_LINE_NUMBERS_ID
 
 763         or id == ZOOM_NORMAL_ID
 
 766         or id == CHOOSE_FONT_ID
 
 767         or id == WORD_WRAP_ID
): 
 774 class TextStatusBar(wx
.StatusBar
): 
 776     # wxBug: Would be nice to show num key status in statusbar, but can't figure out how to detect if it is enabled or disabled 
 778     def __init__(self
, parent
, id, style 
= wx
.ST_SIZEGRIP
, name 
= "statusBar"): 
 779         wx
.StatusBar
.__init
__(self
, parent
, id, style
, name
) 
 780         self
.SetFieldsCount(4) 
 781         self
.SetStatusWidths([-1, 50, 50, 55]) 
 783     def SetInsertMode(self
, insert 
= True): 
 788         if self
.GetStatusText(1) != newText
:     # wxBug: Need to check if the text has changed, otherwise it flickers under win32 
 789             self
.SetStatusText(newText
, 1) 
 791     def SetLineNumber(self
, lineNumber
): 
 792         newText 
= _("Ln %i") % lineNumber
 
 793         if self
.GetStatusText(2) != newText
: 
 794             self
.SetStatusText(newText
, 2) 
 796     def SetColumnNumber(self
, colNumber
): 
 797         newText 
= _("Col %i") % colNumber
 
 798         if self
.GetStatusText(3) != newText
: 
 799             self
.SetStatusText(newText
, 3) 
 802 class TextOptionsPanel(wx
.Panel
): 
 805     def __init__(self
, parent
, id, configPrefix 
= "Text", label 
= "Text", hasWordWrap 
= True, hasTabs 
= False, addPage
=True): 
 806         wx
.Panel
.__init
__(self
, parent
, id) 
 807         self
._configPrefix 
= configPrefix
 
 808         self
._hasWordWrap 
= hasWordWrap
 
 809         self
._hasTabs 
= hasTabs
 
 812         config 
= wx
.ConfigBase_Get() 
 813         self
._textFont 
= wx
.Font(10, wx
.MODERN
, wx
.NORMAL
, wx
.NORMAL
) 
 814         fontData 
= config
.Read(self
._configPrefix 
+ "EditorFont", "") 
 816             nativeFont 
= wx
.NativeFontInfo() 
 817             nativeFont
.FromString(fontData
) 
 818             self
._textFont
.SetNativeFontInfo(nativeFont
) 
 819         self
._originalTextFont 
= self
._textFont
 
 820         self
._textColor 
= wx
.BLACK
 
 821         colorData 
= config
.Read(self
._configPrefix 
+ "EditorColor", "") 
 823             red 
= int("0x" + colorData
[0:2], 16) 
 824             green 
= int("0x" + colorData
[2:4], 16) 
 825             blue 
= int("0x" + colorData
[4:6], 16) 
 826             self
._textColor 
= wx
.Color(red
, green
, blue
) 
 827         self
._originalTextColor 
= self
._textColor
 
 828         fontLabel 
= wx
.StaticText(self
, -1, _("Font:")) 
 829         self
._sampleTextCtrl 
= wx
.TextCtrl(self
, -1, "", size 
= (125, 21)) 
 830         self
._sampleTextCtrl
.SetEditable(False) 
 831         chooseFontButton 
= wx
.Button(self
, -1, _("Choose Font...")) 
 832         wx
.EVT_BUTTON(self
, chooseFontButton
.GetId(), self
.OnChooseFont
) 
 833         if self
._hasWordWrap
: 
 834             self
._wordWrapCheckBox 
= wx
.CheckBox(self
, -1, _("Wrap words inside text area")) 
 835             self
._wordWrapCheckBox
.SetValue(wx
.ConfigBase_Get().ReadInt(self
._configPrefix 
+ "EditorWordWrap", False)) 
 836         self
._viewWhitespaceCheckBox 
= wx
.CheckBox(self
, -1, _("Show whitespace")) 
 837         self
._viewWhitespaceCheckBox
.SetValue(config
.ReadInt(self
._configPrefix 
+ "EditorViewWhitespace", False)) 
 838         self
._viewEOLCheckBox 
= wx
.CheckBox(self
, -1, _("Show end of line markers")) 
 839         self
._viewEOLCheckBox
.SetValue(config
.ReadInt(self
._configPrefix 
+ "EditorViewEOL", False)) 
 840         self
._viewIndentationGuideCheckBox 
= wx
.CheckBox(self
, -1, _("Show indentation guides")) 
 841         self
._viewIndentationGuideCheckBox
.SetValue(config
.ReadInt(self
._configPrefix 
+ "EditorViewIndentationGuides", False)) 
 842         self
._viewRightEdgeCheckBox 
= wx
.CheckBox(self
, -1, _("Show right edge")) 
 843         self
._viewRightEdgeCheckBox
.SetValue(config
.ReadInt(self
._configPrefix 
+ "EditorViewRightEdge", False)) 
 844         self
._viewLineNumbersCheckBox 
= wx
.CheckBox(self
, -1, _("Show line numbers")) 
 845         self
._viewLineNumbersCheckBox
.SetValue(config
.ReadInt(self
._configPrefix 
+ "EditorViewLineNumbers", True)) 
 847             self
._hasTabsCheckBox 
= wx
.CheckBox(self
, -1, _("Use spaces instead of tabs")) 
 848             self
._hasTabsCheckBox
.SetValue(not wx
.ConfigBase_Get().ReadInt(self
._configPrefix 
+ "EditorUseTabs", False)) 
 849             indentWidthLabel 
= wx
.StaticText(self
, -1, _("Indent Width:")) 
 850             self
._indentWidthChoice 
= wx
.Choice(self
, -1, choices 
= ["2", "4", "6", "8", "10"]) 
 851             self
._indentWidthChoice
.SetStringSelection(str(config
.ReadInt(self
._configPrefix 
+ "EditorIndentWidth", 4))) 
 852         textPanelBorderSizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
 853         textPanelSizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
 854         textFontSizer 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
 855         textFontSizer
.Add(fontLabel
, 0, wx
.ALIGN_LEFT | wx
.RIGHT | wx
.TOP
, HALF_SPACE
) 
 856         textFontSizer
.Add(self
._sampleTextCtrl
, 0, wx
.ALIGN_LEFT | wx
.EXPAND | wx
.RIGHT
, HALF_SPACE
) 
 857         textFontSizer
.Add(chooseFontButton
, 0, wx
.ALIGN_RIGHT | wx
.LEFT
, HALF_SPACE
) 
 858         textPanelSizer
.Add(textFontSizer
, 0, wx
.ALL
, HALF_SPACE
) 
 859         if self
._hasWordWrap
: 
 860             textPanelSizer
.Add(self
._wordWrapCheckBox
, 0, wx
.ALL
, HALF_SPACE
) 
 861         textPanelSizer
.Add(self
._viewWhitespaceCheckBox
, 0, wx
.ALL
, HALF_SPACE
) 
 862         textPanelSizer
.Add(self
._viewEOLCheckBox
, 0, wx
.ALL
, HALF_SPACE
) 
 863         textPanelSizer
.Add(self
._viewIndentationGuideCheckBox
, 0, wx
.ALL
, HALF_SPACE
) 
 864         textPanelSizer
.Add(self
._viewRightEdgeCheckBox
, 0, wx
.ALL
, HALF_SPACE
) 
 865         textPanelSizer
.Add(self
._viewLineNumbersCheckBox
, 0, wx
.ALL
, HALF_SPACE
) 
 867             textPanelSizer
.Add(self
._hasTabsCheckBox
, 0, wx
.ALL
, HALF_SPACE
) 
 868             textIndentWidthSizer 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
 869             textIndentWidthSizer
.Add(indentWidthLabel
, 0, wx
.ALIGN_LEFT | wx
.RIGHT | wx
.TOP
, HALF_SPACE
) 
 870             textIndentWidthSizer
.Add(self
._indentWidthChoice
, 0, wx
.ALIGN_LEFT | wx
.EXPAND
, HALF_SPACE
) 
 871             textPanelSizer
.Add(textIndentWidthSizer
, 0, wx
.ALL
, HALF_SPACE
) 
 872         textPanelBorderSizer
.Add(textPanelSizer
, 0, wx
.ALL
, SPACE
) 
 873 ##        styleButton = wx.Button(self, -1, _("Choose Style...")) 
 874 ##        wx.EVT_BUTTON(self, styleButton.GetId(), self.OnChooseStyle) 
 875 ##        textPanelBorderSizer.Add(styleButton, 0, wx.ALL, SPACE) 
 876         self
.SetSizer(textPanelBorderSizer
) 
 877         self
.UpdateSampleFont() 
 879             parent
.AddPage(self
, _(label
)) 
 881     def UpdateSampleFont(self
): 
 882         nativeFont 
= wx
.NativeFontInfo() 
 883         nativeFont
.FromString(self
._textFont
.GetNativeFontInfoDesc()) 
 885         font
.SetNativeFontInfo(nativeFont
) 
 886         font
.SetPointSize(self
._sampleTextCtrl
.GetFont().GetPointSize())  # Use the standard point size 
 887         self
._sampleTextCtrl
.SetFont(font
) 
 888         self
._sampleTextCtrl
.SetForegroundColour(self
._textColor
) 
 889         self
._sampleTextCtrl
.SetValue(str(self
._textFont
.GetPointSize()) + _(" pt. ") + self
._textFont
.GetFaceName()) 
 890         self
._sampleTextCtrl
.Refresh() 
 894 ##    def OnChooseStyle(self, event): 
 895 ##        import STCStyleEditor 
 897 ##        base = os.path.split(__file__)[0] 
 898 ##        config = os.path.abspath(os.path.join(base, 'stc-styles.rc.cfg')) 
 900 ##        dlg = STCStyleEditor.STCStyleEditDlg(None, 
 901 ##                                'Python', 'python', 
 911     def OnChooseFont(self
, event
): 
 913         data
.EnableEffects(True) 
 914         data
.SetInitialFont(self
._textFont
) 
 915         data
.SetColour(self
._textColor
) 
 916         fontDialog 
= wx
.FontDialog(self
, data
) 
 917         if fontDialog
.ShowModal() == wx
.ID_OK
: 
 918             data 
= fontDialog
.GetFontData() 
 919             self
._textFont 
= data
.GetChosenFont() 
 920             self
._textColor 
= data
.GetColour() 
 921             self
.UpdateSampleFont() 
 925     def OnOK(self
, optionsDialog
): 
 926         config 
= wx
.ConfigBase_Get() 
 927         doViewStuffUpdate 
= config
.ReadInt(self
._configPrefix 
+ "EditorViewWhitespace", False) != self
._viewWhitespaceCheckBox
.GetValue() 
 928         config
.WriteInt(self
._configPrefix 
+ "EditorViewWhitespace", self
._viewWhitespaceCheckBox
.GetValue()) 
 929         doViewStuffUpdate 
= doViewStuffUpdate 
or config
.ReadInt(self
._configPrefix 
+ "EditorViewEOL", False) != self
._viewEOLCheckBox
.GetValue() 
 930         config
.WriteInt(self
._configPrefix 
+ "EditorViewEOL", self
._viewEOLCheckBox
.GetValue()) 
 931         doViewStuffUpdate 
= doViewStuffUpdate 
or config
.ReadInt(self
._configPrefix 
+ "EditorViewIndentationGuides", False) != self
._viewIndentationGuideCheckBox
.GetValue() 
 932         config
.WriteInt(self
._configPrefix 
+ "EditorViewIndentationGuides", self
._viewIndentationGuideCheckBox
.GetValue()) 
 933         doViewStuffUpdate 
= doViewStuffUpdate 
or config
.ReadInt(self
._configPrefix 
+ "EditorViewRightEdge", False) != self
._viewRightEdgeCheckBox
.GetValue() 
 934         config
.WriteInt(self
._configPrefix 
+ "EditorViewRightEdge", self
._viewRightEdgeCheckBox
.GetValue()) 
 935         doViewStuffUpdate 
= doViewStuffUpdate 
or config
.ReadInt(self
._configPrefix 
+ "EditorViewLineNumbers", True) != self
._viewLineNumbersCheckBox
.GetValue() 
 936         config
.WriteInt(self
._configPrefix 
+ "EditorViewLineNumbers", self
._viewLineNumbersCheckBox
.GetValue()) 
 937         if self
._hasWordWrap
: 
 938             doViewStuffUpdate 
= doViewStuffUpdate 
or config
.ReadInt(self
._configPrefix 
+ "EditorWordWrap", False) != self
._wordWrapCheckBox
.GetValue() 
 939             config
.WriteInt(self
._configPrefix 
+ "EditorWordWrap", self
._wordWrapCheckBox
.GetValue()) 
 941             doViewStuffUpdate 
= doViewStuffUpdate 
or not config
.ReadInt(self
._configPrefix 
+ "EditorUseTabs", True) != self
._hasTabsCheckBox
.GetValue() 
 942             config
.WriteInt(self
._configPrefix 
+ "EditorUseTabs", not self
._hasTabsCheckBox
.GetValue()) 
 943             newIndentWidth 
= int(self
._indentWidthChoice
.GetStringSelection()) 
 944             oldIndentWidth 
= config
.ReadInt(self
._configPrefix 
+ "EditorIndentWidth", 4) 
 945             if newIndentWidth 
!= oldIndentWidth
: 
 946                 doViewStuffUpdate 
= True 
 947                 config
.WriteInt(self
._configPrefix 
+ "EditorIndentWidth", newIndentWidth
) 
 948         doFontUpdate 
= self
._originalTextFont 
!= self
._textFont 
or self
._originalTextColor 
!= self
._textColor
 
 949         config
.Write(self
._configPrefix 
+ "EditorFont", self
._textFont
.GetNativeFontInfoDesc()) 
 950         config
.Write(self
._configPrefix 
+ "EditorColor", "%02x%02x%02x" % (self
._textColor
.Red(), self
._textColor
.Green(), self
._textColor
.Blue())) 
 951         if doViewStuffUpdate 
or doFontUpdate
: 
 952             for document 
in optionsDialog
.GetDocManager().GetDocuments(): 
 953                 if issubclass(document
.GetDocumentTemplate().GetDocumentType(), TextDocument
): 
 954                     if doViewStuffUpdate
: 
 955                         document
.UpdateAllViews(hint 
= "ViewStuff") 
 957                         document
.UpdateAllViews(hint 
= "Font") 
 960 class TextCtrl(wx
.stc
.StyledTextCtrl
): 
 962     def __init__(self
, parent
, ID 
= -1, style 
= wx
.NO_FULL_REPAINT_ON_RESIZE
): 
 965         wx
.stc
.StyledTextCtrl
.__init
__(self
, parent
, ID
, style 
= style
) 
 968         self
._fontColor 
= None 
 970         self
.SetVisiblePolicy(wx
.stc
.STC_VISIBLE_STRICT
,1) 
 972         self
.CmdKeyClear(wx
.stc
.STC_KEY_ADD
, wx
.stc
.STC_SCMOD_CTRL
) 
 973         self
.CmdKeyClear(wx
.stc
.STC_KEY_SUBTRACT
, wx
.stc
.STC_SCMOD_CTRL
) 
 974         self
.CmdKeyAssign(wx
.stc
.STC_KEY_PRIOR
, wx
.stc
.STC_SCMOD_CTRL
, wx
.stc
.STC_CMD_ZOOMIN
) 
 975         self
.CmdKeyAssign(wx
.stc
.STC_KEY_NEXT
, wx
.stc
.STC_SCMOD_CTRL
, wx
.stc
.STC_CMD_ZOOMOUT
) 
 976         self
.Bind(wx
.stc
.EVT_STC_ZOOM
, self
.OnUpdateLineNumberMarginWidth
)  # auto update line num width on zoom 
 977         wx
.EVT_KEY_DOWN(self
, self
.OnKeyPressed
) 
 984         self
.SetViewWhiteSpace(False) 
 985         self
.SetEOLMode(wx
.stc
.STC_EOL_LF
) 
 986         self
.SetEdgeMode(wx
.stc
.STC_EDGE_NONE
) 
 987         self
.SetEdgeColumn(78) 
 989         self
.SetMarginType(1, wx
.stc
.STC_MARGIN_NUMBER
) 
 990         self
.SetMarginWidth(1, self
.EstimatedLineNumberMarginWidth()) 
 993         self
.SetCaretForeground("BLACK") 
 995         self
.SetViewDefaults() 
 996         font
, color 
= self
.GetFontAndColorFromConfig() 
 998         self
.SetFontColor(color
) 
 999         self
.MarkerDefineDefault() 
1001         # for multisash initialization 
1002         if isinstance(parent
, wx
.lib
.multisash
.MultiClient
): 
1003             while parent
.GetParent(): 
1004                 parent 
= parent
.GetParent() 
1005                 if hasattr(parent
, "GetView"): 
1007             if hasattr(parent
, "GetView"): 
1008                 textEditor 
= parent
.GetView()._textEditor
 
1010                     doc 
= textEditor
.GetDocPointer() 
1012                         self
.SetDocPointer(doc
) 
1016     def SetViewDefaults(self
, configPrefix 
= "Text", hasWordWrap 
= True, hasTabs 
= False): 
1017         config 
= wx
.ConfigBase_Get() 
1018         self
.SetViewWhiteSpace(config
.ReadInt(configPrefix 
+ "EditorViewWhitespace", False)) 
1019         self
.SetViewEOL(config
.ReadInt(configPrefix 
+ "EditorViewEOL", False)) 
1020         self
.SetIndentationGuides(config
.ReadInt(configPrefix 
+ "EditorViewIndentationGuides", False)) 
1021         self
.SetViewRightEdge(config
.ReadInt(configPrefix 
+ "EditorViewRightEdge", False)) 
1022         self
.SetViewLineNumbers(config
.ReadInt(configPrefix 
+ "EditorViewLineNumbers", True)) 
1024             self
.SetWordWrap(config
.ReadInt(configPrefix 
+ "EditorWordWrap", False)) 
1025         if hasTabs
:  # These methods do not exist in STCTextEditor and are meant for subclasses 
1026             self
.SetUseTabs(config
.ReadInt(configPrefix 
+ "EditorUseTabs", False)) 
1027             self
.SetIndent(config
.ReadInt(configPrefix 
+ "EditorIndentWidth", 4)) 
1028             self
.SetTabWidth(config
.ReadInt(configPrefix 
+ "EditorIndentWidth", 4)) 
1030             self
.SetUseTabs(True) 
1036     def GetDefaultFont(self
): 
1037         """ Subclasses should override this """ 
1038         return wx
.Font(10, wx
.MODERN
, wx
.NORMAL
, wx
.NORMAL
) 
1041     def GetDefaultColor(self
): 
1042         """ Subclasses should override this """ 
1046     def GetFontAndColorFromConfig(self
, configPrefix 
= "Text"): 
1047         font 
= self
.GetDefaultFont() 
1048         config 
= wx
.ConfigBase_Get() 
1049         fontData 
= config
.Read(configPrefix 
+ "EditorFont", "") 
1051             nativeFont 
= wx
.NativeFontInfo() 
1052             nativeFont
.FromString(fontData
) 
1053             font
.SetNativeFontInfo(nativeFont
) 
1054         color 
= self
.GetDefaultColor() 
1055         colorData 
= config
.Read(configPrefix 
+ "EditorColor", "") 
1057             red 
= int("0x" + colorData
[0:2], 16) 
1058             green 
= int("0x" + colorData
[2:4], 16) 
1059             blue 
= int("0x" + colorData
[4:6], 16) 
1060             color 
= wx
.Color(red
, green
, blue
) 
1067     def SetFont(self
, font
): 
1069         self
.StyleSetFont(wx
.stc
.STC_STYLE_DEFAULT
, self
._font
) 
1072     def GetFontColor(self
): 
1073         return self
._fontColor
 
1076     def SetFontColor(self
, fontColor 
= wx
.BLACK
): 
1077         self
._fontColor 
= fontColor
 
1078         self
.StyleSetForeground(wx
.stc
.STC_STYLE_DEFAULT
, "#%02x%02x%02x" % (self
._fontColor
.Red(), self
._fontColor
.Green(), self
._fontColor
.Blue())) 
1081     def UpdateStyles(self
): 
1082         self
.StyleClearAll() 
1086     def EstimatedLineNumberMarginWidth(self
): 
1089         lineNum 
= self
.GetLineCount() 
1090         lineNum 
= lineNum
/100 
1091         while lineNum 
>= 10: 
1092             lineNum 
= lineNum
/10 
1093             baseNumbers 
= baseNumbers 
+ "0" 
1095         return self
.TextWidth(wx
.stc
.STC_STYLE_LINENUMBER
, baseNumbers
) + MARGIN
 
1098     def OnUpdateLineNumberMarginWidth(self
, event
): 
1099         self
.UpdateLineNumberMarginWidth() 
1102     def UpdateLineNumberMarginWidth(self
): 
1103         if self
.GetViewLineNumbers(): 
1104             self
.SetMarginWidth(1, self
.EstimatedLineNumberMarginWidth()) 
1106     def MarkerDefineDefault(self
): 
1107         """ This must be called after the textcontrol is instantiated """ 
1108         self
.MarkerDefine(TextView
.MARKER_NUM
, wx
.stc
.STC_MARK_ROUNDRECT
, wx
.BLACK
, wx
.BLUE
) 
1112         # Used when Delete key is hit. 
1113         sel 
= self
.GetSelection() 
1115         # Delete the selection or if no selection, the character after the caret. 
1116         if sel
[0] == sel
[1]: 
1117             self
.SetSelection(sel
[0], sel
[0] + 1) 
1119             # remove any folded lines also. 
1120             startLine 
= self
.LineFromPosition(sel
[0]) 
1121             endLine 
= self
.LineFromPosition(sel
[1]) 
1122             endLineStart 
= self
.PositionFromLine(endLine
) 
1123             if startLine 
!= endLine 
and sel
[1] - endLineStart 
== 0: 
1124                 while not self
.GetLineVisible(endLine
): 
1126                 self
.SetSelectionEnd(self
.PositionFromLine(endLine
)) 
1132         # replace any folded lines also. 
1133         sel 
= self
.GetSelection() 
1134         startLine 
= self
.LineFromPosition(sel
[0]) 
1135         endLine 
= self
.LineFromPosition(sel
[1]) 
1136         endLineStart 
= self
.PositionFromLine(endLine
) 
1137         if startLine 
!= endLine 
and sel
[1] - endLineStart 
== 0: 
1138             while not self
.GetLineVisible(endLine
): 
1140             self
.SetSelectionEnd(self
.PositionFromLine(endLine
)) 
1145     def OnKeyPressed(self
, event
): 
1146         key 
= event
.GetKeyCode() 
1147         if key 
== wx
.WXK_NUMPAD_ADD
:  #wxBug: For whatever reason, the key accelerators for numpad add and subtract with modifiers are not working so have to trap them here 
1148             if event
.ControlDown(): 
1149                 self
.ToggleFoldAll(expand 
= True, topLevelOnly 
= True) 
1150             elif event
.ShiftDown(): 
1151                 self
.ToggleFoldAll(expand 
= True) 
1153                 self
.ToggleFold(self
.GetCurrentLine()) 
1154         elif key 
== wx
.WXK_NUMPAD_SUBTRACT
: 
1155             if event
.ControlDown(): 
1156                 self
.ToggleFoldAll(expand 
= False, topLevelOnly 
= True) 
1157             elif event
.ShiftDown(): 
1158                 self
.ToggleFoldAll(expand 
= False) 
1160                 self
.ToggleFold(self
.GetCurrentLine()) 
1165     #---------------------------------------------------------------------------- 
1167     #---------------------------------------------------------------------------- 
1169     def GetViewRightEdge(self
): 
1170         return self
.GetEdgeMode() != wx
.stc
.STC_EDGE_NONE
 
1173     def SetViewRightEdge(self
, viewRightEdge
): 
1175             self
.SetEdgeMode(wx
.stc
.STC_EDGE_LINE
) 
1177             self
.SetEdgeMode(wx
.stc
.STC_EDGE_NONE
) 
1180     def GetViewLineNumbers(self
): 
1181         return self
.GetMarginWidth(1) > 0 
1184     def SetViewLineNumbers(self
, viewLineNumbers 
= True): 
1186             self
.SetMarginWidth(1, self
.EstimatedLineNumberMarginWidth()) 
1188             self
.SetMarginWidth(1, 0) 
1191     def CanWordWrap(self
): 
1195     def GetWordWrap(self
): 
1196         return self
.GetWrapMode() == wx
.stc
.STC_WRAP_WORD
 
1199     def SetWordWrap(self
, wordWrap
): 
1201             self
.SetWrapMode(wx
.stc
.STC_WRAP_WORD
) 
1203             self
.SetWrapMode(wx
.stc
.STC_WRAP_NONE
) 
1206 #---------------------------------------------------------------------------- 
1207 # Icon Bitmaps - generated by encode_bitmaps.py 
1208 #---------------------------------------------------------------------------- 
1209 from wx 
import ImageFromStream
, BitmapFromImage
 
1215 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ 
1216 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ 
1217 \x00\x00`IDAT8\x8d\xed\x931\x0e\xc00\x08\x03m\x92\xff\xff8q\xa7JU!$\x12\x1d\ 
1218 \xeb\t\t8n\x81\xb4\x86J\xfa]h\x0ee\x83\xb4\xc6\x14\x00\x00R\xcc \t\xcd\xa1\ 
1219 \x08\xd2\xa3\xe1\x08*\t$\x1d\xc4\x012\x0b\x00\xce\xe4\xc8\xe0\t}\xf7\x8f\rV\ 
1220 \xd9\x1a\xec\xe0\xbf\xc1\xd7\x06\xd9\xf5UX\xfdF+m\x03\xb8\x00\xe4\xc74B"x\ 
1221 \xf1\xf4\x00\x00\x00\x00IEND\xaeB`\x82'  
1224 def getTextBitmap(): 
1225     return BitmapFromImage(getTextImage()) 
1228     stream 
= cStringIO
.StringIO(getTextData()) 
1229     return ImageFromStream(stream
) 
1232     return wx
.IconFromBitmap(getTextBitmap()) 
1235 #---------------------------------------------------------------------------- 
1236 # Menu Bitmaps - generated by encode_bitmaps.py 
1237 #---------------------------------------------------------------------------- 
1238 #---------------------------------------------------------------------- 
1239 def getZoomInData(): 
1241 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ 
1242 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ 
1243 \x00\x00wIDAT8\x8d\xa5\x93Q\x12\x80 \x08D\xb5\xe9X\xee\xe9\xb7{\xd5Gc\xa9\ 
1244 \xacX\xca\x1f\xa0\x8fE0\x92<\xc3\x82\xed*\x08\xa0\xf2I~\x07\x000\x17T,\xdb\ 
1245 \xd6;\x08\xa4\x00\xa4GA\xab\xca\x00\xbc*\x1eD\xb4\x90\xa4O\x1e\xe3\x16f\xcc(\ 
1246 \xc8\x95F\x95\x8d\x02\xef\xa1n\xa0\xce\xc5v\x91zc\xacU\xbey\x03\xf0.\xa8\xb8\ 
1247 \x04\x8c\xac\x04MM\xa1lA\xfe\x85?\x90\xe5=X\x06\\\xebCA\xb3Q\xf34\x14\x00\ 
1248 \x00\x00\x00IEND\xaeB`\x82'  
1250 def getZoomInBitmap(): 
1251     return BitmapFromImage(getZoomInImage()) 
1253 def getZoomInImage(): 
1254     stream 
= cStringIO
.StringIO(getZoomInData()) 
1255     return ImageFromStream(stream
) 
1257 #---------------------------------------------------------------------- 
1258 def getZoomOutData(): 
1260 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ 
1261 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ 
1262 \x00\x00qIDAT8\x8d\xa5\x92Q\x0e\xc0 \x08C-z\xff\x13O\xd9\xd7\x16"\x05\x8d\ 
1263 \xf6O\xa2\x8f"\x05\xa4\x96\x1b5V\xd4\xd1\xd5\x9e!\x15\xdb\x00\x1d]\xe7\x07\ 
1264 \xac\xf6Iv.B*fW\x0e\x90u\xc9 d\x84\x87v\x82\xb4\xf5\x08\'r\x0e\xa2N\x91~\x07\ 
1265 \xd9G\x95\xe2W\xeb\x00\x19\xc4\xd6\\FX\x12\xa3 \xb1:\x05\xacdAG[\xb0y9r`u\ 
1266 \x9d\x83k\xc0\x0b#3@0A\x0c"\x93\x00\x00\x00\x00IEND\xaeB`\x82'  
1269 def getZoomOutBitmap(): 
1270     return BitmapFromImage(getZoomOutImage()) 
1272 def getZoomOutImage(): 
1273     stream 
= cStringIO
.StringIO(getZoomOutData()) 
1274     return ImageFromStream(stream
)