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