File:  [Public] / Amaya / amaya / templateUtils.c
Revision 1.37: download - view: text, annotated - select for diffs
Fri Feb 13 16:07:36 2009 UTC (15 years, 4 months ago) by vatton
Branches: MAIN
CVS tags: HEAD
Better control of attributes within template instances
Irene

/*
 *
 *  COPYRIGHT INRIA and W3C, 2006-2009
 *  Please first read the full copyright statement in file COPYRIGHT.
 *
 */

#include "templates.h"
#include "Templatename.h"
#include "templates_f.h"

#include "AHTURLTools_f.h"
#include "HTMLsave_f.h"


#include <stdarg.h>

/*----------------------------------------------------------------------
GetSchemaFromDocType: Returns the name of the schema corresponding to
a doc type.
----------------------------------------------------------------------*/
const char *GetSchemaFromDocType (DocumentType docType)
{
#ifdef TEMPLATES
	switch (docType)
    {
    case docAnnot :
		return "Annot";
    case docBookmark :
		return "Topics";
    case docSVG :
		return "SVG";
    case docMath :
		return "MathML";
    case docXml :
		return "XML";
    default :
		return "HTML";
    }
#endif // TEMPLATES
	return "HTML";
}

/*----------------------------------------------------------------------
Set the value of a string attribute
----------------------------------------------------------------------*/
void SetAttributeStringValue (Element el, int att, const char* value)
{
#ifdef TEMPLATES
  Document      doc = TtaGetDocument(el);
  AttributeType attType;
  Attribute     attribute;

  if (doc == 0 || !TtaGetDocumentAccessMode(doc))
    return;
  attType.AttrSSchema = TtaGetElementType(el).ElSSchema;
  attType.AttrTypeNum = att;
  attribute = TtaGetAttribute(el, attType);
  if (attribute == NULL)
    {
      attribute = TtaNewAttribute (attType);
      TtaAttachAttribute(el, attribute, doc);
    }
  TtaSetAttributeText(attribute, value, el, doc);
#endif /* TEMPLATES */
}

/*----------------------------------------------------------------------
Set the value of a string attribute and registering it in undo sequence.
----------------------------------------------------------------------*/
void SetAttributeStringValueWithUndo (Element el, int att, char* value)
{
#ifdef TEMPLATES
  Document      doc = TtaGetDocument(el);
  AttributeType attType;
  Attribute     attribute;

  if (doc == 0 || !TtaGetDocumentAccessMode(doc))
    return;
  attType.AttrSSchema = TtaGetElementType(el).ElSSchema;
  attType.AttrTypeNum = att;
  attribute = TtaGetAttribute(el, attType);
  if (attribute == NULL)
    {
      attribute = TtaNewAttribute (attType);
      TtaAttachAttribute(el, attribute, doc);
      TtaRegisterAttributeCreate(attribute, el, doc);
    }
  TtaSetAttributeText(attribute, value, el, doc);
  TtaRegisterAttributeReplace(attribute, el, doc);
#endif /* TEMPLATES */
}

/*----------------------------------------------------------------------
Returns the value of a string attribute without copy it
----------------------------------------------------------------------*/
void GiveAttributeStringValueFromNum (Element el, int att, char* buff, int* sz)
{
#ifdef TEMPLATES
  AttributeType attType;
  Attribute     attribute;
  int           size;

  attType.AttrSSchema = TtaGetElementType(el).ElSSchema;
  attType.AttrTypeNum = att;
  attribute = TtaGetAttribute(el, attType);

  size = TtaGetTextAttributeLength(attribute);
  TtaGiveTextAttributeValue (attribute, buff, &size);
  buff[size] = EOS;
  if (sz)
    *sz = size;
#endif /* TEMPLATES */
}



/*----------------------------------------------------------------------
  Returns the value of a string attribute or NULL
----------------------------------------------------------------------*/
char *GetAttributeStringValueFromNum (Element el, int att, int* sz)
{
#ifdef TEMPLATES
	AttributeType attType;
  Attribute     attribute;
  char         *aux;
  int           size;

	attType.AttrSSchema = TtaGetElementType(el).ElSSchema;
	attType.AttrTypeNum = att;
	attribute = TtaGetAttribute(el, attType);
	if (attribute == NULL)
    return NULL;

	size = TtaGetTextAttributeLength (attribute);
	aux = (char*) TtaGetMemory (size+1);
	TtaGiveTextAttributeValue (attribute, aux, &size);
  aux[size] = EOS;
  if (sz)
    *sz = size;
	return aux;
#else
	return NULL;
#endif /* TEMPLATES */
}

