def __init__(self, caption): Gtk.VBox.__init__(self, spacing=0) self.value = MarkupLabel(xalign=0.5) self.value.set_margin_bottom(6) self.caption = MarkupLabel(xalign=0.5) self.caption.set_text(caption) self.pack_start(self.value, False, False, 0) self.pack_start(self.caption, False, False, 0)
def __init__(self, base, image, caption): Gtk.VBox.__init__(self, spacing=0) icon = Gtk.Image() icon.set_from_pixbuf(base.load_image(image, True)) title = MarkupLabel() title.set_markup('<b>%s</b>' % caption) self.description = MarkupLabel() self.description.set_margin_bottom(10) title_box = Gtk.HBox() title_box.set_margin_bottom(4) title_box.pack_start(icon, False, False, 0) title_box.pack_start(title, False, False, 5) desc_box = Gtk.HBox() desc_box.pack_start(self.description, True, True, 0) self.pack_start(title_box, False, False, 0) self.pack_start(desc_box, False, False, 0)
class DescriptionBox(Gtk.VBox): def __init__(self, base, image, caption): Gtk.VBox.__init__(self, spacing=0) icon = Gtk.Image() icon.set_from_pixbuf(base.load_image(image, True)) title = MarkupLabel() title.set_markup('<b>%s</b>' % caption) self.description = MarkupLabel() self.description.set_margin_bottom(10) title_box = Gtk.HBox() title_box.set_margin_bottom(4) title_box.pack_start(icon, False, False, 0) title_box.pack_start(title, False, False, 5) desc_box = Gtk.HBox() desc_box.pack_start(self.description, True, True, 0) self.pack_start(title_box, False, False, 0) self.pack_start(desc_box, False, False, 0) def set_description(self, message, as_link=False): if as_link: self.description.set_markup('<a href="%s">%s</a>' % (message, message)) else: self.description.set_markup(message)
class StatBox(Gtk.VBox): def __init__(self, caption): Gtk.VBox.__init__(self, spacing=0) self.value = MarkupLabel(xalign=0.5) self.value.set_margin_bottom(6) self.caption = MarkupLabel(xalign=0.5) self.caption.set_text(caption) self.pack_start(self.value, False, False, 0) self.pack_start(self.caption, False, False, 0) def set_value(self, value): self.value.set_markup('<b>%s</b>' % value)
def __init__(self, base): Gtk.VBox.__init__(self, spacing=0) self.base = base self.avatar = Gtk.Image() self.avatar.set_margin_right(AVATAR_MARGIN) # This resize is to avoid bad redimentioning on parent window self.set_size_request(300, -1) avatar_box = Gtk.Alignment() avatar_box.add(self.avatar) avatar_box.set(0.5, 0, -1, -1) #avatar_box.connect('button-press-event', self.__on_click_avatar) self.favorited_mark = Gtk.Image() self.protected_mark = Gtk.Image() self.verified_mark = Gtk.Image() self.reposted_mark = Gtk.Image() self.repeated_mark = Gtk.Image() self.username = MarkupLabel() self.username.set_ellipsize(Pango.EllipsizeMode.END) self.fullname = MarkupLabel() fullname_box = Gtk.HBox() fullname_box.pack_start(self.fullname, False, False, 2) fullname_box.pack_start(self.verified_mark, False, False, 2) fullname_box.pack_start(self.protected_mark, False, False, 0) userdata_box = Gtk.VBox() userdata_box.pack_start(fullname_box, False, False, 2) userdata_box.pack_start(self.username, False, False, 2) header_box = Gtk.HBox() header_box.set_border_width(BORDER_WIDTH) header_box.pack_start(avatar_box, False, False, 0) header_box.pack_start(userdata_box, False, False, 0) self.bio = DescriptionBox(self.base, 'icon-bio.png', i18n.get('bio')) self.location = DescriptionBox(self.base, 'icon-location.png', i18n.get('location')) self.web = DescriptionBox(self.base, 'icon-home.png', i18n.get('web')) desc_box = Gtk.VBox(spacing=0) desc_box.set_border_width(BORDER_WIDTH) desc_box.pack_start(self.bio, False, False, 0) desc_box.pack_start(self.location, False, False, 0) desc_box.pack_start(self.web, False, False, 0) self.following = StatBox(i18n.get('following')) self.followers = StatBox(i18n.get('followers')) self.statuses = StatBox(i18n.get('statuses')) self.favorites = StatBox(i18n.get('favorites')) stats_box = Gtk.HBox(spacing=0) stats_box.set_border_width(BORDER_WIDTH) stats_box.pack_start(self.following, True, True, 0) stats_box.pack_start(Gtk.VSeparator(), False, False, 2) stats_box.pack_start(self.followers, True, True, 0) stats_box.pack_start(Gtk.VSeparator(), False, False, 2) stats_box.pack_start(self.statuses, True, True, 0) stats_box.pack_start(Gtk.VSeparator(), False, False, 2) stats_box.pack_start(self.favorites, True, True, 0) self.pack_start(header_box, False, False, 0) self.pack_start(Gtk.HSeparator(), False, False, 0) self.pack_start(desc_box, False, False, 0) self.pack_start(Gtk.HSeparator(), False, False, 0) self.pack_start(stats_box, False, False, 0)
def __init__(self, base, status): Gtk.EventBox.__init__(self) self.base = base self.status = status self.set_margin_bottom(OUTTER_BOTTOM_MARGIN) self.modify_bg(Gtk.StateType.NORMAL, Gdk.Color(65535, 65535, 65535)) # Variables to control work in progress over the status self.in_progress = { StatusProgress.FAVING: False, StatusProgress.UNFAVING: False, StatusProgress.RETWEETING: False, StatusProgress.UNRETWEETING: False, StatusProgress.DELETING: False, } self.avatar = Gtk.Image() self.avatar.set_margin_right(AVATAR_MARGIN) self.avatar_box = Gtk.Alignment() self.avatar_box.add(self.avatar) self.avatar_box.set(0.5, 0, -1, -1) self.favorited_mark = Gtk.Image() self.protected_mark = Gtk.Image() self.verified_mark = Gtk.Image() self.reposted_mark = Gtk.Image() self.repeated_mark = Gtk.Image() self.username = MarkupLabel(act_as_link=True) self.username.set_ellipsize(Pango.EllipsizeMode.END) self.status_text = MarkupLabel() self.footer = MarkupLabel() # Setting user image self.avatar.set_from_pixbuf(self.base.load_image('unknown.png', True)) # Building the status style user = '******' % ( self.base.get_color_scheme('links'), status.username ) self.username.set_markup(user) text = status.text.replace('>', '>') text = text.replace('<', '<') pango_text = '<span size="9000">%s</span>' % escape_text_for_markup(text) pango_text = self.__highlight_urls(status, pango_text) pango_text = self.__highlight_hashtags(status, pango_text) pango_text = self.__highlight_groups(status, pango_text) pango_text = self.__highlight_mentions(status, pango_text) self.status_text.set_markup(pango_text) footer = '<span size="small" foreground="#999">%s' % status.datetime if status.source: footer += ' %s %s' % (_('from'), status.source.name) if status.in_reply_to_user: footer += ' %s %s' % (_('in reply to'), status.in_reply_to_user) if status.reposted_by: footer += '\n%s %s' % (_('Retweeted by'), status.reposted_by) footer += '</span>' self.footer.set_markup(footer) starbox = Gtk.HBox() starbox.pack_start(self.repeated_mark, False, False, 2) starbox.pack_start(self.favorited_mark, False, False, 2) staralign = Gtk.Alignment() staralign.set(1, -1, -1, -1) staralign.add(starbox) header = Gtk.HBox() header.pack_start(self.reposted_mark, False, False, 2) header.pack_start(self.username, False, False, 2) header.pack_start(self.verified_mark, False, False, 2) header.pack_start(self.protected_mark, False, False, 0) header.pack_start(staralign, True, True, 0) content = Gtk.VBox() content.pack_start(header, False, False, 0) content.pack_start(self.status_text, True, True, 0) content.pack_start(self.footer, False, False, 0) box = Gtk.HBox() box.pack_start(self.avatar_box, False, False, 0) box.pack_start(content, True, True, 0) bbox = Gtk.VBox() bbox.pack_start(box, True, True, 0) self.add(bbox) self.show_all() # After showing all widgets we set the marks self.set_favorited_mark(status.favorited) self.set_protected_mark(status.protected) self.set_verified_mark(status.verified) self.set_repeated_mark(status.repeated) self.set_reposted_mark(status.reposted_by) self.connect('button-release-event', self.__on_click) self.click_url_handler = self.status_text.connect('activate-link', self.__open_url) self.click_avatar_handler = self.avatar_box.connect('button-press-event', self.__on_click_avatar) self.click_username_handler = self.username.connect('button-release-event', self.__on_click_username) self.base.fetch_status_avatar(status, self.update_avatar)
class ProfileBox(Gtk.VBox): def __init__(self, base): Gtk.VBox.__init__(self, spacing=0) self.base = base self.avatar = Gtk.Image() self.avatar.set_margin_right(AVATAR_MARGIN) # This resize is to avoid bad redimentioning on parent window self.set_size_request(300, -1) avatar_box = Gtk.Alignment() avatar_box.add(self.avatar) avatar_box.set(0.5, 0, -1, -1) #avatar_box.connect('button-press-event', self.__on_click_avatar) self.favorited_mark = Gtk.Image() self.protected_mark = Gtk.Image() self.verified_mark = Gtk.Image() self.reposted_mark = Gtk.Image() self.repeated_mark = Gtk.Image() self.username = MarkupLabel() self.username.set_ellipsize(Pango.EllipsizeMode.END) self.fullname = MarkupLabel() fullname_box = Gtk.HBox() fullname_box.pack_start(self.fullname, False, False, 2) fullname_box.pack_start(self.verified_mark, False, False, 2) fullname_box.pack_start(self.protected_mark, False, False, 0) userdata_box = Gtk.VBox() userdata_box.pack_start(fullname_box, False, False, 2) userdata_box.pack_start(self.username, False, False, 2) header_box = Gtk.HBox() header_box.set_border_width(BORDER_WIDTH) header_box.pack_start(avatar_box, False, False, 0) header_box.pack_start(userdata_box, False, False, 0) self.bio = DescriptionBox(self.base, 'icon-bio.png', i18n.get('bio')) self.location = DescriptionBox(self.base, 'icon-location.png', i18n.get('location')) self.web = DescriptionBox(self.base, 'icon-home.png', i18n.get('web')) desc_box = Gtk.VBox(spacing=0) desc_box.set_border_width(BORDER_WIDTH) desc_box.pack_start(self.bio, False, False, 0) desc_box.pack_start(self.location, False, False, 0) desc_box.pack_start(self.web, False, False, 0) self.following = StatBox(i18n.get('following')) self.followers = StatBox(i18n.get('followers')) self.statuses = StatBox(i18n.get('statuses')) self.favorites = StatBox(i18n.get('favorites')) stats_box = Gtk.HBox(spacing=0) stats_box.set_border_width(BORDER_WIDTH) stats_box.pack_start(self.following, True, True, 0) stats_box.pack_start(Gtk.VSeparator(), False, False, 2) stats_box.pack_start(self.followers, True, True, 0) stats_box.pack_start(Gtk.VSeparator(), False, False, 2) stats_box.pack_start(self.statuses, True, True, 0) stats_box.pack_start(Gtk.VSeparator(), False, False, 2) stats_box.pack_start(self.favorites, True, True, 0) self.pack_start(header_box, False, False, 0) self.pack_start(Gtk.HSeparator(), False, False, 0) self.pack_start(desc_box, False, False, 0) self.pack_start(Gtk.HSeparator(), False, False, 0) self.pack_start(stats_box, False, False, 0) def update(self, profile): self.base.fetch_status_avatar(profile, self.update_avatar) self.avatar.set_from_pixbuf(self.base.load_image('unknown.png', True)) name = '<span size="9000" foreground="%s"><b>%s</b></span>' % ( self.base.get_color_scheme('links'), profile.fullname ) self.fullname.set_markup(name) self.username.set_markup('@' + profile.username) if profile.bio != '': self.bio.set_description(profile.bio) if profile.location != '': self.location.set_description(profile.location) if profile.url: self.web.set_description(profile.url, True) # After showing all widgets we set the marks if profile.protected: self.set_protected_mark(True) else: self.set_protected_mark(False) if profile.verified: self.set_verified_mark(True) else: self.set_verified_mark(False) self.following.set_value(profile.friends_count) self.followers.set_value(profile.followers_count) self.statuses.set_value(profile.statuses_count) self.favorites.set_value(profile.favorites_count) def update_avatar(self, response): if response.code == 0: pix = GdkPixbuf.Pixbuf.new_from_file_at_scale(response.items, 48, 48, True) self.avatar.set_from_pixbuf(pix) del pix def set_protected_mark(self, value): if value: self.protected_mark.set_from_pixbuf(self.base.load_image('mark-protected.png', True)) else: self.protected_mark.set_from_pixbuf(None) def set_verified_mark(self, value): if value: self.verified_mark.set_from_pixbuf(self.base.load_image('mark-verified.png', True)) else: self.verified_mark.set_from_pixbuf(None)
class SearchDialog(Gtk.Window): def __init__(self, base): Gtk.Window.__init__(self) self.base = base self.set_title(i18n.get('search')) self.set_size_request(300, 120) self.set_resizable(False) self.set_icon(self.base.load_image('turpial.png', True)) self.set_transient_for(base) self.set_position(Gtk.WindowPosition.CENTER_ON_PARENT) self.set_gravity(Gdk.Gravity.STATIC) self.set_modal(True) self.connect('delete-event', self.__close) alabel = Gtk.Label(i18n.get('account')) clabel = Gtk.Label(i18n.get('criteria')) alist = Gtk.ListStore(GdkPixbuf.Pixbuf, str, str) for acc in self.base.get_accounts_list(): image = '%s.png' % acc.split('-')[1] icon = self.base.load_image(image, True) alist.append([icon, acc.split('-')[0], acc]) self.account = Gtk.ComboBox() self.account.set_model(alist) icon = Gtk.CellRendererPixbuf() txt = Gtk.CellRendererText() self.account.pack_start(icon, False) self.account.pack_start(txt, False) self.account.add_attribute(icon, 'pixbuf', 0) self.account.add_attribute(txt, 'markup', 1) self.account.connect('changed', self.__reset_error) self.criteria = Gtk.Entry() self.criteria.connect('activate', self.__on_add) self.criteria.set_tooltip_text(i18n.get('search_criteria_tooltip')) self.criteria.connect('changed', self.__reset_error) help_text = i18n.get('this_search_support_advanced_operators') help_text += ' "", OR, -, from, to, filter, source, place, since, until. ' help_text += i18n.get('for_more_information_visit') help_text += " <a href='https://dev.twitter.com/docs/using-search'>%s</a>" % ( i18n.get('twitter_search_documentation')) help_label = MarkupLabel() help_label.set_markup(help_text) help_label.set_margin_top(10) help_label.set_size_request(300, -1) self.error_message = MarkupLabel(xalign=0.5) table = Gtk.Table(3, 2, False) table.attach(alabel, 0, 1, 0, 1, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL) table.attach(self.account, 1, 2, 0, 1, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL) table.attach(clabel, 0, 1, 1, 2, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL) table.attach(self.criteria, 1, 2, 1, 2, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL) table.attach(help_label, 0, 2, 2, 3, Gtk.AttachOptions.SHRINK) table.set_margin_top(4) table.set_row_spacing(0, 2) table.set_row_spacing(1, 2) self.btn_add = Gtk.Button(i18n.get('add')) self.btn_close = Gtk.Button(i18n.get('close')) self.btn_add.connect('clicked', self.__on_add) self.btn_close.connect('clicked', self.__close) box_button = Gtk.HButtonBox() box_button.set_spacing(6) box_button.set_layout(Gtk.ButtonBoxStyle.END) box_button.pack_start(self.btn_close, False, False, 0) box_button.pack_start(self.btn_add, False, False, 0) box_button.set_margin_top(10) vbox = Gtk.VBox(False) vbox.set_border_width(6) vbox.pack_start(table, False, False, 0) vbox.pack_start(self.error_message, False, False, 5) vbox.pack_start(box_button, False, False, 0) self.add(vbox) def __close(self, widget, event=None): self.destroy() return True def __reset_error(self, widget=None): self.error_message.set_markup('') def __on_add(self, widget, event=None): model = self.account.get_model() index = self.account.get_active() criteria = self.criteria.get_text() if index < 0 or criteria == '': self.error_message.set_error_text(i18n.get('fields_cant_be_empty')) self.error_message.set_size_request(-1, 10) else: account_id = model[index][2] column_id = "%s-%s:%s" % (account_id, ColumnType.SEARCH, urllib2.quote(criteria)) self.base.save_column(column_id) self.__close(None) def show(self): self.show_all()
class StatusWidget(Gtk.EventBox): def __init__(self, base, status): Gtk.EventBox.__init__(self) self.base = base self.status = status self.set_margin_bottom(OUTTER_BOTTOM_MARGIN) self.modify_bg(Gtk.StateType.NORMAL, Gdk.Color(65535, 65535, 65535)) # Variables to control work in progress over the status self.in_progress = { StatusProgress.FAVING: False, StatusProgress.UNFAVING: False, StatusProgress.RETWEETING: False, StatusProgress.UNRETWEETING: False, StatusProgress.DELETING: False, } self.avatar = Gtk.Image() self.avatar.set_margin_right(AVATAR_MARGIN) self.avatar_box = Gtk.Alignment() self.avatar_box.add(self.avatar) self.avatar_box.set(0.5, 0, -1, -1) self.favorited_mark = Gtk.Image() self.protected_mark = Gtk.Image() self.verified_mark = Gtk.Image() self.reposted_mark = Gtk.Image() self.repeated_mark = Gtk.Image() self.username = MarkupLabel(act_as_link=True) self.username.set_ellipsize(Pango.EllipsizeMode.END) self.status_text = MarkupLabel() self.footer = MarkupLabel() # Setting user image self.avatar.set_from_pixbuf(self.base.load_image('unknown.png', True)) # Building the status style user = '******' % ( self.base.get_color_scheme('links'), status.username ) self.username.set_markup(user) text = status.text.replace('>', '>') text = text.replace('<', '<') pango_text = '<span size="9000">%s</span>' % escape_text_for_markup(text) pango_text = self.__highlight_urls(status, pango_text) pango_text = self.__highlight_hashtags(status, pango_text) pango_text = self.__highlight_groups(status, pango_text) pango_text = self.__highlight_mentions(status, pango_text) self.status_text.set_markup(pango_text) footer = '<span size="small" foreground="#999">%s' % status.datetime if status.source: footer += ' %s %s' % (_('from'), status.source.name) if status.in_reply_to_user: footer += ' %s %s' % (_('in reply to'), status.in_reply_to_user) if status.reposted_by: footer += '\n%s %s' % (_('Retweeted by'), status.reposted_by) footer += '</span>' self.footer.set_markup(footer) starbox = Gtk.HBox() starbox.pack_start(self.repeated_mark, False, False, 2) starbox.pack_start(self.favorited_mark, False, False, 2) staralign = Gtk.Alignment() staralign.set(1, -1, -1, -1) staralign.add(starbox) header = Gtk.HBox() header.pack_start(self.reposted_mark, False, False, 2) header.pack_start(self.username, False, False, 2) header.pack_start(self.verified_mark, False, False, 2) header.pack_start(self.protected_mark, False, False, 0) header.pack_start(staralign, True, True, 0) content = Gtk.VBox() content.pack_start(header, False, False, 0) content.pack_start(self.status_text, True, True, 0) content.pack_start(self.footer, False, False, 0) box = Gtk.HBox() box.pack_start(self.avatar_box, False, False, 0) box.pack_start(content, True, True, 0) bbox = Gtk.VBox() bbox.pack_start(box, True, True, 0) self.add(bbox) self.show_all() # After showing all widgets we set the marks self.set_favorited_mark(status.favorited) self.set_protected_mark(status.protected) self.set_verified_mark(status.verified) self.set_repeated_mark(status.repeated) self.set_reposted_mark(status.reposted_by) self.connect('button-release-event', self.__on_click) self.click_url_handler = self.status_text.connect('activate-link', self.__open_url) self.click_avatar_handler = self.avatar_box.connect('button-press-event', self.__on_click_avatar) self.click_username_handler = self.username.connect('button-release-event', self.__on_click_username) self.base.fetch_status_avatar(status, self.update_avatar) def __on_click_username(self, widget, event=None): print 'clicked username', widget, event def __on_click(self, widget, event=None, data=None): # Capture clicks for avatar if event.x <= 48 and event.y <= 48 and event.button == 1: self.__on_click_avatar() return True print event.x, event.y if event.button != 3: return False self.menu = StatusMenu(self.base, self.status, self.in_progress) self.menu.show_all() self.menu.popup(None, None, None, None, 0, Gtk.get_current_event_time()) def __on_click_avatar(self): self.base.show_user_avatar(self.status.account_id, self.status.username) def __highlight_urls(self, status, text): for url in status.entities['urls']: if url.url == None: url.url = url.search_for cad = "<a href='%s'>%s</a>" % (escape_text_for_markup(url.url), escape_text_for_markup(url.display_text)) text = text.replace(url.search_for, cad) return text def __highlight_hashtags(self, status, text): for h in status.entities['hashtags']: url = "%s-search:%%23%s" % (self.status.account_id, h.display_text[1:]) cad = '<a href="hashtags:%s">%s</a>' % (url, h.display_text) text = text.replace(h.search_for, cad) return text def __highlight_groups(self, status, text): for h in status.entities['groups']: cad = '<a href="groups:%s">%s</a>' % (h.url, h.display_text) text = text.replace(h.search_for, cad) return text def __highlight_mentions(self, status, text): for h in status.entities['mentions']: args = "%s:%s" % (status.account_id, h.display_text[1:]) cad = '<a href="profile:%s">%s</a>' % (args, h.display_text) pattern = re.compile(h.search_for, re.IGNORECASE) text = pattern.sub(cad, text) return text def __open_url(self, widget, url): if url.startswith('http'): self.base.open_url(url) elif url.startswith('hashtag'): column_id = url.replace('hashtags:', '') self.base.save_column(column_id) elif url.startswith('groups'): print "Opening groups" elif url.startswith('profile'): url = url.replace('profile:', '') account_id = url.split(':')[0] username = url.split(':')[1] self.base.show_user_profile(account_id, username) return True def __del__(self): print 'garbage collected' def release(self): self.avatar_box.disconnect(self.click_avatar_handler) self.username.disconnect(self.click_username_handler) self.status_text.disconnect(self.click_url_handler) def update(self, status): self.status = status # render again def update_avatar(self, response): if response.code == 0: pix = GdkPixbuf.Pixbuf.new_from_file_at_scale(response.items, 48, 48, True) self.avatar.set_from_pixbuf(pix) del pix def set_favorited_mark(self, value): if value: self.favorited_mark.set_from_pixbuf(self.base.load_image('mark-favorite.png', True)) else: self.favorited_mark.set_from_pixbuf(None) self.status.favorited = value def set_repeated_mark(self, value): if value: self.repeated_mark.set_from_pixbuf(self.base.load_image('mark-repeated.png', True)) else: self.repeated_mark.set_from_pixbuf(None) self.status.repeated = value def set_protected_mark(self, value): if value: self.protected_mark.set_from_pixbuf(self.base.load_image('mark-protected.png', True)) else: self.protected_mark.set_from_pixbuf(None) def set_verified_mark(self, value): if value: self.verified_mark.set_from_pixbuf(self.base.load_image('mark-verified.png', True)) else: self.verified_mark.set_from_pixbuf(None) def set_reposted_mark(self, value): if value: self.reposted_mark.set_from_pixbuf(self.base.load_image('mark-reposted.png', True)) else: self.reposted_mark.set_from_pixbuf(None)
class StatusWidget(Gtk.EventBox): def __init__(self, base, status): Gtk.EventBox.__init__(self) self.base = base self.status = status self.set_margin_bottom(OUTTER_BOTTOM_MARGIN) self.modify_bg(Gtk.StateType.NORMAL, Gdk.Color(65535, 65535, 65535)) # Variables to control work in progress over the status self.in_progress = { StatusProgress.FAVING: False, StatusProgress.UNFAVING: False, StatusProgress.RETWEETING: False, StatusProgress.UNRETWEETING: False, StatusProgress.DELETING: False, } self.avatar = Gtk.Image() self.avatar.set_margin_right(AVATAR_MARGIN) self.avatar_box = Gtk.Alignment() self.avatar_box.add(self.avatar) self.avatar_box.set(0.5, 0, -1, -1) self.favorited_mark = Gtk.Image() self.protected_mark = Gtk.Image() self.verified_mark = Gtk.Image() self.reposted_mark = Gtk.Image() self.repeated_mark = Gtk.Image() self.username = MarkupLabel(act_as_link=True) self.username.set_ellipsize(Pango.EllipsizeMode.END) self.status_text = MarkupLabel() self.footer = MarkupLabel() # Setting user image self.avatar.set_from_pixbuf(self.base.load_image('unknown.png', True)) # Building the status style user = '******' % ( self.base.get_color_scheme('links'), status.username) self.username.set_markup(user) text = status.text.replace('>', '>') text = text.replace('<', '<') pango_text = '<span size="9000">%s</span>' % escape_text_for_markup( text) pango_text = self.__highlight_urls(status, pango_text) pango_text = self.__highlight_hashtags(status, pango_text) pango_text = self.__highlight_groups(status, pango_text) pango_text = self.__highlight_mentions(status, pango_text) self.status_text.set_markup(pango_text) footer = '<span size="small" foreground="#999">%s' % status.datetime if status.source: footer += ' %s %s' % (_('from'), status.source.name) if status.in_reply_to_user: footer += ' %s %s' % (_('in reply to'), status.in_reply_to_user) if status.reposted_by: footer += '\n%s %s' % (_('Retweeted by'), status.reposted_by) footer += '</span>' self.footer.set_markup(footer) starbox = Gtk.HBox() starbox.pack_start(self.repeated_mark, False, False, 2) starbox.pack_start(self.favorited_mark, False, False, 2) staralign = Gtk.Alignment() staralign.set(1, -1, -1, -1) staralign.add(starbox) header = Gtk.HBox() header.pack_start(self.reposted_mark, False, False, 2) header.pack_start(self.username, False, False, 2) header.pack_start(self.verified_mark, False, False, 2) header.pack_start(self.protected_mark, False, False, 0) header.pack_start(staralign, True, True, 0) content = Gtk.VBox() content.pack_start(header, False, False, 0) content.pack_start(self.status_text, True, True, 0) content.pack_start(self.footer, False, False, 0) box = Gtk.HBox() box.pack_start(self.avatar_box, False, False, 0) box.pack_start(content, True, True, 0) bbox = Gtk.VBox() bbox.pack_start(box, True, True, 0) self.add(bbox) self.show_all() # After showing all widgets we set the marks self.set_favorited_mark(status.favorited) self.set_protected_mark(status.protected) self.set_verified_mark(status.verified) self.set_repeated_mark(status.repeated) self.set_reposted_mark(status.reposted_by) self.connect('button-release-event', self.__on_click) self.click_url_handler = self.status_text.connect( 'activate-link', self.__open_url) self.click_avatar_handler = self.avatar_box.connect( 'button-press-event', self.__on_click_avatar) self.click_username_handler = self.username.connect( 'button-release-event', self.__on_click_username) self.base.fetch_status_avatar(status, self.update_avatar) def __on_click_username(self, widget, event=None): print 'clicked username', widget, event def __on_click(self, widget, event=None, data=None): # Capture clicks for avatar if event.x <= 48 and event.y <= 48 and event.button == 1: self.__on_click_avatar() return True print event.x, event.y if event.button != 3: return False self.menu = StatusMenu(self.base, self.status, self.in_progress) self.menu.show_all() self.menu.popup(None, None, None, None, 0, Gtk.get_current_event_time()) def __on_click_avatar(self): self.base.show_user_avatar(self.status.account_id, self.status.username) def __highlight_urls(self, status, text): for url in status.entities['urls']: if url.url == None: url.url = url.search_for cad = "<a href='%s'>%s</a>" % (escape_text_for_markup( url.url), escape_text_for_markup(url.display_text)) text = text.replace(url.search_for, cad) return text def __highlight_hashtags(self, status, text): for h in status.entities['hashtags']: url = "%s-search:%%23%s" % (self.status.account_id, h.display_text[1:]) cad = '<a href="hashtags:%s">%s</a>' % (url, h.display_text) text = text.replace(h.search_for, cad) return text def __highlight_groups(self, status, text): for h in status.entities['groups']: cad = '<a href="groups:%s">%s</a>' % (h.url, h.display_text) text = text.replace(h.search_for, cad) return text def __highlight_mentions(self, status, text): for h in status.entities['mentions']: args = "%s:%s" % (status.account_id, h.display_text[1:]) cad = '<a href="profile:%s">%s</a>' % (args, h.display_text) pattern = re.compile(h.search_for, re.IGNORECASE) text = pattern.sub(cad, text) return text def __open_url(self, widget, url): if url.startswith('http'): self.base.open_url(url) elif url.startswith('hashtag'): column_id = url.replace('hashtags:', '') self.base.save_column(column_id) elif url.startswith('groups'): print "Opening groups" elif url.startswith('profile'): url = url.replace('profile:', '') account_id = url.split(':')[0] username = url.split(':')[1] self.base.show_user_profile(account_id, username) return True def __del__(self): print 'garbage collected' def release(self): self.avatar_box.disconnect(self.click_avatar_handler) self.username.disconnect(self.click_username_handler) self.status_text.disconnect(self.click_url_handler) def update(self, status): self.status = status # render again def update_avatar(self, response): if response.code == 0: pix = GdkPixbuf.Pixbuf.new_from_file_at_scale( response.items, 48, 48, True) self.avatar.set_from_pixbuf(pix) del pix def set_favorited_mark(self, value): if value: self.favorited_mark.set_from_pixbuf( self.base.load_image('mark-favorite.png', True)) else: self.favorited_mark.set_from_pixbuf(None) self.status.favorited = value def set_repeated_mark(self, value): if value: self.repeated_mark.set_from_pixbuf( self.base.load_image('mark-repeated.png', True)) else: self.repeated_mark.set_from_pixbuf(None) self.status.repeated = value def set_protected_mark(self, value): if value: self.protected_mark.set_from_pixbuf( self.base.load_image('mark-protected.png', True)) else: self.protected_mark.set_from_pixbuf(None) def set_verified_mark(self, value): if value: self.verified_mark.set_from_pixbuf( self.base.load_image('mark-verified.png', True)) else: self.verified_mark.set_from_pixbuf(None) def set_reposted_mark(self, value): if value: self.reposted_mark.set_from_pixbuf( self.base.load_image('mark-reposted.png', True)) else: self.reposted_mark.set_from_pixbuf(None)
def __init__(self, base, status): Gtk.EventBox.__init__(self) self.base = base self.status = status self.set_margin_bottom(OUTTER_BOTTOM_MARGIN) self.modify_bg(Gtk.StateType.NORMAL, Gdk.Color(65535, 65535, 65535)) # Variables to control work in progress over the status self.in_progress = { StatusProgress.FAVING: False, StatusProgress.UNFAVING: False, StatusProgress.RETWEETING: False, StatusProgress.UNRETWEETING: False, StatusProgress.DELETING: False, } self.avatar = Gtk.Image() self.avatar.set_margin_right(AVATAR_MARGIN) self.avatar_box = Gtk.Alignment() self.avatar_box.add(self.avatar) self.avatar_box.set(0.5, 0, -1, -1) self.favorited_mark = Gtk.Image() self.protected_mark = Gtk.Image() self.verified_mark = Gtk.Image() self.reposted_mark = Gtk.Image() self.repeated_mark = Gtk.Image() self.username = MarkupLabel(act_as_link=True) self.username.set_ellipsize(Pango.EllipsizeMode.END) self.status_text = MarkupLabel() self.footer = MarkupLabel() # Setting user image self.avatar.set_from_pixbuf(self.base.load_image('unknown.png', True)) # Building the status style user = '******' % ( self.base.get_color_scheme('links'), status.username) self.username.set_markup(user) text = status.text.replace('>', '>') text = text.replace('<', '<') pango_text = '<span size="9000">%s</span>' % escape_text_for_markup( text) pango_text = self.__highlight_urls(status, pango_text) pango_text = self.__highlight_hashtags(status, pango_text) pango_text = self.__highlight_groups(status, pango_text) pango_text = self.__highlight_mentions(status, pango_text) self.status_text.set_markup(pango_text) footer = '<span size="small" foreground="#999">%s' % status.datetime if status.source: footer += ' %s %s' % (_('from'), status.source.name) if status.in_reply_to_user: footer += ' %s %s' % (_('in reply to'), status.in_reply_to_user) if status.reposted_by: footer += '\n%s %s' % (_('Retweeted by'), status.reposted_by) footer += '</span>' self.footer.set_markup(footer) starbox = Gtk.HBox() starbox.pack_start(self.repeated_mark, False, False, 2) starbox.pack_start(self.favorited_mark, False, False, 2) staralign = Gtk.Alignment() staralign.set(1, -1, -1, -1) staralign.add(starbox) header = Gtk.HBox() header.pack_start(self.reposted_mark, False, False, 2) header.pack_start(self.username, False, False, 2) header.pack_start(self.verified_mark, False, False, 2) header.pack_start(self.protected_mark, False, False, 0) header.pack_start(staralign, True, True, 0) content = Gtk.VBox() content.pack_start(header, False, False, 0) content.pack_start(self.status_text, True, True, 0) content.pack_start(self.footer, False, False, 0) box = Gtk.HBox() box.pack_start(self.avatar_box, False, False, 0) box.pack_start(content, True, True, 0) bbox = Gtk.VBox() bbox.pack_start(box, True, True, 0) self.add(bbox) self.show_all() # After showing all widgets we set the marks self.set_favorited_mark(status.favorited) self.set_protected_mark(status.protected) self.set_verified_mark(status.verified) self.set_repeated_mark(status.repeated) self.set_reposted_mark(status.reposted_by) self.connect('button-release-event', self.__on_click) self.click_url_handler = self.status_text.connect( 'activate-link', self.__open_url) self.click_avatar_handler = self.avatar_box.connect( 'button-press-event', self.__on_click_avatar) self.click_username_handler = self.username.connect( 'button-release-event', self.__on_click_username) self.base.fetch_status_avatar(status, self.update_avatar)
def __init__(self, base, parent, user=None, pwd=None, protocol=None): Gtk.Window.__init__(self) self.base = base self.set_transient_for(parent) self.set_modal(True) self.set_title(i18n.get("create_account")) self.set_size_request(290, 200) self.set_resizable(False) self.set_position(Gtk.WindowPosition.CENTER) self.set_gravity(Gdk.Gravity.STATIC) self.connect("delete-event", self.__close) self.connect("key-press-event", self.__key_pressed) plabel = Gtk.Label(i18n.get("protocol")) plabel.set_alignment(0, 0.5) plist = Gtk.ListStore(GdkPixbuf.Pixbuf, str, str) for p in self.base.get_protocols_list(): image = "%s.png" % p t_icon = self.base.load_image(image, True) plist.append([t_icon, p, p]) self.protocol = Gtk.ComboBox() self.protocol.set_model(plist) icon = Gtk.CellRendererPixbuf() txt = Gtk.CellRendererText() self.protocol.pack_start(icon, False) self.protocol.pack_start(txt, False) self.protocol.add_attribute(icon, "pixbuf", 0) self.protocol.add_attribute(txt, "markup", 1) self.username = Gtk.Entry() user_box = Gtk.HBox(False) user_box.pack_start(self.username, True, True, 0) self.password = Gtk.Entry() self.password.set_visibility(False) pass_box = Gtk.HBox(True) pass_box.pack_start(self.password, True, True, 0) self.cred_label = Gtk.Label(i18n.get("user_and_password")) self.cred_label.set_alignment(0, 0.5) cred_box = Gtk.VBox(False) cred_box.pack_start(self.cred_label, False, False, 0) cred_box.pack_start(user_box, False, False, 0) cred_box.pack_start(pass_box, False, False, 0) self.btn_signin = Gtk.Button(i18n.get("signin")) self.spinner = Gtk.Spinner() self.waiting_label = MarkupLabel(xalign=0.5) waiting_box = Gtk.HBox() waiting_box.pack_start(self.spinner, False, False, 10) waiting_box.pack_start(self.waiting_label, True, False, 0) vbox = Gtk.VBox(False) vbox.set_border_width(12) vbox.pack_start(plabel, False, False, 0) vbox.pack_start(self.protocol, False, False, 0) vbox.pack_start(Gtk.EventBox(), False, False, 6) vbox.pack_start(cred_box, True, True, 0) vbox.pack_start(waiting_box, False, False, 0) vbox.pack_start(self.btn_signin, False, False, 6) self.add(vbox) self.show_all() self.protocol.connect("changed", self.__on_change_protocol) self.password.connect("activate", self.__on_sign_in) self.btn_signin.connect("clicked", self.__on_sign_in) self.protocol.set_active(0) self.working = False self.spinner.hide()
class AccountForm(Gtk.Window): def __init__(self, base, parent, user=None, pwd=None, protocol=None): Gtk.Window.__init__(self) self.base = base self.set_transient_for(parent) self.set_modal(True) self.set_title(i18n.get("create_account")) self.set_size_request(290, 200) self.set_resizable(False) self.set_position(Gtk.WindowPosition.CENTER) self.set_gravity(Gdk.Gravity.STATIC) self.connect("delete-event", self.__close) self.connect("key-press-event", self.__key_pressed) plabel = Gtk.Label(i18n.get("protocol")) plabel.set_alignment(0, 0.5) plist = Gtk.ListStore(GdkPixbuf.Pixbuf, str, str) for p in self.base.get_protocols_list(): image = "%s.png" % p t_icon = self.base.load_image(image, True) plist.append([t_icon, p, p]) self.protocol = Gtk.ComboBox() self.protocol.set_model(plist) icon = Gtk.CellRendererPixbuf() txt = Gtk.CellRendererText() self.protocol.pack_start(icon, False) self.protocol.pack_start(txt, False) self.protocol.add_attribute(icon, "pixbuf", 0) self.protocol.add_attribute(txt, "markup", 1) self.username = Gtk.Entry() user_box = Gtk.HBox(False) user_box.pack_start(self.username, True, True, 0) self.password = Gtk.Entry() self.password.set_visibility(False) pass_box = Gtk.HBox(True) pass_box.pack_start(self.password, True, True, 0) self.cred_label = Gtk.Label(i18n.get("user_and_password")) self.cred_label.set_alignment(0, 0.5) cred_box = Gtk.VBox(False) cred_box.pack_start(self.cred_label, False, False, 0) cred_box.pack_start(user_box, False, False, 0) cred_box.pack_start(pass_box, False, False, 0) self.btn_signin = Gtk.Button(i18n.get("signin")) self.spinner = Gtk.Spinner() self.waiting_label = MarkupLabel(xalign=0.5) waiting_box = Gtk.HBox() waiting_box.pack_start(self.spinner, False, False, 10) waiting_box.pack_start(self.waiting_label, True, False, 0) vbox = Gtk.VBox(False) vbox.set_border_width(12) vbox.pack_start(plabel, False, False, 0) vbox.pack_start(self.protocol, False, False, 0) vbox.pack_start(Gtk.EventBox(), False, False, 6) vbox.pack_start(cred_box, True, True, 0) vbox.pack_start(waiting_box, False, False, 0) vbox.pack_start(self.btn_signin, False, False, 6) self.add(vbox) self.show_all() self.protocol.connect("changed", self.__on_change_protocol) self.password.connect("activate", self.__on_sign_in) self.btn_signin.connect("clicked", self.__on_sign_in) self.protocol.set_active(0) self.working = False self.spinner.hide() def __close(self, widget, event=None): if not self.working: self.destroy() return False else: return True def __key_pressed(self, widget, event): keyname = Gdk.keyval_name(event.keyval) if keyname == "Escape": self.__close(widget) def __on_change_protocol(self, widget): index = widget.get_active() model = widget.get_model() if index < 0: return self.waiting_label.set_text("") protocol = model[index][1] if protocol == "twitter": self.username.set_visible(False) self.password.set_visible(False) self.cred_label.set_visible(False) self.btn_signin.grab_focus() elif protocol == "identica": self.username.set_visible(True) self.password.set_visible(True) self.cred_label.set_visible(True) self.username.grab_focus() def __on_sign_in(self, widget): self.working = True username = self.username.get_text() passwd = self.password.get_text() model = self.protocol.get_model() pindex = self.protocol.get_active() protocol = model[pindex][1] # Validate if protocol == "identica": if username == "" or passwd == "": self.waiting_label.set_error_text(i18n.get("credentials_could_not_be_empty")) return True self.__lock() self.waiting_label.set_text(i18n.get("connecting")) self.spinner.show() self.spinner.start() self.base.save_account(username, protocol, passwd) def __lock(self): self.username.set_sensitive(False) self.password.set_sensitive(False) self.protocol.set_sensitive(False) self.btn_signin.set_sensitive(False) def __unlock(self): self.username.set_sensitive(True) self.password.set_sensitive(True) self.protocol.set_sensitive(True) self.btn_signin.set_sensitive(True) def cancel(self, message): self.working = False self.__unlock() self.waiting_label.set_error_text(message) self.spinner.stop() self.spinner.hide() def set_loading_message(self, message): self.waiting_label.set_text(message) def done(self): self.working = False self.destroy()
def __init__(self, base): Gtk.Window.__init__(self) self.base = base self.set_title(i18n.get('search')) self.set_size_request(300, 120) self.set_resizable(False) self.set_icon(self.base.load_image('turpial.png', True)) self.set_transient_for(base) self.set_position(Gtk.WindowPosition.CENTER_ON_PARENT) self.set_gravity(Gdk.Gravity.STATIC) self.set_modal(True) self.connect('delete-event', self.__close) alabel = Gtk.Label(i18n.get('account')) clabel = Gtk.Label(i18n.get('criteria')) alist = Gtk.ListStore(GdkPixbuf.Pixbuf, str, str) for acc in self.base.get_accounts_list(): image = '%s.png' % acc.split('-')[1] icon = self.base.load_image(image, True) alist.append([icon, acc.split('-')[0], acc]) self.account = Gtk.ComboBox() self.account.set_model(alist) icon = Gtk.CellRendererPixbuf() txt = Gtk.CellRendererText() self.account.pack_start(icon, False) self.account.pack_start(txt, False) self.account.add_attribute(icon, 'pixbuf', 0) self.account.add_attribute(txt, 'markup', 1) self.account.connect('changed', self.__reset_error) self.criteria = Gtk.Entry() self.criteria.connect('activate', self.__on_add) self.criteria.set_tooltip_text(i18n.get('search_criteria_tooltip')) self.criteria.connect('changed', self.__reset_error) help_text = i18n.get('this_search_support_advanced_operators') help_text += ' "", OR, -, from, to, filter, source, place, since, until. ' help_text += i18n.get('for_more_information_visit') help_text += " <a href='https://dev.twitter.com/docs/using-search'>%s</a>" % ( i18n.get('twitter_search_documentation')) help_label = MarkupLabel() help_label.set_markup(help_text) help_label.set_margin_top(10) help_label.set_size_request(300, -1) self.error_message = MarkupLabel(xalign=0.5) table = Gtk.Table(3, 2, False) table.attach(alabel, 0, 1, 0, 1, Gtk.AttachOptions.EXPAND|Gtk.AttachOptions.FILL) table.attach(self.account, 1, 2, 0, 1, Gtk.AttachOptions.EXPAND|Gtk.AttachOptions.FILL) table.attach(clabel, 0, 1, 1, 2, Gtk.AttachOptions.EXPAND|Gtk.AttachOptions.FILL) table.attach(self.criteria, 1, 2, 1, 2, Gtk.AttachOptions.EXPAND|Gtk.AttachOptions.FILL) table.attach(help_label, 0, 2, 2, 3, Gtk.AttachOptions.SHRINK) table.set_margin_top(4) table.set_row_spacing(0, 2) table.set_row_spacing(1, 2) self.btn_add = Gtk.Button(i18n.get('add')) self.btn_close = Gtk.Button(i18n.get('close')) self.btn_add.connect('clicked', self.__on_add) self.btn_close.connect('clicked', self.__close) box_button = Gtk.HButtonBox() box_button.set_spacing(6) box_button.set_layout(Gtk.ButtonBoxStyle.END) box_button.pack_start(self.btn_close, False, False, 0) box_button.pack_start(self.btn_add, False, False, 0) box_button.set_margin_top(10) vbox = Gtk.VBox(False) vbox.set_border_width(6) vbox.pack_start(table, False, False, 0) vbox.pack_start(self.error_message, False, False, 5) vbox.pack_start(box_button, False, False, 0) self.add(vbox)
def __init__(self, base, parent, user=None, pwd=None, protocol=None): Gtk.Window.__init__(self) self.base = base self.set_transient_for(parent) self.set_modal(True) self.set_title(i18n.get('create_account')) self.set_size_request(290, 200) self.set_resizable(False) self.set_position(Gtk.WindowPosition.CENTER) self.set_gravity(Gdk.Gravity.STATIC) self.connect('delete-event', self.__close) self.connect('key-press-event', self.__key_pressed) plabel = Gtk.Label(i18n.get('protocol')) plabel.set_alignment(0, 0.5) plist = Gtk.ListStore(GdkPixbuf.Pixbuf, str, str) for p in self.base.get_protocols_list(): image = '%s.png' % p t_icon = self.base.load_image(image, True) plist.append([t_icon, p, p]) self.protocol = Gtk.ComboBox() self.protocol.set_model(plist) icon = Gtk.CellRendererPixbuf() txt = Gtk.CellRendererText() self.protocol.pack_start(icon, False) self.protocol.pack_start(txt, False) self.protocol.add_attribute(icon, 'pixbuf', 0) self.protocol.add_attribute(txt, 'markup', 1) self.username = Gtk.Entry() user_box = Gtk.HBox(False) user_box.pack_start(self.username, True, True, 0) self.password = Gtk.Entry() self.password.set_visibility(False) pass_box = Gtk.HBox(True) pass_box.pack_start(self.password, True, True, 0) self.cred_label = Gtk.Label(i18n.get('user_and_password')) self.cred_label.set_alignment(0, 0.5) cred_box = Gtk.VBox(False) cred_box.pack_start(self.cred_label, False, False, 0) cred_box.pack_start(user_box, False, False, 0) cred_box.pack_start(pass_box, False, False, 0) self.btn_signin = Gtk.Button(i18n.get('signin')) self.spinner = Gtk.Spinner() self.waiting_label = MarkupLabel(xalign=0.5) waiting_box = Gtk.HBox() waiting_box.pack_start(self.spinner, False, False, 10) waiting_box.pack_start(self.waiting_label, True, False, 0) vbox = Gtk.VBox(False) vbox.set_border_width(12) vbox.pack_start(plabel, False, False, 0) vbox.pack_start(self.protocol, False, False, 0) vbox.pack_start(Gtk.EventBox(), False, False, 6) vbox.pack_start(cred_box, True, True, 0) vbox.pack_start(waiting_box, False, False, 0) vbox.pack_start(self.btn_signin, False, False, 6) self.add(vbox) self.show_all() self.protocol.connect('changed', self.__on_change_protocol) self.password.connect('activate', self.__on_sign_in) self.btn_signin.connect('clicked', self.__on_sign_in) self.protocol.set_active(0) self.working = False self.spinner.hide()
class AccountForm(Gtk.Window): def __init__(self, base, parent, user=None, pwd=None, protocol=None): Gtk.Window.__init__(self) self.base = base self.set_transient_for(parent) self.set_modal(True) self.set_title(i18n.get('create_account')) self.set_size_request(290, 200) self.set_resizable(False) self.set_position(Gtk.WindowPosition.CENTER) self.set_gravity(Gdk.Gravity.STATIC) self.connect('delete-event', self.__close) self.connect('key-press-event', self.__key_pressed) plabel = Gtk.Label(i18n.get('protocol')) plabel.set_alignment(0, 0.5) plist = Gtk.ListStore(GdkPixbuf.Pixbuf, str, str) for p in self.base.get_protocols_list(): image = '%s.png' % p t_icon = self.base.load_image(image, True) plist.append([t_icon, p, p]) self.protocol = Gtk.ComboBox() self.protocol.set_model(plist) icon = Gtk.CellRendererPixbuf() txt = Gtk.CellRendererText() self.protocol.pack_start(icon, False) self.protocol.pack_start(txt, False) self.protocol.add_attribute(icon, 'pixbuf', 0) self.protocol.add_attribute(txt, 'markup', 1) self.username = Gtk.Entry() user_box = Gtk.HBox(False) user_box.pack_start(self.username, True, True, 0) self.password = Gtk.Entry() self.password.set_visibility(False) pass_box = Gtk.HBox(True) pass_box.pack_start(self.password, True, True, 0) self.cred_label = Gtk.Label(i18n.get('user_and_password')) self.cred_label.set_alignment(0, 0.5) cred_box = Gtk.VBox(False) cred_box.pack_start(self.cred_label, False, False, 0) cred_box.pack_start(user_box, False, False, 0) cred_box.pack_start(pass_box, False, False, 0) self.btn_signin = Gtk.Button(i18n.get('signin')) self.spinner = Gtk.Spinner() self.waiting_label = MarkupLabel(xalign=0.5) waiting_box = Gtk.HBox() waiting_box.pack_start(self.spinner, False, False, 10) waiting_box.pack_start(self.waiting_label, True, False, 0) vbox = Gtk.VBox(False) vbox.set_border_width(12) vbox.pack_start(plabel, False, False, 0) vbox.pack_start(self.protocol, False, False, 0) vbox.pack_start(Gtk.EventBox(), False, False, 6) vbox.pack_start(cred_box, True, True, 0) vbox.pack_start(waiting_box, False, False, 0) vbox.pack_start(self.btn_signin, False, False, 6) self.add(vbox) self.show_all() self.protocol.connect('changed', self.__on_change_protocol) self.password.connect('activate', self.__on_sign_in) self.btn_signin.connect('clicked', self.__on_sign_in) self.protocol.set_active(0) self.working = False self.spinner.hide() def __close(self, widget, event=None): if not self.working: self.destroy() return False else: return True def __key_pressed(self, widget, event): keyname = Gdk.keyval_name(event.keyval) if keyname == 'Escape': self.__close(widget) def __on_change_protocol(self, widget): index = widget.get_active() model = widget.get_model() if index < 0: return self.waiting_label.set_text('') protocol = model[index][1] if protocol == 'twitter': self.username.set_visible(False) self.password.set_visible(False) self.cred_label.set_visible(False) self.btn_signin.grab_focus() elif protocol == 'identica': self.username.set_visible(True) self.password.set_visible(True) self.cred_label.set_visible(True) self.username.grab_focus() def __on_sign_in(self, widget): self.working = True username = self.username.get_text() passwd = self.password.get_text() model = self.protocol.get_model() pindex = self.protocol.get_active() protocol = model[pindex][1] # Validate if protocol == 'identica': if username == '' or passwd == '': self.waiting_label.set_error_text( i18n.get('credentials_could_not_be_empty')) return True self.__lock() self.waiting_label.set_text(i18n.get('connecting')) self.spinner.show() self.spinner.start() self.base.save_account(username, protocol, passwd) def __lock(self): self.username.set_sensitive(False) self.password.set_sensitive(False) self.protocol.set_sensitive(False) self.btn_signin.set_sensitive(False) def __unlock(self): self.username.set_sensitive(True) self.password.set_sensitive(True) self.protocol.set_sensitive(True) self.btn_signin.set_sensitive(True) def cancel(self, message): self.working = False self.__unlock() self.waiting_label.set_error_text(message) self.spinner.stop() self.spinner.hide() def set_loading_message(self, message): self.waiting_label.set_text(message) def done(self): self.working = False self.destroy()