Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * skillgui.cpp - Skill GUI 00004 * 00005 * Created: Mon Nov 03 13:37:33 2008 00006 * Copyright 2008 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. 00014 * 00015 * This program is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU Library General Public License for more details. 00019 * 00020 * Read the full text in the LICENSE.GPL file in the doc directory. 00021 */ 00022 00023 #include "skillgui.h" 00024 #ifdef USE_PAPYRUS 00025 # include "graph_viewport.h" 00026 #else 00027 # include "graph_drawing_area.h" 00028 #endif 00029 00030 #include <utils/system/argparser.h> 00031 #include <blackboard/remote.h> 00032 #include <netcomm/fawkes/client.h> 00033 00034 #include <gui_utils/logview.h> 00035 #include <gui_utils/throbber.h> 00036 #include <gui_utils/service_chooser_dialog.h> 00037 #include <gui_utils/interface_dispatcher.h> 00038 #include <gui_utils/plugin_tree_view.h> 00039 00040 #include <cstring> 00041 #include <string> 00042 00043 #include <gvc.h> 00044 00045 using namespace fawkes; 00046 00047 #define ACTIVE_SKILL "Active Skill" 00048 00049 /** @class SkillGuiGtkWindow "skillgui.h" 00050 * Skill GUI main window. 00051 * The Skill GUI provides shows Skiller log messages and allows for 00052 * executing skills. 00053 * @author Tim Niemueller 00054 */ 00055 00056 /** Constructor. 00057 * @param cobject C base object 00058 * @param builder Gtk Builder 00059 */ 00060 SkillGuiGtkWindow::SkillGuiGtkWindow(BaseObjectType* cobject, 00061 const Glib::RefPtr<Gtk::Builder> &builder) 00062 : Gtk::Window(cobject) 00063 { 00064 bb = NULL; 00065 __skiller_if = NULL; 00066 __skdbg_if = NULL; 00067 __agdbg_if = NULL; 00068 00069 #ifdef HAVE_GCONFMM 00070 __gconf = Gnome::Conf::Client::get_default_client(); 00071 __gconf->add_dir(GCONF_PREFIX); 00072 #endif 00073 00074 builder->get_widget_derived("trv_log", __logview); 00075 builder->get_widget("tb_connection", tb_connection); 00076 builder->get_widget("but_continuous", but_continuous); 00077 builder->get_widget("but_clearlog", but_clearlog); 00078 builder->get_widget("tb_exit", tb_exit); 00079 builder->get_widget("cbe_skillstring", cbe_skillstring); 00080 builder->get_widget("but_exec", but_exec); 00081 builder->get_widget("but_stop", but_stop); 00082 builder->get_widget("lab_status", lab_status); 00083 builder->get_widget("lab_alive", lab_alive); 00084 builder->get_widget("lab_continuous", lab_continuous); 00085 builder->get_widget("lab_skillstring", lab_skillstring); 00086 builder->get_widget("lab_error", lab_error); 00087 builder->get_widget("scw_graph", scw_graph); 00088 //builder->get_widget("drw_graph", drw_graph); 00089 builder->get_widget("ntb_tabs", ntb_tabs); 00090 builder->get_widget("tb_skiller", tb_skiller); 00091 builder->get_widget("tb_agent", tb_agent); 00092 builder->get_widget("tb_graphlist", tb_graphlist); 00093 builder->get_widget("tb_controller", tb_controller); 00094 builder->get_widget("tb_graphsave", tb_graphsave); 00095 builder->get_widget("tb_graphopen", tb_graphopen); 00096 builder->get_widget("tb_graphupd", tb_graphupd); 00097 builder->get_widget("tb_graphrecord", tb_graphrecord); 00098 builder->get_widget("tb_zoomin", tb_zoomin); 00099 builder->get_widget("tb_zoomout", tb_zoomout); 00100 builder->get_widget("tb_zoomfit", tb_zoomfit); 00101 builder->get_widget("tb_zoomreset", tb_zoomreset); 00102 builder->get_widget("tb_graphdir", tb_graphdir); 00103 builder->get_widget("tb_graphcolored", tb_graphcolored); 00104 00105 builder->get_widget_derived("img_throbber", __throbber); 00106 builder->get_widget_derived("trv_plugins", __trv_plugins); 00107 00108 Gtk::SeparatorToolItem *spacesep; 00109 builder->get_widget("tb_spacesep", spacesep); 00110 spacesep->set_expand(); 00111 00112 // This should be in the Glade file, but is not restored for some reason 00113 tb_graphsave->set_homogeneous(false); 00114 tb_graphopen->set_homogeneous(false); 00115 tb_graphupd->set_homogeneous(false); 00116 tb_graphrecord->set_homogeneous(false); 00117 tb_zoomin->set_homogeneous(false); 00118 tb_zoomout->set_homogeneous(false); 00119 tb_zoomfit->set_homogeneous(false); 00120 tb_zoomreset->set_homogeneous(false); 00121 tb_graphdir->set_homogeneous(false); 00122 tb_graphcolored->set_homogeneous(false); 00123 00124 #if GTK_VERSION_GE(3,0) 00125 if (! cbe_skillstring->get_has_entry()) { 00126 throw Exception("Skill string combo box has no entry, invalid UI file?"); 00127 } 00128 #endif 00129 __sks_list = Gtk::ListStore::create(__sks_record); 00130 cbe_skillstring->set_model(__sks_list); 00131 #if GTK_VERSION_GE(3,0) 00132 cbe_skillstring->set_entry_text_column(__sks_record.skillstring); 00133 #else 00134 cbe_skillstring->set_text_column(__sks_record.skillstring); 00135 #endif 00136 00137 cbe_skillstring->get_entry()->set_activates_default(true); 00138 00139 __trv_plugins->set_network_client(connection_dispatcher.get_client()); 00140 #ifdef HAVE_GCONFMM 00141 __trv_plugins->set_gconf_prefix(GCONF_PREFIX); 00142 #endif 00143 00144 #ifdef USE_PAPYRUS 00145 pvp_graph = Gtk::manage(new SkillGuiGraphViewport()); 00146 scw_graph->add(*pvp_graph); 00147 pvp_graph->show(); 00148 #else 00149 gda = Gtk::manage(new SkillGuiGraphDrawingArea()); 00150 scw_graph->add(*gda); 00151 gda->show(); 00152 #endif 00153 00154 cb_graphlist = Gtk::manage(new Gtk::ComboBoxText()); 00155 #if GTK_VERSION_GE(3,0) 00156 cb_graphlist->append(ACTIVE_SKILL); 00157 #else 00158 cb_graphlist->append_text(ACTIVE_SKILL); 00159 #endif 00160 cb_graphlist->set_active_text(ACTIVE_SKILL); 00161 tb_graphlist->add(*cb_graphlist); 00162 cb_graphlist->show(); 00163 00164 //ntb_tabs->set_current_page(1); 00165 00166 connection_dispatcher.signal_connected().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_connect)); 00167 connection_dispatcher.signal_disconnected().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_disconnect)); 00168 00169 tb_connection->signal_clicked().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_connection_clicked)); 00170 but_exec->signal_clicked().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_exec_clicked)); 00171 tb_controller->signal_clicked().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_controller_clicked)); 00172 tb_exit->signal_clicked().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_exit_clicked)); 00173 but_stop->signal_clicked().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_stop_clicked)); 00174 but_continuous->signal_toggled().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_contexec_toggled)); 00175 but_clearlog->signal_clicked().connect(sigc::mem_fun(*__logview, &LogView::clear)); 00176 tb_skiller->signal_toggled().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_skdbg_data_changed)); 00177 tb_skiller->signal_toggled().connect(sigc::bind(sigc::mem_fun(*cb_graphlist, &Gtk::ComboBoxText::set_sensitive),true)); 00178 tb_agent->signal_toggled().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_agdbg_data_changed)); 00179 tb_agent->signal_toggled().connect(sigc::bind(sigc::mem_fun(*cb_graphlist, &Gtk::ComboBoxText::set_sensitive),false)); 00180 cb_graphlist->signal_changed().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_skill_changed)); 00181 tb_graphupd->signal_clicked().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_graphupd_clicked)); 00182 tb_graphdir->signal_clicked().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_graphdir_clicked)); 00183 tb_graphcolored->signal_toggled().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_graphcolor_toggled)); 00184 #ifdef USE_PAPYRUS 00185 tb_graphsave->signal_clicked().connect(sigc::mem_fun(*pvp_graph, &SkillGuiGraphViewport::save)); 00186 tb_zoomin->signal_clicked().connect(sigc::mem_fun(*pvp_graph, &SkillGuiGraphViewport::zoom_in)); 00187 tb_zoomout->signal_clicked().connect(sigc::mem_fun(*pvp_graph, &SkillGuiGraphViewport::zoom_out)); 00188 tb_zoomfit->signal_clicked().connect(sigc::mem_fun(*pvp_graph, &SkillGuiGraphViewport::zoom_fit)); 00189 tb_zoomreset->signal_clicked().connect(sigc::mem_fun(*pvp_graph, &SkillGuiGraphViewport::zoom_reset)); 00190 #else 00191 tb_graphsave->signal_clicked().connect(sigc::mem_fun(*gda, &SkillGuiGraphDrawingArea::save)); 00192 tb_graphopen->signal_clicked().connect(sigc::mem_fun(*gda, &SkillGuiGraphDrawingArea::open)); 00193 tb_zoomin->signal_clicked().connect(sigc::mem_fun(*gda, &SkillGuiGraphDrawingArea::zoom_in)); 00194 tb_zoomout->signal_clicked().connect(sigc::mem_fun(*gda, &SkillGuiGraphDrawingArea::zoom_out)); 00195 tb_zoomfit->signal_clicked().connect(sigc::mem_fun(*gda, &SkillGuiGraphDrawingArea::zoom_fit)); 00196 tb_zoomreset->signal_clicked().connect(sigc::mem_fun(*gda, &SkillGuiGraphDrawingArea::zoom_reset)); 00197 tb_graphrecord->signal_clicked().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_recording_toggled)); 00198 gda->signal_update_disabled().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_update_disabled)); 00199 #endif 00200 00201 #ifdef HAVE_GCONFMM 00202 __gconf->signal_value_changed().connect(sigc::hide(sigc::hide(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_config_changed)))); 00203 on_config_changed(); 00204 #endif 00205 } 00206 00207 00208 /** Destructor. */ 00209 SkillGuiGtkWindow::~SkillGuiGtkWindow() 00210 { 00211 #ifdef HAVE_GCONFMM 00212 __gconf->remove_dir(GCONF_PREFIX); 00213 #endif 00214 __logview->set_client(NULL); 00215 __trv_plugins->set_network_client(NULL); 00216 } 00217 00218 00219 void 00220 SkillGuiGtkWindow::on_config_changed() 00221 { 00222 #ifdef HAVE_GCONFMM 00223 Gnome::Conf::SListHandle_ValueString l(__gconf->get_string_list(GCONF_PREFIX"/command_history")); 00224 00225 __sks_list->clear(); 00226 for (Gnome::Conf::SListHandle_ValueString::const_iterator i = l.begin(); i != l.end(); ++i) { 00227 Gtk::TreeModel::Row row = *__sks_list->append(); 00228 row[__sks_record.skillstring] = *i; 00229 } 00230 00231 #ifdef GLIBMM_EXCEPTIONS_ENABLED 00232 bool continuous = __gconf->get_bool(GCONF_PREFIX"/continuous_exec"); 00233 bool colored = __gconf->get_bool(GCONF_PREFIX"/graph_colored"); 00234 #else 00235 std::auto_ptr<Glib::Error> error; 00236 bool continuous = __gconf->get_bool(GCONF_PREFIX"/continuous_exec", error); 00237 bool colored = __gconf->get_bool(GCONF_PREFIX"/graph_colored", error); 00238 #endif 00239 but_continuous->set_active(continuous); 00240 tb_graphcolored->set_active(colored); 00241 #endif 00242 } 00243 00244 00245 void 00246 SkillGuiGtkWindow::on_skill_changed() 00247 { 00248 Glib::ustring skill = cb_graphlist->get_active_text(); 00249 if ( skill == ACTIVE_SKILL ) { 00250 skill = "ACTIVE"; 00251 } 00252 SkillerDebugInterface::SetGraphMessage *sgm = new SkillerDebugInterface::SetGraphMessage(skill.c_str()); 00253 __skdbg_if->msgq_enqueue(sgm); 00254 } 00255 00256 void 00257 SkillGuiGtkWindow::on_contexec_toggled() 00258 { 00259 #ifdef HAVE_GCONFMM 00260 __gconf->set(GCONF_PREFIX"/continuous_exec", but_continuous->get_active()); 00261 #endif 00262 } 00263 00264 /** Event handler for connection button. */ 00265 void 00266 SkillGuiGtkWindow::on_connection_clicked() 00267 { 00268 if ( ! connection_dispatcher.get_client()->connected() ) { 00269 ServiceChooserDialog ssd(*this, connection_dispatcher.get_client()); 00270 ssd.run_and_connect(); 00271 } else { 00272 connection_dispatcher.get_client()->disconnect(); 00273 } 00274 } 00275 00276 00277 void 00278 SkillGuiGtkWindow::on_exit_clicked() 00279 { 00280 Gtk::Main::quit(); 00281 } 00282 00283 00284 void 00285 SkillGuiGtkWindow::on_controller_clicked() 00286 { 00287 if (__skiller_if && __skiller_if->is_valid() && __skiller_if->has_writer() && 00288 __skiller_if->exclusive_controller() == __skiller_if->serial()) { 00289 // we are exclusive controller, release control 00290 SkillerInterface::ReleaseControlMessage *rcm = new SkillerInterface::ReleaseControlMessage(); 00291 __skiller_if->msgq_enqueue(rcm); 00292 } else if (__skiller_if && __skiller_if->is_valid() && __skiller_if->has_writer() && 00293 __skiller_if->exclusive_controller() == 0) { 00294 // there is no exclusive controller, try to acquire control 00295 SkillerInterface::AcquireControlMessage *acm = new SkillerInterface::AcquireControlMessage(); 00296 __skiller_if->msgq_enqueue(acm); 00297 } else { 00298 Gtk::MessageDialog md(*this, 00299 "Another component already acquired the exclusive " 00300 "control for the Skiller; not acquiring exclusive control.", 00301 /* markup */ false, 00302 Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, 00303 /* modal */ true); 00304 md.set_title("Control Acquisition Failed"); 00305 md.run(); 00306 } 00307 } 00308 00309 void 00310 SkillGuiGtkWindow::on_stop_clicked() 00311 { 00312 if ( bb && __skiller_if && __skiller_if->is_valid() && __skiller_if->has_writer() ) { 00313 SkillerInterface::StopExecMessage *sem = new SkillerInterface::StopExecMessage(); 00314 __skiller_if->msgq_enqueue(sem); 00315 } 00316 } 00317 00318 void 00319 SkillGuiGtkWindow::close_bb() 00320 { 00321 if ( bb ) { 00322 bb->unregister_listener(__skiller_ifd); 00323 bb->unregister_listener(__skdbg_ifd); 00324 bb->unregister_listener(__agdbg_ifd); 00325 delete __skiller_ifd; 00326 delete __skdbg_ifd; 00327 delete __agdbg_ifd; 00328 if ( __skiller_if && __skiller_if->is_valid() && __skiller_if->has_writer() && 00329 (__skiller_if->exclusive_controller() == __skiller_if->serial()) ) { 00330 SkillerInterface::ReleaseControlMessage *rcm = new SkillerInterface::ReleaseControlMessage(); 00331 __skiller_if->msgq_enqueue(rcm); 00332 } 00333 bb->close(__skiller_if); 00334 bb->close(__skdbg_if); 00335 bb->close(__agdbg_if); 00336 delete bb; 00337 __skiller_if = NULL; 00338 __skdbg_if = NULL; 00339 __agdbg_if = NULL; 00340 bb = NULL; 00341 } 00342 } 00343 00344 /** Event handler for connected event. */ 00345 void 00346 SkillGuiGtkWindow::on_connect() 00347 { 00348 try { 00349 if ( ! bb ) { 00350 bb = new RemoteBlackBoard(connection_dispatcher.get_client()); 00351 __skiller_if = bb->open_for_reading<SkillerInterface>("Skiller"); 00352 __skdbg_if = bb->open_for_reading<SkillerDebugInterface>("Skiller"); 00353 __agdbg_if = bb->open_for_reading<SkillerDebugInterface>("LuaAgent"); 00354 on_skiller_data_changed(); 00355 on_skdbg_data_changed(); 00356 on_agdbg_data_changed(); 00357 00358 __skiller_ifd = new InterfaceDispatcher("Skiller IFD", __skiller_if); 00359 __skdbg_ifd = new InterfaceDispatcher("SkillerDebug IFD", __skdbg_if); 00360 __agdbg_ifd = new InterfaceDispatcher("LuaAgent SkillerDebug IFD", __agdbg_if); 00361 bb->register_listener(__skiller_ifd, BlackBoard::BBIL_FLAG_DATA); 00362 bb->register_listener(__skdbg_ifd, BlackBoard::BBIL_FLAG_DATA); 00363 bb->register_listener(__agdbg_ifd, BlackBoard::BBIL_FLAG_DATA); 00364 __skiller_ifd->signal_data_changed().connect(sigc::hide(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_skiller_data_changed))); 00365 __skdbg_ifd->signal_data_changed().connect(sigc::hide(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_skdbg_data_changed))); 00366 __agdbg_ifd->signal_data_changed().connect(sigc::hide(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_agdbg_data_changed))); 00367 00368 // always try to acquire control on connect, this may well fail, for 00369 // example if agent is running, but we don't care 00370 __skiller_if->read(); 00371 if (__skiller_if->has_writer() && __skiller_if->exclusive_controller() == 0) { 00372 SkillerInterface::AcquireControlMessage *aqm = new SkillerInterface::AcquireControlMessage(); 00373 __skiller_if->msgq_enqueue(aqm); 00374 } 00375 if (__skdbg_if->has_writer()) { 00376 SkillerDebugInterface::SetGraphMessage *sgm = new SkillerDebugInterface::SetGraphMessage("LIST"); 00377 __skdbg_if->msgq_enqueue(sgm); 00378 } 00379 } 00380 tb_connection->set_stock_id(Gtk::Stock::DISCONNECT); 00381 __logview->set_client(connection_dispatcher.get_client()); 00382 00383 but_continuous->set_sensitive(true); 00384 tb_controller->set_sensitive(true); 00385 cbe_skillstring->set_sensitive(true); 00386 00387 this->set_title(std::string("Skill GUI @ ") + connection_dispatcher.get_client()->get_hostname()); 00388 } catch (Exception &e) { 00389 Glib::ustring message = *(e.begin()); 00390 Gtk::MessageDialog md(*this, message, /* markup */ false, 00391 Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, 00392 /* modal */ true); 00393 md.set_title("BlackBoard connection failed"); 00394 md.run(); 00395 00396 close_bb(); 00397 connection_dispatcher.get_client()->disconnect(); 00398 } 00399 } 00400 00401 /** Event handler for disconnected event. */ 00402 void 00403 SkillGuiGtkWindow::on_disconnect() 00404 { 00405 but_continuous->set_sensitive(false); 00406 tb_controller->set_sensitive(false); 00407 cbe_skillstring->set_sensitive(false); 00408 but_exec->set_sensitive(false); 00409 but_stop->set_sensitive(false); 00410 00411 close_bb(); 00412 00413 tb_connection->set_stock_id(Gtk::Stock::CONNECT); 00414 #ifdef USE_PAPYRUS 00415 pvp_graph->queue_draw(); 00416 #endif 00417 __logview->set_client(NULL); 00418 00419 this->set_title("Skill GUI"); 00420 } 00421 00422 00423 void 00424 SkillGuiGtkWindow::on_exec_clicked() 00425 { 00426 Glib::ustring sks = ""; 00427 if ( cbe_skillstring->get_active_row_number() == -1 ) { 00428 Gtk::Entry *entry = cbe_skillstring->get_entry(); 00429 sks = entry->get_text(); 00430 } else { 00431 Gtk::TreeModel::Row row = *cbe_skillstring->get_active(); 00432 #if GTK_VERSION_GE(3,0) 00433 row.get_value(cbe_skillstring->get_entry_text_column(), sks); 00434 #else 00435 row.get_value(cbe_skillstring->get_text_column(), sks); 00436 #endif 00437 } 00438 00439 if ( sks != "" ) { 00440 __throbber->set_timeout(80); 00441 00442 if (__skiller_if && __skiller_if->is_valid() && __skiller_if->has_writer() && 00443 __skiller_if->exclusive_controller() == __skiller_if->serial()) { 00444 00445 if ( but_continuous->get_active() ) { 00446 SkillerInterface::ExecSkillContinuousMessage *escm = new SkillerInterface::ExecSkillContinuousMessage(sks.c_str()); 00447 __skiller_if->msgq_enqueue(escm); 00448 } else { 00449 SkillerInterface::ExecSkillMessage *esm = new SkillerInterface::ExecSkillMessage(sks.c_str()); 00450 __skiller_if->msgq_enqueue(esm); 00451 } 00452 00453 Gtk::TreeModel::Children children = __sks_list->children(); 00454 bool ok = true; 00455 if ( ! children.empty() ) { 00456 size_t num = 0; 00457 Gtk::TreeIter i = children.begin(); 00458 while (ok && (i != children.end())) { 00459 if ( num >= 9 ) { 00460 i = __sks_list->erase(i); 00461 } else { 00462 Gtk::TreeModel::Row row = *i; 00463 ok = (row[__sks_record.skillstring] != sks); 00464 ++num; 00465 ++i; 00466 } 00467 } 00468 } 00469 if (ok) { 00470 Gtk::TreeModel::Row row = *__sks_list->prepend(); 00471 row[__sks_record.skillstring] = sks; 00472 00473 std::list<Glib::ustring> l; 00474 for (Gtk::TreeIter i = children.begin(); i != children.end(); ++i) { 00475 Gtk::TreeModel::Row row = *i; 00476 l.push_back(row[__sks_record.skillstring]); 00477 } 00478 00479 #ifdef HAVE_GCONFMM 00480 __gconf->set_string_list(GCONF_PREFIX"/command_history", l); 00481 #endif 00482 } 00483 } else { 00484 Gtk::MessageDialog md(*this, "The exclusive control over the skiller has " 00485 "not been acquired yet and skills cannot be executed", 00486 /* markup */ false, 00487 Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, 00488 /* modal */ true); 00489 md.set_title("Skill Execution Failure"); 00490 md.run(); 00491 } 00492 } 00493 } 00494 00495 00496 void 00497 SkillGuiGtkWindow::on_skiller_data_changed() 00498 { 00499 try { 00500 __skiller_if->read(); 00501 00502 switch (__skiller_if->status()) { 00503 case SkillerInterface::S_INACTIVE: 00504 __throbber->stop_anim(); 00505 lab_status->set_text("S_INACTIVE"); 00506 break; 00507 case SkillerInterface::S_FINAL: 00508 __throbber->stop_anim(); 00509 __throbber->set_stock(Gtk::Stock::APPLY); 00510 lab_status->set_text("S_FINAL"); 00511 break; 00512 case SkillerInterface::S_RUNNING: 00513 __throbber->start_anim(); 00514 lab_status->set_text("S_RUNNING"); 00515 break; 00516 case SkillerInterface::S_FAILED: 00517 __throbber->stop_anim(); 00518 __throbber->set_stock(Gtk::Stock::DIALOG_WARNING); 00519 lab_status->set_text("S_FAILED"); 00520 break; 00521 } 00522 00523 lab_skillstring->set_text(__skiller_if->skill_string()); 00524 lab_error->set_text(__skiller_if->error()); 00525 #if GTKMM_MAJOR_VERSION > 2 || ( GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 12 ) 00526 lab_skillstring->set_tooltip_text(__skiller_if->skill_string()); 00527 lab_error->set_tooltip_text(__skiller_if->error()); 00528 #endif 00529 lab_continuous->set_text(__skiller_if->is_continuous() ? "Yes" : "No"); 00530 lab_alive->set_text(__skiller_if->has_writer() ? "Yes" : "No"); 00531 00532 if ( __skiller_if->exclusive_controller() == __skiller_if->serial() ) { 00533 if ( tb_controller->get_stock_id() == Gtk::Stock::NO.id ) { 00534 tb_controller->set_stock_id(Gtk::Stock::YES); 00535 #if GTKMM_MAJOR_VERSION > 2 || ( GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 12 ) 00536 tb_controller->set_tooltip_text("Release exclusive control"); 00537 #endif 00538 } 00539 but_exec->set_sensitive(true); 00540 but_stop->set_sensitive(true); 00541 } else { 00542 if ( tb_controller->get_stock_id() == Gtk::Stock::YES.id ) { 00543 tb_controller->set_stock_id(Gtk::Stock::NO); 00544 #if GTKMM_MAJOR_VERSION > 2 || ( GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 12 ) 00545 tb_controller->set_tooltip_text("Gain exclusive control"); 00546 #endif 00547 } 00548 but_exec->set_sensitive(false); 00549 but_stop->set_sensitive(false); 00550 } 00551 00552 00553 } catch (Exception &e) { 00554 __throbber->stop_anim(); 00555 } 00556 } 00557 00558 00559 void 00560 SkillGuiGtkWindow::on_skdbg_data_changed() 00561 { 00562 if (tb_skiller->get_active() && __skdbg_if) { 00563 try { 00564 __skdbg_if->read(); 00565 00566 if (strcmp(__skdbg_if->graph_fsm(), "LIST") == 0) { 00567 Glib::ustring list = __skdbg_if->graph(); 00568 #if GTK_VERSION_GE(3,0) 00569 cb_graphlist->remove_all(); 00570 cb_graphlist->append(ACTIVE_SKILL); 00571 #else 00572 cb_graphlist->clear_items(); 00573 cb_graphlist->append_text(ACTIVE_SKILL); 00574 #endif 00575 cb_graphlist->set_active_text(ACTIVE_SKILL); 00576 #if GTK_VERSION_GE(2,14) 00577 Glib::RefPtr<Glib::Regex> regex = Glib::Regex::create("\n"); 00578 std::list<std::string> skills = regex->split(list); 00579 for (std::list<std::string>::iterator i = skills.begin(); i != skills.end(); ++i) { 00580 #if GTK_VERSION_GE(3,0) 00581 if (*i != "") cb_graphlist->append(*i); 00582 #else 00583 if (*i != "") cb_graphlist->append_text(*i); 00584 #endif 00585 } 00586 #endif 00587 if (__skdbg_if->has_writer()) { 00588 SkillerDebugInterface::SetGraphMessage *sgm = new SkillerDebugInterface::SetGraphMessage("ACTIVE"); 00589 __skdbg_if->msgq_enqueue(sgm); 00590 } 00591 } else { 00592 #ifdef USE_PAPYRUS 00593 pvp_graph->set_graph_fsm(__skdbg_if->graph_fsm()); 00594 pvp_graph->set_graph(__skdbg_if->graph()); 00595 pvp_graph->render(); 00596 #else 00597 gda->set_graph_fsm(__skdbg_if->graph_fsm()); 00598 gda->set_graph(__skdbg_if->graph()); 00599 #endif 00600 } 00601 00602 switch (__skdbg_if->graph_dir()) { 00603 case SkillerDebugInterface::GD_TOP_BOTTOM: 00604 tb_graphdir->set_stock_id(Gtk::Stock::GO_DOWN); break; 00605 case SkillerDebugInterface::GD_BOTTOM_TOP: 00606 tb_graphdir->set_stock_id(Gtk::Stock::GO_UP); break; 00607 case SkillerDebugInterface::GD_LEFT_RIGHT: 00608 tb_graphdir->set_stock_id(Gtk::Stock::GO_FORWARD); break; 00609 case SkillerDebugInterface::GD_RIGHT_LEFT: 00610 tb_graphdir->set_stock_id(Gtk::Stock::GO_BACK); break; 00611 } 00612 } catch (Exception &e) { 00613 // ignored 00614 } 00615 } 00616 } 00617 00618 00619 void 00620 SkillGuiGtkWindow::on_agdbg_data_changed() 00621 { 00622 if (tb_agent->get_active() && __agdbg_if) { 00623 try { 00624 __agdbg_if->read(); 00625 #ifdef USE_PAPYRUS 00626 pvp_graph->set_graph_fsm(__agdbg_if->graph_fsm()); 00627 pvp_graph->set_graph(__agdbg_if->graph()); 00628 pvp_graph->render(); 00629 #else 00630 gda->set_graph_fsm(__agdbg_if->graph_fsm()); 00631 gda->set_graph(__agdbg_if->graph()); 00632 #endif 00633 00634 switch (__agdbg_if->graph_dir()) { 00635 case SkillerDebugInterface::GD_TOP_BOTTOM: 00636 tb_graphdir->set_stock_id(Gtk::Stock::GO_DOWN); break; 00637 case SkillerDebugInterface::GD_BOTTOM_TOP: 00638 tb_graphdir->set_stock_id(Gtk::Stock::GO_UP); break; 00639 case SkillerDebugInterface::GD_LEFT_RIGHT: 00640 tb_graphdir->set_stock_id(Gtk::Stock::GO_FORWARD); break; 00641 case SkillerDebugInterface::GD_RIGHT_LEFT: 00642 tb_graphdir->set_stock_id(Gtk::Stock::GO_BACK); break; 00643 } 00644 } catch (Exception &e) { 00645 // ignored 00646 } 00647 } 00648 } 00649 00650 00651 void 00652 SkillGuiGtkWindow::on_graphupd_clicked() 00653 { 00654 #ifdef USE_PAPYRUS 00655 if ( pvp_graph->get_update_graph() ) { 00656 pvp_graph->set_update_graph(false); 00657 tb_graphupd->set_stock_id(Gtk::Stock::MEDIA_STOP); 00658 } else { 00659 pvp_graph->set_update_graph(true); 00660 tb_graphupd->set_stock_id(Gtk::Stock::MEDIA_PLAY); 00661 pvp_graph->render(); 00662 } 00663 #else 00664 if ( gda->get_update_graph() ) { 00665 gda->set_update_graph(false); 00666 tb_graphupd->set_stock_id(Gtk::Stock::MEDIA_STOP); 00667 } else { 00668 gda->set_update_graph(true); 00669 tb_graphupd->set_stock_id(Gtk::Stock::MEDIA_PLAY); 00670 } 00671 #endif 00672 } 00673 00674 00675 void 00676 SkillGuiGtkWindow::on_graphdir_clicked() 00677 { 00678 SkillerDebugInterface *iface = __skdbg_if; 00679 if (tb_agent->get_active()) { 00680 iface = __agdbg_if; 00681 } 00682 00683 Glib::ustring stockid = tb_graphdir->get_stock_id(); 00684 if (stockid == Gtk::Stock::GO_DOWN.id) { 00685 send_graphdir_message(iface, SkillerDebugInterface::GD_BOTTOM_TOP); 00686 } else if (stockid == Gtk::Stock::GO_UP.id) { 00687 send_graphdir_message(iface, SkillerDebugInterface::GD_LEFT_RIGHT); 00688 } else if (stockid == Gtk::Stock::GO_FORWARD.id) { 00689 send_graphdir_message(iface, SkillerDebugInterface::GD_RIGHT_LEFT); 00690 } else if (stockid == Gtk::Stock::GO_BACK.id) { 00691 send_graphdir_message(iface, SkillerDebugInterface::GD_TOP_BOTTOM); 00692 } 00693 } 00694 00695 void 00696 SkillGuiGtkWindow::send_graphdir_message(SkillerDebugInterface *iface, 00697 SkillerDebugInterface::GraphDirectionEnum gd) 00698 { 00699 try { 00700 if (iface) { 00701 SkillerDebugInterface::SetGraphDirectionMessage *m; 00702 m = new SkillerDebugInterface::SetGraphDirectionMessage(gd); 00703 iface->msgq_enqueue(m); 00704 } else { 00705 throw Exception("Not connected to Fawkes."); 00706 } 00707 } catch (Exception &e) { 00708 Gtk::MessageDialog md(*this, 00709 Glib::ustring("Setting graph direction failed: ") + e.what(), 00710 /* markup */ false, 00711 Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, 00712 /* modal */ true); 00713 md.set_title("Communication Failure"); 00714 md.run(); 00715 } 00716 } 00717 00718 void 00719 SkillGuiGtkWindow::on_graphdir_changed(SkillerDebugInterface::GraphDirectionEnum gd) 00720 { 00721 if (tb_agent->get_active()) { 00722 send_graphdir_message(__agdbg_if, gd); 00723 } else { 00724 send_graphdir_message(__skdbg_if, gd); 00725 } 00726 } 00727 00728 00729 void 00730 SkillGuiGtkWindow::on_graphcolor_toggled() 00731 { 00732 #ifdef HAVE_GCONFMM 00733 __gconf->set(GCONF_PREFIX"/graph_colored", tb_graphcolored->get_active()); 00734 #endif 00735 00736 SkillerDebugInterface *iface = __skdbg_if; 00737 if (tb_agent->get_active()) { 00738 iface = __agdbg_if; 00739 } 00740 00741 try { 00742 if (iface) { 00743 SkillerDebugInterface::SetGraphColoredMessage *m; 00744 m = new SkillerDebugInterface::SetGraphColoredMessage(tb_graphcolored->get_active()); 00745 iface->msgq_enqueue(m); 00746 } else { 00747 throw Exception("Not connected to Fawkes."); 00748 } 00749 } catch (Exception &e) { 00750 /* Ignore for now, causes error message on startup 00751 Gtk::MessageDialog md(*this, 00752 Glib::ustring("Setting graph color failed: ") + e.what(), 00753 / markup / false, 00754 Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, 00755 / modal / true); 00756 md.set_title("Communication Failure"); 00757 md.run(); 00758 */ 00759 } 00760 } 00761 00762 00763 /** Constructor. */ 00764 SkillGuiGtkWindow::SkillStringRecord::SkillStringRecord() 00765 { 00766 add(skillstring); 00767 } 00768 00769 00770 void 00771 SkillGuiGtkWindow::on_update_disabled() 00772 { 00773 #ifdef USE_PAPYRUS 00774 #else 00775 tb_graphupd->set_stock_id(Gtk::Stock::MEDIA_STOP); 00776 #endif 00777 } 00778 00779 00780 void 00781 SkillGuiGtkWindow::on_recording_toggled() 00782 { 00783 #ifdef USE_PAPYRUS 00784 #else 00785 bool active = tb_graphrecord->get_active(); 00786 if (gda->set_recording(active) != active) { 00787 tb_graphrecord->set_active(!active); 00788 } 00789 #endif 00790 }