1 |
# |
# |
2 |
# This file is part of GNU Enterprise. |
# This file is part of GNU Enterprise. |
3 |
# |
# |
4 |
# GNU Enterprise is free software; you can redistribute it |
# GNU Enterprise is free software; you can redistribute it |
5 |
# and/or modify it under the terms of the GNU General Public |
# and/or modify it under the terms of the GNU General Public |
6 |
# License as published by the Free Software Foundation; either |
# License as published by the Free Software Foundation; either |
7 |
# version 2, or (at your option) any later version. |
# version 2, or (at your option) any later version. |
8 |
# |
# |
9 |
# GNU Enterprise is distributed in the hope that it will be |
# GNU Enterprise is distributed in the hope that it will be |
10 |
# useful, but WITHOUT ANY WARRANTY; without even the implied |
# useful, but WITHOUT ANY WARRANTY; without even the implied |
11 |
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
12 |
# PURPOSE. See the GNU General Public License for more details. |
# PURPOSE. See the GNU General Public License for more details. |
13 |
# |
# |
14 |
# You should have received a copy of the GNU General Public |
# You should have received a copy of the GNU General Public |
15 |
# License along with program; see the file COPYING. If not, |
# License along with program; see the file COPYING. If not, |
16 |
# write to the Free Software Foundation, Inc., 59 Temple Place |
# write to the Free Software Foundation, Inc., 59 Temple Place |
17 |
# - Suite 330, Boston, MA 02111-1307, USA. |
# - Suite 330, Boston, MA 02111-1307, USA. |
18 |
# |
# |
19 |
# Copyright 2000-2002 Free Software Foundation |
# Copyright 2000-2002 Free Software Foundation |
30 |
import sys |
import sys |
31 |
import types |
import types |
32 |
import string |
import string |
33 |
|
import copy |
34 |
from gnue.common.GObjects import GObj |
from gnue.common.GObjects import GObj |
35 |
from gnue.common import GDebug |
from gnue.common import GDebug |
36 |
|
|
37 |
from gnue.common import GTypecast |
from gnue.common import GTypecast |
38 |
from xml.sax import saxutils |
from xml.sax import saxutils |
39 |
from gnue.common.GParser import GContent |
from gnue.common.GParserHelpers import GContent |
40 |
|
|
41 |
class TriggerError: |
class TriggerError: |
42 |
def __init__(self, msg): |
def __init__(self, msg): |
51 |
pass |
pass |
52 |
|
|
53 |
|
|
54 |
|
|
55 |
|
|
56 |
####################################################################### |
####################################################################### |
57 |
# |
# |
67 |
# GTriggerNSObject based tree |
# GTriggerNSObject based tree |
68 |
# |
# |
69 |
class GTriggerNamespace(GObj): |
class GTriggerNamespace(GObj): |
70 |
def __init__(self,objectTree = None): |
def __init__(self,objectTree = None, rootName="root"): |
71 |
self._globalNamespace = {'True' : 1, |
self._globalNamespace = {'True' : 1, |
72 |
'False': 0, |
'False': 0, |
73 |
} |
} |
74 |
|
|
75 |
|
self._rname = rootName |
76 |
|
|
77 |
if objectTree: |
if objectTree: |
78 |
self._globalNamespace['form'] = self.constructTriggerObject(objectTree) |
self._globalNamespace[self._rname] = self.constructTriggerObject(objectTree) |
79 |
else: |
else: |
80 |
GDebug.printMesg(0,'GTriggerNamespace was passed an empty object tree') |
GDebug.printMesg(0,'GTriggerNamespace was passed an empty object tree') |
81 |
|
|
82 |
|
|
83 |
# |
# |
84 |
# constructTriggerObject |
# constructTriggerObject |
85 |
# |
# |
86 |
# Travels down thru a GObj based tree and builds a set |
# Travels down thru a GObj based tree and builds a set |
87 |
# of GTriggerNSObjects that will implement the namespace |
# of GTriggerNSObjects that will implement the namespace |
88 |
# inside triggers. |
# inside triggers. |
89 |
# |
# |
90 |
def constructTriggerObject(self, gobjObject, triggerParent=None): |
def constructTriggerObject(self, gobjObject, triggerParent=None): |
91 |
triggerObject = None |
triggerObject = None |
92 |
|
|
93 |
# Some items in a GObj tree may not be GObj based (GContent for instance) |
# Some items in a GObj tree may not be GObj based (GContent for instance) |
94 |
|
|
95 |
if isinstance(gobjObject,GObj) and hasattr(gobjObject,'name'): |
if isinstance(gobjObject,GObj) and hasattr(gobjObject,'name'): |
96 |
triggerObject = GTriggerNSObject(triggerParent) |
triggerObject = GTriggerNSObject(triggerParent) |
97 |
triggerObject._object = gobjObject |
triggerObject._object = gobjObject |
98 |
|
|
103 |
# setup get and set functions when they exist in the GObj |
# setup get and set functions when they exist in the GObj |
104 |
triggerObject._triggerSet = gobjObject._triggerSet |
triggerObject._triggerSet = gobjObject._triggerSet |
105 |
triggerObject._triggerGet = gobjObject._triggerGet |
triggerObject._triggerGet = gobjObject._triggerGet |
106 |
|
|
107 |
# Add any trigger methods defined by GObj |
# Add any trigger methods defined by GObj |
108 |
if len(gobjObject._triggerFunctions): |
if len(gobjObject._triggerFunctions): |
109 |
for item in gobjObject._triggerFunctions.keys(): |
for item in gobjObject._triggerFunctions.keys(): |
110 |
|
|
111 |
if type(gobjObject._triggerFunctions[item]['function']) == types.MethodType: |
if type(gobjObject._triggerFunctions[item]['function']) == types.MethodType: |
112 |
object = GTriggerNSFunction(item,gobjObject._triggerFunctions[item]['function']) |
object = GTriggerNSFunction(item,gobjObject._triggerFunctions[item]['function']) |
113 |
triggerObject.__dict__[item] = object |
triggerObject.__dict__[item] = object |
114 |
# Add this function to global namespace if the GObj requests it |
# Add this function to global namespace if the GObj requests it |
115 |
if gobjObject._triggerFunctions[item].has_key('global') and \ |
if gobjObject._triggerFunctions[item].has_key('global') and \ |
118 |
|
|
119 |
else: |
else: |
120 |
GDebug.printMesg(0,'Only functions are supported in an objects _triggerFunctions %s %s' % (gobjObject,item)) |
GDebug.printMesg(0,'Only functions are supported in an objects _triggerFunctions %s %s' % (gobjObject,item)) |
121 |
|
|
122 |
sys.exit() |
sys.exit() |
123 |
|
|
124 |
# Load the defined __properties__ into this object's |
# Load the defined __properties__ into this object's |
131 |
setFunc = None |
setFunc = None |
132 |
triggerObject._triggerProperties.addProperty(item,gobjObject._triggerProperties[item]['get'], setFunc) |
triggerObject._triggerProperties.addProperty(item,gobjObject._triggerProperties[item]['get'], setFunc) |
133 |
|
|
134 |
# Process the children of this Gobj |
# Process the children of this Gobj |
135 |
if len(gobjObject._children): |
if len(gobjObject._children): |
136 |
for child in gobjObject._children: |
for child in gobjObject._children: |
137 |
object = self.constructTriggerObject(child, triggerObject) |
object = self.constructTriggerObject(child, triggerObject) |
138 |
|
|
139 |
# Add this objects children to it's namespace by their name |
# Add this objects children to it's namespace by their name |
140 |
if object: |
if object: |
141 |
triggerObject.__dict__[child.name] = object |
triggerObject.__dict__[child.name] = object |
151 |
# |
# |
152 |
# GTriggerNSObject |
# GTriggerNSObject |
153 |
# |
# |
154 |
# Inherrits GObj to gain it's parent/child system |
# Inherits GObj to gain it's parent/child system |
155 |
# |
# |
156 |
class GTriggerNSObject(GObj): |
class GTriggerNSObject(GObj): |
157 |
def __init__(self, parent): |
def __init__(self, parent): |
160 |
self._triggerSet = None |
self._triggerSet = None |
161 |
self._triggerGet = None |
self._triggerGet = None |
162 |
self._object = None |
self._object = None |
163 |
|
|
164 |
# |
# |
165 |
# showTree |
# showTree |
166 |
# |
# |
202 |
# __getattr__ |
# __getattr__ |
203 |
# |
# |
204 |
# Only needed to return the GTriggerNSObjectProperties |
# Only needed to return the GTriggerNSObjectProperties |
205 |
# object |
# object |
206 |
# |
# |
207 |
def __getattr__(self,name): |
def __getattr__(self,name): |
208 |
if name == '__properties__': |
if name == '__properties__': |
209 |
return self._triggerProperties |
return self._triggerProperties |
210 |
else: |
else: |
211 |
GDebug.printMesg(1,"AttributeError: %s" % name) |
# GDebug.printMesg(1,"AttributeError: %s" % name) |
212 |
# print self.__dict__ |
# print self.__dict__ |
213 |
raise AttributeError |
raise AttributeError, '%s' % (name) |
214 |
|
|
215 |
# |
# |
216 |
# __str__ |
# __str__ |
217 |
# |
# |
309 |
# Hack to ensure that self._properties exists |
# Hack to ensure that self._properties exists |
310 |
if not self.__dict__.has_key('_properties'): |
if not self.__dict__.has_key('_properties'): |
311 |
self.__dict__['_properties'] = {} |
self.__dict__['_properties'] = {} |
312 |
|
|
313 |
if self._properties.has_key(name): |
if self._properties.has_key(name): |
314 |
# If none the it's readonly |
# If none the it's readonly |
315 |
if self._properties[name]['set']: |
if self._properties[name]['set']: |
316 |
self._properties[name]['set'](value) |
self._properties[name]['set'](value) |
317 |
else: |
else: |
318 |
GDebug.printMesg(0,'Attempt to set readonly property :%s' %(name)) |
GDebug.printMesg(0,'Attempt to set readonly property :%s' %(name)) |
342 |
# only here so that the new namespace code could be |
# only here so that the new namespace code could be |
343 |
# put to use right away |
# put to use right away |
344 |
|
|
|
# |
|
|
# A list of all valid triggers, and their "pretty" names |
|
|
# |
|
|
VALIDTRIGGERS = { 'PRE-FOCUSOUT': 'Pre-FocusOut', |
|
|
'POST-FOCUSOUT': 'Post-FocusOut', |
|
|
'PRE-FOCUSIN': 'Pre-FocusIn', |
|
|
'POST-FOCUSIN': 'Post-FocusIn', |
|
|
'PRE-COMMIT': 'Pre-Commit', |
|
|
'POST-COMMIT': 'Post-Commit', |
|
|
'POST-QUERY': 'Post-Query', |
|
|
'ON-SWITCH': 'On-Switch', |
|
|
'PRE-CHANGE': 'Pre-Change', |
|
|
'POST-CHANGE': 'Post-Change', |
|
|
'ON-NEWRECORD': 'On-NewRecord' } |
|
|
|
|
|
|
|
|
|
|
345 |
|
|
346 |
# |
# |
347 |
# GTrigger |
# GTrigger |
350 |
# |
# |
351 |
class GTrigger(GObj): |
class GTrigger(GObj): |
352 |
def __init__(self, parent=None, type=None, name=None, src=None, text=None, language='python'): |
def __init__(self, parent=None, type=None, name=None, src=None, text=None, language='python'): |
353 |
GObj.__init__(self, parent, 'GTrigger') |
|
354 |
|
GObj.__init__(self, parent, 'GCTrigger') |
355 |
|
|
356 |
self._text='' |
self._text='' |
357 |
self._triggerns={} |
self._triggerns={} |
366 |
if self.type != None: |
if self.type != None: |
367 |
self._buildObject() |
self._buildObject() |
368 |
|
|
369 |
|
|
370 |
# |
# |
371 |
# Must be at least a phase 2 init |
# Must be at least a phase 2 init |
372 |
# |
# |
376 |
# TODO: merge the local namespace of the object that |
# TODO: merge the local namespace of the object that |
377 |
# TODO: fired the trigger. |
# TODO: fired the trigger. |
378 |
def initialize(self): |
def initialize(self): |
379 |
self._form = self.findParentOfType('GFForm') |
self._root = self.findParentOfType(None) |
380 |
self._triggerns.update( self._form._triggerns ) |
self._triggerns.update( self._root._triggerns ) |
381 |
|
self._globalns = self._root._globalRuntimeNamespace |
382 |
self.__call__ = self.dummyFunction |
self.__call__ = self.dummyFunction |
383 |
|
|
384 |
if self.type != "NAMED": |
if self.type != "NAMED": |
385 |
if self._parent: |
if self._parent: |
386 |
self._parent.addTrigger( self.type, self ) |
self._parent.associateTrigger( self.type, self ) |
387 |
self._triggerns.update(self._parent._localTriggerNamespace) |
self._triggerns.update(self._parent._localTriggerNamespace) |
388 |
else: |
else: |
389 |
form = self.findParentOfType('GFForm') |
self._root._triggerDictionary[self.name] = self |
390 |
form._triggerDictionary[self.name] = self |
self._triggerns.update(self._root._localTriggerNamespace) |
|
self._triggerns.update(form._localTriggerNamespace) |
|
391 |
|
|
392 |
if self.src == None: |
if self.src == None: |
393 |
self.setFunction( self.getChildrenAsContent(), self.language ) |
self.setFunction( self.getChildrenAsContent(), self.language ) |
394 |
else: |
else: |
395 |
self.setFunctionFrom(self._form._triggerDictionary[self.src]) |
self.setFunctionFrom(self._root._triggerDictionary[self.src]) |
396 |
|
|
397 |
|
|
398 |
def setFunctionFrom(self, object): |
def setFunctionFrom(self, object): |
412 |
GDebug.printMesg(0, "The trigger named %s contains a tab character which is not allowed at pos %s" |
GDebug.printMesg(0, "The trigger named %s contains a tab character which is not allowed at pos %s" |
413 |
% ( self.name, string.find('\t', self._text) )) |
% ( self.name, string.find('\t', self._text) )) |
414 |
sys.exit() |
sys.exit() |
415 |
|
|
416 |
# Remove whitespace from last line |
# Remove whitespace from last line |
417 |
self._text = string.rstrip(self._text) |
self._text = string.rstrip(self._text) |
418 |
|
|
421 |
# syntax errors are spotted during XML parsing rather than |
# syntax errors are spotted during XML parsing rather than |
422 |
# during execution. |
# during execution. |
423 |
|
|
424 |
# Get the indentation level of the first line of code so |
# Get the indentation level of the first line of code so |
425 |
# we can indent our imports to the same level |
# we can indent our imports to the same level |
426 |
indentLevel = 0 |
indentLevel = 0 |
427 |
for line in string.split(string.replace(self._text,'\r',''),'\n'): |
for line in string.split(string.replace(self._text,'\r',''),'\n'): |
444 |
sys.exit() |
sys.exit() |
445 |
|
|
446 |
def thisTrigger(myself, code = self._code, |
def thisTrigger(myself, code = self._code, |
447 |
triggerns = self._triggerns): |
triggerns = self._triggerns, |
448 |
|
globalns = self._globalns): |
449 |
# triggerns['self'] = myself |
# triggerns['self'] = myself |
450 |
# triggerns['runform'] = myself.findParentOfType('GFForm')._app.getManager().runFormFromTrigger |
# triggerns['runform'] = myself.findParentOfType('GFForm')._app.getManager().runFormFromTrigger |
451 |
# triggerns.update( |
# triggerns.update( |
452 |
|
|
453 |
|
# Merge the trigger's namespace with the runtime global namespace |
454 |
|
# (Which can be set via the "global myvar" construct) |
455 |
|
try: |
456 |
|
del globalns['__builtins__'] |
457 |
|
except KeyError: |
458 |
|
pass |
459 |
try: |
try: |
460 |
locals = {} |
localns = copy.copy(triggerns) |
461 |
exec code in triggerns, locals |
localns.update(globalns) |
462 |
|
|
463 |
|
# And execute our code |
464 |
|
exec code in globalns, localns |
465 |
except TriggerError: |
except TriggerError: |
466 |
raise |
raise |
467 |
except: |
except: |
468 |
# May be better to deal with this in GFTriggerAware |
# May be better to deal with this in GTriggerExtension |
469 |
raise |
raise |
470 |
import sys |
import sys |
471 |
GDebug.printMesg(0, "%s in trigger code, value: %s" % (sys.exc_type, sys.exc_value)) |
GDebug.printMesg(0, "%s in trigger code, value: %s" % (sys.exc_type, sys.exc_value)) |
482 |
# for use by designer |
# for use by designer |
483 |
# |
# |
484 |
def getDescription(self): |
def getDescription(self): |
485 |
if self.type == 'NAMED': |
if self.type == 'NAMED': |
486 |
return self.name |
return self.name |
487 |
else: |
else: |
488 |
return VALIDTRIGGERS[string.upper(self.type)] |
return string.upper(self.type) |
489 |
|
|
490 |
# |
# |
491 |
# dumpXML |
# dumpXML |
494 |
# used in saving |
# used in saving |
495 |
# |
# |
496 |
def dumpXML(self, lookupDict, treeDump=None, gap=None,xmlnamespaces={}): |
def dumpXML(self, lookupDict, treeDump=None, gap=None,xmlnamespaces={}): |
497 |
escape = not int(gConfig('StoreTriggersAsCDATA')) |
try: |
498 |
|
escape = not int(gConfig('StoreTriggersAsCDATA')) |
499 |
|
except: |
500 |
|
escape = 1 |
501 |
xmlEntity = "trigger" |
xmlEntity = "trigger" |
502 |
xmlString = "%s<%s" % (gap[:-2],xmlEntity) |
xmlString = "%s<%s" % (gap[:-2],xmlEntity) |
503 |
|
|
504 |
indent = len(xmlString) |
indent = len(xmlString) |
505 |
pos = indent |
pos = indent |
506 |
for attribute in self.__dict__.keys(): |
for attribute in self.__dict__.keys(): |
507 |
|
|
508 |
# variables beginning with _ are never saved out to file |
# variables beginning with _ are never saved out to file |
509 |
# they are internal to the program |
# they are internal to the program |
510 |
if attribute[0] == "_": |
if attribute[0] == "_": |
511 |
continue |
continue |
512 |
|
|
513 |
val = self.__dict__[attribute] |
val = self.__dict__[attribute] |
514 |
if lookupDict[xmlEntity].has_key('Attributes') and \ |
if lookupDict[xmlEntity].has_key('Attributes') and \ |
515 |
lookupDict[xmlEntity]['Attributes'].has_key(attribute): |
lookupDict[xmlEntity]['Attributes'].has_key(attribute): |
516 |
if val != None and \ |
if val != None and \ |
517 |
(not lookupDict[xmlEntity]['Attributes'][attribute].has_key('Default') or \ |
(not lookupDict[xmlEntity]['Attributes'][attribute].has_key('Default') or \ |
518 |
(lookupDict[xmlEntity]['Attributes'][attribute]['Default']) != (val)): |
(lookupDict[xmlEntity]['Attributes'][attribute]['Default']) != (val)): |
519 |
typecast = lookupDict[xmlEntity]['Attributes'][attribute]['Typecast'] |
typecast = lookupDict[xmlEntity]['Attributes'][attribute]['Typecast'] |
520 |
if typecast == GTypecast.boolean \ |
if typecast == GTypecast.boolean \ |
521 |
and val == 1: |
and val == 1: |
523 |
elif typecast == GTypecast.names: |
elif typecast == GTypecast.names: |
524 |
addl = ' %s="%s"' % \ |
addl = ' %s="%s"' % \ |
525 |
(attribute, string.join(val,',')) |
(attribute, string.join(val,',')) |
526 |
else: |
else: |
527 |
addl = ' %s="%s"' % (attribute, saxutils.escape('%s' % val)) |
addl = ' %s="%s"' % (attribute, saxutils.escape('%s' % val)) |
528 |
if len(addl) + pos > 78: |
if len(addl) + pos > 78: |
529 |
xmlString += "\n" + " " * indent + addl |
xmlString += "\n" + " " * indent + addl |
530 |
pos = indent |
pos = indent |
531 |
else: |
else: |
532 |
xmlString = xmlString + addl |
xmlString = xmlString + addl |
533 |
pos += len(addl) |
pos += len(addl) |
534 |
|
|
535 |
if len(self._children): |
if len(self._children): |
536 |
hasContent = 0 |
hasContent = 0 |
537 |
for child in self._children: |
for child in self._children: |
538 |
hasContent = hasContent or isinstance(child,GContent) |
hasContent = hasContent or isinstance(child,GContent) |
539 |
if hasContent: |
if hasContent: |
540 |
xmlString += ">" |
xmlString += ">" |
541 |
else: |
else: |
542 |
xmlString += ">\n" |
xmlString += ">\n" |
543 |
|
|
544 |
if treeDump: |
if treeDump: |
545 |
if hasContent and not escape: |
if hasContent and not escape: |
546 |
xmlString += "<![CDATA[" |
xmlString += "<![CDATA[" |
547 |
for child in self._children: |
for child in self._children: |
548 |
xmlString += child.dumpXML(lookupDict, 1,gap+" ",escape=escape) |
xmlString += child.dumpXML(lookupDict, 1,gap+" ",escape=escape) |
549 |
if hasContent and not escape: |
if hasContent and not escape: |
550 |
xmlString += "]]!>" |
xmlString += "]]>" |
551 |
|
|
552 |
if hasContent: |
if hasContent: |
553 |
xmlString += "</%s>\n" % (xmlEntity) |
xmlString += "</%s>\n" % (xmlEntity) |
554 |
else: |
else: |
555 |
xmlString += "%s</%s>\n" % (gap[:-2], xmlEntity) |
xmlString += "%s</%s>\n" % (gap[:-2], xmlEntity) |
556 |
else: |
else: |
557 |
xmlString += "/>\n" |
xmlString += "/>\n" |
558 |
return xmlString |
return xmlString |
559 |
|
|
560 |
|
|
561 |
|
|
562 |
|
|
563 |
|
|
564 |
####################################################################### |
####################################################################### |
565 |
# |
# |
566 |
# Trigger processor classes |
# Trigger processor classes |
573 |
class GTriggerExtension: |
class GTriggerExtension: |
574 |
def __init__(self): |
def __init__(self): |
575 |
self._trigger = {} |
self._trigger = {} |
576 |
self._validTriggers = {} # TODO : This probably needs moved into the apps trigger manager. |
|
577 |
# TODO : I'll think about this more after sleep. |
#self._validTriggers = validTriggers |
578 |
|
|
579 |
# associateTrigger |
# associateTrigger |
580 |
# |
# |
581 |
# Associates a trigger with the object. More than one trigger of a specific type |
# Associates a trigger with the object. More than one trigger of a specific type |
583 |
# |
# |
584 |
def associateTrigger(self, key, function): |
def associateTrigger(self, key, function): |
585 |
key = string.upper(key) |
key = string.upper(key) |
586 |
if key in self._validTriggers: |
if key in self._validTriggers.keys(): |
587 |
if not self._trigger.has_key(key): |
if not self._trigger.has_key(key): |
588 |
self._trigger[string.upper(key)] = [] |
self._trigger[string.upper(key)] = [] |
589 |
self._trigger[string.upper(key)].append(function) |
self._trigger[string.upper(key)].append(function) |
591 |
print _("Invalid trigger "),key |
print _("Invalid trigger "),key |
592 |
|
|
593 |
# processTrigger |
# processTrigger |
594 |
# |
# |
595 |
# "fires" the trigger |
# "fires" the trigger |
596 |
def processTrigger(self, key): |
def processTrigger(self, key): |
597 |
key = string.upper(key) |
key = string.upper(key) |
598 |
if key in self._validTriggers: |
if key in self._validTriggers.keys(): |
599 |
if self._trigger.has_key(key): |
if self._trigger.has_key(key): |
600 |
for function in self._trigger[key]: |
for function in self._trigger[key]: |
601 |
function(self) |
function(self) |
602 |
else: |
else: |
603 |
GDebug.printMesg(10, "No triggers to fire") |
GDebug.printMesg(10, "No triggers to fire") |
604 |
else: |
else: |
605 |
print _("Invalid trigger "),key |
print self._type,": ",_("Invalid trigger "),key |
|
|
|
606 |
|
|
607 |
|
|
608 |
|
# |
609 |
|
# Return any XML elements associated with |
610 |
|
# GDataSources. Bases is a dictionary of tags |
611 |
|
# whose values are update dictionaries. |
612 |
|
# For example: bases={'datasource': {'BaseClass':myDataSource}} |
613 |
|
# sets xmlElements['datasource']['BaseClass'] = myDataSource |
614 |
|
# |
615 |
|
def getXMLelements(updates={}): |
616 |
|
|
617 |
|
xmlElements = { |
618 |
|
'trigger': { |
619 |
|
'BaseClass': GTrigger, |
620 |
|
'Importable': 1, |
621 |
|
'Attributes': { |
622 |
|
'name': { |
623 |
|
'Unique': 1, |
624 |
|
'Typecast': GTypecast.name }, |
625 |
|
'id': { |
626 |
|
'Deprecated': 'Use name="..." instead.', # DEPRECATED: Use name instead |
627 |
|
'Typecast': GTypecast.name }, |
628 |
|
'type': { |
629 |
|
'Typecast': GTypecast.uppername }, |
630 |
|
'src': { |
631 |
|
'References': (('trigger','name'),), |
632 |
|
'Typecast': GTypecast.name }, |
633 |
|
'language': { |
634 |
|
'Typecast': GTypecast.name, |
635 |
|
'ValueSet': { |
636 |
|
'python': {} }, |
637 |
|
'Default': 'python' } }, |
638 |
|
'MixedContent': 1, |
639 |
|
'KeepWhitespace': 1, |
640 |
|
'UsableBySiblings': 1, |
641 |
|
'ParentTags': None }, |
642 |
|
} |
643 |
|
|
644 |
|
for alteration in updates.keys(): |
645 |
|
xmlElements[alteration].update(updates[alteration]) |
646 |
|
|
647 |
|
return xmlElements |
648 |
|
|