Beispiel #1
0
class GtkLanguageSelector(LanguageSelectorBase):
    def __init__(self, datadir, options):
        LanguageSelectorBase.__init__(self, datadir)
        self._datadir = datadir

        self.widgets = Gtk.Builder()
        self.widgets.set_translation_domain('language-selector')
        self.widgets.add_from_file(datadir + "/data/LanguageSelector.ui")
        self.widgets.connect_signals(self)

        try:
            in_grp_admin = grp.getgrnam("admin")[2] in os.getgroups()
        except KeyError:
            in_grp_admin = False
        try:
            in_grp_sudo = grp.getgrnam("sudo")[2] in os.getgroups()
        except KeyError:
            in_grp_sudo = False

        self.is_admin = (os.getuid() == 0 or in_grp_sudo or in_grp_admin)

        # see if we have any other human users on this system
        self.has_other_users = False
        num = 0
        for l in pwd.getpwall():
            if l.pw_uid >= 500 and l.pw_uid < 65534:
                num += 1
            if num >= 2:
                self.has_other_users = True
                break

        #build the comboboxes (with model)
        combo = self.combobox_locale_chooser
        model = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING)
        cell = Gtk.CellRendererText()
        combo.pack_start(cell, True)
        combo.add_attribute(cell, 'text', LANGTREEVIEW_LANGUAGE)
        combo.set_model(model)
        #        self.combo_syslang_dirty = False

        #        combo = self.combobox_user_language
        #        model = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING)
        #        cell = Gtk.CellRendererText()
        #        combo.pack_start(cell, True)
        #        combo.add_attribute(cell, 'text', COMBO_LANGUAGE)
        #        combo.set_model(model)
        #        self.combo_userlang_dirty = False
        self.options = options

        # get aptdaemon client
        self.ac = aptdaemon.client.AptClient()

        combo = self.combobox_input_method
        model = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING)
        cell = Gtk.CellRendererText()
        combo.pack_start(cell, True)
        combo.add_attribute(cell, 'text', IM_NAME)
        combo.set_model(model)
        self.imSwitch = ImSwitch()
        self._blockSignals = False

        # remove dangling ImSwitch symlinks if present
        self.imSwitch.removeDanglingSymlinks()

        # build the treeview
        self.setupLanguageTreeView()
        if self.is_admin:
            self.setupInstallerTreeView()
            self.updateLanguageView()
#        self.updateUserDefaultCombo()
        self.updateLocaleChooserCombo()
        self.check_input_methods()
        #        self.updateSyncButton()

        # apply button
        self.button_apply.set_sensitive(False)

        # 'Apply System-Wide...' and 'Install/Remove Languages...' buttons
        if self.is_admin:
            self.button_apply_system_wide_languages.set_sensitive(True)
            self.button_install_remove_languages.set_sensitive(True)
            self.button_apply_system_wide_locale.set_sensitive(True)
        else:
            self.button_apply_system_wide_languages.set_sensitive(False)
            self.button_install_remove_languages.set_sensitive(False)
            self.button_apply_system_wide_locale.set_sensitive(False)

        # show it
        self.window_main.show()
        self.setSensitive(False)

        if self.is_admin:
            # check if the package list is up-to-date
            if not self._cache.havePackageLists:
                d = Gtk.MessageDialog(parent=self.window_main,
                                      flags=Gtk.DialogFlags.MODAL,
                                      type=Gtk.MessageType.INFO,
                                      buttons=Gtk.ButtonsType.CANCEL)
                d.set_markup(
                    "<big><b>%s</b></big>\n\n%s" %
                    (_("No language information available"),
                     _("The system does not have information about the "
                       "available languages yet. Do you want to perform "
                       "a network update to get them now? ")))
                d.set_title = ("")
                d.add_button(_("_Update"), Gtk.ResponseType.YES)
                res = d.run()
                d.destroy()
                if res == Gtk.ResponseType.YES:
                    self.setSensitive(False)
                    self.update()
                    self.updateLanguageView()
                    self.setSensitive(True)

            # see if something is missing
            if self.options.verify_installed:
                self.verifyInstalledLangPacks()

        if not self.imSwitch.available():
            self.combobox_input_method.set_sensitive(False)
        self.setSensitive(True)

    def __getattr__(self, name):
        '''Convenient access to GtkBuilder objects'''

        o = self.widgets.get_object(name)
        if o is None:
            raise AttributeError, 'No such widget: ' + name
        return o

    def run(self):
        Gtk.main()

    def setSensitive(self, value):
        if value:
            self.window_main.set_sensitive(True)
            self.window_main.get_window().set_cursor(None)
        else:
            self.window_main.set_sensitive(False)
            self.window_main.get_window().set_cursor(
                Gdk.Cursor.new(Gdk.CursorType.WATCH))
        while Gtk.events_pending():
            Gtk.main_iteration()

