// Copyright (c) Charles J. Cliffe // SPDX-License-Identifier: GPL-2.0+ #include "FrequencyDialog.h" #include "wx/clipbrd.h" #include #include "CubicSDR.h" wxBEGIN_EVENT_TABLE(FrequencyDialog, wxDialog) EVT_CHAR_HOOK(FrequencyDialog::OnChar) EVT_SHOW(FrequencyDialog::OnShow) wxEND_EVENT_TABLE() FrequencyDialog::FrequencyDialog(wxWindow * parent, wxWindowID id, const wxString & title, DemodulatorInstance *demod, const wxPoint & position, const wxSize & size, long style, FrequencyDialogTarget targetMode, wxString initString) : wxDialog(parent, id, title, position, size, style) { wxString freqStr; activeDemod = demod; this->targetMode = targetMode; this->initialString = initString; if (targetMode == FDIALOG_TARGET_DEFAULT) { if (activeDemod) { freqStr = frequencyToStr(activeDemod->getFrequency()); } else { freqStr = frequencyToStr(wxGetApp().getFrequency()); } } if (targetMode == FDIALOG_TARGET_BANDWIDTH) { std::string lastDemodType = activeDemod?activeDemod->getDemodulatorType():wxGetApp().getDemodMgr().getLastDemodulatorType(); if (lastDemodType == "USB" || lastDemodType == "LSB") { freqStr = frequencyToStr(wxGetApp().getDemodMgr().getLastBandwidth()/2); } else { freqStr = frequencyToStr(wxGetApp().getDemodMgr().getLastBandwidth()); } } if (targetMode == FDIALOG_TARGET_WATERFALL_LPS) { freqStr = std::to_string(wxGetApp().getAppFrame()->getWaterfallDataThread()->getLinesPerSecond()); } if (targetMode == FDIALOG_TARGET_SPECTRUM_AVG) { freqStr = std::to_string(wxGetApp().getSpectrumProcessor()->getFFTAverageRate()); } if (targetMode == FDIALOG_TARGET_GAIN) { if (wxGetApp().getActiveGainEntry() != "") { freqStr = std::to_string((int)wxGetApp().getGain(wxGetApp().getActiveGainEntry())); } } dialogText = new wxTextCtrl(this, wxID_FREQ_INPUT, freqStr, wxPoint(6, 1), wxSize(size.GetWidth() - 20, size.GetHeight() - 70), wxTE_PROCESS_ENTER); dialogText->SetFont(wxFont(20, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD)); Centre(); if (initString != "" && initString.length() == 1) { dialogText->SetValue(initString); dialogText->SetSelection(2, 2); dialogText->SetFocus(); } else { if (initString != "") { dialogText->SetValue(initString); } dialogText->SetSelection(-1, -1); } } void FrequencyDialog::OnChar(wxKeyEvent& event) { int c = event.GetKeyCode(); long long freq, freq2, freq_ctr, range_bw; double dblval; std::string lastDemodType = activeDemod?activeDemod->getDemodulatorType():wxGetApp().getDemodMgr().getLastDemodulatorType(); std::string strValue = dialogText->GetValue().ToStdString(); bool ranged = false; std::string strValue2; size_t range_pos; switch (c) { case WXK_RETURN: case WXK_NUMPAD_ENTER: // Do Stuff ranged = false; if ((range_pos = strValue.find_first_of("-")) > 0) { strValue2 = strValue.substr(range_pos+1); strValue = strValue.substr(0,range_pos); if (targetMode == FDIALOG_TARGET_DEFAULT && !activeDemod && strValue.length() && strValue2.length()) { ranged = true; } } if (targetMode == FDIALOG_TARGET_DEFAULT) { if (ranged) { freq = strToFrequency(strValue); freq2 = strToFrequency(strValue2); } else { freq = strToFrequency(strValue); } if (activeDemod) { activeDemod->setTracking(true); activeDemod->setFollow(true); activeDemod->setFrequency(freq); activeDemod->updateLabel(freq); } else { if (ranged && (freq || freq2)) { if (freq > freq2) { std::swap(freq,freq2); } range_bw = (freq2-freq); freq_ctr = freq + (range_bw/2); if (range_bw > wxGetApp().getSampleRate()) { range_bw = wxGetApp().getSampleRate(); } if (range_bw < 30000) { range_bw = 30000; } if (freq == freq2) { wxGetApp().setFrequency(freq_ctr); wxGetApp().getAppFrame()->setViewState(freq_ctr); } else { if (wxGetApp().getSampleRate()/4 > range_bw) { wxGetApp().setFrequency(freq_ctr + wxGetApp().getSampleRate()/4); } else { wxGetApp().setFrequency(freq_ctr); } wxGetApp().getAppFrame()->setViewState(freq_ctr, range_bw); } } else { wxGetApp().setFrequency(freq); } } } if (targetMode == FDIALOG_TARGET_BANDWIDTH) { freq = strToFrequency(strValue); if (lastDemodType == "USB" || lastDemodType == "LSB") { freq *= 2; } if (activeDemod) { activeDemod->setBandwidth(freq); } else { wxGetApp().getDemodMgr().setLastBandwidth(freq); } } if (targetMode == FDIALOG_TARGET_WATERFALL_LPS) { try { freq = std::stoi(strValue); } catch (exception e) { Close(); break; } if (freq > 1024) { freq = 1024; } if (freq < 1) { freq = 1; } wxGetApp().getAppFrame()->setWaterfallLinesPerSecond(freq); } if (targetMode == FDIALOG_TARGET_SPECTRUM_AVG) { try { dblval = std::stod(strValue); } catch (exception e) { Close(); break; } if (dblval > 0.99) { dblval = 0.99; } if (dblval < 0.1) { dblval = 0.1; } wxGetApp().getAppFrame()->setSpectrumAvgSpeed(dblval); } if (targetMode == FDIALOG_TARGET_GAIN) { try { freq = std::stoi(strValue); } catch (exception e) { break; } SDRDeviceInfo *devInfo = wxGetApp().getDevice(); std::string gainName = wxGetApp().getActiveGainEntry(); if (gainName == "") { break; } SDRRangeMap gains = devInfo->getGains(SOAPY_SDR_RX, 0); if (freq > gains[gainName].maximum()) { freq = gains[gainName].maximum(); } if (freq < gains[gainName].minimum()) { freq = gains[gainName].minimum(); } wxGetApp().setGain(gainName, freq); wxGetApp().getAppFrame()->refreshGainUI(); } Close(); break; case WXK_ESCAPE: Close(); break; } std::string allowed("0123456789.MKGHZmkghz"); // Support '-' for range if (targetMode == FDIALOG_TARGET_DEFAULT && !activeDemod && strValue.length() > 0) { allowed.append("-"); } if (allowed.find_first_of(c) != std::string::npos || c == WXK_DELETE || c == WXK_BACK || c == WXK_NUMPAD_DECIMAL || (c >= WXK_NUMPAD0 && c <= WXK_NUMPAD9)) { #ifdef __linux__ dialogText->OnChar(event); event.Skip(); #else event.DoAllowNextEvent(); #endif } else if (event.ControlDown() && c == 'V') { // Alter clipboard contents to remove unwanted chars wxTheClipboard->Open(); wxTextDataObject data; wxTheClipboard->GetData(data); std::string clipText = data.GetText().ToStdString(); std::string pasteText = filterChars(clipText, std::string(allowed)); wxTheClipboard->SetData(new wxTextDataObject(pasteText)); wxTheClipboard->Close(); event.Skip(); } else if (c == WXK_RIGHT || c == WXK_LEFT || event.ControlDown()) { event.Skip(); } } void FrequencyDialog::OnShow(wxShowEvent &event) { if (initialString.length() == 1) { dialogText->SetFocus(); dialogText->SetSelection(2, 2); } event.Skip(); }