Fawkes API Fawkes Development Version
|
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 }