#    @blockSignals
#    def updateSyncButton(self):
#        " check if the sync languages button should be enabled or not "
#        button = self.checkbutton_sync_languages
#        combo = self.combobox_system_language
#        # no admin user, gray out
#        if self.is_admin == False:
#            button.set_active(False)
#            button.set_sensitive(False)
#            combo.set_sensitive(False)
#            return
#        # admin user, check stuff
#        button.set_sensitive(True)
#        combo.set_sensitive(True)
#        # do not enable the keep the same button if the system has other
#        # users or if the language settings are inconsistent already
#        userlang = self.combobox_user_language.get_active()
#        systemlang = self.combobox_system_language.get_active()
#        if (not self.has_other_users and userlang == systemlang):
#            button.set_active(True)
#        else:
#            button.set_active(False)

    def setupInstallerTreeView(self):
        """ do all the treeview setup here """
        def toggle_cell_func(column, cell, model, iter, data):
            langInfo = model.get_value(iter, LIST_LANG_INFO)

            # check for active and inconsitent
            inconsistent = langInfo.inconsistent
            #if inconsistent:
            #    print "%s is inconsistent" % langInfo.language

            cell.set_property("active", langInfo.fullInstalled)
            cell.set_property("inconsistent", inconsistent)

        def lang_view_func(cell_layout, renderer, model, iter, data):
            langInfo = model.get_value(iter, LIST_LANG_INFO)
            langName = model.get_value(iter, LIST_LANG)
            if (langInfo.changes):
                markup = "<b>%s</b>" % langName
            else:
                markup = "%s" % langName
            renderer.set_property("markup", markup)

        renderer = Gtk.CellRendererText()
        column = Gtk.TreeViewColumn(_("Language"), renderer, text=LIST_LANG)
        column.set_property("expand", True)
        column.set_cell_data_func(renderer, lang_view_func, None)
        self.treeview_languages.append_column(column)

        renderer = Gtk.CellRendererToggle()
        renderer.connect("toggled", self.on_toggled)
        column = Gtk.TreeViewColumn(_("Installed"), renderer)
        column.set_cell_data_func(renderer, toggle_cell_func, None)
        self.treeview_languages.append_column(column)
        # build the store
        self._langlist = Gtk.ListStore(str, GObject.TYPE_PYOBJECT)
        self.treeview_languages.set_model(self._langlist)

    def setupLanguageTreeView(self):
        """ do all the treeview setup here """
        def lang_view_func(cell_layout, renderer, model, iter, data):
            langInfo = model.get_value(iter, LANGTREEVIEW_CODE)
            greyFlag = False
            myiter = model.get_iter_first()
            while myiter:
                str = model.get_value(myiter, LANGTREEVIEW_CODE)
                if str == langInfo:
                    greyFlag = False
                    break
                if str == "en":
                    greyFlag = True
                    break
                myiter = model.iter_next(myiter)
            if greyFlag:
                markup = "<span foreground=\"grey\">%s</span>" \
                       % self._localeinfo.translate(langInfo, native=True, allCountries=True)
            else:
                markup = "%s" % self._localeinfo.translate(
                    langInfo, native=True, allCountries=True)
            renderer.set_property("markup", markup)

        renderer = Gtk.CellRendererText()
        column = Gtk.TreeViewColumn(_("Language"),
                                    renderer,
                                    text=LANGTREEVIEW_LANGUAGE)
        column.set_property("expand", True)
        column.set_cell_data_func(renderer, lang_view_func, None)
        self.treeview_locales.append_column(column)

        # build the store
        self._language_options = Gtk.ListStore(GObject.TYPE_STRING,
                                               GObject.TYPE_STRING)
        self.treeview_locales.set_model(self._language_options)

    def _get_langinfo_on_cursor(self):
        (path, column) = self.treeview_languages.get_cursor()
        if not path:
            return None
        iter = self._langlist.get_iter(path)
        langInfo = self._langlist.get_value(iter, LIST_LANG_INFO)
        return langInfo

    def debug_pkg_status(self):
        langInfo = self._get_langinfo_on_cursor()
        for pkg in langInfo.languagePkgList.items():
            print(
                "%s, available: %s, installed: %s, doChange: %s" %
                (pkg[0], pkg[1].available, pkg[1].installed, pkg[1].doChange))
        print("inconsistent? : %s" % langInfo.inconsistent)

    def check_status(self):
        changed = False
        countInstall = 0
        countRemove = 0
        for (lang, langInfo) in self._langlist:
            if langInfo.changes:
                changed = True
                for item in langInfo.languagePkgList.values():
                    if item.doChange:
                        if item.installed:
                            countRemove = countRemove + 1
                        else:
                            countInstall = countInstall + 1
        #print "%(INSTALL)d to install, %(REMOVE)d to remove" % (countInstall, countRemove)
        # Translators: %(INSTALL)d is parsed; either keep it exactly as is or remove it entirely, but don't translate "INSTALL".
        textInstall = gettext.ngettext("%(INSTALL)d to install",
                                       "%(INSTALL)d to install",
                                       countInstall) % {
                                           'INSTALL': countInstall
                                       }
        # Translators: %(REMOVE)d is parsed; either keep it exactly as is or remove it entirely, but don't translate "REMOVE".
        textRemove = gettext.ngettext("%(REMOVE)d to remove",
                                      "%(REMOVE)d to remove", countRemove) % {
                                          'REMOVE': countRemove
                                      }
        if countRemove == 0 and countInstall == 0:
            self.label_install_remove.set_text("")
        elif countRemove == 0:
            self.label_install_remove.set_text(textInstall)
        elif countInstall == 0:
            self.label_install_remove.set_text(textRemove)
        else:
            # Translators: this string will concatenate the "%n to install" and "%n to remove" strings, you can replace the comma if you need to.
            self.label_install_remove.set_text(
                _("%s, %s") % (textInstall, textRemove))

        if changed:
            self.button_apply.set_sensitive(True)
        else:
            self.button_apply.set_sensitive(False)

#    @honorBlockedSignals
#    @insensitive
#    def on_combobox_system_language_changed(self, widget):
#        #print "on_combobox_system_language_changed()"
#        if self.writeSystemDefaultLang():
#            # queue a restart of gdm (if it is runing) to make the new
#            # locales usable
#            gdmscript = "/etc/init.d/gdm"
#            if os.path.exists("/var/run/gdm.pid") and os.path.exists(gdmscript):
#                self.runAsRoot(["invoke-rc.d","gdm","reload"])
#        self.updateSystemDefaultCombo()
#        if self.checkbutton_sync_languages.get_active() == True:
#            self.combobox_user_language.set_active(self.combobox_system_language.get_active())
#            self.updateUserDefaultCombo()

#    @honorBlockedSignals
#    @insensitive
#    def on_combobox_user_language_changed(self, widget):
#        #print "on_combobox_user_language_changed()"
#        self.check_input_methods()
#        self.writeUserDefaultLang()
#        self.updateUserDefaultCombo()
#        if self.checkbutton_sync_languages.get_active() == True:
#            self.combobox_system_language.set_active(self.combobox_user_language.get_active())
#            self.updateSystemDefaultCombo()

    @blockSignals
    def check_input_methods(self):
        """ check if the selected langauge has input method support
            and set checkbutton_enable_input_methods accordingly
        """
        if not self.imSwitch.available():
            return
        # get the current first item in the user LANGUAGE list,
        # but with country code added if not already present
        loc = language2locale(self.userEnvLanguage)
        code = re.split('[.@]', loc)[0]

        combo = self.combobox_input_method
        #cell = combo.get_child().get_cell_renderers()[0]
        # FIXME: use something else than a hardcoded value here
        #cell.set_property("wrap-width",300)
        #cell.set_property("wrap-mode",Pango.WRAP_WORD)
        model = combo.get_model()
        model.clear()

        # find the default
        currentIM = self.imSwitch.getInputMethodForLocale(code)
        if currentIM in (None, 'default'):
            currentIM = 'none'
        #print "Current IM: "+currentIM

        # find out about the other options
        for (i, IM) in enumerate(self.imSwitch.getAvailableInputMethods()):
            iter = model.append()
            name = _('none') if IM == 'none' else IM
            model.set_value(iter, IM_CHOICE, IM)
            model.set_value(iter, IM_NAME, name)
            if IM == currentIM:
                combo.set_active(i)
