[Dextrose] [PATCH 2/5][dx3][sugar] multi-selection listview
Martin Abente
martin.abente.lahaye at gmail.com
Tue Jun 7 17:46:23 EDT 2011
Implements the selection list view, by adding a new toggle cell
renderer and a new column to the "_add_column" method.
Fires a "select-toggled" signal to communicate the selection
status.
Adds a view-level selection cache. This is necessary because
the view can change from/to different mount points and we
want to store/restore every mount point selection state.
Applies a "_is_visible" filter to the journal-model created,
updated and deleted callbacks. This filter will avoid
unnecessary view redraws when the the object_id does not belong
to the current mount point.
Signed-off-by: Martin Abente <martin.abente.lahaye at gmail.com>
---
src/jarabe/journal/listview.py | 76 +++++++++++++++++++++++++++++++++++++--
1 files changed, 72 insertions(+), 4 deletions(-)
diff --git a/src/jarabe/journal/listview.py b/src/jarabe/journal/listview.py
index 0aee1b7..a0296ef 100644
--- a/src/jarabe/journal/listview.py
+++ b/src/jarabe/journal/listview.py
@@ -65,7 +65,10 @@ class BaseListView(gtk.Bin):
__gtype_name__ = 'JournalBaseListView'
__gsignals__ = {
- 'clear-clicked': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
+ 'clear-clicked': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, ([])),
+ 'select-toggled': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, ([bool]))
}
def __init__(self):
@@ -117,16 +120,56 @@ class BaseListView(gtk.Bin):
model.updated.connect(self.__model_updated_cb)
model.deleted.connect(self.__model_deleted_cb)
+ # Multi-selection stuff
+ self._selection_cache = set()
+
+ def get_mountpoint(self):
+ return self._query.get('mountpoints', [''])[0]
+
+ def _is_viewable(self, object_id=None):
+ mount_point = self.get_mountpoint()
+
+ if not object_id or \
+ not mount_point:
+ return False
+ elif not object_id.startswith('/') and \
+ mount_point is '/':
+ return True
+ elif object_id.startswith(mount_point) and \
+ mount_point is not '/':
+ return True
+ else:
+ return False
+
def __model_created_cb(self, sender, **kwargs):
- self._set_dirty()
+ object_id = kwargs.get('object_id', None)
+ if self._is_viewable(object_id):
+ self._set_dirty()
def __model_updated_cb(self, sender, **kwargs):
- self._set_dirty()
+ object_id = kwargs.get('object_id', None)
+ if self._is_viewable(object_id):
+ self._set_dirty()
def __model_deleted_cb(self, sender, **kwargs):
- self._set_dirty()
+ object_id = kwargs.get('object_id', None)
+ if self._is_viewable(object_id):
+ self._set_dirty()
def _add_columns(self):
+
+ cell_select = gtk.CellRendererToggle()
+ cell_select.props.indicator_size = style.zoom(26)
+ cell_select.props.activatable = True
+ cell_select.connect('toggled', self.__selected_cb)
+
+ column = gtk.TreeViewColumn()
+ column.props.sizing = gtk.TREE_VIEW_COLUMN_FIXED
+ column.props.fixed_width = style.GRID_CELL_SIZE
+ column.pack_start(cell_select)
+ column.add_attribute(cell_select, "active", ListModel.COLUMN_SELECT)
+ self.tree_view.append_column(column)
+
cell_favorite = CellRendererFavorite(self.tree_view)
cell_favorite.connect('clicked', self.__favorite_clicked_cb)
@@ -244,6 +287,9 @@ class BaseListView(gtk.Bin):
else:
cell.props.xo_color = None
+ def __selected_cb(self, cell, path):
+ self._model.toggle_selection(path)
+
def __favorite_clicked_cb(self, cell, path):
row = self._model[path]
metadata = model.get(row[ListModel.COLUMN_UID])
@@ -255,6 +301,9 @@ class BaseListView(gtk.Bin):
metadata['keep'] = '1'
model.write(metadata, update_mtime=False)
+ def get_model(self):
+ return self._model
+
def update_with_query(self, query_dict):
logging.debug('ListView.update_with_query')
if 'order_by' not in query_dict:
@@ -275,14 +324,33 @@ class BaseListView(gtk.Bin):
if self._model is not None:
self._model.stop()
+ self._manage_selection_cache()
self._dirty = False
self._model = ListModel(self._query)
+ self._model.connect('select', self.__model_select_cb)
self._model.connect('ready', self.__model_ready_cb)
self._model.connect('progress', self.__model_progress_cb)
self._model.setup()
+ def _manage_selection_cache(self):
+ # Discard from cache elements that might not be selected anymore
+ self._selection_cache = \
+ self._selection_cache.difference(self._model._query_set_cache)
+ # Add to cache elements that are selected
+ self._selection_cache = \
+ self._selection_cache.union(self._model.get_selection())
+
+ def __model_select_cb(self, tree_model, status, refresh_view):
+ if refresh_view:
+ self._refresh_view(tree_model)
+ self.emit('select-toggled', status)
+
def __model_ready_cb(self, tree_model):
+ self._model.add_selection(self._selection_cache)
+ self._refresh_view(tree_model)
+
+ def _refresh_view(self, tree_model):
self._stop_progress_bar()
self._scroll_position = self.tree_view.props.vadjustment.props.value
--
1.7.4.4
More information about the Dextrose
mailing list