Jump to content


Photo

Plugin translation scheme: including code


  • Please log in to reply
43 replies to this topic

#1 Simon Brown

Simon Brown
  • Members
  • 10,185 posts
  • Reputation:15

Posted 03 May 2010 - 01:47 AM

I have written a class which I plan to use to translate my plugins when released (and has already been used for ExtendBorder) and am publishing it here to be freely used by other plugin authors if they wish.

Language packs should be placed in Effects, include the language code in its name and have the extension .fxlang. More than one language pack can be used to help cover a single language. See the basic language pack attached for an example. When creating a language pack, make sure the character encoding is set to UTF-8.

The code (v1.1):

Hidden Content:


Language pack repository:
http://github.com/simonbrown/PluginTrans/blob/master/de%20and%20fr%20default.fxlang
If anyone wants to contribute, PM me your Github username. It might also be possible to suggest edits without being one, although i'm not sure.

Default language pack (v1.2)

Attached Files


Posted Image

#2 Rick Brewster

Rick Brewster

    Paint.NET Author and Developer

  • Administrators
  • 12,564 posts
  • LocationKirkland, WA
  • Reputation:120

Posted 03 May 2010 - 04:04 AM

if (plgLang == null) throw new ApplicationException("Call init plz. Kthx.");
Or you could just call Init() for them, and make Init() a private method.

The Paint.NET Blog: http://blog.getpaint.net/
Donations are always appreciated! http://www.getpaint.net/donate.html

Posted Image

#3 MadJik

MadJik
  • Members
  • 2,428 posts
  • LocationLille;France
  • Reputation:20

Posted 03 May 2010 - 04:15 AM

I don't know how but it would be great to use text file per language, so everyone could create his own translation if it doesn't exist and this task won't belong only to the plugin maker.

#4 pyrochild

pyrochild

    Plugin Author of the Year 2012

  • Administrators
  • 11,245 posts
  • LocationColorado
  • Reputation:131

Posted 03 May 2010 - 04:30 AM

Yeah, this would work much better with external files like Paint.NET already uses.

Posted Image
[I write plugins and stuff] [Follow my stupid brain on Twitter]

If you like a post, upvote it!


#5 VatherLokus

VatherLokus
  • Members
  • 53 posts
  • LocationThe Internet
  • Reputation:0

Posted 03 May 2010 - 09:07 AM

transTable["de:top"] = "Top"; and transTable["de:bottom"] = "Boden";
is more like
transTable["de:top"] = "Oben"; and transTable["de:bottom"] = "Unten";

