--- old/src/gui/Makefile 2008-09-17 01:13:54.975314692 +0100
+++ new/src/gui/Makefile 2008-09-17 01:13:54.781143783 +0100
@@ -52,10 +52,12 @@
modules/remove.py \
modules/enumerations.py \
modules/filelist.py \
+ modules/beadmin.py \
modules/thread.py
PYCMODS = $(PYMODS:%.py=%.pyc)
ICONS = \
+ data/icons/status_checkmark.png \
data/icons/new_update.png
GLADEICONS = \
Binary files /dev/null and new/src/gui/data/icons/status_checkmark.png differ
--- old/src/gui/data/packagemanager.glade 2008-09-17 01:13:56.799839742 +0100
+++ new/src/gui/data/packagemanager.glade 2008-09-17 01:13:56.595646729 +0100
@@ -1,6 +1,6 @@
-
+
GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
@@ -29,6 +29,20 @@
True
GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+
+
+
+
+
+
+
+ 600
+ 500
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+ Boot Environment Management
+ True
+ GTK_WIN_POS_CENTER_ON_PARENT
+ GDK_WINDOW_TYPE_HINT_DIALOG
+ mainwindow
+ False
+
+
+
+ True
+ 2
+
+
+ True
+ 2
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ 0
+ 10
+ 2
+ <b>Manage Your Boot Environments</b>
+ True
+
+
+ False
+
+
+
+
+ 575
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ 0
+ 10
+ 4
+ In some cases, when Update action is performed, a new Boot Environment is created.
+ True
+ True
+
+
+ False
+ 1
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ 0
+ 10
+ 4
+ By managing Boot Environments you may:
+ True
+
+
+ False
+ 2
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ 0
+ 20
+ - Delete old Boot Environments to free up disk space.
+- Set the Active BE for next reboot.
+ True
+
+
+ False
+ 3
+
+
+
+
+ True
+
+
+
+
+
+ False
+ 5
+ 4
+
+
+
+
+ True
+ True
+ GTK_POLICY_AUTOMATIC
+ GTK_POLICY_AUTOMATIC
+
+
+ True
+ True
+ True
+ False
+
+
+
+
+ 5
+
+
+
+
+ True
+
+
+ True
+ 5
+ gtk-missing-image
+
+
+ False
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ 0
+ 10
+ 4
+ Currently Active Boot Environment
+ True
+
+
+ False
+ 1
+
+
+
+
+ False
+ 2
+ 6
+
+
+
+
+ True
+
+
+ False
+ 7
+
+
+
+
+ 1
+
+
+
+
+ True
+ GTK_BUTTONBOX_END
+
+
+ True
+ True
+ True
+ Cancel
+ 0
+
+
+
+
+
+ True
+ False
+ True
+ True
+ Reset
+ 0
+
+
+
+ 1
+
+
+
+
+ True
+ True
+ True
+ Ok
+ 0
+
+
+
+ 2
+
+
+
+
+ False
+ GTK_PACK_END
+
+
+
+
+
+
+ 5
+ Edit Repository
+ True
+ GTK_WIN_POS_CENTER_ON_PARENT
+ GDK_WINDOW_TYPE_HINT_DIALOG
+ mainwindow
+ 0.99999999977648257
+ False
+
+
+ True
+ 2
+
+
+ True
+
+
+ True
+
+
+ True
+ 0
+ 0
+ 10
+ 2
+ <b>Edit Repositories</b>
+ True
+
+
+
+
+ True
+ 0
+ 0
+ 10
+ 4
+ Enter the complete PKG line of the repository you want to add as a source
+and give it a name.
+
+
+ 1
+
+
+
+
+ True
+
+
+ True
+ 0
+ 0
+ 10
+ 4
+ Name:
+
+
+ False
+ 3
+
+
+
+
+ True
+ True
+
+
+ 3
+ 1
+
+
+
+
+ True
+ 0
+ GTK_SHADOW_NONE
+
+
+ True
+ 75
+
+
+
+
+
+
+
+ True
+ True
+
+
+ label_item
+
+
+
+
+ False
+ False
+ 45
+ 2
+
+
+
+
+ 2
+
+
+
+
+ True
+
+
+ True
+ 0
+ 0
+ 9
+ 4
+ URL:
+
+
+ False
+ 5
+
+
+
+
+ True
+ True
+
+
+ 4
+ 1
+
+
+
+
+ True
+ 0
+ GTK_SHADOW_NONE
+
+
+ True
+ 0
+
+
+ True
+
+
+ True
+ True
+ True
+ Add
+ 0
+
+
+ False
+ False
+
+
+
+
+
+
+
+
+
+ label_item
+
+
+
+
+ False
+ False
+ 5
+ 2
+
+
+
+
+ 3
+
+
+
+
+ False
+ False
+
+
+
+
+ True
+
+
+ False
+ 4
+ 1
+
+
+
+
+ True
+
+
+ True
+ True
+ GTK_POLICY_AUTOMATIC
+ GTK_POLICY_AUTOMATIC
+
+
+ True
+ True
+
+
+
+
+
+
+ True
+
+
+ True
+ 0
+ GTK_SHADOW_NONE
+
+
+ True
+ 0
+ 6
+
+
+ True
+
+
+ True
+ True
+ True
+ Remove
+ 0
+
+
+ False
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+ label_item
+
+
+
+
+
+
+ True
+ 0
+ GTK_SHADOW_NONE
+
+
+ True
+ 12
+
+
+
+
+
+
+
+
+ label_item
+
+
+
+
+ 1
+
+
+
+
+ True
+ 0
+ GTK_SHADOW_NONE
+
+
+ True
+ 12
+
+
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ True
+
+
+ label_item
+
+
+
+
+ 2
+
+
+
+
+ False
+ False
+ 1
+
+
+
+
+ 2
+
+
+
+
+ True
+
+
+ False
+ 4
+ 3
+
+
+
+
+ 1
+
+
+
+
+ True
+ GTK_BUTTONBOX_END
+
+
+ True
+ True
+ True
+ Cancel
+ 0
+
+
+
+
+ True
+ True
+ True
+ Reset
+ 0
+
+
+ 1
+
+
+
+
+ True
+ True
+ True
+ OK
+ 0
+
+
+ 2
+
+
+
+
+ False
+ GTK_PACK_END
+
+
+
+
+
+
+ 400
+ 400
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+ BE Management Changes Confirmation
+ True
+ GTK_WIN_POS_CENTER_ON_PARENT
+ GDK_WINDOW_TYPE_HINT_DIALOG
+ False
+ beadmin
+ False
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 10
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ gtk-dialog-warning
+ 5
+
+
+ False
+ False
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ 0
+ Review the Boot Environments to change
+Click OK to proceed
+ True
+ True
+
+
+ 1
+
+
+
+
+ False
+ 15
+ 1
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ 0
+ <b>Boot Environments to be deleted:</b>
+ True
+
+
+ False
+ 2
+
+
+
+
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ GTK_POLICY_AUTOMATIC
+ GTK_POLICY_AUTOMATIC
+
+
+ True
+ False
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ False
+ True
+ False
+
+
+
+
+ 6
+ 3
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ 0
+ <b>Active Boot Environment changed to:</b>
+ True
+
+
+ False
+ 4
+
+
+
+
+ True
+ False
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ 0
+
+
+ True
+
+
+ False
+ 5
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ 0
+ <b>Summary</b>
+ True
+
+
+ False
+ 6
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ 0
+ True
+
+
+ False
+ 7
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+
+
+ False
+ 5
+ 8
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ GTK_BUTTONBOX_END
+
+
+ True
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ Cancel
+ 0
+
+
+
+
+
+ True
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ OK
+ 0
+
+
+
+ 1
+
+
+
+
+ False
+ GTK_PACK_END
+
+
+
+
+
--- old/src/gui/modules/__init__.py 2008-09-17 01:13:58.410045507 +0100
+++ new/src/gui/modules/__init__.py 2008-09-17 01:13:58.209799312 +0100
@@ -23,4 +23,4 @@
# Use is subject to license terms.
#
-__all__ = ['installupdate', 'enumerations', 'filelist', 'thread', 'remove', 'imageinfo']
+__all__ = ['installupdate', 'enumerations', 'filelist', 'thread', 'remove', 'imageinfo', 'beadmin']
--- /dev/null 2008-09-17 01:13:59.000000000 +0100
+++ new/src/gui/modules/beadmin.py 2008-09-17 01:13:59.349325110 +0100
@@ -0,0 +1,546 @@
+#!/usr/bin/python2.4
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+import sys
+import subprocess
+import pango
+import time
+import datetime
+from threading import Thread
+
+try:
+ import gobject
+ gobject.threads_init()
+ import gtk
+ import gtk.glade
+ import pygtk
+ pygtk.require("2.0")
+except ImportError:
+ sys.exit(1)
+
+nobe = False
+
+try:
+ import libbe as be
+except ImportError:
+ # All actions are disabled when libbe can't be imported.
+ nobe = True
+import pkg.misc
+
+class Beadmin:
+ def __init__(self, parent):
+ if nobe:
+ msg = self.parent._("The libbe library was not " + \
+ "found on your system." + \
+ "\nAll functions for managing Boot Environments are disabled")
+ msgbox = gtk.MessageDialog(
+ buttons = gtk.BUTTONS_CLOSE, \
+ flags = gtk.DIALOG_MODAL, type = gtk.MESSAGE_INFO, \
+ message_format = None)
+ msgbox.set_markup(msg)
+ msgbox.set_title(self.parent._("BE management"))
+ result = msgbox.run()
+ msgbox.destroy()
+ return
+
+ self.parent = parent
+
+ self.be_list = \
+ gtk.ListStore(
+ gobject.TYPE_INT, # BE_ID
+ gobject.TYPE_BOOLEAN, # BE_MARK
+ gobject.TYPE_STRING, # BE_NAME
+ gobject.TYPE_STRING, # BE_DATE_TIME
+ gtk.gdk.Pixbuf, # BE_CURRENT
+ gobject.TYPE_BOOLEAN, # BE_DEFAULT
+ gobject.TYPE_STRING, # BE_SIZE
+ )
+ self.progress_stop_thread = False
+ self.initial_active = 0
+ self.initial_default = 0
+ w_tree_beadmin = gtk.glade.XML(parent.gladefile, "beadmin")
+ w_tree_progress = gtk.glade.XML(parent.gladefile, "progressdialog")
+ w_tree_beconfirmation = gtk.glade.XML(parent.gladefile, \
+ "beconfirmationdialog")
+ self.w_beadmin_dialog = w_tree_beadmin.get_widget("beadmin")
+ self.w_be_treeview = w_tree_beadmin.get_widget("betreeview")
+ self.w_cancel_button = w_tree_beadmin.get_widget("cancelbebutton")
+ self.w_reset_button = w_tree_beadmin.get_widget("resetbebutton")
+ w_active_gtkimage = w_tree_beadmin.get_widget("activebeimage")
+ self.w_progress_dialog = w_tree_progress.get_widget("progressdialog")
+ self.w_progressinfo_label = w_tree_progress.get_widget("progressinfo")
+ progress_button = w_tree_progress.get_widget("progresscancel")
+ self.w_progressbar = w_tree_progress.get_widget("progressbar")
+ self.w_beconfirmation_dialog = \
+ w_tree_beconfirmation.get_widget("beconfirmationdialog")
+ self.w_beconfirmation_treeview = \
+ w_tree_beconfirmation.get_widget("beconfirmtreeview")
+ self.w_beconfirmationdefault_label = \
+ w_tree_beconfirmation.get_widget("beconfirmationdefault")
+ self.w_beconfirmationsummary_label = \
+ w_tree_beconfirmation.get_widget("beconfirmationsummary")
+ self.w_cancelbe_button = w_tree_beconfirmation.get_widget("cancel_be")
+ progress_button.hide()
+ self.w_progressbar.set_pulse_step(0.1)
+ self.list_filter = self.be_list.filter_new()
+ self.w_be_treeview.set_model(self.list_filter)
+ self.__init_tree_views()
+ treestore = gtk.ListStore(gobject.TYPE_STRING)
+ self.w_beconfirmation_treeview.set_model(treestore)
+ cell = gtk.CellRendererText()
+ be_column = gtk.TreeViewColumn('BE', cell, text = 0)
+ self.w_beconfirmation_treeview.append_column(be_column)
+ self.active_image = self.parent.get_icon_pixbuf("status_checkmark")
+ w_active_gtkimage.set_from_pixbuf(self.active_image)
+
+ try:
+ dic = \
+ {
+ "on_cancel_be_clicked": \
+ self.__on_cancel_be_clicked,
+ "on_reset_be_clicked": \
+ self.__on_reset_be_clicked,
+ "on_ok_be_clicked": \
+ self.__on_ok_be_clicked,
+ }
+ dic_conf = \
+ {
+ "on_cancel_be_conf_clicked": \
+ self.__on_cancel_be_conf_clicked,
+ "on_ok_be_conf_clicked": \
+ self.__on_ok_be_conf_clicked,
+ }
+ w_tree_beadmin.signal_autoconnect(dic)
+ w_tree_beconfirmation.signal_autoconnect(dic_conf)
+ except AttributeError, error:
+ print self.parent._('GUI will not respond to any event! %s. \
+ Check beadmin.py signals') \
+ % error
+ Thread(target = self.__progress_pulse).start()
+ Thread(target = self.__prepare_beadmin_list).start()
+ sel = self.w_be_treeview.get_selection()
+ self.w_cancel_button.grab_focus()
+ sel.set_mode(gtk.SELECTION_NONE)
+ sel = self.w_beconfirmation_treeview.get_selection()
+ sel.set_mode(gtk.SELECTION_NONE)
+ self.w_beadmin_dialog.show_all()
+ self.w_progress_dialog.set_title(\
+ self.parent._("Loading Boot Environment Information"))
+ self.w_progressinfo_label.set_text(\
+ self.parent._("Fetching BE entries..."))
+ self.be_destroy_supports_capital_f = \
+ self.__check_if_be_supports_capital_f()
+ self.w_progress_dialog.show()
+
+ def __progress_pulse(self):
+ while not self.progress_stop_thread:
+ gobject.idle_add(self.w_progressbar.pulse)
+ time.sleep(0.1)
+ gobject.idle_add(self.w_progress_dialog.hide)
+
+ def __prepare_beadmin_list(self):
+ be_list = be.beList()
+ gobject.idle_add(self.__create_view_with_be, be_list)
+ self.progress_stop_thread = True
+ return
+
+ def __init_tree_views(self):
+ model = self.w_be_treeview.get_model()
+
+ column = gtk.TreeViewColumn()
+ column.set_title("")
+ render_pixbuf = gtk.CellRendererPixbuf()
+ column.pack_start(render_pixbuf, expand = True)
+ column.add_attribute(render_pixbuf, "pixbuf", 4) # BE_CURRENT
+ self.w_be_treeview.append_column(column)
+
+ name_renderer = gtk.CellRendererText()
+ column = gtk.TreeViewColumn(self.parent._("Boot Environment"), \
+ name_renderer, text = 2) # 2 = BE_NAME
+ column.set_cell_data_func(name_renderer, self.__cell_data_function, None)
+ column.set_expand(True)
+ self.w_be_treeview.append_column(column)
+
+ datetime_renderer = gtk.CellRendererText()
+ datetime_renderer.set_property('xalign', 0.0)
+ column = gtk.TreeViewColumn(self.parent._("Created"), datetime_renderer, \
+ text = 3) # 3 = BE_DATE_TIME
+ column.set_cell_data_func(datetime_renderer, \
+ self.__cell_data_function, None)
+ column.set_expand(True)
+ self.w_be_treeview.append_column(column)
+
+ size_renderer = gtk.CellRendererText()
+ size_renderer.set_property('xalign', 1.0)
+ column = gtk.TreeViewColumn(self.parent._("Size"), size_renderer, \
+ text = 6) # 6 = BE_SIZE
+ column.set_cell_data_func(size_renderer, self.__cell_data_function, None)
+ column.set_expand(False)
+ self.w_be_treeview.append_column(column)
+
+ radio_renderer = gtk.CellRendererToggle()
+ radio_renderer.connect('toggled', self.__active_pane_default, model)
+ column = gtk.TreeViewColumn(self.parent._("Active on Reboot"), \
+ radio_renderer, active = 5) # 1 = BE_MARK
+ radio_renderer.set_property("activatable", True)
+ radio_renderer.set_property("radio", True)
+ column.set_cell_data_func(radio_renderer, \
+ self.__cell_data_default_function, None)
+ column.set_expand(False)
+ self.w_be_treeview.append_column(column)
+
+ toggle_renderer = gtk.CellRendererToggle()
+ toggle_renderer.connect('toggled', self.__active_pane_toggle, model)
+ column = gtk.TreeViewColumn(self.parent._("Delete"), toggle_renderer, \
+ active = 1) # 1 = BE_MARK
+ toggle_renderer.set_property("activatable", True)
+ column.set_cell_data_func(toggle_renderer, \
+ self.__cell_data_delete_function, None)
+ column.set_expand(False)
+ self.w_be_treeview.append_column(column)
+
+ def __on_reset_be_clicked(self, widget):
+ self.be_list.clear()
+ self.w_progress_dialog.show()
+ self.progress_stop_thread = False
+ Thread(target = self.__progress_pulse).start()
+ Thread(target = self.__prepare_beadmin_list).start()
+ self.__enable_disable_reset()
+
+ def __on_ok_be_clicked(self, widget):
+ self.w_progress_dialog.set_title(self.parent._("Applying changes"))
+ self.w_progressinfo_label.set_text(\
+ self.parent._("Applying changes, please wait ..."))
+ if self.w_reset_button.get_property('sensitive') == 0:
+ self.progress_stop_thread = True
+ self.__on_beadmin_delete_event(None, None)
+ return
+ Thread(target = self.__activate).start()
+
+ def __on_cancel_be_clicked(self, widget):
+ self.__on_beadmin_delete_event(None, None)
+
+ def __on_cancel_be_conf_clicked(self, widget):
+ self.w_beconfirmation_dialog.hide()
+
+ def __on_ok_be_conf_clicked(self, widget):
+ self.w_beconfirmation_dialog.hide()
+ self.progress_stop_thread = False
+ Thread(target = self.__on_progressdialog_progress).start()
+ Thread(target = self.__delete_activate_be).start()
+
+ def __on_beadmin_delete_event(self, widget, event):
+ self.w_beadmin_dialog.destroy()
+ return True
+
+ def __activate(self):
+ to_delete = []
+ default = None
+ treestore = self.w_beconfirmation_treeview.get_model()
+ treestore.clear()
+ first = True
+ for row in self.be_list:
+ if row[1]:
+ treestore.append([row[2]])
+ if first:
+ self.w_beconfirmation_treeview.set_sensitive(True)
+ first = False
+ if row[5] == True and row[0] != self.initial_default:
+ default = row[2]
+ summary_text = ""
+ be_change_no = len(treestore)
+ if be_change_no == 0:
+ treestore.append([self.parent._("No change")])
+ self.w_beconfirmation_treeview.set_sensitive(False)
+ else:
+ summary_text += \
+ self.parent._("%d BE's will be deleted") % be_change_no
+
+ if default:
+ self.w_beconfirmationdefault_label.set_text(default+"\n")
+ self.w_beconfirmationdefault_label.set_sensitive(True)
+ if be_change_no > 0:
+ summary_text += "\n"
+ summary_text += \
+ self.parent._("The Active BE will be changed upon reboot")
+ else:
+ self.w_beconfirmationdefault_label.set_sensitive(False)
+ self.w_beconfirmationdefault_label.set_text(\
+ self.parent._("No change\n"))
+ self.w_beconfirmationsummary_label.set_text(summary_text)
+ self.w_beconfirmation_treeview.expand_all()
+ self.w_cancelbe_button.grab_focus()
+ self.w_beconfirmation_dialog.show()
+ self.progress_stop_thread = True
+
+ def __on_progressdialog_progress(self):
+ # This needs to be run in gobject.idle_add, otherwise we will get
+ # Xlib: unexpected async reply (sequence 0x2db0)!
+ gobject.idle_add(self.w_progress_dialog.show)
+ while not self.progress_stop_thread:
+ gobject.idle_add(self.w_progressbar.pulse)
+ time.sleep(0.1)
+ gobject.idle_add(self.w_progress_dialog.hide)
+
+ def __delete_activate_be(self):
+ not_deleted = []
+ not_default = None
+ for row in self.be_list:
+ if row[1]:
+ succeed = self.__destroy_be(row[2])
+ if succeed == 1:
+ not_deleted.append(row[2])
+ for row in self.be_list:
+ if row[5] == True and row[0] != self.initial_default:
+ succeed = self.__set_default_be(row[2])
+ if succeed == 1:
+ not_default = row[2]
+ if len(not_deleted) == 0 and not_default == None:
+ self.progress_stop_thread = True
+ else:
+ self.progress_stop_thread = True
+ msg = ""
+ if not_default:
+ msg += self.parent._("Couldn't change Active " + \
+ "Boot Environment to:\n") + not_default
+ if len(not_deleted) > 0:
+ if not_default:
+ msg+= "\n\n"
+ msg += self.parent._("Couldn't delete Boot " + \
+ "Environments:\n")
+ for row in not_deleted:
+ msg += row + "\n"
+ gobject.idle_add(self.__error_occured, msg)
+ return
+ self.__on_beadmin_delete_event(None, None)
+
+ def __error_occured(self, error_msg, reset=True):
+ msg = error_msg
+ msgbox = gtk.MessageDialog(parent = self.w_beadmin_dialog, \
+ buttons = gtk.BUTTONS_CLOSE, \
+ flags = gtk.DIALOG_MODAL, type = gtk.MESSAGE_ERROR, \
+ message_format = None)
+ msgbox.set_markup(msg)
+ msgbox.set_title("BE error")
+ result = msgbox.run()
+ msgbox.destroy()
+ if reset:
+ self.__on_reset_be_clicked(None)
+
+ def __active_pane_toggle(self, cell, filtered_path, filtered_model):
+ model = filtered_model.get_model()
+ path = filtered_model.convert_path_to_child_path(filtered_path)
+ itr = model.get_iter(path)
+ if itr:
+ modified = model.get_value(itr, 1)
+ model.set_value(itr, 1, \
+ not modified)
+ self.__enable_disable_reset()
+
+ def __enable_disable_reset(self):
+ for row in self.be_list:
+ if row[1] == True:
+ self.w_reset_button.set_sensitive(True)
+ return
+ self.initial_default
+ self.initial_active
+ if row[0] == self.initial_default:
+ if row[5] == False:
+ self.w_reset_button.set_sensitive(True)
+ return
+ self.w_reset_button.set_sensitive(False)
+ return
+
+ def __active_pane_default(self, cell, filtered_path, filtered_model):
+ model = filtered_model.get_model()
+ path = filtered_model.convert_path_to_child_path(filtered_path)
+ for row in model:
+ row[5] = False
+ itr = model.get_iter(path)
+ if itr:
+ modified = model.get_value(itr, 5)
+ model.set_value(itr, 5, \
+ not modified)
+ self.__enable_disable_reset()
+
+ def __create_view_with_be(self, be_list):
+ dates = None
+ i = 0
+ j = 0
+ error_code = None
+ be_list_loop = None
+ if len(be_list) > 1 and type(be_list[0]) == type(-1):
+ error_code = be_list[0]
+ if error_code != None and error_code == 0:
+ be_list_loop = be_list[1]
+ elif error_code != None and error_code != 0:
+ msg = self.parent._("The libbe library couldn't " + \
+ "prepare list of Boot Environments." + \
+ "\nAll functions for managing Boot Environments are disabled")
+ gobject.idle_add(self.__error_occured, msg, False)
+ return
+ else:
+ be_list_loop = be_list
+
+ for bee in be_list_loop:
+ if bee.get("orig_be_name"):
+ name = bee.get("orig_be_name")
+ active = bee.get("active")
+ active_boot = bee.get("active_boot")
+ be_size = bee.get("space_used")
+ be_date = bee.get("date")
+ converted_size = \
+ self.__convert_size_of_be_to_string(be_size)
+ active_img = None
+ if not be_date and j == 0:
+ dates = self.__get_dates_of_creation(be_list_loop)
+ if dates:
+ try:
+ date_time = repr(dates[i])[1:-3]
+ date_tmp = time.strptime(date_time, \
+ "%a %b %d %H:%M %Y")
+ date_tmp2 = \
+ datetime.datetime(*date_tmp[0:5])
+ date_time = \
+ date_tmp2.strftime("%m/%d/%y %H:%M")
+ i += 1
+ except:
+ date_time = None
+ else:
+ date_tmp = time.gmtime(be_date)
+ date_time = time.strftime("%m/%d/%y %H:%M", date_tmp)
+ if active:
+ active_img = self.active_image
+ self.initial_active = j
+ if active_boot:
+ self.initial_default = j
+ self.be_list.insert(j, [j, False, \
+ name, \
+ date_time, active_img, \
+ active_boot, converted_size])
+ j += 1
+ self.w_be_treeview.set_cursor(self.initial_active, None, \
+ start_editing=True)
+ self.w_be_treeview.scroll_to_cell(self.initial_active)
+
+ def __convert_size_of_be_to_string(self, be_size):
+ if not be_size:
+ be_size = 0
+ return pkg.misc.bytes_to_str(be_size)
+
+ def __get_dates_of_creation(self, be_list):
+ #zfs list -H -o creation rpool/ROOT/opensolaris-1
+ cmd = [ "/sbin/zfs", "list", "-H", "-o","creation" ]
+ for bee in be_list:
+ if bee.get("orig_be_name"):
+ name = bee.get("orig_be_name")
+ pool = bee.get("orig_be_pool")
+ cmd += [pool+"/ROOT/"+name]
+ if len(cmd) <= 5:
+ return None
+ list_of_dates = []
+ try:
+ proc = subprocess.Popen(cmd, stdout = subprocess.PIPE, \
+ stderr = subprocess.PIPE,)
+ line_out = proc.stdout.readline()
+ while line_out:
+ list_of_dates.append(line_out)
+ line_out = proc.stdout.readline()
+ except OSError, e:
+ pass
+ return list_of_dates
+
+ def __destroy_be(self, be_name):
+ cmd = [ "/sbin/beadm", "destroy", "-F", be_name ]
+ if not self.be_destroy_supports_capital_f:
+ cmd = [ "/sbin/beadm", "destroy", "-f", be_name ]
+ return self.__beadm_invoke_command(cmd)
+
+ def __set_default_be(self, be_name):
+ cmd = [ "/sbin/beadm", "activate", be_name ]
+ return self.__beadm_invoke_command(cmd)
+
+ def __beadm_invoke_command(self, cmd):
+ try:
+ # Subprocess platform specific, but beadm is only on Solars so we
+ # can use it...
+ stdouterr = open('/dev/null', 'w')
+ returncode = subprocess.call(cmd, stdout = stdouterr, \
+ stderr = stdouterr,)
+ except OSError, e:
+ returncode = 1
+ return returncode
+
+ def __check_if_be_supports_capital_f(self):
+ '''The beadmin command changed arguments and before build 86 to supress
+ the prompt back for the destroy operation we had to used -f instead of
+ -F. This function should return True only when the old beadm is used.'''
+ supports_capital_f = True
+ try:
+ cmd = [ "/sbin/beadm" ]
+ stdout = open('/dev/null', 'w')
+ stderr = subprocess.Popen(cmd, stdout = stdout, \
+ stderr=subprocess.PIPE).stderr
+ out = stderr.read().split('\n')
+ for line in out:
+ if "beadm destroy" in line:
+ if "[-f]" in line:
+ supports_capital_f = False
+ except OSError, e:
+ pass
+ return supports_capital_f
+
+
+
+ def __cell_data_default_function(self, column, renderer, model, itr, data):
+ if itr:
+ if model.get_value(itr, 1):
+ self.__set_renderer_active(renderer, False)
+ else:
+ self.__set_renderer_active(renderer, True)
+
+ def __cell_data_delete_function(self, column, renderer, model, itr, data):
+ if itr:
+ if model.get_value(itr, 5) or (self.initial_active == \
+ model.get_value(itr, 0)):
+ self.__set_renderer_active(renderer, False)
+ else:
+ self.__set_renderer_active(renderer, True)
+
+
+ def __set_renderer_active(self, renderer, active):
+ if active:
+ renderer.set_property("sensitive", True)
+ renderer.set_property("mode", gtk.CELL_RENDERER_MODE_ACTIVATABLE)
+ else:
+ renderer.set_property("sensitive", False)
+ renderer.set_property("mode", gtk.CELL_RENDERER_MODE_INERT)
+
+ def __cell_data_function(self, column, renderer, model, itr, data):
+ if itr:
+ if model.get_value(itr, 4):
+ renderer.set_property("weight", pango.WEIGHT_BOLD)
+ else:
+ renderer.set_property("weight", pango.WEIGHT_NORMAL)
--- old/src/packagemanager.py 2008-09-17 01:14:00.713459839 +0100
+++ new/src/packagemanager.py 2008-09-17 01:14:00.250090974 +0100
@@ -59,6 +59,7 @@
import pkg.client.progress as progress
import pkg.misc as misc
import pkg.portable as portable
+import pkg.gui.beadmin as beadm
import pkg.gui.imageinfo as imageinfo
import pkg.gui.installupdate as installupdate
import pkg.gui.remove as remove
@@ -226,6 +227,7 @@
self.__on_repositorycombobox_changed,
#menu signals
"on_file_quit_activate":self.__on_file_quit_activate,
+ "on_file_be_activate":self.__on_file_be_activate,
"on_package_install_update_activate": \
self.__on_install_update,
"on_package_remove_activate":self.__on_remove,
@@ -429,6 +431,10 @@
''' handler for quit menu event '''
self.__on_mainwindow_delete_event(None, None)
+ def __on_file_be_activate(self, widget):
+ ''' handler for be menu event '''
+ beadm.Beadmin(self)
+
def __on_searchentry_changed(self, widget):
'''On text search field changed we should refilter the main view'''
Thread(target = self.__on_searchentry_threaded, args = ()).start()
@@ -1222,7 +1228,7 @@
# but here for completeness.
raise
#Only one instance of those icons should be in memory
- update_available_icon = self.__get_icon_pixbuf("new_update")
+ update_available_icon = self.get_icon_pixbuf("new_update")
#Imageinfo for categories
imginfo = imageinfo.ImageInfo()
sectioninfo = imageinfo.ImageInfo()
@@ -1452,11 +1458,6 @@
enumerations. \
SECTION_ID])
- def __get_icon_pixbuf(self, icon_name):
- #2821: The __get_icon_pixbuf should use PACKAGE_MANAGER_ROOT
- return self.__get_pixbuf_from_path(self.application_dir + \
- "/usr/share/icons/package-manager/", icon_name)
-
def __get_pixbuf_from_path(self, path, icon_name):
icon = icon_name.replace(' ', '_')
@@ -1655,6 +1656,11 @@
self.w_sections_combobox.set_active(0)
self.application_list_filter.set_visible_func(self.__application_filter)
self.__setup_repositories_combobox(self.image_o)
+
+ def get_icon_pixbuf(self, icon_name):
+ #2821: The get_icon_pixbuf should use PACKAGE_MANAGER_ROOT
+ return self.__get_pixbuf_from_path(self.application_dir + \
+ "/usr/share/icons/package-manager/", icon_name)
def get_manifests_for_packages(self):
''' Function, which get's manifest for packages. If the manifest is not
@@ -1776,21 +1782,21 @@
#-----------------------------------------------------------------------------#
def fill_with_fake_data(self):
'''test data for gui'''
- app1 = [False, self.__get_icon_pixbuf("locked"), \
- self.__get_icon_pixbuf("None"), "acc", None, None, None, 4, "desc6", \
+ app1 = [False, self.get_icon_pixbuf("locked"), \
+ self.get_icon_pixbuf("None"), "acc", None, None, None, 4, "desc6", \
"Object Name1", None, True, None]
- app2 = [False, self.__get_icon_pixbuf("update_available"), \
- self.__get_icon_pixbuf(self._('All')), "acc_gam", \
+ app2 = [False, self.get_icon_pixbuf("update_available"), \
+ self.get_icon_pixbuf(self._('All')), "acc_gam", \
"2.3", None, "2.8", \
4, "desc7", "Object Name2", None, True, None]
- app3 = [False, self.__get_icon_pixbuf("None"), \
- self.__get_icon_pixbuf("Other"), "gam_grap", "2.3", None, None, 4, \
+ app3 = [False, self.get_icon_pixbuf("None"), \
+ self.get_icon_pixbuf("Other"), "gam_grap", "2.3", None, None, 4, \
"desc8", "Object Name3", None, True, None]
- app4 = [False, self.__get_icon_pixbuf("update_locked"), \
- self.__get_icon_pixbuf("Office"), "grap_gam", "2.3", None, "2.8", 4, \
+ app4 = [False, self.get_icon_pixbuf("update_locked"), \
+ self.get_icon_pixbuf("Office"), "grap_gam", "2.3", None, "2.8", 4, \
"desc9", "Object Name2", None, True, None]
- app5 = [False, self.__get_icon_pixbuf("update_available"), \
- self.__get_icon_pixbuf("None"), "grap", "2.3", None, "2.8", 4, \
+ app5 = [False, self.get_icon_pixbuf("update_available"), \
+ self.get_icon_pixbuf("None"), "grap", "2.3", None, "2.8", 4, \
"desc0", "Object Name3", None, True, None]
itr1 = self.application_list.append(app1)
itr2 = self.application_list.append(app2)
--- old/src/pkgdefs/SUNWipkg-gui/Makefile 2008-09-17 01:14:02.110684737 +0100
+++ new/src/pkgdefs/SUNWipkg-gui/Makefile 2008-09-17 01:14:01.908817118 +0100
@@ -54,7 +54,7 @@
$$5 = "root"; \
$$6 = "bin"; \
} \
- $$3 ~ /(share(\/applications\/packagemanager.desktop|\/applications|\/icons|\/icons\/package\-manager|\/icons\/package\-manager\/new_update.png))$$/ { \
+ $$3 ~ /(share(\/applications\/packagemanager.desktop|\/applications|\/icons|\/icons\/package\-manager|\/icons\/package\-manager\/new_update.png|\/icons\/package\-manager\/status_checkmark.png))$$/ { \
$$6 = "other"; \
} \
$$3 ~ /(share(\/package\-manager|\/package\-manager\/data|\/package\-manager(\/packagemanager.glade|\/PM_app_48x.png|\/PM_package_36x.png)))$$/ { \