def __init__(self): gtk.ScrolledWindow.__init__(self) self.timeline = None self.stream = None # Add treeview to scrolledwindow self.view = StatusView() self.add(self.view) # Scrollbar policy self.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS) self.set_shadow_type(gtk.SHADOW_IN) self.connect("destroy", self.on_destroy) # Auto scroll to top setup vadj = self.get_vadjustment() self.vadj_upper = vadj.upper self.vadj_lock = False vadj.connect("changed", self.on_vadjustment_changed) vadj.connect("value-changed", self.on_vadjustment_value_changed)
def __init__(self, status): gtk.VPaned.__init__(self) ico = gtk.image_new_from_pixbuf(self.iconstore.get(status.user)) markup = "<big><b>%s</b></big> - %s\n%s\n<small><span foreground='#666666'>%s via %s</span></small>" text = gtk.Label() text.set_padding(30, 10) text.set_alignment(0, 0.5) text.set_line_wrap(True) label_text = markup % ( status.user.screen_name, status.user.name, status.text, status.created_at.strftime("%Y/%m/%d %H:%M:%S"), status.source_name) label_text = TwitterTools.replace_amp(label_text) text.set_markup(label_text) hbox = gtk.HBox() hbox.set_border_width(10) hbox.pack_start(ico, expand = False, fill = False) hbox.pack_start(text) self._box = gtk.VBox() self._box.pack_start(hbox) self.view = StatusView() win = gtk.ScrolledWindow() win.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) win.add(self.view) self.pack1(self._box, shrink = False) self.pack2(win) t = threading.Thread(target = self.get_conversation, args = (status,)) t.setDaemon(True) t.start() self.show_all()
class Timeline(gtk.ScrolledWindow): twitter = None def __init__(self): gtk.ScrolledWindow.__init__(self) self.timeline = None self.stream = None # Add treeview to scrolledwindow self.view = StatusView() self.add(self.view) # Scrollbar policy self.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS) self.set_shadow_type(gtk.SHADOW_IN) self.connect("destroy", self.on_destroy) # Auto scroll to top setup vadj = self.get_vadjustment() self.vadj_upper = vadj.upper self.vadj_lock = False vadj.connect("changed", self.on_vadjustment_changed) vadj.connect("value-changed", self.on_vadjustment_value_changed) # Start Sync Timeline (new twitter timeline thread create) def set_timeline(self, method, interval, counts, args, kwargs): self.timeline = TimelineThread(method, interval, counts, args, kwargs) def set_stream(self, method, kwargs = {}): self.stream = StreamingThread(method, kwargs = kwargs) def start_timeline(self): if self.timeline and not self.timeline.is_alive(): # Set Event Hander (exec in every get timeline self.timeline.on_received_status = self.on_received_statuses # Start Timeline sync thread self.timeline.start() def start_stream(self): if self.stream and not self.stream.is_alive(): self.stream.on_received_status = self.on_received_statuses self.stream.start() # Reload Timeline def reload(self): if self.timeline != None and not self.timeline.lock.isSet(): # lock flag set (unlock) self.timeline.lock.set() # Get timeline ids def get_timeline_ids(self): timeline = self.timeline.timeline if self.timeline != None else set() stream = self.stream.timeline if self.stream != None else set() return timeline.union(stream) # FIXME for notify event def get_processing_ids(self): timeline = self.timeline._processing if self.timeline != None else set() stream = self.stream._processing if self.stream != None else set() return timeline.union(stream) def on_received_statuses(self, ids): statuses = ids.difference(self.get_timeline_ids()) self.view.prepend_new_statuses(statuses) if not self.timeline or not self.timeline._initial_load: for i in statuses: self.on_status_added(i) def on_status_added(self, ids): pass ######################################## # Gtk Signal Events # Scroll to top if upper(list length) changed Event def on_vadjustment_changed(self, adj): if not self.vadj_lock and self.vadj_upper < adj.upper: if len(self.view.store): self.view.scroll_to_cell((0,)) self.view.added = False self.vadj_upper = adj.upper self.vadj_len = len(self.view.store) def on_vadjustment_value_changed(self, adj): if adj.value == 0.0: self.vadj_lock = False elif self.vadj_upper == adj.upper and not self.view.added: self.vadj_lock = True def on_destroy(self, widget): if self.timeline != None: self.timeline.destroy() if self.stream != None: self.stream.destroy() self.view.destroy()
class StatusDetail(gtk.VPaned): twitter = None iconstore = None def __init__(self, status): gtk.VPaned.__init__(self) ico = gtk.image_new_from_pixbuf(self.iconstore.get(status.user)) markup = "<big><b>%s</b></big> - %s\n%s\n<small><span foreground='#666666'>%s via %s</span></small>" text = gtk.Label() text.set_padding(30, 10) text.set_alignment(0, 0.5) text.set_line_wrap(True) label_text = markup % ( status.user.screen_name, status.user.name, status.text, status.created_at.strftime("%Y/%m/%d %H:%M:%S"), status.source_name) label_text = TwitterTools.replace_amp(label_text) text.set_markup(label_text) hbox = gtk.HBox() hbox.set_border_width(10) hbox.pack_start(ico, expand = False, fill = False) hbox.pack_start(text) self._box = gtk.VBox() self._box.pack_start(hbox) self.view = StatusView() win = gtk.ScrolledWindow() win.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) win.add(self.view) self.pack1(self._box, shrink = False) self.pack2(win) t = threading.Thread(target = self.get_conversation, args = (status,)) t.setDaemon(True) t.start() self.show_all() def get_conversation(self, status): s = status i = s.in_reply_to_status_id lim = 0 # Loading label loading = gtk.Label("Now Loading...") self._box.pack_end(loading) while i != None: if i in self.twitter.statuses: # already exists status self.view.prepend_new_statuses([i]) s = self.twitter.statuses[i] i = s.in_reply_to_status_id lim = 0 else: # not found in cache statuses = self.twitter.api_wrapper( self.twitter.api.user_timeline, s.in_reply_to_user_id, count = 20, max_id = i, include_entities = 1) self.twitter.add_statuses(statuses) lim += 1 if lim >= 3: break self._box.remove(loading)