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

1.1       cvs         1: /*
                      2:  *
1.27      vatton      3:  *  COPYRIGHT INRIA and W3C, 1996-2005
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.46      vatton     17: #ifdef TEMPLATES
                     18: #include "Template.h"
1.67      quint      19: #include "templates.h"
1.52      vatton     20: #include "templateDeclarations.h"
                     21: 
1.69      quint      22: #include "mydictionary_f.h"
1.67      quint      23: #include "templateLoad_f.h"
                     24: #include "templateDeclarations_f.h"
1.76      vatton     25: #include "templateInstantiate_f.h"
1.28      tollenae   26: #include "appdialogue_wx.h"
1.29      tollenae   27: #include "init_f.h"
1.46      vatton     28: #include "wxdialogapi_f.h"
1.60      francesc   29: #include "AHTURLTools_f.h"
                     30: 
1.52      vatton     31: #endif /* TEMPLATES */
1.1       cvs        32: 
                     33: /*----------------------------------------------------------------------
1.51      francesc   34:   NewTemplate: Create the "new document from template" dialog
1.1       cvs        35:   ----------------------------------------------------------------------*/
1.18      cvs        36: void NewTemplate (Document doc, View view)
1.1       cvs        37: {
1.51      francesc   38: #ifdef TEMPLATES
1.76      vatton     39:   char        *templateDir = TtaGetEnvString ("TEMPLATES_DIRECTORY");
                     40:   ThotBool     created;
1.28      tollenae   41: 
1.76      vatton     42:   if (Templates_Dic == NULL)
                     43:     InitializeTemplateEnvironment ();
                     44:   created = CreateNewTemplateDocDlgWX (BaseDialog + OpenTemplate,
1.61      francesc   45:                                       /*TtaGetViewFrame (doc, view)*/NULL, doc,
1.52      vatton     46:                                       TtaGetMessage (AMAYA, AM_NEW_TEMPLATE),templateDir);
1.51      francesc   47:   
1.28      tollenae   48:   if (created)
1.25      vatton     49:     {
1.28      tollenae   50:       TtaSetDialoguePosition ();
                     51:       TtaShowDialogue (BaseDialog + OpenTemplate, TRUE);
1.25      vatton     52:     }
1.51      francesc   53: 
1.52      vatton     54: #endif /* TEMPLATES */
1.1       cvs        55: }
1.25      vatton     56: 
1.53      vatton     57: /*----------------------------------------------------------------------
                     58:   Load a template and create the instance file - update images and 
                     59:   stylesheets related to the template.
                     60:   ----------------------------------------------------------------------*/
1.61      francesc   61: void CreateInstanceOfTemplate (Document doc, char *templatename, char *docname)
1.53      vatton     62: {
                     63: #ifdef TEMPLATES
                     64: 
1.60      francesc   65:   char *s;
1.65      francesc   66:   ThotBool dontReplace = DontReplaceOldDoc;
1.60      francesc   67: 
                     68:   if (!IsW3Path (docname) && TtaFileExist (docname))
                     69:     {
                     70:       s = (char *)TtaGetMemory (strlen (docname) +
                     71:                                 strlen (TtaGetMessage (AMAYA, AM_OVERWRITE_CHECK)) + 2);
                     72:       sprintf (s, TtaGetMessage (AMAYA, AM_OVERWRITE_CHECK), docname);
                     73:       InitConfirm (0, 0, s);
1.61      francesc   74:       TtaFreeMemory (s);      
1.62      francesc   75:       if (!UserAnswer)
                     76:         return;
                     77:     }    
                     78: 
1.76      vatton     79:   LoadTemplate (0, templatename);
1.65      francesc   80:   DontReplaceOldDoc = dontReplace;
1.76      vatton     81:   CreateInstance (templatename, docname);
1.62      francesc   82:   
1.53      vatton     83: #endif /* TEMPLATES */
                     84: }
                     85: 
1.52      vatton     86: /*----------------------------------------------------------------------
                     87:   ----------------------------------------------------------------------*/