#        self.check_status()

#    def writeInputMethodConfig(self):
#        """
#        write new input method defaults - currently we only support all_ALL
#        """
#        combo = self.combobox_user_language
#        model = combo.get_model()
#        if combo.get_active() < 0:
#            return
#        (lang, code) = model[combo.get_active()]
#        # check if we need to do something
#        new_value = self.checkbutton_enable_input_methods.get_active()
#        if self.imSwitch.enabledForLocale(code) != new_value:
#            if new_value:
#                self.imSwitch.enable(code)
#            else:
#                self.imSwitch.disable(code)
#            #self.showRebootRequired()
#            #self.checkReloginNotification()

#    @honorBlockedSignals
#    def on_checkbutton_enable_input_methods_toggled(self, widget):
#        #print "on_checkbutton_enable_input_methods_toggled()"
#        active = self.checkbutton_enable_input_methods.get_active()
#        self.combo_userlang_dirty = True
#        self.setSensitive(False)
#        self.writeInputMethodConfig()
#        self.setSensitive(True)

#    @honorBlockedSignals
#    def on_checkbutton_sync_languages_toggled(self, widget):
#        #print "on_checkbutton_sync_languages_toggled()"
#        if self.checkbutton_sync_languages.get_active() == True:
#            self.combobox_user_language.set_active(self.combobox_system_language.get_active())
#            self.updateSystemDefaultCombo()

    def build_commit_lists(self):
        print self._cache.get_changes()

        try:
            for (lang, langInfo) in self._langlist:
                self._cache.tryChangeDetails(langInfo)
        except ExceptionPkgCacheBroken:
            self.error(
                _("Software database is broken"),
                _("It is impossible to install or remove any software. "
                  "Please use the package manager \"Synaptic\" or run "
                  "\"sudo apt-get install -f\" in a terminal to fix "
                  "this issue at first."))
            sys.exit(1)
        (to_inst, to_rm) = self._cache.getChangesList()
        #print "inst: %s" % to_inst
        #print "rm: %s" % to_rm
        print self._cache.get_changes()
        return (to_inst, to_rm)

    def error(self, summary, msg):
        d = Gtk.MessageDialog(parent=self.window_main,
                              flags=Gtk.DialogFlags.MODAL,
                              type=Gtk.MessageType.ERROR,
                              buttons=Gtk.ButtonsType.CLOSE)
        d.set_markup("<big><b>%s</b></big>\n\n%s" % (summary, msg))
        d.set_title = ("")
        d.run()
        d.destroy()

    def _show_error_dialog(self, error):
        msg = str(error)
        self.error(msg, "")

    def verify_commit_lists(self, inst_list, rm_list):
        """ verify if the selected package can actually be installed """
        res = True
        try:
            for pkg in inst_list:
                if pkg in self._cache:
                    self._cache[pkg].mark_install()
            for pkg in rm_list:
                if pkg in self._cache:
                    self._cache[pkg].mark_delete()
        except SystemError:
            res = False

        # undo the selections
        self._cache.clear()
        if self._cache._depcache.broken_count != 0:
            self.error(
                _("Could not install the selected language support"),
                _("This is perhaps a bug of this application. Please "
                  "file a bug report at "
                  "https://bugs.launchpad.net/ubuntu/+source/language-selector/+filebug"
                  ))

            # something went pretty bad, re-get a cache
            progress = GtkProgress(self.dialog_progress,
                                   self.progressbar_cache, self.window_main)
            self._cache = apt.Cache(self._localeinfo, progress)
            progress.hide()
            res = False
        return res

    def commitAllChanges(self):
        """ 
        commit helper, builds the commit lists, verifies it
        
        returns the number of install/removed packages
        """
        self.setSensitive(False)
        # install the new packages (if any)
        (inst_list, rm_list) = self.build_commit_lists()
        if not self.verify_commit_lists(inst_list, rm_list):
            self.error(
                _("Could not install the full language support"),
                _("Usually this is related to an error in your "
                  "software archive or software manager. Check your "
                  "preferences in Software Sources (click the icon "
                  "at the very right of the top bar and select "
                  "\"System Settings... -> Software Sources\")."))
            self.setSensitive(True)
            return 0
        #print "inst_list: %s " % inst_list
        #print "rm_list: %s " % rm_list
        self.commit(inst_list, rm_list)

        self.setSensitive(True)
        return len(inst_list) + len(rm_list)

    def _run_transaction(self, transaction):
        dia = AptProgressDialog(transaction, parent=self.window_main)
        dia.connect("finished", self._on_finished)
        dia.run(error_handler=self._on_error)

    def _wait_for_aptdaemon_finish(self):
        while not self._transaction_finished:
            while Gtk.events_pending():
                Gtk.main_iteration()
            time.sleep(0.02)

    def _on_finished(self, dialog):
        dialog.hide()
        self._transaction_finished = True

    def _on_error(self, error):
        if hasattr(error, 'get_dbus_name') and error.get_dbus_name() == \
                    'org.freedesktop.PolicyKit.Error.NotAuthorized':
            self.error(_("Could not install the full language support"),
                       _('Failed to authorize to install packages.'))
        else:
            self.error(_("Could not install the full language support"),
                       str(error))
        self._transaction_finished = True

    def update_aptdaemon(self):
        self._transaction_finished = False
        self._update_aptdaemon()
        self._wait_for_aptdaemon_finish()

    @inline_callbacks
    def _update_aptdaemon(self):
        try:
            trans = yield self.ac.update_cache(defer=True)
            self._run_transaction(trans)
        except Exception, e:
            self._show_error_dialog(e)
