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-2006 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
): 
  51         wx
.lib
.docview
.Document 
.__init
__(self
) 
  52         self
._inModify 
= False 
  55     def SaveObject(self
, fileObject
): 
  56         view 
= self
.GetFirstView() 
  57         fileObject
.write(view
.GetValue()) 
  62     def LoadObject(self
, fileObject
): 
  63         view 
= self
.GetFirstView() 
  64         data 
= fileObject
.read() 
  71         view 
= self
.GetFirstView() 
  73             return view
.IsModified() 
  77     def Modify(self
, modify
): 
  82         view 
= self
.GetFirstView() 
  83         if not modify 
and view
: 
  86         wx
.lib
.docview
.Document
.Modify(self
, modify
)  # this must called be after the SetModifyFalse call above. 
  88         self
._inModify 
= False 
  91     def OnCreateCommandProcessor(self
): 
  92         # Don't create a command processor, it has its own 
  96 # Use this to override MultiClient.Select to prevent yellow background.   
  97 def MultiClientSelectBGNotYellow(a
):      
  98     a
.GetParent().multiView
.UnSelect()    
 100     #a.SetBackgroundColour(wx.Colour(255,255,0)) # Yellow         
 103 class TextView(wx
.lib
.docview
.View
): 
 107     #---------------------------------------------------------------------------- 
 109     #---------------------------------------------------------------------------- 
 112         wx
.lib
.docview
.View
.__init
__(self
) 
 113         self
._textEditor 
= None 
 114         self
._markerCount 
= 0 
 115         self
._commandProcessor 
= None 
 119     def GetCtrlClass(self
): 
 120         """ Used in split window to instantiate new instances """ 
 125         if wx
.Platform 
== "__WXMAC__": 
 126             # look for active one first   
 127             self
._textEditor 
= self
._GetActiveCtrl
(self
._dynSash
)         
 128             if self
._textEditor 
== None:  # it is possible none are active        
 129                 # look for any existing one       
 130                 self
._textEditor 
= self
._FindCtrl
(self
._dynSash
) 
 131         return self
._textEditor
 
 134     def SetCtrl(self
, ctrl
): 
 135         self
._textEditor 
= ctrl
 
 138     def OnCreatePrintout(self
): 
 139         """ for Print Preview and Print """ 
 140         return TextPrintout(self
, self
.GetDocument().GetPrintableName()) 
 143     def OnCreate(self
, doc
, flags
): 
 144         frame 
= wx
.GetApp().CreateDocumentFrame(self
, doc
, flags
, style 
= wx
.DEFAULT_FRAME_STYLE | wx
.NO_FULL_REPAINT_ON_RESIZE
) 
 145         # wxBug: DynamicSashWindow doesn't work on Mac, so revert to 
 146         # multisash implementation 
 147         if wx
.Platform 
== "__WXMAC__": 
 148             wx
.lib
.multisash
.MultiClient
.Select 
= MultiClientSelectBGNotYellow
 
 149             self
._dynSash 
= wx
.lib
.multisash
.MultiSash(frame
, -1) 
 150             self
._dynSash
.SetDefaultChildClass(self
.GetCtrlClass()) # wxBug:  MultiSash instantiates the first TextCtrl with this call 
 152             self
._textEditor 
= self
.GetCtrl()  # wxBug: grab the TextCtrl from the MultiSash datastructure 
 154             self
._dynSash 
= wx
.gizmos
.DynamicSashWindow(frame
, -1, style
=wx
.CLIP_CHILDREN
) 
 155             self
._dynSash
._view 
= self
 
 156             self
._textEditor 
= self
.GetCtrlClass()(self
._dynSash
, -1, style
=wx
.NO_BORDER
) 
 157         wx
.EVT_LEFT_DOWN(self
._textEditor
, self
.OnLeftClick
) 
 158         self
._textEditor
.Bind(wx
.stc
.EVT_STC_MODIFIED
, self
.OnModify
) 
 160         self
._CreateSizer
(frame
) 
 167     def OnModify(self
, event
): 
 168         self
.GetDocument().Modify(self
._textEditor
.GetModify()) 
 171     def _CreateSizer(self
, frame
): 
 172         sizer 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
 173         sizer
.Add(self
._dynSash
, 1, wx
.EXPAND
) 
 174         frame
.SetSizer(sizer
) 
 177     def OnLeftClick(self
, event
): 
 182     def OnUpdate(self
, sender 
= None, hint 
= None): 
 183         if wx
.lib
.docview
.View
.OnUpdate(self
, sender
, hint
): 
 186         if hint 
== "ViewStuff": 
 187             self
.GetCtrl().SetViewDefaults() 
 189             font
, color 
= self
.GetCtrl().GetFontAndColorFromConfig() 
 190             self
.GetCtrl().SetFont(font
) 
 191             self
.GetCtrl().SetFontColor(color
) 
 194     def OnActivateView(self
, activate
, activeView
, deactiveView
): 
 195         if activate 
and self
.GetCtrl(): 
 196             # In MDI mode just calling set focus doesn't work and in SDI mode using CallAfter causes an endless loop 
 197             if self
.GetDocumentManager().GetFlags() & wx
.lib
.docview
.DOC_SDI
: 
 200                 wx
.CallAfter(self
.SetFocus
) 
 205             self
.GetCtrl().SetFocus() 
 208     def OnClose(self
, deleteWindow 
= True): 
 209         if not wx
.lib
.docview
.View
.OnClose(self
, deleteWindow
): 
 212         if deleteWindow 
and self
.GetFrame(): 
 213             self
.GetFrame().Destroy() 
 217     def ProcessEvent(self
, event
):         
 220             self
.GetCtrl().Undo() 
 222         elif id == wx
.ID_REDO
: 
 223             self
.GetCtrl().Redo() 
 225         elif id == wx
.ID_CUT
: 
 228         elif id == wx
.ID_COPY
: 
 229             self
.GetCtrl().Copy() 
 231         elif id == wx
.ID_PASTE
: 
 232             self
.GetCtrl().OnPaste() 
 234         elif id == wx
.ID_CLEAR
: 
 235             self
.GetCtrl().OnClear() 
 237         elif id == wx
.ID_SELECTALL
: 
 238             self
.GetCtrl().SetSelection(0, -1) 
 240         elif id == VIEW_WHITESPACE_ID
: 
 241             self
.GetCtrl().SetViewWhiteSpace(not self
.GetCtrl().GetViewWhiteSpace()) 
 243         elif id == VIEW_EOL_ID
: 
 244             self
.GetCtrl().SetViewEOL(not self
.GetCtrl().GetViewEOL()) 
 246         elif id == VIEW_INDENTATION_GUIDES_ID
: 
 247             self
.GetCtrl().SetIndentationGuides(not self
.GetCtrl().GetIndentationGuides()) 
 249         elif id == VIEW_RIGHT_EDGE_ID
: 
 250             self
.GetCtrl().SetViewRightEdge(not self
.GetCtrl().GetViewRightEdge()) 
 252         elif id == VIEW_LINE_NUMBERS_ID
: 
 253             self
.GetCtrl().SetViewLineNumbers(not self
.GetCtrl().GetViewLineNumbers()) 
 255         elif id == ZOOM_NORMAL_ID
: 
 256             self
.GetCtrl().SetZoom(0) 
 258         elif id == ZOOM_IN_ID
: 
 259             self
.GetCtrl().CmdKeyExecute(wx
.stc
.STC_CMD_ZOOMIN
) 
 261         elif id == ZOOM_OUT_ID
: 
 262             self
.GetCtrl().CmdKeyExecute(wx
.stc
.STC_CMD_ZOOMOUT
) 
 264         elif id == CHOOSE_FONT_ID
: 
 267         elif id == WORD_WRAP_ID
: 
 268             self
.GetCtrl().SetWordWrap(not self
.GetCtrl().GetWordWrap()) 
 270         elif id == FindService
.FindService
.FIND_ID
: 
 273         elif id == FindService
.FindService
.FIND_PREVIOUS_ID
: 
 274             self
.DoFind(forceFindPrevious 
= True) 
 276         elif id == FindService
.FindService
.FIND_NEXT_ID
: 
 277             self
.DoFind(forceFindNext 
= True) 
 279         elif id == FindService
.FindService
.REPLACE_ID
: 
 280             self
.OnFind(replace 
= True) 
 282         elif id == FindService
.FindService
.FINDONE_ID
: 
 285         elif id == FindService
.FindService
.REPLACEONE_ID
: 
 286             self
.DoFind(replace 
= True) 
 288         elif id == FindService
.FindService
.REPLACEALL_ID
: 
 289             self
.DoFind(replaceAll 
= True) 
 291         elif id == FindService
.FindService
.GOTO_LINE_ID
: 
 292             self
.OnGotoLine(event
) 
 295             return wx
.lib
.docview
.View
.ProcessEvent(self
, event
) 
 298     def ProcessUpdateUIEvent(self
, event
): 
 299         if not self
.GetCtrl(): 
 304             event
.Enable(self
.GetCtrl().CanUndo()) 
 305             event
.SetText(_("&Undo\tCtrl+Z"))  # replace menu string 
 307         elif id == wx
.ID_REDO
: 
 308             event
.Enable(self
.GetCtrl().CanRedo()) 
 309             event
.SetText(_("&Redo\tCtrl+Y"))  # replace menu string 
 311         elif (id == wx
.ID_CUT
 
 313         or id == wx
.ID_CLEAR
): 
 314             hasSelection 
= self
.GetCtrl().GetSelectionStart() != self
.GetCtrl().GetSelectionEnd() 
 315             event
.Enable(hasSelection
) 
 317         elif id == wx
.ID_PASTE
: 
 318             event
