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