From f21eac0e692bcdb336832b652c7e9afffef5dc3f Mon Sep 17 00:00:00 2001 From: hasecilu Date: Mon, 29 Jan 2024 19:03:13 -0600 Subject: [PATCH] Add translation support - Add bash script to include marked strings on translation files (*.ts) - translateutils to import translate() placeholder function --- freecad/gears/basegear.py | 16 +- freecad/gears/bevelgear.py | 74 +++++++-- freecad/gears/commands.py | 54 ++++--- freecad/gears/connector.py | 27 +++- freecad/gears/crowngear.py | 49 ++++-- freecad/gears/cycloidgear.py | 90 ++++++++--- freecad/gears/cycloidgearrack.py | 83 +++++++--- freecad/gears/hypocycloidgear.py | 55 +++++-- freecad/gears/init_gui.py | 4 + freecad/gears/internalinvolutegear.py | 148 +++++++++++++++--- freecad/gears/involutegear.py | 141 ++++++++++++++--- freecad/gears/involutegearrack.py | 91 ++++++++--- freecad/gears/lanterngear.py | 26 ++- freecad/gears/timinggear.py | 60 +++++-- freecad/gears/timinggear_t.py | 62 ++++++-- freecad/gears/translateutils.py | 38 +++++ .../gears/translations/update_translation.sh | 108 +++++++++++++ freecad/gears/wormgear.py | 51 ++++-- 18 files changed, 955 insertions(+), 222 deletions(-) create mode 100644 freecad/gears/translateutils.py create mode 100755 freecad/gears/translations/update_translation.sh diff --git a/freecad/gears/basegear.py b/freecad/gears/basegear.py index 967ad64..d46bcb1 100644 --- a/freecad/gears/basegear.py +++ b/freecad/gears/basegear.py @@ -23,6 +23,7 @@ import numpy as np from freecad import app from freecad import part +from .translateutils import translate from pygears import __version__ from pygears._functions import arc_from_points_and_center @@ -43,10 +44,11 @@ def fcvec(x): return app.Vector(x[0], x[1], x[2]) -class ViewProviderGear(): +class ViewProviderGear: """ The base Viewprovider for the gears """ + def __init__(self, obj, icon_fn=None): # Set this object to the proxy object of the actual view provider obj.Proxy = self @@ -92,10 +94,14 @@ class ViewProviderGear(): self.icon_fn = state["icon_fn"] -class BaseGear(): +class BaseGear: def __init__(self, obj): obj.addProperty( - "App::PropertyString", "version", "version", "freecad.gears-version", 1 + "App::PropertyString", + "version", + "version", + translate("BaseGear", "freecad.gears-version"), + 1, ) obj.version = __version__ self.make_attachable(obj) @@ -163,7 +169,7 @@ def part_arc_from_points_and_center(point_1, point_2, center): center (list, np.array with 2 values): the 2d center of the arc Returns: - freecad.part.Arc: a arc with + freecad.part.Arc: a arc with """ p_1, p_12, p_2 = arc_from_points_and_center(point_1, point_2, center) return part.Arc(fcvec(p_1), fcvec(p_12), fcvec(p_2)) @@ -281,7 +287,7 @@ def fillet_between_edges(edge_1, edge_2, radius, reversed=False): p4 = edge_2.valueAt(edge_2.LastParameter) t1 = p2 - p1 t2 = p4 - p3 - n = t1.cross(t2) * (- reversed * 2 + 1) + n = t1.cross(t2) * (-reversed * 2 + 1) pln = part.Plane(edge_1.valueAt(edge_1.FirstParameter), n) fillet2d_api.init(edge_1, edge_2, pln) if fillet2d_api.perform(radius) > 0: diff --git a/freecad/gears/bevelgear.py b/freecad/gears/bevelgear.py index 434f0fa..23fee4f 100644 --- a/freecad/gears/bevelgear.py +++ b/freecad/gears/bevelgear.py @@ -20,6 +20,7 @@ from freecad import app from freecad import part import numpy as np +from .translateutils import translate from pygears.bevel_tooth import BevelTooth from pygears._functions import rotation3D @@ -36,40 +37,84 @@ class BevelGear(BaseGear): def __init__(self, obj): super(BevelGear, self).__init__(obj) self.bevel_tooth = BevelTooth() - obj.addProperty("App::PropertyInteger", "teeth", "base", "number of teeth") - obj.addProperty("App::PropertyLength", "height", "base", "height") - obj.addProperty("App::PropertyAngle", "pitch_angle", "involute", "pitch_angle") + obj.addProperty( + "App::PropertyInteger", + "teeth", + "base", + translate("BevelGear", "number of teeth"), + ) + obj.addProperty( + "App::PropertyLength", + "height", + "base", + translate("BevelGear", "height"), + ) + obj.addProperty( + "App::PropertyAngle", + "pitch_angle", + "involute", + translate("BevelGear", "pitch_angle"), + ) obj.addProperty( "App::PropertyAngle", "pressure_angle", "involute_parameter", - "pressure_angle", + translate("BevelGear", "pressure_angle"), + ) + obj.addProperty( + "App::PropertyLength", + "module", + "base", + translate("BevelGear", "module"), + ) + obj.addProperty( + "App::PropertyFloat", + "clearance", + "tolerance", + translate("BevelGear", "clearance"), ) - obj.addProperty("App::PropertyLength", "module", "base", "module") - obj.addProperty("App::PropertyFloat", "clearance", "tolerance", "clearance") obj.addProperty( "App::PropertyInteger", "numpoints", "precision", - "number of points for spline", + translate("BevelGear", "number of points for spline"), ) obj.addProperty( "App::PropertyBool", "reset_origin", "base", - "if value is true the gears outer face will match the z=0 plane", + translate( + "BevelGear", + "if value is true the gears outer face will match the z=0 plane", + ), ) obj.addProperty( "App::PropertyLength", "backlash", "tolerance", - "The arc length on the pitch circle by which the tooth thicknes is reduced.", + translate( + "BevelGear", + "The arc length on the pitch circle by which the tooth thicknes is reduced.", + ), ) - obj.addProperty("App::PropertyPythonObject", "gear", "base", "test") obj.addProperty( - "App::PropertyAngle", "beta", "helical", "angle used for spiral bevel-gears" + "App::PropertyPythonObject", + "gear", + "base", + translate("BevelGear", "test"), + ) + obj.addProperty( + "App::PropertyAngle", + "beta", + "helical", + translate("BevelGear", "angle used for spiral bevel-gears"), + ) + obj.addProperty( + "App::PropertyLength", + "dw", + "computed", + translate("BevelGear", "The pitch diameter."), ) - obj.addProperty("App::PropertyLength", "dw", "computed", "The pitch diameter.") obj.setExpression( "dw", "teeth * module" ) # calculate via expression to ease usage for placement @@ -80,7 +125,10 @@ class BevelGear(BaseGear): "App::PropertyAngle", "angular_backlash", "computed", - "The angle by which this gear can turn without moving the mating gear.", + translate( + "BevelGear", + "The angle by which this gear can turn without moving the mating gear.", + ), ) obj.setExpression( "angular_backlash", "backlash / dw * 360° / pi" diff --git a/freecad/gears/commands.py b/freecad/gears/commands.py index ca21e77..47a8b50 100644 --- a/freecad/gears/commands.py +++ b/freecad/gears/commands.py @@ -20,6 +20,8 @@ import os from freecad import app from freecad import gui +from .translateutils import translate + from .basegear import ViewProviderGear, BaseGear from .timinggear_t import TimingGearT @@ -99,104 +101,104 @@ class CreateInvoluteGear(BaseCommand): NAME = "InvoluteGear" GEAR_FUNCTION = InvoluteGear Pixmap = os.path.join(BaseCommand.ICONDIR, "involutegear.svg") - MenuText = "Involute Gear" - ToolTip = "Create an external involute gear" + MenuText = translate("Commands", "Involute Gear") + ToolTip = translate("Commands", "Create an external involute gear") class CreateInternalInvoluteGear(BaseCommand): NAME = "InternalInvoluteGear" GEAR_FUNCTION = InternalInvoluteGear Pixmap = os.path.join(BaseCommand.ICONDIR, "internalinvolutegear.svg") - MenuText = "Internal Involute Gear" - ToolTip = "Create an internal involute gear" + MenuText = translate("Commands", "Internal Involute Gear") + ToolTip = translate("Commands", "Create an internal involute gear") class CreateInvoluteRack(BaseCommand): NAME = "InvoluteRack" GEAR_FUNCTION = InvoluteGearRack Pixmap = os.path.join(BaseCommand.ICONDIR, "involuterack.svg") - MenuText = "Involute Rack" - ToolTip = "Create an Involute rack" + MenuText = translate("Commands", "Involute Rack") + ToolTip = translate("Commands", "Create an Involute rack") class CreateCycloidRack(BaseCommand): NAME = "CycloidRack" GEAR_FUNCTION = CycloidGearRack Pixmap = os.path.join(BaseCommand.ICONDIR, "cycloidrack.svg") - MenuText = "Cycloid Rack" - ToolTip = "Create an Cycloid rack" + MenuText = translate("Commands", "Cycloid Rack") + ToolTip = translate("Commands", "Create an Cycloid rack") class CreateCrownGear(BaseCommand): NAME = "CrownGear" GEAR_FUNCTION = CrownGear Pixmap = os.path.join(BaseCommand.ICONDIR, "crowngear.svg") - MenuText = "Crown Gear" - ToolTip = "Create a Crown gear" + MenuText = translate("Commands", "Crown Gear") + ToolTip = translate("Commands", "Create a Crown gear") class CreateCycloidGear(BaseCommand): NAME = "CycloidGear" GEAR_FUNCTION = CycloidGear Pixmap = os.path.join(BaseCommand.ICONDIR, "cycloidgear.svg") - MenuText = "Cycloid Gear" - ToolTip = "Create a Cycloid gear" + MenuText = translate("Commands", "Cycloid Gear") + ToolTip = translate("Commands", "Create a Cycloid gear") class CreateBevelGear(BaseCommand): NAME = "BevelGear" GEAR_FUNCTION = BevelGear Pixmap = os.path.join(BaseCommand.ICONDIR, "bevelgear.svg") - MenuText = "Bevel Gear" - ToolTip = "Create a Bevel gear" + MenuText = translate("Commands", "Bevel Gear") + ToolTip = translate("Commands", "Create a Bevel gear") class CreateHypoCycloidGear(BaseCommand): NAME = "HypocycloidGear" GEAR_FUNCTION = HypoCycloidGear Pixmap = os.path.join(BaseCommand.ICONDIR, "hypocycloidgear.svg") - MenuText = "HypoCycloid Gear" - ToolTip = "Create a HypoCycloid gear with its pins" + MenuText = translate("Commands", "HypoCycloid Gear") + ToolTip = translate("Commands", "Create a HypoCycloid gear with its pins") class CreateWormGear(BaseCommand): NAME = "WormGear" GEAR_FUNCTION = WormGear Pixmap = os.path.join(BaseCommand.ICONDIR, "wormgear.svg") - MenuText = "Worm Gear" - ToolTip = "Create a Worm gear" + MenuText = translate("Commands", "Worm Gear") + ToolTip = translate("Commands", "Create a Worm gear") class CreateTimingGearT(BaseCommand): NAME = "TimingGearT" GEAR_FUNCTION = TimingGearT Pixmap = os.path.join(BaseCommand.ICONDIR, "timinggear_t.svg") - MenuText = "Timing Gear T-shape" - ToolTip = "Create a Timing gear T-shape" + MenuText = translate("Commands", "Timing Gear T-shape") + ToolTip = translate("Commands", "Create a Timing gear T-shape") class CreateTimingGear(BaseCommand): NAME = "TimingGear" GEAR_FUNCTION = TimingGear Pixmap = os.path.join(BaseCommand.ICONDIR, "timinggear.svg") - MenuText = "Timing Gear" - ToolTip = "Create a Timing gear" + MenuText = translate("Commands", "Timing Gear") + ToolTip = translate("Commands", "Create a Timing gear") class CreateLanternGear(BaseCommand): NAME = "LanternGear" GEAR_FUNCTION = LanternGear Pixmap = os.path.join(BaseCommand.ICONDIR, "lanterngear.svg") - MenuText = "Lantern Gear" - ToolTip = "Create a Lantern gear" + MenuText = translate("Commands", "Lantern Gear") + ToolTip = translate("Commands", "Create a Lantern gear") class CreateGearConnector(BaseCommand): NAME = "GearConnector" GEAR_FUNCTION = GearConnector Pixmap = os.path.join(BaseCommand.ICONDIR, "gearconnector.svg") - MenuText = "Combine two gears" - ToolTip = "Combine two gears" + MenuText = translate("Commands", "Combine two gears") + ToolTip = translate("Commands", "Combine two gears") def Activated(self): gear1 = gui.Selection.getSelection()[0] diff --git a/freecad/gears/connector.py b/freecad/gears/connector.py index f9ae187..d6b00a1 100644 --- a/freecad/gears/connector.py +++ b/freecad/gears/connector.py @@ -25,6 +25,7 @@ from freecad import app from pygears import __version__ from pygears.computation import compute_shifted_gears +from .translateutils import translate from .involutegear import InvoluteGear from .internalinvolutegear import InternalInvoluteGear from .involutegearrack import InvoluteGearRack @@ -64,22 +65,38 @@ class ViewProviderGearConnector(object): class GearConnector(object): def __init__(self, obj, master_gear, slave_gear): obj.addProperty( - "App::PropertyString", "version", "version", "freecad.gears-version", 1 + "App::PropertyString", + "version", + "version", + translate("GearConnector", "freecad.gears-version"), + 1, + ) + obj.addProperty( + "App::PropertyLink", + "master_gear", + "gear", + translate("GearConnector", "master gear"), + 1, + ) + obj.addProperty( + "App::PropertyLink", + "slave_gear", + "gear", + translate("GearConnector", "slave gear"), + 1, ) - obj.addProperty("App::PropertyLink", "master_gear", "gear", "master gear", 1) - obj.addProperty("App::PropertyLink", "slave_gear", "gear", "slave gear", 1) obj.addProperty( "App::PropertyAngle", "angle1", "gear", - "angle at which second gear is placed", + translate("GearConnector", "angle at which second gear is placed"), 0, ) obj.addProperty( "App::PropertyAngle", "angle2", "gear", - "angle at which second gear is placed", + translate("GearConnector", "angle at which second gear is placed"), 1, ) obj.version = __version__ diff --git a/freecad/gears/crowngear.py b/freecad/gears/crowngear.py index 048f735..888da35 100644 --- a/freecad/gears/crowngear.py +++ b/freecad/gears/crowngear.py @@ -22,30 +22,55 @@ import numpy as np from freecad import app from freecad import part +from .translateutils import translate from .basegear import BaseGear, fcvec class CrownGear(BaseGear): """ - A crown gear (also known as a face gear or a contrate gear) is a gear - which has teeth that project at right angles to the face of the wheel. - In particular, a crown gear is a type of bevel gear where the pitch cone - angle is 90 degrees. https://en.wikipedia.org/wiki/Crown_gear + A crown gear (also known as a face gear or a contrate gear) is a gear + which has teeth that project at right angles to the face of the wheel. + In particular, a crown gear is a type of bevel gear where the pitch cone + angle is 90 degrees. https://en.wikipedia.org/wiki/Crown_gear """ + def __init__(self, obj): super(CrownGear, self).__init__(obj) - obj.addProperty("App::PropertyInteger", "teeth", "base", "number of teeth") + obj.addProperty( + "App::PropertyInteger", + "teeth", + "base", + translate("CrownGear", "number of teeth"), + ) obj.addProperty( "App::PropertyInteger", "other_teeth", "base", - "number of teeth of other gear", + translate("CrownGear", "number of teeth of other gear"), ) - obj.addProperty("App::PropertyLength", "module", "base", "module") - obj.addProperty("App::PropertyLength", "height", "base", "height") - obj.addProperty("App::PropertyLength", "thickness", "base", "thickness") obj.addProperty( - "App::PropertyAngle", "pressure_angle", "involute", "pressure angle" + "App::PropertyLength", + "module", + "base", + translate("CrownGear", "module"), + ) + obj.addProperty( + "App::PropertyLength", + "height", + "base", + translate("CrownGear", "height"), + ) + obj.addProperty( + "App::PropertyLength", + "thickness", + "base", + translate("CrownGear", "thickness"), + ) + obj.addProperty( + "App::PropertyAngle", + "pressure_angle", + "involute", + translate("CrownGear", "pressure angle"), ) self.add_accuracy_properties(obj) obj.teeth = 15 @@ -69,13 +94,13 @@ class CrownGear(BaseGear): "App::PropertyInteger", "num_profiles", "accuracy", - "number of profiles used for loft", + translate("CrownGear", "number of profiles used for loft"), ) obj.addProperty( "App::PropertyBool", "preview_mode", "accuracy", - "if true no boolean operation is done", + translate("CrownGear", "if true no boolean operation is done"), ) def profile(self, m, r, r0, t_c, t_i, alpha_w, y0, y1, y2): diff --git a/freecad/gears/cycloidgear.py b/freecad/gears/cycloidgear.py index 125b371..27c16cc 100644 --- a/freecad/gears/cycloidgear.py +++ b/freecad/gears/cycloidgear.py @@ -20,6 +20,7 @@ from freecad import app from freecad import part import numpy as np +from .translateutils import translate from pygears.cycloid_tooth import CycloidTooth from pygears._functions import rotation @@ -38,18 +39,35 @@ class CycloidGear(BaseGear): def __init__(self, obj): super(CycloidGear, self).__init__(obj) self.cycloid_tooth = CycloidTooth() - obj.addProperty("App::PropertyInteger", "teeth", "base", "number of teeth") - obj.addProperty("App::PropertyLength", "module", "base", "module") - obj.addProperty("App::PropertyLength", "height", "base", "height") - + obj.addProperty( + "App::PropertyInteger", + "teeth", + "base", + translate("CycloidGear", "number of teeth"), + ) + obj.addProperty( + "App::PropertyLength", + "module", + "base", + translate("CycloidGear", "module"), + ) + obj.addProperty( + "App::PropertyLength", + "height", + "base", + translate("CycloidGear", "height"), + ) obj.addProperty( "App::PropertyInteger", "numpoints", "accuracy", - "number of points for spline", + translate("CycloidGear", "number of points for spline"), ) obj.addProperty( - "App::PropertyPythonObject", "gear", "base", "the python object" + "App::PropertyPythonObject", + "gear", + "base", + translate("CycloidGear", "the python object"), ) self.add_helical_properties(obj) @@ -76,36 +94,62 @@ class CycloidGear(BaseGear): obj.Proxy = self def add_helical_properties(self, obj): - obj.addProperty("App::PropertyBool", "double_helix", "helical", "double helix") - obj.addProperty("App::PropertyAngle", "beta", "helical", "beta") + obj.addProperty( + "App::PropertyBool", + "double_helix", + "helical", + translate("CycloidGear", "double helix"), + ) + obj.addProperty( + "App::PropertyAngle", + "beta", + "helical", + translate("CycloidGear", "beta"), + ) def add_fillet_properties(self, obj): obj.addProperty( "App::PropertyFloat", "head_fillet", "fillets", - "a fillet for the tooth-head, radius = head_fillet x module", + translate( + "CycloidGear", + "a fillet for the tooth-head, radius = head_fillet x module", + ), ) obj.addProperty( "App::PropertyFloat", "root_fillet", "fillets", - "a fillet for the tooth-root, radius = root_fillet x module", + translate( + "CycloidGear", + "a fillet for the tooth-root, radius = root_fillet x module", + ), ) def add_tolerance_properties(self, obj): - obj.addProperty("App::PropertyFloat", "clearance", "tolerance", "clearance") + obj.addProperty( + "App::PropertyFloat", + "clearance", + "tolerance", + translate("CycloidGear", "clearance"), + ) obj.addProperty( "App::PropertyLength", "backlash", "tolerance", - "The arc length on the pitch circle by which the tooth thicknes is reduced.", + translate( + "CycloidGear", + "The arc length on the pitch circle by which the tooth thicknes is reduced.", + ), ) obj.addProperty( "App::PropertyFloat", "head", "tolerance", - "head_value * modul_value = additional length of head", + translate( + "CycloidGear", "head_value * module_value = additional length of head" + ), ) def add_cycloid_properties(self, obj): @@ -113,17 +157,22 @@ class CycloidGear(BaseGear): "App::PropertyFloat", "inner_diameter", "cycloid", - "inner_diameter divided by module (hypocycloid)", + translate("CycloidGear", "inner_diameter divided by module (hypocycloid)"), ) obj.addProperty( "App::PropertyFloat", "outer_diameter", "cycloid", - "outer_diameter divided by module (epicycloid)", + translate("CycloidGear", "outer_diameter divided by module (epicycloid)"), ) def add_computed_properties(self, obj): - obj.addProperty("App::PropertyLength", "dw", "computed", "The pitch diameter.") + obj.addProperty( + "App::PropertyLength", + "dw", + "computed", + translate("CycloidGear", "The pitch diameter."), + ) obj.setExpression( "dw", "teeth * module" ) # calculate via expression to ease usage for placement @@ -134,7 +183,10 @@ class CycloidGear(BaseGear): "App::PropertyAngle", "angular_backlash", "computed", - "The angle by which this gear can turn without moving the mating gear.", + translate( + "CycloidGear", + "The angle by which this gear can turn without moving the mating gear.", + ), ) obj.setExpression( "angular_backlash", "backlash / dw * 360° / pi" @@ -190,4 +242,6 @@ class CycloidGear(BaseGear): twist_angle = ( fp.height.Value * np.tan(fp.beta.Value * np.pi / 180) * 2 / fp.gear.d ) - return helical_extrusion(base, fp.height.Value, twist_angle, fp.double_helix) + return helical_extrusion( + base, fp.height.Value, twist_angle, fp.double_helix + ) diff --git a/freecad/gears/cycloidgearrack.py b/freecad/gears/cycloidgearrack.py index d746e7e..cedd664 100644 --- a/freecad/gears/cycloidgearrack.py +++ b/freecad/gears/cycloidgearrack.py @@ -24,6 +24,7 @@ from freecad import part import numpy as np +from .translateutils import translate from pygears._functions import reflection from .basegear import BaseGear, fcvec, points_to_wire, insert_fillet @@ -34,24 +35,46 @@ class CycloidGearRack(BaseGear): def __init__(self, obj): super(CycloidGearRack, self).__init__(obj) - obj.addProperty("App::PropertyInteger", "teeth", "base", "number of teeth") - obj.addProperty("App::PropertyLength", "height", "base", "height") - obj.addProperty("App::PropertyLength", "thickness", "base", "thickness") + obj.addProperty( + "App::PropertyInteger", + "teeth", + "base", + translate("CycloidGearRack", "number of teeth"), + ) + obj.addProperty( + "App::PropertyLength", + "height", + "base", + translate("CycloidGearRack", "height"), + ) + obj.addProperty( + "App::PropertyLength", + "thickness", + "base", + translate("CycloidGearRack", "thickness"), + ) obj.addProperty("App::PropertyLength", "module", "involute", "module") obj.addProperty( "App::PropertyBool", "simplified", "precision", - "if enabled the rack is drawn with a constant number of \ - teeth to avoid topologic renaming.", + translate( + "CycloidGearRack", + "if enabled the rack is drawn with a constant number of teeth to avoid topologic renaming.", + ), ) obj.addProperty( "App::PropertyInteger", "numpoints", "accuracy", - "number of points for spline", + translate("CycloidGearRack", "number of points for spline"), + ) + obj.addProperty( + "App::PropertyPythonObject", + "rack", + "base", + translate("CycloidGearRack", "test"), ) - obj.addProperty("App::PropertyPythonObject", "rack", "base", "test") self.add_helical_properties(obj) self.add_computed_properties(obj) @@ -74,23 +97,35 @@ class CycloidGearRack(BaseGear): obj.Proxy = self def add_helical_properties(self, obj): - obj.addProperty("App::PropertyAngle", "beta", "helical", "beta ") - obj.addProperty("App::PropertyBool", "double_helix", "helical", "double helix") + obj.addProperty( + "App::PropertyAngle", + "beta", + "helical", + translate("CycloidGearRack", "beta"), + ) + obj.addProperty( + "App::PropertyBool", + "double_helix", + "helical", + translate("CycloidGearRack", "double helix"), + ) def add_computed_properties(self, obj): obj.addProperty( "App::PropertyLength", "transverse_pitch", "computed", - "pitch in the transverse plane", + translate("CycloidGearRack", "pitch in the transverse plane"), 1, ) obj.addProperty( "App::PropertyBool", "add_endings", "base", - "if enabled the total length of the rack is teeth x pitch, \ - otherwise the rack starts with a tooth-flank", + translate( + "CycloidGearRack", + "if enabled the total length of the rack is teeth x pitch, otherwise the rack starts with a tooth-flank", + ), ) def add_tolerance_properties(self, obj): @@ -98,13 +133,15 @@ class CycloidGearRack(BaseGear): "App::PropertyFloat", "head", "tolerance", - "head * module = additional length of head", + translate("CycloidGearRack", "head * module = additional length of head"), ) obj.addProperty( "App::PropertyFloat", "clearance", "tolerance", - "clearance * module = additional length of root", + translate( + "CycloidGearRack", "clearance * module = additional length of root" + ), ) def add_cycloid_properties(self, obj): @@ -112,13 +149,17 @@ class CycloidGearRack(BaseGear): "App::PropertyFloat", "inner_diameter", "cycloid", - "inner_diameter divided by module (hypocycloid)", + translate( + "CycloidGearRack", "inner_diameter divided by module (hypocycloid)" + ), ) obj.addProperty( "App::PropertyFloat", "outer_diameter", "cycloid", - "outer_diameter divided by module (epicycloid)", + translate( + "CycloidGearRack", "outer_diameter divided by module (epicycloid)" + ), ) def add_fillet_properties(self, obj): @@ -126,13 +167,19 @@ class CycloidGearRack(BaseGear): "App::PropertyFloat", "head_fillet", "fillets", - "a fillet for the tooth-head, radius = head_fillet x module", + translate( + "CycloidGearRack", + "a fillet for the tooth-head, radius = head_fillet x module", + ), ) obj.addProperty( "App::PropertyFloat", "root_fillet", "fillets", - "a fillet for the tooth-root, radius = root_fillet x module", + translate( + "CycloidGearRack", + "a fillet for the tooth-root, radius = root_fillet x module", + ), ) def generate_gear_shape(self, obj): diff --git a/freecad/gears/hypocycloidgear.py b/freecad/gears/hypocycloidgear.py index 66f574a..1272c19 100644 --- a/freecad/gears/hypocycloidgear.py +++ b/freecad/gears/hypocycloidgear.py @@ -23,6 +23,7 @@ import numpy as np from freecad import app from freecad import part +from .translateutils import translate from pygears.bevel_tooth import BevelTooth from pygears._functions import rotation @@ -42,66 +43,92 @@ class HypoCycloidGear(BaseGear): "App::PropertyFloat", "pin_circle_radius", "gear_parameter", - "Pin ball circle radius(overrides Tooth Pitch", + translate( + "HypoCycloidGear", "Pin ball circle radius (overrides Tooth Pitch)" + ), ) obj.addProperty( - "App::PropertyFloat", "roller_diameter", "gear_parameter", "Roller Diameter" + "App::PropertyFloat", + "roller_diameter", + "gear_parameter", + translate("HypoCycloidGear", "Roller Diameter"), ) obj.addProperty( - "App::PropertyFloat", "eccentricity", "gear_parameter", "Eccentricity" + "App::PropertyFloat", + "eccentricity", + "gear_parameter", + translate("HypoCycloidGear", "Eccentricity"), ) obj.addProperty( "App::PropertyAngle", "pressure_angle_lim", "gear_parameter", - "Pressure angle limit", + translate("HypoCycloidGear", "Pressure angle limit"), ) obj.addProperty( "App::PropertyFloat", "pressure_angle_offset", "gear_parameter", - "Offset in pressure angle", + translate("HypoCycloidGear", "Offset in pressure angle"), ) obj.addProperty( "App::PropertyInteger", "teeth_number", "gear_parameter", - "Number of teeth in Cam", + translate("HypoCycloidGear", "Number of teeth in Cam"), ) obj.addProperty( "App::PropertyInteger", "segment_count", "gear_parameter", - "Number of points used for spline interpolation", + translate( + "HypoCycloidGear", "Number of points used for spline interpolation" + ), ) obj.addProperty( "App::PropertyLength", "hole_radius", "gear_parameter", - "Center hole's radius", + translate("HypoCycloidGear", "Center hole's radius"), ) obj.addProperty( - "App::PropertyBool", "show_pins", "Pins", "Create pins in place" + "App::PropertyBool", + "show_pins", + "Pins", + translate("HypoCycloidGear", "Create pins in place"), + ) + obj.addProperty( + "App::PropertyLength", + "pin_height", + "Pins", + translate("HypoCycloidGear", "height"), ) - obj.addProperty("App::PropertyLength", "pin_height", "Pins", "height") obj.addProperty( "App::PropertyBool", "center_pins", "Pins", - "Center pin Z axis to generated disks", + translate("HypoCycloidGear", "Center pin Z axis to generated disks"), ) obj.addProperty( - "App::PropertyBool", "show_disk0", "Disks", "Show main cam disk" + "App::PropertyBool", + "show_disk0", + "Disks", + translate("HypoCycloidGear", "Show main cam disk"), ) obj.addProperty( "App::PropertyBool", "show_disk1", "Disks", - "Show another reversed cam disk on top", + translate("HypoCycloidGear", "Show another reversed cam disk on top"), + ) + obj.addProperty( + "App::PropertyLength", + "disk_height", + "Disks", + translate("HypoCycloidGear", "height"), ) - obj.addProperty("App::PropertyLength", "disk_height", "Disks", "height") obj.pin_circle_radius = 66 obj.roller_diameter = 3 diff --git a/freecad/gears/init_gui.py b/freecad/gears/init_gui.py index fdfc65a..b67fdde 100644 --- a/freecad/gears/init_gui.py +++ b/freecad/gears/init_gui.py @@ -107,6 +107,10 @@ class GearWorkbench(gui.Workbench): return "Gui::PythonWorkbench" def Initialize(self): + # Add translations path + gui.addLanguagePath(os.path.join(os.path.dirname(__file__), "translations")) + gui.updateLocale() + from .commands import ( CreateCycloidGear, CreateInvoluteGear, diff --git a/freecad/gears/internalinvolutegear.py b/freecad/gears/internalinvolutegear.py index b52c846..05d1aa8 100644 --- a/freecad/gears/internalinvolutegear.py +++ b/freecad/gears/internalinvolutegear.py @@ -21,6 +21,7 @@ import numpy as np from freecad import app from freecad import part +from .translateutils import translate from pygears.involute_tooth import InvoluteTooth from pygears._functions import rotation @@ -43,24 +44,51 @@ class InternalInvoluteGear(BaseGear): def __init__(self, obj): super(InternalInvoluteGear, self).__init__(obj) self.involute_tooth = InvoluteTooth() - obj.addProperty("App::PropertyBool", "simple", "precision", "simple") - obj.addProperty("App::PropertyInteger", "teeth", "base", "number of teeth") + obj.addProperty( + "App::PropertyBool", + "simple", + "precision", + translate("InternalInvoluteGear", "simple"), + ) + obj.addProperty( + "App::PropertyInteger", + "teeth", + "base", + translate("InternalInvoluteGear", "number of teeth"), + ) obj.addProperty( "App::PropertyLength", "module", "base", - "normal module if properties_from_tool=True, \ - else it's the transverse module.", + translate( + "InternalInvoluteGear", + "normal module if properties_from_tool=True, else it's the transverse module.", + ), + ) + obj.addProperty( + "App::PropertyLength", + "height", + "base", + translate("InternalInvoluteGear", "height"), + ) + obj.addProperty( + "App::PropertyLength", + "thickness", + "base", + translate("InternalInvoluteGear", "thickness"), ) - obj.addProperty("App::PropertyLength", "height", "base", "height") - obj.addProperty("App::PropertyLength", "thickness", "base", "thickness") obj.addProperty( "App::PropertyInteger", "numpoints", "accuracy", - "number of points for spline", + translate("InternalInvoluteGear", "number of points for spline"), + ) + obj.addProperty( + "App::PropertyPythonObject", + "gear", + "base", + translate("InternalInvoluteGear", "test"), ) - obj.addProperty("App::PropertyPythonObject", "gear", "base", "test") self.add_involute_properties(obj) self.add_tolerance_properties(obj) @@ -91,16 +119,36 @@ class InternalInvoluteGear(BaseGear): obj.Proxy = self def add_limiting_diameter_properties(self, obj): - obj.addProperty("App::PropertyLength", "da", "computed", "inside diameter", 1) - obj.addProperty("App::PropertyLength", "df", "computed", "root diameter", 1) + obj.addProperty( + "App::PropertyLength", + "da", + "computed", + translate("InternalInvoluteGear", "inside diameter"), + 1, + ) + obj.addProperty( + "App::PropertyLength", + "df", + "computed", + translate("InternalInvoluteGear", "root diameter"), + 1, + ) def add_computed_properties(self, obj): - obj.addProperty("App::PropertyLength", "dw", "computed", "The pitch diameter.") + obj.addProperty( + "App::PropertyLength", + "dw", + "computed", + translate("InternalInvoluteGear", "The pitch diameter."), + ) obj.addProperty( "App::PropertyAngle", "angular_backlash", "computed", - "The angle by which this gear can turn without moving the mating gear.", + translate( + "InternalInvoluteGear", + "The angle by which this gear can turn without moving the mating gear.", + ), ) obj.setExpression( "angular_backlash", "backlash / dw * 360° / pi" @@ -109,10 +157,18 @@ class InternalInvoluteGear(BaseGear): "angular_backlash", 1 ) # set read-only after setting the expression, else it won't be visible. bug? obj.addProperty( - "App::PropertyLength", "transverse_pitch", "computed", "transverse_pitch", 1 + "App::PropertyLength", + "transverse_pitch", + "computed", + translate("InternalInvoluteGear", "transverse_pitch"), + 1, ) obj.addProperty( - "App::PropertyLength", "outside_diameter", "computed", "Outside diameter", 1 + "App::PropertyLength", + "outside_diameter", + "computed", + translate("InternalInvoluteGear", "Outside diameter"), + 1, ) def add_fillet_properties(self, obj): @@ -120,13 +176,19 @@ class InternalInvoluteGear(BaseGear): "App::PropertyFloat", "head_fillet", "fillets", - "a fillet for the tooth-head, radius = head_fillet x module", + translate( + "InternalInvoluteGear", + "a fillet for the tooth-head, radius = head_fillet x module", + ), ) obj.addProperty( "App::PropertyFloat", "root_fillet", "fillets", - "a fillet for the tooth-root, radius = root_fillet x module", + translate( + "InternalInvoluteGear", + "a fillet for the tooth-root, radius = root_fillet x module", + ), ) def add_tolerance_properties(self, obj): @@ -134,34 +196,68 @@ class InternalInvoluteGear(BaseGear): "App::PropertyLength", "backlash", "tolerance", - "The arc length on the pitch circle by which the tooth thicknes is reduced.", + translate( + "InternalInvoluteGear", + "The arc length on the pitch circle by which the tooth thicknes is reduced.", + ), ) obj.addProperty( - "App::PropertyBool", "reversed_backlash", "tolerance", "backlash direction" + "App::PropertyBool", + "reversed_backlash", + "tolerance", + translate("InternalInvoluteGear", "backlash direction"), ) obj.addProperty( "App::PropertyFloat", "head", "tolerance", - "head_value * modul_value = additional length of head", + translate( + "InternalInvoluteGear", + "head_value * module_value = additional length of head", + ), + ) + obj.addProperty( + "App::PropertyFloat", + "clearance", + "tolerance", + translate("InternalInvoluteGear", "clearance"), ) - obj.addProperty("App::PropertyFloat", "clearance", "tolerance", "clearance") def add_involute_properties(self, obj): - obj.addProperty("App::PropertyFloat", "shift", "involute", "shift") obj.addProperty( - "App::PropertyAngle", "pressure_angle", "involute", "pressure angle" + "App::PropertyFloat", + "shift", + "involute", + translate("InternalInvoluteGear", "shift"), + ) + obj.addProperty( + "App::PropertyAngle", + "pressure_angle", + "involute", + translate("InternalInvoluteGear", "pressure angle"), ) def add_helical_properties(self, obj): - obj.addProperty("App::PropertyAngle", "beta", "helical", "beta ") - obj.addProperty("App::PropertyBool", "double_helix", "helical", "double helix") + obj.addProperty( + "App::PropertyAngle", + "beta", + "helical", + translate("InternalInvoluteGear", "beta"), + ) + obj.addProperty( + "App::PropertyBool", + "double_helix", + "helical", + translate("InternalInvoluteGear", "double helix"), + ) obj.addProperty( "App::PropertyBool", "properties_from_tool", "helical", - "if beta is given and properties_from_tool is enabled, \ - gear parameters are internally recomputed for the rotated gear", + translate( + "InternalInvoluteGear", + "if beta is given and properties_from_tool is enabled, gear parameters are internally recomputed for the rotated gear", + ), ) def generate_gear_shape(self, fp): diff --git a/freecad/gears/involutegear.py b/freecad/gears/involutegear.py index 46b7a34..ac8b25c 100644 --- a/freecad/gears/involutegear.py +++ b/freecad/gears/involutegear.py @@ -21,6 +21,8 @@ import numpy as np from freecad import app from freecad import part +from .translateutils import translate + from pygears.involute_tooth import InvoluteTooth from pygears._functions import rotation @@ -42,7 +44,10 @@ class InvoluteGear(BaseGear): self.involute_tooth = InvoluteTooth() obj.addProperty( - "App::PropertyPythonObject", "gear", "base", "python gear object" + "App::PropertyPythonObject", + "gear", + "base", + translate("InvoluteGear", "python gear object"), ) self.add_gear_properties(obj) @@ -75,33 +80,64 @@ class InvoluteGear(BaseGear): self.compute_traverse_properties(obj) def add_gear_properties(self, obj): - obj.addProperty("App::PropertyInteger", "teeth", "base", "number of teeth") + obj.addProperty( + "App::PropertyInteger", + "teeth", + "base", + translate("InvoluteGear", "number of teeth"), + ) obj.addProperty( "App::PropertyLength", "module", "base", - "normal module if properties_from_tool=True, \ - else it's the transverse module.", + translate( + "InvoluteGear", + "normal module if properties_from_tool=True, else it's the transverse module.", + ), ) - obj.addProperty("App::PropertyLength", "height", "base", "height") obj.addProperty( - "App::PropertyAngle", "pressure_angle", "involute", "pressure angle" + "App::PropertyLength", + "height", + "base", + translate("InvoluteGear", "height"), + ) + obj.addProperty( + "App::PropertyAngle", + "pressure_angle", + "involute", + translate("InvoluteGear", "pressure angle"), + ) + obj.addProperty( + "App::PropertyFloat", + "shift", + "involute", + translate("InvoluteGear", "shift"), ) - obj.addProperty("App::PropertyFloat", "shift", "involute", "shift") def add_fillet_properties(self, obj): - obj.addProperty("App::PropertyBool", "undercut", "fillets", "undercut") + obj.addProperty( + "App::PropertyBool", + "undercut", + "fillets", + translate("InvoluteGear", "undercut"), + ) obj.addProperty( "App::PropertyFloat", "head_fillet", "fillets", - "a fillet for the tooth-head, radius = head_fillet x module", + translate( + "InvoluteGear", + "a fillet for the tooth-head, radius = head_fillet x module", + ), ) obj.addProperty( "App::PropertyFloat", "root_fillet", "fillets", - "a fillet for the tooth-root, radius = root_fillet x module", + translate( + "InvoluteGear", + "a fillet for the tooth-root, radius = root_fillet x module", + ), ) def add_helical_properties(self, obj): @@ -109,24 +145,55 @@ class InvoluteGear(BaseGear): "App::PropertyBool", "properties_from_tool", "helical", - "if beta is given and properties_from_tool is enabled, \ - gear parameters are internally recomputed for the rotated gear", + translate( + "InvoluteGear", + "if beta is given and properties_from_tool is enabled, gear parameters are internally recomputed for the rotated gear", + ), + ) + obj.addProperty( + "App::PropertyAngle", + "beta", + "helical", + translate("InvoluteGear", "beta"), + ) + obj.addProperty( + "App::PropertyBool", + "double_helix", + "helical", + translate("InvoluteGear", "double helix"), ) - obj.addProperty("App::PropertyAngle", "beta", "helical", "beta ") - obj.addProperty("App::PropertyBool", "double_helix", "helical", "double helix") def add_computed_properties(self, obj): - obj.addProperty("App::PropertyLength", "da", "computed", "outside diameter", 1) - obj.addProperty("App::PropertyLength", "df", "computed", "root diameter", 1) + obj.addProperty( + "App::PropertyLength", + "da", + "computed", + translate("InvoluteGear", "outside diameter"), + 1, + ) + obj.addProperty( + "App::PropertyLength", + "df", + "computed", + translate("InvoluteGear", "root diameter"), + 1, + ) self.add_traverse_module_property(obj) obj.addProperty( - "App::PropertyLength", "dw", "computed", "The pitch diameter.", 1 + "App::PropertyLength", + "dw", + "computed", + translate("InvoluteGear", "The pitch diameter."), + 1, ) obj.addProperty( "App::PropertyAngle", "angular_backlash", "computed", - "The angle by which this gear can turn without moving the mating gear.", + translate( + "InvoluteGear", + "The angle by which this gear can turn without moving the mating gear.", + ), ) obj.setExpression( "angular_backlash", "backlash / dw * 360° / pi" @@ -135,7 +202,11 @@ class InvoluteGear(BaseGear): "angular_backlash", 1 ) # set read-only after setting the expression, else it won't be visible. bug? obj.addProperty( - "App::PropertyLength", "transverse_pitch", "computed", "transverse_pitch", 1 + "App::PropertyLength", + "transverse_pitch", + "computed", + translate("InvoluteGear", "transverse_pitch"), + 1, ) def add_tolerance_properties(self, obj): @@ -143,26 +214,44 @@ class InvoluteGear(BaseGear): "App::PropertyLength", "backlash", "tolerance", - "The arc length on the pitch circle by which the tooth thicknes is reduced.", + translate( + "InvoluteGear", + "The arc length on the pitch circle by which the tooth thicknes is reduced.", + ), ) obj.addProperty( - "App::PropertyBool", "reversed_backlash", "tolerance", "backlash direction" + "App::PropertyBool", + "reversed_backlash", + "tolerance", + translate("InvoluteGear", "backlash direction"), + ) + obj.addProperty( + "App::PropertyFloat", + "clearance", + "tolerance", + translate("InvoluteGear", "clearance"), ) - obj.addProperty("App::PropertyFloat", "clearance", "tolerance", "clearance") obj.addProperty( "App::PropertyFloat", "head", "tolerance", - "head_value * modul_value = additional length of head", + translate( + "InvoluteGear", "head_value * module_value = additional length of head" + ), ) def add_accuracy_properties(self, obj): - obj.addProperty("App::PropertyBool", "simple", "accuracy", "simple") + obj.addProperty( + "App::PropertyBool", + "simple", + "accuracy", + translate("InvoluteGear", "simple"), + ) obj.addProperty( "App::PropertyInteger", "numpoints", "accuracy", - "number of points for spline", + translate("InvoluteGear", "number of points for spline"), ) def add_traverse_module_property(self, obj): @@ -170,7 +259,7 @@ class InvoluteGear(BaseGear): "App::PropertyLength", "traverse_module", "computed", - "traverse module of the generated gear", + translate("InvoluteGear", "traverse module of the generated gear"), 1, ) diff --git a/freecad/gears/involutegearrack.py b/freecad/gears/involutegearrack.py index a36003d..94b2322 100644 --- a/freecad/gears/involutegearrack.py +++ b/freecad/gears/involutegearrack.py @@ -21,6 +21,7 @@ import numpy as np from freecad import app from freecad import part +from .translateutils import translate from pygears.involute_tooth import InvoluteRack from .basegear import BaseGear, fcvec, points_to_wire, insert_fillet @@ -32,18 +33,45 @@ class InvoluteGearRack(BaseGear): def __init__(self, obj): super(InvoluteGearRack, self).__init__(obj) self.involute_rack = InvoluteRack() - obj.addProperty("App::PropertyInteger", "teeth", "base", "number of teeth") - obj.addProperty("App::PropertyLength", "height", "base", "height") - obj.addProperty("App::PropertyLength", "module", "base", "module") - obj.addProperty("App::PropertyLength", "thickness", "base", "thickness") + obj.addProperty( + "App::PropertyInteger", + "teeth", + "base", + translate("InvoluteGearRack", "number of teeth"), + ) + obj.addProperty( + "App::PropertyLength", + "height", + "base", + translate("InvoluteGearRack", "height"), + ) + obj.addProperty( + "App::PropertyLength", + "module", + "base", + translate("InvoluteGearRack", "module"), + ) + obj.addProperty( + "App::PropertyLength", + "thickness", + "base", + translate("InvoluteGearRack", "thickness"), + ) obj.addProperty( "App::PropertyBool", "simplified", "precision", - "if enabled the rack is drawn with a constant number of \ - teeth to avoid topologic renaming.", + translate( + "InvoluteGearRack", + "if enabled the rack is drawn with a constant number of teeth to avoid topologic renaming.", + ), + ) + obj.addProperty( + "App::PropertyPythonObject", + "rack", + "base", + translate("InvoluteGearRack", "test"), ) - obj.addProperty("App::PropertyPythonObject", "rack", "base", "test") self.add_helical_properties(obj) self.add_computed_properties(obj) @@ -70,26 +98,40 @@ class InvoluteGearRack(BaseGear): "App::PropertyBool", "properties_from_tool", "helical", - "if beta is given and properties_from_tool is enabled, \ - gear parameters are internally recomputed for the rotated gear", + translate( + "InvoluteGearRack", + "if beta is given and properties_from_tool is enabled, gear parameters are internally recomputed for the rotated gear", + ), + ) + obj.addProperty( + "App::PropertyAngle", + "beta", + "helical", + translate("InvoluteGearRack", "beta"), + ) + obj.addProperty( + "App::PropertyBool", + "double_helix", + "helical", + translate("InvoluteGearRack", "double helix"), ) - obj.addProperty("App::PropertyAngle", "beta", "helical", "beta ") - obj.addProperty("App::PropertyBool", "double_helix", "helical", "double helix") def add_computed_properties(self, obj): obj.addProperty( "App::PropertyLength", "transverse_pitch", "computed", - "pitch in the transverse plane", + translate("InvoluteGearRack", "pitch in the transverse plane"), 1, ) obj.addProperty( "App::PropertyBool", "add_endings", "base", - "if enabled the total length of the rack is teeth x pitch, \ - otherwise the rack starts with a tooth-flank", + translate( + "InvoluteGearRack", + "if enabled the total length of the rack is teeth x pitch, otherwise the rack starts with a tooth-flank", + ), ) def add_tolerance_properties(self, obj): @@ -97,18 +139,23 @@ class InvoluteGearRack(BaseGear): "App::PropertyFloat", "head", "tolerance", - "head * module = additional length of head", + translate("InvoluteGearRack", "head * module = additional length of head"), ) obj.addProperty( "App::PropertyFloat", "clearance", "tolerance", - "clearance * module = additional length of root", + translate( + "InvoluteGearRack", "clearance * module = additional length of root" + ), ) def add_involute_properties(self, obj): obj.addProperty( - "App::PropertyAngle", "pressure_angle", "involute", "pressure angle" + "App::PropertyAngle", + "pressure_angle", + "involute", + translate("InvoluteGearRack", "pressure angle"), ) def add_fillet_properties(self, obj): @@ -116,13 +163,19 @@ class InvoluteGearRack(BaseGear): "App::PropertyFloat", "head_fillet", "fillets", - "a fillet for the tooth-head, radius = head_fillet x module", + translate( + "InvoluteGearRack", + "a fillet for the tooth-head, radius = head_fillet x module", + ), ) obj.addProperty( "App::PropertyFloat", "root_fillet", "fillets", - "a fillet for the tooth-root, radius = root_fillet x module", + translate( + "InvoluteGearRack", + "a fillet for the tooth-root, radius = root_fillet x module", + ), ) def generate_gear_shape(self, obj): diff --git a/freecad/gears/lanterngear.py b/freecad/gears/lanterngear.py index 7859ce1..64376d8 100644 --- a/freecad/gears/lanterngear.py +++ b/freecad/gears/lanterngear.py @@ -22,6 +22,7 @@ import scipy as sp from freecad import app from freecad import part +from .translateutils import translate from pygears.bevel_tooth import BevelTooth from pygears._functions import rotation @@ -32,27 +33,40 @@ class LanternGear(BaseGear): def __init__(self, obj): super(LanternGear, self).__init__(obj) obj.addProperty( - "App::PropertyInteger", "teeth", "gear_parameter", "number of teeth" + "App::PropertyInteger", + "teeth", + "gear_parameter", + translate("LanternGear", "number of teeth"), + ) + obj.addProperty( + "App::PropertyLength", + "module", + "base", + translate("LanternGear", "module"), ) - obj.addProperty("App::PropertyLength", "module", "base", "module") obj.addProperty( "App::PropertyLength", "bolt_radius", "base", - "the bolt radius of the rack/chain", + translate("LanternGear", "the bolt radius of the rack/chain"), + ) + obj.addProperty( + "App::PropertyLength", + "height", + "base", + translate("LanternGear", "height"), ) - obj.addProperty("App::PropertyLength", "height", "base", "height") obj.addProperty( "App::PropertyInteger", "num_profiles", "accuracy", - "number of profiles used for loft", + translate("LanternGear", "number of profiles used for loft"), ) obj.addProperty( "App::PropertyFloat", "head", "tolerance", - "head * module = additional length of head", + translate("LanternGear", "head * module = additional length of head"), ) obj.teeth = 15 diff --git a/freecad/gears/timinggear.py b/freecad/gears/timinggear.py index 87122c3..bb0ba35 100644 --- a/freecad/gears/timinggear.py +++ b/freecad/gears/timinggear.py @@ -21,7 +21,7 @@ import numpy as np from freecad import app from freecad import part - +from .translateutils import translate from pygears._functions import reflection from .basegear import BaseGear, part_arc_from_points_and_center @@ -104,36 +104,74 @@ class TimingGear(BaseGear): def __init__(self, obj): super(TimingGear, self).__init__(obj) - obj.addProperty("App::PropertyInteger", "teeth", "base", "number of teeth") obj.addProperty( - "App::PropertyEnumeration", "type", "base", "type of timing-gear" + "App::PropertyInteger", + "teeth", + "base", + translate("TimingGear", "number of teeth"), ) - obj.addProperty("App::PropertyLength", "height", "base", "height") - obj.addProperty("App::PropertyLength", "pitch", "computed", "pitch of gear", 1) obj.addProperty( - "App::PropertyLength", "h", "computed", "radial height of teeth", 1 + "App::PropertyEnumeration", + "type", + "base", + translate("TimingGear", "type of timing-gear"), + ) + obj.addProperty( + "App::PropertyLength", + "height", + "base", + translate("TimingGear", "height"), + ) + obj.addProperty( + "App::PropertyLength", + "pitch", + "computed", + translate("TimingGear", "pitch of gear"), + 1, + ) + obj.addProperty( + "App::PropertyLength", + "h", + "computed", + translate("TimingGear", "radial height of teeth"), + 1, ) obj.addProperty( "App::PropertyLength", "u", "computed", - "radial difference between pitch diameter and head of gear", + translate( + "TimingGear", + "radial difference between pitch diameter and head of gear", + ), 1, ) obj.addProperty( - "App::PropertyLength", "r0", "computed", "radius of first arc", 1 + "App::PropertyLength", + "r0", + "computed", + translate("TimingGear", "radius of first arc"), + 1, ) obj.addProperty( - "App::PropertyLength", "r1", "computed", "radius of second arc", 1 + "App::PropertyLength", + "r1", + "computed", + translate("TimingGear", "radius of second arc"), + 1, ) obj.addProperty( - "App::PropertyLength", "rs", "computed", "radius of third arc", 1 + "App::PropertyLength", + "rs", + "computed", + translate("TimingGear", "radius of third arc"), + 1, ) obj.addProperty( "App::PropertyLength", "offset", "computed", - "x-offset of second arc-midpoint", + translate("TimingGear", "x-offset of second arc-midpoint"), 1, ) obj.teeth = 15 diff --git a/freecad/gears/timinggear_t.py b/freecad/gears/timinggear_t.py index c50c7e0..263a488 100644 --- a/freecad/gears/timinggear_t.py +++ b/freecad/gears/timinggear_t.py @@ -23,6 +23,7 @@ import scipy as sp from freecad import app from freecad import part +from .translateutils import translate from pygears._functions import rotation, reflection from .basegear import BaseGear, fcvec, part_arc_from_points_and_center, insert_fillet @@ -30,37 +31,69 @@ from .basegear import BaseGear, fcvec, part_arc_from_points_and_center, insert_f class TimingGearT(BaseGear): def __init__(self, obj): - obj.addProperty("App::PropertyLength", "pitch", "base", "pitch of gear") - obj.addProperty("App::PropertyInteger", "teeth", "base", "number of teeth") obj.addProperty( - "App::PropertyLength", "tooth_height", "base", "radial height of tooth" + "App::PropertyLength", + "pitch", + "base", + translate("TimingGearT", "pitch of gear"), + ) + obj.addProperty( + "App::PropertyInteger", + "teeth", + "base", + translate("TimingGearT", "number of teeth"), + ) + obj.addProperty( + "App::PropertyLength", + "tooth_height", + "base", + translate("TimingGearT", "radial height of tooth"), ) obj.addProperty( "App::PropertyLength", "u", "base", - "radial distance from tooth-head to pitch circle", + translate("TimingGearT", "radial distance from tooth-head to pitch circle"), ) obj.addProperty( "App::PropertyLength", "backlash", "tolerance", - "The arc length on the pitch circle by which the tooth thicknes is reduced.", + translate( + "TimingGearT" + "The arc length on the pitch circle by which the tooth thicknes is reduced.", + ), ) obj.addProperty( "App::PropertyFloat", "head_fillet", "fillets", - "a fillet for the tooth-head, radius = head_fillet x module", + translate( + "TimingGearT", + "a fillet for the tooth-head, radius = head_fillet x module", + ), ) obj.addProperty( "App::PropertyFloat", "root_fillet", "fillets", - "a fillet for the tooth-root, radius = root_fillet x module", + translate( + "TimingGearT", + "a fillet for the tooth-root, radius = root_fillet x module", + ), + ) + obj.addProperty( + "App::PropertyAngle", + "alpha", + "base", + translate("TimingGearT", "angle of tooth flanks"), + ) + obj.addProperty( + "App::PropertyLength", + "height", + "base", + translate("TimingGearT", "extrusion height"), ) - obj.addProperty("App::PropertyAngle", "alpha", "base", "angle of tooth flanks") - obj.addProperty("App::PropertyLength", "height", "base", "extrusion height") obj.pitch = "5. mm" obj.teeth = 15 obj.tooth_height = "1.2 mm" @@ -117,15 +150,16 @@ class TimingGearT(BaseGear): # for the fillets we need some more points rot = rotation(gamma_0) - p_5, p_6, p_7 = rot(np.array([p_1, p_2, p_3])) # the rotation expects a list of points - + p_5, p_6, p_7 = rot( + np.array([p_1, p_2, p_3]) + ) # the rotation expects a list of points e1 = part.LineSegment(fcvec(p_1), fcvec(p_2)).toShape() - e2 = part_arc_from_points_and_center(p_2, p_3, np.array([0., 0.])).toShape() + e2 = part_arc_from_points_and_center(p_2, p_3, np.array([0.0, 0.0])).toShape() e3 = part.LineSegment(fcvec(p_3), fcvec(p_4)).toShape() - e4 = part_arc_from_points_and_center(p_4, p_5, np.array([0., 0.])).toShape() + e4 = part_arc_from_points_and_center(p_4, p_5, np.array([0.0, 0.0])).toShape() e5 = part.LineSegment(fcvec(p_5), fcvec(p_6)).toShape() - e6 = part_arc_from_points_and_center(p_6, p_7, np.array([0., 0.])).toShape() + e6 = part_arc_from_points_and_center(p_6, p_7, np.array([0.0, 0.0])).toShape() edges = [e1, e2, e3, e4, e5, e6] edges = insert_fillet(edges, 4, head_fillet) diff --git a/freecad/gears/translateutils.py b/freecad/gears/translateutils.py new file mode 100644 index 0000000..116c235 --- /dev/null +++ b/freecad/gears/translateutils.py @@ -0,0 +1,38 @@ +# -*- coding: utf8 -*- + +# *************************************************************************** +# * * +# * Copyright (c) 2020 kbwbe * +# * * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +import FreeCAD + + +if FreeCAD.GuiUp: + from PySide.QtCore import QT_TRANSLATE_NOOP + from DraftGui import translate +else: + + def QT_TRANSLATE_NOOP(context, text): + return text + + def translate(context, text): + return text diff --git a/freecad/gears/translations/update_translation.sh b/freecad/gears/translations/update_translation.sh new file mode 100755 index 0000000..6375972 --- /dev/null +++ b/freecad/gears/translations/update_translation.sh @@ -0,0 +1,108 @@ +#!/usr/bin/env bash + +# -------------------------------------------------------------------------------------------------- +# +# Update translation files +# +# Supported locales on FreeCAD <2024-01-20, FreeCADGui.supportedLocales(), total=40>: +# {'English': 'en', 'Afrikaans': 'af', 'Arabic': 'ar', 'Basque': 'eu', 'Belarusian': 'be', +# 'Bulgarian': 'bg', 'Catalan': 'ca', 'Chinese Simplified': 'zh-CN', +# 'Chinese Traditional': 'zh-TW', 'Croatian': 'hr', 'Czech': 'cs', 'Dutch': 'nl', +# 'Filipino': 'fil', 'Finnish': 'fi', 'French': 'fr', 'Galician': 'gl', 'Georgian': 'ka', +# 'German': 'de', 'Greek': 'el', 'Hungarian': 'hu', 'Indonesian': 'id', 'Italian': 'it', +# 'Japanese': 'ja', 'Kabyle': 'kab', 'Korean': 'ko', 'Lithuanian': 'lt', 'Norwegian': 'no', +# 'Polish': 'pl', 'Portuguese': 'pt-PT', 'Portuguese, Brazilian': 'pt-BR', 'Romanian': 'ro', +# 'Russian': 'ru', 'Serbian': 'sr', 'Serbian, Latin': 'sr-CS', 'Slovak': 'sk', +# 'Slovenian': 'sl', 'Spanish': 'es-ES', 'Spanish, Argentina': 'es-AR', 'Swedish': 'sv-SE', +# 'Turkish': 'tr', 'Ukrainian': 'uk', 'Valencian': 'val-ES', 'Vietnamese': 'vi'} +# +# NOTE: WORKFLOW +# 0. Install Qt tools +# Debian-based (e.g., Ubuntu): $ sudo apt-get install qttools5-dev-tools pyqt6-dev-tools +# Fedora-based: $ sudo dnf install qt6-linguist qt6-devel +# Arch-based: $ sudo pacman -S qt6-tools python-pyqt6 +# 1. Make the script executable +# $ chmod +x update_translation.sh +# 2. Execute the script passing the locale code as first parameter +# The script has to be executed within the `resources/translations` directory +# Only update the files you're translating! +# $ ./update_translation.sh es-ES +# 3. Do the translation via Qt Linguist and use `File>Release` +# 4. If releasing with the script execute the script passing the locale code +# as first parameter and use '-r' flag next +# $ ./update_translation.sh es-ES -r +# +# The usage of `pylupdate6` is preferred over 'pylupdate5' when extracting text strings from +# Python files. +# +# -------------------------------------------------------------------------------------------------- + +supported_locales=( + "en" "af" "ar" "eu" "be" "bg" "ca" "zh-CN" "zh-TW" "hr" + "cs" "nl" "fil" "fi" "fr" "gl" "ka" "de" "el" "hu" + "id" "it" "ja" "kab" "ko" "lt" "no" "pl" "pt-PT" "pt-BR" + "ro" "ru" "sr" "es-ES" "es-AR" "sv-SE" "tr" "uk" "val-ES" "vi" +) + +is_locale_supported() { + local locale="$1" + for supported_locale in "${supported_locales[@]}"; do + if [[ "$supported_locale" == "$locale" ]]; then + return 0 + fi + done + return 1 +} + +get_strings() { + # Get translatable strings from ../../*.py Python files + pylupdate6 ../*.py -ts pyfiles.ts +} + +delete_files() { + # Delete files that are no longer needed + rm pyfiles.ts + rm -f ${WB}.ts +} + +add_new_locale() { + echo -e "\033[1;33m\n\t<<< Creating '${WB}_${LOCALE}.ts' file >>>\n\033[m" + get_strings + # Join strings from Qt Designer and Python files + lconvert -source-language en -target-language $LOCALE \ + -i pyfiles.ts -o ${WB}_${LOCALE}.ts +} + +update_locale() { + echo -e "\033[1;32m\n\t<<< Updating '${WB}_${LOCALE}.ts' file >>>\n\033[m" + get_strings + # Join newly created file with older file ( -no-obsolete) + lconvert -source-language en -target-language $LOCALE \ + -i pyfiles.ts ${WB}_${LOCALE}.ts -o ${WB}_${LOCALE}.ts -no-obsolete +} + +release_translation() { + # Release translation (creation of *.qm file from *.ts file) + lrelease ${WB}_${LOCALE}.ts +} + +# Main function ------------------------------------------------------------------------------------ + +WB="Gear" +LOCALE="$1" + +if is_locale_supported "$LOCALE"; then + if [ "$2" == "-r" ]; then + release_translation + else + if [ ! -f "${WB}_${LOCALE}.ts" ]; then + add_new_locale + else + update_locale + fi + delete_files + fi +else + echo "Verify your language code. Case sensitive." + echo "If it's correct ask a maintainer to add support for your language on FreeCAD." +fi diff --git a/freecad/gears/wormgear.py b/freecad/gears/wormgear.py index 40ae5ff..21dd46f 100644 --- a/freecad/gears/wormgear.py +++ b/freecad/gears/wormgear.py @@ -21,6 +21,7 @@ import numpy as np from freecad import app from freecad import part +from .translateutils import translate from pygears.involute_tooth import InvoluteTooth from pygears._functions import rotation @@ -33,28 +34,60 @@ class WormGear(BaseGear): def __init__(self, obj): super(WormGear, self).__init__(obj) - obj.addProperty("App::PropertyInteger", "teeth", "base", "number of teeth") - obj.addProperty("App::PropertyLength", "module", "base", "module") - obj.addProperty("App::PropertyLength", "height", "base", "height") - obj.addProperty("App::PropertyLength", "diameter", "base", "diameter") - obj.addProperty("App::PropertyAngle", "beta", "computed", "beta ", 1) obj.addProperty( - "App::PropertyAngle", "pressure_angle", "involute", "pressure angle" + "App::PropertyInteger", + "teeth", + "base", + translate("WormGear", "number of teeth"), ) obj.addProperty( - "App::PropertyBool", "reverse_pitch", "base", "reverse rotation of helix" + "App::PropertyLength", + "module", + "base", + translate("WormGear", "module"), + ) + obj.addProperty( + "App::PropertyLength", + "height", + "base", + translate("WormGear", "height"), + ) + obj.addProperty( + "App::PropertyLength", + "diameter", + "base", + translate("WormGear", "diameter"), + ) + obj.addProperty( + "App::PropertyAngle", + "beta", + "computed", + translate("WormGear", "beta"), + 1, + ) + obj.addProperty( + "App::PropertyAngle", + "pressure_angle", + "involute", + translate("WormGear", "pressure angle"), + ) + obj.addProperty( + "App::PropertyBool", + "reverse_pitch", + "base", + translate("WormGear", "reverse rotation of helix"), ) obj.addProperty( "App::PropertyFloat", "head", "tolerance", - "head * module = additional length of head", + translate("WormGear", "head * module = additional length of head"), ) obj.addProperty( "App::PropertyFloat", "clearance", "tolerance", - "clearance * module = additional length of root", + translate("WormGear", "clearance * module = additional length of root"), ) obj.teeth = 3 obj.module = "1. mm"