1 '''
2 Defines classes for representing device capabilities and styles.
3
4 @author: Brett Clippingdale
5 @author: Peter Parente
6 @author: Scott Haeger
7 @organization: IBM Corporation
8 @copyright: Copyright (c) 2005, 2007 IBM Corporation
9 @license: The BSD License
10
11 All rights reserved. This program and the accompanying materials are made
12 available under the terms of the BSD license which accompanies
13 this distribution, and is available at
14 U{http://www.opensource.org/licenses/bsd-license.php}
15 '''
16 from i18n import _
17 from AEConstants import *
18 import Word, AEState
19
20 -class Style(AEState.AEState):
21 '''
22 Extends L{AEState} with new kinds of settings for devices.
23
24 Mute (bool): Is all output inhibited? Non-persistent by default.
25
26 @ivar parent_style: Another style object to which this one should dispatch
27 attribute lookups if attributes are not defined in this object
28 @type parent_style: L{Style}
29 '''
31 '''
32 Initializes the style object to which to dispatch requests for attributes
33 that are not defined in this object.
34
35 @param parent_style: Parent style object
36 @type parent_style: L{Style}
37 '''
38 super(Style, self).__init__()
39
40 self.parent_style = parent_style
41
42 if self.isDefault():
43
44 self._initDefault()
45
46 self.newBool('Mute', False, _('Mute'),
47 _('When set, all output is inhibited. This setting is not '
48 'saved to disk.'), False)
49 else:
50
51 self._initFlyweight()
52
53 - def init(self, device):
54 '''
55 Extends the default method signature with a parameter containing a
56 reference the device to which this style belongs.
57
58 @param device: Output device reference
59 @type device: L{AEOutput}
60 '''
61 pass
62
64 '''
65 Does nothing by default. Override to initialze settings that should be
66 created on default objects.
67 '''
68 pass
69
71 '''
72 Copies references to all default settings into this object. This means the
73 setting are shared between this object and the default.
74 '''
75 self.settings.update(self.parent_style.settings)
76
78 '''
79 Gets if the current style is the default meaning it does not have a parent.
80
81 @return: Is this style the default?
82 @rtype: boolean
83 '''
84 return self.parent_style is None
85
87 '''
88 Gets a reference to the default style if it exists or None if it does not.
89
90 @return: L{parent_style}
91 @rtype: L{Style}
92 '''
93 return self.parent_style
94
96 '''
97 Makes a copy of this object and its parent.
98
99 @return: New style object
100 @rtype: L{Style}
101 '''
102 c = super(Style, self).copy()
103 ps = self.parent_style
104 if ps is not None:
105 psc = ps.copy()
106 c.parent_style = psc
107 return c
108
110 '''
111 Gets if values in L{settings} have changed since the last call to
112 L{makeClean}.
113
114 @return: Dirty or not?
115 @rtype: boolean
116 '''
117 d = super(Style, self).isDirty()
118 if self.parent_style is None:
119 return d
120 else:
121 return d or self.parent_style.isDirty()
122
124 '''
125 Resets the dirty set to empty.
126 '''
127 super(Style, self).makeClean()
128 if self.parent_style is not None:
129 self.parent_style.makeClean()
130
132 '''
133 Iterates over all of the names in L{dirty} starting with the parent and
134 then working through this object.
135
136 @return: Name of a dirty setting
137 @rtype: string
138 '''
139 for name in self.parent_style.iterDirty():
140 yield name
141 for name in self.dirty:
142 yield name
143
144 - def newRelNumeric(self, name, default, label, min, max, precision,
145 description='', persist=True):
146 '''
147 Adds a new L{AEState.Setting.RelNumericSetting} to this group.
148
149 @param name: New name of the setting
150 @type name: string
151 @param default: Default value of the setting
152 @type default: float
153 @param label: Label for the new L{AEState.Setting}
154 @type label: string
155 @param min: Minimum value in the range
156 @type min: number
157 @param max: Maximum value in the range
158 @type max: number
159 @param precision: Number of decimal places
160 @type precision: integer
161 @param description: Extended description of the L{AEState.Setting}
162 @type description: string
163 @param persist: Persist the setting value to disk?
164 @type persist: boolean
165 @return: New setting object
166 @rtype: L{AEState.NumericSetting}
167 '''
168 s = AEState.RelNumericSetting(self, name, default, label, description,
169 persist, min, max, precision)
170 self.settings[name] = s
171 return s
172
173 - def newRelRange(self, name, default, label, min, max, precision,
174 description='', persist=True):
175 '''
176 Adds a new L{AEState.Setting.RelRangeSetting} to this group.
177
178 @param name: New name of the setting
179 @type name: string
180 @param default: Default value of the setting
181 @type default: float
182 @param label: Label for the new L{AEState.Setting}
183 @type label: string
184 @param min: Minimum value in the range
185 @type min: number
186 @param max: Maximum value in the range
187 @type max: number
188 @param precision: Number of decimal places
189 @type precision: integer
190 @param description: Extended description of the L{AEState.Setting}
191 @type description: string
192 @param persist: Persist the setting value to disk?
193 @type persist: boolean
194 @return: New setting object
195 @rtype: L{AEState.RangeSetting}
196 '''
197 s = AEState.RelRangeSetting(self, name, default, label, description,
198 persist, min, max, precision)
199 self.settings[name] = s
200 return s
201
202 - def newRelPercent(self, name, default, label, min, max, precision,
203 description='', persist=True):
204 '''
205 Adds a new L{AEState.Setting.RelPercentRangeSetting} to this group.
206
207 @param name: New name of the setting
208 @type name: string
209 @param default: Default value of the setting
210 @type default: float
211 @param label: Label for the new L{AEState.Setting}
212 @type label: string
213 @param min: Minimum value in the range to be shown as 0%
214 @type min: number
215 @param max: Maximum value in the range to be shown as 100%
216 @type max: number
217 @param precision: Number of decimal places
218 @type precision: integer
219 @param description: Extended description of the L{AEState.Setting}
220 @type description: string
221 @param persist: Persist the setting value to disk?
222 @type persist: boolean
223 @return: New setting object
224 @rtype: L{AEState.Setting.PercentRangeSetting}
225 '''
226 s = AEState.RelPercentRangeSetting(self, name, default, label, description,
227 persist, min, max, precision)
228 self.settings[name] = s
229 return s
230
232 '''
233 Defines the basic style attributes for all L{AEOutput.Audio} devices. Most
234 attributes documented below do not exist in this base class. It is the job
235 for a specific output device definition to add new settings to its own style
236 class class if it supports any of the missing concepts. Only those settings
237 related to text parsing are pre-defined here for use by the default
238 implementation of parseString in L{AEOutput.Audio}.
239
240 CapString (string): Set to the string that should be presented prior to the
241 spelling of capitalized letters and presented twice before spelling fully
242 capitalized words. Defaults to 'cap'.
243
244 Volume (range): Current volume
245
246 Rate (range): Current speech rate
247
248 Pitch (range): Current baseline pitch
249
250 Voice (enum): Current voice number
251
252 PosX (integer): Current spatial position x-coordinate, left negative
253
254 PosY (integer): Current spatial position y-coordinate, down negative
255
256 PosZ (integer): Current spatial position z-coordinate, behind negative
257
258 Language (choice): Current language in use by the speech synthesizer
259 formatted according to the syntax set forth in RFC 4646 and drawn from the
260 registry created by RFC 4645. See U{http://www.ietf.org/rfc/rfc4646.txt} and
261 U{http://www.iana.org/assignments/language-subtag-registry}. If an engine
262 implements some unknown derivation, use the 'x' private marker in the name
263 and continue with additional designations. See IBMSpeech for an example
264 implementation. The device is responsible for case-insensitive comparisons.
265
266 Instrument (enum): Current MIDI instrument number
267
268 Continuous (bool): Is output continuous (i.e. looping)?
269
270 Channel (integer): Channel number indicating concurrency of output. Styles
271 sharing a channel number are output sequentially. Styles having different
272 channel numbers are played concurrently if possible.
273
274 Stoppable (bool): Can output be stopped?
275
276 Speakable (bool): Can output be spoken?
277
278 Soundable (bool): Can output be played as a non-speech sound?
279
280 Gender (enum): Speech vocal tract gender
281
282 Aspiration (range): Speech breathiness
283
284 Frication (range): Emphasis of fricatives in speech
285
286 Intonation (range): Speech pitch variation
287
288 HeadSize (range): Speech speaker head size for reverberation
289
290 SpellCaps (bool): When set to True, fully capitalized words will be spelled
291 for presentation if the device supports spelling.
292
293 Blank (string): String to substitute for blank output. Defaults to 'blank'
294 localized.
295
296 CapExpand (bool): When set to True, a space will be inserted before
297 embedded capital letters in the presentation of a word. Defaults to True.
298
299 NumExpand (bool): When set to True, a space will be inserted before embedded
300 numbers in the presentation of a word. Defaults to False.
301
302 SpellFormat (enum): Set to FORMAT_TEXT to present words without additional
303 spelling. Set to FORMAT_PRONOUNCE to spell punctuation characters for
304 presentation. Set to FORMAT_SPELL to spell all characters for
305 presentation. Set to FORMAT_PHONETIC to spell all characters phonetically
306 for presentation. Defaults to FORMAT_TEXT. Any values other than
307 FORMAT_TEXT may be ignored by a device.
308 '''
310 '''
311 Called automatically by the L{Style} base class when this style is a
312 default. Initializes all default audio parsing options. If you want these
313 settings created, be sure to call this base class implementation if you
314 override in a subclass. Defaults to creating all L{Word.WordState}
315 settings.
316 '''
317 self._initWordSettings()
318 self.newString('CapString', 'cap', _('Cap string'),
319 _('String to say once before spelling capitalized letters '
320 ' and twice before spelling fully capitalized words.'))
321 self.newString('Blank', _('blank'), _('Blank string'),
322 _('String to speak when a blank or ignored character is '
323 'output on its own.'))
324 self.newBool('CapExpand', True, _('Expand caps?'),
325 _('When set, insert a space before each capital letter in the '
326 'output.'))
327 self.newBool('NumExpand', False, _('Expand numbers?'),
328 _('When set, insert a space before each number in the '
329 'output.'))
330 self.newEnum('SpellFormat', FORMAT_TEXT, _('Pronunciation rule'),
331 {_('Pronounce words') : FORMAT_TEXT,
332 _('Pronounce punctuation') : FORMAT_PRONOUNCE,
333 _('Pronounce characters') : FORMAT_SPELL,
334 _('Pronounce phonetic') : FORMAT_PHONETIC},
335 _('Defines what and how characters are pronounced.'), False)
336
338 '''
339 Builds a group containing settings that should be available for all audio
340 devices given that the L{Word} parser and the
341 L{AEOutput.Audio.Audio.parseString} methods support them without any extra
342 work on the part of the device.
343
344 @param group: Parent group for the word settings group
345 @type group: L{AEState.Setting.Group}
346 @return: Group containing the word settings, can be extended as needed
347 @rtype: L{AEState.Setting.Group}
348 '''
349 w = group.newGroup(_('Words'))
350 w.extend(['WordDef',
351 'SpellFormat',
352 'MaxRepeat',
353 'Ignore',
354 'Blank',
355 'CapString',
356 'Caps',
357 'CapExpand',
358 'NumExpand'])
359 return w
360
362 '''
363 Defines the basic style attributes for all L{AEOutput.Braille} devices.
364
365 DisplayColumns (integer) Number of cells in each display row.
366
367 DisplayRows (integer) Number of row in display.
368
369 TotalCells (integer) Total cells in display.
370
371 CaretStyle (enum): Current caret style
372
373 EllipsisRight (bool): Does user want right ellipsis shown?
374
375 EllipsisLeft (bool): Does user want left ellipsis shown?
376
377 EllipsisStyle (enum): Current ellipsis style
378
379 CellMask (string): Missing cell string. 0=bad cell; 1=good cell.
380
381 @cvar missingcellcnt: Count of missing cells in CellMask. Initialized as a
382 class variable for convienced, but used as an instance variable.
383 @type missingcellcnt: integer
384 '''
385 missingcellcnt = 0
386
388 '''
389 Called automatically by the L{Style} base class when this style is a
390 default. Initializes all default braille options. If you want these
391 settings created, be sure to call this base class implementation if you
392 override in a subclass.
393 '''
394
395 self.newNumeric('DisplayColumns', 40, _('Columns in display'), 0, 80, 0)
396 self.newNumeric('DisplayRows', 1, _('Rows in display'), 0, 10, 0)
397 self.newNumeric('TotalCells', 40, _('Total cells in display'), 0, 800, 0)
398 self.newEnum('CaretStyle', CARET_TWO_BOTTOM, _('Caret Display Style'),
399 {_('No Caret') : CARET_NONE,
400 _('Two Bottom Pins') : CARET_TWO_BOTTOM,
401 _('Bottom Right Pins') : CARET_BOTTOM_RIGHT,
402 _('All Pins') : CARET_ALL},
403 _('Defines the caret representation.'))
404
405 self.newBool('EllipsisRight', False, _('Ellipsis right?'),
406 _('When set, ellipsis will appear when additional text is to '
407 'the right of the viewport.'))
408 self.newBool('EllipsisLeft', False, _('Ellipsis left?'),
409 _('When set, ellipsis will appear when additional text is to '
410 'the left of the viewport.'))
411 self.newEnum('EllipsisStyle', ELLIPSIS_ELLIPSIS,
412 _('Ellipsis Display Style'),
413 {_('Pin 3 in 3 cells') : ELLIPSIS_ELLIPSIS,
414 _('Continuation symbol') : ELLIPSIS_CONTINUATION},
415 _('Defines the ellipsis representation.'))
416
417 cm = self.newString('CellMask', '', _('Broken Cell String'),
418 _('String of zeros and ones indicating the functionality of '
419 'each cell'))
420
421 cm.addObserver(self._setMissingCells)
422
424 '''
425 Updates the missing cell count instance variable whenever the CellMask
426 setting changes value.
427
428 @param style: This style object
429 @type style: L{BrailleStyle}
430 @param setting: Setting that change value, namely CellMask
431 @type setting: L{AEState.Setting}
432 '''
433 self.missingcellcnt = self.CellMask.count('0')
434
436 '''
437 Builds groups of standard Braille settings that should be available for all
438 Braille devices. The groups are added directly to the root group provided.
439
440 @param root: Parent group for the word settings group
441 @type root: L{AEState.Setting.Group}
442 @return: The root group again
443 @rtype: L{AEState.Setting.Group}
444 '''
445 c = root.newGroup(_('Caret'))
446 c.append('CaretStyle')
447 d = root.newGroup(_('Ellipsis'))
448 d.append('EllipsisRight')
449 d.append('EllipsisLeft')
450 d.append('EllipsisStyle')
451 e = root.newGroup(_('Broken Cells'))
452 e.append('CellMask')
453 return root
454