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