dupeguru/hscommon/gui/selectable_list.py

132 lines
3.9 KiB
Python

# Created By: Virgil Dupras
# Created On: 2011-09-06
# Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
#
# This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at
# http://www.hardcoded.net/licenses/bsd_license
from collections import Sequence, MutableSequence
from .base import GUIObject
class Selectable(Sequence):
def __init__(self):
self._selected_indexes = []
#--- Private
def _check_selection_range(self):
if not self:
self._selected_indexes = []
if not self._selected_indexes:
return
self._selected_indexes = [index for index in self._selected_indexes if index < len(self)]
if not self._selected_indexes:
self._selected_indexes = [len(self) - 1]
#--- Virtual
def _update_selection(self):
# Takes the table's selection and does appropriates updates on the view and/or model, when
# appropriate. Common sense would dictate that when the selection doesn't change, we don't
# update anything (and thus don't call _update_selection() at all), but there are cases
# where it's false. For example, if our list updates its items but doesn't change its
# selection, we probably want to update the model's selection. A redesign of how this whole
# thing works is probably in order, but not now, there's too much breakage at once involved.
pass
#--- Public
def select(self, indexes):
if isinstance(indexes, int):
indexes = [indexes]
self.selected_indexes = indexes
self._update_selection()
#--- Properties
@property
def selected_index(self):
return self._selected_indexes[0] if self._selected_indexes else None
@selected_index.setter
def selected_index(self, value):
self.selected_indexes = [value]
@property
def selected_indexes(self):
return self._selected_indexes
@selected_indexes.setter
def selected_indexes(self, value):
self._selected_indexes = value
self._selected_indexes.sort()
self._check_selection_range()
class SelectableList(MutableSequence, Selectable):
def __init__(self, items=None):
Selectable.__init__(self)
if items:
self._items = list(items)
else:
self._items = []
def __delitem__(self, key):
self._items.__delitem__(key)
self._check_selection_range()
self._on_change()
def __getitem__(self, key):
return self._items.__getitem__(key)
def __len__(self):
return len(self._items)
def __setitem__(self, key, value):
self._items.__setitem__(key, value)
self._on_change()
#--- Override
def append(self, item):
self._items.append(item)
self._on_change()
def insert(self, index, item):
self._items.insert(index, item)
self._on_change()
def remove(self, row):
self._items.remove(row)
self._check_selection_range()
self._on_change()
#--- Virtual
def _on_change(self):
pass
#--- Public
def search_by_prefix(self, prefix):
prefix = prefix.lower()
for index, s in enumerate(self):
if s.lower().startswith(prefix):
return index
return -1
class GUISelectableList(SelectableList, GUIObject):
#--- View interface
# refresh()
# update_selection()
#
def __init__(self, items=None):
SelectableList.__init__(self, items)
GUIObject.__init__(self)
def _view_updated(self):
self.view.refresh()
def _update_selection(self):
self.view.update_selection()
def _on_change(self):
self.view.refresh()