Skip to content

Commit 58beed2

Browse files
committedFeb 9, 2016
[GRASS] better module lookup
1 parent 65afdcf commit 58beed2

File tree

4 files changed

+71
-116
lines changed

4 files changed

+71
-116
lines changed
 

‎src/plugins/grass/qgsgrassmodule.cpp

Lines changed: 1 addition & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -41,98 +41,12 @@ extern "C"
4141
#include <grass/glocale.h>
4242
}
4343

44-
//#include <gdal.h> // to collect version information
45-
46-
//bool QgsGrassModule::mExecPathInited = 0;
47-
//QStringList QgsGrassModule::mExecPath;
48-
49-
QString QgsGrassModule::findExec( QString file )
50-
{
51-
QgsDebugMsg( "called." );
52-
53-
// Init mExecPath
54-
// Windows searches first in current directory
55-
// TODO verify if/why applicationDirPath() is necessary
56-
#if 0
57-
if ( !mExecPathInited )
58-
{
59-
QString path = getenv( "PATH" );
60-
QgsDebugMsg( "path = " + path );
61-
62-
63-
#ifdef Q_OS_WIN
64-
mExecPath = path.split( ";" );
65-
mExecPath.prepend( QgsGrass::shortPath( QgsApplication::applicationDirPath() ) );
66-
#elif defined(Q_OS_MACX)
67-
mExecPath = path.split( ":" );
68-
mExecPath.prepend( QgsApplication::applicationDirPath() + "/bin" );
69-
mExecPath.prepend( QgsApplication::applicationDirPath() + "/grass/bin" );
70-
#else
71-
mExecPath = path.split( ":" );
72-
mExecPath.prepend( QgsApplication::applicationDirPath() );
73-
#endif
74-
mExecPathInited = true;
75-
}
76-
#endif
77-
78-
if ( QFile::exists( file ) )
79-
{
80-
return file; // full path
81-
}
82-
83-
#ifdef Q_OS_WIN
84-
// On windows try .bat first
85-
Q_FOREACH ( const QString& path, QgsGrass::grassModulesPaths() )
86-
{
87-
QString full = path + "/" + file + ".bat";
88-
if ( QFile::exists( full ) )
89-
{
90-
return full;
91-
}
92-
}
93-
94-
// .exe next
95-
Q_FOREACH ( const QString& path, QgsGrass::grassModulesPaths() )
96-
{
97-
QString full = path + "/" + file + ".exe";
98-
if ( QFile::exists( full ) )
99-
{
100-
return full;
101-
}
102-
}
103-
104-
// and then try if it's a script (w/o extension)
105-
#endif
106-
107-
// Search for module
108-
Q_FOREACH ( const QString& path, QgsGrass::grassModulesPaths() )
109-
{
110-
QString full = path + "/" + file;
111-
if ( QFile::exists( full ) )
112-
{
113-
QgsDebugMsg( "found " + full );
114-
return full;
115-
}
116-
else
117-
{
118-
QgsDebugMsg( "not found " + full );
119-
}
120-
}
121-
122-
return QString();
123-
}
124-
125-
bool QgsGrassModule::inExecPath( QString file )
126-
{
127-
return !findExec( file ).isNull();
128-
}
129-
13044
QStringList QgsGrassModule::execArguments( QString module )
13145
{
13246
QString exe;
13347
QStringList arguments;
13448

135-
exe = QgsGrassModule::findExec( module );
49+
exe = QgsGrass::findModule( module );
13650
if ( exe.isNull() )
13751
{
13852
return arguments;

‎src/plugins/grass/qgsgrassmodule.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -73,18 +73,6 @@ class QgsGrassModule : public QWidget, private Ui::QgsGrassModuleBase
7373
// ! Options widget
7474
QgsGrassModuleOptions *options() { return mOptions; }
7575

76-
// ! List of directories in PATH variable + current directory on Windows
77-
//static QStringList mExecPath;
78-
//static bool mExecPathInited;
79-
80-
// ! Find in exec path
81-
// returns full path or null string
82-
// appends automaticaly .exe on Windows
83-
static QString findExec( QString file );
84-
85-
// ! Check if file is in mExecPath
86-
static bool inExecPath( QString file );
87-
8876
// ! Get executable + arguments. Executable is returned as first string.
8977
// On Window if the module is script the executable will be path to shell
9078
// Returns empty list if not found.

‎src/providers/grass/qgsgrass.cpp

Lines changed: 64 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@ bool QgsGrass::init( void )
414414
mGrassModulesPaths << gisbase() + "/bin";
415415
mGrassModulesPaths << gisbase() + "/scripts";
416416
mGrassModulesPaths << QgsApplication::pkgDataPath() + "/grass/scripts";
417+
mGrassModulesPaths << qgisGrassModulePath();
417418

418419
// On windows the GRASS libraries are in
419420
// QgsApplication::prefixPath(), we have to add them
@@ -1543,9 +1544,7 @@ QStringList QgsGrass::grassObjects( const QgsGrassObject& mapsetObject, QgsGrass
15431544
{
15441545
#if GRASS_VERSION_MAJOR >= 7
15451546
QString cmd = gisbase() + "/scripts/t.list";
1546-
#ifdef Q_OS_WIN
1547-
cmd += ".py";
1548-
#endif
1547+
15491548
QStringList arguments;
15501549

15511550
// Running t.list module is quite slow (about 500ms) -> check first if temporal db exists.
@@ -1560,19 +1559,27 @@ QStringList QgsGrass::grassObjects( const QgsGrassObject& mapsetObject, QgsGrass
15601559
arguments << "type=" + QgsGrassObject::elementShort( type );
15611560

15621561
int timeout = -1; // What timeout to use? It can take long time on network or database
1563-
QByteArray data = runModule( mapsetObject.gisdbase(), mapsetObject.location(), mapsetObject.mapset(), cmd, arguments, timeout, false );
1564-
Q_FOREACH ( QString fullName, QString::fromLocal8Bit( data ).split( '\n' ) )
1562+
try
15651563
{
1566-
fullName = fullName.trimmed();
1567-
if ( !fullName.isEmpty() )
1564+
QByteArray data = runModule( mapsetObject.gisdbase(), mapsetObject.location(), mapsetObject.mapset(), cmd, arguments, timeout, false );
1565+
Q_FOREACH ( QString fullName, QString::fromLocal8Bit( data ).split( '\n' ) )
15681566
{
1569-
QStringList nameMapset = fullName.split( "@" );
1570-
if ( nameMapset.value( 1 ) == mapsetObject.mapset() || nameMapset.value( 1 ).isEmpty() )
1567+
fullName = fullName.trimmed();
1568+
if ( !fullName.isEmpty() )
15711569
{
1572-
list << nameMapset.value( 0 );
1570+
QStringList nameMapset = fullName.split( "@" );
1571+
if ( nameMapset.value( 1 ) == mapsetObject.mapset() || nameMapset.value( 1 ).isEmpty() )
1572+
{
1573+
list << nameMapset.value( 0 );
1574+
}
15731575
}
15741576
}
15751577
}
1578+
catch ( QgsGrass::Exception &e )
1579+
{
1580+
// TODO: notify somehow user
1581+
QgsDebugMsg( QString( "Cannot run %1: %2" ).arg( cmd ).arg( e.what() ) );
1582+
}
15761583
}
15771584
#endif
15781585
}
@@ -1958,6 +1965,47 @@ bool QgsGrass::mapRegion( QgsGrassObject::Type type, QString gisdbase,
19581965
return true;
19591966
}
19601967

1968+
QString QgsGrass::findModule( QString module )
1969+
{
1970+
QgsDebugMsg( "called." );
1971+
if ( QFile::exists( module ) )
1972+
{
1973+
return module; // full path
1974+
}
1975+
1976+
QStringList extensions;
1977+
#ifdef Q_OS_WIN
1978+
// On windows try .bat first
1979+
extensions << ".bat" << ".py" << ".exe";
1980+
#endif
1981+
// and then try if it's a module without extension (standard on UNIX)
1982+
extensions << "";
1983+
1984+
QStringList paths;
1985+
// Try first full path
1986+
paths << "";
1987+
paths << QgsGrass::grassModulesPaths();
1988+
1989+
// Extensions first to prefer .bat over .exe on Windows
1990+
Q_FOREACH ( const QString& ext, extensions )
1991+
{
1992+
Q_FOREACH ( const QString& path, paths )
1993+
{
1994+
QString full = path + "/" + module + ext;
1995+
if ( QFile::exists( full ) )
1996+
{
1997+
QgsDebugMsg( "found " + full );
1998+
return full;
1999+
}
2000+
else
2001+
{
2002+
QgsDebugMsg( "not found " + full );
2003+
}
2004+
}
2005+
}
2006+
return QString();
2007+
}
2008+
19612009
QProcess *QgsGrass::startModule( const QString& gisdbase, const QString& location,
19622010
const QString& mapset, const QString& moduleName, const QStringList& arguments,
19632011
QTemporaryFile &gisrcFile, bool qgisModule )
@@ -1970,12 +2018,12 @@ QProcess *QgsGrass::startModule( const QString& gisdbase, const QString& locati
19702018
{
19712019
module += QString::number( QgsGrass::versionMajor() );
19722020
}
1973-
#ifdef Q_OS_WIN
1974-
if ( !module.endsWith( ".exe", Qt::CaseInsensitive ) && !module.endsWith( ".py", Qt::CaseInsensitive ) )
2021+
2022+
QString modulePath = findModule( module );
2023+
if ( modulePath.isEmpty() )
19752024
{
1976-
module += ".exe";
2025+
throw QgsGrass::Exception( QObject::tr( "Cannot find module %1" ).arg( module ) );
19772026
}
1978-
#endif
19792027

19802028
// We have to set GISRC file, uff
19812029
if ( !gisrcFile.open() )
@@ -2008,9 +2056,8 @@ QProcess *QgsGrass::startModule( const QString& gisdbase, const QString& locati
20082056

20092057
process->setEnvironment( environment );
20102058

2011-
QgsDebugMsg( module + " " + arguments.join( " " ) );
2012-
//process->start( module, arguments, QProcess::Unbuffered );
2013-
process->start( module, arguments );
2059+
QgsDebugMsg( modulePath + " " + arguments.join( " " ) );
2060+
process->start( modulePath, arguments );
20142061
if ( !process->waitForStarted() )
20152062
{
20162063
throw QgsGrass::Exception( error );

‎src/providers/grass/qgsgrass.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,12 @@ class GRASS_LIB_EXPORT QgsGrass : public QObject
400400
// ! Get current gisrc path
401401
static QString gisrcFilePath();
402402

403+
/** Find a module trying to append .bat, .py and .exe on Windows. The module may be a full path
404+
* without extension or just a module name in which case it is searched in grassModulesPaths().
405+
* @param module module name or path to module without extension
406+
* @return full path including extension or empty string */
407+
static QString findModule( QString module );
408+
403409
/** Start a GRASS module in any gisdbase/location/mapset.
404410
* @param mapset if empty a first mapset owned by user will be used, if no mapset is owned
405411
* by user, exception is thrown.

0 commit comments

Comments
 (0)
Please sign in to comment.