Commit 82d82d99 authored by 's avatar

- added optional 'subset_ids' argument to move methods

parent 4dde3a93
......@@ -12,7 +12,7 @@
##############################################################################
""" 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
......@@ -25,13 +25,17 @@ class IOrderedContainer(Interface):
collections.
"""
def moveObjectsByDelta(ids, delta):
def moveObjectsByDelta(ids, delta, subset_ids=None):
""" Move specified sub-objects by delta.
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
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
if you don't want to change their original order, make sure the order
of ids corresponds to their original order.
......@@ -43,7 +47,7 @@ class IOrderedContainer(Interface):
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.
If no delta is specified, delta is 1. See moveObjectsByDelta for more
......@@ -54,7 +58,7 @@ class IOrderedContainer(Interface):
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.
If no delta is specified, delta is 1. See moveObjectsByDelta for more
......@@ -65,7 +69,7 @@ class IOrderedContainer(Interface):
Returns -- Number of moved sub-objects
"""
def moveObjectsToTop(ids):
def moveObjectsToTop(ids, subset_ids=None):
""" Move specified sub-objects to top of container.
See moveObjectsByDelta for more details.
......@@ -75,7 +79,7 @@ class IOrderedContainer(Interface):
Returns -- Number of moved sub-objects
"""
def moveObjectsToBottom(ids):
def moveObjectsToBottom(ids, subset_ids=None):
""" Move specified sub-objects to bottom of container.
See moveObjectsByDelta for more details.
......
......@@ -12,7 +12,7 @@
##############################################################################
""" 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
......@@ -130,68 +130,76 @@ class OrderSupport:
#
security.declareProtected(manage_properties, 'moveObjectsByDelta')
def moveObjectsByDelta(self, ids, delta):
def moveObjectsByDelta(self, ids, delta, subset_ids=None):
""" Move specified sub-objects by delta.
"""
if type(ids) is StringType:
ids = (ids,)
min_position = 0
objects = list(self._objects)
obj_dict = {}
for obj in self._objects:
obj_dict[ obj['id'] ] = obj
if subset_ids == None:
subset_ids = [ obj['id'] for obj in objects ]
else:
subset_ids = list(subset_ids)
# unify moving direction
if delta > 0:
ids = list(ids)
ids.reverse()
objects.reverse()
subset_ids.reverse()
counter = 0
for id in ids:
try:
object = obj_dict[id]
except KeyError:
raise ValueError('The object with the id "%s" does not exist.'
% id)
old_position = objects.index(object)
old_position = subset_ids.index(id)
new_position = max( old_position - abs(delta), min_position )
if new_position == min_position:
min_position += 1
if not old_position == new_position:
objects.remove(object)
objects.insert(new_position, object)
subset_ids.remove(id)
subset_ids.insert(new_position, id)
counter += 1
if counter > 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)
return counter
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.
"""
return self.moveObjectsByDelta(ids, -delta)
return self.moveObjectsByDelta(ids, -delta, subset_ids)
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.
"""
return self.moveObjectsByDelta(ids, delta)
return self.moveObjectsByDelta(ids, delta, subset_ids)
security.declareProtected(manage_properties, 'moveObjectsToTop')
def moveObjectsToTop(self, ids):
def moveObjectsToTop(self, ids, subset_ids=None):
""" 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')
def moveObjectsToBottom(self, ids):
def moveObjectsToBottom(self, ids, subset_ids=None):
""" 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')
def orderObjects(self, key, reverse=None):
......
from unittest import TestCase, TestSuite, makeSuite, main
import Testing
import Zope
Zope.startup()
from Interface.Verify import verifyClass
......@@ -40,100 +41,106 @@ class TestOrderSupport(TestCase):
f.o4 = DummyObject('o4', 'mt2')
return f
def _doCanonTestA(self, methodname, table):
for arg1, order, rval in table:
def _doCanonTest(self, methodname, table):
for args, order, rval in table:
f = self._makeOne()
method = getattr(f, methodname)
if rval == 'ValueError':
self.failUnlessRaises( ValueError, method, arg1 )
self.failUnlessRaises( ValueError, method, *args )
else:
self.failUnlessEqual( method(arg1), 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( method(*args), rval )
self.failUnlessEqual( f.objectIds(), order )
def test_moveObjectsUp(self):
self._doCanonTestB( 'moveObjectsUp',
( ( 'o4', 1, ['o1', 'o2', 'o4', 'o3'], 1 )
, ( 'o4', 2, ['o1', 'o4', 'o2', 'o3'], 1 )
, ( ('o1', 'o3'), 1, ['o1', 'o3', 'o2', 'o4'], 1 )
, ( ('o1', 'o3'), 9, ['o1', 'o3', 'o2', 'o4'], 1 )
, ( ('o2', 'o3'), 1, ['o2', 'o3', 'o1', 'o4'], 2 )
, ( ('n2', 'o3'), 1, ['o1', 'o2', 'o3', 'o4'], 'ValueError')
, ( ('o3', 'o1'), 1, ['o1', 'o3', 'o2', 'o4'], 1 )
self._doCanonTest( 'moveObjectsUp',
( ( ( 'o4', 1 ), ['o1', 'o2', 'o4', 'o3'], 1 )
, ( ( 'o4', 2 ), ['o1', 'o4', 'o2', 'o3'], 1 )
, ( ( ('o1', 'o3'), 1 ), ['o1', 'o3', 'o2', 'o4'], 1 )
, ( ( ('o1', 'o3'), 9 ), ['o1', 'o3', 'o2', 'o4'], 1 )
, ( ( ('o2', 'o3'), 1 ), ['o2', 'o3', 'o1', 'o4'], 2 )
, ( ( ('o2', 'o3'), 1, ('o1', 'o2', 'o3', 'o4') ),
['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):
self._doCanonTestB( 'moveObjectsDown',
( ( 'o1', 1, ['o2', 'o1', 'o3', 'o4'], 1 )
, ( 'o1', 2, ['o2', 'o3', 'o1', 'o4'], 1 )
, ( ('o2', 'o4'), 1, ['o1', 'o3', 'o2', 'o4'], 1 )
, ( ('o2', 'o4'), 9, ['o1', 'o3', 'o2', 'o4'], 1 )
, ( ('o2', 'o3'), 1, ['o1', 'o4', 'o2', 'o3'], 2 )
, ( ('n2', 'o3'), 1, ['o1', 'o2', 'o3', 'o4'], 'ValueError')
, ( ('o4', 'o2'), 1, ['o1', 'o3', 'o2', 'o4'], 1 )
self._doCanonTest( 'moveObjectsDown',
( ( ( 'o1', 1 ), ['o2', 'o1', 'o3', 'o4'], 1 )
, ( ( 'o1', 2 ), ['o2', 'o3', 'o1', 'o4'], 1 )
, ( ( ('o2', 'o4'), 1 ), ['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', 'o2', 'o3', 'o4') ),
['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):
self._doCanonTestA( 'moveObjectsToTop',
( ( 'o4', ['o4', 'o1', 'o2', 'o3'], 1 )
, ( ('o1', 'o3'), ['o1', 'o3', 'o2', 'o4'], 1 )
, ( ('o2', 'o3'), ['o2', 'o3', 'o1', 'o4'], 2 )
, ( ('n2', 'o3'), ['o1', 'o2', 'o3', 'o4'], 'ValueError')
, ( ('o3', 'o1'), ['o3', 'o1', 'o2', 'o4'], 1 )
self._doCanonTest( 'moveObjectsToTop',
( ( ( 'o4', ), ['o4', 'o1', 'o2', 'o3'], 1 )
, ( ( ('o1', 'o3'), ), ['o1', 'o3', 'o2', 'o4'], 1 )
, ( ( ('o2', 'o3'), ), ['o2', 'o3', 'o1', 'o4'], 2 )
, ( ( ('o2', 'o3'), ('o1', 'o2', 'o3', 'o4') ),
['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):
self._doCanonTestA( 'moveObjectsToBottom',
( ( 'o1', ['o2', 'o3', 'o4', 'o1'], 1 )
, ( ('o2', 'o4'), ['o1', 'o3', 'o2', 'o4'], 1 )
, ( ('o2', 'o3'), ['o1', 'o4', 'o2', 'o3'], 2 )
, ( ('n2', 'o3'), ['o1', 'o2', 'o3', 'o4'], 'ValueError')
, ( ('o4', 'o2'), ['o1', 'o3', 'o4', 'o2'], 1 )
self._doCanonTest( 'moveObjectsToBottom',
( ( ( 'o1', ), ['o2', 'o3', 'o4', 'o1'], 1 )
, ( ( ('o2', 'o4'), ), ['o1', 'o3', 'o2', 'o4'], 1 )
, ( ( ('o2', 'o3'), ), ['o1', 'o4', 'o2', 'o3'], 2 )
, ( ( ('o2', 'o3'), ('o1', 'o2', 'o3', 'o4') ),
['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):
self._doCanonTestB( 'orderObjects',
( ( 'id', 'id', ['o4', 'o3', 'o2', 'o1'], 3)
, ( 'meta_type', '', ['o1', 'o3', 'o2', 'o4'], 1)
, ( 'meta_type', 'n', ['o4', 'o2', 'o3', 'o1'], 3)
, ( 'position', 0, ['o1', 'o2', 'o3', 'o4'], 0)
, ( 'position', 1, ['o4', 'o3', 'o2', 'o1'], 3)
self._doCanonTest( 'orderObjects',
( ( ( 'id', 'id' ), ['o4', 'o3', 'o2', 'o1'], 3)
, ( ( 'meta_type', '' ), ['o1', 'o3', 'o2', 'o4'], 1)
, ( ( 'meta_type', 'n' ), ['o4', 'o2', 'o3', 'o1'], 3)
, ( ( 'position', 0 ), ['o1', 'o2', 'o3', 'o4'], 0)
, ( ( 'position', 1 ), ['o4', 'o3', 'o2', 'o1'], 3)
)
)
def test_getObjectPosition(self):
self._doCanonTestA( 'getObjectPosition',
( ( 'o2', ['o1', 'o2', 'o3', 'o4'], 1)
, ( 'o4', ['o1', 'o2', 'o3', 'o4'], 3)
, ( 'n2', ['o1', 'o2', 'o3', 'o4'], 'ValueError')
self._doCanonTest( 'getObjectPosition',
( ( ( 'o2', ), ['o1', 'o2', 'o3', 'o4'], 1)
, ( ( 'o4', ), ['o1', 'o2', 'o3', 'o4'], 3)
, ( ( 'n2', ), ['o1', 'o2', 'o3', 'o4'], 'ValueError')
)
)
def test_moveObjectToPosition(self):
self._doCanonTestB( 'moveObjectToPosition',
( ( 'o2', 2, ['o1', 'o3', 'o2', 'o4'], 1)
, ( 'o4', 2, ['o1', 'o2', 'o4', 'o3'], 1)
, ( 'n2', 2, ['o1', 'o2', 'o3', 'o4'], 'ValueError')
self._doCanonTest( 'moveObjectToPosition',
( ( ( 'o2', 2 ), ['o1', 'o3', 'o2', 'o4'], 1)
, ( ( 'o4', 2 ), ['o1', 'o2', 'o4', 'o3'], 1)
, ( ( 'n2', 2 ), ['o1', 'o2', 'o3', 'o4'], 'ValueError')
)
)
def test_manage_renameObject(self):
self._doCanonTestB( 'manage_renameObject',
( ( 'o2', 'n2', ['o1', 'n2', 'o3', 'o4'], None )
, ( 'o3', 'n3', ['o1', 'o2', 'n3', 'o4'], None )
self._doCanonTest( 'manage_renameObject',
( ( ( 'o2', 'n2' ), ['o1', 'n2', 'o3', 'o4'], None )
, ( ( 'o3', 'n3' ), ['o1', 'o2', 'n3', 'o4'], None )
)
)
......
from unittest import TestCase, TestSuite, makeSuite, main
import Testing
import Zope
Zope.startup()
from Interface.Verify import verifyClass
......
......@@ -21,13 +21,17 @@ class OrderSupport:
is totally user-specific.
"""
def moveObjectsByDelta(ids, delta):
def moveObjectsByDelta(ids, delta, subset_ids=None):
""" Move specified sub-objects by delta.
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
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
if you don't want to change their original order, make sure the order
of ids corresponds to their original order.
......@@ -39,7 +43,7 @@ class OrderSupport:
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.
If no delta is specified, delta is 1. See moveObjectsByDelta for more
......@@ -50,7 +54,7 @@ class OrderSupport:
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.
If no delta is specified, delta is 1. See moveObjectsByDelta for more
......@@ -61,7 +65,7 @@ class OrderSupport:
Returns -- Number of moved sub-objects
"""
def moveObjectsToTop(ids):
def moveObjectsToTop(ids, subset_ids=None):
""" Move specified sub-objects to top of container.
See moveObjectsByDelta for more details.
......@@ -71,7 +75,7 @@ class OrderSupport:
Returns -- Number of moved sub-objects
"""
def moveObjectsToBottom(ids):
def moveObjectsToBottom(ids, subset_ids=None):
""" Move specified sub-objects to bottom of container.
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