diff --git a/src/Mod/Arch/ArchWall.py b/src/Mod/Arch/ArchWall.py index 8bc238b09c..2d7b0313db 100644 --- a/src/Mod/Arch/ArchWall.py +++ b/src/Mod/Arch/ArchWall.py @@ -32,7 +32,8 @@ __url__ = "http://free-cad.sourceforge.net" def makeWall(baseobj=None,width=None,height=None,align="Center",name="Wall"): '''makeWall(obj,[width],[height],[align],[name]): creates a wall based on the - given object''' + given object, which can be a sketch, a draft object, a face or a solid. align + can be "Center","Left" or "Right"''' obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython",name) _Wall(obj) _ViewProviderWall(obj.ViewObject) @@ -55,6 +56,8 @@ def joinWalls(walls): return None if not isinstance(walls,list): walls = [walls] + if not areSameWallTypes(walls): + return None base = walls.pop() if base.Base: if base.Base.Shape.Faces: @@ -63,9 +66,8 @@ def joinWalls(walls): sk = base.Base else: sk = Draft.makeSketch(base.Base,autoconstraints=True) - old = base.Base.name - base.Base = sk - FreeCAD.ActiveDocument.removeObject(old) + if sk: + base.Base = sk for w in walls: if w.Base: if not base.Base.Shape.Faces: @@ -74,6 +76,24 @@ def joinWalls(walls): FreeCAD.ActiveDocument.recompute() return base +def areSameWallTypes(walls): + "returns True is all the walls in the given list have same height, width, and alignment" + for att in ["Width","Height","Align"]: + value = None + for w in walls: + if not hasattr(w,att): + return False + if not value: + value = getattr(w,att) + else: + if type(value) == float: + if round(value,Draft.precision()) != round(getattr(w,att),Draft.precision()): + return False + else: + if value != getattr(w,att): + return False + return True + class _CommandWall: "the Arch Wall command definition" def GetResources(self): @@ -83,6 +103,14 @@ class _CommandWall: 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Arch_Wall","Creates a wall object from scratch or from a selected object (wire, face or solid)")} def Activated(self): + + global QtGui, QtCore + from PyQt4 import QtGui, QtCore + + self.Width = 0.1 + self.Height = 1 + self.Align = "Center" + sel = FreeCADGui.Selection.getSelection() done = False self.existing = [] @@ -98,7 +126,7 @@ class _CommandWall: import DraftTrackers self.points = [] self.tracker = DraftTrackers.boxTracker() - FreeCADGui.Snapper.getPoint(callback=self.getPoint) + FreeCADGui.Snapper.getPoint(callback=self.getPoint,extradlg=self.taskbox()) def getPoint(self,point=None,obj=None): "this function is called by the snapper when it has a 3D point" @@ -112,26 +140,92 @@ class _CommandWall: self.points.append(point) if len(self.points) == 1: self.tracker.on() - FreeCADGui.Snapper.getPoint(last=self.points[0],callback=self.getPoint,movecallback=self.update) + FreeCADGui.Snapper.getPoint(last=self.points[0],callback=self.getPoint,movecallback=self.update,extradlg=self.taskbox()) elif len(self.points) == 2: import Part l = Part.Line(self.points[0],self.points[1]) self.tracker.finalize() FreeCAD.ActiveDocument.openTransaction("Wall") if not self.existing: - s = FreeCAD.ActiveDocument.addObject("Sketcher::SketchObject","WallTrace") - s.addGeometry(l) - makeWall(s) + self.addDefault(l) else: w = joinWalls(self.existing) - w.Base.addGeometry(l) + if w: + if areSameWallTypes([w,self]): + w.Base.addGeometry(l) + else: + self.addDefault(l) + else: + self.addDefault(l) FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() + def addDefault(self,l): + s = FreeCAD.ActiveDocument.addObject("Sketcher::SketchObject","WallTrace") + s.addGeometry(l) + makeWall(s,width=self.Width,height=self.Height,align=self.Align) + def update(self,point): "this function is called by the Snapper when the mouse is moved" - self.tracker.update([self.points[0],point]) - + b = self.points[0] + n = FreeCAD.DraftWorkingPlane.axis + bv = point.sub(b) + dv = bv.cross(n) + dv = fcvec.scaleTo(dv,self.Width/2) + if self.Align == "Center": + self.tracker.update([b,point]) + elif self.Align == "Left": + self.tracker.update([b.add(dv),point.add(dv)]) + else: + dv = fcvec.neg(dv) + self.tracker.update([b.add(dv),point.add(dv)]) + + def taskbox(self): + "sets up a taskbox widget" + w = QtGui.QWidget() + w.setWindowTitle("Wall options") + lay0 = QtGui.QVBoxLayout(w) + lay1 = QtGui.QHBoxLayout() + lay0.addLayout(lay1) + label1 = QtGui.QLabel("Width") + lay1.addWidget(label1) + value1 = QtGui.QDoubleSpinBox() + value1.setDecimals(2) + value1.setValue(self.Width) + lay1.addWidget(value1) + lay2 = QtGui.QHBoxLayout() + lay0.addLayout(lay2) + label2 = QtGui.QLabel("Height") + lay2.addWidget(label2) + value2 = QtGui.QDoubleSpinBox() + value2.setDecimals(2) + value2.setValue(self.Height) + lay2.addWidget(value2) + lay3 = QtGui.QHBoxLayout() + lay0.addLayout(lay3) + label3 = QtGui.QLabel("Alignment") + lay3.addWidget(label3) + value3 = QtGui.QComboBox() + items = ["Center","Left","Right"] + value3.addItems(items) + value3.setCurrentIndex(items.index(self.Align)) + lay3.addWidget(value3) + QtCore.QObject.connect(value1,QtCore.SIGNAL("valueChanged(double)"),self.setWidth) + QtCore.QObject.connect(value2,QtCore.SIGNAL("valueChanged(double)"),self.setHeight) + QtCore.QObject.connect(value3,QtCore.SIGNAL("currentIndexChanged(int)"),self.setAlign) + return w + + def setWidth(self,d): + self.Width = d + self.tracker.width(d) + + def setHeight(self,d): + self.Height = d + self.tracker.height(d) + + def setAlign(self,i): + self.Align = ["Center","Left","Right"][i] + class _Wall(ArchComponent.Component): "The Wall object" def __init__(self,obj): @@ -258,10 +352,5 @@ class _ViewProviderWall(ArchComponent.ViewProviderComponent): def getIcon(self): return ":/icons/Arch_Wall_Tree.svg" - -class TaskArchWall: - def __init__(self): - from PyQt4 import QtGui - self.form = QtGui.QWidget() FreeCADGui.addCommand('Arch_Wall',_CommandWall()) diff --git a/src/Mod/Draft/DraftGui.py b/src/Mod/Draft/DraftGui.py index 706d4d54ad..831220e514 100644 --- a/src/Mod/Draft/DraftGui.py +++ b/src/Mod/Draft/DraftGui.py @@ -136,8 +136,14 @@ class DraftLineEdit(QtGui.QLineEdit): QtGui.QLineEdit.keyPressEvent(self, event) class DraftTaskPanel: - def __init__(self,widget): - self.form = widget + def __init__(self,widget,extra=None): + if extra: + if isinstance(extra,list): + self.form = [widget] + extra + else: + self.form = [widget,extra] + else: + self.form = widget def getStandardButtons(self): return int(QtGui.QDialogButtonBox.Cancel) def accept(self): @@ -318,21 +324,6 @@ class DraftToolBar: self.resetPlaneButton = self._pushbutton("none", self.layout) self.isCopy = self._checkbox("isCopy",self.layout,checked=False) - # options buttons for other workbenches - - op1 = QtGui.QHBoxLayout() - self.layout.addLayout(op1) - self.labelop1 = self._label("labelop1", op1) - self.valueop1 = self._lineedit("valueop1", op1) - op2 = QtGui.QHBoxLayout() - self.layout.addLayout(op2) - self.labelop2 = self._label("labelop2", op2) - self.valueop2 = self._lineedit("valueop2", op2) - op3 = QtGui.QHBoxLayout() - self.layout.addLayout(op3) - self.labelop3 = self._label("labelop3", op3) - self.valueop3 = self._combo("valueop3", op3) - # spacer if not self.taskmode: spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, @@ -485,19 +476,17 @@ class DraftToolBar: # Interface modes #--------------------------------------------------------------------------- - def taskUi(self,title,): + def taskUi(self,title,extra=None): if self.taskmode: self.isTaskOn = True todo.delay(FreeCADGui.Control.closeDialog,None) self.baseWidget = QtGui.QWidget() - self.setTitle(title) self.layout = QtGui.QVBoxLayout(self.baseWidget) self.setupToolBar(task=True) self.retranslateUi(self.baseWidget) - self.panel = DraftTaskPanel(self.baseWidget) + self.panel = DraftTaskPanel(self.baseWidget,extra) todo.delay(FreeCADGui.Control.showDialog,self.panel) - else: - self.setTitle(title) + self.setTitle(title) def selectPlaneUi(self): self.taskUi(translate("draft", "Select Plane")) @@ -535,7 +524,7 @@ class DraftToolBar: def pointUi(self,title=translate("draft","Point"),cancel=None,extra=None,getcoords=None,rel=False): if cancel: self.cancel = cancel if getcoords: self.pointcallback = getcoords - self.taskUi(title) + self.taskUi(title,extra) self.xValue.setEnabled(True) self.yValue.setEnabled(True) self.labelx.setText(translate("draft", "X")) @@ -546,7 +535,6 @@ class DraftToolBar: self.yValue.show() self.zValue.show() if rel: self.isRelative.show() - if extra: self.extraUi(extra) self.xValue.setFocus() self.xValue.selectAll() @@ -601,12 +589,6 @@ class DraftToolBar: self.textValue.hide() self.continueCmd.hide() self.occOffset.hide() - self.labelop1.hide() - self.valueop1.hide() - self.labelop2.hide() - self.valueop2.hide() - self.labelop3.hide() - self.valueop3.hide() def trimUi(self,title=translate("draft","Trim")): self.taskUi(title) diff --git a/src/Mod/Draft/DraftSnap.py b/src/Mod/Draft/DraftSnap.py index 1022043b09..bb7fa09f0b 100644 --- a/src/Mod/Draft/DraftSnap.py +++ b/src/Mod/Draft/DraftSnap.py @@ -648,7 +648,7 @@ class Snapper: FreeCADGui.Snapper.getPoint(callback=cb) If the callback function accepts more than one argument, it will also receive - the last snapped object.Finally, a task dialog can be passed as extradlg.""" + the last snapped object. Finally, a pyqt dialog can be passed as extra taskbox.""" import inspect @@ -713,8 +713,8 @@ class Snapper: if callback: callback(None) - # adding 2 callback functions - self.ui.pointUi(cancel=cancel,getcoords=getcoords,rel=bool(last)) + # adding callback functions + self.ui.pointUi(cancel=cancel,getcoords=getcoords,extra=extradlg,rel=bool(last)) self.callbackClick = self.view.addEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(),click) self.callbackMove = self.view.addEventCallbackPivy(coin.SoLocation2Event.getClassTypeId(),move) diff --git a/src/Mod/Draft/DraftTrackers.py b/src/Mod/Draft/DraftTrackers.py index 0fc5b3986a..1f954f2f70 100644 --- a/src/Mod/Draft/DraftTrackers.py +++ b/src/Mod/Draft/DraftTrackers.py @@ -680,7 +680,7 @@ class boxTracker(Tracker): else: return self.cube.width.getValue() - def heigth(self,h=None): + def height(self,h=None): if h: self.cube.depth.setValue(h) self.update()