.Enable(self
.GetCtrl().CanPaste()) 
 320         elif id == wx
.ID_SELECTALL
: 
 321             hasText 
= self
.GetCtrl().GetTextLength() > 0 
 322             event
.Enable(hasText
) 
 327         elif id == VIEW_WHITESPACE_ID
: 
 328             hasText 
= self
.GetCtrl().GetTextLength() > 0 
 329             event
.Enable(hasText
) 
 330             event
.Check(self
.GetCtrl().GetViewWhiteSpace()) 
 332         elif id == VIEW_EOL_ID
: 
 333             hasText 
= self
.GetCtrl().GetTextLength() > 0 
 334             event
.Enable(hasText
) 
 335             event
.Check(self
.GetCtrl().GetViewEOL()) 
 337         elif id == VIEW_INDENTATION_GUIDES_ID
: 
 338             hasText 
= self
.GetCtrl().GetTextLength() > 0 
 339             event
.Enable(hasText
) 
 340             event
.Check(self
.GetCtrl().GetIndentationGuides()) 
 342         elif id == VIEW_RIGHT_EDGE_ID
: 
 343             hasText 
= self
.GetCtrl().GetTextLength() > 0 
 344             event
.Enable(hasText
) 
 345             event
.Check(self
.GetCtrl().GetViewRightEdge()) 
 347         elif id == VIEW_LINE_NUMBERS_ID
: 
 348             hasText 
= self
.GetCtrl().GetTextLength() > 0 
 349             event
.Enable(hasText
) 
 350             event
.Check(self
.GetCtrl().GetViewLineNumbers()) 
 355         elif id == ZOOM_NORMAL_ID
: 
 356             event
.Enable(self
.GetCtrl().GetZoom() != 0) 
 358         elif id == ZOOM_IN_ID
: 
 359             event
.Enable(self
.GetCtrl().GetZoom() < 20) 
 361         elif id == ZOOM_OUT_ID
: 
 362             event
.Enable(self
.GetCtrl().GetZoom() > -10) 
 364         elif id == CHOOSE_FONT_ID
: 
 367         elif id == WORD_WRAP_ID
: 
 368             event
.Enable(self
.GetCtrl().CanWordWrap()) 
 369             event
.Check(self
.GetCtrl().CanWordWrap() and self
.GetCtrl().GetWordWrap()) 
 371         elif id == FindService
.FindService
.FIND_ID
: 
 372             hasText 
= self
.GetCtrl().GetTextLength() > 0 
 373             event
.Enable(hasText
) 
 375         elif id == FindService
.FindService
.FIND_PREVIOUS_ID
: 
 376             hasText 
= self
.GetCtrl().GetTextLength() > 0 
 377             event
.Enable(hasText 
and 
 378                          self
._FindServiceHasString
() and 
 379                          self
.GetCtrl().GetSelection()[0] > 0) 
 381         elif id == FindService
.FindService
.FIND_NEXT_ID
: 
 382             hasText 
= self
.GetCtrl().GetTextLength() > 0 
 383             event
.Enable(hasText 
and 
 384                          self
._FindServiceHasString
() and 
 385                          self
.GetCtrl().GetSelection()[0] < self
.GetCtrl().GetLength()) 
 387         elif id == FindService
.FindService
.REPLACE_ID
: 
 388             hasText 
= self
.GetCtrl().GetTextLength() > 0 
 389             event
.Enable(hasText
) 
 391         elif id == FindService
.FindService
.GOTO_LINE_ID
: 
 394         elif id == TEXT_STATUS_BAR_ID
: 
 395             self
.OnUpdateStatusBar(event
) 
 398             return wx
.lib
.docview
.View
.ProcessUpdateUIEvent(self
, event
) 
 401     def _GetParentFrame(self
): 
 402         return wx
.GetTopLevelParent(self
.GetFrame()) 
 404     def _GetActiveCtrl(self
, parent
):     
 405         """ Walk through the MultiSash windows and find the active Control """    
 406         if isinstance(parent
, wx
.lib
.multisash
.MultiClient
) and parent
.selected
:          
 408         if hasattr(parent
, "GetChildren"):        
 409             for child 
in parent
.GetChildren():    
 410                 found 
= self
._GetActiveCtrl
(child
)        
 416     def _FindCtrl(self
, parent
):          
 417         """ Walk through the MultiSash windows and find the first TextCtrl """    
 418         if isinstance(parent
, self
.GetCtrlClass()):       
 420         if hasattr(parent
, "GetChildren"):        
 421             for child 
in parent
.GetChildren():    
 422                 found 
= self
._FindCtrl
(child
)     
 428     #---------------------------------------------------------------------------- 
 429     # Methods for TextDocument to call 
 430     #---------------------------------------------------------------------------- 
 432     def IsModified(self
): 
 433         if not self
.GetCtrl(): 
 435         return self
.GetCtrl().GetModify() 
 438     def SetModifyFalse(self
): 
 439         self
.GetCtrl().SetSavePoint() 
 444             return self
.GetCtrl().GetText() 
 449     def SetValue(self
, value
): 
 450         self
.GetCtrl().SetText(value
) 
 451         self
.GetCtrl().UpdateLineNumberMarginWidth() 
 452         self
.GetCtrl().EmptyUndoBuffer() 
 455     #---------------------------------------------------------------------------- 
 457     #---------------------------------------------------------------------------- 
 459     def OnUpdateStatusBar(self
, event
): 
 460         statusBar 
= self
._GetParentFrame
().GetStatusBar() 
 461         statusBar
.SetInsertMode(self
.GetCtrl().GetOvertype() == 0) 
 462         statusBar
.SetLineNumber(self
.GetCtrl().GetCurrentLine() + 1) 
 463         statusBar
.SetColumnNumber(self
.GetCtrl().GetColumn(self
.GetCtrl().GetCurrentPos()) + 1) 
 466     #---------------------------------------------------------------------------- 
 468     #---------------------------------------------------------------------------- 
 470     def OnChooseFont(self
): 
 472         data
.EnableEffects(True) 
 473         data
.SetInitialFont(self
.GetCtrl().GetFont()) 
 474         data
.SetColour(self
.GetCtrl().GetFontColor()) 
 475         fontDialog 
= wx
.FontDialog(self
.GetFrame(), data
) 
 476         fontDialog
.CenterOnParent() 
 477         if fontDialog
.ShowModal() == wx
.ID_OK
: 
 478             data 
= fontDialog
.GetFontData() 
 479             self
.GetCtrl().SetFont(data
.GetChosenFont()) 
 480             self
.GetCtrl().SetFontColor(data
.GetColour()) 
 481             self
.GetCtrl().UpdateStyles() 
 485     #---------------------------------------------------------------------------- 
 487     #---------------------------------------------------------------------------- 
 489     def OnFind(self
, replace 
= False): 
 490         findService 
= wx
.GetApp().GetService(FindService
.FindService
) 
 492             findService
.ShowFindReplaceDialog(findString 
= self
.GetCtrl().GetSelectedText(), replace 
= replace
) 
 495     def DoFind(self
, forceFindNext 
= False, forceFindPrevious 
= False, replace 
= False, replaceAll 
= False): 
 496         findService 
= wx
.GetApp().GetService(FindService
.FindService
) 
 499         findString 
= findService
.GetFindString() 
 500         if len(findString
) == 0: 
 502         replaceString 
= findService
.GetReplaceString() 
 503         flags 
= findService
.GetFlags() 
 504         startLoc
, endLoc 
= self
.GetCtrl().GetSelection() 
 506         wholeWord 
= flags 
& wx
.FR_WHOLEWORD 
> 0 
 507         matchCase 
= flags 
& wx
.FR_MATCHCASE 
> 0 
 508         regExp 
= flags 
& FindService
.FindService
.FR_REGEXP 
> 0 
 509         down 
= flags 
& wx
.FR_DOWN 
> 0 
 510         wrap 
= flags 
& FindService
.FindService
.FR_WRAP 
> 0 
 512         if forceFindPrevious
:   # this is from function keys, not dialog box 
 514             wrap 
= False        # user would want to know they're at the end of file 
 517             wrap 
= False        # user would want to know they're at the end of file 
 521         # On replace dialog operations, user is allowed to replace the currently highlighted text to determine if it should be replaced or not. 
 522         # 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. 
 523         # If the text is a match, then replace it. 
 525             result
, start
, end
, replText 
= findService
.DoFind(findString
, replaceString
, self
.GetCtrl().GetSelectedText(), 0, 0, True, matchCase
, wholeWord
, regExp
, replace
) 
 527                 self
.GetCtrl().ReplaceSelection(replText
) 
 528                 self
.GetDocument().Modify(True) 
 529                 wx
.GetApp().GetTopWindow().PushStatusText(_("1 occurrence of \"%s\" replaced") % findString
) 
 531                     startLoc 
+= len(replText
)  # advance start location past replacement string to new text 
 533             elif result 
== FindService
.FIND_SYNTAXERROR
: 
 535                 wx
.GetApp().GetTopWindow().PushStatusText(_("Invalid regular expression \"%s\"") % findString
) 
 538             text 
= self
.GetCtrl().GetText() 
 540             # Find the next matching text occurance or if it is a ReplaceAll, replace all occurances 
 541             # 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 
 542             result
, start
, end
, text 
= findService
.DoFind(findString
, replaceString
, text
, startLoc
, endLoc
, down
, matchCase
, wholeWord
, regExp
, False, replaceAll
, wrap
) 
 544                 self
.GetCtrl().SetTargetStart(0) 
 545                 self
.GetCtrl().SetTargetEnd(self
.GetCtrl().GetLength()) 
 546                 self
.GetCtrl().ReplaceTarget(text
)  # Doing a SetText causes a clear document to be shown when undoing, so using replacetarget instead 
 547                 self
