Merge pull request #5262 from sliptonic/bug/translation

[PATH]  Bug/translation
This commit is contained in:
sliptonic
2021-12-19 09:33:11 -06:00
committed by GitHub
3 changed files with 453 additions and 321 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -30,8 +30,7 @@ import PathScripts.PathOp as PathOp
import PathScripts.PathUtils as PathUtils
import math
import numpy
from PySide import QtCore
from PySide.QtCore import QT_TRANSLATE_NOOP
# lazily loaded modules
from lazy_loader.lazy_loader import LazyLoader
@@ -39,6 +38,7 @@ from lazy_loader.lazy_loader import LazyLoader
Part = LazyLoader("Part", globals(), "Part")
DraftGeomUtils = LazyLoader("DraftGeomUtils", globals(), "DraftGeomUtils")
translate = FreeCAD.Qt.translate
__title__ = "Path Profile Operation"
__author__ = "sliptonic (Brad Collette)"
@@ -55,11 +55,6 @@ else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
# Qt translation handling
def translate(context, text, disambig=None):
return QtCore.QCoreApplication.translate(context, text, disambig)
class ObjectProfile(PathAreaOp.ObjectOp):
"""Proxy object for Profile operations based on faces."""
@@ -79,23 +74,21 @@ class ObjectProfile(PathAreaOp.ObjectOp):
"""initAreaOpProperties(obj) ... create operation specific properties"""
self.addNewProps = []
for (prtyp, nm, grp, tt) in self.areaOpProperties():
if not hasattr(obj, nm):
obj.addProperty(prtyp, nm, grp, tt)
self.addNewProps.append(nm)
for (propertytype, propertyname, grp, tt) in self.areaOpProperties():
if not hasattr(obj, propertyname):
obj.addProperty(propertytype, propertyname, grp, tt)
self.addNewProps.append(propertyname)
if len(self.addNewProps) > 0:
# Set enumeration lists for enumeration properties
ENUMS = self.areaOpPropertyEnumerations()
for n in ENUMS:
if n in self.addNewProps:
setattr(obj, n, ENUMS[n])
if n[0] in self.addNewProps:
setattr(obj, n[0], n[1])
if warn:
newPropMsg = translate("PathProfile", "New property added to")
newPropMsg = "New property added to"
newPropMsg += ' "{}": {}'.format(obj.Label, self.addNewProps) + ". "
newPropMsg += (
translate("PathProfile", "Check its default value.") + "\n"
)
newPropMsg += "Check its default value." + "\n"
FreeCAD.Console.PrintWarning(newPropMsg)
self.propertiesReady = True
@@ -109,7 +102,7 @@ class ObjectProfile(PathAreaOp.ObjectOp):
"App::PropertyEnumeration",
"Direction",
"Profile",
QtCore.QT_TRANSLATE_NOOP(
QT_TRANSLATE_NOOP(
"App::Property",
"The direction that the toolpath should go around the part ClockWise (CW) or CounterClockWise (CCW)",
),
@@ -118,8 +111,8 @@ class ObjectProfile(PathAreaOp.ObjectOp):
"App::PropertyEnumeration",
"HandleMultipleFeatures",
"Profile",
QtCore.QT_TRANSLATE_NOOP(
"PathPocket",
QT_TRANSLATE_NOOP(
"App::Property",
"Choose how to process multiple Base Geometry features.",
),
),
@@ -127,7 +120,7 @@ class ObjectProfile(PathAreaOp.ObjectOp):
"App::PropertyEnumeration",
"JoinType",
"Profile",
QtCore.QT_TRANSLATE_NOOP(
QT_TRANSLATE_NOOP(
"App::Property",
"Controls how tool moves around corners. Default=Round",
),
@@ -136,7 +129,7 @@ class ObjectProfile(PathAreaOp.ObjectOp):
"App::PropertyFloat",
"MiterLimit",
"Profile",
QtCore.QT_TRANSLATE_NOOP(
QT_TRANSLATE_NOOP(
"App::Property", "Maximum distance before a miter join is truncated"
),
),
@@ -144,7 +137,7 @@ class ObjectProfile(PathAreaOp.ObjectOp):
"App::PropertyDistance",
"OffsetExtra",
"Profile",
QtCore.QT_TRANSLATE_NOOP(
QT_TRANSLATE_NOOP(
"App::Property",
"Extra value to stay away from final profile- good for roughing toolpath",
),
@@ -153,7 +146,7 @@ class ObjectProfile(PathAreaOp.ObjectOp):
"App::PropertyBool",
"processHoles",
"Profile",
QtCore.QT_TRANSLATE_NOOP(
QT_TRANSLATE_NOOP(
"App::Property", "Profile holes as well as the outline"
),
),
@@ -161,50 +154,78 @@ class ObjectProfile(PathAreaOp.ObjectOp):
"App::PropertyBool",
"processPerimeter",
"Profile",
QtCore.QT_TRANSLATE_NOOP("App::Property", "Profile the outline"),
QT_TRANSLATE_NOOP("App::Property", "Profile the outline"),
),
(
"App::PropertyBool",
"processCircles",
"Profile",
QtCore.QT_TRANSLATE_NOOP("App::Property", "Profile round holes"),
QT_TRANSLATE_NOOP("App::Property", "Profile round holes"),
),
(
"App::PropertyEnumeration",
"Side",
"Profile",
QtCore.QT_TRANSLATE_NOOP(
"App::Property", "Side of edge that tool should cut"
),
QT_TRANSLATE_NOOP("App::Property", "Side of edge that tool should cut"),
),
(
"App::PropertyBool",
"UseComp",
"Profile",
QtCore.QT_TRANSLATE_NOOP(
QT_TRANSLATE_NOOP(
"App::Property", "Make True, if using Cutter Radius Compensation"
),
),
]
def areaOpPropertyEnumerations(self):
"""areaOpPropertyEnumerations() ... returns a dictionary of enumeration lists
for the operation's enumeration type properties."""
@classmethod
def areaOpPropertyEnumerations(self, dataType="data"):
"""opPropertyEnumerations(dataType="data")... return property enumeration lists of specified dataType.
Args:
dataType = 'data', 'raw', 'translated'
Notes:
'data' is list of internal string literals used in code
'raw' is list of (translated_text, data_string) tuples
'translated' is list of translated string literals
"""
# Enumeration lists for App::PropertyEnumeration properties
return {
"Direction": ["CW", "CCW"], # this is the direction that the profile runs
"HandleMultipleFeatures": ["Collectively", "Individually"],
enums = {
"Direction": [
(translate("PathProfile", "CW"), "CW"),
(translate("PathProfile", "CCW"), "CCW"),
], # this is the direction that the profile runs
"HandleMultipleFeatures": [
(translate("PathProfile", "Collectively"), "Collectively"),
(translate("PathProfile", "Individually"), "Individually"),
],
"JoinType": [
"Round",
"Square",
"Miter",
(translate("PathProfile", "Round"), "Round"),
(translate("PathProfile", "Square"), "Square"),
(translate("PathProfile", "Miter"), "Miter"),
], # this is the direction that the Profile runs
"Side": [
"Outside",
"Inside",
(translate("PathProfile", "Outside"), "Outside"),
(translate("PathProfile", "Inside"), "Inside"),
], # side of profile that cutter is on in relation to direction of profile
}
if dataType == "raw":
return enums
data = list()
idx = 0 if dataType == "translated" else 1
PathLog.debug(enums)
for k, v in enumerate(enums):
# data[k] = [tup[idx] for tup in v]
data.append((v, [tup[idx] for tup in enums[v]]))
PathLog.debug(data)
return data
def areaOpPropertyDefaults(self, obj, job):
"""areaOpPropertyDefaults(obj, job) ... returns a dictionary of default values
for the operation's properties."""
@@ -350,8 +371,7 @@ class ObjectProfile(PathAreaOp.ObjectOp):
shapes = []
remainingObjBaseFeatures = []
self.isDebug = True if PathLog.getLevel(PathLog.thisModule()) == 4 else False
self.inaccessibleMsg = translate(
"PathProfile",
self.inaccessibleMsg = translate("PathProfile",
"The selected edge(s) are inaccessible. If multiple, re-ordering selection might work.",
)
self.offsetExtra = obj.OffsetExtra.Value
@@ -418,10 +438,7 @@ class ObjectProfile(PathAreaOp.ObjectOp):
else:
PathLog.track()
ignoreSub = base.Name + "." + sub
msg = translate(
"PathProfile",
"Found a selected object which is not a face. Ignoring:",
)
msg = "Found a selected object which is not a face. Ignoring:"
PathLog.warning(msg + " {}".format(ignoreSub))
for baseShape, wire in holes:
@@ -458,9 +475,7 @@ class ObjectProfile(PathAreaOp.ObjectOp):
)
except Exception as ee: # pylint: disable=broad-except
# PathUtils.getEnvelope() failed to return an object.
msg = translate(
"Path", "Unable to create path for face(s)."
)
msg = translate("PathProfile", "Unable to create path for face(s).")
PathLog.error(msg + "\n{}".format(ee))
cont = False
@@ -569,10 +584,7 @@ class ObjectProfile(PathAreaOp.ObjectOp):
# Attempt open-edges profile
if self.JOB.GeometryTolerance.Value == 0.0:
msg = self.JOB.Label + ".GeometryTolerance = 0.0. "
msg += translate(
"PathProfile",
"Please set to an acceptable value greater than zero.",
)
msg += "Please set to an acceptable value greater than zero."
PathLog.error(msg)
else:
flattened = self._flattenWire(obj, wire, obj.FinalDepth.Value)
@@ -606,10 +618,7 @@ class ObjectProfile(PathAreaOp.ObjectOp):
shapes.append(tup)
else:
if zDiff < self.JOB.GeometryTolerance.Value:
msg = translate(
"PathProfile",
"Check edge selection and Final Depth requirements for profiling open edge(s).",
)
msg = translate("PathProfile", "Check edge selection and Final Depth requirements for profiling open edge(s).")
PathLog.error(msg)
else:
PathLog.error(self.inaccessibleMsg)
@@ -667,9 +676,7 @@ class ObjectProfile(PathAreaOp.ObjectOp):
fdv = obj.FinalDepth.Value
extLenFwd = sdv - fdv
if extLenFwd <= 0.0:
msg = translate(
"PathProfile", "For open edges, verify Final Depth for this operation."
)
msg = "For open edges, verify Final Depth for this operation."
FreeCAD.Console.PrintError(msg + "\n")
# return False
extLenFwd = 0.1

View File

@@ -22,12 +22,11 @@
import FreeCAD
import FreeCADGui
import PathGui as PGui # ensure Path/Gui/Resources are loaded
import PathGui as PGui # ensure Path/Gui/Resources are loaded
import PathScripts.PathGui as PathGui
import PathScripts.PathOpGui as PathOpGui
import PathScripts.PathProfile as PathProfile
from PySide import QtCore
from PySide.QtCore import QT_TRANSLATE_NOOP
__title__ = "Path Profile Operation UI"
@@ -36,47 +35,48 @@ __url__ = "http://www.freecadweb.org"
__doc__ = "Profile operation page controller and command implementation."
FeatureSide = 0x01
FeatureSide = 0x01
FeatureProcessing = 0x02
def translate(context, text, disambig=None):
return QtCore.QCoreApplication.translate(context, text, disambig)
class TaskPanelOpPage(PathOpGui.TaskPanelPage):
'''Base class for profile operation page controllers. Two sub features are supported:
FeatureSide ... Is the Side property exposed in the UI
FeatureProcessing ... Are the processing check boxes supported by the operation
'''
"""Base class for profile operation page controllers. Two sub features are supported:
FeatureSide ... Is the Side property exposed in the UI
FeatureProcessing ... Are the processing check boxes supported by the operation
"""
def initPage(self, obj):
self.setTitle("Profile - " + obj.Label)
self.updateVisibility()
def profileFeatures(self):
'''profileFeatures() ... return which of the optional profile features are supported.
"""profileFeatures() ... return which of the optional profile features are supported.
Currently two features are supported and returned:
FeatureSide ... Is the Side property exposed in the UI
FeatureProcessing ... Are the processing check boxes supported by the operation
.'''
."""
return FeatureSide | FeatureProcessing
def getForm(self):
'''getForm() ... returns UI customized according to profileFeatures()'''
"""getForm() ... returns UI customized according to profileFeatures()"""
form = FreeCADGui.PySideUic.loadUi(":/panels/PageOpProfileFullEdit.ui")
comboToPropertyMap = [("cutSide", "Side"), ("direction", "Direction")]
enumTups = PathProfile.ObjectProfile.areaOpPropertyEnumerations(dataType="raw")
self.populateCombobox(form, enumTups, comboToPropertyMap)
return form
def getFields(self, obj):
'''getFields(obj) ... transfers values from UI to obj's proprties'''
"""getFields(obj) ... transfers values from UI to obj's proprties"""
self.updateToolController(obj, self.form.toolController)
self.updateCoolant(obj, self.form.coolantController)
if obj.Side != str(self.form.cutSide.currentText()):
obj.Side = str(self.form.cutSide.currentText())
if obj.Direction != str(self.form.direction.currentText()):
obj.Direction = str(self.form.direction.currentText())
PathGui.updateInputField(obj, 'OffsetExtra', self.form.extraOffset)
if obj.Side != str(self.form.cutSide.currentData()):
obj.Side = str(self.form.cutSide.currentData())
if obj.Direction != str(self.form.direction.currentData()):
obj.Direction = str(self.form.direction.currentData())
PathGui.updateInputField(obj, "OffsetExtra", self.form.extraOffset)
if obj.UseComp != self.form.useCompensation.isChecked():
obj.UseComp = self.form.useCompensation.isChecked()
@@ -91,13 +91,17 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage):
obj.processCircles = self.form.processCircles.isChecked()
def setFields(self, obj):
'''setFields(obj) ... transfers obj's property values to UI'''
"""setFields(obj) ... transfers obj's property values to UI"""
self.setupToolController(obj, self.form.toolController)
self.setupCoolant(obj, self.form.coolantController)
self.selectInComboBox(obj.Side, self.form.cutSide)
self.selectInComboBox(obj.Direction, self.form.direction)
self.form.extraOffset.setText(FreeCAD.Units.Quantity(obj.OffsetExtra.Value, FreeCAD.Units.Length).UserString)
self.form.extraOffset.setText(
FreeCAD.Units.Quantity(
obj.OffsetExtra.Value, FreeCAD.Units.Length
).UserString
)
self.form.useCompensation.setChecked(obj.UseComp)
self.form.useStartPoint.setChecked(obj.UseStartPoint)
@@ -108,7 +112,7 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage):
self.updateVisibility()
def getSignalsForUpdate(self, obj):
'''getSignalsForUpdate(obj) ... return list of signals for updating obj'''
"""getSignalsForUpdate(obj) ... return list of signals for updating obj"""
signals = []
signals.append(self.form.toolController.currentIndexChanged)
signals.append(self.form.coolantController.currentIndexChanged)
@@ -127,13 +131,13 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage):
hasFace = False
objBase = list()
if hasattr(self.obj, 'Base'):
if hasattr(self.obj, "Base"):
objBase = self.obj.Base
if objBase.__len__() > 0:
for (base, subsList) in objBase:
for sub in subsList:
if sub[:4] == 'Face':
if sub[:4] == "Face":
hasFace = True
break
@@ -148,15 +152,21 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage):
def registerSignalHandlers(self, obj):
self.form.useCompensation.stateChanged.connect(self.updateVisibility)
# Eclass
Command = PathOpGui.SetupOperation('Profile',
PathProfile.Create,
TaskPanelOpPage,
'Path_Contour',
QtCore.QT_TRANSLATE_NOOP("Path_Profile", "Profile"),
QtCore.QT_TRANSLATE_NOOP("Path_Profile", "Profile entire model, selected face(s) or selected edge(s)"),
PathProfile.SetupProperties)
Command = PathOpGui.SetupOperation(
"Profile",
PathProfile.Create,
TaskPanelOpPage,
"Path_Contour",
QT_TRANSLATE_NOOP("Path", "Profile"),
QT_TRANSLATE_NOOP(
"Path", "Profile entire model, selected face(s) or selected edge(s)"
),
PathProfile.SetupProperties,
)
FreeCAD.Console.PrintLog("Loading PathProfileFacesGui... done\n")