def setup(self, sync=None):

        if float(".".join(FreeCAD.Version()[0:2])) == 0.18:
            #part of the FC 0.18 no proxy change event workaround
            if hasattr(self.obj, 'Proxy'):
                self.proxydata = self.obj.Proxy

        #collect all property values and infos
        infos = []
        for prop in self.obj.PropertiesList:
            info = Property.createInformation(self.obj, prop)
            infos.append(info)

        #check if we need to handle a syncronisation
        if sync:
            self._runner.sync(sync)

        #setup ourself
        self._runner.run(self.Writer.setup, self.obj.TypeId,
                         self.obj.PropertiesList, infos)

        #check if there are properties that need the default values uploaded
        props = Property.getNonDefaultValueProperties(self.obj)
        for prop in props:
            self._runner.run(
                self.Writer.changeProperty(
                    prop, Property.convertPropertyToWamp(self.obj, prop), []))
def createDynamicProperty(obj, prop, typeID, group, documentation, status):

    if hasattr(obj, prop):
        return

    with __fcobject_processing(obj):

        attributes = Property.statusToType(status)
        obj.addProperty(typeID, prop, group, documentation, attributes)

        if float(".".join(FreeCAD.Version()[0:2])) >= 0.19:
            obj.setPropertyStatus(prop, status)
        else:
            mode = Property.statusToEditorMode(status)
            if mode:
                obj.setEditorMode(prop, mode)
def setPropertyStatus(obj, prop, status):

    with __fcobject_processing(obj):

        if float(".".join(FreeCAD.Version()[0:2])) >= 0.19:

            if status:
                #to set the status multiple things need to happen:
                # 1. remove all string status entries we do not support
                supported = obj.getPropertyStatus()
                filtered = [
                    s for s in status
                    if not isinstance(s, str) or s in supported
                ]

                # 2. check which are to be added, and add those
                current = obj.getPropertyStatus(prop)
                add = [s for s in filtered if not s in current]
                obj.setPropertyStatus(prop, add)

                # 3. check which are to be removed, and remove those
                remove = [s for s in current if not s in filtered]
                signed = [-s for s in remove if isinstance(s, int)]
                signed += ["-" + s for s in remove if isinstance(s, str)]
                obj.setPropertyStatus(prop, signed)

            else:
                # None status means removing all of them!
                remove = obj.getPropertyStatus(prop)
                signed = [-s for s in remove if isinstance(s, int)]
                signed += ["-" + s for s in remove if isinstance(s, str)]
                obj.setPropertyStatus(prop, signed)

        else:
            obj.setEditorMode(prop, Property.statusToEditorMode(status))
def createDynamicProperties(obj, props, infos):

    with __fcobject_processing(obj):
        for prop, info in zip(props, infos):
            if prop in obj.PropertiesList:
                continue

            attributes = Property.statusToType(info["status"])
            obj.addProperty(info["id"], prop, info["group"], info["docu"],
                            attributes)

            if float(".".join(FreeCAD.Version()[0:2])) >= 0.19:
                obj.setPropertyStatus(prop, info["status"])
            else:
                mode = Property.statusToEditorMode(info["status"])
                if mode:
                    obj.setEditorMode(prop, mode)
    def setup(self, syncer=None):
        # setup the FC object on the OCP node including all properties

        infos = []
        for prop in self.obj.PropertiesList:
            infos.append(Property.createInformation(self.obj, prop))

        #check if we need to handle a document syncronisation
        if syncer:
            self._runner.sync(syncer)

        self._runner.run(self.Writer.setup, self.obj.TypeId,
                         self.obj.PropertiesList, infos)

        #check if there are properties that need the default values uploaded
        props = Property.getNonDefaultValueProperties(self.obj)
        for prop in props:
            self._runner.run(self.Writer.changeProperty, prop,
                             Property.convertPropertyToWamp(self.obj, prop),
                             [])
    async def upload(self, obj):
        # Creates and uploads the object data into the ocp node
        # Note: this function works async, but cannot handle any changes during execution,
        #       neither on the node nor in the FC object

        try:
            #first check if we are available online.
            if await self.Writer.isAvailable():
                raise Exception("Object already setup, cannot upload")

            #setup object and all properties
            infos = []
            for prop in obj.PropertiesList:
                infos.append(Property.createInformation(obj, prop))

            await self.Writer.setup(obj.TypeId, obj.PropertiesList, infos)

            #we process the other tasks in parallel
            tasks = []

            #upload all extensions
            ext = Object.getExtensions(obj)
            for e in ext:
                tasks.append(self.Writer.addExtension(e))

            #write all properties.
            props = obj.PropertiesList
            for prop in props:
                value = Property.convertPropertyToWamp(obj, prop)
                self.Writer.changeProperty(prop, value, obj.OutList)

            tasks.append(self.Writer.processPropertyChanges())

            if tasks:
                await asyncio.gather(*tasks)

        except Exception as e:
            self.logger.error(f"Uploading object failed: {e}")
            traceback.print_exc()
    def changeProperty(self, prop):

        value = Property.convertPropertyToWamp(self.obj, prop)

        if float(".".join(FreeCAD.Version()[0:2])) == 0.18:
            #work around missing proxy callback in ViewProvider. This may add to some delay, as proxy change is only forwarded
            #when another property changes afterwards, however, at least the order of changes is kept
            if hasattr(self.obj, 'Proxy'):
                if not self.proxydata is self.obj.Proxy:
                    self.proxydata = self.obj.Proxy
                    self._runner.run(self.__changeProperty, 'Proxy',
                                     self.obj.dumpPropertyContent('Proxy'), [])

        self._runner.run(self.__changeProperty, prop, value, [])
def setProperties(obj, props, values):

    with __fcobject_processing(obj):
        for prop, value in zip(props, values):
            Property.convertWampToProperty(obj, prop, value)
def setProperty(obj, prop, value):

    with __fcobject_processing(obj):
        Property.convertWampToProperty(obj, prop, value)
 def changePropertyStatus(self, prop):
     info = Property.createInformation(self.obj, prop)
     self._runner.run(self.__changePropertyStatus, prop, info["status"])
 def addDynamicExtension(self, extension, props):
     infos = []
     for prop in props:
         infos.append(Property.createInformation(self.obj, prop))
     self._runner.run(self.Writer.addExtension, extension, props, infos)
 def createDynamicProperty(self, prop):
     info = Property.createInformation(self.obj, prop)
     self._runner.run(self.__addDynamicProperty, prop, info)
 def changeProperty(self, prop):
     value = Property.convertPropertyToWamp(self.obj, prop)
     outlist = [obj.Name for obj in self.obj.OutList]
     self._runner.run(self.__changeProperty, prop, value, outlist)