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