From 098ae3be7435aa54e096de7c591f10c61db96f37 Mon Sep 17 00:00:00 2001
From: f4exb <f4exb06@gmail.com>
Date: Thu, 4 Jan 2018 23:10:05 +0100
Subject: [PATCH] Commands: fixed error and exit signals handling

---
 sdrbase/commands/command.cpp       | 47 +++++++++++++-----------------
 sdrbase/commands/command.h         |  4 +--
 sdrgui/gui/commandoutputdialog.cpp | 45 ++++++++++++++++------------
 sdrgui/gui/commandoutputdialog.ui  |  6 ++++
 sdrgui/mainwindow.cpp              | 14 +++++----
 sdrgui/mainwindow.ui               |  4 +--
 6 files changed, 65 insertions(+), 55 deletions(-)

diff --git a/sdrbase/commands/command.cpp b/sdrbase/commands/command.cpp
index e5dde8b9b..b2acfc825 100644
--- a/sdrbase/commands/command.cpp
+++ b/sdrbase/commands/command.cpp
@@ -25,7 +25,7 @@ Command::Command() :
     m_currentProcessState(QProcess::NotRunning),
     m_isInError(false),
     m_currentProcessError(QProcess::UnknownError),
-    m_isFinished(true),
+    m_hasExited(false),
     m_currentProcessExitCode(0),
     m_currentProcessExitStatus(QProcess::NormalExit),
     m_currentProcessPid(0)
@@ -52,7 +52,7 @@ Command::Command(const Command& command) :
         m_currentProcessState(QProcess::NotRunning),
         m_isInError(false),
         m_currentProcessError(QProcess::UnknownError),
-        m_isFinished(true),
+        m_hasExited(false),
         m_currentProcessExitCode(0),
         m_currentProcessExitStatus(QProcess::NormalExit),
         m_currentProcessPid(0)
@@ -179,7 +179,7 @@ void Command::run(const QString& apiAddress, int apiPort, int deviceSetIndex)
 
     m_currentProcess = new QProcess(this);
     m_isInError = false;
-    m_isFinished = false;
+    m_hasExited = false;
 
 #if QT_VERSION < 0x051000
     connect(m_currentProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));
@@ -200,17 +200,6 @@ void Command::kill()
     {
         qDebug("Command::kill: %lld", m_currentProcessPid);
         m_currentProcess->kill();
-
-#if QT_VERSION < 0x051000
-        disconnect(m_currentProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));
-#else
-        disconnect(m_currentProcess, SIGNAL(errorOccurred(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));
-#endif
-        disconnect(m_currentProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(processFinished(int, QProcess::ExitStatus)));
-        disconnect(m_currentProcess, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(processStateChanged(QProcess::ProcessState)));
-
-        delete m_currentProcess;
-        m_currentProcess = 0;
     }
 }
 
@@ -228,15 +217,15 @@ bool Command::getLastProcessError(QProcess::ProcessError& error) const
     return m_isInError;
 }
 
-bool Command::getLastProcessTermination(int& exitCode, QProcess::ExitStatus& exitStatus) const
+bool Command::getLastProcessExit(int& exitCode, QProcess::ExitStatus& exitStatus) const
 {
-    if (m_isFinished)
+    if (m_hasExited)
     {
         exitCode = m_currentProcessExitCode;
         exitStatus = m_currentProcessExitStatus;
     }
 
-    return m_isFinished;
+    return m_hasExited;
 }
 
 const QString& Command::getLastProcessLog() const
@@ -255,37 +244,41 @@ void Command::processStateChanged(QProcess::ProcessState newState)
 
 void Command::processError(QProcess::ProcessError error)
 {
+    //qDebug("Command::processError: %d state: %d", error, m_currentProcessState);
     gettimeofday(&m_currentProcessFinishTimeStamp, 0);
     m_currentProcessError = error;
     m_isInError = true;
-    m_isFinished = true;
-    m_log = m_currentProcess->readAllStandardOutput();
+
+    if (m_currentProcessState == QProcess::NotRunning)
+    {
+        m_log = m_currentProcess->readAllStandardOutput();
 
 #if QT_VERSION < 0x051000
         disconnect(m_currentProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));
 #else
         disconnect(m_currentProcess, SIGNAL(errorOccurred(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));
 #endif
-    disconnect(m_currentProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(processFinished(int, QProcess::ExitStatus)));
-    disconnect(m_currentProcess, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(processStateChanged(QProcess::ProcessState)));
+        disconnect(m_currentProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(processFinished(int, QProcess::ExitStatus)));
+        disconnect(m_currentProcess, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(processStateChanged(QProcess::ProcessState)));
 
-    delete m_currentProcess;
-    m_currentProcess = 0;
+        delete m_currentProcess;
+        m_currentProcess = 0;
+    }
 }
 
 void Command::processFinished(int exitCode, QProcess::ExitStatus exitStatus)
 {
+    //qDebug("Command::processFinished: (%d) %d", exitCode, exitStatus);
     gettimeofday(&m_currentProcessFinishTimeStamp, 0);
     m_currentProcessExitCode = exitCode;
     m_currentProcessExitStatus = exitStatus;
-    m_isInError = false;
-    m_isFinished = true;
+    m_hasExited = true;
     m_log = m_currentProcess->readAllStandardOutput();
 
 #if QT_VERSION < 0x051000
-        disconnect(m_currentProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));
+    disconnect(m_currentProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));
 #else
