diff --git a/rigo/data/icons/comment-separator.svg b/rigo/data/icons/comment-separator.svg deleted file mode 100644 index 31d2dbdb4..000000000 --- a/rigo/data/icons/comment-separator.svg +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - diff --git a/rigo/data/ui/gtk3/css/rigo.css b/rigo/data/ui/gtk3/css/rigo.css index aba27a8ac..d9b09be76 100644 --- a/rigo/data/ui/gtk3/css/rigo.css +++ b/rigo/data/ui/gtk3/css/rigo.css @@ -106,6 +106,7 @@ GtkInfoBar #message-area-error GtkLabel { } /* Application View Comment Box */ + #comment-box-title { color: #613056; /* purple */ } @@ -114,4 +115,4 @@ GtkInfoBar #message-area-error GtkLabel { } #comment-box-author { color: brown; -} \ No newline at end of file +} diff --git a/rigo/data/ui/gtk3/rigo.ui b/rigo/data/ui/gtk3/rigo.ui index 092ea657f..ab9738ff9 100644 --- a/rigo/data/ui/gtk3/rigo.ui +++ b/rigo/data/ui/gtk3/rigo.ui @@ -26,7 +26,7 @@ - 600 + 650 400 True False @@ -264,11 +264,21 @@ - + True False + 5 + 25 + 25 - + + 300 + True + False + + + + @@ -278,11 +288,21 @@ - + True False + 5 + 25 + 25 - + + 300 + True + False + + + + @@ -295,20 +315,6 @@ True False - - - True - False - <small><i>Comment this <b>Application</b></i></small> - True - True - - - True - True - 0 - - True @@ -332,7 +338,7 @@ True True - 1 + 0 @@ -341,13 +347,20 @@ False - _Send True True True False - appViewCommentSendImage1 True + + + True + False + _Write a <b>comment</b> + True + True + + True @@ -360,7 +373,19 @@ True True 4 - 3 + 1 + + + + + True + False + Want to see more? + + + True + True + 2 diff --git a/rigo/rigo/models/application.py b/rigo/rigo/models/application.py index 4a85afb5c..5831de839 100644 --- a/rigo/rigo/models/application.py +++ b/rigo/rigo/models/application.py @@ -36,12 +36,13 @@ from entropy.client.services.interfaces import ClientWebService import entropy.tools from rigo.enums import Icons +from rigo.utils import build_application_store_url LOG = logging.getLogger(__name__) class ReviewStats(object): - NO_RATING = 1 + NO_RATING = 0 def __init__(self, app): self.app = app @@ -816,12 +817,17 @@ class Application(object): else: use_txt += _("No use flags") - text = "%s\n%s\n%s\n%s\n%s" % ( + more_txt = "%s" % ( + build_application_store_url(self, ""), + _("Click here for more details"),) + + text = "%s\n%s\n%s\n%s\n%s\n\n%s" % ( down_size_txt, required_space_txt, licenses_txt, digest_txt, use_txt, + more_txt, ) return text diff --git a/rigo/rigo/ui/gtk3/widgets/comments.py b/rigo/rigo/ui/gtk3/widgets/comments.py index 8ee572e65..52d2e13be 100644 --- a/rigo/rigo/ui/gtk3/widgets/comments.py +++ b/rigo/rigo/ui/gtk3/widgets/comments.py @@ -32,6 +32,27 @@ class CommentBox(Gtk.VBox): self._is_last = is_last def render(self): + + vbox = Gtk.VBox() + + ts_id = Document.DOCUMENT_TIMESTAMP_ID + user_id = DocumentFactory.DOCUMENT_USERNAME_ID + label = Gtk.Label() + time_str = entropy.tools.convert_unix_time_to_human_time( + self._comment[ts_id]) + time_str = GObject.markup_escape_text(time_str) + label.set_markup( + "%s" % (self._comment[user_id],) \ + + ", " + time_str + "" \ + + "") + label.set_line_wrap(True) + label.set_line_wrap_mode(Pango.WrapMode.WORD) + label.set_alignment(0.0, 1.0) + label.set_selectable(True) + label.set_name("comment-box-author") + label.show() + vbox.pack_start(label, False, False, 0) + # title, keywords, ddata, document_id title = self._comment['title'].strip() @@ -45,7 +66,7 @@ class CommentBox(Gtk.VBox): label.set_alignment(0.0, 0.0) label.set_selectable(True) label.show() - self.pack_start(label, False, False, 0) + vbox.pack_start(label, False, False, 0) data_id = Document.DOCUMENT_DATA_ID label = Gtk.Label() @@ -56,29 +77,13 @@ class CommentBox(Gtk.VBox): label.set_alignment(0.0, 0.0) label.set_selectable(True) label.show() - self.pack_start(label, False, False, 0) + vbox.pack_start(label, False, False, 0) - ts_id = Document.DOCUMENT_TIMESTAMP_ID - user_id = DocumentFactory.DOCUMENT_USERNAME_ID - label = Gtk.Label() - time_str = entropy.tools.convert_unix_time_to_human_time( - self._comment[ts_id]) - time_str = GObject.markup_escape_text(time_str) - label.set_markup( - "" + time_str \ - + ", %s" % (self._comment[user_id],) \ - + "") - label.set_line_wrap(True) - label.set_line_wrap_mode(Pango.WrapMode.WORD) - label.set_alignment(0.98, 0.0) - label.set_selectable(True) - label.set_name("comment-box-author") - label.show() - self.pack_start(label, False, False, 0) - - if not self._is_last: - image = Gtk.Image.new_from_icon_name("comment-separator", - Gtk.IconSize.BUTTON) - image.set_pixel_size(50) - self.pack_start(image, False, False, 0) - image.show() + if self._is_last: + self.pack_start(vbox, False, False, 0) + else: + align = Gtk.Alignment() + align.set_padding(0, 10, 0, 0) + align.add(vbox) + self.pack_start(align, False, False, 0) + align.show_all() diff --git a/rigo/rigo/ui/gtk3/widgets/notifications.py b/rigo/rigo/ui/gtk3/widgets/notifications.py index d10a2ad33..b66584c9b 100644 --- a/rigo/rigo/ui/gtk3/widgets/notifications.py +++ b/rigo/rigo/ui/gtk3/widgets/notifications.py @@ -1,11 +1,16 @@ +import subprocess + from gi.repository import Gtk, GLib, GObject +from rigo.utils import build_register_url, open_url + from entropy.i18n import _ from entropy.services.client import WebService from entropy.misc import ParallelTask + class NotificationBox(Gtk.HBox): """ @@ -14,7 +19,8 @@ class NotificationBox(Gtk.HBox): """ def __init__(self, message, message_widget=None, - message_type=None, tooltip=None): + message_type=None, tooltip=None, + context_id=None): Gtk.HBox.__init__(self) self._message = message # if not None, it will replace Gtk.Label(self._message) @@ -24,6 +30,7 @@ class NotificationBox(Gtk.HBox): if self._type is None: self._type = Gtk.MessageType.INFO self._tooltip = tooltip + self._context_id = context_id def add_button(self, text, clicked_callback): """ @@ -82,6 +89,15 @@ class NotificationBox(Gtk.HBox): bar.get_action_area().hide() self.pack_start(bar, True, True, 0) + def get_context_id(self): + """ + Multiple NotificationBox instances can + share the same context_id. This information + is useful when showing multiple notifications + sharing the same context is unwanted. + """ + return self._context_id + class UpdatesNotificationBox(NotificationBox): @@ -118,7 +134,8 @@ class UpdatesNotificationBox(NotificationBox): NotificationBox.__init__(self, msg, tooltip=_("Updates available, how about installing them?"), - message_type=Gtk.MessageType.WARNING) + message_type=Gtk.MessageType.WARNING, + context_id="UpdatesNotificationBox") self.add_button(_("_Update System"), self._update) self.add_button(_("_Show"), self._show) self.add_destroy_button(_("_Ignore")) @@ -154,7 +171,8 @@ class RepositoriesUpdateNotificationBox(NotificationBox): NotificationBox.__init__(self, msg, tooltip=_("I dunno dude, I'd say Yes"), - message_type=Gtk.MessageType.ERROR) + message_type=Gtk.MessageType.ERROR, + context_id="RepositoriesUpdateNotificationBox") self.add_button(_("_Yes, why not?"), self._update) self.add_destroy_button(_("_No, thanks")) @@ -185,17 +203,21 @@ class LoginNotificationBox(NotificationBox): ), } - def __init__(self, entropy_ws, app): + def __init__(self, entropy_ws, app, context_id=None): self._entropy_ws = entropy_ws self._app = app self._repository_id = app.get_details().channelname + if context_id is None: + context_id = "LoginNotificationBox" NotificationBox.__init__(self, None, message_widget=self._make_login_box(), tooltip=_("You need to login to Entropy Web Services"), - message_type=Gtk.MessageType.WARNING) + message_type=Gtk.MessageType.WARNING, + context_id=context_id) self.add_button(_("_Login"), self._login) + self.add_button(_("Register"), self._register) def _destroy(*args): self.emit("login-failed", self._app) @@ -277,3 +299,8 @@ class LoginNotificationBox(NotificationBox): task.daemon = True task.start() + def _register(self, button): + """ + Register button click event. + """ + open_url(build_register_url()) diff --git a/rigo/rigo/utils.py b/rigo/rigo/utils.py index 8b4a42154..a0a922713 100644 --- a/rigo/rigo/utils.py +++ b/rigo/rigo/utils.py @@ -1,8 +1,10 @@ import os +import subprocess from entropy.const import etpConst from entropy.core.settings.base import SystemSettings +from entropy.misc import ParallelTask def build_application_store_url(app, sub_page): """ @@ -33,3 +35,15 @@ def build_register_url(): Build User Account Registration Form URL. """ return os.path.join(etpConst['distro_website_url'], "register") + +def open_url(url): + """ + Open the given URL using xdg-open + """ + def _open_url(url): + subprocess.call(["xdg-open", url]) + + task = ParallelTask(_open_url, url) + task.name = "UrlOpen" + task.daemon = True + task.start() diff --git a/rigo/rigo_app.py b/rigo/rigo_app.py index a5dab720f..6b8fcd3ea 100644 --- a/rigo/rigo_app.py +++ b/rigo/rigo_app.py @@ -169,6 +169,7 @@ class NotificationViewController(GObject.Object): self._box = notification_box self._updates = None self._security_updates = None + self._context_id_map = {} def setup(self): GLib.timeout_add(3000, self._calculate_updates) @@ -238,10 +239,18 @@ class NotificationViewController(GObject.Object): """ self._avc.set_many_safe(self._updates) - def append(self, box, timeout=None): + def append(self, box, timeout=None, context_id=None): """ Append a notification to the Notification area. + context_id is used to automatically drop any other + notification exposing the same context identifier. """ + context_id = box.get_context_id() + if context_id is not None: + old_box = self._context_id_map.get(context_id) + if old_box is not None: + old_box.destroy() + self._context_id_map[context_id] = box box.render() self._box.pack_start(box, False, False, 0) box.show() @@ -263,7 +272,7 @@ class NotificationViewController(GObject.Object): area, if there. """ if box in self._box.get_children(): - self._box.remove(box) + self._context_id_map.pop(box.get_context_id(), None) box.destroy() def remove_safe(self, box): @@ -277,8 +286,8 @@ class NotificationViewController(GObject.Object): Clear all the notifications. """ for child in self._box.get_children(): - self._box.remove(child) child.destroy() + self._context_id_map.clear() def clear_safe(self): """ @@ -294,6 +303,19 @@ class ApplicationViewController(GObject.Object): TreeView. """ + class WindowedReactiveStar(ReactiveStar): + + def __init__(self, window): + self._window = window + self._hand = Gdk.Cursor.new(Gdk.CursorType.HAND2) + ReactiveStar.__init__(self) + + def on_enter_notify(self, widget, event): + self._window.get_window().set_cursor(self._hand) + + def on_leave_notify(self, widget, event): + self._window.get_window().set_cursor(None) + __gsignals__ = { # Double click on application widget "application-activated" : (GObject.SignalFlags.RUN_LAST, @@ -325,6 +347,9 @@ class ApplicationViewController(GObject.Object): ), } + VOTE_NOTIFICATION_CONTEXT_ID = "VoteNotificationContext" + COMMENT_NOTIFICATION_CONTEXT_ID = "CommentNotificationContext" + def __init__(self, entropy_client, entropy_ws, builder): GObject.Object.__init__(self) self._builder = builder @@ -334,14 +359,21 @@ class ApplicationViewController(GObject.Object): self._last_app = None self._nc = None + self._window = self._builder.get_object("rigoWindow") self._image = self._builder.get_object("appViewImage") self._app_name_lbl = self._builder.get_object("appViewNameLabel") self._app_info_lbl = self._builder.get_object("appViewInfoLabel") self._app_downloaded_lbl = self._builder.get_object( "appViewDownloadedLabel") self._app_comments_box = self._builder.get_object("appViewCommentsVbox") + self._app_comments_box.set_name("comments-box") + self._app_comments_align = self._builder.get_object( + "appViewCommentsAlign") self._app_my_comments_box = self._builder.get_object( "appViewMyCommentsVbox") + self._app_my_comments_align = self._builder.get_object( + "appViewMyCommentsAlign") + self._app_my_comments_box.set_name("comments-box") self._app_comment_send_button = self._builder.get_object( "appViewCommentSendButton") self._app_comment_text_view = self._builder.get_object( @@ -349,9 +381,12 @@ class ApplicationViewController(GObject.Object): self._app_comment_text_view.set_name("rigo-text-view") self._app_comment_text_buffer = self._builder.get_object( "appViewCommentTextBuffer") + self._app_comment_more_label = self._builder.get_object( + "appViewCommentMoreLabel") self._stars_container = self._builder.get_object("appViewStarsSelVbox") - self._stars = ReactiveStar() + self._stars = ApplicationViewController.WindowedReactiveStar( + self._window) 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) @@ -378,6 +413,7 @@ class ApplicationViewController(GObject.Object): self._app_comment_send_button.set_sensitive(False) self._app_comment_text_buffer.connect( "changed", self._on_comment_buffer_changed) + self._stars.connect("changed", self._on_stars_clicked) def _on_comment_buffer_changed(self, widget): """ @@ -411,6 +447,149 @@ class ApplicationViewController(GObject.Object): icon = self._app_store.get_icon(pkg_match) self._setup_application_stats(stats, icon) + def _on_stars_clicked(self, widget, app=None): + """ + Stars clicked, user wants to vote. + """ + if app is None: + app = self._last_app + if app is None: + # wtf + return + + def _sender(app, vote): + if not app.is_webservice_available(): + GLib.idle_add(self._notify_webservice_na, app, + self.VOTE_NOTIFICATION_CONTEXT_ID) + return + ws_user = app.get_webservice_username() + if ws_user is not None: + GLib.idle_add(self._notify_vote_submit, app, ws_user, vote) + else: + GLib.idle_add(self._notify_login_request, app, vote, + self._on_stars_login_success, + self._on_stars_login_failed, + self.VOTE_NOTIFICATION_CONTEXT_ID) + + vote = int(self._stars.get_rating()) # is float + task = ParallelTask(_sender, app, vote) + task.name = "AppViewSendVote" + task.start() + + def _on_stars_login_success(self, widget, username, app): + """ + Notify user that we successfully logged in! + """ + box = NotificationBox( + _("Logged in as %s! How about your vote?") \ + % (GObject.markup_escape_text(username),), + message_type=Gtk.MessageType.INFO, + context_id=self.VOTE_NOTIFICATION_CONTEXT_ID) + + def _send_vote(widget): + # widget.destroy() + self._on_stars_clicked(self._stars, app=app) + box.add_button(_("_Vote now"), _send_vote) + + box.add_destroy_button(_("_Abort")) + self._nc.append(box) + + def _on_stars_login_failed(self, widget, app): + """ + Entropy Web Services Login failed message. + """ + box = NotificationBox( + _("Login failed. Your vote hasn't been added"), + message_type=Gtk.MessageType.ERROR, + context_id=self.VOTE_NOTIFICATION_CONTEXT_ID) + box.add_destroy_button(_("_Ok, thanks")) + self._nc.append(box) + + def _notify_vote_submit(self, app, username, vote): + """ + Notify User about Comment submission with current credentials. + """ + box = NotificationBox( + _("Rate %s as %s, with %d stars?") \ + % (app.name, GObject.markup_escape_text(username), + vote,), + message_type=Gtk.MessageType.INFO, + context_id=self.VOTE_NOTIFICATION_CONTEXT_ID) + + def _vote_submit(widget): + #box.destroy() + self._vote_submit(app, username, vote) + box.add_button(_("_Ok, cool!"), _vote_submit) + + def _send_vote(): + self._on_stars_clicked(self._stars, app=app) + def _logout_webservice(widget): + #box.destroy() + self._logout_webservice(app, _send_vote) + box.add_button(_("_No, logout!"), _logout_webservice) + + box.add_destroy_button(_("_Abort")) + self._nc.append(box) + + def _vote_submit(self, app, username, vote): + """ + Do the actual vote submit. + """ + task = ParallelTask( + self._vote_submit_thread_body, + app, username, vote) + task.name = "VoteSubmitThreadBody" + task.daemon = True + task.start() + + def _vote_submit_thread_body(self, app, username, vote): + """ + Called by _vote_submit(), does the actualy submit. + """ + repository_id = app.get_details().channelname + webserv = self._entropy_ws.get(repository_id) + if webserv is None: + # impossible! + return + + key = app.get_details().pkgkey + + err_msg = None + try: + voted = webserv.add_vote( + key, vote) + except WebService.WebServiceException as err: + voted = False + err_msg = str(err) + + def _submit_success(): + nbox = NotificationBox( + _("Your vote has been added!"), + message_type=Gtk.MessageType.INFO, + context_id=self.VOTE_NOTIFICATION_CONTEXT_ID) + nbox.add_destroy_button(_("Ok, great!")) + self._nc.append(nbox, timeout=10) + self._on_redraw_request(None, app.get_details().pkg) + + def _submit_fail(err_msg): + if err_msg is None: + box = NotificationBox( + _("You already voted this Application"), + message_type=Gtk.MessageType.ERROR, + context_id=self.VOTE_NOTIFICATION_CONTEXT_ID) + else: + box = NotificationBox( + _("Vote error: %s") % (err_msg,), + message_type=Gtk.MessageType.ERROR, + context_id=self.VOTE_NOTIFICATION_CONTEXT_ID) + box.add_destroy_button(_("Ok, thanks")) + self._nc.append(box) + + if voted: + GLib.idle_add(_submit_success) + else: + GLib.idle_add(_submit_fail, err_msg) + def __application_activate(self, app): """ Collect data from app, then call the UI setup in the main loop. @@ -456,19 +635,23 @@ class ApplicationViewController(GObject.Object): def _sender(app, text): if not app.is_webservice_available(): - GLib.idle_add(self._notify_webservice_na, app) + GLib.idle_add(self._notify_webservice_na, app, + self.COMMENT_NOTIFICATION_CONTEXT_ID) return ws_user = app.get_webservice_username() if ws_user is not None: GLib.idle_add(self._notify_comment_submit, app, ws_user, text) else: - GLib.idle_add(self._notify_login_request, app, text) + GLib.idle_add(self._notify_login_request, app, text, + self._on_comment_login_success, + self._on_comment_login_failed, + self.COMMENT_NOTIFICATION_CONTEXT_ID) task = ParallelTask(_sender, app, text) task.name = "AppViewSendComment" task.start() - def _notify_webservice_na(self, app): + def _notify_webservice_na(self, app, context_id): """ Notify Web Service unavailability for given Application object. """ @@ -476,7 +659,8 @@ class ApplicationViewController(GObject.Object): "%s: %s" % ( _("Entropy Web Services not available for repository"), app.get_details().channelname), - message_type=Gtk.MessageType.ERROR) + message_type=Gtk.MessageType.ERROR, + context_id=context_id) box.add_destroy_button(_("Ok, thanks")) self._nc.append(box) @@ -487,15 +671,16 @@ class ApplicationViewController(GObject.Object): box = NotificationBox( _("You are about to add a comment as %s.") \ % (GObject.markup_escape_text(username),), - message_type=Gtk.MessageType.INFO) + message_type=Gtk.MessageType.INFO, + context_id=self.COMMENT_NOTIFICATION_CONTEXT_ID) def _comment_submit(widget): - box.destroy() + #box.destroy() self._comment_submit(app, username, text) box.add_button(_("_Ok, cool!"), _comment_submit) def _logout_webservice(widget): - box.destroy() + #box.destroy() self._logout_webservice(app) box.add_button(_("_No, logout!"), _logout_webservice) @@ -544,7 +729,8 @@ class ApplicationViewController(GObject.Object): nbox = NotificationBox( _("Your comment has been submitted!"), - message_type=Gtk.MessageType.INFO) + message_type=Gtk.MessageType.INFO, + context_id=self.COMMENT_NOTIFICATION_CONTEXT_ID) nbox.add_destroy_button(_("Ok, great!")) self._app_comment_text_buffer.set_text("") self._nc.append(nbox, timeout=10) @@ -552,7 +738,8 @@ class ApplicationViewController(GObject.Object): def _submit_fail(): box = NotificationBox( _("Comment submit error: %s") % (err_msg,), - message_type=Gtk.MessageType.ERROR) + message_type=Gtk.MessageType.ERROR, + context_id=self.COMMENT_NOTIFICATION_CONTEXT_ID) box.add_destroy_button(_("Ok, thanks")) self._nc.append(box) @@ -561,7 +748,7 @@ class ApplicationViewController(GObject.Object): else: GLib.idle_add(_submit_fail) - def _logout_webservice(self, app): + def _logout_webservice(self, app, reinit_callback): """ Execute logout of current credentials from Web Service. Actually, this means removing the local cookie. @@ -571,17 +758,16 @@ class ApplicationViewController(GObject.Object): if webserv is not None: webserv.remove_credentials() - def _send_comment(): - self._on_send_comment(None, app=app) - GLib.idle_add(_send_comment) + GLib.idle_add(reinit_callback) - def _notify_login_request(self, app, text): + def _notify_login_request(self, app, text, on_success, on_fail, + context_id): """ Notify User that login is required """ box = LoginNotificationBox(self._entropy_ws, app) - box.connect("login-success", self._on_comment_login_success) - box.connect("login-failed", self._on_comment_login_failed) + box.connect("login-success", on_success) + box.connect("login-failed", on_fail) self._nc.append(box) def _on_comment_login_success(self, widget, username, app): @@ -591,9 +777,10 @@ class ApplicationViewController(GObject.Object): box = NotificationBox( _("Logged in as %s! How about your comment?") \ % (GObject.markup_escape_text(username),), - message_type=Gtk.MessageType.INFO) + message_type=Gtk.MessageType.INFO, + context_id=self.COMMENT_NOTIFICATION_CONTEXT_ID) def _send_comment(widget): - box.destroy() + #box.destroy() self._on_send_comment(widget, app=app) box.add_button(_("_Send now"), _send_comment) box.add_destroy_button(_("_Abort")) @@ -605,7 +792,8 @@ class ApplicationViewController(GObject.Object): """ box = NotificationBox( _("Login failed. Your comment hasn't been added"), - message_type=Gtk.MessageType.ERROR) + message_type=Gtk.MessageType.ERROR, + context_id=self.COMMENT_NOTIFICATION_CONTEXT_ID) box.add_destroy_button(_("_Ok, thanks")) self._nc.append(box) @@ -624,33 +812,25 @@ class ApplicationViewController(GObject.Object): label.set_markup( _("No comments for this Application, yet!")) self._app_comments_box.pack_start(label, False, False, 1) - - label = Gtk.Label() - url = build_register_url() - url = GObject.markup_escape_text(url) - reg_msg = _("You need to register here") % ( - url,) - label.set_markup("" + reg_msg + "") label.show() - self._app_comments_box.pack_start(label, False, False, 1) return if has_more: + button_box = Gtk.HButtonBox() button = Gtk.Button() button.set_label(_("Older comments")) button.set_alignment(0.5, 0.5) def _enqueue_download(widget): - widget.hide() + widget.get_parent().destroy() spinner = Gtk.Spinner() - spinner.set_size_request(-1, 24) + spinner.set_size_request(24, 24) spinner.set_tooltip_text(_("Loading older comments...")) spinner.set_name("comment-box-spinner") - self._app_comments_box.pack_start(spinner, False, False, 3) + self._app_comments_box.pack_end(spinner, False, False, 3) spinner.show() downloader.enqueue_download() button.connect("clicked", _enqueue_download) - button_box = Gtk.HButtonBox() button_box.pack_start(button, False, False, 0) self._app_comments_box.pack_start(button_box, False, False, 1) button_box.show_all() @@ -687,7 +867,7 @@ class ApplicationViewController(GObject.Object): self._app_downloaded_lbl.set_markup(down_msg) if icon: self._image.set_from_pixbuf(icon) - self._stars.set_rating(stats.ratings_average - 1) + self._stars.set_rating(stats.ratings_average) self._stars_alignment.show_all() def _setup_application_info(self, app, metadata): @@ -699,7 +879,15 @@ class ApplicationViewController(GObject.Object): # FIXME, lxnay complete # install/remove/update buttons - # for the rest, point to the remote www service + + + # only comments supported, point to the remote + # www service for the rest + self._app_comment_more_label.set_markup( + "%s: %s" % ( + _("Want to add images, etc?"), + build_application_store_url(app, "ugc"), + _("click here!"),)) stats = metadata['stats'] icon = metadata['icon'] @@ -733,16 +921,7 @@ class ApplicationViewController(GObject.Object): self._avc = avc self._offset = 0 self._callback = callback - self._avc.connect("application-hide", self.stop) self._task = ParallelTask(self._download) - self._started = False - - def stop(self, *args): - """ - Stop downloading comments, if we're still doing it. - """ - self._started = False - print("Application-hide called, this is", self) def start(self): """ @@ -750,7 +929,6 @@ class ApplicationViewController(GObject.Object): Loop over until we have more of them to download. """ self._offset = 0 - self._started = True self._task.start() def _download_callback(self, document_list):