00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "projectmodel.h"
00020
00021 #include "core/gluonobject.h"
00022 #include "core/debughelper.h"
00023 #include "engine/game.h"
00024 #include "engine/gameproject.h"
00025 #include "engine/asset.h"
00026 #include "engine/scene.h"
00027
00028 #include <KDebug>
00029 #include <KLocalizedString>
00030 #include <KMimeType>
00031 #include <KIcon>
00032
00033 #include <QtCore/QMimeData>
00034 #include <kmimetype.h>
00035 #include <QtCore/QFileInfo>
00036 #include <engine/filelocation.h>
00037 #include <QDir>
00038 #include <historymanager.h>
00039 #include <objectmanager.h>
00040
00041 using namespace GluonCreator;
00042
00043 class ProjectModel::ProjectModelPrivate
00044 {
00045 public:
00046 ProjectModelPrivate()
00047 {
00048 root = 0;
00049 project = 0;
00050 }
00051
00052 QObject* root;
00053 GluonEngine::GameProject* project;
00054
00055 QStringList acceptedMimeTypes;
00056 };
00057
00058 ProjectModel::ProjectModel( QObject* parent ): QAbstractItemModel( parent ), d( new ProjectModelPrivate )
00059 {
00060 connect( HistoryManager::instance(), SIGNAL( historyChanged( const QUndoCommand* ) ), SIGNAL( layoutChanged() ) );
00061 }
00062
00063 ProjectModel::~ProjectModel()
00064 {
00065 delete d;
00066 }
00067
00068
00069 GluonEngine::GameProject*
00070 ProjectModel::project()
00071 {
00072 return d->project;
00073 }
00074
00075 void
00076 ProjectModel::setProject( GluonEngine::GameProject* project )
00077 {
00078 if( project )
00079 {
00080 d->root = new QObject( this );
00081 d->project = project;
00082 project->setParent( d->root );
00083
00084 reset();
00085 }
00086 }
00087
00088 QVariant
00089 ProjectModel::data( const QModelIndex& index, int role ) const
00090 {
00091 if( !index.isValid() )
00092 return QVariant();
00093
00094 if( role == Qt::DecorationRole )
00095 {
00096 GluonCore::GluonObject* gobj = qobject_cast<GluonCore::GluonObject*>( static_cast<QObject*>( index.internalPointer() ) );
00097 if( gobj )
00098 {
00099 QVariant filename = gobj->property( "file" );
00100 QString classname( gobj->metaObject()->className() );
00101 if( classname == QLatin1String( "GluonCore::GluonObject" ) )
00102 {
00103
00104 return KIcon( "folder" );
00105 }
00106 if( qobject_cast<GluonEngine::Asset*>( gobj ) )
00107 {
00108 QIcon icon = qobject_cast<GluonEngine::Asset*>( gobj )->icon();
00109 if( icon.isNull() )
00110 {
00111 if( filename.isValid() )
00112 {
00113
00114
00115 QString name = filename.value<QString>();
00116 return KIcon( KMimeType::iconNameForUrl( KUrl( name ) ) );
00117 }
00118 else
00119 return KIcon( "unknown" );
00120 }
00121 return icon;
00122 }
00123 else
00124 return KIcon( "text-x-generic" );
00125 }
00126 }
00127
00128 if( role == Qt::DisplayRole || role == Qt::EditRole )
00129 {
00130 GluonCore::GluonObject* gobj = qobject_cast<GluonCore::GluonObject*>( static_cast<QObject*>( index.internalPointer() ) );
00131 if( gobj )
00132 return gobj->name();
00133 }
00134
00135 return QVariant();
00136 }
00137
00138 int
00139 ProjectModel::columnCount( const QModelIndex& parent ) const
00140 {
00141 Q_UNUSED( parent )
00142 return 1;
00143 }
00144
00145 int
00146 ProjectModel::rowCount( const QModelIndex& parent ) const
00147 {
00148 if( parent.column() > 0 )
00149 return 0;
00150
00151 QObject* parentItem = d->root;
00152 if( parent.isValid() )
00153 parentItem = static_cast<QObject*>( parent.internalPointer() );
00154
00155 if( parentItem )
00156 {
00157 if( qobject_cast<GluonCore::GluonObject*>( parentItem ) )
00158 {
00159 if( qobject_cast<GluonEngine::Scene*>( parentItem ) )
00160 return 0;
00161
00162 int childCount = 0;
00163 const QObjectList allChildren = parentItem->children();
00164 foreach( const QObject * child, allChildren )
00165 {
00166 if( qobject_cast<const GluonCore::GluonObject* >( child ) )
00167 ++childCount;
00168 }
00169 return childCount;
00170 }
00171 else
00172 return parentItem->children().count();
00173 }
00174
00175 return 0;
00176 }
00177
00178 QModelIndex
00179 ProjectModel::parent( const QModelIndex& child ) const
00180 {
00181 if( !child.isValid() )
00182 return QModelIndex();
00183
00184 QObject* childItem = static_cast<QObject*>( child.internalPointer() );
00185 QObject* parentItem = childItem->parent();
00186
00187 if( parentItem == d->root )
00188 return QModelIndex();
00189
00190 QObject* grandParent = parentItem->parent();
00191 if( grandParent )
00192 {
00193 int childCount = -1;
00194 const QObjectList allChildren = grandParent->children();
00195 foreach( const QObject * grandChild, allChildren )
00196 {
00197 if( qobject_cast<const GluonCore::GluonObject* >( grandChild ) )
00198 ++childCount;
00199 if( grandChild == parentItem )
00200 return createIndex( childCount, 0, parentItem );
00201 }
00202 }
00203 return createIndex( -1, 0, grandParent );
00204 }
00205
00206 QModelIndex
00207 ProjectModel::index( int row, int column, const QModelIndex& parent ) const
00208 {
00209 if( !hasIndex( row, column, parent ) )
00210 return QModelIndex();
00211
00212 QObject* parentItem = d->root;
00213 if( parent.isValid() )
00214 parentItem = static_cast<QObject*>( parent.internalPointer() );
00215
00216 int childCount = -1;
00217 const QObjectList allChildren = parentItem->children();
00218 foreach( const QObject * child, allChildren )
00219 {
00220 if( qobject_cast<const GluonCore::GluonObject*>( child ) )
00221 ++childCount;
00222 if( childCount == row )
00223 return createIndex( row, column, const_cast<QObject*>( child ) );
00224 }
00225
00226 return QModelIndex();
00227 }
00228
00229 QVariant
00230 ProjectModel::headerData( int section, Qt::Orientation orientation, int role ) const
00231 {
00232 Q_UNUSED( section )
00233 Q_UNUSED( orientation )
00234 Q_UNUSED( role )
00235
00236 return QVariant();
00237 }
00238
00239 Qt::DropActions
00240 ProjectModel::supportedDropActions() const
00241 {
00242 return Qt::CopyAction | Qt::MoveAction | Qt::LinkAction;
00243 }
00244
00245 Qt::ItemFlags
00246 ProjectModel::flags( const QModelIndex& index ) const
00247 {
00248 if( index.isValid() )
00249 {
00250 QObject* obj = static_cast<QObject*>( index.internalPointer() );
00251
00252
00253 if( obj->inherits( "GluonEngine::Asset" ) )
00254 {
00255 return QAbstractItemModel::flags( index ) | Qt::ItemIsDragEnabled | Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
00256 }
00257 else
00258 {
00259 return QAbstractItemModel::flags( index ) | Qt::ItemIsDragEnabled | Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled;
00260 }
00261 }
00262 else
00263 {
00264 return Qt::ItemIsDropEnabled;
00265 }
00266 }
00267
00268 QStringList
00269 ProjectModel::mimeTypes() const
00270 {
00271 if( d->acceptedMimeTypes.count() < 1 )
00272 {
00273 DEBUG_FUNC_NAME
00274 d->acceptedMimeTypes.append( "application/gluoncreator.projectmodel.gluonobject" );
00275 d->acceptedMimeTypes.append( "text/uri-list" );
00276 d->acceptedMimeTypes.append( GluonCore::GluonObjectFactory::instance()->objectMimeTypes() );
00277 foreach( const QString & theName, d->acceptedMimeTypes )
00278 {
00279 DEBUG_TEXT( QString( "%1" ).arg( theName ) );
00280 }
00281 }
00282
00283 return d->acceptedMimeTypes;
00284 }
00285
00286 bool
00287 ProjectModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent )
00288 {
00289 Q_UNUSED( row )
00290 Q_UNUSED( column )
00291 DEBUG_FUNC_NAME
00292
00293 if( action == Qt::IgnoreAction )
00294 return false;
00295
00296 if( data->hasUrls() )
00297 {
00298 foreach( const QUrl & theUrl, data->urls() )
00299 {
00300 ObjectManager::instance()->createNewAsset( theUrl.toLocalFile() );
00301 }
00302 }
00303 else if( data->hasFormat( "application/gluoncreator.projectmodel.gluonobject" ) )
00304 {
00305 }
00306 else
00307 {
00308 }
00309
00310 if( data->formats().length() < 1 )
00311 return false;
00312
00313 return QAbstractItemModel::dropMimeData( data, action, row, column, parent );
00314 }
00315
00316
00317 bool
00318 ProjectModel::setData( const QModelIndex& index, const QVariant& value, int role )
00319 {
00320 if( index.isValid() && role == Qt::EditRole )
00321 {
00322 static_cast<GluonCore::GluonObject*>( index.internalPointer() )->setName( value.toString() );
00323 emit dataChanged( index, index );
00324 return true;
00325 }
00326 return false;
00327 }
00328
00329 bool
00330 ProjectModel::removeRows( int row, int count, const QModelIndex& parent )
00331 {
00332 DEBUG_FUNC_NAME
00333 if( !parent.isValid() )
00334 return false;
00335
00336 if( count < 1 )
00337 return false;
00338
00339 GluonCore::GluonObject* parentObject = static_cast<GluonCore::GluonObject*>( parent.internalPointer() );
00340 DEBUG_TEXT( "Object removal begins..." );
00341
00342 beginRemoveRows( parent, row, row + count - 1 );
00343 for( int i = row; i < row + count; ++i )
00344 {
00345 DEBUG_TEXT( QString( "Removing child at row %1" ).arg( i ) );
00346 GluonCore::GluonObject* child = parentObject->child( row );
00347 if( parentObject->removeChild( child ) )
00348 delete child;
00349 }
00350 endRemoveRows();
00351
00352 return true;
00353 }
00354
00355 void ProjectModel::addChild( QObject* newChild, QModelIndex& parent )
00356 {
00357 if( parent.isValid() )
00358 {
00359 GluonCore::GluonObject* parentObject = static_cast<GluonCore::GluonObject*>( parent.internalPointer() );
00360
00361 int rcount = rowCount( parent );
00362 beginInsertRows( parent, rcount, rcount );
00363
00364 parentObject->addChild( qobject_cast<GluonCore::GluonObject*>( newChild ) );
00365
00366 endInsertRows();
00367 }
00368 }
00369
00370