]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/samples/ide/activegrid/tool/IDEFindService.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  IDEFindService ( 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
,  IDEFindService
. FINDALL_ID
,  self
. ProcessEvent
)   51          wx
. EVT_UPDATE_UI ( frame
,  IDEFindService
. FINDALL_ID
,  self
. ProcessUpdateUIEvent
)   52          editMenu
. Append ( IDEFindService
. 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
,  IDEFindService
. FINDDIR_ID
,  self
. ProcessEvent
)   54          wx
. EVT_UPDATE_UI ( frame
,  IDEFindService
. FINDDIR_ID
,  self
. ProcessUpdateUIEvent
)   55          editMenu
. Append ( IDEFindService
. 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  ==  IDEFindService
. FINDALL_ID
:   61              self
. ShowFindAllDialog ()   63          elif  id  ==  IDEFindService
. FINDDIR_ID
:   64              self
. ShowFindDirDialog ()   67              return  FindService
. FindService
. ProcessEvent ( self
,  event
)   70      def  ProcessUpdateUIEvent ( self
,  event
):   72          if  id  ==  IDEFindService
. 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  ==  IDEFindService
. 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 ()  151          # save user choice state for this and other Find Dialog Boxes  152          dirString 
=  dirCtrl
. GetValue ()  153          searchSubfolders 
=  subfolderCtrl
. IsChecked ()  154          self
. SaveFindDirConfig ( dirString
,  searchSubfolders
)  156          findString 
=  findCtrl
. GetValue ()  157          matchCase 
=  matchCaseCtrl
. IsChecked ()  158          wholeWord 
=  wholeWordCtrl
. IsChecked ()  159          regExpr 
=  regExprCtrl
. IsChecked ()  160          self
. SaveFindConfig ( findString
,  wholeWord
,  matchCase
,  regExpr
)  162          while not  os
. path
. exists ( dirString
):  163              dlg 
=  wx
. MessageDialog ( frame
,  164                                     _ ( "' %s ' does not exist." ) %  dirString
,  165                                     _ ( "Find in Directory" ),  166                                     wx
. OK | wx
. ICON_EXCLAMATION
 171              status 
=  frame
. ShowModal ()  173              # save user choice state for this and other Find Dialog Boxes  174              dirString 
=  dirCtrl
. GetValue ()  175              searchSubfolders 
=  subfolderCtrl
. IsChecked ()  176              self
. SaveFindDirConfig ( dirString
,  searchSubfolders
)  178              findString 
=  findCtrl
. GetValue ()  179              matchCase 
=  matchCaseCtrl
. IsChecked ()  180              wholeWord 
=  wholeWordCtrl
. IsChecked ()  181              regExpr 
=  regExprCtrl
. IsChecked ()  182              self
. SaveFindConfig ( findString
,  wholeWord
,  matchCase
,  regExpr
)  184              if  status 
==  wx
. ID_CANCEL
:  188          if  status 
==  wx
. ID_OK
:              191              messageService 
=  wx
. GetApp (). GetService ( MessageService
. MessageService
)  192              messageService
. ShowWindow ()  194              view 
=  messageService
. GetView ()  196                  wx
. GetApp (). GetTopWindow (). SetCursor ( wx
. StockCursor ( wx
. CURSOR_WAIT
))  198                  view
. SetCallback ( self
. OnJumpToFoundLine
)  200                  view
. AddLines ( _ ( "Searching for ' %s ' in ' %s ' \n\n " ) % ( findString
,  dirString
))  202                  if  os
. path
. isfile ( dirString
):  204                          docFile 
=  file ( dirString
,  'r' )  206                          needToDisplayFilename 
=  True  207                          line 
=  docFile
. readline ()  209                              count
,  foundStart
,  foundEnd
,  newText 
=  self
. DoFind ( findString
,  None ,  line
,  0 ,  0 ,  True ,  matchCase
,  wholeWord
,  regExpr
)  211                                  if  needToDisplayFilename
:  212                                      view
. AddLines ( FILENAME_MARKER 
+  dirString 
+  " \n " )  213                                      needToDisplayFilename 
=  False  214                                  line 
=  repr ( lineNum
). zfill ( 4 ) +  ":"  +  line
 216                              line 
=  docFile
. readline ()  218                          if not  needToDisplayFilename
:  220                      except  IOError , ( code
,  message
):  221                          print  _ ( "Warning, unable to read file: ' %s '.   %s " ) % ( dirString
,  message
)  223                      # do search in files on disk  224                      for  root
,  dirs
,  files 
in  os
. walk ( dirString
):  225                          if not  searchSubfolders 
and  root 
!=  dirString
:  229                              filename 
=  os
. path
. join ( root
,  name
)  231                                  docFile 
=  file ( filename
,  'r' )  232                              except  IOError , ( code
,  message
):  233                                  print  _ ( "Warning, unable to read file: ' %s '.   %s " ) % ( filename
,  message
)  237                              needToDisplayFilename 
=  True  238                              line 
=  docFile
. readline ()  240                                  count
,  foundStart
,  foundEnd
,  newText 
=  self
. DoFind ( findString
,  None ,  line
,  0 ,  0 ,  True ,  matchCase
,  wholeWord
,  regExpr
)  242                                      if  needToDisplayFilename
:  243                                          view
. AddLines ( FILENAME_MARKER 
+  filename 
+  " \n " )  244                                          needToDisplayFilename 
=  False  245                                      line 
=  repr ( lineNum
). zfill ( 4 ) +  ":"  +  line
 247                                  line 
=  docFile
. readline ()  249                              if not  needToDisplayFilename
:  252                  view
. AddLines ( _ ( "Search completed." ))  253                  wx
. GetApp (). GetTopWindow (). SetCursor ( wx
. StockCursor ( wx
. CURSOR_DEFAULT
))  261      def  SaveFindDirConfig ( self
,  dirString
,  searchSubfolders
):  262          """ Save search dir patterns and flags to registry.  264              dirString = search directory  265              searchSubfolders = Search subfolders  267          config 
=  wx
. ConfigBase_Get ()  268          config
. Write ( FIND_MATCHDIR
,  dirString
)  269          config
. WriteInt ( FIND_MATCHDIRSUBFOLDERS
,  searchSubfolders
)  272      def  ShowFindAllDialog ( self
):  273          config 
=  wx
. ConfigBase_Get ()  275          frame 
=  wx
. Dialog ( None , - 1 ,  _ ( "Find in Project" ),  size
= ( 320 , 200 ))  276          borderSizer 
=  wx
. BoxSizer ( wx
. HORIZONTAL
)  278          contentSizer 
=  wx
. BoxSizer ( wx
. VERTICAL
)  279          lineSizer 
=  wx
. BoxSizer ( wx
. HORIZONTAL
)  280          lineSizer
. Add ( wx
. StaticText ( frame
, - 1 ,  _ ( "Find what:" )),  0 ,  wx
. ALIGN_CENTER | wx
. RIGHT
,  HALF_SPACE
)  281          findCtrl 
=  wx
. TextCtrl ( frame
, - 1 ,  config
. Read ( FindService
. FIND_MATCHPATTERN
,  "" ),  size
=( 200 ,- 1 ))  282          lineSizer
. Add ( findCtrl
,  0 ,  wx
. LEFT
,  HALF_SPACE
)  283          contentSizer
. Add ( lineSizer
,  0 ,  wx
. BOTTOM
,  SPACE
)  284          wholeWordCtrl 
=  wx
. CheckBox ( frame
, - 1 ,  _ ( "Match whole word only" ))  285          wholeWordCtrl
. SetValue ( config
. ReadInt ( FindService
. FIND_MATCHWHOLEWORD
,  False ))  286          matchCaseCtrl 
=  wx
. CheckBox ( frame
, - 1 ,  _ ( "Match case" ))  287          matchCaseCtrl
. SetValue ( config
. ReadInt ( FindService
. FIND_MATCHCASE
,  False ))  288          regExprCtrl 
=  wx
. CheckBox ( frame
, - 1 ,  _ ( "Regular expression" ))  289          regExprCtrl
. SetValue ( config
. ReadInt ( FindService
. FIND_MATCHREGEXPR
,  False ))  290          contentSizer
. Add ( wholeWordCtrl
,  0 ,  wx
. BOTTOM
,  SPACE
)  291          contentSizer
. Add ( matchCaseCtrl
,  0 ,  wx
. BOTTOM
,  SPACE
)  292          contentSizer
. Add ( regExprCtrl
,  0 ,  wx
. BOTTOM
,  SPACE
)  293          borderSizer
. Add ( contentSizer
,  0 ,  wx
. TOP | wx
. BOTTOM | wx
. LEFT
,  SPACE
)  295          buttonSizer 
=  wx
. BoxSizer ( wx
. VERTICAL
)  296          findBtn 
=  wx
. Button ( frame
,  wx
. ID_OK
,  _ ( "Find" ))  298          buttonSizer
. Add ( findBtn
,  0 ,  wx
. BOTTOM
,  HALF_SPACE
)  299          buttonSizer
. Add ( wx
. Button ( frame
,  wx
. ID_CANCEL
,  _ ( "Cancel" )),  0 )  300          borderSizer
. Add ( buttonSizer
,  0 ,  wx
. ALL
,  SPACE
)  302          frame
. SetSizer ( borderSizer
)  305          status 
=  frame
. ShowModal ()  307          # save user choice state for this and other Find Dialog Boxes  308          findString 
=  findCtrl
. GetValue ()  309          matchCase 
=  matchCaseCtrl
. IsChecked ()  310          wholeWord 
=  wholeWordCtrl
. IsChecked ()  311          regExpr 
=  regExprCtrl
. IsChecked ()  312          self
. SaveFindConfig ( findString
,  wholeWord
,  matchCase
,  regExpr
)  314          if  status 
==  wx
. ID_OK
:  317              messageService 
=  wx
. GetApp (). GetService ( MessageService
. MessageService
)  318              messageService
. ShowWindow ()  320              view 
=  messageService
. GetView ()  323                  view
. SetCallback ( self
. OnJumpToFoundLine
)  325                  projectService 
=  wx
. GetApp (). GetService ( ProjectEditor
. ProjectService
)  326                  projectFilenames 
=  projectService
. GetFilesFromCurrentProject ()  328                  projView 
=  projectService
. GetView ()  330                      projName 
=  wx
. lib
. docview
. FileNameFromPath ( projView
. GetDocument (). GetFilename ())  331                      view
. AddLines ( PROJECT_MARKER 
+  projName 
+  " \n\n " )  333                  # do search in open files first, open files may have been modified and different from disk because it hasn't been saved  334                  openDocs 
=  wx
. GetApp (). GetDocumentManager (). GetDocuments ()  335                  openDocsInProject 
=  filter ( lambda  openDoc
:  openDoc
. GetFilename ()  in  projectFilenames
,  openDocs
)  336                  for  openDoc 
in  openDocsInProject
:  337                      if  isinstance ( openDoc
,  ProjectEditor
. ProjectDocument
):   # don't search project model  340                      openDocView 
=  openDoc
. GetFirstView ()  341                      # some views don't have a in memory text object to search through such as the PM and the DM  342                      # even if they do have a non-text searchable object, how do we display it in the message window?  343                      if not  hasattr ( openDocView
,  "GetValue" ):  345                      text 
=  openDocView
. GetValue ()  348                      needToDisplayFilename 
=  True  353                          count
,  foundStart
,  foundEnd
,  newText 
=  self
. DoFind ( findString
,  None ,  text
,  start
,  end
,  True ,  matchCase
,  wholeWord
,  regExpr
)  355                              if  needToDisplayFilename
:  356                                  view
. AddLines ( FILENAME_MARKER 
+  openDoc
. GetFilename () +  " \n " )  357                                  needToDisplayFilename 
=  False  359                              lineNum 
=  openDocView
. LineFromPosition ( foundStart
)  360                              line 
=  repr ( lineNum
). zfill ( 4 ) +  ":"  +  openDocView
. GetLine ( lineNum
)  363                              start 
=  text
. find ( " \n " ,  foundStart
)  367                      if not  needToDisplayFilename
:  369                  openDocNames 
=  map ( lambda  openDoc
:  openDoc
. GetFilename (),  openDocs
)  371                  # do search in closed files, skipping the open ones we already searched  372                  filenames 
=  filter ( lambda  filename
:  filename 
not in  openDocNames
,  projectFilenames
)  373                  for  filename 
in  filenames
:  375                          docFile 
=  file ( filename
,  'r' )  376                      except  IOError , ( code
,  message
):  377                          print  _ ( "Warning, unable to read file: ' %s '.   %s " ) % ( filename
,  message
)  381                      needToDisplayFilename 
=  True  382                      line 
=  docFile
. readline ()  384                          count
,  foundStart
,  foundEnd
,  newText 
=  self
. DoFind ( findString
,  None ,  line
,  0 ,  0 ,  True ,  matchCase
,  wholeWord
,  regExpr
)  386                              if  needToDisplayFilename
:  387                                  view
. AddLines ( FILENAME_MARKER 
+  filename 
+  " \n " )  388                                  needToDisplayFilename 
=  False  389                              line 
=  repr ( lineNum
). zfill ( 4 ) +  ":"  +  line
 391                          line 
=  docFile
. readline ()  393                      if not  needToDisplayFilename
:  396                  view
. AddLines ( _ ( "Search for ' %s ' completed." ) %  findString
)  404      def  OnJumpToFoundLine ( self
,  event
):  405          messageService 
=  wx
. GetApp (). GetService ( MessageService
. MessageService
)  406          lineText
,  pos 
=  messageService
. GetView (). GetCurrLine ()  407          if  lineText 
==  " \n "  or  lineText
. find ( FILENAME_MARKER
) != - 1  or  lineText
. find ( PROJECT_MARKER
) != - 1 :  409          lineEnd 
=  lineText
. find ( ":" )  413              lineNum 
=  int ( lineText
[ 0 : lineEnd
])  415          text 
=  messageService
. GetView (). GetText ()  416          curPos 
=  messageService
. GetView (). GetCurrentPos ()  418          startPos 
=  text
. rfind ( FILENAME_MARKER
,  0 ,  curPos
)  419          endPos 
=  text
. find ( " \n " ,  startPos
)  420          filename 
=  text
[ startPos 
+  len ( FILENAME_MARKER
): endPos
]  423          openDocs 
=  wx
. GetApp (). GetDocumentManager (). GetDocuments ()  424          for  openDoc 
in  openDocs
:  425              if  openDoc
. GetFilename () ==  filename
:  426                  foundView 
=  openDoc
. GetFirstView ()  430              doc 
=  wx
. GetApp (). GetDocumentManager (). CreateDocument ( filename
,  wx
. lib
. docview
. DOC_SILENT
)  431              foundView 
=  doc
. GetFirstView ()  434              foundView
. GetFrame (). SetFocus ()  436              if  hasattr ( foundView
,  "GotoLine" ):  437                  foundView
. GotoLine ( lineNum
)  438                  startPos 
=  foundView
. PositionFromLine ( lineNum
)  439                  # wxBug:  Need to select in reverse order, (end, start) to put cursor at head of line so positioning is correct  440                  #         Also, if we use the correct positioning order (start, end), somehow, when we open a edit window for the first  441                  #         time, we don't see the selection, it is scrolled off screen  442                  foundView
. SetSelection ( startPos 
-  1  +  len ( lineText
[ lineEnd
:]. rstrip ( " \n " )),  startPos
)  443                  wx
. GetApp (). GetService ( OutlineService
. OutlineService
). LoadOutline ( foundView
,  position
= startPos
)