Robot Framework Integrated Development Environment (RIDE)
review.py
Go to the documentation of this file.
1 # Copyright 2008-2015 Nokia Networks
2 # Copyright 2016- Robot Framework Foundation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 import os
17 import re
18 import time
19 from threading import Thread
20 
21 import wx
22 import wx.lib.mixins.listctrl as listmix
23 from wx import Colour
24 
25 from ..context import IS_MAC
26 from ..spec.iteminfo import LibraryKeywordInfo
27 from ..ui.searchdots import DottedSearch
28 from ..usages.commands import FindUsages
29 from ..widgets import ButtonWithHandler, Label, RIDEDialog
30 
31 
32 class ReviewDialog(RIDEDialog):
33 
34  def __init__(self, controller, frame):
35  RIDEDialog.__init__(self, parent=frame, title="Search unused keywords",
36  style=wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN |
37  wx.FRAME_FLOAT_ON_PARENT)
38  # set Left to Right direction (while we don't have localization)
39  self.SetLayoutDirection(wx.Layout_LeftToRight)
40  self.indexindex = 0
41  self.frameframe = frame
42  self._search_model_search_model = ResultModel()
43  self._runner_runner = ReviewRunner(controller, self._search_model_search_model)
44  self._build_ui_build_ui()
45  self._make_bindings_make_bindings()
46  self._set_default_values_set_default_values()
47  self.CenterOnParent()
48 
49  def _build_ui(self):
50  self.SetSize((800,600))
51  self.SetBackgroundColour(Colour(self.color_background))
52  self.SetForegroundColour(Colour(self.color_foreground))
53  self.SetSizer(wx.BoxSizer(wx.VERTICAL))
54  self._build_header_build_header()
55  self._build_filter_build_filter()
56  self._build_notebook_build_notebook()
57  self._build_unused_keywords_build_unused_keywords()
58  self._build_controls_build_controls()
59 
60  def _build_header(self):
61  label_introduction = wx.StaticText(self, label="This dialog helps you finding unused "
62  "keywords within your opened project.\nIf "
63  "you want, you can restrict the search to "
64  "a set of files with the filter.")
65  label_filter_is = wx.StaticText(self, label='Filter is')
66  self.label_filter_statuslabel_filter_status = wx.StaticText(self, label='inactive')
67  header_sizer = wx.BoxSizer(wx.HORIZONTAL)
68  header_sizer.Add(label_introduction, 0, wx.ALL | wx.EXPAND, 3)
69  header_sizer.AddStretchSpacer(1)
70  header_sizer.Add(label_filter_is, 0,
71  wx.LEFT | wx.TOP | wx.BOTTOM | wx.ALIGN_BOTTOM, 3)
72  if wx.VERSION < (4, 1, 0):
73  header_sizer.Add(self.label_filter_statuslabel_filter_status, 0, wx.ALL | wx.ALIGN_BOTTOM | wx.ALIGN_RIGHT, 3)
74  else:
75  header_sizer.Add(self.label_filter_statuslabel_filter_status, 0, wx.ALL | wx.ALIGN_BOTTOM, 3)
76  self.Sizer.Add(header_sizer, 0, wx.ALL | wx.EXPAND, 3)
77 
78  def _build_filter(self):
79  self._filter_pane_filter_pane = MyCollapsiblePane(self, label="Filter",
80  style=wx.CP_DEFAULT_STYLE | wx.CP_NO_TLW_RESIZE)
81  self._filter_pane_filter_pane.SetBackgroundColour(Colour(self.color_background))
82  self._filter_pane_filter_pane.SetForegroundColour(Colour(self.color_foreground))
83  self._filter_input_filter_input = wx.TextCtrl(self._filter_pane_filter_pane.GetPane(),
84  size=(-1, 20))
85  self._filter_regex_switch_filter_regex_switch = wx.CheckBox(self._filter_pane_filter_pane.GetPane(),
86  wx.ID_ANY, label="Use RegEx")
87  self._filter_info_filter_info = wx.StaticText(self._filter_pane_filter_pane.GetPane(),
88  label="Here you can define one or more strings separated"
89  " by comma (e.g. common,abc,123).\nThe filter "
90  "matches if at least one string is part of "
91  "the filename.\nIf you don\'t enter any strings, "
92  "all opened files are included")
93  filter_source_box = wx.StaticBox(self._filter_pane_filter_pane.GetPane(), label="Search")
94  self._filter_source_testcases_filter_source_testcases = wx.CheckBox(self._filter_pane_filter_pane.GetPane(),
95  wx.ID_ANY,
96  label="Test case files")
97  self._filter_source_resources_filter_source_resources = wx.CheckBox(self._filter_pane_filter_pane.GetPane(),
98  wx.ID_ANY,
99  label="Resource files")
100  self._filter_mode_filter_mode = wx.RadioBox(self._filter_pane_filter_pane.GetPane(),
101  label="Mode",
102  choices=["exclude", "include"])
103  self._filter_test_button_filter_test_button = wx.Button(self._filter_pane_filter_pane.GetPane(),
104  wx.ID_INFO, label="Test the filter")
105  self._filter_test_button_filter_test_button.SetBackgroundColour(Colour(self.color_secondary_background))
106  self._filter_test_button_filter_test_button.SetForegroundColour(Colour(self.color_secondary_foreground))
107  filter_box_sizer = wx.BoxSizer(wx.HORIZONTAL)
108  filter_box_sizer.SetSizeHints(self._filter_pane_filter_pane.GetPane())
109  filter_source_sizer = wx.StaticBoxSizer(filter_source_box, wx.VERTICAL)
110  checkbox_border = 0 if IS_MAC else 3
111  filter_source_sizer.Add(self._filter_source_testcases_filter_source_testcases, 0, wx.ALL, checkbox_border)
112  filter_source_sizer.Add(self._filter_source_resources_filter_source_resources, 0, wx.ALL, checkbox_border)
113  filter_options = wx.BoxSizer(wx.VERTICAL)
114  filter_options.Add(filter_source_sizer, 0,
115  wx.BOTTOM | wx.RIGHT | wx.LEFT | wx.EXPAND, 3)
116  filter_options.Add(self._filter_mode_filter_mode, 0, wx.ALL | wx.EXPAND, 3)
117  filter_input_sizer = wx.BoxSizer(wx.VERTICAL)
118  filter_input_sizer.SetMinSize((600, -1))
119  filter_input_sizer.Add(self._filter_info_filter_info, 0, wx.ALL | wx.ALIGN_LEFT, 3)
120  filter_input_sizer.Add(self._filter_input_filter_input, 0, wx.ALL | wx.EXPAND, 3)
121  filter_input_sizer.Add(self._filter_regex_switch_filter_regex_switch, 0, wx.ALL | wx.ALIGN_RIGHT, 3)
122  filter_input_sizer.Add(self._filter_test_button_filter_test_button, 0, wx.ALL | wx.ALIGN_CENTER, 3)
123  filter_box_sizer.Add(filter_options, 0, wx.ALL | wx.EXPAND, 3)
124  filter_box_sizer.Add(filter_input_sizer, 0, wx.ALL | wx.EXPAND, 3)
125  self._filter_pane_filter_pane.GetPane().SetSizer(filter_box_sizer)
126  self.Sizer.Add(self._filter_pane_filter_pane, 0, wx.ALL | wx.EXPAND, 3)
127 
129  panel_unused_kw = wx.Panel(self._notebook_notebook)
130  sizer_unused_kw = wx.BoxSizer(wx.VERTICAL)
131  panel_unused_kw.SetSizer(sizer_unused_kw)
132  self._unused_kw_list_unused_kw_list = ResultListCtrl(panel_unused_kw,
133  style=wx.LC_REPORT)
134  self._unused_kw_list_unused_kw_list.InsertColumn(0, "Keyword", width=400)
135  self._unused_kw_list_unused_kw_list.InsertColumn(1, "File", width=250)
136  self._unused_kw_list_unused_kw_list.SetMinSize((650, 250))
137  self._unused_kw_list_unused_kw_list.set_dialog(self)
138  self._unused_kw_list_unused_kw_list.SetBackgroundColour(Colour(self.color_background))
139  self._unused_kw_list_unused_kw_list.SetForegroundColour(Colour(self.color_foreground))
140  self._delete_button_delete_button = wx.Button(panel_unused_kw, wx.ID_ANY,
141  'Delete marked keywords')
142  self._delete_button_delete_button.SetBackgroundColour(Colour(self.color_secondary_background))
143  self._delete_button_delete_button.SetForegroundColour(Colour(self.color_secondary_foreground))
144  sizer_unused_kw.Add(self._unused_kw_list_unused_kw_list, 1, wx.ALL | wx.EXPAND, 3)
145  unused_kw_controls = wx.BoxSizer(wx.HORIZONTAL)
146  unused_kw_controls.AddStretchSpacer(1)
147  if wx.VERSION < (4, 1, 0):
148  unused_kw_controls.Add(self._delete_button_delete_button, 0, wx.ALL | wx.ALIGN_RIGHT, 3)
149  else:
150  unused_kw_controls.Add(self._delete_button_delete_button, 0, wx.ALL, 3)
151  sizer_unused_kw.Add(unused_kw_controls, 0, wx.ALL | wx.EXPAND, 3)
152  self._notebook_notebook.AddPage(panel_unused_kw, "Unused Keywords")
153 
154  def _build_controls(self):
155  self._search_button_search_button = ButtonWithHandler(self, 'Search')
156  self._search_button_search_button.SetBackgroundColour(Colour(self.color_secondary_background))
157  self._search_button_search_button.SetForegroundColour(Colour(self.color_secondary_foreground))
158  self._abort_button_abort_button = ButtonWithHandler(self, 'Abort')
159  self._abort_button_abort_button.SetBackgroundColour(Colour(self.color_secondary_background))
160  self._abort_button_abort_button.SetForegroundColour(Colour(self.color_secondary_foreground))
161  self._status_label_status_label = Label(self, label='')
162  controls = wx.BoxSizer(wx.HORIZONTAL)
163  controls.Add(self._search_button_search_button, 0, wx.ALL, 3)
164  controls.Add(self._abort_button_abort_button, 0, wx.ALL, 3)
165  controls.Add(self._status_label_status_label, 1, wx.ALL | wx.EXPAND, 3)
166  self.Sizer.Add(controls, 0, wx.ALL | wx.EXPAND, 3)
167 
168  def _build_notebook(self):
169  self._notebook_notebook = wx.Notebook(self, wx.ID_ANY, style=wx.NB_TOP)
170  self._notebook_notebook.SetBackgroundColour(Colour(self.color_background))
171  self._notebook_notebook.SetForegroundColour(Colour(self.color_foreground))
172  self.Sizer.Add(self._notebook_notebook, 1, wx.ALL | wx.EXPAND, 3)
173 
174  def _make_bindings(self):
175  self.Bind(wx.EVT_CLOSE, self._close_dialog_close_dialog)
176  self.Bind(wx.EVT_TEXT, self._update_filter_update_filter, self._filter_input_filter_input)
177  self.Bind(wx.EVT_RADIOBOX, self._update_filter_mode_update_filter_mode, self._filter_mode_filter_mode)
178  self.Bind(wx.EVT_CHECKBOX, self._update_filter_source_testcases_update_filter_source_testcases,
179  self._filter_source_testcases_filter_source_testcases)
180  self.Bind(wx.EVT_CHECKBOX, self._update_filter_source_resources_update_filter_source_resources,
181  self._filter_source_resources_filter_source_resources)
182  self.Bind(wx.EVT_BUTTON, self.OnDeletemarkedkeywordsOnDeletemarkedkeywords, self._delete_button_delete_button)
183  self.Bind(wx.EVT_BUTTON, self.OnShowfilestobesearchedOnShowfilestobesearched, self._filter_test_button_filter_test_button)
184  self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnResultSelectedOnResultSelected, self._unused_kw_list_unused_kw_list)
185  self.Bind(wx.EVT_CHECKBOX, self._update_filter_regex_update_filter_regex, self._filter_regex_switch_filter_regex_switch)
186  self.Bind(wx.EVT_COLLAPSIBLEPANE_CHANGED, self._toggle_filter_active_toggle_filter_active, self._filter_pane_filter_pane)
187  self.Bind(wx.EVT_LIST_ITEM_CHECKED, self._unused_kw_list_unused_kw_list.OnCheckItem, self._unused_kw_list_unused_kw_list)
188  self.Bind(wx.EVT_LIST_ITEM_UNCHECKED, self._unused_kw_list_unused_kw_list.OnCheckItem, self._unused_kw_list_unused_kw_list)
189 
191  check_testcases = True
192  self._filter_source_testcases_filter_source_testcases.SetValue(check_testcases)
193  self._runner_runner.set_filter_source_testcases(check_testcases)
194  check_resources = True
195  self._filter_source_resources_filter_source_resources.SetValue(check_resources)
196  self._runner_runner.set_filter_source_resources(check_resources)
197  filter_mode = 0
198  self._filter_mode_filter_mode.SetSelection(filter_mode)
199  self._runner_runner.set_filter_mode(filter_mode == 0)
200  use_regex = False
201  self._filter_regex_switch_filter_regex_switch.SetValue(use_regex)
202  self._runner_runner.set_filter_use_regex(use_regex)
203  filter_string = ''
204  self._filter_input_filter_input.ChangeValue(filter_string)
205  self._runner_runner.parse_filter_string(filter_string)
206  self._disable_filter_disable_filter()
207  self._abort_button_abort_button.Disable()
208  self._delete_button_delete_button.Disable()
209 
210  def _update_filter(self, event):
211  self._runner_runner.parse_filter_string(event.GetString())
212 
213  def _update_filter_mode(self, event):
214  self._runner_runner.set_filter_mode(event.GetInt() == 0)
215 
217  self._runner_runner.set_filter_source_testcases(self._filter_source_testcases_filter_source_testcases.IsChecked())
218 
220  self._runner_runner.set_filter_source_resources(self._filter_source_resources_filter_source_resources.IsChecked())
221 
222  def _update_filter_regex(self, event):
223  self._runner_runner.set_filter_use_regex(self._filter_regex_switch_filter_regex_switch.IsChecked())
224 
225  def _toggle_filter_active(self, event):
226  if event.GetCollapsed():
227  self._disable_filter_disable_filter()
228  else:
229  self._enable_filter_enable_filter()
230  self._filter_pane_filter_pane.on_change(event)
231 
232  def _disable_filter(self):
233  self._runner_runner.set_filter_active(False)
234  self.label_filter_statuslabel_filter_status.SetLabel('inactive')
235  self.label_filter_statuslabel_filter_status.SetForegroundColour(wx.RED)
236 
237  def _enable_filter(self):
238  self._runner_runner.set_filter_active(True)
239  self.label_filter_statuslabel_filter_status.SetLabel('active')
240  self.label_filter_statuslabel_filter_status.SetForegroundColour((0,200,0))
241 
242  def OnSearch(self, event):
243  self.begin_searchingbegin_searching()
244  self._runner_runner._run_review()
245 
246  def OnAbort(self, event):
247  self.end_searchingend_searching()
248 
249  def OnDeletemarkedkeywords(self, event):
250  item = self._unused_kw_list_unused_kw_list.get_next_checked_item()
251  while item:
252  index = item[0]
253  kw = item[1]
254  listitem = item[2]
255  item_id = listitem.GetData()
256  self._unused_kw_list_unused_kw_list.DeleteItem(index)
257  self._unused_kw_list_unused_kw_list.RemoveClientData(item_id)
258  kw.delete()
259  self._update_notebook_text_update_notebook_text("Unused Keywords (%d)" % self._unused_kw_list_unused_kw_list.GetItemCount())
260  self.update_statusupdate_status("")
261  item = self._unused_kw_list_unused_kw_list.get_next_checked_item()
262  self.item_in_kw_list_checkeditem_in_kw_list_checked()
263 
264  def OnShowfilestobesearched(self, event):
265  df_list = self._runner_runner._get_datafile_list()
266  if not df_list:
267  string_list = "(None)"
268  else:
269  string_list = "\n".join(df.name for df in df_list)
270  message = "Keywords of the following files will be included in the search:\n\n"+string_list
271  dlg = RIDEDialog(parent=self, title="Included files", message=message, style=wx.OK | wx.ICON_INFORMATION)
272  dlg.ShowModal()
273 
274  def OnResultSelected(self, event):
275  self.frameframe.tree.select_node_by_data(self._unused_kw_list_unused_kw_list.GetClientData(event.GetData()))
276 
278  if self._unused_kw_list_unused_kw_list.get_number_of_checked_items() > 0:
279  self._delete_button_delete_button.Enable(True)
280  else:
281  self._delete_button_delete_button.Disable()
282 
283  def show_dialog(self):
284  if not self.IsShown():
285  self._clear_search_results_clear_search_results()
286  self.Show()
287  self.Raise()
288 
289  def _close_dialog(self, event):
290  if self._search_model_search_model.searching:
291  self.end_searchingend_searching()
292  if event.CanVeto():
293  self.Hide()
294  else:
295  self.Destroy()
296 
297  def begin_searching(self):
298  self._abort_button_abort_button.Enable()
299  self._search_button_search_button.Disable()
300  self._filter_pane_filter_pane.Disable()
301  self._unused_kw_list_unused_kw_list.Disable()
302  self._clear_search_results_clear_search_results()
303  self._dots_dots = DottedSearch(self, self._update_unused_keywords_update_unused_keywords)
304  self._dots_dots.start()
305 
307  self._unused_kw_list_unused_kw_list.ClearAll()
308  self._update_notebook_text_update_notebook_text('Unused Keywords')
309  self._delete_button_delete_button.Disable()
310  self._status_label_status_label.SetLabel('')
311  self._search_model_search_model.clear_search()
312 
313  def add_result_unused_keyword(self, index, keyword):
314  keyword_info = keyword.info
315  self._unused_kw_list_unused_kw_list.InsertItem(index, keyword_info.name)
316  filename = os.path.basename(keyword_info.item.source)
317  self._unused_kw_list_unused_kw_list.SetItem(index, 1, filename)
318  self._unused_kw_list_unused_kw_list.SetItemData(index, index)
319  self._unused_kw_list_unused_kw_list.SetClientData(index, keyword)
320  self._unused_kw_list_unused_kw_list.SetItemBackgroundColour(index, Colour(self.color_secondary_background))
321  self._unused_kw_list_unused_kw_list.SetItemTextColour(index, Colour(self.color_secondary_foreground))
322 
323  def _update_unused_keywords(self, dots):
324  count_before = self._unused_kw_list_unused_kw_list.GetItemCount()
325  for index, kw in list(enumerate(self._search_model_search_model.keywords))[count_before:]:
326  self.add_result_unused_keywordadd_result_unused_keyword(index, kw)
327  self.update_statusupdate_status("Searching.%s \t- %s" % (dots, self._search_model_search_model.status))
328  if not self._search_model_search_model.searching:
329  self.end_searchingend_searching()
330 
331  def _update_notebook_text(self, new_text):
332  self._notebook_notebook.SetPageText(0, new_text)
333 
334  def update_status(self, message, increase=1):
335  self._status_label_status_label.SetLabel(message)
336 
337  def end_searching(self):
338  self._dots_dots.stop()
339  self._search_model_search_model.end_search()
340  self._update_notebook_text_update_notebook_text('Unused Keywords (%d)' % (self._unused_kw_list_unused_kw_list.GetItemCount()))
341  self.update_statusupdate_status("Search finished - Found %d Unused Keywords" %
342  (self._unused_kw_list_unused_kw_list.GetItemCount()))
343  self._unused_kw_list_unused_kw_list.Enable()
344  self._abort_button_abort_button.Disable()
345  self._filter_pane_filter_pane.Enable()
346  self._search_button_search_button.Enable()
347 
348  def send_radiobox_event(self, mycontrol):
349  cmd = wx.CommandEvent(wx.EVT_RADIOBOX.evtType[0])
350  cmd.SetEventObject(mycontrol)
351  cmd.SetId(mycontrol.GetId())
352  mycontrol.GetEventHandler().ProcessEvent(cmd)
353 
354 
355 class ReviewRunner():
356 
357  def __init__(self, controller, model):
358  self._controller_controller = controller
359  self._model_model = model
360  self._filter_filter = ResultFilter()
361 
362  def set_filter_active(self, value):
363  self._filter_filter.active = value
364 
365  def set_filter_mode(self, exclude):
366  self._filter_filter.excludes = exclude
367 
368  def set_filter_source_testcases(self, value):
369  self._filter_filter.check_testcases = value
370 
371  def set_filter_source_resources(self, value):
372  self._filter_filter.check_resources = value
373 
374  def set_filter_use_regex(self, value):
375  self._filter_filter.use_regex = value
376 
377  def parse_filter_string(self, filter_string):
378  self._filter_filter.set_strings(filter_string.split(','))
379 
381  return [df for df in self._controller_controller.datafiles if self._filter_filter.include_file(df)]
382 
383  def _run_review(self):
384  self._model_model.begin_search()
385  Thread(target=self._run_run).start()
386 
387  def _run(self):
388  self._stop_requested_stop_requested = False
389  self._model_model.status = 'listing datafiles'
390  for df in self._get_datafile_list_get_datafile_list():
391  libname = os.path.basename(df.source).rsplit('.', 1)[0]
392  self._model_model.status = 'searching from ' + str(libname)
393  for keyword in df.keywords:
394  time.sleep(0) # GIVE SPACE TO OTHER THREADS -- Thread.yield in Java
395  self._model_model.status = "%s.%s" % (libname, keyword.name)
396  if not self._model_model.searching:
397  break
398  # Check if it is unused
399  if not isinstance(keyword, LibraryKeywordInfo) and keyword.name:
400  if self._is_unused_is_unused(keyword):
401  self._model_model.add_unused_keyword(keyword)
402  if not self._model_model.searching:
403  break
404  self._model_model.end_search()
405 
406  def _is_unused(self, keyword):
407  try:
408  next(self._controller_controller.execute(FindUsages(keyword.name, keyword_info=keyword.info)))
409  return False
410  except StopIteration:
411  return True
412 
413 
414 class ResultFilter():
415 
416  def __init__(self):
417  self._strings_strings = []
418  self.excludesexcludes = True
419  self.check_testcasescheck_testcases = True
420  self.check_resourcescheck_resources = True
421  self.use_regexuse_regex = False
422  self.activeactive = False
423 
424  def set_strings(self, strings):
425  self._strings_strings = [s.strip() for s in strings if s.strip()]
426 
427  def include_file(self, datafile):
428  from ..controller.filecontrollers import (TestCaseFileController, ResourceFileController,
429  TestDataDirectoryController)
430  if isinstance(datafile, TestDataDirectoryController):
431  return False
432  if not self.activeactive:
433  return True
434  if not self.check_testcasescheck_testcases and isinstance(datafile, TestCaseFileController):
435  return False
436  if not self.check_resourcescheck_resources and isinstance(datafile, ResourceFileController):
437  return False
438  if not self._strings_strings:
439  return True
440  return self.excludesexcludes ^ any(self._results_results(datafile.name))
441 
442  def _results(self, name):
443  for string in self._strings_strings:
444  if self.use_regexuse_regex:
445  yield bool(re.match(string, name))
446  else:
447  yield string in name
448 
449 
450 class ResultModel():
451 
452  def __init__(self):
453  self.clear_searchclear_search()
454 
455  def clear_search(self):
456  self.statusstatus = ''
457  self.keywordskeywords = []
458  self.searchingsearching = False
459 
460  def add_unused_keyword(self, keyword):
461  self.keywordskeywords += [keyword]
462 
463  def begin_search(self):
464  self.searchingsearching = True
465 
466  def end_search(self):
467  self.searchingsearching = False
468 
469 
470 class ResultListCtrl(wx.ListCtrl, listmix.CheckListCtrlMixin, listmix.ListCtrlAutoWidthMixin):
471  def __init__(self, parent, style):
472  self.parentparent = parent
473  wx.ListCtrl.__init__(self, parent=parent, style=style)
474  if wx.VERSION < (4, 1, 0):
475  listmix.CheckListCtrlMixin.__init__(self)
476  else:
477  self.EnableCheckBoxes(True)
478  listmix.ListCtrlAutoWidthMixin.__init__(self)
479  self.SetBackgroundColour(Colour(self.GetTopLevelParent().color_background))
480  self.SetForegroundColour(Colour(self.GetTopLevelParent().color_foreground))
481  self.setResizeColumn(2)
482  self._clientData_clientData = {}
483 
484  def set_dialog(self, dialog):
485  self._dlg_dlg = dialog
486 
487  def OnCheckItem(self, event):
488  if self._dlg_dlg:
489  self._dlg_dlg.item_in_kw_list_checked()
490  else:
491  print("No dialog set")
492 
494  for i in range(self.GetItemCount()):
495  if wx.VERSION >= (4, 1, 0):
496  checked = self.IsItemChecked(i)
497  else:
498  checked = self.IsChecked(i)
499  if checked:
500  item = self.GetItem(i)
501  return ([i, self.GetClientDataGetClientData(item.GetData()), item])
502  return None
503 
505  sum = 0
506  for i in range(self.GetItemCount()):
507  if wx.VERSION >= (4, 1, 0):
508  checked = self.IsItemChecked(i)
509  else:
510  checked = self.IsChecked(i)
511  if checked:
512  sum += 1
513  return sum
514 
515  def SetClientData(self, index, data):
516  self._clientData_clientData[index] = data
517 
518  def GetClientData(self, index):
519  return self._clientData_clientData.get(index, None)
520 
521  def RemoveClientData(self, index):
522  del self._clientData_clientData[index]
523 
524  def ClearAll(self):
525  self.DeleteAllItems()
526  self._clientData_clientData.clear()
527 
528  def print_data(self):
529  print(self._clientData_clientData)
530 
531 
532 class MyCollapsiblePane(wx.CollapsiblePane):
533 
534  def __init__(self, parent, *args, **kwargs):
535  wx.CollapsiblePane.__init__(self, parent, *args, **kwargs)
536  """
537  self.SetBackgroundColour(Colour(200, 222, 40))
538  self.SetOwnBackgroundColour(Colour(200, 222, 40))
539  self.SetForegroundColour(Colour(7, 0, 70))
540  self.SetOwnForegroundColour(Colour(7, 0, 70))
541  """
542  self.Bind(wx.EVT_SIZE, self._recalc_size_recalc_size)
543  self.Bind(wx.EVT_COLLAPSIBLEPANE_CHANGED, self.on_changeon_change)
544 
545  def _recalc_size(self, event=None):
546  if self.IsExpanded():
547  expand_button_height = 32 # good guess...
548  height = 150 if IS_MAC else 135
549  self.SetSizeHints(650, height + expand_button_height)
550  if self.IsCollapsed():
551  self.SetSizeHints(650, 40)
552  if event:
553  event.Skip()
554 
555  def on_change(self, event):
556  self.Fit()
557  self.GetParent().Layout()
558  if event:
559  event.Skip()
def __init__(self, parent, *args, **kwargs)
Definition: review.py:534
def _recalc_size(self, event=None)
Definition: review.py:545
def _results(self, name)
Definition: review.py:442
def include_file(self, datafile)
Definition: review.py:427
def set_strings(self, strings)
Definition: review.py:424
def OnCheckItem(self, event)
Definition: review.py:487
def __init__(self, parent, style)
Definition: review.py:471
def GetClientData(self, index)
Definition: review.py:518
def set_dialog(self, dialog)
Definition: review.py:484
def SetClientData(self, index, data)
Definition: review.py:515
def RemoveClientData(self, index)
Definition: review.py:521
def add_unused_keyword(self, keyword)
Definition: review.py:460
def __init__(self, controller, frame)
Definition: review.py:34
def OnShowfilestobesearched(self, event)
Definition: review.py:264
def _update_filter_source_testcases(self, event)
Definition: review.py:216
def _toggle_filter_active(self, event)
Definition: review.py:225
def _update_filter_source_resources(self, event)
Definition: review.py:219
def _close_dialog(self, event)
Definition: review.py:289
def OnSearch(self, event)
Definition: review.py:242
def OnDeletemarkedkeywords(self, event)
Definition: review.py:249
def OnResultSelected(self, event)
Definition: review.py:274
def _update_unused_keywords(self, dots)
Definition: review.py:323
def send_radiobox_event(self, mycontrol)
Definition: review.py:348
def _update_filter_regex(self, event)
Definition: review.py:222
def _update_filter(self, event)
Definition: review.py:210
def _update_filter_mode(self, event)
Definition: review.py:213
def add_result_unused_keyword(self, index, keyword)
Definition: review.py:313
def _update_notebook_text(self, new_text)
Definition: review.py:331
def update_status(self, message, increase=1)
Definition: review.py:334
def OnAbort(self, event)
Definition: review.py:246
def __init__(self, controller, model)
Definition: review.py:357
def parse_filter_string(self, filter_string)
Definition: review.py:377
def set_filter_mode(self, exclude)
Definition: review.py:365
def set_filter_active(self, value)
Definition: review.py:362
def set_filter_use_regex(self, value)
Definition: review.py:374
def set_filter_source_testcases(self, value)
Definition: review.py:368
def _is_unused(self, keyword)
Definition: review.py:406
def set_filter_source_resources(self, value)
Definition: review.py:371
Class that can be used to make Search dots...
Definition: searchdots.py:27