1.76      vatton     88: void giveItems (char *text, int size, struct menuType **items, int *nbitems)
1.1       cvs        89: {
1.70      quint      90: #ifdef TEMPLATES
1.52      vatton     91:        ThotBool         inElement = TRUE;
                     92:   struct menuType *menu;
                     93:   char            *iter;
                     94:        char             temp[128];
                     95:   int              i;
                     96:        int              labelSize;
1.28      tollenae   97: 
1.52      vatton     98:        *nbitems = 1;
                     99:        for (i = 0; i < size; i++)
                    100:     {
                    101:       if (isEOSorWhiteSpace (text[i]))
                    102:         {
                    103:           if (inElement)
                    104:             inElement = FALSE;
                    105:         }
                    106:       else if (!inElement)
                    107:         {
                    108:           inElement = TRUE;
                    109:           (*nbitems)++;
                    110:         }
                    111:     }
1.51      francesc  112: 
1.76      vatton    113:        menu = (struct menuType*) TtaGetMemory (sizeof (struct menuType)* *nbitems);
1.52      vatton    114:        iter = text;
                    115:        for (i = 0; i < *nbitems; i++)
                    116:     {          
                    117:       labelSize = 0;
                    118:       while (isEOSorWhiteSpace (*iter))
                    119:         iter++;
                    120: 
                    121:       while (!isEOSorWhiteSpace (*iter))
                    122:         {
                    123:           temp[labelSize++] = *iter;
                    124:           iter++;
                    125:         }
                    126: 
                    127:       temp[labelSize] = EOS;
1.76      vatton    128:       menu[i].label = (char *) TtaStrdup (temp);
1.68      quint     129:       menu[i].type = SimpleTypeNat;  /* @@@@@ ???? @@@@@ */
1.52      vatton    130:       *items = menu;
                    131:     }
1.70      quint     132: #endif /* TEMPLATES */
1.28      tollenae  133: }
1.37      tollenae  134: 
1.70      quint     135: #ifdef TEMPLATES
1.52      vatton    136: /*----------------------------------------------------------------------
                    137:   ----------------------------------------------------------------------*/
                    138: static char *createMenuString (const struct menuType* items, const int nbItems)
                    139: {
                    140:   char *result, *iter;
                    141:        int   size = 0;
                    142:   int   i;
                    143: 
                    144:        for (i=0; i < nbItems; i++)
                    145:                size += 2 + strlen (items[i].label);
                    146: 
1.76      vatton    147:        result = (char *) TtaGetMemory (size);
1.52      vatton    148:        iter = result;
                    149:        for (i=0; i < nbItems; i++)
                    150:     {
                    151:       *iter = 'B';
                    152:       ++iter;
1.51      francesc  153:                
1.52      vatton    154:       strcpy (iter, items[i].label);
                    155:       iter += strlen (items[i].label)+1;
                    156:     }
1.51      francesc  157:        return result;
1.36      tollenae  158: }
1.71      quint     159: #endif /* TEMPLATES */
1.29      tollenae  160: 
1.71      quint     161: /*----------------------------------------------------------------------
                    162:   UseToBeCreated
                    163:   An new use element will be created by the user through some generic editing
                    164:   command
                    165:   -----------------------------------------------------------------------*/
                    166: ThotBool UseToBeCreated (NotifyElement *event)
                    167: {
                    168: #ifdef TEMPLATES
1.75      quint     169:   Element        el;
1.72      quint     170:        Document       doc;
                    171: 
                    172:   el = event->element;
                    173:   doc = event->document;
                    174:   /* is there a limit to the number of elements in the xt:repeat ? */
1.71      quint     175:   /* @@@@@ */
1.52      vatton    176: #endif /* TEMPLATES */
1.71      quint     177:   return FALSE; /* let Thot perform normal operation */
                    178: }
                    179: 
                    180: /*----------------------------------------------------------------------
                    181:   UseCreated
                    182:   A new "use" element has just been created by the user with a generic editing
                    183:   command.
                    184:   -----------------------------------------------------------------------*/
                    185: void UseCreated (NotifyElement *event)
                    186: {
                    187: #ifdef TEMPLATES
                    188:        Document         doc;
                    189:        Element          el;
                    190:   XTigerTemplate   t;
                    191: 
                    192:        doc = event->document;
1.72      quint     193:   el = event->element;
                    194:   if (TtaGetFirstChild (el))
                    195:     /* this Use element has already some content. It has already been
                    196:        instanciated */
                    197:     return;
1.76      vatton    198:   t = (XTigerTemplate) Get (Templates_Dic, DocumentMeta[doc]->template_url);
1.71      quint     199:   if (!t)
                    200:     return; // no template ?!?!
1.76      vatton    201:   InstantiateUse (t, el, doc, TRUE);
1.71      quint     202: #endif /* TEMPLATES */
                    203: }
