Annotation of Amaya/amaya/templates.c, revision 1.108
1.1 cvs 1: /*
2: *
1.100 vatton 3: * COPYRIGHT INRIA and W3C, 1996-2007
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.52 vatton 16:
1.99 kia 17: #include "undo.h"
18:
1.90 kia 19: #include "containers.h"
20: #include "Elemlist.h"
1.92 kia 21: #include "templates.h"
22:
1.90 kia 23:
1.46 vatton 24: #ifdef TEMPLATES
25: #include "Template.h"
1.52 vatton 26: #include "templateDeclarations.h"
1.89 kia 27: #include "templateUtils_f.h"
1.52 vatton 28:
1.69 quint 29: #include "mydictionary_f.h"
1.67 quint 30: #include "templateLoad_f.h"
31: #include "templateDeclarations_f.h"
1.76 vatton 32: #include "templateInstantiate_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"
37:
1.52 vatton 38: #endif /* TEMPLATES */
1.1 cvs 39:
1.87 kia 40:
41: #include "fetchXMLname_f.h"
1.83 kia 42: #include "MENUconf.h"
43:
1.87 kia 44:
1.83 kia 45: /* Paths from which looking for templates.*/
46: static Prop_Templates_Path *TemplateRepositoryPaths;
47:
1.87 kia 48:
49: /*----------------------------------------------------------------------
50: IsTemplateInstanceDocument: Test if a document is a template instance
51: doc : Document to test
52: return : TRUE if the document is a template instance
53: ----------------------------------------------------------------------*/
1.106 vatton 54: ThotBool IsTemplateInstanceDocument(Document doc)
55: {
1.87 kia 56: #ifdef TEMPLATES
57: return (DocumentMeta[doc]!=NULL) && (DocumentMeta[doc]->template_url!=NULL);
58: #else /* TEMPLATES */
1.88 cvs 59: return FALSE;
1.87 kia 60: #endif /* TEMPLATES */
61: }
62:
1.83 kia 63: /*----------------------------------------------------------------------
1.108 ! vatton 64: AllocTemplateRepositoryListElement: allocates an element for the list
! 65: of template repositories.
1.83 kia 66: path : path of the new element
67: return : address of the new element
68: ----------------------------------------------------------------------*/
69: void* AllocTemplateRepositoryListElement (const char* path, void* prevElement)
70: {
71: Prop_Templates_Path *element = (Prop_Templates_Path*)TtaGetMemory (sizeof(Prop_Templates_Path));
72: element->NextPath = NULL;
73: strcpy (element->Path, path);
74: if (prevElement)
75: {
76: element->NextPath = ((Prop_Templates_Path*)prevElement)->NextPath;
77: ((Prop_Templates_Path*)prevElement)->NextPath = element;
78: }
79: return element;
80: }
81:
82:
83: /*----------------------------------------------------------------------
84: FreeTemplateRepositoryList: Free the list of template repositories.
85: list : address of the list (address of the first element).
86: ----------------------------------------------------------------------*/
87: void FreeTemplateRepositoryList (void* list)
88: {
89: Prop_Templates_Path** l = (Prop_Templates_Path**) list;
90:
91: Prop_Templates_Path* element = *l;
92: l = NULL;
93: while (element)
94: {
95: Prop_Templates_Path* next = element->NextPath;
96: TtaFreeMemory(element);
97: element = next;
98: }
99: }
100:
101: /*----------------------------------------------------------------------
102: CopyTemplateRepositoryList: Copy a list of template repositories.
103: src : address of the list (address of the first element).
104: dst : address where copy the list
105: ----------------------------------------------------------------------*/
1.91 vatton 106: static void CopyTemplateRepositoryList (const Prop_Templates_Path** src,
107: Prop_Templates_Path** dst)
1.83 kia 108: {
109: Prop_Templates_Path *element=NULL, *current=NULL;
110:
111: if(*src!=NULL)
112: {
113: *dst = (Prop_Templates_Path*) TtaGetMemory (sizeof(Prop_Templates_Path));
114: (*dst)->NextPath = NULL;
115: strcpy((*dst)->Path, (*src)->Path);
116:
117: element = (*src)->NextPath;
118: current = *dst;
119: }
120:
1.106 vatton 121: while (element)
122: {
1.83 kia 123: current->NextPath = (Prop_Templates_Path*) TtaGetMemory (sizeof(Prop_Templates_Path));
124: current = current->NextPath;
125: current->NextPath = NULL;
126: strcpy(current->Path, element->Path);
127: element = element->NextPath;
1.106 vatton 128: }
1.83 kia 129: }
130:
131: /*----------------------------------------------------------------------
132: LoadTemplateRepositoryList: Load the list of template repositories.
133: list : address of the list (address of the first element).
134: return : the number of readed repository paths.
135: ----------------------------------------------------------------------*/
136: static int LoadTemplateRepositoryList (Prop_Templates_Path** list)
137: {
138: Prop_Templates_Path *element, *current = NULL;
139: char *path, *homePath;
140: unsigned char *c;
141: int nb = 0;
142: FILE *file;
143:
144: FreeTemplateRepositoryList(list);
145:
146: path = (char *) TtaGetMemory (MAX_LENGTH);
1.86 vatton 147: homePath = TtaGetEnvString ("APP_HOME");
1.106 vatton 148: sprintf (path, "%s%ctemplates.dat", homePath, DIR_SEP);
1.83 kia 149:
150: file = TtaReadOpen ((char *)path);
1.84 kia 151: if (!file)
152: {
153: /* The config file dont exist, create it. */
154: file = TtaWriteOpen ((char *)path);
1.106 vatton 155: fprintf (file, "%s%ctemplate.xtd\n", homePath, DIR_SEP);
1.84 kia 156: TtaWriteClose (file);
157: /* Retry to open it.*/
158: file = TtaReadOpen ((char *)path);
159: }
160:
1.83 kia 161: if (file)
162: {
1.84 kia 163: c = (unsigned char*)path;
164: *c = EOS;
1.83 kia 165: while (TtaReadByte (file, c)){
166: if (*c==13 || *c==EOL)
167: *c = EOS;
168: if (*c==EOS && c!=(unsigned char*)path )
169: {
170: element = (Prop_Templates_Path*) TtaGetMemory (sizeof(Prop_Templates_Path));
171: element->NextPath = NULL;
172: strcpy (element->Path, path);
173:
174: if (*list == NULL)
175: *list = element;
176: else
177: current->NextPath = element;
178: current = element;
179: nb++;
180:
181: c = (unsigned char*) path;
182: *c = EOS;
183: }
184: else
185: c++;
186: }
187: if (c!=(unsigned char*)path && *path!=EOS)
188: {
189: element = (Prop_Templates_Path*) TtaGetMemory (sizeof(Prop_Templates_Path));
190: *(c+1) = EOS;
191: strcpy (element->Path, path);
192: element->NextPath = NULL;
193:
194: if (*list == NULL)
195: *list = element;
196: else
197: current->NextPath = element;
198: nb++;
199: }
200: TtaReadClose (file);
201: }
202: TtaFreeMemory(path);
203: return nb;
204: }
205:
206: /*----------------------------------------------------------------------
207: SaveTemplateRepositoryList: Save the list of template repositories.
208: list : address of the list (address of the first element).
209: ----------------------------------------------------------------------*/
210: static void SaveTemplateRepositoryList (const Prop_Templates_Path** list)
211: {
212: const Prop_Templates_Path *element;
213: char *path, *homePath;
214: unsigned char *c;
215: FILE *file;
216:
217: path = (char *) TtaGetMemory (MAX_LENGTH);
218: homePath = TtaGetEnvString ("APP_HOME");
1.106 vatton 219: sprintf (path, "%s%ctemplates.dat", homePath, DIR_SEP);
1.83 kia 220:
221: file = TtaWriteOpen ((char *)path);
222: c = (unsigned char*)path;
223: *c = EOS;
224: if (file)
225: {
226: element = *list;
227: while (element)
228: {
229: fprintf(file, "%s\n", element->Path);
230: element = element->NextPath;
231: }
232: TtaWriteClose (file);
233: }
234: }
235:
236: /*----------------------------------------------------------------------
237: GetTemplateRepositoryList: Get the list of template repositories from template environment.
238: list : address of the list (address of the first element).
239: ----------------------------------------------------------------------*/
240: void GetTemplateRepositoryList (void* list)
241: {
242: Prop_Templates_Path** l = (Prop_Templates_Path**) list;
243: CopyTemplateRepositoryList((const Prop_Templates_Path**)&TemplateRepositoryPaths, l);
244: }
245:
246: /*----------------------------------------------------------------------
247: SetTemplateRepositoryList: Set the list of template repositories environment.
248: list : address of the list (address of the first element).
249: ----------------------------------------------------------------------*/
250: void SetTemplateRepositoryList (const void* list)
251: {
252: const Prop_Templates_Path** l = (const Prop_Templates_Path**) list;
253: CopyTemplateRepositoryList((const Prop_Templates_Path**)l, &TemplateRepositoryPaths);
254: SaveTemplateRepositoryList((const Prop_Templates_Path**)&TemplateRepositoryPaths);
255: }
256:
257: /*-----------------------------------------------------------------------
258: InitTemplates
259: Initializes the annotation library
260: -----------------------------------------------------------------------*/
261: void InitTemplates ()
262: {
263: TtaSetEnvBoolean ("SHOW_TEMPLATES", TRUE, FALSE);
264: LoadTemplateRepositoryList(&TemplateRepositoryPaths);
265: }
266:
267:
1.1 cvs 268: /*----------------------------------------------------------------------
1.51 francesc 269: NewTemplate: Create the "new document from template" dialog
1.1 cvs 270: ----------------------------------------------------------------------*/
1.18 cvs 271: void NewTemplate (Document doc, View view)
1.1 cvs 272: {
1.51 francesc 273: #ifdef TEMPLATES
1.76 vatton 274: char *templateDir = TtaGetEnvString ("TEMPLATES_DIRECTORY");
275: ThotBool created;
1.28 tollenae 276:
1.76 vatton 277: if (Templates_Dic == NULL)
278: InitializeTemplateEnvironment ();
279: created = CreateNewTemplateDocDlgWX (BaseDialog + OpenTemplate,
1.61 francesc 280: /*TtaGetViewFrame (doc, view)*/NULL, doc,
1.52 vatton 281: TtaGetMessage (AMAYA, AM_NEW_TEMPLATE),templateDir);
1.51 francesc 282:
1.28 tollenae 283: if (created)
1.25 vatton 284: {
1.28 tollenae 285: TtaSetDialoguePosition ();
286: TtaShowDialogue (BaseDialog + OpenTemplate, TRUE);
1.25 vatton 287: }
1.51 francesc 288:
1.52 vatton 289: #endif /* TEMPLATES */
1.1 cvs 290: }
1.25 vatton 291:
1.108 ! vatton 292: /*----------------------------------------------------------------------
! 293: Load a template and create the instance file - update images and
! 294: stylesheets related to the template.
! 295: ----------------------------------------------------------------------*/
! 296: void CreateInstanceOfTemplate (Document doc, char *templatename, char *docname)
! 297: {
! 298: #ifdef TEMPLATES
! 299:
! 300: char *s;
! 301: ThotBool dontReplace = DontReplaceOldDoc;
! 302:
! 303: if (!IsW3Path (docname) && TtaFileExist (docname))
! 304: {
! 305: s = (char *)TtaGetMemory (strlen (docname) +
! 306: strlen (TtaGetMessage (AMAYA, AM_OVERWRITE_CHECK)) + 2);
! 307: sprintf (s, TtaGetMessage (AMAYA, AM_OVERWRITE_CHECK), docname);
! 308: InitConfirm (0, 0, s);
! 309: TtaFreeMemory (s);
! 310: if (!UserAnswer)
! 311: return;
! 312: }
! 313:
! 314: LoadTemplate (0, templatename);
! 315: DontReplaceOldDoc = dontReplace;
! 316: CreateInstance (templatename, docname);
! 317:
! 318: #endif /* TEMPLATES */
! 319: }
! 320:
1.53 vatton 321:
1.52 vatton 322: /*----------------------------------------------------------------------
1.107 kia 323: PreventReloadingTemplate
324: Prevent reloading a template.
325: You must call AllowReloadingTemplate when finish.
326: Usefull for reload an instance without reloading the template.
327: ----------------------------------------------------------------------*/
328: void PreventReloadingTemplate(char* template_url)
329: {
330: #ifdef TEMPLATES
331: XTigerTemplate t = (XTigerTemplate) Dictionary_Get (Templates_Dic, template_url);
332: if(t)
333: t->users++;
334: #endif /* TEMPLATES */
335: }
336:
337: /*----------------------------------------------------------------------
338: AllowReloadingTemplate
339: Allow reloading a template.
340: You must call it after each PreventReloadingTemplate call.
341: ----------------------------------------------------------------------*/
342: void AllowReloadingTemplate(char* template_url)
343: {
344: #ifdef TEMPLATES
345: XTigerTemplate t = (XTigerTemplate) Dictionary_Get (Templates_Dic, template_url);
346: if(t)
347: t->users--;
348: #endif /* TEMPLATES */
349: }
350:
351:
352: /*----------------------------------------------------------------------
1.87 kia 353: giveItems : Lists type items from string
354: example : "one two three" is extracted to {one, two, three}
355: note : item type are setted to SimpleTypeNat
356: text : text from which list items
357: size : size of text in characters
358: items : address of exctracted item list
359: nbitems : items number in items list
1.52 vatton 360: ----------------------------------------------------------------------*/
1.76 vatton 361: void giveItems (char *text, int size, struct menuType **items, int *nbitems)
1.1 cvs 362: {
1.70 quint 363: #ifdef TEMPLATES
1.52 vatton 364: ThotBool inElement = TRUE;
365: struct menuType *menu;
366: char *iter;
367: char temp[128];
368: int i;
369: int labelSize;
1.28 tollenae 370:
1.52 vatton 371: *nbitems = 1;
372: for (i = 0; i < size; i++)
373: {
374: if (isEOSorWhiteSpace (text[i]))
375: {
376: if (inElement)
377: inElement = FALSE;
378: }
379: else if (!inElement)
380: {
381: inElement = TRUE;
382: (*nbitems)++;
383: }
384: }
1.51 francesc 385:
1.76 vatton 386: menu = (struct menuType*) TtaGetMemory (sizeof (struct menuType)* *nbitems);
1.52 vatton 387: iter = text;
388: for (i = 0; i < *nbitems; i++)
389: {
390: labelSize = 0;
391: while (isEOSorWhiteSpace (*iter))
392: iter++;
393:
394: while (!isEOSorWhiteSpace (*iter))
395: {
396: temp[labelSize++] = *iter;
397: iter++;
398: }
399:
400: temp[labelSize] = EOS;
1.76 vatton 401: menu[i].label = (char *) TtaStrdup (temp);
1.68 quint 402: menu[i].type = SimpleTypeNat; /* @@@@@ ???? @@@@@ */
1.52 vatton 403: *items = menu;
404: }
1.70 quint 405: #endif /* TEMPLATES */
1.28 tollenae 406: }
1.37 tollenae 407:
1.70 quint 408: #ifdef TEMPLATES
1.52 vatton 409: /*----------------------------------------------------------------------
410: ----------------------------------------------------------------------*/
411: static char *createMenuString (const struct menuType* items, const int nbItems)
412: {
413: char *result, *iter;
414: int size = 0;
415: int i;
416:
417: for (i=0; i < nbItems; i++)
418: size += 2 + strlen (items[i].label);
419:
1.76 vatton 420: result = (char *) TtaGetMemory (size);
1.52 vatton 421: iter = result;
422: for (i=0; i < nbItems; i++)
423: {
424: *iter = 'B';
425: ++iter;
1.51 francesc 426:
1.52 vatton 427: strcpy (iter, items[i].label);
428: iter += strlen (items[i].label)+1;
429: }
1.51 francesc 430: return result;
1.36 tollenae 431: }
1.71 quint 432: #endif /* TEMPLATES */
1.29 tollenae 433:
1.71 quint 434: /*----------------------------------------------------------------------
435: UseToBeCreated
436: An new use element will be created by the user through some generic editing
437: command
438: -----------------------------------------------------------------------*/
439: ThotBool UseToBeCreated (NotifyElement *event)
440: {
441: #ifdef TEMPLATES
1.75 quint 442: Element el;
1.72 quint 443: Document doc;
444:
445: el = event->element;
446: doc = event->document;
1.101 kia 447:
1.106 vatton 448: #ifdef AMAYA_DEBUG
1.101 kia 449: printf("UseToBeCreated\n");
1.106 vatton 450: #endif /* AMAYA_DEBUG */
1.101 kia 451:
1.72 quint 452: /* is there a limit to the number of elements in the xt:repeat ? */
1.71 quint 453: /* @@@@@ */
1.52 vatton 454: #endif /* TEMPLATES */
1.71 quint 455: return FALSE; /* let Thot perform normal operation */
456: }
457:
458: /*----------------------------------------------------------------------
459: UseCreated
460: A new "use" element has just been created by the user with a generic editing
461: command.
462: -----------------------------------------------------------------------*/
463: void UseCreated (NotifyElement *event)
464: {
465: #ifdef TEMPLATES
466: Document doc;
467: Element el;
468: XTigerTemplate t;
469:
470: doc = event->document;
1.72 quint 471: el = event->element;
472: if (TtaGetFirstChild (el))
473: /* this Use element has already some content. It has already been
474: instanciated */
475: return;
1.87 kia 476: t = (XTigerTemplate) Dictionary_Get (Templates_Dic, DocumentMeta[doc]->template_url);
1.71 quint 477: if (!t)
478: return; // no template ?!?!
1.101 kia 479:
1.76 vatton 480: InstantiateUse (t, el, doc, TRUE);
1.71 quint 481: #endif /* TEMPLATES */
482: }
1.29 tollenae 483:
1.98 kia 484: /*----------------------------------------------------------------------
485: Template_IncrementRepeatOccurNumber
486: Increment the number of occurs of a xt:repeat
487: @param el element (xt:repeat)
488: ----------------------------------------------------------------------*/
489: void Template_IncrementRepeatOccurNumber(Element el)
490: {
491: #ifdef TEMPLATES
492: char* current;
493: char newVal[8];
494: int curVal;
495:
1.104 kia 496: current = GetAttributeStringValueFromNum(el, Template_ATTR_currentOccurs, NULL);
497: if(current)
498: {
499: curVal = atoi(current);
500: curVal++;
501: TtaFreeMemory(current);
502: sprintf(newVal, "%d", curVal);
503: SetAttributeStringValue(el, Template_ATTR_currentOccurs, newVal);
504: }
1.98 kia 505: #endif /* TEMPLATES */
506: }
507:
508: /*----------------------------------------------------------------------
509: Template_DecrementRepeatOccurNumber
510: Decrement the number of occurs of a xt:repeat
511: @param el element (xt:repeat)
512: ----------------------------------------------------------------------*/
513: void Template_DecrementRepeatOccurNumber(Element el)
514: {
515: #ifdef TEMPLATES
516: char* current;
517: char newVal[8];
518: int curVal;
519:
1.104 kia 520: current = GetAttributeStringValueFromNum(el, Template_ATTR_currentOccurs, NULL);
521: if(current)
522: {
523: curVal = atoi(current);
524: curVal--;
525: TtaFreeMemory(current);
526: sprintf(newVal, "%d", curVal);
527: SetAttributeStringValue(el, Template_ATTR_currentOccurs, newVal);
528: }
1.98 kia 529: #endif /* TEMPLATES */
530: }
531:
1.89 kia 532:
1.98 kia 533: /*----------------------------------------------------------------------
534: Template_CanInsertRepeatChild
535: Test if a xt:repeat child can be inserted (number between params min and max).
536: @param el element (xt:repeat) to test
537: @return True if an element can be inserted.
538: ----------------------------------------------------------------------*/
539: ThotBool Template_CanInsertRepeatChild(Element el)
540: {
541: #ifdef TEMPLATES
542: char* max;
543: char* current;
544: int maxVal, curVal;
1.104 kia 545: Element child;
1.98 kia 546:
1.104 kia 547: max = GetAttributeStringValueFromNum(el, Template_ATTR_maxOccurs, NULL);
1.105 vatton 548: if (max)
1.104 kia 549: {
1.105 vatton 550: if(!strcmp(max, "*"))
551: {
552: TtaFreeMemory(max);
553: return TRUE;
554: }
555: maxVal = atoi (max);
556: TtaFreeMemory (max);
1.104 kia 557:
558: current = GetAttributeStringValueFromNum(el, Template_ATTR_currentOccurs, NULL);
1.105 vatton 559: if (current)
1.104 kia 560: {
1.105 vatton 561: curVal = atoi (current);
562: TtaFreeMemory (current);
1.104 kia 563: }
564: else
565: {
566: curVal = 0;
1.105 vatton 567: for (child = TtaGetFirstChild(el); child; TtaNextSibling(&child))
1.104 kia 568: {
569: curVal++;
570: }
571: }
572:
573: return curVal<maxVal;
574: }
575: else
1.98 kia 576: return TRUE;
577: #endif /* TEMPLATES */
578: return FALSE;
579: }
1.96 kia 580:
1.89 kia 581:
582: /*----------------------------------------------------------------------
583: Template_InsertRepeatChildAfter
584: Insert a child to a xt:repeat
585: The decl parameter must be valid and will not be verified. It must be a
586: direct child element or the "use in the use" for union elements.
587: @param el element (xt:repeat) in which insert a new element
588: @param decl Template declaration of the element to insert
589: @param elPrev Element (xt:use) after which insert the new elem, NULL if first.
590: @return The inserted element
591: ----------------------------------------------------------------------*/
592: Element Template_InsertRepeatChildAfter(Document doc, Element el, Declaration decl, Element elPrev)
593: {
594: #ifdef TEMPLATES
595: Element useFirst; /* First xt:use of the repeat.*/
596: Element use; /* xt:use to insert.*/
597: ElementType useType; /* type of xt:use.*/
598:
599: /* Copy xt:use with xt:types param */
600: useFirst = TtaGetFirstChild(el);
601: useType = TtaGetElementType(useFirst);
602: use = TtaCopyElement(useFirst, doc, doc, el);
603:
604: Template_InsertUseChildren(doc, use, decl);
605:
606: /* insert it */
607: if(elPrev)
608: {
609: TtaInsertSibling(use, elPrev, FALSE, doc);
610: }
611: else
612: {
613: TtaInsertSibling(use, useFirst, TRUE, doc);
614: }
1.99 kia 615:
616: TtaRegisterElementCreate(use, doc);
1.97 kia 617:
1.98 kia 618: Template_IncrementRepeatOccurNumber(el);
619:
1.89 kia 620: return use;
621:
1.93 cvs 622: #else /* TEMPLATES */
623: return NULL;
1.89 kia 624: #endif /* TEMPLATES */
625: }
626:
627: /*----------------------------------------------------------------------
628: Template_InsertRepeatChild
629: Insert a child to a xt:repeat
630: The decl parameter must be valid and will not be verified. It must be a
631: direct child element or the "use in the use" for union elements.
632: @param el element (repeat) in which insert a new element
633: @param decl Template declaration of the element to insert
634: @param pos Position of insertion (0 before all, 1 after first ... -1 after all)
635: @return The inserted element
636: ----------------------------------------------------------------------*/
637: Element Template_InsertRepeatChild(Document doc, Element el, Declaration decl, int pos)
638: {
639: if(pos==0)
640: {
641: return Template_InsertRepeatChildAfter(doc, el, decl, NULL);
642: }
643: else if(pos==-1)
644: {
645: return Template_InsertRepeatChildAfter(doc, el, decl, TtaGetLastChild(el));
646: }
647: else
648: {
649: Element elem = TtaGetFirstChild(el);
650: pos--;
651: while(pos>0)
652: {
653: TtaNextSibling(&elem);
654: pos--;
655: }
656: return Template_InsertRepeatChildAfter(doc, el, decl, elem);
657: }
658: }
659:
1.92 kia 660: #ifdef TEMPLATES
1.99 kia 661: /*----------------------------------------------------------------------
662: QueryMenu
663: Show a context menu to query a choice.
664: @param items space-separated choice list string.
665: @return The choosed item 0-based index or -1 if none.
666: ----------------------------------------------------------------------*/
1.89 kia 667: static int QueryMenu(Document doc, char* items)
668: {
669: int nbitems, size;
670: struct menuType *itemlist;
671: char *menuString;
672:
673: size = strlen(items);
674: giveItems (items, size, &itemlist, &nbitems);
675: menuString = createMenuString (itemlist, nbitems);
676: TtaNewScrollPopup (BaseDialog + OptionMenu, TtaGetViewFrame (doc, 1), NULL,
677: nbitems, menuString , NULL, false, 'L');
678: TtaFreeMemory (menuString);
679: ReturnOption = -1;
680: TtaShowDialogue (BaseDialog + OptionMenu, FALSE);
681: TtaWaitShowProcDialogue ();
682: TtaDestroyDialogue (BaseDialog + OptionMenu);
683: TtaFreeMemory (itemlist);
684: return ReturnOption;
685: }
686:
1.99 kia 687: /*----------------------------------------------------------------------
688: QueryStringFromMenu
689: Show a context menu to query a choice.
690: @param items space-separated choice list string.
691: @return The choosed item string or NULL if none.
692: ----------------------------------------------------------------------*/
1.90 kia 693: static char* QueryStringFromMenu(Document doc, char* items)
694: {
695: int nbitems, size;
696: struct menuType *itemlist;
697: char *menuString;
698: char *result = NULL;
699:
700: size = strlen(items);
701: giveItems (items, size, &itemlist, &nbitems);
702: menuString = createMenuString (itemlist, nbitems);
703: TtaNewScrollPopup (BaseDialog + OptionMenu, TtaGetViewFrame (doc, 1), NULL,
704: nbitems, menuString , NULL, false, 'L');
705: TtaFreeMemory (menuString);
706: ReturnOption = -1;
707: TtaShowDialogue (BaseDialog + OptionMenu, FALSE);
708: TtaWaitShowProcDialogue ();
709: TtaDestroyDialogue (BaseDialog + OptionMenu);
710:
711: if(ReturnOption!=-1)
712: {
713: result = TtaStrdup(itemlist[ReturnOption].label);
714: }
715:
716: TtaFreeMemory (itemlist);
717: return result;
718: }
1.92 kia 719: #endif /* TEMPLATES */
1.90 kia 720:
1.56 francesc 721: /*----------------------------------------------------------------------
1.79 quint 722: RepeatButtonClicked
1.89 kia 723: Called when a repeat button is clicked.
724: Can be called for useEl, useSimple or repeat.
725: If called for useEl or useSimple, the new element must be added after.
726: If called for repeat, the element must be added before all.
727:
1.56 francesc 728: Shows a menu with all the types that can be used in a use element.
729: ----------------------------------------------------------------------*/
1.79 quint 730: ThotBool RepeatButtonClicked (NotifyElement *event)
1.56 francesc 731: {
732: #ifdef TEMPLATES
1.89 kia 733: Document doc = event->document;
734: Element el = event->element;
735: ElementType elType;
1.90 kia 736: XTigerTemplate t;
737: Declaration decl;
738: Element repeatEl = el;
739: Element firstEl;
740: Element newEl = NULL;
1.89 kia 741: char* types;
1.90 kia 742: ThotBool oldStructureChecking;
1.95 kia 743: View view;
1.104 kia 744: char* listtypes;
745: char* result;
746:
1.89 kia 747:
1.95 kia 748: TtaGetActiveView (&doc, &view);
749: if (view != 1)
750: return FALSE; /* let Thot perform normal operation */
751:
1.89 kia 752: TtaCancelSelection(doc);
1.90 kia 753:
754: t = (XTigerTemplate) Dictionary_Get (Templates_Dic, DocumentMeta[doc]->template_url);
1.89 kia 755: elType = TtaGetElementType(el);
756: while(elType.ElTypeNum!=Template_EL_repeat)
757: {
1.90 kia 758: repeatEl = TtaGetParent(repeatEl);
759: if(repeatEl==NULL)
1.89 kia 760: break;
1.90 kia 761: elType = TtaGetElementType(repeatEl);
1.89 kia 762: }
1.90 kia 763: if(repeatEl)
1.89 kia 764: {
1.98 kia 765: if(Template_CanInsertRepeatChild(repeatEl))
1.90 kia 766: {
1.98 kia 767: firstEl = TtaGetFirstChild(repeatEl);
1.104 kia 768: types = GetAttributeStringValueFromNum(firstEl, Template_ATTR_types, NULL);
769: if(types)
1.90 kia 770: {
1.104 kia 771: listtypes = Template_ExpandTypes(t, types);
772: result = QueryStringFromMenu(doc, listtypes);
773: if(result)
1.98 kia 774: {
1.104 kia 775: decl = Template_GetDeclaration(t, result);
776: if(decl)
777: {
778: /* Prepare insertion.*/
779: oldStructureChecking = TtaGetStructureChecking (doc);
780: TtaSetStructureChecking (FALSE, doc);
781: TtaOpenUndoSequence(doc, NULL, NULL, 0, 0);
782:
783: /* Insert. */
784: if(el==repeatEl)
785: newEl = Template_InsertRepeatChildAfter(doc, repeatEl, decl, NULL);
786: else
787: newEl = Template_InsertRepeatChildAfter(doc, repeatEl, decl, el);
788:
789: /* Finish insertion.*/
790: TtaCloseUndoSequence(doc);
791: TtaSetStructureChecking (oldStructureChecking, doc);
1.99 kia 792:
1.104 kia 793: firstEl = GetFirstEditableElement(newEl);
794: if(firstEl)
795: {
796: TtaSelectElement (doc, firstEl);
797: TtaSetStatusSelectedElement(doc, view, firstEl);
798: }
799: else
800: {
801: TtaSelectElement (doc, newEl);
802: TtaSetStatusSelectedElement(doc, view, newEl);
803: }
1.98 kia 804: }
805: }
1.90 kia 806: }
1.104 kia 807: TtaFreeMemory(types);
1.98 kia 808: TtaFreeMemory(listtypes);
809: TtaFreeMemory(result);
810: }
811: else /* if(Template_CanInsertRepeatChild(repeatEl)) */
812: {
813: TtaSetStatus(doc, view, TtaGetMessage (AMAYA, AM_NUMBER_OCCUR_HAVE_MAX), NULL);
1.90 kia 814: }
1.89 kia 815: }
1.77 vatton 816: return TRUE; /* don't let Thot perform normal operation */
1.57 francesc 817: #endif /* TEMPLATES */
1.94 kia 818: return TRUE;
819: }
820:
821: /*----------------------------------------------------------------------
822: UseButtonClicked
823: Shows a menu with all the types that can be used in a use element.
824: ----------------------------------------------------------------------*/
825: ThotBool UseButtonClicked (NotifyElement *event)
826: {
827: #ifdef TEMPLATES
828: Document doc = event->document;
829: Element el = event->element;
1.99 kia 830: Element child;
1.94 kia 831: ElementType elType;
832: XTigerTemplate t;
833: Declaration decl;
834: Element firstEl;
835: Element newEl = NULL;
836: char* types;
837: ThotBool oldStructureChecking;
1.95 kia 838: View view;
1.104 kia 839: char* listtypes;
840: char* result;
1.95 kia 841:
842: TtaGetActiveView (&doc, &view);
843: if (view != 1)
844: return FALSE; /* let Thot perform normal operation */
1.94 kia 845:
846: TtaCancelSelection(doc);
847:
848: t = (XTigerTemplate) Dictionary_Get (Templates_Dic, DocumentMeta[doc]->template_url);
849: if (!t)
850: return FALSE; /* let Thot perform normal operation */
851: elType = TtaGetElementType(el);
852:
853: firstEl = TtaGetFirstChild(el);
854: if(firstEl)
855: {
856: RepeatButtonClicked(event);
857: }
858: else
859: {
1.104 kia 860: types = GetAttributeStringValueFromNum(el, Template_ATTR_types, NULL);
861: if(types)
1.94 kia 862: {
1.104 kia 863: listtypes = Template_ExpandTypes(t, types);
864: result = QueryStringFromMenu(doc, listtypes);
865: if(result)
1.94 kia 866: {
1.104 kia 867: decl = Template_GetDeclaration(t, result);
868: if(decl)
1.99 kia 869: {
1.104 kia 870: /* Prepare insertion.*/
871: oldStructureChecking = TtaGetStructureChecking (doc);
872: TtaSetStructureChecking (FALSE, doc);
873: TtaOpenUndoSequence(doc, NULL, NULL, 0, 0);
874:
875: /* Insert */
876: newEl = Template_InsertUseChildren(doc, el, decl);
877:
878: for(child = TtaGetFirstChild(newEl); child; TtaNextSibling(&child))
879: {
880: TtaRegisterElementCreate(child, doc);
881: }
882:
883: TtaChangeTypeOfElement(el, doc, Template_EL_useSimple);
884: TtaRegisterElementTypeChange(el, Template_EL_useEl, doc);
885:
886: /* Finish insertion. */
887: TtaCloseUndoSequence(doc);
888: TtaSetStructureChecking (oldStructureChecking, doc);
889:
890: firstEl = GetFirstEditableElement(newEl);
891: if(firstEl)
892: {
893: TtaSelectElement (doc, firstEl);
894: TtaSetStatusSelectedElement(doc, view, firstEl);
895: }
896: else
897: {
898: TtaSelectElement (doc, newEl);
899: TtaSetStatusSelectedElement(doc, view, newEl);
900: }
1.98 kia 901: }
1.94 kia 902: }
903: }
1.104 kia 904: TtaFreeMemory(types);
1.94 kia 905: TtaFreeMemory(listtypes);
906: TtaFreeMemory(result);
907: }
908:
909: return TRUE;
910: #endif /* TEMPLATES */
1.56 francesc 911: return TRUE;
912: }
1.64 francesc 913:
1.89 kia 914:
1.103 kia 915: /*----------------------------------------------------------------------
916: UseSimpleButtonClicked
917: ----------------------------------------------------------------------*/
918: ThotBool UseSimpleButtonClicked (NotifyElement *event)
919: {
920: #ifdef TEMPLATES
921: ElementType parentType = TtaGetElementType(TtaGetParent(event->element));
922: if(parentType.ElTypeNum == Template_EL_repeat)
923: return RepeatButtonClicked(event);
924: #endif /* TEMPLATES */
925: return FALSE;
926: }
1.94 kia 927:
928: /*----------------------------------------------------------------------
929: OptionButtonClicked
930: ----------------------------------------------------------------------*/
931: ThotBool OptionButtonClicked (NotifyElement *event)
932: {
933: #ifdef TEMPLATES
934: Element child, grandChild, next;
935: ElementType elType, elType1;
936: Document doc;
937: XTigerTemplate t;
938: View view;
939:
940: TtaGetActiveView (&doc, &view);
941: if (view != 1)
942: return FALSE; /* let Thot perform normal operation */
943: doc = event->document;
944: child = TtaGetFirstChild (event->element);
945: if (!child)
946: return FALSE; /* let Thot perform normal operation */
947: elType = TtaGetElementType (child);
948: elType1 = TtaGetElementType (event->element);
949: if ((elType.ElTypeNum != Template_EL_useEl &&
950: elType.ElTypeNum != Template_EL_useSimple) ||
951: elType.ElSSchema != elType1.ElSSchema)
952: return FALSE;
953:
954: TtaCancelSelection (doc);
955: grandChild = TtaGetFirstChild (child);
956: if (!grandChild)
957: /* the "use" element is empty. Instantiate it */
958: {
959: t = (XTigerTemplate) Dictionary_Get (Templates_Dic, DocumentMeta[doc]->template_url);
960: if (!t)
961: return FALSE; // no template ?!?!
962: InstantiateUse (t, child, doc, TRUE);
963: }
964: else
965: /* remove the content of the "use" element */
966: {
967: do
968: {
969: next = grandChild;
970: TtaNextSibling (&next);
971: TtaDeleteTree (grandChild, doc);
972: grandChild = next;
973: }
974: while (next);
975: }
976: TtaSelectElement (doc, event->element);
977: return TRUE; /* don't let Thot perform normal operation */
978: #endif /* TEMPLATES */
979: return TRUE;
980: }
981:
982:
983:
1.66 vatton 984: /*----------------------------------------------------------------------
1.108 ! vatton 985: OpeningInstance checks if it is a template instance needs.
! 986: If it's an instance and the template is not loaded, load it into a
! 987: temporary file
1.66 vatton 988: ----------------------------------------------------------------------*/
1.76 vatton 989: void OpeningInstance (char *fileName, Document doc)
1.65 francesc 990: {
991: #ifdef TEMPLATES
1.76 vatton 992: XTigerTemplate t;
1.103 kia 993: char *content, *ptr, *begin;
1.76 vatton 994: gzFile stream;
995: char buffer[2000];
1.77 vatton 996: int res;
1.65 francesc 997:
1.76 vatton 998: stream = TtaGZOpen (fileName);
999: if (stream != 0)
1.65 francesc 1000: {
1.76 vatton 1001: res = gzread (stream, buffer, 1999);
1002: if (res >= 0)
1.65 francesc 1003: {
1.81 vatton 1004: buffer[res] = EOS;
1.103 kia 1005: begin = strstr (buffer, "<?xtiger");
1006:
1007: if(begin)
1008: {
1009: // Search for template version
1010: ptr = strstr (begin, "templateVersion");
1011: if (ptr)
1012: ptr = strstr (ptr, "=");
1013: if (ptr)
1014: ptr = strstr (ptr, "\"");
1015: if (ptr)
1016: {
1017: // template URI
1018: content = &ptr[1];
1019: ptr = strstr (content, "\"");
1020: }
1021: if (ptr)
1022: {
1023: *ptr = EOS;
1024: //Get now the template URI
1025: DocumentMeta[doc]->template_version = TtaStrdup (content);
1026: *ptr = '"';
1027: }
1028:
1029: // Search for template uri
1030: ptr = strstr (begin, "template");
1031: if (ptr && ptr[8] != 'V')
1032: ptr = strstr (ptr, "=");
1033: if (ptr)
1034: ptr = strstr (ptr, "\"");
1035: if (ptr)
1036: {
1037: // template URI
1038: content = &ptr[1];
1039: ptr = strstr (content, "\"");
1040: }
1041: if (ptr)
1042: {
1043: *ptr = EOS;
1044: //Get now the template URI
1045: DocumentMeta[doc]->template_url = TtaStrdup (content);
1046: if (Templates_Dic == NULL)
1047: InitializeTemplateEnvironment ();
1048: t = (XTigerTemplate) Dictionary_Get (Templates_Dic, content);
1049: if (!t)
1050: {
1.108 ! vatton 1051: LoadTemplate (doc, content);
1.103 kia 1052: t = (XTigerTemplate) Dictionary_Get (Templates_Dic, content);
1053: }
1054: AddUser (t);
1055: *ptr = '"';
1056: }
1057: }
1.65 francesc 1058: }
1059: }
1.76 vatton 1060: TtaGZClose (stream);
1.65 francesc 1061: #endif /* TEMPLATES */
1062: }
1063:
1.64 francesc 1064: /*----------------------------------------------------------------------
1.65 francesc 1065: ClosingInstance
1.64 francesc 1066: Callback called before closing a document. Checks for unused templates.
1067: ----------------------------------------------------------------------*/
1.65 francesc 1068: ThotBool ClosingInstance(NotifyDialog* dialog)
1.64 francesc 1069: {
1.65 francesc 1070: #ifdef TEMPLATES
1071: //If it is a template all has been already freed
1.76 vatton 1072: if (DocumentMeta[dialog->document] == NULL)
1073: return FALSE;
1.65 francesc 1074:
1075: char *turl = DocumentMeta[dialog->document]->template_url;
1.73 vatton 1076: if (turl)
1.104 kia 1077: {
1078: XTigerTemplate t = (XTigerTemplate) Dictionary_Get (Templates_Dic, turl);
1079: if (t)
1080: RemoveUser (t);
1081: TtaFreeMemory (turl);
1082: DocumentMeta[dialog->document]->template_url = NULL;
1083: }
1084:
1085: if(DocumentMeta[dialog->document]->template_version)
1086: {
1087: TtaFreeMemory(DocumentMeta[dialog->document]->template_version);
1088: DocumentMeta[dialog->document]->template_version = NULL;
1089: }
1.65 francesc 1090: #endif /* TEMPLATES */
1091: return FALSE;
1.64 francesc 1092: }
1.87 kia 1093:
1094:
1095: /*----------------------------------------------------------------------
1096: GetFirstTemplateParentElement
1097: Return the first element wich has "Template" as SShema name or null if none.
1098: ----------------------------------------------------------------------*/
1099: ThotBool IsTemplateElement(Element elem)
1100: {
1101: #ifdef TEMPLATES
1102: return strcmp(TtaGetSSchemaName(TtaGetElementType(elem).ElSSchema)
1103: , TEMPLATE_SSHEMA_NAME)==0;
1104: #else
1105: return FALSE;
1106: #endif /* TEMPLATES */
1107: }
1108:
1109:
1110: /*----------------------------------------------------------------------
1111: GetFirstTemplateParentElement
1112: Return the first element wich has "Template" as SShema name or null if none.
1113: ----------------------------------------------------------------------*/
1114: Element GetFirstTemplateParentElement(Element elem)
1115: {
1116: #ifdef TEMPLATES
1117: elem = TtaGetParent(elem);
1118: while(elem!=NULL && strcmp(TtaGetSSchemaName(TtaGetElementType(elem).ElSSchema)
1119: , TEMPLATE_SSHEMA_NAME)!=0)
1120: {
1121: elem = TtaGetParent(elem);
1122: }
1123: return elem;
1124: #else
1125: return NULL;
1126: #endif /* TEMPLATES */
1127: }
1.101 kia 1128:
1.103 kia 1129:
1.101 kia 1130: /*----------------------------------------------------------------------
1.102 vatton 1131: TemplateElementWillBeCreated
1.101 kia 1132: Processed when an element will be created in a template context.
1133: ----------------------------------------------------------------------*/
1.102 vatton 1134: ThotBool TemplateElementWillBeCreated (NotifyElement *event)
1.101 kia 1135: {
1.103 kia 1136: #ifdef TEMPLATES
1137: ElementType elType = event->elementType;
1138: Element parent = event->element;
1139: ElementType parentType = TtaGetElementType(parent);
1.104 kia 1140: // Element ancestor;
1141: // ElementType ancestorType;
1.103 kia 1142:
1.102 vatton 1143: SSchema templateSSchema = TtaGetSSchema ("Template", event->document);
1.101 kia 1144:
1.102 vatton 1145: if (templateSSchema == NULL)
1146: return FALSE; // let Thot do the job
1.103 kia 1147:
1.106 vatton 1148: #ifdef AMAYA_DEBUG
1.103 kia 1149: printf("TemplateElementWillBeCreated %s:%s\n", TtaGetSSchemaName(elType.ElSSchema), TtaGetElementTypeName(elType));
1150: printf(" ^^ %s:%s\n", TtaGetSSchemaName(parentType.ElSSchema), TtaGetElementTypeName(parentType));
1.106 vatton 1151: #endif /* AMAYA_DEBUG */
1.103 kia 1152: return FALSE;
1153:
1154: //
1155: // // A xt:use within a xt:repeat
1156: // if((elType.ElTypeNum==Template_EL_useSimple || elType.ElTypeNum==Template_EL_useEl) && parentType.ElTypeNum==Template_EL_repeat)
1157: // {
1158: // printf(" Intend to insert xt:repeat element\n");
1159: // return !Template_CanInsertRepeatChild(parent);
1160: // }
1161: // else
1162: // {
1163: // ancestor = parent;
1164: // while (ancestor)
1165: // {
1166: // ancestorType = TtaGetElementType(ancestor);
1167: // printf(" >> %s:%s\n", TtaGetSSchemaName(ancestorType.ElSSchema), TtaGetElementTypeName(ancestorType));
1168: // if (ancestorType.ElSSchema == templateSSchema && ancestorType.ElTypeNum == Template_EL_bag)
1169: // {
1.104 kia 1170: // char* types = GetAttributeStringValueFromNum(ancestor, Template_ATTR_types, NULL);
1.103 kia 1171: // ThotBool b = Template_CanInsertElementInBag(event->document, elType, types);
1172: // printf(" Intend to insert xt:bag element : %s\n", b?"TRUE":"FALSE");
1173: // return !b;
1174: // }
1175: // ancestor = TtaGetParent(ancestor);
1176: // }
1177: // }
1178: // // Can not insert.
1179: // return TRUE;
1.101 kia 1180: #endif /* TEMPLATES*/
1.102 vatton 1181: return FALSE;
1.101 kia 1182: }
1183:
1184: /*----------------------------------------------------------------------
1185: TemplateElementWillBeDeleted
1186: Processed when an element will be deleted in a template context.
1187: ----------------------------------------------------------------------*/
1188: ThotBool TemplateElementWillBeDeleted (NotifyElement *event)
1189: {
1.107 kia 1190: #ifdef TEMPLATES
1191: Document doc = event->document;
1192: Element elem = event->element;
1193: Element xtElem, parent;
1194: ElementType xtType;
1195: char* type;
1196: Declaration dec;
1197: SSchema templateSSchema = TtaGetSSchema ("Template", event->document);
1198: XTigerTemplate t;
1199:
1200: printf("TemplateElementWillBeDeleted : %s\n", TtaGetElementTypeName(TtaGetElementType(elem)));
1201:
1202: if (templateSSchema == NULL)
1203: return FALSE; // let Thot do the job
1204:
1.103 kia 1205:
1.107 kia 1206: xtElem = GetFirstTemplateParentElement(elem);
1207: if(xtElem)
1208: {
1209: xtType = TtaGetElementType(xtElem);
1210: if(xtType.ElSSchema==templateSSchema)
1211: {
1212: t = (XTigerTemplate) Dictionary_Get (Templates_Dic, DocumentMeta[doc]->template_url);
1213:
1214: if(xtType.ElTypeNum==Template_EL_bag)
1215: return FALSE; // xt:bag always allow remove children.
1216: else if(xtType.ElTypeNum==Template_EL_useSimple || xtType.ElTypeNum==Template_EL_useEl)
1217: {
1218: parent = TtaGetParent(elem);
1219: if(xtElem==parent){
1220: //TODO replace current xt:use child element by its initial content (reset element)
1221: return TRUE; // Cant remove use direct child. It is mandatory.
1222: }
1223: type = GetAttributeStringValueFromNum(xtElem, Template_ATTR_currentType, NULL);
1224: dec = Template_GetDeclaration(t, type);
1225: TtaFreeMemory(type);
1226: if(dec->nature == XmlElementNat)
1227: return FALSE; // Can remove element only if in xt:use current type is base language element.
1228: else
1229: return TRUE;
1230: }
1231: else if(xtType.ElTypeNum==Template_EL_repeat)
1232: {
1233: printf("Must remove xt:repeat element and validate xt:repeat content.\n");
1234: TtaRemoveTree(elem, doc);
1235: TtaDeleteTree(elem, doc);
1236: //InstantiateRepeat(t, xtType, doc);
1237: }
1238: }
1239: }
1240: return TRUE;
1241: #else /* TEMPLATES */
1.101 kia 1242: return FALSE;
1.107 kia 1243: #endif /* TEMPLATES */
1.101 kia 1244: }
1245:
1246:
Webmaster