@@ -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+
265270QString 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+
548564void 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+
604723jmp_buf QgsGrass::jumper;
605724
606725bool 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}
0 commit comments