1.29      tollenae  204: 
1.46      vatton    205: /*----------------------------------------------------------------------
1.79      quint     206:   UseButtonClicked
1.51      francesc  207:   Shows a menu with all the types that can be used in a use element.
1.46      vatton    208:   ----------------------------------------------------------------------*/
1.79      quint     209: ThotBool UseButtonClicked (NotifyElement *event)
1.39      tollenae  210: {
1.43      tollenae  211: #ifdef TEMPLATES
1.70      quint     212:        Document         doc;
                    213:        Element          el, comp;
1.76      vatton    214:        ElementType      elType;
                    215:        Attribute        att;
                    216:        AttributeType    attributeType;
1.67      quint     217:   XTigerTemplate   t;
                    218:   Declaration      dec;
1.70      quint     219:   Record           rec, first;
1.52      vatton    220:        int              nbitems, size;
                    221:        struct menuType *items;
                    222:   char            *types, *menuString;
1.77      vatton    223:   View            view;
                    224: 
                    225:   TtaGetActiveView (&doc, &view);
                    226:   if (view != 1)
                    227:     return FALSE; /* let Thot perform normal operation */
1.70      quint     228: 
                    229:        doc = event->document;
1.76      vatton    230:   t = (XTigerTemplate) Get (Templates_Dic, DocumentMeta[doc]->template_url);
1.67      quint     231:   if (!t)
1.77      vatton    232:     return FALSE; /* let Thot perform normal operation */
1.67      quint     233: 
1.79      quint     234:        el = event->element;
                    235:   if (TtaGetFirstChild (el))
                    236:     /* this Use element has already some content. Do not do anything */
                    237:     return FALSE; /* let Thot perform normal operation */
                    238: 
                    239:        elType = TtaGetElementType (el);
1.76      vatton    240:   // give the list of possible items
                    241:        attributeType.AttrSSchema = elType.ElSSchema;
                    242:        attributeType.AttrTypeNum = Template_ATTR_types;
                    243:        att = TtaGetAttribute (el, attributeType);
                    244:        size = TtaGetTextAttributeLength (att);
1.52      vatton    245:        types = (char *) TtaGetMemory (size+1); 
1.76      vatton    246:        TtaGiveTextAttributeValue (att, types, &size);
1.52      vatton    247:        giveItems (types, size, &items, &nbitems);
1.70      quint     248:        TtaFreeMemory (types);
                    249: 
1.67      quint     250:   if (nbitems == 1)
                    251:     {
1.76      vatton    252:       dec = GetDeclaration (t, items[0].label);
1.69      quint     253:       /* if it's a union, display the menu of this union */
1.70      quint     254:       if (dec)
1.76      vatton    255:         switch (dec->nature)
1.70      quint     256:           {
                    257:           case SimpleTypeNat :
                    258:             nbitems = 0;
                    259:             break;
                    260:           case XmlElementNat :
                    261:             nbitems = 0;
                    262:             break;
                    263:           case ComponentNat :
                    264:             nbitems = 0;
                    265:             break;
                    266:           case UnionNat :
                    267:             first = dec->unionType.include->first;
                    268:             rec = first;
                    269:             /* count the number of elements in the union */
                    270:             nbitems = 0;
                    271:             while (rec)
                    272:               {
                    273:                 nbitems++;
                    274:                 rec = rec->next;
                    275:               }
                    276:             if (nbitems > 0)
                    277:               {
1.76      vatton    278:                 items = (menuType*) TtaGetMemory (sizeof (struct menuType)* nbitems);
1.70      quint     279:                 rec = first;
                    280:                 nbitems = 0;
                    281:                 while (rec)
                    282:                   {
1.76      vatton    283:                     items[nbitems].label = (char *) TtaStrdup (rec->key);
1.70      quint     284:                     items[nbitems].type = SimpleTypeNat;  /* @@@@@ ???? @@@@@ */
                    285:                     nbitems++;
                    286:                     rec = rec->next;
                    287:                   }
                    288:               }
                    289:             break;
                    290:           default :
                    291:             //Impossible
                    292:             break;   
                    293:           }
                    294:     }
                    295:   if (nbitems > 0)
                    296:     {
1.80      vatton    297:       TtaCancelSelection (doc);
1.70      quint     298:       menuString = createMenuString (items, nbitems);
                    299:       TtaNewScrollPopup (BaseDialog + OptionMenu, TtaGetViewFrame (doc, 1),
                    300:                          NULL, nbitems, menuString , NULL, false, 'L');
                    301:       TtaFreeMemory (menuString);
1.74      vatton    302:       ReturnOption = -1; // no selection yet
1.70      quint     303:       TtaShowDialogue (BaseDialog + OptionMenu, FALSE);
1.76      vatton    304:       TtaWaitShowProcDialogue ();
1.70      quint     305:       TtaDestroyDialogue (BaseDialog + OptionMenu);
1.75      quint     306:       if (ReturnOption != -1)
1.76      vatton    307:         dec = GetDeclaration (t, items[ReturnOption].label);
1.70      quint     308:       TtaFreeMemory (items);
1.75      quint     309:       if (ReturnOption == -1)
                    310:         return FALSE;
1.70      quint     311:       if (dec)
1.67      quint     312:         {
1.76      vatton    313:           switch (dec->nature)
1.70      quint     314:             {
                    315:             case SimpleTypeNat :
                    316:               /* @@@@@ */
                    317:               break;
                    318:             case XmlElementNat :
                    319:               /* @@@@@ */
                    320:               break;
                    321:             case ComponentNat :
                    322:               /* copy element dec->componentType.content */
                    323:               comp = TtaCopyTree (dec->componentType.content, doc, doc, el);
                    324:               TtaInsertFirstChild (&comp, el, doc);
1.80      vatton    325:               el = comp;
1.70      quint     326:               /* @@@@@ */
                    327:               break;
                    328:             case UnionNat :
                    329:               /* @@@@@ */
                    330:               break;
                    331:             default :
                    332:               //Impossible
                    333:               break;   
                    334:             }
1.67      quint     335:         }
                    336:     }
1.80      vatton    337:   TtaSelectElement (doc, el);
1.77      vatton    338:   return TRUE;
1.63      vatton    339: #endif /* TEMPLATES */
                    340:        return TRUE;
                    341: }
