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
33using 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 */
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. */
84void
85NetLogGuiGtkWindow::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
132void
133NetLogGuiGtkWindow::on_exit_clicked()
134{
135 Gtk::Main::quit();
136}
137
138void
139NetLogGuiGtkWindow::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
150int
151NetLogGuiGtkWindow::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));
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
199void
200NetLogGuiGtkWindow::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
238void
239NetLogGuiGtkWindow::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
261void
262NetLogGuiGtkWindow::on_connected(Gtk::Image *image)
263{
264 image->set(Gtk::Stock::DISCONNECT, Gtk::ICON_SIZE_BUTTON);
265}
266
267void
268NetLogGuiGtkWindow::on_disconnected(Gtk::Image *image)
269{
270 image->set(Gtk::Stock::CONNECT, Gtk::ICON_SIZE_BUTTON);
271}
~NetLogGuiGtkWindow()
Destructor.
Definition: netloggui.cpp:75
NetLogGuiGtkWindow(BaseObjectType *cobject, const Glib::RefPtr< Gtk::Builder > &builder)
Constructor.
Definition: netloggui.cpp:46
sigc::signal< void, NetworkService * > signal_service_removed()
Get "service remove" signal.
sigc::signal< void, NetworkService * > signal_service_added()
Get "service added" signal.
Avahi main thread.
Definition: avahi_thread.h:55
void watch_service(const char *service_type, ServiceBrowseHandler *h)
Add a result handler.
sigc::signal< void > signal_connected()
Get "connected" signal.
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
Log View widget.
Definition: logview.h:38
void clear()
Clear all records.
Definition: logview.cpp:185
ConnectionDispatcher * get_connection_dispatcher() const
Get ConnectionDispatcher instance that is used internally.
Definition: logview.cpp:178
FawkesNetworkClient * get_client()
Get the used FawkesNetworkClient.
Definition: logview.cpp:169
Representation of a service announced or found via service discovery (i.e.
Definition: service.h:38
std::string addr_string() const
Get IP address of entry as string.
Definition: service.cpp:420
const char * type() const
Get type of service.
Definition: service.cpp:383
unsigned short int port() const
Get port of service.
Definition: service.cpp:410
const char * name() const
Get name of service.
Definition: service.cpp:349
const char * host() const
Get host of service.
Definition: service.cpp:401
const char * domain() const
Get domain of service.
Definition: service.cpp:392
void start(bool wait=true)
Call this method to start the thread.
Definition: thread.cpp:499
void join()
Join the thread.
Definition: thread.cpp:597
void cancel()
Cancel a thread.
Definition: thread.cpp:646
Fawkes library namespace.