-        disconnect(m_currentProcess, SIGNAL(errorOccurred(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));
+    disconnect(m_currentProcess, SIGNAL(errorOccurred(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));
 #endif
     disconnect(m_currentProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(processFinished(int, QProcess::ExitStatus)));
     disconnect(m_currentProcess, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(processStateChanged(QProcess::ProcessState)));
diff --git a/sdrbase/commands/command.h b/sdrbase/commands/command.h
index 053c71aac..172ac0d31 100644
--- a/sdrbase/commands/command.h
+++ b/sdrbase/commands/command.h
@@ -59,7 +59,7 @@ public:
     void kill();
     QProcess::ProcessState getLastProcessState() const;
     bool getLastProcessError(QProcess::ProcessError& error) const;
-    bool getLastProcessTermination(int& exitCode, QProcess::ExitStatus& exitStatus) const;
+    bool getLastProcessExit(int& exitCode, QProcess::ExitStatus& exitStatus) const;
     const QString& getLastProcessLog() const;
     struct timeval getLastProcessStartTimestamp() const { return m_currentProcessStartTimeStamp; }
     struct timeval getLastProcessFinishTimestamp() const { return m_currentProcessFinishTimeStamp; }
@@ -101,7 +101,7 @@ private:
     QProcess::ProcessState m_currentProcessState;
     bool m_isInError;
     QProcess::ProcessError m_currentProcessError;
-    bool m_isFinished;
+    bool m_hasExited;
     int m_currentProcessExitCode;
     QProcess::ExitStatus m_currentProcessExitStatus;
     QString m_log;
diff --git a/sdrgui/gui/commandoutputdialog.cpp b/sdrgui/gui/commandoutputdialog.cpp
index 8f07cf220..02a878288 100644
--- a/sdrgui/gui/commandoutputdialog.cpp
+++ b/sdrgui/gui/commandoutputdialog.cpp
@@ -64,34 +64,35 @@ void CommandOutputDialog::refresh()
     ui->runningState->setChecked(m_command.getLastProcessState() == QProcess::Running);
     QProcess::ProcessError processError;
 
-    if (m_command.getLastProcessStartTimestamp().tv_sec == 0)
+    if (m_command.getLastProcessStartTimestamp().tv_sec == 0) // not started
     {
         ui->errorText->setText("...");
         ui->exitCode->setText("-");
         ui->exitText->setText("...");
         ui->runningState->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
     }
-    else if (m_command.getLastProcessState() != QProcess::NotRunning)
+    else if (m_command.getLastProcessState() != QProcess::NotRunning) // running
     {
         ui->errorText->setText("...");
-        ui->runningState->setStyleSheet("QToolButton { background-color : blue; }");
+        ui->runningState->setStyleSheet("QToolButton { background-color : orange; }");
     }
-    else if (m_command.getLastProcessError(processError))
+    else // finished
     {
-        ui->runningState->setStyleSheet("QToolButton { background-color : red; }");
-        setErrorText(processError);
-        ui->exitCode->setText("-");
-        ui->exitText->setText("...");
-    }
-    else
-    {
-        ui->runningState->setStyleSheet("QToolButton { background-color : green; }");
-        ui->errorText->setText("No error");
+        if (m_command.getLastProcessError(processError)) // finished
+        {
+            ui->runningState->setStyleSheet("QToolButton { background-color : red; }");
+            setErrorText(processError);
+        }
+        else
+        {
+            ui->runningState->setStyleSheet("QToolButton { background-color : green; }");
+            ui->errorText->setText("No error");
+        }
 
         int processExitCode;
         QProcess::ExitStatus processExitStatus;
 
-        if (m_command.getLastProcessTermination(processExitCode, processExitStatus))
+        if (m_command.getLastProcessExit(processExitCode, processExitStatus))
         {
             ui->exitCode->setText(QString("%1").arg(processExitCode));
             setExitText(processExitStatus);
@@ -148,13 +149,21 @@ void CommandOutputDialog::setExitText(const QProcess::ExitStatus& processExit)
     }
 }
 
-void CommandOutputDialog::on_processRefresh_toggled(bool checked __attribute__((unused)))
+void CommandOutputDialog::on_processRefresh_toggled(bool checked)
 {
-    refresh();
+    if (checked)
+    {
+        refresh();
+        ui->processRefresh->setChecked(false);
+    }
 }
 
-void CommandOutputDialog::on_processKill_toggled(bool checked __attribute__((unused)))
+void CommandOutputDialog::on_processKill_toggled(bool checked)
 {
-    m_command.kill();
+    if (checked)
+    {
+        m_command.kill();
+        ui->processKill->setChecked(false);
+    }
 }
 
diff --git a/sdrgui/gui/commandoutputdialog.ui b/sdrgui/gui/commandoutputdialog.ui
index 18f7220f9..3765c7974 100644
--- a/sdrgui/gui/commandoutputdialog.ui
+++ b/sdrgui/gui/commandoutputdialog.ui
@@ -55,6 +55,9 @@
         <iconset resource="../resources/res.qrc">
          <normaloff>:/recycle.png</normaloff>:/recycle.png</iconset>
        </property>
+       <property name="checkable">
+        <bool>true</bool>
+       </property>
       </widget>
      </item>
      <item>
@@ -158,6 +161,9 @@
         <iconset resource="../resources/res.qrc">
          <normaloff>:/kill.png</normaloff>:/kill.png</iconset>
        </property>
+       <property name="checkable">
+        <bool>true</bool>
+       </property>
       </widget>
      </item>
     </layout>
diff --git a/sdrgui/mainwindow.cpp b/sdrgui/mainwindow.cpp
index 22e270115..d79b316f2 100644
--- a/sdrgui/mainwindow.cpp
+++ b/sdrgui/mainwindow.cpp
@@ -682,14 +682,14 @@ QTreeWidgetItem* MainWindow::addCommandToTree(const Command* command)
 
     QStringList sl;
     sl.append(QString("%1").arg(command->getDescription())); // Descriptions column
-    sl.append(QString("%1").arg(command->getKeyLabel()));   // key column
     sl.append(QString("%1").arg(command->getAssociateKey() ? command->getRelease() ? "R" : "P" : "")); // key press/release column
+    sl.append(QString("%1").arg(command->getKeyLabel()));   // key column
     CommandItem* item = new CommandItem(group, sl, command->getDescription(), PItem);
     item->setData(0, Qt::UserRole, qVariantFromValue(command));
     item->setTextAlignment(0, Qt::AlignLeft);
-    ui->presetTree->resizeColumnToContents(0); // Resize description column to minimum
-    ui->presetTree->resizeColumnToContents(1); // Resize key column to minimum
-    ui->presetTree->resizeColumnToContents(2); // Resize key press/release column to minimum
+    ui->commandTree->resizeColumnToContents(0); // Resize description column to minimum
+    ui->commandTree->resizeColumnToContents(1); // Resize key column to minimum
+    ui->commandTree->resizeColumnToContents(2); // Resize key press/release column to minimum
 
     //updatePresetControls();
     return item;
@@ -816,9 +816,11 @@ void MainWindow::handleMessages()
 
 void MainWindow::on_action_View_Fullscreen_toggled(bool checked)
 {
-	if(checked)
+	if(checked) {
 		showFullScreen();
-	else showNormal();
+	} else {
+	    showNormal();
+	}
 }
 
 void MainWindow::on_commandNew_clicked()
diff --git a/sdrgui/mainwindow.ui b/sdrgui/mainwindow.ui
index e4a0f750f..45160acfd 100644
--- a/sdrgui/mainwindow.ui
+++ b/sdrgui/mainwindow.ui
@@ -591,12 +591,12 @@
        </column>
        <column>
         <property name="text">
-         <string>Key</string>
+         <string>P/R</string>
         </property>
        </column>
        <column>
         <property name="text">
-         <string>P/R</string>
+         <string>Key</string>
         </property>
        </column>
       </widget>