source: flair-src/trunk/lib/FlairCore/src/Widget_impl.cpp @ 2

Last change on this file since 2 was 2, checked in by Sanahuja Guillaume, 6 years ago

flaircore

File size: 10.4 KB
Line 
1// %flair:license{
2// This file is part of the Flair framework distributed under the
3// CECILL-C License, Version 1.0.
4// %flair:license}
5//  created:    2012/05/02
6//  filename:   Widget.cpp
7//
8//  author:     Guillaume Sanahuja
9//              Copyright Heudiasyc UMR UTC/CNRS 7253
10//
11//  version:    $Id: $
12//
13//  purpose:    classe pour widget
14//
15//
16/*********************************************************************/
17
18#include "Widget.h"
19#include "Widget_impl.h"
20#include "Object_impl.h"
21#include "FrameworkManager.h"
22#include "FrameworkManager_impl.h"
23#include "config.h"
24#ifdef __XENO__
25#include <native/heap.h>
26#else
27#include <errno.h>
28#include <cstring>
29#endif
30
31using std::string;
32using std::vector;
33using namespace flair::core;
34using namespace flair::gui;
35
36namespace{
37#ifdef __XENO__
38    RT_HEAP xml_heap;
39
40    void xml2_free(void *mem)
41    {
42        //Printf("free %x\n",mem);
43        if(mem==NULL) return;
44        int status=rt_heap_free(&xml_heap,mem);
45
46        if(status!=0)
47        {
48            printf("libxml2: rt_heap_free error (%s)\n",strerror(-status));
49        }
50    }
51
52    void *xml2_alloc(size_t sz)
53    {
54        void *ptr;
55        //printf("alloc %i\n",sz);
56        int status=rt_heap_alloc(&xml_heap,sz,TM_NONBLOCK ,&ptr);
57        if(status!=0)
58        {
59            printf("libxml2: rt_heap_alloc error (%s)\n",strerror(-status));
60        }
61        //Printf("alloc %x %i\n",ptr,sz);
62
63        return ptr;
64
65    }
66
67    void *xml2_realloc(void *emem,size_t sz)
68    {
69        //Printf("realloc %x %i -> %i\n",emem,sz,sz);
70        void *mem_re;
71
72
73        if (emem == NULL)
74        {
75            return xml2_alloc(sz);
76        }
77        else if (sz == 0)
78        {
79            xml2_free(emem);
80        }
81
82        mem_re = xml2_alloc(sz);
83
84        memcpy(mem_re, emem, sz);
85
86        xml2_free(emem);
87
88        return mem_re;
89    }
90
91    char *xml2_strdup(const char * str)
92    {
93       // printf("strdup %s\n",str);
94        char *s = (char*)xml2_alloc(strlen(str) + 1);
95        if (s == NULL)
96           return NULL;
97
98        strcpy(s, str);
99        return s;
100
101    }
102#endif //__XENO__
103}
104
105Widget_impl::Widget_impl(Widget* self,const Widget* parent,string name,string type)
106{
107    //Printf("Widget %s\n",name.c_str());
108    isenabled=true;
109    file_node=NULL;
110    this->self=self;
111
112    //n'est execute qu'une fois lorsqu'on construit le FrameworkManager
113    if(parent==NULL)
114    {
115#ifdef __XENO__
116        string tmp_name;
117        tmp_name=name + "-xml";
118        int status=rt_heap_create(&xml_heap,tmp_name.c_str(),XML_HEAP,H_FIFO);
119        if(status!=0)
120        {
121            self->Err("rt_heap_create error (%s)\n",strerror(-status));
122        }
123
124        xmlMemSetup(xml2_free,xml2_alloc, xml2_realloc,xml2_strdup);
125#endif //__XENO__
126    }
127
128    //xml init
129    if(parent==NULL)
130    {
131        //create local doc
132        send_doc = xmlNewDoc((xmlChar*)"1.0");
133        send_node = xmlNewNode(NULL, (xmlChar*)type.c_str());
134        xmlDocSetRootElement(send_doc, send_node);
135        xmlSetProp(send_node,(xmlChar*)"name",(xmlChar*)self->ObjectName().c_str());
136    }
137    else
138    {
139        parent->pimpl_->AddChild(self);
140
141        //get node corresponding to this widget in the xml file
142        if(parent->pimpl_->file_node!=NULL)
143        {
144            xmlChar* search=xmlCharStrdup(type.c_str());
145            file_node=GetNodeByProp(parent->pimpl_->file_node->xmlChildrenNode,search,(xmlChar*)"name",(xmlChar*)name.c_str());
146            xmlFree(search);
147        }
148        else
149        {
150            self->Err("parent->file_node is NULL\n");
151        }
152
153        if(file_node==NULL)
154        {
155            self->Warn("%s, no match found in xml file\n",type.c_str());
156            xmlNode *node;
157            node=xmlNewNode(NULL, (xmlChar*)type.c_str());
158            xmlSetProp(node,(xmlChar*)"name",(xmlChar*)name.c_str());
159            file_node=xmlAddChild(parent->pimpl_->file_node,node);
160            //((Widget*)getFrameworkManager())->pimpl_->PrintXml();
161        }
162
163        send_doc=parent->pimpl_->CopyDoc();
164
165        //on recupere le dernier node
166        xmlNodePtr node=xmlDocGetRootElement(send_doc);
167        while(node->children!=NULL) node=node->children;
168
169        //on ajoute le node du widget
170        send_node = xmlNewNode(NULL, (xmlChar*)type.c_str());
171        xmlSetProp(send_node,(xmlChar*)"name",(xmlChar*)name.c_str());
172        xmlAddChild(node,send_node);
173    }
174
175    //Printf("Widget ok %s\n",name.c_str());
176}
177
178Widget_impl::~Widget_impl()
179{
180    //Printf("destruction widget %s\n",self->ObjectName().c_str());
181
182    if(self->Parent()!=NULL) ((Widget*)(self->Parent()))->pimpl_->RemoveChild(self);
183
184    //on efface les widgets enfants avant d'envoyer son propre delete au sol
185    //dans le delete child on modifie le child du parent, donc on se refere toujours au premier
186    while(childs.size()!=0)
187    {
188        //Printf("child %i %s\n",childs.size(),childs.front()->ObjectName().c_str());
189        if(childs.front()!=NULL) delete childs.front();
190    }
191    childs.clear();
192
193    self->SetVolatileXmlProp("Delete",true);
194
195    if(self->Parent()!=NULL) SendXml();
196
197    xmlFreeDoc(send_doc);
198
199    if(self->Parent()==NULL)
200    {
201        xmlCleanupParser();
202#ifdef __XENO__
203        int status;
204        RT_HEAP_INFO info;
205        status=rt_heap_inquire(&xml_heap,&info);
206        if(status!=0)
207        {
208            self->Err("rt_heap_inquire error (%s)\n",strerror(-status));
209        }
210        if(info.usedmem!=0) self->Err("fuite memoire xml heap (%ld)\n",info.usedmem);
211    //Printf("fin heap xml\n");
212        status=rt_heap_delete(&xml_heap);
213        if(status!=0)
214        {
215            self->Err("rt_heap_delete error (%s)\n",strerror(-status));
216        }
217#endif
218    }
219    //Printf("destruction widget %s ok\n",self->ObjectName().c_str());
220}
221
222void Widget_impl::AddChild(const Widget* child)
223{
224    childs.push_back((Widget*)child);
225}
226
227void Widget_impl::RemoveChild(const Widget* child)
228{
229    for(vector<Widget*>::iterator it=childs.begin() ; it < childs.end(); it++ )
230    {
231        if(*it==child)
232        {
233            childs.erase(it);
234            break;
235        }
236    }
237}
238
239xmlDocPtr Widget_impl::CopyDoc(void)
240{
241    return xmlCopyDoc(send_doc,1);
242}
243
244void Widget_impl::ClearXmlProps(void) {
245    xmlUnlinkNode(send_node);
246    xmlFreeNode(send_node);
247
248    xmlNodePtr node;
249    node=xmlDocGetRootElement(send_doc);
250
251    if(node==NULL) {//il ne reste plus rien, on refait le rootelement
252        send_node = xmlNewNode(NULL, (xmlChar*)XML_ROOT_TYPE);
253        xmlSetProp(send_node,(xmlChar*)"name",(xmlChar*)self->ObjectName().c_str());
254        xmlDocSetRootElement(send_doc, send_node);
255    } else {
256        while(node->children!=NULL) node=node->children;
257        send_node = xmlNewNode(NULL, (xmlChar*)self->ObjectType().c_str());
258        xmlSetProp(send_node,(xmlChar*)"name",(xmlChar*)self->ObjectName().c_str());
259        xmlAddChild(node,send_node);
260    }
261}
262
263void Widget_impl::printSendNode() {
264
265    xmlChar *xmlbuff;
266    int buffersize;
267    xmlDocDumpFormatMemory(send_doc, &xmlbuff, &buffersize, 1);
268    Printf("xml:\n%s\n",xmlbuff);
269    xmlFree(xmlbuff);
270}
271
272void Widget_impl::SendXml(void)
273{
274    if(getUiCom()!=NULL) {
275        xmlChar *xmlbuff;
276        int buffersize;
277        xmlDocDumpFormatMemory(send_doc, &xmlbuff, &buffersize, 0);
278        getUiCom()->Send((char*)xmlbuff,buffersize);
279        xmlFree(xmlbuff);
280
281        ClearXmlProps();
282    }
283}
284
285void Widget_impl::setEnabled(bool status) {
286    self->SetVolatileXmlProp("IsEnabled",status);
287    SendXml();
288}
289
290
291void Widget_impl::ProcessXML(xmlNode *node)
292{
293    //Printf("ProcessXML %s %s\n",xmlGetProp(send_node, (xmlChar*)"name"),send_node->name);
294    xmlNode *cur_node = NULL;
295
296    for(size_t i=0;i<childs.size();i++)
297    {
298        for (cur_node = node; cur_node; cur_node = cur_node->next)
299        {
300            if (cur_node->type == XML_ELEMENT_NODE)
301            {
302                //Printf("recherche %s\n", xmlGetProp(cur_node, (xmlChar*)"name"));
303                xmlChar* name=NULL;
304                name=xmlGetProp(cur_node, (xmlChar*)"name");
305                if (!xmlStrcmp((xmlChar *)childs[i]->ObjectName().c_str(), name))
306                {
307                    //Printf("correspond %s\n",childs[i]->ObjectName().c_str());
308                    xmlChar* new_name=NULL;
309                    new_name=xmlGetProp(cur_node, (xmlChar*)"new_name");
310                    if(new_name!=NULL)
311                    {
312                        unsigned char* ren_name=new_name;//xmlGetProp(cur_node, (xmlChar*)"new_name");
313                        self->Warn("%s existe deja, renommage en %s; possiblite de problemes!!\n",childs[i]->ObjectName().c_str(),new_name);
314                        childs[i]->Object::pimpl_->name=((const char*)ren_name);
315                        xmlSetProp(childs[i]->pimpl_->send_node,(xmlChar*)"name",xmlGetProp(cur_node, (xmlChar*)"new_name"));
316                        xmlFree(new_name);
317                        if(name!=NULL) xmlFree(name);
318                        break;
319                    }
320
321                    if(name!=NULL) xmlFree(name);
322
323                    //update file node
324                    xmlAttr *cur_prop = NULL;
325                    //xmlAttr *file_prop = NULL;
326                    for (cur_prop = cur_node->properties; cur_prop; cur_prop = cur_prop->next)
327                    {
328                        //Printf("rcv prop %s %s\n",cur_prop->name,cur_prop->children->content);
329                        xmlSetProp(childs[i]->pimpl_->file_node,cur_prop->name,cur_prop->children->content);
330                    }
331
332                    childs[i]->XmlEvent();
333
334                    childs[i]->pimpl_->ProcessXML(cur_node->children);
335                    break;
336
337                }
338                if(name!=NULL) xmlFree(name);
339            }
340        }
341    }
342
343    //printf("fin ProcessXML %s %s\n",xmlGetProp(send_node, (xmlChar*)"name"),send_node->name);
344}
345
346
347xmlNodePtr Widget_impl::GetNodeByProp(xmlNodePtr doc,xmlChar *type,xmlChar *prop,xmlChar *value)
348{
349        //printf("cherche keyword: %s %s %s\n", type,prop,value);
350    xmlNode *cur_node = NULL;
351        for (cur_node = doc; cur_node; cur_node = cur_node->next)
352    {
353        if (cur_node->type == XML_ELEMENT_NODE)
354        {
355            //printf("node %s %s\n",xmlGetProp(cur_node, (xmlChar*)"name"),cur_node->name);
356            xmlChar *test = NULL;
357            test=xmlGetProp(cur_node, prop);
358            if(!xmlStrcmp(test,value) && !xmlStrcmp(cur_node->name,type ))
359            {
360                //printf("ok\n");
361                if(test!=NULL) xmlFree(test);
362                return cur_node;
363            }
364            if(test!=NULL) xmlFree(test);
365        }
366    }
367
368    return NULL;
369}
Note: See TracBrowser for help on using the repository browser.