Commits

Sergey Astanin  committed 7cdde50

modified code for automatic localization with gettext

* messages wrapped with _() which is an alias to gettext.gettext
* button images are not loaded because they are not translatable
* placement and appearance of the text labels slightly adjusted

  • Participants
  • Parent commits a236cf0

Comments (0)

Files changed (2)

 import time
 import math
 import os
+import gettext
+_ = gettext.gettext
 
 class Clock(Canvas):
     """ This is a simple stop watch displayed on a Tkinter canvas.
             Does not work while the clock is running. """
         if not self.running:
             window = Toplevel()
-            window.title("Change time settings")
-            sc = Scale(window, label='Pick time in seconds (0=off)', length=300,
+            window.title(_('Change time settings'))
+            sc = Scale(window, label=_('Pick time in seconds (0=off)'), length=300,
                        variable = self.maxTime, from_=0, to = 480,
                        tickinterval = 60, showvalue=YES, orient='horizontal')
             sc.pack()
 #!/usr/bin/python
+# vim: fileencoding=utf-8 ts=4 sw=4 expandtab:
 # File: uligo.py
 
 ##   This is the main part of uliGo 0.3, a program for practicing
 from math import sqrt
 import webbrowser
 
+import gettext
+_ = gettext.gettext
+
 from sgfparser import *
 
 import clock
     
     def __init__(self, master):
         p = os.path.join(sys.path[0],'gifs')
-        try:                                                     # try to load the gif's
-            self.solved1 = PhotoImage(file=os.path.join(p,'solved1.gif'))
-            self.solved2 = PhotoImage(file=os.path.join(p,'solved2.gif'))
-            self.wrong   = PhotoImage(file=os.path.join(p,'wrong.gif'))
-            self.empty   = PhotoImage(file=os.path.join(p,'empty.gif'))
-            self.end     = PhotoImage(file=os.path.join(p,'end.gif'))
-        except TclError:
-            self.gifsFound = 0
-        else:
-            self.gifsFound = 1
-        Frame.__init__(self, master, height=20, width=65)
+        # DO NOT load images, they are untranslatable.
+        self.gifsFound = 0
+        Frame.__init__(self, master, height=20, width=65, pady=5)
         self.label = Label(self, bd=1, anchor=W)
-        if self.gifsFound: self.label.config(image=self.empty)
-        else:              self.label.config(font=('Helvetica', 24))
         self.label.pack(fill=X)
 
     def set(self, status=None):
         if   status == 'solved1':
             if self.gifsFound: self.label.config(image = self.solved1)
-            else:              self.label.config(fg='green', text = 'solved!')
+            else:              self.label.config(fg='DarkGreen', text=_('solved!'), font='24')
         elif status == 'solved2':
             if self.gifsFound: self.label.config(image = self.solved2)
-            else:              self.label.config(fg='blue', text='solved')
+            else:              self.label.config(fg='blue', text=_('solved'), font='24')
         elif status == 'wrong':
             if self.gifsFound: self.label.config(image = self.wrong)
-            else:              self.label.config(fg='red', text='wrong!')
+            else:              self.label.config(fg='red', text=_('wrong!'), font='24')
         elif status == 'end':
             if self.gifsFound: self.label.config(image = self.end)
-            else:              self.label.config(fg='red', text='end')
+            else:              self.label.config(fg='red', text=_('end'), font='24')
         else                    :
             if self.gifsFound: self.label.config(image = self.empty)
             else:              self.label.config(text='')
             rightPercentage = ' (' + str(self.noRight*100/self.pbmsAsked) + ' % )'
             wrongPercentage = ' (' + str(100 - (self.noRight*100/self.pbmsAsked) ) + ' % )'
         else: rightPercentage = wrongPercentage = ''
-        return    'Number of problems in database: ' + str(self.noOfPbms) +'\n' \
-               +  'Number of questions asked     : ' + str(self.pbmsAsked) +'\n' \
-               +  'Number of right answers       : ' + str(self.noRight) \
+        return    _('Number of problems in database: ') + str(self.noOfPbms) +'\n' \
+               +  _('Number of questions asked     : ') + str(self.pbmsAsked) +'\n' \
+               +  _('Number of right answers       : ') + str(self.noRight) \
                       + rightPercentage + '\n' \
-               +  'Number of wrong answers       : ' + str(self.noWrong) \
+               +  _('Number of wrong answers       : ') + str(self.noWrong) \
                       + wrongPercentage + '\n' \
 
 
             pickle.dump((self.noOfPbms, self.pbmsAsked, self.noRight, self.noWrong, \
                          self.current, self.handleCurrent, help, self.list),f)
             f.close()
-        except IOError, OSError: showwarning('IO Error', 'Could not write .dat file')
+        except IOError, OSError: showwarning(_('IO Error'), _('Could not write .dat file'))
 
 
     def changeModeQuit(self,w,h1,h2,e):
             the problems. """
         
         window = Toplevel()
-        window.title("Order of the problems")
+        window.title(_('Order of the problems'))
         f1 = Frame(window)
         f2 = Frame(window)
 
 
         h1 = IntVar()
         h1.set(self.modeVar.get())
-        b1 = Radiobutton(f1, text='Random order', variable=h1, value=0,
+        b1 = Radiobutton(f1, text=_('Random order'), variable=h1, value=0,
                          command=lambda e=e: e.config(state=DISABLED))
-        b2 = Radiobutton(f1, text='Sequential order (keep track of correct/wrong answers)',
+        b2 = Radiobutton(f1, text=_('Sequential order (keep track of correct/wrong answers)'),
                          variable=h1, value=1,
                          command=lambda e=e: e.config(state=DISABLED))
-        b3 = Radiobutton(f1, text='Sequential order (don\'t record results); start with problem no. ',
+        b3 = Radiobutton(f1, text=_('Sequential order (don\'t record results); start with problem no. '),
                          variable=h1, value=2,
                          command=lambda e=e: e.config(state=NORMAL))
 
         h2 = IntVar()
         h2.set(0)
-        c = Checkbutton(f1, text='Use this mode as default', variable = h2)
+        c = Checkbutton(f1, text=_('Use this mode as default'), variable = h2)
 
-        OKbutton = Button(f2, text='OK',
+        OKbutton = Button(f2, text=_('OK'),
                           command = lambda s=self, w=window, h1=h1, h2=h2, e=e: s.changeModeQuit(w, h1, h2, e))
-        cancelButton = Button(f2, text='Cancel', command=window.destroy)
+        cancelButton = Button(f2, text=_('Cancel'), command=window.destroy)
         
         b1.grid(row=0, column=0, sticky=NW)
         b2.grid(row=1, column=0, sticky=NW)
             cf = os.path.basename(self.currentFile)
         else:
             cf = 'None'
-        s = 'Database: '+ cf + '\n\n' + s
+        s = _('Database: ')+ cf + '\n\n' + s
         self.statisticsText.set(s)
      
 
                 self.statusbar.set('empty')
 
         except SGFError:
-            showwarning('SGF Error', 'Error in SGF file!')
+            showwarning(_('SGF Error'), _('Error in SGF file!'))
             return
 
 
                     self.board.placeMark(self.convCoord(c[color][0], self.orientation),'red')
                 n = n.down
         except SGFError:
-            showwarning('SGF Error', 'Error in SGF file!')
+            showwarning(_('SGF Error'), _('Error in SGF file!'))
         
 
     def markAll(self):
                 self.board.placeMark(self.convCoord(c[color][0], self.orientation),'blue')
                 n = n.down
         except SGFError:
-            showwarning('SGF Error', 'Error in SGF file!')
+            showwarning(_('SGF Error'), _('Error in SGF file!'))
         
 
     def navSolutionNextMove(self, p):
                         self.cursor.previous()
         
         except SGFError:
-            showwarning('SGF Error', 'Error in SGF file!')
+            showwarning(_('SGF Error'), _('Error in SGF file!'))
         
 
     def undo2(self):
                     self.noMovesMade = self.noMovesMade - 1
 
         except SGFError:
-            showwarning('SGF Error', 'Error in SGF file!')
+            showwarning(_('SGF Error'), _('Error in SGF file!'))
         
 
     def undoTryVar(self):
                     self.noMovesMade = self.noMovesMade - 1
 
         except SGFError:
-            showwarning('SGF Error', 'Error in SGF file!')
+            showwarning(_('SGF Error'), _('Error in SGF file!'))
 
 
     def showSolution(self):
                 self.noSolMoves=0
 
         except SGFError:
-            showwarning('SGF Error', 'Error in SGF file!')
+            showwarning(_('SGF Error'), _('Error in SGF file!'))
 
 
     def giveHint(self):
 
             self.board.state('normal', self.nextMove)
         except SGFError:
-            showwarning('SGF Error', 'Error in SGF file!')
+            showwarning(_('SGF Error'), _('Error in SGF file!'))
 
 
     def findNextParenthesis(self,s,i):
                 s = f.read()
                 f.close()
             except IOError:
-                showwarning('Open file', 'Cannot open this file\n')
+                showwarning(_('Open file'), _('Cannot open this file\n'))
                 return
         else:
             self.currentFile = ''
             if self.currentFile: f.write('f '+self.currentFile +'\n')
             f.close()
         except IOError:
-            showwarning('IOError', 'Could not write uligo.def')
+            showwarning(_('IOError'), _('Could not write uligo.def'))
 
         self.saveOptions()
         self.frame.quit()
         try:
             c = EnhancedCursor(self.pbms[n], self.comments)
         except SGFError:
-            showwarning('Parsing Error', 'Error in SGF file!')
+            showwarning(_('Parsing Error'), _('Error in SGF file!'))
             return
 
         self.statusbar.set('empty')
         try:
             self.setup(c, ' ('+str(n+1)+')', 1, co, ori) # display problem
         except SGFError:
-            showwarning('Parsing Error', 'Error in SGF file!')
+            showwarning(_('Parsing Error'), _('Error in SGF file!'))
             return
 
         self.setWhoseTurn(self.inputColor)
 
     def setWhoseTurn(self, c):
         self.whoseTurnCanv.delete(ALL)
+	x,y,d=65,65,25 # position of the icon and text
         
+	# The sentence should be translated as a whole
+        if c=='B':
+            color = 'black'
+	    turnmsg = _('Black to play')
+        else:
+	    color = 'white'
+	    turnmsg = _('White to play')
         if self.BsTurn:
-            if c == 'B': self.whoseTurnCanv.create_image(40,50, image=self.BsTurn)
-            else: self.whoseTurnCanv.create_image(40,50, image=self.WsTurn)
-            self.whoseTurnCanv.create_text(100,50, text='TO PLAY', font=('Helvetica', 10, 'bold'))
+            if c == 'B': self.whoseTurnCanv.create_image(x,y, image=self.BsTurn)
+            else: self.whoseTurnCanv.create_image(x,y, image=self.WsTurn)
         else:
-            if c=='B': color = 'black'
-            else: color = 'white'
-            self.whoseTurnCanv.create_oval(53,53,78,78,fill=color,outline='')
+            self.whoseTurnCanv.create_oval(x-d/2,y-d/2,x+d/2,y+d/2,fill=color,outline='black')
+        self.whoseTurnCanv.create_text(x+3*d,x, text=turnmsg)
          
 
     def backProblem(self):
             try:
                 c = EnhancedCursor(self.pbms[n], self.comments)
             except SGFError:
-                showwarning('Parsing Error', 'Error in SGF file!')
+                showwarning(_('Parsing Error'), _('Error in SGF file!'))
                 return
 
             self.statusbar.set('empty')
             try:
                 self.setup(c, ' ('+str(n+1)+')', 1, co, ori) # display problem
             except SGFError:
-                showwarning('Parsing Error', 'Error in SGF file!')
+                showwarning(_('Parsing Error'), _('Error in SGF file!'))
                 return
 
             self.setWhoseTurn(self.inputColor)
             self.cursor.reset()
             self.setup(self.cursor, ' ('+str(self.pbmRec.current+1)+')', changeOri) # display problem
         except SGFError:
-            showwarning('Parsing Error', 'Error in SGF file!')
+            showwarning(_('Parsing Error'), _('Error in SGF file!'))
             return
 
         self.setWhoseTurn(self.inputColor)
         try:
             os.remove(os.path.join(path, filename))
         except IOError:
-            showwarning('I/O Error', 'Could not delete .dat file.')
+            showwarning(_('I/O Error'), _('Could not delete .dat file.'))
 
         self.pbmRec = None
         self.readProblemColl(path, filename[:-4]+'.sgf')
                 self.board.state('disabled')
 
         except SGFError:
-            showwarning('SGF Error', 'Error in SGF file!')
+            showwarning(_('SGF Error'), _('Error in SGF file!'))
             
             
     def restartGM(self):
                 s = f.read()
                 f.close()
             except IOError:
-                showwarning('Open file', 'Cannot open this file\n')
+                showwarning(_('Open file'), _('Cannot open this file\n'))
 
             self.board.clear()
             self.board.delMarks()
             cursor = EnhancedCursor(s, self.comments)
             self.setup(cursor, '', 0, self.invertColor, self.orientation)
         except SGFError:
-            showwarning('Parsing Error', 'Error in SGF file!')
+            showwarning(_('Parsing Error'), _('Error in SGF file!'))
             return
         
         self.whoseTurnCanv.delete(ALL)
                 if d.has_key(tag): self.gameInfoCanv.create_text(10, 20+20*i, text=label+d[tag][0], anchor='w')
                 i += 1
         except SGFError:
-            showwarning('SGF Error', 'Error in SGF file!')
+            showwarning(_('SGF Error'), _('Error in SGF file!'))
             return
         
         self.changeModeGM()
                 self.board.undo()                                         # then delete it
                 self.guessFailure(right_pos, (x,y))
         except SGFError:
-            showwarning('SGF Error', 'Error in SGF file!')
+            showwarning(_('SGF Error'), _('Error in SGF file!'))
             
 
     def guessSuccess(self):
         self.guessModeCanvas.create_text(110, 40, text = `perc` + '%', tags='non-bg')
         
         if self.cursor.atEnd:
-            self.guessModeCanvas.create_text(40, 40, text = 'END', font=('Helvetica', 16), tags='non-bg')
+            self.guessModeCanvas.create_text(40, 40, text = _('END'), font=('Helvetica', 16), tags='non-bg')
 
 
     def guessFailure(self, right, pos):
                            100.0/(self.guessRightWrong[0] + self.guessRightWrong[1]))
                 self.guessModeCanvas.create_text(110, 40, text = `perc` + '%', tags='non-bg')
             except ZeroDivisionError: pass
-            self.guessModeCanvas.create_text(40, 40, text = 'END', font=('Helvetica', 16), tags='non-bg')
+            self.guessModeCanvas.create_text(40, 40, text = _('END'), font=('Helvetica', 16), tags='non-bg')
             return
 
         if not right or not pos:
         self.options.windowGeom = StringVar()
         self.options.windowGeom.set(self.master.geometry())
         self.options.saveToDisk(os.path.join(self.optionspath,'uligo.opt'),
-                                lambda: showwarning('Save options', 'IO Error'))
+                                lambda: showwarning(_('Save options'), _('IO Error')))
 
         
     def loadOptions(self):
         t = t + 'The images of the board and the stones were created by Patrice Fontaine.'
         
         window = Toplevel()
-        window.title('About uliGo ...')
+        window.title(_('About uliGo ...'))
 
         canv = Canvas(window, width=400,height=200, highlightthickness=0)
         canv.pack()
         text.config(state=DISABLED)
         text.pack()
 
-        b = Button(window, text="OK", command = window.destroy)
+        b = Button(window, text=_("OK"), command = window.destroy)
         b.pack(side=RIGHT)
         
         window.update_idletasks()
         text.config(state=DISABLED)
         text.pack()
 
-        b = Button(window, text="OK", command = window.destroy)
+        b = Button(window, text=_("OK"), command = window.destroy)
         b.pack(side=RIGHT)
         
         window.update_idletasks()
         self.guessModeCanvas = Canvas(self.clockFrame, height=80, width=150)
         self.options.modeVarGM = StringVar()
         self.options.modeVarGM.set('BW')
-        Label(self.guessModeButtonFrame, text='Guess ').pack(side=LEFT, expand=NO)
+        Label(self.guessModeButtonFrame, text=_('Guess ')).pack(side=LEFT, expand=NO)
         self.BbuttonGM = Radiobutton(self.guessModeButtonFrame, text='B', variable=self.options.modeVarGM,
                                      indicatoron=0,
                                      command=self.changeModeGM, value='B')
         master.config(menu=menu)
 
         filemenu = Menu(menu)
-        menu.add_cascade(label='File', underline=0, menu=filemenu)
-        filemenu.add_command(label='Open problem collection ...', underline=0, command=self.readProblemColl)
-        filemenu.add_command(label='Replay game', underline=0, command=self.replayGame)
+        menu.add_cascade(label=_('File'), underline=0, menu=filemenu)
+        filemenu.add_command(label=_('Open problem collection ...'), underline=0, command=self.readProblemColl)
+        filemenu.add_command(label=_('Replay game'), underline=0, command=self.replayGame)
         filemenu.add_separator()
-        filemenu.add_command(label='Clear Statistics', underline=0, command=self.clearStatistics)
-        filemenu.add_command(label='Statistics', underline=0, command=self.printStatistics)
+        filemenu.add_command(label=_('Clear Statistics'), underline=0, command=self.clearStatistics)
+        filemenu.add_command(label=_('Statistics'), underline=0, command=self.printStatistics)
         filemenu.add_separator()
-        filemenu.add_command(label='Exit', underline =1, command=self.quit)
+        filemenu.add_command(label=_('Exit'), underline =1, command=self.quit)
         self.optionsmenu = Menu(menu)
-        menu.add_cascade(label='Options', underline=0, menu=self.optionsmenu)
+        menu.add_cascade(label=_('Options'), underline=0, menu=self.optionsmenu)
 
         self.options.fuzzy = self.board.fuzzy    # make 'save options' easy
-        self.optionsmenu.add_checkbutton(label='Fuzzy stone placement', underline = 0, 
+        self.optionsmenu.add_checkbutton(label=_('Fuzzy stone placement'), underline = 0, 
                                          variable=self.options.fuzzy, command=self.board.fuzzyStones)
 
         self.options.shadedStoneVar = self.board.shadedStoneVar
         self.options.shadedStoneVar.set(1)
-        self.optionsmenu.add_checkbutton(label='Shaded stone mouse pointer', underline = 0, 
+        self.optionsmenu.add_checkbutton(label=_('Shaded stone mouse pointer'), underline = 0, 
                                          variable=self.options.shadedStoneVar)
 
         self.options.allowInvertColorVar = IntVar()
         self.options.allowInvertColorVar.set(1)
-        self.optionsmenu.add_checkbutton(label='Allow color switch', underline = 7, 
+        self.optionsmenu.add_checkbutton(label=_('Allow color switch'), underline = 7, 
                                          variable=self.options.allowInvertColorVar)
 
         self.options.allowRotatingVar = IntVar()
         self.options.allowRotatingVar.set(1)
-        self.optionsmenu.add_checkbutton(label='Allow mirroring/rotating', underline = 6,
+        self.optionsmenu.add_checkbutton(label=_('Allow mirroring/rotating'), underline = 6,
                                          variable=self.options.allowRotatingVar)
 
         self.options.animateSolVar = IntVar()
         self.options.animateSolVar.set(1)
         animSolMenu = Menu(self.optionsmenu)
-        self.optionsmenu.add_cascade(label='Show solution mode', underline = 7, menu=animSolMenu)
-        animSolMenu.add_radiobutton(label='animate', variable = self.options.animateSolVar, value = 1)
-        animSolMenu.add_radiobutton(label='navigate', variable = self.options.animateSolVar, value = 0)
+        self.optionsmenu.add_cascade(label=_('Show solution mode'), underline = 7, menu=animSolMenu)
+        animSolMenu.add_radiobutton(label=_('animate'), variable = self.options.animateSolVar, value = 1)
+        animSolMenu.add_radiobutton(label=_('navigate'), variable = self.options.animateSolVar, value = 0)
 
         self.options.replaySpeedVar = IntVar()
         self.options.replaySpeedVar.set(2)
         replaySp = Menu(self.optionsmenu)
-        self.optionsmenu.add_cascade(label='Replay speed', underline = 0, menu=replaySp)
-        replaySp.add_radiobutton(label='very fast', variable=self.options.replaySpeedVar, value=0)
-        replaySp.add_radiobutton(label='fast', variable=self.options.replaySpeedVar, value=1)
-        replaySp.add_radiobutton(label='medium', variable=self.options.replaySpeedVar, value=2)
-        replaySp.add_radiobutton(label='slow', variable=self.options.replaySpeedVar, value=4)
+        self.optionsmenu.add_cascade(label=_('Replay speed'), underline = 0, menu=replaySp)
+        replaySp.add_radiobutton(label=_('very fast'), variable=self.options.replaySpeedVar, value=0)
+        replaySp.add_radiobutton(label=_('fast'), variable=self.options.replaySpeedVar, value=1)
+        replaySp.add_radiobutton(label=_('medium'), variable=self.options.replaySpeedVar, value=2)
+        replaySp.add_radiobutton(label=_('slow'), variable=self.options.replaySpeedVar, value=4)
 
-        self.optionsmenu.add_command(label='Change clock settings', underline=7, 
+        self.optionsmenu.add_command(label=_('Change clock settings'), underline=7, 
                                      command=self.clock.changeMaxtime)
 
         wrongmenu = Menu(self.optionsmenu)
-        self.optionsmenu.add_cascade(label='Wrong variations', menu=wrongmenu)
+        self.optionsmenu.add_cascade(label=_('Wrong variations'), menu=wrongmenu)
         self.options.wrongVar = IntVar()
         self.options.wrongVar.set(1)
-        wrongmenu.add_radiobutton(label='Show WRONG at the end of variation',
+        wrongmenu.add_radiobutton(label=_('Show WRONG at the end of variation'),
                                          variable=self.options.wrongVar, value=0)
-        wrongmenu.add_radiobutton(label='Show WRONG when entering variation',
+        wrongmenu.add_radiobutton(label=_('Show WRONG when entering variation'),
                                          variable=self.options.wrongVar, value=1)
-        wrongmenu.add_radiobutton(label='Do not descend into wrong variations',
+        wrongmenu.add_radiobutton(label=_('Do not descend into wrong variations'),
                                          variable=self.options.wrongVar, value=2)
 
-        self.optionsmenu.add_command(label='Random/sequential order mode', underline=2,
+        self.optionsmenu.add_command(label=_('Random/sequential order mode'), underline=2,
                                      state=DISABLED)
         self.options.modeVar = IntVar()
         self.options.modeVar.set(0)
 
-        self.optionsmenu.add_checkbutton(label='Use 3D stones', variable=self.options.use3Dstones,
+        self.optionsmenu.add_checkbutton(label=_('Use 3D stones'), variable=self.options.use3Dstones,
                                          command=self.board.resize)
 
         self.helpmenu = Menu(menu, name='help')
-        menu.add_cascade(label='Help', underline=0, menu=self.helpmenu)
+        menu.add_cascade(label=_('Help'), underline=0, menu=self.helpmenu)
 
-        self.helpmenu.add_command(label='About ...', underline=0, command=self.helpAbout)
-        self.helpmenu.add_command(label='Documentation', underline=0, command=self.helpDoc)
-        self.helpmenu.add_command(label='License', underline=0, command=self.helpLicense)
+        self.helpmenu.add_command(label=_('About ...'), underline=0, command=self.helpAbout)
+        self.helpmenu.add_command(label=_('Documentation'), underline=0, command=self.helpDoc)
+        self.helpmenu.add_command(label=_('License'), underline=0, command=self.helpLicense)
 
         # The buttons
 
         bframe = Frame(leftFrame)
         bframe.pack(side=TOP)
 
-        self.backButton = Button(bframe, text='Back', fg='blue', command=self.backProblem,
+        self.backButton = Button(bframe, text=_('Back'), fg='blue', command=self.backProblem,
                                  underline=0)
-        self.restartButton = Button(bframe, text='Re', fg='blue', command=self.restartProblem,
+        self.restartButton = Button(bframe, text=_('Re'), fg='blue', command=self.restartProblem,
                                  underline=0)
-        self.nextButton = Button(bframe, text='Next', fg='blue', command=self.nextProblem,
+        self.nextButton = Button(bframe, text=_('Next'), fg='blue', command=self.nextProblem,
                                  underline = 0)
         self.frame.bind('<n>', lambda e, s=self.nextButton: s.invoke())
         self.frame.bind('<q>', lambda e, self=self: self.quit())
         b1frame.pack(side=TOP)
 
         self.showSolVar = IntVar()
-        self.showSolutionButton = Checkbutton(b1frame, text='Show solution', fg='blue',
+        self.showSolutionButton = Checkbutton(b1frame, text=_('Show solution'), fg='blue',
                                               underline=0,
                                               indicatoron=0, variable=self.showSolVar, command=self.showSolution)
         self.frame.bind('<s>', lambda e, s=self.showSolutionButton: s.invoke())
 
-        self.hintButton = Button(b1frame, text='Hint', command=self.giveHint)
+        self.hintButton = Button(b1frame, text=_('Hint'), command=self.giveHint)
 
         b2frame = Frame(leftFrame)
         b2frame.pack(side=TOP)
 
-        self.undoButton = Button(b2frame, text='Undo', fg='blue', command=self.undo2,
+        self.undoButton = Button(b2frame, text=_('Undo'), fg='blue', command=self.undo2,
                                  underline=0)
         self.frame.bind('<u>', lambda e, s=self.undoButton: s.invoke())
 
         self.tryVarVar = IntVar()
-        self.tryVarButton = Checkbutton(b2frame, text='Try variation', fg='blue', 
+        self.tryVarButton = Checkbutton(b2frame, text=_('Try variation'), fg='blue', 
                                         indicatoron=0, variable=self.tryVarVar, command=self.tryVariation)
         self.frame.bind('<t>', lambda e, s=self.tryVarButton: s.invoke())
 
         # try to load button images
 
         self.tkImages = []
-        try:
-            for button, imageFile in [(self.backButton, 'left'), (self.restartButton, 'reload'),
-                                      (self.nextButton, 'right'), (self.hintButton, 'hint'),
-                                      (self.showSolutionButton, 'showsol'),
-                                      (self.tryVarButton, 'tryvar'), (self.undoButton, 'undo'),
-                                      (self.BbuttonGM, 'b'), (self.WbuttonGM, 'w'), (self.BWbuttonGM, 'bw')]:
-                im = PhotoImage(file = os.path.join(self.uligopath, 'gifs', imageFile+'.gif'))
-                button.config(image=im)
-                self.tkImages.append(im)
-        except (TclError, IOError): pass
-
+        # DO NOT load images, they are untranslatable.
         try:
             im = PhotoImage(file = os.path.join(self.uligopath, 'gifs', 'bgd.gif'))
             self.guessModeCanvas.create_image(75,40, image=im)
 
         self.statisticsWindow = Toplevel()
         self.statisticsWindow.withdraw()
-        self.statisticsWindow.title('Statistics')
+        self.statisticsWindow.title(_('Statistics'))
         self.statisticsText = StringVar()
         Label(self.statisticsWindow, height=10, width=50, justify=LEFT, font = ('Courier', 11),
                textvariable=self.statisticsText).pack()
 
 # ---------------------------------------------------------------------------------------
 
+gettext.bindtextdomain('uligo', './lang')
+gettext.textdomain('uligo')
+
 root = Tk()
 root.withdraw()
 
 try:
     root.option_readfile(os.path.join(sys.path[0], 'uligo.app'))
 except TclError:
-    showwarning('Error', 'Error reading uligo.app')
+    showwarning(_('Error'), _('Error reading uligo.app'))
     
 app = App(root)
 
 root.protocol('WM_DELETE_WINDOW', app.quit)
-root.title('uliGo')
+root.title(_('uliGo'))
 
 root.resizable(1,1)
 
 root.tkraise()
 
 root.mainloop()
+