/*----------------------------------------------------------------------
Returns the value of an int attribute
----------------------------------------------------------------------*/
int GetAttributeIntValueFromNum (Element el, int att)
{
#ifdef TEMPLATES
  AttributeType attType;
  Attribute     attribute;

  attType.AttrSSchema = TtaGetElementType(el).ElSSchema;
  attType.AttrTypeNum = att;
  attribute = TtaGetAttribute(el, attType);

  return TtaGetAttributeValue(attribute);
#else
  return NULL;
#endif /* TEMPLATES */
}

/*----------------------------------------------------------------------
Set the value of a int attribute and registering it in undo sequence if wanted
----------------------------------------------------------------------*/
void SetAttributeIntValue (Element el, int att, int value, ThotBool undo)
{
#ifdef TEMPLATES
  Document      doc = TtaGetDocument(el);
  AttributeType attType;
  Attribute     attribute;

  if (doc == 0 || !TtaGetDocumentAccessMode(doc))
    return;
  attType.AttrSSchema = TtaGetElementType(el).ElSSchema;
  attType.AttrTypeNum = att;
  attribute = TtaGetAttribute(el, attType);
  if (attribute == NULL)
    {
      attribute = TtaNewAttribute (attType);
      TtaAttachAttribute(el, attribute, doc);
      if (undo)
        TtaRegisterAttributeCreate(attribute, el, doc);
    }
  TtaSetAttributeValue(attribute, value, el, doc);
  if (undo)
    TtaRegisterAttributeReplace(attribute, el, doc);
#endif /* TEMPLATES */
}




/*----------------------------------------------------------------------
Returns the value of a string attribute
----------------------------------------------------------------------*/
char *GetAttributeStringValue (Element el, Attribute attribute, int* sz)
{
#ifdef TEMPLATES
	int size = TtaGetTextAttributeLength(attribute);
	char *aux = (char*) TtaGetMemory(size+1);

	TtaGiveTextAttributeValue (attribute, aux, &size);
  aux[size] = EOS;
  if (sz)
    *sz = size;
	return aux;
#else
	return NULL;
#endif /* TEMPLATES */
}

/*----------------------------------------------------------------------
  GetAncestorComponentName returns the name of the ancestor component
  or NULL;
  ----------------------------------------------------------------------*/
char *GetAncestorComponentName (Element *el)
{
#ifdef TEMPLATES
  ElementType   elType;
  Element       anc = NULL;
  char         *name;

  elType = TtaGetElementType (*el);
  elType.ElTypeNum = Template_EL_component;
  anc = TtaGetParent (*el);
  anc = TtaGetExactTypedAncestor (anc, elType);
  if (anc)
    {
      name = GetAttributeStringValueFromNum (anc, Template_ATTR_name, NULL);
      *el = anc;
      return name;
    }
#endif /* TEMPLATES */
  return NULL;
}


/*----------------------------------------------------------------------
GetFirstEditableElement
Returns the first descendant element which is modifiable.
----------------------------------------------------------------------*/
Element GetFirstEditableElement (Element el)
{
  Element res = NULL;
  Element current = TtaGetFirstChild(el);

  while (!res && current)
  {
    res = GetFirstEditableElement(current);
    TtaNextSibling(&current);
  }

  if (!res && !TtaIsReadOnly(el))
    res = el;

  return res;
}

/*----------------------------------------------------------------------
  TemplateCanInsertFirstChild
  Test if an element can be inserted as child of another, bypassing xt.
----------------------------------------------------------------------*/
ThotBool TemplateCanInsertFirstChild (ElementType elementType, Element parent,
                                      Document document)
{
#ifdef TEMPLATES
  SSchema         templateSSchema = TtaGetSSchema ("Template", document);
  ElementType     parType;

  while (parent)
    {
      parType = TtaGetElementType(parent);
      if (parType.ElSSchema != templateSSchema)
        break;
      parent = TtaGetParent(parent);
    }
  if (!parent)
    return FALSE;
#endif /* TEMPLATES */
  return TtaCanInsertFirstChild(elementType, parent, document);
}

/*----------------------------------------------------------------------
  CheckTemplateAttrInMenu
  Validate the status of an attribute according to xt::atribute rules.
	Return TRUE if the attribute is not valid
  ----------------------------------------------------------------------*/
