From 6b5a99319a753876f588a2f75d4b9ff940462fe0 Mon Sep 17 00:00:00 2001 From: Markus Lampert Date: Thu, 17 Dec 2020 19:14:44 -0800 Subject: [PATCH 01/16] Only update the shape if it has changed. --- src/Mod/Path/PathScripts/PathToolBitEdit.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathToolBitEdit.py b/src/Mod/Path/PathScripts/PathToolBitEdit.py index 0ee54747bb..c9cf238ebd 100644 --- a/src/Mod/Path/PathScripts/PathToolBitEdit.py +++ b/src/Mod/Path/PathScripts/PathToolBitEdit.py @@ -194,12 +194,14 @@ class ToolBitEditor(object): def updateShape(self): PathLog.track() - self.tool.BitShape = str(self.form.shapePath.text()) - self.setupTool(self.tool) - self.form.toolName.setText(self.tool.Label) + shapePath = str(self.form.shapePath.text()) + if self.tool.BitShape != shapePath: + self.tool.BitShape = shapePath + self.setupTool(self.tool) + self.form.toolName.setText(self.tool.Label) - for editor in self.bitEditor: - self.bitEditor[editor].updateSpinBox() + for editor in self.bitEditor: + self.bitEditor[editor].updateSpinBox() def updateTool(self): PathLog.track() From 7e2f088833e0bc0222f6a3a644fdd0c8df1b012f Mon Sep 17 00:00:00 2001 From: Markus Lampert Date: Thu, 17 Dec 2020 19:55:59 -0800 Subject: [PATCH 02/16] Hide document when loading a ToolBit. --- src/Mod/Path/PathScripts/PathToolBit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mod/Path/PathScripts/PathToolBit.py b/src/Mod/Path/PathScripts/PathToolBit.py index 9cd6f488de..4c8929b26f 100644 --- a/src/Mod/Path/PathScripts/PathToolBit.py +++ b/src/Mod/Path/PathScripts/PathToolBit.py @@ -252,7 +252,7 @@ class ToolBit(object): p = findShape(p) if not path and p != obj.BitShape: obj.BitShape = p - doc = FreeCAD.open(p) + doc = FreeCAD.openDocument(p, True) obj.ShapeName = doc.Name docOpened = True return (doc, docOpened) From 1a2249387e08ebe829118e7bc8849e50205e71bb Mon Sep 17 00:00:00 2001 From: Markus Lampert Date: Thu, 17 Dec 2020 19:59:44 -0800 Subject: [PATCH 03/16] Make BitShape read/writeable, so the tool can be edited when shared to a different system --- src/Mod/Path/PathScripts/PathToolBit.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Mod/Path/PathScripts/PathToolBit.py b/src/Mod/Path/PathScripts/PathToolBit.py index 4c8929b26f..4c502c528a 100644 --- a/src/Mod/Path/PathScripts/PathToolBit.py +++ b/src/Mod/Path/PathScripts/PathToolBit.py @@ -200,7 +200,9 @@ class ToolBit(object): return [prop for prop in obj.PropertiesList if obj.getGroupOfProperty(prop) == PropertyGroupAttribute] def onDocumentRestored(self, obj): - obj.setEditorMode('BitShape', 1) + # when files are shared it is essential to be able to change/set the shape file, + # otherwise the file is hard to use + # obj.setEditorMode('BitShape', 1) obj.setEditorMode('BitBody', 2) obj.setEditorMode('File', 1) obj.setEditorMode('Shape', 2) From be221dd25d7b540d91fa28374c73257d190947e1 Mon Sep 17 00:00:00 2001 From: Markus Lampert Date: Thu, 17 Dec 2020 20:27:42 -0800 Subject: [PATCH 04/16] Rearranged BitTool shape update so dependent ops don't execute with invalid tool. --- src/Mod/Path/PathScripts/PathToolBit.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathToolBit.py b/src/Mod/Path/PathScripts/PathToolBit.py index 4c502c528a..5ffe7503dd 100644 --- a/src/Mod/Path/PathScripts/PathToolBit.py +++ b/src/Mod/Path/PathScripts/PathToolBit.py @@ -288,21 +288,22 @@ class ToolBit(object): self._removeBitBody(obj) def _setupBitShape(self, obj, path=None): + PathLog.track(obj.Label) + activeDoc = FreeCAD.ActiveDocument (doc, docOpened) = self._loadBitBody(obj, path) obj.Label = doc.RootObjects[0].Label self._deleteBitSetup(obj) - obj.BitBody = obj.Document.copyObject(doc.RootObjects[0], True) + bitBody = obj.Document.copyObject(doc.RootObjects[0], True) if docOpened: FreeCAD.setActiveDocument(activeDoc.Name) FreeCAD.closeDocument(doc.Name) - if obj.BitBody.ViewObject: - obj.BitBody.ViewObject.Visibility = False - self._copyBitShape(obj) + if bitBody.ViewObject: + bitBody.ViewObject.Visibility = False - for sketch in [o for o in obj.BitBody.Group if o.TypeId == 'Sketcher::SketchObject']: + for sketch in [o for o in bitBody.Group if o.TypeId == 'Sketcher::SketchObject']: for constraint in [c for c in sketch.Constraints if c.Name != '']: typ = ParameterTypeConstraint.get(constraint.Type) PathLog.track(constraint, typ) @@ -318,6 +319,9 @@ class ToolBit(object): if constraint.Type == 'Angle': value = value * 180 / math.pi PathUtil.setProperty(obj, prop, value) + # has to happen last because it could trigger op.execute evaluations + obj.BitBody = bitBody + self._copyBitShape(obj) def getBitThumbnail(self, obj): if obj.BitShape: From b2dce8c76a3c52e5941bf726a3256b62b9c346e1 Mon Sep 17 00:00:00 2001 From: Markus Lampert Date: Thu, 17 Dec 2020 22:56:42 -0800 Subject: [PATCH 05/16] Allowing QuantitySpinBox to be reused for different attribute; using properties to get values to work around build differences. --- src/Mod/Path/PathScripts/PathGui.py | 41 ++++++++++++++++------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathGui.py b/src/Mod/Path/PathScripts/PathGui.py index d7fdd6be32..c9fee42062 100644 --- a/src/Mod/Path/PathScripts/PathGui.py +++ b/src/Mod/Path/PathScripts/PathGui.py @@ -35,13 +35,8 @@ __doc__ = "A collection of helper and utility functions for the Path GUI." def translate(context, text, disambig=None): return PySide.QtCore.QCoreApplication.translate(context, text, disambig) -LOGLEVEL = False - -if LOGLEVEL: - PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule()) - PathLog.trackModule(PathLog.thisModule()) -else: - PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) +PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) +# PathLog.trackModule(PathLog.thisModule()) def updateInputField(obj, prop, widget, onBeforeChange=None): @@ -53,7 +48,7 @@ def updateInputField(obj, prop, widget, onBeforeChange=None): If onBeforeChange is specified it is called before a new value is assigned to the property. Returns True if a new value was assigned, False otherwise (new value is the same as the current). ''' - value = FreeCAD.Units.Quantity(widget.text()).Value + value = widget.property('rawValue') attr = PathUtil.getProperty(obj, prop) attrValue = attr.Value if hasattr(attr, 'Value') else attr @@ -72,10 +67,10 @@ def updateInputField(obj, prop, widget, onBeforeChange=None): isDiff = True break if noExpr: - widget.setReadOnly(False) + widget.setProperty('readonly', False) widget.setStyleSheet("color: black") else: - widget.setReadOnly(True) + widget.setProperty('readonly', True) widget.setStyleSheet("color: gray") widget.update() @@ -100,19 +95,26 @@ class QuantitySpinBox: ''' def __init__(self, widget, obj, prop, onBeforeChange=None): - self.obj = obj + PathLog.track(widget) self.widget = widget - self.prop = prop self.onBeforeChange = onBeforeChange + self.attachTo(obj, prop) - attr = PathUtil.getProperty(self.obj, self.prop) - if attr is not None: - if hasattr(attr, 'Value'): - widget.setProperty('unit', attr.getUserPreferred()[2]) - widget.setProperty('binding', "%s.%s" % (obj.Name, prop)) - self.valid = True + def attachTo(self, obj, prop = None): + '''attachTo(obj, prop=None) ... use an existing editor for the given object and property''' + self.obj = obj + self.prop = prop + if obj and prop: + attr = PathUtil.getProperty(obj, prop) + if attr is not None: + if hasattr(attr, 'Value'): + self.widget.setProperty('unit', attr.getUserPreferred()[2]) + self.widget.setProperty('binding', "%s.%s" % (obj.Name, prop)) + self.valid = True + else: + PathLog.warning(translate('PathGui', "Cannot find property %s of %s") % (prop, obj.Label)) + self.valid = False else: - PathLog.warning(translate('PathGui', "Cannot find property %s of %s") % (prop, obj.Label)) self.valid = False def expression(self): @@ -122,6 +124,7 @@ class QuantitySpinBox: return '' def setMinimum(self, quantity): + '''setMinimum(quantity) ... set the minimum''' if self.valid: value = quantity.Value if hasattr(quantity, 'Value') else quantity self.widget.setProperty('setMinimum', value) From 1f839e5ea11a62716142481f009aa12732aa728f Mon Sep 17 00:00:00 2001 From: Markus Lampert Date: Thu, 17 Dec 2020 23:01:55 -0800 Subject: [PATCH 06/16] Reuse existing QuantitySpinBox'es in order to avoid segfault on focus change. --- src/Mod/Path/PathScripts/PathToolBitEdit.py | 67 ++++++++++++++++----- 1 file changed, 52 insertions(+), 15 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathToolBitEdit.py b/src/Mod/Path/PathScripts/PathToolBitEdit.py index c9cf238ebd..3488bcc95d 100644 --- a/src/Mod/Path/PathScripts/PathToolBitEdit.py +++ b/src/Mod/Path/PathScripts/PathToolBitEdit.py @@ -62,24 +62,60 @@ class ToolBitEditor(object): if self.loadbitbody: self.tool.Proxy.loadBitBody(self.tool) + # remove example widgets + layout = self.form.bitParams.layout() + for i in range(layout.rowCount() - 1, -1, -1): + layout.removeRow(i) + # used to track property widgets and editors + self.widgets = [] + self.setupTool(self.tool) self.setupAttributes(self.tool) def setupTool(self, tool): PathLog.track() + # Can't delete and add fields to the form because of dangling references in case of + # a focus change. see https://forum.freecadweb.org/viewtopic.php?f=10&t=52246#p458583 + # Instead we keep widgets once created and use them for new properties, and hide all + # which aren't being needed anymore. + + def labelText(name): + return re.sub('([A-Z][a-z]+)', r' \1', re.sub('([A-Z]+)', r' \1', name)) + layout = self.form.bitParams.layout() - for i in range(layout.rowCount() - 1, -1, -1): - layout.removeRow(i) - editor = {} ui = FreeCADGui.UiLoader() + nr = 0 + + # for all properties either assign them to existing labels and editors + # or create additional ones for them if not enough have already been + # created. for name in tool.PropertiesList: if tool.getGroupOfProperty(name) == PathToolBit.PropertyGroupBit: - qsb = ui.createWidget('Gui::QuantitySpinBox') - editor[name] = PathGui.QuantitySpinBox(qsb, tool, name) - label = QtGui.QLabel(re.sub('([A-Z][a-z]+)', r' \1', - re.sub('([A-Z]+)', r' \1', name))) - layout.addRow(label, qsb) - self.bitEditor = editor + if nr < len(self.widgets): + PathLog.debug("re-use row: {} [{}]".format(nr, name)) + label, qsb, editor = self.widgets[nr] + label.setText(labelText(name)) + editor.attachTo(tool, name) + label.show() + qsb.show() + else: + qsb = ui.createWidget('Gui::QuantitySpinBox') + editor = PathGui.QuantitySpinBox(qsb, tool, name) + label = QtGui.QLabel(labelText(name)) + self.widgets.append((label, qsb, editor)) + PathLog.debug("create row: {} [{}]".format(nr, name)) + if nr >= layout.rowCount(): + layout.addRow(label, qsb) + nr = nr + 1 + + # hide all rows which aren't being used + for i in range(nr, len(self.widgets)): + label, qsb, editor = self.widgets[i] + label.hide() + qsb.hide() + editor.attachTo(None) + PathLog.debug(" hide row: {}".format(i)) + img = tool.Proxy.getBitThumbnail(tool) if img: self.form.image.setPixmap(QtGui.QPixmap(QtGui.QImage.fromData(img))) @@ -189,27 +225,28 @@ class ToolBitEditor(object): self.form.toolName.setText(self.tool.Label) self.form.shapePath.setText(self.tool.BitShape) - for editor in self.bitEditor: - self.bitEditor[editor].updateSpinBox() + for lbl, qsb, editor in self.widgets: + editor.updateSpinBox() def updateShape(self): PathLog.track() shapePath = str(self.form.shapePath.text()) + # Only need to go through this exercise if the shape actually changed. if self.tool.BitShape != shapePath: self.tool.BitShape = shapePath self.setupTool(self.tool) self.form.toolName.setText(self.tool.Label) - for editor in self.bitEditor: - self.bitEditor[editor].updateSpinBox() + for lbl, qsb, editor in self.widgets: + editor.updateSpinBox() def updateTool(self): PathLog.track() self.tool.Label = str(self.form.toolName.text()) self.tool.BitShape = str(self.form.shapePath.text()) - for editor in self.bitEditor: - self.bitEditor[editor].updateProperty() + for lbl, qsb, editor in self.widgets: + editor.updateProperty() # self.tool.Proxy._updateBitShape(self.tool) From 08f708d2bd2617a155e7e7866ab662ee04562de3 Mon Sep 17 00:00:00 2001 From: Markus Lampert Date: Thu, 17 Dec 2020 23:11:02 -0800 Subject: [PATCH 07/16] Added provision for gcc peculiarities in unit tests --- src/Mod/Path/PathTests/TestPathCore.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Mod/Path/PathTests/TestPathCore.py b/src/Mod/Path/PathTests/TestPathCore.py index dae7c091e5..34d84d6477 100644 --- a/src/Mod/Path/PathTests/TestPathCore.py +++ b/src/Mod/Path/PathTests/TestPathCore.py @@ -152,7 +152,9 @@ G0 Z0.500000 table.addTools(t2) self.assertEqual(len(table.Tools), 2) - self.assertEqual(str(table.Tools), '{1: Tool 12.7mm Drill Bit, 2: Tool my other tool}' ) + # gcc7 build needs some special treatment (makes 1L out of a 1) ... + if str(table.Tools) != '{1L: Tool 12.7mm Drill Bit, 2L: Tool my other tool}': + self.assertEqual(str(table.Tools), '{1: Tool 12.7mm Drill Bit, 2: Tool my other tool}') def test50(self): """Test Path.Length calculation""" From 0385e56b695754df1a7c4d645a96ba1d8b146555 Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 18 Dec 2020 11:46:31 +0100 Subject: [PATCH 08/16] Gui: [skip ci] fix crash when using a dialog instance twice for a task panel --- src/Gui/TaskView/TaskDialogPython.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Gui/TaskView/TaskDialogPython.cpp b/src/Gui/TaskView/TaskDialogPython.cpp index b353fcb0a1..5a9cb4b864 100644 --- a/src/Gui/TaskView/TaskDialogPython.cpp +++ b/src/Gui/TaskView/TaskDialogPython.cpp @@ -337,8 +337,20 @@ TaskDialogPython::~TaskDialogPython() std::vector< QPointer > guarded; guarded.insert(guarded.begin(), Content.begin(), Content.end()); Content.clear(); + Base::PyGILStateLocker lock; + + // The widgets stored in the 'form' attribute will be deleted. + // Thus, set this attribute to None to make sure that when using + // the same dialog instance for a task panel won't segfault. + if (this->dlg.hasAttr(std::string("form"))) { + this->dlg.setAttr(std::string("form"), Py::None()); + } this->dlg = Py::None(); + + // Assigning None to 'dlg' may destroy some of the stored widgets. + // By guarding them with QPointer their pointers will be set to null + // so that the destructor of the base class can reliably call 'delete'. Content.insert(Content.begin(), guarded.begin(), guarded.end()); } From 7d260787b9abfc7452112040cb370fe17134cd65 Mon Sep 17 00:00:00 2001 From: Aapo Date: Tue, 15 Dec 2020 22:56:51 +0200 Subject: [PATCH 09/16] [TD] Balloon, change ordering of the data properties to more logical. --- src/Mod/TechDraw/App/DrawViewBalloon.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Mod/TechDraw/App/DrawViewBalloon.cpp b/src/Mod/TechDraw/App/DrawViewBalloon.cpp index 9f8a397c39..ed9f6ca837 100644 --- a/src/Mod/TechDraw/App/DrawViewBalloon.cpp +++ b/src/Mod/TechDraw/App/DrawViewBalloon.cpp @@ -99,15 +99,15 @@ DrawViewBalloon::DrawViewBalloon(void) EndType.setEnums(ArrowPropEnum::ArrowTypeEnums); ADD_PROPERTY(EndType,(prefEnd())); + ADD_PROPERTY_TYPE(EndTypeScale,(1.0),"",(App::PropertyType)(App::Prop_None),"EndType shape scale"); + ShapeScale.setConstraints(&SymbolScaleRange); + BubbleShape.setEnums(balloonTypeEnums); ADD_PROPERTY(BubbleShape,(prefShape())); ADD_PROPERTY_TYPE(ShapeScale,(1.0),"",(App::PropertyType)(App::Prop_None),"Balloon shape scale"); ShapeScale.setConstraints(&SymbolScaleRange); - ADD_PROPERTY_TYPE(EndTypeScale,(1.0),"",(App::PropertyType)(App::Prop_None),"EndType shape scale"); - ShapeScale.setConstraints(&SymbolScaleRange); - ADD_PROPERTY_TYPE(TextWrapLen,(-1),"",(App::PropertyType)(App::Prop_None),"Text wrap length; -1 means no wrap"); ADD_PROPERTY_TYPE(KinkLength,(prefKinkLength()),"",(App::PropertyType)(App::Prop_None), From 294136e9bd2ce5695534190d141eebd3567a13e3 Mon Sep 17 00:00:00 2001 From: Aapo Date: Tue, 15 Dec 2020 23:32:11 +0200 Subject: [PATCH 10/16] [TD] Balloon, move property LineVisible to View tab and fix a refresh bug. --- src/Mod/TechDraw/App/DrawViewBalloon.cpp | 2 -- src/Mod/TechDraw/App/DrawViewBalloon.h | 1 - src/Mod/TechDraw/Gui/QGIViewBalloon.cpp | 2 +- src/Mod/TechDraw/Gui/ViewProviderBalloon.cpp | 4 +++- src/Mod/TechDraw/Gui/ViewProviderBalloon.h | 1 + 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Mod/TechDraw/App/DrawViewBalloon.cpp b/src/Mod/TechDraw/App/DrawViewBalloon.cpp index ed9f6ca837..2f40d08e37 100644 --- a/src/Mod/TechDraw/App/DrawViewBalloon.cpp +++ b/src/Mod/TechDraw/App/DrawViewBalloon.cpp @@ -113,8 +113,6 @@ DrawViewBalloon::DrawViewBalloon(void) ADD_PROPERTY_TYPE(KinkLength,(prefKinkLength()),"",(App::PropertyType)(App::Prop_None), "Distance from symbol to leader kink"); - ADD_PROPERTY_TYPE(LineVisible,(true),"",(App::PropertyType)(App::Prop_None),"Balloon line visible or hidden"); - SourceView.setScope(App::LinkScope::Global); Rotation.setStatus(App::Property::Hidden,true); Caption.setStatus(App::Property::Hidden,true); diff --git a/src/Mod/TechDraw/App/DrawViewBalloon.h b/src/Mod/TechDraw/App/DrawViewBalloon.h index 0892aac32a..ac72ae8699 100644 --- a/src/Mod/TechDraw/App/DrawViewBalloon.h +++ b/src/Mod/TechDraw/App/DrawViewBalloon.h @@ -59,7 +59,6 @@ public: App::PropertyDistance OriginY; App::PropertyFloat TextWrapLen; App::PropertyDistance KinkLength; - App::PropertyBool LineVisible; short mustExecute() const override; diff --git a/src/Mod/TechDraw/Gui/QGIViewBalloon.cpp b/src/Mod/TechDraw/Gui/QGIViewBalloon.cpp index 1b7b062a0e..205cbfe093 100644 --- a/src/Mod/TechDraw/Gui/QGIViewBalloon.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewBalloon.cpp @@ -766,7 +766,7 @@ void QGIViewBalloon::draw() balloonLines->setPath(dLinePath); // This overwrites the previously created QPainterPath with empty one, in case it should be hidden. Should be refactored. - if (!balloon->LineVisible.getValue()) { + if (!vp->LineVisible.getValue()) { arrow->hide(); balloonLines->setPath(QPainterPath()); } diff --git a/src/Mod/TechDraw/Gui/ViewProviderBalloon.cpp b/src/Mod/TechDraw/Gui/ViewProviderBalloon.cpp index f88dbb6f09..f79910b5e5 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderBalloon.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderBalloon.cpp @@ -75,6 +75,7 @@ ViewProviderBalloon::ViewProviderBalloon() double weight = lg->getWeight("Thin"); delete lg; //Coverity CID 174670 ADD_PROPERTY_TYPE(LineWidth,(weight),group,(App::PropertyType)(App::Prop_None),"Leader line width"); + ADD_PROPERTY_TYPE(LineVisible,(true),group,(App::PropertyType)(App::Prop_None),"Balloon line visible or hidden"); ADD_PROPERTY_TYPE(Color,(PreferencesGui::dimColor()), group,App::Prop_None,"Color of the balloon"); @@ -148,7 +149,8 @@ void ViewProviderBalloon::onChanged(const App::Property* p) if ((p == &Font) || (p == &Fontsize) || (p == &Color) || - (p == &LineWidth)) { + (p == &LineWidth) || + (p == &LineVisible)) { QGIView* qgiv = getQView(); if (qgiv) { qgiv->updateView(true); diff --git a/src/Mod/TechDraw/Gui/ViewProviderBalloon.h b/src/Mod/TechDraw/Gui/ViewProviderBalloon.h index fd9cb6ad27..2f88a50434 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderBalloon.h +++ b/src/Mod/TechDraw/Gui/ViewProviderBalloon.h @@ -48,6 +48,7 @@ public: App::PropertyFont Font; App::PropertyLength Fontsize; App::PropertyLength LineWidth; + App::PropertyBool LineVisible; App::PropertyColor Color; virtual void attach(App::DocumentObject *); From d81e377546be6fd0073bc39e68f575d05a5a1e7a Mon Sep 17 00:00:00 2001 From: Aapo Date: Tue, 15 Dec 2020 23:39:14 +0200 Subject: [PATCH 11/16] [TD] Balloon, fix EndTypeScale refresh bug. --- src/Mod/TechDraw/App/DrawViewBalloon.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Mod/TechDraw/App/DrawViewBalloon.cpp b/src/Mod/TechDraw/App/DrawViewBalloon.cpp index 2f40d08e37..8331d0809d 100644 --- a/src/Mod/TechDraw/App/DrawViewBalloon.cpp +++ b/src/Mod/TechDraw/App/DrawViewBalloon.cpp @@ -129,7 +129,8 @@ void DrawViewBalloon::onChanged(const App::Property* prop) if ( (prop == &EndType) || (prop == &BubbleShape) || (prop == &Text) || - (prop == &KinkLength) ) { + (prop == &KinkLength) || + (prop == &EndTypeScale) ) { requestPaint(); } } From 5f497ab37a2e13fd5ea144120f272f59ba6f0f47 Mon Sep 17 00:00:00 2001 From: Aapo Date: Wed, 16 Dec 2020 14:10:41 +0200 Subject: [PATCH 12/16] [TD] Balloon, fix Origin and scale refresh bugs, make Balloon scale change more reasonable per UI click. --- src/Mod/TechDraw/App/DrawViewBalloon.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Mod/TechDraw/App/DrawViewBalloon.cpp b/src/Mod/TechDraw/App/DrawViewBalloon.cpp index 8331d0809d..2a19855a21 100644 --- a/src/Mod/TechDraw/App/DrawViewBalloon.cpp +++ b/src/Mod/TechDraw/App/DrawViewBalloon.cpp @@ -65,7 +65,7 @@ using namespace TechDraw; App::PropertyFloatConstraint::Constraints DrawViewBalloon::SymbolScaleRange = { Precision::Confusion(), std::numeric_limits::max(), - (1.0) }; + (0.1) }; //=========================================================================== // DrawViewBalloon @@ -100,7 +100,7 @@ DrawViewBalloon::DrawViewBalloon(void) ADD_PROPERTY(EndType,(prefEnd())); ADD_PROPERTY_TYPE(EndTypeScale,(1.0),"",(App::PropertyType)(App::Prop_None),"EndType shape scale"); - ShapeScale.setConstraints(&SymbolScaleRange); + EndTypeScale.setConstraints(&SymbolScaleRange); BubbleShape.setEnums(balloonTypeEnums); ADD_PROPERTY(BubbleShape,(prefShape())); @@ -128,9 +128,12 @@ void DrawViewBalloon::onChanged(const App::Property* prop) if (!isRestoring()) { if ( (prop == &EndType) || (prop == &BubbleShape) || + (prop == &ShapeScale) || (prop == &Text) || (prop == &KinkLength) || - (prop == &EndTypeScale) ) { + (prop == &EndTypeScale) || + (prop == &OriginX) || + (prop == &OriginY) ) { requestPaint(); } } From a7506326c9af96db4c4a8a345d184077ea2e8ff6 Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 18 Dec 2020 14:35:17 +0100 Subject: [PATCH 13/16] Gui: [skip ci] avoid adding a wrong file name to the recent files list --- src/Gui/Document.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Gui/Document.cpp b/src/Gui/Document.cpp index e6463eec6a..51e97c648a 100644 --- a/src/Gui/Document.cpp +++ b/src/Gui/Document.cpp @@ -1189,6 +1189,8 @@ bool Document::saveAs(void) escapedstr = Base::Tools::escapeEncodeFilename(escapedstr); Command::doCommand(Command::Doc,"App.getDocument(\"%s\").saveAs(u\"%s\")" , DocName, escapedstr.c_str()); + // App::Document::saveAs() may modify the passed file name + fi.setFile(QString::fromUtf8(d->_pcDocument->FileName.getValue())); setModified(false); getMainWindow()->appendRecentFile(fi.filePath()); } From d4bd0098c21a20a17c1a434d13a3234691b8db14 Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 18 Dec 2020 16:28:35 +0100 Subject: [PATCH 14/16] PartDesign: [skip ci] fix layout of Drill point controls --- src/Mod/PartDesign/Gui/TaskHoleParameters.ui | 60 +++++++++----------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/src/Mod/PartDesign/Gui/TaskHoleParameters.ui b/src/Mod/PartDesign/Gui/TaskHoleParameters.ui index 7d0a694760..eef3d883f5 100644 --- a/src/Mod/PartDesign/Gui/TaskHoleParameters.ui +++ b/src/Mod/PartDesign/Gui/TaskHoleParameters.ui @@ -267,7 +267,7 @@ Only available for holes without thread - + @@ -314,41 +314,37 @@ Only available for holes without thread - - - - - - 0 - 0 - - - - Angled - - - - - - - - 0 - 0 - - - - deg - - - 0.000000000000000 - - - - + + + + 0 + 0 + + + + Angled + + + + + + + 0 + 0 + + + + deg + + + 0.000000000000000 + + + From a2b1e6226aae5d0b4900c92365be5ca3a62d5564 Mon Sep 17 00:00:00 2001 From: M G Berberich Date: Fri, 18 Dec 2020 15:19:31 +0100 Subject: [PATCH 15/16] cleanup of hole dialog * replaced widget with radiobuttons by button Group, to improve alignemt of DrillPointAngle with grid-layout * made Thread Pitch/Angle/Cutoffs widgets wider --- src/Mod/PartDesign/Gui/TaskHoleParameters.ui | 972 +++++++++---------- 1 file changed, 461 insertions(+), 511 deletions(-) diff --git a/src/Mod/PartDesign/Gui/TaskHoleParameters.ui b/src/Mod/PartDesign/Gui/TaskHoleParameters.ui index eef3d883f5..e0c34186be 100644 --- a/src/Mod/PartDesign/Gui/TaskHoleParameters.ui +++ b/src/Mod/PartDesign/Gui/TaskHoleParameters.ui @@ -6,8 +6,8 @@ 0 0 - 373 - 560 + 441 + 710 @@ -20,21 +20,65 @@ Task Hole Parameters - - - - false - - - mm - - - 0.000000000000000 + + + + Clearance - - + + + + + 0 + 0 + + + + <b>Drill point</b> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + Depth + + + + + + + false + + + Angle + + + + + + + false + + + Cutoff outer + + + + + + + Tapered + + + + + 0 @@ -43,48 +87,36 @@ - 140 + 16777215 16777215 - - - Dimension - - - - - Through all - - - - - - - 0 - 0 - - - - - 110 - 16777215 - - + + - Hole diameter + - - mm - - - 0.000000000000000 + + Right hand + + directionButtonGroup + - + + + + Left hand + + + directionButtonGroup + + + + @@ -119,94 +151,91 @@ Only available for holes without thread - - - - false + + + + + 0 + 0 + - Angle + Profile - - - - Qt::Horizontal + + + + + 0 + 0 + - - QSizePolicy::Fixed + + Direction - + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + + 0 + 0 + + + - 13 - 20 + 140 + 16777215 - - - - - - <b>Hole cut</b> - + + + Dimension + + + + + Through all + + - - - - Thread direction + + + + + 0 + 0 + - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - Right hand - - - - - - - Left hand - - - - - - - - - - false + + + 16777215 + 16777215 + - mm + deg 0.000000000000000 - + + + + Countersink angle + + + + @@ -231,281 +260,7 @@ Only available for holes without thread - - - - false - - - Model actual thread - - - - - - - - 0 - 0 - - - - Depth - - - - - - - - 0 - 0 - - - - Profile - - - - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - Ending of the hole if 'Depth' is set to 'Dimension' - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Flat - - - - - - - - 0 - 0 - - - - Angled - - - - - - - - - - - 0 - 0 - - - - deg - - - 0.000000000000000 - - - - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - - - - - - 0 - 0 - - - - Class - - - - - - - Tapered - - - - - - - false - - - Cutoff inner - - - - - - - - 0 - 0 - - - - - 140 - 16777215 - - - - Tolerance class for threaded holes according to hole profile - - - - - - - - 0 - 0 - - - - mm - - - - - - - - 0 - 0 - - - - Size - - - - - - - - 0 - 0 - - - - <b>Drill point</b> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - Type - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - false - - - Cutoff outer - - - - - - - - 0 - 0 - - - - Type - - - - - - - false - - - deg - - - 0.000000000000000 - - - - - - - <b>Threading and size</b> - - - - + @@ -524,102 +279,13 @@ Only available for holes without thread - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - deg - - - 0.000000000000000 - - - - - - - <b>Misc</b> - - - - - - - - 0 - 0 - - - - Direction - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - - 0 - 0 - - - - Diameter - - - - - - - Depth - - - - - - - Countersink angle - - - - - - - Diameter - - - - - - - Clearance - - - - - + + false - - mm - - - 0.000000000000000 + + Pitch @@ -633,7 +299,174 @@ Only available for holes without thread - + + + + + 0 + 0 + + + + Class + + + + + + + false + + + Cutoff inner + + + + + + + Taper angle for the hole +90 degree: straight hole +under 90: smaller hole radius at the bottom +over 90: larger hole radius at the bottom + + + deg + + + 0.000000000000000 + + + + + + + false + + + mm + + + 0.000000000000000 + + + + + + + <b>Hole cut</b> + + + + + + + false + + + deg + + + 0.000000000000000 + + + + + + + + 0 + 0 + + + + deg + + + 0.000000000000000 + + + + + + + + 0 + 0 + + + + Flat + + + drillPointButtonGroup + + + + + + + <b>Threading and size</b> + + + + + + + + 0 + 0 + + + + Diameter + + + + + + + + 0 + 0 + + + + Type + + + + + + + <b>Misc</b> + + + + + + + + 0 + 0 + + + + mm + + + + + + + false + + + Model actual thread + + + + @@ -649,39 +482,23 @@ Only available for holes without thread - - - - - 120 - 16777215 - - - - Taper angle for the hole -90 degree: straight hole -under 90: smaller hole radius at the bottom -over 90: larger hole radius at the bottom - - - deg - - - 0.000000000000000 - - - - - - - false + + + + + 0 + 0 + - Pitch + Angled + + drillPointButtonGroup + - + @@ -709,7 +526,136 @@ over 90: larger hole radius at the bottom - + + + + + 0 + 0 + + + + Depth + + + + + + + Diameter + + + + + + + + 0 + 0 + + + + + 110 + 16777215 + + + + Hole diameter + + + mm + + + 0.000000000000000 + + + + + + + + 0 + 0 + + + + + 140 + 16777215 + + + + Tolerance class for threaded holes according to hole profile + + + + + + + Type + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + false + + + mm + + + 0.000000000000000 + + + + + + + + 0 + 0 + + + + Size + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 13 + 20 + + + + + + + + false + + + mm + + + 0.000000000000000 + + + + Reverses the hole direction @@ -784,4 +730,8 @@ over 90: larger hole radius at the bottom + + + + From 2db10d82368a1b7423dff83deaef2ba28003b6d4 Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 18 Dec 2020 17:04:27 +0100 Subject: [PATCH 16/16] PartDesign: [skip ci] fix order of controls so that by pressing TAB always the next control gets focus --- src/Mod/PartDesign/Gui/TaskHoleParameters.ui | 732 +++++++++---------- 1 file changed, 366 insertions(+), 366 deletions(-) diff --git a/src/Mod/PartDesign/Gui/TaskHoleParameters.ui b/src/Mod/PartDesign/Gui/TaskHoleParameters.ui index e0c34186be..c723acb05c 100644 --- a/src/Mod/PartDesign/Gui/TaskHoleParameters.ui +++ b/src/Mod/PartDesign/Gui/TaskHoleParameters.ui @@ -20,15 +20,15 @@ Task Hole Parameters - - + + - Clearance + <b>Threading and size</b> - - + + 0 @@ -36,44 +36,7 @@ - <b>Drill point</b> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - Depth - - - - - - - false - - - Angle - - - - - - - false - - - Cutoff outer - - - - - - - Tapered + Profile @@ -93,6 +56,141 @@ + + + + Whether the hole gets a thread + + + Threaded + + + + + + + false + + + Model actual thread + + + + + + + false + + + Pitch + + + + + + + false + + + mm + + + 0.000000000000000 + + + + + + + <b>Hole cut</b> + + + + + + + false + + + Angle + + + + + + + false + + + deg + + + 0.000000000000000 + + + + + + + false + + + Cutoff inner + + + + + + + false + + + mm + + + 0.000000000000000 + + + + + + + false + + + Cutoff outer + + + + + + + false + + + mm + + + 0.000000000000000 + + + + + + + + 0 + 0 + + + + Direction + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + @@ -116,6 +214,42 @@ + + + + + 0 + 0 + + + + Size + + + + + + + + 0 + 0 + + + + + 140 + 16777215 + + + + + + + + Clearance + + + @@ -151,8 +285,8 @@ Only available for holes without thread - - + + 0 @@ -160,12 +294,72 @@ Only available for holes without thread - Profile + Class - - + + + + + 0 + 0 + + + + + 140 + 16777215 + + + + Tolerance class for threaded holes according to hole profile + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 13 + 20 + + + + + + + + + 0 + 0 + + + + + 110 + 16777215 + + + + Hole diameter + + + mm + + + 0.000000000000000 + + + + + 0 @@ -173,10 +367,20 @@ Only available for holes without thread - Direction + Diameter - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + 0 + 0 + + + + Depth @@ -206,57 +410,29 @@ Only available for holes without thread - - + + 0 0 - - - 16777215 - 16777215 - - - - deg - - - 0.000000000000000 - - - - - - - Countersink angle - - - - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - mm - - 0.000000000000000 + + + + + + + 0 + 0 + - - 0.100000000000000 + + Type @@ -279,225 +455,13 @@ Only available for holes without thread - - - - false - - - Pitch - - - - - - - Whether the hole gets a thread - - - Threaded - - - - - - - - 0 - 0 - - - - Class - - - - - - - false - - - Cutoff inner - - - - - - - Taper angle for the hole -90 degree: straight hole -under 90: smaller hole radius at the bottom -over 90: larger hole radius at the bottom - - - deg - - - 0.000000000000000 - - - - - - - false - - - mm - - - 0.000000000000000 - - - - - - - <b>Hole cut</b> - - - - - - - false - - - deg - - - 0.000000000000000 - - - - - - - - 0 - 0 - - - - deg - - - 0.000000000000000 - - - - - - - - 0 - 0 - - - - Flat - - - drillPointButtonGroup - - - - - - - <b>Threading and size</b> - - - - - - - - 0 - 0 - - + + Diameter - - - - - 0 - 0 - - - - Type - - - - - - - <b>Misc</b> - - - - - - - - 0 - 0 - - - - mm - - - - - - - false - - - Model actual thread - - - - - - - - 0 - 0 - - - - - 140 - 16777215 - - - - - - - - - 0 - 0 - - - - Angled - - - drillPointButtonGroup - - - @@ -526,28 +490,15 @@ over 90: larger hole radius at the bottom - - - - - 0 - 0 - - + + Depth - - - - Diameter - - - - - + + 0 @@ -556,37 +507,63 @@ over 90: larger hole radius at the bottom - 110 + 16777215 16777215 - - Hole diameter - mm 0.000000000000000 + + 0.100000000000000 + - - + + + + Countersink angle + + + + + - + 0 0 - 140 + 16777215 16777215 - - Tolerance class for threaded holes according to hole profile + + deg + + + 0.000000000000000 + + + + + + + + 0 + 0 + + + + <b>Drill point</b> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop @@ -600,55 +577,78 @@ over 90: larger hole radius at the bottom - - - - false + + + + + 0 + 0 + + + + Flat + + + drillPointButtonGroup + + + + + + + + 0 + 0 + + + + Angled + + + drillPointButtonGroup + + + + + + + + 0 + 0 + - mm + deg 0.000000000000000 - - - - - 0 - 0 - - + + - Size + <b>Misc</b> - - - - Qt::Horizontal + + + + Tapered - - QSizePolicy::Fixed - - - - 13 - 20 - - - + - - - - false + + + + Taper angle for the hole +90 degree: straight hole +under 90: smaller hole radius at the bottom +over 90: larger hole radius at the bottom - mm + deg 0.000000000000000