service_selector_cbe.cpp

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 }

Generated on Tue Feb 22 13:32:27 2011 for Fawkes API by  doxygen 1.4.7