mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2024-11-23 12:18:37 -05:00
Merge branch 'develop' into master
This commit is contained in:
commit
5c72b97309
735
CMakeLists.txt
735
CMakeLists.txt
@ -6,19 +6,69 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
|
||||
|
||||
SET(CUBICSDR_VERSION_MAJOR "0")
|
||||
SET(CUBICSDR_VERSION_MINOR "2")
|
||||
SET(CUBICSDR_VERSION_PATCH "0")
|
||||
SET(CUBICSDR_VERSION_REL "")
|
||||
SET(CUBICSDR_VERSION "${CUBICSDR_VERSION_MAJOR}.${CUBICSDR_VERSION_MINOR}.${CUBICSDR_VERSION_PATCH}${CUBICSDR_VERSION_REL}")
|
||||
SET(CUBICSDR_VERSION_PATCH "1")
|
||||
SET(CUBICSDR_VERSION_SUFFIX "-alpha-bookmark1")
|
||||
SET(CUBICSDR_VERSION "${CUBICSDR_VERSION_MAJOR}.${CUBICSDR_VERSION_MINOR}.${CUBICSDR_VERSION_PATCH}${CUBICSDR_VERSION_SUFFIX}")
|
||||
|
||||
SET(CPACK_PACKAGE_VERSION "${CUBICSDR_VERSION_MAJOR}.${CUBICSDR_VERSION_MINOR}.${CUBICSDR_VERSION_PATCH}")
|
||||
SET(CPACK_PACKAGE_VERSION_MAJOR ${CUBICSDR_VERSION_MAJOR})
|
||||
SET(CPACK_PACKAGE_VERSION_MINOR ${CUBICSDR_VERSION_MINOR})
|
||||
SET(CPACK_PACKAGE_VERSION_PATCH ${CUBICSDR_VERSION_PATCH})
|
||||
|
||||
SET (VERSION_SUFFIX "" CACHE STRING "Add custom version suffix to CubicSDR application title.")
|
||||
SET (CUSTOM_BUILD OFF CACHE BOOL "Enable custom build options")
|
||||
# Build options for custom deploys, optimization and debugging
|
||||
IF(CUSTOM_BUILD)
|
||||
SET (CUBICSDR_BUILD_TITLE CACHE STRING "Custom Title")
|
||||
# bundle flags
|
||||
SET (CUBICSDR_INSTALL_NAME CACHE "CubicSDR" "Installation Name")
|
||||
SET (CUBICSDR_INSTALL_TITLE CACHE "CubicSDR" "Installation Title")
|
||||
SET (CUBICSDR_HEADER_IMAGE CACHE "" "Image file to display in header")
|
||||
SET (CUBICSDR_HEADER_BG CACHE "000000" "Background Color (HEX) for header")
|
||||
# feature flags
|
||||
SET (CUBICSDR_ENABLE_VIEW_DEMOD ON CACHE BOOL "Enable Second Demodulator Spectrum/Waterfall view.")
|
||||
SET (CUBICSDR_ENABLE_VIEW_SCOPE ON CACHE BOOL "Enable Demodulator Scope/Spectrum view.")
|
||||
SET (CUBICSDR_MODEM_EXCLUDE CACHE "" "Comma-separated list of modems to exclude.")
|
||||
|
||||
IF (NOT CUBICSDR_HEADER_IMAGE STREQUAL "")
|
||||
SET(CUBICSDR_HAS_HEADER_IMAGE TRUE)
|
||||
GET_FILENAME_COMPONENT(CUBICSDR_HEADER_IMAGE_FILE "${CUBICSDR_HEADER_IMAGE}" NAME)
|
||||
GET_FILENAME_COMPONENT(CUBICSDR_HEADER_IMAGE_DIR "${CUBICSDR_HEADER_IMAGE}" PATH)
|
||||
ADD_DEFINITIONS(
|
||||
-DCUBICSDR_HEADER_IMAGE="${CUBICSDR_HEADER_IMAGE_FILE}"
|
||||
-DCUBICSDR_HEADER_BG="${CUBICSDR_HEADER_BG}"
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
IF (NOT CUBICSDR_MODEM_EXCLUDE STREQUAL "")
|
||||
ADD_DEFINITIONS(
|
||||
-DCUBICSDR_MODEM_EXCLUDE="${CUBICSDR_MODEM_EXCLUDE}"
|
||||
)
|
||||
ENDIF()
|
||||
ELSE()
|
||||
SET (CUBICSDR_BUILD_TITLE "CubicSDR v${CUBICSDR_VERSION} by Charles J. Cliffe (@ccliffe) :: www.cubicsdr.com")
|
||||
# bundle flags
|
||||
SET (CUBICSDR_INSTALL_NAME "CubicSDR")
|
||||
SET (CUBICSDR_INSTALL_TITLE "CubicSDR ${CUBICSDR_VERSION} Installer")
|
||||
SET (CUBICSDR_HEADER_IMAGE "")
|
||||
SET (CUBICSDR_HEADER_BG "")
|
||||
# feature flags
|
||||
SET (CUBICSDR_ENABLE_VIEW_DEMOD TRUE)
|
||||
SET (CUBICSDR_ENABLE_VIEW_SCOPE TRUE)
|
||||
SET (CUBICSDR_EXCLUDE_MODEM "")
|
||||
ENDIF()
|
||||
|
||||
IF(CUBICSDR_ENABLE_VIEW_DEMOD)
|
||||
ADD_DEFINITIONS( -DCUBICSDR_ENABLE_VIEW_DEMOD=1 )
|
||||
ENDIF()
|
||||
|
||||
IF(CUBICSDR_ENABLE_VIEW_SCOPE)
|
||||
ADD_DEFINITIONS( -DCUBICSDR_ENABLE_VIEW_SCOPE=1 )
|
||||
ENDIF()
|
||||
|
||||
ADD_DEFINITIONS(
|
||||
-DCUBICSDR_VERSION="${CUBICSDR_VERSION}${VERSION_SUFFIX}"
|
||||
-DCUBICSDR_INSTALL_NAME="${CUBICSDR_INSTALL_NAME}"
|
||||
-DCUBICSDR_VERSION="${CUBICSDR_VERSION}"
|
||||
-DCUBICSDR_BUILD_TITLE="${CUBICSDR_BUILD_TITLE}"
|
||||
)
|
||||
|
||||
SET (ENABLE_DIGITAL_LAB OFF CACHE BOOL "Enable 'Digital Lab' testing features.")
|
||||
@ -27,9 +77,9 @@ ADD_DEFINITIONS(
|
||||
-DENABLE_DIGITAL_LAB=1
|
||||
)
|
||||
IF(MSVC)
|
||||
SET (ENABLE_LIQUID_EXPERIMENTAL OFF CACHE BOOL "Enable experimental liquid-dsp features (requires latest liquid-dsp installed)")
|
||||
SET (ENABLE_LIQUID_EXPERIMENTAL OFF CACHE BOOL "Enable experimental liquid-dsp features (requires latest liquid-dsp installed)")
|
||||
ELSE()
|
||||
SET (ENABLE_LIQUID_EXPERIMENTAL ON CACHE BOOL "Enable experimental liquid-dsp features (requires latest liquid-dsp installed)")
|
||||
SET (ENABLE_LIQUID_EXPERIMENTAL ON CACHE BOOL "Enable experimental liquid-dsp features (requires latest liquid-dsp installed)")
|
||||
ENDIF()
|
||||
IF(ENABLE_LIQUID_EXPERIMENTAL)
|
||||
ADD_DEFINITIONS(
|
||||
@ -50,7 +100,7 @@ if (USE_HAMLIB)
|
||||
include_directories(${HAMLIB_INCLUDE_DIR})
|
||||
link_libraries(${HAMLIB_LIBRARY})
|
||||
|
||||
ADD_DEFINITIONS(-DUSE_HAMLIB)
|
||||
ADD_DEFINITIONS(-DUSE_HAMLIB)
|
||||
endif ()
|
||||
|
||||
macro(configure_files srcDir destDir globStr)
|
||||
@ -103,16 +153,16 @@ SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_BINARY_DIR}/${EX_PLATFORM_NA
|
||||
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_BINARY_DIR}/${EX_PLATFORM_NAME})
|
||||
|
||||
IF (MSVC)
|
||||
include_directories ("${PROJECT_SOURCE_DIR}/external/wglext")
|
||||
SET(LIQUID_INCLUDES "${PROJECT_SOURCE_DIR}/external/liquid-dsp/include/" CACHE STRING "Liquid-DSP include directory")
|
||||
SET(LIQUID_LIBRARIES "${PROJECT_SOURCE_DIR}/external/liquid-dsp/msvc/${EX_PLATFORM}/libliquid.lib" CACHE STRING "Liquid-DSP Library")
|
||||
SET(LIQUID_DLL "${PROJECT_SOURCE_DIR}/external/liquid-dsp/msvc/${EX_PLATFORM}/libliquid.dll" CACHE STRING "Liquid-DSP DLL")
|
||||
SET(HAMLIB_DLLS "${PROJECT_SOURCE_DIR}/external/hamlib/${EX_PLATFORM}/libhamlib-2.dll;${PROJECT_SOURCE_DIR}/external/hamlib/${EX_PLATFORM}/libwinpthread-1.dll" CACHE STRING "HAMLIB DLLS")
|
||||
include_directories ("${PROJECT_SOURCE_DIR}/external/wglext")
|
||||
SET(LIQUID_INCLUDES "${PROJECT_SOURCE_DIR}/external/liquid-dsp/include/" CACHE STRING "Liquid-DSP include directory")
|
||||
SET(LIQUID_LIBRARIES "${PROJECT_SOURCE_DIR}/external/liquid-dsp/msvc/${EX_PLATFORM}/libliquid.lib" CACHE STRING "Liquid-DSP Library")
|
||||
SET(LIQUID_DLL "${PROJECT_SOURCE_DIR}/external/liquid-dsp/msvc/${EX_PLATFORM}/libliquid.dll" CACHE STRING "Liquid-DSP DLL")
|
||||
SET(HAMLIB_DLLS "${PROJECT_SOURCE_DIR}/external/hamlib/${EX_PLATFORM}/libhamlib-2.dll;${PROJECT_SOURCE_DIR}/external/hamlib/${EX_PLATFORM}/libwinpthread-1.dll" CACHE STRING "HAMLIB DLLS")
|
||||
ELSE (MSVC)
|
||||
ADD_DEFINITIONS(
|
||||
-std=c++0x
|
||||
-pthread
|
||||
)
|
||||
ADD_DEFINITIONS(
|
||||
-std=c++0x
|
||||
-pthread
|
||||
)
|
||||
ENDIF(MSVC)
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
@ -128,50 +178,50 @@ find_package(SoapySDR "0.4.0" NO_MODULE REQUIRED)
|
||||
include_directories(${SOAPY_SDR_INCLUDE_DIR})
|
||||
SET(OTHER_LIBRARIES ${SOAPY_SDR_LIBRARY} ${OTHER_LIBRARIES})
|
||||
ADD_DEFINITIONS(
|
||||
-DUSE_SOAPY_SDR=1
|
||||
-DUSE_SOAPY_SDR=1
|
||||
)
|
||||
|
||||
IF (WIN32)
|
||||
set(wxWidgets_USE_STATIC ON)
|
||||
set(wxWidgets_USE_STATIC ON)
|
||||
|
||||
set(BUILD_INSTALLER OFF CACHE BOOL "Build Installer")
|
||||
|
||||
# Audio device selection is not mandatory, dummy audio device is used if none are compiled in.
|
||||
# Can also compile support for more than one simultaneously.
|
||||
set(USE_AUDIO_DS ON CACHE BOOL "Include support for DirectSound")
|
||||
set(USE_AUDIO_WASAPI OFF CACHE BOOL "Include support for WASAPI Audio")
|
||||
# TODO:
|
||||
# set(USE_AUDIO_ASIO OFF CACHE BOOL "Include support for ASIO Audio")
|
||||
set(BUILD_INSTALLER OFF CACHE BOOL "Build Installer")
|
||||
|
||||
# Audio device selection is not mandatory, dummy audio device is used if none are compiled in.
|
||||
# Can also compile support for more than one simultaneously.
|
||||
set(USE_AUDIO_DS ON CACHE BOOL "Include support for DirectSound")
|
||||
set(USE_AUDIO_WASAPI OFF CACHE BOOL "Include support for WASAPI Audio")
|
||||
# TODO:
|
||||
# set(USE_AUDIO_ASIO OFF CACHE BOOL "Include support for ASIO Audio")
|
||||
|
||||
# WASAPI
|
||||
IF(USE_AUDIO_WASAPI)
|
||||
ADD_DEFINITIONS(-D__WINDOWS_WASAPI__)
|
||||
IF (NOT MSVC)
|
||||
SET(OTHER_LIBRARIES ${OTHER_LIBRARIES} -luuid -lksuser)
|
||||
ENDIF(NOT MSVC)
|
||||
ENDIF(USE_AUDIO_WASAPI)
|
||||
# WASAPI
|
||||
IF(USE_AUDIO_WASAPI)
|
||||
ADD_DEFINITIONS(-D__WINDOWS_WASAPI__)
|
||||
IF (NOT MSVC)
|
||||
SET(OTHER_LIBRARIES ${OTHER_LIBRARIES} -luuid -lksuser)
|
||||
ENDIF(NOT MSVC)
|
||||
ENDIF(USE_AUDIO_WASAPI)
|
||||
|
||||
# DirectSound
|
||||
IF (USE_AUDIO_DS)
|
||||
ADD_DEFINITIONS(-D__WINDOWS_DS__)
|
||||
IF (MSVC)
|
||||
SET(OTHER_LIBRARIES ${OTHER_LIBRARIES} dsound.lib)
|
||||
ELSE (MSVC)
|
||||
SET(OTHER_LIBRARIES ${OTHER_LIBRARIES} -ldsound)
|
||||
ENDIF (MSVC)
|
||||
ENDIF(USE_AUDIO_DS)
|
||||
# DirectSound
|
||||
IF (USE_AUDIO_DS)
|
||||
ADD_DEFINITIONS(-D__WINDOWS_DS__)
|
||||
IF (MSVC)
|
||||
SET(OTHER_LIBRARIES ${OTHER_LIBRARIES} dsound.lib)
|
||||
ELSE (MSVC)
|
||||
SET(OTHER_LIBRARIES ${OTHER_LIBRARIES} -ldsound)
|
||||
ENDIF (MSVC)
|
||||
ENDIF(USE_AUDIO_DS)
|
||||
|
||||
SET(USE_MINGW_PATCH OFF CACHE BOOL "Add some missing functions when compiling against mingw liquid-dsp.")
|
||||
IF (USE_MINGW_PATCH)
|
||||
SET(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} legacy_stdio_definitions.lib libgcc.a")
|
||||
ADD_DEFINITIONS(
|
||||
-DMINGW_PATCH=1
|
||||
)
|
||||
SET (GCC_LINKDIR "" CACHE STRING "")
|
||||
IF (GCC_LINKDIR)
|
||||
link_directories("${GCC_LINKDIR}")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
SET(USE_MINGW_PATCH OFF CACHE BOOL "Add some missing functions when compiling against mingw liquid-dsp.")
|
||||
IF (USE_MINGW_PATCH)
|
||||
SET(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} legacy_stdio_definitions.lib libgcc.a")
|
||||
ADD_DEFINITIONS(
|
||||
-DMINGW_PATCH=1
|
||||
)
|
||||
SET (GCC_LINKDIR "" CACHE STRING "")
|
||||
IF (GCC_LINKDIR)
|
||||
link_directories("${GCC_LINKDIR}")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF (WIN32)
|
||||
|
||||
IF (UNIX AND NOT APPLE)
|
||||
@ -240,22 +290,23 @@ ENDIF (APPLE)
|
||||
|
||||
|
||||
SET (cubicsdr_sources
|
||||
src/CubicSDR.cpp
|
||||
src/AppFrame.cpp
|
||||
src/AppConfig.cpp
|
||||
src/FrequencyDialog.cpp
|
||||
src/CubicSDR.cpp
|
||||
src/AppFrame.cpp
|
||||
src/AppConfig.cpp
|
||||
src/FrequencyDialog.cpp
|
||||
src/DemodLabelDialog.cpp
|
||||
src/IOThread.cpp
|
||||
src/ModemProperties.cpp
|
||||
src/sdr/SDRDeviceInfo.cpp
|
||||
src/sdr/SDRPostThread.cpp
|
||||
src/sdr/SDREnumerator.cpp
|
||||
src/sdr/SoapySDRThread.h
|
||||
src/demod/DemodulatorPreThread.cpp
|
||||
src/demod/DemodulatorThread.cpp
|
||||
src/demod/DemodulatorWorkerThread.cpp
|
||||
src/demod/DemodulatorInstance.cpp
|
||||
src/demod/DemodulatorMgr.cpp
|
||||
src/BookmarkMgr.cpp
|
||||
src/sdr/SDRDeviceInfo.cpp
|
||||
src/sdr/SDRPostThread.cpp
|
||||
src/sdr/SDREnumerator.cpp
|
||||
src/sdr/SoapySDRThread.h
|
||||
src/demod/DemodulatorPreThread.cpp
|
||||
src/demod/DemodulatorThread.cpp
|
||||
src/demod/DemodulatorWorkerThread.cpp
|
||||
src/demod/DemodulatorInstance.cpp
|
||||
src/demod/DemodulatorMgr.cpp
|
||||
src/modules/modem/Modem.cpp
|
||||
src/modules/modem/ModemAnalog.cpp
|
||||
src/modules/modem/ModemDigital.cpp
|
||||
@ -267,50 +318,55 @@ SET (cubicsdr_sources
|
||||
src/modules/modem/analog/ModemIQ.cpp
|
||||
src/modules/modem/analog/ModemLSB.cpp
|
||||
src/modules/modem/analog/ModemUSB.cpp
|
||||
src/audio/AudioThread.cpp
|
||||
src/util/Gradient.cpp
|
||||
src/util/Timer.cpp
|
||||
src/util/MouseTracker.cpp
|
||||
src/util/GLExt.cpp
|
||||
src/util/GLFont.cpp
|
||||
src/util/DataTree.cpp
|
||||
src/audio/AudioThread.cpp
|
||||
src/util/Gradient.cpp
|
||||
src/util/Timer.cpp
|
||||
src/util/MouseTracker.cpp
|
||||
src/util/GLExt.cpp
|
||||
src/util/GLFont.cpp
|
||||
src/util/DataTree.cpp
|
||||
src/panel/ScopePanel.cpp
|
||||
src/panel/SpectrumPanel.cpp
|
||||
src/panel/WaterfallPanel.cpp
|
||||
src/panel/MeterPanel.cpp
|
||||
src/panel/MeterPanel.h
|
||||
src/visual/ColorTheme.cpp
|
||||
src/visual/PrimaryGLContext.cpp
|
||||
src/visual/InteractiveCanvas.cpp
|
||||
src/visual/MeterCanvas.cpp
|
||||
src/visual/MeterContext.cpp
|
||||
src/visual/TuningCanvas.cpp
|
||||
src/visual/TuningContext.cpp
|
||||
src/visual/ModeSelectorCanvas.cpp
|
||||
src/visual/ModeSelectorContext.cpp
|
||||
src/visual/ScopeCanvas.cpp
|
||||
src/visual/ScopeContext.cpp
|
||||
src/visual/SpectrumCanvas.cpp
|
||||
src/visual/WaterfallCanvas.cpp
|
||||
src/visual/ColorTheme.cpp
|
||||
src/visual/PrimaryGLContext.cpp
|
||||
src/visual/InteractiveCanvas.cpp
|
||||
src/visual/MeterCanvas.cpp
|
||||
src/visual/MeterContext.cpp
|
||||
src/visual/TuningCanvas.cpp
|
||||
src/visual/TuningContext.cpp
|
||||
src/visual/ModeSelectorCanvas.cpp
|
||||
src/visual/ModeSelectorContext.cpp
|
||||
src/visual/ScopeCanvas.cpp
|
||||
src/visual/ScopeContext.cpp
|
||||
src/visual/SpectrumCanvas.cpp
|
||||
src/visual/WaterfallCanvas.cpp
|
||||
src/visual/GainCanvas.cpp
|
||||
src/process/VisualProcessor.cpp
|
||||
src/process/ScopeVisualProcessor.cpp
|
||||
src/process/SpectrumVisualProcessor.cpp
|
||||
src/process/FFTVisualDataThread.cpp
|
||||
src/process/FFTDataDistributor.cpp
|
||||
src/visual/ImagePanel.cpp
|
||||
src/process/VisualProcessor.cpp
|
||||
src/process/ScopeVisualProcessor.cpp
|
||||
src/process/SpectrumVisualProcessor.cpp
|
||||
src/process/FFTVisualDataThread.cpp
|
||||
src/process/FFTDataDistributor.cpp
|
||||
src/process/SpectrumVisualDataThread.cpp
|
||||
src/ui/GLPanel.cpp
|
||||
src/ui/GLPanel.cpp
|
||||
src/forms/SDRDevices/SDRDevices.cpp
|
||||
src/forms/SDRDevices/SDRDevicesForm.cpp
|
||||
src/forms/SDRDevices/SDRDeviceAdd.cpp
|
||||
src/forms/SDRDevices/SDRDeviceAddForm.cpp
|
||||
external/rtaudio/RtAudio.cpp
|
||||
external/lodepng/lodepng.cpp
|
||||
external/tinyxml/tinyxml.cpp
|
||||
external/tinyxml/tinystr.cpp
|
||||
external/tinyxml/tinyxmlparser.cpp
|
||||
external/tinyxml/tinyxmlerror.cpp
|
||||
external/cubicvr2/math/cubic_math.cpp
|
||||
src/forms/Bookmark/BookmarkPanel.cpp
|
||||
src/forms/Bookmark/BookmarkView.cpp
|
||||
src/forms/Dialog/ActionDialogBase.cpp
|
||||
src/forms/Dialog/ActionDialog.cpp
|
||||
external/rtaudio/RtAudio.cpp
|
||||
external/lodepng/lodepng.cpp
|
||||
external/tinyxml/tinyxml.cpp
|
||||
external/tinyxml/tinystr.cpp
|
||||
external/tinyxml/tinyxmlparser.cpp
|
||||
external/tinyxml/tinyxmlerror.cpp
|
||||
external/cubicvr2/math/cubic_math.cpp
|
||||
)
|
||||
|
||||
IF(ENABLE_DIGITAL_LAB)
|
||||
@ -330,33 +386,34 @@ IF(ENABLE_DIGITAL_LAB)
|
||||
src/modules/modem/digital/ModemQAM.cpp
|
||||
src/modules/modem/digital/ModemQPSK.cpp
|
||||
)
|
||||
IF(ENABLE_LIQUID_EXPERIMENTAL)
|
||||
IF(ENABLE_LIQUID_EXPERIMENTAL)
|
||||
SET (cubicsdr_sources
|
||||
${cubicsdr_sources}
|
||||
src/modules/modem/digital/ModemFSK.cpp
|
||||
)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
SET (cubicsdr_headers
|
||||
src/CubicSDRDefs.h
|
||||
src/CubicSDR.h
|
||||
src/AppFrame.h
|
||||
src/AppConfig.h
|
||||
src/FrequencyDialog.h
|
||||
src/CubicSDRDefs.h
|
||||
src/CubicSDR.h
|
||||
src/AppFrame.h
|
||||
src/AppConfig.h
|
||||
src/FrequencyDialog.h
|
||||
src/DemodLabelDialog.h
|
||||
src/IOThread.h
|
||||
src/ModemProperties.h
|
||||
src/sdr/SDRDeviceInfo.h
|
||||
src/sdr/SDRPostThread.h
|
||||
src/sdr/SDREnumerator.h
|
||||
src/sdr/SoapySDRThread.cpp
|
||||
src/demod/DemodulatorPreThread.h
|
||||
src/demod/DemodulatorThread.h
|
||||
src/demod/DemodulatorWorkerThread.h
|
||||
src/demod/DemodulatorInstance.h
|
||||
src/demod/DemodulatorMgr.h
|
||||
src/demod/DemodDefs.h
|
||||
src/BookmarkMgr.h
|
||||
src/sdr/SDRDeviceInfo.h
|
||||
src/sdr/SDRPostThread.h
|
||||
src/sdr/SDREnumerator.h
|
||||
src/sdr/SoapySDRThread.cpp
|
||||
src/demod/DemodulatorPreThread.h
|
||||
src/demod/DemodulatorThread.h
|
||||
src/demod/DemodulatorWorkerThread.h
|
||||
src/demod/DemodulatorInstance.h
|
||||
src/demod/DemodulatorMgr.h
|
||||
src/demod/DemodDefs.h
|
||||
src/modules/modem/Modem.h
|
||||
src/modules/modem/ModemAnalog.h
|
||||
src/modules/modem/ModemDigital.h
|
||||
@ -368,64 +425,69 @@ SET (cubicsdr_headers
|
||||
src/modules/modem/analog/ModemIQ.h
|
||||
src/modules/modem/analog/ModemLSB.h
|
||||
src/modules/modem/analog/ModemUSB.h
|
||||
src/audio/AudioThread.h
|
||||
src/util/Gradient.h
|
||||
src/util/Timer.h
|
||||
src/util/ThreadQueue.h
|
||||
src/util/MouseTracker.h
|
||||
src/util/GLExt.h
|
||||
src/util/GLFont.h
|
||||
src/util/DataTree.h
|
||||
src/audio/AudioThread.h
|
||||
src/util/Gradient.h
|
||||
src/util/Timer.h
|
||||
src/util/ThreadQueue.h
|
||||
src/util/MouseTracker.h
|
||||
src/util/GLExt.h
|
||||
src/util/GLFont.h
|
||||
src/util/DataTree.h
|
||||
src/panel/ScopePanel.h
|
||||
src/panel/SpectrumPanel.h
|
||||
src/panel/WaterfallPanel.h
|
||||
src/visual/ColorTheme.h
|
||||
src/visual/PrimaryGLContext.h
|
||||
src/visual/InteractiveCanvas.h
|
||||
src/visual/MeterCanvas.h
|
||||
src/visual/MeterContext.h
|
||||
src/visual/TuningCanvas.h
|
||||
src/visual/TuningContext.h
|
||||
src/visual/ModeSelectorCanvas.h
|
||||
src/visual/ModeSelectorContext.h
|
||||
src/visual/ScopeCanvas.h
|
||||
src/visual/ScopeContext.h
|
||||
src/visual/SpectrumCanvas.h
|
||||
src/visual/WaterfallCanvas.h
|
||||
src/visual/ColorTheme.h
|
||||
src/visual/PrimaryGLContext.h
|
||||
src/visual/InteractiveCanvas.h
|
||||
src/visual/MeterCanvas.h
|
||||
src/visual/MeterContext.h
|
||||
src/visual/TuningCanvas.h
|
||||
src/visual/TuningContext.h
|
||||
src/visual/ModeSelectorCanvas.h
|
||||
src/visual/ModeSelectorContext.h
|
||||
src/visual/ScopeCanvas.h
|
||||
src/visual/ScopeContext.h
|
||||
src/visual/SpectrumCanvas.h
|
||||
src/visual/WaterfallCanvas.h
|
||||
src/visual/GainCanvas.h
|
||||
src/process/VisualProcessor.h
|
||||
src/process/ScopeVisualProcessor.h
|
||||
src/process/SpectrumVisualProcessor.h
|
||||
src/process/FFTVisualDataThread.h
|
||||
src/process/FFTDataDistributor.h
|
||||
src/visual/ImagePanel.h
|
||||
src/process/VisualProcessor.h
|
||||
src/process/ScopeVisualProcessor.h
|
||||
src/process/SpectrumVisualProcessor.h
|
||||
src/process/FFTVisualDataThread.h
|
||||
src/process/FFTDataDistributor.h
|
||||
src/process/SpectrumVisualDataThread.h
|
||||
src/ui/GLPanel.h
|
||||
src/ui/UITestCanvas.cpp
|
||||
src/ui/UITestCanvas.h
|
||||
src/ui/UITestContext.cpp
|
||||
src/ui/UITestContext.h
|
||||
src/ui/GLPanel.h
|
||||
src/ui/UITestCanvas.cpp
|
||||
src/ui/UITestCanvas.h
|
||||
src/ui/UITestContext.cpp
|
||||
src/ui/UITestContext.h
|
||||
src/forms/SDRDevices/SDRDevices.h
|
||||
src/forms/SDRDevices/SDRDevicesForm.h
|
||||
src/forms/SDRDevices/SDRDeviceAdd.h
|
||||
src/forms/SDRDevices/SDRDeviceAddForm.h
|
||||
external/rtaudio/RtAudio.h
|
||||
external/lodepng/lodepng.h
|
||||
external/tinyxml/tinyxml.h
|
||||
external/tinyxml/tinystr.h
|
||||
external/cubicvr2/math/aabb.h
|
||||
external/cubicvr2/math/cubic_math.h
|
||||
external/cubicvr2/math/cubic_types.h
|
||||
external/cubicvr2/math/frustum.h
|
||||
external/cubicvr2/math/mat3.h
|
||||
external/cubicvr2/math/mat4.h
|
||||
external/cubicvr2/math/plane.h
|
||||
external/cubicvr2/math/quaternion.h
|
||||
external/cubicvr2/math/sphere.h
|
||||
external/cubicvr2/math/transform.h
|
||||
external/cubicvr2/math/triangle.h
|
||||
external/cubicvr2/math/vec2.h
|
||||
external/cubicvr2/math/vec3.h
|
||||
external/cubicvr2/math/vec4.h
|
||||
src/forms/Bookmark/BookmarkPanel.h
|
||||
src/forms/Bookmark/BookmarkView.h
|
||||
src/forms/Dialog/ActionDialogBase.h
|
||||
src/forms/Dialog/ActionDialog.h
|
||||
external/rtaudio/RtAudio.h
|
||||
external/lodepng/lodepng.h
|
||||
external/tinyxml/tinyxml.h
|
||||
external/tinyxml/tinystr.h
|
||||
external/cubicvr2/math/aabb.h
|
||||
external/cubicvr2/math/cubic_math.h
|
||||
external/cubicvr2/math/cubic_types.h
|
||||
external/cubicvr2/math/frustum.h
|
||||
external/cubicvr2/math/mat3.h
|
||||
external/cubicvr2/math/mat4.h
|
||||
external/cubicvr2/math/plane.h
|
||||
external/cubicvr2/math/quaternion.h
|
||||
external/cubicvr2/math/sphere.h
|
||||
external/cubicvr2/math/transform.h
|
||||
external/cubicvr2/math/triangle.h
|
||||
external/cubicvr2/math/vec2.h
|
||||
external/cubicvr2/math/vec3.h
|
||||
external/cubicvr2/math/vec4.h
|
||||
)
|
||||
|
||||
IF(ENABLE_DIGITAL_LAB)
|
||||
@ -495,6 +557,8 @@ set(REG_EXT "[^/]*([.]cpp|[.]c|[.]h|[.]hpp)$")
|
||||
|
||||
SOURCE_GROUP("Base" REGULAR_EXPRESSION "src/${REG_EXT}")
|
||||
SOURCE_GROUP("Forms\\SDRDevices" REGULAR_EXPRESSION "src/forms/SDRDevices/${REG_EXT}")
|
||||
SOURCE_GROUP("Forms\\Bookmark" REGULAR_EXPRESSION "src/forms/Bookmark/${REG_EXT}")
|
||||
SOURCE_GROUP("Forms\\Dialog" REGULAR_EXPRESSION "src/forms/Dialog/${REG_EXT}")
|
||||
SOURCE_GROUP("SDR" REGULAR_EXPRESSION "src/sdr/${REG_EXT}")
|
||||
IF(USE_HAMLIB)
|
||||
SOURCE_GROUP("Rig" REGULAR_EXPRESSION "src/rig/${REG_EXT}")
|
||||
@ -518,26 +582,28 @@ SOURCE_GROUP("_ext-TinyXML" REGULAR_EXPRESSION "external/tinyxml/.*${REG_EXT}")
|
||||
SOURCE_GROUP("_ext-CubicVR2" REGULAR_EXPRESSION "external/cubicvr2/.*${REG_EXT}")
|
||||
|
||||
include_directories (
|
||||
${PROJECT_SOURCE_DIR}/src/forms/SDRDevices
|
||||
${PROJECT_SOURCE_DIR}/src/forms/DigitalConsole
|
||||
${PROJECT_SOURCE_DIR}/src/sdr
|
||||
${PROJECT_SOURCE_DIR}/src/demod
|
||||
${PROJECT_SOURCE_DIR}/src/modules
|
||||
${PROJECT_SOURCE_DIR}/src/modules/modem
|
||||
${PROJECT_SOURCE_DIR}/src/modules/modem/digital
|
||||
${PROJECT_SOURCE_DIR}/src/modules/modem/analog
|
||||
${PROJECT_SOURCE_DIR}/src/audio
|
||||
${PROJECT_SOURCE_DIR}/src/util
|
||||
${PROJECT_SOURCE_DIR}/src/panel
|
||||
${PROJECT_SOURCE_DIR}/src/visual
|
||||
${PROJECT_SOURCE_DIR}/src/process
|
||||
${PROJECT_SOURCE_DIR}/src/ui
|
||||
${PROJECT_SOURCE_DIR}/src/rig
|
||||
${PROJECT_SOURCE_DIR}/src
|
||||
${PROJECT_SOURCE_DIR}/external/rtaudio
|
||||
${PROJECT_SOURCE_DIR}/external/lodepng
|
||||
${PROJECT_SOURCE_DIR}/external/tinyxml
|
||||
${PROJECT_SOURCE_DIR}/external/cubicvr2/math
|
||||
${PROJECT_SOURCE_DIR}/src/forms/SDRDevices
|
||||
${PROJECT_SOURCE_DIR}/src/forms/DigitalConsole
|
||||
${PROJECT_SOURCE_DIR}/src/forms/Bookmark
|
||||
${PROJECT_SOURCE_DIR}/src/forms/Dialog
|
||||
${PROJECT_SOURCE_DIR}/src/sdr
|
||||
${PROJECT_SOURCE_DIR}/src/demod
|
||||
${PROJECT_SOURCE_DIR}/src/modules
|
||||
${PROJECT_SOURCE_DIR}/src/modules/modem
|
||||
${PROJECT_SOURCE_DIR}/src/modules/modem/digital
|
||||
${PROJECT_SOURCE_DIR}/src/modules/modem/analog
|
||||
${PROJECT_SOURCE_DIR}/src/audio
|
||||
${PROJECT_SOURCE_DIR}/src/util
|
||||
${PROJECT_SOURCE_DIR}/src/panel
|
||||
${PROJECT_SOURCE_DIR}/src/visual
|
||||
${PROJECT_SOURCE_DIR}/src/process
|
||||
${PROJECT_SOURCE_DIR}/src/ui
|
||||
${PROJECT_SOURCE_DIR}/src/rig
|
||||
${PROJECT_SOURCE_DIR}/src
|
||||
${PROJECT_SOURCE_DIR}/external/rtaudio
|
||||
${PROJECT_SOURCE_DIR}/external/lodepng
|
||||
${PROJECT_SOURCE_DIR}/external/tinyxml
|
||||
${PROJECT_SOURCE_DIR}/external/cubicvr2/math
|
||||
)
|
||||
|
||||
set(RES_FILES "")
|
||||
@ -546,11 +612,11 @@ if(MINGW OR MSVC)
|
||||
set(CMAKE_RC_COMPILER_INIT windres)
|
||||
ENABLE_LANGUAGE(RC)
|
||||
IF(EX_PLATFORM EQUAL 64)
|
||||
SET(RC_TARGET "pe-x86-64")
|
||||
SET(RC_TARGET "pe-x86-64")
|
||||
ELSE(EX_PLATFORM EQUAL 64)
|
||||
SET(RC_TARGET "pe-i386")
|
||||
SET(RC_TARGET "pe-i386")
|
||||
ENDIF(EX_PLATFORM EQUAL 64)
|
||||
|
||||
|
||||
SET(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> -O coff <DEFINES> -i <SOURCE> -o <OBJECT>")
|
||||
endif(MINGW OR MSVC)
|
||||
|
||||
@ -558,9 +624,12 @@ IF (NOT BUNDLE_APP)
|
||||
configure_files(${PROJECT_SOURCE_DIR}/font ${CMAKE_BINARY_DIR}/${EX_PLATFORM_NAME}/fonts "*.fnt")
|
||||
configure_files(${PROJECT_SOURCE_DIR}/font ${CMAKE_BINARY_DIR}/${EX_PLATFORM_NAME}/fonts "*.png")
|
||||
configure_files(${PROJECT_SOURCE_DIR}/icon ${CMAKE_BINARY_DIR}/${EX_PLATFORM_NAME} CubicSDR.ico)
|
||||
IF(MSVC)
|
||||
configure_files(${PROJECT_SOURCE_DIR}/external/liquid-dsp/msvc/${EX_PLATFORM}/ ${CMAKE_BINARY_DIR}/${EX_PLATFORM_NAME} "*.dll")
|
||||
ENDIF()
|
||||
IF(MSVC)
|
||||
configure_files(${PROJECT_SOURCE_DIR}/external/liquid-dsp/msvc/${EX_PLATFORM}/ ${CMAKE_BINARY_DIR}/${EX_PLATFORM_NAME} "*.dll")
|
||||
ENDIF()
|
||||
IF (CUBICSDR_HAS_HEADER_IMAGE)
|
||||
configure_files(${CUBICSDR_HEADER_IMAGE_DIR} ${CMAKE_BINARY_DIR}/${EX_PLATFORM_NAME} ${CUBICSDR_HEADER_IMAGE_FILE})
|
||||
ENDIF()
|
||||
add_executable(CubicSDR ${cubicsdr_sources} ${cubicsdr_headers} ${RES_FILES})
|
||||
target_link_libraries(CubicSDR ${LIQUID_LIB} ${wxWidgets_LIBRARIES} ${OPENGL_LIBRARIES} ${OTHER_LIBRARIES})
|
||||
ENDIF (NOT BUNDLE_APP)
|
||||
@ -575,6 +644,8 @@ IF (MSVC)
|
||||
set_target_properties(CubicSDR PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:WINDOWS")
|
||||
set_target_properties(CubicSDR PROPERTIES COMPILE_DEFINITIONS_MINSIZEREL "_WINDOWS")
|
||||
set(CMAKE_CREATE_WIN32_EXE "/SUBSYSTEM:WINDOWS /ENTRY:\"mainCRTStartup\"")
|
||||
set_target_properties (CubicSDR PROPERTIES OUTPUT_NAME "${CUBICSDR_INSTALL_NAME}")
|
||||
|
||||
ENDIF(MSVC)
|
||||
|
||||
IF (APPLE)
|
||||
@ -596,20 +667,20 @@ IF (APPLE AND BUNDLE_APP)
|
||||
set(BUNDLE_MIR_SDR OFF CACHE BOOL "Bundle mir_sdr for personal use only -- do not distribute.")
|
||||
|
||||
IF (BUNDLE_SOAPY_MODS)
|
||||
ADD_DEFINITIONS(
|
||||
-DBUNDLE_SOAPY_MODS=1
|
||||
)
|
||||
set(BUNDLED_MODS_ONLY OFF CACHE BOOL "Use bundled mods only")
|
||||
IF (BUNDLED_MODS_ONLY)
|
||||
ADD_DEFINITIONS(
|
||||
-DBUNDLED_MODS_ONLY=1
|
||||
)
|
||||
ENDIF()
|
||||
ADD_DEFINITIONS(
|
||||
-DBUNDLE_SOAPY_MODS=1
|
||||
)
|
||||
set(BUNDLED_MODS_ONLY OFF CACHE BOOL "Use bundled mods only")
|
||||
IF (BUNDLED_MODS_ONLY)
|
||||
ADD_DEFINITIONS(
|
||||
-DBUNDLED_MODS_ONLY=1
|
||||
)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
ADD_DEFINITIONS(
|
||||
-std=c++0x
|
||||
-pthread
|
||||
-std=c++0x
|
||||
-pthread
|
||||
-D_OSX_APP_
|
||||
)
|
||||
|
||||
@ -639,7 +710,7 @@ IF (APPLE AND BUNDLE_APP)
|
||||
MACOSX_BUNDLE_INFO_STRING "CubicSDR Open-Source Software-Defined Radio Application"
|
||||
MACOSX_BUNDLE_BUNDLE_NAME "CubicSDR"
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION "${CUBICSDR_VERSION}"
|
||||
MACOSX_BUNDLE_LONG_VERSION_STRING "${CUBICSDR_VERSION_MAJOR}.${CUBICSDR_VERSION_MINOR}.${CUBICSDR_VERSION_PATCH}.${CUBICSDR_VERSION_REL}"
|
||||
MACOSX_BUNDLE_LONG_VERSION_STRING "${CUBICSDR_VERSION_MAJOR}.${CUBICSDR_VERSION_MINOR}.${CUBICSDR_VERSION_PATCH}${CUBICSDR_VERSION_SUFFIX}"
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "${CUBICSDR_VERSION_MAJOR}.${CUBICSDR_VERSION_MINOR}.${CUBICSDR_VERSION_PATCH}"
|
||||
MACOSX_BUNDLE_GUI_IDENTIFIER "com.cubicproductions.cubicsdr"
|
||||
MACOSX_BUNDLE_ICON_FILE "CubicSDR.icns"
|
||||
@ -651,9 +722,10 @@ IF (APPLE AND BUNDLE_APP)
|
||||
# SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
|
||||
|
||||
IF (BUNDLE_SOAPY_MODS)
|
||||
|
||||
message(STATUS "SOAPY_ROOT: ${SOAPY_SDR_ROOT}")
|
||||
file(GLOB SOAPY_MODS ${SOAPY_SDR_ROOT}/lib/SoapySDR/modules/*.so)
|
||||
SET(SOAPY_SDR_MOD_PATH "${SOAPY_SDR_ROOT}/lib/SoapySDR/modules/${SOAPY_SDR_ABI_VERSION}")
|
||||
|
||||
file(GLOB SOAPY_MODS ${SOAPY_MOD_PATH}/*.so)
|
||||
|
||||
FOREACH(SOAPY_MOD_FILE ${SOAPY_MODS})
|
||||
INSTALL( FILES "${SOAPY_MOD_FILE}"
|
||||
@ -734,25 +806,26 @@ IF (APPLE AND BUNDLE_APP)
|
||||
|
||||
include(CPack)
|
||||
ENDIF()
|
||||
|
||||
IF(APPLE AND NOT BUNDLE_APP)
|
||||
IF (NOT CMAKE_INSTALL_PREFIX)
|
||||
SET(CMAKE_INSTALL_PREFIX "/usr/")
|
||||
ENDIF()
|
||||
ADD_DEFINITIONS(
|
||||
-DRES_FOLDER="${CMAKE_INSTALL_PREFIX}/share/cubicsdr/"
|
||||
)
|
||||
ADD_DEFINITIONS(
|
||||
-DRES_FOLDER="${CMAKE_INSTALL_PREFIX}/share/cubicsdr/"
|
||||
)
|
||||
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-z,relro")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,relro")
|
||||
|
||||
INSTALL(TARGETS CubicSDR DESTINATION bin)
|
||||
INSTALL(TARGETS CubicSDR DESTINATION bin)
|
||||
install(FILES
|
||||
${PROJECT_SOURCE_DIR}/src/CubicSDR.png
|
||||
DESTINATION share/cubicsdr)
|
||||
DESTINATION share/cubicsdr)
|
||||
|
||||
install(FILES
|
||||
${CUBICSDR_FONTS}
|
||||
DESTINATION share/cubicsdr/fonts)
|
||||
DESTINATION share/cubicsdr/fonts)
|
||||
|
||||
CONFIGURE_FILE(
|
||||
"${PROJECT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
|
||||
@ -768,181 +841,201 @@ IF (WIN32 AND NOT BUILD_INSTALLER)
|
||||
ADD_DEFINITIONS(
|
||||
-DRES_FOLDER="../share/cubicsdr/"
|
||||
)
|
||||
|
||||
|
||||
INSTALL(TARGETS CubicSDR DESTINATION bin)
|
||||
INSTALL(FILES
|
||||
${LIQUID_DLL}
|
||||
DESTINATION bin)
|
||||
INSTALL(FILES
|
||||
${LIQUID_DLL}
|
||||
DESTINATION bin)
|
||||
|
||||
IF(USE_HAMLIB)
|
||||
FOREACH(HAMLIB_DLL ${HAMLIB_DLLS})
|
||||
message(STATUS "Copying Hamlib DLL: ${HAMLIB_DLL}")
|
||||
IF(USE_HAMLIB)
|
||||
FOREACH(HAMLIB_DLL ${HAMLIB_DLLS})
|
||||
message(STATUS "Copying Hamlib DLL: ${HAMLIB_DLL}")
|
||||
INSTALL( FILES "${HAMLIB_DLL}"
|
||||
DESTINATION bin
|
||||
)
|
||||
ENDFOREACH()
|
||||
ENDIF()
|
||||
ENDFOREACH()
|
||||
ENDIF()
|
||||
|
||||
INSTALL(FILES
|
||||
${PROJECT_SOURCE_DIR}/src/CubicSDR.png
|
||||
DESTINATION share/cubicsdr)
|
||||
${PROJECT_SOURCE_DIR}/src/CubicSDR.png
|
||||
DESTINATION share/cubicsdr)
|
||||
|
||||
INSTALL(FILES
|
||||
${CUBICSDR_FONTS}
|
||||
DESTINATION share/cubicsdr/fonts)
|
||||
${CUBICSDR_FONTS}
|
||||
DESTINATION share/cubicsdr/fonts)
|
||||
|
||||
IF (CUBICSDR_HAS_HEADER_IMAGE)
|
||||
INSTALL(FILES
|
||||
${CUBICSDR_HEADER_IMAGE}
|
||||
DESTINATION share/cubicsdr/)
|
||||
ENDIF()
|
||||
|
||||
ENDIF()
|
||||
|
||||
IF (WIN32 AND BUILD_INSTALLER)
|
||||
set(BUNDLE_SOAPY_MODS OFF CACHE BOOL "Bundle local SoapySDR modules")
|
||||
|
||||
set(CPACK_GENERATOR NSIS)
|
||||
set(CPACK_PACKAGE_NAME "CubicSDR")
|
||||
set(CPACK_PACKAGE_VENDOR "cubicsdr.com")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "CubicSDR ${CUBICSDR_VERSION} Installer")
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "CubicSDR")
|
||||
SET(CPACK_NSIS_INSTALLED_ICON_NAME "CubicSDR.ico")
|
||||
SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
|
||||
set(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/icon\\\\NSIS_Header.bmp")
|
||||
IF(EX_PLATFORM EQUAL 64)
|
||||
SET(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64")
|
||||
SET(CPACK_NSIS_PACKAGE_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}")
|
||||
SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION}")
|
||||
set(CMAKE_CL_64 TRUE) # This gets around a bug in the CPack installer name generation for MinGW 64-bit since 2.8
|
||||
ELSE(EX_PLATFORM EQUAL 64)
|
||||
SET(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES")
|
||||
SET(CPACK_NSIS_PACKAGE_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} (x86)")
|
||||
SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION} (x86)")
|
||||
set(CMAKE_CL_64 FALSE)
|
||||
ENDIF(EX_PLATFORM EQUAL 64)
|
||||
|
||||
set(CPACK_NSIS_EXECUTABLES_DIRECTORY ".")
|
||||
install(TARGETS CubicSDR RUNTIME DESTINATION .)
|
||||
set(CPACK_GENERATOR NSIS)
|
||||
set(CPACK_PACKAGE_NAME "${CUBICSDR_INSTALL_NAME}")
|
||||
set(CPACK_NSIS_DISPLAY_NAME "${CUBICSDR_INSTALL_TITLE}")
|
||||
set(CPACK_PACKAGE_VENDOR "cubicsdr.com")
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CUBICSDR_INSTALL_NAME}")
|
||||
SET(CPACK_NSIS_INSTALLED_ICON_NAME "CubicSDR.ico")
|
||||
SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
|
||||
set(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/icon\\\\NSIS_Header.bmp")
|
||||
IF(EX_PLATFORM EQUAL 64)
|
||||
SET(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64")
|
||||
SET(CPACK_NSIS_PACKAGE_NAME "${CUBICSDR_INSTALL_NAME}")
|
||||
SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CUBICSDR_INSTALL_NAME} ${CPACK_PACKAGE_VERSION}")
|
||||
set(CMAKE_CL_64 TRUE) # This gets around a bug in the CPack installer name generation for MinGW 64-bit since 2.8
|
||||
ELSE(EX_PLATFORM EQUAL 64)
|
||||
SET(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES")
|
||||
SET(CPACK_NSIS_PACKAGE_NAME "${CUBICSDR_INSTALL_NAME} (x86)")
|
||||
SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CUBICSDR_INSTALL_NAME} ${CPACK_PACKAGE_VERSION} (x86)")
|
||||
set(CMAKE_CL_64 FALSE)
|
||||
ENDIF(EX_PLATFORM EQUAL 64)
|
||||
|
||||
set(CPACK_NSIS_EXECUTABLES_DIRECTORY ".")
|
||||
install(TARGETS CubicSDR RUNTIME DESTINATION .)
|
||||
|
||||
install(FILES
|
||||
install(FILES
|
||||
${PROJECT_SOURCE_DIR}/icon/CubicSDR.ico
|
||||
${LIQUID_DLL}
|
||||
DESTINATION .)
|
||||
${LIQUID_DLL}
|
||||
DESTINATION .)
|
||||
|
||||
install(FILES
|
||||
install(FILES
|
||||
${CUBICSDR_FONTS}
|
||||
DESTINATION fonts)
|
||||
|
||||
IF(USE_HAMLIB)
|
||||
FOREACH(HAMLIB_DLL ${HAMLIB_DLLS})
|
||||
message(STATUS "Copying Hamlib DLL: ${HAMLIB_DLL}")
|
||||
DESTINATION fonts)
|
||||
|
||||
IF (CUBICSDR_HAS_HEADER_IMAGE)
|
||||
INSTALL(FILES
|
||||
${CUBICSDR_HEADER_IMAGE}
|
||||
DESTINATION .)
|
||||
ENDIF()
|
||||
|
||||
IF(USE_HAMLIB)
|
||||
FOREACH(HAMLIB_DLL ${HAMLIB_DLLS})
|
||||
message(STATUS "Copying Hamlib DLL: ${HAMLIB_DLL}")
|
||||
INSTALL( FILES
|
||||
${HAMLIB_DLL}
|
||||
DESTINATION .)
|
||||
ENDFOREACH()
|
||||
ENDIF()
|
||||
${HAMLIB_DLL}
|
||||
DESTINATION .)
|
||||
ENDFOREACH()
|
||||
ENDIF()
|
||||
|
||||
IF (BUNDLE_SOAPY_MODS)
|
||||
ADD_DEFINITIONS(
|
||||
-DBUNDLE_SOAPY_MODS=1
|
||||
)
|
||||
set(BUNDLED_MODS_ONLY OFF CACHE BOOL "Use bundled mods only")
|
||||
IF (BUNDLED_MODS_ONLY)
|
||||
ADD_DEFINITIONS(
|
||||
-DBUNDLED_MODS_ONLY=1
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
file(GLOB SOAPY_BINS ${SOAPY_SDR_ROOT}/bin/*.dll)
|
||||
file(GLOB SOAPY_MODS ${SOAPY_SDR_ROOT}/lib/SoapySDR/modules/*.dll)
|
||||
message(STATUS "SOAPY_BINS: ${SOAPY_BINS}")
|
||||
message(STATUS "SOAPY_MODS: ${SOAPY_MODS}")
|
||||
install(FILES ${SOAPY_BINS} DESTINATION .)
|
||||
install(FILES ${SOAPY_MODS} DESTINATION modules)
|
||||
ENDIF(BUNDLE_SOAPY_MODS)
|
||||
|
||||
IF(MSVC AND EX_PLATFORM EQUAL 32)
|
||||
install(FILES
|
||||
${PROJECT_SOURCE_DIR}/external/msvc/${EX_PLATFORM_NAME}/libgcc_s_dw2-1.dll
|
||||
DESTINATION .)
|
||||
ENDIF(MSVC AND EX_PLATFORM EQUAL 32)
|
||||
IF (BUNDLE_SOAPY_MODS)
|
||||
ADD_DEFINITIONS(
|
||||
-DBUNDLE_SOAPY_MODS=1
|
||||
)
|
||||
set(BUNDLED_MODS_ONLY OFF CACHE BOOL "Use bundled mods only")
|
||||
IF (BUNDLED_MODS_ONLY)
|
||||
ADD_DEFINITIONS(
|
||||
-DBUNDLED_MODS_ONLY=1
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
file(GLOB SOAPY_BINS ${SOAPY_SDR_ROOT}/bin/*.dll)
|
||||
file(GLOB SOAPY_MODS ${SOAPY_SDR_ROOT}/lib/SoapySDR/modules${SOAPY_SDR_ABI_VERSION}/*.dll)
|
||||
message(STATUS "SOAPY_BINS: ${SOAPY_BINS}")
|
||||
message(STATUS "SOAPY_MODS: ${SOAPY_MODS}")
|
||||
install(FILES ${SOAPY_BINS} DESTINATION .)
|
||||
install(FILES ${SOAPY_MODS} DESTINATION modules)
|
||||
ENDIF(BUNDLE_SOAPY_MODS)
|
||||
|
||||
IF(MSVC AND EX_PLATFORM EQUAL 32)
|
||||
install(FILES
|
||||
${PROJECT_SOURCE_DIR}/external/msvc/${EX_PLATFORM_NAME}/libgcc_s_dw2-1.dll
|
||||
DESTINATION .)
|
||||
ENDIF(MSVC AND EX_PLATFORM EQUAL 32)
|
||||
|
||||
set(CPACK_PACKAGE_EXECUTABLES CubicSDR "CubicSDR")
|
||||
set(CPACK_PACKAGE_EXECUTABLES CubicSDR "CubicSDR")
|
||||
|
||||
IF (MSVC)
|
||||
install(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/external/msvc/${EX_PLATFORM_NAME}/vc_redist.${EX_PLATFORM_NAME}.exe DESTINATION vc_redist)
|
||||
set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "ExecWait '\\\"$INSTDIR\\\\vc_redist\\\\vc_redist.${EX_PLATFORM_NAME}.exe\\\" /q:a'")
|
||||
ENDIF (MSVC)
|
||||
|
||||
|
||||
INCLUDE(CPack)
|
||||
IF (MSVC)
|
||||
install(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/external/msvc/${EX_PLATFORM_NAME}/vc_redist.${EX_PLATFORM_NAME}.exe DESTINATION vc_redist)
|
||||
set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "ExecWait '\\\"$INSTDIR\\\\vc_redist\\\\vc_redist.${EX_PLATFORM_NAME}.exe\\\" /q:a'")
|
||||
ENDIF (MSVC)
|
||||
|
||||
|
||||
INCLUDE(CPack)
|
||||
ENDIF (WIN32 AND BUILD_INSTALLER)
|
||||
|
||||
|
||||
IF (UNIX AND NOT APPLE AND BUILD_DEB)
|
||||
set(CPACK_GENERATOR DEB)
|
||||
set(CPACK_PACKAGE_NAME "CubicSDR")
|
||||
SET(CPACK_DEBIAN_PACKAGE_DEPENDS " libwxgtk3.0-0, libpulse0")
|
||||
SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Charles J. Cliffe <cj@cubicproductions.com>")
|
||||
SET(CPACK_DEBIAN_PACKAGE_DESCRIPTION "CubicSDR Software Defined Radio application v${CUBICSDR_VERSION}")
|
||||
SET(CPACK_DEBIAN_PACKAGE_SECTION "comm")
|
||||
set(CPACK_PACKAGE_NAME "CubicSDR")
|
||||
SET(CPACK_DEBIAN_PACKAGE_DEPENDS " libwxgtk3.0-0, libpulse0")
|
||||
SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Charles J. Cliffe <cj@cubicproductions.com>")
|
||||
SET(CPACK_DEBIAN_PACKAGE_DESCRIPTION "CubicSDR Software Defined Radio application v${CUBICSDR_VERSION}")
|
||||
SET(CPACK_DEBIAN_PACKAGE_SECTION "comm")
|
||||
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
|
||||
SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${EX_PLATFORM_NAME}")
|
||||
SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${EX_PLATFORM_NAME}")
|
||||
|
||||
IF (NOT CMAKE_INSTALL_PREFIX)
|
||||
SET(CMAKE_INSTALL_PREFIX "/usr/")
|
||||
ENDIF()
|
||||
ADD_DEFINITIONS(
|
||||
-DRES_FOLDER="${CMAKE_INSTALL_PREFIX}/share/cubicsdr/"
|
||||
-D_FORTIFY_SOURCE=2
|
||||
)
|
||||
|
||||
ADD_DEFINITIONS(
|
||||
-DRES_FOLDER="${CMAKE_INSTALL_PREFIX}/share/cubicsdr/"
|
||||
-D_FORTIFY_SOURCE=2
|
||||
)
|
||||
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-z,relro")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,relro")
|
||||
|
||||
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/external/deb/deb_post.sh.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/deb_post.sh" @ONLY IMMEDIATE)
|
||||
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/external/deb/deb_post.sh.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/deb_post.sh" @ONLY IMMEDIATE)
|
||||
|
||||
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/cmake/CubicSDR.desktop.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/CubicSDR.desktop" @ONLY IMMEDIATE)
|
||||
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/cmake/CubicSDR.desktop.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/CubicSDR.desktop" @ONLY IMMEDIATE)
|
||||
|
||||
INSTALL(TARGETS CubicSDR DESTINATION bin)
|
||||
INSTALL(TARGETS CubicSDR DESTINATION bin)
|
||||
install(FILES
|
||||
${PROJECT_SOURCE_DIR}/src/CubicSDR.png
|
||||
DESTINATION share/cubicsdr)
|
||||
DESTINATION share/cubicsdr)
|
||||
|
||||
install(FILES
|
||||
${CUBICSDR_FONTS}
|
||||
DESTINATION share/cubicsdr/fonts)
|
||||
DESTINATION share/cubicsdr/fonts)
|
||||
|
||||
INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/CubicSDR.desktop"
|
||||
DESTINATION share/applications)
|
||||
|
||||
INCLUDE(CPack)
|
||||
INCLUDE(CPack)
|
||||
ENDIF()
|
||||
IF(UNIX AND NOT APPLE AND NOT BUILD_DEB)
|
||||
IF (NOT CMAKE_INSTALL_PREFIX)
|
||||
SET(CMAKE_INSTALL_PREFIX "/usr/")
|
||||
ENDIF()
|
||||
ADD_DEFINITIONS(
|
||||
-DRES_FOLDER="${CMAKE_INSTALL_PREFIX}/share/cubicsdr/"
|
||||
)
|
||||
ADD_DEFINITIONS(
|
||||
-DRES_FOLDER="${CMAKE_INSTALL_PREFIX}/share/cubicsdr/"
|
||||
)
|
||||
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-z,relro")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,relro")
|
||||
|
||||
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/cmake/CubicSDR.desktop.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/CubicSDR.desktop" @ONLY IMMEDIATE)
|
||||
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/cmake/CubicSDR.desktop.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/CubicSDR.desktop" @ONLY IMMEDIATE)
|
||||
|
||||
INSTALL(TARGETS CubicSDR DESTINATION bin)
|
||||
INSTALL(TARGETS CubicSDR DESTINATION bin)
|
||||
|
||||
INSTALL(FILES
|
||||
${PROJECT_SOURCE_DIR}/src/CubicSDR.png
|
||||
DESTINATION share/cubicsdr)
|
||||
DESTINATION share/cubicsdr)
|
||||
|
||||
INSTALL(FILES
|
||||
${CUBICSDR_FONTS}
|
||||
DESTINATION share/cubicsdr/fonts)
|
||||
DESTINATION share/cubicsdr/fonts)
|
||||
|
||||
|
||||
IF (CUBICSDR_HAS_HEADER_IMAGE)
|
||||
INSTALL(FILES
|
||||
${CUBICSDR_HEADER_IMAGE}
|
||||
DESTINATION share/cubicsdr)
|
||||
ENDIF()
|
||||
|
||||
INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/CubicSDR.desktop"
|
||||
DESTINATION share/applications)
|
||||
DESTINATION share/applications)
|
||||
|
||||
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/external/deb/deb_post.sh.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/deb_post.sh" @ONLY IMMEDIATE)
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/deb_post.sh" @ONLY IMMEDIATE)
|
||||
CONFIGURE_FILE(
|
||||
"${PROJECT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
|
@ -31,7 +31,6 @@ long long DeviceConfig::getOffset() {
|
||||
return offset.load();
|
||||
}
|
||||
|
||||
|
||||
void DeviceConfig::setSampleRate(long srate) {
|
||||
sampleRate.store(srate);
|
||||
}
|
||||
@ -292,7 +291,13 @@ AppConfig::AppConfig() : configName("") {
|
||||
centerFreq.store(100000000);
|
||||
waterfallLinesPerSec.store(DEFAULT_WATERFALL_LPS);
|
||||
spectrumAvgSpeed.store(0.65f);
|
||||
dbOffset.store(0);
|
||||
modemPropsCollapsed.store(false);
|
||||
mainSplit = -1;
|
||||
visSplit = -1;
|
||||
bookmarkSplit = 200;
|
||||
bookmarksVisible.store(true);
|
||||
|
||||
#ifdef USE_HAMLIB
|
||||
rigEnabled.store(false);
|
||||
rigModel.store(1);
|
||||
@ -428,6 +433,14 @@ float AppConfig::getSpectrumAvgSpeed() {
|
||||
return spectrumAvgSpeed.load();
|
||||
}
|
||||
|
||||
void AppConfig::setDBOffset(int offset) {
|
||||
this->dbOffset.store(offset);
|
||||
}
|
||||
|
||||
int AppConfig::getDBOffset() {
|
||||
return dbOffset.load();
|
||||
}
|
||||
|
||||
void AppConfig::setManualDevices(std::vector<SDRManualDef> manuals) {
|
||||
manualDevices = manuals;
|
||||
}
|
||||
@ -436,6 +449,39 @@ std::vector<SDRManualDef> AppConfig::getManualDevices() {
|
||||
return manualDevices;
|
||||
}
|
||||
|
||||
void AppConfig::setMainSplit(float value) {
|
||||
mainSplit.store(value);
|
||||
}
|
||||
|
||||
float AppConfig::getMainSplit() {
|
||||
return mainSplit.load();
|
||||
}
|
||||
|
||||
void AppConfig::setVisSplit(float value) {
|
||||
visSplit.store(value);
|
||||
}
|
||||
|
||||
float AppConfig::getVisSplit() {
|
||||
return visSplit.load();
|
||||
}
|
||||
|
||||
void AppConfig::setBookmarkSplit(float value) {
|
||||
bookmarkSplit.store(value);
|
||||
}
|
||||
|
||||
float AppConfig::getBookmarkSplit() {
|
||||
return bookmarkSplit.load();
|
||||
}
|
||||
|
||||
void AppConfig::setBookmarksVisible(bool state) {
|
||||
bookmarksVisible.store(state);
|
||||
}
|
||||
|
||||
bool AppConfig::getBookmarksVisible() {
|
||||
return bookmarksVisible.load();
|
||||
}
|
||||
|
||||
|
||||
void AppConfig::setConfigName(std::string configName) {
|
||||
this->configName = configName;
|
||||
}
|
||||
@ -481,6 +527,12 @@ bool AppConfig::save() {
|
||||
*window_node->newChild("waterfall_lps") = waterfallLinesPerSec.load();
|
||||
*window_node->newChild("spectrum_avg") = spectrumAvgSpeed.load();
|
||||
*window_node->newChild("modemprops_collapsed") = modemPropsCollapsed.load();;
|
||||
*window_node->newChild("db_offset") = dbOffset.load();
|
||||
|
||||
*window_node->newChild("main_split") = mainSplit.load();
|
||||
*window_node->newChild("vis_split") = visSplit.load();
|
||||
*window_node->newChild("bookmark_split") = bookmarkSplit.load();
|
||||
*window_node->newChild("bookmark_visible") = bookmarksVisible.load();
|
||||
}
|
||||
|
||||
DataNode *devices_node = cfg.rootNode()->newChild("devices");
|
||||
@ -631,6 +683,37 @@ bool AppConfig::load() {
|
||||
win_node->getNext("modemprops_collapsed")->element()->get(mpc);
|
||||
modemPropsCollapsed.store(mpc?true:false);
|
||||
}
|
||||
|
||||
if (win_node->hasAnother("db_offset")) {
|
||||
DataNode *offset_node = win_node->getNext("db_offset");
|
||||
int offsetValue = 0;
|
||||
offset_node->element()->get(offsetValue);
|
||||
setDBOffset(offsetValue);
|
||||
}
|
||||
|
||||
if (win_node->hasAnother("main_split")) {
|
||||
float gVal;
|
||||
win_node->getNext("main_split")->element()->get(gVal);
|
||||
mainSplit.store(gVal);
|
||||
}
|
||||
|
||||
if (win_node->hasAnother("vis_split")) {
|
||||
float gVal;
|
||||
win_node->getNext("vis_split")->element()->get(gVal);
|
||||
visSplit.store(gVal);
|
||||
}
|
||||
|
||||
if (win_node->hasAnother("bookmark_split")) {
|
||||
float gVal;
|
||||
win_node->getNext("bookmark_split")->element()->get(gVal);
|
||||
bookmarkSplit.store(gVal);
|
||||
}
|
||||
|
||||
if (win_node->hasAnother("bookmark_visible")) {
|
||||
int bVal;
|
||||
win_node->getNext("bookmark_visible")->element()->get(bVal);
|
||||
bookmarksVisible.store(bVal);
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg.rootNode()->hasAnother("devices")) {
|
||||
|
@ -115,9 +115,25 @@ public:
|
||||
void setSpectrumAvgSpeed(float avgSpeed);
|
||||
float getSpectrumAvgSpeed();
|
||||
|
||||
void setDBOffset(int offset);
|
||||
int getDBOffset();
|
||||
|
||||
void setManualDevices(std::vector<SDRManualDef> manuals);
|
||||
std::vector<SDRManualDef> getManualDevices();
|
||||
|
||||
void setMainSplit(float value);
|
||||
float getMainSplit();
|
||||
|
||||
void setVisSplit(float value);
|
||||
float getVisSplit();
|
||||
|
||||
void setBookmarkSplit(float value);
|
||||
float getBookmarkSplit();
|
||||
|
||||
void setBookmarksVisible(bool state);
|
||||
bool getBookmarksVisible();
|
||||
|
||||
|
||||
#if USE_HAMLIB
|
||||
int getRigModel();
|
||||
void setRigModel(int rigModel);
|
||||
@ -160,11 +176,12 @@ private:
|
||||
std::atomic_llong snap;
|
||||
std::atomic_llong centerFreq;
|
||||
std::atomic_int waterfallLinesPerSec;
|
||||
std::atomic<float> spectrumAvgSpeed;
|
||||
std::atomic<float> spectrumAvgSpeed, mainSplit, visSplit, bookmarkSplit;
|
||||
std::atomic_int dbOffset;
|
||||
std::vector<SDRManualDef> manualDevices;
|
||||
#if USE_HAMLIB
|
||||
std::atomic_int rigModel, rigRate;
|
||||
std::string rigPort;
|
||||
std::atomic_bool rigEnabled, rigFollowMode, rigControlMode, rigCenterLock, rigFollowModem;
|
||||
std::atomic_bool rigEnabled, rigFollowMode, rigControlMode, rigCenterLock, rigFollowModem, bookmarksVisible;
|
||||
#endif
|
||||
};
|
||||
|
413
src/AppFrame.cpp
413
src/AppFrame.cpp
@ -23,6 +23,7 @@
|
||||
#include "DataTree.h"
|
||||
#include "ColorTheme.h"
|
||||
#include "DemodulatorMgr.h"
|
||||
#include "ImagePanel.h"
|
||||
|
||||
#include <thread>
|
||||
|
||||
@ -46,6 +47,10 @@ wxEND_EVENT_TABLE()
|
||||
#include "RigThread.h"
|
||||
#endif
|
||||
|
||||
|
||||
/* split a string by 'seperator' into a vector of string */
|
||||
std::vector<std::string> str_explode(const std::string &seperator, const std::string &in_str);
|
||||
|
||||
#define APPFRAME_MODEMPROPS_MINSIZE 20
|
||||
#define APPFRAME_MODEMPROPS_MAXSIZE 240
|
||||
|
||||
@ -57,7 +62,6 @@ AppFrame::AppFrame() :
|
||||
#endif
|
||||
|
||||
wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer *demodVisuals = new wxBoxSizer(wxVERTICAL);
|
||||
demodTray = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer *demodScopeTray = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer *demodTunerTray = new wxBoxSizer(wxHORIZONTAL);
|
||||
@ -68,10 +72,30 @@ AppFrame::AppFrame() :
|
||||
//attribList.PlatformDefaults().MinRGBA(8, 8, 8, 8).DoubleBuffer().Depth(16).EndList();
|
||||
|
||||
mainSplitter = new wxSplitterWindow( this, wxID_MAIN_SPLITTER, wxDefaultPosition, wxDefaultSize, wxSP_3DSASH | wxSP_LIVE_UPDATE );
|
||||
mainSplitter->SetSashGravity(10.0/37.0);
|
||||
mainSplitter->SetSashGravity(10.0f / 37.0f);
|
||||
mainSplitter->SetMinimumPaneSize(1);
|
||||
|
||||
|
||||
wxPanel *demodPanel = new wxPanel(mainSplitter, wxID_ANY);
|
||||
|
||||
#ifdef CUBICSDR_HEADER_IMAGE
|
||||
wxFileName exePath = wxFileName(wxStandardPaths::Get().GetExecutablePath());
|
||||
std::string headerPath = exePath.GetPath().ToStdString();
|
||||
headerPath += filePathSeparator + std::string("" CUBICSDR_HEADER_IMAGE);
|
||||
wxInitAllImageHandlers();
|
||||
|
||||
ImagePanel *imgPanel = new ImagePanel(demodPanel, headerPath, wxBITMAP_TYPE_ANY);
|
||||
|
||||
std::string headerBgColor = "" CUBICSDR_HEADER_BG;
|
||||
if (headerBgColor != "") {
|
||||
imgPanel->SetBackgroundColour(wxColour(headerBgColor));
|
||||
}
|
||||
|
||||
imgPanel->SetBestFittingSize(wxSize(200, 0));
|
||||
|
||||
demodTray->Add(imgPanel, 0, wxEXPAND | wxALL, 0);
|
||||
demodTray->AddSpacer(1);
|
||||
#endif
|
||||
|
||||
gainCanvas = new GainCanvas(demodPanel, attribList);
|
||||
|
||||
@ -80,16 +104,24 @@ AppFrame::AppFrame() :
|
||||
gainSpacerItem = demodTray->AddSpacer(1);
|
||||
gainSpacerItem->Show(false);
|
||||
|
||||
std::string modemListArr[] = { "FM", "FMS", "NBFM", "AM", "LSB", "USB", "DSB", "I/Q" };
|
||||
std::vector<std::string> modemList( modemListArr, modemListArr + 8 );
|
||||
|
||||
#ifdef CUBICSDR_MODEM_EXCLUDE
|
||||
std::string excludeListStr = "" CUBICSDR_MODEM_EXCLUDE;
|
||||
std::vector<std::string> excludeList = str_explode(",",excludeListStr);
|
||||
for (auto ex_i : excludeList) {
|
||||
std::vector<std::string>::iterator found_i = std::find(modemList.begin(),modemList.end(),ex_i);
|
||||
if (found_i != modemList.end()) {
|
||||
modemList.erase(found_i);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
demodModeSelector = new ModeSelectorCanvas(demodPanel, attribList);
|
||||
demodModeSelector->addChoice("FM");
|
||||
demodModeSelector->addChoice("FMS");
|
||||
demodModeSelector->addChoice("NBFM");
|
||||
demodModeSelector->addChoice("AM");
|
||||
demodModeSelector->addChoice("LSB");
|
||||
demodModeSelector->addChoice("USB");
|
||||
demodModeSelector->addChoice("DSB");
|
||||
demodModeSelector->addChoice("I/Q");
|
||||
demodModeSelector->setSelection("FM");
|
||||
for (auto mt_i : modemList) {
|
||||
demodModeSelector->addChoice(mt_i);
|
||||
}
|
||||
demodModeSelector->setHelpTip("Choose modulation type: Frequency Modulation (Hotkey F), Amplitude Modulation (A) and Lower (L), Upper (U), Double Side-Band and more.");
|
||||
demodModeSelector->SetMinSize(wxSize(50,-1));
|
||||
demodModeSelector->SetMaxSize(wxSize(50,-1));
|
||||
@ -120,13 +152,19 @@ AppFrame::AppFrame() :
|
||||
modemProps->SetMinSize(wxSize(APPFRAME_MODEMPROPS_MAXSIZE,-1));
|
||||
modemProps->SetMaxSize(wxSize(APPFRAME_MODEMPROPS_MAXSIZE,-1));
|
||||
|
||||
modemProps->Hide();
|
||||
ModemArgInfoList dummyInfo;
|
||||
modemProps->initProperties(dummyInfo, nullptr);
|
||||
modemProps->updateTheme();
|
||||
|
||||
demodTray->Add(modemProps, 15, wxEXPAND | wxALL, 0);
|
||||
|
||||
#ifndef __APPLE__
|
||||
demodTray->AddSpacer(1);
|
||||
#endif
|
||||
|
||||
|
||||
#if CUBICSDR_ENABLE_VIEW_DEMOD
|
||||
wxBoxSizer *demodVisuals = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
wxGetApp().getDemodSpectrumProcessor()->setup(1024);
|
||||
demodSpectrumCanvas = new SpectrumCanvas(demodPanel, attribList);
|
||||
demodSpectrumCanvas->setView(wxGetApp().getConfig()->getCenterFreq(), 300000);
|
||||
@ -150,7 +188,11 @@ AppFrame::AppFrame() :
|
||||
demodTray->Add(demodVisuals, 30, wxEXPAND | wxALL, 0);
|
||||
|
||||
demodTray->AddSpacer(1);
|
||||
|
||||
#else
|
||||
demodSpectrumCanvas = nullptr;
|
||||
demodWaterfallCanvas = nullptr;
|
||||
#endif
|
||||
|
||||
demodSignalMeter = new MeterCanvas(demodPanel, attribList);
|
||||
demodSignalMeter->setMax(DEMOD_SIGNAL_MAX);
|
||||
demodSignalMeter->setMin(DEMOD_SIGNAL_MIN);
|
||||
@ -163,6 +205,7 @@ AppFrame::AppFrame() :
|
||||
|
||||
demodTray->AddSpacer(1);
|
||||
|
||||
#if CUBICSDR_ENABLE_VIEW_SCOPE
|
||||
scopeCanvas = new ScopeCanvas(demodPanel, attribList);
|
||||
scopeCanvas->setHelpTip("Audio Visuals, drag left/right to toggle Scope or Spectrum.");
|
||||
scopeCanvas->SetMinSize(wxSize(128,-1));
|
||||
@ -171,7 +214,10 @@ AppFrame::AppFrame() :
|
||||
wxGetApp().getScopeProcessor()->attachOutput(scopeCanvas->getInputQueue());
|
||||
|
||||
demodScopeTray->AddSpacer(1);
|
||||
|
||||
#else
|
||||
scopeCanvas = nullptr;
|
||||
#endif
|
||||
|
||||
deltaLockButton = new ModeSelectorCanvas(demodPanel, attribList);
|
||||
deltaLockButton->addChoice(1, "V");
|
||||
deltaLockButton->setPadding(-1,-1);
|
||||
@ -235,10 +281,13 @@ AppFrame::AppFrame() :
|
||||
|
||||
// vbox->Add(demodTray, 12, wxEXPAND | wxALL, 0);
|
||||
// vbox->AddSpacer(1);
|
||||
|
||||
mainVisSplitter = new wxSplitterWindow( mainSplitter, wxID_VIS_SPLITTER, wxDefaultPosition, wxDefaultSize, wxSP_3DSASH | wxSP_LIVE_UPDATE );
|
||||
mainVisSplitter->SetSashGravity(6.0/25.0);
|
||||
bookmarkSplitter = new wxSplitterWindow( mainSplitter, wxID_BM_SPLITTER, wxDefaultPosition, wxDefaultSize, wxSP_3DSASH | wxSP_LIVE_UPDATE );
|
||||
bookmarkSplitter->SetMinimumPaneSize(1);
|
||||
bookmarkSplitter->SetSashGravity(1.0f / 20.0f);
|
||||
|
||||
mainVisSplitter = new wxSplitterWindow( bookmarkSplitter, wxID_VIS_SPLITTER, wxDefaultPosition, wxDefaultSize, wxSP_3DSASH | wxSP_LIVE_UPDATE );
|
||||
mainVisSplitter->SetMinimumPaneSize(1);
|
||||
mainVisSplitter->SetSashGravity(6.0f / 25.0f);
|
||||
|
||||
// mainVisSplitter->Connect( wxEVT_IDLE, wxIdleEventHandler( AppFrame::mainVisSplitterIdle ), NULL, this );
|
||||
|
||||
@ -248,6 +297,7 @@ AppFrame::AppFrame() :
|
||||
wxGetApp().getSpectrumProcessor()->setup(2048);
|
||||
spectrumCanvas = new SpectrumCanvas(spectrumPanel, attribList);
|
||||
spectrumCanvas->setShowDb(true);
|
||||
spectrumCanvas->setUseDBOfs(true);
|
||||
spectrumCanvas->setScaleFactorEnabled(true);
|
||||
wxGetApp().getSpectrumProcessor()->attachOutput(spectrumCanvas->getVisualDataQueue());
|
||||
|
||||
@ -312,10 +362,19 @@ AppFrame::AppFrame() :
|
||||
// vbox->Add(wfSizer, 20, wxEXPAND | wxALL, 0);
|
||||
|
||||
mainVisSplitter->SplitHorizontally( spectrumPanel, waterfallPanel, 0 );
|
||||
mainSplitter->SplitHorizontally( demodPanel, mainVisSplitter );
|
||||
|
||||
bookmarkView = new BookmarkView(bookmarkSplitter, wxID_ANY, wxDefaultPosition, wxSize(120,-1));
|
||||
|
||||
bookmarkSplitter->SplitVertically( bookmarkView, mainVisSplitter );
|
||||
mainSplitter->SplitHorizontally( demodPanel, bookmarkSplitter );
|
||||
|
||||
if (!wxGetApp().getConfig()->getBookmarksVisible()) {
|
||||
bookmarkSplitter->Unsplit(bookmarkView);
|
||||
bookmarkSplitter->Layout();
|
||||
}
|
||||
|
||||
vbox->Add(mainSplitter, 1, wxEXPAND | wxALL, 0);
|
||||
|
||||
|
||||
// TODO: refactor these..
|
||||
waterfallCanvas->attachSpectrumCanvas(spectrumCanvas);
|
||||
spectrumCanvas->attachWaterfallCanvas(waterfallCanvas);
|
||||
@ -378,6 +437,8 @@ AppFrame::AppFrame() :
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
wxGetApp().getDemodMgr().setOutputDevices(outputDevices);
|
||||
//
|
||||
// for (mdevices_i = outputDevices.begin(); mdevices_i != outputDevices.end(); mdevices_i++) {
|
||||
// wxMenuItem *itm = menu->AppendRadioItem(wxID_RT_AUDIO_DEVICE + mdevices_i->first, mdevices_i->second.name, wxT("Description?"));
|
||||
@ -470,6 +531,9 @@ AppFrame::AppFrame() :
|
||||
themeMenu->AppendRadioItem(wxID_THEME_HD, "HD")->Check(themeId==COLOR_THEME_HD);
|
||||
|
||||
displayMenu->AppendSubMenu(themeMenu, wxT("&Color Scheme"));
|
||||
|
||||
hideBookmarksItem = displayMenu->AppendCheckItem(wxID_DISPLAY_BOOKMARKS, wxT("Hide Bookmarks"));
|
||||
hideBookmarksItem->Check(!wxGetApp().getConfig()->getBookmarksVisible());
|
||||
|
||||
GLFont::setScale((GLFont::GLFontScale)fontScale);
|
||||
|
||||
@ -588,13 +652,27 @@ AppFrame::AppFrame() :
|
||||
waterfallCanvas->setLinesPerSecond(wflps);
|
||||
|
||||
ThemeMgr::mgr.setTheme(wxGetApp().getConfig()->getTheme());
|
||||
bookmarkView->updateTheme();
|
||||
|
||||
int mpc =wxGetApp().getConfig()->getModemPropsCollapsed();
|
||||
|
||||
if (mpc) {
|
||||
modemProps->setCollapsed(true);
|
||||
}
|
||||
|
||||
|
||||
int msPos = wxGetApp().getConfig()->getMainSplit();
|
||||
if (msPos != -1) {
|
||||
mainSplitter->SetSashPosition(msPos);
|
||||
}
|
||||
int bsPos = wxGetApp().getConfig()->getBookmarkSplit();
|
||||
if (bsPos != -1) {
|
||||
bookmarkSplitter->SetSashPosition(bsPos);
|
||||
}
|
||||
int vsPos = wxGetApp().getConfig()->getVisSplit();
|
||||
if (vsPos != -1) {
|
||||
mainVisSplitter->SetSashPosition(vsPos);
|
||||
}
|
||||
|
||||
Show();
|
||||
|
||||
#ifdef _WIN32
|
||||
@ -611,6 +689,7 @@ AppFrame::AppFrame() :
|
||||
deviceChanged.store(false);
|
||||
devInfo = NULL;
|
||||
wxGetApp().deviceSelector();
|
||||
saveDisabled = false;
|
||||
|
||||
// static const int attribs[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0 };
|
||||
// wxLogStatus("Double-buffered display %s supported", wxGLCanvas::IsDisplaySupported(attribs) ? "is" : "not");
|
||||
@ -652,6 +731,7 @@ void AppFrame::updateDeviceParams() {
|
||||
|
||||
newSettingsMenu->AppendSeparator();
|
||||
|
||||
newSettingsMenu->Append(wxID_SET_DB_OFFSET, "Power Level Offset");
|
||||
newSettingsMenu->Append(wxID_SET_FREQ_OFFSET, "Frequency Offset");
|
||||
|
||||
if (devInfo->hasCORR(SOAPY_SDR_RX, 0)) {
|
||||
@ -867,6 +947,12 @@ void AppFrame::OnMenu(wxCommandEvent& event) {
|
||||
if (ofs != -1) {
|
||||
wxGetApp().setOffset(ofs);
|
||||
}
|
||||
} else if (event.GetId() == wxID_SET_DB_OFFSET) {
|
||||
long ofs = wxGetNumberFromUser("Shift the displayed RF power level by this amount.\ni.e. -30 for -30 dB", "Decibels (dB)",
|
||||
"Power Level Offset", wxGetApp().getConfig()->getDBOffset(), -1000, 1000, this);
|
||||
if (ofs != -1) {
|
||||
wxGetApp().getConfig()->setDBOffset(ofs);
|
||||
}
|
||||
} else if (event.GetId() == wxID_AGC_CONTROL) {
|
||||
if (wxGetApp().getDevice() == NULL) {
|
||||
agcMenuItem->Check(true);
|
||||
@ -937,6 +1023,9 @@ void AppFrame::OnMenu(wxCommandEvent& event) {
|
||||
demodTuner->Refresh();
|
||||
SetTitle(CUBICSDR_TITLE);
|
||||
currentSessionFile = "";
|
||||
bookmarkSplitter->Unsplit(bookmarkView);
|
||||
bookmarkSplitter->SplitVertically( bookmarkView, mainVisSplitter, wxGetApp().getConfig()->getBookmarkSplit() );
|
||||
hideBookmarksItem->Check(false);
|
||||
} else if (event.GetId() == wxID_CLOSE || event.GetId() == wxID_EXIT) {
|
||||
Close(false);
|
||||
} else if (event.GetId() == wxID_THEME_DEFAULT) {
|
||||
@ -969,6 +1058,14 @@ void AppFrame::OnMenu(wxCommandEvent& event) {
|
||||
GLFont::setScale(GLFont::GLFONT_SCALE_LARGE);
|
||||
//force all windows refresh
|
||||
Refresh();
|
||||
} else if (event.GetId() == wxID_DISPLAY_BOOKMARKS) {
|
||||
if (hideBookmarksItem->IsChecked()) {
|
||||
bookmarkSplitter->Unsplit(bookmarkView);
|
||||
bookmarkSplitter->Layout();
|
||||
} else {
|
||||
bookmarkSplitter->SplitVertically( bookmarkView, mainVisSplitter, wxGetApp().getConfig()->getBookmarkSplit() );
|
||||
bookmarkSplitter->Layout();
|
||||
}
|
||||
}
|
||||
|
||||
if (event.GetId() >= wxID_SETTINGS_BASE && event.GetId() < settingsIdMax) {
|
||||
@ -1029,6 +1126,7 @@ void AppFrame::OnMenu(wxCommandEvent& event) {
|
||||
spectrumAvgMeter->Refresh();
|
||||
gainCanvas->setThemeColors();
|
||||
modemProps->updateTheme();
|
||||
bookmarkView->updateTheme();
|
||||
}
|
||||
|
||||
switch (event.GetId()) {
|
||||
@ -1212,10 +1310,17 @@ void AppFrame::OnMenu(wxCommandEvent& event) {
|
||||
void AppFrame::OnClose(wxCloseEvent& event) {
|
||||
wxGetApp().closeDeviceSelector();
|
||||
|
||||
wxGetApp().getDemodSpectrumProcessor()->removeOutput(demodSpectrumCanvas->getVisualDataQueue());
|
||||
wxGetApp().getDemodSpectrumProcessor()->removeOutput(demodWaterfallCanvas->getVisualDataQueue());
|
||||
if (wxGetApp().getDemodSpectrumProcessor()) {
|
||||
wxGetApp().getDemodSpectrumProcessor()->removeOutput(demodSpectrumCanvas->getVisualDataQueue());
|
||||
wxGetApp().getDemodSpectrumProcessor()->removeOutput(demodWaterfallCanvas->getVisualDataQueue());
|
||||
}
|
||||
wxGetApp().getSpectrumProcessor()->removeOutput(spectrumCanvas->getVisualDataQueue());
|
||||
|
||||
if (saveDisabled) {
|
||||
event.Skip();
|
||||
return;
|
||||
}
|
||||
|
||||
wxGetApp().getConfig()->setWindow(this->GetPosition(), this->GetClientSize());
|
||||
wxGetApp().getConfig()->setWindowMaximized(this->IsMaximized());
|
||||
wxGetApp().getConfig()->setTheme(ThemeMgr::mgr.getTheme());
|
||||
@ -1226,6 +1331,10 @@ void AppFrame::OnClose(wxCloseEvent& event) {
|
||||
wxGetApp().getConfig()->setWaterfallLinesPerSec(waterfallDataThread->getLinesPerSecond());
|
||||
wxGetApp().getConfig()->setManualDevices(SDREnumerator::getManuals());
|
||||
wxGetApp().getConfig()->setModemPropsCollapsed(modemProps->isCollapsed());
|
||||
wxGetApp().getConfig()->setMainSplit(mainSplitter->GetSashPosition());
|
||||
wxGetApp().getConfig()->setVisSplit(mainVisSplitter->GetSashPosition());
|
||||
if (!hideBookmarksItem->IsChecked()) wxGetApp().getConfig()->setBookmarkSplit(bookmarkSplitter->GetSashPosition());
|
||||
wxGetApp().getConfig()->setBookmarksVisible(!hideBookmarksItem->IsChecked());
|
||||
#ifdef USE_HAMLIB
|
||||
wxGetApp().getConfig()->setRigEnabled(rigEnableMenuItem->IsChecked());
|
||||
wxGetApp().getConfig()->setRigModel(rigModel);
|
||||
@ -1237,6 +1346,7 @@ void AppFrame::OnClose(wxCloseEvent& event) {
|
||||
wxGetApp().getConfig()->setRigFollowModem(rigFollowModemMenuItem->IsChecked());
|
||||
#endif
|
||||
wxGetApp().getConfig()->save();
|
||||
wxGetApp().getBookmarkMgr().saveToFile("bookmarks.xml");
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
@ -1244,6 +1354,7 @@ void AppFrame::OnNewWindow(wxCommandEvent& WXUNUSED(event)) {
|
||||
new AppFrame();
|
||||
}
|
||||
|
||||
|
||||
void AppFrame::OnThread(wxCommandEvent& event) {
|
||||
event.Skip();
|
||||
}
|
||||
@ -1284,7 +1395,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
||||
demodGainMeter->setInputValue(demod->getGain());
|
||||
wxGetApp().getDemodMgr().setLastGain(demod->getGain());
|
||||
int outputDevice = demod->getOutputDevice();
|
||||
scopeCanvas->setDeviceName(outputDevices[outputDevice].name);
|
||||
if (scopeCanvas) scopeCanvas->setDeviceName(outputDevices[outputDevice].name);
|
||||
// outputDeviceMenuItems[outputDevice]->Check(true);
|
||||
std::string dType = demod->getDemodulatorType();
|
||||
demodModeSelector->setSelection(dType);
|
||||
@ -1296,7 +1407,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
||||
modemPropertiesUpdated.store(true);
|
||||
demodTuner->setHalfBand(dType=="USB" || dType=="LSB");
|
||||
}
|
||||
if (demodWaterfallCanvas->getDragState() == WaterfallCanvas::WF_DRAG_NONE) {
|
||||
if (!demodWaterfallCanvas || demodWaterfallCanvas->getDragState() == WaterfallCanvas::WF_DRAG_NONE) {
|
||||
long long centerFreq = demod->getFrequency();
|
||||
unsigned int demodBw = (unsigned int) ceil((float) demod->getBandwidth() * 2.25);
|
||||
|
||||
@ -1317,7 +1428,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
||||
demodBw = 20000;
|
||||
}
|
||||
|
||||
if (centerFreq != demodWaterfallCanvas->getCenterFrequency()) {
|
||||
if (demodWaterfallCanvas && centerFreq != demodWaterfallCanvas->getCenterFrequency()) {
|
||||
demodWaterfallCanvas->setCenterFrequency(centerFreq);
|
||||
demodSpectrumCanvas->setCenterFrequency(centerFreq);
|
||||
}
|
||||
@ -1403,8 +1514,10 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
||||
}
|
||||
}
|
||||
|
||||
demodWaterfallCanvas->setBandwidth(demodBw);
|
||||
demodSpectrumCanvas->setBandwidth(demodBw);
|
||||
if (demodWaterfallCanvas) {
|
||||
demodWaterfallCanvas->setBandwidth(demodBw);
|
||||
demodSpectrumCanvas->setBandwidth(demodBw);
|
||||
}
|
||||
}
|
||||
|
||||
demodSignalMeter->setLevel(demod->getSignalLevel());
|
||||
@ -1460,9 +1573,9 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
||||
demodGainMeter->setLevel(demodGainMeter->getInputValue());
|
||||
}
|
||||
|
||||
if (wxGetApp().getFrequency() != demodWaterfallCanvas->getCenterFrequency()) {
|
||||
if (demodWaterfallCanvas && wxGetApp().getFrequency() != demodWaterfallCanvas->getCenterFrequency()) {
|
||||
demodWaterfallCanvas->setCenterFrequency(wxGetApp().getFrequency());
|
||||
demodSpectrumCanvas->setCenterFrequency(wxGetApp().getFrequency());
|
||||
if (demodSpectrumCanvas) demodSpectrumCanvas->setCenterFrequency(wxGetApp().getFrequency());
|
||||
}
|
||||
if (spectrumCanvas->getViewState() && abs(wxGetApp().getFrequency()-spectrumCanvas->getCenterFrequency()) > (wxGetApp().getSampleRate()/2)) {
|
||||
spectrumCanvas->setCenterFrequency(wxGetApp().getFrequency());
|
||||
@ -1479,15 +1592,17 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
||||
}
|
||||
}
|
||||
|
||||
scopeCanvas->setPPMMode(demodTuner->isAltDown());
|
||||
if (scopeCanvas) {
|
||||
scopeCanvas->setPPMMode(demodTuner->isAltDown());
|
||||
|
||||
scopeCanvas->setShowDb(spectrumCanvas->getShowDb());
|
||||
wxGetApp().getScopeProcessor()->setScopeEnabled(scopeCanvas->scopeVisible());
|
||||
wxGetApp().getScopeProcessor()->setSpectrumEnabled(scopeCanvas->spectrumVisible());
|
||||
wxGetApp().getAudioVisualQueue()->set_max_num_items((scopeCanvas->scopeVisible()?1:0) + (scopeCanvas->spectrumVisible()?1:0));
|
||||
|
||||
wxGetApp().getScopeProcessor()->run();
|
||||
}
|
||||
|
||||
scopeCanvas->setShowDb(spectrumCanvas->getShowDb());
|
||||
wxGetApp().getScopeProcessor()->setScopeEnabled(scopeCanvas->scopeVisible());
|
||||
wxGetApp().getScopeProcessor()->setSpectrumEnabled(scopeCanvas->spectrumVisible());
|
||||
wxGetApp().getAudioVisualQueue()->set_max_num_items((scopeCanvas->scopeVisible()?1:0) + (scopeCanvas->spectrumVisible()?1:0));
|
||||
|
||||
wxGetApp().getScopeProcessor()->run();
|
||||
|
||||
SpectrumVisualProcessor *proc = wxGetApp().getSpectrumProcessor();
|
||||
|
||||
if (spectrumAvgMeter->inputChanged()) {
|
||||
@ -1505,9 +1620,11 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
||||
}
|
||||
|
||||
SpectrumVisualProcessor *dproc = wxGetApp().getDemodSpectrumProcessor();
|
||||
|
||||
dproc->setView(demodWaterfallCanvas->getViewState(), demodWaterfallCanvas->getCenterFrequency(),demodWaterfallCanvas->getBandwidth());
|
||||
|
||||
if (dproc) {
|
||||
dproc->setView(demodWaterfallCanvas->getViewState(), demodWaterfallCanvas->getCenterFrequency(),demodWaterfallCanvas->getBandwidth());
|
||||
}
|
||||
|
||||
SpectrumVisualProcessor *wproc = waterfallDataThread->getProcessor();
|
||||
|
||||
if (waterfallSpeedMeter->inputChanged()) {
|
||||
@ -1539,13 +1656,15 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
||||
ModemDigitalOutputConsole *outp = (ModemDigitalOutputConsole *)demod->getOutput();
|
||||
if (!outp->getDialog()) {
|
||||
outp->setTitle(demod->getDemodulatorType() + ": " + frequencyToStr(demod->getFrequency()));
|
||||
outp->setDialog(new DigitalConsole(this, outp));
|
||||
outp->setDialog(new DigitalConsole(this, outp)) ;
|
||||
}
|
||||
demod->showOutput();
|
||||
}
|
||||
#endif
|
||||
} else if (!demod) {
|
||||
modemProps->Hide();
|
||||
} else if (!demod && modemPropertiesUpdated.load()) {
|
||||
ModemArgInfoList dummyInfo;
|
||||
modemProps->initProperties(dummyInfo, nullptr);
|
||||
modemProps->updateTheme();
|
||||
demodTray->Layout();
|
||||
}
|
||||
|
||||
@ -1566,7 +1685,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
||||
wxGetApp().getSpectrumProcessor()->setPeakHold(peakHoldMode == 1);
|
||||
|
||||
//make the peak hold act on the current dmod also, like a zoomed-in version.
|
||||
wxGetApp().getDemodSpectrumProcessor()->setPeakHold(peakHoldMode == 1);
|
||||
if (wxGetApp().getDemodSpectrumProcessor()) wxGetApp().getDemodSpectrumProcessor()->setPeakHold(peakHoldMode == 1);
|
||||
peakHoldButton->clearModeChanged();
|
||||
}
|
||||
|
||||
@ -1580,7 +1699,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
if (scopeCanvas->HasFocus()) {
|
||||
if (scopeCanvas && scopeCanvas->HasFocus()) {
|
||||
waterfallCanvas->SetFocus();
|
||||
}
|
||||
#endif
|
||||
@ -1652,35 +1771,10 @@ void AppFrame::saveSession(std::string fileName) {
|
||||
DataNode *demods = s.rootNode()->newChild("demodulators");
|
||||
|
||||
std::vector<DemodulatorInstance *> &instances = wxGetApp().getDemodMgr().getDemodulators();
|
||||
std::vector<DemodulatorInstance *>::iterator instance_i;
|
||||
for (instance_i = instances.begin(); instance_i != instances.end(); instance_i++) {
|
||||
|
||||
for (auto instance_i : instances) {
|
||||
DataNode *demod = demods->newChild("demodulator");
|
||||
*demod->newChild("bandwidth") = (*instance_i)->getBandwidth();
|
||||
*demod->newChild("frequency") = (*instance_i)->getFrequency();
|
||||
*demod->newChild("type") = (*instance_i)->getDemodulatorType();
|
||||
|
||||
demod->newChild("user_label")->element()->set((*instance_i)->getDemodulatorUserLabel());
|
||||
|
||||
*demod->newChild("squelch_level") = (*instance_i)->getSquelchLevel();
|
||||
*demod->newChild("squelch_enabled") = (*instance_i)->isSquelchEnabled() ? 1 : 0;
|
||||
*demod->newChild("output_device") = outputDevices[(*instance_i)->getOutputDevice()].name;
|
||||
*demod->newChild("gain") = (*instance_i)->getGain();
|
||||
*demod->newChild("muted") = (*instance_i)->isMuted() ? 1 : 0;
|
||||
if ((*instance_i)->isDeltaLock()) {
|
||||
*demod->newChild("delta_lock") = (*instance_i)->isDeltaLock() ? 1 : 0;
|
||||
*demod->newChild("delta_ofs") = (*instance_i)->getDeltaLockOfs();
|
||||
}
|
||||
if ((*instance_i) == wxGetApp().getDemodMgr().getLastActiveDemodulator()) {
|
||||
*demod->newChild("active") = 1;
|
||||
}
|
||||
|
||||
ModemSettings saveSettings = (*instance_i)->readModemSettings();
|
||||
if (saveSettings.size()) {
|
||||
DataNode *settingsNode = demod->newChild("settings");
|
||||
for (ModemSettings::const_iterator msi = saveSettings.begin(); msi != saveSettings.end(); msi++) {
|
||||
*settingsNode->newChild(msi->first.c_str()) = msi->second;
|
||||
}
|
||||
}
|
||||
wxGetApp().getDemodMgr().saveInstance(demod, instance_i);
|
||||
} //end for demodulators
|
||||
|
||||
// Make sure the file name actually ends in .xml
|
||||
@ -1754,7 +1848,6 @@ bool AppFrame::loadSession(std::string fileName) {
|
||||
|
||||
DataNode *demodulators = l.rootNode()->getNext("demodulators");
|
||||
|
||||
int numDemodulators = 0;
|
||||
std::vector<DemodulatorInstance *> demodsLoaded;
|
||||
|
||||
while (demodulators->hasAnother("demodulator")) {
|
||||
@ -1764,122 +1857,15 @@ bool AppFrame::loadSession(std::string fileName) {
|
||||
continue;
|
||||
}
|
||||
|
||||
long bandwidth = *demod->getNext("bandwidth");
|
||||
long long freq = *demod->getNext("frequency");
|
||||
float squelch_level = demod->hasAnother("squelch_level") ? (float) *demod->getNext("squelch_level") : 0;
|
||||
int squelch_enabled = demod->hasAnother("squelch_enabled") ? (int) *demod->getNext("squelch_enabled") : 0;
|
||||
int muted = demod->hasAnother("muted") ? (int) *demod->getNext("muted") : 0;
|
||||
int delta_locked = demod->hasAnother("delta_lock") ? (int) *demod->getNext("delta_lock") : 0;
|
||||
int delta_ofs = demod->hasAnother("delta_ofs") ? (int) *demod->getNext("delta_ofs") : 0;
|
||||
std::string output_device = demod->hasAnother("output_device") ? string(*(demod->getNext("output_device"))) : "";
|
||||
float gain = demod->hasAnother("gain") ? (float) *demod->getNext("gain") : 1.0;
|
||||
newDemod = wxGetApp().getDemodMgr().loadInstance(demod);
|
||||
|
||||
std::string type = "FM";
|
||||
|
||||
|
||||
DataNode *demodTypeNode = demod->hasAnother("type")?demod->getNext("type"):nullptr;
|
||||
|
||||
if (demodTypeNode && demodTypeNode->element()->getDataType() == DATA_INT) {
|
||||
int legacyType = *demodTypeNode;
|
||||
int legacyStereo = demod->hasAnother("stereo") ? (int) *demod->getNext("stereo") : 0;
|
||||
switch (legacyType) { // legacy demod ID
|
||||
case 1: type = legacyStereo?"FMS":"FM"; break;
|
||||
case 2: type = "AM"; break;
|
||||
case 3: type = "LSB"; break;
|
||||
case 4: type = "USB"; break;
|
||||
case 5: type = "DSB"; break;
|
||||
case 6: type = "ASK"; break;
|
||||
case 7: type = "APSK"; break;
|
||||
case 8: type = "BPSK"; break;
|
||||
case 9: type = "DPSK"; break;
|
||||
case 10: type = "PSK"; break;
|
||||
case 11: type = "OOK"; break;
|
||||
case 12: type = "ST"; break;
|
||||
case 13: type = "SQAM"; break;
|
||||
case 14: type = "QAM"; break;
|
||||
case 15: type = "QPSK"; break;
|
||||
case 16: type = "I/Q"; break;
|
||||
default: type = "FM"; break;
|
||||
}
|
||||
} else if (demodTypeNode && demodTypeNode->element()->getDataType() == DATA_STRING) {
|
||||
demodTypeNode->element()->get(type);
|
||||
}
|
||||
|
||||
//read the user label associated with the demodulator
|
||||
std::wstring user_label = L"";
|
||||
|
||||
DataNode *demodUserLabel = demod->hasAnother("user_label") ? demod->getNext("user_label") : nullptr;
|
||||
|
||||
if (demodUserLabel) {
|
||||
|
||||
demodUserLabel->element()->get(user_label);
|
||||
}
|
||||
|
||||
|
||||
ModemSettings mSettings;
|
||||
|
||||
if (demod->hasAnother("settings")) {
|
||||
DataNode *modemSettings = demod->getNext("settings");
|
||||
for (int msi = 0, numSettings = modemSettings->numChildren(); msi < numSettings; msi++) {
|
||||
DataNode *settingNode = modemSettings->child(msi);
|
||||
std::string keyName = settingNode->getName();
|
||||
std::string strSettingValue = settingNode->element()->toString();
|
||||
|
||||
if (keyName != "" && strSettingValue != "") {
|
||||
mSettings[keyName] = strSettingValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
newDemod = wxGetApp().getDemodMgr().newThread();
|
||||
|
||||
if (demod->hasAnother("active")) {
|
||||
loadedActiveDemod = newDemod;
|
||||
}
|
||||
|
||||
numDemodulators++;
|
||||
newDemod->setDemodulatorType(type);
|
||||
newDemod->setDemodulatorUserLabel(user_label);
|
||||
newDemod->writeModemSettings(mSettings);
|
||||
newDemod->setBandwidth(bandwidth);
|
||||
newDemod->setFrequency(freq);
|
||||
newDemod->setGain(gain);
|
||||
newDemod->updateLabel(freq);
|
||||
newDemod->setMuted(muted?true:false);
|
||||
if (delta_locked) {
|
||||
newDemod->setDeltaLock(true);
|
||||
newDemod->setDeltaLockOfs(delta_ofs);
|
||||
}
|
||||
if (squelch_enabled) {
|
||||
newDemod->setSquelchEnabled(true);
|
||||
newDemod->setSquelchLevel(squelch_level);
|
||||
}
|
||||
|
||||
bool found_device = false;
|
||||
std::map<int, RtAudio::DeviceInfo>::iterator i;
|
||||
for (i = outputDevices.begin(); i != outputDevices.end(); i++) {
|
||||
if (i->second.name == output_device) {
|
||||
newDemod->setOutputDevice(i->first);
|
||||
found_device = true;
|
||||
}
|
||||
}
|
||||
|
||||
// if (!found_device) {
|
||||
// std::cout << "\tWarning: named output device '" << output_device << "' was not found. Using default output.";
|
||||
// }
|
||||
|
||||
newDemod->run();
|
||||
newDemod->setActive(true);
|
||||
demodsLoaded.push_back(newDemod);
|
||||
// wxGetApp().bindDemodulator(newDemod);
|
||||
|
||||
std::cout << "\tAdded demodulator at frequency " << newDemod->getFrequency() << " type " << type << std::endl;
|
||||
// std::cout << "\t\tBandwidth: " << bandwidth << std::endl;
|
||||
// std::cout << "\t\tSquelch Level: " << squelch_level << std::endl;
|
||||
// std::cout << "\t\tSquelch Enabled: " << (squelch_enabled ? "true" : "false") << std::endl;
|
||||
// std::cout << "\t\tOutput Device: " << output_device << std::endl;
|
||||
}
|
||||
|
||||
if (demodsLoaded.size()) {
|
||||
@ -1925,6 +1911,8 @@ bool AppFrame::loadSession(std::string fileName) {
|
||||
GetStatusBar()->SetStatusText(wxString::Format(wxT("Loaded session file: %s"), currentSessionFile.c_str()));
|
||||
SetTitle(wxString::Format(wxT("%s: %s"), CUBICSDR_TITLE, filePart.c_str()));
|
||||
|
||||
wxGetApp().getBookmarkMgr().updateActiveList();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1945,7 +1933,7 @@ void AppFrame::setMainWaterfallFFTSize(int fftSize) {
|
||||
}
|
||||
|
||||
void AppFrame::setScopeDeviceName(std::string deviceName) {
|
||||
scopeCanvas->setDeviceName(deviceName);
|
||||
if (scopeCanvas) scopeCanvas->setDeviceName(deviceName);
|
||||
}
|
||||
|
||||
|
||||
@ -1957,12 +1945,20 @@ void AppFrame::refreshGainUI() {
|
||||
bool AppFrame::isUserDemodBusy() {
|
||||
return (modemProps && modemProps->isMouseInView())
|
||||
|| (waterfallCanvas->isMouseInView() && waterfallCanvas->isMouseDown())
|
||||
|| (demodWaterfallCanvas->isMouseInView() && demodWaterfallCanvas->isMouseDown())
|
||||
|| (demodWaterfallCanvas && demodWaterfallCanvas->isMouseInView() && demodWaterfallCanvas->isMouseDown())
|
||||
|| (wxGetApp().getDemodMgr().getLastActiveDemodulator() &&
|
||||
wxGetApp().getDemodMgr().getActiveDemodulator() &&
|
||||
wxGetApp().getDemodMgr().getLastActiveDemodulator() != wxGetApp().getDemodMgr().getActiveDemodulator());
|
||||
}
|
||||
|
||||
BookmarkView *AppFrame::getBookmarkView() {
|
||||
return bookmarkView;
|
||||
}
|
||||
|
||||
void AppFrame::disableSave(bool state) {
|
||||
saveDisabled = state;
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
bool AppFrame::canFocus() {
|
||||
@ -2022,6 +2018,10 @@ int AppFrame::OnGlobalKeyDown(wxKeyEvent &event) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bookmarkView && bookmarkView->isMouseInView()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
DemodulatorInstance *demod = nullptr, *lastDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
|
||||
int snap = wxGetApp().getFrequencySnap();
|
||||
|
||||
@ -2123,6 +2123,10 @@ int AppFrame::OnGlobalKeyUp(wxKeyEvent &event) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bookmarkView && bookmarkView->isMouseInView()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (event.ControlDown()) {
|
||||
return 1;
|
||||
}
|
||||
@ -2195,7 +2199,7 @@ int AppFrame::OnGlobalKeyUp(wxKeyEvent &event) {
|
||||
break;
|
||||
case 'P':
|
||||
wxGetApp().getSpectrumProcessor()->setPeakHold(!wxGetApp().getSpectrumProcessor()->getPeakHold());
|
||||
wxGetApp().getDemodSpectrumProcessor()->setPeakHold(wxGetApp().getSpectrumProcessor()->getPeakHold());
|
||||
if (wxGetApp().getDemodSpectrumProcessor()) wxGetApp().getDemodSpectrumProcessor()->setPeakHold(wxGetApp().getSpectrumProcessor()->getPeakHold());
|
||||
peakHoldButton->setSelection(wxGetApp().getSpectrumProcessor()->getPeakHold()?1:0);
|
||||
peakHoldButton->clearModeChanged();
|
||||
break;
|
||||
@ -2246,3 +2250,42 @@ void AppFrame::setViewState(long long center_freq) {
|
||||
spectrumCanvas->disableView();
|
||||
waterfallCanvas->disableView();
|
||||
}
|
||||
|
||||
|
||||
long long AppFrame::getViewCenterFreq() {
|
||||
return waterfallCanvas->getCenterFrequency();
|
||||
|
||||
}
|
||||
|
||||
|
||||
int AppFrame::getViewBandwidth() {
|
||||
return waterfallCanvas->getBandwidth();
|
||||
}
|
||||
|
||||
|
||||
/* split a string by 'seperator' into a vector of string */
|
||||
std::vector<std::string> str_explode(const std::string &seperator, const std::string &in_str)
|
||||
{
|
||||
std::vector<std::string> vect_out;
|
||||
|
||||
int i = 0, j = 0;
|
||||
int seperator_len = seperator.length();
|
||||
int str_len = in_str.length();
|
||||
|
||||
while(i < str_len)
|
||||
{
|
||||
j = in_str.find_first_of(seperator,i);
|
||||
|
||||
if (j == std::string::npos && i < str_len) j = str_len;
|
||||
|
||||
if (j == std::string::npos) break;
|
||||
|
||||
vect_out.push_back(in_str.substr(i,j-i));
|
||||
|
||||
i = j;
|
||||
|
||||
i+=seperator_len;
|
||||
}
|
||||
|
||||
return vect_out;
|
||||
}
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include <wx/panel.h>
|
||||
#include <wx/splitter.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/statbmp.h>
|
||||
|
||||
#include "PrimaryGLContext.h"
|
||||
|
||||
@ -22,6 +24,7 @@
|
||||
#include "ModemProperties.h"
|
||||
//#include "UITestCanvas.h"
|
||||
#include "FrequencyDialog.h"
|
||||
#include "BookmarkView.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
@ -35,9 +38,11 @@
|
||||
#define wxID_AGC_CONTROL 2009
|
||||
#define wxID_SDR_START_STOP 2010
|
||||
#define wxID_LOW_PERF 2011
|
||||
#define wxID_SET_DB_OFFSET 2012
|
||||
|
||||
#define wxID_MAIN_SPLITTER 2050
|
||||
#define wxID_VIS_SPLITTER 2051
|
||||
#define wxID_BM_SPLITTER 2052
|
||||
|
||||
#define wxID_THEME_DEFAULT 2100
|
||||
#define wxID_THEME_SHARP 2101
|
||||
@ -47,6 +52,8 @@
|
||||
#define wxID_THEME_HD 2105
|
||||
#define wxID_THEME_RADAR 2106
|
||||
|
||||
#define wxID_DISPLAY_BOOKMARKS 2107
|
||||
|
||||
#define wxID_BANDWIDTH_BASE 2150
|
||||
#define wxID_BANDWIDTH_MANUAL 2200
|
||||
|
||||
@ -76,6 +83,7 @@ class AppFrame: public wxFrame {
|
||||
public:
|
||||
AppFrame();
|
||||
~AppFrame();
|
||||
|
||||
void OnThread(wxCommandEvent& event);
|
||||
void OnEventInput(wxThreadEvent& event);
|
||||
void initDeviceParams(SDRDeviceInfo *devInfo);
|
||||
@ -103,9 +111,14 @@ public:
|
||||
void refreshGainUI();
|
||||
void setViewState(long long center_freq, int bandwidth);
|
||||
void setViewState(long long center_freq);
|
||||
|
||||
|
||||
long long getViewCenterFreq();
|
||||
int getViewBandwidth();
|
||||
bool isUserDemodBusy();
|
||||
|
||||
|
||||
BookmarkView *getBookmarkView();
|
||||
void disableSave(bool state);
|
||||
|
||||
#ifdef _WIN32
|
||||
bool canFocus();
|
||||
#endif
|
||||
@ -136,8 +149,9 @@ private:
|
||||
ModeSelectorCanvas *demodMuteButton, *peakHoldButton, *soloModeButton, *deltaLockButton;
|
||||
GainCanvas *gainCanvas;
|
||||
wxSizerItem *gainSizerItem, *gainSpacerItem;
|
||||
wxSplitterWindow *mainVisSplitter, *mainSplitter;
|
||||
wxSplitterWindow *mainVisSplitter, *mainSplitter, *bookmarkSplitter;
|
||||
wxBoxSizer *demodTray;
|
||||
BookmarkView *bookmarkView;
|
||||
|
||||
DemodulatorInstance *activeDemodulator;
|
||||
|
||||
@ -174,7 +188,7 @@ private:
|
||||
wxMenuItem *showTipMenuItem;
|
||||
|
||||
bool lowPerfMode;
|
||||
|
||||
|
||||
#ifdef USE_HAMLIB
|
||||
void enableRig();
|
||||
void disableRig();
|
||||
@ -187,6 +201,7 @@ private:
|
||||
wxMenuItem *rigCenterLockMenuItem;
|
||||
wxMenuItem *rigFollowModemMenuItem;
|
||||
wxMenuItem *sdrIFMenuItem;
|
||||
wxMenuItem *hideBookmarksItem;
|
||||
std::map<int, wxMenuItem *> rigSerialMenuItems;
|
||||
std::map<int, wxMenuItem *> rigModelMenuItems;
|
||||
int rigModel;
|
||||
@ -196,6 +211,7 @@ private:
|
||||
std::string rigPort;
|
||||
int numRigs;
|
||||
bool rigInit;
|
||||
bool saveDisabled;
|
||||
#endif
|
||||
|
||||
wxDECLARE_EVENT_TABLE();
|
||||
|
521
src/BookmarkMgr.cpp
Normal file
521
src/BookmarkMgr.cpp
Normal file
@ -0,0 +1,521 @@
|
||||
#include "BookmarkMgr.h"
|
||||
#include "CubicSDR.h"
|
||||
#include "DataTree.h"
|
||||
|
||||
#define BOOKMARK_RECENTS_MAX 25
|
||||
|
||||
BookmarkMgr::BookmarkMgr() {
|
||||
rangesSorted = false;
|
||||
}
|
||||
|
||||
void BookmarkMgr::saveToFile(std::string bookmarkFn, bool backup) {
|
||||
DataTree s("cubicsdr_bookmarks");
|
||||
DataNode *header = s.rootNode()->newChild("header");
|
||||
header->newChild("version")->element()->set(wxString(CUBICSDR_VERSION).ToStdWstring());
|
||||
|
||||
DataNode *branches = s.rootNode()->newChild("branches");
|
||||
|
||||
*branches->newChild("active") = wxGetApp().getAppFrame()->getBookmarkView()->getExpandState("active")?1:0;
|
||||
*branches->newChild("range") = wxGetApp().getAppFrame()->getBookmarkView()->getExpandState("range")?1:0;
|
||||
*branches->newChild("bookmark") = wxGetApp().getAppFrame()->getBookmarkView()->getExpandState("bookmark")?1:0;
|
||||
*branches->newChild("recent") = wxGetApp().getAppFrame()->getBookmarkView()->getExpandState("recent")?1:0;
|
||||
|
||||
DataNode *view_ranges = s.rootNode()->newChild("ranges");
|
||||
|
||||
for (auto re_i : ranges) {
|
||||
DataNode *range = view_ranges->newChild("range");
|
||||
*range->newChild("label") = re_i->label;
|
||||
*range->newChild("freq") = re_i->freq;
|
||||
*range->newChild("start") = re_i->startFreq;
|
||||
*range->newChild("end") = re_i->endFreq;
|
||||
}
|
||||
|
||||
DataNode *modems = s.rootNode()->newChild("modems");
|
||||
|
||||
for (auto &bmd_i : bmData) {
|
||||
DataNode *group = modems->newChild("group");
|
||||
*group->newChild("@name") = bmd_i.first;
|
||||
*group->newChild("@expanded") = (getExpandState(bmd_i.first)?std::string("true"):std::string("false"));
|
||||
|
||||
for (auto &bm_i : bmd_i.second ) {
|
||||
group->newChildCloneFrom("modem", bm_i->node);
|
||||
}
|
||||
}
|
||||
|
||||
DataNode *recent_modems = s.rootNode()->newChild("recent_modems");
|
||||
|
||||
for (auto demod : wxGetApp().getDemodMgr().getDemodulators()) {
|
||||
wxGetApp().getDemodMgr().saveInstance(recent_modems->newChild("modem"),demod);
|
||||
}
|
||||
|
||||
for (auto &r_i : this->recents) {
|
||||
recent_modems->newChildCloneFrom("modem", r_i->node);
|
||||
}
|
||||
|
||||
wxFileName saveFile(wxGetApp().getConfig()->getConfigDir(), bookmarkFn);
|
||||
wxFileName saveFileBackup(wxGetApp().getConfig()->getConfigDir(), bookmarkFn + ".backup");
|
||||
|
||||
if (saveFile.IsDirWritable()) {
|
||||
// Hopefully leave at least a readable backup in case of failure..
|
||||
if (backup && saveFile.FileExists() && (!saveFileBackup.FileExists() || saveFileBackup.IsFileWritable())) {
|
||||
wxCopyFile(saveFile.GetFullPath(wxPATH_NATIVE).ToStdString(), saveFileBackup.GetFullPath(wxPATH_NATIVE).ToStdString());
|
||||
}
|
||||
s.SaveToFileXML(saveFile.GetFullPath(wxPATH_NATIVE).ToStdString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool BookmarkMgr::loadFromFile(std::string bookmarkFn, bool backup) {
|
||||
wxFileName loadFile(wxGetApp().getConfig()->getConfigDir(), bookmarkFn);
|
||||
wxFileName failFile(wxGetApp().getConfig()->getConfigDir(), bookmarkFn + ".failedload");
|
||||
wxFileName lastLoaded(wxGetApp().getConfig()->getConfigDir(), bookmarkFn + ".lastloaded");
|
||||
wxFileName backupFile(wxGetApp().getConfig()->getConfigDir(), bookmarkFn + ".backup");
|
||||
|
||||
DataTree s;
|
||||
bool loadStatusOk = true;
|
||||
|
||||
// Clear any active data
|
||||
bmData.erase(bmData.begin(),bmData.end());
|
||||
recents.erase(recents.begin(),recents.end());
|
||||
ranges.erase(ranges.begin(),ranges.end());
|
||||
bmDataSorted.erase(bmDataSorted.begin(),bmDataSorted.end());
|
||||
|
||||
// File exists but is not readable
|
||||
if (loadFile.FileExists() && !loadFile.IsFileReadable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// New instance of bookmark savefiles
|
||||
if (backup && !loadFile.FileExists() && !lastLoaded.FileExists() && !backupFile.FileExists()) {
|
||||
wxGetApp().getAppFrame()->getBookmarkView()->loadDefaultRanges();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Attempt to load file
|
||||
if (!s.LoadFromFileXML(loadFile.GetFullPath(wxPATH_NATIVE).ToStdString())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s.rootNode()->hasAnother("branches")) {
|
||||
DataNode *branches = s.rootNode()->getNext("branches");
|
||||
int bActive = 1, bRange = 0, bBookmark = 1, bRecent = 1;
|
||||
if (branches->hasAnother("active")) branches->getNext("active")->element()->get(bActive);
|
||||
if (branches->hasAnother("range")) branches->getNext("range")->element()->get(bRange);
|
||||
if (branches->hasAnother("bookmark")) branches->getNext("bookmark")->element()->get(bBookmark);
|
||||
if (branches->hasAnother("recent")) branches->getNext("recent")->element()->get(bRecent);
|
||||
wxGetApp().getAppFrame()->getBookmarkView()->setExpandState("active", bActive?true:false);
|
||||
wxGetApp().getAppFrame()->getBookmarkView()->setExpandState("range", bRange?true:false);
|
||||
wxGetApp().getAppFrame()->getBookmarkView()->setExpandState("bookmark", bBookmark?true:false);
|
||||
wxGetApp().getAppFrame()->getBookmarkView()->setExpandState("recent", bRecent?true:false);
|
||||
}
|
||||
|
||||
if (s.rootNode()->hasAnother("ranges")) {
|
||||
DataNode *view_ranges = s.rootNode()->getNext("ranges");
|
||||
while (view_ranges->hasAnother("range")) {
|
||||
DataNode *range = view_ranges->getNext("range");
|
||||
|
||||
BookmarkRangeEntry *re = new BookmarkRangeEntry;
|
||||
|
||||
if (range->hasAnother("label")) range->getNext("label")->element()->get(re->label);
|
||||
if (range->hasAnother("freq")) range->getNext("freq")->element()->get(re->freq);
|
||||
if (range->hasAnother("start")) range->getNext("start")->element()->get(re->startFreq);
|
||||
if (range->hasAnother("end")) range->getNext("end")->element()->get(re->endFreq);
|
||||
|
||||
addRange(re);
|
||||
}
|
||||
}
|
||||
|
||||
if (s.rootNode()->hasAnother("modems")) {
|
||||
DataNode *modems = s.rootNode()->getNext("modems");
|
||||
while (modems->hasAnother("group")) {
|
||||
DataNode *group = modems->getNext("group");
|
||||
std::string expandState = "true";
|
||||
std::string groupName = "Unnamed";
|
||||
if (group->hasAnother("@name")) {
|
||||
groupName = group->getNext("@name")->element()->toString();
|
||||
}
|
||||
if (group->hasAnother("@expanded")) {
|
||||
expandState = group->getNext("@expanded")->element()->toString();
|
||||
}
|
||||
setExpandState(groupName, (expandState == "true"));
|
||||
while (group->hasAnother("modem")) {
|
||||
DataNode *modem = group->getNext("modem");
|
||||
BookmarkEntry *be = nodeToBookmark("modem", modem);
|
||||
if (be) {
|
||||
addBookmark(groupName.c_str(), be);
|
||||
} else {
|
||||
std::cout << "error loading bookmarked modem.." << std::endl;
|
||||
loadStatusOk = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (s.rootNode()->hasAnother("recent_modems")) {
|
||||
DataNode *recent_modems = s.rootNode()->getNext("recent_modems");
|
||||
|
||||
while (recent_modems->hasAnother("modem")) {
|
||||
DataNode *modem = recent_modems->getNext("modem");
|
||||
BookmarkEntry *be = nodeToBookmark("modem", modem);
|
||||
if (be) {
|
||||
addRecent(be);
|
||||
} else {
|
||||
std::cout << "error loading recent modem.." << std::endl;
|
||||
loadStatusOk = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (backup) {
|
||||
if (loadStatusOk) { // Loaded OK; keep a copy
|
||||
if (loadFile.IsDirWritable()) {
|
||||
if (loadFile.FileExists() && (!lastLoaded.FileExists() || lastLoaded.IsFileWritable())) {
|
||||
wxCopyFile(loadFile.GetFullPath(wxPATH_NATIVE).ToStdString(), lastLoaded.GetFullPath(wxPATH_NATIVE).ToStdString());
|
||||
}
|
||||
}
|
||||
} else if (!loadStatusOk) {
|
||||
if (loadFile.IsDirWritable()) { // Load failed; keep a copy of the failed bookmark file for analysis?
|
||||
if (loadFile.FileExists() && (!failFile.FileExists() || failFile.IsFileWritable())) {
|
||||
wxCopyFile(loadFile.GetFullPath(wxPATH_NATIVE).ToStdString(), failFile.GetFullPath(wxPATH_NATIVE).ToStdString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return loadStatusOk;
|
||||
}
|
||||
|
||||
|
||||
bool BookmarkMgr::hasLastLoad(std::string bookmarkFn) {
|
||||
wxFileName lastLoaded(wxGetApp().getConfig()->getConfigDir(), bookmarkFn + ".lastloaded");
|
||||
return lastLoaded.FileExists() && lastLoaded.IsFileReadable();
|
||||
}
|
||||
|
||||
bool BookmarkMgr::hasBackup(std::string bookmarkFn) {
|
||||
wxFileName backupFile(wxGetApp().getConfig()->getConfigDir(), bookmarkFn + ".backup");
|
||||
return backupFile.FileExists() && backupFile.IsFileReadable();
|
||||
}
|
||||
|
||||
void BookmarkMgr::addBookmark(std::string group, DemodulatorInstance *demod) {
|
||||
std::lock_guard < std::mutex > lock(busy_lock);
|
||||
|
||||
BookmarkEntry *be = demodToBookmarkEntry(demod);
|
||||
|
||||
wxGetApp().getDemodMgr().saveInstance(be->node, demod);
|
||||
|
||||
bmData[group].push_back(be);
|
||||
bmDataSorted[group] = false;
|
||||
}
|
||||
|
||||
void BookmarkMgr::addBookmark(std::string group, BookmarkEntry *be) {
|
||||
std::lock_guard < std::mutex > lock(busy_lock);
|
||||
|
||||
bmData[group].push_back(be);
|
||||
bmDataSorted[group] = false;
|
||||
}
|
||||
|
||||
|
||||
void BookmarkMgr::removeBookmark(std::string group, BookmarkEntry *be) {
|
||||
std::lock_guard < std::mutex > lockData(busy_lock);
|
||||
std::lock_guard < std::mutex > lockEnt(be->busy_lock);
|
||||
|
||||
if (bmData.find(group) == bmData.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
BookmarkList::iterator i = std::find(bmData[group].begin(), bmData[group].end(), be);
|
||||
|
||||
if (i != bmData[group].end()) {
|
||||
delete *i;
|
||||
bmData[group].erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
void BookmarkMgr::removeBookmark(BookmarkEntry *be) {
|
||||
std::lock_guard < std::mutex > lockData(busy_lock);
|
||||
std::lock_guard < std::mutex > lockEnt(be->busy_lock);
|
||||
|
||||
for (auto &bmd_i : bmData) {
|
||||
BookmarkList::iterator i = std::find(bmd_i.second.begin(), bmd_i.second.end(), be);
|
||||
if (i != bmd_i.second.end()) {
|
||||
bmd_i.second.erase(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BookmarkMgr::moveBookmark(BookmarkEntry *be, std::string group) {
|
||||
std::lock_guard < std::mutex > lockData(busy_lock);
|
||||
std::lock_guard < std::mutex > lockEnt(be->busy_lock);
|
||||
|
||||
for (auto &bmd_i : bmData) {
|
||||
BookmarkList::iterator i = std::find(bmd_i.second.begin(), bmd_i.second.end(), be);
|
||||
if (i != bmd_i.second.end()) {
|
||||
if (bmd_i.first == group) {
|
||||
return;
|
||||
}
|
||||
bmData[group].push_back(*i);
|
||||
bmd_i.second.erase(i);
|
||||
bmDataSorted[group] = false;
|
||||
bmDataSorted[bmd_i.first] = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BookmarkMgr::addGroup(std::string group) {
|
||||
std::lock_guard < std::mutex > lock(busy_lock);
|
||||
|
||||
if (bmData.find(group) == bmData.end()) {
|
||||
BookmarkList dummy = bmData[group];
|
||||
}
|
||||
}
|
||||
|
||||
void BookmarkMgr::removeGroup(std::string group) {
|
||||
std::lock_guard < std::mutex > lock(busy_lock);
|
||||
|
||||
BookmarkMap::iterator i = bmData.find(group);
|
||||
|
||||
if (i != bmData.end()) {
|
||||
for (auto ii : bmData[group]) {
|
||||
delete ii;
|
||||
}
|
||||
bmData.erase(group);
|
||||
}
|
||||
}
|
||||
|
||||
void BookmarkMgr::renameGroup(std::string group, std::string ngroup) {
|
||||
if (group == ngroup) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard < std::mutex > lock(busy_lock);
|
||||
|
||||
BookmarkMap::iterator i = bmData.find(group);
|
||||
BookmarkMap::iterator it = bmData.find(ngroup);
|
||||
|
||||
if (i != bmData.end() && it != bmData.end()) {
|
||||
for (auto ii : bmData[group]) {
|
||||
bmData[ngroup].push_back(ii);
|
||||
}
|
||||
bmData.erase(group);
|
||||
} else if (i != bmData.end()) {
|
||||
bmData[ngroup] = bmData[group];
|
||||
bmData.erase(group);
|
||||
}
|
||||
}
|
||||
|
||||
BookmarkList BookmarkMgr::getBookmarks(std::string group) {
|
||||
std::lock_guard < std::mutex > lock(busy_lock);
|
||||
|
||||
if (bmData.find(group) == bmData.end()) {
|
||||
BookmarkList results;
|
||||
return results;
|
||||
}
|
||||
|
||||
if (!bmDataSorted[group]) {
|
||||
std::sort(bmData[group].begin(), bmData[group].end(), BookmarkEntryCompare());
|
||||
bmDataSorted[group] = true;
|
||||
}
|
||||
|
||||
return bmData[group];
|
||||
}
|
||||
|
||||
|
||||
void BookmarkMgr::getGroups(BookmarkNames &arr) {
|
||||
for (BookmarkMap::iterator i = bmData.begin(); i!= bmData.end(); ++i) {
|
||||
arr.push_back(i->first);
|
||||
}
|
||||
}
|
||||
|
||||
void BookmarkMgr::getGroups(wxArrayString &arr) {
|
||||
for (BookmarkMap::iterator i = bmData.begin(); i!= bmData.end(); ++i) {
|
||||
arr.push_back(i->first);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BookmarkMgr::setExpandState(std::string groupName, bool state) {
|
||||
expandState[groupName] = state;
|
||||
}
|
||||
|
||||
|
||||
bool BookmarkMgr::getExpandState(std::string groupName) {
|
||||
if (expandState.find(groupName) == expandState.end()) {
|
||||
return true;
|
||||
}
|
||||
return expandState[groupName];
|
||||
}
|
||||
|
||||
|
||||
void BookmarkMgr::updateActiveList() {
|
||||
BookmarkView *bmv = wxGetApp().getAppFrame()->getBookmarkView();
|
||||
|
||||
if (bmv) {
|
||||
bmv->updateActiveList();
|
||||
}
|
||||
}
|
||||
|
||||
void BookmarkMgr::updateBookmarks() {
|
||||
BookmarkView *bmv = wxGetApp().getAppFrame()->getBookmarkView();
|
||||
|
||||
if (bmv) {
|
||||
bmv->updateBookmarks();
|
||||
}
|
||||
}
|
||||
|
||||
void BookmarkMgr::updateBookmarks(std::string group) {
|
||||
BookmarkView *bmv = wxGetApp().getAppFrame()->getBookmarkView();
|
||||
|
||||
if (bmv) {
|
||||
bmv->updateBookmarks(group);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BookmarkMgr::addRecent(DemodulatorInstance *demod) {
|
||||
std::lock_guard < std::mutex > lock(busy_lock);
|
||||
recents.push_back(demodToBookmarkEntry(demod));
|
||||
|
||||
trimRecents();
|
||||
}
|
||||
|
||||
void BookmarkMgr::addRecent(BookmarkEntry *be) {
|
||||
std::lock_guard < std::mutex > lock(busy_lock);
|
||||
|
||||
recents.push_back(be);
|
||||
|
||||
trimRecents();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BookmarkMgr::removeRecent(BookmarkEntry *be) {
|
||||
std::lock_guard < std::mutex > lock(busy_lock);
|
||||
|
||||
BookmarkList::iterator bm_i = std::find(recents.begin(),recents.end(), be);
|
||||
|
||||
if (bm_i != recents.end()) {
|
||||
recents.erase(bm_i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BookmarkList BookmarkMgr::getRecents() {
|
||||
|
||||
return BookmarkList(recents.rbegin(), recents.rend());
|
||||
}
|
||||
|
||||
|
||||
void BookmarkMgr::clearRecents() {
|
||||
std::lock_guard < std::mutex > lock(busy_lock);
|
||||
|
||||
recents.erase(recents.begin(),recents.end());
|
||||
}
|
||||
|
||||
|
||||
void BookmarkMgr::trimRecents() {
|
||||
if (recents.size() > BOOKMARK_RECENTS_MAX) {
|
||||
delete *(recents.begin());
|
||||
recents.erase(recents.begin(), recents.begin()+1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BookmarkMgr::addRange(BookmarkRangeEntry *re) {
|
||||
std::lock_guard < std::mutex > lock(busy_lock);
|
||||
|
||||
ranges.push_back(re);
|
||||
rangesSorted = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BookmarkMgr::removeRange(BookmarkRangeEntry *re) {
|
||||
std::lock_guard < std::mutex > lock(busy_lock);
|
||||
|
||||
BookmarkRangeList::iterator re_i = std::find(ranges.begin(), ranges.end(), re);
|
||||
|
||||
if (re_i != ranges.end()) {
|
||||
ranges.erase(re_i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BookmarkRangeList BookmarkMgr::getRanges() {
|
||||
std::lock_guard < std::mutex > lock(busy_lock);
|
||||
|
||||
if (!rangesSorted) {
|
||||
std::sort(ranges.begin(), ranges.end(), BookmarkRangeEntryCompare());
|
||||
rangesSorted = true;
|
||||
}
|
||||
|
||||
return ranges;
|
||||
}
|
||||
|
||||
|
||||
void BookmarkMgr::clearRanges() {
|
||||
std::lock_guard < std::mutex > lock(busy_lock);
|
||||
|
||||
ranges.erase(ranges.begin(),ranges.end());
|
||||
}
|
||||
|
||||
|
||||
BookmarkEntry *BookmarkMgr::demodToBookmarkEntry(DemodulatorInstance *demod) {
|
||||
BookmarkEntry *be = new BookmarkEntry;
|
||||
|
||||
be->bandwidth = demod->getBandwidth();
|
||||
be->type = demod->getDemodulatorType();
|
||||
be->label = demod->getDemodulatorUserLabel();
|
||||
be->frequency = demod->getFrequency();
|
||||
|
||||
be->node = new DataNode;
|
||||
wxGetApp().getDemodMgr().saveInstance(be->node, demod);
|
||||
|
||||
return be;
|
||||
}
|
||||
|
||||
BookmarkEntry *BookmarkMgr::nodeToBookmark(const char *name_in, DataNode *node) {
|
||||
if (!node->hasAnother("frequency") || !node->hasAnother("type") || !node->hasAnother("bandwidth")) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BookmarkEntry *be = new BookmarkEntry();
|
||||
node->getNext("frequency")->element()->get(be->frequency);
|
||||
node->getNext("type")->element()->get(be->type);
|
||||
node->getNext("bandwidth")->element()->get(be->bandwidth);
|
||||
|
||||
if (node->hasAnother("user_label")) {
|
||||
node->getNext("user_label")->element()->get(be->label);
|
||||
}
|
||||
|
||||
node->rewindAll();
|
||||
|
||||
be->node = new DataNode("node",*node);
|
||||
|
||||
return be;
|
||||
}
|
||||
|
||||
|
||||
std::wstring BookmarkMgr::getBookmarkEntryDisplayName(BookmarkEntry *bmEnt) {
|
||||
std::wstring dispName = bmEnt->label;
|
||||
|
||||
if (dispName == "") {
|
||||
std::string freqStr = frequencyToStr(bmEnt->frequency) + " " + bmEnt->type;
|
||||
dispName = wstring(freqStr.begin(),freqStr.end());
|
||||
}
|
||||
|
||||
return dispName;
|
||||
}
|
||||
|
||||
std::wstring BookmarkMgr::getActiveDisplayName(DemodulatorInstance *demod) {
|
||||
std::wstring activeName = demod->getDemodulatorUserLabel();
|
||||
|
||||
if (activeName == "") {
|
||||
std::string wstr = frequencyToStr(demod->getFrequency()) + " " + demod->getDemodulatorType();
|
||||
activeName = std::wstring(wstr.begin(),wstr.end());
|
||||
}
|
||||
|
||||
return activeName;
|
||||
}
|
||||
|
129
src/BookmarkMgr.h
Normal file
129
src/BookmarkMgr.h
Normal file
@ -0,0 +1,129 @@
|
||||
#pragma once
|
||||
|
||||
#include <wx/arrstr.h>
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#include "DemodulatorInstance.h"
|
||||
|
||||
class DataNode;
|
||||
|
||||
class BookmarkEntry {
|
||||
public:
|
||||
std::mutex busy_lock;
|
||||
|
||||
std::string type;
|
||||
std::wstring label;
|
||||
std::wstring userLabel;
|
||||
|
||||
long long frequency;
|
||||
int bandwidth;
|
||||
|
||||
DataNode *node;
|
||||
};
|
||||
|
||||
|
||||
class BookmarkRangeEntry {
|
||||
public:
|
||||
BookmarkRangeEntry() : label(L""), freq(0), startFreq(0), endFreq(0) {
|
||||
|
||||
}
|
||||
BookmarkRangeEntry(std::wstring label, long long freq, long long startFreq, long long endFreq) : label(label), freq(freq), startFreq(startFreq), endFreq(endFreq) {
|
||||
}
|
||||
|
||||
std::mutex busy_lock;
|
||||
|
||||
std::wstring label;
|
||||
|
||||
long long freq;
|
||||
long long startFreq;
|
||||
long long endFreq;
|
||||
};
|
||||
|
||||
|
||||
struct BookmarkEntryCompare : public std::binary_function<BookmarkEntry *,BookmarkEntry *,bool>
|
||||
{
|
||||
bool operator()(const BookmarkEntry *a, BookmarkEntry *b) const
|
||||
{
|
||||
return a->frequency < b->frequency;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct BookmarkRangeEntryCompare : public std::binary_function<BookmarkRangeEntry *,BookmarkRangeEntry *,bool>
|
||||
{
|
||||
bool operator()(const BookmarkRangeEntry *a, BookmarkRangeEntry *b) const
|
||||
{
|
||||
return a->freq < b->freq;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<BookmarkEntry *> BookmarkList;
|
||||
typedef std::vector<BookmarkRangeEntry *> BookmarkRangeList;
|
||||
typedef std::map<std::string, BookmarkList > BookmarkMap;
|
||||
typedef std::map<std::string, bool > BookmarkMapSorted;
|
||||
typedef std::vector<std::string> BookmarkNames;
|
||||
typedef std::map<std::string, bool> BookmarkExpandState;
|
||||
|
||||
class BookmarkMgr {
|
||||
public:
|
||||
BookmarkMgr();
|
||||
|
||||
void saveToFile(std::string bookmarkFn, bool backup = true);
|
||||
bool loadFromFile(std::string bookmarkFn, bool backup = true);
|
||||
|
||||
bool hasLastLoad(std::string bookmarkFn);
|
||||
bool hasBackup(std::string bookmarkFn);
|
||||
|
||||
void addBookmark(std::string group, DemodulatorInstance *demod);
|
||||
void addBookmark(std::string group, BookmarkEntry *be);
|
||||
void removeBookmark(std::string group, BookmarkEntry *be);
|
||||
void removeBookmark(BookmarkEntry *be);
|
||||
void moveBookmark(BookmarkEntry *be, std::string group);
|
||||
|
||||
void addGroup(std::string group);
|
||||
void removeGroup(std::string group);
|
||||
void renameGroup(std::string group, std::string ngroup);
|
||||
BookmarkList getBookmarks(std::string group);
|
||||
void getGroups(BookmarkNames &arr);
|
||||
void getGroups(wxArrayString &arr);
|
||||
|
||||
void setExpandState(std::string groupName, bool state);
|
||||
bool getExpandState(std::string groupName);
|
||||
|
||||
void updateActiveList();
|
||||
void updateBookmarks();
|
||||
void updateBookmarks(std::string group);
|
||||
|
||||
void addRecent(DemodulatorInstance *demod);
|
||||
void addRecent(BookmarkEntry *be);
|
||||
void removeRecent(BookmarkEntry *be);
|
||||
BookmarkList getRecents();
|
||||
void clearRecents();
|
||||
|
||||
void addRange(BookmarkRangeEntry *re);
|
||||
void removeRange(BookmarkRangeEntry *re);
|
||||
BookmarkRangeList getRanges();
|
||||
void clearRanges();
|
||||
|
||||
|
||||
static std::wstring getBookmarkEntryDisplayName(BookmarkEntry *bmEnt);
|
||||
static std::wstring getActiveDisplayName(DemodulatorInstance *demod);
|
||||
|
||||
protected:
|
||||
|
||||
void trimRecents();
|
||||
|
||||
BookmarkEntry *demodToBookmarkEntry(DemodulatorInstance *demod);
|
||||
BookmarkEntry *nodeToBookmark(const char *name_in, DataNode *node);
|
||||
|
||||
BookmarkMap bmData;
|
||||
BookmarkMapSorted bmDataSorted;
|
||||
BookmarkList recents;
|
||||
BookmarkRangeList ranges;
|
||||
bool rangesSorted;
|
||||
std::mutex busy_lock;
|
||||
|
||||
BookmarkExpandState expandState;
|
||||
};
|
138
src/CubicSDR.cpp
138
src/CubicSDR.cpp
@ -30,6 +30,9 @@ IMPLEMENT_APP(CubicSDR)
|
||||
#include <fstream>
|
||||
#include <clocale>
|
||||
|
||||
#include "ActionDialog.h"
|
||||
|
||||
|
||||
//#ifdef ENABLE_DIGITAL_LAB
|
||||
//// console output buffer for windows
|
||||
//#ifdef _WINDOWS
|
||||
@ -136,8 +139,65 @@ long long strToFrequency(std::string freqStr) {
|
||||
}
|
||||
|
||||
|
||||
CubicSDR::CubicSDR() : frequency(0), offset(0), ppm(0), snap(1), sampleRate(DEFAULT_SAMPLE_RATE),agcMode(false)
|
||||
{
|
||||
|
||||
class ActionDialogBookmarkCatastophe : public ActionDialog {
|
||||
public:
|
||||
ActionDialogBookmarkCatastophe() : ActionDialog(wxGetApp().getAppFrame(), wxID_ANY, wxT("Bookmark Last-Loaded Backup Failure :( :( :(")) {
|
||||
m_questionText->SetLabelText(wxT("All attempts to recover bookmarks have failed. \nWould you like to exit without touching any more save files?\nClick OK to exit without saving; or Cancel to continue anyways."));
|
||||
}
|
||||
|
||||
void doClickOK() {
|
||||
wxGetApp().getAppFrame()->disableSave(true);
|
||||
wxGetApp().getAppFrame()->Close(false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
class ActionDialogBookmarkBackupLoadFailed : public ActionDialog {
|
||||
public:
|
||||
ActionDialogBookmarkBackupLoadFailed() : ActionDialog(wxGetApp().getAppFrame(), wxID_ANY, wxT("Bookmark Backup Load Failure :( :(")) {
|
||||
m_questionText->SetLabelText(wxT("Sorry; unable to load your bookmarks backup file. \nWould you like to attempt to load the last succssfully loaded bookmarks file?"));
|
||||
}
|
||||
|
||||
void doClickOK() {
|
||||
if (wxGetApp().getBookmarkMgr().hasLastLoad("bookmarks.xml")) {
|
||||
if (wxGetApp().getBookmarkMgr().loadFromFile("bookmarks.xml.lastloaded",false)) {
|
||||
wxGetApp().getBookmarkMgr().updateBookmarks();
|
||||
wxGetApp().getBookmarkMgr().updateActiveList();
|
||||
} else {
|
||||
ActionDialog::showDialog(new ActionDialogBookmarkCatastophe());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class ActionDialogBookmarkLoadFailed : public ActionDialog {
|
||||
public:
|
||||
ActionDialogBookmarkLoadFailed() : ActionDialog(wxGetApp().getAppFrame(), wxID_ANY, wxT("Bookmark Load Failure :(")) {
|
||||
m_questionText->SetLabelText(wxT("Sorry; unable to load your bookmarks file. \nWould you like to attempt to load the backup file?"));
|
||||
}
|
||||
|
||||
void doClickOK() {
|
||||
bool loadOk = false;
|
||||
if (wxGetApp().getBookmarkMgr().hasBackup("bookmarks.xml")) {
|
||||
loadOk = wxGetApp().getBookmarkMgr().loadFromFile("bookmarks.xml.backup",false);
|
||||
}
|
||||
if (loadOk) {
|
||||
wxGetApp().getBookmarkMgr().updateBookmarks();
|
||||
wxGetApp().getBookmarkMgr().updateActiveList();
|
||||
} else if (wxGetApp().getBookmarkMgr().hasLastLoad("bookmarks.xml")) {
|
||||
ActionDialog::showDialog(new ActionDialogBookmarkBackupLoadFailed());
|
||||
} else {
|
||||
ActionDialog::showDialog(new ActionDialogBookmarkCatastophe());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
CubicSDR::CubicSDR() : frequency(0), offset(0), ppm(0), snap(1), sampleRate(DEFAULT_SAMPLE_RATE), agcMode(false)
|
||||
{
|
||||
sampleRateInitialized.store(false);
|
||||
agcMode.store(true);
|
||||
soloMode.store(false);
|
||||
@ -231,25 +291,16 @@ bool CubicSDR::OnInit() {
|
||||
|
||||
// Visual Data
|
||||
spectrumVisualThread = new SpectrumVisualDataThread();
|
||||
demodVisualThread = new SpectrumVisualDataThread();
|
||||
|
||||
pipeIQVisualData = new DemodulatorThreadInputQueue();
|
||||
pipeIQVisualData->set_max_num_items(1);
|
||||
|
||||
pipeDemodIQVisualData = new DemodulatorThreadInputQueue();
|
||||
pipeDemodIQVisualData->set_max_num_items(1);
|
||||
|
||||
pipeWaterfallIQVisualData = new DemodulatorThreadInputQueue();
|
||||
pipeWaterfallIQVisualData->set_max_num_items(128);
|
||||
|
||||
getDemodSpectrumProcessor()->setInput(pipeDemodIQVisualData);
|
||||
getSpectrumProcessor()->setInput(pipeIQVisualData);
|
||||
getSpectrumProcessor()->setHideDC(true);
|
||||
|
||||
pipeAudioVisualData = new DemodulatorThreadOutputQueue();
|
||||
pipeAudioVisualData->set_max_num_items(1);
|
||||
|
||||
scopeProcessor.setInput(pipeAudioVisualData);
|
||||
|
||||
// I/Q Data
|
||||
pipeSDRIQData = new SDRThreadIQDataQueue();
|
||||
@ -263,12 +314,32 @@ bool CubicSDR::OnInit() {
|
||||
|
||||
sdrPostThread->setOutputQueue("IQVisualDataOutput", pipeIQVisualData);
|
||||
sdrPostThread->setOutputQueue("IQDataOutput", pipeWaterfallIQVisualData);
|
||||
sdrPostThread->setOutputQueue("IQActiveDemodVisualDataOutput", pipeDemodIQVisualData);
|
||||
|
||||
t_PostSDR = new std::thread(&SDRPostThread::threadMain, sdrPostThread);
|
||||
t_SpectrumVisual = new std::thread(&SpectrumVisualDataThread::threadMain, spectrumVisualThread);
|
||||
|
||||
#if CUBICSDR_ENABLE_VIEW_SCOPE
|
||||
pipeAudioVisualData = new DemodulatorThreadOutputQueue();
|
||||
pipeAudioVisualData->set_max_num_items(1);
|
||||
|
||||
scopeProcessor.setInput(pipeAudioVisualData);
|
||||
#else
|
||||
pipeAudioVisualData = nullptr;
|
||||
#endif
|
||||
|
||||
#if CUBICSDR_ENABLE_VIEW_DEMOD
|
||||
demodVisualThread = new SpectrumVisualDataThread();
|
||||
pipeDemodIQVisualData = new DemodulatorThreadInputQueue();
|
||||
pipeDemodIQVisualData->set_max_num_items(1);
|
||||
if (getDemodSpectrumProcessor()) getDemodSpectrumProcessor()->setInput(pipeDemodIQVisualData);
|
||||
sdrPostThread->setOutputQueue("IQActiveDemodVisualDataOutput", pipeDemodIQVisualData);
|
||||
t_DemodVisual = new std::thread(&SpectrumVisualDataThread::threadMain, demodVisualThread);
|
||||
|
||||
#else
|
||||
demodVisualThread = nullptr;
|
||||
pipeDemodIQVisualData = nullptr;
|
||||
t_DemodVisual = nullptr;
|
||||
#endif
|
||||
|
||||
sdrEnum = new SDREnumerator();
|
||||
|
||||
SDREnumerator::setManuals(config.getManualDevices());
|
||||
@ -286,6 +357,19 @@ bool CubicSDR::OnInit() {
|
||||
// pthread_setschedparam(pthread_self(), main_policy, &main_param);
|
||||
//#endif
|
||||
|
||||
if (!wxGetApp().getBookmarkMgr().loadFromFile("bookmarks.xml")) {
|
||||
if (wxGetApp().getBookmarkMgr().hasBackup("bookmarks.xml")) {
|
||||
ActionDialog::showDialog(new ActionDialogBookmarkLoadFailed());
|
||||
} else if (wxGetApp().getBookmarkMgr().hasLastLoad("bookmarks.xml")) {
|
||||
ActionDialog::showDialog(new ActionDialogBookmarkBackupLoadFailed());
|
||||
} else {
|
||||
ActionDialog::showDialog(new ActionDialogBookmarkCatastophe());
|
||||
}
|
||||
} else {
|
||||
getBookmarkMgr().updateActiveList();
|
||||
getBookmarkMgr().updateBookmarks();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -316,16 +400,20 @@ int CubicSDR::OnExit() {
|
||||
|
||||
std::cout << "Terminating Visual Processor threads.." << std::endl;
|
||||
spectrumVisualThread->terminate();
|
||||
demodVisualThread->terminate();
|
||||
|
||||
if (demodVisualThread) {
|
||||
demodVisualThread->terminate();
|
||||
}
|
||||
|
||||
//Wait nicely
|
||||
sdrPostThread->isTerminated(1000);
|
||||
spectrumVisualThread->isTerminated(1000);
|
||||
demodVisualThread->isTerminated(1000);
|
||||
if (demodVisualThread) {
|
||||
demodVisualThread->isTerminated(1000);
|
||||
}
|
||||
|
||||
//Then join the thread themselves
|
||||
t_PostSDR->join();
|
||||
t_DemodVisual->join();
|
||||
if (t_DemodVisual) t_DemodVisual->join();
|
||||
t_SpectrumVisual->join();
|
||||
|
||||
//Now only we can delete
|
||||
@ -494,7 +582,9 @@ void CubicSDR::setFrequency(long long freq) {
|
||||
getSpectrumProcessor()->setPeakHold(getSpectrumProcessor()->getPeakHold());
|
||||
|
||||
//make the peak hold act on the current dmod also, like a zoomed-in version.
|
||||
getDemodSpectrumProcessor()->setPeakHold(getSpectrumProcessor()->getPeakHold());
|
||||
if (getDemodSpectrumProcessor()) {
|
||||
getDemodSpectrumProcessor()->setPeakHold(getSpectrumProcessor()->getPeakHold());
|
||||
}
|
||||
}
|
||||
|
||||
long long CubicSDR::getOffset() {
|
||||
@ -655,7 +745,11 @@ SpectrumVisualProcessor *CubicSDR::getSpectrumProcessor() {
|
||||
}
|
||||
|
||||
SpectrumVisualProcessor *CubicSDR::getDemodSpectrumProcessor() {
|
||||
return demodVisualThread->getProcessor();
|
||||
if (demodVisualThread) {
|
||||
return demodVisualThread->getProcessor();
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
DemodulatorThreadOutputQueue* CubicSDR::getAudioVisualQueue() {
|
||||
@ -674,6 +768,10 @@ DemodulatorMgr &CubicSDR::getDemodMgr() {
|
||||
return demodMgr;
|
||||
}
|
||||
|
||||
BookmarkMgr &CubicSDR::getBookmarkMgr() {
|
||||
return bookmarkMgr;
|
||||
}
|
||||
|
||||
SDRPostThread *CubicSDR::getSDRPostThread() {
|
||||
return sdrPostThread;
|
||||
}
|
||||
@ -707,6 +805,7 @@ void CubicSDR::removeDemodulator(DemodulatorInstance *demod) {
|
||||
}
|
||||
demod->setActive(false);
|
||||
sdrPostThread->removeDemodulator(demod);
|
||||
wxGetApp().getAppFrame()->notifyUpdateModemProperties();
|
||||
}
|
||||
|
||||
std::vector<SDRDeviceInfo*>* CubicSDR::getDevices() {
|
||||
@ -752,6 +851,7 @@ void CubicSDR::showFrequencyInput(FrequencyDialog::FrequencyDialogTarget targetM
|
||||
|
||||
switch (targetMode) {
|
||||
case FrequencyDialog::FDIALOG_TARGET_DEFAULT:
|
||||
case FrequencyDialog::FDIALOG_TARGET_FREQ:
|
||||
title = demodMgr.getActiveDemodulator()?demodTitle:freqTitle;
|
||||
break;
|
||||
case FrequencyDialog::FDIALOG_TARGET_BANDWIDTH:
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "AppFrame.h"
|
||||
#include "FrequencyDialog.h"
|
||||
#include "DemodLabelDialog.h"
|
||||
#include "BookmarkMgr.h"
|
||||
|
||||
#include "ScopeVisualProcessor.h"
|
||||
#include "SpectrumVisualProcessor.h"
|
||||
@ -96,6 +97,9 @@ public:
|
||||
|
||||
void setOffset(long long ofs);
|
||||
long long getOffset();
|
||||
|
||||
void setDBOffset(int ofs);
|
||||
int getDBOffset();
|
||||
|
||||
void setSampleRate(long long rate_in);
|
||||
long long getSampleRate();
|
||||
@ -114,6 +118,7 @@ public:
|
||||
DemodulatorThreadInputQueue* getWaterfallVisualQueue();
|
||||
DemodulatorThreadInputQueue* getActiveDemodVisualQueue();
|
||||
DemodulatorMgr &getDemodMgr();
|
||||
BookmarkMgr &getBookmarkMgr();
|
||||
|
||||
SDRPostThread *getSDRPostThread();
|
||||
SDRThread *getSDRThread();
|
||||
@ -182,6 +187,7 @@ private:
|
||||
std::vector<SDRDeviceInfo *> *devs = nullptr;
|
||||
|
||||
DemodulatorMgr demodMgr;
|
||||
BookmarkMgr bookmarkMgr;
|
||||
|
||||
std::atomic_llong frequency;
|
||||
std::atomic_llong offset;
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define CUBICSDR_TITLE "CubicSDR v" CUBICSDR_VERSION " by Charles J. Cliffe (@ccliffe) :: www.cubicsdr.com"
|
||||
#define CUBICSDR_TITLE "" CUBICSDR_BUILD_TITLE
|
||||
|
||||
#ifndef __BYTE_ORDER
|
||||
#ifdef _WIN32
|
||||
|
@ -60,7 +60,7 @@ void DemodLabelDialog::OnChar(wxKeyEvent& event) {
|
||||
else {
|
||||
activeDemod->setDemodulatorUserLabel(L"");
|
||||
}
|
||||
|
||||
wxGetApp().getBookmarkMgr().updateActiveList();
|
||||
Close();
|
||||
break;
|
||||
case WXK_ESCAPE:
|
||||
|
@ -33,26 +33,10 @@ void ModemProperties::OnShow(wxShowEvent & /* event */) {
|
||||
}
|
||||
|
||||
void ModemProperties::updateTheme() {
|
||||
wxColour bgColor(
|
||||
(unsigned char) (ThemeMgr::mgr.currentTheme->generalBackground.r * 255.0),
|
||||
(unsigned char) (ThemeMgr::mgr.currentTheme->generalBackground.g * 255.0),
|
||||
(unsigned char) (ThemeMgr::mgr.currentTheme->generalBackground.b * 255.0));
|
||||
|
||||
wxColour textColor(
|
||||
(unsigned char) (ThemeMgr::mgr.currentTheme->text.r * 255.0),
|
||||
(unsigned char) (ThemeMgr::mgr.currentTheme->text.g * 255.0),
|
||||
(unsigned char) (ThemeMgr::mgr.currentTheme->text.b * 255.0));
|
||||
|
||||
wxColour btn(
|
||||
(unsigned char) (ThemeMgr::mgr.currentTheme->button.r * 255.0),
|
||||
(unsigned char) (ThemeMgr::mgr.currentTheme->button.g * 255.0),
|
||||
(unsigned char) (ThemeMgr::mgr.currentTheme->button.b * 255.0));
|
||||
|
||||
wxColour btnHl(
|
||||
(unsigned char) (ThemeMgr::mgr.currentTheme->buttonHighlight.r * 255.0),
|
||||
(unsigned char) (ThemeMgr::mgr.currentTheme->buttonHighlight.g * 255.0),
|
||||
(unsigned char) (ThemeMgr::mgr.currentTheme->buttonHighlight.b * 255.0));
|
||||
|
||||
wxColour bgColor(ThemeMgr::mgr.currentTheme->generalBackground);
|
||||
wxColour textColor(ThemeMgr::mgr.currentTheme->text);
|
||||
wxColour btn(ThemeMgr::mgr.currentTheme->button);
|
||||
wxColour btnHl(ThemeMgr::mgr.currentTheme->buttonHighlight);
|
||||
|
||||
m_propertyGrid->SetEmptySpaceColour(bgColor);
|
||||
m_propertyGrid->SetCellBackgroundColour(bgColor);
|
||||
@ -125,10 +109,8 @@ void ModemProperties::initProperties(ModemArgInfoList newArgs, DemodulatorInstan
|
||||
m_propertyGrid->Clear();
|
||||
|
||||
if (!demodInstance) {
|
||||
Hide();
|
||||
m_propertyGrid->Append(new wxPropertyCategory("Modem Settings"));
|
||||
return;
|
||||
} else {
|
||||
Show();
|
||||
}
|
||||
|
||||
m_propertyGrid->Append(new wxPropertyCategory(demodInstance->getDemodulatorType() + " Settings"));
|
||||
|
@ -83,6 +83,8 @@ DemodulatorInstance::~DemodulatorInstance() {
|
||||
delete pipeIQDemodData;
|
||||
delete threadQueueControl;
|
||||
delete pipeAudioData;
|
||||
|
||||
wxGetApp().getBookmarkMgr().updateActiveList();
|
||||
}
|
||||
|
||||
void DemodulatorInstance::setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue) {
|
||||
@ -121,6 +123,7 @@ void DemodulatorInstance::run() {
|
||||
|
||||
active = true;
|
||||
|
||||
wxGetApp().getBookmarkMgr().updateActiveList();
|
||||
}
|
||||
|
||||
void DemodulatorInstance::updateLabel(long long freq) {
|
||||
@ -128,6 +131,7 @@ void DemodulatorInstance::updateLabel(long long freq) {
|
||||
newLabel.precision(3);
|
||||
newLabel << std::fixed << ((long double) freq / 1000000.0);
|
||||
setLabel(newLabel.str());
|
||||
wxGetApp().getBookmarkMgr().updateActiveList();
|
||||
}
|
||||
|
||||
void DemodulatorInstance::terminate() {
|
||||
@ -230,6 +234,8 @@ void DemodulatorInstance::setActive(bool state) {
|
||||
tracking = false;
|
||||
}
|
||||
active = state;
|
||||
|
||||
wxGetApp().getBookmarkMgr().updateActiveList();
|
||||
}
|
||||
|
||||
void DemodulatorInstance::squelchAuto() {
|
||||
@ -334,7 +340,9 @@ void DemodulatorInstance::setDemodulatorType(std::string demod_type_in) {
|
||||
outp->setTitle(getDemodulatorType() + ": " + frequencyToStr(getFrequency()));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
wxGetApp().getBookmarkMgr().updateActiveList();
|
||||
}
|
||||
|
||||
std::string DemodulatorInstance::getDemodulatorType() {
|
||||
@ -394,6 +402,10 @@ void DemodulatorInstance::setFrequency(long long freq) {
|
||||
wxGetApp().getRigThread()->setFrequency(freq,true);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (this->isActive()) {
|
||||
wxGetApp().getBookmarkMgr().updateActiveList();
|
||||
}
|
||||
}
|
||||
|
||||
long long DemodulatorInstance::getFrequency() {
|
||||
|
@ -4,15 +4,18 @@
|
||||
#include <DemodulatorMgr.h>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include "CubicSDR.h"
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
#include "DemodulatorMgr.h"
|
||||
|
||||
#if USE_HAMLIB
|
||||
#include "RigThread.h"
|
||||
#endif
|
||||
|
||||
#include "DataTree.h"
|
||||
|
||||
bool demodFreqCompare (DemodulatorInstance *i, DemodulatorInstance *j) { return (i->getFrequency()<j->getFrequency()); }
|
||||
bool inactiveCompare (DemodulatorInstance *i, DemodulatorInstance *j) { return (i->isActive()<j->isActive()); }
|
||||
|
||||
@ -133,6 +136,8 @@ DemodulatorInstance *DemodulatorMgr::getFirstDemodulator() {
|
||||
|
||||
void DemodulatorMgr::deleteThread(DemodulatorInstance *demod) {
|
||||
std::lock_guard < std::recursive_mutex > lock(demods_busy);
|
||||
|
||||
wxGetApp().getBookmarkMgr().addRecent(demod);
|
||||
|
||||
std::vector<DemodulatorInstance *>::iterator i;
|
||||
|
||||
@ -218,6 +223,7 @@ void DemodulatorMgr::setActiveDemodulator(DemodulatorInstance *demod, bool tempo
|
||||
wxGetApp().getRigThread()->setFrequency(lastActiveDemodulator.load()->getFrequency(),true);
|
||||
}
|
||||
#endif
|
||||
wxGetApp().getBookmarkMgr().updateActiveList();
|
||||
} else {
|
||||
std::lock_guard < std::recursive_mutex > lock(demods_busy);
|
||||
garbageCollect();
|
||||
@ -371,3 +377,138 @@ ModemSettings DemodulatorMgr::getLastModemSettings(std::string modemType) {
|
||||
void DemodulatorMgr::setLastModemSettings(std::string modemType, ModemSettings settings) {
|
||||
lastModemSettings[modemType] = settings;
|
||||
}
|
||||
|
||||
void DemodulatorMgr::setOutputDevices(std::map<int,RtAudio::DeviceInfo> devs) {
|
||||
outputDevices = devs;
|
||||
}
|
||||
|
||||
void DemodulatorMgr::saveInstance(DataNode *node, DemodulatorInstance *inst) {
|
||||
*node->newChild("bandwidth") = inst->getBandwidth();
|
||||
*node->newChild("frequency") = inst->getFrequency();
|
||||
*node->newChild("type") = inst->getDemodulatorType();
|
||||
|
||||
node->newChild("user_label")->element()->set(inst->getDemodulatorUserLabel());
|
||||
|
||||
*node->newChild("squelch_level") = inst->getSquelchLevel();
|
||||
*node->newChild("squelch_enabled") = inst->isSquelchEnabled() ? 1 : 0;
|
||||
*node->newChild("output_device") = outputDevices[inst->getOutputDevice()].name;
|
||||
*node->newChild("gain") = inst->getGain();
|
||||
*node->newChild("muted") = inst->isMuted() ? 1 : 0;
|
||||
if (inst->isDeltaLock()) {
|
||||
*node->newChild("delta_lock") = inst->isDeltaLock() ? 1 : 0;
|
||||
*node->newChild("delta_ofs") = inst->getDeltaLockOfs();
|
||||
}
|
||||
if (inst == getLastActiveDemodulator()) {
|
||||
*node->newChild("active") = 1;
|
||||
}
|
||||
|
||||
ModemSettings saveSettings = inst->readModemSettings();
|
||||
if (saveSettings.size()) {
|
||||
DataNode *settingsNode = node->newChild("settings");
|
||||
for (ModemSettings::const_iterator msi = saveSettings.begin(); msi != saveSettings.end(); msi++) {
|
||||
*settingsNode->newChild(msi->first.c_str()) = msi->second;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DemodulatorInstance *DemodulatorMgr::loadInstance(DataNode *node) {
|
||||
DemodulatorInstance *newDemod = nullptr;
|
||||
|
||||
node->rewindAll();
|
||||
|
||||
long bandwidth = *node->getNext("bandwidth");
|
||||
long long freq = *node->getNext("frequency");
|
||||
float squelch_level = node->hasAnother("squelch_level") ? (float) *node->getNext("squelch_level") : 0;
|
||||
int squelch_enabled = node->hasAnother("squelch_enabled") ? (int) *node->getNext("squelch_enabled") : 0;
|
||||
int muted = node->hasAnother("muted") ? (int) *node->getNext("muted") : 0;
|
||||
int delta_locked = node->hasAnother("delta_lock") ? (int) *node->getNext("delta_lock") : 0;
|
||||
int delta_ofs = node->hasAnother("delta_ofs") ? (int) *node->getNext("delta_ofs") : 0;
|
||||
std::string output_device = node->hasAnother("output_device") ? string(*(node->getNext("output_device"))) : "";
|
||||
float gain = node->hasAnother("gain") ? (float) *node->getNext("gain") : 1.0;
|
||||
|
||||
std::string type = "FM";
|
||||
|
||||
DataNode *demodTypeNode = node->hasAnother("type")?node->getNext("type"):nullptr;
|
||||
|
||||
if (demodTypeNode && demodTypeNode->element()->getDataType() == DATA_INT) {
|
||||
int legacyType = *demodTypeNode;
|
||||
int legacyStereo = node->hasAnother("stereo") ? (int) *node->getNext("stereo") : 0;
|
||||
switch (legacyType) { // legacy demod ID
|
||||
case 1: type = legacyStereo?"FMS":"FM"; break;
|
||||
case 2: type = "AM"; break;
|
||||
case 3: type = "LSB"; break;
|
||||
case 4: type = "USB"; break;
|
||||
case 5: type = "DSB"; break;
|
||||
case 6: type = "ASK"; break;
|
||||
case 7: type = "APSK"; break;
|
||||
case 8: type = "BPSK"; break;
|
||||
case 9: type = "DPSK"; break;
|
||||
case 10: type = "PSK"; break;
|
||||
case 11: type = "OOK"; break;
|
||||
case 12: type = "ST"; break;
|
||||
case 13: type = "SQAM"; break;
|
||||
case 14: type = "QAM"; break;
|
||||
case 15: type = "QPSK"; break;
|
||||
case 16: type = "I/Q"; break;
|
||||
default: type = "FM"; break;
|
||||
}
|
||||
} else if (demodTypeNode && demodTypeNode->element()->getDataType() == DATA_STRING) {
|
||||
demodTypeNode->element()->get(type);
|
||||
}
|
||||
|
||||
//read the user label associated with the demodulator
|
||||
std::wstring user_label = L"";
|
||||
|
||||
DataNode *demodUserLabel = node->hasAnother("user_label") ? node->getNext("user_label") : nullptr;
|
||||
|
||||
if (demodUserLabel) {
|
||||
demodUserLabel->element()->get(user_label);
|
||||
}
|
||||
|
||||
ModemSettings mSettings;
|
||||
|
||||
if (node->hasAnother("settings")) {
|
||||
DataNode *modemSettings = node->getNext("settings");
|
||||
for (int msi = 0, numSettings = modemSettings->numChildren(); msi < numSettings; msi++) {
|
||||
DataNode *settingNode = modemSettings->child(msi);
|
||||
std::string keyName = settingNode->getName();
|
||||
std::string strSettingValue = settingNode->element()->toString();
|
||||
|
||||
if (keyName != "" && strSettingValue != "") {
|
||||
mSettings[keyName] = strSettingValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newDemod = wxGetApp().getDemodMgr().newThread();
|
||||
|
||||
newDemod->setDemodulatorType(type);
|
||||
newDemod->setDemodulatorUserLabel(user_label);
|
||||
newDemod->writeModemSettings(mSettings);
|
||||
newDemod->setBandwidth(bandwidth);
|
||||
newDemod->setFrequency(freq);
|
||||
newDemod->setGain(gain);
|
||||
newDemod->updateLabel(freq);
|
||||
newDemod->setMuted(muted?true:false);
|
||||
if (delta_locked) {
|
||||
newDemod->setDeltaLock(true);
|
||||
newDemod->setDeltaLockOfs(delta_ofs);
|
||||
}
|
||||
if (squelch_enabled) {
|
||||
newDemod->setSquelchEnabled(true);
|
||||
newDemod->setSquelchLevel(squelch_level);
|
||||
}
|
||||
|
||||
bool found_device = false;
|
||||
std::map<int, RtAudio::DeviceInfo>::iterator i;
|
||||
for (i = outputDevices.begin(); i != outputDevices.end(); i++) {
|
||||
if (i->second.name == output_device) {
|
||||
newDemod->setOutputDevice(i->first);
|
||||
found_device = true;
|
||||
}
|
||||
}
|
||||
|
||||
return newDemod;
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
#include "DemodulatorInstance.h"
|
||||
|
||||
class DataNode;
|
||||
|
||||
class DemodulatorMgr {
|
||||
public:
|
||||
DemodulatorMgr();
|
||||
@ -57,6 +59,10 @@ public:
|
||||
|
||||
void updateLastState();
|
||||
|
||||
void setOutputDevices(std::map<int,RtAudio::DeviceInfo> devs);
|
||||
void saveInstance(DataNode *node, DemodulatorInstance *inst);
|
||||
DemodulatorInstance *loadInstance(DataNode *node);
|
||||
|
||||
private:
|
||||
|
||||
void garbageCollect();
|
||||
@ -82,4 +88,5 @@ private:
|
||||
std::recursive_mutex demods_busy;
|
||||
|
||||
std::map<std::string, ModemSettings> lastModemSettings;
|
||||
std::map<int,RtAudio::DeviceInfo> outputDevices;
|
||||
};
|
||||
|
136
src/forms/Bookmark/BookmarkPanel.cpp
Normal file
136
src/forms/Bookmark/BookmarkPanel.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Aug 23 2015)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "BookmarkPanel.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BookmarkPanel::BookmarkPanel( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style )
|
||||
{
|
||||
wxBoxSizer* bSizer1;
|
||||
bSizer1 = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_searchText = new wxTextCtrl( this, wxID_ANY, wxT("Search.."), wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
|
||||
bSizer1->Add( m_searchText, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_clearSearchButton = new wxButton( this, wxID_ANY, wxT("Clear Search"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bSizer1->Add( m_clearSearchButton, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
|
||||
|
||||
m_treeView = new wxTreeCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_DEFAULT_STYLE|wxTR_EDIT_LABELS|wxTR_HAS_VARIABLE_ROW_HEIGHT|wxTR_HIDE_ROOT|wxTR_SINGLE );
|
||||
bSizer1->Add( m_treeView, 1, wxEXPAND, 5 );
|
||||
|
||||
m_propPanel = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||
wxFlexGridSizer* fgPropSizer;
|
||||
fgPropSizer = new wxFlexGridSizer( 0, 2, 0, 0 );
|
||||
fgPropSizer->AddGrowableCol( 1 );
|
||||
fgPropSizer->SetFlexibleDirection( wxBOTH );
|
||||
fgPropSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
|
||||
m_labelLabel = new wxStaticText( m_propPanel, wxID_ANY, wxT("Label"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_labelLabel->Wrap( -1 );
|
||||
fgPropSizer->Add( m_labelLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
|
||||
|
||||
m_labelText = new wxTextCtrl( m_propPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
|
||||
fgPropSizer->Add( m_labelText, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_frequencyLabel = new wxStaticText( m_propPanel, wxID_ANY, wxT("Freq"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_frequencyLabel->Wrap( -1 );
|
||||
fgPropSizer->Add( m_frequencyLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
|
||||
|
||||
m_frequencyVal = new wxStaticText( m_propPanel, wxID_ANY, wxT("FrequencyVal"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_frequencyVal->Wrap( -1 );
|
||||
fgPropSizer->Add( m_frequencyVal, 0, wxALL, 5 );
|
||||
|
||||
m_bandwidthLabel = new wxStaticText( m_propPanel, wxID_ANY, wxT("BW"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_bandwidthLabel->Wrap( -1 );
|
||||
fgPropSizer->Add( m_bandwidthLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
|
||||
|
||||
m_bandwidthVal = new wxStaticText( m_propPanel, wxID_ANY, wxT("BandwidthVal"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_bandwidthVal->Wrap( -1 );
|
||||
fgPropSizer->Add( m_bandwidthVal, 0, wxALL, 5 );
|
||||
|
||||
m_modulationLabel = new wxStaticText( m_propPanel, wxID_ANY, wxT("Type"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_modulationLabel->Wrap( -1 );
|
||||
fgPropSizer->Add( m_modulationLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
|
||||
|
||||
m_modulationVal = new wxStaticText( m_propPanel, wxID_ANY, wxT("TypeVal"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_modulationVal->Wrap( -1 );
|
||||
fgPropSizer->Add( m_modulationVal, 0, wxALL, 5 );
|
||||
|
||||
|
||||
m_propPanel->SetSizer( fgPropSizer );
|
||||
m_propPanel->Layout();
|
||||
fgPropSizer->Fit( m_propPanel );
|
||||
bSizer1->Add( m_propPanel, 0, wxALL|wxBOTTOM|wxEXPAND|wxTOP, 5 );
|
||||
|
||||
m_buttonPanel = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||
wxBoxSizer* m_buttonPanelSizer;
|
||||
m_buttonPanelSizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
|
||||
m_buttonPanel->SetSizer( m_buttonPanelSizer );
|
||||
m_buttonPanel->Layout();
|
||||
m_buttonPanelSizer->Fit( m_buttonPanel );
|
||||
bSizer1->Add( m_buttonPanel, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
this->SetSizer( bSizer1 );
|
||||
this->Layout();
|
||||
m_updateTimer.SetOwner( this, wxID_ANY );
|
||||
|
||||
// Connect Events
|
||||
this->Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( BookmarkPanel::onEnterWindow ) );
|
||||
this->Connect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( BookmarkPanel::onLeaveWindow ) );
|
||||
this->Connect( wxEVT_MOTION, wxMouseEventHandler( BookmarkPanel::onMotion ) );
|
||||
m_searchText->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( BookmarkPanel::onSearchTextFocus ), NULL, this );
|
||||
m_searchText->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( BookmarkPanel::onSearchText ), NULL, this );
|
||||
m_clearSearchButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BookmarkPanel::onClearSearch ), NULL, this );
|
||||
m_treeView->Connect( wxEVT_MOTION, wxMouseEventHandler( BookmarkPanel::onMotion ), NULL, this );
|
||||
m_treeView->Connect( wxEVT_COMMAND_TREE_BEGIN_DRAG, wxTreeEventHandler( BookmarkPanel::onTreeBeginDrag ), NULL, this );
|
||||
m_treeView->Connect( wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT, wxTreeEventHandler( BookmarkPanel::onTreeBeginLabelEdit ), NULL, this );
|
||||
m_treeView->Connect( wxEVT_COMMAND_TREE_END_DRAG, wxTreeEventHandler( BookmarkPanel::onTreeEndDrag ), NULL, this );
|
||||
m_treeView->Connect( wxEVT_COMMAND_TREE_END_LABEL_EDIT, wxTreeEventHandler( BookmarkPanel::onTreeEndLabelEdit ), NULL, this );
|
||||
m_treeView->Connect( wxEVT_COMMAND_TREE_ITEM_ACTIVATED, wxTreeEventHandler( BookmarkPanel::onTreeActivate ), NULL, this );
|
||||
m_treeView->Connect( wxEVT_COMMAND_TREE_ITEM_COLLAPSED, wxTreeEventHandler( BookmarkPanel::onTreeCollapse ), NULL, this );
|
||||
m_treeView->Connect( wxEVT_COMMAND_TREE_ITEM_EXPANDED, wxTreeEventHandler( BookmarkPanel::onTreeExpanded ), NULL, this );
|
||||
m_treeView->Connect( wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP, wxTreeEventHandler( BookmarkPanel::onTreeItemGetTooltip ), NULL, this );
|
||||
m_treeView->Connect( wxEVT_COMMAND_TREE_ITEM_MENU, wxTreeEventHandler( BookmarkPanel::onTreeItemMenu ), NULL, this );
|
||||
m_treeView->Connect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( BookmarkPanel::onTreeSelect ), NULL, this );
|
||||
m_treeView->Connect( wxEVT_COMMAND_TREE_SEL_CHANGING, wxTreeEventHandler( BookmarkPanel::onTreeSelectChanging ), NULL, this );
|
||||
m_labelText->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( BookmarkPanel::onLabelText ), NULL, this );
|
||||
m_frequencyVal->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( BookmarkPanel::onDoubleClickFreq ), NULL, this );
|
||||
m_bandwidthVal->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( BookmarkPanel::onDoubleClickBandwidth ), NULL, this );
|
||||
this->Connect( wxID_ANY, wxEVT_TIMER, wxTimerEventHandler( BookmarkPanel::onUpdateTimer ) );
|
||||
}
|
||||
|
||||
BookmarkPanel::~BookmarkPanel()
|
||||
{
|
||||
// Disconnect Events
|
||||
this->Disconnect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( BookmarkPanel::onEnterWindow ) );
|
||||
this->Disconnect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( BookmarkPanel::onLeaveWindow ) );
|
||||
this->Disconnect( wxEVT_MOTION, wxMouseEventHandler( BookmarkPanel::onMotion ) );
|
||||
m_searchText->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( BookmarkPanel::onSearchTextFocus ), NULL, this );
|
||||
m_searchText->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( BookmarkPanel::onSearchText ), NULL, this );
|
||||
m_clearSearchButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BookmarkPanel::onClearSearch ), NULL, this );
|
||||
m_treeView->Disconnect( wxEVT_MOTION, wxMouseEventHandler( BookmarkPanel::onMotion ), NULL, this );
|
||||
m_treeView->Disconnect( wxEVT_COMMAND_TREE_BEGIN_DRAG, wxTreeEventHandler( BookmarkPanel::onTreeBeginDrag ), NULL, this );
|
||||
m_treeView->Disconnect( wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT, wxTreeEventHandler( BookmarkPanel::onTreeBeginLabelEdit ), NULL, this );
|
||||
m_treeView->Disconnect( wxEVT_COMMAND_TREE_END_DRAG, wxTreeEventHandler( BookmarkPanel::onTreeEndDrag ), NULL, this );
|
||||
m_treeView->Disconnect( wxEVT_COMMAND_TREE_END_LABEL_EDIT, wxTreeEventHandler( BookmarkPanel::onTreeEndLabelEdit ), NULL, this );
|
||||
m_treeView->Disconnect( wxEVT_COMMAND_TREE_ITEM_ACTIVATED, wxTreeEventHandler( BookmarkPanel::onTreeActivate ), NULL, this );
|
||||
m_treeView->Disconnect( wxEVT_COMMAND_TREE_ITEM_COLLAPSED, wxTreeEventHandler( BookmarkPanel::onTreeCollapse ), NULL, this );
|
||||
m_treeView->Disconnect( wxEVT_COMMAND_TREE_ITEM_EXPANDED, wxTreeEventHandler( BookmarkPanel::onTreeExpanded ), NULL, this );
|
||||
m_treeView->Disconnect( wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP, wxTreeEventHandler( BookmarkPanel::onTreeItemGetTooltip ), NULL, this );
|
||||
m_treeView->Disconnect( wxEVT_COMMAND_TREE_ITEM_MENU, wxTreeEventHandler( BookmarkPanel::onTreeItemMenu ), NULL, this );
|
||||
m_treeView->Disconnect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( BookmarkPanel::onTreeSelect ), NULL, this );
|
||||
m_treeView->Disconnect( wxEVT_COMMAND_TREE_SEL_CHANGING, wxTreeEventHandler( BookmarkPanel::onTreeSelectChanging ), NULL, this );
|
||||
m_labelText->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( BookmarkPanel::onLabelText ), NULL, this );
|
||||
m_frequencyVal->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( BookmarkPanel::onDoubleClickFreq ), NULL, this );
|
||||
m_bandwidthVal->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( BookmarkPanel::onDoubleClickBandwidth ), NULL, this );
|
||||
this->Disconnect( wxID_ANY, wxEVT_TIMER, wxTimerEventHandler( BookmarkPanel::onUpdateTimer ) );
|
||||
|
||||
}
|
1230
src/forms/Bookmark/BookmarkPanel.fbp
Normal file
1230
src/forms/Bookmark/BookmarkPanel.fbp
Normal file
File diff suppressed because it is too large
Load Diff
83
src/forms/Bookmark/BookmarkPanel.h
Normal file
83
src/forms/Bookmark/BookmarkPanel.h
Normal file
@ -0,0 +1,83 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Aug 23 2015)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __BOOKMARKPANEL_H__
|
||||
#define __BOOKMARKPANEL_H__
|
||||
|
||||
#include <wx/artprov.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/font.h>
|
||||
#include <wx/colour.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/treectrl.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/timer.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class BookmarkPanel
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class BookmarkPanel : public wxPanel
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
wxTextCtrl* m_searchText;
|
||||
wxButton* m_clearSearchButton;
|
||||
wxTreeCtrl* m_treeView;
|
||||
wxPanel* m_propPanel;
|
||||
wxStaticText* m_labelLabel;
|
||||
wxTextCtrl* m_labelText;
|
||||
wxStaticText* m_frequencyLabel;
|
||||
wxStaticText* m_frequencyVal;
|
||||
wxStaticText* m_bandwidthLabel;
|
||||
wxStaticText* m_bandwidthVal;
|
||||
wxStaticText* m_modulationLabel;
|
||||
wxStaticText* m_modulationVal;
|
||||
wxPanel* m_buttonPanel;
|
||||
wxTimer m_updateTimer;
|
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void onEnterWindow( wxMouseEvent& event ) { event.Skip(); }
|
||||
virtual void onLeaveWindow( wxMouseEvent& event ) { event.Skip(); }
|
||||
virtual void onMotion( wxMouseEvent& event ) { event.Skip(); }
|
||||
virtual void onSearchTextFocus( wxMouseEvent& event ) { event.Skip(); }
|
||||
virtual void onSearchText( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onClearSearch( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onTreeBeginDrag( wxTreeEvent& event ) { event.Skip(); }
|
||||
virtual void onTreeBeginLabelEdit( wxTreeEvent& event ) { event.Skip(); }
|
||||
virtual void onTreeEndDrag( wxTreeEvent& event ) { event.Skip(); }
|
||||
virtual void onTreeEndLabelEdit( wxTreeEvent& event ) { event.Skip(); }
|
||||
virtual void onTreeActivate( wxTreeEvent& event ) { event.Skip(); }
|
||||
virtual void onTreeCollapse( wxTreeEvent& event ) { event.Skip(); }
|
||||
virtual void onTreeExpanded( wxTreeEvent& event ) { event.Skip(); }
|
||||
virtual void onTreeItemGetTooltip( wxTreeEvent& event ) { event.Skip(); }
|
||||
virtual void onTreeItemMenu( wxTreeEvent& event ) { event.Skip(); }
|
||||
virtual void onTreeSelect( wxTreeEvent& event ) { event.Skip(); }
|
||||
virtual void onTreeSelectChanging( wxTreeEvent& event ) { event.Skip(); }
|
||||
virtual void onLabelText( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onDoubleClickFreq( wxMouseEvent& event ) { event.Skip(); }
|
||||
virtual void onDoubleClickBandwidth( wxMouseEvent& event ) { event.Skip(); }
|
||||
virtual void onUpdateTimer( wxTimerEvent& event ) { event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
|
||||
BookmarkPanel( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 169,471 ), long style = wxTAB_TRAVERSAL );
|
||||
~BookmarkPanel();
|
||||
|
||||
};
|
||||
|
||||
#endif //__BOOKMARKPANEL_H__
|
1476
src/forms/Bookmark/BookmarkView.cpp
Normal file
1476
src/forms/Bookmark/BookmarkView.cpp
Normal file
File diff suppressed because it is too large
Load Diff
169
src/forms/Bookmark/BookmarkView.h
Normal file
169
src/forms/Bookmark/BookmarkView.h
Normal file
@ -0,0 +1,169 @@
|
||||
#pragma once
|
||||
|
||||
#include "wx/choice.h"
|
||||
#include "wx/dialog.h"
|
||||
|
||||
#include "BookmarkPanel.h"
|
||||
#include "BookmarkMgr.h"
|
||||
|
||||
|
||||
class TreeViewItem : public wxTreeItemData {
|
||||
public:
|
||||
enum TreeViewItemType {
|
||||
TREEVIEW_ITEM_TYPE_GROUP,
|
||||
TREEVIEW_ITEM_TYPE_ACTIVE,
|
||||
TREEVIEW_ITEM_TYPE_RECENT,
|
||||
TREEVIEW_ITEM_TYPE_BOOKMARK,
|
||||
TREEVIEW_ITEM_TYPE_RANGE
|
||||
};
|
||||
|
||||
TreeViewItem() {
|
||||
bookmarkEnt = nullptr;
|
||||
demod = nullptr;
|
||||
rangeEnt = nullptr;
|
||||
};
|
||||
|
||||
TreeViewItemType type;
|
||||
BookmarkEntry *bookmarkEnt;
|
||||
BookmarkRangeEntry *rangeEnt;
|
||||
DemodulatorInstance *demod;
|
||||
std::string groupName;
|
||||
};
|
||||
|
||||
|
||||
class BookmarkViewVisualDragItem : public wxDialog {
|
||||
public:
|
||||
BookmarkViewVisualDragItem(wxString labelValue = L"Popup");
|
||||
};
|
||||
|
||||
|
||||
|
||||
class BookmarkView : public BookmarkPanel {
|
||||
public:
|
||||
BookmarkView( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1, -1 ), long style = wxTAB_TRAVERSAL );
|
||||
|
||||
void updateActiveList();
|
||||
void updateBookmarks();
|
||||
bool isKeywordMatch(std::wstring str, std::vector<std::wstring> &keywords);
|
||||
void updateBookmarks(std::string group);
|
||||
|
||||
wxTreeItemId refreshBookmarks();
|
||||
void updateTheme();
|
||||
void onMenuItem(wxCommandEvent& event);
|
||||
bool isMouseInView();
|
||||
|
||||
bool getExpandState(std::string branchName);
|
||||
void setExpandState(std::string branchName, bool state);
|
||||
|
||||
void loadDefaultRanges();
|
||||
|
||||
protected:
|
||||
void activeSelection(DemodulatorInstance *dsel);
|
||||
void bookmarkSelection(BookmarkEntry *bmSel);
|
||||
void rangeSelection(BookmarkRangeEntry *re);
|
||||
void activateBookmark(BookmarkEntry *bmEnt);
|
||||
void activateRange(BookmarkRangeEntry *rangeEnt);
|
||||
void recentSelection(BookmarkEntry *bmSel);
|
||||
void groupSelection(std::string groupName);
|
||||
void bookmarkBranchSelection();
|
||||
void recentBranchSelection();
|
||||
void rangeBranchSelection();
|
||||
void activeBranchSelection();
|
||||
|
||||
void hideProps();
|
||||
void showProps();
|
||||
|
||||
void onUpdateTimer( wxTimerEvent& event );
|
||||
|
||||
void doUpdateActiveList();
|
||||
|
||||
void onTreeBeginLabelEdit( wxTreeEvent& event );
|
||||
void onTreeEndLabelEdit( wxTreeEvent& event );
|
||||
void onTreeActivate( wxTreeEvent& event );
|
||||
void onTreeCollapse( wxTreeEvent& event );
|
||||
void onTreeExpanded( wxTreeEvent& event );
|
||||
void onTreeItemMenu( wxTreeEvent& event );
|
||||
void onTreeSelect( wxTreeEvent& event );
|
||||
void onTreeSelectChanging( wxTreeEvent& event );
|
||||
void onLabelText( wxCommandEvent& event );
|
||||
void onDoubleClickFreq( wxMouseEvent& event );
|
||||
void onDoubleClickBandwidth( wxMouseEvent& event );
|
||||
void onTreeBeginDrag( wxTreeEvent& event );
|
||||
void onTreeEndDrag( wxTreeEvent& event );
|
||||
void onTreeItemGetTooltip( wxTreeEvent& event );
|
||||
void onEnterWindow( wxMouseEvent& event );
|
||||
void onLeaveWindow( wxMouseEvent& event );
|
||||
void onMotion( wxMouseEvent& event );
|
||||
|
||||
void onSearchTextFocus( wxMouseEvent& event );
|
||||
void onSearchText( wxCommandEvent& event );
|
||||
void onClearSearch( wxCommandEvent& event );
|
||||
|
||||
void clearButtons();
|
||||
void showButtons();
|
||||
void refreshLayout();
|
||||
|
||||
wxButton *makeButton(wxWindow *parent, std::string labelVal, wxObjectEventFunction handler);
|
||||
wxButton *addButton(wxWindow *parent, std::string labelVal, wxObjectEventFunction handler);
|
||||
|
||||
void doBookmarkActive(std::string group, DemodulatorInstance *demod);
|
||||
void doBookmarkRecent(std::string group, BookmarkEntry *be);
|
||||
void doMoveBookmark(BookmarkEntry *be, std::string group);
|
||||
void doRemoveActive(DemodulatorInstance *demod);
|
||||
void doRemoveRecent(BookmarkEntry *be);
|
||||
void doClearRecents();
|
||||
|
||||
void updateBookmarkChoices();
|
||||
void addBookmarkChoice(wxWindow *parent);
|
||||
void onBookmarkChoice( wxCommandEvent &event );
|
||||
|
||||
void onRemoveActive( wxCommandEvent& event );
|
||||
void onRemoveBookmark( wxCommandEvent& event );
|
||||
|
||||
void onActivateBookmark( wxCommandEvent& event );
|
||||
void onActivateRecent( wxCommandEvent& event );
|
||||
void onRemoveRecent ( wxCommandEvent& event );
|
||||
void onClearRecents ( wxCommandEvent& event );
|
||||
|
||||
void onAddGroup( wxCommandEvent& event );
|
||||
void onRemoveGroup( wxCommandEvent& event );
|
||||
void onRenameGroup( wxCommandEvent& event );
|
||||
|
||||
void onAddRange( wxCommandEvent& event );
|
||||
void onRemoveRange( wxCommandEvent& event );
|
||||
void onRenameRange( wxCommandEvent& event );
|
||||
void onActivateRange( wxCommandEvent& event );
|
||||
|
||||
TreeViewItem *itemToTVI(wxTreeItemId item);
|
||||
|
||||
std::atomic_bool mouseInView;
|
||||
|
||||
wxTreeItemId rootBranch, activeBranch, bookmarkBranch, recentBranch, rangeBranch;
|
||||
|
||||
std::map<std::string, bool> expandState;
|
||||
|
||||
TreeViewItem *dragItem;
|
||||
wxTreeItemId dragItemId;
|
||||
BookmarkViewVisualDragItem *visualDragItem;
|
||||
|
||||
bool editingLabel;
|
||||
|
||||
// Bookmarks
|
||||
std::atomic_bool doUpdateBookmarks;
|
||||
std::set< std::string > doUpdateBookmarkGroup;
|
||||
BookmarkNames groupNames;
|
||||
std::map<std::string, wxTreeItemId> groups;
|
||||
wxArrayString bookmarkChoices;
|
||||
wxChoice *bookmarkChoice;
|
||||
|
||||
// Active
|
||||
std::atomic_bool doUpdateActive;
|
||||
|
||||
// Focus
|
||||
BookmarkEntry *nextEnt;
|
||||
BookmarkRangeEntry *nextRange;
|
||||
DemodulatorInstance *nextDemod;
|
||||
|
||||
// Search
|
||||
std::vector<std::wstring> searchKeywords;
|
||||
};
|
61
src/forms/Dialog/ActionDialog.cpp
Normal file
61
src/forms/Dialog/ActionDialog.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include "ActionDialog.h"
|
||||
|
||||
|
||||
ActionDialog *ActionDialog::activeDialog = nullptr;
|
||||
|
||||
ActionDialog::ActionDialog( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
|
||||
: ActionDialogBase(parent, id, title, pos, size, style) {
|
||||
}
|
||||
|
||||
|
||||
ActionDialog::~ActionDialog() {
|
||||
|
||||
}
|
||||
|
||||
void ActionDialog::showDialog(ActionDialog *dlg) {
|
||||
if (activeDialog) { // rejected
|
||||
delete dlg;
|
||||
return;
|
||||
}
|
||||
activeDialog = dlg;
|
||||
dlg->Layout();
|
||||
dlg->Fit();
|
||||
dlg->ShowModal();
|
||||
}
|
||||
|
||||
ActionDialog *ActionDialog::getActiveDialog() {
|
||||
return activeDialog;
|
||||
}
|
||||
|
||||
|
||||
void ActionDialog::setActiveDialog(ActionDialog *dlg) {
|
||||
activeDialog = dlg;
|
||||
}
|
||||
|
||||
|
||||
void ActionDialog::onClickCancel( wxCommandEvent& event ) {
|
||||
ActionDialog *dlg = activeDialog;
|
||||
ActionDialog::setActiveDialog(nullptr);
|
||||
dlg->EndModal(0);
|
||||
doClickCancel();
|
||||
delete dlg;
|
||||
}
|
||||
|
||||
|
||||
void ActionDialog::onClickOK( wxCommandEvent& event ) {
|
||||
ActionDialog *dlg = activeDialog;
|
||||
ActionDialog::setActiveDialog(nullptr);
|
||||
dlg->EndModal(0);
|
||||
doClickOK();
|
||||
delete dlg;
|
||||
}
|
||||
|
||||
|
||||
void ActionDialog::doClickCancel() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ActionDialog::doClickOK() {
|
||||
|
||||
}
|
21
src/forms/Dialog/ActionDialog.h
Normal file
21
src/forms/Dialog/ActionDialog.h
Normal file
@ -0,0 +1,21 @@
|
||||
#include "ActionDialogBase.h"
|
||||
#include <mutex>
|
||||
|
||||
class ActionDialog : public ActionDialogBase {
|
||||
public:
|
||||
ActionDialog( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("QuestionTitle"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE );
|
||||
~ActionDialog();
|
||||
|
||||
void onClickCancel( wxCommandEvent& event );
|
||||
void onClickOK( wxCommandEvent& event );
|
||||
|
||||
virtual void doClickCancel();
|
||||
virtual void doClickOK();
|
||||
|
||||
static ActionDialog *getActiveDialog();
|
||||
static void setActiveDialog(ActionDialog *dlg);
|
||||
static void showDialog(ActionDialog *dlg);
|
||||
|
||||
private:
|
||||
static ActionDialog *activeDialog;
|
||||
};
|
53
src/forms/Dialog/ActionDialogBase.cpp
Normal file
53
src/forms/Dialog/ActionDialogBase.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Aug 23 2015)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "ActionDialogBase.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ActionDialogBase::ActionDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
|
||||
{
|
||||
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
|
||||
|
||||
wxBoxSizer* mainSizer;
|
||||
mainSizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_questionText = new wxStaticText( this, wxID_ANY, wxT("Question"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE );
|
||||
m_questionText->Wrap( -1 );
|
||||
mainSizer->Add( m_questionText, 1, wxALL|wxEXPAND, 5 );
|
||||
|
||||
wxBoxSizer* buttonSizer;
|
||||
buttonSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
m_cancelButton = new wxButton( this, wxID_ANY, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
buttonSizer->Add( m_cancelButton, 1, wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_okButton = new wxButton( this, wxID_ANY, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
buttonSizer->Add( m_okButton, 1, wxALL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
mainSizer->Add( buttonSizer, 1, wxEXPAND, 5 );
|
||||
|
||||
|
||||
this->SetSizer( mainSizer );
|
||||
this->Layout();
|
||||
mainSizer->Fit( this );
|
||||
|
||||
this->Centre( wxBOTH );
|
||||
|
||||
// Connect Events
|
||||
m_cancelButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ActionDialogBase::onClickCancel ), NULL, this );
|
||||
m_okButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ActionDialogBase::onClickOK ), NULL, this );
|
||||
}
|
||||
|
||||
ActionDialogBase::~ActionDialogBase()
|
||||
{
|
||||
// Disconnect Events
|
||||
m_cancelButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ActionDialogBase::onClickCancel ), NULL, this );
|
||||
m_okButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ActionDialogBase::onClickOK ), NULL, this );
|
||||
|
||||
}
|
369
src/forms/Dialog/ActionDialogBase.fbp
Normal file
369
src/forms/Dialog/ActionDialogBase.fbp
Normal file
@ -0,0 +1,369 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<wxFormBuilder_Project>
|
||||
<FileVersion major="1" minor="13" />
|
||||
<object class="Project" expanded="1">
|
||||
<property name="class_decoration"></property>
|
||||
<property name="code_generation">C++</property>
|
||||
<property name="disconnect_events">1</property>
|
||||
<property name="disconnect_mode">source_name</property>
|
||||
<property name="disconnect_php_events">0</property>
|
||||
<property name="disconnect_python_events">0</property>
|
||||
<property name="embedded_files_path">res</property>
|
||||
<property name="encoding">UTF-8</property>
|
||||
<property name="event_generation">connect</property>
|
||||
<property name="file">ActionDialogBase</property>
|
||||
<property name="first_id">1000</property>
|
||||
<property name="help_provider">none</property>
|
||||
<property name="internationalize">0</property>
|
||||
<property name="name">ActionDialogBase</property>
|
||||
<property name="namespace"></property>
|
||||
<property name="path">.</property>
|
||||
<property name="precompiled_header"></property>
|
||||
<property name="relative_path">1</property>
|
||||
<property name="skip_lua_events">1</property>
|
||||
<property name="skip_php_events">1</property>
|
||||
<property name="skip_python_events">1</property>
|
||||
<property name="ui_table">UI</property>
|
||||
<property name="use_enum">0</property>
|
||||
<property name="use_microsoft_bom">0</property>
|
||||
<object class="Dialog" expanded="1">
|
||||
<property name="aui_managed">0</property>
|
||||
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
|
||||
<property name="bg"></property>
|
||||
<property name="center">wxBOTH</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="event_handler">impl_virtual</property>
|
||||
<property name="extra_style"></property>
|
||||
<property name="fg"></property>
|
||||
<property name="font"></property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">ActionDialogBase</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size"></property>
|
||||
<property name="style">wxDEFAULT_DIALOG_STYLE</property>
|
||||
<property name="subclass"></property>
|
||||
<property name="title">QuestionTitle</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnActivate"></event>
|
||||
<event name="OnActivateApp"></event>
|
||||
<event name="OnAuiFindManager"></event>
|
||||
<event name="OnAuiPaneButton"></event>
|
||||
<event name="OnAuiPaneClose"></event>
|
||||
<event name="OnAuiPaneMaximize"></event>
|
||||
<event name="OnAuiPaneRestore"></event>
|
||||
<event name="OnAuiRender"></event>
|
||||
<event name="OnChar"></event>
|
||||
<event name="OnClose"></event>
|
||||
<event name="OnEnterWindow"></event>
|
||||
<event name="OnEraseBackground"></event>
|
||||
<event name="OnHibernate"></event>
|
||||
<event name="OnIconize"></event>
|
||||
<event name="OnIdle"></event>
|
||||
<event name="OnInitDialog"></event>
|
||||
<event name="OnKeyDown"></event>
|
||||
<event name="OnKeyUp"></event>
|
||||
<event name="OnKillFocus"></event>
|
||||
<event name="OnLeaveWindow"></event>
|
||||
<event name="OnLeftDClick"></event>
|
||||
<event name="OnLeftDown"></event>
|
||||
<event name="OnLeftUp"></event>
|
||||
<event name="OnMiddleDClick"></event>
|
||||
<event name="OnMiddleDown"></event>
|
||||
<event name="OnMiddleUp"></event>
|
||||
<event name="OnMotion"></event>
|
||||
<event name="OnMouseEvents"></event>
|
||||
<event name="OnMouseWheel"></event>
|
||||
<event name="OnPaint"></event>
|
||||
<event name="OnRightDClick"></event>
|
||||
<event name="OnRightDown"></event>
|
||||
<event name="OnRightUp"></event>
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnUpdateUI"></event>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">mainSizer</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL|wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxStaticText" expanded="0">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Question</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_questionText</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style">wxALIGN_CENTRE</property>
|
||||
<property name="subclass"></property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<property name="wrap">-1</property>
|
||||
<event name="OnChar"></event>
|
||||
<event name="OnEnterWindow"></event>
|
||||
<event name="OnEraseBackground"></event>
|
||||
<event name="OnKeyDown"></event>
|
||||
<event name="OnKeyUp"></event>
|
||||
<event name="OnKillFocus"></event>
|
||||
<event name="OnLeaveWindow"></event>
|
||||
<event name="OnLeftDClick"></event>
|
||||
<event name="OnLeftDown"></event>
|
||||
<event name="OnLeftUp"></event>
|
||||
<event name="OnMiddleDClick"></event>
|
||||
<event name="OnMiddleDown"></event>
|
||||
<event name="OnMiddleUp"></event>
|
||||
<event name="OnMotion"></event>
|
||||
<event name="OnMouseEvents"></event>
|
||||
<event name="OnMouseWheel"></event>
|
||||
<event name="OnPaint"></event>
|
||||
<event name="OnRightDClick"></event>
|
||||
<event name="OnRightDown"></event>
|
||||
<event name="OnRightUp"></event>
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnUpdateUI"></event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">buttonSizer</property>
|
||||
<property name="orient">wxHORIZONTAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL|wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxButton" expanded="0">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default">0</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Cancel</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_cancelButton</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnButtonClick">onClickCancel</event>
|
||||
<event name="OnChar"></event>
|
||||
<event name="OnEnterWindow"></event>
|
||||
<event name="OnEraseBackground"></event>
|
||||
<event name="OnKeyDown"></event>
|
||||
<event name="OnKeyUp"></event>
|
||||
<event name="OnKillFocus"></event>
|
||||
<event name="OnLeaveWindow"></event>
|
||||
<event name="OnLeftDClick"></event>
|
||||
<event name="OnLeftDown"></event>
|
||||
<event name="OnLeftUp"></event>
|
||||
<event name="OnMiddleDClick"></event>
|
||||
<event name="OnMiddleDown"></event>
|
||||
<event name="OnMiddleUp"></event>
|
||||
<event name="OnMotion"></event>
|
||||
<event name="OnMouseEvents"></event>
|
||||
<event name="OnMouseWheel"></event>
|
||||
<event name="OnPaint"></event>
|
||||
<event name="OnRightDClick"></event>
|
||||
<event name="OnRightDown"></event>
|
||||
<event name="OnRightUp"></event>
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnUpdateUI"></event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL|wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxButton" expanded="0">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default">0</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">OK</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_okButton</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnButtonClick">onClickOK</event>
|
||||
<event name="OnChar"></event>
|
||||
<event name="OnEnterWindow"></event>
|
||||
<event name="OnEraseBackground"></event>
|
||||
<event name="OnKeyDown"></event>
|
||||
<event name="OnKeyUp"></event>
|
||||
<event name="OnKillFocus"></event>
|
||||
<event name="OnLeaveWindow"></event>
|
||||
<event name="OnLeftDClick"></event>
|
||||
<event name="OnLeftDown"></event>
|
||||
<event name="OnLeftUp"></event>
|
||||
<event name="OnMiddleDClick"></event>
|
||||
<event name="OnMiddleDown"></event>
|
||||
<event name="OnMiddleUp"></event>
|
||||
<event name="OnMotion"></event>
|
||||
<event name="OnMouseEvents"></event>
|
||||
<event name="OnMouseWheel"></event>
|
||||
<event name="OnPaint"></event>
|
||||
<event name="OnRightDClick"></event>
|
||||
<event name="OnRightDown"></event>
|
||||
<event name="OnRightUp"></event>
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnUpdateUI"></event>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</wxFormBuilder_Project>
|
50
src/forms/Dialog/ActionDialogBase.h
Normal file
50
src/forms/Dialog/ActionDialogBase.h
Normal file
@ -0,0 +1,50 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Aug 23 2015)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __ACTIONDIALOGBASE_H__
|
||||
#define __ACTIONDIALOGBASE_H__
|
||||
|
||||
#include <wx/artprov.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/font.h>
|
||||
#include <wx/colour.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/dialog.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class ActionDialogBase
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class ActionDialogBase : public wxDialog
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
wxStaticText* m_questionText;
|
||||
wxButton* m_cancelButton;
|
||||
wxButton* m_okButton;
|
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void onClickCancel( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onClickOK( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
|
||||
ActionDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("QuestionTitle"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE );
|
||||
~ActionDialogBase();
|
||||
|
||||
};
|
||||
|
||||
#endif //__ACTIONDIALOGBASE_H__
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include "CubicSDR.h"
|
||||
|
||||
SDRDevicesDialog::SDRDevicesDialog( wxWindow* parent ): devFrame( parent ) {
|
||||
SDRDevicesDialog::SDRDevicesDialog( wxWindow* parent ): devFrame( parent, wxID_ANY, wxT(CUBICSDR_INSTALL_NAME " :: SDR Devices")) {
|
||||
refresh = true;
|
||||
failed = false;
|
||||
m_refreshButton->Disable();
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include "CubicSDR.h"
|
||||
#include "ColorTheme.h"
|
||||
#include "CubicSDRDefs.h"
|
||||
|
||||
@ -13,6 +14,7 @@ SpectrumPanel::SpectrumPanel() {
|
||||
floorValue = 0;
|
||||
ceilValue = 1;
|
||||
showDb = false;
|
||||
useDbOfs = false;
|
||||
fftSize = DEFAULT_FFT_SIZE;
|
||||
bandwidth = DEFAULT_DEMOD_BW;
|
||||
freq = 0;
|
||||
@ -86,6 +88,14 @@ bool SpectrumPanel::getShowDb() {
|
||||
return showDb;
|
||||
}
|
||||
|
||||
void SpectrumPanel::setUseDBOffset(bool useOfs) {
|
||||
this->useDbOfs = useOfs;
|
||||
}
|
||||
|
||||
bool SpectrumPanel::getUseDBOffset() {
|
||||
return useDbOfs;
|
||||
}
|
||||
|
||||
|
||||
void SpectrumPanel::setPoints(std::vector<float> &points) {
|
||||
this->points.assign(points.begin(), points.end());
|
||||
@ -272,11 +282,11 @@ void SpectrumPanel::drawPanelContents() {
|
||||
if (showDb) {
|
||||
float dbPanelWidth = (1.0 / viewWidth)*88.0 * GLFont::getScaleFactor();
|
||||
float dbPanelHeight = (1.0/viewHeight)*14.0 * GLFont::getScaleFactor();
|
||||
|
||||
float dbOfs = useDbOfs?wxGetApp().getConfig()->getDBOffset():0;
|
||||
|
||||
std::stringstream ssLabel("");
|
||||
if (getCeilValue() != getFloorValue() && fftSize) {
|
||||
ssLabel << std::fixed << std::setprecision(1) << (20.0 * log10(2.0*(getCeilValue())/(double)fftSize)) << "dB";
|
||||
ssLabel << std::fixed << std::setprecision(1) << (dbOfs + 20.0 * log10(2.0*(getCeilValue())/(double)fftSize)) << "dB";
|
||||
}
|
||||
dbPanelCeil.setText(ssLabel.str(), GLFont::GLFONT_ALIGN_RIGHT);
|
||||
dbPanelCeil.setSize(dbPanelWidth, dbPanelHeight);
|
||||
@ -285,7 +295,7 @@ void SpectrumPanel::drawPanelContents() {
|
||||
|
||||
ssLabel.str("");
|
||||
if (getCeilValue() != getFloorValue() && fftSize) {
|
||||
ssLabel << (20.0 * log10(2.0*(getFloorValue())/(double)fftSize)) << "dB";
|
||||
ssLabel << (dbOfs + 20.0 * log10(2.0*(getFloorValue())/(double)fftSize)) << "dB";
|
||||
}
|
||||
|
||||
dbPanelFloor.setText(ssLabel.str(), GLFont::GLFONT_ALIGN_RIGHT);
|
||||
|
@ -29,7 +29,10 @@ public:
|
||||
|
||||
void setShowDb(bool showDb);
|
||||
bool getShowDb();
|
||||
|
||||
|
||||
void setUseDBOffset(bool useOfs);
|
||||
bool getUseDBOffset();
|
||||
|
||||
protected:
|
||||
void drawPanelContents();
|
||||
|
||||
@ -43,5 +46,5 @@ private:
|
||||
|
||||
GLTextPanel dbPanelCeil;
|
||||
GLTextPanel dbPanelFloor;
|
||||
bool showDb;
|
||||
};
|
||||
bool showDb, useDbOfs;
|
||||
};
|
||||
|
@ -41,6 +41,14 @@ using namespace std;
|
||||
DataElement::DataElement() : data_type(DATA_NULL), data_size(0), unit_size(0), data_val(NULL) {
|
||||
}
|
||||
|
||||
DataElement::DataElement(DataElement &cloneFrom) : data_type(cloneFrom.getDataType()), unit_size(cloneFrom.getUnitSize()) {
|
||||
data_val = NULL;
|
||||
data_init(cloneFrom.getDataSize());
|
||||
if (data_size) {
|
||||
memcpy(data_val, cloneFrom.getDataPointer(), data_size);
|
||||
}
|
||||
}
|
||||
|
||||
DataElement::~DataElement() {
|
||||
if (data_val) {
|
||||
delete[] data_val;
|
||||
@ -427,7 +435,12 @@ std::string DataElement::toString() {
|
||||
strValue = std::to_string(floatSettingValue);
|
||||
} else if (dataType == DATA_NULL) {
|
||||
strValue = "";
|
||||
} else {
|
||||
} else if (dataType == DATA_WSTRING) {
|
||||
std::wstring wstr;
|
||||
get(wstr);
|
||||
strValue = *wstr.c_str();
|
||||
}
|
||||
else {
|
||||
std::cout << "Unhandled DataElement toString for type: " << dataType << std::endl;
|
||||
}
|
||||
} catch (DataTypeMismatchException e) {
|
||||
@ -482,6 +495,22 @@ DataNode::DataNode(const char *name_in): parentNode(NULL), ptr(0) {
|
||||
data_elem = new DataElement();
|
||||
}
|
||||
|
||||
DataNode::DataNode(const char *name_in, DataNode &cloneFrom): parentNode(NULL), ptr(0) {
|
||||
node_name = name_in;
|
||||
data_elem = new DataElement(*cloneFrom.element());
|
||||
|
||||
// TODO: stack recursion optimization
|
||||
while (cloneFrom.hasAnother()) {
|
||||
DataNode *cNode = cloneFrom.getNext();
|
||||
newChildCloneFrom(cNode->getName().c_str(), cNode);
|
||||
}
|
||||
}
|
||||
|
||||
DataNode::DataNode(const char *name_in, DataElement &cloneFrom): parentNode(NULL), ptr(0) {
|
||||
node_name = name_in;
|
||||
data_elem = new DataElement(cloneFrom);
|
||||
}
|
||||
|
||||
DataNode::~DataNode() {
|
||||
while (children.size()) {
|
||||
DataNode *del = children.back();
|
||||
@ -510,6 +539,34 @@ DataNode *DataNode::newChild(const char *name_in) {
|
||||
return children.back();
|
||||
}
|
||||
|
||||
DataNode *DataNode::newChild(const char *name_in, DataNode *otherNode) {
|
||||
children.push_back(otherNode);
|
||||
childmap[name_in].push_back(children.back());
|
||||
|
||||
children.back()->setParentNode(*this);
|
||||
|
||||
return children.back();
|
||||
}
|
||||
|
||||
DataNode *DataNode::newChildCloneFrom(const char *name_in, DataNode *cloneFrom) {
|
||||
DataNode *cloneNode = new DataNode(name_in, *cloneFrom->element());
|
||||
|
||||
children.push_back(cloneNode);
|
||||
childmap[name_in].push_back(children.back());
|
||||
children.back()->setParentNode(*this);
|
||||
|
||||
// TODO: stack recursion optimization
|
||||
while (cloneFrom->hasAnother()) {
|
||||
DataNode *cNode = cloneFrom->getNext();
|
||||
cloneNode->newChildCloneFrom(cNode->getName().c_str(), cNode);
|
||||
}
|
||||
|
||||
cloneFrom->rewind();
|
||||
|
||||
return children.back();
|
||||
}
|
||||
|
||||
|
||||
DataNode *DataNode::child(const char *name_in, int index) {
|
||||
DataNode *child_ret;
|
||||
|
||||
@ -565,6 +622,7 @@ DataNode *DataNode::getNext(const char *name_in) {
|
||||
|
||||
void DataNode::rewind() {
|
||||
ptr = 0;
|
||||
childmap_ptr.erase(childmap_ptr.begin(),childmap_ptr.end());
|
||||
}
|
||||
|
||||
void DataNode::rewind(const char *name_in) {
|
||||
@ -1342,6 +1400,38 @@ long DataTree::getSerializedSize(DataElement &de_node_names, bool debug) /* get
|
||||
return total_size;
|
||||
}
|
||||
|
||||
void DataNode::rewindAll() {
|
||||
stack<DataNode *> dn_stack;
|
||||
|
||||
/* start at the root */
|
||||
dn_stack.push(this);
|
||||
|
||||
while (!dn_stack.empty()) {
|
||||
dn_stack.top()->rewind();
|
||||
|
||||
/* if it has children, traverse into them */
|
||||
if (dn_stack.top()->hasAnother()) {
|
||||
dn_stack.push(dn_stack.top()->getNext());
|
||||
dn_stack.top()->rewind();
|
||||
} else {
|
||||
/* no more children, back out until we have children, then add next child to the top */
|
||||
while (!dn_stack.empty()) {
|
||||
if (!dn_stack.top()->hasAnother()) {
|
||||
dn_stack.top()->rewind();
|
||||
dn_stack.pop();
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
if (!dn_stack.empty()) {
|
||||
dn_stack.push(dn_stack.top()->getNext());
|
||||
dn_stack.top()->rewind();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DataNode::findAll(const char *name_in, vector<DataNode *> &node_list_out) {
|
||||
stack<DataNode *> dn_stack;
|
||||
|
||||
|
@ -128,6 +128,7 @@ private:
|
||||
|
||||
public:
|
||||
DataElement();
|
||||
DataElement(DataElement &cloneFrom);
|
||||
~DataElement();
|
||||
|
||||
int getDataType();
|
||||
@ -235,8 +236,10 @@ private:
|
||||
public:
|
||||
DataNode();
|
||||
DataNode(const char *name_in);
|
||||
|
||||
~DataNode();
|
||||
DataNode(const char *name_in, DataElement &cloneFrom);
|
||||
DataNode(const char *name_in, DataNode &cloneFrom);
|
||||
|
||||
~DataNode();
|
||||
|
||||
void setName(const char *name_in);
|
||||
string &getName() { return node_name; }
|
||||
@ -250,6 +253,8 @@ public:
|
||||
DataElement *element(); /* DataElement at this node */
|
||||
|
||||
DataNode *newChild(const char *name_in);
|
||||
DataNode *newChild(const char *name_in, DataNode *otherNode);
|
||||
DataNode *newChildCloneFrom(const char *name_in, DataNode *cloneFrom);
|
||||
DataNode *child(const char *name_in, int index = 0);
|
||||
DataNode *child(int index);
|
||||
|
||||
@ -260,7 +265,8 @@ public:
|
||||
DataNode *getNext(); /* get next child */
|
||||
void rewind(const char *name_in); /* rewind specific */
|
||||
void rewind(); /* rewind generic */
|
||||
|
||||
void rewindAll();
|
||||
|
||||
void findAll(const char *name_in, vector<DataNode *> &node_list_out);
|
||||
|
||||
// operator string () { string s; element()->get(s); return s; }
|
||||
@ -287,6 +293,7 @@ public:
|
||||
operator vector<long double> () { vector<long double> v; element()->get(v); return v; }
|
||||
|
||||
const string &operator= (const string &s) { element()->set(s); return s; }
|
||||
const wstring &operator= (const wstring &s) { element()->set(s); return s; }
|
||||
|
||||
char operator= (char i) { element()->set(i); return i; }
|
||||
unsigned char operator= (unsigned char i) { element()->set(i); return i; }
|
||||
@ -316,7 +323,6 @@ public:
|
||||
bool operator() () { return hasAnother(); }
|
||||
|
||||
DataNode *operator ^(const char *name_in) { return newChild(name_in); }
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <wx/colour.h>
|
||||
|
||||
#define COLOR_THEME_DEFAULT 0
|
||||
#define COLOR_THEME_BW 1
|
||||
@ -41,6 +42,14 @@ public:
|
||||
}
|
||||
|
||||
RGBA4f operator*(float v) { return RGBA4f(r*v, g*v, b*v); }
|
||||
|
||||
operator wxColour() {
|
||||
return wxColour(
|
||||
(unsigned char) std::min((r * 255.0), 255.0),
|
||||
(unsigned char) std::min((g * 255.0), 255.0),
|
||||
(unsigned char) std::min((b * 255.0), 255.0));
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
50
src/visual/ImagePanel.cpp
Normal file
50
src/visual/ImagePanel.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
#include "ImagePanel.h"
|
||||
|
||||
BEGIN_EVENT_TABLE(ImagePanel, wxPanel)
|
||||
EVT_PAINT(ImagePanel::paintEvent)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
|
||||
ImagePanel::ImagePanel(wxPanel * parent, wxString file, wxBitmapType format) :
|
||||
wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE) {
|
||||
image.LoadFile(file, format);
|
||||
}
|
||||
|
||||
void ImagePanel::paintEvent(wxPaintEvent & evt) {
|
||||
wxPaintDC dc(this);
|
||||
render(dc);
|
||||
}
|
||||
|
||||
|
||||
void ImagePanel::paintNow() {
|
||||
wxClientDC dc(this);
|
||||
render(dc);
|
||||
}
|
||||
|
||||
|
||||
void ImagePanel::render(wxDC& dc) {
|
||||
|
||||
double imagew = image.GetWidth();
|
||||
double imageh = image.GetHeight();
|
||||
|
||||
wxSize destSize = dc.GetSize();
|
||||
|
||||
double destw = destSize.GetWidth();
|
||||
double desth = destSize.GetHeight();
|
||||
|
||||
double sf = 1.0, wf, hf;
|
||||
|
||||
wf = destw / imagew;
|
||||
hf = desth / imageh;
|
||||
|
||||
sf = (wf < hf)?wf:hf;
|
||||
|
||||
double resulth = imageh * sf;
|
||||
double resultw = imagew * sf;
|
||||
|
||||
dc.SetUserScale(sf, sf);
|
||||
dc.DrawBitmap( image, (destw/2 - resultw/2)/sf, (desth/2 - resulth/2)/sf, false );
|
||||
}
|
||||
|
||||
|
||||
|
16
src/visual/ImagePanel.h
Normal file
16
src/visual/ImagePanel.h
Normal file
@ -0,0 +1,16 @@
|
||||
#include <wx/wx.h>
|
||||
#include <wx/sizer.h>
|
||||
|
||||
class ImagePanel : public wxPanel {
|
||||
wxBitmap image;
|
||||
|
||||
public:
|
||||
ImagePanel(wxPanel* parent, wxString file, wxBitmapType format);
|
||||
|
||||
void paintEvent(wxPaintEvent & evt);
|
||||
void paintNow();
|
||||
|
||||
void render(wxDC& dc);
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
@ -177,6 +177,14 @@ bool SpectrumCanvas::getShowDb() {
|
||||
return spectrumPanel.getShowDb();
|
||||
}
|
||||
|
||||
void SpectrumCanvas::setUseDBOfs(bool showDb) {
|
||||
spectrumPanel.setUseDBOffset(showDb);
|
||||
}
|
||||
|
||||
bool SpectrumCanvas::getUseDBOfs() {
|
||||
return spectrumPanel.getUseDBOffset();
|
||||
}
|
||||
|
||||
void SpectrumCanvas::setView(long long center_freq_in, int bandwidth_in) {
|
||||
bwChange += bandwidth_in-bandwidth;
|
||||
#define BW_RESET_TH 400000
|
||||
@ -296,7 +304,9 @@ void SpectrumCanvas::OnMouseRightReleased(wxMouseEvent& event) {
|
||||
wxGetApp().getSpectrumProcessor()->setPeakHold(wxGetApp().getSpectrumProcessor()->getPeakHold());
|
||||
|
||||
//make the peak hold act on the current dmod also, like a zoomed-in version.
|
||||
wxGetApp().getDemodSpectrumProcessor()->setPeakHold(wxGetApp().getSpectrumProcessor()->getPeakHold());
|
||||
if (wxGetApp().getDemodSpectrumProcessor()) {
|
||||
wxGetApp().getDemodSpectrumProcessor()->setPeakHold(wxGetApp().getSpectrumProcessor()->getPeakHold());
|
||||
}
|
||||
}
|
||||
mouseTracker.OnMouseRightReleased(event);
|
||||
}
|
||||
|
@ -25,6 +25,9 @@ public:
|
||||
void setShowDb(bool showDb);
|
||||
bool getShowDb();
|
||||
|
||||
void setUseDBOfs(bool showDb);
|
||||
bool getUseDBOfs();
|
||||
|
||||
void setView(long long center_freq_in, int bandwidth_in);
|
||||
void disableView();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user