Beispiel #1
0
    def __init__(self, parent=None):
        qt.QDialog.__init__(self, parent)

        self.setIcon(getPixmap("smart"))
        self.setCaption(_("Change Summary"))
        self.setModal(True)
        self.setMinimumSize(600, 400)
        centerWindow(self)

        self._vbox = qt.QVBoxLayout(self)
        self._vbox.setMargin(10)
        self._vbox.setSpacing(10)

        self._label = qt.QLabel(self)
        self._vbox.addWidget(self._label)

        self._pv = QtPackageView(self)
        self._pv.getTreeView().header().hide()
        self._pv.setExpandPackage(True)
        self._pv.show()
        self._vbox.addWidget(self._pv)

        self._sizelabel = qt.QLabel("", self)
        self._vbox.addWidget(self._sizelabel)

        self._confirmbbox = qt.QHBox(self)
        self._confirmbbox.setSpacing(10)
        self._confirmbbox.layout().addStretch(1)
        self._vbox.addWidget(self._confirmbbox)

        self._cancelbutton = qt.QPushButton(_("Cancel"), self._confirmbbox)
        qt.QObject.connect(self._cancelbutton, qt.SIGNAL("clicked()"), self,
                           qt.SLOT("reject()"))
        self._okbutton = qt.QPushButton(_("OK"), self._confirmbbox)
        qt.QObject.connect(self._okbutton, qt.SIGNAL("clicked()"), self,
                           qt.SLOT("accept()"))

        self._closebbox = qt.QHBox(self)
        self._closebbox.setSpacing(10)
        self._closebbox.layout().addStretch(1)
        self._vbox.addWidget(self._closebbox)

        self._closebutton = qt.QPushButton(_("Close"), self._closebbox)
        qt.QObject.connect(self._closebutton, qt.SIGNAL("clicked()"), self,
                           qt.SLOT("close()"))
    def __init__(self, parent=None):
        qt.QDialog.__init__(self, parent)

        self.setIcon(getPixmap("smart"))
        self.setCaption(_("Change Summary"))
        self.setModal(True)
        self.setMinimumSize(600, 400)
        centerWindow(self)
        
        self._vbox = qt.QVBoxLayout(self)
        self._vbox.setMargin(10)
        self._vbox.setSpacing(10)

        self._label = qt.QLabel(self)
        self._vbox.addWidget(self._label)

        self._pv = QtPackageView(self)
        self._pv.getTreeView().header().hide()
        self._pv.setExpandPackage(True)
        self._pv.show()
        self._vbox.addWidget(self._pv)

        self._sizelabel = qt.QLabel("", self)
        self._vbox.addWidget(self._sizelabel)

        self._confirmbbox = qt.QHBox(self)
        self._confirmbbox.setSpacing(10)
        self._confirmbbox.layout().addStretch(1)
        self._vbox.addWidget(self._confirmbbox)

        self._cancelbutton = qt.QPushButton(_("Cancel"), self._confirmbbox)
        qt.QObject.connect( self._cancelbutton, qt.SIGNAL("clicked()"), self, qt.SLOT("reject()"))
        self._okbutton = qt.QPushButton(_("OK"), self._confirmbbox)
        qt.QObject.connect( self._okbutton, qt.SIGNAL("clicked()"), self, qt.SLOT("accept()"))

        self._closebbox = qt.QHBox(self)
        self._closebbox.setSpacing(10)
        self._closebbox.layout().addStretch(1)
        self._vbox.addWidget(self._closebbox)

        self._closebutton = qt.QPushButton(_("Close"), self._closebbox)
        qt.QObject.connect( self._closebutton, qt.SIGNAL("clicked()"), self, qt.SLOT("close()"))
class QtChanges(qt.QDialog):

    def __init__(self, parent=None):
        qt.QDialog.__init__(self, parent)

        self.setIcon(getPixmap("smart"))
        self.setCaption(_("Change Summary"))
        self.setModal(True)
        self.setMinimumSize(600, 400)
        centerWindow(self)
        
        self._vbox = qt.QVBoxLayout(self)
        self._vbox.setMargin(10)
        self._vbox.setSpacing(10)

        self._label = qt.QLabel(self)
        self._vbox.addWidget(self._label)

        self._pv = QtPackageView(self)
        self._pv.getTreeView().header().hide()
        self._pv.setExpandPackage(True)
        self._pv.show()
        self._vbox.addWidget(self._pv)

        self._sizelabel = qt.QLabel("", self)
        self._vbox.addWidget(self._sizelabel)

        self._confirmbbox = qt.QHBox(self)
        self._confirmbbox.setSpacing(10)
        self._confirmbbox.layout().addStretch(1)
        self._vbox.addWidget(self._confirmbbox)

        self._cancelbutton = qt.QPushButton(_("Cancel"), self._confirmbbox)
        qt.QObject.connect( self._cancelbutton, qt.SIGNAL("clicked()"), self, qt.SLOT("reject()"))
        self._okbutton = qt.QPushButton(_("OK"), self._confirmbbox)
        qt.QObject.connect( self._okbutton, qt.SIGNAL("clicked()"), self, qt.SLOT("accept()"))

        self._closebbox = qt.QHBox(self)
        self._closebbox.setSpacing(10)
        self._closebbox.layout().addStretch(1)
        self._vbox.addWidget(self._closebbox)

        self._closebutton = qt.QPushButton(_("Close"), self._closebbox)
        qt.QObject.connect( self._closebutton, qt.SIGNAL("clicked()"), self, qt.SLOT("close()"))
        
    def showChangeSet(self, changeset, keep=None, confirm=False, label=None):

        report = Report(changeset)
        report.compute()
        
        class Sorter(unicode):
            ORDER = [_("Remove"), _("Downgrade"), _("Reinstall"),
                     _("Install"), _("Upgrade")]
            def _index(self, s):
                i = 0
                for os in self.ORDER:
                    if os.startswith(s):
                        return i
                    i += 1
                return i
            def __cmp__(self, other):
                return cmp(self._index(unicode(self)), self._index(unicode(other)))
            def __lt__(self, other):
                return cmp(self, other) < 0

        packages = {}

        if report.install:
            install = {}
            reinstall = {}
            upgrade = {}
            downgrade = {}
            lst = report.install.keys()
            lst.sort()
            for pkg in lst:
                package = {}
                done = {}
                if pkg in report.upgrading:
                    for upgpkg in report.upgrading[pkg]:
                        package.setdefault(_("Upgrades"), []).append(upgpkg)
                        done[upgpkg] = True
                if pkg in report.downgrading:
                    for dwnpkg in report.downgrading[pkg]:
                        package.setdefault(_("Downgrades"), []).append(dwnpkg)
                        done[dwnpkg] = True
                if pkg in report.requires:
                    for reqpkg in report.requires[pkg]:
                        package.setdefault(_("Requires"), []).append(reqpkg)
                if pkg in report.requiredby:
                    for reqpkg in report.requiredby[pkg]:
                        package.setdefault(_("Required By"), []).append(reqpkg)
                if pkg in report.conflicts:
                    for cnfpkg in report.conflicts[pkg]:
                        if cnfpkg in done:
                            continue
                        package.setdefault(_("Conflicts"), []).append(cnfpkg)
                if pkg.installed:
                    reinstall[pkg] = package
                elif pkg in report.upgrading:
                    upgrade[pkg] = package
                elif pkg in report.downgrading:
                    downgrade[pkg] = package
                else:
                    install[pkg] = package
            if reinstall:
                packages[Sorter(_("Reinstall (%d)") % len(reinstall))] = \
                                                                    reinstall
            if install:
                packages[Sorter(_("Install (%d)") % len(install))] = install
            if upgrade:
                packages[Sorter(_("Upgrade (%d)") % len(upgrade))] = upgrade
            if downgrade:
                packages[Sorter(_("Downgrade (%d)") % len(downgrade))] = \
                                                                    downgrade

        if report.removed:
            remove = {}
            lst = report.removed.keys()
            lst.sort()
            for pkg in lst:
                package = {}
                done = {}
                if pkg in report.requires:
                    for reqpkg in report.requires[pkg]:
                        package.setdefault(_("Requires"), []).append(reqpkg)
                if pkg in report.requiredby:
                    for reqpkg in report.requiredby[pkg]:
                        package.setdefault(_("Required By"), []).append(reqpkg)
                if pkg in report.conflicts:
                    for cnfpkg in report.conflicts[pkg]:
                        if cnfpkg in done:
                            continue
                        package.setdefault(_("Conflicts"), []).append(cnfpkg)
                remove[pkg] = package
            if remove:
                packages[Sorter(_("Remove (%d)") % len(report.removed))] = \
                                                                        remove

        if keep:
            packages[Sorter(_("Keep (%d)") % len(keep))] = keep

        dsize = report.getDownloadSize()
        size = report.getInstallSize() - report.getRemoveSize()
        sizestr = ""
        if dsize:
            sizestr += _("%s of package files are needed. ") % sizeToStr(dsize)
        if size > 0:
            sizestr += _("%s will be used.") % sizeToStr(size)
        elif size < 0:
            size *= -1
            sizestr += _("%s will be freed.") % sizeToStr(size)
        if dsize or size:
            self._sizelabel.setText(sizestr)
            self._sizelabel.show()
        else:
            self._sizelabel.hide()

        if confirm:
            self._confirmbbox.show()
            self._closebbox.hide()
            self._okbutton.setDefault(True)
        else:
            self._closebbox.show()
            self._confirmbbox.hide()
            self._closebutton.setDefault(True)

        if label:
            self._label.set_text(label)
            self._label.show()
        else:
            self._label.hide()

        self._pv.setPackages(packages, changeset)

        # Expand first level
        self._pv.setExpanded([(x,) for x in packages])

        self._result = False
        self.show()
        dialogResult = self.exec_loop()
        self._result = (dialogResult == qt.QDialog.Accepted)

        return self._result