1.42      tollenae  342: 
1.63      vatton    343: /*----------------------------------------------------------------------
1.79      quint     344:   OptionButtonClicked
1.63      vatton    345:   ----------------------------------------------------------------------*/
1.79      quint     346: ThotBool OptionButtonClicked (NotifyElement *event)
1.63      vatton    347: {
                    348: #ifdef TEMPLATES
1.75      quint     349:   Element         child, grandChild, next;
                    350:   ElementType     elType, elType1;
                    351:   Document        doc;
                    352:   XTigerTemplate  t;
1.77      vatton    353:   View            view;
1.75      quint     354: 
1.77      vatton    355:   TtaGetActiveView (&doc, &view);
                    356:   if (view != 1)
                    357:     return FALSE; /* let Thot perform normal operation */
1.75      quint     358:   doc = event->document;
                    359:   child = TtaGetFirstChild (event->element);
                    360:   if (!child)
1.77      vatton    361:     return FALSE; /* let Thot perform normal operation */
1.75      quint     362:   elType = TtaGetElementType (child);
                    363:   elType1 = TtaGetElementType (event->element);
1.76      vatton    364:   if ((elType.ElTypeNum != Template_EL_useEl &&
                    365:        elType.ElTypeNum != Template_EL_useSimple) ||
1.75      quint     366:       elType.ElSSchema != elType1.ElSSchema)
                    367:     return FALSE;
1.80      vatton    368: 
                    369:   TtaCancelSelection (doc);
1.75      quint     370:   grandChild = TtaGetFirstChild (child);
                    371:   if (!grandChild)
1.76      vatton    372:     /* the "use" element is empty. Instantiate it */
1.75      quint     373:     {
1.76      vatton    374:       t = (XTigerTemplate) Get (Templates_Dic, DocumentMeta[doc]->template_url);
1.75      quint     375:       if (!t)
                    376:         return FALSE; // no template ?!?!
1.76      vatton    377:       InstantiateUse (t, child, doc, TRUE);
1.75      quint     378:     }
                    379:   else
                    380:     /* remove the content of the "use" element */
                    381:     {
                    382:       do
                    383:         {
                    384:           next = grandChild;
                    385:           TtaNextSibling (&next);
                    386:           TtaDeleteTree (grandChild, doc);
                    387:           grandChild = next;
                    388:         }
                    389:       while (next);
                    390:     }
1.80      vatton    391:   TtaSelectElement (doc, event->element);
1.77      vatton    392:   return TRUE; /* don't let Thot perform normal operation */
1.57      francesc  393: #endif /* TEMPLATES */
1.52      vatton    394:        return TRUE;
1.42      tollenae  395: }
1.51      francesc  396: 
1.56      francesc  397: /*----------------------------------------------------------------------
1.79      quint     398:   RepeatButtonClicked
1.56      francesc  399:   Shows a menu with all the types that can be used in a use element.
                    400:   ----------------------------------------------------------------------*/
