[GRASS-SVN] r58144 - grass/trunk/gui/wxpython/gmodeler
svn_grass at osgeo.org
svn_grass at osgeo.org
Sun Nov 3 11:16:24 PST 2013
Author: martinl
Date: 2013-11-03 11:16:23 -0800 (Sun, 03 Nov 2013)
New Revision: 58144
Modified:
grass/trunk/gui/wxpython/gmodeler/dialogs.py
grass/trunk/gui/wxpython/gmodeler/frame.py
grass/trunk/gui/wxpython/gmodeler/model.py
Log:
wxGUI/modeler: implement reordering items (work in progress)
Modified: grass/trunk/gui/wxpython/gmodeler/dialogs.py
===================================================================
--- grass/trunk/gui/wxpython/gmodeler/dialogs.py 2013-11-03 01:07:59 UTC (rev 58143)
+++ grass/trunk/gui/wxpython/gmodeler/dialogs.py 2013-11-03 19:16:23 UTC (rev 58144)
@@ -409,7 +409,7 @@
self.itemList = ItemCheckListCtrl(parent = self.panel,
window = self,
- columns = [_("ID"), _("Name"),
+ columns = [_("Name"),
_("Command")],
shape = shape)
self.itemList.Populate(self.parent.GetModel().GetItems())
@@ -511,7 +511,7 @@
label=" %s " % _("List of items in 'else' block"))
self.itemListElse = ItemCheckListCtrl(parent = self.panel,
window = self,
- columns = [_("ID"), _("Name"),
+ columns = [_("Name"),
_("Command")],
shape = shape)
self.itemListElse.SetName('ElseBlockList')
@@ -580,7 +580,7 @@
class ModelListCtrl(wx.ListCtrl,
listmix.ListCtrlAutoWidthMixin,
- listmix.TextEditMixin,
+# listmix.TextEditMixin,
listmix.ColumnSorterMixin):
def __init__(self, parent, columns, id = wx.ID_ANY,
style = wx.LC_REPORT | wx.BORDER_NONE |
@@ -597,7 +597,7 @@
wx.ListCtrl.__init__(self, parent, id = id, style = style, **kwargs)
listmix.ListCtrlAutoWidthMixin.__init__(self)
- listmix.TextEditMixin.__init__(self)
+# listmix.TextEditMixin.__init__(self)
listmix.ColumnSorterMixin.__init__(self, 4)
i = 0
@@ -787,16 +787,15 @@
shapeItems = list()
i = 0
- if len(self.columns) == 3: # ItemCheckList
+ if len(self.columns) == 2: # ItemCheckList
checked = list()
for action in data:
if isinstance(action, ModelData) or \
action == self.shape:
continue
- if len(self.columns) == 3:
- self.itemDataMap[i] = [str(action.GetId()),
- action.GetName(),
+ if len(self.columns) == 2:
+ self.itemDataMap[i] = [action.GetName(),
action.GetLog()]
aId = action.GetBlockId()
if action.GetId() in shapeItems:
@@ -807,8 +806,7 @@
bId = action.GetBlockId()
if not bId:
bId = ''
- self.itemDataMap[i] = [str(action.GetId()),
- action.GetName(),
+ self.itemDataMap[i] = [action.GetName(),
','.join(map(str, bId)),
action.GetLog()]
@@ -817,23 +815,21 @@
self.itemCount = len(self.itemDataMap.keys())
self.DeleteAllItems()
i = 0
- if len(self.columns) == 3:
- for aid, name, desc in self.itemDataMap.itervalues():
- index = self.InsertStringItem(sys.maxint, aid)
- self.SetStringItem(index, 0, aid)
- self.SetStringItem(index, 1, name)
- self.SetStringItem(index, 2, desc)
+ if len(self.columns) == 2:
+ for name, desc in self.itemDataMap.itervalues():
+ index = self.InsertStringItem(sys.maxint, str(i))
+ self.SetStringItem(index, 0, name)
+ self.SetStringItem(index, 1, desc)
self.SetItemData(index, i)
if checked[i]:
self.CheckItem(index, True)
i += 1
else:
- for aid, name, inloop, desc in self.itemDataMap.itervalues():
- index = self.InsertStringItem(sys.maxint, aid)
- self.SetStringItem(index, 0, aid)
- self.SetStringItem(index, 1, name)
- self.SetStringItem(index, 2, inloop)
- self.SetStringItem(index, 3, desc)
+ for name, inloop, desc in self.itemDataMap.itervalues():
+ index = self.InsertStringItem(sys.maxint, str(i))
+ self.SetStringItem(index, 0, name)
+ self.SetStringItem(index, 1, inloop)
+ self.SetStringItem(index, 2, desc)
self.SetItemData(index, i)
i += 1
@@ -847,14 +843,12 @@
self.DeleteItem(item)
del self.itemDataMap[item]
- aId = self.GetItem(item, 0).GetText()
- action = model.GetItem(int(aId))
+ action = model.GetItem(item+1) # action indeces starts at 1
if not action:
item = self.GetFirstSelected()
continue
- model.RemoveItem(action)
- canvas.GetDiagram().RemoveShape(action)
+ canvas.RemoveShapes([action])
self.frame.ModelChanged()
item = self.GetFirstSelected()
@@ -863,22 +857,6 @@
event.Skip()
- def OnRemoveAll(self, event):
- """!Remove all variable(s) from the model"""
- deleteDialog = wx.MessageBox(parent=self,
- message=_("Selected data records (%d) will permanently deleted "
- "from table. Do you want to delete them?") % \
- (len(self.listOfSQLStatements)),
- caption=_("Delete records"),
- style=wx.YES_NO | wx.CENTRE)
- if deleteDialog != wx.YES:
- return False
-
- self.DeleteAllItems()
- self.itemDataMap = dict()
-
- self.parent.UpdateModelVariables()
-
def OnEndEdit(self, event):
"""!Finish editing of item"""
itemIndex = event.GetIndex()
@@ -886,62 +864,69 @@
self.itemDataMap[itemIndex][columnIndex] = event.GetText()
- aId = int(self.GetItem(itemIndex, 0).GetText())
- action = self.frame.GetModel().GetItem(aId)
+ action = self.frame.GetModel().GetItem(itemIndex)
if not action:
event.Veto()
- if columnIndex == 0:
- action.SetId(int(event.GetText()))
self.frame.ModelChanged()
def OnReload(self, event = None):
"""!Reload list of actions"""
- self.Populate(self.frame.GetModel().GetItems())
+ self.Populate(self.frame.GetModel().GetItems(objType=ModelAction))
def OnRightUp(self, event):
"""!Mouse right button up"""
if self.disablePopup:
return
- if not hasattr(self, "popupID1"):
- self.popupID1 = wx.NewId()
- self.popupID2 = wx.NewId()
- self.popupID3 = wx.NewId()
- self.popupID4 = wx.NewId()
- self.Bind(wx.EVT_MENU, self.OnRemove, id = self.popupID1)
- self.Bind(wx.EVT_MENU, self.OnRemoveAll, id = self.popupID2)
- self.Bind(wx.EVT_MENU, self.OnReload, id = self.popupID3)
- self.Bind(wx.EVT_MENU, self.OnNormalize, id = self.popupID4)
+ if not hasattr(self, "popupId"):
+ self.popupID = dict()
+ self.popupID['remove'] = wx.NewId()
+ self.popupID['reload'] = wx.NewId()
+ self.Bind(wx.EVT_MENU, self.OnRemove, id = self.popupID['remove'])
+ self.Bind(wx.EVT_MENU, self.OnReload, id = self.popupID['reload'])
# generate popup-menu
menu = wx.Menu()
- menu.Append(self.popupID1, _("Delete selected"))
- menu.Append(self.popupID2, _("Delete all"))
+ menu.Append(self.popupID['remove'], _("Delete selected"))
if self.GetFirstSelected() == -1:
- menu.Enable(self.popupID1, False)
- menu.Enable(self.popupID2, False)
-
+ menu.Enable(self.popupID['remove'], False)
menu.AppendSeparator()
- menu.Append(self.popupID4, _("Normalize"))
- menu.Append(self.popupID3, _("Reload"))
+ menu.Append(self.popupID['reload'], _("Reload"))
self.PopupMenu(menu)
menu.Destroy()
- def OnNormalize(self, event):
- """!Update id of actions"""
- model = self.frame.GetModel()
+ def MoveItems(self, items, up):
+ """!Move items in the list
+
+ @param items list of items to move
+ @param up True to move up otherwise down
+ """
+ if len(items) < 1:
+ return
- aId = 1
- for item in model.GetItems():
- item.SetId(aId)
- aId += 1
+ if items[0] == 0 and up:
+ del items[0]
+ if len(items) < 1:
+ return
- self.OnReload(None)
- self.frame.GetCanvas().Refresh()
- self.frame.ModelChanged()
+ if items[-1] == len(self.itemDataMap.keys())-1 and not up:
+ del items[-1]
+ if len(items) < 1:
+ return
+ model = self.frame.GetModel()
+ modelActions = model.GetItems(objType=ModelAction)
+ idxList = dict()
+ for i in items:
+ idxList[model.GetItemIndex(modelActions[i])] = model.GetItemIndex(modelActions[i-1])
+
+ # reorganize model items
+ model.ReorderItems(idxList)
+ model.Normalize()
+ self.Populate(model.GetItems(objType=ModelAction))
+
class ItemCheckListCtrl(ItemListCtrl, listmix.CheckListCtrlMixin):
def __init__(self, parent, shape, columns, window = None, **kwargs):
self.parent = parent
@@ -949,7 +934,7 @@
ItemListCtrl.__init__(self, parent, columns, disablePopup = True, **kwargs)
listmix.CheckListCtrlMixin.__init__(self)
- self.SetColumnWidth(0, 50)
+ self.SetColumnWidth(0, 100)
self.shape = shape
@@ -969,12 +954,12 @@
"""!Get list of selected actions"""
ids = { 'checked' : list(),
'unchecked' : list() }
+ # action ids start at 1
for i in range(self.GetItemCount()):
- iId = int(self.GetItem(i, 0).GetText())
if self.IsChecked(i):
- ids['checked'].append(iId)
+ ids['checked'].append(i+1)
else:
- ids['unchecked'].append(iId)
+ ids['unchecked'].append(i+1)
return ids
Modified: grass/trunk/gui/wxpython/gmodeler/frame.py
===================================================================
--- grass/trunk/gui/wxpython/gmodeler/frame.py 2013-11-03 01:07:59 UTC (rev 58143)
+++ grass/trunk/gui/wxpython/gmodeler/frame.py 2013-11-03 19:16:23 UTC (rev 58144)
@@ -907,7 +907,7 @@
def DefineLoop(self, loop):
"""!Define loop with given list of items"""
parent = loop
- items = loop.GetItems()
+ items = loop.GetItems(self.GetModel().GetItems())
if not items:
return
@@ -928,7 +928,7 @@
parent = item
# close loop
- item = loop.GetItems()[-1]
+ item = items[-1]
rel = ModelRelation(parent = self, fromShape = item, toShape = loop)
loop.AddRelation(rel)
self.AddLine(rel)
@@ -1138,14 +1138,16 @@
dlg.CentreOnParent()
if dlg.ShowModal() == wx.ID_OK:
shape.SetText(dlg.GetCondition())
+ model = self.frame.GetModel()
+ modelActions = model.GetItems(objType=ModelAction)
ids = dlg.GetItems()
for b in ids.keys():
alist = list()
- for aId in ids[b]['unchecked']:
- action = self.frame.GetModel().GetItem(aId)
+ for idx in ids[b]['unchecked']:
+ action = modelActions[idx]
action.UnSetBlock(shape)
- for aId in ids[b]['checked']:
- action = self.frame.GetModel().GetItem(aId)
+ for idx in ids[b]['checked']:
+ action = modelActions[idx]
action.SetBlock(shape)
if action:
alist.append(action)
@@ -1464,9 +1466,15 @@
label=" %s " % _("List of items - right-click to delete"))
self.list = ItemListCtrl(parent = self,
- columns = [_("ID"), _("Name"), _("In block"),
+ columns = [_("Name"), _("In block"),
_("Command / Condition")])
+ self.btnMoveUp = wx.Button(parent=self, id=wx.ID_UP)
+ self.btnMoveDown = wx.Button(parent=self, id=wx.ID_DOWN)
+
+ self.btnMoveUp.Bind(wx.EVT_BUTTON, self.OnMoveItemsUp)
+ self.btnMoveDown.Bind(wx.EVT_BUTTON, self.OnMoveItemsDown)
+
self._layout()
def _layout(self):
@@ -1475,10 +1483,17 @@
listSizer.Add(item = self.list, proportion = 1,
flag = wx.EXPAND)
- mainSizer = wx.BoxSizer(wx.VERTICAL)
+ manageSizer = wx.BoxSizer(wx.VERTICAL)
+ manageSizer.Add(item=self.btnMoveUp, border = 5, flag = wx.ALL)
+ manageSizer.Add(item=self.btnMoveDown, border = 5,
+ flag = wx.LEFT | wx.RIGHT)
+
+ mainSizer = wx.BoxSizer(wx.HORIZONTAL)
mainSizer.Add(item = listSizer, proportion = 1,
- flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
-
+ flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 3)
+ mainSizer.Add(item = manageSizer, proportion = 0,
+ flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 3)
+
self.SetSizer(mainSizer)
mainSizer.Fit(self)
@@ -1486,6 +1501,40 @@
"""!Reload list of variables"""
self.list.OnReload(None)
+ def _getSelectedItems(self):
+ """!Get list of selected items, indeces start at 0"""
+ items = []
+ current = -1
+ while True:
+ next = self.list.GetNextSelected(current)
+ if next == -1:
+ break
+ items.append(next)
+ current = next
+
+ if not items:
+ GMessage(_("No items to selected."), parent = self)
+
+ return items
+
+ def OnMoveItemsUp(self, event):
+ """!Item moved up, update action ids"""
+ items = self._getSelectedItems()
+ if not items:
+ return
+ self.list.MoveItems(items, up = True)
+ self.parent.GetCanvas().Refresh()
+ self.parent.ModelChanged()
+
+ def OnMoveItemsDown(self, event):
+ """!Item moved up, update action ids"""
+ items = self._getSelectedItems()
+ if not items:
+ return
+ self.list.MoveItems(items, up = False)
+ self.parent.GetCanvas().Refresh()
+ self.parent.ModelChanged()
+
class PythonPanel(wx.Panel):
def __init__(self, parent, id = wx.ID_ANY,
**kwargs):
Modified: grass/trunk/gui/wxpython/gmodeler/model.py
===================================================================
--- grass/trunk/gui/wxpython/gmodeler/model.py 2013-11-03 01:07:59 UTC (rev 58143)
+++ grass/trunk/gui/wxpython/gmodeler/model.py 2013-11-03 19:16:23 UTC (rev 58144)
@@ -53,7 +53,7 @@
class Model(object):
"""!Class representing the model"""
def __init__(self, canvas = None):
- self.items = list() # list of actions/loops/...
+ self.items = list() # list of ordered items (action/loop/condition)
# model properties
self.properties = { 'name' : _("model"),
@@ -68,7 +68,7 @@
def GetCanvas(self):
"""!Get canvas or None"""
return self.canvas
-
+
def GetItems(self, objType = None):
"""!Get list of model items
@@ -83,8 +83,8 @@
result.append(item)
return result
-
- def GetItem(self, aId):
+
+ def GetItem(self, aId, objType=None):
"""!Get item of given id
@param aId item id
@@ -92,13 +92,17 @@
@return Model* instance
@return None if no item found
"""
- ilist = self.GetItems()
+ ilist = self.GetItems(objType)
for item in ilist:
if item.GetId() == aId:
return item
-
+
return None
+ def GetItemIndex(self, item):
+ """!Return list index of given item"""
+ return self.items.index(item)
+
def GetNumItems(self, actionOnly = False):
"""!Get number of items"""
if actionOnly:
@@ -106,6 +110,17 @@
return len(self.GetItems())
+ def ReorderItems(self, idxList):
+ for oldIdx, newIdx in idxList.iteritems():
+ item = self.items.pop(oldIdx)
+ self.items.insert(newIdx, item)
+
+ def Normalize(self):
+ iId = 1
+ for item in self.items:
+ item.SetLabel(iId)
+ iId += 1
+
def GetNextId(self):
"""!Get next id (data ignored)
@@ -138,7 +153,7 @@
def Reset(self):
"""!Reset model"""
self.items = list()
-
+
def RemoveItem(self, item):
"""!Remove item from model
@@ -147,8 +162,7 @@
relList = list()
upList = list()
- if not isinstance(item, ModelData):
- self.items.remove(item)
+ self.items.remove(item)
if isinstance(item, ModelAction):
for rel in item.GetRelations():
@@ -323,15 +337,10 @@
# define loops & if/else items
for loop in gxmXml.loops:
- alist = list()
- for aId in loop['items']:
- action = self.GetItem(aId)
- alist.append(action)
-
- loopItem = self.GetItem(loop['id'])
- loopItem.SetItems(alist)
-
- for action in loopItem.GetItems():
+ loopItem = self.GetItem(loop['id'], objType=ModelLoop)
+ loopItem.SetItems(loop['items'])
+ for idx in loop['items']:
+ action = self.GetItem(idx, objType=ModelAction)
action.SetBlock(loopItem)
for condition in gxmXml.conditions:
@@ -348,19 +357,17 @@
for action in items[b]:
action.SetBlock(conditionItem)
- def AddItem(self, newItem):
+ def AddItem(self, newItem, pos = -1):
"""!Add item to the list"""
- iId = newItem.GetId()
-
- i = 0
+ if pos != -1:
+ self.items.insert(pos, newItem)
+ else:
+ self.items.append(newItem)
+ i = 1
for item in self.items:
- if item.GetId() > iId:
- self.items.insert(i, newItem)
- return
+ item.SetLabel(i)
i += 1
- self.items.append(newItem)
-
def IsValid(self):
"""Return True if model is valid"""
if self.Validate():
@@ -621,9 +628,8 @@
params['variables']['params'].append(varDict)
for var in vlist:
- for action in item.GetItems():
- if not isinstance(action, ModelAction) or \
- not action.IsEnabled():
+ for action in item.GetItems(self.GetItems()):
+ if not action.IsEnabled():
continue
varDict['value'] = var
@@ -767,7 +773,7 @@
class ModelObject(object):
def __init__(self, id = -1):
- self.id = id
+ self.id = id # internal id, should be not changed
self.rels = list() # list of ModelRelations
self.isEnabled = True
@@ -779,7 +785,11 @@
def GetId(self):
"""!Get id"""
return self.id
-
+
+ def SetId(self, id):
+ """!Set id"""
+ self.id = id
+
def AddRelation(self, rel):
"""!Record new relation
"""
@@ -925,15 +935,13 @@
pen.SetWidth(width)
self.SetPen(pen)
- def SetId(self, id):
- """!Set id"""
- self.id = id
+ def SetLabel(self, idx=-1):
cmd = self.task.get_cmd(ignoreErrors = True)
+ self.ClearText()
if cmd and len(cmd) > 0:
- self.ClearText()
- self.AddText('(%d) %s' % (self.id, cmd[0]))
+ self.AddText('(%d) %s' % (idx, cmd[0]))
else:
- self.AddText('(%d) <<%s>>' % (self.id, _("unknown")))
+ self.AddText('(%d) <<%s>>' % (idx, _("unknown")))
def SetProperties(self, params, propwin):
"""!Record properties dialog"""
@@ -1335,15 +1343,20 @@
ModelObject.__init__(self, id)
self.parent = parent
self.text = text
- self.items = items # list of items in the loop
+ self.itemIds = list() # unordered
def GetText(self):
"""!Get loop text"""
return self.text
- def GetItems(self):
- """!Get items (id)"""
- return self.items
+ def GetItems(self, items):
+ """!Get sorted items by id"""
+ result = list()
+ for item in items:
+ if item.GetId() in self.itemIds:
+ result.append(item)
+
+ return result
def SetId(self, id):
"""!Set loop id"""
@@ -1371,9 +1384,10 @@
self.rels = list()
class ModelLoop(ModelItem, ogl.RectangleShape):
- def __init__(self, parent, x, y, id = -1, width = None, height = None, text = '', items = []):
+ def __init__(self, parent, x, y, id=-1, idx=-1, width = None, height = None, text = '', items = []):
"""!Defines a loop"""
ModelItem.__init__(self, parent, x, y, id, width, height, text, items)
+ self.cond = text
if not width:
width = UserSettings.Get(group='modeler', key='loop', subkey=('size', 'width'))
@@ -1388,10 +1402,6 @@
self.SetY(y)
self.SetPen(wx.BLACK_PEN)
self.SetCornerRadius(100)
- if text:
- self.AddText('(' + str(self.id) + ') ' + text)
- else:
- self.AddText('(' + str(self.id) + ')')
self._setBrush()
@@ -1407,6 +1417,13 @@
wxColor = wx.Colour(color[0], color[1], color[2])
self.SetBrush(wx.Brush(wxColor))
+ def SetLabel(self, idx=-1):
+ self.ClearText()
+ if self.cond:
+ self.AddText('(%d) %s' % (idx, self.cond))
+ else:
+ self.AddText('(%d)' % (idx))
+
def Enable(self, enabled = True):
"""!Enable/disable action"""
for item in self.items:
@@ -1425,7 +1442,7 @@
def SetItems(self, items):
"""!Set items (id)"""
- self.items = items
+ self.itemIds = items
def OnDraw(self, dc):
"""!Draw loop in canvas"""
More information about the grass-commit
mailing list