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 <stdio.h>
00031
00032 #include <QStringList>
00033 #include <QMimeData>
00034
00035 #include "rviz/properties/property.h"
00036
00037 #include "rviz/properties/property_tree_model.h"
00038
00039 namespace rviz
00040 {
00041
00042 PropertyTreeModel::PropertyTreeModel( Property* root_property, QObject* parent )
00043 : QAbstractItemModel( parent )
00044 , root_property_( root_property )
00045 {
00046 root_property_->setModel( this );
00047 }
00048
00049 PropertyTreeModel::~PropertyTreeModel()
00050 {
00051 delete root_property_;
00052 }
00053
00054 Property* PropertyTreeModel::getProp( const QModelIndex& index ) const
00055 {
00056 if( index.isValid() )
00057 {
00058 Property* prop = static_cast<Property*>( index.internalPointer() );
00059 if( prop )
00060 {
00061 return prop;
00062 }
00063 }
00064 return root_property_;
00065 }
00066
00067 Qt::ItemFlags PropertyTreeModel::flags( const QModelIndex& index ) const
00068 {
00069 if( !index.isValid() )
00070 {
00071 root_property_->getViewFlags( 0 );
00072 }
00073 Property* property = getProp( index );
00074 return property->getViewFlags( index.column() );
00075 }
00076
00077 QModelIndex PropertyTreeModel::index( int row, int column, const QModelIndex& parent_index ) const
00078 {
00079 if( parent_index.isValid() && parent_index.column() != 0 )
00080 {
00081 return QModelIndex();
00082 }
00083 Property* parent = getProp( parent_index );
00084
00085 Property* child = parent->childAt( row );
00086 if( child )
00087 {
00088 return createIndex( row, column, child );
00089 }
00090 else
00091 {
00092 return QModelIndex();
00093 }
00094 }
00095
00096 QModelIndex PropertyTreeModel::parent( const QModelIndex& child_index ) const
00097 {
00098 if( !child_index.isValid() )
00099 {
00100 return QModelIndex();
00101 }
00102 Property* child = getProp( child_index );
00103 return parentIndex( child );
00104 }
00105
00106 QModelIndex PropertyTreeModel::parentIndex( const Property* child ) const
00107 {
00108 if( !child )
00109 {
00110 return QModelIndex();
00111 }
00112 Property* parent = child->getParent();
00113 if( parent == root_property_ || !parent )
00114 {
00115 return QModelIndex();
00116 }
00117 return indexOf( parent );
00118 }
00119
00120 int PropertyTreeModel::rowCount( const QModelIndex& parent_index ) const
00121 {
00122 return getProp( parent_index )->numChildren();
00123 }
00124
00125 QVariant PropertyTreeModel::data( const QModelIndex& index, int role ) const
00126 {
00127 if( !index.isValid() )
00128 {
00129 return QVariant();
00130 }
00131
00132 return getProp( index )->getViewData( index.column(), role );
00133 }
00134
00135 QVariant PropertyTreeModel::headerData( int section, Qt::Orientation orientation, int role ) const
00136 {
00137
00138 return QVariant();
00139 }
00140
00141 bool PropertyTreeModel::setData( const QModelIndex& index, const QVariant& value, int role )
00142 {
00143 Property *property = getProp( index );
00144
00145 if( property->getValue().type() == QVariant::Bool && role == Qt::CheckStateRole )
00146 {
00147 if( property->setValue( value.toInt() != Qt::Unchecked ))
00148 {
00149 return true;
00150 }
00151 }
00152
00153 if( role != Qt::EditRole )
00154 {
00155 return false;
00156 }
00157
00158 if( property->setValue( value ))
00159 {
00160 return true;
00161 }
00162 return false;
00163 }
00164
00171 QMimeData* PropertyTreeModel::mimeData( const QModelIndexList& indexes ) const
00172 {
00173 if( indexes.count() <= 0 )
00174 {
00175 return 0;
00176 }
00177 QStringList types = mimeTypes();
00178 if( types.isEmpty() )
00179 {
00180 return 0;
00181 }
00182 QMimeData *data = new QMimeData();
00183 QString format = types.at(0);
00184 QByteArray encoded;
00185 QDataStream stream( &encoded, QIODevice::WriteOnly );
00186
00187 QModelIndexList::ConstIterator it = indexes.begin();
00188 for( ; it != indexes.end(); ++it )
00189 {
00190 if( (*it).column() == 0 )
00191 {
00192 void* pointer = (*it).internalPointer();
00193 stream.writeRawData( (char*)&pointer, sizeof( void* ));
00194 }
00195 }
00196
00197 data->setData( format, encoded );
00198 return data;
00199 }
00200
00208 bool PropertyTreeModel::dropMimeData( const QMimeData* data,
00209 Qt::DropAction action,
00210 int dest_row, int dest_column,
00211 const QModelIndex& dest_parent )
00212 {
00213 if( !data || action != Qt::MoveAction )
00214 {
00215 return false;
00216 }
00217 QStringList types = mimeTypes();
00218 if( types.isEmpty() )
00219 {
00220 return false;
00221 }
00222 QString format = types.at(0);
00223 if( !data->hasFormat( format ))
00224 {
00225 return false;
00226 }
00227 QByteArray encoded = data->data( format );
00228 QDataStream stream( &encoded, QIODevice::ReadOnly );
00229
00230 Property* dest_parent_property = getProp( dest_parent );
00231
00232 QList<Property*> source_properties;
00233
00234
00235 while( !stream.atEnd() )
00236 {
00237 void* pointer;
00238 if( sizeof( void* ) != stream.readRawData( (char*)&pointer, sizeof( void* )))
00239 {
00240 printf("ERROR: dropped mime data has invalid pointer data.\n");
00241 return false;
00242 }
00243 Property* prop = static_cast<Property*>( pointer );
00244 if( prop == dest_parent_property || prop->isAncestorOf( dest_parent_property ))
00245 {
00246
00247 return false;
00248 }
00249 source_properties.append( prop );
00250 }
00251
00252 if( dest_row == -1 )
00253 {
00254 dest_row = dest_parent_property->numChildren();
00255 }
00256 for( int i = 0; i < source_properties.size(); i++ )
00257 {
00258 Property* prop = source_properties.at( i );
00259
00260
00261
00262 int source_row = prop->rowNumberInParent();
00263
00264 prop->getParent()->takeChildAt( source_row );
00265
00266 if( dest_parent_property == prop->getParent() && dest_row > source_row )
00267 {
00268 dest_row--;
00269 }
00270
00271 dest_parent_property->addChild( prop, dest_row );
00272 dest_row++;
00273 }
00274
00275 return true;
00276 }
00277
00280 QStringList PropertyTreeModel::mimeTypes() const
00281 {
00282 QStringList result;
00283 result.append( "application/x-rvizpropertyitemmodeldatalist" );
00284 return result;
00285 }
00286
00287 QModelIndex PropertyTreeModel::indexOf( Property* property ) const
00288 {
00289 if( property == root_property_ || !property )
00290 {
00291 return QModelIndex();
00292 }
00293 return createIndex( property->rowNumberInParent(), 0, property );
00294 }
00295
00296 void PropertyTreeModel::emitDataChanged( Property* property )
00297 {
00298 if( property->shouldBeSaved() )
00299 {
00300 Q_EMIT configChanged();
00301 }
00302 QModelIndex left_index = indexOf( property );
00303 QModelIndex right_index = createIndex( left_index.row(), 1, left_index.internalPointer() );
00304 Q_EMIT dataChanged( left_index, right_index );
00305 }
00306
00307 void PropertyTreeModel::beginInsert( Property* parent_property, int row_within_parent, int count )
00308 {
00309
00310
00311
00312
00313 beginInsertRows( indexOf( parent_property ), row_within_parent, row_within_parent + count - 1 );
00314 }
00315
00316 void PropertyTreeModel::endInsert()
00317 {
00318 endInsertRows();
00319
00320 }
00321
00322 void PropertyTreeModel::beginRemove( Property* parent_property, int row_within_parent, int count )
00323 {
00324
00325
00326
00327
00328 beginRemoveRows( indexOf( parent_property ), row_within_parent, row_within_parent + count - 1 );
00329 }
00330
00331 void PropertyTreeModel::endRemove()
00332 {
00333 endRemoveRows();
00334
00335 }
00336
00337 void PropertyTreeModel::expandProperty( Property* property )
00338 {
00339 Q_EMIT expand( indexOf( property ));
00340 }
00341
00342 void PropertyTreeModel::collapseProperty( Property* property )
00343 {
00344 Q_EMIT collapse( indexOf( property ));
00345 }
00346
00347 void PropertyTreeModel::printPersistentIndices()
00348 {
00349 QModelIndexList indexes = persistentIndexList();
00350 QModelIndexList::ConstIterator it = indexes.begin();
00351 for( ; it != indexes.end(); ++it )
00352 {
00353 if( !(*it).isValid() )
00354 {
00355 printf( " invalid index\n" );
00356 }
00357 else
00358 {
00359 Property* prop = getProp( *it );
00360 if( !prop )
00361 {
00362 printf( " null property\n" );
00363 }
00364 else
00365 {
00366 printf( " prop name '%s'\n", qPrintable( prop->getName() ));
00367 }
00368 }
00369 }
00370 }
00371
00372 }