Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[GRASS] temporal modules input
  • Loading branch information
blazek committed Oct 18, 2015
1 parent 5f1bb6c commit 6bd96b2
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 23 deletions.
77 changes: 68 additions & 9 deletions src/plugins/grass/qgsgrassmoduleinput.cpp
Expand Up @@ -64,6 +64,7 @@ QgsGrassModuleInputModel::QgsGrassModuleInputModel( QObject *parent )

mWatcher = new QFileSystemWatcher( this );
connect( mWatcher, SIGNAL( directoryChanged( const QString & ) ), SLOT( onDirectoryChanged( const QString & ) ) );
connect( mWatcher, SIGNAL( fileChanged( const QString & ) ), SLOT( onFileChanged( const QString & ) ) );

connect( QgsGrass::instance(), SIGNAL( mapsetChanged() ), SLOT( onMapsetChanged() ) );

Expand All @@ -80,7 +81,7 @@ void QgsGrassModuleInputModel::onDirectoryChanged( const QString & path )
QDir parentDir( path );
parentDir.cdUp();
QString mapset;

QList<QgsGrassObject::Type> types;
if ( path == locationPath )
{
QgsDebugMsg( "location = " + path );
Expand Down Expand Up @@ -117,25 +118,58 @@ void QgsGrassModuleInputModel::onDirectoryChanged( const QString & path )
{
watch( path + "/" + watchedDir );
}
// TODO: use db path defined in mapset VAR
watch( path + "/tgis/sqlite.db" );
}
else // cellhd or vector dir
{
QgsDebugMsg( "cellhd/vector = " + path );
mapset = parentDir.dirName();
if ( path.endsWith( "cellhd" ) )
{
types << QgsGrassObject::Raster;
}
else if ( path.endsWith( "vector" ) )
{
types << QgsGrassObject::Vector;
}
}
if ( !mapset.isEmpty() )
{
QList<QStandardItem *> items = findItems( mapset );
if ( items.size() == 1 )
{
refreshMapset( items[0], mapset );
refreshMapset( items[0], mapset, types );
}
}
}

void QgsGrassModuleInputModel::onFileChanged( const QString & path )
{
QgsDebugMsg( "path = " + path );
// when tgis/sqlite.db is changed, this gets called twice, probably the file changes more times when it is modified
if ( path.endsWith( "/tgis/sqlite.db" ) )
{
QDir dir = QFileInfo( path ).dir();
dir.cdUp();
QString mapset = dir.dirName();
QList<QStandardItem *> items = findItems( mapset );
if ( items.size() == 1 )
{
QList<QgsGrassObject::Type> types;
types << QgsGrassObject::Strds << QgsGrassObject::Stvds << QgsGrassObject::Str3ds;
refreshMapset( items[0], mapset, types );
}
}
}

void QgsGrassModuleInputModel::watch( const QString & path )
{
if ( !mWatcher->directories().contains( path ) && QFileInfo( path ).exists() )
if ( QFileInfo( path ).isDir() && !mWatcher->directories().contains( path ) )
{
mWatcher->addPath( path );
}
else if ( QFileInfo( path ).isFile() && !mWatcher->files().contains( path ) )
{
mWatcher->addPath( path );
}
Expand Down Expand Up @@ -163,19 +197,24 @@ void QgsGrassModuleInputModel::addMapset( const QString & mapset )
appendRow( mapsetItem );
}

