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 refxml Glade XML 00047 */ 00048 NetLogGuiGtkWindow::NetLogGuiGtkWindow(BaseObjectType* cobject, 00049 const Glib::RefPtr<Gnome::Glade::Xml> &refxml) 00050 : Gtk::Window(cobject) 00051 { 00052 refxml->get_widget("vbox_main", vbox_main); 00053 refxml->get_widget("lab_no_connection", lab_no_connection); 00054 refxml->get_widget("tb_connection", tb_connection); 00055 refxml->get_widget("tb_exit", tb_exit); 00056 refxml->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 = Gtk::manage(new LogView(service->addr_string().c_str(), service->port())); 00168 scrolled->add(*logview); 00169 00170 hbox->pack_start(*button); 00171 hbox->pack_start(*label); 00172 hbox->pack_start(*invisible); 00173 00174 button->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &NetLogGuiGtkWindow::on_connbut_clicked), image, logview)); 00175 logview->get_connection_dispatcher()->signal_connected().connect(sigc::bind(sigc::mem_fun(*this, &NetLogGuiGtkWindow::on_connected), image)); 00176 logview->get_connection_dispatcher()->signal_disconnected().connect(sigc::bind(sigc::mem_fun(*this, &NetLogGuiGtkWindow::on_disconnected), image)); 00177 00178 scrolled->show(); 00179 label->show(); 00180 image->show(); 00181 button->show(); 00182 logview->show(); 00183 hbox->show(); 00184 00185 int rv = ntb_logviewers.append_page(*scrolled, *hbox); 00186 00187 return rv; 00188 } 00189 00190 00191 void 00192 NetLogGuiGtkWindow::on_service_removed(fawkes::NetworkService *service) 00193 { 00194 bool removed = false; 00195 do { 00196 removed = false; 00197 00198 for (int i = 0; ! removed && (i < ntb_logviewers.get_n_pages()); ++i) { 00199 Gtk::Widget *child = ntb_logviewers.get_nth_page(i); 00200 Gtk::Widget *tab_label = ntb_logviewers.get_tab_label(*child); 00201 Gtk::HBox *hbox = dynamic_cast<Gtk::HBox *>(tab_label); 00202 00203 if ( hbox ) { 00204 Gtk::Box_Helpers::BoxList b = hbox->children(); 00205 Gtk::Widget *w = b[2].get_widget(); 00206 if (w) { 00207 Gtk::Label *label = dynamic_cast<Gtk::Label *>(w); 00208 if ( label ) { 00209 Glib::ustring s = Glib::ustring(service->name()) + "::" + service->type() + "::" + service->domain(); 00210 if (label->get_text() == s) { 00211 ntb_logviewers.remove_page(i); 00212 removed = true; 00213 } 00214 } 00215 } 00216 } 00217 } 00218 } while (removed); 00219 00220 if ( ntb_logviewers.get_n_pages() == 0 ) { 00221 ntb_logviewers.hide(); 00222 //Gtk::Container *thiscon = this; 00223 //thiscon->remove(ntb_logviewers); 00224 //add(lab_no_connection); 00225 lab_no_connection->show(); 00226 } 00227 } 00228 00229 00230 void 00231 NetLogGuiGtkWindow::on_connbut_clicked(Gtk::Image *image, fawkes::LogView *logview) 00232 { 00233 FawkesNetworkClient *client = logview->get_client(); 00234 if ( client->connected() ) { 00235 client->disconnect(); 00236 } else { 00237 try { 00238 client->connect(); 00239 } catch (Exception &e) { 00240 Glib::ustring message = *(e.begin()); 00241 Gtk::MessageDialog md(*this, message, /* markup */ false, 00242 Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, 00243 /* modal */ true); 00244 md.set_title("Connection failed"); 00245 md.run(); 00246 } 00247 } 00248 } 00249 00250 00251 void 00252 NetLogGuiGtkWindow::on_connected(Gtk::Image *image) 00253 { 00254 image->set(Gtk::Stock::DISCONNECT, Gtk::ICON_SIZE_BUTTON); 00255 } 00256 00257 00258 void 00259 NetLogGuiGtkWindow::on_disconnected(Gtk::Image *image) 00260 { 00261 image->set(Gtk::Stock::CONNECT, Gtk::ICON_SIZE_BUTTON); 00262 }