#include "quickLook.h" /* Function: QuickLook * Params In * QWidget *parent: Pointer to the parent widget of the Main Window. Default is NULL. * Return * N/A * Purpose * The default constructor for the class. Sets up the main window that displays options for the user. */ QuickLook::QuickLook( int rNum, int cNum, ChannelMasks* chMasks, QWidget* parentCP, QWidget* parent ) : QMainWindow( parentCP ) { //Set the name and title of the window. setObjectName( "Main Window" ); setWindowTitle( "MCoRDS CSARP-Flight (Q-Look)" ); // Set the default path for the Quick Look recording files. recPath = QDir::currentPath(); recPath.append( "/output" ); // Copy parameters to member variables. cNumber = cNum; // Number of channels. rNumber = rNum; // Radar number. cMasks = chMasks; // Pointer to channel masks. parCP = parentCP; // Pointer to control panel window. par = parent; // Pointer to parent object. // Initialize variables. uavData = NULL; processData = NULL; // Connect signals to functions in parent window (control panel). connect( this, SIGNAL( quickLookClosed() ), parent, SLOT( closeQLook() ) ); connect( this, SIGNAL( updateStatus( QString, uint32_t, uint32_t ) ), parentCP, SLOT( setStatusValues( QString, uint32_t, uint32_t ) ) ); connect( this, SIGNAL( updateRefresh( QString ) ), parentCP, SLOT( setRefresh( QString ) ) ); connect( this, SIGNAL( writeMsg( QString, int ) ), parentCP, SLOT( writeToLog( QString, int ) ) ); connect( this, SIGNAL( updateLED( QColor, int ) ), parentCP, SLOT( changeStatusLEDColor( QColor, int ) ) ); // Initialize array. channels = new QCheckBox*[ cNumber ]; //Array to tell which channels are checked by the user. channelVals = new bool[ cNumber ]; //Functions to setup the Q-Look GUI. createMenu(); createButtons(); createChannelBox(); createEchoOptions(); createAScopeOptions(); createGenOptions(); //Add box widgets to the main layout so that they are displayed properly. QVBoxLayout* mainLayout = new QVBoxLayout; mainLayout->setMenuBar( menuBar ); mainLayout->addWidget( buttonBox ); mainLayout->addWidget( channelBox ); mainLayout->addWidget( eOptionsBox ); mainLayout->addWidget( aOptionsBox ); mainLayout->addWidget( gOptionsBox ); setCentralWidget( new QWidget() ); centralWidget()->setLayout( mainLayout ); } /* Function: ~QuickLook * Params In * N/A * Return * N/A * Purpose * The default destructor for the class. Deletes memory from pointers to free up space. */ QuickLook::~QuickLook() { delete [] channelVals; //delete buttons; //delete channels; //delete radios; //delete depthScale; //delete eColorMapLabels; //delete eColorMapLines; delete buttonBox; delete channelBox; delete aOptionsBox; delete eOptionsBox; delete gOptionsBox; delete exitAction; delete fileMenu; delete menuBar; // Delete the processing and storage objects. if( processData ) { delete processData; processData = NULL; } if( uavData ) { delete uavData; uavData = NULL; } if( refPulse ) { refPulse->close(); delete refPulse; refPulse = NULL; } } /* Function: createAScopeOptions * Params In * N/A * Return * N/A * Purpose * Function creates the general options to be used by both Echogram * and Plot windows. */ void QuickLook::createGenOptions() { //GroupBox contains the radio buttons. gOptionsBox = new QGroupBox( tr( "General Options for Plotting Channels" ) ); gOffsetBox = new QGroupBox( tr( "Axis Offset Values" ) ); gDepthBox = new QGroupBox( tr( "Depth Units" ) ); gDTypeBox = new QGroupBox( tr( "Data Domain" ) ); gDScaleBox = new QGroupBox( tr( "Magnitude Units" ) ); QHBoxLayout* layoutOffset = new QHBoxLayout; QHBoxLayout* layoutRadio = new QHBoxLayout; QHBoxLayout* layoutType = new QHBoxLayout; QHBoxLayout* layoutScale = new QHBoxLayout; QVBoxLayout* layout = new QVBoxLayout; QHBoxLayout* layoutDepthScale = new QHBoxLayout; QButtonGroup* depth = new QButtonGroup; QButtonGroup* data = new QButtonGroup; QButtonGroup* scale = new QButtonGroup; // Time axes offset value. timeOffsetLabel = new QLabel( tr( "Time (us): " ) ); timeOffsetLine = new QLineEdit( "0" ); airOffsetLabel = new QLabel( tr( "Air (m): " ) ); airOffsetLine = new QLineEdit( "0" ); layoutOffset->addWidget( timeOffsetLabel ); layoutOffset->addWidget( timeOffsetLine ); layoutOffset->addWidget( airOffsetLabel ); layoutOffset->addWidget( airOffsetLine ); // Connect the two offset value QLineEdits connect( timeOffsetLine, SIGNAL( editingFinished() ), this, SLOT( changeTOffset() ) ); connect( airOffsetLine, SIGNAL( editingFinished() ), this, SLOT( changeAOffset() ) ); // Create the radio buttons. There are three groups of radio buttons. // Each group can have one button selected at a time. depthScale[0] = new QRadioButton( "Air Meters", gOptionsBox ); depthScale[1] = new QRadioButton( "Ice Meters", gOptionsBox ); depthScale[2] = new QRadioButton( "Time", gOptionsBox ); dataType[0] = new QRadioButton( "Raw Data", gOptionsBox ); dataType[1] = new QRadioButton( "Frequency Domain Data", gOptionsBox ); dataType[2] = new QRadioButton( "Pulse-Compressed Data", gOptionsBox ); dataScale[0] = new QRadioButton( "Linear Scale (Amplitude)", gOptionsBox ); dataScale[1] = new QRadioButton( "Log Scale (dB)", gOptionsBox ); // Add the buttons to their own group. depth->addButton( depthScale[0] ); depth->addButton( depthScale[1] ); depth->addButton( depthScale[2] ); data->addButton( dataType[0] ); data->addButton( dataType[1] ); data->addButton( dataType[2] ); scale->addButton( dataScale[0] ); scale->addButton( dataScale[1] ); // Set the default button to be selected. depthScale[0]->setChecked( true ); dataType[2]->setChecked( true ); dataScale[1]->setChecked( true ); //Add radio buttons to the layout of the GroupBox. layoutRadio->addWidget( depthScale[0] ); layoutRadio->addWidget( depthScale[1] ); layoutRadio->addWidget( depthScale[2] ); layoutType->addWidget( dataType[0] ); layoutType->addWidget( dataType[1] ); layoutType->addWidget( dataType[2] ); layoutScale->addWidget( dataScale[0] ); layoutScale->addWidget( dataScale[1] ); // Set the layout to be used. gOffsetBox->setLayout( layoutOffset ); gDepthBox->setLayout( layoutRadio ); gDTypeBox->setLayout( layoutType ); gDScaleBox->setLayout( layoutScale ); layoutDepthScale->addWidget( gDepthBox ); layoutDepthScale->addWidget( gDScaleBox ); layout->addWidget( gOffsetBox ); layout->addLayout( layoutDepthScale ); //layout->addWidget( gDepthBox ); layout->addWidget( gDTypeBox ); //layout->addWidget( gDScaleBox ); gOptionsBox->setLayout( layout ); } /* Function: createEchoOptions * Params In * N/A * Return * N/A * Purpose * Function creates the Echogram specific options for how * to display the pulse-compressed data from every channel * in the echogram. */ void QuickLook::createEchoOptions() { // Setup the box for the options. eOptionsBox = new QGroupBox( tr( "Echogram Options" ) ); QVBoxLayout* layout = new QVBoxLayout; QGridLayout* layoutCM = new QGridLayout; // Create the text boxes with default values and labels for the boxes. eColorMapLabels[0] = new QLabel( tr( "Color Map Min:" ) ); eColorMapLabels[1] = new QLabel( tr( "Color Map Max:" ) ); eColorMapLabels[2] = new QLabel( tr( "Step Interval:" ) ); eColorMapLines[0] = new QLineEdit( "0" ); eColorMapLines[1] = new QLineEdit( "200" ); eColorMapLines[2] = new QLineEdit( "60" ); // Add boxes and labels to the layout of the group. layoutCM->addWidget( eColorMapLabels[0], 0, 0 ); layoutCM->addWidget( eColorMapLines[0], 0, 1 ); layoutCM->addWidget( eColorMapLabels[1], 0, 2 ); layoutCM->addWidget( eColorMapLines[1], 0, 3 ); layoutCM->addWidget( eColorMapLabels[2], 0, 4 ); layoutCM->addWidget( eColorMapLines[2], 0, 5 ); // Add smaller layouts to the larger layout. layout->addLayout( layoutCM ); // Set the layout to be used. eOptionsBox->setLayout( layout ); } /* Function: createAScopeOptions * Params In * N/A * Return * N/A * Purpose * Function creates the A-Scope specific options of how to * display the data from each selected channel. */ void QuickLook::createAScopeOptions() { //GroupBox contains the radio buttons. aOptionsBox = new QGroupBox( tr( "Plot Options" ) ); QHBoxLayout* layout = new QHBoxLayout; //Create the radio buttons. (They are a part of the same group, so only one can be selected) radios[0] = new QRadioButton( "Sum of Channels (1 Line)", aOptionsBox ); radios[1] = new QRadioButton( "Plot Each Channel (Up to 8 Lines)", aOptionsBox ); radios[0]->setChecked( true ); //Add radio buttons to the layout of the GroupBox. layout->addWidget( radios[0] ); layout->addWidget( radios[1] ); aOptionsBox->setLayout( layout ); } /* Function: createChannelBox * Params In * N/A * Return * N/A * Purpose * Creates the channel check boxes for the user to select * the channels to display in the windows. */ void QuickLook::createChannelBox() { //Box to contain the channels. channelBox = new QGroupBox( tr( "Select Radar Channels To Use" ) ); QGridLayout* layout = new QGridLayout; //Create all CHANNELNUMBER channel check boxes. for( int i = 0; i < cNumber; ++i ) { int j = i + 1; QString temp = "Channel "; QString num; temp += num.setNum( j ); channels[i] = new QCheckBox( temp, channelBox ); } //Add channel check box i and i+4 to the same row, but different columns. //The channels are in two columns. int rows = ( cNumber/2 ); if( ( cNumber ) % 2 == 0 ) { for( int i = 0; i < rows; ++i ) { layout->addWidget( channels[i], i + 1, 0 ); layout->addWidget( channels[i+rows], i + 1, 1 ); } } else { for( int i = 0; i < rows; ++i ) { layout->addWidget( channels[i], i + 1, 0 ); layout->addWidget( channels[i+rows], i + 1, 1 ); } layout->addWidget( channels[ cNumber - 1 ], rows+1, 0 ); } //Set the layout as the box's layout, then reset the channel values. channelBox->setLayout( layout ); resetChannelVals(); for( int z = 0; z < cNumber; ++z ) { if( cMasks->chanMasked( z ) ) { channels[z]->setEnabled( false ); channels[z]->setChecked( false ); } } } /* Function: createMenu * Params In * N/A * Return * N/A * Purpose * Creates the menu bar at the top of the window. */ void QuickLook::createMenu() { menuBar = new QMenuBar; //Create a new menu (File) and a action (Exit) fileMenu = new QMenu( tr( "&File" ), this ); exitAction = fileMenu->addAction( tr( "E&xit" ) ); //Add menu to the menu bar. menuBar->addMenu( fileMenu ); //Connect an event for when the Exit action is triggered, the window closes. connect( exitAction, SIGNAL( triggered() ), this, SLOT( close() ) ); } /* Function: createButtons * Params In * N/A * Return * N/A * Purpose * Create the buttons to spawn new Echogram and A-Scope windows. */ void QuickLook::createButtons() { //Create the box to house the buttons. buttonBox = new QGroupBox( tr( "Quick-Look Commands" ) ); // Box for both sets of buttons. QGroupBox* recBox = new QGroupBox( tr( "Quick-Look Data Recording Commands" ) ); // Box for the recording buttons. QGroupBox* newBox = new QGroupBox( tr( "Create New Window" ) ); // Box for the new window buttons. QHBoxLayout* layoutNew = new QHBoxLayout; // Layout for the new window buttons. QHBoxLayout* layoutRec = new QHBoxLayout; // Layout for the recording buttons. QVBoxLayout* layout = new QVBoxLayout; //Create the Echogram and A-Scope buttons, then add connections for the event //when they are clicked. Clicking triggers the function create. buttons[0] = new QPushButton( tr( "Echogram" ) ); buttons[0]->setEnabled( false ); layoutNew->addWidget( buttons[0] ); connect( buttons[0], SIGNAL( clicked() ), this, SLOT( createEcho() ) ); buttons[1] = new QPushButton( tr( "Plots" ) ); buttons[1]->setEnabled( false ); layoutNew->addWidget( buttons[1] ); connect( buttons[1], SIGNAL( clicked() ), this, SLOT( createAScope() ) ); buttons[2] = new QPushButton( tr( "Reference Pulse" ) ); layoutNew->addWidget( buttons[2] ); connect( buttons[2], SIGNAL( clicked() ), this, SLOT( createRefPulse() ) ); // Create the data recording buttons, then add connections. recButtons[0] = new QPushButton( tr( "Recording Directory" ) ); recButtons[0]->setEnabled( true ); layoutRec->addWidget( recButtons[0] ); connect( recButtons[0], SIGNAL( clicked() ), this, SLOT( setRecDirectory() ) ); recButtons[1] = new QPushButton( tr( "Start Recording" ) ); recButtons[1]->setEnabled( true ); layoutRec->addWidget( recButtons[1] ); connect( recButtons[1], SIGNAL( clicked() ), this, SLOT( startRecording() ) ); recButtons[2] = new QPushButton( tr( "Stop Recording" ) ); recButtons[2]->setEnabled( false ); // Disable because no point to stopping recording if it hasn't started yet. layoutRec->addWidget( recButtons[2] ); connect( recButtons[2], SIGNAL( clicked() ), this, SLOT( stopRecording() ) ); refWaves = new QPushButton( tr( "Reference Waveforms" ) ); refWaves->setEnabled( true ); layoutRec->addWidget( refWaves ); connect( refWaves, SIGNAL( clicked() ), this, SLOT( refWavesSelect() ) ); //Add the layout to the box layout. newBox->setLayout( layoutNew ); recBox->setLayout( layoutRec ); // Add the boxes to the main layout. layout->addWidget( recBox ); layout->addWidget( newBox ); // Add the main layout to the main box. buttonBox->setLayout( layout ); } /* Function: createEcho * Params In * N/A * Return * N/A * Purpose * Create a new Echogram window. Set the channels to be used, then create * the window if at least one channel is checked. */ void QuickLook::createEcho() { //Mark which channels are selected. //Make sure at least one channel is selected. if( checkChannelVals() ) { //Create a new Echogram window with the data container, //resize the window, show it, and put into the list of opened windows. Echogram* temp = new Echogram( createPlotOptionsStruct(), cNumber, this, uavData ); temp->resize( 400, 400 ); temp->show(); echoWidgets.push_back( temp ); } //No channel checked, can't create window. else { QErrorMessage* msgD = new QErrorMessage( this ); msgD->showMessage( "No channel is checked. Cannot create a window with no channels." ); } } /* Function: createAScope * Params In * N/A * Return * N/A * Purpose * Create a new A-Scope window. Check which channels are checked, then * apply the selected display option to the channels. Show the resulting window. */ void QuickLook::createAScope() { //Mark which channels are selected. //Make sure that at least one channel has been checked. if( checkChannelVals() ) { //Create a new A-Scope window with the data container, //resize the window, show it, and put into the list of opened windows. AScope* temp = new AScope( createPlotOptionsStruct(), this, uavData ); temp->resize( 400, 400 ); temp->show(); aScopeWidgets.push_back( temp ); } //No channel is checked, can't create window. else { QErrorMessage* msgD = new QErrorMessage( this ); msgD->showMessage( "No channel is checked. Cannot create a window with no channels." ); } } /* Function: createRefPulse * Params In * N/A * Return * N/A * Purpose * Create a new Reference Pulse window. Size it to 400x400 and show window. */ void QuickLook::createRefPulse() { //Make sure that at least one channel has been checked. if( checkChannelVals() ) { // Create a new Reference Waveform window. RefPulse* temp = new RefPulse( createPlotOptionsStruct(), this, uavData ); temp->resize( 400, 400 ); temp->show(); refPulseWidgets.push_back( temp ); } //No channel is checked, can't create window. else { QErrorMessage* msgD = new QErrorMessage( this ); msgD->showMessage( "No channel is checked. Cannot create a window with no channels." ); } } /* Function: deleteEWindow * Params In * QObject* window: Pointer to the window to be deleted. * Return * N/A * Purpose * Checks the vector of opened Echogram windows against the pointer of * the window to be deleted. When found in the vector, the spot is erased, * removing the pointer from the vector. */ void QuickLook::deleteEWindow( QObject* window ) { //Search the vector for the Echogram window that was just closed. for( unsigned int i = 0; i < echoWidgets.size(); ++i ) { if( echoWidgets[i] == window ) { //Found the correct window, so erase from the vector and break out of the loop. //Only one window would ever be found, so break. echoWidgets.erase( echoWidgets.begin() + i ); delete window; window = NULL; break; } } } /* Function: deleteAWindow * Params In * QObject* window: Pointer to the window to be deleted. * Return * N/A * Purpose * Checks the vector of opened A-Scope windows against the pointer of * the window to be deleted. When found in the vector, the spot is erased, * removing the pointer from the vector. */ void QuickLook::deleteAWindow( QObject* window ) { //Search the vector for the A-Scope window that was just closed. for( unsigned int i = 0; i < aScopeWidgets.size(); ++i ) { if( aScopeWidgets[i] == window ) { //Found the correct window, so erase from the vector and break out of the loop. //Only one window would ever be found, so break. aScopeWidgets.erase( aScopeWidgets.begin() + i ); delete window; window = NULL; break; } } } /* Function: deleteRWindow * Params In * QObject* window: Pointer to the window to be deleted. * Return * N/A * Purpose * Checks the vector of opened Reference Pulse windows against the pointer of * the window to be deleted. When found in the vector, the spot is erased, * removing the pointer from the vector. */ void QuickLook::deleteRWindow( QObject* window ) { //Search the vector for the Reference Pulse window that was just closed. for( unsigned int i = 0; i < refPulseWidgets.size(); ++i ) { if( refPulseWidgets[i] == window ) { //Found the correct window, so erase from the vector and break out of the loop. //Only one window would ever be found, so break. refPulseWidgets.erase( refPulseWidgets.begin() + i ); delete window; window = NULL; break; } } } /* Function: timerEvent * Params In * QTimerEvent* event: Pointer to the timer event. * Return * N/A * Purpose * Redeclaration of the default timerEvent. There should be a timer event * every x milliseconds. Call updateData() to get new data from the servers. */ void QuickLook::timerEvent() { processData->watch.start(); //When the timer goes off, refresh every open window with new data. updateData(); } /* Function: refreshWindows * Params In * N/A * Return * N/A * Purpose * Check every open Echogram or A-Scope window. If the window is not minimized, * redraw the window. This should display any new data that has been received * from the radar channels. */ void QuickLook::refreshWindows() { int begin = processData->watch.elapsed(); //Check every Echogram window. If the window is not minimized, then refresh it. for( unsigned int i = 0; i < echoWidgets.size(); ++i ) { if( !echoWidgets[i]->isMinimized() ) { echoWidgets[i]->redraw(); } } //Same as above for loop, but for the A-Scope windows. for( unsigned int j = 0; j < aScopeWidgets.size(); ++j ) { if( !aScopeWidgets[j]->isMinimized() ) { aScopeWidgets[j]->redraw(); } } int end = processData->watch.elapsed(); QString temp1, temp2; temp1.setNum( end-begin ); temp2.setNum( processData->watch.elapsed() ); //logViewer->appendPlainText( "Window Refresh: " + temp1 ); //logViewer->appendPlainText( "TotalRefresh: " + temp2 ); emit updateRefresh( temp2 ); } /* Function: updateData * Params In * N/A * Return * N/A * Purpose * Function is called when a timer event is emitted. Starts the process of getting * new data from each radar channel and storing it in the data container. Should * be called twice every second. */ void QuickLook::updateData() { //Get new data from the UAV vehicles and store into the data container. processData->refreshData(); } /* Function: checkChannelVals * Params In * N/A * Return * bool: Return the value of the variable checked. * Purpose * Returns the value of checked. If checked is true, then at least * one channel's check box has been checked and a new A-Scope window * can be created. */ bool QuickLook::checkChannelVals() { checked = false; for( int i = 0; i < uavData->getChanNum(); ++i ) { if( channels[i]->checkState() == Qt::Checked ) { checked = true; } } return checked; } /* Function: resetChannelVals * Params In * N/A * Return * N/A * Purpose * The function resets the bool array channelVals to the original values. By default, * channel 1 is checked, while the other channels are unchecked. channelVals is * used to determine whether a channel check box has been checked. */ void QuickLook::resetChannelVals() { //Reset all the channels to be checked. for( int i = 0; i < cNumber; ++i ) { channelVals[i] = true; channels[i]->setCheckState( Qt::Checked ); } //Since channel 1 is checked, set the checked flag to be true, //indicating to the program that at least one channel is checked. checked = true; } /* Function: copyPlotOptions * Params In * PlotOptions* p: Pointer to the structure of options to be modified. * Return * N/A * Purpose * Copies the values of the window options to the structure. Allows * for each window to have their own persistent options. */ void QuickLook::copyPlotOptions( PlotOptions* p ) { //Look at every channel check box. for( int i = 0; i < uavData->getChanNum(); ++i ) { //The box is checked, so the flag is true and the value is true. if( channels[i]->checkState() == Qt::Checked ) { p->channels[i] = true; } //Box is not checked. else { p->channels[i] = false; } } p->displayType = 0; //Option to sum the checked channels is true. if( radios[0]->isChecked() ) { p->displayType = 0; } //Option to show each channel as a separate line is true. else if( radios[1]->isChecked() ) { p->displayType = 1; } else if( radios[2]->isChecked() ) { p->displayType = 2; } // Set the time offset in the struct. p->timeOffset = tOffset; bool t1; bool t2; bool t3; int temp1 = eColorMapLines[0]->text().toInt( &t1 ); int temp2 = eColorMapLines[1]->text().toInt( &t2 ); int temp3 = eColorMapLines[2]->text().toInt( &t3 ); int tempDepthScale = 0; int tempDataScale = 0; int tempDataType = 0; // Check option boxes for selected value. if( depthScale[0]->isChecked() ) { tempDepthScale = 0; } else if( depthScale[1]->isChecked() ) { tempDepthScale = 1; } else if( depthScale[2]->isChecked() ) { tempDepthScale = 2; } if( dataType[0]->isChecked() ) { tempDataType = 0; } else if( dataType[1]->isChecked() ) { tempDataType = 1; } else if( dataType[2]->isChecked() ) { tempDataType = 2; } if( dataScale[0]->isChecked() ) { tempDataScale = 0; } else if( dataScale[1]->isChecked() ) { tempDataScale = 1; } // Make sure that the text was converted to a number without error. // If an error occured, the text value is not copied. if( t1 && t2 && t3 ) { p->setColorMap( temp1, temp2, temp3 ); p->depthType = tempDepthScale; p->dataType = tempDataType; p->dataScale = tempDataScale; } else { //std::cout << "Error converting Echogram options to ints. Values are not changed." << std::endl; //logViewer->appendPlainText( "Error converting Echogram options to ints. Values are not changed." ); emit writeMsg( "Error converting Echogram options to ints. Values are not changed.", NORMAL ); } // Update the user defined offsets. p->airOffset = aOffset; p->iceOffset = iOffset; p->timeOffset = tOffset; } /* Function: createPlotOptionsStruct * Params In * N/A * Return * PlotOptions * Purpose * Create a new PlotOptions struct, copy the current values into it, and * return the struct. Used when creating a new A-Scope or Echogram window. */ PlotOptions* QuickLook::createPlotOptionsStruct() { PlotOptions* p = new PlotOptions( uavData->getChanNum() );; // Copy the values to the struct. copyPlotOptions( p ); return p; } /* Function: updateWinOptions * Params In * PlotOptions* p; Pointer to the PlotOptions struct to modify. * Return * N/A * Purpose * Copies the current options selected into the structure. */ void QuickLook::updateWinOptions( PlotOptions* p ) { copyPlotOptions( p ); // Set the offset values to use. } /* Function: enableButtons * Params In * N/A * Return * N/A * Purpose * Enables the Echogram and Plot buttons as data has been received. Prevents seg faults. */ void QuickLook::enableButtons() { buttons[0]->setEnabled( true ); buttons[1]->setEnabled( true ); } /* Function: disableChannel * Params In * int c: Channel to disable. * Return * N/A * Purpose * Disables the specified channel from being able to be selected by the user. */ void QuickLook::disableChannel( int c ) { if( channels[c]->isEnabled() ) { channels[c]->setChecked( false ); channels[c]->setEnabled( false ); if( c < ( uavData->getChanNum() - 1 ) ) { if( channels[c+1]->isEnabled() ) { channels[c+1]->setChecked( true ); } } checkChannelVals(); } } void QuickLook::closeEvent( QCloseEvent* event ) { emit quickLookClosed(); event->accept(); } void QuickLook::setStatus( QString utc, uint32_t pps, uint32_t epri ) { emit updateStatus( utc, pps, epri ); } void QuickLook::writeToLog( QString t, int type ) { // Emit the signal with the message and type of log. emit writeMsg( t, type ); } void QuickLook::loadClasses( bool rec, ProcParams* pp ) { //Create a new data container to store all of the data //from the UAV channels. uavData = new MatrixData( rNumber, cNumber, this ); // Create the Load Reference Pulse window. refPulse = new LoadRefPulse( cNumber, pp, parCP, this ); refPulse->setGeometry( 200, 100, 700, 700 ); refPulse->hide(); //Object to get new data, process it, and store into the data container. processData = new DataProcessing( recPath, refPulse, cMasks, pp, uavData, this, rec ); //Run a timer that sounds every 0.5 seconds. timer = new QTimer( this ); connect( timer, SIGNAL( timeout() ), this, SLOT( timerEvent() ) ); timer->start( 500 ); } void QuickLook::setRecDirectory() { // Check if data is being recorded. if( recButtons[1]->isEnabled() ) { // Create the file dialog to find the file to save. QFileDialog fDialog( this, tr( "Set Recording Directory" ), recPath ); fDialog.setFileMode( QFileDialog::Directory ); fDialog.setOptions( QFileDialog::ShowDirsOnly ); fDialog.setAcceptMode( QFileDialog::AcceptOpen ); // If the user clicks OK on a file, enter the if statement. if( fDialog.exec() ) { // Get the absolute path to the file. QStringList pathList = fDialog.selectedFiles(); QString path = pathList[0]; //emit writeMsg( path, DEBUG ); recPath = path; processData->setRecordingPath( recPath ); } } else // Recording is on, so just show the path to the directory where the files are being written. { QMessageBox msgBox( this ); msgBox.setText( "Recording Path" ); msgBox.setInformativeText( "The current path to the Quick-Look recorded data files is: " + recPath + "." ); msgBox.setStandardButtons( QMessageBox::Ok ); msgBox.setDefaultButton( QMessageBox::Ok ); msgBox.exec(); } } void QuickLook::changeTOffset() { tOffset = timeOffsetLine->text().toDouble(); aOffset = convertAir( tOffset ); iOffset = convertIce( tOffset ); QString aVal; aVal.setNum( aOffset ); airOffsetLine->setText( aVal ); } void QuickLook::changeAOffset() { aOffset = airOffsetLine->text().toDouble(); tOffset = convertTime( aOffset ); iOffset = convertIce( tOffset ); QString tVal; tVal.setNum( tOffset ); timeOffsetLine->setText( tVal ); } void QuickLook::setOffset( double offset ) { // Set the hardcoded offset values in the MatrixData object. if( uavData ) { uavData->setRadarOffsetValues( convertAir( offset ), convertIce( offset ), offset ); } } double QuickLook::convertAir( double tVal ) { double microseconds = 1000000.0; QString val; val.setNum ( ( ( ( ( 300000000.0 ) * tVal ) / ( 2.0 ) / microseconds ) / 1000.0 ) ); val.prepend( "Air Meter Offset: " ); emit writeMsg( val, DEBUG ); return ( ( ( 300000000.0 ) * tVal ) / ( 2.0 ) ) / microseconds; } double QuickLook::convertIce( double tVal ) { double microseconds = 1000000.0; return ( ( ( 300000000.0 ) * tVal ) / ( sqrt( 3.15 ) * 2.0 ) ) / microseconds; } double QuickLook::convertTime( double aVal ) { double microseconds = 1000000.0; return ( 2.0 * microseconds * aVal ) / 300000000.0; } void QuickLook::startRecording() { // Enable the stop recording button and disable start recording. recButtons[1]->setEnabled( false ); recButtons[2]->setEnabled( true ); // Tell the data processing object to record the data. processData->startRec(); // Emit a signal to turn the Recording LED green. emit updateLED( Qt::green, 2 ); } void QuickLook::stopRecording() { // Disable the stop recording button and enable start recording. recButtons[1]->setEnabled( true ); recButtons[2]->setEnabled( false ); // Tell the data processing object to stop recording the data. processData->stopRec(); // Emit a signal to turn the Recording LED green. emit updateLED( Qt::red, 2 ); } void QuickLook::closeQL() { emit quickLookClosed(); } void QuickLook::setNewTau( double t ) { uavData->setTau( t ); } void QuickLook::refWavesSelect() { refPulse->show(); } void QuickLook::setWaveChange() { processData->changeRefWaves(); }