[rigo] rework some code paths to be more signal-centric, more work on the app details pane
This commit is contained in:
@@ -73,3 +73,8 @@ GtkViewport {
|
||||
border-width: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#rigoWindow {
|
||||
background-color: white;
|
||||
/* color: black; */
|
||||
}
|
||||
@@ -10,6 +10,8 @@
|
||||
<object class="GtkWindow" id="rigoWindow">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Rigo Browser</property>
|
||||
<property name="window_position">center</property>
|
||||
<property name="icon_name">system-software-update</property>
|
||||
<signal name="delete-event" handler="onDeleteWindow" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkVBox" id="appVbox">
|
||||
@@ -123,148 +125,11 @@
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkVBox" id="appViewInnerStatsVbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkEventBox" id="starsEvent">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkHBox" id="hbox36">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkEventBox" id="starEvent1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="vote1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK</property>
|
||||
<property name="stock">gtk-missing-image</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEventBox" id="starEvent2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="vote2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK</property>
|
||||
<property name="stock">gtk-missing-image</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEventBox" id="starEvent3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="vote3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK</property>
|
||||
<property name="stock">gtk-missing-image</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEventBox" id="starEvent4">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="vote4">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK</property>
|
||||
<property name="stock">gtk-missing-image</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEventBox" id="starEvent5">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="vote5">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events"></property>
|
||||
<property name="stock">gtk-missing-image</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="appViewDownloadedLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="wrap">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">5</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="padding">8</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
@@ -275,11 +140,54 @@
|
||||
<property name="xalign">0.019999999552965164</property>
|
||||
<property name="yalign">0.019999999552965164</property>
|
||||
<property name="label" translatable="yes">Application markup</property>
|
||||
<property name="wrap">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkVBox" id="appViewInnerStatsVbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkVBox" id="appViewStarsSelVbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="appViewDownloadedLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="xalign">0.98000001907348633</property>
|
||||
<property name="label" translatable="yes">Downloaded times</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="wrap">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
<property name="padding">5</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
@@ -134,6 +134,9 @@ class ApplicationMetadata(object):
|
||||
"""
|
||||
Thread executing generic (both rating and doc) metadata retrieval.
|
||||
"""
|
||||
cache_miss = WebService.CacheMiss
|
||||
ws_exception = WebService.WebServiceException
|
||||
|
||||
while True:
|
||||
sem.acquire()
|
||||
discard_signal.set(False)
|
||||
@@ -191,7 +194,7 @@ class ApplicationMetadata(object):
|
||||
try:
|
||||
outcome[(key, repo_id)] = request_map[request](
|
||||
[key], cache=True, cached=True)[key]
|
||||
except WebService.CacheMiss:
|
||||
except cache_miss:
|
||||
uncached_keys.append(key)
|
||||
|
||||
for key in uncached_keys:
|
||||
@@ -201,7 +204,7 @@ class ApplicationMetadata(object):
|
||||
# FIXME, lxnay: work more instances in parallel?
|
||||
outcome[(key, repo_id)] = request_map[request](
|
||||
[key], cache = True)[key]
|
||||
except WebService.WebServiceException as wse:
|
||||
except ws_exception as wse:
|
||||
const_debug_write(
|
||||
__name__,
|
||||
"%s, WebServiceExc: %s" % (name, wse,)
|
||||
@@ -541,7 +544,7 @@ class Application(object):
|
||||
description = _("No description")
|
||||
if len(description) > 79:
|
||||
description = description[:80].strip() + "..."
|
||||
text = "%s %s\n<small><i>%s</i></small>" % (
|
||||
text = "<b>%s</b> %s\n<small><i>%s</i></small>" % (
|
||||
GObject.markup_escape_text(name),
|
||||
GObject.markup_escape_text(version),
|
||||
GObject.markup_escape_text(description))
|
||||
|
||||
@@ -23,6 +23,15 @@ class AppListStore(Gtk.ListStore):
|
||||
_MISSING_ICON_MUTEX = Lock()
|
||||
_ICON_CACHE = {}
|
||||
|
||||
__gsignals__ = {
|
||||
# Redraw signal, requesting UI update
|
||||
# for given pkg_match object
|
||||
"redraw-request" : (GObject.SignalFlags.RUN_LAST,
|
||||
None,
|
||||
(GObject.TYPE_PYOBJECT, ),
|
||||
),
|
||||
}
|
||||
|
||||
def __init__(self, entropy_client, entropy_ws, view, icons):
|
||||
Gtk.ListStore.__init__(self)
|
||||
self._view = view
|
||||
@@ -42,12 +51,6 @@ class AppListStore(Gtk.ListStore):
|
||||
AppListStore._ICON_CACHE.clear()
|
||||
return outcome
|
||||
|
||||
def _ui_redraw_callback(self, *args):
|
||||
if const_debug_enabled():
|
||||
const_debug_write(__name__,
|
||||
"_ui_redraw_callback()")
|
||||
GLib.idle_add(self._view.queue_draw)
|
||||
|
||||
@property
|
||||
def _missing_icon(self):
|
||||
"""
|
||||
@@ -63,14 +66,18 @@ class AppListStore(Gtk.ListStore):
|
||||
AppListStore._MISSING_ICON = _missing_icon
|
||||
return _missing_icon
|
||||
|
||||
def get_icon(self, pkg_match, app=None):
|
||||
def get_icon(self, pkg_match):
|
||||
cached = AppListStore._ICON_CACHE.get(pkg_match)
|
||||
if cached is not None:
|
||||
return cached
|
||||
|
||||
if app is None:
|
||||
app = Application(self._entropy, self._entropy_ws, pkg_match,
|
||||
redraw_callback=self._ui_redraw_callback)
|
||||
def _ui_redraw_callback(*args):
|
||||
if const_debug_enabled():
|
||||
const_debug_write(__name__,
|
||||
"_ui_redraw_callback()")
|
||||
self.emit("redraw-request", pkg_match)
|
||||
app = Application(self._entropy, self._entropy_ws, pkg_match,
|
||||
redraw_callback=_ui_redraw_callback)
|
||||
icon, cache_hit = app.get_details().icon
|
||||
if icon is None:
|
||||
if cache_hit:
|
||||
@@ -113,28 +120,58 @@ class AppListStore(Gtk.ListStore):
|
||||
return pixbuf
|
||||
|
||||
def is_installed(self, pkg_match):
|
||||
def _ui_redraw_callback(*args):
|
||||
if const_debug_enabled():
|
||||
const_debug_write(__name__,
|
||||
"_ui_redraw_callback()")
|
||||
self.emit("redraw-request", pkg_match)
|
||||
|
||||
app = Application(self._entropy, self._entropy_ws, pkg_match,
|
||||
redraw_callback=self._ui_redraw_callback)
|
||||
redraw_callback=_ui_redraw_callback)
|
||||
return app.is_installed()
|
||||
|
||||
def is_available(self, pkg_match):
|
||||
def _ui_redraw_callback(*args):
|
||||
if const_debug_enabled():
|
||||
const_debug_write(__name__,
|
||||
"_ui_redraw_callback()")
|
||||
self.emit("redraw-request", pkg_match)
|
||||
|
||||
app = Application(self._entropy, self._entropy_ws, pkg_match,
|
||||
redraw_callback=self._ui_redraw_callback)
|
||||
redraw_callback=_ui_redraw_callback)
|
||||
return app.is_available()
|
||||
|
||||
def get_markup(self, pkg_match):
|
||||
def _ui_redraw_callback(*args):
|
||||
if const_debug_enabled():
|
||||
const_debug_write(__name__,
|
||||
"_ui_redraw_callback()")
|
||||
self.emit("redraw-request", pkg_match)
|
||||
|
||||
app = Application(self._entropy, self._entropy_ws, pkg_match,
|
||||
redraw_callback=self._ui_redraw_callback)
|
||||
redraw_callback=_ui_redraw_callback)
|
||||
return app.get_markup()
|
||||
|
||||
def get_review_stats(self, pkg_match):
|
||||
def _ui_redraw_callback(*args):
|
||||
if const_debug_enabled():
|
||||
const_debug_write(__name__,
|
||||
"_ui_redraw_callback()")
|
||||
self.emit("redraw-request", pkg_match)
|
||||
|
||||
app = Application(self._entropy, self._entropy_ws, pkg_match,
|
||||
redraw_callback=self._ui_redraw_callback)
|
||||
redraw_callback=_ui_redraw_callback)
|
||||
return app.get_review_stats()
|
||||
|
||||
def get_application(self, pkg_match):
|
||||
def _ui_redraw_callback(*args):
|
||||
if const_debug_enabled():
|
||||
const_debug_write(__name__,
|
||||
"_ui_redraw_callback()")
|
||||
self.emit("redraw-request", pkg_match)
|
||||
|
||||
app = Application(self._entropy, self._entropy_ws, pkg_match,
|
||||
redraw_callback=self._ui_redraw_callback)
|
||||
redraw_callback=_ui_redraw_callback)
|
||||
return app
|
||||
|
||||
def get_transaction_progress(self, pkg_match):
|
||||
|
||||
@@ -48,12 +48,12 @@ def init_sc_css_provider(toplevel, settings, screen, datadir):
|
||||
|
||||
# munge css path for theme-name
|
||||
css_path = os.path.join(datadir,
|
||||
"ui/gtk3/css/softwarecenter.%s.css" % \
|
||||
"ui/gtk3/css/rigo.%s.css" % \
|
||||
theme_name)
|
||||
|
||||
# if no css for theme-name try fallback css
|
||||
if not os.path.exists(css_path):
|
||||
css_path = os.path.join(datadir, "ui/gtk3/css/softwarecenter.css")
|
||||
css_path = os.path.join(datadir, "ui/gtk3/css/rigo.css")
|
||||
|
||||
if not os.path.exists(css_path):
|
||||
# check fallback exists as well... if not return None but warn
|
||||
@@ -64,7 +64,7 @@ def init_sc_css_provider(toplevel, settings, screen, datadir):
|
||||
LOG.warn(msg % css_path)
|
||||
return None
|
||||
|
||||
# things seem ok, now set the css provider for softwarecenter
|
||||
# things seem ok, now set the css provider for Rigo
|
||||
msg = "Rigo style provider for %s Gtk theme: %s"
|
||||
LOG.info(msg % (theme_name, css_path))
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ from cellrenderers import CellRendererAppView, CellButtonRenderer, \
|
||||
CellButtonIDs
|
||||
|
||||
from rigo.em import em, StockEms
|
||||
from rigo.utils import ExecutionTime
|
||||
from rigo.enums import Icons
|
||||
from rigo.models.application import CategoryRowReference
|
||||
|
||||
@@ -544,24 +543,18 @@ def on_entry_changed(widget, data):
|
||||
new_text = widget.get_text()
|
||||
(view, enquirer) = data
|
||||
|
||||
with ExecutionTime("total time"):
|
||||
with ExecutionTime("enquire.set_query()"):
|
||||
# FIXME lxnay
|
||||
enquirer.set_query(get_query_from_search_entry(new_text),
|
||||
limit=100*1000,
|
||||
nonapps_visible=NonAppVisibility.ALWAYS_VISIBLE)
|
||||
# FIXME lxnay
|
||||
enquirer.set_query(get_query_from_search_entry(new_text),
|
||||
limit=100*1000,
|
||||
nonapps_visible=NonAppVisibility.ALWAYS_VISIBLE)
|
||||
|
||||
store = view.tree_view.get_model()
|
||||
with ExecutionTime("store.clear()"):
|
||||
store.clear()
|
||||
store = view.tree_view.get_model()
|
||||
store.clear()
|
||||
|
||||
with ExecutionTime("store.set_documents()"):
|
||||
store.set_from_matches(enquirer.matches)
|
||||
store.set_from_matches(enquirer.matches)
|
||||
|
||||
with ExecutionTime("model settle (size=%s)" % len(store)):
|
||||
while Gtk.events_pending():
|
||||
Gtk.main_iteration()
|
||||
return
|
||||
while Gtk.events_pending():
|
||||
Gtk.main_iteration()
|
||||
|
||||
if widget.stamp:
|
||||
GObject.source_remove(widget.stamp)
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
# Copyright (C) 2009 Canonical
|
||||
#
|
||||
# Authors:
|
||||
# Michael Vogt
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation; version 3.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import logging
|
||||
import time
|
||||
|
||||
class ExecutionTime(object):
|
||||
"""
|
||||
Helper that can be used in with statements to have a simple
|
||||
measure of the timming of a particular block of code, e.g.
|
||||
with ExecutinTime("db flush"):
|
||||
db.flush()
|
||||
"""
|
||||
def __init__(self, info=""):
|
||||
self.info = info
|
||||
|
||||
def __enter__(self):
|
||||
self.now = time.time()
|
||||
|
||||
def __exit__(self, type, value, stack):
|
||||
logger = logging.getLogger("softwarecenter.performance")
|
||||
logger.debug("%s: %s" % (self.info, time.time() - self.now))
|
||||
@@ -2,6 +2,7 @@ import os
|
||||
import sys
|
||||
import copy
|
||||
import tempfile
|
||||
import time
|
||||
from threading import Lock
|
||||
|
||||
sys.path.insert(0, "../lib")
|
||||
@@ -12,7 +13,7 @@ sys.path.insert(4, "/usr/lib/entropy/client")
|
||||
sys.path.insert(5, "/usr/lib/entropy/rigo")
|
||||
|
||||
|
||||
from gi.repository import Gtk, Gdk, Gio, GLib, GObject, GdkPixbuf
|
||||
from gi.repository import Gtk, Gdk, Gio, GLib, GObject
|
||||
|
||||
from rigo.paths import DATA_DIR
|
||||
from rigo.enums import Icons
|
||||
@@ -22,6 +23,7 @@ from rigo.ui.gtk3.widgets.apptreeview import AppTreeView
|
||||
from rigo.ui.gtk3.widgets.notifications import NotificationBox, \
|
||||
RepositoriesUpdateNotificationBox, UpdatesNotificationBox
|
||||
from rigo.ui.gtk3.widgets.welcome import WelcomeBox
|
||||
from rigo.ui.gtk3.widgets.stars import ReactiveStar
|
||||
from rigo.ui.gtk3.models.appliststore import AppListStore
|
||||
from rigo.ui.gtk3.utils import init_sc_css_provider, get_sc_icon_theme
|
||||
|
||||
@@ -312,11 +314,22 @@ class ApplicationViewController(GObject.Object):
|
||||
self._entropy = entropy_client
|
||||
self._entropy_ws = entropy_ws
|
||||
self._app_store = None
|
||||
self._last_pkg_match = None
|
||||
|
||||
self._image = self._builder.get_object("appViewImage")
|
||||
self._app_name_lbl = self._builder.get_object("appViewNameLabel")
|
||||
self._app_download_lbl = self._builder.get_object(
|
||||
"appViewDownloadedLabel")
|
||||
self._stars_container = self._builder.get_object("appViewStarsSelVbox")
|
||||
|
||||
self._stars = ReactiveStar()
|
||||
self._stars_alignment = Gtk.Alignment.new(0.0, 0.5, 1.0, 1.0)
|
||||
self._stars_alignment.set_padding(0, 5, 0, 0)
|
||||
self._stars_alignment.add(self._stars)
|
||||
self._stars.set_size_as_pixel_value(24)
|
||||
|
||||
self._stars_container.pack_start(self._stars_alignment, False, False, 0)
|
||||
|
||||
|
||||
def set_store(self, store):
|
||||
"""
|
||||
@@ -326,6 +339,7 @@ class ApplicationViewController(GObject.Object):
|
||||
|
||||
def setup(self):
|
||||
self.connect("application-activated", self._on_application_activated)
|
||||
self._app_store.connect("redraw-request", self._on_redraw_request)
|
||||
|
||||
def _on_application_activated(self, avc, app):
|
||||
"""
|
||||
@@ -333,11 +347,22 @@ class ApplicationViewController(GObject.Object):
|
||||
information. Once we're done loading the shit, we just emit
|
||||
'application-show' and let others do the UI switch.
|
||||
"""
|
||||
self._last_pkg_match = app.get_details().pkg
|
||||
task = ParallelTask(self.__application_activate, app)
|
||||
task.name = "ApplicationActivate"
|
||||
task.daemon = True
|
||||
task.start()
|
||||
|
||||
def _on_redraw_request(self, widget, pkg_match):
|
||||
"""
|
||||
Redraw request received from AppListStore for given package match.
|
||||
We are required to update rating, number of downloads, icon.
|
||||
"""
|
||||
if pkg_match == self._last_pkg_match:
|
||||
stats = self._app_store.get_review_stats(pkg_match)
|
||||
icon = self._app_store.get_icon(pkg_match)
|
||||
self._setup_application_stats(stats, icon)
|
||||
|
||||
def __application_activate(self, app):
|
||||
"""
|
||||
Collect data from app, then call the UI setup in the main loop.
|
||||
@@ -346,9 +371,28 @@ class ApplicationViewController(GObject.Object):
|
||||
metadata = {}
|
||||
metadata['name'] = app.get_markup()
|
||||
metadata['stats'] = app.get_review_stats()
|
||||
metadata['icon'] = self._app_store.get_icon(details.pkg, app=app)
|
||||
# using app store here because we cache the icon pixbuf
|
||||
metadata['icon'] = self._app_store.get_icon(details.pkg)
|
||||
GLib.idle_add(self._setup_application_info, app, metadata)
|
||||
|
||||
def _setup_application_stats(self, stats, icon):
|
||||
"""
|
||||
Setup widgets related to Application statistics (and icon).
|
||||
"""
|
||||
total_downloads = stats.downloads_total
|
||||
if not total_downloads:
|
||||
down_msg = _("Never downloaded")
|
||||
else:
|
||||
down_msg = ngettext("<small><b>%d</b> download</small>",
|
||||
"<small><b>%d</b> downloads</small>",
|
||||
total_downloads)
|
||||
down_msg = down_msg % (total_downloads,)
|
||||
self._app_download_lbl.set_markup(down_msg)
|
||||
if icon:
|
||||
self._image.set_from_pixbuf(icon)
|
||||
self._stars.set_rating(stats.ratings_average - 1)
|
||||
self._stars_alignment.show_all()
|
||||
|
||||
def _setup_application_info(self, app, metadata):
|
||||
"""
|
||||
Setup the actual UI widgets content and emit 'application-show'
|
||||
@@ -356,18 +400,12 @@ class ApplicationViewController(GObject.Object):
|
||||
# FIXME, lxnay complete
|
||||
self._app_name_lbl.set_markup(metadata['name'])
|
||||
stats = metadata['stats']
|
||||
total_downloads = stats.downloads_total
|
||||
if not total_downloads:
|
||||
down_msg = _("Never downloaded")
|
||||
else:
|
||||
down_msg = ngettext("<b>%d</b> download",
|
||||
"<b>%d</b> downloads",
|
||||
total_downloads)
|
||||
self._app_download_lbl.set_markup(down_msg % (total_downloads,))
|
||||
self._image.set_from_pixbuf(metadata['icon'])
|
||||
icon = metadata['icon']
|
||||
self._setup_application_stats(stats, icon)
|
||||
|
||||
self.emit("application-show", app)
|
||||
|
||||
|
||||
class Rigo(Gtk.Application):
|
||||
|
||||
class RigoHandler:
|
||||
@@ -395,6 +433,7 @@ class Rigo(Gtk.Application):
|
||||
self._builder.add_from_file(os.path.join(DATA_DIR, "ui/gtk3/rigo.ui"))
|
||||
self._builder.connect_signals(Rigo.RigoHandler())
|
||||
self._window = self._builder.get_object("rigoWindow")
|
||||
self._window.set_name("rigoWindow")
|
||||
self._apps_view = self._builder.get_object("appsViewVbox")
|
||||
self._scrolled_view = self._builder.get_object("appsViewScrolledWindow")
|
||||
self._app_view = self._builder.get_object("appViewVbox")
|
||||
@@ -412,6 +451,10 @@ class Rigo(Gtk.Application):
|
||||
self._app_store = AppListStore(
|
||||
self._entropy, self._entropy_ws,
|
||||
self._view, icons)
|
||||
def _queue_draw(*args):
|
||||
self._view.queue_draw()
|
||||
self._app_store.connect("redraw-request", _queue_draw)
|
||||
|
||||
self._app_view_c.set_store(self._app_store)
|
||||
self._app_view_c.connect("application-show",
|
||||
self._on_application_show)
|
||||
|
||||
Reference in New Issue
Block a user