From eae9ec73ba26638e25d23ba2261422461150ad73 Mon Sep 17 00:00:00 2001 From: necoro <> Date: Thu, 16 Aug 2007 03:39:18 +0000 Subject: removed qt --- portato/gui/qt/__init__.py | 39 - portato/gui/qt/dialogs.py | 44 - portato/gui/qt/helper.py | 35 - portato/gui/qt/highlighter.py | 168 ---- portato/gui/qt/terminal.py | 378 --------- portato/gui/qt/tree.py | 155 ---- portato/gui/qt/uncheckbox.py | 38 - portato/gui/qt/windows.py | 1125 -------------------------- portato/gui/templates/ui/AboutDialog.ui | 111 --- portato/gui/templates/ui/EbuildDialog.ui | 88 -- portato/gui/templates/ui/LogDialog.ui | 88 -- portato/gui/templates/ui/MainWindow.ui | 720 ----------------- portato/gui/templates/ui/PluginDialog.ui | 94 --- portato/gui/templates/ui/PreferenceWindow.ui | 379 --------- portato/gui/templates/ui/SearchDialog.ui | 78 -- portato/gui/templates/ui/UpdateDialog.ui | 108 --- 16 files changed, 3648 deletions(-) delete mode 100644 portato/gui/qt/__init__.py delete mode 100644 portato/gui/qt/dialogs.py delete mode 100644 portato/gui/qt/helper.py delete mode 100644 portato/gui/qt/highlighter.py delete mode 100644 portato/gui/qt/terminal.py delete mode 100644 portato/gui/qt/tree.py delete mode 100644 portato/gui/qt/uncheckbox.py delete mode 100644 portato/gui/qt/windows.py delete mode 100644 portato/gui/templates/ui/AboutDialog.ui delete mode 100644 portato/gui/templates/ui/EbuildDialog.ui delete mode 100644 portato/gui/templates/ui/LogDialog.ui delete mode 100644 portato/gui/templates/ui/MainWindow.ui delete mode 100644 portato/gui/templates/ui/PluginDialog.ui delete mode 100644 portato/gui/templates/ui/PreferenceWindow.ui delete mode 100644 portato/gui/templates/ui/SearchDialog.ui delete mode 100644 portato/gui/templates/ui/UpdateDialog.ui (limited to 'portato/gui') diff --git a/portato/gui/qt/__init__.py b/portato/gui/qt/__init__.py deleted file mode 100644 index 3f83aeb..0000000 --- a/portato/gui/qt/__init__.py +++ /dev/null @@ -1,39 +0,0 @@ -# -*- coding: utf-8 -*- -# -# File: portato/gui/qt/__init__.py -# This file is part of the Portato-Project, a graphical portage-frontend. -# -# Copyright (C) 2007 René 'Necoro' Neumann -# This is free software. You may redistribute copies of it under the terms of -# the GNU General Public License version 2. -# There is NO WARRANTY, to the extent permitted by law. -# -# Written by René 'Necoro' Neumann - -from portato import plugin -from portato.backend import system - -from PyQt4.Qt import QApplication -from windows import MainWindow, EbuildDialog, SearchDialog - -def run(): - app = QApplication([]) - m = MainWindow() - app.exec_() - -def show_ebuild (pkg): - plugin.load_plugins("qt") - app = QApplication([]) - - def _show (pkg): - pkg = system.new_package(pkg) - hook = plugin.hook("open_ebuild", pkg, None) - - ew = hook(EbuildDialog)(None, pkg) - ew.setWindowTitle("Portato Ebuild Viewer - %s" % pkg.get_cpv()) - ew.exec_() - - s = SearchDialog(None, [x.get_cpv() for x in system.sort_package_list(system.find_all_packages(pkg, True))], _show) - s.setWindowTitle("Portato Ebuild Viewer - Search") - s.show() - app.exec_() diff --git a/portato/gui/qt/dialogs.py b/portato/gui/qt/dialogs.py deleted file mode 100644 index 6a80164..0000000 --- a/portato/gui/qt/dialogs.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- -# -# File: portato/gui/qt/dialogs.py -# This file is part of the Portato-Project, a graphical portage-frontend. -# -# Copyright (C) 2007 René 'Necoro' Neumann -# This is free software. You may redistribute copies of it under the terms of -# the GNU General Public License version 2. -# There is NO WARRANTY, to the extent permitted by law. -# -# Written by René 'Necoro' Neumann - -from PyQt4.QtGui import QMessageBox - -def queue_not_empty_dialog(parent): - return QMessageBox.question(parent, "Portato", "There are some packages in the emerge queue and/or an emerge process is running.\nDo you really want to quit?", QMessageBox.Ok | QMessageBox.Cancel) - -def io_ex_dialog (parent, ex): - string = ex.strerror - if ex.filename: - string = string+": "+ex.filename - - return QMessageBox.critical(parent, "Portato", string, QMessageBox.Ok) - -def nothing_found_dialog (parent): - return QMessageBox.information(parent, "Portato", "No packages found.", QMessageBox.Ok) - -def not_root_dialog (parent): - return QMessageBox.warning(parent, "Portato", "You are not root!", QMessageBox.Ok) - -def unmask_dialog (parent, cpv): - return QMessageBox.question(parent, "Portato", cpv+" seems to be masked.\nDo you want to unmask it and its dependencies?", QMessageBox.Yes | QMessageBox.No) - -def blocked_dialog (parent, blocked, blocks): - return QMessageBox.warning(parent, "Portato", blocked+" is blocked by "+blocks+".\nPlease unmerge the blocking package.", QMessageBox.Ok) - -def remove_deps_dialog (parent): - return QMessageBox.information(parent, "Portato", "You cannot remove dependencies. :)", QMessageBox.Ok) - -def remove_queue_dialog (parent): - return QMessageBox.question(parent, "Portato", "Do you really want to clear the whole queue?", QMessageBox.Yes | QMessageBox.No) - -def changed_flags_dialog (parent, what = "flags"): - return QMessageBox.information(parent, "Portato", "You have changed %s. Portato will write these changes into the appropriate files. Please backup them if you think it is necessairy." % what, QMessageBox.Ok) diff --git a/portato/gui/qt/helper.py b/portato/gui/qt/helper.py deleted file mode 100644 index fa1576a..0000000 --- a/portato/gui/qt/helper.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- -# -# File: portato/gui/qt/helper.py -# This file is part of the Portato-Project, a graphical portage-frontend. -# -# Copyright (C) 2007 René 'Necoro' Neumann -# This is free software. You may redistribute copies of it under the terms of -# the GNU General Public License version 2. -# There is NO WARRANTY, to the extent permitted by law. -# -# Written by René 'Necoro' Neumann - -from PyQt4 import Qt - -def qCheck (check): - """Maps True or False to Qt.Checked or Qt.Unchecked. - - @param check: boolean value - @type check: bool - @returns: CheckState-Constant - @rtype: int""" - - if check: - return Qt.Qt.Checked - else: - return Qt.Qt.Unchecked - -def qIsChecked (check): - """Maps Qt.Checked and Qt.Unchecked to True and False. - - @param check: CheckState-Constant - @type check: int - @returns: appropriate boolean value - @rtype: bool""" - return check == Qt.Qt.Checked diff --git a/portato/gui/qt/highlighter.py b/portato/gui/qt/highlighter.py deleted file mode 100644 index 74d9ac9..0000000 --- a/portato/gui/qt/highlighter.py +++ /dev/null @@ -1,168 +0,0 @@ -# -*- coding: utf-8 -*- -# -# File: portato/gui/qt/highlighter.py -# This file is part of the Portato-Project, a graphical portage-frontend. -# -# Copyright (C) 2007 René 'Necoro' Neumann -# This is free software. You may redistribute copies of it under the terms of -# the GNU General Public License version 2. -# There is NO WARRANTY, to the extent permitted by law. -# -# Written by René 'Necoro' Neumann - -# The syntax is inspired by the gtksourceview syntax by -# Leonardo Ferreira Fontenelle - -from PyQt4 import Qt -from portato.helper import debug - -import re # prefer Python-Module over Qt-one - -class EbuildHighlighter (Qt.QSyntaxHighlighter): - """A QSyntaxHighlighter implementation for the use with ebuild-syntax.""" - - NORMAL_STATE = 0 - STRING_STATE = 1 - - def __init__ (self, edit): - """Constructor. - - @param edit: the EditWidget to use the highlighter with - @type edit: Qt.QTextEdit""" - - Qt.QSyntaxHighlighter.__init__(self, edit) - - # - # the regular expressions ... *muahahaha* - # - - # comments - self.comment = self.__create(r'#.*', color = "steelblue", italic = True) - - # bash variables - self.bashVar = self.__create(r'(\$\{.+?\})|(\$\w+)', color = "green") - - # a string - self.string = self.__create(r'(? - -from PyQt4 import Qt - -from Queue import Queue -from threading import Thread, currentThread -from os import read, close -import errno - -from portato.gui.wrapper import Console -from portato.helper import debug - -try: - from curses.ascii import ctrl -except ImportError: # emulate ctrl-behavior for known values - def ctrl (val): - if val == "H": return '\x08' - elif val == "W": return '\x17' - else: debug("unknown error passed to emulated ctrl: %s",val) - - -class WriteEvent (Qt.QEvent): - TYPE = Qt.QEvent.Type(1001) - - def __init__ (self, string): - Qt.QEvent.__init__(self, self.TYPE) - self.string = string - - def get_string(self): - return self.string - -class DeleteEvent (Qt.QEvent): - TYPE = Qt.QEvent.Type(1002) - (DEL_CHAR, DEL_WORD, DEL_LINE, DEL_LINE_REVERT) = range(4) - - def __init__ (self, type = DEL_CHAR): - Qt.QEvent.__init__(self, self.TYPE) - self.del_type = type - -class SetPtyEvent (Qt.QEvent): - TYPE = Qt.QEvent.Type(1003) - - def __init__ (self, pty): - Qt.QEvent.__init__(self, self.TYPE) - self.pty = pty - -class BoldFormat (Qt.QTextCharFormat): - - def __init__(self): - Qt.QTextCharFormat.__init__(self) - self.setFontWeight(Qt.QFont.Bold) - -class UnderlineFormat (Qt.QTextCharFormat): - - def __init__(self): - Qt.QTextCharFormat.__init__(self) - self.setFontUnderline(True) - -class ColorFormat (Qt.QTextCharFormat): - - def __init__(self, color): - Qt.QTextCharFormat.__init__(self) - - self.setForeground(Qt.QBrush(Qt.QColor(color))) - -# we only support a subset of the commands -esc_seq = ("\x1b", "[") -reset_seq = "39;49;00" -seq_end = "m" -seq_sep = ";" -backspace = ctrl("H") -backword = ctrl("W") -cr = "\r" - -title_seq = ("\x1b", "]") -title_end = "\x07" - -# the attributes -attr = {} -attr[0] = None # normal -attr[1] = BoldFormat() # bold -attr[4] = UnderlineFormat() # underline -attr[30] = ColorFormat("white") # should be black - but is inverted -attr[31] = ColorFormat("red") -attr[32] = ColorFormat("lime") # lime looks better on black than normal green -attr[33] = ColorFormat("yellow") -attr[34] = ColorFormat("blue") -attr[35] = ColorFormat("magenta") -attr[36] = ColorFormat("cyan") -attr[37] = ColorFormat("white") -attr[39] = None # default - use white too - -class QtConsole (Console, Qt.QTextEdit): - """Self implemented emulation of a terminal emulation. - This only supports a subset of instructions known to normal terminals.""" - - def __init__ (self, parent): - """Constructor. - - @param parent: parent widget - @type parent: Qt.QWidget""" - - Qt.QTextEdit.__init__(self, parent) - - self.pty = None - self.running = False - self.formatQueue = Queue() - self.title = None - self.writeQueue = "" - self.isNotWrapping = False - - self.setContextMenuPolicy(Qt.Qt.ActionsContextMenu) - - # set black bg - self.palette().setColor(Qt.QPalette.Base, Qt.QColor("black")) - - # set highlighting colors ... XXX: for some reasons this does not work ... Qt sucks - self.palette().setColor(Qt.QPalette.Highlight, Qt.QColor("white")) - self.palette().setColor(Qt.QPalette.HighlightedText, Qt.QColor("black")) - - self.setBackgroundRole(Qt.QPalette.Base) - self.setAutoFillBackground(True) - - # set standard char format to "white" - self.stdFormat = self.currentCharFormat() - self.stdFormat.merge(ColorFormat("white")) - self.setCurrentCharFormat(self.stdFormat) - - self.setReadOnly(True) - - def _deletePrev (self, type): - """Deletes the previous character/word.""" - if type == DeleteEvent.DEL_CHAR: # just the prev char - self.textCursor().deletePreviousChar() - - elif type == DeleteEvent.DEL_WORD: - self.textCursor().select(Qt.QTextCursor.WordUnderCursor) - self.textCursor().removeSelectedText() - - elif type == DeleteEvent.DEL_LINE: - self.moveCursor(Qt.QTextCursor.StartOfLine, Qt.QTextCursor.KeepAnchor) - self.textCursor().removeSelectedText() - self.setLineWrapMode(Qt.QTextEdit.NoWrap) - self.isNotWrapping = True - - elif type == DeleteEvent.DEL_LINE_REVERT: - self.setLineWrapMode(Qt.QTextEdit.WidgetWidth) - self.isNotWrapping = False - - def event (self, event): - if event.type() == WriteEvent.TYPE: - self._write(event.get_string()) - event.accept() - return True - - elif event.type() == DeleteEvent.TYPE: - self._deletePrev(event.del_type) - event.accept() - return True - - elif event.type() == SetPtyEvent.TYPE: - self.set_pty(event.pty) - event.accept() - return True - - event.ignore() - return False - - def _write (self, text): - """Writes some text. A text of "\\x1b" signals _write() to reload - the current char format. - - @param text: the text to print - @type text: string""" - - if text == esc_seq[0]: # \x1b -> reload format - self.setCurrentCharFormat(self.get_format()) - else: - if not self.textCursor().atEnd() and not self.isNotWrapping: # move cursor and re-set format - f = self.currentCharFormat() - self.moveCursor(Qt.QTextCursor.End) - self.setCurrentCharFormat(f) - - # insert the text - self.insertPlainText(text) - - # scroll down if needed - if not self.isNotWrapping: self.ensureCursorVisible() - - def write(self, text): - """Convenience function for emitting the writing signal.""" - - def send (text): - Qt.QCoreApplication.postEvent(self, WriteEvent(text)) - - if text is None: - send(self.writeQueue) - self.writeQueue = "" - - elif text == esc_seq[0]: - send(self.writeQueue) - send(text) - self.writeQueue = "" - - elif len(self.writeQueue) == 4: - send(self.writeQueue+text) - self.writeQueue = "" - - else: - self.writeQueue = self.writeQueue + text - - def start_new_thread (self): - """Starts a new thread, which will listen for some input. - @see: QtTerminal.__run()""" - self.run = True - self.current = Thread(target=self.__run, name="QtTerminal Listener") - self.current.setDaemon(True) # close application even if this thread is running - self.current.start() - - def set_pty (self, pty): - if currentThread().getName() != "MainThread": - Qt.QCoreApplication.postEvent(self, SetPtyEvent(pty)) - return - - if not self.running: - self.pty = pty - self.start_new_thread() - self.running = True - - else: # quit current thread - self.run = False - self.clear() - close(self.pty) - - self.pty = pty # set this after clearing to lose no chars :) - self.start_new_thread() - - def __run (self): - """This function is mainly a loop, which looks for some new input at the terminal, - and parses it for text attributes.""" - - got_cr = False - - while self.run: - try: - s = read(self.pty, 1) - except OSError, e: # bug in Python with the subprocess module - if e.errno == errno.EINTR: - continue - raise - - if s == "": break # nothing read -> finish - - if self.isNotWrapping and s == "\n": - self.write(None) - Qt.QCoreApplication.postEvent(self, DeleteEvent(DeleteEvent.DEL_LINE_REVERT)) - - if got_cr: - got_cr = False - if s == "\n": # got \r\n, which is ok - self.write(s) - continue - else: - self.write(None) - Qt.QCoreApplication.postEvent(self, DeleteEvent(DeleteEvent.DEL_LINE)) - - if s == backspace: # BS - self.write(None) - Qt.QCoreApplication.postEvent(self, DeleteEvent()) - - elif s == backword: - self.write(None) - Qt.QCoreApplication.postEvent(self, DeleteEvent(DeleteEvent.DEL_WORD)) - - elif s == cr: # CR -> make the line being deleted - got_cr = True - - elif s == esc_seq[0]: # -> 0x27 - s = read(self.pty, 1) - if s == esc_seq[1]: # -> [ - while True: - _s = read(self.pty, 1) - s += _s - if _s == seq_end: break - self.parse_seq(s[1:-1]) - - elif s == title_seq[1]: # -> ] - while True: - _s = read(self.pty, 1) - s += _s - if _s == title_end: break - - self.parse_title(s[1:-1]) - else: - self.write(esc_seq[0]+s) - - elif not got_cr: - self.write(s) - - self.write(None) - - def parse_seq (self, seq): - """Parses a sequence of bytes. - If a new attribute has been encountered, a new format is created and added - to the internal format queue. - - @param seq: sequence to parse - @type seq: string""" - - global attr # the dict of attributes - - format = self.virgin_format() - - if seq != reset_seq: # resettet -> done - seq = seq.split(seq_sep) - for s in seq: - try: - s = int(s) - except ValueError: - format = self.virgin_format() - break - - try: - if attr[s] is not None: - format.merge(attr[s]) - else: - format = self.virgin_format() - break - except KeyError: # no such attribute - format = self.virgin_format() - break - - self.add_format(format) - self.write(esc_seq[0]) # write \x1b to signal the occurence of a new format - - def parse_title (self, seq): - if not seq.startswith("0;"): - return - - self.title = seq[2:] - - def get_window_title (self): - return self.title - - def add_format (self, format): - """Adds a format to the queue. - We have to take a queue, because the write-signals might occur asynchronus, - so we set a format for the wrong characters. - - @param format: the format to add - @type format: Qt.QTextCharFormat""" - - self.formatQueue.put(format) - - def get_format (self): - """Returns a format from the queue. - We have to take a queue, because the write-signals might occur asynchronus, - so we set a format for the wrong characters. - - @returns: the popped format - @rtype: Qt.QTextCharFormat""" - - return self.formatQueue.get() - - def virgin_format (self): - """The normal standard format. It is necessary to create it as a new one for some - dubious reasons ... only Qt.QGod knows why.""" - return Qt.QTextCharFormat(self.stdFormat) diff --git a/portato/gui/qt/tree.py b/portato/gui/qt/tree.py deleted file mode 100644 index 7c0fa4c..0000000 --- a/portato/gui/qt/tree.py +++ /dev/null @@ -1,155 +0,0 @@ -# -*- coding: utf-8 -*- -# -# File: portato/gui/qt/tree.py -# This file is part of the Portato-Project, a graphical portage-frontend. -# -# Copyright (C) 2007 René 'Necoro' Neumann -# This is free software. You may redistribute copies of it under the terms of -# the GNU General Public License version 2. -# There is NO WARRANTY, to the extent permitted by law. -# -# Written by René 'Necoro' Neumann - -from PyQt4 import Qt -from portato.gui.wrapper import Tree - -from portato.helper import debug -from portato.backend import system # for the tooltips - -class QtTree (Tree): - - def __init__ (self, treeWidget, col = 0): - - self.tree = treeWidget - self.col = col - - self.emergeIt = Qt.QTreeWidgetItem(self.tree, ["Emerge", ""]) - self.unmergeIt = Qt.QTreeWidgetItem(self.tree, ["Unmerge", ""]) - - def build_append_value (self, cpv, oneshot = False, update = False, version = None): - string = "" - - if oneshot: - string += "(oneshot)" - if update: string += "; " - - if update: - string += "(updating" - if version is not None: - string += " from version %s" % version - string += ")" - - return [cpv, string] - - def get_emerge_it (self): - return self.emergeIt - - def get_unmerge_it (self): - return self.unmergeIt - - def is_in_emerge (self, it): - while self.iter_has_parent(it): - it = self.parent_iter(it) - return (it == self.emergeIt) - - def is_in_unmerge (self, it): - return not self.is_in_emerge(it) - - def iter_has_parent (self, it): - return (it.parent() != None) - - def parent_iter (self, it): - return it.parent() - - def first_child_iter (self, it): - return it.child(0) - - def iter_has_children (self, it): - return (it.childCount() > 0) - - def next_iter (self, it): - iter = Qt.QTreeWidgetItemIterator(it) - iter += 1 # next iter ... - - newIt = iter.value() - if not newIt or newIt.parent() != it.parent(): # stop if we left the current parent - return None - else: - return newIt - - def get_value (self, it, column): - return str(it.text(column)) - - def append (self, parent = None, values = None): - if values is None: - values = ["",""] - else: - for i in range(len(values)): - if values[i] is None: - values[i] = "" - - if parent is None: - parent = self.tree - - item = Qt.QTreeWidgetItem(parent, values) - self.make_tooltip(item) - return item - - def remove (self, it): - # a somehow strange approach ;) - go to the parent and delete the child - parent = it.parent() - index = parent.indexOfChild(it) - parent.takeChild(index) - - def get_original (self): - return self.tree - - def get_cpv_column (self): - return self.col - - def make_tooltip (self, item): - tooltip = self.__get_flags(str(item.text(0))) - item.setToolTip(self.col, tooltip) - - def __get_flags(self, cpv): - - try: - pkg = system.new_package(cpv) - except ValueError: # no CPV - return "" - - enabled = [] - disabled = [] - expanded = set() - - pkg_flags = pkg.get_all_use_flags() - if not pkg_flags: # no flags - stop here - return "" - - pkg_flags.sort() - for use in pkg_flags: - exp = pkg.use_expanded(use) - if exp: - expanded.add(exp) - - else: - if pkg.is_use_flag_enabled(use): - enabled.append(use) - else: - disabled.append(use) - - string = "" - - if enabled: - string = "+%s" % ("
+".join(enabled),) - if len(disabled) > 0: - string = string + "
" - - if disabled: - string = string+"- %s" % ("
- ".join(disabled),) - - if expanded: - string = string+"

