Skip to content

Commit f9460f9

Browse files
committedSep 9, 2015
[GRASS] module input model file system watcher
1 parent c86dcd0 commit f9460f9

File tree

4 files changed

+213
-41
lines changed

4 files changed

+213
-41
lines changed
 

‎src/plugins/grass/qgsgrassmoduleinput.cpp

Lines changed: 183 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -57,55 +57,207 @@ extern "C"
5757
/**************************** QgsGrassModuleInputModel ****************************/
5858
QgsGrassModuleInputModel::QgsGrassModuleInputModel( QObject *parent )
5959
: QStandardItemModel( parent )
60+
, mWatcher( 0 )
6061
{
6162
setColumnCount( 1 );
6263
reload();
64+
65+
QString locationPath = QgsGrass::getDefaultLocationPath();
66+
mWatcher = new QFileSystemWatcher( this );
67+
mWatcher->addPath( locationPath );
68+
69+
// Watching all dirs in loacation because a dir may become a mapset later, when WIND is created
70+
71+
//QStringList mapsets = QgsGrass::mapsets( QgsGrass::getDefaultGisdbase(), QgsGrass::getDefaultLocation() );
72+
QStringList dirNames = locationDirNames();
73+
foreach ( QString dirName, dirNames )
74+
{
75+
QString dirPath = locationPath + "/" + dirName;
76+
// Watch the dir in any case, WIND mabe created later
77+
mWatcher->addPath( dirPath );
78+
79+
foreach ( QString watchedDir, watchedDirs() )
80+
{
81+
watch( dirPath + "/" + watchedDir );
82+
}
83+
}
84+
connect( mWatcher, SIGNAL( directoryChanged( const QString & ) ), SLOT( onDirectoryChanged( const QString & ) ) );
6385
}
6486