Beispiel #4
0
    def __init__(self, ctrl, argv=None):
        QtInterface.__init__(self, ctrl, argv)

        self._changeset = None

        self._window = qt.QMainWindow()
        self._window.setCaption("Smart Package Manager %s" % VERSION)
        centerWindow(self._window)
        self._window.setMinimumSize(640, 480)
        app.connect(app, qt.SIGNAL('lastWindowClosed()'), app, qt.SLOT('quit()'))

        self._undo = []
        self._redo = []

        globals = {"self": self, "qt": qt}
        group = qt.QActionGroup(self._window, "Actions")
        self._actions = compileActions(group, ACTIONS, globals)

        class ToggleAction(qt.QAction):
        
            def __init__(self, group, name, label):
                qt.QAction.__init__(self, group, name)
                self.setToggleAction(True)
                self.setMenuText(label.replace("&","&&"))
                self._name = name
            
            def connect(self, signal, callback, userdata):
                self._callback = callback
                self._userdata = userdata
                qt.QObject.connect(self, qt.SIGNAL(signal), self.slot)
            
            def slot(self):
                self._callback(self._userdata)
         
        self._filters = {}
        for name, label in [("hide-non-upgrades", _("Hide Non-upgrades")),
                            ("hide-installed", _("Hide Installed")),
                            ("hide-uninstalled", _("Hide Uninstalled")),
                            ("hide-unmarked", _("Hide Unmarked")),
                            ("hide-unlocked", _("Hide Unlocked")),
                            ("hide-requested", _("Hide Requested")),
                            ("hide-old", _("Hide Old"))]:
            act = ToggleAction(None, name, label)
            act.connect("activated()", self.toggleFilter, name)
            self._actions[name] = act

        treestyle = sysconf.get("package-tree")
        for name, label in [("groups", _("Groups")),
                            ("channels", _("Channels")),
                            ("channels-groups", _("Channels & Groups")),
                            ("none", _("None"))]:
            act = ToggleAction(group, "tree-style-"+name, label)
            if name == treestyle:
                act.setOn(True)
            act.connect("activated()", self.setTreeStyle, name)
            self._actions["tree-style-"+name] = act

        self._menubar = self._window.menuBar()
        for MENU in MENUBAR:
             def insertmenu(menubar, menu):
                item = menu[0]
                action = self._actions[item]
                m = qt.QPopupMenu(menubar)
                text = action.menuText()
                menubar.insertItem(text, m)
                for item in menu[1]:
                    if isinstance(item, tuple):
                        insertmenu(m, item)
                    elif item:
                        action = self._actions[item]
                        #i = qt.QPopupMenu(m)
                        #text = action.menuText()
                        #m.insertItem(text, i)
                        action.addTo(m)
                    else:
                        m.insertSeparator()
             insertmenu(self._menubar, MENU)

        self._toolbar = qt.QToolBar(self._window)
        for TOOL in TOOLBAR:
            def inserttool(toolbar, tool):
                if tool:
                    action = self._actions[tool]
                    #b = qt.QToolButton(toolbar, TOOL)
                    #b.setTextLabel(action.toolTip())
                    pixmap = getPixmap(TOOLBARICONS[tool])
                    #b.setIconSet(qt.QIconSet(pixmap))
                    action.setIconSet(qt.QIconSet(pixmap))
                    action.addTo(toolbar)
                else:
                    toolbar.addSeparator()
            inserttool(self._toolbar, TOOL)

        #self._window.add_accel_group(self._ui.get_accel_group())

        self._actions["exec-changes"].setAccel(qt.QKeySequence("Ctrl+C"))
        self._actions["find"].setAccel(qt.QKeySequence("Ctrl+F"))
        self._actions["expand-all"].setAccel(qt.QKeySequence("Ctrl+O"))
        self._actions["collapse-all"].setAccel(qt.QKeySequence("Ctrl+W"))
        self._actions["summary-window"].setAccel(qt.QKeySequence("Ctrl+S"))

        self._actions["exec-changes"].setEnabled(False)
        self._actions["clear-changes"].setEnabled(False)
        self._actions["undo"].setEnabled(False)
        self._actions["redo"].setEnabled(False)

        # Search bar

        self._searchbar = qt.QToolBar(self._window)
        self._searchbar.hide()
       
        label = qt.QLabel(_("Search:"), self._searchbar)
        label.show()

        self._searchentry = qt.QLineEdit(self._searchbar)
        qt.QObject.connect(self._searchentry, qt.SIGNAL("returnPressed()"), self.refreshPackages)
        self._searchentry.show()

        button = qt.QPushButton(self._searchbar)
        qt.QObject.connect(button, qt.SIGNAL("clicked()"), self.refreshPackages)
        pixmap = getPixmap("crystal-search")
        button.setIconSet(qt.QIconSet(pixmap))
        button.show()

        buttongroup = qt.QButtonGroup(self._searchbar)
        buttongroup.hide()
        
        self._searchname = qt.QRadioButton(_("Automatic"), self._searchbar)
        self._searchname.setChecked(True)
        qt.QObject.connect(self._searchname, qt.SIGNAL("clicked()"), self.refreshPackages)
        buttongroup.insert(self._searchname)
        self._searchname.show()
        self._searchdesc = qt.QRadioButton(_("Description"), self._searchbar)
        self._searchdesc.setChecked(False)
        qt.QObject.connect(self._searchdesc, qt.SIGNAL("clicked()"), self.refreshPackages)
        self._searchdesc.show()
        buttongroup.insert(self._searchdesc)

        # Packages and information

        self._splitter = qt.QSplitter(qt.Qt.Vertical, self._window)
        self._window.setCentralWidget(self._splitter)
        
        self._pv = QtPackageView(self._splitter)
        self._pv.show()

        self._pi = QtPackageInfo(self._splitter)
        self._pi.show()
        qt.QObject.connect(self._pv, qt.PYSIGNAL("packageSelected"), self._pi.setPackage)
        qt.QObject.connect(self._pv, qt.PYSIGNAL("packageActivated"), self.actOnPackages)
        qt.QObject.connect(self._pv, qt.PYSIGNAL("packagePopup"), self.packagePopup)

        self._status = self._window.statusBar()
        self._status.show()
        
        self._legend = QtLegend(self._window)
