00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "componentmodel.h"
00022 #include "core/gluonobject.h"
00023 #include "core/debughelper.h"
00024 #include "creator/lib/objectmanager.h"
00025
00026 #include <QtCore/QMimeData>
00027 #include <KLocalizedString>
00028 #include <engine/component.h>
00029
00030 namespace GluonCreator
00031 {
00032 struct ComponentModelItem
00033 {
00034 public:
00035 ComponentModelItem()
00036 : parent( 0 )
00037 {};
00038 ComponentModelItem( const ComponentModelItem& other )
00039 : name( other.name )
00040 , className( other.className )
00041 {}
00042 ~ComponentModelItem()
00043 {
00044 qDeleteAll( items );
00045 }
00046 int row()
00047 {
00048 if( parent )
00049 return parent->items.indexOf( this );
00050 return -1;
00051 }
00052
00053 QString name;
00054 QString className;
00055
00056 ComponentModelItem* parent;
00057 QList<ComponentModelItem*> items;
00058 QHash<QString, int> itemNames;
00059 };
00060 }
00061
00062
00063 using namespace GluonCreator;
00064
00065 class ComponentModel::ComponentModelPrivate
00066 {
00067 public:
00068 ComponentModelPrivate()
00069 : root( new ComponentModelItem() )
00070 {}
00071
00072 ComponentModelItem* root;
00073 };
00074
00075 ComponentModel::ComponentModel( QObject* parent )
00076 : QAbstractItemModel( parent )
00077 , d( new ComponentModelPrivate )
00078 {
00079 DEBUG_BLOCK
00080
00081 QHash<QString, const QMetaObject*> objectTypes = GluonCore::GluonObjectFactory::instance()->objectTypes();
00082 int i = 0;
00083 foreach( const QMetaObject * obj, objectTypes )
00084 {
00085 GluonEngine::Component* comp = qobject_cast<GluonEngine::Component*>( obj->newInstance() );
00086 if( comp )
00087 {
00088 QString name( obj->className() );
00089
00090 ComponentModelItem* item = new ComponentModelItem();
00091 item->name = ObjectManager::instance()->humanifyClassName( name );
00092 item->className = name;
00093
00094
00095 QString category = comp->category();
00096 if( !d->root->itemNames.contains( category ) )
00097 {
00098 ComponentModelItem* categoryItem = new ComponentModelItem();
00099 categoryItem->name = category;
00100 categoryItem->parent = d->root;
00101 d->root->items.append( categoryItem );
00102 d->root->itemNames.insert( category, i );
00103 ++i;
00104 }
00105
00106 item->parent = d->root->items[ d->root->itemNames[category] ];
00107 d->root->items[ d->root->itemNames[category] ]->itemNames.insert( item->name, d->root->items[ d->root->itemNames[category] ]->items.count() );
00108 d->root->items[ d->root->itemNames[category] ]->items.append( item );
00109 }
00110 else
00111 {
00112 QObject* anobj = obj->newInstance();
00113 if(anobj)
00114 {
00115 if(anobj->inherits("GluonEngine::Component"))
00116 {
00117 DEBUG_TEXT2("The Component %1 is lacking the Q_INTERFACES(GluonEngine::Component) macro", obj->className());
00118 }
00119 }
00120 }
00121 }
00122 }
00123
00124 ComponentModel::~ComponentModel()
00125 {
00126 delete d;
00127 }
00128
00129 QVariant
00130 ComponentModel::data( const QModelIndex& index, int role ) const
00131 {
00132 if( !index.isValid() )
00133 return QVariant();
00134
00135 const ComponentModelItem* item = static_cast<ComponentModelItem*>( index.internalPointer() );
00136
00137 switch( role )
00138 {
00139 case Qt::ToolTipRole:
00140 if( item->parent )
00141 return item->parent->name;
00142 else
00143 return QVariant();
00144 break;
00145 case Qt::DisplayRole:
00146 switch( index.column() )
00147 {
00148 case 2:
00149 return item->className;
00150 break;
00151 case 1:
00152 if( item->parent )
00153 return item->parent->name;
00154 else
00155 return QString();
00156 break;
00157 case 0:
00158 default:
00159 return item->name;
00160 break;
00161 }
00162 break;
00163 default:
00164 return QVariant();
00165 break;
00166 }
00167 return QVariant();
00168 }
00169
00170 QVariant
00171 ComponentModel::headerData( int section, Qt::Orientation orientation, int role ) const
00172 {
00173 if( role != Qt::DisplayRole )
00174 return QVariant();
00175
00176 if( orientation == Qt::Horizontal )
00177 {
00178 switch( section )
00179 {
00180 case 2:
00181 return i18n( "Class Name" );
00182 break;
00183 case 1:
00184 return i18n( "Category" );
00185 break;
00186 case 0:
00187 default:
00188 return i18n( "Component" );
00189 break;
00190 }
00191 }
00192 else
00193 return QString( "Row %1" ).arg( section );
00194 }
00195
00196 QModelIndex
00197 ComponentModel::index( int row, int column, const QModelIndex& parent ) const
00198 {
00199 if( !hasIndex( row, column, parent ) )
00200 return QModelIndex();
00201
00202 ComponentModelItem* parentItem;
00203
00204 if( !parent.isValid() )
00205 parentItem = d->root;
00206 else
00207 parentItem = static_cast<ComponentModelItem*>( parent.internalPointer() );
00208
00209 ComponentModelItem* childItem = parentItem->items[row];
00210 if( childItem )
00211 return createIndex( row, column, childItem );
00212 else
00213 return QModelIndex();
00214 }
00215
00216 QModelIndex
00217 ComponentModel::parent( const QModelIndex& child ) const
00218 {
00219 if( !child.isValid() )
00220 return QModelIndex();
00221
00222 ComponentModelItem* childItem = static_cast<ComponentModelItem*>( child.internalPointer() );
00223 ComponentModelItem* parentItem = childItem->parent;
00224
00225 if( parentItem == d->root )
00226 return QModelIndex();
00227
00228 return createIndex( parentItem->row(), 0, parentItem );
00229 }
00230
00231 Qt::ItemFlags
00232 ComponentModel::flags( const QModelIndex& index ) const
00233 {
00234 Qt::ItemFlags defaultFlags = QAbstractItemModel::flags( index );
00235 if( index.isValid() )
00236 {
00237 ComponentModelItem* item = static_cast<ComponentModelItem*>( index.internalPointer() );
00238 if( item->className.isEmpty() )
00239 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | defaultFlags;
00240 return Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsSelectable | defaultFlags;
00241 }
00242 else
00243 return defaultFlags;
00244 }
00245
00246 QStringList
00247 ComponentModel::mimeTypes() const
00248 {
00249 QStringList types;
00250 types << "application/gluon.text.componentclass";
00251 return types;
00252 }
00253
00254 QMimeData*
00255 ComponentModel::mimeData( const QModelIndexList& indexes ) const
00256 {
00257 QMimeData* mimeData = new QMimeData();
00258 QByteArray encodedData;
00259
00260 QDataStream stream( &encodedData, QIODevice::WriteOnly );
00261
00262
00263 foreach( const QModelIndex & index, indexes )
00264 {
00265 if( index.isValid() )
00266 {
00267 const ComponentModelItem* item = static_cast<ComponentModelItem*>( index.internalPointer() );
00268 if( item )
00269 {
00270 QString text = item->className;
00271 stream << text;
00272 }
00273 }
00274 }
00275
00276 mimeData->setData( "application/gluon.text.componentclass", encodedData );
00277 return mimeData;
00278 }
00279
00280 int
00281 ComponentModel::rowCount( const QModelIndex& parent ) const
00282 {
00283 if( parent.column() > 0 )
00284 return 0;
00285
00286 ComponentModelItem* parentItem;
00287 if( !parent.isValid() )
00288 parentItem = d->root;
00289 else
00290 parentItem = static_cast<ComponentModelItem*>( parent.internalPointer() );
00291
00292 return parentItem->items.count();
00293 }
00294
00295 int
00296 ComponentModel::columnCount( const QModelIndex& parent ) const
00297 {
00298 Q_UNUSED( parent );
00299 return 1;
00300 }
00301
00302