Fawkes API Fawkes Development Version
service_selector_cbe.cpp
1
2/***************************************************************************
3 * service_selector_cbe.cpp - Manages list of discovered services of given type
4 *
5 * Created: Mon Sep 29 17:46:44 2008
6 * Copyright 2008 Daniel Beck
7 * 2008 Tim Niemueller [www.niemueller.de]
8 *
9 ****************************************************************************/
10
11/* This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version. A runtime exception applies to
15 * this software (see LICENSE.GPL_WRE file mentioned below for details).
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Library General Public License for more details.
21 *
22 * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
23 */
24
25#include <gui_utils/connection_dispatcher.h>
26#include <gui_utils/service_model.h>
27#include <gui_utils/service_selector_cbe.h>
28#include <netcomm/fawkes/client.h>
29
30#include <sstream>
31
32using namespace fawkes;
33
34/** @class fawkes::ServiceSelectorCBE gui_utils/service_selector_cbe.h
35 * This widget consists of a Gtk::ComboBox and a Gtk::Button. The
36 * combo box contains all detected services of a given type; upon
37 * click the button opens a network connection to the selected service.
38 *
39 * @author Daniel Beck
40 * @author Tim Niemueller
41 */
42
43/** @var fawkes::ServiceSelectorCBE::m_cbe_services
44 * A Gtk::ComboBox that lists all available services.
45 */
46
47/** @var fawkes::ServiceSelectorCBE::m_btn_connect
48 * A Gtk::Button that triggers the connection.
49 */
50
51/** @var fawkes::ServiceSelectorCBE::m_tbtn_connect
52 * A Gtk::ToolButton that triggers the connection.
53 */
54
55/** @var fawkes::ServiceSelectorCBE::m_parent
56 * The parent Gtk::Window.
57 */
58
59/** @var fawkes::ServiceSelectorCBE::m_service_model
60 * A liststore which contains information about detected services.
61 */
62
63/** @var fawkes::ServiceSelectorCBE::m_dispatcher
64 * A ConnectionDispatcher which dispatches connection signals.
65 */
66
67/** Construtor.
68 * @param services the combo box to hold the list of services
69 * @param connect the button to trigger the network connection
70 * @param parent the parent window. Used for error dialogs.
71 * @param service a service identifier
72 */
73#if GTK_VERSION_GE(3, 0)
74ServiceSelectorCBE::ServiceSelectorCBE(Gtk::ComboBox *services,
75#else
76ServiceSelectorCBE::ServiceSelectorCBE(Gtk::ComboBoxEntry *services,
77#endif
78 Gtk::Button *connect,
79 Gtk::Window *parent,
80 const char * service)
81{
82 m_service_model = new ServiceModel(service);
83
84 m_cbe_services = services;
85 m_btn_connect = connect;
86 m_tbtn_connect = NULL;
87 m_parent = parent;
88
89 initialize();
90}
91
92/** Construtor.
93 * @param services the combo box to hold the list of services
94 * @param connect the button to trigger the network connection
95 * @param parent the parent window. Used for error dialogs.
96 * @param service a service identifier
97 */
98#if GTK_VERSION_GE(3, 0)
99ServiceSelectorCBE::ServiceSelectorCBE(Gtk::ComboBox *services,
100#else
101ServiceSelectorCBE::ServiceSelectorCBE(Gtk::ComboBoxEntry *services,
102#endif
103 Gtk::ToolButton *connect,
104 Gtk::Window * parent,
105 const char * service)
106{
107 m_service_model = new ServiceModel(service);
108
109 m_cbe_services = services;
110 m_btn_connect = NULL;
111 m_tbtn_connect = connect;
112 m_parent = parent;
113
114 initialize();
115}
116
117/** Constructor.
118 * @param builder Gtk builder
119 * @param cbe_name name of the combo box
120 * @param btn_name name of the button
121 * @param wnd_name name of the parent window
122 * @param service service identifier
123 */
124ServiceSelectorCBE::ServiceSelectorCBE(Glib::RefPtr<Gtk::Builder> builder,
125 const char * cbe_name,
126 const char * btn_name,
127 const char * wnd_name,
128 const char * service)
129{
130 m_service_model = new ServiceModel(service);
131
132 builder->get_widget(wnd_name, m_parent);
133 builder->get_widget(cbe_name, m_cbe_services);
134 builder->get_widget(btn_name, m_btn_connect);
135
136 initialize();
137}
138
139/** Initializer method. */
140void
142{
143#if GTK_VERSION_GE(3, 0)
144 if (!m_cbe_services->get_has_entry()) {
145 throw Exception("Service combo box does not have an entry, fix UI file?");
146 }
147#endif
149#if GTK_VERSION_GE(3, 0)
150 m_cbe_services->set_entry_text_column(m_service_model->get_column_record().name);
151#else
153#endif
154 m_cbe_services->get_entry()->set_activates_default(true);
155 m_cbe_services->signal_changed().connect(
156 sigc::mem_fun(*this, &ServiceSelectorCBE::on_service_selected));
157
158 Gtk::Entry *ent = static_cast<Gtk::Entry *>(m_cbe_services->get_child());
159 if (ent) {
160 char *fawkes_ip = getenv("FAWKES_IP");
161 if (fawkes_ip)
162 ent->set_text(fawkes_ip);
163 else
164 ent->set_text("localhost");
165 }
166
167 if (m_btn_connect) {
168 m_btn_connect->signal_clicked().connect(
169 sigc::mem_fun(*this, &ServiceSelectorCBE::on_btn_connect_clicked));
170 m_btn_connect->set_label("gtk-connect");
171 m_btn_connect->set_use_stock(true);
172 m_btn_connect->grab_default();
173 } else {
174 m_tbtn_connect->signal_clicked().connect(
175 sigc::mem_fun(*this, &ServiceSelectorCBE::on_btn_connect_clicked));
176 m_tbtn_connect->set_stock_id(Gtk::StockID("gtk-connect"));
177 m_tbtn_connect->grab_default();
178 }
179
181 m_dispatcher->signal_connected().connect(sigc::mem_fun(*this, &ServiceSelectorCBE::on_connected));
183 sigc::mem_fun(*this, &ServiceSelectorCBE::on_disconnected));
184
185 hostname_ = "";
186 port_ = 0;
187}
188
189/** Destructor. */
191{
192 delete m_dispatcher;
193 delete m_service_model;
194}
195
196/** Access the current network client.
197 * @return the current network client
198 */
201{
202 return m_dispatcher->get_client();
203}
204
205/**
206 * Returns the currently selected hostname (after connect)
207 * @return the hostname
208 */
209Glib::ustring
211{
212 return hostname_;
213}
214
215/**
216 * Returns the currently selected service name (after connect)
217 * @return the service name
218 */
219Glib::ustring
221{
222 return servicename_;
223}
224
225/**
226 * Returns the currently used port (after connect)
227 * @return the port
228 */
229unsigned int
231{
232 return port_;
233}
234
235/** This signal is emitted whenever a network connection is established.
236 * @return reference to the corresponding dispatcher
237 */
238sigc::signal<void>
240{
242}
243
244/** This signal is emitted whenever a network connection is terminated.
245 * @return reference to the corresponding dispatcher
246 */
247sigc::signal<void>
249{
251}
252
253/** Signal handler that is called whenever the connect button is
254 * clicked or an entry in the combo box is selected.
255 */
256void
258{
260
261 if (client->connected()) {
262 client->disconnect();
263 if (m_btn_connect) {
264 m_btn_connect->set_label("gtk-connect");
265 } else {
266 m_tbtn_connect->set_label("gtk-connect");
267 }
268 } else {
269 if (-1 == m_cbe_services->get_active_row_number()) {
270 Gtk::Entry *entry = m_cbe_services->get_entry();
271 hostname_ = entry->get_text();
272
273 Glib::ustring::size_type pos;
274 if ((pos = hostname_.find(':')) != Glib::ustring::npos) {
275 Glib::ustring host = "";
276 unsigned int port = 1234567; //Greater than max port num (i.e. 65535)
277 std::istringstream is(hostname_.replace(pos, 1, " "));
278 is >> host;
279 is >> port;
280
281 if (port != 1234567 && host.size()) {
282 hostname_ = host;
283 port_ = port;
284 }
285 } else
286 port_ = 1910;
287 servicename_ = hostname_;
288 } else {
289 Gtk::TreeModel::Row row = *m_cbe_services->get_active();
290 hostname_ = row[m_service_model->get_column_record().hostname];
291 servicename_ = row[m_service_model->get_column_record().name];
292 port_ = row[m_service_model->get_column_record().port];
293 }
294
295 try {
296 client->connect(hostname_.c_str(), port_);
297 } catch (Exception &e) {
298 Glib::ustring message = *(e.begin());
299 Gtk::MessageDialog md(*m_parent,
300 message,
301 /* markup */ false,
302 Gtk::MESSAGE_ERROR,
303 Gtk::BUTTONS_OK,
304 /* modal */ true);
305 md.set_title("Connection failed");
306 md.run();
307 }
308 }
309}
310
311/** Signal handler that is called whenever an entry is selected from
312 * the combo box.
313 */
314void
316{
317 if (-1 == m_cbe_services->get_active_row_number())
318 return;
319
321 if (client->connected()) {
322 client->disconnect();
323 }
324
325 Gtk::TreeModel::Row row = *m_cbe_services->get_active();
326 hostname_ = row[m_service_model->get_column_record().hostname];
327 servicename_ = row[m_service_model->get_column_record().name];
328 port_ = row[m_service_model->get_column_record().port];
329
330 m_cbe_services->get_entry()->set_text(hostname_);
331
332 try {
333 client->connect(hostname_.c_str(), port_);
334 } catch (Exception &e) {
335 Glib::ustring message = *(e.begin());
336 Gtk::MessageDialog md(*m_parent,
337 message,
338 /* markup */ false,
339 Gtk::MESSAGE_ERROR,
340 Gtk::BUTTONS_OK,
341 /* modal */ true);
342 md.set_title("Connection failed");
343 md.run();
344 }
345}
346
347/** Signal handler for the connection established signal. */
348void
350{
351 if (m_btn_connect) {
352 m_btn_connect->set_label("gtk-disconnect");
353 } else {
354 m_tbtn_connect->set_stock_id(Gtk::StockID("gtk-disconnect"));
355 }
356}
357
358/** Signal handler for the connection terminated signal. */
359void
361{
362 if (m_btn_connect) {
363 m_btn_connect->set_label("gtk-connect");
364 } else {
365 m_tbtn_connect->set_stock_id(Gtk::StockID("gtk-connect"));
366 }
367}
Watches network client events and dispatches them as signals.
sigc::signal< void > signal_connected()
Get "connected" signal.
FawkesNetworkClient * get_client()
Get client.
sigc::signal< void > signal_disconnected()
Get "disconnected" signal.
Base class for exceptions in Fawkes.
Definition: exception.h:36
iterator begin() noexcept
Get iterator for messages.
Definition: exception.cpp:676
Simple Fawkes network client.
Definition: client.h:52
void connect()
Connect to remote.
Definition: client.cpp:424
void disconnect()
Disconnect socket.
Definition: client.cpp:539
bool connected() const noexcept
Check if connection is alive.
Definition: client.cpp:828
Gtk::TreeModelColumn< unsigned short > port
The port the service is running on.
Definition: service_model.h:69
Gtk::TreeModelColumn< Glib::ustring > name
The name of the service.
Definition: service_model.h:60
Gtk::TreeModelColumn< Glib::ustring > hostname
The name of the host the service is running on.
Definition: service_model.h:64
Abstract base class for widgets that allow to view the detected services of a certain type.
Definition: service_model.h:36
ServiceRecord & get_column_record()
Access the column record.
Glib::RefPtr< Gtk::ListStore > & get_list_store()
Get a reference to the model.
void on_btn_connect_clicked()
Signal handler that is called whenever the connect button is clicked or an entry in the combo box is ...
void initialize()
Initializer method.
Glib::ustring get_name()
Returns the currently selected service name (after connect)
void on_disconnected()
Signal handler for the connection terminated signal.
Gtk::Window * m_parent
The parent Gtk::Window.
void on_connected()
Signal handler for the connection established signal.
Gtk::ToolButton * m_tbtn_connect
A Gtk::ToolButton that triggers the connection.
Gtk::Button * m_btn_connect
A Gtk::Button that triggers the connection.
unsigned int get_port()
Returns the currently used port (after connect)
sigc::signal< void > signal_connected()
This signal is emitted whenever a network connection is established.
ServiceModel * m_service_model
A liststore which contains information about detected services.
Gtk::ComboBoxEntry * m_cbe_services
A Gtk::ComboBox that lists all available services.
ConnectionDispatcher * m_dispatcher
A ConnectionDispatcher which dispatches connection signals.
void on_service_selected()
Signal handler that is called whenever an entry is selected from the combo box.
FawkesNetworkClient * get_network_client()
Access the current network client.
sigc::signal< void > signal_disconnected()
This signal is emitted whenever a network connection is terminated.
Glib::ustring get_hostname()
Returns the currently selected hostname (after connect)
virtual ~ServiceSelectorCBE()
Destructor.
Fawkes library namespace.