27
21
from gettext import gettext as _
30
(LIST_LANG, # language (i18n/human-readable)
31
LIST_TRANSLATION, # does the user want the translation pkgs
32
LIST_TRANSLATION_AVAILABLE, # are the translation pkgs available at all?
33
LIST_INPUT, # does the user want the input-aids pkgs
34
LIST_INPUT_AVAILABLE, # are the input aids available at all?
35
LIST_LANG_CODE # the short country code (e.g. de, pt_BR)
39
COMBO_CODE) = range(2)
43
from SimpleGladeApp import SimpleGladeApp
44
22
from LocaleInfo import LocaleInfo
47
class GtkProgress(apt.OpProgress):
48
def __init__(self, host_window ,progressbar, parent):
50
self._window = host_window
51
self._progressbar = progressbar
52
host_window.set_transient_for(parent)
53
self._progressbar.set_pulse_step(0.01)
54
self._progressbar.pulse()
55
self._window.realize()
56
host_window.window.set_functions(gtk.gdk.FUNC_MOVE)
58
def update(self, percent):
63
self._progressbar.set_text(self.op)
64
self._progressbar.set_fraction(percent/100.0)
66
# self._progressbar.set_fraction(1)
68
# self._progressbar.pulse()
69
while gtk.events_pending():
72
self._progressbar.set_fraction(1)
75
class LanguageSelector(SimpleGladeApp):
77
# packages that need special translation packs (not covered by
78
# the normal langpacks)
80
("kdelibs4c2", "language-pack-kde-"),
81
("libgnome2-0", "language-pack-gnome-"),
82
("firefox", "mozilla-firefox-locale-"),
83
("mozilla-thunderbird", "mozilla-thunderbird-local-"),
84
("openoffice.org2", "openoffice.org2-l10n-"),
85
("openoffice.org2", "openoffice.org2-help-")
24
from LangCache import *
27
# the language-selector abstraction
28
class LanguageSelectorBase(object):
29
""" base class for language-selector code """
88
30
def __init__(self, datadir=""):
89
SimpleGladeApp.__init__(self, datadir+"/data/LanguageSelector.glade",
90
domain="language-selector")
92
31
self._datadir = datadir
93
#build the combobox (with model)
94
combo = self.combobox_default_lang
95
model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
96
cell = gtk.CellRendererText()
97
combo.pack_start(cell, True)
98
combo.add_attribute(cell, 'text', COMBO_LANGUAGE)
99
combo.set_model(model)
100
self.combo_dirty = False
103
self.button_apply.set_sensitive(False)
106
renderer = gtk.CellRendererText()
107
column = gtk.TreeViewColumn(_("Language"), renderer, text=LIST_LANG)
108
column.set_property("expand", True)
109
self.treeview_languages.append_column(column)
110
renderer= gtk.CellRendererToggle()
111
renderer.connect("toggled", self.toggled, LIST_TRANSLATION)
112
column = gtk.TreeViewColumn(_("Translations"), renderer,
113
active=LIST_TRANSLATION,
114
activatable=LIST_TRANSLATION_AVAILABLE,
115
sensitive=LIST_TRANSLATION_AVAILABLE,
116
visible=LIST_TRANSLATION_AVAILABLE)
118
self.treeview_languages.append_column(column)
119
renderer= gtk.CellRendererToggle()
120
renderer.connect("toggled", self.toggled, LIST_INPUT)
121
column = gtk.TreeViewColumn(_("Writing Aids"), renderer,
123
activatable=LIST_INPUT_AVAILABLE,
124
sensitive=LIST_INPUT_AVAILABLE,
125
visible=LIST_INPUT_AVAILABLE)
127
self.treeview_languages.append_column(column)
129
self._langlist = gtk.ListStore(str, bool, bool, bool, bool, str)
130
self.treeview_languages.set_model(self._langlist)
131
self.window_main.show()
132
self.window_main.set_sensitive(False)
133
watch = gtk.gdk.Cursor(gtk.gdk.WATCH)
134
self.window_main.window.set_cursor(watch)
135
while gtk.events_pending():
138
32
# load the localeinfo "database"
139
33
self._localeinfo = LocaleInfo("%s/data/languages" % self._datadir,
140
34
"%s/data/countries" % self._datadir,
141
35
"%s/data/languagelist" % self._datadir)
142
self.updateLanguageView()
143
self.updateSystemDefaultCombo()
144
# see if something is missing
145
self.verifyInstalledLangPacks()
146
self.window_main.set_sensitive(True)
147
self.window_main.window.set_cursor(None)
149
def check_apply_button(self):
150
(inst_list, rm_list) = self.build_commit_lists()
151
if self.combo_dirty or len(inst_list) > 0 or len(rm_list) > 0:
152
self.button_apply.set_sensitive(True)
154
self.button_apply.set_sensitive(False)
156
def on_combobox_default_lang_changed(self, widget):
157
self.combo_dirty = True
158
self.check_apply_button()
160
def __missingTranslationPkgs(self, pkg, translation_pkg):
161
""" this will check if the given pkg is installed and if
162
the needed translation package is installed as well
164
It returns a list of packages that need to be
168
# FIXME: this function is called too often and it's too slow
169
# -> see ../TODO for ideas how to fix it
171
# check if the pkg itself is available and installed
172
if not self._cache.has_key(pkg):
174
if not self._cache[pkg].isInstalled:
177
# match every packages that looks similar to translation_pkg
178
for pkg in self._cache:
179
if pkg.name.startswith(translation_pkg):
180
if not pkg.isInstalled and pkg.candidateVersion != None:
181
missing.append(pkg.name)
185
def verifyInstalledLangPacks(self):
186
""" called at the start to inform about possible missing
187
langpacks (e.g. gnome/kde langpack transition)
190
for (lang, trans, has_trans, input, has_inp, code) in self._langlist:
191
trans_package = "language-pack-%s" % code
192
# we have a langpack installed, see if we have all of it
193
# (for hoary -> breezy transition)
194
if self._cache.has_key(trans_package) and \
195
self._cache[trans_package].isInstalled:
196
#print "IsInstalled: %s " % trans_package
197
for (pkg, translation) in self.pkg_translations:
198
missing += self.__missingTranslationPkgs(pkg, translation+code)
200
#print "Missing: %s " % missing
202
# FIXME: add "details"
203
d = gtk.MessageDialog(parent=self.window_main,
204
flags=gtk.DIALOG_MODAL,
205
type=gtk.MESSAGE_QUESTION)
206
d.set_markup("<big><b>%s</b></big>\n\n%s" % (
207
_("The language support is not installed completely"),
208
_("Not all translations or writing aids, that are available for "
209
"the supported languages on your system, are installed.")))
210
d.add_buttons(_("_Remind Me Again"), gtk.RESPONSE_NO,
211
_("_Install"), gtk.RESPONSE_YES)
212
d.set_default_response(gtk.RESPONSE_YES)
214
expander = gtk.Expander(_("Details"))
215
scroll = gtk.ScrolledWindow()
216
scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
217
textview = gtk.TextView()
218
textview.set_cursor_visible(False)
219
textview.set_editable(False)
220
buf = textview.get_buffer()
223
pkgs += "%s (%s)\n" % (pkg, apt.SizeToStr(self._cache[pkg].packageSize))
225
buf.place_cursor(buf.get_start_iter())
228
d.vbox.pack_start(expander)
232
if res == gtk.RESPONSE_YES:
233
self.commit(missing, [])
234
self.updateLanguageView()
237
def toggled(self, renderer, path_string, what):
238
iter = self._langlist.get_iter_from_string(path_string)
239
old = self._langlist.get_value(iter, what)
240
self._langlist.set_value(iter, what, not old)
241
self.check_apply_button()
243
def build_commit_lists(self):
247
for (lang, trans, has_trans, input, has_inp, code) in self._langlist:
248
# see what translation packages we will need
249
trans_packages = ["language-pack-%s" % code]
251
# see what needs to be installed/removed
252
# (use the trans_packages list we computed before)
253
if has_trans and trans != self._cache["language-pack-%s" % code].isInstalled:
255
for (pkg, translation) in self.pkg_translations:
256
trans_packages += self.__missingTranslationPkgs(pkg, translation+code)
257
inst_list.extend(trans_packages)
259
for (pkg, translation) in self.pkg_translations:
260
trans_packages += self.__missingTranslationPkgs(pkg, translation+code)
261
rm_list.extend(trans_packages)
263
if has_inp and input != self._cache["language-support-%s" % code].isInstalled:
265
inst_list.append("language-support-%s" % code)
267
rm_list.append("language-support-%s" % code)
269
#print "inst_list: %s " % inst_list
270
#print "rm_list: %s " % rm_list
271
return (inst_list, rm_list)
273
def verify_commit_lists(self, inst_list, rm_list):
274
""" verify if the selected package can actually be installed """
277
for pkg in inst_list:
278
if self._cache.has_key(pkg):
279
self._cache[pkg].markInstall()
281
if self._cache.has_key(pkg):
282
self._cache[pkg].markDelete()
286
# undo the selections
287
for pkg in self._cache.keys():
288
self._cache[pkg].markKeep()
289
if self._cache._depcache.BrokenCount != 0:
290
# undoing the selections was impossible,
291
d = gtk.MessageDialog(parent=self.window_main,
292
flags=gtk.DIALOG_MODAL,
293
type=gtk.MESSAGE_ERROR,
294
buttons=gtk.BUTTONS_CLOSE)
295
d.set_markup("<big><b>%s</b></big>\n\n%s" % (
296
_("Could not install the selected language support"),
297
_("This is perhaps a bug of this application. Please "
298
"file a bug report at "
299
"https://launchpad.net/bugs/bugs/+package/ against "
300
"the 'language-selector' product.")))
304
# something went pretty bad, re-get a cache
305
progress = GtkProgress(self.dialog_progress,self.progressbar_cache,
307
self._cache = apt.Cache(progress)
312
""" commit helper, builds the commit lists, verifies it """
313
(inst_list, rm_list) = self.build_commit_lists()
314
if not self.verify_commit_lists(inst_list, rm_list):
315
d = gtk.MessageDialog(parent=self.window_main,
316
flags=gtk.DIALOG_MODAL,
317
type=gtk.MESSAGE_ERROR,
318
buttons=gtk.BUTTONS_CLOSE)
319
d.set_markup("<big><b>%s</b></big>\n\n%s" % (
320
_("Could not install the full language support"),
321
_("Usually this is related to an error in your "
322
"software archive or software manager. Check your "
323
"software preferences in the menu \"Adminstration\".")))
328
#print "inst_list: %s " % inst_list
329
#print "rm_list: %s " % rm_list
330
self.commit(inst_list, rm_list)
331
self.writeSystemDefaultLang()
332
# queue a restart of gdm (if it is runing) to make the new
334
gdmscript = "/etc/init.d/gdm"
335
if os.path.exists("/var/run/gdm.pid") and os.path.exists(gdmscript):
336
subprocess.call(["invoke-rc.d","gdm","reload"])
339
def on_button_ok_clicked(self, widget):
343
def on_button_apply_clicked(self, widget):
345
self.updateLanguageView()
346
self.updateSystemDefaultCombo()
348
def run_synaptic(self, lock, inst, rm, id):
349
cmd = ["/usr/sbin/synaptic", "--hide-main-window",
350
"--non-interactive", "--set-selections",
351
"--parent-window-id", "%s" % (id),
352
"--finish-str", _("The list of available languages on the "
353
"system has been updated.")
355
proc = subprocess.Popen(cmd, stdin=subprocess.PIPE)
358
f.write("%s\tinstall\n" % s)
360
f.write("%s\tdeinstall\n" % s)
365
def commit(self, inst, rm):
366
# unlock here to make sure that lock/unlock are always run
367
# pair-wise (and don't explode on errors)
369
apt_pkg.PkgSystemUnLock()
371
print "WARNING: trying to unlock a not-locked PkgSystem"
373
if len(inst) == 0 and len(rm) == 0:
375
self.window_main.set_sensitive(False)
376
lock = thread.allocate_lock()
378
t = thread.start_new_thread(self.run_synaptic,(lock,inst,rm, self.window_main.window.xid))
380
while gtk.events_pending():
383
self.window_main.set_sensitive(True)
384
while gtk.events_pending():
387
def on_button_cancel_clicked(self, widget):
388
#print "button_cancel"
391
def on_delete_event(self, event, data):
392
if self.window_main.get_property("sensitive") is False:
397
def updateLanguageView(self):
398
#print "updateLanguageView()"
402
apt_pkg.PkgSystemLock()
404
d = gtk.MessageDialog(parent=self.window_main,
405
flags=gtk.DIALOG_MODAL,
406
type=gtk.MESSAGE_ERROR,
407
buttons=gtk.BUTTONS_CLOSE)
408
d.set_markup("<big><b>%s</b></big>\n\n%s" % (
409
_("Only one software management tool is allowed to"
410
" run at the same time"),
411
_("Please close the other application e.g. \"Update "
412
"Manager\", \"aptitude\" or \"Synaptic\" at first.")))
418
self._langlist.clear()
420
progress = GtkProgress(self.dialog_progress, self.progressbar_cache,
422
self._cache = apt.Cache(progress)
424
if self._cache._depcache.BrokenCount > 0:
425
d = gtk.MessageDialog(parent=self.window_main,
426
flags=gtk.DIALOG_MODAL,
427
type=gtk.MESSAGE_ERROR,
428
buttons=gtk.BUTTONS_CLOSE)
429
d.set_markup("<big><b>%s</b></big>\n\n%s" % (
430
_("Software database is broken"),
431
_("It is impossible to install or remove any software. "
432
"Please use the package manager \"Synaptic\" or run "
433
"\"sudo apt-get install -f\" in a terminal to fix "
434
"this issue at first.")))
440
for line in open(self._localeinfo._langFile):
38
def openCache(self, progress):
39
self._cache = LanguageSelectorPkgCache(self._localeinfo, progress)
41
def getSystemDefaultLanguage(self):
42
if not os.path.exists("/etc/environment"):
44
for line in open("/etc/environment"):
441
45
tmp = string.strip(line)
442
if tmp.startswith("#"):
444
(code, lang) = tmp.split(":")
447
has_translation = self._cache.has_key("language-pack-%s" % code)
448
has_input = self._cache.has_key("language-support-%s" % code)
450
trans = self._cache["language-pack-%s" % code].isInstalled
452
inp = self._cache["language-support-%s" % code].isInstalled
453
if has_input or has_translation:
454
self._langlist.append([_(lang),
455
trans, has_translation,
458
self._langlist.set_sort_column_id(LIST_LANG, gtk.SORT_ASCENDING)
460
def writeSystemDefaultLang(self):
461
combo = self.combobox_default_lang
462
model = combo.get_model()
463
(lang, code) = model[combo.get_active()]
464
#print "lang=%s, code=%s" % (lang, code)
466
# make a copy (in case we do anything bad)
49
langs = tmp.strip("\"").split(":")
50
# check if LANGUAGE is empty
55
def setSystemDefaultLanguage(self, defaultLanguageCode):
467
56
if os.path.exists("/etc/enviroment"):
468
57
shutil.copy("/etc/environment", "/etc/environment.save")
469
58
out = open("/etc/environment.new","w+")