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