1 #---------------------------------------------------------------------------- 
   2 # Name:         PythonEditor.py 
   3 # Purpose:      PythonEditor for wx.lib.pydocview tbat uses the Styled Text Control 
   9 # Copyright:    (c) 2004-2005 ActiveGrid, Inc. 
  10 # License:      wxWindows License 
  11 #---------------------------------------------------------------------------- 
  16 import wx
.lib
.pydocview
 
  18 import keyword  
# So it knows what to hilite 
  19 import wx
.py  
# For the Python interpreter 
  20 import wx
.stc 
# For the Python interpreter 
  21 import cStringIO  
# For indent 
  24 import keyword 
# for GetAutoCompleteKeywordList 
  25 import sys 
# for GetAutoCompleteKeywordList 
  26 import MessageService 
# for OnCheckCode 
  28 from UICommon 
import CaseInsensitiveCompare
 
  30     import checker 
# for pychecker 
  31     _CHECKER_INSTALLED 
= True 
  33     _CHECKER_INSTALLED 
= False 
  34 import os
.path 
# for pychecker 
  37 if wx
.Platform 
== '__WXMSW__': 
  43 VIEW_PYTHON_INTERPRETER_ID 
= wx
.NewId() 
  46 class PythonDocument(CodeEditor
.CodeDocument
): 
  50 class PythonView(CodeEditor
.CodeView
): 
  53     def GetCtrlClass(self
): 
  54         """ Used in split window to instantiate new instances """ 
  58     def ProcessUpdateUIEvent(self
, event
): 
  59         if not self
.GetCtrl(): 
  63         if id == CodeEditor
.CHECK_CODE_ID
: 
  64             hasText 
= self
.GetCtrl().GetTextLength() > 0 
  68         return CodeEditor
.CodeView
.ProcessUpdateUIEvent(self
, event
) 
  71     def OnActivateView(self
, activate
, activeView
, deactiveView
): 
  72         STCTextEditor
.TextView
.OnActivateView(self
, activate
, activeView
, deactiveView
) 
  73         if activate 
and self
.GetCtrl(): 
  74             if self
.GetDocumentManager().GetFlags() & wx
.lib
.docview
.DOC_SDI
: 
  77                 wx
.CallAfter(self
.LoadOutline
)  # need CallAfter because document isn't loaded yet 
  80     def OnClose(self
, deleteWindow 
= True): 
  81         status 
= STCTextEditor
.TextView
.OnClose(self
, deleteWindow
) 
  82         wx
.CallAfter(self
.ClearOutline
)  # need CallAfter because when closing the document, it is Activated and then Close, so need to match OnActivateView's CallAfter 
  86     def GetAutoCompleteKeywordList(self
, context
, hint
): 
  89             if context 
and len(context
): 
  90                 obj 
= eval(context
, globals(), locals()) 
  92             if not hint 
or len(hint
) == 0:  # context isn't valid, maybe it was the hint 
  96             kw 
= keyword
.kwlist
[:] 
  99             kw 
= filter(lambda item
: item
[0] != '_', symTbl
)  # remove local variables and methods 
 101         if hint 
and len(hint
): 
 102             lowerHint 
= hint
.lower() 
 103             filterkw 
= filter(lambda item
: item
.lower().startswith(lowerHint
), kw
)  # remove variables and methods that don't match hint 
 106         kw
.sort(CaseInsensitiveCompare
) 
 109             replaceLen 
= len(hint
) 
 113         return " ".join(kw
), replaceLen
 
 116     def OnCheckCode(self
): 
 117         if not _CHECKER_INSTALLED
:        
 118             wx
.MessageBox(_("pychecker not found.  Please install pychecker."), _("Check Code")) 
 121         filename 
= os
.path
.basename(self
.GetDocument().GetFilename()) 
 123         # pychecker only works on files, doesn't take a stream or string input 
 124         if self
.GetDocument().IsModified(): 
 125             dlg 
= wx
.MessageDialog(self
.GetFrame(), _("'%s' has been modfied and must be saved first.  Save file and check code?") % filename
, _("Check Code")) 
 127             val 
= dlg
.ShowModal() 
 130                 self
.GetDocument().Save() 
 134         messageService 
= wx
.GetApp().GetService(MessageService
.MessageService
) 
 135         messageService
.ShowWindow() 
 136         view 
= messageService
.GetView() 
 141         view
.SetCallback(self
.OnJumpToFoundLine
) 
 143         # Set cursor to Wait cursor 
 144         wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_WAIT
)) 
 146         # This takes a while for involved code 
 147         checker
.checkSyntax(self
.GetDocument().GetFilename(), view
) 
 149         # Set cursor to Default cursor 
 150         wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_DEFAULT
)) 
 153     def OnJumpToFoundLine(self
, event
): 
 154         messageService 
= wx
.GetApp().GetService(MessageService
.MessageService
) 
 155         lineText
, pos 
= messageService
.GetView().GetCurrLine() 
 157         lineEnd 
= lineText
.find(".py:") 
 161         lineStart 
= lineEnd 
+ len(".py:") 
 162         lineEnd 
= lineText
.find(":", lineStart
) 
 163         lineNum 
= int(lineText
[lineStart
:lineEnd
]) 
 165         filename 
= lineText
[0:lineStart 
- 1] 
 168         openDocs 
= wx
.GetApp().GetDocumentManager().GetDocuments() 
 169         for openDoc 
in openDocs
: 
 170             if openDoc
.GetFilename() == filename
: 
 171                 foundView 
= openDoc
.GetFirstView() 
 175             doc 
= wx
.GetApp().GetDocumentManager().CreateDocument(filename
, wx
.lib
.docview
.DOC_SILENT|wx
.lib
.docview
.DOC_OPEN_ONCE
) 
 176             foundView 
= doc
.GetFirstView() 
 179             foundView
.GetFrame().SetFocus() 
 181             foundView
.GotoLine(lineNum
) 
 182             startPos 
= foundView
.PositionFromLine(lineNum
) 
 183             endPos 
= foundView
.GetLineEndPosition(lineNum
) 
 184             # wxBug:  Need to select in reverse order, (end, start) to put cursor at head of line so positioning is correct 
 185             #         Also, if we use the correct positioning order (start, end), somehow, when we open a edit window for the first 
 186             #         time, we don't see the selection, it is scrolled off screen 
 187             foundView
.SetSelection(endPos
, startPos
) 
 188             wx
.GetApp().GetService(OutlineService
.OutlineService
).LoadOutline(foundView
, position
=startPos
) 
 192 class PythonInterpreterView(wx
.lib
.docview
.View
): 
 195     def OnCreate(self
, doc
, flags
): 
 196         frame 
= wx
.GetApp().CreateDocumentFrame(self
, doc
, flags
) 
 197         sizer 
= wx
.BoxSizer()         
 198         self
._pyCrust 
= wx
.py
.crust
.Crust(frame
) 
 199         sizer
.Add(self
._pyCrust
, 1, wx
.EXPAND
, 0) 
 200         frame
.SetSizer(sizer
) 
 207     def ProcessEvent(self
, event
): 
 208         if not hasattr(self
, "_pyCrust") or not self
._pyCrust
: 
 209             return wx
.lib
.docview
.View
.ProcessEvent(self
, event
) 
 210         stcControl 
= wx
.Window_FindFocus() 
 211         if not isinstance(stcControl
, wx
.stc
.StyledTextCtrl
): 
 212             return wx
.lib
.docview
.View
.ProcessEvent(self
, event
) 
 217         elif id == wx
.ID_REDO
: 
 220         elif id == wx
.ID_CUT
: 
 223         elif id == wx
.ID_COPY
: 
 226         elif id == wx
.ID_PASTE
: 
 229         elif id == wx
