Skip to content

Commit f0b2625

Browse files
committed
Language Editor: new "3rd-party reference translation" tool
One of my biggest challenges is keeping PhotoDemon language files up-to-date after contributors drop out of the project. I never want to abandon people's localization work, but if I don't speak a language it's incredibly hard to know how to maintain a localization, especially given the number of features added to a typical PD release. I've already added an integrated online translation tool to the Language Editor, but that can only go so far - especially for menu text like "Copy". Is that a verb? A noun? If it *is* a verb, which tense should I use? I have no GD idea. So I've now added a helpful localization feature: an option to load a .po file from other software as an additional translation reference. When a phrase from PD matches a phrase from that software, PD can now notify you of the 3rd-party translation choice so you can make an informed decision. For a non-native speaker like me, this is a huge help when trying to figure out how to update a localization. To make this work, I basically wrote a quick-and-dirty .po parser, and it is indeed quick (and dirty). For example, GIMP ships with some 5,500+ phrases in a typical .po and PD will load and parse the full file in < 0.1s. Localized strings are stored in a homebrew hash table and it all works nicely. I have deliberately written this new tool so that you *cannot* bulk-copy translations from a reference file. Translations are typically copyright their original authors and I don't want to encourage anyone to steal or use them inappropriately. So the way PD's tool works is that the 3rd-party translations are only provided as a reference. To replace an existing PD translations with a 3rd-party one, you must manually review the translations one-by-one and interact with the dialog to swap the text. This is by design to try and make this feature helpful but ethically okay. I honestly don't know if anyone else uses PD's language editing tool (most localizers use text editors AFAIK) but as long as I'm writing these features for myself, I may as well make 'em available to others. With this, I think I have everything I need to get un-maintained localizations up-to-date for a 9.0 release.
1 parent de4b123 commit f0b2625

5 files changed

Lines changed: 601 additions & 200 deletions

File tree

App/PhotoDemon/Languages/README.md

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,96 @@
11
## About PhotoDemon localization
22

3-
Thank you for your interest in PhotoDemon's language support.
3+
Thank you for your interest in PhotoDemon localization.
44

5-
This README provides a quick overview of PhotoDemon's localization process. Importantly, it provides critical instructions to prevent you from losing any updates you make to PhotoDemon's language files.
5+
This README provides a quick overview of PhotoDemon's localization process. Importantly, there are **critical instructions** you must follow to avoid losing changes to these language files.
66

7-
Please read this entire document before editing any files in this folder.
7+
Please read this entire document before editing PhotoDemon language files.
88

99
### Quick overview
1010

11-
The XML files in this folder (`/App/PhotoDemon/Languages`) are PhotoDemon's "official" language files. They are included in all PhotoDemon downloads.
11+
The XML files in this folder (`/App/PhotoDemon/Languages`) are PhotoDemon's "official" language files. They ship with all PhotoDemon downloads.
1212

13-
When PhotoDemon applies an automatic update, these files will be replaced with newer versions from the PhotoDemon update server. For nightly builds in particular, language files are frequently updated, so this replacement process could happen at any time.
13+
When PhotoDemon self-updates, these XML files are automatically replaced with newer versions from the update server. For nightly builds in particular, language files are frequently updated, so this replacement process could happen at any time.
1414

15-
Because these language files can be replaced at any time, you **MUST NOT** edit them directly.
15+
Because the language files in this folder can be replaced at any time, **you MUST NOT edit them directly**.
1616

17-
Instead, modified language files must be saved to the `/Data/Languages` folder. The `/App` subfolder is reserved for PhotoDemon itself, but the `/Data` subfolder is your user data folder. Files in the `/Data` folder will never be erased by PhotoDemon updates.
17+
Instead, any modified language files should be saved to the `/Data/Languages` folder. The `/App` subfolder is reserved for PhotoDemon itself, but the `/Data` subfolder is your user data folder. Files in the `/Data` folder will not be erased by PhotoDemon updates.
1818

