-
-
Notifications
You must be signed in to change notification settings - Fork 121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Project basic internationalization support #673
Conversation
Thanks! That's quite a lot of work. Much appreciated. There's a few consistent deviations from the coding style in this, so instead of going through and reviewing them I may just push a commit to change them instead of tagging them all. Mainly, they are:
There are also two constants that have been translated that shouldn't. The "internal" and "enchant" should not be translated. That will break if someone changes language after the program has first been run. "enchant" is the name of a package, and should not be translated at all, and "internal" should only be translated when it's added to the GUI. I can rewrite the code to do a lookup for the GUI where the translation can be injected. The root folder for language files should either be at the root of the project or in the assets folder. I'll have a look at how the files are processed to see what's best. Essentially, the files that must be shipped with the package should be in assets, and the source files for translations should be in a folder on root level. Ideally. I'm not sure what the Qt linguist tool expects. |
We also need to figure out how to make the tests run with the language framework. I see you only initialise it in the default run mode, which isn't the one used for most tests. In any case, I think I will move the translation initialisation into the Config class, if possible, so that it can be overridden by user settings. This will also fix the issue here from where the path to the language files is extracted. The |
The test framework seems fine actually. The tests fail because of bugs introduced here. |
Thank you for prefer to push the changes instead of reviewing them all. |
I've branched off the code for the 1.2 release path, which now lives in the Thanks for explaining the I'm currently working on a commit where I'm moving the initialisation of the translation objects into the CONFIG object. I've almost got it working. When it's moved there, the user config file determines the language for the GUI, which uses the system language as the default. When I get this working, I'll add an option to select GUI language to the Preferences dialog. So let me know if you make any changes to the content of the |
Nice, you may continue your refactor, don't mind. I'm just looking for some composite translations to improve, like |
Sounds good. I just finished the moving of the initialisation from Changing the GUI language can now be achieved by editing the "guilang" option in the main configuration file, which also allows me to test the Portuguese version of the GUI. I'll probably start adding a Norwegian translation too soon to get a feel for that side of it. I'll do that in a later PR though. Anyway, it's getting quite late here in Europe, so I'll pick it up again tomorrow after work. |
By the way, I noticed that the |
I was reading up on the Qt documentation last night and noticed the QLocale and QTranslator objects already have all the logic for parsing localisation strings and figuring out which files to load. I replaced the regex-based and customised loading facility with Qt's own. I also added a global CONFIG.qLocale object that can be used around the code for various localisation purposes. |
Yeah, about the |
I got that, but this is what the Qt tool does as well: https://doc.qt.io/qt-5/qlocale.html#uiLanguages, but I see that I may need to do it in a loop. Let me test with English which is layered like that. |
Yes, this |
That's what I was thinking, It supports all the standards and is maintained, which means I don't have to. Also, it should not be reversed as the translators are used in the reverse order they are added. The one for
So it will pick the last one first, and work its way up. Anyway, I'll convert this back to a loop. |
Great. I'll finish this after work. The previous stuff is something I looked at last night. About the ISO lookup tables. I also looked into what the QLocale class can do, and it has the ability to print the native language name for any given language code it supports. I propose to use this as the information on the status bar and in Preferences, instead of a localised translation of other languages. A lot of apps do this, and it make sense as a user who have multiple languages installed will presumably understand the native name for these languages. At my end, the status bar will say "British English (en-GB)" and "Norsk Bokmål (nb-NO)" for the languages I use, and similar for Portuguese etc. Showing the code will also aid in describing them when you don't understand the native name, which may be the case for the dropdown list of available GUI languages in Preferences. The bonus is of course that I can drop the whole |
I think is the best solution. The translation of iso.py was not that difficult because Wikipedia provides the translation table for ISO names, just have to copy them to "linguist" is the worst. |
The date format should be handled by Python as all dates/times that go onto the GUI are formatted with Any date/time that go onto filenames and into files are ISO 8601 formats and should not be localised. With the changes I'm making now, I'm also making sure the QApplication defaults to the correct locale, so I noticed now that the QDoubleSpinBox widgets have the correct decimal separator for the selected language. This appears to be handled when I added the |
In addition to this, there is an issue with the translation macro from C++ that doesn't transfer well to Python (The Also, you can use Edit: Also, this: https://stackoverflow.com/questions/28385477/pyside-qt-tr-does-not-translate-translate-does-context-wrong |
A possible solution, based on your last link is to have something like from functools import partial
from QtCore import QCoreApplication
tr = partial(QCoreApplication.translate, "context") WDYT? |
nw/gui/build.py
Outdated
self.novelFiles.setToolTip(self.tr("Include files with layouts {0}.").format( | ||
self.locale().createSeparatedList([ | ||
self.locale().quoteString(self.tr('Book')), | ||
self.locale().quoteString(self.tr('Page')), | ||
self.locale().quoteString(self.tr('Partition')), | ||
self.locale().quoteString(self.tr('Chapter')), | ||
self.locale().quoteString(self.tr('Unnumbered')), | ||
self.locale().quoteString(self.tr('Scene')), | ||
]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vkbo This is how I suggest working with lists and quoted terms.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is too much to be honest. Translation already creates overhead, and this is just a tooltip.
Edit: The tooltip text is already localised, so if there is need for different symbols, then that should be done in the ts file, not like this.
Update Aha, it turns out the Anyway, this is the main repo. It should be possible to submit translations. |
…ke some minor changes to tooltips in build and status bar
I saw your ToDo tag in the numberToWord function, so I extended it to support multiple languages. It was hard coded to English. Now it should use the spell check language for the project, and if there is no function to do the conversion, it should fall back to just use plain numbers. I also added the two forms of Norwegian as a test case, and it now picks up the project language setting and produces the correct number words. |
Translation updated. I'm done too. |
Great! I think this is in a good state now. There is just one thing that I thought about just now, and that's the translation of the words "Note", "Comment" and "Synopsis" as used in the I don't want to add a whole new In any case, I have another branch dealing with those functions, so I'll add that there instead. This PR seems complete now and I will merge it after a last full read through of the diff. I still haven't decided on how to deal with the dialog button texts. I'm inclined to stick with your override approach as there are many languages that don't have |
indeed |
About the |
I'll make one last push to this. I found a few more errors and missing translations and I also want to remove most of the nested translations. I understand the point of having the order of items in a string in a different translation entry than the content, but in the majority of cases the order can be handled within a single entry. Python is significantly slower than C/C++, and the only way to keep a Python GUI application snappy and responsive is to save clock cycles at every opportunity. I use a few other Python GUI applications, and as they grow, they get increasingly sluggish. novelWriter is still very responsive in most cases (with the exception of handling >1 MB text files) and I want to keep it this way. The benefit of I'll push the remaining changes after work. |
I've looked at it before, and decided against adding a dependency for such a simple feature. I am avoiding dependencies unless they are absolutely necessary. I spent nearly a week writing the ODT exporter to avoid adding Edit: I'm going to add the German |
Every time I look through the code, I find something. I found more missing translates, and I realise one of my earlier changes broke all the translations in the Constants context. Sorry! After two full passes through the code, I think I've found the majority of issues. After you've updated the translations, I think I will merge. I've updated the There are also some translations that are very long. I realise different languages need different length to achieve the same meaning, but some of the texts are so verbose that they mess up the GUI in several places. See for instance tab labels in Project Settings. I think it would improve the GUI if there are shorter terms that carry a close enough meaning to replace the English terms. I've picked English words often for their shortness on for instance tabs. |
Translation updated |
Thanks! I'm going to merge now before anything else shows up. I'd appreciate if you took a look at how the Portuguese text fits on the various GUI elements at some point. |
Do you think it worth to implement the number translation by hand for all languages? Even for a specialized project like "num2words" it's a complex task and, quoting your words, "It supports all the |
I only need a tiny fraction of the functionality num2words has. The conversion of small integers to words is also a fairly simple piece of code. I really don't want to add external dependencies for minor features. Python dependencies are a nightmare to maintain as packages die all the time and are a big enough security risk that I don't want to more than the absolutely necessary. The three dependencies that I have now are so common that they are in practically all distros. In any case, since I need translations for the words "Synopsis", "Comment" and "Notes" for the Tokenizer class, I'm opting for a simple lookup dictionary with those words and the first hundred numbers in a JSON file. The people that add translations can also provide those I hope. They take a few minutes to make. I just made three of them. |
On another note. I'm tempted to take the What's the common practice on that? Do you know? |
What's the common practice on that? Do you know?
I think both are OK, the advantage of keeping the compiled files within the
project is if someone tries a `pip install git+ssh://...` it will require
the Qt5 installed in the system.
Em ter., 16 de fev. de 2021 às 19:41, Veronica Berglyd Olsen <
[email protected]> escreveu:
… On another note. I'm tempted to take the .qm files out of the repository.
I don't like tracking binary files, especially since they are not small
(relatively speaking). It's better to add them to the build pipeline and
put them into the distributed packages.
What's the common practice on that? Do you know?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#673 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAKC4OD5BQ3TN6MY3HWVYVTS7LYAXANCNFSM4XTR3EZA>
.
|
That's fine. Most people who do a |
This PR adds basic i18n support with localization (l10n) to portuguese (pt_BR).
The localization process is based on QTranslator and
self.tr
andQCoreApplication.translate
methods.To detect the translation the translated file must be added to
novelWriter.pro
underSOURCES
, and the commandpython setup.py qtlupdate
must be invoked to update the.ts
files.To add support for more languages, the translation file names must be added to
novelWriter.pro
underTRANSLATIONS
before thepython setup.py qtlupdate
command to be invoked. This creates the apropriate files in thelanguages
directory.To translate the language files the command
linguist nw/languages/nw_<lang>.ts
must be used.After the translation is done, the compilation of the
.ts
files is made bypython setup.py qtlrelease
command, which generate the compiled.qm
files for allTRANSLATIONS
.Fixes #93