Go to the documentation of this file.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
00278 QStringList PropertyTreeModel::mimeTypes() const
00279 {
00280 QStringList result;
00281 result.append( "application/x-rviz-" + drag_drop_class_ );
00282 return result;
00283 }
00284
00285 QModelIndex PropertyTreeModel::indexOf( Property* property ) const
00286 {
00287 if( property == root_property_ || !property )
00288 {
00289 return QModelIndex();
00290 }
00291 return createIndex( property->rowNumberInParent(), 0, property );
00292 }
00293
00294 void PropertyTreeModel::emitDataChanged( Property* property )
00295 {
00296 if( property->shouldBeSaved() )
00297 {
00298 Q_EMIT configChanged();
00299 }
00300 QModelIndex left_index = indexOf( property );
00301 QModelIndex right_index = createIndex( left_index.row(), 1, left_index.internalPointer() );
00302 Q_EMIT dataChanged( left_index, right_index );
00303 }
00304
00305 void PropertyTreeModel::beginInsert( Property* parent_property, int row_within_parent, int count )
00306 {
00307
00308
00309
00310
00311 beginInsertRows( indexOf( parent_property ), row_within_parent, row_within_parent + count - 1 );
00312 }
00313
00314 void PropertyTreeModel::endInsert()
00315 {
00316 endInsertRows();
00317
00318 }
00319
00320 void PropertyTreeModel::beginRemove( Property* parent_property, int row_within_parent, int count )
00321 {
00322
00323
00324
00325
00326 beginRemoveRows( indexOf( parent_property ), row_within_parent, row_within_parent + count - 1 );
00327 }
00328
00329 void PropertyTreeModel::endRemove()
00330 {
00331 endRemoveRows();
00332
00333 }
00334
00335 void PropertyTreeModel::expandProperty( Property* property )
00336 {
00337 Q_EMIT expand( indexOf( property ));
00338 }
00339
00340 void PropertyTreeModel::collapseProperty( Property* property )
00341 {
00342 Q_EMIT collapse( indexOf( property ));
00343 }
00344
00345 void PropertyTreeModel::printPersistentIndices()
00346 {
00347 QModelIndexList indexes = persistentIndexList();
00348 QModelIndexList::ConstIterator it = indexes.begin();
00349 for( ; it != indexes.end(); ++it )
00350 {
00351 if( !(*it).isValid() )
00352 {
00353 printf( " invalid index\n" );
00354 }
00355 else
00356 {
00357 Property* prop = getProp( *it );
00358 if( !prop )
00359 {
00360 printf( " null property\n" );
00361 }
00362 else
00363 {
00364 printf( " prop name '%s'\n", qPrintable( prop->getName() ));
00365 }
00366 }
00367 }
00368 }
00369
00370 }