19-
So please, please, please remember to place any modified language files in the `/Data/Languages` folder, **not** the `/App/PhotoDemon/Languages` folder.
19+
So please, please, please remember to place any modified language files in the `/Data/Languages` folder, **not** this `/App/PhotoDemon/Languages` folder.
2020

21-
### Editing an existing language file
21+
### Editing an existing language file in any text editor
2222

23-
Editing an existing language file is easy!
23+
Editing existing language files is easy.
24+
25+
**Short version:**
26+
27+
PhotoDemon's language files are plain-text XML-like files. You can edit them in any text editor. After making changes, send the updated file to me and I will add it to PhotoDemon!
28+
29+
**Long version:**
2430

2531
1) Copy the language file you want to edit into the `/Data/Languages` folder, and modify its filename to something like `German_new.xml`.
26-
2) Open the language file in any text editor. Many translators use the free Notepad++ app: https://notepad-plus-plus.org/
27-
3) Inside the language file, you will notice a few tags at the top of the file. These tags have names like `<langid>` or `<author>`.
28-
4a) Ensure the `<langid>` matches the two-letter ISO language code (https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) and two-letter ISO country code (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) that you want to provide. PhotoDemon uses these codes to auto-suggest languages to new users, by matching these codes to the language and country code of each user's PC.
29-
4b) (Optional) You can also modify the language version (to ideally match the PhotoDemon version you are working on), language status (e.g. "complete" or "in-progress"), and author tags, as relevant.
30-
5) All phrases in the program are stored as `<original>` and `<translation>` pairs. You *must not* modify any text inside `<original></original>` tags. PhotoDemon requires these tags to precisely match on-screen interface elements - that's how it locates specific translations inside each file.
32+
2) Open the language file in any text editor. For beginners, I recommend the free Notepad++ app: https://notepad-plus-plus.org/
33+
3) Inside the language file, you will see a collection of tags. Tags are special text enclosed by angle brackets, with names like `<langid>` or `<author>`. Do not edit text within < and > characters. Tag names are used by PhotoDemon to locate translation data. Only translate text *between* tags - for example, if you see `<translation>text goes here</translation>` you can freely edit the `text goes here` portion.
34+
4a) Ensure the `<langid>` text at the top of the file matches the two-letter ISO language code (https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) and two-letter ISO country code (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) are accurate. PhotoDemon uses these codes to auto-suggest languages to new users (by matching the codes to the language and country code of a user's PC).
35+
4b) (Optional) You can also modify the language version to match the PhotoDemon version you are working on, and the language status (e.g. "complete" or "in-progress") and author tags to reflect their current state.
36+
5) All phrases in the program are stored as `<original>` and `<translation>` pairs. You *must not* modify any text inside `<original></original>` tags. PhotoDemon requires these tags to precisely match on-screen interface elements.
3137
6) You can freely modify any text between `<translation>` and `</translation>` tags. Empty tags (e.g. translation tags with no text between them) have not yet been translated. This is common for newly added features. You can use this to quickly locate text that needs to be translated, by searching for `<translation></translation>`.
32-
7) Where possible, PhotoDemon tries to match naming conventions with other popular photo editors, like Adobe Photoshop or GIMP. If a menu command in PhotoDemon does not make sense, you might check what text GIMP uses for their corresponding feature: https://gitlab.gnome.org/GNOME/gimp/-/tree/master/po (click on any language to see the GIMP translations for that language). I must also request that you *do not* blindly copy text from other software's translations. I provide the GIMP link only as a reference for comparison on challenging phrases, *not* as a way to steal their translation work.
38+
7) Where possible, PhotoDemon tries to use similar naming conventions to other popular photo editors, like Adobe Photoshop and GIMP. If a menu command in PhotoDemon does not make sense, you might see what text Photoshop or GIMP uses for their corresponding feature. (Later on, this document will describe an automated way to do this.)
3339
8) Sometimes, PhotoDemon needs to insert dynamic text at run-time. This is usually a number or percent, like `"Step 1 of 3"`. Dynamic text is flagged in translations using a % prefix, so the example phrase `"Step 1 of 3"` would appear as `<original>Step %1 of %2</original>` in a PhotoDemon language file. In your translation, place the same `%1` and `%2` markers in your translation wherever they make sense.
3440
9) When you are satisfied with your changes, save your work and contact me. Filing a pull request or new issue on GitHub and attaching your updated file is the fastest way to get your changes merged into the main application: https://github.com/tannerhelland/PhotoDemon . If you are afraid of GitHub, alternate means of contacting me are available here: https://photodemon.org/about/
3541

