Fawkes API  Fawkes Development Version
netloggui.cpp
1 
2 /***************************************************************************
3  * netloggui.cpp - NetLog GUI
4  *
5  * Created: Wed Nov 05 11:03:56 2008
6  * Copyright 2008 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Library General Public License for more details.
19  *
20  * Read the full text in the LICENSE.GPL file in the doc directory.
21  */
22 
23 #include "netloggui.h"
24 
25 #include <gui_utils/avahi_dispatcher.h>
26 #include <gui_utils/connection_dispatcher.h>
27 #include <gui_utils/logview.h>
28 #include <gui_utils/service_chooser_dialog.h>
29 #include <netcomm/dns-sd/avahi_thread.h>
30 #include <netcomm/fawkes/client.h>
31 #include <netinet/in.h>
32 
33 using namespace fawkes;
34 
35 /** @class NetLogGuiGtkWindow "netloggui.h"
36  * NetLog GUI main window.
37  * The NetLog GUI provides shows log viewers for Fawkes instances on the
38  * network.
39  * @author Tim Niemueller
40  */
41 
42 /** Constructor.
43  * @param cobject C base object
44  * @param builder Gtk builder
45  */
46 NetLogGuiGtkWindow::NetLogGuiGtkWindow(BaseObjectType * cobject,
47  const Glib::RefPtr<Gtk::Builder> &builder)
48 : Gtk::Window(cobject)
49 {
50  builder->get_widget("vbox_main", vbox_main);
51  builder->get_widget("lab_no_connection", lab_no_connection);
52  builder->get_widget("tb_connection", tb_connection);
53  builder->get_widget("tb_exit", tb_exit);
54  builder->get_widget("tb_clear", tb_clear);
55 
56  vbox_main->pack_end(ntb_logviewers);
57 
58  avahi_dispatcher = new AvahiDispatcher();
59  avahi_dispatcher->signal_service_added().connect(
60  sigc::retype_return<void>(sigc::mem_fun(*this, &NetLogGuiGtkWindow::on_service_added)));
61  avahi_dispatcher->signal_service_removed().connect(
62  sigc::mem_fun(*this, &NetLogGuiGtkWindow::on_service_removed));
63 
64  avahi_thread = new AvahiThread();
65  avahi_thread->start();
66  avahi_thread->watch_service("_fawkes._tcp", avahi_dispatcher);
67 
68  tb_connection->signal_clicked().connect(
69  sigc::mem_fun(*this, &NetLogGuiGtkWindow::on_connection_clicked));
70  tb_exit->signal_clicked().connect(sigc::mem_fun(*this, &NetLogGuiGtkWindow::on_exit_clicked));
71  tb_clear->signal_clicked().connect(sigc::mem_fun(*this, &NetLogGuiGtkWindow::on_clear_clicked));
72 }
73 
74 /** Destructor. */
76 {
77  avahi_thread->cancel();
78  avahi_thread->join();
79  delete avahi_dispatcher;
80  delete avahi_thread;
81 }
82 
83 /** Event handler for connection button. */
84 void
85 NetLogGuiGtkWindow::on_connection_clicked()
86 {
87  ServiceChooserDialog ssd(*this);
88  if (ssd.run()) {
89  int page = -1;
90 
91  try {
92  Glib::ustring name, hostname;
93  std::list<std::string> txt;
94  unsigned short int port = 1910;
95  struct sockaddr_in saddr;
96  socklen_t saddr_size = sizeof(struct sockaddr_in);
97  ssd.get_selected_service(name, hostname, port);
98  ssd.get_raw_address((struct sockaddr *)&saddr, saddr_size);
99  NetworkService *service = new NetworkService(name.c_str(),
100  "_fawkes._tcp",
101  "",
102  hostname.c_str(),
103  port,
104  (struct sockaddr *)&saddr,
105  saddr_size,
106  txt);
107  page = on_service_added(service);
108  delete service;
109 
110  if (page >= 0) {
111  Gtk::ScrolledWindow *scrolled =
112  dynamic_cast<Gtk::ScrolledWindow *>(ntb_logviewers.get_nth_page(page));
113  LogView *logview = dynamic_cast<LogView *>(scrolled->get_child());
114  logview->get_client()->connect(hostname.c_str(), port);
115  }
116  } catch (Exception &e) {
117  Glib::ustring message = *(e.begin());
118  Gtk::MessageDialog md(*this,
119  message,
120  /* markup */ false,
121  Gtk::MESSAGE_ERROR,
122  Gtk::BUTTONS_OK,
123  /* modal */ true);
124  md.set_title("Connection failed");
125  md.run();
126 
127  ntb_logviewers.remove_page(page);
128  }
129  }
130 }
131 
132 void
133 NetLogGuiGtkWindow::on_exit_clicked()
134 {
135  Gtk::Main::quit();
136 }
137 
138 void
139 NetLogGuiGtkWindow::on_clear_clicked()
140 {
141  int page = ntb_logviewers.get_current_page();
142  if (page >= 0) {
143  Gtk::ScrolledWindow *scrolled =
144  dynamic_cast<Gtk::ScrolledWindow *>(ntb_logviewers.get_nth_page(page));
145  LogView *lv = dynamic_cast<LogView *>(scrolled->get_child());
146  lv->clear();
147  }
148 }
149 
150 int
151 NetLogGuiGtkWindow::on_service_added(fawkes::NetworkService *service)
152 {
153  if (ntb_logviewers.get_n_pages() == 0) {
154  lab_no_connection->hide();
155  //Gtk::Container *thiscon = this;
156  //thiscon->remove(lab_no_connection);
157  //add(ntb_logviewers);
158  ntb_logviewers.show();
159  }
160 
161  Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));
162  Gtk::Button *button = Gtk::manage(new Gtk::Button());
163  Gtk::Image * image = Gtk::manage(new Gtk::Image(Gtk::Stock::CONNECT, Gtk::ICON_SIZE_BUTTON));
164  button->add(*image);
165  button->set_relief(Gtk::RELIEF_NONE);
166  Gtk::Label *label = Gtk::manage(new Gtk::Label());
167  label->set_markup(Glib::ustring("<b>") + service->host() + "</b>\n" + service->addr_string());
168  label->set_line_wrap();
169  Gtk::Label * invisible = Gtk::manage(new Gtk::Label(
170  Glib::ustring(service->name()) + "::" + service->type() + "::" + service->domain()));
171  Gtk::ScrolledWindow *scrolled = Gtk::manage(new Gtk::ScrolledWindow());
172  scrolled->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
173  LogView *logview = Gtk::manage(new LogView(service->addr_string().c_str(), service->port()));
174  //scrolled->add(*logview);
175 
176  hbox->pack_start(*button);
177  hbox->pack_start(*label);
178  hbox->pack_start(*invisible);
179 
180  button->signal_clicked().connect(
181  sigc::bind(sigc::mem_fun(*this, &NetLogGuiGtkWindow::on_connbut_clicked), image, logview));
182  logview->get_connection_dispatcher()->signal_connected().connect(
183  sigc::bind(sigc::mem_fun(*this, &NetLogGuiGtkWindow::on_connected), image));
184  logview->get_connection_dispatcher()->signal_disconnected().connect(
185  sigc::bind(sigc::mem_fun(*this, &NetLogGuiGtkWindow::on_disconnected), image));
186 
187  scrolled->show();
188  label->show();
189  image->show();
190  button->show();
191  logview->show();
192  hbox->show();
193 
194  int rv = ntb_logviewers.append_page(*logview, *hbox);
195 
196  return rv;
197 }
198 
199 void
200 NetLogGuiGtkWindow::on_service_removed(fawkes::NetworkService *service)
201 {
202  bool removed = false;
203  do {
204  removed = false;
205 
206  for (int i = 0; !removed && (i < ntb_logviewers.get_n_pages()); ++i) {
207  Gtk::Widget *child = ntb_logviewers.get_nth_page(i);
208  Gtk::Widget *tab_label = ntb_logviewers.get_tab_label(*child);
209  Gtk::HBox * hbox = dynamic_cast<Gtk::HBox *>(tab_label);
210 
211  if (hbox) {
212  std::vector<Gtk::Widget *> children = hbox->get_children();
213  Gtk::Widget * w = children[2];
214  if (w) {
215  Gtk::Label *label = dynamic_cast<Gtk::Label *>(w);
216  if (label) {
217  Glib::ustring s =
218  Glib::ustring(service->name()) + "::" + service->type() + "::" + service->domain();
219  if (label->get_text() == s) {
220  ntb_logviewers.remove_page(i);
221  removed = true;
222  }
223  }
224  }
225  }
226  }
227  } while (removed);
228 
229  if (ntb_logviewers.get_n_pages() == 0) {
230  ntb_logviewers.hide();
231  //Gtk::Container *thiscon = this;
232  //thiscon->remove(ntb_logviewers);
233  //add(lab_no_connection);
234  lab_no_connection->show();
235  }
236 }
237 
238 void
239 NetLogGuiGtkWindow::on_connbut_clicked(Gtk::Image *image, fawkes::LogView *logview)
240 {
241  FawkesNetworkClient *client = logview->get_client();
242  if (client->connected()) {
243  client->disconnect();
244  } else {
245  try {
246  client->connect();
247  } catch (Exception &e) {
248  Glib::ustring message = *(e.begin());
249  Gtk::MessageDialog md(*this,
250  message,
251  /* markup */ false,
252  Gtk::MESSAGE_ERROR,
253  Gtk::BUTTONS_OK,
254  /* modal */ true);
255  md.set_title("Connection failed");
256  md.run();
257  }
258  }
259 }
260 
261 void
262 NetLogGuiGtkWindow::on_connected(Gtk::Image *image)
263 {
264  image->set(Gtk::Stock::DISCONNECT, Gtk::ICON_SIZE_BUTTON);
265 }
266 
267 void
268 NetLogGuiGtkWindow::on_disconnected(Gtk::Image *image)
269 {
270  image->set(Gtk::Stock::CONNECT, Gtk::ICON_SIZE_BUTTON);
271 }
Log View widget.
Definition: logview.h:37
sigc::signal< void > signal_disconnected()
Get "disconnected" signal.
sigc::signal< void > signal_connected()
Get "connected" signal.
ConnectionDispatcher * get_connection_dispatcher() const
Get ConnectionDispatcher instance that is used internally.
Definition: logview.cpp:178
Simple Fawkes network client.
Definition: client.h:51
void clear()
Clear all records.
Definition: logview.cpp:185
FawkesNetworkClient * get_client()
Get the used FawkesNetworkClient.
Definition: logview.cpp:169
Fawkes library namespace.
void disconnect()
Disconnect socket.
Definition: client.cpp:539
const char * host() const
Get host of service.
Definition: service.cpp:401
void connect()
Connect to remote.
Definition: client.cpp:424
std::string addr_string() const
Get IP address of entry as string.
Definition: service.cpp:420
unsigned short int port() const
Get port of service.
Definition: service.cpp:410
sigc::signal< void, NetworkService * > signal_service_removed()
Get "service remove" signal.
Base class for exceptions in Fawkes.
Definition: exception.h:35
~NetLogGuiGtkWindow()
Destructor.
Definition: netloggui.cpp:75
void watch_service(const char *service_type, ServiceBrowseHandler *h)
Add a result handler.
iterator begin()
Get iterator for messages.
Definition: exception.cpp:676
Avahi main thread.
Definition: avahi_thread.h:53
Representation of a service announced or found via service discovery (i.e.
Definition: service.h:37
void cancel()
Cancel a thread.
Definition: thread.cpp:646
const char * domain() const
Get domain of service.
Definition: service.cpp:392
void join()
Join the thread.
Definition: thread.cpp:597
bool connected() const
Check if connection is alive.
Definition: client.cpp:828
sigc::signal< void, NetworkService * > signal_service_added()
Get "service added" signal.
const char * type() const
Get type of service.
Definition: service.cpp:383
NetLogGuiGtkWindow(BaseObjectType *cobject, const Glib::RefPtr< Gtk::Builder > &builder)
Constructor.
Definition: netloggui.cpp:46
void start(bool wait=true)
Call this method to start the thread.
Definition: thread.cpp:499
const char * name() const
Get name of service.
Definition: service.cpp:349