.ID_CLEAR
: 
 232         elif id == wx
.ID_SELECTALL
: 
 233             stcControl
.SetSelection(0, -1) 
 236             return wx
.lib
.docview
.View
.ProcessEvent(self
, event
) 
 239     def ProcessUpdateUIEvent(self
, event
): 
 240         if not hasattr(self
, "_pyCrust") or not self
._pyCrust
: 
 241             return wx
.lib
.docview
.View
.ProcessUpdateUIEvent(self
, event
) 
 242         stcControl 
= wx
.Window_FindFocus() 
 243         if not isinstance(stcControl
, wx
.stc
.StyledTextCtrl
): 
 244             return wx
.lib
.docview
.View
.ProcessUpdateUIEvent(self
, event
) 
 247             event
.Enable(stcControl
.CanUndo()) 
 249         elif id == wx
.ID_REDO
: 
 250             event
.Enable(stcControl
.CanRedo()) 
 252         elif id == wx
.ID_CUT
: 
 253             event
.Enable(stcControl
.CanCut()) 
 255         elif id == wx
.ID_COPY
: 
 256             event
.Enable(stcControl
.CanCopy()) 
 258         elif id == wx
.ID_PASTE
: 
 259             event
.Enable(stcControl
.CanPaste()) 
 261         elif id == wx
.ID_CLEAR
: 
 262             event
.Enable(True)  # wxBug: should be stcControl.CanCut()) but disabling clear item means del key doesn't work in control as expected 
 264         elif id == wx
.ID_SELECTALL
: 
 265             event
.Enable(stcControl
.GetTextLength() > 0) 
 268             return wx
.lib
.docview
.View
.ProcessUpdateUIEvent(self
, event
) 
 271     def OnClose(self
, deleteWindow
=True): 
 272         if deleteWindow 
and self
.GetFrame(): 
 273             self
.GetFrame().Destroy() 
 277 class PythonInterpreterDocument(wx
.lib
.docview
.Document
): 
 278     """ Generate Unique Doc Type """ 
 282 class PythonService(CodeEditor
.CodeService
): 
 286         CodeEditor
.CodeService
.__init
__(self
) 
 287         docManager 
= wx
.GetApp().GetDocumentManager() 
 288         pythonInterpreterTemplate 
= wx
.lib
.docview
.DocTemplate(docManager
, 
 289                                           _("Python Interpreter"), 
 293                                           _("Python Interpreter Document"), 
 294                                           _("Python Interpreter View"), 
 295                                           PythonInterpreterDocument
, 
 296                                           PythonInterpreterView
, 
 297                                           flags 
= wx
.lib
.docview
.TEMPLATE_INVISIBLE
, 
 298                                           icon 
= getPythonIcon()) 
 299         docManager
.AssociateTemplate(pythonInterpreterTemplate
) 
 302     def InstallControls(self
, frame
, menuBar 
= None, toolBar 
= None, statusBar 
= None, document 
= None): 
 303         CodeEditor
.CodeService
.InstallControls(self
, frame
, menuBar
, toolBar
, statusBar
, document
) 
 305         if document 
and document
.GetDocumentTemplate().GetDocumentType() != PythonDocument
: 
 307         if not document 
and wx
.GetApp().GetDocumentManager().GetFlags() & wx
.lib
.docview
.DOC_SDI
: 
 310         viewMenu 
= menuBar
.GetMenu(menuBar
.FindMenu(_("&View"))) 
 312         viewStatusBarItemPos 
= self
.GetMenuItemPos(viewMenu
, wx
.lib
.pydocview
.VIEW_STATUSBAR_ID
) 
 313         viewMenu
.InsertCheckItem(viewStatusBarItemPos 
+ 1, VIEW_PYTHON_INTERPRETER_ID
, _("Python &Interpreter"), _("Shows or hides the Python interactive window")) 
 314         wx
.EVT_MENU(frame
, VIEW_PYTHON_INTERPRETER_ID
, frame
.ProcessEvent
) 
 315         wx
