1769 lines
71 KiB
Python
1769 lines
71 KiB
Python
# -*- coding: iso-8859-15 -*-
|
|
|
|
|
|
# Glasnost
|
|
# By: Odile Bénassy <obenassy@entrouvert.com>
|
|
# Romain Chantereau <rchantereau@entrouvert.com>
|
|
# Nicolas Clapiès <nclapies@easter-eggs.org>
|
|
# Pierre-Antoine Dejace <padejace@entrouvert.be>
|
|
# Thierry Dulieu <tdulieu@easter-eggs.com>
|
|
# Florent Monnier <monnier@codelutin.com>
|
|
# Cédric Musso <cmusso@easter-eggs.org>
|
|
# Frédéric Péters <fpeters@entrouvert.be>
|
|
# Benjamin Poussin <poussin@codelutin.com>
|
|
# Emmanuel Raviart <eraviart@entrouvert.com>
|
|
# Sébastien Régnier <regnier@codelutin.com>
|
|
# Emmanuel Saracco <esaracco@easter-eggs.com>
|
|
#
|
|
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
|
|
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
|
|
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
|
|
# Emmanuel Saracco & Théridion
|
|
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
|
|
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
|
|
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
|
|
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
|
|
# Régnier, Emmanuel Saracco, Théridion & Vecam
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License
|
|
# as published by the Free Software Foundation; either version 2
|
|
# of the License, or (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
|
|
from __future__ import nested_scopes
|
|
|
|
|
|
__doc__ = """Glasnost Web Widgets"""
|
|
|
|
__version__ = '$Revision$'[11:-2]
|
|
|
|
|
|
import locale
|
|
import time
|
|
import urllib
|
|
|
|
import glasnost.common.context as context
|
|
import glasnost.common.faults as faults
|
|
import glasnost.common.parsers as parsers
|
|
import glasnost.common.tools_new as commonTools
|
|
import glasnost.common.xhtmlgenerator as X
|
|
|
|
import glasnost.proxy.widgets as proxyWidgets
|
|
|
|
import properties
|
|
import things
|
|
|
|
import calendaring
|
|
from tools import *
|
|
import translation
|
|
|
|
|
|
register = things.register
|
|
|
|
|
|
class WidgetMixin(things.ThingMixin):
|
|
def fillModelFieldChildrenLayout(self, slot, fields, layout, **keywords):
|
|
label = self.getHtmlFieldLabel(slot)
|
|
layout += label
|
|
balloonHelp = slot.getKind().balloonHelp
|
|
showToolTip = context.getVar('virtualHost').useBalloonHelp \
|
|
and balloonHelp and self.isReadOnly(slot)
|
|
if showToolTip:
|
|
tooltipId = 'for-tooltip-%s' % slot.getFieldName()
|
|
layout += X.span(_class = 'field-description tooltip',
|
|
id = tooltipId)(_(balloonHelp))
|
|
cell = self.getHtmlFieldValue(slot, fields, **keywords)
|
|
if cell is not None:
|
|
if isinstance(cell, X.array):
|
|
tooltipCell = [x for x in cell.children if x][0]
|
|
else:
|
|
tooltipCell = cell
|
|
if showToolTip:
|
|
tooltipCell.setAttribute(
|
|
'id', 'tooltip-%s' % slot.getFieldName())
|
|
if self.colSpan:
|
|
cell.setAttribute('class', ' '.join(
|
|
[cell.getAttribute('class'), 'fullwidth']))
|
|
if self.colSpan:
|
|
label.setAttribute('class', ' '.join(
|
|
[label.getAttribute('class'), 'fullwidth']))
|
|
|
|
if slot.getFieldOption(fields, 'error') \
|
|
and not fields.has_key('hideErrors'):
|
|
layout.setAttribute('class', ' '.join(
|
|
[layout.getAttribute('class'), 'error']))
|
|
layout += cell
|
|
|
|
def getHtmlColumnLabel(self, slot):
|
|
label = self.getModelLabel(slot)
|
|
return X.th(scope = 'col')(_(label))
|
|
|
|
def getHtmlColumnValue(self, slot, fields, **keywords):
|
|
tdAttributes = {}
|
|
return X.td(**tdAttributes)(
|
|
self.getHtmlValue(slot, fields, **keywords))
|
|
|
|
def getHtmlFieldLabel(self, slot):
|
|
label = self.getModelLabel(slot)
|
|
|
|
# Disabled since <label> caused some problems (with Mozilla 1.0?)
|
|
# labelAttributes = {'for': slot.getFieldName()}
|
|
#
|
|
# Seen on css-discuss:
|
|
# > This will, however cause a problem with Netscape 6 (7 is fine),
|
|
# > wherein the floated labels will not be visible. To fix that,
|
|
# > unfortunately you have to put the labels inside spans and float the
|
|
# > spans instead.
|
|
#
|
|
# if self.isInForm():
|
|
# if slot.getKind().isRequired and self.isInForm() \
|
|
# and not self.isReadOnly(slot):
|
|
# labelAttributes['class'] = 'required'
|
|
# return X.label(**labelAttributes)(_(label), X.asIs(_(':') + ' '))
|
|
|
|
required = ''
|
|
if slot.getKind().isRequired and self.isInForm() \
|
|
and not self.isReadOnly(slot):
|
|
required = ' required'
|
|
return X.span(_class = 'label%s' % required)(
|
|
_(label), X.asIs(_(':') + ' '))
|
|
|
|
def getHtmlFieldValue(self, slot, fields, **keywords):
|
|
# We have to enclose the field value in a tag with class 'cell' but we
|
|
# want a nice markup so we can't simply <div class="cell"> v </div> and
|
|
# go away with this.
|
|
if self.isInForm() and context.getVar('virtualHost').showTooltips:
|
|
webTools.addContextualHeader('tooltips.js')
|
|
|
|
return X.enclose(self.getHtmlValue(slot, fields, **keywords),
|
|
_class = 'cell')
|
|
|
|
def getHtmlValue(self, slot, fields, **keywords):
|
|
# FIXME: To rename to getModelFieldValueChildrenLayout?
|
|
if not self.isInForm():
|
|
return self.getHtmlViewValue(slot, fields, **keywords)
|
|
elif self.isReadOnly(slot):
|
|
return self.getHtmlReadOnlyValue(slot, fields, **keywords)
|
|
else:
|
|
return self.getHtmlFormValue(slot, fields, **keywords)
|
|
|
|
def getHtmlViewValue(self, slot, fields, **keywords):
|
|
fieldValue = slot.getField(fields, default = '')
|
|
format = slot.getKind().textFormat
|
|
if format == 'html':
|
|
formattedText = parsers.makeHtmlFromHtml(fieldValue, inline = 1)
|
|
elif format == 'text':
|
|
formattedText = parsers.makeHtmlFromPreformattedText(
|
|
fieldValue, inline = 1)
|
|
elif format == 'rst':
|
|
formattedText = parsers.makeHtmlFromReStructuredText(
|
|
fieldValue, inline = 1)
|
|
elif format == 'spip':
|
|
formattedText = parsers.makeHtmlFromSpip(fieldValue, inline = 1)
|
|
else:
|
|
formattedText = parsers.makeHtmlFromUnformattedText(
|
|
fieldValue, inline = 1)
|
|
formattedText = replaceSpecialTags(formattedText)
|
|
return X.asIs(formattedText)
|
|
|
|
def getHtmlReadOnlyValue(self, slot, fields, **keywords):
|
|
return X.array(
|
|
self.getModelHiddenLayout(slot, fields),
|
|
self.getHtmlViewValue(slot, fields, **keywords) )
|
|
|
|
def getHtmlFormValue(self, slot, fields, **keywords):
|
|
fieldName = slot.getFieldName()
|
|
fieldValue = slot.getField(fields, default = '')
|
|
layout = X.array()
|
|
layout += self.getModelErrorLayout(slot, fields)
|
|
layout += self.getModelHelpLayout(slot, fields)
|
|
inputAttributes = {}
|
|
layout += X.input(name = fieldName, type = 'text',
|
|
value = fieldValue, **inputAttributes)
|
|
return layout
|
|
|
|
def getModelErrorLayout(self, slot, fields):
|
|
errorCode = slot.getFieldOption(fields, 'error')
|
|
if errorCode and not fields.has_key('hideErrors'):
|
|
return X.asIs(makeErrorMessage(errorCode))
|
|
return None
|
|
|
|
def getModelFieldLayout(self, slot, fields, **keywords):
|
|
assert fields is not None
|
|
kind = slot.getKind()
|
|
tagName = kind.getModelFieldTag(slot)
|
|
if tagName == 'div-with-label':
|
|
# FIXME: Rename class 'row' to 'field'?
|
|
layout = X.div(_class = 'row',
|
|
id = 'field-%s' % slot.getFieldName())
|
|
self.fillModelFieldChildrenLayout(slot, fields, layout, **keywords)
|
|
return layout
|
|
else:
|
|
tagClass = getattr(X, tagName)
|
|
fieldName = slot.getFieldName()
|
|
level = 'getModelFieldLayout %s' % fieldName
|
|
context.push(_level = level, inline = tagClass.inlineElements)
|
|
try:
|
|
childrenLayout = self.getHtmlValue(slot, fields, **keywords)
|
|
finally:
|
|
context.pull(_level = level)
|
|
if not childrenLayout:
|
|
return None
|
|
return tagClass(id = 'field-%s' % fieldName)(childrenLayout)
|
|
|
|
def getModelHelpLayout(self, slot, fields):
|
|
## helpAlias = self.getHelpAlias(slot, fields)
|
|
## if helpAlias and 'pagenames' in context.getVar('knownRoles') and \
|
|
## getWebForServerRole('pagenames').getIdByName(helpAlias):
|
|
## return X.a(_class = 'online-help',
|
|
## href = X.aliasUrl(helpAlias))(_('help'))
|
|
return None
|
|
|
|
def getModelHiddenLayout(self, slot, fields):
|
|
fieldName = slot.getFieldName()
|
|
fieldValue = slot.getField(fields, default = '')
|
|
return X.input(name = fieldName, type = 'hidden', value = fieldValue)
|
|
|
|
def getModelPageBodyLayout(self, slot, fields):
|
|
layoutMode = context.getVar('layoutMode')
|
|
if layoutMode != 'edit':
|
|
layout = self.getHtmlViewValue(slot, fields)
|
|
elif self.isReadOnly(slot):
|
|
layout = self.getHtmlReadOnlyValue(slot, fields)
|
|
else:
|
|
layout = self.getHtmlFormValue(slot, fields)
|
|
return layout
|
|
|
|
|
|
class InputTextMixin(WidgetMixin):
|
|
def getHtmlViewValue(self, slot, fields, **keywords):
|
|
fieldValue, translationBar = \
|
|
translation.getFieldValueAndTranslationBar(slot, fields)
|
|
|
|
format = slot.getKind().textFormat
|
|
if format == 'html':
|
|
formattedText = parsers.makeHtmlFromHtml(fieldValue, inline = 1)
|
|
elif format == 'text':
|
|
formattedText = parsers.makeHtmlFromPreformattedText(
|
|
fieldValue, inline = 1)
|
|
elif format == 'rst':
|
|
formattedText = parsers.makeHtmlFromReStructuredText(
|
|
fieldValue, inline = 1)
|
|
elif format == 'spip':
|
|
formattedText = parsers.makeHtmlFromSpip(fieldValue, inline = 1)
|
|
else:
|
|
formattedText = parsers.makeHtmlFromUnformattedText(
|
|
fieldValue, inline = 1)
|
|
formattedText = replaceSpecialTags(formattedText)
|
|
|
|
layout = X.asIs(formattedText)
|
|
|
|
if translationBar:
|
|
layout = X.array(layout, translationBar)
|
|
|
|
return layout
|
|
|
|
def getHtmlReadOnlyValue(self, slot, fields, **keywords):
|
|
fieldValue = str(slot.getField(fields, default = ''))
|
|
|
|
format = slot.getKind().textFormat
|
|
if format == 'html':
|
|
formattedText = parsers.makeHtmlFromHtml(fieldValue, inline = 1)
|
|
elif format == 'text':
|
|
formattedText = parsers.makeHtmlFromPreformattedText(
|
|
fieldValue, inline = 1)
|
|
elif format == 'rst':
|
|
formattedText = parsers.makeHtmlFromReStructuredText(
|
|
fieldValue, inline = 1)
|
|
elif format == 'spip':
|
|
formattedText = parsers.makeHtmlFromSpip(fieldValue, inline = 1)
|
|
else:
|
|
formattedText = parsers.makeHtmlFromUnformattedText(
|
|
fieldValue, inline = 1)
|
|
formattedText = replaceSpecialTags(formattedText)
|
|
|
|
return X.array(
|
|
self.getModelHiddenLayout(slot, fields),
|
|
X.asIs(formattedText))
|
|
|
|
def getHtmlFormValue(self, slot, fields, **keywords):
|
|
fieldName = slot.getFieldName()
|
|
fieldValue = str(slot.getField(fields, default = ''))
|
|
|
|
layout = X.array()
|
|
layout += self.getModelErrorLayout(slot, fields)
|
|
layout += self.getModelHelpLayout(slot, fields)
|
|
|
|
inputAttributes = {}
|
|
maxLength = slot.getKind().getTextMaxLength()
|
|
if maxLength is not None:
|
|
inputAttributes['maxlength'] = maxLength
|
|
if self.size is not None:
|
|
size = self.size
|
|
elif maxLength is not None:
|
|
size = min(80, maxLength)
|
|
else:
|
|
size = None
|
|
if size is not None:
|
|
inputAttributes['size'] = size
|
|
layout += X.input(name = fieldName, type = 'text',
|
|
value = fieldValue, **inputAttributes)
|
|
if self.apply:
|
|
layout += ' '
|
|
layout += X.buttonInForm('apply', 'applyButton')
|
|
return layout
|
|
|
|
|
|
class ThingMixin(WidgetMixin):
|
|
def getHtmlValue(self, slot, fields, **keywords):
|
|
kind = slot.getKind()
|
|
parentSlot, value = kind.getCreatedModelSlotAndValue(slot)
|
|
if not self.isInForm():
|
|
layout = X.div(value.getFieldValueChildrenViewLayout(
|
|
fields, parentSlot = parentSlot))
|
|
elif self.isReadOnly(slot):
|
|
layout = X.array(
|
|
value.getHiddenLayout(fields, parentSlot = parentSlot),
|
|
X.div(value.getFieldValueChildrenViewLayout(
|
|
fields, parentSlot = parentSlot)))
|
|
else:
|
|
layout = X.array(
|
|
self.getModelErrorLayout(slot, fields),
|
|
self.getModelHelpLayout(slot, fields),
|
|
X.div(value.getFieldValueChildrenEditLayout(
|
|
fields, parentSlot = parentSlot)))
|
|
return layout
|
|
|
|
def getModelPageBodyLayout(self, slot, fields):
|
|
kind = slot.getKind()
|
|
parentSlot, value = kind.getCreatedModelSlotAndValue(slot)
|
|
layoutMode = context.getVar('layoutMode')
|
|
if layoutMode == 'edit':
|
|
layout = value.getEditLayout(fields, parentSlot = parentSlot)
|
|
else:
|
|
layout = value.getViewLayout(fields, parentSlot = parentSlot)
|
|
return layout
|
|
|
|
|
|
class TimeMixin(InputTextMixin):
|
|
pass
|
|
|
|
|
|
class BaseWidget(WidgetMixin, proxyWidgets.BaseWidget):
|
|
pass
|
|
register(BaseWidget)
|
|
|
|
|
|
class Amount(WidgetMixin, proxyWidgets.Amount):
|
|
centsSep = '.' # FIXME we have to localize that
|
|
|
|
def getHtmlViewValue(self, slot, fields, **keywords):
|
|
mainFieldValue = slot.getFieldOption(fields, 'main', default = '0')
|
|
centsFieldValue = slot.getFieldOption(fields, 'cents', default = '00')
|
|
sideFieldValue = slot.getFieldOption(
|
|
fields, 'side', default = 'credit')
|
|
|
|
sideLabels = self.sideLabels
|
|
sideFieldLabel = sideLabels[sideFieldValue]
|
|
fieldName = slot.getFieldName()
|
|
return X.array(
|
|
X.asIs(mainFieldValue),
|
|
self.centsSep,
|
|
X.asIs(centsFieldValue),
|
|
X.nbsp,
|
|
X.asIs(_(sideFieldLabel)),
|
|
)
|
|
|
|
|
|
def getHtmlFormValue(self, slot, fields, **keywords):
|
|
mainFieldName = slot.getFieldOptionName('main')
|
|
centsFieldName = slot.getFieldOptionName('cents')
|
|
sideFieldName = slot.getFieldOptionName('side')
|
|
|
|
mainFieldValue = slot.getFieldOption(fields, 'main', default = '0')
|
|
centsFieldValue = slot.getFieldOption(fields, 'cents', default = '00')
|
|
sideFieldValue = slot.getFieldOption(
|
|
fields, 'side', default = 'credit')
|
|
|
|
mainSize = 7
|
|
centsSize = 2
|
|
|
|
layout = X.array()
|
|
layout += self.getModelErrorLayout(slot, fields)
|
|
layout += self.getModelHelpLayout(slot, fields)
|
|
layout += X.input(name = mainFieldName, value = mainFieldValue,
|
|
size = mainSize, maxlength = mainSize),
|
|
layout += X.nbsp
|
|
layout += self.centsSep
|
|
layout += X.nbsp
|
|
layout += X.input(name = centsFieldName, value = centsFieldValue,
|
|
size = centsSize, maxlength = centsSize)
|
|
layout += X.nbsp
|
|
select = X.select(name = sideFieldName)
|
|
if not sideFieldValue:
|
|
select += X.option(selected = 'selected', value = '')(
|
|
_('None'))
|
|
else:
|
|
sideLabels = self.sideLabels
|
|
for sideValue in sideLabels.keys():
|
|
optionAttributes = {}
|
|
if sideValue == sideFieldValue:
|
|
optionAttributes['selected'] = 'selected'
|
|
select += X.option(value = sideValue, **optionAttributes)(
|
|
_(sideLabels[sideValue]))
|
|
layout += select
|
|
return layout
|
|
|
|
def getModelHiddenLayout(self, slot, fields):
|
|
mainFieldName = slot.getFieldOptionName('main')
|
|
centsFieldName = slot.getFieldOptionName('cents')
|
|
sideFieldName = slot.getFieldOptionName('side')
|
|
mainFieldValue = slot.getFieldOption(fields, 'main', default = '')
|
|
centsFieldValue = slot.getFieldOption(fields, 'cents', default = '')
|
|
sideFieldValue = slot.getFieldOption(fields, 'side', default = '')
|
|
return X.array(
|
|
X.input(name = mainFieldName, type = 'hidden',
|
|
value = mainFieldValue),
|
|
X.input(name = centsFieldName, type = 'hidden',
|
|
value = centsFieldValue),
|
|
X.input(name = sideFieldName, type = 'hidden',
|
|
value = sideFieldValue),
|
|
)
|
|
register(Amount)
|
|
|
|
|
|
class Date(TimeMixin, proxyWidgets.Date):
|
|
sep = '-'
|
|
|
|
def getHtmlViewValue(self, slot, fields, **keywords):
|
|
yearFieldValue = slot.getFieldOption(fields, 'year', default = '')
|
|
monthFieldValue = slot.getFieldOption(fields, 'month', default = '')
|
|
dayFieldValue = slot.getFieldOption(fields, 'day', default = '')
|
|
|
|
partsToDisplay = slot.getKind().requiredParts
|
|
layout = X.array()
|
|
if monthFieldValue:
|
|
monthTitle = calendaring.getMonthLabelNoCapitalization(
|
|
int(monthFieldValue))
|
|
else:
|
|
monthTitle = ''
|
|
|
|
for partName in partsToDisplay:
|
|
if partName == 'month' and not 'day' in partsToDisplay:
|
|
layout += X.asIs(_(monthTitle)[1:])
|
|
else:
|
|
layout += X.asIs(locals()["%sFieldValue" % partName])
|
|
if partName != partsToDisplay[-1]:
|
|
if partName == 'month' and not 'day' in partsToDisplay:
|
|
layout += X.nbsp
|
|
else:
|
|
layout += self.sep
|
|
return layout
|
|
|
|
def getHtmlFormValue(self, slot, fields, **keywords):
|
|
partsToDisplay = slot.getKind().requiredParts
|
|
|
|
yearFieldName = slot.getFieldOptionName('year')
|
|
monthFieldName = slot.getFieldOptionName('month')
|
|
dayFieldName = slot.getFieldOptionName('day')
|
|
yearFieldValue = slot.getFieldOption(fields, 'year', default = '')
|
|
monthFieldValue = slot.getFieldOption(fields, 'month', default = '')
|
|
dayFieldValue = slot.getFieldOption(fields, 'day', default = '')
|
|
|
|
layout = X.array()
|
|
layout += self.getModelErrorLayout(slot, fields)
|
|
layout += self.getModelHelpLayout(slot, fields)
|
|
# set select specifications
|
|
yearValues = [ '%d'%(
|
|
time.localtime(time.time())[0]+x) for x in range(
|
|
self.yearMinRel, self.yearMaxRel + 1) ]
|
|
if self.reverseYearOrder:
|
|
yearValues.reverse()
|
|
monthValues = [ '%02d'%x for x in range(1, 13) ]
|
|
dayValues = [ '%02d'%x for x in range(1, 32) ]
|
|
# year
|
|
if 'year' in partsToDisplay:
|
|
yearSelect = X.select(name = yearFieldName)
|
|
if not yearFieldValue in yearValues:
|
|
yearSelect += X.option(
|
|
selected = 'selected', value = '')(_('Year'))
|
|
for value in yearValues:
|
|
optionAttributes = {}
|
|
if value == yearFieldValue:
|
|
optionAttributes['selected'] = 'selected'
|
|
yearSelect += X.option(
|
|
value = value, **optionAttributes)(value)
|
|
layout += yearSelect
|
|
layout += X.nbsp
|
|
# month
|
|
if 'month' in partsToDisplay:
|
|
monthSelect = X.select(name = monthFieldName)
|
|
if not monthFieldValue in monthValues:
|
|
monthSelect += X.option(
|
|
selected = 'selected', value = '')(_('Month'))
|
|
for value in monthValues:
|
|
optionAttributes = {}
|
|
if value == monthFieldValue:
|
|
optionAttributes['selected'] = 'selected'
|
|
monthSelect += X.option(
|
|
value = value, **optionAttributes)(
|
|
calendaring.getMonthLabelNoCapitalization(
|
|
int(value)))
|
|
layout += monthSelect
|
|
layout += X.nbsp
|
|
# day
|
|
if 'day' in partsToDisplay:
|
|
daySelect = X.select(name = dayFieldName)
|
|
if not dayFieldValue in dayValues:
|
|
daySelect += X.option(
|
|
selected = 'selected', value = '')(_('Day'))
|
|
for value in dayValues:
|
|
optionAttributes = {}
|
|
if value == dayFieldValue:
|
|
optionAttributes['selected'] = 'selected'
|
|
daySelect += X.option(
|
|
value = value, **optionAttributes)(value)
|
|
layout += daySelect
|
|
return layout
|
|
|
|
def getModelHiddenLayout(self, slot, fields):
|
|
yearFieldName = slot.getFieldOptionName('year')
|
|
monthFieldName = slot.getFieldOptionName('month')
|
|
dayFieldName = slot.getFieldOptionName('day')
|
|
yearFieldValue = slot.getFieldOption(fields, 'year', default = '')
|
|
monthFieldValue = slot.getFieldOption(fields, 'month', default = '')
|
|
dayFieldValue = slot.getFieldOption(fields, 'day', default = '')
|
|
return X.array(
|
|
X.input(name = yearFieldName, type = 'hidden',
|
|
value = yearFieldValue),
|
|
X.input(name = monthFieldName, type = 'hidden',
|
|
value = monthFieldValue),
|
|
X.input(name = dayFieldName, type = 'hidden',
|
|
value = dayFieldValue),
|
|
)
|
|
register(Date)
|
|
|
|
|
|
class Duration(WidgetMixin, proxyWidgets.Duration):
|
|
partLabels = {
|
|
'day' : N_('day'),
|
|
'hour' : N_('hour'),
|
|
'minute' : N_('minute'),
|
|
'second' : N_('second'),
|
|
}
|
|
|
|
def getHtmlViewValue(self, slot, fields, **keywords):
|
|
secondFieldValue = slot.getFieldOption(fields, 'second', default = 0)
|
|
minuteFieldValue = slot.getFieldOption(fields, 'minute', default = 0)
|
|
hourFieldValue = slot.getFieldOption(fields, 'hour', default = 0)
|
|
dayFieldValue = slot.getFieldOption(fields, 'day', default = 0)
|
|
|
|
partsToDisplay = slot.getKind().requiredParts
|
|
layout = X.array()
|
|
for partName in partsToDisplay:
|
|
partValue = locals()['%sFieldValue' % partName]
|
|
if partValue:
|
|
layout += X.asIs(partValue)
|
|
layout += X.nbsp
|
|
if partValue == 1:
|
|
layout += X.asIs('%s' % _(self.partLabels[partName]))
|
|
else:
|
|
layout += X.asIs('%ss' % _(self.partLabels[partName]))
|
|
layout += X.nbsp
|
|
return layout
|
|
|
|
def getHtmlFormValue(self, slot, fields, **keywords):
|
|
secondFieldName = slot.getFieldOptionName('second')
|
|
minuteFieldName = slot.getFieldOptionName('minute')
|
|
hourFieldName = slot.getFieldOptionName('hour')
|
|
dayFieldName = slot.getFieldOptionName('day')
|
|
|
|
secondFieldValue = slot.getFieldOption(fields, 'second', default = 0)
|
|
minuteFieldValue = slot.getFieldOption(fields, 'minute', default = 0)
|
|
hourFieldValue = slot.getFieldOption(fields, 'hour', default = 0)
|
|
dayFieldValue = slot.getFieldOption(fields, 'day', default = 0)
|
|
|
|
partsToDisplay = slot.getKind().requiredParts
|
|
|
|
layout = X.array()
|
|
layout += self.getModelErrorLayout(slot, fields)
|
|
layout += self.getModelHelpLayout(slot, fields)
|
|
|
|
for partName in partsToDisplay:
|
|
layout += X.input(maxlength = 3,
|
|
name = locals()['%sFieldName' % partName],
|
|
size = 3, type = 'text',
|
|
value = locals()['%sFieldValue' % partName])
|
|
layout += X.nbsp
|
|
layout += X.asIs('%ss' % _(self.partLabels[partName]))
|
|
layout += X.nbsp
|
|
return layout
|
|
|
|
def getModelHiddenLayout(self, slot, fields):
|
|
secondFieldName = slot.getFieldOptionName('second')
|
|
minuteFieldName = slot.getFieldOptionName('minute')
|
|
hourFieldName = slot.getFieldOptionName('hour')
|
|
dayFieldName = slot.getFieldOptionName('day')
|
|
|
|
secondFieldValue = slot.getFieldOption(fields, 'second', default = 0)
|
|
minuteFieldValue = slot.getFieldOption(fields, 'minute', default = 0)
|
|
hourFieldValue = slot.getFieldOption(fields, 'hour', default = 0)
|
|
dayFieldValue = slot.getFieldOption(fields, 'day', default = 0)
|
|
|
|
return X.array(
|
|
X.input(name = secondFieldName, type = 'hidden',
|
|
value = secondFieldValue),
|
|
X.input(name = minuteFieldName, type = 'hidden',
|
|
value = minuteFieldValue),
|
|
X.input(name = hourFieldName, type = 'hidden',
|
|
value = hourFieldValue),
|
|
X.input(name = dayFieldName, type = 'hidden',
|
|
value = dayFieldValue),
|
|
)
|
|
register(Duration)
|
|
|
|
|
|
class Email(WidgetMixin, proxyWidgets.Email):
|
|
def getHtmlViewValue(self, slot, fields, **keywords):
|
|
fieldValue = slot.getField(fields, default = '')
|
|
if fieldValue:
|
|
fieldValueMailTo = fieldValue.replace('@', '%40')
|
|
fieldValueHtml = fieldValue.replace('@', ' [at] ')
|
|
return X.a(href = 'mailto:%s' % fieldValueMailTo)(
|
|
fieldValueHtml)
|
|
else:
|
|
return X.asIs(_('undefined'))
|
|
|
|
def getHtmlFormValue(self, slot, fields, **keywords):
|
|
fieldName = slot.getFieldName()
|
|
fieldValue = str(slot.getField(fields, default = ''))
|
|
|
|
layout = X.array()
|
|
layout += self.getModelErrorLayout(slot, fields)
|
|
layout += self.getModelHelpLayout(slot, fields)
|
|
|
|
inputAttributes = {}
|
|
maxLength = slot.getKind().getTextMaxLength()
|
|
if maxLength is not None:
|
|
inputAttributes['maxlength'] = maxLength
|
|
if self.size is not None:
|
|
size = self.size
|
|
elif maxLength is not None:
|
|
size = min(80, maxLength)
|
|
else:
|
|
size = None
|
|
if size is not None:
|
|
inputAttributes['size'] = size
|
|
layout += X.input(name = fieldName, type = 'text',
|
|
value = fieldValue, **inputAttributes)
|
|
if self.apply:
|
|
layout += ' '
|
|
layout += X.buttonInForm('apply', 'applyButton')
|
|
return layout
|
|
|
|
def getModelHiddenLayout(self, slot, fields):
|
|
fieldName = slot.getFieldName()
|
|
fieldValue = slot.getField(fields, default = '')
|
|
|
|
return X.array(
|
|
X.input(name = fieldName, type = 'hidden',
|
|
value = fieldValue),
|
|
)
|
|
register(Email)
|
|
|
|
|
|
class InputCheckBox(WidgetMixin, proxyWidgets.InputCheckBox):
|
|
def getHtmlViewValue(self, slot, fields, **keywords):
|
|
kind = slot.getKind()
|
|
value = kind.getModelValueFromFields(slot, fields)
|
|
return self.makeModelTitleFromValue(slot, fields, value)
|
|
|
|
def getHtmlFormValue(self, slot, fields, **keywords):
|
|
fieldName = slot.getFieldName()
|
|
kind = slot.getKind()
|
|
value = kind.getModelValueFromFields(slot, fields)
|
|
|
|
layout = X.array()
|
|
layout += self.getModelErrorLayout(slot, fields)
|
|
layout += self.getModelHelpLayout(slot, fields)
|
|
inputAttributes = {}
|
|
if value:
|
|
inputAttributes['checked'] = 'checked'
|
|
trueValue = kind.getValues(slot, fields)[1]
|
|
layout += X.input(
|
|
_class = 'checkbox', name = fieldName, type = 'checkbox',
|
|
value = kind.getModelValueAsString(trueValue),
|
|
**inputAttributes)
|
|
layout += X.nbsp
|
|
labels = self.getLabels(slot, fields)
|
|
label = labels[kind.getModelValueAsString(trueValue)]
|
|
layout += _(label)
|
|
if self.apply:
|
|
layout += ' '
|
|
layout += X.buttonInForm('apply', 'applyButton')
|
|
return layout
|
|
|
|
def makeModelTitleFromValue(self, slot, fields, value):
|
|
kind = slot.getKind()
|
|
valueAsString = kind.getModelValueAsString(value)
|
|
layoutMode = context.getVar('layoutMode')
|
|
if layoutMode != 'edit':
|
|
if self.titles and self.titles.has_key(valueAsString):
|
|
return _(self.titles[valueAsString])
|
|
title = kind.makeModelTitleFromValue(slot, fields, value)
|
|
if title:
|
|
return title
|
|
labels = self.getLabels(slot, fields)
|
|
if labels and labels.has_key(valueAsString):
|
|
return _(labels[valueAsString])
|
|
return None
|
|
register(InputCheckBox)
|
|
|
|
|
|
class InputPassword(WidgetMixin, proxyWidgets.InputPassword):
|
|
def getHtmlViewValue(self, slot, fields, **keywords):
|
|
fieldValue = slot.getField(fields, default = '')
|
|
cryptedValue = '*' * len(fieldValue)
|
|
return cryptedValue
|
|
|
|
def getHtmlFormValue(self, slot, fields, **keywords):
|
|
fieldName = slot.getFieldName()
|
|
fieldValue = str(slot.getField(fields, default = ''))
|
|
|
|
layout = X.array()
|
|
layout += self.getModelErrorLayout(slot, fields)
|
|
layout += self.getModelHelpLayout(slot, fields)
|
|
|
|
inputAttributes = {}
|
|
maxLength = slot.getKind().getTextMaxLength()
|
|
if maxLength is not None:
|
|
inputAttributes['maxlength'] = maxLength
|
|
if self.size is not None:
|
|
size = self.size
|
|
elif maxLength is not None:
|
|
size = min(80, maxLength)
|
|
else:
|
|
size = None
|
|
if size is not None:
|
|
inputAttributes['size'] = size
|
|
layout += X.input(name = fieldName, type = 'password',
|
|
value = fieldValue, **inputAttributes)
|
|
if self.apply:
|
|
layout += ' '
|
|
layout += X.buttonInForm('apply', 'applyButton')
|
|
return layout
|
|
register(InputPassword)
|
|
|
|
|
|
class InputText(InputTextMixin, proxyWidgets.InputText):
|
|
pass
|
|
register(InputText)
|
|
|
|
|
|
class Link(WidgetMixin, proxyWidgets.Link):
|
|
def getHtmlViewValue(self, slot, fields, **keywords):
|
|
nameFieldValue = slot.getFieldOption(fields, 'name', default = '')
|
|
urlFieldValue = slot.getFieldOption(fields, 'url', default = '')
|
|
|
|
nameFieldValue, translationBar = \
|
|
translation.getFieldValueAndTranslationBar(slot, fields,
|
|
fieldValue = nameFieldValue)
|
|
|
|
if urlFieldValue.startswith('glasnost://'):
|
|
url = X.idUrl(urlFieldValue)
|
|
else:
|
|
url = urlFieldValue
|
|
layout = X.a(href = url)(nameFieldValue)
|
|
|
|
if translationBar:
|
|
layout = X.array(layout, translationBar)
|
|
|
|
return layout
|
|
|
|
def getHtmlReadOnlyValue(self, slot, fields, **keywords):
|
|
nameFieldValue = slot.getFieldOption(fields, 'name', default = '')
|
|
urlFieldValue = slot.getFieldOption(fields, 'url', default = '')
|
|
return X.array(
|
|
self.getModelHiddenLayout(slot, fields),
|
|
X.a(href = X.absoluteUrl(urlFieldValue))(nameFieldValue))
|
|
|
|
def getHtmlFormValue(self, slot, fields, **keywords):
|
|
nameFieldName = slot.getFieldOptionName('name')
|
|
urlFieldName = slot.getFieldOptionName('url')
|
|
nameFieldValue = slot.getFieldOption(fields, 'name', default = '')
|
|
urlFieldValue = slot.getFieldOption(fields, 'url', default = '')
|
|
|
|
layout = X.array()
|
|
layout += self.getModelErrorLayout(slot, fields)
|
|
layout += self.getModelHelpLayout(slot, fields)
|
|
layout += X.table(
|
|
X.tr(
|
|
X.td(_class = 'field-label')(_('Title'), X.asIs(_(':') + \
|
|
' ')),
|
|
X.td(X.input(
|
|
maxlength = 80, name = nameFieldName, size = 80,
|
|
type = 'text', value = nameFieldValue))),
|
|
X.tr(
|
|
X.td(_class = 'field-label')(_('URL'), X.asIs(_(':') + \
|
|
' ')),
|
|
X.td(X.input(
|
|
maxlength = 80, name = urlFieldName, size = 80,
|
|
type = 'text', value = urlFieldValue))),
|
|
)
|
|
return layout
|
|
|
|
def getModelHiddenLayout(self, slot, fields):
|
|
nameFieldName = slot.getFieldOptionName('name')
|
|
urlFieldName = slot.getFieldOptionName('url')
|
|
nameFieldValue = slot.getFieldOption(fields, 'name', default = '')
|
|
urlFieldValue = slot.getFieldOption(fields, 'url', default = '')
|
|
return X.array(
|
|
X.input(name = nameFieldName, type = 'hidden',
|
|
value = nameFieldValue),
|
|
X.input(name = urlFieldName, type = 'hidden',
|
|
value = urlFieldValue),
|
|
)
|
|
register(Link)
|
|
|
|
|
|
class Mapping(WidgetMixin, proxyWidgets.Mapping):
|
|
def getHtmlValue(self, slot, fields, **keywords):
|
|
kind = slot.getKind()
|
|
countName = slot.getFieldOptionName('count')
|
|
count = kind.getItemsCount(slot, fields)
|
|
layout = X.array()
|
|
fieldset = X.div(_class = 'fieldset')
|
|
# not X.fieldset because it's buggy on several proprietary browsers
|
|
layout += fieldset
|
|
if self.isInForm():
|
|
layout += X.input(name = countName, type = 'hidden', value = count)
|
|
for i in range(count):
|
|
keySlot = kind.getItemKeySlot(slot, i)
|
|
keyWidget = keySlot.getWidget()
|
|
if keyWidget is None:
|
|
raise Exception('Missing key widget for %s in %s' % (
|
|
slot.getPath(), str(keySlot.getKind().__dict__)))
|
|
keyWidget.setInForm(self.isInForm())
|
|
keyWidget.setReadOnly(self.isReadOnly(slot))
|
|
valueSlot = kind.getItemKeyValueSlot(keySlot)
|
|
valueWidget = kind.valueKind.getModelWidget(valueSlot)
|
|
if valueWidget is None:
|
|
raise Exception('Missing value widget for %s in %s' % (
|
|
slot.getPath(), str(valueSlot.getKind().__dict__)))
|
|
valueWidget.setInForm(self.isInForm())
|
|
valueWidget.setReadOnly(self.isReadOnly(slot))
|
|
fieldset += X.div(_class = 'row',
|
|
id = 'field-%s' % slot.getFieldName())(
|
|
keyWidget.getHtmlFieldValue(keySlot, fields),
|
|
valueWidget.getHtmlFieldValue(valueSlot, fields))
|
|
if self.isInForm() and not self.isReadOnly(slot):
|
|
if kind.canAddItem(slot, fields):
|
|
addButtonName = slot.getFieldOptionName('addButton')
|
|
layout += X.buttonInForm('add', addButtonName)
|
|
if self.apply:
|
|
layout += X.buttonInForm('apply', 'applyButton')
|
|
return layout
|
|
|
|
def getModelHiddenLayout(self, slot, fields):
|
|
countName = slot.getFieldOptionName('count')
|
|
count = slot.getKind().fieldsCountMin
|
|
try:
|
|
count = max(count, int(slot.getFieldOption(
|
|
fields, 'count', default = '0')))
|
|
except ValueError:
|
|
pass
|
|
layout = X.array()
|
|
for i in range(count):
|
|
keySlot = slot.getKind().getItemKeySlot(slot, i)
|
|
keyWidget = keySlot.getWidget()
|
|
if keyWidget is None:
|
|
raise Exception('Missing key widget for %s in %s' % (
|
|
slot.getPath(), str(keySlot.getKind().__dict__)))
|
|
layout += keyWidget.getModelHiddenLayout(keySlot, fields)
|
|
valueSlot = slot.getKind().getItemKeyValueSlot(keySlot)
|
|
valueWidget = valueSlot.getWidget()
|
|
if valueWidget is None:
|
|
raise Exception('Missing value widget for %s in %s' % (
|
|
slot.getPath(), str(valueSlot.getKind().__dict__)))
|
|
layout += valueWidget.getModelHiddenLayout(valueSlot, fields)
|
|
return layout
|
|
register(Mapping)
|
|
|
|
|
|
class Multi(WidgetMixin, proxyWidgets.Multi):
|
|
def getHtmlValue(self, slot, fields, **keywords):
|
|
kind = slot.getKind()
|
|
countName = slot.getFieldOptionName('count')
|
|
count = kind.getItemsCount(slot, fields)
|
|
layout = X.array()
|
|
if self.isInForm():
|
|
layout += self.getModelErrorLayout(slot, fields)
|
|
|
|
if self.inline:
|
|
fieldset = X.ul(_class = 'multi inline')
|
|
else:
|
|
fieldset = X.ul(_class = 'multi')
|
|
if self.isInForm():
|
|
layout += X.input(name = countName, type = 'hidden', value = count)
|
|
layout += X.div(fieldset)
|
|
else:
|
|
layout += fieldset
|
|
for i in range(count):
|
|
itemSlot = kind.getItemSlot(slot, i)
|
|
itemWidget = itemSlot.getWidget()
|
|
if itemWidget is None:
|
|
raise Exception('Missing item widget for %s in %s' % (
|
|
slot.getPath(), str(itemSlot.getKind().__dict__)))
|
|
itemWidget.setInForm(self.isInForm())
|
|
itemWidget.setReadOnly(self.isReadOnly(slot))
|
|
if kind.isLabelImportant(slot):
|
|
fieldset += X.li(itemWidget.getModelFieldLayout(
|
|
itemSlot, fields))
|
|
else:
|
|
fieldset += X.li(itemWidget.getHtmlValue(itemSlot, fields))
|
|
if self.isInForm() and not self.isReadOnly(slot):
|
|
if kind.canAddItem(slot, fields):
|
|
addButtonName = slot.getFieldOptionName('addButton')
|
|
layout += X.buttonInForm('add', addButtonName)
|
|
if self.apply:
|
|
layout += X.buttonInForm('apply', 'applyButton')
|
|
return layout
|
|
|
|
def getModelHiddenLayout(self, slot, fields):
|
|
countName = slot.getFieldOptionName('count')
|
|
count = slot.getKind().fieldsCountMin
|
|
try:
|
|
count = max(count, int(slot.getFieldOption(
|
|
fields, 'count', default = '0')))
|
|
except ValueError:
|
|
pass
|
|
layout = X.array()
|
|
if count:
|
|
layout += X.input(name = countName, type = 'hidden', value = count)
|
|
for i in range(count):
|
|
itemSlot = slot.getKind().getItemSlot(slot, i)
|
|
itemWidget = itemSlot.getWidget()
|
|
if itemWidget is None:
|
|
raise Exception('Missing item widget for %s in %s' % (
|
|
slot.getPath(), str(itemSlot.getKind().__dict__)))
|
|
layout += itemWidget.getModelHiddenLayout(itemSlot, fields)
|
|
return layout
|
|
register(Multi)
|
|
|
|
|
|
class MultiCheck(WidgetMixin, proxyWidgets.MultiCheck):
|
|
def getHtmlFormValue(self, slot, fields, **keywords):
|
|
kind = slot.getKind()
|
|
layout = X.ul()
|
|
for i in range(len(kind.itemKind.values)):
|
|
itemSlot = kind.getItemSlot(slot, i)
|
|
itemKind = itemSlot.getKind()
|
|
itemWidget = itemSlot.getWidget()
|
|
layout += X.li(
|
|
X.input(type = 'checkbox', name = kind.itemKind.values[i]),
|
|
itemWidget.labels[kind.itemKind.values[i]])
|
|
return layout
|
|
register(MultiCheck)
|
|
|
|
|
|
class Path(WidgetMixin, proxyWidgets.Path):
|
|
def getHtmlViewValue(self, slot, fields, **keywords):
|
|
fieldValue = slot.getField(fields, default = '')
|
|
return X.a(href = X.idUrl(object.id).add('path', fieldValue))(
|
|
fieldValue)
|
|
|
|
def getHtmlFormValue(self, slot, fields, **keywords):
|
|
fieldName = slot.getFieldName()
|
|
fieldValue = slot.getField(fields, default = '')
|
|
|
|
layout = X.array()
|
|
layout += self.getModelErrorLayout(slot, fields)
|
|
layout += self.getModelHelpLayout(slot, fields)
|
|
layout += X.input(
|
|
maxlength = 80, name = fieldName, size = 80,
|
|
type = 'text', value = fieldValue)
|
|
return layout
|
|
register(Path)
|
|
|
|
|
|
class PushButton(WidgetMixin, proxyWidgets.PushButton):
|
|
def getHtmlViewValue(self, slot, fields, **keywords):
|
|
label = self.getModelLabel(slot)
|
|
return X.span(_class = 'button')(_(label))
|
|
|
|
def getHtmlReadOnlyValue(self, slot, fields, **keywords):
|
|
return self.getHtmlViewValue(slot, fields, **keywords)
|
|
|
|
def getHtmlFormValue(self, slot, fields, **keywords):
|
|
label = self.getModelLabel(slot)
|
|
layout = X.array()
|
|
layout += self.getModelErrorLayout(slot, fields)
|
|
layout += self.getModelHelpLayout(slot, fields)
|
|
fieldName = slot.getFieldName()
|
|
layout += X.buttonInForm(_(label), fieldName)
|
|
return layout
|
|
register(PushButton)
|
|
|
|
|
|
class Select(WidgetMixin, proxyWidgets.Select):
|
|
def getHtmlViewValue(self, slot, fields, **keywords):
|
|
kind = slot.getKind()
|
|
value = kind.getModelValueFromFields(slot, fields)
|
|
valueAsString = kind.getModelValueAsString(value)
|
|
labels = self.getLabels(slot, fields)
|
|
if labels.has_key(valueAsString):
|
|
return self.makeModelTitleFromValue(slot, fields, value)
|
|
elif value == '__all__':
|
|
return _(self.allLabel)
|
|
else:
|
|
return _(self.noneLabel)
|
|
|
|
def getHtmlFormValue(self, slot, fields, **keywords):
|
|
fieldName = slot.getFieldName()
|
|
kind = slot.getKind()
|
|
value = kind.getModelValueFromFields(slot, fields)
|
|
valueAsString = kind.getModelValueAsString(value)
|
|
|
|
if hasattr(kind, 'sortLabels') and kind.sortLabels:
|
|
values = kind.getSortedValues(slot, fields)
|
|
else:
|
|
values = kind.getValues(slot, fields)
|
|
if values is None:
|
|
raise Exception('Kind "%s" of slot "%s" has no values' % (
|
|
kind, slot))
|
|
labels = self.getLabels(slot, fields)
|
|
|
|
layout = X.array()
|
|
layout += self.getModelErrorLayout(slot, fields)
|
|
|
|
selectAttributes = {}
|
|
selectAttributes['name'] = fieldName
|
|
select = X.select(**selectAttributes)
|
|
itemsCount = len(values)
|
|
if not value in values:
|
|
if labels.has_key(valueAsString):
|
|
noneLabel = _(labels[valueAsString])
|
|
else:
|
|
noneLabel = _(self.noneLabel)
|
|
select += X.option(selected = 'selected', value = '')(noneLabel)
|
|
itemsCount += 1
|
|
if itemsCount == 1:
|
|
# The menu has only one item. Replace it by a read-only value.
|
|
layout += self.getHtmlReadOnlyValue(slot, fields, **keywords)
|
|
return layout
|
|
|
|
layout += self.getModelHelpLayout(slot, fields)
|
|
groupNames = None
|
|
if hasattr(kind, 'getGroupedValues'):
|
|
groupNames, groupedValues = kind.getGroupedValues(slot, fields)
|
|
if groupNames is not None:
|
|
for groupName in groupNames:
|
|
groupValues = groupedValues[groupName]
|
|
optgroup = X.optgroup(label = _(groupName))
|
|
select += optgroup
|
|
for itemValue in groupValues:
|
|
optionAttributes = {}
|
|
itemValueAsString = kind.getModelValueAsString(itemValue)
|
|
if itemValue == value:
|
|
optionAttributes['selected'] = 'selected'
|
|
if labels.has_key(itemValueAsString):
|
|
label = _(labels[itemValueAsString])
|
|
elif itemValue == '__all__':
|
|
label = _(self.allLabel)
|
|
elif itemValueAsString:
|
|
label = _(itemValueAsString)
|
|
else:
|
|
label = _(self.noneLabel)
|
|
optgroup += X.option(value = itemValueAsString,
|
|
**optionAttributes)(label)
|
|
else:
|
|
for itemValue in values:
|
|
optionAttributes = {}
|
|
itemValueAsString = kind.getModelValueAsString(itemValue)
|
|
if itemValue == value:
|
|
optionAttributes['selected'] = 'selected'
|
|
if labels.has_key(itemValueAsString):
|
|
label = _(labels[itemValueAsString])
|
|
elif itemValue == '__all__':
|
|
label = _(self.allLabel)
|
|
elif itemValueAsString:
|
|
label = _(itemValueAsString)
|
|
else:
|
|
label = _(self.noneLabel)
|
|
select += X.option(value = itemValueAsString,
|
|
**optionAttributes)(label)
|
|
layout += select
|
|
if self.apply:
|
|
layout += ' '
|
|
layout += X.buttonInForm('apply', 'applyButton')
|
|
return layout
|
|
|
|
def makeModelTitleFromValue(self, slot, fields, value):
|
|
kind = slot.getKind()
|
|
valueAsString = kind.getModelValueAsString(value)
|
|
layoutMode = context.getVar('layoutMode')
|
|
if layoutMode != 'edit':
|
|
if self.titles and self.titles.has_key(valueAsString):
|
|
return _(self.titles[valueAsString])
|
|
title = kind.makeModelTitleFromValue(slot, fields, value)
|
|
if title:
|
|
return title
|
|
labels = self.getLabels(slot, fields)
|
|
if labels and labels.has_key(valueAsString):
|
|
return _(labels[valueAsString])
|
|
return None
|
|
register(Select)
|
|
|
|
|
|
class SelectId(WidgetMixin, proxyWidgets.SelectId):
|
|
def getHtmlViewValue(self, slot, fields, **keywords):
|
|
fieldValue = slot.getField(fields, default = '')
|
|
if fieldValue:
|
|
return X.objectHypertextLabel(fieldValue)
|
|
else:
|
|
return _(self.noneLabel)
|
|
|
|
def getHtmlFormValue(self, slot, fields, **keywords):
|
|
fieldName = slot.getFieldName()
|
|
fieldValue = slot.getField(fields, default = '')
|
|
|
|
layout = X.array()
|
|
layout += self.getModelErrorLayout(slot, fields)
|
|
layout += self.getModelHelpLayout(slot, fields)
|
|
kind = slot.getKind()
|
|
serverRoles = kind.getServerRoles()
|
|
if not serverRoles:
|
|
serverRoles = context.getVar('knownRoles')
|
|
serverRoles = serverRoles[:]
|
|
serverRoles.sort()
|
|
menus = {}
|
|
|
|
showOthersButton = self.showOthersButton
|
|
|
|
if kind.valuesGetterName:
|
|
values = kind.getValues(slot, fields)
|
|
for serverRole in serverRoles:
|
|
ids = [x for x in values if splitObjectId(x)[1] == serverRole]
|
|
if not ids:
|
|
continue
|
|
menus[serverRole] = getObjectLabelsTranslated(
|
|
ids, context.getVar('readLanguages'))
|
|
showOthersButton = 0
|
|
|
|
if not menus:
|
|
virtualHost = context.getVar('virtualHost')
|
|
showFullList = webTools.getConfig(
|
|
'ShowFullListInSelectIdForServerRoles', default = '')
|
|
showFullList = [x.strip() for x in showFullList.split(',')]
|
|
showFullList.sort()
|
|
if serverRoles == showFullList:
|
|
showOthersButton = 0
|
|
for serverRole in serverRoles:
|
|
if not serverRole:
|
|
continue
|
|
if not serverRole in showFullList:
|
|
continue
|
|
proxy = getProxyForServerRole(serverRole)
|
|
objectIds = proxy.getObjectIds()
|
|
if serverRole == 'groups':
|
|
acceptedObjectIds = []
|
|
for objectId in objectIds:
|
|
accepted = 0
|
|
if not proxy.canGetObject(objectId):
|
|
objectIds.remove(objectId)
|
|
continue
|
|
object = proxy.getObject(objectId)
|
|
objectAcceptedRoles = object.getSlot(
|
|
'acceptedRoles').getValue()
|
|
if not objectAcceptedRoles:
|
|
accepted = 1
|
|
else:
|
|
for remainingRole in serverRoles:
|
|
if remainingRole == 'groups':
|
|
continue
|
|
if remainingRole in objectAcceptedRoles:
|
|
accepted = 1
|
|
if accepted:
|
|
acceptedObjectIds.append(objectId)
|
|
objectIds = acceptedObjectIds
|
|
menus[serverRole] = getObjectLabelsTranslated(
|
|
objectIds, context.getVar('readLanguages'))
|
|
preferences = context.getVar('preferences')
|
|
if preferences:
|
|
objectsMemory = preferences.objectsMemory
|
|
if objectsMemory is not None:
|
|
for serverRole in serverRoles:
|
|
if not objectsMemory.has_key(serverRole):
|
|
continue
|
|
serverMemory = objectsMemory[serverRole]
|
|
if not serverMemory:
|
|
continue
|
|
if menus.has_key(serverRole):
|
|
continue
|
|
menus[serverRole] = getObjectLabelsTranslated(
|
|
serverMemory,
|
|
context.getVar('readLanguages'))
|
|
selectAttributes = {}
|
|
selectAttributes['name'] = fieldName
|
|
select = X.select(**selectAttributes)
|
|
|
|
optionAttributes = {}
|
|
if not fieldValue:
|
|
optionAttributes['selected'] = 'selected'
|
|
select += X.option(value = '', **optionAttributes)(_(self.noneLabel))
|
|
|
|
if fieldValue:
|
|
objectId = fieldValue
|
|
try:
|
|
objectLabel = getObjectLabelTranslated(objectId,
|
|
context.getVar('readLanguages'))
|
|
except: # TODO: tighter check
|
|
pass
|
|
else:
|
|
select += X.option(selected = 'selected',
|
|
value = objectId)(objectLabel)
|
|
|
|
permanentIds = kind.permanentIds
|
|
if permanentIds:
|
|
for permanentId in permanentIds:
|
|
if permanentId == fieldValue:
|
|
continue
|
|
try:
|
|
permanentLabel = getObjectLabelTranslated(permanentId,
|
|
context.getVar('readLanguages'))
|
|
except: # TODO: tighter check
|
|
pass
|
|
else:
|
|
select += X.option(value = permanentId)(permanentLabel)
|
|
|
|
usedServerRoles = []
|
|
serverRoleLocalizedLabels = {}
|
|
for serverRole in serverRoles:
|
|
web = getWebForServerRole(serverRole)
|
|
if not web:
|
|
continue
|
|
if not menus.has_key(serverRole):
|
|
continue
|
|
menu = menus[serverRole]
|
|
if not menu or len(menu) == 1 and menu.has_key(fieldValue):
|
|
continue
|
|
usedServerRoles.append(serverRole)
|
|
serverRoleLocalizedLabels[serverRole] = _(
|
|
web.objectsNameCapitalized)
|
|
usedServerRoles.sort(
|
|
lambda x, y:
|
|
locale.strcoll(serverRoleLocalizedLabels[x],
|
|
serverRoleLocalizedLabels[y]))
|
|
for serverRole in usedServerRoles:
|
|
menu = menus[serverRole]
|
|
if len(menus) > 1:
|
|
optgroup = X.optgroup(
|
|
label = serverRoleLocalizedLabels[serverRole])
|
|
select += optgroup
|
|
else:
|
|
optgroup = select
|
|
menuItems = menu.items()
|
|
menuItems.sort(lambda x,y:
|
|
locale.strcoll(x[1].lower(), y[1].lower()))
|
|
for objectId, objectLabel in menuItems:
|
|
if objectId == fieldValue:
|
|
continue
|
|
if len(objectLabel) > 80:
|
|
objectLabel = objectLabel[
|
|
: 70 + objectLabel[70:].find(' ')] + ' (...)'
|
|
optgroup += X.option(value = objectId)(objectLabel)
|
|
layout += select
|
|
if showOthersButton:
|
|
roles = ','.join([
|
|
x
|
|
for x in serverRoles
|
|
if getWebForServerRole(x)
|
|
and hasattr(getWebForServerRole(x),
|
|
'objectsNameCapitalized')])
|
|
url = X.url('/selectOthers').add('roles', roles)
|
|
layout += X.input(
|
|
_class = 'button others', type = 'button',
|
|
onClick = 'selectOthers(this.parentNode, "%s")' % url,
|
|
value = _('Others'))
|
|
return layout
|
|
register(SelectId)
|
|
|
|
|
|
class TextArea(WidgetMixin, proxyWidgets.TextArea):
|
|
def getHtmlViewValue(self, slot, fields, **keywords):
|
|
fieldValue, translationBar = \
|
|
translation.getFieldValueAndTranslationBar(slot, fields)
|
|
if self.viewInTextArea:
|
|
textareaAttributes = self.getTextAreaAttributes()
|
|
layout = X.textarea(readonly = 'readonly',
|
|
**textareaAttributes)(fieldValue)
|
|
else:
|
|
virtualHost = context.getVar('virtualHost')
|
|
sectionLevel = 2
|
|
if virtualHost:
|
|
sectionLevel = int(webTools.getConfig('BaseSectionLevel', '2'))
|
|
format = slot.getKind().textFormat
|
|
inline = context.getVar('inline', default = 0)
|
|
if format == 'docbook':
|
|
formattedText = parsers.makeHtmlFromDocBook(
|
|
fieldValue, inline = inline)
|
|
elif format == 'html':
|
|
formattedText = parsers.makeHtmlFromHtml(
|
|
fieldValue, inline = inline)
|
|
elif format == 'text':
|
|
formattedText = parsers.makeHtmlFromPreformattedText(
|
|
fieldValue, inline = inline)
|
|
elif format == 'rst':
|
|
formattedText = parsers.makeHtmlFromReStructuredText(
|
|
fieldValue, inline = inline,
|
|
sectionLevel = sectionLevel)
|
|
elif format == 'spip':
|
|
formattedText = parsers.makeHtmlFromSpip(
|
|
fieldValue, inline = inline,
|
|
sectionLevel = sectionLevel)
|
|
else:
|
|
formattedText = parsers.makeHtmlFromUnformattedText(
|
|
fieldValue, inline = inline)
|
|
formattedText = replaceSpecialTags(formattedText)
|
|
layout = X.asIs(formattedText)
|
|
|
|
if translationBar:
|
|
layout = X.array(layout, translationBar)
|
|
|
|
return layout
|
|
|
|
def getHtmlReadOnlyValue(self, slot, fields, **keywords):
|
|
fieldValue = slot.getField(fields, default = '')
|
|
layout = X.array(self.getModelHiddenLayout(slot, fields))
|
|
if self.viewInTextArea:
|
|
textareaAttributes = self.getTextAreaAttributes()
|
|
layout += X.textarea(readonly = 'readonly',
|
|
**textareaAttributes)(fieldValue)
|
|
return layout
|
|
else:
|
|
virtualHost = context.getVar('virtualHost')
|
|
sectionLevel = 2
|
|
if virtualHost:
|
|
sectionLevel = int(webTools.getConfig('BaseSectionLevel', '2'))
|
|
format = slot.getKind().textFormat
|
|
inline = context.getVar('inline', default = 0)
|
|
if format == 'docbook':
|
|
formattedText = parsers.makeHtmlFromDocBook(
|
|
fieldValue, inline = inline)
|
|
elif format == 'html':
|
|
formattedText = parsers.makeHtmlFromHtml(
|
|
fieldValue, inline = inline)
|
|
elif format == 'text':
|
|
formattedText = parsers.makeHtmlFromPreformattedText(
|
|
fieldValue, inline = inline)
|
|
elif format == 'rst':
|
|
formattedText = parsers.makeHtmlFromReStructuredText(
|
|
fieldValue, inline = inline,
|
|
sectionLevel = sectionLevel)
|
|
elif format == 'spip':
|
|
formattedText = parsers.makeHtmlFromSpip(
|
|
fieldValue, inline = inline,
|
|
sectionLevel = sectionLevel)
|
|
else:
|
|
formattedText = parsers.makeHtmlFromUnformattedText(
|
|
fieldValue, inline = inline)
|
|
formattedText = replaceSpecialTags(formattedText)
|
|
layout = X.asIs(formattedText)
|
|
return layout
|
|
|
|
def getTextAreaAttributes(self):
|
|
textareaAttributes = {}
|
|
if self.cols:
|
|
textareaAttributes['cols'] = self.cols
|
|
else:
|
|
textareaAttributes['cols'] = 80
|
|
if self.rows:
|
|
textareaAttributes['rows'] = self.rows
|
|
else:
|
|
textareaAttributes['rows'] = 10
|
|
return textareaAttributes
|
|
|
|
def getHtmlFormValue(self, slot, fields, **keywords):
|
|
fieldName = slot.getFieldName()
|
|
fieldValue = slot.getField(fields, default = '')
|
|
|
|
textareaAttributes = self.getTextAreaAttributes()
|
|
|
|
layout = X.array()
|
|
layout += self.getModelErrorLayout(slot, fields)
|
|
layout += self.getModelHelpLayout(slot, fields)
|
|
layout += X.textarea(
|
|
name = fieldName, **textareaAttributes)(fieldValue)
|
|
|
|
if self.preview or self.apply:
|
|
buttonsBar = X.div(_class = 'field-value-buttons-bar')
|
|
layout += buttonsBar
|
|
if self.preview:
|
|
buttonsBar += X.buttonInForm('preview', 'applyButton')
|
|
if self.apply:
|
|
buttonsBar += X.buttonInForm('apply', 'applyButton')
|
|
|
|
if self.preview and fieldValue:
|
|
format = slot.getKind().textFormat
|
|
if format == 'docbook':
|
|
formattedText = parsers.makeHtmlFromDocBook(fieldValue)
|
|
elif format == 'html':
|
|
formattedText = parsers.makeHtmlFromHtml(fieldValue)
|
|
elif format == 'text':
|
|
formattedText = parsers.makeHtmlFromPreformattedText(
|
|
fieldValue)
|
|
elif format == 'rst':
|
|
formattedText = parsers.makeHtmlFromReStructuredText(
|
|
fieldValue)
|
|
elif format == 'spip':
|
|
formattedText = parsers.makeHtmlFromSpip(fieldValue)
|
|
else:
|
|
formattedText = parsers.makeHtmlFromUnformattedText(
|
|
fieldValue)
|
|
formattedText = replaceSpecialTags(formattedText)
|
|
preferences = context.getVar('preferences')
|
|
if (not preferences or preferences.spellcheckEntries) and \
|
|
fields.has_key('language'):
|
|
formattedText = spellcheck(formattedText, fields['language'])
|
|
if formattedText:
|
|
layout += X.div(_class = 'preview')(X.asIs(formattedText))
|
|
|
|
return layout
|
|
register(TextArea)
|
|
|
|
|
|
class Thing(ThingMixin, proxyWidgets.Thing):
|
|
pass
|
|
register(Thing)
|
|
|
|
|
|
class Time(TimeMixin, proxyWidgets.Time):
|
|
def getHtmlValue(self, slot, fields, **keywords):
|
|
layout = TimeMixin.getHtmlValue(self, slot, fields, **keywords)
|
|
if not self.isInForm() or self.isReadOnly(slot):
|
|
return layout
|
|
#layout += X.input(
|
|
# _class = 'button', type = 'button', value = _('Calendar'),
|
|
# onClick = "this.previousSibling.id = 'editedTime'; " \
|
|
# "window.open('%s', 'cal'," \
|
|
# "'dependent=yes,width=180,height=180," \
|
|
# "screenX=200,screenY=300,titlebar=no'); " \
|
|
# "return false" % X.roleUrl('calendarPopup').getAsUrl())
|
|
return layout
|
|
register(Time)
|
|
|
|
|
|
class Token(WidgetMixin, proxyWidgets.Token):
|
|
pass
|
|
register(Token)
|
|
|
|
|
|
class UploadFile(WidgetMixin, proxyWidgets.UploadFile):
|
|
def getHtmlViewValue(self, slot, fields, **keywords):
|
|
object = slot.getObject()
|
|
if object.id is None:
|
|
return ''
|
|
|
|
addedToUrl = ''
|
|
if self.fileName:
|
|
addedToUrl = '/%s' % urllib.quote(self.fileName)
|
|
|
|
typeSlot = slot.getContainer().getSlot(
|
|
slot.name + 'Type', parentSlot = slot.parent)
|
|
|
|
if isTypeOfMimeType(typeSlot.getField(fields, default = ''), 'image'):
|
|
uri = X.idUrl(object.id, 'thumbnail')
|
|
if slot.parent is not None:
|
|
uri.add('path', slot.parent.getPath())
|
|
uri.add('width', 256)
|
|
uri.add('height', 256)
|
|
image = X.img(src = uri)
|
|
uri = X.idUrl(object.id, 'image%s' % addedToUrl)
|
|
if slot.parent is not None \
|
|
and slot.parent.getPath() != 'self':
|
|
uri.add('path', slot.parent.getPath())
|
|
return X.a(_class = 'image', href = uri)(image)
|
|
elif slot.getValue():
|
|
uri = X.idUrl(object.id, 'download')
|
|
if slot.parent is not None:
|
|
uri.add('path', slot.parent.getPath())
|
|
return X.a(href = uri)(_('download'))
|
|
return ''
|
|
|
|
def getHtmlReadOnlyValue(self, slot, fields, **keywords):
|
|
fieldName = slot.getFieldName()
|
|
fieldValue = slot.getField(fields, default = '')
|
|
|
|
session = context.getVar('session')
|
|
session['field_' + fieldName] = base64.encodestring(fieldValue)
|
|
session['isDirty'] = 1
|
|
return X.array(
|
|
self.getModelHiddenLayout(slot, fields),
|
|
self.getRepresentation(slot, fields, **keywords) )
|
|
|
|
def getHtmlFormValue(self, slot, fields, **keywords):
|
|
fieldName = slot.getFieldName()
|
|
fieldValue = slot.getField(fields, default = '')
|
|
|
|
layout = X.array()
|
|
layout += self.getModelErrorLayout(slot, fields)
|
|
layout += self.getModelHelpLayout(slot, fields)
|
|
session = context.getVar('session')
|
|
session['field_' + fieldName] = base64.encodestring(fieldValue)
|
|
session['isDirty'] = 1
|
|
layout += X.input(name = '%s|session' % fieldName,
|
|
type = 'hidden', value = 1)
|
|
representation = self.getRepresentation(slot, fields, **keywords)
|
|
if representation:
|
|
layout += representation
|
|
layout += X.br()
|
|
layout += X.input(name = '%s_field' % fieldName, type = 'file')
|
|
return layout
|
|
|
|
def getRepresentation(self, slot, fields, **keywords):
|
|
typeSlot = slot.getContainer().getSlot(
|
|
slot.name + 'Type', parentSlot = slot.parent)
|
|
|
|
if not isTypeOfMimeType(
|
|
typeSlot.getField(fields, default = ''), 'image'):
|
|
return ''
|
|
|
|
typeSlot = slot.getContainer().getSlot(
|
|
slot.name + 'Type', parentSlot = slot.parent)
|
|
object = slot.getObject()
|
|
|
|
fieldName = slot.getFieldName()
|
|
uri = X.idUrl(object.id, 'imageEdit')
|
|
if slot.parent is not None:
|
|
uri.add('path', slot.parent.getPath())
|
|
uri.add('%s|session' % fieldName, 1)
|
|
uri.addKeywords(keywords)
|
|
return X.img(src = uri)
|
|
register(UploadFile)
|
|
|
|
|
|
class Url(WidgetMixin, proxyWidgets.Url):
|
|
def getHtmlViewValue(self, slot, fields, **keywords):
|
|
fieldValue = slot.getField(fields, default = '')
|
|
if fieldValue:
|
|
if fieldValue.startswith('http://'):
|
|
href = fieldValue
|
|
else:
|
|
href = 'http://%s' % fieldValue
|
|
return X.a(href = href)(fieldValue)
|
|
else:
|
|
return X.nbsp
|
|
|
|
def getHtmlFormValue(self, slot, fields, **keywords):
|
|
fieldName = slot.getFieldName()
|
|
fieldValue = str(slot.getField(fields, default = ''))
|
|
|
|
layout = X.array()
|
|
layout += self.getModelErrorLayout(slot, fields)
|
|
layout += self.getModelHelpLayout(slot, fields)
|
|
|
|
inputAttributes = {}
|
|
maxLength = slot.getKind().getTextMaxLength()
|
|
if maxLength is not None:
|
|
inputAttributes['maxlength'] = maxLength
|
|
if self.size is not None:
|
|
size = self.size
|
|
elif maxLength is not None:
|
|
size = min(80, maxLength)
|
|
else:
|
|
size = None
|
|
if size is not None:
|
|
inputAttributes['size'] = size
|
|
layout += X.input(name = fieldName, type = 'text',
|
|
value = fieldValue, **inputAttributes)
|
|
if self.apply:
|
|
layout += ' '
|
|
layout += X.buttonInForm('apply', 'applyButton')
|
|
return layout
|
|
|
|
def getModelHiddenLayout(self, slot, fields):
|
|
fieldName = slot.getFieldName()
|
|
fieldValue = slot.getField(fields, default = '')
|
|
|
|
return X.array(
|
|
X.input(name = fieldName, type = 'hidden',
|
|
value = fieldValue),
|
|
)
|
|
register(Url)
|
|
|
|
|
|
class XSelect(Select, proxyWidgets.XSelect):
|
|
otherFieldLabel_defaultValue = N_('other:')
|
|
otherFieldLabel_kind_widget_fieldLabel = N_('Label')
|
|
|
|
def getHtmlValue(self, slot, fields, **keywords):
|
|
fieldName = slot.getFieldName()
|
|
fieldValue = slot.getField(fields, default = '')
|
|
if fieldValue is None:
|
|
fieldValue = ''
|
|
else:
|
|
fieldValue = str(fieldValue)
|
|
otherFieldLabel = self.otherFieldLabel or \
|
|
self.otherFieldLabel_defaultValue
|
|
otherFieldValue = slot.getFieldOption(fields, 'other', default = '')
|
|
kind = slot.getKind()
|
|
if kind.sortLabels:
|
|
values = kind.getSortedValues(slot, fields)
|
|
else:
|
|
values = kind.getValues(slot, fields)
|
|
groupNames, groupedValues = kind.getGroupedValues(slot, fields)
|
|
if values is None:
|
|
raise Exception('Kind "%s" of slot "%s" has no values' % (
|
|
kind, slot))
|
|
if not fieldValue in values and (fieldValue or None not in values):
|
|
fieldValue = kind.defaultValue
|
|
if fieldValue is None:
|
|
fieldValue = ''
|
|
else:
|
|
fieldValue = str(fieldValue)
|
|
labels = self.getLabels(slot, fields)
|
|
|
|
if not self.isInForm():
|
|
if labels.has_key(str(fieldValue)):
|
|
layout = self.makeModelTitleFromValue(slot, fields, fieldValue)
|
|
elif fieldValue == '__all__':
|
|
layout = _(self.allLabel)
|
|
elif otherFieldValue:
|
|
layout = X.asIs(_(str(otherFieldValue)))
|
|
else:
|
|
layout = None
|
|
elif self.isReadOnly(slot):
|
|
layout = X.array(
|
|
self.getModelHiddenLayout(slot, fields),
|
|
)
|
|
if labels.has_key(str(fieldValue)):
|
|
displayFieldValue = self.makeModelTitleFromValue(
|
|
slot, fields, fieldValue)
|
|
else:
|
|
displayFieldValue = _(str(fieldValue))
|
|
layout += displayFieldValue
|
|
else:
|
|
layout = X.array()
|
|
layout += self.getModelErrorLayout(slot, fields)
|
|
layout += self.getModelHelpLayout(slot, fields)
|
|
table = X.table(_class = 'field-value', id = '')
|
|
layout += table
|
|
selectAttributes = {}
|
|
selectAttributes['name'] = fieldName
|
|
select = X.select(**selectAttributes)
|
|
if not fieldValue in values and (fieldValue or None not in values):
|
|
if labels.has_key(fieldValue):
|
|
noneLabel = _(labels[fieldValue])
|
|
else:
|
|
noneLabel = _(self.noneLabel)
|
|
select += X.option(selected = 'selected', value = '')(
|
|
noneLabel)
|
|
groupNames = None
|
|
if hasattr(kind, 'getGroupedValues'):
|
|
groupNames, groupedValues = kind.getGroupedValues(slot, fields)
|
|
if groupNames is not None:
|
|
for groupName in groupNames:
|
|
groupValues = groupedValues[groupName]
|
|
optgroup = X.optgroup(label = _(groupName))
|
|
select += optgroup
|
|
for value in groupValues:
|
|
optionAttributes = {}
|
|
if value is None:
|
|
value = ''
|
|
valueAsString = str(value)
|
|
if valueAsString == fieldValue:
|
|
optionAttributes['selected'] = 'selected'
|
|
if labels.has_key(valueAsString):
|
|
label = _(labels[valueAsString])
|
|
elif not value:
|
|
label = _(self.noneLabel)
|
|
elif value == '__all__':
|
|
label = _(self.allLabel)
|
|
else:
|
|
label = _(value)
|
|
optgroup += X.option(
|
|
value = value, **optionAttributes)(label)
|
|
else:
|
|
for value in values:
|
|
optionAttributes = {}
|
|
if value is None:
|
|
value = ''
|
|
valueAsString = str(value)
|
|
if valueAsString == fieldValue:
|
|
optionAttributes['selected'] = 'selected'
|
|
if labels.has_key(valueAsString):
|
|
label = _(labels[valueAsString])
|
|
elif not value:
|
|
label = _(self.noneLabel)
|
|
elif value == '__all__':
|
|
label = _(self.allLabel)
|
|
else:
|
|
label = _(value)
|
|
select += X.option(value = value, **optionAttributes)(
|
|
label)
|
|
table += X.tr(
|
|
_class = 'field-value', id = 'tooltip-%s' % fieldName)(
|
|
X.td(_class = 'field-value', colspan="2")(select))
|
|
inputAttributes = {}
|
|
maxLength = slot.getKind().getTextMaxLength()
|
|
if maxLength is not None:
|
|
inputAttributes['maxlength'] = maxLength
|
|
if self.size is not None:
|
|
size = self.size
|
|
elif maxLength is not None:
|
|
size = min(80, maxLength)
|
|
else:
|
|
size = None
|
|
if size is not None:
|
|
inputAttributes['size'] = size
|
|
table += X.tr(_class = 'field-value')(
|
|
X.td(_class = 'field-label')(X.asIs(_(otherFieldLabel))),
|
|
X.td(_class = 'field-value')(
|
|
X.input(
|
|
name = '%s_other' % fieldName, type = 'text',
|
|
value = otherFieldValue, **inputAttributes)))
|
|
if self.apply:
|
|
layout += ' '
|
|
layout += X.buttonInForm('apply', 'applyButton')
|
|
return layout
|
|
|
|
def getModelHiddenLayout(self, slot, fields):
|
|
fieldName = slot.getFieldName()
|
|
otherFieldName = slot.getFieldOptionName('other')
|
|
fieldValue = slot.getField(fields, default = '')
|
|
otherFieldValue = slot.getFieldOption(fields, 'other', default = '')
|
|
if otherFieldValue:
|
|
return X.input(name = otherFieldName, type = 'hidden',
|
|
value = otherFieldValue)
|
|
return X.input(name = fieldName, type = 'hidden', value = fieldValue)
|
|
|
|
def makeModelTitleFromValue(self, slot, fields, value):
|
|
if value is None:
|
|
valueAsString = ''
|
|
else:
|
|
valueAsString = str(value)
|
|
layoutMode = context.getVar('layoutMode')
|
|
if layoutMode != 'edit':
|
|
if self.titles and self.titles.has_key(valueAsString):
|
|
return _(self.titles[valueAsString])
|
|
kind = slot.getKind()
|
|
title = kind.makeModelTitleFromValue(slot, fields, value)
|
|
if title:
|
|
return title
|
|
labels = self.getLabels(slot, fields)
|
|
if labels and labels.has_key(valueAsString):
|
|
return _(labels[valueAsString])
|
|
return valueAsString
|
|
register(XSelect)
|
|
|