3642
### Starting a new language file
3743

38-
Starting a new PhotoDemon language file is exactly the same as editing an existing one. The only difference is that instead of copying an existing language file into the `/Data/Languages` folder, you will instead copy PhotoDemon's master English text file from `/App/PhotoDemon/Languages/Master/MASTER.xml` into the `/Data/Languages` folder. Rename the file with an appropriate language name, then follow the steps given in `Editing an existing PhotoDemon language file`, above.
44+
Starting a new PhotoDemon language file is exactly the same as editing an existing one. The only difference is that instead of copying an existing language file into the `/Data/Languages` folder, you will instead copy PhotoDemon's master English text file from `/App/PhotoDemon/Languages/Master/MASTER.xml` to the `/Data/Languages` folder. Rename the file with an appropriate language name, then follow the steps given above in `Editing an existing PhotoDemon language file`.
3945

40-
### PhotoDemon's built-in Tools > Language Editor menu
46+
### Using PhotoDemon's built-in Tools > Language Editor menu
4147

4248
Some translators prefer to use PhotoDemon's built-in `Tools > Language editor` tool. It can simplify the language editing process, especially for beginners.
4349

44-
PhotoDemon's Language Editor tool is largely self-explanatory, but one item deserves extra explanation. On the first page of the editor, there is a box titled `(optional) free DeepL.com API key for translation suggestions`.
50+
PhotoDemon's Language Editor tool is largely self-explanatory, but two items deserve extra explanation.
51+
52+
#### Automatic translation suggestions (via the online DeepL service)
4553

