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

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

Webmaster