.EVT_UPDATE_UI(frame
, VIEW_PYTHON_INTERPRETER_ID
, frame
.ProcessUpdateUIEvent
) 
 318     def ProcessEvent(self
, event
): 
 320         if id == VIEW_PYTHON_INTERPRETER_ID
: 
 321             self
.OnViewPythonInterpreter(event
) 
 324             return CodeEditor
.CodeService
.ProcessEvent(self
, event
) 
 327     def ProcessUpdateUIEvent(self
, event
): 
 329         if id == VIEW_PYTHON_INTERPRETER_ID
: 
 331             docManager 
= wx
.GetApp().GetDocumentManager() 
 333             for doc 
in docManager
.GetDocuments(): 
 334                 if isinstance(doc
, PythonInterpreterDocument
): 
 339             return CodeEditor
.CodeService
.ProcessUpdateUIEvent(self
, event
) 
 342     def OnViewPythonInterpreter(self
, event
): 
 343         for doc 
in wx
.GetApp().GetDocumentManager().GetDocuments(): 
 344             if isinstance(doc
, PythonInterpreterDocument
): 
 348         for template 
in self
.GetDocumentManager().GetTemplates(): 
 349             if template
.GetDocumentType() == PythonInterpreterDocument
: 
 350                 newDoc 
= template
.CreateDocument('', wx
.lib
.docview
.DOC_SILENT|wx
.lib
.docview
.DOC_OPEN_ONCE
) 
 352                     newDoc
.SetDocumentName(template
.GetDocumentName()) 
 353                     newDoc
.SetDocumentTemplate(template
) 
 354                     newDoc
.OnNewDocument() 
 355                     newDoc
.SetWriteable(False) 
 356                     newDoc
.GetFirstView().GetFrame().SetTitle(_("Python Interpreter")) 
 360 class PythonCtrl(CodeEditor
.CodeCtrl
): 
 363     def __init__(self
, parent
, id=-1, style
=wx
.NO_FULL_REPAINT_ON_RESIZE
): 
 364         CodeEditor
.CodeCtrl
.__init
__(self
, parent
, id, style
) 
 365         self
.SetProperty("tab.timmy.whinge.level", "1") 
 366         self
.SetProperty("fold.comment.python", "1") 
 367         self
.SetProperty("fold.quotes.python", "1") 
 368         self
.SetLexer(wx
.stc
.STC_LEX_PYTHON
) 
 369         self
.SetKeyWords(0, string
.join(keyword
.kwlist
)) 
 372     def SetViewDefaults(self
): 
 373         CodeEditor
.CodeCtrl
.SetViewDefaults(self
, configPrefix 
= "Python", hasWordWrap 
= True, hasTabs 
= True) 
 376     def GetFontAndColorFromConfig(self
): 
 377         return CodeEditor
.CodeCtrl
.GetFontAndColorFromConfig(self
, configPrefix 
= "Python") 
 380     def UpdateStyles(self
): 
 381         CodeEditor
.CodeCtrl
.UpdateStyles(self
) 
 383         if not self
.GetFont(): 
 386         faces 
