mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-25 09:18:54 -05:00
Commands: implemented run and output GUI
This commit is contained in:
parent
89f98f504a
commit
069d9a7d07
BIN
doc/img/kill.xcf
Normal file
BIN
doc/img/kill.xcf
Normal file
Binary file not shown.
@ -18,12 +18,51 @@
|
||||
#include "util/simpleserializer.h"
|
||||
|
||||
#include <QKeySequence>
|
||||
#include <QProcess>
|
||||
|
||||
Command::Command()
|
||||
Command::Command() :
|
||||
m_currentProcess(0),
|
||||
m_currentProcessState(QProcess::NotRunning),
|
||||
m_isInError(false),
|
||||
m_currentProcessError(QProcess::UnknownError),
|
||||
m_isFinished(true),
|
||||
m_currentProcessExitCode(0),
|
||||
m_currentProcessExitStatus(QProcess::NormalExit),
|
||||
m_currentProcessPid(0)
|
||||
{
|
||||
m_currentProcessStartTimeStamp.tv_sec = 0;
|
||||
m_currentProcessStartTimeStamp.tv_usec = 0;
|
||||
m_currentProcessFinishTimeStamp.tv_sec = 0;
|
||||
m_currentProcessFinishTimeStamp.tv_usec = 0;
|
||||
|
||||
resetToDefaults();
|
||||
}
|
||||
|
||||
Command::Command(const Command& command) :
|
||||
QObject(),
|
||||
m_group(command.m_group),
|
||||
m_description(command.m_description),
|
||||
m_command(command.m_command),
|
||||
m_argString(command.m_argString),
|
||||
m_key(command.m_key),
|
||||
m_keyModifiers(command.m_keyModifiers),
|
||||
m_associateKey(command.m_associateKey),
|
||||
m_release(command.m_release),
|
||||
m_currentProcess(0),
|
||||
m_currentProcessState(QProcess::NotRunning),
|
||||
m_isInError(false),
|
||||
m_currentProcessError(QProcess::UnknownError),
|
||||
m_isFinished(true),
|
||||
m_currentProcessExitCode(0),
|
||||
m_currentProcessExitStatus(QProcess::NormalExit),
|
||||
m_currentProcessPid(0)
|
||||
{
|
||||
m_currentProcessStartTimeStamp.tv_sec = 0;
|
||||
m_currentProcessStartTimeStamp.tv_usec = 0;
|
||||
m_currentProcessFinishTimeStamp.tv_sec = 0;
|
||||
m_currentProcessFinishTimeStamp.tv_usec = 0;
|
||||
}
|
||||
|
||||
Command::~Command()
|
||||
{}
|
||||
|
||||
@ -34,6 +73,7 @@ void Command::resetToDefaults()
|
||||
m_command = "";
|
||||
m_argString = "";
|
||||
m_key = static_cast<Qt::Key>(0);
|
||||
m_keyModifiers = Qt::NoModifier,
|
||||
m_associateKey = false;
|
||||
m_release = false;
|
||||
}
|
||||
@ -106,3 +146,150 @@ QString Command::getKeyLabel() const
|
||||
return QKeySequence(m_key).toString();
|
||||
}
|
||||
}
|
||||
|
||||
void Command::run(const QString& apiAddress, int apiPort, int deviceSetIndex)
|
||||
{
|
||||
if (m_currentProcess)
|
||||
{
|
||||
qWarning("Command::run: process already running");
|
||||
return;
|
||||
}
|
||||
|
||||
QString args = m_argString;
|
||||
|
||||
if (m_argString.contains("%1"))
|
||||
{
|
||||
args = args.arg(apiAddress);
|
||||
}
|
||||
|
||||
if (m_argString.contains("%2"))
|
||||
{
|
||||
args.replace("%2", "%1");
|
||||
args = args.arg(apiPort);
|
||||
}
|
||||
|
||||
if (m_argString.contains("%3"))
|
||||
{
|
||||
args.replace("%3", "%1");
|
||||
args = args.arg(deviceSetIndex);
|
||||
}
|
||||
|
||||
m_currentProcessCommandLine = QString("%1 %2").arg(m_command).arg(args);
|
||||
qDebug("Command::run: %s", qPrintable(m_currentProcessCommandLine));
|
||||
|
||||
m_currentProcess = new QProcess(this);
|
||||
m_isInError = false;
|
||||
m_isFinished = false;
|
||||
|
||||
#if QT_VERSION < 0x051000
|
||||
connect(m_currentProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));
|
||||
#else
|
||||
connect(m_currentProcess, SIGNAL(errorOccurred(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));
|
||||
#endif
|
||||
connect(m_currentProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(processFinished(int, QProcess::ExitStatus)));
|
||||
connect(m_currentProcess, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(processStateChanged(QProcess::ProcessState)));
|
||||
|
||||
m_currentProcess->setProcessChannelMode(QProcess::MergedChannels);
|
||||
gettimeofday(&m_currentProcessStartTimeStamp, 0);
|
||||
m_currentProcess->start(m_currentProcessCommandLine);
|
||||
}
|
||||
|
||||
void Command::kill()
|
||||
{
|
||||
if (m_currentProcess)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
QProcess::ProcessState Command::getLastProcessState() const
|
||||
{
|
||||
return m_currentProcessState;
|
||||
}
|
||||
|
||||
bool Command::getLastProcessError(QProcess::ProcessError& error) const
|
||||
{
|
||||
if (m_isInError) {
|
||||
error = m_currentProcessError;
|
||||
}
|
||||
|
||||
return m_isInError;
|
||||
}
|
||||
|
||||
bool Command::getLastProcessTermination(int& exitCode, QProcess::ExitStatus& exitStatus) const
|
||||
{
|
||||
if (m_isFinished)
|
||||
{
|
||||
exitCode = m_currentProcessExitCode;
|
||||
exitStatus = m_currentProcessExitStatus;
|
||||
}
|
||||
|
||||
return m_isFinished;
|
||||
}
|
||||
|
||||
const QString& Command::getLastProcessLog() const
|
||||
{
|
||||
return m_log;
|
||||
}
|
||||
|
||||
void Command::processStateChanged(QProcess::ProcessState newState)
|
||||
{
|
||||
if (newState == QProcess::Running) {
|
||||
m_currentProcessPid = m_currentProcess->processId();
|
||||
}
|
||||
|
||||
m_currentProcessState = newState;
|
||||
}
|
||||
|
||||
void Command::processError(QProcess::ProcessError error)
|
||||
{
|
||||
gettimeofday(&m_currentProcessFinishTimeStamp, 0);
|
||||
m_currentProcessError = error;
|
||||
m_isInError = true;
|
||||
m_isFinished = true;
|
||||
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)));
|
||||
|
||||
delete m_currentProcess;
|
||||
m_currentProcess = 0;
|
||||
}
|
||||
|
||||
void Command::processFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||
{
|
||||
gettimeofday(&m_currentProcessFinishTimeStamp, 0);
|
||||
m_currentProcessExitCode = exitCode;
|
||||
m_currentProcessExitStatus = exitStatus;
|
||||
m_isInError = false;
|
||||
m_isFinished = true;
|
||||
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)));
|
||||
|
||||
delete m_currentProcess;
|
||||
m_currentProcess = 0;
|
||||
}
|
||||
|
@ -21,11 +21,16 @@
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
#include <QMetaType>
|
||||
#include <QObject>
|
||||
#include <QProcess>
|
||||
#include <sys/time.h>
|
||||
|
||||
class Command
|
||||
class Command : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Command();
|
||||
Command(const Command& command);
|
||||
~Command();
|
||||
void resetToDefaults();
|
||||
|
||||
@ -48,9 +53,19 @@ public:
|
||||
bool getAssociateKey() const { return m_associateKey; }
|
||||
void setRelease(bool release) { m_release = release; }
|
||||
bool getRelease() const { return m_release; }
|
||||
|
||||
QString getKeyLabel() const;
|
||||
|
||||
void run(const QString& apiAddress, int apiPort, int deviceSetIndex);
|
||||
void kill();
|
||||
QProcess::ProcessState getLastProcessState() const;
|
||||
bool getLastProcessError(QProcess::ProcessError& error) const;
|
||||
bool getLastProcessTermination(int& exitCode, QProcess::ExitStatus& exitStatus) const;
|
||||
const QString& getLastProcessLog() const;
|
||||
struct timeval getLastProcessStartTimestamp() const { return m_currentProcessStartTimeStamp; }
|
||||
struct timeval getLastProcessFinishTimestamp() const { return m_currentProcessFinishTimeStamp; }
|
||||
const QString& getLastProcessCommandLine() const { return m_currentProcessCommandLine; }
|
||||
qint64 getLastProcessPid() const { return m_currentProcessPid; }
|
||||
|
||||
static bool commandCompare(const Command *c1, Command *c2)
|
||||
{
|
||||
if (c1->m_group != c2->m_group)
|
||||
@ -74,14 +89,31 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_command;
|
||||
QString m_argString;
|
||||
QString m_group;
|
||||
QString m_description;
|
||||
QString m_command;
|
||||
QString m_argString;
|
||||
Qt::Key m_key;
|
||||
Qt::KeyboardModifiers m_keyModifiers;
|
||||
bool m_associateKey;
|
||||
bool m_release;
|
||||
QProcess *m_currentProcess;
|
||||
QProcess::ProcessState m_currentProcessState;
|
||||
bool m_isInError;
|
||||
QProcess::ProcessError m_currentProcessError;
|
||||
bool m_isFinished;
|
||||
int m_currentProcessExitCode;
|
||||
QProcess::ExitStatus m_currentProcessExitStatus;
|
||||
QString m_log;
|
||||
struct timeval m_currentProcessStartTimeStamp;
|
||||
struct timeval m_currentProcessFinishTimeStamp;
|
||||
QString m_currentProcessCommandLine;
|
||||
qint64 m_currentProcessPid;
|
||||
|
||||
private slots:
|
||||
void processStateChanged(QProcess::ProcessState newState);
|
||||
void processError(QProcess::ProcessError error);
|
||||
void processFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(const Command*);
|
||||
|
@ -10,6 +10,7 @@ set(sdrgui_SOURCES
|
||||
gui/clickablelabel.cpp
|
||||
gui/colormapper.cpp
|
||||
gui/commanditem.cpp
|
||||
gui/commandoutputdialog.cpp
|
||||
gui/cwkeyergui.cpp
|
||||
gui/editcommanddialog.cpp
|
||||
gui/externalclockbutton.cpp
|
||||
@ -63,6 +64,7 @@ set(sdrgui_HEADERS
|
||||
gui/channelwindow.h
|
||||
gui/colormapper.h
|
||||
gui/commanditem.h
|
||||
gui/commandoutputdialog.h
|
||||
gui/cwkeyergui.h
|
||||
gui/editcommanddialog.h
|
||||
gui/externalclockbutton.h
|
||||
@ -118,6 +120,7 @@ set(sdrgui_FORMS
|
||||
gui/aboutdialog.ui
|
||||
gui/addpresetdialog.ui
|
||||
gui/basicchannelsettingsdialog.ui
|
||||
gui/commandoutputdialog.ui
|
||||
gui/cwkeyergui.ui
|
||||
gui/editcommanddialog.ui
|
||||
gui/externalclockdialog.ui
|
||||
|
160
sdrgui/gui/commandoutputdialog.cpp
Normal file
160
sdrgui/gui/commandoutputdialog.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2018 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "commandoutputdialog.h"
|
||||
#include "ui_commandoutputdialog.h"
|
||||
#include "commands/command.h"
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
CommandOutputDialog::CommandOutputDialog(Command& command, QWidget* parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::CommandOutputDialog),
|
||||
m_command(command)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
refresh();
|
||||
}
|
||||
|
||||
CommandOutputDialog::~CommandOutputDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void CommandOutputDialog::refresh()
|
||||
{
|
||||
ui->commandText->setText(m_command.getLastProcessCommandLine());
|
||||
ui->processPid->setText(QString("%1").arg(m_command.getLastProcessPid()));
|
||||
|
||||
if (m_command.getLastProcessStartTimestamp().tv_sec == 0) {
|
||||
ui->startTime->setText(("..."));
|
||||
}
|
||||
else
|
||||
{
|
||||
struct timeval tv = m_command.getLastProcessStartTimestamp();
|
||||
QDateTime dt = QDateTime::fromMSecsSinceEpoch(tv.tv_sec * 1000LL + tv.tv_usec / 1000LL);
|
||||
QString dateStr = dt.toString("yyyy-MM-dd hh:mm:ss.zzz");
|
||||
ui->startTime->setText(dateStr);
|
||||
}
|
||||
|
||||
if (m_command.getLastProcessFinishTimestamp().tv_sec == 0) {
|
||||
ui->endTime->setText(("..."));
|
||||
}
|
||||
else
|
||||
{
|
||||
struct timeval tv = m_command.getLastProcessFinishTimestamp();
|
||||
QDateTime dt = QDateTime::fromMSecsSinceEpoch(tv.tv_sec * 1000LL + tv.tv_usec / 1000LL);
|
||||
QString dateStr = dt.toString("yyyy-MM-dd hh:mm:ss.zzz");
|
||||
ui->endTime->setText(dateStr);
|
||||
}
|
||||
|
||||
ui->runningState->setChecked(m_command.getLastProcessState() == QProcess::Running);
|
||||
QProcess::ProcessError processError;
|
||||
|
||||
if (m_command.getLastProcessStartTimestamp().tv_sec == 0)
|
||||
{
|
||||
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)
|
||||
{
|
||||
ui->errorText->setText("...");
|
||||
ui->runningState->setStyleSheet("QToolButton { background-color : blue; }");
|
||||
}
|
||||
else if (m_command.getLastProcessError(processError))
|
||||
{
|
||||
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");
|
||||
|
||||
int processExitCode;
|
||||
QProcess::ExitStatus processExitStatus;
|
||||
|
||||
if (m_command.getLastProcessTermination(processExitCode, processExitStatus))
|
||||
{
|
||||
ui->exitCode->setText(QString("%1").arg(processExitCode));
|
||||
setExitText(processExitStatus);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->exitCode->setText("-");
|
||||
ui->exitText->setText("...");
|
||||
}
|
||||
}
|
||||
|
||||
ui->logEdit->setPlainText(m_command.getLastProcessLog());
|
||||
}
|
||||
|
||||
void CommandOutputDialog::setErrorText(const QProcess::ProcessError& processError)
|
||||
{
|
||||
switch(processError)
|
||||
{
|
||||
case QProcess::FailedToStart:
|
||||
ui->errorText->setText("Failed to start");
|
||||
break;
|
||||
case QProcess::Crashed:
|
||||
ui->errorText->setText("Crashed");
|
||||
break;
|
||||
case QProcess::Timedout:
|
||||
ui->errorText->setText("Timed out");
|
||||
break;
|
||||
case QProcess::WriteError:
|
||||
ui->errorText->setText("Write error");
|
||||
break;
|
||||
case QProcess::ReadError:
|
||||
ui->errorText->setText("Read error");
|
||||
break;
|
||||
case QProcess::UnknownError:
|
||||
default:
|
||||
ui->errorText->setText("Unknown error");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CommandOutputDialog::setExitText(const QProcess::ExitStatus& processExit)
|
||||
{
|
||||
switch(processExit)
|
||||
{
|
||||
case QProcess::NormalExit:
|
||||
ui->exitText->setText("Normal exit");
|
||||
break;
|
||||
case QProcess::CrashExit:
|
||||
ui->exitText->setText("Program crashed");
|
||||
break;
|
||||
default:
|
||||
ui->exitText->setText("Unknown state");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CommandOutputDialog::on_processRefresh_toggled(bool checked __attribute__((unused)))
|
||||
{
|
||||
refresh();
|
||||
}
|
||||
|
||||
void CommandOutputDialog::on_processKill_toggled(bool checked __attribute__((unused)))
|
||||
{
|
||||
m_command.kill();
|
||||
}
|
||||
|
52
sdrgui/gui/commandoutputdialog.h
Normal file
52
sdrgui/gui/commandoutputdialog.h
Normal file
@ -0,0 +1,52 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2018 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SDRGUI_GUI_COMMANDOUTPUTDIALOG_H_
|
||||
#define SDRGUI_GUI_COMMANDOUTPUTDIALOG_H_
|
||||
|
||||
#include <QDialog>
|
||||
#include <QProcess>
|
||||
|
||||
namespace Ui {
|
||||
class CommandOutputDialog;
|
||||
}
|
||||
|
||||
class Command;
|
||||
|
||||
class CommandOutputDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CommandOutputDialog(Command& command, QWidget* parent = 0);
|
||||
~CommandOutputDialog();
|
||||
|
||||
void fromCommand(const Command& command);
|
||||
|
||||
private:
|
||||
Ui::CommandOutputDialog* ui;
|
||||
Command& m_command;
|
||||
|
||||
void refresh();
|
||||
void setErrorText(const QProcess::ProcessError& processError);
|
||||
void setExitText(const QProcess::ExitStatus& processExit);
|
||||
|
||||
private slots:
|
||||
void on_processRefresh_toggled(bool checked);
|
||||
void on_processKill_toggled(bool checked);
|
||||
};
|
||||
|
||||
|
||||
#endif /* SDRGUI_GUI_COMMANDOUTPUTDIALOG_H_ */
|
332
sdrgui/gui/commandoutputdialog.ui
Normal file
332
sdrgui/gui/commandoutputdialog.ui
Normal file
@ -0,0 +1,332 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CommandOutputDialog</class>
|
||||
<widget class="QDialog" name="CommandOutputDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>547</width>
|
||||
<height>380</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Sans Serif</family>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Command output</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="processLayout">
|
||||
<item>
|
||||
<widget class="QToolButton" name="runningState">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Running state icon</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/res.qrc">
|
||||
<normaloff>:/stop.png</normaloff>
|
||||
<normalon>:/play.png</normalon>:/stop.png</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="processRefresh">
|
||||
<property name="toolTip">
|
||||
<string>Refresh data</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/res.qrc">
|
||||
<normaloff>:/recycle.png</normaloff>:/recycle.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="startTime">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>146</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Start time of last execution</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>2015-01-01 00:00:00.000</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="timeMidLabel">
|
||||
<property name="text">
|
||||
<string>-</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="endTime">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>146</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>End time of last execution</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>2015-01-01 00:00:00.000</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="processPid">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Process PID</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>00000</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="processKill">
|
||||
<property name="toolTip">
|
||||
<string>Kill the process (SIGKILL)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/res.qrc">
|
||||
<normaloff>:/kill.png</normaloff>:/kill.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="commandLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="commandLabel">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>23</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Cmd:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="commandText">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Command that was executed</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="errorExitLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="errorLabel">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>23</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Error:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="errorText">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Process error status</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="exitLabel">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>23</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Exit:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="exitCode">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Return code</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="exitText">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Process exit status</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="logEdit">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Output log (stdout + stderr)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>buttonBox</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../resources/res.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>CommandOutputDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>257</x>
|
||||
<y>194</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>203</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>CommandOutputDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>314</x>
|
||||
<y>194</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>203</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -140,7 +140,7 @@ void EditCommandDialog::on_showFileDialog_clicked(bool checked __attribute__((un
|
||||
this,
|
||||
tr("Select command"),
|
||||
dirStr,
|
||||
tr("Python (*.py);;Shell (*.sh *.bat);;Binary (*.bin *.exe);;All (*.*)"));
|
||||
tr("Python (*.py);;Shell (*.sh *.bat);;Binary (*.bin *.exe);;All (*)"));
|
||||
|
||||
if (fileName != "") {
|
||||
ui->command->setText(fileName);
|
||||
@ -249,4 +249,3 @@ void EditCommandDialog::setKeyAssociate()
|
||||
ui->keyAssociate->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "gui/commanditem.h"
|
||||
#include "gui/addpresetdialog.h"
|
||||
#include "gui/editcommanddialog.h"
|
||||
#include "gui/commandoutputdialog.h"
|
||||
#include "gui/pluginsdialog.h"
|
||||
#include "gui/aboutdialog.h"
|
||||
#include "gui/rollupwidget.h"
|
||||
@ -934,6 +935,32 @@ void MainWindow::on_commandDelete_clicked()
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_commandRun_clicked()
|
||||
{
|
||||
QTreeWidgetItem* item = ui->commandTree->currentItem();
|
||||
|
||||
if ((item != 0) && (item->type() == PItem))
|
||||
{
|
||||
const Command* command = qvariant_cast<const Command*>(item->data(0, Qt::UserRole));
|
||||
Command* command_mod = const_cast<Command*>(command);
|
||||
int currentDeviceSetIndex = ui->tabInputsSelect->currentIndex();
|
||||
command_mod->run(m_apiServer->getHost(), m_apiServer->getPort(), currentDeviceSetIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_commandOutput_clicked()
|
||||
{
|
||||
QTreeWidgetItem* item = ui->commandTree->currentItem();
|
||||
|
||||
if ((item != 0) && (item->type() == PItem))
|
||||
{
|
||||
const Command* command = qvariant_cast<const Command*>(item->data(0, Qt::UserRole));
|
||||
Command* command_mod = const_cast<Command*>(command);
|
||||
CommandOutputDialog commandOutputDialog(*command_mod);
|
||||
commandOutputDialog.exec();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_presetSave_clicked()
|
||||
{
|
||||
QStringList groups;
|
||||
|
@ -348,6 +348,8 @@ private slots:
|
||||
void on_commandDuplicate_clicked();
|
||||
void on_commandEdit_clicked();
|
||||
void on_commandDelete_clicked();
|
||||
void on_commandRun_clicked();
|
||||
void on_commandOutput_clicked();
|
||||
void on_action_Audio_triggered();
|
||||
void on_action_Logging_triggered();
|
||||
void on_action_DV_Serial_triggered(bool checked);
|
||||
|
@ -672,9 +672,9 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="commandViewOutput">
|
||||
<widget class="QToolButton" name="commandOutput">
|
||||
<property name="toolTip">
|
||||
<string>View last run output</string>
|
||||
<string>View last run status and output</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
|
BIN
sdrgui/resources/kill.png
Normal file
BIN
sdrgui/resources/kill.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 673 B |
@ -90,5 +90,6 @@
|
||||
<file>save.png</file>
|
||||
<file>load.png</file>
|
||||
<file>keyboard.png</file>
|
||||
<file>kill.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -51,6 +51,7 @@ SOURCES += mainwindow.cpp\
|
||||
gui/clickablelabel.cpp\
|
||||
gui/colormapper.cpp\
|
||||
gui/commanditem.cpp\
|
||||
gui/commandoutputdialog.cpp\
|
||||
gui/cwkeyergui.cpp\
|
||||
gui/editcommanddialog.cpp\
|
||||
gui/externalclockbutton.cpp\
|
||||
@ -100,6 +101,7 @@ HEADERS += mainwindow.h\
|
||||
gui/clickablelabel.h\
|
||||
gui/colormapper.h\
|
||||
gui/commanditem.h\
|
||||
gui/commandoutputdialog.h\
|
||||
gui/cwkeyergui.h\
|
||||
gui/editcommanddialog.h\
|
||||
gui/externalclockbutton.h\
|
||||
@ -135,6 +137,7 @@ FORMS += mainwindow.ui\
|
||||
gui/scopewindow.ui\
|
||||
gui/addpresetdialog.ui\
|
||||
gui/basicchannelsettingsdialog.ui\
|
||||
gui/commandoutputdialog.ui\
|
||||
gui/cwkeyergui.ui\
|
||||
gui/editcommanddialog.ui\
|
||||
gui/externalclockdialog.ui\
|
||||
|
Loading…
Reference in New Issue
Block a user