Beispiel #5
0
class QtInteractiveInterface(QtInterface):

    def __init__(self, ctrl, argv=None):
        QtInterface.__init__(self, ctrl, argv)

        self._changeset = None

        self._window = qt.QMainWindow()
        self._window.setCaption("Smart Package Manager %s" % VERSION)
        centerWindow(self._window)
        self._window.setMinimumSize(640, 480)
        app.connect(app, qt.SIGNAL('lastWindowClosed()'), app, qt.SLOT('quit()'))

        self._undo = []
        self._redo = []

        globals = {"self": self, "qt": qt}
        group = qt.QActionGroup(self._window, "Actions")
        self._actions = compileActions(group, ACTIONS, globals)

        class ToggleAction(qt.QAction):
        
            def __init__(self, group, name, label):
                qt.QAction.__init__(self, group, name)
                self.setToggleAction(True)
                self.setMenuText(label.replace("&","&&"))
                self._name = name
            
            def connect(self, signal, callback, userdata):
                self._callback = callback
                self._userdata = userdata
                qt.QObject.connect(self, qt.SIGNAL(signal), self.slot)
            
            def slot(self):
                self._callback(self._userdata)
         
        self._filters = {}
        for name, label in [("hide-non-upgrades", _("Hide Non-upgrades")),
                            ("hide-installed", _("Hide Installed")),
                            ("hide-uninstalled", _("Hide Uninstalled")),
                            ("hide-unmarked", _("Hide Unmarked")),
                            ("hide-unlocked", _("Hide Unlocked")),
                            ("hide-requested", _("Hide Requested")),
                            ("hide-old", _("Hide Old"))]:
            act = ToggleAction(None, name, label)
            act.connect("activated()", self.toggleFilter, name)
            self._actions[name] = act

        treestyle = sysconf.get("package-tree")
        for name, label in [("groups", _("Groups")),
                            ("channels", _("Channels")),
                            ("channels-groups", _("Channels & Groups")),
                            ("none", _("None"))]:
            act = ToggleAction(group, "tree-style-"+name, label)
            if name == treestyle:
                act.setOn(True)
            act.connect("activated()", self.setTreeStyle, name)
            self._actions["tree-style-"+name] = act

        self._menubar = self._window.menuBar()
        for MENU in MENUBAR:
             def insertmenu(menubar, menu):
                item = menu[0]
                action = self._actions[item]
                m = qt.QPopupMenu(menubar)
                text = action.menuText()
                menubar.insertItem(text, m)
                for item in menu[1]:
                    if isinstance(item, tuple):
                        insertmenu(m, item)
                    elif item:
                        action = self._actions[item]
                        #i = qt.QPopupMenu(m)
                        #text = action.menuText()
                        #m.insertItem(text, i)
                        action.addTo(m)
                    else:
                        m.insertSeparator()
             insertmenu(self._menubar, MENU)

        self._toolbar = qt.QToolBar(self._window)
        for TOOL in TOOLBAR:
            def inserttool(toolbar, tool):
                if tool:
                    action = self._actions[tool]
                    #b = qt.QToolButton(toolbar, TOOL)
                    #b.setTextLabel(action.toolTip())
                    pixmap = getPixmap(TOOLBARICONS[tool])
                    #b.setIconSet(qt.QIconSet(pixmap))
                    action.setIconSet(qt.QIconSet(pixmap))
                    action.addTo(toolbar)
                else:
                    toolbar.addSeparator()
            inserttool(self._toolbar, TOOL)

        #self._window.add_accel_group(self._ui.get_accel_group())

        self._actions["exec-changes"].setAccel(qt.QKeySequence("Ctrl+C"))
        self._actions["find"].setAccel(qt.QKeySequence("Ctrl+F"))
        self._actions["expand-all"].setAccel(qt.QKeySequence("Ctrl+O"))
        self._actions["collapse-all"].setAccel(qt.QKeySequence("Ctrl+W"))
        self._actions["summary-window"].setAccel(qt.QKeySequence("Ctrl+S"))

        self._actions["exec-changes"].setEnabled(False)
        self._actions["clear-changes"].setEnabled(False)
        self._actions["undo"].setEnabled(False)
        self._actions["redo"].setEnabled(False)

        # Search bar

        self._searchbar = qt.QToolBar(self._window)
        self._searchbar.hide()
       
        label = qt.QLabel(_("Search:"), self._searchbar)
        label.show()

        self._searchentry = qt.QLineEdit(self._searchbar)
        qt.QObject.connect(self._searchentry, qt.SIGNAL("returnPressed()"), self.refreshPackages)
        self._searchentry.show()

        button = qt.QPushButton(self._searchbar)
        qt.QObject.connect(button, qt.SIGNAL("clicked()"), self.refreshPackages)
        pixmap = getPixmap("crystal-search")
        button.setIconSet(qt.QIconSet(pixmap))
        button.show()

        buttongroup = qt.QButtonGroup(self._searchbar)
        buttongroup.hide()
        
        self._searchname = qt.QRadioButton(_("Automatic"), self._searchbar)
        self._searchname.setChecked(True)
        qt.QObject.connect(self._searchname, qt.SIGNAL("clicked()"), self.refreshPackages)
        buttongroup.insert(self._searchname)
        self._searchname.show()
        self._searchdesc = qt.QRadioButton(_("Description"), self._searchbar)
        self._searchdesc.setChecked(False)
        qt.QObject.connect(self._searchdesc, qt.SIGNAL("clicked()"), self.refreshPackages)
        self._searchdesc.show()
        buttongroup.insert(self._searchdesc)

        # Packages and information

        self._splitter = qt.QSplitter(qt.Qt.Vertical, self._window)
        self._window.setCentralWidget(self._splitter)
        
        self._pv = QtPackageView(self._splitter)
        self._pv.show()

        self._pi = QtPackageInfo(self._splitter)
        self._pi.show()
        qt.QObject.connect(self._pv, qt.PYSIGNAL("packageSelected"), self._pi.setPackage)
        qt.QObject.connect(self._pv, qt.PYSIGNAL("packageActivated"), self.actOnPackages)
        qt.QObject.connect(self._pv, qt.PYSIGNAL("packagePopup"), self.packagePopup)

        self._status = self._window.statusBar()
        self._status.show()
        
        self._legend = QtLegend(self._window)

    def showStatus(self, msg):
        self._status.message(msg)

    def hideStatus(self):
        self._status.clear()

    def run(self, command=None, argv=None):
        self.setCatchExceptions(True)
        self.loadState()
        self._window.setIcon(getPixmap("smart"))
        self._window.show()
        self._ctrl.reloadChannels()
        self._changeset = ChangeSet(self._ctrl.getCache())
        self._pi.setChangeSet(self._changeset)
        self._progress.hide()
        self.refreshPackages()
        app.exec_loop()
        self.saveState()
        self.setCatchExceptions(False)

    # Non-standard interface methods:

    def saveState(self):
        # Note: qt.QSize and qt.QPoint are not pickleable, unfortunately
        sysconf.set("qt-size", (self._window.width(),self._window.height()))
        sysconf.set("qt-position", (self._window.x(),self._window.y()))
        sysconf.set("qt-splitter-sizes", self._splitter.sizes())

    def loadState(self):
        var = sysconf.get("qt-size")
        if var is not None:
            self._window.resize(*var)
        var = sysconf.get("qt-position")
        if var is not None:
            self._window.move(*var)
        var = sysconf.get("qt-splitter-sizes")
        if var is not None:
            self._splitter.setSizes(var)

    def getChangeSet(self):
        return self._changeset

    def updateSelected(self):
        self.updateChannels(selected=True)

    def updateChannels(self, selected=False, channels=None):
        if selected:
            aliases = QtChannelSelector().show()
            channels = [channel for channel in self._ctrl.getChannels()
                        if channel.getAlias() in aliases]
            if not channels:
                return
        state = self._changeset.getPersistentState()
        self._ctrl.reloadChannels(channels, caching=NEVER)
        self._changeset.setPersistentState(state)
        self.refreshPackages()

    def rebuildCache(self):
        state = self._changeset.getPersistentState()
        self._ctrl.reloadChannels()
        self._changeset.setPersistentState(state)
        self.refreshPackages()

    def applyChanges(self, confirm=True):
        transaction = Transaction(self._ctrl.getCache(),
                                  changeset=self._changeset)
        if self._ctrl.commitTransaction(transaction, confirm=confirm):
            del self._undo[:]
            del self._redo[:]
            self._actions["redo"].setEnabled(False)
            self._actions["undo"].setEnabled(False)
            pkgs = self._changeset.copy()
            self._changeset.clear()
            self._ctrl.reloadChannels()
            self.refreshPackages()
            self.changedMarks(pkgs)
        self._progress.hide()

    def clearChanges(self):
        self.saveUndo()
        pkgs = self._changeset.copy()
        self._changeset.clear()
        self.changedMarks(pkgs)

    def showChanges(self):
        return self._changes.showChangeSet(self._changeset)

    def showLog(self):
        return self._log.show()

    def showLegend(self):
        return self._legend.show()

    def expandPackages(self):
        self._pv.expandAll()

    def collapsePackages(self):
        self._pv.collapseAll()

    def toggleFilter(self, filter):
        if filter in self._filters:
            del self._filters[filter]
        else:
            self._filters[filter] = True
        self.refreshPackages()

    def upgradeAll(self):
        transaction = Transaction(self._ctrl.getCache())
        transaction.setState(self._changeset)
        for pkg in self._ctrl.getCache().getPackages():
            if pkg.installed:
                transaction.enqueue(pkg, UPGRADE)
        transaction.setPolicy(PolicyUpgrade)
        transaction.run()
        changeset = transaction.getChangeSet()
        if changeset != self._changeset:
            if self.confirmChange(self._changeset, changeset):
                self.saveUndo()
                emptychangeset = not self._changeset
                self._changeset.setState(changeset)
                self.changedMarks()
                if self.askYesNo(_("Apply marked changes now?"), True):
                    self.applyChanges(confirm=not emptychangeset)
        else:
            self.showStatus(_("No interesting upgrades available!"))

    def actOnPackages(self, pkgs, op=None):
        cache = self._ctrl.getCache()
        transaction = Transaction(cache, policy=PolicyInstall)
        transaction.setState(self._changeset)
        changeset = transaction.getChangeSet()
        if op is None:
            if not [pkg for pkg in pkgs if pkg not in changeset]:
                op = KEEP
            else:
                for pkg in pkgs:
                    if not pkg.installed:
                        op = INSTALL
                        break
                else:
                    op = REMOVE
        if op is REMOVE:
            transaction.setPolicy(PolicyRemove)
        policy = transaction.getPolicy()
        for pkg in pkgs:
            if op is KEEP:
                transaction.enqueue(pkg, op)
            elif op in (REMOVE, REINSTALL, FIX):
                if pkg.installed:
                    transaction.enqueue(pkg, op)
                    if op is REMOVE:
                        for _pkg in cache.getPackages(pkg.name):
                            if not _pkg.installed:
                                policy.setLocked(_pkg, True)
            elif op is INSTALL:
                if not pkg.installed:
                    transaction.enqueue(pkg, op)
        transaction.run()
        if op is FIX:
            expected = 0
        else:
            expected = 1
        if self.confirmChange(self._changeset, changeset, expected):
            self.saveUndo()
            self._changeset.setState(changeset)
            pkgs.extend(changeset)
            self.changedMarks(pkgs)

    def lockPackages(self, pkgs, lock):
        if not lock:
             for pkg in pkgs:
                  pkgconf.clearFlag("lock", pkg.name, "=", pkg.version)
             self._pv.updatePackages(pkgs)
             self._pv.update()
             self._pi.setPackage(pkgs[0])
        else:
             for pkg in pkgs:
                  pkgconf.setFlag("lock", pkg.name, "=", pkg.version)
             self._pv.updatePackages(pkgs)
             self._pv.update()
             self._pi.setPackage(pkgs[0])

    def lockAllPackages(self, pkgs, lock):
        if not lock:
             for pkg in pkgs:
                  pkgconf.clearFlag("lock", pkg.name)
             self._pv.updatePackages(pkgs)
             self._pv.update()
             self._pi.setPackage(pkgs[0])
        else:
             for pkg in pkgs:
                  pkgconf.setFlag("lock", pkg.name)
             self._pv.updatePackages(pkgs)
             self._pv.update()
             self._pi.setPackage(pkgs[0])

    def priorityPackages(self, pkgs, none):
        QtSinglePriority(self._window).show(pkgs[0])
        self._pi.setPackage(pkgs[0])

    def packagePopup(self, packageview, pkgs, pnt):
        
        menu = qt.QPopupMenu(packageview)
        menu.move(pnt)
        
        hasinstalled = bool([pkg for pkg in pkgs if pkg.installed
                             and self._changeset.get(pkg) is not REMOVE])
        hasnoninstalled = bool([pkg for pkg in pkgs if not pkg.installed
                                and self._changeset.get(pkg) is not INSTALL])

        class PackagesAction(object):
        
            def __init__(self, pkgs):
                self._pkgs = pkgs
                self._callback = {}
                self._userdata = {}
            
            def connect(self, item, callback, userdata=None):
                self._callback[item] = callback
                self._userdata[item] = userdata
            
            def slot(self, index):
                self._callback[index](self._pkgs, self._userdata[index])

        action = PackagesAction(pkgs)

        iconset = qt.QIconSet(getPixmap("package-install"))
        item = menu.insertItem(iconset, _("Install"), action.slot)
        action.connect(item, self.actOnPackages, INSTALL)
        if not hasnoninstalled:
            menu.setItemEnabled(item, False)

        iconset = qt.QIconSet(getPixmap("package-reinstall"))
        item = menu.insertItem(iconset, _("Reinstall"), action.slot)
        action.connect(item, self.actOnPackages, REINSTALL)
        if not hasinstalled:
            menu.setItemEnabled(item, False)

        iconset = qt.QIconSet(getPixmap("package-remove"))
        item = menu.insertItem(iconset, _("Remove"), action.slot)
        action.connect(item, self.actOnPackages, REMOVE)
        if not hasinstalled:
            menu.setItemEnabled(item, False)

        if not hasinstalled:
            iconset = qt.QIconSet(getPixmap("package-available"))
        else:
            iconset = qt.QIconSet(getPixmap("package-installed"))
        item = menu.insertItem(iconset, _("Keep"), action.slot)
        action.connect(item, self.actOnPackages, KEEP)
        if not [pkg for pkg in pkgs if pkg in self._changeset]:
            menu.setItemEnabled(item, False)

        iconset = qt.QIconSet(getPixmap("package-broken"))
        item = menu.insertItem(iconset, _("Fix problems"), action.slot)
        action.connect(item, self.actOnPackages, FIX)
        if not hasinstalled:
            menu.setItemEnabled(item, False)

        inconsistent = False
        thislocked = None
        alllocked = None
        names = pkgconf.getFlagTargets("lock")
        if [pkg for pkg in pkgs if pkg in self._changeset]:
            inconsistent = True
        else:
            for pkg in pkgs:
                if (names and pkg.name in names and 
                    ("=", pkg.version) in names[pkg.name]):
                    newthislocked = True
                    newalllocked = len(names[pkg.name]) > 1
                else:
                    newthislocked = False
                    newalllocked = pkgconf.testFlag("lock", pkg)
                if (thislocked is not None and thislocked != newthislocked or
                    alllocked is not None and alllocked != newalllocked):
                    inconsistent = True
                    break
                thislocked = newthislocked
                alllocked = newalllocked

        lockaction = PackagesAction(pkgs)

        if thislocked:
            if not hasnoninstalled:
                iconset = qt.QIconSet(getPixmap("package-installed"))
            else:
                iconset = qt.QIconSet(getPixmap("package-available"))
            item = menu.insertItem(iconset, _("Unlock this version"), lockaction.slot)
            lockaction.connect(item, self.lockPackages, False)
        else:
            if not hasnoninstalled:
                iconset = qt.QIconSet(getPixmap("package-installed-locked"))
            else:
                iconset = qt.QIconSet(getPixmap("package-available-locked"))
            item = menu.insertItem(iconset, _("Lock this version"), lockaction.slot)
            lockaction.connect(item, self.lockPackages, True)
        if inconsistent:
            menu.setItemEnabled(item, False)

        lockallaction = PackagesAction(pkgs)

        if alllocked:
            if not hasnoninstalled:
                iconset = qt.QIconSet(getPixmap("package-installed"))
            else:
                iconset = qt.QIconSet(getPixmap("package-available"))
            item = menu.insertItem(iconset, _("Unlock all versions"), lockallaction.slot)
            lockallaction.connect(item, self.lockAllPackages, False)
        else:
            if not hasnoninstalled:
                iconset = qt.QIconSet(getPixmap("package-installed-locked"))
            else:
                iconset = qt.QIconSet(getPixmap("package-available-locked"))
            item = menu.insertItem(iconset, _("Lock all versions"), lockallaction.slot)
            lockallaction.connect(item, self.lockAllPackages, True)
        if inconsistent:
            menu.setItemEnabled(item, False)

        priorityaction = PackagesAction(pkgs)
        
        item = menu.insertItem(_("Priority"), priorityaction.slot)
        priorityaction.connect(item, self.priorityPackages)
        if len(pkgs) != 1:
            menu.setItemEnabled(item, False)

        menu.show()
        menu.exec_loop(packageview.mapToGlobal(pnt))

    def checkInstalledPackages(self):
        self.checkPackages()

    def checkUninstalledPackages(self):
        self.checkPackages(uninstalled=True)

    def checkAllPackages(self):
        self.checkPackages(all=True)

    def checkPackages(self, all=False, uninstalled=False):
        installed = not uninstalled
        available = all or uninstalled
        self.info(_("Checking relations..."))
        if checkPackagesSimple(self._ctrl.getCache(), report=True,
                               installed=installed, available=available):
            self.info(_("All checked packages have correct relations."))

    def fixAllProblems(self):
        self.actOnPackages([pkg for pkg in self._ctrl.getCache().getPackages()
                            if pkg.installed], FIX)

    def undo(self):
        if self._undo:
            state = self._undo.pop(0)
            if not self._undo:
                self._actions["undo"].setEnabled(False)
            self._redo.insert(0, self._changeset.getPersistentState())
            self._actions["redo"].setEnabled(True)
            pkgs = self._changeset.copy()
            self._changeset.setPersistentState(state)
            pkgs.update(self._changeset)
            self.changedMarks(pkgs)

    def redo(self):
        if self._redo:
            state = self._redo.pop(0)
            if not self._redo:
                self._actions["redo"].setEnabled(False)
            self._undo.insert(0, self._changeset.getPersistentState())
            self._actions["undo"].setEnabled(True)
            pkgs = self._changeset.copy()
            self._changeset.setPersistentState(state)
            pkgs.update(self._changeset)
            self.changedMarks(pkgs)

    def saveUndo(self):
        self._undo.insert(0, self._changeset.getPersistentState())
        del self._redo[:]
        del self._undo[20:]
        self._actions["undo"].setEnabled(True)
        self._actions["redo"].setEnabled(False)

    def setTreeStyle(self, mode):
        if mode != sysconf.get("package-tree"):
            sysconf.set("package-tree", mode)
            self.refreshPackages()

    def editChannels(self):
        if QtChannels(self._window).show():
            self.rebuildCache()

    def editMirrors(self):
        QtMirrors(self._window).show()

    def editFlags(self):
        QtFlags(self._window).show()

    def editPriorities(self):
        QtPriorities(self._window).show()

    def setBusy(self, flag):
        if flag:
            qt.QApplication.setOverrideCursor( qt.QCursor(qt.Qt.WaitCursor) )
            while qt.QApplication.eventLoop().hasPendingEvents():
                qt.QApplication.eventLoop().processEvents(qt.QEventLoop.AllEvents)
        else:
            qt.QApplication.restoreOverrideCursor()

    def changedMarks(self, pkgs=[]):
        if "hide-unmarked" in self._filters:
            self.refreshPackages()
        else:
            self._pv.updatePackages(pkgs, self._changeset)
            self._pv.update()
        self._actions["exec-changes"].setEnabled(bool(self._changeset))
        self._actions["clear-changes"].setEnabled(bool(self._changeset))
        

    def toggleSearch(self):
        visible = not self._searchentry.isVisible()
        if visible:
            self._searchbar.show()
        else:
            self._searchbar.hide()
        self.refreshPackages()
        if visible:
            self._searchentry.setFocus()

    def refreshPackages(self):
        if not self._ctrl:
            return

        self.setBusy(True)

        tree = sysconf.get("package-tree", "groups")
        ctrl = self._ctrl
        changeset = self._changeset

        if self._searchbar.isVisible() and \
            self._searchentry.text(): # temporary

            searcher = Searcher()
            dosearch = False
            if self._searchdesc.isChecked():
                text = self._searchentry.text()
                if text:
                    text = str(text).strip()
                    dosearch = True
                    searcher.addDescription(text)
                    searcher.addSummary(text)
            else:
                try:
                    text = self._searchentry.text()
                    tokens = shlex.split(str(text))
                except ValueError:
                    pass
                else:
                    if tokens:
                        dosearch = True
                        for tok in tokens:
                            if searcher.hasAutoMeaning(tok):
                                searcher.addAuto(tok)
                            else:
                                searcher.addNameVersion("*%s*" % tok)

            packages = []
            if dosearch:
                self._ctrl.getCache().search(searcher)
                for ratio, obj in searcher.getResults():
                    if isinstance(obj, Package):
                        packages.append(obj)
                    else:
                        packages.extend(obj.packages)
        else:
            packages = ctrl.getCache().getPackages()

        filters = self._filters
        if filters:
            if "hide-non-upgrades" in filters:
                newpackages = {}
                for pkg in packages:
                    if pkg.installed:
                        upgpkgs = {}
                        try:
                            for prv in pkg.provides:
                                for upg in prv.upgradedby:
                                    for upgpkg in upg.packages:
                                        if upgpkg.installed:
                                            raise StopIteration
                                        upgpkgs[upgpkg] = True
                        except StopIteration:
                            pass
                        else:
                            newpackages.update(upgpkgs)
                packages = newpackages.keys()
            if "hide-uninstalled" in filters:
                packages = [x for x in packages if x.installed]
            if "hide-unmarked" in filters:
                packages = [x for x in packages if x in changeset]
            if "hide-installed" in filters:
                packages = [x for x in packages if not x.installed]
            if "hide-unlocked" in filters:
                packages = pkgconf.filterByFlag("lock", packages)
            if "hide-requested" in filters:
                packages = pkgconf.filterByFlag("auto", packages)
            if "hide-old" in filters:
                packages = pkgconf.filterByFlag("new", packages)

        if tree == "groups":
            groups = {}
            done = {}
            for pkg in packages:
                lastgroup = None
                for loader in pkg.loaders:
                    info = loader.getInfo(pkg)
                    group = info.getGroup()
                    donetuple = (group, pkg)
                    if donetuple not in done:
                        done[donetuple] = True
                        if group in groups:
                            groups[group].append(pkg)
                        else:
                            groups[group] = [pkg]

        elif tree == "channels":
            groups = {}
            done = {}
            for pkg in packages:
                for loader in pkg.loaders:
                    channel = loader.getChannel()
                    group = channel.getName() or channel.getAlias()
                    donetuple = (group, pkg)
                    if donetuple not in done:
                        done[donetuple] = True
                        if group in groups:
                            groups[group].append(pkg)
                        else:
                            groups[group] = [pkg]

        elif tree == "channels-groups":
            groups = {}
            done = {}
            for pkg in packages:
                for loader in pkg.loaders:
                    channel = loader.getChannel()
                    group = channel.getName() or channel.getAlias()
                    subgroup = loader.getInfo(pkg).getGroup()
                    donetuple = (group, subgroup, pkg)
                    if donetuple not in done:
                        done[donetuple] = True
                        if group in groups:
                            if subgroup in groups[group]:
                                groups[group][subgroup].append(pkg)
                            else:
                                groups[group][subgroup] = [pkg]
                        else:
                            groups[group] = {subgroup: [pkg]}

        else:
            groups = packages

        self._pv.setPackages(groups, changeset, keepstate=True)

        self.setBusy(False)

    def showAbout(self):
        copyright = "2010 Smart Team, 2006 Canonical Ltd., 2004 Conectiva, Inc."
        license = """
            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; either version 2 of the License, or
            (at your option) any later version.

            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 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.
            """
        credits=["""Gustavo Niemeyer - Original author and lead developer.""",
           u"""Anders F Bj\u00f6rklund - Current maintainer and developer.""",
            """Conectiva Inc. - Original project funder up to August 2005.""",
            """Canonical Ltd. - Funded Smart up to November of 2009.""",
            """Unity Linux - Smart development and deployment support.""",
            """And many others - Check our website for the complete list.""",
            ]
        website = "http://smartpm.org/"

        qt.QMessageBox.about(self._window, "About " + "Smart Package Manager",
            "<h2>" + "Smart Package Manager" + " " + VERSION + "</h2>" + \
            "<p>Copyright &copy; " + copyright + \
            "<p><small>" + license + "</small>" + \
            "<p><h3>Credits</h3>" + "<br>".join(credits) + \
            "<p><a href=\""+website+"\">"+website+"</a>")