.GetDocument().Modify(True) 
 549                     wx
.GetApp().GetTopWindow().PushStatusText(_("1 occurrence of \"%s\" replaced") % findString
) 
 551                     wx
.GetApp().GetTopWindow().PushStatusText(_("%i occurrences of \"%s\" replaced") % (result
, findString
)) 
 553                 self
.GetCtrl().SetSelection(start
, end
) 
 554                 self
.GetCtrl().EnsureVisible(self
.GetCtrl().LineFromPosition(end
))  # show bottom then scroll up to top 
 555                 self
.GetCtrl().EnsureVisible(self
.GetCtrl().LineFromPosition(start
)) # do this after ensuring bottom is visible 
 556                 wx
.GetApp().GetTopWindow().PushStatusText(_("Found \"%s\".") % findString
) 
 557             elif result 
== FindService
.FIND_SYNTAXERROR
: 
 558                 # Dialog for this case gets popped up by the FindService. 
 559                 wx
.GetApp().GetTopWindow().PushStatusText(_("Invalid regular expression \"%s\"") % findString
) 
 561                 wx
.MessageBox(_("Can't find \"%s\".") % findString
, "Find", 
 562                           wx
.OK | wx
.ICON_INFORMATION
) 
 565     def _FindServiceHasString(self
): 
 566         findService 
= wx
.GetApp().GetService(FindService
.FindService
) 
 567         if not findService 
or not findService
.GetFindString(): 
 572     def OnGotoLine(self
, event
): 
 573         findService 
= wx
.GetApp().GetService(FindService
.FindService
) 
 575             line 
= findService
.GetLineNumber(self
.GetDocumentManager().FindSuitableParent()) 
 578                 self
.GetCtrl().EnsureVisible(line
) 
 579                 self
.GetCtrl().GotoLine(line
) 
 582     def GotoLine(self
, lineNum
): 
 584             lineNum 
= lineNum 
- 1  # line numbering for editor is 0 based, we are 1 based. 
 585             self
.GetCtrl().EnsureVisibleEnforcePolicy(lineNum
) 
 586             self
.GetCtrl().GotoLine(lineNum
) 
 589     def SetSelection(self
, start
, end
): 
 590         self
.GetCtrl().SetSelection(start
, end
) 
 593     def EnsureVisible(self
, line
): 
 594         self
.GetCtrl().EnsureVisible(line
-1)  # line numbering for editor is 0 based, we are 1 based. 
 597     def EnsureVisibleEnforcePolicy(self
, line
): 
 598         self
.GetCtrl().EnsureVisibleEnforcePolicy(line
-1)  # line numbering for editor is 0 based, we are 1 based. 
 601     def LineFromPosition(self
, pos
): 
 602         return self
.GetCtrl().LineFromPosition(pos
)+1  # line numbering for editor is 0 based, we are 1 based. 
 605     def PositionFromLine(self
, line
): 
 606         return self
.GetCtrl().PositionFromLine(line
-1)  # line numbering for editor is 0 based, we are 1 based. 
 609     def GetLineEndPosition(self
, line
): 
 610         return self
.GetCtrl().GetLineEndPosition(line
-1)  # line numbering for editor is 0 based, we are 1 based. 
 613     def GetLine(self
, lineNum
): 
 614         return self
.GetCtrl().GetLine(lineNum
-1)  # line numbering for editor is 0 based, we are 1 based. 
 617     def MarkerDefine(self
): 
 618         """ This must be called after the texteditor is instantiated """ 
 619         self
.GetCtrl().MarkerDefine(TextView
.MARKER_NUM
, wx
.stc
.STC_MARK_CIRCLE
, wx
.BLACK
, wx
.BLUE
) 
 622     def MarkerToggle(self
, lineNum 
= -1, marker_index
=MARKER_NUM
, mask
=MARKER_MASK
): 
 624             lineNum 
= self
.GetCtrl().GetCurrentLine() 
 625         if self
.GetCtrl().MarkerGet(lineNum
) & mask
: 
 626             self
.GetCtrl().MarkerDelete(lineNum
, marker_index
) 
 627             self
._markerCount 
-= 1 
 629             self
.GetCtrl().MarkerAdd(lineNum
, marker_index
) 
 630             self
._markerCount 
+= 1 
 633     def MarkerAdd(self
, lineNum 
= -1, marker_index
=MARKER_NUM
, mask
=MARKER_MASK
): 
 635             lineNum 
= self
.GetCtrl().GetCurrentLine() 
 636         self
.GetCtrl().MarkerAdd(lineNum
, marker_index
) 
 637         self
._markerCount 
+= 1 
 640     def MarkerDelete(self
, lineNum 
= -1, marker_index
=MARKER_NUM
, mask
=MARKER_MASK
): 
 642             lineNum 
= self
.GetCtrl().GetCurrentLine() 
 643         if self
.GetCtrl().MarkerGet(lineNum
) & mask
: 
 644             self
.GetCtrl().MarkerDelete(lineNum
, marker_index
) 
 645             self
._markerCount 
-= 1 
 647     def MarkerDeleteAll(self
, marker_num
=MARKER_NUM
): 
 648         self
.GetCtrl().MarkerDeleteAll(marker_num
) 
 649         if marker_num 
== self
.MARKER_NUM
: 
 650             self
._markerCount 
= 0 
 653     def MarkerNext(self
, lineNum 
= -1): 
 655             lineNum 
= self
.GetCtrl().GetCurrentLine() + 1  # start search below current line 
 656         foundLine 
= self
.GetCtrl().MarkerNext(lineNum
, self
.MARKER_MASK
) 
 658             # wrap to top of file 
 659             foundLine 
= self
.GetCtrl().MarkerNext(0, self
.MARKER_MASK
) 
 661                 wx
.GetApp().GetTopWindow().PushStatusText(_("No markers")) 
 664         self
.GotoLine(foundLine 
+ 1) 
 667     def MarkerPrevious(self
, lineNum 
= -1): 
 669             lineNum 
= self
.GetCtrl().GetCurrentLine() - 1  # start search above current line 
 671                 lineNum 
= self
.GetCtrl().GetLineCount() 
 673         foundLine 
= self
.GetCtrl().MarkerPrevious(lineNum
, self
.MARKER_MASK
) 
 675             # wrap to bottom of file 
 676             foundLine 
= self
.GetCtrl().MarkerPrevious(self
.GetCtrl().GetLineCount(), self
.MARKER_MASK
) 
 678                 wx
.GetApp().GetTopWindow().PushStatusText(_("No markers")) 
 681         self
.GotoLine(foundLine 
+ 1) 
 684     def MarkerExists(self
, lineNum 
= -1, mask
=MARKER_MASK
): 
 686             lineNum 
= self
.GetCtrl().GetCurrentLine() 
 687         if self
.GetCtrl().MarkerGet(lineNum
) & mask
: 
 692     def GetMarkerLines(self
, mask
=MARKER_MASK
): 
 694         for lineNum 
in range(self
.GetCtrl().GetLineCount()): 
 695             if self
.GetCtrl().MarkerGet(lineNum
) & mask
: 
 696                 retval
.append(lineNum
) 
 699     def GetMarkerCount(self
): 
 700         return self
._markerCount
 
 703 class TextService(wx
.lib
.pydocview
.DocService
): 
 707         wx
.lib
.pydocview
.DocService
.__init
__(self
) 
 710     def InstallControls(self
, frame
, menuBar 
= None, toolBar 
= None, statusBar 
= None, document 
= None): 
 711         if document 
and document
.GetDocumentTemplate().GetDocumentType() != TextDocument
: 
 713         if not document 
and wx
.GetApp().GetDocumentManager().GetFlags() & wx
.lib
.docview
.DOC_SDI
: 
 716         statusBar 
= TextStatusBar(frame
, TEXT_STATUS_BAR_ID
) 
 717         frame
.SetStatusBar(statusBar
) 
 718         wx
.EVT_UPDATE_UI(frame
, TEXT_STATUS_BAR_ID
, frame
.ProcessUpdateUIEvent
) 
 720         viewMenu 
= menuBar
.GetMenu(menuBar
.FindMenu(_("&View"))) 
 722         viewMenu
.AppendSeparator() 
 724         textMenu
.AppendCheckItem(VIEW_WHITESPACE_ID
, _("&Whitespace"), _("Shows or hides whitespace")) 
 725         wx
.EVT_MENU(frame
, VIEW_WHITESPACE_ID
, frame
.ProcessEvent
) 
 726         wx
.EVT_UPDATE_UI(frame
, VIEW_WHITESPACE_ID
, frame
.ProcessUpdateUIEvent
) 
 727         textMenu
.AppendCheckItem(VIEW_EOL_ID
, _("&End of Line Markers"), _("Shows or hides indicators at the end of each line")) 
 728         wx
.EVT_MENU(frame
, VIEW_EOL_ID
, frame
.ProcessEvent
) 
 729         wx
.EVT_UPDATE_UI(frame
, VIEW_EOL_ID
, frame
.ProcessUpdateUIEvent
) 
 730         textMenu
.AppendCheckItem(VIEW_INDENTATION_GUIDES_ID
, _("&Indentation Guides"), _("Shows or hides indentations")) 
 731         wx
.EVT_MENU(frame
, VIEW_INDENTATION_GUIDES_ID
, frame
.ProcessEvent
) 
 732         wx
.EVT_UPDATE_UI(frame
, VIEW_INDENTATION_GUIDES_ID
, frame
.ProcessUpdateUIEvent
) 
 733         textMenu
.AppendCheckItem(VIEW_RIGHT_EDGE_ID
, _("&Right Edge"), _("Shows or hides the right edge marker")) 
 734         wx
