Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * netloggui.cpp - NetLog GUI 00004 * 00005 * Created: Wed Nov 05 11:03:56 2008 00006 * Copyright 2008 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. 00014 * 00015 * This program is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU Library General Public License for more details. 00019 * 00020 * Read the full text in the LICENSE.GPL file in the doc directory. 00021 */ 00022 00023 #include "netloggui.h" 00024 00025 #include <gui_utils/logview.h> 00026 #include <gui_utils/avahi_dispatcher.h> 00027 #include <gui_utils/connection_dispatcher.h> 00028 #include <gui_utils/service_chooser_dialog.h> 00029 #include <netcomm/fawkes/client.h> 00030 #include <netcomm/dns-sd/avahi_thread.h> 00031 00032 #include <netinet/in.h> 00033 00034 using namespace fawkes; 00035 00036 00037 /** @class NetLogGuiGtkWindow "netloggui.h" 00038 * NetLog GUI main window. 00039 * The NetLog GUI provides shows log viewers for Fawkes instances on the 00040 * network. 00041 * @author Tim Niemueller 00042 */ 00043 00044 /** Constructor. 00045 * @param cobject C base object 00046 * @param builder Gtk builder 00047 */ 00048 NetLogGuiGtkWindow::NetLogGuiGtkWindow(BaseObjectType* cobject, 00049 const Glib::RefPtr<Gtk::Builder> &builder) 00050 : Gtk::Window(cobject) 00051 { 00052 builder->get_widget("vbox_main", vbox_main); 00053 builder->get_widget("lab_no_connection", lab_no_connection); 00054 builder->get_widget("tb_connection", tb_connection); 00055 builder->get_widget("tb_exit", tb_exit); 00056 builder->get_widget("tb_clear", tb_clear); 00057 00058 vbox_main->pack_end(ntb_logviewers); 00059 00060 avahi_dispatcher = new AvahiDispatcher(); 00061 avahi_dispatcher->signal_service_added().connect(sigc::retype_return<void>(sigc::mem_fun(*this, &NetLogGuiGtkWindow::on_service_added))); 00062 avahi_dispatcher->signal_service_removed().connect(sigc::mem_fun(*this, &NetLogGuiGtkWindow::on_service_removed)); 00063 00064 avahi_thread = new AvahiThread(); 00065 avahi_thread->start(); 00066 avahi_thread->watch_service("_fawkes._tcp", avahi_dispatcher); 00067 00068 tb_connection->signal_clicked().connect(sigc::mem_fun(*this, &NetLogGuiGtkWindow::on_connection_clicked)); 00069 tb_exit->signal_clicked().connect(sigc::mem_fun(*this, &NetLogGuiGtkWindow::on_exit_clicked)); 00070 tb_clear->signal_clicked().connect(sigc::mem_fun(*this, &NetLogGuiGtkWindow::on_clear_clicked)); 00071 } 00072 00073 00074 /** Destructor. */ 00075 NetLogGuiGtkWindow::~NetLogGuiGtkWindow() 00076 { 00077 avahi_thread->cancel(); 00078 avahi_thread->join(); 00079 delete avahi_dispatcher; 00080 delete avahi_thread; 00081 } 00082 00083 00084 /** Event handler for connection button. */ 00085 void 00086 NetLogGuiGtkWindow::on_connection_clicked() 00087 { 00088 ServiceChooserDialog ssd(*this); 00089 if (ssd.run() ) { 00090 struct sockaddr_in saddr; 00091 socklen_t saddr_size = sizeof(struct sockaddr_in); 00092 Glib::ustring name, hostname, ipaddr; 00093 unsigned short int port = 1910; 00094 std::list<std::string> txt; 00095 int page = -1; 00096 00097 try { 00098 ssd.get_selected_service (name, hostname, ipaddr, port); 00099 ssd.get_raw_address((struct sockaddr *)&saddr, saddr_size); 00100 NetworkService *service = new NetworkService(name.c_str(), "_fawkes._tcp", "", 00101 hostname.c_str(), port, 00102 (struct sockaddr *)&saddr, 00103 saddr_size, txt); 00104 page = on_service_added(service); 00105 delete service; 00106 00107 if ( page >= 0 ) { 00108 Gtk::ScrolledWindow *scrolled = dynamic_cast<Gtk::ScrolledWindow *>(ntb_logviewers.get_nth_page(page)); 00109 LogView *logview = dynamic_cast<LogView *>(scrolled->get_child()); 00110 logview->get_client()->connect(ipaddr.c_str(), port); 00111 } 00112 } catch (Exception &e) { 00113 Glib::ustring message = *(e.begin()); 00114 Gtk::MessageDialog md(*this, message, /* markup */ false, 00115 Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, 00116 /* modal */ true); 00117 md.set_title("Connection failed"); 00118 md.run(); 00119 00120 ntb_logviewers.remove_page(page); 00121 } 00122 } 00123 } 00124 00125 00126 void 00127 NetLogGuiGtkWindow::on_exit_clicked() 00128 { 00129 Gtk::Main::quit(); 00130 } 00131 00132 00133 void 00134 NetLogGuiGtkWindow::on_clear_clicked() 00135 { 00136 int page = ntb_logviewers.get_current_page(); 00137 if (page >= 0) { 00138 Gtk::ScrolledWindow *scrolled = dynamic_cast<Gtk::ScrolledWindow *>(ntb_logviewers.get_nth_page(page)); 00139 LogView *lv = dynamic_cast<LogView *>(scrolled->get_child()); 00140 lv->clear(); 00141 } 00142 } 00143 00144 00145 int 00146 NetLogGuiGtkWindow::on_service_added(fawkes::NetworkService *service) 00147 { 00148 if ( ntb_logviewers.get_n_pages() == 0 ) { 00149 lab_no_connection->hide(); 00150 //Gtk::Container *thiscon = this; 00151 //thiscon->remove(lab_no_connection); 00152 //add(ntb_logviewers); 00153 ntb_logviewers.show(); 00154 } 00155 00156 Gtk::HBox *hbox = Gtk::manage(new Gtk::HBox(false, 4)); 00157 Gtk::Button *button = Gtk::manage(new Gtk::Button()); 00158 Gtk::Image *image = Gtk::manage(new Gtk::Image(Gtk::Stock::CONNECT, Gtk::ICON_SIZE_BUTTON)); 00159 button->add(*image); 00160 button->set_relief(Gtk::RELIEF_NONE); 00161 Gtk::Label *label = Gtk::manage(new Gtk::Label()); 00162 label->set_markup(Glib::ustring("<b>") + service->host() + "</b>\n" + service->addr_string()); 00163 label->set_line_wrap(); 00164 Gtk::Label *invisible = Gtk::manage(new Gtk::Label(Glib::ustring(service->name()) + "::" + service->type() + "::" + service->domain())); 00165 Gtk::ScrolledWindow *scrolled = Gtk::manage(new Gtk::ScrolledWindow()); 00166 scrolled->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); 00167 LogView *logview = 00168 Gtk::manage(new LogView(service->addr_string().c_str(), service->port())); 00169 //scrolled->add(*logview); 00170 00171 hbox->pack_start(*button); 00172 hbox->pack_start(*label); 00173 hbox->pack_start(*invisible); 00174 00175 button->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &NetLogGuiGtkWindow::on_connbut_clicked), image, logview)); 00176 logview->get_connection_dispatcher()->signal_connected().connect(sigc::bind(sigc::mem_fun(*this, &NetLogGuiGtkWindow::on_connected), image)); 00177 logview->get_connection_dispatcher()->signal_disconnected().connect(sigc::bind(sigc::mem_fun(*this, &NetLogGuiGtkWindow::on_disconnected), image)); 00178 00179 scrolled->show(); 00180 label->show(); 00181 image->show(); 00182 button->show(); 00183 logview->show(); 00184 hbox->show(); 00185 00186 int rv = ntb_logviewers.append_page(*logview, *hbox); 00187 00188 return rv; 00189 } 00190 00191 00192 void 00193 NetLogGuiGtkWindow::on_service_removed(fawkes::NetworkService *service) 00194 { 00195 bool removed = false; 00196 do { 00197 removed = false; 00198 00199 for (int i = 0; ! removed && (i < ntb_logviewers.get_n_pages()); ++i) { 00200 Gtk::Widget *child = ntb_logviewers.get_nth_page(i); 00201 Gtk::Widget *tab_label = ntb_logviewers.get_tab_label(*child); 00202 Gtk::HBox *hbox = dynamic_cast<Gtk::HBox *>(tab_label); 00203 00204 if ( hbox ) { 00205 std::vector<Gtk::Widget *> children = hbox->get_children(); 00206 Gtk::Widget *w = children[2]; 00207 if (w) { 00208 Gtk::Label *label = dynamic_cast<Gtk::Label *>(w); 00209 if ( label ) { 00210 Glib::ustring s = Glib::ustring(service->name()) + "::" + service->type() + "::" + service->domain(); 00211 if (label->get_text() == s) { 00212 ntb_logviewers.remove_page(i); 00213 removed = true; 00214 } 00215 } 00216 } 00217 } 00218 } 00219 } while (removed); 00220 00221 if ( ntb_logviewers.get_n_pages() == 0 ) { 00222 ntb_logviewers.hide(); 00223 //Gtk::Container *thiscon = this; 00224 //thiscon->remove(ntb_logviewers); 00225 //add(lab_no_connection); 00226 lab_no_connection->show(); 00227 } 00228 } 00229 00230 00231 void 00232 NetLogGuiGtkWindow::on_connbut_clicked(Gtk::Image *image, fawkes::LogView *logview) 00233 { 00234 FawkesNetworkClient *client = logview->get_client(); 00235 if ( client->connected() ) { 00236 client->disconnect(); 00237 } else { 00238 try { 00239 client->connect(); 00240 } catch (Exception &e) { 00241 Glib::ustring message = *(e.begin()); 00242 Gtk::MessageDialog md(*this, message, /* markup */ false, 00243 Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, 00244 /* modal */ true); 00245 md.set_title("Connection failed"); 00246 md.run(); 00247 } 00248 } 00249 } 00250 00251 00252 void 00253 NetLogGuiGtkWindow::on_connected(Gtk::Image *image) 00254 { 00255 image->set(Gtk::Stock::DISCONNECT, Gtk::ICON_SIZE_BUTTON); 00256 } 00257 00258 00259 void 00260 NetLogGuiGtkWindow::on_disconnected(Gtk::Image *image) 00261 { 00262 image->set(Gtk::Stock::CONNECT, Gtk::ICON_SIZE_BUTTON); 00263 }