mirror of
https://github.com/qgis/QGIS.git
synced 2025-03-01 00:46:20 -05:00
[GRASS] browser import cancel action
This commit is contained in:
parent
263d89c334
commit
a6f1ece73b
@ -58,6 +58,7 @@ extern "C"
|
||||
#define G_set_raster_value_d Rast_set_d_value
|
||||
#define G_put_raster_row Rast_put_row
|
||||
#define G_raster_size Rast_cell_size
|
||||
#define G_unopen_cell Rast_unopen
|
||||
#endif
|
||||
|
||||
int main( int argc, char **argv )
|
||||
@ -127,9 +128,15 @@ int main( int argc, char **argv )
|
||||
void *buf = G_allocate_raster_buf( grass_type );
|
||||
|
||||
int expectedSize = cols * QgsRasterBlock::typeSize( qgis_type );
|
||||
bool isCanceled;
|
||||
QByteArray byteArray;
|
||||
for ( int row = 0; row < rows; row++ )
|
||||
{
|
||||
stdinStream >> isCanceled;
|
||||
if ( isCanceled )
|
||||
{
|
||||
break;
|
||||
}
|
||||
stdinStream >> byteArray;
|
||||
if ( byteArray.size() != expectedSize )
|
||||
{
|
||||
@ -162,11 +169,18 @@ int main( int argc, char **argv )
|
||||
G_put_raster_row( cf, buf, grass_type );
|
||||
}
|
||||
|
||||
G_close_cell( cf );
|
||||
struct History history;
|
||||
G_short_history( name, "raster", &history );
|
||||
G_command_history( &history );
|
||||
G_write_history( name, &history );
|
||||
if ( isCanceled )
|
||||
{
|
||||
G_unopen_cell( cf );
|
||||
}
|
||||
else
|
||||
{
|
||||
G_close_cell( cf );
|
||||
struct History history;
|
||||
G_short_history( name, "raster", &history );
|
||||
G_command_history( &history );
|
||||
G_write_history( name, &history );
|
||||
}
|
||||
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
@ -66,6 +66,33 @@ void writePolyline( struct Map_info* map, int type, QgsPolyline polyline, struct
|
||||
Vect_write_line( map, type, line, cats );
|
||||
}
|
||||
|
||||
void exitIfCanceled( QDataStream& stdinStream, bool isPolygon,
|
||||
const QString & tmpName, struct Map_info * tmpMap,
|
||||
const QString & finalName, struct Map_info * finalMap )
|
||||
{
|
||||
bool isCanceled;
|
||||
stdinStream >> isCanceled;
|
||||
if ( !isCanceled )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( isPolygon )
|
||||
{
|
||||
Vect_close( tmpMap );
|
||||
Vect_delete( tmpName.toUtf8().data() );
|
||||
}
|
||||
Vect_close( finalMap );
|
||||
Vect_delete( finalName.toUtf8().data() );
|
||||
G_warning( "import canceled -> maps deleted" );
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
||||
// G_set_percent_routine only works in GRASS >= 7
|
||||
//int percent_routine (int)
|
||||
//{
|
||||
// TODO: use it to interrupt cleaning functions
|
||||
//}
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
struct Option *mapOption;
|
||||
@ -91,6 +118,7 @@ int main( int argc, char **argv )
|
||||
QGis::WkbType wkbFlatType = QGis::flatType( wkbType );
|
||||
bool isPolygon = QGis::singleType( wkbFlatType ) == QGis::WKBPolygon;
|
||||
|
||||
QString finalName = QString( mapOption->answer );
|
||||
struct Map_info finalMap, tmpMap;
|
||||
Vect_open_new( &finalMap, mapOption->answer, 0 );
|
||||
struct Map_info * map = &finalMap;
|
||||
@ -148,6 +176,7 @@ int main( int argc, char **argv )
|
||||
qint32 featureCount = 0;
|
||||
while ( true )
|
||||
{
|
||||
exitIfCanceled( stdinStream, isPolygon, tmpName, &tmpMap, finalName, &finalMap );
|
||||
stdinStream >> feature;
|
||||
if ( !feature.isValid() )
|
||||
{
|
||||
@ -279,6 +308,7 @@ int main( int argc, char **argv )
|
||||
// read once more to assign centroids to polygons
|
||||
while ( true )
|
||||
{
|
||||
exitIfCanceled( stdinStream, isPolygon, tmpName, &tmpMap, finalName, &finalMap );
|
||||
stdinStream >> feature;
|
||||
if ( !feature.isValid() )
|
||||
{
|
||||
|
@ -1007,10 +1007,13 @@ QStringList GRASS_LIB_EXPORT QgsGrass::vectorLayers( const QString& gisdbase, co
|
||||
return list;
|
||||
}
|
||||
|
||||
// TODO: Handle errors as exceptions. Do not open QMessageBox here! This method is also used in browser
|
||||
// items which are populated in threads and creating dialog QPixmap is causing crash or even X server freeze.
|
||||
if ( level == 1 )
|
||||
{
|
||||
QgsDebugMsg( "Cannot open vector on level 2" );
|
||||
QMessageBox::warning( 0, QObject::tr( "Warning" ), QObject::tr( "Cannot open vector %1 in mapset %2 on level 2 (topology not available, try to rebuild topology using v.build module)." ).arg( mapName ).arg( mapset ) );
|
||||
// Do not open QMessageBox here!
|
||||
//QMessageBox::warning( 0, QObject::tr( "Warning" ), QObject::tr( "Cannot open vector %1 in mapset %2 on level 2 (topology not available, try to rebuild topology using v.build module)." ).arg( mapName ).arg( mapset ) );
|
||||
// Vect_close here is correct, it should work, but it seems to cause
|
||||
// crash on win http://trac.osgeo.org/qgis/ticket/2003
|
||||
// disabled on win test it
|
||||
@ -1023,7 +1026,8 @@ QStringList GRASS_LIB_EXPORT QgsGrass::vectorLayers( const QString& gisdbase, co
|
||||
else if ( level < 1 )
|
||||
{
|
||||
QgsDebugMsg( "Cannot open vector" );
|
||||
QMessageBox::warning( 0, QObject::tr( "Warning" ), QObject::tr( "Cannot open vector %1 in mapset %2" ).arg( mapName ).arg( mapset ) );
|
||||
// Do not open QMessageBox here!
|
||||
//QMessageBox::warning( 0, QObject::tr( "Warning" ), QObject::tr( "Cannot open vector %1 in mapset %2" ).arg( mapName ).arg( mapset ) );
|
||||
GRASS_UNLOCK
|
||||
return list;
|
||||
}
|
||||
|
@ -13,6 +13,8 @@
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#include <unistd.h>
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QtConcurrentRun>
|
||||
|
||||
@ -37,6 +39,7 @@ extern "C"
|
||||
QgsGrassImport::QgsGrassImport( QgsGrassObject grassObject )
|
||||
: QObject()
|
||||
, mGrassObject( grassObject )
|
||||
, mCanceled( false )
|
||||
, mFutureWatcher( 0 )
|
||||
{
|
||||
}
|
||||
@ -220,15 +223,27 @@ bool QgsGrassRasterImport::import()
|
||||
char * data = block->bits( row, 0 );
|
||||
int size = iterCols * block->dataTypeSize();
|
||||
QByteArray byteArray = QByteArray::fromRawData( data, size ); // does not copy data and does not take ownership
|
||||
if ( isCanceled() )
|
||||
{
|
||||
outStream << true; // cancel module
|
||||
break;
|
||||
}
|
||||
outStream << false; // not canceled
|
||||
outStream << byteArray;
|
||||
}
|
||||
delete block;
|
||||
if ( isCanceled() )
|
||||
{
|
||||
outStream << true; // cancel module
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: send something back from module and read it here to close map correctly in module
|
||||
|
||||
process->closeWriteChannel();
|
||||
process->waitForFinished( 5000 );
|
||||
// TODO: best timeout?
|
||||
process->waitForFinished( 30000 );
|
||||
|
||||
QString stdoutString = process->readAllStandardOutput().data();
|
||||
QString stderrString = process->readAllStandardError().data();
|
||||
@ -387,9 +402,16 @@ bool QgsGrassVectorImport::import()
|
||||
{
|
||||
feature.geometry()->transform( coordinateTransform );
|
||||
}
|
||||
if ( isCanceled() )
|
||||
{
|
||||
outStream << true; // cancel module
|
||||
break;
|
||||
}
|
||||
outStream << false; // not canceled
|
||||
outStream << feature;
|
||||
}
|
||||
feature = QgsFeature(); // indicate end by invalid feature
|
||||
outStream << false; // not canceled
|
||||
outStream << feature;
|
||||
QgsDebugMsg( "features sent" );
|
||||
}
|
||||
|
@ -39,9 +39,15 @@ class GRASS_LIB_EXPORT QgsGrassImport : public QObject
|
||||
// get error if import failed
|
||||
QString error();
|
||||
virtual QStringList names() const;
|
||||
|
||||
bool isCanceled() const { return mCanceled; }
|
||||
public slots:
|
||||
void onFinished();
|
||||
// TODO: this is not completely kosher, because QgsGrassImport exist on the main thread
|
||||
// but import is running in another thread, to do it right, we should have an import object
|
||||
// created on another thread, send cancel signal to that object which regularly processes events
|
||||
// and thus recieves the signal.
|
||||
// Most probably however, it will work correctly, even if read/write the bool wasn't atomic
|
||||
void cancel() { mCanceled = true; }
|
||||
|
||||
signals:
|
||||
// sent when process finished
|
||||
@ -52,6 +58,7 @@ class GRASS_LIB_EXPORT QgsGrassImport : public QObject
|
||||
void setError( QString error );
|
||||
QgsGrassObject mGrassObject;
|
||||
QString mError;
|
||||
bool mCanceled;
|
||||
QFutureWatcher<bool>* mFutureWatcher;
|
||||
};
|
||||
|
||||
|
@ -99,7 +99,15 @@ QVector<QgsDataItem*> QgsGrassMapsetItem::createChildren()
|
||||
|
||||
QgsGrassObject vectorObject( mGisdbase, mLocation, mName, name, QgsGrassObject::Vector );
|
||||
QgsGrassVectorItem *map = 0;
|
||||
if ( layerNames.size() > 1 )
|
||||
if ( layerNames.size() == 0 )
|
||||
{
|
||||
// TODO: differentiate if it is layer with no layers or without topo (throw exception from QgsGrass::vectorLayers)
|
||||
// TODO: refresh (remove) error if topo was build
|
||||
QgsErrorItem * errorItem = new QgsErrorItem( this, name, mapPath );
|
||||
items.append( errorItem );
|
||||
continue;
|
||||
}
|
||||
else if ( layerNames.size() > 1 )
|
||||
{
|
||||
//map = new QgsDataCollectionItem( this, name, mapPath );
|
||||
//map->setCapabilities( QgsDataItem::NoCapabilities ); // disable fertility
|
||||
@ -612,11 +620,33 @@ QgsGrassRasterItem::QgsGrassRasterItem( QgsDataItem* parent, QgsGrassObject gras
|
||||
QgsGrassImportItem::QgsGrassImportItem( QgsDataItem* parent, const QString& name, const QString& path, QgsGrassImport* import )
|
||||
: QgsDataItem( QgsDataItem::Layer, parent, name, path )
|
||||
, QgsGrassObjectItemBase( import->grassObject() )
|
||||
, mImport( import )
|
||||
{
|
||||
setCapabilities( QgsDataItem::NoCapabilities ); // disable fertility
|
||||
setState( Populating );
|
||||
}
|
||||
|
||||
QList<QAction*> QgsGrassImportItem::actions()
|
||||
{
|
||||
QList<QAction*> lst;
|
||||
|
||||
QAction* actionRename = new QAction( tr( "Cancel" ), this );
|
||||
connect( actionRename, SIGNAL( triggered() ), this, SLOT( cancel() ) );
|
||||
lst.append( actionRename );
|
||||
|
||||
return lst;
|
||||
}
|
||||
|
||||
void QgsGrassImportItem::cancel()
|
||||
{
|
||||
QgsDebugMsg( "Entered" );
|
||||
if ( !mImport ) // should not happen
|
||||
{
|
||||
return;
|
||||
}
|
||||
mImport->cancel();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
QGISEXTERN int dataCapabilities()
|
||||
|
@ -148,16 +148,17 @@ class QgsGrassImportItem : public QgsDataItem, public QgsGrassObjectItemBase
|
||||
//virtual void setState( State state ) override {
|
||||
// QgsDataItem::setState(state);
|
||||
//} // do nothing to keep Populating
|
||||
//virtual QList<QAction*> actions() override;
|
||||
virtual QList<QAction*> actions() override;
|
||||
|
||||
public slots:
|
||||
virtual void refresh() override {}
|
||||
//void deleteGrassObject();
|
||||
void cancel();
|
||||
|
||||
protected:
|
||||
// override refresh to keep Populating state
|
||||
virtual void refresh( QVector<QgsDataItem*> children ) override { Q_UNUSED( children )};
|
||||
//bool mDeleteAction;
|
||||
QgsGrassImport* mImport;
|
||||
};
|
||||
|
||||
#endif // QGSGRASSPROVIDERMODULE_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user