]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/samples/ide/activegrid/tool/FindInDirService.py
1 #----------------------------------------------------------------------------
2 # Name: IDEFindService.py
3 # Purpose: Find Service for pydocview
9 # Copyright: (c) 2004-2005 ActiveGrid, Inc.
10 # License: wxWindows License
11 #----------------------------------------------------------------------------
16 from os
. path
import join
25 #----------------------------------------------------------------------------
27 #----------------------------------------------------------------------------
28 FILENAME_MARKER
= _ ( "Found in file: " )
29 PROJECT_MARKER
= _ ( "Searching project: " )
30 FIND_MATCHDIR
= "FindMatchDir"
31 FIND_MATCHDIRSUBFOLDERS
= "FindMatchDirSubfolders"
37 class FindInDirService ( FindService
. FindService
):
39 #----------------------------------------------------------------------------
41 #----------------------------------------------------------------------------
42 FINDALL_ID
= wx
. NewId () # for bringing up Find All dialog box
43 FINDDIR_ID
= wx
. NewId () # for bringing up Find Dir dialog box
46 def InstallControls ( self
, frame
, menuBar
= None , toolBar
= None , statusBar
= None , document
= None ):
47 FindService
. FindService
. InstallControls ( self
, frame
, menuBar
, toolBar
, statusBar
, document
)
49 editMenu
= menuBar
. GetMenu ( menuBar
. FindMenu ( _ ( "&Edit" )))
50 wx
. EVT_MENU ( frame
, FindInDirService
. FINDALL_ID
, self
. ProcessEvent
)
51 wx
. EVT_UPDATE_UI ( frame
, FindInDirService
. FINDALL_ID
, self
. ProcessUpdateUIEvent
)
52 editMenu
. Append ( FindInDirService
. FINDALL_ID
, _ ( "Find in Project... \t Ctrl+Shift+F" ), _ ( "Searches for the specified text in all the files in the project" ))
53 wx
. EVT_MENU ( frame
, FindInDirService
. FINDDIR_ID
, self
. ProcessEvent
)
54 wx
. EVT_UPDATE_UI ( frame
, FindInDirService
. FINDDIR_ID
, self
. ProcessUpdateUIEvent
)
55 editMenu
. Append ( FindInDirService
. FINDDIR_ID
, _ ( "Find in Directory..." ), _ ( "Searches for the specified text in all the files in the directory" ))
58 def ProcessEvent ( self
, event
):
60 if id == FindInDirService
. FINDALL_ID
:
61 view
= wx
. GetApp (). GetDocumentManager (). GetCurrentView ()
62 if hasattr ( view
, "GetCtrl" ) and view
. GetCtrl () and hasattr ( view
. GetCtrl (), "GetSelectedText" ):
63 self
. ShowFindAllDialog ( view
. GetCtrl (). GetSelectedText ())
65 self
. ShowFindAllDialog ()
67 elif id == FindInDirService
. FINDDIR_ID
:
68 view
= wx
. GetApp (). GetDocumentManager (). GetCurrentView ()
69 if hasattr ( view
, "GetCtrl" ) and view
. GetCtrl () and hasattr ( view
. GetCtrl (), "GetSelectedText" ):
70 self
. ShowFindDirDialog ( view
. GetCtrl (). GetSelectedText ())
72 self
. ShowFindDirDialog ()
75 return FindService
. FindService
. ProcessEvent ( self
, event
)
78 def ProcessUpdateUIEvent ( self
, event
):
80 if id == FindInDirService
. FINDALL_ID
:
81 projectService
= wx
. GetApp (). GetService ( ProjectEditor
. ProjectService
)
82 if projectService
. GetFilesFromCurrentProject ():
87 elif id == FindInDirService
. FINDDIR_ID
:
90 return FindService
. FindService
. ProcessUpdateUIEvent ( self
, event
)
93 def ShowFindDirDialog ( self
, findString
= None ):
94 config
= wx
. ConfigBase_Get ()
96 frame
= wx
. Dialog ( wx
. GetApp (). GetTopWindow (), - 1 , _ ( "Find in Directory" ), size
= ( 320 , 200 ))
97 borderSizer
= wx
. BoxSizer ( wx
. HORIZONTAL
)
99 contentSizer
= wx
. BoxSizer ( wx
. VERTICAL
)
100 lineSizer
= wx
. BoxSizer ( wx
. HORIZONTAL
)
101 lineSizer
. Add ( wx
. StaticText ( frame
, - 1 , _ ( "Directory:" )), 0 , wx
. ALIGN_CENTER | wx
. RIGHT
, HALF_SPACE
)
102 dirCtrl
= wx
. TextCtrl ( frame
, - 1 , config
. Read ( FIND_MATCHDIR
, "" ), size
=( 200 ,- 1 ))
103 dirCtrl
. SetToolTipString ( dirCtrl
. GetValue ())
104 lineSizer
. Add ( dirCtrl
, 0 , wx
. LEFT
, HALF_SPACE
)
105 findDirButton
= wx
. Button ( frame
, - 1 , _ ( "Browse..." ))
106 lineSizer
. Add ( findDirButton
, 0 , wx
. LEFT
, HALF_SPACE
)
107 contentSizer
. Add ( lineSizer
, 0 , wx
. BOTTOM
, SPACE
)
109 def OnBrowseButton ( event
):
110 dlg
= wx
. DirDialog ( frame
, _ ( "Choose a directory:" ), style
= wx
. DD_DEFAULT_STYLE
)
111 dir = dirCtrl
. GetValue ()
115 if dlg
. ShowModal () == wx
. ID_OK
:
116 dirCtrl
. SetValue ( dlg
. GetPath ())
117 dirCtrl
. SetToolTipString ( dirCtrl
. GetValue ())
118 dirCtrl
. SetInsertionPointEnd ()
120 wx
. EVT_BUTTON ( findDirButton
, - 1 , OnBrowseButton
)
122 subfolderCtrl
= wx
. CheckBox ( frame
, - 1 , _ ( "Search in subdirectories" ))
123 subfolderCtrl
. SetValue ( config
. ReadInt ( FIND_MATCHDIRSUBFOLDERS
, True ))
124 contentSizer
. Add ( subfolderCtrl
, 0 , wx
. BOTTOM
, SPACE
)
126 lineSizer
= wx
. BoxSizer ( wx
. VERTICAL
) # let the line expand horizontally without vertical expansion
127 lineSizer
. Add ( wx
. StaticLine ( frame
, - 1 , size
= ( 10 ,- 1 )), 0 , flag
= wx
. EXPAND
)
128 contentSizer
. Add ( lineSizer
, flag
= wx
. EXPAND|wx
. ALIGN_CENTER_VERTICAL|wx
. BOTTOM
, border
= HALF_SPACE
)
130 if wx
. Platform
== "__WXMAC__" :
131 contentSizer
. Add ((- 1 , 10 ), 0 , wx
. EXPAND
)
133 lineSizer
= wx
. BoxSizer ( wx
. HORIZONTAL
)
134 lineSizer
. Add ( wx
. StaticText ( frame
, - 1 , _ ( "Find what:" )), 0 , wx
. ALIGN_CENTER | wx
. RIGHT
, HALF_SPACE
)
136 findString
= config
. Read ( FindService
. FIND_MATCHPATTERN
, "" )
137 findCtrl
= wx
. TextCtrl ( frame
, - 1 , findString
, size
=( 200 ,- 1 ))
139 findCtrl
. SetSelection ( 0 ,- 1 )
140 lineSizer
. Add ( findCtrl
, 0 , wx
. LEFT
, HALF_SPACE
)
141 contentSizer
. Add ( lineSizer
, 0 , wx
. BOTTOM
, SPACE
)
142 wholeWordCtrl
= wx
. CheckBox ( frame
, - 1 , _ ( "Match whole word only" ))
143 wholeWordCtrl
. SetValue ( config
. ReadInt ( FindService
. FIND_MATCHWHOLEWORD
, False ))
144 matchCaseCtrl
= wx
. CheckBox ( frame
, - 1 , _ ( "Match case" ))
145 matchCaseCtrl
. SetValue ( config
. ReadInt ( FindService
. FIND_MATCHCASE
, False ))
146 regExprCtrl
= wx
. CheckBox ( frame
, - 1 , _ ( "Regular expression" ))
147 regExprCtrl
. SetValue ( config
. ReadInt ( FindService
. FIND_MATCHREGEXPR
, False ))
148 contentSizer
. Add ( wholeWordCtrl
, 0 , wx
. BOTTOM
, SPACE
)
149 contentSizer
. Add ( matchCaseCtrl
, 0 , wx
. BOTTOM
, SPACE
)
150 contentSizer
. Add ( regExprCtrl
, 0 , wx
. BOTTOM
, SPACE
)
151 borderSizer
. Add ( contentSizer
, 0 , wx
. TOP | wx
. BOTTOM | wx
. LEFT
, SPACE
)
153 buttonSizer
= wx
. BoxSizer ( wx
. VERTICAL
)
154 findBtn
= wx
. Button ( frame
, wx
. ID_OK
, _ ( "Find" ))
156 BTM_SPACE
= HALF_SPACE
157 if wx
. Platform
== "__WXMAC__" :
159 buttonSizer
. Add ( findBtn
, 0 , wx
. BOTTOM
, BTM_SPACE
)
160 buttonSizer
. Add ( wx
. Button ( frame
, wx
. ID_CANCEL
), 0 )
161 borderSizer
. Add ( buttonSizer
, 0 , wx
. ALL
, SPACE
)
163 frame
. SetSizer ( borderSizer
)
166 frame
. CenterOnParent ()
167 status
= frame
. ShowModal ()
170 while status
== wx
. ID_OK
and not passedCheck
:
171 if not os
. path
. exists ( dirCtrl
. GetValue ()):
172 dlg
= wx
. MessageDialog ( frame
,
173 _ ( "' %s ' does not exist." ) % dirCtrl
. GetValue (),
174 _ ( "Find in Directory" ),
175 wx
. OK | wx
. ICON_EXCLAMATION
181 status
= frame
. ShowModal ()
182 elif len ( findCtrl
. GetValue ()) == 0 :
183 dlg
= wx
. MessageDialog ( frame
,
184 _ ( "'Find what:' cannot be empty." ),
185 _ ( "Find in Directory" ),
186 wx
. OK | wx
. ICON_EXCLAMATION
192 status
= frame
. ShowModal ()
197 # save user choice state for this and other Find Dialog Boxes
198 dirString
= dirCtrl
. GetValue ()
199 searchSubfolders
= subfolderCtrl
. IsChecked ()
200 self
. SaveFindDirConfig ( dirString
, searchSubfolders
)
202 findString
= findCtrl
. GetValue ()
203 matchCase
= matchCaseCtrl
. IsChecked ()
204 wholeWord
= wholeWordCtrl
. IsChecked ()
205 regExpr
= regExprCtrl
. IsChecked ()
206 self
. SaveFindConfig ( findString
, wholeWord
, matchCase
, regExpr
)
209 if status
== wx
. ID_OK
:
210 messageService
= wx
. GetApp (). GetService ( MessageService
. MessageService
)
211 messageService
. ShowWindow ()
213 view
= messageService
. GetView ()
215 wx
. GetApp (). GetTopWindow (). SetCursor ( wx
. StockCursor ( wx
. CURSOR_WAIT
))
217 view
. SetCallback ( self
. OnJumpToFoundLine
)
219 view
. AddLines ( _ ( "Searching for ' %s ' in ' %s ' \n\n " ) % ( findString
, dirString
))
221 if os
. path
. isfile ( dirString
):
223 docFile
= file ( dirString
, 'r' )
225 needToDisplayFilename
= True
226 line
= docFile
. readline ()
228 count
, foundStart
, foundEnd
, newText
= self
. DoFind ( findString
, None , line
, 0 , 0 , True , matchCase
, wholeWord
, regExpr
)
230 if needToDisplayFilename
:
231 view
. AddLines ( FILENAME_MARKER
+ dirString
+ " \n " )
232 needToDisplayFilename
= False
233 line
= repr ( lineNum
). zfill ( 4 ) + ":" + line
235 line
= docFile
. readline ()
237 if not needToDisplayFilename
:
239 except IOError , ( code
, message
):
240 print _ ( "Warning, unable to read file: ' %s '. %s " ) % ( dirString
, message
)
242 # do search in files on disk
243 for root
, dirs
, files
in os
. walk ( dirString
):
244 if not searchSubfolders
and root
!= dirString
:
248 filename
= os
. path
. join ( root
, name
)
250 docFile
= file ( filename
, 'r' )
251 except IOError , ( code
, message
):
252 print _ ( "Warning, unable to read file: ' %s '. %s " ) % ( filename
, message
)
256 needToDisplayFilename
= True
257 line
= docFile
. readline ()
259 count
, foundStart
, foundEnd
, newText
= self
. DoFind ( findString
, None , line
, 0 , 0 , True , matchCase
, wholeWord
, regExpr
)
261 if needToDisplayFilename
:
262 view
. AddLines ( FILENAME_MARKER
+ filename
+ " \n " )
263 needToDisplayFilename
= False
264 line
= repr ( lineNum
). zfill ( 4 ) + ":" + line
266 line
= docFile
. readline ()
268 if not needToDisplayFilename
:
271 view
. AddLines ( _ ( "Search completed." ))
272 wx
. GetApp (). GetTopWindow (). SetCursor ( wx
. StockCursor ( wx
. CURSOR_DEFAULT
))
279 def SaveFindDirConfig ( self
, dirString
, searchSubfolders
):
280 """ Save search dir patterns and flags to registry.
282 dirString = search directory
283 searchSubfolders = Search subfolders
285 config
= wx
. ConfigBase_Get ()
286 config
. Write ( FIND_MATCHDIR
, dirString
)
287 config
. WriteInt ( FIND_MATCHDIRSUBFOLDERS
, searchSubfolders
)
290 def ShowFindAllDialog ( self
, findString
= None ):
291 config
= wx
. ConfigBase_Get ()
293 frame
= wx
. Dialog ( wx
. GetApp (). GetTopWindow (), - 1 , _ ( "Find in Project" ), size
= ( 320 , 200 ))
294 borderSizer
= wx
. BoxSizer ( wx
. HORIZONTAL
)
296 contentSizer
= wx
. BoxSizer ( wx
. VERTICAL
)
297 lineSizer
= wx
. BoxSizer ( wx
. HORIZONTAL
)
298 lineSizer
. Add ( wx
. StaticText ( frame
, - 1 , _ ( "Find what:" )), 0 , wx
. ALIGN_CENTER | wx
. RIGHT
, HALF_SPACE
)
300 findString
= config
. Read ( FindService
. FIND_MATCHPATTERN
, "" )
301 findCtrl
= wx
. TextCtrl ( frame
, - 1 , findString
, size
=( 200 ,- 1 ))
302 lineSizer
. Add ( findCtrl
, 0 , wx
. LEFT
, HALF_SPACE
)
303 contentSizer
. Add ( lineSizer
, 0 , wx
. BOTTOM
, SPACE
)
304 wholeWordCtrl
= wx
. CheckBox ( frame
, - 1 , _ ( "Match whole word only" ))
305 wholeWordCtrl
. SetValue ( config
. ReadInt ( FindService
. FIND_MATCHWHOLEWORD
, False ))
306 matchCaseCtrl
= wx
. CheckBox ( frame
, - 1 , _ ( "Match case" ))
307 matchCaseCtrl
. SetValue ( config
. ReadInt ( FindService
. FIND_MATCHCASE
, False ))
308 regExprCtrl
= wx
. CheckBox ( frame
, - 1 , _ ( "Regular expression" ))
309 regExprCtrl
. SetValue ( config
. ReadInt ( FindService
. FIND_MATCHREGEXPR
, False ))
310 contentSizer
. Add ( wholeWordCtrl
, 0 , wx
. BOTTOM
, SPACE
)
311 contentSizer
. Add ( matchCaseCtrl
, 0 , wx
. BOTTOM
, SPACE
)
312 contentSizer
. Add ( regExprCtrl
, 0 , wx
. BOTTOM
, SPACE
)
313 borderSizer
. Add ( contentSizer
, 0 , wx
. TOP | wx
. BOTTOM | wx
. LEFT
, SPACE
)
315 buttonSizer
= wx
. BoxSizer ( wx
. VERTICAL
)
316 findBtn
= wx
. Button ( frame
, wx
. ID_OK
, _ ( "Find" ))
318 BTM_SPACE
= HALF_SPACE
319 if wx
. Platform
== "__WXMAC__" :
321 buttonSizer
. Add ( findBtn
, 0 , wx
. BOTTOM
, BTM_SPACE
)
322 buttonSizer
. Add ( wx
. Button ( frame
, wx
. ID_CANCEL
), 0 )
323 borderSizer
. Add ( buttonSizer
, 0 , wx
. ALL
, SPACE
)
325 frame
. SetSizer ( borderSizer
)
328 frame
. CenterOnParent ()
329 status
= frame
. ShowModal ()
331 # save user choice state for this and other Find Dialog Boxes
332 findString
= findCtrl
. GetValue ()
333 matchCase
= matchCaseCtrl
. IsChecked ()
334 wholeWord
= wholeWordCtrl
. IsChecked ()
335 regExpr
= regExprCtrl
. IsChecked ()
336 self
. SaveFindConfig ( findString
, wholeWord
, matchCase
, regExpr
)
339 if status
== wx
. ID_OK
:
340 messageService
= wx
. GetApp (). GetService ( MessageService
. MessageService
)
341 messageService
. ShowWindow ()
343 view
= messageService
. GetView ()
346 view
. SetCallback ( self
. OnJumpToFoundLine
)
348 projectService
= wx
. GetApp (). GetService ( ProjectEditor
. ProjectService
)
349 projectFilenames
= projectService
. GetFilesFromCurrentProject ()
351 projView
= projectService
. GetView ()
353 projName
= wx
. lib
. docview
. FileNameFromPath ( projView
. GetDocument (). GetFilename ())
354 view
. AddLines ( PROJECT_MARKER
+ projName
+ " \n\n " )
356 # do search in open files first, open files may have been modified and different from disk because it hasn't been saved
357 openDocs
= wx
. GetApp (). GetDocumentManager (). GetDocuments ()
358 openDocsInProject
= filter ( lambda openDoc
: openDoc
. GetFilename () in projectFilenames
, openDocs
)
359 for openDoc
in openDocsInProject
:
360 if isinstance ( openDoc
, ProjectEditor
. ProjectDocument
): # don't search project model
363 openDocView
= openDoc
. GetFirstView ()
364 # some views don't have a in memory text object to search through such as the PM and the DM
365 # even if they do have a non-text searchable object, how do we display it in the message window?
366 if not hasattr ( openDocView
, "GetValue" ):
368 text
= openDocView
. GetValue ()
371 needToDisplayFilename
= True
376 count
, foundStart
, foundEnd
, newText
= self
. DoFind ( findString
, None , text
, start
, end
, True , matchCase
, wholeWord
, regExpr
)
378 if needToDisplayFilename
:
379 view
. AddLines ( FILENAME_MARKER
+ openDoc
. GetFilename () + " \n " )
380 needToDisplayFilename
= False
382 lineNum
= openDocView
. LineFromPosition ( foundStart
)
383 line
= repr ( lineNum
). zfill ( 4 ) + ":" + openDocView
. GetLine ( lineNum
)
386 start
= text
. find ( " \n " , foundStart
)
390 if not needToDisplayFilename
:
392 openDocNames
= map ( lambda openDoc
: openDoc
. GetFilename (), openDocs
)
394 # do search in closed files, skipping the open ones we already searched
395 filenames
= filter ( lambda filename
: filename
not in openDocNames
, projectFilenames
)
396 for filename
in filenames
:
398 docFile
= file ( filename
, 'r' )
399 except IOError , ( code
, message
):
400 print _ ( "Warning, unable to read file: ' %s '. %s " ) % ( filename
, message
)
404 needToDisplayFilename
= True
405 line
= docFile
. readline ()
407 count
, foundStart
, foundEnd
, newText
= self
. DoFind ( findString
, None , line
, 0 , 0 , True , matchCase
, wholeWord
, regExpr
)
409 if needToDisplayFilename
:
410 view
. AddLines ( FILENAME_MARKER
+ filename
+ " \n " )
411 needToDisplayFilename
= False
412 line
= repr ( lineNum
). zfill ( 4 ) + ":" + line
414 line
= docFile
. readline ()
416 if not needToDisplayFilename
:
419 view
. AddLines ( _ ( "Search for ' %s ' completed." ) % findString
)
426 def OnJumpToFoundLine ( self
, event
):
427 messageService
= wx
. GetApp (). GetService ( MessageService
. MessageService
)
428 lineText
, pos
= messageService
. GetView (). GetCurrLine ()
429 if lineText
== " \n " or lineText
. find ( FILENAME_MARKER
) != - 1 or lineText
. find ( PROJECT_MARKER
) != - 1 :
431 lineEnd
= lineText
. find ( ":" )
435 lineNum
= int ( lineText
[ 0 : lineEnd
])
437 text
= messageService
. GetView (). GetText ()
438 curPos
= messageService
. GetView (). GetCurrentPos ()
440 startPos
= text
. rfind ( FILENAME_MARKER
, 0 , curPos
)
441 endPos
= text
. find ( " \n " , startPos
)
442 filename
= text
[ startPos
+ len ( FILENAME_MARKER
): endPos
]
445 openDocs
= wx
. GetApp (). GetDocumentManager (). GetDocuments ()
446 for openDoc
in openDocs
:
447 if openDoc
. GetFilename () == filename
:
448 foundView
= openDoc
. GetFirstView ()
452 doc
= wx
. GetApp (). GetDocumentManager (). CreateDocument ( filename
, wx
. lib
. docview
. DOC_SILENT|wx
. lib
. docview
. DOC_OPEN_ONCE
)
454 foundView
= doc
. GetFirstView ()
457 foundView
. GetFrame (). SetFocus ()
459 if hasattr ( foundView
, "GotoLine" ):
460 foundView
. GotoLine ( lineNum
)
461 startPos
= foundView
. PositionFromLine ( lineNum
)
462 # wxBug: Need to select in reverse order, (end, start) to put cursor at head of line so positioning is correct
463 # Also, if we use the correct positioning order (start, end), somehow, when we open a edit window for the first
464 # time, we don't see the selection, it is scrolled off screen
465 foundView
. SetSelection ( startPos
- 1 + len ( lineText
[ lineEnd
:]. rstrip ( " \n " )), startPos
)
466 wx
. GetApp (). GetService ( OutlineService
. OutlineService
). LoadOutline ( foundView
, position
= startPos
)