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 #include "rviz/properties/property_tree_widget.h"
00033
00034 #include <ros/console.h>
00035
00036 #include "config.h"
00037
00038 namespace rviz
00039 {
00040
00041 PropertyManager::PropertyManager()
00042 : grid_(0)
00043 , default_user_data_(0)
00044 {
00045 }
00046
00047 PropertyManager::~PropertyManager()
00048 {
00049 clear();
00050 }
00051
00052 void PropertyManager::addProperty(const PropertyBasePtr& property, const std::string& name, const std::string& prefix, void* user_data)
00053 {
00054 bool inserted = properties_.insert( std::make_pair( std::make_pair(prefix, name), property ) ).second;
00055 ROS_ASSERT(inserted);
00056
00057 if (!user_data)
00058 {
00059 user_data = default_user_data_;
00060 }
00061
00062 property->setUserData( user_data );
00063
00064
00065 property->manager_ = this;
00066
00067 if (config_ && property->getSave())
00068 {
00069 property->loadFromConfig(config_.get());
00070 }
00071
00072 if (grid_)
00073 {
00074 property->setPropertyTreeWidget(grid_);
00075 property->writeToGrid();
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_->update();
00155 }
00156
00157 #if 0
00158 if (grid_)
00159 {
00160 grid_->Thaw();
00161 }
00162 #endif
00163 }
00164 }
00165
00166 void PropertyManager::deleteProperty( const PropertyBasePtr& property )
00167 {
00168 if ( !property )
00169 {
00170 return;
00171 }
00172
00173
00174 property->manager_ = 0;
00175
00176 M_Property::iterator it = properties_.begin();
00177 M_Property::iterator end = properties_.end();
00178 for (; it != end; ++it)
00179 {
00180 if (it->second == property)
00181 {
00182
00183 deleteChildren( it->second );
00184
00185 properties_.erase( it );
00186
00187 break;
00188 }
00189 }
00190 }
00191
00192 void PropertyManager::deleteProperty( const std::string& name, const std::string& prefix )
00193 {
00194 M_Property::iterator found_it = properties_.find( std::make_pair( prefix, name ) );
00195 ROS_ASSERT( found_it != properties_.end() );
00196
00197
00198 deleteChildren( found_it->second );
00199
00200 if( found_it->second )
00201 {
00202
00203 found_it->second->manager_ = 0;
00204 }
00205
00206 properties_.erase( found_it );
00207 }
00208
00209 void PropertyManager::changePrefix(const std::string& old_prefix, const std::string& new_prefix)
00210 {
00211
00212
00213 M_Property to_add;
00214 std::vector<M_Property::iterator> to_delete;
00215 M_Property::iterator it = properties_.begin();
00216 M_Property::iterator end = properties_.end();
00217 for (; it != end; ++it)
00218 {
00219 const std::pair<std::string, std::string>& key = it->first;
00220 const PropertyBasePtr& prop = it->second;
00221
00222
00223 size_t pos = key.first.find(old_prefix);
00224 if (pos == 0)
00225 {
00226 std::string np = new_prefix + key.first.substr(old_prefix.size());
00227 prop->setPrefix(np);
00228 to_add[std::make_pair(np, key.second)] = prop;
00229 to_delete.push_back(it);
00230 }
00231 }
00232
00233 for (size_t i = 0; i < to_delete.size(); ++i)
00234 {
00235 properties_.erase(to_delete[i]);
00236 }
00237
00238 properties_.insert(to_add.begin(), to_add.end());
00239 }
00240
00241 void PropertyManager::deleteChildren( const PropertyBasePtr& property )
00242 {
00243 if (!property)
00244 {
00245 return;
00246 }
00247
00248 std::set<PropertyBasePtr> to_delete;
00249
00250 M_Property::iterator prop_it = properties_.begin();
00251 M_Property::iterator prop_end = properties_.end();
00252 for ( ; prop_it != prop_end; ++prop_it )
00253 {
00254 const PropertyBasePtr& child = prop_it->second;
00255
00256 PropertyBaseWPtr parent = child->getParent();
00257 if ( parent.lock() == property )
00258 {
00259 to_delete.insert( child );
00260 }
00261 }
00262
00263
00264
00265
00266
00267
00268 std::set<PropertyBasePtr>::iterator del_it = to_delete.begin();
00269 std::set<PropertyBasePtr>::iterator del_end = to_delete.end();
00270 for ( ; del_it != del_end; ++del_it )
00271 {
00272 deleteProperty( *del_it );
00273 }
00274
00275 to_delete.clear();
00276
00277
00278
00279
00280
00281 }
00282
00283 void PropertyManager::deleteByUserData( void* user_data )
00284 {
00285 std::set<PropertyBasePtr> to_delete;
00286
00287 M_Property::iterator it = properties_.begin();
00288 M_Property::iterator end = properties_.end();
00289 for ( ; it != end; ++it )
00290 {
00291 const PropertyBasePtr& property = it->second;
00292
00293 if ( property->getUserData() == user_data )
00294 {
00295 PropertyBasePtr parent = property->getParent().lock();
00296 if ( !parent || parent->getUserData() != user_data )
00297 {
00298 to_delete.insert( property );
00299 }
00300 }
00301 }
00302
00303
00304
00305
00306
00307
00308 std::set<PropertyBasePtr>::iterator prop_it = to_delete.begin();
00309 std::set<PropertyBasePtr>::iterator prop_end = to_delete.end();
00310 for ( ; prop_it != prop_end; ++prop_it )
00311 {
00312 deleteProperty( *prop_it );
00313 }
00314
00315
00316
00317
00318
00319 }
00320
00321 void PropertyManager::propertySet( const PropertyBasePtr& property )
00322 {
00323 boost::mutex::scoped_lock lock(changed_mutex_);
00324
00325 changed_properties_.insert(property);
00326 }
00327
00328 void PropertyManager::save(const boost::shared_ptr<Config>& config)
00329 {
00330 M_Property::iterator it = properties_.begin();
00331 M_Property::iterator end = properties_.end();
00332 for ( ; it != end; ++it )
00333 {
00334 const PropertyBasePtr& property = it->second;
00335
00336 if ( property->getSave() )
00337 {
00338 property->saveToConfig( config.get() );
00339 }
00340 }
00341 }
00342
00343 void PropertyManager::load(const boost::shared_ptr<Config>& config, const StatusCallback& cb)
00344 {
00345 config_ = config;
00346
00347 M_Property::iterator it = properties_.begin();
00348 M_Property::iterator end = properties_.end();
00349 for ( ; it != end; ++it )
00350 {
00351 const PropertyBasePtr& property = it->second;
00352
00353 if ( property->getSave() )
00354 {
00355 std::stringstream ss;
00356 ss << "Loading property [" << property->getPrefix() + property->getName() << "]";
00357 ROS_DEBUG_STREAM_NAMED("properties", ss.str());
00358
00359 if (cb)
00360 {
00361 cb(ss.str());
00362 }
00363
00364 property->loadFromConfig( config.get() );
00365 }
00366 }
00367
00368 if( grid_ )
00369 {
00370 grid_->update();
00371 }
00372 }
00373
00374 void PropertyManager::setPropertyTreeWidget(PropertyTreeWidget* grid)
00375 {
00376 ROS_ASSERT(!grid_);
00377 ROS_ASSERT(grid);
00378
00379 grid_ = grid;
00380
00381 M_Property::iterator it = properties_.begin();
00382 M_Property::iterator end = properties_.end();
00383 for (; it != end; ++it)
00384 {
00385 const PropertyBasePtr& property = it->second;
00386 property->setPropertyTreeWidget(grid_);
00387 property->writeToGrid();
00388 }
00389 }
00390
00391 void PropertyManager::refreshAll()
00392 {
00393 ROS_ASSERT(grid_);
00394
00395 M_Property::iterator it = properties_.begin();
00396 M_Property::iterator end = properties_.end();
00397 for (; it != end; ++it)
00398 {
00399 propertySet(it->second);
00400 }
00401
00402 update();
00403 }
00404
00405 void PropertyManager::clear()
00406 {
00407 properties_.clear();
00408 }
00409
00410 }