From 9a34a397db3b768caa2a2068916edf57111bd927 Mon Sep 17 00:00:00 2001 From: hasecilu Date: Fri, 23 Feb 2024 13:20:57 -0600 Subject: [PATCH 01/10] Revert af56ed77 --- Asm4_Translate.py | 14 +- FastenersDummy.py | 1 + FastenersLib.py | 1 - HelpCmd.py | 7 +- InitGui.py | 356 +++++++++++++++++++++++++-------------------- gotoDocumentCmd.py | 3 +- newAssemblyCmd.py | 4 +- newPartCmd.py | 2 +- 8 files changed, 222 insertions(+), 166 deletions(-) diff --git a/Asm4_Translate.py b/Asm4_Translate.py index bac75007..a05715b4 100644 --- a/Asm4_Translate.py +++ b/Asm4_Translate.py @@ -5,12 +5,20 @@ # # Asm4_Translate.py - +import os +import FreeCADGui as Gui import FreeCAD as App +Gui.addLanguagePath(os.path.join(os.path.dirname(__file__), "Resources/translations")) + + +def _atr(context: str, text: str) -> str: + """Wrap strings which should be translated in in this function.""" + return App.Qt.translate(context, text) + -# dummy function for the QT translator -def QT_TRANSLATE_NOOP(context, text): +def QT_TRANSLATE_NOOP(context: str, text: str) -> str: + """NOP Marker Macro Alias for strings for which FreeCAD/Qt handles translations.""" return text diff --git a/FastenersDummy.py b/FastenersDummy.py index 3644bd60..bc04ba8f 100644 --- a/FastenersDummy.py +++ b/FastenersDummy.py @@ -9,6 +9,7 @@ import FreeCADGui as Gui import FreeCAD as App +from TranslateUtils import translate #from FastenerBase import FSBaseObject import Asm4_libs as Asm4 diff --git a/FastenersLib.py b/FastenersLib.py index 12b57b61..8e2d183c 100644 --- a/FastenersLib.py +++ b/FastenersLib.py @@ -20,7 +20,6 @@ from Asm4_Translate import translate - # icon to show in the Menu, toolbar and widget window iconFile = os.path.join( Asm4.iconPath , 'Asm4_mvFastener.svg') diff --git a/HelpCmd.py b/HelpCmd.py index ce11abe6..855dc5b5 100644 --- a/HelpCmd.py +++ b/HelpCmd.py @@ -6,12 +6,11 @@ # # HelpCmd.py -import os, webbrowser - -import FreeCADGui as Gui - +import os +import webbrowser import Asm4_libs as Asm4 from Asm4_Translate import translate +import FreeCADGui as Gui """ diff --git a/InitGui.py b/InitGui.py index f3da1528..654c5013 100644 --- a/InitGui.py +++ b/InitGui.py @@ -25,22 +25,24 @@ import os import Asm4_locator -global Asm4_icon, Asm4_path, Asm4_trans -Asm4_path = os.path.dirname( Asm4_locator.__file__ ) -Asm4_icon = os.path.join( Asm4_path , 'Resources/icons/Assembly4.svg' ) -Asm4_trans = os.path.join(Asm4_path, "Resources/translations") # I don't like this being here import selectionFilter +global Asm4_icon, Asm4_path, Asm4_trans +Asm4_path = os.path.dirname(Asm4_locator.__file__) +Asm4_icon = os.path.join(Asm4_path, "Resources/icons/Assembly4.svg") +Asm4_trans = os.path.join(Asm4_path, "Resources/translations") + """ +-----------------------------------------------+ | Initialize the workbench | +-----------------------------------------------+ """ -class Assembly4Workbench(Workbench): + +class Assembly4Workbench(Workbench): global Asm4_icon global selectionFilter MenuText = "Assembly 4" @@ -64,12 +66,14 @@ def __init__(self): def Activated(self): "This function is executed when the workbench is activated" + # FreeCAD.Console.PrintMessage(translate("Asm4", "Activating Assembly4 WorkBench") + '\n') # make buttons of the selection toolbar checkable from PySide import QtGui + mainwin = Gui.getMainWindow() sf_tb = None for tb in mainwin.findChildren(QtGui.QToolBar): - if tb.objectName()=='Selection Filter': + if tb.objectName() == "Selection Filter": sf_tb = tb # make all buttons except last one (clear selection filter) checkable if sf_tb is not None: @@ -80,6 +84,7 @@ def Activated(self): def Deactivated(self): "This function is executed when the workbench is deactivated" selectionFilter.observerDisable() + # FreeCAD.Console.PrintMessage(translate("Asm4", "Leaving Assembly4 WorkBench") + "\n") return def GetClassName(self): @@ -91,6 +96,7 @@ def GetClassName(self): | This is where all is defined | +-----------------------------------------------+ """ + def Initialize(self): # check for FreeCAD version FCver = FreeCAD.Version() @@ -112,90 +118,119 @@ def Initialize(self): ''' # Translations - # from Asm4_Translate import Qtranslate + # from Asm4_Translate import translate FreeCADGui.addLanguagePath(Asm4_trans) FreeCADGui.updateLocale() # Assembly4 version info # with file package.xml (FreeCAD ≥0.21) - packageFile = os.path.join( Asm4_path, 'package.xml' ) + packageFile = os.path.join(Asm4_path, "package.xml") try: - metadata = FreeCAD.Metadata(packageFile) - Asm4_date = metadata.Date + metadata = FreeCAD.Metadata(packageFile) + Asm4_date = metadata.Date Asm4_version = metadata.Version # with file VERSION (FreeCAD ≤0.20) except: - versionPath = os.path.join( Asm4_path, 'VERSION' ) - versionFile = open(versionPath,"r") + """ + FCVersion = App.Version()[0]+'.'+App.Version()[1] + if FCVersion=='0.19': + FCDate = " from "+App.Version()[4][0:4] + elif FCVersion=='0.20': + FCDate = " from "+App.Version()[5][0:4] + else : + FCDate = "" + message = "You seem to be using FreeCAD version "+FCVersion+FCDate+" which is quite old. " + message += "Some functionality of latest versions might be missing\n" + FreeCAD.Console.PrintMessage(message) + """ + versionPath = os.path.join(Asm4_path, "VERSION") + versionFile = open(versionPath, "r") # read second line version = versionFile.readlines()[1] versionFile.close() # remove trailing newline Asm4_version = version[:-1] - - FreeCAD.Console.PrintMessage("Initializing Assembly4 workbench"+ ' ('+Asm4_version+') .') - FreeCADGui.updateGui() - # import all stuff - import newAssemblyCmd # created an App::Part container called 'Assembly' - self.dot() - import newDatumCmd # creates a new LCS in 'Model' + + FreeCAD.Console.PrintMessage(translate("Asm4", "Initializing Assembly4 workbench")+ ' ('+Asm4_version+') .') + self.dot() - import newPartCmd # creates a new App::Part container called 'Model' + import newPartCmd # creates a new App::Part container called 'Model' + self.dot() - import infoPartCmd # edits part information for BoM + import infoPartCmd # edits part information for BoM + self.dot() - import insertLinkCmd # inserts an App::Link to a 'Model' in another file + import insertLinkCmd # inserts an App::Link to a 'Model' in another file + self.dot() - import placeLinkCmd # places a linked part by snapping LCS (in the Part and in the Assembly) + import placeLinkCmd # places a linked part by snapping LCS (in the Part and in the Assembly) + self.dot() - import importDatumCmd # creates an LCS in assembly and attaches it to an LCS relative to an external file + import importDatumCmd # creates an LCS in assembly and attaches it to an LCS relative to an external file + self.dot() - import releaseAttachmentCmd# creates an LCS in assembly and attaches it to an LCS relative to an external file + import releaseAttachmentCmd # creates an LCS in assembly and attaches it to an LCS relative to an external file + self.dot() - import makeBinderCmd # creates an LCS in assembly and attaches it to an LCS relative to an external file + import makeBinderCmd # creates an LCS in assembly and attaches it to an LCS relative to an external file + self.dot() - import VariablesLib # creates an LCS in assembly and attaches it to an LCS relative to an external file + import VariablesLib # creates an LCS in assembly and attaches it to an LCS relative to an external file + self.dot() - import AnimationLib # creates an LCS in assembly and attaches it to an LCS relative to an external file + import AnimationLib # creates an LCS in assembly and attaches it to an LCS relative to an external file + self.dot() - import updateAssemblyCmd # updates all parts and constraints in the assembly + import updateAssemblyCmd # updates all parts and constraints in the assembly + self.dot() - import makeArrayCmd # creates a new array of App::Link + import makeArrayCmd # creates a new array of App::Link + self.dot() - import variantLinkCmd # creates a variant link + import variantLinkCmd # creates a variant link + self.dot() - import gotoDocumentCmd # opens the documentof the selected App::Link + import gotoDocumentCmd # opens the documentof the selected App::Link + self.dot() - import Asm4_Measure # Measure tool in the Task panel + import Asm4_Measure # Measure tool in the Task panel + self.dot() - import makeBomCmd # creates the parts list + import makeBomCmd # creates the parts list + self.dot() - import checkInterference # check interferences btween parts inside the Assembly + import checkInterference # check interferences btween parts inside the Assembly + self.dot() - import exportFiles # creates a hierarchical tree listing of files in an assembly + import exportFiles # creates a hierarchical tree listing of files in an assembly + self.dot() - import HelpCmd # shows a basic help window + import HelpCmd # shows a basic help window + self.dot() - import showHideLcsCmd # shows/hides all the LCSs + import showHideLcsCmd # shows/hides all the LCSs + self.dot() - import configurationEngine # save/restore configuration + import configurationEngine # save/restore configuration + self.dot() # Fasteners - if self.checkWorkbench('FastenersWorkbench'): + if self.checkWorkbench("FastenersWorkbench"): # a library to handle fasteners from the FastenersWorkbench import FastenersLib - self.FastenersCmd = 'Asm4_Fasteners' + + self.FastenersCmd = "Asm4_Fasteners" else: # a dummy library if the FastenersWorkbench is not installed import FastenersDummy - self.FastenersCmd = 'Asm4_insertScrew' - self.dot() + self.FastenersCmd = "Asm4_insertScrew" + self.dot() # Define Menus # commands to appear in the Assembly4 menu 'Assembly' - self.appendMenu("&Assembly", self.assemblyMenuItems()) + self.appendMenu(translate("Workbench", "&Assembly"), self.assemblyMenuItems()) self.dot() # put all constraints related commands in a separate menu @@ -205,177 +240,188 @@ def Initialize(self): # self.appendMenu("&Geometry",["Asm4_newPart"]) # additional entry in the Help menu - # self.appendMenu(Qtranslate("Workbench", "&Help"), ["Asm4_Help"]) - self.appendMenu( "&Help", ["Asm4_Help"]) + # self.appendMenu(translate("Workbench", "&Help"), ["Asm4_Help"]) + self.appendMenu("&Help", ["Asm4_Help"]) self.dot() # Define Toolbars # commands to appear in the Assembly4 toolbar - self.appendToolbar("Assembly", self.assemblyToolbarItems()) + self.appendToolbar(translate("Asm4", "Assembly"), self.assemblyToolbarItems()) self.dot() # build the selection toolbar - self.appendToolbar("Selection Filter", self.selectionToolbarItems()) + self.appendToolbar( + translate("Asm4", "Selection Filter"), self.selectionToolbarItems() + ) self.dot() # self.appendToolbar("Geometry",["Asm4_newPart"]) - FreeCAD.Console.PrintMessage(" " + "done" + ".\n") + FreeCAD.Console.PrintMessage(" " + translate("Asm4", "done") + ".\n") """ +-----------------------------------------------+ | Initialisation finished | +-----------------------------------------------+ """ - - """ +-----------------------------------------------+ | Assembly Menu & Toolbar | +-----------------------------------------------+ """ + def assemblyMenuItems(self): - commandList = [ "Asm4_newAssembly", - "Asm4_newPart", - "Asm4_newBody", - "Asm4_newGroup", - "Asm4_newSketch", - 'Asm4_createDatum', - self.FastenersCmd, - "Separator", - "Asm4_insertLink", - "Asm4_mirrorArray", - "Asm4_linearArray", - "Asm4_circularArray", - "Asm4_expressionArray", - "Asm4_variantLink", - "Separator", - "Asm4_cloneFastenersToAxes", - "Asm4_importDatum", - "Asm4_shapeBinder", - "Separator", - "Asm4_infoPart", - "Asm4_makeLocalBOM", - "Asm4_makeBOM", - "Asm4_listLinkedFiles", - "Asm4_checkInterference", - "Asm4_Measure", - 'Asm4_showLcs', - 'Asm4_hideLcs', - "Asm4_addVariable", - "Asm4_delVariable", - "Asm4_Animate", - "Asm4_openConfigurations" - ] + commandList = [ + "Asm4_newAssembly", + "Asm4_newPart", + "Asm4_newBody", + "Asm4_newGroup", + "Asm4_newSketch", + "Asm4_createDatum", + self.FastenersCmd, + "Separator", + "Asm4_insertLink", + "Asm4_mirrorArray", + "Asm4_linearArray", + "Asm4_circularArray", + "Asm4_expressionArray", + "Asm4_variantLink", + "Separator", + "Asm4_cloneFastenersToAxes", + "Asm4_importDatum", + "Asm4_shapeBinder", + "Separator", + "Asm4_infoPart", + "Asm4_makeLocalBOM", + "Asm4_makeBOM", + "Asm4_listLinkedFiles", + "Asm4_checkInterference", + "Asm4_Measure", + "Asm4_showLcs", + "Asm4_hideLcs", + "Asm4_addVariable", + "Asm4_delVariable", + "Asm4_Animate", + "Asm4_openConfigurations", + ] return commandList def constraintsMenuItems(self): - commandList = [ "Asm4_placeLink", - "Asm4_releaseAttachment", - "Separator", - "Asm4_updateAssembly", - "Separator", - ] + commandList = [ + "Asm4_placeLink", + "Asm4_releaseAttachment", + "Separator", + "Asm4_updateAssembly", + "Separator", + ] return commandList def assemblyToolbarItems(self): - commandList = [ "Asm4_newAssembly", - "Asm4_newPart", - "Asm4_newBody", - "Asm4_newGroup", - "Asm4_infoPart", - "Asm4_insertLink", - "Asm4_variantLink", - self.FastenersCmd, - "Separator", - "Asm4_newSketch", - 'Asm4_createDatum', - "Asm4_importDatum", - "Asm4_shapeBinder", - "Separator", - "Asm4_placeLink", - "Asm4_releaseAttachment", - "Asm4_updateAssembly", - "Separator", - "Asm4_mirrorArray", - "Asm4_linearArray", - "Asm4_circularArray", - "Asm4_expressionArray", - "Asm4_variablesCmd", - "Separator", - "Asm4_Animate", - "Asm4_Measure", - "Asm4_makeBOM", - "Asm4_listLinkedFiles", - 'Asm4_showLcs', - 'Asm4_hideLcs', - "Asm4_checkInterference", - "Asm4_openConfigurations" - ] + commandList = [ + "Asm4_newAssembly", + "Asm4_newPart", + "Asm4_newBody", + "Asm4_newGroup", + "Asm4_infoPart", + "Asm4_insertLink", + "Asm4_variantLink", + self.FastenersCmd, + "Separator", + "Asm4_newSketch", + "Asm4_createDatum", + "Asm4_importDatum", + "Asm4_shapeBinder", + "Separator", + "Asm4_placeLink", + "Asm4_releaseAttachment", + "Asm4_updateAssembly", + "Separator", + "Asm4_mirrorArray", + "Asm4_linearArray", + "Asm4_circularArray", + "Asm4_expressionArray", + "Asm4_variablesCmd", + "Separator", + "Asm4_Animate", + "Asm4_Measure", + "Asm4_makeBOM", + "Asm4_listLinkedFiles", + "Asm4_showLcs", + "Asm4_hideLcs", + "Asm4_checkInterference", + "Asm4_openConfigurations", + ] return commandList - """ +-----------------------------------------------+ | Selection Toolbar | +-----------------------------------------------+ """ + def selectionToolbarItems(self): # commands to appear in the Selection toolbar - commandList = ["Asm4_SelectionFilterVertexCmd", - "Asm4_SelectionFilterEdgeCmd", - "Asm4_SelectionFilterFaceCmd", - "Asm4_selObserver3DViewCmd" , - "Asm4_SelectionFilterClearCmd"] + commandList = [ + "Asm4_SelectionFilterVertexCmd", + "Asm4_SelectionFilterEdgeCmd", + "Asm4_SelectionFilterFaceCmd", + "Asm4_selObserver3DViewCmd", + "Asm4_SelectionFilterClearCmd", + ] return commandList - """ +-----------------------------------------------+ | Contextual Menus | +-----------------------------------------------+ """ + def ContextMenu(self, recipient): # This is executed whenever the user right-clicks on screen" # "recipient" will be either "view" or "tree" - contextMenu = ['Asm4_gotoDocument' , - 'Asm4_showLcs' , - 'Asm4_hideLcs' ] + contextMenu = ["Asm4_gotoDocument", "Asm4_showLcs", "Asm4_hideLcs"] # commands to appear in the 'Assembly' sub-menu in the contextual menu (right-click) - assemblySubMenu =[ "Asm4_insertLink" , - "Asm4_placeLink" , - "Asm4_importDatum" , - 'Asm4_FSparameters' , - 'Separator' , - 'Asm4_applyConfiguration'] + assemblySubMenu = [ + "Asm4_insertLink", + "Asm4_placeLink", + "Asm4_importDatum", + "Asm4_FSparameters", + "Separator", + "Asm4_applyConfiguration", + ] # commands to appear in the 'Create' sub-menu in the contextual menu (right-click) - createSubMenu =["Asm4_newSketch", - "Asm4_newBody", - "Asm4_newLCS", - "Asm4_newAxis", - "Asm4_newPlane", - "Asm4_newPoint", - "Asm4_newHole", - "Asm4_insertScrew", - "Asm4_insertNut", - "Asm4_insertWasher", - 'Separator', - 'Asm4_newConfiguration'] + createSubMenu = [ + "Asm4_newSketch", + "Asm4_newBody", + "Asm4_newLCS", + "Asm4_newAxis", + "Asm4_newPlane", + "Asm4_newPoint", + "Asm4_newHole", + "Asm4_insertScrew", + "Asm4_insertNut", + "Asm4_insertWasher", + "Separator", + "Asm4_newConfiguration", + ] self.appendContextMenu("", "Separator") self.appendContextMenu("", contextMenu) # add commands to the context menu - self.appendContextMenu("Assembly", assemblySubMenu) # add commands to the context menu - self.appendContextMenu("Create", createSubMenu) # add commands to the context menu + self.appendContextMenu( + translate("Asm4", "Assembly"), assemblySubMenu + ) # add commands to the context menu + self.appendContextMenu( + translate("Asm4", "Create"), createSubMenu + ) # add commands to the context menu self.appendContextMenu("", "Separator") - - """ +-----------------------------------------------+ | helper functions | +-----------------------------------------------+ """ - def checkWorkbench( self, workbench ): + + def checkWorkbench(self, workbench): # checks whether the specified workbench (a 'string') is installed listWB = Gui.listWorkbenches() hasWB = False diff --git a/gotoDocumentCmd.py b/gotoDocumentCmd.py index 742ac5e1..43b64cc6 100644 --- a/gotoDocumentCmd.py +++ b/gotoDocumentCmd.py @@ -8,11 +8,12 @@ -import os +import math, re, os from PySide import QtGui, QtCore import FreeCADGui as Gui import FreeCAD as App +import Part import Asm4_libs as Asm4 from Asm4_Translate import translate diff --git a/newAssemblyCmd.py b/newAssemblyCmd.py index 27dd65bb..5bc77156 100644 --- a/newAssemblyCmd.py +++ b/newAssemblyCmd.py @@ -19,6 +19,8 @@ +from TranslateUtils import translate + class newAssemblyCmd: """ +-----------------------------------------------+ @@ -39,7 +41,7 @@ def makeAssembly(): def GetResources(self): tooltip = translate("Commands", "

