Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTomeu Vizoso <tomeu@sugarlabs.org>2009-01-10 18:01:12 (GMT)
committer Tomeu Vizoso <tomeu@sugarlabs.org>2009-01-10 18:01:12 (GMT)
commit3ae6d51ebc0af3298fe058b7ed6acca60d168f22 (patch)
treef9f0aec5e4aa6ba20946bfe902ded1db9fe96148 /src
parent5d15f1caf33f050bf8c3a0422f8a950b186a6215 (diff)
Read removable devices asynchronously
Diffstat (limited to 'src')
-rw-r--r--src/jarabe/journal/listview.py40
-rw-r--r--src/jarabe/journal/model.py70
2 files changed, 83 insertions, 27 deletions
diff --git a/src/jarabe/journal/listview.py b/src/jarabe/journal/listview.py
index b0be70e..e609c8c 100644
--- a/src/jarabe/journal/listview.py
+++ b/src/jarabe/journal/listview.py
@@ -18,6 +18,7 @@ import logging
import traceback
import sys
from gettext import gettext as _
+import time
import hippo
import gobject
@@ -49,6 +50,8 @@ class BaseListView(gtk.HBox):
self._page_size = 0
self._reflow_sid = 0
self._do_scroll_hid = None
+ self._progress_bar = None
+ self._last_progress_bar_pulse = None
gtk.HBox.__init__(self)
self.set_flags(gtk.HAS_FOCUS|gtk.CAN_FOCUS)
@@ -185,7 +188,17 @@ class BaseListView(gtk.HBox):
def refresh(self):
logging.debug('ListView.refresh query %r' % self._query)
+ self._stop_progress_bar()
+ self._start_progress_bar()
+
self._result_set = model.find(self._query)
+ self._result_set.ready.connect(self.__result_set_ready_cb)
+ self._result_set.progress.connect(self.__result_set_progress_cb)
+ self._result_set.setup()
+
+ def __result_set_ready_cb(self, **kwargs):
+ self._stop_progress_bar()
+
self._vadjustment.props.upper = self._result_set.length
self._vadjustment.changed()
@@ -205,6 +218,33 @@ class BaseListView(gtk.HBox):
self._clear_message()
self._do_scroll()
+ def __result_set_progress_cb(self, **kwargs):
+ if time.time() - self._last_progress_bar_pulse > 0.05:
+ if self._progress_bar is not None:
+ self._progress_bar.pulse()
+ self._last_progress_bar_pulse = time.time()
+
+ def _start_progress_bar(self):
+ self.remove(self._canvas)
+ self.remove(self._vscrollbar)
+
+ alignment = gtk.Alignment(xalign=0.5, yalign=0.5, xscale=0.5)
+ self.pack_start(alignment)
+ alignment.show()
+
+ self._progress_bar = gtk.ProgressBar()
+ self._progress_bar.props.pulse_step = 0.01
+ self._last_progress_bar_pulse = time.time()
+ alignment.add(self._progress_bar)
+ self._progress_bar.show()
+
+ def _stop_progress_bar(self):
+ self.remove(self.get_children()[0])
+ self._progress_bar = None
+
+ self.pack_start(self._canvas)
+ self.pack_end(self._vscrollbar, expand=False, fill=False)
+
def _scroll_event_cb(self, hbox, event):
if event.direction == gtk.gdk.SCROLL_UP:
if self._vadjustment.props.value > self._vadjustment.props.lower:
diff --git a/src/jarabe/journal/model.py b/src/jarabe/journal/model.py
index ba98a48..71d0534 100644
--- a/src/jarabe/journal/model.py
+++ b/src/jarabe/journal/model.py
@@ -22,6 +22,7 @@ import shutil
from stat import S_IFMT, S_IFDIR, S_IFREG
import traceback
+import gobject
import dbus
import gconf
@@ -88,6 +89,12 @@ class BaseResultSet(object):
self._offset = 0
self._cache = _Cache()
+ self.ready = dispatch.Signal()
+ self.progress = dispatch.Signal()
+
+ def setup(self):
+ self.ready.send(self)
+
def get_length(self):
if self._total_count == -1:
query = self._query.copy()
@@ -215,50 +222,59 @@ class InplaceResultSet(BaseResultSet):
BaseResultSet.__init__(self, query)
self._mount_point = mount_point
self._file_list = None
+ self._pending_directories = 0
+
+ def setup(self):
+ self._file_list = []
+ self._recurse_dir(self._mount_point)
+
+ def setup_ready(self):
+ self._file_list.sort(lambda a, b: b[2] - a[2])
+ self.ready.send(self)
def find(self, query):
- entries, total_count = self._query_mount_point(self._mount_point, query)
+ if self._file_list is None:
+ raise ValueError('Need to call setup() first')
- for entry in entries:
- entry['mountpoint'] = self._mount_point
+ t = time.time()
+
+ offset = int(query.get('offset', 0))
+ limit = int(query.get('limit', len(self._file_list)))
+ total_count = len(self._file_list)
+
+ files = self._file_list[offset:offset + limit]
+
+ entries = []
+ for file_path, stat, mtime_ in files:
+ metadata = _get_file_metadata(file_path, stat)
+ metadata['mountpoint'] = self._mount_point
+ entries.append(metadata)
+
+ logging.debug('InplaceResultSet.find took %f s.' % (time.time() - t))
return entries, total_count
- def _build_file_list(self, dir_path):
+ def _recurse_dir(self, dir_path):
for entry in os.listdir(dir_path):
full_path = dir_path + '/' + entry
try:
stat = os.stat(full_path)
if S_IFMT(stat.st_mode) == S_IFDIR:
- self._build_file_list(full_path)
+ self._pending_directories += 1
+ gobject.idle_add(lambda s=full_path: self._recurse_dir(s))
+
elif S_IFMT(stat.st_mode) == S_IFREG:
self._file_list.append((full_path, stat, int(stat.st_mtime)))
+ self.progress.send(self)
+
except Exception, e:
logging.error('Error reading file %r: %r' % \
(full_path, traceback.format_exc()))
- def _query_mount_point(self, mount_point, query):
- t = time.time()
-
- if self._file_list is None:
- self._file_list = []
- self._build_file_list(mount_point)
- self._file_list.sort(lambda a, b: b[2] - a[2])
-
- offset = int(query.get('offset', 0))
- limit = int(query.get('limit', len(self._file_list)))
- total_count = len(self._file_list)
-
- files = self._file_list[offset:offset + limit]
-
- result = []
- for file_path, stat, mtime_ in files:
- metadata = _get_file_metadata(file_path, stat)
- result.append(metadata)
-
- logging.debug('_query_mount_point took %f s.' % (time.time() - t))
-
- return result, total_count
+ if self._pending_directories == 0:
+ self.setup_ready()
+ else:
+ self._pending_directories -= 1
def _get_file_metadata(path, stat):
client = gconf.client_get_default()