Skip to content

Commit 27c2b5c

Browse files
committedMay 20, 2015
[GRASS][FEATURE] copy layers within location mapsets using browser drag and drop
1 parent 80a8c49 commit 27c2b5c

File tree

6 files changed

+289
-142
lines changed

6 files changed

+289
-142
lines changed
 

‎src/providers/grass/qgsgrass.cpp‎

Lines changed: 90 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,52 @@ QgsGrassObject::QgsGrassObject( const QString& gisdbase, const QString& location
7676
{
7777
}
7878

79+
bool QgsGrassObject::setFromUri( const QString& uri )
80+
{
81+
QgsDebugMsg( "uri = " + uri );
82+
QFileInfo fi( uri );
83+
84+
if ( fi.isFile() )
85+
{
86+
QString path = fi.canonicalFilePath();
87+
QgsDebugMsg( "path = " + path );
88+
// /gisdbase_path/location/mapset/cellhd/raster_map
89+
QRegExp rx( "(.*)/([^/]*)/([^/]*)/cellhd/([^/]*)", Qt::CaseInsensitive );
90+
if ( rx.indexIn( path ) > -1 )
91+
{
92+
mGisdbase = rx.cap( 1 );
93+
mLocation = rx.cap( 2 );
94+
mMapset = rx.cap( 3 );
95+
mName = rx.cap( 4 );
96+
mType = Raster;
97+
return QgsGrass::isLocation( mGisdbase + "/" + mLocation );
98+
}
99+
}
100+
else
101+
{
102+
// /gisdbase_path/location/mapset/vector_map/layer
103+
// QFileInfo.canonicalPath() on non existing file does not work (returns empty string)
104+
// QFileInfo.absolutePath() does not necessarily remove symbolic links or redundant "." or ".."
105+
QDir dir = fi.dir(); // .../mapset/vector_map - does not exist
106+
if ( dir.cdUp() ) // .../mapset/
107+
{
108+
QString path = dir.canonicalPath();
109+
QRegExp rx( "(.*)/([^/]*)/([^/]*)" );
110+
if ( rx.indexIn( path ) > -1 )
111+
{
112+
mGisdbase = rx.cap( 1 );
113+
mLocation = rx.cap( 2 );
114+
mMapset = rx.cap( 3 );
115+
mName = fi.dir().dirName();
116+
mType = Vector;
117+
QgsDebugMsg( "parsed : " + toString() );
118+
return QgsGrass::isLocation( mGisdbase + "/" + mLocation );
119+
}
120+
}
121+
}
122+
return false;
123+
}
124+
79125
QString QgsGrassObject::elementShort() const
80126
{
81127
if ( mType == Raster )
@@ -122,9 +168,23 @@ QString QgsGrassObject::dirName( Type type )
122168
return "";
123169
}
124170

125-
bool QgsGrassObject::mapsetIdentical( const QgsGrassObject &other )
171+
QString QgsGrassObject::toString() const
172+
{
173+
return elementName() + " : " + mapsetPath() + " : " + mName;
174+
}
175+
176+
bool QgsGrassObject::locationIdentical( const QgsGrassObject &other ) const
126177
{
127-
return mGisdbase == other.mGisdbase && mLocation == other.mLocation && mMapset == other.mMapset;
178+
QFileInfo fi( locationPath() );
179+
QFileInfo otherFi( other.locationPath() );
180+
return fi == otherFi;
181+
}
182+
183+
bool QgsGrassObject::mapsetIdentical( const QgsGrassObject &other ) const
184+
{
185+
QFileInfo fi( mapsetPath() );
186+
QFileInfo otherFi( other.mapsetPath() );
187+
return fi == otherFi;
128188
}
129189

130190
QRegExp QgsGrassObject::newNameRegExp( Type type )
@@ -1792,11 +1852,32 @@ void QgsGrass::renameObject( const QgsGrassObject & object, const QString& newNa
17921852

17931853
arguments << object.elementShort() + "=" + object.name() + "," + newName;
17941854

1795-
int timeout = 10000; // What timeout to use? It can take long time on network or database
1855+
int timeout = -1; // What timeout to use? It can take long time on network or database
17961856
// throws QgsGrass::Exception
17971857
QgsGrass::runModule( object.gisdbase(), object.location(), object.mapset(), cmd, arguments, timeout, false );
17981858
}
17991859

1860+
void QgsGrass::copyObject( const QgsGrassObject & srcObject, const QgsGrassObject & destObject )
1861+
{
1862+
QgsDebugMsg( "srcObject = " + srcObject.toString() );
1863+
QgsDebugMsg( "destObject = " + destObject.toString() );
1864+
1865+
if ( !srcObject.locationIdentical( destObject ) ) // should not happen
1866+
{
1867+
throw QgsGrass::Exception( QObject::tr( "Attempt to copy from different location." ) );
1868+
}
1869+
1870+
QString cmd = "g.copy";
1871+
QStringList arguments;
1872+
1873+
arguments << srcObject.elementShort() + "=" + srcObject.name() + "@" + srcObject.mapset() + "," + destObject.name();
1874+
1875+
int timeout = -1; // What timeout to use? It can take long time on network or database
1876+
// throws QgsGrass::Exception
1877+
// TODO: g.copy does not seem to return error code if fails (6.4.3RC1)
1878+
QgsGrass::runModule( destObject.gisdbase(), destObject.location(), destObject.mapset(), cmd, arguments, timeout, false );
1879+
}
1880+
18001881
bool QgsGrass::deleteObject( const QgsGrassObject & object )
18011882
{
18021883
QgsDebugMsg( "entered" );
@@ -2008,28 +2089,14 @@ Qt::CaseSensitivity GRASS_LIB_EXPORT QgsGrass::caseSensitivity()
20082089
#endif
20092090
}
20102091

2011-
bool GRASS_LIB_EXPORT QgsGrass::isMapset( QString path )
2092+
bool GRASS_LIB_EXPORT QgsGrass::isLocation( const QString& path )
20122093
{
2013-
#if 0
2014-
/* TODO: G_is_mapset() was added to GRASS 6.1 06-05-24,
2015-
enable its use after some period (others do update) */
2016-
2017-
if ( QgsGrass::versionMajor() > 6 || QgsGrass::versionMinor() > 0 )
2018-
{
2019-
if ( G_is_mapset( path.toUtf8().constData() ) )
2020-
return true;
2021-
}
2022-
else
2023-
{
2024-
#endif
2025-
QString windf = path + "/WIND";
2026-
if ( QFile::exists( windf ) )
2027-
return true;
2028-
#if 0
2029-
}
2030-
#endif
2094+
return G_is_location( path.toUtf8().constData() ) == 1;
2095+
}
20312096

2032-
return false;
2097+
bool GRASS_LIB_EXPORT QgsGrass::isMapset( const QString& path )
2098+
{
2099+
return G_is_mapset( path.toUtf8().constData() ) == 1;
20332100
}
20342101

20352102
QString GRASS_LIB_EXPORT QgsGrass::lockFilePath()

‎src/providers/grass/qgsgrass.h‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ class GRASS_LIB_EXPORT QgsGrassObject
8181
void setGisdbase( const QString& gisdbase ) { mGisdbase = gisdbase; }
8282
QString location() const { return mLocation; }
8383
void setLocation( const QString& location ) { mLocation = location; }
84+
QString locationPath() const { return mGisdbase + "/" + mLocation; }
8485
QString mapset() const { return mMapset; }
8586
void setMapset( const QString& mapset ) { mMapset = mapset; }
8687
QString mapsetPath() const { return mGisdbase + "/" + mLocation + "/" + mMapset; }
@@ -89,6 +90,8 @@ class GRASS_LIB_EXPORT QgsGrassObject
8990
QString fullName() const { return mName + "@" + mMapset; }
9091
Type type() const { return mType; }
9192
void setType( Type type ) { mType = type; }
93+
// set from QGIS layer uri, returns true if set correctly, verifies also if location is a GRASS location
94+
bool setFromUri( const QString& uri );
9295
// element name used as modules param, e.g. g.remove element=name
9396
QString elementShort() const;
9497
// descriptive full name
@@ -97,8 +100,11 @@ class GRASS_LIB_EXPORT QgsGrassObject
97100
// name of directory in GRASS mapset to look for the object (cellhd,vector,window)
98101
QString dirName() const;
99102
static QString dirName( Type type );
103+
QString toString() const;
104+
// returns true if gisdbase and location are the same
105+
bool locationIdentical( const QgsGrassObject &other ) const;
100106
// returns true if gisdbase, location and mapset are the same
101-
bool mapsetIdentical( const QgsGrassObject &other );
107+
bool mapsetIdentical( const QgsGrassObject &other ) const;
102108
// get regexp patter for new names, e.g. vectors should not start with number
103109
static QRegExp newNameRegExp( Type type );
104110
private:
@@ -277,8 +283,11 @@ class QgsGrass
277283

278284
static GRASS_LIB_EXPORT void init( void );
279285

286+
//! test if the directory is location
287+
static GRASS_LIB_EXPORT bool isLocation( const QString& path );;
288+
280289
// ! test if the directory is mapset
281-
static GRASS_LIB_EXPORT bool isMapset( QString path );
290+
static GRASS_LIB_EXPORT bool isMapset( const QString& path );
282291

283292
// ! Get the lock file
284293
static GRASS_LIB_EXPORT QString lockFilePath();
@@ -357,6 +366,9 @@ class QgsGrass
357366
// ! Rename GRASS object, throws QgsGrass::Exception
358367
static GRASS_LIB_EXPORT void renameObject( const QgsGrassObject & object, const QString& newName );
359368

369+
// ! Copy GRASS object, throws QgsGrass::Exception
370+
static GRASS_LIB_EXPORT void copyObject( const QgsGrassObject & srcObject, const QgsGrassObject & destObject );
371+
360372
// ! Delete map
361373
static GRASS_LIB_EXPORT bool deleteObject( const QgsGrassObject & object );
362374

‎src/providers/grass/qgsgrassimport.cpp‎

Lines changed: 72 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,19 @@ extern "C"
3737
QgsGrassImport::QgsGrassImport( QgsGrassObject grassObject )
3838
: QObject()
3939
, mGrassObject( grassObject )
40+
, mFutureWatcher( 0 )
4041
{
4142
}
4243

44+
QgsGrassImport::~QgsGrassImport()
45+
{
46+
if ( mFutureWatcher && !mFutureWatcher->isFinished() )
47+
{
48+
QgsDebugMsg( "mFutureWatcher not finished -> waitForFinished()" );
49+
mFutureWatcher->waitForFinished();
50+
}
51+
}
52+
4353
void QgsGrassImport::setError( QString error )
4454
{
4555
QgsDebugMsg( "error: " + error );
@@ -51,6 +61,34 @@ QString QgsGrassImport::error()
5161
return mError;
5262
}
5363

64+
void QgsGrassImport::importInThread()
65+
{
66+
QgsDebugMsg( "entered" );
67+
mFutureWatcher = new QFutureWatcher<bool>( this );
68+
connect( mFutureWatcher, SIGNAL( finished() ), SLOT( onFinished() ) );
69+
mFutureWatcher->setFuture( QtConcurrent::run( run, this ) );
70+
}
71+
72+
bool QgsGrassImport::run( QgsGrassImport *imp )
73+
{
74+
QgsDebugMsg( "entered" );
75+
imp->import();
76+
return true;
77+
}
78+
79+
void QgsGrassImport::onFinished()
80+
{
81+
QgsDebugMsg( "entered" );
82+
emit finished( this );
83+
}
84+
85+
QStringList QgsGrassImport::names() const
86+
{
87+
QStringList list;
88+
list << mGrassObject.name();
89+
return list;
90+
}
91+
5492
//------------------------------ QgsGrassRasterImport ------------------------------------
5593
QgsGrassRasterImport::QgsGrassRasterImport( QgsRasterPipe* pipe, const QgsGrassObject& grassObject,
5694
const QgsRectangle &extent, int xSize, int ySize )
@@ -59,7 +97,6 @@ QgsGrassRasterImport::QgsGrassRasterImport( QgsRasterPipe* pipe, const QgsGrassO
5997
, mExtent( extent )
6098
, mXSize( xSize )
6199
, mYSize( ySize )
62-
, mFutureWatcher( 0 )
63100
{
64101
}
65102

@@ -73,21 +110,6 @@ QgsGrassRasterImport::~QgsGrassRasterImport()
73110
delete mPipe;
74111
}
75112

76-
void QgsGrassRasterImport::importInThread()
77-
{
78-
QgsDebugMsg( "entered" );
79-
mFutureWatcher = new QFutureWatcher<bool>( this );
80-
connect( mFutureWatcher, SIGNAL( finished() ), SLOT( onFinished() ) );
81-
mFutureWatcher->setFuture( QtConcurrent::run( run, this ) );
82-
}
83-
84-
bool QgsGrassRasterImport::run( QgsGrassRasterImport *imp )
85-
{
86-
QgsDebugMsg( "entered" );
87-
imp->import();
88-
return true;
89-
}
90-
91113
bool QgsGrassRasterImport::import()
92114
{
93115
QgsDebugMsg( "entered" );
@@ -152,7 +174,7 @@ bool QgsGrassRasterImport::import()
152174
{
153175
name += QString( "_%1" ).arg( band );
154176
}
155-
arguments.append( "output=" + name );
177+
arguments.append( "output=" + name ); // get list of all output names
156178
QTemporaryFile gisrcFile;
157179
QProcess* process = 0;
158180
try
@@ -236,13 +258,7 @@ bool QgsGrassRasterImport::import()
236258
return true;
237259
}
238260

239-
void QgsGrassRasterImport::onFinished()
240-
{
241-
QgsDebugMsg( "entered" );
242-
emit finished( this );
243-
}
244-
245-
QString QgsGrassRasterImport::uri() const
261+
QString QgsGrassRasterImport::srcDescription() const
246262
{
247263
if ( !mPipe || !mPipe->provider() )
248264
{
@@ -285,7 +301,6 @@ QStringList QgsGrassRasterImport::names() const
285301
QgsGrassVectorImport::QgsGrassVectorImport( QgsVectorDataProvider* provider, const QgsGrassObject& grassObject )
286302
: QgsGrassImport( grassObject )
287303
, mProvider( provider )
288-
, mFutureWatcher( 0 )
289304
{
290305
}
291306

@@ -299,24 +314,8 @@ QgsGrassVectorImport::~QgsGrassVectorImport()
299314
delete mProvider;
300315
}
301316

302-
void QgsGrassVectorImport::importInThread()
303-
{
304-
QgsDebugMsg( "entered" );
305-
mFutureWatcher = new QFutureWatcher<bool>( this );
306-
connect( mFutureWatcher, SIGNAL( finished() ), SLOT( onFinished() ) );
307-
mFutureWatcher->setFuture( QtConcurrent::run( run, this ) );
308-
}
309-
310-
bool QgsGrassVectorImport::run( QgsGrassVectorImport *imp )
311-
{
312-
QgsDebugMsg( "entered" );
313-
imp->import();
314-
return true;
315-
}
316-
317317
bool QgsGrassVectorImport::import()
318318
{
319-
320319
QgsDebugMsg( "entered" );
321320

322321
if ( !mProvider )
@@ -432,13 +431,7 @@ bool QgsGrassVectorImport::import()
432431
return true;
433432
}
434433

435-
void QgsGrassVectorImport::onFinished()
436-
{
437-
QgsDebugMsg( "entered" );
438-
emit finished( this );
439-
}
440-
441-
QString QgsGrassVectorImport::uri() const
434+
QString QgsGrassVectorImport::srcDescription() const
442435
{
443436
if ( !mProvider )
444437
{
@@ -447,9 +440,36 @@ QString QgsGrassVectorImport::uri() const
447440
return mProvider->dataSourceUri();
448441
}
449442

450-
QStringList QgsGrassVectorImport::names() const
443+
//------------------------------ QgsGrassCopy ------------------------------------
444+
QgsGrassCopy::QgsGrassCopy( const QgsGrassObject& srcObject, const QgsGrassObject& destObject )
445+
: QgsGrassImport( destObject )
446+
, mSrcObject( srcObject )
451447
{
452-
QStringList list;
453-
list << mGrassObject.name();
454-
return list;
448+
}
449+
450+
QgsGrassCopy::~QgsGrassCopy()
451+
{
452+
}
453+
454+
bool QgsGrassCopy::import()
455+
{
456+
QgsDebugMsg( "entered" );
457+
458+
try
459+
{
460+
QgsGrass::copyObject( mSrcObject, mGrassObject );
461+
}
462+
catch ( QgsGrass::Exception &e )
463+
{
464+
setError( e.what() );
465+
return false;
466+
}
467+
468+
return true;
469+
}
470+
471+
472+
QString QgsGrassCopy::srcDescription() const
473+
{
474+
return mSrcObject.toString();
455475
}

‎src/providers/grass/qgsgrassimport.h‎

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,29 @@ class GRASS_LIB_EXPORT QgsGrassImport : public QObject
3030
Q_OBJECT
3131
public:
3232
QgsGrassImport( QgsGrassObject grassObject );
33-
virtual ~QgsGrassImport() {}
33+
virtual ~QgsGrassImport();
3434
QgsGrassObject grassObject() const { return mGrassObject; }
35-
virtual void importInThread() = 0;
36-
virtual QString uri() const = 0;
35+
virtual void importInThread();
36+
virtual bool import() = 0;
37+
// source description for error message purposes (maybe uri or something similar)
38+
virtual QString srcDescription() const = 0;
3739
// get error if import failed
3840
QString error();
39-
virtual QStringList names() const = 0;
41+
virtual QStringList names() const;
42+
43+
public slots:
44+
void onFinished();
4045

4146
signals:
4247
// sent when process finished
4348
void finished( QgsGrassImport *import );
4449

4550
protected:
51+
static bool run( QgsGrassImport *imp );
4652
void setError( QString error );
4753
QgsGrassObject mGrassObject;
4854
QString mError;
55+
QFutureWatcher<bool>* mFutureWatcher;
4956
};
5057

5158
class GRASS_LIB_EXPORT QgsGrassRasterImport : public QgsGrassImport
@@ -56,22 +63,18 @@ class GRASS_LIB_EXPORT QgsGrassRasterImport : public QgsGrassImport
5663
QgsGrassRasterImport( QgsRasterPipe* pipe, const QgsGrassObject& grassObject,
5764
const QgsRectangle &extent, int xSize, int ySize );
5865
~QgsGrassRasterImport();
59-
bool import();
60-
void importInThread() override;
61-
QString uri() const override;
66+
bool import() override;
67+
QString srcDescription() const override;
6268
// get list of extensions (for bands)
6369
static QStringList extensions( QgsRasterDataProvider* provider );
6470
// get list of all output names (basename + extension for each band)
6571
QStringList names() const override;
66-
public slots:
67-
void onFinished();
72+
6873
private:
69-
static bool run( QgsGrassRasterImport *imp );
7074
QgsRasterPipe* mPipe;
7175
QgsRectangle mExtent;
7276
int mXSize;
7377
int mYSize;
74-
QFutureWatcher<bool>* mFutureWatcher;
7578
};
7679

7780
class GRASS_LIB_EXPORT QgsGrassVectorImport : public QgsGrassImport
@@ -81,17 +84,26 @@ class GRASS_LIB_EXPORT QgsGrassVectorImport : public QgsGrassImport
8184
// takes provider ownership
8285
QgsGrassVectorImport( QgsVectorDataProvider* provider, const QgsGrassObject& grassObject );
8386
~QgsGrassVectorImport();
84-
bool import();
85-
void importInThread() override;
86-
QString uri() const override;
87-
// get list of all output names
88-
QStringList names() const override;
89-
public slots:
90-
void onFinished();
87+
bool import() override;
88+
QString srcDescription() const override;
89+
9190
private:
92-
static bool run( QgsGrassVectorImport *imp );
9391
QgsVectorDataProvider* mProvider;
94-
QFutureWatcher<bool>* mFutureWatcher;
92+
};
93+
94+
class GRASS_LIB_EXPORT QgsGrassCopy : public QgsGrassImport
95+
{
96+
Q_OBJECT
97+
public:
98+
// takes provider ownership
99+
QgsGrassCopy( const QgsGrassObject& srcObject, const QgsGrassObject& destObject );
100+
~QgsGrassCopy();
101+
bool import() override;
102+
QString srcDescription() const override;
103+
104+
private:
105+
QgsGrassObject mSrcObject;
106+
95107
};
96108

