controls/SearchResultPanel.py
changeset 1784 64beb9e9c749
parent 1782 5b6ad7a7fd9d
child 1836 d42b6cf00fa6
equal deleted inserted replaced
1729:31e63e25b4cc 1784:64beb9e9c749
    28 import wx.lib.buttons
    28 import wx.lib.buttons
    29 import wx.lib.agw.customtreectrl as CT
    29 import wx.lib.agw.customtreectrl as CT
    30 
    30 
    31 from PLCControler import *
    31 from PLCControler import *
    32 from util.BitmapLibrary import GetBitmap
    32 from util.BitmapLibrary import GetBitmap
       
    33 
    33 
    34 
    34 def GenerateName(infos):
    35 def GenerateName(infos):
    35     if infos[0] in ["input", "output", "value"]:
    36     if infos[0] in ["input", "output", "value"]:
    36         return "%s %d:" % (infos[0], infos[1])
    37         return "%s %d:" % (infos[0], infos[1])
    37     elif infos[0] == "range":
    38     elif infos[0] == "range":
    38         return "%s %d %s" % (infos[0], infos[1], infos[2])
    39         return "%s %d %s" % (infos[0], infos[1], infos[2])
    39     elif infos[0] == "struct":
    40     elif infos[0] == "struct":
    40         return "element %d %s" % (infos[1], infos[2])
    41         return "element %d %s" % (infos[1], infos[2])
    41     return "%s:" % infos[0]
    42     return "%s:" % infos[0]
    42 
    43 
    43 #-------------------------------------------------------------------------------
    44 
       
    45 # -------------------------------------------------------------------------------
    44 #                            Search Result Panel
    46 #                            Search Result Panel
    45 #-------------------------------------------------------------------------------
    47 # -------------------------------------------------------------------------------
    46 
    48 
    47 [ID_SEARCHRESULTPANEL, ID_SEARCHRESULTPANELHEADERLABEL,
    49 
    48  ID_SEARCHRESULTPANELSEARCHRESULTSTREE, ID_SEARCHRESULTPANELRESETBUTTON, 
    50 [
       
    51     ID_SEARCHRESULTPANEL, ID_SEARCHRESULTPANELHEADERLABEL,
       
    52     ID_SEARCHRESULTPANELSEARCHRESULTSTREE, ID_SEARCHRESULTPANELRESETBUTTON,
    49 ] = [wx.NewId() for _init_ctrls in range(4)]
    53 ] = [wx.NewId() for _init_ctrls in range(4)]
    50 
    54 
       
    55 
    51 class SearchResultPanel(wx.Panel):
    56 class SearchResultPanel(wx.Panel):
    52 
    57 
    53     if wx.VERSION < (2, 6, 0):
    58     if wx.VERSION < (2, 6, 0):
    54         def Bind(self, event, function, id = None):
    59         def Bind(self, event, function, id=None):
    55             if id is not None:
    60             if id is not None:
    56                 event(self, id, function)
    61                 event(self, id, function)
    57             else:
    62             else:
    58                 event(self, function)
    63                 event(self, function)
    59 
    64 
    60     def _init_coll_MainSizer_Items(self, parent):
    65     def _init_coll_MainSizer_Items(self, parent):
    61         parent.AddSizer(self.HeaderSizer, 0, border=0, flag=wx.GROW)
    66         parent.AddSizer(self.HeaderSizer, 0, border=0, flag=wx.GROW)
    62         parent.AddWindow(self.SearchResultsTree, 1, border=0, flag=wx.GROW)
    67         parent.AddWindow(self.SearchResultsTree, 1, border=0, flag=wx.GROW)
    63     
    68 
    64     def _init_coll_MainSizer_Growables(self, parent):
    69     def _init_coll_MainSizer_Growables(self, parent):
    65         parent.AddGrowableCol(0)
    70         parent.AddGrowableCol(0)
    66         parent.AddGrowableRow(1)
    71         parent.AddGrowableRow(1)
    67 
    72 
    68     def _init_coll_HeaderSizer_Items(self, parent):
    73     def _init_coll_HeaderSizer_Items(self, parent):
    69         parent.AddWindow(self.HeaderLabel, 1, border=5, flag=wx.LEFT|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
    74         parent.AddWindow(self.HeaderLabel, 1, border=5, flag=wx.LEFT | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL)
    70         parent.AddWindow(self.ResetButton, 0, border=0, flag=0)
    75         parent.AddWindow(self.ResetButton, 0, border=0, flag=0)
    71     
    76 
    72     def _init_coll_HeaderSizer_Growables(self, parent):
    77     def _init_coll_HeaderSizer_Growables(self, parent):
    73         parent.AddGrowableCol(0)
    78         parent.AddGrowableCol(0)
    74     
    79 
    75     def _init_sizers(self):
    80     def _init_sizers(self):
    76         self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
    81         self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
    77         self.HeaderSizer = wx.BoxSizer(wx.HORIZONTAL)
    82         self.HeaderSizer = wx.BoxSizer(wx.HORIZONTAL)
    78         
    83 
    79         self._init_coll_MainSizer_Items(self.MainSizer)
    84         self._init_coll_MainSizer_Items(self.MainSizer)
    80         self._init_coll_MainSizer_Growables(self.MainSizer)
    85         self._init_coll_MainSizer_Growables(self.MainSizer)
    81         self._init_coll_HeaderSizer_Items(self.HeaderSizer)
    86         self._init_coll_HeaderSizer_Items(self.HeaderSizer)
    82         
    87 
    83         self.SetSizer(self.MainSizer)
    88         self.SetSizer(self.MainSizer)
    84 
    89 
    85     def _init_ctrls(self, prnt):
    90     def _init_ctrls(self, prnt):
    86         wx.Panel.__init__(self, id=ID_SEARCHRESULTPANEL,
    91         wx.Panel.__init__(self, id=ID_SEARCHRESULTPANEL,
    87               name='SearchResultPanel', parent=prnt, pos=wx.Point(0, 0),
    92                           name='SearchResultPanel', parent=prnt, pos=wx.Point(0, 0),
    88               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
    93                           size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
    89 
    94 
    90         self.HeaderLabel = wx.StaticText(id=ID_SEARCHRESULTPANELHEADERLABEL,
    95         self.HeaderLabel = wx.StaticText(id=ID_SEARCHRESULTPANELHEADERLABEL,
    91               name='HeaderLabel', parent=self,
    96                                          name='HeaderLabel', parent=self,
    92               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
    97                                          pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
    93         
    98 
    94         search_results_tree_style = CT.TR_HAS_BUTTONS|CT.TR_NO_LINES|CT.TR_HAS_VARIABLE_ROW_HEIGHT
    99         search_results_tree_style = CT.TR_HAS_BUTTONS | CT.TR_NO_LINES | CT.TR_HAS_VARIABLE_ROW_HEIGHT
    95         self.SearchResultsTree = CT.CustomTreeCtrl(id=ID_SEARCHRESULTPANELSEARCHRESULTSTREE,
   100         self.SearchResultsTree = CT.CustomTreeCtrl(id=ID_SEARCHRESULTPANELSEARCHRESULTSTREE,
    96               name="SearchResultsTree", parent=self,
   101                                                    name="SearchResultsTree", parent=self,
    97               pos=wx.Point(0, 0), style=search_results_tree_style)
   102                                                    pos=wx.Point(0, 0), style=search_results_tree_style)
    98         if wx.VERSION >= (2, 8, 11):
   103         if wx.VERSION >= (2, 8, 11):
    99             self.SearchResultsTree.SetAGWWindowStyleFlag(search_results_tree_style)
   104             self.SearchResultsTree.SetAGWWindowStyleFlag(search_results_tree_style)
   100         self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnSearchResultsTreeItemActivated,
   105         self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnSearchResultsTreeItemActivated,
   101               id=ID_SEARCHRESULTPANELSEARCHRESULTSTREE)
   106                   id=ID_SEARCHRESULTPANELSEARCHRESULTSTREE)
   102         
   107 
   103         self.ResetButton = wx.lib.buttons.GenBitmapButton(self,
   108         self.ResetButton = wx.lib.buttons.GenBitmapButton(
   104               bitmap=GetBitmap("reset"), size=wx.Size(28, 28), style=wx.NO_BORDER)
   109             self, bitmap=GetBitmap("reset"),
       
   110             size=wx.Size(28, 28), style=wx.NO_BORDER)
   105         self.ResetButton.SetToolTipString(_("Reset search result"))
   111         self.ResetButton.SetToolTipString(_("Reset search result"))
   106         self.Bind(wx.EVT_BUTTON, self.OnResetButton, self.ResetButton)
   112         self.Bind(wx.EVT_BUTTON, self.OnResetButton, self.ResetButton)
   107         
   113 
   108         self._init_sizers()
   114         self._init_sizers()
   109 
   115 
   110     def __init__(self, parent, window):
   116     def __init__(self, parent, window):
   111         self.ParentWindow = window
   117         self.ParentWindow = window
   112         
   118 
   113         self._init_ctrls(parent)
   119         self._init_ctrls(parent)
   114         
   120 
   115         # Define Tree item icon list
   121         # Define Tree item icon list
   116         self.TreeImageList = wx.ImageList(16, 16)
   122         self.TreeImageList = wx.ImageList(16, 16)
   117         self.TreeImageDict = {}
   123         self.TreeImageDict = {}
   118         
   124 
   119         # Icons for other items
   125         # Icons for other items
   120         for imgname, itemtype in [
   126         for imgname, itemtype in [
   121             #editables
   127                 # editables
   122             ("PROJECT",        ITEM_PROJECT),
   128                 ("PROJECT",        ITEM_PROJECT),
   123             ("TRANSITION",     ITEM_TRANSITION),
   129                 ("TRANSITION",     ITEM_TRANSITION),
   124             ("ACTION",         ITEM_ACTION),
   130                 ("ACTION",         ITEM_ACTION),
   125             ("CONFIGURATION",  ITEM_CONFIGURATION),
   131                 ("CONFIGURATION",  ITEM_CONFIGURATION),
   126             ("RESOURCE",       ITEM_RESOURCE),
   132                 ("RESOURCE",       ITEM_RESOURCE),
   127             ("DATATYPE",       ITEM_DATATYPE),
   133                 ("DATATYPE",       ITEM_DATATYPE),
   128             ("ACTION",         "action_block"),
   134                 ("ACTION",         "action_block"),
   129             ("IL",             "IL"),
   135                 ("IL",             "IL"),
   130             ("ST",             "ST")]:
   136                 ("ST",             "ST")]:
   131             self.TreeImageDict[itemtype] = self.TreeImageList.Add(GetBitmap(imgname))
   137             self.TreeImageDict[itemtype] = self.TreeImageList.Add(GetBitmap(imgname))
   132         
   138 
   133         for itemtype in ["function", "functionBlock", "program",
   139         for itemtype in ["function", "functionBlock", "program",
   134                          "comment", "block", "io_variable",
   140                          "comment", "block", "io_variable",
   135                          "connector", "contact", "coil",
   141                          "connector", "contact", "coil",
   136                          "step", "transition", "jump", 
   142                          "step", "transition", "jump",
   137                          "var_local", "var_input", 
   143                          "var_local", "var_input",
   138                          "var_inout", "var_output"]:
   144                          "var_inout", "var_output"]:
   139             self.TreeImageDict[itemtype] = self.TreeImageList.Add(GetBitmap(itemtype.upper()))
   145             self.TreeImageDict[itemtype] = self.TreeImageList.Add(GetBitmap(itemtype.upper()))
   140         
   146 
   141         # Assign icon list to TreeCtrl
   147         # Assign icon list to TreeCtrl
   142         self.SearchResultsTree.SetImageList(self.TreeImageList)
   148         self.SearchResultsTree.SetImageList(self.TreeImageList)
   143         
   149 
   144         self.ResetSearchResults()
   150         self.ResetSearchResults()
   145 
   151 
   146     def SetSearchResults(self, criteria, search_results):
   152     def SetSearchResults(self, criteria, search_results):
   147         self.Criteria = criteria
   153         self.Criteria = criteria
   148         self.SearchResults = {}
   154         self.SearchResults = {}
   149         self.ElementsOrder = []
   155         self.ElementsOrder = []
   150         
   156 
   151         for infos, start, end, text in search_results:
   157         for infos, start, end, text in search_results:
   152             if infos[0] not in self.ElementsOrder:
   158             if infos[0] not in self.ElementsOrder:
   153                 self.ElementsOrder.append(infos[0])
   159                 self.ElementsOrder.append(infos[0])
   154             
   160 
   155             results = self.SearchResults.setdefault(infos[0], [])
   161             results = self.SearchResults.setdefault(infos[0], [])
   156             results.append((infos, start, end, text))
   162             results.append((infos, start, end, text))
   157         
   163 
   158         self.RefreshView()
   164         self.RefreshView()
   159     
   165 
   160     def ResetSearchResults(self):
   166     def ResetSearchResults(self):
   161         self.Criteria = None
   167         self.Criteria = None
   162         self.ElementsOrder = []
   168         self.ElementsOrder = []
   163         self.SearchResults = {}
   169         self.SearchResults = {}
   164         self.RefreshView()
   170         self.RefreshView()
   165     
   171 
   166     def RefreshView(self):
   172     def RefreshView(self):
   167         self.SearchResultsTree.DeleteAllItems()
   173         self.SearchResultsTree.DeleteAllItems()
   168         if self.Criteria is None:
   174         if self.Criteria is None:
   169             self.HeaderLabel.SetLabel(_("No search results available."))
   175             self.HeaderLabel.SetLabel(_("No search results available."))
   170             self.ResetButton.Enable(False)
   176             self.ResetButton.Enable(False)
   171         else:
   177         else:
   172             matches_number = 0
   178             matches_number = 0
   173             search_results_tree_infos = {"name": _("Project '%s':") % self.ParentWindow.Controler.GetProjectName(),
   179             search_results_tree_infos = {
   174                                          "type": ITEM_PROJECT,
   180                 "name": _("Project '%s':") % self.ParentWindow.Controler.GetProjectName(),
   175                                          "data": None,
   181                 "type": ITEM_PROJECT,
   176                                          "text": None,
   182                 "data": None,
   177                                          "matches": None,
   183                 "text": None,
   178                                         }
   184                 "matches": None,
       
   185             }
   179             search_results_tree_children = search_results_tree_infos.setdefault("children", [])
   186             search_results_tree_children = search_results_tree_infos.setdefault("children", [])
   180             for tagname in self.ElementsOrder:
   187             for tagname in self.ElementsOrder:
   181                 results = self.SearchResults.get(tagname, [])
   188                 results = self.SearchResults.get(tagname, [])
   182                 matches_number += len(results)
   189                 matches_number += len(results)
   183                 
   190 
   184                 words = tagname.split("::")
   191                 words = tagname.split("::")
   185                 
   192 
   186                 element_type = self.ParentWindow.Controler.GetElementType(tagname)
   193                 element_type = self.ParentWindow.Controler.GetElementType(tagname)
   187                 if element_type == ITEM_POU:
   194                 if element_type == ITEM_POU:
   188                     element_type = self.ParentWindow.Controler.GetPouType(words[1])
   195                     element_type = self.ParentWindow.Controler.GetPouType(words[1])
   189                 
   196 
   190                 element_infos = {"name": words[-1],
   197                 element_infos = {"name": words[-1],
   191                                  "type": element_type,
   198                                  "type": element_type,
   192                                  "data": tagname,
   199                                  "data": tagname,
   193                                  "text": None,
   200                                  "text": None,
   194                                  "matches": len(results)}
   201                                  "matches": len(results)}
   195                 
   202 
   196                 children = element_infos.setdefault("children", [])
   203                 children = element_infos.setdefault("children", [])
   197                 for infos, start, end, text in results:
   204                 for infos, start, end, text in results:
   198                     if infos[1] == "name" or element_type == ITEM_DATATYPE:
   205                     if infos[1] == "name" or element_type == ITEM_DATATYPE:
   199                         child_name = GenerateName(infos[1:])
   206                         child_name = GenerateName(infos[1:])
   200                         child_type = element_type
   207                         child_type = element_type
   213                                 child_type = self.ParentWindow.Controler.GetActionBodyType(words[1], words[2])
   220                                 child_type = self.ParentWindow.Controler.GetActionBodyType(words[1], words[2])
   214                             else:
   221                             else:
   215                                 child_type = self.ParentWindow.Controler.GetPouBodyType(words[1])
   222                                 child_type = self.ParentWindow.Controler.GetPouBodyType(words[1])
   216                         else:
   223                         else:
   217                             child_name = GenerateName(infos[3:])
   224                             child_name = GenerateName(infos[3:])
   218                     child_infos = {"name": child_name,
   225                     child_infos = {
   219                                    "type": child_type,
   226                         "name": child_name,
   220                                    "data": (infos, start, end ,None),
   227                         "type": child_type,
   221                                    "text": text,
   228                         "data": (infos, start, end, None),
   222                                    "matches": 1,
   229                         "text": text,
   223                                    "children": [],
   230                         "matches": 1,
   224                                   }
   231                         "children": [],
       
   232                     }
   225                     children.append(child_infos)
   233                     children.append(child_infos)
   226                 
   234 
   227                 if len(words) > 2:
   235                 if len(words) > 2:
   228                     for _element_infos in search_results_tree_children:
   236                     for _element_infos in search_results_tree_children:
   229                         if _element_infos["name"] == words[1]:
   237                         if _element_infos["name"] == words[1]:
   230                             _element_infos["matches"] += len(children)
   238                             _element_infos["matches"] += len(children)
   231                             _element_infos["children"].append(element_infos)
   239                             _element_infos["children"].append(element_infos)
   232                             break
   240                             break
   233                     if element_type == ITEM_RESOURCE:
   241                     if element_type == ITEM_RESOURCE:
   234                         search_results_tree_children.append(element_infos)
   242                         search_results_tree_children.append(element_infos)
   235                 else:
   243                 else:
   236                     search_results_tree_children.append(element_infos)
   244                     search_results_tree_children.append(element_infos)
   237             
   245 
   238             if matches_number < 2:
   246             if matches_number < 2:
   239                 header_format = _("'{a1}' - {a2} match in project")
   247                 header_format = _("'{a1}' - {a2} match in project")
   240             else:
   248             else:
   241                 header_format = _("'{a1}' - {a2} matches in project")
   249                 header_format = _("'{a1}' - {a2} matches in project")
   242             
   250 
   243             self.HeaderLabel.SetLabel(header_format.format(a1 = self.Criteria["find_pattern"], a2 = matches_number))
   251             self.HeaderLabel.SetLabel(header_format.format(a1=self.Criteria["find_pattern"], a2=matches_number))
   244             self.ResetButton.Enable(True)
   252             self.ResetButton.Enable(True)
   245             
   253 
   246             if matches_number > 0:
   254             if matches_number > 0:
   247                 root = self.SearchResultsTree.GetRootItem()
   255                 root = self.SearchResultsTree.GetRootItem()
   248                 if root is None:
   256                 if root is None:
   249                     root = self.SearchResultsTree.AddRoot(search_results_tree_infos["name"])
   257                     root = self.SearchResultsTree.AddRoot(search_results_tree_infos["name"])
   250                 self.GenerateSearchResultsTreeBranch(root, search_results_tree_infos)
   258                 self.GenerateSearchResultsTreeBranch(root, search_results_tree_infos)
   251                 self.SearchResultsTree.Expand(root)
   259                 self.SearchResultsTree.Expand(root)
   252     
   260 
   253     def GetTextCtrlClickFunction(self, item):
   261     def GetTextCtrlClickFunction(self, item):
   254         def OnTextCtrlClick(event):
   262         def OnTextCtrlClick(event):
   255             self.SearchResultsTree.SelectItem(item)
   263             self.SearchResultsTree.SelectItem(item)
   256             event.Skip()
   264             event.Skip()
   257         return OnTextCtrlClick
   265         return OnTextCtrlClick
   258     
   266 
   259     def GetTextCtrlDClickFunction(self, item):
   267     def GetTextCtrlDClickFunction(self, item):
   260         def OnTextCtrlDClick(event):
   268         def OnTextCtrlDClick(event):
   261             self.ShowSearchResults(item)
   269             self.ShowSearchResults(item)
   262             event.Skip()
   270             event.Skip()
   263         return OnTextCtrlDClick
   271         return OnTextCtrlDClick
   264     
   272 
   265     def GenerateSearchResultsTreeBranch(self, root, infos):
   273     def GenerateSearchResultsTreeBranch(self, root, infos):
   266         to_delete = []
   274         to_delete = []
   267         if infos["name"] == "body":
   275         if infos["name"] == "body":
   268             item_name = "%d:" % infos["data"][1][0]
   276             item_name = "%d:" % infos["data"][1][0]
   269         else:
   277         else:
   270             item_name = infos["name"]
   278             item_name = infos["name"]
   271         
   279 
   272         self.SearchResultsTree.SetItemText(root, item_name)
   280         self.SearchResultsTree.SetItemText(root, item_name)
   273         self.SearchResultsTree.SetPyData(root, infos["data"])
   281         self.SearchResultsTree.SetPyData(root, infos["data"])
   274         self.SearchResultsTree.SetItemBackgroundColour(root, wx.WHITE)
   282         self.SearchResultsTree.SetItemBackgroundColour(root, wx.WHITE)
   275         self.SearchResultsTree.SetItemTextColour(root, wx.BLACK)
   283         self.SearchResultsTree.SetItemTextColour(root, wx.BLACK)
   276         if infos["type"] is not None:
   284         if infos["type"] is not None:
   277             if infos["type"] == ITEM_POU:
   285             if infos["type"] == ITEM_POU:
   278                 self.SearchResultsTree.SetItemImage(root, self.TreeImageDict[self.ParentWindow.Controler.GetPouType(infos["name"])])
   286                 self.SearchResultsTree.SetItemImage(root, self.TreeImageDict[self.ParentWindow.Controler.GetPouType(infos["name"])])
   279             else:
   287             else:
   280                 self.SearchResultsTree.SetItemImage(root, self.TreeImageDict[infos["type"]])
   288                 self.SearchResultsTree.SetItemImage(root, self.TreeImageDict[infos["type"]])
   281         
   289 
   282         text = None
   290         text = None
   283         if infos["text"] is not None:
   291         if infos["text"] is not None:
   284             text = infos["text"]
   292             text = infos["text"]
   285             start, end = infos["data"][1:3]
   293             start, end = infos["data"][1:3]
   286             text_lines = infos["text"].splitlines()
   294             text_lines = infos["text"].splitlines()
   289             style = wx.TextAttr(wx.BLACK, wx.Colour(206, 204, 247))
   297             style = wx.TextAttr(wx.BLACK, wx.Colour(206, 204, 247))
   290         elif infos["type"] is not None and infos["matches"] > 1:
   298         elif infos["type"] is not None and infos["matches"] > 1:
   291             text = _("(%d matches)") % infos["matches"]
   299             text = _("(%d matches)") % infos["matches"]
   292             start_idx, end_idx = 0, len(text)
   300             start_idx, end_idx = 0, len(text)
   293             style = wx.TextAttr(wx.Colour(0, 127, 174))
   301             style = wx.TextAttr(wx.Colour(0, 127, 174))
   294         
   302 
   295         if text is not None:
   303         if text is not None:
   296             text_ctrl_style = wx.BORDER_NONE|wx.TE_READONLY|wx.TE_RICH2
   304             text_ctrl_style = wx.BORDER_NONE | wx.TE_READONLY | wx.TE_RICH2
   297             if wx.Platform != '__WXMSW__' or len(text.splitlines()) > 1:
   305             if wx.Platform != '__WXMSW__' or len(text.splitlines()) > 1:
   298                 text_ctrl_style |= wx.TE_MULTILINE
   306                 text_ctrl_style |= wx.TE_MULTILINE
   299             text_ctrl = wx.TextCtrl(id=-1, parent=self.SearchResultsTree, pos=wx.Point(0, 0), 
   307             text_ctrl = wx.TextCtrl(id=-1, parent=self.SearchResultsTree, pos=wx.Point(0, 0),
   300                     value=text, style=text_ctrl_style)
   308                                     value=text, style=text_ctrl_style)
   301             width, height = text_ctrl.GetTextExtent(text)
   309             width, height = text_ctrl.GetTextExtent(text)
   302             text_ctrl.SetClientSize(wx.Size(width + 1, height))
   310             text_ctrl.SetClientSize(wx.Size(width + 1, height))
   303             text_ctrl.SetBackgroundColour(self.SearchResultsTree.GetBackgroundColour())
   311             text_ctrl.SetBackgroundColour(self.SearchResultsTree.GetBackgroundColour())
   304             text_ctrl.Bind(wx.EVT_LEFT_DOWN, self.GetTextCtrlClickFunction(root))
   312             text_ctrl.Bind(wx.EVT_LEFT_DOWN, self.GetTextCtrlClickFunction(root))
   305             text_ctrl.Bind(wx.EVT_LEFT_DCLICK, self.GetTextCtrlDClickFunction(root))
   313             text_ctrl.Bind(wx.EVT_LEFT_DCLICK, self.GetTextCtrlDClickFunction(root))
   306             text_ctrl.SetInsertionPoint(0)
   314             text_ctrl.SetInsertionPoint(0)
   307             text_ctrl.SetStyle(start_idx, end_idx, style)
   315             text_ctrl.SetStyle(start_idx, end_idx, style)
   308             self.SearchResultsTree.SetItemWindow(root, text_ctrl)
   316             self.SearchResultsTree.SetItemWindow(root, text_ctrl)
   309             
   317 
   310         if wx.VERSION >= (2, 6, 0):
   318         if wx.VERSION >= (2, 6, 0):
   311             item, root_cookie = self.SearchResultsTree.GetFirstChild(root)
   319             item, root_cookie = self.SearchResultsTree.GetFirstChild(root)
   312         else:
   320         else:
   313             item, root_cookie = self.SearchResultsTree.GetFirstChild(root, 0)
   321             item, root_cookie = self.SearchResultsTree.GetFirstChild(root, 0)
   314         for child in infos["children"]:
   322         for child in infos["children"]:
   315             if item is None:
   323             if item is None:
   316                 item = self.SearchResultsTree.AppendItem(root, "")
   324                 item = self.SearchResultsTree.AppendItem(root, "")
   317                 item, root_cookie = self.SearchResultsTree.GetNextChild(root, root_cookie)
   325                 item, root_cookie = self.SearchResultsTree.GetNextChild(root, root_cookie)
   318             self.GenerateSearchResultsTreeBranch(item, child)
   326             self.GenerateSearchResultsTreeBranch(item, child)
   319             item, root_cookie = self.SearchResultsTree.GetNextChild(root, root_cookie)
   327             item, root_cookie = self.SearchResultsTree.GetNextChild(root, root_cookie)
   320     
   328 
   321     def ShowSearchResults(self, item):
   329     def ShowSearchResults(self, item):
   322         data = self.SearchResultsTree.GetPyData(item)
   330         data = self.SearchResultsTree.GetPyData(item)
   323         if isinstance(data, TupleType):
   331         if isinstance(data, TupleType):
   324             search_results = [data]
   332             search_results = [data]
   325         else:
   333         else:
   326             search_results = self.SearchResults.get(data, [])
   334             search_results = self.SearchResults.get(data, [])
   327         self.ParentWindow.ClearHighlights(SEARCH_RESULT_HIGHLIGHT)
   335         self.ParentWindow.ClearHighlights(SEARCH_RESULT_HIGHLIGHT)
   328         for infos, start, end, text in search_results:
   336         for infos, start, end, text in search_results:
   329             self.ParentWindow.ShowSearchResult(infos, start, end)
   337             self.ParentWindow.ShowSearchResult(infos, start, end)
   330     
   338 
   331     def OnSearchResultsTreeItemActivated(self, event):
   339     def OnSearchResultsTreeItemActivated(self, event):
   332         self.ShowSearchResults(event.GetItem())
   340         self.ShowSearchResults(event.GetItem())
   333         event.Skip()
   341         event.Skip()
   334     
   342 
   335     def OnResetButton(self, event):
   343     def OnResetButton(self, event):
   336         self.ResetSearchResults()
   344         self.ResetSearchResults()
   337         self.ParentWindow.ClearSearchResults()
   345         self.ParentWindow.ClearSearchResults()
   338         event.Skip()
   346         event.Skip()