00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "scenemodel.h"
00021 #include <qmimedata.h>
00022 #include <KLocalizedString>
00023 #include <typeinfo>
00024
00025 #include <historymanager.h>
00026 #include <objectmanager.h>
00027 #include <core/debughelper.h>
00028 #include <engine/gameobject.h>
00029 #include <engine/component.h>
00030 #include <engine/gameproject.h>
00031 #include <engine/game.h>
00032
00033 using namespace GluonCreator;
00034
00035 class SceneModel::SceneModelPrivate
00036 {
00037 public:
00038 SceneModelPrivate()
00039 {
00040 root = 0;
00041 }
00042
00043 GluonEngine::GameObject* root;
00044
00045 int rowIndex( GluonEngine::GameObject* object ) const;
00046 };
00047
00048 SceneModel::SceneModel( QObject* parent ): QAbstractItemModel( parent ), d( new SceneModelPrivate )
00049 {
00050 setSupportedDragActions( Qt::MoveAction );
00051 connect( HistoryManager::instance(), SIGNAL( historyChanged( const QUndoCommand* ) ), SIGNAL( layoutChanged() ) );
00052 }
00053
00054 SceneModel::~SceneModel()
00055 {
00056 delete d;
00057 }
00058
00059 GluonEngine::GameObject* SceneModel::rootGameObject()
00060 {
00061 return d->root;
00062 }
00063
00064
00065 void SceneModel::setRootGameObject( GluonEngine::GameObject* obj )
00066 {
00067 if( obj )
00068 {
00069 d->root = obj;
00070 reset();
00071 }
00072 }
00073
00074 QVariant SceneModel::data( const QModelIndex& index, int role ) const
00075 {
00076 if( !index.isValid() )
00077 return QVariant();
00078
00079 if( role == Qt::DisplayRole || role == Qt::EditRole )
00080 {
00081 GluonEngine::GameObject* item = static_cast<GluonEngine::GameObject*>( index.internalPointer() );
00082
00083 if( item )
00084 return item->name();
00085 }
00086
00087 return QVariant();
00088 }
00089
00090 int SceneModel::columnCount( const QModelIndex& ) const
00091 {
00092 return 1;
00093 }
00094
00095 int SceneModel::rowCount( const QModelIndex& parent ) const
00096 {
00097 GluonEngine::GameObject* parentItem;
00098 if( parent.column() > 0 )
00099 return 0;
00100
00101 if( !parent.isValid() )
00102 parentItem = d->root;
00103 else
00104 parentItem = static_cast<GluonEngine::GameObject*>( parent.internalPointer() );
00105
00106 if( parentItem )
00107 return parentItem->childCount();
00108 return 0;
00109 }
00110
00111 QModelIndex SceneModel::parent( const QModelIndex& child ) const
00112 {
00113 if( !child.isValid() )
00114 return QModelIndex();
00115
00116 GluonEngine::GameObject* childItem = static_cast<GluonEngine::GameObject*>( child.internalPointer() );
00117
00118 if( !childItem )
00119 return QModelIndex();
00120
00121 GluonEngine::GameObject* parentItem = childItem->parentGameObject();
00122
00123 if( parentItem == d->root )
00124 return QModelIndex();
00125
00126 return createIndex( d->rowIndex( parentItem ), 0, parentItem );
00127 }
00128
00129 QModelIndex SceneModel::index( int row, int column, const QModelIndex& parent ) const
00130 {
00131 if( !hasIndex( row, column, parent ) )
00132 return QModelIndex();
00133
00134 GluonEngine::GameObject* parentItem;
00135
00136 if( !parent.isValid() )
00137 parentItem = d->root;
00138 else
00139 parentItem = static_cast<GluonEngine::GameObject*>( parent.internalPointer() );
00140
00141 GluonEngine::GameObject* childItem = parentItem->childGameObject( row );
00142 if( childItem )
00143 return createIndex( row, column, childItem );
00144 else
00145 return QModelIndex();
00146 }
00147
00148 QVariant SceneModel::headerData( int section, Qt::Orientation orientation, int role ) const
00149 {
00150 Q_UNUSED( section )
00151 Q_UNUSED( orientation )
00152 Q_UNUSED( role )
00153
00154 return QVariant();
00155 }
00156
00157 Qt::DropActions SceneModel::supportedDropActions() const
00158 {
00159 return Qt::CopyAction | Qt::MoveAction;
00160 }
00161
00162 Qt::ItemFlags SceneModel::flags( const QModelIndex& index ) const
00163 {
00164 if( index.isValid() )
00165 return QAbstractItemModel::flags( index ) | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
00166 else
00167 return QAbstractItemModel::flags( index ) | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled;
00168 }
00169
00170 QStringList
00171 SceneModel::mimeTypes() const
00172 {
00173 QStringList types;
00174 types << "application/gluon.object.gameobject";
00175 types << "application/gluon.text.componentclass";
00176 return types;
00177 }
00178
00179 QMimeData* SceneModel::mimeData( const QModelIndexList& indexes ) const
00180 {
00181 if( indexes.count() <= 0 )
00182 return 0;
00183
00184 QStringList types = mimeTypes();
00185 if( types.isEmpty() )
00186 return 0;
00187
00188 QMimeData* data = new QMimeData();
00189 QStringList names;
00190 foreach( const QModelIndex & index, indexes )
00191 {
00192 names.append( static_cast<GluonEngine::GameObject*>( index.internalPointer() )->fullyQualifiedName() );
00193 }
00194 data->setData( "application/gluon.object.gameobject", names.join( ";" ).toUtf8() );
00195
00196 return data;
00197 }
00198
00199 bool SceneModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent )
00200 {
00201 Q_UNUSED( column )
00202 DEBUG_FUNC_NAME
00203
00204 if( action == Qt::IgnoreAction )
00205 return false;
00206
00207 if( parent.isValid() )
00208 {
00209 GluonEngine::GameObject* gobj = qobject_cast<GluonEngine::GameObject*>(( QObject* )parent.internalPointer() );
00210
00211 if( !gobj )
00212 {
00213 gobj = d->root;
00214 }
00215
00216 foreach( const QString & something, data->formats() )
00217 {
00218 DEBUG_TEXT( QString( "Dropped mimetype %1 on object %2" ).arg( something ).arg( gobj->fullyQualifiedName() ) );
00219 }
00220
00221 if( data->hasFormat( "application/gluon.text.componentclass" ) )
00222 {
00223 QByteArray encodedData = data->data( "application/gluon.text.componentclass" );
00224 QDataStream stream( &encodedData, QIODevice::ReadOnly );
00225 QStringList newItems;
00226 int rows = 0;
00227
00228 while( !stream.atEnd() )
00229 {
00230 QString text;
00231 stream >> text;
00232 newItems << text;
00233 ++rows;
00234 }
00235 foreach( const QString & text, newItems )
00236 {
00237 DEBUG_TEXT( QString( "Adding component of class %1" ).arg( text ) );
00238 ObjectManager::instance()->createNewComponent( text, gobj );
00239 }
00240 }
00241
00242 if( data->hasFormat( "application/gluon.object.gameobject" ) )
00243 {
00244 QList<GluonEngine::GameObject*> objects;
00245
00246 QString dataString = data->data( "application/gluon.object.gameobject" );
00247 QStringList names = dataString.split( ';' );
00248 DEBUG_TEXT( QString( "Dropped names %1 on Scene Model" ).arg( dataString ) );
00249
00250 GluonEngine::GameProject* project = GluonEngine::Game::instance()->gameProject();
00251 foreach( const QString & name, names )
00252 {
00253 GluonEngine::GameObject* gobj = qobject_cast<GluonEngine::GameObject*>( project->findItemByName( name ) );
00254 if( gobj )
00255 objects.append( gobj );
00256 }
00257
00258 insertRows( row, objects, parent );
00259 emit layoutChanged();
00260 }
00261 }
00262
00263 return true;
00264 }
00265
00266 bool SceneModel::setData( const QModelIndex& index, const QVariant& value, int role )
00267 {
00268 if( !index.isValid() )
00269 return false;
00270
00271 if( role == Qt::EditRole )
00272 {
00273 static_cast<GluonCore::GluonObject*>( index.internalPointer() )->setName( value.toString() );
00274 emit dataChanged( index, index );
00275 return true;
00276 }
00277 return false;
00278 }
00279
00280 bool SceneModel::insertRows( int row, int count, const QModelIndex& parent )
00281 {
00282 beginInsertRows( parent, row, row + count - 1 );
00283
00284 GluonEngine::GameObject* obj = static_cast<GluonEngine::GameObject*>( parent.internalPointer() );
00285 if( !obj )
00286 obj = d->root;
00287
00288 for( int i = 0; i < count; ++i )
00289 {
00290 obj->addChildAt( new GluonEngine::GameObject(), i );
00291 }
00292
00293 endInsertRows();
00294 return true;
00295 }
00296
00297 bool SceneModel::insertRows( int row, const QList<GluonEngine::GameObject*> &children, const QModelIndex& parent )
00298 {
00299 DEBUG_FUNC_NAME;
00300 int count = children.count();
00301 beginInsertRows( parent, row, row + count );
00302
00303 GluonEngine::GameObject* pobj = static_cast<GluonEngine::GameObject*>( parent.internalPointer() );
00304 if( !pobj )
00305 pobj = d->root;
00306
00307 int index = row;
00308 foreach( GluonEngine::GameObject * obj, children )
00309 {
00310 pobj->addChildAt( obj, index++ );
00311 }
00312
00313 endInsertRows();
00314 return true;
00315 }
00316
00317 bool SceneModel::removeRows( int row, int count, const QModelIndex& parent )
00318 {
00319 beginRemoveRows( parent, row, row + count - 1 );
00320
00321 endRemoveRows();
00322 return true;
00323 }
00324
00325 int SceneModel::SceneModelPrivate::rowIndex( GluonEngine::GameObject* object ) const
00326 {
00327 if( object )
00328 {
00329 if( object->parentGameObject() )
00330 {
00331 return object->parentGameObject()->childIndex( object );
00332 }
00333 }
00334 return 0;
00335 }
00336
00337
00338
00339