Cleaning up Qt code. This mostly reformats the code to be more consistent with our...
[debian/gnuradio] / gr-qtgui / src / lib / spectrumdisplayform.cc
1 #include <cmath>
2 #include <QColorDialog>
3 #include <QMessageBox>
4 #include <spectrumdisplayform.h>
5
6 int SpectrumDisplayForm::_openGLWaterfall3DFlag = -1;
7
8 SpectrumDisplayForm::SpectrumDisplayForm(bool useOpenGL, QWidget* parent)
9   : QWidget(parent)
10 {
11   setupUi(this);
12
13   _useOpenGL = useOpenGL;
14   _systemSpecifiedFlag = false;
15   _intValidator = new QIntValidator(this);
16   _intValidator->setBottom(0);
17   _frequencyDisplayPlot = new FrequencyDisplayPlot(FrequencyPlotDisplayFrame);
18   _waterfallDisplayPlot = new WaterfallDisplayPlot(WaterfallPlotDisplayFrame\0);
19
20   if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
21     _waterfall3DDisplayPlot = new Waterfall3DDisplayPlot(Waterfall3DPlotDisplayFrame);
22   }
23
24   _timeDomainDisplayPlot = new TimeDomainDisplayPlot(TimeDomainDisplayFrame);
25   _constellationDisplayPlot = new ConstellationDisplayPlot(ConstellationDisplayFrame);
26   _numRealDataPoints = 1024;
27   _realFFTDataPoints = new double[_numRealDataPoints];
28   _averagedValues = new double[_numRealDataPoints];
29   _historyVector = new std::vector<double*>;
30   
31   AvgLineEdit->setRange(0, 500);                 // Set range of Average box value from 0 to 500
32   PowerLineEdit->setValidator(_intValidator);    // Tell GUI this can only be an integer value
33   MinHoldCheckBox_toggled( false );
34   MaxHoldCheckBox_toggled( false );
35   
36   WaterfallMaximumIntensityWheel->setRange(-200, 0);
37   WaterfallMaximumIntensityWheel->setTickCnt(50);
38   WaterfallMinimumIntensityWheel->setRange(-200, 0);
39   WaterfallMinimumIntensityWheel->setTickCnt(50);
40   WaterfallMinimumIntensityWheel->setValue(-200);
41   
42   if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
43     Waterfall3DMaximumIntensityWheel->setRange(-200, 0);
44     Waterfall3DMaximumIntensityWheel->setTickCnt(50);
45     Waterfall3DMinimumIntensityWheel->setRange(-200, 0);
46     Waterfall3DMinimumIntensityWheel->setTickCnt(50);
47     Waterfall3DMinimumIntensityWheel->setValue(-200);
48   }
49
50   _peakFrequency = 0;
51   _peakAmplitude = -HUGE_VAL;
52   
53   _noiseFloorAmplitude = -HUGE_VAL;
54
55   connect(_waterfallDisplayPlot, SIGNAL(UpdatedLowerIntensityLevel(const double)), 
56           _frequencyDisplayPlot, SLOT(SetLowerIntensityLevel(const double)));
57   connect(_waterfallDisplayPlot, SIGNAL(UpdatedUpperIntensityLevel(const double)), 
58           _frequencyDisplayPlot, SLOT(SetUpperIntensityLevel(const double)));
59   
60   _frequencyDisplayPlot->SetLowerIntensityLevel(-200);
61   _frequencyDisplayPlot->SetUpperIntensityLevel(-200);
62
63   // Load up the acceptable FFT sizes...
64   FFTSizeComboBox->clear();
65   for(long fftSize = SpectrumGUIClass::MIN_FFT_SIZE; fftSize <= SpectrumGUIClass::MAX_FFT_SIZE; fftSize *= 2){
66     FFTSizeComboBox->insertItem(FFTSizeComboBox->count(), QString("%1").arg(fftSize));
67   }
68   Reset();
69
70   ToggleTabFrequency(false);
71   ToggleTabWaterfall(false);
72   ToggleTabWaterfall3D(false);
73   ToggleTabTime(false);
74   ToggleTabConstellation(false);
75 }
76
77 SpectrumDisplayForm::~SpectrumDisplayForm()
78 {
79   // Qt deletes children when parent is deleted
80
81   // Don't worry about deleting Display Plots - they are deleted when parents are deleted
82   /*   delete _intValidator; */
83
84   delete[] _realFFTDataPoints;
85   delete[] _averagedValues;
86
87   for(unsigned int count = 0; count < _historyVector->size(); count++){
88     delete[] _historyVector->operator[](count);
89   }
90
91   delete _historyVector;
92 }
93
94 void
95 SpectrumDisplayForm::setSystem( SpectrumGUIClass * newSystem, 
96                                 const uint64_t numFFTDataPoints, 
97                                 const uint64_t numTimeDomainDataPoints )
98 {
99   ResizeBuffers(numFFTDataPoints, numTimeDomainDataPoints);
100   
101   if(newSystem != NULL){
102     _system = newSystem;
103     _systemSpecifiedFlag = true;
104   }
105   else{
106     _systemSpecifiedFlag = false;
107   }
108 }
109
110 void
111 SpectrumDisplayForm::newFrequencyData( const SpectrumUpdateEvent* spectrumUpdateEvent)
112 {
113   //printf("Parent Width: %d  Height: %d\n", width(), height());
114   //printf("Frequency Frame Width: %d  Height: %d\n", FrequencyPlotDisplayFrame->width(), FrequencyPlotDisplayFrame->height());
115   //printf("Frequency Plot Width: %d  Height: %d\n", _frequencyDisplayPlot->width(), _frequencyDisplayPlot->height());
116
117
118   //_lastSpectrumEvent = (SpectrumUpdateEvent)(*spectrumUpdateEvent);
119   const std::complex<float>* complexDataPoints = spectrumUpdateEvent->getFFTPoints();
120   const uint64_t numFFTDataPoints = spectrumUpdateEvent->getNumFFTDataPoints();
121   const double* realTimeDomainDataPoints = spectrumUpdateEvent->getRealTimeDomainPoints();
122   const double* imagTimeDomainDataPoints = spectrumUpdateEvent->getImagTimeDomainPoints();
123   const uint64_t numTimeDomainDataPoints = spectrumUpdateEvent->getNumTimeDomainDataPoints();
124   const double timePerFFT = spectrumUpdateEvent->getTimePerFFT();
125   const timespec dataTimestamp = spectrumUpdateEvent->getDataTimestamp();;
126   const bool repeatDataFlag = spectrumUpdateEvent->getRepeatDataFlag();
127   const bool lastOfMultipleUpdatesFlag = spectrumUpdateEvent->getLastOfMultipleUpdateFlag();
128   const timespec generatedTimestamp = spectrumUpdateEvent->getEventGeneratedTimestamp();
129
130   // REMEMBER: The dataTimestamp is NOT valid when the repeat data flag is true...
131   ResizeBuffers(numFFTDataPoints, numTimeDomainDataPoints);
132
133   // Calculate the Magnitude of the complex point
134   const std::complex<float>* complexDataPointsPtr = complexDataPoints+numFFTDataPoints/2;
135   double* realFFTDataPointsPtr = _realFFTDataPoints;
136
137   // Run this twice to perform the fftshift operation on the data here as well
138   for(uint64_t point = 0; point < numFFTDataPoints/2; point++){
139     // Calculate dBm
140     // 50 ohm load assumption
141     // 10 * log10 (v^2 / (2 * 50.0 * .001)) = 10 * log10( v^2 * 10)
142     // 75 ohm load assumption
143     // 10 * log10 (v^2 / (2 * 75.0 * .001)) = 10 * log10( v^2 * 15)
144
145     // perform scaling here
146     std::complex<float> pt = (*complexDataPointsPtr) / std::complex<float>((float)numFFTDataPoints);
147     *realFFTDataPointsPtr = 10.0*log10((pt.real() * pt.real() + pt.imag()*pt.imag()) + 1e-20);
148
149     complexDataPointsPtr++;
150     realFFTDataPointsPtr++;
151   }
152   
153   // This loop takes the first half of the input data and puts it in the second half of the plotted data
154   complexDataPointsPtr = complexDataPoints;
155   for(uint64_t point = 0; point < numFFTDataPoints/2; point++){
156     std::complex<float> pt = (*complexDataPointsPtr) / std::complex<float>((float)numFFTDataPoints);
157     *realFFTDataPointsPtr = 10.0*log10((pt.real() * pt.real() + pt.imag()*pt.imag()) + 1e-20);
158
159     complexDataPointsPtr++;
160     realFFTDataPointsPtr++;
161   }
162
163   // Don't update the averaging history if this is repeated data
164   if(!repeatDataFlag){
165     _AverageHistory(_realFFTDataPoints);
166
167     double sumMean;
168     const double fft_bin_size = (_stopFrequency-_startFrequency) /
169       static_cast<double>(numFFTDataPoints);
170
171     // find the peak, sum (for mean), etc
172     _peakAmplitude = -HUGE_VAL;
173     sumMean = 0.0;
174     for(uint64_t number = 0; number < numFFTDataPoints; number++){
175       // find peak
176       if(_realFFTDataPoints[number] > _peakAmplitude){
177         // Calculate the frequency relative to the local bw, adjust for _startFrequency later
178         _peakFrequency = (static_cast<float>(number) * fft_bin_size);
179         _peakAmplitude = _realFFTDataPoints[number];
180         // _peakBin = number;
181       }
182       // sum (for mean)
183       sumMean += _realFFTDataPoints[number];
184     }
185
186     // calculate the spectral mean
187     // +20 because for the comparison below we only want to throw out bins
188     // that are significantly higher (and would, thus, affect the mean more)
189     const double meanAmplitude = (sumMean / numFFTDataPoints) + 20.0;
190
191     // now throw out any bins higher than the mean
192     sumMean = 0.0;
193     uint64_t newNumDataPoints = numFFTDataPoints;
194     for(uint64_t number = 0; number < numFFTDataPoints; number++){
195       if (_realFFTDataPoints[number] <= meanAmplitude)
196         sumMean += _realFFTDataPoints[number];
197       else
198         newNumDataPoints--;
199     }
200
201     if (newNumDataPoints == 0)             // in the odd case that all
202       _noiseFloorAmplitude = meanAmplitude; // amplitudes are equal!
203     else
204       _noiseFloorAmplitude = sumMean / newNumDataPoints;
205   }
206
207   if(lastOfMultipleUpdatesFlag){
208     int tabindex = SpectrumTypeTab->currentIndex();
209     if(tabindex == d_plot_fft) {
210       _frequencyDisplayPlot->PlotNewData(_averagedValues, numFFTDataPoints, 
211                                          _noiseFloorAmplitude, _peakFrequency, 
212                                          _peakAmplitude);
213     }
214     if(tabindex == d_plot_time) {
215       _timeDomainDisplayPlot->PlotNewData(realTimeDomainDataPoints, 
216                                           imagTimeDomainDataPoints, 
217                                           numTimeDomainDataPoints);
218     }
219     if(tabindex == d_plot_constellation) {
220       _constellationDisplayPlot->PlotNewData(realTimeDomainDataPoints, 
221                                              imagTimeDomainDataPoints, 
222                                              numTimeDomainDataPoints);
223     }
224
225     // Don't update the repeated data for the waterfall
226     if(!repeatDataFlag){
227       if(tabindex == d_plot_waterfall) {
228         _waterfallDisplayPlot->PlotNewData(_realFFTDataPoints, numFFTDataPoints, 
229                                            timePerFFT, dataTimestamp, 
230                                            spectrumUpdateEvent->getDroppedFFTFrames());
231       }
232       if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
233         if( _openGLWaterfall3DFlag == 1 && (tabindex == d_plot_waterfall3d)) {
234           _waterfall3DDisplayPlot->PlotNewData(_realFFTDataPoints, numFFTDataPoints, 
235                                                timePerFFT, dataTimestamp, 
236                                                spectrumUpdateEvent->getDroppedFFTFrames());
237         }
238       }
239     }
240
241     
242     // Tell the system the GUI has been updated
243     if(_systemSpecifiedFlag){
244       _system->SetLastGUIUpdateTime(generatedTimestamp);
245       _system->DecrementPendingGUIUpdateEvents();
246     }
247   }
248 }
249
250 void
251 SpectrumDisplayForm::resizeEvent( QResizeEvent *e )
252 {
253   QSize s;
254   s.setWidth(FrequencyPlotDisplayFrame->width());
255   s.setHeight(FrequencyPlotDisplayFrame->height());
256   emit _frequencyDisplayPlot->resizeSlot(&s);
257
258   s.setWidth(TimeDomainDisplayFrame->width());
259   s.setHeight(TimeDomainDisplayFrame->height());
260   emit _timeDomainDisplayPlot->resizeSlot(&s);
261
262   s.setWidth(WaterfallPlotDisplayFrame->width());
263   s.setHeight(WaterfallPlotDisplayFrame->height());
264   emit _waterfallDisplayPlot->resizeSlot(&s);
265
266   if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
267     s.setWidth(Waterfall3DPlotDisplayFrame->width());
268     s.setHeight(Waterfall3DPlotDisplayFrame->height());
269     emit _waterfall3DDisplayPlot->resizeSlot(&s);
270   }
271
272   s.setWidth(ConstellationDisplayFrame->width());
273   s.setHeight(ConstellationDisplayFrame->height());
274   emit _constellationDisplayPlot->resizeSlot(&s);
275 }
276
277 void
278 SpectrumDisplayForm::customEvent( QEvent * e)
279 {
280   if(e->type() == QEvent::User+3){
281     if(_systemSpecifiedFlag){
282       WindowComboBox->setCurrentIndex(_system->GetWindowType());
283       FFTSizeComboBox->setCurrentIndex(_system->GetFFTSizeIndex());
284       //FFTSizeComboBox->setCurrentIndex(1);
285       PowerLineEdit_textChanged(PowerLineEdit->text());
286     }
287
288     waterfallMinimumIntensityChangedCB(WaterfallMinimumIntensityWheel->value());
289     waterfallMaximumIntensityChangedCB(WaterfallMaximumIntensityWheel->value());
290
291     // If the video card doesn't support OpenGL then don't display the 3D Waterfall
292     if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
293       waterfall3DMinimumIntensityChangedCB(Waterfall3DMinimumIntensityWheel->value());
294       waterfall3DMaximumIntensityChangedCB(Waterfall3DMaximumIntensityWheel->value());
295       
296       // Check for Hardware Acceleration of the OpenGL
297       if(!_waterfall3DDisplayPlot->format().directRendering()){
298         // Only ask this once while the program is running...
299         if(_openGLWaterfall3DFlag == -1){
300           _openGLWaterfall3DFlag = 0;
301           if(QMessageBox::warning(this, "OpenGL Direct Rendering NOT Supported", "<center>The system's video card hardware or current drivers do not support direct hardware rendering of the OpenGL modules.</center><br><center>Software rendering is VERY processor intensive.</center><br><center>Do you want to use software rendering?</center>", QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape) == QMessageBox::Yes){
302             _openGLWaterfall3DFlag = 1;
303           }
304         }
305       }
306       else{
307         _openGLWaterfall3DFlag = 1;
308       }
309     }
310     
311     if(_openGLWaterfall3DFlag != 1){
312       ToggleTabWaterfall3D(false);
313     }
314
315     // Clear any previous display
316     Reset();
317   }
318   else if(e->type() == 10005){
319     SpectrumUpdateEvent* spectrumUpdateEvent = (SpectrumUpdateEvent*)e;
320     newFrequencyData(spectrumUpdateEvent);
321   }
322   else if(e->type() == 10008){
323     setWindowTitle(((SpectrumWindowCaptionEvent*)e)->getLabel());
324   }
325   else if(e->type() == 10009){
326     Reset();
327     if(_systemSpecifiedFlag){
328       _system->ResetPendingGUIUpdateEvents();
329     }
330   }
331   else if(e->type() == 10010){
332     _startFrequency = ((SpectrumFrequencyRangeEvent*)e)->GetStartFrequency();
333     _stopFrequency = ((SpectrumFrequencyRangeEvent*)e)->GetStopFrequency();
334     _centerFrequency  = ((SpectrumFrequencyRangeEvent*)e)->GetCenterFrequency();
335
336     UseRFFrequenciesCB(UseRFFrequenciesCheckBox->isChecked());
337   }
338 }
339
340 void
341 SpectrumDisplayForm::AvgLineEdit_valueChanged( int value )
342 {
343   SetAverageCount(value);
344 }
345
346
347 void
348 SpectrumDisplayForm::MaxHoldCheckBox_toggled( bool newState )
349 {
350   MaxHoldResetBtn->setEnabled(newState);
351   _frequencyDisplayPlot->SetMaxFFTVisible(newState);
352   MaxHoldResetBtn_clicked();
353 }
354
355
356 void
357 SpectrumDisplayForm::MinHoldCheckBox_toggled( bool newState )
358 {
359   MinHoldResetBtn->setEnabled(newState);
360   _frequencyDisplayPlot->SetMinFFTVisible(newState);
361   MinHoldResetBtn_clicked();
362 }
363
364
365 void
366 SpectrumDisplayForm::MinHoldResetBtn_clicked()
367 {
368   _frequencyDisplayPlot->ClearMinData();
369   _frequencyDisplayPlot->replot();
370 }
371
372
373 void
374 SpectrumDisplayForm::MaxHoldResetBtn_clicked()
375 {
376   _frequencyDisplayPlot->ClearMaxData();
377   _frequencyDisplayPlot->replot();
378 }
379
380
381 void
382 SpectrumDisplayForm::TabChanged(int index)
383 {
384   // This might be dangerous to call this with NULL
385   resizeEvent(NULL);  
386 }
387
388 void
389 SpectrumDisplayForm::PowerLineEdit_textChanged( const QString &valueString )
390 {
391   if(_systemSpecifiedFlag){
392     if(!valueString.isEmpty()){
393       double value = valueString.toDouble();
394       if(value < 1.0){
395         value = 1.0;
396         PowerLineEdit->setText("1");
397       }
398       _system->SetPowerValue(value);
399     }
400
401     if(_system->GetPowerValue() > 1){
402       UseRFFrequenciesCheckBox->setChecked(false);
403       UseRFFrequenciesCheckBox->setEnabled(false);
404       UseRFFrequenciesCB(false);
405     }
406     else{
407       UseRFFrequenciesCheckBox->setEnabled(true);
408     }
409   }
410 }
411
412 void
413 SpectrumDisplayForm::SetFrequencyRange(const double newCenterFrequency,
414                                        const double newStartFrequency, 
415                                        const double newStopFrequency)
416 {
417   double fdiff;
418   if(UseRFFrequenciesCheckBox->isChecked()) {
419     fdiff = newCenterFrequency;
420   }
421   else {
422     fdiff = std::max(fabs(newStartFrequency), fabs(newStopFrequency));
423   }
424
425   if(fdiff > 0) {
426     std::string strunits[4] = {"Hz", "kHz", "MHz", "GHz"};
427     double units10 = floor(log10(fdiff));
428     double units3  = std::max(floor(units10 / 3.0), 0.0);
429     double units = pow(10, (units10-fmod(units10, 3.0)));
430     int iunit = static_cast<int>(units3);
431     
432     _startFrequency = newStartFrequency;
433     _stopFrequency = newStopFrequency;
434     _centerFrequency = newCenterFrequency;
435
436     _frequencyDisplayPlot->SetFrequencyRange(newStartFrequency,
437                                              newStopFrequency,
438                                              newCenterFrequency,
439                                              UseRFFrequenciesCheckBox->isChecked(),
440                                              units, strunits[iunit]);
441     _waterfallDisplayPlot->SetFrequencyRange(newStartFrequency,
442                                              newStopFrequency,
443                                              newCenterFrequency,
444                                              UseRFFrequenciesCheckBox->isChecked(),
445                                              units, strunits[iunit]);
446     if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
447       _waterfall3DDisplayPlot->SetFrequencyRange(newStartFrequency,
448                                                  newStopFrequency,
449                                                  newCenterFrequency,
450                                                  UseRFFrequenciesCheckBox->isChecked(),
451                                                  units, strunits[iunit]);
452     }
453   }
454 }
455
456 int
457 SpectrumDisplayForm::GetAverageCount()
458 {
459   return _historyVector->size();
460 }
461
462 void
463 SpectrumDisplayForm::SetAverageCount(const int newCount)
464 {
465   if(newCount > -1){
466     if(newCount != static_cast<int>(_historyVector->size())){
467       std::vector<double*>::iterator pos;
468       while(newCount < static_cast<int>(_historyVector->size())){
469         pos = _historyVector->begin();
470         delete[] (*pos);
471         _historyVector->erase(pos);
472       }
473
474       while(newCount > static_cast<int>(_historyVector->size())){
475         _historyVector->push_back(new double[_numRealDataPoints]);
476       }
477       AverageDataReset();
478     }
479   }
480 }
481
482 void
483 SpectrumDisplayForm::_AverageHistory(const double* newBuffer)
484 {
485   if(_numRealDataPoints > 0){
486     if(_historyVector->size() > 0){
487       memcpy(_historyVector->operator[](_historyEntry), newBuffer,
488              _numRealDataPoints*sizeof(double));
489
490       // Increment the next location to store data
491       _historyEntryCount++;
492       if(_historyEntryCount > static_cast<int>(_historyVector->size())){
493         _historyEntryCount = _historyVector->size();
494       }
495       _historyEntry = (++_historyEntry)%_historyVector->size();
496
497       // Total up and then average the values
498       double sum;
499       for(uint64_t location = 0; location < _numRealDataPoints; location++){
500         sum = 0;
501         for(int number = 0; number < _historyEntryCount; number++){
502           sum += _historyVector->operator[](number)[location];
503         }
504         _averagedValues[location] = sum/static_cast<double>(_historyEntryCount);
505       }
506     }
507     else{
508       memcpy(_averagedValues, newBuffer, _numRealDataPoints*sizeof(double));
509     }
510   }
511 }
512
513 void
514 SpectrumDisplayForm::ResizeBuffers( const uint64_t numFFTDataPoints,
515                                     const uint64_t /*numTimeDomainDataPoints*/ )
516 {
517   // Convert from Complex to Real for certain Displays
518   if(_numRealDataPoints != numFFTDataPoints){
519     _numRealDataPoints = numFFTDataPoints;
520     delete[] _realFFTDataPoints;
521     delete[] _averagedValues;
522     
523     _realFFTDataPoints = new double[_numRealDataPoints];
524     _averagedValues = new double[_numRealDataPoints];
525     memset(_realFFTDataPoints, 0x0, _numRealDataPoints*sizeof(double));
526     
527     const int historySize = _historyVector->size();
528     SetAverageCount(0); // Clear the existing history
529     SetAverageCount(historySize);
530     
531     Reset();
532   }
533 }
534
535 void
536 SpectrumDisplayForm::Reset()
537 {
538   AverageDataReset();
539
540   _waterfallDisplayPlot->Reset();
541   if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
542     _waterfall3DDisplayPlot->Reset();
543   }
544 }
545
546
547 void
548 SpectrumDisplayForm::AverageDataReset()
549 {
550   _historyEntry = 0;
551   _historyEntryCount = 0;
552
553   memset(_averagedValues, 0x0, _numRealDataPoints*sizeof(double));
554
555   MaxHoldResetBtn_clicked();
556   MinHoldResetBtn_clicked();
557 }
558
559
560 void
561 SpectrumDisplayForm::closeEvent( QCloseEvent *e )
562 {
563   if(_systemSpecifiedFlag){
564     _system->SetWindowOpenFlag(false);
565   }
566
567   qApp->processEvents();
568
569   QWidget::closeEvent(e);
570 }
571
572
573 void
574 SpectrumDisplayForm::WindowTypeChanged( int newItem )
575 {
576   if(_systemSpecifiedFlag){
577    _system->SetWindowType(newItem);
578   }
579 }
580
581
582 void
583 SpectrumDisplayForm::UseRFFrequenciesCB( bool useRFFlag )
584 {
585   SetFrequencyRange(_centerFrequency, _startFrequency, _stopFrequency);
586 }
587
588
589 void
590 SpectrumDisplayForm::waterfallMaximumIntensityChangedCB( double newValue )
591 {
592   if(newValue > WaterfallMinimumIntensityWheel->value()){
593     WaterfallMaximumIntensityLabel->setText(QString("%1 dB").arg(newValue, 0, 'f', 0));
594   }
595   else{
596     WaterfallMaximumIntensityWheel->setValue(WaterfallMinimumIntensityWheel->value());
597   }
598
599   _waterfallDisplayPlot->SetIntensityRange(WaterfallMinimumIntensityWheel->value(),
600                                            WaterfallMaximumIntensityWheel->value());
601 }
602
603
604 void
605 SpectrumDisplayForm::waterfallMinimumIntensityChangedCB( double newValue )
606 {
607   if(newValue < WaterfallMaximumIntensityWheel->value()){
608     WaterfallMinimumIntensityLabel->setText(QString("%1 dB").arg(newValue, 0, 'f', 0));
609   }
610   else{
611     WaterfallMinimumIntensityWheel->setValue(WaterfallMaximumIntensityWheel->value());
612   }
613
614   _waterfallDisplayPlot->SetIntensityRange(WaterfallMinimumIntensityWheel->value(),
615                                            WaterfallMaximumIntensityWheel->value());
616 }
617
618 void
619 SpectrumDisplayForm::waterfall3DMaximumIntensityChangedCB( double newValue )
620 {
621   if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
622     if(newValue > Waterfall3DMinimumIntensityWheel->value()){
623       Waterfall3DMaximumIntensityLabel->setText(QString("%1 dB").arg(newValue, 0, 'f', 0));
624     }
625     else{
626       Waterfall3DMaximumIntensityWheel->setValue(Waterfall3DMinimumIntensityWheel->value());
627     }
628     
629     _waterfall3DDisplayPlot->SetIntensityRange(Waterfall3DMinimumIntensityWheel->value(),
630                                                Waterfall3DMaximumIntensityWheel->value());
631   }
632 }
633
634
635 void
636 SpectrumDisplayForm::waterfall3DMinimumIntensityChangedCB( double newValue )
637 {
638   if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
639     if(newValue < Waterfall3DMaximumIntensityWheel->value()){
640       Waterfall3DMinimumIntensityLabel->setText(QString("%1 dB").arg(newValue, 0, 'f', 0));
641     }
642     else{
643       Waterfall3DMinimumIntensityWheel->setValue(Waterfall3DMaximumIntensityWheel->value());
644     }
645     
646     _waterfall3DDisplayPlot->SetIntensityRange(Waterfall3DMinimumIntensityWheel->value(),
647                                                Waterfall3DMaximumIntensityWheel->value());
648   }
649 }
650
651
652 void
653 SpectrumDisplayForm::FFTComboBoxSelectedCB( const QString &fftSizeString )
654 {
655   if(_systemSpecifiedFlag){
656     _system->SetFFTSize(fftSizeString.toLong());
657   }
658 }
659
660
661 void
662 SpectrumDisplayForm::WaterfallAutoScaleBtnCB()
663 {
664   double minimumIntensity = _noiseFloorAmplitude - 5;
665   if(minimumIntensity < WaterfallMinimumIntensityWheel->minValue()){
666     minimumIntensity = WaterfallMinimumIntensityWheel->minValue();
667   }
668   WaterfallMinimumIntensityWheel->setValue(minimumIntensity);
669   double maximumIntensity = _peakAmplitude + 10;
670   if(maximumIntensity > WaterfallMaximumIntensityWheel->maxValue()){
671     maximumIntensity = WaterfallMaximumIntensityWheel->maxValue();
672   }
673   WaterfallMaximumIntensityWheel->setValue(maximumIntensity);
674   waterfallMaximumIntensityChangedCB(maximumIntensity);
675 }
676
677 void
678 SpectrumDisplayForm::Waterfall3DAutoScaleBtnCB()
679 {
680   if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
681     double minimumIntensity = _noiseFloorAmplitude - 5;
682     if(minimumIntensity < Waterfall3DMinimumIntensityWheel->minValue()){
683       minimumIntensity = Waterfall3DMinimumIntensityWheel->minValue();
684     }
685     Waterfall3DMinimumIntensityWheel->setValue(minimumIntensity);
686     double maximumIntensity = _peakAmplitude + 10;
687     if(maximumIntensity > Waterfall3DMaximumIntensityWheel->maxValue()){
688       maximumIntensity = Waterfall3DMaximumIntensityWheel->maxValue();
689     }
690     Waterfall3DMaximumIntensityWheel->setValue(maximumIntensity);
691     waterfallMaximumIntensityChangedCB(maximumIntensity);
692   }
693 }
694
695 void
696 SpectrumDisplayForm::WaterfallIntensityColorTypeChanged( int newType )
697 {
698   QColor lowIntensityColor;
699   QColor highIntensityColor;
700   if(newType == WaterfallDisplayPlot::INTENSITY_COLOR_MAP_TYPE_USER_DEFINED){
701     // Select the Low Intensity Color
702     lowIntensityColor = _waterfallDisplayPlot->GetUserDefinedLowIntensityColor();
703     if(!lowIntensityColor.isValid()){
704       lowIntensityColor = Qt::black;
705     }
706     QMessageBox::information(this, "Low Intensity Color Selection", "In the next window, select the low intensity color for the waterfall display",  QMessageBox::Ok);
707     lowIntensityColor = QColorDialog::getColor(lowIntensityColor, this);
708     
709     // Select the High Intensity Color
710     highIntensityColor = _waterfallDisplayPlot->GetUserDefinedHighIntensityColor();
711     if(!highIntensityColor.isValid()){
712       highIntensityColor = Qt::white;
713     }
714     QMessageBox::information(this, "High Intensity Color Selection", "In the next window, select the high intensity color for the waterfall display",  QMessageBox::Ok);
715     highIntensityColor = QColorDialog::getColor(highIntensityColor, this);
716   }
717   
718   _waterfallDisplayPlot->SetIntensityColorMapType(newType, lowIntensityColor, highIntensityColor);
719 }
720
721 void
722 SpectrumDisplayForm::Waterfall3DIntensityColorTypeChanged( int newType )
723 {
724   if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
725     QColor lowIntensityColor;
726     QColor highIntensityColor;
727     if(newType == Waterfall3DDisplayPlot::INTENSITY_COLOR_MAP_TYPE_USER_DEFINED){
728       // Select the Low Intensity Color
729       lowIntensityColor = _waterfallDisplayPlot->GetUserDefinedLowIntensityColor();
730       if(!lowIntensityColor.isValid()){
731         lowIntensityColor = Qt::black;
732       }
733       QMessageBox::information(this, "Low Intensity Color Selection", "In the next window, select the low intensity color for the waterfall display",  QMessageBox::Ok);
734       lowIntensityColor = QColorDialog::getColor(lowIntensityColor, this);
735       
736       // Select the High Intensity Color
737       highIntensityColor = _waterfallDisplayPlot->GetUserDefinedHighIntensityColor();
738       if(!highIntensityColor.isValid()){
739         highIntensityColor = Qt::white;
740       }
741       QMessageBox::information(this, "High Intensity Color Selection", "In the next window, select the high intensity color for the waterfall display",  QMessageBox::Ok);
742       highIntensityColor = QColorDialog::getColor(highIntensityColor, this);
743     }
744     _waterfall3DDisplayPlot->SetIntensityColorMapType(newType, lowIntensityColor,
745                                                       highIntensityColor);
746   }
747 }
748
749
750 void
751 SpectrumDisplayForm::ToggleTabFrequency(const bool state)
752 {
753   if(state == true) {
754     if(d_plot_fft == -1) {
755       SpectrumTypeTab->addTab(FrequencyPage, "Frequency Display");
756       d_plot_fft = SpectrumTypeTab->count()-1;
757     }
758   }
759   else {
760     SpectrumTypeTab->removeTab(SpectrumTypeTab->indexOf(FrequencyPage));
761     d_plot_fft = -1;
762   }
763 }
764
765 void
766 SpectrumDisplayForm::ToggleTabWaterfall(const bool state)
767 {
768   if(state == true) {
769     if(d_plot_waterfall == -1) {
770       SpectrumTypeTab->addTab(WaterfallPage, "Waterfall Display");
771       d_plot_waterfall = SpectrumTypeTab->count()-1;
772     }
773   }
774   else {
775     SpectrumTypeTab->removeTab(SpectrumTypeTab->indexOf(WaterfallPage));
776     d_plot_waterfall = -1;
777   }
778 }
779
780 void
781 SpectrumDisplayForm::ToggleTabWaterfall3D(const bool state)
782 {
783   if(state == true) {
784     if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
785       if(d_plot_waterfall3d == -1) {
786         SpectrumTypeTab->addTab(Waterfall3DPage, "3D Waterfall Display");
787         d_plot_waterfall3d = SpectrumTypeTab->count()-1;
788       }
789     }
790   }
791   else {
792     SpectrumTypeTab->removeTab(SpectrumTypeTab->indexOf(Waterfall3DPage));
793     d_plot_waterfall3d = -1;
794   }
795 }
796
797 void
798 SpectrumDisplayForm::ToggleTabTime(const bool state)
799 {
800   if(state == true) {
801     if(d_plot_time == -1) {
802       SpectrumTypeTab->addTab(TimeDomainPage, "Time Domain Display");
803       d_plot_time = SpectrumTypeTab->count()-1;
804     }
805   }
806   else {
807     SpectrumTypeTab->removeTab(SpectrumTypeTab->indexOf(TimeDomainPage));
808     d_plot_time = -1;
809   }
810 }
811
812 void
813 SpectrumDisplayForm::ToggleTabConstellation(const bool state)
814 {
815   if(state == true) {
816     if(d_plot_constellation == -1) {
817       SpectrumTypeTab->addTab(ConstellationPage, "Constellation Display");
818       d_plot_constellation = SpectrumTypeTab->count()-1;
819     }
820   }
821   else {
822     SpectrumTypeTab->removeTab(SpectrumTypeTab->indexOf(ConstellationPage));
823     d_plot_constellation = -1;
824   }
825 }
826
827
828 void
829 SpectrumDisplayForm::SetTimeDomainAxis(double min, double max)
830 {
831   _timeDomainDisplayPlot->set_yaxis(min, max);
832 }
833
834 void
835 SpectrumDisplayForm::SetConstellationAxis(double xmin, double xmax,
836                                                 double ymin, double ymax)
837 {
838   _constellationDisplayPlot->set_axis(xmin, xmax, ymin, ymax);
839 }
840
841 void
842 SpectrumDisplayForm::SetFrequencyAxis(double min, double max)
843 {
844   _frequencyDisplayPlot->set_yaxis(min, max);
845 }