Fawkes API Fawkes Development Version

firestation.cpp

00001 
00002 /***************************************************************************
00003  *  firestation.cpp - Firestation
00004  *
00005  *  Created: Wed Oct 10 14:19:30 2007
00006  *  Copyright  2007-2008  Daniel Beck
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 "firestation.h"
00024 #include "mirror_calib.h"
00025 #include "color_train_widget.h"
00026 #include "fuse_transfer_widget.h"
00027 
00028 #include <fvwidgets/fuse_image_list_widget.h>
00029 #include <gui_utils/avahi_dispatcher.h>
00030 
00031 #include <cams/fileloader.h>
00032 #include <cams/shmem.h>
00033 #include <cams/net.h>
00034 
00035 #include <fvutils/ipc/shm_image.h>
00036 #include <fvutils/color/conversions.h>
00037 #include <fvutils/color/yuv.h>
00038 #include <fvutils/colormap/yuvcm.h>
00039 #include <fvutils/scalers/lossy.h>
00040 #include <fvutils/system/camargp.h>
00041 #include <fvutils/writers/jpeg.h>
00042 #include <fvutils/writers/fvraw.h>
00043 #include <fvutils/draw/drawer.h>
00044 
00045 #include <core/exception.h>
00046 
00047 #include <gdkmm/pixbuf.h>
00048 
00049 #include <arpa/inet.h>
00050 
00051 #include <iostream>
00052 
00053 using namespace std;
00054 using namespace fawkes;
00055 using namespace firevision;
00056 
00057 /** @class Firestation "firestation.h"
00058  * Control GUI for vision related stuff.
00059  * @author Daniel Beck
00060  */
00061 
00062 /** Constructor.
00063  * @param ref_xml reference pointer to the glade file
00064  */
00065 Firestation::Firestation(Glib::RefPtr<Gnome::Glade::Xml> ref_xml)
00066 {
00067   // --- main window ------------------------------------------------
00068   m_wnd_main = dynamic_cast<Gtk::Window*>( get_widget(ref_xml, "wndMain") );
00069 
00070   m_img_image = dynamic_cast<Gtk::Image*>( get_widget(ref_xml, "imgImage") );
00071   m_img_image->signal_size_allocate().connect( sigc::mem_fun(*this, &Firestation::resize_image) );
00072 
00073   m_evt_image = dynamic_cast<Gtk::EventBox*>( get_widget(ref_xml, "evtImageEventBox") );
00074   m_evt_image->signal_button_press_event().connect( sigc::mem_fun(*this, &Firestation::image_click) );
00075 
00076   m_trv_shm_image_ids = dynamic_cast<Gtk::TreeView*>( get_widget(ref_xml, "trvShmImageIds") );
00077 
00078   m_stb_status = dynamic_cast<Gtk::Statusbar*>( get_widget(ref_xml, "stbStatus") );
00079 
00080   m_ckb_cont_trans = dynamic_cast<Gtk::CheckButton*>( get_widget(ref_xml, "ckbContTrans") );
00081   m_ckb_cont_trans->signal_toggled().connect( sigc::mem_fun(*this, &Firestation::enable_cont_img_trans) );
00082 
00083   m_spb_update_time = dynamic_cast<Gtk::SpinButton*>( get_widget(ref_xml, "spbUpdateTime") );
00084   // ----------------------------------------------------------------
00085 
00086 
00087   // --- toolbar widgets --------------------------------------------
00088   m_tbtn_exit = dynamic_cast<Gtk::ToolButton*>( get_widget(ref_xml, "tbtnExit") );
00089   m_tbtn_exit->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::exit) );
00090 
00091   m_tbtn_close_camera = dynamic_cast<Gtk::ToolButton*>( get_widget(ref_xml, "tbtnCloseCamera") );
00092   m_tbtn_close_camera->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::close_camera) );
00093 
00094   m_tbtn_update = dynamic_cast<Gtk::ToolButton*>( get_widget(ref_xml, "tbtnUpdate") );
00095   m_tbtn_update->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::update_image) );
00096 
00097   m_tbtn_save = dynamic_cast<Gtk::ToolButton*>( get_widget(ref_xml, "tbtnSave") );
00098   m_tbtn_save->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::save_image) );
00099 
00100   m_tbtn_open_file = dynamic_cast<Gtk::ToolButton*>( get_widget(ref_xml, "tbtnOpenFile") );
00101   m_tbtn_open_file->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::open_file) );
00102 
00103   m_tbtn_open_folder = dynamic_cast<Gtk::ToolButton*>( get_widget(ref_xml, "tbtnOpenFolder") );
00104   m_tbtn_open_folder->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::open_folder) );
00105 
00106   m_tbtn_open_shm = dynamic_cast<Gtk::ToolButton*>( get_widget(ref_xml, "tbtnOpenShm") );
00107   m_tbtn_open_shm->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::open_shm) );
00108 
00109   m_tbtn_open_fuse = dynamic_cast<Gtk::ToolButton*>( get_widget(ref_xml, "tbtnOpenFuse") );
00110   m_tbtn_open_fuse->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::open_fuse) );
00111   // ----------------------------------------------------------------
00112 
00113 
00114   // --- dialogs ----------------------------------------------------
00115   ref_xml->get_widget("fcdOpenImage", m_fcd_open_image);
00116   if ( !m_fcd_open_image )
00117     {
00118       throw std::runtime_error("Couldn't find fcdOpenImage.");
00119     }
00120 
00121   Gtk::FileFilter* filter_jpg = new Gtk::FileFilter();
00122   filter_jpg->set_name("JPEG");
00123   filter_jpg->add_pattern("*.jpg");
00124   filter_jpg->add_pattern("*.jpeg");
00125   m_fcd_open_image->add_filter(*filter_jpg);
00126 
00127   Gtk::FileFilter* filter_fvraw = new Gtk::FileFilter();
00128   filter_fvraw->set_name("FVRaw");
00129   filter_fvraw->add_pattern("*.raw");
00130   filter_fvraw->add_pattern("*.fvraw");
00131   m_fcd_open_image->add_filter(*filter_fvraw);
00132 
00133   ref_xml->get_widget("fcdSaveImage", m_fcd_save_image);
00134   if ( !m_fcd_save_image )
00135     {
00136       throw std::runtime_error("Couldn't find fcdSaveImage.");
00137     }
00138   m_fcd_save_image->add_filter(*filter_jpg);
00139   m_fcd_save_image->add_filter(*filter_fvraw);
00140 
00141   ref_xml->get_widget("dlgOpenShm", m_dlg_open_shm);
00142   if (!m_dlg_open_shm)
00143     {
00144       throw std::runtime_error("Couldn't find dlgOpenShm.");
00145     }
00146 
00147   ref_xml->get_widget("trvShmImageIds", m_trv_shm_image_ids);
00148   if ( !m_trv_shm_image_ids )
00149     {
00150       throw std::runtime_error("Couldn't find trvShmImageIds.");
00151     }
00152   m_shm_list_store = Gtk::ListStore::create(m_shm_columns);
00153   m_trv_shm_image_ids->set_model(m_shm_list_store);
00154   m_trv_shm_image_ids->append_column("#", m_shm_columns.m_id);
00155   m_trv_shm_image_ids->append_column("Name", m_shm_columns.m_name);
00156 
00157 
00158   ref_xml->get_widget("dlgOpenFuse", m_dlg_open_fuse);
00159   if (!m_dlg_open_fuse)
00160     {
00161       throw std::runtime_error("Couldn't find dlgOpenFuse.");
00162     }
00163 
00164   ref_xml->get_widget("ckbFuseJpeg", m_ckb_fuse_jpeg);
00165   if (! m_ckb_fuse_jpeg )
00166     {
00167       throw std::runtime_error("Couldn't find ckbFuseJpeg.");
00168     }
00169 
00170   ref_xml->get_widget("trvFuseServices", m_trv_fuse_services);
00171   if ( !m_trv_fuse_services )
00172     {
00173       throw std::runtime_error("Couldn't find trvFuseServices.");
00174     }
00175   m_fuse_tree_store = Gtk::TreeStore::create(m_fuse_columns);
00176   m_trv_fuse_services->set_model(m_fuse_tree_store);
00177   //  m_trv_fuse_services->append_column("#", m_fuse_columns.m_id);
00178   m_trv_fuse_services->append_column("Name", m_fuse_columns.m_name);
00179   // ----------------------------------------------------------------
00180 
00181 
00182   // --- color train widget -----------------------------------------
00183   m_ctw = new ColorTrainWidget(this);
00184   m_cmb_ct_type  = dynamic_cast<Gtk::ComboBox*>( get_widget(ref_xml, "cmbCtObjectType") );
00185   m_cmb_ct_type->signal_changed().connect(sigc::mem_fun(*this, &Firestation::ct_object_changed));
00186   m_cmb_ct_type->set_active(0);
00187 
00188   m_btn_ct_start = dynamic_cast<Gtk::ToggleButton*>( get_widget(ref_xml, "btnCtStart") );
00189   m_btn_ct_start->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::ct_start) );
00190 
00191   m_ctw->update_image().connect( sigc::mem_fun(*this, &Firestation::draw_image) );
00192   m_ctw->colormap_updated().connect( sigc::mem_fun(*this, &Firestation::on_colormap_updated) );
00193 
00194   Gtk::Button* btn;
00195   btn = dynamic_cast<Gtk::Button*>( get_widget(ref_xml, "btnCtUnselect") );
00196   m_ctw->set_reset_selection_btn(btn);
00197 
00198   btn = dynamic_cast<Gtk::Button*>( get_widget(ref_xml, "btnCtAdd") );
00199   m_ctw->set_add_to_colormap_btn(btn);
00200 
00201   btn = dynamic_cast<Gtk::Button*>( get_widget(ref_xml, "btnCtReset") );
00202   m_ctw->set_reset_colormap_btn(btn);
00203 
00204   btn = dynamic_cast<Gtk::Button*>( get_widget(ref_xml, "btnCtSaveHistos") );
00205   m_ctw->set_save_histos_btn(btn);
00206 
00207   btn = dynamic_cast<Gtk::Button*>( get_widget(ref_xml, "btnCtLoadHistos") );
00208   m_ctw->set_load_histos_btn(btn);
00209 
00210   btn = dynamic_cast<Gtk::Button*>( get_widget(ref_xml, "btnCtSaveColormap") );
00211   m_ctw->set_save_colormap_btn(btn);
00212 
00213   btn = dynamic_cast<Gtk::Button*>( get_widget(ref_xml, "btnCtLoadColormap") );
00214   m_ctw->set_load_colormap_btn(btn);
00215 
00216   Gtk::Scale* scl;
00217   scl = dynamic_cast<Gtk::Scale*>( get_widget(ref_xml, "sclCtThreshold") );
00218   m_ctw->set_threshold_scl(scl);
00219 
00220   scl = dynamic_cast<Gtk::Scale*>( get_widget(ref_xml, "sclCtMinProb") );
00221   m_ctw->set_min_prob_scl(scl);
00222 
00223   scl = dynamic_cast<Gtk::Scale*>( get_widget(ref_xml, "sclCtLayerSelector") );
00224   m_ctw->set_cm_layer_selector(scl);
00225 
00226   Gtk::Image* img;
00227   img = dynamic_cast<Gtk::Image*>( get_widget(ref_xml, "imgCtSegmentation") );
00228   m_ctw->set_segmentation_img(img);
00229 
00230   img = dynamic_cast<Gtk::Image*>( get_widget(ref_xml, "imgCtColormap") );
00231   m_ctw->set_colormap_img(img);
00232 
00233   Gtk::FileChooserDialog* fcd;
00234   fcd = dynamic_cast<Gtk::FileChooserDialog*>( get_widget(ref_xml, "fcdFilechooser") );
00235   m_ctw->set_filechooser_dlg(fcd);
00236 
00237 
00238   m_btn_ct_seg = dynamic_cast<Gtk::ToggleButton*>( get_widget(ref_xml, "btnCtSeg") );
00239   m_btn_ct_seg->signal_toggled().connect( sigc::mem_fun(*this, &Firestation::draw_image) );
00240   m_spbtn_depth = dynamic_cast<Gtk::SpinButton*>( get_widget(ref_xml, "spbtnCtCmDepth") );
00241   m_spbtn_width = dynamic_cast<Gtk::SpinButton*>( get_widget(ref_xml, "spbtnCtCmWidth") );
00242   m_spbtn_height = dynamic_cast<Gtk::SpinButton*>( get_widget(ref_xml, "spbtnCtCmHeight") );
00243   m_ctw->set_cm_selector(m_spbtn_depth, m_spbtn_width, m_spbtn_height);
00244   // ----------------------------------------------------------------
00245 
00246 
00247   // --- mirror calibration -----------------------------------------
00248   m_calib_tool = new MirrorCalibTool();
00249 
00250 #ifndef HAVE_BULB_CREATOR
00251   Gtk::Notebook *nb = dynamic_cast<Gtk::Notebook*>( get_widget(ref_xml, "ntbOptions") );
00252   Gtk::HBox *box = dynamic_cast<Gtk::HBox*>( get_widget(ref_xml, "boxMirrorCalib") );
00253   nb->get_tab_label(*box)->set_sensitive(false);
00254   box->set_sensitive(false);
00255 #endif /* HAVE_BULB_CREATOR */
00256 
00257   m_btn_mc_start = dynamic_cast<Gtk::Button*>( get_widget(ref_xml, "btnMcStart") );
00258   m_btn_mc_start->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::mc_start) );
00259 
00260   m_btn_mc_load = dynamic_cast<Gtk::Button*>( get_widget(ref_xml, "btnCalibLoad") );
00261   m_btn_mc_load->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::mc_load) );
00262 
00263   m_btn_mc_save = dynamic_cast<Gtk::Button*>( get_widget(ref_xml, "btnCalibSave") );
00264   m_btn_mc_save->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::mc_save) );
00265 
00266   m_ent_mc_dist = dynamic_cast<Gtk::Entry*>( get_widget(ref_xml, "entCalibDist") );
00267   m_ent_mc_ori = dynamic_cast<Gtk::Entry*>( get_widget(ref_xml, "entCalibOri") );
00268 
00269   m_fcd_mc_save = dynamic_cast<Gtk::FileChooserDialog*>( get_widget(ref_xml, "fcdCalibSave") );
00270   m_fcd_mc_load = dynamic_cast<Gtk::FileChooserDialog*>( get_widget(ref_xml, "fcdCalibLoad") );
00271   // ----------------------------------------------------------------
00272 
00273 
00274   // --- fuse transfer widget ---------------------------------------
00275   m_ftw = new FuseTransferWidget();
00276 
00277   Gtk::TreeView* trv = dynamic_cast<Gtk::TreeView*>( get_widget(ref_xml, "trvFuseRemoteLuts") );
00278   m_ftw->set_remote_lut_list_trv(trv);
00279   trv = dynamic_cast<Gtk::TreeView*>( get_widget(ref_xml, "trvFuseLocalLuts") );
00280   m_ftw->set_local_lut_list_trv(trv);
00281   img = dynamic_cast<Gtk::Image*>( get_widget(ref_xml, "imgFuseLocal") );
00282   m_ftw->set_local_img(img);
00283   img = dynamic_cast<Gtk::Image*>( get_widget(ref_xml, "imgFuseRemote") );
00284   m_ftw->set_remote_img(img);
00285   btn = dynamic_cast<Gtk::Button*>( get_widget(ref_xml, "btnFuseUpload") );
00286   m_ftw->set_upload_btn(btn);
00287   scl = dynamic_cast<Gtk::Scale*>( get_widget(ref_xml, "sclLocalLayerSelector") );
00288   m_ftw->set_local_layer_selector(scl);
00289   scl = dynamic_cast<Gtk::Scale*>( get_widget(ref_xml, "sclRemoteLayerSelector") );
00290   m_ftw->set_remote_layer_selector(scl);
00291   // ----------------------------------------------------------------
00292 
00293 
00294   // --- fuse image list widget -------------------------------------
00295   m_filw = new FuseImageListWidget();
00296   trv = dynamic_cast<Gtk::TreeView*>( get_widget(ref_xml, "trvFuseImageList") );
00297   m_filw->set_image_list_trv(trv);
00298   Gtk::CheckButton* chk = dynamic_cast<Gtk::CheckButton*>( get_widget(ref_xml, "chkFuseImageListUpdate") );
00299   m_filw->set_auto_update_chk(chk);
00300   chk = dynamic_cast<Gtk::CheckButton*>( get_widget(ref_xml, "chkFuseCompression") );
00301   m_filw->set_toggle_compression_chk(chk);
00302   m_filw->image_selected().connect( sigc::mem_fun(*this, &Firestation::on_fuse_image_selected) );
00303   // ----------------------------------------------------------------
00304 
00305   m_yuv_orig_buffer   = 0;
00306   m_yuv_draw_buffer   = 0;
00307   m_yuv_scaled_buffer = 0;
00308   m_rgb_scaled_buffer = 0;
00309 
00310   m_img_width  = 0;
00311   m_img_height = 0;
00312   m_img_size   = 0;
00313   m_img_cs     = CS_UNKNOWN;
00314 
00315   m_img_writer = 0;
00316   m_camera     = 0;
00317   m_shm_buffer = 0;
00318 
00319   m_img_src = SRC_NONE;
00320   m_op_mode = MODE_VIEWER;
00321 
00322   m_cont_img_trans = false;
00323 
00324   m_max_img_width  = m_evt_image->get_width();
00325   m_max_img_height = m_evt_image->get_height();
00326   m_scaled_img_width  = m_evt_image->get_width();
00327   m_scaled_img_height = m_evt_image->get_height();
00328   m_scale_factor = 1.0;
00329 
00330   m_avahi_thread = new AvahiThread();
00331   m_avahi_dispatcher = new AvahiDispatcher;
00332   
00333   m_avahi_dispatcher->signal_service_added().connect( sigc::mem_fun( *this, &Firestation::on_service_added ) );
00334   m_avahi_dispatcher->signal_service_removed().connect( sigc::mem_fun( *this, &Firestation::on_service_removed ) );
00335 
00336   m_avahi_thread->watch_service("_fountain._tcp", m_avahi_dispatcher);
00337   m_avahi_thread->start();
00338 }
00339 
00340 /** Destructor. */
00341 Firestation::~Firestation()
00342 {
00343   if (m_yuv_orig_buffer)    free(m_yuv_orig_buffer);
00344   if (m_yuv_draw_buffer)    free(m_yuv_draw_buffer);
00345   if (m_yuv_scaled_buffer)  free(m_yuv_scaled_buffer);
00346   if (m_rgb_scaled_buffer)  free(m_rgb_scaled_buffer);
00347 
00348   delete m_camera;
00349   delete m_img_writer;
00350 
00351   delete m_calib_tool;
00352   delete m_ctw;
00353   delete m_ftw;
00354   delete m_filw;
00355 
00356   m_avahi_thread->cancel();
00357   m_avahi_thread->join();
00358   delete m_avahi_thread;
00359   delete m_avahi_dispatcher;
00360 
00361   delete m_wnd_main;
00362   delete m_fcd_open_image;
00363   delete m_fcd_save_image;
00364   delete m_dlg_open_shm;
00365   delete m_dlg_open_fuse;
00366 }
00367 
00368 Gtk::Widget*
00369 Firestation::get_widget(Glib::RefPtr<Gnome::Glade::Xml> ref_xml,
00370                         const char* widget_name) const
00371 {
00372   Gtk::Widget* widget;
00373   ref_xml->get_widget(widget_name, widget);
00374   if ( !widget )
00375     {
00376       std::string err_str = "Couldn't find widget ";
00377       err_str += std::string(widget_name);
00378       err_str += ".";
00379       throw runtime_error(err_str);
00380     }
00381 
00382   return widget;
00383 }
00384 
00385 /** Returns reference to main window.
00386  * @return reference to main window
00387  */
00388 Gtk::Window&
00389 Firestation::get_window() const
00390 {
00391   return *m_wnd_main;
00392 }
00393 
00394 /** Exit routine. */
00395 void
00396 Firestation::exit()
00397 {
00398   if (SRC_NONE != m_img_src)
00399     { m_camera->close(); }
00400 
00401   m_wnd_main->hide();
00402 }
00403 
00404 void
00405 Firestation::close_camera()
00406 {
00407   if (SRC_NONE == m_img_src)
00408     { return; }
00409 
00410   m_img_src = SRC_NONE;
00411 
00412   m_camera->close();
00413   delete m_camera;
00414   m_camera = 0;
00415 
00416   m_img_width = 0;
00417   m_img_height = 0;
00418   m_img_cs = CS_UNKNOWN;
00419 
00420   m_img_size = 0;
00421 
00422   m_img_image->clear();
00423   m_img_image->set("gtk-missing-image");
00424 
00425   m_ctw->set_src_buffer(NULL, 0, 0);
00426   m_ctw->set_draw_buffer(NULL);
00427 }
00428 
00429 /** Saves the current image. */
00430 void
00431 Firestation::save_image()
00432 {
00433   if (m_img_src == SRC_NONE)
00434     { return; }
00435 
00436   m_fcd_save_image->set_transient_for(*this);
00437 
00438   int result = m_fcd_save_image->run();
00439 
00440   switch(result)
00441     {
00442     case(Gtk::RESPONSE_OK):
00443       {
00444         delete m_img_writer;
00445 
00446         Glib::ustring filter_name = m_fcd_save_image->get_filter()->get_name();
00447         if ( Glib::ustring("JPEG") == filter_name )
00448           {
00449             m_img_writer = new JpegWriter();
00450           }
00451         else if( Glib::ustring("FVRaw") == filter_name )
00452           {
00453             m_img_writer = new FvRawWriter();
00454           }
00455         else
00456           {
00457             cout << "save_file(): unknown file format" << endl;
00458             break;
00459           }
00460 
00461         std::string filename = m_fcd_save_image->get_filename();
00462         m_img_writer->set_filename( filename.c_str() );
00463         m_img_writer->set_dimensions(m_img_width, m_img_height);
00464         m_img_writer->set_buffer(m_img_cs, m_yuv_orig_buffer);
00465         m_img_writer->write();
00466 
00467         std::cout << "Save file: " <<  filename << std::endl;
00468         break;
00469       }
00470 
00471     case(Gtk::RESPONSE_CANCEL):
00472       break;
00473 
00474     default:
00475       break;
00476     }
00477 
00478   m_fcd_save_image->hide();
00479 }
00480 
00481 /** Reads in a new image for the current image source. */
00482 void
00483 Firestation::update_image()
00484 {
00485   if (m_img_src == SRC_NONE)
00486     { return; }
00487 
00488   try
00489     {
00490       m_camera->capture();
00491       convert(m_img_cs, YUV422_PLANAR,
00492               m_camera->buffer(), m_yuv_orig_buffer,
00493               m_img_width, m_img_height);
00494       memcpy(m_yuv_draw_buffer, m_yuv_orig_buffer,
00495              colorspace_buffer_size(YUV422_PLANAR, m_img_width, m_img_height));
00496       m_camera->dispose_buffer();
00497 
00498       draw_image();
00499 
00500       m_ctw->draw_segmentation_result();
00501     }
00502   catch (Exception& e)
00503     {
00504       e.print_trace();
00505     }
00506 }
00507 
00508 bool
00509 Firestation::call_update_image()
00510 {
00511   if ( !m_cont_img_trans )
00512     { return false; }
00513 
00514   update_image();
00515 
00516   return true;
00517 }
00518 
00519 void
00520 Firestation::enable_cont_img_trans()
00521 {
00522   if (m_cont_img_trans)
00523     {
00524       m_cont_img_trans = false;
00525       return;
00526     }
00527 
00528   int timeout = (int) rint( m_spb_update_time->get_value() );
00529   sigc::connection conn = Glib::signal_timeout().connect( sigc::mem_fun(*this, &Firestation::call_update_image), timeout);
00530   m_cont_img_trans = true;
00531 }
00532 
00533 /** Reads in an image from a file. */
00534 void
00535 Firestation::open_file()
00536 {
00537   m_fcd_open_image->set_action(Gtk::FILE_CHOOSER_ACTION_OPEN);
00538   m_fcd_open_image->set_transient_for(*this);
00539 
00540   int result = m_fcd_open_image->run();
00541 
00542   switch(result)
00543     {
00544     case Gtk::RESPONSE_OK:
00545       {
00546         pre_open_img_src();
00547 
00548         std::string filename = m_fcd_open_image->get_filename();
00549 
00550         m_camera = new FileLoader( filename.c_str() );
00551         m_img_src = SRC_FILE;
00552         post_open_img_src();
00553 
00554         break;
00555       }
00556 
00557     case Gtk::RESPONSE_CANCEL:
00558       {
00559         break;
00560       }
00561 
00562     default:
00563       {
00564         break;
00565       }
00566     }
00567 
00568   m_fcd_open_image->hide();
00569 }
00570 
00571 /** Reads in images from a directory. */
00572 void
00573 Firestation::open_folder()
00574 {
00575   m_fcd_open_image->set_action(Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
00576   m_fcd_open_image->set_transient_for(*this);
00577 
00578   int result = m_fcd_open_image->run();
00579 
00580   switch(result)
00581     {
00582     case Gtk::RESPONSE_OK:
00583       {
00584         pre_open_img_src();
00585 
00586         std::string extension;
00587         Glib::ustring filter_name = m_fcd_save_image->get_filter()->get_name();
00588         if ( Glib::ustring("JPEG") == filter_name )
00589           { extension = "jpg"; }
00590         else if ( Glib::ustring("FVRaw") == filter_name )
00591           { extension = "raw"; }
00592 
00593         std::string folder = m_fcd_open_image->get_current_folder();
00594         char* as;
00595         if (asprintf(&as, "file:file:dir=%s:ext=%s", folder.c_str(), extension.c_str()) != -1) {
00596           CameraArgumentParser cap(as);
00597           m_camera = new FileLoader( &cap );
00598           m_img_src = SRC_FILE;
00599           post_open_img_src();
00600           free(as);
00601         } else {
00602           printf("Cannot open folder, asprintf() ran out of memory");
00603         }
00604 
00605         break;
00606       }
00607 
00608     case Gtk::RESPONSE_CANCEL:
00609       {
00610         break;
00611       }
00612 
00613     default:
00614       {
00615         break;
00616       }
00617     }
00618 
00619   m_fcd_open_image->hide();
00620 }
00621 
00622 /** Opens a SHM image. */
00623 void
00624 Firestation::open_shm()
00625 {
00626   unsigned int num_buffers = 0;
00627   SharedMemory::SharedMemoryIterator shmit;
00628   SharedMemoryImageBufferHeader* h = new SharedMemoryImageBufferHeader;
00629   shmit = SharedMemory::find(FIREVISION_SHM_IMAGE_MAGIC_TOKEN, h);
00630 
00631   if (shmit == SharedMemory::end())
00632     {
00633       m_stb_status->push("No SHM images found");
00634       return;
00635     }
00636   else
00637     {
00638       m_shm_list_store->clear();
00639 
00640       while ( shmit != SharedMemory::end() )
00641         {
00642           ++num_buffers;
00643           Gtk::TreeModel::Row row = *(m_shm_list_store->append());
00644           row[m_shm_columns.m_id] = num_buffers;
00645           const SharedMemoryImageBufferHeader* h = (SharedMemoryImageBufferHeader*)*shmit;
00646           row[m_shm_columns.m_name] = h->image_id();
00647           shmit++;
00648         }
00649     }
00650 
00651   m_dlg_open_shm->set_transient_for(*this);
00652 
00653   int result = m_dlg_open_shm->run();
00654 
00655   switch(result)
00656     {
00657     case Gtk::RESPONSE_OK:
00658       {
00659         delete m_shm_buffer;
00660 
00661         Gtk::TreeModel::Path path;
00662         Gtk::TreeViewColumn* column;
00663         m_trv_shm_image_ids->get_cursor(path, column);
00664 
00665         Gtk::TreeModel::iterator iter = m_shm_list_store->get_iter(path);
00666 
00667         if (iter)
00668           {
00669             Gtk::TreeModel::Row row = *iter;
00670             if (row)
00671               {
00672                 Glib::ustring name = row[m_shm_columns.m_name];
00673                 pre_open_img_src();
00674 
00675                 try
00676                   {
00677                     m_camera = new SharedMemoryCamera( name.c_str() );
00678                   }
00679                 catch (Exception& e)
00680                   {
00681                     e.print_trace();
00682                   }
00683 
00684                 m_img_src = SRC_SHM;
00685 
00686                 post_open_img_src();
00687               }
00688           }
00689         else
00690           {
00691             std::cout << "invalid iter" << std::endl;
00692           }
00693 
00694         break;
00695       }
00696 
00697     case Gtk::RESPONSE_CANCEL:
00698       break;
00699 
00700     default:
00701       break;
00702     }
00703 
00704   m_dlg_open_shm->hide();
00705 }
00706 
00707 /** Connects to a FUSE server. */
00708 void
00709 Firestation::open_fuse()
00710 {
00711   Gtk::TreeModel::Children children = m_fuse_tree_store->children();
00712   if ( 0 == children.size() )
00713     {
00714       m_stb_status->push("No FUSE services found");
00715       return;
00716     }
00717 
00718   m_trv_fuse_services->expand_all();
00719   m_dlg_open_fuse->set_transient_for(*this);
00720 
00721   int result = m_dlg_open_fuse->run();
00722 
00723   switch(result)
00724     {
00725     case Gtk::RESPONSE_OK:
00726       {
00727         Gtk::TreeModel::Path path;
00728         Gtk::TreeViewColumn* column;
00729         m_trv_fuse_services->get_cursor(path, column);
00730 
00731         Gtk::TreeModel::iterator iter = m_fuse_tree_store->get_iter(path);
00732 
00733         if (iter)
00734           {
00735             Gtk::TreeModel::Row row = *iter;
00736             if (row)
00737               {
00738                 Glib::ustring hostname = row[m_fuse_columns.m_service_hostname];
00739                 unsigned short int port = row[m_fuse_columns.m_service_port];
00740                 Glib::ustring image_id = row[m_fuse_columns.m_image_id];
00741                 bool jpeg = m_ckb_fuse_jpeg->get_active();
00742 
00743                 pre_open_img_src();
00744 
00745                 try
00746                   {
00747                     m_camera = new NetworkCamera(hostname.c_str(), port, image_id.c_str(), jpeg);
00748                     m_img_src = SRC_FUSE;
00749                     post_open_img_src();
00750                   }
00751                 catch (Exception& e)
00752                   {
00753                     m_img_src = SRC_NONE;
00754                     e.print_trace();
00755                   }
00756               }
00757           }
00758         else
00759           {
00760             std::cout << "invalid iter" << std::endl;
00761           }
00762 
00763         break;
00764       }
00765 
00766     case Gtk::RESPONSE_CANCEL:
00767       break;
00768 
00769     default:
00770       break;
00771     }
00772 
00773   m_dlg_open_fuse->hide();
00774 }
00775 
00776 void
00777 Firestation::pre_open_img_src()
00778 {
00779   if (SRC_NONE != m_img_src)
00780     {
00781       m_camera->stop();
00782       m_camera->close();
00783 
00784       delete m_camera;
00785       m_camera = 0;
00786 
00787       m_img_src = SRC_NONE;
00788     }
00789 }
00790 
00791 /** Stuff that is executed after an image source has been selected. */
00792 void
00793 Firestation::post_open_img_src()
00794 {
00795   if (m_img_src == SRC_NONE) { return; }
00796 
00797   try
00798     {
00799       m_camera->open();
00800       m_camera->start();
00801       m_camera->capture();
00802       m_img_width = m_camera->pixel_width();
00803       m_img_height = m_camera->pixel_height();
00804       m_img_cs = m_camera->colorspace();
00805 
00806       m_img_size = colorspace_buffer_size( m_img_cs,
00807                                            m_img_width,
00808                                            m_img_height );
00809 
00810       m_yuv_orig_buffer = malloc_buffer(YUV422_PLANAR, m_img_width, m_img_height);
00811       m_yuv_draw_buffer = malloc_buffer(YUV422_PLANAR, m_img_width, m_img_height);
00812 
00813       convert(m_img_cs, YUV422_PLANAR,
00814               m_camera->buffer(), m_yuv_orig_buffer,
00815               m_img_width, m_img_height);
00816       memcpy(m_yuv_draw_buffer, m_yuv_orig_buffer,
00817              colorspace_buffer_size(YUV422_PLANAR, m_img_width, m_img_height));
00818 
00819       m_camera->dispose_buffer();
00820 
00821       m_tbtn_update->set_sensitive(true);
00822       m_tbtn_save->set_sensitive(true);
00823 
00824       draw_image();
00825 
00826       m_ctw->set_src_buffer(m_yuv_orig_buffer, m_img_width, m_img_height);
00827       m_ctw->set_draw_buffer(m_yuv_draw_buffer);
00828       m_ctw->draw_segmentation_result();
00829     }
00830   catch (Exception& e)
00831     {
00832       e.print_trace();
00833       printf("Opening camera failed.\n");
00834     }
00835 
00836 }
00837 
00838 void
00839 Firestation::on_fuse_image_selected()
00840 {
00841   string host_name;
00842   unsigned short port;
00843   string image_id;
00844   bool compression;
00845 
00846   m_filw->get_selected_image(host_name, port, image_id, compression);
00847 
00848   pre_open_img_src();
00849 
00850   try
00851     {
00852       m_camera = new NetworkCamera( host_name.c_str(), port, image_id.c_str(), compression );
00853       m_img_src = SRC_FUSE;
00854     }
00855   catch (Exception& e)
00856     {
00857       m_img_src = SRC_NONE;
00858       e.print_trace();
00859     }
00860 
00861   post_open_img_src();
00862 }
00863 
00864 void
00865 Firestation::on_colormap_updated()
00866 {
00867   m_ftw->set_current_colormap( m_ctw->get_colormap() );
00868 }
00869 
00870 /** Draws the image. */
00871 void
00872 Firestation::draw_image()
00873 {
00874   if ( m_img_src == SRC_NONE ) { return; }
00875 
00876   LossyScaler scaler;
00877   scaler.set_original_buffer( m_yuv_draw_buffer );
00878   scaler.set_original_dimensions(m_img_width, m_img_height);
00879   scaler.set_scaled_dimensions(m_max_img_width, m_max_img_height);
00880 
00881   unsigned int scaled_width  = scaler.needed_scaled_width();
00882   unsigned int scaled_height = scaler.needed_scaled_height();
00883 
00884   if (scaled_width != m_scaled_img_width || scaled_height != m_scaled_img_height)
00885     {
00886       m_scaled_img_width  = scaled_width;
00887       m_scaled_img_height = scaled_height;
00888       m_scale_factor = scaler.get_scale_factor();
00889     }
00890 
00891   if (m_rgb_scaled_buffer)  free(m_rgb_scaled_buffer);
00892   if (m_yuv_scaled_buffer)  free(m_yuv_scaled_buffer);
00893   m_yuv_scaled_buffer = malloc_buffer(YUV422_PLANAR, m_scaled_img_width,
00894                                       m_scaled_img_height);
00895   scaler.set_scaled_buffer(m_yuv_scaled_buffer);
00896   scaler.scale();
00897 
00898   if (m_btn_ct_seg->get_active()) {
00899     unsigned int sld_img_size = m_scaled_img_width * m_scaled_img_height;
00900     unsigned char u_seg = 255 / (unsigned int)pow(2, m_spbtn_width->get_value());
00901     unsigned char v_seg = 255 / (unsigned int)pow(2, m_spbtn_height->get_value());
00902     unsigned int u = 0;
00903     for (u = sld_img_size; u < sld_img_size + sld_img_size / 2; ++u) {
00904       m_yuv_scaled_buffer[u] = (m_yuv_scaled_buffer[u] / u_seg) * u_seg;
00905     }
00906 
00907     for (; u < 2 * sld_img_size; ++u) {
00908       m_yuv_scaled_buffer[u] = (m_yuv_scaled_buffer[u] / v_seg) * v_seg;
00909     }
00910   }
00911 
00912   if ( m_img_src == SRC_SHM )
00913     {
00914       SharedMemoryCamera* shm_camera = dynamic_cast<SharedMemoryCamera*>(m_camera);
00915       if ( shm_camera->shared_memory_image_buffer()->circle_found() )
00916         {
00917           Drawer drawer;
00918           drawer.set_buffer(m_yuv_scaled_buffer, m_scaled_img_width, m_scaled_img_height);
00919           drawer.set_color(YUV_t::white());
00920           unsigned int roi_x = (unsigned int) rint( shm_camera->shared_memory_image_buffer()->roi_x() * m_scale_factor );
00921           unsigned int roi_y = (unsigned int) rint( shm_camera->shared_memory_image_buffer()->roi_y() * m_scale_factor );
00922           unsigned int roi_width  = (unsigned int) rint( shm_camera->shared_memory_image_buffer()->roi_width() * m_scale_factor );
00923           unsigned int roi_height = (unsigned int) rint( shm_camera->shared_memory_image_buffer()->roi_height() * m_scale_factor );
00924           drawer.draw_rectangle( roi_x, roi_y, roi_width, roi_height );
00925         }
00926     }
00927 
00928   m_rgb_scaled_buffer = (unsigned char*) malloc( colorspace_buffer_size( RGB,
00929                                                                          m_scaled_img_width,
00930                                                                          m_scaled_img_height ) );
00931 
00932   convert( YUV422_PLANAR, RGB,
00933            m_yuv_scaled_buffer, m_rgb_scaled_buffer,
00934            m_scaled_img_width, m_scaled_img_height );
00935 
00936   Glib::RefPtr<Gdk::Pixbuf> image = Gdk::Pixbuf::create_from_data( m_rgb_scaled_buffer,
00937                                                                    Gdk::COLORSPACE_RGB,
00938                                                                    false,
00939                                                                    8,
00940                                                                    m_scaled_img_width,
00941                                                                    m_scaled_img_height,
00942                                                                    3 * m_scaled_img_width );
00943 
00944   m_img_image->set(image);
00945 }
00946 
00947 /** Signal handler that is called whenever the window size is changed.
00948  * @param allocation a Gtk allocation
00949  */
00950 void
00951 Firestation::resize_image(Gtk::Allocation& allocation)
00952 {
00953   unsigned int new_width = (unsigned int) allocation.get_width();
00954   unsigned int new_height = (unsigned int) allocation.get_height();
00955 
00956   if (new_width != m_max_img_width ||  new_height != m_max_img_height)
00957     {
00958       m_max_img_width = new_width;
00959       m_max_img_height = new_height;
00960       draw_image();
00961     }
00962 }
00963 
00964 /** Handles mouse clicks in the image area.
00965  * @param event a Gtk event
00966  * @return true if signal was handled
00967  */
00968 bool
00969 Firestation::image_click(GdkEventButton* event)
00970 {
00971   unsigned int offset_x;
00972   unsigned int offset_y;
00973 
00974   offset_x = (m_max_img_width - m_scaled_img_width) / 2;
00975   offset_y = (m_max_img_height - m_scaled_img_height) / 2;
00976 
00977   offset_x = offset_x > m_max_img_width ? 0 : offset_x;
00978   offset_y = offset_y > m_max_img_height ? 0 : offset_y;
00979 
00980   unsigned int image_x;
00981   unsigned int image_y;
00982 
00983   image_x = (unsigned int)rint( (event->x - offset_x) / m_scale_factor);
00984   image_y = (unsigned int)rint( (event->y - offset_y) / m_scale_factor);
00985 
00986   if ( image_x < 0 || image_x > m_img_width ||
00987        image_y < 0 || image_y > m_img_height )
00988     { return true; }
00989 
00990   switch (m_op_mode)
00991     {
00992     case MODE_VIEWER:
00993       if (m_img_src != SRC_NONE)
00994         {
00995           register unsigned char y;
00996           register unsigned char u;
00997           register unsigned char v;
00998           YUV422_PLANAR_YUV( m_yuv_orig_buffer,
00999                              m_img_width,
01000                              m_img_height,
01001                              image_x,
01002                              image_y,
01003                              y, u, v );
01004           printf( "Y=%d  U=%d  Y=%d @ (%d, %d)\n",
01005                   (unsigned int) y, (unsigned int) u, (unsigned int) v,
01006                   image_x, image_y );
01007         }
01008       break;
01009 
01010     case MODE_COLOR_TRAIN:
01011       m_ctw->click(image_x, image_y, event->button);
01012       draw_image();
01013      break;
01014 
01015     case MODE_MIRROR_CALIB:
01016       {
01017         m_calib_tool->step(image_x, image_y);
01018 
01019         bool show;
01020         float next_dist;
01021         float next_ori;
01022         show = m_calib_tool->get_next(&next_dist, &next_ori);
01023 
01024         if (show)
01025           {
01026             char* next_dist_char = (char*) malloc(10);
01027             char* next_ori_char = (char*) malloc(10);
01028 
01029             sprintf(next_dist_char, "%2f", next_dist);
01030             sprintf(next_ori_char, "%2f", next_ori);
01031             m_ent_mc_dist->set_text(Glib::ustring(next_dist_char));
01032             m_ent_mc_ori->set_text(Glib::ustring(next_ori_char));
01033 
01034             free(next_dist_char);
01035             free(next_ori_char);
01036           }
01037         else
01038           {
01039             m_ent_mc_dist->set_text("");
01040             m_ent_mc_ori->set_text("");
01041           }
01042 
01043         break;
01044       }
01045 
01046     case MODE_MIRROR_CALIB_EVAL:
01047       {
01048         float dist;
01049         float phi;
01050         m_calib_tool->eval(image_x, image_y, &dist, &phi);
01051         printf("Distance: %2f\t Phi: %2f\n", dist, phi);
01052         break;
01053       }
01054 
01055     default:
01056       break;
01057     }
01058 
01059   return true;
01060 }
01061 
01062 /** Starts the color training. */
01063 void
01064 Firestation::ct_start()
01065 {
01066   if (m_op_mode == MODE_COLOR_TRAIN)
01067     {
01068       m_op_mode = MODE_VIEWER;
01069       m_stb_status->push("Leaving color training mode");
01070     }
01071   else
01072     {
01073       if (m_img_src != SRC_NONE)
01074         {
01075           m_ctw->set_fg_object( ct_get_fg_object() );
01076 
01077           m_op_mode = MODE_COLOR_TRAIN;
01078 
01079           m_stb_status->push("Entering color training mode");
01080         }
01081     }
01082 }
01083 
01084 hint_t
01085 Firestation::ct_get_fg_object()
01086 {
01087         int active = m_cmb_ct_type->get_active_row_number();
01088         switch(active)
01089         {
01090                 case 0: //Ball
01091                         return H_BALL;
01092 
01093                 case 1: //Field
01094                         return H_FIELD;
01095 
01096                 case 2: //Lines
01097                         return H_LINE;
01098 
01099                 case 3: //Robot (Team A or all)
01100                         return H_ROBOT;
01101 
01102                 case 4: //Robot (Team B)
01103                         return H_ROBOT_OPP;
01104 
01105                 case 5: //Goal (yellow)
01106                         return H_GOAL_YELLOW;
01107 
01108                 case 6: //Goal (sky-blue)
01109                         return H_GOAL_BLUE;
01110 
01111                 case 7: //Background
01112                         return H_UNKNOWN;
01113 
01114                 default:
01115                         printf("ct_get_fg_object(): UNKNOWN\n");
01116                         return H_UNKNOWN;
01117         }
01118 }
01119 
01120 void
01121 Firestation::ct_object_changed()
01122 {
01123         hint_t object = ct_get_fg_object();
01124         m_ctw->set_fg_object(object);
01125 }
01126 
01127 /** Start the mirror calibration process. */
01128 void
01129 Firestation::mc_start()
01130 {
01131   if (m_op_mode == MODE_MIRROR_CALIB)
01132     {
01133       m_op_mode = MODE_VIEWER;
01134       m_stb_status->push("Leaving mirror calibration mode");
01135     }
01136   else
01137     {
01138       if (m_img_src != SRC_NONE)
01139         {
01140           m_calib_tool->set_img_dimensions(m_img_width, m_img_height);
01141           m_calib_tool->start();
01142 
01143           m_op_mode = MODE_MIRROR_CALIB;
01144 
01145           bool show;
01146           float next_dist;
01147           float next_ori;
01148           show = m_calib_tool->get_next(&next_dist, &next_ori);
01149 
01150           if (show)
01151             {
01152               char* next_dist_char = (char*) malloc(10);
01153               char* next_ori_char = (char*) malloc(10);
01154 
01155               sprintf(next_dist_char, "%2f", next_dist);
01156               sprintf(next_ori_char, "%2f", next_ori);
01157               m_ent_mc_dist->set_text(Glib::ustring(next_dist_char));
01158               m_ent_mc_ori->set_text(Glib::ustring(next_ori_char));
01159 
01160               free(next_dist_char);
01161               free(next_ori_char);
01162             }
01163           else
01164             {
01165               m_ent_mc_dist->set_text("");
01166               m_ent_mc_ori->set_text("");
01167             }
01168 
01169           m_stb_status->push("Entering mirror calibration mode");
01170         }
01171     }
01172 }
01173 
01174 /** Load mirror calibration data from a file. */
01175 void
01176 Firestation::mc_load()
01177 {
01178   m_fcd_mc_load->set_transient_for(*this);
01179 
01180   Gtk::FileFilter filter_mirror;
01181   filter_mirror.set_name("Mirror Calibration");
01182   filter_mirror.add_pattern("*.mirror");
01183   filter_mirror.add_pattern("*.bulb");
01184   m_fcd_mc_load->add_filter(filter_mirror);
01185 
01186   int result = m_fcd_mc_load->run();
01187 
01188   switch(result)
01189     {
01190     case Gtk::RESPONSE_OK:
01191       {
01192         std::string filename = m_fcd_mc_load->get_filename();
01193         m_calib_tool->load( filename.c_str() );
01194         m_op_mode = MODE_MIRROR_CALIB_EVAL;
01195         break;
01196       }
01197     case Gtk::RESPONSE_CANCEL:
01198       break;
01199     default:
01200       break;
01201     }
01202 
01203   m_fcd_mc_load->hide();
01204 }
01205 
01206 /** Save calibration data to a file. */
01207 void
01208 Firestation::mc_save()
01209 {
01210   m_fcd_mc_save->set_transient_for(*this);
01211 
01212   int result = m_fcd_mc_save->run();
01213 
01214   switch(result)
01215     {
01216     case(Gtk::RESPONSE_OK):
01217       {
01218         std::string filename = m_fcd_mc_save->get_filename();
01219 
01220         m_calib_tool->save( filename.c_str() );
01221         break;
01222       }
01223 
01224     case(Gtk::RESPONSE_CANCEL):
01225       break;
01226 
01227     default:
01228       break;
01229     }
01230 
01231   m_fcd_mc_save->hide();
01232 
01233 }
01234 
01235 void
01236 Firestation::on_service_added( NetworkService* service )
01237 {
01238   const char* host        = service->host();
01239   const char* name        = service->name();
01240   const char* type        = service->type();
01241   const char* domain      = service->domain();
01242   unsigned short int port = service->port();
01243   
01244   std::vector<FUSE_imageinfo_t> image_list;
01245   NetworkCamera cam(host, port);
01246   try
01247     {
01248       cam.open();
01249       cam.start();
01250       image_list = cam.image_list();
01251     }
01252   catch (Exception& e)
01253     {
01254       e.append("Could not open camera on %s:%d", host, port);
01255       e.print_trace();
01256       return;
01257     }
01258   cam.close();
01259 
01260 #ifdef DEBUG_PRINT
01261   printf("%zu images available on host %s.\n", image_list.size(), host);
01262 #endif /* DEBUG_PRINT */
01263 
01264   std::vector<FUSE_imageinfo_t>::iterator fit;
01265 
01266   Gtk::TreeModel::Children children = m_fuse_tree_store->children();
01267   Gtk::TreeModel::Row row = *(m_fuse_tree_store->append());
01268   row[m_fuse_columns.m_id] = children.size();
01269   row[m_fuse_columns.m_name] = Glib::ustring(name);
01270   row[m_fuse_columns.m_service_name] = Glib::ustring(name);
01271   row[m_fuse_columns.m_service_type] = Glib::ustring(type);
01272   row[m_fuse_columns.m_service_domain] = Glib::ustring(domain);
01273   row[m_fuse_columns.m_service_hostname] = Glib::ustring(host);
01274   row[m_fuse_columns.m_service_port] = port;
01275 
01276   for (fit = image_list.begin(); fit != image_list.end(); ++fit)
01277     {
01278       Gtk::TreeModel::Row childrow = *(m_fuse_tree_store->append(row.children()));
01279       childrow[m_fuse_columns.m_name] = Glib::ustring(fit->image_id);
01280       childrow[m_fuse_columns.m_service_name] = Glib::ustring(name);
01281       childrow[m_fuse_columns.m_service_type] = Glib::ustring(type);
01282       childrow[m_fuse_columns.m_service_domain] = Glib::ustring(domain);
01283       childrow[m_fuse_columns.m_service_hostname] = Glib::ustring(host);
01284       childrow[m_fuse_columns.m_service_port] = port;
01285       childrow[m_fuse_columns.m_image_id] = Glib::ustring(fit->image_id);
01286       childrow[m_fuse_columns.m_image_width] = fit->width;
01287       childrow[m_fuse_columns.m_image_height] = fit->height;
01288       childrow[m_fuse_columns.m_image_colorspace] = Glib::ustring( colorspace_to_string((colorspace_t) fit->colorspace) );
01289     }
01290 
01291   m_ftw->add_fountain_service(name, host, port);
01292   m_filw->add_fountain_service(name, host, port);
01293 }
01294 
01295 void
01296 Firestation::on_service_removed( NetworkService* service )
01297 {
01298   const char* name   = service->name();
01299   const char* type   = service->type();
01300   const char* domain = service->domain();
01301 
01302   Gtk::TreeModel::Children children = m_fuse_tree_store->children();
01303   Gtk::TreeModel::iterator rit;
01304   for (rit = children.begin(); rit != children.end(); ++rit)
01305     {
01306       Glib::ustring n = (*rit)[m_fuse_columns.m_service_name];
01307       Glib::ustring t = (*rit)[m_fuse_columns.m_service_type];
01308       Glib::ustring d = (*rit)[m_fuse_columns.m_service_domain];
01309 
01310       if ( strcmp( n.c_str(), name) == 0 &&
01311            strcmp( t.c_str(), type) == 0 &&
01312            strcmp( d.c_str(), domain) == 0 )
01313         {
01314           m_fuse_tree_store->erase(rit);
01315         }
01316     }
01317 
01318   m_ftw->remove_fountain_service(name);
01319   m_filw->remove_fountain_service(name);
01320 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends