]>
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
)