Fawkes API  Fawkes Development Version
skillgui.cpp
1 
2 /***************************************************************************
3  * skillgui.cpp - Skill GUI
4  *
5  * Created: Mon Nov 03 13:37:33 2008
6  * Copyright 2008 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Library General Public License for more details.
19  *
20  * Read the full text in the LICENSE.GPL file in the doc directory.
21  */
22 
23 #include "skillgui.h"
24 #ifdef USE_PAPYRUS
25 # include "graph_viewport.h"
26 #else
27 # include "graph_drawing_area.h"
28 #endif
29 
30 #include <utils/system/argparser.h>
31 #include <blackboard/remote.h>
32 #include <netcomm/fawkes/client.h>
33 
34 #include <gui_utils/logview.h>
35 #include <gui_utils/service_chooser_dialog.h>
36 #include <gui_utils/interface_dispatcher.h>
37 #include <gui_utils/plugin_tree_view.h>
38 
39 #include <cstring>
40 #include <string>
41 #include <iostream>
42 
43 #include <gvc.h>
44 
45 using namespace fawkes;
46 
47 #define ACTIVE_SKILL "Active Skill"
48 #define SKILL_DOT "Skills dot graph"
49 #define SKILL_SEP_LINE "----------------"
50 
51 /** @class SkillGuiGtkWindow "skillgui.h"
52  * Skill GUI main window.
53  * The Skill GUI provides shows Skiller log messages and allows for
54  * executing skills.
55  * @author Tim Niemueller
56  */
57 
58 /** Constructor.
59  * @param cobject C base object
60  * @param builder Gtk Builder
61  */
62 SkillGuiGtkWindow::SkillGuiGtkWindow(BaseObjectType* cobject,
63  const Glib::RefPtr<Gtk::Builder> &builder)
64  : Gtk::Window(cobject)
65 {
66  bb = NULL;
67  __skiller_if = NULL;
68  __skdbg_if = NULL;
69  __agdbg_if = NULL;
70 
71 #ifdef HAVE_GCONFMM
72  try {
73  __gconf = Gnome::Conf::Client::get_default_client();
74  __gconf->add_dir(GCONF_PREFIX);
75  } catch (Gnome::Conf::Error &e) {
76  std::cerr << e.what() << std::endl;
77  throw;
78  }
79 #endif
80 
81  builder->get_widget_derived("trv_log", __logview);
82  builder->get_widget("tb_connection", tb_connection);
83  builder->get_widget("but_clearlog", but_clearlog);
84  builder->get_widget("tb_exit", tb_exit);
85  builder->get_widget("cbe_skillstring", cbe_skillstring);
86  builder->get_widget("but_exec", but_exec);
87  builder->get_widget("but_stop", but_stop);
88  builder->get_widget("lab_status", lab_status);
89  builder->get_widget("lab_alive", lab_alive);
90  builder->get_widget("lab_skillstring", lab_skillstring);
91  builder->get_widget("lab_error", lab_error);
92  builder->get_widget("scw_graph", scw_graph);
93  //builder->get_widget("drw_graph", drw_graph);
94  builder->get_widget("ntb_tabs", ntb_tabs);
95  builder->get_widget("tb_skiller", tb_skiller);
96  builder->get_widget("tb_agent", tb_agent);
97  builder->get_widget("tb_graphlist", tb_graphlist);
98  builder->get_widget("tb_controller", tb_controller);
99  builder->get_widget("tb_graphsave", tb_graphsave);
100  builder->get_widget("tb_graphopen", tb_graphopen);
101  builder->get_widget("tb_graphupd", tb_graphupd);
102  builder->get_widget("tb_graphrecord", tb_graphrecord);
103  builder->get_widget("tb_zoomin", tb_zoomin);
104  builder->get_widget("tb_zoomout", tb_zoomout);
105  builder->get_widget("tb_zoomfit", tb_zoomfit);
106  builder->get_widget("tb_zoomreset", tb_zoomreset);
107  builder->get_widget("tb_graphdir", tb_graphdir);
108  builder->get_widget("tb_graphcolored", tb_graphcolored);
109 
110 #if GTKMM_VERSION_GE(2,20)
111  builder->get_widget("tb_spinner", tb_spinner);
112 #endif
113  builder->get_widget_derived("trv_plugins", __trv_plugins);
114 
115  Gtk::SeparatorToolItem *spacesep;
116  builder->get_widget("tb_spacesep", spacesep);
117  spacesep->set_expand();
118 
119  // This should be in the Glade file, but is not restored for some reason
120  tb_graphsave->set_homogeneous(false);
121  tb_graphopen->set_homogeneous(false);
122  tb_graphupd->set_homogeneous(false);
123  tb_graphrecord->set_homogeneous(false);
124  tb_zoomin->set_homogeneous(false);
125  tb_zoomout->set_homogeneous(false);
126  tb_zoomfit->set_homogeneous(false);
127  tb_zoomreset->set_homogeneous(false);
128  tb_graphdir->set_homogeneous(false);
129  tb_graphcolored->set_homogeneous(false);
130 
131 #if GTK_VERSION_GE(3,0)
132  if (! cbe_skillstring->get_has_entry()) {
133  throw Exception("Skill string combo box has no entry, invalid UI file?");
134  }
135 #endif
136  __sks_list = Gtk::ListStore::create(__sks_record);
137  cbe_skillstring->set_model(__sks_list);
138 #if GTK_VERSION_GE(3,0)
139  cbe_skillstring->set_entry_text_column(__sks_record.skillstring);
140 #else
141  cbe_skillstring->set_text_column(__sks_record.skillstring);
142 #endif
143 
144  cbe_skillstring->get_entry()->set_activates_default(true);
145 
146  __trv_plugins->set_network_client(connection_dispatcher.get_client());
147 #ifdef HAVE_GCONFMM
148  __trv_plugins->set_gconf_prefix(GCONF_PREFIX);
149 #endif
150 
151 #ifdef USE_PAPYRUS
152  pvp_graph = Gtk::manage(new SkillGuiGraphViewport());
153  scw_graph->add(*pvp_graph);
154  pvp_graph->show();
155 #else
156  gda = Gtk::manage(new SkillGuiGraphDrawingArea());
157  scw_graph->add(*gda);
158  gda->show();
159 #endif
160 
161  cb_graphlist = Gtk::manage(new Gtk::ComboBoxText());
162 #if GTK_VERSION_GE(3,0)
163  cb_graphlist->append(ACTIVE_SKILL);
164 #else
165  cb_graphlist->append_text(ACTIVE_SKILL);
166 #endif
167  cb_graphlist->set_active_text(ACTIVE_SKILL);
168  tb_graphlist->add(*cb_graphlist);
169  cb_graphlist->show();
170 
171  //ntb_tabs->set_current_page(1);
172 
173  connection_dispatcher.signal_connected().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_connect));
174  connection_dispatcher.signal_disconnected().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_disconnect));
175 
176  tb_connection->signal_clicked().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_connection_clicked));
177  but_exec->signal_clicked().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_exec_clicked));
178  tb_controller->signal_clicked().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_controller_clicked));
179  tb_exit->signal_clicked().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_exit_clicked));
180  but_stop->signal_clicked().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_stop_clicked));
181  but_clearlog->signal_clicked().connect(sigc::mem_fun(*__logview, &LogView::clear));
182  tb_skiller->signal_toggled().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_skdbg_data_changed));
183  tb_skiller->signal_toggled().connect(sigc::bind(sigc::mem_fun(*cb_graphlist, &Gtk::ComboBoxText::set_sensitive),true));
184  tb_agent->signal_toggled().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_agdbg_data_changed));
185  tb_agent->signal_toggled().connect(sigc::bind(sigc::mem_fun(*cb_graphlist, &Gtk::ComboBoxText::set_sensitive),false));
186  cb_graphlist->signal_changed().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_skill_changed));
187  tb_graphupd->signal_clicked().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_graphupd_clicked));
188  tb_graphdir->signal_clicked().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_graphdir_clicked));
189  tb_graphcolored->signal_toggled().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_graphcolor_toggled));
190 #ifdef USE_PAPYRUS
191  tb_graphsave->signal_clicked().connect(sigc::mem_fun(*pvp_graph, &SkillGuiGraphViewport::save));
192  tb_zoomin->signal_clicked().connect(sigc::mem_fun(*pvp_graph, &SkillGuiGraphViewport::zoom_in));
193  tb_zoomout->signal_clicked().connect(sigc::mem_fun(*pvp_graph, &SkillGuiGraphViewport::zoom_out));
194  tb_zoomfit->signal_clicked().connect(sigc::mem_fun(*pvp_graph, &SkillGuiGraphViewport::zoom_fit));
195  tb_zoomreset->signal_clicked().connect(sigc::mem_fun(*pvp_graph, &SkillGuiGraphViewport::zoom_reset));
196 #else
197  tb_graphsave->signal_clicked().connect(sigc::mem_fun(*gda, &SkillGuiGraphDrawingArea::save));
198  tb_graphopen->signal_clicked().connect(sigc::mem_fun(*gda, &SkillGuiGraphDrawingArea::open));
199  tb_zoomin->signal_clicked().connect(sigc::mem_fun(*gda, &SkillGuiGraphDrawingArea::zoom_in));
200  tb_zoomout->signal_clicked().connect(sigc::mem_fun(*gda, &SkillGuiGraphDrawingArea::zoom_out));
201  tb_zoomfit->signal_clicked().connect(sigc::mem_fun(*gda, &SkillGuiGraphDrawingArea::zoom_fit));
202  tb_zoomreset->signal_clicked().connect(sigc::mem_fun(*gda, &SkillGuiGraphDrawingArea::zoom_reset));
203  tb_graphrecord->signal_clicked().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_recording_toggled));
204  gda->signal_update_disabled().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_update_disabled));
205 #endif
206 
207 #ifdef HAVE_GCONFMM
208  __gconf->signal_value_changed().connect(sigc::hide(sigc::hide(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_config_changed))));
209  on_config_changed();
210 #endif
211 }
212 
213 
214 /** Destructor. */
216 {
217 #ifdef HAVE_GCONFMM
218  __gconf->remove_dir(GCONF_PREFIX);
219 #endif
220  __logview->set_client(NULL);
221  __trv_plugins->set_network_client(NULL);
222 }
223 
224 
225 void
226 SkillGuiGtkWindow::on_config_changed()
227 {
228 #ifdef HAVE_GCONFMM
229  Gnome::Conf::SListHandle_ValueString l(__gconf->get_string_list(GCONF_PREFIX"/command_history"));
230 
231  __sks_list->clear();
232  for (Gnome::Conf::SListHandle_ValueString::const_iterator i = l.begin(); i != l.end(); ++i) {
233  Gtk::TreeModel::Row row = *__sks_list->append();
234  row[__sks_record.skillstring] = *i;
235  }
236 
237  bool colored = __gconf->get_bool(GCONF_PREFIX"/graph_colored");
238  tb_graphcolored->set_active(colored);
239 #endif
240 }
241 
242 
243 void
244 SkillGuiGtkWindow::on_skill_changed()
245 {
246  Glib::ustring skill = cb_graphlist->get_active_text();
247  if ( skill == ACTIVE_SKILL || skill == SKILL_SEP_LINE ) {
248  skill = "ACTIVE";
249  } else if( skill == SKILL_DOT ) {
250  skill = "SKILL_DEP";
251  }
253  __skdbg_if->msgq_enqueue(sgm);
254 }
255 
256 /** Event handler for connection button. */
257 void
258 SkillGuiGtkWindow::on_connection_clicked()
259 {
260  if ( ! connection_dispatcher.get_client()->connected() ) {
261  ServiceChooserDialog ssd(*this, connection_dispatcher.get_client());
262  ssd.run_and_connect();
263  } else {
264  connection_dispatcher.get_client()->disconnect();
265  }
266 }
267 
268 
269 void
270 SkillGuiGtkWindow::on_exit_clicked()
271 {
272  Gtk::Main::quit();
273 }
274 
275 
276 void
277 SkillGuiGtkWindow::on_controller_clicked()
278 {
279  if (__skiller_if && __skiller_if->is_valid() && __skiller_if->has_writer() &&
280  __skiller_if->exclusive_controller() == __skiller_if->serial()) {
281  // we are exclusive controller, release control
283  __skiller_if->msgq_enqueue(rcm);
284  } else if (__skiller_if && __skiller_if->is_valid() && __skiller_if->has_writer() &&
285  __skiller_if->exclusive_controller() == 0) {
286  // there is no exclusive controller, try to acquire control
288  __skiller_if->msgq_enqueue(acm);
289  } else {
290  Gtk::MessageDialog md(*this,
291  "Another component already acquired the exclusive "
292  "control for the Skiller; not acquiring exclusive control.",
293  /* markup */ false,
294  Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK,
295  /* modal */ true);
296  md.set_title("Control Acquisition Failed");
297  md.run();
298  }
299 }
300 
301 void
302 SkillGuiGtkWindow::on_stop_clicked()
303 {
304  if ( bb && __skiller_if && __skiller_if->is_valid() && __skiller_if->has_writer() ) {
306  __skiller_if->msgq_enqueue(sem);
307  }
308 }
309 
310 void
311 SkillGuiGtkWindow::close_bb()
312 {
313  if ( bb ) {
314  bb->unregister_listener(__skiller_ifd);
315  bb->unregister_listener(__skdbg_ifd);
316  bb->unregister_listener(__agdbg_ifd);
317  delete __skiller_ifd;
318  delete __skdbg_ifd;
319  delete __agdbg_ifd;
320  if ( __skiller_if && __skiller_if->is_valid() && __skiller_if->has_writer() &&
321  (__skiller_if->exclusive_controller() == __skiller_if->serial()) ) {
323  __skiller_if->msgq_enqueue(rcm);
324  }
325  bb->close(__skiller_if);
326  bb->close(__skdbg_if);
327  bb->close(__agdbg_if);
328  delete bb;
329  __skiller_if = NULL;
330  __skdbg_if = NULL;
331  __agdbg_if = NULL;
332  bb = NULL;
333  }
334 }
335 
336 /** Event handler for connected event. */
337 void
338 SkillGuiGtkWindow::on_connect()
339 {
340  try {
341  if ( ! bb ) {
342  bb = new RemoteBlackBoard(connection_dispatcher.get_client());
343  __skiller_if = bb->open_for_reading<SkillerInterface>("Skiller");
344  __skdbg_if = bb->open_for_reading<SkillerDebugInterface>("Skiller");
345  __agdbg_if = bb->open_for_reading<SkillerDebugInterface>("LuaAgent");
346  on_skiller_data_changed();
347  on_skdbg_data_changed();
348  on_agdbg_data_changed();
349 
350  __skiller_ifd = new InterfaceDispatcher("Skiller IFD", __skiller_if);
351  __skdbg_ifd = new InterfaceDispatcher("SkillerDebug IFD", __skdbg_if);
352  __agdbg_ifd = new InterfaceDispatcher("LuaAgent SkillerDebug IFD", __agdbg_if);
353  bb->register_listener(__skiller_ifd, BlackBoard::BBIL_FLAG_DATA);
354  bb->register_listener(__skdbg_ifd, BlackBoard::BBIL_FLAG_DATA);
355  bb->register_listener(__agdbg_ifd, BlackBoard::BBIL_FLAG_DATA);
356  __skiller_ifd->signal_data_changed().connect(sigc::hide(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_skiller_data_changed)));
357  __skdbg_ifd->signal_data_changed().connect(sigc::hide(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_skdbg_data_changed)));
358  __agdbg_ifd->signal_data_changed().connect(sigc::hide(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_agdbg_data_changed)));
359 
360  // always try to acquire control on connect, this may well fail, for
361  // example if agent is running, but we don't care
362  __skiller_if->read();
363  if (__skiller_if->has_writer() && __skiller_if->exclusive_controller() == 0) {
365  __skiller_if->msgq_enqueue(aqm);
366  }
367  if (__skdbg_if->has_writer()) {
369  __skdbg_if->msgq_enqueue(sgm);
370  }
371  }
372  tb_connection->set_stock_id(Gtk::Stock::DISCONNECT);
373  __logview->set_client(connection_dispatcher.get_client());
374 
375  tb_controller->set_sensitive(true);
376  cbe_skillstring->set_sensitive(true);
377 
378  this->set_title(std::string("Skill GUI @ ") + connection_dispatcher.get_client()->get_hostname());
379  } catch (Exception &e) {
380  Glib::ustring message = *(e.begin());
381  Gtk::MessageDialog md(*this, message, /* markup */ false,
382  Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK,
383  /* modal */ true);
384  md.set_title("BlackBoard connection failed");
385  md.run();
386 
387  close_bb();
388  connection_dispatcher.get_client()->disconnect();
389  }
390 }
391 
392 /** Event handler for disconnected event. */
393 void
394 SkillGuiGtkWindow::on_disconnect()
395 {
396  tb_controller->set_sensitive(false);
397  cbe_skillstring->set_sensitive(false);
398  but_exec->set_sensitive(false);
399  but_stop->set_sensitive(false);
400 
401  close_bb();
402 
403  tb_connection->set_stock_id(Gtk::Stock::CONNECT);
404 #ifdef USE_PAPYRUS
405  pvp_graph->queue_draw();
406 #endif
407  __logview->set_client(NULL);
408 
409  this->set_title("Skill GUI");
410 }
411 
412 
413 void
414 SkillGuiGtkWindow::on_exec_clicked()
415 {
416  Glib::ustring sks = "";
417  if ( cbe_skillstring->get_active_row_number() == -1 ) {
418  Gtk::Entry *entry = cbe_skillstring->get_entry();
419  sks = entry->get_text();
420  } else {
421  Gtk::TreeModel::Row row = *cbe_skillstring->get_active();
422 #if GTK_VERSION_GE(3,0)
423  row.get_value(cbe_skillstring->get_entry_text_column(), sks);
424 #else
425  row.get_value(cbe_skillstring->get_text_column(), sks);
426 #endif
427  }
428 
429  if ( sks != "" ) {
430 #if GTKMM_VERSION_GE(2,20)
431  tb_spinner->start();
432 #endif
433 
434  if (__skiller_if && __skiller_if->is_valid() && __skiller_if->has_writer() &&
435  __skiller_if->exclusive_controller() == __skiller_if->serial()) {
436 
438  __skiller_if->msgq_enqueue(esm);
439 
440  Gtk::TreeModel::Children children = __sks_list->children();
441  bool ok = true;
442  if ( ! children.empty() ) {
443  size_t num = 0;
444  Gtk::TreeIter i = children.begin();
445  while (ok && (i != children.end())) {
446  if ( num >= 9 ) {
447  i = __sks_list->erase(i);
448  } else {
449  Gtk::TreeModel::Row row = *i;
450  ok = (row[__sks_record.skillstring] != sks);
451  ++num;
452  ++i;
453  }
454  }
455  }
456  if (ok) {
457  Gtk::TreeModel::Row row = *__sks_list->prepend();
458  row[__sks_record.skillstring] = sks;
459 
460  std::list<Glib::ustring> l;
461  for (Gtk::TreeIter i = children.begin(); i != children.end(); ++i) {
462  Gtk::TreeModel::Row row = *i;
463  l.push_back(row[__sks_record.skillstring]);
464  }
465 
466 #ifdef HAVE_GCONFMM
467  __gconf->set_string_list(GCONF_PREFIX"/command_history", l);
468 #endif
469  }
470  } else {
471  Gtk::MessageDialog md(*this, "The exclusive control over the skiller has "
472  "not been acquired yet and skills cannot be executed",
473  /* markup */ false,
474  Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK,
475  /* modal */ true);
476  md.set_title("Skill Execution Failure");
477  md.run();
478  }
479  }
480 }
481 
482 
483 void
484 SkillGuiGtkWindow::on_skiller_data_changed()
485 {
486  try {
487  __skiller_if->read();
488 
489  switch (__skiller_if->status()) {
490  case SkillerInterface::S_INACTIVE:
491 #if GTKMM_VERSION_GE(2,20)
492  tb_spinner->stop();
493 #endif
494  lab_status->set_text("S_INACTIVE");
495  break;
496  case SkillerInterface::S_FINAL:
497 #if GTKMM_VERSION_GE(2,20)
498  tb_spinner->stop();
499 #endif
500  //__throbber->set_stock(Gtk::Stock::APPLY);
501  lab_status->set_text("S_FINAL");
502  break;
503  case SkillerInterface::S_RUNNING:
504 #if GTKMM_VERSION_GE(2,20)
505  tb_spinner->start();
506 #endif
507  lab_status->set_text("S_RUNNING");
508  break;
509  case SkillerInterface::S_FAILED:
510 #if GTKMM_VERSION_GE(2,20)
511  tb_spinner->stop();
512 #endif
513  //__throbber->set_stock(Gtk::Stock::DIALOG_WARNING);
514  lab_status->set_text("S_FAILED");
515  break;
516  }
517 
518  lab_skillstring->set_text(__skiller_if->skill_string());
519  lab_error->set_text(__skiller_if->error());
520 #if GTKMM_MAJOR_VERSION > 2 || ( GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 12 )
521  lab_skillstring->set_tooltip_text(__skiller_if->skill_string());
522  lab_error->set_tooltip_text(__skiller_if->error());
523 #endif
524  lab_alive->set_text(__skiller_if->has_writer() ? "Yes" : "No");
525 
526  if ( __skiller_if->exclusive_controller() == __skiller_if->serial() ) {
527  if ( tb_controller->get_stock_id() == Gtk::Stock::NO.id ) {
528  tb_controller->set_stock_id(Gtk::Stock::YES);
529 #if GTKMM_MAJOR_VERSION > 2 || ( GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 12 )
530  tb_controller->set_tooltip_text("Release exclusive control");
531 #endif
532  }
533  but_exec->set_sensitive(true);
534  but_stop->set_sensitive(true);
535  } else {
536  if ( tb_controller->get_stock_id() == Gtk::Stock::YES.id ) {
537  tb_controller->set_stock_id(Gtk::Stock::NO);
538 #if GTKMM_MAJOR_VERSION > 2 || ( GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 12 )
539  tb_controller->set_tooltip_text("Gain exclusive control");
540 #endif
541  }
542  but_exec->set_sensitive(false);
543  but_stop->set_sensitive(false);
544  }
545 
546 
547  } catch (Exception &e) {
548 #if GTKMM_VERSION_GE(2,20)
549  tb_spinner->stop();
550 #endif
551  }
552 }
553 
554 
555 void
556 SkillGuiGtkWindow::on_skdbg_data_changed()
557 {
558  if (tb_skiller->get_active() && __skdbg_if) {
559  try {
560  __skdbg_if->read();
561 
562  if (strcmp(__skdbg_if->graph_fsm(), "LIST") == 0) {
563  Glib::ustring list = __skdbg_if->graph();
564 #if GTK_VERSION_GE(3,0)
565  cb_graphlist->remove_all();
566  cb_graphlist->append(ACTIVE_SKILL);
567  cb_graphlist->append(SKILL_DOT);
568  cb_graphlist->append(SKILL_SEP_LINE);
569 #else
570  cb_graphlist->clear_items();
571  cb_graphlist->append_text(ACTIVE_SKILL);
572  cb_graphlist->append_text(SKILL_DOT);
573  cb_graphlist->append_text(SKILL_SEP_LINE);
574 #endif
575  cb_graphlist->set_active_text(ACTIVE_SKILL);
576 #if GTK_VERSION_GE(2,14)
577  Glib::RefPtr<Glib::Regex> regex = Glib::Regex::create("\n");
578  std::list<std::string> skills = regex->split(list);
579  for (std::list<std::string>::iterator i = skills.begin(); i != skills.end(); ++i) {
580 #if GTK_VERSION_GE(3,0)
581  if (*i != "") cb_graphlist->append(*i);
582 #else
583  if (*i != "") cb_graphlist->append_text(*i);
584 #endif
585  }
586 #endif
587  if (__skdbg_if->has_writer()) {
589  __skdbg_if->msgq_enqueue(sgm);
590  }
591  } else {
592 #ifdef USE_PAPYRUS
593  pvp_graph->set_graph_fsm(__skdbg_if->graph_fsm());
594  pvp_graph->set_graph(__skdbg_if->graph());
595  pvp_graph->render();
596 #else
597  gda->set_graph_fsm(__skdbg_if->graph_fsm());
598  gda->set_graph(__skdbg_if->graph());
599 #endif
600  }
601 
602  switch (__skdbg_if->graph_dir()) {
603  case SkillerDebugInterface::GD_TOP_BOTTOM:
604  tb_graphdir->set_stock_id(Gtk::Stock::GO_DOWN); break;
605  case SkillerDebugInterface::GD_BOTTOM_TOP:
606  tb_graphdir->set_stock_id(Gtk::Stock::GO_UP); break;
607  case SkillerDebugInterface::GD_LEFT_RIGHT:
608  tb_graphdir->set_stock_id(Gtk::Stock::GO_FORWARD); break;
609  case SkillerDebugInterface::GD_RIGHT_LEFT:
610  tb_graphdir->set_stock_id(Gtk::Stock::GO_BACK); break;
611  }
612 
613  if (__skdbg_if->is_graph_colored() != tb_graphcolored->get_active()) {
614  tb_graphcolored->set_active(__skdbg_if->is_graph_colored());
615  }
616  } catch (Exception &e) {
617  // ignored
618  }
619  }
620 }
621 
622 
623 void
624 SkillGuiGtkWindow::on_agdbg_data_changed()
625 {
626  if (tb_agent->get_active() && __agdbg_if) {
627  try {
628  __agdbg_if->read();
629 #ifdef USE_PAPYRUS
630  pvp_graph->set_graph_fsm(__agdbg_if->graph_fsm());
631  pvp_graph->set_graph(__agdbg_if->graph());
632  pvp_graph->render();
633 #else
634  gda->set_graph_fsm(__agdbg_if->graph_fsm());
635  gda->set_graph(__agdbg_if->graph());
636 #endif
637 
638  switch (__agdbg_if->graph_dir()) {
639  case SkillerDebugInterface::GD_TOP_BOTTOM:
640  tb_graphdir->set_stock_id(Gtk::Stock::GO_DOWN); break;
641  case SkillerDebugInterface::GD_BOTTOM_TOP:
642  tb_graphdir->set_stock_id(Gtk::Stock::GO_UP); break;
643  case SkillerDebugInterface::GD_LEFT_RIGHT:
644  tb_graphdir->set_stock_id(Gtk::Stock::GO_FORWARD); break;
645  case SkillerDebugInterface::GD_RIGHT_LEFT:
646  tb_graphdir->set_stock_id(Gtk::Stock::GO_BACK); break;
647  }
648  } catch (Exception &e) {
649  // ignored
650  }
651  }
652 }
653 
654 
655 void
656 SkillGuiGtkWindow::on_graphupd_clicked()
657 {
658 #ifdef USE_PAPYRUS
659  if ( pvp_graph->get_update_graph() ) {
660  pvp_graph->set_update_graph(false);
661  tb_graphupd->set_stock_id(Gtk::Stock::MEDIA_STOP);
662  } else {
663  pvp_graph->set_update_graph(true);
664  tb_graphupd->set_stock_id(Gtk::Stock::MEDIA_PLAY);
665  pvp_graph->render();
666  }
667 #else
668  if ( gda->get_update_graph() ) {
669  gda->set_update_graph(false);
670  tb_graphupd->set_stock_id(Gtk::Stock::MEDIA_STOP);
671  } else {
672  gda->set_update_graph(true);
673  tb_graphupd->set_stock_id(Gtk::Stock::MEDIA_PLAY);
674  }
675 #endif
676 }
677 
678 
679 void
680 SkillGuiGtkWindow::on_graphdir_clicked()
681 {
682  SkillerDebugInterface *iface = __skdbg_if;
683  if (tb_agent->get_active()) {
684  iface = __agdbg_if;
685  }
686 
687  Glib::ustring stockid = tb_graphdir->get_stock_id();
688  if (stockid == Gtk::Stock::GO_DOWN.id) {
689  send_graphdir_message(iface, SkillerDebugInterface::GD_BOTTOM_TOP);
690  } else if (stockid == Gtk::Stock::GO_UP.id) {
691  send_graphdir_message(iface, SkillerDebugInterface::GD_LEFT_RIGHT);
692  } else if (stockid == Gtk::Stock::GO_FORWARD.id) {
693  send_graphdir_message(iface, SkillerDebugInterface::GD_RIGHT_LEFT);
694  } else if (stockid == Gtk::Stock::GO_BACK.id) {
695  send_graphdir_message(iface, SkillerDebugInterface::GD_TOP_BOTTOM);
696  }
697 }
698 
699 void
700 SkillGuiGtkWindow::send_graphdir_message(SkillerDebugInterface *iface,
702 {
703  try {
704  if (iface) {
707  iface->msgq_enqueue(m);
708  } else {
709  throw Exception("Not connected to Fawkes.");
710  }
711  } catch (Exception &e) {
712  Gtk::MessageDialog md(*this,
713  Glib::ustring("Setting graph direction failed: ") + e.what(),
714  /* markup */ false,
715  Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK,
716  /* modal */ true);
717  md.set_title("Communication Failure");
718  md.run();
719  }
720 }
721 
722 void
723 SkillGuiGtkWindow::on_graphdir_changed(SkillerDebugInterface::GraphDirectionEnum gd)
724 {
725  if (tb_agent->get_active()) {
726  send_graphdir_message(__agdbg_if, gd);
727  } else {
728  send_graphdir_message(__skdbg_if, gd);
729  }
730 }
731 
732 
733 void
734 SkillGuiGtkWindow::on_graphcolor_toggled()
735 {
736 #ifdef HAVE_GCONFMM
737  __gconf->set(GCONF_PREFIX"/graph_colored", tb_graphcolored->get_active());
738 #endif
739 
740  SkillerDebugInterface *iface = __skdbg_if;
741  if (tb_agent->get_active()) {
742  iface = __agdbg_if;
743  }
744 
745  try {
746  if (iface) {
748  m = new SkillerDebugInterface::SetGraphColoredMessage(tb_graphcolored->get_active());
749  iface->msgq_enqueue(m);
750  } else {
751  throw Exception("Not connected to Fawkes.");
752  }
753  } catch (Exception &e) {
754  /* Ignore for now, causes error message on startup
755  Gtk::MessageDialog md(*this,
756  Glib::ustring("Setting graph color failed: ") + e.what(),
757  / markup / false,
758  Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK,
759  / modal / true);
760  md.set_title("Communication Failure");
761  md.run();
762  */
763  }
764 }
765 
766 
767 /** Constructor. */
768 SkillGuiGtkWindow::SkillStringRecord::SkillStringRecord()
769 {
770  add(skillstring);
771 }
772 
773 
774 void
775 SkillGuiGtkWindow::on_update_disabled()
776 {
777 #ifdef USE_PAPYRUS
778 #else
779  tb_graphupd->set_stock_id(Gtk::Stock::MEDIA_STOP);
780 #endif
781 }
782 
783 
784 void
785 SkillGuiGtkWindow::on_recording_toggled()
786 {
787 #ifdef USE_PAPYRUS
788 #else
789  bool active = tb_graphrecord->get_active();
790  if (gda->set_recording(active) != active) {
791  tb_graphrecord->set_active(!active);
792  }
793 #endif
794 }
char * skill_string() const
Get skill_string value.
SkillerDebugInterface Fawkes BlackBoard Interface.
sigc::signal< void > signal_disconnected()
Get "disconnected" signal.
sigc::signal< void > signal_connected()
Get "connected" signal.
void set_graph(std::string graph)
Set graph.
void zoom_in()
Zoom in.
Fawkes library namespace.
void disconnect()
Disconnect socket.
Definition: client.cpp:529
bool set_recording(bool recording)
Enable/disable recording.
StopExecMessage Fawkes BlackBoard Interface Message.
sigc::signal< void > signal_update_disabled()
Get "update disabled" signal.
char * error() const
Get error value.
ReleaseControlMessage Fawkes BlackBoard Interface Message.
virtual const char * what() const
Get primary string.
Definition: exception.cpp:661
uint32_t exclusive_controller() const
Get exclusive_controller value.
virtual void unregister_listener(BlackBoardInterfaceListener *listener)
Unregister BB interface listener.
Definition: blackboard.cpp:218
Graph drawing area.
SetGraphMessage Fawkes BlackBoard Interface Message.
~SkillGuiGtkWindow()
Destructor.
Definition: skillgui.cpp:215
bool get_update_graph()
Check if graph is being updated.
bool is_valid() const
Check validity of interface.
Definition: interface.cpp:466
AcquireControlMessage Fawkes BlackBoard Interface Message.
void set_graph_fsm(std::string fsm_name)
Set graph&#39;s FSM name.
SkillGuiGtkWindow(BaseObjectType *cobject, const Glib::RefPtr< Gtk::Builder > &builder)
Constructor.
Definition: skillgui.cpp:62
GraphDirectionEnum graph_dir() const
Get graph_dir value.
virtual void register_listener(BlackBoardInterfaceListener *listener, ListenerRegisterFlag flag=BBIL_FLAG_ALL)
Register BB event listener.
Definition: blackboard.cpp:190
void zoom_fit()
Zoom to fit.
Base class for exceptions in Fawkes.
Definition: exception.h:36
unsigned short serial() const
Get instance serial of interface.
Definition: interface.cpp:697
void read()
Read from BlackBoard into local copy.
Definition: interface.cpp:477
GraphDirectionEnum
Primary direction of the graph.
void run_and_connect()
Run dialog and try to connect.
void save()
save current graph.
void set_update_graph(bool update)
Set if the graph should be updated on new data.
void save()
Render current graph.
void set_gconf_prefix(Glib::ustring gconf_prefix)
Set Gconf prefix.
bool has_writer() const
Check if there is a writer for the interface.
Definition: interface.cpp:834
iterator begin()
Get iterator for messages.
Definition: exception.cpp:700
SkillStatusEnum status() const
Get status value.
ExecSkillMessage Fawkes BlackBoard Interface Message.
SetGraphColoredMessage Fawkes BlackBoard Interface Message.
unsigned int msgq_enqueue(Message *message)
Enqueue message at end of queue.
Definition: interface.cpp:903
Remote BlackBoard.
Definition: remote.h:48
virtual Interface * open_for_reading(const char *interface_type, const char *identifier, const char *owner=NULL)=0
Open interface for reading.
void set_network_client(fawkes::FawkesNetworkClient *client)
Set the network client.
const char * get_hostname() const
Get the client&#39;s hostname.
Definition: client.cpp:856
SkillerInterface Fawkes BlackBoard Interface.
void zoom_out()
Zoom out.
bool is_graph_colored() const
Get graph_colored value.
char * graph() const
Get graph value.
void open()
Open a dot graph and display it.
bool connected() const
Check if connection is alive.
Definition: client.cpp:823
void zoom_fit()
Zoom to fit.
char * graph_fsm() const
Get graph_fsm value.
void set_client(FawkesNetworkClient *client)
Set FawkesNetworkClient instance.
Definition: logview.cpp:161
FawkesNetworkClient * get_client()
Get client.
void zoom_reset()
Zoom reset.
SetGraphDirectionMessage Fawkes BlackBoard Interface Message.
Skill FSM Graph Viewport.
Interface listener with dispatcher.
sigc::signal< void, Interface * > signal_data_changed()
Get "data changed" signal.
virtual void close(Interface *interface)=0
Close interface.