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::ComboBox 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::ComboBox 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 #if GTK_VERSION_GE(3,0) 00074 ServiceSelectorCBE::ServiceSelectorCBE( Gtk::ComboBox* services, 00075 #else 00076 ServiceSelectorCBE::ServiceSelectorCBE( Gtk::ComboBoxEntry* services, 00077 #endif 00078 Gtk::Button* connect, 00079 Gtk::Window* parent, 00080 const char* service ) 00081 { 00082 m_service_model = new ServiceModel(service); 00083 00084 m_cbe_services = services; 00085 m_btn_connect = connect; 00086 m_tbtn_connect = NULL; 00087 m_parent = parent; 00088 00089 initialize(); 00090 } 00091 00092 /** Construtor. 00093 * @param services the combo box to hold the list of services 00094 * @param connect the button to trigger the network connection 00095 * @param parent the parent window. Used for error dialogs. 00096 * @param service a service identifier 00097 */ 00098 #if GTK_VERSION_GE(3,0) 00099 ServiceSelectorCBE::ServiceSelectorCBE( Gtk::ComboBox* services, 00100 #else 00101 ServiceSelectorCBE::ServiceSelectorCBE( Gtk::ComboBoxEntry* services, 00102 #endif 00103 Gtk::ToolButton* connect, 00104 Gtk::Window* parent, 00105 const char* service ) 00106 { 00107 m_service_model = new ServiceModel(service); 00108 00109 m_cbe_services = services; 00110 m_btn_connect = NULL; 00111 m_tbtn_connect = connect; 00112 m_parent = parent; 00113 00114 initialize(); 00115 } 00116 00117 /** Constructor. 00118 * @param builder Gtk builder 00119 * @param cbe_name name of the combo box 00120 * @param btn_name name of the button 00121 * @param wnd_name name of the parent window 00122 * @param service service identifier 00123 */ 00124 ServiceSelectorCBE::ServiceSelectorCBE( Glib::RefPtr<Gtk::Builder> builder, 00125 const char* cbe_name, 00126 const char* btn_name, 00127 const char* wnd_name, 00128 const char* service ) 00129 { 00130 m_service_model = new ServiceModel(service); 00131 00132 builder->get_widget(wnd_name, m_parent); 00133 builder->get_widget(cbe_name, m_cbe_services); 00134 builder->get_widget(btn_name, m_btn_connect); 00135 00136 initialize(); 00137 } 00138 00139 /** Initializer method. */ 00140 void 00141 ServiceSelectorCBE::initialize() 00142 { 00143 #if GTK_VERSION_GE(3,0) 00144 if (! m_cbe_services->get_has_entry()) { 00145 throw Exception("Service combo box does not have an entry, fix UI file?"); 00146 } 00147 #endif 00148 m_cbe_services->set_model( m_service_model->get_list_store() ); 00149 #if GTK_VERSION_GE(3,0) 00150 m_cbe_services->set_entry_text_column(m_service_model->get_column_record().name); 00151 #else 00152 m_cbe_services->set_text_column(m_service_model->get_column_record().name); 00153 #endif 00154 m_cbe_services->get_entry()->set_activates_default(true); 00155 m_cbe_services->signal_changed().connect( sigc::mem_fun( *this, &ServiceSelectorCBE::on_service_selected) ); 00156 00157 Gtk::Entry *ent = static_cast<Gtk::Entry *>(m_cbe_services->get_child()); 00158 if (ent) 00159 { 00160 char * fawkes_ip = getenv("FAWKES_IP"); 00161 if (fawkes_ip) ent->set_text(fawkes_ip); 00162 else ent->set_text("localhost"); 00163 } 00164 00165 if ( m_btn_connect ) 00166 { 00167 m_btn_connect->signal_clicked().connect( sigc::mem_fun( *this, &ServiceSelectorCBE::on_btn_connect_clicked) ); 00168 m_btn_connect->set_label("gtk-connect"); 00169 m_btn_connect->set_use_stock(true); 00170 m_btn_connect->grab_default(); 00171 } 00172 else 00173 { 00174 m_tbtn_connect->signal_clicked().connect( sigc::mem_fun( *this, &ServiceSelectorCBE::on_btn_connect_clicked) ); 00175 m_tbtn_connect->set_stock_id( Gtk::StockID("gtk-connect") ); 00176 m_tbtn_connect->grab_default(); 00177 } 00178 00179 m_dispatcher = new ConnectionDispatcher(); 00180 m_dispatcher->signal_connected().connect(sigc::mem_fun(*this, &ServiceSelectorCBE::on_connected)); 00181 m_dispatcher->signal_disconnected().connect(sigc::mem_fun(*this, &ServiceSelectorCBE::on_disconnected)); 00182 00183 __hostname = ""; 00184 __port = 0; 00185 } 00186 00187 /** Destructor. */ 00188 ServiceSelectorCBE::~ServiceSelectorCBE() 00189 { 00190 delete m_dispatcher; 00191 delete m_service_model; 00192 } 00193 00194 /** Access the current network client. 00195 * @return the current network client 00196 */ 00197 FawkesNetworkClient* 00198 ServiceSelectorCBE::get_network_client() 00199 { 00200 return m_dispatcher->get_client(); 00201 } 00202 00203 /** 00204 * Returns the currently selected hostname (after connect) 00205 * @return the hostname 00206 */ 00207 Glib::ustring 00208 ServiceSelectorCBE::get_hostname() 00209 { 00210 return __hostname; 00211 } 00212 00213 /** 00214 * Returns the currently selected service name (after connect) 00215 * @return the service name 00216 */ 00217 Glib::ustring 00218 ServiceSelectorCBE::get_name() 00219 { 00220 return __servicename; 00221 } 00222 00223 /** 00224 * Returns the currently used port (after connect) 00225 * @return the port 00226 */ 00227 unsigned int 00228 ServiceSelectorCBE::get_port() 00229 { 00230 return __port; 00231 } 00232 00233 /** This signal is emitted whenever a network connection is established. 00234 * @return reference to the corresponding dispatcher 00235 */ 00236 sigc::signal<void> 00237 ServiceSelectorCBE::signal_connected() 00238 { 00239 return m_dispatcher->signal_connected(); 00240 } 00241 00242 /** This signal is emitted whenever a network connection is terminated. 00243 * @return reference to the corresponding dispatcher 00244 */ 00245 sigc::signal<void> 00246 ServiceSelectorCBE::signal_disconnected() 00247 { 00248 return m_dispatcher->signal_disconnected(); 00249 } 00250 00251 /** Signal handler that is called whenever the connect button is 00252 * clicked or an entry in the combo box is selected. 00253 */ 00254 void 00255 ServiceSelectorCBE::on_btn_connect_clicked() 00256 { 00257 FawkesNetworkClient *client = m_dispatcher->get_client(); 00258 00259 if (client->connected()) 00260 { 00261 client->disconnect(); 00262 if ( m_btn_connect ) 00263 { m_btn_connect->set_label("gtk-connect"); } 00264 else 00265 { m_tbtn_connect->set_label("gtk-connect"); } 00266 } 00267 else 00268 { 00269 if ( -1 == m_cbe_services->get_active_row_number() ) 00270 { 00271 Gtk::Entry* entry = m_cbe_services->get_entry(); 00272 __hostname = entry->get_text(); 00273 00274 Glib::ustring::size_type pos; 00275 if ((pos = __hostname.find(':')) != Glib::ustring::npos) 00276 { 00277 Glib::ustring host = ""; 00278 unsigned int port = 1234567; //Greater than max port num (i.e. 65535) 00279 std::istringstream is(__hostname.replace(pos, 1, " ")); 00280 is >> host; 00281 is >> port; 00282 00283 if (port != 1234567 && host.size()) 00284 { 00285 __hostname = host; 00286 __port = port; 00287 } 00288 } 00289 else __port = 1910; 00290 __servicename = __hostname; 00291 } 00292 else 00293 { 00294 Gtk::TreeModel::Row row = *m_cbe_services->get_active(); 00295 __hostname = row[m_service_model->get_column_record().hostname]; 00296 __servicename = row[m_service_model->get_column_record().name]; 00297 __port = row[m_service_model->get_column_record().port]; 00298 } 00299 00300 try 00301 { 00302 client->connect( __hostname.c_str(), __port ); 00303 } 00304 catch (Exception& e) 00305 { 00306 Glib::ustring message = *(e.begin()); 00307 Gtk::MessageDialog md(*m_parent, message, /* markup */ false, 00308 Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, 00309 /* modal */ true); 00310 md.set_title("Connection failed"); 00311 md.run(); 00312 } 00313 } 00314 } 00315 00316 /** Signal handler that is called whenever an entry is selected from 00317 * the combo box. 00318 */ 00319 void 00320 ServiceSelectorCBE::on_service_selected() 00321 { 00322 if ( -1 == m_cbe_services->get_active_row_number() ) return; 00323 00324 FawkesNetworkClient *client = m_dispatcher->get_client(); 00325 if ( client->connected() ) 00326 { 00327 client->disconnect(); 00328 } 00329 00330 Gtk::TreeModel::Row row = *m_cbe_services->get_active(); 00331 __hostname = row[m_service_model->get_column_record().hostname]; 00332 __servicename = row[m_service_model->get_column_record().name]; 00333 __port = row[m_service_model->get_column_record().port]; 00334 00335 m_cbe_services->get_entry()->set_text(__hostname); 00336 00337 try 00338 { 00339 client->connect( __hostname.c_str(), __port ); 00340 } 00341 catch (Exception& e) 00342 { 00343 Glib::ustring message = *(e.begin()); 00344 Gtk::MessageDialog md(*m_parent, message, /* markup */ false, 00345 Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, 00346 /* modal */ true); 00347 md.set_title("Connection failed"); 00348 md.run(); 00349 } 00350 } 00351 00352 /** Signal handler for the connection established signal. */ 00353 void 00354 ServiceSelectorCBE::on_connected() 00355 { 00356 if ( m_btn_connect ) 00357 { m_btn_connect->set_label("gtk-disconnect"); } 00358 else 00359 { m_tbtn_connect->set_stock_id( Gtk::StockID("gtk-disconnect") ); } 00360 } 00361 00362 /** Signal handler for the connection terminated signal. */ 00363 void 00364 ServiceSelectorCBE::on_disconnected() 00365 { 00366 if ( m_btn_connect ) 00367 { m_btn_connect->set_label("gtk-connect"); } 00368 else 00369 { m_tbtn_connect->set_stock_id( Gtk::StockID("gtk-connect") ); } 00370 }