class GtkLanguageSelector(LanguageSelectorBase):
    def __init__(self, datadir, options):
        LanguageSelectorBase.__init__(self, datadir)
        self._datadir = datadir

        self.widgets = Gtk.Builder()
        self.widgets.set_translation_domain("language-selector")
        self.widgets.add_from_file(datadir + "/data/LanguageSelector.ui")
        self.widgets.connect_signals(self)

        try:
            in_grp_admin = grp.getgrnam("admin")[2] in os.getgroups()
        except KeyError:
            in_grp_admin = False
        try:
            in_grp_sudo = grp.getgrnam("sudo")[2] in os.getgroups()
        except KeyError:
            in_grp_sudo = False

        self.is_admin = os.getuid() == 0 or in_grp_sudo or in_grp_admin

        # see if we have any other human users on this system
        self.has_other_users = False
        num = 0
        for l in pwd.getpwall():
            if l.pw_uid >= 500 and l.pw_uid < 65534:
                num += 1
            if num >= 2:
                self.has_other_users = True
                break

        # build the comboboxes (with model)
        combo = self.combobox_locale_chooser
        model = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING)
        cell = Gtk.CellRendererText()
        combo.pack_start(cell, True)
        combo.add_attribute(cell, "text", LANGTREEVIEW_LANGUAGE)
        combo.set_model(model)
        #        self.combo_syslang_dirty = False

        #        combo = self.combobox_user_language
        #        model = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING)
        #        cell = Gtk.CellRendererText()
        #        combo.pack_start(cell, True)
        #        combo.add_attribute(cell, 'text', COMBO_LANGUAGE)
        #        combo.set_model(model)
        #        self.combo_userlang_dirty = False
        self.options = options

        # get aptdaemon client
        self.ac = aptdaemon.client.AptClient()

        combo = self.combobox_input_method
        model = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING)
        cell = Gtk.CellRendererText()
        combo.pack_start(cell, True)
        combo.add_attribute(cell, "text", IM_NAME)
        combo.set_model(model)
        self.imSwitch = ImSwitch()
        self._blockSignals = False

        # remove dangling ImSwitch symlinks if present
        self.imSwitch.removeDanglingSymlinks()

        # build the treeview
        self.setupLanguageTreeView()
        if self.is_admin:
            self.setupInstallerTreeView()
            self.updateLanguageView()
        #        self.updateUserDefaultCombo()
        self.updateLocaleChooserCombo()
        self.check_input_methods()
        #        self.updateSyncButton()

        # apply button
        self.button_apply.set_sensitive(False)

        # 'Apply System-Wide...' and 'Install/Remove Languages...' buttons
        if self.is_admin:
            self.button_apply_system_wide_languages.set_sensitive(True)
            self.button_install_remove_languages.set_sensitive(True)
            self.button_apply_system_wide_locale.set_sensitive(True)
        else:
            self.button_apply_system_wide_languages.set_sensitive(False)
            self.button_install_remove_languages.set_sensitive(False)
            self.button_apply_system_wide_locale.set_sensitive(False)

        # show it
        self.window_main.show()
        self.setSensitive(False)

        if self.is_admin:
            # check if the package list is up-to-date
            if not self._cache.havePackageLists:
                d = Gtk.MessageDialog(
                    parent=self.window_main,
                    flags=Gtk.DialogFlags.MODAL,
                    type=Gtk.MessageType.INFO,
                    buttons=Gtk.ButtonsType.CANCEL,
                )
                d.set_markup(
                    "<big><b>%s</b></big>\n\n%s"
                    % (
                        _("No language information available"),
                        _(
                            "The system does not have information about the "
                            "available languages yet. Do you want to perform "
                            "a network update to get them now? "
                        ),
                    )
                )
                d.set_title = ""
                d.add_button(_("_Update"), Gtk.ResponseType.YES)
                res = d.run()
                d.destroy()
                if res == Gtk.ResponseType.YES:
                    self.setSensitive(False)
                    self.update()
                    self.updateLanguageView()
                    self.setSensitive(True)

            # see if something is missing
            if self.options.verify_installed:
                self.verifyInstalledLangPacks()

        if not self.imSwitch.available():
            self.combobox_input_method.set_sensitive(False)
        self.setSensitive(True)

    def __getattr__(self, name):
        """Convenient access to GtkBuilder objects"""

        o = self.widgets.get_object(name)
        if o is None:
            raise AttributeError, "No such widget: " + name
        return o

    def run(self):
        Gtk.main()

    def setSensitive(self, value):
        if value:
            self.window_main.set_sensitive(True)
            self.window_main.get_window().set_cursor(None)
        else:
            self.window_main.set_sensitive(False)
            self.window_main.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH))
        while Gtk.events_pending():
            Gtk.main_iteration()

    #    @blockSignals
    #    def updateSyncButton(self):
    #        " check if the sync languages button should be enabled or not "
    #        button = self.checkbutton_sync_languages
    #        combo = self.combobox_system_language
    #        # no admin user, gray out
    #        if self.is_admin == False:
    #            button.set_active(False)
    #            button.set_sensitive(False)
    #            combo.set_sensitive(False)
    #            return
    #        # admin user, check stuff
    #        button.set_sensitive(True)
    #        combo.set_sensitive(True)
    #        # do not enable the keep the same button if the system has other
    #        # users or if the language settings are inconsistent already
    #        userlang = self.combobox_user_language.get_active()
    #        systemlang = self.combobox_system_language.get_active()
    #        if (not self.has_other_users and userlang == systemlang):
    #            button.set_active(True)
    #        else:
    #            button.set_active(False)

    def setupInstallerTreeView(self):
        """ do all the treeview setup here """

        def toggle_cell_func(column, cell, model, iter, data):
            langInfo = model.get_value(iter, LIST_LANG_INFO)

            # check for active and inconsitent
            inconsistent = langInfo.inconsistent
            # if inconsistent:
            #    print "%s is inconsistent" % langInfo.language

            cell.set_property("active", langInfo.fullInstalled)
            cell.set_property("inconsistent", inconsistent)

        def lang_view_func(cell_layout, renderer, model, iter, data):
            langInfo = model.get_value(iter, LIST_LANG_INFO)
            langName = model.get_value(iter, LIST_LANG)
            if langInfo.changes:
                markup = "<b>%s</b>" % langName
            else:
                markup = "%s" % langName
            renderer.set_property("markup", markup)

        renderer = Gtk.CellRendererText()
        column = Gtk.TreeViewColumn(_("Language"), renderer, text=LIST_LANG)
        column.set_property("expand", True)
        column.set_cell_data_func(renderer, lang_view_func, None)
        self.treeview_languages.append_column(column)

        renderer = Gtk.CellRendererToggle()
        renderer.connect("toggled", self.on_toggled)
        column = Gtk.TreeViewColumn(_("Installed"), renderer)
        column.set_cell_data_func(renderer, toggle_cell_func, None)
        self.treeview_languages.append_column(column)
        # build the store
        self._langlist = Gtk.ListStore(str, GObject.TYPE_PYOBJECT)
        self.treeview_languages.set_model(self._langlist)

    def setupLanguageTreeView(self):
        """ do all the treeview setup here """

        def lang_view_func(cell_layout, renderer, model, iter, data):
            langInfo = model.get_value(iter, LANGTREEVIEW_CODE)
            greyFlag = False
            myiter = model.get_iter_first()
            while myiter:
                str = model.get_value(myiter, LANGTREEVIEW_CODE)
                if str == langInfo:
                    greyFlag = False
                    break
                if str == "en":
                    greyFlag = True
                    break
                myiter = model.iter_next(myiter)
            if greyFlag:
                markup = '<span foreground="grey">%s</span>' % self._localeinfo.translate(
                    langInfo, native=True, allCountries=True
                )
            else:
                markup = "%s" % self._localeinfo.translate(langInfo, native=True, allCountries=True)
            renderer.set_property("markup", markup)

        renderer = Gtk.CellRendererText()
        column = Gtk.TreeViewColumn(_("Language"), renderer, text=LANGTREEVIEW_LANGUAGE)
        column.set_property("expand", True)
        column.set_cell_data_func(renderer, lang_view_func, None)
        self.treeview_locales.append_column(column)

        # build the store
        self._language_options = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING)
        self.treeview_locales.set_model(self._language_options)

    def _get_langinfo_on_cursor(self):
        (path, column) = self.treeview_languages.get_cursor()
        if not path:
            return None
        iter = self._langlist.get_iter(path)
        langInfo = self._langlist.get_value(iter, LIST_LANG_INFO)
        return langInfo

    def debug_pkg_status(self):
        langInfo = self._get_langinfo_on_cursor()
        for pkg in langInfo.languagePkgList.items():
            print (
                "%s, available: %s, installed: %s, doChange: %s"
                % (pkg[0], pkg[1].available, pkg[1].installed, pkg[1].doChange)
            )
        print ("inconsistent? : %s" % langInfo.inconsistent)

    def check_status(self):
        changed = False
        countInstall = 0
        countRemove = 0
        for (lang, langInfo) in self._langlist:
            if langInfo.changes:
                changed = True
                for item in langInfo.languagePkgList.values():
                    if item.doChange:
                        if item.installed:
                            countRemove = countRemove + 1
                        else:
                            countInstall = countInstall + 1
        # print "%(INSTALL)d to install, %(REMOVE)d to remove" % (countInstall, countRemove)
        # Translators: %(INSTALL)d is parsed; either keep it exactly as is or remove it entirely, but don't translate "INSTALL".
        textInstall = gettext.ngettext("%(INSTALL)d to install", "%(INSTALL)d to install", countInstall) % {
            "INSTALL": countInstall
        }
        # Translators: %(REMOVE)d is parsed; either keep it exactly as is or remove it entirely, but don't translate "REMOVE".
        textRemove = gettext.ngettext("%(REMOVE)d to remove", "%(REMOVE)d to remove", countRemove) % {
            "REMOVE": countRemove
        }
        if countRemove == 0 and countInstall == 0:
            self.label_install_remove.set_text("")
        elif countRemove == 0:
            self.label_install_remove.set_text(textInstall)
        elif countInstall == 0:
            self.label_install_remove.set_text(textRemove)
        else:
            # Translators: this string will concatenate the "%n to install" and "%n to remove" strings, you can replace the comma if you need to.
            self.label_install_remove.set_text(_("%s, %s") % (textInstall, textRemove))

        if changed:
            self.button_apply.set_sensitive(True)
        else:
            self.button_apply.set_sensitive(False)

    #    @honorBlockedSignals
    #    @insensitive
    #    def on_combobox_system_language_changed(self, widget):
    #        #print "on_combobox_system_language_changed()"
    #        if self.writeSystemDefaultLang():
    #            # queue a restart of gdm (if it is runing) to make the new
    #            # locales usable
    #            gdmscript = "/etc/init.d/gdm"
    #            if os.path.exists("/var/run/gdm.pid") and os.path.exists(gdmscript):
    #                self.runAsRoot(["invoke-rc.d","gdm","reload"])
    #        self.updateSystemDefaultCombo()
    #        if self.checkbutton_sync_languages.get_active() == True:
    #            self.combobox_user_language.set_active(self.combobox_system_language.get_active())
    #            self.updateUserDefaultCombo()

    #    @honorBlockedSignals
    #    @insensitive
    #    def on_combobox_user_language_changed(self, widget):
    #        #print "on_combobox_user_language_changed()"
    #        self.check_input_methods()
    #        self.writeUserDefaultLang()
    #        self.updateUserDefaultCombo()
    #        if self.checkbutton_sync_languages.get_active() == True:
    #            self.combobox_system_language.set_active(self.combobox_user_language.get_active())
    #            self.updateSystemDefaultCombo()

    @blockSignals
    def check_input_methods(self):
        """ check if the selected langauge has input method support
            and set checkbutton_enable_input_methods accordingly
        """
        if not self.imSwitch.available():
            return
        # get the current first item in the user LANGUAGE list,
        # but with country code added if not already present
        loc = language2locale(self.userEnvLanguage)
        code = re.split("[.@]", loc)[0]

        combo = self.combobox_input_method
        # cell = combo.get_child().get_cell_renderers()[0]
        # FIXME: use something else than a hardcoded value here
        # cell.set_property("wrap-width",300)
        # cell.set_property("wrap-mode",Pango.WRAP_WORD)
        model = combo.get_model()
        model.clear()

        # find the default
        currentIM = self.imSwitch.getInputMethodForLocale(code)
        if currentIM in (None, "default"):
            currentIM = "none"
        # print "Current IM: "+currentIM

        # find out about the other options
        for (i, IM) in enumerate(self.imSwitch.getAvailableInputMethods()):
            iter = model.append()
            name = _("none") if IM == "none" else IM
            model.set_value(iter, IM_CHOICE, IM)
            model.set_value(iter, IM_NAME, name)
            if IM == currentIM:
                combo.set_active(i)

    #        self.check_status()

    #    def writeInputMethodConfig(self):
    #        """
    #        write new input method defaults - currently we only support all_ALL
    #        """
    #        combo = self.combobox_user_language
    #        model = combo.get_model()
    #        if combo.get_active() < 0:
    #            return
    #        (lang, code) = model[combo.get_active()]
    #        # check if we need to do something
    #        new_value = self.checkbutton_enable_input_methods.get_active()
    #        if self.imSwitch.enabledForLocale(code) != new_value:
    #            if new_value:
    #                self.imSwitch.enable(code)
    #            else:
    #                self.imSwitch.disable(code)
    #            #self.showRebootRequired()
    #            #self.checkReloginNotification()

    #    @honorBlockedSignals
    #    def on_checkbutton_enable_input_methods_toggled(self, widget):
    #        #print "on_checkbutton_enable_input_methods_toggled()"
    #        active = self.checkbutton_enable_input_methods.get_active()
    #        self.combo_userlang_dirty = True
    #        self.setSensitive(False)
    #        self.writeInputMethodConfig()
    #        self.setSensitive(True)

    #    @honorBlockedSignals
    #    def on_checkbutton_sync_languages_toggled(self, widget):
    #        #print "on_checkbutton_sync_languages_toggled()"
    #        if self.checkbutton_sync_languages.get_active() == True:
    #            self.combobox_user_language.set_active(self.combobox_system_language.get_active())
    #            self.updateSystemDefaultCombo()

    def build_commit_lists(self):
        print self._cache.get_changes()

        try:
            for (lang, langInfo) in self._langlist:
                self._cache.tryChangeDetails(langInfo)
        except ExceptionPkgCacheBroken:
            self.error(
                _("Software database is broken"),
                _(
                    "It is impossible to install or remove any software. "
                    'Please use the package manager "Synaptic" or run '
                    '"sudo apt-get install -f" in a terminal to fix '
                    "this issue at first."
                ),
            )
            sys.exit(1)
        (to_inst, to_rm) = self._cache.getChangesList()
        # print "inst: %s" % to_inst
        # print "rm: %s" % to_rm
        print self._cache.get_changes()
        return (to_inst, to_rm)

    def error(self, summary, msg):
        d = Gtk.MessageDialog(
            parent=self.window_main,
            flags=Gtk.DialogFlags.MODAL,
            type=Gtk.MessageType.ERROR,
            buttons=Gtk.ButtonsType.CLOSE,
        )
        d.set_markup("<big><b>%s</b></big>\n\n%s" % (summary, msg))
        d.set_title = ""
        d.run()
        d.destroy()

    def _show_error_dialog(self, error):
        msg = str(error)
        self.error(msg, "")

    def verify_commit_lists(self, inst_list, rm_list):
        """ verify if the selected package can actually be installed """
        res = True
        try:
            for pkg in inst_list:
                if pkg in self._cache:
                    self._cache[pkg].mark_install()
            for pkg in rm_list:
                if pkg in self._cache:
                    self._cache[pkg].mark_delete()
        except SystemError:
            res = False

        # undo the selections
        self._cache.clear()
        if self._cache._depcache.broken_count != 0:
            self.error(
                _("Could not install the selected language support"),
                _(
                    "This is perhaps a bug of this application. Please "
                    "file a bug report at "
                    "https://bugs.launchpad.net/ubuntu/+source/language-selector/+filebug"
                ),
            )

            # something went pretty bad, re-get a cache
            progress = GtkProgress(self.dialog_progress, self.progressbar_cache, self.window_main)
            self._cache = apt.Cache(self._localeinfo, progress)
            progress.hide()
            res = False
        return res

    def commitAllChanges(self):
        """ 
        commit helper, builds the commit lists, verifies it
        
        returns the number of install/removed packages
        """
        self.setSensitive(False)
        # install the new packages (if any)
        (inst_list, rm_list) = self.build_commit_lists()
        if not self.verify_commit_lists(inst_list, rm_list):
            self.error(
                _("Could not install the full language support"),
                _(
                    "Usually this is related to an error in your "
                    "software archive or software manager. Check your "
                    "preferences in Software Sources (click the icon "
                    "at the very right of the top bar and select "
                    '"System Settings... -> Software Sources").'
                ),
            )
            self.setSensitive(True)
            return 0
        # print "inst_list: %s " % inst_list
        # print "rm_list: %s " % rm_list
        self.commit(inst_list, rm_list)

        self.setSensitive(True)
        return len(inst_list) + len(rm_list)

    def _run_transaction(self, transaction):
        dia = AptProgressDialog(transaction, parent=self.window_main)
        dia.connect("finished", self._on_finished)
        dia.run(error_handler=self._on_error)

    def _wait_for_aptdaemon_finish(self):
        while not self._transaction_finished:
            while Gtk.events_pending():
                Gtk.main_iteration()
            time.sleep(0.02)

    def _on_finished(self, dialog):
        dialog.hide()
        self._transaction_finished = True

    def _on_error(self, error):
        if hasattr(error, "get_dbus_name") and error.get_dbus_name() == "org.freedesktop.PolicyKit.Error.NotAuthorized":
            self.error(_("Could not install the full language support"), _("Failed to authorize to install packages."))
        else:
            self.error(_("Could not install the full language support"), str(error))
        self._transaction_finished = True

    def update_aptdaemon(self):
        self._transaction_finished = False
        self._update_aptdaemon()
        self._wait_for_aptdaemon_finish()

    @inline_callbacks
    def _update_aptdaemon(self):
        try:
            trans = yield self.ac.update_cache(defer=True)
            self._run_transaction(trans)
        except Exception, e:
            self._show_error_dialog(e)
