Annotation of Amaya/amaya/templates.c, revision 1.103

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

Webmaster