(I'm a native German speacker ;-)


If it's possible to get better, good is not the Status Quo!


#6 Simon Brown

Simon Brown
  • Members
  • 10,185 posts
  • Reputation:15

Posted 03 May 2010 - 10:22 AM

if (plgLang == null) throw new ApplicationException("Call init plz. Kthx.");
Or you could just call Init() for them, and make Init() a private method.


The first time a plugin requests a translation might be in a separate thread.

Yeah, this would work much better with external files like Paint.NET already uses.


Good idea.
Posted Image

#7 Simon Brown

Simon Brown
  • Members
  • 10,185 posts
  • Reputation:15

Posted 03 May 2010 - 10:56 AM

Good idea.


The only problem is that it will have to be in a folder other than Paint.NET User Files. As when an effect's constructor is called, that information isn't available, and that might be a plugin's only chance to call Init.

I'm not sure whether it's best to store this in Paint.NET's Program Files folder, AppData, or somewhere else.
Posted Image

#8 Frontcannon

Frontcannon
  • Members
  • 2,302 posts
  • LocationNorth-Rhine Westphalia, Germany
  • Reputation:4

Posted 03 May 2010 - 12:16 PM

This is just getting better and better.

#9 pyrochild

pyrochild

    Plugin Author of the Year 2012

  • Administrators
  • 11,245 posts
  • LocationColorado
  • Reputation:131

Posted 03 May 2010 - 03:43 PM

The only problem is that it will have to be in a folder other than Paint.NET User Files. As when an effect's constructor is called, that information isn't available, and that might be a plugin's only chance to call Init.

I'm not sure whether it's best to store this in Paint.NET's Program Files folder, AppData, or somewhere else.

You're over-thinking it. There's nothing wrong with Paint.NET\Effects\, and rather than having a static class that has to be Initted, just make an instance class that has to be created in the Effect's ctor.

Posted Image
[I write plugins and stuff] [Follow my stupid brain on Twitter]

If you like a post, upvote it!


#10 Simon Brown

Simon Brown
  • Members
  • 10,185 posts
  • Reputation:15

Posted 03 May 2010 - 04:18 PM

You're over-thinking it. There's nothing wrong with Paint.NET\Effects\, and rather than having a static class that has to be Initted, just make an instance class that has to be created in the Effect's ctor.


Thanks, i'll do that. Update posted.
Posted Image

#11 Rick Brewster

Rick Brewster

    Paint.NET Author and Developer

  • Administrators
  • 12,564 posts
  • LocationKirkland, WA
  • Reputation:120

Posted 03 May 2010 - 05:39 PM

The first time a plugin requests a translation might be in a separate thread.

Then either use a mutex, or use a local variable to create the dictionary and then assign it to the static field as the very last step.
The Paint.NET Blog: http://blog.getpaint.net/
Donations are always appreciated! http://www.getpaint.net/donate.html

Posted Image

#12 Simon Brown

Simon Brown
  • Members
  • 10,185 posts
  • Reputation:15

Posted 03 May 2010 - 06:10 PM

Then either use a mutex, or use a local variable to create the dictionary and then assign it to the static field as the very last step.


It was because of:

For now I'd just use CultureInfo.CurrentUICulture. This isn't guaranteed to be correct since it has to be set per-thread, so pretty much only the UI thread will have the "correct" value. But, Effects are (currently) instantiated on the UI thread for this so you can at least access it in your constructor.


And at that time it was a static class, which it now isn't.

Although on second thought, obviously plugins will only need the translations in the UI thread.
Posted Image

#13 pyrochild

pyrochild

    Plugin Author of the Year 2012

  • Administrators
  • 11,245 posts
  • LocationColorado
  • Reputation:131

Posted 03 May 2010 - 06:13 PM

Ill def be using this at some point. Ive already had offers to translate my plugins into german and russian.

Posted Image
[I write plugins and stuff] [Follow my stupid brain on Twitter]

If you like a post, upvote it!


#14 MadJik

MadJik
  • Members
  • 2,428 posts
  • LocationLille;France
  • Reputation:20

Posted 03 May 2010 - 07:03 PM

Could you provide the source of ExtendBorder to see how to implement this? Or Some part of the code in the plugin side?

#15 Simon Brown

Simon Brown
  • Members
  • 10,185 posts
  • Reputation:15

Posted 03 May 2010 - 07:26 PM

I'll post the relevant parts.

(SNIP)

        PluginTrans pluginTrans;

        public ExtendBorderEffect()
            : base("Extend border", null, SubmenuNames.Distort, EffectFlags.Configurable)
        {
            pluginTrans = new PluginTrans();
        }

(SNIP)

        protected override ControlInfo OnCreateConfigUI(PropertyCollection props)
        {
            ControlInfo uiBuilder = base.OnCreateConfigUI(props);

            uiBuilder.SetPropertyControlType("Left", PropertyControlType.Slider);
            uiBuilder.SetPropertyControlType("Top", PropertyControlType.Slider);
            uiBuilder.SetPropertyControlType("Right", PropertyControlType.Slider);
            uiBuilder.SetPropertyControlType("Bottom", PropertyControlType.Slider);

            uiBuilder.SetPropertyControlValue("Left", ControlInfoPropertyNames.DisplayName, pluginTrans.GetTrans("left", "Left"));
            uiBuilder.SetPropertyControlValue("Top", ControlInfoPropertyNames.DisplayName, pluginTrans.GetTrans("top", "Top"));
            uiBuilder.SetPropertyControlValue("Right", ControlInfoPropertyNames.DisplayName, pluginTrans.GetTrans("right", "Right"));
            uiBuilder.SetPropertyControlValue("Bottom", ControlInfoPropertyNames.DisplayName, pluginTrans.GetTrans("bottom", "Bottom"));

            return uiBuilder;
        }

(SNIP)

Posted Image

#16 BoltBait

BoltBait
  • Administrators
  • 8,909 posts
  • LocationCalifornia, USA
  • Reputation:103

Posted 03 May 2010 - 07:54 PM

So, you still have to send your strings into the translator in English? MadJik might like it if he could program in French...

[/ignore me, I'm a trouble maker]
Click to play:
Posted ImagePosted ImagePosted ImagePosted ImagePosted Image
Download: BoltBait's Plugin Pack | CodeLab | More... and how about a Computer Dominos Game

#17 Frontcannon

Frontcannon
  • Members
  • 2,302 posts
  • LocationNorth-Rhine Westphalia, Germany
  • Reputation:4

Posted 03 May 2010 - 07:56 PM

Just revised the German parts of the pack.
It would be nice if the translator would know what entry he'd be dealing with, context is always important when translating words. 'forever' has alone 3 possible expressions in German..

Attached Files



#18 Simon Brown

Simon Brown
  • Members
  • 10,185 posts
  • Reputation:15

Posted 03 May 2010 - 08:08 PM

Language pack updated. Thanks, VatherLokus and Frontcannon.
Posted Image

#19 Simon Brown

Simon Brown
  • Members
  • 10,185 posts
  • Reputation:15

Posted 03 May 2010 - 08:25 PM

To translators: would you be okay using GitHub to edit the translation file? While it's intended to be used with a special program it's possible to edit the files online.
Posted Image

#20 Frontcannon

Frontcannon
  • Members
  • 2,302 posts
  • LocationNorth-Rhine Westphalia, Germany
  • Reputation:4

Posted 03 May 2010 - 09:04 PM

Looks alright, just signed up...