dialogs.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  1. """!
  2. @package gmodeler.dialogs
  3. @brief wxGUI Graphical Modeler - dialogs
  4. Classes:
  5. - dialogs::ModelDataDialog
  6. - dialogs::ModelSearchDialog
  7. - dialogs::ModelRelationDialog
  8. - dialogs::ModelParamDialog
  9. - dialogs::ModelItemDialog
  10. - dialogs::ModelLoopDialog
  11. - dialogs::ModelConditionDialog
  12. (C) 2010-2011 by the GRASS Development Team
  13. This program is free software under the GNU General Public License
  14. (>=v2). Read the file COPYING that comes with GRASS for details.
  15. @author Martin Landa <landa.martin gmail.com>
  16. """
  17. import os
  18. import wx
  19. from core import globalvar
  20. from core import utils
  21. from gui_core.widgets import GNotebook
  22. from core.gcmd import GError, EncodeString
  23. from gui_core.dialogs import ElementDialog, MapLayersDialog
  24. from gui_core.ghelp import SearchModuleWindow
  25. from gui_core.prompt import GPromptSTC
  26. from grass.script import task as gtask
  27. class ModelDataDialog(ElementDialog):
  28. """!Data item properties dialog"""
  29. def __init__(self, parent, shape, id = wx.ID_ANY, title = _("Data properties"),
  30. style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
  31. self.parent = parent
  32. self.shape = shape
  33. label, etype = self._getLabel()
  34. ElementDialog.__init__(self, parent, title, label = label, etype = etype)
  35. self.element = gselect.Select(parent = self.panel,
  36. type = prompt)
  37. self.element.SetValue(shape.GetValue())
  38. self.Bind(wx.EVT_BUTTON, self.OnOK, self.btnOK)
  39. self.Bind(wx.EVT_BUTTON, self.OnCancel, self.btnCancel)
  40. self.PostInit()
  41. if shape.GetValue():
  42. self.btnOK.Enable()
  43. self._layout()
  44. self.SetMinSize(self.GetSize())
  45. def _getLabel(self):
  46. etype = False
  47. prompt = self.shape.GetPrompt()
  48. if prompt == 'raster':
  49. label = _('Name of raster map:')
  50. elif prompt == 'vector':
  51. label = _('Name of vector map:')
  52. else:
  53. etype = True
  54. label = _('Name of element:')
  55. return label, etype
  56. def _layout(self):
  57. """!Do layout"""
  58. self.dataSizer.Add(self.element, proportion=0,
  59. flag=wx.EXPAND | wx.ALL, border=1)
  60. self.panel.SetSizer(self.sizer)
  61. self.sizer.Fit(self)
  62. def OnOK(self, event):
  63. """!Ok pressed"""
  64. self.shape.SetValue(self.GetElement())
  65. if self.etype:
  66. elem = self.GetType()
  67. if elem == 'rast':
  68. self.shape.SetPrompt('raster')
  69. elif elem == 'vect':
  70. self.shape.SetPrompt('raster')
  71. self.parent.canvas.Refresh()
  72. self.parent.SetStatusText('', 0)
  73. self.shape.SetPropDialog(None)
  74. if self.IsModal():
  75. event.Skip()
  76. else:
  77. self.Destroy()
  78. def OnCancel(self, event):
  79. """!Cancel pressed"""
  80. self.shape.SetPropDialog(None)
  81. if self.IsModal():
  82. event.Skip()
  83. else:
  84. self.Destroy()
  85. class ModelSearchDialog(wx.Dialog):
  86. def __init__(self, parent, id = wx.ID_ANY, title = _("Add new GRASS module to the model"),
  87. style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
  88. """!Graphical modeler module search window
  89. @param parent parent window
  90. @param id window id
  91. @param title window title
  92. @param kwargs wx.Dialogs' arguments
  93. """
  94. self.parent = parent
  95. wx.Dialog.__init__(self, parent = parent, id = id, title = title, **kwargs)
  96. self.SetName("ModelerDialog")
  97. self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO))
  98. self.panel = wx.Panel(parent = self, id = wx.ID_ANY)
  99. self.cmdBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
  100. label=" %s " % _("Command"))
  101. self.cmd_prompt = GPromptSTC(parent = self)
  102. self.search = SearchModuleWindow(parent = self.panel, cmdPrompt = self.cmd_prompt, showTip = True)
  103. wx.CallAfter(self.cmd_prompt.SetFocus)
  104. # get commands
  105. items = self.cmd_prompt.GetCommandItems()
  106. self.btnCancel = wx.Button(self.panel, wx.ID_CANCEL)
  107. self.btnOk = wx.Button(self.panel, wx.ID_OK)
  108. self.btnOk.SetDefault()
  109. self.btnOk.Enable(False)
  110. self.cmd_prompt.Bind(wx.EVT_KEY_UP, self.OnText)
  111. self.search.searchChoice.Bind(wx.EVT_CHOICE, self.OnText)
  112. self.Bind(wx.EVT_BUTTON, self.OnOk, self.btnOk)
  113. self._layout()
  114. self.SetSize((500, 275))
  115. def _layout(self):
  116. cmdSizer = wx.StaticBoxSizer(self.cmdBox, wx.VERTICAL)
  117. cmdSizer.Add(item = self.cmd_prompt, proportion = 1,
  118. flag = wx.EXPAND)
  119. btnSizer = wx.StdDialogButtonSizer()
  120. btnSizer.AddButton(self.btnCancel)
  121. btnSizer.AddButton(self.btnOk)
  122. btnSizer.Realize()
  123. mainSizer = wx.BoxSizer(wx.VERTICAL)
  124. mainSizer.Add(item = self.search, proportion = 0,
  125. flag = wx.EXPAND | wx.ALL, border = 3)
  126. mainSizer.Add(item = cmdSizer, proportion = 1,
  127. flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, border = 3)
  128. mainSizer.Add(item = btnSizer, proportion = 0,
  129. flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
  130. self.panel.SetSizer(mainSizer)
  131. mainSizer.Fit(self.panel)
  132. self.Layout()
  133. def GetPanel(self):
  134. """!Get dialog panel"""
  135. return self.panel
  136. def GetCmd(self):
  137. """!Get command"""
  138. line = self.cmd_prompt.GetCurLine()[0].strip()
  139. if len(line) == 0:
  140. list()
  141. try:
  142. cmd = utils.split(str(line))
  143. except UnicodeError:
  144. cmd = utils.split(EncodeString((line)))
  145. return cmd
  146. def OnOk(self, event):
  147. """!Button 'OK' pressed"""
  148. self.btnOk.SetFocus()
  149. cmd = self.GetCmd()
  150. if len(cmd) < 1:
  151. GError(parent = self,
  152. message = _("Command not defined.\n\n"
  153. "Unable to add new action to the model."))
  154. return
  155. if cmd[0] not in globalvar.grassCmd['all']:
  156. GError(parent = self,
  157. message = _("'%s' is not a GRASS module.\n\n"
  158. "Unable to add new action to the model.") % cmd[0])
  159. return
  160. self.EndModal(wx.ID_OK)
  161. def OnText(self, event):
  162. """!Text in prompt changed"""
  163. if self.cmd_prompt.AutoCompActive():
  164. event.Skip()
  165. return
  166. if isinstance(event, wx.KeyEvent):
  167. entry = self.cmd_prompt.GetTextLeft()
  168. elif isinstance(event, wx.stc.StyledTextEvent):
  169. entry = event.GetText()
  170. else:
  171. entry = event.GetString()
  172. if entry:
  173. self.btnOk.Enable()
  174. else:
  175. self.btnOk.Enable(False)
  176. event.Skip()
  177. def Reset(self):
  178. """!Reset dialog"""
  179. self.search.Reset()
  180. self.cmd_prompt.OnCmdErase(None)
  181. self.btnOk.Enable(False)
  182. self.cmd_prompt.SetFocus()
  183. class ModelRelationDialog(wx.Dialog):
  184. """!Relation properties dialog"""
  185. def __init__(self, parent, shape, id = wx.ID_ANY, title = _("Relation properties"),
  186. style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
  187. self.parent = parent
  188. self.shape = shape
  189. options = self._getOptions()
  190. if not options:
  191. self.valid = False
  192. return
  193. self.valid = True
  194. wx.Dialog.__init__(self, parent, id, title, style = style, **kwargs)
  195. self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO))
  196. self.panel = wx.Panel(parent = self, id = wx.ID_ANY)
  197. self.fromBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
  198. label = " %s " % _("From"))
  199. self.toBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
  200. label = " %s " % _("To"))
  201. self.option = wx.ComboBox(parent = self.panel, id = wx.ID_ANY,
  202. style = wx.CB_READONLY,
  203. choices = options)
  204. self.option.Bind(wx.EVT_COMBOBOX, self.OnOption)
  205. self.btnCancel = wx.Button(self.panel, wx.ID_CANCEL)
  206. self.btnOk = wx.Button(self.panel, wx.ID_OK)
  207. self.btnOk.Enable(False)
  208. self._layout()
  209. def _layout(self):
  210. mainSizer = wx.BoxSizer(wx.VERTICAL)
  211. fromSizer = wx.StaticBoxSizer(self.fromBox, wx.VERTICAL)
  212. self._layoutShape(shape = self.shape.GetFrom(), sizer = fromSizer)
  213. toSizer = wx.StaticBoxSizer(self.toBox, wx.VERTICAL)
  214. self._layoutShape(shape = self.shape.GetTo(), sizer = toSizer)
  215. btnSizer = wx.StdDialogButtonSizer()
  216. btnSizer.AddButton(self.btnCancel)
  217. btnSizer.AddButton(self.btnOk)
  218. btnSizer.Realize()
  219. mainSizer.Add(item = fromSizer, proportion = 0,
  220. flag = wx.EXPAND | wx.ALL, border = 5)
  221. mainSizer.Add(item = toSizer, proportion = 0,
  222. flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border = 5)
  223. mainSizer.Add(item = btnSizer, proportion = 0,
  224. flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
  225. self.panel.SetSizer(mainSizer)
  226. mainSizer.Fit(self.panel)
  227. self.Layout()
  228. self.SetSize(self.GetBestSize())
  229. def _layoutShape(self, shape, sizer):
  230. if isinstance(shape, ModelData):
  231. sizer.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
  232. label = _("Data: %s") % shape.GetLog()),
  233. proportion = 1, flag = wx.EXPAND | wx.ALL,
  234. border = 5)
  235. elif isinstance(shape, ModelAction):
  236. gridSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
  237. gridSizer.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
  238. label = _("Command:")),
  239. pos = (0, 0))
  240. gridSizer.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
  241. label = shape.GetName()),
  242. pos = (0, 1))
  243. gridSizer.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
  244. label = _("Option:")),
  245. flag = wx.ALIGN_CENTER_VERTICAL,
  246. pos = (1, 0))
  247. gridSizer.Add(item = self.option,
  248. pos = (1, 1))
  249. sizer.Add(item = gridSizer,
  250. proportion = 1, flag = wx.EXPAND | wx.ALL,
  251. border = 5)
  252. def _getOptions(self):
  253. """!Get relevant options"""
  254. items = []
  255. fromShape = self.shape.GetFrom()
  256. if not isinstance(fromShape, ModelData):
  257. GError(parent = self.parent,
  258. message = _("Relation doesn't start with data item.\n"
  259. "Unable to add relation."))
  260. return items
  261. toShape = self.shape.GetTo()
  262. if not isinstance(toShape, ModelAction):
  263. GError(parent = self.parent,
  264. message = _("Relation doesn't point to GRASS command.\n"
  265. "Unable to add relation."))
  266. return items
  267. prompt = fromShape.GetPrompt()
  268. task = toShape.GetTask()
  269. for p in task.get_options()['params']:
  270. if p.get('prompt', '') == prompt and \
  271. 'name' in p:
  272. items.append(p['name'])
  273. if not items:
  274. GError(parent = self.parent,
  275. message = _("No relevant option found.\n"
  276. "Unable to add relation."))
  277. return items
  278. def GetOption(self):
  279. """!Get selected option"""
  280. return self.option.GetStringSelection()
  281. def IsValid(self):
  282. """!Check if relation is valid"""
  283. return self.valid
  284. def OnOption(self, event):
  285. """!Set option"""
  286. if event.GetString():
  287. self.btnOk.Enable()
  288. else:
  289. self.btnOk.Enable(False)
  290. class ModelParamDialog(wx.Dialog):
  291. def __init__(self, parent, params, id = wx.ID_ANY, title = _("Model parameters"),
  292. style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
  293. """!Model parameters dialog
  294. """
  295. self.parent = parent
  296. self.params = params
  297. self.tasks = list() # list of tasks/pages
  298. wx.Dialog.__init__(self, parent = parent, id = id, title = title, style = style, **kwargs)
  299. self.notebook = GNotebook(parent = self,
  300. style = globalvar.FNPageDStyle)
  301. panel = self._createPages()
  302. wx.CallAfter(self.notebook.SetSelection, 0)
  303. self.btnCancel = wx.Button(parent = self, id = wx.ID_CANCEL)
  304. self.btnRun = wx.Button(parent = self, id = wx.ID_OK,
  305. label = _("&Run"))
  306. self.btnRun.SetDefault()
  307. self._layout()
  308. size = self.GetBestSize()
  309. self.SetMinSize(size)
  310. self.SetSize((size.width, size.height +
  311. panel.constrained_size[1] -
  312. panel.panelMinHeight))
  313. def _layout(self):
  314. btnSizer = wx.StdDialogButtonSizer()
  315. btnSizer.AddButton(self.btnCancel)
  316. btnSizer.AddButton(self.btnRun)
  317. btnSizer.Realize()
  318. mainSizer = wx.BoxSizer(wx.VERTICAL)
  319. mainSizer.Add(item = self.notebook, proportion = 1,
  320. flag = wx.EXPAND)
  321. mainSizer.Add(item = btnSizer, proportion = 0,
  322. flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
  323. self.SetSizer(mainSizer)
  324. mainSizer.Fit(self)
  325. def _createPages(self):
  326. """!Create for each parameterized module its own page"""
  327. nameOrdered = [''] * len(self.params.keys())
  328. for name, params in self.params.iteritems():
  329. nameOrdered[params['idx']] = name
  330. for name in nameOrdered:
  331. params = self.params[name]
  332. panel = self._createPage(name, params)
  333. if name == 'variables':
  334. name = _('Variables')
  335. self.notebook.AddPage(page = panel, text = name)
  336. return panel
  337. def _createPage(self, name, params):
  338. """!Define notebook page"""
  339. if name in globalvar.grassCmd['all']:
  340. task = gtask.grassTask(name)
  341. else:
  342. task = gtask.grassTask()
  343. task.flags = params['flags']
  344. task.params = params['params']
  345. panel = menuform.cmdPanel(parent = self, id = wx.ID_ANY, task = task)
  346. self.tasks.append(task)
  347. return panel
  348. def GetErrors(self):
  349. """!Check for errors, get list of messages"""
  350. errList = list()
  351. for task in self.tasks:
  352. errList += task.get_cmd_error()
  353. return errList
  354. class ModelItemDialog(wx.Dialog):
  355. """!Abstract item properties dialog"""
  356. def __init__(self, parent, shape, title, id = wx.ID_ANY,
  357. style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
  358. self.parent = parent
  359. self.shape = shape
  360. wx.Dialog.__init__(self, parent, id, title = title, style = style, **kwargs)
  361. self.panel = wx.Panel(parent = self, id = wx.ID_ANY)
  362. self.condBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
  363. label=" %s " % _("Condition"))
  364. self.condText = wx.TextCtrl(parent = self.panel, id = wx.ID_ANY,
  365. value = shape.GetText())
  366. self.itemList = ItemCheckListCtrl(parent = self.panel,
  367. window = self,
  368. columns = [_("ID"), _("Name"),
  369. _("Command")],
  370. shape = shape)
  371. self.itemList.Populate(self.parent.GetModel().GetItems())
  372. self.btnCancel = wx.Button(parent = self.panel, id = wx.ID_CANCEL)
  373. self.btnOk = wx.Button(parent = self.panel, id = wx.ID_OK)
  374. self.btnOk.SetDefault()
  375. def _layout(self):
  376. """!Do layout (virtual method)"""
  377. pass
  378. def GetCondition(self):
  379. """!Get loop condition"""
  380. return self.condText.GetValue()
  381. class ModelLoopDialog(ModelItemDialog):
  382. """!Loop properties dialog"""
  383. def __init__(self, parent, shape, id = wx.ID_ANY, title = _("Loop properties"),
  384. style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
  385. ModelItemDialog.__init__(self, parent, shape, title,
  386. style = style, **kwargs)
  387. self.listBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
  388. label=" %s " % _("List of items in loop"))
  389. self.btnSeries = wx.Button(parent = self.panel, id = wx.ID_ANY,
  390. label = _("Series"))
  391. self.btnSeries.SetToolTipString(_("Define map series as condition for the loop"))
  392. self.btnSeries.Bind(wx.EVT_BUTTON, self.OnSeries)
  393. self._layout()
  394. self.SetMinSize(self.GetSize())
  395. self.SetSize((500, 400))
  396. def _layout(self):
  397. """!Do layout"""
  398. sizer = wx.BoxSizer(wx.VERTICAL)
  399. condSizer = wx.StaticBoxSizer(self.condBox, wx.HORIZONTAL)
  400. condSizer.Add(item = self.condText, proportion = 1,
  401. flag = wx.ALL, border = 3)
  402. condSizer.Add(item = self.btnSeries, proportion = 0,
  403. flag = wx.EXPAND)
  404. listSizer = wx.StaticBoxSizer(self.listBox, wx.VERTICAL)
  405. listSizer.Add(item = self.itemList, proportion = 1,
  406. flag = wx.EXPAND | wx.ALL, border = 3)
  407. btnSizer = wx.StdDialogButtonSizer()
  408. btnSizer.AddButton(self.btnCancel)
  409. btnSizer.AddButton(self.btnOk)
  410. btnSizer.Realize()
  411. sizer.Add(item = condSizer, proportion = 0,
  412. flag = wx.EXPAND | wx.ALL, border = 3)
  413. sizer.Add(item = listSizer, proportion = 1,
  414. flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border = 3)
  415. sizer.Add(item = btnSizer, proportion=0,
  416. flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
  417. self.panel.SetSizer(sizer)
  418. sizer.Fit(self.panel)
  419. self.Layout()
  420. def GetItems(self):
  421. """!Get list of selected actions"""
  422. return self.itemList.GetItems()
  423. def OnSeries(self, event):
  424. """!Define map series as condition"""
  425. dialog = MapLayersDialog(parent = self, title = _("Define series of maps"), modeler = True)
  426. if dialog.ShowModal() != wx.ID_OK:
  427. dialog.Destroy()
  428. return
  429. cond = dialog.GetDSeries()
  430. if not cond:
  431. cond = 'map in %s' % map(lambda x: str(x), dialog.GetMapLayers())
  432. self.condText.SetValue(cond)
  433. dialog.Destroy()
  434. class ModelConditionDialog(ModelItemDialog):
  435. """!Condition properties dialog"""
  436. def __init__(self, parent, shape, id = wx.ID_ANY, title = _("If-else properties"),
  437. style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
  438. ModelItemDialog.__init__(self, parent, shape, title,
  439. style = style, **kwargs)
  440. self.listBoxIf = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
  441. label=" %s " % _("List of items in 'if' block"))
  442. self.itemListIf = self.itemList
  443. self.itemListIf.SetName('IfBlockList')
  444. self.listBoxElse = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
  445. label=" %s " % _("List of items in 'else' block"))
  446. self.itemListElse = ItemCheckListCtrl(parent = self.panel,
  447. window = self,
  448. columns = [_("ID"), _("Name"),
  449. _("Command")],
  450. shape = shape)
  451. self.itemListElse.SetName('ElseBlockList')
  452. self.itemListElse.Populate(self.parent.GetModel().GetItems())
  453. self._layout()
  454. self.SetMinSize(self.GetSize())
  455. self.SetSize((500, 400))
  456. def _layout(self):
  457. """!Do layout"""
  458. sizer = wx.BoxSizer(wx.VERTICAL)
  459. condSizer = wx.StaticBoxSizer(self.condBox, wx.VERTICAL)
  460. condSizer.Add(item = self.condText, proportion = 1,
  461. flag = wx.EXPAND)
  462. listIfSizer = wx.StaticBoxSizer(self.listBoxIf, wx.VERTICAL)
  463. listIfSizer.Add(item = self.itemListIf, proportion = 1,
  464. flag = wx.EXPAND)
  465. listElseSizer = wx.StaticBoxSizer(self.listBoxElse, wx.VERTICAL)
  466. listElseSizer.Add(item = self.itemListElse, proportion = 1,
  467. flag = wx.EXPAND)
  468. btnSizer = wx.StdDialogButtonSizer()
  469. btnSizer.AddButton(self.btnCancel)
  470. btnSizer.AddButton(self.btnOk)
  471. btnSizer.Realize()
  472. sizer.Add(item = condSizer, proportion = 0,
  473. flag = wx.EXPAND | wx.ALL, border = 3)
  474. sizer.Add(item = listIfSizer, proportion = 1,
  475. flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border = 3)
  476. sizer.Add(item = listElseSizer, proportion = 1,
  477. flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border = 3)
  478. sizer.Add(item = btnSizer, proportion=0,
  479. flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
  480. self.panel.SetSizer(sizer)
  481. sizer.Fit(self.panel)
  482. self.Layout()
  483. def OnCheckItemIf(self, index, flag):
  484. """!Item in if-block checked/unchecked"""
  485. if flag is False:
  486. return
  487. aId = int(self.itemListIf.GetItem(index, 0).GetText())
  488. if aId in self.itemListElse.GetItems()['checked']:
  489. self.itemListElse.CheckItemById(aId, False)
  490. def OnCheckItemElse(self, index, flag):
  491. """!Item in else-block checked/unchecked"""
  492. if flag is False:
  493. return
  494. aId = int(self.itemListElse.GetItem(index, 0).GetText())
  495. if aId in self.itemListIf.GetItems()['checked']:
  496. self.itemListIf.CheckItemById(aId, False)
  497. def GetItems(self):
  498. """!Get items"""
  499. return { 'if' : self.itemListIf.GetItems(),
  500. 'else' : self.itemListElse.GetItems() }