97109
#endif // QGSGRASSIMPORT_H

‎src/providers/grass/qgsgrassprovidermodule.cpp‎

Lines changed: 81 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,6 @@ QgsGrassLocationItem::QgsGrassLocationItem( QgsDataItem* parent, QString dirPath
4646
mType = QgsDataItem::Directory;
4747
}
4848

49-
bool QgsGrassLocationItem::isLocation( QString path )
50-
{
51-
//QgsDebugMsg( "path = " + path );
52-
return QFile::exists( path + "/" + "PERMANENT" + "/" + "DEFAULT_WIND" );
53-
}
54-
5549
QVector<QgsDataItem*>QgsGrassLocationItem::createChildren()
5650
{
5751
QVector<QgsDataItem*> mapsets;
@@ -63,7 +57,7 @@ QVector<QgsDataItem*>QgsGrassLocationItem::createChildren()
6357
{
6458
QString path = dir.absoluteFilePath( name );
6559

66-
if ( QgsGrassMapsetItem::isMapset( path ) )
60+
if ( QgsGrass::isMapset( path ) )
6761
{
6862
QgsGrassMapsetItem * mapset = new QgsGrassMapsetItem( this, path, mPath + "/" + name );
6963
mapsets.append( mapset );
@@ -89,11 +83,6 @@ QgsGrassMapsetItem::QgsGrassMapsetItem( QgsDataItem* parent, QString dirPath, QS
8983
mIconName = "grass_mapset.png";
9084
}
9185

92-
bool QgsGrassMapsetItem::isMapset( QString path )
93-
{
94-
return QFile::exists( path + "/WIND" );
95-
}
96-
9786
QVector<QgsDataItem*> QgsGrassMapsetItem::createChildren()
9887
{
9988
QgsDebugMsg( "Entered" );
@@ -122,8 +111,8 @@ QVector<QgsDataItem*> QgsGrassMapsetItem::createChildren()
122111
// somewhere not properly escaped (there was bug in QgsMimeDataUtils for example)
123112
QString uri = mDirPath + "/" + name + "/" + layerName;
124113
QgsLayerItem::LayerType layerType = QgsLayerItem::Vector;
125-
QString typeName = layerName.split( "_" )[1];
126-
QString baseLayerName = layerName.split( "_" )[0];
114+
QString typeName = layerName.split( "_" ).value( 1 );
115+
QString baseLayerName = layerName.split( "_" ).value( 0 );
127116

128117
if ( typeName == "point" )
129118
layerType = QgsLayerItem::Point;
@@ -135,8 +124,8 @@ QVector<QgsDataItem*> QgsGrassMapsetItem::createChildren()
135124
QString layerPath = mapPath + "/" + layerName;
136125
if ( !map )
137126
{
138-
/* This may happen (one layer only) in GRASS 7 with points (no topo layers) */
139-
QgsLayerItem *layer = new QgsGrassVectorLayerItem( this, vectorObject, name + " " + baseLayerName, layerPath, uri, layerType, true );
127+
/* This may happen (one layer only) in GRASS 7 with points (no topo layers) or if topo layers are disabled */
128+
QgsLayerItem *layer = new QgsGrassVectorLayerItem( this, vectorObject, name, layerPath, uri, layerType, true );
140129
//layer->setState( Populated );
141130
items.append( layer );
142131
}
@@ -228,53 +217,93 @@ bool QgsGrassMapsetItem::handleDrop( const QMimeData * data, Qt::DropAction )
228217
QStringList extensions;
229218
QStringList existingNames;
230219
QRegExp regExp;
220+
QgsGrassObject srcObject;
221+
QString srcName;
222+
223+
// use g.copy for GRASS maps in the same location
224+
bool useCopy = false;
225+
231226
if ( u.layerType == "raster" )
232227
{
233-
rasterProvider = qobject_cast<QgsRasterDataProvider*>( QgsProviderRegistry::instance()->provider( u.providerKey, u.uri ) );
234-
provider = rasterProvider;
228+
if ( u.providerKey == "grassraster" && srcObject.setFromUri( u.uri )
229+
&& srcObject.locationIdentical( mapsetObject ) )
230+
{
231+
useCopy = true;
232+
}
233+
else
234+
{
235+
rasterProvider = qobject_cast<QgsRasterDataProvider*>( QgsProviderRegistry::instance()->provider( u.providerKey, u.uri ) );
236+
provider = rasterProvider;
237+
}
235238
existingNames = existingRasters;
236239
regExp = QgsGrassObject::newNameRegExp( QgsGrassObject::Raster );
237240
}
238241
else if ( u.layerType == "vector" )
239242
{
240-
vectorProvider = qobject_cast<QgsVectorDataProvider*>( QgsProviderRegistry::instance()->provider( u.providerKey, u.uri ) );
241-
provider = vectorProvider;
243+
if ( u.providerKey == "grass" && srcObject.setFromUri( u.uri )
244+
&& srcObject.locationIdentical( mapsetObject ) )
245+
{
246+
useCopy = true;
247+
}
248+
else
249+
{
250+
vectorProvider = qobject_cast<QgsVectorDataProvider*>( QgsProviderRegistry::instance()->provider( u.providerKey, u.uri ) );
251+
provider = vectorProvider;
252+
}
242253
existingNames = existingVectors;
243254
regExp = QgsGrassObject::newNameRegExp( QgsGrassObject::Vector );
244255
}
245256
QgsDebugMsg( "existingNames = " + existingNames.join( "," ) );
246257

247-
if ( !provider )
258+
if ( useCopy )
248259
{
249-
errors.append( tr( "Cannot create provider %1 : %2" ).arg( u.providerKey ).arg( u.uri ) );
250-
continue;
251-
}
252-
if ( !provider->isValid() )
253-
{
254-
errors.append( tr( "Provider is not valid %1 : %2" ).arg( u.providerKey ).arg( u.uri ) );
255-
delete provider;
256-
continue;
260+
srcName = srcObject.name();
257261
}
258-
259-
if ( u.layerType == "raster" )
262+
else
260263
{
261-
extensions = QgsGrassRasterImport::extensions( rasterProvider );
264+
if ( !provider )
265+
{
266+
errors.append( tr( "Cannot create provider %1 : %2" ).arg( u.providerKey ).arg( u.uri ) );
267+
continue;
268+
}
269+
if ( !provider->isValid() )
270+
{
271+
errors.append( tr( "Provider is not valid %1 : %2" ).arg( u.providerKey ).arg( u.uri ) );
272+
delete provider;
273+
continue;
274+
}
275+
if ( u.layerType == "raster" )
276+
{
277+
extensions = QgsGrassRasterImport::extensions( rasterProvider );
278+
}
279+
srcName = u.name;
262280
}
263281

264-
QString newName = u.name;
265-
if ( QgsNewNameDialog::exists( u.name, extensions, existingNames, caseSensitivity ) )
282+
// TODO: add a method in QgsGrass to convert a name to GRASS valid name
283+
QString destName = srcName.replace( " ", "_" );
284+
if ( QgsNewNameDialog::exists( destName, extensions, existingNames, caseSensitivity ) )
266285
{
267-
QgsNewNameDialog dialog( u.name, u.name, extensions, existingNames, regExp, caseSensitivity );
286+
QgsNewNameDialog dialog( srcName, destName, extensions, existingNames, regExp, caseSensitivity );
268287
if ( dialog.exec() != QDialog::Accepted )
269288
{
270289
delete provider;
271290
continue;
272291
}
273-
newName = dialog.name();
292+
destName = dialog.name();
274293
}
275294

276295
QgsGrassImport *import = 0;
277-
if ( u.layerType == "raster" )
296+
QStringList newNames;
297+
if ( useCopy )
298+
{
299+
QgsDebugMsg( "location is the same -> g.copy" );
300+
QgsGrassObject destObject( mapsetObject );
301+
destObject.setName( destName );
302+
destObject.setType( srcObject.type() );
303+
import = new QgsGrassCopy( srcObject, destObject );
304+
}
305+
306+
else if ( u.layerType == "raster" )
278307
{
279308
QgsRectangle newExtent = rasterProvider->extent();
280309
int newXSize;
@@ -298,6 +327,7 @@ bool QgsGrassMapsetItem::handleDrop( const QMimeData * data, Qt::DropAction )
298327
continue;
299328
}
300329
newXSize = window.cols;
330+
301331
newYSize = window.rows;
302332

303333
newExtent = QgsGrass::extent( &window );
@@ -326,13 +356,13 @@ bool QgsGrassMapsetItem::handleDrop( const QMimeData * data, Qt::DropAction )
326356
QgsDebugMsg( QString( "newXSize = %1 newYSize = %2" ).arg( newXSize ).arg( newYSize ) );
327357

328358
QString path = mPath + "/" + "raster" + "/" + u.name;
329-
QgsGrassObject rasterObject( mGisdbase, mLocation, mName, newName, QgsGrassObject::Raster );
359+
QgsGrassObject rasterObject( mGisdbase, mLocation, mName, destName, QgsGrassObject::Raster );
330360
import = new QgsGrassRasterImport( pipe, rasterObject, newExtent, newXSize, newYSize ); // takes pipe ownership
331361
}
332362
else if ( u.layerType == "vector" )
333363
{
334364
QString path = mPath + "/" + "raster" + "/" + u.name;
335-
QgsGrassObject vectorObject( mGisdbase, mLocation, mName, newName, QgsGrassObject::Vector );
365+
QgsGrassObject vectorObject( mGisdbase, mLocation, mName, destName, QgsGrassObject::Vector );
336366
import = new QgsGrassVectorImport( vectorProvider, vectorObject ); // takes provider ownership
337367
}
338368

@@ -390,7 +420,7 @@ void QgsGrassMapsetItem::onImportFinished( QgsGrassImport* import )
390420
{
391421
QgsMessageOutput *output = QgsMessageOutput::createMessageOutput();
392422
output->setTitle( tr( "Import to GRASS mapset failed" ) );
393-
output->setMessage( tr( "Failed to import %1 to %2: %3" ).arg( import->uri() ).arg( import->grassObject()
423+
output->setMessage( tr( "Failed to import %1 to %2: %3" ).arg( import->srcDescription() ).arg( import->grassObject()
394424
.mapsetPath() ).arg( import->error() ), QgsMessageOutput::MessageText );
395425
output->showMessage();
396426
}
@@ -553,12 +583,20 @@ QgsGrassVectorLayerItem::QgsGrassVectorLayerItem( QgsDataItem* parent, QgsGrassO
553583
: QgsGrassObjectItem( parent, grassObject, layerName, path, uri, layerType, "grass", mSingleLayer )
554584
, mSingleLayer( singleLayer )
555585
{
586+
556587
}
557588

558589
QString QgsGrassVectorLayerItem::layerName() const
559590
{
560-
// to get map + layer when added from browser
561-
return mGrassObject.name() + " " + name();
591+
if ( mSingleLayer )
592+
{
593+
return name();
594+
}
595+
else
596+
{
597+
// to get map + layer when added from browser
598+
return mGrassObject.name() + " " + name();
599+
}
562600
}
563601

564602
//----------------------- QgsGrassRasterItem ------------------------------
@@ -588,7 +626,7 @@ QGISEXTERN int dataCapabilities()
588626

589627
QGISEXTERN QgsDataItem * dataItem( QString theDirPath, QgsDataItem* parentItem )
590628
{
591-
if ( QgsGrassLocationItem::isLocation( theDirPath ) )
629+
if ( QgsGrass::isLocation( theDirPath ) )
592630
{
593631
QString path;
594632
QDir dir( theDirPath );

‎src/providers/grass/qgsgrassprovidermodule.h‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ class QgsGrassLocationItem : public QgsDirectoryItem
2929

3030
QIcon icon() override { return QgsDataItem::icon(); }
3131

32-
static bool isLocation( QString path );
3332
QVector<QgsDataItem*> createChildren() override;
3433
};
3534

@@ -41,7 +40,6 @@ class QgsGrassMapsetItem : public QgsDirectoryItem
4140

4241
QIcon icon() override { return QgsDataItem::icon(); }
4342

44-
static bool isMapset( QString path );
4543
QVector<QgsDataItem*> createChildren() override;
4644
virtual bool acceptDrop() override { return true; }
4745
virtual bool handleDrop( const QMimeData * data, Qt::DropAction action ) override;

0 commit comments

Comments
 (0)
Please sign in to comment.