Esempio n. 1
0
class BoltsWidget(QBoltsWidget):
	def __init__(self,repo,freecad):
		QBoltsWidget.__init__(self)
		self.ui = Ui_BoltsWidget()
		self.ui.setupUi(self)

		self.repo = repo
		self.freecad = freecad

		self.param_widgets = {}
		self.props_widgets = {}

		self.coll_root = QtGui.QTreeWidgetItem(self.ui.partsTree,['Collections','Ordered by collections'])
		self.coll_root.setData(0,32,None)
		self.std_root = QtGui.QTreeWidgetItem(self.ui.partsTree,['Standard','Ordered by issueing body'])
		self.std_root.setData(0,32,None)

		#set up collections
		for coll in self.repo.collections:
			coll_item = QtGui.QTreeWidgetItem(self.coll_root,[coll.name, coll.description])
			coll_item.setData(0,32,coll)
			for cl in coll.classes:
				if not cl.id in self.freecad.getbase:
					continue
				cl_item = QtGui.QTreeWidgetItem(coll_item,[cl.name, cl.description])
				cl_item.setData(0,32,cl)

		#set up standards
		for body in repo.standard_bodies:
			std_item = QtGui.QTreeWidgetItem(self.std_root,[body, "Standards issued by %s" % body])
			std_item.setData(0,32,None)
			for cl in repo.standardized[body]:
				if not cl.id in self.freecad.getbase:
					continue
				cl_item = QtGui.QTreeWidgetItem(std_item,[cl.name, cl.description])
				cl_item.setData(0,32,cl)


		self.remove_empty_items(self.coll_root)

	def remove_empty_items(self,root_item):
		children = [root_item.child(i) for i in range(root_item.childCount())]
		for child in children:
			self.remove_empty_items(child)
			data = unpack(child.data(0,32))
			if not isinstance(data,BOLTSClass) and child.childCount() == 0:
				root_item.removeChild(child)

	def setup_param_widgets(self,cl,base):
		#construct widgets
		params = cl.parameters.union(base.parameters)

		for p in params.free:
			p_type = params.types[p]
			default = str(params.defaults[p])
			if p_type == "Length (mm)":
				self.param_widgets[p] = LengthWidget(self.ui.params,p + " (mm)",default)
			elif p_type == "Length (in)":
				self.param_widgets[p] = LengthWidget(self.ui.params,p + " (in)",default)
			elif p_type == "Number":
				self.param_widgets[p] = NumberWidget(self.ui.params,p,default)
			elif p_type == "Angle (deg)":
				self.param_widgets[p] = AngleWidget(self.ui.params,p + " (deg)",default)
			elif p_type == "Bool":
				self.param_widgets[p] = BoolWidget(self.ui.params,p,default)
			elif p_type == "Table Index":
				self.param_widgets[p] = TableIndexWidget(self.ui.params,p,params.choices[p],default)
			else:
				raise ValueError("Unknown type encountered for parameter %s: %s" % (p,p_type))
			self.param_widgets[p].setToolTip(params.description[p])
		#add them to layout
			self.ui.param_layout.addWidget(self.param_widgets[p])
		if base.type == "fcstd":
			self.ui.addButton.setText("Add part (may take a bit)")
		else:
			self.ui.addButton.setText("Add part")

	def setup_props_collection(self,coll):
		#construct widgets
		self.props_widgets.append(PropertyWidget(self.ui.props,"Name",coll.name))
		self.props_widgets.append(PropertyWidget(self.ui.props,"Description",coll.description))
		self.props_widgets.append(PropertyWidget(self.ui.props,"Authors",", ".join(coll.author_names)))
		self.props_widgets.append(PropertyWidget(self.ui.props,"License",coll.license_name))

		#add them to layout
		for widget in self.props_widgets:
			self.ui.props_layout.addWidget(widget)

	def setup_props_class(self,cl):
		#construct widgets
		self.props_widgets.append(PropertyWidget(self.ui.props,"Name",cl.name))
		if cl.description:
			self.props_widgets.append(PropertyWidget(self.ui.props,"Description",cl.description))
		if not cl.standard is None:
			if cl.status == "withdrawn":
				self.props_widgets.append(PropertyWidget(self.ui.props,"Status","<font color='red'>%s</font>" % cl.status))
			else:
				self.props_widgets.append(PropertyWidget(self.ui.props,"Status","<font color='green'>%s</font>" % cl.status))
			if not cl.replaces is None:
				self.props_widgets.append(PropertyWidget(self.ui.props,"Replaces",cl.replaces))
			if not cl.replacedby is None:
				self.props_widgets.append(PropertyWidget(self.ui.props,"Replacedby",cl.replacedby))
		if cl.url:
			self.props_widgets.append(PropertyWidget(self.ui.props,"URL",cl.url))

		#add them to layout
		for widget in self.props_widgets:
			self.ui.props_layout.addWidget(widget)

	@Slot(bool)
	def on_addButton_clicked(self,checked):
		if FreeCAD.activeDocument() is None:
			FreeCAD.newDocument()

		items = self.ui.partsTree.selectedItems()

		if len(items) < 1:
			return

		data = unpack(items[0].data(0,32))

		if not isinstance(data,BOLTSClass):
			return

		params = {}
		#read parameters from widgets
		for key in self.param_widgets:
			params[key] = self.param_widgets[key].getValue()
		params = data.parameters.collect(params)
		params['standard'] = data.name

		params['name'] = data.naming.template % \
			tuple(params[k] for k in data.naming.substitute)

		lengths = {"Length (mm)" : "mm", "Length (in)" : "in"}

		for key,tp in data.parameters.types.iteritems():
			if tp in lengths:
				if params[key] is None:
					#A undefined value is not necessarily fatal
					continue
				revision = int(FreeCAD.Version()[2].split()[0])
				if revision >= 2836:
					params[key] = FreeCAD.Units.parseQuantity("%g %s" %
						(params[key], lengths[tp])).Value
				else:
					params[key] = FreeCAD.Units.translateUnit("%g %s" %
						(params[key], lengths[tp]))

		#add part
		try:
			base = self.freecad.getbase[data.id]
			add_part(base,params,FreeCAD.ActiveDocument)
			FreeCADGui.SendMsgToActiveView("ViewFit")
			FreeCAD.ActiveDocument.recompute()
		except ValueError as e:
			QtGui.QErrorMessage(self).showMessage(str(e))
		except Exception as e:
			FreeCAD.Console.PrintMessage(e)
			QtGui.QErrorMessage(self).showMessage("An error occured when trying to add the part: %s\nParameter Values: %s" % (e,params))

	@Slot()
	def on_partsTree_itemSelectionChanged(self):
		items = self.ui.partsTree.selectedItems()
		if len(items) < 1:
			return
		item = items[0]
		data = unpack(item.data(0,32))

		#clear props widget
		for widget in self.props_widgets:
			self.ui.props_layout.removeWidget(widget)
			widget.setParent(None)
		self.props_widgets = []
		#clear
		for key in self.param_widgets:
			self.ui.param_layout.removeWidget(self.param_widgets[key])
			self.param_widgets[key].setParent(None)
		self.param_widgets = {}

		if isinstance(data,BOLTSClass):
			self.setup_props_class(data)
			self.setup_param_widgets(data,self.freecad.getbase[data.id])
		elif isinstance(data,BOLTSCollection):
			self.setup_props_collection(data)
Esempio n. 2
0
class BoltsWidget(QBoltsWidget):
	def __init__(self,repo,freecad):
		QBoltsWidget.__init__(self)
		self.ui = Ui_BoltsWidget()
		self.ui.setupUi(self)

		self.repo = repo
		self.freecad = freecad

		self.param_widgets = {}
		self.props_widgets = {}

		self.coll_root = QtGui.QTreeWidgetItem(self.ui.partsTree,['Collections','Ordered by collections'])
		self.coll_root.setData(0,32,None)
		self.std_root = QtGui.QTreeWidgetItem(self.ui.partsTree,['Standard','Ordered by issueing body'])
		self.std_root.setData(0,32,None)

		#set up collections
		for coll in self.repo.collections:
			coll_item = QtGui.QTreeWidgetItem(self.coll_root,[coll.name, coll.description])
			coll_item.setData(0,32,coll)
			for cl in coll.classes:
				if not cl.id in self.freecad.getbase:
					continue
				cl_item = QtGui.QTreeWidgetItem(coll_item,[cl.name, cl.description])
				cl_item.setData(0,32,cl)

		#set up standards
		for body in repo.standard_bodies:
			std_item = QtGui.QTreeWidgetItem(self.std_root,[body, "Standards issued by %s" % body])
			std_item.setData(0,32,None)
			for cl in repo.standardized[body]:
				if not cl.id in self.freecad.getbase:
					continue
				cl_item = QtGui.QTreeWidgetItem(std_item,[cl.name, cl.description])
				cl_item.setData(0,32,cl)


		self.remove_empty_items(self.coll_root)

	def remove_empty_items(self,root_item):
		children = [root_item.child(i) for i in range(root_item.childCount())]
		for child in children:
			self.remove_empty_items(child)
			data = child.data(0,32).toPyObject()
			if not isinstance(data,BOLTSClass) and child.childCount() == 0:
				root_item.removeChild(child)

	def setup_param_widgets(self,cl,base):
		#construct widgets
		params = cl.parameters.union(base.parameters)
		for p in params.free:
			p_type = params.types[p]
			default = str(params.defaults[p])
			print p,p_type,default
			if p_type == "Length (mm)":
				self.param_widgets[p] = LengthWidget(self.ui.params,p + " (mm)",default)
			elif p_type == "Length (in)":
				self.param_widgets[p] = LengthWidget(self.ui.params,p + " (in)",default)
			elif p_type == "Number":
				self.param_widgets[p] = NumberWidget(self.ui.params,p,default)
			elif p_type == "Bool":
				self.param_widgets[p] = BoolWidget(self.ui.params,p,default)
			elif p_type == "Table Index":
				for table in params.tables:
					if table.index == p:
						sort_idx = table.columns.index(table.sort)
						keys = [key for key,row in sorted(table.data.iteritems(),key=lambda x: x[1][sort_idx])]
						self.param_widgets[p] = TableIndexWidget(self.ui.params,p,keys,default)
						#if more than one table has the same index, they have the same keys, so stop
						break
		#add them to layout
			self.ui.param_layout.addWidget(self.param_widgets[p])

	def setup_props_collection(self,coll):
		#construct widgets
		self.props_widgets.append(PropertyWidget(self.ui.props,"Name",coll.name))
		self.props_widgets.append(PropertyWidget(self.ui.props,"Description",coll.description))
		self.props_widgets.append(PropertyWidget(self.ui.props,"Authors",", ".join(coll.author_names)))
		self.props_widgets.append(PropertyWidget(self.ui.props,"License",coll.license_name))

		#add them to layout
		for widget in self.props_widgets:
			self.ui.props_layout.addWidget(widget)

	def setup_props_class(self,cl):
		#construct widgets
		self.props_widgets.append(PropertyWidget(self.ui.props,"Name",cl.name))
		if cl.description:
			self.props_widgets.append(PropertyWidget(self.ui.props,"Description",cl.description))
		if not cl.standard is None:
			if cl.status == "withdrawn":
				self.props_widgets.append(PropertyWidget(self.ui.props,"Status","<font color='red'>%s</font>" % cl.status))
			else:
				self.props_widgets.append(PropertyWidget(self.ui.props,"Status","<font color='green'>%s</font>" % cl.status))
			if not cl.replaces is None:
				self.props_widgets.append(PropertyWidget(self.ui.props,"Replaces",cl.replaces))
			if not cl.replacedby is None:
				self.props_widgets.append(PropertyWidget(self.ui.props,"Replacedby",cl.replacedby))
		if cl.url:
			self.props_widgets.append(PropertyWidget(self.ui.props,"URL",cl.url))

		#add them to layout
		for widget in self.props_widgets:
			self.ui.props_layout.addWidget(widget)

	@QtCore.pyqtSlot(bool)
	def on_addButton_clicked(self,checked):
		if FreeCAD.activeDocument() is None:
			FreeCAD.newDocument()

		items = self.ui.partsTree.selectedItems()

		if len(items) < 1:
			return

		data = items[0].data(0,32).toPyObject()

		if not isinstance(data,BOLTSClass):
			return

		params = {}
		#read parameters from widgets
		for key in self.param_widgets:
			params[key] = self.param_widgets[key].getValue()
		params = data.parameters.collect(params)
		params['standard'] = data.name

		params['name'] = data.naming.template % \
			tuple(params[k] for k in data.naming.substitute)

		lengths = {"Length (mm)" : "mm", "Length (in)" : "in"}

		for key,tp in data.parameters.types.iteritems():
			if tp in lengths:
				revision = int(FreeCAD.Version()[2].split()[0])
				if revision >= 2836:
					params[key] = FreeCAD.Units.parseQuantity("%g %s" %
						(params[key], lengths[tp])).Value
				else:
					params[key] = FreeCAD.Units.translateUnit("%g %s" %
						(params[key], lengths[tp]))

		#add part
		base = self.freecad.getbase[data.id]
		add_part(base,params,FreeCAD.ActiveDocument)
		FreeCADGui.SendMsgToActiveView("ViewFit")

	def on_partsTree_itemSelectionChanged(self):
		items = self.ui.partsTree.selectedItems()
		if len(items) < 1:
			return
		item = items[0]
		data = item.data(0,32).toPyObject()

		#clear props widget
		for widget in self.props_widgets:
			self.ui.props_layout.removeWidget(widget)
			widget.setParent(None)
		self.props_widgets = []
		#clear
		for key in self.param_widgets:
			self.ui.param_layout.removeWidget(self.param_widgets[key])
			self.param_widgets[key].setParent(None)
		self.param_widgets = {}

		if isinstance(data,BOLTSClass):
			self.setup_props_class(data)
			self.setup_param_widgets(data,self.freecad.getbase[data.id])
		elif isinstance(data,BOLTSCollection):
			self.setup_props_collection(data)