= { 'font' : self
.GetFont().GetFaceName(), 
 387                   'size' : self
.GetFont().GetPointSize(), 
 388                   'size2': self
.GetFont().GetPointSize() - 2, 
 389                   'color' : "%02x%02x%02x" % (self
.GetFontColor().Red(), self
.GetFontColor().Green(), self
.GetFontColor().Blue()) 
 394         self
.StyleSetSpec(wx
.stc
.STC_P_DEFAULT
, "face:%(font)s,fore:#000000,face:%(font)s,size:%(size)d" % faces
) 
 396         self
.StyleSetSpec(wx
.stc
.STC_P_COMMENTLINE
, "face:%(font)s,fore:#007F00,italic,face:%(font)s,size:%(size)d" % faces
) 
 398         self
.StyleSetSpec(wx
.stc
.STC_P_NUMBER
, "face:%(font)s,fore:#007F7F,size:%(size)d" % faces
) 
 400         self
.StyleSetSpec(wx
.stc
.STC_P_STRING
, "face:%(font)s,fore:#7F007F,face:%(font)s,size:%(size)d" % faces
) 
 401         # Single quoted string 
 402         self
.StyleSetSpec(wx
.stc
.STC_P_CHARACTER
, "face:%(font)s,fore:#7F007F,face:%(font)s,size:%(size)d" % faces
) 
 404         self
.StyleSetSpec(wx
.stc
.STC_P_WORD
, "face:%(font)s,fore:#00007F,bold,size:%(size)d" % faces
) 
 406         self
.StyleSetSpec(wx
.stc
.STC_P_TRIPLE
, "face:%(font)s,fore:#7F0000,size:%(size)d" % faces
) 
 407         # Triple double quotes 
 408         self
.StyleSetSpec(wx
.stc
.STC_P_TRIPLEDOUBLE
, "face:%(font)s,fore:#7F0000,size:%(size)d" % faces
) 
 409         # Class name definition 
 410         self
.StyleSetSpec(wx
.stc
.STC_P_CLASSNAME
, "face:%(font)s,fore:#0000FF,bold,size:%(size)d" % faces
) 
 411         # Function or method name definition 
 412         self
.StyleSetSpec(wx
.stc
.STC_P_DEFNAME
, "face:%(font)s,fore:#007F7F,bold,size:%(size)d" % faces
) 
 414         self
.StyleSetSpec(wx
.stc
.STC_P_OPERATOR
, "face:%(font)s,size:%(size)d" % faces
) 
 416         self
.StyleSetSpec(wx
.stc
.STC_P_IDENTIFIER
, "face:%(font)s,fore:#%(color)s,face:%(font)s,size:%(size)d" % faces
) 
 418         self
.StyleSetSpec(wx
.stc
.STC_P_COMMENTBLOCK
, "face:%(font)s,fore:#7F7F7F,size:%(size)d" % faces
) 
 419         # End of line where string is not closed 
 420         self
.StyleSetSpec(wx
.stc
.STC_P_STRINGEOL
, "face:%(font)s,fore:#000000,face:%(font)s,back:#E0C0E0,eol,size:%(size)d" % faces
) 
 423     def OnUpdateUI(self
, evt
): 
 424         braces 
= self
.GetMatchingBraces() 
 426         # check for matching braces 
 430         caretPos 
= self
.GetCurrentPos() 
 432             charBefore 
= self
.GetCharAt(caretPos 
- 1) 
 433             styleBefore 
= self
.GetStyleAt(caretPos 
- 1) 
 436         if charBefore 
and chr(charBefore
) in braces 
and styleBefore 
== wx
.stc
.STC_P_OPERATOR
: 
 437             braceAtCaret 
= caretPos 
- 1 
 441             charAfter 
= self
.GetCharAt(caretPos
) 
 442             styleAfter 
= self
.GetStyleAt(caretPos
) 
 443             if charAfter 
and chr(charAfter
) in braces 
and styleAfter 
== wx
.stc
.STC_P_OPERATOR
: 
 444                 braceAtCaret 
= caretPos
 
 446         if braceAtCaret 
>= 0: 
 447             braceOpposite 
= self
.BraceMatch(braceAtCaret
) 
 449         if braceAtCaret 
!= -1  and braceOpposite 
== -1: 
 450             self
.BraceBadLight(braceAtCaret
) 
 452             self
.BraceHighlight(braceAtCaret
, braceOpposite
) 
 458         (text
, caretPos
) = self
.GetCurLine() 
 460         self
._tokenizerChars 
= {}  # This is really too much, need to find something more like a C array 
 461         for i 
in range(len(text
)): 
 462             self
._tokenizerChars
[i
] = 0 
 464         ctext 
= cStringIO
.StringIO(text
) 
 466             tokenize
.tokenize(ctext
.readline
, self
) 
 470         # Left in for debugging purposes: 
 471         #for i in range(len(text)): 
 472         #    print i, text[i], self._tokenizerChars[i] 
 474         if caretPos 
== 0 or len(string
.strip(text
)) == 0:  # At beginning of line or within an empty line 
 477             doExtraIndent 
= False 
 483                 startSquareBracketCount 
= 0 
 484                 endSquareBracketCount 
= 0 
 485                 startCurlyBracketCount 
= 0 
 486                 endCurlyBracketCount 
= 0 
 489                 for i 
in range(caretPos 
- 1, -1, -1): # Go through each character before the caret 
 490                     if i 
>= len(text
): # Sometimes the caret is at the end of the text if there is no LF 
 492                     if self
._tokenizerChars
[i
] == 1: 
 494                     elif self
._tokenizerChars
[i
] == 2: 
 495                         startQuoteCount 
= startQuoteCount 
+ 1 
 496                     elif self
._tokenizerChars
[i
] == 3: 
 497                         endQuoteCount 
= endQuoteCount 
+ 1 
 498                     elif text
[i
] == '(': # Would be nice to use a dict for this, but the code is much more readable this way 
 499                         startParenCount 
= startParenCount 
+ 1 
 501                         endParenCount 
= endParenCount 
+ 1 
 503                         startSquareBracketCount 
= startSquareBracketCount 
+ 1 
 505                         endSquareBracketCount 
= endSquareBracketCount 
+ 1 
 507                         startCurlyBracketCount 
= startCurlyBracketCount 
+ 1 
 509                         endCurlyBracketCount 
= endCurlyBracketCount 
+ 1 
 513                     if startQuoteCount 
> endQuoteCount 
or startParenCount 
> endParenCount 
or startSquareBracketCount 
> endSquareBracketCount 
or startCurlyBracketCount 
> endCurlyBracketCount
: 
 514                         if i 
+ 1 >= caretPos
:  # Caret is right at the open paren, so just do indent as if colon was there 
 518                             spaces 
= " " * (i 
+ 1) 
 522                 spaces 
= text
[0:len(text
) - len(string
.lstrip(text
))] 
 523                 if caretPos 
< len(spaces
):  # If within the opening spaces of a line 
 524                     spaces 
= spaces
[:caretPos
] 
 527                 if commentStart 
!= -1: 
 528                     text 
= text
[0:commentStart
] 
 530                 textNoTrailingSpaces 
= text
[0:caretPos
].rstrip() 
 531                 if doExtraIndent 
or len(textNoTrailingSpaces
) and textNoTrailingSpaces
[-1] == ':': 
 532                     spaces 
= spaces 
+ ' ' * self
.GetIndent() 
 533             self
.AddText('\n' + spaces
) 
 534         self
.EnsureCaretVisible() 
 537     # Callback for tokenizer in self.DoIndent 
 538     def __call__(self
, toktype
, toktext
, (srow
,scol
), (erow
,ecol
), line
): 
 539         if toktype 
== tokenize
.COMMENT
: 
 540             for i 
in range(scol
, ecol 
+ 1): 
 541                 self
._validChars
[i
] = False 
 542         elif toktype 
== token
.STRING
: 
 543             self
._tokenizerChars
[scol
] = 2 # Open quote 
 544             self
._tokenizerChars
[ecol 
- 1] = 3 # Close quote 
 545             for i 
in range(scol 
+ 1, ecol 
- 2): 
 546                 self
._tokenizerChars
[i
] = 1 # Part of string, 1 == ignore the char 
 549 class PythonOptionsPanel(wx
.Panel
): 
 551     def __init__(self
, parent
, id): 
 552         wx
.Panel
.__init
__(self
, parent
, id) 
 553         pathLabel 
= wx
.StaticText(self
, -1, _("python.exe Path:")) 
 554         config 
= wx
.ConfigBase_Get() 
 555         path 
= config
.Read("ActiveGridPythonLocation") 
 556         self
._pathTextCtrl 
= wx
.TextCtrl(self
, -1, path
, size 
= (150, -1)) 
 557         self
._pathTextCtrl
.SetToolTipString(self
._pathTextCtrl
.GetValue()) 
 558         self
._pathTextCtrl
.SetInsertionPointEnd() 
 559         choosePathButton 
= wx
.Button(self
, -1, _("Browse...")) 
 560         pathSizer 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
 563         pathSizer
.Add(pathLabel
, 0, wx
.ALIGN_CENTER_VERTICAL|wx
.LEFT|wx
.TOP
, HALF_SPACE
) 
 564         pathSizer
.Add(self
._pathTextCtrl
, 1, wx
.EXPAND|wx
.LEFT|wx
.TOP
, HALF_SPACE
) 
 565         pathSizer
.Add(choosePathButton
, 0, wx
.ALIGN_RIGHT|wx
.LEFT|wx
.RIGHT|wx
.TOP
, HALF_SPACE
) 
 566         wx
.EVT_BUTTON(self
, choosePathButton
.GetId(), self
.OnChoosePath
) 
 567         mainSizer 
= wx
.BoxSizer(wx
.VERTICAL
)                 
 568         mainSizer
.Add(pathSizer
, 0, wx
.EXPAND|wx
.LEFT|wx
.RIGHT|wx
.TOP
, SPACE
) 
 570         self
._otherOptions 
= STCTextEditor
.TextOptionsPanel(self
, -1, configPrefix 
= "Python", label 
= "Python", hasWordWrap 
= True, hasTabs 
= True, addPage
=False) 
 571         mainSizer
.Add(self
._otherOptions
, 0, wx
.EXPAND|wx
.BOTTOM
, SPACE
) 
 572         self
.SetSizer(mainSizer
) 
 573         parent
.AddPage(self
, _("Python")) 
 576     def OnChoosePath(self
, event
): 
 577         defaultDir 
= os
.path
.dirname(self
._pathTextCtrl
.GetValue().strip()) 
 578         defaultFile 
= os
.path
.basename(self
._pathTextCtrl
.GetValue().strip()) 
 580             wildcard 
= _("Executable (*.exe)|*.exe|All (*.*)|*.*") 
 582                 defaultFile 
= "python.exe" 
 585         dlg 
= wx
.FileDialog(wx
.GetApp().GetTopWindow(), 
 587                                defaultDir
=defaultDir
, 
 588                                defaultFile
=defaultFile
, 
 590                                style
=wx
.OPEN|wx
.FILE_MUST_EXIST|wx
.HIDE_READONLY
) 
 591         # dlg.CenterOnParent()  # wxBug: caused crash with wx.FileDialog 
 592         if dlg
.ShowModal() == wx
.ID_OK
: 
 595                 self
._pathTextCtrl
.SetValue(path
) 
 596                 self
._pathTextCtrl
.SetToolTipString(self
._pathTextCtrl
.GetValue()) 
 597                 self
._pathTextCtrl
.SetInsertionPointEnd() 
 601     def OnOK(self
, optionsDialog
): 
 602         config 
= wx
.ConfigBase_Get() 
 603         config
.Write("ActiveGridPythonLocation", self
._pathTextCtrl
.GetValue().strip()) 
 605         self
._otherOptions
.OnOK(optionsDialog
) 
 609         return getPythonIcon() 
 612 #---------------------------------------------------------------------------- 
 613 # Icon Bitmaps - generated by encode_bitmaps.py 
 614 #---------------------------------------------------------------------------- 
 615 from wx 
import ImageFromStream
, BitmapFromImage
 
 621 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ 
 622 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ 
 623 \x00\x01\xe7IDAT8\x8d}\x921h\x13Q\x18\xc7\x7fw\xb9\x0ei\x9d*\xbd\xeb\x10\x8f\ 
 624 ,\x99\x1c*A[\xaa\x19B\xe8\xd0\xb1\x0e%K\x87\x88T2\x88Cqp\tD\x14i\xe9\xe0V\ 
 625 \xdaQ\xb7\xe0P\xa1\x8b\xa0(\x95$z\xd5Q1\x90\xa2\xd7\x9a4^\x87\xa0`\x92!w9\ 
 626 \x87\xf8.\xb9\xa6\xc97\xbd\xef{\xef\xfb\xbd\xff\xfb\xbfO*~;v\xf9\x1f\xad\xba\ 
 627 \x05@\xf9\xd4\x06\xc0::$\xbb\x96\x92\x18\x11\n@(4\xdd\xcdB\xd3\xd4\x1d\x85\ 
 628 \x8b\x97\xe1\xe3;\x83\x99\xe5\x15\xb2\xe0\x8e\x82\xc8\xa3\xe8\x003\xcb+\xac\ 
 629 \xaee\xdda\xfb\xb2\x90\rPw\x14\x00\x9a\xb5\n\xbf\xfflSz\x9d\xa2Y\xdc"zca\xe8\ 
 630 \x05\xb2h\x14\xcd\xd0\xf3B\x9f\x98\xe5\xf9\xde\x13"\xaaB\xc7\xb1\xcfU!\x0b\ 
 631 \xc3D4k\x15\xac\x93\x03\xf4\x89Y\xaf\x96\xffT\x028\x17\xa2\xf4\'\xcdZ\x85\ 
 632 \xf7F\x06{\xaa\x80ev\xc1\x91\xb91>\x18\x0f\xb8\xb7\x95a\xe9\xca\x0b:\x8e\xed\ 
 633 \xca\x01E\x1a\x00\x98\r\x89\x92\x91\xa1\xda\xd8\x87\x06ha\x1f\x1b\x80\xcd\ 
 634 \x9d%\xe0\xa5\x0f"[G\x87\x98\x8d\xde/ia\x05-\xac`\x996\xf9\\\x0b\xcb\xb4)\ 
 635 \x1bmOMn\xf7\xd5\xf0\'\\\x8b\xdces\xe7\x8d\xef\x80h\xd6\xc2\n\xf9\\\x0b]\xf5\ 
 636 \xab\xf2\xcdApR#\xf1kp4b\xc9 \xf9\\\x0b\x80\xe4\xcdE\xaf\xdeqlW\xaeVL\xaf`~\ 
 637 \xd9\x03@W\xd3\x00\xc4\x13\x0b\xc4\x92A\xcf\xd0\xf9\xe8:\x89\xebW\x01(|\xfd\ 
 638 \xe1\xbe-~F\xbas\xff\x91\xf75\x82n\x9d\x1c\xf0}\xfciw\xdd\xe7A<\xd1\x1b\xa8j\ 
 639 c\x9f\xb2\xd1F\x92\xe4\x80O\x12\xc0\xc6\xb3\x14\xf6Ta\xe0)g\x81\xba\x9a\xf6\ 
 640 \x9b(\x07\x14I@\x84lq\xb8?\xe6\xa3\xeb\x00\xdc\xba\x9d\xf4+\x10*~\xfem\xf3\ 
 641 \xf8\xe1\x06\xc7\xa7\xdb\xe8j\x9a\xf8\xdc\xa4\xb7\x1f[\\\xe5\xd2\x851/\xff\ 
 642 \x07\xac\x9b\xd1e\x12\x96\x0f\xfd\x00\x00\x00\x00IEND\xaeB`\x82'  
 645 def getPythonBitmap(): 
 646     return BitmapFromImage(getPythonImage()) 
 648 def getPythonImage(): 
 649     stream 
= cStringIO
.StringIO(getPythonData()) 
 650     return ImageFromStream(stream
) 
 653     return wx
.IconFromBitmap(getPythonBitmap())