property.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, Willow Garage, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Willow Garage, Inc. nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include <stdio.h> // for printf()
31 #include <limits.h> // for INT_MIN and INT_MAX
32 
33 #include <QLineEdit>
34 #include <QSpinBox>
35 
38 
40 
41 namespace rviz
42 {
43 
45 {
46 public:
47  virtual Property* subProp( const QString& sub_name ) { return this; }
48 };
49 
53 
54 Property::Property( const QString& name,
55  const QVariant default_value,
56  const QString& description,
57  Property* parent,
58  const char *changed_slot,
59  QObject* receiver )
60  : value_( default_value )
61  , model_( 0 )
62  , child_indexes_valid_( false )
63  , parent_( 0 )
64  , description_( description )
65  , hidden_( false )
66  , is_read_only_( false )
67  , save_( true )
68 {
69  setName( name );
70  if( parent )
71  {
72  parent->addChild( this );
73  }
74  if( receiver == 0 )
75  {
76  receiver = parent;
77  }
78  if( receiver && changed_slot )
79  {
80  connect( this, SIGNAL( changed() ), receiver, changed_slot );
81  }
82 }
83 
85 {
86  // Disconnect myself from my parent.
87  if( getParent() )
88  {
89  getParent()->takeChild( this );
90  }
91  // Destroy my children.
92  for( int i = children_.size() - 1; i >= 0; i-- )
93  {
94  Property* child = children_.takeAt( i );
95  child->setParent( NULL );
96  delete child;
97  }
98 }
99 
100 void Property::removeChildren( int start_index, int count )
101 {
102  if( count < 0 )
103  {
104  count = children_.size() - start_index;
105  }
106 
107  if( count == 0 )
108  return;
109 
110  if( model_ )
111  {
112  model_->beginRemove( this, start_index, count );
113  }
114  // Destroy my children.
115  for( int i = start_index; i < start_index + count; i++ )
116  {
117  Property* child = children_.at( i );
118  child->setParent( NULL ); // prevent child destructor from calling getParent()->takeChild().
119  delete child;
120  }
121  children_.erase( children_.begin() + start_index, children_.begin() + start_index + count );
122  child_indexes_valid_ = false;
123  if( model_ )
124  {
125  model_->endRemove();
126  }
127  Q_EMIT childListChanged( this );
128 }
129 
130 bool Property::setValue( const QVariant& new_value )
131 {
132  if( new_value != value_ ) {
133  Q_EMIT aboutToChange();
134  value_ = new_value;
135  Q_EMIT changed();
136  if( model_ )
137  {
138  model_->emitDataChanged( this );
139  }
140  return true;
141  }
142  return false;
143 }
144 
145 QVariant Property::getValue() const
146 {
147  return value_;
148 }
149 
150 void Property::setName( const QString& name )
151 {
152  setObjectName( name );
153  if( model_ )
154  {
155  model_->emitDataChanged( this );
156  }
157 }
158 
159 QString Property::getName() const
160 {
161  return objectName();
162 }
163 
164 void Property::setDescription( const QString& description )
165 {
166  description_ = description;
167 }
168 
170 {
171  return description_;
172 }
173 
174 Property* Property::subProp( const QString& sub_name )
175 {
176  int size = numChildren();
177  for( int i = 0; i < size; i++ )
178  {
179  Property* prop = childAtUnchecked( i );
180  if( prop->getName() == sub_name )
181  {
182  return prop;
183  }
184  }
185 
186  // Print a useful error message showing the whole ancestry of this
187  // property, but don't crash.
188  QString ancestry = "";
189  for( Property* prop = this; prop != NULL; prop = prop->getParent() )
190  {
191  ancestry = "\"" + prop->getName() + "\"->" + ancestry;
192  }
193  printf( "ERROR: Undefined property %s \"%s\" accessed.\n", qPrintable( ancestry ), qPrintable( sub_name ));
194  return failprop_;
195 }
196 
197 Property* Property::childAt( int index ) const
198 {
199  // numChildren() and childAtUnchecked() can both be overridden, so
200  // call them instead of accessing our children_ list directly.
201  if( 0 <= index && index < numChildren() )
202  {
203  return childAtUnchecked( index );
204  }
205  return NULL;
206 }
207 
209 {
210  return children_.at( index );
211 }
212 
213 bool Property::contains( Property* possible_child ) const
214 {
215  int num_children = numChildren();
216  for( int i = 0; i < num_children; i++ )
217  {
218  if( childAtUnchecked( i ) == possible_child )
219  {
220  return true;
221  }
222  }
223  return false;
224 }
225 
227 {
228  return parent_;
229 }
230 
231 void Property::setParent( Property* new_parent )
232 {
233  parent_ = new_parent;
234 }
235 
236 QVariant Property::getViewData( int column, int role ) const
237 {
238  if ( role == Qt::TextColorRole &&
240  {
241 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
242  return Qt::gray;
243 #else
244  return QColor(Qt::gray);
245 #endif
246  }
247 
248  switch( column )
249  {
250  case 0: // left column: names
251  switch( role )
252  {
253  case Qt::DisplayRole: return getName();
254  case Qt::DecorationRole: return icon_;
255  default: return QVariant();
256  }
257  break;
258  case 1: // right column: values
259  switch( role )
260  {
261  case Qt::DisplayRole:
262  case Qt::EditRole: return (value_.type() == QVariant::Bool ? QVariant() : getValue());
263  case Qt::CheckStateRole:
264  if( value_.type() == QVariant::Bool )
265  return (value_.toBool() ? Qt::Checked : Qt::Unchecked);
266  else
267  return QVariant();
268  default: return QVariant();
269  }
270  break;
271  default: return QVariant();
272  }
273 }
274 
276 {
277  // Pass down the disableChildren flag
278  if ( parent_ )
279  {
280  return parent_->getDisableChildren();
281  }
282  return false;
283 }
284 
285 Qt::ItemFlags Property::getViewFlags( int column ) const
286 {
287  // if the parent propery is a disabled bool property or
288  // has its own enabled view flag not set, disable this property as well
289  Qt::ItemFlags enabled_flag = ( parent_ && parent_->getDisableChildren() ) ? Qt::NoItemFlags : Qt::ItemIsEnabled;
290 
291  if( column == 0 )
292  {
293  return enabled_flag | Qt::ItemIsSelectable;
294  }
295  if( value_.isValid() )
296  {
297  if( value_.type() == QVariant::Bool )
298  {
299  return Qt::ItemIsUserCheckable | enabled_flag | Qt::ItemIsSelectable;
300  }
301  return Qt::ItemIsEditable | enabled_flag | Qt::ItemIsSelectable;
302  }
303  return enabled_flag | Qt::ItemIsSelectable;
304 }
305 
306 bool Property::isAncestorOf( Property* possible_child ) const
307 {
308  Property* prop = possible_child->getParent();
309  while( prop != NULL && prop != this )
310  {
311  prop = prop->getParent();
312  }
313  return prop == this;
314 }
315 
317 {
318  for( int i = 0; i < numChildren(); i++ )
319  {
320  if( childAtUnchecked( i ) == child )
321  {
322  return takeChildAt( i );
323  }
324  }
325  return NULL;
326 }
327 
329 {
330  if( index < 0 || index >= children_.size() )
331  {
332  return NULL;
333  }
334  if( model_ )
335  {
336  model_->beginRemove( this, index, 1 );
337  }
338  Property* child = children_.takeAt( index );
339  child->setModel( NULL );
340  child->parent_ = NULL;
341  child_indexes_valid_ = false;
342  if( model_ )
343  {
344  model_->endRemove();
345  }
346  Q_EMIT childListChanged( this );
347  return child;
348 }
349 
350 void Property::addChild( Property* child, int index )
351 {
352  if( !child )
353  {
354  return;
355  }
356  int num_children = children_.size();
357  if( index < 0 || index > num_children )
358  {
359  index = num_children;
360  }
361  if( model_ )
362  {
363  model_->beginInsert( this, index );
364  }
365 
366  children_.insert( index, child );
367  child_indexes_valid_ = false;
368  child->setModel( model_ );
369  child->parent_ = this;
370 
371  if( model_ )
372  {
373  model_->endInsert();
374  }
375 
376  Q_EMIT childListChanged( this );
377 }
378 
380 {
381  model_ = model;
382  if( model_ && hidden_ )
383  {
385  }
386  int num_children = numChildren();
387  for( int i = 0; i < num_children; i++ )
388  {
389  Property* child = childAtUnchecked( i );
390  child->setModel( model );
391  }
392 }
393 
395 {
396  int num_children = numChildren();
397  for( int i = 0; i < num_children; i++ )
398  {
399  Property* child = childAtUnchecked( i );
400  child->row_number_within_parent_ = i;
401  }
402  child_indexes_valid_ = true;
403 }
404 
406 {
407  Property* parent = getParent();
408  if( !parent )
409  {
410  return -1;
411  }
412  if( !parent->child_indexes_valid_ )
413  {
414  parent->reindexChildren();
415  }
417 }
418 
419 void Property::moveChild( int from_index, int to_index )
420 {
421  children_.move( from_index, to_index );
422  child_indexes_valid_ = false;
423  Q_EMIT childListChanged( this );
424 }
425 
426 void Property::load( const Config& config )
427 {
428  if( config.getType() == Config::Value )
429  {
430  loadValue( config );
431  }
432  else if( config.getType() == Config::Map )
433  {
434  // A special map entry named "Value" means the value of this property, not a child.
435  // (If child "Value"does not exist, loadValue() will do nothing.)
436  loadValue( config.mapGetChild( "Value" ));
437 
438  // Loop over all child Properties.
439  int num_property_children = children_.size();
440  for( int i = 0; i < num_property_children; i++ )
441  {
442  Property* child = children_.at( i );
443  // Load the child Property with the config under the child property's name.
444  child->load( config.mapGetChild( child->getName() ));
445  }
446  }
447 }
448 
449 void Property::loadValue( const Config& config )
450 {
451  if( config.getType() == Config::Value )
452  {
453  switch( int( value_.type() ))
454  {
455  case QVariant::Int: setValue( config.getValue().toInt() ); break;
456  case QMetaType::Float:
457  case QVariant::Double: setValue( config.getValue().toDouble() ); break;
458  case QVariant::String: setValue( config.getValue().toString() ); break;
459  case QVariant::Bool: setValue( config.getValue().toBool() ); break;
460  default:
461  printf( "Property::loadValue() TODO: error handling - unexpected QVariant type %d.\n", int( value_.type() ));
462  break;
463  }
464  }
465 }
466 
467 void Property::save( Config config ) const
468 {
469  // If there are child properties, save them in a map from names to children.
470  if( children_.size() > 0 )
471  {
472  // If this property has child properties *and* a value itself,
473  // save the value in a special map entry named "Value".
474  if( value_.isValid() )
475  {
476  config.mapSetValue( "Value", value_ );
477  }
478  int num_properties = children_.size();
479  for( int i = 0; i < num_properties; i++ )
480  {
481  Property* prop = children_.at( i );
482  if( prop && prop->shouldBeSaved() )
483  {
484  prop->save( config.mapMakeChild( prop->getName() ));
485  }
486  }
487  }
488  else // Else there are no child properties, so just save the value itself.
489  {
490  if( value_.isValid() )
491  {
492  config.setValue( value_ );
493  }
494  else
495  {
496  // Empty Properties get saved as empty Maps instead of null values.
497  config.setType( Config::Map );
498  }
499  }
500 }
501 
502 QWidget* Property::createEditor( QWidget* parent,
503  const QStyleOptionViewItem& option )
504 {
505  switch( int( value_.type() ))
506  {
507  case QVariant::Int:
508  {
509  QSpinBox* editor = new QSpinBox( parent );
510  editor->setFrame( false );
511  editor->setRange( INT_MIN, INT_MAX );
512  return editor;
513  }
514  case QMetaType::Float:
515  case QVariant::Double:
516  {
517  FloatEdit* editor = new FloatEdit( parent );
518  return editor;
519  }
520  case QVariant::String:
521  default:
522  {
523  QLineEdit* editor = new QLineEdit( parent );
524  editor->setFrame( false );
525  return editor;
526  }
527  }
528 }
529 
530 void Property::setHidden( bool hidden )
531 {
532  if( hidden != hidden_ )
533  {
534  hidden_ = hidden;
535  if( model_ )
536  {
538  }
539  }
540 }
541 
543 {
544  if( model_ )
545  {
546  model_->expandProperty( this );
547  }
548 }
549 
551 {
552  if( model_ )
553  {
554  model_->collapseProperty( this );
555  }
556 }
557 
558 } // end namespace rviz
QList< Property * > children_
Definition: property.h:471
#define NULL
Definition: global.h:37
void setValue(const QVariant &value)
Ensures this is a valid Config object, sets the type to Value then sets the value.
Definition: config.cpp:305
Property * getParent() const
Return the parent Property.
Definition: property.cpp:226
QString description_
Definition: property.h:472
virtual void expand()
Expand (show the children of) this Property.
Definition: property.cpp:542
Type getType() const
Return the Type of the referenced Node, or Invalid if this Config does not refer to a Node at all...
Definition: config.cpp:167
int rowNumberInParent() const
Return the row number of this property within its parent, or -1 if it has no parent.
Definition: property.cpp:405
virtual ~Property()
Destructor. Removes this property from its parent&#39;s list of children.
Definition: property.cpp:84
void changed()
Emitted by setValue() just after the value has changed.
PropertyTreeModel * model_
Pointer to the PropertyTreeModel managing this property tree.
Definition: property.h:454
virtual void load(const Config &config)
Load the value of this property and/or its children from the given Config reference.
Definition: property.cpp:426
virtual bool setValue(const QVariant &new_value)
Set the new value for this property. Returns true if the new value is different from the old value...
Definition: property.cpp:130
bool child_indexes_valid_
True if row_number_within_parent_ of all children is valid, false if not.
Definition: property.h:461
A single element of a property tree, with a name, value, description, and possibly children...
Definition: property.h:100
bool shouldBeSaved() const
Returns true if the property is not read-only AND has data worth saving.
Definition: property.h:357
void childListChanged(Property *this_property)
Emitted after insertions and deletions of child Properties.
virtual QVariant getViewData(int column, int role) const
Return data appropriate for the given column (0 or 1) and role for this Property. ...
Definition: property.cpp:236
virtual void setName(const QString &name)
Set the name.
Definition: property.cpp:150
virtual bool getDisableChildren()
If true, the children of this property should set their ItemIsEnabled flag to false.
Definition: property.cpp:275
virtual void setDescription(const QString &description)
Set the description.
Definition: property.cpp:164
QVariant value_
This is the central property value. If you set it directly in a subclass, do so with care because man...
Definition: property.h:440
void beginRemove(Property *parent_property, int row_within_parent, int count=1)
virtual int numChildren() const
Return the number of child objects (Property or otherwise).
Definition: property.h:215
void mapSetValue(const QString &key, QVariant value)
Set a named child to the given value.
Definition: config.cpp:185
Property * takeChild(Property *child)
Remove a given child object and return a pointer to it.
Definition: property.cpp:316
int row_number_within_parent_
Definition: property.h:479
Configuration data storage class.
Definition: config.h:125
virtual void collapse()
Collapse (hide the children of) this Property.
Definition: property.cpp:550
bool isAncestorOf(Property *possible_child) const
Returns true if this is an ancestor of possible_child, meaning is the parent or parent of parent etc...
Definition: property.cpp:306
void loadValue(const Config &config)
Load the value of this property specifically, not including children.
Definition: property.cpp:449
virtual Property * subProp(const QString &sub_name)
Return the first child Property with the given name, or the FailureProperty if no child has the name...
Definition: property.cpp:174
void reindexChildren()
Set row_number_within_parent_ correctly for every child. Sets child_indexes_valid_ to true when done...
Definition: property.cpp:394
void expandProperty(Property *property)
Expand (show the children of) the given Property.
virtual void removeChildren(int start_index=0, int count=-1)
Remove and delete some or all child Properties. Does not change the value of this Property...
Definition: property.cpp:100
static Property * failprop_
The property returned by subProp() when the requested name is not found.
Definition: property.h:477
virtual void save(Config config) const
Write the value of this property and/or its children into the given Config reference.
Definition: property.cpp:467
Property * childAt(int index) const
Return the child Property with the given index, or NULL if the index is out of bounds or if the child...
Definition: property.cpp:197
void setParent(Property *new_parent)
Set parent property, without telling the parent.
Definition: property.cpp:231
void setModel(PropertyTreeModel *model)
Set the model managing this Property and all its child properties, recursively.
Definition: property.cpp:379
virtual void moveChild(int from_index, int to_index)
Move the child at from_index to to_index.
Definition: property.cpp:419
QVariant getValue() const
If this config object is valid and is a Value type, this returns its value. Otherwise it returns an i...
Definition: config.cpp:312
Config mapMakeChild(const QString &key)
Create a child node stored with the given key, and return the child.
Definition: config.cpp:190
Property * parent_
Definition: property.h:470
bool contains(Property *possible_child) const
Return true if the list of children includes possible_child, false if not.
Definition: property.cpp:213
virtual Property * takeChildAt(int index)
Take a child out of the child list, but don&#39;t destroy it.
Definition: property.cpp:328
bool is_read_only_
Definition: property.h:480
virtual void setHidden(bool hidden)
Hide or show this property in any PropertyTreeWidget viewing its parent.
Definition: property.cpp:530
Property(const QString &name=QString(), const QVariant default_value=QVariant(), const QString &description=QString(), Property *parent=0, const char *changed_slot=0, QObject *receiver=0)
Constructor.
Definition: property.cpp:54
void aboutToChange()
Emitted by setValue() just before the value has changed.
virtual void addChild(Property *child, int index=-1)
Add a child property.
Definition: property.cpp:350
void collapseProperty(Property *property)
Collapse (hide the children of) the given Property.
virtual QVariant getValue() const
Return the value of this Property as a QVariant. If the value has never been set, an invalid QVariant...
Definition: property.cpp:145
virtual QString getDescription() const
Return the description.
Definition: property.cpp:169
void emitDataChanged(Property *property)
void beginInsert(Property *parent_property, int row_within_parent, int count=1)
virtual QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option)
Create an editor widget to edit the value of this property.
Definition: property.cpp:502
virtual Property * subProp(const QString &sub_name)
Return the first child Property with the given name, or the FailureProperty if no child has the name...
Definition: property.cpp:47
Config mapGetChild(const QString &key) const
If the referenced Node is a Map and it has a child with the given key, return a reference to the chil...
Definition: config.cpp:201
void emitPropertyHiddenChanged(const Property *property)
Emit the propertyHiddenChanged() signal for the given Property.
virtual Property * childAtUnchecked(int index) const
Return the child Property with the given index, without checking whether the index is within bounds...
Definition: property.cpp:208
virtual QString getName() const
Return the name of this Property as a QString.
Definition: property.cpp:159
void setType(Type new_type)
Set the type of this Config Node.
Definition: config.cpp:172
virtual Qt::ItemFlags getViewFlags(int column) const
Return item flags appropriate for the given column (0 or 1) for this Property.
Definition: property.cpp:285


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust
autogenerated on Wed Aug 28 2019 04:01:51