ThotBool CheckTemplateAttrInMenu (NotifyAttribute *event)
{
#ifdef TEMPLATES
  Document      doc = event->document;
  Element       elem;
  Element       parent = event->element;
  ElementType   elType;
  AttributeType attrType;
  Attribute     attr;
  char         *attrName;
  char          buffer[MAX_LENGTH];
  int           sz, useAt, type;

  /* Prevent from showing attributes for template instance but not templates. */
  if (IsTemplateInstanceDocument(doc))
    {
      /* Prevent if attribute's element is not a descendant of xt:use */
      /* Dont prevent if descendant of xt:bag. */
      elem = GetFirstTemplateParentElement(parent);
      if (!elem)
        return TRUE;
      elType = TtaGetElementType(elem);
      if (elType.ElTypeNum == Template_EL_bag)
        return FALSE;	/* let Thot perform normal operation */
      if (elType.ElTypeNum != Template_EL_useSimple)
        return TRUE;
      if (!TtaIsReadOnly (parent))
        return FALSE;	/* let Thot perform normal operation */
 
      /* Search for the corresponding xt:attribute element*/
      attrName = TtaGetAttributeName(event->attributeType);
      attrType.AttrSSchema = TtaGetSSchema ("Template", doc);
      for (elem = TtaGetFirstChild(parent); elem; TtaNextSibling(&elem))
        {
          attrType.AttrTypeNum = Template_ATTR_ref_name;
          elType = TtaGetElementType(elem);
          if (elType.ElTypeNum == Template_EL_attribute &&
              elType.ElSSchema == TtaGetSSchema ("Template", doc))
            {
               attr = TtaGetAttribute(elem, attrType);
               if (attr)
                 {
                   sz = MAX_LENGTH;
                   TtaGiveTextAttributeValue(attr, buffer, &sz);
                   if (!strcmp(buffer, attrName))
                     {
                       /* Process the attribute filtering */
                       /* Get 'useAt' attr value. */
                       attrType.AttrTypeNum = Template_ATTR_useAt;
                       attr = TtaGetAttribute(elem, attrType);
                       if (attr)
                         useAt = TtaGetAttributeValue(attr);
                       else
                         useAt = Template_ATTR_useAt_VAL_required;
                       /* Get 'type' attr value. */
                       attrType.AttrTypeNum = Template_ATTR_type;
                       attr = TtaGetAttribute(elem, attrType);
                       if (attr)
                         type = TtaGetAttributeValue(attr);
                       else
                         type = Template_ATTR_type_VAL_string;

                       event->restr.RestrType = (RestrictionContentType)type;
                       /* If attr is prohibited, dont show it.*/
                       if (useAt == Template_ATTR_useAt_VAL_prohibited)
                           return TRUE;
                       if (useAt == Template_ATTR_useAt_VAL_required)
                         {
                           /* Force the usage of this attribute.*/
                           event->restr.RestrFlags |= attr_mandatory;
                         }

                       /* Get 'fixed' attr value. */
                       attrType.AttrTypeNum = Template_ATTR_fixed;
                       attr = TtaGetAttribute(elem, attrType);
                       if (attr)
                         {
                           sz = MAX_LENGTH;
                           TtaGiveTextAttributeValue(attr, buffer, &sz);
                           event->restr.RestrFlags |= attr_readonly;
                           event->restr.RestrDefVal = TtaStrdup(buffer);
                           return FALSE;	/* let Thot perform normal operation */
                         }

                       /* Get 'default' attr value.*/
                       attrType.AttrTypeNum = Template_ATTR_defaultAt;
                       attr = TtaGetAttribute(elem, attrType);
                       if (attr)
                         {
                           sz = MAX_LENGTH;
                           TtaGiveTextAttributeValue(attr, buffer, &sz);
                           event->restr.RestrDefVal = TtaStrdup(buffer);
                         }

                       /* Get 'values' attr value.*/
                       attrType.AttrTypeNum = Template_ATTR_values;
                       attr = TtaGetAttribute(elem, attrType);
                       if (attr)
                         {
                           sz = MAX_LENGTH;
                           TtaGiveTextAttributeValue(attr, buffer, &sz);
                           event->restr.RestrEnumVal = TtaStrdup(buffer);
                           event->restr.RestrFlags |= attr_enum;
                         }
                       return FALSE;	/* let Thot perform normal operation */
                     }
                 }
            }
        }
      return TRUE;
    }
#endif /* TEMPLATES */
  return FALSE;
}

/*----------------------------------------------------------------------
 * Dump element path
  ----------------------------------------------------------------------*/
void DumpElementSubPath (Element el, char* buffer)
{
#ifdef TEMPLATE_DEBUG
  Element parent = TtaGetParent(el);
  if (parent == NULL)
    strcpy(buffer, TtaGetElementTypeName(TtaGetElementType(el)));
  else
    {
      DumpElementSubPath(parent, buffer);
      strcat(buffer, "/");
      strcat(buffer, TtaGetElementTypeName(TtaGetElementType(el)));
    }
#endif /* TEMPLATE_DEBUG */
}

