def _append_sub_toprated(self): self.toprated = FlowableGrid() self.toprated.set_row_spacing(6) self.toprated.set_column_spacing(6) self.toprated_frame = FramedHeaderBox() self.toprated_frame.pack_start(self.toprated, True, True, 0) self.vbox.pack_start(self.toprated_frame, False, True, 0) return
class RecommendationsPanelCategory(RecommendationsPanel): """ Panel for use in the category view that displays recommended apps for the given category """ def __init__(self, catview, subcategory): RecommendationsPanel.__init__(self, catview) self.subcategory = subcategory if self.subcategory: self.set_header_label(GObject.markup_escape_text(utf8( _("Recommended For You in %s")) % utf8(self.subcategory.name))) self.recommended_for_you_content = None if self.recommender_agent.is_opted_in(): self._update_recommended_for_you_content() else: self._hide_recommended_for_you_panel() def _update_recommended_for_you_content(self): # destroy the old content to ensure we don't see it twice if self.recommended_for_you_content: self.recommended_for_you_content.destroy() # add the new stuff self.recommended_for_you_content = FlowableGrid() self.add(self.recommended_for_you_content) self.spinner_notebook.show_spinner(_(u"Receiving recommendations…")) # get the recommendations from the recommender agent self.recommended_for_you_cat = RecommendedForYouCategory( subcategory=self.subcategory) self.recommended_for_you_cat.connect( 'needs-refresh', self._on_recommended_for_you_agent_refresh) self.recommended_for_you_cat.connect('recommender-agent-error', self._on_recommender_agent_error) def _on_recommended_for_you_agent_refresh(self, cat): self.header_implements_more_button() docs = cat.get_documents(self.catview.db) # display the recommendedations if len(docs) > 0: self.catview._add_tiles_to_flowgrid(docs, self.recommended_for_you_content, 12) self.recommended_for_you_content.show_all() self.spinner_notebook.hide_spinner() self.more.connect('clicked', self.catview.on_category_clicked, cat) self.header.queue_draw() self.show_all() else: # hide the panel if we have no recommendations to show self._hide_recommended_for_you_panel()
def _append_subcat_departments(self): self.subcat_label = Gtk.Label() self.subcat_label.set_alignment(0, 0.5) self.departments = FlowableGrid(paint_grid_pattern=False) self.departments.set_row_spacing(StockEms.SMALL) self.departments.set_column_spacing(StockEms.SMALL) frame = FramedBox(spacing=StockEms.MEDIUM, padding=StockEms.MEDIUM) # set x/y-alignment and x/y-expand frame.set(0.5, 0.0, 1.0, 1.0) frame.pack_start(self.subcat_label, False, False, 0) frame.pack_start(self.departments, True, True, 0) # append the departments section to the page self.vbox.pack_start(frame, False, True, 0) return
class RecommendationsPanelCategory(RecommendationsPanel): """ Panel for use in the category view that displays recommended apps for the given category """ def __init__(self, catview, subcategory): RecommendationsPanel.__init__(self, catview) self.subcategory = subcategory if self.subcategory: self.set_header_label( GObject.markup_escape_text( utf8(_("Recommended For You in %s")) % utf8(self.subcategory.name))) self.recommended_for_you_content = None if self.recommender_agent.is_opted_in(): self._update_recommended_for_you_content() else: self._hide_recommended_for_you_panel() def _update_recommended_for_you_content(self): # destroy the old content to ensure we don't see it twice if self.recommended_for_you_content: self.recommended_for_you_content.destroy() # add the new stuff self.recommended_for_you_content = FlowableGrid() self.add(self.recommended_for_you_content) self.spinner_notebook.show_spinner(_(u"Receiving recommendations…")) # get the recommendations from the recommender agent self.recommended_for_you_cat = RecommendedForYouCategory( subcategory=self.subcategory) self.recommended_for_you_cat.connect( 'needs-refresh', self._on_recommended_for_you_agent_refresh) self.recommended_for_you_cat.connect('recommender-agent-error', self._on_recommender_agent_error) def _on_recommended_for_you_agent_refresh(self, cat): self.header_implements_more_button() docs = cat.get_documents(self.catview.db) # display the recommendedations if len(docs) > 0: self.catview._add_tiles_to_flowgrid( docs, self.recommended_for_you_content, 12) self.recommended_for_you_content.show_all() self.spinner_notebook.hide_spinner() self.more.connect('clicked', self.catview.on_category_clicked, cat) self.header.queue_draw() self.show_all() else: # hide the panel if we have no recommendations to show self._hide_recommended_for_you_panel()
def _update_recommended_for_you_content(self): # destroy the old content to ensure we don't see it twice if self.recommended_for_you_content: self.recommended_for_you_content.destroy() # add the new stuff self.recommended_for_you_content = FlowableGrid() self.add(self.recommended_for_you_content) self.spinner_notebook.show_spinner(_(u"Receiving recommendations…")) # get the recommendations from the recommender agent self.recommended_for_you_cat = RecommendedForYouCategory( subcategory=self.subcategory) self.recommended_for_you_cat.connect( 'needs-refresh', self._on_recommended_for_you_agent_refresh) self.recommended_for_you_cat.connect('recommender-agent-error', self._on_recommender_agent_error)
class RecommendationsPanelDetails(RecommendationsPanel): """ Panel for use in the details view to display recommendations for a given application """ def __init__(self, catview): RecommendationsPanel.__init__(self, catview) self.set_header_label(_(u"People Also Installed")) self.app_recommendations_content = FlowableGrid() self.add(self.app_recommendations_content) def set_pkgname(self, pkgname): self.pkgname = pkgname self._update_app_recommendations_content() def _update_app_recommendations_content(self): if self.app_recommendations_content: self.app_recommendations_content.remove_all() self.spinner_notebook.show_spinner(_(u"Receiving recommendations…")) # get the recommendations from the recommender agent self.app_recommendations_cat = AppRecommendationsCategory(self.pkgname) self.app_recommendations_cat.connect( 'needs-refresh', self._on_app_recommendations_agent_refresh) self.app_recommendations_cat.connect('recommender-agent-error', self._on_recommender_agent_error) def _on_app_recommendations_agent_refresh(self, cat): docs = cat.get_documents(self.catview.db) # display the recommendations if len(docs) > 0: self.catview._add_tiles_to_flowgrid(docs, self.app_recommendations_content, 3) self.show_all() self.spinner_notebook.hide_spinner() else: self._hide_app_recommendations_panel() def _on_recommender_agent_error(self, agent, msg): LOG.warn("Error while accessing the recommender agent for the " "details view recommendations: %s" % msg) # TODO: temporary, instead we will display cached recommendations here self._hide_app_recommendations_panel() def _hide_app_recommendations_panel(self): # and hide the pane self.hide()
class RecommendationsPanelDetails(RecommendationsPanel): """ Panel for use in the details view to display recommendations for a given application """ def __init__(self, catview): RecommendationsPanel.__init__(self, catview) self.set_header_label(_(u"People Also Installed")) self.app_recommendations_content = FlowableGrid() self.add(self.app_recommendations_content) def set_pkgname(self, pkgname): self.pkgname = pkgname self._update_app_recommendations_content() def _update_app_recommendations_content(self): if self.app_recommendations_content: self.app_recommendations_content.remove_all() self.spinner_notebook.show_spinner(_(u"Receiving recommendations…")) # get the recommendations from the recommender agent self.app_recommendations_cat = AppRecommendationsCategory(self.pkgname) self.app_recommendations_cat.connect( 'needs-refresh', self._on_app_recommendations_agent_refresh) self.app_recommendations_cat.connect('recommender-agent-error', self._on_recommender_agent_error) def _on_app_recommendations_agent_refresh(self, cat): docs = cat.get_documents(self.catview.db) # display the recommendations if len(docs) > 0: self.catview._add_tiles_to_flowgrid( docs, self.app_recommendations_content, 3) self.show_all() self.spinner_notebook.hide_spinner() else: self._hide_app_recommendations_panel() def _on_recommender_agent_error(self, agent, msg): LOG.warn("Error while accessing the recommender agent for the " "details view recommendations: %s" % msg) # TODO: temporary, instead we will display cached recommendations here self._hide_app_recommendations_panel() def _hide_app_recommendations_panel(self): # and hide the pane self.hide()
def _append_sub_top_rated(self): self.top_rated = FlowableGrid() self.top_rated.set_row_spacing(6) self.top_rated.set_column_spacing(6) self.top_rated_frame = FramedHeaderBox() self.top_rated_frame.pack_start(self.top_rated, True, True, 0) self.vbox.pack_start(self.top_rated_frame, False, True, 0) return
def _append_whats_new(self): self.whats_new = FlowableGrid() self.whats_new_frame = FramedHeaderBox() self.whats_new_frame.set_header_label(_(u"What\u2019s New")) self.whats_new_frame.add(self.whats_new) whats_new_cat = self._update_whats_new_content() if whats_new_cat is not None: # only add to the visible right_frame if we actually have it self.right_column.pack_start(self.whats_new_frame, True, True, 0) self.whats_new_frame.header_implements_more_button() self.whats_new_frame.more.connect('clicked', self.on_category_clicked, whats_new_cat)
def _append_top_rated(self): self.top_rated = FlowableGrid() #~ self.top_rated.row_spacing = StockEms.SMALL self.top_rated_frame = FramedHeaderBox() self.top_rated_frame.set_header_label(_("Top Rated")) self.top_rated_frame.add(self.top_rated) self.right_column.pack_start(self.top_rated_frame, True, True, 0) top_rated_cat = self._update_top_rated_content() # only display the 'More' LinkButton if we have top_rated content if top_rated_cat is not None: self.top_rated_frame.header_implements_more_button() self.top_rated_frame.more.connect('clicked', self.on_category_clicked, top_rated_cat) return
def _append_subcat_departments(self): self.subcat_label = Gtk.Label() self.subcat_label.set_alignment(0, 0.5) self.departments = FlowableGrid(paint_grid_pattern=False) self.departments.set_row_spacing(StockEms.SMALL) self.departments.set_column_spacing(StockEms.SMALL) self.departments_frame = FramedBox(spacing=StockEms.MEDIUM, padding=StockEms.MEDIUM) # set x/y-alignment and x/y-expand self.departments_frame.set(0.5, 0.0, 1.0, 1.0) self.departments_frame.pack_start(self.subcat_label, False, False, 0) self.departments_frame.pack_start(self.departments, True, True, 0) # append the departments section to the page self.vbox.pack_start(self.departments_frame, False, True, 0) return
def _update_recommended_for_you_content(self): # destroy the old content to ensure we don't see it twice # (also removes the opt-in panel if it was there) if self.recommended_for_you_content: self.recommended_for_you_content.destroy() # add the new stuff self.header_implements_more_button() self.recommended_for_you_content = FlowableGrid() self.add(self.recommended_for_you_content) self.spinner_notebook.show_spinner(_(u"Receiving recommendations…")) # get the recommendations from the recommender agent self.recommended_for_you_cat = RecommendedForYouCategory() self.recommended_for_you_cat.connect( 'needs-refresh', self._on_recommended_for_you_agent_refresh) self.recommended_for_you_cat.connect('recommender-agent-error', self._on_recommender_agent_error)
def __init__(self, catview): RecommendationsPanel.__init__(self, catview) self.set_header_label(_(u"People Also Installed")) self.app_recommendations_content = FlowableGrid() self.add(self.app_recommendations_content)
class RecommendationsPanelLobby(RecommendationsPanel): """ Panel for use in the lobby view that manages the recommendations experience, includes the initial opt-in screen and display of recommendations once they have been received from the recommender agent """ __gsignals__ = { "recommendations-opt-in": (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, (GObject.TYPE_STRING,), ), "recommendations-opt-out": (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, (), ), } def __init__(self, catview): RecommendationsPanel.__init__(self, catview) self.set_header_label(_(u"Recommended for You")) # if we already have a recommender UUID, then the user is already # opted-in to the recommender service self.recommended_for_you_content = None if self.recommender_agent.recommender_uuid: self._update_recommended_for_you_content() else: self._show_opt_in_view() def _show_opt_in_view(self): # opt in box vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, StockEms.MEDIUM) vbox.set_border_width(StockEms.LARGE) self.opt_in_vbox = vbox # for tests self.recommended_for_you_content = vbox # hook it up to the rest self.add(self.recommended_for_you_content) # opt in button button = Gtk.Button(_("Turn On Recommendations")) button.connect("clicked", self._on_opt_in_button_clicked) hbox = Gtk.Box(Gtk.Orientation.HORIZONTAL) hbox.pack_start(button, False, False, 0) vbox.pack_start(hbox, False, False, 0) self.opt_in_button = button # for tests # opt in text text = _("To make recommendations, Ubuntu Software Center " "will occasionally send to Canonical an anonymous list " "of software currently installed.") label = Gtk.Label(text) label.set_alignment(0, 0.5) label.set_line_wrap(True) vbox.pack_start(label, False, False, 0) def _on_opt_in_button_clicked(self, button): # we upload the user profile here, and only after this is finished # do we fire the request for recommendations and finally display # them here -- a spinner is shown for this process (the spec # wants a progress bar, but we don't have access to real-time # progress info) self._upload_user_profile_and_get_recommendations() def _upload_user_profile_and_get_recommendations(self): # initiate upload of the user profile here self._upload_user_profile() def _upload_user_profile(self): self.spinner_notebook.show_spinner(_(u"Submitting inventory…")) self.recommender_agent.connect("submit-profile-finished", self._on_profile_submitted) self.recommender_agent.connect("error", self._on_profile_submitted_error) self.recommender_agent.post_submit_profile(self.catview.db) def _on_profile_submitted(self, agent, profile, recommender_uuid): # after the user profile data has been uploaded, make the request # and load the the recommended_for_you content LOG.debug("The recommendations profile has been successfully " "submitted to the recommender agent") self.emit("recommendations-opt-in", recommender_uuid) self._update_recommended_for_you_content() def _on_profile_submitted_error(self, agent, msg): LOG.warn("Error while submitting the recommendations profile to the " "recommender agent: %s" % msg) # TODO: handle this! display an error message in the panel self._hide_recommended_for_you_panel() def _update_recommended_for_you_content(self): # destroy the old content to ensure we don't see it twice # (also removes the opt-in panel if it was there) if self.recommended_for_you_content: self.recommended_for_you_content.destroy() # add the new stuff self.header_implements_more_button() self.recommended_for_you_content = FlowableGrid() self.add(self.recommended_for_you_content) self.spinner_notebook.show_spinner(_(u"Receiving recommendations…")) # get the recommendations from the recommender agent self.recommended_for_you_cat = RecommendedForYouCategory() self.recommended_for_you_cat.connect( 'needs-refresh', self._on_recommended_for_you_agent_refresh) self.recommended_for_you_cat.connect('recommender-agent-error', self._on_recommender_agent_error) def _on_recommended_for_you_agent_refresh(self, cat): docs = cat.get_documents(self.catview.db) # display the recommendedations if len(docs) > 0: self.catview._add_tiles_to_flowgrid(docs, self.recommended_for_you_content, 8) self.recommended_for_you_content.show_all() self.spinner_notebook.hide_spinner() self.more.connect('clicked', self.catview.on_category_clicked, cat) else: # TODO: this test for zero docs is temporary and will not be # needed once the recommendation agent is up and running self._hide_recommended_for_you_panel() def _on_recommender_agent_error(self, agent, msg): LOG.warn("Error while accessing the recommender agent for the " "lobby recommendations: %s" % msg) # TODO: temporary, instead we will display cached recommendations here self._hide_recommended_for_you_panel() def _hide_recommended_for_you_panel(self): # and hide the pane self.hide()
class SubCategoryViewGtk(CategoriesViewGtk): def __init__(self, datadir, desktopdir, cache, db, icons, apps_filter, apps_limit=0, root_category=None): CategoriesViewGtk.__init__(self, datadir, desktopdir, cache, db, icons, apps_filter, apps_limit) # state self._built = False # data self.root_category = root_category self.enquire = AppEnquire(self.cache, self.db) self.helper = AppPropertiesHelper(self.db, self.cache, self.icons) # sections self.current_category = None self.departments = None self.toprated = None self.appcount = None # widgetry self.vbox.set_margin_left(StockEms.MEDIUM - 2) self.vbox.set_margin_right(StockEms.MEDIUM - 2) self.vbox.set_margin_top(StockEms.MEDIUM) return def _get_sub_toprated_content(self, category): app_filter = AppFilter(self.db, self.cache) self.enquire.set_query(category.query, limit=TOP_RATED_CAROUSEL_LIMIT, sortmode=SortMethods.BY_TOP_RATED, filter=app_filter, nonapps_visible=NonAppVisibility.ALWAYS_VISIBLE, nonblocking_load=False) return self.enquire.get_documents() @wait_for_apt_cache_ready # be consistent with new apps def _update_sub_toprated_content(self, category): self.toprated.remove_all() # FIXME: should this be m = "%s %s" % (_(gettext text), header text) ?? m = _('Top Rated %s') % GObject.markup_escape_text(self.header) self.toprated_frame.set_header_label(m) docs = self._get_sub_toprated_content(category) self._add_tiles_to_flowgrid(docs, self.toprated, TOP_RATED_CAROUSEL_LIMIT) return def _append_sub_toprated(self): self.toprated = FlowableGrid() self.toprated.set_row_spacing(6) self.toprated.set_column_spacing(6) self.toprated_frame = FramedHeaderBox() self.toprated_frame.pack_start(self.toprated, True, True, 0) self.vbox.pack_start(self.toprated_frame, False, True, 0) return def _update_subcat_departments(self, category, num_items): self.departments.remove_all() # set the subcat header m = "<b><big>%s</big></b>" self.subcat_label.set_markup(m % GObject.markup_escape_text(self.header)) # sort Category.name's alphabetically sorted_cats = categories_sorted_by_name(self.categories) enquire = xapian.Enquire(self.db.xapiandb) app_filter = AppFilter(self.db, self.cache) for cat in sorted_cats: # add the subcategory if and only if it is non-empty enquire.set_query(cat.query) if len(enquire.get_mset(0, 1)): tile = CategoryTile(cat.name, cat.iconname) tile.connect('clicked', self.on_category_clicked, cat) self.departments.add_child(tile) # partialy work around a (quite rare) corner case if num_items == 0: enquire.set_query( xapian.Query(xapian.Query.OP_AND, category.query, xapian.Query("ATapplication"))) # assuming that we only want apps is not always correct ^^^ tmp_matches = enquire.get_mset(0, len(self.db), None, app_filter) num_items = tmp_matches.get_matches_estimated() # append an additional button to show all of the items in the category all_cat = Category("All", _("All"), "category-show-all", category.query) name = GObject.markup_escape_text('%s %s' % (_("All"), num_items)) tile = CategoryTile(name, "category-show-all") tile.connect('clicked', self.on_category_clicked, all_cat) self.departments.add_child(tile) self.departments.queue_draw() return num_items def _append_subcat_departments(self): self.subcat_label = Gtk.Label() self.subcat_label.set_alignment(0, 0.5) self.departments = FlowableGrid(paint_grid_pattern=False) self.departments.set_row_spacing(StockEms.SMALL) self.departments.set_column_spacing(StockEms.SMALL) frame = FramedBox(spacing=StockEms.MEDIUM, padding=StockEms.MEDIUM) # set x/y-alignment and x/y-expand frame.set(0.5, 0.0, 1.0, 1.0) frame.pack_start(self.subcat_label, False, False, 0) frame.pack_start(self.departments, True, True, 0) # append the departments section to the page self.vbox.pack_start(frame, False, True, 0) return def _update_appcount(self, appcount): text = gettext.ngettext("%(amount)s item available", "%(amount)s items available", appcount) % { 'amount': appcount, } self.appcount.set_text(text) return def _append_appcount(self): self.appcount = Gtk.Label() self.appcount.set_alignment(0.5, 0.5) self.appcount.set_margin_top(1) self.appcount.set_margin_bottom(4) self.vbox.pack_end(self.appcount, False, False, 0) return def _build_subcat_view(self): # these methods add sections to the page # changing order of methods changes order that they appear in the page self._append_subcat_departments() self._append_sub_toprated() self._append_appcount() self._built = True return def _update_subcat_view(self, category, num_items=0): num_items = self._update_subcat_departments(category, num_items) self._update_sub_toprated_content(category) self._update_appcount(num_items) self.show_all() return def set_subcategory(self, root_category, num_items=0, block=False): # nothing to do if (root_category is None or self.categories == root_category.subcategories): return self.current_category = root_category self.header = root_category.name self.categories = root_category.subcategories if not self._built: self._build_subcat_view() self._update_subcat_view(root_category, num_items) GObject.idle_add(self.queue_draw) return def refresh_apps(self): supported_only = get_global_filter().supported_only if (self.current_category is None or self._supported_only == supported_only): return self._supported_only = supported_only if not self._built: self._build_subcat_view() self._update_subcat_view(self.current_category) GObject.idle_add(self.queue_draw) return
class SubCategoryViewGtk(CategoriesViewGtk): def __init__(self, datadir, desktopdir, cache, db, icons, apps_filter, apps_limit=0, root_category=None): CategoriesViewGtk.__init__(self, datadir, desktopdir, cache, db, icons, apps_filter, apps_limit) # state self._built = False # data self.root_category = root_category self.enquire = AppEnquire(self.cache, self.db) self.properties_helper = AppPropertiesHelper( self.db, self.cache, self.icons) # sections self.current_category = None self.departments = None self.top_rated = None self.recommended_for_you_in_cat = None self.appcount = None # widgetry self.vbox.set_margin_left(StockEms.MEDIUM - 2) self.vbox.set_margin_right(StockEms.MEDIUM - 2) self.vbox.set_margin_top(StockEms.MEDIUM) return def _get_sub_top_rated_content(self, category): app_filter = AppFilter(self.db, self.cache) self.enquire.set_query(category.query, limit=TOP_RATED_CAROUSEL_LIMIT, sortmode=SortMethods.BY_TOP_RATED, filter=app_filter, nonapps_visible=NonAppVisibility.ALWAYS_VISIBLE, nonblocking_load=False) return self.enquire.get_documents() @wait_for_apt_cache_ready # be consistent with new apps def _update_sub_top_rated_content(self, category): self.top_rated.remove_all() # FIXME: should this be m = "%s %s" % (_(gettext text), header text) ?? # TRANSLATORS: %s is a category name, like Internet or Development # Tools m = _('Top Rated %(category)s') % { 'category': GObject.markup_escape_text(self.header)} self.top_rated_frame.set_header_label(m) docs = self._get_sub_top_rated_content(category) self._add_tiles_to_flowgrid(docs, self.top_rated, TOP_RATED_CAROUSEL_LIMIT) return def _append_sub_top_rated(self): self.top_rated = FlowableGrid() self.top_rated.set_row_spacing(6) self.top_rated.set_column_spacing(6) self.top_rated_frame = FramedHeaderBox() self.top_rated_frame.pack_start(self.top_rated, True, True, 0) self.vbox.pack_start(self.top_rated_frame, False, True, 0) return def _update_recommended_for_you_in_cat_content(self, category): if (self.recommended_for_you_in_cat and self.recommended_for_you_in_cat.get_parent()): self.vbox.remove(self.recommended_for_you_in_cat) self.recommended_for_you_in_cat = RecommendationsPanelCategory( self, category) # only show the panel in the categories view when the user # is opted in to the recommender service # FIXME: this is needed vs. a simple hide() on the widget because # we do a show_all on the view if self.recommended_for_you_in_cat.recommender_agent.is_opted_in(): self.vbox.pack_start(self.recommended_for_you_in_cat, False, False, 0) def _update_subcat_departments(self, category, num_items): self.departments.remove_all() # set the subcat header m = "<b><big>%s</big></b>" self.subcat_label.set_markup(m % GObject.markup_escape_text( self.header)) # sort Category.name's alphabetically sorted_cats = categories_sorted_by_name(self.categories) enquire = xapian.Enquire(self.db.xapiandb) app_filter = AppFilter(self.db, self.cache) for cat in sorted_cats: # add the subcategory if and only if it is non-empty enquire.set_query(cat.query) if len(enquire.get_mset(0, 1)): tile = CategoryTile(cat.name, cat.iconname) tile.connect('clicked', self.on_category_clicked, cat) self.departments.add_child(tile) # partialy work around a (quite rare) corner case if num_items == 0: enquire.set_query(xapian.Query(xapian.Query.OP_AND, category.query, xapian.Query("ATapplication"))) # assuming that we only want apps is not always correct ^^^ tmp_matches = enquire.get_mset(0, len(self.db), None, app_filter) num_items = tmp_matches.get_matches_estimated() # append an additional button to show all of the items in the category all_cat = Category("All", _("All"), "category-show-all", category.query) name = GObject.markup_escape_text('%s %s' % (_("All"), num_items)) tile = CategoryTile(name, "category-show-all") tile.connect('clicked', self.on_category_clicked, all_cat) self.departments.add_child(tile) self.departments.queue_draw() return num_items def _append_subcat_departments(self): self.subcat_label = Gtk.Label() self.subcat_label.set_alignment(0, 0.5) self.departments = FlowableGrid(paint_grid_pattern=False) self.departments.set_row_spacing(StockEms.SMALL) self.departments.set_column_spacing(StockEms.SMALL) self.departments_frame = FramedBox(spacing=StockEms.MEDIUM, padding=StockEms.MEDIUM) # set x/y-alignment and x/y-expand self.departments_frame.set(0.5, 0.0, 1.0, 1.0) self.departments_frame.pack_start(self.subcat_label, False, False, 0) self.departments_frame.pack_start(self.departments, True, True, 0) # append the departments section to the page self.vbox.pack_start(self.departments_frame, False, True, 0) return def _update_appcount(self, appcount): text = gettext.ngettext("%(amount)s item available", "%(amount)s items available", appcount) % {'amount': appcount} self.appcount.set_text(text) return def _append_appcount(self): self.appcount = Gtk.Label() self.appcount.set_alignment(0.5, 0.5) self.appcount.set_margin_top(1) self.appcount.set_margin_bottom(4) self.vbox.pack_end(self.appcount, False, False, 0) return def _build_subcat_view(self): # these methods add sections to the page # changing order of methods changes order that they appear in the page self._append_subcat_departments() self._append_sub_top_rated() # NOTE that the recommended for you in category view is built and added # in the _update_recommended_for_you_in_cat method (and so is not # needed here) self._append_appcount() self._built = True return def _update_subcat_view(self, category, num_items=0): num_items = self._update_subcat_departments(category, num_items) self._update_sub_top_rated_content(category) self._update_recommended_for_you_in_cat_content(category) self._update_appcount(num_items) self.show_all() return def set_subcategory(self, root_category, num_items=0, block=False): # nothing to do if (root_category is None or self.categories == root_category.subcategories): return self.current_category = root_category self.header = root_category.name self.categories = root_category.subcategories if not self._built: self._build_subcat_view() self._update_subcat_view(root_category, num_items) GObject.idle_add(self.queue_draw) return def refresh_apps(self): supported_only = get_global_filter().supported_only if (self.current_category is None or self._supported_only == supported_only): return self._supported_only = supported_only if not self._built: self._build_subcat_view() self._update_subcat_view(self.current_category) GObject.idle_add(self.queue_draw) return