"+"
".join(expanded) - - return string - diff --git a/portato/gui/qt/uncheckbox.py b/portato/gui/qt/uncheckbox.py deleted file mode 100644 index d87fb06..0000000 --- a/portato/gui/qt/uncheckbox.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- coding: utf-8 -*- -# -# File: portato/gui/qt/uncheckbox.py -# This file is part of the Portato-Project, a graphical portage-frontend. -# -# Copyright (C) 2007 René 'Necoro' Neumann -# This is free software. You may redistribute copies of it under the terms of -# the GNU General Public License version 2. -# There is NO WARRANTY, to the extent permitted by law. -# -# Written by René 'Necoro' Neumann - -from PyQt4.QtGui import QCheckBox -from PyQt4.QtCore import Qt - -class UncheckBox (QCheckBox): - """A checkbox which looks like a normal one, but cannot be checked by the user. - Focusing and hovering are disabled too.""" - - def __init__ (self, *args): - QCheckBox.__init__(self, *args) - self.setFocusPolicy(Qt.NoFocus) - - def mousePressEvent (self, event): - if event.button() == Qt.LeftButton: # ignore leftbutton clicks - pass - else: - QCheckBox.mousePressEvent(self, event) - - def keyPressEvent (self, event): - if event.key() == Qt.Key_Space: # ignore space - pass - else: - QCheckBox.keyPressEvent(self, event) - - def enterEvent (self, event): - # disable hovering - this is set to True somewhere I cannot fix ;) - self.setAttribute(Qt.WA_Hover, False) diff --git a/portato/gui/qt/windows.py b/portato/gui/qt/windows.py deleted file mode 100644 index 539a0f7..0000000 --- a/portato/gui/qt/windows.py +++ /dev/null @@ -1,1125 +0,0 @@ -# -*- coding: utf-8 -*- -# -# File: portato/gui/qt/windows.py -# This file is part of the Portato-Project, a graphical portage-frontend. -# -# Copyright (C) 2007 René 'Necoro' Neumann -# This is free software. You may redistribute copies of it under the terms of -# the GNU General Public License version 2. -# There is NO WARRANTY, to the extent permitted by law. -# -# Written by René 'Necoro' Neumann - -# qt4 -from PyQt4 import Qt, uic -import sip - -# our backend stuff -from portato.helper import * -from portato.constants import CONFIG_LOCATION, VERSION, DATA_DIR, APP_ICON -from portato.backend import flags, system -from portato.backend.exceptions import * - -from portato.gui.gui_helper import Database, Config, EmergeQueue - -# plugins -from portato import plugin - -# own GUI stuff -from terminal import QtConsole -from tree import QtTree -from highlighter import EbuildHighlighter -from dialogs import * -from helper import qCheck, qIsChecked - -import types, logging -from subprocess import Popen - -UI_DIR = DATA_DIR+"ui/" - -class WindowMeta (sip.wrappertype, type): - """This is the metaclass of all Qt-Windows. It automatically - sets the correct base classes, so they do not have to be set - by the programmer. - @attention: The class has to have the same name as the .ui-file.""" - - def __new__ (cls, name, bases, dict): - new_bases = uic.loadUiType(UI_DIR+name+".ui") - dict.update(_bases = new_bases) - dict.update(_qt_base = new_bases[1]) - return super(WindowMeta, cls).__new__(cls, name, new_bases+bases, dict) - - def __init__ (cls, name, bases, dict): - b = dict["_bases"] - del dict["_bases"] - super(WindowMeta, cls).__init__(name, b+bases, dict) - -class Window (object): - """Base class of all Qt-Windows. - Sets up the UI and provides the watch_cursor function.""" - - def __init__(self, parent = None): - self._qt_base.__init__(self, parent) - self.setupUi(self) - self.setWindowIcon(Qt.QIcon(APP_ICON)) - - @staticmethod - def watch_cursor (func): - """This is a decorator for functions being so time consuming, that it is appropriate to show the watch-cursor.""" - def wrapper (*args, **kwargs): - ret = None - - Qt.QApplication.setOverrideCursor(Qt.Qt.WaitCursor) - try: - try: - ret = func(*args, **kwargs) - finally: - Qt.QApplication.restoreOverrideCursor() - except TypeError: - pass # invalid signature called - - return ret - - return wrapper - -class PluginDialog (Window): - __metaclass__ = WindowMeta - - def __init__ (self, parent, plugins): - - Window.__init__(self, parent) - - self.pluginList.setHeaderLabels(["Plugin", "Author"]) - self.plugins = {} - self.changedPlugins = {} - - for p in plugins: - item = Qt.QTreeWidgetItem(self.pluginList, [p.name,p.author]) - item.setCheckState(0, qCheck(p.is_enabled())) - self.plugins.update({self.create_key(p.name,p.author) : p}) # create a list of plugins - - self.pluginList.resizeColumnToContents(0) - - Qt.QObject.connect(self.pluginList, Qt.SIGNAL("itemClicked(QTreeWidgetItem*, int)"), self.cb_plugin_toggled) - - def create_key (self, name, author): - return str(name + "_" + author) - - def cb_plugin_toggled (self, item, col): - if col != 0: - return - - self.changedPlugins.update({ \ - self.create_key(str(item.text(0)), str(item.text(1))) : \ - qIsChecked(item.checkState(0))\ - }) - - @Qt.pyqtSignature("") - def on_buttonBox_accepted(self): - for pluginKey, value in self.changedPlugins.iteritems(): - self.plugins[pluginKey].set_option("disabled", not value) - - self.accept() - -class AboutDialog (Window): - """A window showing the "about"-informations.""" - __metaclass__ = WindowMeta - - def __init__ (self, parent = None): - """Constructor. - - @param parent: the parent window - @type parent: Qt.QWidget""" - - Window.__init__(self, parent) - - self.pix = Qt.QPixmap(APP_ICON) - self.imgLabel.setPixmap(self.pix) # yes we have to use a label for the image ... - - self.label.setText(""" -Portato v.%s