class QtLanguageSelector(KCModule, LanguageSelectorBase):
    """ actual implementation of the qt GUI """

    def __init__(self, datadir, component_data=None, parent=None):
        LanguageSelectorBase.__init__(self, datadir)
        KCModule.__init__(self, component_data, parent)
        
        self.parentApp = KApplication.kApplication()
        self.ui = Ui_QtLanguageSelectorGUI()
        self.ui.setupUi(self)
        self.about = MakeAboutData()
        self.setAboutData(self.about)
        
        self.setWindowIcon(KIcon("preferences-desktop-locale"))
        
        self.imSwitch = ImSwitch()
        # remove dangling ImSwitch symlinks if present
        self.imSwitch.removeDanglingSymlinks()
        self.init()

        # connect the signals
        self.connect(self.ui.listViewLanguagesInst, SIGNAL("itemSelectionChanged()"), self.checkInstallableComponents)
        self.connect(self.ui.listViewLanguagesUninst, SIGNAL("itemSelectionChanged()"), self.onChanged)
        self.connect(self.ui.ktabwidget, SIGNAL("currentChanged(int)"), self.onTabChangeRevertApply)
        self.connect(self.ui.listBoxDefaultLanguage, SIGNAL("itemSelectionChanged()"), self.checkInputMethods)
        self.connect(self.ui.checkBoxTr, SIGNAL("stateChanged(int)"), self.onChanged)
        self.connect(self.ui.checkBoxIm, SIGNAL("stateChanged(int)"), self.onChanged)
        self.connect(self.ui.checkBoxSpell, SIGNAL("stateChanged(int)"), self.onChanged)
        self.connect(self.ui.checkBoxFonts, SIGNAL("stateChanged(int)"), self.onChanged)

    def init(self):
        self.translateUI()
        try:
            self.openCache(apt.progress.OpProgress())
        except ExceptionPkgCacheBroken:
            s = _("Software database is broken")
            t = _("It is impossible to install or remove any software. "
                  "Please use the package manager \"Adept\" or run "
                  "\"sudo apt-get install -f\" in a terminal to fix "
                  "this issue at first.")
            KMessageBox.error(self, t, s)
            sys.exit(1)
        self.updateLanguagesList()
        self.updateSystemDefaultListbox()

        if not self._cache.havePackageLists:
            yesText = _("_Update").replace("_", "&")
            noText = _("_Remind Me Later").replace("_", "&")
            yes = KGuiItem(yesText, "dialog-ok")
            no = KGuiItem(noText, "process-stop")
            text = "<big><b>%s</b></big>\n\n%s" % (
              _("No language information available"),
              _("The system does not have information about the "
                "available languages yet. Do you want to perform "
                "a network update to get them now? "))
            text = text.replace("\n", "<br />")
            res = KMessageBox.questionYesNo(self, text, "", yes, no)
            if res == KMessageBox.Yes:
                self.setEnabled(False)
                self.update()
                self.openCache(apt.progress.OpProgress())
                self.updateLanguagesList()
                self.setEnabled(True)

    def load(self):
      # See if something is missing
      self.verifyInstalledLangPacks()

    def save(self):
        idx = self.ui.ktabwidget.currentIndex()

        if idx == 0:
            self.pkgChanges("install")
        elif idx == 1:
            self.pkgChanges("uninstall")
        else:
            self.onSystemLanguageApply()

    def translateUI(self):
        """ translate the strings in the UI, needed because Qt designer doesn't use gettext """
        self.ui.ktabwidget.setTabText(self.ui.ktabwidget.indexOf(self.ui.SystemDefaultTab), _("Set System Language"))
        self.ui.defaultSystemLabel.setText(_("Default system language:"))
        self.ui.labelInputMethod.setText(_("Keyboard input method:"))
        self.ui.selectLanguageLabel.setText(_("Select language to install:"))
        self.ui.selectLanguageLabel_2.setText(_("Select language to uninstall:"))
        self.ui.checkBoxTr.setText(_("Translations"))
        self.ui.checkBoxIm.setText(_("Input methods"))
        self.ui.checkBoxSpell.setText(_("Spellchecking and writing aids"))
        self.ui.checkBoxFonts.setText(_("Extra fonts"))
        self.ui.ComponentsLabel.setText(_("Components:"))
         
    def updateSystemDefaultListbox(self):
        self.ui.listBoxDefaultLanguage.clear()
        self._localeinfo.localeToCodeMap = {}
        # get the current default lang
        defaultLangName = None
        defaultLangCode = self._localeinfo.getSystemDefaultLanguage()[0]
        if defaultLangCode:
            defaultLangName = utf8(self._localeinfo.translate(defaultLangCode, native=True))
        locales = []
        for locale in self._localeinfo.generated_locales():
            name = utf8(self._localeinfo.translate(locale, native=True))
            locales.append(name)
            self._localeinfo.localeToCodeMap[name] = locale
        locales.sort()
        for localeName in locales:
            item = QListWidgetItem(utf8(localeName), self.ui.listBoxDefaultLanguage)
            if defaultLangName == localeName:
                item.setSelected(True)
        if (not os.path.exists("/etc/alternatives/xinput-all_ALL") or
            not os.path.exists("/usr/bin/im-switch")):
            self.ui.comboBoxInputMethod.setEnabled(False)

    def verifyInstalledLangPacks(self):
        """ called at the start to inform about possible missing
            langpacks (e.g. gnome/kde langpack transition)
        """
        print "verifyInstalledLangPacks"
        missing = self.getMissingLangPacks()

        print "Missing: %s " % missing
        if len(missing) > 0:
            # FIXME: add "details"
            yesText = _("_Install").replace("_", "&")
            noText = _("_Remind Me Later").replace("_", "&")
            yes = KGuiItem(yesText, "dialog-ok")
            no = KGuiItem(noText, "process-stop")
            text = "<big><b>%s</b></big>\n\n%s" % (
                _("The language support is not installed completely"),
                _("Some translations or writing aids available for your "
                  "chosen languages are not installed yet. Do you want "
                  "to install them now?"))
            text = text.replace("\n", "<br />")
            res = KMessageBox.questionYesNo(self, text, "", yes, no)
            if res == KMessageBox.Yes:
                self.setEnabled(False)
                self.commit(missing, [])
                self.updateLanguagesList()
                self.setEnabled(True)

    def update(self):
        self.run_pkg_manager_update()

    def commit(self, inst, rm):
        # unlock here to make sure that lock/unlock are always run
        # pair-wise (and don't explode on errors)
        if len(inst) == 0 and len(rm) == 0:
            return
        self.run_pkg_manager(inst,rm)

    def updateLanguagesList(self):
        self.ui.listViewLanguagesInst.clear()
        self.ui.listViewLanguagesUninst.clear()
        # get the language names and sort them alphabetically
        languageList = self._cache.getLanguageInformation()
        self._localeinfo.listviewStrToLangInfoMap = {}
        for lang in languageList:
            self._localeinfo.listviewStrToLangInfoMap[utf8(self._localeinfo.translate(lang.languageCode))] = lang
        languages = self._localeinfo.listviewStrToLangInfoMap.keys()
        languages.sort()

        for langName in languages:
            lang = self._localeinfo.listviewStrToLangInfoMap[langName]
            elmIn = QListWidgetItem(utf8(self._localeinfo.translate(lang.languageCode)), self.ui.listViewLanguagesInst)
            elmUn = QListWidgetItem(utf8(self._localeinfo.translate(lang.languageCode)), self.ui.listViewLanguagesUninst)
            
            if lang.fullInstalled:
                elmIn.setFlags(Qt.ItemIsDropEnabled)  #not sure how to unset all flags, but this disables the item
                elmIn.setToolTip(_("Already installed"))
                elmUn.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
            elif lang.inconsistent:
                elmIn.setToolTip(_("Partially Installed"))
            else:
                elmUn.setFlags(Qt.ItemIsDropEnabled)  #not sure how to unset all flags, but this disables the item
                elmUn.setToolTip(_("Not installed"))
                elmUn.setHidden(True)
                elmIn.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)

    def onChanged(self, state = 1):
        if state:
            self.changed()
        else:
            for button in [ "checkBoxTr", "checkBoxIm", "checkBoxSpell", "checkBoxFonts" ]:
                if getattr(self.ui, button).isEnabled() and getattr(self.ui, button).isChecked():
                    return
            self.emit(SIGNAL("changed(bool)"), False)

    def onTabChangeRevertApply(self):
        for listView in [ "listViewLanguagesInst", "listViewLanguagesUninst", "listBoxDefaultLanguage" ]:
          getattr(self.ui, listView).clearSelection()
        for button in [ "checkBoxTr", "checkBoxIm", "checkBoxSpell", "checkBoxFonts" ]:
          getattr(self.ui, button).setChecked(False)
          getattr(self.ui, button).setEnabled(False)
        self.emit(SIGNAL("changed(bool)"), False)

    def checkInstallableComponents(self):
        """ check available components for the selected language
            and set/unset the corresponding checkbutton accordingly
        """
        items = self.ui.listViewLanguagesInst.selectedItems()

        if len(items) == 1:
            li = self._localeinfo.listviewStrToLangInfoMap[unicode(items[0].text())]
            langPkg = li.languagePkgList["languagePack"]
            self.ui.checkBoxTr.setEnabled(langPkg.available)
            self.ui.checkBoxTr.setChecked(False)
            if langPkg.installed:
                self.ui.checkBoxTr.setChecked(True)
                self.ui.checkBoxTr.setEnabled(False)
                self.ui.checkBoxTr.setToolTip(_("Component already installed"))
            elif not langPkg.available:
                self.ui.checkBoxTr.setToolTip(_("Component not available"))
            else:
                self.ui.checkBoxTr.setToolTip(_("Component not installed"))
        
    def checkInputMethods(self):
        """ check if the selected language has input method support
            and set checkbutton_enable_input_methods accordingly
        """
        if (not self.imSwitch.available()) or (not self.getSystemLanguage()):
            return
        self.changed()
        (lang, code) = self.getSystemLanguage()

        combo = self.ui.comboBoxInputMethod
        combo.clear()

        currentIM = self.imSwitch.getInputMethodForLocale(code)
        if currentIM == None:
            currentIM = 'none'

        for (i, IM) in enumerate(self.imSwitch.getAvailableInputMethods()):
            combo.insertItem(i,IM)
            if IM == currentIM:
                combo.setCurrentIndex(i)

    def run_pkg_manager_update(self):
        self.returncode = 0
        self.returncode = subprocess.call(["qapt-batch", "--attach", str(self.winId()), "--update"])

    def run_pkg_manager(self, to_inst, to_rm):
        self.returncode = 0
        if len(to_inst) > 0:
            print str(["qapt-batch","--install"]+to_inst)
            self.returncode = subprocess.call(["qapt-batch", "--attach", str(self.winId()), "--install"]+to_inst)
        # then remove
        if len(to_rm) > 0:
            print str(["qapt-batch","--uninstall"]+to_rm)
            self.returncode = subprocess.call(["qapt-batch", "--attach", str(self.winId()), "--uninstall"]+to_rm)

    def onSystemLanguageApply(self):
        (lang, code) = self.getSystemLanguage()
        self.writeSysLanguageSetting(code)
        self.writeSysLangSetting(code)
        self.updateInputMethods(code)
        KMessageBox.information(self, _("Default system Language now set to %s.") % lang, _("Language Set"))

    def updateInputMethods(self,code):
        IM_choice = self.ui.comboBoxInputMethod.currentText()
        self.imSwitch.setInputMethodForLocale(IM_choice, code)

    def getSystemLanguage(self):
        """ returns tuple of (lang, code) strings """
        items = self.ui.listBoxDefaultLanguage.selectedItems()
        if len(items) == 1:
            item = items[0]
            lang = item.text()
            new_locale = ("%s"%lang)
            try:
                code = self._localeinfo.localeToCodeMap[new_locale]
                return (lang, code)
            except KeyError:
                print "ERROR: can not find new_locale: '%s'"%new_locale
      
    def pkgChanges(self, mode):

        if mode == "install":
            items = self.ui.listViewLanguagesInst.selectedItems()
        else:
            items = self.ui.listViewLanguagesUninst.selectedItems()
            
        if len(items) == 1:
            elm = items[0]
            li = self._localeinfo.listviewStrToLangInfoMap[unicode(elm.text())]
            langPkg = li.languagePkgList["languagePack"]
            if langPkg.available:
                if (mode == "install") and (not langPkg.installed):
                    langPkg.doChange = self.ui.checkBoxTr.isChecked()
                elif (mode == "uninstall") and langPkg.installed:
                    langPkg.doChange = True
            try:
                self._cache.tryChangeDetails(li)
                for langPkg in li.languagePkgList.values():
                  langPkg.doChange = False
            except ExceptionPkgCacheBroken:
                s = _("Software database is broken")
                t = _("It is impossible to install or remove any software. "
                      "Please use the package manager \"Adept\" or run "
                      "\"sudo apt-get install -f\" in a terminal to fix "
                      "this issue at first.")
                KMessageBox.error(self, t, s)
                sys.exit(1)

        (to_inst, to_rm) = self._cache.getChangesList()
        if len(to_inst) == len(to_rm) == 0:
            return
        # first install
        self.setCursor(Qt.WaitCursor)
        self.setEnabled(False)
        self.run_pkg_manager(to_inst,to_rm)
        self.setCursor(Qt.ArrowCursor)
        self.setEnabled(True)
        
#        kdmscript = "/etc/init.d/kdm"
#        if os.path.exists("/var/run/kdm.pid") and os.path.exists(kdmscript):
#            subprocess.call(["invoke-rc.d","kdm","reload"])

        #self.run_pkg_manager(to_inst, to_rm)

        if self.returncode == 0:
            if (mode == "install"):
                KMessageBox.information( self, _("All selected components have now been installed for %s.  Select them from Country/Region & Language.") % unicode(items[0].text()), _("Language Installed") )
            elif (mode == "uninstall"):
                KMessageBox.information( self, _("Translations and support have now been uninstalled for %s.") % unicode(items[0].text()), _("Language Uninstalled") )
            # Resync the cache to match packageManager changes, then update views
            self._cache.open(None)
            self.updateLanguagesList()
            self.updateSystemDefaultListbox()
            if mode == "install":
                self.checkInstallableComponents()
        else:
            KMessageBox.sorry(self, _("Failed to set system language."), _("Language Not Set"))
            self._cache.clear() # undo all selections