Create a new Assembly container

") iconFile = os.path.join( Asm4.iconPath , 'Asm4_Model.svg') - return {"MenuText": "New Assembly", "ToolTip": tooltip, "Pixmap" : iconFile } + return {"MenuText": translate("Commands", "New Assembly"), "ToolTip": tooltip, "Pixmap" : iconFile } def IsActive(self): diff --git a/newPartCmd.py b/newPartCmd.py index 59cee0c3..e384c9d2 100644 --- a/newPartCmd.py +++ b/newPartCmd.py @@ -9,7 +9,7 @@ -import os +import math, re, os from PySide import QtGui, QtCore import FreeCADGui as Gui From 8cd58879a277132d2a9301362539765f40eac4cf Mon Sep 17 00:00:00 2001 From: hasecilu Date: Fri, 23 Feb 2024 15:12:24 -0600 Subject: [PATCH 02/10] Add `BaseCommand` class This class is used to assign the resources from `self.pixmap`, `self.menutext`, `self.tooltip` instance variables. Variables are assigned on `__init__()` methods. The code is more readable than previous dictionary returns. --- BaseCommand.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 BaseCommand.py diff --git a/BaseCommand.py b/BaseCommand.py new file mode 100644 index 00000000..95a9d3f0 --- /dev/null +++ b/BaseCommand.py @@ -0,0 +1,23 @@ +import os + +import FreeCAD +import FreeCADGui as Gui + +from TranslateUtils import translate + +class BaseCommand(object): + """Base class to prepare all the commands.""" + + def __init__(self): + pass + + def Activated(self): + pass + + def GetResources(self): + return { + "Pixmap": self.pixmap, + "MenuText": self.menutext, + "ToolTip": self.tooltip, + } + From b7c38120b2babed60b6c6927de7f31b4f412687d Mon Sep 17 00:00:00 2001 From: hasecilu Date: Fri, 23 Feb 2024 17:17:28 -0600 Subject: [PATCH 03/10] Continue translation efforts This commit applies the `translation()` function to more tooltips. Also make the classes to be child of BaseCommand class to inherit GetResources() method which facilitates process. --- BaseCommand.py | 9 +---- FastenersDummy.py | 45 ++++++++++----------- FastenersLib.py | 100 +++++++++++++++++++++++----------------------- infoPartCmd.py | 15 +++---- insertLinkCmd.py | 30 ++++++-------- variantLinkCmd.py | 22 +++++----- 6 files changed, 103 insertions(+), 118 deletions(-) diff --git a/BaseCommand.py b/BaseCommand.py index 95a9d3f0..91a21c97 100644 --- a/BaseCommand.py +++ b/BaseCommand.py @@ -1,11 +1,4 @@ -import os - -import FreeCAD -import FreeCADGui as Gui - -from TranslateUtils import translate - -class BaseCommand(object): +class BaseCommand(): """Base class to prepare all the commands.""" def __init__(self): diff --git a/FastenersDummy.py b/FastenersDummy.py index bc04ba8f..99793f90 100644 --- a/FastenersDummy.py +++ b/FastenersDummy.py @@ -9,7 +9,9 @@ import FreeCADGui as Gui import FreeCAD as App -from TranslateUtils import translate + +from BaseCommand import BaseCommand +from Asm4_Translate import translate #from FastenerBase import FSBaseObject import Asm4_libs as Asm4 @@ -29,10 +31,14 @@ screwObj = sm.createFastener('ISO7046', 'M6', '20', 'simple', shapeOnly=False) """ -class insertFastener: +class insertFastener(BaseCommand): "My tool object" def __init__(self, fastenerType): self.fastenerType = fastenerType + self.tooltip = translate("Fasteners", + "FastenersWorkbench is not installed.\n \n" + "You can install it with the FreeCAD AddonsManager:\n" + "Menu Tools > Addon Manager > fasteners") # Screw: if self.fastenerType=='Screw': self.menutext = translate("Fasteners", "Insert Screw") @@ -73,17 +79,17 @@ def Activated(self): | dummy placeFastener | +-----------------------------------------------+ """ -class placeFastenerCmd(): +class placeFastenerCmd(BaseCommand): "My tool object" def __init__(self): super(placeFastenerCmd,self).__init__() - - def GetResources(self): - return {"MenuText": "Edit Attachment of a Fastener", - "ToolTip": 'FastenersWorkbench is not installed.\n \nYou can install it with the FreeCAD AddonsManager:\nMenu Tools > Addon Manager > fasteners', - "Pixmap" : os.path.join( Asm4.iconPath , 'Asm4_mvFastener.svg') - } + self.icon = os.path.join( Asm4.iconPath , 'Asm4_mvFastener.svg') + self.menutext = translate("Fasteners", "Edit Attachment of a Fastener") + self.tooltip = translate("Fasteners", + "FastenersWorkbench is not installed.\n \n" + "You can install it with the FreeCAD AddonsManager:\n" + "Menu Tools > Addon Manager > fasteners") def IsActive(self): # it's a dummy, always inactive @@ -98,15 +104,13 @@ def Activated(self): | dummy parameters | +-----------------------------------------------+ """ -class changeFSparametersCmd(): +class changeFSparametersCmd(BaseCommand): def __init__(self): super(changeFSparametersCmd,self).__init__() - - def GetResources(self): - return {"MenuText": "Change Fastener parameters", - "ToolTip": "Change Fastener parameters", - "Pixmap" : os.path.join( Asm4.iconPath , 'Asm4_FSparams.svg') - } + self.icon = os.path.join( Asm4.iconPath , 'Asm4_FSparams.svg') + self.menutext = translate("Fasteners", "Change Fastener parameters") + self.tooltip = translate("Fasteners", + "Change Fastener parameters") def IsActive(self): # it's a dummy, always inactive @@ -117,15 +121,10 @@ def Activated(self): -class cloneFastenersToAxesCmd(): +class cloneFastenersToAxesCmd(BaseCommand): def __init__(self): super(cloneFastenersToAxesCmd,self).__init__() - - def GetResources(self): - return {"MenuText": "Clone Fastener to Axes", - "ToolTip": 'FastenersWorkbench is not installed.\n \nYou can install it with the FreeCAD AddonsManager:\nMenu Tools > Addon Manager > fasteners', - "Pixmap" : os.path.join( Asm4.iconPath , 'Asm4_cloneFasteners.svg') - } + self.pixmap def IsActive(self): # it's a dummy, always inactive diff --git a/FastenersLib.py b/FastenersLib.py index 8e2d183c..8d33b525 100644 --- a/FastenersLib.py +++ b/FastenersLib.py @@ -20,6 +20,7 @@ from Asm4_Translate import translate + # icon to show in the Menu, toolbar and widget window iconFile = os.path.join( Asm4.iconPath , 'Asm4_mvFastener.svg') @@ -48,7 +49,7 @@ """ -class insertFastener: +class insertFastener(BaseCommand): "My tool object" def __init__(self, fastenerType): self.FSclass = fastenerType @@ -58,40 +59,43 @@ def __init__(self, fastenerType): 'ThreadedRod':(0.3, 0.5, 0.75) } # Screw - if self.FSclass == 'Screw': - self.menutext = translate("Fasteners", "Insert Screw") - self.tooltip = "

Insert a Screw into the Assembly

" - self.tooltip += "

If another fastener is selected, a new fastener of the same type is created in the same assembly." - self.tooltip += "If an axis or LCS is selected, the new fastener will be attached to it." - self.tooltip += "If an assembly is selected, the new fastener will be inside that assembly.

