property.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 <QColor>
00031 
00032 #include <tf/transform_listener.h>
00033 
00034 #include "rviz/config.h"
00035 #include "rviz/frame_manager.h"
00036 #include "rviz/properties/property.h"
00037 #include "rviz/properties/property_manager.h"
00038 #include "rviz/properties/property_widget_item.h"
00039 #include "rviz/properties/property_tree_widget.h"
00040 #include "rviz/properties/topic_info_variant.h"
00041 #include "rviz/properties/color_item.h"
00042 #include "rviz/properties/enum_item.h"
00043 #include "rviz/properties/edit_enum_item.h"
00044 #include "rviz/properties/compound_widget_item.h"
00045 
00046 namespace rviz
00047 {
00048 
00049 static const QColor ERROR_COLOR(178, 23, 46);
00050 static const QColor WARN_COLOR(222, 213, 17);
00051 
00052 void PropertyBase::writeToGrid()
00053 {
00054   // Any change events coming from the grid during a "writeToGrid()"
00055   // call are caused by us, not by the user, so make sure we don't
00056   // end up calling readFromGrid() as a result (i.e. ignore them).
00057   bool ign = grid_->setIgnoreChanges( true );
00058   doWriteToGrid();
00059   grid_->setIgnoreChanges( ign );
00060 }
00061 
00062 PropertyWidgetItem* getCategoryPGProperty(const CategoryPropertyWPtr& wprop)
00063 {
00064   CategoryPropertyPtr prop = wprop.lock();
00065 
00066   if (prop)
00067   {
00068     return prop->getWidgetItem();
00069   }
00070 
00071   return NULL;
00072 }
00073 
00074 void setPropertyHelpText(PropertyTreeWidget* grid, PropertyWidgetItem* widget_item, const std::string& text)
00075 {
00076   if( widget_item )
00077   {
00078     bool ign = grid->setIgnoreChanges( true );
00079     widget_item->setWhatsThis( 0, QString::fromStdString( text ));
00080     widget_item->setWhatsThis( 1, QString::fromStdString( text ));
00081     grid->setIgnoreChanges( ign );
00082   }
00083 }
00084 
00085 void setPropertyToColors(PropertyTreeWidget* grid, PropertyWidgetItem* widget_item, const QColor& fg_color, const QColor& bg_color, uint32_t column)
00086 {
00087   if( widget_item )
00088   {
00089     bool ign = grid->setIgnoreChanges( true );
00090     widget_item->setForeground( column, fg_color );
00091     widget_item->setBackground( column, bg_color );
00092     grid->setIgnoreChanges( ign );
00093   }
00094 }
00095 
00096 void setPropertyToError(PropertyTreeWidget* grid, PropertyWidgetItem* property, uint32_t column)
00097 {
00098   setPropertyToColors(grid, property, Qt::white, ERROR_COLOR, column);
00099 }
00100 
00101 void setPropertyToWarn(PropertyTreeWidget* grid, PropertyWidgetItem* property, uint32_t column)
00102 {
00103   setPropertyToColors(grid, property, Qt::white, WARN_COLOR, column);
00104 }
00105 
00106 void setPropertyToOK(PropertyTreeWidget* grid, PropertyWidgetItem* property, uint32_t column)
00107 {
00108   setPropertyToColors(grid, property, Qt::black, Qt::white, column);
00109 }
00110 
00111 void setPropertyToDisabled(PropertyTreeWidget* grid, PropertyWidgetItem* property, uint32_t column)
00112 {
00113   setPropertyToColors(grid, property, QColor(0x33, 0x44, 0x44), QColor(0xaa, 0xaa, 0xaa), column);
00114 }
00115 
00116 PropertyBase::PropertyBase()
00117 : grid_(NULL)
00118 , widget_item_(NULL)
00119 , user_data_(NULL)
00120 , manager_(NULL)
00121 {
00122 }
00123 
00124 PropertyBase::~PropertyBase()
00125 {
00126   delete widget_item_;
00127 }
00128 
00129 void PropertyBase::reset()
00130 {
00131   grid_ = 0;
00132 
00133   delete widget_item_;
00134   widget_item_ = 0;
00135 }
00136 
00137 void PropertyBase::setPropertyTreeWidget(PropertyTreeWidget* grid)
00138 {
00139   grid_ = grid;
00140 }
00141 
00142 void PropertyBase::hide()
00143 {
00144   if( widget_item_ )
00145   {
00146     widget_item_->setHidden( true );
00147   }
00148 }
00149 
00150 void PropertyBase::show()
00151 {
00152   if( widget_item_ )
00153   {
00154     widget_item_->setHidden( false );
00155   }
00156 }
00157 
00158 bool PropertyBase::isSelected()
00159 {
00160   if( widget_item_ && grid_ )
00161   {
00162     return grid_->currentItem() == widget_item_;
00163   }
00164 
00165   return false;
00166 }
00167 
00168 void PropertyBase::changed()
00169 {
00170   // I needed to purge boost::signal, and I didn't really want to make
00171   // every Property a QObject.  There is only one class which needs to
00172   // be notified of property changes, and that is PropertyManager.
00173   // Therefore I'm making an explicit function call connection instead
00174   // of a Qt signal or a boost signal.
00175   if( manager_ )
00176   {
00177     manager_->propertySet( shared_from_this() );
00178   }
00179 }
00180 
00181 StatusProperty::StatusProperty(const std::string& name, const std::string& prefix, const CategoryPropertyWPtr& parent, void* user_data)
00182 : name_(name)
00183 , prefix_(prefix)
00184 , parent_(parent)
00185 , top_widget_item_(0)
00186 , enabled_(true)
00187 , prefix_changed_(false)
00188 , top_status_(status_levels::Ok)
00189 {
00190   user_data_ = user_data;
00191 }
00192 
00193 StatusProperty::~StatusProperty()
00194 {
00195   delete top_widget_item_;
00196 }
00197 
00198 void StatusProperty::enable()
00199 {
00200   boost::mutex::scoped_lock lock(status_mutex_);
00201   enabled_ = true;
00202 
00203   changed();
00204 }
00205 
00206 void StatusProperty::disable()
00207 {
00208   clear();
00209 
00210   boost::mutex::scoped_lock lock(status_mutex_);
00211   enabled_ = false;
00212 
00213   changed();
00214 }
00215 
00216 void StatusProperty::setPrefix(const std::string& prefix)
00217 {
00218   boost::mutex::scoped_lock lock(status_mutex_);
00219   prefix_ = prefix;
00220   prefix_changed_ = true;
00221   changed();
00222 }
00223 
00224 void StatusProperty::clear()
00225 {
00226   boost::mutex::scoped_lock lock(status_mutex_);
00227 
00228   if (!enabled_)
00229   {
00230     return;
00231   }
00232 
00233   M_StringToStatus::iterator it = statuses_.begin();
00234   M_StringToStatus::iterator end = statuses_.end();
00235   for (; it != end; ++it)
00236   {
00237     Status& status = it->second;
00238     status.kill = true;
00239   }
00240 
00241   // Update the top level status here so that it can be used immediately
00242   updateTopLevelStatus();
00243 
00244   changed();
00245 }
00246 
00247 void StatusProperty::updateTopLevelStatus()
00248 {
00249   top_status_ = status_levels::Ok;
00250   M_StringToStatus::iterator it = statuses_.begin();
00251   M_StringToStatus::iterator end = statuses_.end();
00252   for (; it != end; ++it)
00253   {
00254     Status& status = it->second;
00255 
00256     if (status.kill)
00257     {
00258       continue;
00259     }
00260 
00261     if (status.level > top_status_)
00262     {
00263       top_status_ = status.level;
00264     }
00265   }
00266 }
00267 
00268 void StatusProperty::setStatus(StatusLevel level, const std::string& name, const std::string& text)
00269 {
00270   boost::mutex::scoped_lock lock(status_mutex_);
00271 
00272   if (!enabled_)
00273   {
00274     return;
00275   }
00276 
00277   Status& status = statuses_[name];
00278 
00279   // Status hasn't changed, return
00280   if (status.level == level && status.text == text && !status.kill)
00281   {
00282     return;
00283   }
00284 
00285   status.name = name;
00286   status.text = text;
00287   status.level = level;
00288   status.kill = false;
00289 
00290   // Update the top level status here so that it can be used immediately
00291   updateTopLevelStatus();
00292 
00293   changed();
00294 }
00295 
00296 void StatusProperty::deleteStatus(const std::string& name)
00297 {
00298   boost::mutex::scoped_lock lock(status_mutex_);
00299 
00300   if (!enabled_)
00301   {
00302     return;
00303   }
00304 
00305   M_StringToStatus::iterator it = statuses_.find(name);
00306   if (it != statuses_.end())
00307   {
00308     Status& status = it->second;
00309     status.kill = true;
00310   }
00311 
00312   // Update the top level status here so that it can be used immediately
00313   updateTopLevelStatus();
00314 
00315   changed();
00316 }
00317 
00318 void StatusProperty::doWriteToGrid()
00319 {
00320   boost::mutex::scoped_lock lock(status_mutex_);
00321 
00322   if ( !top_widget_item_ )
00323   {
00324     std::string top_name = name_ + "TopStatus";
00325 
00326     top_widget_item_ = new PropertyWidgetItem( this, "", false, false, true );
00327     top_widget_item_->addToParent();
00328   }
00329 
00330   bool expanded = top_widget_item_->isExpanded();
00331 
00332   top_status_ = status_levels::Ok;
00333 
00334   std::vector<std::string> to_erase;
00335   M_StringToStatus::iterator it = statuses_.begin();
00336   M_StringToStatus::iterator end = statuses_.end();
00337   for( ; it != end; ++it )
00338   {
00339     Status& status = it->second;
00340 
00341     if( status.kill )
00342     {
00343       to_erase.push_back(it->first);
00344       continue;
00345     }
00346 
00347     if( !status.widget_item )
00348     {
00349       status.widget_item = new PropertyWidgetItem( this, status.name, false, false, false );
00350       status.widget_item->addToParent( top_widget_item_ );
00351     }
00352 
00353     if( status.level > top_status_ )
00354     {
00355       top_status_ = status.level;
00356     }
00357 
00358     if( enabled_ )
00359     {
00360       switch( status.level )
00361       {
00362       case status_levels::Ok:
00363         setPropertyToOK( grid_, status.widget_item );
00364         break;
00365       case status_levels::Warn:
00366         setPropertyToColors( grid_, status.widget_item, WARN_COLOR, Qt::white );
00367         break;
00368       case status_levels::Error:
00369         setPropertyToColors( grid_, status.widget_item, ERROR_COLOR, Qt::white );
00370         break;
00371       }
00372     }
00373     else
00374     {
00375       setPropertyToDisabled( grid_, status.widget_item );
00376     }
00377 
00378     status.widget_item->setRightText( status.text );
00379     setPropertyHelpText( grid_, status.widget_item, status.text );
00380   }
00381 
00382   std::vector<std::string>::iterator kill_it = to_erase.begin();
00383   std::vector<std::string>::iterator kill_end = to_erase.end();
00384   for( ; kill_it != kill_end; ++kill_it )
00385   {
00386     Status& status = statuses_[*kill_it];
00387     delete status.widget_item;
00388     statuses_.erase( *kill_it );
00389   }
00390 
00391   top_widget_item_->setExpanded( expanded );
00392 
00393   std::string label;
00394   if( enabled_ )
00395   {
00396     switch( top_status_ )
00397     {
00398     case status_levels::Ok:
00399       setPropertyToColors( grid_, top_widget_item_, Qt::black, Qt::white );
00400       label = name_ + ": OK";
00401       break;
00402     case status_levels::Warn:
00403       setPropertyToColors( grid_, top_widget_item_, WARN_COLOR, Qt::white );
00404       label = name_ + ": Warning";
00405       break;
00406     case status_levels::Error:
00407       setPropertyToColors( grid_, top_widget_item_, ERROR_COLOR, Qt::white );
00408       label = name_ + ": Error";
00409       break;
00410     }
00411   }
00412   else
00413   {
00414     setPropertyToDisabled( grid_, top_widget_item_ );
00415     label = name_ + ": Disabled";
00416   }
00417 
00418   top_widget_item_->setLeftText( label );
00419   top_widget_item_->sortChildren( 0, Qt::AscendingOrder );
00420 }
00421 
00422 StatusLevel StatusProperty::getTopLevelStatus()
00423 {
00424   return top_status_;
00425 }
00426 
00427 void BoolProperty::doWriteToGrid()
00428 {
00429   if ( !widget_item_ )
00430   {
00431     widget_item_ = new PropertyWidgetItem( this, name_, hasSetter(), true );
00432     widget_item_->addToParent();
00433   }
00434   bool ign = getPropertyTreeWidget()->setIgnoreChanges( true );
00435 
00436   widget_item_->setData( 1, Qt::CheckStateRole, get() ? Qt::Checked : Qt::Unchecked );
00437   setPropertyHelpText(grid_, widget_item_, help_text_);
00438 
00439   getPropertyTreeWidget()->setIgnoreChanges( ign );
00440 }
00441 
00442 void BoolProperty::readFromGrid()
00443 {
00444   QVariant check_state = widget_item_->data( 1, Qt::CheckStateRole );
00445   set( check_state == Qt::Checked );
00446 }
00447 
00448 void BoolProperty::saveToConfig( Config* config )
00449 {
00450   config->set( prefix_ + name_, (int)get() );
00451 }
00452 
00453 void BoolProperty::loadFromConfig( Config* config )
00454 {
00455   int val;
00456   if( !config->get( prefix_ + name_, &val, get() ))
00457   {
00458     V_string::iterator it = legacy_names_.begin();
00459     V_string::iterator end = legacy_names_.end();
00460     for (; it != end; ++it)
00461     {
00462       if (config->get( prefix_ + *it, &val, get() ))
00463       {
00464         break;
00465       }
00466     }
00467   }
00468 
00469   set( (bool) val );
00470 }
00471 
00472 void IntProperty::setMin( int min )
00473 {
00474   if( widget_item_ )
00475   {
00476     widget_item_->min_ = min;
00477   }
00478   min_ = min;
00479 }
00480 
00481 void IntProperty::setMax( int max )
00482 {
00483   if (widget_item_)
00484   {
00485     widget_item_->max_ = max;
00486   }
00487   max_ = max;
00488 }
00489 
00490 void IntProperty::doWriteToGrid()
00491 {
00492   if ( !widget_item_ )
00493   {
00494     widget_item_ = new PropertyWidgetItem( this, name_, hasSetter() );
00495     widget_item_->addToParent();
00496     widget_item_->max_ = max_;
00497     widget_item_->min_ = min_;
00498   }
00499 
00500   widget_item_->setUserData( get() );
00501 
00502   setPropertyHelpText(grid_, widget_item_, help_text_);
00503 }
00504 
00505 void IntProperty::readFromGrid()
00506 {
00507   set( widget_item_->userData().toInt() );
00508 }
00509 
00510 void IntProperty::saveToConfig( Config* config )
00511 {
00512   config->set( prefix_ + name_, (int)get() );
00513 }
00514 
00515 void IntProperty::loadFromConfig( Config* config )
00516 {
00517   int val;
00518   if (!config->get( prefix_ + name_, &val, get() ))
00519   {
00520     V_string::iterator it = legacy_names_.begin();
00521     V_string::iterator end = legacy_names_.end();
00522     for (; it != end; ++it)
00523     {
00524       if (config->get( prefix_ + *it, &val, get() ))
00525       {
00526         break;
00527       }
00528     }
00529   }
00530 
00531   set( val );
00532 }
00533 
00534 void FloatProperty::setMin( float min )
00535 {
00536   if (widget_item_)
00537   {
00538     widget_item_->min_ = min;
00539   }
00540   min_ = min;
00541 }
00542 
00543 void FloatProperty::setMax( float max )
00544 {
00545   if (widget_item_)
00546   {
00547     widget_item_->max_ = max;
00548   }
00549   max_ = max;
00550 }
00551 
00552 void FloatProperty::doWriteToGrid()
00553 {
00554   if( !widget_item_ )
00555   {
00556     widget_item_ = new PropertyWidgetItem( this, name_, hasSetter() );
00557     widget_item_->addToParent();
00558     widget_item_->max_ = max_;
00559     widget_item_->min_ = min_;
00560   }
00561 
00562   widget_item_->setUserData( QVariant( get() ));
00563 
00564   setPropertyHelpText(grid_, widget_item_, help_text_);
00565 }
00566 
00567 void FloatProperty::readFromGrid()
00568 {
00569   set( widget_item_->userData().toFloat() );
00570 }
00571 
00572 void FloatProperty::saveToConfig( Config* config )
00573 {
00574   config->set( prefix_ + name_, (float)get() );
00575 }
00576 
00577 void FloatProperty::loadFromConfig( Config* config )
00578 {
00579   float val;
00580   if (!config->get( prefix_ + name_, &val, get() ))
00581   {
00582     V_string::iterator it = legacy_names_.begin();
00583     V_string::iterator end = legacy_names_.end();
00584     for (; it != end; ++it)
00585     {
00586       if (config->get( prefix_ + *it, &val, get() ))
00587       {
00588         break;
00589       }
00590     }
00591   }
00592 
00593   set( val );
00594 }
00595 
00596 void StringProperty::doWriteToGrid()
00597 {
00598   if( !widget_item_ )
00599   {
00600     widget_item_ = new PropertyWidgetItem( this, name_, hasSetter() );
00601     widget_item_->addToParent();
00602   }
00603 
00604   widget_item_->setUserData( QString::fromStdString( get() ));
00605 
00606   setPropertyHelpText( grid_, widget_item_, help_text_ );
00607 }
00608 
00609 void StringProperty::readFromGrid()
00610 {
00611   set( widget_item_->userData().toString().toStdString() );
00612 }
00613 
00614 void StringProperty::saveToConfig( Config* config )
00615 {
00616   config->set( prefix_ + name_, get() );
00617 }
00618 
00619 void StringProperty::loadFromConfig( Config* config )
00620 {
00621   std::string val;
00622   if (!config->get( prefix_ + name_, &val, get() ))
00623   {
00624     V_string::iterator it = legacy_names_.begin();
00625     V_string::iterator end = legacy_names_.end();
00626     for (; it != end; ++it)
00627     {
00628       if (config->get( prefix_ + *it, &val, get() ))
00629       {
00630         break;
00631       }
00632     }
00633   }
00634 
00635   set( val );
00636 }
00637 
00638 void ROSTopicStringProperty::doWriteToGrid()
00639 {
00640   if ( !widget_item_ )
00641   {
00642     widget_item_ = new PropertyWidgetItem( this, name_, hasSetter() );
00643     widget_item_->addToParent();
00644   }
00645   ros::master::TopicInfo topic;
00646   topic.name = get();
00647   topic.datatype = message_type_;
00648 
00649   widget_item_->setUserData( QVariant::fromValue( topic ));
00650 
00651   setPropertyHelpText(grid_, widget_item_, help_text_);
00652 }
00653 
00654 void ROSTopicStringProperty::readFromGrid()
00655 {
00656   ros::master::TopicInfo topic = widget_item_->userData().value<ros::master::TopicInfo>();
00657   set( topic.name );
00658 }
00659 
00660 void ColorProperty::doWriteToGrid()
00661 {
00662   if( !widget_item_ )
00663   {
00664     widget_item_ = new ColorItem( this );
00665     widget_item_->addToParent();
00666   }
00667 
00668   Color c = get();
00669   widget_item_->setUserData( QVariant::fromValue( QColor( c.r_ * 255, c.g_ * 255, c.b_ * 255 )));
00670 
00671   setPropertyHelpText( grid_, widget_item_, help_text_ );
00672 }
00673 
00674 void ColorProperty::readFromGrid()
00675 {
00676   QColor col = widget_item_->userData().value<QColor>();
00677   set( Color( col.red() / 255.0f, col.green() / 255.0f, col.blue() / 255.0f ) );
00678 }
00679 
00680 void ColorProperty::saveToConfig( Config* config )
00681 {
00682   Color c = get();
00683 
00684   config->set( prefix_ + name_ + "R", c.r_ );
00685   config->set( prefix_ + name_ + "G", c.g_ );
00686   config->set( prefix_ + name_ + "B", c.b_ );
00687 }
00688 
00689 void ColorProperty::loadFromConfig( Config* config )
00690 {
00691   Color c = get();
00692   float r, g, b;
00693   bool found = true;
00694   found &= config->get( prefix_ + name_ + "R", &r, c.r_ );
00695   found &= config->get( prefix_ + name_ + "G", &g, c.g_ );
00696   found &= config->get( prefix_ + name_ + "B", &b, c.b_ );
00697 
00698   if (!found)
00699   {
00700     V_string::iterator it = legacy_names_.begin();
00701     V_string::iterator end = legacy_names_.end();
00702     for (; it != end; ++it)
00703     {
00704       found = true;
00705       found &= config->get( prefix_ + *it + "R", &r, c.r_ );
00706       found &= config->get( prefix_ + *it + "G", &g, c.g_ );
00707       found &= config->get( prefix_ + *it + "B", &b, c.b_ );
00708 
00709       if (found)
00710       {
00711         break;
00712       }
00713     }
00714   }
00715 
00716   set( Color( r, g, b ) );
00717 }
00718 
00719 void EnumProperty::addOption( const std::string& name, int value )
00720 {
00721   boost::mutex::scoped_lock lock(mutex_);
00722   choices_.push_back( Choice( name, value ));
00723   changed();
00724 }
00725 
00726 void EnumProperty::clear ()
00727 {
00728   boost::mutex::scoped_lock lock(mutex_);
00729   choices_.clear();
00730   changed();
00731 }
00732 
00733 void EnumProperty::doWriteToGrid()
00734 {
00735   boost::mutex::scoped_lock lock(mutex_);
00736 
00737   if (isSelected())
00738   {
00739     changed();
00740     return;
00741   }
00742 
00743   if( !widget_item_ )
00744   {
00745     widget_item_ = new EnumItem( this );
00746     widget_item_->addToParent();
00747   }
00748   EnumItem* enum_item = dynamic_cast<EnumItem*>( widget_item_ );
00749   ROS_ASSERT( enum_item );
00750   enum_item->setChoices( choices_ );
00751   enum_item->setChoiceValue( get() );
00752 
00753   setPropertyHelpText( grid_, widget_item_, help_text_ );
00754 }
00755 
00756 void EnumProperty::readFromGrid()
00757 {
00758   EnumItem* enum_item = dynamic_cast<EnumItem*>( widget_item_ );
00759   ROS_ASSERT( enum_item );
00760   set( enum_item->getChoiceValue() );
00761 }
00762 
00763 void EnumProperty::saveToConfig( Config* config )
00764 {
00765   config->set( prefix_ + name_, (int)get() );
00766 }
00767 
00768 void EnumProperty::loadFromConfig( Config* config )
00769 {
00770   int val = INT_MAX;
00771   if( !config->get( prefix_ + name_, &val, get() ))
00772   {
00773     V_string::iterator it = legacy_names_.begin();
00774     V_string::iterator end = legacy_names_.end();
00775     for (; it != end; ++it)
00776     {
00777       if (config->get( prefix_ + *it, &val, get() ))
00778       {
00779         break;
00780       }
00781     }
00782   }
00783 
00784   set( val );
00785 }
00786 
00787 void EditEnumProperty::addOption( const std::string& name )
00788 {
00789   boost::mutex::scoped_lock lock(mutex_);
00790   choices_.push_back( name );
00791   changed();
00792 }
00793 
00794 void EditEnumProperty::setOptionCallback(const EditEnumOptionCallback& cb)
00795 {
00796   option_cb_ = cb;
00797   if( EditEnumItem* ee_item = dynamic_cast<EditEnumItem*>( widget_item_ ))
00798   {
00799     ee_item->setOptionCallback( cb );
00800   }
00801 
00802   changed();
00803 }
00804 
00805 void EditEnumProperty::clear ()
00806 {
00807   boost::mutex::scoped_lock lock(mutex_);
00808   choices_.clear();
00809   changed();
00810 }
00811 
00812 void EditEnumProperty::doWriteToGrid()
00813 {
00814   boost::mutex::scoped_lock lock(mutex_);
00815 
00816   if (isSelected())
00817   {
00818     changed();
00819     return;
00820   }
00821 
00822   if ( !widget_item_ )
00823   {
00824     widget_item_ = new EditEnumItem( this );
00825     widget_item_->addToParent();
00826   }
00827   EditEnumItem* ee_item = dynamic_cast<EditEnumItem*>( widget_item_ );
00828   ROS_ASSERT( ee_item );
00829   ee_item->setOptionCallback( option_cb_ );
00830   ee_item->setChoices( choices_ );
00831   ee_item->setChoice( get() );
00832   
00833   setPropertyHelpText(grid_, widget_item_, help_text_);
00834 }
00835 
00836 void EditEnumProperty::readFromGrid()
00837 {
00838   EditEnumItem* ee_item = dynamic_cast<EditEnumItem*>( widget_item_ );
00839   ROS_ASSERT( ee_item );
00840   set( ee_item->getChoice() );
00841 }
00842 
00843 void EditEnumProperty::saveToConfig( Config* config )
00844 {
00845   config->set( prefix_ + name_, get() );
00846 }
00847 
00848 void EditEnumProperty::loadFromConfig( Config* config )
00849 {
00850   std::string val;
00851   if (!config->get( prefix_ + name_, &val, get() ))
00852   {
00853     V_string::iterator it = legacy_names_.begin();
00854     V_string::iterator end = legacy_names_.end();
00855     for (; it != end; ++it)
00856     {
00857       if (config->get( prefix_ + *it, &val, get() ))
00858       {
00859         break;
00860       }
00861     }
00862   }
00863 
00864   set( val );
00865 }
00866 
00867 void TFFrameProperty::optionCallback( V_string& options_out )
00868 {
00869   typedef std::vector<std::string> V_string;
00870   FrameManager::instance()->getTFClient()->getFrameStrings( options_out );
00871   std::sort(options_out.begin(), options_out.end());
00872 
00873   options_out.insert( options_out.begin(), FIXED_FRAME_STRING );
00874 }
00875 
00876 void TFFrameProperty::doWriteToGrid()
00877 {
00878   EditEnumProperty::doWriteToGrid();
00879 
00880   EditEnumItem* ee_item = dynamic_cast<EditEnumItem*>( widget_item_ );
00881   ROS_ASSERT( ee_item );
00882   ee_item->setOptionCallback( boost::bind( &TFFrameProperty::optionCallback, this, _1 ));
00883 }
00884 
00885 CategoryProperty::~CategoryProperty()
00886 {
00887   if( widget_item_ )
00888   {
00889     // QTreeWidgetItem's destructor deletes all its children, but
00890     // PropertyManager also deletes each property (child or not)
00891     // individually.  Therefore before we destroy a category property
00892     // we need to disconnect (take) all of the widget item's children,
00893     // which will then be deleted by their respective Property
00894     // objects.
00895     widget_item_->takeChildren();
00896   }
00897 }
00898 
00899 void CategoryProperty::reset()
00900 {
00901   if( widget_item_ )
00902   {
00903     // QTreeWidgetItem's destructor deletes all its children, but
00904     // PropertyManager also deletes each property (child or not)
00905     // individually.  Therefore before we destroy a category property
00906     // we need to disconnect (take) all of the widget item's children,
00907     // which will then be deleted by their respective Property
00908     // objects.
00909     widget_item_->takeChildren();
00910   }
00911   Property<bool>::reset(); // manually chain reset() like a virtual destructor
00912 }
00913 
00914 void CategoryProperty::setLabel( const std::string& label )
00915 {
00916   label_ = label;
00917 
00918   if( widget_item_ )
00919   {
00920     widget_item_->setLeftText( label_ );
00921   }
00922 }
00923 
00924 void CategoryProperty::expand()
00925 {
00926   if (widget_item_)
00927   {
00928     widget_item_->setExpanded( true );
00929   }
00930 }
00931 
00932 void CategoryProperty::collapse()
00933 {
00934   if (widget_item_)
00935   {
00936     widget_item_->setExpanded( false );
00937   }
00938 }
00939 
00940 void CategoryProperty::doWriteToGrid()
00941 {
00942   if( !widget_item_ )
00943   {
00944     widget_item_ = new PropertyWidgetItem( this, label_, checkbox_, checkbox_, !checkbox_ );
00945     widget_item_->addToParent();
00946     widget_item_->setExpanded( true );
00947   }
00948   // setData() call must be before any setProperty...() calls, because
00949   // those can trigger the itemChanged() signal which ultimately
00950   // causes readFromGrid() to be called, which calls the Setter and
00951   // clobbers our new data.
00952   if( checkbox_ )
00953   {
00954     widget_item_->setData( 1, Qt::CheckStateRole, get() ? Qt::Checked : Qt::Unchecked );
00955   }
00956   setPropertyToColors( grid_, widget_item_, Qt::white, QColor( 4, 89, 127 ));
00957   setPropertyHelpText( grid_, widget_item_, help_text_ );
00958 }
00959 
00960 void CategoryProperty::readFromGrid()
00961 {
00962   if (checkbox_)
00963   {
00964     QVariant check_state = widget_item_->data( 1, Qt::CheckStateRole );
00965     ROS_ASSERT( !check_state.isNull() );
00966     set( check_state != Qt::Unchecked );
00967   }
00968 }
00969 
00970 void CategoryProperty::saveToConfig( Config* config )
00971 {
00972   if (checkbox_)
00973   {
00974     config->set( prefix_ + name_, get() );
00975   }
00976 }
00977 
00978 void CategoryProperty::loadFromConfig( Config* config )
00979 {
00980   if (checkbox_)
00981   {
00982     int val;
00983     if (!config->get( prefix_ + name_, &val, get() ))
00984     {
00985       V_string::iterator it = legacy_names_.begin();
00986       V_string::iterator end = legacy_names_.end();
00987       for (; it != end; ++it)
00988       {
00989         if (config->get( prefix_ + *it, &val, get() ))
00990         {
00991           break;
00992         }
00993       }
00994     }
00995 
00996     set( (bool) val );
00997   }
00998 }
00999 
01000 void CategoryProperty::setToOK()
01001 {
01002   if (grid_)
01003   {
01004     setPropertyToOK(grid_, widget_item_, 0);
01005     if( widget_item_ )
01006     {
01007       QFont font = widget_item_->font( 0 );
01008       font.setBold( true );
01009       widget_item_->setFont( 0, font );
01010     }
01011   }
01012 }
01013 
01014 void Vector3Property::doWriteToGrid()
01015 {
01016   if( !widget_item_ )
01017   {
01018     widget_item_ = new CompoundWidgetItem( this, name_, hasSetter() );
01019     widget_item_->addToParent();
01020     x_ = new PropertyWidgetItem( this, "X", hasSetter() );
01021     x_->addToParent( widget_item_ );
01022     y_ = new PropertyWidgetItem( this, "Y", hasSetter() );
01023     y_->addToParent( widget_item_ );
01024     z_ = new PropertyWidgetItem( this, "Z", hasSetter() );
01025     z_->addToParent( widget_item_ );
01026 
01027     widget_item_->setExpanded( false );
01028   }
01029   
01030   Ogre::Vector3 v = get();
01031   x_->setUserData( QVariant( v.x ));
01032   y_->setUserData( QVariant( v.y ));
01033   z_->setUserData( QVariant( v.z ));
01034 
01035   CompoundWidgetItem* cwi = dynamic_cast<CompoundWidgetItem*>( widget_item_ );
01036   ROS_ASSERT( cwi );
01037   cwi->updateText();
01038 
01039   setPropertyHelpText( grid_, widget_item_, help_text_ );
01040   setPropertyHelpText( grid_, x_, help_text_ );
01041   setPropertyHelpText( grid_, y_, help_text_ );
01042   setPropertyHelpText( grid_, z_, help_text_ );
01043 }
01044 
01045 void Vector3Property::readFromGrid()
01046 {
01047   float x = x_->userData().toFloat();
01048   float y = y_->userData().toFloat();
01049   float z = z_->userData().toFloat();
01050 
01051   CompoundWidgetItem* cwi = dynamic_cast<CompoundWidgetItem*>( widget_item_ );
01052   ROS_ASSERT( cwi );
01053   cwi->updateText();
01054 
01055   set( Ogre::Vector3( x, y, z ));
01056 }
01057 
01058 void Vector3Property::saveToConfig( Config* config )
01059 {
01060   Ogre::Vector3 v = get();
01061 
01062   config->set( prefix_ + name_ + "X", v.x );
01063   config->set( prefix_ + name_ + "Y", v.y );
01064   config->set( prefix_ + name_ + "Z", v.z );
01065 }
01066 
01067 void Vector3Property::loadFromConfig( Config* config )
01068 {
01069   Ogre::Vector3 v = get();
01070   float x, y, z;
01071   bool found = true;
01072   found &= config->get( prefix_ + name_ + "X", &x, v.x );
01073   found &= config->get( prefix_ + name_ + "Y", &y, v.y );
01074   found &= config->get( prefix_ + name_ + "Z", &z, v.z );
01075 
01076   if (!found)
01077   {
01078     V_string::iterator it = legacy_names_.begin();
01079     V_string::iterator end = legacy_names_.end();
01080     for (; it != end; ++it)
01081     {
01082       found = true;
01083       found &= config->get( prefix_ + *it + "X", &x, v.x );
01084       found &= config->get( prefix_ + *it + "Y", &y, v.y );
01085       found &= config->get( prefix_ + *it + "Z", &z, v.z );
01086 
01087       if (found)
01088       {
01089         break;
01090       }
01091     }
01092   }
01093 
01094   set( Ogre::Vector3( x, y, z ) );
01095 }
01096 
01097 void Vector3Property::reset()
01098 {
01099   Property<Ogre::Vector3>::reset();
01100 
01101   // Widget item children of widget_item_ are deleted by their parent,
01102   // in PropertyBase::reset(), so don't need to be deleted here.
01103   x_ = 0;
01104   y_ = 0;
01105   z_ = 0;
01106 }
01107 
01108 void QuaternionProperty::doWriteToGrid()
01109 {
01110   if( !widget_item_ )
01111   {
01112     widget_item_ = new CompoundWidgetItem( this, name_, hasSetter() );
01113     widget_item_->addToParent();
01114     x_ = new PropertyWidgetItem( this, "X", hasSetter() );
01115     x_->addToParent( widget_item_ );
01116     y_ = new PropertyWidgetItem( this, "Y", hasSetter() );
01117     y_->addToParent( widget_item_ );
01118     z_ = new PropertyWidgetItem( this, "Z", hasSetter() );
01119     z_->addToParent( widget_item_ );
01120     w_ = new PropertyWidgetItem( this, "W", hasSetter() );
01121     w_->addToParent( widget_item_ );
01122 
01123     widget_item_->setExpanded( false );
01124   }
01125   
01126   Ogre::Quaternion q = get();
01127   x_->setUserData( QVariant( q.x ));
01128   y_->setUserData( QVariant( q.y ));
01129   z_->setUserData( QVariant( q.z ));
01130   w_->setUserData( QVariant( q.w ));
01131 
01132   CompoundWidgetItem* cwi = dynamic_cast<CompoundWidgetItem*>( widget_item_ );
01133   ROS_ASSERT( cwi );
01134   cwi->updateText();
01135 
01136   setPropertyHelpText( grid_, widget_item_, help_text_ );
01137   setPropertyHelpText( grid_, x_, help_text_ );
01138   setPropertyHelpText( grid_, y_, help_text_ );
01139   setPropertyHelpText( grid_, z_, help_text_ );
01140   setPropertyHelpText( grid_, w_, help_text_ );
01141 }
01142 
01143 void QuaternionProperty::readFromGrid()
01144 {
01145   float x = x_->userData().toFloat();
01146   float y = y_->userData().toFloat();
01147   float z = z_->userData().toFloat();
01148   float w = w_->userData().toFloat();
01149 
01150   CompoundWidgetItem* cwi = dynamic_cast<CompoundWidgetItem*>( widget_item_ );
01151   ROS_ASSERT( cwi );
01152   cwi->updateText();
01153 
01154   set( Ogre::Quaternion( w, x, y, z ));
01155 }
01156 
01157 void QuaternionProperty::saveToConfig( Config* config )
01158 {
01159   Ogre::Quaternion q = get();
01160 
01161   config->set( prefix_ + name_ + "X", q.x );
01162   config->set( prefix_ + name_ + "Y", q.y );
01163   config->set( prefix_ + name_ + "Z", q.z );
01164   config->set( prefix_ + name_ + "W", q.w );
01165 }
01166 
01167 void QuaternionProperty::loadFromConfig( Config* config )
01168 {
01169   Ogre::Quaternion q = get();
01170   float x, y, z, w;
01171   bool found = true;
01172   found &= config->get( prefix_ + name_ + "X", &x, q.x );
01173   found &= config->get( prefix_ + name_ + "Y", &y, q.y );
01174   found &= config->get( prefix_ + name_ + "Z", &z, q.z );
01175   found &= config->get( prefix_ + name_ + "W", &w, q.w );
01176 
01177   if (!found)
01178   {
01179     V_string::iterator it = legacy_names_.begin();
01180     V_string::iterator end = legacy_names_.end();
01181     for (; it != end; ++it)
01182     {
01183       found = true;
01184       found &= config->get( prefix_ + *it + "X", &x, q.x );
01185       found &= config->get( prefix_ + *it + "Y", &y, q.y );
01186       found &= config->get( prefix_ + *it + "Z", &z, q.z );
01187       found &= config->get( prefix_ + *it + "W", &w, q.w );
01188 
01189       if (found)
01190       {
01191         break;
01192       }
01193     }
01194   }
01195 
01196   set( Ogre::Quaternion( w, x, y, z ) );
01197 }
01198 
01199 void QuaternionProperty::reset()
01200 {
01201   Property<Ogre::Quaternion>::reset();
01202 
01203   // Widget item children of widget_item_ are deleted by their parent,
01204   // in PropertyBase::reset(), so don't need to be deleted here.
01205   x_ = 0;
01206   y_ = 0;
01207   z_ = 0;
01208   w_ = 0;
01209 }
01210 
01211 }


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