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

Last change on this file since 16 was 15, checked in by Bayard Gildas, 6 years ago

sources reformatted with flair-format-dir script

File size: 9.8 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__
38RT_HEAP xml_heap;
39
40void xml2_free(void *mem) {
41  // Printf("free %x\n",mem);
42  if (mem == NULL)
43    return;
44  int status = rt_heap_free(&xml_heap, mem);
45
46  if (status != 0) {
47    printf("libxml2: rt_heap_free error (%s)\n", strerror(-status));
48  }
49}
50
51void *xml2_alloc(size_t sz) {
52  void *ptr;
53  // printf("alloc %i\n",sz);
54  int status = rt_heap_alloc(&xml_heap, sz, TM_NONBLOCK, &ptr);
55  if (status != 0) {
56    printf("libxml2: rt_heap_alloc error (%s)\n", strerror(-status));
57  }
58  // Printf("alloc %x %i\n",ptr,sz);
59
60  return ptr;
61}
62
63void *xml2_realloc(void *emem, size_t sz) {
64  // Printf("realloc %x %i -> %i\n",emem,sz,sz);
65  void *mem_re;
66
67  if (emem == NULL) {
68    return xml2_alloc(sz);
69  } else if (sz == 0) {
70    xml2_free(emem);
71  }
72
73  mem_re = xml2_alloc(sz);
74
75  memcpy(mem_re, emem, sz);
76
77  xml2_free(emem);
78
79  return mem_re;
80}
81
82char *xml2_strdup(const char *str) {
83  // printf("strdup %s\n",str);
84  char *s = (char *)xml2_alloc(strlen(str) + 1);
85  if (s == NULL)
86    return NULL;
87
88  strcpy(s, str);
89  return s;
90}
91#endif //__XENO__
92}
93
94Widget_impl::Widget_impl(Widget *self, const Widget *parent, string name,
95                         string type) {
96  // Printf("Widget %s\n",name.c_str());
97  isenabled = true;
98  file_node = NULL;
99  this->self = self;
100
101  // n'est execute qu'une fois lorsqu'on construit le FrameworkManager
102  if (parent == NULL) {
103#ifdef __XENO__
104    string tmp_name;
105    tmp_name = name + "-xml";
106    int status = rt_heap_create(&xml_heap, tmp_name.c_str(), XML_HEAP, H_FIFO);
107    if (status != 0) {
108      self->Err("rt_heap_create error (%s)\n", strerror(-status));
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    RT_HEAP_INFO info;
191    status = rt_heap_inquire(&xml_heap, &info);
192    if (status != 0) {
193      self->Err("rt_heap_inquire error (%s)\n", strerror(-status));
194    }
195    if (info.usedmem != 0)
196      self->Err("fuite memoire xml heap (%ld)\n", info.usedmem);
197    // Printf("fin heap xml\n");
198    status = rt_heap_delete(&xml_heap);
199    if (status != 0) {
200      self->Err("rt_heap_delete error (%s)\n", strerror(-status));
201    }
202#endif
203  }
204  // Printf("destruction widget %s ok\n",self->ObjectName().c_str());
205}
206
207void Widget_impl::AddChild(const Widget *child) {
208  childs.push_back((Widget *)child);
209}
210
211void Widget_impl::RemoveChild(const Widget *child) {
212  for (vector<Widget *>::iterator it = childs.begin(); it < childs.end();
213       it++) {
214    if (*it == child) {
215      childs.erase(it);
216      break;
217    }
218  }
219}
220
221xmlDocPtr Widget_impl::CopyDoc(void) { return xmlCopyDoc(send_doc, 1); }
222
223void Widget_impl::ClearXmlProps(void) {
224  xmlUnlinkNode(send_node);
225  xmlFreeNode(send_node);
226
227  xmlNodePtr node;
228  node = xmlDocGetRootElement(send_doc);
229
230  if (node == NULL) { // il ne reste plus rien, on refait le rootelement
231    send_node = xmlNewNode(NULL, (xmlChar *)XML_ROOT_TYPE);
232    xmlSetProp(send_node, (xmlChar *)"name",
233               (xmlChar *)self->ObjectName().c_str());
234    xmlDocSetRootElement(send_doc, send_node);
235  } else {
236    while (node->children != NULL)
237      node = node->children;
238    send_node = xmlNewNode(NULL, (xmlChar *)self->ObjectType().c_str());
239    xmlSetProp(send_node, (xmlChar *)"name",
240               (xmlChar *)self->ObjectName().c_str());
241    xmlAddChild(node, send_node);
242  }
243}
244
245void Widget_impl::printSendNode() {
246
247  xmlChar *xmlbuff;
248  int buffersize;
249  xmlDocDumpFormatMemory(send_doc, &xmlbuff, &buffersize, 1);
250  Printf("xml:\n%s\n", xmlbuff);
251  xmlFree(xmlbuff);
252}
253
254void Widget_impl::SendXml(void) {
255  if (getUiCom() != NULL) {
256    xmlChar *xmlbuff;
257    int buffersize;
258    xmlDocDumpFormatMemory(send_doc, &xmlbuff, &buffersize, 0);
259    getUiCom()->Send((char *)xmlbuff, buffersize);
260    xmlFree(xmlbuff);
261
262    ClearXmlProps();
263  }
264}
265
266void Widget_impl::setEnabled(bool status) {
267  self->SetVolatileXmlProp("IsEnabled", status);
268  SendXml();
269}
270
271void Widget_impl::ProcessXML(xmlNode *node) {
272  // Printf("ProcessXML %s %s\n",xmlGetProp(send_node,
273  // (xmlChar*)"name"),send_node->name);
274  xmlNode *cur_node = NULL;
275
276  for (size_t i = 0; i < childs.size(); i++) {
277    for (cur_node = node; cur_node; cur_node = cur_node->next) {
278      if (cur_node->type == XML_ELEMENT_NODE) {
279        // Printf("recherche %s\n", xmlGetProp(cur_node, (xmlChar*)"name"));
280        xmlChar *name = NULL;
281        name = xmlGetProp(cur_node, (xmlChar *)"name");
282        if (!xmlStrcmp((xmlChar *)childs[i]->ObjectName().c_str(), name)) {
283          // Printf("correspond %s\n",childs[i]->ObjectName().c_str());
284          xmlChar *new_name = NULL;
285          new_name = xmlGetProp(cur_node, (xmlChar *)"new_name");
286          if (new_name != NULL) {
287            unsigned char *ren_name =
288                new_name; // xmlGetProp(cur_node, (xmlChar*)"new_name");
289            self->Warn(
290                "%s existe deja, renommage en %s; possiblite de problemes!!\n",
291                childs[i]->ObjectName().c_str(), new_name);
292            childs[i]->Object::pimpl_->name = ((const char *)ren_name);
293            xmlSetProp(childs[i]->pimpl_->send_node, (xmlChar *)"name",
294                       xmlGetProp(cur_node, (xmlChar *)"new_name"));
295            xmlFree(new_name);
296            if (name != NULL)
297              xmlFree(name);
298            break;
299          }
300
301          if (name != NULL)
302            xmlFree(name);
303
304          // update file node
305          xmlAttr *cur_prop = NULL;
306          // xmlAttr *file_prop = NULL;
307          for (cur_prop = cur_node->properties; cur_prop;
308               cur_prop = cur_prop->next) {
309            // Printf("rcv prop %s
310            // %s\n",cur_prop->name,cur_prop->children->content);
311            xmlSetProp(childs[i]->pimpl_->file_node, cur_prop->name,
312                       cur_prop->children->content);
313          }
314
315          childs[i]->XmlEvent();
316
317          childs[i]->pimpl_->ProcessXML(cur_node->children);
318          break;
319        }
320        if (name != NULL)
321          xmlFree(name);
322      }
323    }
324  }
325
326  // printf("fin ProcessXML %s %s\n",xmlGetProp(send_node,
327  // (xmlChar*)"name"),send_node->name);
328}
329
330xmlNodePtr Widget_impl::GetNodeByProp(xmlNodePtr doc, xmlChar *type,
331                                      xmlChar *prop, xmlChar *value) {
332  // printf("cherche keyword: %s %s %s\n", type,prop,value);
333  xmlNode *cur_node = NULL;
334  for (cur_node = doc; cur_node; cur_node = cur_node->next) {
335    if (cur_node->type == XML_ELEMENT_NODE) {
336      // printf("node %s %s\n",xmlGetProp(cur_node,
337      // (xmlChar*)"name"),cur_node->name);
338      xmlChar *test = NULL;
339      test = xmlGetProp(cur_node, prop);
340      if (!xmlStrcmp(test, value) && !xmlStrcmp(cur_node->name, type)) {
341        // printf("ok\n");
342        if (test != NULL)
343          xmlFree(test);
344        return cur_node;
345      }
346      if (test != NULL)
347        xmlFree(test);
348    }
349  }
350
351  return NULL;
352}
Note: See TracBrowser for help on using the repository browser.