]>
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 view
= projectService
. GetView ()
83 if view
and view
. GetDocument () and view
. GetDocument (). GetFiles ():
88 elif id == FindInDirService
. FINDDIR_ID
:
91 return FindService
. FindService
. ProcessUpdateUIEvent ( self
, event
)
94 def ShowFindDirDialog ( self
, findString
= None ):
95 config
= wx
. ConfigBase_Get ()
97 frame
= wx
. Dialog ( None , - 1 , _ ( "Find in Directory" ), size
= ( 320 , 200 ))
98 borderSizer
= wx
. BoxSizer ( wx
. HORIZONTAL
)
100 contentSizer
= wx
. BoxSizer ( wx
. VERTICAL
)
101 lineSizer
= wx
. BoxSizer ( wx
. HORIZONTAL
)
102 lineSizer
. Add ( wx
. StaticText ( frame
, - 1 , _ ( "Directory:" )), 0 , wx
. ALIGN_CENTER | wx
. RIGHT
, HALF_SPACE
)
103 dirCtrl
= wx
. TextCtrl ( frame
, - 1 , config
. Read ( FIND_MATCHDIR
, "" ), size
=( 200 ,- 1 ))
104 dirCtrl
. SetToolTipString ( dirCtrl
. GetValue ())
105 lineSizer
. Add ( dirCtrl
, 0 , wx
. LEFT
, HALF_SPACE
)
106 findDirButton
= wx
. Button ( frame
, - 1 , _ ( "Browse..." ))
107 lineSizer
. Add ( findDirButton
, 0 , wx
. LEFT
, HALF_SPACE
)
108 contentSizer
. Add ( lineSizer
, 0 , wx
. BOTTOM
, SPACE
)
110 def OnBrowseButton ( event
):
111 dlg
= wx
. DirDialog ( frame
, _ ( "Choose a directory:" ), style
= wx
. DD_DEFAULT_STYLE
)
112 dir = dirCtrl
. GetValue ()
115 if dlg
. ShowModal () == wx
. ID_OK
:
116 dirCtrl
. SetValue ( dlg
. GetPath ())
117 dirCtrl
. SetToolTipString ( dirCtrl
. GetValue ())
118 dirCtrl
. SetInsertionPointEnd ()
121 wx
. EVT_BUTTON ( findDirButton
, - 1 , OnBrowseButton
)
123 subfolderCtrl
= wx
. CheckBox ( frame
, - 1 , _ ( "Search in subdirectories" ))
124 subfolderCtrl
. SetValue ( config
. ReadInt ( FIND_MATCHDIRSUBFOLDERS
, True ))
125 contentSizer
. Add ( subfolderCtrl
, 0 , wx
. BOTTOM
, SPACE
)
127 lineSizer
= wx
. BoxSizer ( wx
. VERTICAL
) # let the line expand horizontally without vertical expansion
128 lineSizer
. Add ( wx
. StaticLine ( frame
, - 1 , size
= ( 10 ,- 1 )), 0 , flag
= wx
. EXPAND
)
129 contentSizer
. Add ( lineSizer
, flag
= wx
. EXPAND|wx
. ALIGN_CENTER_VERTICAL|wx
. BOTTOM
, border
= HALF_SPACE
)
131 lineSizer
= wx
. BoxSizer ( wx
. HORIZONTAL
)
132 lineSizer
. Add ( wx
. StaticText ( frame
, - 1 , _ ( "Find what:" )), 0 , wx
. ALIGN_CENTER | wx
. RIGHT
, HALF_SPACE
)
134 findString
= config
. Read ( FindService
. FIND_MATCHPATTERN
, "" )
135 findCtrl
= wx
. TextCtrl ( frame
, - 1 , findString
, size
=( 200 ,- 1 ))
137 findCtrl
. SetSelection ( 0 ,- 1 )
138 lineSizer
. Add ( findCtrl
, 0 , wx
. LEFT
, HALF_SPACE
)
139 contentSizer
. Add ( lineSizer
, 0 , wx
. BOTTOM
, SPACE
)
140 wholeWordCtrl
= wx
. CheckBox ( frame
, - 1 , _ ( "Match whole word only" ))
141 wholeWordCtrl
. SetValue ( config
. ReadInt ( FindService
. FIND_MATCHWHOLEWORD
, False ))
142 matchCaseCtrl
= wx
. CheckBox ( frame
, - 1 , _ ( "Match case" ))
143 matchCaseCtrl
. SetValue ( config
. ReadInt ( FindService
. FIND_MATCHCASE
, False ))
144 regExprCtrl
= wx
. CheckBox ( frame
, - 1 , _ ( "Regular expression" ))
145 regExprCtrl
. SetValue ( config
. ReadInt ( FindService
. FIND_MATCHREGEXPR
, False ))
146 contentSizer
. Add ( wholeWordCtrl
, 0 , wx
. BOTTOM
, SPACE
)
147 contentSizer
. Add ( matchCaseCtrl
, 0 , wx
. BOTTOM
, SPACE
)
148 contentSizer
. Add ( regExprCtrl
, 0 , wx
. BOTTOM
, SPACE
)
149 borderSizer
. Add ( contentSizer
, 0 , wx
. TOP | wx
. BOTTOM | wx
. LEFT
, SPACE
)
151 buttonSizer
= wx
. BoxSizer ( wx
. VERTICAL
)
152 findBtn
= wx
. Button ( frame
, wx
. ID_OK
, _ ( "Find" ))
154 buttonSizer
. Add ( findBtn
, 0 , wx
. BOTTOM
, HALF_SPACE
)
155 buttonSizer
. Add ( wx
. Button ( frame
, wx
. ID_CANCEL
), 0 )
156 borderSizer
. Add ( buttonSizer
, 0 , wx
. ALL
, SPACE
)
158 frame
. SetSizer ( borderSizer
)
161 status
= frame
. ShowModal ()
164 while status
== wx
. ID_OK
and not passedCheck
:
165 if not os
. path
. exists ( dirCtrl
. GetValue ()):
166 dlg
= wx
. MessageDialog ( frame
,
167 _ ( "' %s ' does not exist." ) % dirCtrl
. GetValue (),
168 _ ( "Find in Directory" ),
169 wx
. OK | wx
. ICON_EXCLAMATION
174 status
= frame
. ShowModal ()
175 elif len ( findCtrl
. GetValue ()) == 0 :
176 dlg
= wx
. MessageDialog ( frame
,
177 _ ( "'Find what:' cannot be empty." ),
178 _ ( "Find in Directory" ),
179 wx
. OK | wx
. ICON_EXCLAMATION
184 status
= frame
. ShowModal ()
189 # save user choice state for this and other Find Dialog Boxes
190 dirString
= dirCtrl
. GetValue ()
191 searchSubfolders
= subfolderCtrl
. IsChecked ()
192 self
. SaveFindDirConfig ( dirString
, searchSubfolders
)
194 findString
= findCtrl
. GetValue ()
195 matchCase
= matchCaseCtrl
. IsChecked ()
196 wholeWord
= wholeWordCtrl
. IsChecked ()
197 regExpr
= regExprCtrl
. IsChecked ()
198 self
. SaveFindConfig ( findString
, wholeWord
, matchCase
, regExpr
)
201 if status
== wx
. ID_OK
:
204 messageService
= wx
. GetApp (). GetService ( MessageService
. MessageService
)
205 messageService
. ShowWindow ()
207 view
= messageService
. GetView ()
209 wx
. GetApp (). GetTopWindow (). SetCursor ( wx
. StockCursor ( wx
. CURSOR_WAIT
))
211 view
. SetCallback ( self
. OnJumpToFoundLine
)
213 view
. AddLines ( _ ( "Searching for ' %s ' in ' %s ' \n\n " ) % ( findString
, dirString
))
215 if os
. path
. isfile ( dirString
):
217 docFile
= file ( dirString
, 'r' )
219 needToDisplayFilename
= True
220 line
= docFile
. readline ()
222 count
, foundStart
, foundEnd
, newText
= self
. DoFind ( findString
, None , line
, 0 , 0 , True , matchCase
, wholeWord
, regExpr
)
224 if needToDisplayFilename
:
225 view
. AddLines ( FILENAME_MARKER
+ dirString
+ " \n " )
226 needToDisplayFilename
= False
227 line
= repr ( lineNum
). zfill ( 4 ) + ":" + line
229 line
= docFile
. readline ()
231 if not needToDisplayFilename
:
233 except IOError , ( code
, message
):
234 print _ ( "Warning, unable to read file: ' %s '. %s " ) % ( dirString
, message
)
236 # do search in files on disk
237 for root
, dirs
, files
in os
. walk ( dirString
):
238 if not searchSubfolders
and root
!= dirString
:
242 filename
= os
. path
. join ( root
, name
)
244 docFile
= file ( filename
, 'r' )
245 except IOError , ( code
, message
):
246 print _ ( "Warning, unable to read file: ' %s '. %s " ) % ( filename
, message
)
250 needToDisplayFilename
= True
251 line
= docFile
. readline ()
253 count
, foundStart
, foundEnd
, newText
= self
. DoFind ( findString
, None , line
, 0 , 0 , True , matchCase
, wholeWord
, regExpr
)
255 if needToDisplayFilename
:
256 view
. AddLines ( FILENAME_MARKER
+ filename
+ " \n " )
257 needToDisplayFilename
= False
258 line
= repr ( lineNum
). zfill ( 4 ) + ":" + line
260 line
= docFile
. readline ()
262 if not needToDisplayFilename
:
265 view
. AddLines ( _ ( "Search completed." ))
266 wx
. GetApp (). GetTopWindow (). SetCursor ( wx
. StockCursor ( wx
. CURSOR_DEFAULT
))
274 def SaveFindDirConfig ( self
, dirString
, searchSubfolders
):
275 """ Save search dir patterns and flags to registry.
277 dirString = search directory
278 searchSubfolders = Search subfolders
280 config
= wx
. ConfigBase_Get ()
281 config
. Write ( FIND_MATCHDIR
, dirString
)
282 config
. WriteInt ( FIND_MATCHDIRSUBFOLDERS
, searchSubfolders
)
285 def ShowFindAllDialog ( self
, findString
= None ):
286 config
= wx
. ConfigBase_Get ()
288 frame
= wx
. Dialog ( None , - 1 , _ ( "Find in Project" ), size
= ( 320 , 200 ))
289 borderSizer
= wx
. BoxSizer ( wx
. HORIZONTAL
)
291 contentSizer
= wx
. BoxSizer ( wx
. VERTICAL
)
292 lineSizer
= wx
. BoxSizer ( wx
. HORIZONTAL
)
293 lineSizer
. Add ( wx
. StaticText ( frame
, - 1 , _ ( "Find what:" )), 0 , wx
. ALIGN_CENTER | wx
. RIGHT
, HALF_SPACE
)
295 findString
= config
. Read ( FindService
. FIND_MATCHPATTERN
, "" )
296 findCtrl
= wx
. TextCtrl ( frame
, - 1 , findString
, size
=( 200 ,- 1 ))
297 lineSizer
. Add ( findCtrl
, 0 , wx
. LEFT
, HALF_SPACE
)
298 contentSizer
. Add ( lineSizer
, 0 , wx
. BOTTOM
, SPACE
)
299 wholeWordCtrl
= wx
. CheckBox ( frame
, - 1 , _ ( "Match whole word only" ))
300 wholeWordCtrl
. SetValue ( config
. ReadInt ( FindService
. FIND_MATCHWHOLEWORD
, False ))
301 matchCaseCtrl
= wx
. CheckBox ( frame
, - 1 , _ ( "Match case" ))
302 matchCaseCtrl
. SetValue ( config
. ReadInt ( FindService
. FIND_MATCHCASE
, False ))
303 regExprCtrl
= wx
. CheckBox ( frame
, - 1 , _ ( "Regular expression" ))
304 regExprCtrl
. SetValue ( config
. ReadInt ( FindService
. FIND_MATCHREGEXPR
, False ))
305 contentSizer
. Add ( wholeWordCtrl
, 0 , wx
. BOTTOM
, SPACE
)
306 contentSizer
. Add ( matchCaseCtrl
, 0 , wx
. BOTTOM
, SPACE
)
307 contentSizer
. Add ( regExprCtrl
, 0 , wx
. BOTTOM
, SPACE
)
308 borderSizer
. Add ( contentSizer
, 0 , wx
. TOP | wx
. BOTTOM | wx
. LEFT
, SPACE
)
310 buttonSizer
= wx
. BoxSizer ( wx
. VERTICAL
)
311 findBtn
= wx
. Button ( frame
, wx
. ID_OK
, _ ( "Find" ))
313 buttonSizer
. Add ( findBtn
, 0 , wx
. BOTTOM
, HALF_SPACE
)
314 buttonSizer
. Add ( wx
. Button ( frame
, wx
. ID_CANCEL
), 0 )
315 borderSizer
. Add ( buttonSizer
, 0 , wx
. ALL
, SPACE
)
317 frame
. SetSizer ( borderSizer
)
320 status
= frame
. ShowModal ()
322 # save user choice state for this and other Find Dialog Boxes
323 findString
= findCtrl
. GetValue ()
324 matchCase
= matchCaseCtrl
. IsChecked ()
325 wholeWord
= wholeWordCtrl
. IsChecked ()
326 regExpr
= regExprCtrl
. IsChecked ()
327 self
. SaveFindConfig ( findString
, wholeWord
, matchCase
, regExpr
)
329 if status
== wx
. ID_OK
:
332 messageService
= wx
. GetApp (). GetService ( MessageService
. MessageService
)
333 messageService
. ShowWindow ()
335 view
= messageService
. GetView ()
338 view
. SetCallback ( self
. OnJumpToFoundLine
)
340 projectService
= wx
. GetApp (). GetService ( ProjectEditor
. ProjectService
)
341 projectFilenames
= projectService
. GetFilesFromCurrentProject ()
343 projView
= projectService
. GetView ()
345 projName
= wx
. lib
. docview
. FileNameFromPath ( projView
. GetDocument (). GetFilename ())
346 view
. AddLines ( PROJECT_MARKER
+ projName
+ " \n\n " )
348 # do search in open files first, open files may have been modified and different from disk because it hasn't been saved
349 openDocs
= wx
. GetApp (). GetDocumentManager (). GetDocuments ()
350 openDocsInProject
= filter ( lambda openDoc
: openDoc
. GetFilename () in projectFilenames
, openDocs
)
351 for openDoc
in openDocsInProject
:
352 if isinstance ( openDoc
, ProjectEditor
. ProjectDocument
): # don't search project model
355 openDocView
= openDoc
. GetFirstView ()
356 # some views don't have a in memory text object to search through such as the PM and the DM
357 # even if they do have a non-text searchable object, how do we display it in the message window?
358 if not hasattr ( openDocView
, "GetValue" ):
360 text
= openDocView
. GetValue ()
363 needToDisplayFilename
= True
368 count
, foundStart
, foundEnd
, newText
= self
. DoFind ( findString
, None , text
, start
, end
, True , matchCase
, wholeWord
, regExpr
)
370 if needToDisplayFilename
:
371 view
. AddLines ( FILENAME_MARKER
+ openDoc
. GetFilename () + " \n " )
372 needToDisplayFilename
= False
374 lineNum
= openDocView
. LineFromPosition ( foundStart
)
375 line
= repr ( lineNum
). zfill ( 4 ) + ":" + openDocView
. GetLine ( lineNum
)
378 start
= text
. find ( " \n " , foundStart
)
382 if not needToDisplayFilename
:
384 openDocNames
= map ( lambda openDoc
: openDoc
. GetFilename (), openDocs
)
386 # do search in closed files, skipping the open ones we already searched
387 filenames
= filter ( lambda filename
: filename
not in openDocNames
, projectFilenames
)
388 for filename
in filenames
:
390 docFile
= file ( filename
, 'r' )
391 except IOError , ( code
, message
):
392 print _ ( "Warning, unable to read file: ' %s '. %s " ) % ( filename
, message
)
396 needToDisplayFilename
= True
397 line
= docFile
. readline ()
399 count
, foundStart
, foundEnd
, newText
= self
. DoFind ( findString
, None , line
, 0 , 0 , True , matchCase
, wholeWord
, regExpr
)
401 if needToDisplayFilename
:
402 view
. AddLines ( FILENAME_MARKER
+ filename
+ " \n " )
403 needToDisplayFilename
= False
404 line
= repr ( lineNum
). zfill ( 4 ) + ":" + line
406 line
= docFile
. readline ()
408 if not needToDisplayFilename
:
411 view
. AddLines ( _ ( "Search for ' %s ' completed." ) % findString
)
419 def OnJumpToFoundLine ( self
, event
):
420 messageService
= wx
. GetApp (). GetService ( MessageService
. MessageService
)
421 lineText
, pos
= messageService
. GetView (). GetCurrLine ()
422 if lineText
== " \n " or lineText
. find ( FILENAME_MARKER
) != - 1 or lineText
. find ( PROJECT_MARKER
) != - 1 :
424 lineEnd
= lineText
. find ( ":" )
428 lineNum
= int ( lineText
[ 0 : lineEnd
])
430 text
= messageService
. GetView (). GetText ()
431 curPos
= messageService
. GetView (). GetCurrentPos ()
433 startPos
= text
. rfind ( FILENAME_MARKER
, 0 , curPos
)
434 endPos
= text
. find ( " \n " , startPos
)
435 filename
= text
[ startPos
+ len ( FILENAME_MARKER
): endPos
]
438 openDocs
= wx
. GetApp (). GetDocumentManager (). GetDocuments ()
439 for openDoc
in openDocs
:
440 if openDoc
. GetFilename () == filename
:
441 foundView
= openDoc
. GetFirstView ()
445 doc
= wx
. GetApp (). GetDocumentManager (). CreateDocument ( filename
, wx
. lib
. docview
. DOC_SILENT
)
446 foundView
= doc
. GetFirstView ()
449 foundView
. GetFrame (). SetFocus ()
451 if hasattr ( foundView
, "GotoLine" ):
452 foundView
. GotoLine ( lineNum
)
453 startPos
= foundView
. PositionFromLine ( lineNum
)
454 # wxBug: Need to select in reverse order, (end, start) to put cursor at head of line so positioning is correct
455 # Also, if we use the correct positioning order (start, end), somehow, when we open a edit window for the first
456 # time, we don't see the selection, it is scrolled off screen
457 foundView
. SetSelection ( startPos
- 1 + len ( lineText
[ lineEnd
:]. rstrip ( " \n " )), startPos
)
458 wx
. GetApp (). GetService ( OutlineService
. OutlineService
). LoadOutline ( foundView
, position
= startPos
)