Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * service_selector_cbe.cpp - Manages list of discovered services of given type 00004 * 00005 * Created: Mon Sep 29 17:46:44 2008 00006 * Copyright 2008 Daniel Beck 00007 * 2008 Tim Niemueller [www.niemueller.de] 00008 * 00009 ****************************************************************************/ 00010 00011 /* This program is free software; you can redistribute it and/or modify 00012 * it under the terms of the GNU General Public License as published by 00013 * the Free Software Foundation; either version 2 of the License, or 00014 * (at your option) any later version. A runtime exception applies to 00015 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00016 * 00017 * This program is distributed in the hope that it will be useful, 00018 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 * GNU Library General Public License for more details. 00021 * 00022 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00023 */ 00024 00025 #include <gui_utils/service_selector_cbe.h> 00026 #include <gui_utils/service_model.h> 00027 #include <gui_utils/connection_dispatcher.h> 00028 #include <netcomm/fawkes/client.h> 00029 00030 #include <sstream> 00031 00032 using namespace fawkes; 00033 00034 /** @class fawkes::ServiceSelectorCBE gui_utils/service_selector_cbe.h 00035 * This widget consists of a Gtk::ComboBoxEntry and a Gtk::Button. The 00036 * combo box contains all detected services of a given type; upon 00037 * click the button opens a network connection to the selected service. 00038 * 00039 * @author Daniel Beck 00040 * @author Tim Niemueller 00041 */ 00042 00043 /** @var fawkes::ServiceSelectorCBE::m_cbe_services 00044 * A Gtk::ComboBoxEntry that lists all available services. 00045 */ 00046 00047 /** @var fawkes::ServiceSelectorCBE::m_btn_connect 00048 * A Gtk::Button that triggers the connection. 00049 */ 00050 00051 /** @var fawkes::ServiceSelectorCBE::m_tbtn_connect 00052 * A Gtk::ToolButton that triggers the connection. 00053 */ 00054 00055 /** @var fawkes::ServiceSelectorCBE::m_parent 00056 * The parent Gtk::Window. 00057 */ 00058 00059 /** @var fawkes::ServiceSelectorCBE::m_service_model 00060 * A liststore which contains information about detected services. 00061 */ 00062 00063 /** @var fawkes::ServiceSelectorCBE::m_dispatcher 00064 * A ConnectionDispatcher which dispatches connection signals. 00065 */ 00066 00067 /** Construtor. 00068 * @param services the combo box to hold the list of services 00069 * @param connect the button to trigger the network connection 00070 * @param parent the parent window. Used for error dialogs. 00071 * @param service a service identifier 00072 */ 00073 ServiceSelectorCBE::ServiceSelectorCBE( Gtk::ComboBoxEntry* services, 00074 Gtk::Button* connect, 00075 Gtk::Window* parent, 00076 const char* service ) 00077 { 00078 m_service_model = new ServiceModel(service); 00079 00080 m_cbe_services = services; 00081 m_btn_connect = connect; 00082 m_tbtn_connect = NULL; 00083 m_parent = parent; 00084 00085 initialize(); 00086 } 00087 00088 /** Construtor. 00089 * @param services the combo box to hold the list of services 00090 * @param connect the button to trigger the network connection 00091 * @param parent the parent window. Used for error dialogs. 00092 * @param service a service identifier 00093 */ 00094 ServiceSelectorCBE::ServiceSelectorCBE( Gtk::ComboBoxEntry* services, 00095 Gtk::ToolButton* connect, 00096 Gtk::Window* parent, 00097 const char* service ) 00098 { 00099 m_service_model = new ServiceModel(service); 00100 00101 m_cbe_services = services; 00102 m_btn_connect = NULL; 00103 m_tbtn_connect = connect; 00104 m_parent = parent; 00105 00106 initialize(); 00107 } 00108 00109 #ifdef HAVE_GLADEMM 00110 /** Constructor. 00111 * @param ref_xml Glade XML file 00112 * @param cbe_name name of the combo box 00113 * @param btn_name name of the button 00114 * @param wnd_name name of the parent window 00115 * @param service service identifier 00116 */ 00117 ServiceSelectorCBE::ServiceSelectorCBE( Glib::RefPtr<Gnome::Glade::Xml> ref_xml, 00118 const char* cbe_name, 00119 const char* btn_name, 00120 const char* wnd_name, 00121 const char* service ) 00122 { 00123 m_service_model = new ServiceModel(service); 00124 00125 ref_xml->get_widget(wnd_name, m_parent); 00126 ref_xml->get_widget(cbe_name, m_cbe_services); 00127 ref_xml->get_widget(btn_name, m_btn_connect); 00128 00129 initialize(); 00130 } 00131 #endif 00132 00133 /** Initializer method. */ 00134 void 00135 ServiceSelectorCBE::initialize() 00136 { 00137 m_cbe_services->set_model( m_service_model->get_list_store() ); 00138 m_cbe_services->set_text_column(m_service_model->get_column_record().name); 00139 m_cbe_services->get_entry()->set_activates_default(true); 00140 m_cbe_services->signal_changed().connect( sigc::mem_fun( *this, &ServiceSelectorCBE::on_service_selected) ); 00141 00142 Gtk::Entry *ent = static_cast<Gtk::Entry *>(m_cbe_services->get_child()); 00143 if (ent) 00144 { 00145 char * fawkes_ip = getenv("FAWKES_IP"); 00146 if (fawkes_ip) ent->set_text(fawkes_ip); 00147 else ent->set_text("localhost"); 00148 } 00149 00150 if ( m_btn_connect ) 00151 { 00152 m_btn_connect->signal_clicked().connect( sigc::mem_fun( *this, &ServiceSelectorCBE::on_btn_connect_clicked) ); 00153 m_btn_connect->set_label("gtk-connect"); 00154 m_btn_connect->set_use_stock(true); 00155 m_btn_connect->grab_default(); 00156 } 00157 else 00158 { 00159 m_tbtn_connect->signal_clicked().connect( sigc::mem_fun( *this, &ServiceSelectorCBE::on_btn_connect_clicked) ); 00160 m_tbtn_connect->set_stock_id( Gtk::StockID("gtk-connect") ); 00161 m_tbtn_connect->grab_default(); 00162 } 00163 00164 m_dispatcher = new ConnectionDispatcher(); 00165 m_dispatcher->signal_connected().connect(sigc::mem_fun(*this, &ServiceSelectorCBE::on_connected)); 00166 m_dispatcher->signal_disconnected().connect(sigc::mem_fun(*this, &ServiceSelectorCBE::on_disconnected)); 00167 00168 __hostname = ""; 00169 __port = 0; 00170 } 00171 00172 /** Destructor. */ 00173 ServiceSelectorCBE::~ServiceSelectorCBE() 00174 { 00175 delete m_dispatcher; 00176 delete m_service_model; 00177 } 00178 00179 /** Access the current network client. 00180 * @return the current network client 00181 */ 00182 FawkesNetworkClient* 00183 ServiceSelectorCBE::get_network_client() 00184 { 00185 return m_dispatcher->get_client(); 00186 } 00187 00188 /** 00189 * Returns the currently selected hostname (after connect) 00190 * @return the hostname 00191 */ 00192 Glib::ustring 00193 ServiceSelectorCBE::get_hostname() 00194 { 00195 return __hostname; 00196 } 00197 00198 /** 00199 * Returns the currently selected service name (after connect) 00200 * @return the service name 00201 */ 00202 Glib::ustring 00203 ServiceSelectorCBE::get_name() 00204 { 00205 return __servicename; 00206 } 00207 00208 /** 00209 * Returns the currently used port (after connect) 00210 * @return the port 00211 */ 00212 unsigned int 00213 ServiceSelectorCBE::get_port() 00214 { 00215 return __port; 00216 } 00217 00218 /** This signal is emitted whenever a network connection is established. 00219 * @return reference to the corresponding dispatcher 00220 */ 00221 sigc::signal<void> 00222 ServiceSelectorCBE::signal_connected() 00223 { 00224 return m_dispatcher->signal_connected(); 00225 } 00226 00227 /** This signal is emitted whenever a network connection is terminated. 00228 * @return reference to the corresponding dispatcher 00229 */ 00230 sigc::signal<void> 00231 ServiceSelectorCBE::signal_disconnected() 00232 { 00233 return m_dispatcher->signal_disconnected(); 00234 } 00235 00236 /** Signal handler that is called whenever the connect button is 00237 * clicked or an entry in the combo box is selected. 00238 */ 00239 void 00240 ServiceSelectorCBE::on_btn_connect_clicked() 00241 { 00242 FawkesNetworkClient *client = m_dispatcher->get_client(); 00243 00244 if (client->connected()) 00245 { 00246 client->disconnect(); 00247 if ( m_btn_connect ) 00248 { m_btn_connect->set_label("gtk-connect"); } 00249 else 00250 { m_tbtn_connect->set_label("gtk-connect"); } 00251 } 00252 else 00253 { 00254 if ( -1 == m_cbe_services->get_active_row_number() ) 00255 { 00256 Gtk::Entry* entry = m_cbe_services->get_entry(); 00257 __hostname = entry->get_text(); 00258 00259 Glib::ustring::size_type pos; 00260 if ((pos = __hostname.find(':')) != Glib::ustring::npos) 00261 { 00262 Glib::ustring host = ""; 00263 unsigned int port = 1234567; //Greater than max port num (i.e. 65535) 00264 std::istringstream is(__hostname.replace(pos, 1, " ")); 00265 is >> host; 00266 is >> port; 00267 00268 if (port != 1234567 && host.size()) 00269 { 00270 __hostname = host; 00271 __port = port; 00272 } 00273 } 00274 else __port = 1910; 00275 __servicename = __hostname; 00276 } 00277 else 00278 { 00279 Gtk::TreeModel::Row row = *m_cbe_services->get_active(); 00280 __hostname = row[m_service_model->get_column_record().hostname]; 00281 __servicename = row[m_service_model->get_column_record().name]; 00282 __port = row[m_service_model->get_column_record().port]; 00283 } 00284 00285 try 00286 { 00287 client->connect( __hostname.c_str(), __port ); 00288 } 00289 catch (Exception& e) 00290 { 00291 Glib::ustring message = *(e.begin()); 00292 Gtk::MessageDialog md(*m_parent, message, /* markup */ false, 00293 Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, 00294 /* modal */ true); 00295 md.set_title("Connection failed"); 00296 md.run(); 00297 } 00298 } 00299 } 00300 00301 /** Signal handler that is called whenever an entry is selected from 00302 * the combo box. 00303 */ 00304 void 00305 ServiceSelectorCBE::on_service_selected() 00306 { 00307 if ( -1 == m_cbe_services->get_active_row_number() ) return; 00308 00309 FawkesNetworkClient *client = m_dispatcher->get_client(); 00310 if ( client->connected() ) 00311 { 00312 client->disconnect(); 00313 } 00314 00315 Gtk::TreeModel::Row row = *m_cbe_services->get_active(); 00316 __hostname = row[m_service_model->get_column_record().hostname]; 00317 __servicename = row[m_service_model->get_column_record().name]; 00318 __port = row[m_service_model->get_column_record().port]; 00319 00320 m_cbe_services->get_entry()->set_text(__hostname); 00321 00322 try 00323 { 00324 client->connect( __hostname.c_str(), __port ); 00325 } 00326 catch (Exception& e) 00327 { 00328 Glib::ustring message = *(e.begin()); 00329 Gtk::MessageDialog md(*m_parent, message, /* markup */ false, 00330 Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, 00331 /* modal */ true); 00332 md.set_title("Connection failed"); 00333 md.run(); 00334 } 00335 } 00336 00337 /** Signal handler for the connection established signal. */ 00338 void 00339 ServiceSelectorCBE::on_connected() 00340 { 00341 if ( m_btn_connect ) 00342 { m_btn_connect->set_label("gtk-disconnect"); } 00343 else 00344 { m_tbtn_connect->set_stock_id( Gtk::StockID("gtk-disconnect") ); } 00345 } 00346 00347 /** Signal handler for the connection terminated signal. */ 00348 void 00349 ServiceSelectorCBE::on_disconnected() 00350 { 00351 if ( m_btn_connect ) 00352 { m_btn_connect->set_label("gtk-connect"); } 00353 else 00354 { m_tbtn_connect->set_stock_id( Gtk::StockID("gtk-connect") ); } 00355 }