Beispiel #6
0
class QtChanges(qt.QDialog):
    def __init__(self, parent=None):
        qt.QDialog.__init__(self, parent)

        self.setIcon(getPixmap("smart"))
        self.setCaption(_("Change Summary"))
        self.setModal(True)
        self.setMinimumSize(600, 400)
        centerWindow(self)

        self._vbox = qt.QVBoxLayout(self)
        self._vbox.setMargin(10)
        self._vbox.setSpacing(10)

        self._label = qt.QLabel(self)
        self._vbox.addWidget(self._label)

        self._pv = QtPackageView(self)
        self._pv.getTreeView().header().hide()
        self._pv.setExpandPackage(True)
        self._pv.show()
        self._vbox.addWidget(self._pv)

        self._sizelabel = qt.QLabel("", self)
        self._vbox.addWidget(self._sizelabel)

        self._confirmbbox = qt.QHBox(self)
        self._confirmbbox.setSpacing(10)
        self._confirmbbox.layout().addStretch(1)
        self._vbox.addWidget(self._confirmbbox)

        self._cancelbutton = qt.QPushButton(_("Cancel"), self._confirmbbox)
        qt.QObject.connect(self._cancelbutton, qt.SIGNAL("clicked()"), self,
                           qt.SLOT("reject()"))
        self._okbutton = qt.QPushButton(_("OK"), self._confirmbbox)
        qt.QObject.connect(self._okbutton, qt.SIGNAL("clicked()"), self,
                           qt.SLOT("accept()"))

        self._closebbox = qt.QHBox(self)
        self._closebbox.setSpacing(10)
        self._closebbox.layout().addStretch(1)
        self._vbox.addWidget(self._closebbox)

        self._closebutton = qt.QPushButton(_("Close"), self._closebbox)
        qt.QObject.connect(self._closebutton, qt.SIGNAL("clicked()"), self,
                           qt.SLOT("close()"))

    def showChangeSet(self, changeset, keep=None, confirm=False, label=None):

        report = Report(changeset)
        report.compute()

        class Sorter(unicode):
            ORDER = [
                _("Remove"),
                _("Downgrade"),
                _("Reinstall"),
                _("Install"),
                _("Upgrade")
            ]

            def _index(self, s):
                i = 0
                for os in self.ORDER:
                    if os.startswith(s):
                        return i
                    i += 1
                return i

            def __cmp__(self, other):
                return cmp(self._index(unicode(self)),
                           self._index(unicode(other)))

            def __lt__(self, other):
                return cmp(self, other) < 0

        packages = {}

        if report.install:
            install = {}
            reinstall = {}
            upgrade = {}
            downgrade = {}
            lst = report.install.keys()
            lst.sort()
            for pkg in lst:
                package = {}
                done = {}
                if pkg in report.upgrading:
                    for upgpkg in report.upgrading[pkg]:
                        package.setdefault(_("Upgrades"), []).append(upgpkg)
                        done[upgpkg] = True
                if pkg in report.downgrading:
                    for dwnpkg in report.downgrading[pkg]:
                        package.setdefault(_("Downgrades"), []).append(dwnpkg)
                        done[dwnpkg] = True
                if pkg in report.requires:
                    for reqpkg in report.requires[pkg]:
                        package.setdefault(_("Requires"), []).append(reqpkg)
                if pkg in report.requiredby:
                    for reqpkg in report.requiredby[pkg]:
                        package.setdefault(_("Required By"), []).append(reqpkg)
                if pkg in report.conflicts:
                    for cnfpkg in report.conflicts[pkg]:
                        if cnfpkg in done:
                            continue
                        package.setdefault(_("Conflicts"), []).append(cnfpkg)
                if pkg.installed:
                    reinstall[pkg] = package
                elif pkg in report.upgrading:
                    upgrade[pkg] = package
                elif pkg in report.downgrading:
                    downgrade[pkg] = package
                else:
                    install[pkg] = package
            if reinstall:
                packages[Sorter(_("Reinstall (%d)") % len(reinstall))] = \
                                                                    reinstall
            if install:
                packages[Sorter(_("Install (%d)") % len(install))] = install
            if upgrade:
                packages[Sorter(_("Upgrade (%d)") % len(upgrade))] = upgrade
            if downgrade:
                packages[Sorter(_("Downgrade (%d)") % len(downgrade))] = \
                                                                    downgrade

        if report.removed:
            remove = {}
            lst = report.removed.keys()
            lst.sort()
            for pkg in lst:
                package = {}
                done = {}
                if pkg in report.requires:
                    for reqpkg in report.requires[pkg]:
                        package.setdefault(_("Requires"), []).append(reqpkg)
                if pkg in report.requiredby:
                    for reqpkg in report.requiredby[pkg]:
                        package.setdefault(_("Required By"), []).append(reqpkg)
                if pkg in report.conflicts:
                    for cnfpkg in report.conflicts[pkg]:
                        if cnfpkg in done:
                            continue
                        package.setdefault(_("Conflicts"), []).append(cnfpkg)
                remove[pkg] = package
            if remove:
                packages[Sorter(_("Remove (%d)") % len(report.removed))] = \
                                                                        remove

        if keep:
            packages[Sorter(_("Keep (%d)") % len(keep))] = keep

        dsize = report.getDownloadSize()
        size = report.getInstallSize() - report.getRemoveSize()
        sizestr = ""
        if dsize:
            sizestr += _("%s of package files are needed. ") % sizeToStr(dsize)
        if size > 0:
            sizestr += _("%s will be used.") % sizeToStr(size)
        elif size < 0:
            size *= -1
            sizestr += _("%s will be freed.") % sizeToStr(size)
        if dsize or size:
            self._sizelabel.setText(sizestr)
            self._sizelabel.show()
        else:
            self._sizelabel.hide()

        if confirm:
            self._confirmbbox.show()
            self._closebbox.hide()
            self._okbutton.setDefault(True)
        else:
            self._closebbox.show()
            self._confirmbbox.hide()
            self._closebutton.setDefault(True)

        if label:
            self._label.set_text(label)
            self._label.show()
        else:
            self._label.hide()

        self._pv.setPackages(packages, changeset)

        # Expand first level
        self._pv.setExpanded([(x, ) for x in packages])

        self._result = False
        self.show()
        dialogResult = self.exec_loop()
        self._result = (dialogResult == qt.QDialog.Accepted)

        return self._result
    def __init__(self, parent):
        qt.QTabWidget.__init__(self, parent)

        self._pkg = None
        self._changeset = None

        self._tabwidget = self
        self._tabwidget.show()

        sv = BackgroundScrollView(self._tabwidget)
        sv.setMargin(5)
        sv.show()

        grid = qt.QGrid(2, sv.viewport())
        grid.setSpacing(5)
        grid.setMargin(5)
        grid.show()
        sv.addChild(grid)

        self._info = type("Info", (), {})()

        row = 1
        for attr, text in [("status", _("Status:")),
                           ("priority", _("Priority:")),
                           ("group", _("Group:")),
                           ("installedsize", _("Installed Size:")),
                           ("channels", _("Channels:")),
                           ("reference", _("Reference URLs:"))]:
            label = qt.QLabel(text, grid)
            label.show()
            setattr(self._info, attr+"_label", label)
            label = qt.QLabel("", grid)
            label.show()
            setattr(self._info, attr, label)
            row += 1
        
        self._grid = grid

        self._grid.adjustSize()
        self._tabwidget.addTab(sv, _("General"))

        sv = BackgroundScrollView(self._tabwidget)
        sv.setMargin(5)
        sv.show()

        self._descr = qt.QLabel(sv.viewport())
        self._descr.setAlignment(qt.Qt.AlignTop)
        self._descr.show()
        sv.addChild(self._descr)

        self._descr.adjustSize()
        self._tabwidget.addTab(sv, _("Description"))

        sv = BackgroundScrollView(self._tabwidget)
        sv.setVScrollBarMode(qt.QScrollView.AlwaysOn)
        sv.setMargin(5)
        sv.show()

        self._cont = qt.QLabel(sv.viewport())
        self._cont.setAlignment(qt.Qt.AlignTop)
        self._cont.setSizePolicy(qt.QSizePolicy.Expanding,qt.QSizePolicy.Expanding)
        self._cont.show()
        sv.addChild(self._cont)

        self._cont.adjustSize()
        self._tabwidget.addTab(sv, _("Content"))

        sv = BackgroundScrollView(self._tabwidget)
        sv.setVScrollBarMode(qt.QScrollView.AlwaysOn)
        sv.setMargin(5)
        sv.show()

        self._change = qt.QLabel(sv.viewport())
        self._change.setAlignment(qt.Qt.AlignTop)
        self._change.setSizePolicy(qt.QSizePolicy.Expanding,qt.QSizePolicy.Expanding)
        self._change.show()
        sv.addChild(self._change)

        self._change.adjustSize()
        self._tabwidget.addTab(sv, _("Changelog"))

        self._relations = QtPackageView(self._tabwidget)
        self._relations.getTreeView().header().hide()
        self._relations.show()

        self._tabwidget.addTab(self._relations, _("Relations"))

        self._urls = qt.QListView(self._tabwidget)
        self._urls.setSizePolicy(qt.QSizePolicy.Expanding,qt.QSizePolicy.Expanding)
        self._urls.setAllColumnsShowFocus(True)
        self._urls.header().hide()
        self._urls.show()
        self._urls.addColumn(_("Channel"))
        self._urls.addColumn(_("Size"))
        self._urls.addColumn(_("URL"))
        
        self._tabwidget.addTab(self._urls, _("URLs"))

        self._tabwidget.adjustSize()
        qt.QObject.connect(self._tabwidget, qt.SIGNAL("currentChanged(QWidget *)"), self._currentChanged)