/*----------------------------------------------------------------------
 * Dump element path
  ----------------------------------------------------------------------*/
void DumpElementPath (Element el)
{
#ifdef TEMPLATE_DEBUG
  char buffer[MAX_LENGTH];

  DumpElementSubPath(el, buffer);
  printf("%s\n", buffer);
#endif /* TEMPLATE_DEBUG */
}


/*----------------------------------------------------------------------
 * Dump template element
  ----------------------------------------------------------------------*/
void DumpTemplateElement (Element el, Document doc)
{
#ifdef TEMPLATE_DEBUG
  ElementType    elType;
  AttributeType  attType;
  Attribute      att;
  SSchema        schema = TtaGetSSchema ("Template", doc);
  char*          str;
  char           buffer[MAX_LENGTH];
  int            len;
  Language       lang;

  if (el && doc)
    {
      elType = TtaGetElementType(el);
      printf("- %p %d ", elType.ElSSchema, elType.ElTypeNum);
      printf(" %s", TtaGetSSchemaName(elType.ElSSchema));
      printf(":%s", TtaGetElementTypeName(elType));
      if (elType.ElTypeNum == 1)
        {
          len = MAX_LENGTH-1;
          TtaGiveTextContent(el, (unsigned char*)buffer, &len, &lang);
          buffer[len] = EOS;
          printf(" \"%s\"", buffer);
        }

      if (elType.ElSSchema == schema)
        {
          switch(elType.ElTypeNum)
            {
              case Template_EL_head:
                str = GetAttributeStringValueFromNum(el, Template_ATTR_version, NULL);
                printf(" version=%s", str);
                TtaFreeMemory(str);
                str = GetAttributeStringValueFromNum(el, Template_ATTR_templateVersion, NULL);
                printf(" templateVersion=%s", str);
                TtaFreeMemory(str);
                break;
              case Template_EL_component:
                str = GetAttributeStringValueFromNum(el, Template_ATTR_name, NULL);
                printf(" name=%s", str);
                TtaFreeMemory(str);
                break;
              case Template_EL_union:
                str = GetAttributeStringValueFromNum(el, Template_ATTR_name, NULL);
                printf(" name=%s", str);
                TtaFreeMemory(str);
                str = GetAttributeStringValueFromNum(el, Template_ATTR_includeAt, NULL);
                printf(" include=%s", str);
                TtaFreeMemory(str);
                str = GetAttributeStringValueFromNum(el, Template_ATTR_exclude, NULL);
                printf(" exclude=%s", str);
                TtaFreeMemory(str);
                break;
              case Template_EL_import:
                str = GetAttributeStringValueFromNum(el, Template_ATTR_src, NULL);
                printf(" src=%s", str);
                TtaFreeMemory(str);
                break;
              case Template_EL_repeat:
                str = GetAttributeStringValueFromNum(el, Template_ATTR_title, NULL);
                printf(" label=%s", str);
                TtaFreeMemory(str);
                str = GetAttributeStringValueFromNum(el, Template_ATTR_minOccurs, NULL);
                printf(" minOccurs=%s", str);
                TtaFreeMemory(str);
                str = GetAttributeStringValueFromNum(el, Template_ATTR_maxOccurs, NULL);
                printf(" maxOccurs=%s", str);
                TtaFreeMemory(str);
                break;
              case Template_EL_useSimple:
              case Template_EL_useEl:
                str = GetAttributeStringValueFromNum(el, Template_ATTR_title, NULL);
                printf(" label=%s", str);
                TtaFreeMemory(str);
                str = GetAttributeStringValueFromNum(el, Template_ATTR_types, NULL);
                printf(" types=%s", str);
                TtaFreeMemory(str);
                attType.AttrSSchema = elType.ElSSchema;
                attType.AttrTypeNum = Template_ATTR_option;
                att = TtaGetAttribute (el, attType);
                if (att)
                  printf(" option");
                break;
              case Template_EL_bag:
                str = GetAttributeStringValueFromNum(el, Template_ATTR_title, NULL);
                printf(" label=%s", str);
                TtaFreeMemory(str);
                str = GetAttributeStringValueFromNum(el, Template_ATTR_types, NULL);
                printf(" types=%s", str);
                TtaFreeMemory(str);
                break;
              case Template_EL_attribute:
                str = GetAttributeStringValueFromNum(el, Template_ATTR_ref_name, NULL);
                printf(" name=%s", str);
                TtaFreeMemory(str);
                str = GetAttributeStringValueFromNum(el, Template_ATTR_type, NULL);
                printf(" type=%s", str);
                TtaFreeMemory(str);
                str = GetAttributeStringValueFromNum(el, Template_ATTR_useAt, NULL);
                printf(" use=%s", str);
                TtaFreeMemory(str);
                str = GetAttributeStringValueFromNum(el, Template_ATTR_defaultAt, NULL);
                printf(" default=%s", str);
                TtaFreeMemory(str);
                str = GetAttributeStringValueFromNum(el, Template_ATTR_fixed, NULL);
                printf(" fixed=%s", str);
                TtaFreeMemory(str);
                break;
            }
        }
    }
#endif /* TEMPLATE_DEBUG */
}

