--- a/src/packagemanager.py Fri Jul 17 14:42:45 2009 -0500
+++ b/src/packagemanager.py Sat Jul 18 01:41:10 2009 +0200
@@ -23,20 +23,6 @@
# Use is subject to license terms.
#
-# Progress:
-# Startup Progress has two phases:
-# - Start phase:
-# The start phase should be fairly constant at around a few seconds and so is given 5%
-# of the total progress bar.
-# - Package entry loading phase:
-# The package entry loading phase is given the remaining 95% of the bar for progress.
-
-INITIAL_PROGRESS_TIME_INTERVAL = 0.5 # Time to update progress during start phase
-INITIAL_PROGRESS_TIME_PERCENTAGE = 0.005 # Amount to update progress during start phase
-INITIAL_PROGRESS_TOTAL_PERCENTAGE = 0.05 # Total progress for start phase
-PACKAGE_PROGRESS_TOTAL_INCREMENTS = 95 # Total increments for loading phase
-PACKAGE_PROGRESS_PERCENT_INCREMENT = 0.01 # Amount to update progress during loading phase
-PACKAGE_PROGRESS_PERCENT_TOTAL = 1.0 # Total progress for loading phase
MAX_DESC_LEN = 60 # Max length of the description
MAX_INFO_CACHE_LIMIT = 100 # Max number of package descriptions to cache
NOTEBOOK_PACKAGE_LIST_PAGE = 0 # Main Package List page index
@@ -218,14 +204,13 @@
module.textdomain("pkg")
gui_misc.init_for_help(self.application_dir)
self.main_window_title = _('Package Manager')
+ self.gdk_window = None
self.user_rights = portable.is_admin()
self.cancelled = False # For background processes
self.image_directory = None
self.description_thread_running = False # For background processes
gtk.rc_parse('~/.gtkrc-1.2-gnome2') # Load gtk theme
- self.progress_stop_timer_thread = False
- self.progress_fraction_time_count = 0
- self.progress_canceled = False
+ self.progress_stop_thread = True
self.catalog_loaded = False
self.image_dir_arg = None
self.update_all_proceed = False
@@ -301,7 +286,6 @@
self.gladefile = os.path.join(self.application_dir,
"usr/share/package-manager/packagemanager.glade")
w_tree_main = gtk.glade.XML(self.gladefile, "mainwindow")
- w_tree_progress = gtk.glade.XML(self.gladefile, "progressdialog")
w_tree_preferences = gtk.glade.XML(self.gladefile, "preferencesdialog")
w_tree_api_search_error = gtk.glade.XML(self.gladefile,
"api_search_error")
@@ -354,9 +338,15 @@
gtk.gdk.color_parse("white"))
self.w_main_statusbar = w_tree_main.get_widget("statusbar")
+ self.w_statusbar_hbox = w_tree_main.get_widget("statusbar_hbox")
self.w_infosearch_frame = w_tree_main.get_widget("infosearch_frame")
self.w_infosearch_button = w_tree_main.get_widget("infosearch_button")
+ self.w_progress_frame = w_tree_main.get_widget("progress_frame")
+ self.w_status_progressbar = w_tree_main.get_widget("status_progressbar")
+ self.w_status_progressbar.set_pulse_step(0.1)
+ self.w_progress_frame.hide()
+
self.w_main_view_notebook = \
w_tree_main.get_widget("main_view_notebook")
self.w_searchentry = w_tree_main.get_widget("searchentry")
@@ -389,19 +379,10 @@
self.w_deselect_menuitem = w_tree_main.get_widget("edit_deselect")
self.w_clear_search_menuitem = w_tree_main.get_widget("clear")
self.w_main_clipboard = gtk.clipboard_get(gtk.gdk.SELECTION_CLIPBOARD)
- self.w_progress_dialog = w_tree_progress.get_widget("progressdialog")
- self.w_progress_dialog.connect('delete-event', lambda stub1, stub2: True)
- self.w_progress_dialog.set_title(_("Update All"))
- self.w_progressinfo_label = w_tree_progress.get_widget("progressinfo")
- self.w_progressinfo_label.set_text(_(
- "Checking SUNWipkg and SUNWipkg-gui versions\n\nPlease wait ..."))
- self.w_progressbar = w_tree_progress.get_widget("progressbar")
- self.w_progressbar.set_pulse_step(0.1)
- self.w_progress_cancel = w_tree_progress.get_widget("progresscancel")
- self.progress_canceled = False
self.saved_filter_combobox_active = self.initial_show_filter
self.search_image = w_tree_main.get_widget("search_image")
self.search_button = w_tree_main.get_widget("do_search")
+ self.progress_cancel = w_tree_main.get_widget("progress_cancel")
self.is_all_publishers = False
self.search_image.set_from_pixbuf(gui_misc.get_icon(self.icon_theme,
'search', 20))
@@ -447,6 +428,8 @@
{
"on_mainwindow_delete_event": \
self.__on_mainwindow_delete_event,
+ "on_mainwindow_check_resize": \
+ self.__on_mainwindow_check_resize,
"on_mainwindow_key_press_event": \
self.__on_mainwindow_key_press_event,
"on_searchentry_changed":self.__on_searchentry_changed,
@@ -481,6 +464,8 @@
"on_clear_search_clicked":self.__on_clear_search,
"on_do_search_clicked":self.__do_search,
"on_do_search_button_press_event":self.__do_search,
+ "on_progress_cancel_clicked": \
+ self.__on_progress_cancel_clicked,
"on_edit_select_all_activate":self.__on_select_all,
"on_edit_select_updates_activate": \
self.__on_select_updates,
@@ -501,11 +486,6 @@
"on_infosearch_button_clicked": \
self.__on_infosearch_button_clicked,
}
- dic_progress = \
- {
- "on_cancel_progressdialog_clicked": \
- self.__on_cancel_progressdialog_clicked,
- }
dic_preferences = \
{
"on_startpage_checkbutton_toggled": \
@@ -535,7 +515,6 @@
w_tree_main.signal_autoconnect(dic_mainwindow)
- w_tree_progress.signal_autoconnect(dic_progress)
w_tree_preferences.signal_autoconnect(dic_preferences)
w_tree_api_search_error.signal_autoconnect(
dic_api_search_error)
@@ -570,6 +549,7 @@
self.gdk_window = gtk.gdk.Window(gdk_win, gtk.gdk.screen_width(),
gtk.gdk.screen_height(), gtk.gdk.WINDOW_CHILD, 0, gtk.gdk.INPUT_ONLY)
gdk_cursor = gtk.gdk.Cursor(gtk.gdk.WATCH)
+
self.gdk_window.set_cursor(gdk_cursor)
# Until package icons become available hide Package Icon Panel
w_package_hbox.hide()
@@ -788,7 +768,7 @@
else:
display_link = self.__handle_link(None, link, DISPLAY_LINK)
if display_link != None:
- self.w_main_statusbar.push(0, display_link)
+ self.__update_statusbar_message(display_link)
else:
self.update_statusbar()
@@ -818,13 +798,13 @@
pass
def __load_uri(self, document, link):
- self.w_main_statusbar.push(0, _("Loading... " + link))
+ self.__update_statusbar_message(_("Loading... " + link))
try:
f = self.__open_url(link)
except (IOError, OSError), err:
if debug:
print "err: %s" % (err)
- self.w_main_statusbar.push(0, _("Stopped"))
+ self.__update_statusbar_message(_("Stopped"))
return False
self.current_url = self.__resolve_uri(link)
@@ -838,7 +818,7 @@
self.document.write_stream(f.read())
self.document.close_stream()
- self.w_main_statusbar.push(0, _("Done"))
+ self.__update_statusbar_message(_("Done"))
return True
def __link_load_error(self, link):
@@ -1402,6 +1382,8 @@
def __update_description_from_iter(self, pkg_descriptions_for_update, orig_model):
sort_filt_model = \
self.w_application_treeview.get_model() #gtk.TreeModelSort
+ if not sort_filt_model:
+ return
filt_model = sort_filt_model.get_model() #gtk.TreeModelFilter
model = filt_model.get_model() #gtk.ListStore
@@ -1520,10 +1502,6 @@
else:
return length_to_check
- def __on_cancel_progressdialog_clicked(self, widget):
- self.progress_canceled = True
- self.progress_stop_timer_thread = True
-
def __on_mainwindow_key_press_event(self, widget, event):
if self.is_busy_cursor_set():
return True
@@ -1540,6 +1518,12 @@
else:
self.__main_application_quit()
+ def __on_mainwindow_check_resize(self, widget):
+ if widget and self.gdk_window:
+ status_height = self.w_statusbar_hbox.get_allocation().height
+ self.gdk_window.move_resize(0, 0, widget.get_size()[0],
+ widget.get_size()[1]-status_height)
+
def __on_api_search_error_delete_event(self, widget, event):
self.__on_api_search_button_clicked(None)
@@ -1614,7 +1598,6 @@
self.in_search_mode = False
self.is_all_publishers = False
self.w_infosearch_frame.hide()
-
self.set_busy_cursor()
self.w_repository_combobox.set_active(
self.saved_repository_combobox_active)
@@ -1743,7 +1726,6 @@
for query_num, pub, (v, return_type, tmp) in \
itertools.chain(*searches):
if v < 1 or return_type != api.Query.RETURN_PACKAGES:
- gobject.idle_add(self.w_progress_dialog.hide)
self.__process_after_search_failure()
return
@@ -1770,14 +1752,18 @@
self.pylintstub = query_num
except api_errors.ProblematicSearchServers, ex:
self.__process_api_search_error(ex)
- gobject.idle_add(self.w_progress_dialog.hide)
gobject.idle_add(self.__handle_api_search_error)
if len(result) == 0:
self.__process_after_search_with_zero_results()
return
+ except api_errors.CanceledException:
+ # TBD. Currently search is not cancelable
+ # so this should not happen, but the logic is in place
+ # to support cancelable search.
+ self.unset_busy_cursor()
+ return
except Exception, ex:
# We are not interested in this error
- gobject.idle_add(self.w_progress_dialog.hide)
self.__process_after_search_failure()
return
if debug:
@@ -1850,7 +1836,6 @@
err = _("Unable to get status for search results.\n"
"The catalogs have not been loaded.\n"
"Please try after few seconds.\n")
- gobject.idle_add(self.w_progress_dialog.hide)
gobject.idle_add(self.error_occurred, err)
return
return self.__add_pkgs_to_lists(pkgs_known, application_list,
@@ -1914,6 +1899,9 @@
self.__update_statusbar_message(_("Search cleared"))
return
+ def __on_progress_cancel_clicked(self, widget):
+ Thread(target = self.api_o.cancel, args = ()).start()
+
def __on_startpage(self, widget):
self.__load_startpage()
self.w_main_view_notebook.set_current_page(NOTEBOOK_START_PAGE)
@@ -2417,7 +2405,6 @@
application_list = self.__get_new_application_liststore()
category_list = self.__get_new_category_liststore()
section_list = self.__get_new_section_liststore()
- first_loop = True
for pub in publishers:
uptodate = False
try:
@@ -2433,9 +2420,9 @@
category_list = self.__get_new_category_liststore()
uptodate = False
if not uptodate:
- if first_loop == True:
- first_loop = False
- gobject.idle_add(self.setup_progressdialog_show)
+ status_str = _("Refreshing package catalog information")
+ gobject.idle_add(self.__update_statusbar_message,
+ status_str)
self.api_o.refresh(pubs=[pub])
self.__add_pkgs_to_lists_from_api(pub,
application_list, category_list, section_list)
@@ -2443,6 +2430,9 @@
True, None])
if self.application_list and self.category_list and \
not self.last_visible_publisher_uptodate:
+ status_str = _("Loading package list")
+ gobject.idle_add(self.__update_statusbar_message,
+ status_str)
if self.last_visible_publisher:
dump_list = self.application_list
if self.saved_application_list != None:
@@ -2456,7 +2446,11 @@
def __check_if_cache_uptodate(self, pub):
if self.cache_o:
- return self.cache_o.check_if_cache_uptodate(pub)
+ uptodate = self.cache_o.check_if_cache_uptodate(pub)
+ # We need to reset the state of the api, otherwise
+ # method api.can_be_canceled() will return True
+ self.api_o.reset()
+ return uptodate
return False
def __dump_datamodels(self, pub, application_list, category_list,
@@ -2577,6 +2571,7 @@
action = enumerations.REMOVE)
def __on_reload(self, widget):
+ self.w_searchentry.grab_focus()
if self.description_thread_running:
self.cancelled = True
if self.in_search_mode or self.is_all_publishers:
@@ -2586,22 +2581,14 @@
self.last_visible_publisher = None
if widget != None:
self.__remove_cache()
- self.w_progress_dialog.set_title(_("Refreshing catalogs"))
- self.w_progressinfo_label.set_text(_("Refreshing catalogs..."))
- self.progress_stop_timer_thread = False
- Thread(target = self.__progressdialog_progress_pulse).start()
- self.w_progress_dialog.show()
- self.w_progress_cancel.hide()
+ self.set_busy_cursor()
+ status_str = _("Refreshing package catalog information")
+ self.__update_statusbar_message(status_str)
self.__disconnect_models()
self.in_reload = True
Thread(target = self.__catalog_refresh).start()
def __catalog_refresh_done(self):
- self.progress_stop_timer_thread = True
- #Let the progress_pulse finish. This should be done other way, but at
- #The moment this works fine
- time.sleep(0.2)
- gobject.idle_add(self.w_progress_cancel.show)
gobject.idle_add(self.process_package_list_start,
self.image_directory)
@@ -3411,7 +3398,6 @@
# This can happen if the repository does not
# contain any packages
err = _("Selected repository does not contain any packages.")
- gobject.idle_add(self.w_progress_dialog.hide)
gobject.idle_add(self.error_occurred, err, None,
gtk.MESSAGE_INFO)
self.unset_busy_cursor()
@@ -3448,13 +3434,9 @@
sections[pub] = section
pkg_count = 0
pkg_add = 0
- progress_percent = INITIAL_PROGRESS_TOTAL_PERCENTAGE
total_pkg_count = len(pkgs_known)
- progress_increment = \
- total_pkg_count / PACKAGE_PROGRESS_TOTAL_INCREMENTS
- self.progress_stop_timer_thread = True
- while gtk.events_pending():
- gtk.main_iteration(False)
+ status_str = _("Loading package list")
+ gobject.idle_add(self.__update_statusbar_message, status_str)
prev_stem = ""
prev_pfmri_str = ""
next_app = None
@@ -3484,14 +3466,8 @@
prev_pfmri_str = pkg.get_short_fmri()
prev_state = state
- if progress_increment > 0 and pkg_count % progress_increment == 0:
- progress_percent += PACKAGE_PROGRESS_PERCENT_INCREMENT
- if progress_percent <= PACKAGE_PROGRESS_PERCENT_TOTAL:
- self.__progressdialog_progress_percent(
- progress_percent, pkg_count, total_pkg_count)
- while gtk.events_pending():
- gtk.main_iteration(False)
-
+ gobject.idle_add(self.__progress_set_fraction,
+ pkg_count, total_pkg_count)
status_icon = None
category_icon = None
pkg_name = pkg.get_name()
@@ -3530,8 +3506,8 @@
if category_list != None:
self.__add_categories_to_sections(sections,
category_list, section_list)
- self.__progressdialog_progress_percent(PACKAGE_PROGRESS_PERCENT_TOTAL,
- total_pkg_count, total_pkg_count)
+ gobject.idle_add(self.__progress_set_fraction,
+ pkg_count, total_pkg_count)
return
def __add_categories_to_sections(self, sections, category_list, section_list):
@@ -3626,32 +3602,44 @@
section_lst.append(
section_id)
- def __progressdialog_progress_pulse(self):
- while not self.progress_stop_timer_thread:
- gobject.idle_add(self.w_progressbar.pulse)
+
+ def __progress_set_fraction(self, count, total):
+ self.__progress_pulse_stop()
+ if count == total:
+ self.w_progress_frame.hide()
+ return False
+ if self.api_o.can_be_canceled():
+ self.progress_cancel.show()
+ else:
+ self.progress_cancel.hide()
+ self.w_progress_frame.show()
+ result = (count + 0.0)/total
+ if result > 1.0:
+ result = 1.0
+ elif result < 0.0:
+ result = 0.0
+ self.w_status_progressbar.set_fraction(result)
+
+
+ def __progress_pulse_start(self):
+ if self.progress_stop_thread == True:
+ self.progress_stop_thread = False
+ Thread(target = self.__progress_pulse).start()
+
+ def __progress_pulse_stop(self):
+ self.progress_stop_thread = True
+
+ def __progress_pulse(self):
+ gobject.idle_add(self.w_progress_frame.show)
+ while not self.progress_stop_thread:
+ if self.api_o.can_be_canceled():
+ gobject.idle_add(self.progress_cancel.show)
+ else:
+ gobject.idle_add(self.progress_cancel.hide)
+ gobject.idle_add(self.w_status_progressbar.pulse)
time.sleep(0.1)
- gobject.idle_add(self.w_progress_dialog.hide)
- self.progress_stop_timer_thread = False
-
- # For initial setup before loading package entries allow 5% of progress bar
- # update it on a time base as we have no other way to judge progress at this point
- def __progressdialog_progress_time(self):
- while not self.progress_stop_timer_thread and \
- self.progress_fraction_time_count <= \
- INITIAL_PROGRESS_TOTAL_PERCENTAGE:
-
- gobject.idle_add(self.w_progressbar.set_fraction,
- self.progress_fraction_time_count)
- self.progress_fraction_time_count += \
- INITIAL_PROGRESS_TIME_PERCENTAGE
- time.sleep(INITIAL_PROGRESS_TIME_INTERVAL)
- self.progress_stop_timer_thread = False
- self.progress_fraction_time_count = 0
-
- def __progressdialog_progress_percent(self, fraction, count, total):
- gobject.idle_add(self.w_progressinfo_label.set_text, _(
- "Processing package entries: %d of %d") % (count, total) )
- gobject.idle_add(self.w_progressbar.set_fraction, fraction)
+ gobject.idle_add(self.w_progress_frame.hide)
+ self.progress_stop_thread = True
def error_occurred(self, error_msg, msg_title=None, msg_type=gtk.MESSAGE_ERROR):
if msg_title:
@@ -3754,18 +3742,6 @@
#-----------------------------------------------------------------------------#
# Public Methods
#-----------------------------------------------------------------------------#
- def setup_progressdialog_show(self):
- self.w_progress_dialog.set_title(_("Loading Repository Information"))
- self.w_progressinfo_label.set_text(
- _( "Fetching package entries ..."))
- self.w_progress_cancel.hide()
- self.w_progress_dialog.show()
- Thread(target = self.__progressdialog_progress_time).start()
-
- def setup_progressdialog_hide(self):
- self.progress_stop_timer_thread = True
- self.w_progress_dialog.hide()
-
def init_show_filter(self):
""" Sets up the Filter Combobox and returns the maximum length of text
labels it is displaying."""
@@ -3782,9 +3758,11 @@
return self.gdk_window.is_visible()
def set_busy_cursor(self):
+ self.__progress_pulse_start()
self.gdk_window.show()
def unset_busy_cursor(self):
+ self.__progress_pulse_stop()
self.gdk_window.hide()
def process_package_list_start(self, image_directory):
@@ -3823,7 +3801,6 @@
# in update all: bug 6357
self.__on_update_all(None)
self.update_all_proceed = False
- self.setup_progressdialog_hide()
self.__enable_disable_install_remove()
self.update_statusbar()
self.in_setup = False
@@ -3873,7 +3850,7 @@
inst_str = _('%d installed') % installed
status_str = _("%s: %s , %s, %s.") % (visible_publisher,
listed_str, inst_str, sel_str)
- self.w_main_statusbar.push(0, status_str)
+ self.__update_statusbar_message(status_str)
return
# In Search Mode
@@ -3908,7 +3885,7 @@
status_str = fmt_str % {"option_str" : opt_str, "number" :
len(self.application_list), "time" : time_str}
- self.w_main_statusbar.push(0, status_str)
+ self.__update_statusbar_message(status_str)
def update_package_list(self, update_list):
if update_list == None and self.img_timestamp: