diff --git a/images/images.qrc b/images/images.qrc index 37371a74d22..c87cce8a774 100644 --- a/images/images.qrc +++ b/images/images.qrc @@ -13,6 +13,8 @@ themes/default/geographic.png themes/default/gpsicons/barchart.svg themes/default/gpsicons/polarchart.svg + themes/default/grass_location.png + themes/default/grass_mapset.png themes/default/join_bevel.png themes/default/join_miter.png themes/default/join_round.png diff --git a/images/themes/default/grass_location.png b/images/themes/default/grass_location.png new file mode 100644 index 00000000000..4d5be2a6b4d Binary files /dev/null and b/images/themes/default/grass_location.png differ diff --git a/images/themes/default/grass_mapset.png b/images/themes/default/grass_mapset.png new file mode 100644 index 00000000000..4d5be2a6b4d Binary files /dev/null and b/images/themes/default/grass_mapset.png differ diff --git a/src/browser/qgsbrowser.cpp b/src/browser/qgsbrowser.cpp index dc79dd235f2..0820faf7f71 100644 --- a/src/browser/qgsbrowser.cpp +++ b/src/browser/qgsbrowser.cpp @@ -419,7 +419,7 @@ void QgsBrowser::updateCurrentTab() if (current == Metadata && mDirtyMetadata) { - if (mLayer) + if (mLayer && mLayer->isValid()) { // Set meta QString myStyle = QgsApplication::reportStyleSheet(); @@ -436,7 +436,7 @@ void QgsBrowser::updateCurrentTab() if (current == Preview && mDirtyPreview) { - if (mLayer) + if (mLayer && mLayer->isValid()) { // Create preview: add to map canvas QList layers; @@ -452,7 +452,7 @@ void QgsBrowser::updateCurrentTab() if (current == Attributes && mDirtyAttributes) { - if ( mLayer && mLayer->type() == QgsMapLayer::VectorLayer ) + if ( mLayer && mLayer->isValid() && mLayer->type() == QgsMapLayer::VectorLayer ) { QgsVectorLayer* vlayer = qobject_cast( mLayer ); QApplication::setOverrideCursor(Qt::WaitCursor); diff --git a/src/core/qgsdataitem.cpp b/src/core/qgsdataitem.cpp index 3c4f72b7f49..58d1b6130fb 100755 --- a/src/core/qgsdataitem.cpp +++ b/src/core/qgsdataitem.cpp @@ -93,7 +93,7 @@ const QIcon &QgsDataCollectionItem::iconDir() { static QIcon icon; - if ( !icon.isNull() ) + if ( icon.isNull() ) { // initialize shared icons QStyle *style = QApplication::style(); @@ -250,6 +250,16 @@ void QgsDataItem::refresh() } } +bool QgsDataItem::equal( const QgsDataItem *other ) +{ + if ( typeid ( this ) == typeid ( other ) && + mPath == other->path() ) + { + return true; + } + return false; +} + // --------------------------------------------------------------------- QgsLayerItem::QgsLayerItem( QgsDataItem* parent, QString name, QString path, QString uri, LayerType layerType, QString providerKey ) @@ -327,9 +337,10 @@ QgsDirectoryItem::QgsDirectoryItem( QgsDataItem* parent, QString name, QString p } if ( dataCapabilities() == QgsDataProvider::NoDataCapabilities ) { - QgsDebugMsg( library->fileName() + " does not have File capability" ); + QgsDebugMsg( library->fileName() + " has NoDataCapabilities" ); continue; } + QgsDebugMsg( QString ( "%1 dataCapabilities : %2").arg(library->fileName()).arg(dataCapabilities() ) ); mLibraries.append( library ); } else @@ -360,10 +371,11 @@ QVector QgsDirectoryItem::createChildren( ) children.append( item ); } - QStringList fileEntries = dir.entryList( QDir::Files, QDir::Name ); + QStringList fileEntries = dir.entryList( QDir::Dirs|QDir::NoDotAndDotDot|QDir::Files, QDir::Name ); foreach( QString name, fileEntries ) { QString path = dir.absoluteFilePath( name ); + QFileInfo fileInfo ( path ); foreach( QLibrary *library, mLibraries ) { // we could/should create separate list of providers for each purpose @@ -374,7 +386,11 @@ QVector QgsDirectoryItem::createChildren( ) int capabilities = dataCapabilities(); - if ( !( capabilities & QgsDataProvider::File ) ) continue; + if ( !( (fileInfo.isFile() && (capabilities & QgsDataProvider::File)) || + (fileInfo.isDir() && (capabilities & QgsDataProvider::Dir))) ) + { + continue; + } dataItem_t * dataItem = ( dataItem_t * ) cast_to_fptr( library->resolve( "dataItem" ) ); if ( ! dataItem ) diff --git a/src/core/qgsdataitem.h b/src/core/qgsdataitem.h index 21ea31fa895..75d28d5fc95 100755 --- a/src/core/qgsdataitem.h +++ b/src/core/qgsdataitem.h @@ -73,7 +73,7 @@ class CORE_EXPORT QgsDataItem : public QObject // remove and delete child item, signals to browser are emited virtual void deleteChildItem( QgsDataItem * child ); - virtual bool equal( const QgsDataItem *other ) { return false; } + virtual bool equal( const QgsDataItem *other ); virtual QWidget * paramWidget() { return 0; } diff --git a/src/plugins/grass/qgsgrassbrowser.cpp b/src/plugins/grass/qgsgrassbrowser.cpp index 76c8f017b6d..499c324a1d9 100644 --- a/src/plugins/grass/qgsgrassbrowser.cpp +++ b/src/plugins/grass/qgsgrassbrowser.cpp @@ -162,7 +162,7 @@ void QgsGrassBrowser::addMap() else if ( type == QgsGrassModel::VectorLayer ) { - QStringList list = QgsGrassSelect::vectorLayers( + QStringList list = QgsGrass::vectorLayers( QgsGrass::getDefaultGisdbase(), QgsGrass::getDefaultLocation(), mModel->itemMapset( *it ), map ); diff --git a/src/plugins/grass/qgsgrassmodel.cpp b/src/plugins/grass/qgsgrassmodel.cpp index b7cbd86b945..f42756a7e9b 100644 --- a/src/plugins/grass/qgsgrassmodel.cpp +++ b/src/plugins/grass/qgsgrassmodel.cpp @@ -759,7 +759,7 @@ void QgsGrassModel::refreshItem( QgsGrassModelItem *item ) case QgsGrassModel::Vector: { - QStringList list = QgsGrassSelect::vectorLayers( + QStringList list = QgsGrass::vectorLayers( QgsGrass::getDefaultGisdbase(), QgsGrass::getDefaultLocation(), item->mMapset, item->mMap ); diff --git a/src/plugins/grass/qgsgrassmodule.cpp b/src/plugins/grass/qgsgrassmodule.cpp index 91612b9239f..c6a06745a32 100644 --- a/src/plugins/grass/qgsgrassmodule.cpp +++ b/src/plugins/grass/qgsgrassmodule.cpp @@ -1593,7 +1593,7 @@ void QgsGrassModule::viewOutput() { QString map = mOutputVector.at( i ); - QStringList layers = QgsGrassSelect::vectorLayers( + QStringList layers = QgsGrass::vectorLayers( QgsGrass::getDefaultGisdbase(), QgsGrass::getDefaultLocation(), QgsGrass::getDefaultMapset(), map ); diff --git a/src/plugins/grass/qgsgrassselect.cpp b/src/plugins/grass/qgsgrassselect.cpp index 6c6e2a82b81..326dda7e035 100644 --- a/src/plugins/grass/qgsgrassselect.cpp +++ b/src/plugins/grass/qgsgrassselect.cpp @@ -323,7 +323,7 @@ void QgsGrassSelect::setLayers() if ( type != VECTOR ) return; if ( emap->count() < 1 ) return; - QStringList layers = vectorLayers( egisdbase->text(), + QStringList layers = QgsGrass::vectorLayers( egisdbase->text(), elocation->currentText(), emapset->currentText(), emap->currentText().toUtf8() ); @@ -369,100 +369,6 @@ void QgsGrassSelect::setLayers() } } -QStringList QgsGrassSelect::vectorLayers( QString gisdbase, - QString location, QString mapset, QString mapName ) -{ - QStringList list; - - // Set location - QgsGrass::setLocation( gisdbase, location ); - - /* Open vector */ - QgsGrass::resetError(); - //Vect_set_open_level( 2 ); - struct Map_info map; - int level = -1; - - try - { - level = Vect_open_old_head( &map, ( char * ) mapName.toUtf8().data(), ( char * ) mapset.toUtf8().data() ); - } - catch ( QgsGrass::Exception &e ) - { - Q_UNUSED( e ); - QgsDebugMsg( QString( "Cannot open GRASS vector: %1" ).arg( e.what() ) ); - return list; - } - - if ( level == 1 ) - { - QgsDebugMsg( "Cannot open vector on level 2" ); - QMessageBox::warning( 0, tr( "Warning" ), tr( "Cannot open vector %1 in mapset %2 on level 2 (topology not available, try to rebuild topology using v.build module)." ).arg( mapName ).arg( mapset ) ); - // Vect_close here is correct, it should work, but it seems to cause - // crash on win http://trac.osgeo.org/qgis/ticket/2003 - // disabled on win test it -#if !defined(WIN32) - Vect_close( &map ); -#endif - return list; - } - else if ( level < 1 ) - { - QgsDebugMsg( "Cannot open vector" ); - QMessageBox::warning( 0, tr( "Warning" ), tr( "Cannot open vector %1 in mapset %2" ).arg( mapName ).arg( mapset ) ); - return list; - } - - QgsDebugMsg( "GRASS vector successfully opened" ); - - - // Get layers - int ncidx = Vect_cidx_get_num_fields( &map ); - - for ( int i = 0; i < ncidx; i++ ) - { - int field = Vect_cidx_get_field_number( &map, i ); - QString fs; - fs.sprintf( "%d", field ); - - QgsDebugMsg( QString( "i = %1 layer = %2" ).arg( i ).arg( field ) ); - - /* Points */ - int npoints = Vect_cidx_get_type_count( &map, field, GV_POINT ); - if ( npoints > 0 ) - { - QString l = fs + "_point"; - list.append( l ); - } - - /* Lines */ - /* Lines without category appears in layer 0, but not boundaries */ - int tp; - if ( field == 0 ) - tp = GV_LINE; - else - tp = GV_LINE | GV_BOUNDARY; - - int nlines = Vect_cidx_get_type_count( &map, field, tp ); - if ( nlines > 0 ) - { - QString l = fs + "_line"; - list.append( l ); - } - - /* Polygons */ - int nareas = Vect_cidx_get_type_count( &map, field, GV_AREA ); - if ( nareas > 0 ) - { - QString l = fs + "_polygon"; - list.append( l ); - } - } - Vect_close( &map ); - - return list; -} - void QgsGrassSelect::on_GisdbaseBrowse_clicked() { QString Gisdbase = QFileDialog::getExistingDirectory( this, diff --git a/src/plugins/grass/qgsgrassselect.h b/src/plugins/grass/qgsgrassselect.h index a048993182b..90c5a577008 100644 --- a/src/plugins/grass/qgsgrassselect.h +++ b/src/plugins/grass/qgsgrassselect.h @@ -41,9 +41,6 @@ class QgsGrassSelect: public QDialog, private Ui::QgsGrassSelectBase MAPCALC // file in $MAPSET/mapcalc directory (used by QgsGrassMapcalc) }; - //! Get list of vector layer - static QStringList vectorLayers( QString, QString, QString, QString ); - QString gisdbase; QString location; QString mapset; diff --git a/src/plugins/grass/qgsgrassutils.cpp b/src/plugins/grass/qgsgrassutils.cpp index b755fd25b9e..d41ecd15adc 100644 --- a/src/plugins/grass/qgsgrassutils.cpp +++ b/src/plugins/grass/qgsgrassutils.cpp @@ -36,7 +36,7 @@ QString QgsGrassUtils::vectorLayerName( QString map, QString layer, void QgsGrassUtils::addVectorLayers( QgisInterface *iface, QString gisbase, QString location, QString mapset, QString map ) { - QStringList layers = QgsGrassSelect::vectorLayers( + QStringList layers = QgsGrass::vectorLayers( gisbase, location, mapset, map ); diff --git a/src/providers/grass/CMakeLists.txt b/src/providers/grass/CMakeLists.txt index 610ea639c18..e9e34c191a9 100755 --- a/src/providers/grass/CMakeLists.txt +++ b/src/providers/grass/CMakeLists.txt @@ -3,11 +3,11 @@ ADD_DEFINITIONS(-DGRASS_BASE=\\\"${GRASS_PREFIX}\\\") ######################################################## # Files -SET(GRASS_PROVIDER_SRCS provider.cpp) +SET(GRASS_PROVIDER_SRCS provider.cpp qgsgrassprovider.cpp ) SET(GRASS_RASTER_PROVIDER_SRCS qgsgrassrasterprovider.cpp) -SET(GRASS_LIB_SRCS qgsgrassprovider.cpp qgsgrass.cpp) +SET(GRASS_LIB_SRCS qgsgrass.cpp) SET(QGIS_D_RAST_SRCS qgis.d.rast.c) diff --git a/src/providers/grass/qgsgrass.cpp b/src/providers/grass/qgsgrass.cpp index 36d98e04fba..40b2836742a 100644 --- a/src/providers/grass/qgsgrass.cpp +++ b/src/providers/grass/qgsgrass.cpp @@ -767,6 +767,99 @@ QStringList GRASS_EXPORT QgsGrass::vectors( QString mapsetPath ) } return list; } +QStringList GRASS_EXPORT QgsGrass::vectorLayers( QString gisdbase, + QString location, QString mapset, QString mapName ) +{ + QStringList list; + + // Set location + QgsGrass::setLocation( gisdbase, location ); + + /* Open vector */ + QgsGrass::resetError(); + //Vect_set_open_level( 2 ); + struct Map_info map; + int level = -1; + + try + { + level = Vect_open_old_head( &map, ( char * ) mapName.toUtf8().data(), ( char * ) mapset.toUtf8().data() ); + } + catch ( QgsGrass::Exception &e ) + { + Q_UNUSED( e ); + QgsDebugMsg( QString( "Cannot open GRASS vector: %1" ).arg( e.what() ) ); + return list; + } + + if ( level == 1 ) + { + QgsDebugMsg( "Cannot open vector on level 2" ); + QMessageBox::warning( 0, QObject::tr( "Warning" ), QObject::tr( "Cannot open vector %1 in mapset %2 on level 2 (topology not available, try to rebuild topology using v.build module)." ).arg( mapName ).arg( mapset ) ); + // Vect_close here is correct, it should work, but it seems to cause + // crash on win http://trac.osgeo.org/qgis/ticket/2003 + // disabled on win test it +#if !defined(WIN32) + Vect_close( &map ); +#endif + return list; + } + else if ( level < 1 ) + { + QgsDebugMsg( "Cannot open vector" ); + QMessageBox::warning( 0, QObject::tr( "Warning" ), QObject::tr( "Cannot open vector %1 in mapset %2" ).arg( mapName ).arg( mapset ) ); + return list; + } + + QgsDebugMsg( "GRASS vector successfully opened" ); + + + // Get layers + int ncidx = Vect_cidx_get_num_fields( &map ); + + for ( int i = 0; i < ncidx; i++ ) + { + int field = Vect_cidx_get_field_number( &map, i ); + QString fs; + fs.sprintf( "%d", field ); + + QgsDebugMsg( QString( "i = %1 layer = %2" ).arg( i ).arg( field ) ); + + /* Points */ + int npoints = Vect_cidx_get_type_count( &map, field, GV_POINT ); + if ( npoints > 0 ) + { + QString l = fs + "_point"; + list.append( l ); + } + + /* Lines */ + /* Lines without category appears in layer 0, but not boundaries */ + int tp; + if ( field == 0 ) + tp = GV_LINE; + else + tp = GV_LINE | GV_BOUNDARY; + + int nlines = Vect_cidx_get_type_count( &map, field, tp ); + if ( nlines > 0 ) + { + QString l = fs + "_line"; + list.append( l ); + } + + /* Polygons */ + int nareas = Vect_cidx_get_type_count( &map, field, GV_AREA ); + if ( nareas > 0 ) + { + QString l = fs + "_polygon"; + list.append( l ); + } + } + Vect_close( &map ); + + return list; +} QStringList GRASS_EXPORT QgsGrass::rasters( QString gisbase, QString locationName, QString mapsetName ) diff --git a/src/providers/grass/qgsgrass.h b/src/providers/grass/qgsgrass.h index e7fd21d7837..ad34bd293bc 100644 --- a/src/providers/grass/qgsgrass.h +++ b/src/providers/grass/qgsgrass.h @@ -139,6 +139,9 @@ class QgsGrass QString mapsetName ); static GRASS_EXPORT QStringList rasters( QString mapsetPath ); + //! Get list of vector layers + static QStringList vectorLayers( QString, QString, QString, QString ); + //! List of elements static GRASS_EXPORT QStringList elements( QString gisbase, QString locationName, QString mapsetName, QString element ); diff --git a/src/providers/grass/qgsgrassprovider.cpp b/src/providers/grass/qgsgrassprovider.cpp index 037d8ae0428..65e476797d5 100644 --- a/src/providers/grass/qgsgrassprovider.cpp +++ b/src/providers/grass/qgsgrassprovider.cpp @@ -27,6 +27,8 @@ #include #include +#include +#include #include #include //#include @@ -2372,3 +2374,126 @@ QString QgsGrassProvider::description() const { return GRASS_DESCRIPTION; } // QgsGrassProvider::description() + + +QgsGrassLocationItem::QgsGrassLocationItem ( QgsDataItem* parent, QString path ) + : QgsDataCollectionItem ( parent, "", path ) +{ + QFileInfo fi ( path ); + mName =fi.baseName(); + mIcon = QIcon ( getThemePixmap ( "grass_location.png" ) ); +} +QgsGrassLocationItem::~QgsGrassLocationItem () {} + +bool QgsGrassLocationItem::isLocation ( QString path ) +{ + //QgsDebugMsg( "path = " + path ); + return QFile::exists( path + QDir::separator() + "PERMANENT" + QDir::separator() + "DEFAULT_WIND" ); +} + +QVectorQgsGrassLocationItem::createChildren() +{ + QVector mapsets; + + QDir dir( mPath ); + + QStringList entries = dir.entryList( QDir::Dirs|QDir::NoDotAndDotDot, QDir::Name ); + foreach( QString name, entries ) + { + QString path = dir.absoluteFilePath( name ); + + if ( QgsGrassMapsetItem::isMapset ( path ) ) + { + QgsGrassMapsetItem * mapset = new QgsGrassMapsetItem ( this, path ); + mapsets.append ( mapset ); + } + } + return mapsets; +} + +QgsGrassMapsetItem::QgsGrassMapsetItem ( QgsDataItem* parent, QString path ) + : QgsDataCollectionItem ( parent, "", path ) +{ + QDir dir( path ); + mName = dir.dirName(); + dir.cdUp(); + mLocation = dir.dirName(); + dir.cdUp(); + mGisdbase = dir.path(); + + mIcon = QIcon ( getThemePixmap ( "grass_mapset.png" ) ); +} + +QgsGrassMapsetItem::~QgsGrassMapsetItem () {} + +bool QgsGrassMapsetItem::isMapset ( QString path ) +{ + return QFile::exists( path + QDir::separator() + "WIND" ); +} + +QVector QgsGrassMapsetItem::createChildren() +{ + QVector items; + + QStringList vectorNames = QgsGrass::vectors( mPath ); + + foreach( QString name, vectorNames ) + { + QStringList layerNames = QgsGrass::vectorLayers( mGisdbase , mLocation, mName, name ); + + QString path = mPath + QDir::separator() + "vector" + QDir::separator() + name; + + QgsDataCollectionItem *map; + if ( layerNames.size() != 1 ) map = new QgsDataCollectionItem( this, name ); + foreach( QString layerName, layerNames ) + { + QString uri = mPath + QDir::separator() + name + QDir::separator() +layerName; + QgsLayerItem::LayerType layerType = QgsLayerItem::Vector; + QString typeName = layerName.split("_")[1]; + QString baseLayerName = layerName.split("_")[0]; + if ( typeName == "point" ) layerType = QgsLayerItem::Point; + else if ( typeName == "line" ) layerType = QgsLayerItem::Line; + else if ( typeName == "polygon" ) layerType = QgsLayerItem::Polygon; + if ( layerNames.size() == 1 ) + { + + QgsLayerItem *layer = new QgsLayerItem ( this, name + " " + baseLayerName, path, uri, layerType, "grass" ); + items.append( layer ); + } + else + { + QgsLayerItem *layer = new QgsLayerItem ( map, baseLayerName, path, uri, layerType, "grass" ); + map->addChild( layer ); + } + } + if ( layerNames.size() != 1 ) items.append( map ); + } + + QStringList rasterNames = QgsGrass::rasters( mPath ); + + foreach( QString name, rasterNames ) + { + QString uri = mPath + QDir::separator() + "cellhd" + QDir::separator() + name; + QgsDebugMsg ( "uri = " + uri ); + + QgsLayerItem *layer = new QgsLayerItem ( this, name, uri, uri, QgsLayerItem::Raster, "grassraster" ); + + items.append( layer ); + } + + return items; +} + +QGISEXTERN int dataCapabilities () { + return QgsDataProvider::Dir; +} + +QGISEXTERN QgsDataItem * dataItem ( QString thePath, QgsDataItem* parentItem ) +{ + if ( QgsGrassLocationItem::isLocation ( thePath ) ) + { + QgsGrassLocationItem * location = new QgsGrassLocationItem ( parentItem, thePath ); + return location; + } + return 0; +} \ No newline at end of file diff --git a/src/providers/grass/qgsgrassprovider.h b/src/providers/grass/qgsgrassprovider.h index e342320a807..55d2e828465 100644 --- a/src/providers/grass/qgsgrassprovider.h +++ b/src/providers/grass/qgsgrassprovider.h @@ -18,8 +18,9 @@ class QgsFeature; class QgsField; - #include + +#include "qgsdataitem.h" #include "qgsvectordataprovider.h" #include @@ -685,4 +686,30 @@ class GRASS_EXPORT QgsGrassProvider : public QgsVectorDataProvider static std::vector mMaps; // Map }; + +class QgsGrassLocationItem : public QgsDataCollectionItem +{ + public: + QgsGrassLocationItem (QgsDataItem* parent, QString path ); + ~QgsGrassLocationItem(); + + static bool isLocation ( QString path ); + QVector createChildren(); +}; + +class QgsGrassMapsetItem : public QgsDataCollectionItem +{ + public: + QgsGrassMapsetItem (QgsDataItem* parent, QString path ); + ~QgsGrassMapsetItem(); + + static bool isMapset ( QString path ); + QVector createChildren(); + + QString mLocation; + QString mGisdbase; +}; + + + #endif // QGSGRASSPROVIDER_H