From d031163551b10cd7bfb1eb2da7ce99c15d9f7b38 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Sat, 31 Aug 2013 13:01:26 -0300 Subject: [PATCH] Arch: Arch creation tools are now active even when selection is empty --- src/Mod/Arch/ArchComponent.py | 38 ++++++++++++++++-- src/Mod/Arch/ArchRoof.py | 12 +++--- src/Mod/Arch/ArchSpace.py | 45 ++++++++++----------- src/Mod/Arch/ArchWindow.py | 74 +++++++++++++++++++++-------------- 4 files changed, 106 insertions(+), 63 deletions(-) diff --git a/src/Mod/Arch/ArchComponent.py b/src/Mod/Arch/ArchComponent.py index 9875ac7960..f6bc681435 100644 --- a/src/Mod/Arch/ArchComponent.py +++ b/src/Mod/Arch/ArchComponent.py @@ -105,6 +105,22 @@ def removeFromComponent(compobject,subobject): compobject.Subtractions = l if Draft.getType(subobject) != "Window": subobject.ViewObject.hide() + + +class SelectionTaskPanel: + """A temp taks panel to wait for a selection""" + def __init__(self): + self.form = QtGui.QLabel() + self.form.setText(QtGui.QApplication.translate("Arch", "Please select a base object", None, QtGui.QApplication.UnicodeUTF8)) + + def getStandardButtons(self): + return int(QtGui.QDialogButtonBox.Cancel) + + def reject(self): + if hasattr(FreeCAD,"ArchObserver"): + FreeCADGui.Selection.removeObserver(FreeCAD.ArchObserver) + del FreeCAD.ArchObserver + return True class ComponentTaskPanel: @@ -467,18 +483,32 @@ class ViewProviderComponent: return False class ArchSelectionObserver: - def __init__(self,origin,watched,hide=True,nextCommand=None): + """ArchSelectionObserver([origin,watched,hide,nextCommand]): The ArchSelectionObserver + object can be added as a selection observer to the FreeCAD Gui. If watched is given (a + document object), the observer will be triggered only when that object is selected/unselected. + If hide is True, the watched object will be hidden. If origin is given (a document + object), that object will have its visibility/selectability restored. If nextCommand + is given (a FreeCAD command), it will be executed on leave.""" + + def __init__(self,origin=None,watched=None,hide=True,nextCommand=None): self.origin = origin self.watched = watched self.hide = hide self.nextCommand = nextCommand + def addSelection(self,document, object, element, position): - if object == self.watched.Name: + if not self.watched: + FreeCADGui.Selection.removeObserver(FreeCAD.ArchObserver) + if self.nextCommand: + FreeCADGui.runCommand(self.nextCommand) + del FreeCAD.ArchObserver + elif object == self.watched.Name: if not element: FreeCAD.Console.PrintMessage(str(translate("Arch","closing Sketch edit"))) if self.hide: - self.origin.ViewObject.Transparency = 0 - self.origin.ViewObject.Selectable = True + if self.origin: + self.origin.ViewObject.Transparency = 0 + self.origin.ViewObject.Selectable = True self.watched.ViewObject.hide() FreeCADGui.activateWorkbench("ArchWorkbench") FreeCADGui.Selection.removeObserver(FreeCAD.ArchObserver) diff --git a/src/Mod/Arch/ArchRoof.py b/src/Mod/Arch/ArchRoof.py index 8b20daf5a9..505a0a915e 100644 --- a/src/Mod/Arch/ArchRoof.py +++ b/src/Mod/Arch/ArchRoof.py @@ -52,17 +52,12 @@ class _CommandRoof: 'Accel': "R, F", 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Arch_Roof","Creates a roof object from the selected face of an object")} - def IsActive(self): - if FreeCADGui.Selection.getSelection(): - return True - else: - return False - def Activated(self): sel = FreeCADGui.Selection.getSelectionEx() if sel: sel = sel[0] obj = sel.Object + FreeCADGui.Control.closeDialog() if sel.HasSubObjects: if "Face" in sel.SubElementNames[0]: idx = int(sel.SubElementNames[0][4:]) @@ -83,7 +78,10 @@ class _CommandRoof: else: FreeCAD.Console.PrintMessage(str(translate("Arch","Unable to create a roof"))) else: - FreeCAD.Console.PrintMessage(str(translate("Arch","No object selected"))) + FreeCAD.Console.PrintMessage(str(translate("Arch","Please select a base object\n"))) + FreeCADGui.Control.showDialog(ArchComponent.SelectionTaskPanel()) + FreeCAD.ArchObserver = ArchComponent.ArchSelectionObserver(nextCommand="Arch_Roof") + FreeCADGui.Selection.addObserver(FreeCAD.ArchObserver) class _Roof(ArchComponent.Component): "The Roof object" diff --git a/src/Mod/Arch/ArchSpace.py b/src/Mod/Arch/ArchSpace.py index c7468bdeb7..d3161e555f 100644 --- a/src/Mod/Arch/ArchSpace.py +++ b/src/Mod/Arch/ArchSpace.py @@ -25,22 +25,21 @@ import FreeCAD,FreeCADGui,ArchComponent,ArchCommands,math,Draft from DraftTools import translate from PyQt4 import QtCore -def makeSpace(objects): - """makeSpace(objects): Creates a space object from the given objects. Objects can be one +def makeSpace(objects=None): + """makeSpace([objects]): Creates a space object from the given objects. Objects can be one document object, in which case it becomes the base shape of the space object, or a list of selection objects as got from getSelectionEx(), or a list of tuples (object, subobjectname)""" - if not objects: - return - if not isinstance(objects,list): - objects = [objects] obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Space") _Space(obj) _ViewProviderSpace(obj.ViewObject) - if len(objects) == 1: - obj.Base = objects[0] - objects[0].ViewObject.hide() - else: - obj.Proxy.addSubobjects(obj,objects) + if objects: + if not isinstance(objects,list): + objects = [objects] + if len(objects) == 1: + obj.Base = objects[0] + objects[0].ViewObject.hide() + else: + obj.Proxy.addSubobjects(obj,objects) def addSpaceBoundaries(space,subobjects): """addSpaceBoundaries(space,subobjects): adds the given subobjects to the given space""" @@ -68,21 +67,23 @@ class _CommandSpace: 'Accel': "S, P", 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Arch_Space","Creates a space object from selected boundary objects")} - def IsActive(self): - if FreeCADGui.Selection.getSelection(): - return True - else: - return False - def Activated(self): FreeCAD.ActiveDocument.openTransaction(str(translate("Arch","Create Space"))) FreeCADGui.doCommand("import Arch") - if len(FreeCADGui.Selection.getSelection()) == 1: - FreeCADGui.doCommand("Arch.makeSpace(FreeCADGui.Selection.getSelection())") + sel = FreeCADGui.Selection.getSelection() + if sel: + FreeCADGui.Control.closeDialog() + if len(sel) == 1: + FreeCADGui.doCommand("Arch.makeSpace(FreeCADGui.Selection.getSelection())") + else: + FreeCADGui.doCommand("Arch.makeSpace(FreeCADGui.Selection.getSelectionEx())") + FreeCAD.ActiveDocument.commitTransaction() + FreeCAD.ActiveDocument.recompute() else: - FreeCADGui.doCommand("Arch.makeSpace(FreeCADGui.Selection.getSelectionEx())") - FreeCAD.ActiveDocument.commitTransaction() - FreeCAD.ActiveDocument.recompute() + FreeCAD.Console.PrintMessage(str(translate("Arch","Please select a base object\n"))) + FreeCADGui.Control.showDialog(ArchComponent.SelectionTaskPanel()) + FreeCAD.ArchObserver = ArchComponent.ArchSelectionObserver(nextCommand="Arch_Space") + FreeCADGui.Selection.addObserver(FreeCAD.ArchObserver) class _Space(ArchComponent.Component): diff --git a/src/Mod/Arch/ArchWindow.py b/src/Mod/Arch/ArchWindow.py index c3d72f30a1..ab58b74a9a 100644 --- a/src/Mod/Arch/ArchWindow.py +++ b/src/Mod/Arch/ArchWindow.py @@ -51,7 +51,7 @@ def makeWindow(baseobj=None,width=None,name=str(translate("Arch","Window"))): if obj.Base: obj.Base.ViewObject.DisplayMode = "Wireframe" obj.Base.ViewObject.hide() - obj.ViewObject.ShapeColor = ArchCommands.getDefaultColor("Window") + #obj.ViewObject.ShapeColor = ArchCommands.getDefaultColor("Window") return obj def makeDefaultWindowPart(obj): @@ -77,38 +77,40 @@ class _CommandWindow: 'Accel': "W, N", 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Arch_Window","Creates a window object from a selected object (wire, rectangle or sketch)")} - def IsActive(self): - if FreeCADGui.Selection.getSelection(): - return True - else: - return False - def Activated(self): sel = FreeCADGui.Selection.getSelection() if sel: - if Draft.getType(sel[0]) == "Wall": + obj = sel[0] + if Draft.getType(obj) == "Wall": FreeCADGui.activateWorkbench("SketcherWorkbench") FreeCADGui.runCommand("Sketcher_NewSketch") - FreeCAD.ArchObserver = ArchComponent.ArchSelectionObserver(sel[0],FreeCAD.ActiveDocument.Objects[-1],hide=False,nextCommand="Arch_Window") + FreeCAD.ArchObserver = ArchComponent.ArchSelectionObserver(obj,FreeCAD.ActiveDocument.Objects[-1],hide=False,nextCommand="Arch_Window") FreeCADGui.Selection.addObserver(FreeCAD.ArchObserver) else: + FreeCADGui.Control.closeDialog() FreeCAD.ActiveDocument.openTransaction(str(translate("Arch","Create Window"))) FreeCADGui.doCommand("import Arch") - for obj in sel: - FreeCADGui.doCommand("Arch.makeWindow(FreeCAD.ActiveDocument."+obj.Name+")") - if hasattr(obj,"Support"): - if obj.Support: - if isinstance(obj.Support,tuple): - s = obj.Support[0] - else: - s = obj.Support - w = FreeCAD.ActiveDocument.Objects[-1] # last created object - FreeCADGui.doCommand("Arch.removeComponents(FreeCAD.ActiveDocument."+w.Name+",host=FreeCAD.ActiveDocument."+s.Name+")") - elif Draft.isClone(obj,"Window"): - if obj.Objects[0].Inlist: - FreeCADGui.doCommand("Arch.removeComponents(FreeCAD.ActiveDocument."+obj.Name+",host=FreeCAD.ActiveDocument."+obj.Objects[0].Inlist[0].Name+")") + FreeCADGui.doCommand("Arch.makeWindow(FreeCAD.ActiveDocument."+obj.Name+")") + if hasattr(obj,"Support"): + if obj.Support: + if isinstance(obj.Support,tuple): + s = obj.Support[0] + else: + s = obj.Support + w = FreeCAD.ActiveDocument.Objects[-1] # last created object + FreeCADGui.doCommand("Arch.removeComponents(FreeCAD.ActiveDocument."+w.Name+",host=FreeCAD.ActiveDocument."+s.Name+")") + elif Draft.isClone(obj,"Window"): + if obj.Objects[0].Inlist: + FreeCADGui.doCommand("Arch.removeComponents(FreeCAD.ActiveDocument."+obj.Name+",host=FreeCAD.ActiveDocument."+obj.Objects[0].Inlist[0].Name+")") FreeCAD.ActiveDocument.commitTransaction() - + FreeCAD.ActiveDocument.recompute() + else: + FreeCAD.Console.PrintMessage(str(translate("Arch","Please select a base object\n"))) + FreeCADGui.Control.showDialog(ArchComponent.SelectionTaskPanel()) + FreeCAD.ArchObserver = ArchComponent.ArchSelectionObserver(nextCommand="Arch_Window") + FreeCADGui.Selection.addObserver(FreeCAD.ArchObserver) + + class _Window(ArchComponent.Component): "The Window object" def __init__(self,obj): @@ -122,6 +124,7 @@ class _Window(ArchComponent.Component): self.createGeometry(obj) def onChanged(self,obj,prop): + print prop self.hideSubobjects(obj,prop) if prop in ["Base","WindowParts"]: self.createGeometry(obj) @@ -170,6 +173,11 @@ class _Window(ArchComponent.Component): base = Part.makeCompound(shapes) if not DraftGeomUtils.isNull(pl): base.Placement = pl + elif not obj.WindowParts: + # create default parts + obj.WindowParts = makeDefaultWindowPart(obj.Base) + else: + print "Arch: Bad formatting of window parts definitions" base = self.processSubShapes(obj,base) if base: @@ -188,12 +196,16 @@ class _ViewProviderWindow(ArchComponent.ViewProviderComponent): def updateData(self,obj,prop): if (prop in ["WindowParts","Shape"]) and obj.ViewObject: - self.colorize(obj) + if obj.Shape: + if not obj.Shape.isNull(): + self.colorize(obj) def onChanged(self,vobj,prop): if (prop == "DiffuseColor") and vobj.Object: if len(vobj.DiffuseColor) < 2: - self.colorize(vobj.Object) + if vobj.Object.Shape: + if not vobj.Object.Shape.isNull(): + self.colorize(vobj.Object) def setEdit(self,vobj,mode): taskd = _ArchWindowTaskPanel() @@ -217,20 +229,22 @@ class _ViewProviderWindow(ArchComponent.ViewProviderComponent): def colorize(self,obj): "setting different part colors" - print "Colorizing ", obj.Shape.Solids + solids = obj.Shape.copy().Solids + #print "Colorizing ", solids colors = [] base = obj.ViewObject.ShapeColor - for i in range(len(obj.Shape.Solids)): + for i in range(len(solids)): ccol = base typeidx = (i*5)+1 if typeidx < len(obj.WindowParts): typ = obj.WindowParts[typeidx] if typ == WindowPartTypes[2]: # transparent parts ccol = ArchCommands.getDefaultColor("WindowGlass") - for f in obj.Shape.Solids[i].Faces: + for f in solids[i].Faces: colors.append(ccol) - print "colors: ",colors - obj.ViewObject.DiffuseColor = colors + #print "colors: ",colors + if colors: + obj.ViewObject.DiffuseColor = colors class _ArchWindowTaskPanel: '''The TaskPanel for Arch Windows'''