.EVT_MENU(frame
, VIEW_RIGHT_EDGE_ID
, frame
.ProcessEvent
) 
 735         wx
.EVT_UPDATE_UI(frame
, VIEW_RIGHT_EDGE_ID
, frame
.ProcessUpdateUIEvent
) 
 736         textMenu
.AppendCheckItem(VIEW_LINE_NUMBERS_ID
, _("&Line Numbers"), _("Shows or hides the line numbers")) 
 737         wx
.EVT_MENU(frame
, VIEW_LINE_NUMBERS_ID
, frame
.ProcessEvent
) 
 738         wx
.EVT_UPDATE_UI(frame
, VIEW_LINE_NUMBERS_ID
, frame
.ProcessUpdateUIEvent
) 
 740         viewMenu
.AppendMenu(TEXT_ID
, _("&Text"), textMenu
) 
 741         wx
.EVT_UPDATE_UI(frame
, TEXT_ID
, frame
.ProcessUpdateUIEvent
) 
 743         isWindows 
= (wx
.Platform 
== '__WXMSW__') 
 746         zoomMenu
.Append(ZOOM_NORMAL_ID
, _("Normal Size"), _("Sets the document to its normal size")) 
 747         wx
.EVT_MENU(frame
, ZOOM_NORMAL_ID
, frame
.ProcessEvent
) 
 748         wx
.EVT_UPDATE_UI(frame
, ZOOM_NORMAL_ID
, frame
.ProcessUpdateUIEvent
) 
 750             zoomMenu
.Append(ZOOM_IN_ID
, _("Zoom In\tCtrl+Page Up"), _("Zooms the document to a larger size")) 
 752             zoomMenu
.Append(ZOOM_IN_ID
, _("Zoom In"), _("Zooms the document to a larger size")) 
 753         wx
.EVT_MENU(frame
, ZOOM_IN_ID
, frame
.ProcessEvent
) 
 754         wx
.EVT_UPDATE_UI(frame
, ZOOM_IN_ID
, frame
.ProcessUpdateUIEvent
) 
 756             zoomMenu
.Append(ZOOM_OUT_ID
, _("Zoom Out\tCtrl+Page Down"), _("Zooms the document to a smaller size")) 
 758             zoomMenu
.Append(ZOOM_OUT_ID
, _("Zoom Out"), _("Zooms the document to a smaller size")) 
 759         wx
.EVT_MENU(frame
, ZOOM_OUT_ID
, frame
.ProcessEvent
) 
 760         wx
.EVT_UPDATE_UI(frame
, ZOOM_OUT_ID
, frame
.ProcessUpdateUIEvent
) 
 762         viewMenu
.AppendMenu(ZOOM_ID
, _("&Zoom"), zoomMenu
) 
 763         wx
.EVT_UPDATE_UI(frame
, ZOOM_ID
, frame
.ProcessUpdateUIEvent
) 
 765         formatMenuIndex 
= menuBar
.FindMenu(_("&Format")) 
 766         if formatMenuIndex 
> -1: 
 767             formatMenu 
= menuBar
.GetMenu(formatMenuIndex
) 
 769             formatMenu 
= wx
.Menu() 
 770         if not menuBar
.FindItemById(CHOOSE_FONT_ID
): 
 771             formatMenu
.Append(CHOOSE_FONT_ID
, _("&Font..."), _("Sets the font to use")) 
 772             wx
.EVT_MENU(frame
, CHOOSE_FONT_ID
, frame
.ProcessEvent
) 
 773             wx
.EVT_UPDATE_UI(frame
, CHOOSE_FONT_ID
, frame
.ProcessUpdateUIEvent
) 
 774         if not menuBar
.FindItemById(WORD_WRAP_ID
): 
 775             formatMenu
.AppendCheckItem(WORD_WRAP_ID
, _("Word Wrap"), _("Wraps text horizontally when checked")) 
 776             wx
.EVT_MENU(frame
, WORD_WRAP_ID
, frame
.ProcessEvent
) 
 777             wx
.EVT_UPDATE_UI(frame
, WORD_WRAP_ID
, frame
.ProcessUpdateUIEvent
) 
 778         if formatMenuIndex 
== -1: 
 779             viewMenuIndex 
= menuBar
.FindMenu(_("&View")) 
 780             menuBar
.Insert(viewMenuIndex 
+ 1, formatMenu
, _("&Format")) 
 782         # wxBug: wxToolBar::GetToolPos doesn't exist, need it to find cut tool and then insert find in front of it. 
 783         toolBar
.AddSeparator() 
 784         toolBar
.AddTool(ZOOM_IN_ID
, getZoomInBitmap(), shortHelpString 
= _("Zoom In"), longHelpString 
= _("Zooms the document to a larger size")) 
 785         toolBar
.AddTool(ZOOM_OUT_ID
, getZoomOutBitmap(), shortHelpString 
= _("Zoom Out"), longHelpString 
= _("Zooms the document to a smaller size")) 
 789     def ProcessUpdateUIEvent(self
, event
): 
 792         or id == VIEW_WHITESPACE_ID
 
 794         or id == VIEW_INDENTATION_GUIDES_ID
 
 795         or id == VIEW_RIGHT_EDGE_ID
 
 796         or id == VIEW_LINE_NUMBERS_ID
 
 798         or id == ZOOM_NORMAL_ID
 
 801         or id == CHOOSE_FONT_ID
 
 802         or id == WORD_WRAP_ID
): 
 809 class TextStatusBar(wx
.StatusBar
): 
 811     # 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 
 813     def __init__(self
, parent
, id, style 
= wx
.ST_SIZEGRIP
, name 
= "statusBar"): 
 814         wx
.StatusBar
.__init
__(self
, parent
, id, style
, name
) 
 815         self
.SetFieldsCount(4) 
 816         self
.SetStatusWidths([-1, 50, 50, 55]) 
 818     def SetInsertMode(self
, insert 
= True): 
 823         if self
.GetStatusText(1) != newText
:     # wxBug: Need to check if the text has changed, otherwise it flickers under win32 
 824             self
.SetStatusText(newText
, 1) 
 826     def SetLineNumber(self
, lineNumber
): 
 827         newText 
= _("Ln %i") % lineNumber
 
 828         if self
.GetStatusText(2) != newText
: 
 829             self
.SetStatusText(newText
, 2) 
 831     def SetColumnNumber(self
, colNumber
): 
 832         newText 
= _("Col %i") % colNumber
 
 833         if self
.GetStatusText(3) != newText
: 
 834             self
.SetStatusText(newText
, 3) 
 837 class TextOptionsPanel(wx
.Panel
): 
 840     def __init__(self
, parent
, id, configPrefix 
= "Text", label 
= "Text", hasWordWrap 
= True, hasTabs 
= False, addPage
=True, hasFolding
=False): 
 841         wx
.Panel
.__init
__(self
, parent
, id) 
 842         self
._configPrefix 
= configPrefix
 
 843         self
._hasWordWrap 
= hasWordWrap
 
 844         self
._hasTabs 
= hasTabs
 
 845         self
._hasFolding 
= hasFolding
 
 848         config 
= wx
.ConfigBase_Get() 
 849         self
._textFont 
= wx
.Font(10, wx
.MODERN
, wx
.NORMAL
, wx
.NORMAL
) 
 850         fontData 
= config
.Read(self
._configPrefix 
+ "EditorFont", "") 
 852             nativeFont 
= wx
.NativeFontInfo() 
 853             nativeFont
.FromString(fontData
) 
 854             self
._textFont
.SetNativeFontInfo(nativeFont
) 
 855         self
._originalTextFont 
= self
._textFont
 
 856         self
._textColor 
= wx
.BLACK
 
 857         colorData 
= config
.Read(self
._configPrefix 
+ "EditorColor", "") 
 859             red 
= int("0x" + colorData
[0:2], 16) 
 860             green 
= int("0x" + colorData
[2:4], 16) 
 861             blue 
= int("0x" + colorData
[4:6], 16) 
 862             self
._textColor 
= wx
.Color(red
, green
, blue
) 
 863         self
._originalTextColor 
= self
._textColor
 
 864         fontLabel 
= wx
.StaticText(self
, -1, _("Font:")) 
 865         self
._sampleTextCtrl 
= wx
.TextCtrl(self
, -1, "", size 
= (125, 21)) 
 866         self
._sampleTextCtrl
.SetEditable(False) 
 867         chooseFontButton 
= wx
.Button(self
, -1, _("Choose Font...")) 
 868         wx
.EVT_BUTTON(self
, chooseFontButton
.GetId(), self
.OnChooseFont
) 
 869         if self
._hasWordWrap
: 
 870             self
._wordWrapCheckBox 
= wx
.CheckBox(self
, -1, _("Wrap words inside text area")) 
 871             self
._wordWrapCheckBox
.SetValue(wx
.ConfigBase_Get().ReadInt(self
._configPrefix 
+ "EditorWordWrap", False)) 
 872         self
._viewWhitespaceCheckBox 
= wx
.CheckBox(self
, -1, _("Show whitespace")) 
 873         self
._viewWhitespaceCheckBox
.SetValue(config
.ReadInt(self
._configPrefix 
+ "EditorViewWhitespace", False)) 
 874         self
._viewEOLCheckBox 
= wx
.CheckBox(self
, -1, _("Show end of line markers")) 
 875         self
._viewEOLCheckBox
.SetValue(config
.ReadInt(self
._configPrefix 
+ "EditorViewEOL", False)) 
 876         self
._viewIndentationGuideCheckBox 
= wx
.CheckBox(self
, -1, _("Show indentation guides")) 
 877         self
._viewIndentationGuideCheckBox
.SetValue(config
.ReadInt(self
._configPrefix 
+ "EditorViewIndentationGuides", False)) 
 878         self
