[Checkins] SVN: Products.CMFCore/trunk/Products/CMFCore/ - ActionInformation: extend the ActionInformation and ActionInfo classes
Jens Vagelpohl
jens at dataflake.org
Wed Sep 17 17:22:41 EDT 2008
Log message for revision 91221:
- ActionInformation: extend the ActionInformation and ActionInfo classes
to support a icon URL just like the newer Action class already does
Changed:
U Products.CMFCore/trunk/Products/CMFCore/ActionInformation.py
U Products.CMFCore/trunk/Products/CMFCore/ActionProviderBase.py
U Products.CMFCore/trunk/Products/CMFCore/CHANGES.txt
U Products.CMFCore/trunk/Products/CMFCore/TypesTool.py
U Products.CMFCore/trunk/Products/CMFCore/dtml/editToolsActions.dtml
U Products.CMFCore/trunk/Products/CMFCore/exportimport/tests/test_typeinfo.py
U Products.CMFCore/trunk/Products/CMFCore/exportimport/typeinfo.py
U Products.CMFCore/trunk/Products/CMFCore/tests/test_ActionInformation.py
U Products.CMFCore/trunk/Products/CMFCore/tests/test_ActionProviderBase.py
U Products.CMFCore/trunk/Products/CMFCore/tests/test_ActionsTool.py
-=-
Modified: Products.CMFCore/trunk/Products/CMFCore/ActionInformation.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/ActionInformation.py 2008-09-17 21:15:09 UTC (rev 91220)
+++ Products.CMFCore/trunk/Products/CMFCore/ActionInformation.py 2008-09-17 21:22:41 UTC (rev 91221)
@@ -173,6 +173,7 @@
self.data.setdefault( 'title', self.data['name'] )
del self.data['name']
self.data.setdefault( 'url', '' )
+ self.data.setdefault( 'icon', '' )
self.data.setdefault( 'category', 'object' )
self.data.setdefault( 'visible', True )
self.data['available'] = True
@@ -200,7 +201,7 @@
def __eq__(self, other):
# this is expensive, use it with care
- [ self.__getitem__(key) for key in self._lazy_keys ]
+ [ self.__getitem__(key) for key in self._lazy_keys[:] ]
if isinstance(other, self.__class__):
[ other[key] for key in other._lazy_keys ]
@@ -261,6 +262,7 @@
, priority=10
, visible=True
, action=''
+ , icon_expr=''
):
""" Set up an instance.
"""
@@ -273,6 +275,7 @@
, priority
, visible
, action
+ , icon_expr
)
security.declarePrivate('edit')
@@ -286,6 +289,7 @@
, priority=_unchanged
, visible=_unchanged
, action=_unchanged
+ , icon_expr=_unchanged
):
"""Edit the specified properties.
"""
@@ -314,6 +318,10 @@
if action and isinstance(action, basestring):
action = Expression(action)
self.setActionExpression(action)
+ if icon_expr is not _unchanged:
+ if icon_expr and isinstance(icon_expr, basestring):
+ icon_expr = Expression(icon_expr)
+ self.setIconExpression(icon_expr)
security.declareProtected( View, 'Title' )
def Title(self):
@@ -385,6 +393,36 @@
action = Expression( action )
self.action = action
+ security.declarePrivate( '_getIconExpressionObject' )
+ def _getIconExpressionObject( self ):
+
+ """ Find the icon expression object, working around name changes.
+ """
+ return getattr( self, 'icon_expr', None )
+
+ security.declarePublic( 'getIconExpression' )
+ def getIconExpression( self ):
+
+ """ Return the text of the TALES expression for our icon URL.
+ """
+ icon_expr = self._getIconExpressionObject()
+ expr = icon_expr and icon_expr.text or ''
+ if expr and isinstance(expr, basestring):
+ if ( not expr.startswith('string:')
+ and not expr.startswith('python:') ):
+ expr = 'string:${object_url}/%s' % expr
+ self.icon_expr = Expression( expr )
+ return expr
+
+ security.declarePrivate( 'setIconExpression' )
+ def setIconExpression(self, icon_expr):
+ if icon_expr and isinstance(icon_expr, basestring):
+ if ( not icon_expr.startswith('string:')
+ and not icon_expr.startswith('python:') ):
+ icon_expr = 'string:${object_url}/%s' % icon_expr
+ icon_expr = Expression( icon_expr )
+ self.icon_expr = icon_expr
+
security.declarePublic( 'getCondition' )
def getCondition(self):
@@ -427,7 +465,8 @@
and self.condition.text or '',
'permissions': self.permissions,
'visible': bool(self.visible),
- 'action': self.getActionExpression() }
+ 'action': self.getActionExpression(),
+ 'icon_expr' : self.getIconExpression() }
security.declarePrivate('clone')
def clone( self ):
@@ -449,6 +488,13 @@
lazy_map['url'] = ''
del lazy_map['action']
+ if lazy_map['icon_expr']:
+ lazy_map['icon'] = self._getIconExpressionObject()
+ lazy_keys.append('icon')
+ else:
+ lazy_map['icon'] = ''
+ del lazy_map['icon_expr']
+
if lazy_map['condition']:
lazy_map['available'] = self.testCondition
lazy_keys.append('available')
Modified: Products.CMFCore/trunk/Products/CMFCore/ActionProviderBase.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/ActionProviderBase.py 2008-09-17 21:15:09 UTC (rev 91220)
+++ Products.CMFCore/trunk/Products/CMFCore/ActionProviderBase.py 2008-09-17 21:22:41 UTC (rev 91221)
@@ -168,6 +168,7 @@
, permission
, category
, visible=1
+ , icon_expr=''
, REQUEST=None
):
""" Add an action to our list.
@@ -190,6 +191,7 @@
, permissions=permission
, visible=bool(visible)
, action=action
+ , icon_expr=icon_expr
)
new_actions.append( new_action )
@@ -312,6 +314,7 @@
id = str( properties.get( 'id_%d' % index, '' ) )
title = str( properties.get( 'name_%d' % index, '' ) )
action = str( properties.get( 'action_%d' % index, '' ) )
+ icon_expr = str( properties.get( 'icon_expr_%d' % index, '' ) )
condition = str( properties.get( 'condition_%d' % index, '' ) )
category = str( properties.get( 'category_%d' % index, '' ))
visible = bool( properties.get('visible_%d' % index, False) )
@@ -333,6 +336,7 @@
, permissions=permissions
, category=category
, visible=visible
+ , icon_expr=icon_expr
)
def _getOAI(self, object):
Modified: Products.CMFCore/trunk/Products/CMFCore/CHANGES.txt
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/CHANGES.txt 2008-09-17 21:15:09 UTC (rev 91220)
+++ Products.CMFCore/trunk/Products/CMFCore/CHANGES.txt 2008-09-17 21:22:41 UTC (rev 91221)
@@ -4,6 +4,9 @@
2.2.0 (unreleased)
------------------
+- ActionInformation: extend the ActionInformation and ActionInfo classes
+ to support a icon URL just like the newer Action class already does
+
- WorkflowTool: Passing the "magic" chain name "(Default)" to the
setChainForPortalTypes method did not set the chain to the default
chain value as expected.
Modified: Products.CMFCore/trunk/Products/CMFCore/TypesTool.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/TypesTool.py 2008-09-17 21:15:09 UTC (rev 91220)
+++ Products.CMFCore/trunk/Products/CMFCore/TypesTool.py 2008-09-17 21:22:41 UTC (rev 91221)
@@ -156,6 +156,7 @@
, permission=action.get( 'permissions', () )
, category=action.get('category', 'object')
, visible=action.get('visible', True)
+ , icon_expr=action.get('icon_expr', '')
)
self.setMethodAliases(kw.get('aliases', {}))
Modified: Products.CMFCore/trunk/Products/CMFCore/dtml/editToolsActions.dtml
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/dtml/editToolsActions.dtml 2008-09-17 21:15:09 UTC (rev 91220)
+++ Products.CMFCore/trunk/Products/CMFCore/dtml/editToolsActions.dtml 2008-09-17 21:22:41 UTC (rev 91221)
@@ -70,6 +70,20 @@
<td></td>
<td>
<div class="form-label">
+ Icon (Expression)
+ </div>
+</td>
+<td>
+ <div class="form-element">
+ <input type="text" name="icon_expr_&dtml-index;" value="&dtml-icon_expr;" size="80" />
+ </div>
+</td>
+</tr>
+
+<tr>
+<td></td>
+<td>
+ <div class="form-label">
Condition (Expression)
</div>
</td>
@@ -205,10 +219,25 @@
</div>
</td>
</tr>
+
<tr>
<td></td>
<td>
<div class="form-label">
+ Icon (Expression)
+ </div>
+</td>
+<td>
+ <div class="form-element">
+ <input type="text" name="icon_expr" value="" size="80" />
+ </div>
+</td>
+</tr>
+
+<tr>
+<td></td>
+<td>
+ <div class="form-label">
Condition (Expression)
</div>
</td>
Modified: Products.CMFCore/trunk/Products/CMFCore/exportimport/tests/test_typeinfo.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/exportimport/tests/test_typeinfo.py 2008-09-17 21:15:09 UTC (rev 91220)
+++ Products.CMFCore/trunk/Products/CMFCore/exportimport/tests/test_typeinfo.py 2008-09-17 21:22:41 UTC (rev 91221)
@@ -52,8 +52,8 @@
<alias from="(Default)" to="foo"/>
<alias from="view" to="foo"/>
<action title="Foo" action_id="foo_action" category="Bar"
- condition_expr="python:1" url_expr="string:${object_url}/foo"
- visible="True"/>
+ condition_expr="python:1" icon_expr="string:${portal_url}/icon.png"
+ url_expr="string:${object_url}/foo" visible="True"/>
</object>
"""
@@ -86,16 +86,19 @@
'actions': ({'id': 'view',
'title': 'View',
'action': 'string:${object_url}/foo_view',
+ 'icon_expr': 'string:${portal_url}/preview_icon.png',
'permissions': (View,),
},
{'id': 'edit',
'title': 'Edit',
'action': 'string:${object_url}/foo_edit_form',
+ 'icon_expr': 'string:${portal_url}/edit_icon.png',
'permissions': (ModifyPortalContent,),
},
{'id': 'metadata',
'title': 'Metadata',
'action': 'string:${object_url}/metadata_edit_form',
+ 'icon_expr': 'string:${portal_url}/metadata_icon.png',
'permissions': (ModifyPortalContent,),
},
),
@@ -197,16 +200,18 @@
<alias from="(Default)" to="foo_view"/>
<alias from="view" to="foo_view"/>
<action title="View" action_id="view" category="object" condition_expr=""
- url_expr="string:${object_url}/foo_view" visible="True">
+ url_expr="string:${object_url}/foo_view"
+ icon_expr="string:${portal_url}/preview_icon.png" visible="True">
<permission value="View"/>
</action>
<action title="Edit" action_id="edit" category="object" condition_expr=""
- url_expr="string:${object_url}/foo_edit_form" visible="True">
+ url_expr="string:${object_url}/foo_edit_form"
+ icon_expr="string:${portal_url}/edit_icon.png" visible="True">
<permission value="Modify portal content"/>
</action>
<action title="Metadata" action_id="metadata" category="object"
condition_expr="" url_expr="string:${object_url}/metadata_edit_form"
- visible="True">
+ icon_expr="string:${portal_url}/metadata_icon.png" visible="True">
<permission value="Modify portal content"/>
</action>
</object>
@@ -233,21 +238,23 @@
<alias from="(Default)" to="bar_view"/>
<alias from="view" to="bar_view"/>
<action title="View" action_id="view" category="object" condition_expr=""
- url_expr="string:${object_url}/bar_view" visible="True">
+ url_expr="string:${object_url}/bar_view"
+ icon_expr="" visible="True">
<permission value="View"/>
</action>
<action title="Edit" action_id="edit" category="object" condition_expr=""
- url_expr="string:${object_url}/bar_edit_form" visible="True">
+ url_expr="string:${object_url}/bar_edit_form"
+ icon_expr="" visible="True">
<permission value="Modify portal content"/>
</action>
<action title="Contents" action_id="contents" category="object"
condition_expr="" url_expr="string:${object_url}/folder_contents"
- visible="True">
+ icon_expr="" visible="True">
<permission value="Access contents information"/>
</action>
<action title="Metadata" action_id="metadata" category="object"
condition_expr="" url_expr="string:${object_url}/metadata_edit_form"
- visible="True">
+ icon_expr="" visible="True">
<permission value="Modify portal content"/>
</action>
</object>
@@ -273,7 +280,8 @@
def _populate(self, obj):
obj.setMethodAliases({'(Default)': 'foo', 'view': 'foo'})
obj.addAction('foo_action', 'Foo', 'string:${object_url}/foo',
- 'python:1', (), 'Bar')
+ 'python:1', (), 'Bar',
+ icon_expr="string:${portal_url}/icon.png")
def _verifyImport(self, obj):
self.assertEqual(type(obj._aliases), dict)
@@ -291,6 +299,9 @@
self.assertEqual(obj._actions[0].category, 'Bar')
self.assertEqual(type(obj._actions[0].condition.text), str)
self.assertEqual(obj._actions[0].condition.text, 'python:1')
+ self.assertEqual(type(obj._actions[0].icon_expr.text), str)
+ self.assertEqual(obj._actions[0].icon_expr.text,
+ "string:${portal_url}/icon.png")
def setUp(self):
self._obj = FactoryTypeInformation('foo_fti')
Modified: Products.CMFCore/trunk/Products/CMFCore/exportimport/typeinfo.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/exportimport/typeinfo.py 2008-09-17 21:15:09 UTC (rev 91220)
+++ Products.CMFCore/trunk/Products/CMFCore/exportimport/typeinfo.py 2008-09-17 21:22:41 UTC (rev 91221)
@@ -101,6 +101,7 @@
child.setAttribute('category', ai_info['category'])
child.setAttribute('condition_expr', ai_info['condition'])
child.setAttribute('url_expr', ai_info['action'])
+ child.setAttribute('icon_expr', ai_info['icon_expr'])
child.setAttribute('visible', str(bool(ai_info['visible'])))
for permission in ai_info['permissions']:
sub = self._doc.createElement('permission')
@@ -121,6 +122,7 @@
category = str(child.getAttribute('category'))
condition = str(child.getAttribute('condition_expr'))
action = str(child.getAttribute('url_expr'))
+ icon_expr = str(child.getAttribute('icon_expr'))
visible = self._convertToBoolean(child.getAttribute('visible'))
permissions = []
for sub in child.childNodes:
@@ -131,10 +133,11 @@
action_obj = self.context.getActionObject(category+'/'+id)
if action_obj is None:
self.context.addAction(id, title, action, condition,
- tuple(permissions), category, visible)
+ tuple(permissions), category, visible,
+ icon_expr=icon_expr)
else:
action_obj.edit(title=title, action=action,
- condition=condition,
+ icon_expr=icon_expr, condition=condition,
permissions=tuple(permissions),
visible=visible)
Modified: Products.CMFCore/trunk/Products/CMFCore/tests/test_ActionInformation.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/tests/test_ActionInformation.py 2008-09-17 21:15:09 UTC (rev 91220)
+++ Products.CMFCore/trunk/Products/CMFCore/tests/test_ActionInformation.py 2008-09-17 21:22:41 UTC (rev 91221)
@@ -167,7 +167,7 @@
WANTED = {'allowed': True, 'available': True, 'category': 'object',
'description': '', 'id': 'foo', 'title': 'foo', 'url': '',
- 'visible': True}
+ 'visible': True, 'icon': ''}
action = ActionInformation(id='foo')
ec = None
@@ -177,6 +177,7 @@
self.assertEqual( ai['title'], WANTED['title'] )
self.assertEqual( ai['description'], WANTED['description'] )
self.assertEqual( ai['url'], WANTED['url'] )
+ self.assertEqual( ai['icon'], WANTED['icon'] )
self.assertEqual( ai['category'], WANTED['category'] )
self.assertEqual( ai['visible'], WANTED['visible'] )
self.assertEqual( ai['available'], WANTED['available'] )
@@ -185,7 +186,8 @@
def test_create_from_dict(self):
WANTED = {'allowed': True, 'available': True, 'category': 'object',
- 'id': 'foo', 'title': 'foo', 'url': '', 'visible': True}
+ 'id': 'foo', 'title': 'foo', 'url': '', 'visible': True,
+ 'icon': '' }
action = {'name': 'foo', 'url': ''}
ec = None
@@ -194,6 +196,7 @@
self.assertEqual( ai['id'], WANTED['id'] )
self.assertEqual( ai['title'], WANTED['title'] )
self.assertEqual( ai['url'], WANTED['url'] )
+ self.assertEqual( ai['icon'], WANTED['icon'] )
self.assertEqual( ai['category'], WANTED['category'] )
self.assertEqual( ai['visible'], WANTED['visible'] )
self.assertEqual( ai['available'], WANTED['available'] )
@@ -215,7 +218,8 @@
def test_create_from_dict(self):
WANTED = {'allowed': True, 'available': True, 'category': 'object',
- 'id': 'foo', 'title': 'foo', 'url': '', 'visible': True}
+ 'id': 'foo', 'title': 'foo', 'url': '', 'visible': True,
+ 'icon': ''}
action = {'name': 'foo', 'url': '', 'permissions': ('View',)}
ec = createExprContext(self.site, self.site, None)
@@ -224,6 +228,7 @@
self.assertEqual( ai['id'], WANTED['id'] )
self.assertEqual( ai['title'], WANTED['title'] )
self.assertEqual( ai['url'], WANTED['url'] )
+ self.assertEqual( ai['icon'], WANTED['icon'] )
self.assertEqual( ai['category'], WANTED['category'] )
self.assertEqual( ai['visible'], WANTED['visible'] )
self.assertEqual( ai['available'], WANTED['available'] )
@@ -418,7 +423,7 @@
def test_getInfoData_empty(self):
WANTED = ( {'available': True, 'category': 'object',
'description': '', 'id': 'foo', 'permissions': (),
- 'title': 'foo', 'url': '', 'visible': True}, [] )
+ 'title': 'foo', 'url': '', 'visible': True, 'icon': ''},[])
a = self._makeOne('foo')
self.assertEqual( a.getInfoData(), WANTED )
@@ -427,14 +432,16 @@
title='Foo Title',
description='Foo description.',
action='string:${object_url}/foo_url',
+ icon_expr='string:${object_url}/icon.gif',
condition='',
permissions=('View',),
visible=False)
WANTED = ( {'available': True, 'category': 'object',
'description': 'Foo description.', 'id': 'foo',
'permissions': ('View',), 'title': 'Foo Title',
- 'url': a._getActionObject(), 'visible': False},
- ['url'] )
+ 'url': a._getActionObject(), 'visible': False,
+ 'icon': a._getIconExpressionObject(), },
+ ['url', 'icon'] )
self.assertEqual( a.getInfoData(), WANTED )
Modified: Products.CMFCore/trunk/Products/CMFCore/tests/test_ActionProviderBase.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/tests/test_ActionProviderBase.py 2008-09-17 21:15:09 UTC (rev 91220)
+++ Products.CMFCore/trunk/Products/CMFCore/tests/test_ActionProviderBase.py 2008-09-17 21:22:41 UTC (rev 91221)
@@ -239,7 +239,7 @@
def test_listActionInfos(self):
wanted = [{'id': 'an_id', 'title': 'A Title', 'description': '',
'url': '', 'category': 'object', 'visible': False,
- 'available': True, 'allowed': True}]
+ 'available': True, 'allowed': True, 'icon': ''}]
apb = self.site._setObject( 'portal_apb', self._makeProvider(1) )
rval = apb.listActionInfos()
@@ -260,7 +260,7 @@
def test_getActionInfo(self):
wanted = {'id': 'an_id', 'title': 'A Title', 'description': '',
'url': '', 'category': 'object', 'visible': False,
- 'available': True, 'allowed': True}
+ 'available': True, 'allowed': True, 'icon': ''}
apb = self.site._setObject( 'portal_apb', self._makeProvider(1) )
rval = apb.getActionInfo( ('object/an_id',) )
Modified: Products.CMFCore/trunk/Products/CMFCore/tests/test_ActionsTool.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/tests/test_ActionsTool.py 2008-09-17 21:15:09 UTC (rev 91220)
+++ Products.CMFCore/trunk/Products/CMFCore/tests/test_ActionsTool.py 2008-09-17 21:22:41 UTC (rev 91221)
@@ -120,6 +120,8 @@
title='Folder contents',
action=Expression(text='string:'
'${folder_url}/folder_contents'),
+ icon_expr=Expression(text='string:'
+ '${folder_url}/icon.gif'),
condition=Expression(text='python: '
'folder is not object'),
permissions=('List folder contents',),
@@ -133,6 +135,7 @@
'object': [],
'folder': [{'id': 'folderContents',
'url': 'http://nohost/folder_contents',
+ 'icon': 'http://nohost/icon.gif',
'title': 'Folder contents',
'description': '',
'visible': True,
More information about the Checkins
mailing list