Translating an external workbench

From FreeCAD Documentation
Revision as of 10:31, 25 May 2019 by Mario52 (talk | contribs) (Marked this version for translation)

In the following notes, “context” should be your addon name, ex. “MySuperAddon”. It is how all the translations of your addon will be gathered under a same name, to be more easily identified by translators

1. Preparing the sources

General

  • Add a “translations” folder. You can name it to something else, but this will be easier as it is the same throughout FreeCAD. In this folder, you will place the .ts files (the “source” translation files) and .qm files (compiled translation files).
  • Only the text that is shown to the user in the FreeCAD UI should be translated. Text that is only shown in the Python console should not be translated.

In every .py file:

  • In every file where you need to translate text, you need a translate() function defined. An easy way is to use the one from the Draft workbench: from DraftTools import translate
  • All text that must be translated must be placed inside the translate() function. So print("My text") becomes print(translate("context","My text")). This can be used anywhere: in print() functions, in FreeCAD.Console.PrintMessage(), in Qt dialogs, etc. In functions from FreeCAD.Console.Print*, it is necessary to end the string with the new line character (\n). It is advised to leave that character out of the translation: FreeCAD.Console.PrintMessage(translatr("context","My String")+"\n")
  • If you are using .ui files made with QtDesigner, nothing special needs to be done with them.
  • When creating new objects, do not translate object names. Rather, translate object labels
  • When creating properties for your objects, don’t translate the property name. But place the description inside QT_TRANSLATE_NOOP: obj.addProperty("App::PropertyBool","MyProperty","PropertyGroup",QT_TRANSLATE_NOOP("App::Property","This is what My Property does")) (don’t use your own “context” in this specific case. Keep “App::Property”).
  • Do not translate the text of Document transactions made with Document.openTransaction()

In InitGui.py:

  • Add the following line, close to the top of the file: def QT_TRANSLATE_NOOP(scope, text): return text
  • To translate menu names: self.appendMenu(QT_TRANSLATE_NOOP("context","My Menu"),[list of commands,...])
  • The QT_TRANSLATE_NOOP macro doesn’t do anything, but it marks texts to be picked up by the lupdate utility later on. Since it doesn’t actually translate the text in FreeCAD (it does nothing), we only use it in special cases where FreeCAD itself takes care of everything.
  • Add the path to your “translations” folder in the Initialized function: FreeCADGui.addLanguagePath("/path/to/translations"). The InitGui.py file has no file attribute, so it is not easy to find the translations folder’s relative location. An easy way to workaround this is to make it import another file from the same folder, and in that file, do FreeCADGui.addLanguagePath(os.path.join(os.path.dirname(__file__),"translations"))

Inside each FreeCAD command class:

  • Add the following line, close to the top of the file: def QT_TRANSLATE_NOOP(context, text): return text
  • Translate the MenuText and Tooltip of the command like this:
    def GetResources(self):

        return {'Pixmap'  : "path/to/icon.svg"),
                'MenuText': QT_TRANSLATE_NOOP("CommandName", "My Command"),
                'ToolTip' : QT_TRANSLATE_NOOP("CommandName", "Describes what the command does"),
                'Accel':    "Shift+A"}

where CommandName is the name of the command, defined by FreeCADGui.addCommand('CommandName',My_Command_Class())

2. Gather all the strings from your module

  • You will need the lupdate, lconvert, lrelease and pylupdate tools installed on your system. They usually come with packages named pysie-tools or pyside2-tools. On some systems lupdate is named lupdate4 or lupdate5 or lupdate-qt4. Same for the other tools. You can usually use the qt4 or qt5 version at your choice.
  • If you have .ui files, you need to run lupdate first: lupdate *.ui -ts translations/uifiles.ts. This is recursive and will find ui files inside all your dir structure
  • If you have .py files, you need to run pylupdate too: pylupdate *.py -ts translations/pyfiles.ts
  • If you ran both operations, you now need to unify these two files into one: lconvert -i translations/uifiles.ts translations/pyfiles.ts -o translations/MyModule.ts
  • Check the contents of the three ts files to make sure that they contain the strings, then you can delete both pyfile.ts and uifiles.ts.
  • you can do it all in one bash script like this:
#!env sh
lupdate *.ui -ts translations/uifiles.ts
pylupdate *.py -ts translations/pyfiles.ts
lconvert -i translations/uifiles.ts translations/pyfiles.ts -o translations/MyModule.ts
rm translations/pyfiles.ts
rm translations/uifiles.ts

3. Send the .ts file to a translation platform

It is time to have your .ts file translated. You can choose to set up an account on a public translation platform such as Crowdin or Transifex, or you can benefit from our existing FreeCAD account at https://crowdin.com/project/freecad, which has many users already, and therefore more chance to have your file translated quickly and by people who know FreeCAD.

If you wish to host your file on the FreeCAD crowdin account, get in touch with Yorik on the forum.

Note that some platforms like Crowdin can integrate with github and do all the process from points 2,3 and 4 automatically. For that, you can’t use the FreeCAD crowdin account, and will need to set up yours.

4. Merge the translations

Once your .ts file has been translated, even if partially, you can download the translations from the site:

  • You will usually download a .zip file containing one .ts per language
  • Place all the translated .ts files, together with your base .ts file, in the “translations” folder

5. Compile the translations

for f in translations/*_*.ts; do lrelease "translations/$f"; done

You should find one .qm file for each translated .ts file. The .qm files is what will be used by Qt and FreeCAD at runtime.

That’s all you need. Note that certain parts of your workbench cannot be retranslated on-the-fly, and will need a FreeCAD restart if you change the language.

Related Pages