#include "runCmd.h" RunCmd::RunCmd( int c, int r, ChannelMasks* m, QWidget* parentCP, QWidget* parent ) : QMainWindow( parentCP ) { //Set the name and title of the window. setObjectName( "Run Commands" ); setWindowTitle( "Run Command Window" ); // Copy the parameters to the member variables. channels = c; masks = m; rNum = r; // Connect the signal to the parent's activity log. connect( this, SIGNAL( writeMsg( QString, int ) ), parent, SLOT( writeLog( QString, int ) ) ); // Create the QGridLayout layout = new QGridLayout; // Create the QLabels and QCheckBoxes for the channels. chanBox = new QCheckBox*[ channels+1 ]; for( int i = 0; i < channels; ++i ) { QString ch = "Channel "; QString chanNum; chanNum.setNum( i + 1 ); ch.append( chanNum ); chanBox[i] = new QCheckBox( ch, this ); } // Control channel label and check box. QString ch = "Channel C"; chanBox[ channels ] = new QCheckBox( ch, this ); // Create the QProcesses that could run for each channel. procs = new QProcess*[ channels + 1 ]; procFinished = new bool[ channels + 1 ]; for( int l = 0; l <= channels; ++l ) { procs[l] = NULL; } // Create the QLineEdit for the command to run. cmdLine = new QLineEdit( "" ); cmdLineLabel = new QLabel( "Command to run: " ); // Create the QPushButton to run the command on the selected channels. runCmdButton = new QPushButton( "Run Command" ); connect( runCmdButton, SIGNAL( clicked() ), this, SLOT( runCommand() ) ); selAllButton = new QPushButton( "Select All Slices" ); connect( selAllButton, SIGNAL( clicked() ), this, SLOT( selectAll() ) ); selNoneButton = new QPushButton( "Deselect All Slices" ); connect( selNoneButton, SIGNAL( clicked() ), this, SLOT( deselectAll() ) ); // Place the checkboxes in a QGridLayout. int remainder = ( channels + 1 ) % 4; int rows = ( channels + 1 ) / 4; // Check the remainder when dividing by 4 to determine how to add the elements to layout. if( remainder == 0 ) { // Add the rows with a full 4 checkboxes. for( int i = 0; i < rows; ++i ) { layout->addWidget( chanBox[ ( 4 * i ) + 0 ], i + 1, 0 ); layout->addWidget( chanBox[ ( 4 * i ) + 1 ], i + 1, 1 ); layout->addWidget( chanBox[ ( 4 * i ) + 2 ], i + 1, 2 ); layout->addWidget( chanBox[ ( 4 * i ) + 3 ], i + 1, 3 ); } // Place the command line QLineEdit in the grid. layout->addWidget( cmdLineLabel, rows+1, 0 ); layout->addWidget( cmdLine, rows+1, 1, 1, 3 ); layout->addWidget( selAllButton, rows+2, 0 ); layout->addWidget( selNoneButton, rows+2, 1 ); layout->addWidget( runCmdButton, rows+2, 2, 1, 2 ); } else if( remainder == 1 ) { // Add the rows with a full 4 checkboxes. for( int i = 0; i < rows; ++i ) { layout->addWidget( chanBox[ ( 4 * i ) + 0 ], i + 1, 0 ); layout->addWidget( chanBox[ ( 4 * i ) + 1 ], i + 1, 1 ); layout->addWidget( chanBox[ ( 4 * i ) + 2 ], i + 1, 2 ); layout->addWidget( chanBox[ ( 4 * i ) + 3 ], i + 1, 3 ); } // Add the remaining checkboxes. layout->addWidget( chanBox[ channels ], rows+1, 0 ); // Place the command line QLineEdit in the grid. layout->addWidget( cmdLineLabel, rows+2, 0 ); layout->addWidget( cmdLine, rows+2, 1, 1, 3 ); layout->addWidget( selAllButton, rows+3, 0 ); layout->addWidget( selNoneButton, rows+3, 1 ); layout->addWidget( runCmdButton, rows+3, 2, 1, 2 ); } else if( remainder == 2 ) { // Add the rows with a full 4 checkboxes. for( int i = 0; i < rows; ++i ) { layout->addWidget( chanBox[ ( 4 * i ) + 0 ], i + 1, 0 ); layout->addWidget( chanBox[ ( 4 * i ) + 1 ], i + 1, 1 ); layout->addWidget( chanBox[ ( 4 * i ) + 2 ], i + 1, 2 ); layout->addWidget( chanBox[ ( 4 * i ) + 3 ], i + 1, 3 ); } // Add the remaining checkboxes. layout->addWidget( chanBox[ channels - 1 ], rows+1, 0 ); layout->addWidget( chanBox[ channels ], rows+1, 1 ); // Place the command line QLineEdit in the grid. layout->addWidget( cmdLineLabel, rows+2, 0 ); layout->addWidget( cmdLine, rows+2, 1, 1, 3 ); layout->addWidget( selAllButton, rows+3, 0 ); layout->addWidget( selNoneButton, rows+3, 1 ); layout->addWidget( runCmdButton, rows+3, 2, 1, 2 ); } else { // Add the rows with a full 4 checkboxes. for( int i = 0; i < rows; ++i ) { layout->addWidget( chanBox[ ( 4 * i ) + 0 ], i + 1, 0 ); layout->addWidget( chanBox[ ( 4 * i ) + 1 ], i + 1, 1 ); layout->addWidget( chanBox[ ( 4 * i ) + 2 ], i + 1, 2 ); layout->addWidget( chanBox[ ( 4 * i ) + 3 ], i + 1, 3 ); } // Add the remaining checkboxes. layout->addWidget( chanBox[ channels - 2 ], rows+1, 0 ); layout->addWidget( chanBox[ channels - 1 ], rows+1, 1 ); layout->addWidget( chanBox[ channels ], rows+1, 2 ); // Place the command line QLineEdit in the grid. layout->addWidget( cmdLineLabel, rows+2, 0 ); layout->addWidget( cmdLine, rows+2, 1, 1, 3 ); layout->addWidget( selAllButton, rows+3, 0 ); layout->addWidget( selNoneButton, rows+3, 1 ); layout->addWidget( runCmdButton, rows+3, 2, 1, 2 ); } // Create a central widget and set the layout for the window. setCentralWidget( new QWidget() ); centralWidget()->setLayout( layout ); } RunCmd::~RunCmd() { } void RunCmd::runCommand() { // Write message to log. emit writeMsg( ">Running terminal command on selected slices.", CMD ); // Get the command to be run on each selected slice. QString cmdRun = cmdLine->text(); // Debug message. //emit writeMsg( cmdRun, DEBUG ); // Create the processes to run. QString cmd[ channels + 1 ]; QStringList args[ channels + 1 ]; QString radar; radar.setNum( rNum ); for( int i = 0; i < channels; ++i ) { // Create the server string to add to the args. QString server; server = "root@10.14."; QString chan; chan.setNum( i + 1 ); server.append( radar ); server.append( "." ); server.append( chan ); //emit writeMsg( server, DEBUG ); // Set the command to run in the QProcess. cmd[i] = "ssh"; // Add the server and the command to run to args. args[i] << server << cmdRun; // Create the process for the channel. if( procs[i] ) { delete procs[i]; procs[i] = NULL; } procs[i] = new QProcess( this ); // Process has not finished. procFinished[i] = false; } // Create the process and strings for the control channel. QString server = "root@10.14."; server.append( radar ); server.append( ".100" ); cmd[ channels ] = "ssh"; args[ channels ] << server << cmdRun; if( procs[ channels ] ) { delete procs[ channels ]; procs[ channels ] = NULL; } procs[ channels ] = new QProcess( this ); // Control process has not finished. procFinished[ channels ] = false; // Run the processes on the selected channels. for( int k = 0; k <= channels; ++k ) { if( chanBox[k]->isChecked() && chanBox[k]->isEnabled() ) { connect( procs[k], SIGNAL( finished( int ) ), this, SLOT( runCommandFin() ) ); procs[k]->start( cmd[k], args[k] ); } } } void RunCmd::runCommandFin() { // Check if every process has finished. // If a process is not running, it has finished. bool allFinished = true; for( int i = 0; i <= channels; ++i ) { if( ( procs[i]->state() != QProcess::NotRunning ) && chanBox[i]->isChecked() && chanBox[i]->isEnabled() ) { allFinished = false; if( !procFinished[i] ) { procFinished[i] = true; QString chanNum; // Determine if the finished process is the one on the control channel. if( i == channels ) { emit writeMsg( "Command finished running on control slice.", CMD ); } else { chanNum.setNum( i+1 ); emit writeMsg( "Command finished running on slice " + chanNum, CMD ); } } } } // All of the processes have finished. if( allFinished ) { // Write out a message for the last process to finish. for( int k = 0; k <= channels; ++k ) { if( !procFinished[k] && chanBox[k]->isChecked() && chanBox[k]->isEnabled() ) { procFinished[k] = true; QString chanNum; // Determine if the finished process is the one on the control channel. if( k == channels ) { emit writeMsg( "Command finished running on control slice.", CMD ); } else { chanNum.setNum( k+1 ); emit writeMsg( "Command finished running on slice " + chanNum, CMD ); } } } for( int m = 0; m <= channels; ++m ) { if( chanBox[m]->isEnabled() && chanBox[m]->isChecked() ) { if( m == channels ) { emit writeMsg( "Output from control slice.", CMD ); readOutput( m ); } else { QString chanNum; chanNum.setNum( m+1 ); emit writeMsg( "Output from slice " + chanNum, CMD ); readOutput( m ); } } } // Write a message that the processes are all finished. emit writeMsg( ">All commands have been run.", CMD ); } } void RunCmd::readOutput( int c ) { while( procs[c]->bytesAvailable() ) { QString outputTxt = procs[c]->readAll(); emit writeMsg( outputTxt, CMD ); } } void RunCmd::closeEvent( QCloseEvent* event ) { // Accept the close event. event->accept(); } void RunCmd::displayWindow() { for( int i = 0; i < channels; ++i ) { if( masks->chanMasked( i ) ) { chanBox[i]->setEnabled( false ); chanBox[i]->setChecked( false ); } else { chanBox[i]->setEnabled( true ); } } this->show(); } void RunCmd::selectAll() { for( int i = 0; i <= channels; ++i ) { if( chanBox[i]->isEnabled() ) { chanBox[i]->setChecked( true ); } } } void RunCmd::deselectAll() { for( int i = 0; i <= channels; ++i ) { if( chanBox[i]->isEnabled() ) { chanBox[i]->setChecked( false ); } } }