netloggui.cpp

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 }

Generated on 1 Mar 2011 for Fawkes API by  doxygen 1.6.1