diff options
Diffstat (limited to 'portato/gui/windows/main.py')
-rw-r--r-- | portato/gui/windows/main.py | 3482 |
1 files changed, 1741 insertions, 1741 deletions
diff --git a/portato/gui/windows/main.py b/portato/gui/windows/main.py index 1b7c0f0..fca4535 100644 --- a/portato/gui/windows/main.py +++ b/portato/gui/windows/main.py @@ -36,8 +36,8 @@ from ..session import SESSION_VERSION, SessionException, OldSessionException, Ne from ..wrapper import GtkTree, GtkConsole from ..views import LogView, HighlightView, InstalledOnlyView from ..dialogs import (blocked_dialog, changed_flags_dialog, io_ex_dialog, - nothing_found_dialog, queue_not_empty_dialog, remove_deps_dialog, - remove_queue_dialog, remove_updates_dialog, unmask_dialog) + nothing_found_dialog, queue_not_empty_dialog, remove_deps_dialog, + remove_queue_dialog, remove_updates_dialog, unmask_dialog) # even more GUI stuff from .basic import Window, Popup @@ -48,1744 +48,1744 @@ from .search import SearchWindow from .update import UpdateWindow class PackageTable: - """A window with data about a specfic package.""" - - def __init__ (self, main): - """Build up window contents. - - @param main: the main window - @type main: MainWindow""" - - self.main = main - self.tree = main.tree - self.window = main.window - self.tree.signal_autoconnect(self) - - # all the package data is in this one VB - self.vb = self.tree.get_widget("packageVB") - - # the notebook - self.notebook = self.tree.get_widget("packageNotebook") - - # chechboxes - self.installedCheck = self.tree.get_widget("installedCheck") - self.maskedCheck = self.tree.get_widget("maskedCheck") - self.testingCheck = self.tree.get_widget("testingCheck") - self.maskedLabel = self.tree.get_widget("maskedLabel") - - # labels - generalVB = self.tree.get_widget("generalVB") - generalVB.modify_bg(gtk.STATE_NORMAL, get_color(self.main.cfg, "packagetable")) - - self.nameLabel = self.tree.get_widget("nameLabel") - self.descLabel = self.tree.get_widget("descLabel") - self.overlayLabel = self.tree.get_widget("overlayLabel") - self.overlayLL = self.tree.get_widget("overlayLabelLabel") - self.licenseLabel = self.tree.get_widget("licenseLabel") - self.linkBox = self.tree.get_widget("linkBox") - self.notInSysLabel = self.tree.get_widget("notInSysLabel") - self.missingLabel = self.tree.get_widget("missingLabel") - self.useFlagsLabel = self.tree.get_widget("useFlagsLabel") - self.useFlagsLL = self.tree.get_widget("useFlagsLabelLabel") - - # buttons - self.emergeBtn = self.tree.get_widget("pkgEmergeBtn") - self.unmergeBtn = self.tree.get_widget("pkgUnmergeBtn") - self.revertBtn = self.tree.get_widget("pkgRevertBtn") - - # useList - self.useList = self.tree.get_widget("useList") - self.build_use_list() - - # depList - self.depList = self.tree.get_widget("dependencyList") - self.build_dep_list() - - # views - self.ebuildView = self.tree.get_widget("ebuildScroll").get_child() - self.changelogView = self.tree.get_widget("changelogScroll").get_child() - self.filesView = self.tree.get_widget("filesScroll").get_child() - - # icons - self.icons = {} - self.icons["use"] = self.window.render_icon(gtk.STOCK_REMOVE, gtk.ICON_SIZE_MENU) - self.icons["installed"] = self.window.render_icon(gtk.STOCK_YES, gtk.ICON_SIZE_MENU) - self.icons["or"] = self.window.render_icon(gtk.STOCK_MEDIA_PAUSE, gtk.ICON_SIZE_MENU) - self.icons["block"] = self.window.render_icon(gtk.STOCK_NO, gtk.ICON_SIZE_MENU) - - def update (self, pkg, queue = None, doEmerge = True, instantChange = False, type = None): - """Updates the table to show the contents for the package. - - @param pkg: the selected package - @type pkg: Package - @param queue: emerge-queue (if None the emerge-buttons are disabled) - @type queue: EmergeQueue - @param doEmerge: if False, the emerge buttons are disabled - @type doEmerge: boolean - @param instantChange: if True the changed keywords are updated instantly - @type instantChange: boolean - @param type: the type of the queue this package is in; if None there is no queue :) - @type type: string""" - - self.pkg = pkg - self.queue = queue - self.doEmerge = doEmerge - self.instantChange = instantChange - self.type = type - - if not self.queue or not self.doEmerge: - self.emergeBtn.set_sensitive(False) - self.unmergeBtn.set_sensitive(False) - - # current status - self._update_table() - self.vb.show_all() - - def hide (self): - self.vb.hide_all() - - def set_labels (self): - pkg = self.pkg - - # name - self.nameLabel.set_markup("<b>%s</b>" % pkg.get_cpv()) - - # description - desc = pkg.get_package_settings("DESCRIPTION") or _("<no description>") - self.descLabel.set_label(desc) - - # overlay - if pkg.is_in_overlay(): - self.overlayLabel.set_label(pkg.get_overlay_path()) - self.overlayLabel.show() - self.overlayLL.show() - else: - self.overlayLabel.hide() - self.overlayLL.hide() - - # license - self.licenseLabel.set_label(pkg.get_package_settings("LICENSE")) - - # link - for c in self.linkBox.get_children(): - self.linkBox.remove(c) - - text = pkg.get_package_settings("HOMEPAGE") - texts = text.split(" ") - ftexts = [] - - for count, t in enumerate(texts): - if not t.startswith(("http", "ftp")): - if count == 0: - error(_("The first homepage part does not start with 'http' or 'ftp'.")) - ftexts.append(t) - continue - else: - info(_("Blank inside homepage.")) - ftexts[-1] += " %s" % t - else: - ftexts.append(t) - - for t in ftexts: - link = gtk.LinkButton(t) - link.set_alignment(0.0, 0.5) - link.set_border_width(0) - self.linkBox.add(link) - - # useflags - flaglist = list(itt.ifilterfalse(pkg.use_expanded, pkg.get_iuse_flags())) - flaglist.sort() - flags = ", ".join(flaglist) - - if flags: - self.useFlagsLL.show() - self.useFlagsLabel.show() - self.useFlagsLabel.set_label(flags) - else: - self.useFlagsLL.hide() - self.useFlagsLabel.hide() - - def fill_dep_list(self): - - store = self.depList.get_model() - - def add (tree, it): - - def get_icon (dep): - if dep.satisfied: - return self.icons["installed"] - elif dep.dep[0] == "!": - return self.icons["block"] - else: - return None - - # useflags - for use, usetree in tree.flags.iteritems(): - if use[0] == "!": - usestring = _("If '%s' is disabled") % use[1:] - else: - usestring = _("If '%s' is enabled") % use - useit = store.append(it, [self.icons["use"], usestring]) - add(usetree, useit) - - # ORs - ordeps = (dep for dep in tree.deps if isinstance(dep, dependency.OrDependency)) - - for ordep in ordeps: - orit = store.append(it, [self.icons["or"], _("One of the following")]) - - for dep in ordep.dep: - if isinstance(dep, dependency.AllOfDependency): # a list inside or - allit = store.append(orit, [None, _("All of the following")]) - for adep in dep.dep: - store.append(allit, [get_icon(adep), adep.dep]) - else: - store.append(orit, [get_icon(dep), dep.dep]) - - # normal - def sort_key (x): - split = system.split_cpv(x.dep) - - if split is None: # split_cpv returns None if this is only a CP; we assume there are only valid deps - return x.dep - else: - return "/".join(split[0:2]) - - ndeps = [dep for dep in tree.deps if not isinstance(dep, dependency.OrDependency)] - ndeps.sort(key = sort_key) - for dep in ndeps: - store.append(it, [get_icon(dep), dep.dep]) - - try: - deptree = self.pkg.get_dependencies() - except AssertionError: - w = _("Can't display dependencies: This package has an unsupported dependency string.") - error(w) - store.append(None, [None, w]) - else: - add(deptree, None) - - def fill_use_list(self): - - pkg = self.pkg - pkg_flags = pkg.get_iuse_flags() - pkg_flags.sort() - - actual_exp = None - actual_exp_it = None - - euse = pkg.get_actual_use_flags() - instuse = pkg.get_installed_use_flags() - - store = self.useList.get_model() - - for use in pkg_flags: - exp = pkg.use_expanded(use, suggest = actual_exp) - if exp is not None: - if exp != actual_exp: - actual_exp_it = store.append(None, [None, None, exp, "<i>%s</i>" % _("This is an expanded use flag and cannot be selected")]) - actual_exp = exp - else: - actual_exp_it = None - actual_exp = None - - enabled = use in euse - installed = use in instuse - store.append(actual_exp_it, [enabled, installed, use, system.get_use_desc(use, self.pkg.get_cp())]) - - def build_dep_list (self): - store = gtk.TreeStore(gtk.gdk.Pixbuf, str) - - self.depList.set_model(store) - - col = gtk.TreeViewColumn() - - cell = gtk.CellRendererPixbuf() - col.pack_start(cell, False) - col.add_attribute(cell, "pixbuf", 0) - - cell = gtk.CellRendererText() - col.pack_start(cell, True) - col.add_attribute(cell, "text", 1) - - self.depList.append_column(col) - - def build_use_list (self): - """Builds the useList.""" - store = gtk.TreeStore(bool, bool, str, str) - self.useList.set_model(store) - - # build view - cell = gtk.CellRendererText() - iCell = gtk.CellRendererToggle() - iCell.set_property("activatable", False) - tCell = gtk.CellRendererToggle() - tCell.set_property("activatable", True) - tCell.connect("toggled", self.cb_use_flag_toggled, store) - self.useList.append_column(gtk.TreeViewColumn(_("Enabled"), tCell, active = 0)) - self.useList.append_column(gtk.TreeViewColumn(_("Installed"), iCell, active = 1)) - self.useList.append_column(gtk.TreeViewColumn(_("Flag"), cell, text = 2)) - self.useList.append_column(gtk.TreeViewColumn(_("Description"), cell, markup = 3)) - - self.useList.set_search_column(2) - self.useList.set_enable_tree_lines(True) - - def _update_keywords (self, emerge, update = False): - if emerge: - type = "install" if not self.type else self.type - try: - try: - self.queue.append(self.pkg.get_cpv(), type = type, update = update) - except PackageNotFoundException, e: - if unmask_dialog(e[0]) == gtk.RESPONSE_YES: - self.queue.append(self.pkg.get_cpv(), type = type, unmask = True, update = update) - except BlockedException, e: - blocked_dialog(e[0], e[1]) - else: - try: - self.queue.append(self.pkg.get_cpv(), type = "uninstall") - except PackageNotFoundException, e: - error(_("Package could not be found: %s"), e[0]) - #masked_dialog(e[0]) - - def _update_table (self, *args): - - pkg = self.pkg - - # set the views - for v in (self.ebuildView, self.changelogView, self.filesView): - v.update(pkg, force = self.notebook.get_nth_page(self.notebook.get_current_page()) == v.get_parent()) - - # set the labels - self.set_labels() - - # set use list - self.useList.get_model().clear() - self.useList.columns_autosize() - self.fill_use_list() - - # set dep list - self.depList.get_model().clear() - self.useList.columns_autosize() - self.fill_dep_list() - - # - # rebuild the buttons and checkboxes in all the different manners which are possible - # - if (not pkg.is_in_system()) or pkg.is_missing_keyword(): - if not pkg.is_in_system(): - self.missingLabel.hide() - self.notInSysLabel.show() - else: # missing keyword - self.missingLabel.show() - self.notInSysLabel.hide() -# - self.installedCheck.hide() - self.maskedCheck.hide() - self.maskedLabel.hide() - self.testingCheck.hide() - self.emergeBtn.set_sensitive(False) - else: # normal package - self.missingLabel.hide() - self.notInSysLabel.hide() - self.installedCheck.show() - self.maskedCheck.show() - self.maskedLabel.show() - self.testingCheck.show() - if self.doEmerge: - self.emergeBtn.set_sensitive(True) - self.installedCheck.set_active(pkg.is_installed()) - - reason = pkg.get_masking_reason() or " " - if pkg.is_masked(use_changed = False) and not pkg.is_masked(use_changed = True): - self.maskedCheck.set_label("<i>(%s)</i>" % _("Masked")) - self.maskedCheck.get_child().set_use_markup(True) - else: - self.maskedCheck.set_label(_("Masked")) - - if pkg.is_locally_masked(): - self.maskedCheck.set_label("<b>%s</b>" % _("Masked")) - self.maskedCheck.get_child().set_use_markup(True) - self.maskedCheck.set_active(True) - reason = _("Masked by user") - else: - self.maskedCheck.set_active(pkg.is_masked(use_changed = False)) - - if reason: - self.maskedLabel.set_label(reason) - - if pkg.is_testing(use_keywords = False) and not pkg.is_testing(use_keywords = True): - self.testingCheck.set_label("<i>(%s)</i>" % _("Testing")) - self.testingCheck.get_child().set_use_markup(True) - else: - self.testingCheck.set_label(_("Testing")) - - self.testingCheck.set_active(pkg.is_testing(use_keywords = False)) - - if self.doEmerge: - # set emerge-button-label - if not pkg.is_installed(): - self.unmergeBtn.set_sensitive(False) - else: - self.unmergeBtn.set_sensitive(True) - - self.vb.show_all() - return True - - def cb_button_pressed (self, b, event): - """Callback for pressed checkboxes. Just quits the event-loop - no redrawing.""" - if not isinstance(b, gtk.CellRendererToggle): - b.emit_stop_by_name("button-press-event") - return True - - def cb_package_revert_clicked (self, button): - """Callback for pressed revert-button.""" - self.pkg.remove_new_use_flags() - self.pkg.remove_new_masked() - self.pkg.remove_new_testing() - self._update_table() - if self.instantChange: - self._update_keywords(True, update = True) - return True - - def cb_package_emerge_clicked (self, button): - """Callback for pressed emerge-button. Adds the package to the EmergeQueue.""" - self._update_keywords(True) - self.main.sysNotebook.set_current_page(self.main.QUEUE_PAGE) - return True - - def cb_package_unmerge_clicked (self, button): - """Callback for pressed unmerge-button clicked. Adds the package to the UnmergeQueue.""" - self._update_keywords(False) - self.main.sysNotebook.set_current_page(self.main.QUEUE_PAGE) - return True - - def cb_testing_toggled (self, button): - """Callback for toggled testing-checkbox.""" - status = button.get_active() - - # end of recursion :) - if self.pkg.is_testing(use_keywords = False) == status: - return False - - # if the package is not testing - don't allow to set it as such - if not self.pkg.is_testing(use_keywords = False): - button.set_active(False) - return True - - # re-set to testing status - if not self.pkg.is_testing(use_keywords = True): - self.pkg.set_testing(False) - button.set_label(_("Testing")) - button.set_active(True) - else: # disable testing - self.pkg.set_testing(True) - button.set_label("<i>(%s)</i>" % _("Testing")) - button.get_child().set_use_markup(True) - button.set_active(True) - - if self.instantChange: - self._update_keywords(True, update = True) - - return True - - def cb_masked_toggled (self, button): - """Callback for toggled masking-checkbox.""" - status = button.get_active() - pkg = self.pkg - - if pkg.is_masked(use_changed = False) == status and not pkg.is_locally_masked(): - return False - - if pkg.is_locally_masked() and status: - return False - - if not pkg.is_masked(use_changed = True): - pkg.set_masked(True) - if pkg.is_locally_masked(): - button.set_label("<b>%s</b>" % _("Masked")) - button.get_child().set_use_markup(True) - self.maskedLabel.set_label(_("Masked by user")) - else: - button.set_label(_("Masked")) - - button.set_active(True) - else: - locally = pkg.is_locally_masked() - pkg.set_masked(False) - if pkg.is_masked(use_changed=False) and not locally: - button.set_label("<i>(%s)</i>" % _("Masked")) - button.get_child().set_use_markup(True) - button.set_active(True) - else: - button.set_label(_("Masked")) - self.maskedLabel.set_label("") - - if self.instantChange: - self._update_keywords(True, update = True) - - return True - - def cb_use_flag_toggled (self, cell, path, store): - """Callback for a toggled use-flag button.""" - flag = store[path][2] - pkg = self.pkg - - if pkg.use_expanded(flag): # ignore expanded flags - return False - - store[path][0] = not store[path][0] - prefix = "" - if not store[path][0]: - prefix = "-" - - pkg.set_use_flag(prefix+flag) - if self.instantChange: - self._update_keywords(True, update = True) - - return True + """A window with data about a specfic package.""" + + def __init__ (self, main): + """Build up window contents. + + @param main: the main window + @type main: MainWindow""" + + self.main = main + self.tree = main.tree + self.window = main.window + self.tree.signal_autoconnect(self) + + # all the package data is in this one VB + self.vb = self.tree.get_widget("packageVB") + + # the notebook + self.notebook = self.tree.get_widget("packageNotebook") + + # chechboxes + self.installedCheck = self.tree.get_widget("installedCheck") + self.maskedCheck = self.tree.get_widget("maskedCheck") + self.testingCheck = self.tree.get_widget("testingCheck") + self.maskedLabel = self.tree.get_widget("maskedLabel") + + # labels + generalVB = self.tree.get_widget("generalVB") + generalVB.modify_bg(gtk.STATE_NORMAL, get_color(self.main.cfg, "packagetable")) + + self.nameLabel = self.tree.get_widget("nameLabel") + self.descLabel = self.tree.get_widget("descLabel") + self.overlayLabel = self.tree.get_widget("overlayLabel") + self.overlayLL = self.tree.get_widget("overlayLabelLabel") + self.licenseLabel = self.tree.get_widget("licenseLabel") + self.linkBox = self.tree.get_widget("linkBox") + self.notInSysLabel = self.tree.get_widget("notInSysLabel") + self.missingLabel = self.tree.get_widget("missingLabel") + self.useFlagsLabel = self.tree.get_widget("useFlagsLabel") + self.useFlagsLL = self.tree.get_widget("useFlagsLabelLabel") + + # buttons + self.emergeBtn = self.tree.get_widget("pkgEmergeBtn") + self.unmergeBtn = self.tree.get_widget("pkgUnmergeBtn") + self.revertBtn = self.tree.get_widget("pkgRevertBtn") + + # useList + self.useList = self.tree.get_widget("useList") + self.build_use_list() + + # depList + self.depList = self.tree.get_widget("dependencyList") + self.build_dep_list() + + # views + self.ebuildView = self.tree.get_widget("ebuildScroll").get_child() + self.changelogView = self.tree.get_widget("changelogScroll").get_child() + self.filesView = self.tree.get_widget("filesScroll").get_child() + + # icons + self.icons = {} + self.icons["use"] = self.window.render_icon(gtk.STOCK_REMOVE, gtk.ICON_SIZE_MENU) + self.icons["installed"] = self.window.render_icon(gtk.STOCK_YES, gtk.ICON_SIZE_MENU) + self.icons["or"] = self.window.render_icon(gtk.STOCK_MEDIA_PAUSE, gtk.ICON_SIZE_MENU) + self.icons["block"] = self.window.render_icon(gtk.STOCK_NO, gtk.ICON_SIZE_MENU) + + def update (self, pkg, queue = None, doEmerge = True, instantChange = False, type = None): + """Updates the table to show the contents for the package. + + @param pkg: the selected package + @type pkg: Package + @param queue: emerge-queue (if None the emerge-buttons are disabled) + @type queue: EmergeQueue + @param doEmerge: if False, the emerge buttons are disabled + @type doEmerge: boolean + @param instantChange: if True the changed keywords are updated instantly + @type instantChange: boolean + @param type: the type of the queue this package is in; if None there is no queue :) + @type type: string""" + + self.pkg = pkg + self.queue = queue + self.doEmerge = doEmerge + self.instantChange = instantChange + self.type = type + + if not self.queue or not self.doEmerge: + self.emergeBtn.set_sensitive(False) + self.unmergeBtn.set_sensitive(False) + + # current status + self._update_table() + self.vb.show_all() + + def hide (self): + self.vb.hide_all() + + def set_labels (self): + pkg = self.pkg + + # name + self.nameLabel.set_markup("<b>%s</b>" % pkg.get_cpv()) + + # description + desc = pkg.get_package_settings("DESCRIPTION") or _("<no description>") + self.descLabel.set_label(desc) + + # overlay + if pkg.is_in_overlay(): + self.overlayLabel.set_label(pkg.get_overlay_path()) + self.overlayLabel.show() + self.overlayLL.show() + else: + self.overlayLabel.hide() + self.overlayLL.hide() + + # license + self.licenseLabel.set_label(pkg.get_package_settings("LICENSE")) + + # link + for c in self.linkBox.get_children(): + self.linkBox.remove(c) + + text = pkg.get_package_settings("HOMEPAGE") + texts = text.split(" ") + ftexts = [] + + for count, t in enumerate(texts): + if not t.startswith(("http", "ftp")): + if count == 0: + error(_("The first homepage part does not start with 'http' or 'ftp'.")) + ftexts.append(t) + continue + else: + info(_("Blank inside homepage.")) + ftexts[-1] += " %s" % t + else: + ftexts.append(t) + + for t in ftexts: + link = gtk.LinkButton(t) + link.set_alignment(0.0, 0.5) + link.set_border_width(0) + self.linkBox.add(link) + + # useflags + flaglist = list(itt.ifilterfalse(pkg.use_expanded, pkg.get_iuse_flags())) + flaglist.sort() + flags = ", ".join(flaglist) + + if flags: + self.useFlagsLL.show() + self.useFlagsLabel.show() + self.useFlagsLabel.set_label(flags) + else: + self.useFlagsLL.hide() + self.useFlagsLabel.hide() + + def fill_dep_list(self): + + store = self.depList.get_model() + + def add (tree, it): + + def get_icon (dep): + if dep.satisfied: + return self.icons["installed"] + elif dep.dep[0] == "!": + return self.icons["block"] + else: + return None + + # useflags + for use, usetree in tree.flags.iteritems(): + if use[0] == "!": + usestring = _("If '%s' is disabled") % use[1:] + else: + usestring = _("If '%s' is enabled") % use + useit = store.append(it, [self.icons["use"], usestring]) + add(usetree, useit) + + # ORs + ordeps = (dep for dep in tree.deps if isinstance(dep, dependency.OrDependency)) + + for ordep in ordeps: + orit = store.append(it, [self.icons["or"], _("One of the following")]) + + for dep in ordep.dep: + if isinstance(dep, dependency.AllOfDependency): # a list inside or + allit = store.append(orit, [None, _("All of the following")]) + for adep in dep.dep: + store.append(allit, [get_icon(adep), adep.dep]) + else: + store.append(orit, [get_icon(dep), dep.dep]) + + # normal + def sort_key (x): + split = system.split_cpv(x.dep) + + if split is None: # split_cpv returns None if this is only a CP; we assume there are only valid deps + return x.dep + else: + return "/".join(split[0:2]) + + ndeps = [dep for dep in tree.deps if not isinstance(dep, dependency.OrDependency)] + ndeps.sort(key = sort_key) + for dep in ndeps: + store.append(it, [get_icon(dep), dep.dep]) + + try: + deptree = self.pkg.get_dependencies() + except AssertionError: + w = _("Can't display dependencies: This package has an unsupported dependency string.") + error(w) + store.append(None, [None, w]) + else: + add(deptree, None) + + def fill_use_list(self): + + pkg = self.pkg + pkg_flags = pkg.get_iuse_flags() + pkg_flags.sort() + + actual_exp = None + actual_exp_it = None + + euse = pkg.get_actual_use_flags() + instuse = pkg.get_installed_use_flags() + + store = self.useList.get_model() + + for use in pkg_flags: + exp = pkg.use_expanded(use, suggest = actual_exp) + if exp is not None: + if exp != actual_exp: + actual_exp_it = store.append(None, [None, None, exp, "<i>%s</i>" % _("This is an expanded use flag and cannot be selected")]) + actual_exp = exp + else: + actual_exp_it = None + actual_exp = None + + enabled = use in euse + installed = use in instuse + store.append(actual_exp_it, [enabled, installed, use, system.get_use_desc(use, self.pkg.get_cp())]) + + def build_dep_list (self): + store = gtk.TreeStore(gtk.gdk.Pixbuf, str) + + self.depList.set_model(store) + + col = gtk.TreeViewColumn() + + cell = gtk.CellRendererPixbuf() + col.pack_start(cell, False) + col.add_attribute(cell, "pixbuf", 0) + + cell = gtk.CellRendererText() + col.pack_start(cell, True) + col.add_attribute(cell, "text", 1) + + self.depList.append_column(col) + + def build_use_list (self): + """Builds the useList.""" + store = gtk.TreeStore(bool, bool, str, str) + self.useList.set_model(store) + + # build view + cell = gtk.CellRendererText() + iCell = gtk.CellRendererToggle() + iCell.set_property("activatable", False) + tCell = gtk.CellRendererToggle() + tCell.set_property("activatable", True) + tCell.connect("toggled", self.cb_use_flag_toggled, store) + self.useList.append_column(gtk.TreeViewColumn(_("Enabled"), tCell, active = 0)) + self.useList.append_column(gtk.TreeViewColumn(_("Installed"), iCell, active = 1)) + self.useList.append_column(gtk.TreeViewColumn(_("Flag"), cell, text = 2)) + self.useList.append_column(gtk.TreeViewColumn(_("Description"), cell, markup = 3)) + + self.useList.set_search_column(2) + self.useList.set_enable_tree_lines(True) + + def _update_keywords (self, emerge, update = False): + if emerge: + type = "install" if not self.type else self.type + try: + try: + self.queue.append(self.pkg.get_cpv(), type = type, update = update) + except PackageNotFoundException, e: + if unmask_dialog(e[0]) == gtk.RESPONSE_YES: + self.queue.append(self.pkg.get_cpv(), type = type, unmask = True, update = update) + except BlockedException, e: + blocked_dialog(e[0], e[1]) + else: + try: + self.queue.append(self.pkg.get_cpv(), type = "uninstall") + except PackageNotFoundException, e: + error(_("Package could not be found: %s"), e[0]) + #masked_dialog(e[0]) + + def _update_table (self, *args): + + pkg = self.pkg + + # set the views + for v in (self.ebuildView, self.changelogView, self.filesView): + v.update(pkg, force = self.notebook.get_nth_page(self.notebook.get_current_page()) == v.get_parent()) + + # set the labels + self.set_labels() + + # set use list + self.useList.get_model().clear() + self.useList.columns_autosize() + self.fill_use_list() + + # set dep list + self.depList.get_model().clear() + self.useList.columns_autosize() + self.fill_dep_list() + + # + # rebuild the buttons and checkboxes in all the different manners which are possible + # + if (not pkg.is_in_system()) or pkg.is_missing_keyword(): + if not pkg.is_in_system(): + self.missingLabel.hide() + self.notInSysLabel.show() + else: # missing keyword + self.missingLabel.show() + self.notInSysLabel.hide() +# + self.installedCheck.hide() + self.maskedCheck.hide() + self.maskedLabel.hide() + self.testingCheck.hide() + self.emergeBtn.set_sensitive(False) + else: # normal package + self.missingLabel.hide() + self.notInSysLabel.hide() + self.installedCheck.show() + self.maskedCheck.show() + self.maskedLabel.show() + self.testingCheck.show() + if self.doEmerge: + self.emergeBtn.set_sensitive(True) + self.installedCheck.set_active(pkg.is_installed()) + + reason = pkg.get_masking_reason() or " " + if pkg.is_masked(use_changed = False) and not pkg.is_masked(use_changed = True): + self.maskedCheck.set_label("<i>(%s)</i>" % _("Masked")) + self.maskedCheck.get_child().set_use_markup(True) + else: + self.maskedCheck.set_label(_("Masked")) + + if pkg.is_locally_masked(): + self.maskedCheck.set_label("<b>%s</b>" % _("Masked")) + self.maskedCheck.get_child().set_use_markup(True) + self.maskedCheck.set_active(True) + reason = _("Masked by user") + else: + self.maskedCheck.set_active(pkg.is_masked(use_changed = False)) + + if reason: + self.maskedLabel.set_label(reason) + + if pkg.is_testing(use_keywords = False) and not pkg.is_testing(use_keywords = True): + self.testingCheck.set_label("<i>(%s)</i>" % _("Testing")) + self.testingCheck.get_child().set_use_markup(True) + else: + self.testingCheck.set_label(_("Testing")) + + self.testingCheck.set_active(pkg.is_testing(use_keywords = False)) + + if self.doEmerge: + # set emerge-button-label + if not pkg.is_installed(): + self.unmergeBtn.set_sensitive(False) + else: + self.unmergeBtn.set_sensitive(True) + + self.vb.show_all() + return True + + def cb_button_pressed (self, b, event): + """Callback for pressed checkboxes. Just quits the event-loop - no redrawing.""" + if not isinstance(b, gtk.CellRendererToggle): + b.emit_stop_by_name("button-press-event") + return True + + def cb_package_revert_clicked (self, button): + """Callback for pressed revert-button.""" + self.pkg.remove_new_use_flags() + self.pkg.remove_new_masked() + self.pkg.remove_new_testing() + self._update_table() + if self.instantChange: + self._update_keywords(True, update = True) + return True + + def cb_package_emerge_clicked (self, button): + """Callback for pressed emerge-button. Adds the package to the EmergeQueue.""" + self._update_keywords(True) + self.main.sysNotebook.set_current_page(self.main.QUEUE_PAGE) + return True + + def cb_package_unmerge_clicked (self, button): + """Callback for pressed unmerge-button clicked. Adds the package to the UnmergeQueue.""" + self._update_keywords(False) + self.main.sysNotebook.set_current_page(self.main.QUEUE_PAGE) + return True + + def cb_testing_toggled (self, button): + """Callback for toggled testing-checkbox.""" + status = button.get_active() + + # end of recursion :) + if self.pkg.is_testing(use_keywords = False) == status: + return False + + # if the package is not testing - don't allow to set it as such + if not self.pkg.is_testing(use_keywords = False): + button.set_active(False) + return True + + # re-set to testing status + if not self.pkg.is_testing(use_keywords = True): + self.pkg.set_testing(False) + button.set_label(_("Testing")) + button.set_active(True) + else: # disable testing + self.pkg.set_testing(True) + button.set_label("<i>(%s)</i>" % _("Testing")) + button.get_child().set_use_markup(True) + button.set_active(True) + + if self.instantChange: + self._update_keywords(True, update = True) + + return True + + def cb_masked_toggled (self, button): + """Callback for toggled masking-checkbox.""" + status = button.get_active() + pkg = self.pkg + + if pkg.is_masked(use_changed = False) == status and not pkg.is_locally_masked(): + return False + + if pkg.is_locally_masked() and status: + return False + + if not pkg.is_masked(use_changed = True): + pkg.set_masked(True) + if pkg.is_locally_masked(): + button.set_label("<b>%s</b>" % _("Masked")) + button.get_child().set_use_markup(True) + self.maskedLabel.set_label(_("Masked by user")) + else: + button.set_label(_("Masked")) + + button.set_active(True) + else: + locally = pkg.is_locally_masked() + pkg.set_masked(False) + if pkg.is_masked(use_changed=False) and not locally: + button.set_label("<i>(%s)</i>" % _("Masked")) + button.get_child().set_use_markup(True) + button.set_active(True) + else: + button.set_label(_("Masked")) + self.maskedLabel.set_label("") + + if self.instantChange: + self._update_keywords(True, update = True) + + return True + + def cb_use_flag_toggled (self, cell, path, store): + """Callback for a toggled use-flag button.""" + flag = store[path][2] + pkg = self.pkg + + if pkg.use_expanded(flag): # ignore expanded flags + return False + + store[path][0] = not store[path][0] + prefix = "" + if not store[path][0]: + prefix = "-" + + pkg.set_use_flag(prefix+flag) + if self.instantChange: + self._update_keywords(True, update = True) + + return True class MainWindow (Window): - """ - Application main window. - """ - - # NOTEBOOK PAGE CONSTANTS - ( - QUEUE_PAGE, - CONSOLE_PAGE, - LOG_PAGE - ) = range(3) - - def __init__ (self, splash = None): - """ - Build up window. - - @param splash: the splash screen =) - @type splash: SplashScreen - """ - - if splash is None: - splash = lambda x: True - - # the title - self.main_title = "Portato (%s)" % VERSION - - # main window stuff - Window.__init__(self) - self.window.set_title(self.main_title) - self.window.set_geometry_hints (self.window, max_height = gtk.gdk.screen_height(), max_width = gtk.gdk.screen_width()) - - # booleans - self.doUpdate = False - self.showAll = True # show only installed or all packages? - self.__searchChanged = False - - # installed pixbuf - self.instPixbuf = self.window.render_icon(gtk.STOCK_YES, gtk.ICON_SIZE_MENU) - - # get the logging window as soon as possible - self.logView = LogView(self.tree.get_widget |