From 57c377c2ea2d8f2b3c265a2f54925fd661ac3164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Tue, 18 Mar 2008 20:02:53 +0100 Subject: Removed gtk subdir --- portato/gui/__init__.py | 23 +- portato/gui/dialogs.py | 95 ++ portato/gui/exception_handling.py | 124 +++ portato/gui/gtk/__init__.py | 33 - portato/gui/gtk/dialogs.py | 96 -- portato/gui/gtk/exception_handling.py | 125 --- portato/gui/gtk/session.py | 33 - portato/gui/gtk/splash.py | 51 - portato/gui/gtk/views.py | 147 --- portato/gui/gtk/windows/__init__.py | 15 - portato/gui/gtk/windows/about.py | 34 - portato/gui/gtk/windows/basic.py | 108 --- portato/gui/gtk/windows/main.py | 1661 --------------------------------- portato/gui/gtk/windows/plugin.py | 85 -- portato/gui/gtk/windows/preference.py | 163 ---- portato/gui/gtk/windows/search.py | 75 -- portato/gui/gtk/windows/update.py | 117 --- portato/gui/gtk/wrapper.py | 333 ------- portato/gui/queue.py | 2 +- portato/gui/session.py | 33 + portato/gui/updater.py | 3 +- portato/gui/views.py | 146 +++ portato/gui/windows/__init__.py | 11 + portato/gui/windows/about.py | 34 + portato/gui/windows/basic.py | 108 +++ portato/gui/windows/main.py | 1661 +++++++++++++++++++++++++++++++++ portato/gui/windows/plugin.py | 85 ++ portato/gui/windows/preference.py | 163 ++++ portato/gui/windows/search.py | 75 ++ portato/gui/windows/splash.py | 51 + portato/gui/windows/update.py | 117 +++ portato/gui/wrapper.py | 331 +++++++ 32 files changed, 3058 insertions(+), 3080 deletions(-) create mode 100644 portato/gui/dialogs.py create mode 100644 portato/gui/exception_handling.py delete mode 100644 portato/gui/gtk/__init__.py delete mode 100644 portato/gui/gtk/dialogs.py delete mode 100644 portato/gui/gtk/exception_handling.py delete mode 100644 portato/gui/gtk/session.py delete mode 100644 portato/gui/gtk/splash.py delete mode 100644 portato/gui/gtk/views.py delete mode 100644 portato/gui/gtk/windows/__init__.py delete mode 100644 portato/gui/gtk/windows/about.py delete mode 100644 portato/gui/gtk/windows/basic.py delete mode 100644 portato/gui/gtk/windows/main.py delete mode 100644 portato/gui/gtk/windows/plugin.py delete mode 100644 portato/gui/gtk/windows/preference.py delete mode 100644 portato/gui/gtk/windows/search.py delete mode 100644 portato/gui/gtk/windows/update.py delete mode 100644 portato/gui/gtk/wrapper.py create mode 100644 portato/gui/session.py create mode 100644 portato/gui/views.py create mode 100644 portato/gui/windows/__init__.py create mode 100644 portato/gui/windows/about.py create mode 100644 portato/gui/windows/basic.py create mode 100644 portato/gui/windows/main.py create mode 100644 portato/gui/windows/plugin.py create mode 100644 portato/gui/windows/preference.py create mode 100644 portato/gui/windows/search.py create mode 100644 portato/gui/windows/splash.py create mode 100644 portato/gui/windows/update.py create mode 100644 portato/gui/wrapper.py (limited to 'portato/gui') diff --git a/portato/gui/__init__.py b/portato/gui/__init__.py index 6df684c..1349e00 100644 --- a/portato/gui/__init__.py +++ b/portato/gui/__init__.py @@ -3,9 +3,30 @@ # File: portato/gui/__init__.py # This file is part of the Portato-Project, a graphical portage-frontend. # -# Copyright (C) 2006-2007 René 'Necoro' Neumann +# Copyright (C) 2006-2008 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 __future__ import absolute_import + +from ..helper import _ +from .. import get_listener +from .exception_handling import register_ex_handler + +def run (): + from .windows.splash import SplashScreen + try: + s = SplashScreen(_("Loading Portage")) + register_ex_handler() + s.show() + from .windows.main import MainWindow + m = MainWindow(s) + s.hide() + m.main() + except KeyboardInterrupt: + pass + + get_listener().close() diff --git a/portato/gui/dialogs.py b/portato/gui/dialogs.py new file mode 100644 index 0000000..1beb6be --- /dev/null +++ b/portato/gui/dialogs.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- +# +# File: portato/gui/dialogs.py +# This file is part of the Portato-Project, a graphical portage-frontend. +# +# Copyright (C) 2006-2008 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 + +import gtk +from ..helper import _, error + +def queue_not_empty_dialog(): + dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_NONE, _("There are some packages in the emerge queue and/or an emerge process is running.\nDo you really want to quit?")) + #dialog.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_YES, gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE) + dialog.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE) + ret = dialog.run() + dialog.destroy() + return ret + +def io_ex_dialog (io_ex): + string = io_ex.strerror + if io_ex.filename: + string = string+": "+io_ex.filename + + error(string) + dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, string) + ret = dialog.run() + dialog.destroy() + return ret + +def blocked_dialog (blocked, blocks): + dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("%(blocked)s is blocked by %(blocks)s.\nPlease unmerge the blocking package.") % {"blocked":blocked, "blocks" : blocks}) + ret = dialog.run() + dialog.destroy() + return ret + +def not_root_dialog (): + errorMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("You are not root.")) + ret = errorMB.run() + errorMB.destroy() + return ret + +def unmask_dialog (cpv): + dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, _("%s seems to be masked.\nDo you want to unmask it and its dependencies?") % cpv) + ret = dialog.run() + dialog.destroy() + return ret + +def nothing_found_dialog (): + dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("Package not found!")) + ret = dialog.run() + dialog.destroy() + return ret + +def changed_flags_dialog (what = "flags"): + hintMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, + _("You have changed %s. Portato will write these changes into the appropriate files. Please backup them if you think it is necessairy.") % what) + ret = hintMB.run() + hintMB.destroy() + return ret + +def remove_deps_dialog (): + infoMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("You cannot remove dependencies. :)")) + ret = infoMB.run() + infoMB.destroy() + return ret + +def remove_updates_dialog(): + askMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, _("This is the updates queue. You cannot remove single elements.\nDo you want to clear the whole queue instead?")) + ret = askMB.run() + askMB.destroy() + return ret + +def remove_queue_dialog (): + askMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, _("Do you really want to clear the whole queue?")) + ret = askMB.run() + askMB.destroy() + return ret + +def file_chooser_dialog (title, parent): + fc = gtk.FileChooserDialog(title = title, parent = parent, action = gtk.FILE_CHOOSER_ACTION_SAVE, buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) + fc.set_do_overwrite_confirmation(True) + ret = fc.run() + + if ret == gtk.RESPONSE_ACCEPT: + ret = fc.get_filename() + else: + ret = None + + fc.destroy() + return ret diff --git a/portato/gui/exception_handling.py b/portato/gui/exception_handling.py new file mode 100644 index 0000000..db0cab9 --- /dev/null +++ b/portato/gui/exception_handling.py @@ -0,0 +1,124 @@ +# -*- coding: utf-8 -*- +# +# File: portato/gui/exception_handling.py +# This file is part of the Portato-Project, a graphical portage-frontend. +# +# Copyright (C) 2007-2008 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 __future__ import absolute_import, with_statement + +import gtk, pango, gobject +import sys, traceback + +from threading import Thread +from StringIO import StringIO + +from ..helper import _, debug, error +from .dialogs import file_chooser_dialog, io_ex_dialog + +class GtkThread (Thread): + def run(self): + try: + Thread.run(self) + except SystemExit: + raise # let normal thread handle it + except: + type, val, tb = sys.exc_info() + try: + sys.excepthook(type, val, tb, thread = self.getName()) + except TypeError: + raise type, val, tb # let normal thread handle it + finally: + del type, val, tb + +class UncaughtExceptionDialog(gtk.MessageDialog): + """Original idea by Gustavo Carneiro - original code: http://www.daa.com.au/pipermail/pygtk/attachments/20030828/2d304204/gtkexcepthook.py.""" + + def __init__(self, type, value, tb, thread = None): + + super(UncaughtExceptionDialog,self).__init__(parent=None, flags=0, type=gtk.MESSAGE_WARNING, buttons=gtk.BUTTONS_NONE, message_format=_("A programming error has been detected during the execution of this program.")) + self.set_title(_("Bug Detected")) + self.format_secondary_text(_("It probably isn't fatal, but should be reported to the developers nonetheless.")) + + self.add_button(_("Show Details"), 1) + self.add_button(gtk.STOCK_SAVE_AS, 2) + self.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE) + + # Details + self.textview = gtk.TextView() + self.textview.set_editable(False) + self.textview.modify_font(pango.FontDescription("Monospace")) + + self.sw = gtk.ScrolledWindow(); + self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + self.sw.add(self.textview) + + self.tbFrame = gtk.Frame() + self.tbFrame.set_shadow_type(gtk.SHADOW_IN) + self.tbFrame.add(self.sw) + self.tbFrame.set_border_width(6) + + self.vbox.add(self.tbFrame) + + textbuffer = self.textview.get_buffer() + self.text = get_trace(type, value, tb) + if thread: + self.text = _("Exception in thread \"%(thread)s\":\n%(trace)s") % {"thread": thread, "trace": self.text} + textbuffer.set_text(self.text) + self.textview.set_size_request(gtk.gdk.screen_width()/2, gtk.gdk.screen_height()/3) + + self.details = self.tbFrame + self.set_position(gtk.WIN_POS_CENTER) + self.set_gravity(gtk.gdk.GRAVITY_CENTER) + + def run (self): + while True: + resp = super(UncaughtExceptionDialog, self).run() + if resp == 1: + self.details.show_all() + self.set_response_sensitive(1, False) + elif resp == 2: + debug("Want to save") + file = file_chooser_dialog(_("Save traceback..."), self) + if file: + debug("Save to %s", file) + + try: + with open(file, "w") as f: + f.writelines(self.text) + except IOError, e: + io_ex_dialog(e) + + else: + debug("Nothing to save") + else: + break + self.destroy() + +def get_trace(type, value, tb): + trace = StringIO() + traceback.print_exception(type, value, tb, None, trace) + traceStr = trace.getvalue() + trace.close() + return traceStr + +def register_ex_handler(): + + def handler(type, val, tb, thread = None): + def run_dialog(): + UncaughtExceptionDialog(type, val, tb, thread).run() + + if thread: + error(_("Exception in thread \"%(thread)s\":\n%(trace)s"), {"thread": thread, "trace": get_trace(type, val, tb)}) + else: + error(_("Exception:\n%s"), get_trace(type, val, tb)) + + gobject.idle_add(run_dialog) + + sys.excepthook = handler diff --git a/portato/gui/gtk/__init__.py b/portato/gui/gtk/__init__.py deleted file mode 100644 index 9a5338b..0000000 --- a/portato/gui/gtk/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -# -# File: portato/gui/gtk/__init__.py -# This file is part of the Portato-Project, a graphical portage-frontend. -# -# Copyright (C) 2006-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 __future__ import absolute_import - -from gettext import lgettext as _ - -from ... import get_listener -from .exception_handling import register_ex_handler - -def run (): - from .splash import SplashScreen - try: - s = SplashScreen(_("Loading Portage")) - register_ex_handler() - s.show() - from .windows import MainWindow - m = MainWindow(s) - s.hide() - m.main() - except KeyboardInterrupt: - pass - - get_listener().close() diff --git a/portato/gui/gtk/dialogs.py b/portato/gui/gtk/dialogs.py deleted file mode 100644 index c26835c..0000000 --- a/portato/gui/gtk/dialogs.py +++ /dev/null @@ -1,96 +0,0 @@ -# -*- coding: utf-8 -*- -# -# File: portato/gui/gtk/dialogs.py -# This file is part of the Portato-Project, a graphical portage-frontend. -# -# Copyright (C) 2006 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 - -import gtk -from ...helper import error -from gettext import lgettext as _ - -def queue_not_empty_dialog(): - dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_NONE, _("There are some packages in the emerge queue and/or an emerge process is running.\nDo you really want to quit?")) - #dialog.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_YES, gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE) - dialog.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE) - ret = dialog.run() - dialog.destroy() - return ret - -def io_ex_dialog (io_ex): - string = io_ex.strerror - if io_ex.filename: - string = string+": "+io_ex.filename - - error(string) - dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, string) - ret = dialog.run() - dialog.destroy() - return ret - -def blocked_dialog (blocked, blocks): - dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("%(blocked)s is blocked by %(blocks)s.\nPlease unmerge the blocking package.") % {"blocked":blocked, "blocks" : blocks}) - ret = dialog.run() - dialog.destroy() - return ret - -def not_root_dialog (): - errorMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("You are not root.")) - ret = errorMB.run() - errorMB.destroy() - return ret - -def unmask_dialog (cpv): - dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, _("%s seems to be masked.\nDo you want to unmask it and its dependencies?") % cpv) - ret = dialog.run() - dialog.destroy() - return ret - -def nothing_found_dialog (): - dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("Package not found!")) - ret = dialog.run() - dialog.destroy() - return ret - -def changed_flags_dialog (what = "flags"): - hintMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, - _("You have changed %s. Portato will write these changes into the appropriate files. Please backup them if you think it is necessairy.") % what) - ret = hintMB.run() - hintMB.destroy() - return ret - -def remove_deps_dialog (): - infoMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("You cannot remove dependencies. :)")) - ret = infoMB.run() - infoMB.destroy() - return ret - -def remove_updates_dialog(): - askMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, _("This is the updates queue. You cannot remove single elements.\nDo you want to clear the whole queue instead?")) - ret = askMB.run() - askMB.destroy() - return ret - -def remove_queue_dialog (): - askMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, _("Do you really want to clear the whole queue?")) - ret = askMB.run() - askMB.destroy() - return ret - -def file_chooser_dialog (title, parent): - fc = gtk.FileChooserDialog(title = title, parent = parent, action = gtk.FILE_CHOOSER_ACTION_SAVE, buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) - fc.set_do_overwrite_confirmation(True) - ret = fc.run() - - if ret == gtk.RESPONSE_ACCEPT: - ret = fc.get_filename() - else: - ret = None - - fc.destroy() - return ret diff --git a/portato/gui/gtk/exception_handling.py b/portato/gui/gtk/exception_handling.py deleted file mode 100644 index c44f554..0000000 --- a/portato/gui/gtk/exception_handling.py +++ /dev/null @@ -1,125 +0,0 @@ -# -*- coding: utf-8 -*- -# -# File: portato/gui/gtk/exception_handling.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 __future__ import absolute_import, with_statement - -import gtk, pango, gobject -import sys, traceback - -from threading import Thread -from gettext import lgettext as _ -from StringIO import StringIO - -from ...helper import debug, error -from .dialogs import file_chooser_dialog, io_ex_dialog - -class GtkThread (Thread): - def run(self): - try: - Thread.run(self) - except SystemExit: - raise # let normal thread handle it - except: - type, val, tb = sys.exc_info() - try: - sys.excepthook(type, val, tb, thread = self.getName()) - except TypeError: - raise type, val, tb # let normal thread handle it - finally: - del type, val, tb - -class UncaughtExceptionDialog(gtk.MessageDialog): - """Original idea by Gustavo Carneiro - original code: http://www.daa.com.au/pipermail/pygtk/attachments/20030828/2d304204/gtkexcepthook.py.""" - - def __init__(self, type, value, tb, thread = None): - - super(UncaughtExceptionDialog,self).__init__(parent=None, flags=0, type=gtk.MESSAGE_WARNING, buttons=gtk.BUTTONS_NONE, message_format=_("A programming error has been detected during the execution of this program.")) - self.set_title(_("Bug Detected")) - self.format_secondary_text(_("It probably isn't fatal, but should be reported to the developers nonetheless.")) - - self.add_button(_("Show Details"), 1) - self.add_button(gtk.STOCK_SAVE_AS, 2) - self.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE) - - # Details - self.textview = gtk.TextView() - self.textview.set_editable(False) - self.textview.modify_font(pango.FontDescription("Monospace")) - - self.sw = gtk.ScrolledWindow(); - self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - self.sw.add(self.textview) - - self.tbFrame = gtk.Frame() - self.tbFrame.set_shadow_type(gtk.SHADOW_IN) - self.tbFrame.add(self.sw) - self.tbFrame.set_border_width(6) - - self.vbox.add(self.tbFrame) - - textbuffer = self.textview.get_buffer() - self.text = get_trace(type, value, tb) - if thread: - self.text = _("Exception in thread \"%(thread)s\":\n%(trace)s") % {"thread": thread, "trace": self.text} - textbuffer.set_text(self.text) - self.textview.set_size_request(gtk.gdk.screen_width()/2, gtk.gdk.screen_height()/3) - - self.details = self.tbFrame - self.set_position(gtk.WIN_POS_CENTER) - self.set_gravity(gtk.gdk.GRAVITY_CENTER) - - def run (self): - while True: - resp = super(UncaughtExceptionDialog, self).run() - if resp == 1: - self.details.show_all() - self.set_response_sensitive(1, False) - elif resp == 2: - debug("Want to save") - file = file_chooser_dialog(_("Save traceback..."), self) - if file: - debug("Save to %s", file) - - try: - with open(file, "w") as f: - f.writelines(self.text) - except IOError, e: - io_ex_dialog(e) - - else: - debug("Nothing to save") - else: - break - self.destroy() - -def get_trace(type, value, tb): - trace = StringIO() - traceback.print_exception(type, value, tb, None, trace) - traceStr = trace.getvalue() - trace.close() - return traceStr - -def register_ex_handler(): - - def handler(type, val, tb, thread = None): - def run_dialog(): - UncaughtExceptionDialog(type, val, tb, thread).run() - - if thread: - error(_("Exception in thread \"%(thread)s\":\n%(trace)s"), {"thread": thread, "trace": get_trace(type, val, tb)}) - else: - error(_("Exception:\n%s"), get_trace(type, val, tb)) - - gobject.idle_add(run_dialog) - - sys.excepthook = handler diff --git a/portato/gui/gtk/session.py b/portato/gui/gtk/session.py deleted file mode 100644 index 5d6c607..0000000 --- a/portato/gui/gtk/session.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -# -# File: portato/gui/gtk/session.py -# This file is part of the Portato-Project, a graphical portage-frontend. -# -# Copyright (C) 2008 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 ...helper import debug, _ - -# the current version for saved sessions -# change this, whenever the change is incompatible with previous versions -SESSION_VERSION = 1 - -class SessionException (Exception): - - error = _("Version mismatch.") - def __init__ (self, got, expected): - self.got = got - self.expected = expected - - def __str__ (self): - return "%s %s" % (self.error, (_("Got '%d' - expected '%d'.") % (self.got, self.expected))) - -class OldSessionException (SessionException): - error = _("Current session format is too old.") - -class NewSessionException (SessionException): - error = _("Current session format is newer than this version supports.") diff --git a/portato/gui/gtk/splash.py b/portato/gui/gtk/splash.py deleted file mode 100644 index 48f8061..0000000 --- a/portato/gui/gtk/splash.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -# -# File: portato/gui/gtk/splash.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 __future__ import absolute_import - -import gtk -from gettext import lgettext as _ - -from ...constants import VERSION, APP_ICON -from .windows.basic import Window - -class SplashScreen (Window): - - def __init__ (self, startStr = ""): - Window.__init__(self) - - self.image = self.tree.get_widget("image") - self.genLabel = self.tree.get_widget("generalLabel") - self.descrLabel = self.tree.get_widget("descrLabel") - - self.image.set_from_file(APP_ICON) - self.genLabel.set_label("Portato %s ..." % VERSION) - - self.set_descr(startStr) - - def set_descr (self, string): - self.descrLabel.set_label(_("... is starting up: %s") % string) - self.do_iteration() - - def do_iteration (self): - while gtk.events_pending(): - gtk.main_iteration() - - def show (self): - self.window.show_all() - self.do_iteration() - - def hide (self): - self.window.hide() - self.do_iteration() - - __call__ = set_descr diff --git a/portato/gui/gtk/views.py b/portato/gui/gtk/views.py deleted file mode 100644 index d341c10..0000000 --- a/portato/gui/gtk/views.py +++ /dev/null @@ -1,147 +0,0 @@ -# -*- coding: utf-8 -*- -# -# File: portato/gui/gtk/views.py -# This file is part of the Portato-Project, a graphical portage-frontend. -# -# Copyright (C) 2006-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 __future__ import absolute_import, with_statement - -import pango -import gtksourceview2 -import gtk -import logging - -from gettext import lgettext as _ -from ...helper import warning - -class LazyView (object): - def __init__ (self): - self.connect("map", self.cb_mapped) - - self.pkg = None - self.updated = False - - def update (self, pkg, force = False): - self.pkg = pkg - self.updated = True - - if force: - self.cb_mapped() - - def cb_mapped (self, *args): - if self.updated and self.pkg: - self.set_text("".join(self._get_content())) - self.updated = False - - return False - - def set_text (self, text): - raise NotImplementedError - - def _get_content (self): - raise NotImplementedError - -class ListView (gtk.TextView, LazyView): - - def __init__ (self, content_fn): - self.content_fn = content_fn - - gtk.TextView.__init__(self) - LazyView.__init__(self) - - self.set_editable(False) - self.set_cursor_visible(False) - - def set_text (self, text): - self.get_buffer().set_text(text) - - def _get_content (self): - return self.content_fn(self.pkg) - -class InstalledOnlyView (ListView): - def _get_content (self): - if self.pkg: - if not self.pkg.is_installed(): - return _("Package is not installed") - else: - return ListView._get_content(self) - else: - return "Huh?" - -class HighlightView (gtksourceview2.View, LazyView): - - def __init__ (self, get_file_fn, languages = []): - self.get_fn = get_file_fn - - man = gtksourceview2.LanguageManager() - - language = None - old_lang = None - for lang in languages: - if old_lang: - warning(_("No %(old)s language file installed. Falling back to %(new)s."), {"old" : old_lang, "new" : lang}) - - language = man.get_language(lang) - if language: - break - else: - old_lang = lang - - if not language and old_lang: - warning(_("No %(old)s language file installed. Disable highlighting."), {"old" : old_lang}) - - buf = gtksourceview2.Buffer() - buf.set_language(language) - - gtksourceview2.View.__init__(self, buf) - LazyView.__init__(self) - - self.set_editable(False) - self.set_cursor_visible(False) - - def set_text (self, text): - self.get_buffer().set_text(text) - - def _get_content (self): - try: - with open(self.get_fn(self.pkg)) as f: - return f.readlines() - except IOError, e: - return _("Error: %s") % e.strerror - -class LogView (logging.Handler): - - colors = ( - (logging.DEBUG, "debug", "blue"), - (logging.INFO, "info", "green"), - (logging.WARNING, "warning", "yellow"), - (-1, "error", "red") - ) - - def __init__ (self, view): - logging.Handler.__init__(self, logging.DEBUG) - - self.view = view - self.buf = view.get_buffer() - - # set tags - for lvl, name, color in self.colors: - self.buf.create_tag("log_%s" % name, foreground = color,weight = pango.WEIGHT_BOLD) - - logging.getLogger("portatoLogger").addHandler(self) - - def emit (self, record): - - for lvl, name, color in self.colors: - if lvl == -1 or record.levelno <= lvl: - tag = "log_%s" % name - break - - self.buf.insert_with_tags_by_name(self.buf.get_end_iter(), "* ", tag) - self.buf.insert(self.buf.get_end_iter(), record.getMessage()+"\n") diff --git a/portato/gui/gtk/windows/__init__.py b/portato/gui/gtk/windows/__init__.py deleted file mode 100644 index 0107937..0000000 --- a/portato/gui/gtk/windows/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -# -# File: portato/gui/gtk/windows/__init__.py -# This file is part of the Portato-Project, a graphical portage-frontend. -# -# Copyright (C) 2008 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 __future__ import absolute_import - -from .main import MainWindow diff --git a/portato/gui/gtk/windows/about.py b/portato/gui/gtk/windows/about.py deleted file mode 100644 index d9297d0..0000000 --- a/portato/gui/gtk/windows/about.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -# -# File: portato/gui/gtk/windows/about.py -# This file is part of the Portato-Project, a graphical portage-frontend. -# -# Copyright (C) 2008 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 __future__ import absolute_import - -import gtk - -from .basic import AbstractDialog -from ....constants import VERSION, APP_ICON - -class AboutWindow (AbstractDialog): - """A window showing the "about"-informations.""" - - def __init__ (self, parent): - - AbstractDialog.__init__(self, parent) - - img = gtk.Image() - img.set_from_file(APP_ICON) - - self.window.set_version(VERSION) - self.window.set_logo(img.get_pixbuf()) - - self.window.show_all() - diff --git a/portato/gui/gtk/windows/basic.py b/portato/gui/gtk/windows/basic.py deleted file mode 100644 index e202ac9..0000000 --- a/portato/gui/gtk/windows/basic.py +++ /dev/null @@ -1,108 +0,0 @@ -# -*- coding: utf-8 -*- -# -# File: portato/gui/gtk/windows/basic.py -# This file is part of the Portato-Project, a graphical portage-frontend. -# -# Copyright (C) 2006-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 __future__ import absolute_import - -# gtk stuff -import gtk -import gtk.glade -import gobject - -from functools import wraps -import os.path - -from ....constants import TEMPLATE_DIR, APP_ICON, APP, LOCALE_DIR - -gtk.glade.bindtextdomain (APP, LOCALE_DIR) -gtk.glade.textdomain (APP) - -class Window (object): - def __init__ (self): - - if not hasattr(self, "__tree__"): - self.__tree__ = self.__class__.__name__ - - if not hasattr(self, "__window__"): - self.__window__ = self.__class__.__name__ - - if not hasattr(self, "__file__"): - self.__file__ = self.__class__.__name__ - - self.tree = self.get_tree(self.__tree__) - self.tree.signal_autoconnect(self) - self.window = self.tree.get_widget(self.__window__) - self.window.set_icon_from_file(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. - @attention: this function relies on the gtk.Window-Object being stored as self.window""" - - @wraps(func) - def wrapper (self, *args, **kwargs): - ret = None - def cb_idle(): - try: - ret = func(self, *args, **kwargs) - finally: - self.window.window.set_cursor(None) - return False - - watch = gtk.gdk.Cursor(gtk.gdk.WATCH) - self.window.window.set_cursor(watch) - gobject.idle_add(cb_idle) - return ret - - return wrapper - - def get_tree (self, name): - return gtk.glade.XML(os.path.join(TEMPLATE_DIR, self.__file__+".glade"), name) - -class AbstractDialog (Window): - """A class all our dialogs get derived from. It sets useful default vars and automatically handles the ESC-Button.""" - - def __init__ (self, parent): - """Constructor. - - @param parent: the parent window - @type parent: gtk.Window""" - - Window.__init__(self) - - # set parent - self.window.set_transient_for(parent) - self.parent = parent - - # catch the ESC-key - self.window.connect("key-press-event", self.cb_key_pressed) - - def cb_key_pressed (self, widget, event): - """Closes the window if ESC is pressed.""" - keyname = gtk.gdk.keyval_name(event.keyval) - if keyname == "Escape": - self.close() - return True - else: - return False - - def close (self, *args): - self.window.destroy() - -class Popup (object): - - def __init__ (self, name, parent, file = "popups"): - self.tree = gtk.glade.XML(os.path.join(TEMPLATE_DIR, file+".glade"), root = name) - self.tree.signal_autoconnect(parent) - self._popup = self.tree.get_widget(name) - - def popup (self, *args): - self._popup.popup(*args) diff --git a/portato/gui/gtk/windows/main.py b/portato/gui/gtk/windows/main.py deleted file mode 100644 index 0f25572..0000000 --- a/portato/gui/gtk/windows/main.py +++ /dev/null @@ -1,1661 +0,0 @@ -# -*- coding: utf-8 -*- -# -# File: portato/gui/gtk/windows/main.py -# This file is part of the Portato-Project, a graphical portage-frontend. -# -# Copyright (C) 2006-2008 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 __future__ import absolute_import, with_statement - -# gtk stuff -import gtk -import gobject - -# other -import os.path -import itertools as itt - -# our backend stuff -from ....backend import flags, system # must be the first to avoid circular deps -from .... import get_listener, plugin, dependency -from ....helper import debug, warning, error, info, unique_array, N_, _ -from ....session import Session -from ....constants import CONFIG_LOCATION, VERSION, APP_ICON -from ....backend.exceptions import PackageNotFoundException, BlockedException - -# more GUI stuff -from ...utils import Database, Config -from ...queue import EmergeQueue -from ..session import SESSION_VERSION, SessionException, OldSessionException, NewSessionException -from ..wrapper import GtkTree, GtkConsole -from ..exception_handling import GtkThread -from ..views import LogView, HighlightView, InstalledOnlyView -from ..dialogs import (blocked_dialog, changed_flags_dialog, io_ex_dialog, - nothing_found_dialog, queue_not_empty_dialog, remove_deps_dialog, - remove_queue_dialog, remove_updates_dialog, unmask_dialog) - -# even more GUI stuff -from .basic import Window, Popup -from .about import AboutWindow -from .plugin import PluginWindow -from .preference import PreferenceWindow -from .search import SearchWindow -from .update import UpdateWindow - -class PackageTable: - """A window with data about a specfic package.""" - - def __init__ (self, main): - """Build up window contents. - - @param main: the main window - @type main: MainWindow""" - - self.main = main - self.tree = main.tree - self.window = main.window - self.tree.signal_autoconnect(self) - - # all the package data is in this one VB - self.vb = self.tree.get_widget("packageVB") - - # the notebook - self.notebook = self.tree.get_widget("packageNotebook") - - # the version combo - self.versionCombo = self.tree.get_widget("versionCombo") - self.build_version_combo() - - # chechboxes - self.installedCheck = self.tree.get_widget("installedCheck") - self.maskedCheck = self.tree.get_widget("maskedCheck") - self.testingCheck = self.tree.get_widget("testingCheck") - self.maskedLabel = self.tree.get_widget("maskedLabel") - - # labels - generalVB = self.tree.get_widget("generalVB") - generalVB.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#FFFFFF")) - - self.nameLabel = self.tree.get_widget("nameLabel") - self.descLabel = self.tree.get_widget("descLabel") - self.overlayLabel = self.tree.get_widget("overlayLabel") - self.overlayLL = self.tree.get_widget("overlayLabelLabel") - self.licenseLabel = self.tree.get_widget("licenseLabel") - self.linkBox = self.tree.get_widget("linkBox") - self.notInSysLabel = self.tree.get_widget("notInSysLabel") - self.missingLabel = self.tree.get_widget("missingLabel") - self.useFlagsLabel = self.tree.get_widget("useFlagsLabel") - self.useFlagsLL = self.tree.get_widget("useFlagsLabelLabel") - - # buttons - self.emergeBtn = self.tree.get_widget("pkgEmergeBtn") - self.unmergeBtn = self.tree.get_widget("pkgUnmergeBtn") - self.revertBtn = self.tree.get_widget("pkgRevertBtn") - - # useList - self.useList = self.tree.get_widget("useList") - self.build_use_list() - - # depList - self.depList = self.tree.get_widget("dependencyList") - self.build_dep_list() - - # views - self.ebuildView = self.tree.get_widget("ebuildScroll").get_child() - self.changelogView = self.tree.get_widget("changelogScroll").get_child() - self.filesView = self.tree.get_widget("filesScroll").get_child() - - # icons - self.icons = {} - self.icons["use"] = self.window.render_icon(gtk.STOCK_REMOVE, gtk.ICON_SIZE_MENU) - self.icons["installed"] = self.window.render_icon(gtk.STOCK_YES, gtk.ICON_SIZE_MENU) - self.icons["or"] = self.window.render_icon(gtk.STOCK_MEDIA_PAUSE, gtk.ICON_SIZE_MENU) - self.icons["block"] = self.window.render_icon(gtk.STOCK_NO, gtk.ICON_SIZE_MENU) - - def update (self, cp, queue = None, version = None, doEmerge = True, instantChange = False, type = 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: boolean - @param instantChange: if True the changed keywords are updated instantly - @type instantChange: boolean - @param type: the type of the queue this package is in; if None there is no queue :) - @type type: string""" - - self.cp = cp # category/package - self.version = version # version - if not None this is used - self.queue = queue - self.doEmerge = doEmerge - self.instantChange = instantChange - self.type = type - - # 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)) - - # version-combo-box - self.versionCombo.handler_block(self.versionCombo.changeHandler) # block change handler, because it would be called several times - self.versionCombo.get_model().clear() - self.fill_version_combo() - self.versionCombo.handler_unblock(self.versionCombo.changeHandler) # unblock handler again - - if not self.queue or not self.doEmerge: - self.emergeBtn.set_sensitive(False) - self.unmergeBtn.set_sensitive(False) - - # current status - self.cb_version_combo_changed() - self.vb.show_all() - - def hide (self): - self.vb.hide_all() - - def set_labels (self): - pkg = self.actual_package() - - # name - self.nameLabel.set_markup("%s" % pkg.get_cp()) - - # description - desc = pkg.get_package_settings("DESCRIPTION") or _("") - self.descLabel.set_label(desc) - - # overlay - if pkg.is_overlay(): - self.overlayLabel.set_label(pkg.get_overlay_path()) - self.overlayLabel.show() - self.overlayLL.show() - else: - self.overlayLabel.hide() - self.overlayLL.hide() - - # license - self.licenseLabel.set_label(pkg.get_package_settings("LICENSE")) - - # link - for c in self.linkBox.get_children(): - self.linkBox.remove(c) - - text = pkg.get_package_settings("HOMEPAGE") - texts = text.split(" ") - ftexts = [] - - for count, t in enumerate(texts): - if not t.startswith(("http:", "ftp:")): - if count == 0: - error(_("The first homepage part does not start with 'http' or 'ftp'.")) - ftexts.append(t) - continue - else: - info(_("Blank inside homepage.")) - ftexts[-1] += " %s" % t - else: - ftexts.append(t) - - for t in ftexts: - link = gtk.LinkButton(t) - link.set_alignment(0.0, 0.5) - link.set_border_width(0) - self.linkBox.add(link) - - # useflags - flaglist = list(itt.ifilterfalse(pkg.use_expanded, pkg.get_iuse_flags())) - flaglist.sort() - flags = ", ".join(flaglist) - - if flags: - self.useFlagsLL.show() - self.useFlagsLabel.show() - self.useFlagsLabel.set_label(flags) - else: - self.useFlagsLL.hide() - self.useFlagsLabel.hide() - - def fill_dep_list(self): - - deptree = self.actual_package().get_dependencies() - store = self.depList.get_model() - - def add (tree, it): - - def get_icon (dep): - if dep.satisfied: - return self.icons["installed"] - elif dep.dep[0] == "!": - return self.icons["block"] - else: - return None - - # useflags - for use, usetree in tree.flags.iteritems(): - if use[0] == "!": - usestring = _("If '%s' is disabled") % use[1:] - else: - usestring = _("If '%s' is enabled") % use - useit = store.append(it, [self.icons["use"], usestring]) - add(usetree, useit) - - # ORs - ordeps = (dep for dep in tree.deps if isinstance(dep, dependency.OrDependency)) - - for ordep in ordeps: - orit = store.append(it, [self.icons["or"], _("One of the following")]) - - for dep in ordep.dep: - store.append(orit, [get_icon(dep), dep.dep]) - - # normal - def sort_key (x): - split = system.split_cpv(x.dep) - - if split is None: # split_cpv returns None if this is only a CP; we assume there are only valid deps - return x.dep - else: - return "/".join(split[0:2]) - - ndeps = [dep for dep in tree.deps if not isinstance(dep, dependency.OrDependency)] - ndeps.sort(key = sort_key) - for dep in ndeps: - store.append(it, [get_icon(dep), dep.dep]) - - add (deptree, None) - - def fill_use_list(self): - - pkg = self.actual_package() - pkg_flags = pkg.get_iuse_flags() - pkg_flags.sort() - - actual_exp = None - actual_exp_it = None - - euse = pkg.get_actual_use_flags() - instuse = pkg.get_installed_use_flags() - - store = self.useList.get_model() - - for use in pkg_flags: - exp = pkg.use_expanded(use, suggest = actual_exp) - if exp is not None: - if exp != actual_exp: - actual_exp_it = store.append(None, [None, None, exp, "%s" % _("This is an expanded use flag and cannot be selected")]) - actual_exp = exp - else: - actual_exp_it = None - actual_exp = None - - enabled = use in euse - installed = use in instuse - store.append(actual_exp_it, [enabled, installed, use, system.get_use_desc(use, self.cp)]) - - def build_dep_list (self): - store = gtk.TreeStore(gtk.gdk.Pixbuf, str) - - self.depList.set_model(store) - - col = gtk.TreeViewColumn() - - cell = gtk.CellRendererPixbuf() - col.pack_start(cell, False) - col.add_attribute(cell, "pixbuf", 0) - - cell = gtk.CellRendererText() - col.pack_start(cell, True) - col.add_attribute(cell, "text", 1) - - self.depList.append_column(col) - - def build_use_list (self): - """Builds the useList.""" - store = gtk.TreeStore(bool, bool, str, str) - self.useList.set_model(store) - - # build view - cell = gtk.CellRendererText() - iCell = gtk.CellRendererToggle() - iCell.set_property("activatable", False) - tCell = gtk.CellRendererToggle() - tCell.set_property("activatable", True) - tCell.connect("toggled", self.cb_use_flag_toggled, store) - self.useList.append_column(gtk.TreeViewColumn(_("Enabled"), tCell, active = 0)) - self.useList.append_column(gtk.TreeViewColumn(_("Installed"), iCell, active = 1)) - self.useList.append_column(gtk.TreeViewColumn(_("Flag"), cell, text = 2)) - self.useList.append_column(gtk.TreeViewColumn(_("Description"), cell, markup = 3)) - - self.useList.set_search_column(2) - self.useList.set_enable_tree_lines(True) - - def build_version_combo (self): - store = gtk.ListStore(gtk.gdk.Pixbuf, str) - - # build view - self.versionCombo.set_model(store) - col = gtk.TreeViewColumn("Versions") - - # adding the pixbuf - cell = gtk.CellRendererPixbuf() - self.versionCombo.pack_start(cell, False) - self.versionCombo.add_attribute(cell, "pixbuf", 0) - - # adding the package name - cell = gtk.CellRendererText() - self.versionCombo.pack_start(cell, True) - self.versionCombo.add_attribute(cell, "text", 1) - - # connect - self.versionCombo.changeHandler = self.versionCombo.connect("changed", self.cb_version_combo_changed) - - def fill_version_combo (self): - - store = self.versionCombo.get_model() - - # append versions - for vers, inst in ((x.get_version(), x.is_installed()) for x in self.packages): - if inst: - icon = self.main.instPixbuf - else: - icon = None - store.append([icon, vers]) - - # activate the first one - try: - best_version = "" - if self.version: - best_version = self.version - else: - best_version = system.find_best_match(self.packages[0].get_cp(), only_installed = (self.instPackages != [])).get_version() - for i in range(len(self.packages)): - if self.packages[i].get_version() == best_version: - self.versionCombo.set_active(i) - break - except AttributeError: # no package found - self.versionCombo.set_active(0) - - def actual_package (self): - """Returns the actual selected package. - - @returns: the actual selected package - @rtype: backend.Package""" - - return self.packages[self.versionCombo.get_active()] - - def _update_keywords (self, emerge, update = False): - if emerge: - type = "install" if not self.type else self.type - try: - try: - self.queue.append(self.actual_package().get_cpv(), type = type, update = update) - except PackageNotFoundException, e: - if unmask_dialog(e[0]) == gtk.RESPONSE_YES: - self.queue.append(self.actual_package().get_cpv(), type = type, unmask = True, update = update) - except BlockedException, e: - blocked_dialog(e[0], e[1]) - else: - try: - self.queue.append(self.actual_package().get_cpv(), type = "uninstall") - except PackageNotFoundException, e: - error(_("Package could not be found: %s"), e[0]) - #masked_dialog(e[0]) - - def cb_version_combo_changed (self, *args): - - pkg = self.actual_package() - - # set the views - for v in (self.ebuildView, self.changelogView, self.filesView): - v.update(pkg, force = self.notebook.get_nth_page(self.notebook.get_current_page()) == v.get_parent()) - - # set the labels - self.set_labels() - - # set use list - self.useList.get_model().clear() - self.useList.columns_autosize() - self.fill_use_list() - - # set dep list - self.depList.get_model().clear() - self.useList.columns_autosize() - self.fill_dep_list() - - # - # rebuild the buttons and checkboxes in all the different manners which are possible - # - if (not pkg.is_in_system()) or pkg.is_missing_keyword(): - if not pkg.is_in_system(): - self.missingLabel.hide() - self.notInSysLabel.show() - else: # missing keyword - self.missingLabel.show() - self.notInSysLabel.hide() -# - self.installedCheck.hide() - self.maskedCheck.hide() - self.maskedLabel.hide() - self.testingCheck.hide() - self.emergeBtn.set_sensitive(False) - else: # normal package - self.missingLabel.hide() - self.notInSysLabel.hide() - self.installedCheck.show() - self.maskedCheck.show() - self.maskedLabel.show() - self.testingCheck.show() - if self.doEmerge: - self.emergeBtn.set_sensitive(True) - self.installedCheck.set_active(pkg.is_installed()) - - reason = pkg.get_masking_reason() or " " - if pkg.is_masked(use_changed = False) and not pkg.is_masked(use_changed = True): - self.maskedCheck.set_label("(%s)" % _("Masked")) - self.maskedCheck.get_child().set_use_markup(True) - else: - self.maskedCheck.set_label(_("Masked")) - - if pkg.is_locally_masked(): - self.maskedCheck.set_label("%s" % _("Masked")) - self.maskedCheck.get_child().set_use_markup(True) - self.maskedCheck.set_active(True) - reason = _("Masked by user") - else: - self.maskedCheck.set_active(pkg.is_masked(use_changed = False)) - - if reason: - self.maskedLabel.set_label(reason) - - if pkg.is_testing(use_keywords = False) and not pkg.is_testing(use_keywords = True): - self.testingCheck.set_label("(%s)" % _("Testing")) - self.testingCheck.get_child().set_use_markup(True) - else: - self.testingCheck.set_label(_("Testing")) - - self.testingCheck.set_active(pkg.is_testing(use_keywords = False)) - - if self.doEmerge: - # set emerge-button-label - if not self.actual_package().is_installed(): - self.unmergeBtn.set_sensitive(False) - else: - self.unmergeBtn.set_sensitive(True) - - self.vb.show_all() - return True - - def cb_button_pressed (self, b, event): - """Callback for pressed checkboxes. Just quits the event-loop - no redrawing.""" - if not isinstance(b, gtk.CellRendererToggle): - b.emit_stop_by_name("button-press-event") - return True - - def cb_package_revert_clicked (self, button): - """Callback for pressed revert-button.""" - self.actual_package().remove_new_use_flags() - self.actual_package().remove_new_masked() - self.actual_package().remove_new_testing() - self.versionCombo.get_model().clear() - self.fill_version_combo() - self.cb_version_combo_changed() - if self.instantChange: - self._update_keywords(True, update = True) - return True - - def cb_package_emerge_clicked (self, button): - """Callback for pressed emerge-button. Adds the package to the EmergeQueue.""" - self._update_keywords(True) - self.main.sysNotebook.set_current_page(self.main.QUEUE_PAGE) - return True - - def cb_package_unmerge_clicked (self, button): - """Callback for pressed unmerge-button clicked. Adds the package to the UnmergeQueue.""" - self._update_keywords(False) - self.main.sysNotebook.set_current_page(self.main.QUEUE_PAGE) - return True - - def cb_testing_toggled (self, button): - """Callback for toggled testing-checkbox.""" - status = button.get_active() - - # end of recursion :) - if self.actual_package().is_testing(use_keywords = False) == status: - return False - - # if the package is not testing - don't allow to set it as such - if not self.actual_package().is_testing(use_keywords = False): - button.set_active(False) - return True - - # re-set to testing status - if not self.actual_package().is_testing(use_keywords = True): - self.actual_package().set_testing(False) - button.set_label(_("Testing")) - button.set_active(True) - else: # disable testing - self.actual_package().set_testing(True) - button.set_label("(%s)" % _("Testing")) - button.get_child().set_use_markup(True) - button.set_active(True) - - if self.instantChange: - self._update_keywords(True, update = True) - - return True - - def cb_masked_toggled (self, button): - """Callback for toggled masking-checkbox.""" - status = button.get_active() - pkg = self.actual_package() - - if pkg.is_masked(use_changed = False) == status and not pkg.is_locally_masked(): - return False - - if pkg.is_locally_masked() and status: - return False - - if not pkg.is_masked(use_changed = True): - pkg.set_masked(True) - if pkg.is_locally_masked(): - button.set_label("%s" % _("Masked")) - button.get_child().set_use_markup(True) - self.maskedLabel.set_label(_("Masked by user")) - else: - button.set_label(_("Masked")) - - button.set_active(True) - else: - locally = pkg.is_locally_masked() - pkg.set_masked(False) - if pkg.is_masked(use_changed=False) and not locally: - button.set_label("(%s)" % _("Masked")) - button.get_child().set_use_markup(True) - button.set_active(True) - else: - button.set_label(_("Masked")) - self.maskedLabel.set_label("") - - if self.instantChange: - self._update_keywords(True, update = True) - - return True - - def cb_use_flag_toggled (self, cell, path, store): - """Callback for a toggled use-flag button.""" - flag = store[path][2] - pkg = self.actual_package() - - if pkg.use_expanded(flag): # ignore expanded flags - return False - - store[path][0] = not store[path][0] - prefix = "" - if not store[path][0]: - prefix = "-" - - pkg.set_use_flag(prefix+flag) - if self.instantChange: - self._update_keywords(True, update = True) - - return True - -class MainWindow (Window): - """ - Application main window. - """ - - # NOTEBOOK PAGE CONSTANTS - ( - QUEUE_PAGE, - CONSOLE_PAGE, - LOG_PAGE - ) = range(3) - - def __init__ (self, splash = None): - """ - Build up window. - - @param splash: the splash screen =) - @type splash: SplashScreen - """ - - if splash is None: - splash = lambda x: True - - # the title - self.main_title = "Portato (%s)" % VERSION - - # main window stuff - Window.__init__(self) - self.window.set_title(self.main_title) - self.window.set_geometry_hints (self.window, max_height = gtk.gdk.screen_height(), max_width = gtk.gdk.screen_width()) - - # booleans - self.doUpdate = False - self.showAll = True # show only installed or all packages? - self.__searchChanged = False - - # installed pixbuf - self.instPixbuf = self.window.render_icon(gtk.STOCK_YES, gtk.ICON_SIZE_MENU) - - # get the logging window as soon as possible - self.logView = LogView(self.tree.get_widget("logView")) - - # config - splash(_("Loading Config")) - try: - self.cfg = Config(CONFIG_LOCATION) - except IOError, e: - io_ex_dialog(e) - raise - - self.cfg.modify_external_configs() - self.set_uri_hook(self.cfg.get("browserCmd", section = "GUI")) - gtk.about_dialog_set_url_hook(lambda *args: True) # dummy - if not set link is not set as link; if link is clicked the normal uuri_hook is called too - thus do not call browser here - - # package db - splash(_("Creating Database")) - self.db = Database() - self.db.populate() - - # set plugins and plugin-menu - splash(_("Loading Plugins")) - - plugin.load_plugins("gtk") - menus = plugin.get_plugin_queue().get_plugin_menus() - if menus: - self.tree.get_widget("pluginMenuItem").set_no_show_all(False) - pluginMenu = self.tree.get_widget("pluginMenu") - - for m in menus: - item = gtk.MenuItem(m.label) - item.connect("activate", m.call) - pluginMenu.append(item) - - splash(_("Building frontend")) - # set paned position - self.vpaned = self.tree.get_widget("vpaned") - self.vpaned.set_position(int(self.window.get_size()[1]/2)) - self.hpaned = self.tree.get_widget("hpaned") - self.hpaned.set_position(int(self.window.get_size()[0]/1.5)) - - # cat and pkg list - self.sortPkgListByName = True - self.catList = self.tree.get_widget("catList") - self.pkgList = self.tree.get_widget("pkgList") - self.build_cat_list() - self.build_pkg_list() - - # search entry - self.searchEntry = self.tree.get_widget("searchEntry") - - # queue list - self.queueList = self.tree.get_widget("queueList") - self.build_queue_list() - - # the terminal - self.console = GtkConsole() - self.termHB = self.tree.get_widget("termHB") - self.build_terminal() - - # notebooks - self.sysNotebook = self.tree.get_widget("systemNotebook") - self.pkgNotebook = self.tree.get_widget("packageNotebook") - self.set_notebook_tabpos(map(PreferenceWindow.tabpos.get, map(int, (self.cfg.get("packageTabPos", "GTK"), self.cfg.get("systemTabPos", "GTK"))))) - - # the different scrolls - ebuildScroll = self.tree.get_widget("ebuildScroll") - ebuildScroll.add(HighlightView(lambda p: p.get_ebuild_path(), ["gentoo", "sh"])) - - changelogScroll = self.tree.get_widget("changelogScroll") - changelogScroll.add(HighlightView(lambda p: os.path.join(p.get_package_path(), "ChangeLog"), ["changelog"])) - - def show_files (p): - try: - for f in p.get_files(): - yield " %s\n" % f - except IOError, e: - yield _("Error: %s") % e.strerror - - filesScroll = self.tree.get_widget("filesScroll") - filesScroll.add(InstalledOnlyView(show_files)) - - # table - self.packageTable = PackageTable(self) - - # popups - self.queuePopup = Popup("queuePopup", self, self.__file__) - self.consolePopup = Popup("consolePopup", self, self.__file__) - self.trayPopup = Popup("systrayPopup", self) - - # pause menu items - self.emergePaused = False - self.pauseItems = {} - self.pauseItems["tray"] = self.trayPopup.tree.get_widget("pauseItemTray") - self.pauseItems["popup"] = self.consolePopup.tree.get_widget("pauseItemPopup") - self.pauseItems["menu"] = self.tree.get_widget("pauseItemMenu") - - for k,v in self.pauseItems.iteritems(): - self.pauseItems[k] = (v, v.connect_after("activate", self.cb_pause_emerge(k))) - - # systray - if self.cfg.get_boolean("showSystray", "GUI"): - self.tray = gtk.status_icon_new_from_file(APP_ICON) - self.tray.connect("activate", self.cb_systray_activated) - self.tray.connect("popup-menu", lambda icon, btn, time: self.trayPopup.popup(None, None, None, btn, time)) - else: - self.tray = None - - # set emerge queue - self.queueTree = GtkTree(self.queueList.get_model()) - self.queue = EmergeQueue(console = self.console, tree = self.queueTree, db = self.db, title_update = self.title_update, threadClass = GtkThread) - - self.catList.get_selection().select_path(1) - self.pkgList.get_selection().select_path(0) - - # session - splash(_("Restoring Session")) - try: - try: - self.load_session() - except OldSessionException, e: - self.load_session(e) - except SessionException, e: - warning(str(e)) - - splash(_("Finishing startup")) - - self.window.show_all() - - def show_package (self, *args, **kwargs): - self.packageTable.update(*args, **kwargs) - - def build_terminal (self): - """ - Builds the terminal. - """ - - self.console.set_scrollback_lines(1024) - self.console.set_scroll_on_output(True) - self.console.set_font_from_string(self.cfg.get("consolefont", "GTK")) - self.console.connect("button-press-event", self.cb_right_click) - self.termHB.pack_start(self.console, True, True) - - # add scrollbar - termScroll = gtk.VScrollbar(self.console.get_adjustment()) - self.termHB.pack_start(termScroll, False) - - def build_queue_list (self): - """ - Builds the queue list. - """ - - store = gtk.TreeStore(str,str,bool) - - self.queueList.set_model(store) - - cell = gtk.CellRendererText() - col = gtk.TreeViewColumn(_("Queue"), cell, markup = 0) - self.queueList.append_column(col) - - col = gtk.TreeViewColumn(_("Options"), cell, markup = 1) - self.queueList.append_column(col) - - def build_cat_list (self): - """ - Builds the category list. - """ - - store = gtk.ListStore(str) - - self.catList.set_model(store) - cell = gtk.CellRendererText() - col = gtk.TreeViewColumn(_("Categories"), cell, text = 0) - self.catList.append_column(col) - - self.fill_cat_store(store) - self.catList.get_selection().connect("changed", self.cb_cat_list_selection) - - def fill_cat_store (self, store): - """ - Fills the category store with data. - - @param store: the store to fill - @type store: gtk.ListStore - """ - - cats = self.db.get_categories(installed = not self.showAll) - - for p in cats: - store.append([p]) - - # sort them alphabetically - store.set_sort_column_id(0, gtk.SORT_ASCENDING) - - def build_pkg_list (self, name = None): - """ - Builds the package list. - - @param name: name of the selected catetegory - @type name: string - """ - - store = gtk.ListStore(gtk.gdk.Pixbuf, str, str) - self.fill_pkg_store(store,name) - - # build view - self.pkgList.set_model(store) - - col = gtk.TreeViewColumn(_("Packages")) - col.set_clickable(True) - col.connect("clicked", self.cb_pkg_list_header_clicked) - - # adding the pixbuf - cell = gtk.CellRendererPixbuf() - col.pack_start(cell, False) - col.add_attribute(cell, "pixbuf", 0) - - # adding the package name - cell = gtk.CellRendererText() - col.pack_start(cell, True) - col.add_attribute(cell, "text", 1) - - self.pkgList.append_column(col) - - self.pkgList.get_selection().connect("changed", self.cb_pkg_list_selection) - - def fill_pkg_store (self, store, name = None): - """ - Fills a given ListStore with the packages in a category. - - @param store: the store to fill - @type store: gtk.ListStore - @param name: the name of the category - @type name: string - """ - - if name: - for cat, pkg, is_inst in self.db.get_cat(name, self.sortPkgListByName): - if is_inst: - icon = self.instPixbuf - elif not self.showAll: - continue # ignore not installed packages - else: - icon = None - store.append([icon, pkg, cat]) - - def refresh_stores (self): - """ - Refreshes the category and package stores. - """ - store = self.catList.get_model() - store.clear() - self.fill_cat_store(store) - - store = self.pkgList.get_model() - store.clear() - try: - self.fill_pkg_store(store, self.selCatName) - except AttributeError: # no selCatName -> so no category selected --> ignore - debug("No category selected --> should be no harm.") - - def load_session(self, sessionEx = None): - """ - Loads the session data. - """ - try: - self.session = Session("gtk_session.cfg") - except (OSError, IOError), e: - io_ex_dialog(e) - return - - oldVersion = SESSION_VERSION - allowedVersions = (0,) - - if sessionEx and isinstance(sessionEx, SessionException): - if sessionEx.got in allowedVersions: - info(_("Translating session from version %d to %d.") % (sessionEx.got, sessionEx.expected)) - oldVersion = sessionEx.got - else: - warning(_("Cannot translate session from version %d to %d.") % (sessionEx.got, sessionEx.expected)) - raise sessionEx - - # - # the callbacks for the different session variables - # - - # QUEUE - def load_queue (merge, unmerge, oneshot): - def _load(q, **kwargs): - if q: - for i in q.split(","): - self.queue.append(i, **kwargs) - - _load(merge) - _load(unmerge, unmerge = True) - _load(oneshot, oneshot = True) - - def save_queue (): - if self.__save_queue: - return (",".join(self.queue.mergequeue), ",".join(self.queue.unmergequeue), ",".join(self.queue.oneshotmerge)) - else: - return ("", "", "") - - # PANED - def load_paned (*pos): - pos = map(int, pos) - [x.set_position(p) for x,p in zip((self.vpaned, self.hpaned), pos)] - - def save_paned (): - return [x.get_position() for x in (self.vpaned, self.hpaned)] - - # SELECTION - def load_selection (list, col): - def _load (name): - pos = "0" # default - - if name: - for cname, path in ((x[col], x.path) for x in list.get_model()): - if cname == name: - pos = path - - list.get_selection().select_path(pos) - list.scroll_to_cell(pos) - - return _load - - def save_pkg_selection (): - store, iter = self.pkgList.get_selection().get_selected() - if iter: - return store.get_value(iter, 1) - else: - return "" - - def save_cat_selection (): - # try to find the correct category using the pkgList selection - # so we do not select ALL =) - # if no package has been selected - return selCatName - store, iter = self.pkgList.get_selection().get_selected() - if iter: - return store.get_value(iter, 2) - else: - return self.selCatName - - # PLUGIN - def load_plugin (p): - def _load(val): - if val: - p.status = int(val)*2 - - return _load - - def save_plugin (p): - def _save (): - stat_on = p.status >= p.STAT_ENABLED - hard_on = not p.get_option("disabled") - - if stat_on != hard_on: - return int(stat_on) - else: - return "" - return _save - - # SESSION VERSION - def load_session_version (version): - if oldVersion != SESSION_VERSION: # we are trying to convert - return - - version = int(version) - - if version < SESSION_VERSION: - raise OldSessionException(version, SESSION_VERSION) - elif version > SESSION_VERSION: - raise NewSessionException(version, SESSION_VERSION) - - # set the simple ones :) - map(self.session.add_handler,[ - ([("gtksessionversion", "session")], load_session_version, lambda: SESSION_VERSION), - ([("width", "window"), ("height", "window")], lambda w,h: self.window.resize(int(w), int(h)), self.window.get_size), - ([("vpanedpos", "window"), ("hpanedpos", "window")], load_paned, save_paned), - ([("catsel", "window")], load_selection(self.catList, 0), save_cat_selection), - ([("pkgsel", "window")], load_selectio