]>
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 self
. ShowFindAllDialog ()
63 elif id == FindInDirService
. FINDDIR_ID
:
64 self
. ShowFindDirDialog ()
67 return FindService
. FindService
. ProcessEvent ( self
, event
)
70 def ProcessUpdateUIEvent ( self
, event
):
72 if id == FindInDirService
. FINDALL_ID
:
73 projectService
= wx
. GetApp (). GetService ( ProjectEditor
. ProjectService
)
74 view
= projectService
. GetView ()
75 if view
and view
. GetDocument () and view
. GetDocument (). GetFiles ():
80 elif id == FindInDirService
. FINDDIR_ID
:
83 return FindService
. FindService
. ProcessUpdateUIEvent ( self
, event
)
86 def ShowFindDirDialog ( self
):
87 config
= wx
. ConfigBase_Get ()
89 frame
= wx
. Dialog ( None , - 1 , _ ( "Find in Directory" ), size
= ( 320 , 200 ))
90 borderSizer
= wx
. BoxSizer ( wx
. HORIZONTAL
)
92 contentSizer
= wx
. BoxSizer ( wx
. VERTICAL
)
93 lineSizer
= wx
. BoxSizer ( wx
. HORIZONTAL
)
94 lineSizer
. Add ( wx
. StaticText ( frame
, - 1 , _ ( "Directory:" )), 0 , wx
. ALIGN_CENTER | wx
. RIGHT
, HALF_SPACE
)
95 dirCtrl
= wx
. TextCtrl ( frame
, - 1 , config
. Read ( FIND_MATCHDIR
, "" ), size
=( 200 ,- 1 ))
96 dirCtrl
. SetToolTipString ( dirCtrl
. GetValue ())
97 lineSizer
. Add ( dirCtrl
, 0 , wx
. LEFT
, HALF_SPACE
)
98 findDirButton
= wx
. Button ( frame
, - 1 , "Browse..." )
99 lineSizer
. Add ( findDirButton
, 0 , wx
. LEFT
, HALF_SPACE
)
100 contentSizer
. Add ( lineSizer
, 0 , wx
. BOTTOM
, SPACE
)
102 def OnBrowseButton ( event
):
103 dlg
= wx
. DirDialog ( frame
, _ ( "Choose a directory:" ), style
= wx
. DD_DEFAULT_STYLE
)
104 dir = dirCtrl
. GetValue ()
107 if dlg
. ShowModal () == wx
. ID_OK
:
108 dirCtrl
. SetValue ( dlg
. GetPath ())
109 dirCtrl
. SetToolTipString ( dirCtrl
. GetValue ())
110 dirCtrl
. SetInsertionPointEnd ()
113 wx
. EVT_BUTTON ( findDirButton
, - 1 , OnBrowseButton
)
115 subfolderCtrl
= wx
. CheckBox ( frame
, - 1 , _ ( "Search in subfolders" ))
116 subfolderCtrl
. SetValue ( config
. ReadInt ( FIND_MATCHDIRSUBFOLDERS
, True ))
117 contentSizer
. Add ( subfolderCtrl
, 0 , wx
. BOTTOM
, SPACE
)
119 lineSizer
= wx
. BoxSizer ( wx
. VERTICAL
) # let the line expand horizontally without vertical expansion
120 lineSizer
. Add ( wx
. StaticLine ( frame
, - 1 , size
= ( 10 ,- 1 )), 0 , flag
= wx
. EXPAND
)
121 contentSizer
. Add ( lineSizer
, flag
= wx
. EXPAND|wx
. ALIGN_CENTER_VERTICAL|wx
. BOTTOM
, border
= HALF_SPACE
)
123 lineSizer
= wx
. BoxSizer ( wx
. HORIZONTAL
)
124 lineSizer
. Add ( wx
. StaticText ( frame
, - 1 , _ ( "Find what:" )), 0 , wx
. ALIGN_CENTER | wx
. RIGHT
, HALF_SPACE
)
125 findCtrl
= wx
. TextCtrl ( frame
, - 1 , config
. Read ( FindService
. FIND_MATCHPATTERN
, "" ), size
=( 200 ,- 1 ))
126 lineSizer
. Add ( findCtrl
, 0 , wx
. LEFT
, HALF_SPACE
)
127 contentSizer
. Add ( lineSizer
, 0 , wx
. BOTTOM
, SPACE
)
128 wholeWordCtrl
= wx
. CheckBox ( frame
, - 1 , _ ( "Match whole word only" ))
129 wholeWordCtrl
. SetValue ( config
. ReadInt ( FindService
. FIND_MATCHWHOLEWORD
, False ))
130 matchCaseCtrl
= wx
. CheckBox ( frame
, - 1 , _ ( "Match case" ))
131 matchCaseCtrl
. SetValue ( config
. ReadInt ( FindService
. FIND_MATCHCASE
, False ))
132 regExprCtrl
= wx
. CheckBox ( frame
, - 1 , _ ( "Regular expression" ))
133 regExprCtrl
. SetValue ( config
. ReadInt ( FindService
. FIND_MATCHREGEXPR
, False ))
134 contentSizer
. Add ( wholeWordCtrl
, 0 , wx
. BOTTOM
, SPACE
)
135 contentSizer
. Add ( matchCaseCtrl
, 0 , wx
. BOTTOM
, SPACE
)
136 contentSizer
. Add ( regExprCtrl
, 0 , wx
. BOTTOM
, SPACE
)
137 borderSizer
. Add ( contentSizer
, 0 , wx
. TOP | wx
. BOTTOM | wx
. LEFT
, SPACE
)
139 buttonSizer
= wx
. BoxSizer ( wx
. VERTICAL
)
140 findBtn
= wx
. Button ( frame
, wx
. ID_OK
, _ ( "Find" ))
142 buttonSizer
. Add ( findBtn
, 0 , wx
. BOTTOM
, HALF_SPACE
)
143 buttonSizer
. Add ( wx
. Button ( frame
, wx
. ID_CANCEL
, _ ( "Cancel" )), 0 )
144 borderSizer
. Add ( buttonSizer
, 0 , wx
. ALL
, SPACE
)
146 frame
. SetSizer ( borderSizer
)
149 status
= frame
. ShowModal ()
152 while status
== wx
. ID_OK
and not passedCheck
:
153 if not os
. path
. exists ( dirCtrl
. GetValue ()):
154 dlg
= wx
. MessageDialog ( frame
,
155 _ ( "' %s ' does not exist." ) % dirCtrl
. GetValue (),
156 _ ( "Find in Directory" ),
157 wx
. OK | wx
. ICON_EXCLAMATION
162 status
= frame
. ShowModal ()
163 elif len ( findCtrl
. GetValue ()) == 0 :
164 dlg
= wx
. MessageDialog ( frame
,
165 _ ( "'Find what:' cannot be empty." ),
166 _ ( "Find in Directory" ),
167 wx
. OK | wx
. ICON_EXCLAMATION
172 status
= frame
. ShowModal ()
177 # save user choice state for this and other Find Dialog Boxes
178 dirString
= dirCtrl
. GetValue ()
179 searchSubfolders
= subfolderCtrl
. IsChecked ()
180 self
. SaveFindDirConfig ( dirString
, searchSubfolders
)
182 findString
= findCtrl
. GetValue ()
183 matchCase
= matchCaseCtrl
. IsChecked ()
184 wholeWord
= wholeWordCtrl
. IsChecked ()
185 regExpr
= regExprCtrl
. IsChecked ()
186 self
. SaveFindConfig ( findString
, wholeWord
, matchCase
, regExpr
)
189 if status
== wx
. ID_OK
:
192 messageService
= wx
. GetApp (). GetService ( MessageService
. MessageService
)
193 messageService
. ShowWindow ()
195 view
= messageService
. GetView ()
197 wx
. GetApp (). GetTopWindow (). SetCursor ( wx
. StockCursor ( wx
. CURSOR_WAIT
))
199 view
. SetCallback ( self
. OnJumpToFoundLine
)
201 view
. AddLines ( _ ( "Searching for ' %s ' in ' %s ' \n\n " ) % ( findString
, dirString
))
203 if os
. path
. isfile ( dirString
):
205 docFile
= file ( dirString
, 'r' )
207 needToDisplayFilename
= True
208 line
= docFile
. readline ()
210 count
, foundStart
, foundEnd
, newText
= self
. DoFind ( findString
, None , line
, 0 , 0 , True , matchCase
, wholeWord
, regExpr
)
212 if needToDisplayFilename
:
213 view
. AddLines ( FILENAME_MARKER
+ dirString
+ " \n " )
214 needToDisplayFilename
= False
215 line
= repr ( lineNum
). zfill ( 4 ) + ":" + line
217 line
= docFile
. readline ()
219 if not needToDisplayFilename
:
221 except IOError , ( code
, message
):
222 print _ ( "Warning, unable to read file: ' %s '. %s " ) % ( dirString
, message
)
224 # do search in files on disk
225 for root
, dirs
, files
in os
. walk ( dirString
):
226 if not searchSubfolders
and root
!= dirString
:
230 filename
= os
. path
. join ( root
, name
)
232 docFile
= file ( filename
, 'r' )
233 except IOError , ( code
, message
):
234 print _ ( "Warning, unable to read file: ' %s '. %s " ) % ( filename
, message
)
238 needToDisplayFilename
= True
239 line
= docFile
. readline ()
241 count
, foundStart
, foundEnd
, newText
= self
. DoFind ( findString
, None , line
, 0 , 0 , True , matchCase
, wholeWord
, regExpr
)
243 if needToDisplayFilename
:
244 view
. AddLines ( FILENAME_MARKER
+ filename
+ " \n " )
245 needToDisplayFilename
= False
246 line
= repr ( lineNum
). zfill ( 4 ) + ":" + line
248 line
= docFile
. readline ()
250 if not needToDisplayFilename
:
253 view
. AddLines ( _ ( "Search completed." ))
254 wx
. GetApp (). GetTopWindow (). SetCursor ( wx
. StockCursor ( wx
. CURSOR_DEFAULT
))
262 def SaveFindDirConfig ( self
, dirString
, searchSubfolders
):
263 """ Save search dir patterns and flags to registry.
265 dirString = search directory
266 searchSubfolders = Search subfolders
268 config
= wx
. ConfigBase_Get ()
269 config
. Write ( FIND_MATCHDIR
, dirString
)
270 config
. WriteInt ( FIND_MATCHDIRSUBFOLDERS
, searchSubfolders
)
273 def ShowFindAllDialog ( self
):
274 config
= wx
. ConfigBase_Get ()
276 frame
= wx
. Dialog ( None , - 1 , _ ( "Find in Project" ), size
= ( 320 , 200 ))
277 borderSizer
= wx
. BoxSizer ( wx
. HORIZONTAL
)
279 contentSizer
= wx
. BoxSizer ( wx
. VERTICAL
)
280 lineSizer
= wx
. BoxSizer ( wx
. HORIZONTAL
)
281 lineSizer
. Add ( wx
. StaticText ( frame
, - 1 , _ ( "Find what:" )), 0 , wx
. ALIGN_CENTER | wx
. RIGHT
, HALF_SPACE
)
282 findCtrl
= wx
. TextCtrl ( frame
, - 1 , config
. Read ( FindService
. FIND_MATCHPATTERN
, "" ), size
=( 200 ,- 1 ))
283 lineSizer
. Add ( findCtrl
, 0 , wx
. LEFT
, HALF_SPACE
)
284 contentSizer
. Add ( lineSizer
, 0 , wx
. BOTTOM
, SPACE
)
285 wholeWordCtrl
= wx
. CheckBox ( frame
, - 1 , _ ( "Match whole word only" ))
286 wholeWordCtrl
. SetValue ( config
. ReadInt ( FindService
. FIND_MATCHWHOLEWORD
, False ))
287 matchCaseCtrl
= wx
. CheckBox ( frame
, - 1 , _ ( "Match case" ))
288 matchCaseCtrl
. SetValue ( config
. ReadInt ( FindService
. FIND_MATCHCASE
, False ))
289 regExprCtrl
= wx
. CheckBox ( frame
, - 1 , _ ( "Regular expression" ))
290 regExprCtrl
. SetValue ( config
. ReadInt ( FindService
. FIND_MATCHREGEXPR
, False ))
291 contentSizer
. Add ( wholeWordCtrl
, 0 , wx
. BOTTOM
, SPACE
)
292 contentSizer
. Add ( matchCaseCtrl
, 0 , wx
. BOTTOM
, SPACE
)
293 contentSizer
. Add ( regExprCtrl
, 0 , wx
. BOTTOM
, SPACE
)
294 borderSizer
. Add ( contentSizer
, 0 , wx
. TOP | wx
. BOTTOM | wx
. LEFT
, SPACE
)
296 buttonSizer
= wx
. BoxSizer ( wx
. VERTICAL
)
297 findBtn
= wx
. Button ( frame
, wx
. ID_OK
, _ ( "Find" ))
299 buttonSizer
. Add ( findBtn
, 0 , wx
. BOTTOM
, HALF_SPACE
)
300 buttonSizer
. Add ( wx
. Button ( frame
, wx
. ID_CANCEL
, _ ( "Cancel" )), 0 )
301 borderSizer
. Add ( buttonSizer
, 0 , wx
. ALL
, SPACE
)
303 frame
. SetSizer ( borderSizer
)
306 status
= frame
. ShowModal ()
308 # save user choice state for this and other Find Dialog Boxes
309 findString
= findCtrl
. GetValue ()
310 matchCase
= matchCaseCtrl
. IsChecked ()
311 wholeWord
= wholeWordCtrl
. IsChecked ()
312 regExpr
= regExprCtrl
. IsChecked ()
313 self
. SaveFindConfig ( findString
, wholeWord
, matchCase
, regExpr
)
315 if status
== wx
. ID_OK
:
318 messageService
= wx
. GetApp (). GetService ( MessageService
. MessageService
)
319 messageService
. ShowWindow ()
321 view
= messageService
. GetView ()
324 view
. SetCallback ( self
. OnJumpToFoundLine
)
326 projectService
= wx
. GetApp (). GetService ( ProjectEditor
. ProjectService
)
327 projectFilenames
= projectService
. GetFilesFromCurrentProject ()
329 projView
= projectService
. GetView ()
331 projName
= wx
. lib
. docview
. FileNameFromPath ( projView
. GetDocument (). GetFilename ())
332 view
. AddLines ( PROJECT_MARKER
+ projName
+ " \n\n " )
334 # do search in open files first, open files may have been modified and different from disk because it hasn't been saved
335 openDocs
= wx
. GetApp (). GetDocumentManager (). GetDocuments ()
336 openDocsInProject
= filter ( lambda openDoc
: openDoc
. GetFilename () in projectFilenames
, openDocs
)
337 for openDoc
in openDocsInProject
:
338 if isinstance ( openDoc
, ProjectEditor
. ProjectDocument
): # don't search project model
341 openDocView
= openDoc
. GetFirstView ()
342 # some views don't have a in memory text object to search through such as the PM and the DM
343 # even if they do have a non-text searchable object, how do we display it in the message window?
344 if not hasattr ( openDocView
, "GetValue" ):
346 text
= openDocView
. GetValue ()
349 needToDisplayFilename
= True
354 count
, foundStart
, foundEnd
, newText
= self
. DoFind ( findString
, None , text
, start
, end
, True , matchCase
, wholeWord
, regExpr
)
356 if needToDisplayFilename
:
357 view
. AddLines ( FILENAME_MARKER
+ openDoc
. GetFilename () + " \n " )
358 needToDisplayFilename
= False
360 lineNum
= openDocView
. LineFromPosition ( foundStart
)
361 line
= repr ( lineNum
). zfill ( 4 ) + ":" + openDocView
. GetLine ( lineNum
)
364 start
= text
. find ( " \n " , foundStart
)
368 if not needToDisplayFilename
:
370 openDocNames
= map ( lambda openDoc
: openDoc
. GetFilename (), openDocs
)
372 # do search in closed files, skipping the open ones we already searched
373 filenames
= filter ( lambda filename
: filename
not in openDocNames
, projectFilenames
)
374 for filename
in filenames
:
376 docFile
= file ( filename
, 'r' )
377 except IOError , ( code
, message
):
378 print _ ( "Warning, unable to read file: ' %s '. %s " ) % ( filename
, message
)
382 needToDisplayFilename
= True
383 line
= docFile
. readline ()
385 count
, foundStart
, foundEnd
, newText
= self
. DoFind ( findString
, None , line
, 0 , 0 , True , matchCase
, wholeWord
, regExpr
)
387 if needToDisplayFilename
:
388 view
. AddLines ( FILENAME_MARKER
+ filename
+ " \n " )
389 needToDisplayFilename
= False
390 line
= repr ( lineNum
). zfill ( 4 ) + ":" + line
392 line
= docFile
. readline ()
394 if not needToDisplayFilename
:
397 view
. AddLines ( _ ( "Search for ' %s ' completed." ) % findString
)
405 def OnJumpToFoundLine ( self
, event
):
406 messageService
= wx
. GetApp (). GetService ( MessageService
. MessageService
)
407 lineText
, pos
= messageService
. GetView (). GetCurrLine ()
408 if lineText
== " \n " or lineText
. find ( FILENAME_MARKER
) != - 1 or lineText
. find ( PROJECT_MARKER
) != - 1 :
410 lineEnd
= lineText
. find ( ":" )
414 lineNum
= int ( lineText
[ 0 : lineEnd
])
416 text
= messageService
. GetView (). GetText ()
417 curPos
= messageService
. GetView (). GetCurrentPos ()
419 startPos
= text
. rfind ( FILENAME_MARKER
, 0 , curPos
)
420 endPos
= text
. find ( " \n " , startPos
)
421 filename
= text
[ startPos
+ len ( FILENAME_MARKER
): endPos
]
424 openDocs
= wx
. GetApp (). GetDocumentManager (). GetDocuments ()
425 for openDoc
in openDocs
:
426 if openDoc
. GetFilename () == filename
:
427 foundView
= openDoc
. GetFirstView ()
431 doc
= wx
. GetApp (). GetDocumentManager (). CreateDocument ( filename
, wx
. lib
. docview
. DOC_SILENT
)
432 foundView
= doc
. GetFirstView ()
435 foundView
. GetFrame (). SetFocus ()
437 if hasattr ( foundView
, "GotoLine" ):
438 foundView
. GotoLine ( lineNum
)
439 startPos
= foundView
. PositionFromLine ( lineNum
)
440 # wxBug: Need to select in reverse order, (end, start) to put cursor at head of line so positioning is correct
441 # Also, if we use the correct positioning order (start, end), somehow, when we open a edit window for the first
442 # time, we don't see the selection, it is scrolled off screen
443 foundView
. SetSelection ( startPos
- 1 + len ( lineText
[ lineEnd
:]. rstrip ( " \n " )), startPos
)
444 wx
. GetApp (). GetService ( OutlineService
. OutlineService
). LoadOutline ( foundView
, position
= startPos
)