6969#include < QPushButton>
7070#include < QGroupBox>
7171#include < QFileDialog>
72+ #include < QProcess>
7273
7374#include " qgis.h"
7475#include " qgsapplication.h"
@@ -233,10 +234,9 @@ QgsGrassModule::QgsGrassModule ( QgsGrassTools *tools, QgisApp *qgisApp, QgisIfa
233234 mManualTextBrowser ->setSource ( manPath );
234235 }
235236
236- connect ( &mProcess , SIGNAL (readyReadStdout ()), this , SLOT (readStdout ()));
237- connect ( &mProcess , SIGNAL (readyReadStderr ()), this , SLOT (readStderr ()));
238- connect ( &mProcess , SIGNAL (launchFinished ()), this , SLOT (finished ()));
239- connect ( &mProcess , SIGNAL (processExited ()), this , SLOT (finished ()));
237+ connect ( &mProcess , SIGNAL (readyReadStandardOutput ()), this , SLOT (readStdout ()));
238+ connect ( &mProcess , SIGNAL (readyReadStandardError ()), this , SLOT (readStderr ()));
239+ connect ( &mProcess , SIGNAL (finished (int ,QProcess::ExitStatus)), this , SLOT (finished (int ,QProcess::ExitStatus)));
240240
241241 char *env = " GRASS_MESSAGE_FORMAT=gui" ;
242242 char *envstr = new char [strlen (env)+1 ];
@@ -543,6 +543,172 @@ QStringList QgsGrassModuleStandardOptions::ready()
543543 return list;
544544}
545545
546+ QStringList QgsGrassModuleStandardOptions::checkRegion ()
547+ {
548+ #ifdef QGISDEBUG
549+ std::cerr << " QgsGrassModuleStandardOptions::checkRegion()" << std::endl;
550+ #endif
551+ QStringList list;
552+
553+ struct Cell_head currentWindow;
554+ if ( !QgsGrass::region ( QgsGrass::getDefaultGisdbase (),
555+ QgsGrass::getDefaultLocation (),
556+ QgsGrass::getDefaultMapset (), ¤tWindow ) )
557+ {
558+ QMessageBox::warning ( 0 , " Warning" , " Cannot get current region" );
559+ return list;
560+ }
561+
562+ for ( int i = 0 ; i < mItems .size (); i++ )
563+ {
564+ if ( typeid (*(mItems [i])) != typeid (QgsGrassModuleInput) ) {
565+ continue ;
566+ }
567+
568+ struct Cell_head window;
569+
570+ QgsGrassModuleInput *item = dynamic_cast <QgsGrassModuleInput *>
571+ (mItems [i]);
572+
573+ int mapType;
574+ switch ( item->type () ) {
575+ case QgsGrassModuleInput::Raster :
576+ mapType = QgsGrass::Raster;
577+ break ;
578+ case QgsGrassModuleInput::Vector :
579+ mapType = QgsGrass::Vector;
580+ break ;
581+ }
582+
583+ if ( !QgsGrass::mapRegion ( mapType,
584+ QgsGrass::getDefaultGisdbase (),
585+ QgsGrass::getDefaultLocation (), " " , item->currentMap (),
586+ &window ) )
587+ {
588+ QMessageBox::warning ( 0 , " Warning" , " Cannot check region "
589+ " of map " + item->currentMap () );
590+ continue ;
591+ }
592+
593+ if ( G_window_overlap ( ¤tWindow ,
594+ window.north , window.south , window.east , window.west ) == 0 )
595+ {
596+ list.append ( item->currentMap () );
597+ }
598+ }
599+
600+ return list;
601+ }
602+
603+ bool QgsGrassModuleStandardOptions::inputRegion ( struct Cell_head *window, bool all )
604+ {
605+ #ifdef QGISDEBUG
606+ std::cerr << " QgsGrassModuleStandardOptions::inputRegion()" << std::endl;
607+ #endif
608+
609+ // Get current resolution
610+ if ( !QgsGrass::region ( QgsGrass::getDefaultGisdbase (),
611+ QgsGrass::getDefaultLocation (),
612+ QgsGrass::getDefaultMapset (), window ) )
613+ {
614+ QMessageBox::warning ( 0 , " Warning" , " Cannot get current region" );
615+ return false ;
616+ }
617+
618+ int rasterCount = 0 ;
619+ int vectorCount = 0 ;
620+ for ( int i = 0 ; i < mItems .size (); i++ )
621+ {
622+ if ( typeid (*(mItems [i])) != typeid (QgsGrassModuleInput) ) {
623+ continue ;
624+ }
625+
626+ // TODO all flag
627+
628+ struct Cell_head mapWindow;
629+
630+ QgsGrassModuleInput *item = dynamic_cast <QgsGrassModuleInput *>
631+ (mItems [i]);
632+
633+ int mapType;
634+ switch ( item->type () ) {
635+ case QgsGrassModuleInput::Raster :
636+ mapType = QgsGrass::Raster;
637+ break ;
638+ case QgsGrassModuleInput::Vector :
639+ mapType = QgsGrass::Vector;
640+ break ;
641+ }
642+
643+ if ( !QgsGrass::mapRegion ( mapType,
644+ QgsGrass::getDefaultGisdbase (),
645+ QgsGrass::getDefaultLocation (), " " , item->currentMap (),
646+ &mapWindow ) )
647+ {
648+ QMessageBox::warning ( 0 , " Warning" , " Cannot set region "
649+ " of map " + item->currentMap () );
650+ return false ;
651+ }
652+
653+ // TODO: best way to set resolution ?
654+ if ( item->type () == QgsGrassModuleInput::Raster
655+ && rasterCount == 0 )
656+ {
657+ QgsGrass::copyRegionResolution ( &mapWindow, window );
658+ }
659+ if ( rasterCount + vectorCount == 0 )
660+ {
661+ QgsGrass::copyRegionExtent ( &mapWindow, window );
662+ }
663+ else
664+ {
665+ QgsGrass::extendRegion ( &mapWindow, window );
666+ }
667+
668+ if ( item->type () == QgsGrassModuleInput::Raster )
669+ rasterCount++;
670+ else if ( item->type () == QgsGrassModuleInput::Vector )
671+ vectorCount++;
672+ }
673+
674+ G_adjust_Cell_head3 ( window, 0 , 0 , 0 );
675+
676+ return true ;
677+ }
678+
679+ bool QgsGrassModuleStandardOptions::usesRegion ()
680+ {
681+ #ifdef QGISDEBUG
682+ std::cerr << " QgsGrassModuleStandardOptions::usesRegion()" << std::endl;
683+ #endif
684+
685+ for ( int i = 0 ; i < mItems .size (); i++ )
686+ {
687+ if ( typeid (*(mItems [i])) == typeid (QgsGrassModuleInput) )
688+ {
689+ QgsGrassModuleInput *item =
690+ dynamic_cast <QgsGrassModuleInput *>(mItems [i]);
691+
692+ if ( item->type () == QgsGrassModuleInput::Raster )
693+ return true ;
694+ }
695+
696+ if ( typeid (*(mItems [i])) == typeid (QgsGrassModuleOption) )
697+ {
698+ QgsGrassModuleOption *item =
699+ dynamic_cast <QgsGrassModuleOption *> ( mItems [i] );
700+
701+ if ( item->isOutput ()
702+ && item->outputType () == QgsGrassModuleOption::Raster )
703+ {
704+ return true ;
705+ }
706+ }
707+ }
708+
709+ return false ;
710+ }
711+
546712QgsGrassModuleStandardOptions::~QgsGrassModuleStandardOptions ()
547713{
548714}
@@ -703,18 +869,16 @@ void QgsGrassModule::run()
703869 std::cerr << " QgsGrassModule::run()" << std::endl;
704870 #endif
705871
706- if ( mProcess .isRunning () ) {
872+ if ( mProcess .state () == QProcess::Running ) {
707873 mProcess .kill ();
708874 mRunButton ->setText ( tr (" Run" ) );
709875 } else {
710- QString command;
876+ // QString command;
877+ QStringList arguments;
711878
712- if ( mProcess .isRunning () ) {
713- }
714-
715- mProcess .clearArguments ();
716- mProcess .addArgument ( mXName );
717- command = mXName ;
879+ // mProcess.clearArguments();
880+ // mProcess.addArgument( mXName );
881+ // command = mXName;
718882
719883 // Check if options are ready
720884 QStringList readyErrors = mOptions ->ready ();
@@ -729,6 +893,55 @@ void QgsGrassModule::run()
729893 return ;
730894 }
731895
896+ // Check/set region
897+ struct Cell_head tempWindow;
898+ bool resetRegion = false ;
899+ if ( mOptions ->requestsRegion () )
900+ {
901+ if ( !mOptions ->inputRegion ( &tempWindow, false ) )
902+ {
903+ QMessageBox::warning ( 0 , " Warning" , " Cannot get input region" );
904+ return ;
905+ }
906+ resetRegion = true ;
907+ }
908+ else if ( mOptions ->usesRegion () )
909+ {
910+ QStringList outsideRegion = mOptions ->checkRegion ();
911+ if ( outsideRegion.size () > 0 )
912+ {
913+ if ( QgsGrass::versionMajor () >= 6 && QgsGrass::versionMinor () >= 1 )
914+ {
915+ int ret = QMessageBox::question ( 0 , " Warning" ,
916+ " Input " + outsideRegion.join (" ," )
917+ + " outside current region!" ,
918+ " Use input region" , " Continue" , " Cancel" );
919+
920+ if ( ret == 2 ) return ;
921+ if ( ret == 0 ) resetRegion = true ;
922+ }
923+ else
924+ {
925+ int ret = QMessageBox::question ( 0 , " Warning" ,
926+ " Input " + outsideRegion.join (" ," )
927+ + " outside current region!" ,
928+ " Continue" , " Cancel" );
929+
930+ if ( ret == 1 ) return ;
931+ }
932+
933+ if ( resetRegion )
934+ {
935+ if ( !mOptions ->inputRegion ( &tempWindow, true ) )
936+ {
937+ QMessageBox::warning ( 0 , " Warning" ,
938+ " Cannot get input region" );
939+ return ;
940+ }
941+ }
942+ }
943+ }
944+
732945 // Check if output exists
733946 QStringList outputExists = mOptions ->checkOutput ();
734947 if ( outputExists.size () > 0 )
@@ -743,8 +956,9 @@ void QgsGrassModule::run()
743956 // r.mapcalc does not use standard parser
744957 if ( typeid (*mOptions ) != typeid (QgsGrassMapcalc) )
745958 {
746- mProcess .addArgument ( " --o" );
747- command.append ( " --o" );
959+ arguments.append ( " --o" );
960+ // mProcess.addArgument( "--o" );
961+ // command.append ( " --o" );
748962 }
749963 }
750964
@@ -760,8 +974,9 @@ void QgsGrassModule::run()
760974
761975 for ( QStringList::Iterator it = list.begin (); it != list.end (); ++it ) {
762976 std::cerr << " option: " << (*it).toLocal8Bit ().data () << std::endl;
763- command.append ( " " + *it );
764- mProcess .addArgument ( *it );
977+ // command.append ( " " + *it );
978+ arguments.append ( *it );
979+ // mProcess.addArgument( *it );
765980 }
766981
767982 /* WARNING - TODO: there was a bug in GRASS 6.0.0 / 6.1.CVS (< 2005-04-29):
@@ -773,28 +988,53 @@ void QgsGrassModule::run()
773988 */
774989 putenv ( " GISRC_MODE_MEMORY" ); // unset
775990
776- mProcess .start ( );
777-
778- std::cerr << " command" << command.toLocal8Bit ().data () << std::endl;
779991 mOutputTextBrowser ->clear ();
780992
781- command.replace ( " &" , " &" );
782- command.replace ( " <" , " <" );
783- command.replace ( " >" , " >" );
784- mOutputTextBrowser ->append ( " <B>" + command + " </B>" );
993+ QString commandHtml = mXName + " " + arguments.join (" " );
994+
995+ std::cerr << " command: " << commandHtml.toLocal8Bit ().data () << std::endl;
996+ commandHtml.replace ( " &" , " &" );
997+ commandHtml.replace ( " <" , " <" );
998+ commandHtml.replace ( " >" , " >" );
999+ mOutputTextBrowser ->append ( " <B>" + commandHtml + " </B>" );
1000+
1001+ // Warning: it is not useful to write requested region to WIND file and
1002+ // reset then to original beacuse it is reset before
1003+ // the region is read by a module even if waitForStarted() is used
1004+ // -> necessary to pass region as enviroment variable
1005+ // but the feature is available in GRASS 6.1 only since 23.3.2006
1006+
1007+ QStringList env;
1008+
1009+ if ( resetRegion )
1010+ {
1011+ env = QProcess::systemEnvironment ();
1012+ QString reg = QgsGrass::regionString ( &tempWindow );
1013+ std::cerr << " reg: " << reg.ascii () << std::endl;
1014+ env.append ( " GRASS_REGION=" + reg );
1015+ }
1016+ mProcess .setEnvironment ( env );
1017+
1018+ mProcess .start ( mXName , arguments );
1019+
1020+ if ( resetRegion )
1021+ {
1022+ }
1023+
7851024 mTabWidget ->setCurrentPage (1 );
7861025 mRunButton ->setText ( tr (" Stop" ) );
7871026 }
7881027}
7891028
790- void QgsGrassModule::finished ()
1029+ void QgsGrassModule::finished (int exitCode, QProcess::ExitStatus exitStatus )
7911030{
7921031 #ifdef QGISDEBUG
7931032 std::cerr << " QgsGrassModule::finished()" << std::endl;
7941033 #endif
7951034
796- if ( mProcess .normalExit () ) {
797- if ( mProcess .exitStatus () == 0 ) {
1035+ std::cerr << " exitCode = " << exitCode << std::endl;
1036+ if ( exitStatus == QProcess::NormalExit ) {
1037+ if ( exitCode == 0 ) {
7981038 mOutputTextBrowser ->append ( " <B>Successfully finished</B>" );
7991039 mProgressBar ->setProgress ( 100 , 100 );
8001040 mSuccess = true ;
@@ -815,8 +1055,11 @@ void QgsGrassModule::readStdout()
8151055 #endif
8161056
8171057 QString line;
818- while ( mProcess .canReadLineStdout () ) {
819- line = QString::fromLocal8Bit ( mProcess .readLineStdout ().ascii () );
1058+ mProcess .setReadChannel ( QProcess::StandardOutput );
1059+ while ( mProcess .canReadLine () ) {
1060+ // line = QString::fromLocal8Bit( mProcess.readLineStdout().ascii() );
1061+ QByteArray ba = mProcess .readLine ();
1062+ line = QString::fromLocal8Bit ( QString (ba).ascii () );
8201063 mOutputTextBrowser ->append ( line );
8211064 }
8221065}
@@ -827,6 +1070,8 @@ void QgsGrassModule::readStderr()
8271070 std::cerr << " QgsGrassModule::readStderr()" << std::endl;
8281071 #endif
8291072
1073+ mProcess .setReadChannel ( QProcess::StandardError );
1074+
8301075 QString line;
8311076 QRegExp rxpercent ( " GRASS_INFO_PERCENT: (\\ d+)" );
8321077 QRegExp rxmessage ( " GRASS_INFO_MESSAGE\\ (\\ d+,\\ d+\\ ): (.*)" );
@@ -835,8 +1080,10 @@ void QgsGrassModule::readStderr()
8351080 QRegExp rxend ( " GRASS_INFO_END\\ (\\ d+,\\ d+\\ )" );
8361081
8371082
838- while ( mProcess .canReadLineStderr () ) {
839- line = QString::fromLocal8Bit ( mProcess .readLineStderr ().ascii () );
1083+ while ( mProcess .canReadLine () ) {
1084+ // line = QString::fromLocal8Bit( mProcess.readLineStderr().ascii() );
1085+ QByteArray ba = mProcess .readLine ();
1086+ line = QString::fromLocal8Bit ( QString (ba).ascii () );
8401087 // std::cerr << "stderr: " << line << std::endl;
8411088
8421089 if ( rxpercent.search ( line ) != -1 ) {
0 commit comments