diff options
Diffstat (limited to 'src/pyexiv2.py')
-rw-r--r-- | src/pyexiv2.py | 163 |
1 files changed, 3 insertions, 160 deletions
diff --git a/src/pyexiv2.py b/src/pyexiv2.py index 1a8a2c4..309c112 100644 --- a/src/pyexiv2.py +++ b/src/pyexiv2.py @@ -246,153 +246,6 @@ class Rational(object): return '%d/%d' % (self.numerator, self.denominator) -class ListenerInterface(object): - # Define an interface that an object that wants to listen to changes on a - # notifying list should implement. - - """ - Changes that can happen on a list: - - items changed - - items deleted - - items inserted - - reordered - """ - - def items_changed(self, start_index, items): - raise NotImplementedError() - - def items_deleted(self, start_index, end_index): - raise NotImplementedError() - - def items_inserted(self, start_index, items): - raise NotImplementedError() - - def reordered(self): - raise NotImplementedError() - - -class NotifyingList(list): - - """ - DOCME - Not asynchronous. - """ - - # file:///usr/share/doc/python2.5/html/lib/typesseq-mutable.html - # http://docs.python.org/reference/datamodel.html#additional-methods-for-emulation-of-sequence-types - - def __init__(self, items=[]): - super(NotifyingList, self).__init__(items) - self._listeners = set() - - def register_listener(self, listener): - self._listeners.add(listener) - - def unregister_listener(self, listener): - self._listeners.remove(listener) - - def _notify_listeners(self, method_name, *args): - for listener in self._listeners: - getattr(listener, method_name)(*args) - - def _positive_index(self, index): - # Convert a negative index to its positive representation. - length = len(self) - if index < 0: - return length + index - elif index > length: - return length - else: - return index - - def __setitem__(self, index, item): - # FIXME: support slice arguments for extended slicing - super(NotifyingList, self).__setitem__(index, item) - self._notify_listeners('items_changed', index, [item]) - - def __delitem__(self, index): - # FIXME: support slice arguments for extended slicing - super(NotifyingList, self).__delitem__(index) - self._notify_listeners('items_deleted', index, index + 1) - - def append(self, item): - index = len(self) - super(NotifyingList, self).append(item) - self._notify_listeners('items_inserted', index, [item]) - - def extend(self, items): - index = len(self) - super(NotifyingList, self).extend(items) - self._notify_listeners('items_inserted', index, items) - - def insert(self, index, item): - start = self._positive_index(index) - super(NotifyingList, self).insert(index, item) - self._notify_listeners('items_inserted', start, [item]) - - def pop(self, index=None): - if index is None: - start = len(self) - 1 - item = super(NotifyingList, self).pop() - else: - start = self._positive_index(index) - item = super(NotifyingList, self).pop(index) - self._notify_listeners('items_deleted', start, start + 1) - return item - - def remove(self, item): - index = self.index(item) - super(NotifyingList, self).remove(item) - self._notify_listeners('items_deleted', index, index + 1) - - def reverse(self): - super(NotifyingList, self).reverse() - self._notify_listeners('reordered') - - def sort(self, cmp=None, key=None, reverse=False): - super(NotifyingList, self).sort(cmp, key, reverse) - self._notify_listeners('reordered') - - def __iadd__(self, other): - index = len(self) - self = super(NotifyingList, self).__iadd__(other) - self._notify_listeners('items_inserted', index, other) - return self - - def __imul__(self, coefficient): - index = len(self) - self = super(NotifyingList, self).__imul__(coefficient) - self._notify_listeners('items_inserted', index, self[index:]) - return self - - def __setslice__(self, i, j, items): - # __setslice__ is deprecated but needs to be overridden for completeness - start, end = self._positive_index(i), self._positive_index(j) - deleted = self[start:end] - super(NotifyingList, self).__setslice__(i, j, items) - old_size = end - start - new_size = len(items) - diff = new_size - old_size - if diff == 0: - self._notify_listeners('items_changed', start, items) - elif diff < 0: - if new_size > 0: - self._notify_listeners('items_changed', start, items) - self._notify_listeners('items_deleted', start + new_size, end) - elif diff > 0: - if old_size > 0: - self._notify_listeners('items_deleted', start, end) - self._notify_listeners('items_inserted', start, items) - - def __delslice__(self, i, j): - # __delslice__ is deprecated but needs to be overridden for completeness - start, end = self._positive_index(i), self._positive_index(j) - deleted = self[start:end] - super(NotifyingList, self).__delslice__(i, j) - if deleted: - self._notify_listeners('items_deleted', start, end) - - class MetadataTag(object): """ @@ -663,7 +516,7 @@ class IptcValueError(ValueError): (self.xtype, self.value) -class IptcTag(MetadataTag, ListenerInterface): +class IptcTag(MetadataTag): """ An IPTC metadata tag can have several values (tags that have the repeatable @@ -680,8 +533,8 @@ class IptcTag(MetadataTag, ListenerInterface): Constructor. """ super(IptcTag, self).__init__(key, name, label, description, xtype, values) - self._values = NotifyingList(map(lambda x: IptcTag._convert_to_python(x, xtype), values)) - self._values.register_listener(self) + # FIXME: make values either a tuple (immutable) or a notifying list + self._values = map(lambda x: IptcTag._convert_to_python(x, xtype), values) def _get_values(self): return self._values @@ -695,22 +548,12 @@ class IptcTag(MetadataTag, ListenerInterface): def _del_values(self): if self.metadata is not None: self.metadata._delete_iptc_tag(self.key) - self._values.unregister_listener(self) del self._values # DOCME values = property(fget=_get_values, fset=_set_values, fdel=_del_values, doc=None) - # Implement the listener interface. - - def item_changed(self, index, item): - # An item of self._values was changed. - # The following is a quick, non optimal solution. - # FIXME: do not update the whole list, only the item that changed. - self._set_values(self._values) - - @staticmethod def _convert_to_python(value, xtype): """ |