Translation Cleanup Project - sliptonic/FreeCAD GitHub Wiki
Background
A problem was reported with Path's translation.. After analysis, it was found that much of Path has inconsistent and problematic translation. This results from too much copy-pasting of code over the years. This page is documenting a cleanup effort.
Technical details about translation are found on this wiki page:
SNIPPETS
from PySide.QtCore import QT_TRANSLATE_NOOP
translate = FreeCAD.Qt.translate
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
Procedure.
Work on a group of related files together. Keep the commits ordered so that a git bisect can be used to identify where a problem is introduced.
BASELINE
First run black and commit. (all the black reformats can be in one commit) This gives a baseline. A black reformat shouldn't introduce any errors. When anyone needs to rebase later, they can run black on their own file and commit. Then a rebase will eliminate the black related changes and make merge resolution much easier.
IMPORTS and SNIPPETS
Check if the file uses QT_TRANSLATE_NOOP, translate() or both. Use the snippest above that are appropriate and delete the old ones.
If the file has a PathLog statement, it should look like the if block above. If not, replace it.
QT_TRANSLATE_NOOP usage
run a global search and replace to replace instances of QtCore.QT_TRANSLATE_NOOP() with QT_TRANSLATE_NOOP() This just shortens lines that may be overlong.
PROPERTIES
Check if any objects add properties. The important part is that the help text uses QT_TRANSLATE_NOOP and the context string is "App::Property" See example below
obj.addProperty("App::PropertyBool", "MyProperty", "PropertyGroup", QT_TRANSLATE_NOOP("App::Property", "This is what My Property does"))
COMMANDS
Check any commands that are created. Look for a function like GetResources that returns a dictionary. It should use QT_TRANSLATE_NOOP() for MenuText and ToolTip
Context Strings in Commands MUST match the command name.
Check all uses of translate()
Translate
- User-output to report view
Do Not translated
- Developer oriented error messages should not be translated
- Transactions
Regularize Context Strings
Check all the context strings for both translate() and QT_TRANSLATE_NOOP() Property context strings should always be "App::Property" General Path related context should be "Path" Operation specific context should be "Profile" or "PathProfile" Multiword context strings should be PascalCase not camelCase or snake_case Try to change context strings as little as possible.
COMBOBOXES
For Gui and FeatureObjects with comboboxes
- Build enums for comboboxes in the Object file. Make sure the Gui file is getting them and populating the comboboxes.
- Use QT Designer, Edit the .ui file and replace contents with PLACEHOLDER
- Mark comboboxes not translated
- Change blocksignals to use QSignalBlocker
TESTS
Make sure you haven't broken anything. From the command line run
FreeCADCmd -t TestPathApp
and make sure it ends without error 'ok'
Run pylupdate output and check results. The following command run from the Mod directory will extract the strings from PathOpGui.py and build the xml in junk.tx. You can then open this to see results. The @default context should be missing or empty. Check the remaining output to make sure the context looks appropriate. You can then delete junk.tx. (DON'T COMMIT IT)
pylupdate5 Path/PathScripts/PathOpGui.py -ts junk.ts
Launch FreeCAD, switch to Path. Make sure the UI for your area looks good. Go to Edit->Preferences and change language to another. German is a good choice. Say 'ok' Inspect the GUI again looking at menus and task panels. Make sure no new console errors are appearing.
Strings may not be translated, and will not be translated if the context string changed. This is normal.
If everything looks good, Run Black one more time, commit any changes.
Changes that require correct context strings to be tested need the .ts file to be updated. This is an xml file that can be edited by hand for testing. one per language. After editing, run lrelease on the file to generate a .qm file. Then a full build. Now the translated strings with context should be available to the translate() call.
The Work to be done
The following are complete
- Path/PathScripts/PathOpGui.py
- Path/PathScripts/PathProfile.py
- Path/PathScripts/PathProfileGui.py
- Path/InitGui.py
- Path/PathCommands.py
- Path/PathScripts/PathCopy.py
- Path/PathScripts/PathComment.py
- Path/PathScripts/PathCustom.py
- Path/PathScripts/PathCustomGui.py
- Path/PathScripts/PathUtil.py
- Path/PathScripts/PathUtils.py
- Path/PathScripts/PathStock.py
- Path/PathScripts/PathStop.py
- Path/PathScripts/PathSanity.py
- Path/PathScripts/PathGeom.py
- Path/PathScripts/PathHop.py
- Path/PathScripts/PathArray.py
- Path/PathScripts/PathCollision.py
- Path/PathScripts/PathFixture.py
- Path/PathScripts/PathPlane.py
- Path/PathScripts/PathPropertyEditor.py
- Path/PathScripts/PathIconViewProvider.py
- Path/PathScripts/PathPost.py
- Path/PathScripts/PostUtils.py
- Path/PathScripts/post/gcode_pre.py
- Path/PathScripts/post/grbl_post.py
- Path/PathScripts/post/marlin_post.py
- Path/PathScripts/PathSetupSheet.py
- Path/PathScripts/PathSetupSheetGui.py
- Path/PathScripts/PathSetupSheetOpPrototypeGui.py
- Path/PathScripts/PathSimpleCopy.py
- Path/PathScripts/PathSimulatorGui.py
- Path/PathScripts/PathDressupLeadInOut.py
- Path/PathScripts/PathDressupDragknife.py
- Path/PathScripts/PathDeburr.py
- Path/PathScripts/PathDeburrGui.py
- Path/PathScripts/PathInspect.py
- Path/PathScripts/PathProbe.py
- Path/PathScripts/PathProbeGui.py
- Path/PathScripts/PathHelix.py
- Path/PathScripts/PathHelixGui.py
- Path/PathScripts/PathGui.py
- Path/PathScripts/PathDressupZCorrect.py
- Path/PathScripts/PathDressupAxisMap.py
- Path/PathScripts/PathVcarve.py
- Path/PathScripts/PathVcarveGui.py
- Path/PathScripts/PathDrilling.py
- Path/PathScripts/PathDrillingGui.py
- Path/PathScripts/PathThreadMilling.py
- Path/PathScripts/PathThreadMillingGui.py
- Path/PathScripts/PathToolController.py
- Path/PathScripts/PathToolControllerGui.py
- Path/PathScripts/PathToolLibraryEditor.py
- Path/PathScripts/PathToolLibraryManager.py
- Path/PathScripts/PathAdaptive.py
- Path/PathScripts/PathAdaptiveGui.py
- Path/PathScripts/PathPreferencesAdvanced.py
- Path/PathScripts/PathToolBit.py
- Path/PathScripts/PathToolBitCmd.py
- Path/PathScripts/PathToolBitEdit.py
- Path/PathScripts/PathToolBitGui.py
- Path/PathScripts/PathToolBitLibraryCmd.py
- Path/PathScripts/PathToolBitLibraryGui.py
- Path/PathScripts/PathEngrave.py
- Path/PathScripts/PathEngraveBase.py
- Path/PathScripts/PathEngraveGui.py
- Path/PathScripts/PathMillFace.py
- Path/PathScripts/PathMillFaceGui.py
- Path/PathScripts/PathPocketBase.py
- Path/PathScripts/PathPocketBaseGui.py
- Path/PathScripts/PathPocketShape.py
- Path/PathScripts/PathPocketShapeGui.py
- Path/PathScripts/PathPocket.py
- Path/PathScripts/PathPocketGui.py
PR is pending
#5436 bug/translationjob
- Path/PathScripts/PathJob.py
- Path/PathScripts/PathJobCmd.py
- Path/PathScripts/PathJobDlg.py
- Path/PathScripts/PathJobGui.py
- Path/PathScripts/PathPreferencesPathDressup.py
- Path/PathScripts/PathProfileContourGui.py
- Path/PathScripts/PathProfileEdgesGui.py
- Path/PathScripts/PathProfileFacesGui.py
- Path/PathScripts/PathDressupDogbone.py
- Path/PathScripts/PathDressupPathBoundary.py
- Path/PathScripts/PathDressupPathBoundaryGui.py
- Path/PathScripts/PathDressupRampEntry.py
- Path/PathScripts/PathDressupTag.py
- Path/PathScripts/PathDressupTagGui.py
- Path/PathScripts/PathDressupTagPreferences.py
- Path/PathScripts/PathDressupHoldingTags.py
- Path/PathScripts/PathFeatureExtensions.py
- Path/PathScripts/PathFeatureExtensionsGui.py (5442)
- Path/PathScripts/PathAreaOp.py
- Path/PathScripts/PathCircularHoleBase.py
- Path/PathScripts/PathOp.py
- Path/PathScripts/PathOpTools.py
- Path/PathScripts/PathSurface.py
- Path/PathScripts/PathSurfaceGui.py
- Path/PathScripts/PathSurfaceSupport.py
- Path/PathScripts/PathWaterline.py
- Path/PathScripts/PathWaterlineGui.py
- Path/PathScripts/PathPropertyBag.py
- Path/PathScripts/PathPropertyBagGui.py
The following are complete but a PR has not been submitted yet.
The Following are still to be done.
- Path/PathScripts/PathSlot.py
- Path/PathScripts/PathSlotGui.py