2 # -*- coding: utf-8 -*-
4 # Copyright 2003, 2004 Zuza Software Foundation
6 # This file is part of the translate-toolkit
8 # translate is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
13 # translate is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with translate; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 """tool for building multilingual openoffice.org setup files"""
25 from translate
.misc
import sparse
29 from translate
import __version__
39 class SetupParser(sparse
.SimpleParser
):
41 sparse
.SimpleParser
.__init
__(self
)
42 self
.defaulttokenlist
.extend(';\n')
43 self
.whitespacechars
= " \t\r"
44 self
.quotechars
= ('"', '{')
45 self
.endquotechars
= {'"':'"', '{':'}'}
46 self
.stringescaping
= 0
47 self
.sectiontypes
= ('ConfigurationItem', 'Custom', 'DataCarrier', 'Directory',
48 'File', 'Folder', 'FolderItem', 'Function', 'HelpText', 'Installation', 'Module', 'Procedure',
49 'Profile', 'ProfileItem', 'RegistryItem', 'Shortcut', 'StarRegistry', 'StarRegistryItem')
53 # insert after the given tokennums
55 for sectiontype
in self
.sectiontypes
:
56 self
.bytype
[sectiontype
] = {}
58 def parse(self
, contents
):
59 self
.tokenize(contents
)
60 self
.originaltokens
= self
.tokens
[:]
62 while tokennum
< len(self
.tokens
):
63 tokennum
= self
.parsesection(tokennum
)
65 def parsesection(self
, tokennum
):
66 sectiontype
= self
.tokens
[tokennum
]
67 if sectiontype
not in self
.sectiontypes
:
68 print >>sys
.stderr
, "unknown sectiontype....", sectiontype
69 if sectiontype
not in self
.bytype
:
70 self
.bytype
[sectiontype
] = {}
71 sectionname
= self
.tokens
[tokennum
+ 1]
73 if sectionname
in self
.definitions
:
74 print >>sys
.stderr
, "duplicate", sectionname
75 self
.definitions
[sectionname
] = section
76 self
.bytype
[sectiontype
][sectionname
] = section
77 section
['type'] = sectiontype
78 section
['tokennums'] = {'start':tokennum
}
80 while self
.tokens
[tokennum
] == '\n':
82 while self
.tokens
[tokennum
].lower() != 'end':
83 varname
= self
.tokens
[tokennum
]
84 if self
.tokens
[tokennum
+1] != '=':
85 print >>sys
.stderr
, "expected =...", sectiontype
, sectionname
, varname
86 startvardef
= tokennum
+2
88 while self
.tokens
[tokennum
] != '\n' or nestlevel
> 0:
89 varpart
= self
.tokens
[tokennum
]
90 if varpart
.lower().startswith('gid_'):
91 self
.referrals
.append((varpart
, tokennum
))
97 value
= "".join(self
.tokens
[startvardef
:tokennum
])
98 if value
.endswith(";"): value
= value
[:-1]
99 section
[varname
] = value
100 section
['tokennums'][varname
] = startvardef
- section
['tokennums']['start']
101 section
['tokennums'][varname
+" end"] = tokennum
- section
['tokennums']['start']
102 tokennum
= tokennum
+ 1
103 section
['tokennums']['end'] = tokennum
- section
['tokennums']['start']
105 while tokennum
< len(self
.tokens
) and self
.tokens
[tokennum
] == '\n':
109 def rename(self
, sectionname
, newname
):
110 section
= self
.definitions
[sectionname
]
111 tokennum
= section
['tokennums']['start']
112 self
.tokens
[tokennum
+1] = newname
113 for varpart
, tokennum
in self
.referrals
:
114 if varpart
.lower() == sectionname
.lower():
115 self
.tokens
[tokennum
] = newname
117 def insertforeignsection(self
, aftersection
, sectionname
, section
, index
, tokenrange
):
118 tokennum
= self
.getsectionendtokennum(aftersection
)
119 while self
.tokens
[tokennum
+1] == '\n':
121 self
.definitions
[sectionname
] = copy
.deepcopy(section
)
122 self
.definitions
[sectionname
]['tokennums']['start'] = tokennum
123 if tokennum
in self
.insertions
:
124 self
.insertions
[tokennum
].append((index
, tokenrange
))
126 self
.insertions
[tokennum
] = [(index
, tokenrange
)]
128 def insertforeignvalue(self
, sectionname
, index
, tokenrange
):
129 tokennum
= self
.getsectionendtokennum(sectionname
) - 1
130 if self
.tokens
[tokennum
] == "\n":
132 if tokennum
in self
.insertions
:
133 self
.insertions
[tokennum
].append((index
, tokenrange
))
135 self
.insertions
[tokennum
] = [(index
, tokenrange
)]
137 def getsource(self
, start
=None, end
=None):
142 end
= len(self
.tokens
)
144 for tokennum
in range(start
+1):
145 tokenpos
= self
.source
.find(self
.originaltokens
[tokennum
], tokenpos
)
146 for tokennum
in range(start
, end
):
147 originaltoken
= self
.originaltokens
[tokennum
]
148 nexttokenpos
= self
.source
.find(originaltoken
, tokenpos
)
149 sourceparts
.append(self
.source
[tokenpos
:nexttokenpos
])
150 sourceparts
.append(self
.tokens
[tokennum
])
151 tokenpos
= nexttokenpos
+ len(originaltoken
)
152 if tokennum
in self
.insertions
:
153 for index
, tokenrange
in self
.insertions
[tokennum
]:
154 foreignstart
, foreignend
= tokenrange
155 foreignsource
= index
.getsource(foreignstart
, foreignend
)
156 sourceparts
.append(foreignsource
)
157 if end
== len(self
.tokens
):
158 sourceparts
.append(self
.source
[tokenpos
:end
])
159 return "".join(sourceparts
)
161 def getfieldvalue(self
, sectionname
, fieldname
, default
=None):
162 section
= self
.definitions
[sectionname
]
163 return section
.get(fieldname
, default
)
165 def getfieldtokennum(self
, sectionname
, fieldname
):
166 section
= self
.definitions
[sectionname
]
167 return section
['tokennums'][fieldname
] + section
['tokennums']['start']
169 def getsectionendtokennum(self
, sectionname
):
170 section
= self
.definitions
[sectionname
]
171 return section
['tokennums']['end'] + section
['tokennums']['start']
173 def setfieldvalue(self
, sectionname
, fieldname
, fieldvalue
):
174 fieldtokennum
= self
.getfieldtokennum(sectionname
, fieldname
)
175 self
.tokens
[fieldtokennum
] = fieldvalue
177 def renamefield(self
, sectionname
, fieldname
, newfieldname
):
178 fieldtokennum
= self
.getfieldtokennum(sectionname
, fieldname
)
179 self
.tokens
[fieldtokennum
- 2] = newfieldname
181 def getsectiontokenrange(self
, sectionname
):
182 section
= self
.definitions
[sectionname
]
183 start
, end
= section
['tokennums']['start'], section
['tokennums']['end']+1
184 while self
.tokens
[start
+end
] == '\n' and start
+end
< len(self
.tokens
)-1:
186 return (start
, start
+end
)
188 def getfieldtokenrange(self
, sectionname
, fieldname
):
189 section
= self
.definitions
[sectionname
]
190 sectionstart
= section
['tokennums']['start']
191 start
, end
= section
['tokennums'][fieldname
]-2, section
['tokennums'][fieldname
+' end']
192 while self
.tokens
[sectionstart
+end
] == '\n' and sectionstart
+end
< len(self
.tokens
)-1:
194 if self
.tokens
[sectionstart
+start
-1] == '\n' and start
> 0:
196 if self
.tokens
[sectionstart
+end
-1] == '\n':
198 return (sectionstart
+start
, sectionstart
+end
)
200 def getmoduleentrytokennum(self
, modulename
, fileentry
):
201 start
, end
= self
.getsectiontokenrange(modulename
)
202 for tokennum
in range(start
, end
):
203 if self
.originaltokens
[tokennum
] == fileentry
:
207 class SetupIndex(SetupParser
):
208 def __init__(self
, filename
=None):
209 SetupParser
.__init
__(self
)
210 self
.manualfiles
= []
211 self
.filemodules
= {}
212 self
.directorychildren
= {}
213 self
.directoryfiles
= {}
214 if filename
is not None:
215 self
.readfile(filename
)
217 def readfile(self
, filename
):
218 self
.filename
= filename
219 # f = codecs.open(self.filename, 'r', encoding='utf8')
220 f
= open(self
.filename
, 'r')
225 def parse(self
, contents
):
226 SetupParser
.parse(self
, contents
)
227 self
.languagename
= sparse
.stringeval(self
.getfieldvalue('gid_Dir_Config_Language', 'HostName'))
228 self
.isocode
= sparse
.stringeval(self
.getfieldvalue('gid_Dir_Share_Registry_Res_Lang', 'HostName'))
229 if self
.isocode
.find("-") == -1:
230 self
.shortisocode
= self
.isocode
232 self
.shortisocode
= self
.isocode
[:self
.isocode
.find("-")]
233 self
.dialingcode
= sparse
.stringeval(self
.getfieldvalue('gid_Installation', 'DefaultLanguage'))
235 def keymunge(self
, keyname
):
236 """munges a keyname and removes invalid entries"""
237 return keyname
.replace("-", "_")
239 def islocalizefile(self
, filename
):
240 """returns whether a file is part of localization"""
241 # handle resource files
242 if filename
.endswith("%s.res" % self
.dialingcode
):
244 # handle README and LICENSE files
245 if filename
in [(template
% self
.dialingcode
) for template
in \
246 ("README%s", "LICENSE%s", "README%s.html", "LICENSE%s.html")]:
248 # everything else is normal...
251 def merge(self
, otherindexes
):
252 """merges this with another index... hmmm ...."""
253 indexes
= [self
] + otherindexes
254 languages
= [index
.getfieldvalue('gid_Installation', 'Languages') for index
in indexes
]
255 languages
= [sparse
.stringeval(languagevalues
).split(",") for languagevalues
in languages
]
256 languages
= reduce(operator
.add
, languages
)
258 languages
= ",".join(languages
)
259 # support for Languages is needed in setup2/source/ui/pages/plang.*
260 self
.setfieldvalue('gid_Installation', 'Languages', '"%s"' % languages
)
261 directoriestorename
= {}
262 for index
in indexes
:
263 for directory
in index
.bytype
["Directory"]:
264 hostname
= index
.getfieldvalue(directory
, 'HostName')
265 hostname
= sparse
.stringeval(hostname
)
266 if hostname
in (index
.languagename
, index
.isocode
, index
.shortisocode
):
267 directoriestorename
[directory
] = 1
268 parentid
= index
.getfieldvalue(directory
, 'ParentID')
269 if parentid
not in index
.directorychildren
:
270 index
.directorychildren
[parentid
] = [directory
]
272 index
.directorychildren
[parentid
].append(directory
)
273 # make sure that if a directory is renamed, all its child directories are too...
277 for directory
in directoriestorename
.keys():
278 for child
in index
.directorychildren
.get(directory
, []):
279 if not child
in directoriestorename
:
280 directoriestorename
[child
] = 1
282 # make an index of which files go in which directory
283 for fileentry
in index
.bytype
["File"]:
284 directory
= index
.getfieldvalue(fileentry
, 'Dir')
285 if directory
not in index
.directoryfiles
:
286 index
.directoryfiles
[directory
] = [fileentry
]
288 index
.directoryfiles
[directory
].append(fileentry
)
289 # make an index of which modules files belong to...
290 for module
in index
.bytype
["Module"]:
291 filelist
= index
.getfieldvalue(module
, 'Files', None)
293 # not all modules have a file list
295 filelist
= [fileentry
.strip() for fileentry
in filelist
[1:-1].split(",")]
296 for fileentry
in filelist
:
297 if fileentry
not in index
.filemodules
:
298 index
.filemodules
[fileentry
] = [module
]
300 index
.filemodules
[fileentry
].append(module
)
301 for index
in indexes
:
302 suffix
= self
.keymunge("_" + index
.isocode
)
303 for directory
in directoriestorename
:
304 if directory
.find('_Language') != -1:
305 newname
= directory
.replace("_Language", suffix
)
306 elif directory
.find('_Lang') != -1:
307 newname
= directory
.replace("_Lang", suffix
)
308 elif directory
.find('_Isolanguage') != -1:
309 newname
= directory
.replace("_Isolanguage", suffix
)
310 else: newname
= directory
+ suffix
311 index
.renamedirectory(directory
, newname
, suffix
)
313 directorysection
= index
.definitions
[directory
]
314 tokenrange
= index
.getsectiontokenrange(directory
)
315 self
.insertforeignsection(directory
, newname
, directorysection
, index
, tokenrange
)
316 if directory
in index
.directoryfiles
:
317 for fileentry
in index
.directoryfiles
[directory
]:
318 self
.addforeignfile(index
, fileentry
, suffix
)
319 for fileentry
in index
.bytype
["File"]:
320 filename
= sparse
.stringeval(index
.getfieldvalue(fileentry
, 'Name'))
321 if index
.islocalizefile(filename
):
322 index
.rename(fileentry
, fileentry
+ suffix
)
323 packedname
= sparse
.stringeval(index
.getfieldvalue(fileentry
, "PackedName"))
324 newpackedname
= packedname
+ suffix
325 index
.setfieldvalue(fileentry
, "PackedName", '"%s"' % newpackedname
)
327 self
.addforeignfile(index
, fileentry
, suffix
)
328 for configitem
in index
.bytype
["ConfigurationItem"]:
329 key
= sparse
.stringeval(index
.getfieldvalue(configitem
, 'Key'))
330 # TODO: when <sequence_languages> is working correctly, remove this code - i#33113
331 # if configitem == "gid_Configurationitem_Setup_Office_Locales":
332 # wierdness. the setup program will put in a comma-separated attribute if its all alpha
333 # but if there's a - it won't, so we need to check for this...
334 # isocodes = ",".join([eachindex.isocode for eachindex in indexes if eachindex.isocode.isalpha()])
335 # index.setfieldvalue(configitem, "Value", '"%s"' % isocodes)
336 if key
== index
.isocode
:
337 index
.rename(configitem
, configitem
+ suffix
)
339 self
.addforeignconfigitem(index
, configitem
, suffix
)
340 for helpitem
in index
.bytype
["HelpText"]:
341 index
.renamefield(helpitem
, "Text", "Text(%s)" % index
.dialingcode
)
343 self
.addforeignhelptext(index
, helpitem
)
344 for moduleitem
in index
.bytype
["Module"]:
345 index
.renamefield(moduleitem
, "Name", "Name(%s)" % index
.dialingcode
)
346 index
.renamefield(moduleitem
, "Description", "Description(%s)" % index
.dialingcode
)
348 self
.addforeignmoduletext(index
, moduleitem
)
350 def addmanualshortcut(self
, shortcutentry
, fileentry
, iconid
, baseentry
):
351 """Inserts a manual shortcut into the build system"""
352 shortcutsectionlines
= ["FolderItem %s" % shortcutentry
]
353 def addparam(paramname
, paramstr
):
354 shortcutsectionlines
.append(" %s%s = %s;" % (paramname
, " "*(16-len(paramname
)), paramstr
))
355 addparam("ModuleID", self
.getfieldvalue(baseentry
, "ModuleID"))
356 addparam("Name", '"Change language"')
357 addparam("FolderID", self
.getfieldvalue(baseentry
, "FolderID"))
358 addparam("FileID", fileentry
)
359 addparam("IconFile", fileentry
)
360 addparam("IconID", "%d" % iconid
)
361 addparam("Styles", self
.getfieldvalue(baseentry
, "Styles"))
362 shortcutsectionlines
.append("End")
363 shortcutsectionlines
.extend(["", "", ""])
364 shortcutsectionstr
= "\r\n".join(shortcutsectionlines
)
365 dummysetup
= SetupParser()
366 dummysetup
.parse(shortcutsectionstr
)
367 shortcutentrysection
= dummysetup
.definitions
[shortcutentry
]
368 tokenrange
= dummysetup
.getsectiontokenrange(shortcutentry
)
369 self
.insertforeignsection(baseentry
, shortcutentry
, shortcutentrysection
, dummysetup
, tokenrange
)
371 def addtozipfile(self
, destdirectory
, zipfileentry
, filename
, filecontents
=None):
372 """adds a filename to a zip file. filecontents=None means read from file, otherwise create with contents and remove after"""
373 packedname
= sparse
.stringeval(self
.getfieldvalue(zipfileentry
, "PackedName"))
374 packedpath
= os
.path
.join(destdirectory
, packedname
)
375 if filecontents
is not None:
376 open(filename
, 'w').write(filecontents
)
377 print "doing zipfile", packedpath
, filename
378 os
.system('mv %s %s.zip' % (packedpath
, packedpath
))
379 os
.system('zip %s.zip %s' % (packedpath
, filename
))
380 os
.system('mv %s.zip %s' % (packedpath
, packedpath
))
381 if filecontents
is not None:
383 fileinfo
= os
.stat_result(os
.stat(packedpath
))
384 filedate
= datetime
.datetime
.fromtimestamp(fileinfo
.st_mtime
)
385 self
.setfieldvalue(zipfileentry
, "Size", "%d" % fileinfo
.st_size
)
386 self
.setfieldvalue(zipfileentry
, "Date", filedate
.strftime('"%d%m%Y"'))
387 self
.setfieldvalue(zipfileentry
, "Time", filedate
.strftime('"%H%M"'))
389 def readfromzipfile(self
, zipfileentry
, filename
):
390 """reads contents of a file from a zip file"""
391 packedname
= sparse
.stringeval(self
.getfieldvalue(zipfileentry
, "PackedName"))
392 srcdirectory
= os
.path
.dirname(self
.filename
)
393 packedpath
= os
.path
.join(srcdirectory
, packedname
)
394 return os
.popen('unzip -p %s %s' % (packedpath
, filename
)).read()
396 def addmanualfile(self
, fileentry
, filename
, packedname
, baseentry
):
397 """Inserts an external file into the build system"""
398 fileinfo
= os
.stat_result(os
.stat(filename
))
399 filedate
= datetime
.datetime
.fromtimestamp(fileinfo
.st_mtime
)
400 direntry
= self
.getfieldvalue(baseentry
, "Dir")
401 filesectionlines
= ["File %s" % fileentry
]
402 def addparam(paramname
, paramstr
):
403 filesectionlines
.append(" %s%s = %s;" % (paramname
, " "*(16-len(paramname
)), paramstr
))
404 addparam("Name", '"%s"' % os
.path
.basename(filename
))
405 addparam("PackedName", '"%s"' % packedname
)
406 addparam("Size", "%d" % fileinfo
.st_size
)
407 addparam("Dir", "%s" % direntry
)
408 addparam("Carrier", "gid_DataCarrier")
409 addparam("UnixRights", ("%o" % fileinfo
.st_mode
)[-3:])
410 addparam("Date", filedate
.strftime('"%d%m%Y"'))
411 addparam("Time", filedate
.strftime('"%H%M"'))
412 addparam("Styles", "(PACKED)")
413 filesectionlines
.append("End")
414 filesectionlines
.extend(["", "", ""])
415 filesectionstr
= "\r\n".join(filesectionlines
)
416 dummysetup
= SetupParser()
417 dummysetup
.parse(filesectionstr
)
418 fileentrysection
= dummysetup
.definitions
[fileentry
]
419 tokenrange
= dummysetup
.getsectiontokenrange(fileentry
)
420 self
.insertforeignsection(baseentry
, fileentry
, fileentrysection
, dummysetup
, tokenrange
)
421 if baseentry
in self
.filemodules
:
422 for modulename
in self
.filemodules
[baseentry
]:
423 self
.addfiletomodule(modulename
, fileentry
, baseentry
)
424 self
.manualfiles
.append((filename
, packedname
))
426 def addforeignconfigitem(self
, index
, configitem
, suffix
):
427 """adds the foreign config item and updates the modules list..."""
428 tokenrange
= index
.getsectiontokenrange(configitem
)
429 configitemsection
= index
.definitions
[configitem
]
430 # the config item will already have been renamed by the index.renamedirectory
431 self
.insertforeignsection(configitem
, configitem
+ suffix
, configitemsection
, index
, tokenrange
)
433 def addforeignhelptext(self
, index
, helpitem
):
434 """adds the foreign helpitem's text to the corresponding item in self"""
435 # see http://installation.openoffice.org/pics/scpitem_helptext.html
436 tokenrange
= index
.getfieldtokenrange(helpitem
, "Text")
437 # the help item field will already have been renamed
438 self
.insertforeignvalue(helpitem
, index
, tokenrange
)
440 def addforeignmoduletext(self
, index
, moduleitem
):
441 """adds the foreign modules's text to the corresponding item in self"""
442 # the module item fields will already have been renamed, but not in the lookup dicts
443 tokenrange
= index
.getfieldtokenrange(moduleitem
, "Name")
444 self
.insertforeignvalue(moduleitem
, index
, tokenrange
)
445 tokenrange
= index
.getfieldtokenrange(moduleitem
, "Description")
446 self
.insertforeignvalue(moduleitem
, index
, tokenrange
)
448 def addforeignfile(self
, index
, fileentry
, suffix
):
449 """adds the foreign file entry and updates the modules list..."""
450 tokenrange
= index
.getsectiontokenrange(fileentry
)
451 fileentrysection
= index
.definitions
[fileentry
]
452 # the file will already have been renamed by the index.renamedirectory
453 self
.insertforeignsection(fileentry
, fileentry
+ suffix
, fileentrysection
, index
, tokenrange
)
454 if fileentry
in self
.filemodules
:
455 for modulename
in self
.filemodules
[fileentry
]:
456 self
.addfiletomodule(modulename
, fileentry
+ suffix
, fileentry
)
458 def addfiletomodule(self
, modulename
, fileentry
, afterfileentry
):
459 """adds the given fileentry to module modulename using the definition from the index"""
460 tokennum
= self
.getmoduleentrytokennum(modulename
, afterfileentry
)
461 dummysetuplines
= ["Module %s" % modulename
, " Files = (dummy, %s);" % fileentry
, "End", ""]
462 dummyparser
= SetupParser()
463 dummyparser
.parse("\r\n".join(dummysetuplines
))
464 dummytokennum
= dummyparser
.getmoduleentrytokennum(modulename
, fileentry
)
465 insertion
= (dummyparser
, (dummytokennum
- 1, dummytokennum
+ 1))
466 if tokennum
not in self
.insertions
:
467 self
.insertions
[tokennum
] = [insertion
]
469 self
.insertions
[tokennum
].append(insertion
)
471 def renamedirectory(self
, directory
, newname
, suffix
):
472 self
.rename(directory
, newname
)
473 if directory
in self
.directorychildren
:
474 for child
in self
.directorychildren
[directory
]:
475 self
.renamedirectory(child
, child
+ suffix
, suffix
)
476 if directory
in self
.directoryfiles
:
477 for fileentry
in self
.directoryfiles
[directory
]:
478 self
.rename(fileentry
, fileentry
+ suffix
)
479 packedname
= sparse
.stringeval(self
.getfieldvalue(fileentry
, "PackedName", '""'))
481 self
.setfieldvalue(fileentry
, "PackedName", '"%s"' % (packedname
+suffix
))
483 def makepackedname(self
, prefix
, offset
=1):
484 """finds a new packedname starting with prefix in the sequence"""
485 packednames
= [self
.getfieldvalue(fileentry
, "PackedName", '""') for fileentry
in self
.bytype
['File']]
486 packednames
= map(sparse
.stringeval
, packednames
)
487 packednames
= [packedname
.replace(prefix
,"",1) for packedname
in packednames
if packedname
.startswith(prefix
)]
488 packednums
= [filter(str.isdigit
, packedname
) for packedname
in packednames
]
489 formatstring
= '%s%0' + str(max(map(len, packednums
))) + 'd'
490 packednums
= map(int, packednums
)
491 return formatstring
% (prefix
, max(packednums
)+offset
)
493 def copyfiles(self
, srcdirectory
, destdirectory
, onlychanged
=0):
494 """copy all the [changed] files listed in this setup file from srcdirectory to destdirectory"""
495 for fileentry
in self
.bytype
['File']:
496 fileentrysection
= self
.definitions
[fileentry
]
497 if 'PackedName' not in fileentrysection
: continue
498 packedtokennum
= self
.getfieldtokennum(fileentry
, "PackedName")
499 originalpackedname
= sparse
.stringeval(self
.originaltokens
[packedtokennum
])
500 packedname
= sparse
.stringeval(self
.tokens
[packedtokennum
])
501 if not onlychanged
or packedname
!= originalpackedname
:
502 srcfile
= os
.path
.join(srcdirectory
, originalpackedname
)
503 destfile
= os
.path
.join(destdirectory
, packedname
)
504 if packedname
!= originalpackedname
:
505 print '%s -> %s' % (srcfile
, destfile
)
506 os
.system('cp -p %s %s' % (srcfile
, destfile
))
507 for filename
, packedname
in self
.manualfiles
:
508 packedpath
= os
.path
.join(destdirectory
, packedname
)
509 os
.system('zip -j %s.zip %s' % (packedpath
, filename
))
510 os
.system('mv %s.zip %s' % (packedpath
, packedpath
))
512 def adddesktopentries(self
, desktopentries
, outputdir
):
513 """add desktop (menu) entries and icons for KDE and Gnome"""
514 # add desktop (menu) entries and icons for KDE
515 # icons require file icons/ooo_languageselector.png
516 if "gid_File_Extra_Kdeapplnk" in self
.definitions
:
517 self
.addtozipfile(outputdir
, "gid_File_Extra_Kdeapplnk", "languageselector.desktop", desktopentries
["kde"])
518 if "gid_File_Extra_Kdeicons" in self
.definitions
and os
.path
.exists("icons/ooo_languageselector.png"):
519 os
.system("for f in hicolor/{16x16,22x22,32x32,48x48} locolor/{16x16,22x22,32x32} ; do mkdir -p share/icons/$f/apps ; convert icons/ooo_languageselector.png -scale `basename $f` share/icons/$f/apps/ooo_languageselector.xpm ; done")
520 for scale
in [16,22,32,48]:
521 xpmfilename
= os
.path
.join("share", "icons", "hicolor", "%dx%d" % (scale
, scale
), "apps", "ooo_languageselector.xpm")
522 self
.addtozipfile(outputdir
, "gid_File_Extra_Kdeicons", xpmfilename
)
523 for scale
in [16,22,32]:
524 xpmfilename
= os
.path
.join("share", "icons", "locolor", "%dx%d" % (scale
, scale
), "apps", "ooo_languageselector.xpm")
525 self
.addtozipfile(outputdir
, "gid_File_Extra_Kdeicons", xpmfilename
)
526 # add desktop (menu) entries and icons for Gnome and Gnome2
527 if "gid_File_Extra_Gnome_Apps" in self
.definitions
:
528 ordercontents
= self
.readfromzipfile("gid_File_Extra_Gnome_Apps", ".order")
529 ordercontents
+= "languageselector.desktop\n"
530 self
.addtozipfile(outputdir
, "gid_File_Extra_Gnome_Apps", "languageselector.desktop", desktopentries
["gnome"])
531 self
.addtozipfile(outputdir
, "gid_File_Extra_Gnome_Apps", ".order", ordercontents
)
532 if "gid_File_Extra_Gnome_Icons" in self
.definitions
and os
.path
.exists("icons/ooo_languageselector.png"):
533 self
.addtozipfile(outputdir
, "gid_File_Extra_Gnome_Icons", "icons/ooo_languageselector.png")
534 if "gid_File_Extra_Gnome2_Apps" in self
.definitions
:
535 self
.addtozipfile(outputdir
, "gid_File_Extra_Gnome2_Apps", "ooo645_languageselector.desktop", desktopentries
["gnome2"])
537 setuplaunchscript
= """#!/bin/bash
538 # this is a script to launch OpenOffice.org setup in the appropriate language
539 # name it setup-nn where nn is the ISO code for the language
541 setupdir=`dirname $0`
542 scriptname=`basename $0`
543 LANG=${scriptname/setup-/}
546 export LANG LANGUAGE LC_MESSAGES
557 Icon=ooo_languageselector.xpm
558 Exec="<progpath_utf8>/program/ooswitchlang"
560 Name=<productname> Language Selector
561 Name[en]=<productname> Language Selector
566 Encoding=Legacy-Mixed
567 Name=<singleproductname> Language Selector
568 Name[en]=<singleproductname> Language Selector
571 Icon=<progpath>/share/icons/ooo_languageselector.png
572 Exec=<progpath>/program/ooswitchlang
580 Categories=Application;Office;
581 Icon=<progpath>/share/icons/ooo_languageselector.png
582 Exec=<progpath_utf8>/program/ooswitchlang
584 Name=<productname> Language Selector
586 Name[en]=<productname> Language Selector
590 if __name__
== '__main__':
598 optparser
= optparse
.OptionParser(version
="%prog "+__version__
.ver
, description
=__doc__
)
599 optparser
.set_usage("%prog maindir [--switchlangexe ooswitchlang.exe] [otherdirs] outputdir")
600 optparser
.add_option("", "--switchlangexe", dest
="switchlangexe", default
=None,
601 help="add SWITCHLANGEXE to program", metavar
="SWITCHLANGEXE")
602 options
, args
= optparser
.parse_args()
604 optparser
.error("need at least one inputdir and an outputdir")
606 otherdirs
= args
[1:-1]
608 if os
.path
.isfile(os
.path
.join(maindir
, 'setup.ins')):
609 setupname
= 'setup.ins'
610 elif os
.path
.isfile(os
.path
.join(maindir
, 'setup.inf')):
611 setupname
= 'setup.inf'
613 print >>sys
.stderr
, "could not find setup.ins or setup.inf in main input directory %s" % maindir
615 mainsetupfile
= SetupIndex(os
.path
.join(maindir
, setupname
))
617 for otherdir
in otherdirs
:
618 othersetupfiles
.append(SetupIndex(os
.path
.join(otherdir
, setupname
)))
619 mainsetupfile
.merge(othersetupfiles
)
620 if options
.switchlangexe
is not None:
621 packedname
= mainsetupfile
.makepackedname("f_")
622 mainsetupfile
.addmanualfile("gid_File_Bin_Switchlang", options
.switchlangexe
, packedname
, "gid_File_Bin_Setofficelang")
623 if "gid_Folderitem_Opendocument" in mainsetupfile
.definitions
:
624 mainsetupfile
.addmanualshortcut("gid_Folderitem_Switchlang", "gid_File_Bin_Switchlang", 0, "gid_Folderitem_Opendocument")
625 if not os
.path
.isdir(outputdir
):
627 mainsetupfile
.copyfiles(maindir
, outputdir
)
628 if options
.switchlangexe
is not None:
629 mainsetupfile
.adddesktopentries(desktopentries
, outputdir
)
630 open(os
.path
.join(outputdir
, setupname
), 'w').write(mainsetupfile
.getsource())
631 for dirnum
in range(len(otherdirs
)):
632 otherdir
= otherdirs
[dirnum
]
633 othersetupfile
= othersetupfiles
[dirnum
]
634 othersetupfile
.copyfiles(otherdir
, outputdir
, 1)
635 # copy other unmodified files
636 for filename
in os
.listdir(maindir
):
637 checkname
= filename
.lower()
638 if checkname
.startswith('f') or checkname
== setupname
:
640 srcfile
= os
.path
.join(maindir
, filename
)
641 destfile
= os
.path
.join(outputdir
, filename
)
642 print '%s -> %s' % (srcfile
, destfile
)
643 os
.system('cp -p %s %s' % (srcfile
, destfile
))
644 # also copy the following files to language-specific names
645 if checkname
.startswith("readme") or checkname
.startswith("license") or checkname
.endswith("html"):
646 extpos
= filename
.rfind(os
.extsep
)
648 destname
= filename
+ "-" + mainsetupfile
.isocode
650 destname
= filename
[:extpos
] + "-" + mainsetupfile
.isocode
+ filename
[extpos
:]
651 destfile
= os
.path
.join(outputdir
, destname
)
652 print '%s -> %s' % (srcfile
, destfile
)
653 os
.system('cp -p %s %s' % (srcfile
, destfile
))
654 for dirnum
in range(len(otherdirs
)):
655 otherdir
= otherdirs
[dirnum
]
656 setupfile
= othersetupfiles
[dirnum
]
657 for filename
in os
.listdir(otherdir
):
658 checkname
= filename
.lower()
659 if checkname
.startswith('f') or checkname
== setupname
:
661 # we want readmes in every language...
662 if checkname
.startswith("readme") or checkname
.startswith("license") or checkname
.endswith("html"):
663 srcfile
= os
.path
.join(otherdir
, filename
)
664 extpos
= filename
.rfind(os
.extsep
)
666 destname
= filename
+ "-" + setupfile
.isocode
668 destname
= filename
[:extpos
] + "-" + setupfile
.isocode
+ filename
[extpos
:]
669 destfile
= os
.path
.join(outputdir
, destname
)
670 print '%s -> %s' % (srcfile
, destfile
)
671 os
.system('cp -p %s %s' % (srcfile
, destfile
))
672 # on posix, create setup-lang scripts
673 if os
.path
.exists(os
.path
.join(outputdir
, "setup")):
674 for setupfile
in [mainsetupfile
] + othersetupfiles
:
675 destfile
= os
.path
.join(outputdir
, "setup-%s" % setupfile
.isocode
)
676 open(destfile
, 'w').write(setuplaunchscript
)
677 os
.system('chmod a+x %s' % destfile
)