65-
void QgsGrassModuleInputModel::reload()
87+
void QgsGrassModuleInputModel::onDirectoryChanged( const QString & path )
6688
{
67-
clear();
68-
QStringList mapsets = QgsGrass::mapsets( QgsGrass::getDefaultGisdbase(), QgsGrass::getDefaultLocation() );
69-
// Put current mapset on top
70-
mapsets.removeOne( QgsGrass::getDefaultMapset() );
71-
mapsets.prepend( QgsGrass::getDefaultMapset() );
89+
QgsDebugMsg( "path = " + path );
7290

73-
foreach ( QString mapset, mapsets )
91+
QString locationPath = QgsGrass::getDefaultLocationPath();
92+
QDir parentDir( path );
93+
parentDir.cdUp();
94+
QString mapset;
95+
96+
if ( path == locationPath )
7497
{
75-
bool currentMapset = mapset == QgsGrass::getDefaultMapset();
76-
QStandardItem *mapsetItem = new QStandardItem( mapset );
77-
mapsetItem->setData( mapset, MapsetRole );
78-
mapsetItem->setData( mapset, Qt::EditRole );
79-
mapsetItem->setData( QgsGrassObject::None, TypeRole );
80-
mapsetItem->setSelectable( false );
98+
QgsDebugMsg( "location = " + path );
99+
QStringList dirNames = locationDirNames();
100+
//QStringList mapsets = QgsGrass::mapsets( QgsGrass::getDefaultGisdbase(), QgsGrass::getDefaultLocation() );
81101

82-
QList<QgsGrassObject::Type> types;
83-
types << QgsGrassObject::Raster << QgsGrassObject::Vector;
84-
foreach ( QgsGrassObject::Type type, types )
102+
for ( int i = rowCount() - 1; i >= 0; i-- )
85103
{
86-
QStringList maps = QgsGrass::grassObjects( QgsGrass::getDefaultGisdbase() + "/" + QgsGrass::getDefaultLocation() + "/" + mapset, type );
87-
foreach ( QString map, maps )
104+
QString mapset = item( i )->text();
105+
if ( !QgsGrass::isMapset( locationPath + "/" + mapset ) )
88106
{
89-
if ( map.startsWith( "qgis_import_tmp_" ) )
90-
{
91-
continue;
92-
}
93-
QString mapName = map;
94-
// For now, for completer popup simplicity
95-
// TODO: implement tree view in popup
96-
if ( !currentMapset )
107+
QgsDebugMsg( "removed mapset " + mapset );
108+
removeRows( i, 1 );
109+
}
110+
}
111+
112+
foreach ( QString dirName, dirNames )
113+
{
114+
// Add to watcher in any case, either for WIND, cellhd or vector
115+
QString dirPath = locationPath + "/" + dirName;
116+
watch( dirPath );
117+
if ( QgsGrass::isMapset( dirPath ) && findItems( dirName ).isEmpty() )
118+
{
119+
addMapset( dirName );
120+
}
121+
}
122+
}
123+
else if ( parentDir.canonicalPath() == QDir( locationPath ).canonicalPath() ) // mapset
124+
{
125+
QgsDebugMsg( "mapset = " + path );
126+
QDir dir( path );
127+
mapset = dir.dirName();
128+
foreach ( QString watchedDir, watchedDirs() )
129+
{
130+
watch( path + "/" + watchedDir );
131+
}
132+
}
133+
else // cellhd or vector dir
134+
{
135+
QgsDebugMsg( "cellhd/vector = " + path );
136+
mapset = parentDir.dirName();
137+
}
138+
if ( !mapset.isEmpty() )
139+
{
140+
QList<QStandardItem *> items = findItems( mapset );
141+
if ( items.size() == 1 )
142+
{
143+
refreshMapset( items[0], mapset );
144+
}
145+
}
146+
}
147+
148+
void QgsGrassModuleInputModel::watch( const QString & path )
149+
{
150+
if ( !mWatcher->directories().contains( path ) && QFileInfo( path ).exists() )
151+
{
152+
mWatcher->addPath( path );
153+
}
154+
}
155+
156+
QStringList QgsGrassModuleInputModel::locationDirNames()
157+
{
158+
QString locationPath = QgsGrass::getDefaultLocationPath();
159+
QDir locationDir( locationPath );
160+
return locationDir.entryList( QDir::Dirs | QDir::NoDotAndDotDot );
161+
}
162+
163+
void QgsGrassModuleInputModel::addMapset( const QString & mapset )
164+
{
165+
QgsDebugMsg( "mapset = " + mapset );
166+
167+
168+
QStandardItem *mapsetItem = new QStandardItem( mapset );
169+
mapsetItem->setData( mapset, MapsetRole );
170+
mapsetItem->setData( mapset, Qt::EditRole );
171+
mapsetItem->setData( QgsGrassObject::None, TypeRole );
172+
mapsetItem->setSelectable( false );
173+
174+
refreshMapset( mapsetItem, mapset );
175+
176+
appendRow( mapsetItem );
177+
}
178+
179+
void QgsGrassModuleInputModel::refreshMapset( QStandardItem *mapsetItem, const QString & mapset )
180+
{
181+
QgsDebugMsg( "mapset = " + mapset );
182+
if ( !mapsetItem )
183+
{
184+
return;
185+
}
186+
bool currentMapset = mapset == QgsGrass::getDefaultMapset();
187+
QList<QgsGrassObject::Type> types;
188+
types << QgsGrassObject::Raster << QgsGrassObject::Vector;
189+
foreach ( QgsGrassObject::Type type, types )
190+
{
191+
QStringList maps = QgsGrass::grassObjects( QgsGrass::getDefaultGisdbase() + "/" + QgsGrass::getDefaultLocation() + "/" + mapset, type );
192+
QStringList mapNames;
193+
foreach ( QString map, maps )
194+
{
195+
if ( map.startsWith( "qgis_import_tmp_" ) )
196+
{
197+
continue;
198+
}
199+
QString mapName = map;
200+
// For now, for completer popup simplicity
201+
// TODO: implement tree view in popup
202+
if ( !currentMapset )
203+
{
204+
mapName += "@" + mapset;
205+
}
206+
207+
bool found = false;
208+
for ( int i = 0; i < mapsetItem->rowCount(); i++ )
209+
{
210+
QStandardItem * item = mapsetItem->child( i );
211+
if ( item->text() == mapName && item->data( TypeRole ).toInt() == type )
97212
{
98-
mapName += "@" + mapset;
213+
found = true;
214+
break;
99215
}
216+
}
217+
if ( !found )
218+
{
219+
QgsDebugMsg( "add map : " + mapName );
100220
QStandardItem *mapItem = new QStandardItem( mapName );
101221
mapItem->setData( mapName, Qt::EditRole );
102222
mapItem->setData( map, MapRole );
103223
mapItem->setData( mapset, MapsetRole );
104224
mapItem->setData( type, TypeRole );
105225
mapsetItem->appendRow( mapItem );
106226
}
227+
else
228+
{
229+
QgsDebugMsg( "map exists : " + mapName );
230+
}
231+
mapNames << mapName;
232+
}
233+
234+
for ( int i = mapsetItem->rowCount() - 1; i >= 0; i-- )
235+
{
236+
if ( mapsetItem->child( i )->data( TypeRole ).toInt() != type )
237+
{
238+
continue;
239+
}
240+
QString mapName = mapsetItem->child( i )->text();
241+
if ( !mapNames.contains( mapName ) )
242+
{
243+
QgsDebugMsg( "remove map : " + mapName );
244+
mapsetItem->removeRows( i, 1 );
245+
}
107246
}
108-
appendRow( mapsetItem );
247+
}
248+
}
249+
250+
void QgsGrassModuleInputModel::reload()
251+
{
252+
clear();
253+
QStringList mapsets = QgsGrass::mapsets( QgsGrass::getDefaultGisdbase(), QgsGrass::getDefaultLocation() );
254+
// Put current mapset on top
255+
mapsets.removeOne( QgsGrass::getDefaultMapset() );
256+
mapsets.prepend( QgsGrass::getDefaultMapset() );
257+
258+
foreach ( QString mapset, mapsets )
259+
{
260+
addMapset( mapset );
109261
}
110262
}
111263