46-
DeepL.com (https://www.deepl.com/translator) is a free, high-quality translation service. It is not connected to or affiliated with PhotoDemon in any way, but PhotoDemon's Language Editor can interface with DeepL.com to automatically suggest translations for you. This is especially helpful for longer phrases, like error messages, which can be tedious to translate manually.
54+
On the first page of the editor, there is a box titled `(optional) free DeepL.com API key for translation suggestions`.
4755

48-
Like most online services, DeepL requires you to set up a free user account before using their translation service. As of June 2022, the "Free" button at this link is the fastest way to setup a new, free account:
56+
DeepL.com (https://www.deepl.com/translator) is a free, high-quality translation service. DeepL is not connected to or affiliated with PhotoDemon in any way, but PhotoDemon's Language Editor can interface with DeepL.com to automatically suggest translations for you. This is especially helpful for longer phrases, like error messages, which can be tedious to translate manually.
57+
58+
Like most online services, DeepL requires you to set up a free user account before using their translation service. As of June 2022, the "Free" button at this link is the fastest way to setup a new account:
4959

5060
https://www.deepl.com/pro-api?cta=header-pro-api/
5161

52-
After setting up an account, you will be provided with a unique API key. Simply copy and paste that key into the matching box in PhotoDemon's Language Editor, and PhotoDemon can now auto-suggest translations for you. PhotoDemon will also save the pasted API key to your user preferences file, so you only need to enter it once.
62+
After setting up an account, you will receive a unique API key. Simply copy and paste that key into the matching box in PhotoDemon's Language Editor, and PhotoDemon can now auto-suggest translations for you. PhotoDemon will also save the pasted API key to your user preferences file, so you do not need to enter it again.
63+
64+
Again, this feature **is not required** to edit PhotoDemon translations. It is simply provided as a convenience for those who want it. I initially added it to help me update language files that no longer have active contributors, and because I use it frequently I wanted to share it with others.
65+
66+
If other automated translation services are more appropriate for your language, please contact me and I'll see if I can add them to the tool as well.
67+
68+
#### Comparing translations to other open-source software
5369

54-
Again, this feature **is not required** to edit PhotoDemon translations. It is simply provided as a convenience for those who want it. I initially added it to help me update language files that no longer have active contributors, and because I use it so frequently I thought it might also be useful to others. If other automated translation services are more appropriate for your language, please contact me and I'll see if I can add them to the tool as well.
70+
Where possible, PhotoDemon tries to use the same terminology as other popular photo editors. This reduces the learning curve for new users and makes it easier to switch between PhotoDemon and other software.
71+
72+
To help achieve this, the first page of PhotoDemon's Language Editor provides a box titled `(optional) 3rd-party language file (.po) to compare`. Click the `...` button to select a language file from any other software. For example, GIMP's language files are freely downloadable from this link:
73+
74+
https://gitlab.gnome.org/GNOME/gimp/-/tree/master/po
75+
76+
If you provide a translation file from another app, PhotoDemon will also display that app's translations on the translation panel (when available). This is especially helpful for common terms like menu and tool names.
77+
78+
While this feature is very helpful, I must request that you *do not* blindly copy text from other software's translations. These translations are typically copyright by their original authors and should be used as a reference only. PhotoDemon's Language Editor will not allow you to bulk-copy these translations, by design. In particular, I provide the GIMP link only as a helpful reference for challenging phrases, *not* as a way to steal anyone else's translation work.
79+
80+
Again, note that this feature is 100% optional and you do not need to use it to translate PhotoDemon text. It only exists as an extra help for those who want it.
5581

5682
### Conclusion
5783

58-
Thank you again for helping me improve PhotoDemon's language files. If you have any other questions, please contact me directly. My contact info is available here:
84+
Thank you again for helping me improve PhotoDemon's language files. If you have any other questions, please contact me. My contact info is available here:
5985

6086
http://photodemon.org/about/contact/
6187

88+
I am very excited to merge your work into the project!
89+
6290
Kind regards,
91+
6392
Tanner Helland
93+
6494
(PhotoDemon developer)
6595

6696
Last modified: 28 June 2022

Classes/pdAutoLocalize.cls

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ Private m_ServiceAvailable As Boolean
6666
'The user needs to supply an API key for the target translation service; without this, the class WILL NOT WORK
6767
Private m_apiKey As String
6868

69+
Public Function GetAPIKey() As String
70+
GetAPIKey = m_apiKey
71+
End Function
72+
6973
Public Sub SetAPIKey(ByRef srcKey As String)
7074
m_apiKey = srcKey
7175
End Sub

Classes/pdStringHash.cls

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ Attribute VB_Exposed = False
1515
'Fast String-based collection, using hash-table + separate chaining (linked-list) for collisions
1616
'Copyright 2022-2022 by Tanner Helland
1717
'Created: 07/March/22
18-
'Last updated: 21/March/22
19-
'Last update: wrap up initial build, including official integration into pdTranslate
18+
'Last updated: 30/June/22
19+
'Last update: fix overflow table bug when re-adding the same key multiple times
2020
'
2121
'PhotoDemon's run-time localization engine has to manage a ton of strings. Historically, we've just
2222
' pulled strings on-demand from the base XML string. This is very fast (especially since localization
@@ -49,6 +49,7 @@ Attribute VB_Exposed = False
4949
'***************************************************************************
5050

5151
Option Explicit
52+
Option Compare Binary
5253

5354
'Item entry in the table. Key and value are stored together, alongside a link to the next item in this chain.
5455
Private Type MergedEntry
@@ -141,7 +142,7 @@ Friend Function AddItem(ByRef srcKey As String, ByRef srcItem As String) As Bool
141142

142143
'Key already exists in the table. Overwrite it with the new value, then exit.
143144
If (m_overflowTable(idxTable).sKey = srcKey) Then
144-
m_hashTable(idxTable).sItem = srcItem
145+
m_overflowTable(idxTable).sItem = srcItem
145146
Exit Function
146147

147148
Else

0 commit comments

Comments
 (0)