-A Portage-GUI
-
-This software is licensed under the terms of the GPLv2.
-Copyright (C) 2006-2007 René 'Necoro' Neumann <necoro@necoro.net>
-
-Icon created by P4R4D0X""" % VERSION) - - -class SearchDialog (Window): - """A window showing the results of a search process.""" - __metaclass__ = WindowMeta - - def __init__ (self, parent, list, jumpTo): - """Constructor. - - @param parent: parent-window - @type parent: Qt.QWidget - @param list: list of results to show - @type list: string[] - @param jumpTo: function to call if "OK"-Button is hit - @type jumpTo: function(string)""" - - Window.__init__(self, parent) - - self.comboBox.addItems(list) - self.comboBox.setCurrentIndex(0) - self.jumpTo = jumpTo - - Qt.QObject.connect(self, Qt.SIGNAL("accepted()"), self.finish) - - def finish (self): - s = str(self.comboBox.currentText()) - self.done(0) - self.jumpTo(s) - -class UpdateDialog (Window): - """Dialog showing updatable packages.""" - __metaclass__ = WindowMeta - - def __init__ (self, parent, packages, queue, jump_to): - Window.__init__(self, parent) - - self.queue = queue - self.jump = jump_to - - self.packages = system.sort_package_list(packages) - self.items = [] - for p in self.packages: - item = Qt.QListWidgetItem(p.get_cpv(), self.packageList) - item.setCheckState(qCheck(False)) - self.items.append(item) - - self.adjustSize() - - @Qt.pyqtSignature("QListWidgetItem*, QListWidgetItem*") - def on_packageList_currentItemChanged (self, index, prev): - cpv = str(index.text()) - pkg = system.new_package(cpv) - self.jump(pkg.get_cp(), pkg.get_version()) - - @Qt.pyqtSignature("") - def on_installBtn_clicked (self): - world = [x.get_cp() for x in system.find_all_world_packages()] - for item in [x for x in self.items if qIsChecked(x.checkState())]: - cpv = str(item.text()) - cp = "/".join(system.split_cpv(cpv)[:2]) - not_in_world = cp not in world - - try: - try: - self.queue.append(cpv, unmerge = False, oneshot = not_in_world) - except PackageNotFoundException, e: - if unmask_dialog(self, e[0]) == Qt.QMessageBox.Yes : - self.queue.append(cpv, unmerge = False, unmask = True, oneshot = not_in_world) - - except BlockedException, e: - blocked_dialog(self, e[0], e[1]) - - self.accept() - - @Qt.pyqtSignature("") - def on_selectAllBtn_clicked (self): - for item in self.items: - item.setCheckState(qCheck(True)) - -class EbuildDialog (Window): - """Window showing an ebuild.""" - __metaclass__ = WindowMeta - - def __init__ (self, parent, package): - """Constructor. - - @param parent: parent window - @type parent: Qt.QWidget - @param package: The package to show the ebuild of. - @type package: backend.Package""" - - Window.__init__(self, parent) - - self.setWindowTitle(package.get_cpv()) - - self.doc = Qt.QTextDocument() - self.hl = EbuildHighlighter(self.doc) - - try: # read ebuild - f = open(package.get_ebuild_path(), "r") - lines = f.readlines() - f.close() - except IOError,e: - io_ex_dialog(self, e) - return - - self.doc.setPlainText("".join(lines)) - self.ebuildEdit.setDocument(self.doc) - -class LogDialog (Window, logging.Handler): - - __metaclass__ = WindowMeta - - def __init__ (self, parent): - Window.__init__(self, parent) - - self.setAttribute(Qt.Qt.WA_DeleteOnClose, False) - logging.Handler.__init__(self, logging.INFO) - logging.getLogger("portatoLogger").addHandler(self) - - def format (self, record): - - if (record.levelno > logging.INFO): - return "%s: %s" % (record.levelname, record.getMessage()) - else: - return record.getMessage() - - def emit (self, record): - self.logView.insertPlainText(self.format(record)+"\n") - -class PreferenceWindow (Window): - """Window displaying some preferences.""" - - __metaclass__ = WindowMeta - - # all checkboxes in the window - # widget name -> option name - checkboxes = { - "debugCheck" : "debug", - "deepCheck" : "deep", - "newUseCheck" : "newuse", - "maskCheck" : "maskPerVersion", - "useCheck" : "usePerVersion", - "testingCheck" : "testingPerVersion", - "pkgIconsCheck" : ("pkgIcons", "QT"), - "minimizeCheck" : ("minimize", "GUI"), - "systrayCheck" : ("systray", "GUI"), - "titleUpdateCheck" : ("updateTitle", "GUI") - } - - # all edits in the window - # widget name -> option name - edits = { - "maskEdit" : "maskFile", - "testingEdit" : "testingFile", - "useEdit" : "useFile", - "syncCmdEdit" : "syncCmd" - } - - def __init__ (self, parent, cfg): - """Constructor. - - @param parent: parent window - @type parent: Qt.QWidget - @param cfg: the actual configuration - @type cfg: Config""" - - Window.__init__(self, parent) - - self.cfg = cfg - - # set hintLabel background - palette = self.hintLabel.palette() - palette.setColor(Qt.QPalette.Active, Qt.QPalette.Window, Qt.QColor(Qt.Qt.yellow)) - self.hintLabel.setPalette(palette) - - # the checkboxes - for box in self.checkboxes: - val = self.checkboxes[box] - box = self.__getattribute__(box) - if type(val) == types.TupleType: - box.setCheckState(qCheck(self.cfg.get_boolean(val[0], section = val[1]))) - else: - box.setCheckState(qCheck(self.cfg.get_boolean(val))) - - # the edits - for edit in self.edits: - _edit = self.__getattribute__(edit) - _edit.setText(self.cfg.get(self.edits[edit])) - - # the font choser - self.consoleFontFam = self.cfg.get("consolefontfamily", "QT") - self.consoleFontSize = self.cfg.get("consolefontsize", "QT") - self.fontBtn.setText(self.consoleFontFam+" "+self.consoleFontSize) - - Qt.QObject.connect(self, Qt.SIGNAL("accepted()"), self.finish) - - def _save (self): - """Sets all options in the Config-instance.""" - - for box in self.checkboxes: - val = self.checkboxes[box] - box = self.__getattribute__(box) - if type(val) == types.TupleType: - self.cfg.set_boolean(val[0], qIsChecked(box.checkState()), section = val[1]) - else: - self.cfg.set_boolean(val, qIsChecked(box.checkState())) - - for edit in self.edits: - _edit = self.__getattribute__(edit) - self.cfg.set(self.edits[edit], _edit.text()) - - self.cfg.set("consolefontfamily", self.consoleFontFam, "QT") - self.cfg.set("consolefontsize", self.consoleFontSize, "QT") - - def finish (self): - """Saves and writes to config-file.""" - self._save() - try: - self.cfg.write() - except IOError, e: - io_ex_dialog(self, e) - - @Qt.pyqtSignature("") - def on_fontBtn_clicked(self): - font, ok = Qt.QFontDialog.getFont(Qt.QFont(self.consoleFontFam, int(self.consoleFontSize)), self, "Console Font") - if ok: - self.consoleFontFam = font.family() - self.consoleFontSize = str(font.pointSize()) - self.fontBtn.setText(self.consoleFontFam+" "+self.consoleFontSize) - -class PackageDetails: - """The tab showing the details of a package.""" - - def __init__ (self, window): - self.window = window - self.window.pkgTab.setHidden(True) - self.window.tabWidget.removeTab(0) - - self.window.installedCheck.blockSignals(True) - - # combo - Qt.QObject.connect(self.window.versList, Qt.SIGNAL("currentRowChanged(int)"), self.cb_combo_changed) - - # buttons - Qt.QObject.connect(self.window.pkgEmergeBtn, Qt.SIGNAL("clicked()"), self.cb_emerge_clicked) - Qt.QObject.connect(self.window.pkgUnmergeBtn, Qt.SIGNAL("clicked()"), self.cb_unmerge_clicked) - Qt.QObject.connect(self.window.pkgRevertBtn, Qt.SIGNAL("clicked()"), self.cb_revert_clicked) - Qt.QObject.connect(self.window.pkgEbuildBtn, Qt.SIGNAL("clicked()"), self.cb_ebuild_clicked) - - # checkboxes - Qt.QObject.connect(self.window.maskedCheck, Qt.SIGNAL("clicked(bool)"), self.cb_masked_clicked) - Qt.QObject.connect(self.window.testingCheck, Qt.SIGNAL("clicked(bool)"), self.cb_testing_clicked) - - # useflags - Qt.QObject.connect(self.window.useList, Qt.SIGNAL("itemClicked(QTreeWidgetItem*, int)"), self.cb_use_flag_changed) - - def _show_tab (self): - # first update -> show - if self.window.pkgTab.isHidden(): - self.window.tabWidget.insertTab(0, self.window.pkgTab, "Package") - self.window.pkgTab.setHidden(False) - - def update (self, cp, queue = None, version = None, doEmerge = True, instantChange = None): - """Updates the table to show the contents for the package. - - @param cp: the selected package - @type cp: string (cp) - @param queue: emerge-queue (if None the emerge-buttons are disabled) - @type queue: EmergeQueue - @param version: if not None, specifies the version to select - @type version: string - @param doEmerge: if False, the emerge buttons are disabled - @type doEmerge: False - @param instantChange: if not None, the item given is updated immediatly - @type instantChange: Qt.QTreeWidgetItem""" - - self.cp = cp - self.version = version - self.queue = queue - self.doEmerge = doEmerge - self.instantChange = instantChange - - # packages and installed packages - if not self.doEmerge: - self.instPackages = self.packages = system.find_packages("=%s-%s" % (cp, version), masked = True) - else: - self.packages = system.sort_package_list(system.find_packages(cp, masked = True)) - self.instPackages = system.sort_package_list(system.find_installed_packages(cp, masked = True)) - - # comboBox - self.set_vers_list() - - # disable buttons when emerging is not allowed - if not self.queue or not self.doEmerge: - self.window.pkgEmergeBtn.setEnabled(False) - self.window.pkgUnmergeBtn.setEnabled(False) - - self._show_tab() - - self.window.tabWidget.setCurrentIndex(self.window.PKG_PAGE) - - def set_labels (self): - desc = self.actual_package().get_package_settings("DESCRIPTION").replace("&","&") - - if not desc: - desc = "" - else: - desc = "%s" % desc - - name = "%s" % self.actual_package().get_cp() - if self.actual_package().is_overlay(): - self.window.overlayLabel.setText("(%s)" % self.actual_package().get_overlay_path()) - self.window.overlayLabel.show() - else: - self.window.overlayLabel.hide() - - self.window.descLabel.setText(desc) - self.window.nameLabel.setText(name) - self.window.pkgLink.setText('%(link)s' % { "link" : self.actual_package().get_package_settings("HOMEPAGE")}) - - def set_vers_list (self): - """Fills the version combo box with the right items and selects the correct one.""" - - use_icons = self.window.cfg.get_boolean("pkgIcons", section = "QT") - - # installed icon - if use_icons: - yes = Qt.QApplication.style().standardIcon(Qt.QStyle.SP_DialogYesButton) - no = Qt.QApplication.style().standardIcon(Qt.QStyle.SP_DialogNoButton) - - self.window.versList.clear() - - for vers, inst in [(x.get_version(), x.is_installed()) for x in self.packages]: - if use_icons: - if inst: - icon = yes - else: - icon = no - Qt.QListWidgetItem(icon, vers, self.window.versList) - else: # use checkboxes - item = Qt.QListWidgetItem(vers, self.window.versList) - item.setCheckState(qCheck(inst)) - item.setFlags(Qt.Qt.ItemIsSelectable | Qt.Qt.ItemIsEnabled) - - try: - best_version = "" - if self.version: - best_version = self.version - else: - best_version = system.find_best_match(self.packages[0].get_cp(), (self.instPackages != [])).get_version() - - for i in range(len(self.packages)): - if self.packages[i].get_version() == best_version: - self.window.versList.setCurrentRow(i) - except AttributeError: - self.window.versList.setCurrentRow(0) - - def build_use_list (self): - """Builds the list of use flags.""" - self.window.useList.clear() - self.window.useList.setHeaderLabels(["Enabled","Flag","Description"]) - - pkg = self.actual_package() - pkg_flags = pkg.get_all_use_flags() - pkg_flags.sort() - - actual_exp = None - actual_exp_it = self.window.useList - - for use in pkg_flags: - exp = pkg.use_expanded(use, suggest = actual_exp) - if exp is not None: - if exp != actual_exp: - actual_exp_it = Qt.QTreeWidgetItem(self.window.useList, ["", exp, ""]) - actual_exp = exp - else: - actual_exp_it = self.window.useList - actual_exp = None - - item = Qt.QTreeWidgetItem(actual_exp_it, ["", use, system.get_use_desc(use, self.cp)]) - item.setCheckState(0, qCheck(pkg.is_use_flag_enabled(use))) - - def _update_keywords (self, emerge, update = False): - if emerge: - try: - try: - self.queue.append(self.actual_package().get_cpv(), unmerge = False, update = update) - except PackageNotFoundException, e: - if unmask_dialog(self.window, e[0]) == Qt.QMessageBox.Yes : - self.queue.append(self.actual_package().get_cpv(), unmerge = False, unmask = True, update = update) - except BlockedException, e: - blocked_dialog(self.window, e[0], e[1]) - else: - try: - self.queue.append(self.actual_package().get_cpv(), unmerge = True) - except PackageNotFoundException, e: - error("Package could not be found: %s", e[0]) - - - def actual_package (self): - """Returns the actual selected package. - - @returns: the actual selected package - @rtype: backend.Package""" - - return self.packages[self.window.versList.currentIndex().row()] - - def cb_ebuild_clicked (self): - hook = plugin.hook("open_ebuild", package = self.actual_package(), parent = self.window) - hook(EbuildDialog)(self.window, self.actual_package()).exec_() - - def cb_emerge_clicked (self): - """Callback for pressed emerge-button. Adds the package to the EmergeQueue.""" - if not am_i_root(): - not_root_dialog(self.window) - else: - self._update_keywords(True) - self.window.tabWidget.setCurrentIndex(self.window.QUEUE_PAGE) - return True - - def cb_unmerge_clicked (self): - """Callback for pressed unmerge-button. Adds the package to the EmergeQueue.""" - if not am_i_root(): - not_root_dialog(self.window) - else: - self._update_keywords(False) - self.window.tabWidget.setCurrentIndex(self.window.QUEUE_PAGE) - return True - - def cb_revert_clicked (self): - """Callback for pressed revert-button.""" - self.actual_package().remove_new_use_flags() - self.actual_package().remove_new_masked() - self.actual_package().remove_new_testing() - self.cb_combo_changed() - if self.instantChange: - self._update_keywords(True, update = True) - return True - - def cb_testing_clicked (self, status): - """Callback for toggled testing-checkbox.""" - button = self.window.testingCheck - - if self.actual_package().is_testing(use_keywords = False) == status: - return - - if not self.actual_package().is_testing(use_keywords = True): - self.actual_package().set_testing(False) - button.setText("Testing") - button.setCheckState(qCheck(True)) - else: - self.actual_package().set_testing(True) - if self.actual_package().is_testing(use_keywords=False): - button.setText("(Testing)") - button.setCheckState(qCheck(True)) - - if self.instantChange: - self._update_keywords(True, update = True) - - def cb_masked_clicked (self, status): - """Callback for toggled masking-checkbox.""" - pkg = self.actual_package() - button = self.window.maskedCheck - - if pkg.is_masked(use_changed = False) == status and not pkg.is_locally_masked(): - return - - if pkg.is_locally_masked() and status: - return False - - if not pkg.is_masked(use_changed = True): - pkg.set_masked(True) - if pkg.is_locally_masked(): - button.setText("Masked by User") - else: - button.setText("Masked") - - button.setCheckState(qCheck(True)) - - else: - locally = pkg.is_locally_masked() - pkg.set_masked(False) - - if pkg.is_masked(use_changed=False) and not locally: - button.setText("(Masked)") - button.setCheckState(qCheck(True)) - else: - button.setText("Masked") - - if self.instantChange: - self._update_keywords(True, update = True) - - return True - - def cb_use_flag_changed (self, item, col): - if col != 0: return - - flag = str(item.text(1)) - pkg = self.actual_package() - - if flag in pkg.get_global_settings("USE_EXPAND").split(" "): # ignore expanded flags - return - - checked = qIsChecked(item.checkState(0)) - - prefix = "" - if not checked: prefix = "-" - - pkg.set_use_flag(prefix+flag) - if self.instantChange: - self._update_keywords(True, update = True) - self.window.queueTree.make_tooltip(self.instantChange) - - def cb_combo_changed (self): - """Callback for the changed ComboBox. - It then rebuilds the useList and the checkboxes.""" - - # - # ATTENTION: BIG'n'DIRTY :) - # - - # labels - self.set_labels() - - # build new - self.build_use_list() - pkg = self.actual_package() - - shown = Qt.QSizePolicy(Qt.QSizePolicy.MinimumExpanding, Qt.QSizePolicy.Fixed) - hidden = Qt.QSizePolicy(Qt.QSizePolicy.Ignored, Qt.QSizePolicy.Fixed) - - # - # rebuild the buttons and checkboxes in all the different manners which are possible - # - if (not pkg.is_in_system()) or pkg.is_missing_keyword(): - if not pkg.is_in_system(): - self.window.missingLabel.setSizePolicy(hidden) - self.window.notInSysLabel.setSizePolicy(shown) - else: # missing keyword - self.window.missingLabel.setSizePolicy(shown) - self.window.notInSysLabel.setSizePolicy(hidden) - - self.window.installedCheck.setSizePolicy(hidden) - self.window.maskedCheck.setSizePolicy(hidden) - self.window.testingCheck.setSizePolicy(hidden) - self.window.pkgEmergeBtn.setEnabled(False) - else: # normal package - self.window.missingLabel.setSizePolicy(hidden) - self.window.notInSysLabel.setSizePolicy(hidden) - self.window.installedCheck.setSizePolicy(shown) - self.window.maskedCheck.setSizePolicy(shown) - self.window.testingCheck.setSizePolicy(shown) - if self.doEmerge: - self.window.pkgEmergeBtn.setEnabled(True) - self.window.installedCheck.setCheckState(qCheck(pkg.is_installed())) - - masking_reason = pkg.get_masking_reason() or "" # set to "" if the reason is None - self.window.maskedCheck.setToolTip(masking_reason) - - if pkg.is_masked(use_changed = False) and not pkg.is_masked(use_changed = True): - self.window.maskedCheck.setText("(Masked)") - else: - self.window.maskedCheck.setText("Masked") - - if pkg.is_locally_masked(): - self.window.maskedCheck.setText("Masked by User") - self.window.maskedCheck.setCheckState(qCheck(True)) - else: - self.window.maskedCheck.setCheckState(qCheck(pkg.is_masked(use_changed = False))) - - if pkg.is_testing(use_keywords = False) and not pkg.is_testing(use_keywords = True): - self.window.testingCheck.setText("(Testing)") - else: - self.window.testingCheck.setText("Testing") - - self.window.testingCheck.setCheckState(qCheck(pkg.is_testing(use_keywords = False))) - - if self.doEmerge: - # set emerge-button-label - if not self.actual_package().is_installed(): - self.window.pkgEmergeBtn.setText("E&merge") - self.window.pkgUnmergeBtn.setEnabled(False) - else: - self.window.pkgEmergeBtn.setText("Re&merge") - self.window.pkgUnmergeBtn.setEnabled(True) - -class MainWindow (Window): - """The application's main window.""" - - __metaclass__ = WindowMeta - - # NOTEBOOK PAGE CONSTANTS - PKG_PAGE = 0 - QUEUE_PAGE = 1 - CONSOLE_PAGE = 2 - - def __init__ (self): - Window.__init__(self) - - self.main_title = "Portato (%s)" % VERSION - self.setWindowTitle(self.main_title) - self.statusbar.showMessage("Portato - A Portage GUI") - - self.doUpdate = False - self.pkgDetails = PackageDetails(self) - - # set the logger as early as possible - self.logDialog = LogDialog(self) - - # package db - self.db = Database() - self.db.populate() - - # config - try: - self.cfg = Config(CONFIG_LOCATION) - except IOError, e: - io_ex_dialog(self, e) - raise - - self.cfg.modify_external_configs() - - # set plugins and plugin-menu - plugin.load_plugins("qt") - menus = plugin.get_plugin_queue().get_plugin_menus() - if menus: - self.pluginMenu = Qt.QMenu("&Plugins", self) - self.menubar.insertMenu(self.helpMenu.menuAction(), self.pluginMenu) - for m in menus: - action = self.pluginMenu.addAction(m.label.replace("_","&")) - Qt.QObject.connect(action, Qt.SIGNAL("triggered()"), m.call) - - # the two lists - self.sortPkgListByName = True - self.pkgList.addAction(self.pkgListSortAction) - self.build_cat_list() - Qt.QObject.connect(self.selCatListModel, Qt.SIGNAL("currentChanged(QModelIndex, QModelIndex)"), self.cb_cat_list_selected) - Qt.QObject.connect(self.pkgList, Qt.SIGNAL("currentItemChanged(QListWidgetItem*, QListWidgetItem*)"), self.cb_pkg_list_selected) - - # build console - self.console = QtConsole(self.consoleTab) - self.console.setCurrentFont(Qt.QFont(self.cfg.get("consolefontfamily", "QT"), int(self.cfg.get("consolefontsize", "QT")))) - self.consoleLayout = Qt.QVBoxLayout() - self.consoleLayout.setMargin(0) - self.consoleLayout.setSpacing(0) - self.consoleTab.setLayout(self.consoleLayout) - self.consoleLayout.addWidget(self.console) - - self.console.addAction(self.killAction) - self.console.addAction(self.pauseAction) - - Qt.QObject.connect(self, Qt.SIGNAL("doTitleUpdate"), self._title_update) - - # build queueList - self.queueList.addAction(self.oneshotAction) - self.queueList.setHeaderLabels(["Package", "Additional infos"]) - self.queueTree = QtTree(self.queueList) - Qt.QObject.connect(self.queueList.model(), Qt.SIGNAL("rowsInserted (const QModelIndex&, int, int)"), self.cb_queue_list_items_added) - Qt.QObject.connect(self.queueList, Qt.SIGNAL("expanded (const QModelIndex&)"), self.cb_queue_list_items_added) - Qt.QObject.connect(self.queueList, Qt.SIGNAL("itemActivated (QTreeWidgetItem*, int)"), self.cb_queue_list_item_selected) - Qt.QObject.connect(self.queueList, Qt.SIGNAL("itemDoubleClicked (QTreeWidgetItem*, int)"), self.cb_queue_list_item_selected) - - # build systray - self.build_systray() - - # set emerge queue - self.queue = EmergeQueue(console = self.console, tree = self.queueTree, db = self.db, title_update = self.title_update) - - self.showMaximized() - - def title_update (self, title): - self.emit(Qt.SIGNAL("doTitleUpdate"), title) - - def _title_update (self, title): - - def window_update (title): - if title is None or not self.cfg.get_boolean("updateTitle", "GUI"): - self.setWindowTitle(self.main_title) - else: - title = title.strip() - if title[0] == '*': - self.setWindowTitle(self.main_title) - else: - space_idx = title.rfind(" ") - if space_idx != -1: - title = title[:space_idx] - - self.setWindowTitle(("Portato >>> %s" % title)) - - window_update(title) - if title is None: - if self.systray: self.systray.setToolTip("") - title = "Console" - else: - if self.systray: self.systray.setToolTip(title) - title = ("Console (%s)" % title) - - self.tabWidget.setTabText(self.CONSOLE_PAGE, title) - - def jump_to (self, cp, version = None): - """Is called when we want to jump to a specific package.""" - self.pkgDetails.update(cp, self.queue, version = version) - - def fill_pkg_list (self, cat): - use_icons = self.cfg.get_boolean("pkgIcons", section = "QT") - - # installed icon - if use_icons: - yes = Qt.QApplication.style().standardIcon(Qt.QStyle.SP_DialogYesButton) - no = Qt.QApplication.style().standardIcon(Qt.QStyle.SP_DialogNoButton) - - self.pkgList.clear() - - for name, inst in self.db.get_cat(cat, self.sortPkgListByName): - if use_icons: - if inst: - icon = yes - else: - icon = no - Qt.QListWidgetItem(icon, name, self.pkgList) - else: # use checkboxes - item = Qt.QListWidgetItem(name, self.pkgList) - item.setCheckState(qCheck(inst)) - item.setFlags(Qt.Qt.ItemIsSelectable | Qt.Qt.ItemIsEnabled) - - def build_cat_list (self): - self.catListModel = Qt.QStringListModel(system.list_categories()) - self.catListModel.sort(0) - self.selCatListModel = Qt.QItemSelectionModel(self.catListModel) - self.catList.setModel(self.catListModel) - self.catList.setSelectionModel(self.selCatListModel) - - def build_systray (self): - if self.cfg.get_boolean("systray", "GUI"): - self.systray = Qt.QSystemTrayIcon(Qt.QIcon(APP_ICON), self) # use this until Qt supports proper SVG images in the systray - self.trayIconMenu = Qt.QMenu(self) - self.trayIconMenu.addAction(self.quitAction) - self.systray.setContextMenu(self.trayIconMenu) - self.systray.show() - - Qt.QObject.connect(self.systray, Qt.SIGNAL("activated(QSystemTrayIcon::ActivationReason)"), self.cb_systray_activated) - else: - self.systray = None - - @Qt.pyqtSignature("") - def on_logAction_triggered (self): - self.logDialog.show() - - @Qt.pyqtSignature("") - def on_aboutAction_triggered (self): - AboutDialog(self).exec_() - - @Qt.pyqtSignature("") - def on_pluginAction_triggered (self): - queue = plugin.get_plugin_queue().get_plugins() - if queue is None: - queue = [] - - PluginDialog(self, queue).exec_() - - @Qt.pyqtSignature("") - def on_prefAction_triggered (self): - PreferenceWindow(self, self.cfg).show() - - # set font as it might has changed - self.console.setCurrentFont(Qt.QFont(self.cfg.get("consolefontfamily", "QT"), int(self.cfg.get("consolefontsize", "QT")))) - - @Window.watch_cursor - @Qt.pyqtSignature("") - def on_reloadAction_triggered (self): - """Reloads the portage settings and the database.""" - system.reload_settings() - del self.db - self.db = Database() - self.db.populate() - - @Qt.pyqtSignature("bool") - def on_pauseAction_triggered (self, checked): - if checked: - self.queue.stop_emerge() - else: - self.queue.continue_emerge() - - @Qt.pyqtSignature("") - def on_killAction_triggered (self): - self.queue.kill_emerge() - - @Qt.pyqtSignature("") - def cb_saveAction_triggered (self): - if not am_i_root(): - not_root_dialog(self) - else: - flags.write_use_flags() - flags.write_testing() - flags.write_masked() - - @Qt.pyqtSignature("") - def on_syncAction_triggered (self): - if not am_i_root(): - not_root_dialog(self) - else: - self.tabWidget.setCurrentIndex(self.CONSOLE_PAGE) - cmd = self.cfg.get("syncCmd") - - if cmd != "emerge --sync": - cmd = cmd.split() - self.queue.sync(cmd) - else: - self.queue.sync() - - @Qt.pyqtSignature("") - def on_updateListAction_triggered (self): - Window.watch_cursor(UpdateDialog)(self, system.get_updated_packages(), self.queue, self.jump_to).exec_() - - @Qt.pyqtSignature("") - def on_oneshotAction_triggered (self): - current = self.queueList.currentItem() - - if self.queueTree.is_in_emerge(current) and self.queueTree.iter_has_parent(current): - pkg = self.queueTree.get_value(current, self.queueTree.get_cpv_column()) - - if not self.cfg.get_local(pkg, "oneshot"): - set = True - else: - set = False - - self.cfg.set_local(pkg, "oneshot", set) - self.queue.append(pkg, update = True, oneshot = set, forceUpdate = True) - - @Qt.pyqtSignature("bool") - def on_pkgListSortAction_triggered (self, checked): - self.sortPkgListByName = checked - self.fill_pkg_list(self.selCatName) - - @Qt.pyqtSignature("") - def on_searchBtn_clicked (self): - """Do a search.""" - text = str(self.searchEdit.text()) - - if text != "": - packages = Window.watch_cursor(system.find_all_packages)\ - (text, withVersion = False) # show watch cursor during this process - - if packages == []: - nothing_found_dialog(self) - else: - if len(packages) == 1: - self.jump_to(packages[0]) - else: - SearchDialog(self, packages, self.jump_to).exec_() - - @Qt.pyqtSignature("") - def on_removeBtn_clicked (self): - """Removes a selected item in the (un)emerge-queue if possible.""" - selected = self.queueList.currentItem() - - if selected: - if not selected.parent(): # top-level - if self.queueTree.iter_has_children(selected): # and has children which can be removed :) - if remove_queue_dialog(self) == Qt.QMessageBox.Yes : - self.queue.remove_children(selected) - self.doUpdate = False - - elif selected.parent().parent(): # this is in the 3rd level => dependency - remove_deps_dialog(self) - else: - self.queue.remove_with_children(selected) - self.doUpdate = False - - @Qt.pyqtSignature("") - def on_emergeBtn_clicked (self): - """Do emerge.""" - - self.tabWidget.setCurrentIndex(self.CONSOLE_PAGE) - - if len(flags.newUseFlags) > 0: - changed_flags_dialog(self, "use flags") - flags.write_use_flags() - - if len(flags.new_masked)>0 or len(flags.new_unmasked)>0 or len(flags.newTesting)>0: - debug("new masked: %s",flags.new_masked) - debug("new unmasked: %s", flags.new_unmasked) - debug("new testing: %s", flags.newTesting) - changed_flags_dialog(self, "masking keywords") - flags.write_masked() - flags.write_testing() - system.reload_settings() - - if not self.doUpdate: - self.queue.emerge(force=True) - else: - self.queue.update_world(force=True, newuse = self.cfg.get_boolean("newuse"), deep = self.cfg.get_boolean("deep")) - self.doUpdate = False - - @Qt.pyqtSignature("") - def on_unmergeBtn_clicked (self): - """Do unmerge.""" - - self.tabWidget.setCurrentIndex(self.CONSOLE_PAGE) - self.queue.unmerge(force = True) - - @Window.watch_cursor - @Qt.pyqtSignature("") - def on_updateBtn_clicked (self): - if not am_i_root(): - not_root_dialog(self) - - else: - updating = system.update_world(newuse = self.cfg.get_boolean("newuse"), deep = self.cfg.get_boolean("deep")) - - debug("updating list: %s --> length: %s", [(x.get_cpv(), y.get_cpv()) for x,y in updating], len(updating)) - try: - try: - for pkg, old_pkg in updating: - self.queue.append(pkg.get_cpv(), unmask = False) - except PackageNotFoundException, e: - if unmask_dialog(self, e[0]) == Qt.QMessageBox.Yes: - for pkg, old_pkg in updating: - self.queue.append(pkg.get_cpv(), unmask = True) - - except BlockedException, e: - blocked_dialog(self, e[0], e[1]) - self.queue.remove_children(self.queue.emergeIt) - - if len(updating): self.doUpdate = True - - def cb_queue_list_item_selected (self, item, col): - if col == -1: return # nothing selected - - if self.queueTree.iter_has_parent(item): - package = self.queueTree.get_value(item, self.queueTree.get_cpv_column()) - cat, name, vers, rev = system.split_cpv(package) - if rev != "r0": vers = vers+"-"+rev - self.pkgDetails.update(cat+"/"+name, queue = self.queue, version = vers, instantChange = item, doEmerge = False) - - def cb_queue_list_items_added (self, *args): - self.queueList.resizeColumnToContents(0) - - def cb_cat_list_selected (self, index, prev): - self.selCatName = str(index.data().toString()) - self.fill_pkg_list(self.selCatName) - - def cb_pkg_list_selected (self, index, prev): - if not index is None: - self.pkgDetails.update(self.selCatName+"/"+str(index.text()), self.queue) - - def cb_systray_activated (self, reason): - if reason != Qt.QSystemTrayIcon.Context: # do not react on context menu calls - if self.windowState() & Qt.Qt.WindowMinimized: # window is minimized - self.show() - self.showNormal() - else: # window is not minimized - self.setWindowState(self.windowState() | Qt.Qt.WindowMinimized) - - def closeEvent (self, event): - if not self.queue.is_empty(): - ret = queue_not_empty_dialog(self) - if ret == Qt.QMessageBox.Cancel: - event.ignore() - return - else: - self.queue.kill_emerge() - - if self.systray and self.systray.isVisible(): - self.systray.hide() - - self.pkgDetails._show_tab() # workaround for segfault with PyQt-4.2 - Qt.QMainWindow.closeEvent(self, event) - - def changeEvent (self, event): - if event.type() == Qt.QEvent.WindowStateChange: - if self.systray and self.cfg.get_boolean("minimize", "GUI"): - if self.windowState() & Qt.Qt.WindowMinimized: # going to be minimized - self.hide() - return - - Qt.QMainWindow.changeEvent(self,event) - diff --git a/portato/gui/templates/ui/AboutDialog.ui b/portato/gui/templates/ui/AboutDialog.ui deleted file mode 100644 index ce89b44..0000000 --- a/portato/gui/templates/ui/AboutDialog.ui +++ /dev/null @@ -1,111 +0,0 @@ - - AboutDialog - - - Qt::ApplicationModal - - - - 0 - 0 - 400 - 300 - - - - About Portato - - - - 9 - - - 6 - - - - - - - - Qt::AlignCenter - - - - - - - TextLabel - - - Qt::AlignCenter - - - true - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Ok - - - true - - - - - - - - - buttonBox - accepted() - AboutDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - AboutDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/portato/gui/templates/ui/EbuildDialog.ui b/portato/gui/templates/ui/EbuildDialog.ui deleted file mode 100644 index 831a93b..0000000 --- a/portato/gui/templates/ui/EbuildDialog.ui +++ /dev/null @@ -1,88 +0,0 @@ - - EbuildDialog - - - - 0 - 0 - 481 - 603 - - - - Dialog - - - - 9 - - - 6 - - - - - false - - - true - - - false - - - 0 - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Ok - - - true - - - - - - - - - buttonBox - accepted() - EbuildDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - EbuildDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/portato/gui/templates/ui/LogDialog.ui b/portato/gui/templates/ui/LogDialog.ui deleted file mode 100644 index 3415893..0000000 --- a/portato/gui/templates/ui/LogDialog.ui +++ /dev/null @@ -1,88 +0,0 @@ - - LogDialog - - - - 0 - 0 - 481 - 603 - - - - Log Viewer - - - - 9 - - - 6 - - - - - false - - - true - - - false - - - 0 - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Ok - - - true - - - - - - - - - buttonBox - accepted() - LogDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - LogDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/portato/gui/templates/ui/MainWindow.ui b/portato/gui/templates/ui/MainWindow.ui deleted file mode 100644 index 40315cd..0000000 --- a/portato/gui/templates/ui/MainWindow.ui +++ /dev/null @@ -1,720 +0,0 @@ - - MainWindow - - - - 0 - 0 - 532 - 695 - - - - Portato - - - - - - - - 9 - - - 6 - - - - - 0 - - - 6 - - - - - - - - &Search - - - - - - - - - Qt::Vertical - - - - - 0 - - - 6 - - - - - false - - - QFrame::Sunken - - - QAbstractItemView::NoEditTriggers - - - - - - - Qt::ActionsContextMenu - - - QAbstractItemView::NoEditTriggers - - - false - - - false - - - - - - - - 0 - - - - Package - - - - 9 - - - 6 - - - - - TextLabel - - - Qt::AlignCenter - - - - - - - TextLabel - - - Qt::AlignCenter - - - - - - - TextLabel - - - Qt::AlignCenter - - - true - - - - - - - TextLabel - - - Qt::RichText - - - Qt::AlignCenter - - - true - - - Qt::TextBrowserInteraction - - - - - - - 0 - - - 6 - - - - - - 13 - 5 - 0 - 0 - - - - <html><head><meta name="qrichtext" content="1" /><style type="text/css"> - p, li { white-space: pre-wrap; } - </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> - <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; color:#ff0000;">MISSING KEYWORD</span></p></body></html> - - - Qt::AlignCenter - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 13 - 5 - 0 - 0 - - - - <b>Installed, but not in portage anymore</b> - - - Qt::AlignCenter - - - - - - - - 3 - 5 - 0 - 0 - - - - Installed - - - - - - - - 3 - 0 - 0 - 0 - - - - Masked - - - - - - - true - - - - 3 - 0 - 0 - 0 - - - - Testing - - - - - - - - - 0 - - - 6 - - - - - - 0 - 7 - 0 - 0 - - - - - 150 - 16777215 - - - - Qt::ScrollBarAlwaysOff - - - - - - - - 3 - 7 - 0 - 0 - - - - Qt::ScrollBarAlwaysOn - - - QAbstractItemView::NoEditTriggers - - - Qt::ElideNone - - - true - - - false - - - false - - - 3 - - - - 1 - - - - - 1 - - - - - 2 - - - - - - - - - - 0 - - - 6 - - - - - &Emerge - - - - - - - &Unmerge - - - - - - - Re&vert - - - - - - - E&build - - - - - - - - - - Queue - - - - 0 - - - 6 - - - - - Qt::ActionsContextMenu - - - QAbstractItemView::NoEditTriggers - - - 2 - - - - 1 - - - - - 1 - - - - - - - - 2 - - - 6 - - - - - - 1 - 0 - 0 - 0 - - - - E&merge - - - - - - - &Unmerge - - - - - - - Update &World - - - - - - - &Remove - - - - - - - - - - Console - - - - - - - - - - - 0 - 0 - 532 - 31 - - - - - &File - - - - - - - - - &Emerge - - - - - - - - - - - - - - - &? - - - - - - - - - - - - true - - - - - - - - &Quit - - - QAction::QuitRole - - - - - &About - - - QAction::AboutRole - - - - - &Emerge - - - - - &Unmerge - - - - - Update &World - - - - - &Preferences - - - QAction::PreferencesRole - - - - - S&ync - - - - - Save &Flage - - - - - Ki&ll Emerge - - - - - &Reload Portage - - - - - &Oneshot - - - - - true - - - true - - - Sort by Name - - - - - Show &new packages - - - - - &Plugins - - - - - true - - - Emerge &paused - - - - - Show &Logs - - - - - - UncheckBox - QCheckBox -
portato/gui/qt/uncheckbox.h
-
-
- - - - quitAction - triggered() - MainWindow - close() - - - -1 - -1 - - - 361 - 299 - - - - - searchEdit - returnPressed() - searchBtn - click() - - - 287 - 49 - - - 400 - 55 - - - - - emergeAction - triggered() - emergeBtn - click() - - - -1 - -1 - - - 66 - 642 - - - - - unmergeAction - triggered() - unmergeBtn - click() - - - -1 - -1 - - - 177 - 642 - - - - - updateAction - triggered() - updateBtn - click() - - - -1 - -1 - - - 288 - 642 - - - - -
diff --git a/portato/gui/templates/ui/PluginDialog.ui b/portato/gui/templates/ui/PluginDialog.ui deleted file mode 100644 index 50e0453..0000000 --- a/portato/gui/templates/ui/PluginDialog.ui +++ /dev/null @@ -1,94 +0,0 @@ - - PluginDialog - - - Qt::ApplicationModal - - - - 0 - 0 - 400 - 300 - - - - Plugins - - - - 9 - - - 6 - - - - - Qt::ScrollBarAlwaysOff - - - Qt::ScrollBarAlwaysOff - - - QAbstractItemView::NoEditTriggers - - - true - - - QAbstractItemView::ScrollPerPixel - - - false - - - 2 - - - - 1 - - - - - 1 - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok - - - true - - - - - - - - - buttonBox - rejected() - PluginDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/portato/gui/templates/ui/PreferenceWindow.ui b/portato/gui/templates/ui/PreferenceWindow.ui deleted file mode 100644 index 38c6564..0000000 --- a/portato/gui/templates/ui/PreferenceWindow.ui +++ /dev/null @@ -1,379 +0,0 @@ - - PreferencesWindow - - - - 0 - 0 - 563 - 699 - - - - Preferences - - - - 9 - - - 6 - - - - - 1 - - - - General - - - - 9 - - - 6 - - - - - Debug - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - Portage - - - - 9 - - - 6 - - - - - Sync Options - - - - 9 - - - 6 - - - - - Sync command: - - - - - - - - - - - - - Update World Options - - - - 9 - - - 0 - - - - - --deep - - - - - - - --newuse - - - - - - - - - - Use Flag and Keyword Options - - - - 9 - - - 6 - - - - - <u><i>Masking Keywords</u></i> - - - - - - - <i><u>Use Flags</u></i> - - - - - - - portato - - - - - - - Add only exact version to package.keywords - - - - - - - File name to use, if package.keywords is a directory - - - - - - - File name to use if package.mask/.unmask is a directory - - - - - - - Add only exact version to package.use - - - - - - - portato - - - - - - - <i><u>Testing Keywords</u></i> - - - - - - - File name to use, if package.use is a directory - - - - - - - Add only exact version to package.mask/.unmask - - - - - - - portato - - - - - - - true - - - QFrame::StyledPanel - - - QFrame::Raised - - - <html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans Serif'; font-size:11pt; font-weight:400; font-style:normal; text-decoration:none;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" text-decoration: underline;">You may use the following placeholders:</span> </p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">$(cat)</span>: category</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">$(pkg)</span>: package name</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">$(cat-1)/$(cat-2)</span>: first/second part of the category</p></body></html> - - - - - - - - - - - Visual - - - - 9 - - - 6 - - - - - Use icons in package list - - - - - - - Show emerge progress in title - similar to the console tab - - - - - - - Show systray icon - - - - - - - Minimize to systray (only if systray icon is activated) - - - - - - - 0 - - - 6 - - - - - Console Font: - - - - - - - PushButton - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok - - - true - - - - - - - - - buttonBox - accepted() - PreferencesWindow - accept() - - - 227 - 676 - - - 157 - 274 - - - - - buttonBox - rejected() - PreferencesWindow - reject() - - - 295 - 682 - - - 286 - 274 - - - - - diff --git a/portato/gui/templates/ui/SearchDialog.ui b/portato/gui/templates/ui/SearchDialog.ui deleted file mode 100644 index 02c62ff..0000000 --- a/portato/gui/templates/ui/SearchDialog.ui +++ /dev/null @@ -1,78 +0,0 @@ - - SearchDialog - - - Qt::ApplicationModal - - - - 0 - 0 - 246 - 97 - - - - Search... - - - - 9 - - - 6 - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok - - - true - - - - - - - - - buttonBox - accepted() - SearchDialog - accept() - - - 164 - 112 - - - 157 - 70 - - - - - buttonBox - rejected() - SearchDialog - reject() - - - 164 - 112 - - - 173 - 70 - - - - - diff --git a/portato/gui/templates/ui/UpdateDialog.ui b/portato/gui/templates/ui/UpdateDialog.ui deleted file mode 100644 index a602dae..0000000 --- a/portato/gui/templates/ui/UpdateDialog.ui +++ /dev/null @@ -1,108 +0,0 @@ - - UpdateDialog - - - - 0 - 0 - 400 - 372 - - - - Update List - - - - 9 - - - 6 - - - - - true - - - QAbstractItemView::ScrollPerPixel - - - - - - - 0 - - - 6 - - - - - - 5 - 0 - 0 - 0 - - - - Close - - - - - - - - 5 - 0 - 0 - 0 - - - - Select All - - - - - - - - 5 - 0 - 0 - 0 - - - - Install Selected - - - - - - - - - - - closeBtn - clicked() - UpdateDialog - reject() - - - 117 - 352 - - - 140 - 368 - - - - - -- cgit v1.2.3-54-g00ecf