class QtPackageInfo(qt.QTabWidget):
    def __init__(self, parent):
        qt.QTabWidget.__init__(self, parent)

        self._pkg = None
        self._changeset = None

        self._tabwidget = self
        self._tabwidget.show()

        sv = BackgroundScrollView(self._tabwidget)
        sv.setMargin(5)
        sv.show()

        grid = qt.QGrid(2, sv.viewport())
        grid.setSpacing(5)
        grid.setMargin(5)
        grid.show()
        sv.addChild(grid)

        self._info = type("Info", (), {})()

        row = 1
        for attr, text in [("status", _("Status:")),
                           ("priority", _("Priority:")),
                           ("group", _("Group:")),
                           ("installedsize", _("Installed Size:")),
                           ("channels", _("Channels:")),
                           ("reference", _("Reference URLs:"))]:
            label = qt.QLabel(text, grid)
            label.show()
            setattr(self._info, attr+"_label", label)
            label = qt.QLabel("", grid)
            label.show()
            setattr(self._info, attr, label)
            row += 1
        
        self._grid = grid

        self._grid.adjustSize()
        self._tabwidget.addTab(sv, _("General"))

        sv = BackgroundScrollView(self._tabwidget)
        sv.setMargin(5)
        sv.show()

        self._descr = qt.QLabel(sv.viewport())
        self._descr.setAlignment(qt.Qt.AlignTop)
        self._descr.show()
        sv.addChild(self._descr)

        self._descr.adjustSize()
        self._tabwidget.addTab(sv, _("Description"))

        sv = BackgroundScrollView(self._tabwidget)
        sv.setVScrollBarMode(qt.QScrollView.AlwaysOn)
        sv.setMargin(5)
        sv.show()

        self._cont = qt.QLabel(sv.viewport())
        self._cont.setAlignment(qt.Qt.AlignTop)
        self._cont.setSizePolicy(qt.QSizePolicy.Expanding,qt.QSizePolicy.Expanding)
        self._cont.show()
        sv.addChild(self._cont)

        self._cont.adjustSize()
        self._tabwidget.addTab(sv, _("Content"))

        sv = BackgroundScrollView(self._tabwidget)
        sv.setVScrollBarMode(qt.QScrollView.AlwaysOn)
        sv.setMargin(5)
        sv.show()

        self._change = qt.QLabel(sv.viewport())
        self._change.setAlignment(qt.Qt.AlignTop)
        self._change.setSizePolicy(qt.QSizePolicy.Expanding,qt.QSizePolicy.Expanding)
        self._change.show()
        sv.addChild(self._change)

        self._change.adjustSize()
        self._tabwidget.addTab(sv, _("Changelog"))

        self._relations = QtPackageView(self._tabwidget)
        self._relations.getTreeView().header().hide()
        self._relations.show()

        self._tabwidget.addTab(self._relations, _("Relations"))

        self._urls = qt.QListView(self._tabwidget)
        self._urls.setSizePolicy(qt.QSizePolicy.Expanding,qt.QSizePolicy.Expanding)
        self._urls.setAllColumnsShowFocus(True)
        self._urls.header().hide()
        self._urls.show()
        self._urls.addColumn(_("Channel"))
        self._urls.addColumn(_("Size"))
        self._urls.addColumn(_("URL"))
        
        self._tabwidget.addTab(self._urls, _("URLs"))

        self._tabwidget.adjustSize()
        qt.QObject.connect(self._tabwidget, qt.SIGNAL("currentChanged(QWidget *)"), self._currentChanged)
         
    def _currentChanged(self, widget):
        pagenum = qt.QTabWidget.indexOf(self._tabwidget, widget)
        self.setPackage(self._pkg, pagenum)

    def setChangeSet(self, changeset):
        self._changeset = changeset

    def setPackage(self, pkg, _pagenum=None):

        self._pkg = pkg

        if _pagenum is not None:
            num = _pagenum
        else:
            num = self._tabwidget.currentPageIndex()

        if num == 0:

            # Update general information

            if not pkg:
                self._info.status.setText("")
                self._info.group.setText("")
                self._info.installedsize.setText("")
                self._info.priority.setText("")
                self._info.channels.setText("")
                self._info.reference.setText("")
                return

            group = None
            installedsize = None
            channels = []
            urls = []
            for loader in pkg.loaders:
                info = loader.getInfo(pkg)
                if group is None:
                    group = info.getGroup()
                if installedsize is None:
                    installedsize = info.getInstalledSize()
                channel = loader.getChannel()
                channels.append("%s (%s)" %
                                (channel.getName() or channel.getAlias(),
                                 channel.getAlias()))
                urls.extend(info.getReferenceURLs())

            flags = pkgconf.testAllFlags(pkg)
            if flags:
                flags.sort()
                flags = " (%s)" % ", ".join(flags)
            else:
                flags = ""

            def bold(text):
                return "<b>"+unicode(qt.QStyleSheet.escape(text))+"</b>"

            def link(text, url):
                return "<a href=\""+url+"\">"+unicode(qt.QStyleSheet.escape(text))+"</a>"
            
            status = pkg.installed and _("Installed") or _("Available")
            self._info.status.setText(bold(status+flags))
            self._info.group.setText(bold(group or _("Unknown")))
            self._info.priority.setText(bold(str(pkg.getPriority())))
            self._info.channels.setText(bold("\n".join(channels)))
            links = []
            for url in urls:
                links.append(link(url, url))
            self._info.reference.setText(" ".join(links))

            if installedsize:
                self._info.installedsize.setText(bold(sizeToStr(installedsize)))
                self._info.installedsize.show()
                self._info.installedsize_label.show()
            else:
                self._info.installedsize.hide()
                self._info.installedsize_label.hide()
                pass
                
            self._grid.adjustSize()

        elif num == 1:

            # Update summary/description

            self._descr.setText("")
            if not pkg: return

            #iter = descrbuf.get_end_iter()
            text = ""
            for loader in pkg.loaders:
                info = loader.getInfo(pkg)
                summary = info.getSummary()
                if summary:
                    text += "<b>"+unicode(qt.QStyleSheet.escape(summary))+"</b><br><br>"
                    description = info.getDescription()
                    if description != summary:
                         text += description+"\n\n"
                    break
            else:
                loader = pkg.loaders.keys()[0]

            self._descr.setText(text)

        elif num == 2:

            # Update contents

            self._cont.setText("")
            if not pkg: return

            text = ""
            for loader in pkg.loaders:
                if loader.getInstalled():
                    break
            else:
                loader = pkg.loaders.keys()[0]
            info = loader.getInfo(pkg)
            pathlist = info.getPathList()
            pathlist.sort()
            for path in pathlist:
                text += path+"\n"

            self._cont.setText(text)
            self._cont.adjustSize()

        elif num == 3:
            # Update changelog

            self._change.setText("")
            if not pkg: return

            text = ""
            for loader in pkg.loaders:
                if loader.getInstalled():
                    break
            else:
                loader = pkg.loaders.keys()[0]
            info = loader.getInfo(pkg)
            changelog = info.getChangeLog()

            for i in range(len(changelog)/2):
                text += "<b>"+unicode(qt.QStyleSheet.escape(changelog[2*i]))+"</b><br>"
                changesplit = changelog[2*i+1].split("\n")
                text += unicode(qt.QStyleSheet.escape(changesplit[0]))+"<br>"
                for i in range(1, len(changesplit)):
                   text += "  " + unicode(qt.QStyleSheet.escape(changesplit[i]))+"<br>"

            self._change.setText(text)
            self._change.adjustSize()

        elif num == 4:

            # Update relations

            if not pkg:
                self._relations.setPackages([])
                return

            self._setRelations(pkg)

        elif num == 5:

            # Update URLs

            self._urls.clear()

            if not pkg:
                return

            items = []
            for loader in pkg.loaders:
                channel = loader.getChannel()
                alias = channel.getAlias()
                info = loader.getInfo(pkg)
                for url in info.getURLs():
                    items.append((alias, sizeToStr(info.getSize(url)), url))

            items.sort()

            lastitem = None
            for item in items:
                if item != lastitem:
                    lastitem = item
                    listitem = qt.QListViewItem(self._urls)
                    listitem.setText(0, item[0])
                    listitem.setText(1, item[1])
                    listitem.setText(2, item[2])

    def _setRelations(self, pkg):

        class Sorter(unicode):
            ORDER = [_("Provides"), _("Upgrades"),
                     _("Requires"), _("Conflicts")]
            def __cmp__(self, other):
                return cmp(self.ORDER.index(unicode(self)),
                           self.ORDER.index(unicode(other)))
            def __lt__(self, other):
                return cmp(self, other) < 0

        relations = {}

        for prv in pkg.provides:

            prvmap = {}
            
            requiredby = []
            for req in prv.requiredby:
                requiredby.extend(req.packages)
            if requiredby:
                prvmap[_("Required By")] = requiredby

            upgradedby = []
            for upg in prv.upgradedby:
                upgradedby.extend(upg.packages)
            if upgradedby:
                prvmap[_("Upgraded By")] = upgradedby

            conflictedby = []
            for cnf in prv.conflictedby:
                conflictedby.extend(cnf.packages)
            if conflictedby:
                prvmap[_("Conflicted By")] = conflictedby

            if prvmap:
                relations.setdefault(Sorter(_("Provides")), {})[str(prv)] = \
                                                                        prvmap

        requires = {}
        for req in pkg.requires:
            lst = requires.setdefault(str(req), [])
            for prv in req.providedby:
                lst.extend(prv.packages)
            lst[:] = dict.fromkeys(lst).keys()
        if requires:
            relations[Sorter(_("Requires"))] = requires

        upgrades = {}
        for upg in pkg.upgrades:
            lst = upgrades.setdefault(str(upg), [])
            for prv in upg.providedby:
                lst.extend(prv.packages)
            lst[:] = dict.fromkeys(lst).keys()
        if upgrades:
            relations[Sorter(_("Upgrades"))] = upgrades

        conflicts = {}
        for cnf in pkg.conflicts:
            lst = conflicts.setdefault(str(cnf), [])
            for prv in cnf.providedby:
                lst.extend(prv.packages)
            lst[:] = dict.fromkeys(lst).keys()
        if conflicts:
            relations[Sorter(_("Conflicts"))] = conflicts

        self._relations.setPackages(relations, self._changeset)
Beispiel #9
0
    def __init__(self, parent):
        qt.QTabWidget.__init__(self, parent)

        self._pkg = None
        self._changeset = None

        self._tabwidget = self
        self._tabwidget.show()

        sv = BackgroundScrollView(self._tabwidget)
        sv.setMargin(5)
        sv.show()

        grid = qt.QGrid(2, sv.viewport())
        grid.setSpacing(5)
        grid.setMargin(5)
        grid.show()
        sv.addChild(grid)

        self._info = type("Info", (), {})()

        row = 1
        for attr, text in [("status", _("Status:")),
                           ("priority", _("Priority:")),
                           ("group", _("Group:")),
                           ("installedsize", _("Installed Size:")),
                           ("channels", _("Channels:")),
                           ("reference", _("Reference URLs:"))]:
            label = qt.QLabel(text, grid)
            label.show()
            setattr(self._info, attr + "_label", label)
            label = qt.QLabel("", grid)
            label.show()
            setattr(self._info, attr, label)
            row += 1

        self._grid = grid

        self._grid.adjustSize()
        self._tabwidget.addTab(sv, _("General"))

        sv = BackgroundScrollView(self._tabwidget)
        sv.setMargin(5)
        sv.show()

        self._descr = qt.QLabel(sv.viewport())
        self._descr.setAlignment(qt.Qt.AlignTop)
        self._descr.show()
        sv.addChild(self._descr)

        self._descr.adjustSize()
        self._tabwidget.addTab(sv, _("Description"))

        sv = BackgroundScrollView(self._tabwidget)
        sv.setVScrollBarMode(qt.QScrollView.AlwaysOn)
        sv.setMargin(5)
        sv.show()

        self._cont = qt.QLabel(sv.viewport())
        self._cont.setAlignment(qt.Qt.AlignTop)
        self._cont.setSizePolicy(qt.QSizePolicy.Expanding,
                                 qt.QSizePolicy.Expanding)
        self._cont.show()
        sv.addChild(self._cont)

        self._cont.adjustSize()
        self._tabwidget.addTab(sv, _("Content"))

        sv = BackgroundScrollView(self._tabwidget)
        sv.setVScrollBarMode(qt.QScrollView.AlwaysOn)
        sv.setMargin(5)
        sv.show()

        self._change = qt.QLabel(sv.viewport())
        self._change.setAlignment(qt.Qt.AlignTop)
        self._change.setSizePolicy(qt.QSizePolicy.Expanding,
                                   qt.QSizePolicy.Expanding)
        self._change.show()
        sv.addChild(self._change)

        self._change.adjustSize()
        self._tabwidget.addTab(sv, _("Changelog"))

        self._relations = QtPackageView(self._tabwidget)
        self._relations.getTreeView().header().hide()
        self._relations.show()

        self._tabwidget.addTab(self._relations, _("Relations"))

        self._urls = qt.QListView(self._tabwidget)
        self._urls.setSizePolicy(qt.QSizePolicy.Expanding,
                                 qt.QSizePolicy.Expanding)
        self._urls.setAllColumnsShowFocus(True)
        self._urls.header().hide()
        self._urls.show()
        self._urls.addColumn(_("Channel"))
        self._urls.addColumn(_("Size"))
        self._urls.addColumn(_("URL"))

        self._tabwidget.addTab(self._urls, _("URLs"))

        self._tabwidget.adjustSize()
        qt.QObject.connect(self._tabwidget,
                           qt.SIGNAL("currentChanged(QWidget *)"),
                           self._currentChanged)