._viewRightEdgeCheckBox 
= wx
.CheckBox(self
, -1, _("Show right edge")) 
 879         self
._viewRightEdgeCheckBox
.SetValue(config
.ReadInt(self
._configPrefix 
+ "EditorViewRightEdge", False)) 
 880         self
._viewLineNumbersCheckBox 
= wx
.CheckBox(self
, -1, _("Show line numbers")) 
 881         self
._viewLineNumbersCheckBox
.SetValue(config
.ReadInt(self
._configPrefix 
+ "EditorViewLineNumbers", True)) 
 883             self
._viewFoldingCheckBox 
= wx
.CheckBox(self
, -1, _("Show folding")) 
 884             self
._viewFoldingCheckBox
.SetValue(config
.ReadInt(self
._configPrefix 
+ "EditorViewFolding", True)) 
 886             self
._hasTabsCheckBox 
= wx
.CheckBox(self
, -1, _("Use spaces instead of tabs")) 
 887             self
._hasTabsCheckBox
.SetValue(not wx
.ConfigBase_Get().ReadInt(self
._configPrefix 
+ "EditorUseTabs", False)) 
 888             indentWidthLabel 
= wx
.StaticText(self
, -1, _("Indent Width:")) 
 889             self
._indentWidthChoice 
= wx
.Choice(self
, -1, choices 
= ["2", "4", "6", "8", "10"]) 
 890             self
._indentWidthChoice
.SetStringSelection(str(config
.ReadInt(self
._configPrefix 
+ "EditorIndentWidth", 4))) 
 891         textPanelBorderSizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
 892         textPanelSizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
 893         textFontSizer 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
 894         textFontSizer
.Add(fontLabel
, 0, wx
.ALIGN_LEFT | wx
.RIGHT | wx
.TOP
, HALF_SPACE
) 
 895         textFontSizer
.Add(self
._sampleTextCtrl
, 1, wx
.ALIGN_LEFT | wx
.EXPAND | wx
.RIGHT
, HALF_SPACE
) 
 896         textFontSizer
.Add(chooseFontButton
, 0, wx
.ALIGN_RIGHT | wx
.LEFT
, HALF_SPACE
) 
 897         textPanelSizer
.Add(textFontSizer
, 0, wx
.ALL|wx
.EXPAND
, HALF_SPACE
) 
 898         if self
._hasWordWrap
: 
 899             textPanelSizer
.Add(self
._wordWrapCheckBox
, 0, wx
.ALL
, HALF_SPACE
) 
 900         textPanelSizer
.Add(self
._viewWhitespaceCheckBox
, 0, wx
.ALL
, HALF_SPACE
) 
 901         textPanelSizer
.Add(self
._viewEOLCheckBox
, 0, wx
.ALL
, HALF_SPACE
) 
 902         textPanelSizer
.Add(self
._viewIndentationGuideCheckBox
, 0, wx
.ALL
, HALF_SPACE
) 
 903         textPanelSizer
.Add(self
._viewRightEdgeCheckBox
, 0, wx
.ALL
, HALF_SPACE
) 
 904         textPanelSizer
.Add(self
._viewLineNumbersCheckBox
, 0, wx
.ALL
, HALF_SPACE
) 
 906             textPanelSizer
.Add(self
._viewFoldingCheckBox
, 0, wx
.ALL
, HALF_SPACE
) 
 908             textPanelSizer
.Add(self
._hasTabsCheckBox
, 0, wx
.ALL
, HALF_SPACE
) 
 909             textIndentWidthSizer 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
 910             textIndentWidthSizer
.Add(indentWidthLabel
, 0, wx
.ALIGN_LEFT | wx
.RIGHT | wx
.TOP
, HALF_SPACE
) 
 911             textIndentWidthSizer
.Add(self
._indentWidthChoice
, 0, wx
.ALIGN_LEFT | wx
.EXPAND
, HALF_SPACE
) 
 912             textPanelSizer
.Add(textIndentWidthSizer
, 0, wx
.ALL
, HALF_SPACE
) 
 913         textPanelBorderSizer
.Add(textPanelSizer
, 0, wx
.ALL|wx
.EXPAND
, SPACE
) 
 914 ##        styleButton = wx.Button(self, -1, _("Choose Style...")) 
 915 ##        wx.EVT_BUTTON(self, styleButton.GetId(), self.OnChooseStyle) 
 916 ##        textPanelBorderSizer.Add(styleButton, 0, wx.ALL, SPACE) 
 917         self
.SetSizer(textPanelBorderSizer
) 
 918         self
.UpdateSampleFont() 
 920             parent
.AddPage(self
, _(label
)) 
 922     def UpdateSampleFont(self
): 
 923         nativeFont 
= wx
.NativeFontInfo() 
 924         nativeFont
.FromString(self
._textFont
.GetNativeFontInfoDesc()) 
 926         font
.SetNativeFontInfo(nativeFont
) 
 927         font
.SetPointSize(self
._sampleTextCtrl
.GetFont().GetPointSize())  # Use the standard point size 
 928         self
._sampleTextCtrl
.SetFont(font
) 
 929         self
._sampleTextCtrl
.SetForegroundColour(self
._textColor
) 
 930         self
._sampleTextCtrl
.SetValue(str(self
._textFont
.GetPointSize()) + _(" pt. ") + self
._textFont
.GetFaceName()) 
 931         self
._sampleTextCtrl
.Refresh() 
 935 ##    def OnChooseStyle(self, event): 
 936 ##        import STCStyleEditor 
 938 ##        base = os.path.split(__file__)[0] 
 939 ##        config = os.path.abspath(os.path.join(base, 'stc-styles.rc.cfg')) 
 941 ##        dlg = STCStyleEditor.STCStyleEditDlg(None, 
 942 ##                                'Python', 'python', 
 946 ##        dlg.CenterOnParent() 
 953     def OnChooseFont(self
, event
): 
 955         data
.EnableEffects(True) 
 956         data
.SetInitialFont(self
._textFont
) 
 957         data
.SetColour(self
._textColor
) 
 958         fontDialog 
= wx
.FontDialog(self
, data
) 
 959         fontDialog
.CenterOnParent() 
 960         if fontDialog
.ShowModal() == wx
.ID_OK
: 
 961             data 
= fontDialog
.GetFontData() 
 962             self
._textFont 
= data
.GetChosenFont() 
 963             self
._textColor 
= data
.GetColour() 
 964             self
.UpdateSampleFont() 
 968     def OnOK(self
, optionsDialog
): 
 969         config 
= wx
.ConfigBase_Get() 
 970         doViewStuffUpdate 
= config
.ReadInt(self
._configPrefix 
+ "EditorViewWhitespace", False) != self
._viewWhitespaceCheckBox
.GetValue() 
 971         config
.WriteInt(self
._configPrefix 
+ "EditorViewWhitespace", self
._viewWhitespaceCheckBox
.GetValue()) 
 972         doViewStuffUpdate 
= doViewStuffUpdate 
or config
.ReadInt(self
._configPrefix 
+ "EditorViewEOL", False) != self
._viewEOLCheckBox
.GetValue() 
 973         config
.WriteInt(self
._configPrefix 
+ "EditorViewEOL", self
._viewEOLCheckBox
.GetValue()) 
 974         doViewStuffUpdate 
= doViewStuffUpdate 
or config
.ReadInt(self
._configPrefix 
+ "EditorViewIndentationGuides", False) != self
._viewIndentationGuideCheckBox
.GetValue() 
 975         config
.WriteInt(self
._configPrefix 
+ "EditorViewIndentationGuides", self
._viewIndentationGuideCheckBox
.GetValue()) 
 976         doViewStuffUpdate 
= doViewStuffUpdate 
or config
.ReadInt(self
._configPrefix 
+ "EditorViewRightEdge", False) != self
._viewRightEdgeCheckBox
.GetValue() 
 977         config
.WriteInt(self
._configPrefix 
+ "EditorViewRightEdge", self
._viewRightEdgeCheckBox
.GetValue()) 
 978         doViewStuffUpdate 
= doViewStuffUpdate 
or config
.ReadInt(self
._configPrefix 
+ "EditorViewLineNumbers", True) != self
._viewLineNumbersCheckBox
.GetValue() 
 979         config
.WriteInt(self
._configPrefix 
+ "EditorViewLineNumbers", self
._viewLineNumbersCheckBox
.GetValue()) 
 981             doViewStuffUpdate 
= doViewStuffUpdate 
or config
.ReadInt(self
._configPrefix 
+ "EditorViewFolding", True) != self
._viewFoldingCheckBox
.GetValue() 
 982             config
.WriteInt(self
._configPrefix 
+ "EditorViewFolding", self
._viewFoldingCheckBox
.GetValue()) 
 983         if self
._hasWordWrap
: 
 984             doViewStuffUpdate 
= doViewStuffUpdate 
or config
.ReadInt(self
._configPrefix 
+ "EditorWordWrap", False) != self
._wordWrapCheckBox
.GetValue() 
 985             config
.WriteInt(self
._configPrefix 
+ "EditorWordWrap", self
._wordWrapCheckBox
.GetValue()) 
 987             doViewStuffUpdate 
= doViewStuffUpdate 
or not config
.ReadInt(self
._configPrefix 
+ "EditorUseTabs", True) != self
._hasTabsCheckBox
.GetValue() 
 988             config
.WriteInt(self
._configPrefix 
+ "EditorUseTabs", not self
._hasTabsCheckBox
.GetValue()) 
 989             newIndentWidth 
= int(self
._indentWidthChoice
.GetStringSelection()) 
 990             oldIndentWidth 
= config
.ReadInt(self
._configPrefix 
+ "EditorIndentWidth", 4) 
 991             if newIndentWidth 
