/* * * COPYRIGHT INRIA and W3C, 1996-2007 * Please first read the full copyright statement in file COPYRIGHT. * */ /* * Authors: Emilien Kia * */ #define THOT_EXPORT extern #include "amaya.h" #include "document.h" #include "containers.h" #include "Elemlist.h" #ifdef TEMPLATES #include "Template.h" #include "templates.h" #include "templates_f.h" #include "templateDeclarations.h" #include "mydictionary_f.h" #include "templateLoad_f.h" #include "templateDeclarations_f.h" #include "templateInstantiate_f.h" #include "appdialogue_wx.h" #include "init_f.h" #include "wxdialogapi_f.h" #include "AHTURLTools_f.h" #endif /* TEMPLATES */ #include "fetchXMLname_f.h" #include "MENUconf.h" #include "parser.h" #include "fetchXMLname_f.h" typedef struct _sInsertableElementList *InsertableElementList; typedef struct _sInsertableElementList { /** Current selected element.*/ Element elem; /** Insertable element list.*/ DLList list; } sInsertableElementList; static HashMap InsertableElementMap = NULL; /*---------------------------------------------------------------------- ----------------------------------------------------------------------*/ static InsertableElementList InsertableElementList_Create(Element elem, DLList list) { InsertableElementList lst = (InsertableElementList)TtaGetMemory(sizeof(sInsertableElementList)); lst->elem = elem; lst->list = list; return lst; } static void InsertableElementList_Destroy(InsertableElementList list) { if (list->list) DLList_Destroy(list->list); TtaFreeMemory(list); } /*---------------------------------------------------------------------- InsertableElement_Init Initialize the module. ----------------------------------------------------------------------*/ void InsertableElement_Init() { if (!InsertableElementMap) InsertableElementMap = PointerHashMap_Create((Container_DestroyElementFunction)InsertableElementList_Destroy, 32); } /*---------------------------------------------------------------------- InsertableElement_Final Finalize the module. ----------------------------------------------------------------------*/ void InsertableElement_Final() { if (InsertableElementMap) { HashMap_Destroy(InsertableElementMap); InsertableElementMap = NULL; } } #ifdef TEMPLATES /*---------------------------------------------------------------------- FillUnionResolvedPossibleElement Fill an element list with all possible element, resolving them if union. @param name Element name @param elem Document element to attach @param resolvedPath Path of different succesive union name. @param list List to fill. ----------------------------------------------------------------------*/ static void FillUnionResolvedPossibleElement(XTigerTemplate t, const char* name, Element elem, const char* resolvedPath, DLList list, int level) { Declaration dec = Template_GetDeclaration (t, name); if (dec == NULL) return; if (dec->declaredIn->isPredefined) { // DLList_Append(list, ElemListElement_CreateComponent(level, dec->name, // (void*)dec, resolvedPath, elem)); } else if (dec->nature==ComponentNat) { DLList_Append(list, ElemListElement_CreateComponent(level, dec->name, (void*)dec, resolvedPath, elem)); } else if (dec->nature==UnionNat) { DLList tempList = ElemList_Create(); Record first = dec->unionType.include->first; Record rec = first; int len1 = 0 , len2 = strlen(dec->name); if (resolvedPath!=NULL) len1 = strlen(resolvedPath); char* newPath = (char*)TtaGetMemory(len1+len2+2); if (len1>0) { strcpy(newPath, resolvedPath); newPath[len1] = '/'; strcpy(newPath+len1+1, dec->name); } else { strcpy(newPath, dec->name); } while(rec) { FillUnionResolvedPossibleElement(t, rec->key, elem, newPath, tempList, level); rec = rec->next; } ForwardIterator iter = DLList_GetForwardIterator(tempList); DLListNode node = (DLListNode) ForwardIterator_GetFirst(iter); while(node) { DLList_Append(list, node->elem); node = (DLListNode) ForwardIterator_GetNext(iter); } tempList->destroyElement = NULL; DLList_Destroy(tempList); TtaFreeMemory(newPath); /** todo Remove excluded elements.*/ } else if (dec->nature==SimpleTypeNat) { DLList_Append(list, ElemListElement_CreateBaseType(level, dec->name, resolvedPath, elem)); /* Do nothing. */ } else { /* Search in tgt std elements. */ int xmlType; /* See parser.h */ for(xmlType=XHTML_TYPE; xmlTypename, &elType, &mappedName, &content, &checkProfile, TtaGetDocument(elem)); if (elType.ElTypeNum!=0) { DLList_Append(list, ElemListElement_CreateLanguageElement(level, elType, resolvedPath, elem)); break; } } } } /*---------------------------------------------------------------------- FillInsertableTemplateElementFromStringList Fill an element list with all possible elements extracted from a stringlist. ----------------------------------------------------------------------*/ static void FillInsertableTemplateElementFromStringList(XTigerTemplate t, Element refelem, const char* strlist, DLList list, int level) { int pos = 0, offset = 0; int size = strlen(strlist); char* types = strdup(strlist); while(posoffset) { types[pos] = 0; FillUnionResolvedPossibleElement(t, types+offset, refelem, NULL, list, level); } offset = pos+1; } pos++; } if (pos>offset) { types[pos] = 0; FillUnionResolvedPossibleElement(t, types+offset, refelem, NULL, list, level); } TtaFreeMemory(types); } /*---------------------------------------------------------------------- FillInsertableElementFromElemAttribute Fill an element list with all possible elements from an attribute list. ----------------------------------------------------------------------*/ static void FillInsertableElementFromElemAttribute(XTigerTemplate t, Element elem, Element refelem, int attrib, DLList list, int level) { ElementType type = TtaGetElementType(elem); AttributeType attributeType = {type.ElSSchema, attrib}; Attribute att = TtaGetAttribute (elem, attributeType); int size = TtaGetTextAttributeLength (att); char* types = (char *) TtaGetMemory (size+1); TtaGiveTextAttributeValue (att, types, &size); FillInsertableTemplateElementFromStringList (t, refelem, types, list, level); TtaFreeMemory (types); } #endif/* TEMPLATES */ /*---------------------------------------------------------------------- FillInsertableElemList Fill an element list with all insertable elements (base element or XTiger comonent). ----------------------------------------------------------------------*/ static void FillInsertableElemList(Document doc, Element elem, DLList list) { ElementType type; #ifdef TEMPLATES Element child; ElementType childType; XTigerTemplate t; #endif/* TEMPLATES */ int level; ThotBool cont; if (elem){ if (doc==0) doc = TtaGetDocument(elem); #ifdef TEMPLATES t = (XTigerTemplate) Dictionary_Get (Templates_Dic, DocumentMeta[doc]->template_url); #endif/* TEMPLATES */ level = 0; cont = TRUE; while(elem!=NULL && cont) { type = TtaGetElementType(elem); switch(type.ElTypeNum) { #ifdef TEMPLATES case Template_EL_repeat: child = TtaGetFirstChild(elem); childType = TtaGetElementType(child); switch(childType.ElTypeNum) { case Template_EL_useEl: FillInsertableElementFromElemAttribute(t, child, elem, Template_ATTR_types, list, level); break; case Template_EL_useSimple: FillInsertableElementFromElemAttribute(t, child, elem, Template_ATTR_types, list, level); break; case Template_EL_bag: FillInsertableElementFromElemAttribute(t, child, elem, Template_ATTR_types, list, level); break; default: break; } cont = TRUE; break; case Template_EL_useEl: // Fill for xt:use only if have no child. if (TtaGetFirstChild(elem)==NULL){ FillInsertableElementFromElemAttribute(t, elem, elem, Template_ATTR_types, list, level); cont = TRUE; } break; case Template_EL_bag: FillInsertableElementFromElemAttribute(t, elem, elem, Template_ATTR_types, list, level); cont = TRUE; break; #endif /*TEMPLATES */ default: break; } elem = TtaGetParent(elem); level ++; } } } /*---------------------------------------------------------------------- InsertableElement_GetList Get the insertable element list for a document. @param doc Document @return The insertable element list or NULL. ----------------------------------------------------------------------*/ DLList InsertableElement_GetList(Document doc) { InsertableElementList list = (InsertableElementList) HashMap_Get(InsertableElementMap, (void*)doc); if (list) return list->list; else return NULL; } /*---------------------------------------------------------------------- InsertableElement_Update Update the insertable element list for a document. @param el Selected element, cant be NULL. @param document Document, can be NULL. @param force No dont force the refresh of the list if the element is already selected. @return List of insertable elements. ----------------------------------------------------------------------*/ DLList InsertableElement_Update(Document doc, Element el) { InsertableElementList list; if (doc==0) doc= TtaGetDocument(el); list = (InsertableElementList) HashMap_Get(InsertableElementMap, (void*)doc); if (list==NULL) { list = InsertableElementList_Create(0, DLList_Create()); HashMap_Set(InsertableElementMap, (void*)doc, list); } DLList_Empty(list->list); FillInsertableElemList(doc, el, list->list); list->elem = el; return list->list; } /*---------------------------------------------------------------------- InsertableElement_DoInsertElement Insert the specified element. @param el Element to insert (ElemListElement) ----------------------------------------------------------------------*/ void InsertableElement_DoInsertElement(void* el) { ElemListElement elem = (ElemListElement)el; Element ref = elem->refElem; ElementType refType = TtaGetElementType(ref); Document doc = TtaGetDocument(ref); Element newEl = NULL; SSchema templateSSchema; #ifdef AMAYA_DEBUG printf("insert %s into %s\n", ElemListElement_GetName(elem), TtaGetElementTypeName(refType)); #endif /* AMAYA_DEBUG */ #ifdef TEMPLATES templateSSchema = TtaGetSSchema("Template", doc); if(templateSSchema && refType.ElSSchema==templateSSchema) { switch(refType.ElTypeNum) { case Template_EL_repeat: if (elem->typeClass==DefinedComponent) newEl = Template_InsertRepeatChild(doc, ref, (Declaration)elem->elem.component.declaration, -1); break; case Template_EL_bag: newEl = Template_InsertBagChild(doc, ref, (Declaration)elem->elem.component.declaration); break; default: break; } } #endif /* TEMPLATES */ if(newEl) { TtaSelectElement(doc, newEl); TtaSetStatusSelectedElement(doc, 1, newEl); } }