Beispiel #10
0
class QtPackageInfo(qt.QTabWidget):
    def __init__(self, parent):
        qt.QTabWidget.__init__(self, parent)

        self._pkg = None
        self._changeset = None

        self._tabwidget = self
        self._tabwidget.show()

        sv = BackgroundScrollView(self._tabwidget)
        sv.setMargin(5)
        sv.show()

        grid = qt.QGrid(2, sv.viewport())
        grid.setSpacing(5)
        grid.setMargin(5)
        grid.show()
        sv.addChild(grid)

        self._info = type("Info", (), {})()

        row = 1
        for attr, text in [("status", _("Status:")),
                           ("priority", _("Priority:")),
                           ("group", _("Group:")),
                           ("installedsize", _("Installed Size:")),
                           ("channels", _("Channels:")),
                           ("reference", _("Reference URLs:"))]:
            label = qt.QLabel(text, grid)
            label.show()
            setattr(self._info, attr + "_label", label)
            label = qt.QLabel("", grid)
            label.show()
            setattr(self._info, attr, label)
            row += 1

        self._grid = grid

        self._grid.adjustSize()
        self._tabwidget.addTab(sv, _("General"))

        sv = BackgroundScrollView(self._tabwidget)
        sv.setMargin(5)
        sv.show()

        self._descr = qt.QLabel(sv.viewport())
        self._descr.setAlignment(qt.Qt.AlignTop)
        self._descr.show()
        sv.addChild(self._descr)

        self._descr.adjustSize()
        self._tabwidget.addTab(sv, _("Description"))

        sv = BackgroundScrollView(self._tabwidget)
        sv.setVScrollBarMode(qt.QScrollView.AlwaysOn)
        sv.setMargin(5)
        sv.show()

        self._cont = qt.QLabel(sv.viewport())
        self._cont.setAlignment(qt.Qt.AlignTop)
        self._cont.setSizePolicy(qt.QSizePolicy.Expanding,
                                 qt.QSizePolicy.Expanding)
        self._cont.show()
        sv.addChild(self._cont)

        self._cont.adjustSize()
        self._tabwidget.addTab(sv, _("Content"))

        sv = BackgroundScrollView(self._tabwidget)
        sv.setVScrollBarMode(qt.QScrollView.AlwaysOn)
        sv.setMargin(5)
        sv.show()

        self._change = qt.QLabel(sv.viewport())
        self._change.setAlignment(qt.Qt.AlignTop)
        self._change.setSizePolicy(qt.QSizePolicy.Expanding,
                                   qt.QSizePolicy.Expanding)
        self._change.show()
        sv.addChild(self._change)

        self._change.adjustSize()
        self._tabwidget.addTab(sv, _("Changelog"))

        self._relations = QtPackageView(self._tabwidget)
        self._relations.getTreeView().header().hide()
        self._relations.show()

        self._tabwidget.addTab(self._relations, _("Relations"))

        self._urls = qt.QListView(self._tabwidget)
        self._urls.setSizePolicy(qt.QSizePolicy.Expanding,
                                 qt.QSizePolicy.Expanding)
        self._urls.setAllColumnsShowFocus(True)
        self._urls.header().hide()
        self._urls.show()
        self._urls.addColumn(_("Channel"))
        self._urls.addColumn(_("Size"))
        self._urls.addColumn(_("URL"))

        self._tabwidget.addTab(self._urls, _("URLs"))

        self._tabwidget.adjustSize()
        qt.QObject.connect(self._tabwidget,
                           qt.SIGNAL("currentChanged(QWidget *)"),
                           self._currentChanged)

    def _currentChanged(self, widget):
        pagenum = qt.QTabWidget.indexOf(self._tabwidget, widget)
        self.setPackage(self._pkg, pagenum)

    def setChangeSet(self, changeset):
        self._changeset = changeset

    def setPackage(self, pkg, _pagenum=None):

        self._pkg = pkg

        if _pagenum is not None:
            num = _pagenum
        else:
            num = self._tabwidget.currentPageIndex()

        if num == 0:

            # Update general information

            if not pkg:
                self._info.status.setText("")
                self._info.group.setText("")
                self._info.installedsize.setText("")
                self._info.priority.setText("")
                self._info.channels.setText("")
                self._info.reference.setText("")
                return

            group = None
            installedsize = None
            channels = []
            urls = []
            for loader in pkg.loaders:
                info = loader.getInfo(pkg)
                if group is None:
                    group = info.getGroup()
                if installedsize is None:
                    installedsize = info.getInstalledSize()
                channel = loader.getChannel()
                channels.append("%s (%s)" %
                                (channel.getName()
                                 or channel.getAlias(), channel.getAlias()))
                urls.extend(info.getReferenceURLs())

            flags = pkgconf.testAllFlags(pkg)
            if flags:
                flags.sort()
                flags = " (%s)" % ", ".join(flags)
            else:
                flags = ""

            def bold(text):
                return "<b>" + unicode(qt.QStyleSheet.escape(text)) + "</b>"

            def link(text, url):
                return "<a href=\"" + url + "\">" + unicode(
                    qt.QStyleSheet.escape(text)) + "</a>"

            status = pkg.installed and _("Installed") or _("Available")
            self._info.status.setText(bold(status + flags))
            self._info.group.setText(bold(group or _("Unknown")))
            self._info.priority.setText(bold(str(pkg.getPriority())))
            self._info.channels.setText(bold("\n".join(channels)))
            links = []
            for url in urls:
                links.append(link(url, url))
            self._info.reference.setText(" ".join(links))

            if installedsize:
                self._info.installedsize.setText(bold(
                    sizeToStr(installedsize)))
                self._info.installedsize.show()
                self._info.installedsize_label.show()
            else:
                self._info.installedsize.hide()
                self._info.installedsize_label.hide()
                pass

            self._grid.adjustSize()

        elif num == 1:

            # Update summary/description

            self._descr.setText("")
            if not pkg: return

            #iter = descrbuf.get_end_iter()
            text = ""
            for loader in pkg.loaders:
                info = loader.getInfo(pkg)
                summary = info.getSummary()
                if summary:
                    text += "<b>" + unicode(
                        qt.QStyleSheet.escape(summary)) + "</b><br><br>"
                    description = info.getDescription()
                    if description != summary:
                        text += description + "\n\n"
                    break
            else:
                loader = pkg.loaders.keys()[0]

            self._descr.setText(text)

        elif num == 2:

            # Update contents

            self._cont.setText("")
            if not pkg: return

            text = ""
            for loader in pkg.loaders:
                if loader.getInstalled():
                    break
            else:
                loader = pkg.loaders.keys()[0]
            info = loader.getInfo(pkg)
            pathlist = info.getPathList()
            pathlist.sort()
            for path in pathlist:
                text += path + "\n"

            self._cont.setText(text)
            self._cont.adjustSize()

        elif num == 3:
            # Update changelog

            self._change.setText("")
            if not pkg: return

            text = ""
            for loader in pkg.loaders:
                if loader.getInstalled():
                    break
            else:
                loader = pkg.loaders.keys()[0]
            info = loader.getInfo(pkg)
            changelog = info.getChangeLog()

            for i in range(len(changelog) / 2):
                text += "<b>" + unicode(qt.QStyleSheet.escape(
                    changelog[2 * i])) + "</b><br>"
                changesplit = changelog[2 * i + 1].split("\n")
                text += unicode(qt.QStyleSheet.escape(changesplit[0])) + "<br>"
                for i in range(1, len(changesplit)):
                    text += "  " + unicode(
                        qt.QStyleSheet.escape(changesplit[i])) + "<br>"

            self._change.setText(text)
            self._change.adjustSize()

        elif num == 4:

            # Update relations

            if not pkg:
                self._relations.setPackages([])
                return

            self._setRelations(pkg)

        elif num == 5:

            # Update URLs

            self._urls.clear()

            if not pkg:
                return

            items = []
            for loader in pkg.loaders:
                channel = loader.getChannel()
                alias = channel.getAlias()
                info = loader.getInfo(pkg)
                for url in info.getURLs():
                    items.append((alias, sizeToStr(info.getSize(url)), url))

            items.sort()

            lastitem = None
            for item in items:
                if item != lastitem:
                    lastitem = item
                    listitem = qt.QListViewItem(self._urls)
                    listitem.setText(0, item[0])
                    listitem.setText(1, item[1])
                    listitem.setText(2, item[2])

    def _setRelations(self, pkg):
        class Sorter(unicode):
            ORDER = [
                _("Provides"),
                _("Upgrades"),
                _("Requires"),
                _("Conflicts")
            ]

            def __cmp__(self, other):
                return cmp(self.ORDER.index(unicode(self)),
                           self.ORDER.index(unicode(other)))

            def __lt__(self, other):
                return cmp(self, other) < 0

        relations = {}

        for prv in pkg.provides:

            prvmap = {}

            requiredby = []
            for req in prv.requiredby:
                requiredby.extend(req.packages)
            if requiredby:
                prvmap[_("Required By")] = requiredby

            upgradedby = []
            for upg in prv.upgradedby:
                upgradedby.extend(upg.packages)
            if upgradedby:
                prvmap[_("Upgraded By")] = upgradedby

            conflictedby = []
            for cnf in prv.conflictedby:
                conflictedby.extend(cnf.packages)
            if conflictedby:
                prvmap[_("Conflicted By")] = conflictedby

            if prvmap:
                relations.setdefault(Sorter(_("Provides")), {})[str(prv)] = \
                                                                        prvmap

        requires = {}
        for req in pkg.requires:
            lst = requires.setdefault(str(req), [])
            for prv in req.providedby:
                lst.extend(prv.packages)
            lst[:] = dict.fromkeys(lst).keys()
        if requires:
            relations[Sorter(_("Requires"))] = requires

        upgrades = {}
        for upg in pkg.upgrades:
            lst = upgrades.setdefault(str(upg), [])
            for prv in upg.providedby:
                lst.extend(prv.packages)
            lst[:] = dict.fromkeys(lst).keys()
        if upgrades:
            relations[Sorter(_("Upgrades"))] = upgrades

        conflicts = {}
        for cnf in pkg.conflicts:
            lst = conflicts.setdefault(str(cnf), [])
            for prv in cnf.providedby:
                lst.extend(prv.packages)
            lst[:] = dict.fromkeys(lst).keys()
        if conflicts:
            relations[Sorter(_("Conflicts"))] = conflicts

        self._relations.setPackages(relations, self._changeset)