@@ -612,7 +764,7 @@ QgsGrassModuleInput::QgsGrassModuleInput( QgsGrassModule *module,
612764

613765
QVBoxLayout *layout = new QVBoxLayout( this );
614766
// Map + region
615-
QHBoxLayout *mapLayout = new QHBoxLayout( this );
767+
QHBoxLayout *mapLayout = new QHBoxLayout();
616768
layout->addLayout( mapLayout );
617769

618770
// Map input
@@ -651,7 +803,7 @@ QgsGrassModuleInput::QgsGrassModuleInput( QgsGrassModule *module,
651803
// Vector layer + type
652804
if ( mType == QgsGrassObject::Vector && !multiple() )
653805
{
654-
QHBoxLayout *layerLayout = new QHBoxLayout( this );
806+
QHBoxLayout *layerLayout = new QHBoxLayout();
655807
layout->addLayout( layerLayout );
656808

657809
mLayerLabel = new QLabel( tr( "Sublayer" ), this );
@@ -661,7 +813,7 @@ QgsGrassModuleInput::QgsGrassModuleInput( QgsGrassModule *module,
661813
connect( mLayerComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( onLayerChanged() ) );
662814
layerLayout->addWidget( mLayerComboBox );
663815

664-
QHBoxLayout *typeLayout = new QHBoxLayout( this );
816+
QHBoxLayout *typeLayout = new QHBoxLayout();
665817
layerLayout->addLayout( typeLayout );
666818

667819
// Vector types
@@ -686,13 +838,6 @@ QgsGrassModuleInput::QgsGrassModuleInput( QgsGrassModule *module,
686838
layerLayout->addItem( new QSpacerItem( 10, 10, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
687839
}
688840

689-
690-
connect( QgsMapLayerRegistry::instance(), SIGNAL( layersAdded( QList<QgsMapLayer *> ) ),
691-
this, SLOT( updateQgisLayers() ) );
692-
connect( QgsMapLayerRegistry::instance(), SIGNAL( layersRemoved( QStringList ) ),
693-
this, SLOT( updateQgisLayers() ) );
694-
695-
696841
if ( !mMapId.isEmpty() )
697842
{
698843
QgsGrassModuleParam *item = mModuleStandardOptions->item( mMapId );

‎src/plugins/grass/qgsgrassmoduleinput.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <QComboBox>
2222
#include <QCompleter>
2323
#include <QFileSystemModel>
24+
#include <QFileSystemWatcher>
2425
#include <QGroupBox>
2526
#include <QListView>
2627
#include <QMap>
@@ -70,10 +71,20 @@ class QgsGrassModuleInputModel : public QStandardItemModel
7071
/** Reload current mapset */
7172
void reload();
7273

73-
signals:
74+
void onDirectoryChanged( const QString & path );
7475

75-
protected:
76+
signals:
7677

78+
private:
79+
void addMapset( const QString & mapset );
80+
void refreshMapset( QStandardItem *mapsetItem, const QString & mapset );
81+
// Add to watched paths if exists and if not yet watched
82+
void watch( const QString & path );
83+
// mapset watched dirs
84+
QStringList watchedDirs() { QStringList l; l << "cellhd" << "vector"; return l; }
85+
// names of
86+
QStringList locationDirNames();
87+
QFileSystemWatcher *mWatcher;
7788

7889
};
7990

@@ -171,11 +182,14 @@ class QgsGrassModuleInputComboBox : public QComboBox
171182

172183
class QgsGrassModuleInputSelectedDelegate : public QStyledItemDelegate
173184
{
185+
Q_OBJECT
174186
public:
175187
explicit QgsGrassModuleInputSelectedDelegate( QObject *parent = 0 );
176188

189+
void paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const override;
190+
191+
public slots:
177192
void handlePressed( const QModelIndex &index );
178-
void paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const;
179193

180194
private:
181195
mutable QModelIndex mPressedIndex;

‎src/providers/grass/qgsgrass.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,16 @@ QString QgsGrass::getDefaultLocation()
576576
return defaultLocation;
577577
}
578578

579+
QString QgsGrass::getDefaultLocationPath()
580+
{
581+
init();
582+
if ( !active )
583+
{
584+
return QString();
585+
}
586+
return defaultGisdbase + "/" + defaultLocation;
587+
}
588+
579589
QString QgsGrass::getDefaultMapset()
580590
{
581591
init();

‎src/providers/grass/qgsgrass.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,9 @@ class GRASS_LIB_EXPORT QgsGrass : public QObject
184184
//! Get default LOCATION_NAME, returns LOCATION_NAME name or empty string if not in active mode
185185
static QString getDefaultLocation();
186186

187+
//! Get default path to location (gisdbase/location) or empty string if not in active mode
188+
static QString getDefaultLocationPath();
189+
187190
//! Get default MAPSET, returns MAPSET name or empty string if not in active mode
188191
static QString getDefaultMapset();
189192

0 commit comments

Comments
 (0)
Please sign in to comment.