Skip to content

Commit 6bd96b2

Browse files
committed
[GRASS] temporal modules input
1 parent 5f1bb6c commit 6bd96b2

File tree

7 files changed

+148
-23
lines changed

7 files changed

+148
-23
lines changed

src/plugins/grass/qgsgrassmoduleinput.cpp

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ QgsGrassModuleInputModel::QgsGrassModuleInputModel( QObject *parent )
6464

6565
mWatcher = new QFileSystemWatcher( this );
6666
connect( mWatcher, SIGNAL( directoryChanged( const QString & ) ), SLOT( onDirectoryChanged( const QString & ) ) );
67+
connect( mWatcher, SIGNAL( fileChanged( const QString & ) ), SLOT( onFileChanged( const QString & ) ) );
6768

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

@@ -80,7 +81,7 @@ void QgsGrassModuleInputModel::onDirectoryChanged( const QString & path )
8081
QDir parentDir( path );
8182
parentDir.cdUp();
8283
QString mapset;
83-
84+
QList<QgsGrassObject::Type> types;
8485
if ( path == locationPath )
8586
{
8687
QgsDebugMsg( "location = " + path );
@@ -117,25 +118,58 @@ void QgsGrassModuleInputModel::onDirectoryChanged( const QString & path )
117118
{
118119
watch( path + "/" + watchedDir );
119120
}
121+
// TODO: use db path defined in mapset VAR
122+
watch( path + "/tgis/sqlite.db" );
120123
}
121124
else // cellhd or vector dir
122125
{
123126
QgsDebugMsg( "cellhd/vector = " + path );
124127
mapset = parentDir.dirName();
128+
if ( path.endsWith( "cellhd" ) )
129+
{
130+
types << QgsGrassObject::Raster;
131+
}
132+
else if ( path.endsWith( "vector" ) )
133+
{
134+
types << QgsGrassObject::Vector;
135+
}
125136
}
126137
if ( !mapset.isEmpty() )
127138
{
128139
QList<QStandardItem *> items = findItems( mapset );
129140
if ( items.size() == 1 )
130141
{
131-
refreshMapset( items[0], mapset );
142+
refreshMapset( items[0], mapset, types );
143+
}
144+
}
145+
}
146+
147+
void QgsGrassModuleInputModel::onFileChanged( const QString & path )
148+
{
149+
QgsDebugMsg( "path = " + path );
150+
// when tgis/sqlite.db is changed, this gets called twice, probably the file changes more times when it is modified
151+
if ( path.endsWith( "/tgis/sqlite.db" ) )
152+
{
153+
QDir dir = QFileInfo( path ).dir();
154+
dir.cdUp();
155+
QString mapset = dir.dirName();
156+
QList<QStandardItem *> items = findItems( mapset );
157+
if ( items.size() == 1 )
158+
{
159+
QList<QgsGrassObject::Type> types;
160+
types << QgsGrassObject::Strds << QgsGrassObject::Stvds << QgsGrassObject::Str3ds;
161+
refreshMapset( items[0], mapset, types );
132162
}
133163
}
134164
}
135165

136166
void QgsGrassModuleInputModel::watch( const QString & path )
137167
{
138-
if ( !mWatcher->directories().contains( path ) && QFileInfo( path ).exists() )
168+
if ( QFileInfo( path ).isDir() && !mWatcher->directories().contains( path ) )
169+
{
170+
mWatcher->addPath( path );
171+
}
172+
else if ( QFileInfo( path ).isFile() && !mWatcher->files().contains( path ) )
139173
{
140174
mWatcher->addPath( path );
141175
}
@@ -163,19 +197,24 @@ void QgsGrassModuleInputModel::addMapset( const QString & mapset )
163197
appendRow( mapsetItem );
164198
}
165199

166-
void QgsGrassModuleInputModel::refreshMapset( QStandardItem *mapsetItem, const QString & mapset )
200+
void QgsGrassModuleInputModel::refreshMapset( QStandardItem *mapsetItem, const QString & mapset, const QList<QgsGrassObject::Type> & theTypes )
167201
{
168202
QgsDebugMsg( "mapset = " + mapset );
169203
if ( !mapsetItem )
170204
{
171205
return;
172206
}
173207

174-
QList<QgsGrassObject::Type> types;
175-
types << QgsGrassObject::Raster << QgsGrassObject::Vector;
208+
QList<QgsGrassObject::Type> types = theTypes;
209+
if ( types.isEmpty() )
210+
{
211+
types << QgsGrassObject::Raster << QgsGrassObject::Vector;
212+
types << QgsGrassObject::Strds << QgsGrassObject::Stvds << QgsGrassObject::Str3ds;
213+
}
176214
foreach ( QgsGrassObject::Type type, types )
177215
{
178-
QStringList maps = QgsGrass::grassObjects( QgsGrass::getDefaultGisdbase() + "/" + QgsGrass::getDefaultLocation() + "/" + mapset, type );
216+
QgsGrassObject mapsetObject( QgsGrass::getDefaultGisdbase(), QgsGrass::getDefaultLocation(), mapset, "", QgsGrassObject::Mapset );
217+
QStringList maps = QgsGrass::grassObjects( mapsetObject, type );
179218
QStringList mapNames;
180219
foreach ( const QString& map, maps )
181220
{
@@ -230,9 +269,16 @@ void QgsGrassModuleInputModel::refreshMapset( QStandardItem *mapsetItem, const Q
230269

231270
void QgsGrassModuleInputModel::reload()
232271
{
272+
233273
QgsDebugMsg( "entered" );
234-
mWatcher->removePaths( mWatcher->files() );
235-
mWatcher->removePaths( mWatcher->directories() );
274+
if ( !mWatcher->files().isEmpty() )
275+
{
276+
mWatcher->removePaths( mWatcher->files() );
277+
}
278+
if ( !mWatcher->directories().isEmpty() )
279+
{
280+
mWatcher->removePaths( mWatcher->directories() );
281+
}
236282

237283
clear();
238284

@@ -258,6 +304,7 @@ void QgsGrassModuleInputModel::reload()
258304
{
259305
watch( dirPath + "/" + watchedDir );
260306
}
307+
watch( dirPath + "/tgis/sqlite.db" );
261308
}
262309
}
263310

@@ -825,6 +872,18 @@ QgsGrassModuleInput::QgsGrassModuleInput( QgsGrassModule *module,
825872
{
826873
mType = QgsGrassObject::Raster;
827874
}
875+
else if ( element == "strds" )
876+
{
877+
mType = QgsGrassObject::Strds;
878+
}
879+
else if ( element == "stvds" )
880+
{
881+
mType = QgsGrassObject::Stvds;
882+
}
883+
else if ( element == "str3ds" )
884+
{
885+
mType = QgsGrassObject::Str3ds;
886+
}
828887
else
829888
{
830889
mErrors << tr( "GRASS element %1 not supported" ).arg( element );

src/plugins/grass/qgsgrassmoduleinput.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,17 @@ class QgsGrassModuleInputModel : public QStandardItemModel
7777
void onMapsetChanged();
7878

7979
void onDirectoryChanged( const QString & path );
80+
void onFileChanged( const QString & path );
8081
void onMapsetSearchPathChanged();
8182

8283
private:
8384
void addMapset( const QString & mapset );
84-
void refreshMapset( QStandardItem *mapsetItem, const QString & mapset );
85+
void refreshMapset( QStandardItem *mapsetItem, const QString & mapset, const QList<QgsGrassObject::Type> & theTypes = QList<QgsGrassObject::Type>() );
8586
// Add to watched paths if exists and if not yet watched
8687
void watch( const QString & path );
8788
QString mLocationPath;
8889
// mapset watched dirs
89-
QStringList watchedDirs() { QStringList l; l << "cellhd" << "vector"; return l; }
90+
QStringList watchedDirs() { QStringList l; l << "cellhd" << "vector" << "tgis"; return l; }
9091
// names of
9192
QStringList locationDirNames();
9293
QFileSystemWatcher *mWatcher;

src/plugins/grass/qgsgrassmoduleoptions.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,8 @@ QgsGrassModuleStandardOptions::QgsGrassModuleStandardOptions(
201201
QString element = promptElem.attribute( "element" );
202202
QString age = promptElem.attribute( "age" );
203203
//QgsDebugMsg("element = " + element + " age = " + age);
204-
if ( age == "old" && ( element == "vector" || element == "cell" ) )
204+
if ( age == "old" && ( element == "vector" || element == "cell" ||
205+
element == "strds" || element == "stvds" || element == "str3ds" ) )
205206
{
206207
QgsGrassModuleInput *mi = new QgsGrassModuleInput(
207208
mModule, this, key, confDomElement, descDocElem, gnode, mDirect, this );

src/plugins/grass/qgsgrasstools.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ class QgsGrassToolsTreeFilterProxyModel : public QSortFilterProxyModel
128128

129129
for ( int i = 0; i < mModel->rowCount( sourceIndex ); i++ )
130130
{
131-
QgsDebugMsg( QString( "i = %1" ).arg( i ) );
132131
QModelIndex sourceChildIndex = mModel->index( i, 0, sourceIndex );
133132
if ( filterAcceptsItem( sourceChildIndex ) )
134133
return true;

src/providers/grass/qgsgrass.cpp

Lines changed: 68 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -165,22 +165,33 @@ bool QgsGrassObject::setFromUri( const QString& uri )
165165

166166
QString QgsGrassObject::elementShort() const
167167
{
168-
if ( mType == Raster )
168+
return elementShort( mType );
169+
}
170+
171+
QString QgsGrassObject::elementShort( Type type )
172+
{
173+
if ( type == Raster )
169174
#if GRASS_VERSION_MAJOR < 7
170175
return "rast";
171176
#else
172177
return "raster";
173178
#endif
174-
else if ( mType == Group )
179+
else if ( type == Group )
175180
return "group";
176-
else if ( mType == Vector )
181+
else if ( type == Vector )
177182
#if GRASS_VERSION_MAJOR < 7
178183
return "vect";
179184
#else
180185
return "vector";
181186
#endif
182-
else if ( mType == Region )
187+
else if ( type == Region )
183188
return "region";
189+
else if ( type == Strds )
190+
return "strds";
191+
else if ( type == Stvds )
192+
return "stvds";
193+
else if ( type == Str3ds )
194+
return "str3ds";
184195
else
185196
return "";
186197
}
@@ -1462,9 +1473,56 @@ QStringList QgsGrass::elements( const QString& mapsetPath, const QString& elem
14621473
return list;
14631474
}
14641475

1465-
QStringList QgsGrass::grassObjects( const QString& mapsetPath, QgsGrassObject::Type type )
1476+
QStringList QgsGrass::grassObjects( const QgsGrassObject& mapsetObject, QgsGrassObject::Type type )
14661477
{
1467-
return QgsGrass::elements( mapsetPath, QgsGrassObject::dirName( type ) );
1478+
QgsDebugMsg( "mapsetPath = " + mapsetObject.mapsetPath() + " type = " + QgsGrassObject::elementShort( type ) );
1479+
QTime time;
1480+
time.start();
1481+
QStringList list;
1482+
if ( !QDir( mapsetObject.mapsetPath() ).isReadable() )
1483+
{
1484+
QgsDebugMsg( "mapset is not readable" );
1485+
return QStringList();
1486+
}
1487+
else if ( type == QgsGrassObject::Strds || type == QgsGrassObject::Stvds || type == QgsGrassObject::Str3ds )
1488+
{
1489+
QString cmd = gisbase() + "/scripts/t.list";
1490+
QStringList arguments;
1491+
1492+
// Running t.list module is quite slow (about 500ms) -> check first if temporal db exists.
1493+
// Also, if tgis/sqlite.db does not exist, it is created by t.list for current mapset!
1494+
// If user is not owner of the mapset (even if has read permission) t.list fails because it checks ownership.
1495+
if ( !QFile( mapsetObject.mapsetPath() + "/tgis/sqlite.db" ).exists() )
1496+
{
1497+
QgsDebugMsg( "tgis/sqlite.db does not exist" );
1498+
}
1499+
else
1500+
{
1501+
arguments << "type=" + QgsGrassObject::elementShort( type );
1502+
1503+
int timeout = -1; // What timeout to use? It can take long time on network or database
1504+
QByteArray data = runModule( mapsetObject.gisdbase(), mapsetObject.location(), mapsetObject.mapset(), cmd, arguments, timeout, false );
1505+
Q_FOREACH ( QString fullName, QString::fromLocal8Bit( data ).split( '\n' ) )
1506+
{
1507+
fullName = fullName.trimmed();
1508+
if ( !fullName.isEmpty() )
1509+
{
1510+
QStringList nameMapset = fullName.split( "@" );
1511+
if ( nameMapset.value( 1 ) == mapsetObject.mapset() || nameMapset.value( 1 ).isEmpty() )
1512+
{
1513+
list << nameMapset.value( 0 );
1514+
}
1515+
}
1516+
}
1517+
}
1518+
}
1519+
else
1520+
{
1521+
list = QgsGrass::elements( mapsetObject.mapsetPath(), QgsGrassObject::dirName( type ) );
1522+
}
1523+
QgsDebugMsg( "list = " + list.join( "," ) );
1524+
QgsDebugMsg( QString( "time (ms) = %1" ).arg( time.elapsed() ) );
1525+
return list;
14681526
}
14691527

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

18971956
process->setEnvironment( environment );
18981957

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

19151976
QTemporaryFile gisrcFile;
19161977
QProcess *process = startModule( gisdbase, location, mapset, moduleName, arguments, gisrcFile, qgisModule );
@@ -1927,6 +1988,7 @@ QByteArray QgsGrass::runModule( const QString& gisdbase, const QString& locatio
19271988
process->readAllStandardError().constData() ) );
19281989
}
19291990
QByteArray data = process->readAllStandardOutput();
1991+
QgsDebugMsg( QString( "time (ms) = %1" ).arg( time.elapsed() ) );
19301992
delete process;
19311993
return data;
19321994
}

src/providers/grass/qgsgrass.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@ class GRASS_LIB_EXPORT QgsGrassObject
8181
{
8282
public:
8383
//! Element type
84-
enum Type { None, Location, Mapset, Raster, Group, Vector, Region };
84+
enum Type { None, Location, Mapset, Raster, Group, Vector, Region,
85+
Strds, Stvds, Str3ds
86+
};
8587

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

317320
//! List of existing objects
318-
static QStringList grassObjects( const QString& mapsetPath, QgsGrassObject::Type type );
321+
static QStringList grassObjects( const QgsGrassObject& mapsetObject, QgsGrassObject::Type type );
319322

320323
// returns true if object (vector, raster, region) exists
321324
static bool objectExists( const QgsGrassObject& grassObject );

src/providers/grass/qgsgrassprovidermodule.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ void QgsGrassItemActions::renameGrassObject()
142142
{
143143
QgsDebugMsg( "Entered" );
144144

145-
QStringList existingNames = QgsGrass::grassObjects( mGrassObject.mapsetPath(), mGrassObject.type() );
145+
QStringList existingNames = QgsGrass::grassObjects( mGrassObject, mGrassObject.type() );
146146
// remove current name to avoid warning that exists
147147
existingNames.removeOne( mGrassObject.name() );
148148
QgsDebugMsg( "existingNames = " + existingNames.join( "," ) );
@@ -200,7 +200,7 @@ QString QgsGrassItemActions::newVectorMap()
200200
{
201201
QgsDebugMsg( "entered" );
202202

203-
QStringList existingNames = QgsGrass::grassObjects( mGrassObject.mapsetPath(), QgsGrassObject::Vector );
203+
QStringList existingNames = QgsGrass::grassObjects( mGrassObject, QgsGrassObject::Vector );
204204
QgsDebugMsg( "existingNames = " + existingNames.join( "," ) );
205205
QRegExp regExp = QgsGrassObject::newNameRegExp( QgsGrassObject::Vector );
206206
Qt::CaseSensitivity caseSensitivity = QgsGrass::caseSensitivity();

0 commit comments

Comments
 (0)