/*----------------------------------------------------------------------
 * Dump subtree
  ----------------------------------------------------------------------*/
void DumpSubtree(Element el, Document doc, int off)
{
#ifdef TEMPLATE_DEBUG
  Element child = TtaGetFirstChild(el);
  int i;

  for (i=0; i<off; i++)
    printf("  ");
  DumpTemplateElement(el, doc);
  printf("\n");

  while (child)
    {
      DumpSubtree(child, doc, off+1);
      TtaNextSibling(&child);
    }
#endif /* TEMPLATE_DEBUG */
}

/*----------------------------------------------------------------------
  Save an opened document to a specified path in order to open.
  The parameter doc is the original doc to be saved
  The parameter newdoc is the new document
  The parameter newpath is the newdoc URI
  Return the saved localFile (to be freed) or NULL
  ----------------------------------------------------------------------*/
char *SaveDocumentToNewDoc(Document doc, Document newdoc, char* newpath)
{
  ElementType   elType;
  Element       root;
  char         *localFile = NULL, *s;
  ThotBool      res = FALSE;

  localFile = GetLocalPath (newdoc, newpath);
  // update all links
  SetRelativeURLs (doc, newpath, NULL, FALSE, FALSE, FALSE);
  // prepare the new document view
  TtaExtractName (newpath, DirectoryName, DocumentName);

  root = TtaGetRootElement(doc);
  elType = TtaGetElementType (root);
  // get the target document type
  s = TtaGetSSchemaName (elType.ElSSchema);
  if (strcmp (s, "HTML") == 0)
    {
      /* docType = docHTML; */
      if (TtaGetDocumentProfile(doc) == L_Xhtml11 ||
          TtaGetDocumentProfile(doc) == L_Basic)
        res = TtaExportDocumentWithNewLineNumbers (doc, localFile, "HTMLT11", FALSE);
      else
        res = TtaExportDocumentWithNewLineNumbers (doc, localFile, "HTMLTX", FALSE);
    }
  else if (strcmp (s, "SVG") == 0)
    /* docType = docSVG; */
    res = TtaExportDocumentWithNewLineNumbers (doc, localFile, "SVGT", FALSE);
  else if (strcmp (s, "MathML") == 0)
    /* docType = docMath; */
    res = TtaExportDocumentWithNewLineNumbers (doc, localFile, "MathMLT", FALSE);
  else
    /* docType = docXml; */
    res = TtaExportDocumentWithNewLineNumbers (doc, localFile, NULL, FALSE);
  if (res)
    return localFile;
  else
    {
      TtaFreeMemory (localFile);
      return NULL;
    }
}

/*----------------------------------------------------------------------
 * Retrieve the xt:head element.
  ----------------------------------------------------------------------*/
Element TemplateFindHead (Document doc)
{
#ifdef TEMPLATES
  ElementType headType, elType;
  Element     head, root;

  headType.ElSSchema = TtaGetSSchema ("Template", doc);
  if (headType.ElSSchema == NULL)
    return NULL;

  headType.ElTypeNum = Template_EL_head;
  root = TtaGetMainRoot (doc);
  head = TtaSearchTypedElement (headType, SearchInTree, root);
  if (head == NULL)
    {
      // create the template head
      head = TtaNewElement (doc, headType);
      elType = TtaGetElementType (root);
      if (!strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML"))
        {
          elType.ElTypeNum = HTML_EL_HEAD;
          root = TtaSearchTypedElement (elType, SearchInTree, root);
        }
      TtaInsertFirstChild (&head, root, doc);
      SetAttributeStringValue (head, Template_ATTR_version, Template_Current_Version);
      SetAttributeStringValue (head, Template_ATTR_templateVersion, "1.0");      
    }
  return head;
#else /* TEMPLATES */
  return NULL;
#endif /* TEMPLATES */
}



Webmaster