!= oldIndentWidth
: 
 992                 doViewStuffUpdate 
= True 
 993                 config
.WriteInt(self
._configPrefix 
+ "EditorIndentWidth", newIndentWidth
) 
 994         doFontUpdate 
= self
._originalTextFont 
!= self
._textFont 
or self
._originalTextColor 
!= self
._textColor
 
 995         config
.Write(self
._configPrefix 
+ "EditorFont", self
._textFont
.GetNativeFontInfoDesc()) 
 996         config
.Write(self
._configPrefix 
+ "EditorColor", "%02x%02x%02x" % (self
._textColor
.Red(), self
._textColor
.Green(), self
._textColor
.Blue())) 
 997         if doViewStuffUpdate 
or doFontUpdate
: 
 998             for document 
in optionsDialog
.GetDocManager().GetDocuments(): 
 999                 if issubclass(document
.GetDocumentTemplate().GetDocumentType(), TextDocument
): 
1000                     if doViewStuffUpdate
: 
1001                         document
.UpdateAllViews(hint 
= "ViewStuff") 
1003                         document
.UpdateAllViews(hint 
= "Font") 
1007         return getTextIcon() 
1010 class TextCtrl(wx
.stc
.StyledTextCtrl
): 
1012     def __init__(self
, parent
, id=-1, style
=wx
.NO_FULL_REPAINT_ON_RESIZE
): 
1013         wx
.stc
.StyledTextCtrl
.__init
__(self
, parent
, id, style
=style
) 
1015         if isinstance(parent
, wx
.gizmos
.DynamicSashWindow
): 
1016             self
._dynSash 
= parent
 
1017             self
.SetupDSScrollBars() 
1018             self
.Bind(wx
.gizmos
.EVT_DYNAMIC_SASH_SPLIT
, self
.OnDSSplit
) 
1019             self
.Bind(wx
.gizmos
.EVT_DYNAMIC_SASH_UNIFY
, self
.OnDSUnify
) 
1022         self
._fontColor 
= None 
1024         self
.SetVisiblePolicy(wx
.stc
.STC_VISIBLE_STRICT
,1) 
1026         self
.CmdKeyClear(wx
.stc
.STC_KEY_ADD
, wx
.stc
.STC_SCMOD_CTRL
) 
1027         self
.CmdKeyClear(wx
.stc
.STC_KEY_SUBTRACT
, wx
.stc
.STC_SCMOD_CTRL
) 
1028         self
.CmdKeyAssign(wx
.stc
.STC_KEY_PRIOR
, wx
.stc
.STC_SCMOD_CTRL
, wx
.stc
.STC_CMD_ZOOMIN
) 
1029         self
.CmdKeyAssign(wx
.stc
.STC_KEY_NEXT
, wx
.stc
.STC_SCMOD_CTRL
, wx
.stc
.STC_CMD_ZOOMOUT
) 
1030         self
.Bind(wx
.stc
.EVT_STC_ZOOM
, self
.OnUpdateLineNumberMarginWidth
)  # auto update line num width on zoom 
1031         wx
.EVT_KEY_DOWN(self
, self
.OnKeyPressed
) 
1032         wx
.EVT_KILL_FOCUS(self
, self
.OnKillFocus
) 
1033         wx
.EVT_SET_FOCUS(self
, self
.OnFocus
) 
1034         self
.SetMargins(0,0) 
1040         self
.SetViewWhiteSpace(False) 
1041         self
.SetEOLMode(wx
.stc
.STC_EOL_LF
) 
1042         self
.SetEdgeMode(wx
.stc
.STC_EDGE_NONE
) 
1043         self
.SetEdgeColumn(78) 
1045         self
.SetMarginType(1, wx
.stc
.STC_MARGIN_NUMBER
) 
1046         self
.SetMarginWidth(1, self
.EstimatedLineNumberMarginWidth()) 
1049         self
.SetCaretForeground("BLACK") 
1051         self
.SetViewDefaults() 
1052         font
, color 
= self
.GetFontAndColorFromConfig() 
1054         self
.SetFontColor(color
) 
1055         self
.MarkerDefineDefault() 
1057         # for multisash initialization    
1058         if isinstance(parent
, wx
.lib
.multisash
.MultiClient
):      
1059             while parent
.GetParent():     
1060                 parent 
= parent
.GetParent()       
1061                 if hasattr(parent
, "GetView"):    
1063             if hasattr(parent
, "GetView"):        
1064                 textEditor 
= parent
.GetView()._textEditor        
 
1066                     doc 
= textEditor
.GetDocPointer()      
1068                         self
.SetDocPointer(doc
) 
1071     def OnFocus(self
, event
): 
1072         # wxBug: On Mac, the STC control may fire a focus/kill focus event 
1073         # on shutdown even if the control is in an invalid state. So check 
1074         # before handling the event. 
1075         if self
.IsBeingDeleted(): 
1078         self
.SetSelBackground(1, "BLUE") 
1079         self
.SetSelForeground(1, "WHITE") 
1080         if hasattr(self
, "_dynSash"): 
1081             self
._dynSash
._view
.SetCtrl(self
) 
1085     def OnKillFocus(self
, event
): 
1086         # wxBug: On Mac, the STC control may fire a focus/kill focus event 
1087         # on shutdown even if the control is in an invalid state. So check 
1088         # before handling the event. 
1089         if self
.IsBeingDeleted(): 
1091         self
.SetSelBackground(0, "BLUE") 
1092         self
.SetSelForeground(0, "WHITE") 
1093         self
.SetSelBackground(1, "#C0C0C0") 
1094         # Don't set foreground color, use syntax highlighted default colors. 
1098     def SetViewDefaults(self
, configPrefix
="Text", hasWordWrap
=True, hasTabs
=False, hasFolding
=False): 
1099         config 
= wx
.ConfigBase_Get() 
1100         self
.SetViewWhiteSpace(config
.ReadInt(configPrefix 
+ "EditorViewWhitespace", False)) 
1101         self
.SetViewEOL(config
.ReadInt(configPrefix 
+ "EditorViewEOL", False)) 
1102         self
.SetIndentationGuides(config
.ReadInt(configPrefix 
+ "EditorViewIndentationGuides", False)) 
1103         self
.SetViewRightEdge(config
.ReadInt(configPrefix 
+ "EditorViewRightEdge", False)) 
1104         self
.SetViewLineNumbers(config
.ReadInt(configPrefix 
+ "EditorViewLineNumbers", True)) 
1106             self
.SetViewFolding(config
.ReadInt(configPrefix 
+ "EditorViewFolding", True)) 
1108             self
.SetWordWrap(config
.ReadInt(configPrefix 
+ "EditorWordWrap", False)) 
1109         if hasTabs
:  # These methods do not exist in STCTextEditor and are meant for subclasses 
1110             self
.SetUseTabs(config
.ReadInt(configPrefix 
+ "EditorUseTabs", False)) 
1111             self
.SetIndent(config
.ReadInt(configPrefix 
+ "EditorIndentWidth", 4)) 
1112             self
.SetTabWidth(config
.ReadInt(configPrefix 
+ "EditorIndentWidth", 4)) 
1114             self
.SetUseTabs(True) 
1119     def GetDefaultFont(self
): 
1120         """ Subclasses should override this """ 
1121         return wx
.Font(10, wx
.MODERN
, wx
.NORMAL
, wx
.NORMAL
) 
1124     def GetDefaultColor(self
): 
1125         """ Subclasses should override this """ 
1129     def GetFontAndColorFromConfig(self
, configPrefix 
= "Text"): 
1130         font 
= self
.GetDefaultFont() 
1131         config 
= wx
.ConfigBase_Get() 
1132         fontData 
= config
.Read(configPrefix 
+ "EditorFont", "") 
1134             nativeFont 
= wx
.NativeFontInfo() 
1135             nativeFont
.FromString(fontData
) 
1136             font
.SetNativeFontInfo(nativeFont
) 
1137         color 
= self
.GetDefaultColor() 
1138         colorData 
= config
.Read(configPrefix 
+ "EditorColor", "") 
1140             red 
= int("0x" + colorData
[0:2], 16) 
1141             green 
= int("0x" + colorData
[2:4], 16) 
1142             blue 
= int("0x" + colorData
[4:6], 16) 
1143             color 
= wx
.Color(red
, green
, blue
) 
1151     def SetFont(self
, font
): 
1153         self
.StyleSetFont(wx
.stc
.STC_STYLE_DEFAULT
, self
._font
) 
1156     def GetFontColor(self
): 
1157         return self
._fontColor
 
1160     def SetFontColor(self
, fontColor 
= wx
.BLACK
): 
1161         self
._fontColor 
= fontColor
 
1162         self
.StyleSetForeground(wx
.stc
.STC_STYLE_DEFAULT
, "#%02x%02x%02x" % (self
._fontColor
.Red(), self
._fontColor
.Green(), self
._fontColor
.Blue())) 
1165     def UpdateStyles(self
): 
1166         self
.StyleClearAll() 
1170     def EstimatedLineNumberMarginWidth(self
): 
1173         lineNum 
= self
.GetLineCount() 
1174         lineNum 
= lineNum
/100 
1175         while lineNum 
>= 10: 
1176             lineNum 
= lineNum
/10 
1177             baseNumbers 
= baseNumbers 
+ "0" 
1179         return self
.TextWidth(wx
.stc
.STC_STYLE_LINENUMBER
, baseNumbers
) + MARGIN
 
