📄 findindirservice.py
字号:
def SaveFindInDirConfig(self, dirString, searchSubfolders):
""" Save search dir patterns and flags to registry.
dirString = search directory
searchSubfolders = Search subfolders
"""
config = wx.ConfigBase_Get()
config.Write(FIND_MATCHDIR, dirString)
config.WriteInt(FIND_MATCHDIRSUBFOLDERS, searchSubfolders)
def DoFindIn(self, findString, matchCase, wholeWord, regExpr, currFileOnly=False, jumpToFound=False):
messageService = wx.GetApp().GetService(MessageService.MessageService)
if not messageService:
return
messageService.ShowWindow()
view = messageService.GetView()
if not view:
return
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
try:
#Switch to messages tab.
view.GetControl().GetParent().SetSelection(0)
view.ClearLines()
view.SetCallback(self.OnJumpToFoundLine)
projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
if wx.GetApp().GetDocumentManager().GetCurrentView():
currDoc = wx.GetApp().GetDocumentManager().GetCurrentView().GetDocument()
else:
currDoc = None
if currFileOnly:
if currDoc:
projectFilenames = [currDoc.GetFilename()]
view.AddLines(FILE_MARKER + currDoc.GetFilename() + "\n\n")
else:
projectFilenames = []
else:
projectFilenames = projectService.GetFilesFromCurrentProject()
projView = projectService.GetView()
if projView:
projName = wx.lib.docview.FileNameFromPath(projView.GetDocument().GetFilename())
view.AddLines(PROJECT_MARKER + projName + "\n\n")
firstDef = -1
# do search in open files first, open files may have been modified and different from disk because it hasn't been saved
openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
openDocsInProject = filter(lambda openDoc: openDoc.GetFilename() in projectFilenames, openDocs)
if currDoc and currDoc in openDocsInProject:
# make sure current document is searched first.
openDocsInProject.remove(currDoc)
openDocsInProject.insert(0, currDoc)
for openDoc in openDocsInProject:
if isinstance(openDoc, ProjectEditor.ProjectDocument): # don't search project model
continue
openDocView = openDoc.GetFirstView()
# some views don't have a in memory text object to search through such as the PM and the DM
# even if they do have a non-text searchable object, how do we display it in the message window?
if not hasattr(openDocView, "GetValue"):
continue
text = openDocView.GetValue()
lineNum = 1
needToDisplayFilename = True
start = 0
end = 0
count = 0
while count != -1:
count, foundStart, foundEnd, newText = self.DoFind(findString, None, text, start, end, True, matchCase, wholeWord, regExpr)
if count != -1:
if needToDisplayFilename:
view.AddLines(FILENAME_MARKER + openDoc.GetFilename() + "\n")
needToDisplayFilename = False
lineNum = openDocView.LineFromPosition(foundStart)
line = repr(lineNum).zfill(4) + ":" + openDocView.GetLine(lineNum)
view.AddLines(line)
if firstDef == -1:
firstDef = view.GetControl().GetCurrentLine() - 1
start = text.find("\n", foundStart)
if start == -1:
break
end = start
if not needToDisplayFilename:
view.AddLines("\n")
wx.GetApp().Yield(True)
openDocNames = map(lambda openDoc: openDoc.GetFilename(), openDocs)
# do search in closed files, skipping the open ones we already searched
filenames = filter(lambda filename: filename not in openDocNames, projectFilenames)
for filename in filenames:
try:
docFile = file(filename, 'r')
except IOError, (code, message):
print _("Warning, unable to read file: '%s'. %s") % (filename, message)
continue
lineNum = 1
needToDisplayFilename = True
line = docFile.readline()
while line:
count, foundStart, foundEnd, newText = self.DoFind(findString, None, line, 0, 0, True, matchCase, wholeWord, regExpr)
if count != -1:
if needToDisplayFilename:
view.AddLines(FILENAME_MARKER + filename + "\n")
needToDisplayFilename = False
line = repr(lineNum).zfill(4) + ":" + line
view.AddLines(line)
if firstDef == -1:
firstDef = view.GetControl().GetCurrentLine() - 1
line = docFile.readline()
lineNum += 1
if not needToDisplayFilename:
view.AddLines("\n")
wx.GetApp().Yield(True)
view.AddLines(_("Search for '%s' completed.") % findString)
if jumpToFound:
self.OnJumpToFoundLine(event=None, defLineNum=firstDef)
finally:
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
def FindInProject(self, findString):
self.DoFindIn(findString, matchCase=True, wholeWord=True, regExpr=True, jumpToFound=True)
def ShowFindInProjectDialog(self, findString=None):
config = wx.ConfigBase_Get()
frame = wx.Dialog(wx.GetApp().GetTopWindow(), -1, _("Find in Project"), size= (320,200))
borderSizer = wx.BoxSizer(wx.HORIZONTAL)
contentSizer = wx.BoxSizer(wx.VERTICAL)
lineSizer = wx.BoxSizer(wx.HORIZONTAL)
lineSizer.Add(wx.StaticText(frame, -1, _("Find what:")), 0, wx.ALIGN_CENTER | wx.RIGHT, HALF_SPACE)
if not findString:
findString = config.Read(FindService.FIND_MATCHPATTERN, "")
findCtrl = wx.TextCtrl(frame, -1, findString, size=(200,-1))
lineSizer.Add(findCtrl, 0, wx.LEFT, HALF_SPACE)
contentSizer.Add(lineSizer, 0, wx.BOTTOM, SPACE)
wholeWordCtrl = wx.CheckBox(frame, -1, _("Match whole word only"))
wholeWordCtrl.SetValue(config.ReadInt(FindService.FIND_MATCHWHOLEWORD, False))
matchCaseCtrl = wx.CheckBox(frame, -1, _("Match case"))
matchCaseCtrl.SetValue(config.ReadInt(FindService.FIND_MATCHCASE, False))
regExprCtrl = wx.CheckBox(frame, -1, _("Regular expression"))
regExprCtrl.SetValue(config.ReadInt(FindService.FIND_MATCHREGEXPR, False))
contentSizer.Add(wholeWordCtrl, 0, wx.BOTTOM, SPACE)
contentSizer.Add(matchCaseCtrl, 0, wx.BOTTOM, SPACE)
contentSizer.Add(regExprCtrl, 0, wx.BOTTOM, SPACE)
borderSizer.Add(contentSizer, 0, wx.TOP | wx.BOTTOM | wx.LEFT, SPACE)
buttonSizer = wx.BoxSizer(wx.VERTICAL)
findBtn = wx.Button(frame, wx.ID_OK, _("Find"))
findBtn.SetDefault()
BTM_SPACE = HALF_SPACE
if wx.Platform == "__WXMAC__":
BTM_SPACE = SPACE
buttonSizer.Add(findBtn, 0, wx.BOTTOM, BTM_SPACE)
buttonSizer.Add(wx.Button(frame, wx.ID_CANCEL), 0)
borderSizer.Add(buttonSizer, 0, wx.ALL, SPACE)
frame.SetSizer(borderSizer)
frame.Fit()
frame.CenterOnParent()
status = frame.ShowModal()
# save user choice state for this and other Find Dialog Boxes
findString = findCtrl.GetValue()
matchCase = matchCaseCtrl.IsChecked()
wholeWord = wholeWordCtrl.IsChecked()
regExpr = regExprCtrl.IsChecked()
self.SaveFindConfig(findString, wholeWord, matchCase, regExpr)
frame.Destroy()
if status == wx.ID_OK:
self.DoFindIn(findString, matchCase, wholeWord, regExpr)
return True
else:
return False
def ShowFindInFileDialog(self, findString=None):
config = wx.ConfigBase_Get()
frame = wx.Dialog(wx.GetApp().GetTopWindow(), -1, _("Find in File"), size= (320,200))
borderSizer = wx.BoxSizer(wx.HORIZONTAL)
contentSizer = wx.BoxSizer(wx.VERTICAL)
lineSizer = wx.BoxSizer(wx.HORIZONTAL)
lineSizer.Add(wx.StaticText(frame, -1, _("Find what:")), 0, wx.ALIGN_CENTER | wx.RIGHT, HALF_SPACE)
if not findString:
findString = config.Read(FindService.FIND_MATCHPATTERN, "")
findCtrl = wx.TextCtrl(frame, -1, findString, size=(200,-1))
lineSizer.Add(findCtrl, 0, wx.LEFT, HALF_SPACE)
contentSizer.Add(lineSizer, 0, wx.BOTTOM, SPACE)
wholeWordCtrl = wx.CheckBox(frame, -1, _("Match whole word only"))
wholeWordCtrl.SetValue(config.ReadInt(FindService.FIND_MATCHWHOLEWORD, False))
matchCaseCtrl = wx.CheckBox(frame, -1, _("Match case"))
matchCaseCtrl.SetValue(config.ReadInt(FindService.FIND_MATCHCASE, False))
regExprCtrl = wx.CheckBox(frame, -1, _("Regular expression"))
regExprCtrl.SetValue(config.ReadInt(FindService.FIND_MATCHREGEXPR, False))
contentSizer.Add(wholeWordCtrl, 0, wx.BOTTOM, SPACE)
contentSizer.Add(matchCaseCtrl, 0, wx.BOTTOM, SPACE)
contentSizer.Add(regExprCtrl, 0, wx.BOTTOM, SPACE)
borderSizer.Add(contentSizer, 0, wx.TOP | wx.BOTTOM | wx.LEFT, SPACE)
buttonSizer = wx.BoxSizer(wx.VERTICAL)
findBtn = wx.Button(frame, wx.ID_OK, _("Find"))
findBtn.SetDefault()
BTM_SPACE = HALF_SPACE
if wx.Platform == "__WXMAC__":
BTM_SPACE = SPACE
buttonSizer.Add(findBtn, 0, wx.BOTTOM, BTM_SPACE)
buttonSizer.Add(wx.Button(frame, wx.ID_CANCEL), 0)
borderSizer.Add(buttonSizer, 0, wx.ALL, SPACE)
frame.SetSizer(borderSizer)
frame.Fit()
frame.CenterOnParent()
status = frame.ShowModal()
# save user choice state for this and other Find Dialog Boxes
findString = findCtrl.GetValue()
matchCase = matchCaseCtrl.IsChecked()
wholeWord = wholeWordCtrl.IsChecked()
regExpr = regExprCtrl.IsChecked()
self.SaveFindConfig(findString, wholeWord, matchCase, regExpr)
frame.Destroy()
if status == wx.ID_OK:
self.DoFindIn(findString, matchCase, wholeWord, regExpr, currFileOnly=True)
return True
else:
return False
def OnJumpToFoundLine(self, event=None, defLineNum=-1):
messageService = wx.GetApp().GetService(MessageService.MessageService)
if defLineNum == -1:
lineText, pos = messageService.GetView().GetCurrLine()
else:
lineText = messageService.GetView().GetControl().GetLine(defLineNum)
pos = 0
if lineText == "\n" or lineText.find(FILENAME_MARKER) != -1 or lineText.find(PROJECT_MARKER) != -1 or lineText.find(FILE_MARKER) != -1:
return
lineEnd = lineText.find(":")
if lineEnd == -1:
return
else:
lineNum = int(lineText[0:lineEnd])
text = messageService.GetView().GetText()
if defLineNum == -1:
curPos = messageService.GetView().GetCurrentPos()
else:
curPos = messageService.GetView().GetControl().GetLineEndPosition(defLineNum)
startPos = text.rfind(FILENAME_MARKER, 0, curPos)
endPos = text.find("\n", startPos)
filename = text[startPos + len(FILENAME_MARKER):endPos]
foundView = None
openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
for openDoc in openDocs:
if openDoc.GetFilename() == filename:
foundView = openDoc.GetFirstView()
break
if not foundView:
doc = wx.GetApp().GetDocumentManager().CreateDocument(filename, wx.lib.docview.DOC_SILENT|wx.lib.docview.DOC_OPEN_ONCE)
if doc:
foundView = doc.GetFirstView()
if foundView:
foundView.GetFrame().SetFocus()
foundView.Activate()
if hasattr(foundView, "GotoLine"):
foundView.GotoLine(lineNum)
startPos = foundView.PositionFromLine(lineNum)
# wxBug: Need to select in reverse order, (end, start) to put cursor at head of line so positioning is correct
# Also, if we use the correct positioning order (start, end), somehow, when we open a edit window for the first
# time, we don't see the selection, it is scrolled off screen
foundView.SetSelection(startPos - 1 + len(lineText[lineEnd:].rstrip("\n")), startPos)
wx.GetApp().GetService(OutlineService.OutlineService).LoadOutline(foundView, position=startPos)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -