Skip to content

Commit 74f8d47

Browse files
committedOct 8, 2015
[GRASS] restrict module input by SEARCH_PATH
1 parent 814e848 commit 74f8d47

File tree

4 files changed

+173
-3
lines changed

4 files changed

+173
-3
lines changed
 

‎src/plugins/grass/qgsgrassmoduleinput.cpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ QgsGrassModuleInputModel::QgsGrassModuleInputModel( QObject *parent )
6767

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

70+
connect( QgsGrass::instance(), SIGNAL( mapsetSearchPathChanged() ), SLOT( onMapsetSearchPathChanged() ) );
71+
7072
reload();
7173
}
7274

@@ -268,6 +270,12 @@ void QgsGrassModuleInputModel::onMapsetChanged()
268270
}
269271
}
270272

273+
void QgsGrassModuleInputModel::onMapsetSearchPathChanged()
274+
{
275+
QgsDebugMsg( "entered" );
276+
emit dataChanged( index( 0, 0 ), index( rowCount() - 1, 0 ) );
277+
}
278+
271279
QgsGrassModuleInputModel::~QgsGrassModuleInputModel()
272280
{
273281

@@ -317,8 +325,23 @@ bool QgsGrassModuleInputProxy::filterAcceptsRow( int sourceRow, const QModelInde
317325

318326
QgsDebugMsg( QString( "mType = %1 item type = %2" ).arg( mType ).arg( sourceModel()->data( sourceIndex, QgsGrassModuleInputModel::TypeRole ).toInt() ) );
319327
QgsGrassObject::Type itemType = ( QgsGrassObject::Type )( sourceModel()->data( sourceIndex, QgsGrassModuleInputModel::TypeRole ).toInt() );
320-
// TODO: filter out mapsets without given type? May be confusing.
321-
return itemType == QgsGrassObject::Mapset || mType == itemType;
328+
329+
if ( itemType == QgsGrassObject::Mapset )
330+
{
331+
// TODO: filter out mapsets which have no map of given type? May be confusin if user does not see existing mapset in the tree.
332+
QString mapset = sourceModel()->data( sourceIndex, QgsGrassModuleInputModel::MapsetRole ).toString();
333+
if ( QgsGrass::instance()->isMapsetInSearchPath( mapset ) )
334+
{
335+
return true;
336+
}
337+
else
338+
{
339+
QgsDebugMsg( "mapset " + mapset + " is not in search path" );
340+
return false;
341+
}
342+
}
343+
344+
return mType == itemType;
322345
}
323346

324347
bool QgsGrassModuleInputProxy::lessThan( const QModelIndex & left, const QModelIndex & right ) const

‎src/plugins/grass/qgsgrassmoduleinput.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class QgsGrassModuleInputModel : public QStandardItemModel
7777
void onMapsetChanged();
7878

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

8182
private:
8283
void addMapset( const QString & mapset );

‎src/providers/grass/qgsgrass.cpp

Lines changed: 124 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,11 @@ bool QgsGrassObject::operator==( const QgsGrassObject& other ) const
262262
&& mName == other.mName && mType == other.mType;
263263
}
264264

265+
QgsGrass::QgsGrass()
266+
: mMapsetSearchPathWatcher( 0 )
267+
{
268+
}
269+
265270
QString QgsGrass::pathSeparator()
266271
{
267272
#ifdef Q_OS_WIN
@@ -316,8 +321,8 @@ bool QgsGrass::init( void )
316321
lock();
317322
QgsDebugMsg( "do init" );
318323

319-
// Is it active mode ?
320324
active = false;
325+
// Is it active mode ?
321326
if ( getenv( "GISRC" ) )
322327
{
323328
G_TRY
@@ -352,6 +357,12 @@ bool QgsGrass::init( void )
352357
return false;
353358
}
354359

360+
if ( active )
361+
{
362+
QgsGrass::instance()->loadMapsetSearchPath(); // must be after G_no_gisinit()
363+
QgsGrass::instance()->setMapsetSearchPathWatcher();
364+
}
365+
355366
// I think that mask should not be used in QGIS as it can only confuses people,
356367
// anyway, I don't think anybody is using MASK
357368
// TODO7: Rast_suppress_masking (see G_suppress_masking() macro above) needs MAPSET
@@ -545,6 +556,11 @@ QString QgsGrass::getDefaultMapset()
545556
return defaultMapset;
546557
}
547558

559+
QString QgsGrass::getDefaultMapsetPath()
560+
{
561+
return getDefaultLocationPath() + "/" + defaultMapset;
562+
}
563+
548564
void QgsGrass::setLocation( QString gisdbase, QString location )
549565
{
550566
QgsDebugMsg( QString( "gisdbase = %1 location = %2" ).arg( gisdbase ).arg( location ) );
@@ -601,6 +617,109 @@ void QgsGrass::setMapset( QgsGrassObject grassObject )
601617
setMapset( grassObject.gisdbase(), grassObject.location(), grassObject.mapset() );
602618
}
603619

620+
bool QgsGrass::isMapsetInSearchPath( QString mapset )
621+
{
622+
return mMapsetSearchPath.contains( mapset );
623+
}
624+
625+
void QgsGrass::loadMapsetSearchPath()
626+
{
627+
QgsDebugMsg( "entered" );
628+
// do not lock, it is called from locked function
629+
QStringList oldMapsetSearchPath = mMapsetSearchPath;
630+
mMapsetSearchPath.clear();
631+
if ( !activeMode() )
632+
{
633+
QgsDebugMsg( "not active" );
634+
emit mapsetSearchPathChanged();
635+
return;
636+
}
637+
G_TRY
638+
{
639+
QgsGrass::setMapset( getDefaultGisdbase(), getDefaultLocation(), getDefaultMapset() );
640+
const char *mapset = 0;
641+
#if GRASS_VERSION_MAJOR >= 7
642+
G_reset_mapsets();
643+
for ( int i = 0; ( mapset = G_get_mapset_name( i ) ); i++ )
644+
#else
645+
int result = G_reset_mapsets();
646+
Q_UNUSED( result );
647+
for ( int i = 0; ( mapset = G__mapset_name( i ) ); i++ )
648+
#endif
649+
{
650+
QgsDebugMsg( QString( "mapset = %1" ).arg( mapset ) );
651+
if ( G_is_mapset_in_search_path( mapset ) )
652+
{
653+
mMapsetSearchPath << mapset;
654+
}
655+
}
656+
}
657+
G_CATCH( QgsGrass::Exception &e )
658+
{
659+
QgsDebugMsg( "cannot load mapset search path: " + QString( e.what() ) );
660+
}
661+
QgsDebugMsg( "mMapsetSearchPath = " + mMapsetSearchPath.join( "," ) );
662+
if ( mMapsetSearchPath != oldMapsetSearchPath )
663+
{
664+
emit mapsetSearchPathChanged();
665+
}
666+
}
667+
668+
void QgsGrass::setMapsetSearchPathWatcher()
669+
{
670+
QgsDebugMsg( "etered" );
671+
if ( mMapsetSearchPathWatcher )
672+
{
673+
delete mMapsetSearchPathWatcher;
674+
mMapsetSearchPathWatcher = 0;
675+
}
676+
if ( !activeMode() )
677+
{
678+
return;
679+
}
680+
mMapsetSearchPathWatcher = new QFileSystemWatcher( this );
681+
682+
QString searchFilePath = getDefaultMapsetPath() + "/SEARCH_PATH";
683+
684+
if ( QFileInfo( searchFilePath ).exists() )
685+
{
686+
QgsDebugMsg( "add watcher on SEARCH_PATH file " + searchFilePath );
687+
mMapsetSearchPathWatcher->addPath( searchFilePath );
688+
connect( mMapsetSearchPathWatcher, SIGNAL( fileChanged( const QString & ) ), SLOT( onSearchPathFileChanged( const QString & ) ) );
689+
}
690+
else
691+
{
692+
QgsDebugMsg( "add watcher on mapset " + getDefaultMapsetPath() );
693+
mMapsetSearchPathWatcher->addPath( getDefaultMapsetPath() );
694+
connect( mMapsetSearchPathWatcher, SIGNAL( directoryChanged( const QString & ) ), SLOT( onSearchPathFileChanged( const QString & ) ) );
695+
}
696+
}
697+
698+
void QgsGrass::onSearchPathFileChanged( const QString & path )
699+
{
700+
QgsDebugMsg( "path = " + path );
701+
QString searchFilePath = getDefaultMapsetPath() + "/SEARCH_PATH";
702+
if ( path == searchFilePath )
703+
{
704+
// changed or removed
705+
loadMapsetSearchPath();
706+
if ( !QFileInfo( searchFilePath ).exists() ) // removed
707+
{
708+
// reset watcher to mapset
709+
setMapsetSearchPathWatcher();
710+
}
711+
}
712+
else
713+
{
714+
// mapset directory changed
715+
if ( QFileInfo( searchFilePath ).exists() ) // search path file added
716+
{
717+
loadMapsetSearchPath();
718+
setMapsetSearchPathWatcher();
719+
}
720+
}
721+
}
722+
604723
jmp_buf QgsGrass::jumper;
605724

606725
bool QgsGrass::mNonInitializable = false;
@@ -860,6 +979,9 @@ QString QgsGrass::openMapset( const QString& gisdbase,
860979

861980
active = true;
862981

982+
QgsGrass::instance()->loadMapsetSearchPath();
983+
QgsGrass::instance()->setMapsetSearchPathWatcher();
984+
863985
// closeMapset() added at the beginning
864986
#if 0
865987
#ifndef Q_OS_WIN
@@ -936,6 +1058,7 @@ QString QgsGrass::closeMapset()
9361058
}
9371059
}
9381060

1061+
QgsGrass::instance()->setMapsetSearchPathWatcher(); // unset watcher
9391062
emit QgsGrass::instance()->mapsetChanged();
9401063
return QString::null;
9411064
}

‎src/providers/grass/qgsgrass.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ extern "C"
3636
#include "qgsfeature.h"
3737
#include "qgsfield.h"
3838
#include <qgsrectangle.h>
39+
#include <QFileSystemWatcher>
3940
#include <QProcess>
4041
#include <QString>
4142
#include <QMap>
@@ -172,6 +173,8 @@ class GRASS_LIB_EXPORT QgsGrass : public QObject
172173
int red1, red2, green1, green2, blue1, blue2;
173174
};
174175

176+
QgsGrass();
177+
175178
/** Get singleton instance of this class. Used as signals proxy between provider and plugin. */
176179
static QgsGrass* instance();
177180

@@ -198,6 +201,9 @@ class GRASS_LIB_EXPORT QgsGrass : public QObject
198201
//! Get default MAPSET, returns MAPSET name or empty string if not in active mode
199202
static QString getDefaultMapset();
200203

204+
//! Get default path to MAPSET (gisdbase/location/mapset) or empty string if not in active mode
205+
static QString getDefaultMapsetPath();
206+
201207
//! Init or reset GRASS library
202208
/*!
203209
\param gisdbase full path to GRASS GISDBASE.
@@ -217,6 +223,10 @@ class GRASS_LIB_EXPORT QgsGrass : public QObject
217223
* @param grassObject */
218224
static void setMapset( QgsGrassObject grassObject );
219225

226+
/** Check if mapset is in search pat set by g.mapsets
227+
* @return true if in search path */
228+
bool isMapsetInSearchPath( QString mapset );
229+
220230
//! Error codes returned by error()
221231
enum GERROR
222232
{
@@ -592,13 +602,22 @@ class GRASS_LIB_EXPORT QgsGrass : public QObject
592602

593603
void openOptions();
594604

605+
/** Read mapset search path from GRASS location */
606+
void loadMapsetSearchPath();
607+
608+
void setMapsetSearchPathWatcher();
609+
void onSearchPathFileChanged( const QString & path );
610+
595611
signals:
596612
/** Signal emitted when user changed GISBASE */
597613
void gisbaseChanged();
598614

599615
/** Signal emitted after mapset was opened */
600616
void mapsetChanged();
601617

618+
/** Signal emited when mapset search path changed (SEARCH_PATH file changed and it was loaded to mMapsetSearchPath) */
619+
void mapsetSearchPathChanged();
620+
602621
/** Emitted when path to modules config dir changed */
603622
void modulesConfigChanged();
604623

@@ -627,6 +646,10 @@ class GRASS_LIB_EXPORT QgsGrass : public QObject
627646
static QString defaultLocation;
628647
static QString defaultMapset;
629648

649+
// Mapsets in current search path
650+
QStringList mMapsetSearchPath;
651+
QFileSystemWatcher *mMapsetSearchPathWatcher;
652+
630653
/* last error in GRASS libraries */
631654
static GERROR lastError; // static, because used in constructor
632655
static QString error_message;

0 commit comments

Comments
 (0)
Please sign in to comment.