[pod,px] Allow to reference an already defined variable instead of defining one in a var statement, via the '@' prefix. For example, in PX: var='@i = i + 1'. [pod] Repaired broken tests [gen] Bugfixes.

This commit is contained in:
Gaetan Delannay 2013-09-23 22:36:09 +02:00
parent bd80d63eda
commit 180b3473e8
11 changed files with 1903 additions and 1887 deletions

View file

@ -72,8 +72,9 @@ class Computed(Field):
if not self.method: return if not self.method: return
if isinstance(self.method, Px): if isinstance(self.method, Px):
obj = obj.appy() obj = obj.appy()
ctx = {'obj': obj, 'field': self, tool = obj.tool
'_': obj.translate, 'tool': obj.tool} ctx = {'obj': obj, 'field': self, 'req': obj.request, 'tool': tool,
'_': tool.translate, 'url': tool.o.getIncludeUrl}
if self.context: ctx.update(self.context) if self.context: ctx.update(self.context)
return self.method(ctx) return self.method(ctx)
else: else:

View file

@ -245,26 +245,30 @@ function toggleCheckbox(visibleCheckbox, hiddenBoolean) {
} }
// Function that sets a value for showing/hiding sub-titles. // Function that sets a value for showing/hiding sub-titles.
function setSubTitles(value) { function setSubTitles(value, tag) {
createCookie('showSubTitles', value); createCookie('showSubTitles', value);
// Get the sub-titles // Get the sub-titles
var subTitles = getElementsHavingName('div', 'subTitle'); var subTitles = getElementsHavingName(tag, 'subTitle');
if (subTitles.length == 0) return; if (subTitles.length == 0) return;
// Define the display style depending on p_tag.
var displayStyle = 'inline';
if (tag == 'tr') displayStyle = 'table-row';
for (var i=0; i < subTitles.length; i++) { for (var i=0; i < subTitles.length; i++) {
if (value == 'true') subTitles[i].style.display = 'inline'; if (value == 'true') subTitles[i].style.display = displayStyle;
else subTitles[i].style.display = 'none'; else subTitles[i].style.display = 'none';
} }
} }
// Function that toggles the value for showing/hiding sub-titles. // Function that toggles the value for showing/hiding sub-titles.
function toggleSubTitles() { function toggleSubTitles(tag) {
// Get the current value // Get the current value
var value = readCookie('showSubTitles'); var value = readCookie('showSubTitles');
if (value == null) value = 'true'; if (value == null) value = 'true';
// Toggle the value // Toggle the value
var newValue = 'true'; var newValue = 'true';
if (value == 'true') newValue = 'false'; if (value == 'true') newValue = 'false';
setSubTitles(newValue); if (!tag) tag = 'div';
setSubTitles(newValue, tag);
} }
// Functions used for master/slave relationships between widgets // Functions used for master/slave relationships between widgets

View file

@ -48,7 +48,7 @@ class ToolWrapper(AbstractWrapper):
var="mustSortAndFilter=ajaxHookId == 'queryResult'; var="mustSortAndFilter=ajaxHookId == 'queryResult';
sortAndFilter=mustSortAndFilter and \ sortAndFilter=mustSortAndFilter and \
',%s,%s,%s' % (q(sortKey),q(sortOrder),q(filterKey)) or ''"> ',%s,%s,%s' % (q(sortKey),q(sortOrder),q(filterKey)) or ''">
<tr valign="middle"> <tr valign="bottom">
<!-- Go to the first page --> <!-- Go to the first page -->
<td if="(startNumber != 0) and (startNumber != batchSize)"><img <td if="(startNumber != 0) and (startNumber != batchSize)"><img
class="clickable" src=":url('arrowLeftDouble')" class="clickable" src=":url('arrowLeftDouble')"
@ -63,10 +63,10 @@ class ToolWrapper(AbstractWrapper):
str(sNumber)+sortAndFilter)"/></td> str(sNumber)+sortAndFilter)"/></td>
<!-- Explain which elements are currently shown --> <!-- Explain which elements are currently shown -->
<td class="discreet">&nbsp; <td class="discreet">
<x>:startNumber + 1</x> <img src=":url('to')"/> <x>:startNumber + 1</x> <img src=":url('to')"/>
<x>:startNumber + batchNumber</x>&nbsp;<b>//</b> <x>:startNumber + batchNumber</x> <b>//</b>
<x>:totalNumber</x>&nbsp;&nbsp;</td> <x>:totalNumber</x> </td>
<!-- Go to the next page --> <!-- Go to the next page -->
<td var="sNumber=startNumber + batchSize" <td var="sNumber=startNumber + batchSize"

View file