" - self.icon = os.path.join( Asm4.iconPath , 'Asm4_Screw.svg') + if self.FSclass == "Screw": + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_Screw.svg") + self.menutext = translate("Fasteners", "Insert Screw") + self.tooltip = translate( + "Fasteners", + "

Insert a Screw into the Assembly

\n" + "

If another fastener is selected, a new fastener of the same type is created in the same assembly.\n" + "If an axis or LCS is selected, the new fastener will be attached to it.\n" + "If an assembly is selected, the new fastener will be inside that assembly.

", + ) # Nut - elif self.FSclass == 'Nut': - self.menutext = translate("Fasteners", "Insert Nut") - self.tooltip = "

Insert a Nut into the Assembly

" - self.tooltip += "

If another fastener is selected, a new fastener of the same type is created in the same assembly." - self.tooltip += "If an axis or LCS is selected, the new fastener will be attached to it." - self.tooltip += "If an assembly is selected, the new fastener will be inside that assembly.

" - self.icon = os.path.join( Asm4.iconPath , 'Asm4_Nut.svg') + elif self.FSclass == "Nut": + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_Nut.svg") + self.menutext = translate("Fasteners", "Insert Nut") + self.tooltip = translate( + "Fasteners", + "

Insert a Nut into the Assembly

\n" + "

If another fastener is selected, a new fastener of the same type is created in the same assembly.\n" + "If an axis or LCS is selected, the new fastener will be attached to it.\n" + "If an assembly is selected, the new fastener will be inside that assembly.

", + ) # Washer - elif self.FSclass == 'Washer': - self.menutext = translate("Fasteners", "Insert Washer") - self.tooltip = "

Insert a Washer into the Assembly

" - self.tooltip += "

If another fastener is selected, a new fastener of the same type is created in the same assembly." - self.tooltip += "If an axis or LCS is selected, the new fastener will be attached to it." - self.tooltip += "If an assembly is selected, the new fastener will be inside that assembly.

" - self.icon = os.path.join( Asm4.iconPath , 'Asm4_Washer.svg') + elif self.FSclass == "Washer": + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_Washer.svg") + self.menutext = translate("Fasteners", "Insert Washer") + self.tooltip = translate( + "Fasteners", + "

Insert a Washer into the Assembly

\n" + "

If another fastener is selected, a new fastener of the same type is created in the same assembly.\n" + "If an axis or LCS is selected, the new fastener will be attached to it.\n" + "If an assembly is selected, the new fastener will be inside that assembly.

", + ) # Threaded Rod (makes errors) - elif self.FSclass == 'ThreadedRod': - self.menutext = translate("Fasteners", "Insert threaded rod") - self.tooltip = "Insert threaded rod" - self.icon = os.path.join( Asm4.iconPath , 'Asm4_Rod.svg') - - - def GetResources(self): - return {"MenuText": self.menutext, - "ToolTip" : self.tooltip, - "Pixmap" : self.icon } + elif self.FSclass == "ThreadedRod": + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_Rod.svg") + self.menutext = translate("Fasteners", "Insert threaded rod") + self.tooltip = translate("Fasteners", "Insert threaded rod") def IsActive(self): # if Asm4.getAssembly(): @@ -215,16 +219,13 @@ def Activated(self): | wrapper for FSChangeParams | +-----------------------------------------------+ """ -class changeFSparametersCmd(): +class changeFSparametersCmd(BaseCommand): def __init__(self): super(changeFSparametersCmd,self).__init__() - - def GetResources(self): - return {"MenuText": "Change Fastener parameters", - "ToolTip": "Change Fastener parameters", - "Pixmap" : os.path.join( Asm4.iconPath , 'Asm4_FSparams.svg') - } + self.pixmap = os.path.join( Asm4.iconPath , 'Asm4_FSparams.svg') + self.menutext = translate("Fasteners", "Change Fastener parameters") + self.tooltip = translate("Fasteners", "Change Fastener parameters") def IsActive(self): if App.ActiveDocument and getSelectionFS(): @@ -277,21 +278,18 @@ def isFastener(obj): +-----------------------------------------------+ | clone per App::Link fasteners | +-----------------------------------------------+ - + Select a fastener and several datum axes and the fastener will be cloned (as App::Link) and attached to those axes """ -class cloneFastenersToAxesCmd(): - +class cloneFastenersToAxesCmd(BaseCommand): + def __init__(self): super(cloneFastenersToAxesCmd,self).__init__() - - def GetResources(self): - return {"MenuText": "Clone Fastener to Axes", - "ToolTip": "Clone Fastener to Axes", - "Pixmap" : os.path.join( Asm4.iconPath , 'Asm4_cloneFasteners.svg') - } - + self.pixmap = os.path.join( Asm4.iconPath , 'Asm4_cloneFasteners.svg') + self.menutext = translate("Fasteners", "Clone Fastener to Axes") + self.tooltip = translate("Fasteners", "Clone Fastener to Axes") + def IsActive(self): self.selection = self.getSelectedAxes() if Asm4.getAssembly() and self.selection: @@ -315,7 +313,7 @@ def Activated(self): if axis and axis.Document: newFstnr = Asm4.cloneObject(fstnr) Asm4.placeObjectToLCS(newFstnr, axisData[2], axis.Document.Name, axisData[3]) - + Gui.Selection.clearSelection() self.rootAssembly = Asm4.getAssembly() if self.rootAssembly: @@ -326,7 +324,7 @@ def getSelectedAxes(self): holeAxes = [] fstnr = None selection = Gui.Selection.getSelectionEx('', 0) - + if selection: for s in selection: for seNames in s.SubElementNames: diff --git a/infoPartCmd.py b/infoPartCmd.py index e9aa05d1..e28c5e40 100644 --- a/infoPartCmd.py +++ b/infoPartCmd.py @@ -16,6 +16,9 @@ import Asm4_libs as Asm4 import infoKeys +from BaseCommand import BaseCommand +from Asm4_Translate import translate + #This is partcoded part information. partInfo = [ 'BomKey', @@ -231,16 +234,14 @@ def AssignValuesForAutofile(part, doc, singleBodyOfPart): | Info Part Command | +-----------------------------------------------+ """ -class infoPartCmd(): +class infoPartCmd(BaseCommand): def __init__(self): super(infoPartCmd, self).__init__() - - def GetResources(self): - tooltip = "

Edit Part information

" - tooltip += "

User-supplied information can be added to a part

" - iconFile = os.path.join(Asm4.iconPath, 'Asm4_PartInfo.svg') - return {"MenuText": "Edit Part Information", "ToolTip": tooltip, "Pixmap": iconFile} + self.pixmap = os.path.join(Asm4.iconPath, 'Asm4_PartInfo.svg') + self.menutext = "Edit Part Information" + self.tooltip = translate("Commands", + "User-supplied information can be added to a part") def IsActive(self): if App.ActiveDocument and Asm4.getSelectedContainer(): diff --git a/insertLinkCmd.py b/insertLinkCmd.py index d7cb0d86..e667a942 100644 --- a/insertLinkCmd.py +++ b/insertLinkCmd.py @@ -17,6 +17,8 @@ import Asm4_libs as Asm4 +from BaseCommand import BaseCommand +from Asm4_Translate import translate """ @@ -24,7 +26,7 @@ | main class | +-----------------------------------------------+ """ -class insertLink(): +class insertLink(BaseCommand): "My tool object" def __init__(self): @@ -32,22 +34,16 @@ def __init__(self): # the GUI objects are defined later down # self.UI = QtGui.QDialog() # self.drawUI() - - - def GetResources(self): - tooltip = "

Insert a Part into the assembly. " - tooltip += "This will create a dynamic link to the part, " - tooltip += "which can be in this document or in another document " - tooltip += "that is open in the current session

" - tooltip += "

Usage: the part must be open in the current session

" - tooltip += "

This command also enables to repair broken/missing links. " - tooltip += "Select the broken link, launch this command, and select a new target part in the list

" - iconFile = 'Link_Part.svg' - return {"MenuText" : "Insert Part", - "ToolTip" : tooltip, - "Pixmap" : os.path.join( Asm4.iconPath , iconFile ) - } - + self.pixmap = os.path.join(Asm4.iconPath, 'Link_Part.svg') + self.menutext = "Insert Part" + self.tooltip = translate("Commands", + "

Insert a Part into the assembly.\n" + "This will create a dynamic link to the part,\n" + "which can be in this document or in another document\n" + "that is open in the current session

\n" + "

Usage: the part must be open in the current session

\n" + "

This command also enables to repair broken/missing links.\n" + "Select the broken link, launch this command, and select a new target part in the list

") def IsActive(self): # if an App::Link is selected, even a broken one diff --git a/variantLinkCmd.py b/variantLinkCmd.py index c153ea73..96b75d05 100755 --- a/variantLinkCmd.py +++ b/variantLinkCmd.py @@ -18,6 +18,9 @@ from Asm4_objects import VariantLink, ViewProviderVariant +from BaseCommand import BaseCommand +from Asm4_Translate import translate + """ @@ -28,20 +31,15 @@ var = App.ActiveDocument.addObject("Part::FeaturePython", 'varLink', VariantLink(),None,True) """ -class makeVariantLink(): +class makeVariantLink(BaseCommand): def __init__(self): super(makeVariantLink,self).__init__() - #pass - - def GetResources(self): - tooltip = "EXPERIMENTAL !!!\n" - tooltip += "Create a variant link to a part\n" - tooltip += "Select a part containing a \"Variables\" property container" - iconFile = 'Variant_Link.svg' - return {"MenuText" : "Create a variant Part", - "ToolTip" : tooltip, - "Pixmap" : os.path.join( Asm4.iconPath, iconFile ) - } + self.pixmap = os.path.join(Asm4.iconPath, 'Variant_Link.svg') + self.menutext = "Create a variant Part" + self.tooltip = translate("Commands", + "EXPERIMENTAL !!!\n" + "Create a variant link to a part\n" + "Select a part containing a \"Variables\" property container") def IsActive(self): # we only insert variant links into assemblies and root parts From 54b7be67cb11b304b9d81f37eb0ac1cb51ff4d1d Mon Sep 17 00:00:00 2001 From: hasecilu Date: Fri, 23 Feb 2024 23:27:15 -0600 Subject: [PATCH 04/10] Mark 8 more tooltips for translation Commands from the 2nd group. --- FastenersLib.py | 13 ++++--- importDatumCmd.py | 28 ++++++++------- makeBinderCmd.py | 25 +++++++------ newDatumCmd.py | 90 +++++++++++++++++++++++------------------------ newPartCmd.py | 6 ++-- 5 files changed, 82 insertions(+), 80 deletions(-) diff --git a/FastenersLib.py b/FastenersLib.py index 8d33b525..97cb9220 100644 --- a/FastenersLib.py +++ b/FastenersLib.py @@ -20,11 +20,8 @@ from Asm4_Translate import translate - # icon to show in the Menu, toolbar and widget window -iconFile = os.path.join( Asm4.iconPath , 'Asm4_mvFastener.svg') - - +iconFile = os.path.join(Asm4.iconPath, "Asm4_mvFastener.svg") """ @@ -49,6 +46,7 @@ """ + class insertFastener(BaseCommand): "My tool object" def __init__(self, fastenerType): @@ -219,11 +217,12 @@ def Activated(self): | wrapper for FSChangeParams | +-----------------------------------------------+ """ -class changeFSparametersCmd(BaseCommand): + +class changeFSparametersCmd(BaseCommand): def __init__(self): - super(changeFSparametersCmd,self).__init__() - self.pixmap = os.path.join( Asm4.iconPath , 'Asm4_FSparams.svg') + super(changeFSparametersCmd, self).__init__() + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_FSparams.svg") self.menutext = translate("Fasteners", "Change Fastener parameters") self.tooltip = translate("Fasteners", "Change Fastener parameters") diff --git a/importDatumCmd.py b/importDatumCmd.py index 22e54bc6..cba3a7ba 100644 --- a/importDatumCmd.py +++ b/importDatumCmd.py @@ -16,7 +16,8 @@ import Asm4_libs as Asm4 - +from BaseCommand import BaseCommand +from Asm4_Translate import translate """ @@ -24,19 +25,20 @@ | The command | +-----------------------------------------------+ """ -class importDatumCmd(): + + +class importDatumCmd(BaseCommand): def __init__(self): - super(importDatumCmd,self).__init__() - - def GetResources(self): - tooltip = "Imports the selected Datum object(s) from a sub-part into the root assembly.\n" - tooltip += "This creates a new datum of the same type, and with the same global placement\n\n" - tooltip += "This command can also be used to override the placement of an existing datum :\n" - tooltip += "select a second datum in the same root container as the first selected datum" - iconFile = os.path.join( Asm4.iconPath , 'Import_Datum.svg') - return {"MenuText": "Import Datum object", - "ToolTip" : tooltip, - "Pixmap" : iconFile } + super(importDatumCmd, self).__init__() + self.pixmap = os.path.join(Asm4.iconPath, "Import_Datum.svg") + self.menutext = "Import Datum object" + self.tooltip = translate( + "Commands2", + "Imports the selected Datum object(s) from a sub-part into the root assembly.\n" + "This creates a new datum of the same type, and with the same global placement\n\n" + "This command can also be used to override the placement of an existing datum :\n" + "select a second datum in the same root container as the first selected datum", + ) def IsActive(self): if App.ActiveDocument and self.getSelectedDatums(): diff --git a/makeBinderCmd.py b/makeBinderCmd.py index b320ebb7..3527e8a1 100755 --- a/makeBinderCmd.py +++ b/makeBinderCmd.py @@ -17,7 +17,8 @@ import Asm4_libs as Asm4 - +from BaseCommand import BaseCommand +from Asm4_Translate import translate """ @@ -25,17 +26,19 @@ | a circular link array class and command | +-----------------------------------------------+ """ -class makeShapeBinder(): + + +class makeShapeBinder(BaseCommand): def __init__(self): - pass - - def GetResources(self): - tooltip = "Create a reference to an external shape\n" - tooltip += "This creates a SubShapeBinder of the selected shapes\n" - tooltip += "(face, edge, point) in the root assembly\n" - tooltip += "Only shapes belonging to the same part can be imported in a single step" - iconFile = os.path.join( Asm4.iconPath, 'Asm4_shapeBinder.svg' ) - return {"MenuText": "Create a shape binder", "ToolTip": tooltip, "Pixmap": iconFile} + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_shapeBinder.svg") + self.menutext = "Create a shape binder" + self.tooltip = translate( + "Commands2", + "Create a reference to an external shape\n" + "This creates a SubShapeBinder of the selected shapes\n" + "(face, edge, point) in the root assembly\n" + "Only shapes belonging to the same part can be imported in a single step", + ) def IsActive(self): # only do this for assembly objects and all selected shapes must be in the same part diff --git a/newDatumCmd.py b/newDatumCmd.py index d1f29302..cdc4e68c 100644 --- a/newDatumCmd.py +++ b/newDatumCmd.py @@ -15,8 +15,8 @@ from FreeCAD import Console as FCC import Asm4_libs as Asm4 - - +from BaseCommand import BaseCommand +from Asm4_Translate import translate """ @@ -24,54 +24,52 @@ | a class to create all Datum objects | +-----------------------------------------------+ """ -class newDatum: + + +class newDatum(BaseCommand): "My tool object" + def __init__(self, datumName): self.datumName = datumName # recognised containers (not the same as Asm4.containerTypes !) - self.containers = [ 'App::Part', 'PartDesign::Body', 'App::DocumentObjectGroup'] - if self.datumName == 'Point': - self.datumType = 'PartDesign::Point' - self.menutext = "New Point" - self.tooltip = "Create a new Datum Point in a Part" - self.icon = os.path.join( Asm4.iconPath , 'Asm4_Point.svg') - self.datumColor = (0.00,0.00,0.00) - self.datumAlpha = [] - elif self.datumName == 'Axis': - self.datumType = 'PartDesign::Line' - self.menutext = "New Axis" - self.tooltip = "Create a new Datum Axis in a Part" - self.icon = os.path.join( Asm4.iconPath , 'Asm4_Axis.svg') - self.datumColor = (0.00,0.00,0.50) - self.datumAlpha = [] - elif self.datumName == 'Plane': - self.datumType = 'PartDesign::Plane' - self.menutext = "New Plane" - self.tooltip = "Create a new Datum Plane in a Part" - self.icon = os.path.join( Asm4.iconPath , 'Asm4_Plane.svg') - self.datumColor = (0.50,0.50,0.50) - self.datumAlpha = 80 - elif self.datumName == 'LCS': - self.datumType = 'PartDesign::CoordinateSystem' - self.menutext = "New Coordinate System" - self.tooltip = "Create a new Coordinate System in a Part" - self.icon = os.path.join( Asm4.iconPath , 'Asm4_CoordinateSystem.svg') - self.datumColor = [] - self.datumAlpha = [] - elif self.datumName == 'Sketch': - self.datumType = 'Sketcher::SketchObject' - self.menutext = "New Sketch" - self.tooltip = "Create a new Sketch in a Part" - self.icon = os.path.join( Asm4.iconPath , 'Asm4_Sketch.svg') - self.datumColor = [] - self.datumAlpha = [] - - - def GetResources(self): - return {"MenuText": self.menutext, - "ToolTip": self.tooltip, - "Pixmap" : self.icon } - + self.containers = ["App::Part", "PartDesign::Body", "App::DocumentObjectGroup"] + if self.datumName == "Point": + self.datumType = "PartDesign::Point" + self.menutext = "New Point" + self.tooltip = translate("Commands2", "Create a new Datum Point in a Part") + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_Point.svg") + self.datumColor = (0.00, 0.00, 0.00) + self.datumAlpha = [] + elif self.datumName == "Axis": + self.datumType = "PartDesign::Line" + self.menutext = "New Axis" + self.tooltip = translate("Commands2", "Create a new Datum Axis in a Part") + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_Axis.svg") + self.datumColor = (0.00, 0.00, 0.50) + self.datumAlpha = [] + elif self.datumName == "Plane": + self.datumType = "PartDesign::Plane" + self.menutext = "New Plane" + self.tooltip = translate("Commands2", "Create a new Datum Plane in a Part") + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_Plane.svg") + self.datumColor = (0.50, 0.50, 0.50) + self.datumAlpha = 80 + elif self.datumName == "LCS": + self.datumType = "PartDesign::CoordinateSystem" + self.menutext = "New Coordinate System" + self.tooltip = translate( + "Commands2", "Create a new Coordinate System in a Part" + ) + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_CoordinateSystem.svg") + self.datumColor = [] + self.datumAlpha = [] + elif self.datumName == "Sketch": + self.datumType = "Sketcher::SketchObject" + self.menutext = "New Sketch" + self.tooltip = translate("Commands2", "Create a new Sketch in a Part") + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_Sketch.svg") + self.datumColor = [] + self.datumAlpha = [] def IsActive(self): if App.ActiveDocument: diff --git a/newPartCmd.py b/newPartCmd.py index e384c9d2..5726eeb4 100644 --- a/newPartCmd.py +++ b/newPartCmd.py @@ -32,17 +32,17 @@ def __init__(self, partName): self.partName = partName if self.partName == "Part": self.partType = "App::Part" - self.menutext = "New Part" + self.menutext = translate("Commands1", "New Part") self.tooltip = translate("Commands1", "Create a new Part") self.icon = os.path.join(Asm4.iconPath, "Asm4_Part.svg") elif self.partName == "Body": self.partType = "PartDesign::Body" - self.menutext = "New Body" + self.menutext = translate("Commands1", "New Body") self.tooltip = translate("Commands1", "Create a new Body") self.icon = os.path.join(Asm4.iconPath, "Asm4_Body.svg") elif self.partName == "Group": self.partType = "App::DocumentObjectGroup" - self.menutext = "New Group" + self.menutext = translate("Commands1", "New Group") self.tooltip = translate("Commands1", "Create a new Group") self.icon = os.path.join(Asm4.iconPath, "Asm4_Group.svg") From 424dcfcd803be0505bad35a052e6eaf7dbf67761 Mon Sep 17 00:00:00 2001 From: hasecilu Date: Sun, 25 Feb 2024 07:54:04 -0600 Subject: [PATCH 05/10] Mark 3 more tooltips for translation Commands from the 3rd group. --- placeLinkCmd.py | 20 +++++++++----------- releaseAttachmentCmd.py | 21 ++++++++++----------- updateAssemblyCmd.py | 20 +++++++++----------- 3 files changed, 28 insertions(+), 33 deletions(-) diff --git a/placeLinkCmd.py b/placeLinkCmd.py index 99b734f7..e80639a7 100644 --- a/placeLinkCmd.py +++ b/placeLinkCmd.py @@ -18,9 +18,8 @@ from placeLinkUI import placeLinkUI from placePartUI import placePartUI import selectionFilter - - - +from BaseCommand import BaseCommand +from Asm4_Translate import translate """ @@ -28,15 +27,14 @@ | The command | +-----------------------------------------------+ """ -class placeLinkCmd(): - def __init__(self): - super(placeLinkCmd,self).__init__() - def GetResources(self): - return {"MenuText": "Edit Placement of a Part", - "ToolTip": "Move/Attach a Part in the assembly", - "Pixmap" : os.path.join( Asm4.iconPath , 'Place_Link.svg') - } + +class placeLinkCmd(BaseCommand): + def __init__(self): + super(placeLinkCmd, self).__init__() + self.menutext = "Edit Placement of a Part" + self.tooltip = translate("Commands3", "Move/Attach a Part in the assembly") + self.pixmap = os.path.join(Asm4.iconPath, "Place_Link.svg") def IsActive(self): # We only insert a link into an Asm4 Model diff --git a/releaseAttachmentCmd.py b/releaseAttachmentCmd.py index 44190d11..f337e714 100644 --- a/releaseAttachmentCmd.py +++ b/releaseAttachmentCmd.py @@ -15,7 +15,8 @@ import Part import Asm4_libs as Asm4 - +from BaseCommand import BaseCommand +from Asm4_Translate import translate """ @@ -23,19 +24,17 @@ | main class | +-----------------------------------------------+ """ -class releaseAttachment: + +class releaseAttachment(BaseCommand): def __init__(self): - super(releaseAttachment,self).__init__() + super(releaseAttachment, self).__init__() self.selectedObj = [] - - - def GetResources(self): - return {"MenuText": "Release from Attachment", - "ToolTip": "Release an object from all attachments to any geometry", - "Pixmap" : os.path.join( Asm4.iconPath , 'Asm4_releaseAttachment.svg') - } - + self.menutext = "Release from Attachment" + self.tooltip = translate( + "Commands3", "Release an object from all attachments to any geometry" + ) + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_releaseAttachment.svg") def IsActive(self): # is there an active document ? diff --git a/updateAssemblyCmd.py b/updateAssemblyCmd.py index 8de38b4a..342ebee4 100644 --- a/updateAssemblyCmd.py +++ b/updateAssemblyCmd.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # coding: utf-8 -# -# updateAssembly.py +# +# updateAssembly.py import math, re, os @@ -12,17 +12,15 @@ import Part import Asm4_libs as Asm4 +from BaseCommand import BaseCommand +from Asm4_Translate import translate - -class updateAssembly: - - def GetResources(self): - return {"MenuText": "Solve and Update Assembly", - "ToolTip": "Update Assembly", - "Pixmap" : os.path.join( Asm4.iconPath , 'Asm4_Solver.svg') - } - +class updateAssembly(BaseCommand): + def __init__(self): + self.menutext = "Solve and Update Assembly" + self.tooltip = translate("Commands3", "Update Assembly") + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_Solver.svg") def IsActive(self): if App.ActiveDocument: From f4a71ef8aa1acc551aa5a633166fa42b7ddf674c Mon Sep 17 00:00:00 2001 From: hasecilu Date: Sun, 25 Feb 2024 10:24:28 -0600 Subject: [PATCH 06/10] Mark 6 more tooltips for translation Commands from the 4th group. --- Resources/translations/asm4_es-ES.qm | Bin 2776 -> 18970 bytes VariablesLib.py | 62 +++++++-------- makeArrayCmd.py | 110 +++++++++++++++------------ 3 files changed, 92 insertions(+), 80 deletions(-) diff --git a/Resources/translations/asm4_es-ES.qm b/Resources/translations/asm4_es-ES.qm index a57d898a77cc503091187b79364ffb29520f5a53..dd6cf0c2992c960aafa45f119431e8d592f1a766 100644 GIT binary patch literal 18970 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 S^DoNuJ^piew{m!B=zjn>)W)#@ delta 247 zcmbO=h4F^y1X&}78w_mQTp1V`9T>FU7%(t!E@SZFWC8Ni849EA7#LV5FvpmLGca&e zGM}&yVPIf3oY*f}-x&T0D72rg@XZef28KAc72cH$3~WVgE3W~Suq$)=Jpu}|@8W8$ zS^yM3%{6`X7od^*x#kG(1X_{FHOCf6GcfQ>4gjj>Fy@&u;U`di4bPPGTNoIa@_DA_ zUIFsI^Ez0I0M+yGCpv%({K%gfD$KyZ(mDA&Bd6evwLml2G&6w;t}+8*OhXUXyq8M^4Tc+Bn%+YWwC=kEM(N^Atmb diff --git a/VariablesLib.py b/VariablesLib.py index c6ad21bb..06bab404 100644 --- a/VariablesLib.py +++ b/VariablesLib.py @@ -14,7 +14,8 @@ import FreeCAD as App import Asm4_libs as Asm4 - +from BaseCommand import BaseCommand +from Asm4_Translate import translate # get the Variables feature @@ -45,10 +46,11 @@ def checkPart(): | add a new Variable | +-----------------------------------------------+ """ -class addVariable(): + +class addVariable(BaseCommand): def __init__(self): - super(addVariable,self).__init__() + super(addVariable, self).__init__() self.UI = QtGui.QDialog() self.drawUI() self.allowedProperties = [ 'App::PropertyBool', @@ -67,23 +69,20 @@ def __init__(self): 'App::PropertyColor', 'App::PropertyFile'] - - def GetResources(self): - tooltip = "

