diff --git a/Gui/Resources/icons/Assembly_TreeItemDown.svg b/Gui/Resources/icons/Assembly_TreeItemDown.svg
new file mode 100644
index 0000000..ee85640
--- /dev/null
+++ b/Gui/Resources/icons/Assembly_TreeItemDown.svg
@@ -0,0 +1,622 @@
+
+
+
+
diff --git a/Gui/Resources/icons/Assembly_TreeItemUp.svg b/Gui/Resources/icons/Assembly_TreeItemUp.svg
new file mode 100644
index 0000000..24874bd
--- /dev/null
+++ b/Gui/Resources/icons/Assembly_TreeItemUp.svg
@@ -0,0 +1,622 @@
+
+
+
+
diff --git a/assembly.py b/assembly.py
index 2d082f9..2fd1e48 100644
--- a/assembly.py
+++ b/assembly.py
@@ -95,7 +95,8 @@ class AsmGroup(AsmBase):
def setGroupMode(self):
self.Object.GroupMode = 1 # auto delete children
self.Object.setPropertyStatus('GroupMode','Hidden')
- self.Object.setPropertyStatus('GroupMode','Immutable')
+ # self.Object.setPropertyStatus('GroupMode','Immutable')
+ self.Object.setPropertyStatus('GroupMode','ReadOnly')
self.Object.setPropertyStatus('GroupMode','Transient')
def attach(self,obj):
@@ -151,7 +152,7 @@ class AsmElement(AsmBase):
def linkSetup(self,obj):
super(AsmElement,self).linkSetup(obj)
obj.configLinkProperty('LinkedObject')
- obj.setPropertyStatus('LinkedObject','Immutable')
+ # obj.setPropertyStatus('LinkedObject','Immutable')
obj.setPropertyStatus('LinkedObject','ReadOnly')
def attach(self,obj):
@@ -314,7 +315,7 @@ class AsmElementLink(AsmBase):
def linkSetup(self,obj):
super(AsmElementLink,self).linkSetup(obj)
obj.configLinkProperty('LinkedObject')
- obj.setPropertyStatus('LinkedObject','Immutable')
+ # obj.setPropertyStatus('LinkedObject','Immutable')
obj.setPropertyStatus('LinkedObject','ReadOnly')
def attach(self,obj):
@@ -325,9 +326,6 @@ class AsmElementLink(AsmBase):
obj.ViewObject.Proxy.onExecute(self.getInfo(True))
return False
- def getAssembly(self):
- return self.parent.parent.parent
-
def getElement(self):
linked = self.Object.getLinkedObject(False)
if not linked:
@@ -336,6 +334,9 @@ class AsmElementLink(AsmBase):
raise RuntimeError('Invalid element type')
return linked.Proxy
+ def getAssembly(self):
+ return self.parent.parent.parent
+
def getSubName(self):
link = self.Object.LinkedObject
if not isinstance(link,tuple):
@@ -615,10 +616,7 @@ class ViewProviderAsmElementLink(ViewProviderAsmBase):
obj.recompute()
return
- try:
- asm3.solver.solve(obj.Proxy.getAssembly().Object)
- except RuntimeError as e:
- logger.error(e)
+ obj.Proxy.parent.solve()
return ctx.placement
def onDragEnd(self):
@@ -638,6 +636,17 @@ class AsmConstraint(AsmGroup):
self.parent = getProxy(parent,AsmConstraintGroup)
super(AsmConstraint,self).__init__()
+ def solve(self, excp=False):
+ try:
+ asm3.solver.solve(self.getAssembly().Object)
+ except RuntimeError as e:
+ if excp:
+ raise e
+ logger.error(e)
+
+ def getAssembly(self):
+ return self.parent.parent
+
def checkSupport(self):
# this function maybe called during document restore, hence the
# extensive check below
@@ -786,7 +795,7 @@ class AsmConstraint(AsmGroup):
AsmElementLink.make(AsmElementLink.MakeInfo(cstr,*e))
cstr.Proxy._initializing = False
if cstr.recompute() and asm3.gui.AsmCmdManager.AutoRecompute:
- asm3.solver.solve(cstr.Proxy.getAssembly().Object)
+ cstr.Proxy.solve()
return cstr
diff --git a/gui.py b/gui.py
index 8dc73ca..8d7e158 100644
--- a/gui.py
+++ b/gui.py
@@ -236,3 +236,68 @@ class AsmCmdAutoRecompute(AsmCmdCheckable):
_menuText = 'Auto recompute'
_iconName = 'Assembly_AutoRecompute.svg'
_saveParam = True
+
+class AsmCmdUp(AsmCmdBase):
+ _id = 6
+ _menuText = 'Move item up'
+ _iconName = 'Assembly_TreeItemUp.svg'
+
+ @classmethod
+ def getSelection(cls):
+ from asm3.assembly import isTypeOf, Assembly, AsmGroup
+ sels = FreeCADGui.Selection.getSelectionEx('',False)
+ if len(sels)!=1 or len(sels[0].SubElementNames)!=1:
+ return
+ obj,parent,_ = FreeCADGui.Selection.resolveObject(
+ sels[0].Object, sels[0].SubElementNames[0])
+ if isTypeOf(parent,Assembly) or not isTypeOf(parent,AsmGroup) or \
+ len(parent.Group) <= 1:
+ return
+ return (obj,parent,sels[0].Object,sels[0].SubElementNames[0])
+
+ @classmethod
+ def checkActive(cls):
+ cls._active = True if cls.getSelection() else False
+
+ @classmethod
+ def move(cls,step):
+ ret = cls.getSelection()
+ if not ret:
+ return
+ obj,parent,topParent,subname = ret
+ children = parent.Group
+ i = children.index(obj)
+ j = i+step
+ if j<0:
+ j = len(children)-1
+ elif j>=len(children):
+ j = 0
+ logger.debug('move {}:{} -> {}:{}'.format(
+ i,objName(obj),j,objName(children[j])))
+ parent.Document.openTransaction(cls._menuText)
+ parent.Group = {i:children[j],j:obj}
+ parent.Document.commitTransaction()
+ # The tree view may deselect the item because of claimChildren changes,
+ # so we restore the selection here
+ FreeCADGui.Selection.addSelection(topParent,subname)
+
+ if AsmCmdManager.AutoRecompute:
+ parent.Proxy.solve()
+
+ @classmethod
+ def onClearSelection(cls):
+ cls._active = False
+
+ @classmethod
+ def Activated(cls):
+ cls.move(-1)
+
+
+class AsmCmdDown(AsmCmdUp):
+ _id = 7
+ _menuText = 'Move item down'
+ _iconName = 'Assembly_TreeItemDown.svg'
+
+ @classmethod
+ def Activated(cls):
+ cls.move(1)