1182     def OnUpdateLineNumberMarginWidth(self
, event
): 
1183         self
.UpdateLineNumberMarginWidth() 
1186     def UpdateLineNumberMarginWidth(self
): 
1187         if self
.GetViewLineNumbers(): 
1188             self
.SetMarginWidth(1, self
.EstimatedLineNumberMarginWidth()) 
1190     def MarkerDefineDefault(self
): 
1191         """ This must be called after the textcontrol is instantiated """ 
1192         self
.MarkerDefine(TextView
.MARKER_NUM
, wx
.stc
.STC_MARK_ROUNDRECT
, wx
.BLACK
, wx
.BLUE
) 
1196         # Used when Delete key is hit. 
1197         sel 
= self
.GetSelection() 
1199         # Delete the selection or if no selection, the character after the caret. 
1200         if sel
[0] == sel
[1]: 
1201             self
.SetSelection(sel
[0], sel
[0] + 1) 
1203             # remove any folded lines also. 
1204             startLine 
= self
.LineFromPosition(sel
[0]) 
1205             endLine 
= self
.LineFromPosition(sel
[1]) 
1206             endLineStart 
= self
.PositionFromLine(endLine
) 
1207             if startLine 
!= endLine 
and sel
[1] - endLineStart 
== 0: 
1208                 while not self
.GetLineVisible(endLine
): 
1210                 self
.SetSelectionEnd(self
.PositionFromLine(endLine
)) 
1216         # replace any folded lines also. 
1217         sel 
= self
.GetSelection() 
1218         startLine 
= self
.LineFromPosition(sel
[0]) 
1219         endLine 
= self
.LineFromPosition(sel
[1]) 
1220         endLineStart 
= self
.PositionFromLine(endLine
) 
1221         if startLine 
!= endLine 
and sel
[1] - endLineStart 
== 0: 
1222             while not self
.GetLineVisible(endLine
): 
1224             self
.SetSelectionEnd(self
.PositionFromLine(endLine
)) 
1229     def OnKeyPressed(self
, event
): 
1230         key 
= event
.GetKeyCode() 
1231         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 
1232             if event
.ControlDown(): 
1233                 self
.ToggleFoldAll(expand 
= True, topLevelOnly 
= True) 
1234             elif event
.ShiftDown(): 
1235                 self
.ToggleFoldAll(expand 
= True) 
1237                 self
.ToggleFold(self
.GetCurrentLine()) 
1238         elif key 
== wx
.WXK_NUMPAD_SUBTRACT
: 
1239             if event
.ControlDown(): 
1240                 self
.ToggleFoldAll(expand 
= False, topLevelOnly 
= True) 
1241             elif event
.ShiftDown(): 
1242                 self
.ToggleFoldAll(expand 
= False) 
1244                 self
.ToggleFold(self
.GetCurrentLine()) 
1249     #---------------------------------------------------------------------------- 
1251     #---------------------------------------------------------------------------- 
1253     def GetViewRightEdge(self
): 
1254         return self
.GetEdgeMode() != wx
.stc
.STC_EDGE_NONE
 
1257     def SetViewRightEdge(self
, viewRightEdge
): 
1259             self
.SetEdgeMode(wx
.stc
.STC_EDGE_LINE
) 
1261             self
.SetEdgeMode(wx
.stc
.STC_EDGE_NONE
) 
1264     def GetViewLineNumbers(self
): 
1265         return self
.GetMarginWidth(1) > 0 
1268     def SetViewLineNumbers(self
, viewLineNumbers 
= True): 
1270             self
.SetMarginWidth(1, self
.EstimatedLineNumberMarginWidth()) 
1272             self
.SetMarginWidth(1, 0) 
1275     def GetViewFolding(self
): 
1276         return self
.GetMarginWidth(2) > 0 
1279     def SetViewFolding(self
, viewFolding 
= True): 
1281             self
.SetMarginWidth(2, 12) 
1283             self
.SetMarginWidth(2, 0) 
1286     def CanWordWrap(self
): 
1290     def GetWordWrap(self
): 
1291         return self
.GetWrapMode() == wx
.stc
.STC_WRAP_WORD
 
1294     def SetWordWrap(self
, wordWrap
): 
1296             self
.SetWrapMode(wx
.stc
.STC_WRAP_WORD
) 
1298             self
.SetWrapMode(wx
.stc
.STC_WRAP_NONE
) 
1301     #---------------------------------------------------------------------------- 
1302     # DynamicSashWindow methods 
1303     #---------------------------------------------------------------------------- 
1305     def SetupDSScrollBars(self
): 
1306         # hook the scrollbars provided by the wxDynamicSashWindow 
1308         v_bar 
= self
._dynSash
.GetVScrollBar(self
) 
1309         h_bar 
= self
._dynSash
.GetHScrollBar(self
) 
1310         v_bar
.Bind(wx
.EVT_SCROLL
, self
.OnDSSBScroll
) 
1311         h_bar
.Bind(wx
.EVT_SCROLL
, self
.OnDSSBScroll
) 
1312         v_bar
.Bind(wx
.EVT_SET_FOCUS
, self
.OnDSSBFocus
) 
1313         h_bar
.Bind(wx
.EVT_SET_FOCUS
, self
.OnDSSBFocus
) 
1315         # And set the wxStyledText to use these scrollbars instead 
1316         # of its built-in ones. 
1317         self
.SetVScrollBar(v_bar
) 
1318         self
.SetHScrollBar(h_bar
) 
1321     def OnDSSplit(self
, evt
): 
1322         newCtrl 
= self
._dynSash
._view
.GetCtrlClass()(self
._dynSash
, -1, style
=wx
.NO_BORDER
) 
1323         newCtrl
.SetDocPointer(self
.GetDocPointer())     # use the same document 
1324         self
.SetupDSScrollBars() 
1325         if self 
== self
._dynSash
._view
.GetCtrl():  # originally had focus 
1326             wx
.CallAfter(self
.SetFocus
)  # do this to set colors correctly.  wxBug:  for some reason, if we don't do a CallAfter, it immediately calls OnKillFocus right after our SetFocus. 
1329     def OnDSUnify(self
, evt
): 
1330         self
.SetupDSScrollBars() 
1331         self
.SetFocus()  # do this to set colors correctly 
1334     def OnDSSBScroll(self
, evt
): 
1335         # redirect the scroll events from the _dynSash's scrollbars to the STC 
1336         self
.GetEventHandler().ProcessEvent(evt
) 
1339     def OnDSSBFocus(self
, evt
): 
1340         # when the scrollbar gets the focus move it back to the STC 
1344     def DSProcessEvent(self
, event
): 
1345         # wxHack: Needed for customized right mouse click menu items.         
1346         if hasattr(self
, "_dynSash"): 
1347             if event
.GetId() == wx
.ID_SELECTALL
: 
1348                 # force focus so that select all occurs in the window user right clicked on. 
1351             return self
._dynSash
._view
.ProcessEvent(event
) 
1355     def DSProcessUpdateUIEvent(self
, event
): 
1356         # wxHack: Needed for customized right mouse click menu items.         
1357         if hasattr(self
, "_dynSash"): 
1359             if (id == wx
.ID_SELECTALL  
# allow select all even in non-active window, then force focus to it, see above ProcessEvent 
1361             or id == wx
.ID_REDO
): 
1362                 pass  # allow these actions even in non-active window 
1363             else:  # disallow events in non-active windows.  Cut/Copy/Paste/Delete is too confusing user experience. 
1364                 if self
._dynSash
._view
.GetCtrl() != self
: 
1368             return self
._dynSash
._view
.ProcessUpdateUIEvent(event
) 
1372 class TextPrintout(wx
.lib
.docview
.DocPrintout
): 
1373     """ for Print Preview and Print """ 
1376     def OnPreparePrinting(self
): 
1377         """ initialization """ 
1380         ppiScreenX
, ppiScreenY 
= self
.GetPPIScreen() 
1381         ppiPrinterX
, ppiPrinterY 
= self
.GetPPIPrinter() 
1382         scaleX 
= float(ppiPrinterX
)/ppiScreenX
 
1383         scaleY 
= float(ppiPrinterY
)/ppiScreenY
 
1385         pageWidth
, pageHeight 
= self
.GetPageSizePixels() 
1386         self
._scaleFactorX 
= scaleX
/pageWidth
 
1387         self
._scaleFactorY 
= scaleY
/pageHeight
 
1390         overallScaleX 
= self
._scaleFactorX 
* w
 
1391         overallScaleY 
= self
._scaleFactorY 
* h
 
1393         txtCtrl 
= self
._printoutView
.GetCtrl() 
1394         font
, color 
= txtCtrl
.GetFontAndColorFromConfig() 
1397         self
._fontHeight 
= font
.GetPointSize() + 1 
1398         self
._pageLines 
= int((h
/overallScaleY 
- (2 * self
._margin
))/self
._fontHeight
) 
1399         self
._maxLines 
= txtCtrl
.GetLineCount() 
1400         self
._numPages
, remainder 
= divmod(self
._maxLines
, self
._pageLines
) 
1405         lineNum 
= self
._maxLines
 
1406         while lineNum 
>= 10: 
1407             lineNum 
= lineNum
/10 
1409         self
._printFormat 
= "%%0%sd: %%s" % spaces
 
1412     def OnPrintPage(self
, page
): 
1413         """ Prints the given page of the view """ 
1416         txtCtrl 
= self
._printoutView
.GetCtrl() 
1417         font
, color 
= txtCtrl
.GetFontAndColorFromConfig() 
1421         dc
.SetUserScale(self
._scaleFactorX 
* w
, self
._scaleFactorY 
* h
) 
1425         dc
.DrawText("%s - page %s" % (self
.GetTitle(), page
), self
._margin
, self
._margin
/2) 
1427         startY 
= self
._margin
 
1428         startLine 
= (page 
- 1) * self
._pageLines
 
