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