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

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

Webmaster