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, 8 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.