# HG changeset patch # User Sergey Surkov # Date 1477667503 -10800 # Node ID 32e9d0ef30dc50c598a109ce6ab40b173b302d14 # Parent dac6002ff58e4e1f05cc045005a1d24c2280d750 fix major bugs in Find and Search in Project functionality. fix case sensitive and regexp search, remove duplicating code Signed-off-by: Andrey Skvortsov diff -r dac6002ff58e -r 32e9d0ef30dc IDEFrame.py --- a/IDEFrame.py Fri Oct 28 17:21:42 2016 +0300 +++ b/IDEFrame.py Fri Oct 28 18:11:43 2016 +0300 @@ -1260,6 +1260,7 @@ def OnFindMenu(self, event): if not self.FindDialog.IsShown(): self.FindDialog.Show() + self.FindDialog.FindPattern.SetFocus() def CloseFindInPouDialog(self): selected = self.TabsOpened.GetSelection() @@ -1284,10 +1285,11 @@ dialog = SearchInProjectDialog(self) if dialog.ShowModal() == wx.ID_OK: criteria = dialog.GetCriteria() - result = self.Controler.SearchInProject(criteria) - self.ClearSearchResults() - self.SearchResultPanel.SetSearchResults(criteria, result) - self.SelectTab(self.SearchResultPanel) + if len(criteria) > 0: + result = self.Controler.SearchInProject(criteria) + self.ClearSearchResults() + self.SearchResultPanel.SetSearchResults(criteria, result) + self.SelectTab(self.SearchResultPanel) #------------------------------------------------------------------------------- # Display Menu Functions diff -r dac6002ff58e -r 32e9d0ef30dc controls/SearchResultPanel.py --- a/controls/SearchResultPanel.py Fri Oct 28 17:21:42 2016 +0300 +++ b/controls/SearchResultPanel.py Fri Oct 28 18:11:43 2016 +0300 @@ -253,7 +253,7 @@ else: header_format = _("'%s' - %d matches in project") - self.HeaderLabel.SetLabel(header_format % (self.Criteria["raw_pattern"], matches_number)) + self.HeaderLabel.SetLabel(header_format % (self.Criteria["find_pattern"], matches_number)) self.ResetButton.Enable(True) if matches_number > 0: diff -r dac6002ff58e -r 32e9d0ef30dc dialogs/FindInPouDialog.py --- a/dialogs/FindInPouDialog.py Fri Oct 28 17:21:42 2016 +0300 +++ b/dialogs/FindInPouDialog.py Fri Oct 28 18:11:43 2016 +0300 @@ -23,6 +23,7 @@ #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import wx +from plcopen.plcopen import * class FindInPouDialog(wx.Frame): @@ -33,13 +34,14 @@ def __init__(self, parent): wx.Frame.__init__(self, parent, title=_("Find"), - size=wx.Size(400, 250), style=wx.CAPTION| + size=wx.Size(410, 250), style=wx.CAPTION| wx.CLOSE_BOX| wx.CLIP_CHILDREN| wx.RESIZE_BORDER| wx.STAY_ON_TOP) self._init_icon(parent) + self.CreateStatusBar(style=wx.SB_FLAT) panel = wx.Panel(self, style=wx.TAB_TRAVERSAL) main_sizer = wx.FlexGridSizer(cols=1, hgap=5, rows=2, vgap=5) @@ -116,7 +118,8 @@ self.ParentWindow = parent self.Bind(wx.EVT_CLOSE, self.OnCloseFrame) - + self.infosPrev = {} + self.criteria = {} self.FindPattern.SetFocus() self.RefreshButtonsState() @@ -141,8 +144,21 @@ "find_pattern": self.FindPattern.GetValue(), "wrap": self.WrapSearch.GetValue(), "case_sensitive": self.CaseSensitive.GetValue(), - "regular_expression": self.RegularExpressions.GetValue()} - wx.CallAfter(self.ParentWindow.FindInPou, - {True: 1, False:-1}[self.Forward.GetValue()], - infos) + "regular_expression": self.RegularExpressions.GetValue(), + "filter": "all"} + + if self.infosPrev != infos: + self.infosPrev = infos + message = "" + try: + self.criteria = infos + CompilePattern(self.criteria) + except: + self.criteria.clear() + message = _("Syntax error in regular expression of pattern to search!") + self.SetStatusText(message) + if len(self.criteria) > 0: + wx.CallAfter(self.ParentWindow.FindInPou, + {True: 1, False:-1}[self.Forward.GetValue()], + self.criteria) event.Skip() diff -r dac6002ff58e -r 32e9d0ef30dc dialogs/SearchInProjectDialog.py --- a/dialogs/SearchInProjectDialog.py Fri Oct 28 17:21:42 2016 +0300 +++ b/dialogs/SearchInProjectDialog.py Fri Oct 28 18:11:43 2016 +0300 @@ -23,17 +23,9 @@ #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import re - +from plcopen.plcopen import * import wx -RE_ESCAPED_CHARACTERS = ".*+()[]?:|{}^$<>=-," - -def EscapeText(text): - text = text.replace('\\', '\\\\') - for c in RE_ESCAPED_CHARACTERS: - text = text.replace(c, '\\' + c) - return text - #------------------------------------------------------------------------------- # Search In Project Dialog #------------------------------------------------------------------------------- @@ -68,6 +60,7 @@ pattern_sizer.AddWindow(self.CaseSensitive, flag=wx.GROW) self.Pattern = wx.TextCtrl(self) + self.Bind(wx.EVT_TEXT, self.FindPatternChanged, self.Pattern) pattern_sizer.AddWindow(self.Pattern, flag=wx.GROW) self.RegularExpression = wx.CheckBox(self, label=_('Regular expression')) @@ -99,58 +92,68 @@ self.ElementsList.Enable(False) scope_sizer.AddWindow(self.ElementsList, 1, border=5, flag=wx.GROW|wx.TOP|wx.RIGHT|wx.BOTTOM) - - self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) - ok_button = self.ButtonSizer.GetAffirmativeButton() - ok_button.SetLabel(_('Search')) - self.Bind(wx.EVT_BUTTON, self.OnOK, ok_button) - main_sizer.AddSizer(self.ButtonSizer, border=20, - flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) + + buttons_sizer = wx.BoxSizer(wx.HORIZONTAL) + main_sizer.AddSizer(buttons_sizer, border=20, + flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.ALIGN_RIGHT) + + self.FindButton = wx.Button(self, label=_("Find")) + self.FindButton.SetDefault() + self.Bind(wx.EVT_BUTTON, self.OnFindButton, self.FindButton) + buttons_sizer.AddWindow(self.FindButton, border=5, flag=wx.RIGHT) + + self.CloseButton = wx.Button(self, label=_("Close")) + self.Bind(wx.EVT_BUTTON, self.OnCloseButton, self.CloseButton) + buttons_sizer.AddWindow(self.CloseButton) self.SetSizer(main_sizer) for name, label in GetElementsChoices(): self.ElementsList.Append(_(label)) - + self.infosPrev = {} + self.criteria = {} self.Pattern.SetFocus() + self.RefreshButtonsState() + + def RefreshButtonsState(self): + find_pattern = self.Pattern.GetValue() + self.FindButton.Enable(find_pattern != "") def GetCriteria(self): - raw_pattern = pattern = self.Pattern.GetValue() - if not self.CaseSensitive.GetValue(): - pattern = pattern.upper() - if not self.RegularExpression.GetValue(): - pattern = EscapeText(pattern) - criteria = { - "raw_pattern": raw_pattern, - "pattern": re.compile(pattern), + return self.criteria + + def FindPatternChanged(self, event): + self.RefreshButtonsState() + event.Skip() + def OnScopeChanged(self, event): + self.ElementsList.Enable(self.OnlyElements.GetValue()) + event.Skip() + + def OnCloseButton(self, event): + self.EndModal(wx.ID_CANCEL) + + def OnFindButton(self, event): + message = None + infos = { + "find_pattern": self.Pattern.GetValue(), "case_sensitive": self.CaseSensitive.GetValue(), "regular_expression": self.RegularExpression.GetValue(), } if self.WholeProject.GetValue(): - criteria["filter"] = "all" + infos["filter"] = "all" elif self.OnlyElements.GetValue(): - criteria["filter"] = [] + infos["filter"] = [] for index, (name, label) in enumerate(GetElementsChoices()): if self.ElementsList.IsChecked(index): - criteria["filter"].append(name) - return criteria - - def OnScopeChanged(self, event): - self.ElementsList.Enable(self.OnlyElements.GetValue()) - event.Skip() - - def OnOK(self, event): - message = None - if self.Pattern.GetValue() == "": - message = _("Form isn't complete. Pattern to search must be filled!") - else: - wrong_pattern = False - if self.RegularExpression.GetValue(): - try: - re.compile(self.Pattern.GetValue()) - except: - wrong_pattern = True - if wrong_pattern: + infos["filter"].append(name) + + if self.infosPrev != infos: + try: + self.criteria = infos + CompilePattern(self.criteria) + self.infosPrev = infos + except: + self.criteria.clear() message = _("Syntax error in regular expression of pattern to search!") if message is not None: diff -r dac6002ff58e -r 32e9d0ef30dc editors/CodeFileEditor.py --- a/editors/CodeFileEditor.py Fri Oct 28 17:21:42 2016 +0300 +++ b/editors/CodeFileEditor.py Fri Oct 28 18:11:43 2016 +0300 @@ -506,17 +506,11 @@ self.ClearHighlights(SEARCH_RESULT_HIGHLIGHT) self.SearchParams = search_params - criteria = { - "raw_pattern": search_params["find_pattern"], - "pattern": re.compile(search_params["find_pattern"]), - "case_sensitive": search_params["case_sensitive"], - "regular_expression": search_params["regular_expression"], - "filter": "all"} self.SearchResults = [ (start, end, SEARCH_RESULT_HIGHLIGHT) for start, end, text in - TestTextElement(self.GetText(), criteria)] + TestTextElement(self.GetText(), search_params)] self.CurrentFindHighlight = None if len(self.SearchResults) > 0: diff -r dac6002ff58e -r 32e9d0ef30dc editors/TextViewer.py --- a/editors/TextViewer.py Fri Oct 28 17:21:42 2016 +0300 +++ b/editors/TextViewer.py Fri Oct 28 18:11:43 2016 +0300 @@ -810,17 +810,10 @@ self.ClearHighlights(SEARCH_RESULT_HIGHLIGHT) self.SearchParams = search_params - criteria = { - "raw_pattern": search_params["find_pattern"], - "pattern": re.compile(search_params["find_pattern"]), - "case_sensitive": search_params["case_sensitive"], - "regular_expression": search_params["regular_expression"], - "filter": "all"} - self.SearchResults = [ (infos[1:], start, end, SEARCH_RESULT_HIGHLIGHT) for infos, start, end, text in - self.Search(criteria)] + self.Search(search_params)] self.CurrentFindHighlight = None if len(self.SearchResults) > 0: diff -r dac6002ff58e -r 32e9d0ef30dc editors/Viewer.py --- a/editors/Viewer.py Fri Oct 28 17:21:42 2016 +0300 +++ b/editors/Viewer.py Fri Oct 28 18:11:43 2016 +0300 @@ -3408,16 +3408,9 @@ self.ClearHighlights(SEARCH_RESULT_HIGHLIGHT) self.SearchParams = search_params - criteria = { - "raw_pattern": search_params["find_pattern"], - "pattern": re.compile(search_params["find_pattern"]), - "case_sensitive": search_params["case_sensitive"], - "regular_expression": search_params["regular_expression"], - "filter": "all"} - self.SearchResults = [] blocks = [] - for infos, start, end, text in self.Controler.SearchInPou(self.TagName, criteria, self.Debug): + for infos, start, end, text in self.Controler.SearchInPou(self.TagName, search_params, self.Debug): if infos[1] in ["var_local", "var_input", "var_output", "var_inout"]: self.SearchResults.append((infos[1:], start, end, SEARCH_RESULT_HIGHLIGHT)) else: diff -r dac6002ff58e -r 32e9d0ef30dc plcopen/plcopen.py --- a/plcopen/plcopen.py Fri Oct 28 17:21:42 2016 +0300 +++ b/plcopen/plcopen.py Fri Oct 28 18:11:43 2016 +0300 @@ -111,10 +111,15 @@ lines = text.split("\n") return len(lines) - 1, len(lines[-1]) +def CompilePattern(criteria): + flag = 0 if criteria["case_sensitive"] else re.IGNORECASE + find_pattern = criteria["find_pattern"] + if not criteria["regular_expression"]: + find_pattern = re.escape(find_pattern) + criteria["pattern"] = re.compile(find_pattern, flag) + def TestTextElement(text, criteria): lines = text.splitlines() - if not criteria["case_sensitive"]: - text = text.upper() test_result = [] result = criteria["pattern"].search(text) while result is not None: