]> git.llucax.com Git - z.facultad/75.42/plaqui.git/blob - Client/src/principal.cpp
* Se completa el diaglo "Acerca de" del cliente
[z.facultad/75.42/plaqui.git] / Client / src / principal.cpp
1
2 #include "principal.h"
3 #include <iostream>
4 #include <sstream>
5 #include <string>
6 #include "item_codo.h"
7 #include "item_conduct.h"
8 #include "item_exclusa.h"
9 #include "item_tank.h"
10 #include "item_pump.h"
11 #include "item_union.h"
12 #include "item_drain.h"
13 #include "item_not.h"
14 #include "item_or.h"
15 #include "item_and.h"
16 #include <unistd.h>
17 #include <glibmm/thread.h>
18
19 #define INFINITO 99999999
20
21 Principal::Principal(BaseObjectType *co, const Glib::RefPtr<Gnome::Glade::Xml> &rg):Gtk::Window(co),refXml(rg)
22 {
23         Gtk::MenuItem *conect=0, *exit=0, *about=0, *mnu_prop=0, *mnu_disconnect=0, *server_stop=0;
24         Gtk::Button *bar_connect=0, *close_about=0;
25         Gtk::Image *plaqui_logo;
26         txt_view = 0;
27         work_place = 0;
28         lbl_cap_flujo = lbl_cap_extra = lbl_extra = lbl_nombre = lbl_color = lbl_flujo = 0;
29         btn_simulate = btn_pause = 0;
30
31         anim_frames[0] = Gdk::Pixbuf::create_from_file(PACKAGE_DATA_DIR"/plaqui-client/pixmaps/anim_0.png");
32         anim_frames[1] = Gdk::Pixbuf::create_from_file(PACKAGE_DATA_DIR"/plaqui-client/pixmaps/anim_1.png");
33         anim_frames[2] = Gdk::Pixbuf::create_from_file(PACKAGE_DATA_DIR"/plaqui-client/pixmaps/anim_2.png");
34         anim_frames[3] = Gdk::Pixbuf::create_from_file(PACKAGE_DATA_DIR"/plaqui-client/pixmaps/anim_3.png");
35         anim_frames[4] = Gdk::Pixbuf::create_from_file(PACKAGE_DATA_DIR"/plaqui-client/pixmaps/anim_4.png");
36         anim_frames[5] = Gdk::Pixbuf::create_from_file(PACKAGE_DATA_DIR"/plaqui-client/pixmaps/anim_5.png");
37         anim_frames[6] = Gdk::Pixbuf::create_from_file(PACKAGE_DATA_DIR"/plaqui-client/pixmaps/anim_6.png");
38         anim_frames[7] = Gdk::Pixbuf::create_from_file(PACKAGE_DATA_DIR"/plaqui-client/pixmaps/anim_7.png");
39         current_frame = 0;
40
41         plaqui_logo = anim = 0;
42         rg->get_widget("plaqui_logo", plaqui_logo);
43         plaqui_logo->set(PACKAGE_DATA_DIR"/plaqui-client/pixmaps/logo.png");
44
45         rg->get_widget("anim_frames", anim);
46         anim->set(anim_frames[current_frame]);
47
48         rg->get_widget("close_about", close_about);
49         rg->get_widget("dlgAbout", dlg_about);
50         rg->get_widget("btn_pausa", btn_pause);
51         rg->get_widget("btn_simular", btn_simulate);
52         rg->get_widget("btn_activar", btn_activar);
53         rg->get_widget("color_preview", color_preview);
54         rg->get_widget("lbl_nombre", lbl_nombre);
55         rg->get_widget("lbl_extra", lbl_extra);
56         rg->get_widget("lbl_cap_extra", lbl_cap_extra);
57         rg->get_widget("lbl_cap_flujo", lbl_cap_flujo);
58         rg->get_widget("lbl_flujo", lbl_flujo);
59         rg->get_widget("mnu_file_connect", conect);
60         rg->get_widget("mnu_file_disconnect", mnu_disconnect);
61         rg->get_widget("mnu_file_exit", exit);
62         rg->get_widget("mnu_help_about", about);
63         rg->get_widget("mnu_server_stop", server_stop);
64         rg->get_widget("mnu_prop", mnu_prop);
65         rg->get_widget_derived("dlg_property", dlg_property);
66         rg->get_widget_derived("dlgConectar", dlg_conectar);
67         rg->get_widget("txt_view", txt_view);
68         rg->get_widget("bar_connect", bar_connect);
69         rg->get_widget("work_place", work_place);
70         rg->get_widget("ico_conected", ico_conected);
71
72         work_place->signal_expose_event().connect( SigC::slot(*this, &Principal::on_workplace_expose_event) );
73         dlg_property->get_ok_button()->signal_clicked().connect( SigC::slot(*this, &Principal::on_dlg_property_ok) );
74         dlg_conectar->get_ok_button()->signal_clicked().connect( SigC::slot(*this, &Principal::on_dlg_connect_ok) );
75         mnu_prop->signal_activate().connect( SigC::slot(*this, &Principal::on_mnu_property));
76         mnu_disconnect->signal_activate().connect( SigC::slot(*this, &Principal::on_mnu_file_disconnect));
77         server_stop->signal_activate().connect( SigC::slot(*this, &Principal::on_mnu_server_stop_activate));
78         conect->signal_activate().connect( SigC::slot(*this, &Principal::on_mnu_file_connect));
79         bar_connect->signal_clicked().connect( SigC::slot(*this, &Principal::on_mnu_file_connect));
80         exit->signal_activate().connect( SigC::slot(*this, &Principal::on_mnu_file_exit));
81         about->signal_activate().connect( SigC::slot(*this, &Principal::on_mnu_help_about));
82         btn_activar->signal_clicked().connect( SigC::slot(*this, &Principal::on_btn_activar_clicked) );
83         btn_simulate->signal_clicked().connect( SigC::slot(*this, &Principal::on_btn_simulate_clicked) );
84         btn_pause->signal_clicked().connect( SigC::slot(*this, &Principal::on_btn_pause_clicked) );
85         close_about->signal_clicked().connect( SigC::slot(*dlg_about, &Gtk::Widget::hide) );
86         
87         conexion = NULL;
88         is_xml_loaded = false;
89         last_selected = NULL;
90         paused = true;
91         update_ui.connect( SigC::slot(*this, &Principal::update_items_prop ) );
92         load_xml_dispatch.connect( SigC::slot(*this, &Principal::loadXML ) );
93         gc = Gdk::GC::create(get_window());
94         color_low = Gdk::Color("blue");
95         color_high = Gdk::Color("red");
96         Gtk::Widget::get_default_colormap()->alloc_color(color_low);
97         Gtk::Widget::get_default_colormap()->alloc_color(color_high);
98 }
99
100 Principal::~Principal()
101 {
102 }
103
104 void Principal::on_realize()
105 {
106         Gtk::Window::on_realize();
107 }
108
109 bool Principal::on_workplace_expose_event(GdkEventExpose *e)
110 {
111         Glib::RefPtr<Gdk::Window> window = work_place->get_window();
112
113         int x1, y1, x2, y2;
114         // Dibujo las lineas
115         std::map<const std::string, ViewItem *>::iterator i;
116         for(i=mapItems.begin(); i!=mapItems.end(); i++) {
117                 if (dynamic_cast<ViewAnd *>(i->second) || dynamic_cast<ViewOr *>(i->second) || dynamic_cast<ViewNot *>(i->second)) {
118                         x1 = i->second->x + i->second->in_x;
119                         y1 = i->second->y + i->second->in_y;
120                         std::list<std::string>::iterator linea;
121                         for(linea=i->second->in_lines.begin(); linea!=i->second->in_lines.end(); linea++) {
122                                 ViewItem *tmp = find_item(*linea);
123                                 x2 = tmp->x + tmp->out_x;
124                                 y2 = tmp->y + tmp->out_y;
125                                 if (tmp->get_open()) {
126                                         gc->set_foreground(color_high);
127                                 } else {
128                                         gc->set_foreground(color_low);
129                                 }
130                                 gc->set_line_attributes(3, Gdk::LINE_SOLID, Gdk::CAP_NOT_LAST, Gdk::JOIN_MITER);
131                                 window->draw_line(gc, x2+tmp->item_offset_x, y2+tmp->item_offset_y, x2+tmp->item_offset_x, y1+i->second->offset_y);
132                                 window->draw_line(gc, x2+tmp->item_offset_x, y1+i->second->offset_y, x1+i->second->offset_x, y1+i->second->offset_y);
133                                 window->draw_line(gc, x1, y1, x1+i->second->offset_x, y1+i->second->offset_y);
134                                 window->draw_line(gc, x2, y2, x2+tmp->item_offset_x, y2+tmp->item_offset_y);
135                         }
136                         x1 = i->second->x + i->second->out_x;
137                         y1 = i->second->y + i->second->out_y;
138                         for(linea=i->second->out_lines.begin(); linea!=i->second->out_lines.end(); linea++) {
139                                 ViewItem *tmp = find_item(*linea);
140                                 x2 = tmp->x + tmp->in_x;
141                                 y2 = tmp->y + tmp->in_y;
142                                 if (i->second->get_open()) {
143                                         gc->set_foreground(color_high);
144                                 } else {
145                                         gc->set_foreground(color_low);
146                                 }
147                                 gc->set_line_attributes(3, Gdk::LINE_SOLID, Gdk::CAP_NOT_LAST, Gdk::JOIN_MITER);
148                                 window->draw_line(gc, x1+i->second->offset_x, y1+i->second->offset_y, x1+i->second->offset_x, y2+tmp->item_offset_y);
149                                 window->draw_line(gc, x1+i->second->offset_x, y2+tmp->item_offset_y, x2+tmp->item_offset_x, y2+tmp->item_offset_y);
150                                 window->draw_line(gc, x1, y1, x1+i->second->offset_x, y1+i->second->offset_y);
151                                 window->draw_line(gc, x2, y2, x2+tmp->item_offset_x, y2+tmp->item_offset_y);
152                         }
153                 }
154         }
155 }
156
157 ViewItem *Principal::find_item(std::string &_name)
158 {
159         std::map<const std::string, ViewItem *>::iterator i;
160         for(i=mapItems.begin(); i!=mapItems.end(); i++) {
161                 if (i->second->get_name() == _name) {
162                         return i->second;
163                 }
164         }
165         return NULL;
166 }
167
168 void Principal::on_dlg_connect_ok()
169 {
170         if (conexion == NULL) {
171                 // Creo la conexion
172                 try {
173                         conexion = new PlaQui::Server::ControlClient(dlg_conectar->get_server_name(), dlg_conectar->get_server_port());
174                 }
175                 catch (...) {
176                         txt_view->get_buffer()->insert_at_cursor("NO SE PUDO CREAR OBJETO\n");
177                         //delete conexion; XXX Si no me equivoco, si falla el
178                         //constructor, no se reserva la memoria (el delete no va).
179                         conexion = NULL;
180                         return;
181                 }
182
183                 // Conecto las señales
184                 conexion->signal_ok_received().connect( SigC::slot(*this, &Principal::on_conexion_ok) );
185                 conexion->signal_error().connect( SigC::slot(*this, &Principal::on_conexion_fatal_error) );
186                 conexion->signal_error_received().connect( SigC::slot(*this, &Principal::on_conexion_error) );
187                 conexion->signal_finished().connect( SigC::slot(*this, &Principal::on_conexion_finished) );
188                 conexion->signal_frame_received().connect(SigC::slot(*this, &Principal::on_conexion_frame));
189                 // Lanzo la conexion!
190                 conexion->run();
191                 txt_view->get_buffer()->insert_at_cursor("CONNECTED\n");
192                 ico_conected->set( Gtk::Stock::YES , Gtk::IconSize(Gtk::ICON_SIZE_LARGE_TOOLBAR));
193
194                 // Pido la planta por defecto
195                 PlaQui::Server::Command c("plant", "get");
196                 c.add_arg("default");
197                 conexion->send(c);
198         }
199         dlg_conectar->hide();
200 }
201
202 void Principal::on_mnu_file_exit()
203 {
204         on_mnu_file_disconnect();
205         if (conexion) {
206                 conexion->finish();
207         }
208         // Espera a que termine realmente.
209         while (conexion) {
210                 Glib::usleep(100000); // 0,1 segundo
211         }
212         Gtk::Main::quit();
213 }
214
215 bool Principal::on_delete_event(GdkEventAny *e)
216 {
217         on_mnu_file_exit();
218         return false;
219 }
220
221 void Principal::on_mnu_server_stop_activate()
222 {
223         if (conexion == NULL) return;
224
225         PlaQui::Server::Command c("server", "stop");
226         conexion->send(c);
227 }
228
229 void Principal::on_btn_activar_clicked()
230 {
231         if ((conexion == NULL) || (last_selected == NULL)) return;
232
233         PlaQui::Server::Command c("plant", "set");
234         c.add_arg("default");
235         c.add_arg(last_selected->get_name());
236         c.add_arg("open");
237         
238         if (last_selected->get_open())
239                 c.add_arg("false");
240         else
241                 c.add_arg("true");
242
243         conexion->send(c);
244 }
245
246 void Principal::on_mnu_file_disconnect()
247 {
248         if (conexion == NULL) return;
249
250         PlaQui::Server::Command c("transmission", "stop");
251         c.add_arg(conexion->get_host());
252         c.add_arg("7528");
253         conexion->send(c);
254         PlaQui::Server::Command c2("connection", "stop");
255         c2.add_arg(conexion->get_host());
256         c2.add_arg(conexion->get_port());
257         conexion->send(c2);
258 }
259
260 void Principal::on_mnu_file_connect()
261 {
262         dlg_conectar->show();
263 }
264
265 void Principal::on_mnu_help_about()
266 {
267         dlg_about->run();
268 }
269
270 bool Principal::on_item_clicked(GdkEventButton *e, ViewItem *i)
271 {
272         
273         txt_view->get_buffer()->insert_at_cursor("Selecciono ");
274         txt_view->get_buffer()->insert_at_cursor(i->get_name());
275         txt_view->get_buffer()->insert_at_cursor("\n");
276
277         last_selected = i;
278         update_items_prop();
279 }
280
281 void Principal::update_items_prop()
282 {
283         if (last_selected != NULL) {
284                 lbl_nombre->set_text(last_selected->get_name());
285                 lbl_flujo->set_text(last_selected->get_actual_flow());
286                 lbl_extra->set_text(last_selected->get_extra());
287
288                 lbl_cap_flujo->set_text(last_selected->get_cap_flow());
289                 lbl_cap_extra->set_text(last_selected->get_cap_extra());
290
291                 color_preview->modify_bg(Gtk::STATE_NORMAL, last_selected->get_color());
292                 color_preview->queue_draw();
293         }
294
295         if (!paused) {
296                 current_frame++;
297                 if (current_frame > 7) {
298                         current_frame = 0;
299                 }
300                 anim->set(anim_frames[current_frame]);
301         }
302
303         // Mando a redibujar a todos los items
304         std::map<const std::string, ViewItem *>::iterator i;
305         for(i=mapItems.begin(); i!=mapItems.end(); i++) {
306                 i->second->queue_draw();
307         }
308         work_place->queue_draw();
309 }
310
311 void Principal::on_conexion_frame(const std::string &frame)
312 {
313         if (conexion != NULL) {
314                 read_status_xml(frame);
315         }
316 }
317
318 void Principal::on_conexion_finished()
319 {
320         txt_view->get_buffer()->insert_at_cursor("HANG UP\n");
321         ico_conected->set( Gtk::Stock::NO , Gtk::IconSize(Gtk::ICON_SIZE_LARGE_TOOLBAR));
322         conexion = NULL;
323         // Elimino la planta    
324         std::map<const std::string, ViewItem *>::iterator i;
325         for(i=mapItems.begin(); i!=mapItems.end(); i++) {
326                 delete i->second;
327         }
328         mapItems.clear();
329         is_xml_loaded = false;
330 }
331
332 void Principal::on_conexion_ok(const std::string &body)
333 {
334         /* lo paso a la carga del XML */
335         /* verifico que body este completo */
336         if ((body.find("</planta>")>0) && (body.find("<planta>")>0)) {
337                 //loadXML(body);
338                 xml_body = body;
339                 load_xml_dispatch();
340         } else {
341                 std::cout << body << std::endl;
342                 txt_view->get_buffer()->insert_at_cursor("<IN>\n");
343                 txt_view->get_buffer()->insert_at_cursor(Glib::locale_to_utf8(body));
344                 txt_view->get_buffer()->insert_at_cursor("</IN>\n");
345         }
346 }
347
348 void Principal::on_conexion_fatal_error(const PlaQui::Server::ControlClient::Error& code, const std::string& desc)
349 {
350         std::stringstream a;
351         std::string s;
352         a << code;
353         a >> s;
354         txt_view->get_buffer()->insert_at_cursor("Error de red nro. ");
355         txt_view->get_buffer()->insert_at_cursor(s);
356         txt_view->get_buffer()->insert_at_cursor(": ");
357         txt_view->get_buffer()->insert_at_cursor(desc);
358         txt_view->get_buffer()->insert_at_cursor("\n");
359 }
360
361 void Principal::on_conexion_error(unsigned code, const std::string& desc)
362 {
363         std::stringstream a;
364         std::string s;
365         a << code;
366         a >> s;
367         txt_view->get_buffer()->insert_at_cursor("El server dice que hay error nro. ");
368         txt_view->get_buffer()->insert_at_cursor(s);
369         txt_view->get_buffer()->insert_at_cursor(": ");
370         txt_view->get_buffer()->insert_at_cursor(desc);
371         txt_view->get_buffer()->insert_at_cursor("\n");
372 }
373
374 void Principal::loadXML()
375 {
376         // ya lo cargue
377         if (is_xml_loaded) return;
378
379         /* Parseo de ejemplo de un XML desde archivo */
380         xmlDocPtr document;
381         document = xmlParseMemory(xml_body.c_str(),xml_body.size());
382         if (document == NULL) {
383                 std::cout << "EEERRRRRRROOOOOOOOOO" << std::endl;
384                 return;
385         }
386         is_xml_loaded = true;
387         /* bien, el archivo se parseo bien! */
388         xmlNodePtr nodo, items;
389         nodo = document->children;
390
391         if (strcmp((char *)nodo->name, "planta") == 0) {
392                 items = nodo->children;
393                 while (items != NULL) {
394                         if (items->type == XML_ELEMENT_NODE) {
395                                 if (xmlStrcmp(items->name, BAD_CAST"bomba")==0) {
396                                         loadBomba(items);
397                                 } else if (xmlStrcmp(items->name, BAD_CAST"codo")==0) {
398                                         loadCodo(items);
399                                 } else if (xmlStrcmp(items->name, BAD_CAST"tubo")==0) {
400                                         loadConduct(items);
401                                 } else if (xmlStrcmp(items->name, BAD_CAST"exclusa")==0) {
402                                         loadExclusa(items);
403                                 } else if (xmlStrcmp(items->name, BAD_CAST"tanque")==0) {
404                                         loadTank(items);
405                                 } else if (xmlStrcmp(items->name, BAD_CAST"empalme")==0) {
406                                         loadUnion(items);
407                                 } else if (xmlStrcmp(items->name, BAD_CAST"drenaje")==0) {
408                                         loadDrain(items);
409                                 } else if (xmlStrcmp(items->name, BAD_CAST"and")==0) {
410                                         loadAnd(items);
411                                 } else if (xmlStrcmp(items->name, BAD_CAST"or")==0) {
412                                         loadOr(items);
413                                 } else if (xmlStrcmp(items->name, BAD_CAST"not")==0) {
414                                         loadNot(items);
415                                 }
416
417                         }
418                         items = items->next;
419                 }
420         }
421
422         xmlFreeDoc(document);
423
424         // Ya cargado el XML, mando un msg para empezar a recibir los frames!
425         PlaQui::Server::Command c("transmission", "start");
426         c.add_arg("default");
427         c.add_arg(conexion->get_host());
428         c.add_arg("7528");
429         conexion->send(c);
430 }
431
432 void Principal::loadNot(xmlNodePtr nodo)
433 {
434         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
435         std::string id = (char *)xmlGetProp(nodo, BAD_CAST"id");
436         int orientacion=0, x, y;
437
438         ViewNot *p;
439         nodo = nodo->children;
440         while (nodo != NULL) {
441                 if (nodo->type == XML_ELEMENT_NODE) {
442                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
443                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
444                                 p = new ViewNot(name, orientacion);
445                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
446                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
447                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
448                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
449                         } else if (xmlStrcmp(nodo->name, BAD_CAST"salida") == 0) {
450                                 p->out_lines.push_back((char *)XML_GET_CONTENT(nodo->children));
451                         } else if (xmlStrcmp(nodo->name, BAD_CAST"entrada") == 0) {
452                                 p->in_lines.push_back((char *)XML_GET_CONTENT(nodo->children));
453                         }
454                 }
455                 nodo = nodo->next;
456         }
457         
458         p->signal_button_press_event().connect(SigC::bind( SigC::slot(*this, &Principal::on_item_clicked), p) );
459         p->set_position(x,y);
460         work_place->put(*p, x, y);
461         p->show();
462         // los agrego al hash
463         mapItems[name] = p;
464 }
465
466 void Principal::loadOr(xmlNodePtr nodo)
467 {
468         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
469         std::string id = (char *)xmlGetProp(nodo, BAD_CAST"id");
470         int orientacion=0, x, y;
471
472         ViewOr *p;
473
474         nodo = nodo->children;
475         while (nodo != NULL) {
476                 if (nodo->type == XML_ELEMENT_NODE) {
477                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
478                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
479                                 p = new ViewOr(name, orientacion);
480                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
481                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
482                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
483                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
484                         } else if (xmlStrcmp(nodo->name, BAD_CAST"salida") == 0) {
485                                 p->out_lines.push_back((char *)XML_GET_CONTENT(nodo->children));
486                         } else if (xmlStrcmp(nodo->name, BAD_CAST"entrada") == 0) {
487                                 p->in_lines.push_back((char *)XML_GET_CONTENT(nodo->children));
488                         }
489                 }
490                 nodo = nodo->next;
491         }
492
493         p->signal_button_press_event().connect(SigC::bind( SigC::slot(*this, &Principal::on_item_clicked), p) );
494         p->set_position(x,y);
495         work_place->put(*p, x, y);
496         p->show();
497         // los agrego al hash
498         mapItems[name] = p;
499 }
500
501 void Principal::loadAnd(xmlNodePtr nodo)
502 {
503         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
504         std::string id = (char *)xmlGetProp(nodo, BAD_CAST"id");
505         int orientacion=0, x, y;
506         float flujo;
507         xmlNodePtr inicial = nodo;
508
509         ViewAnd *p;
510         
511         nodo = nodo->children;
512         while (nodo != NULL) {
513                 if (nodo->type == XML_ELEMENT_NODE) {
514                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
515                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
516                                 p = new ViewAnd(name, orientacion);
517                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
518                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
519                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
520                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
521                         } else if (xmlStrcmp(nodo->name, BAD_CAST"salida") == 0) {
522                                 p->out_lines.push_back((char *)XML_GET_CONTENT(nodo->children));
523                         } else if (xmlStrcmp(nodo->name, BAD_CAST"entrada") == 0) {
524                                 p->in_lines.push_back((char *)XML_GET_CONTENT(nodo->children));
525                         }
526                 }
527                 nodo = nodo->next;
528         }
529
530         p->signal_button_press_event().connect(SigC::bind( SigC::slot(*this, &Principal::on_item_clicked), p) );
531         p->set_position(x,y);
532         work_place->put(*p, x, y);
533         p->show();
534         // los agrego al hash
535         mapItems[name] = p;
536 }
537
538 void Principal::loadBomba(xmlNodePtr nodo)
539 {
540         Glib::ustring name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
541         int orientacion=0, x, y;
542
543         nodo = nodo->children;
544         while (nodo != NULL) {
545                 if (nodo->type == XML_ELEMENT_NODE) {
546                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
547                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
548                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
549                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
550                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
551                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
552                         }
553                 }
554                 nodo = nodo->next;
555         }
556
557         // listo, ya recolecte todos los datos, ahora creo el objeto!
558         ViewPump *b = new ViewPump(name, orientacion);
559         b->signal_button_press_event().connect(SigC::bind( SigC::slot(*this, &Principal::on_item_clicked), b) );
560         b->set_position(x,y);
561         work_place->put(*b, x, y);
562         b->show();
563         // los agrego al hash
564         mapItems[name] = b;
565 }
566
567 void Principal::loadCodo(xmlNodePtr nodo)
568 {
569         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
570         int orientacion=0, x, y;
571
572         nodo = nodo->children;
573         while (nodo != NULL) {
574                 if (nodo->type == XML_ELEMENT_NODE) {
575                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
576                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
577                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
578                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
579                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
580                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
581                         }
582                 }
583                 nodo = nodo->next;
584         }
585
586         // listo, ya recolecte todos los datos, ahora creo el objeto!
587         ViewItem *b = new ViewCodo(name, orientacion);
588         b->signal_button_press_event().connect(SigC::bind( SigC::slot(*this, &Principal::on_item_clicked), b) );
589         b->set_position(x,y);
590         work_place->put(*b, x, y);
591         b->show();
592         // los agrego al hash
593         mapItems[name] = b;
594 }
595
596 void Principal::loadConduct(xmlNodePtr nodo)
597 {
598         Glib::ustring name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
599         int orientacion=0, x, y;
600
601         nodo = nodo->children;
602         while (nodo != NULL) {
603                 if (nodo->type == XML_ELEMENT_NODE) {
604                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
605                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
606                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
607                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
608                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
609                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
610                         }
611                 }
612                 nodo = nodo->next;
613         }
614
615         // listo, ya recolecte todos los datos, ahora creo el objeto!
616         ViewConduct *b = new ViewConduct(name, orientacion);
617         b->signal_button_press_event().connect(SigC::bind( SigC::slot(*this, &Principal::on_item_clicked), b) );
618         b->set_position(x,y);
619         work_place->put(*b, x, y);
620         b->show();
621         // los agrego al hash
622         mapItems[name] = b;
623 }
624
625 void Principal::loadExclusa(xmlNodePtr nodo)
626 {
627         Glib::ustring name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
628         int orientacion=0, x, y;
629
630         nodo = nodo->children;
631         while (nodo != NULL) {
632                 if (nodo->type == XML_ELEMENT_NODE) {
633                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
634                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
635                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
636                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
637                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
638                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
639                         }
640                 }
641                 nodo = nodo->next;
642         }
643
644         // listo, ya recolecte todos los datos, ahora creo el objeto!
645         ViewExclusa *b = new ViewExclusa(name, orientacion);
646         b->signal_button_press_event().connect(SigC::bind( SigC::slot(*this, &Principal::on_item_clicked), b) );
647         b->set_position(x,y);
648         work_place->put(*b, x, y);
649         b->show();
650         // los agrego al hash
651         mapItems[name] = b;
652 }
653
654 void Principal::loadTank(xmlNodePtr nodo)
655 {
656         Glib::ustring name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
657         int orientacion=0, x, y;
658
659         nodo = nodo->children;
660         while (nodo != NULL) {
661                 if (nodo->type == XML_ELEMENT_NODE) {
662                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
663                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
664                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
665                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
666                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
667                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
668                         }
669                 }
670                 nodo = nodo->next;
671         }
672
673         // listo, ya recolecte todos los datos, ahora creo el objeto!
674         ViewTank *b = new ViewTank(name, orientacion);
675         b->signal_button_press_event().connect(SigC::bind( SigC::slot(*this, &Principal::on_item_clicked), b) );
676         b->set_position(x,y);
677         work_place->put(*b, x, y);
678         b->show();
679         // los agrego al hash
680         mapItems[name] = b;
681 }
682
683 void Principal::loadUnion(xmlNodePtr nodo)
684 {
685         Glib::ustring name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
686         int orientacion=0, x, y;
687
688         nodo = nodo->children;
689         while (nodo != NULL) {
690                 if (nodo->type == XML_ELEMENT_NODE) {
691                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
692                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
693                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
694                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
695                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
696                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
697                         }
698                 }
699                 nodo = nodo->next;
700         }
701
702         // listo, ya recolecte todos los datos, ahora creo el objeto!
703         ViewUnion *b = new ViewUnion(name, orientacion);
704         b->signal_button_release_event().connect(SigC::bind( SigC::slot(*this, &Principal::on_item_clicked), b) );
705         b->set_position(x,y);
706         work_place->put(*b, x, y);
707         b->show();
708         // los agrego al hash
709         mapItems[name] = b;
710 }
711
712 void Principal::loadDrain(xmlNodePtr nodo)
713 {
714         Glib::ustring name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
715         int orientacion=0, x, y;
716
717         nodo = nodo->children;
718         while (nodo != NULL) {
719                 if (nodo->type == XML_ELEMENT_NODE) {
720                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
721                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
722                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
723                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
724                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
725                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
726                         }
727                 }
728                 nodo = nodo->next;
729         }
730
731         // listo, ya recolecte todos los datos, ahora creo el objeto!
732         ViewDrain *b = new ViewDrain(name, orientacion);
733         b->signal_button_release_event().connect(SigC::bind( SigC::slot(*this, &Principal::on_item_clicked), b) );
734         b->set_position(x,y);
735         work_place->put(*b, x, y);
736         b->show();
737         // los agrego al hash
738         mapItems[name] = b;
739 }
740
741 void Principal::read_status_xml(const std::string &frame)
742 {
743         std::string item_name;
744         xmlDocPtr document;
745         document = xmlParseMemory(frame.c_str(),frame.size());
746         if (document == NULL) {
747                 std::cout << "read_status_xml::no se creo documento" << std::endl;
748                 return;
749         }
750         
751         xmlNodePtr nodo, items, props;
752         nodo = document->children;
753         float tmp;
754         bool tmp_b;
755
756         if (strcmp((char *)nodo->name, "plantstatus") == 0) {
757                 items = nodo->children;
758                 while (items != NULL) {
759                         if (items->type == XML_ELEMENT_NODE) {
760                                 tmp = -1;
761                                 item_name = "";
762                                 if (xmlStrcmp(items->name, BAD_CAST"float")==0) {
763                                         tmp = get_float_from_xml(items->children);
764                                         item_name = (char *)xmlGetProp(items, BAD_CAST"name");
765                                         mapItems[item_name]->set_actual_flow(tmp);
766                                 } else if (xmlStrcmp(items->name, BAD_CAST"exclusa")==0) {
767                                         tmp_b = get_bool_from_xml(items->children);
768                                         item_name = (char *)xmlGetProp(items, BAD_CAST"name");
769                                         mapItems[item_name]->set_open(tmp_b);
770                                 } else if (xmlStrcmp(items->name, BAD_CAST"pump")==0) {
771                                         tmp_b = get_bool_from_xml(items->children);
772                                         item_name = (char *)xmlGetProp(items, BAD_CAST"name");
773                                         mapItems[item_name]->set_open(tmp_b);
774                                 } else if (xmlStrcmp(items->name, BAD_CAST"logic")==0) {
775                                         tmp_b = get_bool_from_xml(items->children);
776                                         item_name = (char *)xmlGetProp(items, BAD_CAST"name");
777                                         mapItems[item_name]->set_open(tmp_b);
778                                 } else if (xmlStrcmp(items->name, BAD_CAST"color")==0) {
779                                         item_name = (char *)xmlGetProp(items, BAD_CAST"name");
780                                         mapItems[item_name]->set_color( get_rgb_from_xml(items->children) );
781                                 } else if (xmlStrcmp(items->name, BAD_CAST"tank")==0) {
782                                         xmlNodePtr nodo_tmp = items->children;
783                                         float cap, lit;
784                                         cap = lit = -1;
785                                         while (nodo_tmp != NULL) {
786                                                 if (nodo_tmp->type == XML_ELEMENT_NODE) {
787                                                         if (xmlStrcmp(nodo_tmp->name, BAD_CAST"capacity")==0)
788                                                                 cap = atof( (char *)XML_GET_CONTENT(nodo_tmp->children) );
789                                                         else if (xmlStrcmp(nodo_tmp->name, BAD_CAST"litros")==0)
790                                                                 lit= atof( (char *)XML_GET_CONTENT(nodo_tmp->children) );
791                                                 }
792                                                 nodo_tmp = nodo_tmp->next;
793                                         }
794                                         item_name = (char *)xmlGetProp(items, BAD_CAST"name");
795                                         mapItems[item_name]->set_actual_flow(cap);
796                                         mapItems[item_name]->set_extra(lit);
797                                 }
798                         }
799                         items = items->next;
800                 }
801
802                 xmlFreeDoc(document);
803                 // Actualizo la UI
804                 update_ui();
805         }
806 }
807
808 Gdk::Color Principal::get_rgb_from_xml(xmlNodePtr nodo)
809 {
810         gushort r,g,b;
811         while (nodo != NULL) {
812                 if (nodo->type == XML_ELEMENT_NODE) {
813                         if (xmlStrcmp(nodo->name, BAD_CAST"r")==0)
814                                 r = atoi( (char *)XML_GET_CONTENT(nodo->children) );
815                         if (xmlStrcmp(nodo->name, BAD_CAST"g")==0)
816                                 g = atoi( (char *)XML_GET_CONTENT(nodo->children) );
817                         if (xmlStrcmp(nodo->name, BAD_CAST"b")==0)
818                                 b = atoi( (char *)XML_GET_CONTENT(nodo->children) );
819                 }
820                 nodo = nodo->next;
821         }
822         r = static_cast<gushort>(65535 * (r / 255.0f));
823         g = static_cast<gushort>(65535 * (g / 255.0f));
824         b = static_cast<gushort>(65535 * (b / 255.0f));
825         Gdk::Color c;
826         c.set_rgb(r,g,b);
827
828         return c;
829 }
830
831 float Principal::get_float_from_xml(xmlNodePtr nodo)
832 {
833         float tmp = -1;
834         while (nodo != NULL) {
835                 if (nodo->type == XML_ELEMENT_NODE) {
836                         if (xmlStrcmp(nodo->name, BAD_CAST"actual_flow")==0) {
837                                 tmp = atof( (char *)XML_GET_CONTENT(nodo->children) );
838                                 break;
839                         }
840                 }
841                 nodo = nodo->next;
842         }
843         if (tmp == INFINITO) tmp = 0;
844         return tmp;
845 }
846
847 bool Principal::get_bool_from_xml(xmlNodePtr nodo)
848 {
849         std::string tmp;
850         while (nodo != NULL) {
851                 if (nodo->type == XML_ELEMENT_NODE) {
852                         if (xmlStrcmp(nodo->name, BAD_CAST"active")==0) {
853                                 tmp = (char *)XML_GET_CONTENT(nodo->children);
854                                 break;
855                         }
856                 }
857                 nodo = nodo->next;
858         }
859         return tmp == "true";
860 }
861
862 void Principal::on_mnu_property()
863 {
864         dlg_property->show();
865 }
866
867 void Principal::on_dlg_property_ok()
868 {
869         if (conexion) {
870                 PlaQui::Server::Command c("plant", "set_frequency");
871                 c.add_arg("default");
872                 c.add_arg( dlg_property->get_velocity() );
873
874                 conexion->send(c);
875         }
876         dlg_property->hide();
877 }
878
879 void Principal::on_btn_simulate_clicked()
880 {
881         if (conexion == NULL) return;
882
883         PlaQui::Server::Command c("plant", "start");
884         c.add_arg("default");
885         conexion->send(c);
886         paused = false;
887 }
888
889 void Principal::on_btn_pause_clicked()
890 {
891         if (conexion == NULL) return;
892
893         PlaQui::Server::Command c("plant", "stop");
894         c.add_arg("default");
895         conexion->send(c);
896         paused = true;
897 }
898