# Programmer: Daniel Pozmanter # E-mail: drpython@bluebottle.com # Note: You must reply to the verification e-mail to get through. # # Copyright 2003-2005 Daniel Pozmanter # # Distributed under the terms of the GPL (GNU Public License) # # DrPython is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #FindReplace Dialog import wx import wx.stc import drScrolledMessageDialog import re class drFinder: #copy old finder limodou 2004/04/19 def __init__(self, parent, stc, oldfinder=None): #end limodou self.parent = parent self.stc = stc self.reset() #copy old finder limodou 2004/04/19 self.Copy(oldfinder) #end limodou #copy old finder limodou 2004/04/19 def Copy(self, finder): if finder: self.findtext = finder.findtext self.findflags = finder.findflags self.backwards = finder.backwards #Franz: Bug Report with Fix self.RE = finder.RE #Moved here by Dan. #Edited by Dan #(Bug Report, Franz.) #copy old finder limodou 2004/04/19 self.docEnd = self.stc.GetTextLength() self.SetTargetRange(0, self.docEnd) #end limodou #end limodou def DoFind(self, findtext, findflags, backwards=False): self.RE = 0 self.rectanglefind = 0 doclength = self.stc.GetLength() self.findtext = findtext self.findflags = findflags prev = self.findpos if self.backwards != backwards: self.backwards = backwards if (backwards): endpos = self.targetStart else: endpos = self.targetEnd self.findpos = self.stc.FindText(self.findpos, endpos, findtext, findflags) if (self.findpos == -1): if self.stc.FindText(self.targetStart, self.targetEnd, findtext, findflags) == -1: drScrolledMessageDialog.ShowMessage(self.parent, ('Search string "' + findtext + '" not found.'), "DrPython Find") return if ((self.findpos >= doclength) or (self.findpos < 0)) and (doclength > 0): self.lastposition = -1 if self.backwards: msg = 'Start of document reached: "' + findtext + '".\nStart again from the end?' self.findpos = self.targetEnd else: msg = 'End of document reached: "' + findtext + '".\nStart again from the beginning?' self.findpos = self.targetStart if self.parent.prefs.findreplaceautowrap: answer = wx.ID_OK else: d = wx.MessageDialog(self.parent, msg, "DrPython Find", wx.OK | wx.CANCEL | wx.ICON_QUESTION) answer = d.ShowModal() d.Destroy() if (answer == wx.ID_OK): self.stc.GotoPos(self.findpos) if self.backwards: self.DoFindPrevious() else: self.DoFindNext() else: self.stc.GotoPos(prev) return if self.parent.prefs.docfolding: self.stc.EnsureVisible(self.stc.LineFromPosition(self.findpos)) endpos = self.findpos + len(findtext) self.stc.EnsurePositionIsVisible(endpos) self.stc.GotoPos(self.findpos) self.stc.SetSelectionStart(self.findpos) self.stc.SetSelectionEnd(endpos) self.lastposition = self.findpos + len(findtext) if (backwards): self.findpos = self.findpos - 1 else: self.findpos = self.findpos + 1 def DoREFind(self, findtext, matchcase): self.RE = 1 self.rectanglefind = 0 self.findtext = findtext self.findflags = matchcase prev = self.findpos case = 0 if (not matchcase): case = re.IGNORECASE try: regularexpression = re.compile(findtext, case | re.MULTILINE) except: drScrolledMessageDialog.ShowMessage(self.parent, 'Regular Expression Error', "DrPython Find") return endpos = self.targetEnd matchedtext = regularexpression.search(self.stc.GetText()[self.findpos:endpos]) if matchedtext is None: testforexist = regularexpression.search(self.stc.GetText()) if testforexist is None: drScrolledMessageDialog.ShowMessage(self.parent, ('Regular expression "' + findtext + '" not found.'), "DrPython Find") return self.lastposition = -1 if (prev > self.targetStart): self.findpos = self.targetStart if self.parent.prefs.findreplaceautowrap: answer = wx.ID_OK else: d = wx.MessageDialog(self.parent, 'End of document reached: "' + findtext + '".\nStart again from the beginning?', "DrPython Find", wx.OK | wx.CANCEL | wx.ICON_QUESTION) answer = d.ShowModal() d.Destroy() if (answer == wx.ID_OK): self.stc.GotoPos(self.findpos) self.DoFindNext() else: self.stc.GotoPos(prev) return oldpos = self.findpos self.findpos = oldpos + matchedtext.start() endpos = oldpos + matchedtext.end() if self.parent.prefs.docfolding: self.stc.EnsureVisible(self.stc.LineFromPosition(self.findpos)) self.stc.EnsurePositionIsVisible(endpos) self.stc.GotoPos(self.findpos) self.stc.SetSelectionStart(self.findpos) self.stc.SetSelectionEnd(endpos) self.lastposition = endpos self.findpos = endpos def DoFindNext(self): if len(self.findtext) < 1: return if not self.inselection: textlength = self.stc.GetTextLength() if textlength != self.docEnd: self.docEnd = textlength self.SetTargetRange(0, self.docEnd) self.findpos = self.stc.GetCurrentPos() if (not self.RE): if self.rectanglefind: self.DoRectangleFind(self.findtext, self.findflags) else: self.DoFind(self.findtext, self.findflags) return if self.rectanglefind: self.DoRERectangleFind(self.findtext, self.findflags) return self.DoREFind(self.findtext, self.findflags) def DoFindPrevious(self): if len(self.findtext) < 1: return if not self.inselection: textlength = self.stc.GetTextLength() if textlength != self.docEnd: self.docEnd = textlength self.SetTargetRange(self.docEnd, 0) self.findpos = self.stc.GetCurrentPos() if (not self.RE): if (self.findpos == self.lastposition) and not self.rectanglefind: self.findpos = self.findpos - len(self.findtext) - 1 self.stc.GotoPos(self.findpos) elif self.rectanglefind and (self.lastposition == -1) and (not self.backwards): self.stc.GotoPos(self.findpos) if self.rectanglefind: self.DoRectangleFind(self.findtext, self.findflags, True) else: self.DoFind(self.findtext, self.findflags, True) else: drScrolledMessageDialog.ShowMessage(self.parent, 'Find Previous Not Possible:\nRegular Expressions Are On.', 'DrPython Find') def DoRectangleFind(self, findtext, matchcase, backwards=False): self.RE = 0 self.rectanglefind = 1 doclength = self.stc.GetLength() lenlines = len(self.Lines) if matchcase: self.findtext = findtext else: self.findtext = findtext.lower() prev = self.findpos if self.backwards != backwards: self.backwards = backwards self.findpos = self.stc.GetCurrentPos() endpos = self.targetEnd lineArrayPosition = self.getArrayPosition(self.findpos) if lineArrayPosition == -1: self.findpos = self.findpos - 1 lineArrayPosition = self.getArrayPosition(self.findpos - 1) if lineArrayPosition == -1: self.findpos = -1 else: relative_findpos = self.positions[lineArrayPosition].index(self.findpos) + 1 else: relative_findpos = self.positions[lineArrayPosition].index(self.findpos) if self.findpos > -1: self.findpos = self.findInArray(lineArrayPosition, relative_findpos) if (self.findpos == -1): if self.backwards: notFound = self.findInArray(0, self.positions[lenlines-1][len(self.positions[lenlines-1])-1]) == -1 else: notFound = self.findInArray(0, 0) == -1 if notFound: drScrolledMessageDialog.ShowMessage(self.parent, ('Search string "' + findtext + '" not found.'), "DrPython Find") return if ((self.findpos >= doclength) or (self.findpos < 0)) and (doclength > 0): self.lastposition = -1 if self.backwards: msg = 'Start of document reached: "' + findtext + '".\nStart again from the end?' self.findpos = self.targetEnd else: msg = 'End of document reached: "' + findtext + '".\nStart again from the beginning?' self.findpos = self.targetStart if self.parent.prefs.findreplaceautowrap: answer = wx.ID_OK else: d = wx.MessageDialog(self.parent, msg, "DrPython Find", wx.OK | wx.CANCEL | wx.ICON_QUESTION) answer = d.ShowModal() d.Destroy() if (answer == wx.ID_OK): self.stc.GotoPos(self.findpos) if self.backwards: self.DoFindPrevious() else: self.DoFindNext() else: self.stc.GotoPos(prev) return if self.parent.prefs.docfolding: self.stc.EnsureVisible(self.stc.LineFromPosition(self.findpos)) endpos = self.findpos + len(findtext) self.stc.EnsurePositionIsVisible(endpos) self.stc.GotoPos(self.findpos) self.stc.SetSelectionStart(self.findpos) self.stc.SetSelectionEnd(endpos) self.lastposition = self.findpos + len(findtext) def DoRERectangleFind(self, findtext, matchcase): self.RE = 1 self.rectanglefind = 1 doclength = self.stc.GetLength() self.findtext = findtext self.findflags = matchcase prev = self.findpos case = 0 if (not matchcase): case = re.IGNORECASE try: regularexpression = re.compile(findtext, case | re.MULTILINE) except: drScrolledMessageDialog.ShowMessage(self.parent, 'Regular Expression Error', "DrPython Find") return endpos = self.targetEnd if (self.findpos >= doclength) or (self.findpos < 0): self.findpos = 0 lineArrayPosition = self.getArrayPosition(self.findpos) if lineArrayPosition == -1: self.findpos = self.findpos - 1 lineArrayPosition = self.getArrayPosition(self.findpos - 1) if lineArrayPosition == -1: self.findpos = -1 else: relative_findpos = self.positions[lineArrayPosition].index(self.findpos) + 1 else: relative_findpos = self.positions[lineArrayPosition].index(self.findpos) if self.findpos > -1: matchedtext, newArrayPosition = self.searchInArray(regularexpression, lineArrayPosition, relative_findpos) else: matchedtext = None if matchedtext is None: testforexist, nap = self.searchInArray(regularexpression, 0, 0) if testforexist is None: drScrolledMessageDialog.ShowMessage(self.parent, ('Regular expression "' + findtext + '" not found.'), "DrPython Find") return self.lastposition = -1 if (prev > self.targetStart): self.findpos = self.targetStart if self.parent.prefs.findreplaceautowrap: answer = wx.ID_OK else: d = wx.MessageDialog(self.parent, 'End of document reached: "' + findtext + '".\nStart again from the beginning?', "DrPython Find", wx.OK | wx.CANCEL | wx.ICON_QUESTION) answer = d.ShowModal() d.Destroy() if (answer == wx.ID_OK): self.stc.GotoPos(self.findpos) self.DoFindNext() else: self.stc.GotoPos(prev) return relative_findpos = matchedtext.start() self.findpos = self.positions[newArrayPosition][relative_findpos] endpos = self.findpos + (matchedtext.end() - matchedtext.start()) if self.parent.prefs.docfolding: self.stc.EnsureVisible(self.stc.LineFromPosition(self.findpos)) self.stc.EnsurePositionIsVisible(endpos) self.stc.GotoPos(self.findpos) self.stc.SetSelectionStart(self.findpos) self.stc.SetSelectionEnd(endpos) self.lastposition = endpos self.findpos = endpos def findInArray(self, arrayposition, position): if self.backwards: r = self.Lines[arrayposition][:position].rfind(self.findtext) if r == -1: arrayposition -= 1 while arrayposition > -1: r = self.Lines[arrayposition].rfind(self.findtext) if r == -1: arrayposition -= 1 else: return self.positions[arrayposition][r] else: return self.positions[arrayposition][r] else: l = len(self.Lines) r = self.Lines[arrayposition][position:].find(self.findtext) if r == -1: arrayposition += 1 while arrayposition < l: r = self.Lines[arrayposition].find(self.findtext) if r == -1: arrayposition += 1 else: return self.positions[arrayposition][r] else: return self.positions[arrayposition][r] return -1 def getArrayPosition(self, position): x = 0 for posArray in self.positions: if position in posArray: return x x += 1 return -1 def GetFindPos(self): return self.findpos def GetFindText(self): return self.findtext def RectangleReplaceAll(self, findtext, replacetext, matchcase): targetText = self.stc.GetSelectedText() if not matchcase: targetText = targetText.lower() eolchar = self.stc.GetEndOfLineCharacter() lines = targetText.strip().split(eolchar) c = self.stc.GetColumn(self.targetStart) linenumber = self.stc.LineFromPosition(self.targetStart) lenline = len(lines[0]) x = 0 for line in lines: position_of_first_character = c + self.stc.PositionFromLine(linenumber) p = line.find(findtext) if p > -1: line = line.replace(findtext, replacetext) self.stc.SetTargetStart(position_of_first_character) self.stc.SetTargetEnd(position_of_first_character+lenline) self.stc.ReplaceTarget(line) x = x + 1 linenumber = linenumber + 1 return x def RectangleREReplaceAll(self, findtext, replacetext, matchcase): case = 0 if (not matchcase): case = re.IGNORECASE try: regularexpression = re.compile(findtext, case | re.MULTILINE) except: drScrolledMessageDialog.ShowMessage(self.parent, 'Regular Expression Error', "DrPython Replace") return targetText = self.stc.GetSelectedText() if not matchcase: targetText = targetText.lower() eolchar = self.stc.GetEndOfLineCharacter() lines = targetText.strip().split(eolchar) c = self.stc.GetColumn(self.targetStart) linenumber = self.stc.LineFromPosition(self.targetStart) lenline = len(lines[0]) y = 0 for line in lines: #You need to update the position(do the replace) during the loop. position_of_first_character = c + self.stc.PositionFromLine(linenumber) line, x = regularexpression.subn(replacetext, line) y = y + x self.stc.SetTargetStart(position_of_first_character) self.stc.SetTargetEnd(position_of_first_character+lenline) self.stc.ReplaceTarget(line) linenumber = linenumber + 1 return y def ReplaceAll(self, findtext, replacetext, flags, prompt = 0): p = self.stc.FindText(self.targetStart, self.targetEnd, findtext, flags) diff = len(replacetext) - len(findtext) x = 0 notfirst = 0 favpos = wx.Point(5, 5) while (p is not -1): if self.parent.prefs.docfolding: self.stc.EnsureVisible(self.stc.LineFromPosition(p)) self.stc.GotoPos(p) self.stc.EnsureCaretVisible() self.stc.SetTargetStart(p) self.stc.SetTargetEnd(p + len(findtext)) if prompt: self.stc.SetSelection(p, (p + len(findtext))) d = wx.SingleChoiceDialog(self.parent, ("Found \"" + findtext + "\" at Line: " \ + str(self.stc.LineFromPosition(p)+1) + \ " Col: " + str(self.stc.GetColumn(p)) + "\n(Hit Cancel to Stop)"), "Replace", ["Replace", "Skip"], wx.CHOICEDLG_STYLE) if notfirst: d.Move(favpos) else: notfirst = 1 answer = d.ShowModal() favpos = d.GetPosition() d.Destroy() if (answer == wx.ID_OK): if (d.GetStringSelection() == "Replace"): self.stc.ReplaceTarget(replacetext) self.targetEnd = self.targetEnd + diff else: x = x - 1 p = p + 1 p = self.stc.FindText((p + len(replacetext)), self.targetEnd, findtext, flags) else: p = -1 x = x - 1 else: self.stc.ReplaceTarget(replacetext) self.targetEnd = self.targetEnd + diff p = self.stc.FindText((p + len(replacetext)), self.targetEnd, findtext, flags) x = x + 1 return x def REReplaceAll(self, findtext, replacetext, matchcase, prompt = 0): case = 0 if (not matchcase): case = re.IGNORECASE try: regularexpression = re.compile(findtext, case | re.MULTILINE) except: drScrolledMessageDialog.ShowMessage(self.parent, 'Regular Expression Error', "DrPython Replace") return oldtext = self.stc.GetText() if not prompt: newtext, x = regularexpression.subn(replacetext, oldtext[self.targetStart:self.targetEnd]) self.stc.SetText(oldtext[0:self.targetStart] + newtext + oldtext[self.targetEnd:]) else: matchedtext = regularexpression.search(self.stc.GetText()[self.findpos:self.targetEnd]) diff = len(replacetext) - len(findtext) x = 0 notfirst = 0 favpos = wx.Point(5, 5) while matchedtext is not None: oldpos = self.findpos self.findpos = oldpos + matchedtext.start() endpos = oldpos + matchedtext.end() if self.parent.prefs.docfolding: self.stc.EnsureVisible(self.stc.LineFromPosition(self.findpos)) self.stc.GotoPos(self.findpos) self.stc.EnsureCaretVisible() self.stc.SetSelectionStart(self.findpos) self.stc.SetSelectionEnd(endpos) self.stc.SetTargetStart(self.findpos) self.stc.SetTargetEnd(endpos) d = wx.SingleChoiceDialog(self.parent, ("Found \"" + findtext + "\" at Line: " \ + str(self.stc.LineFromPosition(self.findpos)+1) + \ " Col: " + str(self.stc.GetColumn(self.findpos)) + \ "\n(Hit Cancel to Stop)"), "Replace", ["Replace", "Skip"], wx.CHOICEDLG_STYLE) if notfirst: d.Move(favpos) else: notfirst = 1 answer = d.ShowModal() favpos = d.GetPosition() d.Destroy() if (answer == wx.ID_OK): if (d.GetStringSelection() == "Replace"): self.stc.ReplaceTarget(replacetext) self.findpos = self.findpos + len(replacetext) self.targetEnd = self.targetEnd + diff else: self.findpos = endpos x = x - 1 x = x + 1 matchedtext = regularexpression.search(self.stc.GetText()[self.findpos:self.targetEnd]) else: matchedtext = None return x def reset(self): self.inselection = 0 self.findflags = 0 self.findpos = 0 self.lastposition = 0 self.backwards = 0 self.findtext = "" self.targetStart = 0 self.targetEnd = 0 self.docEnd = 0 self.RE = 0 self.rectanglefind = 0 def searchInArray(self, regularexpression, arrayposition, position): l = len(self.Lines) match = regularexpression.search(self.Lines[arrayposition][position:]) if match == None: arrayposition += 1 while arrayposition < l: match = regularexpression.search(self.Lines[arrayposition]) if match == None: arrayposition += 1 else: return match, arrayposition return match, arrayposition def SetFindPos(self, findpos): self.findpos = findpos def SetFindText(self, findtext): self.findtext = findtext def SetTargetPositions(self, matchcase): self.targetText = self.stc.GetSelectedText() self.findflags = matchcase if not matchcase: self.targetText = self.targetText.lower() eolchar = self.stc.GetEndOfLineCharacter() self.Lines = self.targetText.strip().split(eolchar) self.targetText = self.targetText.replace(eolchar, '') c = self.stc.GetColumn(self.targetStart) linenumber = self.stc.LineFromPosition(self.targetStart) lenline = len(self.Lines[0]) self.positions = [] for line in self.Lines: position_of_first_character = c + self.stc.PositionFromLine(linenumber) self.positions.append(range(position_of_first_character, position_of_first_character+lenline)) linenumber = linenumber + 1 def SetTargetRange(self, start, end, backwards = 0): self.docEnd = self.stc.GetTextLength() self.inselection = (start > 0) | (end < self.docEnd) self.findpos = start if (backwards): self.findpos = end self.targetStart = start self.targetEnd = end class drFindTextCtrl(wx.ComboBox): def __init__(self, parent, id, value, pos, size, returnfunction = None, InFiles = False): wx.ComboBox.__init__(self, parent, id, value, pos, size) #This is a workaround for a bug in how wx.TextCtrl handles #carriage returns on windows. self.parent = parent if InFiles: self.ancestor = parent.parent.parent else: self.ancestor = parent.parent if self.ancestor.prefs.platform_is_windows: self.doReplace = True self.cr = chr(5) else: self.doReplace = False self.cr = '\r' self.ID_CHAR_BASE = 20 self.ID_MENU_BASE = 50 self.ID_HISTORY_BASE = 420 self.returnfunc = returnfunction if self.returnfunc is None: self.returnfunc = self.parent.OnbtnFind self.Bind(wx.EVT_CHAR, self.OnChar) self.Bind(wx.EVT_RIGHT_DOWN, self.OnPopUp) #wxPython Bug Work-Around if self.ancestor.prefs.platform_is_windows: self.insertionpoint = -1 self.Bind(wx.EVT_SET_FOCUS, self.OnFocus) #franz07/19: catch kill focus self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus) #endfranz07/19 def AppendToHistory(self, targetList): text = self.GetText() try: i = targetList.index(text) targetList.pop(i) except: pass targetList.append(text) def GetText(self): text = self.GetValue() if self.doReplace: return text.replace(chr(5), '\r') else: return text def OnChar(self, event): if (event.GetKeyCode() == wx.WXK_ESCAPE): self.parent.OnbtnCancel(event) elif (event.GetKeyCode() == wx.WXK_RETURN): self.returnfunc(event) else: event.Skip() def OnFocus(self, event): self.insertionpoint = -1 event.Skip() #franz07/19: do not steal focus #drpython: removed "pass", replaced with function code below. def OnKillFocus(self, event): self.insertionpoint = self.GetInsertionPoint() event.Skip() #franz07/19 def OnPopUp(self, event): self.PopUp(event.GetPosition()) def OnPopUpMenu(self, event): eid = event.GetId() pos = self.GetInsertionPoint() #wxPython Bug Work-Around if self.ancestor.prefs.platform_is_windows: if self.insertionpoint > -1: pos = self.insertionpoint text = self.GetValue() if eid == self.ID_CHAR_BASE: self.SetValue(text[:pos] + '\t' + text[pos:]) self.SetInsertionPoint(pos+1) elif eid == self.ID_CHAR_BASE+1: self.SetValue(text[:pos] + '\n' + text[pos:]) self.SetInsertionPoint(pos+1) elif eid == self.ID_CHAR_BASE+2: self.SetValue(text[:pos] + self.cr + text[pos:]) self.SetInsertionPoint(pos+1) elif eid == self.ID_MENU_BASE+1: self.Cut() elif eid == self.ID_MENU_BASE+2: self.Copy() elif eid == self.ID_MENU_BASE+3: self.Paste() elif eid == self.ID_MENU_BASE+4: f, to = self.GetSelection() self.Remove(f, to) elif eid == self.ID_MENU_BASE+5: self.SetValue("") self.SetFocus() def PopUp(self, pos): self.PopUpMenu = wx.Menu() self.CharMenu = wx.Menu() self.CharMenu.Append(self.ID_CHAR_BASE, "Tab (\\t)") self.CharMenu.Append(self.ID_CHAR_BASE+1, "Newline (\\n)") self.CharMenu.Append(self.ID_CHAR_BASE+2, "Carraige Return (\\r)") self.PopUpMenu.Append(self.ID_MENU_BASE+5, "Clear Text") self.PopUpMenu.AppendSeparator() self.PopUpMenu.AppendMenu(self.ID_MENU_BASE, "Insert Special Character", self.CharMenu) self.PopUpMenu.AppendSeparator() self.PopUpMenu.Append(self.ID_MENU_BASE+1, "Cut") self.PopUpMenu.Append(self.ID_MENU_BASE+2, "Copy") self.PopUpMenu.Append(self.ID_MENU_BASE+3, "Paste") self.PopUpMenu.Append(self.ID_MENU_BASE+4, "Delete") x = 0 y = 0 while x < 6: if y < 3: self.Bind(wx.EVT_MENU, self.OnPopUpMenu, id=self.ID_CHAR_BASE+y) y = y + 1 self.Bind(wx.EVT_MENU, self.OnPopUpMenu, id=self.ID_MENU_BASE+x) x = x + 1 self.PopupMenu(self.PopUpMenu, pos) self.PopUpMenu.Destroy() def SetHistory(self, history): if self.GetCount() > 0: self.Clear() l = len(history) self.Append('') x = l - 1 while x > -1: self.Append(history[x]) x = x - 1 if l > 0: self.SetMark(0, len(history[l-1])) class drFindReplaceDialog(wx.Dialog): def __init__(self, parent, id, title, stc, IsReplace = 0): wx.Dialog.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(-1, -1), wx.DEFAULT_DIALOG_STYLE | wx.MAXIMIZE_BOX | wx.THICK_FRAME | wx.RESIZE_BORDER) self.ID_FIND = 1001 self.ID_CANCEL = 1002 self.ID_CHK_REGEX = 1010 self.ID_CREATERE = 1011 self.ID_SEARCH_TXT = 1012 self.ID_BTNSF = 98 self.ID_BTNRW = 99 self.parent = parent self.stc = stc self.theSizer = wx.FlexGridSizer(8, 3, 5, 10) self.IsReplace = IsReplace #Size Buffer self.theSizer.Add(wx.StaticText(self, -1, " "), 1, wx.SHAPED) self.theSizer.Add(wx.StaticText(self, -1, " "), 1, wx.SHAPED) self.theSizer.Add(wx.StaticText(self, -1, " "), 1, wx.SHAPED) self.theSizer.Add(wx.StaticText(self, -1, " "), 1, wx.SHAPED) self.theSizer.Add(wx.StaticText(self, -1, "Search For: "), 1, wx.SHAPED) self.theSizer.Add(wx.StaticText(self, -1, " "), 1, wx.SHAPED) self.txtSearchFor = drFindTextCtrl(self, self.ID_SEARCH_TXT, "", wx.DefaultPosition, wx.Size(250, -1)) self.btnPopUpSearchFor = wx.Button(self, self.ID_BTNSF, " Menu ") self.theSizer.Add(wx.StaticText(self, -1, " "), 1, wx.SHAPED) self.theSizer.Add(self.txtSearchFor, 1, wx.SHAPED) self.theSizer.Add(self.btnPopUpSearchFor, 1, wx.SHAPED) self.txtSearchFor.SetHistory(parent.FindHistory) if (IsReplace): #self.SetSize(wx.Size(400, 345)) self.txtReplaceWith = drFindTextCtrl(self, -1, "", wx.DefaultPosition, wx.Size(250, -1)) self.btnPopUpReplaceWith = wx.Button(self, self.ID_BTNRW, " Menu ") self.txtReplaceWith.SetHistory(parent.ReplaceHistory) self.chkRegularExpression = wx.CheckBox(self, self.ID_CHK_REGEX, "RegularExpression") self.btnCreateRE = wx.Button(self, self.ID_CREATERE, " &Create ") self.chkMatchCase = wx.CheckBox(self, -1, "Match Case") self.chkFindBackwards = wx.CheckBox(self, -1, "Find Backwards") self.chkWholeWord = wx.CheckBox(self, -1, "Whole Word") self.chkInSelection = wx.CheckBox(self, -1, "In Selection") self.chkFromCursor = wx.CheckBox(self, -1, "From Cursor") #Prefs self.chkRegularExpression.SetValue(parent.prefs.findreplaceregularexpression) self.btnCreateRE.Enable(parent.prefs.findreplaceregularexpression) self.chkMatchCase.SetValue(parent.prefs.findreplacematchcase) self.chkFindBackwards.SetValue(parent.prefs.findreplacefindbackwards) self.chkWholeWord.SetValue(parent.prefs.findreplacewholeword) self.chkInSelection.SetValue(parent.prefs.findreplaceinselection) self.chkFromCursor.SetValue(parent.prefs.findreplacefromcursor) self.chkInSelection.Enable(len(parent.txtDocument.GetSelectedText()) > 0) if (IsReplace): self.chkPromptOnReplace = wx.CheckBox(self, -1, "Prompt on Replace") self.theSizer.Add(wx.StaticText(self, -1, " "), 1, wx.SHAPED) self.theSizer.Add(wx.StaticText(self, -1, "Replace With: "), 1, wx.SHAPED) self.theSizer.Add(wx.StaticText(self, -1, " "), 1, wx.SHAPED) self.theSizer.Add(wx.StaticText(self, -1, " "), 1, wx.SHAPED) self.theSizer.Add(self.txtReplaceWith, 1 ,wx.SHAPED) self.theSizer.Add(self.btnPopUpReplaceWith, 1, wx.SHAPED) self.chkFromCursor.Disable() self.chkFindBackwards.Disable() #Prefs self.chkPromptOnReplace.SetValue(parent.prefs.findreplacepromptonreplace) self.Bind(wx.EVT_BUTTON, self.OnbtnPopUp, id=self.ID_BTNRW) #Size Buffer self.theSizer.Add(wx.StaticText(self, -1, " "), 1, wx.SHAPED) self.theSizer.Add(wx.StaticText(self, -1, " "), 1, wx.SHAPED) self.theSizer.Add(wx.StaticText(self, -1, " "), 1, wx.SHAPED) self.theSizer.Add(wx.StaticText(self, -1, " "), 1, wx.SHAPED) self.theSizer.Add(self.chkRegularExpression, 1, wx.SHAPED) self.theSizer.Add(self.btnCreateRE, 1, wx.SHAPED) self.theSizer.Add(wx.StaticText(self, -1, " "), 1, wx.SHAPED) self.theSizer.Add(self.chkMatchCase, 1, wx.SHAPED) self.theSizer.Add(self.chkFindBackwards, 1, wx.SHAPED) self.theSizer.Add(wx.StaticText(self, -1, " "), 1, wx.SHAPED) self.theSizer.Add(self.chkWholeWord, 1, wx.SHAPED) self.theSizer.Add(self.chkInSelection, 1, wx.SHAPED) self.theSizer.Add(wx.StaticText(self, -1, " "), 1, wx.SHAPED) self.theSizer.Add(self.chkFromCursor, 1, wx.SHAPED) if (IsReplace): self.theSizer.Add(self.chkPromptOnReplace, 1, wx.SHAPED) else: self.theSizer.Add(wx.StaticText(self, -1, " "), 1, wx.SHAPED) self.theSizer.Add(wx.StaticText(self, -1, " "), 1, wx.SHAPED) self.theSizer.Add(wx.StaticText(self, -1, " "), 1, wx.SHAPED) self.theSizer.Add(wx.StaticText(self, -1, " "), 1, wx.SHAPED) self.btnCancel = wx.Button(self, self.ID_CANCEL, "&Cancel") self.btnFind = wx.Button(self, self.ID_FIND, "&Ok") self.btnFind.Enable(False) self.theSizer.Add(wx.StaticText(self, -1, " "), 1, wx.SHAPED) self.theSizer.Add(self.btnCancel, 1, wx.SHAPED) self.theSizer.Add(self.btnFind, 1, wx.SHAPED) self.SetAutoLayout(True) self.SetSizerAndFit(self.theSizer) self.btnFind.SetDefault() self.txtSearchFor.SetFocus() self.Bind(wx.EVT_BUTTON, self.OnbtnCancel, id=self.ID_CANCEL) self.Bind(wx.EVT_BUTTON, self.OnbtnFind, id=self.ID_FIND) self.Bind(wx.EVT_BUTTON, self.OnbtnCreateRE, id=self.ID_CREATERE) self.Bind(wx.EVT_BUTTON, self.OnbtnPopUp, id=self.ID_BTNSF) self.Bind(wx.EVT_CHECKBOX, self.OnCheckRegularExpression, id=self.ID_CHK_REGEX) self.Bind(wx.EVT_TEXT, self.OnTextChanged, id=self.ID_SEARCH_TXT) self.parent.LoadDialogSizeAndPosition(self, 'findreplacedialog.sizeandposition.dat') def OnCloseW(self, event): self.parent.SaveDialogSizeAndPosition(self, 'findreplacedialog.sizeandposition.dat') if event is not None: event.Skip() def GetOptions(self): rarray = [self.chkRegularExpression.GetValue(), self.chkMatchCase.GetValue(), \ self.chkFindBackwards.GetValue(), self.chkWholeWord.GetValue(), \ self.chkInSelection.GetValue(), self.chkFromCursor.GetValue()] if (self.IsReplace): rarray.append(self.chkPromptOnReplace.GetValue()) return rarray def OnbtnCancel(self, event): self.Close(1) def OnbtnCreateRE(self, event): from drRegularExpressionDialog import drRegularExpressionDialog d = drRegularExpressionDialog(self, -1, "Create Regular Expression") d.Show() def OnbtnFind(self, event): if not self.btnFind.IsEnabled(): return self.Show(0) findflags = 0 findbackwards = self.chkFindBackwards.GetValue() isRegularExpression = self.chkRegularExpression.GetValue() isMatchCase = self.chkMatchCase.GetValue() self.txtSearchFor.AppendToHistory(self.parent.FindHistory) if self.IsReplace: self.txtReplaceWith.AppendToHistory(self.parent.ReplaceHistory) #Set Target Range if (self.chkInSelection.GetValue()): selstart = self.stc.GetSelectionStart() selend = self.stc.GetSelectionEnd() if (selend - selstart) < 1: selstart = 0 selend = self.stc.GetTextLength() self.stc.Finder.SetTargetRange(selstart, selend, findbackwards) #Do the Search if it's a rectangle: if self.stc.SelectionIsRectangle(): if self.IsReplace: if isRegularExpression: x = self.stc.Finder.RectangleREReplaceAll(self.txtSearchFor.GetText(), self.txtReplaceWith.GetText(), isMatchCase) if self.parent.prefs.enablefeedback: drScrolledMessageDialog.ShowMessage(self, (str(x) + " occurances of \"" + self.txtSearchFor.GetText() + "\" replaced with \"" + self.txtReplaceWith.GetText() + "\""), "Replace") else: x = self.stc.Finder.RectangleReplaceAll(self.txtSearchFor.GetText(), self.txtReplaceWith.GetText(), isMatchCase) if self.parent.prefs.enablefeedback: drScrolledMessageDialog.ShowMessage(self, (str(x) + " occurances of \"" + self.txtSearchFor.GetText() + "\" replaced with \"" + self.txtReplaceWith.GetText() + "\""), "Replace") else: self.stc.Finder.SetTargetPositions(isMatchCase) if isRegularExpression: self.stc.Finder.DoRERectangleFind(self.txtSearchFor.GetText(), isMatchCase) else: self.stc.Finder.DoRectangleFind(self.txtSearchFor.GetText(), isMatchCase, findbackwards) self.Close(1) return else: self.stc.Finder.SetTargetRange(0, self.stc.GetTextLength(), findbackwards) if (self.chkFromCursor.GetValue()) and (not self.IsReplace): self.stc.Finder.SetFindPos(self.stc.GetCurrentPos()) #Do Search if (isRegularExpression): if (self.IsReplace): x = self.stc.Finder.REReplaceAll(self.txtSearchFor.GetText(), self.txtReplaceWith.GetText(), isMatchCase, self.chkPromptOnReplace.GetValue()) if x == 0: drScrolledMessageDialog.ShowMessage(self, 'Search string: "' + self.txtSearchFor.GetText() + '" not found.', 'DrPython Replace') elif self.parent.prefs.enablefeedback: drScrolledMessageDialog.ShowMessage(self, (str(x) + " occurances of \"" + self.txtSearchFor.GetText() + "\" replaced with \"" + self.txtReplaceWith.GetText() + "\""), "Replace") else: self.stc.Finder.DoREFind(self.txtSearchFor.GetText(), isMatchCase) else: #Set Flags if (self.chkWholeWord.GetValue()): findflags = findflags | wx.stc.STC_FIND_WHOLEWORD if (isMatchCase): findflags = findflags | wx.stc.STC_FIND_MATCHCASE if (self.IsReplace): x = self.stc.Finder.ReplaceAll(self.txtSearchFor.GetText(), self.txtReplaceWith.GetText(), findflags, self.chkPromptOnReplace.GetValue()) if x == 0: drScrolledMessageDialog.ShowMessage(self, 'Search string: "' + self.txtSearchFor.GetText() + '" not found.', 'DrPython Replace') elif self.parent.prefs.enablefeedback: drScrolledMessageDialog.ShowMessage(self, (str(x) + " occurances of \"" + self.txtSearchFor.GetText() + "\" replaced with \"" + self.txtReplaceWith.GetText() + "\""), "Replace") else: self.stc.Finder.DoFind(self.txtSearchFor.GetText(), findflags, findbackwards) self.Close(1) if (self.IsReplace): self.parent.ReplaceOptions = self.GetOptions() else: self.parent.FindOptions = self.GetOptions() def OnbtnPopUp(self, event): eid = event.GetId() if eid == self.ID_BTNSF: s = self.txtSearchFor.GetPosition()[0] x = self.btnPopUpSearchFor.GetPosition()[0] self.txtSearchFor.PopUp((x-s, 0)) elif eid == self.ID_BTNRW: s = self.txtReplaceWith.GetPosition()[0] x = self.btnPopUpReplaceWith.GetPosition()[0] self.txtReplaceWith.PopUp((x-s, 0)) def OnCheckRegularExpression(self, event): usingRegularExpressions = self.chkRegularExpression.GetValue() self.btnCreateRE.Enable(usingRegularExpressions) self.chkWholeWord.Enable(not usingRegularExpressions) if not self.IsReplace: self.chkFindBackwards.Enable(not usingRegularExpressions) def OnTextChanged(self, event): self.btnFind.Enable(len(self.txtSearchFor.GetText()) > 0) def SetFindString(self, findstring): self.txtSearchFor.SetValue(findstring) self.txtSearchFor.SetMark(0, len(findstring)) self.OnTextChanged(None) def SetOptions(self, OptionsArray): if len(OptionsArray) > 0: self.chkRegularExpression.SetValue(OptionsArray[0]) self.btnCreateRE.Enable(OptionsArray[0]) self.chkMatchCase.SetValue(OptionsArray[1]) self.chkFindBackwards.SetValue(OptionsArray[2]) self.chkWholeWord.SetValue(OptionsArray[3]) self.chkInSelection.SetValue(OptionsArray[4]) self.chkFromCursor.SetValue(OptionsArray[5]) if (self.IsReplace): self.chkPromptOnReplace.SetValue(OptionsArray[6])