summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormathieui <mathieui@mathieui.net>2013-01-21 19:23:23 +0100
committermathieui <mathieui@mathieui.net>2013-01-21 19:23:23 +0100
commit1bf61cde38dc67945f12882aeffa6e3a67229f5e (patch)
tree7cfbe7197bf326e11d8cbdab625b277b8acd7f58
parentbedf22574934fa569e3c6fcd487033366c7408e4 (diff)
downloadpoezio-1bf61cde38dc67945f12882aeffa6e3a67229f5e.tar.gz
poezio-1bf61cde38dc67945f12882aeffa6e3a67229f5e.tar.bz2
poezio-1bf61cde38dc67945f12882aeffa6e3a67229f5e.tar.xz
poezio-1bf61cde38dc67945f12882aeffa6e3a67229f5e.zip
Break the ugly roster refresh loop into two
- The code is more understandable - The number of iterations may have slightly increased - Less things are done inside the lock, so the overall experience should be smoother
-rw-r--r--src/contact.py5
-rw-r--r--src/windows.py91
2 files changed, 52 insertions, 44 deletions
diff --git a/src/contact.py b/src/contact.py
index 0d7276f9..62092057 100644
--- a/src/contact.py
+++ b/src/contact.py
@@ -47,6 +47,11 @@ class Resource(object):
def __repr__(self):
return '<%s>' % self._jid
+ def __eq__(self, value):
+ if not isinstance(value, Resource):
+ return False
+ return self.jid == value.jid and self._data == value._data
+
class Contact(object):
"""
This a way to gather multiple resources from the same bare JID.
diff --git a/src/windows.py b/src/windows.py
index 22c5bec3..e3a8d136 100644
--- a/src/windows.py
+++ b/src/windows.py
@@ -25,7 +25,7 @@ from config import config
from threading import RLock
-from contact import Contact
+from contact import Contact, Resource
from roster import RosterGroup
from poopt import cut_text
@@ -1658,7 +1658,7 @@ class RosterWin(Win):
self.start_pos = 1 # position of the start of the display
self.roster_len = 0
self.selected_row = None
- self.roster_cache = []
+ self.roster_cache = []
def move_cursor_down(self, number=1):
"""
@@ -1674,6 +1674,7 @@ class RosterWin(Win):
self.scroll_down(8)
else:
self.scroll_down(self.pos-self.start_pos - self.height // 2)
+ self.update_pos()
return pos != self.pos
def move_cursor_up(self, number=1):
@@ -1690,8 +1691,15 @@ class RosterWin(Win):
self.scroll_up(8)
else:
self.scroll_up(self.start_pos-self.pos + self.height // 2)
+ self.update_pos()
return pos != self.pos
+ def update_pos(self):
+ if len(self.roster_cache) > self.pos and self.pos >= 0:
+ self.selected_row = self.roster_cache[self.pos]
+ elif self.roster_cache:
+ self.selected_row = self.roster_cache[-1]
+
def scroll_down(self, number=8):
pos = self.start_pos
if self.start_pos + number <= self.roster_len-1:
@@ -1713,55 +1721,50 @@ class RosterWin(Win):
We get the roster object
"""
log.debug('Refresh: %s',self.__class__.__name__)
- self.roster_cache = []
+ self.roster_cache = []
+ show_offline = config.get('roster_show_offline', 'false') == 'true'
+ sort = config.get('roster_sort', 'jid:show') or 'jid:show'
+ group_sort = config.get('roster_group_sort', 'name') or 'name'
+ # build the cache
+ for group in roster.get_groups(group_sort):
+ contacts_filtered = group.get_contacts(roster.contact_filter)
+ if (not show_offline and group.get_nb_connected_contacts() == 0) or not contacts_filtered:
+ continue # Ignore empty groups
+ self.roster_cache.append(group)
+ if group.folded:
+ continue # ignore folded groups
+ for contact in group.get_contacts(roster.contact_filter, sort):
+ if not show_offline and len(contact) == 0:
+ continue # ignore offline contacts
+ self.roster_cache.append(contact)
+ if not contact.folded:
+ for resource in contact.get_resources():
+ self.roster_cache.append(resource)
+
with g_lock:
self.roster_len = len(roster);
- while self.roster_len and self.pos >= self.roster_len:
- self.move_cursor_up()
+ self.move_cursor_up(self.roster_len - self.pos if self.pos >= self.roster_len else 0)
self._win.erase()
self._win.move(0, 0)
self.draw_roster_information(roster)
y = 1
- show_offline = config.get('roster_show_offline', 'false') == 'true'
- sort = config.get('roster_sort', 'jid:show') or 'jid:show'
- group_sort = config.get('roster_group_sort', 'name') or 'name'
- for group in roster.get_groups(group_sort):
- contacts_filtered = group.get_contacts(roster.contact_filter)
- if (not show_offline and group.get_nb_connected_contacts() == 0) or not contacts_filtered:
- continue # Ignore empty groups
- # This loop is really REALLY ugly :^)
- if y-1 == self.pos:
- self.selected_row = group
- if y >= self.start_pos:
- self.draw_group(y-self.start_pos+1, group, y-1==self.pos)
- self.roster_cache.append(group)
+ # draw the roster from the cache
+ for item in self.roster_cache[self.start_pos-1:self.start_pos+self.height]:
+
+ draw_selected = False
+ if y -2 + self.start_pos == self.pos:
+ draw_selected = True
+ self.selected_row = item
+
+ if isinstance(item, RosterGroup):
+ self.draw_group(y, item, draw_selected)
+ elif isinstance(item, Contact):
+ self.draw_contact_line(y, item, draw_selected)
+ elif isinstance(item, Resource):
+ self.draw_resource_line(y, item, draw_selected)
+
y += 1
- if group.folded:
- continue
- for contact in group.get_contacts(roster.contact_filter, sort):
- if not show_offline and len(contact) == 0:
- continue
- if y-1 == self.pos:
- self.selected_row = contact
- if y-self.start_pos+1 == self.height:
- break
- if y >= self.start_pos:
- self.draw_contact_line(y-self.start_pos+1, contact, y-1==self.pos)
- log.debug('ammend: %s',contact.bare_jid)
- self.roster_cache.append(contact)
- y += 1
- if not contact.folded:
- for resource in contact.get_resources():
- if y-1 == self.pos:
- self.selected_row = resource
- if y-self.start_pos+1 == self.height:
- break
- if y >= self.start_pos:
- self.draw_resource_line(y-self.start_pos+1, resource, y-1==self.pos)
- self.roster_cache.append(resource)
- y += 1
- if y-self.start_pos+1 == self.height:
- break
+
if self.start_pos > 1:
self.draw_plus(1)
if self.start_pos + self.height-2 < self.roster_len: