GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gmodeler/dialogs.py
Go to the documentation of this file.
1 """!
2 @package gmodeler.dialogs
3 
4 @brief wxGUI Graphical Modeler - dialogs
5 
6 Classes:
7  - dialogs::ModelDataDialog
8  - dialogs::ModelSearchDialog
9  - dialogs::ModelRelationDialog
10  - dialogs::ModelItemDialog
11  - dialogs::ModelLoopDialog
12  - dialogs::ModelConditionDialog
13  - dialogs::ModelListCtrl
14  - dialogs::ValiableListCtrl
15  - dialogs::ItemListCtrl
16  - dialogs::ItemCheckListCtrl
17 
18 (C) 2010-2011 by the GRASS Development Team
19 
20 This program is free software under the GNU General Public License
21 (>=v2). Read the file COPYING that comes with GRASS for details.
22 
23 @author Martin Landa <landa.martin gmail.com>
24 """
25 
26 import os
27 import sys
28 
29 import wx
30 import wx.lib.mixins.listctrl as listmix
31 
32 from core import globalvar
33 from core import utils
34 from gui_core.widgets import GNotebook
35 from core.gcmd import GError, EncodeString
36 from gui_core.dialogs import ElementDialog, MapLayersDialog
37 from gui_core.ghelp import SearchModuleWindow
38 from gui_core.prompt import GPromptSTC
39 from gui_core.forms import CmdPanel
40 from gui_core.gselect import Select
41 from gmodeler.model import *
42 
43 from grass.script import task as gtask
44 
46  """!Data item properties dialog"""
47  def __init__(self, parent, shape, id = wx.ID_ANY, title = _("Data properties"),
48  style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
49  self.parent = parent
50  self.shape = shape
51 
52  label, etype = self._getLabel()
53  ElementDialog.__init__(self, parent, title, label = label, etype = etype)
54 
55  self.element = Select(parent = self.panel)
56  self.element.SetValue(shape.GetValue())
57 
58  self.Bind(wx.EVT_BUTTON, self.OnOK, self.btnOK)
59  self.Bind(wx.EVT_BUTTON, self.OnCancel, self.btnCancel)
60 
61  self.PostInit()
62 
63  if shape.GetValue():
64  self.btnOK.Enable()
65 
66  self._layout()
67  self.SetMinSize(self.GetSize())
68 
69  def _getLabel(self):
70  etype = False
71  prompt = self.shape.GetPrompt()
72  if prompt == 'raster':
73  label = _('Name of raster map:')
74  elif prompt == 'vector':
75  label = _('Name of vector map:')
76  else:
77  etype = True
78  label = _('Name of element:')
79 
80  return label, etype
81 
82  def _layout(self):
83  """!Do layout"""
84  self.dataSizer.Add(self.element, proportion=0,
85  flag=wx.EXPAND | wx.ALL, border=1)
86 
87  self.panel.SetSizer(self.sizer)
88  self.sizer.Fit(self)
89 
90  def OnOK(self, event):
91  """!Ok pressed"""
92  self.shape.SetValue(self.GetElement())
93  if self.etype:
94  elem = self.GetType()
95  if elem == 'rast':
96  self.shape.SetPrompt('raster')
97  elif elem == 'vect':
98  self.shape.SetPrompt('raster')
99 
100  self.parent.canvas.Refresh()
101  self.parent.SetStatusText('', 0)
102  self.shape.SetPropDialog(None)
103 
104  if self.IsModal():
105  event.Skip()
106  else:
107  self.Destroy()
108 
109  def OnCancel(self, event):
110  """!Cancel pressed"""
111  self.shape.SetPropDialog(None)
112  if self.IsModal():
113  event.Skip()
114  else:
115  self.Destroy()
116 
117 class ModelSearchDialog(wx.Dialog):
118  def __init__(self, parent, id = wx.ID_ANY, title = _("Add new GRASS module to the model"),
119  style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
120  """!Graphical modeler module search window
121 
122  @param parent parent window
123  @param id window id
124  @param title window title
125  @param kwargs wx.Dialogs' arguments
126  """
127  self.parent = parent
128 
129  wx.Dialog.__init__(self, parent = parent, id = id, title = title, **kwargs)
130  self.SetName("ModelerDialog")
131  self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO))
132 
133  self.panel = wx.Panel(parent = self, id = wx.ID_ANY)
134 
135  self.cmdBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
136  label=" %s " % _("Command"))
137 
138  self.cmd_prompt = GPromptSTC(parent = self)
139  self.search = SearchModuleWindow(parent = self.panel, cmdPrompt = self.cmd_prompt, showTip = True)
140  wx.CallAfter(self.cmd_prompt.SetFocus)
141 
142  # get commands
143  items = self.cmd_prompt.GetCommandItems()
144 
145  self.btnCancel = wx.Button(self.panel, wx.ID_CANCEL)
146  self.btnOk = wx.Button(self.panel, wx.ID_OK)
147  self.btnOk.SetDefault()
148  self.btnOk.Enable(False)
149 
150  self.cmd_prompt.Bind(wx.EVT_KEY_UP, self.OnText)
151  self.search.searchChoice.Bind(wx.EVT_CHOICE, self.OnText)
152  self.Bind(wx.EVT_BUTTON, self.OnOk, self.btnOk)
153  self.Bind(wx.EVT_BUTTON, self.OnCancel, self.btnCancel)
154 
155  self._layout()
156 
157  self.SetSize((500, 275))
158 
159  def _layout(self):
160  cmdSizer = wx.StaticBoxSizer(self.cmdBox, wx.VERTICAL)
161  cmdSizer.Add(item = self.cmd_prompt, proportion = 1,
162  flag = wx.EXPAND)
163 
164  btnSizer = wx.StdDialogButtonSizer()
165  btnSizer.AddButton(self.btnCancel)
166  btnSizer.AddButton(self.btnOk)
167  btnSizer.Realize()
168 
169  mainSizer = wx.BoxSizer(wx.VERTICAL)
170  mainSizer.Add(item = self.search, proportion = 0,
171  flag = wx.EXPAND | wx.ALL, border = 3)
172  mainSizer.Add(item = cmdSizer, proportion = 1,
173  flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, border = 3)
174  mainSizer.Add(item = btnSizer, proportion = 0,
175  flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
176 
177  self.panel.SetSizer(mainSizer)
178  mainSizer.Fit(self.panel)
179 
180  self.Layout()
181 
182  def GetPanel(self):
183  """!Get dialog panel"""
184  return self.panel
185 
186  def GetCmd(self):
187  """!Get command"""
188  line = self.cmd_prompt.GetCurLine()[0].strip()
189  if len(line) == 0:
190  list()
191 
192  try:
193  cmd = utils.split(str(line))
194  except UnicodeError:
195  cmd = utils.split(utils.EncodeString((line)))
196 
197  return cmd
198 
199  def OnOk(self, event):
200  """!Button 'OK' pressed"""
201  # hide autocomplete
202  if self.cmd_prompt.AutoCompActive():
203  self.cmd_prompt.AutoCompCancel()
204 
205  self.btnOk.SetFocus()
206  cmd = self.GetCmd()
207 
208  if len(cmd) < 1:
209  GError(parent = self,
210  message = _("Command not defined.\n\n"
211  "Unable to add new action to the model."))
212  return
213 
214  if cmd[0] not in globalvar.grassCmd:
215  GError(parent = self,
216  message = _("'%s' is not a GRASS module.\n\n"
217  "Unable to add new action to the model.") % cmd[0])
218  return
219 
220  self.EndModal(wx.ID_OK)
221 
222  def OnCancel(self, event):
223  """Cancel pressed, close window"""
224  # hide autocomplete
225  if self.cmd_prompt.AutoCompActive():
226  self.cmd_prompt.AutoCompCancel()
227 
228  self.Hide()
229 
230  def OnText(self, event):
231  """!Text in prompt changed"""
232  if self.cmd_prompt.AutoCompActive():
233  event.Skip()
234  return
235 
236  if isinstance(event, wx.KeyEvent):
237  entry = self.cmd_prompt.GetTextLeft()
238  elif isinstance(event, wx.stc.StyledTextEvent):
239  entry = event.GetText()
240  else:
241  entry = event.GetString()
242 
243  if entry:
244  self.btnOk.Enable()
245  else:
246  self.btnOk.Enable(False)
247 
248  event.Skip()
249 
250  def Reset(self):
251  """!Reset dialog"""
252  self.search.Reset()
253  self.cmd_prompt.OnCmdErase(None)
254  self.btnOk.Enable(False)
255  self.cmd_prompt.SetFocus()
256 
257 class ModelRelationDialog(wx.Dialog):
258  """!Relation properties dialog"""
259  def __init__(self, parent, shape, id = wx.ID_ANY, title = _("Relation properties"),
260  style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
261  self.parent = parent
262  self.shape = shape
263 
264  options = self._getOptions()
265  if not options:
266  self.valid = False
267  return
268 
269  self.valid = True
270  wx.Dialog.__init__(self, parent, id, title, style = style, **kwargs)
271  self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO))
272 
273  self.panel = wx.Panel(parent = self, id = wx.ID_ANY)
274 
275  self.fromBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
276  label = " %s " % _("From"))
277  self.toBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
278  label = " %s " % _("To"))
279 
280  self.option = wx.ComboBox(parent = self.panel, id = wx.ID_ANY,
281  style = wx.CB_READONLY,
282  choices = options)
283  self.option.Bind(wx.EVT_COMBOBOX, self.OnOption)
284 
285  self.btnCancel = wx.Button(self.panel, wx.ID_CANCEL)
286  self.btnOk = wx.Button(self.panel, wx.ID_OK)
287  self.btnOk.Enable(False)
288 
289  self._layout()
290 
291  def _layout(self):
292  mainSizer = wx.BoxSizer(wx.VERTICAL)
293 
294  fromSizer = wx.StaticBoxSizer(self.fromBox, wx.VERTICAL)
295  self._layoutShape(shape = self.shape.GetFrom(), sizer = fromSizer)
296  toSizer = wx.StaticBoxSizer(self.toBox, wx.VERTICAL)
297  self._layoutShape(shape = self.shape.GetTo(), sizer = toSizer)
298 
299  btnSizer = wx.StdDialogButtonSizer()
300  btnSizer.AddButton(self.btnCancel)
301  btnSizer.AddButton(self.btnOk)
302  btnSizer.Realize()
303 
304  mainSizer.Add(item = fromSizer, proportion = 0,
305  flag = wx.EXPAND | wx.ALL, border = 5)
306  mainSizer.Add(item = toSizer, proportion = 0,
307  flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border = 5)
308  mainSizer.Add(item = btnSizer, proportion = 0,
309  flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
310 
311  self.panel.SetSizer(mainSizer)
312  mainSizer.Fit(self.panel)
313 
314  self.Layout()
315  self.SetSize(self.GetBestSize())
316 
317  def _layoutShape(self, shape, sizer):
318  if isinstance(shape, ModelData):
319  sizer.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
320  label = _("Data: %s") % shape.GetLog()),
321  proportion = 1, flag = wx.EXPAND | wx.ALL,
322  border = 5)
323  elif isinstance(shape, ModelAction):
324  gridSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
325  gridSizer.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
326  label = _("Command:")),
327  pos = (0, 0))
328  gridSizer.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
329  label = shape.GetName()),
330  pos = (0, 1))
331  gridSizer.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
332  label = _("Option:")),
333  flag = wx.ALIGN_CENTER_VERTICAL,
334  pos = (1, 0))
335  gridSizer.Add(item = self.option,
336  pos = (1, 1))
337  sizer.Add(item = gridSizer,
338  proportion = 1, flag = wx.EXPAND | wx.ALL,
339  border = 5)
340 
341  def _getOptions(self):
342  """!Get relevant options"""
343  items = []
344  fromShape = self.shape.GetFrom()
345  if not isinstance(fromShape, ModelData):
346  GError(parent = self.parent,
347  message = _("Relation doesn't start with data item.\n"
348  "Unable to add relation."))
349  return items
350 
351  toShape = self.shape.GetTo()
352  if not isinstance(toShape, ModelAction):
353  GError(parent = self.parent,
354  message = _("Relation doesn't point to GRASS command.\n"
355  "Unable to add relation."))
356  return items
357 
358  prompt = fromShape.GetPrompt()
359  task = toShape.GetTask()
360  for p in task.get_options()['params']:
361  if p.get('prompt', '') == prompt and \
362  'name' in p:
363  items.append(p['name'])
364 
365  if not items:
366  GError(parent = self.parent,
367  message = _("No relevant option found.\n"
368  "Unable to add relation."))
369  return items
370 
371  def GetOption(self):
372  """!Get selected option"""
373  return self.option.GetStringSelection()
374 
375  def IsValid(self):
376  """!Check if relation is valid"""
377  return self.valid
378 
379  def OnOption(self, event):
380  """!Set option"""
381  if event.GetString():
382  self.btnOk.Enable()
383  else:
384  self.btnOk.Enable(False)
385 
386 class ModelItemDialog(wx.Dialog):
387  """!Abstract item properties dialog"""
388  def __init__(self, parent, shape, title, id = wx.ID_ANY,
389  style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
390  self.parent = parent
391  self.shape = shape
392 
393  wx.Dialog.__init__(self, parent, id, title = title, style = style, **kwargs)
394 
395  self.panel = wx.Panel(parent = self, id = wx.ID_ANY)
396 
397  self.condBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
398  label=" %s " % _("Condition"))
399  self.condText = wx.TextCtrl(parent = self.panel, id = wx.ID_ANY,
400  value = shape.GetText())
401 
402  self.itemList = ItemCheckListCtrl(parent = self.panel,
403  window = self,
404  columns = [_("ID"), _("Name"),
405  _("Command")],
406  shape = shape)
407  self.itemList.Populate(self.parent.GetModel().GetItems())
408 
409  self.btnCancel = wx.Button(parent = self.panel, id = wx.ID_CANCEL)
410  self.btnOk = wx.Button(parent = self.panel, id = wx.ID_OK)
411  self.btnOk.SetDefault()
412 
413  def _layout(self):
414  """!Do layout (virtual method)"""
415  pass
416 
417  def GetCondition(self):
418  """!Get loop condition"""
419  return self.condText.GetValue()
420 
422  """!Loop properties dialog"""
423  def __init__(self, parent, shape, id = wx.ID_ANY, title = _("Loop properties"),
424  style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
425  ModelItemDialog.__init__(self, parent, shape, title,
426  style = style, **kwargs)
427 
428  self.listBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
429  label=" %s " % _("List of items in loop"))
430 
431  self.btnSeries = wx.Button(parent = self.panel, id = wx.ID_ANY,
432  label = _("Series"))
433  self.btnSeries.SetToolTipString(_("Define map series as condition for the loop"))
434  self.btnSeries.Bind(wx.EVT_BUTTON, self.OnSeries)
435 
436  self._layout()
437  self.SetMinSize(self.GetSize())
438  self.SetSize((500, 400))
439 
440  def _layout(self):
441  """!Do layout"""
442  sizer = wx.BoxSizer(wx.VERTICAL)
443 
444  condSizer = wx.StaticBoxSizer(self.condBox, wx.HORIZONTAL)
445  condSizer.Add(item = self.condText, proportion = 1,
446  flag = wx.ALL, border = 3)
447  condSizer.Add(item = self.btnSeries, proportion = 0,
448  flag = wx.EXPAND)
449 
450  listSizer = wx.StaticBoxSizer(self.listBox, wx.VERTICAL)
451  listSizer.Add(item = self.itemList, proportion = 1,
452  flag = wx.EXPAND | wx.ALL, border = 3)
453 
454  btnSizer = wx.StdDialogButtonSizer()
455  btnSizer.AddButton(self.btnCancel)
456  btnSizer.AddButton(self.btnOk)
457  btnSizer.Realize()
458 
459  sizer.Add(item = condSizer, proportion = 0,
460  flag = wx.EXPAND | wx.ALL, border = 3)
461  sizer.Add(item = listSizer, proportion = 1,
462  flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border = 3)
463  sizer.Add(item = btnSizer, proportion=0,
464  flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
465 
466  self.panel.SetSizer(sizer)
467  sizer.Fit(self.panel)
468 
469  self.Layout()
470 
471  def GetItems(self):
472  """!Get list of selected actions"""
473  return self.itemList.GetItems()
474 
475  def OnSeries(self, event):
476  """!Define map series as condition"""
477  dialog = MapLayersDialog(parent = self, title = _("Define series of maps"), modeler = True)
478  if dialog.ShowModal() != wx.ID_OK:
479  dialog.Destroy()
480  return
481 
482  cond = dialog.GetDSeries()
483  if not cond:
484  cond = 'map in %s' % map(lambda x: str(x), dialog.GetMapLayers())
485 
486  self.condText.SetValue(cond)
487 
488  dialog.Destroy()
489 
491  """!Condition properties dialog"""
492  def __init__(self, parent, shape, id = wx.ID_ANY, title = _("If-else properties"),
493  style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
494  ModelItemDialog.__init__(self, parent, shape, title,
495  style = style, **kwargs)
496 
497  self.listBoxIf = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
498  label=" %s " % _("List of items in 'if' block"))
499  self.itemListIf = self.itemList
500  self.itemListIf.SetName('IfBlockList')
501 
502  self.listBoxElse = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
503  label=" %s " % _("List of items in 'else' block"))
504  self.itemListElse = ItemCheckListCtrl(parent = self.panel,
505  window = self,
506  columns = [_("ID"), _("Name"),
507  _("Command")],
508  shape = shape)
509  self.itemListElse.SetName('ElseBlockList')
510  self.itemListElse.Populate(self.parent.GetModel().GetItems())
511 
512  self._layout()
513  self.SetMinSize(self.GetSize())
514  self.SetSize((500, 400))
515 
516  def _layout(self):
517  """!Do layout"""
518  sizer = wx.BoxSizer(wx.VERTICAL)
519 
520  condSizer = wx.StaticBoxSizer(self.condBox, wx.VERTICAL)
521  condSizer.Add(item = self.condText, proportion = 1,
522  flag = wx.EXPAND)
523 
524  listIfSizer = wx.StaticBoxSizer(self.listBoxIf, wx.VERTICAL)
525  listIfSizer.Add(item = self.itemListIf, proportion = 1,
526  flag = wx.EXPAND)
527  listElseSizer = wx.StaticBoxSizer(self.listBoxElse, wx.VERTICAL)
528  listElseSizer.Add(item = self.itemListElse, proportion = 1,
529  flag = wx.EXPAND)
530 
531  btnSizer = wx.StdDialogButtonSizer()
532  btnSizer.AddButton(self.btnCancel)
533  btnSizer.AddButton(self.btnOk)
534  btnSizer.Realize()
535 
536  sizer.Add(item = condSizer, proportion = 0,
537  flag = wx.EXPAND | wx.ALL, border = 3)
538  sizer.Add(item = listIfSizer, proportion = 1,
539  flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border = 3)
540  sizer.Add(item = listElseSizer, proportion = 1,
541  flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border = 3)
542  sizer.Add(item = btnSizer, proportion=0,
543  flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
544 
545  self.panel.SetSizer(sizer)
546  sizer.Fit(self.panel)
547 
548  self.Layout()
549 
550  def OnCheckItemIf(self, index, flag):
551  """!Item in if-block checked/unchecked"""
552  if flag is False:
553  return
554 
555  aId = int(self.itemListIf.GetItem(index, 0).GetText())
556  if aId in self.itemListElse.GetItems()['checked']:
557  self.itemListElse.CheckItemById(aId, False)
558 
559  def OnCheckItemElse(self, index, flag):
560  """!Item in else-block checked/unchecked"""
561  if flag is False:
562  return
563 
564  aId = int(self.itemListElse.GetItem(index, 0).GetText())
565  if aId in self.itemListIf.GetItems()['checked']:
566  self.itemListIf.CheckItemById(aId, False)
567 
568  def GetItems(self):
569  """!Get items"""
570  return { 'if' : self.itemListIf.GetItems(),
571  'else' : self.itemListElse.GetItems() }
572 
573 class ModelListCtrl(wx.ListCtrl,
574  listmix.ListCtrlAutoWidthMixin,
575  listmix.TextEditMixin,
576  listmix.ColumnSorterMixin):
577  def __init__(self, parent, columns, id = wx.ID_ANY,
578  style = wx.LC_REPORT | wx.BORDER_NONE |
579  wx.LC_SORT_ASCENDING |wx.LC_HRULES |
580  wx.LC_VRULES, **kwargs):
581  """!List of model variables"""
582  self.parent = parent
583  self.columns = columns
584  self.shape = None
585  try:
586  self.frame = parent.parent
587  except AttributeError:
588  self.frame = None
589 
590  wx.ListCtrl.__init__(self, parent, id = id, style = style, **kwargs)
591  listmix.ListCtrlAutoWidthMixin.__init__(self)
592  listmix.TextEditMixin.__init__(self)
593  listmix.ColumnSorterMixin.__init__(self, 4)
594 
595  i = 0
596  for col in columns:
597  self.InsertColumn(i, col)
598  self.SetColumnWidth(i, wx.LIST_AUTOSIZE_USEHEADER)
599  i += 1
600 
601  self.itemDataMap = {} # requested by sorter
602  self.itemCount = 0
603 
604  self.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.OnBeginEdit)
605  self.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnEndEdit)
606  self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick)
607  self.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnRightUp) #wxMSW
608  self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) #wxGTK
609 
610  def OnBeginEdit(self, event):
611  """!Editing of item started"""
612  event.Allow()
613 
614  def OnEndEdit(self, event):
615  """!Finish editing of item"""
616  pass
617 
618  def OnColClick(self, event):
619  """!Click on column header (order by)"""
620  event.Skip()
621 
623  def __init__(self, parent, columns, **kwargs):
624  """!List of model variables"""
625  ModelListCtrl.__init__(self, parent, columns, **kwargs)
626 
627  self.SetColumnWidth(2, 200) # default value
628 
629  def GetListCtrl(self):
630  """!Used by ColumnSorterMixin"""
631  return self
632 
633  def GetData(self):
634  """!Get list data"""
635  return self.itemDataMap
636 
637  def Populate(self, data):
638  """!Populate the list"""
639  self.itemDataMap = dict()
640  i = 0
641  for name, values in data.iteritems():
642  self.itemDataMap[i] = [name, values['type'],
643  values.get('value', ''),
644  values.get('description', '')]
645  i += 1
646 
647  self.itemCount = len(self.itemDataMap.keys())
648  self.DeleteAllItems()
649  i = 0
650  for name, vtype, value, desc in self.itemDataMap.itervalues():
651  index = self.InsertStringItem(sys.maxint, name)
652  self.SetStringItem(index, 0, name)
653  self.SetStringItem(index, 1, vtype)
654  self.SetStringItem(index, 2, value)
655  self.SetStringItem(index, 3, desc)
656  self.SetItemData(index, i)
657  i += 1
658 
659  def Append(self, name, vtype, value, desc):
660  """!Append new item to the list
661 
662  @return None on success
663  @return error string
664  """
665  for iname, ivtype, ivalue, idesc in self.itemDataMap.itervalues():
666  if iname == name:
667  return _("Variable <%s> already exists in the model. "
668  "Adding variable failed.") % name
669 
670  index = self.InsertStringItem(sys.maxint, name)
671  self.SetStringItem(index, 0, name)
672  self.SetStringItem(index, 1, vtype)
673  self.SetStringItem(index, 2, value)
674  self.SetStringItem(index, 3, desc)
675  self.SetItemData(index, self.itemCount)
676 
677  self.itemDataMap[self.itemCount] = [name, vtype, value, desc]
678  self.itemCount += 1
679 
680  return None
681 
682  def OnRemove(self, event):
683  """!Remove selected variable(s) from the model"""
684  item = self.GetFirstSelected()
685  while item != -1:
686  self.DeleteItem(item)
687  del self.itemDataMap[item]
688  item = self.GetFirstSelected()
689  self.parent.UpdateModelVariables()
690 
691  event.Skip()
692 
693  def OnRemoveAll(self, event):
694  """!Remove all variable(s) from the model"""
695  dlg = wx.MessageBox(parent=self,
696  message=_("Do you want to delete all variables from "
697  "the model?"),
698  caption=_("Delete variables"),
699  style=wx.YES_NO | wx.CENTRE)
700  if dlg != wx.YES:
701  return
702 
703  self.DeleteAllItems()
704  self.itemDataMap = dict()
705 
706  self.parent.UpdateModelVariables()
707 
708  def OnEndEdit(self, event):
709  """!Finish editing of item"""
710  itemIndex = event.GetIndex()
711  columnIndex = event.GetColumn()
712  nameOld = self.GetItem(itemIndex, 0).GetText()
713 
714  if columnIndex == 0: # TODO
715  event.Veto()
716 
717  self.itemDataMap[itemIndex][columnIndex] = event.GetText()
718 
719  self.parent.UpdateModelVariables()
720 
721  def OnReload(self, event):
722  """!Reload list of variables"""
723  self.Populate(self.parent.parent.GetModel().GetVariables())
724 
725  def OnRightUp(self, event):
726  """!Mouse right button up"""
727  if not hasattr(self, "popupID1"):
728  self.popupID1 = wx.NewId()
729  self.popupID2 = wx.NewId()
730  self.popupID3 = wx.NewId()
731  self.Bind(wx.EVT_MENU, self.OnRemove, id = self.popupID1)
732  self.Bind(wx.EVT_MENU, self.OnRemoveAll, id = self.popupID2)
733  self.Bind(wx.EVT_MENU, self.OnReload, id = self.popupID3)
734 
735  # generate popup-menu
736  menu = wx.Menu()
737  menu.Append(self.popupID1, _("Delete selected"))
738  menu.Append(self.popupID2, _("Delete all"))
739  if self.GetFirstSelected() == -1:
740  menu.Enable(self.popupID1, False)
741  menu.Enable(self.popupID2, False)
742 
743  menu.AppendSeparator()
744  menu.Append(self.popupID3, _("Reload"))
745 
746  self.PopupMenu(menu)
747  menu.Destroy()
748 
750  def __init__(self, parent, columns, disablePopup = False, **kwargs):
751  """!List of model actions"""
752  self.disablePopup = disablePopup
753 
754  ModelListCtrl.__init__(self, parent, columns, **kwargs)
755  self.SetColumnWidth(1, 100)
756  self.SetColumnWidth(2, 65)
757 
758  def GetListCtrl(self):
759  """!Used by ColumnSorterMixin"""
760  return self
761 
762  def GetData(self):
763  """!Get list data"""
764  return self.itemDataMap
765 
766  def Populate(self, data):
767  """!Populate the list"""
768  self.itemDataMap = dict()
769 
770  if self.shape:
771  if isinstance(self.shape, ModelCondition):
772  if self.GetName() == 'ElseBlockList':
773  shapeItems = map(lambda x: x.GetId(), self.shape.GetItems()['else'])
774  else:
775  shapeItems = map(lambda x: x.GetId(), self.shape.GetItems()['if'])
776  else:
777  shapeItems = map(lambda x: x.GetId(), self.shape.GetItems())
778  else:
779  shapeItems = list()
780 
781  i = 0
782  if len(self.columns) == 3: # ItemCheckList
783  checked = list()
784  for action in data:
785  if isinstance(action, ModelData) or \
786  action == self.shape:
787  continue
788 
789  if len(self.columns) == 3:
790  self.itemDataMap[i] = [str(action.GetId()),
791  action.GetName(),
792  action.GetLog()]
793  aId = action.GetBlockId()
794  if action.GetId() in shapeItems:
795  checked.append(aId)
796  else:
797  checked.append(None)
798  else:
799  bId = action.GetBlockId()
800  if not bId:
801  bId = ''
802  self.itemDataMap[i] = [str(action.GetId()),
803  action.GetName(),
804  ','.join(map(str, bId)),
805  action.GetLog()]
806 
807  i += 1
808 
809  self.itemCount = len(self.itemDataMap.keys())
810  self.DeleteAllItems()
811  i = 0
812  if len(self.columns) == 3:
813  for aid, name, desc in self.itemDataMap.itervalues():
814  index = self.InsertStringItem(sys.maxint, aid)
815  self.SetStringItem(index, 0, aid)
816  self.SetStringItem(index, 1, name)
817  self.SetStringItem(index, 2, desc)
818  self.SetItemData(index, i)
819  if checked[i]:
820  self.CheckItem(index, True)
821  i += 1
822  else:
823  for aid, name, inloop, desc in self.itemDataMap.itervalues():
824  index = self.InsertStringItem(sys.maxint, aid)
825  self.SetStringItem(index, 0, aid)
826  self.SetStringItem(index, 1, name)
827  self.SetStringItem(index, 2, inloop)
828  self.SetStringItem(index, 3, desc)
829  self.SetItemData(index, i)
830  i += 1
831 
832  def OnRemove(self, event):
833  """!Remove selected action(s) from the model"""
834  model = self.frame.GetModel()
835  canvas = self.frame.GetCanvas()
836 
837  item = self.GetFirstSelected()
838  while item != -1:
839  self.DeleteItem(item)
840  del self.itemDataMap[item]
841 
842  aId = self.GetItem(item, 0).GetText()
843  action = model.GetItem(int(aId))
844  if not action:
845  item = self.GetFirstSelected()
846  continue
847 
848  model.RemoveItem(action)
849  canvas.GetDiagram().RemoveShape(action)
850  self.frame.ModelChanged()
851 
852  item = self.GetFirstSelected()
853 
854  canvas.Refresh()
855 
856  event.Skip()
857 
858  def OnRemoveAll(self, event):
859  """!Remove all variable(s) from the model"""
860  deleteDialog = wx.MessageBox(parent=self,
861  message=_("Selected data records (%d) will permanently deleted "
862  "from table. Do you want to delete them?") % \
863  (len(self.listOfSQLStatements)),
864  caption=_("Delete records"),
865  style=wx.YES_NO | wx.CENTRE)
866  if deleteDialog != wx.YES:
867  return False
868 
869  self.DeleteAllItems()
870  self.itemDataMap = dict()
871 
872  self.parent.UpdateModelVariables()
873 
874  def OnEndEdit(self, event):
875  """!Finish editing of item"""
876  itemIndex = event.GetIndex()
877  columnIndex = event.GetColumn()
878 
879  self.itemDataMap[itemIndex][columnIndex] = event.GetText()
880 
881  aId = int(self.GetItem(itemIndex, 0).GetText())
882  action = self.frame.GetModel().GetItem(aId)
883  if not action:
884  event.Veto()
885  if columnIndex == 0:
886  action.SetId(int(event.GetText()))
887 
888  self.frame.ModelChanged()
889 
890  def OnReload(self, event = None):
891  """!Reload list of actions"""
892  self.Populate(self.frame.GetModel().GetItems())
893 
894  def OnRightUp(self, event):
895  """!Mouse right button up"""
896  if self.disablePopup:
897  return
898 
899  if not hasattr(self, "popupID1"):
900  self.popupID1 = wx.NewId()
901  self.popupID2 = wx.NewId()
902  self.popupID3 = wx.NewId()
903  self.popupID4 = wx.NewId()
904  self.Bind(wx.EVT_MENU, self.OnRemove, id = self.popupID1)
905  self.Bind(wx.EVT_MENU, self.OnRemoveAll, id = self.popupID2)
906  self.Bind(wx.EVT_MENU, self.OnReload, id = self.popupID3)
907  self.Bind(wx.EVT_MENU, self.OnNormalize, id = self.popupID4)
908 
909  # generate popup-menu
910  menu = wx.Menu()
911  menu.Append(self.popupID1, _("Delete selected"))
912  menu.Append(self.popupID2, _("Delete all"))
913  if self.GetFirstSelected() == -1:
914  menu.Enable(self.popupID1, False)
915  menu.Enable(self.popupID2, False)
916 
917  menu.AppendSeparator()
918  menu.Append(self.popupID4, _("Normalize"))
919  menu.Append(self.popupID3, _("Reload"))
920 
921  self.PopupMenu(menu)
922  menu.Destroy()
923 
924  def OnNormalize(self, event):
925  """!Update id of actions"""
926  model = self.frame.GetModel()
927 
928  aId = 1
929  for item in model.GetItems():
930  item.SetId(aId)
931  aId += 1
932 
933  self.OnReload(None)
934  self.frame.GetCanvas().Refresh()
935  self.frame.ModelChanged()
936 
937 class ItemCheckListCtrl(ItemListCtrl, listmix.CheckListCtrlMixin):
938  def __init__(self, parent, shape, columns, window = None, **kwargs):
939  self.parent = parent
940  self.window = window
941 
942  ItemListCtrl.__init__(self, parent, columns, disablePopup = True, **kwargs)
943  listmix.CheckListCtrlMixin.__init__(self)
944  self.SetColumnWidth(0, 50)
945 
946  self.shape = shape
947 
948  def OnBeginEdit(self, event):
949  """!Disable editing"""
950  event.Veto()
951 
952  def OnCheckItem(self, index, flag):
953  """!Item checked/unchecked"""
954  name = self.GetName()
955  if name == 'IfBlockList' and self.window:
956  self.window.OnCheckItemIf(index, flag)
957  elif name == 'ElseBlockList' and self.window:
958  self.window.OnCheckItemElse(index, flag)
959 
960  def GetItems(self):
961  """!Get list of selected actions"""
962  ids = { 'checked' : list(),
963  'unchecked' : list() }
964  for i in range(self.GetItemCount()):
965  iId = int(self.GetItem(i, 0).GetText())
966  if self.IsChecked(i):
967  ids['checked'].append(iId)
968  else:
969  ids['unchecked'].append(iId)
970 
971  return ids
972 
973  def CheckItemById(self, aId, flag):
974  """!Check/uncheck given item by id"""
975  for i in range(self.GetItemCount()):
976  iId = int(self.GetItem(i, 0).GetText())
977  if iId == aId:
978  self.CheckItem(i, flag)
979  break
def OnRightUp
Mouse right button up.
def GetData
Get list data.
def Append
Append new item to the list.
wxGUI command interface
def OnReload
Reload list of actions.
Data item properties dialog.
def OnReload
Reload list of variables.
def IsValid
Check if relation is valid.
def OnEndEdit
Finish editing of item.
def OnBeginEdit
Disable editing.
wxGUI Graphical Modeler (base classes &amp; read/write)
def OnBeginEdit
Editing of item started.
def GetType
Get element type.
def GetItems
Get list of selected actions.
def Populate
Populate the list.
Relation properties dialog.
Core GUI widgets.
Abstract item properties dialog.
def GetListCtrl
Used by ColumnSorterMixin.
def OnRemove
Remove selected action(s) from the model.
def OnEndEdit
Finish editing of item.
def OnCheckItemIf
Item in if-block checked/unchecked.
Condition properties dialog.
wxGUI command prompt
def GetCondition
Get loop condition.
def OnColClick
Click on column header (order by)
Various dialogs used in wxGUI.
def GetListCtrl
Used by ColumnSorterMixin.
Custom control that selects elements.
def GetPanel
Get dialog panel.
def split
Platform spefic shlex.split.
Definition: core/utils.py:37
def OnRightUp
Mouse right button up.
def OnText
Text in prompt changed.
def __init__
List of model variables.
def OnOk
Button &#39;OK&#39; pressed.
def __init__
Graphical modeler module search window.
def OnSeries
Define map series as condition.
def CheckItemById
Check/uncheck given item by id.
def EncodeString
Return encoded string using system locales.
Definition: core/utils.py:721
def GetElement
Return (mapName, overwrite)
def OnNormalize
Update id of actions.
def GetOption
Get selected option.
def OnRemoveAll
Remove all variable(s) from the model.
def OnRemove
Remove selected variable(s) from the model.
Help window.
def GetItems
Get list of selected actions.
def OnRemoveAll
Remove all variable(s) from the model.
def OnEndEdit
Finish editing of item.
def Populate
Populate the list.
def GetData
Get list data.
Loop properties dialog.
def OnCheckItemElse
Item in else-block checked/unchecked.
tuple range
Definition: tools.py:1406
def __init__
List of model variables.
def __init__
List of model actions.
def OnCheckItem
Item checked/unchecked.
def OnCancel
Cancel pressed.
def _getOptions
Get relevant options.
def _layout
Do layout (virtual method)