1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 """Defines a component for showing non-editable short texts."""
17
18 try:
19 from cStringIO import StringIO
20 except ImportError, e:
21 from StringIO import StringIO
22
23 from muntjac.data.util.object_property import ObjectProperty
24 from muntjac.ui.abstract_component import AbstractComponent
25 from muntjac.ui.component import Event as ComponentEvent
26
27 from muntjac.data import property as prop
28
29
30 _VALUE_CHANGE_METHOD = getattr(prop.IValueChangeListener, "valueChange")
31
32
33 -class Label(AbstractComponent, prop.IProperty, prop.IViewer,
34 prop.IValueChangeListener, prop.IValueChangeNotifier):
35 """Label component for showing non-editable short texts.
36
37 The label content can be set to the modes specified by the final members
38 CONTENT_*
39
40 The contents of the label may contain simple formatting:
41
42 - B{<b>} Bold
43 - B{<i>} Italic
44 - B{<u>} Underlined
45 - B{<br/>} Linebreak
46 - B{<ul><li>item 1</li><li>item 2</li></ul>} List of items
47
48 The B{b},B{i},B{u} and B{li} tags can contain all the tags
49 in the list recursively.
50
51 @author: Vaadin Ltd.
52 @author: Richard Lincoln
53 @version: 1.1.2
54 """
55
56 CLIENT_WIDGET = None
57
58
59
60 CONTENT_TEXT = 0
61
62
63 CONTENT_PREFORMATTED = 1
64
65
66
67
68
69 CONTENT_UIDL = 2
70
71
72
73
74 CONTENT_XHTML = 3
75
76
77
78 CONTENT_XML = 4
79
80
81
82
83
84
85 CONTENT_RAW = 5
86
87
88 CONTENT_DEFAULT = CONTENT_TEXT
89
90
91 _CONTENT_MODE_NAME = ['text', 'pre', 'uidl', 'xhtml', 'xml', 'raw']
92
93 _DATASOURCE_MUST_BE_SET = 'Datasource must be set'
94
95
96 - def __init__(self, contentSource="", contentMode=None):
117
118
120 """Set the component to read-only. Readonly is not used in label.
121
122 @param readOnly:
123 True to enable read-only mode, False to disable it.
124 """
125 if self._dataSource is None:
126 raise ValueError, self._DATASOURCE_MUST_BE_SET
127 self._dataSource.setReadOnly(readOnly)
128
129
131 """Is the component read-only ? Readonly is not used in label - this
132 returns always false.
133
134 @return: C{True} if the component is in read only mode.
135 """
136 if self._dataSource is None:
137 raise ValueError, self._DATASOURCE_MUST_BE_SET
138 return self._dataSource.isReadOnly()
139
140
141 - def paintContent(self, target):
142 """Paints the content of this component.
143
144 @param target:
145 the Paint Event.
146 @raise PaintException:
147 if the Paint Operation fails.
148 """
149 if self._contentMode != self.CONTENT_TEXT:
150 target.addAttribute('mode',
151 self._CONTENT_MODE_NAME[self._contentMode])
152
153 if self._contentMode == self.CONTENT_TEXT:
154 target.addText(str(self))
155
156 elif self._contentMode == self.CONTENT_UIDL:
157 target.addUIDL(str(self))
158
159 elif self._contentMode == self.CONTENT_XHTML:
160 target.startTag('data')
161 target.addXMLSection('div', str(self),
162 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd')
163 target.endTag('data')
164
165 elif self._contentMode == self.CONTENT_PREFORMATTED:
166 target.startTag('pre')
167 target.addText(str(self))
168 target.endTag('pre')
169
170 elif self._contentMode == self.CONTENT_XML:
171 target.addXMLSection('data', str(self), None)
172
173 elif self._contentMode == self.CONTENT_RAW:
174 target.startTag('data')
175 target.addAttribute('escape', False)
176 target.addText(str(self))
177 target.endTag('data')
178
179
181 """Gets the value of the label. Value of the label is the XML
182 contents of the label.
183
184 @return: the Value of the label.
185 """
186 if self._dataSource is None:
187 raise ValueError, self._DATASOURCE_MUST_BE_SET
188 return self._dataSource.getValue()
189
190
192 """Set the value of the label. Value of the label is the XML
193 contents of the label.
194
195 @param newValue:
196 the New value of the label.
197 """
198 if self._dataSource is None:
199 raise ValueError, self._DATASOURCE_MUST_BE_SET
200 self._dataSource.setValue(newValue)
201
202
204 if self._dataSource is None:
205 raise ValueError, self._DATASOURCE_MUST_BE_SET
206 return str(self._dataSource)
207
208
210 """Gets the type of the IProperty.
211
212 @see: L{IProperty.getType}
213 """
214 if self._dataSource is None:
215 raise ValueError, self._DATASOURCE_MUST_BE_SET
216 return self._dataSource.getType()
217
218
220 """Gets the viewing data-source property.
221
222 @return: the data source property.
223 @see: L{IViewer.getPropertyDataSource}
224 """
225 return self._dataSource
226
227
229 """Sets the property as data-source for viewing.
230
231 @param newDataSource:
232 the new data source IProperty
233 @see: L{IViewer.setPropertyDataSource}
234 """
235
236 if (self._dataSource is not None
237 and issubclass(self._dataSource.__class__,
238 prop.IValueChangeNotifier)):
239 self._dataSource.removeListener(self, prop.IValueChangeListener)
240
241
242 self._dataSource = newDataSource
243
244
245 if (self._dataSource is not None
246 and issubclass(self._dataSource.__class__,
247 prop.IValueChangeNotifier)):
248 self._dataSource.addListener(self, prop.IValueChangeListener)
249
250 self.requestRepaint()
251
252
253 - def getContentMode(self):
254 """Gets the content mode of the Label.
255
256 Possible content modes include:
257
258 - B{CONTENT_TEXT} Content mode, where the label contains only plain
259 text. The getValue() result is coded to XML when painting.
260 - B{CONTENT_PREFORMATTED} Content mode, where the label contains
261 preformatted text.
262 - B{CONTENT_UIDL} Formatted content mode, where the contents is XML
263 restricted to the UIDL 1.0 formatting markups.
264 - B{CONTENT_XHTML} Content mode, where the label contains XHTML.
265 Contents is then enclosed in DIV elements having namespace of
266 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd".
267 - B{CONTENT_XML} Content mode, where the label contains well-formed
268 or well-balanced XML. Each of the root elements must have their
269 default namespace specified.
270 - B{CONTENT_RAW} Content mode, where the label contains RAW output.
271 Output is not required to comply to with XML. In Web Adapter output
272 is inserted inside the resulting HTML document as-is. This is
273 useful for some specific purposes where possibly broken HTML
274 content needs to be shown, but in most cases XHTML mode should be
275 preferred.
276
277 @return: the Content mode of the label.
278 """
279 return self._contentMode
280
281
282 - def setContentMode(self, contentMode):
283 """Sets the content mode of the Label.
284
285 Possible content modes include:
286
287 - B{CONTENT_TEXT} Content mode, where the label contains only plain
288 text. The getValue() result is coded to XML when painting.
289 - B{CONTENT_PREFORMATTED} Content mode, where the label contains
290 preformatted text.
291 - B{CONTENT_UIDL} Formatted content mode, where the contents is XML
292 restricted to the UIDL 1.0 formatting markups.
293 - B{CONTENT_XHTML} Content mode, where the label contains XHTML.
294 Contents is then enclosed in DIV elements having namespace of
295 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd".
296 - B{CONTENT_XML} Content mode, where the label contains well-formed
297 or well-balanced XML. Each of the root elements must have their
298 default namespace specified.
299 - B{CONTENT_RAW} Content mode, where the label contains RAW output.
300 Output is not required to comply to with XML. In Web Adapter output
301 is inserted inside the resulting HTML document as-is. This is
302 useful for some specific purposes where possibly broken HTML
303 content needs to be shown, but in most cases XHTML mode should be
304 preferred.
305
306 @param contentMode:
307 the New content mode of the label.
308 """
309
310 if (contentMode != self._contentMode
311 and contentMode >= self.CONTENT_TEXT
312 and contentMode <= self.CONTENT_RAW):
313 self._contentMode = contentMode
314 self.requestRepaint()
315
316
326
327
328 - def addCallback(self, callback, eventType=None, *args):
336
337
347
348
357
358
364
365
367 """Listens the value change events from data source."""
368 self.fireValueChange()
369
370
372 """Compares the Label to other objects.
373
374 Labels can be compared to other labels for sorting label contents.
375 This is especially handy for sorting table columns.
376
377 In RAW, PREFORMATTED and TEXT modes, the label contents are compared
378 as is. In XML, UIDL and XHTML modes, only CDATA is compared and tags
379 ignored. If the other object is not a Label, its toString() return
380 value is used in comparison.
381
382 @param other:
383 the Other object to compare to.
384 @return: a negative integer, zero, or a positive integer as this object
385 is less than, equal to, or greater than the specified object.
386 """
387 if (self._contentMode == self.CONTENT_XML
388 or self._contentMode == self.CONTENT_UIDL
389 or self._contentMode == self.CONTENT_XHTML):
390 thisValue = self.stripTags(str(self))
391 else:
392 thisValue = str(self)
393
394 if (isinstance(other, Label)
395 and (other.getContentMode() == self.CONTENT_XML
396 or other.getContentMode() == self.CONTENT_UIDL
397 or other.getContentMode() == self.CONTENT_XHTML)):
398 otherValue = self.stripTags(str(other))
399 else:
400 otherValue = str(other)
401
402 return cmp(thisValue, otherValue)
403
404
427
428
430 """Value change event."""
431
435
436
438 """Gets the IProperty that has been modified."""
439 return self.getSource()
440