Commit 82d82d99 authored by 's avatar

- added optional 'subset_ids' argument to move methods

parent 4dde3a93
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
############################################################################## ##############################################################################
""" Order support interfaces. """ Order support interfaces.
$Id: IOrderSupport.py,v 1.3 2003/12/11 17:39:18 yuppie Exp $ $Id: IOrderSupport.py,v 1.4 2004/04/09 12:26:26 yuppie Exp $
""" """
from Interface import Interface from Interface import Interface
...@@ -25,13 +25,17 @@ class IOrderedContainer(Interface): ...@@ -25,13 +25,17 @@ class IOrderedContainer(Interface):
collections. collections.
""" """
def moveObjectsByDelta(ids, delta): def moveObjectsByDelta(ids, delta, subset_ids=None):
""" Move specified sub-objects by delta. """ Move specified sub-objects by delta.
If delta is higher than the possible maximum, objects will be moved to If delta is higher than the possible maximum, objects will be moved to
the bottom. If delta is lower than the possible minimum, objects will the bottom. If delta is lower than the possible minimum, objects will
be moved to the top. be moved to the top.
If subset_ids is not None, delta will be interpreted relative to the
subset specified by a sequence of ids. The position of objects that
are not part of this subset will not be changed.
The order of the objects specified by ids will always be preserved. So The order of the objects specified by ids will always be preserved. So
if you don't want to change their original order, make sure the order if you don't want to change their original order, make sure the order
of ids corresponds to their original order. of ids corresponds to their original order.
...@@ -43,7 +47,7 @@ class IOrderedContainer(Interface): ...@@ -43,7 +47,7 @@ class IOrderedContainer(Interface):
Returns -- Number of moved sub-objects Returns -- Number of moved sub-objects
""" """
def moveObjectsUp(ids, delta=1): def moveObjectsUp(ids, delta=1, subset_ids=None):
""" Move specified sub-objects up by delta in container. """ Move specified sub-objects up by delta in container.
If no delta is specified, delta is 1. See moveObjectsByDelta for more If no delta is specified, delta is 1. See moveObjectsByDelta for more
...@@ -54,7 +58,7 @@ class IOrderedContainer(Interface): ...@@ -54,7 +58,7 @@ class IOrderedContainer(Interface):
Returns -- Number of moved sub-objects Returns -- Number of moved sub-objects
""" """
def moveObjectsDown(ids, delta=1): def moveObjectsDown(ids, delta=1, subset_ids=None):
""" Move specified sub-objects down by delta in container. """ Move specified sub-objects down by delta in container.
If no delta is specified, delta is 1. See moveObjectsByDelta for more If no delta is specified, delta is 1. See moveObjectsByDelta for more
...@@ -65,7 +69,7 @@ class IOrderedContainer(Interface): ...@@ -65,7 +69,7 @@ class IOrderedContainer(Interface):
Returns -- Number of moved sub-objects Returns -- Number of moved sub-objects
""" """
def moveObjectsToTop(ids): def moveObjectsToTop(ids, subset_ids=None):
""" Move specified sub-objects to top of container. """ Move specified sub-objects to top of container.
See moveObjectsByDelta for more details. See moveObjectsByDelta for more details.
...@@ -75,7 +79,7 @@ class IOrderedContainer(Interface): ...@@ -75,7 +79,7 @@ class IOrderedContainer(Interface):
Returns -- Number of moved sub-objects Returns -- Number of moved sub-objects
""" """
def moveObjectsToBottom(ids): def moveObjectsToBottom(ids, subset_ids=None):
""" Move specified sub-objects to bottom of container. """ Move specified sub-objects to bottom of container.
See moveObjectsByDelta for more details. See moveObjectsByDelta for more details.
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
############################################################################## ##############################################################################
""" Order support for 'Object Manager'. """ Order support for 'Object Manager'.
$Id: OrderSupport.py,v 1.5 2003/12/11 17:39:18 yuppie Exp $ $Id: OrderSupport.py,v 1.6 2004/04/09 12:26:26 yuppie Exp $
""" """
from types import StringType from types import StringType
...@@ -130,68 +130,76 @@ class OrderSupport: ...@@ -130,68 +130,76 @@ class OrderSupport:
# #
security.declareProtected(manage_properties, 'moveObjectsByDelta') security.declareProtected(manage_properties, 'moveObjectsByDelta')
def moveObjectsByDelta(self, ids, delta): def moveObjectsByDelta(self, ids, delta, subset_ids=None):
""" Move specified sub-objects by delta. """ Move specified sub-objects by delta.
""" """
if type(ids) is StringType: if type(ids) is StringType:
ids = (ids,) ids = (ids,)
min_position = 0 min_position = 0
objects = list(self._objects) objects = list(self._objects)
obj_dict = {} if subset_ids == None:
for obj in self._objects: subset_ids = [ obj['id'] for obj in objects ]
obj_dict[ obj['id'] ] = obj else:
subset_ids = list(subset_ids)
# unify moving direction # unify moving direction
if delta > 0: if delta > 0:
ids = list(ids) ids = list(ids)
ids.reverse() ids.reverse()
objects.reverse() subset_ids.reverse()
counter = 0 counter = 0
for id in ids: for id in ids:
try: old_position = subset_ids.index(id)
object = obj_dict[id]
except KeyError:
raise ValueError('The object with the id "%s" does not exist.'
% id)
old_position = objects.index(object)
new_position = max( old_position - abs(delta), min_position ) new_position = max( old_position - abs(delta), min_position )
if new_position == min_position: if new_position == min_position:
min_position += 1 min_position += 1
if not old_position == new_position: if not old_position == new_position:
objects.remove(object) subset_ids.remove(id)
objects.insert(new_position, object) subset_ids.insert(new_position, id)
counter += 1 counter += 1
if counter > 0: if counter > 0:
if delta > 0: if delta > 0:
objects.reverse() subset_ids.reverse()
obj_dict = {}
for obj in objects:
obj_dict[ obj['id'] ] = obj
pos = 0
for i in range( len(objects) ):
if objects[i]['id'] in subset_ids:
try:
objects[i] = obj_dict[ subset_ids[pos] ]
pos += 1
except KeyError:
raise ValueError('The object with the id "%s" does '
'not exist.' % subset_ids[pos])
self._objects = tuple(objects) self._objects = tuple(objects)
return counter return counter
security.declareProtected(manage_properties, 'moveObjectsUp') security.declareProtected(manage_properties, 'moveObjectsUp')
def moveObjectsUp(self, ids, delta=1): def moveObjectsUp(self, ids, delta=1, subset_ids=None):
""" Move specified sub-objects up by delta in container. """ Move specified sub-objects up by delta in container.
""" """
return self.moveObjectsByDelta(ids, -delta) return self.moveObjectsByDelta(ids, -delta, subset_ids)
security.declareProtected(manage_properties, 'moveObjectsDown') security.declareProtected(manage_properties, 'moveObjectsDown')
def moveObjectsDown(self, ids, delta=1): def moveObjectsDown(self, ids, delta=1, subset_ids=None):
""" Move specified sub-objects down by delta in container. """ Move specified sub-objects down by delta in container.
""" """
return self.moveObjectsByDelta(ids, delta) return self.moveObjectsByDelta(ids, delta, subset_ids)
security.declareProtected(manage_properties, 'moveObjectsToTop') security.declareProtected(manage_properties, 'moveObjectsToTop')
def moveObjectsToTop(self, ids): def moveObjectsToTop(self, ids, subset_ids=None):
""" Move specified sub-objects to top of container. """ Move specified sub-objects to top of container.
""" """
return self.moveObjectsByDelta( ids, -len(self._objects) ) return self.moveObjectsByDelta( ids, -len(self._objects), subset_ids )
security.declareProtected(manage_properties, 'moveObjectsToBottom') security.declareProtected(manage_properties, 'moveObjectsToBottom')
def moveObjectsToBottom(self, ids): def moveObjectsToBottom(self, ids, subset_ids=None):
""" Move specified sub-objects to bottom of container. """ Move specified sub-objects to bottom of container.
""" """
return self.moveObjectsByDelta( ids, len(self._objects) ) return self.moveObjectsByDelta( ids, len(self._objects), subset_ids )
security.declareProtected(manage_properties, 'orderObjects') security.declareProtected(manage_properties, 'orderObjects')
def orderObjects(self, key, reverse=None): def orderObjects(self, key, reverse=None):
......
from unittest import TestCase, TestSuite, makeSuite, main from unittest import TestCase, TestSuite, makeSuite, main
import Testing
import Zope import Zope
Zope.startup() Zope.startup()
from Interface.Verify import verifyClass from Interface.Verify import verifyClass
...@@ -40,100 +41,106 @@ class TestOrderSupport(TestCase): ...@@ -40,100 +41,106 @@ class TestOrderSupport(TestCase):
f.o4 = DummyObject('o4', 'mt2') f.o4 = DummyObject('o4', 'mt2')
return f return f
def _doCanonTestA(self, methodname, table): def _doCanonTest(self, methodname, table):
for arg1, order, rval in table: for args, order, rval in table:
f = self._makeOne() f = self._makeOne()
method = getattr(f, methodname) method = getattr(f, methodname)
if rval == 'ValueError': if rval == 'ValueError':
self.failUnlessRaises( ValueError, method, arg1 ) self.failUnlessRaises( ValueError, method, *args )
else: else:
self.failUnlessEqual( method(arg1), rval ) self.failUnlessEqual( method(*args), rval )
self.failUnlessEqual( f.objectIds(), order )
def _doCanonTestB(self, methodname, table):
for arg1, arg2, order, rval in table:
f = self._makeOne()
method = getattr(f, methodname)
if rval == 'ValueError':
self.failUnlessRaises( ValueError, method, arg1, arg2 )
else:
self.failUnlessEqual( method(arg1, arg2), rval )
self.failUnlessEqual( f.objectIds(), order ) self.failUnlessEqual( f.objectIds(), order )
def test_moveObjectsUp(self): def test_moveObjectsUp(self):
self._doCanonTestB( 'moveObjectsUp', self._doCanonTest( 'moveObjectsUp',
( ( 'o4', 1, ['o1', 'o2', 'o4', 'o3'], 1 ) ( ( ( 'o4', 1 ), ['o1', 'o2', 'o4', 'o3'], 1 )
, ( 'o4', 2, ['o1', 'o4', 'o2', 'o3'], 1 ) , ( ( 'o4', 2 ), ['o1', 'o4', 'o2', 'o3'], 1 )
, ( ('o1', 'o3'), 1, ['o1', 'o3', 'o2', 'o4'], 1 ) , ( ( ('o1', 'o3'), 1 ), ['o1', 'o3', 'o2', 'o4'], 1 )
, ( ('o1', 'o3'), 9, ['o1', 'o3', 'o2', 'o4'], 1 ) , ( ( ('o1', 'o3'), 9 ), ['o1', 'o3', 'o2', 'o4'], 1 )
, ( ('o2', 'o3'), 1, ['o2', 'o3', 'o1', 'o4'], 2 ) , ( ( ('o2', 'o3'), 1 ), ['o2', 'o3', 'o1', 'o4'], 2 )
, ( ('n2', 'o3'), 1, ['o1', 'o2', 'o3', 'o4'], 'ValueError') , ( ( ('o2', 'o3'), 1, ('o1', 'o2', 'o3', 'o4') ),
, ( ('o3', 'o1'), 1, ['o1', 'o3', 'o2', 'o4'], 1 ) ['o2', 'o3', 'o1', 'o4'], 2 )
, ( ( ('o2', 'o3'), 1, ('o2', 'o3', 'o4') ),
['o1', 'o2', 'o3', 'o4'], 0 )
, ( ( ('n2', 'o3'), 1 ), ['o1', 'o2', 'o3', 'o4'], 'ValueError')
, ( ( ('o3', 'o1'), 1 ), ['o1', 'o3', 'o2', 'o4'], 1 )
) )
) )
def test_moveObjectsDown(self): def test_moveObjectsDown(self):
self._doCanonTestB( 'moveObjectsDown', self._doCanonTest( 'moveObjectsDown',
( ( 'o1', 1, ['o2', 'o1', 'o3', 'o4'], 1 ) ( ( ( 'o1', 1 ), ['o2', 'o1', 'o3', 'o4'], 1 )
, ( 'o1', 2, ['o2', 'o3', 'o1', 'o4'], 1 ) , ( ( 'o1', 2 ), ['o2', 'o3', 'o1', 'o4'], 1 )
, ( ('o2', 'o4'), 1, ['o1', 'o3', 'o2', 'o4'], 1 ) , ( ( ('o2', 'o4'), 1 ), ['o1', 'o3', 'o2', 'o4'], 1 )
, ( ('o2', 'o4'), 9, ['o1', 'o3', 'o2', 'o4'], 1 ) , ( ( ('o2', 'o4'), 9 ), ['o1', 'o3', 'o2', 'o4'], 1 )
, ( ('o2', 'o3'), 1, ['o1', 'o4', 'o2', 'o3'], 2 ) , ( ( ('o2', 'o3'), 1 ), ['o1', 'o4', 'o2', 'o3'], 2 )
, ( ('n2', 'o3'), 1, ['o1', 'o2', 'o3', 'o4'], 'ValueError') , ( ( ('o2', 'o3'), 1, ('o1', 'o2', 'o3', 'o4') ),
, ( ('o4', 'o2'), 1, ['o1', 'o3', 'o2', 'o4'], 1 ) ['o1', 'o4', 'o2', 'o3'], 2 )
, ( ( ('o2', 'o3'), 1, ('o1', 'o2', 'o3') ),
['o1', 'o2', 'o3', 'o4'], 0 )
, ( ( ('n2', 'o3'), 1 ), ['o1', 'o2', 'o3', 'o4'], 'ValueError')
, ( ( ('o4', 'o2'), 1 ), ['o1', 'o3', 'o2', 'o4'], 1 )
) )
) )
def test_moveObjectsToTop(self): def test_moveObjectsToTop(self):
self._doCanonTestA( 'moveObjectsToTop', self._doCanonTest( 'moveObjectsToTop',
( ( 'o4', ['o4', 'o1', 'o2', 'o3'], 1 ) ( ( ( 'o4', ), ['o4', 'o1', 'o2', 'o3'], 1 )
, ( ('o1', 'o3'), ['o1', 'o3', 'o2', 'o4'], 1 ) , ( ( ('o1', 'o3'), ), ['o1', 'o3', 'o2', 'o4'], 1 )
, ( ('o2', 'o3'), ['o2', 'o3', 'o1', 'o4'], 2 ) , ( ( ('o2', 'o3'), ), ['o2', 'o3', 'o1', 'o4'], 2 )
, ( ('n2', 'o3'), ['o1', 'o2', 'o3', 'o4'], 'ValueError') , ( ( ('o2', 'o3'), ('o1', 'o2', 'o3', 'o4') ),
, ( ('o3', 'o1'), ['o3', 'o1', 'o2', 'o4'], 1 ) ['o2', 'o3', 'o1', 'o4'], 2 )
, ( ( ('o2', 'o3'), ('o2', 'o3', 'o4') ),
['o1', 'o2', 'o3', 'o4'], 0 )
, ( ( ('n2', 'o3'), ), ['o1', 'o2', 'o3', 'o4'], 'ValueError')
, ( ( ('o3', 'o1'), ), ['o3', 'o1', 'o2', 'o4'], 1 )
) )
) )
def test_moveObjectsToBottom(self): def test_moveObjectsToBottom(self):
self._doCanonTestA( 'moveObjectsToBottom', self._doCanonTest( 'moveObjectsToBottom',
( ( 'o1', ['o2', 'o3', 'o4', 'o1'], 1 ) ( ( ( 'o1', ), ['o2', 'o3', 'o4', 'o1'], 1 )
, ( ('o2', 'o4'), ['o1', 'o3', 'o2', 'o4'], 1 ) , ( ( ('o2', 'o4'), ), ['o1', 'o3', 'o2', 'o4'], 1 )
, ( ('o2', 'o3'), ['o1', 'o4', 'o2', 'o3'], 2 ) , ( ( ('o2', 'o3'), ), ['o1', 'o4', 'o2', 'o3'], 2 )
, ( ('n2', 'o3'), ['o1', 'o2', 'o3', 'o4'], 'ValueError') , ( ( ('o2', 'o3'), ('o1', 'o2', 'o3', 'o4') ),
, ( ('o4', 'o2'), ['o1', 'o3', 'o4', 'o2'], 1 ) ['o1', 'o4', 'o2', 'o3'], 2 )
, ( ( ('o2', 'o3'), ('o1', 'o2', 'o3') ),
['o1', 'o2', 'o3', 'o4'], 0 )
, ( ( ('n2', 'o3'), ), ['o1', 'o2', 'o3', 'o4'], 'ValueError')
, ( ( ('o4', 'o2'), ), ['o1', 'o3', 'o4', 'o2'], 1 )
) )
) )
def test_orderObjects(self): def test_orderObjects(self):
self._doCanonTestB( 'orderObjects', self._doCanonTest( 'orderObjects',
( ( 'id', 'id', ['o4', 'o3', 'o2', 'o1'], 3) ( ( ( 'id', 'id' ), ['o4', 'o3', 'o2', 'o1'], 3)
, ( 'meta_type', '', ['o1', 'o3', 'o2', 'o4'], 1) , ( ( 'meta_type', '' ), ['o1', 'o3', 'o2', 'o4'], 1)
, ( 'meta_type', 'n', ['o4', 'o2', 'o3', 'o1'], 3) , ( ( 'meta_type', 'n' ), ['o4', 'o2', 'o3', 'o1'], 3)
, ( 'position', 0, ['o1', 'o2', 'o3', 'o4'], 0) , ( ( 'position', 0 ), ['o1', 'o2', 'o3', 'o4'], 0)
, ( 'position', 1, ['o4', 'o3', 'o2', 'o1'], 3) , ( ( 'position', 1 ), ['o4', 'o3', 'o2', 'o1'], 3)
) )
) )
def test_getObjectPosition(self): def test_getObjectPosition(self):
self._doCanonTestA( 'getObjectPosition', self._doCanonTest( 'getObjectPosition',
( ( 'o2', ['o1', 'o2', 'o3', 'o4'], 1) ( ( ( 'o2', ), ['o1', 'o2', 'o3', 'o4'], 1)
, ( 'o4', ['o1', 'o2', 'o3', 'o4'], 3) , ( ( 'o4', ), ['o1', 'o2', 'o3', 'o4'], 3)
, ( 'n2', ['o1', 'o2', 'o3', 'o4'], 'ValueError') , ( ( 'n2', ), ['o1', 'o2', 'o3', 'o4'], 'ValueError')
) )
) )
def test_moveObjectToPosition(self): def test_moveObjectToPosition(self):
self._doCanonTestB( 'moveObjectToPosition', self._doCanonTest( 'moveObjectToPosition',
( ( 'o2', 2, ['o1', 'o3', 'o2', 'o4'], 1) ( ( ( 'o2', 2 ), ['o1', 'o3', 'o2', 'o4'], 1)
, ( 'o4', 2, ['o1', 'o2', 'o4', 'o3'], 1) , ( ( 'o4', 2 ), ['o1', 'o2', 'o4', 'o3'], 1)
, ( 'n2', 2, ['o1', 'o2', 'o3', 'o4'], 'ValueError') , ( ( 'n2', 2 ), ['o1', 'o2', 'o3', 'o4'], 'ValueError')
) )
) )
def test_manage_renameObject(self): def test_manage_renameObject(self):
self._doCanonTestB( 'manage_renameObject', self._doCanonTest( 'manage_renameObject',
( ( 'o2', 'n2', ['o1', 'n2', 'o3', 'o4'], None ) ( ( ( 'o2', 'n2' ), ['o1', 'n2', 'o3', 'o4'], None )
, ( 'o3', 'n3', ['o1', 'o2', 'n3', 'o4'], None ) , ( ( 'o3', 'n3' ), ['o1', 'o2', 'n3', 'o4'], None )
) )
) )
......
from unittest import TestCase, TestSuite, makeSuite, main from unittest import TestCase, TestSuite, makeSuite, main
import Testing
import Zope import Zope
Zope.startup() Zope.startup()
from Interface.Verify import verifyClass from Interface.Verify import verifyClass
......
...@@ -21,13 +21,17 @@ class OrderSupport: ...@@ -21,13 +21,17 @@ class OrderSupport:
is totally user-specific. is totally user-specific.
""" """
def moveObjectsByDelta(ids, delta): def moveObjectsByDelta(ids, delta, subset_ids=None):
""" Move specified sub-objects by delta. """ Move specified sub-objects by delta.
If delta is higher than the possible maximum, objects will be moved to If delta is higher than the possible maximum, objects will be moved to
the bottom. If delta is lower than the possible minimum, objects will the bottom. If delta is lower than the possible minimum, objects will
be moved to the top. be moved to the top.
If subset_ids is not None, delta will be interpreted relative to the
subset specified by a sequence of ids. The position of objects that
are not part of this subset will not be changed.
The order of the objects specified by ids will always be preserved. So The order of the objects specified by ids will always be preserved. So
if you don't want to change their original order, make sure the order if you don't want to change their original order, make sure the order
of ids corresponds to their original order. of ids corresponds to their original order.
...@@ -39,7 +43,7 @@ class OrderSupport: ...@@ -39,7 +43,7 @@ class OrderSupport:
Returns -- Number of moved sub-objects Returns -- Number of moved sub-objects
""" """
def moveObjectsUp(ids, delta=1): def moveObjectsUp(ids, delta=1, subset_ids=None):
""" Move specified sub-objects up by delta in container. """ Move specified sub-objects up by delta in container.
If no delta is specified, delta is 1. See moveObjectsByDelta for more If no delta is specified, delta is 1. See moveObjectsByDelta for more
...@@ -50,7 +54,7 @@ class OrderSupport: ...@@ -50,7 +54,7 @@ class OrderSupport:
Returns -- Number of moved sub-objects Returns -- Number of moved sub-objects
""" """
def moveObjectsDown(ids, delta=1): def moveObjectsDown(ids, delta=1, subset_ids=None):
""" Move specified sub-objects down by delta in container. """ Move specified sub-objects down by delta in container.
If no delta is specified, delta is 1. See moveObjectsByDelta for more If no delta is specified, delta is 1. See moveObjectsByDelta for more
...@@ -61,7 +65,7 @@ class OrderSupport: ...@@ -61,7 +65,7 @@ class OrderSupport:
Returns -- Number of moved sub-objects Returns -- Number of moved sub-objects
""" """
def moveObjectsToTop(ids): def moveObjectsToTop(ids, subset_ids=None):
""" Move specified sub-objects to top of container. """ Move specified sub-objects to top of container.
See moveObjectsByDelta for more details. See moveObjectsByDelta for more details.
...@@ -71,7 +75,7 @@ class OrderSupport: ...@@ -71,7 +75,7 @@ class OrderSupport:
Returns -- Number of moved sub-objects Returns -- Number of moved sub-objects
""" """
def moveObjectsToBottom(ids): def moveObjectsToBottom(ids, subset_ids=None):
""" Move specified sub-objects to bottom of container. """ Move specified sub-objects to bottom of container.
See moveObjectsByDelta for more details. See moveObjectsByDelta for more details.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment