property_tree_widget.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2012, 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 <QTimer>
00031 #include <QHash>
00032 #include <QSet>
00033 
00034 #include "rviz/properties/property.h"
00035 #include "rviz/properties/property_tree_delegate.h"
00036 #include "rviz/properties/splitter_handle.h"
00037 #include "rviz/properties/status_list.h"
00038 
00039 #include "rviz/properties/property_tree_widget.h"
00040 
00041 namespace rviz
00042 {
00043 
00044 PropertyTreeWidget::PropertyTreeWidget( QWidget* parent )
00045   : QTreeView( parent )
00046   , model_( NULL )
00047   , splitter_handle_( new SplitterHandle( this ))
00048 {
00049   setItemDelegateForColumn( 1, new PropertyTreeDelegate( this ));
00050   setDropIndicatorShown( true );
00051   setUniformRowHeights( true );
00052   setHeaderHidden( true );
00053   setDragEnabled( true );
00054   setAcceptDrops( true );
00055   setAnimated( true );
00056   setSelectionMode( QAbstractItemView::ExtendedSelection );
00057   setEditTriggers( QAbstractItemView::AllEditTriggers );
00058   setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
00059 
00060   QTimer* timer = new QTimer( this );
00061   connect( timer, SIGNAL( timeout() ), this, SLOT( update() ));
00062   timer->start( 100 );
00063 }
00064 
00065 void PropertyTreeWidget::currentChanged( const QModelIndex& new_current_index, const QModelIndex& previous_current_index )
00066 {
00067   QTreeView::currentChanged( new_current_index, previous_current_index );
00068   Q_EMIT currentPropertyChanged( static_cast<const Property*>( new_current_index.internalPointer() ));
00069 }
00070 
00071 void PropertyTreeWidget::selectionChanged( const QItemSelection& selected, const QItemSelection& deselected )
00072 {
00073   QTreeView::selectionChanged( selected, deselected );
00074   Q_EMIT selectionHasChanged();
00075 }
00076 
00077 void PropertyTreeWidget::setModel( PropertyTreeModel* model )
00078 {
00079   if( model_ )
00080   {
00081     disconnect( model_, SIGNAL( propertyHiddenChanged( const Property* )),
00082                 this, SLOT( propertyHiddenChanged( const Property* )));
00083     disconnect( model_, SIGNAL( expand( const QModelIndex& )),
00084                 this, SLOT( expand( const QModelIndex& )));
00085     disconnect( model_, SIGNAL( collapse( const QModelIndex& )),
00086                 this, SLOT( collapse( const QModelIndex& )));
00087   }
00088   model_ = model;
00089   QTreeView::setModel( model_ );
00090   if( model_ )
00091   {
00092     connect( model_, SIGNAL( propertyHiddenChanged( const Property* )),
00093              this, SLOT( propertyHiddenChanged( const Property* )), Qt::QueuedConnection );
00094     connect( model_, SIGNAL( expand( const QModelIndex& )),
00095              this, SLOT( expand( const QModelIndex& )));
00096     connect( model_, SIGNAL( collapse( const QModelIndex& )),
00097              this, SLOT( collapse( const QModelIndex& )));
00098 
00099     // this will trigger all hiddenChanged events to get re-fired
00100     model_->getRoot()->setModel( model_->getRoot()->getModel() );
00101   }
00102 
00103 }
00104 
00105 void PropertyTreeWidget::propertyHiddenChanged( const Property* property )
00106 {
00107   if( model_ )
00108   {
00109     setRowHidden( property->rowNumberInParent(), model_->parentIndex( property ), property->getHidden() );
00110   }
00111 }
00112 
00113 void PropertyTreeWidget::save( Config config ) const
00114 {
00115   saveExpandedEntries( config.mapMakeChild( "Expanded" ), QModelIndex(), "" );
00116 
00117   config.mapSetValue( "Splitter Ratio", splitter_handle_->getRatio() );
00118 }
00119 
00120 void PropertyTreeWidget::saveExpandedEntries( Config config, const QModelIndex& parent_index, const QString& prefix ) const
00121 {
00122   int num_children = model_->rowCount( parent_index );
00123   if( num_children > 0 )
00124   {
00125     QHash<QString, int> name_counts;
00126     for( int i = 0; i < num_children; i++ )
00127     {
00128       QModelIndex child_index = model_->index( i, 0, parent_index );
00129       Property* child = model_->getProp( child_index );
00130       QString child_name = child->getName();
00131       if( qobject_cast<StatusList*>( child ))
00132       {
00133         // StatusList objects change their name dynamically, so
00134         // normalize to a standard string.
00135         child_name = "Status";
00136       }
00137       int name_occurrence = ++( name_counts[ child_name ]);
00138       QString full_name = prefix + "/" + child_name + QString::number( name_occurrence );
00139       if( isExpanded( child_index ))
00140       {
00141         config.listAppendNew().setValue( full_name );
00142       }
00143       saveExpandedEntries( config, child_index, full_name );
00144     }
00145   }
00146 }
00147 
00148 void PropertyTreeWidget::load( const Config& config )
00149 {
00150   Config expanded_list_config = config.mapGetChild( "Expanded" );
00151   QSet<QString> expanded_full_names;
00152   int num_expanded = expanded_list_config.listLength();
00153   for( int i = 0; i < num_expanded; i++ )
00154   {
00155     expanded_full_names.insert( expanded_list_config.listChildAt( i ).getValue().toString() );
00156   }
00157   expandEntries( expanded_full_names, QModelIndex(), "" );
00158 
00159   float ratio;
00160   if( config.mapGetFloat( "Splitter Ratio", &ratio ))
00161   {
00162     splitter_handle_->setRatio( ratio );
00163   }
00164 }
00165 
00166 void PropertyTreeWidget::expandEntries( const QSet<QString>& expanded_full_names,
00167                                         const QModelIndex& parent_index,
00168                                         const QString& prefix )
00169 {
00170   int num_children = model_->rowCount( parent_index );
00171   if( num_children > 0 )
00172   {
00173     QHash<QString, int> name_counts;
00174     for( int i = 0; i < num_children; i++ )
00175     {
00176       QModelIndex child_index = model_->index( i, 0, parent_index );
00177       Property* child = model_->getProp( child_index );
00178       QString child_name = child->getName();
00179       if( qobject_cast<StatusList*>( child ))
00180       {
00181         child_name = "Status";
00182       }
00183       int name_occurrence = ++( name_counts[ child_name ]);
00184       QString full_name = prefix + "/" + child_name + QString::number( name_occurrence );
00185       if( expanded_full_names.contains( full_name ))
00186       {
00187         setExpanded( child_index, true );
00188       }
00189       expandEntries( expanded_full_names, child_index, full_name );
00190     }
00191   }
00192 }
00193 
00194 } // end namespace rviz


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust
autogenerated on Thu Aug 27 2015 15:02:27