From 5f65b8181780e53aa4bb69ae7090bcbb6fdf9873 Mon Sep 17 00:00:00 2001 From: Antoine Choppin Date: Fri, 15 Apr 2016 21:29:15 +0900 Subject: [PATCH 1/5] I18nalize UI and create initial Japanese translation --- .gitignore | 2 + TRANSLATION.md | 61 ++ kano_init_flow/kw_slideshow/main.py | 18 +- kano_init_flow/stages/audio_lab/main.py | 36 +- kano_init_flow/stages/blocks/main.py | 14 +- kano_init_flow/stages/bugs/main.py | 4 +- kano_init_flow/stages/desktop/main.py | 82 +-- kano_init_flow/stages/drag_and_drop/main.py | 8 +- kano_init_flow/stages/intro/main.py | 20 +- kano_init_flow/stages/light_lab/main.py | 18 +- kano_init_flow/stages/overscan/main.py | 18 +- kano_init_flow/stages/overscan_old/main.py | 14 +- kano_init_flow/stages/pi_audio/main.py | 4 +- kano_init_flow/stages/pi_complete/main.py | 2 +- kano_init_flow/stages/pi_hdmi/main.py | 2 +- kano_init_flow/stages/pi_keyboard/main.py | 2 +- kano_init_flow/stages/pi_wifi/main.py | 4 +- kano_init_flow/stages/quests/main.py | 22 +- kano_init_flow/stages/wardrobe/main.py | 6 +- kano_init_flow/stages/wifi/main.py | 44 +- po/Makefile | 36 ++ po/PYPOTFILES | 18 + po/ja.po | 668 ++++++++++++++++++++ 23 files changed, 944 insertions(+), 159 deletions(-) create mode 100644 TRANSLATION.md create mode 100644 po/Makefile create mode 100644 po/PYPOTFILES create mode 100644 po/ja.po diff --git a/.gitignore b/.gitignore index 3da575e..daf06b3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ *.pyc .DS_Store .* +.mo +po/messages.pot diff --git a/TRANSLATION.md b/TRANSLATION.md new file mode 100644 index 0000000..49c2801 --- /dev/null +++ b/TRANSLATION.md @@ -0,0 +1,61 @@ +# Translation + +Translation files are found in the `po/` directory. + +## i18n not released yet + +Kano OS is not fully i18n-aware and locales are not installed for end users, yet. You can translate this application, but as of now, users will still see the default English message strings. + +## How to add a new translation + +In this example, we're going to add a French translation: + + # install your target locale `fr_FR.utf8` with: + sudo dpkg-reconfigure locales + + cd po/ + # create messages.pot + make messages + + # create fr.po from messages.pot: + msginit -l fr_FR.utf8 + + # now use your favourite editor to translate fr.po + + # build locale files: + make + + cd .. + + # when testing, make sure LC_ALL is set to your locale e.g. + LC_ALL=fr_FR.utf8 + +## How to make sure your code is i18n-aware + +Add the gettext `_()` macro to all the user-visible message strings in your Python. List the Python source files that contain message strings in `PYPOTFILES`. + +If you added new message strings or made changes to existing ones, do `make messages` to keep the template file up-to-date. + +After that, merge the existing translations with `make update` and ask your translators to update their translations. + +## gettext explained (in 20 seconds) + +* User-visible strings in the source are marked with a macro of your choice. Usually, it's `_()`. +* `xgettext` extracts these message strings from your sources and puts them into a template file. +* This template file, usually named `messages.pot`, contains all user-visible strings of the project, but no translations. +* Translators use `msginit` to copy the template file into a new *portable object* file for their language (explained above). +* The translations are put into `.po`. It's a plain-text file format, you can use any text editor. +* More convenient, specialized `.po`-editors and web-based tools such as Pootle exist, as well. +* If your template file changes, use `msgmerge` to merge your existing translations with the new template, then re-translate the updated messages. Beware of `msgmerge`'s "fuzzy" matches. +* `msgfmt` converts a `.po` file into a binary *message object* file. +* You don't link these `.mo` files with your application binary. +* The `.mo` files are bundled alongside with your software as part of the distribution package. +* During installation, the `.mo` files are copied into the system's locale directory, usually `/usr/share/locale`. +* On startup, your application will look for the message object file that it needs for the current system locale. +* The locale even allows you to provide region-specific translations, e.g. "colour" for en_UK vs "color" for en_US. +* At runtime, all user-visible strings are being replaced with the translations. +* If no message object was found for the system locale, the original strings will be shown. + +## To-Do + +Pootle or Transifex integration. diff --git a/kano_init_flow/kw_slideshow/main.py b/kano_init_flow/kw_slideshow/main.py index 96336ec..00f38e4 100644 --- a/kano_init_flow/kw_slideshow/main.py +++ b/kano_init_flow/kw_slideshow/main.py @@ -31,19 +31,19 @@ def slide1(self): 678 ) image = Gtk.Image.new_from_pixbuf(pixbuf) - title1 = Gtk.Label("Get Started") + title1 = Gtk.Label(_("Get Started")) title1.get_style_context().add_class("title") - title2 = Gtk.Label("Apps") + title2 = Gtk.Label(_("Apps")) title2.get_style_context().add_class("title") - desc = Gtk.Label( + desc = Gtk.Label(_( "Create and play with\n" + "Kano's Apps to make and save your\n" + "own code masterpieces, from games\n" + "and minecraft world, to art and music pieces..." - ) + )) desc.get_style_context().add_class("description") - next_button = KanoButton("NEXT") + next_button = KanoButton(_("NEXT")) next_button.connect("clicked", self.slide2_wrapper) fixed.put(image, 0, 0) @@ -66,17 +66,17 @@ def slide2(self): 678 ) image = Gtk.Image.new_from_pixbuf(pixbuf) - title = Gtk.Label("Kano World") + title = Gtk.Label(_("Kano World")) title.get_style_context().add_class("title") - desc = Gtk.Label( + desc = Gtk.Label(_( "Show off and share your creations to friends\n" + "family and other Kano users on Kano World.\n\n" + "Why not check it out now by clicking on the\n" + "icon to see what people have made today." - ) + )) desc.get_style_context().add_class("description") - next_button = KanoButton("LET'S GO") + next_button = KanoButton(_("LET'S GO")) next_button.connect("clicked", Gtk.main_quit) fixed.put(image, 0, 0) diff --git a/kano_init_flow/stages/audio_lab/main.py b/kano_init_flow/stages/audio_lab/main.py index b747575..22b8422 100644 --- a/kano_init_flow/stages/audio_lab/main.py +++ b/kano_init_flow/stages/audio_lab/main.py @@ -85,7 +85,7 @@ def _setup_first_scene(self): Placement(0.95, 0.9) ) - copy = 'Press the TAB key to play a song!' + copy = _('Press the TAB key to play a song!') scene.add_widget( SpeechBubble(text=copy, source=SpeechBubble.BOTTOM, source_align=0.8, scale=scene.scale_factor), @@ -151,9 +151,9 @@ def _setup_help_jack(self, scene): Notebook( self, self.media_path('jack.png'), 1.0, 0.5, - 'Plug in the blue cable', - ['Check you\'ve plugged in the audio'], - [{'label': 'NEXT', + _('Plug in the blue cable'), + [_('Check you\'ve plugged in the audio')], + [{'label': _('NEXT'), 'callback': self.help_leds, 'color': 'green'}] ), @@ -168,11 +168,11 @@ def _setup_help_leds(self, scene): Notebook( self, self.media_path('troubleshooting-sound.png'), 0.5, 0.3, - 'Can you see the blue light?', - ['If the power plugs are connected correctly,', - 'you should see a blue light.'], - [{'label': 'YES', 'callback': self.remove_overlays, 'color': 'green'}, - {'label': 'NO', 'callback': self.help_power, 'color': 'red'}] + _('Can you see the blue light?'), + [_('If the power plugs are connected correctly,'), + _('you should see a blue light.')], + [{'label': _('YES'), 'callback': self.remove_overlays, 'color': 'green'}, + {'label': _('NO'), 'callback': self.help_power, 'color': 'red'}] ), Placement(0.5, 0.5, 0.0), Placement(0.5, 0.5, 0.0), @@ -182,16 +182,16 @@ def _setup_help_leds(self, scene): def _setup_help_power(self, scene): buttons = [{ - 'label': 'TRY AGAIN', + 'label': _('TRY AGAIN'), 'callback': self.remove_overlays, 'color': 'green'}, - {'label': 'SKIP', + {'label': _('SKIP'), 'callback': self._ctl.next_stage, 'color': 'grey'} ] if hdmi_supported: buttons.insert(1, { - 'label': 'USE TV SPEAKERS', + 'label': _('USE TV SPEAKERS'), 'callback': self._set_to_hdmi, 'color': 'blue' }) @@ -200,9 +200,9 @@ def _setup_help_power(self, scene): Notebook( self, self.media_path('power.png'), 0.8, 0.5, - 'No light? Check the GPIO', - ['The cable has to be connected to these', - 'pins exactly.'], + _('No light? Check the GPIO'), + [_('The cable has to be connected to these'), + _('pins exactly.')], buttons ), Placement(0.5, 0.5, 0.0), @@ -232,7 +232,7 @@ def __init__(self, stage, scene, yes_cb, no_cb): vbox = Gtk.VBox(False, 0) vbox.set_halign(Gtk.Align.CENTER) - question = Gtk.Label('Can you hear a sound?') + question = Gtk.Label(_('Can you hear a sound?')) question.set_line_wrap(True) question.set_justify(Gtk.Justification.CENTER) question.set_valign(Gtk.Align.CENTER) @@ -244,10 +244,10 @@ def __init__(self, stage, scene, yes_cb, no_cb): hbox.set_halign(Gtk.Align.CENTER) hbox.set_valign(Gtk.Align.CENTER) - yes = KanoButton('YES') + yes = KanoButton(_('YES')) yes.connect('clicked', cb_wrapper, yes_cb) - no = KanoButton('NO', color='red') + no = KanoButton(_('NO'), color='red') no.connect('clicked', cb_wrapper, no_cb) hbox.pack_start(yes, False, False, 0) diff --git a/kano_init_flow/stages/blocks/main.py b/kano_init_flow/stages/blocks/main.py index 43ff99d..3ec110e 100644 --- a/kano_init_flow/stages/blocks/main.py +++ b/kano_init_flow/stages/blocks/main.py @@ -78,8 +78,8 @@ def _setup_first_scene(self): scene = self._setup_base_temple_scene() copy = [ - 'Oh no, there\'s a boulder', - 'in the way!' + _('Oh no, there\'s a boulder'), + _('in the way!') ] scene.add_widget( SpeechBubble( @@ -112,10 +112,10 @@ def _setup_second_scene(self): scene = self._setup_base_temple_scene() copy = [ - 'But don\'t worry, you can', - 'use Kano blocks to create code', - 'to change what\'s around you.\n', - 'Looks like there\'s one over there!' + _('But don\'t worry, you can'), + _('use Kano blocks to create code'), + _('to change what\'s around you.\n'), + _('Looks like there\'s one over there!') ] scene.add_widget( SpeechBubble( @@ -230,7 +230,7 @@ def _setup_fifth_scene(self): scene.add_widget( SpeechBubble( - text="Awesome, now we can escape!", + text=_("Awesome, now we can escape!"), source=SpeechBubble.BOTTOM, source_align=0.5, scale=scene.scale_factor diff --git a/kano_init_flow/stages/bugs/main.py b/kano_init_flow/stages/bugs/main.py index 948b9ac..fcdefdd 100644 --- a/kano_init_flow/stages/bugs/main.py +++ b/kano_init_flow/stages/bugs/main.py @@ -70,10 +70,10 @@ def _setup_first_scene(self): def _place_judoka_into_scene(self, scene, happy=False): image = 'judoka-scared.png' - copy = "Oh no bugs!\nClick on them quick to remove them." + copy = _("Oh no bugs!\nClick on them quick to remove them.") if happy: image = 'judoka.png' - copy = 'Phew, thanks for cleaning up!' + copy = _('Phew, thanks for cleaning up!') scene.add_widget( Gtk.Image.new_from_file(self.media_path(image)), diff --git a/kano_init_flow/stages/desktop/main.py b/kano_init_flow/stages/desktop/main.py index c845cc0..fbec5b8 100644 --- a/kano_init_flow/stages/desktop/main.py +++ b/kano_init_flow/stages/desktop/main.py @@ -76,8 +76,8 @@ def _setup_first_scene(self): scene.add_widget( SpeechBubble( - text="We made it to the desktop!\n" + - "Click here to set up your profile", + text=_("We made it to the desktop!\n" + + "Click here to set up your profile"), source=SpeechBubble.TOP, source_align=0.0 ), @@ -130,10 +130,10 @@ def _setup_second_scene(self): scene.add_widget( SpeechBubble( - text="This is Kano World, where\n" - "you can code with cool people,\n" - "and get new apps.\n" - "Click to continue.", + text=_("This is Kano World, where\n" + + "you can code with cool people,\n" + + "and get new apps.\n" + + "Click to continue."), source=SpeechBubble.TOP, source_align=1.0 ), @@ -156,44 +156,44 @@ def _setup_third_scene(self): self._toolbar_icons = { "home": { - "text": "Click the Home button to\n" + - "return to the desktop.", + "text": _("Click the Home button to\n" + + "return to the desktop."), "position": [0, 100], "source_align": 0.2 }, "help": { - "text": "If you need Help,\n" + - "you can click here.", + "text": _("If you need Help,\n" + + "you can click here."), "position": [19, 100], "source_align": 0.5 }, "profile": { - "text": "Here's where you can\n" + - "sync your online Profile.", + "text": _("Here's where you can\n" + + "sync your online Profile."), "position": [38, 100], "source_align": 0.5 }, "wifi": { - "text": "You can change Internet\n" + - "settings here.", + "text": _("You can change Internet\n" + + "settings here."), "position": [75, 100], "source_align": 0.5 }, "updater": { - "text": "Want updates?\n" + - "Click on the Updater.", + "text": _("Want updates?\n" + + "Click on the Updater."), "position": [150, 100], "source_align": 0.5 }, "settings": { - "text": "And this is where you can change\n" + - "all the system Settings.", + "text": _("And this is where you can change\n" + + "all the system Settings."), "position": [55, 100], "source_align": 0.7 }, "audio": { - "text": "Control the volume\n" + - "of the system.", + "text": _("Control the volume\n" + + "of the system."), "position": [150, 100], "source_align": 1.0 } @@ -214,9 +214,9 @@ def _setup_third_scene(self): speechbubble_fixed.set_size_request(500, 400) speechbubble_fixed.put( SpeechBubble( - text='This is your Taskbar!\n' + + text=_('This is your Taskbar!\n' + 'Click on the different widgets to find\n' + - 'out more about what they do.', + 'out more about what they do.'), # 'Use its buttons to change settings,\n' + # 'get updates, and more.', source=SpeechBubble.BOTTOM @@ -273,63 +273,63 @@ def _setup_fourth_scene(self): self._desktop_icons = { "snake": { - "text": "Customize your own Snake game,\n" + - "and share special gameboards.", + "text": _("Customize your own Snake game,\n" + + "and share special gameboards."), "position": [0, 340], "source_align": 0.1 }, "pong": { - "text": "You can make this classic game yourself,\n" + - "with new rules, cheats, and powers.", + "text": _("You can make this classic game yourself,\n" + + "with new rules, cheats, and powers."), "position": [0, 340], "source_align": 0.42 }, "minecraft": { - "text": "Normal people play Minecraft.\n" + - "On Kano, you can hack the game with code.", + "text": _("Normal people play Minecraft.\n" + + "On Kano, you can hack the game with code."), "position": [95, 340], "source_align": 0.5 }, "terminal-quest": { - "text": "The Terminal talks to the computer's\n" + - "brain directly. Use its powers to go on a quest.", + "text": _("The Terminal talks to the computer's\n" + + "brain directly. Use its powers to go on a quest."), "position": [0, 210], "source_align": 0.37 }, "music": { - "text": "You can make sounds, beats, loops,\n" + - "and songs on Kano.", + "text": _("You can make sounds, beats, loops,\n" + + "and songs on Kano."), "position": [290, 340], "source_align": 0.5 }, "art": { - "text": "Ever drawn or painted?\n" + - "You can create incredible artworks with code.", + "text": _("Ever drawn or painted?\n" + + "You can create incredible artworks with code."), "position": [0, 210], "source_align": 0.07 }, "internet": { - "text": "You can browse the web.", + "text": _("You can browse the web."), "position": [490, 360], "source_align": 0.5 }, "scratch": { - "text": "You can play with code blocks.", + "text": _("You can play with code blocks."), "position": [167, 210], "source_align": 0.5 }, "home": { - "text": "Look at your files and folders here.", + "text": _("Look at your files and folders here."), "position": [550, 360], "source_align": 1.0 }, "apps": { - "text": "Find even more apps here.", + "text": _("Find even more apps here."), "position": [620, 360], "source_align": 0.5 }, "video": { - "text": "YouTube", + "text": _("YouTube"), "position": [435, 250], "source_align": 0.5 } @@ -377,10 +377,10 @@ def _setup_fourth_scene(self): speechbubble_fixed.set_size_request(1024, 720) speechbubble_fixed.put( SpeechBubble( - text='These are your Apps!\n' + + text=_('These are your Apps!\n' + 'You can make games, songs,\n' + 'artworks and more,\n' + - 'then share them to World.', + 'then share them to World.'), source=SpeechBubble.BOTTOM ), 300, 100 diff --git a/kano_init_flow/stages/drag_and_drop/main.py b/kano_init_flow/stages/drag_and_drop/main.py index f03d198..dc072ca 100644 --- a/kano_init_flow/stages/drag_and_drop/main.py +++ b/kano_init_flow/stages/drag_and_drop/main.py @@ -45,7 +45,7 @@ def _setup_first_scene(self): judoka = Gtk.Image.new_from_file(self.media_path('cliff-judoka.png')) judoka = scene.scale_image_to_scene(judoka, 0.92, 0.96) speechbubble = SpeechBubble( - text='Click on me,\nhold down the mouse button,\nand drag me across!', + text=_('Click on me,\nhold down the mouse button,\nand drag me across!'), source=SpeechBubble.LEFT, source_align=0.0, scale=scene.scale_factor @@ -92,8 +92,8 @@ def _setup_first_scene(self): def _scene_1_hint(self, speechbubble): speechbubble.set_text( - 'Pick me up with the cursor\nand hold the left button down\n' + - 'while dragging me over.' + _('Pick me up with the cursor\nand hold the left button down\n' + + 'while dragging me over.') ) def _setup_second_scene(self): @@ -102,7 +102,7 @@ def _setup_second_scene(self): self.media_path('cliff-file-1920x1080.png')) scene.add_widget( - SpeechBubble(text='Thanks!', source=SpeechBubble.BOTTOM, + SpeechBubble(text=_('Thanks!'), source=SpeechBubble.BOTTOM, scale=scene.scale_factor), Placement(0.845, 0.08), Placement(0.895, 0.1) diff --git a/kano_init_flow/stages/intro/main.py b/kano_init_flow/stages/intro/main.py index 883f6cc..af0d137 100644 --- a/kano_init_flow/stages/intro/main.py +++ b/kano_init_flow/stages/intro/main.py @@ -77,7 +77,7 @@ def _setup_first_scene(self): # move_label.set_margin_right(30) # Create the keyboard and pack it before putting it in the - grab_label = Gtk.Label("Click NEXT to start") + grab_label = Gtk.Label(_("Click NEXT to start")) grab_label.get_style_context().add_class("big_intro_label") keyboard_gif = Gtk.Image.new_from_file( @@ -119,10 +119,10 @@ def _setup_second_scene(self): common_media_path('blueprint-bg-16-9.png')) copy = [ - 'Well done! You brought your', - 'Kano to life! I\'m Judoka and I', - 'will be your guide through the', - 'world of Kano.' + _('Well done! You brought your'), + _('Kano to life! I\'m Judoka and I'), + _('will be your guide through the'), + _('world of Kano.') ] scene.add_widget( SpeechBubble( @@ -171,10 +171,10 @@ def _setup_third_scene(self): ) copy = [ - "Kano is a world where", - "anything is possible!", - "Judokas can make and play", - "using code powers." + _("Kano is a world where"), + _("anything is possible!"), + _("Judokas can make and play"), + _("using code powers.") ] scene.add_widget( SpeechBubble( @@ -216,7 +216,7 @@ def _setup_fourth_scene(self): Placement(0.18, 0.60, 0), ) - copy = ['Ready to go? Jump on in!'] + copy = [_('Ready to go? Jump on in!')] scene.add_widget( SpeechBubble( text='\n'.join(copy), diff --git a/kano_init_flow/stages/light_lab/main.py b/kano_init_flow/stages/light_lab/main.py index 1a86f43..c56418f 100644 --- a/kano_init_flow/stages/light_lab/main.py +++ b/kano_init_flow/stages/light_lab/main.py @@ -59,8 +59,8 @@ def _setup_first_scene(self): Placement(0.12, 0.9) ) - copy = 'Now let\'s check the lights work!\n\n' + \ - 'Press the ON button to light up.' + copy = _('Now let\'s check the lights work!\n\n' + \ + 'Press the ON button to light up.') scene.add_widget( SpeechBubble(text=copy, source=SpeechBubble.BOTTOM, source_align=0.2, scale=scene.scale_factor), @@ -121,10 +121,10 @@ def _setup_help_power(self): Notebook( self, self.media_path('power.png'), 0.8, 0.5, - 'No light? Check the GPIO', - ['The cable has to be connected to these', - 'pins exactly.'], - [{'label': 'GOT IT', 'callback': self.remove_overlay, 'color': 'green'}] + _('No light? Check the GPIO'), + [_('The cable has to be connected to these'), + _('pins exactly.')], + [{'label': _('GOT IT'), 'callback': self.remove_overlay, 'color': 'green'}] ), Placement(0.5, 0.5, 0.0), Placement(0.45, 0.5, 0.0), @@ -149,7 +149,7 @@ def __init__(self, stage, scene, yes_cb, no_cb): vbox.set_halign(Gtk.Align.CENTER) # vbox.set_valign(Gtk.Align.CENTER) - question = Gtk.Label('Can you see the lights?') + question = Gtk.Label(_('Can you see the lights?')) question.set_line_wrap(True) question.set_justify(Gtk.Justification.CENTER) question.set_valign(Gtk.Align.CENTER) @@ -161,10 +161,10 @@ def __init__(self, stage, scene, yes_cb, no_cb): hbox.set_halign(Gtk.Align.CENTER) hbox.set_valign(Gtk.Align.CENTER) - yes = KanoButton('YES') + yes = KanoButton(_('YES')) yes.connect('clicked', cb_wrapper, yes_cb) - no = KanoButton('NO', color='red') + no = KanoButton(_('NO'), color='red') no.connect('clicked', cb_wrapper, no_cb) hbox.pack_start(yes, False, False, 0) diff --git a/kano_init_flow/stages/overscan/main.py b/kano_init_flow/stages/overscan/main.py index 2951dc1..e376ca2 100644 --- a/kano_init_flow/stages/overscan/main.py +++ b/kano_init_flow/stages/overscan/main.py @@ -143,15 +143,15 @@ def __init__(self, stage, next_cb): vbox.set_margin_left(10) vbox.set_margin_right(10) - heading = Gtk.Label('Screen machine') + heading = Gtk.Label(_('Screen machine')) add_class(heading, 'heading') add_class(heading, 'notebook-heading') body_lines = [ - "Use the up and down arrows on the", - "keyboard to adjust the picture until the", - "screen pushing machine lines up with the", - "edges of your TV." + _("Use the up and down arrows on the"), + _("keyboard to adjust the picture until the"), + _("screen pushing machine lines up with the"), + _("edges of your TV.") ] body_widgets = [] for line in body_lines: @@ -164,9 +164,9 @@ def __init__(self, stage, next_cb): # TODO: info legend_data = [ - {'icon': 'up-icon.png', 'desc': 'on your keyboard to increase'}, - {'icon': 'down-icon.png', 'desc': 'on your keyboard to decrease'}, - {'icon': 'ok-icon.png', 'desc': 'click the button to confirm'} + {'icon': 'up-icon.png', 'desc': _('on your keyboard to increase')}, + {'icon': 'down-icon.png', 'desc': _('on your keyboard to decrease')}, + {'icon': 'ok-icon.png', 'desc': _('click the button to confirm')} ] legend_widgets = [] for l in legend_data: @@ -180,7 +180,7 @@ def __init__(self, stage, next_cb): legend_widgets.append(legend) - button = KanoButton('GO') + button = KanoButton(_('GO')) button.connect('clicked', cb_wrapper, next_cb) # Pack heading diff --git a/kano_init_flow/stages/overscan_old/main.py b/kano_init_flow/stages/overscan_old/main.py index dd64634..bf16ef2 100644 --- a/kano_init_flow/stages/overscan_old/main.py +++ b/kano_init_flow/stages/overscan_old/main.py @@ -132,17 +132,17 @@ def __init__(self, stage, yes_cb, no_cb): add_class(heading, 'notebook-heading') box.pack_start(heading, False, False, 0) - heading = Gtk.Label('Are the white lines touching the edges?') + heading = Gtk.Label(_('Are the white lines touching the edges?')) heading.set_margin_bottom(35) add_class(heading, 'notebook-text') box.pack_start(heading, False, False, 0) buttons = Gtk.HBox(halign=Gtk.Align.CENTER) buttons.set_margin_bottom(25) - yes = KanoButton('YES', color='green') + yes = KanoButton(_('YES'), color='green') yes.connect('clicked', cb_wrapper, yes_cb) buttons.pack_start(yes, False, False, 0) - no = KanoButton('NO', color='red') + no = KanoButton(_('NO'), color='red') no.connect('clicked', cb_wrapper, no_cb) buttons.pack_start(no, False, False, 10) @@ -161,25 +161,25 @@ def __init__(self, stage, overscan_ctl, next_cb): box.pack_start(head_img, False, False, 0) - heading = Gtk.Label('Use UP and DOWN keys') + heading = Gtk.Label(_('Use UP and DOWN keys')) heading.set_margin_top(25) heading.set_margin_bottom(25) add_class(heading, 'notebook-heading') box.pack_start(heading, False, False, 0) - text1 = Gtk.Label('Stretch or shrink your screen, until the white lines') + text1 = Gtk.Label(_('Stretch or shrink your screen, until the white lines')) text1.set_margin_bottom(5) add_class(text1, 'notebook-text') box.pack_start(text1, False, False, 0) - text2 = Gtk.Label('are lined up with the edges') + text2 = Gtk.Label(_('are lined up with the edges')) text2.set_margin_bottom(25) add_class(text2, 'notebook-text') box.pack_start(text2, False, False, 0) buttons = Gtk.HBox(halign=Gtk.Align.CENTER) buttons.set_margin_bottom(25) - done = KanoButton('DONE', color='green') + done = KanoButton(_('DONE'), color='green') buttons.pack_start(done, False, False, 0) done.connect('clicked', cb_wrapper, next_cb) diff --git a/kano_init_flow/stages/pi_audio/main.py b/kano_init_flow/stages/pi_audio/main.py index 1368059..e4a7c07 100644 --- a/kano_init_flow/stages/pi_audio/main.py +++ b/kano_init_flow/stages/pi_audio/main.py @@ -81,7 +81,7 @@ def _setup_first_scene(self): ) sb = SpeechBubble( - 'Let\'s make sure our sound\nis loud and clear.', + _('Let\'s make sure our sound\nis loud and clear.'), source=SpeechBubble.BOTTOM, scale=scene.scale_factor ) @@ -97,4 +97,4 @@ def _setup_first_scene(self): return scene def _show_hint(self, sb): - sb.set_text('Click on the blue cable\nto continue.') + sb.set_text(_('Click on the blue cable\nto continue.')) diff --git a/kano_init_flow/stages/pi_complete/main.py b/kano_init_flow/stages/pi_complete/main.py index 634a339..bae5e19 100644 --- a/kano_init_flow/stages/pi_complete/main.py +++ b/kano_init_flow/stages/pi_complete/main.py @@ -50,7 +50,7 @@ def _setup_first_scene(self): scene.add_widget( SpeechBubble( - text='You set it up! Now it\'s time to play.', + text=_('You set it up! Now it\'s time to play.'), source=SpeechBubble.BOTTOM, scale=scene.scale_factor ), diff --git a/kano_init_flow/stages/pi_hdmi/main.py b/kano_init_flow/stages/pi_hdmi/main.py index 762592b..0d2c9d4 100644 --- a/kano_init_flow/stages/pi_hdmi/main.py +++ b/kano_init_flow/stages/pi_hdmi/main.py @@ -82,7 +82,7 @@ def _setup_first_scene(self): ) scene.add_widget( - SpeechBubble('Let\'s set up your display!', + SpeechBubble(_('Let\'s set up your display!'), source=SpeechBubble.BOTTOM, scale=scene.scale_factor), Placement(0.49, 0.2), diff --git a/kano_init_flow/stages/pi_keyboard/main.py b/kano_init_flow/stages/pi_keyboard/main.py index 2c6e0ae..9898178 100644 --- a/kano_init_flow/stages/pi_keyboard/main.py +++ b/kano_init_flow/stages/pi_keyboard/main.py @@ -82,7 +82,7 @@ def _setup_first_scene(self): ) scene.add_widget( - SpeechBubble('Time to set up the keyboard!', + SpeechBubble(_('Time to set up the keyboard!'), source=SpeechBubble.BOTTOM, scale=scene.scale_factor), Placement(0.49, 0.2), diff --git a/kano_init_flow/stages/pi_wifi/main.py b/kano_init_flow/stages/pi_wifi/main.py index 6c1335a..4e85001 100644 --- a/kano_init_flow/stages/pi_wifi/main.py +++ b/kano_init_flow/stages/pi_wifi/main.py @@ -87,7 +87,7 @@ def _setup_first_scene(self): Placement(0.5, 0.5) ) - sb = SpeechBubble('Let\'s set up WiFi', + sb = SpeechBubble(_('Let\'s set up WiFi'), source=SpeechBubble.BOTTOM, scale=scene.scale_factor) scene.add_widget( @@ -102,4 +102,4 @@ def _setup_first_scene(self): return scene def _show_hint(self, sb): - sb.set_text('Click on the green dongle\nto continue.') + sb.set_text(_('Click on the green dongle\nto continue.')) diff --git a/kano_init_flow/stages/quests/main.py b/kano_init_flow/stages/quests/main.py index 5d526c5..77cfa56 100644 --- a/kano_init_flow/stages/quests/main.py +++ b/kano_init_flow/stages/quests/main.py @@ -73,7 +73,7 @@ def _setup_first_scene(self): scene.add_widget( SpeechBubble( - text="You did it! Now you know how\nto control your computer.\nThis was the first of many\nquests you'll find in the\nWorld of Kano", + text=_("You did it! Now you know how\nto control your computer.\nThis was the first of many\nquests you'll find in the\nWorld of Kano"), source=SpeechBubble.RIGHT, scale=scene.scale_factor ), @@ -122,9 +122,9 @@ def _setup_second_scene(self): ) copy = [ - 'Click on my scroll to find', - 'out more and start the', - 'next adventure...' + _('Click on my scroll to find'), + _('out more and start the'), + _('next adventure...') ] scene.add_widget( SpeechBubble( @@ -182,9 +182,9 @@ def __init__(self, stage): def first_scroll(self): self._clear() copy = [ - "Quests are a series of tasks that you", - "can complete on your Kano to get", - "great rewards." + _("Quests are a series of tasks that you"), + _("can complete on your Kano to get"), + _("great rewards.") ] text_widgets = self._get_text_widgets(copy) @@ -213,8 +213,8 @@ def second_scroll(self): ticks = Gtk.Image.new_from_file(self._stage.media_path('ticks.png')) copy = [ - "Complete all of the ticks in a", - "quest to unlock rewards." + _("Complete all of the ticks in a"), + _("quest to unlock rewards.") ] text_widgets = self._get_text_widgets(copy) @@ -243,13 +243,13 @@ def second_scroll(self): def third_scroll(self): self._clear() - heading = Gtk.Label('New quest') + heading = Gtk.Label(_('New quest')) add_class(heading, 'scroll-heading') world = Gtk.Image.new_from_file(self._stage.media_path('world.png')) copy = [ - "Journey to Kano World", + _("Journey to Kano World"), ] text_widgets = self._get_text_widgets(copy) diff --git a/kano_init_flow/stages/wardrobe/main.py b/kano_init_flow/stages/wardrobe/main.py index 116a850..e79743b 100644 --- a/kano_init_flow/stages/wardrobe/main.py +++ b/kano_init_flow/stages/wardrobe/main.py @@ -49,7 +49,7 @@ def _setup_first_scene(self): scene.add_widget( SpeechBubble( - text="Let's dress up your\ncharacter!", + text=_("Let's dress up your\ncharacter!"), source=SpeechBubble.BOTTOM, scale=scene.scale_factor ), @@ -128,7 +128,7 @@ def _setup_second_scene(self): scene.add_widget( SpeechBubble( - text="You look amazing!", + text=_("You look amazing!"), source=SpeechBubble.BOTTOM, scale=scene.scale_factor ), @@ -164,7 +164,7 @@ def __init__(self, cb): self.add(vbox) vbox.pack_start(self.char_edit, False, False, 0) - button = KanoButton("OK") + button = KanoButton(_("OK")) button.connect("clicked", self.close_window) button.pack_and_align() diff --git a/kano_init_flow/stages/wifi/main.py b/kano_init_flow/stages/wifi/main.py index 72e5751..7fc151e 100644 --- a/kano_init_flow/stages/wifi/main.py +++ b/kano_init_flow/stages/wifi/main.py @@ -88,10 +88,10 @@ def _setup_first_scene(self): ) copy = [ - 'Let\'s connect to the web!', + _('Let\'s connect to the web!'), '', - 'Get started by clicking', - 'the WiFi console!' + _('Get started by clicking'), + _('the WiFi console!') ] sb = SpeechBubble(text='\n'.join(copy), source=SpeechBubble.BOTTOM, scale=scene.scale_factor) @@ -195,8 +195,8 @@ def _setup_disconnected_scene(self): ) copy = [ - 'Oh no, the connection failed!', - 'But we can still play.', + _('Oh no, the connection failed!'), + _('But we can still play.'), ] scene.add_widget( SpeechBubble(text='\n'.join(copy), source=SpeechBubble.BOTTOM, @@ -297,8 +297,8 @@ def troubleshoot_option(self): def troubleshoot_ethernet(self): self._clear() - copy = 'If you have access to an ethernet cable, ' +\ - 'try using that instead.' + copy = _('If you have access to an ethernet cable, ' +\ + 'try using that instead.') screen = SlideScreen( self._stage, self._stage.media_path('ethernet-cable.png'), @@ -312,7 +312,7 @@ def troubleshoot_ethernet(self): def troubleshoot_router(self): self._clear() - copy = 'Try moving your Kano closer to the internet wireless router.' + copy = _('Try moving your Kano closer to the internet wireless router.') screen = SlideScreen( self._stage, self._stage.media_path('router.png'), @@ -325,7 +325,7 @@ def troubleshoot_router(self): def contact_us(self): self._clear() - copy = 'Having trouble connecting? Find us at help.kano.me and we\'ll come to the rescue!' + copy = _('Having trouble connecting? Find us at help.kano.me and we\'ll come to the rescue!') screen = SlideScreen( self._stage, self._stage.media_path('judoka-call-centre.png'), @@ -363,17 +363,17 @@ def __init__(self, stage, troubleshoot_cb, skip_cb): self.set_margin_left(40) self.set_margin_right(40) - desc = Gtk.Label('Oops there was a problem connecting to internet.') + desc = Gtk.Label(_('Oops there was a problem connecting to internet.')) desc.set_line_wrap(True) add_class(desc, 'console-screen-desc') img_path = self._stage.media_path("troubleshooting.png") image = Gtk.Image.new_from_file(img_path) - troubleshoot = KanoButton('FIX IT') + troubleshoot = KanoButton(_('FIX IT')) troubleshoot.connect('clicked', self._cb_wrapper, troubleshoot_cb) - skip = KanoButton('SKIP', color="orange") + skip = KanoButton(_('SKIP'), color="orange") skip.connect('clicked', self._cb_wrapper, skip_cb) buttons = Gtk.HBox(False, 0) @@ -400,23 +400,23 @@ def __init__(self, stage, try_again_cb, skip_cb): self.set_margin_left(40) self.set_margin_right(40) - heading = Gtk.Label('Are You Sure?') + heading = Gtk.Label(_('Are You Sure?')) heading.set_margin_top(20) add_class(heading, 'console-screen-heading') desc = Gtk.Label( - "Kano uses WiFi to stay up to date" + + _("Kano uses WiFi to stay up to date" + "\nwith all new software updates, apps" + - "\nand features." + "\nand features.") ) desc.set_justify(Gtk.Justification.CENTER) desc.set_line_wrap(True) add_class(desc, 'console-screen-desc') - try_again = KanoButton('TRY AGAIN') + try_again = KanoButton(_('TRY AGAIN')) try_again.connect('clicked', self._cb_wrapper, try_again_cb) - skip = KanoButton('YES I WANT TO SKIP', color="grey") + skip = KanoButton(_('YES I WANT TO SKIP'), color="grey") skip.connect('clicked', self._cb_wrapper, skip_cb, 'init-flow-wifi-skipped') @@ -444,22 +444,22 @@ def __init__(self, stage, now_cb, later_cb): self.set_margin_left(40) self.set_margin_right(40) - heading = Gtk.Label('For parents...') + heading = Gtk.Label(_('For parents...')) add_class(heading, 'console-screen-heading') - copy = 'You can put a safety filter on Kano\'s internet. ' + \ - 'You can set it now or later.' + copy = _('You can put a safety filter on Kano\'s internet. ' + \ + 'You can set it now or later.') desc = Gtk.Label(copy) desc.set_line_wrap(True) add_class(desc, 'console-screen-desc') padlock = Gtk.Image.new_from_file(stage.media_path('padlock.png')) - later = KanoButton('GOT IT') + later = KanoButton(_('GOT IT')) later.connect('clicked', self._cb_wrapper, later_cb, 'init-flow-parental-skipped') later.set_size_request(200, 50) - now = OrangeButton('SET NOW') + now = OrangeButton(_('SET NOW')) now.connect('clicked', self._cb_wrapper, now_cb, 'init-flow-parental-set') emptylabel = Gtk.Label(" ") diff --git a/po/Makefile b/po/Makefile new file mode 100644 index 0000000..c345b70 --- /dev/null +++ b/po/Makefile @@ -0,0 +1,36 @@ +APPNAME=kano-init-flow +ORG="Kano Computing Ltd." + +MSGLANGS=$(notdir $(wildcard *po)) +MSGOBJS=$(addprefix ../locale/,$(MSGLANGS:.po=/LC_MESSAGES/$(APPNAME).mo)) + +.PHONY: clean_locales messages + +build: $(MSGOBJS) + +update: $(MSGLANGS) + +clean_locales: + rm -rf ../locale + +clean: clean_locales + rm -f messages.pot + +define run-xgettext +xgettext -f PYPOTFILES -L Python --force-po -o messages.pot \ + --package-name=$(APPNAME) --copyright-holder=$(ORG) +endef + +messages: + $(run-xgettext) + +messages.pot: + $(run-xgettext) + +%.po: messages.pot + msgmerge -N -U $*.po messages.pot + touch $*.po + +../locale/%/LC_MESSAGES/$(APPNAME).mo: clean_locales + mkdir -p $(dir $@) + msgfmt -c -o $@ $*.po diff --git a/po/PYPOTFILES b/po/PYPOTFILES new file mode 100644 index 0000000..de336f0 --- /dev/null +++ b/po/PYPOTFILES @@ -0,0 +1,18 @@ +../kano_init_flow/stages/audio_lab/main.py +../kano_init_flow/stages/blocks/main.py +../kano_init_flow/stages/bugs/main.py +../kano_init_flow/stages/desktop/main.py +../kano_init_flow/stages/drag_and_drop/main.py +../kano_init_flow/stages/intro/main.py +../kano_init_flow/stages/light_lab/main.py +../kano_init_flow/stages/overscan/main.py +../kano_init_flow/stages/overscan_old/main.py +../kano_init_flow/stages/pi_audio/main.py +../kano_init_flow/stages/pi_complete/main.py +../kano_init_flow/stages/pi_hdmi/main.py +../kano_init_flow/stages/pi_keyboard/main.py +../kano_init_flow/stages/pi_wifi/main.py +../kano_init_flow/stages/quests/main.py +../kano_init_flow/stages/wardrobe/main.py +../kano_init_flow/stages/wifi/main.py +../kano_init_flow/kw_slideshow/main.py diff --git a/po/ja.po b/po/ja.po new file mode 100644 index 0000000..baa856a --- /dev/null +++ b/po/ja.po @@ -0,0 +1,668 @@ +# Japanese translations for kano-init-flow package. +# Copyright (C) 2016 Kano Computing Ltd. +# This file is distributed under the same license as the kano-init-flow package. +# Choppin Antoine , 2016. +# +msgid "" +msgstr "" +"Project-Id-Version: kano-init-flow\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-04-15 21:26+0900\n" +"PO-Revision-Date: 2016-04-13 21:19+0900\n" +"Last-Translator: Choppin Antoine \n" +"Language-Team: Japanese\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: ../kano_init_flow/stages/audio_lab/main.py:88 +msgid "Press the TAB key to play a song!" +msgstr "音楽を流すにはTABキーを押して!" + +#: ../kano_init_flow/stages/audio_lab/main.py:154 +msgid "Plug in the blue cable" +msgstr "青いケーブルを挿し込んでね" + +#: ../kano_init_flow/stages/audio_lab/main.py:155 +msgid "Check you've plugged in the audio" +msgstr "オーディオケーブルを挿し込んだか確認しよう" + +#: ../kano_init_flow/stages/audio_lab/main.py:156 +#: ../kano_init_flow/kw_slideshow/main.py:46 +msgid "NEXT" +msgstr "次へ" + +#: ../kano_init_flow/stages/audio_lab/main.py:171 +msgid "Can you see the blue light?" +msgstr "青いライトは見えますか?" + +#: ../kano_init_flow/stages/audio_lab/main.py:172 +msgid "If the power plugs are connected correctly," +msgstr "電力プラグが正しく接続されれば" + +#: ../kano_init_flow/stages/audio_lab/main.py:173 +msgid "you should see a blue light." +msgstr "青いライトが見えるはずだ。" + +#: ../kano_init_flow/stages/audio_lab/main.py:174 +#: ../kano_init_flow/stages/audio_lab/main.py:247 +#: ../kano_init_flow/stages/light_lab/main.py:164 +#: ../kano_init_flow/stages/overscan_old/main.py:142 +msgid "YES" +msgstr "はい" + +#: ../kano_init_flow/stages/audio_lab/main.py:175 +#: ../kano_init_flow/stages/audio_lab/main.py:250 +#: ../kano_init_flow/stages/light_lab/main.py:167 +#: ../kano_init_flow/stages/overscan_old/main.py:145 +msgid "NO" +msgstr "いいえ" + +#: ../kano_init_flow/stages/audio_lab/main.py:185 +#: ../kano_init_flow/stages/wifi/main.py:416 +msgid "TRY AGAIN" +msgstr "やり直す" + +#: ../kano_init_flow/stages/audio_lab/main.py:188 +#: ../kano_init_flow/stages/wifi/main.py:376 +msgid "SKIP" +msgstr "飛ばす" + +#: ../kano_init_flow/stages/audio_lab/main.py:194 +msgid "USE TV SPEAKERS" +msgstr "TVスピーカーを使って" + +#: ../kano_init_flow/stages/audio_lab/main.py:203 +#: ../kano_init_flow/stages/light_lab/main.py:124 +msgid "No light? Check the GPIO" +msgstr "光らない?GPIOを確認して" + +#: ../kano_init_flow/stages/audio_lab/main.py:204 +#: ../kano_init_flow/stages/light_lab/main.py:125 +msgid "The cable has to be connected to these" +msgstr "このピンにケーブルを正しく接続" + +#: ../kano_init_flow/stages/audio_lab/main.py:205 +#: ../kano_init_flow/stages/light_lab/main.py:126 +msgid "pins exactly." +msgstr "しなければならない。" + +#: ../kano_init_flow/stages/audio_lab/main.py:235 +msgid "Can you hear a sound?" +msgstr "音は聞こえますか?" + +#: ../kano_init_flow/stages/blocks/main.py:81 +msgid "Oh no, there's a boulder" +msgstr "いゃ〜、玉石が道に" + +#: ../kano_init_flow/stages/blocks/main.py:82 +msgid "in the way!" +msgstr "あるぞ!" + +#: ../kano_init_flow/stages/blocks/main.py:115 +msgid "But don't worry, you can" +msgstr "でも心配しないで、カノ" + +#: ../kano_init_flow/stages/blocks/main.py:116 +msgid "use Kano blocks to create code" +msgstr "ブロックを使って、君の周りの世界を" + +#: ../kano_init_flow/stages/blocks/main.py:117 +msgid "to change what's around you.\n" +msgstr "変えるためのコードが作れる。\n" + +#: ../kano_init_flow/stages/blocks/main.py:118 +msgid "Looks like there's one over there!" +msgstr "ほら、ここに一個あるよ!" + +#: ../kano_init_flow/stages/blocks/main.py:233 +msgid "Awesome, now we can escape!" +msgstr "素晴らしい、これで逃げられる!" + +#: ../kano_init_flow/stages/bugs/main.py:73 +msgid "" +"Oh no bugs!\n" +"Click on them quick to remove them." +msgstr "" +"いゃ〜、バグ(虫)だ!\n" +"早く、クリックして取り除いてよ。" + +#: ../kano_init_flow/stages/bugs/main.py:76 +msgid "Phew, thanks for cleaning up!" +msgstr "ホッと、きれいにしてくれてありがとう!" + +#: ../kano_init_flow/stages/desktop/main.py:79 +msgid "" +"We made it to the desktop!\n" +"Click here to set up your profile" +msgstr "" +"デスクトップまできましたよ!\n" +"ここをクリックして、君のプロファイルを作ろう" + +#: ../kano_init_flow/stages/desktop/main.py:133 +msgid "" +"This is Kano World, where\n" +"you can code with cool people,\n" +"and get new apps.\n" +"Click to continue." +msgstr "" +"こちらはKanoワールドだよ\n" +"仲間と一緒にコードを書いたり\n" +"新しいアプリをゲットできたりするよ。\n" +"クリックして次へ。" + +#: ../kano_init_flow/stages/desktop/main.py:159 +msgid "" +"Click the Home button to\n" +"return to the desktop." +msgstr "" +"ホームボタンをクリックして\n" +"デスクトップに戻ろう。" + +#: ../kano_init_flow/stages/desktop/main.py:165 +msgid "" +"If you need Help,\n" +"you can click here." +msgstr "" +"ヘルプを求めるには\n" +"ここをクリックしてね。" + +#: ../kano_init_flow/stages/desktop/main.py:171 +msgid "" +"Here's where you can\n" +"sync your online Profile." +msgstr "" +"ここで君のオンライン\n" +"プロファイルを同期できる。" + +#: ../kano_init_flow/stages/desktop/main.py:177 +msgid "" +"You can change Internet\n" +"settings here." +msgstr "" +"インターネットの設定は\n" +"ここで変えられる。" + +#: ../kano_init_flow/stages/desktop/main.py:183 +msgid "" +"Want updates?\n" +"Click on the Updater." +msgstr "" +"アップデートしたい?\n" +"アップデーターをクリックしてね。" + +#: ../kano_init_flow/stages/desktop/main.py:189 +msgid "" +"And this is where you can change\n" +"all the system Settings." +msgstr "" +"そしてここで全てのシステム設定を\n" +"変更できるよ。" + +#: ../kano_init_flow/stages/desktop/main.py:195 +msgid "" +"Control the volume\n" +"of the system." +msgstr "" +"システムの音量を\n" +"制御できる。" + +#: ../kano_init_flow/stages/desktop/main.py:217 +msgid "" +"This is your Taskbar!\n" +"Click on the different widgets to find\n" +"out more about what they do." +msgstr "" +"これは君のタスクバーだよ!\n" +"それぞれのウィジェットをクリックして\n" +"何ができるか見つけよう。" + +#: ../kano_init_flow/stages/desktop/main.py:276 +msgid "" +"Customize your own Snake game,\n" +"and share special gameboards." +msgstr "" +"自分のスネーク(ヘビ)ゲームを\n" +"改造して、独特のゲームボードを作ろう。" + +#: ../kano_init_flow/stages/desktop/main.py:282 +msgid "" +"You can make this classic game yourself,\n" +"with new rules, cheats, and powers." +msgstr "" +"新しいルール、ずる、パワーを付け加えて、\n" +"このクラシックゲームを自分で作れる。" + +#: ../kano_init_flow/stages/desktop/main.py:288 +msgid "" +"Normal people play Minecraft.\n" +"On Kano, you can hack the game with code." +msgstr "" +"普通の人々はマインクラフトで遊んでるけど、\n" +"Kanoではコードでゲームをハックできるよ。" + +#: ../kano_init_flow/stages/desktop/main.py:294 +msgid "" +"The Terminal talks to the computer's\n" +"brain directly. Use its powers to go on a quest." +msgstr "" +"ターミナルはコンピューターの頭脳に直接\n" +"命令してる。そのパワーを使って探検しよう。" + +#: ../kano_init_flow/stages/desktop/main.py:300 +msgid "" +"You can make sounds, beats, loops,\n" +"and songs on Kano." +msgstr "" +"Kanoで音、リズム、ループと歌を\n" +"作れるよ。" + +#: ../kano_init_flow/stages/desktop/main.py:306 +msgid "" +"Ever drawn or painted?\n" +"You can create incredible artworks with code." +msgstr "" +"お絵描きや塗り絵は好き?\n" +"コードで素晴らしいアートワークが作れるよ。" + +#: ../kano_init_flow/stages/desktop/main.py:312 +msgid "You can browse the web." +msgstr "ウェブサーフィンができる。" + +#: ../kano_init_flow/stages/desktop/main.py:317 +msgid "You can play with code blocks." +msgstr "コードブロックで遊べる。" + +#: ../kano_init_flow/stages/desktop/main.py:322 +msgid "Look at your files and folders here." +msgstr "ここで自分のファイルとフォルダーが見られる。" + +#: ../kano_init_flow/stages/desktop/main.py:327 +msgid "Find even more apps here." +msgstr "ここでさらに他のアプリがあるよ。" + +#: ../kano_init_flow/stages/desktop/main.py:332 +msgid "YouTube" +msgstr "ユーチューブ" + +#: ../kano_init_flow/stages/desktop/main.py:380 +msgid "" +"These are your Apps!\n" +"You can make games, songs,\n" +"artworks and more,\n" +"then share them to World." +msgstr "" +"これは君のアプリだよ!\n" +"ゲーム、歌、アートワーク\n" +"などなど作って、世界と\n" +"共有できるよ。" + +#: ../kano_init_flow/stages/drag_and_drop/main.py:48 +msgid "" +"Click on me,\n" +"hold down the mouse button,\n" +"and drag me across!" +msgstr "" +"僕をクリックし、\n" +"マウスボタンを押しながら、\n" +"僕を反対側まで運んでね!" + +#: ../kano_init_flow/stages/drag_and_drop/main.py:95 +msgid "" +"Pick me up with the cursor\n" +"and hold the left button down\n" +"while dragging me over." +msgstr "" +"カーソルで僕を引っ張って\n" +"左ボタンを押し続けながら\n" +"あっちまで運んでね。" + +#: ../kano_init_flow/stages/drag_and_drop/main.py:105 +msgid "Thanks!" +msgstr "ありがとう!" + +#: ../kano_init_flow/stages/intro/main.py:80 +msgid "Click NEXT to start" +msgstr "始めるには「次」をクリックしてね" + +#: ../kano_init_flow/stages/intro/main.py:122 +msgid "Well done! You brought your" +msgstr "よくやったぞ!" + +#: ../kano_init_flow/stages/intro/main.py:123 +msgid "Kano to life! I'm Judoka and I" +msgstr "君のKanoを生かしたね!" + +#: ../kano_init_flow/stages/intro/main.py:124 +msgid "will be your guide through the" +msgstr "僕は柔道家で、君にKanoの世界を" + +#: ../kano_init_flow/stages/intro/main.py:125 +msgid "world of Kano." +msgstr "紹介していくよ。" + +#: ../kano_init_flow/stages/intro/main.py:174 +msgid "Kano is a world where" +msgstr "Kanoは何でもできる" + +#: ../kano_init_flow/stages/intro/main.py:175 +msgid "anything is possible!" +msgstr "世界だよ!" + +#: ../kano_init_flow/stages/intro/main.py:176 +msgid "Judokas can make and play" +msgstr "柔道家がコードの力を使って" + +#: ../kano_init_flow/stages/intro/main.py:177 +msgid "using code powers." +msgstr "物を作ったり、遊んだりできるよ。" + +#: ../kano_init_flow/stages/intro/main.py:219 +msgid "Ready to go? Jump on in!" +msgstr "準備はいいか?さー、行くよ!" + +#: ../kano_init_flow/stages/light_lab/main.py:62 +msgid "" +"Now let's check the lights work!\n" +"\n" +"Press the ON button to light up." +msgstr "" +"それでは、ライトを確認しよう!\n" +"\n" +"ONボタンを押して、ライトをつけよう。" + +#: ../kano_init_flow/stages/light_lab/main.py:127 +#: ../kano_init_flow/stages/wifi/main.py:458 +msgid "GOT IT" +msgstr "了解" + +#: ../kano_init_flow/stages/light_lab/main.py:152 +msgid "Can you see the lights?" +msgstr "ライトは見えるか?" + +#: ../kano_init_flow/stages/overscan/main.py:146 +msgid "Screen machine" +msgstr "スクリーンマシン" + +#: ../kano_init_flow/stages/overscan/main.py:151 +msgid "Use the up and down arrows on the" +msgstr "キーボードの上下矢印キーを使って" + +#: ../kano_init_flow/stages/overscan/main.py:152 +msgid "keyboard to adjust the picture until the" +msgstr "スクリーン押し線がモニターや" + +#: ../kano_init_flow/stages/overscan/main.py:153 +msgid "screen pushing machine lines up with the" +msgstr "テレビ画面の端と一致するまで" + +#: ../kano_init_flow/stages/overscan/main.py:154 +msgid "edges of your TV." +msgstr "画像を調整してみてね。" + +#: ../kano_init_flow/stages/overscan/main.py:167 +msgid "on your keyboard to increase" +msgstr "キーで上げられる" + +#: ../kano_init_flow/stages/overscan/main.py:168 +msgid "on your keyboard to decrease" +msgstr "キーで下げられる" + +#: ../kano_init_flow/stages/overscan/main.py:169 +msgid "click the button to confirm" +msgstr "確定するにはこのボタンをクリック" + +#: ../kano_init_flow/stages/overscan/main.py:183 +msgid "GO" +msgstr "ゴー" + +#: ../kano_init_flow/stages/overscan_old/main.py:135 +msgid "Are the white lines touching the edges?" +msgstr "白線はモニターの端を触れているか?" + +#: ../kano_init_flow/stages/overscan_old/main.py:164 +msgid "Use UP and DOWN keys" +msgstr "上下のキーを使って" + +#: ../kano_init_flow/stages/overscan_old/main.py:170 +msgid "Stretch or shrink your screen, until the white lines" +msgstr "白線が端と一致するまで、画面を伸ばしたり縮めたり" + +#: ../kano_init_flow/stages/overscan_old/main.py:175 +msgid "are lined up with the edges" +msgstr "してみてね。" + +#: ../kano_init_flow/stages/overscan_old/main.py:182 +msgid "DONE" +msgstr "終わり" + +#: ../kano_init_flow/stages/pi_audio/main.py:84 +msgid "" +"Let's make sure our sound\n" +"is loud and clear." +msgstr "" +"音量と音がキレイかどうか\n" +"確認しよう。" + +#: ../kano_init_flow/stages/pi_audio/main.py:100 +msgid "" +"Click on the blue cable\n" +"to continue." +msgstr "" +"続けるには、青いケーブルを\n" +"クリックしてね。" + +#: ../kano_init_flow/stages/pi_complete/main.py:53 +msgid "You set it up! Now it's time to play." +msgstr "設定は終わった!これから遊ぶ時間だ。" + +#: ../kano_init_flow/stages/pi_hdmi/main.py:85 +msgid "Let's set up your display!" +msgstr "ディスプレーを設定しよう!" + +#: ../kano_init_flow/stages/pi_keyboard/main.py:85 +msgid "Time to set up the keyboard!" +msgstr "キーボードを設定しよう!" + +#: ../kano_init_flow/stages/pi_wifi/main.py:90 +msgid "Let's set up WiFi" +msgstr "WiFiを設定しよう" + +#: ../kano_init_flow/stages/pi_wifi/main.py:105 +msgid "" +"Click on the green dongle\n" +"to continue." +msgstr "" +"続けるには緑のドングルを\n" +"クリックしてね。" + +#: ../kano_init_flow/stages/quests/main.py:76 +msgid "" +"You did it! Now you know how\n" +"to control your computer.\n" +"This was the first of many\n" +"quests you'll find in the\n" +"World of Kano" +msgstr "" +"よくやった!コンピューターの\n" +"操作が分かったね。\n" +"これでKanoワールドの最初の\n" +"クェストができた。他にも\n" +"いっぱいあるよ。" + +#: ../kano_init_flow/stages/quests/main.py:125 +msgid "Click on my scroll to find" +msgstr "僕のスクロールを" + +#: ../kano_init_flow/stages/quests/main.py:126 +msgid "out more and start the" +msgstr "クリックして、次の冒険を" + +#: ../kano_init_flow/stages/quests/main.py:127 +msgid "next adventure..." +msgstr "始めよう..." + +#: ../kano_init_flow/stages/quests/main.py:185 +msgid "Quests are a series of tasks that you" +msgstr "クェストというのは、Kanoでいくつかの" + +#: ../kano_init_flow/stages/quests/main.py:186 +msgid "can complete on your Kano to get" +msgstr "課題をクリアすれば、素晴らしい" + +#: ../kano_init_flow/stages/quests/main.py:187 +msgid "great rewards." +msgstr "プレゼントがもらえるものだよ。" + +#: ../kano_init_flow/stages/quests/main.py:216 +msgid "Complete all of the ticks in a" +msgstr "クェストの全ての課題をクリアすると" + +#: ../kano_init_flow/stages/quests/main.py:217 +msgid "quest to unlock rewards." +msgstr "プレゼントが手に入る。" + +#: ../kano_init_flow/stages/quests/main.py:246 +msgid "New quest" +msgstr "新しいクェスト" + +#: ../kano_init_flow/stages/quests/main.py:252 +msgid "Journey to Kano World" +msgstr "Kanoワールドへの旅" + +#: ../kano_init_flow/stages/wardrobe/main.py:52 +msgid "" +"Let's dress up your\n" +"character!" +msgstr "" +"君のキャラクターに\n" +"服を着せよう!" + +#: ../kano_init_flow/stages/wardrobe/main.py:131 +msgid "You look amazing!" +msgstr "すごく似合う!" + +#: ../kano_init_flow/stages/wardrobe/main.py:167 +msgid "OK" +msgstr "了解" + +#: ../kano_init_flow/stages/wifi/main.py:91 +msgid "Let's connect to the web!" +msgstr "ウェブに接続しよう!" + +#: ../kano_init_flow/stages/wifi/main.py:93 +msgid "Get started by clicking" +msgstr "まず、WiFiコンソールを" + +#: ../kano_init_flow/stages/wifi/main.py:94 +msgid "the WiFi console!" +msgstr "クリックしてね!" + +#: ../kano_init_flow/stages/wifi/main.py:198 +msgid "Oh no, the connection failed!" +msgstr "しまったー、接続が失敗したよ!" + +#: ../kano_init_flow/stages/wifi/main.py:199 +msgid "But we can still play." +msgstr "それでも遊べる。" + +#: ../kano_init_flow/stages/wifi/main.py:300 +msgid "If you have access to an ethernet cable, try using that instead." +msgstr "イーサネットケーブルを持っていれば、替わりに使ってみて。" + +#: ../kano_init_flow/stages/wifi/main.py:315 +msgid "Try moving your Kano closer to the internet wireless router." +msgstr "Kanoを無線ルーターに近づいてみれば?" + +#: ../kano_init_flow/stages/wifi/main.py:328 +msgid "" +"Having trouble connecting? Find us at help.kano.me and we'll come to the " +"rescue!" +msgstr "" +"接続できないの? help.kano.meで連絡すれば、\n" +"助けに行くよ!" + +#: ../kano_init_flow/stages/wifi/main.py:366 +msgid "Oops there was a problem connecting to internet." +msgstr "あれっ、インターネット接続に問題があるよ。" + +#: ../kano_init_flow/stages/wifi/main.py:373 +msgid "FIX IT" +msgstr "直す" + +#: ../kano_init_flow/stages/wifi/main.py:403 +msgid "Are You Sure?" +msgstr "本当に?" + +#: ../kano_init_flow/stages/wifi/main.py:408 +msgid "" +"Kano uses WiFi to stay up to date\n" +"with all new software updates, apps\n" +"and features." +msgstr "" +"KanoはWiFiを使って、ソフトウェアや\n" +"アプリ、また新しい機能をどんどん\n" +"更新していくんだ。" + +#: ../kano_init_flow/stages/wifi/main.py:419 +msgid "YES I WANT TO SKIP" +msgstr "はい、飛ばします。" + +#: ../kano_init_flow/stages/wifi/main.py:447 +msgid "For parents..." +msgstr "保護者の方へ..." + +#: ../kano_init_flow/stages/wifi/main.py:450 +msgid "" +"You can put a safety filter on Kano's internet. You can set it now or later." +msgstr "" +"Kanoのインターネットに安全フィルターを設定できます。今でも後でも設定できま" +"す。" + +#: ../kano_init_flow/stages/wifi/main.py:462 +msgid "SET NOW" +msgstr "今設定する" + +#: ../kano_init_flow/kw_slideshow/main.py:34 +msgid "Get Started" +msgstr "はじめる" + +#: ../kano_init_flow/kw_slideshow/main.py:36 +msgid "Apps" +msgstr "アプリ" + +#: ../kano_init_flow/kw_slideshow/main.py:39 +msgid "" +"Create and play with\n" +"Kano's Apps to make and save your\n" +"own code masterpieces, from games\n" +"and minecraft world, to art and music pieces..." +msgstr "" +"Kanoアプリで遊んで、ゲームから\n" +"マインクラフトの世界まで、アートや\n" +"音楽など、自分だけの作品を作って\n" +"保存できるよ。" + +#: ../kano_init_flow/kw_slideshow/main.py:69 +msgid "Kano World" +msgstr "Kanoワールド" + +#: ../kano_init_flow/kw_slideshow/main.py:72 +msgid "" +"Show off and share your creations to friends\n" +"family and other Kano users on Kano World.\n" +"\n" +"Why not check it out now by clicking on the\n" +"icon to see what people have made today." +msgstr "" +"Kanoワールドで自分の作品を友達、家族と、\n" +"他のKanoユーザに自慢しよう。\n" +"\n" +"このアイコンをクリックし、他の人が今日\n" +"作ったものを今見てみない?" + +#: ../kano_init_flow/kw_slideshow/main.py:79 +msgid "LET'S GO" +msgstr "レッツゴー" From 73ebb7e90cb8984199fa1b45e5513b6b0eb90565 Mon Sep 17 00:00:00 2001 From: Antoine Choppin Date: Fri, 15 Apr 2016 22:15:24 +0900 Subject: [PATCH 2/5] i18n: add locales to the package --- setup.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/setup.py b/setup.py index a577222..667f4c0 100644 --- a/setup.py +++ b/setup.py @@ -40,6 +40,20 @@ def get_stages_data(): return data +def get_locales(): + locale_dir = 'locale' + locales = [] + + for dirpath, dirnames, filenames in os.walk(locale_dir): + for filename in filenames: + locales.append( + (os.path.join('/usr/share', dirpath), + [os.path.join(dirpath, filename)]) + ) + + return locales + + def merge_dicts(a, b): res = a.copy() res.update(b) @@ -58,4 +72,5 @@ def merge_dicts(a, b): package_data=merge_dicts({"kano_init_flow.ui": pkg_data, "kano_init_flow.kw_slideshow": pkg_data, }, get_stages_data()) + data_files=get_locales() ) From f42f67062f2a63db33fa16c3211cc7dfaad57d6d Mon Sep 17 00:00:00 2001 From: Antoine Choppin Date: Sat, 16 Apr 2016 00:21:44 +0900 Subject: [PATCH 3/5] i18n: fix build and initialization --- bin/kano-init-flow | 5 +++++ debian/control | 2 +- debian/rules | 1 + setup.py | 2 +- 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/bin/kano-init-flow b/bin/kano-init-flow index e4c9a7a..47a6d13 100755 --- a/bin/kano-init-flow +++ b/bin/kano-init-flow @@ -21,6 +21,7 @@ Options: import os import sys +import gettext # Add the parent directory in the python path # TODO: move this elsewhere? @@ -28,7 +29,11 @@ if __name__ == '__main__' and __package__ is None: dir_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) if dir_path != '/usr': sys.path.insert(1, dir_path) + LOCALE_PATH = os.path.join(dir_path, 'locale') + else: + LOCALE_PATH = None +gettext.install('kano-init-flow', LOCALE_PATH, unicode=1) import docopt from gi.repository import Gtk, GObject diff --git a/debian/control b/debian/control index 654950b..d8e8939 100644 --- a/debian/control +++ b/debian/control @@ -9,5 +9,5 @@ Package: kano-init-flow Architecture: all Depends: ${misc:Depends}, gir1.2-gtk-3.0, kano-toolset (>=1.2-2), kano-profile (>=2.2.0-5), kano-settings (>=2.2-1), - kano-connect (>=2.0-1), kano-peripherals + kano-connect (>=2.0-1), kano-peripherals, gettext Description: Kanux initial boot diff --git a/debian/rules b/debian/rules index 4647c9c..8bf5e42 100755 --- a/debian/rules +++ b/debian/rules @@ -1,4 +1,5 @@ #!/usr/bin/make -f %: + cd po && make dh $@ --with python2 diff --git a/setup.py b/setup.py index 667f4c0..898ed74 100644 --- a/setup.py +++ b/setup.py @@ -71,6 +71,6 @@ def merge_dicts(a, b): 'bin/kano-world-slideshow'], package_data=merge_dicts({"kano_init_flow.ui": pkg_data, "kano_init_flow.kw_slideshow": pkg_data, - }, get_stages_data()) + }, get_stages_data()), data_files=get_locales() ) From 16a813fcd5723a2d6215406cc15e817bcf47f4ee Mon Sep 17 00:00:00 2001 From: Antoine Choppin Date: Sun, 17 Apr 2016 15:41:11 +0900 Subject: [PATCH 4/5] Fix locale path, use kano-i18n dependency, fix NEXT labels --- bin/kano-init-flow | 6 +++--- debian/control | 4 ++-- kano_init_flow/stages/quests/main.py | 4 ++-- po/ja.po | 4 +++- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/bin/kano-init-flow b/bin/kano-init-flow index 47a6d13..2f22bb8 100755 --- a/bin/kano-init-flow +++ b/bin/kano-init-flow @@ -21,7 +21,6 @@ Options: import os import sys -import gettext # Add the parent directory in the python path # TODO: move this elsewhere? @@ -29,11 +28,12 @@ if __name__ == '__main__' and __package__ is None: dir_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) if dir_path != '/usr': sys.path.insert(1, dir_path) - LOCALE_PATH = os.path.join(dir_path, 'locale') + LOCALE_PATH = '/usr/share/locale' else: LOCALE_PATH = None -gettext.install('kano-init-flow', LOCALE_PATH, unicode=1) +import kano_i18n.init +kano_i18n.init.install('kano-init-flow', LOCALE_PATH) import docopt from gi.repository import Gtk, GObject diff --git a/debian/control b/debian/control index d8e8939..68e169a 100644 --- a/debian/control +++ b/debian/control @@ -3,11 +3,11 @@ Maintainer: Team Kano Section: x11 Priority: optional Standards-Version: 3.9.4 -Build-Depends: debhelper (>=9.0.0), python-setuptools +Build-Depends: debhelper (>=9.0.0), python-setuptools, gettext Package: kano-init-flow Architecture: all Depends: ${misc:Depends}, gir1.2-gtk-3.0, kano-toolset (>=1.2-2), kano-profile (>=2.2.0-5), kano-settings (>=2.2-1), - kano-connect (>=2.0-1), kano-peripherals, gettext + kano-connect (>=2.0-1), kano-peripherals, kano-i18n Description: Kanux initial boot diff --git a/kano_init_flow/stages/quests/main.py b/kano_init_flow/stages/quests/main.py index 77cfa56..242b1d6 100644 --- a/kano_init_flow/stages/quests/main.py +++ b/kano_init_flow/stages/quests/main.py @@ -191,7 +191,7 @@ def first_scroll(self): img_path = self._stage.media_path('chest-closed.png') chest = Gtk.Image.new_from_file(img_path) - button = KanoButton('NEXT', color='orange') + button = KanoButton(_('NEXT'), color='orange') button.connect('clicked', cb_wrapper, self.second_scroll) text_widgets[0].set_margin_top(30) @@ -220,7 +220,7 @@ def second_scroll(self): chest = Gtk.Image.new_from_file(self._stage.media_path('chest-open.png')) - button = KanoButton('NEXT', color='orange') + button = KanoButton(_('NEXT'), color='orange') button.connect('clicked', cb_wrapper, self.third_scroll) ticks.set_margin_top(20) diff --git a/po/ja.po b/po/ja.po index baa856a..b4bd644 100644 --- a/po/ja.po +++ b/po/ja.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: kano-init-flow\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-04-15 21:26+0900\n" +"POT-Creation-Date: 2016-04-17 15:39+0900\n" "PO-Revision-Date: 2016-04-13 21:19+0900\n" "Last-Translator: Choppin Antoine \n" "Language-Team: Japanese\n" @@ -30,6 +30,8 @@ msgid "Check you've plugged in the audio" msgstr "オーディオケーブルを挿し込んだか確認しよう" #: ../kano_init_flow/stages/audio_lab/main.py:156 +#: ../kano_init_flow/stages/quests/main.py:194 +#: ../kano_init_flow/stages/quests/main.py:223 #: ../kano_init_flow/kw_slideshow/main.py:46 msgid "NEXT" msgstr "次へ" From 3f5990bedbb47ef1df632d378b9c59436f37e129 Mon Sep 17 00:00:00 2001 From: Antoine Choppin Date: Sun, 17 Apr 2016 17:38:22 +0900 Subject: [PATCH 5/5] Fix some translations --- po/ja.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/po/ja.po b/po/ja.po index b4bd644..3e4d522 100644 --- a/po/ja.po +++ b/po/ja.po @@ -141,7 +141,7 @@ msgid "" "Click here to set up your profile" msgstr "" "デスクトップまできましたよ!\n" -"ここをクリックして、君のプロファイルを作ろう" +"ここをクリックして、君のプロフィールを作ろう" #: ../kano_init_flow/stages/desktop/main.py:133 msgid "" @@ -218,7 +218,7 @@ msgid "" "out more about what they do." msgstr "" "これは君のタスクバーだよ!\n" -"それぞれのウィジェットをクリックして\n" +"それぞれのマークをクリックして\n" "何ができるか見つけよう。" #: ../kano_init_flow/stages/desktop/main.py:276 @@ -235,7 +235,7 @@ msgid "" "with new rules, cheats, and powers." msgstr "" "新しいルール、ずる、パワーを付け加えて、\n" -"このクラシックゲームを自分で作れる。" +"このクラシックゲームを自分で改造できる。" #: ../kano_init_flow/stages/desktop/main.py:288 msgid ""