jetxee / uligo-l10n (http://u-go.net/uligo/)

Some modifications to uliGo 0.3 (Go problem solving app) which enable its localization. Russian translation.

Clone this repository (size: 358.0 KB): HTTPS / SSH
$ hg clone http://bitbucket.org/jetxee/uligo-l10n/
commit 4: 7cdde50a5095
parent 3: a236cf0f5822
branch: default
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
jetxee
12 months ago

Changed (Δ606 bytes):

raw changeset »

clock.py (4 lines added, 2 lines removed)

uligo.py (109 lines added, 115 lines removed)

Up to file-list clock.py:

@@ -25,6 +25,8 @@ from Tkinter import *
25
25
import time
26
26
import math
27
27
import os
28
import gettext
29
_ = gettext.gettext
28
30
29
31
class Clock(Canvas):
30
32
    """ This is a simple stop watch displayed on a Tkinter canvas.
@@ -121,8 +123,8 @@ class Clock(Canvas):
121
123
            Does not work while the clock is running. """
122
124
        if not self.running:
123
125
            window = Toplevel()
124
            window.title("Change time settings")
125
            sc = Scale(window, label='Pick time in seconds (0=off)', length=300,
126
            window.title(_('Change time settings'))
127
            sc = Scale(window, label=_('Pick time in seconds (0=off)'), length=300,
126
128
                       variable = self.maxTime, from_=0, to = 480,
127
129
                       tickinterval = 60, showvalue=YES, orient='horizontal')
128
130
            sc.pack()

Up to file-list uligo.py:

1
1
#!/usr/bin/python
2
# vim: fileencoding=utf-8 ts=4 sw=4 expandtab:
2
3
# File: uligo.py
3
4
4
5
##   This is the main part of uliGo 0.3, a program for practicing
@@ -37,6 +38,9 @@ from string import split
37
38
from math import sqrt
38
39
import webbrowser
39
40
41
import gettext
42
_ = gettext.gettext
43
40
44
from sgfparser import *
41
45
42
46
import clock
@@ -137,35 +141,25 @@ class StatusBar(Frame):
137
141
    
138
142
    def __init__(self, master):
139
143
        p = os.path.join(sys.path[0],'gifs')
140
        try:                                                     # try to load the gif's
141
            self.solved1 = PhotoImage(file=os.path.join(p,'solved1.gif'))
142
            self.solved2 = PhotoImage(file=os.path.join(p,'solved2.gif'))
143
            self.wrong   = PhotoImage(file=os.path.join(p,'wrong.gif'))
144
            self.empty   = PhotoImage(file=os.path.join(p,'empty.gif'))
145
            self.end     = PhotoImage(file=os.path.join(p,'end.gif'))
146
        except TclError:
147
            self.gifsFound = 0
148
        else:
149
            self.gifsFound = 1
150
        Frame.__init__(self, master, height=20, width=65)
144
        # DO NOT load images, they are untranslatable.
145
        self.gifsFound = 0
146
        Frame.__init__(self, master, height=20, width=65, pady=5)
151
147
        self.label = Label(self, bd=1, anchor=W)
152
        if self.gifsFound: self.label.config(image=self.empty)
153
        else:              self.label.config(font=('Helvetica', 24))
154
148
        self.label.pack(fill=X)
155
149
156
150
    def set(self, status=None):
157
151
        if   status == 'solved1':
158
152
            if self.gifsFound: self.label.config(image = self.solved1)
159
            else:              self.label.config(fg='green', text = 'solved!')
153
            else:              self.label.config(fg='DarkGreen', text=_('solved!'), font='24')
160
154
        elif status == 'solved2':
161
155
            if self.gifsFound: self.label.config(image = self.solved2)
162
            else:              self.label.config(fg='blue', text='solved')
156
            else:              self.label.config(fg='blue', text=_('solved'), font='24')
163
157
        elif status == 'wrong':
164
158
            if self.gifsFound: self.label.config(image = self.wrong)
165
            else:              self.label.config(fg='red', text='wrong!')
159
            else:              self.label.config(fg='red', text=_('wrong!'), font='24')
166
160
        elif status == 'end':
167
161
            if self.gifsFound: self.label.config(image = self.end)
168
            else:              self.label.config(fg='red', text='end')
162
            else:              self.label.config(fg='red', text=_('end'), font='24')
169
163
        else                    :
170
164
            if self.gifsFound: self.label.config(image = self.empty)
171
165
            else:              self.label.config(text='')
@@ -266,11 +260,11 @@ class PbmRecord:
266
260
            rightPercentage = ' (' + str(self.noRight*100/self.pbmsAsked) + ' % )'
267
261
            wrongPercentage = ' (' + str(100 - (self.noRight*100/self.pbmsAsked) ) + ' % )'
268
262
        else: rightPercentage = wrongPercentage = ''
269
        return    'Number of problems in database: ' + str(self.noOfPbms) +'\n' \
270
               +  'Number of questions asked     : ' + str(self.pbmsAsked) +'\n' \
271
               +  'Number of right answers       : ' + str(self.noRight) \
263
        return    _('Number of problems in database: ') + str(self.noOfPbms) +'\n' \
264
               +  _('Number of questions asked     : ') + str(self.pbmsAsked) +'\n' \
265
               +  _('Number of right answers       : ') + str(self.noRight) \
272
266
                      + rightPercentage + '\n' \
273
               +  'Number of wrong answers       : ' + str(self.noWrong) \
267
               +  _('Number of wrong answers       : ') + str(self.noWrong) \
274
268
                      + wrongPercentage + '\n' \
275
269
276
270
@@ -304,7 +298,7 @@ class PbmRecord:
304
298
            pickle.dump((self.noOfPbms, self.pbmsAsked, self.noRight, self.noWrong, \
305
299
                         self.current, self.handleCurrent, help, self.list),f)
306
300
            f.close()
307
        except IOError, OSError: showwarning('IO Error', 'Could not write .dat file')
301
        except IOError, OSError: showwarning(_('IO Error'), _('Could not write .dat file'))
308
302
309
303
310
304
    def changeModeQuit(self,w,h1,h2,e):
@@ -332,7 +326,7 @@ class PbmRecord:
332
326
            the problems. """
333
327
        
334
328
        window = Toplevel()
335
        window.title("Order of the problems")
329
        window.title(_('Order of the problems'))
336
330
        f1 = Frame(window)
337
331
        f2 = Frame(window)
338
332
@@ -341,22 +335,22 @@ class PbmRecord:
341
335
342
336
        h1 = IntVar()
343
337
        h1.set(self.modeVar.get())
344
        b1 = Radiobutton(f1, text='Random order', variable=h1, value=0,
338
        b1 = Radiobutton(f1, text=_('Random order'), variable=h1, value=0,
345
339
                         command=lambda e=e: e.config(state=DISABLED))
346
        b2 = Radiobutton(f1, text='Sequential order (keep track of correct/wrong answers)',
340
        b2 = Radiobutton(f1, text=_('Sequential order (keep track of correct/wrong answers)'),
347
341
                         variable=h1, value=1,
348
342
                         command=lambda e=e: e.config(state=DISABLED))
349
        b3 = Radiobutton(f1, text='Sequential order (don\'t record results); start with problem no. ',
343
        b3 = Radiobutton(f1, text=_('Sequential order (don\'t record results); start with problem no. '),
350
344
                         variable=h1, value=2,
351
345
                         command=lambda e=e: e.config(state=NORMAL))
352
346
353
347
        h2 = IntVar()
354
348
        h2.set(0)
355
        c = Checkbutton(f1, text='Use this mode as default', variable = h2)
349
        c = Checkbutton(f1, text=_('Use this mode as default'), variable = h2)
356
350
357
        OKbutton = Button(f2, text='OK',
351
        OKbutton = Button(f2, text=_('OK'),
358
352
                          command = lambda s=self, w=window, h1=h1, h2=h2, e=e: s.changeModeQuit(w, h1, h2, e))
359
        cancelButton = Button(f2, text='Cancel', command=window.destroy)
353
        cancelButton = Button(f2, text=_('Cancel'), command=window.destroy)
360
354
        
361
355
        b1.grid(row=0, column=0, sticky=NW)
362
356
        b2.grid(row=1, column=0, sticky=NW)
@@ -399,7 +393,7 @@ class App:
399
393
            cf = os.path.basename(self.currentFile)
400
394
        else:
401
395
            cf = 'None'
402
        s = 'Database: '+ cf + '\n\n' + s
396
        s = _('Database: ')+ cf + '\n\n' + s
403
397
        self.statisticsText.set(s)
404
398
     
405
399
@@ -545,7 +539,7 @@ class App:
545
539
                self.statusbar.set('empty')
546
540
547
541
        except SGFError:
548
            showwarning('SGF Error', 'Error in SGF file!')
542
            showwarning(_('SGF Error'), _('Error in SGF file!'))
549
543
            return
550
544
551
545
@@ -568,7 +562,7 @@ class App:
568
562
                    self.board.placeMark(self.convCoord(c[color][0], self.orientation),'red')
569
563
                n = n.down
570
564
        except SGFError:
571
            showwarning('SGF Error', 'Error in SGF file!')
565
            showwarning(_('SGF Error'), _('Error in SGF file!'))
572
566
        
573
567
574
568
    def markAll(self):
@@ -585,7 +579,7 @@ class App:
585
579
                self.board.placeMark(self.convCoord(c[color][0], self.orientation),'blue')
586
580
                n = n.down
587
581
        except SGFError:
588
            showwarning('SGF Error', 'Error in SGF file!')
582
            showwarning(_('SGF Error'), _('Error in SGF file!'))
589
583
        
590
584
591
585
    def navSolutionNextMove(self, p):
@@ -622,7 +616,7 @@ class App:
622
616
                        self.cursor.previous()
623
617
        
624
618
        except SGFError:
625
            showwarning('SGF Error', 'Error in SGF file!')
619
            showwarning(_('SGF Error'), _('Error in SGF file!'))
626
620
        
627
621
628
622
    def undo2(self):
@@ -649,7 +643,7 @@ class App:
649
643
                    self.noMovesMade = self.noMovesMade - 1
650
644
651
645
        except SGFError:
652
            showwarning('SGF Error', 'Error in SGF file!')
646
            showwarning(_('SGF Error'), _('Error in SGF file!'))
653
647
        
654
648
655
649
    def undoTryVar(self):
@@ -680,7 +674,7 @@ class App:
680
674
                    self.noMovesMade = self.noMovesMade - 1
681
675
682
676
        except SGFError:
683
            showwarning('SGF Error', 'Error in SGF file!')
677
            showwarning(_('SGF Error'), _('Error in SGF file!'))
684
678
685
679
686
680
    def showSolution(self):
@@ -755,7 +749,7 @@ class App:
755
749
                self.noSolMoves=0
756
750
757
751
        except SGFError:
758
            showwarning('SGF Error', 'Error in SGF file!')
752
            showwarning(_('SGF Error'), _('Error in SGF file!'))
759
753
760
754
761
755
    def giveHint(self):
@@ -805,7 +799,7 @@ class App:
805
799
806
800
            self.board.state('normal', self.nextMove)
807
801
        except SGFError:
808
            showwarning('SGF Error', 'Error in SGF file!')
802
            showwarning(_('SGF Error'), _('Error in SGF file!'))
809
803
810
804
811
805
    def findNextParenthesis(self,s,i):
@@ -858,7 +852,7 @@ class App:
858
852
                s = f.read()
859
853
                f.close()
860
854
            except IOError:
861
                showwarning('Open file', 'Cannot open this file\n')
855
                showwarning(_('Open file'), _('Cannot open this file\n'))
862
856
                return
863
857
        else:
864
858
            self.currentFile = ''
@@ -928,7 +922,7 @@ class App:
928
922
            if self.currentFile: f.write('f '+self.currentFile +'\n')
929
923
            f.close()
930
924
        except IOError:
931
            showwarning('IOError', 'Could not write uligo.def')
925
            showwarning(_('IOError'), _('Could not write uligo.def'))
932
926
933
927
        self.saveOptions()
934
928
        self.frame.quit()
@@ -945,7 +939,7 @@ class App:
945
939
        try:
946
940
            c = EnhancedCursor(self.pbms[n], self.comments)
947
941
        except SGFError:
948
            showwarning('Parsing Error', 'Error in SGF file!')
942
            showwarning(_('Parsing Error'), _('Error in SGF file!'))
949
943
            return
950
944
951
945
        self.statusbar.set('empty')
@@ -962,7 +956,7 @@ class App:
962
956
        try:
963
957
            self.setup(c, ' ('+str(n+1)+')', 1, co, ori) # display problem
964
958
        except SGFError:
965
            showwarning('Parsing Error', 'Error in SGF file!')
959
            showwarning(_('Parsing Error'), _('Error in SGF file!'))
966
960
            return
967
961
968
962
        self.setWhoseTurn(self.inputColor)
@@ -974,15 +968,21 @@ class App:
974
968
975
969
    def setWhoseTurn(self, c):
976
970
        self.whoseTurnCanv.delete(ALL)
971
	x,y,d=65,65,25 # position of the icon and text
977
972
        
973
	# The sentence should be translated as a whole
974
        if c=='B':
975
            color = 'black'
976
	    turnmsg = _('Black to play')
977
        else:
978
	    color = 'white'
979
	    turnmsg = _('White to play')
978
980
        if self.BsTurn:
979
            if c == 'B': self.whoseTurnCanv.create_image(40,50, image=self.BsTurn)
980
            else: self.whoseTurnCanv.create_image(40,50, image=self.WsTurn)
981
            self.whoseTurnCanv.create_text(100,50, text='TO PLAY', font=('Helvetica', 10, 'bold'))
981
            if c == 'B': self.whoseTurnCanv.create_image(x,y, image=self.BsTurn)
982
            else: self.whoseTurnCanv.create_image(x,y, image=self.WsTurn)
982
983
        else:
983
            if c=='B': color = 'black'
984
            else: color = 'white'
985
            self.whoseTurnCanv.create_oval(53,53,78,78,fill=color,outline='')
984
            self.whoseTurnCanv.create_oval(x-d/2,y-d/2,x+d/2,y+d/2,fill=color,outline='black')
985
        self.whoseTurnCanv.create_text(x+3*d,x, text=turnmsg)
986
986
         
987
987
988
988
    def backProblem(self):
@@ -996,7 +996,7 @@ class App:
996
996
            try:
997
997
                c = EnhancedCursor(self.pbms[n], self.comments)
998
998
            except SGFError:
999
                showwarning('Parsing Error', 'Error in SGF file!')
999
                showwarning(_('Parsing Error'), _('Error in SGF file!'))
1000
1000
                return
1001
1001
1002
1002
            self.statusbar.set('empty')
@@ -1013,7 +1013,7 @@ class App:
1013
1013
            try:
1014
1014
                self.setup(c, ' ('+str(n+1)+')', 1, co, ori) # display problem
1015
1015
            except SGFError:
1016
                showwarning('Parsing Error', 'Error in SGF file!')
1016
                showwarning(_('Parsing Error'), _('Error in SGF file!'))
1017
1017
                return
1018
1018
1019
1019
            self.setWhoseTurn(self.inputColor)
@@ -1050,7 +1050,7 @@ class App:
1050
1050
            self.cursor.reset()
1051
1051
            self.setup(self.cursor, ' ('+str(self.pbmRec.current+1)+')', changeOri) # display problem
1052
1052
        except SGFError:
1053
            showwarning('Parsing Error', 'Error in SGF file!')
1053
            showwarning(_('Parsing Error'), _('Error in SGF file!'))
1054
1054
            return
1055
1055
1056
1056
        self.setWhoseTurn(self.inputColor)
@@ -1111,7 +1111,7 @@ class App:
1111
1111
        try:
1112
1112
            os.remove(os.path.join(path, filename))
1113
1113
        except IOError:
1114
            showwarning('I/O Error', 'Could not delete .dat file.')
1114
            showwarning(_('I/O Error'), _('Could not delete .dat file.'))
1115
1115
1116
1116
        self.pbmRec = None
1117
1117
        self.readProblemColl(path, filename[:-4]+'.sgf')
@@ -1194,7 +1194,7 @@ class App:
1194
1194
                self.board.state('disabled')
1195
1195
1196
1196
        except SGFError:
1197
            showwarning('SGF Error', 'Error in SGF file!')
1197
            showwarning(_('SGF Error'), _('Error in SGF file!'))
1198
1198
            
1199
1199
            
1200
1200
    def restartGM(self):
@@ -1254,7 +1254,7 @@ class App:
1254
1254
                s = f.read()
1255
1255
                f.close()
1256
1256
            except IOError:
1257
                showwarning('Open file', 'Cannot open this file\n')
1257
                showwarning(_('Open file'), _('Cannot open this file\n'))
1258
1258
1259
1259
            self.board.clear()
1260
1260
            self.board.delMarks()
@@ -1283,7 +1283,7 @@ class App:
1283
1283
            cursor = EnhancedCursor(s, self.comments)
1284
1284
            self.setup(cursor, '', 0, self.invertColor, self.orientation)
1285
1285
        except SGFError:
1286
            showwarning('Parsing Error', 'Error in SGF file!')
1286
            showwarning(_('Parsing Error'), _('Error in SGF file!'))
1287
1287
            return
1288
1288
        
1289
1289
        self.whoseTurnCanv.delete(ALL)
@@ -1296,7 +1296,7 @@ class App:
1296
1296
                if d.has_key(tag): self.gameInfoCanv.create_text(10, 20+20*i, text=label+d[tag][0], anchor='w')
1297
1297
                i += 1
1298
1298
        except SGFError:
1299
            showwarning('SGF Error', 'Error in SGF file!')
1299
            showwarning(_('SGF Error'), _('Error in SGF file!'))
1300
1300
            return
1301
1301
        
1302
1302
        self.changeModeGM()
@@ -1350,7 +1350,7 @@ class App:
1350
1350
                self.board.undo()                                         # then delete it
1351
1351
                self.guessFailure(right_pos, (x,y))
1352
1352
        except SGFError:
1353
            showwarning('SGF Error', 'Error in SGF file!')
1353
            showwarning(_('SGF Error'), _('Error in SGF file!'))
1354
1354
            
1355
1355
1356
1356
    def guessSuccess(self):
@@ -1368,7 +1368,7 @@ class App:
1368
1368
        self.guessModeCanvas.create_text(110, 40, text = `perc` + '%', tags='non-bg')
1369
1369
        
1370
1370
        if self.cursor.atEnd:
1371
            self.guessModeCanvas.create_text(40, 40, text = 'END', font=('Helvetica', 16), tags='non-bg')
1371
            self.guessModeCanvas.create_text(40, 40, text = _('END'), font=('Helvetica', 16), tags='non-bg')
1372
1372
1373
1373
1374
1374
    def guessFailure(self, right, pos):
@@ -1386,7 +1386,7 @@ class App:
1386
1386
                           100.0/(self.guessRightWrong[0] + self.guessRightWrong[1]))
1387
1387
                self.guessModeCanvas.create_text(110, 40, text = `perc` + '%', tags='non-bg')
1388
1388
            except ZeroDivisionError: pass
1389
            self.guessModeCanvas.create_text(40, 40, text = 'END', font=('Helvetica', 16), tags='non-bg')
1389
            self.guessModeCanvas.create_text(40, 40, text = _('END'), font=('Helvetica', 16), tags='non-bg')
1390
1390
            return
1391
1391
1392
1392
        if not right or not pos:
@@ -1425,7 +1425,7 @@ class App:
1425
1425
        self.options.windowGeom = StringVar()
1426
1426
        self.options.windowGeom.set(self.master.geometry())
1427
1427
        self.options.saveToDisk(os.path.join(self.optionspath,'uligo.opt'),
1428
                                lambda: showwarning('Save options', 'IO Error'))
1428
                                lambda: showwarning(_('Save options'), _('IO Error')))
1429
1429
1430
1430
        
1431
1431
    def loadOptions(self):
@@ -1451,7 +1451,7 @@ class App:
1451
1451
        t = t + 'The images of the board and the stones were created by Patrice Fontaine.'
1452
1452
        
1453
1453
        window = Toplevel()
1454
        window.title('About uliGo ...')
1454
        window.title(_('About uliGo ...'))
1455
1455
1456
1456
        canv = Canvas(window, width=400,height=200, highlightthickness=0)
1457
1457
        canv.pack()
@@ -1463,7 +1463,7 @@ class App:
1463
1463
        text.config(state=DISABLED)
1464
1464
        text.pack()
1465
1465
1466
        b = Button(window, text="OK", command = window.destroy)
1466
        b = Button(window, text=_("OK"), command = window.destroy)
1467
1467
        b.pack(side=RIGHT)
1468
1468
        
1469
1469
        window.update_idletasks()
@@ -1512,7 +1512,7 @@ class App:
1512
1512
        text.config(state=DISABLED)
1513
1513
        text.pack()
1514
1514
1515
        b = Button(window, text="OK", command = window.destroy)
1515
        b = Button(window, text=_("OK"), command = window.destroy)
1516
1516
        b.pack(side=RIGHT)
1517
1517
        
1518
1518
        window.update_idletasks()
@@ -1559,7 +1559,7 @@ class App:
1559
1559
        self.guessModeCanvas = Canvas(self.clockFrame, height=80, width=150)
1560
1560
        self.options.modeVarGM = StringVar()
1561
1561
        self.options.modeVarGM.set('BW')
1562
        Label(self.guessModeButtonFrame, text='Guess ').pack(side=LEFT, expand=NO)
1562
        Label(self.guessModeButtonFrame, text=_('Guess ')).pack(side=LEFT, expand=NO)
1563
1563
        self.BbuttonGM = Radiobutton(self.guessModeButtonFrame, text='B', variable=self.options.modeVarGM,
1564
1564
                                     indicatoron=0,
1565
1565
                                     command=self.changeModeGM, value='B')
@@ -1578,91 +1578,91 @@ class App:
1578
1578
        master.config(menu=menu)
1579
1579
1580
1580
        filemenu = Menu(menu)
1581
        menu.add_cascade(label='File', underline=0, menu=filemenu)
1582
        filemenu.add_command(label='Open problem collection ...', underline=0, command=self.readProblemColl)
1583
        filemenu.add_command(label='Replay game', underline=0, command=self.replayGame)
1581
        menu.add_cascade(label=_('File'), underline=0, menu=filemenu)
1582
        filemenu.add_command(label=_('Open problem collection ...'), underline=0, command=self.readProblemColl)
1583
        filemenu.add_command(label=_('Replay game'), underline=0, command=self.replayGame)
1584
1584
        filemenu.add_separator()
1585
        filemenu.add_command(label='Clear Statistics', underline=0, command=self.clearStatistics)
1586
        filemenu.add_command(label='Statistics', underline=0, command=self.printStatistics)
1585
        filemenu.add_command(label=_('Clear Statistics'), underline=0, command=self.clearStatistics)
1586
        filemenu.add_command(label=_('Statistics'), underline=0, command=self.printStatistics)
1587
1587
        filemenu.add_separator()
1588
        filemenu.add_command(label='Exit', underline =1, command=self.quit)
1588
        filemenu.add_command(label=_('Exit'), underline =1, command=self.quit)
1589
1589
        self.optionsmenu = Menu(menu)
1590
        menu.add_cascade(label='Options', underline=0, menu=self.optionsmenu)
1590
        menu.add_cascade(label=_('Options'), underline=0, menu=self.optionsmenu)
1591
1591
1592
1592
        self.options.fuzzy = self.board.fuzzy    # make 'save options' easy
1593
        self.optionsmenu.add_checkbutton(label='Fuzzy stone placement', underline = 0, 
1593
        self.optionsmenu.add_checkbutton(label=_('Fuzzy stone placement'), underline = 0, 
1594
1594
                                         variable=self.options.fuzzy, command=self.board.fuzzyStones)
1595
1595
1596
1596
        self.options.shadedStoneVar = self.board.shadedStoneVar
1597
1597
        self.options.shadedStoneVar.set(1)
1598
        self.optionsmenu.add_checkbutton(label='Shaded stone mouse pointer', underline = 0, 
1598
        self.optionsmenu.add_checkbutton(label=_('Shaded stone mouse pointer'), underline = 0, 
1599
1599
                                         variable=self.options.shadedStoneVar)
1600
1600
1601
1601
        self.options.allowInvertColorVar = IntVar()
1602
1602
        self.options.allowInvertColorVar.set(1)
1603
        self.optionsmenu.add_checkbutton(label='Allow color switch', underline = 7, 
1603
        self.optionsmenu.add_checkbutton(label=_('Allow color switch'), underline = 7, 
1604
1604
                                         variable=self.options.allowInvertColorVar)
1605
1605
1606
1606
        self.options.allowRotatingVar = IntVar()
1607
1607
        self.options.allowRotatingVar.set(1)
1608
        self.optionsmenu.add_checkbutton(label='Allow mirroring/rotating', underline = 6,
1608
        self.optionsmenu.add_checkbutton(label=_('Allow mirroring/rotating'), underline = 6,
1609
1609
                                         variable=self.options.allowRotatingVar)
1610
1610
1611
1611
        self.options.animateSolVar = IntVar()
1612
1612
        self.options.animateSolVar.set(1)
1613
1613
        animSolMenu = Menu(self.optionsmenu)
1614
        self.optionsmenu.add_cascade(label='Show solution mode', underline = 7, menu=animSolMenu)
1615
        animSolMenu.add_radiobutton(label='animate', variable = self.options.animateSolVar, value = 1)
1616
        animSolMenu.add_radiobutton(label='navigate', variable = self.options.animateSolVar, value = 0)
1614
        self.optionsmenu.add_cascade(label=_('Show solution mode'), underline = 7, menu=animSolMenu)
1615
        animSolMenu.add_radiobutton(label=_('animate'), variable = self.options.animateSolVar, value = 1)
1616
        animSolMenu.add_radiobutton(label=_('navigate'), variable = self.options.animateSolVar, value = 0)
1617
1617
1618
1618
        self.options.replaySpeedVar = IntVar()
1619
1619
        self.options.replaySpeedVar.set(2)
1620
1620
        replaySp = Menu(self.optionsmenu)
1621
        self.optionsmenu.add_cascade(label='Replay speed', underline = 0, menu=replaySp)
1622
        replaySp.add_radiobutton(label='very fast', variable=self.options.replaySpeedVar, value=0)
1623
        replaySp.add_radiobutton(label='fast', variable=self.options.replaySpeedVar, value=1)
1624
        replaySp.add_radiobutton(label='medium', variable=self.options.replaySpeedVar, value=2)
1625
        replaySp.add_radiobutton(label='slow', variable=self.options.replaySpeedVar, value=4)
1621
        self.optionsmenu.add_cascade(label=_('Replay speed'), underline = 0, menu=replaySp)
1622
        replaySp.add_radiobutton(label=_('very fast'), variable=self.options.replaySpeedVar, value=0)
1623
        replaySp.add_radiobutton(label=_('fast'), variable=self.options.replaySpeedVar, value=1)
1624
        replaySp.add_radiobutton(label=_('medium'), variable=self.options.replaySpeedVar, value=2)
1625
        replaySp.add_radiobutton(label=_('slow'), variable=self.options.replaySpeedVar, value=4)
1626
1626
1627
        self.optionsmenu.add_command(label='Change clock settings', underline=7, 
1627
        self.optionsmenu.add_command(label=_('Change clock settings'), underline=7, 
1628
1628
                                     command=self.clock.changeMaxtime)
1629
1629
1630
1630
        wrongmenu = Menu(self.optionsmenu)
1631
        self.optionsmenu.add_cascade(label='Wrong variations', menu=wrongmenu)
1631
        self.optionsmenu.add_cascade(label=_('Wrong variations'), menu=wrongmenu)
1632
1632
        self.options.wrongVar = IntVar()
1633
1633
        self.options.wrongVar.set(1)
1634
        wrongmenu.add_radiobutton(label='Show WRONG at the end of variation',
1634
        wrongmenu.add_radiobutton(label=_('Show WRONG at the end of variation'),
1635
1635
                                         variable=self.options.wrongVar, value=0)
1636
        wrongmenu.add_radiobutton(label='Show WRONG when entering variation',
1636
        wrongmenu.add_radiobutton(label=_('Show WRONG when entering variation'),
1637
1637
                                         variable=self.options.wrongVar, value=1)
1638
        wrongmenu.add_radiobutton(label='Do not descend into wrong variations',
1638
        wrongmenu.add_radiobutton(label=_('Do not descend into wrong variations'),
1639
1639
                                         variable=self.options.wrongVar, value=2)
1640
1640
1641
        self.optionsmenu.add_command(label='Random/sequential order mode', underline=2,
1641
        self.optionsmenu.add_command(label=_('Random/sequential order mode'), underline=2,
1642
1642
                                     state=DISABLED)
1643
1643
        self.options.modeVar = IntVar()
1644
1644
        self.options.modeVar.set(0)
1645
1645
1646
        self.optionsmenu.add_checkbutton(label='Use 3D stones', variable=self.options.use3Dstones,
1646
        self.optionsmenu.add_checkbutton(label=_('Use 3D stones'), variable=self.options.use3Dstones,
1647
1647
                                         command=self.board.resize)
1648
1648
1649
1649
        self.helpmenu = Menu(menu, name='help')
1650
        menu.add_cascade(label='Help', underline=0, menu=self.helpmenu)
1650
        menu.add_cascade(label=_('Help'), underline=0, menu=self.helpmenu)
1651
1651
1652
        self.helpmenu.add_command(label='About ...', underline=0, command=self.helpAbout)
1653
        self.helpmenu.add_command(label='Documentation', underline=0, command=self.helpDoc)
1654
        self.helpmenu.add_command(label='License', underline=0, command=self.helpLicense)
1652
        self.helpmenu.add_command(label=_('About ...'), underline=0, command=self.helpAbout)
1653
        self.helpmenu.add_command(label=_('Documentation'), underline=0, command=self.helpDoc)
1654
        self.helpmenu.add_command(label=_('License'), underline=0, command=self.helpLicense)
1655
1655
1656
1656
        # The buttons
1657
1657
1658
1658
        bframe = Frame(leftFrame)
1659
1659
        bframe.pack(side=TOP)
1660
1660
1661
        self.backButton = Button(bframe, text='Back', fg='blue', command=self.backProblem,
1661
        self.backButton = Button(bframe, text=_('Back'), fg='blue', command=self.backProblem,
1662
1662
                                 underline=0)
1663
        self.restartButton = Button(bframe, text='Re', fg='blue', command=self.restartProblem,
1663
        self.restartButton = Button(bframe, text=_('Re'), fg='blue', command=self.restartProblem,
1664
1664
                                 underline=0)
1665
        self.nextButton = Button(bframe, text='Next', fg='blue', command=self.nextProblem,
1665
        self.nextButton = Button(bframe, text=_('Next'), fg='blue', command=self.nextProblem,
1666
1666
                                 underline = 0)
1667
1667
        self.frame.bind('<n>', lambda e, s=self.nextButton: s.invoke())
1668
1668
        self.frame.bind('<q>', lambda e, self=self: self.quit())
@@ -1676,22 +1676,22 @@ class App:
1676
1676
        b1frame.pack(side=TOP)
1677
1677
1678
1678
        self.showSolVar = IntVar()
1679
        self.showSolutionButton = Checkbutton(b1frame, text='Show solution', fg='blue',
1679
        self.showSolutionButton = Checkbutton(b1frame, text=_('Show solution'), fg='blue',
1680
1680
                                              underline=0,
1681
1681
                                              indicatoron=0, variable=self.showSolVar, command=self.showSolution)
1682
1682
        self.frame.bind('<s>', lambda e, s=self.showSolutionButton: s.invoke())
1683
1683
1684
        self.hintButton = Button(b1frame, text='Hint', command=self.giveHint)
1684
        self.hintButton = Button(b1frame, text=_('Hint'), command=self.giveHint)
1685
1685
1686
1686
        b2frame = Frame(leftFrame)
1687
1687
        b2frame.pack(side=TOP)
1688
1688
1689
        self.undoButton = Button(b2frame, text='Undo', fg='blue', command=self.undo2,
1689
        self.undoButton = Button(b2frame, text=_('Undo'), fg='blue', command=self.undo2,
1690
1690
                                 underline=0)
1691
1691
        self.frame.bind('<u>', lambda e, s=self.undoButton: s.invoke())
1692
1692
1693
1693
        self.tryVarVar = IntVar()
1694
        self.tryVarButton = Checkbutton(b2frame, text='Try variation', fg='blue', 
1694
        self.tryVarButton = Checkbutton(b2frame, text=_('Try variation'), fg='blue', 
1695
1695
                                        indicatoron=0, variable=self.tryVarVar, command=self.tryVariation)
1696
1696
        self.frame.bind('<t>', lambda e, s=self.tryVarButton: s.invoke())
1697
1697
@@ -1720,17 +1720,7 @@ class App:
1720
1720
        # try to load button images
1721
1721
1722
1722
        self.tkImages = []
1723
        try:
1724
            for button, imageFile in [(self.backButton, 'left'), (self.restartButton, 'reload'),
1725
                                      (self.nextButton, 'right'), (self.hintButton, 'hint'),
1726
                                      (self.showSolutionButton, 'showsol'),
1727
                                      (self.tryVarButton, 'tryvar'), (self.undoButton, 'undo'),
1728
                                      (self.BbuttonGM, 'b'), (self.WbuttonGM, 'w'), (self.BWbuttonGM, 'bw')]:
1729
                im = PhotoImage(file = os.path.join(self.uligopath, 'gifs', imageFile+'.gif'))
1730
                button.config(image=im)
1731
                self.tkImages.append(im)
1732
        except (TclError, IOError): pass
1733
1723
        # DO NOT load images, they are untranslatable.
1734
1724
        try:
1735
1725
            im = PhotoImage(file = os.path.join(self.uligopath, 'gifs', 'bgd.gif'))
1736
1726
            self.guessModeCanvas.create_image(75,40, image=im)
@@ -1773,7 +1763,7 @@ class App:
1773
1763
1774
1764
        self.statisticsWindow = Toplevel()
1775
1765
        self.statisticsWindow.withdraw()
1776
        self.statisticsWindow.title('Statistics')
1766
        self.statisticsWindow.title(_('Statistics'))
1777
1767
        self.statisticsText = StringVar()
1778
1768
        Label(self.statisticsWindow, height=10, width=50, justify=LEFT, font = ('Courier', 11),
1779
1769
               textvariable=self.statisticsText).pack()
@@ -1857,18 +1847,21 @@ class App:
1857
1847
1858
1848
# ---------------------------------------------------------------------------------------
1859
1849
1850
gettext.bindtextdomain('uligo', './lang')
1851
gettext.textdomain('uligo')
1852
1860
1853
root = Tk()
1861
1854
root.withdraw()
1862
1855
1863
1856
try:
1864
1857
    root.option_readfile(os.path.join(sys.path[0], 'uligo.app'))
1865
1858
except TclError:
1866
    showwarning('Error', 'Error reading uligo.app')
1859
    showwarning(_('Error'), _('Error reading uligo.app'))
1867
1860
    
1868
1861
app = App(root)
1869
1862
1870
1863
root.protocol('WM_DELETE_WINDOW', app.quit)
1871
root.title('uliGo')
1864
root.title(_('uliGo'))
1872
1865
1873
1866
root.resizable(1,1)
1874
1867
@@ -1876,3 +1869,4 @@ app.frame.focus_force()
1876
1869
root.tkraise()
1877
1870
1878
1871
root.mainloop()
1872