@ -244,25 +244,30 @@ class UserWrapper(AbstractWrapper):
# Call a custom "onDelete" if any. # Call a custom "onDelete" if any.
return self._callCustom('onDelete') return self._callCustom('onDelete')
def getLogins(self): def getLogins(self, groupsOnly=False):
'''Gets all the logins that can "match" this user: it own login and the '''Gets all the logins that can "match" this user: it own login
logins of all the groups he belongs to.''' (excepted if p_groupsOnly is True) and the logins of all the groups
# Try first to get those logins from a cache on the request. he belongs to.'''
try: # Try first to get those logins from a cache on the request, if this
return self.request.userLogins # user corresponds to the logged user.
except AttributeError: rq = self.request
if (self.user == self) and hasattr(rq, 'userLogins'):
return rq.userLogins
# Compute it.
res = [group.login for group in self.groups] res = [group.login for group in self.groups]
res.append(self.login) if not groupsOnly: res.append(self.login)
return res return res
def getRoles(self): def getRoles(self):
'''This method returns all the global roles for this user, not simply '''This method returns all the global roles for this user, not simply
self.roles, but also "ungrantable roles" (like Anonymous or self.roles, but also "ungrantable roles" (like Anonymous or
Authenticated) and roles inherited from group membership.''' Authenticated) and roles inherited from group membership.'''
# Try first to get those roles from a cache on the request. # Try first to get those roles from a cache on the request, if this user
try: # corresponds to the logged user.
return self.request.userRoles rq = self.request
except AttributeError: if (self.user == self) and hasattr(rq, 'userRoles'):
return rq.userRoles
# Compute it.
res = list(self.roles) res = list(self.roles)
# Add ungrantable roles # Add ungrantable roles
if self.o.id == 'anon': if self.o.id == 'anon':

View file

@ -38,26 +38,21 @@ class AbstractWrapper(object):
or gotoSource" or gotoSource"
src=":url('gotoSource')" title=":goBack"/></a> src=":url('gotoSource')" title=":goBack"/></a>
<!-- Go to the first page --> <!-- Go to the first or previous page -->
<a if="ni.firstUrl" href=":ni.firstUrl"><img title=":_('goto_first')" <a if="ni.firstUrl" href=":ni.firstUrl"><img title=":_('goto_first')"
src=":url('arrowLeftDouble')"/></a> src=":url('arrowLeftDouble')"/></a><a
if="ni.previousUrl" href=":ni.previousUrl"><img
<!-- Go to the previous page -->
<a if="ni.previousUrl" href=":ni.previousUrl"><img
title=":_('goto_previous')" src=":url('arrowLeftSimple')"/></a> title=":_('goto_previous')" src=":url('arrowLeftSimple')"/></a>
<!-- Explain which element is currently shown --> <!-- Explain which element is currently shown -->
<span class="discreet">&nbsp; <span class="discreet">
<x>:ni.currentNumber</x>&nbsp;<b>//</b> <x>:ni.currentNumber</x> <b>//</b>
<x>:ni.totalNumber</x>&nbsp;&nbsp; <x>:ni.totalNumber</x> </span>
</span>
<!-- Go to the next page --> <!-- Go to the next or last page -->
<a if="ni.nextUrl" href=":ni.nextUrl"><img title=":_('goto_next')" <a if="ni.nextUrl" href=":ni.nextUrl"><img title=":_('goto_next')"
src=":url('arrowRightSimple')"/></a> src=":url('arrowRightSimple')"/></a><a
if="ni.lastUrl" href=":ni.lastUrl"><img title=":_('goto_last')"
<!-- Go to the last page -->
<a if="ni.lastUrl" href=":ni.lastUrl"><img title=":_('goto_last')"
src=":url('arrowRightDouble')"/></a> src=":url('arrowRightDouble')"/></a>
</div>''') </div>''')
@ -289,13 +284,14 @@ class AbstractWrapper(object):
# This PX displays an object's history. # This PX displays an object's history.
pxHistory = Px(''' pxHistory = Px('''
<x var="startNumber=req.get'startNumber', 0); <x var="startNumber=req.get('startNumber', 0);
startNumber=int(startNumber); startNumber=int(startNumber);
batchSize=int(req.get('maxPerPage', 5)); batchSize=int(req.get('maxPerPage', 5));
historyInfo=zobj.getHistory(startNumber,batchSize=batchSize)" historyInfo=zobj.getHistory(startNumber,batchSize=batchSize)"
if="historyInfo.events" if="historyInfo.events"
var2="objs=historyInfo.events; var2="objs=historyInfo.events;
totalNumber=historyInfo.totalNumber; totalNumber=historyInfo.totalNumber;
batchNumber=len(objs);
ajaxHookId='appyHistory'; ajaxHookId='appyHistory';
navBaseCall='askObjectHistory(%s,%s,%d,**v**)' % \ navBaseCall='askObjectHistory(%s,%s,%d,**v**)' % \
(q(ajaxHookId), q(zobj.absolute_url()), batchSize)"> (q(ajaxHookId), q(zobj.absolute_url()), batchSize)">
@ -329,7 +325,7 @@ class AbstractWrapper(object):
<x if="not actorId">?</x> <x if="not actorId">?</x>
<x if="actorId">:ztool.getUserName(actorId)</x> <x if="actorId">:ztool.getUserName(actorId)</x>
</td> </td>
<td>:ztool.formatDate(event['time'], withHour=True)"></td> <td>:ztool.formatDate(event['time'], withHour=True)</td>
<td if="not isDataChange"> <td if="not isDataChange">
<x if="rhComments">::zobj.formatText(rhComments)</x> <x if="rhComments">::zobj.formatText(rhComments)</x>
<x if="not rhComments">-</x> <x if="not rhComments">-</x>
@ -400,8 +396,8 @@ class AbstractWrapper(object):
<!-- Plus/minus icon for accessing history --> <!-- Plus/minus icon for accessing history -->
<x if="hasHistory"> <x if="hasHistory">
<img class="clickable" onclick="toggleCookie('appyHistory')" <img class="clickable" onclick="toggleCookie('appyHistory')"
src="historyExpanded and url('collapse.gif') or url('expand.gif')" src=":historyExpanded and url('collapse.gif') or url('expand.gif')"
align=":dleft" id="appyHistory_img"/> align=":dleft" id="appyHistory_img" style="padding-right:4px"/>
<x>:_('object_history')</x> || <x>:_('object_history')</x> ||
</x> </x>
@ -412,7 +408,7 @@ class AbstractWrapper(object):
<x>:_('object_created_on')</x> <x>:_('object_created_on')</x>
<x var="creationDate=zobj.Created(); <x var="creationDate=zobj.Created();
modificationDate=zobj.Modified()"> modificationDate=zobj.Modified()">
<x>:ztool.formatDate(creationDate, withHour=True)></x> <x>:ztool.formatDate(creationDate, withHour=True)</x>
<x if="modificationDate != creationDate">&mdash; <x if="modificationDate != creationDate">&mdash;
<x>:_('object_modified_on')</x> <x>:_('object_modified_on')</x>
<x>:ztool.formatDate(modificationDate, withHour=True)</x> <x>:ztool.formatDate(modificationDate, withHour=True)</x>
@ -430,9 +426,9 @@ class AbstractWrapper(object):
<tr if="hasHistory"> <tr if="hasHistory">
<td colspan="2"> <td colspan="2">
<span id="appyHistory" <span id="appyHistory"
style=":historyExpanded and 'display:block' or 'display:none')"> style=":historyExpanded and 'display:block' or 'display:none'">
<div var="ajaxHookId=zobj.UID() + '_history'" id=":ajaxHookId"> <div var="ajaxHookId=zobj.UID() + '_history'" id=":ajaxHookId">
<script type="text/javascript">:'askObjectHistory(%s,%s,%d,0)' % \ <script type="text/javascript">::'askObjectHistory(%s,%s,%d,0)' % \
(q(ajaxHookId), q(zobj.absolute_url()), \ (q(ajaxHookId), q(zobj.absolute_url()), \
historyMaxPerPage)</script> historyMaxPerPage)</script>
</div> </div>

View file

@ -346,6 +346,10 @@ class VariablesAction(BufferAction):
# Evaluate variable expression in vRes. # Evaluate variable expression in vRes.
vRes, error = self.evaluateExpression(result, context, expr) vRes, error = self.evaluateExpression(result, context, expr)
if error: return if error: return
# Replace the value of global variables
if name.startswith('@'):
context[name[1:]] = vRes
continue
# Remember the variable previous value if already in the context # Remember the variable previous value if already in the context
if name in context: if name in context:
if not hidden: if not hidden:
@ -364,6 +368,7 @@ class VariablesAction(BufferAction):
if hidden: context.update(hidden) if hidden: context.update(hidden)
# Delete not-hidden variables # Delete not-hidden variables
for name, expr in self.variables: for name, expr in self.variables:
if name.startswith('@'): continue
if hidden and (name in hidden): continue if hidden and (name in hidden): continue
del context[name] del context[name]
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View file

@ -242,7 +242,7 @@ class MemoryBuffer(Buffer):
actionRex = re.compile('(?:(\w+)\s*\:\s*)?do\s+(\w+)(-)?' \ actionRex = re.compile('(?:(\w+)\s*\:\s*)?do\s+(\w+)(-)?' \
'(?:\s+(for|if|else|with)\s*(.*))?') '(?:\s+(for|if|else|with)\s*(.*))?')
forRex = re.compile('\s*([\w\-_]+)\s+in\s+(.*)') forRex = re.compile('\s*([\w\-_]+)\s+in\s+(.*)')
varRex = re.compile('\s*([\w\-_]+)\s*=\s*(.*)') varRex = re.compile('\s*(@?[\w\-_]+)\s*=\s*(.*)')
def __init__(self, env, parent): def __init__(self, env, parent):
Buffer.__init__(self, env, parent) Buffer.__init__(self, env, parent)

File diff suppressed because it is too large Load diff

Binary file not shown.

Binary file not shown.

Binary file not shown.