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 <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
00055
00056
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
00171
00172
00173
00174
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
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
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
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
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
00890
00891
00892
00893
00894
00895 widget_item_->takeChildren();
00896 }
00897 }
00898
00899 void CategoryProperty::reset()
00900 {
00901 if( widget_item_ )
00902 {
00903
00904
00905
00906
00907
00908
00909 widget_item_->takeChildren();
00910 }
00911 Property<bool>::reset();
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
00949
00950
00951
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
01102
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
01204
01205 x_ = 0;
01206 y_ = 0;
01207 z_ = 0;
01208 w_ = 0;
01209 }
01210
01211 }