widgets.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699
  1. """
  2. @package vnet.widgets
  3. @brief Base class for list of points.
  4. Classes:
  5. - widgets::PointsList
  6. - widgets::EditItem
  7. (C) 2012 by the GRASS Development Team
  8. This program is free software under the GNU General Public License
  9. (>=v2). Read the file COPYING that comes with GRASS for details.
  10. @author Original author Michael Barton
  11. @author Original version improved by Martin Landa <landa.martin gmail.com>
  12. @author Rewritten by Markus Metz redesign georectfier -> GCP Manage
  13. @author Stepan Turek <stepan.turek seznam.cz> (Created PointsList from GCPList) (GSoC 2012, mentor: Martin Landa)
  14. """
  15. import os
  16. import sys
  17. import six
  18. from copy import copy, deepcopy
  19. import wx
  20. from wx.lib.mixins.listctrl import ColumnSorterMixin, ListCtrlAutoWidthMixin
  21. from core import globalvar
  22. from core.gcmd import GError
  23. from gui_core.widgets import FloatValidator, IntegerValidator
  24. from gui_core.wrap import (
  25. BitmapFromImage,
  26. Button,
  27. ComboBox,
  28. ListCtrl,
  29. Panel,
  30. StaticBox,
  31. StaticText,
  32. TextCtrl,
  33. CheckListCtrlMixin,
  34. )
  35. if sys.version_info.major >= 3:
  36. basestring = str
  37. class PointsList(
  38. ListCtrl, CheckListCtrlMixin, ListCtrlAutoWidthMixin, ColumnSorterMixin
  39. ):
  40. def __init__(
  41. self,
  42. parent,
  43. cols,
  44. id=wx.ID_ANY,
  45. pos=wx.DefaultPosition,
  46. size=wx.DefaultSize,
  47. style=wx.LC_REPORT | wx.SUNKEN_BORDER | wx.LC_HRULES | wx.LC_SINGLE_SEL,
  48. ):
  49. """Creates list for points.
  50. PointsList class was created from GCPList class in GCP manager. It is possible
  51. to be shared by GCP and VNET front end.
  52. Important parameters:
  53. :param cols: is list containing list items. which represents columns.
  54. This columns will be added in order as they are in list.
  55. Class will add as first column "use" with number of point and checkbox.
  56. Structure of list item must be this:
  57. -1. item: column name
  58. -2. item: column label
  59. -3. item: If column is editable by user, it must contain convert function to convert
  60. inserted string to it's type for sorting. Use None for not editable
  61. columns. Values for insertion can be in list. This allows insert
  62. just values in the list.
  63. -4. item: Default value for column cell. Value should be given in it's type
  64. in order to sorting would work properly. If 3. item is list, it must be index
  65. of some item in the list.
  66. Example of cols parameter:
  67. column name, column label, convert function, default val
  68. @code
  69. cols = [
  70. ['E', _('source E'), float, 0.0],
  71. ['N', _('source N'), float, 0.0],
  72. ['E', _('target E'), float, 0.0],
  73. ['N', _('target N'), float, 0.0],
  74. ['F_Err', _('Forward error'), None, 0],
  75. ['B_Err', _(Backward error'), None, 0]
  76. ['type', _('type'), [_(""), _("Start point"), _("End point")], 0] # Select from 3 choices ("Start point", "End point"),
  77. # Choice with index 0 ("") is default.
  78. ]
  79. @endcode
  80. """
  81. ListCtrl.__init__(self, parent, id, pos, size, style)
  82. # Mixin settings
  83. CheckListCtrlMixin.__init__(self)
  84. ListCtrlAutoWidthMixin.__init__(self)
  85. # TextEditMixin.__init__(self)
  86. # inserts first column with points numbers and checkboxes
  87. cols.insert(0, ["use", _("use"), False, 0])
  88. self.colsData = cols
  89. self.dataTypes = {
  90. "colName": 0,
  91. "colLabel": 1,
  92. "colEditable": 2,
  93. "itemDefaultValue": 3,
  94. } # just for better understanding
  95. # information whether list items are checked or not
  96. self.CheckList = []
  97. self._createCols()
  98. self.hiddenCols = {}
  99. self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected)
  100. self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated)
  101. self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick)
  102. self.selected = wx.NOT_FOUND
  103. self.selectedkey = -1
  104. # CheckListCtrlMixin must set an ImageList first
  105. self.il = self.GetImageList(wx.IMAGE_LIST_SMALL)
  106. # images for column sorting
  107. SmallUpArrow = BitmapFromImage(self.getSmallUpArrowImage())
  108. SmallDnArrow = BitmapFromImage(self.getSmallDnArrowImage())
  109. self.sm_dn = self.il.Add(SmallDnArrow)
  110. self.sm_up = self.il.Add(SmallUpArrow)
  111. # initialize column sorter
  112. self.itemDataMap = []
  113. ncols = self.GetColumnCount()
  114. ColumnSorterMixin.__init__(self, ncols)
  115. # init to ascending sort on first click
  116. self._colSortFlag = [1] * ncols
  117. # same structure as itemDataMap, information about choice index selected
  118. # if cell is in column without values to choose then is -1
  119. self.selIdxs = []
  120. self.ResizeColumns()
  121. self.SetColumnWidth(0, 50)
  122. def _createCols(self):
  123. """Creates columns in list"""
  124. if 0:
  125. # normal, simple columns
  126. for col in enumerate(self.colsData):
  127. iLabel = self.dataTypes["colLabel"]
  128. self.InsertColumn(col[0], col[1][iLabel])
  129. else:
  130. # the hard way: we want images on the column header
  131. info = wx.ListItem()
  132. info.SetMask(wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT)
  133. info.SetImage(-1)
  134. if globalvar.wxPythonPhoenix:
  135. info.Format = wx.LIST_FORMAT_LEFT
  136. else:
  137. info.m_format = wx.LIST_FORMAT_LEFT
  138. for col in enumerate(self.colsData):
  139. iLabel = self.dataTypes["colLabel"]
  140. info.SetText(col[1][iLabel])
  141. if globalvar.wxPythonPhoenix:
  142. self.InsertColumn(col[0], info)
  143. else:
  144. self.InsertColumnInfo(col[0], info)
  145. def AddItem(self):
  146. """Appends an item to list with default values"""
  147. iDefVal = self.dataTypes["itemDefaultValue"]
  148. iColEd = self.dataTypes["colEditable"]
  149. itemData = []
  150. itemIndexes = []
  151. for col in self.colsData:
  152. if type(col[iColEd]).__name__ == "list":
  153. itemData.append(col[iColEd][col[iDefVal]])
  154. itemIndexes.append(col[iDefVal])
  155. else:
  156. itemData.append(col[iDefVal])
  157. itemIndexes.append(-1) # not a choise column
  158. self.selIdxs.append(itemIndexes)
  159. for hCol in six.itervalues(self.hiddenCols):
  160. defVal = hCol["colsData"][iDefVal]
  161. if type(hCol["colsData"][iColEd]).__name__ == "list":
  162. hCol["itemDataMap"].append(hCol["colsData"][iColEd][defVal])
  163. hCol["selIdxs"].append(defVal)
  164. else:
  165. hCol["itemDataMap"].append(defVal)
  166. hCol["selIdxs"].append(-1)
  167. self.selectedkey = self.GetItemCount()
  168. itemData[0] = self.selectedkey + 1
  169. self.itemDataMap.append(copy(itemData))
  170. self.Append(list(map(str, itemData)))
  171. self.selected = self.GetItemCount() - 1
  172. self.SetItemData(self.selected, self.selectedkey)
  173. self.SetItemState(self.selected, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED)
  174. self.ResizeColumns()
  175. return self.selected
  176. def GetCellValue(self, key, colName):
  177. """Get value in cell of list using key (same regardless of sorting)"""
  178. colNum = self._getColumnNum(colName)
  179. if colNum < 0:
  180. return None
  181. iColEd = self.dataTypes["colEditable"]
  182. if self.selIdxs[key][colNum] != -1:
  183. return self.selIdxs[key][colNum]
  184. return self.itemDataMap[key][colNum]
  185. def GetCellSelIdx(self, key, colName):
  186. """Get selected index in cell of list using key (same regardless of sorting)
  187. :return: number of chosen value, if column has values to choose
  188. :return: -1 if column does not has values to choose
  189. """
  190. colNum = self._getColumnNum(colName)
  191. iColEd = self.dataTypes["colEditable"]
  192. return self.selIdxs[key][colNum]
  193. def EditCellIndex(self, index, colName, cellData):
  194. """Changes value in list using key (same regardless of sorting)"""
  195. colNum = self._getColumnNum(colName)
  196. key = self.GetItemData(index)
  197. iColEd = self.dataTypes["colEditable"]
  198. if type(self.colsData[colNum][iColEd]).__name__ == "list":
  199. cellVal = self.colsData[colNum][iColEd][cellData]
  200. self.selIdxs[key][colNum] = cellData
  201. else:
  202. cellVal = cellData
  203. self.selIdxs[key][colNum] = -1
  204. self.itemDataMap[key][colNum] = cellVal
  205. if not isinstance(cellVal, basestring):
  206. cellVal = str(cellVal)
  207. self.SetItem(index, colNum, cellVal)
  208. def EditCellKey(self, key, colName, cellData):
  209. """Changes value in list using index (changes during sorting)"""
  210. colNum = self._getColumnNum(colName)
  211. iColEd = self.dataTypes["colEditable"]
  212. if type(self.colsData[colNum][iColEd]).__name__ == "list":
  213. cellVal = self.colsData[colNum][iColEd][cellData]
  214. self.selIdxs[key][colNum] = cellData
  215. else:
  216. cellVal = cellData
  217. self.selIdxs[key][colNum] = -1
  218. self.itemDataMap[key][colNum] = cellVal
  219. index = self._findIndex(key)
  220. if index != -1:
  221. if not isinstance(cellVal, basestring):
  222. cellVal = str(cellVal)
  223. self.SetItem(index, colNum, cellVal)
  224. def _findIndex(self, key):
  225. """Find index for key"""
  226. index = -1
  227. while True:
  228. index = self.GetNextItem(index, wx.LIST_NEXT_BELOW)
  229. if key == self.GetItemData(index):
  230. return index
  231. if index == -1:
  232. break
  233. return -1
  234. def ChangeColEditable(self, colName, colType):
  235. """Change 3. item in constructor parameter cols (see the class constructor hint)"""
  236. colNum = self._getColumnNum(colName)
  237. iColEd = self.dataTypes["colEditable"]
  238. self.colsData[colNum][iColEd] = colType
  239. def DeleteItem(self):
  240. """Delete selected item in list"""
  241. if self.selected == wx.NOT_FOUND:
  242. return
  243. key = self.GetItemData(self.selected)
  244. ListCtrl.DeleteItem(self, self.selected)
  245. del self.itemDataMap[key]
  246. self.selIdxs.pop(key)
  247. # update hidden columns
  248. for hCol in six.itervalues(self.hiddenCols):
  249. hCol["itemDataMap"].pop(key)
  250. hCol["selIdxs"].pop(key)
  251. # update key and point number
  252. for newkey in range(key, len(self.itemDataMap)):
  253. index = self.FindItem(-1, newkey + 1)
  254. self.itemDataMap[newkey][0] = newkey
  255. self.SetItem(index, 0, str(newkey + 1))
  256. self.SetItemData(index, newkey)
  257. # update selected
  258. if self.GetItemCount() > 0:
  259. if self.selected < self.GetItemCount():
  260. self.selectedkey = self.GetItemData(self.selected)
  261. else:
  262. self.selected = self.GetItemCount() - 1
  263. self.selectedkey = self.GetItemData(self.selected)
  264. self.SetItemState(
  265. self.selected, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED
  266. )
  267. else:
  268. self.selected = wx.NOT_FOUND
  269. self.selectedkey = -1
  270. def ClearItem(self, event):
  271. """Set all values to default in selected item of points list and uncheck it."""
  272. if self.selected == wx.NOT_FOUND:
  273. return
  274. index = self.selected
  275. iDefVal = self.dataTypes["itemDefaultValue"]
  276. iColEd = self.dataTypes["colEditable"]
  277. i = 0
  278. for col in self.colsData:
  279. if i == 0:
  280. i += 1
  281. continue
  282. if type(col[iColEd]).__name__ == "list":
  283. self.EditCell(index, i, col[iColEd][col[iDefVal]])
  284. else:
  285. self.EditCell(index, i, col[iDefVal])
  286. i += 1
  287. self.CheckItem(index, False)
  288. def ResizeColumns(self, minWidth=[90, 120]):
  289. """Resize columns"""
  290. for i in range(self.GetColumnCount()):
  291. self.SetColumnWidth(i, wx.LIST_AUTOSIZE)
  292. # first column is checkbox, don't set to minWidth
  293. if i > 0 and self.GetColumnWidth(i) < minWidth[i > 4]:
  294. self.SetColumnWidth(i, minWidth[i > 4])
  295. self.SendSizeEvent()
  296. def GetSelected(self):
  297. """Get index of selected item."""
  298. return self.selected
  299. # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
  300. def GetSortImages(self):
  301. return (self.sm_dn, self.sm_up)
  302. # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
  303. def GetListCtrl(self):
  304. return self
  305. def OnItemActivated(self, event):
  306. """When item is double clicked, open editor to edit editable columns."""
  307. data = []
  308. index = event.GetIndex()
  309. key = self.GetItemData(index)
  310. changed = False
  311. iColEd = self.dataTypes["colEditable"]
  312. for col in enumerate(self.colsData):
  313. if col[1][iColEd]:
  314. data.append(
  315. [
  316. col[0], # culumn number
  317. self.GetItem(index, col[0]).GetText(), # cell value
  318. col[1][iColEd],
  319. ]
  320. ) # convert function for type check
  321. if not data:
  322. return
  323. dlg = self.CreateEditDialog(data=data, pointNo=key)
  324. if dlg.ShowModal() == wx.ID_OK:
  325. editedData = dlg.GetValues() # string
  326. if len(editedData) == 0:
  327. GError(
  328. parent=self,
  329. message=_("Invalid value inserted. Operation canceled."),
  330. )
  331. else:
  332. i = 0
  333. for editedCell in editedData:
  334. if editedCell[1] != data[i][1]:
  335. value = editedCell[1]
  336. if not isinstance(editedCell[1], basestring):
  337. value = str(editedCell[1])
  338. self.SetItem(index, editedCell[0], value)
  339. self.itemDataMap[key][editedCell[0]] = editedCell[1]
  340. changed = True
  341. i += 1
  342. self.selIdxs[key] = dlg.GetSelectionIndexes()
  343. dlg.Destroy()
  344. return changed, key
  345. def CreateEditDialog(self, data, pointNo):
  346. """Helper function
  347. It is possible to define in child derived class
  348. and adapt created dialog (e. g. it's title...)
  349. """
  350. return EditItem(parent=self, id=wx.ID_ANY, data=data, pointNo=pointNo)
  351. def OnColClick(self, event):
  352. """ListCtrl forgets selected item..."""
  353. self.selected = self.FindItem(-1, self.selectedkey)
  354. self.SetItemState(self.selected, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED)
  355. event.Skip()
  356. def OnItemSelected(self, event):
  357. """Updates class attributes holding information about selected item"""
  358. if self.selected != event.GetIndex():
  359. self.selected = event.GetIndex()
  360. self.selectedkey = self.GetItemData(self.selected)
  361. event.Skip()
  362. def getSmallUpArrowImage(self):
  363. """Get arrow up symbol for indication of sorting"""
  364. stream = open(os.path.join(globalvar.IMGDIR, "small_up_arrow.png"), "rb")
  365. try:
  366. img = wx.Image(stream)
  367. finally:
  368. stream.close()
  369. return img
  370. def getSmallDnArrowImage(self):
  371. """Get arrow down symbol for indication of sorting"""
  372. stream = open(os.path.join(globalvar.IMGDIR, "small_down_arrow.png"), "rb")
  373. try:
  374. img = wx.Image(stream)
  375. finally:
  376. stream.close()
  377. return img
  378. def _getColumnNum(self, colName):
  379. """Get position of column among showed columns
  380. :param colName: name of column
  381. :type colName: str
  382. :return: index of columns or -1 if col was not found
  383. """
  384. for iCol, col in enumerate(self.colsData):
  385. if colName == col[0]:
  386. return iCol
  387. return -1
  388. def HideColumn(self, colName):
  389. """Hide column (hidden columns are not editable)
  390. :param colName: name of column
  391. :type colName: str
  392. :return: True - if column was hidden
  393. :return: False - if position is not valid or column is not showed
  394. """
  395. colNum = self._getColumnNum(colName)
  396. if colNum == -1:
  397. return False
  398. hiddenCol = self.GetColumn(colNum)
  399. self.DeleteColumn(colNum)
  400. self.hiddenCols[colName] = {}
  401. self.hiddenCols[colName]["wxCol"] = hiddenCol
  402. hiddenMaps = []
  403. hiddenSelIdxs = []
  404. for item in self.itemDataMap:
  405. hiddenMaps.append(item.pop(colNum))
  406. for item in self.selIdxs:
  407. hiddenSelIdxs.append(item.pop(colNum))
  408. self.hiddenCols[colName]["itemDataMap"] = hiddenMaps
  409. self.hiddenCols[colName]["selIdxs"] = hiddenSelIdxs
  410. self.hiddenCols[colName]["colsData"] = self.colsData.pop(colNum)
  411. self.ResizeColumns()
  412. return True
  413. def ShowColumn(self, colName, pos):
  414. """Show column
  415. :param colName: name of column
  416. :type colName: str
  417. :param pos: zero based index of position among showed columns (including added 'use' column)
  418. :return: True if column was shown
  419. :return: False if position is not valid or column is not hidden
  420. """
  421. if pos < 0 and pos >= self.self.GetColumnCount():
  422. return False
  423. if colName in self.hiddenCols:
  424. col = self.hiddenCols[colName]
  425. for item in enumerate(self.itemDataMap):
  426. item[1].insert(pos, col["itemDataMap"][item[0]])
  427. for item in enumerate(self.selIdxs):
  428. item[1].insert(pos, col["selIdxs"][item[0]])
  429. self.colsData.insert(pos, col["colsData"])
  430. self.InsertColumnItem(pos, col["wxCol"])
  431. self.ResizeColumns()
  432. del self.hiddenCols[colName]
  433. return True
  434. return False
  435. def IsShown(self, colName):
  436. """Is column shown
  437. :param colName: name of column
  438. :type colName: str
  439. :return: True - if is shown
  440. :return: False - if is not shown
  441. """
  442. if self._getColumnNum(colName) == -1:
  443. return False
  444. else:
  445. return True
  446. class EditItem(wx.Dialog):
  447. def __init__(
  448. self,
  449. parent,
  450. data,
  451. pointNo,
  452. itemCap="Point No.",
  453. id=wx.ID_ANY,
  454. title=_("Edit point"),
  455. style=wx.DEFAULT_DIALOG_STYLE,
  456. ):
  457. """Dialog for editing item cells in list"""
  458. wx.Dialog.__init__(self, parent, id, title=_(title), style=style)
  459. self.parent = parent
  460. panel = Panel(parent=self)
  461. sizer = wx.BoxSizer(wx.VERTICAL)
  462. box = StaticBox(
  463. parent=panel, id=wx.ID_ANY, label=" %s %s " % (_(itemCap), str(pointNo + 1))
  464. )
  465. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  466. # source coordinates
  467. gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
  468. self.fields = []
  469. self.data = deepcopy(data)
  470. col = 0
  471. row = 0
  472. iField = 0
  473. for cell in self.data:
  474. # Select
  475. if type(cell[2]).__name__ == "list":
  476. self.fields.append(
  477. ComboBox(
  478. parent=panel,
  479. id=wx.ID_ANY,
  480. choices=cell[2],
  481. style=wx.CB_READONLY,
  482. size=(110, -1),
  483. )
  484. )
  485. # Text field
  486. else:
  487. if cell[2] == float:
  488. validator = FloatValidator()
  489. elif cell[2] == int:
  490. validator = IntegerValidator()
  491. else:
  492. validator = None
  493. if validator:
  494. self.fields.append(
  495. TextCtrl(
  496. parent=panel,
  497. id=wx.ID_ANY,
  498. validator=validator,
  499. size=(150, -1),
  500. )
  501. )
  502. else:
  503. self.fields.append(
  504. TextCtrl(parent=panel, id=wx.ID_ANY, size=(150, -1))
  505. )
  506. value = cell[1]
  507. if not isinstance(cell[1], basestring):
  508. value = str(cell[1])
  509. self.fields[iField].SetValue(value)
  510. label = StaticText(
  511. parent=panel,
  512. id=wx.ID_ANY,
  513. label=_(parent.GetColumn(cell[0]).GetText()) + ":",
  514. ) # name of column)
  515. gridSizer.Add(label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, col))
  516. col += 1
  517. gridSizer.Add(self.fields[iField], pos=(row, col))
  518. if col % 3 == 0:
  519. col = 0
  520. row += 1
  521. else:
  522. col += 1
  523. iField += 1
  524. boxSizer.Add(gridSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  525. sizer.Add(boxSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  526. #
  527. # buttons
  528. #
  529. self.btnCancel = Button(panel, wx.ID_CANCEL)
  530. self.btnOk = Button(panel, wx.ID_OK)
  531. self.btnOk.SetDefault()
  532. btnSizer = wx.StdDialogButtonSizer()
  533. btnSizer.AddButton(self.btnCancel)
  534. btnSizer.AddButton(self.btnOk)
  535. btnSizer.Realize()
  536. sizer.Add(btnSizer, proportion=0, flag=wx.ALIGN_RIGHT | wx.ALL, border=5)
  537. panel.SetSizer(sizer)
  538. sizer.Fit(self)
  539. def GetValues(self):
  540. """Return list of values (as strings)."""
  541. iField = 0
  542. for cell in self.data:
  543. value = self.fields[iField].GetValue()
  544. if type(cell[2]).__name__ == "list":
  545. cell[1] = value
  546. else:
  547. try:
  548. cell[1] = cell[2](value)
  549. except ValueError:
  550. return []
  551. iField += 1
  552. return self.data
  553. def GetSelectionIndexes(self):
  554. """Return indexes of selected values (works just for choice
  555. columns).
  556. """
  557. iField = 0
  558. itemIndexes = []
  559. for cell in self.parent.colsData:
  560. if type(cell[2]).__name__ == "list":
  561. itemIndexes.append(self.fields[iField].GetSelection())
  562. else:
  563. itemIndexes.append(-1) # not a choise column
  564. if cell[2]:
  565. iField += 1
  566. return itemIndexes