00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <QDir>
00016 #include <QApplication>
00017 #include <QStyle>
00018
00019 #include "qgis.h"
00020 #include "qgsapplication.h"
00021 #include "qgsdataprovider.h"
00022 #include "qgsmimedatautils.h"
00023 #include "qgslogger.h"
00024 #include "qgsproviderregistry.h"
00025
00026 #include "qgsbrowsermodel.h"
00027
00028 #include <QSettings>
00029
00030 QgsBrowserModel::QgsBrowserModel( QObject *parent ) :
00031 QAbstractItemModel( parent )
00032 {
00033 addRootItems();
00034 }
00035
00036 QgsBrowserModel::~QgsBrowserModel()
00037 {
00038 removeRootItems();
00039 }
00040
00041 void QgsBrowserModel::addRootItems()
00042 {
00043
00044 QgsDirectoryItem *item = new QgsDirectoryItem( NULL, tr( "Home" ), QDir::homePath() );
00045 QStyle *style = QApplication::style();
00046 QIcon homeIcon( style->standardPixmap( QStyle::SP_DirHomeIcon ) );
00047 item->setIcon( homeIcon );
00048 connectItem( item );
00049 mRootItems << item;
00050
00051
00052 QgsFavouritesItem *favitem = new QgsFavouritesItem( NULL, tr( "Favourites" ) );
00053 if ( favitem )
00054 {
00055 connectItem( favitem );
00056 mRootItems << favitem;
00057 }
00058
00059
00060 foreach( QFileInfo drive, QDir::drives() )
00061 {
00062 QString path = drive.absolutePath();
00063 QgsDirectoryItem *item = new QgsDirectoryItem( NULL, path, path );
00064
00065 connectItem( item );
00066 mRootItems << item;
00067 }
00068
00069
00070 QStringList providersList = QgsProviderRegistry::instance()->providerList();
00071 providersList.sort();
00072 foreach( QString key, providersList )
00073 {
00074 QLibrary *library = QgsProviderRegistry::instance()->providerLibrary( key );
00075 if ( !library )
00076 continue;
00077
00078 dataCapabilities_t * dataCapabilities = ( dataCapabilities_t * ) cast_to_fptr( library->resolve( "dataCapabilities" ) );
00079 if ( !dataCapabilities )
00080 {
00081 QgsDebugMsg( library->fileName() + " does not have dataCapabilities" );
00082 continue;
00083 }
00084
00085 int capabilities = dataCapabilities();
00086 if ( capabilities == QgsDataProvider::NoDataCapabilities )
00087 {
00088 QgsDebugMsg( library->fileName() + " does not have any dataCapabilities" );
00089 continue;
00090 }
00091
00092 dataItem_t * dataItem = ( dataItem_t * ) cast_to_fptr( library->resolve( "dataItem" ) );
00093 if ( !dataItem )
00094 {
00095 QgsDebugMsg( library->fileName() + " does not have dataItem" );
00096 continue;
00097 }
00098
00099 QgsDataItem *item = dataItem( "", NULL );
00100 if ( item )
00101 {
00102 QgsDebugMsg( "Add new top level item : " + item->name() );
00103 connectItem( item );
00104 mRootItems << item;
00105 }
00106 }
00107 }
00108
00109 void QgsBrowserModel::removeRootItems()
00110 {
00111 foreach( QgsDataItem* item, mRootItems )
00112 {
00113 delete item;
00114 }
00115
00116 mRootItems.clear();
00117 }
00118
00119
00120 Qt::ItemFlags QgsBrowserModel::flags( const QModelIndex & index ) const
00121 {
00122 if ( !index.isValid() )
00123 return 0;
00124
00125 Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
00126
00127 QgsDataItem* ptr = ( QgsDataItem* ) index.internalPointer();
00128 if ( ptr->type() == QgsDataItem::Layer )
00129 {
00130 QgsLayerItem *layer = ( QgsLayerItem* ) ptr;
00131 if ( layer->providerKey() != "wms" )
00132 {
00133 flags |= Qt::ItemIsDragEnabled;
00134 }
00135 }
00136 if ( ptr->acceptDrop() )
00137 flags |= Qt::ItemIsDropEnabled;
00138 return flags;
00139 }
00140
00141 QVariant QgsBrowserModel::data( const QModelIndex &index, int role ) const
00142 {
00143 if ( !index.isValid() )
00144 return QVariant();
00145
00146 QgsDataItem *item = dataItem( index );
00147 if ( !item )
00148 {
00149 return QVariant();
00150 }
00151 else if ( role == Qt::DisplayRole )
00152 {
00153 return item->name();
00154 }
00155 else if ( role == Qt::ToolTipRole )
00156 {
00157 return item->toolTip();
00158 }
00159 else if ( role == Qt::DecorationRole && index.column() == 0 )
00160 {
00161 return item->icon();
00162 }
00163 else
00164 {
00165
00166 return QVariant();
00167 }
00168 }
00169
00170 QVariant QgsBrowserModel::headerData( int section, Qt::Orientation orientation, int role ) const
00171 {
00172 Q_UNUSED( section );
00173 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole )
00174 {
00175 return QVariant( "header" );
00176 }
00177
00178 return QVariant();
00179 }
00180
00181 int QgsBrowserModel::rowCount( const QModelIndex &parent ) const
00182 {
00183
00184
00185 if ( !parent.isValid() )
00186 {
00187
00188 return mRootItems.count();
00189 }
00190 else
00191 {
00192
00193 QgsDataItem *item = dataItem( parent );
00194 return item ? item->rowCount() : 0;
00195 }
00196 }
00197
00198 bool QgsBrowserModel::hasChildren( const QModelIndex &parent ) const
00199 {
00200 if ( !parent.isValid() )
00201 return true;
00202
00203 QgsDataItem *item = dataItem( parent );
00204 return item && item->hasChildren();
00205 }
00206
00207 int QgsBrowserModel::columnCount( const QModelIndex &parent ) const
00208 {
00209 Q_UNUSED( parent );
00210 return 1;
00211 }
00212
00213 QModelIndex QgsBrowserModel::findPath( QString path )
00214 {
00215 QModelIndex theIndex;
00216 bool foundChild = true;
00217
00218 while ( foundChild )
00219 {
00220 foundChild = false;
00221
00222 for ( int i = 0; i < rowCount( theIndex ); i++ )
00223 {
00224 QModelIndex idx = index( i, 0, theIndex );
00225 QgsDataItem *item = dataItem( idx );
00226 if ( !item )
00227 return QModelIndex();
00228
00229 if ( item->path() == path )
00230 {
00231 QgsDebugMsg( "Arrived " + item->path() );
00232 return idx;
00233 }
00234
00235 if ( path.startsWith( item->path() ) )
00236 {
00237
00238 foundChild = true;
00239 theIndex = idx;
00240 break;
00241 }
00242 }
00243 }
00244
00245 return QModelIndex();
00246 }
00247
00248 void QgsBrowserModel::reload()
00249 {
00250 removeRootItems();
00251 addRootItems();
00252 reset();
00253 }
00254
00255
00256 void QgsBrowserModel::refresh( QString path )
00257 {
00258 QModelIndex idx = findPath( path );
00259 if ( idx.isValid() )
00260 {
00261 QgsDataItem* item = dataItem( idx );
00262 if ( item )
00263 item->refresh();
00264 }
00265 }
00266
00267 QModelIndex QgsBrowserModel::index( int row, int column, const QModelIndex &parent ) const
00268 {
00269 QgsDataItem *p = dataItem( parent );
00270 const QVector<QgsDataItem*> &items = p ? p->children() : mRootItems;
00271 QgsDataItem *item = items.value( row, 0 );
00272 return item ? createIndex( row, column, item ) : QModelIndex();
00273 }
00274
00275 QModelIndex QgsBrowserModel::parent( const QModelIndex &index ) const
00276 {
00277 QgsDataItem *item = dataItem( index );
00278 if ( !item )
00279 return QModelIndex();
00280
00281 return findItem( item->parent() );
00282 }
00283
00284 QModelIndex QgsBrowserModel::findItem( QgsDataItem *item, QgsDataItem *parent ) const
00285 {
00286 const QVector<QgsDataItem*> &items = parent ? parent->children() : mRootItems;
00287
00288 for ( int i = 0; i < items.size(); i++ )
00289 {
00290 if ( items[i] == item )
00291 return createIndex( i, 0, item );
00292
00293 QModelIndex childIndex = findItem( item, items[i] );
00294 if ( childIndex.isValid() )
00295 return childIndex;
00296 }
00297
00298 return QModelIndex();
00299 }
00300
00301
00302 void QgsBrowserModel::refresh( const QModelIndex& theIndex )
00303 {
00304 QgsDataItem *item = dataItem( theIndex );
00305 if ( !item )
00306 return;
00307
00308 QgsDebugMsg( "Refresh " + item->path() );
00309 item->refresh();
00310 }
00311
00312 void QgsBrowserModel::beginInsertItems( QgsDataItem *parent, int first, int last )
00313 {
00314 QgsDebugMsg( "parent mPath = " + parent->path() );
00315 QModelIndex idx = findItem( parent );
00316 if ( !idx.isValid() )
00317 return;
00318 QgsDebugMsg( "valid" );
00319 beginInsertRows( idx, first, last );
00320 QgsDebugMsg( "end" );
00321 }
00322 void QgsBrowserModel::endInsertItems()
00323 {
00324 QgsDebugMsg( "Entered" );
00325 endInsertRows();
00326 }
00327 void QgsBrowserModel::beginRemoveItems( QgsDataItem *parent, int first, int last )
00328 {
00329 QgsDebugMsg( "parent mPath = " + parent->path() );
00330 QModelIndex idx = findItem( parent );
00331 if ( !idx.isValid() )
00332 return;
00333 beginRemoveRows( idx, first, last );
00334 }
00335 void QgsBrowserModel::endRemoveItems()
00336 {
00337 QgsDebugMsg( "Entered" );
00338 endRemoveRows();
00339 }
00340 void QgsBrowserModel::connectItem( QgsDataItem* item )
00341 {
00342 connect( item, SIGNAL( beginInsertItems( QgsDataItem*, int, int ) ),
00343 this, SLOT( beginInsertItems( QgsDataItem*, int, int ) ) );
00344 connect( item, SIGNAL( endInsertItems() ),
00345 this, SLOT( endInsertItems() ) );
00346 connect( item, SIGNAL( beginRemoveItems( QgsDataItem*, int, int ) ),
00347 this, SLOT( beginRemoveItems( QgsDataItem*, int, int ) ) );
00348 connect( item, SIGNAL( endRemoveItems() ),
00349 this, SLOT( endRemoveItems() ) );
00350 }
00351
00352 QStringList QgsBrowserModel::mimeTypes() const
00353 {
00354 QStringList types;
00355
00356
00357 types << "application/x-vnd.qgis.qgis.uri";
00358 return types;
00359 }
00360
00361 QMimeData * QgsBrowserModel::mimeData( const QModelIndexList &indexes ) const
00362 {
00363 QgsMimeDataUtils::UriList lst;
00364 foreach( const QModelIndex &index, indexes )
00365 {
00366 if ( index.isValid() )
00367 {
00368 QgsDataItem* ptr = ( QgsDataItem* ) index.internalPointer();
00369 if ( ptr->type() != QgsDataItem::Layer ) continue;
00370 QgsLayerItem *layer = ( QgsLayerItem* ) ptr;
00371 if ( layer->providerKey() == "wms" ) continue;
00372 lst.append( QgsMimeDataUtils::Uri( layer ) );
00373 }
00374 }
00375 return QgsMimeDataUtils::encodeUriList( lst );
00376 }
00377
00378 bool QgsBrowserModel::dropMimeData( const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent )
00379 {
00380 Q_UNUSED( row );
00381 Q_UNUSED( column );
00382
00383 QgsDataItem* destItem = dataItem( parent );
00384 if ( !destItem )
00385 {
00386 QgsDebugMsg( "DROP PROBLEM!" );
00387 return false;
00388 }
00389
00390 return destItem->handleDrop( data, action );
00391 }
00392
00393 QgsDataItem *QgsBrowserModel::dataItem( const QModelIndex &idx ) const
00394 {
00395 void *v = idx.internalPointer();
00396 QgsDataItem *d = reinterpret_cast<QgsDataItem*>( v );
00397 Q_ASSERT( !v || d );
00398 return d;
00399 }