Annotation of Amaya/amaya/templateInstantiate.c, revision 1.62
1.19 vatton 1: /*
2: *
1.60 vatton 3: * COPYRIGHT INRIA and W3C, 2006-2008
1.19 vatton 4: * Please first read the full copyright statement in file COPYRIGHT.
5: *
6: */
7:
1.1 vatton 8: #include "templates.h"
9:
10: #define THOT_EXPORT extern
11: #include "templateDeclarations.h"
12:
1.8 kia 13: #include "Elemlist.h"
14:
1.41 vatton 15: #include "AHTURLTools_f.h"
1.1 vatton 16: #include "EDITimage_f.h"
17: #include "HTMLactions_f.h"
18: #include "HTMLsave_f.h"
1.34 vatton 19: #include "HTMLtable_f.h"
1.49 vatton 20: #include "html2thot_f.h"
1.1 vatton 21: #include "init_f.h"
22: #include "templates_f.h"
23: #include "templateDeclarations_f.h"
24: #include "templateInstantiate_f.h"
25: #include "Templatebuilder_f.h"
26: #include "templateUtils_f.h"
27: #include "fetchHTMLname_f.h"
28: #include "Template.h"
29:
30: #ifdef TEMPLATES
31: #define TEMPLATE_SCHEMA_NAME "Template"
32:
33: typedef struct _InstantiateCtxt
34: {
1.47 kia 35: char *templatePath;
36: char *instancePath;
37: char *schemaName;
1.41 vatton 38: Document doc;
1.47 kia 39: DocumentType docType;
40: ThotBool dontReplace;
1.1 vatton 41: } InstantiateCtxt;
42: #endif /* TEMPLATES */
43:
44:
1.49 vatton 45:
46: /*----------------------------------------------------------------------
47: Template_InsertRepeatChildAfter
48: Insert a child to a xt:repeat
49: The decl parameter must be valid and will not be verified. It must be a
50: direct child element or the "use in the use" for union elements.
51: @param el element (xt:repeat) in which insert a new element
52: @param decl Template declaration of the element to insert
53: @param elPrev Element (xt:use) after which insert the new elem, NULL if first.
54: @return The inserted element
55: ----------------------------------------------------------------------*/
56: Element Template_InsertRepeatChildAfter (Document doc, Element el,
57: Declaration decl, Element elPrev)
58: {
59: #ifdef TEMPLATES
60: Element useFirst; /* First xt:use of the repeat.*/
61: Element use; /* xt:use to insert.*/
62: ElementType useType; /* type of xt:use.*/
63:
64: if (!TtaGetDocumentAccessMode (doc))
65: return NULL;
1.56 kia 66:
1.49 vatton 67: /* Copy xt:use with xt:types param */
68: useFirst = TtaGetFirstChild (el);
69: useType = TtaGetElementType (useFirst);
70: use = TtaCopyElement (useFirst, doc, doc, el);
71:
1.51 kia 72: TtaChangeElementType(use, Template_EL_useSimple);
73:
1.49 vatton 74: /* insert it */
75: if (elPrev)
76: TtaInsertSibling(use, elPrev, FALSE, doc);
77: else
78: TtaInsertSibling(use, useFirst, TRUE, doc);
79: Template_InsertUseChildren(doc, use, decl);
80:
81: TtaRegisterElementCreate (use, doc);
82: return use;
83: #else /* TEMPLATES */
84: return NULL;
85: #endif /* TEMPLATES */
86: }
87:
88: /*----------------------------------------------------------------------
89: Template_InsertRepeatChild
90: Insert a child to a xt:repeat
91: The decl parameter must be valid and will not be verified. It must be a
92: direct child element or the "use in the use" for union elements.
93: @param el element (repeat) in which insert a new element
94: @param decl Template declaration of the element to insert
95: @param pos Position of insertion (0 before all, 1 after first ... -1 after all)
96: @return The inserted element
97: ----------------------------------------------------------------------*/
98: Element Template_InsertRepeatChild (Document doc, Element el, Declaration decl, int pos)
99: {
100: #ifdef TEMPLATES
101: if (!TtaGetDocumentAccessMode(doc) || !decl)
102: return NULL;
103:
104: if (pos == 0)
105: return Template_InsertRepeatChildAfter (doc, el, decl, NULL);
106: else if (pos == -1)
107: return Template_InsertRepeatChildAfter (doc, el, decl, TtaGetLastChild(el));
108: else
109: {
110: Element elem = TtaGetFirstChild(el);
111: pos--;
112: while (pos > 0)
113: {
114: TtaNextSibling(&elem);
115: pos--;
116: }
117: return Template_InsertRepeatChildAfter (doc, el, decl, elem);
118: }
119: #else /* TEMPLATES */
120: return NULL;
121: #endif /* TEMPLATES */
122: }
123:
124:
125: /*----------------------------------------------------------------------
126: Template_InsertBagChild
127: Insert a child to a xt:bag at the current insertion point.
128: The decl parameter must be valid and will not be verified.
129: @param el element (xt:bag) in which insert a new element
130: @param decl Template declaration of the element to insert
131: @return The inserted element
132: ----------------------------------------------------------------------*/
1.53 kia 133: Element Template_InsertBagChild (Document doc, Element el, Declaration decl, ThotBool before)
1.49 vatton 134: {
135: #ifdef TEMPLATES
136: Element sel;
137: ElementType newElType, selType;
138: int start, end;
1.56 kia 139: SSchema sstempl = TtaGetSSchema ("Template", doc);
1.49 vatton 140:
141: if (!TtaGetDocumentAccessMode (doc) || !decl)
142: return NULL;
143:
144: TtaGiveFirstSelectedElement (doc, &sel, &start, &end);
145: if (TtaIsAncestor (sel, el))
146: {
1.56 kia 147:
148: switch(decl->nature)
149: {
150: case UnionNat:
151: newElType.ElTypeNum = Template_EL_useEl;
152: newElType.ElSSchema = sstempl;
153: break;
154: case ComponentNat:
155: newElType.ElTypeNum = Template_EL_useSimple;
156: newElType.ElSSchema = sstempl;
157: break;
158: case XmlElementNat:
159: GIType (decl->name, &newElType, doc);
160: break;
161: default:
162: break;
163: }
1.49 vatton 164:
165: selType = TtaGetElementType (sel);
166: if (decl->blockLevel &&
167: (TtaIsLeaf (selType) || !IsTemplateElement (sel)))
168: {
169: // force the insertion of a block level element at the right position
170: while (sel && IsCharacterLevelElement (sel))
171: sel = TtaGetParent (sel);
172: if (sel)
173: TtaSelectElement (doc, sel);
1.53 kia 174: TtaInsertAnyElement (doc, before);
1.57 vatton 175: TtaExtendUndoSequence (doc);
1.49 vatton 176: }
177: TtaInsertElement (newElType, doc);
178: TtaGiveFirstSelectedElement (doc, &sel, &start, &end);
1.56 kia 179: if (sel && newElType.ElSSchema == sstempl)
1.49 vatton 180: {
1.57 vatton 181: selType = TtaGetElementType (sel);
182: TtaUnselect (doc);
183:
184: if (selType.ElSSchema == newElType.ElSSchema &&
185: selType.ElTypeNum == Template_EL_useSimple)
186: {
187: SetAttributeStringValueWithUndo (sel, Template_ATTR_types, decl->name);
188: SetAttributeStringValueWithUndo (sel, Template_ATTR_title, decl->name);
189: Template_InsertUseChildren (doc, sel, decl);
190: }
191: }
192: return sel;
1.49 vatton 193: }
194: #endif /* TEMPLATES */
195: return NULL;
196: }
197:
1.1 vatton 198: /*----------------------------------------------------------------------
199: CreateInstance
1.41 vatton 200: basedoc is the displayed doc that launchs the creation of instance
1.3 vatton 201: ----------------------------------------------------------------------*/
1.41 vatton 202: void CreateInstance(char *templatePath, char *instancePath, int basedoc)
1.3 vatton 203: {
1.1 vatton 204: #ifdef TEMPLATES
1.41 vatton 205: Document doc = 0, newdoc = 0;
206: DocumentType docType;
207: ElementType elType;
208: Element root, title, text;
1.54 vatton 209: CHARSET charset;
210: char *localFile, *s, *charsetname;
1.1 vatton 211:
1.35 kia 212: XTigerTemplate t = GetXTigerTemplate(templatePath);
1.1 vatton 213: if (t == NULL)
1.29 vatton 214: {
215: // the template cannot be loaded
216: InitConfirm (doc, 1, TtaGetMessage (AMAYA, AM_BAD_TEMPLATE));
217: return;
218: }
1.41 vatton 219: // the template document
1.5 vatton 220: doc = GetTemplateDocument (t);
1.41 vatton 221: // localize the new created document
222: if (DontReplaceOldDoc)
223: newdoc = TtaGetNextDocumentIndex ();
224: else
225: newdoc = basedoc;
1.54 vatton 226:
1.41 vatton 227: localFile = GetLocalPath (newdoc, instancePath);
1.58 vatton 228: if (!TtaHasUndoSequence (doc))
1.1 vatton 229: {
230: TtaOpenUndoSequence (doc, NULL, NULL, 0, 0);
1.14 vatton 231: root = TtaGetRootElement(doc);
232: elType = TtaGetElementType (root);
233: // get the target document type
234: s = TtaGetSSchemaName (elType.ElSSchema);
235: if (strcmp (s, "HTML") == 0)
236: docType = docHTML;
237: else if (strcmp (s, "SVG") == 0)
238: docType = docSVG;
239: else if (strcmp (s, "MathML") == 0)
240: docType = docMath;
241: else
242: docType = docXml;
1.30 vatton 243: // update all links
1.33 vatton 244: SetRelativeURLs (doc, instancePath, "", FALSE, FALSE, FALSE);
1.41 vatton 245:
246: // prepare the new document view
247: TtaExtractName (instancePath, DirectoryName, DocumentName);
248: // save in the local path
1.1 vatton 249: switch (docType)
250: {
1.14 vatton 251: case docSVG:
1.55 vatton 252: TtaExportDocumentWithNewLineNumbers (doc, localFile, "SVGT", FALSE);
1.1 vatton 253: break;
1.14 vatton 254: case docMath:
1.55 vatton 255: TtaExportDocumentWithNewLineNumbers (doc, localFile, "MathMLT", FALSE);
1.1 vatton 256: break;
1.14 vatton 257: case docHTML:
258: // Initialize the document title
259: elType.ElTypeNum = HTML_EL_TITLE;
260: title = TtaSearchTypedElement (elType, SearchInTree, root);
261: text = TtaGetFirstChild (title);
262: while (text)
263: {
264: elType = TtaGetElementType (text);
265: if (elType.ElTypeNum == HTML_EL_TEXT_UNIT && Answer_text[0] != EOS)
266: {
267: TtaSetTextContent (text, (unsigned char*)Answer_text,
268: TtaGetDefaultLanguage (), doc);
269: text = NULL;
270: }
271: else if ((elType.ElTypeNum == Template_EL_useEl ||
272: elType.ElTypeNum == Template_EL_useSimple) &&
273: !strcmp (TtaGetSSchemaName (elType.ElSSchema), "Template"))
274: // Ignore the template use element
275: text = TtaGetFirstChild (text);
276: else
277: // Look for the first text child
278: TtaNextSibling (&text);
279: }
1.54 vatton 280:
281: // update the charset if needed
282: charsetname = TtaGetEnvString ("DOCUMENT_CHARSET");
283: charset = TtaGetCharset (charsetname);
1.59 kia 284: if (charset != UNDEFINED_CHARSET &&
285: DocumentMeta[doc]->charset &&
286: strcmp (charsetname, DocumentMeta[doc]->charset))
1.54 vatton 287: {
288: TtaSetDocumentCharset (doc, charset, FALSE);
289: DocumentMeta[doc]->charset = TtaStrdup (charsetname);
290: SetNamespacesAndDTD (doc);
291: }
292:
293: // export the document
1.41 vatton 294: if (TtaGetDocumentProfile(doc) == L_Xhtml11 ||
295: TtaGetDocumentProfile(doc) == L_Basic)
1.55 vatton 296: TtaExportDocumentWithNewLineNumbers (doc, localFile, "HTMLT11", FALSE);
1.1 vatton 297: else
1.55 vatton 298: TtaExportDocumentWithNewLineNumbers (doc, localFile, "HTMLTX", FALSE);
1.1 vatton 299: break;
1.14 vatton 300: default:
1.55 vatton 301: TtaExportDocumentWithNewLineNumbers (doc, localFile, NULL, FALSE);
1.1 vatton 302: break;
303: }
1.47 kia 304:
1.1 vatton 305: TtaCloseUndoSequence (doc);
306: TtaUndoNoRedo (doc);
307: TtaClearUndoHistory (doc);
1.41 vatton 308: RemoveParsingErrors (doc);
309: GetAmayaDoc (instancePath, NULL, basedoc, basedoc, CE_INSTANCE,
310: !DontReplaceOldDoc, NULL, NULL);
311: TtaSetDocumentModified (newdoc);
1.1 vatton 312: }
1.41 vatton 313: TtaFreeMemory (localFile);
1.1 vatton 314: #endif /* TEMPLATES */
315: }
316:
317: /*----------------------------------------------------------------------
1.3 vatton 318: ----------------------------------------------------------------------*/
1.41 vatton 319: void InstantiateTemplate_callback (int newdoc, int status, char *urlName,
320: char *outputfile,
321: char *proxyName, AHTHeaders *http_headers,
322: void * context)
1.1 vatton 323: {
324: #ifdef TEMPLATES
1.47 kia 325: InstantiateCtxt *ctx = (InstantiateCtxt*)context;
1.1 vatton 326:
1.47 kia 327: DoInstanceTemplate (ctx->templatePath);
1.41 vatton 328: CreateInstance (ctx->templatePath, ctx->instancePath, ctx->doc);
1.1 vatton 329: TtaFreeMemory (ctx->templatePath);
330: TtaFreeMemory (ctx->instancePath);
331: TtaFreeMemory (ctx);
332: #endif /* TEMPLATES */
333: }
334:
335: /*----------------------------------------------------------------------
1.3 vatton 336: ----------------------------------------------------------------------*/
1.1 vatton 337: void InstantiateTemplate (Document doc, char *templatename, char *docname,
338: DocumentType docType, ThotBool loaded)
339: {
340: #ifdef TEMPLATES
1.47 kia 341: if (!loaded)
1.3 vatton 342: {
343: // Create the callback context
344: InstantiateCtxt *ctx = (InstantiateCtxt *)TtaGetMemory (sizeof (InstantiateCtxt));
345: ctx->templatePath = TtaStrdup (templatename);
346: ctx->instancePath = TtaStrdup (docname);
347: ctx->schemaName = GetSchemaFromDocType(docType);
1.41 vatton 348: ctx->doc = doc;
1.3 vatton 349: ctx->docType = docType;
1.47 kia 350:
1.3 vatton 351: GetAmayaDoc (templatename, NULL, doc, doc, CE_MAKEBOOK, FALSE,
1.41 vatton 352: (void (*)(int, int, char*, char*, char*,
353: const AHTHeaders*, void*)) InstantiateTemplate_callback,
1.3 vatton 354: (void *) ctx);
355: }
1.47 kia 356: else
1.1 vatton 357: {
358: DoInstanceTemplate (templatename);
1.41 vatton 359: CreateInstance (templatename, docname, doc);
1.3 vatton 360: }
1.1 vatton 361: #endif /* TEMPLATES */
362: }
363:
364: /*----------------------------------------------------------------------
365: InstantiateAttribute
1.3 vatton 366: ----------------------------------------------------------------------*/
1.1 vatton 367: static void InstantiateAttribute (XTigerTemplate t, Element el, Document doc)
368: {
369: #ifdef TEMPLATES
370: AttributeType useType, nameType, defaultType, attrType;
371: Attribute useAttr, nameAttr, defAttr, attr;
372: ElementType elType;
373: Element parent;
374: char *text, *elementName;
375: ThotBool level;
376: NotifyAttribute event;
1.48 kia 377: int val;
1.1 vatton 378:
379: parent = TtaGetParent (el);
380: if (!parent)
381: return;
382: // if attribute "use" has value "optional", don't do anything
383: useType.AttrSSchema = TtaGetSSchema (TEMPLATE_SCHEMA_NAME, doc);
384: useType.AttrTypeNum = Template_ATTR_useAt;
385: useAttr = TtaGetAttribute (el, useType);
386: if (useAttr)
387: // there is a "use" attribute. Check its value
388: {
1.48 kia 389: val = TtaGetAttributeValue(useAttr);
390: if (val == Template_ATTR_useAt_VAL_optional)
1.18 kia 391: {
392: return;
393: }
1.1 vatton 394: }
1.18 kia 395:
1.1 vatton 396: // get the "name" and "default" attributes
397: nameType.AttrSSchema = defaultType.AttrSSchema = TtaGetSSchema (TEMPLATE_SCHEMA_NAME, doc);
1.9 vatton 398: nameType.AttrTypeNum = Template_ATTR_ref_name;
1.1 vatton 399: defaultType.AttrTypeNum = Template_ATTR_defaultAt;
400: nameAttr = TtaGetAttribute (el, nameType);
401: defAttr = TtaGetAttribute (el, defaultType);
402: if (nameAttr)
403: {
1.10 kia 404: text = GetAttributeStringValue (el, nameAttr, NULL);
1.1 vatton 405: if (text)
406: {
407: elType = TtaGetElementType (parent);
408: elementName = TtaGetElementTypeName (elType);
409: level = TRUE;
410: MapHTMLAttribute (text, &attrType, elementName, &level, doc);
411: TtaFreeMemory(text);
412: attr = TtaNewAttribute (attrType);
413: if (attr)
414: {
415: TtaAttachAttribute (parent, attr, doc);
416: if (defAttr)
417: {
1.10 kia 418: text = GetAttributeStringValue (el, defAttr, NULL);
1.25 vatton 419: if (text)
1.18 kia 420: TtaSetAttributeText(attr, text, parent, doc);
1.1 vatton 421: TtaFreeMemory(text);
422: // if it's a src arttribute for an image, load the image
423: if (!strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML") &&
424: elType.ElTypeNum == HTML_EL_IMG)
425: if (attrType.AttrTypeNum == HTML_ATTR_SRC &&
426: attrType.AttrSSchema == elType.ElSSchema)
427: {
428: event.document = doc;
429: event.element = parent;
430: event.attribute = attr;
431: SRCattrModified (&event);
432: }
433: }
434: }
435: }
436: }
437: #endif /* TEMPLATES */
438: }
439:
440: #ifdef TEMPLATES
441: /*----------------------------------------------------------------------
442: ProcessAttr
1.9 vatton 443: Look for all "attribute" elements in the subtree and instantiate them
1.3 vatton 444: ----------------------------------------------------------------------*/
1.1 vatton 445: static void ProcessAttr (XTigerTemplate t, Element el, Document doc)
446: {
447: Element child;
448: ElementType elType;
449:
450: for (child = TtaGetFirstChild (el); child; TtaNextSibling(&child))
451: {
452: elType = TtaGetElementType (child);
453: if (elType.ElTypeNum == Template_EL_attribute &&
454: !strcmp (TtaGetSSchemaName (elType.ElSSchema), TEMPLATE_SCHEMA_NAME))
455: InstantiateAttribute (t, child, doc);
456: else
457: ProcessAttr (t, child, doc);
458: }
459: }
460: #endif /* TEMPLATES */
461:
1.12 kia 462:
463: /*----------------------------------------------------------------------
464: Template_GetNewSimpleTypeInstance
465: Create an new instance of xt:use/SimpleType
466: The decl attribute must embed SimpleType declaration (no validation).
467: @param decl Declaration of new element
468: @param parent Future parent element
469: @param doc Document
470: @return The new element
471: ----------------------------------------------------------------------*/
472: Element Template_GetNewSimpleTypeInstance(Document doc, Element parent, Declaration decl)
473: {
474: Element newEl = NULL;
475: #ifdef TEMPLATES
476: ElementType elType;
477: char *empty = " ";
1.24 vatton 478:
1.38 vatton 479: elType.ElSSchema = TtaGetSSchema("Template", doc);
1.12 kia 480: elType.ElTypeNum = Template_EL_TEXT_UNIT;
481: newEl = TtaNewElement (doc, elType);
482: TtaSetTextContent (newEl, (unsigned char*) empty, 0, doc);
1.24 vatton 483: #endif /* TEMPLATES */
1.12 kia 484: return newEl;
485: }
486:
487: /*----------------------------------------------------------------------
488: Template_GetNewXmlElementInstance
489: Create an new instance of xt:use/XmlElement
490: The decl attribute must embed XmlElement declaration (no validation).
491: @param decl Declaration of new element
492: @param parent Future parent element
493: @param doc Document
494: @return The new element
495: ----------------------------------------------------------------------*/
496: Element Template_GetNewXmlElementInstance(Document doc, Element parent, Declaration decl)
497: {
498: Element newEl = NULL;
499: #ifdef TEMPLATES
500: ElementType elType;
501:
1.24 vatton 502: GIType (decl->name, &elType, doc);
503: if (elType.ElTypeNum != 0)
1.12 kia 504: {
1.23 kia 505: newEl = TtaNewTree (doc, elType, "");
1.12 kia 506: }
507: #endif /* TEMPLATES */
508: return newEl;
509: }
510:
1.34 vatton 511:
512: /*----------------------------------------------------------------------
513: InsertWithNotify applies pre and post functions when inserting the new
514: element el after child (if not NULL) or as first child of parent.
515: ----------------------------------------------------------------------*/
516: Element InsertWithNotify (Element el, Element child, Element parent, Document doc)
517: {
518: ElementType elType;
519: NotifyElement event;
520: char *name;
521: ThotBool isRow = FALSE, isCell = FALSE;
1.50 vatton 522: ThotBool isImage = FALSE;
523: ThotBool oldStructureChecking;
524:
525: // avoid to check attributes now
526: oldStructureChecking = TtaGetStructureChecking (doc);
527: TtaSetStructureChecking (FALSE, doc);
1.34 vatton 528:
529: elType = TtaGetElementType (el);
530: name = TtaGetSSchemaName (elType.ElSSchema);
531: isCell = ((!strcmp (name,"HTML") &&
532: elType.ElTypeNum == HTML_EL_Data_cell ||
533: elType.ElTypeNum == HTML_EL_Heading_cell) ||
534: (!strcmp (name,"MathML") && elType.ElTypeNum == MathML_EL_MTD));
535: isRow = ((!strcmp (name,"HTML") && elType.ElTypeNum == HTML_EL_Table_row) ||
536: (!strcmp (name,"MathML") &&
537: (elType.ElTypeNum == MathML_EL_MTR ||
538: elType.ElTypeNum == MathML_EL_MLABELEDTR)));
1.50 vatton 539: isImage = (!strcmp (name,"HTML") &&
540: (elType.ElTypeNum == HTML_EL_IMG || elType.ElTypeNum == HTML_EL_Object));
1.34 vatton 541: if (child)
542: TtaInsertSibling (el, child, FALSE, doc);
543: else
544: TtaInsertFirstChild (&el, parent, doc);
1.50 vatton 545: TtaSetStructureChecking (oldStructureChecking, doc);
1.34 vatton 546:
1.50 vatton 547: if (isImage)
548: InsertImageOrObject (el, doc);
549: else if (isCell)
1.34 vatton 550: {
551: // a cell is created
1.39 quint 552: NewCell (el, doc, TRUE, TRUE, TRUE);
1.34 vatton 553: }
554: else if (isRow)
555: {
556: // a row is created
557: event.element = el;
558: event.document = doc;
559: RowPasted (&event);
560: }
1.50 vatton 561:
562: if (!strcmp (name,"HTML"))
563: {
564: elType.ElTypeNum = HTML_EL_IMG;
565: child = TtaSearchTypedElement (elType, SearchInTree, el);
566: while (child)
567: {
568: InsertImageOrObject (child, doc);
569: child = TtaSearchTypedElementInTree (elType, SearchForward, el, child);
570: }
571: elType.ElTypeNum = HTML_EL_Object;
572: child = TtaSearchTypedElement (elType, SearchInTree, el);
573: while (child)
574: {
575: InsertImageOrObject (child, doc);
576: child = TtaSearchTypedElementInTree (elType, SearchForward, el, child);
577: }
578: }
1.34 vatton 579: return el;
580: }
581:
582:
1.12 kia 583: /*----------------------------------------------------------------------
1.16 kia 584: Template_InsertUseChildren
585: Insert children to a xt:use
586: The dec parameter must be valid and will not be verified. It must be a
587: direct child element (for union elements).
588: @param el element (xt:use) in which insert a new element
589: @param dec Template declaration of the element to insert
590: @return The inserted element (the xt:use element if insertion is multiple as component)
591: ----------------------------------------------------------------------*/
592: Element Template_InsertUseChildren(Document doc, Element el, Declaration dec)
593: {
1.34 vatton 594: Element newEl = NULL;
1.16 kia 595: #ifdef TEMPLATES
1.19 vatton 596: Element current = NULL;
1.34 vatton 597: Element child = NULL;
1.19 vatton 598: //char *attrCurrentTypeValue;
599: //ElementType elType;
1.17 kia 600:
1.25 vatton 601: if (TtaGetDocumentAccessMode(doc))
1.16 kia 602: {
1.23 kia 603: switch (dec->nature)
604: {
605: case SimpleTypeNat:
606: newEl = Template_GetNewSimpleTypeInstance(doc, el, dec);
1.34 vatton 607: newEl = InsertWithNotify (newEl, NULL, el, doc);
1.23 kia 608: break;
609: case XmlElementNat:
610: newEl = Template_GetNewXmlElementInstance(doc, el, dec);
1.34 vatton 611: newEl = InsertWithNotify (newEl, NULL, el, doc);
1.23 kia 612: break;
613: case ComponentNat:
614: newEl = TtaCopyTree(dec->componentType.content, doc, doc, el);
1.35 kia 615: ProcessAttr (dec->usedIn, newEl, doc);
1.23 kia 616: /* Copy elements from new use to existing use. */
1.34 vatton 617: while ((child = TtaGetFirstChild(newEl)))
1.23 kia 618: {
619: TtaRemoveTree (child, doc);
1.34 vatton 620: child = InsertWithNotify (child, current, el, doc);
1.23 kia 621: current = child;
622: }
623:
624: /* Copy currentType attribute. */
625: //attrCurrentTypeValue = GetAttributeStringValue (el, Template_ATTR_currentType, NULL);
626: //SetAttributeStringValue (el, Template_ATTR_currentType, attrCurrentTypeValue);
627: TtaDeleteTree(newEl, doc);
628: newEl = el;
629: break;
630: case UnionNat :
631: /* Nothing to do.*/
632: // elType.ElTypeNum = Template_EL_useEl;
633: // cont = TtaNewElement (doc, elType);
634: // if (cont)
635: // {
636: // TtaSetAccessRight (cont, ReadWrite, doc);
637: // at = TtaNewAttribute (att);
638: // if (at)
639: // {
640: // TtaAttachAttribute (cont, at, doc);
641: // TtaSetAttributeText(at, types, cont, doc);
642: // }
643: // }
644: /* @@@@@ */
645: break;
646: default :
647: //Impossible
648: break;
649: }
1.44 kia 650: Template_FixAccessRight (dec->usedIn, el, doc);
651: TtaUpdateAccessRightInViews (doc, el);
1.23 kia 652: }
1.16 kia 653: #endif /* TEMPLATES */
654: return newEl;
655: }
656:
1.40 kia 657:
658: /*----------------------------------------------------------------------
659: Fix access rights.
660: ----------------------------------------------------------------------*/
1.41 vatton 661: void Template_FixAccessRight (XTigerTemplate t, Element el, Document doc)
1.40 kia 662: {
663: #ifdef TEMPLATES
664: ElementType elType;
665: Element child;
666: char currentType[MAX_LENGTH];
667: Declaration decl;
668:
1.62 ! kia 669: // DumpElementPath(el);
1.61 kia 670:
1.40 kia 671: if (t && el && doc)
672: {
673: elType = TtaGetElementType(el);
1.41 vatton 674: if (elType.ElSSchema == TtaGetSSchema ("Template", doc))
1.40 kia 675: {
1.41 vatton 676: switch (elType.ElTypeNum)
1.40 kia 677: {
678: case Template_EL_TEXT_UNIT:
1.41 vatton 679: //TtaSetAccessRight( el, ReadWrite, doc);
680: return;
1.40 kia 681: case Template_EL_useEl:
682: case Template_EL_useSimple:
683: GiveAttributeStringValueFromNum(el, Template_ATTR_currentType,
684: (char*)currentType, NULL);
685: decl = Template_GetDeclaration(t, currentType);
686: if (decl)
687: {
688: switch (decl->nature)
689: {
690: case SimpleTypeNat:
691: case XmlElementNat:
1.41 vatton 692: TtaSetAccessRight (el, ReadWrite, doc);
693: return;
1.40 kia 694: default:
1.41 vatton 695: TtaSetAccessRight (el, ReadOnly, doc);
696: break;
1.40 kia 697: }
698: }
699: break;
700: case Template_EL_bag:
1.45 vatton 701: case Template_EL_repeat:
1.40 kia 702: TtaSetAccessRight(el, ReadWrite, doc);
703: break;
704: default:
705: TtaSetAccessRight(el, ReadOnly, doc);
706: break;
707: }
708: }
709:
1.41 vatton 710: child = TtaGetFirstChild (el);
711: // fix access right to children
712: while (child)
1.40 kia 713: {
1.41 vatton 714: Template_FixAccessRight (t, child, doc);
715: TtaNextSibling (&child);
1.40 kia 716: }
717: }
718: #endif /* TEMPLATES */
719: }
720:
1.16 kia 721: /*----------------------------------------------------------------------
1.46 vatton 722: AddPromptIndicator
723: ----------------------------------------------------------------------*/
724: void AddPromptIndicator (Element el, Document doc)
725: {
726: #ifdef TEMPLATES
727: ElementType elType;
728: AttributeType attrType;
729: Attribute att;
730:
731: elType = TtaGetElementType (el);
732: attrType.AttrSSchema = elType.ElSSchema;
733: attrType.AttrTypeNum = Template_ATTR_prompt;
734: att = TtaNewAttribute (attrType);
735: TtaAttachAttribute (el, att, doc);
736: #endif /* TEMPLATES */
737: }
738:
739: /*----------------------------------------------------------------------
1.1 vatton 740: InstantiateUse
1.3 vatton 741: ----------------------------------------------------------------------*/
1.1 vatton 742: Element InstantiateUse (XTigerTemplate t, Element el, Document doc,
1.27 kia 743: ThotBool registerUndo)
1.1 vatton 744: {
745: #ifdef TEMPLATES
1.47 kia 746: Element cont = NULL;
1.1 vatton 747: ElementType elType;
748: Declaration dec;
1.28 kia 749: int size, nbitems, i;
1.1 vatton 750: struct menuType *items;
1.33 vatton 751: char *types, *text = NULL;
1.1 vatton 752: ThotBool oldStructureChecking;
753:
1.25 vatton 754: if (!t)
1.23 kia 755: return NULL;
756:
1.1 vatton 757: /* get the value of the "types" attribute */
758: cont = NULL;
1.12 kia 759: elType = TtaGetElementType (el);
1.46 vatton 760: AddPromptIndicator (el, doc);
1.32 vatton 761: types = GetAttributeStringValueFromNum (el, Template_ATTR_types, &size);
1.36 vatton 762: if (!types || types[0] == EOS)
763: {
764: TtaFreeMemory (types);
765: return NULL;
766: }
1.1 vatton 767: giveItems (types, size, &items, &nbitems);
768: // No structure checking
769: oldStructureChecking = TtaGetStructureChecking (doc);
770: TtaSetStructureChecking (FALSE, doc);
1.10 kia 771:
1.1 vatton 772: if (nbitems == 1)
773: /* only one type in the "types" attribute */
774: {
1.17 kia 775: dec = Template_GetDeclaration (t, items[0].label);
1.1 vatton 776: if (dec)
1.27 kia 777: {
1.46 vatton 778: cont = Template_InsertUseChildren (doc, el, dec);
1.32 vatton 779: if (cont)
1.27 kia 780: {
781: TtaChangeTypeOfElement (el, doc, Template_EL_useSimple);
1.32 vatton 782: if (registerUndo)
783: TtaRegisterElementTypeChange (el, Template_EL_useEl, doc);
1.27 kia 784: }
785: }
1.1 vatton 786: }
1.33 vatton 787: TtaFreeMemory (text);
1.32 vatton 788: TtaFreeMemory (types);
1.28 kia 789:
1.32 vatton 790: for (i = 0; i < nbitems; i++)
1.28 kia 791: TtaFreeMemory(items[i].label);
1.18 kia 792: TtaFreeMemory(items);
1.1 vatton 793: TtaSetStructureChecking (oldStructureChecking, doc);
1.40 kia 794:
1.44 kia 795: Template_FixAccessRight (t, el, doc);
796: TtaUpdateAccessRightInViews (doc, el);
797:
1.1 vatton 798: return cont;
1.23 kia 799: #else /* TEMPLATES */
800: return NULL;
1.1 vatton 801: #endif /* TEMPLATES */
802: }
803:
804: /*----------------------------------------------------------------------
1.22 kia 805: InstantiateRepeat
806: Check for min and max param and validate xt:repeat element content.
807: @param registerUndo True to register undo creation sequences.
1.3 vatton 808: ----------------------------------------------------------------------*/
1.46 vatton 809: void InstantiateRepeat (XTigerTemplate t, Element el, Document doc,
810: ThotBool registerUndo)
1.1 vatton 811: {
812: #ifdef TEMPLATES
1.32 vatton 813: Element child, newChild;
1.52 vatton 814: ElementType newElType;
815: Attribute minAtt, maxAtt;
816: AttributeType minType, maxType;
817: char *text, *types = NULL, *title = NULL;
818: int curVal, minVal, maxVal;
1.32 vatton 819: int childrenCount;
820:
1.1 vatton 821:
1.25 vatton 822: if (!t)
1.23 kia 823: return;
824:
1.1 vatton 825: //Preparing types
1.52 vatton 826: minType.AttrSSchema = TtaGetSSchema (TEMPLATE_SCHEMA_NAME, doc);
1.1 vatton 827: minType.AttrTypeNum = Template_ATTR_minOccurs;
1.52 vatton 828: maxType.AttrSSchema = minType.AttrSSchema;
1.1 vatton 829: maxType.AttrTypeNum = Template_ATTR_maxOccurs;
1.52 vatton 830: newElType.ElSSchema = minType.AttrSSchema;
831: //Get minOccurs and maxOccurs attributes
1.1 vatton 832: minAtt = TtaGetAttribute (el, minType);
833: maxAtt = TtaGetAttribute (el, maxType);
834: //Get the values
835: if (minAtt)
836: {
1.10 kia 837: text = GetAttributeStringValue(el, minAtt, NULL);
1.1 vatton 838: if (text)
839: {
840: minVal = atoi(text);
841: TtaFreeMemory(text);
1.52 vatton 842: curVal = minVal;
1.1 vatton 843: }
844: else
845: //Error : Attribute with no value
846: return;
847: }
848: else
1.52 vatton 849: {
850: minVal = 0;
851: curVal = 1;
852: }
1.1 vatton 853:
854: if (maxAtt)
855: {
1.10 kia 856: text = GetAttributeStringValue (el, maxAtt, NULL);
1.1 vatton 857: if (text)
858: {
859: if (!strcmp (text, "*"))
860: maxVal = INT_MAX;
861: else
862: maxVal = atoi (text);
863: TtaFreeMemory (text);
864: }
865: else
866: //Error : Attribute with no value
867: return;
868: }
869: else
870: maxVal = INT_MAX;
871:
872: text = (char*)TtaGetMemory(MAX_LENGTH);
1.52 vatton 873: //Create non existing min max attributes
874: if (minAtt == NULL)
1.1 vatton 875: {
1.32 vatton 876: minAtt = TtaNewAttribute (minType);
877: sprintf (text, "%d", minVal);
878: TtaAttachAttribute (el, minAtt, doc);
879: TtaSetAttributeText (minAtt, text, el, doc);
1.25 vatton 880: if (registerUndo)
1.32 vatton 881: TtaRegisterAttributeCreate (minAtt, el, doc);
1.1 vatton 882: }
883:
1.52 vatton 884: if (maxAtt == NULL)
1.1 vatton 885: {
1.32 vatton 886: maxAtt = TtaNewAttribute (maxType);
887: if (maxVal < INT_MAX)
888: sprintf(text, "%d", maxVal);
1.1 vatton 889: else
1.32 vatton 890: sprintf (text, "*");
891: TtaAttachAttribute (el, maxAtt, doc);
892: TtaSetAttributeText (maxAtt, text, el, doc);
1.25 vatton 893: if (registerUndo)
1.32 vatton 894: TtaRegisterAttributeCreate (maxAtt, el, doc);
1.1 vatton 895: }
1.52 vatton 896: TtaFreeMemory(text);
1.1 vatton 897:
1.52 vatton 898: //We must have minOccurs children
1.1 vatton 899: child = TtaGetFirstChild(el);
900: if (!child)
901: //Error : a repeat must have at least one child which will be the model
902: return;
903:
904: for(childrenCount = 0; child; TtaNextSibling(&child))
905: {
906: //TODO : Check that every child is valid
907: childrenCount ++;
908: }
909:
910: if (childrenCount > maxVal)
911: //Error : too many children!
912: return;
913:
914: child = TtaGetLastChild(el);
1.32 vatton 915: types = GetAttributeStringValueFromNum (child, Template_ATTR_types, NULL);
916: title = GetAttributeStringValueFromNum (child, Template_ATTR_title, NULL);
1.52 vatton 917: newElType.ElTypeNum = Template_EL_useEl;
1.32 vatton 918: while (childrenCount < curVal)
1.1 vatton 919: {
1.32 vatton 920: newChild = TtaNewElement (doc, newElType);
1.27 kia 921: // Insert it
1.32 vatton 922: TtaInsertSibling (newChild, child, FALSE, doc);
923: SetAttributeStringValueWithUndo (newChild, Template_ATTR_types, types);
924: SetAttributeStringValueWithUndo (newChild, Template_ATTR_title, title);
1.34 vatton 925: InstantiateUse (t, newChild, doc, TRUE);
1.27 kia 926:
1.25 vatton 927: if (registerUndo)
1.34 vatton 928: TtaRegisterElementCreate (newChild, doc);
1.1 vatton 929: child = newChild;
930: childrenCount++;
931: }
1.27 kia 932:
1.44 kia 933: Template_FixAccessRight (t, el, doc);
934: TtaUpdateAccessRightInViews (doc, el);
1.32 vatton 935: TtaFreeMemory (types);
936: TtaFreeMemory (title);
1.1 vatton 937: #endif /* TEMPLATES */
938: }
939:
940: /*----------------------------------------------------------------------
941: ParseTemplate
1.3 vatton 942: ----------------------------------------------------------------------*/
1.1 vatton 943: static void ParseTemplate (XTigerTemplate t, Element el, Document doc,
944: ThotBool loading)
945: {
946: #ifdef TEMPLATES
1.47 kia 947: AttributeType attType;
948: Attribute att;
949: Element aux, child; //Needed when deleting trees
950: char *name;
951: ElementType elType = TtaGetElementType (el);
952:
1.37 kia 953: if (!t || !el)
1.23 kia 954: return;
955:
1.61 kia 956: // static int off = 0;
957: // int i;
958: // off++;
959: // printf("ParseTemplate ");
960: // for(i=0; i<off; i++)
961: // printf(" ");
962: // DumpTemplateElement(el, doc);
963: // printf("\n");
964:
1.5 vatton 965: name = TtaGetSSchemaName (elType.ElSSchema);
1.47 kia 966: if (!strcmp (name, "Template"))
1.1 vatton 967: {
1.5 vatton 968: switch(elType.ElTypeNum)
1.1 vatton 969: {
970: case Template_EL_head :
971: //Remove it and all of its children
972: TtaDeleteTree(el, doc);
973: //We must stop searching into this tree
1.61 kia 974: // off--;
1.1 vatton 975: return;
976: break;
977: case Template_EL_component :
1.25 vatton 978: // remove the name attribute
1.5 vatton 979: attType.AttrSSchema = elType.ElSSchema;
1.1 vatton 980: attType.AttrTypeNum = Template_ATTR_name;
1.18 kia 981: name = GetAttributeStringValueFromNum (el, Template_ATTR_name, NULL);
1.5 vatton 982: TtaRemoveAttribute (el, TtaGetAttribute (el, attType), doc);
1.25 vatton 983: // replace the component by a use
1.1 vatton 984: if (NeedAMenu (el, doc))
1.5 vatton 985: TtaChangeElementType (el, Template_EL_useEl);
1.1 vatton 986: else
1.5 vatton 987: TtaChangeElementType (el, Template_EL_useSimple);
1.25 vatton 988: // generate the types attribute
1.1 vatton 989: attType.AttrTypeNum = Template_ATTR_types;
1.5 vatton 990: att = TtaNewAttribute (attType);
991: TtaAttachAttribute (el, att, doc);
1.25 vatton 992: if (name)
1.18 kia 993: TtaSetAttributeText (att, name, el, doc);
1.25 vatton 994: // generate the title attribute
995: attType.AttrTypeNum = Template_ATTR_title;
996: att = TtaNewAttribute (attType);
997: TtaAttachAttribute (el, att, doc);
998: if (name)
999: TtaSetAttributeText (att, name, el, doc);
1000: // generate the currentType attribute
1.1 vatton 1001: attType.AttrTypeNum = Template_ATTR_currentType;
1.5 vatton 1002: att = TtaNewAttribute (attType);
1.18 kia 1003: TtaAttachAttribute (el, att, doc);
1.25 vatton 1004: if (name)
1.18 kia 1005: TtaSetAttributeText (att, name, el, doc);
1.28 kia 1006: TtaFreeMemory(name);
1.1 vatton 1007: break;
1008: case Template_EL_option :
1009: aux = NULL;
1010: break;
1011: case Template_EL_bag :
1012: //Link to types
1013: //Allow editing the content
1014: break;
1015: case Template_EL_useEl :
1016: case Template_EL_useSimple :
1017: /* if this use element is not empty, don't do anything: it is
1018: supposed to contain a valid instance. This should be
1019: checked, though */
1.46 vatton 1020: if (DocumentMeta[doc] && DocumentMeta[doc]->isTemplate)
1021: // add the initial indicator
1022: AddPromptIndicator (el, doc);
1023:
1.1 vatton 1024: if (!TtaGetFirstChild (el))
1.27 kia 1025: InstantiateUse (t, el, doc, FALSE);
1.1 vatton 1026: break;
1027: case Template_EL_attribute :
1028: if (!loading)
1029: InstantiateAttribute (t, el, doc);
1030: break;
1031: case Template_EL_repeat :
1.22 kia 1032: InstantiateRepeat (t, el, doc, FALSE);
1.1 vatton 1033: break;
1034: default :
1035: break;
1036: }
1037: }
1.47 kia 1038:
1039: child = TtaGetFirstChild (el);
1040: while (child)
1.1 vatton 1041: {
1042: aux = child;
1.5 vatton 1043: TtaNextSibling (&aux);
1044: ParseTemplate (t, child, doc, loading);
1.1 vatton 1045: child = aux;
1046: }
1.61 kia 1047: // off--;
1.1 vatton 1048: #endif /* TEMPLATES */
1049: }
1050:
1051: /*----------------------------------------------------------------------
1.3 vatton 1052: ----------------------------------------------------------------------*/
1.1 vatton 1053: void DoInstanceTemplate (char *templatename)
1054: {
1055: #ifdef TEMPLATES
1.47 kia 1056: XTigerTemplate t;
1057: ElementType elType;
1058: Element root, piElem, doctype, elFound, text;
1.54 vatton 1059: Document doc;
1.47 kia 1060: char *s, *charsetname = NULL, buffer[MAX_LENGTH];
1.1 vatton 1061: int pi_type;
1062:
1.47 kia 1063: //Instantiate all elements
1064: t = GetXTigerTemplate(templatename);
1.25 vatton 1065: if (!t)
1.23 kia 1066: return;
1.47 kia 1067:
1.1 vatton 1068: doc = GetTemplateDocument (t);
1.47 kia 1069: root = TtaGetMainRoot (doc);
1070: ParseTemplate (t, root, doc, FALSE);
1.1 vatton 1071:
1072: //Look for PIs
1073: /* check if the document has a DOCTYPE declaration */
1074: #ifdef ANNOTATIONS
1075: if (DocumentTypes[doc] == docAnnot)
1076: elType = TtaGetElementType (root);
1077: else
1078: #endif /* ANNOTATIONS */
1079: elType = TtaGetElementType (root);
1080: s = TtaGetSSchemaName (elType.ElSSchema);
1081: if (strcmp (s, "HTML") == 0)
1082: {
1083: elType.ElTypeNum = HTML_EL_DOCTYPE;
1084: pi_type = HTML_EL_XMLPI;
1085: }
1086: #ifdef _SVG
1087: else if (strcmp (s, "SVG") == 0)
1088: {
1089: elType.ElTypeNum = SVG_EL_DOCTYPE;
1090: pi_type = SVG_EL_XMLPI;
1091: }
1092: #endif /* _SVG */
1093: else if (strcmp (s, "MathML") == 0)
1094: {
1095: elType.ElTypeNum = MathML_EL_DOCTYPE;
1096: pi_type = MathML_EL_XMLPI;
1097: }
1098: else
1099: {
1100: elType.ElTypeNum = XML_EL_doctype;
1101: pi_type = XML_EL_xmlpi;
1102: }
1.54 vatton 1103:
1.1 vatton 1104: doctype = TtaSearchTypedElement (elType, SearchInTree, root);
1105: if (!doctype)
1106: {
1107: /* generate the XML declaration */
1108: /* Check the Thot abstract tree against the structure schema. */
1109: TtaSetStructureChecking (FALSE, doc);
1110: elType.ElTypeNum = pi_type;
1111: doctype = TtaNewTree (doc, elType, "");
1112: TtaInsertFirstChild (&doctype, root, doc);
1113: elFound = TtaGetFirstChild (doctype);
1114: text = TtaGetFirstChild (elFound);
1115: strcpy (buffer, "xml version=\"1.0\" encoding=\"");
1116: charsetname = UpdateDocumentCharset (doc);
1117: strcat (buffer, charsetname);
1118: strcat (buffer, "\"");
1119: TtaSetTextContent (text, (unsigned char*)buffer, Latin_Script, doc);
1120: TtaSetStructureChecking (TRUE, doc);
1.28 kia 1121: TtaFreeMemory(charsetname);
1.1 vatton 1122: }
1123:
1124: /* generate the XTiger PI */
1125: /* Check the Thot abstract tree against the structure schema. */
1126: TtaSetStructureChecking (FALSE, doc);
1127: elType.ElTypeNum = pi_type;
1128: piElem = TtaNewTree (doc, elType, "");
1.34 vatton 1129: TtaInsertSibling (piElem, doctype, FALSE, doc);
1.1 vatton 1130: elFound = TtaGetFirstChild (piElem);
1131: text = TtaGetFirstChild (elFound);
1132: strcpy (buffer, "xtiger template=\"");
1133: strcat (buffer, templatename);
1.17 kia 1134: strcat (buffer, "\" version=\"");
1.20 vatton 1135: if (t->version)
1136: strcat (buffer, t->version);
1137: else
1138: strcat (buffer, "0.8");
1.1 vatton 1139: strcat (buffer, "\"");
1.25 vatton 1140: if (t->templateVersion)
1.20 vatton 1141: {
1142: strcat (buffer, " templateVersion=\"");
1143: strcat (buffer, t->templateVersion);
1144: strcat (buffer, "\"");
1145: }
1.1 vatton 1146: TtaSetTextContent (text, (unsigned char*)buffer, Latin_Script, doc);
1147: TtaSetStructureChecking (TRUE, doc);
1.5 vatton 1148:
1149: // update the document title
1.47 kia 1150: if (!strcmp (s, "HTML"))
1.5 vatton 1151: {
1152: elType.ElTypeNum = HTML_EL_TITLE;
1153: elFound = TtaSearchTypedElement (elType, SearchInTree, root);
1154: if (elFound)
1155: {
1156: elFound = TtaGetFirstChild (elFound);
1157: TtaSetTextContent (elFound, (unsigned char *)Answer_text,
1158: TtaGetDefaultLanguage (), doc);
1159: }
1160: }
1.1 vatton 1161: #endif /* TEMPLATES */
1162: }
1163:
1164: /*----------------------------------------------------------------------
1.46 vatton 1165: Template_PreInstantiateComponents: Instantiates all components in
1166: order to improve editing.
1.3 vatton 1167: ----------------------------------------------------------------------*/
1.35 kia 1168: void Template_PreInstantiateComponents (XTigerTemplate t)
1.1 vatton 1169: {
1170: #ifdef TEMPLATES
1.25 vatton 1171: if (!t)
1.23 kia 1172: return;
1173:
1.35 kia 1174: HashMap components = GetComponents(t);
1175: ForwardIterator iter = HashMap_GetForwardIterator(components);
1176: Declaration comp;
1177: HashMapNode node;
1.47 kia 1178:
1.35 kia 1179: ITERATOR_FOREACH(iter, HashMapNode, node)
1.1 vatton 1180: {
1.35 kia 1181: comp = (Declaration) node->elem;
1.1 vatton 1182: ParseTemplate(t, GetComponentContent(comp), GetTemplateDocument(t), TRUE);
1183: }
1.35 kia 1184: TtaFreeMemory(iter);
1.1 vatton 1185: #endif /* TEMPLATES */
1186: }
Webmaster