property_manager.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008, Willow Garage, Inc.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the Willow Garage, Inc. nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
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   // "connect" the property's changed() callback to this->propertySet().
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   // "disconnect" from the property's changed() callback.
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       // search for any children of this property, and delete them as well
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   // search for any children of this property, and delete them as well
00198   deleteChildren( found_it->second );
00199 
00200   if( found_it->second )
00201   {
00202     // "disconnect" from the property's changed() callback.
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   // This kind of sucks... because properties are split into name + prefix, can't just lookup based on the prefix
00212   // so we have to iterate through
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     // We want to get everything that started with the old prefix, not just those that are an exact match
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 //  if (grid_)
00264 //  {
00265 //    grid_->Freeze();
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 //  if (grid_)
00278 //  {
00279 //    grid_->Thaw();
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 //  if (grid_)
00304 //  {
00305 //    grid_->Freeze();
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 //  if (grid_)
00316 //  {
00317 //    grid_->Thaw();
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 } // end namespace rviz


rviz_qt
Author(s): Dave Hershberger
autogenerated on Fri Dec 6 2013 20:56:53