📄 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 + -