Esempio n. 3
0
class BoltsWidget(QBoltsWidget):
    def __init__(self, repo, freecad):
        QBoltsWidget.__init__(self)
        self.ui = Ui_BoltsWidget()
        self.ui.setupUi(self)

        self.repo = repo
        self.dbs = {}
        self.dbs["freecad"] = freecad

        self.param_widgets = {}
        self.props_widgets = {}

        self.coll_root = QtGui.QTreeWidgetItem(
            self.ui.partsTree, ['Collections', 'Ordered by collections'])
        self.coll_root.setData(0, 32, None)
        self.std_root = QtGui.QTreeWidgetItem(
            self.ui.partsTree, ['Standard', 'Ordered by issuing body'])
        self.std_root.setData(0, 32, None)

        # set up collections
        for coll, in self.repo.itercollections():
            coll_item = QtGui.QTreeWidgetItem(self.coll_root,
                                              [coll.name, coll.description])
            coll_item.setData(0, 32, coll)

            multinames = {}
            multistds = {}

            clasids = []
            # names
            for name, multiname in self.dbs["freecad"].iternames(
                ['name', 'multiname'], filter_collection=coll):
                # append classid
                clasids.append(self.repo.class_names.get_src(name).id)
                item = None
                if multiname is None:
                    item = QtGui.QTreeWidgetItem(
                        coll_item, [name.name.get_nice(), name.description])
                else:
                    if multiname not in multinames:
                        multinames[multiname] = QtGui.QTreeWidgetItem(
                            coll_item, [multiname.group.get_nice(), ""])
                    item = QtGui.QTreeWidgetItem(
                        multinames[multiname],
                        [name.name.get_nice(), name.description])

                item.setData(0, 32, name)

            # single names
            for std, multistd in self.dbs["freecad"].iterstandards(
                ['standard', 'multistandard'], filter_collection=coll):
                item = None
                # only add item if it is not in classids
                if self.repo.class_standards.get_src(std).id not in clasids:
                    if multistd is None:
                        item = QtGui.QTreeWidgetItem(
                            coll_item,
                            [std.standard.get_nice(), std.description])
                    else:
                        if multistd not in multistds:
                            multistds[multistd] = QtGui.QTreeWidgetItem(
                                coll_item, [multistd.standard.get_nice(), ""])
                        item = QtGui.QTreeWidgetItem(
                            multistds[multistd],
                            [std.standard.get_nice(), std.description])

                    item.setData(0, 32, std)

        multistds = {}

        # set up standards
        for body, in repo.iterbodies():
            std_item = QtGui.QTreeWidgetItem(
                self.std_root,
                [body.body, "Standards issued by %s" % body.body])
            std_item.setData(0, 32, None)
            # single standards
            for std, multistd in self.dbs["freecad"].iterstandards(
                ['standard', 'multistandard'], filter_body=body):
                if multistd is None:
                    item = QtGui.QTreeWidgetItem(
                        std_item, [std.standard.get_nice(), std.description])
                else:
                    if multistd not in multistds:
                        multistds[multistd] = QtGui.QTreeWidgetItem(
                            std_item, [multistd.standard.get_nice(), ""])
                    item = QtGui.QTreeWidgetItem(
                        multistds[multistd],
                        [std.standard.get_nice(), std.description])

                item.setData(0, 32, std)

        self.remove_empty_items(self.coll_root)

    def remove_empty_items(self, root_item):
        children = [root_item.child(i) for i in range(root_item.childCount())]
        for child in children:
            self.remove_empty_items(child)
            data = unpack(child.data(0, 32))
            if (not (isinstance(data, ClassName)
                     or isinstance(data, ClassStandard))
                    and child.childCount() == 0):
                root_item.removeChild(child)

    def setup_param_widgets(self, cl, base):
        # construct widgets
        params = cl.parameters.union(base.parameters)

        for p in params.free:
            p_type = params.types[p]
            default = str(params.defaults[p])
            if p_type == "Length (mm)":
                self.param_widgets[p] = LengthWidget(self.ui.params,
                                                     p + " (mm)", default)
            elif p_type == "Length (in)":
                self.param_widgets[p] = LengthWidget(self.ui.params,
                                                     p + " (in)", default)
            elif p_type == "Number":
                self.param_widgets[p] = NumberWidget(self.ui.params, p,
                                                     default)
            elif p_type == "Angle (deg)":
                self.param_widgets[p] = AngleWidget(self.ui.params,
                                                    p + " (deg)", default)
            elif p_type == "Bool":
                self.param_widgets[p] = BoolWidget(self.ui.params, p, default)
            elif p_type == "Table Index":
                self.param_widgets[p] = TableIndexWidget(
                    self.ui.params, p, params.choices[p], default)
            else:
                raise ValueError(
                    "Unknown type encountered for parameter %s: %s" %
                    (p, p_type))
            self.param_widgets[p].setToolTip(params.description[p])

            # add them to layout
            self.ui.param_layout.addWidget(self.param_widgets[p])
        if base.type == "fcstd":
            self.ui.addButton.setText("Add part (may take a bit)")
        else:
            self.ui.addButton.setText("Add part")

    def setup_props_collection(self, coll):
        # construct widgets
        self.props_widgets.append(
            PropertyWidget(self.ui.props, "Name", coll.name))
        self.props_widgets.append(
            PropertyWidget(self.ui.props, "Description", coll.description))
        self.props_widgets.append(
            PropertyWidget(self.ui.props, "Authors",
                           ", ".join(coll.author_names)))
        self.props_widgets.append(
            PropertyWidget(self.ui.props, "License", coll.license_name))

        # add them to layout
        for widget in self.props_widgets:
            self.ui.props_layout.addWidget(widget)

    def setup_props_standard(self, std):
        # construct widgets
        self.props_widgets.append(
            PropertyWidget(self.ui.props, "Name", std.standard.get_nice()))
        if std.description:
            self.props_widgets.append(
                PropertyWidget(self.ui.props, "Description", std.description))
        if std.status == "withdrawn":
            self.props_widgets.append(
                PropertyWidget(self.ui.props, "Status",
                               "<font color='red'>%s</font>" % std.status))
        else:
            self.props_widgets.append(
                PropertyWidget(self.ui.props, "Status",
                               "<font color='green'>%s</font>" % std.status))
        if std.replaces is not None:
            self.props_widgets.append(
                PropertyWidget(self.ui.props, "Replaces", std.replaces))
        if std.replacedby is not None:
            self.props_widgets.append(
                PropertyWidget(self.ui.props, "Replacedby", std.replacedby))
        self.props_widgets.append(
            PropertyWidget(self.ui.props, "ID", std.get_id()))

        # add them to layout
        for widget in self.props_widgets:
            self.ui.props_layout.addWidget(widget)

    def setup_props_name(self, name):
        # construct widgets
        self.props_widgets.append(
            PropertyWidget(self.ui.props, "Name", name.name.get_nice()))
        if name.description:
            self.props_widgets.append(
                PropertyWidget(self.ui.props, "Description", name.description))
        self.props_widgets.append(
            PropertyWidget(self.ui.props, "ID", name.get_id()))

        # add them to layout
        for widget in self.props_widgets:
            self.ui.props_layout.addWidget(widget)

    @Slot(bool)
    def on_addButton_clicked(self, checked):
        if FreeCAD.activeDocument() is None:
            FreeCAD.newDocument()

        items = self.ui.partsTree.selectedItems()

        if len(items) < 1:
            return

        data = unpack(items[0].data(0, 32))

        if isinstance(data, ClassName):
            cl = self.repo.class_names.get_src(data)
        elif isinstance(data, ClassStandard):
            cl = self.repo.class_standards.get_src(data)
        else:
            return

        params = {}
        # read parameters from widgets
        for key in self.param_widgets:
            params[key] = self.param_widgets[key].getValue()
        params = cl.parameters.collect(params)

        params['name'] = data.labeling.get_nice(params)

        lengths = {"Length (mm)": "mm", "Length (in)": "in"}

        for key, tp in cl.parameters.types.items():
            if tp in lengths:
                if params[key] is None:
                    # A undefined value is not necessarily fatal
                    continue
                if hasattr(FreeCAD.Units, "parseQuantity"):
                    params[key] = FreeCAD.Units.parseQuantity(
                        "%g %s" % (params[key], lengths[tp])).Value
                else:
                    params[key] = FreeCAD.Units.translateUnit(
                        "%g %s" % (params[key], lengths[tp]))

        # add part
        try:
            base = self.dbs["freecad"].base_classes.get_src(cl)
            coll = self.repo.collection_classes.get_src(cl)
            add_part(coll, base, params, FreeCAD.ActiveDocument)
            FreeCADGui.SendMsgToActiveView("ViewFit")
            FreeCAD.ActiveDocument.recompute()
        except ValueError as e:
            QtGui.QErrorMessage(self).showMessage(str(e))
        except Exception as e:
            FreeCAD.Console.PrintMessage(e)
            QtGui.QErrorMessage(self).showMessage(
                "An error occurred when trying to add the part: "
                "%s\nParameter Values: %s" % (e, params))

    @Slot()
    def on_partsTree_itemSelectionChanged(self):
        items = self.ui.partsTree.selectedItems()
        if len(items) < 1:
            return
        item = items[0]
        data = unpack(item.data(0, 32))

        # clear props widget
        for widget in self.props_widgets:
            self.ui.props_layout.removeWidget(widget)
            widget.setParent(None)
        self.props_widgets = []
        # clear
        for key in self.param_widgets:
            self.ui.param_layout.removeWidget(self.param_widgets[key])
            self.param_widgets[key].setParent(None)
        self.param_widgets = {}

        if isinstance(data, ClassName):
            self.setup_props_name(data)
            cl = self.repo.class_names.get_src(data)
            base = self.dbs["freecad"].base_classes.get_src(cl)
            print(self.dbs["freecad"])
            self.setup_param_widgets(cl, base)
        elif isinstance(data, ClassStandard):
            self.setup_props_standard(data)
            cl = self.repo.class_standards.get_src(data)
            base = self.dbs["freecad"].base_classes.get_src(cl)
            self.setup_param_widgets(cl, base)
        elif isinstance(data, Collection):
            self.setup_props_collection(data)