Adds a variable into the Variables placeholder in the document. " - tooltip += "This variable can then be used in any formula using the ExpressionEngine " - tooltip += "of any compatible input field. These are marked with a \"f(x)\" symbol

" - iconFile = os.path.join( Asm4.iconPath , 'Asm4_addVariable.svg') - return {"MenuText": "Add Variable", - "ToolTip": tooltip, - "Pixmap" : iconFile } - + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_addVariable.svg") + self.menutext = "Add Variable" + self.tooltip = translate( + "Commands4", + "

Adds a variable into the Variables placeholder in the document.\n" + "This variable can then be used in any formula using the ExpressionEngine\n" + 'of any compatible input field. These are marked with the "f(x)" symbol

', + ) def IsActive(self): # if there is an Asm4 Model in the ActiveDocument, or if an App::Part is selected if App.ActiveDocument: return True return False - def Activated(self): # retrieve the Variables object @@ -229,18 +228,16 @@ def drawUI(self): | delete an existing Variable | +-----------------------------------------------+ """ -class delVariable(): + +class delVariable(BaseCommand): def __init__(self): - super(delVariable,self).__init__() + super(delVariable, self).__init__() self.UI = QtGui.QDialog() self.drawUI() - - def GetResources(self): - return {"MenuText": "Delete Variable", - "ToolTip": "Delete a Variable", - "Pixmap" : os.path.join( Asm4.iconPath , 'Asm4_delVariable.svg') - } + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_delVariable.svg") + self.menutext = "Delete Variable" + self.tooltip = translate("Commands4", "Delete a Variable") def IsActive(self): # if there is an Asm4 Model in the ActiveDocument @@ -359,11 +356,16 @@ def drawUI(self): | add the command to the workbench | +-----------------------------------------------+ """ -Gui.addCommand( 'Asm4_addVariable', addVariable() ) -Gui.addCommand( 'Asm4_delVariable', delVariable() ) - -variablesCmdList = [ 'Asm4_addVariable', 'Asm4_delVariable' ] -tooltip = "Adds a variable into the \"Variables\" placeholder in the document.\n" -tooltip += "This variable can then be used in any formula using the ExpressionEngine\n" -tooltip += "of any compatible input field. These are marked with a \"f(x)\" symbol." -Gui.addCommand( 'Asm4_variablesCmd', Asm4.dropDownCmd( variablesCmdList, 'Variables', tooltip )) +Gui.addCommand("Asm4_addVariable", addVariable()) +Gui.addCommand("Asm4_delVariable", delVariable()) + +variablesCmdList = ["Asm4_addVariable", "Asm4_delVariable"] +tooltip = translate( + "Commands4", + "

Adds a variable into the Variables placeholder in the document.\n" + "This variable can then be used in any formula using the ExpressionEngine\n" + 'of any compatible input field. These are marked with the "f(x)" symbol

', +) +Gui.addCommand( + "Asm4_variablesCmd", Asm4.dropDownCmd(variablesCmdList, "Variables", tooltip) +) diff --git a/makeArrayCmd.py b/makeArrayCmd.py index 1595137f..7fab44c6 100755 --- a/makeArrayCmd.py +++ b/makeArrayCmd.py @@ -17,6 +17,8 @@ ExpressionArray, findAxisPlacement, ) +from BaseCommand import BaseCommand +from Asm4_Translate import translate """ @@ -26,30 +28,24 @@ """ -class makeExpressionArray: - - iconFileName = 'Asm4_ExpressionArray.svg' - menuText = 'Create an expression driven Array' - arrayType = 'Expression Array' - namePrefix = 'XArray_' - tooltip = """Create an array of the selected object where the placement of each element is calculated using expressions and an Index property.
- Select a source object to array and optionally an Axis that transformation will be related to.
- Without axis the transformations relates to the source object internal Z axis.
-
- Count : The amount of elements in the array.
- Index : Hidden but Placer use it in expressions to calculating the Placements. Increments for each element starting with 0.
- Placer : Set an expression for the entire placement or its sub-properties.
- By opening Placer property in Tasks panel it is possible to set expressions for euler angles too.
- Also see tooltips in Property view - """ - - def GetResources(self): - iconFile = os.path.join(Asm4.iconPath, self.iconFileName) - return { - 'MenuText': self.menuText, - 'ToolTip': self.tooltip, - 'Pixmap': iconFile, - } +class makeExpressionArray(BaseCommand): + def __init__(self): + self.arrayType = "Expression Array" + self.namePrefix = "XArray_" + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_ExpressionArray.svg") + self.menutext = "Create an expression driven Array" + self.tooltip = translate( + "Commands4", + "Create an array of the selected object where the placement of each element is calculated using expressions and an Index property.
\n" + "Select a source object to array and optionally an Axis that transformation will be related to.
\n" + "Without axis the transformations relates to the source object internal Z axis.
\n" + "
\n" + "Count : The amount of elements in the array.
\n" + "Index : Hidden but Placer use it in expressions to calculating the Placements. Increments for each element starting with 0.
\n" + "Placer : Set an expression for the entire placement or its sub-properties.
\n" + " By opening Placer property in Tasks panel it is possible to set expressions for euler angles too.
\n" + "Also see tooltips in Property view", + ) def _cacheSelectionInfo(self): """Check axis and caches useful data for selected items. @@ -124,16 +120,20 @@ def Activated(self): +-----------------------------------------------+ """ -class makeCircularArray(makeExpressionArray): - iconFileName = 'Asm4_PolarArray.svg' - menuText = 'Create a circular array' - arrayType = 'Circular Array' - namePrefix = 'Circular_' - tooltip = """

Create a circular (polar) array around an axis. - Supported axis objects are axis or plane from an origin, datum line, LCS axes, straight line segments, arcs and circles

-

Usage: Select an object and the axis (hold CTRL key to select second object)

""" - +class makeCircularArray(BaseCommand): + def __init__(self): + self.arrayType = "Circular Array" + self.namePrefix = "Circular_" + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_PolarArray.svg") + self.menutext = "Create a circular array" + self.tooltip = translate( + "Commands4", + "

Create a circular (polar) array around an axis.\n" + "Supported axis objects are axis or plane from an origin, datum line, LCS axes, straight line segments, arcs and circles

\n" + "

Usage: Select an object and an axis (hold CTRL key to select second object)

", + ) + def IsActive(self): self._cacheSelectionInfo() return self._selectionInfo[2] is not None @@ -156,15 +156,19 @@ def _setupProperties(self, obj): +-----------------------------------------------+ """ -class makeLinearArray(makeExpressionArray): - iconFileName = 'Asm4_LinearArray.svg' - menuText = 'Create a linear array' - arrayType = 'Linear Array' - namePrefix = 'Linear_' - tooltip = """

Create a linear array along an axis. - Supported axis objects are axis or plane from an origin, datum line, LCS axes, straight line segments, arcs and circles

-

Usage: Select an object and an axis for the direction (hold CTRL key to select second object)

""" +class makeLinearArray(BaseCommand): + def __init__(self): + self.arrayType = "Linear Array" + self.namePrefix = "Linear_" + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_LinearArray.svg") + self.menutext = "Create a linear array" + self.tooltip = translate( + "Commands4", + "

Create a linear array along an axis.\n" + "Supported axis objects are axis or plane from an origin, datum line, LCS axes, straight line segments, arcs and circles

\n" + "

Usage: Select an object and an axis for the direction (hold CTRL key to select second object)

", + ) def IsActive(self): self._cacheSelectionInfo() @@ -187,15 +191,21 @@ def _setupProperties(self, obj): | a mirror link array class and command | +-----------------------------------------------+ """ -class makeMirrorArray(makeExpressionArray): - - iconFileName = 'Asm4_Mirror.svg' - menuText = 'Create mirror' - arrayType = 'Mirror Array' - namePrefix = 'Mirror_' - tooltip = """

Create a mirror of a part. - Supported axis objects are axis or plane from an origin, datum line, LCS axes, straight line segments, arcs and circles

-

Usage: Select a source object and a mirror plane or a normal to a plane (hold CTRL key to select second object)

""" + + +class makeMirrorArray(BaseCommand): + def __init__(self) -> None: + super().__init__() + self.arrayType = "Mirror Array" + self.namePrefix = "Mirror_" + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_Mirror.svg") + self.menutext = "Create mirror" + self.tooltip = translate( + "Commands4", + "

Create a mirror of a part.\n" + "Supported axis objects are axis or plane from an origin, datum line, LCS axes, straight line segments, arcs and circles

\n" + "

Usage: Select a source object and a mirror plane or a normal to a plane (hold CTRL key to select second object)

", + ) def IsActive(self): self._cacheSelectionInfo() From 9ee61b0d9534dd20678e26a7b1d8679acc2fcc1e Mon Sep 17 00:00:00 2001 From: hasecilu Date: Sun, 25 Feb 2024 11:32:44 -0600 Subject: [PATCH 07/10] Mark 10 more tooltips for translation Commands from the 5th group. --- AnimationLib.py | 11 ++-- Asm4_Measure.py | 19 +++--- checkInterference.py | 21 +++--- configurationEngine.py | 58 ++++++++-------- exportFiles.py | 146 ++++++++++++++++++++--------------------- makeBomCmd.py | 44 ++++++------- showHideLcsCmd.py | 34 +++++----- 7 files changed, 168 insertions(+), 165 deletions(-) diff --git a/AnimationLib.py b/AnimationLib.py index bb5bf565..346d6807 100644 --- a/AnimationLib.py +++ b/AnimationLib.py @@ -16,6 +16,7 @@ import FreeCAD as App import Asm4_libs as Asm4 +from Asm4_Translate import translate # from AnimationProvider import animationProvider @@ -121,11 +122,11 @@ def __init__(self): def GetResources(self): - return {"MenuText": "Animate Assembly", - "ToolTip": "Animate Assembly", - "Pixmap" : os.path.join( Asm4.iconPath , 'Asm4_GearsAnimate.svg') - } - + return { + "MenuText": "Animate Assembly", + "ToolTip": translate("Commands5", "Animate Assembly"), + "Pixmap": os.path.join(Asm4.iconPath, "Asm4_GearsAnimate.svg"), + } def IsActive(self): # is there an active document ? diff --git a/Asm4_Measure.py b/Asm4_Measure.py index e3039abd..23c305bc 100644 --- a/Asm4_Measure.py +++ b/Asm4_Measure.py @@ -42,8 +42,8 @@ # only needed for icons import Asm4_libs as Asm4 import selectionFilter - - +from BaseCommand import BaseCommand +from Asm4_Translate import translate """ @@ -88,15 +88,14 @@ def getIcon(self): | The menu and toolbar command | +-----------------------------------------------+ """ -class MeasureCmd(): - def __init__(self): - super(MeasureCmd,self).__init__() - def GetResources(self): - return {"MenuText": "Measure", - "ToolTip": "Measure Tool", - "Pixmap" : os.path.join( iconDir , 'Part_Measure.svg') - } + +class MeasureCmd(BaseCommand): + def __init__(self): + super(MeasureCmd, self).__init__() + self.pixmap = os.path.join(iconDir, "Part_Measure.svg") + self.menutext = "Measure" + self.tooltip = translate("Commands5", "Measure Tool") def IsActive(self): if App.ActiveDocument: diff --git a/checkInterference.py b/checkInterference.py index 739e932c..71898bb6 100644 --- a/checkInterference.py +++ b/checkInterference.py @@ -22,23 +22,18 @@ import Asm4_libs as Asm4 import showHideLcsCmd as lcs import Part +from BaseCommand import BaseCommand +from Asm4_Translate import translate -class checkInterference: +class checkInterference(BaseCommand): def __init__(self): super(checkInterference, self).__init__() - - - def GetResources(self): - menutext = "Check Intereferences" - tooltip = "Check interferences among assembled objects (may take time)" - iconFile = os.path.join(Asm4.iconPath, 'Asm4_Interference_Check.svg') - return { - "MenuText": menutext, - "ToolTip": tooltip, - "Pixmap": iconFile - } - + self.menutext = "Check Interferences" + self.tooltip = translate( + "Commands5", "Check interferences among assembled objects (may take time)" + ) + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_Interference_Check.svg") def IsActive(self): if Asm4.getAssembly() is None: diff --git a/configurationEngine.py b/configurationEngine.py index 20251190..2024fb0b 100644 --- a/configurationEngine.py +++ b/configurationEngine.py @@ -14,6 +14,9 @@ from FreeCAD import Console as FCC import Asm4_libs as Asm4 +from BaseCommand import BaseCommand +from Asm4_Translate import translate + ASM4_CONFIG_TYPE = 'Asm4::ConfigurationTable' HEADER_CELL = 'A1' @@ -31,7 +34,6 @@ NAME_COL_WIDTH = 250 - """ +-----------------------------------------------+ | create a new empty configuration table | @@ -72,15 +74,18 @@ def createConfig(name, description): | Apply configuration command | +-----------------------------------------------+ """ -class applyConfigurationCmd: - def __init__(self): - super(applyConfigurationCmd,self).__init__() - def GetResources(self): - return {"MenuText": "Apply configuration", - "ToolTip": "Applies selected configuration\nConfigurations allow to set visibilities and offsets of parts", - "Pixmap" : os.path.join( Asm4.iconPath , 'Asm4_applyConfig.svg') - } + +class applyConfigurationCmd(BaseCommand): + def __init__(self): + super(applyConfigurationCmd, self).__init__() + self.menutext = "Apply configuration" + self.tooltip = translate( + "Commands5", + "Applies selected configuration\n" + "Configurations allow to set visibilities and offsets of parts", + ) + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_applyConfig.svg") def IsActive(self): # if a spreadsheet in a Group called "Configuration" is selected @@ -103,15 +108,16 @@ def Activated(self): | General configuration Task UI | +-----------------------------------------------+ """ -class openConfigurationsCmd: - def __init__(self): - super(openConfigurationsCmd,self).__init__() - def GetResources(self): - return {"MenuText": "Open configurations panel", - "ToolTip": "Configurations allow to set visibilities and offsets of parts", - "Pixmap" : os.path.join( Asm4.iconPath , 'Asm4_Configurations.svg') - } + +class openConfigurationsCmd(BaseCommand): + def __init__(self): + super(openConfigurationsCmd, self).__init__() + self.menutext = "Open configurations panel" + self.tooltip = translate( + "Commands5", "Configurations allow to set visibilities and offsets of parts" + ) + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_Configurations.svg") def IsActive(self): # Will handle LCSs only for the Assembly4 model @@ -273,18 +279,18 @@ def drawUI(self): | Create new configuration Button | +-----------------------------------------------+ """ -class newConfigurationCmd: + + +class newConfigurationCmd(BaseCommand): def __init__(self): - super(newConfigurationCmd,self).__init__() + super(newConfigurationCmd, self).__init__() self.UI = QtGui.QDialog() self.drawUI() - - def GetResources(self): - return {"MenuText": "New configuration", - "ToolTip": "Create a new configuration of the assembly", - "Pixmap" : os.path.join( Asm4.iconPath , 'Asm4_applyConfig.svg') - } - + self.menutext = "New configuration" + self.tooltip = translate( + "Commands5", "Create a new configuration of the assembly" + ) + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_applyConfig.svg") def IsActive(self): # is there an active document ? diff --git a/exportFiles.py b/exportFiles.py index 5546b641..7b52bd88 100644 --- a/exportFiles.py +++ b/exportFiles.py @@ -29,71 +29,73 @@ from FreeCAD import Console as FCC import Asm4_libs as Asm4 +from BaseCommand import BaseCommand +from Asm4_Translate import translate -''' +""" has_anytree = False try: from anytree import Node, RenderTree has_anytree = True except ImportError: FCC.PrintMessage("\nINFO : Pylib anytree is missing, exportFiles is not available\n") -''' - -# lists the parts and linked parts of the selected container -class listLinkedFiles(): - - def GetResources(self): - menutext = "Structure tree of the assembly" - tooltip = "

Show the hierarchical tree structure of parts and sub-assemblies in the assembly. " - tooltip += "The tree is displayed with ASCII art

" - tooltip += "

Usage: select an entity and click the command

" - iconFile = os.path.join(Asm4.iconPath, 'Asm4_List_Liked_Files_Tree.svg') - return { - "MenuText": menutext, - "ToolTip" : tooltip, - "Pixmap" : iconFile - } - - - def IsActive(self): - if App.ActiveDocument and len(Gui.Selection.getSelection())==1: - return True - elif App.ActiveDocument and Asm4.getAssembly(): - return True - else: - return False +""" +# lists the parts and linked parts of the selected container +class listLinkedFiles(BaseCommand): def __init__(self): super(listLinkedFiles, self).__init__() # types of objects to be included in the listing # links and derivatives are also included - self.DEF_TYPES = ['App::Part', 'PartDesign::Body', 'Part::FeaturePython', 'App::DocumentObjectGroup'] + self.DEF_TYPES = [ + "App::Part", + "PartDesign::Body", + "Part::FeaturePython", + "App::DocumentObjectGroup", + ] # visual ASCII art - self.TAB = ' ' - self.BRANCH = ' │ ' - self.FORK = ' ├─ ' - self.LAST = ' └─ ' + self.TAB = " " + self.BRANCH = " │ " + self.FORK = " ├─ " + self.LAST = " └─ " # where we write stuff self.ascii_tree = "" - self.root_path = "" + self.root_path = "" # the UI self.UI = QtGui.QDialog() self.drawUI() + self.menutext = "Tree of Linked Files" + self.tooltip = translate( + "Commands5", + "

Show the hierarchical tree structure of parts in the selected container.\n" + "The tree is displayed with ASCII art

\n" + "

Usage: select an entity and click the command

", + ) + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_List_Liked_Files_Tree.svg") + def IsActive(self): + if App.ActiveDocument and len(Gui.Selection.getSelection()) == 1: + return True + elif App.ActiveDocument and Asm4.getAssembly(): + return True + else: + return False def Activated(self): # clear stuff self.ascii_tree = "" - self.root_path = "" + self.root_path = "" self.tree_view.clear() # - if len(Gui.Selection.getSelection())==1: + if len(Gui.Selection.getSelection()) == 1: objects = Gui.Selection.getSelection() elif Asm4.getAssembly(): - objects = [ Asm4.getAssembly() ] + objects = [Asm4.getAssembly()] else: - FCC.PrintWarning("Oups, you shouldn't see this message, something went wrong") + FCC.PrintWarning( + "Oups, you shouldn't see this message, something went wrong" + ) # get the directory path of the selected object filename = objects[0].Document.Name self.root_path = objects[0].Document.FileName.partition(filename)[0] @@ -103,14 +105,13 @@ def Activated(self): self.UI.show() self.tree_view.setPlainText(self.ascii_tree) - # this is where the magic happens. Copied from TreeToAscii macro # Build ASCII tree by recursive call - def printChildren(self, objs=None, level=0, baseline=''): - for cnt, obj in enumerate(objs,1): + def printChildren(self, objs=None, level=0, baseline=""): + for cnt, obj in enumerate(objs, 1): # find the filepath - filepath = '' - if obj.isDerivedFrom('App::Link'): + filepath = "" + if obj.isDerivedFrom("App::Link"): target = obj.LinkedObject else: target = obj @@ -118,84 +119,84 @@ def printChildren(self, objs=None, level=0, baseline=''): if self.root_path: filepath = target.Document.FileName.partition(self.root_path)[2] # ... else absolute - if filepath =='': + if filepath == "": filepath = target.Document.FileName # make the data data = { - "LBL" : obj.Label, - "NAME" : '('+obj.Name+')' if obj.Label!=obj.Name else '', - "DOC" : filepath, - "TARG" : obj.LinkedObject.Name if obj.isDerivedFrom('App::Link') else '' + "LBL": obj.Label, + "NAME": "(" + obj.Name + ")" if obj.Label != obj.Name else "", + "DOC": filepath, + "TARG": obj.LinkedObject.Name if obj.isDerivedFrom("App::Link") else "", } # print the line if cnt == len(objs): - if level>0: + if level > 0: self.ascii_tree += baseline + self.LAST else: self.ascii_tree += baseline + self.FORK # new data print - if obj.isDerivedFrom('App::Link'): - pattern = '{LBL} => {TARG} @ {DOC}' + if obj.isDerivedFrom("App::Link"): + pattern = "{LBL} => {TARG} @ {DOC}" else: - pattern = '{LBL} {NAME}' + pattern = "{LBL} {NAME}" self.ascii_tree += pattern.format(**data) # we add the filename for the first element - if level==0 and target.Document.FileName != '' : - self.ascii_tree += ' @ '+target.Document.FileName - self.ascii_tree += '\n' + if level == 0 and target.Document.FileName != "": + self.ascii_tree += " @ " + target.Document.FileName + self.ascii_tree += "\n" # for the next line if cnt == len(objs): - if level>0: + if level > 0: baselinenext = baseline + self.TAB else: - baselinenext = '' + baselinenext = "" else: baselinenext = baseline + self.BRANCH # table of children to be listed next children = [] for child in obj.ViewObject.claimChildren(): - if child.TypeId in self.DEF_TYPES or child.isDerivedFrom('App::Link'): + if child.TypeId in self.DEF_TYPES or child.isDerivedFrom("App::Link"): children.append(child) self.printChildren(children, level + 1, baselinenext) - def copyToClip(self): """Copies ASCII tree to clipboard""" self.tree_view.selectAll() self.tree_view.copy() self.tree_view.setPlainText("Copied to clipboard") - QtCore.QTimer.singleShot(3000, lambda:self.tree_view.setPlainText(self.ascii_tree)) - + QtCore.QTimer.singleShot( + 3000, lambda: self.tree_view.setPlainText(self.ascii_tree) + ) # defines the UI, only static elements def drawUI(self): # Our main window will be a QDialog # make this dialog stay above the others, always visible - self.UI.setWindowFlags( QtCore.Qt.WindowStaysOnTopHint ) - self.UI.setWindowTitle('Tree structure of the selected object') - self.UI.setWindowIcon( QtGui.QIcon( os.path.join( Asm4.iconPath , 'FreeCad.svg' ) ) ) + self.UI.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) + self.UI.setWindowTitle("Tree structure of the selected object") + self.UI.setWindowIcon(QtGui.QIcon(os.path.join(Asm4.iconPath, "FreeCad.svg"))) self.UI.setMinimumWidth(470) - self.UI.resize(470,300) + self.UI.resize(470, 300) self.UI.setModal(False) # the layout for the main window is vertical (top to down) mainLayout = QtGui.QVBoxLayout(self.UI) # from TreeToAscii macro self.tree_view = QtGui.QPlainTextEdit(self.ascii_tree) self.tree_view.setReadOnly(True) - self.tree_view.setMinimumWidth(Gui.getMainWindow().width()/2) - self.tree_view.setMinimumHeight(Gui.getMainWindow().height()/2) + self.tree_view.setMinimumWidth(Gui.getMainWindow().width() / 2) + self.tree_view.setMinimumHeight(Gui.getMainWindow().height() / 2) self.tree_view.setLineWrapMode(QtGui.QPlainTextEdit.NoWrap) - f = QtGui.QFont("unexistent"); - f.setStyleHint(QtGui.QFont.Monospace); - self.tree_view.setFont(f); + f = QtGui.QFont("unexistent") + f.setStyleHint(QtGui.QFont.Monospace) + self.tree_view.setFont(f) button_box = QtGui.QDialogButtonBox() copy_clip_but = QtGui.QPushButton("Copy to clipboard", button_box) button_box.addButton(copy_clip_but, QtGui.QDialogButtonBox.ActionRole) - #button_box.addStretch() + # button_box.addStretch() close_dlg_but = QtGui.QPushButton("Close", button_box) button_box.addButton(close_dlg_but, QtGui.QDialogButtonBox.RejectRole) - #button_box.addButton(QtGui.QDialogButtonBox.Close) - #button_box.button(QtGui.QDialogButtonBox.Close).setDefault(True) + # button_box.addButton(QtGui.QDialogButtonBox.Close) + # button_box.button(QtGui.QDialogButtonBox.Close).setDefault(True) mainLayout.addWidget(self.tree_view) mainLayout.addWidget(button_box) # actions @@ -311,5 +312,4 @@ def export_zip_package(self): ''' # Add the command in the workbench -Gui.addCommand('Asm4_listLinkedFiles', listLinkedFiles()) - +Gui.addCommand("Asm4_listLinkedFiles", listLinkedFiles()) diff --git a/makeBomCmd.py b/makeBomCmd.py index 95ba1306..d2ff1ebf 100644 --- a/makeBomCmd.py +++ b/makeBomCmd.py @@ -15,8 +15,10 @@ import Asm4_libs as Asm4 import infoPartCmd -#import infoKeys -#All infor from infoKeys is process by infoPartCmd shouldn't need to +from BaseCommand import BaseCommand +from Asm4_Translate import translate +# import infoKeys +# All infor from infoKeys is process by infoPartCmd shouldn't need to crea = infoPartCmd.infoPartUI.makePartInfo @@ -52,33 +54,31 @@ ''' -class makeBOM: +class makeBOM(BaseCommand): def __init__(self, follow_subassemblies=True): - #super().__init__() + # super().__init__() self.follow_subassemblies = follow_subassemblies - ''' + """ file = open(ConfUserFilejson, 'r') self.infoKeysUser = json.load(file).copy() file.close() - ''' - - def GetResources(self): - - if self.follow_subassemblies == True: - menutext = "Bill of Materials" - tooltip = "Create the Bill of Materials of the Assembly including sub-assemblies" - iconFile = os.path.join( Asm4.iconPath, 'Asm4_PartsList_Subassemblies.svg' ) + """ + if self.follow_subassemblies: + self.menutext = "Bill of Materials" + self.tooltip = translate( + "Commands5", + "Create the Bill of Materials of the Assembly including sub-assemblies", + ) + self.pixmap = os.path.join( + Asm4.iconPath, "Asm4_PartsList_Subassemblies.svg" + ) else: - menutext = "Local Bill of Materials" - tooltip = "Create the Bill of Materials of the Assembly" - iconFile = os.path.join( Asm4.iconPath, 'Asm4_PartsList.svg' ) - - return { - "MenuText": menutext, - "ToolTip": tooltip, - "Pixmap": iconFile - } + self.menutext = "Local Bill of Materials" + self.tooltip = translate( + "Commands5", "Create the Bill of Materials of the Assembly" + ) + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_PartsList.svg") def IsActive(self): if Asm4.getAssembly() is None: diff --git a/showHideLcsCmd.py b/showHideLcsCmd.py index 7356f710..31485515 100644 --- a/showHideLcsCmd.py +++ b/showHideLcsCmd.py @@ -9,6 +9,7 @@ import FreeCAD as App import Asm4_libs as Asm4 +from BaseCommand import BaseCommand from Asm4_Translate import translate @@ -19,16 +20,16 @@ | Show | +-----------------------------------------------+ """ -class showLcsCmd: - def __init__(self): - super(showLcsCmd,self).__init__() - def GetResources(self): - return {"MenuText": translate("Asm4_showLcs", "Show LCS"), - "ToolTip": translate("Asm4_showLcs", "Show LCS and Datums of selected part and its children"), - "Pixmap": os.path.join(Asm4.iconPath, 'Asm4_showLCS.svg') - } +class showLcsCmd(BaseCommand): + def __init__(self): + super(showLcsCmd, self).__init__() + self.menutext = "Show LCS" + self.tooltip = translate( + "Commands5", "Show LCS and Datums of selected part and its children" + ) + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_showLCS.svg") def IsActive(self): # if something is selected or an Asm4 assembly present @@ -47,15 +48,16 @@ def Activated(self): | Hide | +-----------------------------------------------+ """ -class hideLcsCmd: - def __init__(self): - super(hideLcsCmd,self).__init__() - def GetResources(self): - return {"MenuText": translate("Asm4_hideLcs", "Hide LCS"), - "ToolTip": translate("Asm4_hideLcs", "Hide LCS and Datums of selected part and its children"), - "Pixmap": os.path.join(Asm4.iconPath, 'Asm4_hideLCS.svg') - } + +class hideLcsCmd(BaseCommand): + def __init__(self): + super(hideLcsCmd, self).__init__() + self.menutext = "Hide LCS" + self.tooltip = translate( + "Commands5", "Hide LCS and Datums of selected part and its children" + ) + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_hideLCS.svg") def IsActive(self): # if something is selected or an Asm4 assembly present From 97443e907ee7f8964c30c82ece0c36f3ff8bc124 Mon Sep 17 00:00:00 2001 From: hasecilu Date: Sun, 25 Feb 2024 12:03:55 -0600 Subject: [PATCH 08/10] Mark 5 more tooltips for translation Commands from the 6th group. --- selectionFilter.py | 76 +++++++++++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 31 deletions(-) diff --git a/selectionFilter.py b/selectionFilter.py index cfd5c02f..cf0b94dd 100644 --- a/selectionFilter.py +++ b/selectionFilter.py @@ -12,6 +12,8 @@ from FreeCAD import Console as FCC import Asm4_libs as Asm4 +from BaseCommand import BaseCommand +from Asm4_Translate import translate global Asm4_3DselObserver @@ -33,14 +35,17 @@ button.objectName() button.setCheckable(True) """ -class selectionFilterClearCmd: - def GetResources(self): - return {"MenuText": "Clear all selection filters", - "ToolTip": "Clear all selection filters", - "Pixmap" : os.path.join( Asm4.iconPath , 'Asm4_SelectionAll.svg') - } + + +class selectionFilterClearCmd(BaseCommand): + def __init__(self): + self.menutext = "Clear all selection filters" + self.tooltip = translate("Commands6", "Clear all selection filters") + self.pixmap = os.path.join(Asm4.iconPath, "Asm4_SelectionAll.svg") + def IsActive(self): return True + def Activated(self): # This function is executed when the command is activated Gui.Selection.removeSelectionGate() @@ -49,14 +54,15 @@ def Activated(self): FCC.PrintMessage("All selection filters cleared\n") -class selectionFilterVertexCmd: - def GetResources(self): - return {"MenuText": "Select only Vertices", - "ToolTip": "Select only Vertices", - "Pixmap" : os.path.join( Asm4.iconPath , 'Snap_Vertex.svg') - } +class selectionFilterVertexCmd(BaseCommand): + def __init__(self): + self.menutext = "Select only Vertices" + self.tooltip = translate("Commands6", "Select only Vertices") + self.pixmap = os.path.join(Asm4.iconPath, "Snap_Vertex.svg") + def IsActive(self): return True + def Activated(self): # This function is executed when the command is activated button = 0 @@ -66,14 +72,15 @@ def Activated(self): Gui.Selection.removeSelectionGate() -class selectionFilterEdgeCmd: - def GetResources(self): - return {"MenuText": "Select only Edges", - "ToolTip": "Select only Edges", - "Pixmap" : os.path.join( Asm4.iconPath , 'Snap_Edge.svg') - } +class selectionFilterEdgeCmd(BaseCommand): + def __init__(self): + self.menutext = "Select only Edges" + self.tooltip = translate("Commands6", "Select only Edges") + self.pixmap = os.path.join(Asm4.iconPath, "Snap_Edge.svg") + def IsActive(self): return True + def Activated(self): # This function is executed when the command is activated button = 1 @@ -83,14 +90,15 @@ def Activated(self): Gui.Selection.removeSelectionGate() -class selectionFilterFaceCmd: - def GetResources(self): - return {"MenuText": "Select only Faces", - "ToolTip": "Select only Faces", - "Pixmap" : os.path.join( Asm4.iconPath , 'Snap_Face.svg') - } +class selectionFilterFaceCmd(BaseCommand): + def __init__(self): + self.menutext = "Select only Faces" + self.tooltip = translate("Commands6", "Select only Faces") + self.pixmap = os.path.join(Asm4.iconPath, "Snap_Face.svg") + def IsActive(self): return True + def Activated(self): # This function is executed when the command is activated button = 2 @@ -163,19 +171,25 @@ def applyFilter(button): | treeSelectionOverride | +-----------------------------------------------+ """ -class selObserver3DViewCmd( QtGui.QDialog): + + +class selObserver3DViewCmd(QtGui.QDialog): def __init__(self): - super(selObserver3DViewCmd,self).__init__() + super(selObserver3DViewCmd, self).__init__() global Asm4_3DselObserver Asm4_3DselObserver = None def GetResources(self): - return {"MenuText": "Enable/Disable 3D View selection mode", - "ToolTip": "Enable/Disable 3D View selection mode\n\n" + \ - "Allows to select a Link object in the 3D view\n" + \ + return { + "MenuText": "Enable/Disable 3D View selection mode", + "ToolTip": translate( + "Commands6", + "Enable/Disable 3D View selection mode\n\n" + "Allows to select a Link object in the 3D view\n" "window instead of the Model tree", - "Pixmap" : os.path.join( Asm4.iconPath , 'Asm4_enableLinkSelection.svg') - } + ), + "Pixmap": os.path.join(Asm4.iconPath, "Asm4_enableLinkSelection.svg"), + } def IsActive(self): return True From 272105a110ae7b60a66c61dadff769819ef7aab3 Mon Sep 17 00:00:00 2001 From: hasecilu Date: Fri, 1 Mar 2024 20:26:16 -0600 Subject: [PATCH 09/10] Make WB tooltip and menus translatables FreeCADGui.addLanguagePath(Asm4_trans) & FreeCADGui.updateLocale() need to be moved over the workbench class to be able to translate the WB tooltip --- InitGui.py | 22 ++++++++++++---------- newAssemblyCmd.py | 2 +- treeSelectionOverride.py | 22 ++++++++++++++-------- 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/InitGui.py b/InitGui.py index 654c5013..5384b535 100644 --- a/InitGui.py +++ b/InitGui.py @@ -29,11 +29,16 @@ # I don't like this being here import selectionFilter +from Asm4_Translate import translate + global Asm4_icon, Asm4_path, Asm4_trans Asm4_path = os.path.dirname(Asm4_locator.__file__) Asm4_icon = os.path.join(Asm4_path, "Resources/icons/Assembly4.svg") Asm4_trans = os.path.join(Asm4_path, "Resources/translations") +FreeCADGui.addLanguagePath(Asm4_trans) +FreeCADGui.updateLocale() + """ +-----------------------------------------------+ @@ -43,10 +48,12 @@ class Assembly4Workbench(Workbench): + from TranslateUtils import translate + global Asm4_icon global selectionFilter MenuText = "Assembly 4" - ToolTip = "Assembly 4 workbench" + ToolTip = translate("Asm4", "Assembly 4 workbench") Icon = Asm4_icon def __init__(self): @@ -117,11 +124,6 @@ def Initialize(self): pass ''' - # Translations - # from Asm4_Translate import translate - FreeCADGui.addLanguagePath(Asm4_trans) - FreeCADGui.updateLocale() - # Assembly4 version info # with file package.xml (FreeCAD ≥0.21) packageFile = os.path.join(Asm4_path, "package.xml") @@ -230,18 +232,18 @@ def Initialize(self): # Define Menus # commands to appear in the Assembly4 menu 'Assembly' - self.appendMenu(translate("Workbench", "&Assembly"), self.assemblyMenuItems()) + self.appendMenu(translate("Asm4", "&Assembly"), self.assemblyMenuItems()) self.dot() # put all constraints related commands in a separate menu - self.appendMenu("&Constraints", self.constraintsMenuItems()) + self.appendMenu(translate("Asm4", "&Constraints"), self.constraintsMenuItems()) self.dot() # self.appendMenu("&Geometry",["Asm4_newPart"]) # additional entry in the Help menu - # self.appendMenu(translate("Workbench", "&Help"), ["Asm4_Help"]) - self.appendMenu("&Help", ["Asm4_Help"]) + # self.appendMenu(translate("Asm4", "&Help"), ["Asm4_Help"]) + self.appendMenu(translate("Asm4", "&Help"), ["Asm4_Help"]) self.dot() # Define Toolbars diff --git a/newAssemblyCmd.py b/newAssemblyCmd.py index 5bc77156..183c101e 100644 --- a/newAssemblyCmd.py +++ b/newAssemblyCmd.py @@ -19,7 +19,7 @@ -from TranslateUtils import translate +from Asm4_Translate import translate class newAssemblyCmd: """ diff --git a/treeSelectionOverride.py b/treeSelectionOverride.py index 3efe0b57..7d71ec53 100644 --- a/treeSelectionOverride.py +++ b/treeSelectionOverride.py @@ -12,7 +12,7 @@ from FreeCAD import Console as FCC import Asm4_libs as Asm4 - +from Asm4_Translate import translate observer = None @@ -22,17 +22,23 @@ | main class | +-----------------------------------------------+ """ -class treeSelectionOverrideCmd( QtGui.QDialog): + + +class treeSelectionOverrideCmd(QtGui.QDialog): def __init__(self): - super(treeSelectionOverrideCmd,self).__init__() + super(treeSelectionOverrideCmd, self).__init__() def GetResources(self): - return {"MenuText": "Enable/Disable 3D View selection mode", - "ToolTip": "Enable/Disable 3D View selection mode\n\n" + \ - "Allows to select a Link object in the 3D view\n" + \ + return { + "MenuText": "Enable/Disable 3D View selection mode", + "ToolTip": translate( + "Commands6", + "Enable/Disable 3D View selection mode\n\n" + "Allows to select a Link object in the 3D view\n" "window instead of the Model tree", - "Pixmap" : os.path.join( Asm4.iconPath , 'Asm4_enableLinkSelection.svg') - } + ), + "Pixmap": os.path.join(Asm4.iconPath, "Asm4_enableLinkSelection.svg"), + } def IsActive(self): return True From 4bb9c8b92330a63e8df1e0c2845bd1943db8b705 Mon Sep 17 00:00:00 2001 From: hasecilu Date: Sun, 25 Feb 2024 12:42:53 -0600 Subject: [PATCH 10/10] Update translation script and Spanish translation The script was updated to enable the update of the `asm4.ts` file every time any other translation file is created or updated. This is made with the objective of having this file updated with the most current changes. If a translator doesn't have access to `pylupdate` command it can start translating based on the `asm4.ts` file, it's only needed to replace for using their language code (must be supported on FreeCAD). --- Resources/translations/asm4.ts | 456 +++++++++++++++++-- Resources/translations/asm4_es-ES.qm | Bin 18970 -> 21697 bytes Resources/translations/asm4_es-ES.ts | 423 +++++++++++++++-- Resources/translations/update_translation.sh | 155 ++++--- 4 files changed, 907 insertions(+), 127 deletions(-) diff --git a/Resources/translations/asm4.ts b/Resources/translations/asm4.ts index 2680cc68..7f37ca0b 100644 --- a/Resources/translations/asm4.ts +++ b/Resources/translations/asm4.ts @@ -1,28 +1,31 @@ - + + - App::Property + Asm4 - - The hintfield for the animation dialog + + Assembly 4 workbench - - - Asm4 - - Activating Assembly4 WorkBench + + Initializing Assembly4 workbench - - Leaving Assembly4 WorkBench + + &Assembly - - Initializing Assembly4 workbench + + &Constraints + + + + + &Help @@ -45,6 +48,398 @@ Create + + + Activating Assembly4 WorkBench + + + + + Leaving Assembly4 WorkBench + + + + + Asm4_Help + + + Help for Assembly4 + + + + + Show basic usage for FreeCAD and Assembly4 + + + + + Commands + + + Activates the document of the selected linked part + + + + + User-supplied information can be added to a part + + + + + <p>Insert a Part into the assembly. +This will create a dynamic link to the part, +which can be in this document or in another document +that is open in the current session</p> +<p><b>Usage</b>: the part must be open in the current session</p> +<p>This command also enables to repair broken/missing links. +Select the broken link, launch this command, and select a new target part in the list</p> + + + + + <p>Create a new Assembly container</p> + + + + + New Assembly + + + + + EXPERIMENTAL !!! +Create a variant link to a part +Select a part containing a "Variables" property container + + + + + Commands1 + + + New Part + + + + + Create a new Part + + + + + New Body + + + + + Create a new Body + + + + + New Group + + + + + Create a new Group + + + + + Commands2 + + + Imports the selected Datum object(s) from a sub-part into the root assembly. +This creates a new datum of the same type, and with the same global placement + +This command can also be used to override the placement of an existing datum : +select a second datum in the same root container as the first selected datum + + + + + Create a reference to an external shape +This creates a SubShapeBinder of the selected shapes +(face, edge, point) in the root assembly +Only shapes belonging to the same part can be imported in a single step + + + + + Create a new Datum Point in a Part + + + + + Create a new Datum Axis in a Part + + + + + Create a new Datum Plane in a Part + + + + + Create a new Coordinate System in a Part + + + + + Create a new Sketch in a Part + + + + + Commands3 + + + Move/Attach a Part in the assembly + + + + + Release an object from all attachments to any geometry + + + + + Update Assembly + + + + + Commands4 + + + Create an array of the selected object where the placement of each element is calculated using expressions and an Index property.<br> +Select a source object to array and optionally an Axis that transformation will be related to.<br> +Without axis the transformations relates to the source object internal Z axis.<br> +<br> +<b>Count :</b> The amount of elements in the array.<br> +<b>Index :</b> Hidden but Placer use it in expressions to calculating the Placements. Increments for each element starting with 0.<br> +<b>Placer :</b> Set an expression for the entire placement or its sub-properties.<br> + By opening Placer property in Tasks panel it is possible to set expressions for euler angles too.<br> +Also see tooltips in Property view + + + + + <p>Create a circular (polar) array around an axis. +Supported axis objects are axis or plane from an origin, datum line, LCS axes, straight line segments, arcs and circles</p> +<p><b>Usage</b>: Select an object and an axis (hold CTRL key to select second object)</p> + + + + + <p>Create a linear array along an axis. +Supported axis objects are axis or plane from an origin, datum line, LCS axes, straight line segments, arcs and circles</p> +<p><b>Usage</b>: Select an object and an axis for the direction (hold CTRL key to select second object)</p> + + + + + <p>Create a mirror of a part. +Supported axis objects are axis or plane from an origin, datum line, LCS axes, straight line segments, arcs and circles</p> +<p><b>Usage</b>: Select a source object and a mirror plane or a normal to a plane (hold CTRL key to select second object)</p> + + + + + + <p>Adds a variable into the <i>Variables</i> placeholder in the document. +This variable can then be used in any formula using the <i>ExpressionEngine</i> +of any compatible input field. These are marked with the "f(x)" symbol</p> + + + + + Delete a Variable + + + + + Commands5 + + + Animate Assembly + + + + + Measure Tool + + + + + Check interferences among assembled objects (may take time) + + + + + Applies selected configuration +Configurations allow to set visibilities and offsets of parts + + + + + Configurations allow to set visibilities and offsets of parts + + + + + Create a new configuration of the assembly + + + + + <p>Show the hierarchical tree structure of parts in the selected container. +The tree is displayed with ASCII art</p> +<p><b>Usage</b>: select an entity and click the command</p> + + + + + Create the Bill of Materials of the Assembly including sub-assemblies + + + + + Create the Bill of Materials of the Assembly + + + + + Show LCS and Datums of selected part and its children + + + + + Hide LCS and Datums of selected part and its children + + + + + Commands6 + + + Clear all selection filters + + + + + Select only Vertices + + + + + Select only Edges + + + + + Select only Faces + + + + + + Enable/Disable 3D View selection mode + +Allows to select a Link object in the 3D view +window instead of the Model tree + + + + + Fasteners + + + + + FastenersWorkbench is not installed. + +You can install it with the FreeCAD AddonsManager: +Menu Tools > Addon Manager > fasteners + + + + + + Insert Screw + + + + + + Insert Nut + + + + + + Insert Washer + + + + + + + Insert threaded rod + + + + + Edit Attachment of a Fastener + + + + + + + + Change Fastener parameters + + + + + <p>Insert a Screw into the Assembly</p> +<p>If another fastener is selected, a new fastener of the same type is created in the same assembly. +If an axis or LCS is selected, the new fastener will be attached to it. +If an assembly is selected, the new fastener will be inside that assembly.</p> + + + + + <p>Insert a Nut into the Assembly</p> +<p>If another fastener is selected, a new fastener of the same type is created in the same assembly. +If an axis or LCS is selected, the new fastener will be attached to it. +If an assembly is selected, the new fastener will be inside that assembly.</p> + + + + + <p>Insert a Washer into the Assembly</p> +<p>If another fastener is selected, a new fastener of the same type is created in the same assembly. +If an axis or LCS is selected, the new fastener will be attached to it. +If an assembly is selected, the new fastener will be inside that assembly.</p> + + + + + + Clone Fastener to Axes + + + + + App::Property + + + The hintfield for the animation dialog + + Asm4_Animate @@ -59,18 +454,18 @@ - - Animate Assembly + + Select Variable (only float) - - Select Variable (only float) + + Unknown State/Transition - - Variable + + Animate Assembly @@ -93,6 +488,11 @@ Sleep (s) + + + Variable + + Current Value: @@ -163,24 +563,6 @@ Run - - - Unknown State/Transition - - - - - Asm4_Help - - - Help for Assembly4 - - - - - Show basic usage for FreeCAD and Assembly4 - - Asm4_gotoDocument diff --git a/Resources/translations/asm4_es-ES.qm b/Resources/translations/asm4_es-ES.qm index dd6cf0c2992c960aafa45f119431e8d592f1a766..366bef9fcc5126e1a80e4fc555425774cb7cf5c5 100644 GIT binary patch delta 2799 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 diff --git a/Resources/translations/asm4_es-ES.ts b/Resources/translations/asm4_es-ES.ts index 3f64e575..9af638b6 100644 --- a/Resources/translations/asm4_es-ES.ts +++ b/Resources/translations/asm4_es-ES.ts @@ -3,11 +3,31 @@ Asm4 + + + Assembly 4 workbench + Entorno de trabajo Assembly 4 + Initializing Assembly4 workbench Inicializando en entorno de trabajo Assembly4 + + + &Assembly + En&samblaje + + + + &Constraints + Restri&cciones + + + + &Help + Ay&uda + @@ -19,6 +39,11 @@ Selection Filter Filtro de selección + + + Assembly 4 + Assembly 4 + done @@ -44,46 +69,34 @@ - Asm4_gotoDocument - - - Open Document - Abrir documento - + Commands Activates the document of the selected linked part Activa el documento de la parte enlazada seleccionada - - - Asm4_hideLcs - - Hide LCS - Ocultar LCS + + User-supplied information can be added to a part + La información proporcionada por el usuario se puede agregar a una parte - - Hide LCS and Datums of selected part and its children - Ocultar LCS y datums de la parte seleccionada y sus hijos - - - - Asm4_showLcs - - - Show LCS - Mostrar LCS + + <p>Insert a Part into the assembly. +This will create a dynamic link to the part, +which can be in this document or in another document +that is open in the current session</p> +<p><b>Usage</b>: the part must be open in the current session</p> +<p>This command also enables to repair broken/missing links. +Select the broken link, launch this command, and select a new target part in the list</p> + <p>Insertar una Parte en el ensamblaje. +Esto creará un enlace dinámico a la wparte, +que puede estar en este documento o en otro documento +que está abierto en la sesión actual<p> +<p><b> Uso </b>: la parte debe estar abierta en la sesión actual<p> +<p> Este comando también permite reparar enlaces rotos/faltantes. +Seleccione el enlace roto, ejecute este comando y seleccione una nueva parte de destino en la lista<p> - - - Show LCS and Datums of selected part and its children - Mostrar LCS y datums de la parte seleccionada y sus hijos - - - - Commands <p>Create a new Assembly container</p> @@ -94,6 +107,15 @@ New Assembly Nuevo ensamblaje + + + EXPERIMENTAL !!! +Create a variant link to a part +Select a part containing a "Variables" property container + ¡¡¡EXPERIMENTAL!!! +Crear un enlace variante a una parte +Seleccione una parte que contenga un contenedor de propiedades "Variables" + Commands1 @@ -128,8 +150,283 @@ Crear un nuevo grupo + + Commands2 + + + Imports the selected Datum object(s) from a sub-part into the root assembly. +This creates a new datum of the same type, and with the same global placement + +This command can also be used to override the placement of an existing datum : +select a second datum in the same root container as the first selected datum + Importa los objetos datum seleccionados de una subparte en el ensamblaje raíz. +Esto crea un nuevo datum del mismo tipo, y con la misma ubicación global + +Este comando también se puede utilizar para reemplazar la colocación de un datum existente: +seleccione un segundo datum en el mismo contenedor raíz que el primer datum seleccionado + + + + Create a reference to an external shape +This creates a SubShapeBinder of the selected shapes +(face, edge, point) in the root assembly +Only shapes belonging to the same part can be imported in a single step + Crear una referencia a una forma externa +Esto crea un SubShapeBinder de las formas seleccionadas +(cara, arista, punto) en el ensamblaje raíz +Solo las formas que pertenecen a la misma parte se pueden importar en un solo paso + + + + Create a new Datum Point in a Part + Crear un nuevo punto datum en una parte + + + + Create a new Datum Axis in a Part + Crear un nuevo eje datum en una parte + + + + Create a new Datum Plane in a Part + Crear un nuevo plano datum en una parte + + + + Create a new Coordinate System in a Part + Crear un nuevo sistema de coordenadas datum en una parte + + + + Create a new Sketch in a Part + Crear un nuevo croquis datum en una parte + + + + New Part + Nueva parte + + + + Create a new Part + Crear una nueva parte + + + + New Body + Nuevo cuerpo + + + + Create a new Body + Crear un nuevo cuerpo + + + + New Group + Nuevo grupo + + + + Create a new Group + Crear un nuevo grupo + + + + Commands3 + + + Move/Attach a Part in the assembly + Mover/Asociar una parte en el ensamblaje + + + + Release an object from all attachments to any geometry + Liberar un objeto de todas las asociaciones a cualquier geometría + + + + Update Assembly + Actualizar ensamblaje + + + + Commands4 + + + Create an array of the selected object where the placement of each element is calculated using expressions and an Index property.<br> +Select a source object to array and optionally an Axis that transformation will be related to.<br> +Without axis the transformations relates to the source object internal Z axis.<br> +<br> +<b>Count :</b> The amount of elements in the array.<br> +<b>Index :</b> Hidden but Placer use it in expressions to calculating the Placements. Increments for each element starting with 0.<br> +<b>Placer :</b> Set an expression for the entire placement or its sub-properties.<br> + By opening Placer property in Tasks panel it is possible to set expressions for euler angles too.<br> +Also see tooltips in Property view + Crear un arreglo del objeto seleccionado donde se calcula la colocación de cada elemento utilizando expresiones y una propiedad de índice.<br> +Seleccione un objeto de origen al arreglo y opcionalmente un eje con el que la transformación estará relacionada.<br> +Sin un eje, las transformaciones se relacionan con el eje z interno del objeto de origen.<br> +<br> +<b>Cuenta: </b>La cantidad de elementos en el arreglo. <br> +<b>Índice: </b>Oculto pero se usa en expresiones para calcular las ubicaciones. Incrementos para cada elemento comenzando en 0.<br> +<b>Placer: </b> Establece una expresión para toda la colocación o sus subpropiedades.<br> +Al abrir la propiedad Placer en el panel de tareas, también es posible establecer expresiones para los ángulos de Euler.<br> +Consulte también la información sobre herramientas en la vista de propiedades + + + + <p>Create a circular (polar) array around an axis. +Supported axis objects are axis or plane from an origin, datum line, LCS axes, straight line segments, arcs and circles</p> +<p><b>Usage</b>: Select an object and an axis (hold CTRL key to select second object)</p> + <p>Crear un arreglo circular (polar) alrededor de un eje. +Los objetos del eje soportados son un eje o un plano desde un origen, línea datum, ejes LCS, segmentos de línea recta, arcos y círculos</p> +<p><b>Uso</b>: Seleccione un objeto y un eje (mantenga presionado la tecla CTRL para seleccionar el segundo objeto)</p> + + + + <p>Create a linear array along an axis. +Supported axis objects are axis or plane from an origin, datum line, LCS axes, straight line segments, arcs and circles</p> +<p><b>Usage</b>: Select an object and an axis for the direction (hold CTRL key to select second object)</p> + <p>Crear un arreglo lineal a lo largo de un eje. +Los objetos del eje soportados son un eje o un plano desde un origen, línea datum, ejes LCS, segmentos de línea recta, arcos y círculos</p> +<p><b>Uso</b>: Seleccione un objeto y un eje para la dirección (mantenga presionado la tecla CTRL para seleccionar el segundo objeto)</p> + + + + <p>Create a mirror of a part. +Supported axis objects are axis or plane from an origin, datum line, LCS axes, straight line segments, arcs and circles</p> +<p><b>Usage</b>: Select a source object and a mirror plane or a normal to a plane (hold CTRL key to select second object)</p> + <p>Crear un espejo de una parte. +Los objetos del eje soportados son un eje o un plano desde un origen, línea datum, ejes LCS, segmentos de línea recta, arcos y círculos</p> +<p><b>Uso</b>: Seleccione un objeto de origen y un plano espejo o una normal a un plano (mantenga presionado la tecla CTRL para seleccionar el segundo objeto)</p> + + + + <p>Adds a variable into the <i>Variables</i> placeholder in the document. +This variable can then be used in any formula using the <i>ExpressionEngine</i> +of any compatible input field. These are marked with the "f(x)" symbol</p> + <p>Agregar una variable a <i>Variables </i> en el documento. +Esta variable se puede usar en cualquier fórmula usando <i>ExpressionEngine</i> +de cualquier campo de entrada compatible. Estos están marcados con el símbolo "f(x)"</p> + + + + Delete a Variable + Eliminar una variable + + + + Commands5 + + + Animate Assembly + Animar ensamblaje + + + + Measure Tool + Herramienta de medición + + + + Check interferences among assembled objects (may take time) + Comprobar interferencias entre los objetos ensamblados (podría tomar tiempo) + + + + Applies selected configuration +Configurations allow to set visibilities and offsets of parts + Aplicar la configuración seleccionada +Las configuraciones permiten establecer visibilidades y desplazamientos de partes + + + + Configurations allow to set visibilities and offsets of parts + Las configuraciones permiten establecer visibilidades y desplazamientos de partes + + + + Create a new configuration of the assembly + Crear una nueva configuración del ensamblaje + + + + <p>Show the hierarchical tree structure of parts in the selected container. +The tree is displayed with ASCII art</p> +<p><b>Usage</b>: select an entity and click the command</p> + <p>Mostrar el árbol de estructura jerárquica de las partes en el contenedor seleccionado. +El árbol es mostrado con arte ASCII</p> +<p><b>Uso</b>: seleccione una entidad y dé clic en el comando</p> + + + + Create the Bill of Materials of the Assembly including sub-assemblies + Crear la lista de materiales del ensamblaje incluyendo sub-ensamblajes + + + + Create the Bill of Materials of the Assembly + Crear la lista de materiales del ensamblaje + + + + Show LCS and Datums of selected part and its children + Mostrar LCS y datums de la parte seleccionada y sus hijos + + + + Hide LCS and Datums of selected part and its children + Ocultar LCS y datums de la parte seleccionada y sus hijos + + + + Commands6 + + + Clear all selection filters + Borrar todos los filtros de selección + + + + Select only Vertices + Seleccionar solo vértices + + + + Select only Edges + Seleccionar solo aristas + + + + Select only Faces + Seleccionar solo caras + + + + Enable/Disable 3D View selection mode + +Allows to select a Link object in the 3D view +window instead of the Model tree + Habilitar/deshabilitar el modo de selección de vista 3D + +Permite seleccionar un objeto de enlace en la ventana +de vista 3D en lugar del árbol del modelo + + Fasteners + + + + FastenersWorkbench is not installed. + +You can install it with the FreeCAD AddonsManager: +Menu Tools > Addon Manager > fasteners + El entorno de trabajo Fasteners no está instalado. + +Puede instalarlo con el gestor de complementos de FreeCAD: +Menú Herramientas > Gestor de complementos > Fasteners + @@ -154,18 +451,68 @@ Insert threaded rod Insertar barra roscada + + + Edit Attachment of a Fastener + Editar asociación de un elemento de sujeción + + + + + Change Fastener parameters + Cambiar parámetros de elemento de sujeción + + + + <p>Insert a Screw into the Assembly</p> +<p>If another fastener is selected, a new fastener of the same type is created in the same assembly. +If an axis or LCS is selected, the new fastener will be attached to it. +If an assembly is selected, the new fastener will be inside that assembly.</p> + <p> Insertar un perno en el conjunto</p> +<p> Si se selecciona otro elemento de sujeción, se crea un nuevo elemento de sujeción del mismo tipo en el mismo ensamblaje. +Si se selecciona un eje o LCS, el nuevo elemento de sujeción se unirá a él. +Si se selecciona un ensamblaje, el nuevo elemento de sujeción estará dentro de ese ensamblaje. </p> + + + + <p>Insert a Nut into the Assembly</p> +<p>If another fastener is selected, a new fastener of the same type is created in the same assembly. +If an axis or LCS is selected, the new fastener will be attached to it. +If an assembly is selected, the new fastener will be inside that assembly.</p> + <p> Insertar una tuerca en el conjunto</p> +<p> Si se selecciona otro elemento de sujeción, se crea un nuevo elemento de sujeción del mismo tipo en el mismo ensamblaje. +Si se selecciona un eje o LCS, el nuevo elemento de sujeción se unirá a él. +Si se selecciona un ensamblaje, el nuevo elemento de sujeción estará dentro de ese ensamblaje. </p> + + + + <p>Insert a Washer into the Assembly</p> +<p>If another fastener is selected, a new fastener of the same type is created in the same assembly. +If an axis or LCS is selected, the new fastener will be attached to it. +If an assembly is selected, the new fastener will be inside that assembly.</p> + <p> Insertar una arandela en el conjunto</p> +<p> Si se selecciona otro elemento de sujeción, se crea un nuevo elemento de sujeción del mismo tipo en el mismo ensamblaje. +Si se selecciona un eje o LCS, el nuevo elemento de sujeción se unirá a él. +Si se selecciona un ensamblaje, el nuevo elemento de sujeción estará dentro de ese ensamblaje. </p> + + + + + Clone Fastener to Axes + Clonar elemento de sujeción al eje + - Workbench + Asm4_gotoDocument - - &Assembly - &Ensamblaje + + Open Document + Abrir documento - - &Help - &Ayuda + + Activates the document of the selected linked part + Activa el documento de la parte enlazada seleccionada diff --git a/Resources/translations/update_translation.sh b/Resources/translations/update_translation.sh index 57ed5991..387d05d0 100755 --- a/Resources/translations/update_translation.sh +++ b/Resources/translations/update_translation.sh @@ -2,9 +2,9 @@ # -------------------------------------------------------------------------------------------------- # -# Update translation files +# Create, update and release translation files. # -# Supported locales on FreeCAD <2024-01-20, FreeCADGui.supportedLocales(), total=40>: +# Supported locales on FreeCAD <2024-03-13, FreeCADGui.supportedLocales(), total=43>: # {'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', @@ -16,24 +16,36 @@ # '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 +# NOTE: PREPARATION +# - 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 +# - 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 script has to be executed within the `Resources/translations` directory. +# Executing the script with no flags invokes the help. +# $ ./update_translation.sh +# +# NOTE: WORKFLOW TRANSLATOR (LOCAL) +# - Execute the script passing the `-u` flag plus locale code as argument +# Only update the file(s) you're translating! +# $ ./update_translation.sh -u es-ES +# - Do the translation via Qt Linguist and use `File>Release` +# - If releasing with the script execute it passing the `-r` flag +# plus locale code as argument +# $ ./update_translation.sh -r es-ES +# +# NOTE: WORKFLOW MAINTAINER (CROWDIN) +# - Execute the script passing the '-U' flag +# $ ./update_translation.sh -U +# - Upload the updated file to Crowdin and wait for translators do their thing ;-) +# - Once done, download the translated files, copy them to `Resources/translations` +# and release all the files to update the changes +# $ ./update_translation.sh -R # # The usage of `pylupdate6` is preferred over 'pylupdate5' when extracting text strings from -# Python files. +# Python files. Also using `lupdate` from Qt6 is possible. # # -------------------------------------------------------------------------------------------------- @@ -41,7 +53,8 @@ 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" + "ro" "ru" "sr" "sr-CS" "sk" "sl" "es-ES" "es-AR" "sv-SE" "tr" + "uk" "val-ES" "vi" ) is_locale_supported() { @@ -55,61 +68,99 @@ is_locale_supported() { } get_strings() { - # Get translatable strings from ../ui/*.ui Qt Designer files - # lupdate ../ui/*.ui -ts uifiles.ts -no-obsolete - # Get translatable strings from ../../*.py Python files + # Get translatable strings from Qt Designer files + # lupdate ../*.ui -ts uifiles.ts -no-obsolete + # Get translatable strings from Python files + # pylupdate5 -verbose ../../*.py -ts pyfiles.ts pylupdate6 ../../*.py -ts pyfiles.ts + # Join strings from Qt Designer and Python files into a single temp file + lconvert -i pyfiles.ts -o _${WB}.ts -sort-contexts -no-obsolete } -delete_files() { +update_locale() { + local locale="$1" + local u=${locale:+_} # Conditional underscore + + # NOTE: Execute the right commands depending on: + # - if the file already exists and + # - if it's a locale file or the main, agnostic one + if [ ! -f "${WB}${u}${locale}.ts" ]; then + echo -e "\033[1;34m\n\t<<< Creating '${WB}${u}${locale}.ts' file >>>\n\033[m" + get_strings + if [ "$locale" == "" ]; then + lconvert -i _${WB}.ts -o ${WB}.ts + else + lconvert -source-language en -target-language "${locale//-/_}" \ + -i _${WB}.ts -o ${WB}_${locale}.ts + fi + else + echo -e "\033[1;34m\n\t<<< Updating '${WB}${u}${locale}.ts' file >>>\n\033[m" + get_strings + if [ "$locale" == "" ]; then + lconvert -i _${WB}.ts ${WB}.ts -o ${WB}.ts + else + lconvert -source-language en -target-language "${locale//-/_}" \ + -i _${WB}.ts ${WB}_${locale}.ts -o ${WB}_${locale}.ts + fi + fi + # Delete files that are no longer needed - # rm uifiles.ts rm pyfiles.ts - rm -f ${WB}.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 -i uifiles.ts pyfiles.ts -o ${WB}_${LOCALE}.ts - 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 strings from Qt Designer and Python files - # lconvert -i uifiles.ts pyfiles.ts -o ${WB}.ts - lconvert -i pyfiles.ts -o ${WB}.ts - # Join newly created file with older file ( -no-obsolete) - lconvert -source-language en -target-language $LOCALE \ - -i ${WB}.ts ${WB}_${LOCALE}.ts -o ${WB}_${LOCALE}.ts +release_locale() { + # Release locale (creation of *.qm file from *.ts file) + local locale="$1" + lrelease ${WB}_${locale}.ts } -release_translation() { - # Release translation (creation of *.qm file from *.ts file) - lrelease ${WB}_${LOCALE}.ts +help() { + echo -e "\nDescription:" + echo -e "\tCreate, update and release translation files." + echo -e "\nUsage:" + echo -e "\t./update_translation.sh [-R] [-U] [-r ] [-u ]" + echo -e "\nFlags:" + echo -e " -R\n\tRelease all locales" + echo -e " -U\n\tUpdate main translation file (locale agnostic)" + echo -e " -r \n\tRelease the specified locale" + echo -e " -u \n\tUpdate strings for the specified locale" } # Main function ------------------------------------------------------------------------------------ WB="asm4" -LOCALE="$1" -if is_locale_supported "$LOCALE"; then - if [ "$2" == "-r" ]; then - release_translation +if [ $# -eq 0 ]; then + help +elif [ $# -eq 1 ]; then + if [ "$1" == "-R" ]; then + find . -type f -name '*_*.ts' | while IFS= read -r file; do + # Release all locales + lrelease $file + echo + done + elif [ "$1" == "-U" ]; then + # Update main file (agnostic) + update_locale else - if [ ! -f "${WB}_${LOCALE}.ts" ]; then - add_new_locale - else + help + fi +elif [ $# -eq 2 ]; then + LOCALE="$2" + if is_locale_supported "$LOCALE"; then + if [ "$1" == "-r" ]; then + # Release locale + release_locale "$LOCALE" + elif [ "$1" == "-u" ]; then + # Update main & locale files update_locale + update_locale "$LOCALE" fi - delete_files + 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 else - echo "Verify your language code. Case sensitive." - echo "If it's correct ask a maintainer to add support for your language on FreeCAD." + help fi