Annotation of Amaya/amaya/templates.c, revision 1.162
1.1 cvs 1: /*
2: *
1.162 ! vatton 3: * COPYRIGHT INRIA and W3C, 1996-2008
1.1 cvs 4: * Please first read the full copyright statement in file COPYRIGHT.
5: *
6: */
1.14 cvs 7:
1.1 cvs 8: /*
1.51 francesc 9: * Authors: Francesc Campoy Flores
1.1 cvs 10: *
11: */
12:
13: #define THOT_EXPORT extern
14: #include "amaya.h"
15: #include "document.h"
1.99 kia 16: #include "undo.h"
1.90 kia 17: #include "containers.h"
18: #include "Elemlist.h"
1.92 kia 19: #include "templates.h"
20:
1.90 kia 21:
1.46 vatton 22: #ifdef TEMPLATES
23: #include "Template.h"
1.52 vatton 24: #include "templateDeclarations.h"
1.140 vatton 25:
26: #include "html2thot_f.h"
1.122 kia 27: #include "templates_f.h"
1.89 kia 28: #include "templateUtils_f.h"
1.67 quint 29: #include "templateLoad_f.h"
30: #include "templateDeclarations_f.h"
1.76 vatton 31: #include "templateInstantiate_f.h"
1.145 kia 32: #include "Templatebuilder_f.h"
1.28 tollenae 33: #include "appdialogue_wx.h"
1.29 tollenae 34: #include "init_f.h"
1.46 vatton 35: #include "wxdialogapi_f.h"
1.60 francesc 36: #include "AHTURLTools_f.h"
1.52 vatton 37: #endif /* TEMPLATES */
1.1 cvs 38:
1.87 kia 39: #include "fetchXMLname_f.h"
1.83 kia 40: #include "MENUconf.h"
41:
1.158 kia 42:
1.83 kia 43: /* Paths from which looking for templates.*/
44: static Prop_Templates_Path *TemplateRepositoryPaths;
45:
1.87 kia 46: /*----------------------------------------------------------------------
47: IsTemplateInstanceDocument: Test if a document is a template instance
48: doc : Document to test
49: return : TRUE if the document is a template instance
50: ----------------------------------------------------------------------*/
1.106 vatton 51: ThotBool IsTemplateInstanceDocument(Document doc)
52: {
1.87 kia 53: #ifdef TEMPLATES
1.138 vatton 54: return (DocumentMeta[doc] != NULL) && (DocumentMeta[doc]->template_url != NULL);
1.87 kia 55: #else /* TEMPLATES */
1.88 cvs 56: return FALSE;
1.87 kia 57: #endif /* TEMPLATES */
58: }
59:
1.83 kia 60: /*----------------------------------------------------------------------
1.109 kia 61: IsTemplateDocument: Test if a document is a template (not an instance)
62: doc : Document to test
63: return : TRUE if the document is an instance
64: ----------------------------------------------------------------------*/
65: ThotBool IsTemplateDocument(Document doc)
66: {
67: #ifdef TEMPLATES
1.143 kia 68: return (DocumentMeta[doc] != NULL && DocumentMeta[doc]->isTemplate);
1.109 kia 69: #else /* TEMPLATES */
70: return FALSE;
71: #endif /* TEMPLATES */
72: }
73:
1.146 vatton 74: /*----------------------------------------------------------------------
75: CheckPromptIndicator checks if the element is a prompt text unit
76: ----------------------------------------------------------------------*/
77: ThotBool CheckPromptIndicator (Element el, Document doc)
78: {
79: #ifdef TEMPLATES
80: ElementType elType;
81: Element parent;
82: AttributeType attrType;
83: Attribute att;
84: SSchema templateSSchema;
85:
86: elType = TtaGetElementType (el);
87: templateSSchema = TtaGetSSchema ("Template", doc);
88: if (elType.ElTypeNum == HTML_EL_TEXT_UNIT)
89: {
90: parent = TtaGetParent (el);
91: elType = TtaGetElementType (parent);
92: while (parent && elType.ElSSchema != templateSSchema)
93: {
94: parent = TtaGetParent (parent);
95: elType = TtaGetElementType (parent);
96: }
97: if (parent &&
98: (elType.ElTypeNum == Template_EL_useEl ||
99: elType.ElTypeNum == Template_EL_useSimple))
100: {
101: // there is a parent template use
102: attrType.AttrSSchema = elType.ElSSchema;
103: attrType.AttrTypeNum = Template_ATTR_prompt;
104: att = TtaGetAttribute (parent, attrType);
105: if (att)
1.151 quint 106: {
107: TtaSelectElement (doc, el);
108: return TRUE;
109: }
1.146 vatton 110: }
111: }
112: #endif /* TEMPLATES */
113: return FALSE;
114: }
115:
116: /*----------------------------------------------------------------------
117: RemovePromptIndicator removes the enclosing prompt indicator
118: ----------------------------------------------------------------------*/
1.153 vatton 119: ThotBool RemovePromptIndicator (NotifyOnTarget *event)
1.146 vatton 120: {
121: #ifdef TEMPLATES
122: ElementType elType;
1.153 vatton 123: Element parent, el;
1.146 vatton 124: AttributeType attrType;
125: Attribute att;
1.153 vatton 126: Document doc;
1.146 vatton 127: SSchema templateSSchema;
128:
1.153 vatton 129: el = event->element;
130: doc = event->document;
1.146 vatton 131: elType = TtaGetElementType (el);
132: templateSSchema = TtaGetSSchema ("Template", doc);
1.153 vatton 133: parent = TtaGetParent (el);
134: elType = TtaGetElementType (parent);
135: while (parent && elType.ElSSchema != templateSSchema)
1.146 vatton 136: {
1.153 vatton 137: parent = TtaGetParent (parent);
1.146 vatton 138: elType = TtaGetElementType (parent);
1.153 vatton 139: }
140: if (parent &&
141: (elType.ElTypeNum == Template_EL_useEl ||
142: elType.ElTypeNum == Template_EL_useSimple))
143: {
144: // there is a parent template use
145: attrType.AttrSSchema = elType.ElSSchema;
146: attrType.AttrTypeNum = Template_ATTR_prompt;
147: att = TtaGetAttribute (parent, attrType);
148: if (att)
1.146 vatton 149: {
1.153 vatton 150: TtaRegisterAttributeDelete (att, parent, doc);
151: TtaRemoveAttribute (parent, att, doc);
1.146 vatton 152: }
153: }
154: #endif /* TEMPLATES */
1.153 vatton 155: return FALSE; /* let Thot perform normal operation */
1.146 vatton 156: }
157:
1.109 kia 158:
159: /*----------------------------------------------------------------------
1.108 vatton 160: AllocTemplateRepositoryListElement: allocates an element for the list
161: of template repositories.
1.83 kia 162: path : path of the new element
163: return : address of the new element
164: ----------------------------------------------------------------------*/
165: void* AllocTemplateRepositoryListElement (const char* path, void* prevElement)
166: {
1.129 vatton 167: Prop_Templates_Path *element;
168:
169: element = (Prop_Templates_Path*)TtaGetMemory (sizeof(Prop_Templates_Path));
170: memset (element, 0, sizeof(Prop_Templates_Path));
171: strncpy (element->Path, path, MAX_LENGTH - 1);
1.83 kia 172: if (prevElement)
1.129 vatton 173: {
174: element->NextPath = ((Prop_Templates_Path*)prevElement)->NextPath;
175: ((Prop_Templates_Path*)prevElement)->NextPath = element;
176: }
1.83 kia 177: return element;
178: }
179:
180:
181: /*----------------------------------------------------------------------
182: FreeTemplateRepositoryList: Free the list of template repositories.
183: list : address of the list (address of the first element).
184: ----------------------------------------------------------------------*/
185: void FreeTemplateRepositoryList (void* list)
186: {
1.131 vatton 187: Prop_Templates_Path **l = (Prop_Templates_Path**) list;
188: Prop_Templates_Path *element = *l;
189:
1.83 kia 190: l = NULL;
191: while (element)
192: {
193: Prop_Templates_Path* next = element->NextPath;
1.131 vatton 194: TtaFreeMemory (element);
1.83 kia 195: element = next;
196: }
197: }
198:
199: /*----------------------------------------------------------------------
200: CopyTemplateRepositoryList: Copy a list of template repositories.
201: src : address of the list (address of the first element).
202: dst : address where copy the list
203: ----------------------------------------------------------------------*/
1.91 vatton 204: static void CopyTemplateRepositoryList (const Prop_Templates_Path** src,
205: Prop_Templates_Path** dst)
1.83 kia 206: {
207: Prop_Templates_Path *element=NULL, *current=NULL;
208:
1.131 vatton 209: if (*src)
1.83 kia 210: {
211: *dst = (Prop_Templates_Path*) TtaGetMemory (sizeof(Prop_Templates_Path));
212: (*dst)->NextPath = NULL;
213: strcpy((*dst)->Path, (*src)->Path);
214:
215: element = (*src)->NextPath;
216: current = *dst;
217: }
218:
1.106 vatton 219: while (element)
220: {
1.83 kia 221: current->NextPath = (Prop_Templates_Path*) TtaGetMemory (sizeof(Prop_Templates_Path));
222: current = current->NextPath;
223: current->NextPath = NULL;
224: strcpy(current->Path, element->Path);
225: element = element->NextPath;
1.106 vatton 226: }
1.83 kia 227: }
228:
229: /*----------------------------------------------------------------------
230: LoadTemplateRepositoryList: Load the list of template repositories.
231: list : address of the list (address of the first element).
232: return : the number of readed repository paths.
233: ----------------------------------------------------------------------*/
234: static int LoadTemplateRepositoryList (Prop_Templates_Path** list)
235: {
236: Prop_Templates_Path *element, *current = NULL;
237: char *path, *homePath;
238: unsigned char *c;
239: int nb = 0;
240: FILE *file;
241:
1.131 vatton 242: //clean up the curent list
243: FreeTemplateRepositoryList (list);
244:
245: // open the file
1.83 kia 246: path = (char *) TtaGetMemory (MAX_LENGTH);
1.86 vatton 247: homePath = TtaGetEnvString ("APP_HOME");
1.106 vatton 248: sprintf (path, "%s%ctemplates.dat", homePath, DIR_SEP);
1.83 kia 249: file = TtaReadOpen ((char *)path);
1.84 kia 250: if (!file)
251: {
252: /* The config file dont exist, create it. */
253: file = TtaWriteOpen ((char *)path);
1.122 kia 254: fprintf (file, "http://www.w3.org/Amaya/Templates/cv.xtd\n");
1.144 vatton 255: fprintf (file, "http://www.w3.org/Amaya/Templates/slides.xtd\n");
256: fprintf (file, "http://www.w3.org/Amaya/Templates/ACM-Proc-Article.xtd\n");
1.84 kia 257: TtaWriteClose (file);
258: /* Retry to open it.*/
259: file = TtaReadOpen ((char *)path);
260: }
261:
1.83 kia 262: if (file)
1.129 vatton 263: {
1.131 vatton 264: // read the file
1.129 vatton 265: c = (unsigned char*)path;
266: *c = EOS;
267: while (TtaReadByte (file, c))
268: {
269: if (*c == 13 || *c == EOL)
270: *c = EOS;
271: if (*c == EOS && c != (unsigned char*)path )
272: {
273: element = (Prop_Templates_Path*) TtaGetMemory (sizeof(Prop_Templates_Path));
274: element->NextPath = NULL;
275: strcpy (element->Path, path);
1.148 kia 276:
1.129 vatton 277: if (*list == NULL)
278: *list = element;
279: else
280: current->NextPath = element;
281: current = element;
282: nb++;
1.83 kia 283:
1.129 vatton 284: c = (unsigned char*) path;
285: *c = EOS;
286: }
287: else
288: c++;
289: }
290: if (c != (unsigned char*)path && *path != EOS)
291: {
292: element = (Prop_Templates_Path*) TtaGetMemory (sizeof(Prop_Templates_Path));
293: *(c+1) = EOS;
294: strcpy (element->Path, path);
295: element->NextPath = NULL;
1.148 kia 296:
1.129 vatton 297: if (*list == NULL)
298: *list = element;
299: else
300: current->NextPath = element;
301: nb++;
302: }
303: TtaReadClose (file);
1.83 kia 304: }
305: TtaFreeMemory(path);
306: return nb;
307: }
308:
309: /*----------------------------------------------------------------------
310: SaveTemplateRepositoryList: Save the list of template repositories.
311: list : address of the list (address of the first element).
312: ----------------------------------------------------------------------*/
313: static void SaveTemplateRepositoryList (const Prop_Templates_Path** list)
314: {
315: const Prop_Templates_Path *element;
316: char *path, *homePath;
317: unsigned char *c;
318: FILE *file;
319:
320: path = (char *) TtaGetMemory (MAX_LENGTH);
321: homePath = TtaGetEnvString ("APP_HOME");
1.106 vatton 322: sprintf (path, "%s%ctemplates.dat", homePath, DIR_SEP);
1.83 kia 323:
324: file = TtaWriteOpen ((char *)path);
325: c = (unsigned char*)path;
326: *c = EOS;
327: if (file)
328: {
329: element = *list;
330: while (element)
331: {
332: fprintf(file, "%s\n", element->Path);
333: element = element->NextPath;
334: }
335: TtaWriteClose (file);
336: }
337: }
338:
339: /*----------------------------------------------------------------------
340: GetTemplateRepositoryList: Get the list of template repositories from template environment.
341: list : address of the list (address of the first element).
342: ----------------------------------------------------------------------*/
343: void GetTemplateRepositoryList (void* list)
344: {
345: Prop_Templates_Path** l = (Prop_Templates_Path**) list;
346: CopyTemplateRepositoryList((const Prop_Templates_Path**)&TemplateRepositoryPaths, l);
347: }
348:
349: /*----------------------------------------------------------------------
350: SetTemplateRepositoryList: Set the list of template repositories environment.
351: list : address of the list (address of the first element).
352: ----------------------------------------------------------------------*/
353: void SetTemplateRepositoryList (const void* list)
354: {
355: const Prop_Templates_Path** l = (const Prop_Templates_Path**) list;
356: CopyTemplateRepositoryList((const Prop_Templates_Path**)l, &TemplateRepositoryPaths);
357: SaveTemplateRepositoryList((const Prop_Templates_Path**)&TemplateRepositoryPaths);
358: }
359:
360: /*-----------------------------------------------------------------------
361: InitTemplates
362: Initializes the annotation library
363: -----------------------------------------------------------------------*/
364: void InitTemplates ()
365: {
366: TtaSetEnvBoolean ("SHOW_TEMPLATES", TRUE, FALSE);
1.131 vatton 367: LoadTemplateRepositoryList (&TemplateRepositoryPaths);
1.83 kia 368: }
369:
370:
1.1 cvs 371: /*----------------------------------------------------------------------
1.108 vatton 372: Load a template and create the instance file - update images and
373: stylesheets related to the template.
374: ----------------------------------------------------------------------*/
375: void CreateInstanceOfTemplate (Document doc, char *templatename, char *docname)
376: {
377: #ifdef TEMPLATES
378:
379: char *s;
380: ThotBool dontReplace = DontReplaceOldDoc;
381:
382: if (!IsW3Path (docname) && TtaFileExist (docname))
383: {
384: s = (char *)TtaGetMemory (strlen (docname) +
385: strlen (TtaGetMessage (AMAYA, AM_OVERWRITE_CHECK)) + 2);
386: sprintf (s, TtaGetMessage (AMAYA, AM_OVERWRITE_CHECK), docname);
387: InitConfirm (0, 0, s);
388: TtaFreeMemory (s);
389: if (!UserAnswer)
390: return;
391: }
392:
393: LoadTemplate (0, templatename);
394: DontReplaceOldDoc = dontReplace;
1.144 vatton 395: CreateInstance (templatename, docname, doc);
1.108 vatton 396: #endif /* TEMPLATES */
397: }
398:
1.53 vatton 399:
1.109 kia 400:
1.52 vatton 401: /*----------------------------------------------------------------------
1.107 kia 402: PreventReloadingTemplate
403: Prevent reloading a template.
404: You must call AllowReloadingTemplate when finish.
405: Usefull for reload an instance without reloading the template.
406: ----------------------------------------------------------------------*/
407: void PreventReloadingTemplate(char* template_url)
408: {
409: #ifdef TEMPLATES
1.134 kia 410: XTigerTemplate t = GetXTigerTemplate (template_url);
1.112 vatton 411: if (t)
1.107 kia 412: t->users++;
413: #endif /* TEMPLATES */
414: }
415:
416: /*----------------------------------------------------------------------
417: AllowReloadingTemplate
418: Allow reloading a template.
419: You must call it after each PreventReloadingTemplate call.
420: ----------------------------------------------------------------------*/
421: void AllowReloadingTemplate(char* template_url)
422: {
423: #ifdef TEMPLATES
1.134 kia 424: XTigerTemplate t = GetXTigerTemplate (template_url);
1.112 vatton 425: if (t)
1.107 kia 426: t->users--;
427: #endif /* TEMPLATES */
428: }
429:
430:
1.137 vatton 431: /*----------------------------------------------------------------------
432: ----------------------------------------------------------------------*/
1.134 kia 433: ThotBool isEOSorWhiteSpace (const char c)
434: {
1.137 vatton 435: return c == SPACE || c == TAB || c == EOL || c ==__CR__ || c == EOS;
436: }
437: ThotBool isWhiteSpace (const char c)
438: {
439: return c == SPACE || c == TAB || c == EOL || c ==__CR__;
1.134 kia 440: }
441:
1.107 kia 442: /*----------------------------------------------------------------------
1.87 kia 443: giveItems : Lists type items from string
444: example : "one two three" is extracted to {one, two, three}
445: note : item type are setted to SimpleTypeNat
446: text : text from which list items
447: size : size of text in characters
448: items : address of exctracted item list
449: nbitems : items number in items list
1.52 vatton 450: ----------------------------------------------------------------------*/
1.76 vatton 451: void giveItems (char *text, int size, struct menuType **items, int *nbitems)
1.1 cvs 452: {
1.70 quint 453: #ifdef TEMPLATES
1.148 kia 454: ThotBool inElement = TRUE;
1.52 vatton 455: struct menuType *menu;
456: char *iter;
1.148 kia 457: char temp[128];
1.52 vatton 458: int i;
1.148 kia 459: int labelSize;
1.28 tollenae 460:
1.148 kia 461: *nbitems = 1;
462: for (i = 0; i < size; i++)
1.52 vatton 463: {
464: if (isEOSorWhiteSpace (text[i]))
465: {
466: if (inElement)
467: inElement = FALSE;
468: }
469: else if (!inElement)
470: {
471: inElement = TRUE;
472: (*nbitems)++;
473: }
474: }
1.51 francesc 475:
1.148 kia 476: menu = (struct menuType*) TtaGetMemory (sizeof (struct menuType)* *nbitems);
477: iter = text;
478: for (i = 0; i < *nbitems; i++)
479: {
1.52 vatton 480: labelSize = 0;
1.137 vatton 481: while (isWhiteSpace (*iter))
1.52 vatton 482: iter++;
1.137 vatton 483: if (*iter != EOS)
484: {
485: while (!isEOSorWhiteSpace (*iter))
486: {
487: temp[labelSize++] = *iter;
488: iter++;
489: }
1.52 vatton 490:
1.137 vatton 491: temp[labelSize] = EOS;
492: menu[i].label = (char *) TtaStrdup (temp);
493: menu[i].type = SimpleTypeNat; /* @@@@@ ???? @@@@@ */
1.52 vatton 494: }
495: }
1.137 vatton 496: *items = menu;
1.70 quint 497: #endif /* TEMPLATES */
1.28 tollenae 498: }
1.37 tollenae 499:
1.70 quint 500: #ifdef TEMPLATES
1.52 vatton 501: /*----------------------------------------------------------------------
502: ----------------------------------------------------------------------*/
503: static char *createMenuString (const struct menuType* items, const int nbItems)
504: {
505: char *result, *iter;
1.148 kia 506: int size = 0;
1.52 vatton 507: int i;
508:
1.148 kia 509: for (i=0; i < nbItems; i++)
510: size += 2 + strlen (items[i].label);
1.52 vatton 511:
1.148 kia 512: result = (char *) TtaGetMemory (size);
513: iter = result;
514: for (i=0; i < nbItems; i++)
1.52 vatton 515: {
516: *iter = 'B';
517: ++iter;
1.148 kia 518:
1.52 vatton 519: strcpy (iter, items[i].label);
520: iter += strlen (items[i].label)+1;
521: }
1.148 kia 522: return result;
1.36 tollenae 523: }
1.71 quint 524: #endif /* TEMPLATES */
1.29 tollenae 525:
1.71 quint 526: /*----------------------------------------------------------------------
527: UseToBeCreated
528: An new use element will be created by the user through some generic editing
529: command
530: -----------------------------------------------------------------------*/
531: ThotBool UseToBeCreated (NotifyElement *event)
532: {
533: #ifdef TEMPLATES
1.122 kia 534: ElementType parentType;
1.138 vatton 535: SSchema templateSSchema = TtaGetSSchema ("Template", event->document);
1.130 vatton 536: if (templateSSchema)
1.122 kia 537: {
1.130 vatton 538: parentType = TtaGetElementType (event->element);
539: if (parentType.ElSSchema == templateSSchema &&
540: parentType.ElTypeNum == Template_EL_repeat)
541: return !Template_CanInsertRepeatChild (event->element);
542: return TemplateElementWillBeCreated (event);
1.122 kia 543: }
1.52 vatton 544: #endif /* TEMPLATES */
1.71 quint 545: return FALSE; /* let Thot perform normal operation */
546: }
547:
548: /*----------------------------------------------------------------------
549: UseCreated
550: A new "use" element has just been created by the user with a generic editing
551: command.
552: -----------------------------------------------------------------------*/
553: void UseCreated (NotifyElement *event)
554: {
555: #ifdef TEMPLATES
1.148 kia 556: Document doc = event->document;
557: Element el = event->element;
1.117 kia 558: Element parent;
559: Element first;
560: ElementType parentType;
561: XTigerTemplate t;
562: SSchema templateSSchema;
1.130 vatton 563: char* types, *text = NULL;
1.148 kia 564:
1.112 vatton 565: if (!TtaGetDocumentAccessMode(doc))
1.110 kia 566: return;
567:
1.72 quint 568: if (TtaGetFirstChild (el))
569: /* this Use element has already some content. It has already been
570: instanciated */
571: return;
1.117 kia 572:
1.134 kia 573: t = GetXTigerTemplate (DocumentMeta[doc]->template_url);
1.71 quint 574: if (!t)
575: return; // no template ?!?!
1.101 kia 576:
1.138 vatton 577: templateSSchema = TtaGetSSchema ("Template", doc);
1.117 kia 578: parent = TtaGetParent(el);
579: parentType = TtaGetElementType(parent);
1.148 kia 580:
1.130 vatton 581: if (parentType.ElSSchema == templateSSchema &&
582: parentType.ElTypeNum == Template_EL_repeat)
1.117 kia 583: {
1.130 vatton 584: first = TtaGetFirstChild (parent);
585: if (first)
1.117 kia 586: {
1.130 vatton 587: types = GetAttributeStringValueFromNum (first, Template_ATTR_types, NULL);
588: if (types)
1.117 kia 589: {
1.130 vatton 590: SetAttributeStringValueWithUndo (el, Template_ATTR_types, types);
591: text = GetAttributeStringValueFromNum (el, Template_ATTR_title, NULL);
592: SetAttributeStringValueWithUndo (first, Template_ATTR_title, text);
593: TtaFreeMemory (text);
594: text = GetAttributeStringValueFromNum (el, Template_ATTR_currentType, NULL);
595: SetAttributeStringValueWithUndo (first, Template_ATTR_currentType, text);
596: TtaFreeMemory (text);
597: TtaFreeMemory (types);
1.117 kia 598: }
599: }
600: }
601:
1.76 vatton 602: InstantiateUse (t, el, doc, TRUE);
1.71 quint 603: #endif /* TEMPLATES */
604: }
1.29 tollenae 605:
1.89 kia 606:
1.98 kia 607: /*----------------------------------------------------------------------
608: Template_CanInsertRepeatChild
609: Test if a xt:repeat child can be inserted (number between params min and max).
610: @param el element (xt:repeat) to test
611: @return True if an element can be inserted.
612: ----------------------------------------------------------------------*/
613: ThotBool Template_CanInsertRepeatChild(Element el)
614: {
615: #ifdef TEMPLATES
1.154 vatton 616: char *max;
617: int maxVal, curVal;
618: Element child;
1.148 kia 619:
1.104 kia 620: max = GetAttributeStringValueFromNum(el, Template_ATTR_maxOccurs, NULL);
1.105 vatton 621: if (max)
1.104 kia 622: {
1.154 vatton 623: if (!strcmp(max, "*"))
624: {
625: TtaFreeMemory(max);
626: return TRUE;
627: }
628: maxVal = atoi (max);
629: TtaFreeMemory (max);
1.104 kia 630: curVal = 0;
1.105 vatton 631: for (child = TtaGetFirstChild(el); child; TtaNextSibling(&child))
1.104 kia 632: curVal++;
1.154 vatton 633: return (curVal < maxVal);
1.104 kia 634: }
635: else
1.98 kia 636: return TRUE;
637: #endif /* TEMPLATES */
638: return FALSE;
639: }
1.96 kia 640:
1.89 kia 641:
1.92 kia 642: #ifdef TEMPLATES
1.99 kia 643: /*----------------------------------------------------------------------
644: QueryStringFromMenu
645: Show a context menu to query a choice.
646: @param items space-separated choice list string.
647: @return The choosed item string or NULL if none.
648: ----------------------------------------------------------------------*/
1.138 vatton 649: static char* QueryStringFromMenu (Document doc, char* items)
1.90 kia 650: {
651: int nbitems, size;
652: struct menuType *itemlist;
653: char *menuString;
654: char *result = NULL;
1.148 kia 655:
1.138 vatton 656: if (!TtaGetDocumentAccessMode (doc))
1.112 vatton 657: return NULL;
658: if (items == NULL)
1.110 kia 659: return NULL;
1.138 vatton 660: size = strlen (items);
661: if (size == 0)
662: return NULL;
1.90 kia 663: giveItems (items, size, &itemlist, &nbitems);
664: menuString = createMenuString (itemlist, nbitems);
665: TtaNewScrollPopup (BaseDialog + OptionMenu, TtaGetViewFrame (doc, 1), NULL,
666: nbitems, menuString , NULL, false, 'L');
667: TtaFreeMemory (menuString);
668: ReturnOption = -1;
669: TtaShowDialogue (BaseDialog + OptionMenu, FALSE);
670: TtaWaitShowProcDialogue ();
671: TtaDestroyDialogue (BaseDialog + OptionMenu);
1.148 kia 672:
1.112 vatton 673: if (ReturnOption!=-1)
1.90 kia 674: {
675: result = TtaStrdup(itemlist[ReturnOption].label);
676: }
677:
678: TtaFreeMemory (itemlist);
679: return result;
680: }
1.92 kia 681: #endif /* TEMPLATES */
1.90 kia 682:
1.158 kia 683: #ifdef AMAYA_DEBUG
684: void FillInsertableElemList (Document doc, Element elem, DLList list);
685: #endif /* AMAYA_DEBUG */
1.162 ! vatton 686: /*----------------------------------------------------------------------
! 687: ----------------------------------------------------------------------*/
! 688: char *Template_GetListTypes (XTigerTemplate t, Element el)
! 689: {
! 690: #ifdef TEMPLATES
! 691: char *listtypes = NULL, *types;
! 692:
! 693: types = GetAttributeStringValueFromNum (el, Template_ATTR_types, NULL);
! 694: if (types)
! 695: listtypes = Template_ExpandTypes (t, types, el, FALSE);
! 696: return listtypes;
! 697: #endif /* TEMPLATES */
! 698: }
1.158 kia 699:
1.56 francesc 700: /*----------------------------------------------------------------------
1.138 vatton 701: BagButtonClicked
702: Called when a bag button is clicked.
703: Can be called for useEl, useSimple or bag.
704: If called for useEl or useSimple, the new element must be added after.
705: If called for bag, the element must be added before all.
706:
707: Shows a menu with all the types that can be used in the bag.
708: ----------------------------------------------------------------------*/
709: ThotBool BagButtonClicked (NotifyElement *event)
710: {
711: #ifdef TEMPLATES
712: Document doc = event->document;
713: Element el = event->element;
714: ElementType elType;
715: XTigerTemplate t;
716: Declaration decl;
717: Element bagEl = el;
718: Element firstEl;
719: Element newEl = NULL;
720: View view;
721: SSchema templateSSchema;
1.162 ! vatton 722: char *listtypes = NULL;
! 723: char *result = NULL;
! 724: char *types;
1.138 vatton 725: ThotBool oldStructureChecking;
726: DisplayMode dispMode;
727:
728: if (!TtaGetDocumentAccessMode(doc))
729: return TRUE;
1.148 kia 730:
1.138 vatton 731: TtaGetActiveView (&doc, &view);
732: if (view != 1)
733: return FALSE; /* let Thot perform normal operation */
734:
735: TtaCancelSelection (doc);
736: templateSSchema = TtaGetSSchema ("Template", doc);
737: t = GetXTigerTemplate (DocumentMeta[doc]->template_url);
738: elType = TtaGetElementType (el);
739: while (bagEl &&
740: (elType.ElSSchema != templateSSchema ||
741: elType.ElTypeNum != Template_EL_bag))
742: {
743: bagEl = TtaGetParent (bagEl);
744: elType = TtaGetElementType (bagEl);
745: }
746:
747: if (bagEl)
748: {
1.162 ! vatton 749: listtypes = Template_GetListTypes (t, bagEl);
! 750: if (listtypes)
1.138 vatton 751: {
1.158 kia 752: #ifdef AMAYA_DEBUG
753: printf("BagButtonClicked : \n > %s\n", listtypes);
754: // {
755: // DLList list = DLList_Create();
756: // FillInsertableElemList (doc, TtaGetFirstChild(bagEl), list);
757: // DLListNode node;
758: // ForwardIterator iter = DLList_GetForwardIterator(list);
759: // ITERATOR_FOREACH(iter, DLListNode, node)
760: // {
761: // ElemListElement elem = (ElemListElement)node->elem;
762: // printf(" + %s\n", ElemListElement_GetName(elem));
763: // }
764: // DLList_Destroy(list);
765: // }
766: #endif /* AMAYA_DEBUG */
1.138 vatton 767: result = QueryStringFromMenu (doc, listtypes);
768: TtaFreeMemory (listtypes);
769: if (result)
770: {
771: decl = Template_GetDeclaration (t, result);
772: if (decl)
773: {
774: dispMode = TtaGetDisplayMode (doc);
775: if (dispMode == DisplayImmediately)
776: /* don't set NoComputedDisplay
777: -> it breaks down views formatting when Enter generates new elements */
1.139 vatton 778: TtaSetDisplayMode (doc, DeferredDisplay);
1.138 vatton 779:
780: /* Prepare insertion.*/
781: oldStructureChecking = TtaGetStructureChecking (doc);
782: TtaSetStructureChecking (FALSE, doc);
783: TtaOpenUndoSequence (doc, NULL, NULL, 0, 0);
784:
785: /* Insert */
786: if (el == bagEl)
787: {
788: el = TtaGetFirstChild (el);
789: TtaSelectElement (doc, el);
790: TtaInsertAnyElement (doc, TRUE);
791: }
792: else
793: {
794: TtaSelectElement (doc, el);
795: TtaInsertAnyElement (doc, FALSE);
796: }
1.155 kia 797: newEl = Template_InsertBagChild (doc, bagEl, decl, FALSE);
1.138 vatton 798:
799: /* Finish insertion.*/
800: TtaCloseUndoSequence (doc);
801: TtaSetDocumentModified (doc);
802: TtaSetStructureChecking (oldStructureChecking, doc);
803: // restore the display
804: TtaSetDisplayMode (doc, dispMode);
805: firstEl = GetFirstEditableElement (newEl);
806: if (firstEl)
807: {
808: TtaSelectElement (doc, firstEl);
809: TtaSetStatusSelectedElement (doc, view, firstEl);
810: }
811: else
812: {
813: TtaSelectElement (doc, newEl);
814: TtaSetStatusSelectedElement (doc, view, newEl);
815: }
816: }
817: }
818: }
819: TtaFreeMemory (result);
820: }
821: #endif /* TEMPLATES */
822: return TRUE; /* don't let Thot perform normal operation */
823: }
824:
825: /*----------------------------------------------------------------------
1.79 quint 826: RepeatButtonClicked
1.89 kia 827: Called when a repeat button is clicked.
828: Can be called for useEl, useSimple or repeat.
829: If called for useEl or useSimple, the new element must be added after.
830: If called for repeat, the element must be added before all.
831:
1.56 francesc 832: Shows a menu with all the types that can be used in a use element.
833: ----------------------------------------------------------------------*/
1.79 quint 834: ThotBool RepeatButtonClicked (NotifyElement *event)
1.56 francesc 835: {
836: #ifdef TEMPLATES
1.89 kia 837: Document doc = event->document;
838: Element el = event->element;
839: ElementType elType;
1.90 kia 840: XTigerTemplate t;
841: Declaration decl;
842: Element repeatEl = el;
843: Element firstEl;
844: Element newEl = NULL;
1.95 kia 845: View view;
1.162 ! vatton 846: char *listtypes = NULL;
! 847: char *result = NULL;
1.138 vatton 848: ThotBool oldStructureChecking;
849: DisplayMode dispMode;
1.104 kia 850:
1.112 vatton 851: if (!TtaGetDocumentAccessMode(doc))
1.110 kia 852: return TRUE;
1.148 kia 853:
1.95 kia 854: TtaGetActiveView (&doc, &view);
855: if (view != 1)
856: return FALSE; /* let Thot perform normal operation */
857:
1.89 kia 858: TtaCancelSelection(doc);
1.148 kia 859:
1.134 kia 860: t = GetXTigerTemplate (DocumentMeta[doc]->template_url);
1.89 kia 861: elType = TtaGetElementType(el);
1.138 vatton 862: while (elType.ElTypeNum != Template_EL_repeat)
1.89 kia 863: {
1.90 kia 864: repeatEl = TtaGetParent(repeatEl);
1.138 vatton 865: if (repeatEl == NULL)
1.89 kia 866: break;
1.90 kia 867: elType = TtaGetElementType(repeatEl);
1.89 kia 868: }
1.112 vatton 869: if (repeatEl)
1.89 kia 870: {
1.138 vatton 871: if (Template_CanInsertRepeatChild (repeatEl))
1.90 kia 872: {
1.138 vatton 873: firstEl = TtaGetFirstChild (repeatEl);
1.162 ! vatton 874: listtypes = Template_GetListTypes (t, firstEl);
! 875: if (listtypes)
1.90 kia 876: {
1.158 kia 877: #ifdef AMAYA_DEBUG
878: printf("RepeatButtonClicked : \n > %s\n", listtypes);
879: #endif /* AMAYA_DEBUG */
880:
1.138 vatton 881: result = QueryStringFromMenu (doc, listtypes);
882: TtaFreeMemory (listtypes);
1.112 vatton 883: if (result)
1.98 kia 884: {
1.138 vatton 885: decl = Template_GetDeclaration (t, result);
1.112 vatton 886: if (decl)
1.104 kia 887: {
1.138 vatton 888: dispMode = TtaGetDisplayMode (doc);
889: if (dispMode == DisplayImmediately)
890: /* don't set NoComputedDisplay
891: -> it breaks down views formatting when Enter generates new elements */
1.139 vatton 892: TtaSetDisplayMode (doc, DeferredDisplay);
1.138 vatton 893:
1.104 kia 894: /* Prepare insertion.*/
895: oldStructureChecking = TtaGetStructureChecking (doc);
896: TtaSetStructureChecking (FALSE, doc);
1.138 vatton 897: TtaOpenUndoSequence (doc, NULL, NULL, 0, 0);
1.104 kia 898: /* Insert. */
1.138 vatton 899: if (el == repeatEl)
900: newEl = Template_InsertRepeatChildAfter (doc, repeatEl, decl, NULL);
1.104 kia 901: else
1.138 vatton 902: newEl = Template_InsertRepeatChildAfter (doc, repeatEl, decl, el);
1.104 kia 903:
904: /* Finish insertion.*/
905: TtaCloseUndoSequence(doc);
1.114 vatton 906: TtaSetDocumentModified (doc);
1.104 kia 907: TtaSetStructureChecking (oldStructureChecking, doc);
1.138 vatton 908:
909: // restore the display
910: TtaSetDisplayMode (doc, dispMode);
911: firstEl = GetFirstEditableElement (newEl);
1.112 vatton 912: if (firstEl)
1.104 kia 913: {
914: TtaSelectElement (doc, firstEl);
1.138 vatton 915: TtaSetStatusSelectedElement (doc, view, firstEl);
1.104 kia 916: }
917: else
918: {
919: TtaSelectElement (doc, newEl);
1.138 vatton 920: TtaSetStatusSelectedElement (doc, view, newEl);
1.104 kia 921: }
1.98 kia 922: }
923: }
1.90 kia 924: }
1.98 kia 925: TtaFreeMemory(result);
926: }
1.112 vatton 927: else /* if (Template_CanInsertRepeatChild(repeatEl)) */
1.98 kia 928: {
929: TtaSetStatus(doc, view, TtaGetMessage (AMAYA, AM_NUMBER_OCCUR_HAVE_MAX), NULL);
1.90 kia 930: }
1.89 kia 931: }
1.77 vatton 932: return TRUE; /* don't let Thot perform normal operation */
1.57 francesc 933: #endif /* TEMPLATES */
1.94 kia 934: return TRUE;
935: }
936:
937: /*----------------------------------------------------------------------
938: UseButtonClicked
939: Shows a menu with all the types that can be used in a use element.
940: ----------------------------------------------------------------------*/
941: ThotBool UseButtonClicked (NotifyElement *event)
942: {
943: #ifdef TEMPLATES
944: Document doc = event->document;
945: Element el = event->element;
1.99 kia 946: Element child;
1.94 kia 947: ElementType elType;
948: XTigerTemplate t;
949: Declaration decl;
950: Element firstEl;
951: Element newEl = NULL;
952: char* types;
953: ThotBool oldStructureChecking;
1.95 kia 954: View view;
1.133 vatton 955: char* listtypes = NULL;
956: char* result = NULL;
1.95 kia 957:
1.112 vatton 958: if (!TtaGetDocumentAccessMode(doc))
1.110 kia 959: return TRUE;
960:
1.95 kia 961: TtaGetActiveView (&doc, &view);
962: if (view != 1)
963: return FALSE; /* let Thot perform normal operation */
1.148 kia 964:
1.94 kia 965: TtaCancelSelection(doc);
966:
1.134 kia 967: t = GetXTigerTemplate (DocumentMeta[doc]->template_url);
1.94 kia 968: if (!t)
969: return FALSE; /* let Thot perform normal operation */
970: elType = TtaGetElementType(el);
971:
972: firstEl = TtaGetFirstChild(el);
1.112 vatton 973: if (firstEl)
1.94 kia 974: {
975: RepeatButtonClicked(event);
976: }
977: else
978: {
1.104 kia 979: types = GetAttributeStringValueFromNum(el, Template_ATTR_types, NULL);
1.112 vatton 980: if (types)
1.94 kia 981: {
1.142 kia 982: listtypes = Template_ExpandTypes(t, types, NULL, FALSE);
1.158 kia 983: #ifdef AMAYA_DEBUG
984: printf("UseButtonClicked : \n > %s\n", listtypes);
985: #endif /* AMAYA_DEBUG */
986:
1.104 kia 987: result = QueryStringFromMenu(doc, listtypes);
1.112 vatton 988: if (result)
1.94 kia 989: {
1.104 kia 990: decl = Template_GetDeclaration(t, result);
1.112 vatton 991: if (decl)
1.99 kia 992: {
1.104 kia 993: /* Prepare insertion.*/
994: oldStructureChecking = TtaGetStructureChecking (doc);
995: TtaSetStructureChecking (FALSE, doc);
1.138 vatton 996: TtaOpenUndoSequence (doc, NULL, NULL, 0, 0);
1.104 kia 997:
998: /* Insert */
999: newEl = Template_InsertUseChildren(doc, el, decl);
1000: for(child = TtaGetFirstChild(newEl); child; TtaNextSibling(&child))
1001: {
1002: TtaRegisterElementCreate(child, doc);
1003: }
1004:
1005: TtaChangeTypeOfElement(el, doc, Template_EL_useSimple);
1006: TtaRegisterElementTypeChange(el, Template_EL_useEl, doc);
1007:
1.117 kia 1008: /* xt:currentType attribute.*/
1009: SetAttributeStringValueWithUndo(el, Template_ATTR_currentType, result);
1010:
1.104 kia 1011: /* Finish insertion. */
1012: TtaCloseUndoSequence(doc);
1.114 vatton 1013: TtaSetDocumentModified (doc);
1.104 kia 1014: TtaSetStructureChecking (oldStructureChecking, doc);
1015:
1016: firstEl = GetFirstEditableElement(newEl);
1.112 vatton 1017: if (firstEl)
1.104 kia 1018: {
1019: TtaSelectElement (doc, firstEl);
1020: TtaSetStatusSelectedElement(doc, view, firstEl);
1021: }
1022: else
1023: {
1024: TtaSelectElement (doc, newEl);
1025: TtaSetStatusSelectedElement(doc, view, newEl);
1026: }
1.98 kia 1027: }
1.94 kia 1028: }
1029: }
1.104 kia 1030: TtaFreeMemory(types);
1.94 kia 1031: TtaFreeMemory(listtypes);
1032: TtaFreeMemory(result);
1033: }
1.148 kia 1034:
1.94 kia 1035: return TRUE;
1036: #endif /* TEMPLATES */
1.56 francesc 1037: return TRUE;
1038: }
1.64 francesc 1039:
1.89 kia 1040:
1.103 kia 1041: /*----------------------------------------------------------------------
1042: UseSimpleButtonClicked
1043: ----------------------------------------------------------------------*/
1044: ThotBool UseSimpleButtonClicked (NotifyElement *event)
1045: {
1046: #ifdef TEMPLATES
1.112 vatton 1047: if (!TtaGetDocumentAccessMode(event->document))
1.110 kia 1048: return TRUE;
1049:
1.138 vatton 1050: ElementType parentType = TtaGetElementType (TtaGetParent( event->element));
1.112 vatton 1051: if (parentType.ElTypeNum == Template_EL_repeat)
1.138 vatton 1052: return RepeatButtonClicked (event);
1053: else if (parentType.ElTypeNum == Template_EL_bag)
1054: return BagButtonClicked (event);
1.103 kia 1055: #endif /* TEMPLATES */
1056: return FALSE;
1057: }
1.94 kia 1058:
1059: /*----------------------------------------------------------------------
1060: OptionButtonClicked
1061: ----------------------------------------------------------------------*/
1062: ThotBool OptionButtonClicked (NotifyElement *event)
1063: {
1064: #ifdef TEMPLATES
1.145 kia 1065: Element useEl, contentEl, next;
1066: ElementType useType, optType;
1.94 kia 1067: Document doc;
1068: XTigerTemplate t;
1069: View view;
1070:
1.112 vatton 1071: if (!TtaGetDocumentAccessMode(event->document))
1.110 kia 1072: return TRUE;
1073:
1.94 kia 1074: TtaGetActiveView (&doc, &view);
1075: if (view != 1)
1076: return FALSE; /* let Thot perform normal operation */
1.110 kia 1077:
1.94 kia 1078: doc = event->document;
1.145 kia 1079: useEl = TtaGetFirstChild (event->element);
1080: if (!useEl)
1.94 kia 1081: return FALSE; /* let Thot perform normal operation */
1.145 kia 1082: useType = TtaGetElementType (useEl);
1083: optType = TtaGetElementType (event->element);
1084: if ((useType.ElTypeNum != Template_EL_useEl &&
1.148 kia 1085: useType.ElTypeNum != Template_EL_useSimple) ||
1086: useType.ElSSchema != optType.ElSSchema)
1.94 kia 1087: return FALSE;
1088:
1.145 kia 1089: TtaOpenUndoSequence(doc, NULL, NULL, 0, 0);
1.148 kia 1090:
1.94 kia 1091: TtaCancelSelection (doc);
1.148 kia 1092:
1.145 kia 1093: contentEl = TtaGetFirstChild (useEl);
1094: if (!contentEl)
1.94 kia 1095: /* the "use" element is empty. Instantiate it */
1096: {
1.134 kia 1097: t = GetXTigerTemplate (DocumentMeta[doc]->template_url);
1.94 kia 1098: if (!t)
1099: return FALSE; // no template ?!?!
1.145 kia 1100: InstantiateUse (t, useEl, doc, TRUE);
1.94 kia 1101: }
1102: else
1103: /* remove the content of the "use" element */
1104: {
1105: do
1106: {
1.145 kia 1107: next = contentEl;
1.94 kia 1108: TtaNextSibling (&next);
1.145 kia 1109: TtaRegisterElementDelete(contentEl, doc);
1110: TtaDeleteTree (contentEl, doc);
1111: contentEl = next;
1.94 kia 1112: }
1113: while (next);
1.145 kia 1114: if (NeedAMenu (useEl, doc))
1115: {
1116: TtaChangeTypeOfElement (useEl, doc, Template_EL_useEl);
1117: TtaRegisterElementTypeChange(useEl, Template_EL_useSimple, doc);
1118: }
1.94 kia 1119: }
1120: TtaSelectElement (doc, event->element);
1.145 kia 1121: TtaCloseUndoSequence(doc);
1.94 kia 1122: return TRUE; /* don't let Thot perform normal operation */
1123: #endif /* TEMPLATES */
1124: return TRUE;
1125: }
1126:
1.111 vatton 1127: /*----------------------------------------------------------------------
1128: CheckTemplate checks if the template of the instance is loaded
1.126 vatton 1129: Return TRUE if the template is loaded
1.111 vatton 1130: ----------------------------------------------------------------------*/
1131: void CheckTemplate (Document doc)
1132: {
1133: #ifdef TEMPLATES
1.144 vatton 1134: Element root;
1135:
1136: if (DocumentMeta[doc] && DocumentMeta[doc]->template_url)
1.111 vatton 1137: {
1.144 vatton 1138: XTigerTemplate t;
1139:
1140: root = TtaGetRootElement (doc);
1141: TtaSetAccessRight (root, ReadOnly, doc);
1142: t = GetXTigerTemplate (DocumentMeta[doc]->template_url);
1143: if (t == NULL)
1144: {
1145: // the template cannot be loaded
1146: InitConfirm (doc, 1, TtaGetMessage (AMAYA, AM_BAD_TEMPLATE));
1147: TtaSetDocumentAccessMode (doc, 0); // document readonly
1148: }
1149: else
1150: {
1151: // fix all access rights in the instance
1152: Template_FixAccessRight (t, root, doc);
1153: TtaUpdateAccessRightInViews (doc, root);
1154: }
1.111 vatton 1155: }
1156: #endif /* TEMPLATES */
1157: }
1.94 kia 1158:
1.66 vatton 1159: /*----------------------------------------------------------------------
1.108 vatton 1160: OpeningInstance checks if it is a template instance needs.
1161: If it's an instance and the template is not loaded, load it into a
1162: temporary file
1.66 vatton 1163: ----------------------------------------------------------------------*/
1.76 vatton 1164: void OpeningInstance (char *fileName, Document doc)
1.65 francesc 1165: {
1166: #ifdef TEMPLATES
1.76 vatton 1167: XTigerTemplate t;
1.103 kia 1168: char *content, *ptr, *begin;
1.76 vatton 1169: gzFile stream;
1170: char buffer[2000];
1.77 vatton 1171: int res;
1.65 francesc 1172:
1.76 vatton 1173: stream = TtaGZOpen (fileName);
1174: if (stream != 0)
1.65 francesc 1175: {
1.76 vatton 1176: res = gzread (stream, buffer, 1999);
1177: if (res >= 0)
1.65 francesc 1178: {
1.81 vatton 1179: buffer[res] = EOS;
1.103 kia 1180: begin = strstr (buffer, "<?xtiger");
1181:
1.112 vatton 1182: if (begin)
1.103 kia 1183: {
1184: // Search for template version
1185: ptr = strstr (begin, "templateVersion");
1186: if (ptr)
1187: ptr = strstr (ptr, "=");
1188: if (ptr)
1189: ptr = strstr (ptr, "\"");
1190: if (ptr)
1191: {
1192: // template URI
1193: content = &ptr[1];
1194: ptr = strstr (content, "\"");
1195: }
1196: if (ptr)
1197: {
1198: *ptr = EOS;
1199: //Get now the template URI
1200: DocumentMeta[doc]->template_version = TtaStrdup (content);
1201: *ptr = '"';
1202: }
1203:
1204: // Search for template uri
1205: ptr = strstr (begin, "template");
1206: if (ptr && ptr[8] != 'V')
1207: ptr = strstr (ptr, "=");
1208: if (ptr)
1209: ptr = strstr (ptr, "\"");
1210: if (ptr)
1211: {
1212: // template URI
1213: content = &ptr[1];
1214: ptr = strstr (content, "\"");
1215: }
1216: if (ptr)
1217: {
1218: *ptr = EOS;
1219: //Get now the template URI
1220: DocumentMeta[doc]->template_url = TtaStrdup (content);
1.134 kia 1221: if (Templates_Map == NULL)
1.103 kia 1222: InitializeTemplateEnvironment ();
1.134 kia 1223: t = GetXTigerTemplate (content);
1.103 kia 1224: if (!t)
1225: {
1.108 vatton 1226: LoadTemplate (doc, content);
1.134 kia 1227: t = GetXTigerTemplate(content);
1.103 kia 1228: }
1229: AddUser (t);
1230: *ptr = '"';
1231: }
1232: }
1.65 francesc 1233: }
1234: }
1.76 vatton 1235: TtaGZClose (stream);
1.65 francesc 1236: #endif /* TEMPLATES */
1237: }
1238:
1.64 francesc 1239: /*----------------------------------------------------------------------
1.65 francesc 1240: ClosingInstance
1.64 francesc 1241: Callback called before closing a document. Checks for unused templates.
1242: ----------------------------------------------------------------------*/
1.65 francesc 1243: ThotBool ClosingInstance(NotifyDialog* dialog)
1.64 francesc 1244: {
1.65 francesc 1245: #ifdef TEMPLATES
1246: //If it is a template all has been already freed
1.76 vatton 1247: if (DocumentMeta[dialog->document] == NULL)
1248: return FALSE;
1.65 francesc 1249:
1250: char *turl = DocumentMeta[dialog->document]->template_url;
1.73 vatton 1251: if (turl)
1.104 kia 1252: {
1.134 kia 1253: XTigerTemplate t = GetXTigerTemplate(turl);
1.104 kia 1254: if (t)
1255: RemoveUser (t);
1256: TtaFreeMemory (turl);
1257: DocumentMeta[dialog->document]->template_url = NULL;
1258: }
1259:
1.112 vatton 1260: if (DocumentMeta[dialog->document]->template_version)
1.104 kia 1261: {
1262: TtaFreeMemory(DocumentMeta[dialog->document]->template_version);
1263: DocumentMeta[dialog->document]->template_version = NULL;
1264: }
1.65 francesc 1265: #endif /* TEMPLATES */
1266: return FALSE;
1.64 francesc 1267: }
1.87 kia 1268:
1269:
1270: /*----------------------------------------------------------------------
1.120 kia 1271: IsTemplateElement
1.138 vatton 1272: Test if an element is a template element.
1.87 kia 1273: ----------------------------------------------------------------------*/
1.140 vatton 1274: ThotBool IsTemplateElement (Element elem)
1.87 kia 1275: {
1276: #ifdef TEMPLATES
1.138 vatton 1277: ElementType elType;
1278:
1279: elType = TtaGetElementType(elem);
1280: if (elType.ElSSchema)
1281: return (strcmp(TtaGetSSchemaName(elType.ElSSchema) , "Template") != 0);
1282: #endif /* TEMPLATES */
1.87 kia 1283: return FALSE;
1284: }
1285:
1286:
1287: /*----------------------------------------------------------------------
1288: GetFirstTemplateParentElement
1.138 vatton 1289: Return the first element which has "Template" as schema name or null.
1.87 kia 1290: ----------------------------------------------------------------------*/
1291: Element GetFirstTemplateParentElement(Element elem)
1292: {
1293: #ifdef TEMPLATES
1.138 vatton 1294: ElementType elType;
1295:
1296: elem = TtaGetParent (elem);
1297: elType = TtaGetElementType(elem);
1298: while (elem && strcmp(TtaGetSSchemaName(elType.ElSSchema), "Template"))
1299: {
1300: elem = TtaGetParent (elem);
1301: elType = TtaGetElementType(elem);
1.87 kia 1302: }
1303: return elem;
1304: #else
1305: return NULL;
1306: #endif /* TEMPLATES */
1307: }
1.101 kia 1308:
1.103 kia 1309:
1.101 kia 1310: /*----------------------------------------------------------------------
1.102 vatton 1311: TemplateElementWillBeCreated
1.101 kia 1312: Processed when an element will be created in a template context.
1313: ----------------------------------------------------------------------*/
1.102 vatton 1314: ThotBool TemplateElementWillBeCreated (NotifyElement *event)
1.101 kia 1315: {
1.103 kia 1316: #ifdef TEMPLATES
1317: ElementType elType = event->elementType;
1318: Element parent = event->element;
1319: ElementType parentType = TtaGetElementType(parent);
1.113 kia 1320: Element ancestor;
1321: ElementType ancestorType;
1322: SSchema templateSSchema;
1323: char* types;
1324: ThotBool b;
1.101 kia 1325:
1.115 kia 1326: if(event->info==1)
1327: return FALSE;
1328:
1.112 vatton 1329: if (!TtaGetDocumentAccessMode(event->document))
1.110 kia 1330: return TRUE;
1331:
1.138 vatton 1332: templateSSchema = TtaGetSSchema ("Template", event->document);
1.102 vatton 1333: if (templateSSchema == NULL)
1334: return FALSE; // let Thot do the job
1.115 kia 1335:
1.113 kia 1336: // Fisrt, test if in a xt:bag or in a base-element xt:use
1.147 vatton 1337: if(parentType.ElSSchema == templateSSchema)
1.113 kia 1338: ancestor = parent;
1339: else
1.147 vatton 1340: ancestor = GetFirstTemplateParentElement (parent);
1.113 kia 1341:
1.147 vatton 1342: if (ancestor)
1.113 kia 1343: {
1344: ancestorType = TtaGetElementType(ancestor);
1.147 vatton 1345: if (ancestorType.ElTypeNum == Template_EL_bag)
1.113 kia 1346: {
1.147 vatton 1347: // only check the use child
1348: if (ancestor != parent)
1349: return FALSE; // let Thot do the job
1350: if (elType.ElSSchema == templateSSchema &&
1351: (elType.ElTypeNum == Template_EL_useSimple ||
1352: elType.ElTypeNum == Template_EL_useEl))
1.116 kia 1353: return FALSE;
1.147 vatton 1354: return !Template_CanInsertElementInBagElement (event->document, elType, ancestor);
1.113 kia 1355: }
1.147 vatton 1356: else if(ancestorType.ElTypeNum == Template_EL_useSimple ||
1357: ancestorType.ElTypeNum == Template_EL_useEl)
1.113 kia 1358: {
1.147 vatton 1359: // only check the bag child @@@ will be check exclude/include later
1.159 vatton 1360: //if (ancestor != parent)
1361: // return FALSE; // let Thot do the job
1.113 kia 1362: types = GetAttributeStringValueFromNum(ancestor, Template_ATTR_currentType, NULL);
1.128 kia 1363: b = Template_CanInsertElementInUse(event->document, elType, types, parent, event->position);
1364: TtaFreeMemory(types);
1.115 kia 1365: return !b;
1.113 kia 1366:
1367: }
1368: }
1.115 kia 1369:
1.147 vatton 1370: if (elType.ElSSchema == templateSSchema && elType.ElTypeNum == Template_EL_TEXT_UNIT)
1.115 kia 1371: {
1372: return FALSE;
1373: }
1374:
1.113 kia 1375: // Can not insert.
1376: return TRUE;
1.101 kia 1377: #endif /* TEMPLATES*/
1.102 vatton 1378: return FALSE;
1.101 kia 1379: }
1380:
1381: /*----------------------------------------------------------------------
1382: TemplateElementWillBeDeleted
1383: Processed when an element will be deleted in a template context.
1384: ----------------------------------------------------------------------*/
1385: ThotBool TemplateElementWillBeDeleted (NotifyElement *event)
1386: {
1.107 kia 1387: #ifdef TEMPLATES
1388: Document doc = event->document;
1389: Element elem = event->element;
1.158 kia 1390: Element xtElem, parent, sibling;
1.117 kia 1391: ElementType xtType, elType;
1.107 kia 1392: char* type;
1393: Declaration dec;
1.115 kia 1394: SSchema templateSSchema;
1.107 kia 1395: XTigerTemplate t;
1.156 vatton 1396: ThotBool selparent = FALSE;
1.107 kia 1397:
1.115 kia 1398: if(event->info==1)
1399: return FALSE;
1400:
1.112 vatton 1401: if (!TtaGetDocumentAccessMode(event->document))
1.110 kia 1402: return TRUE;
1403:
1.138 vatton 1404: templateSSchema = TtaGetSSchema ("Template", event->document);
1.107 kia 1405: if (templateSSchema == NULL)
1406: return FALSE; // let Thot do the job
1.122 kia 1407:
1.107 kia 1408: xtElem = GetFirstTemplateParentElement(elem);
1.112 vatton 1409: if (xtElem)
1.107 kia 1410: {
1411: xtType = TtaGetElementType(xtElem);
1.117 kia 1412:
1.134 kia 1413: t = GetXTigerTemplate(DocumentMeta[doc]->template_url);
1.109 kia 1414:
1.112 vatton 1415: if (xtType.ElTypeNum==Template_EL_bag)
1.117 kia 1416: {
1417: elType = TtaGetElementType(elem);
1418: if(elType.ElSSchema==templateSSchema &&
1419: (elType.ElTypeNum==Template_EL_useSimple || elType.ElTypeNum==Template_EL_useEl))
1420: {
1421: // Remove element manually.
1422: TtaOpenUndoSequence(doc, elem, elem, 0, 0);
1423: TtaRegisterElementDelete(elem, doc);
1424: TtaDeleteTree(elem, doc);
1425: TtaCloseUndoSequence(doc);
1426: return TRUE;
1427: }
1428: else
1429: return FALSE; // xt:bag always allow remove children.
1430: }
1.112 vatton 1431: else if (xtType.ElTypeNum==Template_EL_useSimple || xtType.ElTypeNum==Template_EL_useEl)
1.107 kia 1432: {
1.109 kia 1433: parent = TtaGetParent(elem);
1.117 kia 1434: if (xtElem!=parent)
1435: {
1436: type = GetAttributeStringValueFromNum(xtElem, Template_ATTR_currentType, NULL);
1437: dec = Template_GetDeclaration(t, type);
1438: TtaFreeMemory(type);
1439:
1440: if (dec && dec->nature == XmlElementNat)
1441: return FALSE; // Can remove element only if in xt:use current type is base language element.
1442: else
1443: return TRUE;
1.107 kia 1444: }
1.109 kia 1445: }
1.112 vatton 1446: else if (xtType.ElTypeNum==Template_EL_repeat)
1.109 kia 1447: {
1.156 vatton 1448: sibling = TtaGetSuccessor (elem);
1449: if (sibling == NULL)
1450: {
1451: // there is no next element
1452: sibling = TtaGetPredecessor (elem);
1453: if (sibling == NULL)
1454: selparent = TRUE;
1455: }
1.109 kia 1456: TtaRegisterElementDelete(elem, doc);
1457: TtaDeleteTree(elem, doc);
1458: InstantiateRepeat(t, xtElem, doc, TRUE);
1.156 vatton 1459: if (selparent)
1460: // look for the new sibling
1461: sibling = TtaGetFirstChild (parent);
1462: if (sibling)
1463: TtaSelectElement(doc, sibling);
1.151 quint 1464: else
1.156 vatton 1465: TtaSelectElement(doc, parent);
1.109 kia 1466: return TRUE;
1.107 kia 1467: }
1468: }
1.109 kia 1469:
1470: //TODO Test if current element is use or repeat.
1471: // Because if an element is delete and it is the unique child of its parent,
1472: // the parent intends to destroy itself.
1473:
1.107 kia 1474: return TRUE;
1475: #else /* TEMPLATES */
1.101 kia 1476: return FALSE;
1.107 kia 1477: #endif /* TEMPLATES */
1.101 kia 1478: }
1479:
1.109 kia 1480: /*----------------------------------------------------------------------
1481: CurrentTypeWillBeExported
1482: Check if the xt:currentType attribute can be exported
1483: ----------------------------------------------------------------------*/
1484: ThotBool CurrentTypeWillBeExported (NotifyAttribute *event)
1485: {
1486: #ifdef TEMPLATES
1.110 kia 1487:
1.112 vatton 1488: if (!TtaGetDocumentAccessMode(event->document))
1.110 kia 1489: return TRUE;
1490:
1.112 vatton 1491: if (IsTemplateDocument(event->document))
1.109 kia 1492: return TRUE;
1493: #endif /* TEMPLATES */
1494: return FALSE;
1495: }
1.127 kia 1496:
1497: /*----------------------------------------------------------------------
1498: TemplateAttrInMenu
1499: Called by Thot when building the Attributes menu for template elements.
1500: ----------------------------------------------------------------------*/
1501: ThotBool TemplateAttrInMenu (NotifyAttribute * event)
1502: {
1503: #ifdef TEMPLATES
1504: // Prevent from showing attributes for template instance but not templates.
1505: if(IsTemplateInstanceDocument(event->document))
1506: return TRUE;
1507: else
1508: #endif /* TEMPLATES */
1509: return FALSE;
1510: }
1.160 kia 1511:
Webmaster