def onParentSelected(self):
        # clear the selection in the GUI window
        Gui.Selection.clearSelection()
        # build the LCS table
        self.attLCStable = []
        # the current text in the combo-box is the link's name...
        # ... or it's 'Parent Assembly' then the parent is the 'Model' root App::Part
        if self.parentList.currentText() == 'Parent Assembly':
            parentName = 'Parent Assembly'
            parentPart = self.parentAssembly
            # we get the LCS directly in the root App::Part 'Model'
            self.attLCStable = Asm4.getPartLCS(parentPart)
            self.parentDoc.setText(parentPart.Document.Name + '#' +
                                   Asm4.nameLabel(parentPart))
        # if something is selected
        elif self.parentList.currentIndex() > 1:
            parentName = self.parentTable[self.parentList.currentIndex()].Name
            parentPart = self.activeDoc.getObject(parentName)
            if parentPart:
                # we get the LCS from the linked part
                self.attLCStable = Asm4.getPartLCS(parentPart.LinkedObject)
                # linked part & doc
                dText = parentPart.LinkedObject.Document.Name + '#'
                # if the linked part has been renamed by the user
                pText = Asm4.nameLabel(parentPart.LinkedObject)
                self.parentDoc.setText(dText + pText)
                # show all LCS in selected parent
                for lcsName in parentPart.LinkedObject.getSubObjects(1):
                    lcs = parentPart.LinkedObject.Document.getObject(
                        lcsName[0:-1])
                    if lcs.TypeId in [
                            'PartDesign::CoordinateSystem', 'PartDesign::Line'
                    ]:
                        lcs.ViewObject.show()
                # highlight the selected part:
                Gui.Selection.addSelection( \
                        parentPart.Document.Name, 'Model', parentPart.Name+'.' )
                QtCore.QTimer.singleShot(1500, lambda:Gui.Selection.removeSelection( \
                        parentPart.Document.Name, 'Model', parentPart.Name+'.' ) )
        # something wrong
        else:
            return

        # build the list
        self.attLCSlist.clear()
        for lcs in self.attLCStable:
            newItem = QtGui.QListWidgetItem()
            newItem.setText(Asm4.nameLabel(lcs))
            newItem.setIcon(lcs.ViewObject.Icon)
            self.attLCSlist.addItem(newItem)
            #self.attLCStable.append(lcs)
        return
    def onParentSelected(self):
        # clear the selection in the GUI window
        Gui.Selection.clearSelection()
        # build the LCS table
        self.attLCStable = []
        # the current text in the combo-box is the link's name...
        if self.parentList.currentIndex() > 0:
            parentName = self.parentTable[self.parentList.currentIndex()].Name
            parentPart = self.activeDoc.getObject(parentName)
            if parentPart:
                # we get the LCS from the linked part
                self.attLCStable = Asm4.getPartLCS(parentPart.LinkedObject)
                # linked part & doc
                dText = parentPart.LinkedObject.Document.Name + '#'
                # if the linked part has been renamed by the user
                pText = Asm4.nameLabel(parentPart.LinkedObject)
                self.parentDoc.setText(dText + pText)
                # highlight the selected part:
                Gui.Selection.addSelection(parentPart.Document.Name, 'Model',
                                           parentPart.Name + '.')
        # something wrong
        else:
            return

        # build the list
        self.attLCSlist.clear()
        for lcs in self.attLCStable:
            newItem = QtGui.QListWidgetItem()
            newItem.setText(Asm4.nameLabel(lcs))
            newItem.setIcon(lcs.ViewObject.Icon)
            self.attLCSlist.addItem(newItem)
            #self.attLCStable.append(lcs)
        return
 def onParentList(self):
     # clear the LCS list
     self.attLCSlist.clear()
     self.attLCStable = []
     # clear the selection in the GUI window
     Gui.Selection.clearSelection()
     # keep the fastener selected
     Gui.Selection.addSelection( self.activeDoc.Name, 'Model', self.selectedFastener.Name+'.')
     # the current text in the combo-box is the link's name...
     # ... or it's 'Parent Assembly' then the parent is the 'Model' root App::Part		
     if self.parentList.currentText() == 'Parent Assembly':
         parentName = 'Parent Assembly'
         parentPart = self.activeDoc.getObject( 'Model' )
         # we get the LCS directly in the root App::Part 'Model'
         self.attLCStable = Asm4.getPartLCS( parentPart )
         self.parentDoc.setText( parentPart.Document.Name+'#'+Asm4.nameLabel(parentPart) )
     # if something is selected
     elif self.parentList.currentIndex() > 1:
         parentName = self.parentTable[ self.parentList.currentIndex() ].Name
         parentPart = self.activeDoc.getObject( parentName )
         if parentPart:
             # we get the LCS from the linked part
             self.attLCStable = Asm4.getPartLCS( parentPart.LinkedObject )
             # linked part & doc
             dText = parentPart.LinkedObject.Document.Name +'#'
             # if the linked part has been renamed by the user
             pText = Asm4.nameLabel( parentPart.LinkedObject )
             self.parentDoc.setText( dText + pText )
             # highlight the selected part:
             Gui.Selection.addSelection( parentPart.Document.Name, 'Model', parentPart.Name+'.' )
     # something wrong
     else:
         return
     
     # build the list
     self.attLCSlist.clear()
     for lcs in self.attLCStable:
         newItem = QtGui.QListWidgetItem()
         newItem.setText(Asm4.nameLabel(lcs))
         newItem.setIcon( lcs.ViewObject.Icon )
         self.attLCSlist.addItem( newItem )
         #self.attLCStable.append(lcs)
     return
    def __init__(self):
        self.base = QtGui.QWidget()
        self.form = self.base
        iconFile = os.path.join(Asm4.iconPath, 'Place_Link.svg')
        self.form.setWindowIcon(QtGui.QIcon(iconFile))
        self.form.setWindowTitle('Place linked Part')

        # check that we have selected two LCS or an App::Link object
        self.selectedLink = []
        self.selectedLCSA = None
        self.selectedLinkB = None
        self.selectedLCSB = None
        selection = Asm4.getSelectedLink()
        #selectedLCSPair = Asm4.getLinkAndDatum2()
        self.Xtranslation = 0.00
        self.Ytranslation = 0.00
        self.Ztranslation = 0.00
        self.XrotationAngle = 0.00
        self.YrotationAngle = 0.00
        self.ZrotationAngle = 0.00

        # draw the GUI, objects are defined later down
        self.drawUI()
        global taskUI
        taskUI = self

        #Handle single selected App::Link
        if not selection:
            # This shouldn't happen
            FCC.PrintWarning(
                "This is not an error message you are supposed to see, something went wrong\n"
            )
            Gui.Control.closeDialog()
        else:
            self.selectedLink = selection
            Asm4.makeAsmProperties(self.selectedLink)

        #save original AttachmentOffset of linked part
        self.old_LinkAttachmentOffset = self.selectedLink.AttachmentOffset
        self.old_LinkRotation = self.selectedLink.AttachmentOffset.Rotation
        self.old_LinkPosition = self.selectedLink.AttachmentOffset.Base
        # default values correspond to original AttachmentOffset of linked part
        self.Xtranslation = self.old_LinkPosition[0]
        self.Ytranslation = self.old_LinkPosition[1]
        self.Ztranslation = self.old_LinkPosition[2]
        self.XrotationAngle = self.old_LinkRotation.toEuler()[0]
        self.YrotationAngle = self.old_LinkRotation.toEuler()[1]
        self.ZrotationAngle = self.old_LinkRotation.toEuler()[2]

        # save previous view properties
        self.old_OverrideMaterial = self.selectedLink.ViewObject.OverrideMaterial
        self.old_DrawStyle = self.selectedLink.ViewObject.DrawStyle
        self.old_LineWidth = self.selectedLink.ViewObject.LineWidth
        self.old_DiffuseColor = self.selectedLink.ViewObject.ShapeMaterial.DiffuseColor
        self.old_Transparency = self.selectedLink.ViewObject.ShapeMaterial.Transparency
        # set new view properties
        self.selectedLink.ViewObject.OverrideMaterial = True
        self.selectedLink.ViewObject.DrawStyle = DrawStyle
        self.selectedLink.ViewObject.LineWidth = LineWidth
        self.selectedLink.ViewObject.ShapeMaterial.DiffuseColor = DiffuseColor
        self.selectedLink.ViewObject.ShapeMaterial.Transparency = Transparency

        # get the current active document to avoid errors if user changes tab
        self.activeDoc = App.activeDocument()
        # the parent (top-level) assembly is the App::Part called Model (hard-coded)
        self.parentAssembly = self.activeDoc.Model

        # check that the link is an Asm4 link:
        self.isAsm4EE = False
        if hasattr(self.selectedLink, 'AssemblyType'):
            if self.selectedLink.AssemblyType == 'Asm4EE' or self.selectedLink.AssemblyType == '':
                self.isAsm4EE = True
            else:
                Asm4.warningBox(
                    "This Link's assembly type doesn't correspond to this WorkBench"
                )
                return

        # initialize the UI with the current data
        self.attLCStable = []
        self.initUI()
        # now self.parentList and self.parentTable are available

        # find all the linked parts in the assembly
        for objName in self.parentAssembly.getSubObjects():
            # remove the trailing .
            obj = self.activeDoc.getObject(objName[0:-1])
            if obj.TypeId == 'App::Link' and hasattr(obj.LinkedObject,
                                                     'isDerivedFrom'):
                if obj.LinkedObject.isDerivedFrom(
                        'App::Part') or obj.LinkedObject.isDerivedFrom(
                            'PartDesign::Body'):
                    # ... except if it's the selected link itself
                    if obj != self.selectedLink:
                        self.parentTable.append(obj)
                        # add to the drop-down combo box with the assembly tree's parts
                        objIcon = obj.LinkedObject.ViewObject.Icon
                        objText = Asm4.nameLabel(obj)
                        self.parentList.addItem(objIcon, objText, obj)

        # find all the LCS in the selected link
        self.partLCStable = Asm4.getPartLCS(self.selectedLink.LinkedObject)
        # build the list
        self.partLCSlist.clear()
        for lcs in self.partLCStable:
            newItem = QtGui.QListWidgetItem()
            newItem.setText(Asm4.nameLabel(lcs))
            newItem.setIcon(lcs.ViewObject.Icon)
            self.partLCSlist.addItem(newItem)

        # get the old values
        if self.isAsm4EE:
            self.old_AO = self.selectedLink.AttachmentOffset
            self.old_linkLCS = self.selectedLink.AttachedBy[1:]
            (self.old_Parent, separator,
             self.old_parentLCS) = self.selectedLink.AttachedTo.partition('#')
        else:
            self.old_AO = []
            self.old_Parent = ''

        self.old_EE = ''
        # get and store the current expression engine:
        self.old_EE = Asm4.placementEE(self.selectedLink.ExpressionEngine)

        # decode the old ExpressionEngine
        old_Parent = ''
        old_ParentPart = ''
        old_attLCS = ''
        constrName = ''
        linkedDoc = ''
        old_linkLCS = ''
        # if the decode is unsuccessful, old_Expression is set to False and the other things are set to 'None'
        (old_Parent, old_attLCS,
         old_linkLCS) = Asm4.splitExpressionLink(self.old_EE, self.old_Parent)

        # find the old LCS in the list of LCS of the linked part...
        # MatchExactly, MatchContains, MatchEndsWith ...
        lcs_found = self.partLCSlist.findItems(old_linkLCS,
                                               QtCore.Qt.MatchExactly)
        if not lcs_found:
            lcs_found = self.partLCSlist.findItems(old_linkLCS + ' (',
                                                   QtCore.Qt.MatchStartsWith)
        if lcs_found:
            # ... and select it
            self.partLCSlist.setCurrentItem(lcs_found[0])

        # find the oldPart in the part list...
        if old_Parent == 'Parent Assembly':
            parent_found = True
            parent_index = 1
        else:
            parent_found = False
            parent_index = 1
            for item in self.parentTable[1:]:
                if item.Name == old_Parent:
                    parent_found = True
                    break
                else:
                    parent_index = parent_index + 1
        if not parent_found:
            parent_index = 0
        self.parentList.setCurrentIndex(parent_index)
        # this should have triggered self.getPartLCS() to fill the LCS list

        # find the old attachment Datum in the list of the Datums in the linked part...
        lcs_found = self.attLCSlist.findItems(old_attLCS,
                                              QtCore.Qt.MatchExactly)
        if not lcs_found:
            lcs_found = self.attLCSlist.findItems(old_attLCS + ' (',
                                                  QtCore.Qt.MatchStartsWith)
        if lcs_found:
            # ... and select it
            self.attLCSlist.setCurrentItem(lcs_found[0])