00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "property_manager.h"
00031 #include "property.h"
00032
00033 #include <ros/console.h>
00034
00035 #include <wx/wx.h>
00036 #include <wx/propgrid/propgrid.h>
00037 #include <wx/confbase.h>
00038
00039 namespace rviz
00040 {
00041
00042 PropertyManager::PropertyManager()
00043 : grid_(0)
00044 , default_user_data_(0)
00045 {
00046 }
00047
00048 PropertyManager::~PropertyManager()
00049 {
00050 clear();
00051 }
00052
00053 void PropertyManager::addProperty(const PropertyBasePtr& property, const std::string& name, const std::string& prefix, void* user_data)
00054 {
00055 bool inserted = properties_.insert( std::make_pair( std::make_pair(prefix, name), property ) ).second;
00056 ROS_ASSERT(inserted);
00057
00058 if (!user_data)
00059 {
00060 user_data = default_user_data_;
00061 }
00062
00063 property->setUserData( user_data );
00064 property->addChangedListener( boost::bind( &PropertyManager::propertySet, this, _1 ) );
00065
00066 if (config_ && property->getSave())
00067 {
00068 property->loadFromConfig(config_.get());
00069 }
00070
00071 if (grid_)
00072 {
00073 property->setPropertyGrid(grid_);
00074 property->writeToGrid();
00075 property->setPGClientData();
00076 }
00077 }
00078
00079 StatusPropertyWPtr PropertyManager::createStatus(const std::string& name, const std::string& prefix, const CategoryPropertyWPtr& parent, void* user_data)
00080 {
00081 StatusPropertyPtr prop(new StatusProperty(name, prefix, parent, user_data));
00082 addProperty(prop, name, prefix, user_data);
00083
00084 return StatusPropertyWPtr(prop);
00085 }
00086
00087 CategoryPropertyWPtr PropertyManager::createCategory(const std::string& name, const std::string& prefix, const CategoryPropertyWPtr& parent, void* user_data)
00088 {
00089 CategoryPropertyPtr category(new CategoryProperty(name, name, prefix, parent, CategoryProperty::Getter(), CategoryProperty::Setter(), false));
00090 category->setSave( false );
00091 addProperty(category, name, prefix, user_data);
00092
00093 return CategoryPropertyWPtr(category);
00094 }
00095
00096 CategoryPropertyWPtr PropertyManager::createCheckboxCategory(const std::string& label, const std::string& name, const std::string& prefix, const boost::function<bool(void)>& getter,
00097 const boost::function<void(bool)>& setter, const CategoryPropertyWPtr& parent, void* user_data)
00098 {
00099 CategoryPropertyPtr category(new CategoryProperty(label, name, prefix, parent, getter, setter, true));
00100 addProperty(category, name, prefix, user_data);
00101
00102 return CategoryPropertyWPtr(category);
00103 }
00104
00105 void PropertyManager::update()
00106 {
00107 #if 0
00108 if (grid_)
00109 {
00110 if (grid_->IsEditorFocused())
00111 {
00112 return;
00113 }
00114 }
00115 #endif
00116
00117 S_PropertyBaseWPtr local_props;
00118 {
00119 boost::mutex::scoped_lock lock(changed_mutex_);
00120
00121 local_props.swap(changed_properties_);
00122 }
00123
00124 if (!local_props.empty())
00125 {
00126 #if 0
00127 if (grid_)
00128 {
00129 grid_->Freeze();
00130 }
00131 #endif
00132
00133 S_PropertyBaseWPtr::iterator it = local_props.begin();
00134 S_PropertyBaseWPtr::iterator end = local_props.end();
00135 for (; it != end; ++it)
00136 {
00137 PropertyBasePtr property = it->lock();
00138 if (property)
00139 {
00140 if (grid_)
00141 {
00142 property->writeToGrid();
00143 }
00144
00145 if (config_ && property->getSave())
00146 {
00147 property->saveToConfig(config_.get());
00148 }
00149 }
00150 }
00151
00152 if (grid_)
00153 {
00154 grid_->Refresh();
00155 }
00156
00157 #if 0
00158 if (grid_)
00159 {
00160 grid_->Thaw();
00161 }
00162 #endif
00163 }
00164
00165 static bool do_refresh = false;
00166 if (do_refresh)
00167 {
00168 grid_->Refresh();
00169 }
00170 }
00171
00172 void PropertyManager::deleteProperty( const PropertyBasePtr& property )
00173 {
00174 if ( !property )
00175 {
00176 return;
00177 }
00178
00179 M_Property::iterator it = properties_.begin();
00180 M_Property::iterator end = properties_.end();
00181 for (; it != end; ++it)
00182 {
00183 if (it->second == property)
00184 {
00185
00186 deleteChildren( it->second );
00187
00188 grid_->Freeze();
00189
00190 properties_.erase( it );
00191
00192 grid_->Thaw();
00193
00194 break;
00195 }
00196 }
00197 }
00198
00199 void PropertyManager::deleteProperty( const std::string& name, const std::string& prefix )
00200 {
00201 M_Property::iterator found_it = properties_.find( std::make_pair( prefix, name ) );
00202 ROS_ASSERT( found_it != properties_.end() );
00203
00204
00205 deleteChildren( found_it->second );
00206
00207 if (grid_)
00208 {
00209 grid_->Freeze();
00210 }
00211
00212 properties_.erase( found_it );
00213
00214 if (grid_)
00215 {
00216 grid_->Thaw();
00217 }
00218 }
00219
00220 void PropertyManager::changePrefix(const std::string& old_prefix, const std::string& new_prefix)
00221 {
00222
00223
00224 M_Property to_add;
00225 std::vector<M_Property::iterator> to_delete;
00226 M_Property::iterator it = properties_.begin();
00227 M_Property::iterator end = properties_.end();
00228 for (; it != end; ++it)
00229 {
00230 const std::pair<std::string, std::string>& key = it->first;
00231 const PropertyBasePtr& prop = it->second;
00232
00233
00234 size_t pos = key.first.find(old_prefix);
00235 if (pos == 0)
00236 {
00237 std::string np = new_prefix + key.first.substr(old_prefix.size());
00238 prop->setPrefix(np);
00239 to_add[std::make_pair(np, key.second)] = prop;
00240 to_delete.push_back(it);
00241 }
00242 }
00243
00244 for (size_t i = 0; i < to_delete.size(); ++i)
00245 {
00246 properties_.erase(to_delete[i]);
00247 }
00248
00249 properties_.insert(to_add.begin(), to_add.end());
00250 }
00251
00252 void PropertyManager::deleteChildren( const PropertyBasePtr& property )
00253 {
00254 if (!property)
00255 {
00256 return;
00257 }
00258
00259 std::set<PropertyBasePtr> to_delete;
00260
00261 M_Property::iterator prop_it = properties_.begin();
00262 M_Property::iterator prop_end = properties_.end();
00263 for ( ; prop_it != prop_end; ++prop_it )
00264 {
00265 const PropertyBasePtr& child = prop_it->second;
00266
00267 PropertyBaseWPtr parent = child->getParent();
00268 if ( parent.lock() == property )
00269 {
00270 to_delete.insert( child );
00271 }
00272 }
00273
00274 if (grid_)
00275 {
00276 grid_->Freeze();
00277 }
00278
00279 std::set<PropertyBasePtr>::iterator del_it = to_delete.begin();
00280 std::set<PropertyBasePtr>::iterator del_end = to_delete.end();
00281 for ( ; del_it != del_end; ++del_it )
00282 {
00283 deleteProperty( *del_it );
00284 }
00285
00286 to_delete.clear();
00287
00288 if (grid_)
00289 {
00290 grid_->Thaw();
00291 }
00292 }
00293
00294 void PropertyManager::deleteByUserData( void* user_data )
00295 {
00296 std::set<PropertyBasePtr> to_delete;
00297
00298 M_Property::iterator it = properties_.begin();
00299 M_Property::iterator end = properties_.end();
00300 for ( ; it != end; ++it )
00301 {
00302 const PropertyBasePtr& property = it->second;
00303
00304 if ( property->getUserData() == user_data )
00305 {
00306 PropertyBasePtr parent = property->getParent().lock();
00307 if ( !parent || parent->getUserData() != user_data )
00308 {
00309 to_delete.insert( property );
00310 }
00311 }
00312 }
00313
00314 if (grid_)
00315 {
00316 grid_->Freeze();
00317 }
00318
00319 std::set<PropertyBasePtr>::iterator prop_it = to_delete.begin();
00320 std::set<PropertyBasePtr>::iterator prop_end = to_delete.end();
00321 for ( ; prop_it != prop_end; ++prop_it )
00322 {
00323 deleteProperty( *prop_it );
00324 }
00325
00326 if (grid_)
00327 {
00328 grid_->Thaw();
00329 }
00330 }
00331
00332 void PropertyManager::propertyChanging( wxPropertyGridEvent& event )
00333 {
00334
00335 }
00336
00337 void PropertyManager::propertyChanged( wxPropertyGridEvent& event )
00338 {
00339 wxPGProperty* property = event.GetProperty();
00340
00341 void* client_data = property->GetClientData();
00342 if ( client_data )
00343 {
00344 PropertyBase* property = reinterpret_cast<PropertyBase*>(client_data);
00345
00346 property->readFromGrid();
00347 }
00348 }
00349
00350 void PropertyManager::propertySet( const PropertyBasePtr& property )
00351 {
00352 boost::mutex::scoped_lock lock(changed_mutex_);
00353
00354 changed_properties_.insert(property);
00355 }
00356
00357 void PropertyManager::save(const boost::shared_ptr<wxConfigBase>& config)
00358 {
00359 M_Property::iterator it = properties_.begin();
00360 M_Property::iterator end = properties_.end();
00361 for ( ; it != end; ++it )
00362 {
00363 const PropertyBasePtr& property = it->second;
00364
00365 if ( property->getSave() )
00366 {
00367 property->saveToConfig( config.get() );
00368 }
00369 }
00370 }
00371
00372 void PropertyManager::load(const boost::shared_ptr<wxConfigBase>& config, const StatusCallback& cb)
00373 {
00374 config_ = config;
00375
00376 M_Property::iterator it = properties_.begin();
00377 M_Property::iterator end = properties_.end();
00378 for ( ; it != end; ++it )
00379 {
00380 const PropertyBasePtr& property = it->second;
00381
00382 if ( property->getSave() )
00383 {
00384 std::stringstream ss;
00385 ss << "Loading property [" << property->getPrefix() + property->getName() << "]";
00386 ROS_DEBUG_STREAM_NAMED("properties", ss.str());
00387
00388 if (cb)
00389 {
00390 cb(ss.str());
00391 }
00392
00393 property->loadFromConfig( config.get() );
00394 }
00395 }
00396 }
00397
00398 void PropertyManager::setPropertyGrid(wxPropertyGrid* grid)
00399 {
00400 ROS_ASSERT(!grid_);
00401 ROS_ASSERT(grid);
00402
00403 grid_ = grid;
00404
00405 M_Property::iterator it = properties_.begin();
00406 M_Property::iterator end = properties_.end();
00407 for (; it != end; ++it)
00408 {
00409 const PropertyBasePtr& property = it->second;
00410 property->setPropertyGrid(grid_);
00411 property->writeToGrid();
00412 property->setPGClientData();
00413 }
00414 }
00415
00416 void PropertyManager::refreshAll()
00417 {
00418 ROS_ASSERT(grid_);
00419
00420 M_Property::iterator it = properties_.begin();
00421 M_Property::iterator end = properties_.end();
00422 for (; it != end; ++it)
00423 {
00424 propertySet(it->second);
00425 }
00426
00427 update();
00428 }
00429
00430 void PropertyManager::clear()
00431 {
00432 if (grid_)
00433 {
00434 grid_->Freeze();
00435 }
00436
00437 M_Property::iterator it = properties_.begin();
00438 M_Property::iterator end = properties_.end();
00439 for (; it != end; ++it)
00440 {
00441 it->second->reset();
00442 }
00443 properties_.clear();
00444
00445 if (grid_)
00446 {
00447 grid_->Clear();
00448 grid_->Thaw();
00449 }
00450 }
00451
00452 }