1.79      quint     401: ThotBool RepeatButtonClicked (NotifyElement *event)
1.56      francesc  402: {
                    403: #ifdef TEMPLATES
1.70      quint     404:   XTigerTemplate   t;
                    405:        Document         doc;
                    406:   Element          el, child, newEl;
                    407:   ElementType      elt, elt1;
1.63      vatton    408:        int              nbitems, size;
                    409:        struct menuType *items;
                    410:   char            *types, *menuString;
1.78      quint     411:   ThotBool          oldStructureChecking;
1.77      vatton    412:   View            view;
                    413: 
                    414:   TtaGetActiveView (&doc, &view);
                    415:   if (view != 1)
                    416:     return FALSE; /* let Thot perform normal operation */
1.70      quint     417:   doc = event->document;
1.76      vatton    418:   t = (XTigerTemplate) Get (Templates_Dic, DocumentMeta[doc]->template_url);
1.70      quint     419:   if (!t)
1.78      quint     420:     return FALSE; // no template ?!?!
1.80      vatton    421: 
                    422:   TtaCancelSelection (doc);
1.78      quint     423:        types = "begining end"; 
1.63      vatton    424:        size = strlen (types);
                    425:        giveItems (types, size, &items, &nbitems);
                    426:        menuString = createMenuString (items, nbitems);
                    427:        TtaNewScrollPopup (BaseDialog + OptionMenu, TtaGetViewFrame (doc, 1), NULL, 
                    428:                      nbitems, menuString , NULL, false, 'L');
                    429:        TtaFreeMemory (menuString);
1.74      vatton    430:   ReturnOption = -1; // no selection yet
1.63      vatton    431:        TtaShowDialogue (BaseDialog + OptionMenu, FALSE);
1.76      vatton    432:        TtaWaitShowProcDialogue ();
1.63      vatton    433:        TtaDestroyDialogue (BaseDialog + OptionMenu);
1.80      vatton    434:   el = event->element;
1.70      quint     435:   if (ReturnOption == 0 || ReturnOption == 1)
                    436:     {
                    437:       child = TtaGetFirstChild (el);
                    438:       if (child)
                    439:         {
                    440:           elt = TtaGetElementType (el);
                    441:           elt1 = TtaGetElementType (child);
1.78      quint     442:           if (elt.ElSSchema == elt1.ElSSchema)
1.70      quint     443:             {
1.78      quint     444:               if (elt1.ElTypeNum == Template_EL_useEl ||
                    445:                   elt1.ElTypeNum == Template_EL_useSimple)
                    446:                 newEl = InstantiateUse (t, child, doc, FALSE);
                    447:               else if (elt1.ElTypeNum == Template_EL_folder)
                    448:                 newEl = TtaCopyTree (child, doc, doc, el);
                    449:               else
                    450:                 newEl = NULL;
1.70      quint     451:               if (newEl)
                    452:                 {
1.78      quint     453:                   oldStructureChecking = TtaGetStructureChecking (doc);
                    454:                   TtaSetStructureChecking (FALSE, doc);
1.70      quint     455:                   if (ReturnOption == 0)
                    456:                     TtaInsertFirstChild (&newEl, el, doc);
                    457:                   else
                    458:                     {
                    459:                       child = TtaGetLastChild (el);
                    460:                       TtaInsertSibling (newEl, child, FALSE, doc);
1.80      vatton    461:                       el = newEl;
1.70      quint     462:                     }
1.78      quint     463:                   TtaSetStructureChecking (oldStructureChecking, doc);
1.70      quint     464:                 }
                    465:             }
                    466:         }
                    467:     }
1.80      vatton    468:   TtaSelectElement (doc, el);
1.77      vatton    469:   return TRUE; /* don't let Thot perform normal operation */
1.57      francesc  470: #endif /* TEMPLATES */
1.56      francesc  471:        return TRUE;
                    472: }
