22#include "moc_qgsrunprocess.cpp" 
   32#include <QApplication> 
   35QgsRunProcess::QgsRunProcess( 
const QString &action, 
bool capture )
 
   44  QStringList arguments = QProcess::splitCommand( action );
 
   45  const QString command = arguments.value( 0 );
 
   46  if ( !arguments.isEmpty() )
 
   47    arguments.removeFirst();
 
   49  mProcess = std::make_unique<QProcess>();
 
   53    connect( mProcess.get(), &QProcess::errorOccurred, 
this, &QgsRunProcess::processError );
 
   54    connect( mProcess.get(), &QProcess::readyReadStandardOutput, 
this, &QgsRunProcess::stdoutAvailable );
 
   55    connect( mProcess.get(), &QProcess::readyReadStandardError, 
this, &QgsRunProcess::stderrAvailable );
 
   59    connect( mProcess.get(), 
static_cast < void ( QProcess::* )( 
int,  QProcess::ExitStatus ) 
>( &QProcess::finished ), 
this, &QgsRunProcess::processExit );
 
   64    mOutput->setTitle( action );
 
   66    mOutput->showMessage( 
false ); 
 
   69    QObject *mOutputObj = 
dynamic_cast<QObject *
>( mOutput );
 
   72      connect( mOutputObj, &QObject::destroyed, 
this, &QgsRunProcess::dialogGone );
 
   76    mProcess->start( command, arguments );
 
   80    if ( ! QProcess::startDetached( command, arguments ) ) 
 
   82      QMessageBox::critical( 
nullptr, tr( 
"Action" ),
 
   83                             tr( 
"Unable to run command\n%1" ).arg( action ),
 
   84                             QMessageBox::Ok, Qt::NoButton );
 
   92QgsRunProcess::~QgsRunProcess()
 
   97void QgsRunProcess::die()
 
  103void QgsRunProcess::stdoutAvailable()
 
  105  const QByteArray bytes( mProcess->readAllStandardOutput() );
 
  106  QTextCodec *codec = QTextCodec::codecForLocale();
 
  107  const QString line( codec->toUnicode( bytes ) );
 
  110  mOutput->appendMessage( line );
 
  113void QgsRunProcess::stderrAvailable()
 
  115  const QByteArray bytes( mProcess->readAllStandardOutput() );
 
  116  QTextCodec *codec = QTextCodec::codecForLocale();
 
  117  const QString line( codec->toUnicode( bytes ) );
 
  120  mOutput->appendMessage( 
"<font color=red>" + line + 
"</font>" );
 
  123void QgsRunProcess::processExit( 
int, QProcess::ExitStatus )
 
  134    mOutput->appendMessage( 
"<b>" + tr( 
"Done" ) + 
"</b>" );
 
  143void QgsRunProcess::dialogGone()
 
  154  disconnect( mProcess.get(), &QProcess::errorOccurred, 
this, &QgsRunProcess::processError );
 
  155  disconnect( mProcess.get(), &QProcess::readyReadStandardOutput, 
this, &QgsRunProcess::stdoutAvailable );
 
  156  disconnect( mProcess.get(), &QProcess::readyReadStandardError, 
this, &QgsRunProcess::stderrAvailable );
 
  157  disconnect( mProcess.get(), 
static_cast < void ( QProcess::* )( 
int, QProcess::ExitStatus ) 
>( &QProcess::finished ), 
this, &QgsRunProcess::processExit );
 
  162void QgsRunProcess::processError( QProcess::ProcessError err )
 
  164  if ( err == QProcess::FailedToStart )
 
  179  return QProcess::splitCommand( command );
 
  182QgsRunProcess::QgsRunProcess( 
const QString &action, 
bool )
 
  188QgsRunProcess::~QgsRunProcess()
 
  194  return QStringList();
 
 
  203#if QT_CONFIG(process) 
  204QgsBlockingProcess::QgsBlockingProcess( 
const QString &process, 
const QStringList &arguments )
 
  206  , mProcess( process )
 
  207  , mArguments( arguments )
 
  212int QgsBlockingProcess::run( 
QgsFeedback *feedback )
 
  214  const bool requestMadeFromMainThread = QThread::currentThread() == QCoreApplication::instance()->thread();
 
  217  QProcess::ExitStatus exitStatus = QProcess::NormalExit;
 
  218  QProcess::ProcessError error = QProcess::UnknownError;
 
  220  const std::function<void()> runFunction = [ 
this, &result, &exitStatus, &error, feedback]()
 
  227    const QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
 
  228    p.setProcessEnvironment( env );
 
  234    connect( qApp, &QCoreApplication::aboutToQuit, &loop, &QEventLoop::quit, Qt::DirectConnection );
 
  248    connect( &p, qOverload< int, QProcess::ExitStatus >( &QProcess::finished ), 
this, [&loop, &result, &exitStatus]( 
int res, QProcess::ExitStatus st )
 
  253    }, Qt::DirectConnection );
 
  255    connect( &p, &QProcess::readyReadStandardOutput, &p, [&p, 
this]
 
  257      const QByteArray ba = p.readAllStandardOutput();
 
  258      mStdoutHandler( ba );
 
  260    connect( &p, &QProcess::readyReadStandardError, &p, [&p, 
this]
 
  262      const QByteArray ba = p.readAllStandardError();
 
  263      mStderrHandler( ba );
 
  265    p.start( mProcess, mArguments, QProcess::Unbuffered | QProcess::ReadWrite );
 
  266    if ( !p.waitForStarted() )
 
  269      exitStatus = QProcess::NormalExit;
 
  277    mStdoutHandler( p.readAllStandardOutput() );
 
  278    mStderrHandler( p.readAllStandardError() );
 
  281  if ( requestMadeFromMainThread )
 
  283    auto processThread = std::make_unique<ProcessThread>( runFunction );
 
  284    processThread->start();
 
  286    processThread->wait();
 
  293  mExitStatus = exitStatus;
 
  294  mProcessError = error;
 
  298QProcess::ExitStatus QgsBlockingProcess::exitStatus()
 const 
  303QProcess::ProcessError QgsBlockingProcess::processError()
 const 
  305  return mProcessError;
 
static QgsApplication * instance()
Returns the singleton instance of the QgsApplication.
 
Base class for feedback objects to be used for cancellation of something running in a worker thread.
 
void canceled()
Internal routines can connect to this signal if they use event loop.
 
Interface for showing messages from QGIS in GUI independent way.
 
static QgsMessageOutput * createMessageOutput()
function that returns new class derived from QgsMessageOutput (don't forget to delete it then if show...
 
virtual void setMessage(const QString &message, MessageType msgType)=0
Sets message, it won't be displayed until.
 
static QStringList splitCommand(const QString &command)
Splits the string command into a list of tokens, and returns the list.
 
#define QgsDebugMsgLevel(str, level)
 
#define QgsDebugError(str)