# # task_gui.py: Choose tasks for installation # # Copyright 2006 Red Hat, Inc. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # import gtk import gtk.glade import gobject import gui from iw_gui import * from rhpl.translate import _, N_ from constants import productName from netconfig_dialog import NetworkConfigurator import network from yuminstall import AnacondaYumRepo import yum.Errors import logging log = logging.getLogger("anaconda") class TaskWindow(InstallWindow): def getNext(self): if self.xml.get_widget("customRadio").get_active(): self.dispatch.skipStep("group-selection", skip = 0) else: self.dispatch.skipStep("group-selection", skip = 1) tasks = self.xml.get_widget("taskList").get_model() # Quick hack to handle overlapping groups in tasks for an installclass for (cb, task, grps) in tasks: if not cb: map(self.backend.deselectGroup, grps) for (cb, task, grps) in tasks: if cb: map(self.backend.selectGroup, grps) if self.anaconda.id.instClass.allowExtraRepos: repos = self.xml.get_widget("repoList").get_model() for (cb, reponame, repo) in repos: if cb: repo.enable() # Setup any repositories that were in the installclass's # default list. if not repo.ready(): self._setupRepo(repo) else: repo.disable() def groupsInstalled(self, lst): # FIXME: yum specific rc = False for gid in lst: g = self.backend.ayum.comps.return_group(gid) if g and not g.selected: return False elif g: rc = True return rc def groupsExist(self, lst): # FIXME: yum specific for gid in lst: g = self.backend.ayum.comps.return_group(gid) if not g: return False return True def _setupRepo(self, repo): try: self.backend.doRepoSetup(self.anaconda, repo.id, fatalerrors = False) log.info("added repository %s with with source URL %s" % (repo.name, repo.baseurl[0])) except yum.Errors.RepoError, e: self.intf.messageWindow(_("Error"), _("Unable to read package metadata from repository. " "This may be due to a missing repodata directory. " "Please ensure that your repository has been " "correctly generated.\n\n%s" %(e,)), type="ok", custom_icon="error") self.backend.ayum.repos.delete(repo.id) return False if not repo.groups_added: self.intf.messageWindow(_("Warning"), _("Unable to find a group file for %s. " "This will make manual selection of packages " "from the repository not work") %(repo.id,), type="warning") return True def _addRepo(self, *args): if not network.hasActiveNetDev(): net = NetworkConfigurator(self.anaconda.id.network) ret = net.run() net.destroy() if ret == gtk.RESPONSE_CANCEL: return gtk.RESPONSE_CANCEL (dxml, dialog) = gui.getGladeWidget("addrepo.glade", "addRepoDialog") gui.addFrame(dialog) lbl = dxml.get_widget("descLabel") txt = lbl.get_text() lbl.set_text(txt %(productName,)) dialog.show_all() while 1: rc = dialog.run() if rc == gtk.RESPONSE_CANCEL: break reponame = dxml.get_widget("nameEntry").get_text() reponame.strip() if len(reponame) == 0: self.intf.messageWindow(_("Invalid Repository Name"), _("You must provide a non-zero length " "repository name.")) continue repourl = dxml.get_widget("urlEntry").get_text() repourl.strip() if (len(repourl) == 0 or not (repourl.startswith("http://") or repourl.startswith("ftp://"))): self.intf.messageWindow(_("Invalid Repository URL"), _("You must provide an HTTP or FTP " "URL to a repository.")) continue # FIXME: this is yum specific repo = AnacondaYumRepo(uri=repourl, repoid=reponame) repo.name = reponame repo.basecachedir = self.backend.ayum.conf.cachedir repo.enable() try: self.backend.ayum.repos.add(repo) except yum.Errors.DuplicateRepoError, e: self.intf.messageWindow(_("Error"), _("The repository %s has already been added. Please " "choose a different repository name and " "URL.") % reponame, type="ok", custom_icon="error") continue if not self._setupRepo(repo): continue s = self.xml.get_widget("repoList").get_model() s.append([repo.isEnabled(), repo.name, repo]) self.repos[repo.name] = (repo.baseurl[0], None) break dialog.destroy() return rc def _taskToggled(self, data, row, store): i = store.get_iter(int(row)) val = store.get_value(i, 0) store.set_value(i, 0, not val) def _repoToggled(self, data, row, store): i = store.get_iter(int(row)) val = store.get_value(i, 0) if not val and not network.hasActiveNetDev(): net = NetworkConfigurator(self.anaconda.id.network) ret = net.run() net.destroy() if ret == gtk.RESPONSE_CANCEL: return store.set_value(i, 0, not val) def _createTaskStore(self): store = gtk.ListStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_PYOBJECT) tl = self.xml.get_widget("taskList") tl.set_model(store) cbr = gtk.CellRendererToggle() col = gtk.TreeViewColumn('', cbr, active = 0) cbr.connect("toggled", self._taskToggled, store) tl.append_column(col) col = gtk.TreeViewColumn('Text', gtk.CellRendererText(), text = 1) col.set_clickable(False) tl.append_column(col) for (txt, grps) in self.tasks: if not self.groupsExist(grps): continue store.append([self.groupsInstalled(grps), _(txt), grps]) return len(store) def _createRepoStore(self): store = gtk.ListStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_PYOBJECT) tl = self.xml.get_widget("repoList") tl.set_model(store) cbr = gtk.CellRendererToggle() col = gtk.TreeViewColumn('', cbr, active = 0) cbr.connect("toggled", self._repoToggled, store) tl.append_column(col) col = gtk.TreeViewColumn('Text', gtk.CellRendererText(), text = 1) col.set_clickable(False) tl.append_column(col) for (reponame, uri) in self.repos.items(): repoid = reponame.replace(" ", "") if not self.backend.ayum.repos.repos.has_key(repoid): continue repo = self.backend.ayum.repos.repos[repoid] store.append([repo.isEnabled(), repo.name, repo]) def getScreen (self, anaconda): self.intf = anaconda.intf self.dispatch = anaconda.dispatch self.backend = anaconda.backend self.anaconda = anaconda self.tasks = anaconda.id.instClass.tasks self.repos = anaconda.id.instClass.repos (self.xml, vbox) = gui.getGladeWidget("tasksel.glade", "taskBox") lbl = self.xml.get_widget("mainLabel") if anaconda.id.instClass.description: lbl.set_text(_(anaconda.id.instClass.description)) else: txt = lbl.get_text() lbl.set_text(txt %(productName,)) custom = not self.dispatch.stepInSkipList("group-selection") if custom: self.xml.get_widget("customRadio").set_active(True) else: self.xml.get_widget("customRadio").set_active(False) if self._createTaskStore() == 0: self.xml.get_widget("cbVBox").hide() self.xml.get_widget("mainLabel").hide() self._createRepoStore() if not anaconda.id.instClass.allowExtraRepos: vbox.remove(self.xml.get_widget("addRepoBox")) self.xml.get_widget("addRepoButton").connect("clicked", self._addRepo) return vbox