Viewing file: PackageList.py (13.67 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
# Copyright 2005-2006 Red Hat, Inc. # # Jeremy Katz <katzj@redhat.com> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 only # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import os, sys
# # Python gettext: # import gettext
import gtk import gtk.glade import gobject
import yum import yum.Errors from yum.constants import *
from pirut.constants import * import pirut
I18N_DOMAIN = "pirut"
if os.access("data/PackageList.glade", os.R_OK): gladefn = "data/PackageList.glade" else: gladefn = "/usr/share/pirut/ui/PackageList.glade"
PO_COLUMN = 0 PO_SELECTED_COLUMN = 1 PO_PIX_COLUMN = 2 PO_DISPLAYSTR_COLUMN = 3 PO_PKGTYPE_COLUMN = 4
if os.access("data/remove.png", os.R_OK): removepb = gtk.gdk.pixbuf_new_from_file("data/remove.png") else: removepb = gtk.gdk.pixbuf_new_from_file(PIRUTPIX + "remove.png")
if os.access("data/install.png", os.R_OK): installpb = gtk.gdk.pixbuf_new_from_file("data/install.png") else: installpb = gtk.gdk.pixbuf_new_from_file(PIRUTPIX + "install.png")
if os.access("data/installed.png", os.R_OK): installedpb = gtk.gdk.pixbuf_new_from_file("data/installed.png") else: installedpb = gtk.gdk.pixbuf_new_from_file(PIRUTPIX + "installed.png") installedpix = (installedpb, installpb) removepix = (removepb,)
# given a package object, spit out a string reasonable for the list widgets def listEntryString(po): desc = po.returnSimple('summary') or '' desc = "<b>%s</b> - %s" %(po, pirut.sanitizeString(desc)) return desc
class PirutPackageList(gtk.VBox): __gsignals__ = { 'changed': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)), 'toggled': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()) } __gproperties__ = { 'multiselect': (bool, 'multiselect', 'Allow multiple selection', True, gobject.PARAM_READWRITE), } def __init__(self, yumobj): gtk.VBox.__init__(self) self._multiselect = True self.ayum = yumobj self.xml = gtk.glade.XML(gladefn, domain=I18N_DOMAIN, root = "packageListBox") w = self.xml.get_widget("packageListBox") self.add(w) self._showPackageType = SHOW_ALL
self._createPackageStore(self.xml.get_widget("packageListTree"))
sigs = {"on_allRadioButton_toggled": self._showAllPackages, "on_installedRadioButton_toggled": self._showInstalledPackages, "on_availableRadioButton_toggled": self._showAvailablePackages, "on_packageList_button_press": self._plistButtonPress, "on_packageList_popup_menu": self._plistPopup, "on_selectMenu_select": lambda x: self._multiPackageSelect(True, x), "on_selectMenu_unselect": lambda x: self._multiPackageSelect(False, x)} self.xml.signal_autoconnect(sigs)
# reset the radio button to what it was last if self._showPackageType == SHOW_ALL: self.xml.get_widget("allRadioButton").set_active(True) elif self._showPackageType == SHOW_INSTALLED: self.xml.get_widget("installedRadioButton").set_active(True) elif self._showPackageType == SHOW_AVAIL: self.xml.get_widget("availableRadioButton").set_active(True)
x = gtk.glade.XML(gladefn, domain=I18N_DOMAIN, root="selectMenu") self._menu = x.get_widget("selectMenu") x.signal_autoconnect(sigs)
self.pkgFilter = None self.sortedStore = None self.show()
def do_set_property(self, pspec, value): if pspec.name == 'multiselect': self._set_multiselect(value) else: raise AttributeError, 'unknown property %s' % pspec.name
def do_get_property(self, pspec): if pspec.name == 'multiselect': return self._multiselect else: raise AttributeError, 'unknown property %s' % pspec.name def addPackage(self, po, type = SHOW_AVAIL): if apply(self.ayum.tsInfo.matchNaevr, po.pkgtup): if type == SHOW_INSTALLED: pix = removepb else: pix = installpb elif type == SHOW_INSTALLED: pix = installedpb else: pix = None
self.pkgStore.append([po, pix in installedpix, pix, listEntryString(po), type])
def doneAdding(self, sort = True, filter = True): if sort: self.sortedStore = gtk.TreeModelSort(self.pkgStore) def _tree_sort_pos(treemodel, iter1, iter2, user_data=None): d1 = treemodel.get(iter1, PO_COLUMN)[0] d2 = treemodel.get(iter2, PO_COLUMN)[0] ret = cmp(d1, d2) if ret > 0: return 1 if ret < 0: return -1 return 0 self.sortedStore.set_sort_func(PO_DISPLAYSTR_COLUMN, _tree_sort_pos) self.sortedStore.set_sort_column_id(PO_DISPLAYSTR_COLUMN, gtk.SORT_ASCENDING) store = self.sortedStore else: store = self.pkgStore
if filter: self.pkgFilter = store.filter_new() self.pkgFilter.set_visible_func(self.__filter_package_list) store = self.pkgFilter else: store = store
tree = self.xml.get_widget("packageListTree") tree.set_model(store)
def clear(self): self.pkgStore.clear()
def grab_focus(self): t = self.xml.get_widget("packageListTree") if t is not None: t.grab_focus()
def __search_pkgs(self, model, col, key, i): val = model.get_value(i, PO_COLUMN).returnSimple('name') if val.lower().startswith(key.lower()): return False return True
def __filter_package_list(self, model, i): if self._showPackageType == SHOW_ALL: return True elif self._showPackageType != model.get_value(i, PO_PKGTYPE_COLUMN): return False return True
def _createPackageStore(self, tree): self.pkgStore = gtk.ListStore(gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN, gobject.TYPE_OBJECT, gobject.TYPE_STRING, gobject.TYPE_INT)
column = gtk.TreeViewColumn(None, None) pixr = gtk.CellRendererPixbuf() column.pack_start(pixr, False) column.add_attribute(pixr, 'pixbuf', PO_PIX_COLUMN) tree.append_column(column)
column = gtk.TreeViewColumn(None, None) cbr = gtk.CellRendererToggle() column.pack_start(cbr, False) column.add_attribute(cbr, 'active', PO_SELECTED_COLUMN) cbr.connect("toggled", self._packageToggled) tree.append_column(column)
column = gtk.TreeViewColumn(None, None) txtr = gtk.CellRendererText() column.pack_start(txtr, False) column.add_attribute(txtr, 'markup', 3) tree.append_column(column)
tree.set_search_equal_func(self.__search_pkgs) tree.connect("row-activated", self._rowToggled)
tree = self.xml.get_widget("packageListTree") selection = tree.get_selection() selection.connect('changed', self._packageSelected) self._set_multiselect(self.get_property("multiselect"))
def _set_multiselect(self, value): self._multiselect = value tree = self.xml.get_widget("packageListTree") selection = tree.get_selection() if self.get_property("multiselect"): selection.set_mode(gtk.SELECTION_MULTIPLE)
def _packageSelected(self, selection): if selection.count_selected_rows() != 1: self.emit('changed', None) return (model, paths) = selection.get_selected_rows() po = None for p in paths: po = model.get_value(model.get_iter(p), PO_COLUMN) self.emit('changed', po)
def _convert_path_to_real_iter(self, path): if self.pkgFilter is not None: path = self.pkgFilter.convert_path_to_child_path(path) if self.sortedStore is not None: path = self.sortedStore.convert_path_to_child_path(path) i = self.pkgStore.get_iter(path) return i
def _rowToggled(self, tree, path, col): self._packageToggled(None, path) def _packageToggled(self, widget, path, selected = None): i = self._convert_path_to_real_iter(path) po = self.pkgStore.get_value(i, PO_COLUMN) cb = self.pkgStore.get_value(i, PO_SELECTED_COLUMN)
if selected not in (True, False): set = not cb else: set = selected if not set and po.repoid == "installed": self.ayum.remove(po) self.pkgStore.set_value(i, PO_PIX_COLUMN, removepb) elif not set: self.ayum.tsInfo.remove(po.pkgtup) self.pkgStore.set_value(i, PO_PIX_COLUMN, None) elif po.repoid == "installed": self.ayum.tsInfo.remove(po.pkgtup) self.pkgStore.set_value(i, PO_PIX_COLUMN, installedpb) else: self.ayum.install(po) self.pkgStore.set_value(i, PO_PIX_COLUMN, installpb) self.pkgStore.set_value(i, PO_SELECTED_COLUMN, set)
self.emit('toggled')
def _multiPackageSelect(self, val, *args): # val is True or False for select vs unselect t = self.xml.get_widget("packageListTree") sel = t.get_selection() if sel.count_selected_rows() < 1: return (model, paths) = sel.get_selected_rows() for p in paths: self._packageToggled(t, p, val)
def __doPlistPopup(self, button, time): menu = self._menu menu.popup(None, None, None, button, time) menu.show_all()
def _plistButtonPress(self, widget, event): if event.button == 3: x = int(event.x) y = int(event.y) pthinfo = widget.get_path_at_pos(x, y) if pthinfo is not None: sel = widget.get_selection() if sel.count_selected_rows() == 1: path, col, cellx, celly = pthinfo widget.grab_focus() widget.set_cursor(path, col, 0) self.__doPlistPopup(event.button, event.time) return 1
def _plistPopup(self, widget): sel = widget.get_selection() if sel.count_selected_rows() > 0: self.__doPlistPopup(0, 0)
def _showAllPackages(self, w): if not w.get_active(): return self._showPackageType = SHOW_ALL if self.pkgFilter: gobject.idle_add(self.pkgFilter.refilter)
def _showInstalledPackages(self, w): if not w.get_active(): return self._showPackageType = SHOW_INSTALLED if self.pkgFilter: gobject.idle_add(self.pkgFilter.refilter)
def _showAvailablePackages(self, w): if not w.get_active(): return self._showPackageType = SHOW_AVAIL if self.pkgFilter: gobject.idle_add(self.pkgFilter.refilter)
gobject.type_register(PirutPackageList)
class PackageListTester(yum.YumBase): def __init__(self): yum.YumBase.__init__(self) self.doConfigSetup() self.closeRpmDB() self.doTsSetup() self.doRpmDBSetup() self.doRepoSetup() self.doSackSetup()
self.window = gtk.Window() self.window.connect("destroy", self._quit)
self.plist = PirutPackageList(self) self.window.add(self.plist)
def simpleDBInstalled(self, name): # FIXME: doing this directly instead of using self.rpmdb.installed() # speeds things up by 400% mi = self.ts.ts.dbMatch('name', name) if mi.count() > 0: return True return False
def isPackageInstalled(self, pkgname): # FIXME: this sucks. we should probably suck it into yum proper # but it'll need a bit of cleanup first. installed = False if self.rpmdb.installed(name = pkgname): installed = True lst = self.tsInfo.matchNaevr(name = pkgname) for txmbr in lst: if txmbr.po.state in TS_INSTALL_STATES: return True if installed and len(lst) > 0: # if we get here, then it was installed, but it's in the tsInfo # for an erase or obsoleted --> not going to be installed at end return False return installed
def _quit(self, *args): sys.exit(0)
def run(self): pos = self.pkgSack.returnNewestByNameArch() for po in pos: if self.simpleDBInstalled(po.returnSimple('name')): continue self.plist.addPackage(po, SHOW_AVAIL) for po in self.rpmdb.returnPackages(): self.plist.addPackage(po, SHOW_INSTALLED) self.plist.doneAdding()
self.window.show() gtk.main()
if __name__ == "__main__": w = PackageListTester() w.run()
|