[Rigo] implement a Bottom NotificationBox "Activity" button

This Button allows users to see the current Application management
queue by leveraging the new RigoDaemon API.
This commit is contained in:
Fabio Erculiani
2012-07-31 19:35:35 +02:00
parent 9859dc2e67
commit 2ddd3b4d0f
5 changed files with 143 additions and 15 deletions
+28 -4
View File
@@ -856,7 +856,8 @@ class Application(object):
return self._licenses
def __init__(self, entropy_client, entropy_ws, rigo_service,
package_match, redraw_callback=None, package_path=None):
package_match, redraw_callback=None, package_path=None,
children=None, vanished_callback=None):
self._entropy = entropy_client
self._entropy_ws = entropy_ws
self._service = rigo_service
@@ -864,6 +865,8 @@ class Application(object):
self._pkg_id, self._repo_id = package_match
self._path = package_path
self._redraw_callback = redraw_callback
self._children = children
self._vanished_callback = vanished_callback
@property
def name(self):
@@ -873,6 +876,8 @@ class Application(object):
repo = self._entropy.open_repository(self._repo_id)
name = repo.retrieveName(self._pkg_id)
if name is None:
if self._vanished_callback is not None:
self._vanished_callback(self)
return _("N/A")
name = " ".join([x.capitalize() for x in \
name.replace("-"," ").split()])
@@ -888,6 +893,15 @@ class Application(object):
"""
return self._path
@property
def children(self):
"""
If the Application is the parent of other Applications,
this object shall contain a list of children Application
objects. Otherwise, it returns None.
"""
return self._children
def is_installed(self):
"""
Return if Application is currently installed.
@@ -931,9 +945,7 @@ class Application(object):
# in the installed packages repository, matches
# must be of length < 2.
if len(matches) > 1:
raise AttributeError(
"searchKeySlot for %s returned: %s" % (
(key, slot), matches,))
return None
if not matches:
# not installed
return None
@@ -1232,6 +1244,10 @@ class Application(object):
self._entropy.rwsem().reader_acquire()
try:
repo = self._entropy.open_repository(self._repo_id)
if self._vanished_callback is not None:
if not repo.isPackageIdAvailable(self._pkg_id):
self._vanished_callback(self)
version = repo.retrieveVersion(self._pkg_id)
if version is None:
version = _("N/A")
@@ -1271,6 +1287,10 @@ class Application(object):
self._entropy.rwsem().reader_acquire()
try:
repo = self._entropy.open_repository(self._repo_id)
if self._vanished_callback is not None:
if not repo.isPackageIdAvailable(self._pkg_id):
self._vanished_callback(self)
inst_repo = self._entropy.installed_repository()
strict = repo.getStrictData(self._pkg_id)
if strict is None:
@@ -1347,6 +1367,10 @@ class Application(object):
lic_url = "%s/license/" % (etpConst['packages_website_url'],)
repo = self._entropy.open_repository(self._repo_id)
if self._vanished_callback is not None:
if not repo.isPackageIdAvailable(self._pkg_id):
self._vanished_callback(self)
licenses = repo.retrieveLicense(self._pkg_id)
if licenses:
licenses_txt = "<b>%s</b>: " % (escape_markup(_("License")),)
+51 -2
View File
@@ -78,9 +78,10 @@ class ApplicationsViewController(GObject.Object):
MIN_RECENT_SEARCH_KEY_LEN = 2
SHOW_INSTALLED_KEY = "in:installed"
SHOW_QUEUE_KEY = "in:queue"
def __init__(self, activity_rwsem, entropy_client, entropy_ws,
nc, rigo_service, prefc, icons, nf_box,
nc, bottom_nc, rigo_service, prefc, icons, nf_box,
search_entry, search_entry_completion,
search_entry_store, store, view):
GObject.Object.__init__(self)
@@ -97,6 +98,7 @@ class ApplicationsViewController(GObject.Object):
self._not_found_search_box = None
self._not_found_label = None
self._nc = nc
self._bottom_nc = bottom_nc
self._prefc = prefc
self._cacher = EntropyCacher()
@@ -333,6 +335,39 @@ class ApplicationsViewController(GObject.Object):
__name__, "upgrade:"
" upgrade_system() sent")
def _show_action_queue_items(self, _invalid_matches=False):
"""
Request the UI to show the current Action Queue, if any.
"""
const_debug_write(
__name__, "_show_action_queue_items called")
apps = self._service.action_queue_items()
const_debug_write(
__name__, "_show_action_queue_items, items: %d" % (len(apps),))
matches = []
if not _invalid_matches:
for app in apps:
const_debug_write(
__name__, "_show_action_queue_items:"
" %s" % (app,))
matches.append(app.get_details().pkg)
else:
self._entropy.rwsem().reader_acquire()
try:
inst_repo = self._entropy.installed_repository()
repo_name = inst_repo.repository_id()
matches.extend(
[(-2, repo_name),
(-5, repo_name),
(-10, repo_name)])
finally:
self._entropy.rwsem().reader_release()
if matches:
self.set_many_safe(matches,
_from_search=ApplicationsViewController.SHOW_QUEUE_KEY)
def __simulate_orphaned_apps(self, text):
const_debug_write(
@@ -368,6 +403,9 @@ class ApplicationsViewController(GObject.Object):
elif text == "in:confupdate":
self._service.configuration_updates()
return
elif text == ApplicationsViewController.SHOW_QUEUE_KEY:
self._show_action_queue_items()
return
elif text == "in:config":
GLib.idle_add(self.emit, "view-want-change",
RigoViewStates.PREFERENCES_VIEW_STATE,
@@ -403,9 +441,12 @@ class ApplicationsViewController(GObject.Object):
if sim_str:
self.__simulate_orphaned_apps(sim_str)
return
if text == "in:simulate:u":
elif text == "in:simulate:u":
self.upgrade(simulate=True)
return
elif text == "in:simulate:v":
self._show_action_queue_items(_invalid_matches=True)
return
return self.__search_thread_body(text)
@@ -655,6 +696,14 @@ class ApplicationsViewController(GObject.Object):
"drive-harddisk", _show_installed)
self._prefc.append(pref)
def _show_queue_view(widget):
self._search(ApplicationsViewController.SHOW_QUEUE_KEY,
_force=True)
self._bottom_nc.connect("show-queue-view", _show_queue_view)
def _clear(widget):
self.clear()
self._store.connect("all-vanished", _clear)
self._view.set_model(self._store)
self._search_entry.connect(
"changed", self._search_changed)
@@ -181,6 +181,10 @@ class BottomNotificationViewController(NotificationViewController):
None,
tuple(),
),
"show-queue-view" : (GObject.SignalFlags.RUN_LAST,
None,
tuple(),
),
"work-interrupt" : (GObject.SignalFlags.RUN_LAST,
None,
tuple(),
@@ -206,6 +210,12 @@ class BottomNotificationViewController(NotificationViewController):
"""
self.emit("work-interrupt")
def _on_show_activity(self, widget):
"""
User is asking to show the Application Queue.
"""
self.emit("show-queue-view")
def _append_repositories_update(self):
"""
Add a NotificationBox related to Repositories Update
@@ -232,6 +242,7 @@ class BottomNotificationViewController(NotificationViewController):
w, h = self._window.get_size()
self._window.resize(w, 1)
box.add_button(_("Show me"), _show_me)
box.add_button(_("Activity"), self._on_show_activity)
box.add_button(_("Interrupt"), self._on_work_interrupt)
self.append(box)
@@ -249,6 +260,7 @@ class BottomNotificationViewController(NotificationViewController):
w, h = self._window.get_size()
self._window.resize(w, 1)
box.add_button(_("Show me"), _show_me)
box.add_button(_("Activity"), self._on_show_activity)
box.add_button(_("Interrupt"), self._on_work_interrupt)
self.append(box)
+43 -1
View File
@@ -50,6 +50,12 @@ class AppListStore(Gtk.ListStore):
None,
(GObject.TYPE_PYOBJECT,),
),
# signal that all the elements in the List
# have vanished.
"all-vanished" : (GObject.SignalFlags.RUN_LAST,
None,
tuple(),
),
}
def __init__(self, entropy_client, entropy_ws, rigo_service,
@@ -194,6 +200,41 @@ class AppListStore(Gtk.ListStore):
AppListStore._ICON_CACHE[pkg_match] = pixbuf
return pixbuf
def _vanished_callback(self, app):
"""
Remove elements that are marked as "vanished" due
to unavailable metadata.
"""
def _remove(_app):
pkg_match = _app.get_details().pkg
vis_data = self._view.get_visible_range()
if vis_data is None:
return
if len(vis_data) == 2:
# Gtk 3.4
valid_paths = True
start_path, end_path = vis_data
else:
# Gtk <3.2
valid_paths, start_path, end_path = vis_data
if not valid_paths:
return
path = start_path
while path <= end_path:
path_iter = self.get_iter(path)
if self.iter_is_valid(path_iter):
visible_pkg_match = self.get_value(path_iter, 0)
if visible_pkg_match == pkg_match:
self.remove(path_iter)
if len(self) == 0:
self.emit("all-vanished")
return
GLib.idle_add(_remove, app)
def get_application(self, pkg_match):
def _ui_redraw_callback(*args):
if const_debug_enabled():
@@ -203,5 +244,6 @@ class AppListStore(Gtk.ListStore):
app = Application(self._entropy, self._entropy_ws,
self._service, pkg_match,
redraw_callback=_ui_redraw_callback)
redraw_callback=_ui_redraw_callback,
vanished_callback=self._vanished_callback)
return app
+9 -8
View File
@@ -291,10 +291,18 @@ class Rigo(Gtk.Application):
self._nc = UpperNotificationViewController(
self._entropy, self._entropy_ws, self._notification)
# Bottom NotificationBox controller.
# Bottom notifications are only used for
# providing Activity control to User during
# the Activity itself.
self._bottom_nc = BottomNotificationViewController(
self._window, self._bottom_notification,
self._pref_button)
self._avc = ApplicationsViewController(
self._activity_rwsem,
self._entropy, self._entropy_ws, self._nc, self._service,
self._entropy, self._entropy_ws,
self._nc, self._bottom_nc, self._service,
self._pref_view_c, icons, self._not_found_box,
self._search_entry, self._search_entry_completion,
self._search_entry_store, self._app_store, self._view)
@@ -303,13 +311,6 @@ class Rigo(Gtk.Application):
self._avc.connect("view-filled", self._on_view_filled)
self._avc.connect("view-want-change", self._on_view_change)
# Bottom NotificationBox controller.
# Bottom notifications are only used for
# providing Activity control to User during
# the Activity itself.
self._bottom_nc = BottomNotificationViewController(
self._window, self._bottom_notification,
self._pref_button)
self._service.set_bottom_notification_controller(
self._bottom_nc)