property_tree_widget.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 <QTimer>
31 #include <QHash>
32 #include <QSet>
33 
38 
40 
41 namespace rviz
42 {
43 
45  : QTreeView( parent )
46  , model_( NULL )
47  , splitter_handle_( new SplitterHandle( this ))
48 {
49  setItemDelegateForColumn( 1, new PropertyTreeDelegate( this ));
50  setDropIndicatorShown( true );
51  setUniformRowHeights( true );
52  setHeaderHidden( true );
53  setDragEnabled( true );
54  setAcceptDrops( true );
55  setAnimated( true );
56  setSelectionMode( QAbstractItemView::ExtendedSelection );
57  setEditTriggers( QAbstractItemView::AllEditTriggers );
58  setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
59 
60  QTimer* timer = new QTimer( this );
61  connect( timer, SIGNAL( timeout() ), this, SLOT( update() ));
62  timer->start( 100 );
63 }
64 
65 void PropertyTreeWidget::currentChanged( const QModelIndex& new_current_index, const QModelIndex& previous_current_index )
66 {
67  QTreeView::currentChanged( new_current_index, previous_current_index );
68  Q_EMIT currentPropertyChanged( static_cast<const Property*>( new_current_index.internalPointer() ));
69 }
70 
71 void PropertyTreeWidget::selectionChanged( const QItemSelection& selected, const QItemSelection& deselected )
72 {
73  QTreeView::selectionChanged( selected, deselected );
74  Q_EMIT selectionHasChanged();
75 }
76 
78 {
79  if( model_ )
80  {
81  disconnect( model_, SIGNAL( propertyHiddenChanged( const Property* )),
82  this, SLOT( propertyHiddenChanged( const Property* )));
83  disconnect( model_, SIGNAL( expand( const QModelIndex& )),
84  this, SLOT( expand( const QModelIndex& )));
85  disconnect( model_, SIGNAL( collapse( const QModelIndex& )),
86  this, SLOT( collapse( const QModelIndex& )));
87  }
88  model_ = model;
89  QTreeView::setModel( model_ );
90  if( model_ )
91  {
92  connect( model_, SIGNAL( propertyHiddenChanged( const Property* )),
93  this, SLOT( propertyHiddenChanged( const Property* )), Qt::QueuedConnection );
94  connect( model_, SIGNAL( expand( const QModelIndex& )),
95  this, SLOT( expand( const QModelIndex& )));
96  connect( model_, SIGNAL( collapse( const QModelIndex& )),
97  this, SLOT( collapse( const QModelIndex& )));
98 
99  // this will trigger all hiddenChanged events to get re-fired
101  }
102 
103 }
104 
106 {
107  if( model_ )
108  {
109  setRowHidden( property->rowNumberInParent(), model_->parentIndex( property ), property->getHidden() );
110  }
111 }
112 
113 void PropertyTreeWidget::save( Config config ) const
114 {
115  saveExpandedEntries( config.mapMakeChild( "Expanded" ), QModelIndex(), "" );
116 
117  config.mapSetValue( "Splitter Ratio", splitter_handle_->getRatio() );
118 }
119 
120 void PropertyTreeWidget::saveExpandedEntries( Config config, const QModelIndex& parent_index, const QString& prefix ) const
121 {
122  int num_children = model_->rowCount( parent_index );
123  if( num_children > 0 )
124  {
125  QHash<QString, int> name_counts;
126  for( int i = 0; i < num_children; i++ )
127  {
128  QModelIndex child_index = model_->index( i, 0, parent_index );
129  Property* child = model_->getProp( child_index );
130  QString child_name = child->getName();
131  if( qobject_cast<StatusList*>( child ))
132  {
133  // StatusList objects change their name dynamically, so
134  // normalize to a standard string.
135  child_name = "Status";
136  }
137  int name_occurrence = ++( name_counts[ child_name ]);
138  QString full_name = prefix + "/" + child_name + QString::number( name_occurrence );
139  if( isExpanded( child_index ))
140  {
141  config.listAppendNew().setValue( full_name );
142  }
143  saveExpandedEntries( config, child_index, full_name );
144  }
145  }
146 }
147 
148 void PropertyTreeWidget::load( const Config& config )
149 {
150  Config expanded_list_config = config.mapGetChild( "Expanded" );
151  QSet<QString> expanded_full_names;
152  int num_expanded = expanded_list_config.listLength();
153  for( int i = 0; i < num_expanded; i++ )
154  {
155  expanded_full_names.insert( expanded_list_config.listChildAt( i ).getValue().toString() );
156  }
157  expandEntries( expanded_full_names, QModelIndex(), "" );
158 
159  float ratio;
160  if( config.mapGetFloat( "Splitter Ratio", &ratio ))
161  {
162  splitter_handle_->setRatio( ratio );
163  }
164 }
165 
166 void PropertyTreeWidget::expandEntries( const QSet<QString>& expanded_full_names,
167  const QModelIndex& parent_index,
168  const QString& prefix )
169 {
170  int num_children = model_->rowCount( parent_index );
171  if( num_children > 0 )
172  {
173  QHash<QString, int> name_counts;
174  for( int i = 0; i < num_children; i++ )
175  {
176  QModelIndex child_index = model_->index( i, 0, parent_index );
177  Property* child = model_->getProp( child_index );
178  QString child_name = child->getName();
179  if( qobject_cast<StatusList*>( child ))
180  {
181  child_name = "Status";
182  }
183  int name_occurrence = ++( name_counts[ child_name ]);
184  QString full_name = prefix + "/" + child_name + QString::number( name_occurrence );
185  if( expanded_full_names.contains( full_name ))
186  {
187  setExpanded( child_index, true );
188  }
189  expandEntries( expanded_full_names, child_index, full_name );
190  }
191  }
192 }
193 
194 } // end namespace rviz
#define NULL
Definition: global.h:37
void setModel(PropertyTreeModel *model)
Set the data model this widget should view.
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
float getRatio()
Get the ratio of the parent&#39;s left column to the parent widget width.
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 QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
int listLength() const
Returns the length of the List in this Node, or 0 if this Node does not have type List...
Definition: config.cpp:317
Config listChildAt(int i) const
Return the i&#39;th child in the list, if the referenced Node has type List. Returns an Invalid Config if...
Definition: config.cpp:322
A single element of a property tree, with a name, value, description, and possibly children...
Definition: property.h:100
bool mapGetFloat(const QString &key, float *value_out) const
Convenience function for looking up a named float.
Definition: config.cpp:245
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const
Return the number of rows under the given parent index.
A tall skinny invisible widget providing left-right sliding column separator adjustment for a two-col...
void mapSetValue(const QString &key, QVariant value)
Set a named child to the given value.
Definition: config.cpp:185
void update(const std::string &key, const XmlRpc::XmlRpcValue &v)
Configuration data storage class.
Definition: config.h:125
QModelIndex parentIndex(const Property *child) const
Same as parent() but taking a Property pointer instead of an index.
void load(const Config &config)
Read state from the given Config.
void setModel(PropertyTreeModel *model)
Set the model managing this Property and all its child properties, recursively.
Definition: property.cpp:379
void currentPropertyChanged(const Property *new_current_property)
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
virtual void propertyHiddenChanged(const Property *property)
PropertyTreeModel * getModel() const
Return the model managing this Property and its childrent.
Definition: property.h:335
void save(Config config) const
Write state to the given Config.
virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
Called whenever selection changes. Calls QTreeView implementation then emits selectionHasChanged().
Config listAppendNew()
Ensure the referenced Node is of type List, append a new Empty Node to the end of the list...
Definition: config.cpp:334
void expandEntries(const QSet< QString > &expanded_full_names, const QModelIndex &parent_index, const QString &prefix)
Recursively expand entries whose full names appear in expanded_full_names.
void setRatio(float ratio)
Set the ratio of the parent&#39;s left column to the parent widget width.
PropertyTreeWidget(QWidget *parent=0)
Property * getProp(const QModelIndex &index) const
return the Property at the given index, or the root property if the index is invalid.
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
Property * getRoot() const
virtual QString getName() const
Return the name of this Property as a QString.
Definition: property.cpp:159
void saveExpandedEntries(Config config, const QModelIndex &parent_index, const QString &prefix) const
Recursively write full names of properties which are expanded in this view to the given Config...
virtual void currentChanged(const QModelIndex &current, const QModelIndex &previous)
Called whenever current item changes. Calls QTreeView implementation then emits currentPropertyChange...


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