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

Last change on this file since 149 was 133, checked in by Sanahuja Guillaume, 7 years ago

modif sterror

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