]> git.llucax.com Git - z.facultad/75.42/plaqui.git/blob - Client/src/principal.cpp
Se arregla un 'bug' en las referencias al cliente en la documentacion.
[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                 txt_view->get_buffer()->insert(txt_view->get_buffer()->begin(),"No se pudo cargar XML enviado por el servidor.");
418                 is_xml_loaded = false;
419                 return;
420         }
421         is_xml_loaded = true;
422         /* bien, el archivo se parseo bien! */
423         xmlNodePtr nodo, items;
424         nodo = document->children;
425
426         if (strcmp((char *)nodo->name, "planta") == 0) {
427                 items = nodo->children;
428                 while (items != NULL) {
429                         if (items->type == XML_ELEMENT_NODE) {
430                                 if (xmlStrcmp(items->name, BAD_CAST"bomba")==0) {
431                                         loadBomba(items);
432                                 } else if (xmlStrcmp(items->name, BAD_CAST"codo")==0) {
433                                         loadCodo(items);
434                                 } else if (xmlStrcmp(items->name, BAD_CAST"tubo")==0) {
435                                         loadConduct(items);
436                                 } else if (xmlStrcmp(items->name, BAD_CAST"exclusa")==0) {
437                                         loadExclusa(items);
438                                 } else if (xmlStrcmp(items->name, BAD_CAST"tanque")==0) {
439                                         loadTank(items);
440                                 } else if (xmlStrcmp(items->name, BAD_CAST"empalme")==0) {
441                                         loadUnion(items);
442                                 } else if (xmlStrcmp(items->name, BAD_CAST"drenaje")==0) {
443                                         loadDrain(items);
444                                 } else if (xmlStrcmp(items->name, BAD_CAST"and")==0) {
445                                         loadAnd(items);
446                                 } else if (xmlStrcmp(items->name, BAD_CAST"or")==0) {
447                                         loadOr(items);
448                                 } else if (xmlStrcmp(items->name, BAD_CAST"not")==0) {
449                                         loadNot(items);
450                                 }
451
452                         }
453                         items = items->next;
454                 }
455         }
456
457         xmlFreeDoc(document);
458
459         // Ya cargado el XML, mando un msg para empezar a recibir los frames!
460         PlaQui::Server::Command c("transmission", "start");
461         c.add_arg("default");
462         c.add_arg(conexion->get_host());
463         c.add_arg("7528");
464         conexion->send(c);
465 }
466
467 void Principal::loadNot(xmlNodePtr nodo)
468 {
469         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
470         std::string id = (char *)xmlGetProp(nodo, BAD_CAST"id");
471         int orientacion=0, x, y;
472         t_Linea linea;
473
474         ViewNot *p;
475         nodo = nodo->children;
476         while (nodo != NULL) {
477                 if (nodo->type == XML_ELEMENT_NODE) {
478                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
479                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
480                                 p = new ViewNot(name, orientacion);
481                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
482                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
483                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
484                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
485                         } else if (xmlStrcmp(nodo->name, BAD_CAST"salida") == 0) {
486                                 linea.dst = (char *)XML_GET_CONTENT(nodo->children);
487                                 p->out_lines.push_back(linea);
488                         } else if (xmlStrcmp(nodo->name, BAD_CAST"entrada") == 0) {
489                                 linea.dst = (char *)XML_GET_CONTENT(nodo->children);
490                                 linea.is_tank = false;
491                                 if (dynamic_cast<ViewTank *>(find_item(linea.dst)) != NULL) {
492                                         linea.is_tank = true;
493                                         linea.is_tank_lower = false;
494                                         if (xmlStrcmp(xmlGetProp(nodo, BAD_CAST"id"), BAD_CAST"inferior")==0)
495                                                 linea.is_tank_lower = true;
496                                 }
497                                 p->in_lines.push_back(linea);
498                         }
499                 }
500                 nodo = nodo->next;
501         }
502         
503         p->signal_button_press_event().connect(SigC::bind( SigC::slot(*this, &Principal::on_item_clicked), p) );
504         p->set_position(x,y);
505         work_place->put(*p, x, y);
506         p->show();
507         // los agrego al hash
508         mapItems[name] = p;
509 }
510
511 void Principal::loadOr(xmlNodePtr nodo)
512 {
513         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
514         std::string id = (char *)xmlGetProp(nodo, BAD_CAST"id");
515         int orientacion=0, x, y;
516         t_Linea linea;
517
518         ViewOr *p;
519
520         nodo = nodo->children;
521         while (nodo != NULL) {
522                 if (nodo->type == XML_ELEMENT_NODE) {
523                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
524                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
525                                 p = new ViewOr(name, orientacion);
526                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
527                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
528                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
529                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
530                         } else if (xmlStrcmp(nodo->name, BAD_CAST"salida") == 0) {
531                                 linea.dst = (char *)XML_GET_CONTENT(nodo->children);
532                                 p->out_lines.push_back(linea);
533                         } else if (xmlStrcmp(nodo->name, BAD_CAST"entrada") == 0) {
534                                 linea.dst = (char *)XML_GET_CONTENT(nodo->children);
535                                 linea.is_tank = false;
536                                 if (dynamic_cast<ViewTank *>(find_item(linea.dst)) != NULL) {
537                                         linea.is_tank = true;
538                                         linea.is_tank_lower = false;
539                                         if (xmlStrcmp(xmlGetProp(nodo, BAD_CAST"id"), BAD_CAST"inferior")==0)
540                                                 linea.is_tank_lower = true;
541                                 }
542                                 p->in_lines.push_back(linea);
543                         }
544                 }
545                 nodo = nodo->next;
546         }
547
548         p->signal_button_press_event().connect(SigC::bind( SigC::slot(*this, &Principal::on_item_clicked), p) );
549         p->set_position(x,y);
550         work_place->put(*p, x, y);
551         p->show();
552         // los agrego al hash
553         mapItems[name] = p;
554 }
555
556 void Principal::loadAnd(xmlNodePtr nodo)
557 {
558         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
559         std::string id = (char *)xmlGetProp(nodo, BAD_CAST"id");
560         int orientacion=0, x, y;
561         float flujo;
562         xmlNodePtr inicial = nodo;
563         t_Linea linea;
564         ViewAnd *p;
565         
566         nodo = nodo->children;
567         while (nodo != NULL) {
568                 if (nodo->type == XML_ELEMENT_NODE) {
569                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
570                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
571                                 p = new ViewAnd(name, orientacion);
572                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
573                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
574                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
575                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
576                         } else if (xmlStrcmp(nodo->name, BAD_CAST"salida") == 0) {
577                                 linea.dst = (char *)XML_GET_CONTENT(nodo->children);
578                                 p->out_lines.push_back(linea);
579                         } else if (xmlStrcmp(nodo->name, BAD_CAST"entrada") == 0) {
580                                 linea.dst = (char *)XML_GET_CONTENT(nodo->children);
581                                 linea.is_tank = false;
582                                 if (dynamic_cast<ViewTank *>(find_item(linea.dst)) != NULL) {
583                                         linea.is_tank = true;
584                                         linea.is_tank_lower = false;
585                                         if (xmlStrcmp(xmlGetProp(nodo, BAD_CAST"id"), BAD_CAST"inferior")==0)
586                                                 linea.is_tank_lower = true;
587                                 }
588                                 p->in_lines.push_back(linea);
589                         }
590                 }
591                 nodo = nodo->next;
592         }
593
594         p->signal_button_press_event().connect(SigC::bind( SigC::slot(*this, &Principal::on_item_clicked), p) );
595         p->set_position(x,y);
596         work_place->put(*p, x, y);
597         p->show();
598         // los agrego al hash
599         mapItems[name] = p;
600 }
601
602 void Principal::loadBomba(xmlNodePtr nodo)
603 {
604         Glib::ustring name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
605         int orientacion=0, x, y;
606
607         nodo = nodo->children;
608         while (nodo != NULL) {
609                 if (nodo->type == XML_ELEMENT_NODE) {
610                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
611                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
612                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
613                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
614                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
615                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
616                         }
617                 }
618                 nodo = nodo->next;
619         }
620
621         // listo, ya recolecte todos los datos, ahora creo el objeto!
622         ViewPump *b = new ViewPump(name, orientacion);
623         b->signal_button_press_event().connect(SigC::bind( SigC::slot(*this, &Principal::on_item_clicked), b) );
624         b->set_position(x,y);
625         work_place->put(*b, x, y);
626         b->show();
627         // los agrego al hash
628         mapItems[name] = b;
629 }
630
631 void Principal::loadCodo(xmlNodePtr nodo)
632 {
633         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
634         int orientacion=0, x, y;
635
636         nodo = nodo->children;
637         while (nodo != NULL) {
638                 if (nodo->type == XML_ELEMENT_NODE) {
639                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
640                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
641                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
642                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
643                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
644                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
645                         }
646                 }
647                 nodo = nodo->next;
648         }
649
650         // listo, ya recolecte todos los datos, ahora creo el objeto!
651         ViewItem *b = new ViewCodo(name, orientacion);
652         b->signal_button_press_event().connect(SigC::bind( SigC::slot(*this, &Principal::on_item_clicked), b) );
653         b->set_position(x,y);
654         work_place->put(*b, x, y);
655         b->show();
656         // los agrego al hash
657         mapItems[name] = b;
658 }
659
660 void Principal::loadConduct(xmlNodePtr nodo)
661 {
662         Glib::ustring name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
663         int orientacion=0, x, y;
664
665         nodo = nodo->children;
666         while (nodo != NULL) {
667                 if (nodo->type == XML_ELEMENT_NODE) {
668                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
669                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
670                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
671                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
672                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
673                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
674                         }
675                 }
676                 nodo = nodo->next;
677         }
678
679         // listo, ya recolecte todos los datos, ahora creo el objeto!
680         ViewConduct *b = new ViewConduct(name, orientacion);
681         b->signal_button_press_event().connect(SigC::bind( SigC::slot(*this, &Principal::on_item_clicked), b) );
682         b->set_position(x,y);
683         work_place->put(*b, x, y);
684         b->show();
685         // los agrego al hash
686         mapItems[name] = b;
687 }
688
689 void Principal::loadExclusa(xmlNodePtr nodo)
690 {
691         Glib::ustring name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
692         int orientacion=0, x, y;
693
694         nodo = nodo->children;
695         while (nodo != NULL) {
696                 if (nodo->type == XML_ELEMENT_NODE) {
697                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
698                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
699                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
700                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
701                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
702                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
703                         }
704                 }
705                 nodo = nodo->next;
706         }
707
708         // listo, ya recolecte todos los datos, ahora creo el objeto!
709         ViewExclusa *b = new ViewExclusa(name, orientacion);
710         b->signal_button_press_event().connect(SigC::bind( SigC::slot(*this, &Principal::on_item_clicked), b) );
711         b->set_position(x,y);
712         work_place->put(*b, x, y);
713         b->show();
714         // los agrego al hash
715         mapItems[name] = b;
716 }
717
718 void Principal::loadTank(xmlNodePtr nodo)
719 {
720         Glib::ustring name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
721         int orientacion=0, x, y;
722
723         nodo = nodo->children;
724         while (nodo != NULL) {
725                 if (nodo->type == XML_ELEMENT_NODE) {
726                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
727                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
728                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
729                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
730                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
731                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
732                         }
733                 }
734                 nodo = nodo->next;
735         }
736
737         // listo, ya recolecte todos los datos, ahora creo el objeto!
738         ViewTank *b = new ViewTank(name, orientacion);
739         b->signal_button_press_event().connect(SigC::bind( SigC::slot(*this, &Principal::on_item_clicked), b) );
740         b->set_position(x,y);
741         work_place->put(*b, x, y);
742         b->show();
743         // los agrego al hash
744         mapItems[name] = b;
745 }
746
747 void Principal::loadUnion(xmlNodePtr nodo)
748 {
749         Glib::ustring name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
750         int orientacion=0, x, y;
751
752         nodo = nodo->children;
753         while (nodo != NULL) {
754                 if (nodo->type == XML_ELEMENT_NODE) {
755                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
756                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
757                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
758                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
759                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
760                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
761                         }
762                 }
763                 nodo = nodo->next;
764         }
765
766         // listo, ya recolecte todos los datos, ahora creo el objeto!
767         ViewUnion *b = new ViewUnion(name, orientacion);
768         b->signal_button_release_event().connect(SigC::bind( SigC::slot(*this, &Principal::on_item_clicked), b) );
769         b->set_position(x,y);
770         work_place->put(*b, x, y);
771         b->show();
772         // los agrego al hash
773         mapItems[name] = b;
774 }
775
776 void Principal::loadDrain(xmlNodePtr nodo)
777 {
778         Glib::ustring name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
779         int orientacion=0, x, y;
780
781         nodo = nodo->children;
782         while (nodo != NULL) {
783                 if (nodo->type == XML_ELEMENT_NODE) {
784                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
785                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
786                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
787                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
788                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
789                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
790                         }
791                 }
792                 nodo = nodo->next;
793         }
794
795         // listo, ya recolecte todos los datos, ahora creo el objeto!
796         ViewDrain *b = new ViewDrain(name, orientacion);
797         b->signal_button_release_event().connect(SigC::bind( SigC::slot(*this, &Principal::on_item_clicked), b) );
798         b->set_position(x,y);
799         work_place->put(*b, x, y);
800         b->show();
801         // los agrego al hash
802         mapItems[name] = b;
803 }
804
805 void Principal::read_status_xml(const std::string &frame)
806 {
807         std::string item_name;
808         xmlDocPtr document;
809         document = xmlParseMemory(frame.c_str(),frame.size());
810         if (document == NULL) {
811                 txt_view->get_buffer()->insert(txt_view->get_buffer()->begin(), "ERROR : No se pudo leer el último frame!\n");
812                 return;
813         }
814         
815         xmlNodePtr nodo, items, props;
816         nodo = document->children;
817         float tmp;
818         bool tmp_b;
819
820         if (strcmp((char *)nodo->name, "plantstatus") == 0) {
821                 items = nodo->children;
822                 while (items != NULL) {
823                         if (items->type == XML_ELEMENT_NODE) {
824                                 tmp = -1;
825                                 item_name = "";
826                                 if (xmlStrcmp(items->name, BAD_CAST"float")==0) {
827                                         tmp = get_float_from_xml(items->children);
828                                         item_name = (char *)xmlGetProp(items, BAD_CAST"name");
829                                         mapItems[item_name]->set_actual_flow(tmp);
830                                 } else if (xmlStrcmp(items->name, BAD_CAST"exclusa")==0) {
831                                         tmp_b = get_bool_from_xml(items->children);
832                                         item_name = (char *)xmlGetProp(items, BAD_CAST"name");
833                                         mapItems[item_name]->set_open(tmp_b);
834                                 } else if (xmlStrcmp(items->name, BAD_CAST"pump")==0) {
835                                         tmp_b = get_bool_from_xml(items->children);
836                                         item_name = (char *)xmlGetProp(items, BAD_CAST"name");
837                                         mapItems[item_name]->set_open(tmp_b);
838                                 } else if (xmlStrcmp(items->name, BAD_CAST"logic")==0) {
839                                         tmp_b = get_bool_from_xml(items->children);
840                                         item_name = (char *)xmlGetProp(items, BAD_CAST"name");
841                                         mapItems[item_name]->set_open(tmp_b);
842                                 } else if (xmlStrcmp(items->name, BAD_CAST"color")==0) {
843                                         item_name = (char *)xmlGetProp(items, BAD_CAST"name");
844                                         mapItems[item_name]->set_color( get_rgb_from_xml(items->children) );
845                                 } else if (xmlStrcmp(items->name, BAD_CAST"tank")==0) {
846                                         xmlNodePtr nodo_tmp = items->children;
847                                         float cap, lit;
848                                         cap = lit = -1;
849                                         bool b_inf, b_sup;
850                                         while (nodo_tmp != NULL) {
851                                                 if (nodo_tmp->type == XML_ELEMENT_NODE) {
852                                                         if (xmlStrcmp(nodo_tmp->name, BAD_CAST"capacity")==0)
853                                                                 cap = atof( (char *)XML_GET_CONTENT(nodo_tmp->children) );
854                                                         else if (xmlStrcmp(nodo_tmp->name, BAD_CAST"litros")==0)
855                                                                 lit= atof( (char *)XML_GET_CONTENT(nodo_tmp->children) );
856                                                         else if (xmlStrcmp(nodo_tmp->name, BAD_CAST"salida")==0) {
857                                                                 if (xmlStrcmp(xmlGetProp(items, BAD_CAST"id"), BAD_CAST"inferior")==0) {
858                                                                         b_inf = get_bool_from_xml(nodo_tmp->children);
859                                                                 } else {
860                                                                         b_sup = get_bool_from_xml(nodo_tmp->children);
861                                                                 }
862                                                         }
863                                                 }
864                                                 nodo_tmp = nodo_tmp->next;
865                                         }
866                                         item_name = (char *)xmlGetProp(items, BAD_CAST"name");
867                                         mapItems[item_name]->set_actual_flow(cap);
868                                         mapItems[item_name]->set_extra(lit);
869                                         dynamic_cast<ViewTank *>(mapItems[item_name])->set_out_sup(b_sup);
870                                         dynamic_cast<ViewTank *>(mapItems[item_name])->set_out_inf(b_inf);
871                                 }
872                         }
873                         items = items->next;
874                 }
875
876                 xmlFreeDoc(document);
877                 // Actualizo la UI
878                 update_ui();
879         }
880 }
881
882 Gdk::Color Principal::get_rgb_from_xml(xmlNodePtr nodo)
883 {
884         gushort r,g,b;
885         while (nodo != NULL) {
886                 if (nodo->type == XML_ELEMENT_NODE) {
887                         if (xmlStrcmp(nodo->name, BAD_CAST"r")==0)
888                                 r = atoi( (char *)XML_GET_CONTENT(nodo->children) );
889                         if (xmlStrcmp(nodo->name, BAD_CAST"g")==0)
890                                 g = atoi( (char *)XML_GET_CONTENT(nodo->children) );
891                         if (xmlStrcmp(nodo->name, BAD_CAST"b")==0)
892                                 b = atoi( (char *)XML_GET_CONTENT(nodo->children) );
893                 }
894                 nodo = nodo->next;
895         }
896         r = static_cast<gushort>(65535 * (r / 255.0f));
897         g = static_cast<gushort>(65535 * (g / 255.0f));
898         b = static_cast<gushort>(65535 * (b / 255.0f));
899         Gdk::Color c;
900         c.set_rgb(r,g,b);
901
902         return c;
903 }
904
905 float Principal::get_float_from_xml(xmlNodePtr nodo)
906 {
907         float tmp = -1;
908         while (nodo != NULL) {
909                 if (nodo->type == XML_ELEMENT_NODE) {
910                         if (xmlStrcmp(nodo->name, BAD_CAST"actual_flow")==0) {
911                                 tmp = atof( (char *)XML_GET_CONTENT(nodo->children) );
912                                 break;
913                         }
914                 }
915                 nodo = nodo->next;
916         }
917         if (tmp == INFINITO) tmp = 0;
918         return tmp;
919 }
920
921 bool Principal::get_bool_from_xml(xmlNodePtr nodo)
922 {
923         std::string tmp;
924         while (nodo != NULL) {
925                 if (nodo->type == XML_ELEMENT_NODE) {
926                         if (xmlStrcmp(nodo->name, BAD_CAST"active")==0) {
927                                 tmp = (char *)XML_GET_CONTENT(nodo->children);
928                                 break;
929                         }
930                 }
931                 nodo = nodo->next;
932         }
933         return tmp == "true";
934 }
935
936 void Principal::on_mnu_property()
937 {
938         dlg_property->show();
939 }
940
941 void Principal::on_dlg_property_ok()
942 {
943         if (conexion) {
944                 PlaQui::Server::Command c("plant", "set_frequency");
945                 c.add_arg("default");
946                 c.add_arg( dlg_property->get_velocity() );
947
948                 conexion->send(c);
949         }
950         dlg_property->hide();
951 }
952
953 void Principal::on_btn_simulate_clicked()
954 {
955         if (conexion == NULL) return;
956
957         PlaQui::Server::Command c("plant", "start");
958         c.add_arg("default");
959         conexion->send(c);
960         paused = false;
961 }
962
963 void Principal::on_btn_pause_clicked()
964 {
965         if (conexion == NULL) return;
966
967         PlaQui::Server::Command c("plant", "stop");
968         c.add_arg("default");
969         conexion->send(c);
970         paused = true;
971 }
972