Skip to content

Commit

Permalink
[GRASS][FEATURE] rename maps in browser
Browse files Browse the repository at this point in the history
  • Loading branch information
blazek committed May 20, 2015
1 parent b89b6a5 commit eaeea21
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 27 deletions.
80 changes: 69 additions & 11 deletions src/providers/grass/qgsgrass.cpp
Expand Up @@ -105,11 +105,42 @@ QString QgsGrassObject::elementName( Type type )
return "";
}

QString QgsGrassObject::dirName() const
{
return dirName( mType );
}

QString QgsGrassObject::dirName( Type type )
{
if ( type == Raster )
return "cellhd";
else if ( type == Vector )
return "vector";
else if ( type == Region )
return "windows";
else
return "";
}

bool QgsGrassObject::mapsetIdentical( const QgsGrassObject &other )
{
return mGisdbase == other.mGisdbase && mLocation == other.mLocation && mMapset == other.mMapset;
}

QRegExp QgsGrassObject::newNameRegExp( Type type )
{
QRegExp rx;
if ( type == QgsGrassObject::Vector )
{
rx.setPattern( "[A-Za-z_][A-Za-z0-9_]+" );
}
else
{
rx.setPattern( "[A-Za-z0-9_.]+" );
}
return rx;
}

#ifdef Q_OS_WIN
#include <windows.h>
QString GRASS_LIB_EXPORT QgsGrass::shortPath( const QString &path )
Expand Down Expand Up @@ -1085,15 +1116,22 @@ QStringList GRASS_LIB_EXPORT QgsGrass::elements( const QString& gisdbase, const

QStringList GRASS_LIB_EXPORT QgsGrass::elements( const QString& mapsetPath, const QString& element )
{
QgsDebugMsg( QString( "mapsetPath = %1" ).arg( mapsetPath ) );
QgsDebugMsg( QString( "mapsetPath = %1 element = %2" ).arg( mapsetPath ).arg( element ) );

QStringList list;

if ( mapsetPath.isEmpty() )
return list;

QDir d = QDir( mapsetPath + "/" + element );
d.setFilter( QDir::Files );
if ( element == "vector" )
{
d.setFilter( QDir::Dirs | QDir::NoDotAndDotDot );
}
else
{
d.setFilter( QDir::Files );
}

for ( unsigned int i = 0; i < d.count(); i++ )
{
Expand All @@ -1102,17 +1140,15 @@ QStringList GRASS_LIB_EXPORT QgsGrass::elements( const QString& mapsetPath, con
return list;
}

bool GRASS_LIB_EXPORT QgsGrass::objectExists( const QgsGrassObject& grassObject )
QStringList GRASS_LIB_EXPORT QgsGrass::grassObjects( const QString& mapsetPath, QgsGrassObject::Type type )
{
QString path = grassObject.mapsetPath();
if ( grassObject.type() == QgsGrassObject::Raster )
path += "/cellhd";
else if ( grassObject.type() == QgsGrassObject::Vector )
path += "/vector";
else if ( grassObject.type() == QgsGrassObject::Region )
path += "/windows";
return QgsGrass::elements( mapsetPath, QgsGrassObject::dirName( type ) );
}

path += "/" + grassObject.name();
bool GRASS_LIB_EXPORT QgsGrass::objectExists( const QgsGrassObject& grassObject )
{
QString path = grassObject.mapsetPath() + "/" + QgsGrassObject::dirName( grassObject.type() )
+ "/" + grassObject.name();
QFileInfo fi( path );
return fi.exists();
}
Expand Down Expand Up @@ -1748,6 +1784,19 @@ QMap<QString, QString> GRASS_LIB_EXPORT QgsGrass::query( QString gisdbase, QStri
return result;
}

void QgsGrass::renameObject( const QgsGrassObject & object, const QString& newName )
{
QgsDebugMsg( "entered" );
QString cmd = "g.rename";
QStringList arguments;

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

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

bool QgsGrass::deleteObject( const QgsGrassObject & object )
{
QgsDebugMsg( "entered" );
Expand Down Expand Up @@ -1950,6 +1999,15 @@ QString GRASS_LIB_EXPORT QgsGrass::versionString()
return QString( GRASS_VERSION_STRING );
}

Qt::CaseSensitivity GRASS_LIB_EXPORT QgsGrass::caseSensitivity()
{
#ifdef WIN32
return Qt::CaseInsensitive;
#else
return Qt::CaseSensitive;
#endif
}

bool GRASS_LIB_EXPORT QgsGrass::isMapset( QString path )
{
#if 0
Expand Down
15 changes: 15 additions & 0 deletions src/providers/grass/qgsgrass.h
Expand Up @@ -39,6 +39,7 @@ extern "C"
#include <QString>
#include <QMap>
#include <QHash>
#include <QRegExp>
#include <QTemporaryFile>
class QgsCoordinateReferenceSystem;
class QgsRectangle;
Expand Down Expand Up @@ -93,8 +94,13 @@ class GRASS_LIB_EXPORT QgsGrassObject
// descriptive full name
QString elementName() const;
static QString elementName( Type type );
// name of directory in GRASS mapset to look for the object (cellhd,vector,window)
QString dirName() const;
static QString dirName( Type type );
// returns true if gisdbase, location and mapset are the same
bool mapsetIdentical( const QgsGrassObject &other );
// get regexp patter for new names, e.g. vectors should not start with number
static QRegExp newNameRegExp( Type type );
private:
QString mGisdbase;
QString mLocation;
Expand Down Expand Up @@ -216,10 +222,14 @@ class QgsGrass
const QString& mapset, const QString& mapName );

//! List of elements
// TODO rename elements to objects
static GRASS_LIB_EXPORT QStringList elements( const QString& gisdbase, const QString& locationName,
const QString& mapsetName, const QString& element );
static GRASS_LIB_EXPORT QStringList elements( const QString& mapsetPath, const QString& element );

//! List of existing objects
static GRASS_LIB_EXPORT QStringList grassObjects( const QString& mapsetPath, QgsGrassObject::Type type );

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

Expand Down Expand Up @@ -344,6 +354,9 @@ class QgsGrass
static GRASS_LIB_EXPORT QMap<QString, QString> query( QString gisdbase, QString location,
QString mapset, QString map, QgsGrassObject::Type type, double x, double y );

// ! Rename GRASS object, throws QgsGrass::Exception
static GRASS_LIB_EXPORT void renameObject( const QgsGrassObject & object, const QString& newName );

// ! Delete map
static GRASS_LIB_EXPORT bool deleteObject( const QgsGrassObject & object );

Expand All @@ -365,6 +378,8 @@ class QgsGrass
static GRASS_LIB_EXPORT int versionRelease();
static GRASS_LIB_EXPORT QString versionString();

// files case sensitivity (insensitive on windows)
static GRASS_LIB_EXPORT Qt::CaseSensitivity caseSensitivity();
// set environment variable
static GRASS_LIB_EXPORT void putEnv( QString name, QString value );

Expand Down
94 changes: 80 additions & 14 deletions src/providers/grass/qgsgrassprovidermodule.cpp
Expand Up @@ -29,6 +29,7 @@
#include <QFileInfo>
#include <QDir>
#include <QLabel>
#include <QObject>

//----------------------- QgsGrassLocationItem ------------------------------

Expand Down Expand Up @@ -212,11 +213,8 @@ bool QgsGrassMapsetItem::handleDrop( const QMimeData * data, Qt::DropAction )

QStringList errors;
QgsMimeDataUtils::UriList lst = QgsMimeDataUtils::decodeUriList( data );
#ifdef WIN32
Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive;
#else
Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive;
#endif
Qt::CaseSensitivity caseSensitivity = QgsGrass::caseSensitivity();

foreach ( const QgsMimeDataUtils::Uri& u, lst )
{
if ( u.layerType != "raster" && u.layerType != "vector" )
Expand All @@ -229,17 +227,20 @@ bool QgsGrassMapsetItem::handleDrop( const QMimeData * data, Qt::DropAction )
QgsDataProvider* provider = 0;
QStringList extensions;
QStringList existingNames;
QRegExp regExp;
if ( u.layerType == "raster" )
{
rasterProvider = qobject_cast<QgsRasterDataProvider*>( QgsProviderRegistry::instance()->provider( u.providerKey, u.uri ) );
provider = rasterProvider;
existingNames = existingRasters;
regExp = QgsGrassObject::newNameRegExp( QgsGrassObject::Raster );
}
else if ( u.layerType == "vector" )
{
vectorProvider = qobject_cast<QgsVectorDataProvider*>( QgsProviderRegistry::instance()->provider( u.providerKey, u.uri ) );
provider = vectorProvider;
existingNames = existingVectors;
regExp = QgsGrassObject::newNameRegExp( QgsGrassObject::Vector );
}
QgsDebugMsg( "existingNames = " + existingNames.join( "," ) );

Expand All @@ -263,7 +264,7 @@ bool QgsGrassMapsetItem::handleDrop( const QMimeData * data, Qt::DropAction )
QString newName = u.name;
if ( QgsNewNameDialog::exists( u.name, extensions, existingNames, caseSensitivity ) )
{
QgsNewNameDialog dialog( u.name, u.name, extensions, existingNames, QRegExp(), caseSensitivity );
QgsNewNameDialog dialog( u.name, u.name, extensions, existingNames, regExp, caseSensitivity );
if ( dialog.exec() != QDialog::Accepted )
{
delete provider;
Expand Down Expand Up @@ -374,10 +375,9 @@ bool QgsGrassMapsetItem::handleDrop( const QMimeData * data, Qt::DropAction )

if ( !errors.isEmpty() )
{
QgsMessageOutput *output = QgsMessageOutput::createMessageOutput();
output->setTitle( tr( "Import to GRASS mapset" ) );
output->setMessage( tr( "Failed to import some layers!\n\n" ) + errors.join( "\n" ), QgsMessageOutput::MessageText );
output->showMessage();
QgsMessageOutput::showMessage( tr( "Import to GRASS mapset" ),
tr( "Failed to import some layers!\n\n" ) + errors.join( "\n" ),
QgsMessageOutput::MessageText );
}

return true;
Expand Down Expand Up @@ -407,6 +407,54 @@ QgsGrassObjectItemBase::QgsGrassObjectItemBase( QgsGrassObject grassObject ) :
{
}

void QgsGrassObjectItemBase::renameGrassObject( QgsDataItem* parent )
{
QgsDebugMsg( "Entered" );

QStringList existingNames = QgsGrass::grassObjects( mGrassObject.mapsetPath(), mGrassObject.type() );
// remove current name to avoid warning that exists
existingNames.removeOne( mGrassObject.name() );
QgsDebugMsg( "existingNames = " + existingNames.join( "," ) );
QRegExp regExp = QgsGrassObject::newNameRegExp( mGrassObject.type() );
Qt::CaseSensitivity caseSensitivity = QgsGrass::caseSensitivity();
QgsNewNameDialog dialog( mGrassObject.name(), mGrassObject.name(), QStringList(), existingNames, regExp, caseSensitivity );

if ( dialog.exec() != QDialog::Accepted || dialog.name() == mGrassObject.name() )
{
return;
}

QgsDebugMsg( "rename " + mGrassObject.name() + " -> " + dialog.name() );

QgsGrassObject obj( mGrassObject );
obj.setName( dialog.name() );
QString errorTitle = QObject::tr( "Rename GRASS %1" ).arg( mGrassObject.elementName() );
if ( QgsGrass::objectExists( obj ) )
{
QgsDebugMsg( obj.name() + " exists -> delete" );
if ( !QgsGrass::deleteObject( obj ) )
{
QgsMessageOutput::showMessage( errorTitle, QObject::tr( "Cannot delete %1" ).arg( obj.name() ), QgsMessageOutput::MessageText );
return;
}
}

try
{
QgsGrass::renameObject( mGrassObject, obj.name() );
if ( parent )
{
parent->refresh();
}
}
catch ( QgsGrass::Exception &e )
{
QgsMessageOutput::showMessage( errorTitle,
QObject::tr( "Cannot rename %1 to %2" ).arg( mGrassObject.name() ).arg( obj.name() ) + "\n" + e.what(),
QgsMessageOutput::MessageText );
}
}

void QgsGrassObjectItemBase::deleteGrassObject( QgsDataItem* parent )
{
QgsDebugMsg( "Entered" );
Expand All @@ -426,10 +474,10 @@ void QgsGrassObjectItemBase::deleteGrassObject( QgsDataItem* parent )
QgsGrassObjectItem::QgsGrassObjectItem( QgsDataItem* parent, QgsGrassObject grassObject,
QString name, QString path, QString uri,
LayerType layerType, QString providerKey,
bool deleteAction )
bool showObjectActions )
: QgsLayerItem( parent, name, path, uri, layerType, providerKey )
, QgsGrassObjectItemBase( grassObject )
, mDeleteAction( deleteAction )
, mShowObjectActions( showObjectActions )
{
setState( Populated ); // no children, to show non expandable in browser
}
Expand All @@ -438,8 +486,12 @@ QList<QAction*> QgsGrassObjectItem::actions()
{
QList<QAction*> lst;

if ( mDeleteAction )
if ( mShowObjectActions )
{
QAction* actionRename = new QAction( tr( "Rename" ), this );
connect( actionRename, SIGNAL( triggered() ), this, SLOT( renameGrassObject() ) );
lst.append( actionRename );

QAction* actionDelete = new QAction( tr( "Delete" ), this );
connect( actionDelete, SIGNAL( triggered() ), this, SLOT( deleteGrassObject() ) );
lst.append( actionDelete );
Expand All @@ -448,6 +500,11 @@ QList<QAction*> QgsGrassObjectItem::actions()
return lst;
}

void QgsGrassObjectItem::renameGrassObject()
{
QgsGrassObjectItemBase::renameGrassObject( parent() );
}

void QgsGrassObjectItem::deleteGrassObject()
{
QgsGrassObjectItemBase::deleteGrassObject( parent() );
Expand All @@ -467,13 +524,22 @@ QList<QAction*> QgsGrassVectorItem::actions()
{
QList<QAction*> lst;

QAction* actionRename = new QAction( tr( "Rename" ), this );
connect( actionRename, SIGNAL( triggered() ), this, SLOT( renameGrassObject() ) );
lst.append( actionRename );

QAction* actionDelete = new QAction( tr( "Delete" ), this );
connect( actionDelete, SIGNAL( triggered() ), this, SLOT( deleteGrassObject() ) );
lst.append( actionDelete );

return lst;
}

void QgsGrassVectorItem::renameGrassObject()
{
QgsGrassObjectItemBase::renameGrassObject( parent() );
}

void QgsGrassVectorItem::deleteGrassObject()
{
QgsGrassObjectItemBase::deleteGrassObject( parent() );
Expand All @@ -484,7 +550,7 @@ void QgsGrassVectorItem::deleteGrassObject()
QgsGrassVectorLayerItem::QgsGrassVectorLayerItem( QgsDataItem* parent, QgsGrassObject grassObject, QString layerName,
QString path, QString uri,
LayerType layerType, bool singleLayer )
: QgsGrassObjectItem( parent, grassObject, layerName, path, uri, layerType, "grass" )
: QgsGrassObjectItem( parent, grassObject, layerName, path, uri, layerType, "grass", mSingleLayer )
, mSingleLayer( singleLayer )
{
}
Expand Down

0 comments on commit eaeea21

Please sign in to comment.