1429         endLine 
= min((startLine 
+ self
._pageLines
), self
._maxLines
) 
1430         for i 
in range(startLine
, endLine
): 
1431             text 
= txtCtrl
.GetLine(i
).rstrip() 
1432             startY 
+= self
._fontHeight
 
1433             if txtCtrl
.GetViewLineNumbers(): 
1434                 dc
.DrawText(self
._printFormat 
% (i
+1, text
), self
._margin
, startY
) 
1436                 dc
.DrawText(text
, self
._margin
, startY
) 
1443     def HasPage(self
, pageNum
): 
1444         return pageNum 
<= self
._numPages
 
1447     def GetPageInfo(self
): 
1449         maxPage 
= self
._numPages
 
1451         selPageTo 
= self
._numPages
 
1452         return (minPage
, maxPage
, selPageFrom
, selPageTo
) 
1455 #---------------------------------------------------------------------------- 
1456 # Icon Bitmaps - generated by encode_bitmaps.py 
1457 #---------------------------------------------------------------------------- 
1458 from wx 
import ImageFromStream
, BitmapFromImage
 
1464 "\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ 
1465 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ 
1466 \x00\x015IDAT8\x8d\xad\x90\xb1N\xc2P\x14\x86\xbf\x02/\xe0\xec#\x18g\xc3\xe6T\ 
1467 \x13':1\x18H\x98\x14\x12\x17G\x177\x17\x9c4a\xc5\xc0d0\xc2\xccdLx\x02^@+\t\ 
1468 \xc1\x90\xf6r\xdb\xc6\x94\xe5:\\\xdbP)\xc5DOr\x92\x9b{\xff\xfb\xfd\xff9\xc6h\ 
1469 l+\xbek.\x02\x00\xec\x99\x03\x80\xeb\xf8\\\x9d\x1d\x1bd\xd5hl\xab\xd7O\x15\ 
1470 \xf7x\xa1\xfb\xeeq\xa4^>\x94\xba\xb8yRF.\xcf\xa6.D\xa0Nw\x18C\xad\xb2\x19\ 
1471 \x9f\x0f\xca\x165\xd1V\xed\xebZj\x92\xc2\\\x04\xec\x02\xd5\x8a\x89\xb7\xd4\ 
1472 \x97n\xa8\xe3?\x0f\x86\x08\x19dNP\x00\xf0\x96\xd0\x7f\xd0\t\x84\x0c(U-\x0eK&\ 
1473 \xd3P\x8bz\xcdV6 \x8a\xed\x86\x99f\xe9\x00{\xe6\xb0\x13\xc2\xa0\xd3\xd7\t\ 
1474 \x84\x9f\x10\xec\x9dTp\x1d\xb1=A\xa9j\x01\xc4\xb1\x01&\xfe\x9a~\x1d\xe0:Zu\ 
1475 \x7f\xdb\x05@J/!(\xd6\x1bL\xde\xec\xcd\x00!\x03\xa6!\x1c\x9dVR\x9d\xdf\xe5\ 
1476 \x96\x04\xd1au\xd3\xab3\xef\x9f_f\x03\xa2\xa5\x15\xeb\x8d\xc4\xc36\xe7\x18 \ 
1477 \xa5G\xaf\xd9J\xb8f\xcd\xfc\xb3\x0c#\x97\xff\xb58\xadr\x7f\xfa\xfd\x1f\x80/\ 
1478 \x04\x1f\x8fW\x0e^\xc3\x12\x00\x00\x00\x00IEND\xaeB`\x82"  
1481 def getTextBitmap(): 
1482     return BitmapFromImage(getTextImage()) 
1485     stream 
= cStringIO
.StringIO(getTextData()) 
1486     return ImageFromStream(stream
) 
1489     return wx
.IconFromBitmap(getTextBitmap()) 
1492 #---------------------------------------------------------------------------- 
1493 # Menu Bitmaps - generated by encode_bitmaps.py 
1494 #---------------------------------------------------------------------------- 
1495 #---------------------------------------------------------------------- 
1496 def getZoomInData(): 
1498 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ 
1499 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ 
1500 \x00\x01TIDAT8\x8d\x8d\x93\xbbJ\x03A\x14\x86\xbf\xd9,\xc6\xd8E%`)VF[{\xc1v\ 
1501 \xf1\x82\x8f\xb0\xb94\xda\xa5\x13\x11\x8b`\xa9h\x10F\xe3#H.\xa6\x15\xccKhg\ 
1502 \x10\xc1B\x8bTF\x90\xc0X\x8c3\xbb\xd9\xcdF\x7f\x18\xf6\xec\x9cs\xbe\xfd\xe70\ 
1503 +\x84\x93"\xacb\xc1W\xe1\xf7\xeb\xfa\x8d`\x82\xdcXcI\x8e\x02AM\x02\t\xe1\xa4\ 
1504 (\x16|uz)y\x19\xc0\xc9\xdd;\x99\xee!\x00\xd9\xbd\x00\xd6\xaf\x95\xc7B\xac\ 
1505 \x03\xd3\x1c\xd6\xc2t\x10\xf7\x13\x8e\xe0\x14\x0b\xbe\xa2$m\xf3\xca\xea\xacM\ 
1506 \xe6\xd2\xc1\xcaWdl>#\x0e\x8c\xed\xe7n\x90|\xa8\x96m\xbc~ y\x04Z\xcd\x86\xda\ 
1507 \xda\xde\xb1Gq\x00\xb2S\t\xfeB\x9aK\xa8\xb1\x0e\xf2\x15I.\xad\x0bo\x8f\xf4\ 
1508 \x97\xab\xe7z\x88\x1f\xdf\xf0\xfa9\x1e\xe0x\x9eG\xbf\x16X\xcd\xb8Ar\xc6\xd5\ 
1509 \x0b4\xd4\xf3\xbcd\x07F_\xc3 \x1e\x0c\xa3Y\x08\x9f\x1f~\xefA\xab\xd9P\x9dN\ 
1510 \x07\x80\xddcI\xc6\x85\xf9\xb4.8\xabhwK\xbd+6\x16\xf5\xdeZ=%F\x00\xa0\xa7\ 
1511 \x0b`@F\xc6\xf6\xd3\xc5&@\x0c"\xa2\xff\x82\x01\x85-\xb7\x9a\re\x00QH\x0c0N\ 
1512 \x06\x1a\x85\xbcym}\x0f\xfe\x92\x19\xdc\xf2~\xdb\xee\xdd\xf7\xf4\xf3_\x0e\ 
1513 \xa2N\xc2\xfa\x01MYp\xbc\xe4a\x0f\xa9\x00\x00\x00\x00IEND\xaeB`\x82'  
1515 def getZoomInBitmap(): 
1516     return BitmapFromImage(getZoomInImage()) 
1518 def getZoomInImage(): 
1519     stream 
= cStringIO
.StringIO(getZoomInData()) 
1520     return ImageFromStream(stream
) 
1522 #---------------------------------------------------------------------- 
1523 def getZoomOutData(): 
1525 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ 
1526 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ 
1527 \x00\x01RIDAT8\x8d\x8d\x93\xbbJ\x03A\x14\x86\xbf\xd9\x04\x93\x90J\x0cj#Dl\ 
1528 \xf4\x01\xec\x05\xdb\xc5\x0b>B\x92]\x1b+\xed,D\xb0\xb4\x08\x9afc|\x04\xc9\ 
1529 \x85\xb4>\x84\x95`\x93\x80`\x15\xd8*\x98\x84\xc0X\xcc\xce\xde7\xf8\xc30\x97=\ 
1530 \xf3\xcd\x7f\xce\xcc\na\xe4\x08\xabQ\xaf\xc9\xf0\xfc\xa5\xf3*X\xa1|b\xa3\xe5\ 
1531 D\x81 W\x81\x840r4\xea5\xf9\xf0\xe40Y@\xf3+\xf8\xb8\xbe\x16\x8c\xdd\x96\x9d\ 
1532 \n1\xf4\xc0\xdf\xdc\xb6\x01\xa8\xca\x19[\x05\xfc\x96%aY\x96\x0c\xdb\xae\xca\ 
1533 \x99\xea7\x8b\x91@w.\xf9x\xbcL\xb8\xf0k\xa0O\x1e{\xd31Q\x1d\xdd\xaaC\xfa\xbd\ 
1534 \xae<=;\xf7!F<\xd7,md\xc4\xf8\x0e\xf6\xaf\x1d\xb6\x8b*p\xa7\x0c\x95\xd0\x86\ 
1535 \xc9\x02\xbe\xa7\xe9\x00\xc34M\xdc\x96MA\xa8[,y\xc8r>h\x00ow6\xa6if;\x98K\ 
1536 \x95\xd6\xef\x12(\xc0t\x99~b8\x7f\xf0\xdeA\xbf\xd7\x95\xc3\xe1\x10\x80\x8b{\ 
1537 \x87R\x1e*\xde\xd55oTq\xf7Fm\x8ew\xd5\xdaa\'\'"\x00P\xd5\x05\xd0 -m\xfb\xf3\ 
1538 \xf9\x04 \x01\x11\xf1\x7fA\x83\xc2\x96\xfb\xbd\xae\xd4\x808$\x01H\x93\x86\ 
1539 \xc6!?\xe6 x\xca\xab\xa4\x0bwp5\xf0\xd7\xdeG\xaa\xff\x97\x83\xb8\x93\xb0\xfe\ 
1540 \x00\xc3\xa8ov\xfd\xe4\x9c\xa2\x00\x00\x00\x00IEND\xaeB`\x82'  
1543 def getZoomOutBitmap(): 
1544     return BitmapFromImage(getZoomOutImage()) 
1546 def getZoomOutImage(): 
1547     stream 
= cStringIO
.StringIO(getZoomOutData()) 
1548     return ImageFromStream(stream
)