source: flair-src/branches/sanscv/lib/FlairCore/src/Widget_impl.cpp @ 326

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

removing opencv dependency

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 rt_xml_heap;
36
37void rt_xml2_free(void *mem) {
38  // Printf("free %x\n",mem);
39  if (mem == NULL)
40    return;
41  int status = rt_heap_free(&rt_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 *rt_xml2_alloc(size_t sz) {
50  void *ptr;
51  // printf("alloc %i\n",sz);
52  int status = rt_heap_alloc(&rt_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 *rt_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 rt_xml2_alloc(sz);
68  } else if (sz == 0) {
69    rt_xml2_free(emem);
70  }
71
72  mem_re = rt_xml2_alloc(sz);
73
74  memcpy(mem_re, emem, sz);
75
76  rt_xml2_free(emem);
77
78  return mem_re;
79}
80
81char *rt_xml2_strdup(const char *str) {
82  // printf("strdup %s\n",str);
83  char *s = (char *)rt_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(&rt_xml_heap, tmp_name.c_str(), RT_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(rt_xml2_free, rt_xml2_alloc, rt_xml2_realloc, rt_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(&rt_xml_heap, &info);
192    if (status != 0) {
193      char errorMsg[256];
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(&rt_xml_heap);
200    if (status != 0) {
201      char errorMsg[256];
202      self->Err("rt_heap_delete error (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
203    }
204#endif
205  }
206  // Printf("destruction widget %s ok\n",self->ObjectName().c_str());
207}
208
209void Widget_impl::AddChild(const Widget *child) {
210  childs.push_back((Widget *)child);
211}
212
213void Widget_impl::RemoveChild(const Widget *child) {
214  for (vector<Widget *>::iterator it = childs.begin(); it < childs.end();
215       it++) {
216    if (*it == child) {
217      childs.erase(it);
218      break;
219    }
220  }
221}
222
223xmlDocPtr Widget_impl::CopyDoc(void) { return xmlCopyDoc(send_doc, 1); }
224
225void Widget_impl::ClearXmlProps(void) {
226  xmlUnlinkNode(send_node);
227  xmlFreeNode(send_node);
228
229  xmlNodePtr node;
230  node = xmlDocGetRootElement(send_doc);
231
232  if (node == NULL) { // il ne reste plus rien, on refait le rootelement
233    send_node = xmlNewNode(NULL, (xmlChar *)XML_ROOT_TYPE);
234    xmlSetProp(send_node, (xmlChar *)"name",
235               (xmlChar *)self->ObjectName().c_str());
236    xmlDocSetRootElement(send_doc, send_node);
237  } else {
238    while (node->children != NULL)
239      node = node->children;
240    send_node = xmlNewNode(NULL, (xmlChar *)self->ObjectType().c_str());
241    xmlSetProp(send_node, (xmlChar *)"name",
242               (xmlChar *)self->ObjectName().c_str());
243    xmlAddChild(node, send_node);
244  }
245}
246
247void Widget_impl::printSendNode() {
248
249  xmlChar *xmlbuff;
250  int buffersize;
251  xmlDocDumpFormatMemory(send_doc, &xmlbuff, &buffersize, 1);
252  Printf("xml:\n%s\n", xmlbuff);
253  xmlFree(xmlbuff);
254}
255
256void Widget_impl::SendXml(void) {
257  if (getUiCom() != NULL) {
258    xmlChar *xmlbuff;
259    int buffersize;
260    xmlDocDumpFormatMemory(send_doc, &xmlbuff, &buffersize, 0);
261    getUiCom()->Send((char *)xmlbuff, buffersize);
262    xmlFree(xmlbuff);
263
264    ClearXmlProps();
265  }
266}
267
268void Widget_impl::setEnabled(bool status) {
269  self->SetVolatileXmlProp("IsEnabled", status);
270  SendXml();
271}
272
273void Widget_impl::ProcessXML(xmlNode *node) {
274  // Printf("ProcessXML %s %s\n",xmlGetProp(send_node,
275  // (xmlChar*)"name"),send_node->name);
276  xmlNode *cur_node = NULL;
277
278  for (size_t i = 0; i < childs.size(); i++) {
279    for (cur_node = node; cur_node; cur_node = cur_node->next) {
280      if (cur_node->type == XML_ELEMENT_NODE) {
281        // Printf("recherche %s\n", xmlGetProp(cur_node, (xmlChar*)"name"));
282        xmlChar *name = NULL;
283        name = xmlGetProp(cur_node, (xmlChar *)"name");
284        if (!xmlStrcmp((xmlChar *)childs[i]->ObjectName().c_str(), name)) {
285          // Printf("correspond %s\n",childs[i]->ObjectName().c_str());
286          xmlChar *new_name = NULL;
287          new_name = xmlGetProp(cur_node, (xmlChar *)"new_name");
288          if (new_name != NULL) {
289            unsigned char *ren_name =
290                new_name; // xmlGetProp(cur_node, (xmlChar*)"new_name");
291            self->Warn(
292                "%s existe deja, renommage en %s; possiblite de problemes!!\n",
293                childs[i]->ObjectName().c_str(), new_name);
294            childs[i]->Object::pimpl_->name = ((const char *)ren_name);
295            xmlSetProp(childs[i]->pimpl_->send_node, (xmlChar *)"name",
296                       xmlGetProp(cur_node, (xmlChar *)"new_name"));
297            xmlFree(new_name);
298            if (name != NULL)
299              xmlFree(name);
300            break;
301          }
302
303          if (name != NULL)
304            xmlFree(name);
305
306          // update file node
307          xmlAttr *cur_prop = NULL;
308          // xmlAttr *file_prop = NULL;
309          for (cur_prop = cur_node->properties; cur_prop;
310               cur_prop = cur_prop->next) {
311            // Printf("rcv prop %s
312            // %s\n",cur_prop->name,cur_prop->children->content);
313            xmlSetProp(childs[i]->pimpl_->file_node, cur_prop->name,
314                       cur_prop->children->content);
315          }
316
317          childs[i]->XmlEvent();
318
319          childs[i]->pimpl_->ProcessXML(cur_node->children);
320          break;
321        }
322        if (name != NULL)
323          xmlFree(name);
324      }
325    }
326  }
327
328  // printf("fin ProcessXML %s %s\n",xmlGetProp(send_node,
329  // (xmlChar*)"name"),send_node->name);
330}
331
332xmlNodePtr Widget_impl::GetNodeByProp(xmlNodePtr doc, xmlChar *type,
333                                      xmlChar *prop, xmlChar *value) {
334  // printf("cherche keyword: %s %s %s\n", type,prop,value);
335  xmlNode *cur_node = NULL;
336  for (cur_node = doc; cur_node; cur_node = cur_node->next) {
337    if (cur_node->type == XML_ELEMENT_NODE) {
338      // printf("node %s %s\n",xmlGetProp(cur_node,
339      // (xmlChar*)"name"),cur_node->name);
340      xmlChar *test = NULL;
341      test = xmlGetProp(cur_node, prop);
342      if (!xmlStrcmp(test, value) && !xmlStrcmp(cur_node->name, type)) {
343        // printf("ok\n");
344        if (test != NULL)
345          xmlFree(test);
346        return cur_node;
347      }
348      if (test != NULL)
349        xmlFree(test);
350    }
351  }
352
353  return NULL;
354}
Note: See TracBrowser for help on using the repository browser.