Robot Framework Integrated Development Environment (RIDE)
fieldeditors.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 wx
17 import wx.grid
18 from wx import Colour
19 
20 from .contentassist import ContentAssistTextCtrl
21 from .gridbase import GridEditor
22 from ..context import ctrl_or_cmd, bind_keys_to_evt_menu
23 from ..editor.contentassist import ContentAssistFileButton
24 from ..namespace.suggesters import SuggestionSource
25 from ..widgets import Label
26 
27 
28 class ValueEditor(wx.Panel):
29  expand_factor = 0
30 
33  _sizer_flags_for_editor = wx.ALL
34 
37  _sizer_flags_for_label = wx.ALL
38 
39  def __init__(self, parent, value, label=None, validator=None,
40  settings=None):
41  wx.Panel.__init__(self, parent)
42  self._label_label = label
43  self._sizer_sizer = wx.BoxSizer(wx.VERTICAL)
44  from ..preferences import RideSettings
45 
48  _settings = RideSettings()
49  self.general_settingsgeneral_settings = _settings['General']
50  self.color_backgroundcolor_background = self.general_settingsgeneral_settings['background']
51  self.color_foregroundcolor_foreground = self.general_settingsgeneral_settings['foreground']
52  self.color_secondary_backgroundcolor_secondary_background = self.general_settingsgeneral_settings['secondary background']
53  self.color_secondary_foregroundcolor_secondary_foreground = self.general_settingsgeneral_settings['secondary foreground']
54  self.color_background_helpcolor_background_help = self.general_settingsgeneral_settings['background help']
55  self.color_foreground_textcolor_foreground_text = self.general_settingsgeneral_settings['foreground text']
56  self._create_editor_create_editor(value, label, settings)
57  if validator:
58  self.set_validatorset_validator(validator)
59  self.SetSizer(self._sizer_sizer)
60 
61  def _create_editor(self, value, label, settings):
62  sizer = wx.BoxSizer(wx.HORIZONTAL)
63  if self._label_label:
64  sizer.Add(Label(self, label=self._label_label, size=(80, -1)), 0,
65  self._sizer_flags_for_label_sizer_flags_for_label, 5)
66  self._editor_editor = self._get_text_ctrl_get_text_ctrl()
67  # self._editor.SetDefaultStyle(wx.TextAttr(wx.TEXT_ATTR_CHARACTER))
68  # self._editor.SetBackgroundColour(Colour(self.color_secondary_background))
69  # self._editor.SetOwnBackgroundColour(Colour(self.color_secondary_background))
70  # self._editor.SetForegroundColour(Colour(self.color_secondary_foreground))
71  # self._editor.SetOwnForegroundColour(Colour(self.color_secondary_foreground))
72  self._editor_editor.AppendText(value)
73  sizer.Add(self._editor_editor, 1, self._sizer_flags_for_editor_sizer_flags_for_editor, 3)
74  self._sizer_sizer.Add(sizer, 1, wx.EXPAND)
75  self._editor_editor.Bind(wx.EVT_KEY_DOWN, self.on_key_downon_key_down)
76  # print("DEBUG: ValueEditor _create_editor: %s\n" % (self._editor.__repr__()))
77 
78  def _get_text_ctrl(self):
79  editor = wx.TextCtrl(self, size=(600, -1))
80  editor.SetBackgroundColour(Colour(self.color_secondary_backgroundcolor_secondary_background))
81  editor.SetOwnBackgroundColour(Colour(self.color_secondary_backgroundcolor_secondary_background))
82  editor.SetForegroundColour(Colour(self.color_secondary_foregroundcolor_secondary_foreground))
83  editor.SetOwnForegroundColour(Colour(self.color_secondary_foregroundcolor_secondary_foreground))
84  return editor
85 
86  def set_validator(self, validator):
87  self._editor_editor.SetValidator(validator)
88 
89  def get_value(self):
90  # print("DEBUG: ValueEditor get_value: %s" % self._editor.GetValue())
91  return self._editor_editor.GetValue()
92 
93  def set_focus(self):
94  self._editor_editor.SetFocus()
95  self._editor_editor.SelectAll()
96 
97  def on_key_down(self, event):
98  character = None
99  keycode, control_down = event.GetKeyCode(), event.CmdDown()
100  # print("DEBUG: ValueEditor on_key_down: k=%s Ctrl=%s\n" % (keycode, control_down))
101  if event.CmdDown() and event.GetKeyCode() == ord('1'):
102  character = '$'
103  elif event.CmdDown() and event.GetKeyCode() == ord('2'):
104  character = '@'
105  elif event.CmdDown() and event.GetKeyCode() == ord('5'): # DEBUG New
106  character = '&'
107  if character:
108  if len(self.get_valueget_value()) == 0:
109  self._editor_editor.WriteText(character + "{}")
110  else:
111  self._editor_editor.AppendText(" | " + character + "{}")
112  _from, _ = self._editor_editor.GetSelection()
113  self._editor_editor.SetInsertionPoint(_from-1)
114  else:
115  event.Skip()
116 
117 
119 
120  def _create_editor(self, value, label, settings):
121  sizer = wx.BoxSizer(wx.HORIZONTAL)
122  if self._label_label:
123  sizer.Add(Label(self, label=self._label_label, size=(80, -1)), 0,
124  self._sizer_flags_for_label_sizer_flags_for_label, 5)
125  self._editor_editor_editor = self._get_text_ctrl_get_text_ctrl()
126  self._editor_editor_editor.AppendText(value)
127  sizer.Add(self._editor_editor_editor, 1, self._sizer_flags_for_editor_sizer_flags_for_editor, 3)
128  self._sizer_sizer.Add(sizer, 1, wx.EXPAND)
129 
130 
132 
133 
136  _sizer_flags_for_editor = 0
137 
140  _sizer_flags_for_label = wx.TOP | wx.BOTTOM | wx.LEFT
141 
142  def __init__(self, parent, value, label, controller, validator=None,
143  settings=None, suggestion_source=None):
144  self._suggestion_source_suggestion_source = suggestion_source or SuggestionSource(
145  parent.plugin, None)
146  self._controller_controller = controller
147  self._label_label_label = label
148  self._parent_parent = parent
149  ValueEditor.__init__(self, parent, value, label, validator, settings)
150 
151  def setFocusToOK(self):
152  self._parent_parent.setFocusToOK()
153 
154  def _get_text_ctrl(self):
155  filename_ctrl = ContentAssistFileButton(self, self._suggestion_source_suggestion_source, '',
156  self._controller_controller, (500, -1))
157  filename_ctrl.SetBackgroundColour(Colour(self.color_secondary_backgroundcolor_secondary_background))
158  filename_ctrl.SetForegroundColour(Colour(self.color_secondary_foregroundcolor_secondary_foreground))
159  return filename_ctrl
160 
161 
163 
164  def _get_text_ctrl(self):
165  textctrl = ValueEditor._get_text_ctrl(self)
166  textctrl.Bind(wx.EVT_SET_FOCUS, self.OnFocusOnFocus)
167  return textctrl
168 
169  def OnFocus(self, event):
170  wx.CallAfter(self.SetSelectionSetSelection, event.GetEventObject())
171  event.Skip()
172 
173  def SetSelection(self, event):
174  self._editor_editor.SetSelection(2, len(self._editor_editor.Value) - 1)
175 
176 
178  expand_factor = 1
179 
182  _sizer_flags_for_editor = wx.ALL | wx.EXPAND
183 
184  def _create_editor(self, value, label, settings):
185  sizer = wx.BoxSizer(wx.HORIZONTAL)
186  self._settings_settings = settings
187  cols = self._settings_settings.get("list variable columns", 4)
188  # print(f"DEBUG: ListValueEditor before calling sizer.Add _create_components label={label} cols={cols}")
189  sizer.Add(self._create_components_create_components(label, cols))
190  self._editor_editor_editor = _EditorGrid(self, value, cols)
191  sizer.Add(self._editor_editor_editor, 1, self._sizer_flags_for_editor_sizer_flags_for_editor_sizer_flags_for_editor, 3)
192  self._sizer_sizer.Add(sizer, 1, wx.EXPAND)
193  self.Bind(wx.EVT_SIZE, self.OnSizeOnSize)
194 
195  def _create_components(self, label, cols):
196  sizer = wx.BoxSizer(wx.VERTICAL)
197  sizer.Add(self._create_label_create_label(label), 0, wx.ALL, 5)
198  sizer.Add((-1, 10))
199  sizer.Add(self._create_column_selector_create_column_selector(cols))
200  return sizer
201 
202  def _create_label(self, label_text):
203  return Label(self, label=label_text, size=(80, -1))
204 
205  def _create_column_selector(self, cols):
206  sizer = wx.BoxSizer(wx.VERTICAL)
207  col_label = Label(self, label="Columns", size=(80, -1))
208  sizer.Add(col_label, 0, wx.ALL, 5)
209  combo = wx.ComboBox(self, value=str(cols), size=(60, 25),
210  choices=[str(i) for i in range(1, 11)])
211  tool_tip = wx.ToolTip("Number of columns that are shown in this editor."
212  " Selected value is stored and used globally.")
213  combo.SetToolTip(tool_tip)
214  tool_tip.GetWindow().SetBackgroundColour(Colour(self.color_background_helpcolor_background_help))
215  tool_tip.GetWindow().SetForegroundColour(Colour(self.color_foreground_textcolor_foreground_text))
216  # DEBUG attributes = self.GetClassDefaultAttributes()
217  combo.SetBackgroundColour(Colour(self.color_secondary_backgroundcolor_secondary_background))
218  combo.SetOwnBackgroundColour(Colour(self.color_secondary_backgroundcolor_secondary_background))
219  combo.SetForegroundColour(Colour(self.color_secondary_foregroundcolor_secondary_foreground))
220  combo.SetOwnForegroundColour(Colour(self.color_secondary_foregroundcolor_secondary_foreground))
221  self.Bind(wx.EVT_COMBOBOX, self.OnColumnsOnColumns, source=combo)
222  sizer.Add(combo)
223  # DEBUG children = self.GetChildren()
224  # print(f"DEBUG: Creating columns size selector: attributes bg ={attributes.colBg}\n children={children}")
225  return sizer
226 
227  def OnColumns(self, event):
228  num_cols = int(event.String)
229  self._settings_settings["list variable columns"] = num_cols
230  self._editor_editor_editor.set_number_of_columns(num_cols)
231 
232  def OnAddRow(self, event):
233  self._editor_editor_editor.add_row()
234 
235  def OnSize(self, event):
236  self._editor_editor_editor.resize_columns(event.Size[0] - 110)
237  event.Skip()
238 
239  def get_value(self):
240  return self._editor_editor_editor.get_value()
241 
242 
244 
245  def __init__(self, parent, value, num_cols):
246  num_rows = round(len(value) / num_cols + 2)
247  # print(f"DEBUG: _EditorGrid __init__ calc num_rows={num_rows} num_cols={num_cols}")
248  GridEditor.__init__(self, parent, num_rows, num_cols)
249  """
250  self.SetBackgroundColour(Colour(200, 222, 40))
251  self.SetOwnBackgroundColour(Colour(200, 222, 40))
252  self.SetForegroundColour(Colour(7, 0, 70))
253  self.SetOwnForegroundColour(Colour(7, 0, 70))
254  """
255  self._set_default_sizes_set_default_sizes()
256  self._bind_actions_bind_actions()
257  self._write_content_write_content(value)
258  self.Refresh(True)
259  """
260  self._colorize()
261  """
262 
264  self.SetColLabelSize(wx.grid.GRID_AUTOSIZE)
265  self.SetRowLabelSize(wx.grid.GRID_AUTOSIZE)
266  self.SetDefaultColSize(20)
267  self.SetDefaultRenderer(wx.grid.GridCellAutoWrapStringRenderer())
268 
269  def _bind_actions(self):
270  bind_keys_to_evt_menu(self, self._get_bind_keys_get_bind_keys())
271  self.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN, self.OnEditorShownOnEditorShown)
272 
273  def _get_bind_keys(self):
274  return [(ctrl_or_cmd(), ord('c'), self.OnCopyOnCopy),
275  (ctrl_or_cmd(), ord('x'), self.OnCutOnCut),
276  (ctrl_or_cmd(), ord('v'), self.OnPasteOnPaste),
277  (ctrl_or_cmd(), ord('z'), self.OnUndoOnUndo),
278  (ctrl_or_cmd(), ord('a'), self.OnSelectAllOnSelectAll),
279  (wx.ACCEL_NORMAL, wx.WXK_DELETE, self.OnDeleteOnDelete)]
280 
281  def _write_content(self, value):
282  self.BeginBatch()
283  self.ClearGrid()
284  for index, item in enumerate(value):
285  row, col = divmod(index, self.NumberCols)
286  self.write_cellwrite_cell(row, col, item, False)
287  self.EndBatch()
288  self.AutoSizeRows()
289 
290 
299  def _colorize(self):
300  pass
301 
302  def get_value(self):
303  value = []
304  for row in range(self.NumberRows):
305  for col in range(self.NumberCols):
306  value.append(self.GetCellValue(row, col))
307  while value and not value[-1]:
308  value.pop()
309  return value
310 
311  def OnEditorShown(self, event):
312  if event.Row >= self.NumberRows - 1:
313  self.AppendRows(1)
314 
315  def OnInsertCells(self, event):
316  if len(self.selectionselection.rows()) != 1:
317  self._insert_cells_to_multiple_rows_insert_cells_to_multiple_rows(event)
318  return
319 
320  def insert_cells(data, start, end):
321  return data[:start] + [''] * (end - start) + data[start:]
322  self._insert_or_delete_cells_on_single_row_insert_or_delete_cells_on_single_row(insert_cells, event)
323 
324  def OnDeleteCells(self, event):
325  # print("DEBUG delete cells %s" % self.selection.rows())
326  if len(self.selectionselection.rows()) != 1:
327  self._delete_cells_from_multiple_rows_delete_cells_from_multiple_rows(event)
328  return
329 
330  def delete_cells(data, start, end):
331  return data[:start] + data[end:]
332  self._insert_or_delete_cells_on_single_row_insert_or_delete_cells_on_single_row(delete_cells, event)
333 
334  def _insert_or_delete_cells_on_single_row(self, action, event):
335  self._update_history_update_history()
336  value = self.get_valueget_value()
337  row, col = self.selectionselection.cell
338  start = row * self.NumberCols + col
339  data = action(value, start, start + len(self.selectionselection.cols()))
340  self._write_content_write_content(data)
341  event.Skip()
342 
344  GridEditor.OnInsertCells(self, event)
345 
347  GridEditor.OnDeleteCells(self, event)
348 
349  def OnCopy(self, event):
350  self.copycopy()
351 
352  def OnCut(self, event):
353  self.cutcut()
354 
355  def OnPaste(self, event):
356  self.pastepaste()
357 
358  def OnDelete(self, event):
359  self.deletedelete()
360 
361  def OnUndo(self, event):
362  self.undoundo()
363 
364  def OnSelectAll(self, event):
365  self.SelectAll()
366 
367  def resize_columns(self, width):
368  # print("DEBUG: Called resize coluumns, width=%d" % width)
369  self.SetDefaultColSize(max(int(width / self.NumberCols), 100), True)
370 
371  def set_number_of_columns(self, columns):
372  new_cols = columns - self.NumberCols
373  if not new_cols:
374  return
375  width = self.NumberCols * self.GetDefaultColSize()
376  data = self.get_valueget_value()
377  self._set_cols_set_cols(new_cols)
378  self.resize_columnsresize_columns(width)
379  self._write_content_write_content(data)
380 
381  def _set_cols(self, new_cols):
382  if new_cols > 0:
383  self.AppendCols(numCols=new_cols)
384  else:
385  self.DeleteCols(numCols=-new_cols)
386 
387 
389 
392  _sizer_flags_for_editor = wx.ALL | wx.EXPAND
393 
394  def _get_text_ctrl(self):
395  editor = wx.TextCtrl(self, style=wx.TE_MULTILINE|wx.TE_NOHIDESEL, size=(600, 400))
396  editor.SetBackgroundColour(Colour(self.color_secondary_backgroundcolor_secondary_background))
397  editor.SetForegroundColour(Colour(self.color_secondary_foregroundcolor_secondary_foreground))
398  """
399  editor.SetBackgroundColour(Colour(200, 222, 40))
400  editor.SetOwnBackgroundColour(Colour(200, 222, 40))
401  editor.SetForegroundColour(Colour(7, 0, 70))
402  editor.SetOwnForegroundColour(Colour(7, 0, 70))
403  """
404  return editor
405 
406 
408 
409  def __init__(self, parent, value, label=None, validator=None,
410  settings=None, suggestion_source=None):
411  self._suggestion_source_suggestion_source = suggestion_source or SuggestionSource(
412  parent.plugin, None)
413  ValueEditor.__init__(self, parent, value, label, validator, settings)
414 
415  def _get_text_ctrl(self):
416  editor_ctrl = ContentAssistTextCtrl(self, self._suggestion_source_suggestion_source)
417  editor_ctrl.SetBackgroundColour(Colour(self.color_background_helpcolor_background_help))
418  editor_ctrl.SetForegroundColour(Colour(self.color_foreground_textcolor_foreground_text))
419  return editor_ctrl
420  #DEBUG size, (500, -1))
def _create_editor(self, value, label, settings)
def __init__(self, parent, value, label=None, validator=None, settings=None, suggestion_source=None)
def __init__(self, parent, value, label, controller, validator=None, settings=None, suggestion_source=None)
def _create_editor(self, value, label, settings)
def __init__(self, parent, value, label=None, validator=None, settings=None)
Definition: fieldeditors.py:40
def _create_editor(self, value, label, settings)
Definition: fieldeditors.py:61
def _insert_or_delete_cells_on_single_row(self, action, event)
def __init__(self, parent, value, num_cols)
def write_cell(self, row, col, value, update_history=True)
Definition: gridbase.py:92
def bind_keys_to_evt_menu(target, actions)
Definition: __init__.py:74
def ctrl_or_cmd()
Definition: __init__.py:68