void QgsGrassModuleInputModel::refreshMapset( QStandardItem *mapsetItem, const QString & mapset )
void QgsGrassModuleInputModel::refreshMapset( QStandardItem *mapsetItem, const QString & mapset, const QList<QgsGrassObject::Type> & theTypes )
{
QgsDebugMsg( "mapset = " + mapset );
if ( !mapsetItem )
{
return;
}

QList<QgsGrassObject::Type> types;
types << QgsGrassObject::Raster << QgsGrassObject::Vector;
QList<QgsGrassObject::Type> types = theTypes;
if ( types.isEmpty() )
{
types << QgsGrassObject::Raster << QgsGrassObject::Vector;
types << QgsGrassObject::Strds << QgsGrassObject::Stvds << QgsGrassObject::Str3ds;
}
foreach ( QgsGrassObject::Type type, types )
{
QStringList maps = QgsGrass::grassObjects( QgsGrass::getDefaultGisdbase() + "/" + QgsGrass::getDefaultLocation() + "/" + mapset, type );
QgsGrassObject mapsetObject( QgsGrass::getDefaultGisdbase(), QgsGrass::getDefaultLocation(), mapset, "", QgsGrassObject::Mapset );
QStringList maps = QgsGrass::grassObjects( mapsetObject, type );
QStringList mapNames;
foreach ( const QString& map, maps )
{
Expand Down Expand Up @@ -230,9 +269,16 @@ void QgsGrassModuleInputModel::refreshMapset( QStandardItem *mapsetItem, const Q

void QgsGrassModuleInputModel::reload()
{

QgsDebugMsg( "entered" );
mWatcher->removePaths( mWatcher->files() );
mWatcher->removePaths( mWatcher->directories() );
if ( !mWatcher->files().isEmpty() )
{
mWatcher->removePaths( mWatcher->files() );
}
if ( !mWatcher->directories().isEmpty() )
{
mWatcher->removePaths( mWatcher->directories() );
}

clear();

Expand All @@ -258,6 +304,7 @@ void QgsGrassModuleInputModel::reload()
{
watch( dirPath + "/" + watchedDir );
}
watch( dirPath + "/tgis/sqlite.db" );
}
}

Expand Down Expand Up @@ -825,6 +872,18 @@ QgsGrassModuleInput::QgsGrassModuleInput( QgsGrassModule *module,
{
mType = QgsGrassObject::Raster;
}
else if ( element == "strds" )
{
mType = QgsGrassObject::Strds;
}
else if ( element == "stvds" )
{
mType = QgsGrassObject::Stvds;
}
else if ( element == "str3ds" )
{
mType = QgsGrassObject::Str3ds;
}
else
{
mErrors << tr( "GRASS element %1 not supported" ).arg( element );
Expand Down
5 changes: 3 additions & 2 deletions src/plugins/grass/qgsgrassmoduleinput.h
Expand Up @@ -77,16 +77,17 @@ class QgsGrassModuleInputModel : public QStandardItemModel
void onMapsetChanged();

void onDirectoryChanged( const QString & path );
void onFileChanged( const QString & path );
void onMapsetSearchPathChanged();

private:
void addMapset( const QString & mapset );
void refreshMapset( QStandardItem *mapsetItem, const QString & mapset );
void refreshMapset( QStandardItem *mapsetItem, const QString & mapset, const QList<QgsGrassObject::Type> & theTypes = QList<QgsGrassObject::Type>() );
// Add to watched paths if exists and if not yet watched
void watch( const QString & path );
QString mLocationPath;
// mapset watched dirs
QStringList watchedDirs() { QStringList l; l << "cellhd" << "vector"; return l; }
QStringList watchedDirs() { QStringList l; l << "cellhd" << "vector" << "tgis"; return l; }
// names of
QStringList locationDirNames();
QFileSystemWatcher *mWatcher;
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/grass/qgsgrassmoduleoptions.cpp
Expand Up @@ -201,7 +201,8 @@ QgsGrassModuleStandardOptions::QgsGrassModuleStandardOptions(
QString element = promptElem.attribute( "element" );
QString age = promptElem.attribute( "age" );
//QgsDebugMsg("element = " + element + " age = " + age);
if ( age == "old" && ( element == "vector" || element == "cell" ) )
if ( age == "old" && ( element == "vector" || element == "cell" ||
element == "strds" || element == "stvds" || element == "str3ds" ) )
{
QgsGrassModuleInput *mi = new QgsGrassModuleInput(
mModule, this, key, confDomElement, descDocElem, gnode, mDirect, this );
Expand Down
1 change: 0 additions & 1 deletion src/plugins/grass/qgsgrasstools.cpp
Expand Up @@ -128,7 +128,6 @@ class QgsGrassToolsTreeFilterProxyModel : public QSortFilterProxyModel

for ( int i = 0; i < mModel->rowCount( sourceIndex ); i++ )
{
QgsDebugMsg( QString( "i = %1" ).arg( i ) );
QModelIndex sourceChildIndex = mModel->index( i, 0, sourceIndex );
if ( filterAcceptsItem( sourceChildIndex ) )
return true;
Expand Down
74 changes: 68 additions & 6 deletions src/providers/grass/qgsgrass.cpp
Expand Up @@ -165,22 +165,33 @@ bool QgsGrassObject::setFromUri( const QString& uri )

QString QgsGrassObject::elementShort() const
{
if ( mType == Raster )
return elementShort( mType );
}

QString QgsGrassObject::elementShort( Type type )
{
if ( type == Raster )
#if GRASS_VERSION_MAJOR < 7
return "rast";
#else
return "raster";
#endif
else if ( mType == Group )
else if ( type == Group )
return "group";
else if ( mType == Vector )
else if ( type == Vector )
#if GRASS_VERSION_MAJOR < 7
return "vect";
#else
return "vector";
#endif
else if ( mType == Region )
else if ( type == Region )
return "region";
else if ( type == Strds )
return "strds";
else if ( type == Stvds )
return "stvds";
else if ( type == Str3ds )
return "str3ds";
else
return "";
}
Expand Down Expand Up @@ -1462,9 +1473,56 @@ QStringList QgsGrass::elements( const QString& mapsetPath, const QString& elem
return list;
}

QStringList QgsGrass::grassObjects( const QString& mapsetPath, QgsGrassObject::Type type )
QStringList QgsGrass::grassObjects( const QgsGrassObject& mapsetObject, QgsGrassObject::Type type )
{
return QgsGrass::elements( mapsetPath, QgsGrassObject::dirName( type ) );
QgsDebugMsg( "mapsetPath = " + mapsetObject.mapsetPath() + " type = " + QgsGrassObject::elementShort( type ) );
QTime time;
time.start();
QStringList list;
if ( !QDir( mapsetObject.mapsetPath() ).isReadable() )
{
QgsDebugMsg( "mapset is not readable" );
return QStringList();
}
else if ( type == QgsGrassObject::Strds || type == QgsGrassObject::Stvds || type == QgsGrassObject::Str3ds )
{
QString cmd = gisbase() + "/scripts/t.list";
QStringList arguments;

// Running t.list module is quite slow (about 500ms) -> check first if temporal db exists.
// Also, if tgis/sqlite.db does not exist, it is created by t.list for current mapset!
// If user is not owner of the mapset (even if has read permission) t.list fails because it checks ownership.
if ( !QFile( mapsetObject.mapsetPath() + "/tgis/sqlite.db" ).exists() )
{
QgsDebugMsg( "tgis/sqlite.db does not exist" );
}
else
{
arguments << "type=" + QgsGrassObject::elementShort( type );

int timeout = -1; // What timeout to use? It can take long time on network or database
QByteArray data = runModule( mapsetObject.gisdbase(), mapsetObject.location(), mapsetObject.mapset(), cmd, arguments, timeout, false );
Q_FOREACH ( QString fullName, QString::fromLocal8Bit( data ).split( '\n' ) )
{
fullName = fullName.trimmed();
if ( !fullName.isEmpty() )
{
QStringList nameMapset = fullName.split( "@" );
if ( nameMapset.value( 1 ) == mapsetObject.mapset() || nameMapset.value( 1 ).isEmpty() )
{
list << nameMapset.value( 0 );
}
}
}
}
}
else
{
list = QgsGrass::elements( mapsetObject.mapsetPath(), QgsGrassObject::dirName( type ) );
}
QgsDebugMsg( "list = " + list.join( "," ) );
QgsDebugMsg( QString( "time (ms) = %1" ).arg( time.elapsed() ) );
return list;
}

bool QgsGrass::objectExists( const QgsGrassObject& grassObject )
Expand Down Expand Up @@ -1893,6 +1951,7 @@ QProcess *QgsGrass::startModule( const QString& gisdbase, const QString& locati
QStringList environment = QProcess::systemEnvironment();
environment.append( "GISRC=" + gisrcFile.fileName() );
environment.append( "GRASS_MESSAGE_FORMAT=gui" );
environment.append( "GRASS_SKIP_MAPSET_OWNER_CHECK=1" );

process->setEnvironment( environment );

Expand All @@ -1911,6 +1970,8 @@ QByteArray QgsGrass::runModule( const QString& gisdbase, const QString& locatio
const QStringList& arguments, int timeOut, bool qgisModule )
{
QgsDebugMsg( QString( "gisdbase = %1 location = %2 timeOut = %3" ).arg( gisdbase, location ).arg( timeOut ) );
QTime time;
time.start();

QTemporaryFile gisrcFile;
QProcess *process = startModule( gisdbase, location, mapset, moduleName, arguments, gisrcFile, qgisModule );
Expand All @@ -1927,6 +1988,7 @@ QByteArray QgsGrass::runModule( const QString& gisdbase, const QString& locatio
process->readAllStandardError().constData() ) );
}
QByteArray data = process->readAllStandardOutput();
QgsDebugMsg( QString( "time (ms) = %1" ).arg( time.elapsed() ) );
delete process;
return data;
}
Expand Down
7 changes: 5 additions & 2 deletions src/providers/grass/qgsgrass.h
Expand Up @@ -81,7 +81,9 @@ class GRASS_LIB_EXPORT QgsGrassObject
{
public:
//! Element type
enum Type { None, Location, Mapset, Raster, Group, Vector, Region };
enum Type { None, Location, Mapset, Raster, Group, Vector, Region,
Strds, Stvds, Str3ds
};

QgsGrassObject() : mType( None ) {}
QgsGrassObject( const QString& gisdbase, const QString& location = QString::null,
Expand All @@ -108,6 +110,7 @@ class GRASS_LIB_EXPORT QgsGrassObject
// set from QGIS layer uri, returns true if set correctly, verifies also if location is a GRASS location
bool setFromUri( const QString& uri );
// element name used as modules param, e.g. g.remove element=name
static QString elementShort( Type type );
QString elementShort() const;
// descriptive full name
QString elementName() const;
Expand Down Expand Up @@ -315,7 +318,7 @@ class GRASS_LIB_EXPORT QgsGrass : public QObject
static QStringList elements( const QString& mapsetPath, const QString& element );

//! List of existing objects
static QStringList grassObjects( const QString& mapsetPath, QgsGrassObject::Type type );
static QStringList grassObjects( const QgsGrassObject& mapsetObject, QgsGrassObject::Type type );

// returns true if object (vector, raster, region) exists
static bool objectExists( const QgsGrassObject& grassObject );
Expand Down
4 changes: 2 additions & 2 deletions src/providers/grass/qgsgrassprovidermodule.cpp
Expand Up @@ -142,7 +142,7 @@ void QgsGrassItemActions::renameGrassObject()
{
QgsDebugMsg( "Entered" );

QStringList existingNames = QgsGrass::grassObjects( mGrassObject.mapsetPath(), mGrassObject.type() );
QStringList existingNames = QgsGrass::grassObjects( mGrassObject, mGrassObject.type() );
// remove current name to avoid warning that exists
existingNames.removeOne( mGrassObject.name() );
QgsDebugMsg( "existingNames = " + existingNames.join( "," ) );
Expand Down Expand Up @@ -200,7 +200,7 @@ QString QgsGrassItemActions::newVectorMap()
{
QgsDebugMsg( "entered" );

QStringList existingNames = QgsGrass::grassObjects( mGrassObject.mapsetPath(), QgsGrassObject::Vector );
QStringList existingNames = QgsGrass::grassObjects( mGrassObject, QgsGrassObject::Vector );
QgsDebugMsg( "existingNames = " + existingNames.join( "," ) );
QRegExp regExp = QgsGrassObject::newNameRegExp( QgsGrassObject::Vector );
Qt::CaseSensitivity caseSensitivity = QgsGrass::caseSensitivity();
Expand Down

0 comments on commit 6bd96b2

Please sign in to comment.