Esempio n. 4
0
class BoltsWidget(QBoltsWidget):
	def __init__(self,repo,freecad):
		QBoltsWidget.__init__(self)
		self.ui = Ui_BoltsWidget()
		self.ui.setupUi(self)

		self.repo = repo
		self.dbs = {}
		self.dbs["freecad"] = freecad

		self.param_widgets = {}
		self.props_widgets = {}

		self.coll_root = QtGui.QTreeWidgetItem(self.ui.partsTree,['Collections','Ordered by collections'])
		self.coll_root.setData(0,32,None)
		self.std_root = QtGui.QTreeWidgetItem(self.ui.partsTree,['Standard','Ordered by issueing body'])
		self.std_root.setData(0,32,None)

		#set up collections
		for coll, in self.repo.itercollections():
			coll_item = QtGui.QTreeWidgetItem(self.coll_root,[coll.name, coll.description])
			coll_item.setData(0,32,coll)

			multinames = {}
			multistds = {}

			#names
			for name,multiname in self.dbs["freecad"].iternames(['name','multiname'],filter_collection=coll):
				item = None
				if multiname is None:
					item = QtGui.QTreeWidgetItem(coll_item,[name.name.get_nice(), name.description])
				else:
					if not multiname in multinames:
						multinames[multiname] = QtGui.QTreeWidgetItem(coll_item,[multiname.group.get_nice(),""])
					item = QtGui.QTreeWidgetItem(multinames[multiname],[name.name.get_nice(), name.description])

				item.setData(0,32,name)

			#single names
			for std,multistd in self.dbs["freecad"].iterstandards(['standard','multistandard'],filter_collection = coll):
				item = None
				if multistd is None:
					item = QtGui.QTreeWidgetItem(coll_item,[std.standard.get_nice(), std.description])
				else:
					if not multistd in multistds:
						multistds[multistd] = QtGui.QTreeWidgetItem(coll_item,[multistd.standard.get_nice(),""])
					item = QtGui.QTreeWidgetItem(multistds[multistd],[std.standard.get_nice(), std.description])

				item.setData(0,32,std)

		multistds = {}

		#set up standards
		for body, in repo.iterbodies():
			std_item = QtGui.QTreeWidgetItem(self.std_root,[body.body, "Standards issued by %s" % body.body])
			std_item.setData(0,32,None)
			#single standards
			for std,multistd in self.dbs["freecad"].iterstandards(['standard','multistandard'], filter_body = body):
				if multistd is None:
					item = QtGui.QTreeWidgetItem(std_item,[std.standard.get_nice(), std.description])
				else:
					if not multistd in multistds:
						multistds[multistd] = QtGui.QTreeWidgetItem(std_item,[multistd.standard.get_nice(),""])
					item = QtGui.QTreeWidgetItem(multistds[multistd],[std.standard.get_nice(), std.description])

				item.setData(0,32,std)

		self.remove_empty_items(self.coll_root)

	def remove_empty_items(self,root_item):
		children = [root_item.child(i) for i in range(root_item.childCount())]
		for child in children:
			self.remove_empty_items(child)
			data = unpack(child.data(0,32))
			if not (isinstance(data,ClassName) or isinstance(data,ClassStandard)) and child.childCount() == 0:
				root_item.removeChild(child)

	def setup_param_widgets(self,cl,base):
		#construct widgets
		params = cl.parameters.union(base.parameters)

		for p in params.free:
			p_type = params.types[p]
			default = str(params.defaults[p])
			if p_type == "Length (mm)":
				self.param_widgets[p] = LengthWidget(self.ui.params,p + " (mm)",default)
			elif p_type == "Length (in)":
				self.param_widgets[p] = LengthWidget(self.ui.params,p + " (in)",default)
			elif p_type == "Number":
				self.param_widgets[p] = NumberWidget(self.ui.params,p,default)
			elif p_type == "Angle (deg)":
				self.param_widgets[p] = AngleWidget(self.ui.params,p + " (deg)",default)
			elif p_type == "Bool":
				self.param_widgets[p] = BoolWidget(self.ui.params,p,default)
			elif p_type == "Table Index":
				self.param_widgets[p] = TableIndexWidget(self.ui.params,p,params.choices[p],default)
			else:
				raise ValueError("Unknown type encountered for parameter %s: %s" % (p,p_type))
			self.param_widgets[p].setToolTip(params.description[p])
		#add them to layout
			self.ui.param_layout.addWidget(self.param_widgets[p])
		if base.type == "fcstd":
			self.ui.addButton.setText("Add part (may take a bit)")
		else:
			self.ui.addButton.setText("Add part")

	def setup_props_collection(self,coll):
		#construct widgets
		self.props_widgets.append(PropertyWidget(self.ui.props,"Name",coll.name))
		self.props_widgets.append(PropertyWidget(self.ui.props,"Description",coll.description))
		self.props_widgets.append(PropertyWidget(self.ui.props,"Authors",", ".join(coll.author_names)))
		self.props_widgets.append(PropertyWidget(self.ui.props,"License",coll.license_name))

		#add them to layout
		for widget in self.props_widgets:
			self.ui.props_layout.addWidget(widget)

	def setup_props_standard(self,std):
		#construct widgets
		self.props_widgets.append(PropertyWidget(self.ui.props,"Name",std.standard.get_nice()))
		if std.description:
			self.props_widgets.append(PropertyWidget(self.ui.props,"Description",std.description))
		if std.status == "withdrawn":
			self.props_widgets.append(PropertyWidget(self.ui.props,"Status","<font color='red'>%s</font>" % std.status))
		else:
			self.props_widgets.append(PropertyWidget(self.ui.props,"Status","<font color='green'>%s</font>" % std.status))
		if not std.replaces is None:
			self.props_widgets.append(PropertyWidget(self.ui.props,"Replaces",std.replaces))
		if not std.replacedby is None:
			self.props_widgets.append(PropertyWidget(self.ui.props,"Replacedby",std.replacedby))
		self.props_widgets.append(PropertyWidget(self.ui.props,"ID",std.get_id()))

		#add them to layout
		for widget in self.props_widgets:
			self.ui.props_layout.addWidget(widget)

	def setup_props_name(self,name):
		#construct widgets
		self.props_widgets.append(PropertyWidget(self.ui.props,"Name",name.name.get_nice()))
		if name.description:
			self.props_widgets.append(PropertyWidget(self.ui.props,"Description",name.description))
		self.props_widgets.append(PropertyWidget(self.ui.props,"ID",name.get_id()))

		#add them to layout
		for widget in self.props_widgets:
			self.ui.props_layout.addWidget(widget)

	@Slot(bool)
	def on_addButton_clicked(self,checked):
		if FreeCAD.activeDocument() is None:
			FreeCAD.newDocument()

		items = self.ui.partsTree.selectedItems()

		if len(items) < 1:
			return

		data = unpack(items[0].data(0,32))

		if isinstance(data,ClassName):
			cl = self.repo.class_names.get_src(data)
		elif isinstance(data,ClassStandard):
			cl = self.repo.class_standards.get_src(data)
		else:
			return

		params = {}
		#read parameters from widgets
		for key in self.param_widgets:
			params[key] = self.param_widgets[key].getValue()
		params = cl.parameters.collect(params)

		params['name'] = data.labeling.get_nice(params)

		lengths = {"Length (mm)" : "mm", "Length (in)" : "in"}

		for key,tp in cl.parameters.types.iteritems():
			if tp in lengths:
				if params[key] is None:
					#A undefined value is not necessarily fatal
					continue
				if hasattr(FreeCAD.Units, "parseQuantity"):
					params[key] = FreeCAD.Units.parseQuantity("%g %s" %
						(params[key], lengths[tp])).Value
				else:
					params[key] = FreeCAD.Units.translateUnit("%g %s" %
						(params[key], lengths[tp]))

		#add part
		try:
			base = self.dbs["freecad"].base_classes.get_src(cl)
			coll = self.repo.collection_classes.get_src(cl)
			add_part(coll,base,params,FreeCAD.ActiveDocument)
			FreeCADGui.SendMsgToActiveView("ViewFit")
			FreeCAD.ActiveDocument.recompute()
		except ValueError as e:
			QtGui.QErrorMessage(self).showMessage(str(e))
		except Exception as e:
			FreeCAD.Console.PrintMessage(e)
			QtGui.QErrorMessage(self).showMessage("An error occured when trying to add the part: %s\nParameter Values: %s" % (e,params))

	@Slot()
	def on_partsTree_itemSelectionChanged(self):
		items = self.ui.partsTree.selectedItems()
		if len(items) < 1:
			return
		item = items[0]
		data = unpack(item.data(0,32))

		#clear props widget
		for widget in self.props_widgets:
			self.ui.props_layout.removeWidget(widget)
			widget.setParent(None)
		self.props_widgets = []
		#clear
		for key in self.param_widgets:
			self.ui.param_layout.removeWidget(self.param_widgets[key])
			self.param_widgets[key].setParent(None)
		self.param_widgets = {}

		if isinstance(data,ClassName):
			self.setup_props_name(data)
			cl = self.repo.class_names.get_src(data)
			base = self.dbs["freecad"].base_classes.get_src(cl)
			self.setup_param_widgets(cl,base)
		elif isinstance(data,ClassStandard):
			self.setup_props_standard(data)
			cl = self.repo.class_standards.get_src(data)
			base = self.dbs["freecad"].base_classes.get_src(cl)
			self.setup_param_widgets(cl,base)
		elif isinstance(data,Collection):
			self.setup_props_collection(data)