From 496df34369330174b4e35067f7843308e50310b5 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Sat, 29 Sep 2018 16:40:51 -0300 Subject: [PATCH] Arch: Finished base implementation of Reference object --- src/Mod/Arch/ArchBuildingPart.py | 27 +++-- src/Mod/Arch/ArchReference.py | 112 ++++++++++++++++-- src/Mod/Arch/Resources/ui/preferences-arch.ui | 56 ++++++++- 3 files changed, 175 insertions(+), 20 deletions(-) diff --git a/src/Mod/Arch/ArchBuildingPart.py b/src/Mod/Arch/ArchBuildingPart.py index 713086df5b6a..06efa842a497 100644 --- a/src/Mod/Arch/ArchBuildingPart.py +++ b/src/Mod/Arch/ArchBuildingPart.py @@ -211,9 +211,9 @@ def makeBuildingPart(objectslist=None,baseobj=None,name="BuildingPart"): def makeFloor(objectslist=None,baseobj=None,name="Floor"): - + """overwrites ArchFloor.makeFloor""" - + obj = makeBuildingPart(objectslist) obj.Label = name obj.IfcRole = "Building Storey" @@ -221,9 +221,9 @@ def makeFloor(objectslist=None,baseobj=None,name="Floor"): def makeBuilding(objectslist=None,baseobj=None,name="Building"): - + """overwrites ArchBuilding.makeBuilding""" - + obj = makeBuildingPart(objectslist) obj.Label = name obj.IfcRole = "Building" @@ -396,17 +396,28 @@ def onChanged(self,obj,prop): def execute(self,obj): # gather all the child shapes into a compound - shapes = [] - for o in obj.Group: - if o.isDerivedFrom("Part::Feature") and o.Shape and (not o.Shape.isNull()): - shapes.append(o.Shape) + shapes = self.getShapes(obj) if shapes: import Part obj.Shape = Part.makeCompound(shapes) + def getShapes(self,obj): + + "recursively get the shapes of objects inside this BuildingPart" + + shapes = [] + if hasattr(obj,"Group"): + for child in obj.Group: + if child.isDerivedFrom("Part::Feature") and child.Shape and (not child.Shape.isNull()): + shapes.append(child.Shape) + elif hasattr(child,"Group"): + shapes.extend(self.getShapes(child)) + return shapes + def getSpaces(self,obj): "gets the list of Spaces that have this object as their Zone property" + g = [] for o in obj.OutList: if hasattr(o,"Zone"): diff --git a/src/Mod/Arch/ArchReference.py b/src/Mod/Arch/ArchReference.py index e82c4bdbdccc..ec1947bc2458 100644 --- a/src/Mod/Arch/ArchReference.py +++ b/src/Mod/Arch/ArchReference.py @@ -82,14 +82,15 @@ def __init__(self,obj): obj.Proxy = self ArchReference.setProperties(self,obj) self.Type = "Reference" + self.reload = True def setProperties(self,obj): pl = obj.PropertiesList if not "File" in pl: - obj.addProperty("App::PropertyFile","File","Component",QT_TRANSLATE_NOOP("App::Property","The base file this component is built upon")) + obj.addProperty("App::PropertyFile","File","Reference",QT_TRANSLATE_NOOP("App::Property","The base file this component is built upon")) if not "Part" in pl: - obj.addProperty("App::PropertyString","Part","Component",QT_TRANSLATE_NOOP("App::Property","The part to use from the base file")) + obj.addProperty("App::PropertyString","Part","Reference",QT_TRANSLATE_NOOP("App::Property","The part to use from the base file")) self.Type = "Reference" def onDocumentRestored(self,obj): @@ -104,9 +105,14 @@ def __setstate__(self,state): return None + def onChanged(self,obj,prop): + + if prop in ["File","Part"]: + self.reload = True + def execute(self,obj): - if obj.File and obj.Part: + if obj.File and obj.Part and self.reload: self.parts = self.getPartsList(obj) if self.parts: zdoc = zipfile.ZipFile(obj.File) @@ -122,7 +128,7 @@ def execute(self,obj): obj.Shape = shape else: print("Part not found in file") - return True + self.reload = False def getPartsList(self,obj,filename=None): @@ -171,6 +177,14 @@ class ViewProviderArchReference: def __init__(self,vobj): vobj.Proxy = self + self.setProperties(vobj) + + def setProperties(self,vobj): + + pl = vobj.PropertiesList + if not "TimeStamp" in pl: + vobj.addProperty("App::PropertyFloat","TimeStamp","Reference",QT_TRANSLATE_NOOP("App::Property","The latest time stamp of the linked file")) + vobj.setEditorMode("TimeStamp",2) def getIcon(self): @@ -188,6 +202,15 @@ def unsetEdit(self,vobj,mode): FreeCADGui.Control.closeDialog() return + def attach(self,vobj): + + self.Object = vobj.Object + # Check for file change every minute + self.timer = QtCore.QTimer() + self.timer.timeout.connect(self.checkChanges) + s = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch").GetInt("ReferenceCheckInterval",60) + self.timer.start(1000*s) + def doubleClicked(self,vobj): self.setEdit(vobj) @@ -200,6 +223,57 @@ def __setstate__(self,state): return None + def checkChanges(self): + + "checks if the linked file has changed" + + if hasattr(self,"Object") and self.Object: + try: + f = self.Object.File + except ReferenceError: + f = None + if hasattr(self,"timer"): + self.timer.stop() + del self.timer + if f: + st_mtime = os.stat(self.Object.File).st_mtime + if hasattr(self.Object.ViewObject,"TimeStamp"): + if self.Object.ViewObject.TimeStamp: + if self.Object.ViewObject.TimeStamp != st_mtime: + self.Object.Proxy.reload = True + self.Object.touch() + self.Object.ViewObject.TimeStamp = st_mtime + + def onDelete(self): + + self.timer.stop() + del self.timer + + def setupContextMenu(self,vobj,menu): + + action1 = QtGui.QAction(QtGui.QIcon(":/icons/view-refresh.svg"),"Reload reference",menu) + QtCore.QObject.connect(action1,QtCore.SIGNAL("triggered()"),self.onReload) + menu.addAction(action1) + action2 = QtGui.QAction(QtGui.QIcon(":/icons/document-open.svg"),"Open reference",menu) + QtCore.QObject.connect(action2,QtCore.SIGNAL("triggered()"),self.onOpen) + menu.addAction(action2) + + def onReload(self): + + "reloads the reference object" + + if hasattr(self,"Object") and self.Object: + self.Object.Proxy.reload = True + self.Object.touch() + FreeCAD.ActiveDocument.recompute() + + def onOpen(self): + + "opens the reference file" + + if hasattr(self,"Object") and self.Object: + if self.Object.File: + FreeCAD.openDocument(self.Object.File) class ArchReferenceTaskPanel: @@ -217,7 +291,14 @@ def __init__(self,obj): label1 = QtGui.QLabel("External file:") layout.addWidget(label1) self.fileButton = QtGui.QPushButton(self.form) - layout.addWidget(self.fileButton) + self.openButton = QtGui.QPushButton(self.form) + self.openButton.setText("Open") + if not self.obj.File: + self.openButton.setEnabled(False) + l2 = QtGui.QHBoxLayout(self.form) + layout.addLayout(l2) + l2.addWidget(self.fileButton) + l2.addWidget(self.openButton) label2 = QtGui.QLabel("Part to use:") layout.addWidget(label2) if self.obj.File: @@ -230,12 +311,13 @@ def __init__(self,obj): parts = self.obj.Proxy.parts else: parts = self.obj.Proxy.getPartsList(self.obj) - keys = parts.keys() + keys = parts.keys() self.partCombo.addItems(keys) if self.obj.Part: if self.obj.Part in keys: self.partCombo.setCurrentIndex(keys.index(self.obj.Part)) QtCore.QObject.connect(self.fileButton, QtCore.SIGNAL("clicked()"), self.chooseFile) + QtCore.QObject.connect(self.openButton, QtCore.SIGNAL("clicked()"), self.openFile) def chooseFile(self): @@ -255,12 +337,21 @@ def chooseFile(self): if self.obj.Part in keys: self.partCombo.setCurrentIndex(keys.index(self.obj.Part)) + def openFile(self): + if self.obj.File: + FreeCAD.openDocument(self.obj.File) + FreeCADGui.Control.closeDialog() + def accept(self): - if self.filename and self.partCombo.currentText(): - self.obj.File = self.filename - self.obj.Part = self.partCombo.currentText() - FreeCAD.ActiveDocument.recompute() + if self.filename: + if self.filename != self.obj.File: + self.obj.File = self.filename + FreeCAD.ActiveDocument.recompute() + if self.partCombo.currentText(): + if self.partCombo.currentText() != self.obj.Part: + self.obj.Part = self.partCombo.currentText() + FreeCAD.ActiveDocument.recompute() return True @@ -274,6 +365,7 @@ def GetResources(self): return {'Pixmap' : 'Arch_Reference', 'MenuText': QtCore.QT_TRANSLATE_NOOP("Arch_Reference","External reference"), + 'Accel': "E, X", 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Arch_Reference","Creates an external reference object")} def IsActive(self): diff --git a/src/Mod/Arch/Resources/ui/preferences-arch.ui b/src/Mod/Arch/Resources/ui/preferences-arch.ui index 31dd1c4ca574..4ec36883931a 100644 --- a/src/Mod/Arch/Resources/ui/preferences-arch.ui +++ b/src/Mod/Arch/Resources/ui/preferences-arch.ui @@ -6,8 +6,8 @@ 0 0 - 428 - 703 + 446 + 792 @@ -113,6 +113,9 @@ Qt::Horizontal + + QSizePolicy::Fixed + 20 @@ -146,6 +149,55 @@ + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + Interval between file checks for references + + + + + + + seconds + + + 1 + + + 9999 + + + 60 + + + ReferenceCheckInterval + + + Mod/Arch + + + + +