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 refxml Glade XML 00059 */ 00060 SkillGuiGtkWindow::SkillGuiGtkWindow(BaseObjectType* cobject, 00061 const Glib::RefPtr<Gnome::Glade::Xml> &refxml) 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 refxml->get_widget_derived("trv_log", __logview); 00075 refxml->get_widget("tb_connection", tb_connection); 00076 refxml->get_widget("but_continuous", but_continuous); 00077 refxml->get_widget("but_clearlog", but_clearlog); 00078 refxml->get_widget("tb_exit", tb_exit); 00079 refxml->get_widget("cbe_skillstring", cbe_skillstring); 00080 refxml->get_widget("but_exec", but_exec); 00081 refxml->get_widget("but_stop", but_stop); 00082 refxml->get_widget("lab_status", lab_status); 00083 refxml->get_widget("lab_alive", lab_alive); 00084 refxml->get_widget("lab_continuous", lab_continuous); 00085 refxml->get_widget("lab_skillstring", lab_skillstring); 00086 refxml->get_widget("lab_error", lab_error); 00087 refxml->get_widget("scw_graph", scw_graph); 00088 //refxml->get_widget("drw_graph", drw_graph); 00089 refxml->get_widget("ntb_tabs", ntb_tabs); 00090 refxml->get_widget("tb_skiller", tb_skiller); 00091 refxml->get_widget("tb_agent", tb_agent); 00092 refxml->get_widget("tb_graphlist", tb_graphlist); 00093 refxml->get_widget("tb_controller", tb_controller); 00094 refxml->get_widget("tb_graphsave", tb_graphsave); 00095 refxml->get_widget("tb_graphopen", tb_graphopen); 00096 refxml->get_widget("tb_graphupd", tb_graphupd); 00097 refxml->get_widget("tb_graphrecord", tb_graphrecord); 00098 refxml->get_widget("tb_zoomin", tb_zoomin); 00099 refxml->get_widget("tb_zoomout", tb_zoomout); 00100 refxml->get_widget("tb_zoomfit", tb_zoomfit); 00101 refxml->get_widget("tb_zoomreset", tb_zoomreset); 00102 refxml->get_widget("tb_graphdir", tb_graphdir); 00103 refxml->get_widget("tb_graphcolored", tb_graphcolored); 00104 refxml->get_widget("mi_graphdir_title", mi_graphdir); 00105 refxml->get_widget("mi_top_bottom", mi_top_bottom); 00106 refxml->get_widget("mi_bottom_top", mi_bottom_top); 00107 refxml->get_widget("mi_left_right", mi_left_right); 00108 refxml->get_widget("mi_right_left", mi_right_left); 00109 00110 refxml->get_widget_derived("img_throbber", __throbber); 00111 refxml->get_widget_derived("trv_plugins", __trv_plugins); 00112 00113 Gtk::SeparatorToolItem *spacesep; 00114 refxml->get_widget("tb_spacesep", spacesep); 00115 spacesep->set_expand(); 00116 00117 Gtk::Label *mi_graphdir_label = dynamic_cast<Gtk::Label *>(mi_graphdir->get_child()); 00118 if ( mi_graphdir_label ) { 00119 mi_graphdir_label->set_markup("<b>Graph Direction</b>"); 00120 } 00121 mi_graphdir->set_sensitive(false); 00122 00123 // This should be in the Glade file, but is not restored for some reason 00124 tb_graphsave->set_homogeneous(false); 00125 tb_graphopen->set_homogeneous(false); 00126 tb_graphupd->set_homogeneous(false); 00127 tb_graphrecord->set_homogeneous(false); 00128 tb_zoomin->set_homogeneous(false); 00129 tb_zoomout->set_homogeneous(false); 00130 tb_zoomfit->set_homogeneous(false); 00131 tb_zoomreset->set_homogeneous(false); 00132 tb_graphdir->set_homogeneous(false); 00133 tb_graphcolored->set_homogeneous(false); 00134 00135 __sks_list = Gtk::ListStore::create(__sks_record); 00136 cbe_skillstring->set_model(__sks_list); 00137 cbe_skillstring->set_text_column(__sks_record.skillstring); 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 cb_graphlist->append_text(ACTIVE_SKILL); 00156 cb_graphlist->set_active_text(ACTIVE_SKILL); 00157 tb_graphlist->add(*cb_graphlist); 00158 cb_graphlist->show(); 00159 00160 //ntb_tabs->set_current_page(1); 00161 00162 connection_dispatcher.signal_connected().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_connect)); 00163 connection_dispatcher.signal_disconnected().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_disconnect)); 00164 00165 tb_connection->signal_clicked().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_connection_clicked)); 00166 but_exec->signal_clicked().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_exec_clicked)); 00167 tb_controller->signal_clicked().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_controller_clicked)); 00168 tb_exit->signal_clicked().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_exit_clicked)); 00169 but_stop->signal_clicked().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_stop_clicked)); 00170 but_continuous->signal_toggled().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_contexec_toggled)); 00171 but_clearlog->signal_clicked().connect(sigc::mem_fun(*__logview, &LogView::clear)); 00172 tb_skiller->signal_toggled().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_skdbg_data_changed)); 00173 tb_skiller->signal_toggled().connect(sigc::bind(sigc::mem_fun(*cb_graphlist, &Gtk::ComboBoxText::set_sensitive),true)); 00174 tb_agent->signal_toggled().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_agdbg_data_changed)); 00175 tb_agent->signal_toggled().connect(sigc::bind(sigc::mem_fun(*cb_graphlist, &Gtk::ComboBoxText::set_sensitive),false)); 00176 cb_graphlist->signal_changed().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_skill_changed)); 00177 tb_graphupd->signal_clicked().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_graphupd_clicked)); 00178 tb_graphdir->signal_clicked().connect(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_graphdir_clicked)); 00179 mi_top_bottom->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_graphdir_changed), SkillerDebugInterface::GD_TOP_BOTTOM)); 00180 mi_bottom_top->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_graphdir_changed), SkillerDebugInterface::GD_BOTTOM_TOP)); 00181 mi_left_right->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_graphdir_changed), SkillerDebugInterface::GD_LEFT_RIGHT)); 00182 mi_right_left->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SkillGuiGtkWindow::on_graphdir_changed), SkillerDebugInterface::GD_RIGHT_LEFT)); 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 row.get_value(cbe_skillstring->get_text_column(), sks); 00433 } 00434 00435 if ( sks != "" ) { 00436 __throbber->set_timeout(80); 00437 00438 if (__skiller_if && __skiller_if->is_valid() && __skiller_if->has_writer() && 00439 __skiller_if->exclusive_controller() == __skiller_if->serial()) { 00440 00441 if ( but_continuous->get_active() ) { 00442 SkillerInterface::ExecSkillContinuousMessage *escm = new SkillerInterface::ExecSkillContinuousMessage(sks.c_str()); 00443 __skiller_if->msgq_enqueue(escm); 00444 } else { 00445 SkillerInterface::ExecSkillMessage *esm = new SkillerInterface::ExecSkillMessage(sks.c_str()); 00446 __skiller_if->msgq_enqueue(esm); 00447 } 00448 00449 Gtk::TreeModel::Children children = __sks_list->children(); 00450 bool ok = true; 00451 if ( ! children.empty() ) { 00452 size_t num = 0; 00453 Gtk::TreeIter i = children.begin(); 00454 while (ok && (i != children.end())) { 00455 if ( num >= 9 ) { 00456 i = __sks_list->erase(i); 00457 } else { 00458 Gtk::TreeModel::Row row = *i; 00459 ok = (row[__sks_record.skillstring] != sks); 00460 ++num; 00461 ++i; 00462 } 00463 } 00464 } 00465 if (ok) { 00466 Gtk::TreeModel::Row row = *__sks_list->prepend(); 00467 row[__sks_record.skillstring] = sks; 00468 00469 std::list<Glib::ustring> l; 00470 for (Gtk::TreeIter i = children.begin(); i != children.end(); ++i) { 00471 Gtk::TreeModel::Row row = *i; 00472 l.push_back(row[__sks_record.skillstring]); 00473 } 00474 00475 #ifdef HAVE_GCONFMM 00476 __gconf->set_string_list(GCONF_PREFIX"/command_history", l); 00477 #endif 00478 } 00479 } else { 00480 Gtk::MessageDialog md(*this, "The exclusive control over the skiller has " 00481 "not been acquired yet and skills cannot be executed", 00482 /* markup */ false, 00483 Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, 00484 /* modal */ true); 00485 md.set_title("Skill Execution Failure"); 00486 md.run(); 00487 } 00488 } 00489 } 00490 00491 00492 void 00493 SkillGuiGtkWindow::on_skiller_data_changed() 00494 { 00495 try { 00496 __skiller_if->read(); 00497 00498 switch (__skiller_if->status()) { 00499 case SkillerInterface::S_INACTIVE: 00500 __throbber->stop_anim(); 00501 lab_status->set_text("S_INACTIVE"); 00502 break; 00503 case SkillerInterface::S_FINAL: 00504 __throbber->stop_anim(); 00505 __throbber->set_stock(Gtk::Stock::APPLY); 00506 lab_status->set_text("S_FINAL"); 00507 break; 00508 case SkillerInterface::S_RUNNING: 00509 __throbber->start_anim(); 00510 lab_status->set_text("S_RUNNING"); 00511 break; 00512 case SkillerInterface::S_FAILED: 00513 __throbber->stop_anim(); 00514 __throbber->set_stock(Gtk::Stock::DIALOG_WARNING); 00515 lab_status->set_text("S_FAILED"); 00516 break; 00517 } 00518 00519 lab_skillstring->set_text(__skiller_if->skill_string()); 00520 lab_error->set_text(__skiller_if->error()); 00521 #if GTKMM_MAJOR_VERSION > 2 || ( GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 12 ) 00522 lab_skillstring->set_tooltip_text(__skiller_if->skill_string()); 00523 lab_error->set_tooltip_text(__skiller_if->error()); 00524 #endif 00525 lab_continuous->set_text(__skiller_if->is_continuous() ? "Yes" : "No"); 00526 lab_alive->set_text(__skiller_if->has_writer() ? "Yes" : "No"); 00527 00528 if ( __skiller_if->exclusive_controller() == __skiller_if->serial() ) { 00529 if ( tb_controller->get_stock_id() == Gtk::Stock::NO.id ) { 00530 tb_controller->set_stock_id(Gtk::Stock::YES); 00531 #if GTKMM_MAJOR_VERSION > 2 || ( GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 12 ) 00532 tb_controller->set_tooltip_text("Release exclusive control"); 00533 #endif 00534 } 00535 but_exec->set_sensitive(true); 00536 but_stop->set_sensitive(true); 00537 } else { 00538 if ( tb_controller->get_stock_id() == Gtk::Stock::YES.id ) { 00539 tb_controller->set_stock_id(Gtk::Stock::NO); 00540 #if GTKMM_MAJOR_VERSION > 2 || ( GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 12 ) 00541 tb_controller->set_tooltip_text("Gain exclusive control"); 00542 #endif 00543 } 00544 but_exec->set_sensitive(false); 00545 but_stop->set_sensitive(false); 00546 } 00547 00548 00549 } catch (Exception &e) { 00550 __throbber->stop_anim(); 00551 } 00552 } 00553 00554 00555 void 00556 SkillGuiGtkWindow::on_skdbg_data_changed() 00557 { 00558 if (tb_skiller->get_active() && __skdbg_if) { 00559 try { 00560 __skdbg_if->read(); 00561 00562 if (strcmp(__skdbg_if->graph_fsm(), "LIST") == 0) { 00563 Glib::ustring list = __skdbg_if->graph(); 00564 cb_graphlist->clear_items(); 00565 cb_graphlist->append_text(ACTIVE_SKILL); 00566 cb_graphlist->set_active_text(ACTIVE_SKILL); 00567 #if GLIBMM_MAJOR_VERSION > 2 || ( GLIBMM_MAJOR_VERSION == 2 && GLIBMM_MINOR_VERSION >= 14 ) 00568 Glib::RefPtr<Glib::Regex> regex = Glib::Regex::create("\n"); 00569 std::list<std::string> skills = regex->split(list); 00570 for (std::list<std::string>::iterator i = skills.begin(); i != skills.end(); ++i) { 00571 if (*i != "") cb_graphlist->append_text(*i); 00572 } 00573 #endif 00574 if (__skdbg_if->has_writer()) { 00575 SkillerDebugInterface::SetGraphMessage *sgm = new SkillerDebugInterface::SetGraphMessage("ACTIVE"); 00576 __skdbg_if->msgq_enqueue(sgm); 00577 } 00578 } else { 00579 #ifdef USE_PAPYRUS 00580 pvp_graph->set_graph_fsm(__skdbg_if->graph_fsm()); 00581 pvp_graph->set_graph(__skdbg_if->graph()); 00582 pvp_graph->render(); 00583 #else 00584 gda->set_graph_fsm(__skdbg_if->graph_fsm()); 00585 gda->set_graph(__skdbg_if->graph()); 00586 #endif 00587 } 00588 00589 switch (__skdbg_if->graph_dir()) { 00590 case SkillerDebugInterface::GD_TOP_BOTTOM: 00591 tb_graphdir->set_stock_id(Gtk::Stock::GO_DOWN); break; 00592 case SkillerDebugInterface::GD_BOTTOM_TOP: 00593 tb_graphdir->set_stock_id(Gtk::Stock::GO_UP); break; 00594 case SkillerDebugInterface::GD_LEFT_RIGHT: 00595 tb_graphdir->set_stock_id(Gtk::Stock::GO_FORWARD); break; 00596 case SkillerDebugInterface::GD_RIGHT_LEFT: 00597 tb_graphdir->set_stock_id(Gtk::Stock::GO_BACK); break; 00598 } 00599 } catch (Exception &e) { 00600 // ignored 00601 } 00602 } 00603 } 00604 00605 00606 void 00607 SkillGuiGtkWindow::on_agdbg_data_changed() 00608 { 00609 if (tb_agent->get_active() && __agdbg_if) { 00610 try { 00611 __agdbg_if->read(); 00612 #ifdef USE_PAPYRUS 00613 pvp_graph->set_graph_fsm(__agdbg_if->graph_fsm()); 00614 pvp_graph->set_graph(__agdbg_if->graph()); 00615 pvp_graph->render(); 00616 #else 00617 gda->set_graph_fsm(__agdbg_if->graph_fsm()); 00618 gda->set_graph(__agdbg_if->graph()); 00619 #endif 00620 00621 switch (__agdbg_if->graph_dir()) { 00622 case SkillerDebugInterface::GD_TOP_BOTTOM: 00623 tb_graphdir->set_stock_id(Gtk::Stock::GO_DOWN); break; 00624 case SkillerDebugInterface::GD_BOTTOM_TOP: 00625 tb_graphdir->set_stock_id(Gtk::Stock::GO_UP); break; 00626 case SkillerDebugInterface::GD_LEFT_RIGHT: 00627 tb_graphdir->set_stock_id(Gtk::Stock::GO_FORWARD); break; 00628 case SkillerDebugInterface::GD_RIGHT_LEFT: 00629 tb_graphdir->set_stock_id(Gtk::Stock::GO_BACK); break; 00630 } 00631 } catch (Exception &e) { 00632 // ignored 00633 } 00634 } 00635 } 00636 00637 00638 void 00639 SkillGuiGtkWindow::on_graphupd_clicked() 00640 { 00641 #ifdef USE_PAPYRUS 00642 if ( pvp_graph->get_update_graph() ) { 00643 pvp_graph->set_update_graph(false); 00644 tb_graphupd->set_stock_id(Gtk::Stock::MEDIA_STOP); 00645 } else { 00646 pvp_graph->set_update_graph(true); 00647 tb_graphupd->set_stock_id(Gtk::Stock::MEDIA_PLAY); 00648 pvp_graph->render(); 00649 } 00650 #else 00651 if ( gda->get_update_graph() ) { 00652 gda->set_update_graph(false); 00653 tb_graphupd->set_stock_id(Gtk::Stock::MEDIA_STOP); 00654 } else { 00655 gda->set_update_graph(true); 00656 tb_graphupd->set_stock_id(Gtk::Stock::MEDIA_PLAY); 00657 } 00658 #endif 00659 } 00660 00661 00662 void 00663 SkillGuiGtkWindow::on_graphdir_clicked() 00664 { 00665 SkillerDebugInterface *iface = __skdbg_if; 00666 if (tb_agent->get_active()) { 00667 iface = __agdbg_if; 00668 } 00669 00670 Glib::ustring stockid = tb_graphdir->get_stock_id(); 00671 if (stockid == Gtk::Stock::GO_DOWN.id) { 00672 send_graphdir_message(iface, SkillerDebugInterface::GD_BOTTOM_TOP); 00673 } else if (stockid == Gtk::Stock::GO_UP.id) { 00674 send_graphdir_message(iface, SkillerDebugInterface::GD_LEFT_RIGHT); 00675 } else if (stockid == Gtk::Stock::GO_FORWARD.id) { 00676 send_graphdir_message(iface, SkillerDebugInterface::GD_RIGHT_LEFT); 00677 } else if (stockid == Gtk::Stock::GO_BACK.id) { 00678 send_graphdir_message(iface, SkillerDebugInterface::GD_TOP_BOTTOM); 00679 } 00680 } 00681 00682 void 00683 SkillGuiGtkWindow::send_graphdir_message(SkillerDebugInterface *iface, 00684 SkillerDebugInterface::GraphDirectionEnum gd) 00685 { 00686 try { 00687 if (iface) { 00688 SkillerDebugInterface::SetGraphDirectionMessage *m; 00689 m = new SkillerDebugInterface::SetGraphDirectionMessage(gd); 00690 iface->msgq_enqueue(m); 00691 } else { 00692 throw Exception("Not connected to Fawkes."); 00693 } 00694 } catch (Exception &e) { 00695 Gtk::MessageDialog md(*this, 00696 Glib::ustring("Setting graph direction failed: ") + e.what(), 00697 /* markup */ false, 00698 Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, 00699 /* modal */ true); 00700 md.set_title("Communication Failure"); 00701 md.run(); 00702 } 00703 } 00704 00705 void 00706 SkillGuiGtkWindow::on_graphdir_changed(SkillerDebugInterface::GraphDirectionEnum gd) 00707 { 00708 if (tb_agent->get_active()) { 00709 send_graphdir_message(__agdbg_if, gd); 00710 } else { 00711 send_graphdir_message(__skdbg_if, gd); 00712 } 00713 } 00714 00715 00716 void 00717 SkillGuiGtkWindow::on_graphcolor_toggled() 00718 { 00719 #ifdef HAVE_GCONFMM 00720 __gconf->set(GCONF_PREFIX"/graph_colored", tb_graphcolored->get_active()); 00721 #endif 00722 00723 SkillerDebugInterface *iface = __skdbg_if; 00724 if (tb_agent->get_active()) { 00725 iface = __agdbg_if; 00726 } 00727 00728 try { 00729 if (iface) { 00730 SkillerDebugInterface::SetGraphColoredMessage *m; 00731 m = new SkillerDebugInterface::SetGraphColoredMessage(tb_graphcolored->get_active()); 00732 iface->msgq_enqueue(m); 00733 } else { 00734 throw Exception("Not connected to Fawkes."); 00735 } 00736 } catch (Exception &e) { 00737 /* Ignore for now, causes error message on startup 00738 Gtk::MessageDialog md(*this, 00739 Glib::ustring("Setting graph color failed: ") + e.what(), 00740 / markup / false, 00741 Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, 00742 / modal / true); 00743 md.set_title("Communication Failure"); 00744 md.run(); 00745 */ 00746 } 00747 } 00748 00749 00750 SkillGuiGtkWindow::SkillStringRecord::SkillStringRecord() 00751 { 00752 add(skillstring); 00753 } 00754 00755 00756 void 00757 SkillGuiGtkWindow::on_update_disabled() 00758 { 00759 #ifdef USE_PAPYRUS 00760 #else 00761 tb_graphupd->set_stock_id(Gtk::Stock::MEDIA_STOP); 00762 #endif 00763 } 00764 00765 00766 void 00767 SkillGuiGtkWindow::on_recording_toggled() 00768 { 00769 #ifdef USE_PAPYRUS 00770 #else 00771 bool active = tb_graphrecord->get_active(); 00772 if (gda->set_recording(active) != active) { 00773 tb_graphrecord->set_active(!active); 00774 } 00775 #endif 00776 }