1.64      francesc  473: 
1.66      vatton    474: /*----------------------------------------------------------------------
                    475:   ----------------------------------------------------------------------*/
1.76      vatton    476: void OpeningInstance (char *fileName, Document doc)
1.65      francesc  477: {
                    478: #ifdef TEMPLATES
1.76      vatton    479:   XTigerTemplate   t;
                    480:   char            *content, *ptr;
                    481:   gzFile           stream;
                    482:   char             buffer[2000];
1.77      vatton    483:   int              res;
1.65      francesc  484: 
1.76      vatton    485:   stream = TtaGZOpen (fileName);
                    486:   if (stream != 0)
1.65      francesc  487:     {
1.76      vatton    488:       res = gzread (stream, buffer, 1999);
                    489:       if (res >= 0)
1.65      francesc  490:         {
1.81    ! vatton    491:           buffer[res] = EOS;
1.76      vatton    492:           ptr = strstr (buffer, "<?xtiger");
                    493:           if (ptr)
                    494:             ptr = strstr (ptr, "template");
                    495:           if (ptr)
                    496:             ptr = strstr (ptr, "=");
                    497:           if (ptr)
                    498:             ptr = strstr (ptr, "\"");
                    499:           if (ptr)
                    500:             {
                    501:               // template URI
                    502:               content = &ptr[1];
                    503:               ptr = strstr (content, "\"");
                    504:             }
                    505:           if (ptr)
                    506:             {
                    507:               *ptr = EOS;
                    508:               //Get now the template URI
                    509:               DocumentMeta[doc]->template_url = TtaStrdup (content);
                    510:               if (Templates_Dic == NULL)
                    511:                 InitializeTemplateEnvironment ();
                    512:               t = (XTigerTemplate) Get (Templates_Dic, content);
                    513:               if (!t)
                    514:                 {
                    515:                   LoadTemplate (0, content);
                    516:                   t = (XTigerTemplate) Get (Templates_Dic, content);
                    517:                 }
                    518:               AddUser (t);
                    519:             }
1.65      francesc  520:         }
                    521:     }
1.76      vatton    522:   TtaGZClose (stream);
1.65      francesc  523: #endif /* TEMPLATES */
                    524: }
                    525: 
1.64      francesc  526: /*----------------------------------------------------------------------
1.65      francesc  527:   ClosingInstance
1.64      francesc  528:   Callback called before closing a document. Checks for unused templates.
                    529:   ----------------------------------------------------------------------*/
1.65      francesc  530: ThotBool ClosingInstance(NotifyDialog* dialog)
1.64      francesc  531: {
1.65      francesc  532: #ifdef TEMPLATES
                    533:   //If it is a template all has been already freed
1.76      vatton    534:   if (DocumentMeta[dialog->document] == NULL)
                    535:     return FALSE;
1.65      francesc  536: 
                    537:   char *turl = DocumentMeta[dialog->document]->template_url;
1.73      vatton    538:   if (turl)
1.65      francesc  539:     {
1.76      vatton    540:       XTigerTemplate t = (XTigerTemplate) Get (Templates_Dic, turl);
1.73      vatton    541:       if (t)
1.76      vatton    542:         RemoveUser (t);
                    543:       TtaFreeMemory (turl);
1.65      francesc  544:     }
                    545: #endif /* TEMPLATES */
                    546:   return FALSE;
1.64      francesc  547: }

Webmaster