diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 6712c324c2c..c0449c7b921 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -2,7 +2,7 @@ // https://github.com/microsoft/vscode-dev-containers/tree/v0.187.0/containers/cpp { "name": "edgetx-dev", - "image": "ghcr.io/edgetx/edgetx-dev:latest", + "image": "ghcr.io/edgetx/edgetx-dev:pr-24", "runArgs": [ "--ipc=host"], // Add the IDs of extensions you want installed when the container is created. diff --git a/.github/workflows/macosx_cpn.yml b/.github/workflows/macosx_cpn.yml index da813d9a704..268275478f1 100644 --- a/.github/workflows/macosx_cpn.yml +++ b/.github/workflows/macosx_cpn.yml @@ -24,7 +24,7 @@ on: env: # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) BUILD_TYPE: Release - QT_VERSION: "5.15.2" + QT_VERSION: "6.9.0" jobs: build: @@ -61,6 +61,7 @@ jobs: AQT_CONFIG: ${{ github.workspace }}/tools/aqt-settings.ini with: version: ${{ env.QT_VERSION }} + modules: 'qtmultimedia qtserialport' setup-python: 'false' cache: true cache-key-prefix: 'install-qt-action-macOS' diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 412e9d54c8f..53f25888f1c 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -5,7 +5,7 @@ on: - cron: '0 2 * * *' # run at 2 AM UTC workflow_dispatch: -concurrency: +concurrency: group: 'nightly' cancel-in-progress: true diff --git a/.github/workflows/win_cpn-64.yml b/.github/workflows/win_cpn-64.yml index 896c4d65aba..e5d562a5478 100644 --- a/.github/workflows/win_cpn-64.yml +++ b/.github/workflows/win_cpn-64.yml @@ -25,9 +25,9 @@ env: # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) BUILD_TYPE: Release CMAKE_GENERATOR: "MSYS Makefiles" - QT_VERSION: "5.15.2" - MINGW_VERSION: "win64_mingw81" - MINGW_PATH: "mingw81_64" + QT_VERSION: "6.9.0" + MINGW_VERSION: "win64_mingw" + MINGW_PATH: "mingw_64" jobs: build: @@ -83,6 +83,7 @@ jobs: cache-key-prefix: 'install-qt-action-win64' version: ${{ env.QT_VERSION }} arch: ${{ env.MINGW_VERSION }} + modules: 'qtmultimedia qtserialport' - name: Build working-directory: ${{github.workspace}} diff --git a/CMakeLists.txt b/CMakeLists.txt index 95f0b6495c1..0ad793010ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -142,7 +142,7 @@ if(NATIVE_BUILD) include(NativeTargets) else() # Prevent CMake warnings - set(IGNORE "${SDL2_LIBRARY_PATH}" "${LIBSSL1_ROOT_DIR}" "${OPENSSL_ROOT_DIR}") + set(IGNORE "${SDL2_LIBRARY_PATH}" "${LIBUSB1_ROOT_DIR}" "${OPENSSL_ROOT_DIR}") endif() add_subdirectory(${RADIO_SRC_DIR}) diff --git a/cmake/FetchMaxLibQt.cmake b/cmake/FetchMaxLibQt.cmake index 2e2d8e1e874..6268bfd70de 100644 --- a/cmake/FetchMaxLibQt.cmake +++ b/cmake/FetchMaxLibQt.cmake @@ -5,7 +5,7 @@ include(FetchContent) FetchContent_Declare( maxLibQt GIT_REPOSITORY https://github.com/edgetx/maxLibQt - GIT_TAG ac1988ffd005cd15a8449b92150ce6c08574a4f1 + GIT_TAG 6dfbfc41e258cd2446e1fd1f547e6c5d742aa2c0 ) FetchContent_MakeAvailable(maxLibQt) diff --git a/cmake/FindLibssl1.cmake b/cmake/FindLibssl1.cmake deleted file mode 100644 index 38041481ecb..00000000000 --- a/cmake/FindLibssl1.cmake +++ /dev/null @@ -1,27 +0,0 @@ -# - try to find libssl-1 library - -if (DEFINED ENV{LIBSSL1_ROOT_DIR}) - set(LIBSSL1_ROOT_DIR "$ENV{LIBSSL1_ROOT_DIR}") -endif() - -find_library(LIBSSL1_LIBRARY - NAMES - libssl.so.1.1 - libssl-1_1.dll - libssl-1_1.dylib - HINTS - "${LIBSSL1_ROOT_DIR}") - -get_filename_component(LIBSSL1_LIBRARY_PATH ${LIBSSL1_LIBRARY} PATH) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(LIBSSL1 - DEFAULT_MSG - LIBSSL1_LIBRARY_PATH) - -if(LIBSSL1_FOUND) - set(LIBSSL1_LIBRARY_DIR "${LIBSSL1_LIBRARY_PATH}") - mark_as_advanced(LIBSSL1_ROOT_DIR) -endif() - -mark_as_advanced(LIBSSL1_LIBRARY_PATH) diff --git a/cmake/FindLibusb1.cmake b/cmake/FindLibusb1.cmake index bb91e846d69..d63f22aae10 100644 --- a/cmake/FindLibusb1.cmake +++ b/cmake/FindLibusb1.cmake @@ -16,16 +16,9 @@ find_library(LIBUSB1_LIBRARY HINTS "${LIBUSB1_ROOT_DIR}") -get_filename_component(LIBUSB1_LIBRARY_PATH ${LIBUSB1_LIBRARY} PATH) - include(FindPackageHandleStandardArgs) find_package_handle_standard_args(LIBUSB1 DEFAULT_MSG - LIBUSB1_LIBRARY_PATH) - -if(LIBUSB1_FOUND) - set(LIBUSB1_LIBRARY_DIR "${LIBUSB1_LIBRARY_PATH}") - mark_as_advanced(LIBUSB1_ROOT_DIR) -endif() + LIBUSB1_LIBRARY) -mark_as_advanced(LIBUSB1_LIBRARY_PATH) +mark_as_advanced(LIBUSB1_LIBRARY) diff --git a/cmake/NativeTargets.cmake b/cmake/NativeTargets.cmake index d2df4d32d14..3bbc281a350 100644 --- a/cmake/NativeTargets.cmake +++ b/cmake/NativeTargets.cmake @@ -24,19 +24,20 @@ else() message(STATUS "SDL not found! Simulator audio, and joystick inputs, will not work.") endif() -if(Qt5Core_FOUND AND NOT DISABLE_COMPANION) +if(Qt6Core_FOUND AND NOT DISABLE_COMPANION) + # environment variable set in github workflows and build-edgetx Dockerfile + if(DEFINED ENV{LIBUSB1_ROOT_DIR}) + set(LIBUSB1_ROOT_DIR "$ENV{LIBUSB1_ROOT_DIR}") + endif() + find_package(Libusb1) + if(LIBUSB1_FOUND) find_package(Dfuutil) endif() - if(LINUX) - find_package(Libssl1) - endif() - - # OpenSSL # environment variable set in github workflows and build-edgetx Dockerfile - if (DEFINED ENV{OPENSSL_ROOT_DIR}) + if(DEFINED ENV{OPENSSL_ROOT_DIR}) set(OPENSSL_ROOT_DIR "$ENV{OPENSSL_ROOT_DIR}") endif() @@ -61,7 +62,7 @@ add_custom_target(tests-radio DEPENDS gtests-radio ) -if(Qt5Core_FOUND AND NOT DISABLE_COMPANION) +if(Qt6Core_FOUND AND NOT DISABLE_COMPANION) add_subdirectory(${COMPANION_SRC_DIRECTORY}) add_custom_target(tests-companion COMMAND ${CMAKE_CURRENT_BINARY_DIR}/gtests-companion diff --git a/cmake/QtDefs.cmake b/cmake/QtDefs.cmake index f5adf7b38d0..c298d67c4b0 100644 --- a/cmake/QtDefs.cmake +++ b/cmake/QtDefs.cmake @@ -1,29 +1,27 @@ -if(APPLE AND DEFINED ENV{HOMEBREW_PREFIX} AND EXISTS $ENV{HOMEBREW_PREFIX}/opt/qt@5) +if(APPLE AND DEFINED ENV{HOMEBREW_PREFIX}) # If Homebrew is used, HOMEBREW_PREFIX should be defined - list(APPEND CMAKE_PREFIX_PATH "$ENV{HOMEBREW_PREFIX}/opt/qt@5") + if(EXISTS $ENV{HOMEBREW_PREFIX}/opt/qt@6) + list(APPEND CMAKE_PREFIX_PATH "$ENV{HOMEBREW_PREFIX}/opt/qt@6") + endif() endif() -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTOUIC ON) +find_package(Qt6 REQUIRED COMPONENTS Core) + +if(Qt6_FOUND) + message(STATUS "Qt Version: ${Qt6_VERSION}") -find_package(Qt5Core QUIET) -find_package(Qt5Widgets QUIET) -find_package(Qt5Xml QUIET) -find_package(Qt5LinguistTools QUIET) -find_package(Qt5PrintSupport QUIET) -find_package(Qt5Multimedia QUIET) -find_package(Qt5Svg QUIET) -find_package(Qt5SerialPort QUIET) + # call after Qt6Core package is found + qt_standard_project_setup() -if(Qt5Core_FOUND) - message(STATUS "Qt Version: ${Qt5Core_VERSION}") + find_package(Qt6 REQUIRED COMPONENTS Widgets LinguistTools Multimedia PrintSupport SerialPort Svg Xml) ### Get locations of Qt binary executables & libs (libs are for distros, not for linking) # first set up some hints - get_target_property(QtCore_LOCATION Qt5::Core LOCATION) - get_filename_component(qt_core_path ${QtCore_LOCATION} PATH) + get_target_property(QtCore_LOCATION Qt::Core LOCATION) + cmake_path(GET QtCore_LOCATION ROOT_PATH qt_core_path) if(APPLE) - get_filename_component(qt_core_path "${qt_core_path}/.." ABSOLUTE) + set(qt_core_path "${qt_core_path}/..") + cmake_path(ABSOLUTE_PATH qt_core_path OUTPUT_VARIABLE qt_core_path) endif() set(QT_LIB_DIR ${qt_core_path} CACHE PATH "Path to Qt libraries (.dll|.framework|.so).") @@ -63,5 +61,5 @@ if(Qt5Core_FOUND) list(APPEND APP_COMMON_DEFINES -DAPP_DBG_HANDLER_ENABLE=0) endif() else() - message(WARNING "Qt not found! Companion and Simulator builds disabled.") + message(WARNING "Required Qt version not found! Companion, Simulator and libsim builds disabled.") endif() diff --git a/companion/src/CMakeLists.txt b/companion/src/CMakeLists.txt index eaecab5dbfb..70dcf49dab4 100644 --- a/companion/src/CMakeLists.txt +++ b/companion/src/CMakeLists.txt @@ -1,9 +1,13 @@ set(SIMULATOR_INSTALL_PREFIX "" CACHE STRING "Alternative simulator library search path") +set(COMPANION_NAME "companion") +set(SIMULATOR_NAME "simulator") +set(APP_NAME_SUFFIX "") + if(${CMAKE_SYSTEM_NAME} MATCHES "(Linux|FreeBSD)") - set(APP_NAME_SUFFIX ${VERSION_MAJOR}${VERSION_MINOR}) - set(COMPANION_NAME "companion${APP_NAME_SUFFIX}") - set(SIMULATOR_NAME "simulator${APP_NAME_SUFFIX}") + set(APP_NAME_SUFFIX "${VERSION_MAJOR}${VERSION_MINOR}") + set(COMPANION_NAME "${COMPANION_NAME}${APP_NAME_SUFFIX}") + set(SIMULATOR_NAME "${SIMULATOR_NAME}${APP_NAME_SUFFIX}") # by default cmake sets CMAKE_INSTALL_PREFIX to /usr/local however linuxdeploy works best with '/usr' as base directory if (${CMAKE_INSTALL_PREFIX} MATCHES "/usr/local") set(CMAKE_INSTALL_PREFIX "/usr") @@ -14,21 +18,14 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "(Linux|FreeBSD)") set(SIMULATOR_LIB_PATH "../lib/${COMPANION_NAME}") endif() message(STATUS "Simulators library search path: " ${SIMULATOR_LIB_PATH}) -else() - set(COMPANION_NAME "companion") - set(SIMULATOR_NAME "simulator") endif() -# This the name that the user will see in the generated DMG and what the application -# will be called under /Applications. We include the version string to make installing -# different versions for different eeproms easier, i.e. without manually renaming -set(COMPANION_OSX_APP_BUNDLE_NAME "EdgeTX Companion ${VERSION_MAJOR}.${VERSION_MINOR}") - option(DEBUG_STORAGE_IMPORT "Turn on debug output for storage import") # Disabled by default if(DEBUG_STORAGE_IMPORT) add_definitions(-DDEBUG_STORAGE_IMPORT) message(STATUS "Storage import debugging enabled") endif() + if(DEBUG) add_definitions(-DDEBUG) endif() @@ -93,8 +90,6 @@ include_directories( ############# Do macro replacements on input files ############# configure_file(${COMPANION_SRC_DIRECTORY}/version.h.in ${CMAKE_BINARY_DIR}/version.h @ONLY) -configure_file(${COMPANION_SRC_DIRECTORY}/companion.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/companion.desktop @ONLY) -configure_file(${COMPANION_SRC_DIRECTORY}/simulator.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/simulator.desktop @ONLY) ############# Translations ############### @@ -106,7 +101,7 @@ foreach(language ${LANGUAGES}) list(APPEND companion_TS translations/companion_${language}.ts) endforeach(language) # .ts -> .qm -qt5_add_translation(companion_QM ${companion_TS}) +qt_add_translation(companion_QM ${companion_TS}) # add Qt translations if found if(QT_TRANSLATIONS_DIR) @@ -139,20 +134,20 @@ else() endif() ############# Import radio hardware definitions ############### - set(HWDEFS_DIR "${CMAKE_CURRENT_BINARY_DIR}/../../radio/src") set(HWDEFS_TMPL "${COMPANION_SRC_DIRECTORY}/hwdefs.qrc.in") set(HWDEFS_PHDR "HWDEF_JSON_LIST") set(HWDEFS_QRC "${CMAKE_CURRENT_BINARY_DIR}/hwdefs.qrc") set(HWDEFS_CMD "${COMPANION_SRC_DIRECTORY}/../util/generate_hwdefs_qrc.py") +# qrc used by Companion and Simulator add_custom_command(OUTPUT ${HWDEFS_QRC} COMMAND ${HWDEFS_CMD} -d ${HWDEFS_DIR} -t ${HWDEFS_TMPL} -p ${HWDEFS_PHDR} -o ${HWDEFS_QRC} DEPENDS ${HWDEFS_TMPL} - ) +) ############# Common lib ############### @@ -175,8 +170,8 @@ set(common_RESOURCES ${HWDEFS_QRC} ) -qt5_wrap_cpp(common_SRCS ${common_MOC_HDRS}) -qt5_add_resources(common_RCC ${common_RESOURCES}) +qt_wrap_cpp(common_SRCS ${common_MOC_HDRS}) +qt_add_resources(common_RCC ${common_RESOURCES}) add_library(common ${common_SRCS} ${common_RCC}) @@ -187,10 +182,10 @@ target_link_libraries(common simulation storage maxLibQt - Qt5::Core - Qt5::Xml - Qt5::Widgets - Qt5::SerialPort + Qt::Core + Qt::Xml + Qt::Widgets + Qt::SerialPort ${SDL2_LIBRARIES} ${WIN_LINK_LIBRARIES} ) @@ -201,7 +196,6 @@ set(CPN_COMMON_LIB common) include(FetchMiniz) include(FetchYamlCpp) - include(FetchMaxLibQt) add_subdirectory(datamodels) @@ -274,8 +268,10 @@ if(WIN32) set(icon_RC images/winicons/icon.rc) endif() -add_executable(${COMPANION_NAME} MACOSX_BUNDLE ${WIN_EXECUTABLE_TYPE} ${companion_SRCS} ${companion_HDRS} ${icon_RC}) -target_link_libraries(${COMPANION_NAME} PRIVATE ${CPN_COMMON_LIB} generaledit modeledit qcustomplot miniz updates) +add_executable(${COMPANION_NAME} + MACOSX_BUNDLE ${WIN_EXECUTABLE_TYPE} ${companion_SRCS} ${companion_HDRS} ${icon_RC}) +target_link_libraries(${COMPANION_NAME} + PRIVATE ${CPN_COMMON_LIB} generaledit modeledit qcustomplot miniz updates) PrintTargetReport("${COMPANION_NAME}") @@ -283,8 +279,10 @@ PrintTargetReport("${COMPANION_NAME}") set(simu_SRCS simulator.cpp ) -add_executable(${SIMULATOR_NAME} MACOSX_BUNDLE ${WIN_EXECUTABLE_TYPE} ${simu_SRCS} ${icon_RC}) -target_link_libraries(${SIMULATOR_NAME} PRIVATE ${CPN_COMMON_LIB}) +add_executable(${SIMULATOR_NAME} + MACOSX_BUNDLE ${WIN_EXECUTABLE_TYPE} ${simu_SRCS} ${icon_RC}) +target_link_libraries(${SIMULATOR_NAME} + PRIVATE ${CPN_COMMON_LIB}) add_subdirectory(tests) @@ -292,317 +290,337 @@ add_subdirectory(tests) # the current flavour is not automatically added if build in the current cmake iteration, so always # add its library name to be sure -if(PCB STREQUAL X7 AND PCBREV STREQUAL ACCESS) - set(FLAVOUR x7access) -elseif(PCB STREQUAL X7 AND PCBREV STREQUAL T12) - set(FLAVOUR t12) -elseif(PCB STREQUAL X7 AND PCBREV STREQUAL TLITE) - set(FLAVOUR tlite) -elseif(PCB STREQUAL X7 AND PCBREV STREQUAL TLITEF4) - set(FLAVOUR tlitef4) -elseif(PCB STREQUAL X7 AND PCBREV STREQUAL TPRO) - set(FLAVOUR tpro) -elseif(PCB STREQUAL X7 AND PCBREV STREQUAL TPROV2) - set(FLAVOUR tprov2) -elseif(PCB STREQUAL X7 AND PCBREV STREQUAL TPROS) - set(FLAVOUR tpros) -elseif(PCB STREQUAL X7 AND PCBREV STREQUAL BUMBLEBEE) - set(FLAVOUR bumblebee) -elseif(PCB STREQUAL X7 AND PCBREV STREQUAL T20) - set(FLAVOUR t20) -elseif(PCB STREQUAL X7 AND PCBREV STREQUAL T20V2) - set(FLAVOUR t20v2) -elseif(PCB STREQUAL X7 AND PCBREV STREQUAL TX12) - set(FLAVOUR tx12) -elseif(PCB STREQUAL X7 AND PCBREV STREQUAL TX12MK2) - set(FLAVOUR tx12mk2) -elseif(PCB STREQUAL X7 AND PCBREV STREQUAL ZORRO) - set(FLAVOUR zorro) -elseif(PCB STREQUAL X7 AND PCBREV STREQUAL BOXER) - set(FLAVOUR boxer) -elseif(PCB STREQUAL X7 AND PCBREV STREQUAL GX12) - set(FLAVOUR gx12) -elseif(PCB STREQUAL X7 AND PCBREV STREQUAL POCKET) - set(FLAVOUR pocket) -elseif(PCB STREQUAL X7 AND PCBREV STREQUAL LR3PRO) - set(FLAVOUR lr3pro) -elseif(PCB STREQUAL X7 AND PCBREV STREQUAL COMMANDO8) - set(FLAVOUR commando8) -elseif(PCB STREQUAL X7 AND PCBREV STREQUAL T8) - set(FLAVOUR t8) -elseif(PCB STREQUAL X7 AND PCBREV STREQUAL MT12) - set(FLAVOUR mt12) -elseif(PCB STREQUAL X7 AND PCBREV STREQUAL V14) - set(FLAVOUR v14) -elseif(PCB STREQUAL X9D+ AND PCBREV STREQUAL 2019) - set(FLAVOUR x9d+2019) -elseif(PCB STREQUAL X10 AND PCBREV STREQUAL EXPRESS) - set(FLAVOUR x10express) -elseif(PCB STREQUAL X10 AND PCBREV STREQUAL TX16S) - set(FLAVOUR tx16s) -elseif(PCB STREQUAL X10 AND PCBREV STREQUAL F16) - set(FLAVOUR f16) -elseif(PCB STREQUAL X10 AND PCBREV STREQUAL V16) - set(FLAVOUR v16) -elseif(PCB STREQUAL X7 AND PCBREV STREQUAL T14) - set(FLAVOUR t14) -elseif(PCB STREQUAL X10 AND PCBREV STREQUAL T15) - set(FLAVOUR t15) -elseif(PCB STREQUAL X10 AND PCBREV STREQUAL T16) - set(FLAVOUR t16) -elseif(PCB STREQUAL X10 AND PCBREV STREQUAL T18) - set(FLAVOUR t18) -elseif(PCB STREQUAL PL18 AND PCBREV STREQUAL EL18) - set(FLAVOUR el18) -elseif(PCB STREQUAL PL18 AND PCBREV STREQUAL PL18EV) - set(FLAVOUR pl18ev) -elseif(PCB STREQUAL PL18 AND PCBREV STREQUAL PL18U) - set(FLAVOUR pl18u) -elseif(PCB STREQUAL PL18) - set(FLAVOUR pl18) -elseif(PCB STREQUAL ST16) - set(FLAVOR st16) -else() - string(TOLOWER ${PCB} FLAVOUR) +string(TOLOWER ${PCB} FLAVOUR) + +if(PCBREV) + if(PCB STREQUAL X7 AND PCBREV STREQUAL ACCESS) + set(FLAVOUR x7access) + elseif(PCB STREQUAL X9D+ AND PCBREV STREQUAL 2019) + set(FLAVOUR x9d+2019) + elseif(PCB STREQUAL X10 AND PCBREV STREQUAL EXPRESS) + set(FLAVOUR x10express) + else() + string(TOLOWER ${PCBREV} FLAVOUR) + endif() +endif(PCBREV) + +set(COMPANION_TARGETS_DIR_ROOT "${COMPANION_SRC_DIRECTORY}/../targets") + +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(COMPANION_TARGETS_DIR "${COMPANION_TARGETS_DIR_ROOT}/linux") +elseif(APPLE) + set(COMPANION_TARGETS_DIR "${COMPANION_TARGETS_DIR_ROOT}/mac") +elseif(WIN32) + set(COMPANION_TARGETS_DIR "${COMPANION_TARGETS_DIR_ROOT}/windows") endif() -include(FindDfuutil) -include(FindLibusb1) -include(FindOpenSSL) - -if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - message(STATUS "install " ${CMAKE_BINARY_DIR} " to " ${CMAKE_INSTALL_PREFIX}) - install(TARGETS ${COMPANION_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) - install(TARGETS ${SIMULATOR_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) - install(DIRECTORY ${CMAKE_BINARY_DIR}/plugins/ DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/${COMPANION_NAME}) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/companion.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications RENAME companion${APP_NAME_SUFFIX}.desktop) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/simulator.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications RENAME simulator${APP_NAME_SUFFIX}.desktop) - install(FILES images/linuxicons/16x16/companion.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/16x16/apps RENAME companion${APP_NAME_SUFFIX}.png) - install(FILES images/linuxicons/22x22/companion.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/22x22/apps RENAME companion${APP_NAME_SUFFIX}.png) - install(FILES images/linuxicons/24x24/companion.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/24x24/apps RENAME companion${APP_NAME_SUFFIX}.png) - install(FILES images/linuxicons/32x32/companion.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/32x32/apps RENAME companion${APP_NAME_SUFFIX}.png) - install(FILES images/linuxicons/48x48/companion.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/48x48/apps RENAME companion${APP_NAME_SUFFIX}.png) - install(FILES images/linuxicons/128x128/companion.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/128x128/apps RENAME companion${APP_NAME_SUFFIX}.png) - install(FILES images/linuxicons/256x256/companion.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/256x256/apps RENAME companion${APP_NAME_SUFFIX}.png) - install(FILES images/linuxicons/512x512/companion.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/512x512/apps RENAME companion${APP_NAME_SUFFIX}.png) - install(FILES images/linuxicons/scalable/companion.svg DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps RENAME companion${APP_NAME_SUFFIX}.svg) - install(FILES ../targets/linux/45-companion-taranis.rules DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/udev/rules.d RENAME 45-companion${APP_NAME_SUFFIX}-taranis.rules) - install(FILES ../targets/linux/45-usbasp.rules DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/udev/rules.d RENAME 45-companion${APP_NAME_SUFFIX}-usbasp.rules) - - if(LIBSSL1_FOUND) - install(DIRECTORY ${LIBSSL1_LIBRARY_DIR}/ DESTINATION ${CMAKE_INSTALL_PREFIX}/lib FILES_MATCHING PATTERN "libcrypto.so.*" PATTERN "libssl.so.*") +# updated license file +set(LICENSE_FILE "${CMAKE_CURRENT_BINARY_DIR}/license.txt") +configure_file("${COMPANION_TARGETS_DIR_ROOT}/license.txt.in" ${LICENSE_FILE} @ONLY) + +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + message(STATUS "Install " ${CMAKE_BINARY_DIR} " to " ${CMAKE_INSTALL_PREFIX}) + install(TARGETS ${COMPANION_NAME} + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}) + install(TARGETS ${SIMULATOR_NAME} + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}) + + # configure and set variables used by package script + set(COMPANION_DESKTOP_FILE ${CMAKE_CURRENT_BINARY_DIR}/${COMPANION_NAME}.desktop) + configure_file(${COMPANION_TARGETS_DIR}/companion.desktop.in ${COMPANION_DESKTOP_FILE} @ONLY) + + set(SIMULATOR_DESKTOP_FILE ${CMAKE_CURRENT_BINARY_DIR}/${SIMULATOR_NAME}.desktop) + configure_file(${COMPANION_TARGETS_DIR}/simulator.desktop.in ${SIMULATOR_DESKTOP_FILE} @ONLY) + + # libsim*.so files + install(DIRECTORY ${CMAKE_BINARY_DIR}/plugins/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/${COMPANION_NAME}) + + # application icons + set(icon_sizes "16;22;24;32;48;64;128;256;512") + foreach(icon_size ${icon_sizes}) + install(FILES "images/linuxicons/${icon_size}x${icon_size}/companion.png" + DESTINATION "${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/${icon_size}x${icon_size}/apps" + RENAME "${COMPANION_NAME}.png") + endforeach() + + unset(icon_size) + unset(icon_sizes) + + install(FILES "images/linuxicons/scalable/companion.svg" + DESTINATION "${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps" + RENAME "${COMPANION_NAME}.svg") + + # udev rules + install(FILES "${COMPANION_TARGETS_DIR}/45-companion-taranis.rules" + DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/udev/rules.d" + RENAME "45-${COMPANION_NAME}-taranis.rules") + + install(FILES "${COMPANION_TARGETS_DIR}/45-usbasp.rules" + DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/udev/rules.d" + RENAME "45-${COMPANION_NAME}-usbasp.rules") + + if(OPENSSL_FOUND) + get_filename_component(OPENSSL_SSL_LIBRARY_DIR ${OPENSSL_SSL_LIBRARY} DIRECTORY) + install(DIRECTORY ${OPENSSL_SSL_LIBRARY_DIR}/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/lib + FILES_MATCHING + PATTERN "libcrypto.so.*" + PATTERN "libssl.so.*") endif() if(LIBUSB1_FOUND) - install(DIRECTORY ${LIBUSB1_LIBRARY_DIR}/ DESTINATION ${CMAKE_INSTALL_PREFIX}/lib FILES_MATCHING PATTERN "libusb-1.0.so*") + get_filename_component(LIBUSB1_LIBRARY_DIR ${LIBUSB1_LIBRARY} DIRECTORY) + install(DIRECTORY ${LIBUSB1_LIBRARY_DIR}/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/lib + FILES_MATCHING PATTERN "libusb-1.0.so.*") if(DFU_UTIL_FOUND) - install(FILES "${DFU_UTIL_PATH}" DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) + # dfuutil is an app + install(FILES "${DFU_UTIL_PATH}" + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}) endif() endif() - # Linux specific code set(OperatingSystem "Linux") # Shortcut target add_custom_target(companion DEPENDS ${COMPANION_NAME}) add_custom_target(simulator DEPENDS ${SIMULATOR_NAME}) + elseif(WIN32) - set(INSTALL_DESTINATION "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_BUILD_TYPE}") - message(STATUS "Install to " ${INSTALL_DESTINATION}) - # companion & simulator binaries - install(TARGETS ${COMPANION_NAME} DESTINATION ${INSTALL_DESTINATION}) - install(TARGETS ${SIMULATOR_NAME} DESTINATION ${INSTALL_DESTINATION}) - install(DIRECTORY ${CMAKE_BINARY_DIR}/plugins/ DESTINATION ${INSTALL_DESTINATION}) + set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/_install") + message(STATUS "Install to " ${CMAKE_INSTALL_PREFIX}) + + # companion and simulator apps + install(TARGETS + ${COMPANION_NAME} + ${SIMULATOR_NAME} + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}) + + # install libsim dlls into same directory as apps + install(DIRECTORY ${CMAKE_BINARY_DIR}/plugins/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR} + COMPONENT Runtime) + + install(FILES ${LICENSE_FILE} + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}) # supporting utilities if(LIBUSB1_FOUND) + cmake_path(GET LIBUSB1_LIBRARY + PARENT_PATH + LIBUSB1_LIBRARY_DIR) + if(MINGW) + # finds dll.a directory but we need dlls but should check extension just to be sure and future proof set(LIBUSB1_LIBRARY_DIR "${LIBUSB1_LIBRARY_DIR}/../bin") endif() set(LIBUSB1_LIBRARY_FILE "${LIBUSB1_LIBRARY_DIR}/libusb-1.0.dll") if(EXISTS "${LIBUSB1_LIBRARY_FILE}") - install(FILES "${LIBUSB1_LIBRARY_FILE}" DESTINATION ${INSTALL_DESTINATION}) + install(FILES "${LIBUSB1_LIBRARY_FILE}" + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR} + COMPONENT Runtime) endif() if(DFU_UTIL_FOUND) - install(FILES "${DFU_UTIL_PATH}" DESTINATION ${INSTALL_DESTINATION}) + install(FILES "${DFU_UTIL_PATH}" + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR} + COMPONENT Runtime) endif() - endif() + endif(LIBUSB1_FOUND) if(OPENSSL_FOUND) - if ((OPENSSL_VERSION VERSION_LESS "1.2.0" AND Qt5Core_VERSION VERSION_LESS "6.0.0") OR (OPENSSL_VERSION VERSION_GREATER "3.0.0" AND Qt5Core_VERSION VERSION_GREATER_EQUAL "6.0.0")) - get_filename_component(OPENSSL_SSL_LIBRARY_DIR ${OPENSSL_SSL_LIBRARY} DIRECTORY) - if(MINGW) - # the dlls are stored in the bin directory - set(OPENSSL_SSL_LIBRARY_DIR "${OPENSSL_SSL_LIBRARY_DIR}/../bin") - endif() - if(EXISTS "${OPENSSL_SSL_LIBRARY_DIR}") - # install only files Qt networking requires - install(DIRECTORY ${OPENSSL_SSL_LIBRARY_DIR}/ DESTINATION ${INSTALL_DESTINATION} FILES_MATCHING PATTERN "libcrypto-*.dll" PATTERN "libssl-*.dll") - endif() - endif() - endif() + cmake_path(GET OPENSSL_SSL_LIBRARY + PARENT_PATH + OPENSSL_SSL_LIBRARY_DIR) - if(NOT OPENSSL_FOUND OR Qt5Core_VERSION VERSION_LESS "6.0.0") - if(MINGW AND $ENV{MSYSTEM} STREQUAL "MINGW32") - install(FILES "${COMPANION_SRC_DIRECTORY}/../targets/windows/libcrypto-1_1.dll" DESTINATION ${INSTALL_DESTINATION}) - install(FILES "${COMPANION_SRC_DIRECTORY}/../targets/windows/libssl-1_1.dll" DESTINATION ${INSTALL_DESTINATION}) - else() - # MINGW64 or assume 64 bit native - install(FILES "${COMPANION_SRC_DIRECTORY}/../targets/windows/libcrypto-1_1-x64.dll" DESTINATION ${INSTALL_DESTINATION}) - install(FILES "${COMPANION_SRC_DIRECTORY}/../targets/windows/libssl-1_1-x64.dll" DESTINATION ${INSTALL_DESTINATION}) + if(MINGW) + # the dlls are stored in the bin directory + set(OPENSSL_SSL_LIBRARY_DIR "${OPENSSL_SSL_LIBRARY_DIR}/../bin") endif() - endif() - set(LICENSE_FILE "${CMAKE_CURRENT_BINARY_DIR}/license.txt") - configure_file("${COMPANION_SRC_DIRECTORY}/../targets/windows/license.txt.in" ${LICENSE_FILE} @ONLY) - install(FILES "${LICENSE_FILE}" DESTINATION ${INSTALL_DESTINATION}) + if(EXISTS "${OPENSSL_SSL_LIBRARY_DIR}") + install(DIRECTORY ${OPENSSL_SSL_LIBRARY_DIR}/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR} + COMPONENT Runtime + FILES_MATCHING + PATTERN "libcrypto-*.dll" + PATTERN "libssl-*.dll") + + endif() + endif(OPENSSL_FOUND) if(SDL2_FOUND AND DEFINED SDL2_LIB_PATH) - install(FILES "${SDL2_LIB_PATH}" DESTINATION ${INSTALL_DESTINATION}) + install(FILES "${SDL2_LIB_PATH}" + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR} + COMPONENT Runtime) endif() - # Qt dlls (using windeployqt) - ## Qt translations are already packaged into our custom qrc. Also don't need software rendering engines. - set(wdqtopts --no-translations --no-opengl-sw --no-system-d3d-compiler --no-angle) - if(CMAKE_BUILD_TYPE STREQUAL "Release") - #set(wdqtopts ${wdqtopts} --release) # release builds aren't always properly detected with mingw - set(wdqtopts ${wdqtopts} --debug) # workaround for bug in Qt 5.15 windeployqt.exe - endif() - set(wdqtopts ${wdqtopts} -dir "\"${INSTALL_DESTINATION}\"" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${COMPANION_NAME}.exe" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${SIMULATOR_NAME}.exe") - list(JOIN wdqtopts " " wdqtopts) +elseif(APPLE) + # Qt + Cmake + Mac is poorly documented. A lot of this is guesswork + # and trial and error. Do not hesitate to fix it for the better + set_target_properties(${COMPANION_NAME} PROPERTIES + MACOSX_RPATH TRUE + MACOSX_BUNDLE TRUE + MACOSX_BUNDLE_INFO_PLIST ${COMPANION_TARGETS_DIR}/MacOSXBundleInfo.plist.in - # Add installer command to execute windeployqt - message(STATUS "windeployqt command: ${QT_BIN_DIR}/windeployqt.exe ${wdqtopts}") -endif() # WIN32 install + INSTALL_RPATH "@executable_path/../Frameworks" + BUILD_WITH_INSTALL_RPATH TRUE + ) -############# Packaging #################### + # This the name that the user will see in the generated DMG and what the application + # will be called under /Applications. We include the version string to make installing + # different versions side-by-side + set(COMPANION_OSX_APP_BUNDLE_NAME "EdgeTX Companion ${VERSION_FAMILY}") + set(MACOSX_BUNDLE_GUI_IDENTIFIER "org.edgetx.companion") -# Create Windows installer with NSIS -if(WIN32) - find_program(NSIS_EXE makensis.exe PATHS - "C:/Program Files/NSIS" - "C:/Program Files (x86)/NSIS" - "C:/Programs/NSIS" - "${WIN_EXTRA_LIBS_PATH}/NSIS" + set(companion_app_dir "companion.app") + set(companion_res_dir "${companion_app_dir}/Contents/Resources") + + # Only Companion is distributed for macOS + install(TARGETS ${COMPANION_NAME} + BUNDLE DESTINATION . COMPONENT Runtime) + + # libsims + install(DIRECTORY ${CMAKE_BINARY_DIR}/plugins/ + DESTINATION "${companion_res_dir}" + COMPONENT Runtime ) - if (NSIS_EXE) - file(TO_NATIVE_PATH "${INSTALL_DESTINATION}" NSIS_DISTRO) # all files in here will be included in installer - set(NSI_FILE "${PROJECT_BINARY_DIR}/companion/companion.nsi") - configure_file("${CMAKE_CURRENT_SOURCE_DIR}/../targets/windows/companion.nsi.in" "${NSI_FILE}" @ONLY) + # menu file + install(DIRECTORY ${COMPANION_TARGETS_DIR}/qt_menu.nib + DESTINATION "${companion_res_dir}" + COMPONENT Runtime + ) - add_custom_target(installer - # The 'install' target prepares all the distro files, make sure it has been executed first. - COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_BINARY_DIR}" --target install --config Release - COMMAND "${QT_BIN_DIR}/windeployqt.exe" "${wdqtopts}" - COMMAND "${NSIS_EXE}" "${NSI_FILE}" - DEPENDS "${NSI_FILE}" - COMMENT "Building Windows NSIS installer..." - ) - endif() + # Add icon + set(MAC_ICON_FILE ${COMPANION_SRC_DIRECTORY}/images/iconmac.icns) + set_source_files_properties( + ${MAC_ICON_FILE} + PROPERTIES MACOSX_PACKAGE_LOCATION Resources + ) + + install(FILES ${MAC_ICON_FILE} + DESTINATION ${companion_res_dir} + COMPONENT Runtime) + + if(DFU_UTIL_FOUND) + # Copy dfu-util, resolve symlink first + file(REAL_PATH "${DFU_UTIL_PATH}" DFU_UTIL_ABSOLUTE_PATH) + install(PROGRAMS ${DFU_UTIL_ABSOLUTE_PATH} + DESTINATION ${companion_res_dir} + COMPONENT Runtime) + endif(DFU_UTIL_FOUND) endif() +############# Packaging #################### + +string(TOLOWER "${PROJECT_NAME}" PROJECT_NAME_LOWERCASE) + +# Variables common to all CPack generators +set(CPACK_GENERATOR) set(CPACK_PACKAGE_NAME "companion${APP_NAME_SUFFIX}") -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Models and settings editor for the EdgeTX open source firmware") string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_PACKAGE_NAME_LOWERCASE) - +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Models and settings editor for the ${PROJECT_NAME} open source firmware") +set(CPACK_PACKAGE_VENDOR "${PROJECT_NAME}") +set(CPACK_PACKAGE_CONTACT "${PROJECT_NAME} Project Steering Committee ") +set(CPACK_PACKAGE_HOMEPAGE_URL "https://${PROJECT_NAME_LOWERCASE}.org") +set(CPACK_PACKAGE_VERSION "${VERSION_FAMILY}") +set(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR}) +set(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR}) +set(CPACK_PACKAGE_VERSION_PATCH ${VERSION_REVISION}) +set(CPACK_RESOURCE_FILE_LICENSE ${LICENSE_FILE}) # The file stripping is deliberately disabled, with the stripped file we get # very poor trace-backs from the users when they report Companion crash set(CPACK_STRIP_FILES FALSE) -# Qt5 + Cmake + Mac is poorly documented. A lot of this is guesswork -# and trial and error. Do not hesitate to fix it for the better -IF(APPLE) - set(plugin_dest_dir ${COMPANION_NAME}.app/Contents/Plugins) - set(qtconf_dest_dir ${COMPANION_NAME}.app/Contents/Resources) - set(APPS "\${CMAKE_INSTALL_PREFIX}/${COMPANION_NAME}.app") - set(companion_res_dir ${COMPANION_NAME}.app/Contents/Resources) - - set_target_properties(${COMPANION_NAME} PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Companion ${VERSION_MAJOR}.${VERSION_MINOR}") - set_target_properties(${SIMULATOR_NAME} PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Simulator ${VERSION_MAJOR}.${VERSION_MINOR}") - - # Use a non standard Info.plist that adds Retina support flags - set_target_properties(${COMPANION_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${PROJECT_SOURCE_DIR}/companion/targets/mac/MacOSXBundleInfo.plist.in) - set_target_properties(${SIMULATOR_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${PROJECT_SOURCE_DIR}/companion/targets/mac/MacOSXBundleInfo.plist.in) - - set(MACOSX_BUNDLE_GUI_IDENTIFIER "org.edgetx.companion") - - INSTALL(TARGETS ${COMPANION_NAME} - BUNDLE DESTINATION . COMPONENT Runtime - RUNTIME DESTINATION bin COMPONENT Runtime +if(WIN32) + set(companion_executable_path "\${CMAKE_INSTALL_BINDIR}/$") + set(simulator_executable_path "\${CMAKE_INSTALL_BINDIR}/$") + + qt_generate_deploy_script( + TARGET companion + OUTPUT_SCRIPT qt_deploy_script + CONTENT " + set(QT_DEPLOY_PREFIX ${CMAKE_INSTALL_PREFIX}) + qt_deploy_runtime_dependencies( + EXECUTABLE ${companion_executable_path} + ADDITIONAL_EXECUTABLES ${simulator_executable_path} + NO_TRANSLATIONS + NO_COMPILER_RUNTIME + GENERATE_QT_CONF + VERBOSE ) + " + ) - install(DIRECTORY ${CMAKE_BINARY_DIR}/plugins/ DESTINATION "${companion_res_dir}" COMPONENT Runtime) - - # Write qt.conf to tell qt where to find it plugins - file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf" - "[Paths]\nPlugins = Plugins\n") - install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf" - DESTINATION "${companion_res_dir}" - COMPONENT Runtime) - - # menu file - install(DIRECTORY ${PROJECT_SOURCE_DIR}/companion/targets/mac/qt_menu.nib DESTINATION "${companion_res_dir}" COMPONENT Runtime) - - # manually add the required plugins - foreach (plugin ${Qt5Multimedia_PLUGINS} ${Qt5PrintSupport_PLUGINS} ${Qt5Gui_PLUGINS} ${Qt5Svg_PLUGINS}) - get_target_property(QPA_PLUGIN ${plugin} LOCATION) - get_filename_component(QPA_PLUGIN_FILENAME ${QPA_PLUGIN} NAME) - # Todo is there a nicer way to get the QT Plugin directory name?! - get_filename_component(QPA_PLUGIN_DIRECTORY ${QPA_PLUGIN} DIRECTORY) - get_filename_component(QPA_PLUGIN_DIRECTORY ${QPA_PLUGIN_DIRECTORY} NAME) + # Create Windows installer with NSIS + # TODO use in-built CPack NSIS + find_program(NSIS_EXE makensis.exe + PATHS + "C:/Program Files/NSIS" + "C:/Program Files (x86)/NSIS" + "C:/Programs/NSIS" + "${WIN_EXTRA_LIBS_PATH}/NSIS" + ) - install(FILES ${QPA_PLUGIN} DESTINATION "${plugin_dest_dir}/${QPA_PLUGIN_DIRECTORY}/" COMPONENT Runtime) + if(NSIS_EXE) + # list(APPEND CPACK_GENERATOR "NSIS") + # Set CPACK_NSIS_variables - list(APPEND bundle_qt_libs "\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/${QPA_PLUGIN_DIRECTORY}/${QPA_PLUGIN_FILENAME}") - endforeach() + cmake_path(NATIVE_PATH CMAKE_INSTALL_PREFIX NORMALIZE NSIS_DISTRO) # all files in here will be included in installer + cmake_path(NATIVE_PATH COMPANION_TARGETS_DIR NORMALIZE NSIS_TARGETS_DIR) # all files in here will be included in installer + set(NSI_FILE "${PROJECT_BINARY_DIR}/companion/companion.nsi") + configure_file("${COMPANION_TARGETS_DIR}/companion.nsi.in" "${NSI_FILE}" @ONLY) - # Add icon - set(MACOSX_BUNDLE_ICON_FILE iconmac.icns) - set(MAC_ICON_FILE ${COMPANION_SRC_DIRECTORY}/images/${MACOSX_BUNDLE_ICON_FILE}) - SET_SOURCE_FILES_PROPERTIES(${MAC_ICON_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) - set(${COMPANION_SOURCES} ${COMPANION_SOURCES} ${PROJECT_SOURCE_DIR}/images/${MACOSX_BUNDLE_ICON_FILE}) - install(FILES ${MAC_ICON_FILE} DESTINATION ${companion_res_dir} COMPONENT Runtime) + # The 'install' target prepares all the distro files, make sure it has been executed first. + add_custom_target(installer + COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_BINARY_DIR}" --target install --config Release + COMMAND "${CMAKE_COMMAND}" -P "${qt_deploy_script}" + COMMAND "${NSIS_EXE}" "${NSI_FILE}" + DEPENDS "${NSI_FILE}" "${qt_deploy_script}" + COMMENT "Building Windows NSIS installer..." + ) + endif() - # Copy dfu-util, resolve symlink first - if(DFU_UTIL_FOUND) - get_filename_component(DFU_UTIL_ABSOLUTE_PATH ${DFU_UTIL_PATH} REALPATH) - install(PROGRAMS ${DFU_UTIL_ABSOLUTE_PATH} DESTINATION ${companion_res_dir} COMPONENT Runtime) +elseif(APPLE) + set(CPACK_GENERATOR "DragNDrop") + set(CPACK_BINARY_DRAGNDROP ON) - set(bundle_tools_path "\${CMAKE_INSTALL_PREFIX}/${companion_res_dir}/dfu-util;") - endif() + set(CPACK_DMG_VOLUME_NAME "${PROJECT_NAME} Companion") + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME_LOWERCASE}-${CPACK_PACKAGE_NAME_LOWERCASE}-${VERSION}") + set(CPACK_DMG_DS_STORE ${COMPANION_TARGETS_DIR}/DS_Store) + + qt_generate_deploy_script( + TARGET companion + OUTPUT_SCRIPT qt_deploy_companion + CONTENT " + qt_deploy_runtime_dependencies( + EXECUTABLE ${companion_app_dir} + ADDITIONAL_EXECUTABLES ${companion_res_dir}/dfu-util + NO_TRANSLATIONS + NO_COMPILER_RUNTIME + GENERATE_QT_CONF + ) + " + ) - if(OPENSSL_FOUND) - # Copy openssl, resolve symlink first - #get_filename_component(OPENSSL_ABSOLUTE_PATH ${OPENSSL_SSL_LIBRARY} REALPATH) - #install(FILES ${OPENSSL_ABSOLUTE_PATH} DESTINATION ${companion_res_dir} COMPONENT Runtime) - endif() + # Run macdeployqt + install(SCRIPT ${qt_deploy_companion} COMPONENT Runtime) - # Include depencies (adding frameworks, fixing the embbeded libraries) - # I get write errors without setting BU_CHMOD_BUNDLE_ITEMS even though it is - # technically a hack (that is already is in the Bundle library ...) + # Fix Code Signing and rename bundle install(CODE " - include(BundleUtilities) - file(GLOB bundle_simulator_libs \"\${CMAKE_INSTALL_PREFIX}/${companion_res_dir}/libedgetx-*${CMAKE_SHARED_LIBRARY_SUFFIX}\") - set(BU_CHMOD_BUNDLE_ITEMS on) - fixup_bundle(\"${APPS}\" \"\${bundle_simulator_libs};${bundle_qt_libs};${bundle_tools_path}\" \"${QT_LIB_DIR}\") - file(RENAME \"\${CMAKE_INSTALL_PREFIX}/${COMPANION_NAME}.app\" \"\${CMAKE_INSTALL_PREFIX}/${COMPANION_OSX_APP_BUNDLE_NAME}.app\") - " COMPONENT Runtime) -endif() - -if(APPLE) - set(CPACK_GENERATOR "DragNDrop") -# set(CPACK_GENERATOR "TGZ") # for quick testing - set(CPACK_BINARY_DRAGNDROP ON) - set(CPACK_DMG_BACKGROUND_IMAGE ${COMPANION_SRC_DIRECTORY}/images/splash_dmg.png) - set(CPACK_DMG_VOLUME_NAME "EdgeTX Companion") - set(CPACK_DMG_DS_STORE ${PROJECT_SOURCE_DIR}/companion/targets/mac/DS_Store) - set(CPACK_PACKAGE_FILE_NAME "edgetx-${CPACK_PACKAGE_NAME_LOWERCASE}-${VERSION}") -endif(APPLE) + set(app_dir \"\${CMAKE_INSTALL_PREFIX}/${companion_app_dir}\") + execute_process(COMMAND \${CMAKE_COMMAND} -E echo \"Re-signing: \${app_dir}\") + execute_process( + COMMAND codesign --remove-signature \${app_dir} + COMMAND codesign --force --deep -s - \${app_dir} + ) + file(RENAME \"\${app_dir}\" \"\${CMAKE_INSTALL_PREFIX}/${COMPANION_OSX_APP_BUNDLE_NAME}.app\") + " COMPONENT Runtime) -if (CMAKE_SYSTEM_NAME STREQUAL "Linux") +else() set(LINUXDEPLOY_APPIMAGE "linuxdeploy-x86_64.AppImage") set(LINUXDEPLOY_PLUGIN_QT "linuxdeploy-plugin-qt-x86_64.AppImage") set(LINUXDEPLOY_URL "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous") @@ -610,7 +628,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux") set(LINUXDEPLOY_DIRECTORY "${CMAKE_BINARY_DIR}/linuxdeploy") set(LINUXDEPLOY_APP "${LINUXDEPLOY_DIRECTORY}/usr/bin/linuxdeploy") - if (NOT EXISTS "${LINUXDEPLOY_DIRECTORY}") + if(NOT EXISTS "${LINUXDEPLOY_DIRECTORY}") message(STATUS "Downloading linuxdeploy and plugins...") file(DOWNLOAD "${LINUXDEPLOY_URL}/${LINUXDEPLOY_APPIMAGE}" "${CMAKE_BINARY_DIR}/${LINUXDEPLOY_APPIMAGE}") @@ -642,16 +660,17 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux") WORKING_DIRECTORY "${CMAKE_BINARY_DIR}") # test installation - #execute_process( - # COMMAND ${LINUXDEPLOY_APP} --list-plugins - # WORKING_DIRECTORY "${CMAKE_BINARY_DIR}") + execute_process( + COMMAND ${LINUXDEPLOY_APP} --list-plugins + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}") endif() + list(APPEND CPACK_GENERATOR "External") set(CPACK_PACKAGE_DIRECTORY "${CMAKE_BINARY_DIR}") - set(CPACK_GENERATOR "External") - - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CPackLinuxDeploy.cmake.in "${CMAKE_BINARY_DIR}/CPackExternal.cmake" @ONLY) + set(APPIMAGE_DIR "${CPACK_PACKAGE_DIRECTORY}/_CPack_Packages/Linux/External/AppImage") + configure_file("${COMPANION_TARGETS_DIR}/CPackLinuxDeploy.cmake.in" "${CMAKE_BINARY_DIR}/CPackExternal.cmake" @ONLY) set(CPACK_EXTERNAL_PACKAGE_SCRIPT "${CMAKE_BINARY_DIR}/CPackExternal.cmake") endif() include(CPack) + diff --git a/companion/src/CPackLinuxDeploy.cmake.in b/companion/src/CPackLinuxDeploy.cmake.in deleted file mode 100644 index d6078067e49..00000000000 --- a/companion/src/CPackLinuxDeploy.cmake.in +++ /dev/null @@ -1,13 +0,0 @@ -set(APP_DIR "@CPACK_PACKAGE_DIRECTORY@/_CPack_Packages/Linux/External/AppImage") - -execute_process(COMMAND @CMAKE_MAKE_PROGRAM@ DESTDIR=${APP_DIR} install - WORKING_DIRECTORY @CMAKE_BINARY_DIR@) - -set(cpn_desktop_file ${APP_DIR}@CMAKE_INSTALL_PREFIX@/share/applications/@COMPANION_NAME@.desktop) -#set(icon_file ${APP_DIR}@CMAKE_INSTALL_PREFIX@/share/applications/@COMPANION_NAME@.desktop) - -# This is done by cmake install target -# setup Companion application -# add -v0 to linuxdeploy for debug info -execute_process(COMMAND env NO_APPSTREAM=1 @LINUXDEPLOY_APP@ --appdir ${APP_DIR} -e @COMPANION_NAME@ -d ${cpn_desktop_file} --plugin qt --output appimage - WORKING_DIRECTORY @CMAKE_BINARY_DIR@) diff --git a/companion/src/apppreferencesdialog.cpp b/companion/src/apppreferencesdialog.cpp index ee51eff3f74..d07a7824618 100644 --- a/companion/src/apppreferencesdialog.cpp +++ b/companion/src/apppreferencesdialog.cpp @@ -450,8 +450,8 @@ void AppPreferencesDialog::initSettings() } }); - connect(ui->chkDelDecompress, &QCheckBox::stateChanged, [=](const int checked) { - if (!checked) { + connect(ui->chkDelDecompress, &QCheckBox::checkStateChanged, [=](const int checked) { + if (!checked) { if (ui->chkDecompressDirUseDwnld->isChecked()) { ui->chkDelDownloads->setEnabled(false); ui->chkDelDownloads->setChecked(false); diff --git a/companion/src/companion.cpp b/companion/src/companion.cpp index 4371ce28dde..0d9a072fc74 100644 --- a/companion/src/companion.cpp +++ b/companion/src/companion.cpp @@ -59,7 +59,7 @@ class MyProxyStyle : public QProxyStyle void importError() { - QMessageBox::critical(nullptr, CPN_STR_APP_NAME, QCoreApplication::translate("Companion", "The saved settings could not be imported, please try again or continue with current settings."), QMessageBox::Ok, 0); + QMessageBox::critical(nullptr, CPN_STR_APP_NAME, QCoreApplication::translate("Companion", "The saved settings could not be imported, please try again or continue with current settings."), QMessageBox::Ok, QMessageBox::NoButton); } void checkSettingsImport(bool force = false) @@ -72,19 +72,23 @@ void checkSettingsImport(bool force = false) if (!found && !force) return; - QString msg; if (previousVersion.isEmpty()) { const QString impFileBtn = QCoreApplication::translate("Companion", "Import from File"); const QString impNoneBtn = QCoreApplication::translate("Companion", "Do not import"); + QString msg; + if (found) msg = QCoreApplication::translate("Companion", "We have found possible Companion settings backup file(s).\nDo you want to import settings from a file?"); else msg = QCoreApplication::translate("Companion", "Import settings from a file, or start with current values."); - const int ret = QMessageBox::question(nullptr, CPN_STR_APP_NAME, msg, impNoneBtn, impFileBtn, 0, 0); + QMessageBox msgBox(QMessageBox::Question, CPN_STR_APP_NAME, msg); + msgBox.addButton(impFileBtn, QMessageBox::AcceptRole); + QPushButton *btnCancel = msgBox.addButton(impNoneBtn, QMessageBox::RejectRole); + msgBox.exec(); - if (!ret) + if (msgBox.clickedButton() == btnCancel) return; } else { @@ -131,11 +135,6 @@ void printHelpText() int main(int argc, char *argv[]) { -#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) - /* From doc: This attribute must be set before Q(Gui)Application is constructed. */ - QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); -#endif - QApplication app(argc, argv); app.setApplicationName(APP_COMPANION); app.setOrganizationName(COMPANY); diff --git a/companion/src/firmwares/CMakeLists.txt b/companion/src/firmwares/CMakeLists.txt index 165e324e180..3e20dc37d22 100644 --- a/companion/src/firmwares/CMakeLists.txt +++ b/companion/src/firmwares/CMakeLists.txt @@ -70,8 +70,6 @@ target_include_directories(${PROJECT_NAME} ${CMAKE_CURRENT_BINARY_DIR} PUBLIC "${CMAKE_CURRENT_LIST_DIR}" - "${CMAKE_CURRENT_LIST_DIR}/er9x" - "${CMAKE_CURRENT_LIST_DIR}/ersky9x" "${CMAKE_CURRENT_LIST_DIR}/opentx" "${CMAKE_CURRENT_LIST_DIR}/edgetx" ) diff --git a/companion/src/firmwares/boards.cpp b/companion/src/firmwares/boards.cpp index b6af8929e5d..c80df5f81fe 100644 --- a/companion/src/firmwares/boards.cpp +++ b/companion/src/firmwares/boards.cpp @@ -365,7 +365,7 @@ int Boards::getCapability(Board::Type board, Board::Capability capability) return ((IS_TARANIS_X9LITE(board) || (IS_TARANIS_XLITE(board) && !IS_TARANIS_X9LITES(board)) || IS_TARANIS_X9DP_2019(board) || IS_TARANIS_X7_ACCESS(board) || IS_RADIOMASTER_ZORRO(board) || IS_RADIOMASTER_TX12_MK2(board) || IS_RADIOMASTER_BOXER(board) || IS_RADIOMASTER_POCKET(board) || - IS_RADIOMASTER_MT12(board) || IS_RADIOMASTER_GX12(board) || IS_JUMPER_T20(board) || + IS_RADIOMASTER_MT12(board) || IS_RADIOMASTER_GX12(board) || IS_JUMPER_T20(board) || IS_JUMPER_BUMBLEBEE(board)) || IS_FAMILY_T16(board) || IS_FAMILY_HORUS(board) || (getCapability(board, HasExternalModuleSupport) && (IS_TARANIS(board) && !IS_FAMILY_T12(board)))); @@ -726,31 +726,25 @@ AbstractStaticItemModel * Boards::switchTypeItemModel() QList Boards::getSupportedInternalModules(Board::Type board) { QList modules; - modules = {(int)MODULE_TYPE_NONE}; + modules.append((int)MODULE_TYPE_NONE); if (IS_TARANIS_X9DP_2019(board) || IS_TARANIS_X7_ACCESS(board)) { - modules.append({(int)MODULE_TYPE_ISRM_PXX2}); + modules.append((int)MODULE_TYPE_ISRM_PXX2); } else if (IS_FLYSKY_NV14(board)) { - modules.append({(int)MODULE_TYPE_FLYSKY_AFHDS2A}); + modules.append((int)MODULE_TYPE_FLYSKY_AFHDS2A); } else if (IS_FLYSKY_EL18(board)) { - modules.append({ - (int)MODULE_TYPE_FLYSKY_AFHDS3, - (int)MODULE_TYPE_CROSSFIRE, - }); + modules.append((int)MODULE_TYPE_FLYSKY_AFHDS3); + modules.append((int)MODULE_TYPE_CROSSFIRE); } else if (IS_RADIOMASTER_MT12(board)) { - modules.append({ - (int)MODULE_TYPE_CROSSFIRE, - (int)MODULE_TYPE_MULTIMODULE, - }); + modules.append((int)MODULE_TYPE_CROSSFIRE); + modules.append((int)MODULE_TYPE_MULTIMODULE); } else if (IS_FAMILY_HORUS_OR_T16(board) || IS_FAMILY_T12(board) || (IS_TARANIS_SMALL(board) && IS_ACCESS_RADIO(board))) { - modules.append({ - (int)MODULE_TYPE_XJT_PXX1, - (int)MODULE_TYPE_ISRM_PXX2, - (int)MODULE_TYPE_CROSSFIRE, - (int)MODULE_TYPE_MULTIMODULE, - }); + modules.append((int)MODULE_TYPE_XJT_PXX1); + modules.append((int)MODULE_TYPE_ISRM_PXX2); + modules.append((int)MODULE_TYPE_CROSSFIRE); + modules.append((int)MODULE_TYPE_MULTIMODULE); } else if (IS_TARANIS(board)) { - modules.append({(int)MODULE_TYPE_XJT_PXX1}); + modules.append((int)MODULE_TYPE_XJT_PXX1); } return modules; diff --git a/companion/src/firmwares/modeldata.cpp b/companion/src/firmwares/modeldata.cpp index b2160b8e5f6..840ffb19398 100644 --- a/companion/src/firmwares/modeldata.cpp +++ b/companion/src/firmwares/modeldata.cpp @@ -965,7 +965,7 @@ void ModelData::updateTypeValueRef(R & curRef, const T type, const int idxAdj, c newRef.value += updRefInfo.shift; - if (newRef.value < (updRefInfo.index1 + idxAdj) || newRef.value > (updRefInfo.maxindex + idxAdj)) { + if ((newRef.value < (updRefInfo.index1 + idxAdj)) || (newRef.value > (updRefInfo.maxindex + idxAdj))) { if (defClear) newRef.clear(); else { diff --git a/companion/src/firmwares/radiodata.cpp b/companion/src/firmwares/radiodata.cpp index f5e10958346..ee96a86d402 100644 --- a/companion/src/firmwares/radiodata.cpp +++ b/companion/src/firmwares/radiodata.cpp @@ -72,14 +72,13 @@ void RadioData::fixModelFilenames() QString RadioData::getNextModelFilename() { - const bool hasSDCard = Boards::getCapability(getCurrentFirmware()->getBoard(), Board::HasSDCard); char filename[sizeof(ModelData::filename)]; - int index = 0; + int8_t index = 0; bool found = true; while (found) { - sprintf(filename, "model%d.%s", ++index, hasSDCard ? "yml" : "bin"); + sprintf(filename, "model%d.yml", ++index); found = false; - for (unsigned int i=0; i b.getCapability(Board::SwitchesPositions)) return false; diff --git a/companion/src/firmwares/sourcenumref.cpp b/companion/src/firmwares/sourcenumref.cpp index 520e44ee1d7..6aa7fac032b 100644 --- a/companion/src/firmwares/sourcenumref.cpp +++ b/companion/src/firmwares/sourcenumref.cpp @@ -58,9 +58,8 @@ SourceNumRefEditor::SourceNumRefEditor(int & srcNumValue, QCheckBox * chkUseSour model(model), lock(false) { - if (chkUseSource) { - connect(chkUseSource, &QCheckBox::stateChanged, this, &SourceNumRefEditor::chkUseSourceChanged); - } + if (chkUseSource) + connect(chkUseSource, &QCheckBox::checkStateChanged, this, &SourceNumRefEditor::chkUseSourceChanged); if (sbxValue) { sbxValue->setMinimum(minValue); diff --git a/companion/src/generaledit/CMakeLists.txt b/companion/src/generaledit/CMakeLists.txt index 44389805e07..a5c2c26fc38 100644 --- a/companion/src/generaledit/CMakeLists.txt +++ b/companion/src/generaledit/CMakeLists.txt @@ -21,7 +21,7 @@ add_library(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME} PRIVATE ${CPN_COMMON_LIB} - Qt5::Multimedia + Qt::Multimedia ) target_include_directories(${PROJECT_NAME} diff --git a/companion/src/generaledit/generalsetup.cpp b/companion/src/generaledit/generalsetup.cpp index 11df5dbed7e..da6ec49948b 100644 --- a/companion/src/generaledit/generalsetup.cpp +++ b/companion/src/generaledit/generalsetup.cpp @@ -439,7 +439,7 @@ void GeneralSetupPanel::populateVoiceLangCB() { NULL, NULL }}; b->clear(); - for (int i = 0; strings[i][0] != NULL; i++) { + for (int i = 0; !strings[i][0].isNull(); i++) { b->addItem(strings[i][0],strings[i][1]); if (generalSettings.ttsLanguage == strings[i][1]) { b->setCurrentIndex(b->count() - 1); diff --git a/companion/src/generaledit/hardware.cpp b/companion/src/generaledit/hardware.cpp index 59973b8fa40..5d58b85fbbd 100644 --- a/companion/src/generaledit/hardware.cpp +++ b/companion/src/generaledit/hardware.cpp @@ -446,8 +446,7 @@ void HardwarePanel::addFlex(int index) AutoComboBox *type = new AutoComboBox(this); setFlexTypeModel(type, index); - int & flexType = (int &)config.flexType; - type->setField(flexType, this); + type->setField(config.flexType, this); connect(type, &AutoComboBox::currentDataChanged, [=] (int val) { AbstractItemModel *mdl = editorItemModels->getItemModel(AbstractItemModel::IMID_FlexSwitches); @@ -531,8 +530,7 @@ void HardwarePanel::addSwitch(int index) else type->setModel(tabFilteredModels->getItemModel(FIM_SWITCHTYPE3POS)); - int & swtype = (int &)config.type; - type->setField(swtype, this); + type->setField(config.type, this); params->append(type); if (generalSettings.isSwitchFlex(index)) { diff --git a/companion/src/helpers.cpp b/companion/src/helpers.cpp index e895d9c2960..9417f4b3733 100644 --- a/companion/src/helpers.cpp +++ b/companion/src/helpers.cpp @@ -371,13 +371,14 @@ void startSimulation(QWidget * parent, RadioData & radioData, int modelIdx) simuData->setCurrentModel(modelIdx); } -#ifdef __APPLE__ SimulatorMainWindow * dialog = new SimulatorMainWindow(parent, simulatorId, flags); dialog->setWindowModality(Qt::ApplicationModal); dialog->setAttribute(Qt::WA_DeleteOnClose); QObject::connect(dialog, &SimulatorMainWindow::destroyed, [simuData] (void) { +#ifdef __APPLE__ simulatorRunning = false; +#endif // TODO simuData and Horus tmp directory is deleted on simulator close OR we could use it to get back data from the simulation delete simuData; }); @@ -389,70 +390,14 @@ void startSimulation(QWidget * parent, RadioData & radioData, int modelIdx) QMessageBox::critical(NULL, QCoreApplication::translate("Companion", "Simulator Error"), resultMsg); dialog->deleteLater(); } else if (dialog->setRadioData(simuData)) { +#ifdef __APPLE__ simulatorRunning = true; +#endif dialog->show(); } else { QMessageBox::critical(NULL, QCoreApplication::translate("Companion", "Data Load Error"), QCoreApplication::translate("Companion", "Error occurred while starting simulator.")); dialog->deleteLater(); } -#else - // the directory will be automatically deleted when QTemporaryDir goes out of scope - QTemporaryDir tmpDir(QDir::tempPath() + "/etx-XXXXXX"); - if (tmpDir.isValid()) { - qDebug() << "Created temporary settings directory" << tmpDir.path(); - } - else { - QString resultMsg = QCoreApplication::translate("Companion", "Error creating temporary directory for models and settings."); - QMessageBox::critical(NULL, QCoreApplication::translate("Companion", "Simulator Error"), resultMsg); - return; - } - - simuData->fixModelFilenames(); - Storage storage(tmpDir.path()); - if (!storage.write(*simuData)) { - QString resultMsg = QCoreApplication::translate("Companion", "Error writing models and settings to temporary directory."); - QMessageBox::critical(NULL, QCoreApplication::translate("Companion", "Simulator Error"), resultMsg); - return; - } - - const QString path = QCoreApplication::applicationDirPath(); - -#if defined Q_OS_WIN - const QString program = "simulator.exe"; -#elif defined Q_OS_APPLE - const QString program = "simulator.dmg"; -#else - const QString program = QString("simulator%1%2").arg(VERSION_MAJOR).arg(VERSION_MINOR); -#endif - - QStringList arguments; - arguments << "--profile" << g.currentProfile().name() - << "--start-with" << "folder" - << "--flags" << QString::number(flags) - << tmpDir.path(); - - QProcess *simu = new QProcess(parent); - - qDebug() << "Launching simulator with command:" << QDir::toNativeSeparators(path % "/" % program) << arguments; - - // wait for the simulator to finish - int result = simu->execute(path % "/" % program, arguments); - - QString resultMsg; - - if (result == -2) - resultMsg = QCoreApplication::translate("Companion", "Unable to start."); - else if (result == -1) - resultMsg = QCoreApplication::translate("Companion", "Crashed."); - else if (result > 0) - resultMsg = QCoreApplication::translate("Companion", "Exited with result code:") % QString(result); - - if (result != 0) - QMessageBox::critical(NULL, QCoreApplication::translate("Companion", "Simulator Error"), resultMsg); - - if (simuData) - delete simuData; -#endif } QPixmap makePixMap(const QImage & image) diff --git a/companion/src/images/linuxicons/64x64/companion.png b/companion/src/images/linuxicons/64x64/companion.png new file mode 100644 index 00000000000..fb1a3f2459b Binary files /dev/null and b/companion/src/images/linuxicons/64x64/companion.png differ diff --git a/companion/src/images/originals/9CX.xcf b/companion/src/images/originals/9CX.xcf deleted file mode 100644 index 167a1ad102b..00000000000 Binary files a/companion/src/images/originals/9CX.xcf and /dev/null differ diff --git a/companion/src/images/originals/9xdb-bl.xcf b/companion/src/images/originals/9xdb-bl.xcf deleted file mode 100644 index 8b09f5c82c8..00000000000 Binary files a/companion/src/images/originals/9xdb-bl.xcf and /dev/null differ diff --git a/companion/src/images/originals/9xdb-gr.xcf b/companion/src/images/originals/9xdb-gr.xcf deleted file mode 100644 index 416ea3f504f..00000000000 Binary files a/companion/src/images/originals/9xdb-gr.xcf and /dev/null differ diff --git a/companion/src/images/originals/9xdb-or.xcf b/companion/src/images/originals/9xdb-or.xcf deleted file mode 100644 index 0bbe3113b47..00000000000 Binary files a/companion/src/images/originals/9xdb-or.xcf and /dev/null differ diff --git a/companion/src/images/originals/9xdb-rd.xcf b/companion/src/images/originals/9xdb-rd.xcf deleted file mode 100644 index b1a38946529..00000000000 Binary files a/companion/src/images/originals/9xdb-rd.xcf and /dev/null differ diff --git a/companion/src/images/originals/9xdb-yl.xcf b/companion/src/images/originals/9xdb-yl.xcf deleted file mode 100644 index 6fc4e78839e..00000000000 Binary files a/companion/src/images/originals/9xdb-yl.xcf and /dev/null differ diff --git a/companion/src/images/originals/9xdb.xcf b/companion/src/images/originals/9xdb.xcf deleted file mode 100644 index d0ed5459391..00000000000 Binary files a/companion/src/images/originals/9xdb.xcf and /dev/null differ diff --git a/companion/src/images/originals/companion-title.xcf b/companion/src/images/originals/companion-title.xcf deleted file mode 100644 index 808d8f4bc69..00000000000 Binary files a/companion/src/images/originals/companion-title.xcf and /dev/null differ diff --git a/companion/src/images/originals/logotypes/firmware_logo.xcf b/companion/src/images/originals/logotypes/firmware_logo.xcf deleted file mode 100644 index ced05eb12cd..00000000000 Binary files a/companion/src/images/originals/logotypes/firmware_logo.xcf and /dev/null differ diff --git a/companion/src/images/originals/logotypes/old_opentx_companion_logo.odg b/companion/src/images/originals/logotypes/old_opentx_companion_logo.odg deleted file mode 100644 index a4c4278c84e..00000000000 Binary files a/companion/src/images/originals/logotypes/old_opentx_companion_logo.odg and /dev/null differ diff --git a/companion/src/images/originals/logotypes/opentx_2_logo.png b/companion/src/images/originals/logotypes/opentx_2_logo.png deleted file mode 100644 index aae169a8af9..00000000000 Binary files a/companion/src/images/originals/logotypes/opentx_2_logo.png and /dev/null differ diff --git a/companion/src/images/originals/logotypes/opentx_2_logo.svg b/companion/src/images/originals/logotypes/opentx_2_logo.svg deleted file mode 100644 index 41b597ebe6e..00000000000 --- a/companion/src/images/originals/logotypes/opentx_2_logo.svg +++ /dev/null @@ -1,361 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/companion/src/images/originals/logotypes/opentx_companion_logo.png b/companion/src/images/originals/logotypes/opentx_companion_logo.png deleted file mode 100644 index a7c3a90320f..00000000000 Binary files a/companion/src/images/originals/logotypes/opentx_companion_logo.png and /dev/null differ diff --git a/companion/src/images/originals/logotypes/opentx_companion_logo.svg b/companion/src/images/originals/logotypes/opentx_companion_logo.svg deleted file mode 100644 index 90a78b883a3..00000000000 --- a/companion/src/images/originals/logotypes/opentx_companion_logo.svg +++ /dev/null @@ -1,334 +0,0 @@ - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/companion/src/images/originals/logotypes/opentx_logo.png b/companion/src/images/originals/logotypes/opentx_logo.png deleted file mode 100644 index f1af0cdb496..00000000000 Binary files a/companion/src/images/originals/logotypes/opentx_logo.png and /dev/null differ diff --git a/companion/src/images/originals/logotypes/opentx_logo.svg b/companion/src/images/originals/logotypes/opentx_logo.svg deleted file mode 100644 index 95f040b1585..00000000000 --- a/companion/src/images/originals/logotypes/opentx_logo.svg +++ /dev/null @@ -1,340 +0,0 @@ - -image/svg+xml -O -P -E -N - \ No newline at end of file diff --git a/companion/src/images/originals/logotypes/opentx_logo_128x128.png b/companion/src/images/originals/logotypes/opentx_logo_128x128.png deleted file mode 100644 index 9b4ad31a219..00000000000 Binary files a/companion/src/images/originals/logotypes/opentx_logo_128x128.png and /dev/null differ diff --git a/companion/src/images/originals/logotypes/opentx_logo_16x16.png b/companion/src/images/originals/logotypes/opentx_logo_16x16.png deleted file mode 100644 index 7fa027e149c..00000000000 Binary files a/companion/src/images/originals/logotypes/opentx_logo_16x16.png and /dev/null differ diff --git a/companion/src/images/originals/logotypes/opentx_logo_22x22.png b/companion/src/images/originals/logotypes/opentx_logo_22x22.png deleted file mode 100644 index b71e62d6aeb..00000000000 Binary files a/companion/src/images/originals/logotypes/opentx_logo_22x22.png and /dev/null differ diff --git a/companion/src/images/originals/logotypes/opentx_logo_24x24.png b/companion/src/images/originals/logotypes/opentx_logo_24x24.png deleted file mode 100644 index 0ae5ffe178c..00000000000 Binary files a/companion/src/images/originals/logotypes/opentx_logo_24x24.png and /dev/null differ diff --git a/companion/src/images/originals/logotypes/opentx_logo_256x256.png b/companion/src/images/originals/logotypes/opentx_logo_256x256.png deleted file mode 100644 index 1ed7a9ae9bd..00000000000 Binary files a/companion/src/images/originals/logotypes/opentx_logo_256x256.png and /dev/null differ diff --git a/companion/src/images/originals/logotypes/opentx_logo_32x32.png b/companion/src/images/originals/logotypes/opentx_logo_32x32.png deleted file mode 100644 index 0b7375c0cd7..00000000000 Binary files a/companion/src/images/originals/logotypes/opentx_logo_32x32.png and /dev/null differ diff --git a/companion/src/images/originals/logotypes/opentx_logo_48x48.png b/companion/src/images/originals/logotypes/opentx_logo_48x48.png deleted file mode 100644 index d591f97d280..00000000000 Binary files a/companion/src/images/originals/logotypes/opentx_logo_48x48.png and /dev/null differ diff --git a/companion/src/images/originals/logotypes/opentx_logo_512x512.png b/companion/src/images/originals/logotypes/opentx_logo_512x512.png deleted file mode 100644 index 6938b2c424e..00000000000 Binary files a/companion/src/images/originals/logotypes/opentx_logo_512x512.png and /dev/null differ diff --git a/companion/src/images/originals/logotypes/opentx_logo_64x64.png b/companion/src/images/originals/logotypes/opentx_logo_64x64.png deleted file mode 100644 index 0ae7c8682cf..00000000000 Binary files a/companion/src/images/originals/logotypes/opentx_logo_64x64.png and /dev/null differ diff --git a/companion/src/images/originals/logotypes/opentx_logo_96x96.png b/companion/src/images/originals/logotypes/opentx_logo_96x96.png deleted file mode 100644 index 2936917c757..00000000000 Binary files a/companion/src/images/originals/logotypes/opentx_logo_96x96.png and /dev/null differ diff --git a/companion/src/images/originals/splash.xcf b/companion/src/images/originals/splash.xcf deleted file mode 100644 index 4130570dd15..00000000000 Binary files a/companion/src/images/originals/splash.xcf and /dev/null differ diff --git a/companion/src/images/originals/splasht.xcf b/companion/src/images/originals/splasht.xcf deleted file mode 100644 index 66466d2cc6a..00000000000 Binary files a/companion/src/images/originals/splasht.xcf and /dev/null differ diff --git a/companion/src/images/originals/windows-icon.xcf b/companion/src/images/originals/windows-icon.xcf deleted file mode 100644 index 7cf9bcf7144..00000000000 Binary files a/companion/src/images/originals/windows-icon.xcf and /dev/null differ diff --git a/companion/src/logsdialog.cpp b/companion/src/logsdialog.cpp index 384037a6f1d..3352a8f9ed3 100644 --- a/companion/src/logsdialog.cpp +++ b/companion/src/logsdialog.cpp @@ -80,8 +80,7 @@ LogsDialog::LogsDialog(QWidget *parent) : timeTicker->setDateTimeFormat("hh:mm:ss.zzz"); axisRect->axis(QCPAxis::atBottom)->setTicker(timeTicker); QDateTime now = QDateTime::currentDateTime(); - axisRect->axis(QCPAxis::atBottom)->setRange(now.addSecs(-60 * 60 * 2).toTime_t(), now.toTime_t()); - + axisRect->axis(QCPAxis::atBottom)->setRange(now.addSecs(-60 * 60 * 2).toMSecsSinceEpoch(), now.toMSecsSinceEpoch()); axisRect->axis(QCPAxis::atLeft)->setTickLabels(false); axisRect->addAxis(QCPAxis::atLeft); axisRect->addAxis(QCPAxis::atRight); @@ -884,13 +883,12 @@ void LogsDialog::plotLogs() if (plotCoords.max_y < y) plotCoords.max_y = y; if (time_str.contains('.')) { - time = QDateTime::fromString(time_str, "yyyy-MM-dd HH:mm:ss.zzz") - .toTime_t(); + time = QDateTime::fromString(time_str, "yyyy-MM-dd HH:mm:ss.zzz").toMSecsSinceEpoch(); time += time_str.mid(time_str.indexOf('.')).toDouble(); } else { - time = QDateTime::fromString(time_str, "yyyy-MM-dd HH:mm:ss") - .toTime_t(); + time = QDateTime::fromString(time_str, "yyyy-MM-dd HH:mm:ss").toMSecsSinceEpoch(); } + plotCoords.x.push_back(time); if(plots.min_x == INVALID_MIN) diff --git a/companion/src/mainwindow.cpp b/companion/src/mainwindow.cpp index 3c1110e486e..f4a2610422d 100644 --- a/companion/src/mainwindow.cpp +++ b/companion/src/mainwindow.cpp @@ -1426,7 +1426,7 @@ void MainWindow::importAppSettings() // Do the import QSettings fromSettings(impFile, QSettings::IniFormat); if (!g.importSettings(&fromSettings)) { - QMessageBox::critical(this, CPN_STR_APP_NAME, tr("The settings could not be imported."), QMessageBox::Ok, 0); + QMessageBox::critical(this, CPN_STR_APP_NAME, tr("The settings could not be imported."), QMessageBox::Ok); return; } resultMsg = tr("" \ diff --git a/companion/src/mdichild.cpp b/companion/src/mdichild.cpp index ac1e1b6c59d..709e9ad0890 100644 --- a/companion/src/mdichild.cpp +++ b/companion/src/mdichild.cpp @@ -1426,7 +1426,7 @@ void MdiChild::setCurrentFile(const QString & fileName) void MdiChild::forceNewFilename(const QString & suffix, const QString & ext) { - curFile.replace(QRegExp("\\.(eepe|bin|hex|otx|etx)$"), suffix + "." + ext); + curFile.replace(QRegularExpression("\\.(eepe|bin|hex|otx|etx)$"), suffix + "." + ext); } bool MdiChild::convertStorage(Board::Type from, Board::Type to, bool newFile) @@ -1518,8 +1518,7 @@ void MdiChild::writeSettings(StatusDialog * status, bool toRadio) // write to T QCheckBox *cb = new QCheckBox(tr("Do not show this message again")); msgbox.setCheckBox(cb); - connect(cb, &QCheckBox::stateChanged, [=](const int &state){ g.confirmWriteModelsAndSettings(!state); }); - + connect(cb, &QCheckBox::checkStateChanged, [=](const int &state){ g.confirmWriteModelsAndSettings(!state); }); if (msgbox.exec() == QMessageBox::Abort) return; } diff --git a/companion/src/modeledit/CMakeLists.txt b/companion/src/modeledit/CMakeLists.txt index ab5ce980e69..c8e13e38842 100644 --- a/companion/src/modeledit/CMakeLists.txt +++ b/companion/src/modeledit/CMakeLists.txt @@ -28,7 +28,7 @@ set(${PROJECT_NAME}_NAMES AddHeadersSources() # AUTOMOC does not detect so manually process -qt5_wrap_cpp(${PROJECT_NAME}_SRCS +qt_wrap_cpp(${PROJECT_NAME}_SRCS ${${PROJECT_NAME}_HDRS} ) @@ -39,7 +39,7 @@ add_library(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME} PRIVATE ${CPN_COMMON_LIB} - Qt5::Multimedia + Qt::Multimedia ) target_include_directories(${PROJECT_NAME} diff --git a/companion/src/modeledit/customfunctions.cpp b/companion/src/modeledit/customfunctions.cpp index 1d27330ce6e..13c53ef50de 100644 --- a/companion/src/modeledit/customfunctions.cpp +++ b/companion/src/modeledit/customfunctions.cpp @@ -31,6 +31,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, functions(model ? model->customFn : generalSettings.customFn), mediaPlayerCurrent(-1), mediaPlayer(nullptr), + audioOutput(new QAudioOutput()), modelsUpdateCnt(0) { lock = true; @@ -245,16 +246,16 @@ CustomFunctionsPanel::~CustomFunctionsPanel() delete tabFilterFactory; } -void CustomFunctionsPanel::onMediaPlayerStateChanged(QMediaPlayer::State state) +void CustomFunctionsPanel::onMediaPlayerPlaybackStateChanged(QMediaPlayer::PlaybackState state) { if (state != QMediaPlayer::PlayingState) stopSound(mediaPlayerCurrent); } -void CustomFunctionsPanel::onMediaPlayerError(QMediaPlayer::Error error) +void CustomFunctionsPanel::onMediaPlayerErrorOccurred(QMediaPlayer::Error error, const QString &errorString) { stopSound(mediaPlayerCurrent); - QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Error occurred while trying to play sound, possibly the file is already opened. (Err: %1 [%2])").arg(mediaPlayer ? mediaPlayer->errorString() : "").arg(error)); + QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Error occurred while trying to play sound, possibly the file is already opened. (Err: %1 [%2])").arg(errorString).arg(error)); } bool CustomFunctionsPanel::playSound(int index) @@ -288,13 +289,16 @@ bool CustomFunctionsPanel::playSound(int index) if (mediaPlayer) stopSound(mediaPlayerCurrent); - mediaPlayer = new QMediaPlayer(this, QMediaPlayer::LowLatency); + mediaPlayer = new QMediaPlayer(this); + mediaPlayer->setAudioOutput(audioOutput); + if (functions[index].func == FuncPlaySound) - mediaPlayer->setMedia(QUrl(path.prepend("qrc"))); + mediaPlayer->setSource(QUrl(path.prepend("qrc"))); else - mediaPlayer->setMedia(QUrl::fromLocalFile(path)); - connect(mediaPlayer, &QMediaPlayer::stateChanged, this, &CustomFunctionsPanel::onMediaPlayerStateChanged); - connect(mediaPlayer, static_cast(&QMediaPlayer::error), this, &CustomFunctionsPanel::onMediaPlayerError); + mediaPlayer->setSource(QUrl::fromLocalFile(path)); + + connect(mediaPlayer, &QMediaPlayer::playbackStateChanged, this, &CustomFunctionsPanel::onMediaPlayerPlaybackStateChanged); + connect(mediaPlayer, &QMediaPlayer::errorOccurred, this, &CustomFunctionsPanel::onMediaPlayerErrorOccurred); mediaPlayerCurrent = index; mediaPlayer->play(); return true; @@ -304,7 +308,9 @@ void CustomFunctionsPanel::stopSound(int index) { if (index > -1 && index < (int)DIM(playBT)) playBT[index]->setChecked(false); + mediaPlayerCurrent = -1; + if (mediaPlayer) { disconnect(mediaPlayer, 0, this, 0); mediaPlayer->stop(); diff --git a/companion/src/modeledit/customfunctions.h b/companion/src/modeledit/customfunctions.h index c64ef860cf6..29b4b4ea2bd 100644 --- a/companion/src/modeledit/customfunctions.h +++ b/companion/src/modeledit/customfunctions.h @@ -27,6 +27,7 @@ #include "filtereditemmodels.h" #include +#include class TimerEdit; @@ -53,8 +54,9 @@ class CustomFunctionsPanel : public GenericPanel bool playSound(int index); void stopSound(int index); void toggleSound(bool play); - void onMediaPlayerStateChanged(QMediaPlayer::State state); - void onMediaPlayerError(QMediaPlayer::Error error); + void onMediaPlayerPlaybackStateChanged(QMediaPlayer::PlaybackState state); + void onMediaPlayerErrorOccurred(QMediaPlayer::Error error, const QString &errorString); + void cmDelete(); void cmCopy(); void cmPaste(); @@ -107,6 +109,7 @@ class CustomFunctionsPanel : public GenericPanel QComboBox * fswtchRepeat[CPN_MAX_SPECIAL_FUNCTIONS]; QComboBox * fswtchGVmode[CPN_MAX_SPECIAL_FUNCTIONS]; QMediaPlayer * mediaPlayer; + QAudioOutput * audioOutput; int selectedIndex; int fswCapability; diff --git a/companion/src/modeledit/inputs.cpp b/companion/src/modeledit/inputs.cpp index eb423fde22e..a2523d2d7bf 100644 --- a/companion/src/modeledit/inputs.cpp +++ b/companion/src/modeledit/inputs.cpp @@ -391,41 +391,53 @@ void InputsPanel::expoAdd() gm_openExpo(index); } +QAction * InputsPanel::addAct(const QString & icon, const QString & text, const char * slot, const QKeySequence & shortcut, bool enabled) +{ + QAction * newAction = new QAction(this); + newAction->setMenuRole(QAction::NoRole); + newAction->setText(text); + newAction->setIcon(CompanionIcon(icon)); + newAction->setShortcut(shortcut); + newAction->setEnabled(enabled); + connect(newAction, SIGNAL(triggered()), this, slot); + return newAction; +} + void InputsPanel::expolistWidget_customContextMenuRequested(QPoint pos) { QPoint globalPos = ExposlistWidget->mapToGlobal(pos); const QClipboard *clipboard = QApplication::clipboard(); const QMimeData *mimeData = clipboard->mimeData(); - bool hasData = mimeData->hasFormat(MIMETYPE_EXPO); + bool hasClipData = mimeData->hasFormat(MIMETYPE_EXPO); selectedIdx = getIndexFromSelected(); inputIdx = getInputIndexFromSelected(); QMenu contextMenu; QMenu *contextMenuLines = contextMenu.addMenu(tr("Lines")); - contextMenuLines->addAction(CompanionIcon("add.png"), tr("&Add"), this, SLOT(expoAdd()), tr("Ctrl+A")); - contextMenuLines->addAction(CompanionIcon("edit.png"), tr("&Edit"), this, SLOT(expoOpen()), tr("Enter")); + contextMenuLines->addAction(addAct("add.png", tr("&Add"), SLOT(expoAdd()), tr("Ctrl+A"))); + contextMenuLines->addAction(addAct("edit.png", tr("&Edit"), SLOT(expoOpen()), tr("Enter"))); contextMenuLines->addSeparator(); - contextMenuLines->addAction(CompanionIcon("clear.png"), tr("&Delete"), this, SLOT(exposDelete()), tr("Delete")); - contextMenuLines->addAction(CompanionIcon("copy.png"), tr("&Copy"), this, SLOT(exposCopy()), tr("Ctrl+C")); - contextMenuLines->addAction(CompanionIcon("cut.png"), tr("&Cut"), this, SLOT(exposCut()), tr("Ctrl+X")); - contextMenuLines->addAction(CompanionIcon("paste.png"), tr("&Paste"), this, SLOT(exposPaste()), tr("Ctrl+V"))->setEnabled(hasData); - contextMenuLines->addAction(CompanionIcon("duplicate.png"), tr("Du&plicate"), this, SLOT(exposDuplicate()), tr("Ctrl+U")); + contextMenuLines->addAction(addAct("clear.png", tr("&Delete"), SLOT(exposDelete()), tr("Delete"))); + contextMenuLines->addAction(addAct("copy.png", tr("&Copy"), SLOT(exposCopy()), tr("Ctrl+C"))); + contextMenuLines->addAction(addAct("cut.png", tr("&Cut"), SLOT(exposCut()), tr("Ctrl+X"))); + contextMenuLines->addAction(addAct("paste.png", tr("&Paste"), SLOT(exposPaste()), tr("Ctrl+V"), hasClipData)); + contextMenuLines->addAction(addAct("duplicate.png", tr("Du&plicate"), SLOT(exposDuplicate()), tr("Ctrl+U"))); contextMenuLines->addSeparator(); - contextMenuLines->addAction(CompanionIcon("moveup.png"), tr("Move Up"), this, SLOT(moveExpoUp()), tr("Ctrl+Up")); - contextMenuLines->addAction(CompanionIcon("movedown.png"), tr("Move Down"), this, SLOT(moveExpoDown()), tr("Ctrl+Down")); + contextMenuLines->addAction(addAct("moveup.png", tr("Move Up"), SLOT(moveExpoUp()), tr("Ctrl+Up"))); + contextMenuLines->addAction(addAct("movedown.png", tr("Move Down"), SLOT(moveExpoDown()), tr("Ctrl+Down"))); QMenu *contextMenuInputs = contextMenu.addMenu(tr("Input")); - contextMenuInputs->addAction(CompanionIcon("arrow-right.png"), tr("Insert"), this, SLOT(cmInputInsert()))->setEnabled(cmInputInsertAllowed()); - contextMenuInputs->addAction(CompanionIcon("arrow-left.png"), tr("Delete"), this, SLOT(cmInputDelete())); - contextMenuInputs->addAction(CompanionIcon("moveup.png"), tr("Move Up"), this, SLOT(cmInputMoveUp()))->setEnabled(cmInputMoveUpAllowed()); - contextMenuInputs->addAction(CompanionIcon("movedown.png"), tr("Move Down"), this, SLOT(cmInputMoveDown()))->setEnabled(cmInputMoveDownAllowed()); + contextMenuInputs->addAction(addAct("arrow-right.png", tr("Insert"), SLOT(cmInputInsert()), 0, cmInputInsertAllowed())); + contextMenuInputs->addAction(addAct("arrow-left.png", tr("Delete"), SLOT(cmInputDelete()), 0)); + contextMenuInputs->addAction(addAct("moveup.png", tr("Move Up"), SLOT(cmInputMoveUp()), 0, cmInputMoveUpAllowed())); + contextMenuInputs->addAction(addAct("movedown.png", tr("Move Down"), SLOT(cmInputMoveDown()), 0, cmInputMoveDownAllowed())); contextMenuInputs->addSeparator(); - contextMenuInputs->addAction(CompanionIcon("clear.png"), tr("Clear"), this, SLOT(cmInputClear()))->setEnabled(isExpoIndex(selectedIdx)); + contextMenuInputs->addAction(addAct("clear.png", tr("Clear"), SLOT(cmInputClear()), 0, isExpoIndex(selectedIdx))); contextMenu.addSeparator(); - contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear All"), this, SLOT(clearExpos())); + contextMenu.addAction(addAct( "clear.png", tr("Clear All"), SLOT(clearExpos()))); contextMenu.addSeparator(); contextMenu.addActions(ExposlistWidget->actions()); contextMenu.exec(globalPos); diff --git a/companion/src/modeledit/inputs.h b/companion/src/modeledit/inputs.h index ab4f00973e3..c5108e0372a 100644 --- a/companion/src/modeledit/inputs.h +++ b/companion/src/modeledit/inputs.h @@ -96,4 +96,5 @@ class InputsPanel : public ModelPanel int getInputIndexFromSelected(); void updateItemModels(); void connectItemModelEvents(const int id); + QAction * addAct(const QString & icon, const QString & text, const char * slot, const QKeySequence & shortcut = 0, bool enabled = true); }; diff --git a/companion/src/modeledit/mixerslistwidget.cpp b/companion/src/modeledit/mixerslistwidget.cpp index 783bf6877a7..da65d802484 100644 --- a/companion/src/modeledit/mixerslistwidget.cpp +++ b/companion/src/modeledit/mixerslistwidget.cpp @@ -131,7 +131,7 @@ void MixersListWidget::dropEvent(QDropEvent * event) else { event->acceptProposedAction(); } - dropMimeData(indexAt(event->pos()).row(), event->mimeData(), event->dropAction()); + dropMimeData(indexAt(event->position().toPoint()).row(), event->mimeData(), event->dropAction()); } } diff --git a/companion/src/modeledit/mixes.cpp b/companion/src/modeledit/mixes.cpp index 409150193c8..1af673ddc88 100644 --- a/companion/src/modeledit/mixes.cpp +++ b/companion/src/modeledit/mixes.cpp @@ -419,27 +419,39 @@ void MixesPanel::mixerAdd() gm_openMix(index); } +QAction * MixesPanel::addAct(const QString & icon, const QString & text, const char * slot, const QKeySequence & shortcut, bool enabled) +{ + QAction * newAction = new QAction(this); + newAction->setMenuRole(QAction::NoRole); + newAction->setText(text); + newAction->setIcon(CompanionIcon(icon)); + newAction->setShortcut(shortcut); + newAction->setEnabled(enabled); + connect(newAction, SIGNAL(triggered()), this, slot); + return newAction; +} + void MixesPanel::mixerlistWidget_customContextMenuRequested(QPoint pos) { QPoint globalPos = mixersListWidget->mapToGlobal(pos); const QClipboard *clipboard = QApplication::clipboard(); const QMimeData *mimeData = clipboard->mimeData(); - bool hasData = mimeData->hasFormat("application/x-companion-mix"); + bool hasClipData = mimeData->hasFormat("application/x-companion-mix"); QMenu contextMenu; - contextMenu.addAction(CompanionIcon("add.png"), tr("&Add"), this, SLOT(mixerAdd()), tr("Ctrl+A")); - contextMenu.addAction(CompanionIcon("edit.png"), tr("&Edit"), this, SLOT(mixerOpen()), tr("Enter")); - contextMenu.addAction(CompanionIcon("fuses.png"), tr("&Toggle highlight"), this, SLOT(mixerHighlight()), tr("Ctrl+T")); + contextMenu.addAction(addAct("add.png", tr("&Add"), SLOT(mixerAdd()), tr("Ctrl+A"))); + contextMenu.addAction(addAct("edit.png", tr("&Edit"), SLOT(mixerOpen()), tr("Enter"))); + contextMenu.addAction(addAct("fuses.png", tr("&Toggle highlight"), SLOT(mixerHighlight()), tr("Ctrl+T"))); contextMenu.addSeparator(); - contextMenu.addAction(CompanionIcon("clear.png"), tr("&Delete"), this, SLOT(mixersDelete()), tr("Delete")); - contextMenu.addAction(CompanionIcon("copy.png"), tr("&Copy"), this, SLOT(mixersCopy()), tr("Ctrl+C")); - contextMenu.addAction(CompanionIcon("cut.png"), tr("C&ut"), this, SLOT(mixersCut()), tr("Ctrl+X")); - contextMenu.addAction(CompanionIcon("paste.png"), tr("&Paste"), this, SLOT(mixersPaste()), tr("Ctrl+V"))->setEnabled(hasData); - contextMenu.addAction(CompanionIcon("duplicate.png"), tr("Du&plicate"), this, SLOT(mixersDuplicate()), tr("Ctrl+U")); + contextMenu.addAction(addAct("clear.png", tr("&Delete"), SLOT(mixersDelete()), tr("Delete"))); + contextMenu.addAction(addAct("copy.png", tr("&Copy"), SLOT(mixersCopy()), tr("Ctrl+C"))); + contextMenu.addAction(addAct("cut.png", tr("C&ut"), SLOT(mixersCut()), tr("Ctrl+X"))); + contextMenu.addAction(addAct("paste.png", tr("&Paste"), SLOT(mixersPaste()), tr("Ctrl+V"), hasClipData)); + contextMenu.addAction(addAct("duplicate.png", tr("Du&plicate"), SLOT(mixersDuplicate()), tr("Ctrl+U"))); contextMenu.addSeparator(); - contextMenu.addAction(CompanionIcon("moveup.png"), tr("Move Up"), this, SLOT(moveMixUp()), tr("Ctrl+Up")); - contextMenu.addAction(CompanionIcon("movedown.png"), tr("Move Down"), this, SLOT(moveMixDown()), tr("Ctrl+Down")); + contextMenu.addAction(addAct("moveup.png", tr("Move Up"), SLOT(moveMixUp()), tr("Ctrl+Up"))); + contextMenu.addAction(addAct("movedown.png", tr("Move Down"), SLOT(moveMixDown()), tr("Ctrl+Down"))); contextMenu.addSeparator(); contextMenu.addActions(mixersListWidget->actions()); diff --git a/companion/src/modeledit/mixes.h b/companion/src/modeledit/mixes.h index 0eb30ac92fd..7ed3e85b717 100644 --- a/companion/src/modeledit/mixes.h +++ b/companion/src/modeledit/mixes.h @@ -19,8 +19,7 @@ * GNU General Public License for more details. */ -#ifndef _MIXES_H_ -#define _MIXES_H_ +#pragma once #include "modeledit.h" #include "mixerslistwidget.h" @@ -84,6 +83,5 @@ class MixesPanel : public ModelPanel QString getMixerText(int dest, bool newChannel); void connectItemModelEvents(const int id); void updateItemModels(); + QAction * addAct(const QString & icon, const QString & text, const char * slot, const QKeySequence & shortcut = 0, bool enabled = true); }; - -#endif // _MIXES_H_ diff --git a/companion/src/multimodelprinter.cpp b/companion/src/multimodelprinter.cpp index 257855cc3d6..d29cd201814 100644 --- a/companion/src/multimodelprinter.cpp +++ b/companion/src/multimodelprinter.cpp @@ -550,7 +550,7 @@ QString MultiModelPrinter::printOutputs() for (int i=0; igetCapability(Outputs); i++) { int count = 0; for (int k=0; k < modelPrinterMap.size(); k++) - count = std::max(count, modelPrinterMap.value(k).first->mixes(i).size()); + count = std::max(count, (int)modelPrinterMap.value(k).first->mixes(i).size()); if (!count) continue; columns.appendRowStart(); @@ -606,7 +606,7 @@ QString MultiModelPrinter::printInputs() for (int i=0; igetCapability(VirtualInputs)); i++) { int count = 0; for (int k=0; k < modelPrinterMap.size(); k++) { - count = std::max(count, modelPrinterMap.value(k).first->expos(i).size()); + count = std::max(count, (int)modelPrinterMap.value(k).first->expos(i).size()); } if (count > 0) { columns.appendRowStart(); @@ -636,7 +636,7 @@ QString MultiModelPrinter::printMixers() for (int i=0; igetCapability(Outputs); i++) { int count = 0; for (int k=0; k < modelPrinterMap.size(); k++) { - count = std::max(count, modelPrinterMap.value(k).first->mixes(i).size()); + count = std::max(count, (int)modelPrinterMap.value(k).first->mixes(i).size()); } if (count > 0) { columns.appendRowStart(); diff --git a/companion/src/process_sync.cpp b/companion/src/process_sync.cpp index 2edb4e2df59..24a394bf0a4 100644 --- a/companion/src/process_sync.cpp +++ b/companion/src/process_sync.cpp @@ -26,6 +26,10 @@ #include #include +#ifdef Q_OS_WIN +#include +#endif + #define SYNC_MAX_ERRORS 50 // give up after this many errors per destination // a flood of log messages can make the UI unresponsive so we'll introduce a dynamic sleep period based on log frequency (values in [us]) @@ -34,10 +38,6 @@ #define PAUSE_MINTM 100UL #define PAUSE_MAXTM 75000UL -#if (QT_VERSION < QT_VERSION_CHECK(5, 5, 0)) - #define QtInfoMsg QtMsgType(4) -#endif - #define PRINT_CREATE(str) emitProgressMessage((str), QtInfoMsg) #define PRINT_REPLACE(str) emitProgressMessage((str), QtWarningMsg) //#define PRINT_DELETE(str) emitProgressMessage((str), QtCriticalMsg) // unused @@ -46,13 +46,6 @@ #define PRINT_INFO(str) emit progressMessage((str)) // this is always emitted regardless of logLevel option #define PRINT_SEP() PRINT_INFO(QString(70, '=')) -#ifdef Q_OS_WIN - extern Q_CORE_EXPORT int qt_ntfs_permission_lookup; - #define FILTER_RE_SYNTX QRegExp::Wildcard -#else - #define FILTER_RE_SYNTX QRegExp::WildcardUnix -#endif - SyncProcess::SyncProcess(const SyncProcess::SyncOptions & options) : m_options(options), m_pauseTime(PAUSE_MINTM), @@ -60,6 +53,10 @@ SyncProcess::SyncProcess(const SyncProcess::SyncOptions & options) : { qRegisterMetaType(); +#ifdef Q_OS_WIN + QNtfsPermissionCheckGuard permissionGuard; // check is enabled +#endif + if (m_options.compareType == OVERWR_ALWAYS && (m_options.direction == SYNC_A2B_B2A || m_options.direction == SYNC_B2A_A2B)) m_options.compareType = OVERWR_IF_DIFF; @@ -72,23 +69,18 @@ SyncProcess::SyncProcess(const SyncProcess::SyncOptions & options) : if (!m_options.excludeFilter.isEmpty()) { for (const QString & f : m_options.excludeFilter.split(',', Qt::SkipEmptyParts)) - m_excludeFilters.append(QRegExp(f, ((m_dirFilters & QDir::CaseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive), FILTER_RE_SYNTX)); + m_excludeFilters.append(QRegularExpression(QRegularExpression::wildcardToRegularExpression(f), + ((m_dirFilters & QDir::CaseSensitive) ? QRegularExpression::NoPatternOption : QRegularExpression::CaseInsensitiveOption))); } if (m_options.flags & OPT_DRY_RUN) testRunStr = tr("[TEST RUN] "); //qDebug() << m_options; -#ifdef Q_OS_WIN - qt_ntfs_permission_lookup++; // global enable NTFS permissions checking -#endif -} +} // for Q_OS_WIN as the permissionGuard goes out of scope the check is disabled SyncProcess::~SyncProcess() { -#ifdef Q_OS_WIN - qt_ntfs_permission_lookup--; // global revert NTFS permissions checking -#endif } void SyncProcess::stop() @@ -193,8 +185,8 @@ SyncProcess::FileFilterResult SyncProcess::fileFilter(const QFileInfo & fileInfo return FILE_OVERSIZE; if (!m_excludeFilters.isEmpty() && (!(m_dirFilters & QDir::AllDirs) || fileInfo.isFile())) { - for (QVector::const_iterator it = m_excludeFilters.constBegin(), end = m_excludeFilters.constEnd(); it != end; ++it) { - if (QRegExp(*it).exactMatch(fileInfo.fileName())) + for (QVector::const_iterator it = m_excludeFilters.constBegin(), end = m_excludeFilters.constEnd(); it != end; ++it) { + if (QRegularExpression(*it).match(fileInfo.fileName()).hasMatch()) return FILE_EXCLUDE; } } diff --git a/companion/src/process_sync.h b/companion/src/process_sync.h index 3ec1f532861..9fa83097944 100644 --- a/companion/src/process_sync.h +++ b/companion/src/process_sync.h @@ -19,8 +19,7 @@ * GNU General Public License for more details. */ -#ifndef PROCESS_SYNC_H -#define PROCESS_SYNC_H +#pragma once #include #include @@ -28,7 +27,7 @@ #include #include #include -#include +#include #include class SyncProcess : public QObject @@ -139,7 +138,7 @@ class SyncProcess : public QObject SyncStatus m_stat; QReadWriteLock stopReqMutex; QString testRunStr; - QVector m_excludeFilters; + QVector m_excludeFilters; QStringList m_dirIteratorFilters; QDir::Filters m_dirFilters; QDateTime m_startTime; @@ -151,5 +150,3 @@ Q_DECLARE_METATYPE(SyncProcess::SyncOptions) Q_DECLARE_TYPEINFO(SyncProcess::SyncOptions, Q_MOVABLE_TYPE); Q_DECLARE_METATYPE(SyncProcess::SyncStatus) Q_DECLARE_TYPEINFO(SyncProcess::SyncStatus, Q_PRIMITIVE_TYPE); - -#endif // PROCESS_SYNC_H diff --git a/companion/src/shared/CMakeLists.txt b/companion/src/shared/CMakeLists.txt index 52df91c58e0..0b284cd967a 100644 --- a/companion/src/shared/CMakeLists.txt +++ b/companion/src/shared/CMakeLists.txt @@ -32,7 +32,7 @@ set(${PROJECT_NAME}_HDRS ) # AUTOMOC does not detect so manually process -qt5_wrap_cpp(${PROJECT_NAME}_SRCS +qt_wrap_cpp(${PROJECT_NAME}_SRCS ${${PROJECT_NAME}_HDRS} ) diff --git a/companion/src/shared/autobitmappedcombobox.h b/companion/src/shared/autobitmappedcombobox.h index 0a0168cafe2..5d3e0d5613c 100644 --- a/companion/src/shared/autobitmappedcombobox.h +++ b/companion/src/shared/autobitmappedcombobox.h @@ -52,7 +52,7 @@ class AutoBitMappedComboBox : public QComboBox, public AutoWidget void setField(RawSwitch & field, GenericPanel * panel = nullptr); void setAutoIndexes(); - void setModel(QAbstractItemModel * model); + void setModel(QAbstractItemModel * model) override; signals: void currentDataChanged(int value); diff --git a/companion/src/shared/autocombobox.cpp b/companion/src/shared/autocombobox.cpp index d42f01e79fc..5a174a165e4 100644 --- a/companion/src/shared/autocombobox.cpp +++ b/companion/src/shared/autocombobox.cpp @@ -24,12 +24,10 @@ AutoComboBox::AutoComboBox(QWidget * parent): QComboBox(parent), AutoWidget(), - m_field(nullptr), m_next(0), - m_hasModel(false), - m_rawSource(nullptr), - m_rawSwitch(nullptr) + m_hasModel(false) { + initField(); connect(this, QOverload::of(&QComboBox::currentIndexChanged), this, &AutoComboBox::onCurrentIndexChanged); } @@ -37,82 +35,104 @@ AutoComboBox::~AutoComboBox() { } -void AutoComboBox::clear() +void AutoComboBox::initField() { - if (m_hasModel) - return; + m_field = nullptr; + m_rawSource = nullptr; + m_rawSwitch = nullptr; + m_curveType = nullptr; + m_flexType = nullptr; + m_switchType = nullptr; +} - setLock(true); - QComboBox::clear(); - m_next = 0; - setLock(false); +void AutoComboBox::clear() +{ + if (!m_hasModel) { + setLock(true); + QComboBox::clear(); + m_next = 0; + setLock(false); + } } void AutoComboBox::insertItems(int index, const QStringList & items) { - if (m_hasModel) - return; + if (!m_hasModel) { + foreach(QString item, items) + addItem(item); - foreach(QString item, items) { - addItem(item); } } void AutoComboBox::addItem(const QString & item) { - if (m_hasModel) - return; - - addItem(item, m_next++); + if (!m_hasModel) + addItem(item, m_next++); } void AutoComboBox::addItem(const QString & item, int value) { - if (m_hasModel) - return; - - setLock(true); - QComboBox::addItem(item, value); - setLock(false); - updateValue(); + if (!m_hasModel) { + setLock(true); + QComboBox::addItem(item, value); + setLock(false); + updateValue(); + } } void AutoComboBox::setField(unsigned int & field, GenericPanel * panel) { - m_field = (int *)&field; - m_rawSource = nullptr; - m_rawSwitch = nullptr; setFieldInit(panel); + m_field = (int *)&field; + updateValue(); } void AutoComboBox::setField(int & field, GenericPanel * panel) { - m_field = &field; - m_rawSource = nullptr; - m_rawSwitch = nullptr; setFieldInit(panel); + m_field = &field; + updateValue(); } void AutoComboBox::setField(RawSource & field, GenericPanel * panel) { - m_rawSource = &field; - m_rawSwitch = nullptr; - m_field = nullptr; setFieldInit(panel); + m_rawSource = &field; + updateValue(); } void AutoComboBox::setField(RawSwitch & field, GenericPanel * panel) { + setFieldInit(panel); m_rawSwitch = &field; - m_rawSource = nullptr; - m_field = nullptr; + updateValue(); +} + +void AutoComboBox::setField(CurveData::CurveType & field, GenericPanel * panel) +{ + setFieldInit(panel); + m_curveType = &field; + updateValue(); +} + +void AutoComboBox::setField(Board::FlexType & field, GenericPanel * panel) +{ + setFieldInit(panel); + m_flexType = &field; + updateValue(); +} + +void AutoComboBox::setField(Board::SwitchType & field, GenericPanel * panel) +{ setFieldInit(panel); + m_switchType = &field; + updateValue(); } void AutoComboBox::setFieldInit(GenericPanel * panel) { + initField(); setPanel(panel); - updateValue(); } void AutoComboBox::setModel(QAbstractItemModel * model) @@ -126,19 +146,16 @@ void AutoComboBox::setModel(QAbstractItemModel * model) void AutoComboBox::setAutoIndexes() { - if (m_hasModel) - return; + if (!m_hasModel) { + for (int i = 0; i < count(); ++i) + setItemData(i, i); - for (int i = 0; i < count(); ++i) - setItemData(i, i); - updateValue(); + updateValue(); + } } void AutoComboBox::updateValue() { - if (!m_field && !m_rawSource && !m_rawSwitch) - return; - setLock(true); if (m_field) @@ -147,6 +164,12 @@ void AutoComboBox::updateValue() setCurrentIndex(findData(m_rawSource->toValue())); else if (m_rawSwitch) setCurrentIndex(findData(m_rawSwitch->toValue())); + else if (m_curveType) + setCurrentIndex(findData(*m_curveType)); + else if (m_flexType) + setCurrentIndex(findData(*m_flexType)); + else if (m_switchType) + setCurrentIndex(findData(*m_switchType)); setLock(false); } @@ -158,21 +181,24 @@ void AutoComboBox::onCurrentIndexChanged(int index) bool ok; const int val = itemData(index).toInt(&ok); - if (!ok) - return; - if (m_field && *m_field != val) { - *m_field = val; + if (ok) { + if (m_field && *m_field != val) + *m_field = val; + else if (m_rawSource && m_rawSource->toValue() != val) + *m_rawSource = RawSource(val); + else if (m_rawSwitch && m_rawSwitch->toValue() != val) + *m_rawSwitch = RawSwitch(val); + else if (m_curveType && *m_curveType != val) + *m_curveType = (CurveData::CurveType)val; + else if (m_flexType && *m_flexType != val) + *m_flexType = (Board::FlexType)val; + else if (m_switchType && *m_switchType != val) + *m_switchType = (Board::SwitchType)val; + else + return; + + emit currentDataChanged(val); + dataChanged(); } - else if (m_rawSource && m_rawSource->toValue() != val) { - *m_rawSource = RawSource(val); - } - else if (m_rawSwitch && m_rawSwitch->toValue() != val) { - *m_rawSwitch = RawSwitch(val); - } - else - return; - - emit currentDataChanged(val); - dataChanged(); } diff --git a/companion/src/shared/autocombobox.h b/companion/src/shared/autocombobox.h index 30df00ed243..2939f4d280e 100644 --- a/companion/src/shared/autocombobox.h +++ b/companion/src/shared/autocombobox.h @@ -24,9 +24,15 @@ #include "autowidget.h" #include "rawsource.h" #include "rawswitch.h" +#include "curvedata.h" +#include "boards.h" #include +/* + NOTE: Q_OBJECT classes cannot be templated and since we use signals we have no choice but to + take this approach or create a class per data type +*/ class AutoComboBox : public QComboBox, public AutoWidget { Q_OBJECT @@ -48,9 +54,12 @@ class AutoComboBox : public QComboBox, public AutoWidget void setField(int & field, GenericPanel * panel = nullptr); void setField(RawSource & field, GenericPanel * panel = nullptr); void setField(RawSwitch & field, GenericPanel * panel = nullptr); + void setField(CurveData::CurveType & field, GenericPanel * panel = nullptr); + void setField(Board::FlexType & field, GenericPanel * panel = nullptr); + void setField(Board::SwitchType & field, GenericPanel * panel = nullptr); void setAutoIndexes(); - void setModel(QAbstractItemModel * model); + void setModel(QAbstractItemModel * model) override; signals: void currentDataChanged(int value); @@ -59,11 +68,15 @@ class AutoComboBox : public QComboBox, public AutoWidget void onCurrentIndexChanged(int index); private: - int *m_field; int m_next; bool m_hasModel; + int *m_field; RawSource *m_rawSource; RawSwitch *m_rawSwitch; + CurveData::CurveType *m_curveType; + Board::FlexType *m_flexType; + Board::SwitchType *m_switchType; + void initField(); void setFieldInit(GenericPanel * panel); }; diff --git a/companion/src/shared/autohexspinbox.cpp b/companion/src/shared/autohexspinbox.cpp index 7a1089a98fa..997f0d49f3d 100644 --- a/companion/src/shared/autohexspinbox.cpp +++ b/companion/src/shared/autohexspinbox.cpp @@ -20,6 +20,7 @@ */ #include "autohexspinbox.h" +#include AutoHexSpinBox::AutoHexSpinBox(QWidget * parent): QSpinBox(parent), @@ -56,7 +57,7 @@ void AutoHexSpinBox::setRange(const unsigned int min, const unsigned int max) m_length = QString("%1").arg(max, 0, 16).size(); - m_validator = new QRegExpValidator(QRegExp(QString("[0-9A-Fa-f]{1,%1}").arg(m_length)), this); + m_validator = new QRegularExpressionValidator(QRegularExpression(QString("[0-9A-Fa-f]{1,%1}").arg(m_length)), this); } void AutoHexSpinBox::updateValue() diff --git a/companion/src/shared/autohexspinbox.h b/companion/src/shared/autohexspinbox.h index 4f5b9e99887..a59c071c74e 100644 --- a/companion/src/shared/autohexspinbox.h +++ b/companion/src/shared/autohexspinbox.h @@ -26,7 +26,7 @@ #include #include -class QRegExpValidator; +class QRegularExpressionValidator; class AutoHexSpinBox : public QSpinBox, public AutoWidget { @@ -57,6 +57,6 @@ class AutoHexSpinBox : public QSpinBox, public AutoWidget private: unsigned int *m_field; - QRegExpValidator *m_validator; + QRegularExpressionValidator *m_validator; unsigned int m_length; }; diff --git a/companion/src/shared/autolineedit.h b/companion/src/shared/autolineedit.h index 14a8e526ce0..ccaaa2e22ea 100644 --- a/companion/src/shared/autolineedit.h +++ b/companion/src/shared/autolineedit.h @@ -24,7 +24,6 @@ #include "autowidget.h" #include -#include class AutoLineEdit: public QLineEdit, public AutoWidget { diff --git a/companion/src/shared/curvedialog.cpp b/companion/src/shared/curvedialog.cpp index eed3a951da1..734936f53ba 100644 --- a/companion/src/shared/curvedialog.cpp +++ b/companion/src/shared/curvedialog.cpp @@ -144,7 +144,7 @@ CurveDialog::CurveDialog(QWidget * parent, ModelData & model, const int curveIdx int id = dialogFilterFactory->registerItemModel(new FilteredItemModel(CurveData::typeItemModel()), "Curve Type"); ui->curveType->setModel(dialogFilterFactory->getItemModel(id)); - ui->curveType->setField((int &)curve.type); + ui->curveType->setField(curve.type); connect(ui->curveType, &AutoComboBox::currentDataChanged, this, [&] () { on_curveTypeChanged(ui->curveType->currentIndex()) ;}); id = dialogFilterFactory->registerItemModel(new FilteredItemModel(CurveData::pointsItemModel()), diff --git a/companion/src/shared/curveimagewidget.cpp b/companion/src/shared/curveimagewidget.cpp index dfc14e12bd6..7d27ab1ca86 100644 --- a/companion/src/shared/curveimagewidget.cpp +++ b/companion/src/shared/curveimagewidget.cpp @@ -81,7 +81,7 @@ void CurveImageWidget::draw() QImage image = curveImage->get(); if (index < 0) - image = image.mirrored(true, false); + image = image.flipped(Qt::Horizontal); setPixmap(QPixmap::fromImage(image.scaled(height(), width()))); delete curveImage; diff --git a/companion/src/simulation/CMakeLists.txt b/companion/src/simulation/CMakeLists.txt index a3728eda19e..d09d631ceba 100644 --- a/companion/src/simulation/CMakeLists.txt +++ b/companion/src/simulation/CMakeLists.txt @@ -47,7 +47,7 @@ set(${PROJECT_NAME}_HDRS ) # AUTOMOC does not detect so manually process -qt5_wrap_cpp(${PROJECT_NAME}_SRCS +qt_wrap_cpp(${PROJECT_NAME}_SRCS ${${PROJECT_NAME}_HDRS} ) @@ -58,7 +58,7 @@ add_library(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME} PRIVATE ${CPN_COMMON_LIB} - Qt5::Svg + Qt::Svg ) target_include_directories(${PROJECT_NAME} diff --git a/companion/src/simulation/debugoutput.cpp b/companion/src/simulation/debugoutput.cpp index 8319c29471e..d45341477b5 100644 --- a/companion/src/simulation/debugoutput.cpp +++ b/companion/src/simulation/debugoutput.cpp @@ -172,8 +172,8 @@ void DebugOutput::processBytesReceived() const int sbValue = ui->console->verticalScrollBar()->value(); const bool sbAtBottom = (sbValue == ui->console->verticalScrollBar()->maximum()); - while (m_dataBufferDevice && m_dataBufferDevice->bytesAvailable() > 0) { - text = m_dataBufferDevice->read(qint64(text.capacity())); + while (m_dataBufferDevice && m_dataBufferDevice->bytesAvailable() > 0) { // Note: bytesAvailable() returns a boolean - TODO why? + text = m_dataBufferDevice->read(DEBUG_OUTPUT_WIDGET_OUT_BUFF_SIZE); if (text.isEmpty()) break; ui->console->moveCursor(QTextCursor::End); @@ -326,9 +326,9 @@ QRegularExpression DebugOutput::makeRegEx(const QString & input, bool * isExlusi } // no, convert arbitrary string to regex else { - output.replace(QRegExp("^\\\\/"), "/"); // remove escape before fwd-slash ("\/...") + output.replace(QRegularExpression("^\\\\/"), "/"); // remove escape before fwd-slash ("\/...") // escape all special chars except * and ? - output.replace(QRegExp("(\\\\|\\.|\\+|\\^|\\$|\\||\\)|\\(|\\]|\\[|\\}|\\{)"), "\\\\1"); + output.replace(QRegularExpression("(\\\\|\\.|\\+|\\^|\\$|\\||\\)|\\(|\\]|\\[|\\}|\\{)"), "\\\\1"); output.replace("\\*", "\x30").replace("\\?", "\x31"); // save escaped wildcard chars output.replace("*", ".*").replace("?", "."); // convert common wildcards output.replace("\x30", "\\\\*").replace("\x31", "\\\\?"); // replace escaped wildcard chars diff --git a/companion/src/simulation/joystickdialog.cpp b/companion/src/simulation/joystickdialog.cpp index e0dad5486e0..ba9f6cb6f54 100644 --- a/companion/src/simulation/joystickdialog.cpp +++ b/companion/src/simulation/joystickdialog.cpp @@ -375,10 +375,10 @@ void joystickDialog::on_okButton_clicked() if (started && step < 4) { int resp = QMessageBox::warning(this, CPN_STR_TTL_WARNING, tr("Calibration not complete, save anyway?"), - QDialogButtonBox::Ok | QMessageBox::Default, QDialogButtonBox::Cancel | QMessageBox::Escape, QMessageBox::NoButton); - if (resp == QDialogButtonBox::Cancel) + QMessageBox::Ok | QMessageBox::Cancel); + if (resp == QMessageBox::Cancel) return; - } + } g.clearJSData(); diff --git a/companion/src/simulation/radiooutputswidget.cpp b/companion/src/simulation/radiooutputswidget.cpp index 1a4b2977168..41d64fd1784 100644 --- a/companion/src/simulation/radiooutputswidget.cpp +++ b/companion/src/simulation/radiooutputswidget.cpp @@ -292,11 +292,7 @@ QWidget * RadioOutputsWidget::createLogicalSwitch(QWidget * parent, int switchNo QFont font = swtch->font(); font.setBold(true); swtch->setFont(font); -#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0) - swtch->setMinimumWidth(swtch->fontMetrics().width("99") + 10); -#else swtch->setMinimumWidth(swtch->fontMetrics().horizontalAdvance("99") + 10); -#endif font.setBold(false); swtch->setFont(font); swtch->setText(QString("%1").arg(switchNo+1, 2, 10, QChar('0'))); diff --git a/companion/src/simulation/simulatedgps.cpp b/companion/src/simulation/simulatedgps.cpp index 60d26fda081..c07c2696223 100644 --- a/companion/src/simulation/simulatedgps.cpp +++ b/companion/src/simulation/simulatedgps.cpp @@ -22,6 +22,7 @@ #include "simulatedgps.h" #include #include +#include SimulatedGPS::SimulatedGPS() { @@ -109,7 +110,7 @@ void SimulatedGPS::update() return; } - dt = QDateTime::currentDateTime().toTimeSpec(Qt::UTC); + dt = QDateTime::currentDateTime().toTimeZone(QTimeZone::utc()); emitDateTimeChange(); double b2 = lat; @@ -140,7 +141,7 @@ void SimulatedGPS::update() lat = b3; lon = c3; - emitPositionChange(); + emitPositionChange(); } void SimulatedGPS::emitPositionChange() diff --git a/companion/src/simulation/simulatorinterface.cpp b/companion/src/simulation/simulatorinterface.cpp index f3489b54099..188ae2bb669 100644 --- a/companion/src/simulation/simulatorinterface.cpp +++ b/companion/src/simulation/simulatorinterface.cpp @@ -73,7 +73,7 @@ void SimulatorLoader::registerSimulators() } #if defined(__APPLE__) - dir = QLibraryInfo::location(QLibraryInfo::PrefixPath) + "/Resources"; + dir.setPath(QLibraryInfo::path(QLibraryInfo::PrefixPath) + "/Resources"); #else if (QDir::isAbsolutePath(SIMULATOR_LIB_SEARCH_PATH)) { dir.setPath(SIMULATOR_LIB_SEARCH_PATH); diff --git a/companion/src/simulation/telemetryproviderfrsky.cpp b/companion/src/simulation/telemetryproviderfrsky.cpp index 13303449211..a92e00dbb4d 100644 --- a/companion/src/simulation/telemetryproviderfrsky.cpp +++ b/companion/src/simulation/telemetryproviderfrsky.cpp @@ -397,7 +397,7 @@ QString convertGPSDate(QString input) // output is dd-MM-yyyy hh:mm:ss QString localDateString = dateParts[2] + "-" + dateParts[1] + "-20" + dateParts[0] + " " + dateTime[1]; QString format("dd-MM-yyyy hh:mm:ss"); - QDateTime utcDate = QDateTime::fromString(localDateString, format).toTimeSpec(Qt::UTC); + QDateTime utcDate = QDateTime::fromString(localDateString, format).toTimeZone(QTimeZone::UTC); return utcDate.toString(format); } @@ -601,7 +601,7 @@ uint32_t TelemetryProviderFrSky::getNextGPSPacketData(uint32_t packetType) void TelemetryProviderFrSky::setGPSDateTime(QString dateTime) { - QDateTime dt = QDateTime::currentDateTime().toTimeSpec(Qt::UTC); // default to current systemtime + QDateTime dt = QDateTime::currentDateTime().toTimeZone(QTimeZone::UTC); // default to current systemtime if (!dateTime.startsWith('*')) { QString format("dd-MM-yyyy hh:mm:ss"); dt = QDateTime::fromString(dateTime, format); @@ -679,9 +679,9 @@ void TelemetryProviderFrSky::on_saveTelemetryvalues_clicked() out << ui -> cell6 -> text(); out<<"\r\n"; out << ui -> cell7 -> text(); - out<<"\r\n"; + out<<"\r\n"; out << ui -> cell8 -> text(); - out<<"\r\n"; + out<<"\r\n"; out << ui -> aspeed -> text(); out<<"\r\n"; out << ui -> gps_alt -> text(); @@ -830,7 +830,7 @@ void TelemetryProviderFrSky::on_loadTelemetryvalues_clicked() n = in.readLine(); ns = n.toDouble(); ui -> cell7 -> setValue(ns); - + n = in.readLine(); ns = n.toDouble(); ui -> cell8 -> setValue(ns); diff --git a/companion/src/simulation/telemetrysimu.cpp b/companion/src/simulation/telemetrysimu.cpp index 960dbe510eb..3508ed0d595 100644 --- a/companion/src/simulation/telemetrysimu.cpp +++ b/companion/src/simulation/telemetrysimu.cpp @@ -401,7 +401,7 @@ QString convertItemValue(QString sourceUnit, QString destUnit, QString value) return value; int i = 0; - while (conversions[i].source != NULL) { + while (!conversions[i].source.isNull()) { if (conversions[i].source == sourceUnit && conversions[i].destination == destUnit) { return ((conversions[i].converter)(value)); } diff --git a/companion/src/simulation/widgets/buttonswidget.h b/companion/src/simulation/widgets/buttonswidget.h index 7dd086522e5..c4c070d6db3 100644 --- a/companion/src/simulation/widgets/buttonswidget.h +++ b/companion/src/simulation/widgets/buttonswidget.h @@ -134,7 +134,7 @@ class ButtonsWidget : public QWidget void paintEvent(QPaintEvent *) { QStyleOption opt; - opt.init(this); + opt.initFrom(this); QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } diff --git a/companion/src/simulator.cpp b/companion/src/simulator.cpp index c25eb9fb6f5..ef2297e028f 100644 --- a/companion/src/simulator.cpp +++ b/companion/src/simulator.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #if defined(JOYSTICKS) || defined(SIMU_AUDIO) #include #undef main @@ -148,8 +149,8 @@ CommandLineParseResult cliOptions(SimulatorOptions * simOptions, int * profileId #ifdef Q_OS_WIN // For backwards compat. with QxtCommandOptions, convert Windows-style CLI switches (/opt) since QCommandLineParser doesn't support them for (int i=0; i < args.size(); ++i) { - args[i].replace(QRegExp("^/([^\\s]{2,10})$"), "--\\1"); // long opts - args[i].replace(QRegExp("^/([^\\s]){1}$"), "-\\1"); // short opts + args[i].replace(QRegularExpression("^/([^\\s]{2,10})$"), "--\\1"); // long opts + args[i].replace(QRegularExpression("^/([^\\s]){1}$"), "-\\1"); // short opts } #endif @@ -202,7 +203,7 @@ CommandLineParseResult cliOptions(SimulatorOptions * simOptions, int * profileId if (cliOptions.positionalArguments().size()) { QString datasrc = cliOptions.positionalArguments().at(0); - if (datasrc.contains(QRegExp(".*\\.[\\w]{2,6}$"))) { + if (datasrc.contains(QRegularExpression(".*\\.[\\w]{2,6}$"))) { simOptions->dataFile = datasrc; simOptions->startupDataType = SimulatorOptions::START_WITH_FILE; } @@ -252,9 +253,6 @@ CommandLineParseResult cliOptions(SimulatorOptions * simOptions, int * profileId int main(int argc, char *argv[]) { - /* From doc: This attribute must be set before Q(Gui)Application is constructed. */ - QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - QApplication app(argc, argv); app.setApplicationName(APP_SIMULATOR); app.setApplicationVersion(VERSION); diff --git a/companion/src/splashlibrarydialog.cpp b/companion/src/splashlibrarydialog.cpp index 6bd41bfd8dd..0b843e31a51 100644 --- a/companion/src/splashlibrarydialog.cpp +++ b/companion/src/splashlibrarydialog.cpp @@ -92,7 +92,7 @@ void SplashLibraryDialog::getFileList() QDir myRes(":/images/library"); QStringList tmp = myRes.entryList(); for (int i = 0; i < tmp.size(); i++) { - QFileInfo fileInfo = tmp.at(i); + QFileInfo fileInfo(tmp.at(i)); imageList.append(":/images/library/" + fileInfo.fileName()); } } @@ -107,7 +107,7 @@ void SplashLibraryDialog::getFileList() myDir.setNameFilters(supportedImageFormats); QStringList tmp = myDir.entryList(); for (int i = 0; i < tmp.size(); i++) { - QFileInfo fileInfo = tmp.at(i); + QFileInfo fileInfo(tmp.at(i)); QString filename = libraryPath + "/" + fileInfo.fileName(); QImage image(filename); if (!image.isNull()) { diff --git a/companion/src/storage/CMakeLists.txt b/companion/src/storage/CMakeLists.txt index d5984f56306..28d9466abc2 100644 --- a/companion/src/storage/CMakeLists.txt +++ b/companion/src/storage/CMakeLists.txt @@ -24,7 +24,7 @@ set(${PROJECT_NAME}_MOC appdata.h ) -qt5_wrap_cpp(${PROJECT_NAME}_SRCS +qt_wrap_cpp(${PROJECT_NAME}_SRCS ${${PROJECT_NAME}_MOC} ) diff --git a/companion/src/storage/appdata.cpp b/companion/src/storage/appdata.cpp index 64887b870cb..931381b5b83 100644 --- a/companion/src/storage/appdata.cpp +++ b/companion/src/storage/appdata.cpp @@ -56,7 +56,7 @@ void CompStoreObj::load(CompStoreObj * obj, const QString & name, const QString const QMetaProperty & prop = obj->metaObject()->property(idx); const QVariant currValue = prop.read(obj); QVariant savedValue = m_settings.value(pathForKey(key, group), def); - if (savedValue.isValid() && savedValue.convert(currValue.userType()) && savedValue != currValue) + if (savedValue.isValid() && savedValue.convert(currValue.metaType()) && savedValue != currValue) prop.write(obj, savedValue); } @@ -366,7 +366,6 @@ bool ComponentAssetData::existsOnDisk() ComponentData::ComponentData() : CompStoreObj(), index(-1) { - qRegisterMetaTypeStreamOperators("ComponentData::ReleaseChannel"); CompStoreObj::addObjectMapping(propertyGroup(), this); } @@ -425,12 +424,6 @@ AppData::AppData() : CompStoreObj(), m_sessionId(0) { - QMetaType::registerComparators(); - qRegisterMetaTypeStreamOperators("SimulatorOptions"); - qRegisterMetaTypeStreamOperators("AppData::NewModelAction"); - qRegisterMetaTypeStreamOperators("AppData::UpdateCheckFreq"); - qRegisterMetaTypeStreamOperators("AppData::SimuGenericKeysPos"); - CompStoreObj::addObjectMapping(propertyGroup(), this); firstUse = !hasCurrentSettings(); diff --git a/companion/src/storage/hexinterface.cpp b/companion/src/storage/hexinterface.cpp index 0d67502bbcd..ce0c11edad5 100644 --- a/companion/src/storage/hexinterface.cpp +++ b/companion/src/storage/hexinterface.cpp @@ -41,13 +41,14 @@ int HexInterface::load(uint8_t *data, int maxsize) QString line = stream.readLine(); if(line.left(1)!=":") continue; - + int byteCount = getValueFromLine(line,1); int address = getValueFromLine(line,3,4); int recType = getValueFromLine(line,7); - if (recType==0x02) { - offset+=0x010000; - } + + if (recType==0x02) + offset+=0x010000; + if(byteCount<0 || address<0 || recType<0) return 0; @@ -59,11 +60,10 @@ int HexInterface::load(uint8_t *data, int maxsize) chkSum -= recType; chkSum -= address & 0xFF; chkSum -= address >> 8; - for(int i=0; i #include +#include class HexInterface { public: @@ -40,5 +39,3 @@ class HexInterface { QTextStream & stream; }; - -#endif // _HEXINTERFACE_H_ diff --git a/companion/src/tests/CMakeLists.txt b/companion/src/tests/CMakeLists.txt index 6cc6fdc7d52..6b8c8163fa7 100644 --- a/companion/src/tests/CMakeLists.txt +++ b/companion/src/tests/CMakeLists.txt @@ -1,6 +1,5 @@ - -if(Qt5Widgets_FOUND) +if(Qt6Widgets_FOUND) add_library(gtests-companion-lib STATIC EXCLUDE_FROM_ALL ${googletest_SOURCE_DIR}/googletest/src/gtest-all.cc ) @@ -30,5 +29,5 @@ if(Qt5Widgets_FOUND) target_link_libraries(gtests-companion gtests-companion-lib simulation firmwares storage common) message(STATUS "Added optional gtests-companion target") else() - message(WARNING "WARNING: gtests target will not be available (check that Qt5Widgets are configured).") + message(WARNING "WARNING: gtests target will not be available (check that QtWidgets are configured).") endif() diff --git a/companion/src/thirdparty/qcustomplot/CMakeLists.txt b/companion/src/thirdparty/qcustomplot/CMakeLists.txt index 9bccbd622f3..7b01e648410 100644 --- a/companion/src/thirdparty/qcustomplot/CMakeLists.txt +++ b/companion/src/thirdparty/qcustomplot/CMakeLists.txt @@ -6,7 +6,7 @@ set(qcustomplot_HDRS qcustomplot.h ) -qt5_wrap_cpp(qcustomplot_SRCS ${qcustomplot_HDRS}) +qt_wrap_cpp(qcustomplot_SRCS ${qcustomplot_HDRS}) add_library(qcustomplot ${qcustomplot_SRCS}) -target_link_libraries(qcustomplot PRIVATE ${CPN_COMMON_LIB} Qt5::Widgets Qt5::PrintSupport) +target_link_libraries(qcustomplot PRIVATE ${CPN_COMMON_LIB} Qt::Widgets Qt::PrintSupport) diff --git a/companion/src/thirdparty/qcustomplot/qcustomplot.cpp b/companion/src/thirdparty/qcustomplot/qcustomplot.cpp index 72b5bfb8bb3..67d74c95c6e 100644 --- a/companion/src/thirdparty/qcustomplot/qcustomplot.cpp +++ b/companion/src/thirdparty/qcustomplot/qcustomplot.cpp @@ -35,7 +35,7 @@ /*! \class QCPVector2D \brief Represents two doubles as a mathematical 2D vector - + This class acts as a replacement for QVector2D with the advantage of double precision instead of single, and some convenience methods tailored for the QCustomPlot library. */ @@ -43,70 +43,70 @@ /* start documentation of inline functions */ /*! \fn void QCPVector2D::setX(double x) - + Sets the x coordinate of this vector to \a x. - + \see setY */ /*! \fn void QCPVector2D::setY(double y) - + Sets the y coordinate of this vector to \a y. - + \see setX */ /*! \fn double QCPVector2D::length() const - + Returns the length of this vector. - + \see lengthSquared */ /*! \fn double QCPVector2D::lengthSquared() const - + Returns the squared length of this vector. In some situations, e.g. when just trying to find the shortest vector of a group, this is faster than calculating \ref length, because it avoids calculation of a square root. - + \see length */ /*! \fn double QCPVector2D::angle() const - + Returns the angle of the vector in radians. The angle is measured between the positive x line and the vector, counter-clockwise in a mathematical coordinate system (y axis upwards positive). In screen/widget coordinates where the y axis is inverted, the angle appears clockwise. */ /*! \fn QPoint QCPVector2D::toPoint() const - + Returns a QPoint which has the x and y coordinates of this vector, truncating any floating point information. - + \see toPointF */ /*! \fn QPointF QCPVector2D::toPointF() const - + Returns a QPointF which has the x and y coordinates of this vector. - + \see toPoint */ /*! \fn bool QCPVector2D::isNull() const - + Returns whether this vector is null. A vector is null if \c qIsNull returns true for both x and y coordinates, i.e. if both are binary equal to 0. */ /*! \fn QCPVector2D QCPVector2D::perpendicular() const - + Returns a vector perpendicular to this vector, with the same length. */ /*! \fn double QCPVector2D::dot() const - + Returns the dot/scalar product of this vector with the specified vector \a vec. */ @@ -153,9 +153,9 @@ QCPVector2D::QCPVector2D(const QPointF &point) : /*! Normalizes this vector. After this operation, the length of the vector is equal to 1. - + If the vector has both entries set to zero, this method does nothing. - + \see normalized, length, lengthSquared */ void QCPVector2D::normalize() @@ -168,9 +168,9 @@ void QCPVector2D::normalize() /*! Returns a normalized version of this vector. The length of the returned vector is equal to 1. - + If the vector has both entries set to zero, this method returns the vector unmodified. - + \see normalize, length, lengthSquared */ QCPVector2D QCPVector2D::normalized() const @@ -181,10 +181,10 @@ QCPVector2D QCPVector2D::normalized() const } /*! \overload - + Returns the squared shortest distance of this vector (interpreted as a point) to the finite line segment given by \a start and \a end. - + \see distanceToStraightLine */ double QCPVector2D::distanceSquaredToLine(const QCPVector2D &start, const QCPVector2D &end) const @@ -205,10 +205,10 @@ double QCPVector2D::distanceSquaredToLine(const QCPVector2D &start, const QCPVec } /*! \overload - + Returns the squared shortest distance of this vector (interpreted as a point) to the finite line segment given by \a line. - + \see distanceToStraightLine */ double QCPVector2D::distanceSquaredToLine(const QLineF &line) const @@ -219,7 +219,7 @@ double QCPVector2D::distanceSquaredToLine(const QLineF &line) const /*! Returns the shortest distance of this vector (interpreted as a point) to the infinite straight line given by a \a base point and a \a direction vector. - + \see distanceSquaredToLine */ double QCPVector2D::distanceToStraightLine(const QCPVector2D &base, const QCPVector2D &direction) const @@ -280,11 +280,11 @@ QCPVector2D &QCPVector2D::operator-=(const QCPVector2D &vector) /*! \class QCPPainter \brief QPainter subclass used internally - + This QPainter subclass is used to provide some extended functionality e.g. for tweaking position consistency between antialiased and non-antialiased painting. Further it provides workarounds for QPainter quirks. - + \warning This class intentionally hides non-virtual functions of QPainter, e.g. setPen, save and restore. So while it is possible to pass a QCPPainter instance to a function that expects a QPainter pointer, some of the workarounds and tweaks will be unavailable to the function (because @@ -305,7 +305,7 @@ QCPPainter::QCPPainter() : /*! Creates a new QCPPainter instance on the specified paint \a device and sets default values. Just like the analogous QPainter constructor, begins painting on \a device immediately. - + Like \ref begin, this method sets QPainter::NonCosmeticDefaultPen in Qt versions before Qt5. */ QCPPainter::QCPPainter(QPaintDevice *device) : @@ -322,7 +322,7 @@ QCPPainter::QCPPainter(QPaintDevice *device) : /*! Sets the pen of the painter and applies certain fixes to it, depending on the mode of this QCPPainter. - + \note this function hides the non-virtual base class implementation. */ void QCPPainter::setPen(const QPen &pen) @@ -333,10 +333,10 @@ void QCPPainter::setPen(const QPen &pen) } /*! \overload - + Sets the pen (by color) of the painter and applies certain fixes to it, depending on the mode of this QCPPainter. - + \note this function hides the non-virtual base class implementation. */ void QCPPainter::setPen(const QColor &color) @@ -347,10 +347,10 @@ void QCPPainter::setPen(const QColor &color) } /*! \overload - + Sets the pen (by style) of the painter and applies certain fixes to it, depending on the mode of this QCPPainter. - + \note this function hides the non-virtual base class implementation. */ void QCPPainter::setPen(Qt::PenStyle penStyle) @@ -361,11 +361,11 @@ void QCPPainter::setPen(Qt::PenStyle penStyle) } /*! \overload - + Works around a Qt bug introduced with Qt 4.8 which makes drawing QLineF unpredictable when antialiasing is disabled. Thus when antialiasing is disabled, it rounds the \a line to integer coordinates and then passes it to the original drawLine. - + \note this function hides the non-virtual base class implementation. */ void QCPPainter::drawLine(const QLineF &line) @@ -412,10 +412,10 @@ void QCPPainter::setModes(QCPPainter::PainterModes modes) device. This is necessary to get cosmetic pen consistency across Qt versions, because since Qt5, all pens are non-cosmetic by default, and in Qt4 this render hint must be set to get that behaviour. - + The Constructor \ref QCPPainter(QPaintDevice *device) which directly starts painting also sets the render hint as appropriate. - + \note this function hides the non-virtual base class implementation. */ bool QCPPainter::begin(QPaintDevice *device) @@ -429,7 +429,7 @@ bool QCPPainter::begin(QPaintDevice *device) } /*! \overload - + Sets the mode of the painter. This controls whether the painter shall adjust its fixes/workarounds optimized for certain output devices. */ @@ -444,9 +444,9 @@ void QCPPainter::setMode(QCPPainter::PainterMode mode, bool enabled) /*! Saves the painter (see QPainter::save). Since QCPPainter adds some new internal state to QPainter, the save/restore functions are reimplemented to also save/restore those members. - + \note this function hides the non-virtual base class implementation. - + \see restore */ void QCPPainter::save() @@ -458,9 +458,9 @@ void QCPPainter::save() /*! Restores the painter (see QPainter::restore). Since QCPPainter adds some new internal state to QPainter, the save/restore functions are reimplemented to also save/restore those members. - + \note this function hides the non-virtual base class implementation. - + \see save */ void QCPPainter::restore() @@ -766,7 +766,7 @@ QCPPainter *QCPPaintBufferGlPbuffer::startPainting() qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; return 0; } - + QCPPainter *result = new QCPPainter(mGlPBuffer); result->setRenderHint(QPainter::HighQualityAntialiasing); return result; @@ -806,7 +806,7 @@ void QCPPaintBufferGlPbuffer::reallocateBuffer() { if (mGlPBuffer) delete mGlPBuffer; - + QGLFormat format; format.setAlpha(true); format.setSamples(mMultisamples); @@ -875,7 +875,7 @@ QCPPainter *QCPPaintBufferGlFbo::startPainting() qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; return 0; } - + if (QOpenGLContext::currentContext() != context.data()) context->makeCurrent(context->surface()); mGlFrameBuffer->bind(); @@ -925,7 +925,7 @@ void QCPPaintBufferGlFbo::clear(const QColor &color) qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; return; } - + if (QOpenGLContext::currentContext() != context.data()) context->makeCurrent(context->surface()); mGlFrameBuffer->bind(); @@ -945,7 +945,7 @@ void QCPPaintBufferGlFbo::reallocateBuffer() delete mGlFrameBuffer; mGlFrameBuffer = 0; } - + QSharedPointer paintDevice = mGlPaintDevice.toStrongRef(); QSharedPointer context = mGlContext.toStrongRef(); if (!paintDevice) @@ -958,7 +958,7 @@ void QCPPaintBufferGlFbo::reallocateBuffer() qDebug() << Q_FUNC_INFO << "OpenGL context doesn't exist"; return; } - + // create new fbo with appropriate size: context->makeCurrent(context->surface()); QOpenGLFramebufferObjectFormat frameBufferFormat; @@ -1041,16 +1041,16 @@ void QCPPaintBufferGlFbo::reallocateBuffer() /* start documentation of inline functions */ /*! \fn QList QCPLayer::children() const - + Returns a list of all layerables on this layer. The order corresponds to the rendering order: layerables with higher indices are drawn above layerables with lower indices. */ /*! \fn int QCPLayer::index() const - + Returns the index this layer has in the QCustomPlot. The index is the integer number by which this layer can be accessed via \ref QCustomPlot::layer. - + Layers with higher indices will be drawn above layers with lower indices. */ @@ -1058,9 +1058,9 @@ void QCPPaintBufferGlFbo::reallocateBuffer() /*! Creates a new QCPLayer instance. - + Normally you shouldn't directly instantiate layers, use \ref QCustomPlot::addLayer instead. - + \warning It is not checked that \a layerName is actually a unique layer name in \a parentPlot. This check is only performed by \ref QCustomPlot::addLayer. */ @@ -1082,10 +1082,10 @@ QCPLayer::~QCPLayer() // then invalid layer once they get deleted/moved themselves. This only happens when layers are deleted // directly, like in the QCustomPlot destructor. (The regular layer removal procedure for the user is to // call QCustomPlot::removeLayer, which moves all layerables off this layer before deleting it.) - + while (!mChildren.isEmpty()) mChildren.last()->setLayer(nullptr); // removes itself from mChildren via removeChild() - + if (mParentPlot->currentLayer() == this) qDebug() << Q_FUNC_INFO << "The parent plot's mCurrentLayer will be a dangling pointer. Should have been set to a valid layer or nullptr beforehand."; } @@ -1212,13 +1212,13 @@ void QCPLayer::replot() } /*! \internal - + Adds the \a layerable to the list of this layer. If \a prepend is set to true, the layerable will be prepended to the list, i.e. be drawn beneath the other layerables already in the list. - + This function does not change the \a mLayer member of \a layerable to this layer. (Use QCPLayerable::setLayer to change the layer of an object, not this function.) - + \see removeChild */ void QCPLayer::addChild(QCPLayerable *layerable, bool prepend) @@ -1236,12 +1236,12 @@ void QCPLayer::addChild(QCPLayerable *layerable, bool prepend) } /*! \internal - + Removes the \a layerable from the list of this layer. - + This function does not change the \a mLayer member of \a layerable. (Use QCPLayerable::setLayer to change the layer of an object, not this function.) - + \see addChild */ void QCPLayer::removeChild(QCPLayerable *layerable) @@ -1261,28 +1261,28 @@ void QCPLayer::removeChild(QCPLayerable *layerable) /*! \class QCPLayerable \brief Base class for all drawable objects - + This is the abstract base class most visible objects derive from, e.g. plottables, axes, grid etc. Every layerable is on a layer (QCPLayer) which allows controlling the rendering order by stacking the layers accordingly. - + For details about the layering mechanism, see the QCPLayer documentation. */ /* start documentation of inline functions */ /*! \fn QCPLayerable *QCPLayerable::parentLayerable() const - + Returns the parent layerable of this layerable. The parent layerable is used to provide visibility hierarchies in conjunction with the method \ref realVisibility. This way, layerables only get drawn if their parent layerables are visible, too. - + Note that a parent layerable is not necessarily also the QObject parent for memory management. Further, a layerable doesn't always have a parent layerable, so this function may return \c nullptr. - + A parent layerable is set implicitly when placed inside layout elements and doesn't need to be set manually by the user. */ @@ -1292,7 +1292,7 @@ void QCPLayer::removeChild(QCPLayerable *layerable) /*! \fn virtual void QCPLayerable::applyDefaultAntialiasingHint(QCPPainter *painter) const = 0 \internal - + This function applies the default antialiasing setting to the specified \a painter, using the function \ref applyAntialiasingHint. It is the antialiasing state the painter is put in, when \ref draw is called on the layerable. If the layerable has multiple entities whose antialiasing @@ -1300,7 +1300,7 @@ void QCPLayer::removeChild(QCPLayerable *layerable) most prominent entity. In this case however, the \ref draw function usually calls the specialized versions of this function before drawing each entity, effectively overriding the setting of the default antialiasing hint. - + First example: QCPGraph has multiple entities that have an antialiasing setting: The graph line, fills and scatters. Those can be configured via QCPGraph::setAntialiased, QCPGraph::setAntialiasedFill and QCPGraph::setAntialiasedScatters. Consequently, there isn't only @@ -1308,7 +1308,7 @@ void QCPLayer::removeChild(QCPLayerable *layerable) antialiasing), but specialized ones like QCPGraph::applyFillAntialiasingHint and QCPGraph::applyScattersAntialiasingHint. So before drawing one of those entities, QCPGraph::draw calls the respective specialized applyAntialiasingHint function. - + Second example: QCPItemLine consists only of a line so there is only one antialiasing setting which can be controlled with QCPItemLine::setAntialiased. (This function is inherited by all layerables. The specialized functions, as seen on QCPGraph, must be added explicitly to the @@ -1321,10 +1321,10 @@ void QCPLayer::removeChild(QCPLayerable *layerable) /*! \fn virtual void QCPLayerable::draw(QCPPainter *painter) const = 0 \internal - + This function draws the layerable with the specified \a painter. It is only called by QCustomPlot, if the layerable is visible (\ref setVisible). - + Before this function is called, the painter's antialiasing state is set via \ref applyDefaultAntialiasingHint, see the documentation there. Further, the clipping rectangle was set to \ref clipRect. @@ -1334,10 +1334,10 @@ void QCPLayer::removeChild(QCPLayerable *layerable) /* start documentation of signals */ /*! \fn void QCPLayerable::layerChanged(QCPLayer *newLayer); - + This signal is emitted when the layer of this layerable changes, i.e. this layerable is moved to a different layer. - + \see setLayer */ @@ -1345,17 +1345,17 @@ void QCPLayer::removeChild(QCPLayerable *layerable) /*! Creates a new QCPLayerable instance. - + Since QCPLayerable is an abstract base class, it can't be instantiated directly. Use one of the derived classes. - + If \a plot is provided, it automatically places itself on the layer named \a targetLayer. If \a targetLayer is an empty string, it places itself on the current layer of the plot (see \ref QCustomPlot::setCurrentLayer). - + It is possible to provide \c nullptr as \a plot. In that case, you should assign a parent plot at a later time with \ref initializeParentPlot. - + The layerable's parent layerable is set to \a parentLayerable, if provided. Direct layerable parents are mainly used to control visibility in a hierarchy of layerables. This means a layerable is only drawn, if all its ancestor layerables are also visible. Note that \a @@ -1402,10 +1402,10 @@ void QCPLayerable::setVisible(bool on) /*! Sets the \a layer of this layerable object. The object will be placed on top of the other objects already on \a layer. - + If \a layer is 0, this layerable will not be on any layer and thus not appear in the plot (or interact/receive events). - + Returns true if the layer of this layerable was successfully changed to \a layer. */ bool QCPLayerable::setLayer(QCPLayer *layer) @@ -1415,7 +1415,7 @@ bool QCPLayerable::setLayer(QCPLayer *layer) /*! \overload Sets the layer of this layerable object by name - + Returns true on success, i.e. if \a layerName is a valid layer name. */ bool QCPLayerable::setLayer(const QString &layerName) @@ -1437,7 +1437,7 @@ bool QCPLayerable::setLayer(const QString &layerName) /*! Sets whether this object will be drawn antialiased or not. - + Note that antialiasing settings may be overridden by QCustomPlot::setAntialiasedElements and QCustomPlot::setNotAntialiasedElements. */ @@ -1450,7 +1450,7 @@ void QCPLayerable::setAntialiased(bool enabled) Returns whether this layerable is visible, taking the visibility of the layerable parent and the visibility of this layerable's layer into account. This is the method that is consulted to decide whether a layerable shall be drawn or not. - + If this layerable has a direct layerable parent (usually set via hierarchies implemented in subclasses, like in the case of \ref QCPLayoutElement), this function returns true only if this layerable has its visibility set to true and the parent layerable's \ref realVisibility returns @@ -1473,15 +1473,15 @@ bool QCPLayerable::realVisibility() const bars of a \ref QCPBars plottable, a click inside the area should also be considered a hit. In these cases this function thus returns a constant value greater zero but still below the parent plot's selection tolerance. (typically the selectionTolerance multiplied by 0.99). - + Providing a constant value for area objects allows selecting line objects even when they are obscured by such area objects, by clicking close to the lines (i.e. closer than 0.99*selectionTolerance). - + The actual setting of the selection state is not done by this function. This is handled by the parent QCustomPlot when the mouseReleaseEvent occurs, and the finally selected object is notified via the \ref selectEvent/\ref deselectEvent methods. - + \a details is an optional output parameter. Every layerable subclass may place any information in \a details. This information will be passed to \ref selectEvent when the parent QCustomPlot decides on the basis of this selectTest call, that the object was successfully selected. The @@ -1490,13 +1490,13 @@ bool QCPLayerable::realVisibility() const is only done once in \ref selectTest. The result (i.e. the actually clicked part) can then be placed in \a details. So in the subsequent \ref selectEvent, the decision which part was selected doesn't have to be done a second time for a single selection operation. - + In the case of 1D Plottables (\ref QCPAbstractPlottable1D, like \ref QCPGraph or \ref QCPBars) \a details will be set to a \ref QCPDataSelection, describing the closest data point to \a pos. - + You may pass \c nullptr as \a details to indicate that you are not interested in those selection details. - + \see selectEvent, deselectEvent, mousePressEvent, wheelEvent, QCustomPlot::setInteractions, QCPAbstractPlottable1D::selectTestRect */ @@ -1509,18 +1509,18 @@ double QCPLayerable::selectTest(const QPointF &pos, bool onlySelectable, QVarian } /*! \internal - + Sets the parent plot of this layerable. Use this function once to set the parent plot if you have passed \c nullptr in the constructor. It can not be used to move a layerable from one QCustomPlot to another one. - + Note that, unlike when passing a non \c nullptr parent plot in the constructor, this function does not make \a parentPlot the QObject-parent of this layerable. If you want this, call QObject::setParent(\a parentPlot) in addition to this function. - + Further, you will probably want to set a layer (\ref setLayer) after calling this function, to make the layerable appear on the QCustomPlot. - + The parent plot change will be propagated to subclasses via a call to \ref parentPlotInitialized so they can react accordingly (e.g. also initialize the parent plot of child layerables, like QCPLayout does). @@ -1532,23 +1532,23 @@ void QCPLayerable::initializeParentPlot(QCustomPlot *parentPlot) qDebug() << Q_FUNC_INFO << "called with mParentPlot already initialized"; return; } - + if (!parentPlot) qDebug() << Q_FUNC_INFO << "called with parentPlot zero"; - + mParentPlot = parentPlot; parentPlotInitialized(mParentPlot); } /*! \internal - + Sets the parent layerable of this layerable to \a parentLayerable. Note that \a parentLayerable does not become the QObject-parent (for memory management) of this layerable. - + The parent layerable has influence on the return value of the \ref realVisibility method. Only layerables with a fully visible parent tree will return true for \ref realVisibility, and thus be drawn. - + \see realVisibility */ void QCPLayerable::setParentLayerable(QCPLayerable *parentLayerable) @@ -1557,11 +1557,11 @@ void QCPLayerable::setParentLayerable(QCPLayerable *parentLayerable) } /*! \internal - + Moves this layerable object to \a layer. If \a prepend is true, this object will be prepended to the new layer's list, i.e. it will be drawn below the objects already on the layer. If it is false, the object will be appended. - + Returns true on success, i.e. if \a layer is a valid layer. */ bool QCPLayerable::moveToLayer(QCPLayer *layer, bool prepend) @@ -1576,7 +1576,7 @@ bool QCPLayerable::moveToLayer(QCPLayer *layer, bool prepend) qDebug() << Q_FUNC_INFO << "layer" << layer->name() << "is not in same QCustomPlot as this layerable"; return false; } - + QCPLayer *oldLayer = mLayer; if (mLayer) mLayer->removeChild(this); @@ -1610,15 +1610,15 @@ void QCPLayerable::applyAntialiasingHint(QCPPainter *painter, bool localAntialia This function is called by \ref initializeParentPlot, to allow subclasses to react on the setting of a parent plot. This is the case when \c nullptr was passed as parent plot in the constructor, and the parent plot is set at a later time. - + For example, QCPLayoutElement/QCPLayout hierarchies may be created independently of any QCustomPlot at first. When they are then added to a layout inside the QCustomPlot, the top level element of the hierarchy gets its parent plot initialized with \ref initializeParentPlot. To propagate the parent plot to all the children of the hierarchy, the top level element then uses this function to pass the parent plot on to its child elements. - + The default implementation does nothing. - + \see initializeParentPlot */ void QCPLayerable::parentPlotInitialized(QCustomPlot *parentPlot) @@ -1631,10 +1631,10 @@ void QCPLayerable::parentPlotInitialized(QCustomPlot *parentPlot) Returns the selection category this layerable shall belong to. The selection category is used in conjunction with \ref QCustomPlot::setInteractions to control which objects are selectable and which aren't. - + Subclasses that don't fit any of the normal \ref QCP::Interaction values can use \ref QCP::iSelectOther. This is what the default implementation returns. - + \see QCustomPlot::setInteractions */ QCP::Interaction QCPLayerable::selectionCategory() const @@ -1643,11 +1643,11 @@ QCP::Interaction QCPLayerable::selectionCategory() const } /*! \internal - + Returns the clipping rectangle of this layerable object. By default, this is the viewport of the parent QCustomPlot. Specific subclasses may reimplement this function to provide different clipping rects. - + The returned clipping rect is set on the painter before the draw function of the respective object is called. */ @@ -1660,16 +1660,16 @@ QRect QCPLayerable::clipRect() const } /*! \internal - + This event is called when the layerable shall be selected, as a consequence of a click by the user. Subclasses should react to it by setting their selection state appropriately. The default implementation does nothing. - + \a event is the mouse event that caused the selection. \a additive indicates, whether the user was holding the multi-select-modifier while performing the selection (see \ref QCustomPlot::setMultiSelectModifier). if \a additive is true, the selection state must be toggled (i.e. become selected when unselected and unselected when selected). - + Every selectEvent is preceded by a call to \ref selectTest, which has returned positively (i.e. returned a value greater than 0 and less than the selection tolerance of the parent QCustomPlot). The \a details data you output from \ref selectTest is fed back via \a details here. You may @@ -1677,14 +1677,14 @@ QRect QCPLayerable::clipRect() const selectEvent. Usually \a details is used to transfer which part was clicked, if it is a layerable that has multiple individually selectable parts (like QCPAxis). This way selectEvent doesn't need to do the calculation again to find out which part was actually clicked. - + \a selectionStateChanged is an output parameter. If the pointer is non-null, this function must set the value either to true or false, depending on whether the selection state of this layerable was actually changed. For layerables that only are selectable as a whole and not in parts, this is simple: if \a additive is true, \a selectionStateChanged must also be set to true, because the selection toggles. If \a additive is false, \a selectionStateChanged is only set to true, if the layerable was previously unselected and now is switched to the selected state. - + \see selectTest, deselectEvent */ void QCPLayerable::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) @@ -1696,15 +1696,15 @@ void QCPLayerable::selectEvent(QMouseEvent *event, bool additive, const QVariant } /*! \internal - + This event is called when the layerable shall be deselected, either as consequence of a user interaction or a call to \ref QCustomPlot::deselectAll. Subclasses should react to it by unsetting their selection appropriately. - + just as in \ref selectEvent, the output parameter \a selectionStateChanged (if non-null), must return true or false when the selection state of this layerable has changed or not changed, respectively. - + \see selectTest, selectEvent */ void QCPLayerable::deselectEvent(bool *selectionStateChanged) @@ -1843,10 +1843,10 @@ void QCPLayerable::wheelEvent(QWheelEvent *event) //////////////////////////////////////////////////////////////////////////////////////////////////// /*! \class QCPRange \brief Represents the range an axis is encompassing. - + contains a \a lower and \a upper double value and provides convenience input, output and modification functions. - + \see QCPAxis::setRange */ @@ -2022,7 +2022,7 @@ QCPRange QCPRange::expanded(double includeCoord) const /*! Returns this range, possibly modified to not exceed the bounds provided as \a lowerBound and \a upperBound. If possible, the size of the current range is preserved in the process. - + If the range shall only be bounded at the lower side, you can set \a upperBound to \ref QCPRange::maxRange. If it shall only be bounded at the upper side, set \a lowerBound to -\ref QCPRange::maxRange. @@ -2031,7 +2031,7 @@ QCPRange QCPRange::bounded(double lowerBound, double upperBound) const { if (lowerBound > upperBound) qSwap(lowerBound, upperBound); - + QCPRange result(lower, upper); if (result.lower < lowerBound) { @@ -2046,7 +2046,7 @@ QCPRange QCPRange::bounded(double lowerBound, double upperBound) const if (result.lower < lowerBound || qFuzzyCompare(size(), upperBound-lowerBound)) result.lower = lowerBound; } - + return result; } @@ -2054,7 +2054,7 @@ QCPRange QCPRange::bounded(double lowerBound, double upperBound) const Returns a sanitized version of the range. Sanitized means for logarithmic scales, that the range won't span the positive and negative sign domain, i.e. contain zero. Further \a lower will always be numerically smaller (or equal) to \a upper. - + If the original range does span positive and negative sign domains or contains zero, the returned range will try to approximate the original range as good as possible. If the positive interval of the original range is wider than the negative interval, the @@ -2166,7 +2166,7 @@ bool QCPRange::validRange(const QCPRange &range) /*! \class QCPDataRange \brief Describes a data range given by begin and end index - + QCPDataRange holds two integers describing the begin (\ref setBegin) and end (\ref setEnd) index of a contiguous set of data points. The \a end index corresponds to the data point just after the last data point of the data range, like in standard iterators. @@ -2175,16 +2175,16 @@ bool QCPRange::validRange(const QCPRange &range) modified. If a non-contiguous data set shall be described, the class \ref QCPDataSelection is used, which holds and manages multiple instances of \ref QCPDataRange. In most situations, \ref QCPDataSelection is thus used. - + Both \ref QCPDataRange and \ref QCPDataSelection offer convenience methods to work with them, e.g. \ref bounded, \ref expanded, \ref intersects, \ref intersection, \ref adjusted, \ref contains. Further, addition and subtraction operators (defined in \ref QCPDataSelection) can be used to join/subtract data ranges and data selections (or mixtures), to retrieve a corresponding \ref QCPDataSelection. - + %QCustomPlot's \ref dataselection "data selection mechanism" is based on \ref QCPDataSelection and QCPDataRange. - + \note Do not confuse \ref QCPDataRange with \ref QCPRange. A \ref QCPRange describes an interval in floating point plot coordinates, e.g. the current axis range. */ @@ -2192,43 +2192,43 @@ bool QCPRange::validRange(const QCPRange &range) /* start documentation of inline functions */ /*! \fn int QCPDataRange::size() const - + Returns the number of data points described by this data range. This is equal to the end index minus the begin index. - + \see length */ /*! \fn int QCPDataRange::length() const - + Returns the number of data points described by this data range. Equivalent to \ref size. */ /*! \fn void QCPDataRange::setBegin(int begin) - + Sets the begin of this data range. The \a begin index points to the first data point that is part of the data range. - + No checks or corrections are made to ensure the resulting range is valid (\ref isValid). - + \see setEnd */ /*! \fn void QCPDataRange::setEnd(int end) - + Sets the end of this data range. The \a end index points to the data point just after the last data point that is part of the data range. - + No checks or corrections are made to ensure the resulting range is valid (\ref isValid). - + \see setBegin */ /*! \fn bool QCPDataRange::isValid() const - + Returns whether this range is valid. A valid range has a begin index greater or equal to 0, and an end index greater or equal to the begin index. - + \note Invalid ranges should be avoided and are never the result of any of QCustomPlot's methods (unless they are themselves fed with invalid ranges). Do not pass invalid ranges to QCustomPlot's methods. The invalid range is not inherently prevented in QCPDataRange, to allow temporary @@ -2237,14 +2237,14 @@ bool QCPRange::validRange(const QCPRange &range) */ /*! \fn bool QCPDataRange::isEmpty() const - + Returns whether this range is empty, i.e. whether its begin index equals its end index. - + \see size, length */ /*! \fn QCPDataRange QCPDataRange::adjusted(int changeBegin, int changeEnd) const - + Returns a data range where \a changeBegin and \a changeEnd were added to the begin and end indices, respectively. */ @@ -2262,7 +2262,7 @@ QCPDataRange::QCPDataRange() : /*! Creates a QCPDataRange, initialized with the specified \a begin and \a end. - + No checks or corrections are made to ensure the resulting range is valid (\ref isValid). */ QCPDataRange::QCPDataRange(int begin, int end) : @@ -2274,7 +2274,7 @@ QCPDataRange::QCPDataRange(int begin, int end) : /*! Returns a data range that matches this data range, except that parts exceeding \a other are excluded. - + This method is very similar to \ref intersection, with one distinction: If this range and the \a other range share no intersection, the returned data range will be empty with begin and end set to the respective boundary side of \a other, at which this range is residing. (\ref intersection @@ -2303,12 +2303,12 @@ QCPDataRange QCPDataRange::expanded(const QCPDataRange &other) const /*! Returns the data range which is contained in both this data range and \a other. - + This method is very similar to \ref bounded, with one distinction: If this range and the \a other range share no intersection, the returned data range will be empty with begin and end set to 0. (\ref bounded would return a range with begin and end set to one of the boundaries of \a other, depending on which side this range is on.) - + \see QCPDataSelection::intersection */ QCPDataRange QCPDataRange::intersection(const QCPDataRange &other) const @@ -2322,7 +2322,7 @@ QCPDataRange QCPDataRange::intersection(const QCPDataRange &other) const /*! Returns whether this data range and \a other share common data points. - + \see intersection, contains */ bool QCPDataRange::intersects(const QCPDataRange &other) const @@ -2333,7 +2333,7 @@ bool QCPDataRange::intersects(const QCPDataRange &other) const /*! Returns whether all data points of \a other are also contained inside this data range. - + \see intersects */ bool QCPDataRange::contains(const QCPDataRange &other) const @@ -2349,14 +2349,14 @@ bool QCPDataRange::contains(const QCPDataRange &other) const /*! \class QCPDataSelection \brief Describes a data set by holding multiple QCPDataRange instances - + QCPDataSelection manages multiple instances of QCPDataRange in order to represent any (possibly disjoint) set of data selection. - + The data selection can be modified with addition and subtraction operators which take QCPDataSelection and QCPDataRange instances, as well as methods such as \ref addDataRange and \ref clear. Read access is provided by \ref dataRange, \ref dataRanges, \ref dataRangeCount, etc. - + The method \ref simplify is used to join directly adjacent or even overlapping QCPDataRange instances. QCPDataSelection automatically simplifies when using the addition/subtraction operators. The only case when \ref simplify is left to the user, is when calling \ref @@ -2364,46 +2364,46 @@ bool QCPDataRange::contains(const QCPDataRange &other) const ranges will be added to the selection successively and the overhead for simplifying after each iteration shall be avoided. In this case, you should make sure to call \ref simplify after completing the operation. - + Use \ref enforceType to bring the data selection into a state complying with the constraints for selections defined in \ref QCP::SelectionType. - + %QCustomPlot's \ref dataselection "data selection mechanism" is based on QCPDataSelection and QCPDataRange. - + \section qcpdataselection-iterating Iterating over a data selection - + As an example, the following code snippet calculates the average value of a graph's data \ref QCPAbstractPlottable::selection "selection": - + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpdataselection-iterating-1 - + */ /* start documentation of inline functions */ /*! \fn int QCPDataSelection::dataRangeCount() const - + Returns the number of ranges that make up the data selection. The ranges can be accessed by \ref dataRange via their index. - + \see dataRange, dataPointCount */ /*! \fn QList QCPDataSelection::dataRanges() const - + Returns all data ranges that make up the data selection. If the data selection is simplified (the usual state of the selection, see \ref simplify), the ranges are sorted by ascending data point index. - + \see dataRange */ /*! \fn bool QCPDataSelection::isEmpty() const - + Returns true if there are no data ranges, and thus no data points, in this QCPDataSelection instance. - + \see dataRangeCount */ @@ -2471,7 +2471,7 @@ QCPDataSelection &QCPDataSelection::operator-=(const QCPDataSelection &other) { for (int i=0; i= other.end()) break; // since data ranges are sorted after the simplify() call, no ranges which contain other will come after this - + if (thisEnd > other.begin()) // ranges which don't fulfill this are entirely before other and can be ignored { if (thisBegin >= other.begin()) // range leading segment is encompassed @@ -2517,7 +2517,7 @@ QCPDataSelection &QCPDataSelection::operator-=(const QCPDataRange &other) } ++i; } - + return *this; } @@ -2535,10 +2535,10 @@ int QCPDataSelection::dataPointCount() const /*! Returns the data range with the specified \a index. - + If the data selection is simplified (the usual state of the selection, see \ref simplify), the ranges are sorted by ascending data point index. - + \see dataRangeCount */ QCPDataRange QCPDataSelection::dataRange(int index) const @@ -2580,7 +2580,7 @@ void QCPDataSelection::addDataRange(const QCPDataRange &dataRange, bool simplify /*! Removes all data ranges. The data selection then contains no data points. - + \ref isEmpty */ void QCPDataSelection::clear() @@ -2607,10 +2607,10 @@ void QCPDataSelection::simplify() } if (mDataRanges.isEmpty()) return; - + // sort ranges by starting value, ascending: std::sort(mDataRanges.begin(), mDataRanges.end(), lessThanDataRangeBegin); - + // join overlapping/contiguous ranges: int i = 1; while (i < mDataRanges.size()) @@ -2627,11 +2627,11 @@ void QCPDataSelection::simplify() /*! Makes sure this data selection conforms to the specified \a type selection type. Before the type is enforced, \ref simplify is called. - + Depending on \a type, enforcing means adding new data points that were previously not part of the selection, or removing data points from the selection. If the current selection already conforms to \a type, the data selection is not changed. - + \see QCP::SelectionType */ void QCPDataSelection::enforceType(QCP::SelectionType type) @@ -2678,13 +2678,13 @@ void QCPDataSelection::enforceType(QCP::SelectionType type) /*! Returns true if the data selection \a other is contained entirely in this data selection, i.e. all data point indices that are in \a other are also in this data selection. - + \see QCPDataRange::contains */ bool QCPDataSelection::contains(const QCPDataSelection &other) const { if (other.isEmpty()) return false; - + int otherIndex = 0; int thisIndex = 0; while (thisIndex < mDataRanges.size() && otherIndex < other.mDataRanges.size()) @@ -2741,7 +2741,7 @@ QCPDataSelection QCPDataSelection::inverse(const QCPDataRange &outerRange) const if (isEmpty()) return QCPDataSelection(outerRange); QCPDataRange fullRange = outerRange.expanded(span()); - + QCPDataSelection result; // first unselected segment: if (mDataRanges.first().begin() != fullRange.begin()) @@ -2767,19 +2767,19 @@ QCPDataSelection QCPDataSelection::inverse(const QCPDataRange &outerRange) const /*! \class QCPSelectionRect \brief Provides rect/rubber-band data selection and range zoom interaction - + QCPSelectionRect is used by QCustomPlot when the \ref QCustomPlot::setSelectionRectMode is not \ref QCP::srmNone. When the user drags the mouse across the plot, the current selection rect instance (\ref QCustomPlot::setSelectionRect) is forwarded these events and makes sure an according rect shape is drawn. At the begin, during, and after completion of the interaction, it emits the corresponding signals \ref started, \ref changed, \ref canceled, and \ref accepted. - + The QCustomPlot instance connects own slots to the current selection rect instance, in order to react to an accepted selection rect interaction accordingly. - + \ref isActive can be used to check whether the selection rect is currently active. An ongoing selection interaction can be cancelled programmatically via calling \ref cancel at any time. - + The appearance of the selection rect can be controlled via \ref setPen and \ref setBrush. If you wish to provide custom behaviour, e.g. a different visual representation of the selection @@ -2790,10 +2790,10 @@ QCPDataSelection QCPDataSelection::inverse(const QCPDataRange &outerRange) const /* start of documentation of inline functions */ /*! \fn bool QCPSelectionRect::isActive() const - + Returns true if there is currently a selection going on, i.e. the user has started dragging a selection rect, but hasn't released the mouse button yet. - + \see cancel */ @@ -2801,37 +2801,37 @@ QCPDataSelection QCPDataSelection::inverse(const QCPDataRange &outerRange) const /* start documentation of signals */ /*! \fn void QCPSelectionRect::started(QMouseEvent *event); - + This signal is emitted when a selection rect interaction was initiated, i.e. the user just started dragging the selection rect with the mouse. */ /*! \fn void QCPSelectionRect::changed(const QRect &rect, QMouseEvent *event); - + This signal is emitted while the selection rect interaction is ongoing and the \a rect has changed its size due to the user moving the mouse. - + Note that \a rect may have a negative width or height, if the selection is being dragged to the upper or left side of the selection rect origin. */ /*! \fn void QCPSelectionRect::canceled(const QRect &rect, QInputEvent *event); - + This signal is emitted when the selection interaction was cancelled. Note that \a event is \c nullptr if the selection interaction was cancelled programmatically, by a call to \ref cancel. - + The user may cancel the selection interaction by pressing the escape key. In this case, \a event holds the respective input event. - + Note that \a rect may have a negative width or height, if the selection is being dragged to the upper or left side of the selection rect origin. */ /*! \fn void QCPSelectionRect::accepted(const QRect &rect, QMouseEvent *event); - + This signal is emitted when the selection interaction was completed by the user releasing the mouse button. - + Note that \a rect may have a negative width or height, if the selection is being dragged to the upper or left side of the selection rect origin. */ @@ -2877,7 +2877,7 @@ QCPRange QCPSelectionRect::range(const QCPAxis *axis) const /*! Sets the pen that will be used to draw the selection rect outline. - + \see setBrush */ void QCPSelectionRect::setPen(const QPen &pen) @@ -2888,7 +2888,7 @@ void QCPSelectionRect::setPen(const QPen &pen) /*! Sets the brush that will be used to fill the selection rect. By default the selection rect is not filled, i.e. \a brush is Qt::NoBrush. - + \see setPen */ void QCPSelectionRect::setBrush(const QBrush &brush) @@ -2910,7 +2910,7 @@ void QCPSelectionRect::cancel() } /*! \internal - + This method is called by QCustomPlot to indicate that a selection rect interaction was initiated. The default implementation sets the selection rect to active, initializes the selection rect geometry and emits the \ref started signal. @@ -2923,7 +2923,7 @@ void QCPSelectionRect::startSelection(QMouseEvent *event) } /*! \internal - + This method is called by QCustomPlot to indicate that an ongoing selection rect interaction needs to update its geometry. The default implementation updates the rect and emits the \ref changed signal. @@ -2936,7 +2936,7 @@ void QCPSelectionRect::moveSelection(QMouseEvent *event) } /*! \internal - + This method is called by QCustomPlot to indicate that an ongoing selection rect interaction has finished by the user releasing the mouse button. The default implementation deactivates the selection rect and emits the \ref accepted signal. @@ -2949,7 +2949,7 @@ void QCPSelectionRect::endSelection(QMouseEvent *event) } /*! \internal - + This method is called by QCustomPlot when a key has been pressed by the user while the selection rect interaction is active. The default implementation allows to \ref cancel the interaction by hitting the escape key. @@ -2970,9 +2970,9 @@ void QCPSelectionRect::applyDefaultAntialiasingHint(QCPPainter *painter) const } /*! \internal - + If the selection rect is active (\ref isActive), draws the selection rect defined by \a mRect. - + \seebaseclassmethod */ void QCPSelectionRect::draw(QCPPainter *painter) @@ -2996,27 +2996,27 @@ void QCPSelectionRect::draw(QCPPainter *painter) /*! \class QCPMarginGroup \brief A margin group allows synchronization of margin sides if working with multiple layout elements. - + QCPMarginGroup allows you to tie a margin side of two or more layout elements together, such that they will all have the same size, based on the largest required margin in the group. - + \n \image html QCPMarginGroup.png "Demonstration of QCPMarginGroup" \n - + In certain situations it is desirable that margins at specific sides are synchronized across layout elements. For example, if one QCPAxisRect is below another one in a grid layout, it will provide a cleaner look to the user if the left and right margins of the two axis rects are of the same size. The left axis of the top axis rect will then be at the same horizontal position as the left axis of the lower axis rect, making them appear aligned. The same applies for the right axes. This is what QCPMarginGroup makes possible. - + To add/remove a specific side of a layout element to/from a margin group, use the \ref QCPLayoutElement::setMarginGroup method. To completely break apart the margin group, either call \ref clear, or just delete the margin group. - + \section QCPMarginGroup-example Example - + First create a margin group: \snippet documentation/doc-code-snippets/mainwindow.cpp qcpmargingroup-creation-1 Then set this group on the layout element sides: @@ -3028,7 +3028,7 @@ void QCPSelectionRect::draw(QCPPainter *painter) /* start documentation of inline functions */ /*! \fn QList QCPMarginGroup::elements(QCP::MarginSide side) const - + Returns a list of all layout elements that have their margin \a side associated with this margin group. */ @@ -3087,10 +3087,10 @@ void QCPMarginGroup::clear() } /*! \internal - + Returns the synchronized common margin for \a side. This is the margin value that will be used by the layout element on the respective side, if it is part of this margin group. - + The common margin is calculated by requesting the automatic margin (\ref QCPLayoutElement::calculateAutoMargin) of each element associated with \a side in this margin group, and choosing the largest returned value. (QCPLayoutElement::minimumMargins is taken into @@ -3112,9 +3112,9 @@ int QCPMarginGroup::commonMargin(QCP::MarginSide side) const } /*! \internal - + Adds \a element to the internal list of child elements, for the margin \a side. - + This function does not modify the margin group property of \a element. */ void QCPMarginGroup::addChild(QCP::MarginSide side, QCPLayoutElement *element) @@ -3126,9 +3126,9 @@ void QCPMarginGroup::addChild(QCP::MarginSide side, QCPLayoutElement *element) } /*! \internal - + Removes \a element from the internal list of child elements, for the margin \a side. - + This function does not modify the margin group property of \a element. */ void QCPMarginGroup::removeChild(QCP::MarginSide side, QCPLayoutElement *element) @@ -3144,20 +3144,20 @@ void QCPMarginGroup::removeChild(QCP::MarginSide side, QCPLayoutElement *element /*! \class QCPLayoutElement \brief The abstract base class for all objects that form \ref thelayoutsystem "the layout system". - + This is an abstract base class. As such, it can't be instantiated directly, rather use one of its subclasses. - + A Layout element is a rectangular object which can be placed in layouts. It has an outer rect (QCPLayoutElement::outerRect) and an inner rect (\ref QCPLayoutElement::rect). The difference between outer and inner rect is called its margin. The margin can either be set to automatic or manual (\ref setAutoMargins) on a per-side basis. If a side is set to manual, that margin can be set explicitly with \ref setMargins and will stay fixed at that value. If it's set to automatic, the layout element subclass will control the value itself (via \ref calculateAutoMargin). - + Layout elements can be placed in layouts (base class QCPLayout) like QCPLayoutGrid. The top level layout is reachable via \ref QCustomPlot::plotLayout, and is a \ref QCPLayoutGrid. Since \ref QCPLayout itself derives from \ref QCPLayoutElement, layouts can be nested. - + Thus in QCustomPlot one can divide layout elements into two categories: The ones that are invisible by themselves, because they don't draw anything. Their only purpose is to manage the position and size of other layout elements. This category of layout elements usually use @@ -3171,31 +3171,31 @@ void QCPMarginGroup::removeChild(QCP::MarginSide side, QCPLayoutElement *element /* start documentation of inline functions */ /*! \fn QCPLayout *QCPLayoutElement::layout() const - + Returns the parent layout of this layout element. */ /*! \fn QRect QCPLayoutElement::rect() const - + Returns the inner rect of this layout element. The inner rect is the outer rect (\ref outerRect, \ref setOuterRect) shrinked by the margins (\ref setMargins, \ref setAutoMargins). - + In some cases, the area between outer and inner rect is left blank. In other cases the margin area is used to display peripheral graphics while the main content is in the inner rect. This is where automatic margin calculation becomes interesting because it allows the layout element to adapt the margins to the peripheral graphics it wants to draw. For example, \ref QCPAxisRect draws the axis labels and tick labels in the margin area, thus needs to adjust the margins (if \ref setAutoMargins is enabled) according to the space required by the labels of the axes. - + \see outerRect */ /*! \fn QRect QCPLayoutElement::outerRect() const - + Returns the outer rect of this layout element. The outer rect is the inner rect expanded by the margins (\ref setMargins, \ref setAutoMargins). The outer rect is used (and set via \ref setOuterRect) by the parent \ref QCPLayout to control the size of this layout element. - + \see rect */ @@ -3229,12 +3229,12 @@ QCPLayoutElement::~QCPLayoutElement() /*! Sets the outer rect of this layout element. If the layout element is inside a layout, the layout sets the position and size of this layout element using this function. - + Calling this function externally has no effect, since the layout will overwrite any changes to the outer rect upon the next replot. - + The layout element will adapt its inner \ref rect by applying the margins inward to the outer rect. - + \see rect */ void QCPLayoutElement::setOuterRect(const QRect &rect) @@ -3250,11 +3250,11 @@ void QCPLayoutElement::setOuterRect(const QRect &rect) Sets the margins of this layout element. If \ref setAutoMargins is disabled for some or all sides, this function is used to manually set the margin on those sides. Sides that are still set to be handled automatically are ignored and may have any value in \a margins. - + The margin is the distance between the outer rect (controlled by the parent layout via \ref setOuterRect) and the inner \ref rect (which usually contains the main content of this layout element). - + \see setAutoMargins */ void QCPLayoutElement::setMargins(const QMargins &margins) @@ -3269,10 +3269,10 @@ void QCPLayoutElement::setMargins(const QMargins &margins) /*! If \ref setAutoMargins is enabled on some or all margins, this function is used to provide minimum values for those margins. - + The minimum values are not enforced on margin sides that were set to be under manual control via \ref setAutoMargins. - + \see setAutoMargins */ void QCPLayoutElement::setMinimumMargins(const QMargins &margins) @@ -3287,10 +3287,10 @@ void QCPLayoutElement::setMinimumMargins(const QMargins &margins) Sets on which sides the margin shall be calculated automatically. If a side is calculated automatically, a minimum margin value may be provided with \ref setMinimumMargins. If a side is set to be controlled manually, the value may be specified with \ref setMargins. - + Margin sides that are under automatic control may participate in a \ref QCPMarginGroup (see \ref setMarginGroup), to synchronize (align) it with other layout elements in the plot. - + \see setMinimumMargins, setMargins, QCP::MarginSide */ void QCPLayoutElement::setAutoMargins(QCP::MarginSides sides) @@ -3301,12 +3301,12 @@ void QCPLayoutElement::setAutoMargins(QCP::MarginSides sides) /*! Sets the minimum size of this layout element. A parent layout tries to respect the \a size here by changing row/column sizes in the layout accordingly. - + If the parent layout size is not sufficient to satisfy all minimum size constraints of its child layout elements, the layout may set a size that is actually smaller than \a size. QCustomPlot propagates the layout's size constraints to the outside by setting its own minimum QWidget size accordingly, so violations of \a size should be exceptions. - + Whether this constraint applies to the inner or the outer rect can be specified with \ref setSizeConstraintRect (see \ref rect and \ref outerRect). */ @@ -3321,9 +3321,9 @@ void QCPLayoutElement::setMinimumSize(const QSize &size) } /*! \overload - + Sets the minimum size of this layout element. - + Whether this constraint applies to the inner or the outer rect can be specified with \ref setSizeConstraintRect (see \ref rect and \ref outerRect). */ @@ -3335,7 +3335,7 @@ void QCPLayoutElement::setMinimumSize(int width, int height) /*! Sets the maximum size of this layout element. A parent layout tries to respect the \a size here by changing row/column sizes in the layout accordingly. - + Whether this constraint applies to the inner or the outer rect can be specified with \ref setSizeConstraintRect (see \ref rect and \ref outerRect). */ @@ -3350,9 +3350,9 @@ void QCPLayoutElement::setMaximumSize(const QSize &size) } /*! \overload - + Sets the maximum size of this layout element. - + Whether this constraint applies to the inner or the outer rect can be specified with \ref setSizeConstraintRect (see \ref rect and \ref outerRect). */ @@ -3364,10 +3364,10 @@ void QCPLayoutElement::setMaximumSize(int width, int height) /*! Sets to which rect of a layout element the size constraints apply. Size constraints can be set via \ref setMinimumSize and \ref setMaximumSize. - + The outer rect (\ref outerRect) includes the margins (e.g. in the case of a QCPAxisRect the axis labels), whereas the inner rect (\ref rect) does not. - + \see setMinimumSize, setMaximumSize */ void QCPLayoutElement::setSizeConstraintRect(SizeConstraintRect constraintRect) @@ -3382,15 +3382,15 @@ void QCPLayoutElement::setSizeConstraintRect(SizeConstraintRect constraintRect) /*! Sets the margin \a group of the specified margin \a sides. - + Margin groups allow synchronizing specified margins across layout elements, see the documentation of \ref QCPMarginGroup. - + To unset the margin group of \a sides, set \a group to \c nullptr. - + Note that margin groups only work for margin sides that are set to automatic (\ref setAutoMargins). - + \see QCP::MarginSide */ void QCPLayoutElement::setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group) @@ -3400,7 +3400,7 @@ void QCPLayoutElement::setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *gr if (sides.testFlag(QCP::msRight)) sideVector.append(QCP::msRight); if (sides.testFlag(QCP::msTop)) sideVector.append(QCP::msTop); if (sides.testFlag(QCP::msBottom)) sideVector.append(QCP::msBottom); - + foreach (QCP::MarginSide side, sideVector) { if (marginGroup(side) != group) @@ -3408,7 +3408,7 @@ void QCPLayoutElement::setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *gr QCPMarginGroup *oldGroup = marginGroup(side); if (oldGroup) // unregister at old group oldGroup->removeChild(side, this); - + if (!group) // if setting to 0, remove hash entry. Else set hash entry to new group and register there { mMarginGroups.remove(side); @@ -3426,10 +3426,10 @@ void QCPLayoutElement::setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *gr replot by the parent layout element. It is called multiple times, once for every \ref UpdatePhase. The phases are run through in the order of the enum values. For details about what happens at the different phases, see the documentation of \ref UpdatePhase. - + Layout elements that have child elements should call the \ref update method of their child elements, and pass the current \a phase unchanged. - + The default implementation executes the automatic margin mechanism in the \ref upMargins phase. Subclasses should make sure to call the base class implementation. */ @@ -3463,13 +3463,13 @@ void QCPLayoutElement::update(UpdatePhase phase) /*! Returns the suggested minimum size this layout element (the \ref outerRect) may be compressed to, if no manual minimum size is set. - + if a minimum size (\ref setMinimumSize) was not set manually, parent layouts use the returned size (usually indirectly through \ref QCPLayout::getFinalMinimumOuterSize) to determine the minimum allowed size of this layout element. A manual minimum size is considered set if it is non-zero. - + The default implementation simply returns the sum of the horizontal margins for the width and the sum of the vertical margins for the height. Reimplementations may use their detailed knowledge about the layout element's content to provide size hints. @@ -3482,13 +3482,13 @@ QSize QCPLayoutElement::minimumOuterSizeHint() const /*! Returns the suggested maximum size this layout element (the \ref outerRect) may be expanded to, if no manual maximum size is set. - + if a maximum size (\ref setMaximumSize) was not set manually, parent layouts use the returned size (usually indirectly through \ref QCPLayout::getFinalMaximumOuterSize) to determine the maximum allowed size of this layout element. A manual maximum size is considered set if it is smaller than Qt's \c QWIDGETSIZE_MAX. - + The default implementation simply returns \c QWIDGETSIZE_MAX for both width and height, implying no suggested maximum size. Reimplementations may use their detailed knowledge about the layout element's content to provide size hints. @@ -3501,7 +3501,7 @@ QSize QCPLayoutElement::maximumOuterSizeHint() const /*! Returns a list of all child elements in this layout element. If \a recursive is true, all sub-child elements are included in the list, too. - + \warning There may be \c nullptr entries in the returned list. For example, QCPLayoutGrid may have empty cells which yield \c nullptr at the respective index. */ @@ -3516,19 +3516,19 @@ QList QCPLayoutElement::elements(bool recursive) const rect, this method returns a value corresponding to 0.99 times the parent plot's selection tolerance. However, layout elements are not selectable by default. So if \a onlySelectable is true, -1.0 is returned. - + See \ref QCPLayerable::selectTest for a general explanation of this virtual method. - + QCPLayoutElement subclasses may reimplement this method to provide more specific selection test behaviour. */ double QCPLayoutElement::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const { Q_UNUSED(details) - + if (onlySelectable) return -1; - + if (QRectF(mOuterRect).contains(pos)) { if (mParentPlot) @@ -3543,7 +3543,7 @@ double QCPLayoutElement::selectTest(const QPointF &pos, bool onlySelectable, QVa } /*! \internal - + propagates the parent plot initialization to all child elements, by calling \ref QCPLayerable::initializeParentPlot on them. */ @@ -3557,11 +3557,11 @@ void QCPLayoutElement::parentPlotInitialized(QCustomPlot *parentPlot) } /*! \internal - + Returns the margin size for this \a side. It is used if automatic margins is enabled for this \a side (see \ref setAutoMargins). If a minimum margin was set with \ref setMinimumMargins, the returned value will not be smaller than the specified minimum margin. - + The default implementation just returns the respective manual margin (\ref setMargins) or the minimum margin, whichever is larger. */ @@ -3571,14 +3571,14 @@ int QCPLayoutElement::calculateAutoMargin(QCP::MarginSide side) } /*! \internal - + This virtual method is called when this layout element was moved to a different QCPLayout, or when this layout element has changed its logical position (e.g. row and/or column) within the same QCPLayout. Subclasses may use this to react accordingly. - + Since this method is called after the completion of the move, you can access the new parent layout via \ref layout(). - + The default implementation does nothing. */ void QCPLayoutElement::layoutChanged() @@ -3591,23 +3591,23 @@ void QCPLayoutElement::layoutChanged() /*! \class QCPLayout \brief The abstract base class for layouts - + This is an abstract base class for layout elements whose main purpose is to define the position and size of other child layout elements. In most cases, layouts don't draw anything themselves (but there are exceptions to this, e.g. QCPLegend). - + QCPLayout derives from QCPLayoutElement, and thus can itself be nested in other layouts. - + QCPLayout introduces a common interface for accessing and manipulating the child elements. Those functions are most notably \ref elementCount, \ref elementAt, \ref takeAt, \ref take, \ref simplify, \ref removeAt, \ref remove and \ref clear. Individual subclasses may add more functions to this interface which are more specialized to the form of the layout. For example, \ref QCPLayoutGrid adds functions that take row and column indices to access cells of the layout grid more conveniently. - + Since this is an abstract base class, you can't instantiate it directly. Rather use one of its subclasses like QCPLayoutGrid or QCPLayoutInset. - + For a general introduction to the layout system, see the dedicated documentation page \ref thelayoutsystem "The Layout System". */ @@ -3615,45 +3615,45 @@ void QCPLayoutElement::layoutChanged() /* start documentation of pure virtual functions */ /*! \fn virtual int QCPLayout::elementCount() const = 0 - + Returns the number of elements/cells in the layout. - + \see elements, elementAt */ /*! \fn virtual QCPLayoutElement* QCPLayout::elementAt(int index) const = 0 - + Returns the element in the cell with the given \a index. If \a index is invalid, returns \c nullptr. - + Note that even if \a index is valid, the respective cell may be empty in some layouts (e.g. QCPLayoutGrid), so this function may return \c nullptr in those cases. You may use this function to check whether a cell is empty or not. - + \see elements, elementCount, takeAt */ /*! \fn virtual QCPLayoutElement* QCPLayout::takeAt(int index) = 0 - + Removes the element with the given \a index from the layout and returns it. - + If the \a index is invalid or the cell with that index is empty, returns \c nullptr. - + Note that some layouts don't remove the respective cell right away but leave an empty cell after successful removal of the layout element. To collapse empty cells, use \ref simplify. - + \see elementAt, take */ /*! \fn virtual bool QCPLayout::take(QCPLayoutElement* element) = 0 - + Removes the specified \a element from the layout and returns true on success. - + If the \a element isn't in this layout, returns false. - + Note that some layouts don't remove the respective cell right away but leave an empty cell after successful removal of the layout element. To collapse empty cells, use \ref simplify. - + \see takeAt */ @@ -3670,20 +3670,20 @@ QCPLayout::QCPLayout() /*! If \a phase is \ref upLayout, calls \ref updateLayout, which subclasses may reimplement to reposition and resize their cells. - + Finally, the call is propagated down to all child \ref QCPLayoutElement "QCPLayoutElements". - + For details about this method and the update phases, see the documentation of \ref QCPLayoutElement::update. */ void QCPLayout::update(UpdatePhase phase) { QCPLayoutElement::update(phase); - + // set child element rects according to layout: if (phase == upLayout) updateLayout(); - + // propagate update call to child elements: const int elCount = elementCount(); for (int i=0; i QCPLayout::elements(bool recursive) const /*! Simplifies the layout by collapsing empty cells. The exact behavior depends on subclasses, the default implementation does nothing. - + Not all layouts need simplification. For example, QCPLayoutInset doesn't use explicit simplification while QCPLayoutGrid does. */ @@ -3728,12 +3728,12 @@ void QCPLayout::simplify() /*! Removes and deletes the element at the provided \a index. Returns true on success. If \a index is invalid or points to an empty cell, returns false. - + This function internally uses \ref takeAt to remove the element from the layout and then deletes the returned element. Note that some layouts don't remove the respective cell right away but leave an empty cell after successful removal of the layout element. To collapse empty cells, use \ref simplify. - + \see remove, takeAt */ bool QCPLayout::removeAt(int index) @@ -3749,12 +3749,12 @@ bool QCPLayout::removeAt(int index) /*! Removes and deletes the provided \a element. Returns true on success. If \a element is not in the layout, returns false. - + This function internally uses \ref takeAt to remove the element from the layout and then deletes the element. Note that some layouts don't remove the respective cell right away but leave an empty cell after successful removal of the layout element. To collapse empty cells, use \ref simplify. - + \see removeAt, take */ bool QCPLayout::remove(QCPLayoutElement *element) @@ -3770,7 +3770,7 @@ bool QCPLayout::remove(QCPLayoutElement *element) /*! Removes and deletes all layout elements in this layout. Finally calls \ref simplify to make sure all empty cells are collapsed. - + \see remove, removeAt */ void QCPLayout::clear() @@ -3785,7 +3785,7 @@ void QCPLayout::clear() /*! Subclasses call this method to report changed (minimum/maximum) size constraints. - + If the parent of this layout is again a QCPLayout, forwards the call to the parent's \ref sizeConstraintsChanged. If the parent is a QWidget (i.e. is the \ref QCustomPlot::plotLayout of QCustomPlot), calls QWidget::updateGeometry, so if the QCustomPlot widget is inside a Qt QLayout, @@ -3800,15 +3800,15 @@ void QCPLayout::sizeConstraintsChanged() const } /*! \internal - + Subclasses reimplement this method to update the position and sizes of the child elements/cells via calling their \ref QCPLayoutElement::setOuterRect. The default implementation does nothing. - + The geometry used as a reference is the inner \ref rect of this layout. Child elements should stay within that rect. - + \ref getSectionSizes may help with the reimplementation of this function. - + \see update */ void QCPLayout::updateLayout() @@ -3817,13 +3817,13 @@ void QCPLayout::updateLayout() /*! \internal - + Associates \a el with this layout. This is done by setting the \ref QCPLayoutElement::layout, the \ref QCPLayerable::parentLayerable and the QObject parent to this layout. - + Further, if \a el didn't previously have a parent plot, calls \ref QCPLayerable::initializeParentPlot on \a el to set the paret plot. - + This method is used by subclass specific methods that add elements to the layout. Note that this method only changes properties in \a el. The removal from the old layout and the insertion into the new layout must be done additionally. @@ -3843,11 +3843,11 @@ void QCPLayout::adoptElement(QCPLayoutElement *el) } /*! \internal - + Disassociates \a el from this layout. This is done by setting the \ref QCPLayoutElement::layout and the \ref QCPLayerable::parentLayerable to zero. The QObject parent is set to the parent QCustomPlot. - + This method is used by subclass specific methods that remove elements from the layout (e.g. \ref take or \ref takeAt). Note that this method only changes properties in \a el. The removal from the old layout must be done additionally. @@ -3865,32 +3865,32 @@ void QCPLayout::releaseElement(QCPLayoutElement *el) } /*! \internal - + This is a helper function for the implementation of \ref updateLayout in subclasses. - + It calculates the sizes of one-dimensional sections with provided constraints on maximum section sizes, minimum section sizes, relative stretch factors and the final total size of all sections. - + The QVector entries refer to the sections. Thus all QVectors must have the same size. - + \a maxSizes gives the maximum allowed size of each section. If there shall be no maximum size imposed, set all vector values to Qt's QWIDGETSIZE_MAX. - + \a minSizes gives the minimum allowed size of each section. If there shall be no minimum size imposed, set all vector values to zero. If the \a minSizes entries add up to a value greater than \a totalSize, sections will be scaled smaller than the proposed minimum sizes. (In other words, not exceeding the allowed total size is taken to be more important than not going below minimum section sizes.) - + \a stretchFactors give the relative proportions of the sections to each other. If all sections shall be scaled equally, set all values equal. If the first section shall be double the size of each individual other section, set the first number of \a stretchFactors to double the value of the other individual values (e.g. {2, 1, 1, 1}). - + \a totalSize is the value that the final section sizes will add up to. Due to rounding, the actual sum may differ slightly. If you want the section sizes to sum up to exactly that value, you could distribute the remaining difference on the sections. - + The return value is a QVector containing the section sizes. */ QVector QCPLayout::getSectionSizes(QVector maxSizes, QVector minSizes, QVector stretchFactors, int totalSize) const @@ -3917,13 +3917,13 @@ QVector QCPLayout::getSectionSizes(QVector maxSizes, QVector minS minSizes[i] = 0; } } - + QList minimumLockedSections; QList unfinishedSections; for (int i=0; i QCPLayout::getSectionSizes(QVector maxSizes, QVector minS } if (innerIterations == sectionCount*2) qDebug() << Q_FUNC_INFO << "Exceeded maximum expected inner iteration count, layouting aborted. Input was:" << maxSizes << minSizes << stretchFactors << totalSize; - + // now check whether the resulting section sizes violate minimum restrictions: bool foundMinimumViolation = false; for (int i=0; i QCPLayout::getSectionSizes(QVector maxSizes, QVector minS } if (outerIterations == sectionCount*2) qDebug() << Q_FUNC_INFO << "Exceeded maximum expected outer iteration count, layouting aborted. Input was:" << maxSizes << minSizes << stretchFactors << totalSize; - + QVector result(sectionCount); for (int i=0; i QCPLayout::getSectionSizes(QVector maxSizes, QVector minS } /*! \internal - + This is a helper function for the implementation of subclasses. - + It returns the minimum size that should finally be used for the outer rect of the passed layout element \a el. - + It takes into account whether a manual minimum size is set (\ref QCPLayoutElement::setMinimumSize), which size constraint is set (\ref QCPLayoutElement::setSizeConstraintRect), as well as the minimum size hint, if no manual minimum @@ -4025,18 +4025,18 @@ QSize QCPLayout::getFinalMinimumOuterSize(const QCPLayoutElement *el) minOuter.rwidth() += el->margins().left() + el->margins().right(); if (minOuter.height() > 0 && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) minOuter.rheight() += el->margins().top() + el->margins().bottom(); - + return {minOuter.width() > 0 ? minOuter.width() : minOuterHint.width(), minOuter.height() > 0 ? minOuter.height() : minOuterHint.height()}; } /*! \internal - + This is a helper function for the implementation of subclasses. - + It returns the maximum size that should finally be used for the outer rect of the passed layout element \a el. - + It takes into account whether a manual maximum size is set (\ref QCPLayoutElement::setMaximumSize), which size constraint is set (\ref QCPLayoutElement::setSizeConstraintRect), as well as the maximum size hint, if no manual maximum @@ -4050,7 +4050,7 @@ QSize QCPLayout::getFinalMaximumOuterSize(const QCPLayoutElement *el) maxOuter.rwidth() += el->margins().left() + el->margins().right(); if (maxOuter.height() < QWIDGETSIZE_MAX && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) maxOuter.rheight() += el->margins().top() + el->margins().bottom(); - + return {maxOuter.width() < QWIDGETSIZE_MAX ? maxOuter.width() : maxOuterHint.width(), maxOuter.height() < QWIDGETSIZE_MAX ? maxOuter.height() : maxOuterHint.height()}; } @@ -4118,10 +4118,10 @@ QCPLayoutGrid::~QCPLayoutGrid() /*! Returns the element in the cell in \a row and \a column. - + Returns \c nullptr if either the row/column is invalid or if the cell is empty. In those cases, a qDebug message is printed. To check whether a cell exists and isn't empty, use \ref hasElement. - + \see addElement, hasElement */ QCPLayoutElement *QCPLayoutGrid::element(int row, int column) const @@ -4215,7 +4215,7 @@ bool QCPLayoutGrid::addElement(QCPLayoutElement *element) /*! Returns whether the cell at \a row and \a column exists and contains a valid element, i.e. isn't empty. - + \see element */ bool QCPLayoutGrid::hasElement(int row, int column) @@ -4228,14 +4228,14 @@ bool QCPLayoutGrid::hasElement(int row, int column) /*! Sets the stretch \a factor of \a column. - + Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond their minimum and maximum widths/heights, regardless of the stretch factor. (see \ref QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize, \ref QCPLayoutElement::setSizeConstraintRect.) - + The default stretch factor of newly created rows/columns is 1. - + \see setColumnStretchFactors, setRowStretchFactor */ void QCPLayoutGrid::setColumnStretchFactor(int column, double factor) @@ -4252,14 +4252,14 @@ void QCPLayoutGrid::setColumnStretchFactor(int column, double factor) /*! Sets the stretch \a factors of all columns. \a factors must have the size \ref columnCount. - + Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond their minimum and maximum widths/heights, regardless of the stretch factor. (see \ref QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize, \ref QCPLayoutElement::setSizeConstraintRect.) - + The default stretch factor of newly created rows/columns is 1. - + \see setColumnStretchFactor, setRowStretchFactors */ void QCPLayoutGrid::setColumnStretchFactors(const QList &factors) @@ -4281,14 +4281,14 @@ void QCPLayoutGrid::setColumnStretchFactors(const QList &factors) /*! Sets the stretch \a factor of \a row. - + Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond their minimum and maximum widths/heights, regardless of the stretch factor. (see \ref QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize, \ref QCPLayoutElement::setSizeConstraintRect.) - + The default stretch factor of newly created rows/columns is 1. - + \see setColumnStretchFactors, setRowStretchFactor */ void QCPLayoutGrid::setRowStretchFactor(int row, double factor) @@ -4305,14 +4305,14 @@ void QCPLayoutGrid::setRowStretchFactor(int row, double factor) /*! Sets the stretch \a factors of all rows. \a factors must have the size \ref rowCount. - + Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond their minimum and maximum widths/heights, regardless of the stretch factor. (see \ref QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize, \ref QCPLayoutElement::setSizeConstraintRect.) - + The default stretch factor of newly created rows/columns is 1. - + \see setRowStretchFactor, setColumnStretchFactors */ void QCPLayoutGrid::setRowStretchFactors(const QList &factors) @@ -4334,7 +4334,7 @@ void QCPLayoutGrid::setRowStretchFactors(const QList &factors) /*! Sets the gap that is left blank between columns to \a pixels. - + \see setRowSpacing */ void QCPLayoutGrid::setColumnSpacing(int pixels) @@ -4344,7 +4344,7 @@ void QCPLayoutGrid::setColumnSpacing(int pixels) /*! Sets the gap that is left blank between rows to \a pixels. - + \see setColumnSpacing */ void QCPLayoutGrid::setRowSpacing(int pixels) @@ -4358,7 +4358,7 @@ void QCPLayoutGrid::setRowSpacing(int pixels) on \ref setFillOrder, whether rows or columns are wrapped. If \a count is set to zero, no wrapping will ever occur. - + If you wish to re-wrap the elements currently in the layout, call \ref setFillOrder with \a rearrange set to true (the actual fill order doesn't need to be changed for the rearranging to be done). @@ -4427,15 +4427,15 @@ void QCPLayoutGrid::setFillOrder(FillOrder order, bool rearrange) /*! Expands the layout to have \a newRowCount rows and \a newColumnCount columns. So the last valid row index will be \a newRowCount-1, the last valid column index will be \a newColumnCount-1. - + If the current column/row count is already larger or equal to \a newColumnCount/\a newRowCount, this function does nothing in that dimension. - + Newly created cells are empty, new rows and columns have the stretch factor 1. - + Note that upon a call to \ref addElement, the layout is expanded automatically to contain the specified row and column, using this function. - + \see simplify */ void QCPLayoutGrid::expandTo(int newRowCount, int newColumnCount) @@ -4460,7 +4460,7 @@ void QCPLayoutGrid::expandTo(int newRowCount, int newColumnCount) /*! Inserts a new row with empty cells at the row index \a newIndex. Valid values for \a newIndex range from 0 (inserts a row at the top) to \a rowCount (appends a row at the bottom). - + \see insertColumn */ void QCPLayoutGrid::insertRow(int newIndex) @@ -4470,12 +4470,12 @@ void QCPLayoutGrid::insertRow(int newIndex) expandTo(1, 1); return; } - + if (newIndex < 0) newIndex = 0; if (newIndex > rowCount()) newIndex = rowCount(); - + mRowStretchFactors.insert(newIndex, 1); QList newRow; for (int col=0; col columnCount()) newIndex = columnCount(); - + mColumnStretchFactors.insert(newIndex, 1); for (int row=0; row minColWidths, minRowHeights, maxColWidths, maxRowHeights; getMinimumRowColSizes(&minColWidths, &minRowHeights); getMaximumRowColSizes(&maxColWidths, &maxRowHeights); - + int totalRowSpacing = (rowCount()-1) * mRowSpacing; int totalColSpacing = (columnCount()-1) * mColumnSpacing; QVector colWidths = getSectionSizes(maxColWidths, minColWidths, mColumnStretchFactors.toVector(), mRect.width()-totalColSpacing); QVector rowHeights = getSectionSizes(maxRowHeights, minRowHeights, mRowStretchFactors.toVector(), mRect.height()-totalRowSpacing); - + // go through cells and set rects accordingly: int yOffset = mRect.top(); for (int row=0; row=0; --col) { @@ -4766,7 +4766,7 @@ QSize QCPLayoutGrid::maximumOuterSizeHint() const { QVector maxColWidths, maxRowHeights; getMaximumRowColSizes(&maxColWidths, &maxRowHeights); - + QSize result(0, 0); foreach (int w, maxColWidths) result.setWidth(qMin(result.width()+w, QWIDGETSIZE_MAX)); @@ -4784,16 +4784,16 @@ QSize QCPLayoutGrid::maximumOuterSizeHint() const } /*! \internal - + Places the minimum column widths and row heights into \a minColWidths and \a minRowHeights respectively. - + The minimum height of a row is the largest minimum height of any element's outer rect in that row. The minimum width of a column is the largest minimum width of any element's outer rect in that column. - + This is a helper function for \ref updateLayout. - + \see getMaximumRowColSizes */ void QCPLayoutGrid::getMinimumRowColSizes(QVector *minColWidths, QVector *minRowHeights) const @@ -4817,16 +4817,16 @@ void QCPLayoutGrid::getMinimumRowColSizes(QVector *minColWidths, QVector *maxColWidths, QVector *maxRowHeights) const @@ -4855,7 +4855,7 @@ void QCPLayoutGrid::getMaximumRowColSizes(QVector *maxColWidths, QVector *maxColWidths, QVectorpen(); QBrush brushBackup = painter->brush(); QPen miterPen = penBackup; @@ -5444,7 +5444,7 @@ void QCPLineEnding::draw(QCPPainter *painter, const QCPVector2D &pos, const QCPV /*! \internal \overload - + Draws the line ending. The direction is controlled with the \a angle parameter in radians. */ void QCPLineEnding::draw(QCPPainter *painter, const QCPVector2D &pos, double angle) const @@ -5466,9 +5466,9 @@ void QCPLineEnding::draw(QCPPainter *painter, const QCPVector2D &pos, double ang \internal \brief (Private) - + This is a private class and not part of the public QCustomPlot interface. - + */ const QChar QCPLabelPainterPrivate::SymbolDot(183); @@ -5477,7 +5477,7 @@ const QChar QCPLabelPainterPrivate::SymbolCross(215); /*! Constructs a QCPLabelPainterPrivate instance. Make sure to not create a new instance on every redraw, to utilize the caching mechanisms. - + the \a parentPlot does not take ownership of the label painter. Make sure to delete it appropriately. */ @@ -5573,12 +5573,12 @@ int QCPLabelPainterPrivate::cacheSize() const void QCPLabelPainterPrivate::drawTickLabel(QCPPainter *painter, const QPointF &tickPos, const QString &text) { double realRotation = mRotation; - + AnchorSide realSide = mAnchorSide; // for circular axes, the anchor side is determined depending on the quadrant of tickPos with respect to mCircularReference if (mAnchorMode == amSkewedUpright) { - realSide = skewedAnchorSide(tickPos, 0.2, 0.3); + realSide = skewedAnchorSide(tickPos, 0.2, 0.3); } else if (mAnchorMode == amSkewedRotated) // in this mode every label is individually rotated to match circle tangent { realSide = skewedAnchorSide(tickPos, 0, 0); @@ -5586,13 +5586,13 @@ void QCPLabelPainterPrivate::drawTickLabel(QCPPainter *painter, const QPointF &t if (realRotation > 90) realRotation -= 180; else if (realRotation < -90) realRotation += 180; } - + realSide = rotationCorrectedSide(realSide, realRotation); // rotation angles may change the true anchor side of the label drawLabelMaybeCached(painter, mFont, mColor, getAnchorPos(tickPos), realSide, realRotation, text); } /*! \internal - + Returns the size ("margin" in QCPAxisRect context, so measured perpendicular to the axis backbone direction) needed to fit the axis. */ @@ -5603,7 +5603,7 @@ int QCPLabelPainterPrivate::size() const // get length of tick marks pointing outwards: if (!tickPositions.isEmpty()) result += qMax(0, qMax(tickLengthOut, subTickLengthOut)); - + // calculate size of tick labels: if (tickLabelSide == QCPAxis::lsOutside) { @@ -5616,7 +5616,7 @@ int QCPLabelPainterPrivate::size() const result += tickLabelPadding; } } - + // calculate size of axis label (only height needed, because left/right labels are rotated by 90 degrees): if (!label.isEmpty()) { @@ -5631,7 +5631,7 @@ int QCPLabelPainterPrivate::size() const */ /*! \internal - + Clears the internal label cache. Upon the next \ref draw, all labels will be created new. This method is called automatically if any parameters have changed that invalidate the cached labels, such as font, color, etc. Usually you won't need to call this method manually. @@ -5642,7 +5642,7 @@ void QCPLabelPainterPrivate::clearCache() } /*! \internal - + Returns a hash that allows uniquely identifying whether the label parameters have changed such that the cached labels must be refreshed (\ref clearCache). It is used in \ref draw. If the return value of this method hasn't changed since the last redraw, the respective label parameters @@ -5662,20 +5662,20 @@ QByteArray QCPLabelPainterPrivate::generateLabelParameterHash() const } /*! \internal - + Draws a single tick label with the provided \a painter, utilizing the internal label cache to significantly speed up drawing of labels that were drawn in previous calls. The tick label is always bound to an axis, the distance to the axis is controllable via \a distanceToAxis in pixels. The pixel position in the axis direction is passed in the \a position parameter. Hence for the bottom axis, \a position would indicate the horizontal pixel position (not coordinate), at which the label should be drawn. - + In order to later draw the axis label in a place that doesn't overlap with the tick labels, the largest tick label size is needed. This is acquired by passing a \a tickLabelsSize to the \ref drawTickLabel calls during the process of drawing all tick labels of one axis. In every call, \a tickLabelsSize is expanded, if the drawn label exceeds the value \a tickLabelsSize currently holds. - + The label is drawn with the font and pen that are currently set on the \a painter. To draw superscripted powers, the font is temporarily made smaller by a fixed factor (see \ref getTickLabelData). @@ -5777,9 +5777,9 @@ QPointF QCPLabelPainterPrivate::getAnchorPos(const QPointF &tickPos) } /*! \internal - + This is a \ref placeTickLabel helper function. - + Draws the tick label specified in \a labelData with \a painter at the pixel positions \a x and \a y. This function is used by \ref placeTickLabel to create new tick labels for the cache, or to directly draw the labels on the QCustomPlot surface when label caching is disabled, i.e. when @@ -5791,11 +5791,11 @@ void QCPLabelPainterPrivate::drawText(QCPPainter *painter, const QPointF &pos, c QTransform oldTransform = painter->transform(); QFont oldFont = painter->font(); QPen oldPen = painter->pen(); - + // transform painter to position/rotation: painter->translate(pos); painter->setTransform(labelData.transform, true); - + // draw text: painter->setFont(labelData.baseFont); painter->setPen(QPen(labelData.color)); @@ -5810,7 +5810,7 @@ void QCPLabelPainterPrivate::drawText(QCPPainter *painter, const QPointF &pos, c { painter->drawText(0, 0, labelData.totalBounds.width(), labelData.totalBounds.height(), Qt::TextDontClip | Qt::AlignHCenter, labelData.basePart); } - + /* Debug code to draw label bounding boxes, baseline, and capheight painter->save(); painter->setPen(QPen(QColor(0, 0, 0, 150))); @@ -5822,7 +5822,7 @@ void QCPLabelPainterPrivate::drawText(QCPPainter *painter, const QPointF &pos, c painter->drawLine(QLineF(0, baseline-mLetterCapHeight, labelData.totalBounds.width(), baseline-mLetterCapHeight)); painter->restore(); */ - + // reset painter settings to what it was before: painter->setTransform(oldTransform); painter->setFont(oldFont); @@ -5830,9 +5830,9 @@ void QCPLabelPainterPrivate::drawText(QCPPainter *painter, const QPointF &pos, c } /*! \internal - + This is a \ref placeTickLabel helper function. - + Transforms the passed \a text and \a font to a tickLabelData structure that can then be further processed by \ref getTickLabelDrawOffset and \ref drawTickLabel. It splits the text into base and exponent if necessary (member substituteExponent) and calculates appropriate bounding boxes. @@ -5843,7 +5843,7 @@ QCPLabelPainterPrivate::LabelData QCPLabelPainterPrivate::getTickLabelData(const result.rotation = rotation; result.side = side; result.color = color; - + // determine whether beautiful decimal powers should be used bool useBeautifulPowers = false; int ePos = -1; // first index of exponent part, text before that will be basePart, text until eLast will be expPart @@ -5860,12 +5860,12 @@ QCPLabelPainterPrivate::LabelData QCPLabelPainterPrivate::getTickLabelData(const useBeautifulPowers = true; } } - + // calculate text bounding rects and do string preparation for beautiful decimal powers: result.baseFont = font; if (result.baseFont.pointSizeF() > 0) // might return -1 if specified with setPixelSize, in that case we can't do correction in next line result.baseFont.setPointSizeF(result.baseFont.pointSizeF()+0.05); // QFontMetrics.boundingRect has a bug for exact point sizes that make the results oscillate due to internal rounding - + QFontMetrics baseFontMetrics(result.baseFont); if (useBeautifulPowers) { @@ -5903,7 +5903,7 @@ QCPLabelPainterPrivate::LabelData QCPLabelPainterPrivate::getTickLabelData(const result.totalBounds.moveTopLeft(QPoint(0, 0)); applyAnchorTransform(result); result.rotatedTotalBounds = result.transform.mapRect(result.totalBounds); - + return result; } @@ -5911,16 +5911,16 @@ void QCPLabelPainterPrivate::applyAnchorTransform(LabelData &labelData) const { if (!qFuzzyIsNull(labelData.rotation)) labelData.transform.rotate(labelData.rotation); // rotates effectively clockwise (due to flipped y axis of painter vs widget coordinate system) - + // from now on we translate in rotated label-local coordinate system. // shift origin of coordinate system to appropriate point on label: labelData.transform.translate(0, -labelData.totalBounds.height()+mLetterDescent+mLetterCapHeight); // shifts origin to true top of capital (or number) characters - + if (labelData.side == asLeft || labelData.side == asRight) // anchor is centered vertically labelData.transform.translate(0, -mLetterCapHeight/2.0); else if (labelData.side == asTop || labelData.side == asBottom) // anchor is centered horizontally labelData.transform.translate(-labelData.totalBounds.width()/2.0, 0); - + if (labelData.side == asTopRight || labelData.side == asRight || labelData.side == asBottomRight) // anchor is at right labelData.transform.translate(-labelData.totalBounds.width(), 0); if (labelData.side == asBottomLeft || labelData.side == asBottom || labelData.side == asBottomRight) // anchor is at bottom (no elseif!) @@ -5928,7 +5928,7 @@ void QCPLabelPainterPrivate::applyAnchorTransform(LabelData &labelData) const } /*! \internal - + Simulates the steps done by \ref placeTickLabel by calculating bounding boxes of the text label to be drawn, depending on number format etc. Since only the largest tick label is wanted for the margin calculation, the passed \a tickLabelsSize is only expanded, if it's currently set to a @@ -5948,7 +5948,7 @@ void QCPLabelPainterPrivate::getMaxTickLabelSize(const QFont &font, const QStrin // TODO: LabelData labelData = getTickLabelData(font, text); // TODO: finalSize = labelData.rotatedTotalBounds.size(); } - + // expand passed tickLabelsSize if current tick label is larger: if (finalSize.width() > tickLabelsSize->width()) tickLabelsSize->setWidth(finalSize.width()); @@ -5960,7 +5960,7 @@ void QCPLabelPainterPrivate::getMaxTickLabelSize(const QFont &font, const QStrin QCPLabelPainterPrivate::CachedLabel *QCPLabelPainterPrivate::createCachedLabel(const LabelData &labelData) const { CachedLabel *result = new CachedLabel; - + // allocate pixmap with the correct size and pixel ratio: if (!qFuzzyCompare(1.0, mParentPlot->bufferDevicePixelRatio())) { @@ -5975,7 +5975,7 @@ QCPLabelPainterPrivate::CachedLabel *QCPLabelPainterPrivate::createCachedLabel(c } else result->pixmap = QPixmap(labelData.rotatedTotalBounds.size()); result->pixmap.fill(Qt::transparent); - + // draw the label into the pixmap // offset is between label anchor and topleft of cache pixmap, so pixmap can be drawn at pos+offset to make the label anchor appear at pos. // We use rotatedTotalBounds.topLeft() because rotatedTotalBounds is in a coordinate system where the label anchor is at (0, 0) @@ -6065,12 +6065,12 @@ void QCPLabelPainterPrivate::analyzeFontMetrics() //////////////////////////////////////////////////////////////////////////////////////////////////// /*! \class QCPAxisTicker \brief The base class tick generator used by QCPAxis to create tick positions and tick labels - + Each QCPAxis has an internal QCPAxisTicker (or a subclass) in order to generate tick positions and tick labels for the current axis range. The ticker of an axis can be set via \ref QCPAxis::setTicker. Since that method takes a QSharedPointer, multiple axes can share the same ticker instance. - + This base class generates normal tick coordinates and numeric labels for linear axes. It picks a reasonable tick step (the separation between ticks) which results in readable tick labels. The number of ticks that should be approximately generated can be set via \ref setTickCount. @@ -6078,10 +6078,10 @@ void QCPLabelPainterPrivate::analyzeFontMetrics() sacrifices readability to better match the specified tick count (\ref QCPAxisTicker::tssMeetTickCount) or relaxes the tick count in favor of better tick steps (\ref QCPAxisTicker::tssReadability), which is the default. - + The following more specialized axis ticker subclasses are available, see details in the respective class documentation: - +
@@ -6093,25 +6093,25 @@ void QCPLabelPainterPrivate::analyzeFontMetrics() \image html axisticker-time2.png
QCPAxisTickerFixed\image html axisticker-fixed.png
- + \section axisticker-subclassing Creating own axis tickers - + Creating own axis tickers can be achieved very easily by sublassing QCPAxisTicker and reimplementing some or all of the available virtual methods. In the simplest case you might wish to just generate different tick steps than the other tickers, so you only reimplement the method \ref getTickStep. If you additionally want control over the string that will be shown as tick label, reimplement \ref getTickLabel. - + If you wish to have complete control, you can generate the tick vectors and tick label vectors yourself by reimplementing \ref createTickVector and \ref createLabelVector. The default implementations use the previously mentioned virtual methods \ref getTickStep and \ref getTickLabel, but your reimplementations don't necessarily need to do so. For example in the case of unequal tick steps, the method \ref getTickStep loses its usefulness and can be ignored. - + The sub tick count between major ticks can be controlled with \ref getSubTickCount. Full sub tick placement control is obtained by reimplementing \ref createSubTickVector. - + See the documentation of all these virtual methods in QCPAxisTicker for detailed information about the parameters and expected return values. */ @@ -6129,7 +6129,7 @@ QCPAxisTicker::QCPAxisTicker() : QCPAxisTicker::~QCPAxisTicker() { - + } /*! @@ -6160,7 +6160,7 @@ void QCPAxisTicker::setTickCount(int count) /*! Sets the mathematical coordinate (or "offset") of the zeroth tick. This tick coordinate is just a concept and doesn't need to be inside the currently visible axis range. - + By default \a origin is zero, which for example yields ticks {-5, 0, 5, 10, 15,...} when the tick step is five. If \a origin is now set to 1 instead, the correspondingly generated ticks would be {-4, 1, 6, 11, 16,...}. @@ -6173,11 +6173,11 @@ void QCPAxisTicker::setTickOrigin(double origin) /*! This is the method called by QCPAxis in order to actually generate tick coordinates (\a ticks), tick label strings (\a tickLabels) and sub tick coordinates (\a subTicks). - + The ticks are generated for the specified \a range. The generated labels typically follow the specified \a locale, \a formatChar and number \a precision, however this might be different (or even irrelevant) for certain QCPAxisTicker subclasses. - + The output parameter \a ticks is filled with the generated tick positions in axis coordinates. The output parameters \a subTicks and \a tickLabels are optional (set them to \c nullptr if not needed) and are respectively filled with sub tick coordinates, and tick label strings belonging @@ -6189,7 +6189,7 @@ void QCPAxisTicker::generate(const QCPRange &range, const QLocale &locale, QChar double tickStep = getTickStep(range); ticks = createTickVector(tickStep, range); trimTicks(range, ticks, true); // trim ticks to visible range plus one outer tick on each side (incase a subclass createTickVector creates more) - + // generate sub ticks between major ticks: if (subTicks) { @@ -6200,7 +6200,7 @@ void QCPAxisTicker::generate(const QCPRange &range, const QLocale &locale, QChar } else *subTicks = QVector(); } - + // finally trim also outliers (no further clipping happens in axis drawing): trimTicks(range, ticks, false); // generate labels for visible ticks if requested: @@ -6209,11 +6209,11 @@ void QCPAxisTicker::generate(const QCPRange &range, const QLocale &locale, QChar } /*! \internal - + Takes the entire currently visible axis range and returns a sensible tick step in order to provide readable tick labels as well as a reasonable number of tick counts (see \ref setTickCount, \ref setTickStepStrategy). - + If a QCPAxisTicker subclass only wants a different tick step behaviour than the default implementation, it should reimplement this method. See \ref cleanMantissa for a possible helper function. @@ -6225,23 +6225,23 @@ double QCPAxisTicker::getTickStep(const QCPRange &range) } /*! \internal - + Takes the \a tickStep, i.e. the distance between two consecutive ticks, and returns an appropriate number of sub ticks for that specific tick step. - + Note that a returned sub tick count of e.g. 4 will split each tick interval into 5 sections. */ int QCPAxisTicker::getSubTickCount(double tickStep) { int result = 1; // default to 1, if no proper value can be found - + // separate integer and fractional part of mantissa: double epsilon = 0.01; double intPartf; int intPart; double fracPart = modf(getMantissa(tickStep), &intPartf); intPart = int(intPartf); - + // handle cases with (almost) integer mantissa: if (fracPart < epsilon || 1.0-fracPart < epsilon) { @@ -6279,16 +6279,16 @@ int QCPAxisTicker::getSubTickCount(double tickStep) } // if mantissa fraction isn't 0.0 or 0.5, don't bother finding good sub tick marks, leave default } - + return result; } /*! \internal - + This method returns the tick label string as it should be printed under the \a tick coordinate. If a textual number is returned, it should respect the provided \a locale, \a formatChar and \a precision. - + If the returned value contains exponentials of the form "2e5" and beautifully typeset powers is enabled in the QCPAxis number format (\ref QCPAxis::setNumberFormat), the exponential part will be formatted accordingly using multiplication symbol and superscript during rendering of the @@ -6300,10 +6300,10 @@ QString QCPAxisTicker::getTickLabel(double tick, const QLocale &locale, QChar fo } /*! \internal - + Returns a vector containing all coordinates of sub ticks that should be drawn. It generates \a subTickCount sub ticks between each tick pair given in \a ticks. - + If a QCPAxisTicker subclass needs maximal control over the generated sub ticks, it should reimplement this method. Depending on the purpose of the subclass it doesn't necessarily need to base its result on \a subTickCount or \a ticks. @@ -6313,7 +6313,7 @@ QVector QCPAxisTicker::createSubTickVector(int subTickCount, const QVect QVector result; if (subTickCount <= 0 || ticks.size() < 2) return result; - + result.reserve((ticks.size()-1)*subTickCount); for (int i=1; i QCPAxisTicker::createSubTickVector(int subTickCount, const QVect } /*! \internal - + Returns a vector containing all coordinates of ticks that should be drawn. The default implementation generates ticks with a spacing of \a tickStep (mathematically starting at the tick step origin, see \ref setTickOrigin) distributed over the passed \a range. - + In order for the axis ticker to generate proper sub ticks, it is necessary that the first and last tick coordinates returned by this method are just below/above the provided \a range. Otherwise the outer intervals won't contain any sub ticks. - + If a QCPAxisTicker subclass needs maximal control over the generated ticks, it should reimplement this method. Depending on the purpose of the subclass it doesn't necessarily need to base its result on \a tickStep, e.g. when the ticks are spaced unequally like in the case of @@ -6354,11 +6354,11 @@ QVector QCPAxisTicker::createTickVector(double tickStep, const QCPRange } /*! \internal - + Returns a vector containing all tick label strings corresponding to the tick coordinates provided in \a ticks. The default implementation calls \ref getTickLabel to generate the respective strings. - + It is possible but uncommon for QCPAxisTicker subclasses to reimplement this method, as reimplementing \ref getTickLabel often achieves the intended result easier. */ @@ -6372,10 +6372,10 @@ QVector QCPAxisTicker::createLabelVector(const QVector &ticks, } /*! \internal - + Removes tick coordinates from \a ticks which lie outside the specified \a range. If \a keepOneOutlier is true, it preserves one tick just outside the range on both sides, if present. - + The passed \a ticks must be sorted in ascending order. */ void QCPAxisTicker::trimTicks(const QCPRange &range, QVector &ticks, bool keepOneOutlier) const @@ -6384,7 +6384,7 @@ void QCPAxisTicker::trimTicks(const QCPRange &range, QVector &ticks, boo bool highFound = false; int lowIndex = 0; int highIndex = -1; - + for (int i=0; i < ticks.size(); ++i) { if (ticks.at(i) >= range.lower) @@ -6403,7 +6403,7 @@ void QCPAxisTicker::trimTicks(const QCPRange &range, QVector &ticks, boo break; } } - + if (highFound && lowFound) { int trimFront = qMax(0, lowIndex-(keepOneOutlier ? 1 : 0)); @@ -6415,9 +6415,9 @@ void QCPAxisTicker::trimTicks(const QCPRange &range, QVector &ticks, boo } /*! \internal - + Returns the coordinate contained in \a candidates which is closest to the provided \a target. - + This method assumes \a candidates is not empty and sorted in ascending order. */ double QCPAxisTicker::pickClosest(double target, const QVector &candidates) const @@ -6434,10 +6434,10 @@ double QCPAxisTicker::pickClosest(double target, const QVector &candidat } /*! \internal - + Returns the decimal mantissa of \a input. Optionally, if \a magnitude is not set to zero, it also returns the magnitude of \a input as a power of 10. - + For example, an input of 142.6 will return a mantissa of 1.426 and a magnitude of 100. */ double QCPAxisTicker::getMantissa(double input, double *magnitude) const @@ -6448,7 +6448,7 @@ double QCPAxisTicker::getMantissa(double input, double *magnitude) const } /*! \internal - + Returns a number that is close to \a input but has a clean, easier human readable mantissa. How strongly the mantissa is altered, and thus how strong the result deviates from the original \a input, depends on the current tick step strategy (see \ref setTickStepStrategy). @@ -6485,9 +6485,9 @@ double QCPAxisTicker::cleanMantissa(double input) const //////////////////////////////////////////////////////////////////////////////////////////////////// /*! \class QCPAxisTickerDateTime \brief Specialized axis ticker for calendar dates and times as axis ticks - + \image html axisticker-datetime.png - + This QCPAxisTicker subclass generates ticks that correspond to real calendar dates and times. The plot axis coordinate is interpreted as Unix Time, so seconds since Epoch (January 1, 1970, 00:00 UTC). This is also used for example by QDateTime in the toTime_t()/setTime_t() methods @@ -6495,26 +6495,26 @@ double QCPAxisTicker::cleanMantissa(double input) const by using QDateTime::fromMSecsSinceEpoch()/1000.0. The static methods \ref dateTimeToKey and \ref keyToDateTime conveniently perform this conversion achieving a precision of one millisecond on all Qt versions. - + The format of the date/time display in the tick labels is controlled with \ref setDateTimeFormat. If a different time spec or time zone shall be used for the tick label appearance, see \ref setDateTimeSpec or \ref setTimeZone, respectively. - + This ticker produces unequal tick spacing in order to provide intuitive date and time-of-day ticks. For example, if the axis range spans a few years such that there is one tick per year, ticks will be positioned on 1. January of every year. This is intuitive but, due to leap years, will result in slightly unequal tick intervals (visually unnoticeable). The same can be seen in the image above: even though the number of days varies month by month, this ticker generates ticks on the same day of each month. - + If you would like to change the date/time that is used as a (mathematical) starting date for the ticks, use the \ref setTickOrigin(const QDateTime &origin) method overload, which takes a QDateTime. If you pass 15. July, 9:45 to this method, the yearly ticks will end up on 15. July at 9:45 of every year. - + The ticker can be created and assigned to an axis like this: \snippet documentation/doc-image-generator/mainwindow.cpp axistickerdatetime-creation - + \note If you rather wish to display relative times in terms of days, hours, minutes, seconds and milliseconds, and are not interested in the intricacies of real calendar dates with months and (leap) years, have a look at QCPAxisTickerTime instead. @@ -6535,7 +6535,7 @@ QCPAxisTickerDateTime::QCPAxisTickerDateTime() : /*! Sets the format in which dates and times are displayed as tick labels. For details about the \a format string, see the documentation of QDateTime::toString(). - + Typical expressions are @@ -6562,11 +6562,11 @@ QCPAxisTickerDateTime::QCPAxisTickerDateTime() :
\c dThe day as a number without a leading zero (1 to 31)
\c ap or \c aUse am/pm display. a/ap will be replaced by a lower-case version of either QLocale::amText() or QLocale::pmText().
\c tThe timezone (for example "CEST")
- + Newlines can be inserted with \c "\n", literal strings (even when containing above expressions) by encapsulating them using single-quotes. A literal single quote can be generated by using two consecutive single quotes in the format. - + \see setDateTimeSpec, setTimeZone */ void QCPAxisTickerDateTime::setDateTimeFormat(const QString &format) @@ -6580,11 +6580,11 @@ void QCPAxisTickerDateTime::setDateTimeFormat(const QString &format) The default value of QDateTime objects (and also QCPAxisTickerDateTime) is Qt::LocalTime. However, if the displayed tick labels shall be given in UTC, set \a spec to Qt::UTC. - + Tick labels corresponding to other time zones can be achieved with \ref setTimeZone (which sets \a spec to \c Qt::TimeZone internally). Note that if \a spec is afterwards set to not be \c Qt::TimeZone again, the \ref setTimeZone setting will be ignored accordingly. - + \see setDateTimeFormat, setTimeZone */ void QCPAxisTickerDateTime::setDateTimeSpec(Qt::TimeSpec spec) @@ -6596,7 +6596,7 @@ void QCPAxisTickerDateTime::setDateTimeSpec(Qt::TimeSpec spec) /*! Sets the time zone that is used for creating the tick labels from corresponding dates/times. The time spec (\ref setDateTimeSpec) is set to \c Qt::TimeZone. - + \see setDateTimeFormat, setTimeZone */ void QCPAxisTickerDateTime::setTimeZone(const QTimeZone &zone) @@ -6610,7 +6610,7 @@ void QCPAxisTickerDateTime::setTimeZone(const QTimeZone &zone) Sets the tick origin (see \ref QCPAxisTicker::setTickOrigin) in seconds since Epoch (1. Jan 1970, 00:00 UTC). For the date time ticker it might be more intuitive to use the overload which directly takes a QDateTime, see \ref setTickOrigin(const QDateTime &origin). - + This is useful to define the month/day/time recurring at greater tick interval steps. For example, If you pass 15. July, 9:45 to this method and the tick interval happens to be one tick per year, the ticks will end up on 15. July at 9:45 of every year. @@ -6622,7 +6622,7 @@ void QCPAxisTickerDateTime::setTickOrigin(double origin) /*! Sets the tick origin (see \ref QCPAxisTicker::setTickOrigin) as a QDateTime \a origin. - + This is useful to define the month/day/time recurring at greater tick interval steps. For example, If you pass 15. July, 9:45 to this method and the tick interval happens to be one tick per year, the ticks will end up on 15. July at 9:45 of every year. @@ -6633,22 +6633,22 @@ void QCPAxisTickerDateTime::setTickOrigin(const QDateTime &origin) } /*! \internal - + Returns a sensible tick step with intervals appropriate for a date-time-display, such as weekly, monthly, bi-monthly, etc. - + Note that this tick step isn't used exactly when generating the tick vector in \ref createTickVector, but only as a guiding value requiring some correction for each individual tick interval. Otherwise this would lead to unintuitive date displays, e.g. jumping between first day in the month to the last day in the previous month from tick to tick, due to the non-uniform length of months. The same problem arises with leap years. - + \seebaseclassmethod */ double QCPAxisTickerDateTime::getTickStep(const QCPRange &range) { double result = range.size()/double(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers - + mDateStrategy = dsNone; // leaving it at dsNone means tick coordinates will not be tuned in any special way in createTickVector if (result < 1) // ideal tick step is below 1 second -> use normal clean mantissa algorithm in units of seconds { @@ -6673,10 +6673,10 @@ double QCPAxisTickerDateTime::getTickStep(const QCPRange &range) } /*! \internal - + Returns a sensible sub tick count with intervals appropriate for a date-time-display, such as weekly, monthly, bi-monthly, etc. - + \seebaseclassmethod */ int QCPAxisTickerDateTime::getSubTickCount(double tickStep) @@ -6708,11 +6708,11 @@ int QCPAxisTickerDateTime::getSubTickCount(double tickStep) } /*! \internal - + Generates a date/time tick label for tick coordinate \a tick, based on the currently set format (\ref setDateTimeFormat), time spec (\ref setDateTimeSpec), and possibly time zone (\ref setTimeZone). - + \seebaseclassmethod */ QString QCPAxisTickerDateTime::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) @@ -6723,17 +6723,28 @@ QString QCPAxisTickerDateTime::getTickLabel(double tick, const QLocale &locale, if (mDateTimeSpec == Qt::TimeZone) return locale.toString(keyToDateTime(tick).toTimeZone(mTimeZone), mDateTimeFormat); else +// EdgeTX patch until upstream solution available +// Suppresses compiler Qt depeciation warnings +// Will break at Qt6.9 if TimeSpec is obsolete as planned +# if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) + if (mDateTimeSpec == Qt::LocalTime) + return locale.toString(keyToDateTime(tick).toTimeZone(QTimeZone::LocalTime), mDateTimeFormat); + else + return locale.toString(keyToDateTime(tick).toTimeZone(QTimeZone::UTC), mDateTimeFormat); +// End EdgeTX patch until upstream solution available +# else return locale.toString(keyToDateTime(tick).toTimeSpec(mDateTimeSpec), mDateTimeFormat); +# endif # else return locale.toString(keyToDateTime(tick).toTimeSpec(mDateTimeSpec), mDateTimeFormat); # endif } /*! \internal - + Uses the passed \a tickStep as a guiding value and applies corrections in order to obtain non-uniform tick intervals but intuitive tick labels, e.g. falling on the same day of each month. - + \seebaseclassmethod */ QVector QCPAxisTickerDateTime::createTickVector(double tickStep, const QCPRange &range) @@ -6775,10 +6786,10 @@ QVector QCPAxisTickerDateTime::createTickVector(double tickStep, const Q /*! A convenience method which turns \a key (in seconds since Epoch 1. Jan 1970, 00:00 UTC) into a QDateTime object. This can be used to turn axis coordinates to actual QDateTimes. - + The accuracy achieved by this method is one millisecond, irrespective of the used Qt version (it works around the lack of a QDateTime::fromMSecsSinceEpoch in Qt 4.6) - + \see dateTimeToKey */ QDateTime QCPAxisTickerDateTime::keyToDateTime(double key) @@ -6791,14 +6802,14 @@ QDateTime QCPAxisTickerDateTime::keyToDateTime(double key) } /*! \overload - + A convenience method which turns a QDateTime object into a double value that corresponds to seconds since Epoch (1. Jan 1970, 00:00 UTC). This is the format used as axis coordinates by QCPAxisTickerDateTime. - + The accuracy achieved by this method is one millisecond, irrespective of the used Qt version (it works around the lack of a QDateTime::toMSecsSinceEpoch in Qt 4.6) - + \see keyToDateTime */ double QCPAxisTickerDateTime::dateTimeToKey(const QDateTime &dateTime) @@ -6811,14 +6822,14 @@ double QCPAxisTickerDateTime::dateTimeToKey(const QDateTime &dateTime) } /*! \overload - + A convenience method which turns a QDate object into a double value that corresponds to seconds since Epoch (1. Jan 1970, 00:00 UTC). This is the format used as axis coordinates by QCPAxisTickerDateTime. - + The returned value will be the start of the passed day of \a date, interpreted in the given \a timeSpec. - + \see keyToDateTime */ double QCPAxisTickerDateTime::dateTimeToKey(const QDate &date, Qt::TimeSpec timeSpec) @@ -6827,8 +6838,17 @@ double QCPAxisTickerDateTime::dateTimeToKey(const QDate &date, Qt::TimeSpec time return QDateTime(date, QTime(0, 0), timeSpec).toTime_t(); # elif QT_VERSION < QT_VERSION_CHECK(5, 14, 0) return QDateTime(date, QTime(0, 0), timeSpec).toMSecsSinceEpoch()/1000.0; -# else +// EdgeTX patch until upstream solution available +// Suppresses compiler Qt depeciation warnings +// Will break at Qt6.9 if TimeSpec is obsolete as planned +# elif QT_VERSION < QT_VERSION_CHECK(6, 5, 0) return date.startOfDay(timeSpec).toMSecsSinceEpoch()/1000.0; +# else + if (timeSpec == Qt::LocalTime) + return date.startOfDay(QTimeZone::LocalTime).toMSecsSinceEpoch()/1000.0; + else + return date.startOfDay(QTimeZone::UTC).toMSecsSinceEpoch()/1000.0; +// EdgeTX patch until upstream solution available # endif } /* end of 'src/axis/axistickerdatetime.cpp' */ @@ -6842,16 +6862,16 @@ double QCPAxisTickerDateTime::dateTimeToKey(const QDate &date, Qt::TimeSpec time //////////////////////////////////////////////////////////////////////////////////////////////////// /*! \class QCPAxisTickerTime \brief Specialized axis ticker for time spans in units of milliseconds to days - + \image html axisticker-time.png - + This QCPAxisTicker subclass generates ticks that corresponds to time intervals. - + The format of the time display in the tick labels is controlled with \ref setTimeFormat and \ref setFieldWidth. The time coordinate is in the unit of seconds with respect to the time coordinate zero. Unlike with QCPAxisTickerDateTime, the ticks don't correspond to a specific calendar date and time. - + The time can be displayed in milliseconds, seconds, minutes, hours and days. Depending on the largest available unit in the format specified with \ref setTimeFormat, any time spans above will be carried in that largest unit. So for example if the format string is "%m:%s" and a tick at @@ -6859,19 +6879,19 @@ double QCPAxisTickerDateTime::dateTimeToKey(const QDate &date, Qt::TimeSpec time label will show "130:15" (130 minutes, 15 seconds). If the format string is "%h:%m:%s", the hour unit will be used and the label will thus be "02:10:15". Negative times with respect to the axis zero will carry a leading minus sign. - + The ticker can be created and assigned to an axis like this: \snippet documentation/doc-image-generator/mainwindow.cpp axistickertime-creation - + Here is an example of a time axis providing time information in days, hours and minutes. Due to the axis range spanning a few days and the wanted tick count (\ref setTickCount), the ticker decided to use tick steps of 12 hours: - + \image html axisticker-time2.png - + The format string for this example is \snippet documentation/doc-image-generator/mainwindow.cpp axistickertime-creation-2 - + \note If you rather wish to display calendar dates and times, have a look at QCPAxisTickerDateTime instead. */ @@ -6891,7 +6911,7 @@ QCPAxisTickerTime::QCPAxisTickerTime() : mFieldWidth[tuMinutes] = 2; mFieldWidth[tuHours] = 2; mFieldWidth[tuDays] = 1; - + mFormatPattern[tuMilliseconds] = QLatin1String("%z"); mFormatPattern[tuSeconds] = QLatin1String("%s"); mFormatPattern[tuMinutes] = QLatin1String("%m"); @@ -6901,16 +6921,16 @@ QCPAxisTickerTime::QCPAxisTickerTime() : /*! Sets the format that will be used to display time in the tick labels. - + The available patterns are: - %%z for milliseconds - %%s for seconds - %%m for minutes - %%h for hours - %%d for days - + The field width (zero padding) can be controlled for each unit with \ref setFieldWidth. - + The largest unit that appears in \a format will carry all the remaining time of a certain tick coordinate, even if it overflows the natural limit of the unit. For example, if %%m is the largest unit it might become larger than 59 in order to consume larger time values. If on the @@ -6920,7 +6940,7 @@ QCPAxisTickerTime::QCPAxisTickerTime() : void QCPAxisTickerTime::setTimeFormat(const QString &format) { mTimeFormat = format; - + // determine smallest and biggest unit in format, to optimize unit replacement and allow biggest // unit to consume remaining time of a tick value and grow beyond its modulo (e.g. min > 59) mSmallestUnit = tuMilliseconds; @@ -6945,7 +6965,7 @@ void QCPAxisTickerTime::setTimeFormat(const QString &format) Sets the field widh of the specified \a unit to be \a width digits, when displayed in the tick label. If the number for the specific unit is shorter than \a width, it will be padded with an according number of zeros to the left in order to reach the field width. - + \see setTimeFormat */ void QCPAxisTickerTime::setFieldWidth(QCPAxisTickerTime::TimeUnit unit, int width) @@ -6959,13 +6979,13 @@ void QCPAxisTickerTime::setFieldWidth(QCPAxisTickerTime::TimeUnit unit, int widt smallest available time unit in the current format (\ref setTimeFormat). For example if the unit of seconds isn't available in the format, this method will not generate steps (like 2.5 minutes) that require sub-minute precision to be displayed correctly. - + \seebaseclassmethod */ double QCPAxisTickerTime::getTickStep(const QCPRange &range) { double result = range.size()/double(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers - + if (result < 1) // ideal tick step is below 1 second -> use normal clean mantissa algorithm in units of seconds { if (mSmallestUnit == tuMilliseconds) @@ -7010,7 +7030,7 @@ double QCPAxisTickerTime::getTickStep(const QCPRange &range) /*! \internal Returns the sub tick count appropriate for the provided \a tickStep and time displays. - + \seebaseclassmethod */ int QCPAxisTickerTime::getSubTickCount(double tickStep) @@ -7033,10 +7053,10 @@ int QCPAxisTickerTime::getSubTickCount(double tickStep) } /*! \internal - + Returns the tick label corresponding to the provided \a tick and the configured format and field widths (\ref setTimeFormat, \ref setFieldWidth). - + \seebaseclassmethod */ QString QCPAxisTickerTime::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) @@ -7048,14 +7068,14 @@ QString QCPAxisTickerTime::getTickLabel(double tick, const QLocale &locale, QCha if (negative) tick *= -1; double values[tuDays+1]; // contains the msec/sec/min/... value with its respective modulo (e.g. minute 0..59) double restValues[tuDays+1]; // contains the msec/sec/min/... value as if it's the largest available unit and thus consumes the remaining time - + restValues[tuMilliseconds] = tick*1000; values[tuMilliseconds] = modf(restValues[tuMilliseconds]/1000, &restValues[tuSeconds])*1000; values[tuSeconds] = modf(restValues[tuSeconds]/60, &restValues[tuMinutes])*60; values[tuMinutes] = modf(restValues[tuMinutes]/60, &restValues[tuHours])*60; values[tuHours] = modf(restValues[tuHours]/24, &restValues[tuDays])*24; // no need to set values[tuDays] because days are always a rest value (there is no higher unit so it consumes all remaining time) - + QString result = mTimeFormat; for (int i = mSmallestUnit; i <= mBiggestUnit; ++i) { @@ -7068,7 +7088,7 @@ QString QCPAxisTickerTime::getTickLabel(double tick, const QLocale &locale, QCha } /*! \internal - + Replaces all occurrences of the format pattern belonging to \a unit in \a text with the specified \a value, using the field width as specified with \ref setFieldWidth for the \a unit. */ @@ -7077,7 +7097,7 @@ void QCPAxisTickerTime::replaceUnit(QString &text, QCPAxisTickerTime::TimeUnit u QString valueStr = QString::number(value); while (valueStr.size() < mFieldWidth.value(unit)) valueStr.prepend(QLatin1Char('0')); - + text.replace(mFormatPattern.value(unit), valueStr); } /* end of 'src/axis/axistickertime.cpp' */ @@ -7091,20 +7111,20 @@ void QCPAxisTickerTime::replaceUnit(QString &text, QCPAxisTickerTime::TimeUnit u //////////////////////////////////////////////////////////////////////////////////////////////////// /*! \class QCPAxisTickerFixed \brief Specialized axis ticker with a fixed tick step - + \image html axisticker-fixed.png - + This QCPAxisTicker subclass generates ticks with a fixed tick step set with \ref setTickStep. It is also possible to allow integer multiples and integer powers of the specified tick step with \ref setScaleStrategy. - + A typical application of this ticker is to make an axis only display integers, by setting the tick step of the ticker to 1.0 and the scale strategy to \ref ssMultiples. - + Another case is when a certain number has a special meaning and axis ticks should only appear at multiples of that value. In this case you might also want to consider \ref QCPAxisTickerPi because despite the name it is not limited to only pi symbols/values. - + The ticker can be created and assigned to an axis like this: \snippet documentation/doc-image-generator/mainwindow.cpp axistickerfixed-creation */ @@ -7121,7 +7141,7 @@ QCPAxisTickerFixed::QCPAxisTickerFixed() : /*! Sets the fixed tick interval to \a step. - + The axis ticker will only use this tick step when generating axis ticks. This might cause a very high tick density and overlapping labels if the axis range is zoomed out. Using \ref setScaleStrategy it is possible to relax the fixed step and also allow multiples or powers of \a @@ -7140,7 +7160,7 @@ void QCPAxisTickerFixed::setTickStep(double step) Sets whether the specified tick step (\ref setTickStep) is absolutely fixed or whether modifications may be applied to it before calculating the finally used tick step, such as permitting multiples or powers. See \ref ScaleStrategy for details. - + The default strategy is \ref ssNone, which means the tick step is absolutely fixed. */ void QCPAxisTickerFixed::setScaleStrategy(QCPAxisTickerFixed::ScaleStrategy strategy) @@ -7149,13 +7169,13 @@ void QCPAxisTickerFixed::setScaleStrategy(QCPAxisTickerFixed::ScaleStrategy stra } /*! \internal - + Determines the actually used tick step from the specified tick step and scale strategy (\ref setTickStep, \ref setScaleStrategy). - + This method either returns the specified tick step exactly, or, if the scale strategy is not \ref ssNone, a modification of it to allow varying the number of ticks in the current axis range. - + \seebaseclassmethod */ double QCPAxisTickerFixed::getTickStep(const QCPRange &range) @@ -7193,20 +7213,20 @@ double QCPAxisTickerFixed::getTickStep(const QCPRange &range) //////////////////////////////////////////////////////////////////////////////////////////////////// /*! \class QCPAxisTickerText \brief Specialized axis ticker which allows arbitrary labels at specified coordinates - + \image html axisticker-text.png - + This QCPAxisTicker subclass generates ticks which can be directly specified by the user as coordinates and associated strings. They can be passed as a whole with \ref setTicks or one at a time with \ref addTick. Alternatively you can directly access the internal storage via \ref ticks and modify the tick/label data there. - + This is useful for cases where the axis represents categories rather than numerical values. - + If you are updating the ticks of this ticker regularly and in a dynamic fasion (e.g. dependent on the axis range), it is a sign that you should probably create an own ticker by subclassing QCPAxisTicker, instead of using this one. - + The ticker can be created and assigned to an axis like this: \snippet documentation/doc-image-generator/mainwindow.cpp axistickertext-creation */ @@ -7214,7 +7234,7 @@ double QCPAxisTickerFixed::getTickStep(const QCPRange &range) /* start of documentation of inline functions */ /*! \fn QMap &QCPAxisTickerText::ticks() - + Returns a non-const reference to the internal map which stores the tick coordinates and their labels. @@ -7234,13 +7254,13 @@ QCPAxisTickerText::QCPAxisTickerText() : } /*! \overload - + Sets the ticks that shall appear on the axis. The map key of \a ticks corresponds to the axis coordinate, and the map value is the string that will appear as tick label. - + An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks getter. - + \see addTicks, addTick, clear */ void QCPAxisTickerText::setTicks(const QMap &ticks) @@ -7249,11 +7269,11 @@ void QCPAxisTickerText::setTicks(const QMap &ticks) } /*! \overload - + Sets the ticks that shall appear on the axis. The entries of \a positions correspond to the axis coordinates, and the entries of \a labels are the respective strings that will appear as tick labels. - + \see addTicks, addTick, clear */ void QCPAxisTickerText::setTicks(const QVector &positions, const QVector &labels) @@ -7277,10 +7297,10 @@ void QCPAxisTickerText::setSubTickCount(int subTicks) /*! Clears all ticks. - + An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks getter. - + \see setTicks, addTicks, addTick */ void QCPAxisTickerText::clear() @@ -7291,7 +7311,7 @@ void QCPAxisTickerText::clear() /*! Adds a single tick to the axis at the given axis coordinate \a position, with the provided tick \a label. - + \see addTicks, setTicks, clear */ void QCPAxisTickerText::addTick(double position, const QString &label) @@ -7300,13 +7320,13 @@ void QCPAxisTickerText::addTick(double position, const QString &label) } /*! \overload - + Adds the provided \a ticks to the ones already existing. The map key of \a ticks corresponds to the axis coordinate, and the map value is the string that will appear as tick label. - + An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks getter. - + \see addTick, setTicks, clear */ void QCPAxisTickerText::addTicks(const QMap &ticks) @@ -7319,14 +7339,14 @@ void QCPAxisTickerText::addTicks(const QMap &ticks) } /*! \overload - + Adds the provided ticks to the ones already existing. The entries of \a positions correspond to the axis coordinates, and the entries of \a labels are the respective strings that will appear as tick labels. - + An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks getter. - + \see addTick, setTicks, clear */ void QCPAxisTickerText::addTicks(const QVector &positions, const QVector &labels) @@ -7340,7 +7360,7 @@ void QCPAxisTickerText::addTicks(const QVector &positions, const QVector /*! Since the tick coordinates are provided externally, this method implementation does nothing. - + \seebaseclassmethod */ double QCPAxisTickerText::getTickStep(const QCPRange &range) @@ -7352,7 +7372,7 @@ double QCPAxisTickerText::getTickStep(const QCPRange &range) /*! Returns the sub tick count that was configured with \ref setSubTickCount. - + \seebaseclassmethod */ int QCPAxisTickerText::getSubTickCount(double tickStep) @@ -7364,7 +7384,7 @@ int QCPAxisTickerText::getSubTickCount(double tickStep) /*! Returns the tick label which corresponds to the key \a tick in the internal tick storage. Since the labels are provided externally, \a locale, \a formatChar, and \a precision are ignored. - + \seebaseclassmethod */ QString QCPAxisTickerText::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) @@ -7379,7 +7399,7 @@ QString QCPAxisTickerText::getTickLabel(double tick, const QLocale &locale, QCha Returns the externally provided tick coordinates which are in the specified \a range. If available, one tick above and below the range is provided in addition, to allow possible sub tick calculation. The parameter \a tickStep is ignored. - + \seebaseclassmethod */ QVector QCPAxisTickerText::createTickVector(double tickStep, const QCPRange &range) @@ -7388,7 +7408,7 @@ QVector QCPAxisTickerText::createTickVector(double tickStep, const QCPRa QVector result; if (mTicks.isEmpty()) return result; - + QMap::const_iterator start = mTicks.lowerBound(range.lower); QMap::const_iterator end = mTicks.upperBound(range.upper); // this method should try to give one tick outside of range so proper subticks can be generated: @@ -7396,7 +7416,7 @@ QVector QCPAxisTickerText::createTickVector(double tickStep, const QCPRa if (end != mTicks.constEnd()) ++end; for (QMap::const_iterator it = start; it != end; ++it) result.append(it.key()); - + return result; } /* end of 'src/axis/axistickertext.cpp' */ @@ -7410,16 +7430,16 @@ QVector QCPAxisTickerText::createTickVector(double tickStep, const QCPRa //////////////////////////////////////////////////////////////////////////////////////////////////// /*! \class QCPAxisTickerPi \brief Specialized axis ticker to display ticks in units of an arbitrary constant, for example pi - + \image html axisticker-pi.png - + This QCPAxisTicker subclass generates ticks that are expressed with respect to a given symbolic constant with a numerical value specified with \ref setPiValue and an appearance in the tick labels specified with \ref setPiSymbol. - + Ticks may be generated at fractions of the symbolic constant. How these fractions appear in the tick label can be configured with \ref setFractionStyle. - + The ticker can be created and assigned to an axis like this: \snippet documentation/doc-image-generator/mainwindow.cpp axistickerpi-creation */ @@ -7441,7 +7461,7 @@ QCPAxisTickerPi::QCPAxisTickerPi() : /*! Sets how the symbol part (which is always a suffix to the number) shall appear in the axis tick label. - + If a space shall appear between the number and the symbol, make sure the space is contained in \a symbol. */ @@ -7464,9 +7484,9 @@ void QCPAxisTickerPi::setPiValue(double pi) /*! Sets whether the axis labels shall appear periodicly and if so, at which multiplicity of the symbolic constant. - + To disable periodicity, set \a multiplesOfPi to zero. - + For example, an axis that identifies 0 with 2pi would set \a multiplesOfPi to two. */ void QCPAxisTickerPi::setPeriodicity(int multiplesOfPi) @@ -7484,11 +7504,11 @@ void QCPAxisTickerPi::setFractionStyle(QCPAxisTickerPi::FractionStyle style) } /*! \internal - + Returns the tick step, using the constant's value (\ref setPiValue) as base unit. In consequence the numerical/fractional part preceding the symbolic constant is made to have a readable mantissa. - + \seebaseclassmethod */ double QCPAxisTickerPi::getTickStep(const QCPRange &range) @@ -7499,11 +7519,11 @@ double QCPAxisTickerPi::getTickStep(const QCPRange &range) } /*! \internal - + Returns the sub tick count, using the constant's value (\ref setPiValue) as base unit. In consequence the sub ticks divide the numerical/fractional part preceding the symbolic constant reasonably, and not the total tick coordinate. - + \seebaseclassmethod */ int QCPAxisTickerPi::getSubTickCount(double tickStep) @@ -7512,11 +7532,11 @@ int QCPAxisTickerPi::getSubTickCount(double tickStep) } /*! \internal - + Returns the tick label as a fractional/numerical part and a symbolic string as suffix. The formatting of the fraction is done according to the specified \ref setFractionStyle. The appended symbol is specified with \ref setPiSymbol. - + \seebaseclassmethod */ QString QCPAxisTickerPi::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) @@ -7524,7 +7544,7 @@ QString QCPAxisTickerPi::getTickLabel(double tick, const QLocale &locale, QChar double tickInPis = tick/mPiValue; if (mPeriodicity > 0) tickInPis = fmod(tickInPis, mPeriodicity); - + if (mFractionStyle != fsFloatingPoint && mPiTickStep > 0.09 && mPiTickStep < 50) { // simply construct fraction from decimal like 1.234 -> 1234/1000 and then simplify fraction, smaller digits are irrelevant due to mPiTickStep conditional above @@ -7549,7 +7569,7 @@ QString QCPAxisTickerPi::getTickLabel(double tick, const QLocale &locale, QChar } /*! \internal - + Takes the fraction given by \a numerator and \a denominator and modifies the values to make sure the fraction is in irreducible form, i.e. numerator and denominator don't share any common factors which could be cancelled. @@ -7558,7 +7578,7 @@ void QCPAxisTickerPi::simplifyFraction(int &numerator, int &denominator) const { if (numerator == 0 || denominator == 0) return; - + int num = numerator; int denom = denominator; while (denom != 0) // euclidean gcd algorithm @@ -7573,10 +7593,10 @@ void QCPAxisTickerPi::simplifyFraction(int &numerator, int &denominator) const } /*! \internal - + Takes the fraction given by \a numerator and \a denominator and returns a string representation. The result depends on the configured fraction style (\ref setFractionStyle). - + This method is used to format the numerical/fractional part when generating tick labels. It simplifies the passed fraction to an irreducible form using \ref simplifyFraction and factors out any integer parts of the fraction (e.g. "10/4" becomes "2 1/2"). @@ -7596,7 +7616,7 @@ QString QCPAxisTickerPi::fractionToString(int numerator, int denominator) const int sign = numerator*denominator < 0 ? -1 : 1; numerator = qAbs(numerator); denominator = qAbs(denominator); - + if (denominator == 1) { return QString::number(sign*numerator); @@ -7629,11 +7649,11 @@ QString QCPAxisTickerPi::fractionToString(int numerator, int denominator) const } /*! \internal - + Returns the unicode string representation of the fraction given by \a numerator and \a denominator. This is the representation used in \ref fractionToString when the fraction style (\ref setFractionStyle) is \ref fsUnicodeFractions. - + This method doesn't use the single-character common fractions but builds each fraction from a superscript unicode number, the unicode fraction character, and a subscript unicode number. */ @@ -7643,7 +7663,7 @@ QString QCPAxisTickerPi::unicodeFraction(int numerator, int denominator) const } /*! \internal - + Returns the unicode string representing \a number as superscript. This is used to build unicode fractions in \ref unicodeFraction. */ @@ -7651,7 +7671,7 @@ QString QCPAxisTickerPi::unicodeSuperscript(int number) const { if (number == 0) return QString(QChar(0x2070)); - + QString result; while (number > 0) { @@ -7669,7 +7689,7 @@ QString QCPAxisTickerPi::unicodeSuperscript(int number) const } /*! \internal - + Returns the unicode string representing \a number as subscript. This is used to build unicode fractions in \ref unicodeFraction. */ @@ -7677,7 +7697,7 @@ QString QCPAxisTickerPi::unicodeSubscript(int number) const { if (number == 0) return QString(QChar(0x2080)); - + QString result; while (number > 0) { @@ -7697,23 +7717,23 @@ QString QCPAxisTickerPi::unicodeSubscript(int number) const //////////////////////////////////////////////////////////////////////////////////////////////////// /*! \class QCPAxisTickerLog \brief Specialized axis ticker suited for logarithmic axes - + \image html axisticker-log.png - + This QCPAxisTicker subclass generates ticks with unequal tick intervals suited for logarithmic axis scales. The ticks are placed at powers of the specified log base (\ref setLogBase). - + Especially in the case of a log base equal to 10 (the default), it might be desirable to have tick labels in the form of powers of ten without mantissa display. To achieve this, set the number precision (\ref QCPAxis::setNumberPrecision) to zero and the number format (\ref QCPAxis::setNumberFormat) to scientific (exponential) display with beautifully typeset decimal powers, so a format string of "eb". This will result in the following axis tick labels: - + \image html axisticker-log-powers.png The ticker can be created and assigned to an axis like this: \snippet documentation/doc-image-generator/mainwindow.cpp axistickerlog-creation - + Note that the nature of logarithmic ticks imply that there exists a smallest possible tick step, corresponding to one multiplication by the log base. If the user zooms in further than that, no new ticks would appear, leading to very sparse or even no axis ticks on the axis. To prevent this @@ -7750,7 +7770,7 @@ void QCPAxisTickerLog::setLogBase(double base) Sets the number of sub ticks in a tick interval. Within each interval, the sub ticks are spaced linearly to provide a better visual guide, so the sub tick density increases toward the higher tick. - + Note that \a subTicks is the number of sub ticks (not sub intervals) in one tick interval. So in the case of logarithm base 10 an intuitive sub tick spacing would be achieved with eight sub ticks (the default). This means e.g. between the ticks 10 and 100 there will be eight ticks, @@ -7765,10 +7785,10 @@ void QCPAxisTickerLog::setSubTickCount(int subTicks) } /*! \internal - + Returns the sub tick count specified in \ref setSubTickCount. For QCPAxisTickerLog, there is no automatic sub tick count calculation necessary. - + \seebaseclassmethod */ int QCPAxisTickerLog::getSubTickCount(double tickStep) @@ -7778,7 +7798,7 @@ int QCPAxisTickerLog::getSubTickCount(double tickStep) } /*! \internal - + Creates ticks with a spacing given by the logarithm base and an increasing integer power in the provided \a range. The step in which the power increases tick by tick is chosen in order to keep the total number of ticks as close as possible to the tick count (\ref setTickCount). @@ -7786,7 +7806,7 @@ int QCPAxisTickerLog::getSubTickCount(double tickStep) The parameter \a tickStep is ignored for the normal logarithmic ticker generation. Only when zoomed in very far such that not enough logarithmically placed ticks would be visible, this function falls back to the regular QCPAxisTicker::createTickVector, which then uses \a tickStep. - + \seebaseclassmethod */ QVector QCPAxisTickerLog::createTickVector(double tickStep, const QCPRange &range) @@ -7824,7 +7844,7 @@ QVector QCPAxisTickerLog::createTickVector(double tickStep, const QCPRan { qDebug() << Q_FUNC_INFO << "Invalid range for logarithmic plot: " << range.lower << ".." << range.upper; } - + return result; } /* end of 'src/axis/axistickerlog.cpp' */ @@ -7840,11 +7860,11 @@ QVector QCPAxisTickerLog::createTickVector(double tickStep, const QCPRan /*! \class QCPGrid \brief Responsible for drawing the grid of a QCPAxis. - + This class is tightly bound to QCPAxis. Every axis owns a grid instance and uses it to draw the grid lines, sub grid lines and zero-line. You can interact with the grid of an axis via \ref QCPAxis::grid. Normally, you don't need to create an instance of QCPGrid yourself. - + The axis and grid drawing was split into two classes to allow them to be placed on different layers (both QCPAxis and QCPGrid inherit from QCPLayerable). Thus it is possible to have the grid in the background and the axes in the foreground, and any plottables/items in between. This @@ -7853,7 +7873,7 @@ QVector QCPAxisTickerLog::createTickVector(double tickStep, const QCPRan /*! Creates a QCPGrid instance and sets default values. - + You shouldn't instantiate grids on their own, since every QCPAxis brings its own QCPGrid. */ QCPGrid::QCPGrid(QCPAxis *parentAxis) : @@ -7876,7 +7896,7 @@ QCPGrid::QCPGrid(QCPAxis *parentAxis) : /*! Sets whether grid lines at sub tick marks are drawn. - + \see setSubGridPen */ void QCPGrid::setSubGridVisible(bool visible) @@ -7918,7 +7938,7 @@ void QCPGrid::setSubGridPen(const QPen &pen) /*! Sets the pen with which zero lines are drawn. - + Zero lines are lines at value coordinate 0 which may be drawn with a different pen than other grid lines. To disable zero lines and just draw normal grid lines at zero, set \a pen to Qt::NoPen. */ @@ -7933,11 +7953,11 @@ void QCPGrid::setZeroLinePen(const QPen &pen) before drawing the major grid lines. This is the antialiasing state the painter passed to the \ref draw method is in by default. - + This function takes into account the local setting of the antialiasing flag as well as the overrides set with \ref QCustomPlot::setAntialiasedElements and \ref QCustomPlot::setNotAntialiasedElements. - + \see setAntialiased */ void QCPGrid::applyDefaultAntialiasingHint(QCPPainter *painter) const @@ -7946,29 +7966,29 @@ void QCPGrid::applyDefaultAntialiasingHint(QCPPainter *painter) const } /*! \internal - + Draws grid lines and sub grid lines at the positions of (sub) ticks of the parent axis, spanning over the complete axis rect. Also draws the zero line, if appropriate (\ref setZeroLinePen). */ void QCPGrid::draw(QCPPainter *painter) { if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } - + if (mParentAxis->subTicks() && mSubGridVisible) drawSubGridLines(painter); drawGridLines(painter); } /*! \internal - + Draws the main grid lines and possibly a zero line with the specified painter. - + This is a helper function called by \ref draw. */ void QCPGrid::drawGridLines(QCPPainter *painter) const { if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } - + const int tickCount = mParentAxis->mTickVector.size(); double t; // helper variable, result of coordinate-to-pixel transforms if (mParentAxis->orientation() == Qt::Horizontal) @@ -8033,15 +8053,15 @@ void QCPGrid::drawGridLines(QCPPainter *painter) const } /*! \internal - + Draws the sub grid lines with the specified painter. - + This is a helper function called by \ref draw. */ void QCPGrid::drawSubGridLines(QCPPainter *painter) const { if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } - + applyAntialiasingHint(painter, mAntialiasedSubGrid, QCP::aeSubGrid); double t; // helper variable, result of coordinate-to-pixel transforms painter->setPen(mSubGridPen); @@ -8073,16 +8093,16 @@ void QCPGrid::drawSubGridLines(QCPPainter *painter) const Usually doesn't need to be instantiated externally. Access %QCustomPlot's default four axes via QCustomPlot::xAxis (bottom), QCustomPlot::yAxis (left), QCustomPlot::xAxis2 (top) and QCustomPlot::yAxis2 (right). - + Axes are always part of an axis rect, see QCPAxisRect. \image html AxisNamesOverview.png
Naming convention of axis parts
\n - + \image html AxisRectSpacingOverview.png
Overview of the spacings and paddings that define the geometry of an axis. The dashed gray line on the left represents the QCustomPlot widget border.
- + Each axis holds an instance of QCPAxisTicker which is used to generate the tick coordinates and tick labels. You can access the currently installed \ref ticker or set a new one (possibly one of the specialized subclasses, or your own subclass) via \ref setTicker. For details, see the @@ -8100,7 +8120,7 @@ void QCPGrid::drawSubGridLines(QCPPainter *painter) const */ /*! \fn QCPGrid *QCPAxis::grid() const - + Returns the \ref QCPGrid instance belonging to this axis. Access it to set details about the way the grid is displayed. */ @@ -8155,7 +8175,7 @@ void QCPGrid::drawSubGridLines(QCPPainter *painter) const This signal is emitted when the range of this axis has changed. You can connect it to the \ref setRange slot of another axis to communicate the new range to the other axis, in order for it to be synchronized. - + You may also manipulate/correct the range with \ref setRange in a slot connected to this signal. This is useful if for example a maximum range span shall not be exceeded, or if the lower/upper range shouldn't go beyond certain values (see \ref QCPRange::bounded). For example, the following @@ -8167,24 +8187,24 @@ void QCPGrid::drawSubGridLines(QCPPainter *painter) const /*! \fn void QCPAxis::rangeChanged(const QCPRange &newRange, const QCPRange &oldRange) \overload - + Additionally to the new range, this signal also provides the previous range held by the axis as \a oldRange. */ /*! \fn void QCPAxis::scaleTypeChanged(QCPAxis::ScaleType scaleType); - + This signal is emitted when the scale type changes, by calls to \ref setScaleType */ /*! \fn void QCPAxis::selectionChanged(QCPAxis::SelectableParts selection) - + This signal is emitted when the selection state of this axis has changed, either by user interaction or by a direct call to \ref setSelectedParts. */ /*! \fn void QCPAxis::selectableChanged(const QCPAxis::SelectableParts &parts); - + This signal is emitted when the selectability changes, by calls to \ref setSelectableParts */ @@ -8192,7 +8212,7 @@ void QCPGrid::drawSubGridLines(QCPPainter *painter) const /*! Constructs an Axis instance of Type \a type for the axis rect \a parent. - + Usually it isn't necessary to instantiate axes directly, because you can let QCustomPlot create them for you with \ref QCPAxisRect::addAxis. If you want to use own QCPAxis-subclasses however, create them manually and then inject them also via \ref QCPAxisRect::addAxis. @@ -8246,7 +8266,7 @@ QCPAxis::QCPAxis(QCPAxisRect *parent, AxisType type) : mGrid->setVisible(false); setAntialiased(false); setLayer(mParentPlot->currentLayer()); // it's actually on that layer already, but we want it in front of the grid, so we place it on there again - + if (type == atTop) { setTickLabelPadding(3); @@ -8354,16 +8374,16 @@ QCPLineEnding QCPAxis::upperEnding() const /*! Sets whether the axis uses a linear scale or a logarithmic scale. - + Note that this method controls the coordinate transformation. For logarithmic scales, you will likely also want to use a logarithmic tick spacing and labeling, which can be achieved by setting the axis ticker to an instance of \ref QCPAxisTickerLog : - + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpaxisticker-log-creation - + See the documentation of \ref QCPAxisTickerLog about the details of logarithmic axis tick creation. - + \ref setNumberPrecision */ void QCPAxis::setScaleType(QCPAxis::ScaleType type) @@ -8380,17 +8400,17 @@ void QCPAxis::setScaleType(QCPAxis::ScaleType type) /*! Sets the range of the axis. - + This slot may be connected with the \ref rangeChanged signal of another axis so this axis is always synchronized with the other axis range, when it changes. - + To invert the direction of an axis, use \ref setRangeReversed. */ void QCPAxis::setRange(const QCPRange &range) { if (range.lower == mRange.lower && range.upper == mRange.upper) return; - + if (!QCPRange::validRange(range)) return; QCPRange oldRange = mRange; if (mScaleType == stLogarithmic) @@ -8407,11 +8427,11 @@ void QCPAxis::setRange(const QCPRange &range) /*! Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface. (When \ref QCustomPlot::setInteractions contains iSelectAxes.) - + However, even when \a selectable is set to a value not allowing the selection of a specific part, it is still possible to set the selection of this part manually, by calling \ref setSelectedParts directly. - + \see SelectablePart, setSelectedParts */ void QCPAxis::setSelectableParts(const SelectableParts &selectable) @@ -8426,15 +8446,15 @@ void QCPAxis::setSelectableParts(const SelectableParts &selectable) /*! Sets the selected state of the respective axis parts described by \ref SelectablePart. When a part is selected, it uses a different pen/font. - + The entire selection mechanism for axes is handled automatically when \ref QCustomPlot::setInteractions contains iSelectAxes. You only need to call this function when you wish to change the selection state manually. - + This function can change the selection state of a part, independent of the \ref setSelectableParts setting. - + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. - + \see SelectablePart, setSelectableParts, selectTest, setSelectedBasePen, setSelectedTickPen, setSelectedSubTickPen, setSelectedTickLabelFont, setSelectedLabelFont, setSelectedTickLabelColor, setSelectedLabelColor */ @@ -8449,18 +8469,18 @@ void QCPAxis::setSelectedParts(const SelectableParts &selected) /*! \overload - + Sets the lower and upper bound of the axis range. - + To invert the direction of an axis, use \ref setRangeReversed. - + There is also a slot to set a range, see \ref setRange(const QCPRange &range). */ void QCPAxis::setRange(double lower, double upper) { if (lower == mRange.lower && upper == mRange.upper) return; - + if (!QCPRange::validRange(lower, upper)) return; QCPRange oldRange = mRange; mRange.lower = lower; @@ -8478,9 +8498,9 @@ void QCPAxis::setRange(double lower, double upper) /*! \overload - + Sets the range of the axis. - + The \a position coordinate indicates together with the \a alignment parameter, where the new range will be positioned. \a size defines the size of the new axis range. \a alignment may be Qt::AlignLeft, Qt::AlignRight or Qt::AlignCenter. This will cause the left border, right border, @@ -8505,7 +8525,7 @@ void QCPAxis::setRangeLower(double lower) { if (mRange.lower == lower) return; - + QCPRange oldRange = mRange; mRange.lower = lower; if (mScaleType == stLogarithmic) @@ -8527,7 +8547,7 @@ void QCPAxis::setRangeUpper(double upper) { if (mRange.upper == upper) return; - + QCPRange oldRange = mRange; mRange.upper = upper; if (mScaleType == stLogarithmic) @@ -8558,14 +8578,14 @@ void QCPAxis::setRangeReversed(bool reversed) /*! The axis ticker is responsible for generating the tick positions and tick labels. See the documentation of QCPAxisTicker for details on how to work with axis tickers. - + You can change the tick positioning/labeling behaviour of this axis by setting a different QCPAxisTicker subclass using this method. If you only wish to modify the currently installed axis ticker, access it via \ref ticker. - + Since the ticker is stored in the axis as a shared pointer, multiple axes may share the same axis ticker simply by passing the same shared pointer to multiple axes. - + \see ticker */ void QCPAxis::setTicker(QSharedPointer ticker) @@ -8582,7 +8602,7 @@ void QCPAxis::setTicker(QSharedPointer ticker) Note that setting \a show to false does not imply that tick labels are invisible, too. To achieve that, see \ref setTickLabels. - + \see setSubTicks */ void QCPAxis::setTicks(bool show) @@ -8623,7 +8643,7 @@ void QCPAxis::setTickLabelPadding(int padding) /*! Sets the font of the tick labels. - + \see setTickLabels, setTickLabelColor */ void QCPAxis::setTickLabelFont(const QFont &font) @@ -8637,7 +8657,7 @@ void QCPAxis::setTickLabelFont(const QFont &font) /*! Sets the color of the tick labels. - + \see setTickLabels, setTickLabelFont */ void QCPAxis::setTickLabelColor(const QColor &color) @@ -8649,7 +8669,7 @@ void QCPAxis::setTickLabelColor(const QColor &color) Sets the rotation of the tick labels. If \a degrees is zero, the labels are drawn normally. Else, the tick labels are drawn rotated by \a degrees clockwise. The specified angle is bound to values from -90 to 90 degrees. - + If \a degrees is exactly -90, 0 or 90, the tick labels are centered on the tick coordinate. For other angles, the label is drawn with an offset such that it seems to point toward or away from the tick mark. @@ -8665,7 +8685,7 @@ void QCPAxis::setTickLabelRotation(double degrees) /*! Sets whether the tick labels (numbers) shall appear inside or outside the axis rect. - + The usual and default setting is \ref lsOutside. Very compact plots sometimes require tick labels to be inside the axis rect, to save space. If \a side is set to \ref lsInside, the tick labels appear on the inside are additionally clipped to the axis rect. @@ -8680,7 +8700,7 @@ void QCPAxis::setTickLabelSide(LabelSide side) Sets the number format for the numbers in tick labels. This \a formatCode is an extended version of the format code used e.g. by QString::number() and QLocale::toString(). For reference about that, see the "Argument Formats" section in the detailed description of the QString class. - + \a formatCode is a string of one, two or three characters. The first character is identical to @@ -8698,7 +8718,7 @@ void QCPAxis::setTickLabelSide(LabelSide side) If instead a cross should be shown (as is usual in the USA), the third char of \a formatCode can be set to 'c'. The inserted multiplication signs are the UTF-8 characters 215 (0xD7) for the cross and 183 (0xB7) for the dot. - + Examples for \a formatCode: \li \c g normal format code behaviour. If number is small, fixed format is used, if number is large, normal scientific format is used @@ -8719,7 +8739,7 @@ void QCPAxis::setNumberFormat(const QString &formatCode) return; } mCachedMarginValid = false; - + // interpret first char as number format char: QString allowedFormatChars(QLatin1String("eEfgG")); if (allowedFormatChars.contains(formatCode.at(0))) @@ -8736,7 +8756,7 @@ void QCPAxis::setNumberFormat(const QString &formatCode) mAxisPainter->numberMultiplyCross = false; return; } - + // interpret second char as indicator for beautiful decimal powers: if (formatCode.at(1) == QLatin1Char('b') && (mNumberFormatChar == QLatin1Char('e') || mNumberFormatChar == QLatin1Char('g'))) { @@ -8751,7 +8771,7 @@ void QCPAxis::setNumberFormat(const QString &formatCode) mAxisPainter->numberMultiplyCross = false; return; } - + // interpret third char as indicator for dot or cross multiplication symbol: if (formatCode.at(2) == QLatin1Char('c')) { @@ -8785,7 +8805,7 @@ void QCPAxis::setNumberPrecision(int precision) plot and \a outside is the length they will reach outside the plot. If \a outside is greater than zero, the tick labels and axis label will increase their distance to the axis accordingly, so they won't collide with the ticks. - + \see setSubTickLength, setTickLengthIn, setTickLengthOut */ void QCPAxis::setTickLength(int inside, int outside) @@ -8797,7 +8817,7 @@ void QCPAxis::setTickLength(int inside, int outside) /*! Sets the length of the inward ticks in pixels. \a inside is the length the ticks will reach inside the plot. - + \see setTickLengthOut, setTickLength, setSubTickLength */ void QCPAxis::setTickLengthIn(int inside) @@ -8812,7 +8832,7 @@ void QCPAxis::setTickLengthIn(int inside) Sets the length of the outward ticks in pixels. \a outside is the length the ticks will reach outside the plot. If \a outside is greater than zero, the tick labels and axis label will increase their distance to the axis accordingly, so they won't collide with the ticks. - + \see setTickLengthIn, setTickLength, setSubTickLength */ void QCPAxis::setTickLengthOut(int outside) @@ -8826,9 +8846,9 @@ void QCPAxis::setTickLengthOut(int outside) /*! Sets whether sub tick marks are displayed. - + Sub ticks are only potentially visible if (major) ticks are also visible (see \ref setTicks) - + \see setTicks */ void QCPAxis::setSubTicks(bool show) @@ -8845,7 +8865,7 @@ void QCPAxis::setSubTicks(bool show) the plot and \a outside is the length they will reach outside the plot. If \a outside is greater than zero, the tick labels and axis label will increase their distance to the axis accordingly, so they won't collide with the ticks. - + \see setTickLength, setSubTickLengthIn, setSubTickLengthOut */ void QCPAxis::setSubTickLength(int inside, int outside) @@ -8857,7 +8877,7 @@ void QCPAxis::setSubTickLength(int inside, int outside) /*! Sets the length of the inward subticks in pixels. \a inside is the length the subticks will reach inside the plot. - + \see setSubTickLengthOut, setSubTickLength, setTickLength */ void QCPAxis::setSubTickLengthIn(int inside) @@ -8872,7 +8892,7 @@ void QCPAxis::setSubTickLengthIn(int inside) Sets the length of the outward subticks in pixels. \a outside is the length the subticks will reach outside the plot. If \a outside is greater than zero, the tick labels will increase their distance to the axis accordingly, so they won't collide with the ticks. - + \see setSubTickLengthIn, setSubTickLength, setTickLength */ void QCPAxis::setSubTickLengthOut(int outside) @@ -8886,7 +8906,7 @@ void QCPAxis::setSubTickLengthOut(int outside) /*! Sets the pen, the axis base line is drawn with. - + \see setTickPen, setSubTickPen */ void QCPAxis::setBasePen(const QPen &pen) @@ -8896,7 +8916,7 @@ void QCPAxis::setBasePen(const QPen &pen) /*! Sets the pen, tick marks will be drawn with. - + \see setTickLength, setBasePen */ void QCPAxis::setTickPen(const QPen &pen) @@ -8906,7 +8926,7 @@ void QCPAxis::setTickPen(const QPen &pen) /*! Sets the pen, subtick marks will be drawn with. - + \see setSubTickCount, setSubTickLength, setBasePen */ void QCPAxis::setSubTickPen(const QPen &pen) @@ -8916,7 +8936,7 @@ void QCPAxis::setSubTickPen(const QPen &pen) /*! Sets the font of the axis label. - + \see setLabelColor */ void QCPAxis::setLabelFont(const QFont &font) @@ -8930,7 +8950,7 @@ void QCPAxis::setLabelFont(const QFont &font) /*! Sets the color of the axis label. - + \see setLabelFont */ void QCPAxis::setLabelColor(const QColor &color) @@ -8953,7 +8973,7 @@ void QCPAxis::setLabel(const QString &str) /*! Sets the distance between the tick labels and the axis label. - + \see setTickLabelPadding, setPadding */ void QCPAxis::setLabelPadding(int padding) @@ -8970,9 +8990,9 @@ void QCPAxis::setLabelPadding(int padding) When \ref QCPAxisRect::setAutoMargins is enabled, the padding is the additional outer most space, that is left blank. - + The axis padding has no meaning if \ref QCPAxisRect::setAutoMargins is disabled. - + \see setLabelPadding, setTickLabelPadding */ void QCPAxis::setPadding(int padding) @@ -8986,7 +9006,7 @@ void QCPAxis::setPadding(int padding) /*! Sets the offset the axis has to its axis rect side. - + If an axis rect side has multiple axes and automatic margin calculation is enabled for that side, only the offset of the inner most axis has meaning (even if it is set to be invisible). The offset of the other, outer axes is controlled automatically, to place them at appropriate @@ -8999,7 +9019,7 @@ void QCPAxis::setOffset(int offset) /*! Sets the font that is used for tick labels when they are selected. - + \see setTickLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions */ void QCPAxis::setSelectedTickLabelFont(const QFont &font) @@ -9013,7 +9033,7 @@ void QCPAxis::setSelectedTickLabelFont(const QFont &font) /*! Sets the font that is used for the axis label when it is selected. - + \see setLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions */ void QCPAxis::setSelectedLabelFont(const QFont &font) @@ -9024,7 +9044,7 @@ void QCPAxis::setSelectedLabelFont(const QFont &font) /*! Sets the color that is used for tick labels when they are selected. - + \see setTickLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions */ void QCPAxis::setSelectedTickLabelColor(const QColor &color) @@ -9037,7 +9057,7 @@ void QCPAxis::setSelectedTickLabelColor(const QColor &color) /*! Sets the color that is used for the axis label when it is selected. - + \see setLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions */ void QCPAxis::setSelectedLabelColor(const QColor &color) @@ -9047,7 +9067,7 @@ void QCPAxis::setSelectedLabelColor(const QColor &color) /*! Sets the pen that is used to draw the axis base line when selected. - + \see setBasePen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions */ void QCPAxis::setSelectedBasePen(const QPen &pen) @@ -9057,7 +9077,7 @@ void QCPAxis::setSelectedBasePen(const QPen &pen) /*! Sets the pen that is used to draw the (major) ticks when selected. - + \see setTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions */ void QCPAxis::setSelectedTickPen(const QPen &pen) @@ -9067,7 +9087,7 @@ void QCPAxis::setSelectedTickPen(const QPen &pen) /*! Sets the pen that is used to draw the subticks when selected. - + \see setSubTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions */ void QCPAxis::setSelectedSubTickPen(const QPen &pen) @@ -9078,11 +9098,11 @@ void QCPAxis::setSelectedSubTickPen(const QPen &pen) /*! Sets the style for the lower axis ending. See the documentation of QCPLineEnding for available styles. - + For horizontal axes, this method refers to the left ending, for vertical axes the bottom ending. Note that this meaning does not change when the axis range is reversed with \ref setRangeReversed. - + \see setUpperEnding */ void QCPAxis::setLowerEnding(const QCPLineEnding &ending) @@ -9093,11 +9113,11 @@ void QCPAxis::setLowerEnding(const QCPLineEnding &ending) /*! Sets the style for the upper axis ending. See the documentation of QCPLineEnding for available styles. - + For horizontal axes, this method refers to the right ending, for vertical axes the top ending. Note that this meaning does not change when the axis range is reversed with \ref setRangeReversed. - + \see setLowerEnding */ void QCPAxis::setUpperEnding(const QCPLineEnding &ending) @@ -9108,7 +9128,7 @@ void QCPAxis::setUpperEnding(const QCPLineEnding &ending) /*! If the scale type (\ref setScaleType) is \ref stLinear, \a diff is added to the lower and upper bounds of the range. The range is simply moved by \a diff. - + If the scale type is \ref stLogarithmic, the range bounds are multiplied by \a diff. This corresponds to an apparent "linear" move in logarithmic scaling by a distance of log(diff). */ @@ -9193,17 +9213,17 @@ void QCPAxis::scaleRange(double factor, double center) void QCPAxis::setScaleRatio(const QCPAxis *otherAxis, double ratio) { int otherPixelSize, ownPixelSize; - + if (otherAxis->orientation() == Qt::Horizontal) otherPixelSize = otherAxis->axisRect()->width(); else otherPixelSize = otherAxis->axisRect()->height(); - + if (orientation() == Qt::Horizontal) ownPixelSize = axisRect()->width(); else ownPixelSize = axisRect()->height(); - + double newRangeSize = ratio*otherAxis->range().size()*ownPixelSize/double(otherPixelSize); setRange(range().center(), newRangeSize, Qt::AlignCenter); } @@ -9211,7 +9231,7 @@ void QCPAxis::setScaleRatio(const QCPAxis *otherAxis, double ratio) /*! Changes the axis range such that all plottables associated with this axis are fully visible in that dimension. - + \see QCPAbstractPlottable::rescaleAxes, QCustomPlot::rescaleAxes */ void QCPAxis::rescale(bool onlyVisiblePlottables) @@ -9353,16 +9373,16 @@ double QCPAxis::coordToPixel(double value) const Returns the part of the axis that is hit by \a pos (in pixels). The return value of this function is independent of the user-selectable parts defined with \ref setSelectableParts. Further, this function does not change the current selection state of the axis. - + If the axis is not visible (\ref setVisible), this function always returns \ref spNone. - + \see setSelectedParts, setSelectableParts, QCustomPlot::setInteractions */ QCPAxis::SelectablePart QCPAxis::getPartAt(const QPointF &pos) const { if (!mVisible) return spNone; - + if (mAxisPainter->axisSelectionBox().contains(pos.toPoint())) return spAxis; else if (mAxisPainter->tickLabelsSelectionBox().contains(pos.toPoint())) @@ -9380,7 +9400,7 @@ double QCPAxis::selectTest(const QPointF &pos, bool onlySelectable, QVariant *de SelectablePart part = getPartAt(pos); if ((onlySelectable && !mSelectableParts.testFlag(part)) || part == spNone) return -1; - + if (details) details->setValue(part); return mParentPlot->selectionTolerance()*0.99; @@ -9388,16 +9408,16 @@ double QCPAxis::selectTest(const QPointF &pos, bool onlySelectable, QVariant *de /*! Returns a list of all the plottables that have this axis as key or value axis. - + If you are only interested in plottables of type QCPGraph, see \ref graphs. - + \see graphs, items */ QList QCPAxis::plottables() const { QList result; if (!mParentPlot) return result; - + foreach (QCPAbstractPlottable *plottable, mParentPlot->mPlottables) { if (plottable->keyAxis() == this || plottable->valueAxis() == this) @@ -9408,14 +9428,14 @@ QList QCPAxis::plottables() const /*! Returns a list of all the graphs that have this axis as key or value axis. - + \see plottables, items */ QList QCPAxis::graphs() const { QList result; if (!mParentPlot) return result; - + foreach (QCPGraph *graph, mParentPlot->mGraphs) { if (graph->keyAxis() == this || graph->valueAxis() == this) @@ -9427,14 +9447,14 @@ QList QCPAxis::graphs() const /*! Returns a list of all the items that are associated with this axis. An item is considered associated with an axis if at least one of its positions uses the axis as key or value axis. - + \see plottables, graphs */ QList QCPAxis::items() const { QList result; if (!mParentPlot) return result; - + foreach (QCPAbstractItem *item, mParentPlot->mItems) { foreach (QCPItemPosition *position, item->positions()) @@ -9507,7 +9527,7 @@ void QCPAxis::deselectEvent(bool *selectionStateChanged) } /*! \internal - + This mouse event reimplementation provides the functionality to let the user drag individual axes exclusively, by startig the drag on top of the axis. @@ -9515,9 +9535,9 @@ void QCPAxis::deselectEvent(bool *selectionStateChanged) must be configured accordingly, i.e. it must allow range dragging in the orientation of this axis (\ref QCPAxisRect::setRangeDrag) and this axis must be a draggable axis (\ref QCPAxisRect::setRangeDragAxes) - + \seebaseclassmethod - + \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. */ @@ -9531,7 +9551,7 @@ void QCPAxis::mousePressEvent(QMouseEvent *event, const QVariant &details) event->ignore(); return; } - + if (event->buttons() & Qt::LeftButton) { mDragging = true; @@ -9548,15 +9568,15 @@ void QCPAxis::mousePressEvent(QMouseEvent *event, const QVariant &details) } /*! \internal - + This mouse event reimplementation provides the functionality to let the user drag individual axes exclusively, by startig the drag on top of the axis. - + \seebaseclassmethod - + \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. - + \see QCPAxis::mousePressEvent */ void QCPAxis::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) @@ -9574,7 +9594,7 @@ void QCPAxis::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) const double diff = pixelToCoord(startPixel) / pixelToCoord(currentPixel); setRange(mDragStartRange.lower*diff, mDragStartRange.upper*diff); } - + if (mParentPlot->noAntialiasingOnDrag()) mParentPlot->setNotAntialiasedElements(QCP::aeAll); mParentPlot->replot(QCustomPlot::rpQueuedReplot); @@ -9582,15 +9602,15 @@ void QCPAxis::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) } /*! \internal - + This mouse event reimplementation provides the functionality to let the user drag individual axes exclusively, by startig the drag on top of the axis. - + \seebaseclassmethod - + \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. - + \see QCPAxis::mousePressEvent */ void QCPAxis::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) @@ -9606,7 +9626,7 @@ void QCPAxis::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) } /*! \internal - + This mouse event reimplementation provides the functionality to let the user zoom individual axes exclusively, by performing the wheel event on top of the axis. @@ -9614,9 +9634,9 @@ void QCPAxis::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) must be configured accordingly, i.e. it must allow range zooming in the orientation of this axis (\ref QCPAxisRect::setRangeZoom) and this axis must be a zoomable axis (\ref QCPAxisRect::setRangeZoomAxes) - + \seebaseclassmethod - + \note The zooming of possibly multiple axes at once by performing the wheel event anywhere in the axis rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::wheelEvent. */ @@ -9630,19 +9650,19 @@ void QCPAxis::wheelEvent(QWheelEvent *event) event->ignore(); return; } - + #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) const double delta = event->delta(); #else const double delta = event->angleDelta().y(); #endif - + #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) const QPointF pos = event->pos(); #else const QPointF pos = event->position(); #endif - + const double wheelSteps = delta/120.0; // a single step delta is +/-120 usually const double factor = qPow(mAxisRect->rangeZoomFactor(orientation()), wheelSteps); scaleRange(factor, pixelToCoord(orientation() == Qt::Horizontal ? pos.x() : pos.y())); @@ -9655,13 +9675,13 @@ void QCPAxis::wheelEvent(QWheelEvent *event) before drawing axis lines. This is the antialiasing state the painter passed to the \ref draw method is in by default. - + This function takes into account the local setting of the antialiasing flag as well as the overrides set with \ref QCustomPlot::setAntialiasedElements and \ref QCustomPlot::setNotAntialiasedElements. - + \seebaseclassmethod - + \see setAntialiased */ void QCPAxis::applyDefaultAntialiasingHint(QCPPainter *painter) const @@ -9670,7 +9690,7 @@ void QCPAxis::applyDefaultAntialiasingHint(QCPPainter *painter) const } /*! \internal - + Draws the axis with the specified \a painter, using the internal QCPAxisPainterPrivate instance. \seebaseclassmethod @@ -9683,7 +9703,7 @@ void QCPAxis::draw(QCPPainter *painter) tickPositions.reserve(mTickVector.size()); tickLabels.reserve(mTickVector.size()); subTickPositions.reserve(mSubTickVector.size()); - + if (mTicks) { for (int i=0; itype = mAxisType; @@ -9724,10 +9744,10 @@ void QCPAxis::draw(QCPPainter *painter) } /*! \internal - + Prepares the internal tick vector, sub tick vector and tick label vector. This is done by calling QCPAxisTicker::generate on the currently installed ticker. - + If a change in the label text/count is detected, the cached axis margin is invalidated to make sure the next margin calculation recalculates the label sizes and returns an up-to-date value. */ @@ -9735,14 +9755,14 @@ void QCPAxis::setupTickVectors() { if (!mParentPlot) return; if ((!mTicks && !mTickLabels && !mGrid->visible()) || mRange.size() <= 0) return; - + QVector oldLabels = mTickVectorLabels; mTicker->generate(mRange, mParentPlot->locale(), mNumberFormatChar, mNumberPrecision, mTickVector, mSubTicks ? &mSubTickVector : nullptr, mTickLabels ? &mTickVectorLabels : nullptr); mCachedMarginValid &= mTickVectorLabels == oldLabels; // if labels have changed, margin might have changed, too } /*! \internal - + Returns the pen that is used to draw the axis base line. Depending on the selection state, this is either mSelectedBasePen or mBasePen. */ @@ -9752,7 +9772,7 @@ QPen QCPAxis::getBasePen() const } /*! \internal - + Returns the pen that is used to draw the (major) ticks. Depending on the selection state, this is either mSelectedTickPen or mTickPen. */ @@ -9762,7 +9782,7 @@ QPen QCPAxis::getTickPen() const } /*! \internal - + Returns the pen that is used to draw the subticks. Depending on the selection state, this is either mSelectedSubTickPen or mSubTickPen. */ @@ -9772,7 +9792,7 @@ QPen QCPAxis::getSubTickPen() const } /*! \internal - + Returns the font that is used to draw the tick labels. Depending on the selection state, this is either mSelectedTickLabelFont or mTickLabelFont. */ @@ -9782,7 +9802,7 @@ QFont QCPAxis::getTickLabelFont() const } /*! \internal - + Returns the font that is used to draw the axis label. Depending on the selection state, this is either mSelectedLabelFont or mLabelFont. */ @@ -9792,7 +9812,7 @@ QFont QCPAxis::getLabelFont() const } /*! \internal - + Returns the color that is used to draw the tick labels. Depending on the selection state, this is either mSelectedTickLabelColor or mTickLabelColor. */ @@ -9802,7 +9822,7 @@ QColor QCPAxis::getTickLabelColor() const } /*! \internal - + Returns the color that is used to draw the axis label. Depending on the selection state, this is either mSelectedLabelColor or mLabelColor. */ @@ -9812,16 +9832,16 @@ QColor QCPAxis::getLabelColor() const } /*! \internal - + Returns the appropriate outward margin for this axis. It is needed if \ref QCPAxisRect::setAutoMargins is set to true on the parent axis rect. An axis with axis type \ref atLeft will return an appropriate left margin, \ref atBottom will return an appropriate bottom margin and so forth. For the calculation, this function goes through similar steps as \ref draw, so changing one function likely requires the modification of the other one as well. - + The margin consists of the outward tick length, tick label padding, tick label size, label padding, label size, and padding. - + The margin is cached internally, so repeated calls while leaving the axis range, fonts, etc. unchanged are very fast. */ @@ -9829,18 +9849,18 @@ int QCPAxis::calculateMargin() { if (!mVisible) // if not visible, directly return 0, don't cache 0 because we can't react to setVisible in QCPAxis return 0; - + if (mCachedMarginValid) return mCachedMargin; - + // run through similar steps as QCPAxis::draw, and calculate margin needed to fit axis and its labels int margin = 0; - + QVector tickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter QVector tickLabels; // the final vector passed to QCPAxisPainter tickPositions.reserve(mTickVector.size()); tickLabels.reserve(mTickVector.size()); - + if (mTicks) { for (int i=0; idrawLine(baseLine); - + // draw ticks: if (!tickPositions.isEmpty()) { @@ -9983,7 +10003,7 @@ void QCPAxisPainterPrivate::draw(QCPPainter *painter) painter->drawLine(QLineF(origin.x()-tickLengthOut*tickDir+xCor, tickPos+yCor, origin.x()+tickLengthIn*tickDir+xCor, tickPos+yCor)); } } - + // draw subticks: if (!subTickPositions.isEmpty()) { @@ -10001,7 +10021,7 @@ void QCPAxisPainterPrivate::draw(QCPPainter *painter) } } margin += qMax(0, qMax(tickLengthOut, subTickLengthOut)); - + // draw axis base endings: bool antialiasingBackup = painter->antialiasing(); painter->setAntialiasing(true); // always want endings to be antialiased, even if base and ticks themselves aren't @@ -10012,7 +10032,7 @@ void QCPAxisPainterPrivate::draw(QCPPainter *painter) if (upperEnding.style() != QCPLineEnding::esNone) upperEnding.draw(painter, QCPVector2D(baseLine.p2())+baseLineVector.normalized()*upperEnding.realLength()*(upperEnding.inverted()?-1:1), baseLineVector); painter->setAntialiasing(antialiasingBackup); - + // tick labels: QRect oldClipRect; if (tickLabelSide == QCPAxis::lsInside) // if using inside labels, clip them to the axis rect @@ -10038,7 +10058,7 @@ void QCPAxisPainterPrivate::draw(QCPPainter *painter) } if (tickLabelSide == QCPAxis::lsInside) painter->setClipRect(oldClipRect); - + // axis label: QRect labelBounds; if (!label.isEmpty()) @@ -10068,7 +10088,7 @@ void QCPAxisPainterPrivate::draw(QCPPainter *painter) else if (type == QCPAxis::atBottom) painter->drawText(origin.x(), origin.y()+margin, axisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); } - + // set selection boxes: int selectionTolerance = 0; if (mParentPlot) @@ -10120,7 +10140,7 @@ void QCPAxisPainterPrivate::draw(QCPPainter *painter) } /*! \internal - + Returns the size ("margin" in QCPAxisRect context, so measured perpendicular to the axis backbone direction) needed to fit the axis. */ @@ -10134,11 +10154,11 @@ int QCPAxisPainterPrivate::size() mLabelCache.clear(); mLabelParameterHash = newHash; } - + // get length of tick marks pointing outwards: if (!tickPositions.isEmpty()) result += qMax(0, qMax(tickLengthOut, subTickLengthOut)); - + // calculate size of tick labels: if (tickLabelSide == QCPAxis::lsOutside) { @@ -10151,7 +10171,7 @@ int QCPAxisPainterPrivate::size() result += tickLabelPadding; } } - + // calculate size of axis label (only height needed, because left/right labels are rotated by 90 degrees): if (!label.isEmpty()) { @@ -10165,7 +10185,7 @@ int QCPAxisPainterPrivate::size() } /*! \internal - + Clears the internal label cache. Upon the next \ref draw, all labels will be created new. This method is called automatically in \ref draw, if any parameters have changed that invalidate the cached labels, such as font, color, etc. @@ -10176,7 +10196,7 @@ void QCPAxisPainterPrivate::clearCache() } /*! \internal - + Returns a hash that allows uniquely identifying whether the label parameters have changed such that the cached labels must be refreshed (\ref clearCache). It is used in \ref draw. If the return value of this method hasn't changed since the last redraw, the respective label parameters @@ -10196,20 +10216,20 @@ QByteArray QCPAxisPainterPrivate::generateLabelParameterHash() const } /*! \internal - + Draws a single tick label with the provided \a painter, utilizing the internal label cache to significantly speed up drawing of labels that were drawn in previous calls. The tick label is always bound to an axis, the distance to the axis is controllable via \a distanceToAxis in pixels. The pixel position in the axis direction is passed in the \a position parameter. Hence for the bottom axis, \a position would indicate the horizontal pixel position (not coordinate), at which the label should be drawn. - + In order to later draw the axis label in a place that doesn't overlap with the tick labels, the largest tick label size is needed. This is acquired by passing a \a tickLabelsSize to the \ref drawTickLabel calls during the process of drawing all tick labels of one axis. In every call, \a tickLabelsSize is expanded, if the drawn label exceeds the value \a tickLabelsSize currently holds. - + The label is drawn with the font and pen that are currently set on the \a painter. To draw superscripted powers, the font is temporarily made smaller by a fixed factor (see \ref getTickLabelData). @@ -10286,7 +10306,7 @@ void QCPAxisPainterPrivate::placeTickLabel(QCPPainter *painter, double position, finalSize = labelData.rotatedTotalBounds.size(); } } - + // expand passed tickLabelsSize if current tick label is larger: if (finalSize.width() > tickLabelsSize->width()) tickLabelsSize->setWidth(finalSize.width()); @@ -10295,9 +10315,9 @@ void QCPAxisPainterPrivate::placeTickLabel(QCPPainter *painter, double position, } /*! \internal - + This is a \ref placeTickLabel helper function. - + Draws the tick label specified in \a labelData with \a painter at the pixel positions \a x and \a y. This function is used by \ref placeTickLabel to create new tick labels for the cache, or to directly draw the labels on the QCustomPlot surface when label caching is disabled, i.e. when @@ -10308,12 +10328,12 @@ void QCPAxisPainterPrivate::drawTickLabel(QCPPainter *painter, double x, double // backup painter settings that we're about to change: QTransform oldTransform = painter->transform(); QFont oldFont = painter->font(); - + // transform painter to position/rotation: painter->translate(x, y); if (!qFuzzyIsNull(tickLabelRotation)) painter->rotate(tickLabelRotation); - + // draw text: if (!labelData.expPart.isEmpty()) // indicator that beautiful powers must be used { @@ -10328,16 +10348,16 @@ void QCPAxisPainterPrivate::drawTickLabel(QCPPainter *painter, double x, double painter->setFont(labelData.baseFont); painter->drawText(0, 0, labelData.totalBounds.width(), labelData.totalBounds.height(), Qt::TextDontClip | Qt::AlignHCenter, labelData.basePart); } - + // reset painter settings to what it was before: painter->setTransform(oldTransform); painter->setFont(oldFont); } /*! \internal - + This is a \ref placeTickLabel helper function. - + Transforms the passed \a text and \a font to a tickLabelData structure that can then be further processed by \ref getTickLabelDrawOffset and \ref drawTickLabel. It splits the text into base and exponent if necessary (member substituteExponent) and calculates appropriate bounding boxes. @@ -10345,7 +10365,7 @@ void QCPAxisPainterPrivate::drawTickLabel(QCPPainter *painter, double x, double QCPAxisPainterPrivate::TickLabelData QCPAxisPainterPrivate::getTickLabelData(const QFont &font, const QString &text) const { TickLabelData result; - + // determine whether beautiful decimal powers should be used bool useBeautifulPowers = false; int ePos = -1; // first index of exponent part, text before that will be basePart, text until eLast will be expPart @@ -10362,7 +10382,7 @@ QCPAxisPainterPrivate::TickLabelData QCPAxisPainterPrivate::getTickLabelData(con useBeautifulPowers = true; } } - + // calculate text bounding rects and do string preparation for beautiful decimal powers: result.baseFont = font; if (result.baseFont.pointSizeF() > 0) // might return -1 if specified with setPixelSize, in that case we can't do correction in next line @@ -10401,7 +10421,7 @@ QCPAxisPainterPrivate::TickLabelData QCPAxisPainterPrivate::getTickLabelData(con result.totalBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter, result.basePart); } result.totalBounds.moveTopLeft(QPoint(0, 0)); // want bounding box aligned top left at origin, independent of how it was created, to make further processing simpler - + // calculate possibly different bounding rect after rotation: result.rotatedTotalBounds = result.totalBounds; if (!qFuzzyIsNull(tickLabelRotation)) @@ -10410,17 +10430,17 @@ QCPAxisPainterPrivate::TickLabelData QCPAxisPainterPrivate::getTickLabelData(con transform.rotate(tickLabelRotation); result.rotatedTotalBounds = transform.mapRect(result.rotatedTotalBounds); } - + return result; } /*! \internal - + This is a \ref placeTickLabel helper function. - + Calculates the offset at which the top left corner of the specified tick label shall be drawn. The offset is relative to a point right next to the tick the label belongs to. - + This function is thus responsible for e.g. centering tick labels under ticks and positioning them appropriately when they are rotated. */ @@ -10514,12 +10534,12 @@ QPointF QCPAxisPainterPrivate::getTickLabelDrawOffset(const TickLabelData &label y = 0; } } - + return {x, y}; } /*! \internal - + Simulates the steps done by \ref placeTickLabel by calculating bounding boxes of the text label to be drawn, depending on number format etc. Since only the largest tick label is wanted for the margin calculation, the passed \a tickLabelsSize is only expanded, if it's currently set to a @@ -10538,7 +10558,7 @@ void QCPAxisPainterPrivate::getMaxTickLabelSize(const QFont &font, const QString TickLabelData labelData = getTickLabelData(font, text); finalSize = labelData.rotatedTotalBounds.size(); } - + // expand passed tickLabelsSize if current tick label is larger: if (finalSize.width() > tickLabelsSize->width()) tickLabelsSize->setWidth(finalSize.width()); @@ -10557,33 +10577,33 @@ void QCPAxisPainterPrivate::getMaxTickLabelSize(const QFont &font, const QString /*! \class QCPScatterStyle \brief Represents the visual appearance of scatter points - + This class holds information about shape, color and size of scatter points. In plottables like QCPGraph it is used to store how scatter points shall be drawn. For example, \ref QCPGraph::setScatterStyle takes a QCPScatterStyle instance. - + A scatter style consists of a shape (\ref setShape), a line color (\ref setPen) and possibly a fill (\ref setBrush), if the shape provides a fillable area. Further, the size of the shape can be controlled with \ref setSize. \section QCPScatterStyle-defining Specifying a scatter style - + You can set all these configurations either by calling the respective functions on an instance: \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-creation-1 - + Or you can use one of the various constructors that take different parameter combinations, making it easy to specify a scatter style in a single call, like so: \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-creation-2 - + \section QCPScatterStyle-undefinedpen Leaving the color/pen up to the plottable - + There are two constructors which leave the pen undefined: \ref QCPScatterStyle() and \ref QCPScatterStyle(ScatterShape shape, double size). If those constructors are used, a call to \ref isPenDefined will return false. It leads to scatter points that inherit the pen from the plottable that uses the scatter style. Thus, if such a scatter style is passed to QCPGraph, the line color of the graph (\ref QCPGraph::setPen) will be used by the scatter points. This makes it very convenient to set up typical scatter settings: - + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-shortcreation Notice that it wasn't even necessary to explicitly call a QCPScatterStyle constructor. This works @@ -10591,15 +10611,15 @@ void QCPAxisPainterPrivate::getMaxTickLabelSize(const QFont &font, const QString into a QCPScatterStyle instance (that's the \ref QCPScatterStyle(ScatterShape shape, double size) constructor with a default for \a size). In those cases, C++ allows directly supplying a \ref ScatterShape, where actually a QCPScatterStyle is expected. - + \section QCPScatterStyle-custompath-and-pixmap Custom shapes and pixmaps - + QCPScatterStyle supports drawing custom shapes and arbitrary pixmaps as scatter points. For custom shapes, you can provide a QPainterPath with the desired shape to the \ref setCustomPath function or call the constructor that takes a painter path. The scatter shape will automatically be set to \ref ssCustom. - + For pixmaps, you call \ref setPixmap with the desired QPixmap. Alternatively you can use the constructor that takes a QPixmap. The scatter shape will automatically be set to \ref ssPixmap. Note that \ref setSize does not influence the appearance of the pixmap. @@ -10608,23 +10628,23 @@ void QCPAxisPainterPrivate::getMaxTickLabelSize(const QFont &font, const QString /* start documentation of inline functions */ /*! \fn bool QCPScatterStyle::isNone() const - + Returns whether the scatter shape is \ref ssNone. - + \see setShape */ /*! \fn bool QCPScatterStyle::isPenDefined() const - + Returns whether a pen has been defined for this scatter style. - + The pen is undefined if a constructor is called that does not carry \a pen as parameter. Those are \ref QCPScatterStyle() and \ref QCPScatterStyle(ScatterShape shape, double size). If the pen is undefined, the pen of the respective plottable will be used for drawing scatters. - + If a pen was defined for this scatter style instance, and you now wish to undefine the pen, call \ref undefinePen. - + \see setPen */ @@ -10632,7 +10652,7 @@ void QCPAxisPainterPrivate::getMaxTickLabelSize(const QFont &font, const QString /*! Creates a new QCPScatterStyle instance with size set to 6. No shape, pen or brush is defined. - + Since the pen is undefined (\ref isPenDefined returns false), the scatter color will be inherited from the plottable that uses this scatter style. */ @@ -10648,7 +10668,7 @@ QCPScatterStyle::QCPScatterStyle() : /*! Creates a new QCPScatterStyle instance with shape set to \a shape and size to \a size. No pen or brush is defined. - + Since the pen is undefined (\ref isPenDefined returns false), the scatter color will be inherited from the plottable that uses this scatter style. */ @@ -10690,7 +10710,7 @@ QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QColor &color, const /*! Creates a new QCPScatterStyle instance with shape set to \a shape, the pen set to \a pen, the brush to \a brush, and size to \a size. - + \warning In some cases it might be tempting to directly use a pen style like Qt::NoPen as \a pen and a color like Qt::blue as \a brush. Notice however, that the corresponding call\n QCPScatterStyle(QCPScatterShape::ssCircle, Qt::NoPen, Qt::blue, 5)\n @@ -10728,7 +10748,7 @@ QCPScatterStyle::QCPScatterStyle(const QPixmap &pixmap) : /*! Creates a new QCPScatterStyle instance with a custom shape that is defined via \a customPath. The scatter shape is set to \ref ssCustom. - + The custom shape line will be drawn with \a pen and filled with \a brush. The size has a slightly different meaning than for built-in scatter points: The custom path will be drawn scaled by a factor of \a size/6.0. Since the default \a size is 6, the custom path will appear in its @@ -10771,7 +10791,7 @@ void QCPScatterStyle::setFromOther(const QCPScatterStyle &other, ScatterProperti /*! Sets the size (pixel diameter) of the drawn scatter points to \a size. - + \see setShape */ void QCPScatterStyle::setSize(double size) @@ -10781,10 +10801,10 @@ void QCPScatterStyle::setSize(double size) /*! Sets the shape to \a shape. - + Note that the calls \ref setPixmap and \ref setCustomPath automatically set the shape to \ref ssPixmap and \ref ssCustom, respectively. - + \see setSize */ void QCPScatterStyle::setShape(QCPScatterStyle::ScatterShape shape) @@ -10794,11 +10814,11 @@ void QCPScatterStyle::setShape(QCPScatterStyle::ScatterShape shape) /*! Sets the pen that will be used to draw scatter points to \a pen. - + If the pen was previously undefined (see \ref isPenDefined), the pen is considered defined after a call to this function, even if \a pen is Qt::NoPen. If you have defined a pen previously by calling this function and now wish to undefine the pen, call \ref undefinePen. - + \see setBrush */ void QCPScatterStyle::setPen(const QPen &pen) @@ -10810,7 +10830,7 @@ void QCPScatterStyle::setPen(const QPen &pen) /*! Sets the brush that will be used to fill scatter points to \a brush. Note that not all scatter shapes have fillable areas. For example, \ref ssPlus does not while \ref ssCircle does. - + \see setPen */ void QCPScatterStyle::setBrush(const QBrush &brush) @@ -10820,9 +10840,9 @@ void QCPScatterStyle::setBrush(const QBrush &brush) /*! Sets the pixmap that will be drawn as scatter point to \a pixmap. - + Note that \ref setSize does not influence the appearance of the pixmap. - + The scatter shape is automatically set to \ref ssPixmap. */ void QCPScatterStyle::setPixmap(const QPixmap &pixmap) @@ -10833,7 +10853,7 @@ void QCPScatterStyle::setPixmap(const QPixmap &pixmap) /*! Sets the custom shape that will be drawn as scatter point to \a customPath. - + The scatter shape is automatically set to \ref ssCustom. */ void QCPScatterStyle::setCustomPath(const QPainterPath &customPath) @@ -10856,10 +10876,10 @@ void QCPScatterStyle::undefinePen() /*! Applies the pen and the brush of this scatter style to \a painter. If this scatter style has an undefined pen (\ref isPenDefined), sets the pen of \a painter to \a defaultPen instead. - + This function is used by plottables (or any class that wants to draw scatters) just before a number of scatters with this style shall be drawn with the \a painter. - + \see drawShape */ void QCPScatterStyle::applyTo(QCPPainter *painter, const QPen &defaultPen) const @@ -10870,10 +10890,10 @@ void QCPScatterStyle::applyTo(QCPPainter *painter, const QPen &defaultPen) const /*! Draws the scatter shape with \a painter at position \a pos. - + This function does not modify the pen or the brush on the painter, as \ref applyTo is meant to be called before scatter points are drawn with \ref drawShape. - + \see applyTo */ void QCPScatterStyle::drawShape(QCPPainter *painter, const QPointF &pos) const @@ -11030,24 +11050,24 @@ void QCPScatterStyle::drawShape(QCPPainter *painter, double x, double y) const /*! \class QCPSelectionDecorator \brief Controls how a plottable's data selection is drawn - + Each \ref QCPAbstractPlottable instance has one \ref QCPSelectionDecorator (accessible via \ref QCPAbstractPlottable::selectionDecorator) and uses it when drawing selected segments of its data. - + The selection decorator controls both pen (\ref setPen) and brush (\ref setBrush), as well as the scatter style (\ref setScatterStyle) if the plottable draws scatters. Since a \ref QCPScatterStyle is itself composed of different properties such as color shape and size, the decorator allows specifying exactly which of those properties shall be used for the selected data point, via \ref setUsedScatterProperties. - + A \ref QCPSelectionDecorator subclass instance can be passed to a plottable via \ref QCPAbstractPlottable::setSelectionDecorator, allowing greater customizability of the appearance of selected segments. - + Use \ref copyFrom to easily transfer the settings of one decorator to another one. This is especially useful since plottables take ownership of the passed selection decorator, and thus the same decorator instance can not be passed to multiple plottables. - + Selection decorators can also themselves perform drawing operations by reimplementing \ref drawDecoration, which is called by the plottable's draw method. The base class \ref QCPSelectionDecorator does not make use of this however. For example, \ref @@ -11088,7 +11108,7 @@ void QCPSelectionDecorator::setBrush(const QBrush &brush) /*! Sets the scatter style that will be used by the parent plottable to draw scatters in selected data segments. - + \a usedProperties specifies which parts of the passed \a scatterStyle will be used by the plottable. The used properties can also be changed via \ref setUsedScatterProperties. */ @@ -11102,7 +11122,7 @@ void QCPSelectionDecorator::setScatterStyle(const QCPScatterStyle &scatterStyle, Use this method to define which properties of the scatter style (set via \ref setScatterStyle) will be used for selected data segments. All properties of the scatter style that are not specified in \a properties will remain as specified in the plottable's original scatter style. - + \see QCPScatterStyle::ScatterProperty */ void QCPSelectionDecorator::setUsedScatterProperties(const QCPScatterStyle::ScatterProperties &properties) @@ -11112,7 +11132,7 @@ void QCPSelectionDecorator::setUsedScatterProperties(const QCPScatterStyle::Scat /*! Sets the pen of \a painter to the pen of this selection decorator. - + \see applyBrush, getFinalScatterStyle */ void QCPSelectionDecorator::applyPen(QCPPainter *painter) const @@ -11122,7 +11142,7 @@ void QCPSelectionDecorator::applyPen(QCPPainter *painter) const /*! Sets the brush of \a painter to the brush of this selection decorator. - + \see applyPen, getFinalScatterStyle */ void QCPSelectionDecorator::applyBrush(QCPPainter *painter) const @@ -11135,20 +11155,20 @@ void QCPSelectionDecorator::applyBrush(QCPPainter *painter) const plottable's original (unselected) scatter style must be passed as \a unselectedStyle. Depending on the setting of \ref setUsedScatterProperties, the returned scatter style is a mixture of this selecion decorator's scatter style (\ref setScatterStyle), and \a unselectedStyle. - + \see applyPen, applyBrush, setScatterStyle */ QCPScatterStyle QCPSelectionDecorator::getFinalScatterStyle(const QCPScatterStyle &unselectedStyle) const { QCPScatterStyle result(unselectedStyle); result.setFromOther(mScatterStyle, mUsedScatterProperties); - + // if style shall inherit pen from plottable (has no own pen defined), give it the selected // plottable pen explicitly, so it doesn't use the unselected plottable pen when used in the // plottable: if (!result.isPenDefined()) result.setPen(mPen); - + return result; } @@ -11167,7 +11187,7 @@ void QCPSelectionDecorator::copyFrom(const QCPSelectionDecorator *other) This method is called by all plottables' draw methods to allow custom selection decorations to be drawn. Use the passed \a painter to perform the drawing operations. \a selection carries the data selection for which the decoration shall be drawn. - + The default base class implementation of \ref QCPSelectionDecorator has no special decoration, so this method does nothing. */ @@ -11178,11 +11198,11 @@ void QCPSelectionDecorator::drawDecoration(QCPPainter *painter, QCPDataSelection } /*! \internal - + This method is called as soon as a selection decorator is associated with a plottable, by a call to \ref QCPAbstractPlottable::setSelectionDecorator. This way the selection decorator can obtain a pointer to the plottable that uses it (e.g. to access data points via the \ref QCPAbstractPlottable::interface1D interface). - + If the selection decorator was already added to a different plottable before, this method aborts the registration and returns false. */ @@ -11213,7 +11233,7 @@ bool QCPSelectionDecorator::registerWithPlottable(QCPAbstractPlottable *plottabl one-dimensional data (i.e. data points have a single key dimension and one or multiple values at each key) are based off of the template subclass \ref QCPAbstractPlottable1D, see details there. - + All further specifics are in the subclasses, for example: \li A normal graph with possibly a line and/or scatter points \ref QCPGraph (typically created with \ref QCustomPlot::addGraph) @@ -11222,14 +11242,14 @@ bool QCPSelectionDecorator::registerWithPlottable(QCPAbstractPlottable *plottabl \li A statistical box plot: \ref QCPStatisticalBox \li A color encoded two-dimensional map: \ref QCPColorMap \li An OHLC/Candlestick chart: \ref QCPFinancial - + \section plottables-subclassing Creating own plottables - + Subclassing directly from QCPAbstractPlottable is only recommended if you wish to display two-dimensional data like \ref QCPColorMap, i.e. two logical key dimensions and one (or more) data dimensions. If you want to display data with only one logical key dimension, you should rather derive from \ref QCPAbstractPlottable1D. - + If subclassing QCPAbstractPlottable directly, these are the pure virtual functions you must implement: \li \ref selectTest @@ -11237,9 +11257,9 @@ bool QCPSelectionDecorator::registerWithPlottable(QCPAbstractPlottable *plottabl \li \ref drawLegendIcon \li \ref getKeyRange \li \ref getValueRange - + See the documentation of those functions for what they need to do. - + For drawing your plot, you can use the \ref coordsToPixels functions to translate a point in plot coordinates to pixel coordinates. This function is quite convenient, because it takes the orientation of the key and value axes into account for you (x and y are swapped when the key axis @@ -11247,7 +11267,7 @@ bool QCPSelectionDecorator::registerWithPlottable(QCPAbstractPlottable *plottabl to translate many points in a loop like QCPGraph), you can directly use \ref QCPAxis::coordToPixel. However, you must then take care about the orientation of the axis yourself. - + Here are some important members you inherit from QCPAbstractPlottable: @@ -11288,35 +11308,35 @@ bool QCPSelectionDecorator::registerWithPlottable(QCPAbstractPlottable *plottabl /* start of documentation of inline functions */ /*! \fn QCPSelectionDecorator *QCPAbstractPlottable::selectionDecorator() const - + Provides access to the selection decorator of this plottable. The selection decorator controls how selected data ranges are drawn (e.g. their pen color and fill), see \ref QCPSelectionDecorator for details. - + If you wish to use an own \ref QCPSelectionDecorator subclass, pass an instance of it to \ref setSelectionDecorator. */ /*! \fn bool QCPAbstractPlottable::selected() const - + Returns true if there are any data points of the plottable currently selected. Use \ref selection to retrieve the current \ref QCPDataSelection. */ /*! \fn QCPDataSelection QCPAbstractPlottable::selection() const - + Returns a \ref QCPDataSelection encompassing all the data points that are currently selected on this plottable. - + \see selected, setSelection, setSelectable */ /*! \fn virtual QCPPlottableInterface1D *QCPAbstractPlottable::interface1D() - + If this plottable is a one-dimensional plottable, i.e. it implements the \ref QCPPlottableInterface1D, returns the \a this pointer with that type. Otherwise (e.g. in the case of a \ref QCPColorMap) returns zero. - + You can use this method to gain read access to data coordinates while holding a pointer to the abstract base class only. */ @@ -11326,16 +11346,16 @@ bool QCPSelectionDecorator::registerWithPlottable(QCPAbstractPlottable *plottabl /*! \fn void QCPAbstractPlottable::drawLegendIcon(QCPPainter *painter, const QRect &rect) const = 0 \internal - + called by QCPLegend::draw (via QCPPlottableLegendItem::draw) to create a graphical representation of this plottable inside \a rect, next to the plottable name. - + The passed \a painter has its cliprect set to \a rect, so painting outside of \a rect won't appear outside the legend icon border. */ /*! \fn QCPRange QCPAbstractPlottable::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const = 0 - + Returns the coordinate range that all data in this plottable span in the key axis dimension. For logarithmic plots, one can set \a inSignDomain to either \ref QCP::sdNegative or \ref QCP::sdPositive in order to restrict the returned range to that sign domain. E.g. when only @@ -11348,12 +11368,12 @@ bool QCPSelectionDecorator::registerWithPlottable(QCPAbstractPlottable *plottabl this function may have size zero (e.g. when there is only one data point). In this case \a foundRange would return true, but the returned range is not a valid range in terms of \ref QCPRange::validRange. - + \see rescaleAxes, getValueRange */ /*! \fn QCPRange QCPAbstractPlottable::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const = 0 - + Returns the coordinate range that the data points in the specified key range (\a inKeyRange) span in the value axis dimension. For logarithmic plots, one can set \a inSignDomain to either \ref QCP::sdNegative or \ref QCP::sdPositive in order to restrict the returned range to that sign @@ -11362,7 +11382,7 @@ bool QCPSelectionDecorator::registerWithPlottable(QCPAbstractPlottable *plottabl inSignDomain to \ref QCP::sdBoth (default). \a foundRange is an output parameter that indicates whether a range could be found or not. If this is false, you shouldn't use the returned range (e.g. no points in data). - + If \a inKeyRange has both lower and upper bound set to zero (is equal to QCPRange()), all data points are considered, without any restriction on the keys. @@ -11370,7 +11390,7 @@ bool QCPSelectionDecorator::registerWithPlottable(QCPAbstractPlottable *plottabl this function may have size zero (e.g. when there is only one data point). In this case \a foundRange would return true, but the returned range is not a valid range in terms of \ref QCPRange::validRange. - + \see rescaleAxes, getKeyRange */ @@ -11378,27 +11398,27 @@ bool QCPSelectionDecorator::registerWithPlottable(QCPAbstractPlottable *plottabl /* start of documentation of signals */ /*! \fn void QCPAbstractPlottable::selectionChanged(bool selected) - + This signal is emitted when the selection state of this plottable has changed, either by user interaction or by a direct call to \ref setSelection. The parameter \a selected indicates whether there are any points selected or not. - + \see selectionChanged(const QCPDataSelection &selection) */ /*! \fn void QCPAbstractPlottable::selectionChanged(const QCPDataSelection &selection) - + This signal is emitted when the selection state of this plottable has changed, either by user interaction or by a direct call to \ref setSelection. The parameter \a selection holds the currently selected data ranges. - + \see selectionChanged(bool selected) */ /*! \fn void QCPAbstractPlottable::selectableChanged(QCP::SelectionType selectable); - + This signal is emitted when the selectability of this plottable has changed. - + \see setSelectable */ @@ -11409,10 +11429,10 @@ bool QCPSelectionDecorator::registerWithPlottable(QCPAbstractPlottable *plottabl its value axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and have perpendicular orientations. If either of these restrictions is violated, a corresponding message is printed to the debug output (qDebug), the construction is not aborted, though. - + Since QCPAbstractPlottable is an abstract class that defines the basic interface to plottables, it can't be directly instantiated. - + You probably want one of the subclasses like \ref QCPGraph or \ref QCPCurve instead. */ QCPAbstractPlottable::QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis) : @@ -11431,7 +11451,7 @@ QCPAbstractPlottable::QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis) qDebug() << Q_FUNC_INFO << "Parent plot of keyAxis is not the same as that of valueAxis."; if (keyAxis->orientation() == valueAxis->orientation()) qDebug() << Q_FUNC_INFO << "keyAxis and valueAxis must be orthogonal to each other."; - + mParentPlot->registerPlottable(this); setSelectionDecorator(new QCPSelectionDecorator); } @@ -11456,7 +11476,7 @@ void QCPAbstractPlottable::setName(const QString &name) /*! Sets whether fills of this plottable are drawn antialiased or not. - + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref QCustomPlot::setNotAntialiasedElements. */ @@ -11467,7 +11487,7 @@ void QCPAbstractPlottable::setAntialiasedFill(bool enabled) /*! Sets whether the scatter symbols of this plottable are drawn antialiased or not. - + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref QCustomPlot::setNotAntialiasedElements. */ @@ -11479,7 +11499,7 @@ void QCPAbstractPlottable::setAntialiasedScatters(bool enabled) /*! The pen is used to draw basic lines that make up the plottable representation in the plot. - + For example, the \ref QCPGraph subclass draws its graph lines with this pen. \see setBrush @@ -11492,7 +11512,7 @@ void QCPAbstractPlottable::setPen(const QPen &pen) /*! The brush is used to draw basic fills of the plottable representation in the plot. The Fill can be a color, gradient or texture, see the usage of QBrush. - + For example, the \ref QCPGraph subclass draws the fill under the graph with this brush, when it's not set to Qt::NoBrush. @@ -11508,7 +11528,7 @@ void QCPAbstractPlottable::setBrush(const QBrush &brush) to the plottable's value axis. This function performs no checks to make sure this is the case. The typical mathematical choice is to use the x-axis (QCustomPlot::xAxis) as key axis and the y-axis (QCustomPlot::yAxis) as value axis. - + Normally, the key and value axes are set in the constructor of the plottable (or \ref QCustomPlot::addGraph when working with QCPGraphs through the dedicated graph interface). @@ -11527,7 +11547,7 @@ void QCPAbstractPlottable::setKeyAxis(QCPAxis *axis) Normally, the key and value axes are set in the constructor of the plottable (or \ref QCustomPlot::addGraph when working with QCPGraphs through the dedicated graph interface). - + \see setKeyAxis */ void QCPAbstractPlottable::setValueAxis(QCPAxis *axis) @@ -11540,18 +11560,18 @@ void QCPAbstractPlottable::setValueAxis(QCPAxis *axis) Sets which data ranges of this plottable are selected. Selected data ranges are drawn differently (e.g. color) in the plot. This can be controlled via the selection decorator (see \ref selectionDecorator). - + The entire selection mechanism for plottables is handled automatically when \ref QCustomPlot::setInteractions contains iSelectPlottables. You only need to call this function when you wish to change the selection state programmatically. - + Using \ref setSelectable you can further specify for each plottable whether and to which granularity it is selectable. If \a selection is not compatible with the current \ref QCP::SelectionType set via \ref setSelectable, the resulting selection will be adjusted accordingly (see \ref QCPDataSelection::enforceType). - + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. - + \see setSelectable, selectTest */ void QCPAbstractPlottable::setSelection(QCPDataSelection selection) @@ -11569,9 +11589,9 @@ void QCPAbstractPlottable::setSelection(QCPDataSelection selection) Use this method to set an own QCPSelectionDecorator (subclass) instance. This allows you to customize the visual representation of selected data ranges further than by using the default QCPSelectionDecorator. - + The plottable takes ownership of the \a decorator. - + The currently set decorator can be accessed via \ref selectionDecorator. */ void QCPAbstractPlottable::setSelectionDecorator(QCPSelectionDecorator *decorator) @@ -11597,7 +11617,7 @@ void QCPAbstractPlottable::setSelectionDecorator(QCPSelectionDecorator *decorato QCustomPlot::setInteractions contains \ref QCP::iSelectPlottables), by dragging a selection rect (When \ref QCustomPlot::setSelectionRectMode is \ref QCP::srmSelect), or programmatically by calling \ref setSelection. - + \see setSelection, QCP::SelectionType */ void QCPAbstractPlottable::setSelectable(QCP::SelectionType selectable) @@ -11631,7 +11651,7 @@ void QCPAbstractPlottable::coordsToPixels(double key, double value, double &x, d QCPAxis *keyAxis = mKeyAxis.data(); QCPAxis *valueAxis = mValueAxis.data(); if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - + if (keyAxis->orientation() == Qt::Horizontal) { x = keyAxis->coordToPixel(key); @@ -11652,7 +11672,7 @@ const QPointF QCPAbstractPlottable::coordsToPixels(double key, double value) con QCPAxis *keyAxis = mKeyAxis.data(); QCPAxis *valueAxis = mValueAxis.data(); if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); } - + if (keyAxis->orientation() == Qt::Horizontal) return QPointF(keyAxis->coordToPixel(key), valueAxis->coordToPixel(value)); else @@ -11673,7 +11693,7 @@ void QCPAbstractPlottable::pixelsToCoords(double x, double y, double &key, doubl QCPAxis *keyAxis = mKeyAxis.data(); QCPAxis *valueAxis = mValueAxis.data(); if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - + if (keyAxis->orientation() == Qt::Horizontal) { key = keyAxis->pixelToCoord(x); @@ -11700,11 +11720,11 @@ void QCPAbstractPlottable::pixelsToCoords(const QPointF &pixelPos, double &key, sure not to rescale to an illegal range i.e. a range containing different signs and/or zero. Instead it will stay in the current sign domain and ignore all parts of the plottable that lie outside of that domain. - + \a onlyEnlarge makes sure the ranges are only expanded, never reduced. So it's possible to show multiple plottables in their entirety by multiple calls to rescaleAxes where the first call has \a onlyEnlarge set to false (the default), and all subsequent set to true. - + \see rescaleKeyAxis, rescaleValueAxis, QCustomPlot::rescaleAxes, QCPAxis::rescale */ void QCPAbstractPlottable::rescaleAxes(bool onlyEnlarge) const @@ -11715,18 +11735,18 @@ void QCPAbstractPlottable::rescaleAxes(bool onlyEnlarge) const /*! Rescales the key axis of the plottable so the whole plottable is visible. - + See \ref rescaleAxes for detailed behaviour. */ void QCPAbstractPlottable::rescaleKeyAxis(bool onlyEnlarge) const { QCPAxis *keyAxis = mKeyAxis.data(); if (!keyAxis) { qDebug() << Q_FUNC_INFO << "invalid key axis"; return; } - + QCP::SignDomain signDomain = QCP::sdBoth; if (keyAxis->scaleType() == QCPAxis::stLogarithmic) signDomain = (keyAxis->range().upper < 0 ? QCP::sdNegative : QCP::sdPositive); - + bool foundRange; QCPRange newRange = getKeyRange(foundRange, signDomain); if (foundRange) @@ -11765,11 +11785,11 @@ void QCPAbstractPlottable::rescaleValueAxis(bool onlyEnlarge, bool inKeyRange) c QCPAxis *keyAxis = mKeyAxis.data(); QCPAxis *valueAxis = mValueAxis.data(); if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - + QCP::SignDomain signDomain = QCP::sdBoth; if (valueAxis->scaleType() == QCPAxis::stLogarithmic) signDomain = (valueAxis->range().upper < 0 ? QCP::sdNegative : QCP::sdPositive); - + bool foundRange; QCPRange newRange = getValueRange(foundRange, signDomain, inKeyRange ? keyAxis->range() : QCPRange()); if (foundRange) @@ -11819,7 +11839,7 @@ bool QCPAbstractPlottable::addToLegend(QCPLegend *legend) qDebug() << Q_FUNC_INFO << "passed legend isn't in the same QCustomPlot as this plottable"; return false; } - + if (!legend->hasItemWithPlottable(this)) { legend->addItem(new QCPPlottableLegendItem(legend, this)); @@ -11859,7 +11879,7 @@ bool QCPAbstractPlottable::removeFromLegend(QCPLegend *legend) const qDebug() << Q_FUNC_INFO << "passed legend is null"; return false; } - + if (QCPPlottableLegendItem *lip = legend->itemWithPlottable(this)) return legend->removeItem(lip); else @@ -11901,13 +11921,13 @@ QCP::Interaction QCPAbstractPlottable::selectionCategory() const before drawing plottable lines. This is the antialiasing state the painter passed to the \ref draw method is in by default. - + This function takes into account the local setting of the antialiasing flag as well as the overrides set with \ref QCustomPlot::setAntialiasedElements and \ref QCustomPlot::setNotAntialiasedElements. - + \seebaseclassmethod - + \see setAntialiased, applyFillAntialiasingHint, applyScattersAntialiasingHint */ void QCPAbstractPlottable::applyDefaultAntialiasingHint(QCPPainter *painter) const @@ -11919,11 +11939,11 @@ void QCPAbstractPlottable::applyDefaultAntialiasingHint(QCPPainter *painter) con A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter before drawing plottable fills. - + This function takes into account the local setting of the antialiasing flag as well as the overrides set with \ref QCustomPlot::setAntialiasedElements and \ref QCustomPlot::setNotAntialiasedElements. - + \see setAntialiased, applyDefaultAntialiasingHint, applyScattersAntialiasingHint */ void QCPAbstractPlottable::applyFillAntialiasingHint(QCPPainter *painter) const @@ -11935,11 +11955,11 @@ void QCPAbstractPlottable::applyFillAntialiasingHint(QCPPainter *painter) const A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter before drawing plottable scatter points. - + This function takes into account the local setting of the antialiasing flag as well as the overrides set with \ref QCustomPlot::setAntialiasedElements and \ref QCustomPlot::setNotAntialiasedElements. - + \see setAntialiased, applyFillAntialiasingHint, applyDefaultAntialiasingHint */ void QCPAbstractPlottable::applyScattersAntialiasingHint(QCPPainter *painter) const @@ -11951,7 +11971,7 @@ void QCPAbstractPlottable::applyScattersAntialiasingHint(QCPPainter *painter) co void QCPAbstractPlottable::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) { Q_UNUSED(event) - + if (mSelectable != QCP::stNone) { QCPDataSelection newSelection = details.value(); @@ -12001,7 +12021,7 @@ void QCPAbstractPlottable::deselectEvent(bool *selectionStateChanged) /*! \class QCPItemAnchor \brief An anchor of an item to which positions can be attached to. - + An item (QCPAbstractItem) may have one or more anchors. Unlike QCPItemPosition, an anchor doesn't control anything on its item, but provides a way to tie other items via their positions to the anchor. @@ -12012,10 +12032,10 @@ void QCPAbstractPlottable::deselectEvent(bool *selectionStateChanged) calling QCPItemPosition::setParentAnchor on \a start, passing the wanted anchor of the QCPItemRect. This way the start of the line will now always follow the respective anchor location on the rect item. - + Note that QCPItemPosition derives from QCPItemAnchor, so every position can also serve as an anchor to other positions. - + To learn how to provide anchors in your own item subclasses, see the subclassing section of the QCPAbstractItem documentation. */ @@ -12023,10 +12043,10 @@ void QCPAbstractPlottable::deselectEvent(bool *selectionStateChanged) /* start documentation of inline functions */ /*! \fn virtual QCPItemPosition *QCPItemAnchor::toQCPItemPosition() - + Returns \c nullptr if this instance is merely a QCPItemAnchor, and a valid pointer of type QCPItemPosition* if it actually is a QCPItemPosition (which is a subclass of QCPItemAnchor). - + This safe downcast functionality could also be achieved with a dynamic_cast. However, QCustomPlot avoids dynamic_cast to work with projects that don't have RTTI support enabled (e.g. -fno-rtti flag with gcc compiler). @@ -12064,7 +12084,7 @@ QCPItemAnchor::~QCPItemAnchor() /*! Returns the final absolute pixel position of the QCPItemAnchor on the QCustomPlot surface. - + The pixel information is internally retrieved via QCPAbstractItem::anchorPixelPosition of the parent item, QCPItemAnchor is just an intermediary. */ @@ -12092,7 +12112,7 @@ QPointF QCPItemAnchor::pixelPosition() const Adds \a pos to the childX list of this anchor, which keeps track of which children use this anchor as parent anchor for the respective coordinate. This is necessary to notify the children prior to destruction of the anchor. - + Note that this function does not change the parent setting in \a pos. */ void QCPItemAnchor::addChildX(QCPItemPosition *pos) @@ -12106,7 +12126,7 @@ void QCPItemAnchor::addChildX(QCPItemPosition *pos) /*! \internal Removes \a pos from the childX list of this anchor. - + Note that this function does not change the parent setting in \a pos. */ void QCPItemAnchor::removeChildX(QCPItemPosition *pos) @@ -12120,7 +12140,7 @@ void QCPItemAnchor::removeChildX(QCPItemPosition *pos) Adds \a pos to the childY list of this anchor, which keeps track of which children use this anchor as parent anchor for the respective coordinate. This is necessary to notify the children prior to destruction of the anchor. - + Note that this function does not change the parent setting in \a pos. */ void QCPItemAnchor::addChildY(QCPItemPosition *pos) @@ -12134,7 +12154,7 @@ void QCPItemAnchor::addChildY(QCPItemPosition *pos) /*! \internal Removes \a pos from the childY list of this anchor. - + Note that this function does not change the parent setting in \a pos. */ void QCPItemAnchor::removeChildY(QCPItemPosition *pos) @@ -12150,7 +12170,7 @@ void QCPItemAnchor::removeChildY(QCPItemPosition *pos) /*! \class QCPItemPosition \brief Manages the position of an item. - + Every item has at least one public QCPItemPosition member pointer which provides ways to position the item on the QCustomPlot surface. Some items have multiple positions, for example QCPItemRect has two: \a topLeft and \a bottomRight. @@ -12186,23 +12206,23 @@ void QCPItemAnchor::removeChildY(QCPItemPosition *pos) /* start documentation of inline functions */ /*! \fn QCPItemPosition::PositionType *QCPItemPosition::type() const - + Returns the current position type. - + If different types were set for X and Y (\ref setTypeX, \ref setTypeY), this method returns the type of the X coordinate. In that case rather use \a typeX() and \a typeY(). - + \see setType */ /*! \fn QCPItemAnchor *QCPItemPosition::parentAnchor() const - + Returns the current parent anchor. - + If different parent anchors were set for X and Y (\ref setParentAnchorX, \ref setParentAnchorY), this method returns the parent anchor of the Y coordinate. In that case rather use \a parentAnchorX() and \a parentAnchorY(). - + \see setParentAnchor */ @@ -12255,25 +12275,25 @@ QCPAxisRect *QCPItemPosition::axisRect() const /*! Sets the type of the position. The type defines how the coordinates passed to \ref setCoords should be handled and how the QCPItemPosition should behave in the plot. - + The possible values for \a type can be separated in two main categories: \li The position is regarded as a point in plot coordinates. This corresponds to \ref ptPlotCoords and requires two axes that define the plot coordinate system. They can be specified with \ref setAxes. By default, the QCustomPlot's x- and yAxis are used. - + \li The position is fixed on the QCustomPlot surface, i.e. independent of axis ranges. This corresponds to all other types, i.e. \ref ptAbsolute, \ref ptViewportRatio and \ref ptAxisRectRatio. They differ only in the way the absolute position is described, see the documentation of \ref PositionType for details. For \ref ptAxisRectRatio, note that you can specify the axis rect with \ref setAxisRect. By default this is set to the main axis rect. - + Note that the position type \ref ptPlotCoords is only available (and sensible) when the position has no parent anchor (\ref setParentAnchor). - + If the type is changed, the apparent pixel position on the plot is preserved. This means the coordinates as retrieved with coords() and set with \ref setCoords may change in the process. - + This method sets the type for both X and Y directions. It is also possible to set different types for X and Y, see \ref setTypeX, \ref setTypeY. */ @@ -12285,9 +12305,9 @@ void QCPItemPosition::setType(QCPItemPosition::PositionType type) /*! This method sets the position type of the X coordinate to \a type. - + For a detailed description of what a position type is, see the documentation of \ref setType. - + \see setType, setTypeY */ void QCPItemPosition::setTypeX(QCPItemPosition::PositionType type) @@ -12301,13 +12321,13 @@ void QCPItemPosition::setTypeX(QCPItemPosition::PositionType type) retainPixelPosition = false; if ((mPositionTypeX == ptAxisRectRatio || type == ptAxisRectRatio) && (!mAxisRect)) retainPixelPosition = false; - + QPointF pixel; if (retainPixelPosition) pixel = pixelPosition(); - + mPositionTypeX = type; - + if (retainPixelPosition) setPixelPosition(pixel); } @@ -12315,9 +12335,9 @@ void QCPItemPosition::setTypeX(QCPItemPosition::PositionType type) /*! This method sets the position type of the Y coordinate to \a type. - + For a detailed description of what a position type is, see the documentation of \ref setType. - + \see setType, setTypeX */ void QCPItemPosition::setTypeY(QCPItemPosition::PositionType type) @@ -12331,13 +12351,13 @@ void QCPItemPosition::setTypeY(QCPItemPosition::PositionType type) retainPixelPosition = false; if ((mPositionTypeY == ptAxisRectRatio || type == ptAxisRectRatio) && (!mAxisRect)) retainPixelPosition = false; - + QPointF pixel; if (retainPixelPosition) pixel = pixelPosition(); - + mPositionTypeY = type; - + if (retainPixelPosition) setPixelPosition(pixel); } @@ -12348,16 +12368,16 @@ void QCPItemPosition::setTypeY(QCPItemPosition::PositionType type) follow any position changes of the anchor. The local coordinate system of positions with a parent anchor always is absolute pixels, with (0, 0) being exactly on top of the parent anchor. (Hence the type shouldn't be set to \ref ptPlotCoords for positions with parent anchors.) - + if \a keepPixelPosition is true, the current pixel position of the QCPItemPosition is preserved during reparenting. If it's set to false, the coordinates are set to (0, 0), i.e. the position will be exactly on top of the parent anchor. - + To remove this QCPItemPosition from any parent anchor, set \a parentAnchor to \c nullptr. - + If the QCPItemPosition previously had no parent and the type is \ref ptPlotCoords, the type is set to \ref ptAbsolute, to keep the position in a valid state. - + This method sets the parent anchor for both X and Y directions. It is also possible to set different parents for X and Y, see \ref setParentAnchorX, \ref setParentAnchorY. */ @@ -12370,9 +12390,9 @@ bool QCPItemPosition::setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixe /*! This method sets the parent anchor of the X coordinate to \a parentAnchor. - + For a detailed description of what a parent anchor is, see the documentation of \ref setParentAnchor. - + \see setParentAnchor, setParentAnchorY */ bool QCPItemPosition::setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition) @@ -12409,11 +12429,11 @@ bool QCPItemPosition::setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPix break; } } - + // if previously no parent set and PosType is still ptPlotCoords, set to ptAbsolute: if (!mParentAnchorX && mPositionTypeX == ptPlotCoords) setTypeX(ptAbsolute); - + // save pixel position: QPointF pixelP; if (keepPixelPosition) @@ -12435,9 +12455,9 @@ bool QCPItemPosition::setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPix /*! This method sets the parent anchor of the Y coordinate to \a parentAnchor. - + For a detailed description of what a parent anchor is, see the documentation of \ref setParentAnchor. - + \see setParentAnchor, setParentAnchorX */ bool QCPItemPosition::setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition) @@ -12474,11 +12494,11 @@ bool QCPItemPosition::setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPix break; } } - + // if previously no parent set and PosType is still ptPlotCoords, set to ptAbsolute: if (!mParentAnchorY && mPositionTypeY == ptPlotCoords) setTypeY(ptAbsolute); - + // save pixel position: QPointF pixelP; if (keepPixelPosition) @@ -12501,14 +12521,14 @@ bool QCPItemPosition::setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPix /*! Sets the coordinates of this QCPItemPosition. What the coordinates mean, is defined by the type (\ref setType, \ref setTypeX, \ref setTypeY). - + For example, if the type is \ref ptAbsolute, \a key and \a value mean the x and y pixel position on the QCustomPlot surface. In that case the origin (0, 0) is in the top left corner of the QCustomPlot viewport. If the type is \ref ptPlotCoords, \a key and \a value mean a point in the plot coordinate system defined by the axes set by \ref setAxes. By default those are the QCustomPlot's xAxis and yAxis. See the documentation of \ref setType for other available coordinate types and their meaning. - + If different types were configured for X and Y (\ref setTypeX, \ref setTypeY), \a key and \a value must also be provided in the different coordinate systems. Here, the X type refers to \a key, and the Y type refers to \a value. @@ -12540,7 +12560,7 @@ void QCPItemPosition::setCoords(const QPointF &pos) QPointF QCPItemPosition::pixelPosition() const { QPointF result; - + // determine X: switch (mPositionTypeX) { @@ -12584,7 +12604,7 @@ QPointF QCPItemPosition::pixelPosition() const break; } } - + // determine Y: switch (mPositionTypeY) { @@ -12628,7 +12648,7 @@ QPointF QCPItemPosition::pixelPosition() const break; } } - + return result; } @@ -12667,7 +12687,7 @@ void QCPItemPosition::setPixelPosition(const QPointF &pixelPosition) { double x = pixelPosition.x(); double y = pixelPosition.y(); - + switch (mPositionTypeX) { case ptAbsolute: @@ -12709,7 +12729,7 @@ void QCPItemPosition::setPixelPosition(const QPointF &pixelPosition) break; } } - + switch (mPositionTypeY) { case ptAbsolute: @@ -12751,7 +12771,7 @@ void QCPItemPosition::setPixelPosition(const QPointF &pixelPosition) break; } } - + setCoords(x, y); } @@ -12762,18 +12782,18 @@ void QCPItemPosition::setPixelPosition(const QPointF &pixelPosition) /*! \class QCPAbstractItem \brief The abstract base class for all items in a plot. - + In QCustomPlot, items are supplemental graphical elements that are neither plottables (QCPAbstractPlottable) nor axes (QCPAxis). While plottables are always tied to two axes and thus plot coordinates, items can also be placed in absolute coordinates independent of any axes. Each specific item has at least one QCPItemPosition member which controls the positioning. Some items are defined by more than one coordinate and thus have two or more QCPItemPosition members (For example, QCPItemRect has \a topLeft and \a bottomRight). - + This abstract base class defines a very basic interface like visibility and clipping. Since this class is abstract, it can't be instantiated. Use one of the subclasses or create a subclass yourself to create new items. - + The built-in items are:
@@ -12786,7 +12806,7 @@ void QCPItemPosition::setPixelPosition(const QPointF &pixelPosition)
QCPItemLineA line defined by a start and an end point. May have different ending styles on each side (e.g. arrows).
QCPItemBracketA bracket which may be used to reference/highlight certain parts in the plot.
QCPItemTracerAn item that can be attached to a QCPGraph and sticks to its data points, given a key coordinate.
- + \section items-clipping Clipping Items are by default clipped to the main axis rect (they are only visible inside the axis rect). @@ -12798,9 +12818,9 @@ void QCPItemPosition::setPixelPosition(const QPointF &pixelPosition) in principle is independent of the coordinate axes the item might be tied to via its position members (\ref QCPItemPosition::setAxes). However, it is common that the axis rect for clipping also contains the axes used for the item positions. - + \section items-using Using items - + First you instantiate the item you want to use and add it to the plot: \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-1 by default, the positions of the item are bound to the x- and y-Axis of the plot. So we can just @@ -12813,35 +12833,35 @@ void QCPItemPosition::setPixelPosition(const QPointF &pixelPosition) \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-4 and make the line visible on the entire QCustomPlot, by disabling clipping to the axis rect: \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-5 - + For more advanced plots, it is even possible to set different types and parent anchors per X/Y coordinate of an item position, using for example \ref QCPItemPosition::setTypeX or \ref QCPItemPosition::setParentAnchorX. For details, see the documentation of \ref QCPItemPosition. - + \section items-subclassing Creating own items - + To create an own item, you implement a subclass of QCPAbstractItem. These are the pure virtual functions, you must implement: \li \ref selectTest \li \ref draw - + See the documentation of those functions for what they need to do. - + \subsection items-positioning Allowing the item to be positioned - + As mentioned, item positions are represented by QCPItemPosition members. Let's assume the new item shall have only one point as its position (as opposed to two like a rect or multiple like a polygon). You then add a public member of type QCPItemPosition like so: - + \code QCPItemPosition * const myPosition;\endcode - + the const makes sure the pointer itself can't be modified from the user of your new item (the QCPItemPosition instance it points to, can be modified, of course). The initialization of this pointer is made easy with the \ref createPosition function. Just assign the return value of this function to each QCPItemPosition in the constructor of your item. \ref createPosition takes a string which is the name of the position, typically this is identical to the variable name. For example, the constructor of QCPItemExample could look like this: - + \code QCPItemExample::QCPItemExample(QCustomPlot *parentPlot) : QCPAbstractItem(parentPlot), @@ -12850,9 +12870,9 @@ void QCPItemPosition::setPixelPosition(const QPointF &pixelPosition) // other constructor code } \endcode - + \subsection items-drawing The draw function - + To give your item a visual representation, reimplement the \ref draw function and use the passed QCPPainter to draw the item. You can retrieve the item position in pixel coordinates from the position member(s) via \ref QCPItemPosition::pixelPosition. @@ -12860,19 +12880,19 @@ void QCPItemPosition::setPixelPosition(const QPointF &pixelPosition) To optimize performance you should calculate a bounding rect first (don't forget to take the pen width into account), check whether it intersects the \ref clipRect, and only draw the item at all if this is the case. - + \subsection items-selection The selectTest function - + Your implementation of the \ref selectTest function may use the helpers \ref QCPVector2D::distanceSquaredToLine and \ref rectDistance. With these, the implementation of the selection test becomes significantly simpler for most items. See the documentation of \ref selectTest for what the function parameters mean and what the function should return. - + \subsection anchors Providing anchors - + Providing anchors (QCPItemAnchor) starts off like adding a position. First you create a public member, e.g. - + \code QCPItemAnchor * const bottom;\endcode and create it in the constructor with the \ref createAnchor function, assigning it a name and an @@ -12880,7 +12900,7 @@ void QCPItemPosition::setPixelPosition(const QPointF &pixelPosition) Since anchors can be placed anywhere, relative to the item's position(s), your item needs to provide the position of every anchor with the reimplementation of the \ref anchorPixelPosition(int anchorId) function. - + In essence the QCPItemAnchor is merely an intermediary that itself asks your item for the pixel position when anything attached to the anchor needs to know the coordinates. */ @@ -12888,17 +12908,17 @@ void QCPItemPosition::setPixelPosition(const QPointF &pixelPosition) /* start of documentation of inline functions */ /*! \fn QList QCPAbstractItem::positions() const - + Returns all positions of the item in a list. - + \see anchors, position */ /*! \fn QList QCPAbstractItem::anchors() const - + Returns all anchors of the item in a list. Note that since a position (QCPItemPosition) is always also an anchor, the list will also contain the positions of this item. - + \see positions, anchor */ @@ -12907,9 +12927,9 @@ void QCPItemPosition::setPixelPosition(const QPointF &pixelPosition) /*! \fn void QCPAbstractItem::draw(QCPPainter *painter) = 0 \internal - + Draws this item with the provided \a painter. - + The cliprect of the provided painter is set to the rect returned by \ref clipRect before this function is called. The clipRect depends on the clipping settings defined by \ref setClipToAxisRect and \ref setClipAxisRect. @@ -12935,7 +12955,7 @@ QCPAbstractItem::QCPAbstractItem(QCustomPlot *parentPlot) : mSelected(false) { parentPlot->registerItem(this); - + QList rects = parentPlot->axisRects(); if (!rects.isEmpty()) { @@ -12959,7 +12979,7 @@ QCPAxisRect *QCPAbstractItem::clipAxisRect() const /*! Sets whether the item shall be clipped to an axis rect or whether it shall be visible on the entire QCustomPlot. The axis rect can be set with \ref setClipAxisRect. - + \see setClipAxisRect */ void QCPAbstractItem::setClipToAxisRect(bool clip) @@ -12972,7 +12992,7 @@ void QCPAbstractItem::setClipToAxisRect(bool clip) /*! Sets the clip axis rect. It defines the rect that will be used to clip the item when \ref setClipToAxisRect is set to true. - + \see setClipToAxisRect */ void QCPAbstractItem::setClipAxisRect(QCPAxisRect *rect) @@ -12985,10 +13005,10 @@ void QCPAbstractItem::setClipAxisRect(QCPAxisRect *rect) /*! Sets whether the user can (de-)select this item by clicking on the QCustomPlot surface. (When \ref QCustomPlot::setInteractions contains QCustomPlot::iSelectItems.) - + However, even when \a selectable was set to false, it is possible to set the selection manually, by calling \ref setSelected. - + \see QCustomPlot::setInteractions, setSelected */ void QCPAbstractItem::setSelectable(bool selectable) @@ -13007,11 +13027,11 @@ void QCPAbstractItem::setSelectable(bool selectable) The entire selection mechanism for items is handled automatically when \ref QCustomPlot::setInteractions contains QCustomPlot::iSelectItems. You only need to call this function when you wish to change the selection state manually. - + This function can change the selection state even when \ref setSelectable was set to false. - + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. - + \see setSelectable, selectTest */ void QCPAbstractItem::setSelected(bool selected) @@ -13026,11 +13046,11 @@ void QCPAbstractItem::setSelected(bool selected) /*! Returns the QCPItemPosition with the specified \a name. If this item doesn't have a position by that name, returns \c nullptr. - + This function provides an alternative way to access item positions. Normally, you access positions direcly by their member pointers (which typically have the same variable name as \a name). - + \see positions, anchor */ QCPItemPosition *QCPAbstractItem::position(const QString &name) const @@ -13047,11 +13067,11 @@ QCPItemPosition *QCPAbstractItem::position(const QString &name) const /*! Returns the QCPItemAnchor with the specified \a name. If this item doesn't have an anchor by that name, returns \c nullptr. - + This function provides an alternative way to access item anchors. Normally, you access anchors direcly by their member pointers (which typically have the same variable name as \a name). - + \see anchors, position */ QCPItemAnchor *QCPAbstractItem::anchor(const QString &name) const @@ -13067,10 +13087,10 @@ QCPItemAnchor *QCPAbstractItem::anchor(const QString &name) const /*! Returns whether this item has an anchor with the specified \a name. - + Note that you can check for positions with this function, too. This is because every position is also an anchor (QCPItemPosition inherits from QCPItemAnchor). - + \see anchor, position */ bool QCPAbstractItem::hasAnchor(const QString &name) const @@ -13084,12 +13104,12 @@ bool QCPAbstractItem::hasAnchor(const QString &name) const } /*! \internal - + Returns the rect the visual representation of this item is clipped to. This depends on the current setting of \ref setClipToAxisRect as well as the axis rect set with \ref setClipAxisRect. - + If the item is not clipped to an axis rect, QCustomPlot's viewport rect is returned. - + \see draw */ QRect QCPAbstractItem::clipRect() const @@ -13106,11 +13126,11 @@ QRect QCPAbstractItem::clipRect() const before drawing item lines. This is the antialiasing state the painter passed to the \ref draw method is in by default. - + This function takes into account the local setting of the antialiasing flag as well as the overrides set with \ref QCustomPlot::setAntialiasedElements and \ref QCustomPlot::setNotAntialiasedElements. - + \see setAntialiased */ void QCPAbstractItem::applyDefaultAntialiasingHint(QCPPainter *painter) const @@ -13123,10 +13143,10 @@ void QCPAbstractItem::applyDefaultAntialiasingHint(QCPPainter *painter) const A convenience function which returns the selectTest value for a specified \a rect and a specified click position \a pos. \a filledRect defines whether a click inside the rect should also be considered a hit or whether only the rect border is sensitive to hits. - + This function may be used to help with the implementation of the \ref selectTest function for specific items. - + For example, if your item consists of four rects, call this function four times, once for each rect, in your \ref selectTest reimplementation. Finally, return the minimum (non -1) of all four returned values. @@ -13147,7 +13167,7 @@ double QCPAbstractItem::rectDistance(const QRectF &rect, const QPointF &pos, boo minDistSqr = distSqr; } result = qSqrt(minDistSqr); - + // filled rect, allow click inside to count as hit: if (filledRect && result > mParentPlot->selectionTolerance()*0.99) { @@ -13161,10 +13181,10 @@ double QCPAbstractItem::rectDistance(const QRectF &rect, const QPointF &pos, boo Returns the pixel position of the anchor with Id \a anchorId. This function must be reimplemented in item subclasses if they want to provide anchors (QCPItemAnchor). - + For example, if the item has two anchors with id 0 and 1, this function takes one of these anchor ids and returns the respective pixel points of the specified anchor. - + \see createAnchor */ QPointF QCPAbstractItem::anchorPixelPosition(int anchorId) const @@ -13178,13 +13198,13 @@ QPointF QCPAbstractItem::anchorPixelPosition(int anchorId) const Creates a QCPItemPosition, registers it with this item and returns a pointer to it. The specified \a name must be a unique string that is usually identical to the variable name of the position member (This is needed to provide the name-based \ref position access to positions). - + Don't delete positions created by this function manually, as the item will take care of it. - + Use this function in the constructor (initialization list) of the specific item subclass to create each position member. Don't create QCPItemPositions with \b new yourself, because they won't be registered with the item properly. - + \see createAnchor */ QCPItemPosition *QCPAbstractItem::createPosition(const QString &name) @@ -13207,18 +13227,18 @@ QCPItemPosition *QCPAbstractItem::createPosition(const QString &name) Creates a QCPItemAnchor, registers it with this item and returns a pointer to it. The specified \a name must be a unique string that is usually identical to the variable name of the anchor member (This is needed to provide the name based \ref anchor access to anchors). - + The \a anchorId must be a number identifying the created anchor. It is recommended to create an enum (e.g. "AnchorIndex") for this on each item that uses anchors. This id is used by the anchor to identify itself when it calls QCPAbstractItem::anchorPixelPosition. That function then returns the correct pixel coordinates for the passed anchor id. - + Don't delete anchors created by this function manually, as the item will take care of it. - + Use this function in the constructor (initialization list) of the specific item subclass to create each anchor member. Don't create QCPItemAnchors with \b new yourself, because then they won't be registered with the item properly. - + \see createPosition */ QCPItemAnchor *QCPAbstractItem::createAnchor(const QString &name, int anchorId) @@ -13272,10 +13292,10 @@ QCP::Interaction QCPAbstractItem::selectionCategory() const //////////////////////////////////////////////////////////////////////////////////////////////////// /*! \class QCustomPlot - + \brief The central class of the library. This is the QWidget which displays the plot and interacts with the user. - + For tutorials on how to use QCustomPlot, see the website\n https://www.qcustomplot.com/ */ @@ -13283,15 +13303,15 @@ QCP::Interaction QCPAbstractItem::selectionCategory() const /* start of documentation of inline functions */ /*! \fn QCPSelectionRect *QCustomPlot::selectionRect() const - + Allows access to the currently used QCPSelectionRect instance (or subclass thereof), that is used to handle and draw selection rect interactions (see \ref setSelectionRectMode). - + \see setSelectionRect */ /*! \fn QCPLayoutGrid *QCustomPlot::plotLayout() const - + Returns the top level layout of this QCustomPlot instance. It is a \ref QCPLayoutGrid, initially containing just one cell with the main QCPAxisRect inside. */ @@ -13307,7 +13327,7 @@ QCP::Interaction QCPAbstractItem::selectionCategory() const /*! \fn void QCustomPlot::mousePress(QMouseEvent *event) This signal is emitted when the QCustomPlot receives a mouse press event. - + It is emitted before QCustomPlot handles any other mechanism like range dragging. So a slot connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeDrag or \ref QCPAxisRect::setRangeDragAxes. @@ -13316,11 +13336,11 @@ QCP::Interaction QCPAbstractItem::selectionCategory() const /*! \fn void QCustomPlot::mouseMove(QMouseEvent *event) This signal is emitted when the QCustomPlot receives a mouse move event. - + It is emitted before QCustomPlot handles any other mechanism like range dragging. So a slot connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeDrag or \ref QCPAxisRect::setRangeDragAxes. - + \warning It is discouraged to change the drag-axes with \ref QCPAxisRect::setRangeDragAxes here, because the dragging starting point was saved the moment the mouse was pressed. Thus it only has a meaning for the range drag axes that were set at that moment. If you want to change the drag @@ -13330,7 +13350,7 @@ QCP::Interaction QCPAbstractItem::selectionCategory() const /*! \fn void QCustomPlot::mouseRelease(QMouseEvent *event) This signal is emitted when the QCustomPlot receives a mouse release event. - + It is emitted before QCustomPlot handles any other mechanisms like object selection. So a slot connected to this signal can still influence the behaviour e.g. with \ref setInteractions or \ref QCPAbstractPlottable::setSelectable. @@ -13339,7 +13359,7 @@ QCP::Interaction QCPAbstractItem::selectionCategory() const /*! \fn void QCustomPlot::mouseWheel(QMouseEvent *event) This signal is emitted when the QCustomPlot receives a mouse wheel event. - + It is emitted before QCustomPlot handles any other mechanisms like range zooming. So a slot connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeZoomAxes or \ref QCPAxisRect::setRangeZoomFactor. @@ -13368,93 +13388,93 @@ QCP::Interaction QCPAbstractItem::selectionCategory() const */ /*! \fn void QCustomPlot::itemClick(QCPAbstractItem *item, QMouseEvent *event) - + This signal is emitted when an item is clicked. \a event is the mouse event that caused the click and \a item is the item that received the click. - + \see itemDoubleClick */ /*! \fn void QCustomPlot::itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event) - + This signal is emitted when an item is double clicked. - + \a event is the mouse event that caused the click and \a item is the item that received the click. - + \see itemClick */ /*! \fn void QCustomPlot::axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event) - + This signal is emitted when an axis is clicked. - + \a event is the mouse event that caused the click, \a axis is the axis that received the click and \a part indicates the part of the axis that was clicked. - + \see axisDoubleClick */ /*! \fn void QCustomPlot::axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event) This signal is emitted when an axis is double clicked. - + \a event is the mouse event that caused the click, \a axis is the axis that received the click and \a part indicates the part of the axis that was clicked. - + \see axisClick */ /*! \fn void QCustomPlot::legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event) This signal is emitted when a legend (item) is clicked. - + \a event is the mouse event that caused the click, \a legend is the legend that received the click and \a item is the legend item that received the click. If only the legend and no item is clicked, \a item is \c nullptr. This happens for a click inside the legend padding or the space between two items. - + \see legendDoubleClick */ /*! \fn void QCustomPlot::legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event) This signal is emitted when a legend (item) is double clicked. - + \a event is the mouse event that caused the click, \a legend is the legend that received the click and \a item is the legend item that received the click. If only the legend and no item is clicked, \a item is \c nullptr. This happens for a click inside the legend padding or the space between two items. - + \see legendClick */ /*! \fn void QCustomPlot::selectionChangedByUser() - + This signal is emitted after the user has changed the selection in the QCustomPlot, e.g. by clicking. It is not emitted when the selection state of an object has changed programmatically by a direct call to setSelected()/setSelection() on an object or by calling \ref deselectAll. - + In addition to this signal, selectable objects also provide individual signals, for example \ref QCPAxis::selectionChanged or \ref QCPAbstractPlottable::selectionChanged. Note that those signals are emitted even if the selection state is changed programmatically. - + See the documentation of \ref setInteractions for details about the selection mechanism. - + \see selectedPlottables, selectedGraphs, selectedItems, selectedAxes, selectedLegends */ /*! \fn void QCustomPlot::beforeReplot() - + This signal is emitted immediately before a replot takes place (caused by a call to the slot \ref replot). - + It is safe to mutually connect the replot slot with this signal on two QCustomPlots to make them replot synchronously, it won't cause an infinite recursion. - + \see replot, afterReplot, afterLayout */ @@ -13480,13 +13500,13 @@ QCP::Interaction QCPAbstractItem::selectionCategory() const */ /*! \fn void QCustomPlot::afterReplot() - + This signal is emitted immediately after a replot has taken place (caused by a call to the slot \ref replot). - + It is safe to mutually connect the replot slot with this signal on two QCustomPlots to make them replot synchronously, it won't cause an infinite recursion. - + \see replot, beforeReplot, afterLayout */ @@ -13496,7 +13516,7 @@ QCP::Interaction QCPAbstractItem::selectionCategory() const /*! \var QCPAxis *QCustomPlot::xAxis A pointer to the primary x Axis (bottom) of the main axis rect of the plot. - + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref yAxis2) and the \ref legend. They make it very easy working with plots that only have a single axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the @@ -13504,7 +13524,7 @@ QCP::Interaction QCPAbstractItem::selectionCategory() const QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the default legend is removed due to manipulation of the layout system (e.g. by removing the main axis rect), the corresponding pointers become \c nullptr. - + If an axis convenience pointer is currently \c nullptr and a new axis rect or a corresponding axis is added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the according new axes. Similarly the \ref legend convenience pointer will be reset if a legend @@ -13514,7 +13534,7 @@ QCP::Interaction QCPAbstractItem::selectionCategory() const /*! \var QCPAxis *QCustomPlot::yAxis A pointer to the primary y Axis (left) of the main axis rect of the plot. - + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref yAxis2) and the \ref legend. They make it very easy working with plots that only have a single axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the @@ -13522,7 +13542,7 @@ QCP::Interaction QCPAbstractItem::selectionCategory() const QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the default legend is removed due to manipulation of the layout system (e.g. by removing the main axis rect), the corresponding pointers become \c nullptr. - + If an axis convenience pointer is currently \c nullptr and a new axis rect or a corresponding axis is added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the according new axes. Similarly the \ref legend convenience pointer will be reset if a legend @@ -13534,7 +13554,7 @@ QCP::Interaction QCPAbstractItem::selectionCategory() const A pointer to the secondary x Axis (top) of the main axis rect of the plot. Secondary axes are invisible by default. Use QCPAxis::setVisible to change this (or use \ref QCPAxisRect::setupFullAxesBox). - + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref yAxis2) and the \ref legend. They make it very easy working with plots that only have a single axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the @@ -13542,7 +13562,7 @@ QCP::Interaction QCPAbstractItem::selectionCategory() const QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the default legend is removed due to manipulation of the layout system (e.g. by removing the main axis rect), the corresponding pointers become \c nullptr. - + If an axis convenience pointer is currently \c nullptr and a new axis rect or a corresponding axis is added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the according new axes. Similarly the \ref legend convenience pointer will be reset if a legend @@ -13554,7 +13574,7 @@ QCP::Interaction QCPAbstractItem::selectionCategory() const A pointer to the secondary y Axis (right) of the main axis rect of the plot. Secondary axes are invisible by default. Use QCPAxis::setVisible to change this (or use \ref QCPAxisRect::setupFullAxesBox). - + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref yAxis2) and the \ref legend. They make it very easy working with plots that only have a single axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the @@ -13562,7 +13582,7 @@ QCP::Interaction QCPAbstractItem::selectionCategory() const QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the default legend is removed due to manipulation of the layout system (e.g. by removing the main axis rect), the corresponding pointers become \c nullptr. - + If an axis convenience pointer is currently \c nullptr and a new axis rect or a corresponding axis is added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the according new axes. Similarly the \ref legend convenience pointer will be reset if a legend @@ -13573,7 +13593,7 @@ QCP::Interaction QCPAbstractItem::selectionCategory() const A pointer to the default legend of the main axis rect. The legend is invisible by default. Use QCPLegend::setVisible to change this. - + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref yAxis2) and the \ref legend. They make it very easy working with plots that only have a single axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the @@ -13582,7 +13602,7 @@ QCP::Interaction QCPAbstractItem::selectionCategory() const QCPAxisRect::insetLayout "inset layout", and must then also be accessed via the inset layout. If the default legend is removed due to manipulation of the layout system (e.g. by removing the main axis rect), the corresponding pointer becomes \c nullptr. - + If an axis convenience pointer is currently \c nullptr and a new axis rect or a corresponding axis is added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the according new axes. Similarly the \ref legend convenience pointer will be reset if a legend @@ -13642,7 +13662,7 @@ QCustomPlot::QCustomPlot(QWidget *parent) : setBufferDevicePixelRatio(QWidget::devicePixelRatio()); # endif #endif - + mOpenGlAntialiasedElementsBackup = mAntialiasedElements; mOpenGlCacheLabelsBackup = mPlottingHints.testFlag(QCP::phCacheLabels); // create initial layers: @@ -13655,7 +13675,7 @@ QCustomPlot::QCustomPlot(QWidget *parent) : updateLayerIndices(); setCurrentLayer(QLatin1String("main")); layer(QLatin1String("overlay"))->setMode(QCPLayer::lmBuffered); - + // create initial layout, axis rect and legend: mPlotLayout = new QCPLayoutGrid; mPlotLayout->initializeParentPlot(this); @@ -13671,7 +13691,7 @@ QCustomPlot::QCustomPlot(QWidget *parent) : legend->setVisible(false); defaultAxisRect->insetLayout()->addElement(legend, Qt::AlignRight|Qt::AlignTop); defaultAxisRect->insetLayout()->setMargins(QMargins(12, 12, 12, 12)); - + defaultAxisRect->setLayer(QLatin1String("background")); xAxis->setLayer(QLatin1String("axes")); yAxis->setLayer(QLatin1String("axes")); @@ -13682,13 +13702,13 @@ QCustomPlot::QCustomPlot(QWidget *parent) : xAxis2->grid()->setLayer(QLatin1String("grid")); yAxis2->grid()->setLayer(QLatin1String("grid")); legend->setLayer(QLatin1String("legend")); - + // create selection rect instance: mSelectionRect = new QCPSelectionRect(this); mSelectionRect->setLayer(QLatin1String("overlay")); - + setViewport(rect()); // needs to be called after mPlotLayout has been created - + replot(rpQueuedReplot); } @@ -13702,7 +13722,7 @@ QCustomPlot::~QCustomPlot() delete mPlotLayout; mPlotLayout = nullptr; } - + mCurrentLayer = nullptr; qDeleteAll(mLayers); // don't use removeLayer, because it would prevent the last layer to be removed mLayers.clear(); @@ -13710,25 +13730,25 @@ QCustomPlot::~QCustomPlot() /*! Sets which elements are forcibly drawn antialiased as an \a or combination of QCP::AntialiasedElement. - + This overrides the antialiasing settings for whole element groups, normally controlled with the \a setAntialiasing function on the individual elements. If an element is neither specified in \ref setAntialiasedElements nor in \ref setNotAntialiasedElements, the antialiasing setting on each individual element instance is used. - + For example, if \a antialiasedElements contains \ref QCP::aePlottables, all plottables will be drawn antialiased, no matter what the specific QCPAbstractPlottable::setAntialiased value was set to. - + if an element in \a antialiasedElements is already set in \ref setNotAntialiasedElements, it is removed from there. - + \see setNotAntialiasedElements */ void QCustomPlot::setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements) { mAntialiasedElements = antialiasedElements; - + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: if ((mNotAntialiasedElements & mAntialiasedElements) != 0) mNotAntialiasedElements |= ~mAntialiasedElements; @@ -13736,9 +13756,9 @@ void QCustomPlot::setAntialiasedElements(const QCP::AntialiasedElements &antiali /*! Sets whether the specified \a antialiasedElement is forcibly drawn antialiased. - + See \ref setAntialiasedElements for details. - + \see setNotAntialiasedElement */ void QCustomPlot::setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled) @@ -13747,7 +13767,7 @@ void QCustomPlot::setAntialiasedElement(QCP::AntialiasedElement antialiasedEleme mAntialiasedElements &= ~antialiasedElement; else if (enabled && !mAntialiasedElements.testFlag(antialiasedElement)) mAntialiasedElements |= antialiasedElement; - + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: if ((mNotAntialiasedElements & mAntialiasedElements) != 0) mNotAntialiasedElements |= ~mAntialiasedElements; @@ -13756,25 +13776,25 @@ void QCustomPlot::setAntialiasedElement(QCP::AntialiasedElement antialiasedEleme /*! Sets which elements are forcibly drawn not antialiased as an \a or combination of QCP::AntialiasedElement. - + This overrides the antialiasing settings for whole element groups, normally controlled with the \a setAntialiasing function on the individual elements. If an element is neither specified in \ref setAntialiasedElements nor in \ref setNotAntialiasedElements, the antialiasing setting on each individual element instance is used. - + For example, if \a notAntialiasedElements contains \ref QCP::aePlottables, no plottables will be drawn antialiased, no matter what the specific QCPAbstractPlottable::setAntialiased value was set to. - + if an element in \a notAntialiasedElements is already set in \ref setAntialiasedElements, it is removed from there. - + \see setAntialiasedElements */ void QCustomPlot::setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements) { mNotAntialiasedElements = notAntialiasedElements; - + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: if ((mNotAntialiasedElements & mAntialiasedElements) != 0) mAntialiasedElements |= ~mNotAntialiasedElements; @@ -13782,9 +13802,9 @@ void QCustomPlot::setNotAntialiasedElements(const QCP::AntialiasedElements ¬A /*! Sets whether the specified \a notAntialiasedElement is forcibly drawn not antialiased. - + See \ref setNotAntialiasedElements for details. - + \see setAntialiasedElement */ void QCustomPlot::setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled) @@ -13793,7 +13813,7 @@ void QCustomPlot::setNotAntialiasedElement(QCP::AntialiasedElement notAntialiase mNotAntialiasedElements &= ~notAntialiasedElement; else if (enabled && !mNotAntialiasedElements.testFlag(notAntialiasedElement)) mNotAntialiasedElements |= notAntialiasedElement; - + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: if ((mNotAntialiasedElements & mAntialiasedElements) != 0) mAntialiasedElements |= ~mNotAntialiasedElements; @@ -13802,7 +13822,7 @@ void QCustomPlot::setNotAntialiasedElement(QCP::AntialiasedElement notAntialiase /*! If set to true, adding a plottable (e.g. a graph) to the QCustomPlot automatically also adds the plottable to the legend (QCustomPlot::legend). - + \see addGraph, QCPLegend::addItem */ void QCustomPlot::setAutoAddPlottableToLegend(bool on) @@ -13813,13 +13833,13 @@ void QCustomPlot::setAutoAddPlottableToLegend(bool on) /*! Sets the possible interactions of this QCustomPlot as an or-combination of \ref QCP::Interaction enums. There are the following types of interactions: - + Axis range manipulation is controlled via \ref QCP::iRangeDrag and \ref QCP::iRangeZoom. When the respective interaction is enabled, the user may drag axes ranges and zoom with the mouse wheel. For details how to control which axes the user may drag/zoom and in what orientations, see \ref QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeDragAxes, \ref QCPAxisRect::setRangeZoomAxes. - + Plottable data selection is controlled by \ref QCP::iSelectPlottables. If \ref QCP::iSelectPlottables is set, the user may select plottables (graphs, curves, bars,...) and their data by clicking on them or in their vicinity (\ref setSelectionTolerance). Whether the @@ -13828,40 +13848,40 @@ void QCustomPlot::setAutoAddPlottableToLegend(bool on) special page about the \ref dataselection "data selection mechanism". To retrieve a list of all currently selected plottables, call \ref selectedPlottables. If you're only interested in QCPGraphs, you may use the convenience function \ref selectedGraphs. - + Item selection is controlled by \ref QCP::iSelectItems. If \ref QCP::iSelectItems is set, the user may select items (QCPItemLine, QCPItemText,...) by clicking on them or in their vicinity. To find out whether a specific item is selected, call QCPAbstractItem::selected(). To retrieve a list of all currently selected items, call \ref selectedItems. - + Axis selection is controlled with \ref QCP::iSelectAxes. If \ref QCP::iSelectAxes is set, the user may select parts of the axes by clicking on them. What parts exactly (e.g. Axis base line, tick labels, axis label) are selectable can be controlled via \ref QCPAxis::setSelectableParts for each axis. To retrieve a list of all axes that currently contain selected parts, call \ref selectedAxes. Which parts of an axis are selected, can be retrieved with QCPAxis::selectedParts(). - + Legend selection is controlled with \ref QCP::iSelectLegend. If this is set, the user may select the legend itself or individual items by clicking on them. What parts exactly are selectable can be controlled via \ref QCPLegend::setSelectableParts. To find out whether the legend or any of its child items are selected, check the value of QCPLegend::selectedParts. To find out which child items are selected, call \ref QCPLegend::selectedItems. - + All other selectable elements The selection of all other selectable objects (e.g. QCPTextElement, or your own layerable subclasses) is controlled with \ref QCP::iSelectOther. If set, the user may select those objects by clicking on them. To find out which are currently selected, you need to check their selected state explicitly. - + If the selection state has changed by user interaction, the \ref selectionChangedByUser signal is emitted. Each selectable object additionally emits an individual selectionChanged signal whenever their selection state has changed, i.e. not only by user interaction. - + To allow multiple objects to be selected by holding the selection modifier (\ref setMultiSelectModifier), set the flag \ref QCP::iMultiSelect. - + \note In addition to the selection mechanism presented here, QCustomPlot always emits corresponding signals, when an object is clicked or double clicked. see \ref plottableClick and \ref plottableDoubleClick for example. - + \see setInteraction, setSelectionTolerance */ void QCustomPlot::setInteractions(const QCP::Interactions &interactions) @@ -13871,9 +13891,9 @@ void QCustomPlot::setInteractions(const QCP::Interactions &interactions) /*! Sets the single \a interaction of this QCustomPlot to \a enabled. - + For details about the interaction system, see \ref setInteractions. - + \see setInteractions */ void QCustomPlot::setInteraction(const QCP::Interaction &interaction, bool enabled) @@ -13887,14 +13907,14 @@ void QCustomPlot::setInteraction(const QCP::Interaction &interaction, bool enabl /*! Sets the tolerance that is used to decide whether a click selects an object (e.g. a plottable) or not. - + If the user clicks in the vicinity of the line of e.g. a QCPGraph, it's only regarded as a potential selection when the minimum distance between the click position and the graph line is smaller than \a pixels. Objects that are defined by an area (e.g. QCPBars) only react to clicks directly inside the area and ignore this selection tolerance. In other words, it only has meaning for parts of objects that are too thin to exactly hit with a click and thus need such a tolerance. - + \see setInteractions, QCPLayerable::selectTest */ void QCustomPlot::setSelectionTolerance(int pixels) @@ -13908,7 +13928,7 @@ void QCustomPlot::setSelectionTolerance(int pixels) performance during dragging. Thus it creates a more responsive user experience. As soon as the user stops dragging, the last replot is done with normal antialiasing, to restore high image quality. - + \see setAntialiasedElements, setNotAntialiasedElements */ void QCustomPlot::setNoAntialiasingOnDrag(bool enabled) @@ -13918,7 +13938,7 @@ void QCustomPlot::setNoAntialiasingOnDrag(bool enabled) /*! Sets the plotting hints for this QCustomPlot instance as an \a or combination of QCP::PlottingHint. - + \see setPlottingHint */ void QCustomPlot::setPlottingHints(const QCP::PlottingHints &hints) @@ -13928,7 +13948,7 @@ void QCustomPlot::setPlottingHints(const QCP::PlottingHints &hints) /*! Sets the specified plotting \a hint to \a enabled. - + \see setPlottingHints */ void QCustomPlot::setPlottingHint(QCP::PlottingHint hint, bool enabled) @@ -13938,19 +13958,19 @@ void QCustomPlot::setPlottingHint(QCP::PlottingHint hint, bool enabled) newHints &= ~hint; else newHints |= hint; - + if (newHints != mPlottingHints) setPlottingHints(newHints); } /*! Sets the keyboard modifier that will be recognized as multi-select-modifier. - + If \ref QCP::iMultiSelect is specified in \ref setInteractions, the user may select multiple objects (or data points) by clicking on them one after the other while holding down \a modifier. - + By default the multi-select-modifier is set to Qt::ControlModifier. - + \see setInteractions */ void QCustomPlot::setMultiSelectModifier(Qt::KeyboardModifier modifier) @@ -13965,17 +13985,17 @@ void QCustomPlot::setMultiSelectModifier(Qt::KeyboardModifier modifier) example, QCPAxisRect may process a mouse drag by dragging axis ranges, see \ref QCPAxisRect::setRangeDrag. If \a mode is not \ref QCP::srmNone, the current selection rect (\ref selectionRect) becomes activated and allows e.g. rect zooming and data point selection. - + If you wish to provide your user both with axis range dragging and data selection/range zooming, use this method to switch between the modes just before the interaction is processed, e.g. in reaction to the \ref mousePress or \ref mouseMove signals. For example you could check whether the user is holding a certain keyboard modifier, and then decide which \a mode shall be set. - + If a selection rect interaction is currently active, and \a mode is set to \ref QCP::srmNone, the interaction is canceled (\ref QCPSelectionRect::cancel). Switching between any of the other modes will keep the selection rect active. Upon completion of the interaction, the behaviour is as defined by the currently set \a mode, not the mode that was set when the interaction started. - + \see setInteractions, setSelectionRect, QCPSelectionRect */ void QCustomPlot::setSelectionRectMode(QCP::SelectionRectMode mode) @@ -13984,20 +14004,20 @@ void QCustomPlot::setSelectionRectMode(QCP::SelectionRectMode mode) { if (mode == QCP::srmNone) mSelectionRect->cancel(); // when switching to none, we immediately want to abort a potentially active selection rect - + // disconnect old connections: if (mSelectionRectMode == QCP::srmSelect) disconnect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*))); else if (mSelectionRectMode == QCP::srmZoom) disconnect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*))); - + // establish new ones: if (mode == QCP::srmSelect) connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*))); else if (mode == QCP::srmZoom) connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*))); } - + mSelectionRectMode = mode; } @@ -14005,18 +14025,18 @@ void QCustomPlot::setSelectionRectMode(QCP::SelectionRectMode mode) Sets the \ref QCPSelectionRect instance that QCustomPlot will use if \a mode is not \ref QCP::srmNone and the user performs a click-and-drag interaction. QCustomPlot takes ownership of the passed \a selectionRect. It can be accessed later via \ref selectionRect. - + This method is useful if you wish to replace the default QCPSelectionRect instance with an instance of a QCPSelectionRect subclass, to introduce custom behaviour of the selection rect. - + \see setSelectionRectMode */ void QCustomPlot::setSelectionRect(QCPSelectionRect *selectionRect) { delete mSelectionRect; - + mSelectionRect = selectionRect; - + if (mSelectionRect) { // establish connections with new selection rect: @@ -14031,7 +14051,7 @@ void QCustomPlot::setSelectionRect(QCPSelectionRect *selectionRect) \warning This is still an experimental feature and its performance depends on the system that it runs on. Having multiple QCustomPlot widgets in one application with enabled OpenGL rendering might cause context conflicts on some systems. - + This method allows to enable OpenGL plot rendering, for increased plotting performance of graphically demanding plots (thick lines, translucent fills, etc.). @@ -14159,7 +14179,7 @@ void QCustomPlot::setBufferDevicePixelRatio(double ratio) enabled with \ref setBackgroundScaled and the scaling mode (whether and how the aspect ratio is preserved) can be set with \ref setBackgroundScaledMode. To set all these options in one call, consider using the overloaded version of this function. - + If a background brush was set with \ref setBackground(const QBrush &brush), the viewport will first be filled with that brush, before drawing the background pixmap. This can be useful for background pixmaps with translucent areas. @@ -14179,7 +14199,7 @@ void QCustomPlot::setBackground(const QPixmap &pm) was set with \ref setBackground(const QPixmap &pm), this brush will be used to fill the viewport before the background pixmap is drawn. This can be useful for background pixmaps with translucent areas. - + Set \a brush to Qt::NoBrush or Qt::Transparent to leave background transparent. This can be useful for exporting to image formats which support transparency, e.g. \ref savePng. @@ -14191,7 +14211,7 @@ void QCustomPlot::setBackground(const QBrush &brush) } /*! \overload - + Allows setting the background pixmap of the viewport, whether it shall be scaled and how it shall be scaled in one call. @@ -14209,10 +14229,10 @@ void QCustomPlot::setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioM Sets whether the viewport background pixmap shall be scaled to fit the viewport. If \a scaled is set to true, control whether and how the aspect ratio of the original pixmap is preserved with \ref setBackgroundScaledMode. - + Note that the scaled version of the original pixmap is buffered, so there is no performance penalty on replots. (Except when the viewport dimensions are changed continuously.) - + \see setBackground, setBackgroundScaledMode */ void QCustomPlot::setBackgroundScaled(bool scaled) @@ -14223,7 +14243,7 @@ void QCustomPlot::setBackgroundScaled(bool scaled) /*! If scaling of the viewport background pixmap is enabled (\ref setBackgroundScaled), use this function to define whether and how the aspect ratio of the original pixmap is preserved. - + \see setBackground, setBackgroundScaled */ void QCustomPlot::setBackgroundScaledMode(Qt::AspectRatioMode mode) @@ -14233,10 +14253,10 @@ void QCustomPlot::setBackgroundScaledMode(Qt::AspectRatioMode mode) /*! Returns the plottable with \a index. If the index is invalid, returns \c nullptr. - + There is an overloaded version of this function with no parameter which returns the last added plottable, see QCustomPlot::plottable() - + \see plottableCount */ QCPAbstractPlottable *QCustomPlot::plottable(int index) @@ -14252,10 +14272,10 @@ QCPAbstractPlottable *QCustomPlot::plottable(int index) } /*! \overload - + Returns the last plottable that was added to the plot. If there are no plottables in the plot, returns \c nullptr. - + \see plottableCount */ QCPAbstractPlottable *QCustomPlot::plottable() @@ -14270,9 +14290,9 @@ QCPAbstractPlottable *QCustomPlot::plottable() /*! Removes the specified plottable from the plot and deletes it. If necessary, the corresponding legend item is also removed from the default legend (QCustomPlot::legend). - + Returns true on success. - + \see clearPlottables */ bool QCustomPlot::removePlottable(QCPAbstractPlottable *plottable) @@ -14282,7 +14302,7 @@ bool QCustomPlot::removePlottable(QCPAbstractPlottable *plottable) qDebug() << Q_FUNC_INFO << "plottable not in list:" << reinterpret_cast(plottable); return false; } - + // remove plottable from legend: plottable->removeFromLegend(); // special handling for QCPGraphs to maintain the simple graph interface: @@ -14295,7 +14315,7 @@ bool QCustomPlot::removePlottable(QCPAbstractPlottable *plottable) } /*! \overload - + Removes and deletes the plottable by its \a index. */ bool QCustomPlot::removePlottable(int index) @@ -14312,9 +14332,9 @@ bool QCustomPlot::removePlottable(int index) /*! Removes all plottables from the plot and deletes them. Corresponding legend items are also removed from the default legend (QCustomPlot::legend). - + Returns the number of plottables removed. - + \see removePlottable */ int QCustomPlot::clearPlottables() @@ -14327,7 +14347,7 @@ int QCustomPlot::clearPlottables() /*! Returns the number of currently existing plottables in the plot - + \see plottable */ int QCustomPlot::plottableCount() const @@ -14337,9 +14357,9 @@ int QCustomPlot::plottableCount() const /*! Returns a list of the selected plottables. If no plottables are currently selected, the list is empty. - + There is a convenience function if you're only interested in selected graphs, see \ref selectedGraphs. - + \see setInteractions, QCPAbstractPlottable::setSelectable, QCPAbstractPlottable::setSelection */ QList QCustomPlot::selectedPlottables() const @@ -14356,10 +14376,10 @@ QList QCustomPlot::selectedPlottables() const /*! Returns any plottable at the pixel position \a pos. Since it can capture all plottables, the return type is the abstract base class of all plottables, QCPAbstractPlottable. - + For details, and if you wish to specify a certain plottable type (e.g. QCPGraph), see the template method plottableAt() - + \see plottableAt(), itemAt, layoutElementAt */ QCPAbstractPlottable *QCustomPlot::plottableAt(const QPointF &pos, bool onlySelectable, int *dataIndex) const @@ -14377,10 +14397,10 @@ bool QCustomPlot::hasPlottable(QCPAbstractPlottable *plottable) const /*! Returns the graph with \a index. If the index is invalid, returns \c nullptr. - + There is an overloaded version of this function with no parameter which returns the last created graph, see QCustomPlot::graph() - + \see graphCount, addGraph */ QCPGraph *QCustomPlot::graph(int index) const @@ -14396,10 +14416,10 @@ QCPGraph *QCustomPlot::graph(int index) const } /*! \overload - + Returns the last graph, that was created with \ref addGraph. If there are no graphs in the plot, returns \c nullptr. - + \see graphCount, addGraph */ QCPGraph *QCustomPlot::graph() const @@ -14415,12 +14435,12 @@ QCPGraph *QCustomPlot::graph() const Creates a new graph inside the plot. If \a keyAxis and \a valueAxis are left unspecified (0), the bottom (xAxis) is used as key and the left (yAxis) is used as value axis. If specified, \a keyAxis and \a valueAxis must reside in this QCustomPlot. - + \a keyAxis will be used as key axis (typically "x") and \a valueAxis as value axis (typically "y") for the graph. - + Returns a pointer to the newly created graph, or \c nullptr if adding the graph failed. - + \see graph, graphCount, removeGraph, clearGraphs */ QCPGraph *QCustomPlot::addGraph(QCPAxis *keyAxis, QCPAxis *valueAxis) @@ -14437,7 +14457,7 @@ QCPGraph *QCustomPlot::addGraph(QCPAxis *keyAxis, QCPAxis *valueAxis) qDebug() << Q_FUNC_INFO << "passed keyAxis or valueAxis doesn't have this QCustomPlot as parent"; return nullptr; } - + QCPGraph *newGraph = new QCPGraph(keyAxis, valueAxis); newGraph->setName(QLatin1String("Graph ")+QString::number(mGraphs.size())); return newGraph; @@ -14448,9 +14468,9 @@ QCPGraph *QCustomPlot::addGraph(QCPAxis *keyAxis, QCPAxis *valueAxis) legend item is also removed from the default legend (QCustomPlot::legend). If any other graphs in the plot have a channel fill set towards the removed graph, the channel fill property of those graphs is reset to \c nullptr (no channel fill). - + Returns true on success. - + \see clearGraphs */ bool QCustomPlot::removeGraph(QCPGraph *graph) @@ -14459,7 +14479,7 @@ bool QCustomPlot::removeGraph(QCPGraph *graph) } /*! \overload - + Removes and deletes the graph by its \a index. */ bool QCustomPlot::removeGraph(int index) @@ -14475,7 +14495,7 @@ bool QCustomPlot::removeGraph(int index) from the default legend (QCustomPlot::legend). Returns the number of graphs removed. - + \see removeGraph */ int QCustomPlot::clearGraphs() @@ -14488,7 +14508,7 @@ int QCustomPlot::clearGraphs() /*! Returns the number of currently existing graphs in the plot - + \see graph, addGraph */ int QCustomPlot::graphCount() const @@ -14498,10 +14518,10 @@ int QCustomPlot::graphCount() const /*! Returns a list of the selected graphs. If no graphs are currently selected, the list is empty. - + If you are not only interested in selected graphs but other plottables like QCPCurve, QCPBars, etc., use \ref selectedPlottables. - + \see setInteractions, selectedPlottables, QCPAbstractPlottable::setSelectable, QCPAbstractPlottable::setSelection */ QList QCustomPlot::selectedGraphs() const @@ -14517,10 +14537,10 @@ QList QCustomPlot::selectedGraphs() const /*! Returns the item with \a index. If the index is invalid, returns \c nullptr. - + There is an overloaded version of this function with no parameter which returns the last added item, see QCustomPlot::item() - + \see itemCount */ QCPAbstractItem *QCustomPlot::item(int index) const @@ -14536,10 +14556,10 @@ QCPAbstractItem *QCustomPlot::item(int index) const } /*! \overload - + Returns the last item that was added to this plot. If there are no items in the plot, returns \c nullptr. - + \see itemCount */ QCPAbstractItem *QCustomPlot::item() const @@ -14553,9 +14573,9 @@ QCPAbstractItem *QCustomPlot::item() const /*! Removes the specified item from the plot and deletes it. - + Returns true on success. - + \see clearItems */ bool QCustomPlot::removeItem(QCPAbstractItem *item) @@ -14573,7 +14593,7 @@ bool QCustomPlot::removeItem(QCPAbstractItem *item) } /*! \overload - + Removes and deletes the item by its \a index. */ bool QCustomPlot::removeItem(int index) @@ -14589,9 +14609,9 @@ bool QCustomPlot::removeItem(int index) /*! Removes all items from the plot and deletes them. - + Returns the number of items removed. - + \see removeItem */ int QCustomPlot::clearItems() @@ -14604,7 +14624,7 @@ int QCustomPlot::clearItems() /*! Returns the number of currently existing items in the plot - + \see item */ int QCustomPlot::itemCount() const @@ -14614,7 +14634,7 @@ int QCustomPlot::itemCount() const /*! Returns a list of the selected items. If no items are currently selected, the list is empty. - + \see setInteractions, QCPAbstractItem::setSelectable, QCPAbstractItem::setSelected */ QList QCustomPlot::selectedItems() const @@ -14631,10 +14651,10 @@ QList QCustomPlot::selectedItems() const /*! Returns the item at the pixel position \a pos. Since it can capture all items, the return type is the abstract base class of all items, QCPAbstractItem. - + For details, and if you wish to specify a certain item type (e.g. QCPItemLine), see the template method itemAt() - + \see itemAt(), plottableAt, layoutElementAt */ QCPAbstractItem *QCustomPlot::itemAt(const QPointF &pos, bool onlySelectable) const @@ -14644,7 +14664,7 @@ QCPAbstractItem *QCustomPlot::itemAt(const QPointF &pos, bool onlySelectable) co /*! Returns whether this QCustomPlot contains the \a item. - + \see item */ bool QCustomPlot::hasItem(QCPAbstractItem *item) const @@ -14655,9 +14675,9 @@ bool QCustomPlot::hasItem(QCPAbstractItem *item) const /*! Returns the layer with the specified \a name. If there is no layer with the specified name, \c nullptr is returned. - + Layer names are case-sensitive. - + \see addLayer, moveLayer, removeLayer */ QCPLayer *QCustomPlot::layer(const QString &name) const @@ -14671,9 +14691,9 @@ QCPLayer *QCustomPlot::layer(const QString &name) const } /*! \overload - + Returns the layer by \a index. If the index is invalid, \c nullptr is returned. - + \see addLayer, moveLayer, removeLayer */ QCPLayer *QCustomPlot::layer(int index) const @@ -14699,11 +14719,11 @@ QCPLayer *QCustomPlot::currentLayer() const /*! Sets the layer with the specified \a name to be the current layer. All layerables (\ref QCPLayerable), e.g. plottables and items, are created on the current layer. - + Returns true on success, i.e. if there is a layer with the specified \a name in the QCustomPlot. - + Layer names are case-sensitive. - + \see addLayer, moveLayer, removeLayer, QCPLayerable::setLayer */ bool QCustomPlot::setCurrentLayer(const QString &name) @@ -14719,11 +14739,11 @@ bool QCustomPlot::setCurrentLayer(const QString &name) } /*! \overload - + Sets the provided \a layer to be the current layer. - + Returns true on success, i.e. when \a layer is a valid layer in the QCustomPlot. - + \see addLayer, moveLayer, removeLayer */ bool QCustomPlot::setCurrentLayer(QCPLayer *layer) @@ -14733,14 +14753,14 @@ bool QCustomPlot::setCurrentLayer(QCPLayer *layer) qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); return false; } - + mCurrentLayer = layer; return true; } /*! Returns the number of currently existing layers in the plot - + \see layer, addLayer */ int QCustomPlot::layerCount() const @@ -14751,14 +14771,14 @@ int QCustomPlot::layerCount() const /*! Adds a new layer to this QCustomPlot instance. The new layer will have the name \a name, which must be unique. Depending on \a insertMode, it is positioned either below or above \a otherLayer. - + Returns true on success, i.e. if there is no other layer named \a name and \a otherLayer is a valid layer inside this QCustomPlot. - + If \a otherLayer is 0, the highest layer in the QCustomPlot will be used. - + For an explanation of what layers are in QCustomPlot, see the documentation of \ref QCPLayer. - + \see layer, moveLayer, removeLayer */ bool QCustomPlot::addLayer(const QString &name, QCPLayer *otherLayer, QCustomPlot::LayerInsertMode insertMode) @@ -14775,7 +14795,7 @@ bool QCustomPlot::addLayer(const QString &name, QCPLayer *otherLayer, QCustomPlo qDebug() << Q_FUNC_INFO << "A layer exists already with the name" << name; return false; } - + QCPLayer *newLayer = new QCPLayer(this, name); mLayers.insert(otherLayer->index() + (insertMode==limAbove ? 1:0), newLayer); updateLayerIndices(); @@ -14785,16 +14805,16 @@ bool QCustomPlot::addLayer(const QString &name, QCPLayer *otherLayer, QCustomPlo /*! Removes the specified \a layer and returns true on success. - + All layerables (e.g. plottables and items) on the removed layer will be moved to the layer below \a layer. If \a layer is the bottom layer, the layerables are moved to the layer above. In both cases, the total rendering order of all layerables in the QCustomPlot is preserved. - + If \a layer is the current layer (\ref setCurrentLayer), the layer below (or above, if bottom layer) becomes the new current layer. - + It is not possible to remove the last layer of the plot. - + \see layer, addLayer, moveLayer */ bool QCustomPlot::removeLayer(QCPLayer *layer) @@ -14809,7 +14829,7 @@ bool QCustomPlot::removeLayer(QCPLayer *layer) qDebug() << Q_FUNC_INFO << "can't remove last layer"; return false; } - + // append all children of this layer to layer below (if this is lowest layer, prepend to layer above) int removedIndex = layer->index(); bool isFirstLayer = removedIndex==0; @@ -14819,15 +14839,15 @@ bool QCustomPlot::removeLayer(QCPLayer *layer) std::reverse(children.begin(), children.end()); foreach (QCPLayerable *child, children) child->moveToLayer(targetLayer, isFirstLayer); // prepend if isFirstLayer, otherwise append - + // if removed layer is current layer, change current layer to layer below/above: if (layer == mCurrentLayer) setCurrentLayer(targetLayer); - + // invalidate the paint buffer that was responsible for this layer: if (QSharedPointer pb = layer->mPaintBuffer.toStrongRef()) pb->setInvalidated(); - + // remove layer: delete layer; mLayers.removeOne(layer); @@ -14838,10 +14858,10 @@ bool QCustomPlot::removeLayer(QCPLayer *layer) /*! Moves the specified \a layer either above or below \a otherLayer. Whether it's placed above or below is controlled with \a insertMode. - + Returns true on success, i.e. when both \a layer and \a otherLayer are valid layers in the QCustomPlot. - + \see layer, addLayer, moveLayer */ bool QCustomPlot::moveLayer(QCPLayer *layer, QCPLayer *otherLayer, QCustomPlot::LayerInsertMode insertMode) @@ -14856,29 +14876,29 @@ bool QCustomPlot::moveLayer(QCPLayer *layer, QCPLayer *otherLayer, QCustomPlot:: qDebug() << Q_FUNC_INFO << "otherLayer not a layer of this QCustomPlot:" << reinterpret_cast(otherLayer); return false; } - + if (layer->index() > otherLayer->index()) mLayers.move(layer->index(), otherLayer->index() + (insertMode==limAbove ? 1:0)); else if (layer->index() < otherLayer->index()) mLayers.move(layer->index(), otherLayer->index() + (insertMode==limAbove ? 0:-1)); - + // invalidate the paint buffers that are responsible for the layers: if (QSharedPointer pb = layer->mPaintBuffer.toStrongRef()) pb->setInvalidated(); if (QSharedPointer pb = otherLayer->mPaintBuffer.toStrongRef()) pb->setInvalidated(); - + updateLayerIndices(); return true; } /*! Returns the number of axis rects in the plot. - + All axis rects can be accessed via QCustomPlot::axisRect(). - + Initially, only one axis rect exists in the plot. - + \see axisRect, axisRects */ int QCustomPlot::axisRectCount() const @@ -14888,21 +14908,21 @@ int QCustomPlot::axisRectCount() const /*! Returns the axis rect with \a index. - + Initially, only one axis rect (with index 0) exists in the plot. If multiple axis rects were added, all of them may be accessed with this function in a linear fashion (even when they are nested in a layout hierarchy or inside other axis rects via QCPAxisRect::insetLayout). - + The order of the axis rects is given by the fill order of the \ref QCPLayout that is holding them. For example, if the axis rects are in the top level grid layout (accessible via \ref QCustomPlot::plotLayout), they are ordered from left to right, top to bottom, if the layout's default \ref QCPLayoutGrid::setFillOrder "setFillOrder" of \ref QCPLayoutGrid::foColumnsFirst "foColumnsFirst" wasn't changed. - + If you want to access axis rects by their row and column index, use the layout interface. For example, use \ref QCPLayoutGrid::element of the top level grid layout, and \c qobject_cast the returned layout element to \ref QCPAxisRect. (See also \ref thelayoutsystem.) - + \see axisRectCount, axisRects, QCPLayoutGrid::setFillOrder */ QCPAxisRect *QCustomPlot::axisRect(int index) const @@ -14920,13 +14940,13 @@ QCPAxisRect *QCustomPlot::axisRect(int index) const /*! Returns all axis rects in the plot. - + The order of the axis rects is given by the fill order of the \ref QCPLayout that is holding them. For example, if the axis rects are in the top level grid layout (accessible via \ref QCustomPlot::plotLayout), they are ordered from left to right, top to bottom, if the layout's default \ref QCPLayoutGrid::setFillOrder "setFillOrder" of \ref QCPLayoutGrid::foColumnsFirst "foColumnsFirst" wasn't changed. - + \see axisRectCount, axisRect, QCPLayoutGrid::setFillOrder */ QList QCustomPlot::axisRects() const @@ -14935,7 +14955,7 @@ QList QCustomPlot::axisRects() const QStack elementStack; if (mPlotLayout) elementStack.push(mPlotLayout); - + while (!elementStack.isEmpty()) { foreach (QCPLayoutElement *element, elementStack.pop()->elements(false)) @@ -14948,17 +14968,17 @@ QList QCustomPlot::axisRects() const } } } - + return result; } /*! Returns the layout element at pixel position \a pos. If there is no element at that position, returns \c nullptr. - + Only visible elements are used. If \ref QCPLayoutElement::setVisible on the element itself or on any of its parent elements is set to false, it will not be considered. - + \see itemAt, plottableAt */ QCPLayoutElement *QCustomPlot::layoutElementAt(const QPointF &pos) const @@ -15017,7 +15037,7 @@ QCPAxisRect *QCustomPlot::axisRectAt(const QPointF &pos) const /*! Returns the axes that currently have selected parts, i.e. whose selection state is not \ref QCPAxis::spNone. - + \see selectedPlottables, selectedLegends, setInteractions, QCPAxis::setSelectedParts, QCPAxis::setSelectableParts */ @@ -15026,31 +15046,31 @@ QList QCustomPlot::selectedAxes() const QList result, allAxes; foreach (QCPAxisRect *rect, axisRects()) allAxes << rect->axes(); - + foreach (QCPAxis *axis, allAxes) { if (axis->selectedParts() != QCPAxis::spNone) result.append(axis); } - + return result; } /*! Returns the legends that currently have selected parts, i.e. whose selection state is not \ref QCPLegend::spNone. - + \see selectedPlottables, selectedAxes, setInteractions, QCPLegend::setSelectedParts, QCPLegend::setSelectableParts, QCPLegend::selectedItems */ QList QCustomPlot::selectedLegends() const { QList result; - + QStack elementStack; if (mPlotLayout) elementStack.push(mPlotLayout); - + while (!elementStack.isEmpty()) { foreach (QCPLayoutElement *subElement, elementStack.pop()->elements(false)) @@ -15066,17 +15086,17 @@ QList QCustomPlot::selectedLegends() const } } } - + return result; } /*! Deselects all layerables (plottables, items, axes, legends,...) of the QCustomPlot. - + Since calling this function is not a user interaction, this does not emit the \ref selectionChangedByUser signal. The individual selectionChanged signals are emitted though, if the objects were previously selected. - + \see setInteractions, selectedPlottables, selectedItems, selectedAxes, selectedLegends */ void QCustomPlot::deselectAll() @@ -15112,7 +15132,7 @@ void QCustomPlot::deselectAll() If a layer is in mode \ref QCPLayer::lmBuffered (\ref QCPLayer::setMode), it is also possible to replot only that specific layer via \ref QCPLayer::replot. See the documentation there for details. - + \see replotTime */ void QCustomPlot::replot(QCustomPlot::RefreshPriority refreshPriority) @@ -15126,13 +15146,13 @@ void QCustomPlot::replot(QCustomPlot::RefreshPriority refreshPriority) } return; } - + if (mReplotting) // incase signals loop back to replot slot return; mReplotting = true; mReplotQueued = false; emit beforeReplot(); - + # if QT_VERSION < QT_VERSION_CHECK(4, 8, 0) QTime replotTimer; replotTimer.start(); @@ -15140,7 +15160,7 @@ void QCustomPlot::replot(QCustomPlot::RefreshPriority refreshPriority) QElapsedTimer replotTimer; replotTimer.start(); # endif - + updateLayout(); // draw all layered objects (grid, axes, plottables, items, legend,...) into their buffers: setupPaintBuffers(); @@ -15148,12 +15168,12 @@ void QCustomPlot::replot(QCustomPlot::RefreshPriority refreshPriority) layer->drawToPaintBuffer(); foreach (QSharedPointer buffer, mPaintBuffers) buffer->setInvalidated(false); - + if ((refreshPriority == rpRefreshHint && mPlottingHints.testFlag(QCP::phImmediateRefresh)) || refreshPriority==rpImmediateRefresh) repaint(); else update(); - + # if QT_VERSION < QT_VERSION_CHECK(4, 8, 0) mReplotTime = replotTimer.elapsed(); # else @@ -15163,7 +15183,7 @@ void QCustomPlot::replot(QCustomPlot::RefreshPriority refreshPriority) mReplotTimeAverage = mReplotTimeAverage*0.9 + mReplotTime*0.1; // exponential moving average with a time constant of 10 last replots else mReplotTimeAverage = mReplotTime; // no previous replots to average with, so initialize with replot time - + emit afterReplot(); mReplotting = false; } @@ -15171,7 +15191,7 @@ void QCustomPlot::replot(QCustomPlot::RefreshPriority refreshPriority) /*! Returns the time in milliseconds that the last replot took. If \a average is set to true, an exponential moving average over the last couple of replots is returned. - + \see replot */ double QCustomPlot::replotTime(bool average) const @@ -15181,10 +15201,10 @@ double QCustomPlot::replotTime(bool average) const /*! Rescales the axes such that all plottables (like graphs) in the plot are fully visible. - + if \a onlyVisiblePlottables is set to true, only the plottables that have their visibility set to true (QCPLayerable::setVisible), will be used to rescale the axes. - + \see QCPAbstractPlottable::rescaleAxes, QCPAxis::rescale */ void QCustomPlot::rescaleAxes(bool onlyVisiblePlottables) @@ -15192,7 +15212,7 @@ void QCustomPlot::rescaleAxes(bool onlyVisiblePlottables) QList allAxes; foreach (QCPAxisRect *rect, axisRects()) allAxes << rect->axes(); - + foreach (QCPAxis *axis, allAxes) axis->rescale(onlyVisiblePlottables); } @@ -15256,7 +15276,7 @@ bool QCustomPlot::savePdf(const QString &fileName, int width, int height, QCP::E newWidth = width; newHeight = height; } - + QPrinter printer(QPrinter::ScreenResolution); printer.setOutputFileName(fileName); printer.setOutputFormat(QPrinter::PdfFormat); @@ -15439,7 +15459,7 @@ bool QCustomPlot::saveBmp(const QString &fileName, int width, int height, double } /*! \internal - + Returns a minimum size hint that corresponds to the minimum size of the top level layout (\ref plotLayout). To prevent QCustomPlot from being collapsed to size/width zero, set a minimum size (setMinimumSize) either on the whole QCustomPlot or on any layout elements inside the plot. @@ -15452,9 +15472,9 @@ QSize QCustomPlot::minimumSizeHint() const } /*! \internal - + Returns a size hint that is the same as \ref minimumSizeHint. - + */ QSize QCustomPlot::sizeHint() const { @@ -15462,14 +15482,14 @@ QSize QCustomPlot::sizeHint() const } /*! \internal - + Event handler for when the QCustomPlot widget needs repainting. This does not cause a \ref replot, but draws the internal buffer on the widget surface. */ void QCustomPlot::paintEvent(QPaintEvent *event) { Q_UNUSED(event) - + // detect if the device pixel ratio has changed (e.g. moving window between different DPI screens), and adapt buffers if necessary: #ifdef QCP_DEVICEPIXELRATIO_SUPPORTED # ifdef QCP_DEVICEPIXELRATIO_FLOAT @@ -15484,7 +15504,7 @@ void QCustomPlot::paintEvent(QPaintEvent *event) return; } #endif - + QCPPainter painter(this); if (painter.isActive()) { @@ -15500,7 +15520,7 @@ void QCustomPlot::paintEvent(QPaintEvent *event) } /*! \internal - + Event handler for a resize of the QCustomPlot widget. The viewport (which becomes the outer rect of mPlotLayout) is resized appropriately. Finally a \ref replot is performed. */ @@ -15513,12 +15533,12 @@ void QCustomPlot::resizeEvent(QResizeEvent *event) } /*! \internal - + Event handler for when a double click occurs. Emits the \ref mouseDoubleClick signal, then determines the layerable under the cursor and forwards the event to it. Finally, emits the specialized signals when certain objecs are clicked (e.g. \ref plottableDoubleClick, \ref axisDoubleClick, etc.). - + \see mousePressEvent, mouseReleaseEvent */ void QCustomPlot::mouseDoubleClickEvent(QMouseEvent *event) @@ -15526,7 +15546,7 @@ void QCustomPlot::mouseDoubleClickEvent(QMouseEvent *event) emit mouseDoubleClick(event); mMouseHasMoved = false; mMousePressPos = event->pos(); - + // determine layerable under the cursor (this event is called instead of the second press event in a double-click): QList details; QList candidates = layerableListAt(mMousePressPos, false, &details); @@ -15541,7 +15561,7 @@ void QCustomPlot::mouseDoubleClickEvent(QMouseEvent *event) break; } } - + // emit specialized object double click signals: if (!candidates.isEmpty()) { @@ -15560,17 +15580,17 @@ void QCustomPlot::mouseDoubleClickEvent(QMouseEvent *event) else if (QCPAbstractLegendItem *li = qobject_cast(candidates.first())) emit legendDoubleClick(li->parentLegend(), li, event); } - + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. } /*! \internal - + Event handler for when a mouse button is pressed. Emits the mousePress signal. If the current \ref setSelectionRectMode is not \ref QCP::srmNone, passes the event to the selection rect. Otherwise determines the layerable under the cursor and forwards the event to it. - + \see mouseMoveEvent, mouseReleaseEvent */ void QCustomPlot::mousePressEvent(QMouseEvent *event) @@ -15579,7 +15599,7 @@ void QCustomPlot::mousePressEvent(QMouseEvent *event) // save some state to tell in releaseEvent whether it was a click: mMouseHasMoved = false; mMousePressPos = event->pos(); - + if (mSelectionRect && mSelectionRectMode != QCP::srmNone) { if (mSelectionRectMode != QCP::srmZoom || qobject_cast(axisRectAt(mMousePressPos))) // in zoom mode only activate selection rect if on an axis rect @@ -15607,34 +15627,34 @@ void QCustomPlot::mousePressEvent(QMouseEvent *event) } } } - + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. } /*! \internal - + Event handler for when the cursor is moved. Emits the \ref mouseMove signal. If the selection rect (\ref setSelectionRect) is currently active, the event is forwarded to it in order to update the rect geometry. - + Otherwise, if a layout element has mouse capture focus (a mousePressEvent happened on top of the layout element before), the mouseMoveEvent is forwarded to that element. - + \see mousePressEvent, mouseReleaseEvent */ void QCustomPlot::mouseMoveEvent(QMouseEvent *event) { emit mouseMove(event); - + if (!mMouseHasMoved && (mMousePressPos-event->pos()).manhattanLength() > 3) mMouseHasMoved = true; // moved too far from mouse press position, don't handle as click on mouse release - + if (mSelectionRect && mSelectionRect->isActive()) mSelectionRect->moveSelection(event); else if (mMouseEventLayerable) // call event of affected layerable: mMouseEventLayerable->mouseMoveEvent(event, mMousePressPos); - + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. } @@ -15655,14 +15675,14 @@ void QCustomPlot::mouseMoveEvent(QMouseEvent *event) void QCustomPlot::mouseReleaseEvent(QMouseEvent *event) { emit mouseRelease(event); - + if (!mMouseHasMoved) // mouse hasn't moved (much) between press and release, so handle as click { if (mSelectionRect && mSelectionRect->isActive()) // a simple click shouldn't successfully finish a selection rect, so cancel it here mSelectionRect->cancel(); if (event->button() == Qt::LeftButton) processPointSelection(event); - + // emit specialized click signals of QCustomPlot instance: if (QCPAbstractPlottable *ap = qobject_cast(mMouseSignalLayerable)) { @@ -15680,7 +15700,7 @@ void QCustomPlot::mouseReleaseEvent(QMouseEvent *event) emit legendClick(li->parentLegend(), li, event); mMouseSignalLayerable = nullptr; } - + if (mSelectionRect && mSelectionRect->isActive()) // Note: if a click was detected above, the selection rect is canceled there { // finish selection rect, the appropriate action will be taken via signal-slot connection: @@ -15694,10 +15714,10 @@ void QCustomPlot::mouseReleaseEvent(QMouseEvent *event) mMouseEventLayerable = nullptr; } } - + if (noAntialiasingOnDrag()) replot(rpQueuedReplot); - + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. } @@ -15709,13 +15729,13 @@ void QCustomPlot::mouseReleaseEvent(QMouseEvent *event) void QCustomPlot::wheelEvent(QWheelEvent *event) { emit mouseWheel(event); - + #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) const QPointF pos = event->pos(); #else const QPointF pos = event->position(); #endif - + // forward event to layerable under cursor: foreach (QCPLayerable *candidate, layerableListAt(pos, false)) { @@ -15728,7 +15748,7 @@ void QCustomPlot::wheelEvent(QWheelEvent *event) } /*! \internal - + This function draws the entire plot, including background pixmap, with the specified \a painter. It does not make use of the paint buffers like \ref replot, so this is the function typically used by saving/exporting methods such as \ref savePdf or \ref toPainter. @@ -15740,14 +15760,14 @@ void QCustomPlot::wheelEvent(QWheelEvent *event) void QCustomPlot::draw(QCPPainter *painter) { updateLayout(); - + // draw viewport background pixmap: drawBackground(painter); // draw all layered objects (grid, axes, plottables, items, legend,...): foreach (QCPLayer *layer, mLayers) layer->draw(painter); - + /* Debug code to draw all layout element rects foreach (QCPLayoutElement *el, findChildren()) { @@ -15779,9 +15799,9 @@ void QCustomPlot::updateLayout() } /*! \internal - + Draws the viewport background pixmap of the plot. - + If a pixmap was provided via \ref setBackground, this function buffers the scaled version depending on \ref setBackgroundScaled and \ref setBackgroundScaledMode and then draws it inside the viewport with the provided \a painter. The scaled version is buffered in @@ -15789,10 +15809,10 @@ void QCustomPlot::updateLayout() the axis rect has changed in a way that requires a rescale of the background pixmap (this is dependent on the \ref setBackgroundScaledMode), or when a differend axis background pixmap was set. - + Note that this function does not draw a fill with the background brush (\ref setBackground(const QBrush &brush)) beneath the pixmap. - + \see setBackground, setBackgroundScaled, setBackgroundScaledMode */ void QCustomPlot::drawBackground(QCPPainter *painter) @@ -15841,7 +15861,7 @@ void QCustomPlot::setupPaintBuffers() int bufferIndex = 0; if (mPaintBuffers.isEmpty()) mPaintBuffers.append(QSharedPointer(createPaintBuffer())); - + for (int layerIndex = 0; layerIndex < mLayers.size(); ++layerIndex) { QCPLayer *layer = mLayers.at(layerIndex); @@ -16000,7 +16020,7 @@ void QCustomPlot::freeOpenGl() } /*! \internal - + This method is used by \ref QCPAxisRect::removeAxis to report removed axes to the QCustomPlot so it may clear its QCustomPlot::xAxis, yAxis, xAxis2 and yAxis2 members accordingly. */ @@ -16014,12 +16034,12 @@ void QCustomPlot::axisRemoved(QCPAxis *axis) yAxis = nullptr; if (yAxis2 == axis) yAxis2 = nullptr; - + // Note: No need to take care of range drag axes and range zoom axes, because they are stored in smart pointers } /*! \internal - + This method is used by the QCPLegend destructor to report legend removal to the QCustomPlot so it may clear its QCustomPlot::legend member accordingly. */ @@ -16030,7 +16050,7 @@ void QCustomPlot::legendRemoved(QCPLegend *legend) } /*! \internal - + This slot is connected to the selection rect's \ref QCPSelectionRect::accepted signal when \ref setSelectionRectMode is set to \ref QCP::srmSelect. @@ -16038,21 +16058,21 @@ void QCustomPlot::legendRemoved(QCPLegend *legend) point of the selection. Then it goes through the plottables (\ref QCPAbstractPlottable1D to be precise) associated with that axis rect and finds the data points that are in \a rect. It does this by querying their \ref QCPAbstractPlottable1D::selectTestRect method. - + Then, the actual selection is done by calling the plottables' \ref QCPAbstractPlottable::selectEvent, placing the found selected data points in the \a details parameter as QVariant(\ref QCPDataSelection). All plottables that weren't touched by \a rect receive a \ref QCPAbstractPlottable::deselectEvent. - + \see processRectZoom */ void QCustomPlot::processRectSelection(QRect rect, QMouseEvent *event) { typedef QPair SelectionCandidate; typedef QMultiMap SelectionCandidates; // map key is number of selected data points, so we have selections sorted by size - + bool selectionStateChanged = false; - + if (mInteractions.testFlag(QCP::iSelectPlottables)) { SelectionCandidates potentialSelections; @@ -16069,7 +16089,7 @@ void QCustomPlot::processRectSelection(QRect rect, QMouseEvent *event) potentialSelections.insert(dataSel.dataPointCount(), SelectionCandidate(plottable, dataSel)); } } - + if (!mInteractions.testFlag(QCP::iMultiSelect)) { // only leave plottable with most selected points in map, since we will only select a single plottable: @@ -16080,7 +16100,7 @@ void QCustomPlot::processRectSelection(QRect rect, QMouseEvent *event) it = potentialSelections.erase(it); } } - + bool additive = event->modifiers().testFlag(mMultiSelectModifier); // deselect all other layerables if not additive selection: if (!additive) @@ -16099,7 +16119,7 @@ void QCustomPlot::processRectSelection(QRect rect, QMouseEvent *event) } } } - + // go through selections in reverse (largest selection first) and emit select events: SelectionCandidates::const_iterator it = potentialSelections.constEnd(); while (it != potentialSelections.constBegin()) @@ -16114,7 +16134,7 @@ void QCustomPlot::processRectSelection(QRect rect, QMouseEvent *event) } } } - + if (selectionStateChanged) { emit selectionChangedByUser(); @@ -16124,14 +16144,14 @@ void QCustomPlot::processRectSelection(QRect rect, QMouseEvent *event) } /*! \internal - + This slot is connected to the selection rect's \ref QCPSelectionRect::accepted signal when \ref setSelectionRectMode is set to \ref QCP::srmZoom. It determines which axis rect was the origin of the selection rect judging by the starting point of the selection, and then zooms the axes defined via \ref QCPAxisRect::setRangeZoomAxes to the provided \a rect (see \ref QCPAxisRect::zoom). - + \see processRectSelection */ void QCustomPlot::processRectZoom(QRect rect, QMouseEvent *event) @@ -16200,14 +16220,14 @@ void QCustomPlot::processPointSelection(QMouseEvent *event) } /*! \internal - + Registers the specified plottable with this QCustomPlot and, if \ref setAutoAddPlottableToLegend is enabled, adds it to the legend (QCustomPlot::legend). QCustomPlot takes ownership of the plottable. - + Returns true on success, i.e. when \a plottable isn't already in this plot and the parent plot of \a plottable is this QCustomPlot. - + This method is called automatically in the QCPAbstractPlottable base class constructor. */ bool QCustomPlot::registerPlottable(QCPAbstractPlottable *plottable) @@ -16222,7 +16242,7 @@ bool QCustomPlot::registerPlottable(QCPAbstractPlottable *plottable) qDebug() << Q_FUNC_INFO << "plottable not created with this QCustomPlot as parent:" << reinterpret_cast(plottable); return false; } - + mPlottables.append(plottable); // possibly add plottable to legend: if (mAutoAddPlottableToLegend) @@ -16233,11 +16253,11 @@ bool QCustomPlot::registerPlottable(QCPAbstractPlottable *plottable) } /*! \internal - + In order to maintain the simplified graph interface of QCustomPlot, this method is called by the QCPGraph constructor to register itself with this QCustomPlot's internal graph list. Returns true on success, i.e. if \a graph is valid and wasn't already registered with this QCustomPlot. - + This graph specific registration happens in addition to the call to \ref registerPlottable by the QCPAbstractPlottable base class. */ @@ -16253,7 +16273,7 @@ bool QCustomPlot::registerGraph(QCPGraph *graph) qDebug() << Q_FUNC_INFO << "graph already registered with this QCustomPlot"; return false; } - + mGraphs.append(graph); return true; } @@ -16262,10 +16282,10 @@ bool QCustomPlot::registerGraph(QCPGraph *graph) /*! \internal Registers the specified item with this QCustomPlot. QCustomPlot takes ownership of the item. - + Returns true on success, i.e. when \a item wasn't already in the plot and the parent plot of \a item is this QCustomPlot. - + This method is called automatically in the QCPAbstractItem base class constructor. */ bool QCustomPlot::registerItem(QCPAbstractItem *item) @@ -16280,7 +16300,7 @@ bool QCustomPlot::registerItem(QCPAbstractItem *item) qDebug() << Q_FUNC_INFO << "item not created with this QCustomPlot as parent:" << reinterpret_cast(item); return false; } - + mItems.append(item); if (!item->layer()) // usually the layer is already set in the constructor of the item (via QCPLayerable constructor) item->setLayer(currentLayer()); @@ -16288,7 +16308,7 @@ bool QCustomPlot::registerItem(QCPAbstractItem *item) } /*! \internal - + Assigns all layers their index (QCPLayer::mIndex) in the mLayers list. This method is thus called after every operation that changes the layer indices, like layer removal, layer creation, layer moving. @@ -16311,7 +16331,7 @@ void QCustomPlot::updateLayerIndices() const information about which part of the layerable was hit, in multi-part layerables (e.g. QCPAxis::SelectablePart). If the layerable is a plottable, \a selectionDetails contains a \ref QCPDataSelection instance with the single data point which is closest to \a pos. - + \see layerableListAt, layoutElementAt, axisRectAt */ QCPLayerable *QCustomPlot::layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails) const @@ -16342,7 +16362,7 @@ QCPLayerable *QCustomPlot::layerableAt(const QPointF &pos, bool onlySelectable, information about which part of the layerable was hit, in multi-part layerables (e.g. QCPAxis::SelectablePart). If the layerable is a plottable, \a selectionDetails contains a \ref QCPDataSelection instance with the single data point which is closest to \a pos. - + \see layerableAt, layoutElementAt, axisRectAt */ QList QCustomPlot::layerableListAt(const QPointF &pos, bool onlySelectable, QList *selectionDetails) const @@ -16389,7 +16409,7 @@ QList QCustomPlot::layerableListAt(const QPointF &pos, bool onlyS bool QCustomPlot::saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality, int resolution, QCP::ResolutionUnit resolutionUnit) { QImage buffer = toPixmap(width, height, scale).toImage(); - + int dotsPerMeter = 0; switch (resolutionUnit) { @@ -16407,10 +16427,10 @@ bool QCustomPlot::saveRastered(const QString &fileName, int width, int height, d /*! Renders the plot to a pixmap and returns it. - + The plot is sized to \a width and \a height in pixels and scaled with \a scale. (width 100 and scale 2.0 lead to a full resolution pixmap with width 200.) - + \see toPainter, saveRastered, saveBmp, savePng, saveJpg, savePdf */ QPixmap QCustomPlot::toPixmap(int width, int height, double scale) @@ -16459,14 +16479,14 @@ QPixmap QCustomPlot::toPixmap(int width, int height, double scale) /*! Renders the plot using the passed \a painter. - + The plot is sized to \a width and \a height in pixels. If the \a painter's scale is not 1.0, the resulting plot will appear scaled accordingly. - + \note If you are restricted to using a QPainter (instead of QCPPainter), create a temporary QPicture and open a QCPPainter on it. Then call \ref toPainter with this QCPPainter. After ending the paint operation on the picture, draw it with the QPainter. This will reproduce the painter actions the QCPPainter took, with a QPainter. - + \see toPixmap */ void QCustomPlot::toPainter(QCPPainter *painter, int width, int height) @@ -16508,7 +16528,7 @@ void QCustomPlot::toPainter(QCPPainter *painter, int width, int height) /*! \class QCPColorGradient \brief Defines a color gradient for use with e.g. \ref QCPColorMap - + This class describes a color gradient which can be used to encode data with color. For example, QCPColorMap and QCPColorScale have \ref QCPColorMap::setGradient "setGradient" methods which take an instance of this class. Colors are set with \ref setColorStopAt(double position, const QColor &color) @@ -16517,20 +16537,20 @@ void QCustomPlot::toPainter(QCPPainter *painter, int width, int height) Alternatively, load one of the preset color gradients shown in the image below, with \ref loadPreset, or by directly specifying the preset in the constructor. - + Apart from red, green and blue components, the gradient also interpolates the alpha values of the configured color stops. This allows to display some portions of the data range as transparent in the plot. - + How NaN values are interpreted can be configured with \ref setNanHandling. - + \image html QCPColorGradient.png - + The constructor \ref QCPColorGradient(GradientPreset preset) allows directly converting a \ref GradientPreset to a QCPColorGradient. This means that you can directly pass \ref GradientPreset to all the \a setGradient methods, e.g.: \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorgradient-setgradient - + The total number of levels used in the gradient can be set with \ref setLevelCount. Whether the color gradient shall be applied periodically (wrapping around) to data values that lie outside the data range specified on the plottable instance can be controlled with \ref setPeriodic. @@ -16606,11 +16626,11 @@ void QCPColorGradient::setLevelCount(int n) Sets at which positions from 0 to 1 which color shall occur. The positions are the keys, the colors are the values of the passed QMap \a colorStops. In between these color stops, the color is interpolated according to \ref setColorInterpolation. - + A more convenient way to create a custom gradient may be to clear all color stops with \ref clearColorStops (or creating a new, empty QCPColorGradient) and then adding them one by one with \ref setColorStopAt. - + \see clearColorStops */ void QCPColorGradient::setColorStops(const QMap &colorStops) @@ -16622,7 +16642,7 @@ void QCPColorGradient::setColorStops(const QMap &colorStops) /*! Sets the \a color the gradient will have at the specified \a position (from 0 to 1). In between these color stops, the color is interpolated according to \ref setColorInterpolation. - + \see setColorStops, clearColorStops */ void QCPColorGradient::setColorStopAt(double position, const QColor &color) @@ -16634,7 +16654,7 @@ void QCPColorGradient::setColorStopAt(double position, const QColor &color) /*! Sets whether the colors in between the configured color stops (see \ref setColorStopAt) shall be interpolated linearly in RGB or in HSV color space. - + For example, a sweep in RGB space from red to green will have a muddy brown intermediate color, whereas in HSV space the intermediate color is yellow. */ @@ -16649,7 +16669,7 @@ void QCPColorGradient::setColorInterpolation(QCPColorGradient::ColorInterpolatio /*! Sets how NaNs in the data are displayed in the plot. - + \see setNanColor */ void QCPColorGradient::setNanHandling(QCPColorGradient::NanHandling handling) @@ -16660,7 +16680,7 @@ void QCPColorGradient::setNanHandling(QCPColorGradient::NanHandling handling) /*! Sets the color that NaN data is represented by, if \ref setNanHandling is set to ref nhNanColor. - + \see setNanHandling */ void QCPColorGradient::setNanColor(const QColor &color) @@ -16672,13 +16692,13 @@ void QCPColorGradient::setNanColor(const QColor &color) Sets whether data points that are outside the configured data range (e.g. \ref QCPColorMap::setDataRange) are colored by periodically repeating the color gradient or whether they all have the same color, corresponding to the respective gradient boundary color. - + \image html QCPColorGradient-periodic.png - + As shown in the image above, gradients that have the same start and end color are especially suitable for a periodic gradient mapping, since they produce smooth color transitions throughout the color map. A preset that has this property is \ref gpHues. - + In practice, using periodic color gradients makes sense when the data corresponds to a periodic dimension, such as an angle or a phase. If this is not the case, the color encoding might become ambiguous, because multiple different data values are shown as the same color. @@ -16689,7 +16709,7 @@ void QCPColorGradient::setPeriodic(bool enabled) } /*! \overload - + This method is used to quickly convert a \a data array to colors. The colors will be output in the array \a scanLine. Both \a data and \a scanLine must have the length \a n when passed to this function. The data range that shall be used for mapping the data value to the gradient is passed @@ -16700,7 +16720,7 @@ void QCPColorGradient::setPeriodic(bool enabled) set \a dataIndexFactor to columnCount to convert a column instead of a row of the data array, in \a scanLine. \a scanLine will remain a regular (1D) array. This works because \a data is addressed data[i*dataIndexFactor]. - + Use the overloaded method to additionally provide alpha map data. The QRgb values that are placed in \a scanLine have their r, g, and b components premultiplied @@ -16721,7 +16741,7 @@ void QCPColorGradient::colorize(const double *data, const QCPRange &range, QRgb } if (mColorBufferInvalidated) updateColorBuffer(); - + const bool skipNanCheck = mNanHandling == nhNone; const double posToIndexFactor = !logarithmic ? (mLevelCount-1)/range.size() : (mLevelCount-1)/qLn(range.upper/range.lower); for (int i=0; iinterface1D()) { foreach (const QCPDataRange &dataRange, selection.dataRanges()) @@ -17346,16 +17366,16 @@ void QCPSelectionDecoratorBracket::drawDecoration(QCPPainter *painter, QCPDataSe } /*! \internal - + If \ref setTangentToData is enabled, brackets need to be rotated according to the data slope. This method returns the angle in radians by which a bracket at the given \a dataIndex must be rotated. - + The parameter \a direction must be set to either -1 or 1, representing whether it is an opening or closing bracket. Since for slope calculation multiple data points are required, this defines the direction in which the algorithm walks, starting at \a dataIndex, to average those data points. (see \ref setTangentToData and \ref setTangentAverage) - + \a interface1d is the interface to the plottable's data which is used to query data coordinates. */ double QCPSelectionDecoratorBracket::getTangentAngle(const QCPPlottableInterface1D *interface1d, int dataIndex, int direction) const @@ -17363,7 +17383,7 @@ double QCPSelectionDecoratorBracket::getTangentAngle(const QCPPlottableInterface if (!interface1d || dataIndex < 0 || dataIndex >= interface1d->dataCount()) return 0; direction = direction < 0 ? -1 : 1; // enforce direction is either -1 or 1 - + // how many steps we can actually go from index in the given direction without exceeding data bounds: int averageCount; if (direction < 0) @@ -17382,7 +17402,7 @@ double QCPSelectionDecoratorBracket::getTangentAngle(const QCPPlottableInterface currentIndex += direction; } pointsAverage /= double(averageCount); - + // calculate slope of linear regression through points: double numSum = 0; double denomSum = 0; @@ -17401,7 +17421,7 @@ double QCPSelectionDecoratorBracket::getTangentAngle(const QCPPlottableInterface } /*! \internal - + Returns the pixel coordinates of the data point at \a dataIndex, using \a interface1d to access the data points. */ @@ -17410,7 +17430,7 @@ QPointF QCPSelectionDecoratorBracket::getPixelCoordinates(const QCPPlottableInte QCPAxis *keyAxis = mPlottable->keyAxis(); QCPAxis *valueAxis = mPlottable->valueAxis(); if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return {0, 0}; } - + if (keyAxis->orientation() == Qt::Horizontal) return {keyAxis->coordToPixel(interface1d->dataMainKey(dataIndex)), valueAxis->coordToPixel(interface1d->dataMainValue(dataIndex))}; else @@ -17429,36 +17449,36 @@ QPointF QCPSelectionDecoratorBracket::getPixelCoordinates(const QCPPlottableInte /*! \class QCPAxisRect \brief Holds multiple axes and arranges them in a rectangular shape. - + This class represents an axis rect, a rectangular area that is bounded on all sides with an arbitrary number of axes. - + Initially QCustomPlot has one axis rect, accessible via QCustomPlot::axisRect(). However, the layout system allows to have multiple axis rects, e.g. arranged in a grid layout (QCustomPlot::plotLayout). - + By default, QCPAxisRect comes with four axes, at bottom, top, left and right. They can be accessed via \ref axis by providing the respective axis type (\ref QCPAxis::AxisType) and index. If you need all axes in the axis rect, use \ref axes. The top and right axes are set to be invisible initially (QCPAxis::setVisible). To add more axes to a side, use \ref addAxis or \ref addAxes. To remove an axis, use \ref removeAxis. - + The axis rect layerable itself only draws a background pixmap or color, if specified (\ref setBackground). It is placed on the "background" layer initially (see \ref QCPLayer for an explanation of the QCustomPlot layer system). The axes that are held by the axis rect can be placed on other layers, independently of the axis rect. - + Every axis rect has a child layout of type \ref QCPLayoutInset. It is accessible via \ref insetLayout and can be used to have other layout elements (or even other layouts with multiple elements) hovering inside the axis rect. - + If an axis rect is clicked and dragged, it processes this by moving certain axis ranges. The behaviour can be controlled with \ref setRangeDrag and \ref setRangeDragAxes. If the mouse wheel is scrolled while the cursor is on the axis rect, certain axes are scaled. This is controllable via \ref setRangeZoom, \ref setRangeZoomAxes and \ref setRangeZoomFactor. These interactions are only enabled if \ref QCustomPlot::setInteractions contains \ref QCP::iRangeDrag and \ref QCP::iRangeZoom. - + \image html AxisRectSpacingOverview.png
Overview of the spacings and paddings that define the geometry of an axis. The dashed line on the far left indicates the viewport/widget border.
@@ -17467,81 +17487,81 @@ QPointF QCPSelectionDecoratorBracket::getPixelCoordinates(const QCPPlottableInte /* start documentation of inline functions */ /*! \fn QCPLayoutInset *QCPAxisRect::insetLayout() const - + Returns the inset layout of this axis rect. It can be used to place other layout elements (or even layouts with multiple other elements) inside/on top of an axis rect. - + \see QCPLayoutInset */ /*! \fn int QCPAxisRect::left() const - + Returns the pixel position of the left border of this axis rect. Margins are not taken into account here, so the returned value is with respect to the inner \ref rect. */ /*! \fn int QCPAxisRect::right() const - + Returns the pixel position of the right border of this axis rect. Margins are not taken into account here, so the returned value is with respect to the inner \ref rect. */ /*! \fn int QCPAxisRect::top() const - + Returns the pixel position of the top border of this axis rect. Margins are not taken into account here, so the returned value is with respect to the inner \ref rect. */ /*! \fn int QCPAxisRect::bottom() const - + Returns the pixel position of the bottom border of this axis rect. Margins are not taken into account here, so the returned value is with respect to the inner \ref rect. */ /*! \fn int QCPAxisRect::width() const - + Returns the pixel width of this axis rect. Margins are not taken into account here, so the returned value is with respect to the inner \ref rect. */ /*! \fn int QCPAxisRect::height() const - + Returns the pixel height of this axis rect. Margins are not taken into account here, so the returned value is with respect to the inner \ref rect. */ /*! \fn QSize QCPAxisRect::size() const - + Returns the pixel size of this axis rect. Margins are not taken into account here, so the returned value is with respect to the inner \ref rect. */ /*! \fn QPoint QCPAxisRect::topLeft() const - + Returns the top left corner of this axis rect in pixels. Margins are not taken into account here, so the returned value is with respect to the inner \ref rect. */ /*! \fn QPoint QCPAxisRect::topRight() const - + Returns the top right corner of this axis rect in pixels. Margins are not taken into account here, so the returned value is with respect to the inner \ref rect. */ /*! \fn QPoint QCPAxisRect::bottomLeft() const - + Returns the bottom left corner of this axis rect in pixels. Margins are not taken into account here, so the returned value is with respect to the inner \ref rect. */ /*! \fn QPoint QCPAxisRect::bottomRight() const - + Returns the bottom right corner of this axis rect in pixels. Margins are not taken into account here, so the returned value is with respect to the inner \ref rect. */ /*! \fn QPoint QCPAxisRect::center() const - + Returns the center of this axis rect in pixels. Margins are not taken into account here, so the returned value is with respect to the inner \ref rect. */ @@ -17567,14 +17587,14 @@ QCPAxisRect::QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes) : mInsetLayout->initializeParentPlot(mParentPlot); mInsetLayout->setParentLayerable(this); mInsetLayout->setParent(this); - + setMinimumSize(50, 50); setMinimumMargins(QMargins(15, 15, 15, 15)); mAxes.insert(QCPAxis::atLeft, QList()); mAxes.insert(QCPAxis::atRight, QList()); mAxes.insert(QCPAxis::atTop, QList()); mAxes.insert(QCPAxis::atBottom, QList()); - + if (setupDefaultAxes) { QCPAxis *xAxis = addAxis(QCPAxis::atBottom); @@ -17600,14 +17620,14 @@ QCPAxisRect::~QCPAxisRect() { delete mInsetLayout; mInsetLayout = nullptr; - + foreach (QCPAxis *axis, axes()) removeAxis(axis); } /*! Returns the number of axes on the axis rect side specified with \a type. - + \see axis */ int QCPAxisRect::axisCount(QCPAxis::AxisType type) const @@ -17617,7 +17637,7 @@ int QCPAxisRect::axisCount(QCPAxis::AxisType type) const /*! Returns the axis with the given \a index on the axis rect side specified with \a type. - + \see axisCount, axes */ QCPAxis *QCPAxisRect::axis(QCPAxis::AxisType type, int index) const @@ -17635,10 +17655,10 @@ QCPAxis *QCPAxisRect::axis(QCPAxis::AxisType type, int index) const /*! Returns all axes on the axis rect sides specified with \a types. - + \a types may be a single \ref QCPAxis::AxisType or an or-combination, to get the axes of multiple sides. - + \see axis */ QList QCPAxisRect::axes(QCPAxis::AxisTypes types) const @@ -17656,7 +17676,7 @@ QList QCPAxisRect::axes(QCPAxis::AxisTypes types) const } /*! \overload - + Returns all axes of this axis rect. */ QList QCPAxisRect::axes() const @@ -17722,7 +17742,7 @@ QCPAxis *QCPAxisRect::addAxis(QCPAxis::AxisType type, QCPAxis *axis) newAxis->setUpperEnding(QCPLineEnding(QCPLineEnding::esHalfBar, 6, 10, invert)); } mAxes[type].append(newAxis); - + // reset convenience axis pointers on parent QCustomPlot if they are unset: if (mParentPlot && mParentPlot->axisRectCount() > 0 && mParentPlot->axisRect(0) == this) { @@ -17734,16 +17754,16 @@ QCPAxis *QCPAxisRect::addAxis(QCPAxis::AxisType type, QCPAxis *axis) case QCPAxis::atRight: { if (!mParentPlot->yAxis2) mParentPlot->yAxis2 = newAxis; break; } } } - + return newAxis; } /*! Adds a new axis with \ref addAxis to each axis rect side specified in \a types. This may be an or-combination of QCPAxis::AxisType, so axes can be added to multiple sides at once. - + Returns a list of the added axes. - + \see addAxis, setupFullAxesBox */ QList QCPAxisRect::addAxes(QCPAxis::AxisTypes types) @@ -17762,9 +17782,9 @@ QList QCPAxisRect::addAxes(QCPAxis::AxisTypes types) /*! Removes the specified \a axis from the axis rect and deletes it. - + Returns true on success, i.e. if \a axis was a valid axis in this axis rect. - + \see addAxis */ bool QCPAxisRect::removeAxis(QCPAxis *axis) @@ -17794,7 +17814,7 @@ bool QCPAxisRect::removeAxis(QCPAxis *axis) All axes of this axis rect will have their range zoomed accordingly. If you only wish to zoom specific axes, use the overloaded version of this method. - + \see QCustomPlot::setSelectionRectMode */ void QCPAxisRect::zoom(const QRectF &pixelRect) @@ -17803,11 +17823,11 @@ void QCPAxisRect::zoom(const QRectF &pixelRect) } /*! \overload - + Zooms in (or out) to the passed rectangular region \a pixelRect, given in pixel coordinates. - + Only the axes passed in \a affectedAxes will have their ranges zoomed accordingly. - + \see QCustomPlot::setSelectionRectMode */ void QCPAxisRect::zoom(const QRectF &pixelRect, const QList &affectedAxes) @@ -17854,29 +17874,29 @@ void QCPAxisRect::setupFullAxesBox(bool connectRanges) xAxis = addAxis(QCPAxis::atBottom); else xAxis = axis(QCPAxis::atBottom); - + if (axisCount(QCPAxis::atLeft) == 0) yAxis = addAxis(QCPAxis::atLeft); else yAxis = axis(QCPAxis::atLeft); - + if (axisCount(QCPAxis::atTop) == 0) xAxis2 = addAxis(QCPAxis::atTop); else xAxis2 = axis(QCPAxis::atTop); - + if (axisCount(QCPAxis::atRight) == 0) yAxis2 = addAxis(QCPAxis::atRight); else yAxis2 = axis(QCPAxis::atRight); - + xAxis->setVisible(true); yAxis->setVisible(true); xAxis2->setVisible(true); yAxis2->setVisible(true); xAxis2->setTickLabels(false); yAxis2->setTickLabels(false); - + xAxis2->setRange(xAxis->range()); xAxis2->setRangeReversed(xAxis->rangeReversed()); xAxis2->setScaleType(xAxis->scaleType()); @@ -17885,7 +17905,7 @@ void QCPAxisRect::setupFullAxesBox(bool connectRanges) xAxis2->setNumberPrecision(xAxis->numberPrecision()); xAxis2->ticker()->setTickCount(xAxis->ticker()->tickCount()); xAxis2->ticker()->setTickOrigin(xAxis->ticker()->tickOrigin()); - + yAxis2->setRange(yAxis->range()); yAxis2->setRangeReversed(yAxis->rangeReversed()); yAxis2->setScaleType(yAxis->scaleType()); @@ -17894,7 +17914,7 @@ void QCPAxisRect::setupFullAxesBox(bool connectRanges) yAxis2->setNumberPrecision(yAxis->numberPrecision()); yAxis2->ticker()->setTickCount(yAxis->ticker()->tickCount()); yAxis2->ticker()->setTickOrigin(yAxis->ticker()->tickOrigin()); - + if (connectRanges) { connect(xAxis, SIGNAL(rangeChanged(QCPRange)), xAxis2, SLOT(setRange(QCPRange))); @@ -17904,10 +17924,10 @@ void QCPAxisRect::setupFullAxesBox(bool connectRanges) /*! Returns a list of all the plottables that are associated with this axis rect. - + A plottable is considered associated with an axis rect if its key or value axis (or both) is in this axis rect. - + \see graphs, items */ QList QCPAxisRect::plottables() const @@ -17924,10 +17944,10 @@ QList QCPAxisRect::plottables() const /*! Returns a list of all the graphs that are associated with this axis rect. - + A graph is considered associated with an axis rect if its key or value axis (or both) is in this axis rect. - + \see plottables, items */ QList QCPAxisRect::graphs() const @@ -17944,12 +17964,12 @@ QList QCPAxisRect::graphs() const /*! Returns a list of all the items that are associated with this axis rect. - + An item is considered associated with an axis rect if any of its positions has key or value axis set to an axis that is in this axis rect, or if any of its positions has \ref QCPItemPosition::setAxisRect set to the axis rect, or if the clip axis rect (\ref QCPAbstractItem::setClipAxisRect) is set to this axis rect. - + \see plottables, graphs */ QList QCPAxisRect::items() const @@ -17981,17 +18001,17 @@ QList QCPAxisRect::items() const /*! This method is called automatically upon replot and doesn't need to be called by users of QCPAxisRect. - + Calls the base class implementation to update the margins (see \ref QCPLayoutElement::update), and finally passes the \ref rect to the inset layout (\ref insetLayout) and calls its QCPInsetLayout::update function. - + \seebaseclassmethod */ void QCPAxisRect::update(UpdatePhase phase) { QCPLayoutElement::update(phase); - + switch (phase) { case upPreparation: @@ -18007,7 +18027,7 @@ void QCPAxisRect::update(UpdatePhase phase) } default: break; } - + // pass update call on to inset layout (doesn't happen automatically, because QCPAxisRect doesn't derive from QCPLayout): mInsetLayout->update(phase); } @@ -18049,7 +18069,7 @@ void QCPAxisRect::draw(QCPPainter *painter) Below the pixmap, the axis rect may be optionally filled with a brush, if specified with \ref setBackground(const QBrush &brush). - + \see setBackgroundScaled, setBackgroundScaledMode, setBackground(const QBrush &brush) */ void QCPAxisRect::setBackground(const QPixmap &pm) @@ -18059,7 +18079,7 @@ void QCPAxisRect::setBackground(const QPixmap &pm) } /*! \overload - + Sets \a brush as the background brush. The axis rect background will be filled with this brush. Since axis rects place themselves on the "background" layer by default, the axis rect backgrounds are usually drawn below everything else. @@ -18068,7 +18088,7 @@ void QCPAxisRect::setBackground(const QPixmap &pm) setBackground(const QPixmap &pm). To disable drawing of a background brush, set \a brush to Qt::NoBrush. - + \see setBackground(const QPixmap &pm) */ void QCPAxisRect::setBackground(const QBrush &brush) @@ -18077,7 +18097,7 @@ void QCPAxisRect::setBackground(const QBrush &brush) } /*! \overload - + Allows setting the background pixmap of the axis rect, whether it shall be scaled and how it shall be scaled in one call. @@ -18095,10 +18115,10 @@ void QCPAxisRect::setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioM Sets whether the axis background pixmap shall be scaled to fit the axis rect or not. If \a scaled is set to true, you may control whether and how the aspect ratio of the original pixmap is preserved with \ref setBackgroundScaledMode. - + Note that the scaled version of the original pixmap is buffered, so there is no performance penalty on replots. (Except when the axis rect dimensions are changed continuously.) - + \see setBackground, setBackgroundScaledMode */ void QCPAxisRect::setBackgroundScaled(bool scaled) @@ -18198,7 +18218,7 @@ QList QCPAxisRect::rangeZoomAxes(Qt::Orientation orientation) /*! Returns the range zoom factor of the \a orientation provided. - + \see setRangeZoomFactor */ double QCPAxisRect::rangeZoomFactor(Qt::Orientation orientation) @@ -18212,14 +18232,14 @@ double QCPAxisRect::rangeZoomFactor(Qt::Orientation orientation) \ref setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical). By default, the horizontal axis is the bottom axis (xAxis) and the vertical axis is the left axis (yAxis). - + To disable range dragging entirely, pass \c nullptr as \a orientations or remove \ref QCP::iRangeDrag from \ref QCustomPlot::setInteractions. To enable range dragging for both directions, pass Qt::Horizontal | Qt::Vertical as \a orientations. - + In addition to setting \a orientations to a non-zero value, make sure \ref QCustomPlot::setInteractions contains \ref QCP::iRangeDrag to enable the range dragging interaction. - + \see setRangeZoom, setRangeDragAxes, QCustomPlot::setNoAntialiasingOnDrag */ void QCPAxisRect::setRangeDrag(Qt::Orientations orientations) @@ -18236,10 +18256,10 @@ void QCPAxisRect::setRangeDrag(Qt::Orientations orientations) To disable range zooming entirely, pass \c nullptr as \a orientations or remove \ref QCP::iRangeZoom from \ref QCustomPlot::setInteractions. To enable range zooming for both directions, pass Qt::Horizontal | Qt::Vertical as \a orientations. - + In addition to setting \a orientations to a non-zero value, make sure \ref QCustomPlot::setInteractions contains \ref QCP::iRangeZoom to enable the range zooming interaction. - + \see setRangeZoomFactor, setRangeZoomAxes, setRangeDrag */ void QCPAxisRect::setRangeZoom(Qt::Orientations orientations) @@ -18248,7 +18268,7 @@ void QCPAxisRect::setRangeZoom(Qt::Orientations orientations) } /*! \overload - + Sets the axes whose range will be dragged when \ref setRangeDrag enables mouse range dragging on the QCustomPlot widget. Pass \c nullptr if no axis shall be dragged in the respective orientation. @@ -18407,7 +18427,7 @@ void QCPAxisRect::setRangeZoomFactor(double horizontalFactor, double verticalFac } /*! \overload - + Sets both the horizontal and vertical zoom \a factor. */ void QCPAxisRect::setRangeZoomFactor(double factor) @@ -18417,13 +18437,13 @@ void QCPAxisRect::setRangeZoomFactor(double factor) } /*! \internal - + Draws the background of this axis rect. It may consist of a background fill (a QBrush) and a pixmap. - + If a brush was given via \ref setBackground(const QBrush &brush), this function first draws an according filling inside the axis rect with the provided \a painter. - + Then, if a pixmap was provided via \ref setBackground, this function buffers the scaled version depending on \ref setBackgroundScaled and \ref setBackgroundScaledMode and then draws it inside the axis rect with the provided \a painter. The scaled version is buffered in @@ -18431,7 +18451,7 @@ void QCPAxisRect::setRangeZoomFactor(double factor) the axis rect has changed in a way that requires a rescale of the background pixmap (this is dependent on the \ref setBackgroundScaledMode), or when a differend axis background pixmap was set. - + \see setBackground, setBackgroundScaled, setBackgroundScaledMode */ void QCPAxisRect::drawBackground(QCPPainter *painter) @@ -18439,7 +18459,7 @@ void QCPAxisRect::drawBackground(QCPPainter *painter) // draw background fill: if (mBackgroundBrush != Qt::NoBrush) painter->fillRect(mRect, mBackgroundBrush); - + // draw background pixmap (on top of fill, if brush specified): if (!mBackgroundPixmap.isNull()) { @@ -18459,13 +18479,13 @@ void QCPAxisRect::drawBackground(QCPPainter *painter) } /*! \internal - + This function makes sure multiple axes on the side specified with \a type don't collide, but are distributed according to their respective space requirement (QCPAxis::calculateMargin). - + It does this by setting an appropriate offset (\ref QCPAxis::setOffset) on all axes except the one with index zero. - + This function is called by \ref calculateAutoMargin. */ void QCPAxisRect::updateAxesOffset(QCPAxis::AxisType type) @@ -18473,7 +18493,7 @@ void QCPAxisRect::updateAxesOffset(QCPAxis::AxisType type) const QList axesList = mAxes.value(type); if (axesList.isEmpty()) return; - + bool isFirstVisible = !axesList.first()->visible(); // if the first axis is visible, the second axis (which is where the loop starts) isn't the first visible axis, so initialize with false for (int i=1; i axesList = mAxes.value(QCPAxis::marginSideToAxisType(side)); if (!axesList.isEmpty()) @@ -18505,12 +18525,12 @@ int QCPAxisRect::calculateAutoMargin(QCP::MarginSide side) } /*! \internal - + Reacts to a change in layout to potentially set the convenience axis pointers \ref QCustomPlot::xAxis, \ref QCustomPlot::yAxis, etc. of the parent QCustomPlot to the respective axes of this axis rect. This is only done if the respective convenience pointer is currently zero and if there is no QCPAxisRect at position (0, 0) of the plot layout. - + This automation makes it simpler to replace the main axis rect with a newly created one, without the need to manually reset the convenience pointers. */ @@ -18530,14 +18550,14 @@ void QCPAxisRect::layoutChanged() } /*! \internal - + Event handler for when a mouse button is pressed on the axis rect. If the left mouse button is pressed, the range dragging interaction is initialized (the actual range manipulation happens in the \ref mouseMoveEvent). The mDragging flag is set to true and some anchor points are set that are needed to determine the distance the mouse was dragged in the mouse move/release events later. - + \see mouseMoveEvent, mouseReleaseEvent */ void QCPAxisRect::mousePressEvent(QMouseEvent *event, const QVariant &details) @@ -18566,10 +18586,10 @@ void QCPAxisRect::mousePressEvent(QMouseEvent *event, const QVariant &details) } /*! \internal - + Event handler for when the mouse is moved on the axis rect. If range dragging was activated in a preceding \ref mousePressEvent, the range is moved accordingly. - + \see mousePressEvent, mouseReleaseEvent */ void QCPAxisRect::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) @@ -18578,7 +18598,7 @@ void QCPAxisRect::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) // Mouse range dragging interaction: if (mDragging && mParentPlot->interactions().testFlag(QCP::iRangeDrag)) { - + if (mRangeDrag.testFlag(Qt::Horizontal)) { for (int i=0; inoAntialiasingOnDrag()) mParentPlot->setNotAntialiasedElements(QCP::aeAll); mParentPlot->replot(QCustomPlot::rpQueuedReplot); } - + } } @@ -18645,13 +18665,13 @@ void QCPAxisRect::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) } /*! \internal - + Event handler for mouse wheel events. If rangeZoom is Qt::Horizontal, Qt::Vertical or both, the ranges of the axes defined as rangeZoomHorzAxis and rangeZoomVertAxis are scaled. The center of the scaling operation is the current cursor position inside the axis rect. The scaling factor is dependent on the mouse wheel delta (which direction the wheel was rotated) to provide a natural zooming feel. The Strength of the zoom can be controlled via \ref setRangeZoomFactor. - + Note, that event->angleDelta() is usually +/-120 for single rotation steps. However, if the mouse wheel is turned rapidly, many steps may bunch up to one event, so the delta may then be multiples of 120. This is taken into account here, by calculating \a wheelSteps and using it as exponent of @@ -18665,13 +18685,13 @@ void QCPAxisRect::wheelEvent(QWheelEvent *event) #else const double delta = event->angleDelta().y(); #endif - + #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) const QPointF pos = event->pos(); #else const QPointF pos = event->position(); #endif - + // Mouse range zooming interaction: if (mParentPlot->interactions().testFlag(QCP::iRangeZoom)) { @@ -18713,16 +18733,16 @@ void QCPAxisRect::wheelEvent(QWheelEvent *event) /*! \class QCPAbstractLegendItem \brief The abstract base class for all entries in a QCPLegend. - + It defines a very basic interface for entries in a QCPLegend. For representing plottables in the legend, the subclass \ref QCPPlottableLegendItem is more suitable. - + Only derive directly from this class when you need absolute freedom (e.g. a custom legend entry that's not even associated with a plottable). You must implement the following pure virtual functions: \li \ref draw (from QCPLayerable) - + You inherit the following members you may use: @@ -18738,7 +18758,7 @@ void QCPAxisRect::wheelEvent(QWheelEvent *event) /* start of documentation of signals */ /*! \fn void QCPAbstractLegendItem::selectionChanged(bool selected) - + This signal is emitted when the selection state of this legend item has changed, either by user interaction or by a direct call to \ref setSelected. */ @@ -18765,7 +18785,7 @@ QCPAbstractLegendItem::QCPAbstractLegendItem(QCPLegend *parent) : /*! Sets the default font of this specific legend item to \a font. - + \see setTextColor, QCPLegend::setFont */ void QCPAbstractLegendItem::setFont(const QFont &font) @@ -18775,7 +18795,7 @@ void QCPAbstractLegendItem::setFont(const QFont &font) /*! Sets the default text color of this specific legend item to \a color. - + \see setFont, QCPLegend::setTextColor */ void QCPAbstractLegendItem::setTextColor(const QColor &color) @@ -18786,7 +18806,7 @@ void QCPAbstractLegendItem::setTextColor(const QColor &color) /*! When this legend item is selected, \a font is used to draw generic text, instead of the normal font set with \ref setFont. - + \see setFont, QCPLegend::setSelectedFont */ void QCPAbstractLegendItem::setSelectedFont(const QFont &font) @@ -18797,7 +18817,7 @@ void QCPAbstractLegendItem::setSelectedFont(const QFont &font) /*! When this legend item is selected, \a color is used to draw generic text, instead of the normal color set with \ref setTextColor. - + \see setTextColor, QCPLegend::setSelectedTextColor */ void QCPAbstractLegendItem::setSelectedTextColor(const QColor &color) @@ -18807,7 +18827,7 @@ void QCPAbstractLegendItem::setSelectedTextColor(const QColor &color) /*! Sets whether this specific legend item is selectable. - + \see setSelectedParts, QCustomPlot::setInteractions */ void QCPAbstractLegendItem::setSelectable(bool selectable) @@ -18821,10 +18841,10 @@ void QCPAbstractLegendItem::setSelectable(bool selectable) /*! Sets whether this specific legend item is selected. - + It is possible to set the selection state of this item by calling this function directly, even if setSelectable is set to false. - + \see setSelectableParts, QCustomPlot::setInteractions */ void QCPAbstractLegendItem::setSelected(bool selected) @@ -18843,7 +18863,7 @@ double QCPAbstractLegendItem::selectTest(const QPointF &pos, bool onlySelectable if (!mParentPlot) return -1; if (onlySelectable && (!mSelectable || !mParentLegend->selectableParts().testFlag(QCPLegend::spItems))) return -1; - + if (mRect.contains(pos.toPoint())) return mParentPlot->selectionTolerance()*0.99; else @@ -18894,13 +18914,13 @@ void QCPAbstractLegendItem::deselectEvent(bool *selectionStateChanged) /*! \class QCPPlottableLegendItem \brief A legend item representing a plottable with an icon and the plottable name. - + This is the standard legend item for plottables. It displays an icon of the plottable next to the plottable name. The icon is drawn by the respective plottable itself (\ref QCPAbstractPlottable::drawLegendIcon), and tries to give an intuitive symbol for the plottable. For example, the QCPGraph draws a centered horizontal line and/or a single scatter point in the middle. - + Legend items of this type are always associated with one plottable (retrievable via the plottable() function and settable with the constructor). You may change the font of the plottable name with \ref setFont. Icon padding and border pen is taken from the parent QCPLegend, see \ref @@ -18908,7 +18928,7 @@ void QCPAbstractLegendItem::deselectEvent(bool *selectionStateChanged) The function \ref QCPAbstractPlottable::addToLegend/\ref QCPAbstractPlottable::removeFromLegend creates/removes legend items of this type. - + Since QCPLegend is based on QCPLayoutGrid, a legend item itself is just a subclass of QCPLayoutElement. While it could be added to a legend (or any other layout) via the normal layout interface, QCPLegend has specialized functions for handling legend items conveniently, see the @@ -18917,9 +18937,9 @@ void QCPAbstractLegendItem::deselectEvent(bool *selectionStateChanged) /*! Creates a new legend item associated with \a plottable. - + Once it's created, it can be added to the legend via \ref QCPLegend::addItem. - + A more convenient way of adding/removing a plottable to/from the legend is via the functions \ref QCPAbstractPlottable::addToLegend and \ref QCPAbstractPlottable::removeFromLegend. */ @@ -18931,7 +18951,7 @@ QCPPlottableLegendItem::QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlo } /*! \internal - + Returns the pen that shall be used to draw the icon border, taking into account the selection state of this item. */ @@ -18941,7 +18961,7 @@ QPen QCPPlottableLegendItem::getIconBorderPen() const } /*! \internal - + Returns the text color that shall be used to draw text, taking into account the selection state of this item. */ @@ -18951,7 +18971,7 @@ QColor QCPPlottableLegendItem::getTextColor() const } /*! \internal - + Returns the font that shall be used to draw text, taking into account the selection state of this item. */ @@ -18961,7 +18981,7 @@ QFont QCPPlottableLegendItem::getFont() const } /*! \internal - + Draws the item with \a painter. The size and position of the drawn legend item is defined by the parent layout (typically a \ref QCPLegend) and the \ref minimumOuterSizeHint and \ref maximumOuterSizeHint of this legend item. @@ -18993,10 +19013,10 @@ void QCPPlottableLegendItem::draw(QCPPainter *painter) } /*! \internal - + Calculates and returns the size of this item. This includes the icon, the text and the padding in between. - + \seebaseclassmethod */ QSize QCPPlottableLegendItem::minimumOuterSizeHint() const @@ -19058,7 +19078,7 @@ QSize QCPPlottableLegendItem::minimumOuterSizeHint() const /*! \fn void QCPLegend::selectionChanged(QCPLegend::SelectableParts selection); This signal is emitted when the selection state of this legend has changed. - + \see setSelectedParts, setSelectableParts */ @@ -19066,7 +19086,7 @@ QSize QCPPlottableLegendItem::minimumOuterSizeHint() const /*! Constructs a new QCPLegend instance with default values. - + Note that by default, QCustomPlot already contains a legend ready to be used as \ref QCustomPlot::legend */ @@ -19075,18 +19095,18 @@ QCPLegend::QCPLegend() : { setFillOrder(QCPLayoutGrid::foRowsFirst); setWrap(0); - + setRowSpacing(3); setColumnSpacing(8); setMargins(QMargins(7, 5, 7, 4)); setAntialiased(false); setIconSize(32, 18); - + setIconTextPadding(7); - + setSelectableParts(spLegendBox | spItems); setSelectedParts(spNone); - + setBorderPen(QPen(Qt::black, 0)); setSelectedBorderPen(QPen(Qt::blue, 2)); setIconBorderPen(Qt::NoPen); @@ -19143,9 +19163,9 @@ void QCPLegend::setBrush(const QBrush &brush) Sets the default font of legend text. Legend items that draw text (e.g. the name of a graph) will use this font by default. However, a different font can be specified on a per-item-basis by accessing the specific legend item. - + This function will also set \a font on all already existing legend items. - + \see QCPAbstractLegendItem::setFont */ void QCPLegend::setFont(const QFont &font) @@ -19162,9 +19182,9 @@ void QCPLegend::setFont(const QFont &font) Sets the default color of legend text. Legend items that draw text (e.g. the name of a graph) will use this color by default. However, a different colors can be specified on a per-item-basis by accessing the specific legend item. - + This function will also set \a color on all already existing legend items. - + \see QCPAbstractLegendItem::setTextColor */ void QCPLegend::setTextColor(const QColor &color) @@ -19207,7 +19227,7 @@ void QCPLegend::setIconTextPadding(int padding) /*! Sets the pen used to draw a border around each legend icon. Legend items that draw an icon (e.g. a visual representation of the graph) will use this pen by default. - + If no border is wanted, set this to \a Qt::NoPen. */ void QCPLegend::setIconBorderPen(const QPen &pen) @@ -19218,11 +19238,11 @@ void QCPLegend::setIconBorderPen(const QPen &pen) /*! Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface. (When \ref QCustomPlot::setInteractions contains \ref QCP::iSelectLegend.) - + However, even when \a selectable is set to a value not allowing the selection of a specific part, it is still possible to set the selection of this part manually, by calling \ref setSelectedParts directly. - + \see SelectablePart, setSelectedParts */ void QCPLegend::setSelectableParts(const SelectableParts &selectable) @@ -19238,20 +19258,20 @@ void QCPLegend::setSelectableParts(const SelectableParts &selectable) Sets the selected state of the respective legend parts described by \ref SelectablePart. When a part is selected, it uses a different pen/font and brush. If some legend items are selected and \a selected doesn't contain \ref spItems, those items become deselected. - + The entire selection mechanism is handled automatically when \ref QCustomPlot::setInteractions contains iSelectLegend. You only need to call this function when you wish to change the selection state manually. - + This function can change the selection state of a part even when \ref setSelectableParts was set to a value that actually excludes the part. - + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. - + Note that it doesn't make sense to set the selected state \ref spItems here when it wasn't set before, because there's no way to specify which exact items to newly select. Do this by calling \ref QCPAbstractLegendItem::setSelected directly on the legend item you wish to select. - + \see SelectablePart, setSelectableParts, selectTest, setSelectedBorderPen, setSelectedIconBorderPen, setSelectedBrush, setSelectedFont */ @@ -19314,7 +19334,7 @@ void QCPLegend::setSelectedBrush(const QBrush &brush) /*! Sets the default font that is used by legend items when they are selected. - + This function will also set \a font on all already existing legend items. \see setFont, QCPAbstractLegendItem::setSelectedFont @@ -19331,7 +19351,7 @@ void QCPLegend::setSelectedFont(const QFont &font) /*! Sets the default text color that is used by legend items when they are selected. - + This function will also set \a color on all already existing legend items. \see setTextColor, QCPAbstractLegendItem::setSelectedTextColor @@ -19362,7 +19382,7 @@ QCPAbstractLegendItem *QCPLegend::item(int index) const /*! Returns the QCPPlottableLegendItem which is associated with \a plottable (e.g. a \ref QCPGraph*). If such an item isn't in the legend, returns \c nullptr. - + \see hasItemWithPlottable */ QCPPlottableLegendItem *QCPLegend::itemWithPlottable(const QCPAbstractPlottable *plottable) const @@ -19395,7 +19415,7 @@ int QCPLegend::itemCount() const /*! Returns whether the legend contains \a item. - + \see hasItemWithPlottable */ bool QCPLegend::hasItem(QCPAbstractLegendItem *item) const @@ -19411,7 +19431,7 @@ bool QCPLegend::hasItem(QCPAbstractLegendItem *item) const /*! Returns whether the legend contains a QCPPlottableLegendItem which is associated with \a plottable (e.g. a \ref QCPGraph*). If such an item isn't in the legend, returns false. - + \see itemWithPlottable */ bool QCPLegend::hasItemWithPlottable(const QCPAbstractPlottable *plottable) const @@ -19495,7 +19515,7 @@ void QCPLegend::clearItems() /*! Returns the legend items that are currently selected. If no items are selected, the list is empty. - + \see QCPAbstractLegendItem::setSelected, setSelectable */ QList QCPLegend::selectedItems() const @@ -19518,13 +19538,13 @@ QList QCPLegend::selectedItems() const before drawing main legend elements. This is the antialiasing state the painter passed to the \ref draw method is in by default. - + This function takes into account the local setting of the antialiasing flag as well as the overrides set with \ref QCustomPlot::setAntialiasedElements and \ref QCustomPlot::setNotAntialiasedElements. - + \seebaseclassmethod - + \see setAntialiased */ void QCPLegend::applyDefaultAntialiasingHint(QCPPainter *painter) const @@ -19533,7 +19553,7 @@ void QCPLegend::applyDefaultAntialiasingHint(QCPPainter *painter) const } /*! \internal - + Returns the pen used to paint the border of the legend, taking into account the selection state of the legend box. */ @@ -19543,7 +19563,7 @@ QPen QCPLegend::getBorderPen() const } /*! \internal - + Returns the brush used to paint the background of the legend, taking into account the selection state of the legend box. */ @@ -19553,7 +19573,7 @@ QBrush QCPLegend::getBrush() const } /*! \internal - + Draws the legend box with the provided \a painter. The individual legend items are layerables themselves, thus are drawn independently. */ @@ -19571,7 +19591,7 @@ double QCPLegend::selectTest(const QPointF &pos, bool onlySelectable, QVariant * if (!mParentPlot) return -1; if (onlySelectable && !mSelectableParts.testFlag(spLegendBox)) return -1; - + if (mOuterRect.contains(pos.toPoint())) { if (details) details->setValue(spLegendBox); @@ -19648,10 +19668,10 @@ void QCPLegend::parentPlotInitialized(QCustomPlot *parentPlot) /* start documentation of signals */ /*! \fn void QCPTextElement::selectionChanged(bool selected) - + This signal is emitted when the selection state has changed to \a selected, either by user interaction or by a direct call to \ref setSelected. - + \see setSelected, setSelectable */ @@ -19672,7 +19692,7 @@ void QCPLegend::parentPlotInitialized(QCustomPlot *parentPlot) /* end documentation of signals */ /*! \overload - + Creates a new QCPTextElement instance and sets default values. The initial text is empty (\ref setText). */ @@ -19696,7 +19716,7 @@ QCPTextElement::QCPTextElement(QCustomPlot *parentPlot) : } /*! \overload - + Creates a new QCPTextElement instance and sets default values. The initial text is set to \a text. @@ -19721,7 +19741,7 @@ QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text) : } /*! \overload - + Creates a new QCPTextElement instance and sets default values. The initial text is set to \a text with \a pointSize. @@ -19749,7 +19769,7 @@ QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, dou } /*! \overload - + Creates a new QCPTextElement instance and sets default values. The initial text is set to \a text with \a pointSize and the specified \a fontFamily. @@ -19770,7 +19790,7 @@ QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, con } /*! \overload - + Creates a new QCPTextElement instance and sets default values. The initial text is set to \a text with the specified \a font. @@ -19791,7 +19811,7 @@ QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, con /*! Sets the text that will be displayed to \a text. Multiple lines can be created by insertion of "\n". - + \see setFont, setTextColor, setTextFlags */ void QCPTextElement::setText(const QString &text) @@ -19802,7 +19822,7 @@ void QCPTextElement::setText(const QString &text) /*! Sets options for text alignment and wrapping behaviour. \a flags is a bitwise OR-combination of \c Qt::AlignmentFlag and \c Qt::TextFlag enums. - + Possible enums are: - Qt::AlignLeft - Qt::AlignRight @@ -19826,7 +19846,7 @@ void QCPTextElement::setTextFlags(int flags) /*! Sets the \a font of the text. - + \see setTextColor, setSelectedFont */ void QCPTextElement::setFont(const QFont &font) @@ -19836,7 +19856,7 @@ void QCPTextElement::setFont(const QFont &font) /*! Sets the \a color of the text. - + \see setFont, setSelectedTextColor */ void QCPTextElement::setTextColor(const QColor &color) @@ -19846,7 +19866,7 @@ void QCPTextElement::setTextColor(const QColor &color) /*! Sets the \a font of the text that will be used if the text element is selected (\ref setSelected). - + \see setFont */ void QCPTextElement::setSelectedFont(const QFont &font) @@ -19856,7 +19876,7 @@ void QCPTextElement::setSelectedFont(const QFont &font) /*! Sets the \a color of the text that will be used if the text element is selected (\ref setSelected). - + \see setTextColor */ void QCPTextElement::setSelectedTextColor(const QColor &color) @@ -19882,7 +19902,7 @@ void QCPTextElement::setSelectable(bool selectable) /*! Sets the selection state of this text element to \a selected. If the selection has changed, \ref selectionChanged is emitted. - + Note that this function can change the selection state independently of the current \ref setSelectable state. */ @@ -19970,7 +19990,7 @@ double QCPTextElement::selectTest(const QPointF &pos, bool onlySelectable, QVari Q_UNUSED(details) if (onlySelectable && !mSelectable) return -1; - + if (mTextBoundingRect.contains(pos.toPoint())) return mParentPlot->selectionTolerance()*0.99; else @@ -20013,7 +20033,7 @@ void QCPTextElement::mouseDoubleClickEvent(QMouseEvent *event, const QVariant &d } /*! \internal - + Returns the main font to be used. This is mSelectedFont if \ref setSelected is set to true, else mFont is returned. */ @@ -20023,7 +20043,7 @@ QFont QCPTextElement::mainFont() const } /*! \internal - + Returns the main color to be used. This is mSelectedTextColor if \ref setSelected is set to true, else mTextColor is returned. */ @@ -20044,35 +20064,35 @@ QColor QCPTextElement::mainTextColor() const /*! \class QCPColorScale \brief A color scale for use with color coding data such as QCPColorMap - + This layout element can be placed on the plot to correlate a color gradient with data values. It is usually used in combination with one or multiple \ref QCPColorMap "QCPColorMaps". \image html QCPColorScale.png - + The color scale can be either horizontal or vertical, as shown in the image above. The orientation and the side where the numbers appear is controlled with \ref setType. - + Use \ref QCPColorMap::setColorScale to connect a color map with a color scale. Once they are connected, they share their gradient, data range and data scale type (\ref setGradient, \ref setDataRange, \ref setDataScaleType). Multiple color maps may be associated with a single color scale, to make them all synchronize these properties. - + To have finer control over the number display and axis behaviour, you can directly access the \ref axis. See the documentation of QCPAxis for details about configuring axes. For example, if you want to change the number of automatically generated ticks, call \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-tickcount - + Placing a color scale next to the main axis rect works like with any other layout element: \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-creation In this case we have placed it to the right of the default axis rect, so it wasn't necessary to call \ref setType, since \ref QCPAxis::atRight is already the default. The text next to the color scale can be set with \ref setLabel. - + For optimum appearance (like in the image above), it may be desirable to line up the axis rect and the borders of the color scale. Use a \ref QCPMarginGroup to achieve this: \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-margingroup - + Color scales are initialized with a non-zero minimum top and bottom margin (\ref setMinimumMargins), because vertical color scales are most common and the minimum top/bottom margin makes sure it keeps some distance to the top/bottom widget border. So if you change to a @@ -20083,14 +20103,14 @@ QColor QCPTextElement::mainTextColor() const /* start documentation of inline functions */ /*! \fn QCPAxis *QCPColorScale::axis() const - + Returns the internal \ref QCPAxis instance of this color scale. You can access it to alter the appearance and behaviour of the axis. \ref QCPColorScale duplicates some properties in its interface for convenience. Those are \ref setDataRange (\ref QCPAxis::setRange), \ref setDataScaleType (\ref QCPAxis::setScaleType), and the method \ref setLabel (\ref QCPAxis::setLabel). As they each are connected, it does not matter whether you use the method on the QCPColorScale or on its QCPAxis. - + If the type of the color scale is changed with \ref setType, the axis returned by this method will change, too, to either the left, right, bottom or top axis, depending on which type was set. */ @@ -20099,23 +20119,23 @@ QColor QCPTextElement::mainTextColor() const /* start documentation of signals */ /*! \fn void QCPColorScale::dataRangeChanged(const QCPRange &newRange); - + This signal is emitted when the data range changes. - + \see setDataRange */ /*! \fn void QCPColorScale::dataScaleTypeChanged(QCPAxis::ScaleType scaleType); - + This signal is emitted when the data scale type changes. - + \see setDataScaleType */ /*! \fn void QCPColorScale::gradientChanged(const QCPColorGradient &newGradient); - + This signal is emitted when the gradient changes. - + \see setGradient */ @@ -20150,7 +20170,7 @@ QString QCPColorScale::label() const qDebug() << Q_FUNC_INFO << "internal color axis undefined"; return QString(); } - + return mColorAxis.data()->label(); } @@ -20162,7 +20182,7 @@ bool QCPColorScale::rangeDrag() const qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; return false; } - + return mAxisRect.data()->rangeDrag().testFlag(QCPAxis::orientation(mType)) && mAxisRect.data()->rangeDragAxis(QCPAxis::orientation(mType)) && mAxisRect.data()->rangeDragAxis(QCPAxis::orientation(mType))->orientation() == QCPAxis::orientation(mType); @@ -20176,7 +20196,7 @@ bool QCPColorScale::rangeZoom() const qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; return false; } - + return mAxisRect.data()->rangeZoom().testFlag(QCPAxis::orientation(mType)) && mAxisRect.data()->rangeZoomAxis(QCPAxis::orientation(mType)) && mAxisRect.data()->rangeZoomAxis(QCPAxis::orientation(mType))->orientation() == QCPAxis::orientation(mType); @@ -20184,7 +20204,7 @@ bool QCPColorScale::rangeZoom() const /*! Sets at which side of the color scale the axis is placed, and thus also its orientation. - + Note that after setting \a type to a different value, the axis returned by \ref axis() will be a different one. The new axis will adopt the following properties from the previous axis: The range, scale type, label and ticker (the latter will be shared and not copied). @@ -20236,11 +20256,11 @@ void QCPColorScale::setType(QCPAxis::AxisType type) /*! Sets the range spanned by the color gradient and that is shown by the axis in the color scale. - + It is equivalent to calling QCPColorMap::setDataRange on any of the connected color maps. It is also equivalent to directly accessing the \ref axis and setting its range with \ref QCPAxis::setRange. - + \see setDataScaleType, setGradient, rescaleDataRange */ void QCPColorScale::setDataRange(const QCPRange &dataRange) @@ -20257,20 +20277,20 @@ void QCPColorScale::setDataRange(const QCPRange &dataRange) /*! Sets the scale type of the color scale, i.e. whether values are associated with colors linearly or logarithmically. - + It is equivalent to calling QCPColorMap::setDataScaleType on any of the connected color maps. It is also equivalent to directly accessing the \ref axis and setting its scale type with \ref QCPAxis::setScaleType. - + Note that this method controls the coordinate transformation. For logarithmic scales, you will likely also want to use a logarithmic tick spacing and labeling, which can be achieved by setting the color scale's \ref axis ticker to an instance of \ref QCPAxisTickerLog : - + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpaxisticker-log-colorscale - + See the documentation of \ref QCPAxisTickerLog about the details of logarithmic axis tick creation. - + \see setDataRange, setGradient */ void QCPColorScale::setDataScaleType(QCPAxis::ScaleType scaleType) @@ -20288,9 +20308,9 @@ void QCPColorScale::setDataScaleType(QCPAxis::ScaleType scaleType) /*! Sets the color gradient that will be used to represent data values. - + It is equivalent to calling QCPColorMap::setGradient on any of the connected color maps. - + \see setDataRange, setDataScaleType */ void QCPColorScale::setGradient(const QCPColorGradient &gradient) @@ -20315,7 +20335,7 @@ void QCPColorScale::setLabel(const QString &str) qDebug() << Q_FUNC_INFO << "internal color axis undefined"; return; } - + mColorAxis.data()->setLabel(str); } @@ -20330,7 +20350,7 @@ void QCPColorScale::setBarWidth(int width) /*! Sets whether the user can drag the data range (\ref setDataRange). - + Note that \ref QCP::iRangeDrag must be in the QCustomPlot's interactions (\ref QCustomPlot::setInteractions) to allow range dragging. */ @@ -20341,7 +20361,7 @@ void QCPColorScale::setRangeDrag(bool enabled) qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; return; } - + if (enabled) { mAxisRect.data()->setRangeDrag(QCPAxis::orientation(mType)); @@ -20357,7 +20377,7 @@ void QCPColorScale::setRangeDrag(bool enabled) /*! Sets whether the user can zoom the data range (\ref setDataRange) by scrolling the mouse wheel. - + Note that \ref QCP::iRangeZoom must be in the QCustomPlot's interactions (\ref QCustomPlot::setInteractions) to allow range dragging. */ @@ -20368,7 +20388,7 @@ void QCPColorScale::setRangeZoom(bool enabled) qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; return; } - + if (enabled) { mAxisRect.data()->setRangeZoom(QCPAxis::orientation(mType)); @@ -20400,7 +20420,7 @@ QList QCPColorScale::colorMaps() const /*! Changes the data range such that all color maps associated with this color scale are fully mapped to the gradient in the data dimension. - + \see setDataRange */ void QCPColorScale::rescaleDataRange(bool onlyVisibleMaps) @@ -20471,9 +20491,9 @@ void QCPColorScale::update(UpdatePhase phase) qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; return; } - + mAxisRect.data()->update(phase); - + switch (phase) { case upMargins: @@ -20556,9 +20576,9 @@ void QCPColorScale::wheelEvent(QWheelEvent *event) \internal \brief An axis rect subclass for use in a QCPColorScale - + This is a private class and not part of the public QCustomPlot interface. - + It provides the axis rect functionality for the QCPColorScale class. */ @@ -20591,7 +20611,7 @@ QCPColorScaleAxisRectPrivate::QCPColorScaleAxisRectPrivate(QCPColorScale *parent connect(axis(QCPAxis::atRight), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atLeft), SLOT(setScaleType(QCPAxis::ScaleType))); connect(axis(QCPAxis::atBottom), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atTop), SLOT(setScaleType(QCPAxis::ScaleType))); connect(axis(QCPAxis::atTop), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atBottom), SLOT(setScaleType(QCPAxis::ScaleType))); - + // make layer transfers of color scale transfer to axis rect and axes // the axes must be set after axis rect, such that they appear above color gradient drawn by axis rect: connect(parentColorScale, SIGNAL(layerChanged(QCPLayer*)), this, SLOT(setLayer(QCPLayer*))); @@ -20600,17 +20620,17 @@ QCPColorScaleAxisRectPrivate::QCPColorScaleAxisRectPrivate(QCPColorScale *parent } /*! \internal - + Updates the color gradient image if necessary, by calling \ref updateGradientImage, then draws it. Then the axes are drawn by calling the \ref QCPAxisRect::draw base class implementation. - + \seebaseclassmethod */ void QCPColorScaleAxisRectPrivate::draw(QCPPainter *painter) { if (mGradientImageInvalidated) updateGradientImage(); - + bool mirrorHorz = false; bool mirrorVert = false; if (mParentColorScale->mColorAxis) @@ -20618,8 +20638,14 @@ void QCPColorScaleAxisRectPrivate::draw(QCPPainter *painter) mirrorHorz = mParentColorScale->mColorAxis.data()->rangeReversed() && (mParentColorScale->type() == QCPAxis::atBottom || mParentColorScale->type() == QCPAxis::atTop); mirrorVert = mParentColorScale->mColorAxis.data()->rangeReversed() && (mParentColorScale->type() == QCPAxis::atLeft || mParentColorScale->type() == QCPAxis::atRight); } - - painter->drawImage(rect().adjusted(0, -1, 0, -1), mGradientImage.mirrored(mirrorHorz, mirrorVert)); + + // Qt 6.9.0 fix for depreciated function + // painter->drawImage(rect().adjusted(0, -1, 0, -1), mGradientImage.mirrored(mirrorHorz, mirrorVert)); + if (mirrorHorz) + painter->drawImage(rect().adjusted(0, -1, 0, -1), mGradientImage.flipped(Qt::Horizontal)); + if (mirrorVert) + painter->drawImage(rect().adjusted(0, -1, 0, -1), mGradientImage.flipped(Qt::Vertical)); + // end fix QCPAxisRect::draw(painter); } @@ -20632,7 +20658,7 @@ void QCPColorScaleAxisRectPrivate::updateGradientImage() { if (rect().isEmpty()) return; - + const QImage::Format format = QImage::Format_ARGB32_Premultiplied; int n = mParentColorScale->mGradient.levelCount(); int w, h; @@ -20680,7 +20706,7 @@ void QCPColorScaleAxisRectPrivate::axisSelectionChanged(QCPAxis::SelectableParts if (QCPAxis *senderAxis = qobject_cast(sender())) if (senderAxis->axisType() == type) continue; - + if (axis(type)->selectableParts().testFlag(QCPAxis::spAxis)) { if (selectedParts.testFlag(QCPAxis::spAxis)) @@ -20705,7 +20731,7 @@ void QCPColorScaleAxisRectPrivate::axisSelectableChanged(QCPAxis::SelectablePart if (QCPAxis *senderAxis = qobject_cast(sender())) if (senderAxis->axisType() == type) continue; - + if (axis(type)->selectableParts().testFlag(QCPAxis::spAxis)) { if (selectableParts.testFlag(QCPAxis::spAxis)) @@ -20727,65 +20753,65 @@ void QCPColorScaleAxisRectPrivate::axisSelectableChanged(QCPAxis::SelectablePart /*! \class QCPGraphData \brief Holds the data of one single data point for QCPGraph. - + The stored data is: \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey) \li \a value: coordinate on the value axis of this data point (this is the \a mainValue) - + The container for storing multiple data points is \ref QCPGraphDataContainer. It is a typedef for \ref QCPDataContainer with \ref QCPGraphData as the DataType template parameter. See the documentation there for an explanation regarding the data type's generic methods. - + \see QCPGraphDataContainer */ /* start documentation of inline functions */ /*! \fn double QCPGraphData::sortKey() const - + Returns the \a key member of this data point. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn static QCPGraphData QCPGraphData::fromSortKey(double sortKey) - + Returns a data point with the specified \a sortKey. All other members are set to zero. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn static static bool QCPGraphData::sortKeyIsMainKey() - + Since the member \a key is both the data point key coordinate and the data ordering parameter, this method returns true. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn double QCPGraphData::mainKey() const - + Returns the \a key member of this data point. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn double QCPGraphData::mainValue() const - + Returns the \a value member of this data point. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn QCPRange QCPGraphData::valueRange() const - + Returns a QCPRange with both lower and upper boundary set to \a value of this data point. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ @@ -20819,33 +20845,33 @@ QCPGraphData::QCPGraphData(double key, double value) : \brief A plottable representing a graph in a plot. \image html QCPGraph.png - + Usually you create new graphs by calling QCustomPlot::addGraph. The resulting instance can be accessed via QCustomPlot::graph. To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can also access and modify the data via the \ref data method, which returns a pointer to the internal \ref QCPGraphDataContainer. - + Graphs are used to display single-valued data. Single-valued means that there should only be one data point per unique key coordinate. In other words, the graph can't have \a loops. If you do want to plot non-single-valued curves, rather use the QCPCurve plottable. - + Gaps in the graph line can be created by adding data points with NaN as value (qQNaN() or std::numeric_limits::quiet_NaN()) in between the two data points that shall be separated. - + \section qcpgraph-appearance Changing the appearance - + The appearance of the graph is mainly determined by the line style, scatter style, brush and pen of the graph (\ref setLineStyle, \ref setScatterStyle, \ref setBrush, \ref setPen). - + \subsection filling Filling under or between graphs - + QCPGraph knows two types of fills: Normal graph fills towards the zero-value-line parallel to the key axis of the graph, and fills between two graphs, called channel fills. To enable a fill, just set a brush with \ref setBrush which is neither Qt::NoBrush nor fully transparent. - + By default, a normal fill towards the zero-value-line will be drawn. To set up a channel fill between this graph and another one, call \ref setChannelFillGraph with the other graph as parameter. @@ -20856,7 +20882,7 @@ QCPGraphData::QCPGraphData(double key, double value) : /* start of documentation of inline functions */ /*! \fn QSharedPointer QCPGraph::data() const - + Returns a shared pointer to the internal data storage of type \ref QCPGraphDataContainer. You may use it to directly manipulate the data, which may be more convenient and faster than using the regular \ref setData or \ref addData methods. @@ -20869,11 +20895,11 @@ QCPGraphData::QCPGraphData(double key, double value) : axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have the same orientation. If either of these restrictions is violated, a corresponding message is printed to the debug output (qDebug), the construction is not aborted, though. - + The created QCPGraph is automatically registered with the QCustomPlot instance inferred from \a keyAxis. This QCustomPlot instance takes ownership of the QCPGraph, so do not delete it manually but use QCustomPlot::removePlottable() instead. - + To directly create a graph inside a plot, you can also use the simpler QCustomPlot::addGraph function. */ QCPGraph::QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis) : @@ -20887,7 +20913,7 @@ QCPGraph::QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis) : setPen(QPen(Qt::blue, 0)); setBrush(Qt::NoBrush); - + setLineStyle(lsLine); setScatterSkip(0); setChannelFillGraph(nullptr); @@ -20899,18 +20925,18 @@ QCPGraph::~QCPGraph() } /*! \overload - + Replaces the current data container with the provided \a data container. - + Since a QSharedPointer is used, multiple QCPGraphs may share the same data container safely. Modifying the data in the container will then affect all graphs that share the container. Sharing can be achieved by simply exchanging the data containers wrapped in shared pointers: \snippet documentation/doc-code-snippets/mainwindow.cpp qcpgraph-datasharing-1 - + If you do not wish to share containers, but create a copy from an existing container, rather use the \ref QCPDataContainer::set method on the graph's data container directly: \snippet documentation/doc-code-snippets/mainwindow.cpp qcpgraph-datasharing-2 - + \see addData */ void QCPGraph::setData(QSharedPointer data) @@ -20919,14 +20945,14 @@ void QCPGraph::setData(QSharedPointer data) } /*! \overload - + Replaces the current data with the provided points in \a keys and \a values. The provided vectors should have equal length. Else, the number of added points will be the size of the smallest vector. - + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you can set \a alreadySorted to true, to improve performance by saving a sorting run. - + \see addData */ void QCPGraph::setData(const QVector &keys, const QVector &values, bool alreadySorted) @@ -20938,7 +20964,7 @@ void QCPGraph::setData(const QVector &keys, const QVector &value /*! Sets how the single data points are connected in the plot. For scatter-only plots, set \a ls to \ref lsNone and \ref setScatterStyle to the desired scatter style. - + \see setScatterStyle */ void QCPGraph::setLineStyle(LineStyle ls) @@ -20949,7 +20975,7 @@ void QCPGraph::setLineStyle(LineStyle ls) /*! Sets the visual appearance of single data points in the plot. If set to \ref QCPScatterStyle::ssNone, no scatter points are drawn (e.g. for line-only-plots with appropriate line style). - + \see QCPScatterStyle, setLineStyle */ void QCPGraph::setScatterStyle(const QCPScatterStyle &style) @@ -20976,7 +21002,7 @@ void QCPGraph::setScatterSkip(int skip) /*! Sets the target graph for filling the area between this graph and \a targetGraph with the current brush (\ref setBrush). - + When \a targetGraph is set to 0, a normal graph fill to the zero-value-line will be shown. To disable any filling, set the brush to Qt::NoBrush. @@ -20998,7 +21024,7 @@ void QCPGraph::setChannelFillGraph(QCPGraph *targetGraph) mChannelFillGraph = nullptr; return; } - + mChannelFillGraph = targetGraph; } @@ -21006,19 +21032,19 @@ void QCPGraph::setChannelFillGraph(QCPGraph *targetGraph) Sets whether adaptive sampling shall be used when plotting this graph. QCustomPlot's adaptive sampling technique can drastically improve the replot performance for graphs with a larger number of points (e.g. above 10,000), without notably changing the appearance of the graph. - + By default, adaptive sampling is enabled. Even if enabled, QCustomPlot decides whether adaptive sampling shall actually be used on a per-graph basis. So leaving adaptive sampling enabled has no disadvantage in almost all cases. - + \image html adaptive-sampling-line.png "A line plot of 500,000 points without and with adaptive sampling" - + As can be seen, line plots experience no visual degradation from adaptive sampling. Outliers are reproduced reliably, as well as the overall shape of the data set. The replot time reduces dramatically though. This allows QCustomPlot to display large amounts of data in realtime. - + \image html adaptive-sampling-scatter.png "A scatter plot of 100,000 points without and with adaptive sampling" - + Care must be taken when using high-density scatter plots in combination with adaptive sampling. The adaptive sampling algorithm treats scatter plots more carefully than line plots which still gives a significant reduction of replot times, but not quite as much as for line plots. This is @@ -21027,7 +21053,7 @@ void QCPGraph::setChannelFillGraph(QCPGraph *targetGraph) identical, as banding occurs for the outer data points. This is in fact intentional, such that the boundaries of the data cloud stay visible to the viewer. How strong the banding appears, depends on the point density, i.e. the number of points in the plot. - + For some situations with scatter plots it might thus be desirable to manually turn adaptive sampling off. For example, when saving the plot to disk. This can be achieved by setting \a enabled to false before issuing a command like \ref QCustomPlot::savePng, and setting \a enabled @@ -21039,14 +21065,14 @@ void QCPGraph::setAdaptiveSampling(bool enabled) } /*! \overload - + Adds the provided points in \a keys and \a values to the current data. The provided vectors should have equal length. Else, the number of added points will be the size of the smallest vector. - + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you can set \a alreadySorted to true, to improve performance by saving a sorting run. - + Alternatively, you can also access and modify the data directly via the \ref data method, which returns a pointer to the internal data container. */ @@ -21070,9 +21096,9 @@ void QCPGraph::addData(const QVector &keys, const QVector &value } /*! \overload - + Adds the provided data point as \a key and \a value to the current data. - + Alternatively, you can also access and modify the data directly via the \ref data method, which returns a pointer to the internal data container. */ @@ -21086,7 +21112,7 @@ void QCPGraph::addData(double key, double value) If \a details is not 0, it will be set to a \ref QCPDataSelection, describing the closest data point to \a pos. - + \seebaseclassmethod \ref QCPAbstractPlottable::selectTest */ double QCPGraph::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const @@ -21095,7 +21121,7 @@ double QCPGraph::selectTest(const QPointF &pos, bool onlySelectable, QVariant *d return -1; if (!mKeyAxis || !mValueAxis) return -1; - + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()) || mParentPlot->interactions().testFlag(QCP::iSelectPlottablesBeyondAxisRect)) { QCPGraphDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); @@ -21128,9 +21154,9 @@ void QCPGraph::draw(QCPPainter *painter) if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } if (mKeyAxis.data()->range().size() <= 0 || mDataContainer->isEmpty()) return; if (mLineStyle == lsNone && mScatterStyle.isNone()) return; - + QVector lines, scatters; // line and (if necessary) scatter pixel coordinates will be stored here while iterating over segments - + // loop over and draw segments of unselected/selected data: QList selectedSegments, unselectedSegments, allSegments; getDataSegments(selectedSegments, unselectedSegments); @@ -21141,7 +21167,7 @@ void QCPGraph::draw(QCPPainter *painter) // get line pixel points appropriate to line style: QCPDataRange lineDataRange = isSelectedSegment ? allSegments.at(i) : allSegments.at(i).adjusted(-1, 1); // unselected segments extend lines to bordering selected data point (safe to exceed total data bounds in first/last segment, getLines takes care) getLines(&lines, lineDataRange); - + // check data validity if flag set: #ifdef QCUSTOMPLOT_CHECK_DATA QCPGraphDataContainer::const_iterator it; @@ -21151,7 +21177,7 @@ void QCPGraph::draw(QCPPainter *painter) qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "invalid." << "Plottable name:" << name(); } #endif - + // draw fill of graph: if (isSelectedSegment && mSelectionDecorator) mSelectionDecorator->applyBrush(painter); @@ -21159,7 +21185,7 @@ void QCPGraph::draw(QCPPainter *painter) painter->setBrush(mBrush); painter->setPen(Qt::NoPen); drawFill(painter, &lines); - + // draw line: if (mLineStyle != lsNone) { @@ -21173,7 +21199,7 @@ void QCPGraph::draw(QCPPainter *painter) else drawLinePlot(painter, lines); // also step plots can be drawn as a line plot } - + // draw scatters: QCPScatterStyle finalScatterStyle = mScatterStyle; if (isSelectedSegment && mSelectionDecorator) @@ -21184,7 +21210,7 @@ void QCPGraph::draw(QCPPainter *painter) drawScatterPlot(painter, scatters, finalScatterStyle); } } - + // draw other selection decoration that isn't just line/scatter pens and brushes: if (mSelectionDecorator) mSelectionDecorator->drawDecoration(painter, selection()); @@ -21255,11 +21281,11 @@ void QCPGraph::getLines(QVector *lines, const QCPDataRange &dataRange) lines->clear(); return; } - + QVector lineData; if (mLineStyle != lsNone) getOptimizedLineData(&lineData, begin, end); - + if (mKeyAxis->rangeReversed() != (mKeyAxis->orientation() == Qt::Vertical)) // make sure key pixels are sorted ascending in lineData (significantly simplifies following processing) std::reverse(lineData.begin(), lineData.end()); @@ -21292,7 +21318,7 @@ void QCPGraph::getScatters(QVector *scatters, const QCPDataRange &dataR QCPAxis *keyAxis = mKeyAxis.data(); QCPAxis *valueAxis = mValueAxis.data(); if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; scatters->clear(); return; } - + QCPGraphDataContainer::const_iterator begin, end; getVisibleDataBounds(begin, end, dataRange); if (begin == end) @@ -21300,13 +21326,13 @@ void QCPGraph::getScatters(QVector *scatters, const QCPDataRange &dataR scatters->clear(); return; } - + QVector data; getOptimizedScatterData(&data, begin, end); - + if (mKeyAxis->rangeReversed() != (mKeyAxis->orientation() == Qt::Vertical)) // make sure key pixels are sorted ascending in data (significantly simplifies following processing) std::reverse(data.begin(), data.end()); - + scatters->resize(data.size()); if (keyAxis->orientation() == Qt::Vertical) { @@ -21335,7 +21361,7 @@ void QCPGraph::getScatters(QVector *scatters, const QCPDataRange &dataR Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel coordinate points which are suitable for drawing the line style \ref lsLine. - + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a getLines if the line style is set accordingly. @@ -21349,7 +21375,7 @@ QVector QCPGraph::dataToLines(const QVector &data) const if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } result.resize(data.size()); - + // transform data points to pixels: if (keyAxis->orientation() == Qt::Vertical) { @@ -21373,7 +21399,7 @@ QVector QCPGraph::dataToLines(const QVector &data) const Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel coordinate points which are suitable for drawing the line style \ref lsStepLeft. - + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a getLines if the line style is set accordingly. @@ -21385,9 +21411,9 @@ QVector QCPGraph::dataToStepLeftLines(const QVector &data QCPAxis *keyAxis = mKeyAxis.data(); QCPAxis *valueAxis = mValueAxis.data(); if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } - + result.resize(data.size()*2); - + // calculate steps from data and transform to pixel coordinates: if (keyAxis->orientation() == Qt::Vertical) { @@ -21421,7 +21447,7 @@ QVector QCPGraph::dataToStepLeftLines(const QVector &data Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel coordinate points which are suitable for drawing the line style \ref lsStepRight. - + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a getLines if the line style is set accordingly. @@ -21433,9 +21459,9 @@ QVector QCPGraph::dataToStepRightLines(const QVector &dat QCPAxis *keyAxis = mKeyAxis.data(); QCPAxis *valueAxis = mValueAxis.data(); if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } - + result.resize(data.size()*2); - + // calculate steps from data and transform to pixel coordinates: if (keyAxis->orientation() == Qt::Vertical) { @@ -21469,7 +21495,7 @@ QVector QCPGraph::dataToStepRightLines(const QVector &dat Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel coordinate points which are suitable for drawing the line style \ref lsStepCenter. - + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a getLines if the line style is set accordingly. @@ -21481,9 +21507,9 @@ QVector QCPGraph::dataToStepCenterLines(const QVector &da QCPAxis *keyAxis = mKeyAxis.data(); QCPAxis *valueAxis = mValueAxis.data(); if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } - + result.resize(data.size()*2); - + // calculate steps from data and transform to pixel coordinates: if (keyAxis->orientation() == Qt::Vertical) { @@ -21529,7 +21555,7 @@ QVector QCPGraph::dataToStepCenterLines(const QVector &da Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel coordinate points which are suitable for drawing the line style \ref lsImpulse. - + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a getLines if the line style is set accordingly. @@ -21541,9 +21567,9 @@ QVector QCPGraph::dataToImpulseLines(const QVector &data) QCPAxis *keyAxis = mKeyAxis.data(); QCPAxis *valueAxis = mValueAxis.data(); if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } - + result.resize(data.size()*2); - + // transform data points to pixels: if (keyAxis->orientation() == Qt::Vertical) { @@ -21586,18 +21612,18 @@ QVector QCPGraph::dataToImpulseLines(const QVector &data) } /*! \internal - + Draws the fill of the graph using the specified \a painter, with the currently set brush. - + Depending on whether a normal fill or a channel fill (\ref setChannelFillGraph) is needed, \ref getFillPolygon or \ref getChannelFillPolygon are used to find the according fill polygons. - + In order to handle NaN Data points correctly (the fill needs to be split into disjoint areas), this method first determines a list of non-NaN segments with \ref getNonNanSegments, on which to operate. In the channel fill case, \ref getOverlappingSegments is used to consolidate the non-NaN segments of the two involved graphs, before passing the overlapping pairs to \ref getChannelFillPolygon. - + Pass the points of this graph's line as \a lines, in pixel coordinates. \see drawLinePlot, drawImpulsePlot, drawScatterPlot @@ -21606,7 +21632,7 @@ void QCPGraph::drawFill(QCPPainter *painter, QVector *lines) const { if (mLineStyle == lsImpulse) return; // fill doesn't make sense for impulse plot if (painter->brush().style() == Qt::NoBrush || painter->brush().color().alpha() == 0) return; - + applyFillAntialiasingHint(painter); const QVector segments = getNonNanSegments(lines, keyAxis()->orientation()); if (!mChannelFillGraph) @@ -21645,9 +21671,9 @@ void QCPGraph::drawScatterPlot(QCPPainter *painter, const QVector &scat } /*! \internal - + Draws lines between the points in \a lines, given in pixel coordinates. - + \see drawScatterPlot, drawImpulsePlot, QCPAbstractPlottable1D::drawPolyline */ void QCPGraph::drawLinePlot(QCPPainter *painter, const QVector &lines) const @@ -21700,7 +21726,7 @@ void QCPGraph::getOptimizedLineData(QVector *lineData, const QCPGr QCPAxis *valueAxis = mValueAxis.data(); if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } if (begin == end) return; - + int dataCount = int(end-begin); int maxCount = (std::numeric_limits::max)(); if (mAdaptiveSampling) @@ -21709,7 +21735,7 @@ void QCPGraph::getOptimizedLineData(QVector *lineData, const QCPGr if (2*keyPixelSpan+2 < static_cast((std::numeric_limits::max)())) maxCount = int(2*keyPixelSpan+2); } - + if (mAdaptiveSampling && dataCount >= maxCount) // use adaptive sampling only if there are at least two points per pixel on average { QCPGraphDataContainer::const_iterator it = begin; @@ -21765,7 +21791,7 @@ void QCPGraph::getOptimizedLineData(QVector *lineData, const QCPGr lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.75, maxValue)); } else lineData->append(QCPGraphData(currentIntervalFirstPoint->key, currentIntervalFirstPoint->value)); - + } else // don't use adaptive sampling algorithm, transfer points one-to-one from the data container into the output { lineData->resize(dataCount); @@ -21791,7 +21817,7 @@ void QCPGraph::getOptimizedScatterData(QVector *scatterData, QCPGr QCPAxis *keyAxis = mKeyAxis.data(); QCPAxis *valueAxis = mValueAxis.data(); if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - + const int scatterModulo = mScatterSkip+1; const bool doScatterSkip = mScatterSkip > 0; int beginIndex = int(begin-mDataContainer->constBegin()); @@ -21809,7 +21835,7 @@ void QCPGraph::getOptimizedScatterData(QVector *scatterData, QCPGr int keyPixelSpan = int(qAbs(keyAxis->coordToPixel(begin->key)-keyAxis->coordToPixel((end-1)->key))); maxCount = 2*keyPixelSpan+2; } - + if (mAdaptiveSampling && dataCount >= maxCount) // use adaptive sampling only if there are at least two points per pixel on average { double valueMaxRange = valueAxis->range().upper; @@ -21930,7 +21956,7 @@ void QCPGraph::getOptimizedScatterData(QVector *scatterData, QCPGr } } else if (currentIntervalStart->value > valueMinRange && currentIntervalStart->value < valueMaxRange) scatterData->append(*currentIntervalStart); - + } else // don't use adaptive sampling algorithm, transfer points one-to-one from the data container into the output { QCPGraphDataContainer::const_iterator it = begin; @@ -21986,24 +22012,24 @@ void QCPGraph::getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin } /*! \internal - + This method goes through the passed points in \a lineData and returns a list of the segments which don't contain NaN data points. - + \a keyOrientation defines whether the \a x or \a y member of the passed QPointF is used to check for NaN. If \a keyOrientation is \c Qt::Horizontal, the \a y member is checked, if it is \c Qt::Vertical, the \a x member is checked. - + \see getOverlappingSegments, drawFill */ QVector QCPGraph::getNonNanSegments(const QVector *lineData, Qt::Orientation keyOrientation) const { QVector result; const int n = lineData->size(); - + QCPDataRange currentSegment(-1, -1); int i = 0; - + if (keyOrientation == Qt::Horizontal) { while (i < n) @@ -22037,21 +22063,21 @@ QVector QCPGraph::getNonNanSegments(const QVector *lineDa } /*! \internal - + This method takes two segment lists (e.g. created by \ref getNonNanSegments) \a thisSegments and \a otherSegments, and their associated point data \a thisData and \a otherData. It returns all pairs of segments (the first from \a thisSegments, the second from \a otherSegments), which overlap in plot coordinates. - + This method is useful in the case of a channel fill between two graphs, when only those non-NaN segments which actually overlap in their key coordinate shall be considered for drawing a channel fill polygon. - + It is assumed that the passed segments in \a thisSegments are ordered ascending by index, and that the segments don't overlap themselves. The same is assumed for the segments in \a otherSegments. This is fulfilled when the segments are obtained via \ref getNonNanSegments. - + \see getNonNanSegments, segmentsIntersect, drawFill, getChannelFillPolygon */ QVector > QCPGraph::getOverlappingSegments(QVector thisSegments, const QVector *thisData, QVector otherSegments, const QVector *otherData) const @@ -22059,7 +22085,7 @@ QVector > QCPGraph::getOverlappingSegments(QVe QVector > result; if (thisData->isEmpty() || otherData->isEmpty() || thisSegments.isEmpty() || otherSegments.isEmpty()) return result; - + int thisIndex = 0; int otherIndex = 0; const bool verticalKey = mKeyAxis->orientation() == Qt::Vertical; @@ -22089,32 +22115,32 @@ QVector > QCPGraph::getOverlappingSegments(QVe otherLower = otherData->at(otherSegments.at(otherIndex).begin()).y(); otherUpper = otherData->at(otherSegments.at(otherIndex).end()-1).y(); } - + int bPrecedence; if (segmentsIntersect(thisLower, thisUpper, otherLower, otherUpper, bPrecedence)) result.append(QPair(thisSegments.at(thisIndex), otherSegments.at(otherIndex))); - + if (bPrecedence <= 0) // otherSegment doesn't reach as far as thisSegment, so continue with next otherSegment, keeping current thisSegment ++otherIndex; else // otherSegment reaches further than thisSegment, so continue with next thisSegment, keeping current otherSegment ++thisIndex; } - + return result; } /*! \internal - + Returns whether the segments defined by the coordinates (aLower, aUpper) and (bLower, bUpper) have overlap. - + The output parameter \a bPrecedence indicates whether the \a b segment reaches farther than the \a a segment or not. If \a bPrecedence returns 1, segment \a b reaches the farthest to higher coordinates (i.e. bUpper > aUpper). If it returns -1, segment \a a reaches the farthest. Only if both segment's upper bounds are identical, 0 is returned as \a bPrecedence. - + It is assumed that the lower bounds always have smaller or equal values than the upper bounds. - + \see getOverlappingSegments */ bool QCPGraph::segmentsIntersect(double aLower, double aUpper, double bLower, double bUpper, int &bPrecedence) const @@ -22134,13 +22160,13 @@ bool QCPGraph::segmentsIntersect(double aLower, double aUpper, double bLower, do bPrecedence = -1; else if (aUpper < bUpper) bPrecedence = 1; - + return true; } } /*! \internal - + Returns the point which closes the fill polygon on the zero-value-line parallel to the key axis. The logarithmic axis scale case is a bit special, since the zero-value-line in pixel coordinates is in positive or negative infinity. So this case is handled separately by just closing the fill @@ -22155,7 +22181,7 @@ QPointF QCPGraph::getFillBasePoint(QPointF matchingDataPoint) const QCPAxis *keyAxis = mKeyAxis.data(); QCPAxis *valueAxis = mValueAxis.data(); if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return {}; } - + QPointF result; if (valueAxis->scaleType() == QCPAxis::stLinear) { @@ -22194,19 +22220,19 @@ QPointF QCPGraph::getFillBasePoint(QPointF matchingDataPoint) const } /*! \internal - + Returns the polygon needed for drawing normal fills between this graph and the key axis. - + Pass the graph's data points (in pixel coordinates) as \a lineData, and specify the \a segment which shall be used for the fill. The collection of \a lineData points described by \a segment must not contain NaN data points (see \ref getNonNanSegments). - + The returned fill polygon will be closed at the key axis (the zero-value line) for linear value axes. For logarithmic value axes the polygon will reach just beyond the corresponding axis rect side (see \ref getFillBasePoint). For increased performance (due to implicit sharing), keep the returned QPolygonF const. - + \see drawFill, getNonNanSegments */ const QPolygonF QCPGraph::getFillPolygon(const QVector *lineData, QCPDataRange segment) const @@ -22214,45 +22240,45 @@ const QPolygonF QCPGraph::getFillPolygon(const QVector *lineData, QCPDa if (segment.size() < 2) return QPolygonF(); QPolygonF result(segment.size()+2); - + result[0] = getFillBasePoint(lineData->at(segment.begin())); std::copy(lineData->constBegin()+segment.begin(), lineData->constBegin()+segment.end(), result.begin()+1); result[result.size()-1] = getFillBasePoint(lineData->at(segment.end()-1)); - + return result; } /*! \internal - + Returns the polygon needed for drawing (partial) channel fills between this graph and the graph specified by \ref setChannelFillGraph. - + The data points of this graph are passed as pixel coordinates via \a thisData, the data of the other graph as \a otherData. The returned polygon will be calculated for the specified data segments \a thisSegment and \a otherSegment, pertaining to the respective \a thisData and \a otherData, respectively. - + The passed \a thisSegment and \a otherSegment should correspond to the segment pairs returned by \ref getOverlappingSegments, to make sure only segments that actually have key coordinate overlap need to be processed here. - + For increased performance due to implicit sharing, keep the returned QPolygonF const. - + \see drawFill, getOverlappingSegments, getNonNanSegments */ const QPolygonF QCPGraph::getChannelFillPolygon(const QVector *thisData, QCPDataRange thisSegment, const QVector *otherData, QCPDataRange otherSegment) const { if (!mChannelFillGraph) return QPolygonF(); - + QCPAxis *keyAxis = mKeyAxis.data(); QCPAxis *valueAxis = mValueAxis.data(); if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPolygonF(); } if (!mChannelFillGraph.data()->mKeyAxis) { qDebug() << Q_FUNC_INFO << "channel fill target key axis invalid"; return QPolygonF(); } - + if (mChannelFillGraph.data()->mKeyAxis.data()->orientation() != keyAxis->orientation()) return QPolygonF(); // don't have same axis orientation, can't fill that (Note: if keyAxis fits, valueAxis will fit too, because it's always orthogonal to keyAxis) - + if (thisData->isEmpty()) return QPolygonF(); QVector thisSegmentData(thisSegment.size()); QVector otherSegmentData(otherSegment.size()); @@ -22261,7 +22287,7 @@ const QPolygonF QCPGraph::getChannelFillPolygon(const QVector *thisData // pointers to be able to swap them, depending which data range needs cropping: QVector *staticData = &thisSegmentData; QVector *croppedData = &otherSegmentData; - + // crop both vectors to ranges in which the keys overlap (which coord is key, depends on axisType): if (keyAxis->orientation() == Qt::Horizontal) { @@ -22281,7 +22307,7 @@ const QPolygonF QCPGraph::getChannelFillPolygon(const QVector *thisData slope = 0; (*croppedData)[0].setY(croppedData->at(0).y()+slope*(staticData->first().x()-croppedData->at(0).x())); (*croppedData)[0].setX(staticData->first().x()); - + // crop upper bound: if (staticData->last().x() > croppedData->last().x()) // other one must be cropped qSwap(staticData, croppedData); @@ -22315,7 +22341,7 @@ const QPolygonF QCPGraph::getChannelFillPolygon(const QVector *thisData slope = 0; (*croppedData)[0].setX(croppedData->at(0).x()+slope*(staticData->first().y()-croppedData->at(0).y())); (*croppedData)[0].setY(staticData->first().y()); - + // crop upper bound: if (staticData->last().y() > croppedData->last().y()) // other one must be cropped qSwap(staticData, croppedData); @@ -22332,7 +22358,7 @@ const QPolygonF QCPGraph::getChannelFillPolygon(const QVector *thisData (*croppedData)[li].setX(croppedData->at(li-1).x()+slope*(staticData->last().y()-croppedData->at(li-1).y())); (*croppedData)[li].setY(staticData->last().y()); } - + // return joined: for (int i=otherSegmentData.size()-1; i>=0; --i) // insert reversed, otherwise the polygon will be twisted thisSegmentData << otherSegmentData.at(i); @@ -22340,7 +22366,7 @@ const QPolygonF QCPGraph::getChannelFillPolygon(const QVector *thisData } /*! \internal - + Finds the smallest index of \a data, whose points x value is just above \a x. Assumes x values in \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key axis is horizontal. @@ -22363,11 +22389,11 @@ int QCPGraph::findIndexAboveX(const QVector *data, double x) const } /*! \internal - + Finds the highest index of \a data, whose points x value is just below \a x. Assumes x values in \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key axis is horizontal. - + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. */ int QCPGraph::findIndexBelowX(const QVector *data, double x) const @@ -22386,11 +22412,11 @@ int QCPGraph::findIndexBelowX(const QVector *data, double x) const } /*! \internal - + Finds the smallest index of \a data, whose points y value is just above \a y. Assumes y values in \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key axis is vertical. - + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. */ int QCPGraph::findIndexAboveY(const QVector *data, double y) const @@ -22409,13 +22435,13 @@ int QCPGraph::findIndexAboveY(const QVector *data, double y) const } /*! \internal - + Calculates the minimum distance in pixels the graph's representation has from the given \a pixelPoint. This is used to determine whether the graph was clicked or not, e.g. in \ref selectTest. The closest data point to \a pixelPoint is returned in \a closestData. Note that if the graph has a line representation, the returned distance may be smaller than the distance to the \a closestData point, since the distance to the graph line is also taken into account. - + If either the graph has no data or if the line style is \ref lsNone and the scatter style's shape is \ref QCPScatterStyle::ssNone (i.e. there is no visual representation of the graph), returns -1.0. */ @@ -22426,7 +22452,7 @@ double QCPGraph::pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer: return -1.0; if (mLineStyle == lsNone && mScatterStyle.isNone()) return -1.0; - + // calculate minimum distances to graph data points and find closestData iterator: double minDistSqr = (std::numeric_limits::max)(); // determine which key range comes into question, taking selection tolerance around pos into account: @@ -22447,7 +22473,7 @@ double QCPGraph::pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer: closestData = it; } } - + // calculate distance to graph line if there is one (if so, will probably be smaller than distance to closest data point): if (mLineStyle != lsNone) { @@ -22463,12 +22489,12 @@ double QCPGraph::pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer: minDistSqr = currentDistSqr; } } - + return qSqrt(minDistSqr); } /*! \internal - + Finds the highest index of \a data, whose points y value is just below \a y. Assumes y values in \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key axis is vertical. @@ -22501,67 +22527,67 @@ int QCPGraph::findIndexBelowY(const QVector *data, double y) const /*! \class QCPCurveData \brief Holds the data of one single data point for QCPCurve. - + The stored data is: \li \a t: the free ordering parameter of this curve point, like in the mathematical vector (x(t), y(t)). (This is the \a sortKey) \li \a key: coordinate on the key axis of this curve point (this is the \a mainKey) \li \a value: coordinate on the value axis of this curve point (this is the \a mainValue) - + The container for storing multiple data points is \ref QCPCurveDataContainer. It is a typedef for \ref QCPDataContainer with \ref QCPCurveData as the DataType template parameter. See the documentation there for an explanation regarding the data type's generic methods. - + \see QCPCurveDataContainer */ /* start documentation of inline functions */ /*! \fn double QCPCurveData::sortKey() const - + Returns the \a t member of this data point. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn static QCPCurveData QCPCurveData::fromSortKey(double sortKey) - + Returns a data point with the specified \a sortKey (assigned to the data point's \a t member). All other members are set to zero. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn static static bool QCPCurveData::sortKeyIsMainKey() - + Since the member \a key is the data point key coordinate and the member \a t is the data ordering parameter, this method returns false. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn double QCPCurveData::mainKey() const - + Returns the \a key member of this data point. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn double QCPCurveData::mainValue() const - + Returns the \a value member of this data point. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn QCPRange QCPCurveData::valueRange() const - + Returns a QCPRange with both lower and upper boundary set to \a value of this data point. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ @@ -22595,9 +22621,9 @@ QCPCurveData::QCPCurveData(double t, double key, double value) : /*! \class QCPCurve \brief A plottable representing a parametric curve in a plot. - + \image html QCPCurve.png - + Unlike QCPGraph, plottables of this type may have multiple points with the same key coordinate, so their visual representation can have \a loops. This is realized by introducing a third coordinate \a t, which defines the order of the points described by the other two coordinates \a @@ -22606,21 +22632,21 @@ QCPCurveData::QCPCurveData(double t, double key, double value) : To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can also access and modify the curve's data via the \ref data method, which returns a pointer to the internal \ref QCPCurveDataContainer. - + Gaps in the curve can be created by adding data points with NaN as key and value (qQNaN() or std::numeric_limits::quiet_NaN()) in between the two data points that shall be separated. - + \section qcpcurve-appearance Changing the appearance - + The appearance of the curve is determined by the pen and the brush (\ref setPen, \ref setBrush). - + \section qcpcurve-usage Usage - + Like all data representing objects in QCustomPlot, the QCPCurve is a plottable (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) - + Usually, you first create an instance: \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-creation-1 which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes @@ -22632,7 +22658,7 @@ QCPCurveData::QCPCurveData(double t, double key, double value) : /* start of documentation of inline functions */ /*! \fn QSharedPointer QCPCurve::data() const - + Returns a shared pointer to the internal data storage of type \ref QCPCurveDataContainer. You may use it to directly manipulate the data, which may be more convenient and faster than using the regular \ref setData or \ref addData methods. @@ -22645,7 +22671,7 @@ QCPCurveData::QCPCurveData(double t, double key, double value) : axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have the same orientation. If either of these restrictions is violated, a corresponding message is printed to the debug output (qDebug), the construction is not aborted, though. - + The created QCPCurve is automatically registered with the QCustomPlot instance inferred from \a keyAxis. This QCustomPlot instance takes ownership of the QCPCurve, so do not delete it manually but use QCustomPlot::removePlottable() instead. @@ -22658,7 +22684,7 @@ QCPCurve::QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis) : // modify inherited properties from abstract plottable: setPen(QPen(Qt::blue, 0)); setBrush(Qt::NoBrush); - + setScatterStyle(QCPScatterStyle()); setLineStyle(lsLine); setScatterSkip(0); @@ -22669,18 +22695,18 @@ QCPCurve::~QCPCurve() } /*! \overload - + Replaces the current data container with the provided \a data container. - + Since a QSharedPointer is used, multiple QCPCurves may share the same data container safely. Modifying the data in the container will then affect all curves that share the container. Sharing can be achieved by simply exchanging the data containers wrapped in shared pointers: \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-datasharing-1 - + If you do not wish to share containers, but create a copy from an existing container, rather use the \ref QCPDataContainer::set method on the curve's data container directly: \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-datasharing-2 - + \see addData */ void QCPCurve::setData(QSharedPointer data) @@ -22689,14 +22715,14 @@ void QCPCurve::setData(QSharedPointer data) } /*! \overload - + Replaces the current data with the provided points in \a t, \a keys and \a values. The provided vectors should have equal length. Else, the number of added points will be the size of the smallest vector. - + If you can guarantee that the passed data points are sorted by \a t in ascending order, you can set \a alreadySorted to true, to improve performance by saving a sorting run. - + \see addData */ void QCPCurve::setData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted) @@ -22707,14 +22733,14 @@ void QCPCurve::setData(const QVector &t, const QVector &keys, co /*! \overload - + Replaces the current data with the provided points in \a keys and \a values. The provided vectors should have equal length. Else, the number of added points will be the size of the smallest vector. - + The t parameter of each data point will be set to the integer index of the respective key/value pair. - + \see addData */ void QCPCurve::setData(const QVector &keys, const QVector &values) @@ -22727,7 +22753,7 @@ void QCPCurve::setData(const QVector &keys, const QVector &value Sets the visual appearance of single data points in the plot. If set to \ref QCPScatterStyle::ssNone, no scatter points are drawn (e.g. for line-only plots with appropriate line style). - + \see QCPScatterStyle, setLineStyle */ void QCPCurve::setScatterStyle(const QCPScatterStyle &style) @@ -22755,7 +22781,7 @@ void QCPCurve::setScatterSkip(int skip) Sets how the single data points are connected in the plot or how they are represented visually apart from the scatter symbol. For scatter-only plots, set \a style to \ref lsNone and \ref setScatterStyle to the desired scatter style. - + \see setScatterStyle */ void QCPCurve::setLineStyle(QCPCurve::LineStyle style) @@ -22764,14 +22790,14 @@ void QCPCurve::setLineStyle(QCPCurve::LineStyle style) } /*! \overload - + Adds the provided points in \a t, \a keys and \a values to the current data. The provided vectors should have equal length. Else, the number of added points will be the size of the smallest vector. - + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you can set \a alreadySorted to true, to improve performance by saving a sorting run. - + Alternatively, you can also access and modify the data directly via the \ref data method, which returns a pointer to the internal data container. */ @@ -22796,14 +22822,14 @@ void QCPCurve::addData(const QVector &t, const QVector &keys, co } /*! \overload - + Adds the provided points in \a keys and \a values to the current data. The provided vectors should have equal length. Else, the number of added points will be the size of the smallest vector. - + The t parameter of each data point will be set to the integer index of the respective key/value pair. - + Alternatively, you can also access and modify the data directly via the \ref data method, which returns a pointer to the internal data container. */ @@ -22834,7 +22860,7 @@ void QCPCurve::addData(const QVector &keys, const QVector &value /*! \overload Adds the provided data point as \a t, \a key and \a value to the current data. - + Alternatively, you can also access and modify the data directly via the \ref data method, which returns a pointer to the internal data container. */ @@ -22844,12 +22870,12 @@ void QCPCurve::addData(double t, double key, double value) } /*! \overload - + Adds the provided data point as \a key and \a value to the current data. - + The t parameter is generated automatically by increments of 1 for each point, starting at the highest t of previously existing data or 0, if the curve data is empty. - + Alternatively, you can also access and modify the data directly via the \ref data method, which returns a pointer to the internal data container. */ @@ -22866,7 +22892,7 @@ void QCPCurve::addData(double key, double value) If \a details is not 0, it will be set to a \ref QCPDataSelection, describing the closest data point to \a pos. - + \seebaseclassmethod \ref QCPAbstractPlottable::selectTest */ double QCPCurve::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const @@ -22875,7 +22901,7 @@ double QCPCurve::selectTest(const QPointF &pos, bool onlySelectable, QVariant *d return -1; if (!mKeyAxis || !mValueAxis) return -1; - + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()) || mParentPlot->interactions().testFlag(QCP::iSelectPlottablesBeyondAxisRect)) { QCPCurveDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); @@ -22906,10 +22932,10 @@ QCPRange QCPCurve::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, void QCPCurve::draw(QCPPainter *painter) { if (mDataContainer->isEmpty()) return; - + // allocate line vector: QVector lines, scatters; - + // loop over and draw segments of unselected/selected data: QList selectedSegments, unselectedSegments, allSegments; getDataSegments(selectedSegments, unselectedSegments); @@ -22917,15 +22943,15 @@ void QCPCurve::draw(QCPPainter *painter) for (int i=0; i= unselectedSegments.size(); - + // fill with curve data: QPen finalCurvePen = mPen; // determine the final pen already here, because the line optimization depends on its stroke width if (isSelectedSegment && mSelectionDecorator) finalCurvePen = mSelectionDecorator->pen(); - + QCPDataRange lineDataRange = isSelectedSegment ? allSegments.at(i) : allSegments.at(i).adjusted(-1, 1); // unselected segments extend lines to bordering selected data point (safe to exceed total data bounds in first/last segment, getCurveLines takes care) getCurveLines(&lines, lineDataRange, finalCurvePen.widthF()); - + // check data validity if flag set: #ifdef QCUSTOMPLOT_CHECK_DATA for (QCPCurveDataContainer::const_iterator it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) @@ -22935,7 +22961,7 @@ void QCPCurve::draw(QCPPainter *painter) qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "invalid." << "Plottable name:" << name(); } #endif - + // draw curve fill: applyFillAntialiasingHint(painter); if (isSelectedSegment && mSelectionDecorator) @@ -22945,7 +22971,7 @@ void QCPCurve::draw(QCPPainter *painter) painter->setPen(Qt::NoPen); if (painter->brush().style() != Qt::NoBrush && painter->brush().color().alpha() != 0) painter->drawPolygon(QPolygonF(lines)); - + // draw curve line: if (mLineStyle != lsNone) { @@ -22953,7 +22979,7 @@ void QCPCurve::draw(QCPPainter *painter) painter->setBrush(Qt::NoBrush); drawCurveLine(painter, lines); } - + // draw scatters: QCPScatterStyle finalScatterStyle = mScatterStyle; if (isSelectedSegment && mSelectionDecorator) @@ -22964,7 +22990,7 @@ void QCPCurve::draw(QCPPainter *painter) drawScatterPlot(painter, scatters, finalScatterStyle); } } - + // draw other selection decoration that isn't just line/scatter pens and brushes: if (mSelectionDecorator) mSelectionDecorator->drawDecoration(painter, selection()); @@ -23072,7 +23098,7 @@ void QCPCurve::getCurveLines(QVector *lines, const QCPDataRange &dataRa QCPAxis *keyAxis = mKeyAxis.data(); QCPAxis *valueAxis = mValueAxis.data(); if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - + // add margins to rect to compensate for stroke width const double strokeMargin = qMax(qreal(1.0), qreal(penWidth*0.75)); // stroke radius + 50% safety const double keyMin = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyAxis->range().lower)-strokeMargin*keyAxis->pixelOrientation()); @@ -23175,7 +23201,7 @@ void QCPCurve::getScatters(QVector *scatters, const QCPDataRange &dataR QCPAxis *keyAxis = mKeyAxis.data(); QCPAxis *valueAxis = mValueAxis.data(); if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - + QCPCurveDataContainer::const_iterator begin = mDataContainer->constBegin(); QCPCurveDataContainer::const_iterator end = mDataContainer->constEnd(); mDataContainer->limitIteratorsToDataRange(begin, end, dataRange); @@ -23184,7 +23210,7 @@ void QCPCurve::getScatters(QVector *scatters, const QCPDataRange &dataR const int scatterModulo = mScatterSkip+1; const bool doScatterSkip = mScatterSkip > 0; int endIndex = int( end-mDataContainer->constBegin() ); - + QCPRange keyRange = keyAxis->range(); QCPRange valueRange = valueAxis->range(); // extend range to include width of scatter symbols: @@ -23192,7 +23218,7 @@ void QCPCurve::getScatters(QVector *scatters, const QCPDataRange &dataR keyRange.upper = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyRange.upper)+scatterWidth*keyAxis->pixelOrientation()); valueRange.lower = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueRange.lower)-scatterWidth*valueAxis->pixelOrientation()); valueRange.upper = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueRange.upper)+scatterWidth*valueAxis->pixelOrientation()); - + QCPCurveDataContainer::const_iterator it = begin; int itIndex = int( begin-mDataContainer->constBegin() ); while (doScatterSkip && it != end && itIndex % scatterModulo != 0) // advance begin iterator to first non-skipped scatter @@ -23206,7 +23232,7 @@ void QCPCurve::getScatters(QVector *scatters, const QCPDataRange &dataR { if (!qIsNaN(it->value) && keyRange.contains(it->key) && valueRange.contains(it->value)) scatters->append(QPointF(valueAxis->coordToPixel(it->value), keyAxis->coordToPixel(it->key))); - + // advance iterator to next (non-skipped) data point: if (!doScatterSkip) ++it; @@ -23228,7 +23254,7 @@ void QCPCurve::getScatters(QVector *scatters, const QCPDataRange &dataR { if (!qIsNaN(it->value) && keyRange.contains(it->key) && valueRange.contains(it->value)) scatters->append(QPointF(keyAxis->coordToPixel(it->key), valueAxis->coordToPixel(it->value))); - + // advance iterator to next (non-skipped) data point: if (!doScatterSkip) ++it; @@ -23296,15 +23322,15 @@ int QCPCurve::getRegion(double key, double value, double keyMin, double valueMax } /*! \internal - + This function is part of the curve optimization algorithm of \ref getCurveLines. - + This method is used in case the current segment passes from inside the visible rect (region 5, see \ref getRegion) to any of the outer regions (\a otherRegion). The current segment is given by the line connecting (\a key, \a value) with (\a otherKey, \a otherValue). - + It returns the intersection point of the segment with the border of region 5. - + For this function it doesn't matter whether (\a key, \a value) is the point inside region 5 or whether it's (\a otherKey, \a otherValue), i.e. whether the segment is coming from region 5 or leaving it. It is important though that \a otherRegion correctly identifies the other region not @@ -23316,7 +23342,7 @@ QPointF QCPCurve::getOptimizedPoint(int otherRegion, double otherKey, double oth // differentiate between different axis scale types. Note that the nomenclature // top/left/bottom/right/min/max is with respect to the rect in plot coordinates, wich may be // different in pixel coordinates (horz/vert key axes, reversed ranges) - + const double keyMinPx = mKeyAxis->coordToPixel(keyMin); const double keyMaxPx = mKeyAxis->coordToPixel(keyMax); const double valueMinPx = mValueAxis->coordToPixel(valueMin); @@ -23409,16 +23435,16 @@ QPointF QCPCurve::getOptimizedPoint(int otherRegion, double otherKey, double oth } /*! \internal - + This function is part of the curve optimization algorithm of \ref getCurveLines. - + In situations where a single segment skips over multiple regions it might become necessary to add extra points at the corners of region 5 (see \ref getRegion) such that the optimized segment doesn't unintentionally cut through the visible area of the axis rect and create plot artifacts. This method provides these points that must be added, assuming the original segment doesn't start, end, or traverse region 5. (Corner points where region 5 is traversed are calculated by \ref getTraverseCornerPoints.) - + For example, consider a segment which directly goes from region 4 to 2 but originally is far out to the top left such that it doesn't cross region 5. Naively optimizing these points by projecting them on the top and left borders of region 5 will create a segment that surely crosses @@ -23579,13 +23605,13 @@ QVector QCPCurve::getOptimizedCornerPoints(int prevRegion, int currentR } /*! \internal - + This function is part of the curve optimization algorithm of \ref getCurveLines. - + This method returns whether a segment going from \a prevRegion to \a currentRegion (see \ref getRegion) may traverse the visible region 5. This function assumes that neither \a prevRegion nor \a currentRegion is 5 itself. - + If this method returns false, the segment for sure doesn't pass region 5. If it returns true, the segment may or may not pass region 5 and a more fine-grained calculation must be used (\ref getTraverse). @@ -23681,15 +23707,15 @@ bool QCPCurve::mayTraverse(int prevRegion, int currentRegion) const /*! \internal - + This function is part of the curve optimization algorithm of \ref getCurveLines. - + This method assumes that the \ref mayTraverse test has returned true, so there is a chance the segment defined by (\a prevKey, \a prevValue) and (\a key, \a value) goes through the visible region 5. - + The return value of this method indicates whether the segment actually traverses region 5 or not. - + If the segment traverses 5, the output parameters \a crossA and \a crossB indicate the entry and exit points of region 5. They will become the optimized points for that segment. */ @@ -23699,7 +23725,7 @@ bool QCPCurve::getTraverse(double prevKey, double prevValue, double key, double // differentiate between different axis scale types. Note that the nomenclature // top/left/bottom/right/min/max is with respect to the rect in plot coordinates, wich may be // different in pixel coordinates (horz/vert key axes, reversed ranges) - + QList intersections; const double valueMinPx = mValueAxis->coordToPixel(valueMin); const double valueMaxPx = mValueAxis->coordToPixel(valueMax); @@ -23741,7 +23767,7 @@ bool QCPCurve::getTraverse(double prevKey, double prevValue, double key, double if (gamma >= qMin(valueMinPx, valueMaxPx) && gamma <= qMax(valueMinPx, valueMaxPx)) // qMin/qMax necessary since axes may be reversed intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMaxPx, gamma) : QPointF(gamma, keyMaxPx)); } - + // handle cases where found points isn't exactly 2: if (intersections.size() > 2) { @@ -23768,7 +23794,7 @@ bool QCPCurve::getTraverse(double prevKey, double prevValue, double key, double // one or even zero points found (shouldn't happen unless line perfectly tangent to corner), no need to draw segment return false; } - + // possibly re-sort points so optimized point segment has same direction as original segment: double xDelta = keyPx-prevKeyPx; double yDelta = valuePx-prevValuePx; @@ -23782,26 +23808,26 @@ bool QCPCurve::getTraverse(double prevKey, double prevValue, double key, double } /*! \internal - + This function is part of the curve optimization algorithm of \ref getCurveLines. - + This method assumes that the \ref getTraverse test has returned true, so the segment definitely traverses the visible region 5 when going from \a prevRegion to \a currentRegion. - + In certain situations it is not sufficient to merely generate the entry and exit points of the segment into/out of region 5, as \ref getTraverse provides. It may happen that a single segment, in addition to traversing region 5, skips another region outside of region 5, which makes it necessary to add an optimized corner point there (very similar to the job \ref getOptimizedCornerPoints does for segments that are completely in outside regions and don't traverse 5). - + As an example, consider a segment going from region 1 to region 6, traversing the lower left corner of region 5. In this configuration, the segment additionally crosses the border between region 1 and 2 before entering region 5. This makes it necessary to add an additional point in the top left corner, before adding the optimized traverse points. So in this case, the output parameter \a beforeTraverse will contain the top left corner point, and \a afterTraverse will be empty. - + In some cases, such as when going from region 1 to 9, it may even be necessary to add additional corner points before and after the traverse. Then both \a beforeTraverse and \a afterTraverse return the respective corner points. @@ -23891,13 +23917,13 @@ void QCPCurve::getTraverseCornerPoints(int prevRegion, int currentRegion, double } /*! \internal - + Calculates the (minimum) distance (in pixels) the curve's representation has from the given \a pixelPoint in pixels. This is used to determine whether the curve was clicked or not, e.g. in \ref selectTest. The closest data point to \a pixelPoint is returned in \a closestData. Note that if the curve has a line representation, the returned distance may be smaller than the distance to the \a closestData point, since the distance to the curve line is also taken into account. - + If either the curve has no data or if the line style is \ref lsNone and the scatter style's shape is \ref QCPScatterStyle::ssNone (i.e. there is no visual representation of the curve), returns -1.0. @@ -23909,14 +23935,14 @@ double QCPCurve::pointDistance(const QPointF &pixelPoint, QCPCurveDataContainer: return -1.0; if (mLineStyle == lsNone && mScatterStyle.isNone()) return -1.0; - + if (mDataContainer->size() == 1) { QPointF dataPoint = coordsToPixels(mDataContainer->constBegin()->key, mDataContainer->constBegin()->value); closestData = mDataContainer->constBegin(); return QCPVector2D(dataPoint-pixelPoint).length(); } - + // calculate minimum distances to curve data points and find closestData iterator: double minDistSqr = (std::numeric_limits::max)(); // iterate over found data points and then choose the one with the shortest distance to pos: @@ -23931,7 +23957,7 @@ double QCPCurve::pointDistance(const QPointF &pixelPoint, QCPCurveDataContainer: closestData = it; } } - + // calculate distance to line if there is one (if so, will probably be smaller than distance to closest data point): if (mLineStyle != lsNone) { @@ -23944,7 +23970,7 @@ double QCPCurve::pointDistance(const QPointF &pixelPoint, QCPCurveDataContainer: minDistSqr = currentDistSqr; } } - + return qSqrt(minDistSqr); } /* end of 'src/plottables/plottable-curve.cpp' */ @@ -23960,34 +23986,34 @@ double QCPCurve::pointDistance(const QPointF &pixelPoint, QCPCurveDataContainer: /*! \class QCPBarsGroup \brief Groups multiple QCPBars together so they appear side by side - + \image html QCPBarsGroup.png - + When showing multiple QCPBars in one plot which have bars at identical keys, it may be desirable to have them appearing next to each other at each key. This is what adding the respective QCPBars plottables to a QCPBarsGroup achieves. (An alternative approach is to stack them on top of each other, see \ref QCPBars::moveAbove.) - + \section qcpbarsgroup-usage Usage - + To add a QCPBars plottable to the group, create a new group and then add the respective bars intances: \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbarsgroup-creation Alternatively to appending to the group like shown above, you can also set the group on the QCPBars plottable via \ref QCPBars::setBarsGroup. - + The spacing between the bars can be configured via \ref setSpacingType and \ref setSpacing. The bars in this group appear in the plot in the order they were appended. To insert a bars plottable at a certain index position, or to reposition a bars plottable which is already in the group, use \ref insert. - + To remove specific bars from the group, use either \ref remove or call \ref QCPBars::setBarsGroup "QCPBars::setBarsGroup(0)" on the respective bars plottable. - + To clear the entire group, call \ref clear, or simply delete the group. - + \section qcpbarsgroup-example Example - + The image above is generated with the following code: \snippet documentation/doc-image-generator/mainwindow.cpp qcpbarsgroup-example */ @@ -23995,29 +24021,29 @@ double QCPCurve::pointDistance(const QPointF &pixelPoint, QCPCurveDataContainer: /* start of documentation of inline functions */ /*! \fn QList QCPBarsGroup::bars() const - + Returns all bars currently in this group. - + \see bars(int index) */ /*! \fn int QCPBarsGroup::size() const - + Returns the number of QCPBars plottables that are part of this group. - + */ /*! \fn bool QCPBarsGroup::isEmpty() const - + Returns whether this bars group is empty. - + \see size */ /*! \fn bool QCPBarsGroup::contains(QCPBars *bars) - + Returns whether the specified \a bars plottable is part of this group. - + */ /* end of documentation of inline functions */ @@ -24040,7 +24066,7 @@ QCPBarsGroup::~QCPBarsGroup() /*! Sets how the spacing between adjacent bars is interpreted. See \ref SpacingType. - + The actual spacing can then be specified with \ref setSpacing. \see setSpacing @@ -24104,7 +24130,7 @@ void QCPBarsGroup::append(QCPBars *bars) qDebug() << Q_FUNC_INFO << "bars is 0"; return; } - + if (!mBars.contains(bars)) bars->setBarsGroup(this); else @@ -24114,7 +24140,7 @@ void QCPBarsGroup::append(QCPBars *bars) /*! Inserts the specified \a bars plottable into this group at the specified index position \a i. This gives you full control over the ordering of the bars. - + \a bars may already be part of this group. In that case, \a bars is just moved to the new index position. @@ -24127,7 +24153,7 @@ void QCPBarsGroup::insert(int i, QCPBars *bars) qDebug() << Q_FUNC_INFO << "bars is 0"; return; } - + // first append to bars list normally: if (!mBars.contains(bars)) bars->setBarsGroup(this); @@ -24137,7 +24163,7 @@ void QCPBarsGroup::insert(int i, QCPBars *bars) /*! Removes the specified \a bars plottable from this group. - + \see contains, clear */ void QCPBarsGroup::remove(QCPBars *bars) @@ -24147,7 +24173,7 @@ void QCPBarsGroup::remove(QCPBars *bars) qDebug() << Q_FUNC_INFO << "bars is 0"; return; } - + if (mBars.contains(bars)) bars->setBarsGroup(nullptr); else @@ -24155,10 +24181,10 @@ void QCPBarsGroup::remove(QCPBars *bars) } /*! \internal - + Adds the specified \a bars to the internal mBars list of bars. This method does not change the barsGroup property on \a bars. - + \see unregisterBars */ void QCPBarsGroup::registerBars(QCPBars *bars) @@ -24168,10 +24194,10 @@ void QCPBarsGroup::registerBars(QCPBars *bars) } /*! \internal - + Removes the specified \a bars from the internal mBars list of bars. This method does not change the barsGroup property on \a bars. - + \see registerBars */ void QCPBarsGroup::unregisterBars(QCPBars *bars) @@ -24180,7 +24206,7 @@ void QCPBarsGroup::unregisterBars(QCPBars *bars) } /*! \internal - + Returns the pixel offset in the key dimension the specified \a bars plottable should have at the given key coordinate \a keyCoord. The offset is relative to the pixel position of the key coordinate \a keyCoord. @@ -24200,7 +24226,7 @@ double QCPBarsGroup::keyPixelOffset(const QCPBars *bars, double keyCoord) const QCPBars *thisBase = bars; while (thisBase->barBelow()) thisBase = thisBase->barBelow(); - + // determine key pixel offset of this base bars considering all other base bars in this barsgroup: double result = 0; int index = baseBars.indexOf(thisBase); @@ -24242,10 +24268,10 @@ double QCPBarsGroup::keyPixelOffset(const QCPBars *bars, double keyCoord) } /*! \internal - + Returns the spacing in pixels which is between this \a bars and the following one, both at the key coordinate \a keyCoord. - + \note Typically the returned value doesn't depend on \a bars or \a keyCoord. \a bars is only needed to get access to the key axis transformation and axis rect for the modes \ref stAxisRectRatio and \ref stPlotCoords. The \a keyCoord is only relevant for spacings given in @@ -24282,65 +24308,65 @@ double QCPBarsGroup::getPixelSpacing(const QCPBars *bars, double keyCoord) /*! \class QCPBarsData \brief Holds the data of one single data point (one bar) for QCPBars. - + The stored data is: \li \a key: coordinate on the key axis of this bar (this is the \a mainKey and the \a sortKey) \li \a value: height coordinate on the value axis of this bar (this is the \a mainValue) - + The container for storing multiple data points is \ref QCPBarsDataContainer. It is a typedef for \ref QCPDataContainer with \ref QCPBarsData as the DataType template parameter. See the documentation there for an explanation regarding the data type's generic methods. - + \see QCPBarsDataContainer */ /* start documentation of inline functions */ /*! \fn double QCPBarsData::sortKey() const - + Returns the \a key member of this data point. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn static QCPBarsData QCPBarsData::fromSortKey(double sortKey) - + Returns a data point with the specified \a sortKey. All other members are set to zero. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn static static bool QCPBarsData::sortKeyIsMainKey() - + Since the member \a key is both the data point key coordinate and the data ordering parameter, this method returns true. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn double QCPBarsData::mainKey() const - + Returns the \a key member of this data point. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn double QCPBarsData::mainValue() const - + Returns the \a value member of this data point. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn QCPRange QCPBarsData::valueRange() const - + Returns a QCPRange with both lower and upper boundary set to \a value of this data point. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ @@ -24374,29 +24400,29 @@ QCPBarsData::QCPBarsData(double key, double value) : \brief A plottable representing a bar chart in a plot. \image html QCPBars.png - + To plot data, assign it with the \ref setData or \ref addData functions. - + \section qcpbars-appearance Changing the appearance - + The appearance of the bars is determined by the pen and the brush (\ref setPen, \ref setBrush). The width of the individual bars can be controlled with \ref setWidthType and \ref setWidth. - + Bar charts are stackable. This means, two QCPBars plottables can be placed on top of each other (see \ref QCPBars::moveAbove). So when two bars are at the same key position, they will appear stacked. - + If you would like to group multiple QCPBars plottables together so they appear side by side as shown below, use QCPBarsGroup. - + \image html QCPBarsGroup.png - + \section qcpbars-usage Usage - + Like all data representing objects in QCustomPlot, the QCPBars is a plottable (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) - + Usually, you first create an instance: \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-creation-1 which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes @@ -24408,7 +24434,7 @@ QCPBarsData::QCPBarsData(double key, double value) : /* start of documentation of inline functions */ /*! \fn QSharedPointer QCPBars::data() const - + Returns a shared pointer to the internal data storage of type \ref QCPBarsDataContainer. You may use it to directly manipulate the data, which may be more convenient and faster than using the regular \ref setData or \ref addData methods. @@ -24417,14 +24443,14 @@ QCPBarsData::QCPBarsData(double key, double value) : /*! \fn QCPBars *QCPBars::barBelow() const Returns the bars plottable that is directly below this bars plottable. If there is no such plottable, returns \c nullptr. - + \see barAbove, moveBelow, moveAbove */ /*! \fn QCPBars *QCPBars::barAbove() const Returns the bars plottable that is directly above this bars plottable. If there is no such plottable, returns \c nullptr. - + \see barBelow, moveBelow, moveAbove */ @@ -24435,7 +24461,7 @@ QCPBarsData::QCPBarsData(double key, double value) : axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have the same orientation. If either of these restrictions is violated, a corresponding message is printed to the debug output (qDebug), the construction is not aborted, though. - + The created QCPBars is automatically registered with the QCustomPlot instance inferred from \a keyAxis. This QCustomPlot instance takes ownership of the QCPBars, so do not delete it manually but use QCustomPlot::removePlottable() instead. @@ -24464,18 +24490,18 @@ QCPBars::~QCPBars() } /*! \overload - + Replaces the current data container with the provided \a data container. - + Since a QSharedPointer is used, multiple QCPBars may share the same data container safely. Modifying the data in the container will then affect all bars that share the container. Sharing can be achieved by simply exchanging the data containers wrapped in shared pointers: \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-datasharing-1 - + If you do not wish to share containers, but create a copy from an existing container, rather use the \ref QCPDataContainer::set method on the bar's data container directly: \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-datasharing-2 - + \see addData */ void QCPBars::setData(QSharedPointer data) @@ -24484,14 +24510,14 @@ void QCPBars::setData(QSharedPointer data) } /*! \overload - + Replaces the current data with the provided points in \a keys and \a values. The provided vectors should have equal length. Else, the number of added points will be the size of the smallest vector. - + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you can set \a alreadySorted to true, to improve performance by saving a sorting run. - + \see addData */ void QCPBars::setData(const QVector &keys, const QVector &values, bool alreadySorted) @@ -24514,9 +24540,9 @@ void QCPBars::setWidth(double width) /*! Sets how the width of the bars is defined. See the documentation of \ref WidthType for an explanation of the possible values for \a widthType. - + The default value is \ref wtPlotCoords. - + \see setWidth */ void QCPBars::setWidthType(QCPBars::WidthType widthType) @@ -24527,7 +24553,7 @@ void QCPBars::setWidthType(QCPBars::WidthType widthType) /*! Sets to which QCPBarsGroup this QCPBars instance belongs to. Alternatively, you can also use \ref QCPBarsGroup::append. - + To remove this QCPBars from any group, set \a barsGroup to \c nullptr. */ void QCPBars::setBarsGroup(QCPBarsGroup *barsGroup) @@ -24548,9 +24574,9 @@ void QCPBars::setBarsGroup(QCPBarsGroup *barsGroup) the base value is given by their individual value data. For example, if the base value is set to 1, a bar with data value 2 will have its lowest point at value coordinate 1 and highest point at 3. - + For stacked bars, only the base value of the bottom-most QCPBars has meaning. - + The default base value is 0. */ void QCPBars::setBaseValue(double baseValue) @@ -24569,14 +24595,14 @@ void QCPBars::setStackingGap(double pixels) } /*! \overload - + Adds the provided points in \a keys and \a values to the current data. The provided vectors should have equal length. Else, the number of added points will be the size of the smallest vector. - + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you can set \a alreadySorted to true, to improve performance by saving a sorting run. - + Alternatively, you can also access and modify the data directly via the \ref data method, which returns a pointer to the internal data container. */ @@ -24601,7 +24627,7 @@ void QCPBars::addData(const QVector &keys, const QVector &values /*! \overload Adds the provided data point as \a key and \a value to the current data. - + Alternatively, you can also access and modify the data directly via the \ref data method, which returns a pointer to the internal data container. */ @@ -24614,14 +24640,14 @@ void QCPBars::addData(double key, double value) Moves this bars plottable below \a bars. In other words, the bars of this plottable will appear below the bars of \a bars. The move target \a bars must use the same key and value axis as this plottable. - + Inserting into and removing from existing bar stacking is handled gracefully. If \a bars already has a bars object below itself, this bars object is inserted between the two. If this bars object is already between two other bars, the two other bars will be stacked on top of each other after the operation. - + To remove this bars plottable from any stacking, set \a bars to \c nullptr. - + \see moveBelow, barAbove, barBelow */ void QCPBars::moveBelow(QCPBars *bars) @@ -24647,14 +24673,14 @@ void QCPBars::moveBelow(QCPBars *bars) Moves this bars plottable above \a bars. In other words, the bars of this plottable will appear above the bars of \a bars. The move target \a bars must use the same key and value axis as this plottable. - + Inserting into and removing from existing bar stacking is handled gracefully. If \a bars already has a bars object above itself, this bars object is inserted between the two. If this bars object is already between two other bars, the two other bars will be stacked on top of each other after the operation. - + To remove this bars plottable from any stacking, set \a bars to \c nullptr. - + \see moveBelow, barBelow, barAbove */ void QCPBars::moveAbove(QCPBars *bars) @@ -24686,10 +24712,10 @@ QCPDataSelection QCPBars::selectTestRect(const QRectF &rect, bool onlySelectable return result; if (!mKeyAxis || !mValueAxis) return result; - + QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd; getVisibleDataBounds(visibleBegin, visibleEnd); - + for (QCPBarsDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) { if (rect.intersects(getBarRect(it->key, it->value))) @@ -24704,7 +24730,7 @@ QCPDataSelection QCPBars::selectTestRect(const QRectF &rect, bool onlySelectable If \a details is not 0, it will be set to a \ref QCPDataSelection, describing the closest data point to \a pos. - + \seebaseclassmethod \ref QCPAbstractPlottable::selectTest */ double QCPBars::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const @@ -24714,7 +24740,7 @@ double QCPBars::selectTest(const QPointF &pos, bool onlySelectable, QVariant *de return -1; if (!mKeyAxis || !mValueAxis) return -1; - + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()) || mParentPlot->interactions().testFlag(QCP::iSelectPlottablesBeyondAxisRect)) { // get visible data range: @@ -24750,7 +24776,7 @@ QCPRange QCPBars::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) co */ QCPRange range; range = mDataContainer->keyRange(foundRange, inSignDomain); - + // determine exact range of bars by including bar width and barsgroup offset: if (foundRange && mKeyAxis) { @@ -24810,7 +24836,7 @@ QCPRange QCPBars::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, } } } - + foundRange = true; // return true because bar charts always have the 0-line visible return range; } @@ -24823,7 +24849,7 @@ QPointF QCPBars::dataPixelPosition(int index) const QCPAxis *keyAxis = mKeyAxis.data(); QCPAxis *valueAxis = mValueAxis.data(); if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return {}; } - + const QCPDataContainer::const_iterator it = mDataContainer->constBegin()+index; const double valuePixel = valueAxis->coordToPixel(getStackedBaseValue(it->key, it->value >= 0) + it->value); const double keyPixel = keyAxis->coordToPixel(it->key) + (mBarsGroup ? mBarsGroup->keyPixelOffset(this, it->key) : 0); @@ -24843,10 +24869,10 @@ void QCPBars::draw(QCPPainter *painter) { if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } if (mDataContainer->isEmpty()) return; - + QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd; getVisibleDataBounds(visibleBegin, visibleEnd); - + // loop over and draw segments of unselected/selected data: QList selectedSegments, unselectedSegments, allSegments; getDataSegments(selectedSegments, unselectedSegments); @@ -24859,7 +24885,7 @@ void QCPBars::draw(QCPPainter *painter) mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i)); if (begin == end) continue; - + for (QCPBarsDataContainer::const_iterator it=begin; it!=end; ++it) { // check data validity if flag set: @@ -24881,7 +24907,7 @@ void QCPBars::draw(QCPPainter *painter) painter->drawPolygon(getBarRect(it->key, it->value)); } } - + // draw other selection decoration that isn't just line/scatter pens and brushes: if (mSelectionDecorator) mSelectionDecorator->drawDecoration(painter, selection()); @@ -24900,17 +24926,17 @@ void QCPBars::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const } /*! \internal - + called by \ref draw to determine which data (key) range is visible at the current key axis range setting, so only that needs to be processed. It also takes into account the bar width. - + \a begin returns an iterator to the lowest data point that needs to be taken into account when plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a lower may still be just outside the visible range. - + \a end returns an iterator one higher than the highest visible data point. Same as before, \a end may also lie just outside of the visible range. - + if the plottable contains no data, both \a begin and \a end point to constEnd. */ void QCPBars::getVisibleDataBounds(QCPBarsDataContainer::const_iterator &begin, QCPBarsDataContainer::const_iterator &end) const @@ -24928,7 +24954,7 @@ void QCPBars::getVisibleDataBounds(QCPBarsDataContainer::const_iterator &begin, end = mDataContainer->constEnd(); return; } - + // get visible data range as QMap iterators begin = mDataContainer->findBegin(mKeyAxis.data()->range().lower); end = mDataContainer->findEnd(mKeyAxis.data()->range().upper); @@ -24968,7 +24994,7 @@ void QCPBars::getVisibleDataBounds(QCPBarsDataContainer::const_iterator &begin, } /*! \internal - + Returns the rect in pixel coordinates of a single bar with the specified \a key and \a value. The rect is shifted according to the bar stacking (see \ref moveAbove) and base value (see \ref setBaseValue), and to have non-overlapping border lines with the bars stacked below. @@ -24978,7 +25004,7 @@ QRectF QCPBars::getBarRect(double key, double value) const QCPAxis *keyAxis = mKeyAxis.data(); QCPAxis *valueAxis = mValueAxis.data(); if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return {}; } - + double lowerPixelWidth, upperPixelWidth; getPixelWidth(key, lowerPixelWidth, upperPixelWidth); double base = getStackedBaseValue(key, value >= 0); @@ -25002,10 +25028,10 @@ QRectF QCPBars::getBarRect(double key, double value) const } /*! \internal - + This function is used to determine the width of the bar at coordinate \a key, according to the specified width (\ref setWidth) and width type (\ref setWidthType). - + The output parameters \a lower and \a upper return the number of pixels the bar extends to lower and higher keys, relative to the \a key coordinate (so with a non-reversed horizontal axis, \a lower is negative and \a upper positive). @@ -25052,10 +25078,10 @@ void QCPBars::getPixelWidth(double key, double &lower, double &upper) const } /*! \internal - + This function is called to find at which value to start drawing the base of a bar at \a key, when it is stacked on top of another QCPBars (e.g. with \ref moveAbove). - + positive and negative bars are separated per stack (positive are stacked above baseValue upwards, negative are stacked below baseValue downwards). This can be indicated with \a positive. So if the bar for which we need the base value is negative, set \a positive to false. @@ -25091,14 +25117,14 @@ double QCPBars::getStackedBaseValue(double key, bool positive) const Connects \a below and \a above to each other via their mBarAbove/mBarBelow properties. The bar(s) currently above lower and below upper will become disconnected to lower/upper. - + If lower is zero, upper will be disconnected at the bottom. If upper is zero, lower will be disconnected at the top. */ void QCPBars::connectBars(QCPBars *lower, QCPBars *upper) { if (!lower && !upper) return; - + if (!lower) // disconnect upper at bottom { // disconnect old bar below upper: @@ -25135,87 +25161,87 @@ void QCPBars::connectBars(QCPBars *lower, QCPBars *upper) /*! \class QCPStatisticalBoxData \brief Holds the data of one single data point for QCPStatisticalBox. - + The stored data is: - + \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey) - + \li \a minimum: the position of the lower whisker, typically the minimum measurement of the sample that's not considered an outlier. - + \li \a lowerQuartile: the lower end of the box. The lower and the upper quartiles are the two statistical quartiles around the median of the sample, they should contain 50% of the sample data. - + \li \a median: the value of the median mark inside the quartile box. The median separates the sample data in half (50% of the sample data is below/above the median). (This is the \a mainValue) - + \li \a upperQuartile: the upper end of the box. The lower and the upper quartiles are the two statistical quartiles around the median of the sample, they should contain 50% of the sample data. - + \li \a maximum: the position of the upper whisker, typically the maximum measurement of the sample that's not considered an outlier. - + \li \a outliers: a QVector of outlier values that will be drawn as scatter points at the \a key coordinate of this data point (see \ref QCPStatisticalBox::setOutlierStyle) - + The container for storing multiple data points is \ref QCPStatisticalBoxDataContainer. It is a typedef for \ref QCPDataContainer with \ref QCPStatisticalBoxData as the DataType template parameter. See the documentation there for an explanation regarding the data type's generic methods. - + \see QCPStatisticalBoxDataContainer */ /* start documentation of inline functions */ /*! \fn double QCPStatisticalBoxData::sortKey() const - + Returns the \a key member of this data point. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn static QCPStatisticalBoxData QCPStatisticalBoxData::fromSortKey(double sortKey) - + Returns a data point with the specified \a sortKey. All other members are set to zero. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn static static bool QCPStatisticalBoxData::sortKeyIsMainKey() - + Since the member \a key is both the data point key coordinate and the data ordering parameter, this method returns true. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn double QCPStatisticalBoxData::mainKey() const - + Returns the \a key member of this data point. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn double QCPStatisticalBoxData::mainValue() const - + Returns the \a median member of this data point. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn QCPRange QCPStatisticalBoxData::valueRange() const - + Returns a QCPRange spanning from the \a minimum to the \a maximum member of this statistical box data point, possibly further expanded by outliers. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ @@ -25259,19 +25285,19 @@ QCPStatisticalBoxData::QCPStatisticalBoxData(double key, double minimum, double \brief A plottable representing a single statistical box in a plot. \image html QCPStatisticalBox.png - + To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can also access and modify the data via the \ref data method, which returns a pointer to the internal \ref QCPStatisticalBoxDataContainer. - + Additionally each data point can itself have a list of outliers, drawn as scatter points at the key coordinate of the respective statistical box data point. They can either be set by using the respective \ref addData(double,double,double,double,double,double,const QVector&) "addData" method or accessing the individual data points through \ref data, and setting the QVector outliers of the data points directly. - + \section qcpstatisticalbox-appearance Changing the appearance - + The appearance of each data point box, ranging from the lower to the upper quartile, is controlled via \ref setPen and \ref setBrush. You may change the width of the boxes with \ref setWidth in plot coordinates. @@ -25283,18 +25309,18 @@ QCPStatisticalBoxData::QCPStatisticalBoxData(double key, double minimum, double the top (for maximum) and bottom (for minimum). If the whisker pen is changed, make sure to set the \c capStyle to \c Qt::FlatCap. Otherwise the backbone line might exceed the whisker bars by a few pixels due to the pen cap being not perfectly flat. - + The median indicator line inside the box has its own pen, \ref setMedianPen. - + The outlier data points are drawn as normal scatter points. Their look can be controlled with \ref setOutlierStyle - + \section qcpstatisticalbox-usage Usage - + Like all data representing objects in QCustomPlot, the QCPStatisticalBox is a plottable (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) - + Usually, you first create an instance: \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-creation-1 which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes @@ -25306,7 +25332,7 @@ QCPStatisticalBoxData::QCPStatisticalBoxData(double key, double minimum, double /* start documentation of inline functions */ /*! \fn QSharedPointer QCPStatisticalBox::data() const - + Returns a shared pointer to the internal data storage of type \ref QCPStatisticalBoxDataContainer. You may use it to directly manipulate the data, which may be more convenient and faster than using the regular \ref setData or \ref addData methods. @@ -25319,7 +25345,7 @@ QCPStatisticalBoxData::QCPStatisticalBoxData(double key, double minimum, double value axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have the same orientation. If either of these restrictions is violated, a corresponding message is printed to the debug output (qDebug), the construction is not aborted, though. - + The created QCPStatisticalBox is automatically registered with the QCustomPlot instance inferred from \a keyAxis. This QCustomPlot instance takes ownership of the QCPStatisticalBox, so do not delete it manually but use QCustomPlot::removePlottable() instead. @@ -25339,19 +25365,19 @@ QCPStatisticalBox::QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis) : } /*! \overload - + Replaces the current data container with the provided \a data container. - + Since a QSharedPointer is used, multiple QCPStatisticalBoxes may share the same data container safely. Modifying the data in the container will then affect all statistical boxes that share the container. Sharing can be achieved by simply exchanging the data containers wrapped in shared pointers: \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-datasharing-1 - + If you do not wish to share containers, but create a copy from an existing container, rather use the \ref QCPDataContainer::set method on the statistical box data container directly: \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-datasharing-2 - + \see addData */ void QCPStatisticalBox::setData(QSharedPointer data) @@ -25359,14 +25385,14 @@ void QCPStatisticalBox::setData(QSharedPointer d mDataContainer = data; } /*! \overload - + Replaces the current data with the provided points in \a keys, \a minimum, \a lowerQuartile, \a median, \a upperQuartile and \a maximum. The provided vectors should have equal length. Else, the number of added points will be the size of the smallest vector. - + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you can set \a alreadySorted to true, to improve performance by saving a sorting run. - + \see addData */ void QCPStatisticalBox::setData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted) @@ -25377,7 +25403,7 @@ void QCPStatisticalBox::setData(const QVector &keys, const QVector &keys, const QVectoraxisRect()->rect().contains(pos.toPoint()) || mParentPlot->interactions().testFlag(QCP::iSelectPlottablesBeyondAxisRect)) { // get visible data range: @@ -25617,10 +25643,10 @@ void QCPStatisticalBox::draw(QCPPainter *painter) QCPAxis *keyAxis = mKeyAxis.data(); QCPAxis *valueAxis = mValueAxis.data(); if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - + QCPStatisticalBoxDataContainer::const_iterator visibleBegin, visibleEnd; getVisibleDataBounds(visibleBegin, visibleEnd); - + // loop over and draw segments of unselected/selected data: QList selectedSegments, unselectedSegments, allSegments; getDataSegments(selectedSegments, unselectedSegments); @@ -25633,7 +25659,7 @@ void QCPStatisticalBox::draw(QCPPainter *painter) mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i)); if (begin == end) continue; - + for (QCPStatisticalBoxDataContainer::const_iterator it=begin; it!=end; ++it) { // check data validity if flag set: @@ -25646,7 +25672,7 @@ void QCPStatisticalBox::draw(QCPPainter *painter) if (QCP::isInvalidData(it->outliers.at(i))) qDebug() << Q_FUNC_INFO << "Data point outlier at" << it->key << "of drawn range invalid." << "Plottable name:" << name(); # endif - + if (isSelectedSegment && mSelectionDecorator) { mSelectionDecorator->applyPen(painter); @@ -25662,7 +25688,7 @@ void QCPStatisticalBox::draw(QCPPainter *painter) drawStatisticalBox(painter, it, finalOutlierStyle); } } - + // draw other selection decoration that isn't just line/scatter pens and brushes: if (mSelectionDecorator) mSelectionDecorator->drawDecoration(painter, selection()); @@ -25714,17 +25740,17 @@ void QCPStatisticalBox::drawStatisticalBox(QCPPainter *painter, QCPStatisticalBo } /*! \internal - + called by \ref draw to determine which data (key) range is visible at the current key axis range setting, so only that needs to be processed. It also takes into account the bar width. - + \a begin returns an iterator to the lowest data point that needs to be taken into account when plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a lower may still be just outside the visible range. - + \a end returns an iterator one higher than the highest visible data point. Same as before, \a end may also lie just outside of the visible range. - + if the plottable contains no data, both \a begin and \a end point to constEnd. */ void QCPStatisticalBox::getVisibleDataBounds(QCPStatisticalBoxDataContainer::const_iterator &begin, QCPStatisticalBoxDataContainer::const_iterator &end) const @@ -25797,25 +25823,25 @@ QVector QCPStatisticalBox::getWhiskerBarLines(QCPStatisticalBoxDataConta /*! \class QCPColorMapData \brief Holds the two-dimensional data of a QCPColorMap plottable. - + This class is a data storage for \ref QCPColorMap. It holds a two-dimensional array, which \ref QCPColorMap then displays as a 2D image in the plot, where the array values are represented by a color, depending on the value. - + The size of the array can be controlled via \ref setSize (or \ref setKeySize, \ref setValueSize). Which plot coordinates these cells correspond to can be configured with \ref setRange (or \ref setKeyRange, \ref setValueRange). - + The data cells can be accessed in two ways: They can be directly addressed by an integer index with \ref setCell. This is the fastest method. Alternatively, they can be addressed by their plot coordinate with \ref setData. plot coordinate to cell index transformations and vice versa are provided by the functions \ref coordToCell and \ref cellToCoord. - + A \ref QCPColorMapData also holds an on-demand two-dimensional array of alpha values which (if allocated) has the same size as the data map. It can be accessed via \ref setAlpha, \ref fillAlpha and \ref clearAlpha. The memory for the alpha map is only allocated if needed, i.e. on the first call of \ref setAlpha. \ref clearAlpha restores full opacity and frees the alpha map. - + This class also buffers the minimum and maximum values that are in the data set, to provide QCPColorMap::rescaleDataRange with the necessary information quickly. Setting a cell to a value that is greater than the current maximum increases this maximum to the new value. However, @@ -25831,7 +25857,7 @@ QVector QCPStatisticalBox::getWhiskerBarLines(QCPStatisticalBoxDataConta /* start of documentation of inline functions */ /*! \fn bool QCPColorMapData::isEmpty() const - + Returns whether this instance carries no data. This is equivalent to having a size where at least one of the dimensions is 0 (see \ref setSize). */ @@ -25842,7 +25868,7 @@ QVector QCPStatisticalBox::getWhiskerBarLines(QCPStatisticalBoxDataConta Constructs a new QCPColorMapData instance. The instance has \a keySize cells in the key direction and \a valueSize cells in the value direction. These cells will be displayed by the \ref QCPColorMap at the coordinates \a keyRange and \a valueRange. - + \see setSize, setKeySize, setValueSize, setRange, setKeyRange, setValueRange */ QCPColorMapData::QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange) : @@ -25949,7 +25975,7 @@ unsigned char QCPColorMapData::alpha(int keyIndex, int valueIndex) The current data is discarded and the map cells are set to 0, unless the map had already the requested size. - + Setting at least one of \a keySize or \a valueSize to zero frees the internal data array and \ref isEmpty returns true. @@ -25978,10 +26004,10 @@ void QCPColorMapData::setSize(int keySize, int valueSize) qDebug() << Q_FUNC_INFO << "out of memory for data dimensions "<< mKeySize << "*" << mValueSize; } else mData = nullptr; - + if (mAlpha) // if we had an alpha map, recreate it with new size createAlpha(); - + mDataModified = true; } } @@ -25991,7 +26017,7 @@ void QCPColorMapData::setSize(int keySize, int valueSize) The current data is discarded and the map cells are set to 0, unless the map had already the requested size. - + Setting \a keySize to zero frees the internal data array and \ref isEmpty returns true. \see setKeyRange, setSize, setValueSize @@ -26006,7 +26032,7 @@ void QCPColorMapData::setKeySize(int keySize) The current data is discarded and the map cells are set to 0, unless the map had already the requested size. - + Setting \a valueSize to zero frees the internal data array and \ref isEmpty returns true. \see setValueRange, setSize, setKeySize @@ -26019,11 +26045,11 @@ void QCPColorMapData::setValueSize(int valueSize) /*! Sets the coordinate ranges the data shall be distributed over. This defines the rectangular area covered by the color map in plot coordinates. - + The outer cells will be centered on the range boundaries given to this function. For example, if the key size (\ref setKeySize) is 3 and \a keyRange is set to QCPRange(2, 3) there will be cells centered on the key coordinates 2, 2.5 and 3. - + \see setSize */ void QCPColorMapData::setRange(const QCPRange &keyRange, const QCPRange &valueRange) @@ -26035,11 +26061,11 @@ void QCPColorMapData::setRange(const QCPRange &keyRange, const QCPRange &valueRa /*! Sets the coordinate range the data shall be distributed over in the key dimension. Together with the value range, This defines the rectangular area covered by the color map in plot coordinates. - + The outer cells will be centered on the range boundaries given to this function. For example, if the key size (\ref setKeySize) is 3 and \a keyRange is set to QCPRange(2, 3) there will be cells centered on the key coordinates 2, 2.5 and 3. - + \see setRange, setValueRange, setSize */ void QCPColorMapData::setKeyRange(const QCPRange &keyRange) @@ -26050,11 +26076,11 @@ void QCPColorMapData::setKeyRange(const QCPRange &keyRange) /*! Sets the coordinate range the data shall be distributed over in the value dimension. Together with the key range, This defines the rectangular area covered by the color map in plot coordinates. - + The outer cells will be centered on the range boundaries given to this function. For example, if the value size (\ref setValueSize) is 3 and \a valueRange is set to QCPRange(2, 3) there will be cells centered on the value coordinates 2, 2.5 and 3. - + \see setRange, setKeyRange, setSize */ void QCPColorMapData::setValueRange(const QCPRange &valueRange) @@ -26065,13 +26091,13 @@ void QCPColorMapData::setValueRange(const QCPRange &valueRange) /*! Sets the data of the cell, which lies at the plot coordinates given by \a key and \a value, to \a z. - + \note The QCPColorMap always displays the data at equal key/value intervals, even if the key or value axis is set to a logarithmic scaling. If you want to use QCPColorMap with logarithmic axes, you shouldn't use the \ref QCPColorMapData::setData method as it uses a linear transformation to determine the cell index. Rather directly access the cell index with \ref QCPColorMapData::setCell. - + \see setCell, setRange */ void QCPColorMapData::setData(double key, double value, double z) @@ -26093,11 +26119,11 @@ void QCPColorMapData::setData(double key, double value, double z) Sets the data of the cell with indices \a keyIndex and \a valueIndex to \a z. The indices enumerate the cells starting from zero, up to the map's size-1 in the respective dimension (see \ref setSize). - + In the standard plot configuration (horizontal key axis and vertical value axis, both not range-reversed), the cell with indices (0, 0) is in the bottom left corner and the cell with indices (keySize-1, valueSize-1) is in the top right corner of the color map. - + \see setData, setSize */ void QCPColorMapData::setCell(int keyIndex, int valueIndex, double z) @@ -26144,13 +26170,13 @@ void QCPColorMapData::setAlpha(int keyIndex, int valueIndex, unsigned char alpha /*! Goes through the data and updates the buffered minimum and maximum data values. - + Calling this method is only advised if you are about to call \ref QCPColorMap::rescaleDataRange and can not guarantee that the cells holding the maximum or minimum data haven't been overwritten with a smaller or larger value respectively, since the buffered maximum/minimum values have been updated the last time. Why this is the case is explained in the class description (\ref QCPColorMapData). - + Note that the method \ref QCPColorMap::rescaleDataRange provides a parameter \a recalculateDataBounds for convenience. Setting this to true will call this method for you, before doing the rescale. @@ -26176,7 +26202,7 @@ void QCPColorMapData::recalculateDataBounds() /*! Frees the internal data memory. - + This is equivalent to calling \ref setSize "setSize(0, 0)". */ void QCPColorMapData::clear() @@ -26231,17 +26257,17 @@ void QCPColorMapData::fillAlpha(unsigned char alpha) Transforms plot coordinates given by \a key and \a value to cell indices of this QCPColorMapData instance. The resulting cell indices are returned via the output parameters \a keyIndex and \a valueIndex. - + The retrieved key/value cell indices can then be used for example with \ref setCell. - + If you are only interested in a key or value index, you may pass \c nullptr as \a valueIndex or \a keyIndex. - + \note The QCPColorMap always displays the data at equal key/value intervals, even if the key or value axis is set to a logarithmic scaling. If you want to use QCPColorMap with logarithmic axes, you shouldn't use the \ref QCPColorMapData::coordToCell method as it uses a linear transformation to determine the cell index. - + \see cellToCoord, QCPAxis::coordToPixel */ void QCPColorMapData::coordToCell(double key, double value, int *keyIndex, int *valueIndex) const @@ -26256,15 +26282,15 @@ void QCPColorMapData::coordToCell(double key, double value, int *keyIndex, int * Transforms cell indices given by \a keyIndex and \a valueIndex to cell indices of this QCPColorMapData instance. The resulting coordinates are returned via the output parameters \a key and \a value. - + If you are only interested in a key or value coordinate, you may pass \c nullptr as \a key or \a value. - + \note The QCPColorMap always displays the data at equal key/value intervals, even if the key or value axis is set to a logarithmic scaling. If you want to use QCPColorMap with logarithmic axes, you shouldn't use the \ref QCPColorMapData::cellToCoord method as it uses a linear transformation to determine the cell index. - + \see coordToCell, QCPAxis::pixelToCoord */ void QCPColorMapData::cellToCoord(int keyIndex, int valueIndex, double *key, double *value) const @@ -26293,7 +26319,7 @@ bool QCPColorMapData::createAlpha(bool initializeOpaque) clearAlpha(); if (isEmpty()) return false; - + #ifdef __EXCEPTIONS try { // 2D arrays get memory intensive fast. So if the allocation fails, at least output debug message #endif @@ -26322,10 +26348,10 @@ bool QCPColorMapData::createAlpha(bool initializeOpaque) \brief A plottable representing a two-dimensional color map in a plot. \image html QCPColorMap.png - + The data is stored in the class \ref QCPColorMapData, which can be accessed via the data() method. - + A color map has three dimensions to represent a data point: The \a key dimension, the \a value dimension and the \a data dimension. As with other plottables such as graphs, \a key and \a value correspond to two orthogonal axes on the QCustomPlot surface that you specify in the QCPColorMap @@ -26340,53 +26366,53 @@ bool QCPColorMapData::createAlpha(bool initializeOpaque) their plot coordinates with \ref QCPColorMapData::setData. If possible, you should prefer setCell, since it doesn't need to do any coordinate transformation and thus performs a bit better. - + The cell with index (0, 0) is at the bottom left, if the color map uses normal (i.e. not reversed) key and value axes. - + To show the user which colors correspond to which \a data values, a \ref QCPColorScale is typically placed to the right of the axis rect. See the documentation there for details on how to add and use a color scale. - + \section qcpcolormap-appearance Changing the appearance - + Most important to the appearance is the color gradient, which can be specified via \ref setGradient. See the documentation of \ref QCPColorGradient for details on configuring a color gradient. - + The \a data range that is mapped to the colors of the gradient can be specified with \ref setDataRange. To make the data range encompass the whole data set minimum to maximum, call \ref rescaleDataRange. If your data may contain NaN values, use \ref QCPColorGradient::setNanHandling to define how they are displayed. - + \section qcpcolormap-transparency Transparency - + Transparency in color maps can be achieved by two mechanisms. On one hand, you can specify alpha values for color stops of the \ref QCPColorGradient, via the regular QColor interface. This will cause the color map data which gets mapped to colors around those color stops to appear with the accordingly interpolated transparency. - + On the other hand you can also directly apply an alpha value to each cell independent of its data, by using the alpha map feature of \ref QCPColorMapData. The relevant methods are \ref QCPColorMapData::setAlpha, QCPColorMapData::fillAlpha and \ref QCPColorMapData::clearAlpha(). - + The two transparencies will be joined together in the plot and otherwise not interfere with each other. They are mixed in a multiplicative matter, so an alpha of e.g. 50% (128/255) in both modes simultaneously, will result in a total transparency of 25% (64/255). - + \section qcpcolormap-usage Usage - + Like all data representing objects in QCustomPlot, the QCPColorMap is a plottable (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) - + Usually, you first create an instance: \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolormap-creation-1 which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead. The newly created plottable can be modified, e.g.: \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolormap-creation-2 - + \note The QCPColorMap always displays the data at equal key/value intervals, even if the key or value axis is set to a logarithmic scaling. If you want to use QCPColorMap with logarithmic axes, you shouldn't use the \ref QCPColorMapData::setData method as it uses a linear transformation to @@ -26397,10 +26423,10 @@ bool QCPColorMapData::createAlpha(bool initializeOpaque) /* start documentation of inline functions */ /*! \fn QCPColorMapData *QCPColorMap::data() const - + Returns a pointer to the internal data storage of type \ref QCPColorMapData. Access this to modify data points (cells) and the color map key/value range. - + \see setData */ @@ -26409,23 +26435,23 @@ bool QCPColorMapData::createAlpha(bool initializeOpaque) /* start documentation of signals */ /*! \fn void QCPColorMap::dataRangeChanged(const QCPRange &newRange); - + This signal is emitted when the data range changes. - + \see setDataRange */ /*! \fn void QCPColorMap::dataScaleTypeChanged(QCPAxis::ScaleType scaleType); - + This signal is emitted when the data scale type changes. - + \see setDataScaleType */ /*! \fn void QCPColorMap::gradientChanged(const QCPColorGradient &newGradient); - + This signal is emitted when the gradient changes. - + \see setGradient */ @@ -26433,7 +26459,7 @@ bool QCPColorMapData::createAlpha(bool initializeOpaque) /*! Constructs a color map with the specified \a keyAxis and \a valueAxis. - + The created QCPColorMap is automatically registered with the QCustomPlot instance inferred from \a keyAxis. This QCustomPlot instance takes ownership of the QCPColorMap, so do not delete it manually but use QCustomPlot::removePlottable() instead. @@ -26456,7 +26482,7 @@ QCPColorMap::~QCPColorMap() /*! Replaces the current \ref data with the provided \a data. - + If \a copy is set to true, the \a data object will only be copied. if false, the color map takes ownership of the passed data and replaces the internal data pointer with it. This is significantly faster than copying for large datasets. @@ -26482,9 +26508,9 @@ void QCPColorMap::setData(QCPColorMapData *data, bool copy) /*! Sets the data range of this color map to \a dataRange. The data range defines which data values are mapped to the color gradient. - + To make the data range span the full range of the data set, use \ref rescaleDataRange. - + \see QCPColorScale::setDataRange */ void QCPColorMap::setDataRange(const QCPRange &dataRange) @@ -26503,7 +26529,7 @@ void QCPColorMap::setDataRange(const QCPRange &dataRange) /*! Sets whether the data is correlated with the color gradient linearly or logarithmically. - + \see QCPColorScale::setDataScaleType */ void QCPColorMap::setDataScaleType(QCPAxis::ScaleType scaleType) @@ -26521,12 +26547,12 @@ void QCPColorMap::setDataScaleType(QCPAxis::ScaleType scaleType) /*! Sets the color gradient that is used to represent the data. For more details on how to create an own gradient or use one of the preset gradients, see \ref QCPColorGradient. - + The colors defined by the gradient will be used to represent data values in the currently set data range, see \ref setDataRange. Data points that are outside this data range will either be colored uniformly with the respective gradient boundary color, or the gradient will repeat, depending on \ref QCPColorGradient::setPeriodic. - + \see QCPColorScale::setGradient */ void QCPColorMap::setGradient(const QCPColorGradient &gradient) @@ -26542,7 +26568,7 @@ void QCPColorMap::setGradient(const QCPColorGradient &gradient) /*! Sets whether the color map image shall use bicubic interpolation when displaying the color map shrinked or expanded, and not at a 1:1 pixel-to-data scale. - + \image html QCPColorMap-interpolate.png "A 10*10 color map, with interpolation and without interpolation enabled" */ void QCPColorMap::setInterpolate(bool enabled) @@ -26554,12 +26580,12 @@ void QCPColorMap::setInterpolate(bool enabled) /*! Sets whether the outer most data rows and columns are clipped to the specified key and value range (see \ref QCPColorMapData::setKeyRange, \ref QCPColorMapData::setValueRange). - + if \a enabled is set to false, the data points at the border of the color map are drawn with the same width and height as all other data points. Since the data points are represented by rectangles of one color centered on the data coordinate, this means that the shown color map extends by half a data point over the specified key/value range in each direction. - + \image html QCPColorMap-tightboundary.png "A color map, with tight boundary enabled and disabled" */ void QCPColorMap::setTightBoundary(bool enabled) @@ -26569,16 +26595,16 @@ void QCPColorMap::setTightBoundary(bool enabled) /*! Associates the color scale \a colorScale with this color map. - + This means that both the color scale and the color map synchronize their gradient, data range and data scale type (\ref setGradient, \ref setDataRange, \ref setDataScaleType). Multiple color maps can be associated with one single color scale. This causes the color maps to also synchronize those properties, via the mutual color scale. - + This function causes the color map to adopt the current color gradient, data range and data scale type of \a colorScale. After this call, you may change these properties at either the color map or the color scale, and the setting will be applied to both. - + Pass \c nullptr as \a colorScale to disconnect the color scale from this color map again. */ void QCPColorMap::setColorScale(QCPColorScale *colorScale) @@ -26611,7 +26637,7 @@ void QCPColorMap::setColorScale(QCPColorScale *colorScale) Sets the data range (\ref setDataRange) to span the minimum and maximum values that occur in the current data set. This corresponds to the \ref rescaleKeyAxis or \ref rescaleValueAxis methods, only for the third data dimension of the color map. - + The minimum and maximum values of the data set are buffered in the internal QCPColorMapData instance (\ref data). As data is updated via its \ref QCPColorMapData::setCell or \ref QCPColorMapData::setData, the buffered minimum and maximum values are updated, too. For @@ -26624,7 +26650,7 @@ void QCPColorMap::setColorScale(QCPColorScale *colorScale) QCPColorMapData::recalculateDataBounds can be used. For convenience, setting the parameter \a recalculateDataBounds calls this method before setting the data range to the buffered minimum and maximum. - + \see setDataRange */ void QCPColorMap::rescaleDataRange(bool recalculateDataBounds) @@ -26637,27 +26663,35 @@ void QCPColorMap::rescaleDataRange(bool recalculateDataBounds) /*! Takes the current appearance of the color map and updates the legend icon, which is used to represent this color map in the legend (see \ref QCPLegend). - + The \a transformMode specifies whether the rescaling is done by a faster, low quality image scaling algorithm (Qt::FastTransformation) or by a slower, higher quality algorithm (Qt::SmoothTransformation). - + The current color map appearance is scaled down to \a thumbSize. Ideally, this should be equal to the size of the legend icon (see \ref QCPLegend::setIconSize). If it isn't exactly the configured legend icon size, the thumb will be rescaled during drawing of the legend item. - + \see setDataRange */ void QCPColorMap::updateLegendIcon(Qt::TransformationMode transformMode, const QSize &thumbSize) { if (mMapImage.isNull() && !data()->isEmpty()) updateMapImage(); // try to update map image if it's null (happens if no draw has happened yet) - + if (!mMapImage.isNull()) // might still be null, e.g. if data is empty, so check here again { bool mirrorX = (keyAxis()->orientation() == Qt::Horizontal ? keyAxis() : valueAxis())->rangeReversed(); bool mirrorY = (valueAxis()->orientation() == Qt::Vertical ? valueAxis() : keyAxis())->rangeReversed(); - mLegendIcon = QPixmap::fromImage(mMapImage.mirrored(mirrorX, mirrorY)).scaled(thumbSize, Qt::KeepAspectRatio, transformMode); + // Qt 6.9.0 depreciated function + // mLegendIcon = QPixmap::fromImage(mMapImage.mirrored(mirrorX, mirrorY)).scaled(thumbSize, Qt::KeepAspectRatio, transformMode); + QImage img = mMapImage; + if (mirrorX) + img = img.flipped(Qt::Horizontal); + if (mirrorY) + img = img.flipped(Qt::Vertical); + mLegendIcon = QPixmap::fromImage(img).scaled(thumbSize, Qt::KeepAspectRatio, transformMode); + // end fix } } @@ -26669,7 +26703,7 @@ double QCPColorMap::selectTest(const QPointF &pos, bool onlySelectable, QVariant return -1; if (!mKeyAxis || !mValueAxis) return -1; - + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()) || mParentPlot->interactions().testFlag(QCP::iSelectPlottablesBeyondAxisRect)) { double posKey, posValue; @@ -26717,7 +26751,7 @@ QCPRange QCPColorMap::getValueRange(bool &foundRange, QCP::SignDomain inSignDoma return {}; } } - + foundRange = true; QCPRange result = mMapData->valueRange(); result.normalize(); @@ -26738,14 +26772,14 @@ QCPRange QCPColorMap::getValueRange(bool &foundRange, QCP::SignDomain inSignDoma } /*! \internal - + Updates the internal map image buffer by going through the internal \ref QCPColorMapData and turning the data values into color pixels with \ref QCPColorGradient::colorize. - + This method is called by \ref QCPColorMap::draw if either the data has been modified or the map image has been invalidated for a different reason (e.g. a change of the data range with \ref setDataRange). - + If the map cell count is low, the image created will be oversampled in order to avoid a QPainter::drawImage bug which makes inner pixel boundaries jitter when stretch-drawing images without smooth transform enabled. Accordingly, oversampling isn't performed if \ref @@ -26756,19 +26790,19 @@ void QCPColorMap::updateMapImage() QCPAxis *keyAxis = mKeyAxis.data(); if (!keyAxis) return; if (mMapData->isEmpty()) return; - + const QImage::Format format = QImage::Format_ARGB32_Premultiplied; const int keySize = mMapData->keySize(); const int valueSize = mMapData->valueSize(); int keyOversamplingFactor = mInterpolate ? 1 : int(1.0+100.0/double(keySize)); // make mMapImage have at least size 100, factor becomes 1 if size > 200 or interpolation is on int valueOversamplingFactor = mInterpolate ? 1 : int(1.0+100.0/double(valueSize)); // make mMapImage have at least size 100, factor becomes 1 if size > 200 or interpolation is on - + // resize mMapImage to correct dimensions including possible oversampling factors, according to key/value axes orientation: if (keyAxis->orientation() == Qt::Horizontal && (mMapImage.width() != keySize*keyOversamplingFactor || mMapImage.height() != valueSize*valueOversamplingFactor)) mMapImage = QImage(QSize(keySize*keyOversamplingFactor, valueSize*valueOversamplingFactor), format); else if (keyAxis->orientation() == Qt::Vertical && (mMapImage.width() != valueSize*valueOversamplingFactor || mMapImage.height() != keySize*keyOversamplingFactor)) mMapImage = QImage(QSize(valueSize*valueOversamplingFactor, keySize*keyOversamplingFactor), format); - + if (mMapImage.isNull()) { qDebug() << Q_FUNC_INFO << "Couldn't create map image (possibly too large for memory)"; @@ -26787,7 +26821,7 @@ void QCPColorMap::updateMapImage() localMapImage = &mUndersampledMapImage; // make the colorization run on the undersampled image } else if (!mUndersampledMapImage.isNull()) mUndersampledMapImage = QImage(); // don't need oversampling mechanism anymore (map size has changed) but mUndersampledMapImage still has nonzero size, free it - + const double *rawData = mMapData->mData; const unsigned char *rawAlpha = mMapData->mAlpha; if (keyAxis->orientation() == Qt::Horizontal) @@ -26815,7 +26849,7 @@ void QCPColorMap::updateMapImage() mGradient.colorize(rawData+line, mDataRange, pixels, rowCount, lineCount, mDataScaleType==QCPAxis::stLogarithmic); } } - + if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) { if (keyAxis->orientation() == Qt::Horizontal) @@ -26834,10 +26868,10 @@ void QCPColorMap::draw(QCPPainter *painter) if (mMapData->isEmpty()) return; if (!mKeyAxis || !mValueAxis) return; applyDefaultAntialiasingHint(painter); - + if (mMapData->mDataModified || mMapImageInvalidated) updateMapImage(); - + // use buffer if painting vectorized (PDF): const bool useBuffer = painter->modes().testFlag(QCPPainter::pmVectorized); QCPPainter *localPainter = painter; // will be redirected to paint on mapBuffer if painting vectorized @@ -26853,7 +26887,7 @@ void QCPColorMap::draw(QCPPainter *painter) localPainter->scale(mapBufferPixelRatio, mapBufferPixelRatio); localPainter->translate(-mapBufferTarget.topLeft()); } - + QRectF imageRect = QRectF(coordsToPixels(mMapData->keyRange().lower, mMapData->valueRange().lower), coordsToPixels(mMapData->keyRange().upper, mMapData->valueRange().upper)).normalized(); // extend imageRect to contain outer halves/quarters of bordering/cornering pixels (cells are centered on map range boundary): @@ -26885,11 +26919,19 @@ void QCPColorMap::draw(QCPPainter *painter) coordsToPixels(mMapData->keyRange().upper, mMapData->valueRange().upper)).normalized(); localPainter->setClipRect(tightClipRect, Qt::IntersectClip); } - localPainter->drawImage(imageRect, mMapImage.mirrored(mirrorX, mirrorY)); + // Qt 6.9.0 depreciated function + //localPainter->drawImage(imageRect, mMapImage.mirrored(mirrorX, mirrorY)); + QImage img = mMapImage; + if (mirrorX) + img = img.flipped(Qt::Horizontal); + if (mirrorY) + img = img.flipped(Qt::Vertical); + localPainter->drawImage(imageRect, img); + // end fix if (mTightBoundary) localPainter->setClipRegion(clipBackup); localPainter->setRenderHint(QPainter::SmoothPixmapTransform, smoothBackup); - + if (useBuffer) // localPainter painted to mapBuffer, so now draw buffer with original painter { delete localPainter; @@ -26928,68 +26970,68 @@ void QCPColorMap::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const /*! \class QCPFinancialData \brief Holds the data of one single data point for QCPFinancial. - + The stored data is: \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey) \li \a open: The opening value at the data point (this is the \a mainValue) \li \a high: The high/maximum value at the data point \li \a low: The low/minimum value at the data point \li \a close: The closing value at the data point - + The container for storing multiple data points is \ref QCPFinancialDataContainer. It is a typedef for \ref QCPDataContainer with \ref QCPFinancialData as the DataType template parameter. See the documentation there for an explanation regarding the data type's generic methods. - + \see QCPFinancialDataContainer */ /* start documentation of inline functions */ /*! \fn double QCPFinancialData::sortKey() const - + Returns the \a key member of this data point. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn static QCPFinancialData QCPFinancialData::fromSortKey(double sortKey) - + Returns a data point with the specified \a sortKey. All other members are set to zero. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn static static bool QCPFinancialData::sortKeyIsMainKey() - + Since the member \a key is both the data point key coordinate and the data ordering parameter, this method returns true. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn double QCPFinancialData::mainKey() const - + Returns the \a key member of this data point. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn double QCPFinancialData::mainValue() const - + Returns the \a open member of this data point. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ /*! \fn QCPRange QCPFinancialData::valueRange() const - + Returns a QCPRange spanning from the \a low to the \a high value of this data point. - + For a general explanation of what this method is good for in the context of the data container, see the documentation of \ref QCPDataContainer. */ @@ -27077,7 +27119,7 @@ QCPFinancialData::QCPFinancialData(double key, double open, double high, double /* start of documentation of inline functions */ /*! \fn QCPFinancialDataContainer *QCPFinancial::data() const - + Returns a pointer to the internal data storage of type \ref QCPFinancialDataContainer. You may use it to directly manipulate the data, which may be more convenient and faster than using the regular \ref setData or \ref addData methods, in certain situations. @@ -27090,7 +27132,7 @@ QCPFinancialData::QCPFinancialData(double key, double open, double high, double axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have the same orientation. If either of these restrictions is violated, a corresponding message is printed to the debug output (qDebug), the construction is not aborted, though. - + The created QCPFinancial is automatically registered with the QCustomPlot instance inferred from \a keyAxis. This QCustomPlot instance takes ownership of the QCPFinancial, so do not delete it manually but use QCustomPlot::removePlottable() instead. @@ -27114,18 +27156,18 @@ QCPFinancial::~QCPFinancial() } /*! \overload - + Replaces the current data container with the provided \a data container. - + Since a QSharedPointer is used, multiple QCPFinancials may share the same data container safely. Modifying the data in the container will then affect all financials that share the container. Sharing can be achieved by simply exchanging the data containers wrapped in shared pointers: \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-datasharing-1 - + If you do not wish to share containers, but create a copy from an existing container, rather use the \ref QCPDataContainer::set method on the financial's data container directly: \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-datasharing-2 - + \see addData, timeSeriesToOhlc */ void QCPFinancial::setData(QSharedPointer data) @@ -27134,14 +27176,14 @@ void QCPFinancial::setData(QSharedPointer data) } /*! \overload - + Replaces the current data with the provided points in \a keys, \a open, \a high, \a low and \a close. The provided vectors should have equal length. Else, the number of added points will be the size of the smallest vector. - + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you can set \a alreadySorted to true, to improve performance by saving a sorting run. - + \see addData, timeSeriesToOhlc */ void QCPFinancial::setData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted) @@ -27160,7 +27202,7 @@ void QCPFinancial::setChartStyle(QCPFinancial::ChartStyle style) /*! Sets the width of the individual bars/candlesticks to \a width in plot key coordinates. - + A typical choice is to set it to (or slightly less than) one bin interval width. */ void QCPFinancial::setWidth(double width) @@ -27184,10 +27226,10 @@ void QCPFinancial::setWidthType(QCPFinancial::WidthType widthType) /*! Sets whether this chart shall contrast positive from negative trends per data point by using two separate colors to draw the respective bars/candlesticks. - + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref setBrush). - + \see setPenPositive, setPenNegative, setBrushPositive, setBrushNegative */ void QCPFinancial::setTwoColored(bool twoColored) @@ -27198,10 +27240,10 @@ void QCPFinancial::setTwoColored(bool twoColored) /*! If \ref setTwoColored is set to true, this function controls the brush that is used to draw fills of data points with a positive trend (i.e. bars/candlesticks with close >= open). - + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref setBrush). - + \see setBrushNegative, setPenPositive, setPenNegative */ void QCPFinancial::setBrushPositive(const QBrush &brush) @@ -27212,10 +27254,10 @@ void QCPFinancial::setBrushPositive(const QBrush &brush) /*! If \ref setTwoColored is set to true, this function controls the brush that is used to draw fills of data points with a negative trend (i.e. bars/candlesticks with close < open). - + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref setBrush). - + \see setBrushPositive, setPenNegative, setPenPositive */ void QCPFinancial::setBrushNegative(const QBrush &brush) @@ -27226,10 +27268,10 @@ void QCPFinancial::setBrushNegative(const QBrush &brush) /*! If \ref setTwoColored is set to true, this function controls the pen that is used to draw outlines of data points with a positive trend (i.e. bars/candlesticks with close >= open). - + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref setBrush). - + \see setPenNegative, setBrushPositive, setBrushNegative */ void QCPFinancial::setPenPositive(const QPen &pen) @@ -27240,10 +27282,10 @@ void QCPFinancial::setPenPositive(const QPen &pen) /*! If \ref setTwoColored is set to true, this function controls the pen that is used to draw outlines of data points with a negative trend (i.e. bars/candlesticks with close < open). - + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref setBrush). - + \see setPenPositive, setBrushNegative, setBrushPositive */ void QCPFinancial::setPenNegative(const QPen &pen) @@ -27252,17 +27294,17 @@ void QCPFinancial::setPenNegative(const QPen &pen) } /*! \overload - + Adds the provided points in \a keys, \a open, \a high, \a low and \a close to the current data. The provided vectors should have equal length. Else, the number of added points will be the size of the smallest vector. - + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you can set \a alreadySorted to true, to improve performance by saving a sorting run. - + Alternatively, you can also access and modify the data directly via the \ref data method, which returns a pointer to the internal data container. - + \see timeSeriesToOhlc */ void QCPFinancial::addData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted) @@ -27288,13 +27330,13 @@ void QCPFinancial::addData(const QVector &keys, const QVector &o } /*! \overload - + Adds the provided data point as \a key, \a open, \a high, \a low and \a close to the current data. - + Alternatively, you can also access and modify the data directly via the \ref data method, which returns a pointer to the internal data container. - + \see timeSeriesToOhlc */ void QCPFinancial::addData(double key, double open, double high, double low, double close) @@ -27312,10 +27354,10 @@ QCPDataSelection QCPFinancial::selectTestRect(const QRectF &rect, bool onlySelec return result; if (!mKeyAxis || !mValueAxis) return result; - + QCPFinancialDataContainer::const_iterator visibleBegin, visibleEnd; getVisibleDataBounds(visibleBegin, visibleEnd); - + for (QCPFinancialDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) { if (rect.intersects(selectionHitBox(it))) @@ -27330,7 +27372,7 @@ QCPDataSelection QCPFinancial::selectTestRect(const QRectF &rect, bool onlySelec If \a details is not 0, it will be set to a \ref QCPDataSelection, describing the closest data point to \a pos. - + \seebaseclassmethod \ref QCPAbstractPlottable::selectTest */ double QCPFinancial::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const @@ -27340,7 +27382,7 @@ double QCPFinancial::selectTest(const QPointF &pos, bool onlySelectable, QVarian return -1; if (!mKeyAxis || !mValueAxis) return -1; - + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()) || mParentPlot->interactions().testFlag(QCP::iSelectPlottablesBeyondAxisRect)) { // get visible data range: @@ -27363,7 +27405,7 @@ double QCPFinancial::selectTest(const QPointF &pos, bool onlySelectable, QVarian } return result; } - + return -1; } @@ -27392,11 +27434,11 @@ QCPRange QCPFinancial::getValueRange(bool &foundRange, QCP::SignDomain inSignDom A convenience function that converts time series data (\a value against \a time) to OHLC binned data points. The return value can then be passed on to \ref QCPFinancialDataContainer::set(const QCPFinancialDataContainer&). - + The size of the bins can be controlled with \a timeBinSize in the same units as \a time is given. For example, if the unit of \a time is seconds and single OHLC/Candlesticks should span an hour each, set \a timeBinSize to 3600. - + \a timeBinOffset allows to control precisely at what \a time coordinate a bin should start. The value passed as \a timeBinOffset doesn't need to be in the range encompassed by the \a time keys. It merely defines the mathematical offset/phase of the bins that will be used to process the @@ -27408,7 +27450,7 @@ QCPFinancialDataContainer QCPFinancial::timeSeriesToOhlc(const QVector & int count = qMin(time.size(), value.size()); if (count == 0) return QCPFinancialDataContainer(); - + QCPFinancialData currentBinData(0, value.first(), value.first(), value.first(), value.first()); int currentBinIndex = qFloor((time.first()-timeBinOffset)/timeBinSize+0.5); for (int i=0; i & currentBinData.low = value.at(i); } } - + return data; } @@ -27447,7 +27489,7 @@ void QCPFinancial::draw(QCPPainter *painter) // get visible data range: QCPFinancialDataContainer::const_iterator visibleBegin, visibleEnd; getVisibleDataBounds(visibleBegin, visibleEnd); - + // loop over and draw segments of unselected/selected data: QList selectedSegments, unselectedSegments, allSegments; getDataSegments(selectedSegments, unselectedSegments); @@ -27460,7 +27502,7 @@ void QCPFinancial::draw(QCPPainter *painter) mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i)); if (begin == end) continue; - + // draw data segment according to configured style: switch (mChartStyle) { @@ -27470,7 +27512,7 @@ void QCPFinancial::draw(QCPPainter *painter) drawCandlestickPlot(painter, begin, end, isSelectedSegment); break; } } - + // draw other selection decoration that isn't just line/scatter pens and brushes: if (mSelectionDecorator) mSelectionDecorator->drawDecoration(painter, selection()); @@ -27536,7 +27578,7 @@ void QCPFinancial::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const } /*! \internal - + Draws the data from \a begin to \a end-1 as OHLC bars with the provided \a painter. This method is a helper function for \ref draw. It is used when the chart style is \ref csOhlc. @@ -27546,7 +27588,7 @@ void QCPFinancial::drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataConta QCPAxis *keyAxis = mKeyAxis.data(); QCPAxis *valueAxis = mValueAxis.data(); if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - + if (keyAxis->orientation() == Qt::Horizontal) { for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) @@ -27593,7 +27635,7 @@ void QCPFinancial::drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataConta } /*! \internal - + Draws the data from \a begin to \a end-1 as Candlesticks with the provided \a painter. This method is a helper function for \ref draw. It is used when the chart style is \ref csCandlestick. @@ -27603,7 +27645,7 @@ void QCPFinancial::drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDa QCPAxis *keyAxis = mKeyAxis.data(); QCPAxis *valueAxis = mValueAxis.data(); if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - + if (keyAxis->orientation() == Qt::Horizontal) { for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) @@ -27714,7 +27756,7 @@ double QCPFinancial::getPixelWidth(double key, double keyPixel) const This method is a helper function for \ref selectTest. It is used to test for selection when the chart style is \ref csOhlc. It only tests against the data points between \a begin and \a end. - + Like \ref selectTest, this method returns the shortest distance of \a pos to the graphical representation of the plottable, and \a closestDataPoint will point to the respective data point. */ @@ -27757,11 +27799,11 @@ double QCPFinancial::ohlcSelectTest(const QPointF &pos, const QCPFinancialDataCo } /*! \internal - + This method is a helper function for \ref selectTest. It is used to test for selection when the chart style is \ref csCandlestick. It only tests against the data points between \a begin and \a end. - + Like \ref selectTest, this method returns the shortest distance of \a pos to the graphical representation of the plottable, and \a closestDataPoint will point to the respective data point. */ @@ -27832,17 +27874,17 @@ double QCPFinancial::candlestickSelectTest(const QPointF &pos, const QCPFinancia } /*! \internal - + called by the drawing methods to determine which data (key) range is visible at the current key axis range setting, so only that needs to be processed. - + \a begin returns an iterator to the lowest data point that needs to be taken into account when plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a begin may still be just outside the visible range. - + \a end returns the iterator just above the highest data point that needs to be taken into account. Same as before, \a end may also lie just outside of the visible range - + if the plottable contains no data, both \a begin and \a end point to \c constEnd. */ void QCPFinancial::getVisibleDataBounds(QCPFinancialDataContainer::const_iterator &begin, QCPFinancialDataContainer::const_iterator &end) const @@ -27868,7 +27910,7 @@ QRectF QCPFinancial::selectionHitBox(QCPFinancialDataContainer::const_iterator i QCPAxis *keyAxis = mKeyAxis.data(); QCPAxis *valueAxis = mValueAxis.data(); if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return {}; } - + double keyPixel = keyAxis->coordToPixel(it->key); double highPixel = valueAxis->coordToPixel(it->high); double lowPixel = valueAxis->coordToPixel(it->low); @@ -28086,7 +28128,7 @@ void QCPErrorBars::setDataPlottable(QCPAbstractPlottable *plottable) qDebug() << Q_FUNC_INFO << "passed plottable doesn't implement 1d interface, can't associate with QCPErrorBars"; return; } - + mDataPlottable = plottable; } @@ -28269,10 +28311,10 @@ QCPDataSelection QCPErrorBars::selectTestRect(const QRectF &rect, bool onlySelec return result; if (!mKeyAxis || !mValueAxis) return result; - + QCPErrorBarsDataContainer::const_iterator visibleBegin, visibleEnd; getVisibleDataBounds(visibleBegin, visibleEnd, QCPDataRange(0, dataCount())); - + QVector backbones, whiskers; for (QCPErrorBarsDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) { @@ -28329,18 +28371,18 @@ int QCPErrorBars::findEnd(double sortKey, bool expandedRange) const If \a details is not 0, it will be set to a \ref QCPDataSelection, describing the closest data point to \a pos. - + \seebaseclassmethod \ref QCPAbstractPlottable::selectTest */ double QCPErrorBars::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const { if (!mDataPlottable) return -1; - + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) return -1; if (!mKeyAxis || !mValueAxis) return -1; - + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()) || mParentPlot->interactions().testFlag(QCP::iSelectPlottablesBeyondAxisRect)) { QCPErrorBarsDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); @@ -28361,11 +28403,11 @@ void QCPErrorBars::draw(QCPPainter *painter) if (!mDataPlottable) return; if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } if (mKeyAxis.data()->range().size() <= 0 || mDataContainer->isEmpty()) return; - + // if the sort key isn't the main key, we must check the visibility for each data point/error bar individually // (getVisibleDataBounds applies range restriction, but otherwise can only return full data range): bool checkPointVisibility = !mDataPlottable->interface1D()->sortKeyIsMainKey(); - + // check data validity if flag set: #ifdef QCUSTOMPLOT_CHECK_DATA QCPErrorBarsDataContainer::const_iterator it; @@ -28375,7 +28417,7 @@ void QCPErrorBars::draw(QCPPainter *painter) qDebug() << Q_FUNC_INFO << "Data point at index" << it-mDataContainer->constBegin() << "invalid." << "Plottable name:" << name(); } #endif - + applyDefaultAntialiasingHint(painter); painter->setBrush(Qt::NoBrush); // loop over and draw segments of unselected/selected data: @@ -28389,7 +28431,7 @@ void QCPErrorBars::draw(QCPPainter *painter) getVisibleDataBounds(begin, end, allSegments.at(i)); if (begin == end) continue; - + bool isSelectedSegment = i >= unselectedSegments.size(); if (isSelectedSegment && mSelectionDecorator) mSelectionDecorator->applyPen(painter); @@ -28411,7 +28453,7 @@ void QCPErrorBars::draw(QCPPainter *painter) painter->drawLines(backbones); painter->drawLines(whiskers); } - + // draw other selection decoration that isn't just line/scatter pens and brushes: if (mSelectionDecorator) mSelectionDecorator->drawDecoration(painter, selection()); @@ -28443,7 +28485,7 @@ QCPRange QCPErrorBars::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomai foundRange = false; return {}; } - + QCPRange range; bool haveLower = false; bool haveUpper = false; @@ -28494,7 +28536,7 @@ QCPRange QCPErrorBars::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomai } } } - + if (haveUpper && !haveLower) { range.lower = range.upper; @@ -28504,7 +28546,7 @@ QCPRange QCPErrorBars::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomai range.upper = range.lower; haveUpper = true; } - + foundRange = haveLower && haveUpper; return range; } @@ -28517,7 +28559,7 @@ QCPRange QCPErrorBars::getValueRange(bool &foundRange, QCP::SignDomain inSignDom foundRange = false; return {}; } - + QCPRange range; const bool restrictKeyRange = inKeyRange != QCPRange(); bool haveLower = false; @@ -28581,7 +28623,7 @@ QCPRange QCPErrorBars::getValueRange(bool &foundRange, QCP::SignDomain inSignDom } } } - + if (haveUpper && !haveLower) { range.lower = range.upper; @@ -28591,7 +28633,7 @@ QCPRange QCPErrorBars::getValueRange(bool &foundRange, QCP::SignDomain inSignDom range.upper = range.lower; haveUpper = true; } - + foundRange = haveLower && haveUpper; return range; } @@ -28610,7 +28652,7 @@ QCPRange QCPErrorBars::getValueRange(bool &foundRange, QCP::SignDomain inSignDom void QCPErrorBars::getErrorBarLines(QCPErrorBarsDataContainer::const_iterator it, QVector &backbones, QVector &whiskers) const { if (!mDataPlottable) return; - + int index = int(it-mDataContainer->constBegin()); QPointF centerPixel = mDataPlottable->interface1D()->dataPixelPosition(index); if (qIsNaN(centerPixel.x()) || qIsNaN(centerPixel.y())) @@ -28704,7 +28746,7 @@ void QCPErrorBars::getVisibleDataBounds(QCPErrorBarsDataContainer::const_iterato end = mDataContainer->constBegin()+dataRange.end(); return; } - + // get visible data range via interface from data plottable, and then restrict to available error data points: const int n = qMin(mDataContainer->size(), mDataPlottable->interface1D()->dataCount()); int beginIndex = mDataPlottable->interface1D()->findBegin(keyAxis->range().lower); @@ -28745,10 +28787,10 @@ double QCPErrorBars::pointDistance(const QPointF &pixelPoint, QCPErrorBarsDataCo qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1.0; } - + QCPErrorBarsDataContainer::const_iterator begin, end; getVisibleDataBounds(begin, end, QCPDataRange(0, dataCount())); - + // calculate minimum distances to error backbones (whiskers are ignored for speed) and find closestData iterator: double minDistSqr = (std::numeric_limits::max)(); QVector backbones, whiskers; @@ -28809,7 +28851,7 @@ bool QCPErrorBars::errorBarVisible(int index) const const double centerKeyPixel = mKeyAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y(); if (qIsNaN(centerKeyPixel)) return false; - + double keyMin, keyMax; if (mErrorType == etKeyError) { @@ -28866,7 +28908,7 @@ bool QCPErrorBars::rectIntersectsLine(const QRectF &pixelRect, const QLineF &lin /*! Creates a straight line item and sets default values. - + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. */ @@ -28877,7 +28919,7 @@ QCPItemStraightLine::QCPItemStraightLine(QCustomPlot *parentPlot) : { point1->setCoords(0, 0); point2->setCoords(1, 1); - + setPen(QPen(Qt::black)); setSelectedPen(QPen(Qt::blue,2)); } @@ -28888,7 +28930,7 @@ QCPItemStraightLine::~QCPItemStraightLine() /*! Sets the pen that will be used to draw the line - + \see setSelectedPen */ void QCPItemStraightLine::setPen(const QPen &pen) @@ -28898,7 +28940,7 @@ void QCPItemStraightLine::setPen(const QPen &pen) /*! Sets the pen that will be used to draw the line when selected - + \see setPen, setSelected */ void QCPItemStraightLine::setSelectedPen(const QPen &pen) @@ -28912,7 +28954,7 @@ double QCPItemStraightLine::selectTest(const QPointF &pos, bool onlySelectable, Q_UNUSED(details) if (onlySelectable && !mSelectable) return -1; - + return QCPVector2D(pos).distanceToStraightLine(point1->pixelPosition(), point2->pixelPosition()-point1->pixelPosition()); } @@ -28936,7 +28978,7 @@ void QCPItemStraightLine::draw(QCPPainter *painter) Returns the section of the straight line defined by \a base and direction vector \a vec, that is visible in the specified \a rect. - + This is a helper function for \ref draw. */ QLineF QCPItemStraightLine::getRectClippedStraightLine(const QCPVector2D &base, const QCPVector2D &vec, const QRect &rect) const @@ -28989,7 +29031,7 @@ QLineF QCPItemStraightLine::getRectClippedStraightLine(const QCPVector2D &base, gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); if (gamma >= 0 && gamma <= rect.height()) pointVectors.append(QCPVector2D(bx, by+gamma)); - + // evaluate points: if (pointVectors.size() == 2) { @@ -29043,13 +29085,13 @@ QPen QCPItemStraightLine::mainPen() const \image html QCPItemLine.png "Line example. Blue dotted circles are anchors, solid blue discs are positions." It has two positions, \a start and \a end, which define the end points of the line. - + With \ref setHead and \ref setTail you may set different line ending styles, e.g. to create an arrow. */ /*! Creates a line item and sets default values. - + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. */ @@ -29060,7 +29102,7 @@ QCPItemLine::QCPItemLine(QCustomPlot *parentPlot) : { start->setCoords(0, 0); end->setCoords(1, 1); - + setPen(QPen(Qt::black)); setSelectedPen(QPen(Qt::blue,2)); } @@ -29071,7 +29113,7 @@ QCPItemLine::~QCPItemLine() /*! Sets the pen that will be used to draw the line - + \see setSelectedPen */ void QCPItemLine::setPen(const QPen &pen) @@ -29081,7 +29123,7 @@ void QCPItemLine::setPen(const QPen &pen) /*! Sets the pen that will be used to draw the line when selected - + \see setPen, setSelected */ void QCPItemLine::setSelectedPen(const QPen &pen) @@ -29091,10 +29133,10 @@ void QCPItemLine::setSelectedPen(const QPen &pen) /*! Sets the line ending style of the head. The head corresponds to the \a end position. - + Note that due to the overloaded QCPLineEnding constructor, you may directly specify a QCPLineEnding::EndingStyle here, e.g. \code setHead(QCPLineEnding::esSpikeArrow) \endcode - + \see setTail */ void QCPItemLine::setHead(const QCPLineEnding &head) @@ -29104,10 +29146,10 @@ void QCPItemLine::setHead(const QCPLineEnding &head) /*! Sets the line ending style of the tail. The tail corresponds to the \a start position. - + Note that due to the overloaded QCPLineEnding constructor, you may directly specify a QCPLineEnding::EndingStyle here, e.g. \code setTail(QCPLineEnding::esSpikeArrow) \endcode - + \see setHead */ void QCPItemLine::setTail(const QCPLineEnding &tail) @@ -29121,7 +29163,7 @@ double QCPItemLine::selectTest(const QPointF &pos, bool onlySelectable, QVariant Q_UNUSED(details) if (onlySelectable && !mSelectable) return -1; - + return qSqrt(QCPVector2D(pos).distanceSquaredToLine(start->pixelPosition(), end->pixelPosition())); } @@ -29153,7 +29195,7 @@ void QCPItemLine::draw(QCPPainter *painter) Returns the section of the line defined by \a start and \a end, that is visible in the specified \a rect. - + This is a helper function for \ref draw. */ QLineF QCPItemLine::getRectClippedLine(const QCPVector2D &start, const QCPVector2D &end, const QRect &rect) const @@ -29162,7 +29204,7 @@ QLineF QCPItemLine::getRectClippedLine(const QCPVector2D &start, const QCPVector bool containsEnd = rect.contains(qRound(end.x()), qRound(end.y())); if (containsStart && containsEnd) return {start.toPointF(), end.toPointF()}; - + QCPVector2D base = start; QCPVector2D vec = end-start; double bx, by; @@ -29216,12 +29258,12 @@ QLineF QCPItemLine::getRectClippedLine(const QCPVector2D &start, const QCPVector pointVectors.append(QCPVector2D(bx, by+gamma)); } } - + if (containsStart) pointVectors.append(start); if (containsEnd) pointVectors.append(end); - + // evaluate points: if (pointVectors.size() == 2) { @@ -29276,10 +29318,10 @@ QPen QCPItemLine::mainPen() const It has four positions, \a start and \a end, which define the end points of the line, and two control points which define the direction the line exits from the start and the direction from which it approaches the end: \a startDir and \a endDir. - + With \ref setHead and \ref setTail you may set different line ending styles, e.g. to create an arrow. - + Often it is desirable for the control points to stay at fixed relative positions to the start/end point. This can be achieved by setting the parent anchor e.g. of \a startDir simply to \a start, and then specify the desired pixel offset with QCPItemPosition::setCoords on \a startDir. @@ -29287,7 +29329,7 @@ QPen QCPItemLine::mainPen() const /*! Creates a curve item and sets default values. - + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. */ @@ -29302,7 +29344,7 @@ QCPItemCurve::QCPItemCurve(QCustomPlot *parentPlot) : startDir->setCoords(0.5, 0); endDir->setCoords(0, 0.5); end->setCoords(1, 1); - + setPen(QPen(Qt::black)); setSelectedPen(QPen(Qt::blue,2)); } @@ -29313,7 +29355,7 @@ QCPItemCurve::~QCPItemCurve() /*! Sets the pen that will be used to draw the line - + \see setSelectedPen */ void QCPItemCurve::setPen(const QPen &pen) @@ -29323,7 +29365,7 @@ void QCPItemCurve::setPen(const QPen &pen) /*! Sets the pen that will be used to draw the line when selected - + \see setPen, setSelected */ void QCPItemCurve::setSelectedPen(const QPen &pen) @@ -29333,10 +29375,10 @@ void QCPItemCurve::setSelectedPen(const QPen &pen) /*! Sets the line ending style of the head. The head corresponds to the \a end position. - + Note that due to the overloaded QCPLineEnding constructor, you may directly specify a QCPLineEnding::EndingStyle here, e.g. \code setHead(QCPLineEnding::esSpikeArrow) \endcode - + \see setTail */ void QCPItemCurve::setHead(const QCPLineEnding &head) @@ -29346,10 +29388,10 @@ void QCPItemCurve::setHead(const QCPLineEnding &head) /*! Sets the line ending style of the tail. The tail corresponds to the \a start position. - + Note that due to the overloaded QCPLineEnding constructor, you may directly specify a QCPLineEnding::EndingStyle here, e.g. \code setTail(QCPLineEnding::esSpikeArrow) \endcode - + \see setHead */ void QCPItemCurve::setTail(const QCPLineEnding &tail) @@ -29363,7 +29405,7 @@ double QCPItemCurve::selectTest(const QPointF &pos, bool onlySelectable, QVarian Q_UNUSED(details) if (onlySelectable && !mSelectable) return -1; - + QPointF startVec(start->pixelPosition()); QPointF startDirVec(startDir->pixelPosition()); QPointF endDirVec(endDir->pixelPosition()); @@ -29371,7 +29413,7 @@ double QCPItemCurve::selectTest(const QPointF &pos, bool onlySelectable, QVarian QPainterPath cubicPath(startVec); cubicPath.cubicTo(startDirVec, endDirVec, endVec); - + QList polygons = cubicPath.toSubpathPolygons(); if (polygons.isEmpty()) return -1; @@ -29447,7 +29489,7 @@ QPen QCPItemCurve::mainPen() const /*! Creates a rectangle item and sets default values. - + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. */ @@ -29464,7 +29506,7 @@ QCPItemRect::QCPItemRect(QCustomPlot *parentPlot) : { topLeft->setCoords(0, 1); bottomRight->setCoords(1, 0); - + setPen(QPen(Qt::black)); setSelectedPen(QPen(Qt::blue,2)); setBrush(Qt::NoBrush); @@ -29477,7 +29519,7 @@ QCPItemRect::~QCPItemRect() /*! Sets the pen that will be used to draw the line of the rectangle - + \see setSelectedPen, setBrush */ void QCPItemRect::setPen(const QPen &pen) @@ -29487,7 +29529,7 @@ void QCPItemRect::setPen(const QPen &pen) /*! Sets the pen that will be used to draw the line of the rectangle when selected - + \see setPen, setSelected */ void QCPItemRect::setSelectedPen(const QPen &pen) @@ -29498,7 +29540,7 @@ void QCPItemRect::setSelectedPen(const QPen &pen) /*! Sets the brush that will be used to fill the rectangle. To disable filling, set \a brush to Qt::NoBrush. - + \see setSelectedBrush, setPen */ void QCPItemRect::setBrush(const QBrush &brush) @@ -29509,7 +29551,7 @@ void QCPItemRect::setBrush(const QBrush &brush) /*! Sets the brush that will be used to fill the rectangle when selected. To disable filling, set \a brush to Qt::NoBrush. - + \see setBrush */ void QCPItemRect::setSelectedBrush(const QBrush &brush) @@ -29523,7 +29565,7 @@ double QCPItemRect::selectTest(const QPointF &pos, bool onlySelectable, QVariant Q_UNUSED(details) if (onlySelectable && !mSelectable) return -1; - + QRectF rect = QRectF(topLeft->pixelPosition(), bottomRight->pixelPosition()).normalized(); bool filledRect = mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0; return rectDistance(rect, pos, filledRect); @@ -29560,7 +29602,7 @@ QPointF QCPItemRect::anchorPixelPosition(int anchorId) const case aiBottomLeft: return rect.bottomLeft(); case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5; } - + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; return {}; } @@ -29601,16 +29643,16 @@ QBrush QCPItemRect::mainBrush() const Its position is defined by the member \a position and the setting of \ref setPositionAlignment. The latter controls which part of the text rect shall be aligned with \a position. - + The text alignment itself (i.e. left, center, right) can be controlled with \ref setTextAlignment. - + The text may be rotated around the \a position point with \ref setRotation. */ /*! Creates a text item and sets default values. - + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. */ @@ -29631,7 +29673,7 @@ QCPItemText::QCPItemText(QCustomPlot *parentPlot) : mRotation(0) { position->setCoords(0, 0); - + setPen(Qt::NoPen); setSelectedPen(Qt::NoPen); setBrush(Qt::NoBrush); @@ -29663,7 +29705,7 @@ void QCPItemText::setSelectedColor(const QColor &color) /*! Sets the pen that will be used do draw a rectangular border around the text. To disable the border, set \a pen to Qt::NoPen. - + \see setSelectedPen, setBrush, setPadding */ void QCPItemText::setPen(const QPen &pen) @@ -29674,7 +29716,7 @@ void QCPItemText::setPen(const QPen &pen) /*! Sets the pen that will be used do draw a rectangular border around the text, when the item is selected. To disable the border, set \a pen to Qt::NoPen. - + \see setPen */ void QCPItemText::setSelectedPen(const QPen &pen) @@ -29685,7 +29727,7 @@ void QCPItemText::setSelectedPen(const QPen &pen) /*! Sets the brush that will be used do fill the background of the text. To disable the background, set \a brush to Qt::NoBrush. - + \see setSelectedBrush, setPen, setPadding */ void QCPItemText::setBrush(const QBrush &brush) @@ -29696,7 +29738,7 @@ void QCPItemText::setBrush(const QBrush &brush) /*! Sets the brush that will be used do fill the background of the text, when the item is selected. To disable the background, set \a brush to Qt::NoBrush. - + \see setBrush */ void QCPItemText::setSelectedBrush(const QBrush &brush) @@ -29706,7 +29748,7 @@ void QCPItemText::setSelectedBrush(const QBrush &brush) /*! Sets the font of the text. - + \see setSelectedFont, setColor */ void QCPItemText::setFont(const QFont &font) @@ -29716,7 +29758,7 @@ void QCPItemText::setFont(const QFont &font) /*! Sets the font of the text that will be used when the item is selected. - + \see setFont */ void QCPItemText::setSelectedFont(const QFont &font) @@ -29727,7 +29769,7 @@ void QCPItemText::setSelectedFont(const QFont &font) /*! Sets the text that will be displayed. Multi-line texts are supported by inserting a line break character, e.g. '\n'. - + \see setFont, setColor, setTextAlignment */ void QCPItemText::setText(const QString &text) @@ -29737,13 +29779,13 @@ void QCPItemText::setText(const QString &text) /*! Sets which point of the text rect shall be aligned with \a position. - + Examples: \li If \a alignment is Qt::AlignHCenter | Qt::AlignTop, the text will be positioned such that the top of the text rect will be horizontally centered on \a position. \li If \a alignment is Qt::AlignLeft | Qt::AlignBottom, \a position will indicate the bottom left corner of the text rect. - + If you want to control the alignment of (multi-lined) text within the text rect, use \ref setTextAlignment. */ @@ -29784,7 +29826,7 @@ double QCPItemText::selectTest(const QPointF &pos, bool onlySelectable, QVariant Q_UNUSED(details) if (onlySelectable && !mSelectable) return -1; - + // The rect may be rotated, so we transform the actual clicked pos to the rotated // coordinate system, so we can use the normal rectDistance function for non-rotated rects: QPointF positionPixels(position->pixelPosition()); @@ -29849,7 +29891,7 @@ QPointF QCPItemText::anchorPixelPosition(int anchorId) const QPointF textPos = getTextDrawPoint(QPointF(0, 0), textBoxRect, mPositionAlignment); // 0, 0 because the transform does the translation textBoxRect.moveTopLeft(textPos.toPoint()); QPolygonF rectPoly = transform.map(QPolygonF(textBoxRect)); - + switch (anchorId) { case aiTopLeft: return rectPoly.at(0); @@ -29861,17 +29903,17 @@ QPointF QCPItemText::anchorPixelPosition(int anchorId) const case aiBottomLeft: return rectPoly.at(3); case aiLeft: return (rectPoly.at(3)+rectPoly.at(0))*0.5; } - + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; return {}; } /*! \internal - + Returns the point that must be given to the QPainter::drawText function (which expects the top left point of the text rect), according to the position \a pos, the text bounding box \a rect and the requested \a positionAlignment. - + For example, if \a positionAlignment is Qt::AlignLeft | Qt::AlignBottom the returned point will be shifted upward by the height of \a rect, starting from \a pos. So if the text is finally drawn at that point, the lower left corner of the resulting text rect is at \a pos. @@ -29880,7 +29922,7 @@ QPointF QCPItemText::getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt { if (positionAlignment == 0 || positionAlignment == (Qt::AlignLeft|Qt::AlignTop)) return pos; - + QPointF result = pos; // start at top left if (positionAlignment.testFlag(Qt::AlignHCenter)) result.rx() -= rect.width()/2.0; @@ -29952,7 +29994,7 @@ QBrush QCPItemText::mainBrush() const /*! Creates an ellipse item and sets default values. - + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. */ @@ -29972,7 +30014,7 @@ QCPItemEllipse::QCPItemEllipse(QCustomPlot *parentPlot) : { topLeft->setCoords(0, 1); bottomRight->setCoords(1, 0); - + setPen(QPen(Qt::black)); setSelectedPen(QPen(Qt::blue, 2)); setBrush(Qt::NoBrush); @@ -29985,7 +30027,7 @@ QCPItemEllipse::~QCPItemEllipse() /*! Sets the pen that will be used to draw the line of the ellipse - + \see setSelectedPen, setBrush */ void QCPItemEllipse::setPen(const QPen &pen) @@ -29995,7 +30037,7 @@ void QCPItemEllipse::setPen(const QPen &pen) /*! Sets the pen that will be used to draw the line of the ellipse when selected - + \see setPen, setSelected */ void QCPItemEllipse::setSelectedPen(const QPen &pen) @@ -30006,7 +30048,7 @@ void QCPItemEllipse::setSelectedPen(const QPen &pen) /*! Sets the brush that will be used to fill the ellipse. To disable filling, set \a brush to Qt::NoBrush. - + \see setSelectedBrush, setPen */ void QCPItemEllipse::setBrush(const QBrush &brush) @@ -30017,7 +30059,7 @@ void QCPItemEllipse::setBrush(const QBrush &brush) /*! Sets the brush that will be used to fill the ellipse when selected. To disable filling, set \a brush to Qt::NoBrush. - + \see setBrush */ void QCPItemEllipse::setSelectedBrush(const QBrush &brush) @@ -30031,7 +30073,7 @@ double QCPItemEllipse::selectTest(const QPointF &pos, bool onlySelectable, QVari Q_UNUSED(details) if (onlySelectable && !mSelectable) return -1; - + QPointF p1 = topLeft->pixelPosition(); QPointF p2 = bottomRight->pixelPosition(); QPointF center((p1+p2)/2.0); @@ -30039,7 +30081,7 @@ double QCPItemEllipse::selectTest(const QPointF &pos, bool onlySelectable, QVari double b = qAbs(p1.y()-p2.y())/2.0; double x = pos.x()-center.x(); double y = pos.y()-center.y(); - + // distance to border: double c = 1.0/qSqrt(x*x/(a*a)+y*y/(b*b)); double result = qAbs(c-1)*qSqrt(x*x+y*y); @@ -30097,7 +30139,7 @@ QPointF QCPItemEllipse::anchorPixelPosition(int anchorId) const case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5; case aiCenter: return (rect.topLeft()+rect.bottomRight())*0.5; } - + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; return {}; } @@ -30139,7 +30181,7 @@ QBrush QCPItemEllipse::mainBrush() const It has two positions, \a topLeft and \a bottomRight, which define the rectangle the pixmap will be drawn in. Depending on the scale setting (\ref setScaled), the pixmap will be either scaled to fit the rectangle or be drawn aligned to the topLeft position. - + If scaling is enabled and \a topLeft is further to the bottom/right than \a bottomRight (as shown on the right side of the example image), the pixmap will be flipped in the respective orientations. @@ -30147,7 +30189,7 @@ QBrush QCPItemEllipse::mainBrush() const /*! Creates a rectangle item and sets default values. - + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. */ @@ -30168,7 +30210,7 @@ QCPItemPixmap::QCPItemPixmap(QCustomPlot *parentPlot) : { topLeft->setCoords(0, 1); bottomRight->setCoords(1, 0); - + setPen(Qt::NoPen); setSelectedPen(QPen(Qt::blue)); } @@ -30202,7 +30244,7 @@ void QCPItemPixmap::setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode, /*! Sets the pen that will be used to draw a border around the pixmap. - + \see setSelectedPen, setBrush */ void QCPItemPixmap::setPen(const QPen &pen) @@ -30212,7 +30254,7 @@ void QCPItemPixmap::setPen(const QPen &pen) /*! Sets the pen that will be used to draw a border around the pixmap when selected - + \see setPen, setSelected */ void QCPItemPixmap::setSelectedPen(const QPen &pen) @@ -30226,7 +30268,7 @@ double QCPItemPixmap::selectTest(const QPointF &pos, bool onlySelectable, QVaria Q_UNUSED(details) if (onlySelectable && !mSelectable) return -1; - + return rectDistance(getFinalRect(), pos, true); } @@ -30264,7 +30306,7 @@ QPointF QCPItemPixmap::anchorPixelPosition(int anchorId) const rect.adjust(rect.width(), 0, -rect.width(), 0); if (flipVert) rect.adjust(0, rect.height(), 0, -rect.height()); - + switch (anchorId) { case aiTop: return (rect.topLeft()+rect.topRight())*0.5; @@ -30274,29 +30316,29 @@ QPointF QCPItemPixmap::anchorPixelPosition(int anchorId) const case aiBottomLeft: return rect.bottomLeft(); case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5; } - + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; return {}; } /*! \internal - + Creates the buffered scaled image (\a mScaledPixmap) to fit the specified \a finalRect. The parameters \a flipHorz and \a flipVert control whether the resulting image shall be flipped horizontally or vertically. (This is used when \a topLeft is further to the bottom/right than \a bottomRight.) - + This function only creates the scaled pixmap when the buffered pixmap has a different size than the expected result, so calling this function repeatedly, e.g. in the \ref draw function, does not cause expensive rescaling every time. - + If scaling is disabled, sets mScaledPixmap to a null QPixmap. */ void QCPItemPixmap::updateScaledPixmap(QRect finalRect, bool flipHorz, bool flipVert) { if (mPixmap.isNull()) return; - + if (mScaled) { #ifdef QCP_DEVICEPIXELRATIO_SUPPORTED @@ -30309,8 +30351,18 @@ void QCPItemPixmap::updateScaledPixmap(QRect finalRect, bool flipHorz, bool flip if (mScaledPixmapInvalidated || finalRect.size() != mScaledPixmap.size()/devicePixelRatio) { mScaledPixmap = mPixmap.scaled(finalRect.size()*devicePixelRatio, mAspectRatioMode, mTransformationMode); - if (flipHorz || flipVert) - mScaledPixmap = QPixmap::fromImage(mScaledPixmap.toImage().mirrored(flipHorz, flipVert)); + // Qt 6.9.0 depreciated function + // if (flipHorz || flipVert) + // mScaledPixmap = QPixmap::fromImage(mScaledPixmap.toImage().mirrored(flipHorz, flipVert)); + if (flipHorz || flipVert) { + QImage img = mScaledPixmap.toImage(); + if (flipHorz) + img = img.flipped(Qt::Horizontal); + if (flipVert) + img = img.flipped(Qt::Vertical); + mScaledPixmap = QPixmap::fromImage(img); + } + // end fix #ifdef QCP_DEVICEPIXELRATIO_SUPPORTED mScaledPixmap.setDevicePixelRatio(devicePixelRatio); #endif @@ -30321,16 +30373,16 @@ void QCPItemPixmap::updateScaledPixmap(QRect finalRect, bool flipHorz, bool flip } /*! \internal - + Returns the final (tight) rect the pixmap is drawn in, depending on the current item positions and scaling settings. - + The output parameters \a flippedHorz and \a flippedVert return whether the pixmap should be drawn flipped horizontally or vertically in the returned rect. (The returned rect itself is always normalized, i.e. the top left corner of the rect is actually further to the top/left than the bottom right corner). This is the case when the item position \a topLeft is further to the bottom/right than \a bottomRight. - + If scaling is disabled, returns a rect with size of the original pixmap and the top left corner aligned with the item position \a topLeft. The position \a bottomRight is ignored. */ @@ -30412,19 +30464,19 @@ QPen QCPItemPixmap::mainPen() const QCPGraph is connected, note that setting the coordinates of the tracer item directly via \a position will have no effect because they will be overriden in the next redraw (this is when the coordinate update happens). - + If the specified key in \ref setGraphKey is outside the key bounds of the graph, the tracer will stay at the corresponding end of the graph. - + With \ref setInterpolating you may specify whether the tracer may only stay exactly on data points or whether it interpolates data points linearly, if given a key that lies between two data points of the graph. - + The tracer has different visual styles, see \ref setStyle. It is also possible to make the tracer have no own visual appearance (set the style to \ref tsNone), and just connect other item positions to the tracer \a position (used as an anchor) via \ref QCPItemPosition::setParentAnchor. - + \note The tracer position is only automatically updated upon redraws. So when the data of the graph changes and immediately afterwards (without a redraw) the position coordinates of the tracer are retrieved, they will not reflect the updated data of the graph. In this case \ref @@ -30433,7 +30485,7 @@ QPen QCPItemPixmap::mainPen() const /*! Creates a tracer item and sets default values. - + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. */ @@ -30460,7 +30512,7 @@ QCPItemTracer::~QCPItemTracer() /*! Sets the pen that will be used to draw the line of the tracer - + \see setSelectedPen, setBrush */ void QCPItemTracer::setPen(const QPen &pen) @@ -30470,7 +30522,7 @@ void QCPItemTracer::setPen(const QPen &pen) /*! Sets the pen that will be used to draw the line of the tracer when selected - + \see setPen, setSelected */ void QCPItemTracer::setSelectedPen(const QPen &pen) @@ -30480,7 +30532,7 @@ void QCPItemTracer::setSelectedPen(const QPen &pen) /*! Sets the brush that will be used to draw any fills of the tracer - + \see setSelectedBrush, setPen */ void QCPItemTracer::setBrush(const QBrush &brush) @@ -30490,7 +30542,7 @@ void QCPItemTracer::setBrush(const QBrush &brush) /*! Sets the brush that will be used to draw any fills of the tracer, when selected. - + \see setBrush, setSelected */ void QCPItemTracer::setSelectedBrush(const QBrush &brush) @@ -30509,7 +30561,7 @@ void QCPItemTracer::setSize(double size) /*! Sets the style/visual appearance of the tracer. - + If you only want to use the tracer \a position as an anchor for other items, set \a style to \ref tsNone. */ @@ -30521,11 +30573,11 @@ void QCPItemTracer::setStyle(QCPItemTracer::TracerStyle style) /*! Sets the QCPGraph this tracer sticks to. The tracer \a position will be set to type QCPItemPosition::ptPlotCoords and the axes will be set to the axes of \a graph. - + To free the tracer from any graph, set \a graph to \c nullptr. The tracer \a position can then be placed freely like any other item position. This is the state the tracer will assume when its graph gets deleted while still attached to it. - + \see setGraphKey */ void QCPItemTracer::setGraph(QCPGraph *graph) @@ -30549,10 +30601,10 @@ void QCPItemTracer::setGraph(QCPGraph *graph) /*! Sets the key of the graph's data point the tracer will be positioned at. This is the only free coordinate of a tracer when attached to a graph. - + Depending on \ref setInterpolating, the tracer will be either positioned on the data point closest to \a key, or will stay exactly at \a key and interpolate the value linearly. - + \see setGraph, setInterpolating */ void QCPItemTracer::setGraphKey(double key) @@ -30563,12 +30615,12 @@ void QCPItemTracer::setGraphKey(double key) /*! Sets whether the value of the graph's data points shall be interpolated, when positioning the tracer. - + If \a enabled is set to false and a key is given with \ref setGraphKey, the tracer is placed on the data point of the graph which is closest to the key, but which is not necessarily exactly there. If \a enabled is true, the tracer will be positioned exactly at the specified key, and the appropriate value will be interpolated from the graph's data points linearly. - + \see setGraph, setGraphKey */ void QCPItemTracer::setInterpolating(bool enabled) @@ -30683,13 +30735,13 @@ void QCPItemTracer::draw(QCPPainter *painter) /*! If the tracer is connected with a graph (\ref setGraph), this function updates the tracer's \a position to reside on the graph data, depending on the configured key (\ref setGraphKey). - + It is called automatically on every redraw and normally doesn't need to be called manually. One exception is when you want to read the tracer coordinates via \a position and are not sure that the graph's data (or the tracer key with \ref setGraphKey) hasn't changed since the last redraw. In that situation, call this function before accessing \a position, to make sure you don't get out-of-date coordinates. - + If there is no graph set on this tracer, this function does nothing. */ void QCPItemTracer::updatePosition() @@ -30779,21 +30831,21 @@ QBrush QCPItemTracer::mainBrush() const It has two positions, \a left and \a right, which define the span of the bracket. If \a left is actually farther to the left than \a right, the bracket is opened to the bottom, as shown in the example image. - + The bracket supports multiple styles via \ref setStyle. The length, i.e. how far the bracket stretches away from the embraced span, can be controlled with \ref setLength. - + \image html QCPItemBracket-length.png
Demonstrating the effect of different values for \ref setLength, for styles \ref bsCalligraphic and \ref bsSquare. Anchors and positions are displayed for reference.
- + It provides an anchor \a center, to allow connection of other items, e.g. an arrow (QCPItemLine or QCPItemCurve) or a text label (QCPItemText), to the bracket. */ /*! Creates a bracket item and sets default values. - + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. */ @@ -30807,7 +30859,7 @@ QCPItemBracket::QCPItemBracket(QCustomPlot *parentPlot) : { left->setCoords(0, 0); right->setCoords(1, 1); - + setPen(QPen(Qt::black)); setSelectedPen(QPen(Qt::blue, 2)); } @@ -30818,11 +30870,11 @@ QCPItemBracket::~QCPItemBracket() /*! Sets the pen that will be used to draw the bracket. - + Note that when the style is \ref bsCalligraphic, only the color will be taken from the pen, the stroke and width are ignored. To change the apparent stroke width of a calligraphic bracket, use \ref setLength, which has a similar effect. - + \see setSelectedPen */ void QCPItemBracket::setPen(const QPen &pen) @@ -30832,7 +30884,7 @@ void QCPItemBracket::setPen(const QPen &pen) /*! Sets the pen that will be used to draw the bracket when selected - + \see setPen, setSelected */ void QCPItemBracket::setSelectedPen(const QPen &pen) @@ -30843,7 +30895,7 @@ void QCPItemBracket::setSelectedPen(const QPen &pen) /*! Sets the \a length in pixels how far the bracket extends in the direction towards the embraced span of the bracket (i.e. perpendicular to the left-right-direction) - + \image html QCPItemBracket-length.png
Demonstrating the effect of different values for \ref setLength, for styles \ref bsCalligraphic and \ref bsSquare. Anchors and positions are displayed for reference.
@@ -30855,7 +30907,7 @@ void QCPItemBracket::setLength(double length) /*! Sets the style of the bracket, i.e. the shape/visual appearance. - + \see setPen */ void QCPItemBracket::setStyle(QCPItemBracket::BracketStyle style) @@ -30869,17 +30921,17 @@ double QCPItemBracket::selectTest(const QPointF &pos, bool onlySelectable, QVari Q_UNUSED(details) if (onlySelectable && !mSelectable) return -1; - + QCPVector2D p(pos); QCPVector2D leftVec(left->pixelPosition()); QCPVector2D rightVec(right->pixelPosition()); if (leftVec.toPoint() == rightVec.toPoint()) return -1; - + QCPVector2D widthVec = (rightVec-leftVec)*0.5; QCPVector2D lengthVec = widthVec.perpendicular().normalized()*mLength; QCPVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; - + switch (mStyle) { case QCPItemBracket::bsSquare: @@ -30910,7 +30962,7 @@ void QCPItemBracket::draw(QCPPainter *painter) QCPVector2D rightVec(right->pixelPosition()); if (leftVec.toPoint() == rightVec.toPoint()) return; - + QCPVector2D widthVec = (rightVec-leftVec)*0.5; QCPVector2D lengthVec = widthVec.perpendicular().normalized()*mLength; QCPVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; @@ -30958,13 +31010,13 @@ void QCPItemBracket::draw(QCPPainter *painter) painter->setBrush(QBrush(mainPen().color())); QPainterPath path; path.moveTo((centerVec+widthVec+lengthVec).toPointF()); - + path.cubicTo((centerVec+widthVec-lengthVec*0.8).toPointF(), (centerVec+0.4*widthVec+0.8*lengthVec).toPointF(), centerVec.toPointF()); path.cubicTo((centerVec-0.4*widthVec+0.8*lengthVec).toPointF(), (centerVec-widthVec-lengthVec*0.8).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); - + path.cubicTo((centerVec-widthVec-lengthVec*0.5).toPointF(), (centerVec-0.2*widthVec+1.2*lengthVec).toPointF(), (centerVec+lengthVec*0.2).toPointF()); path.cubicTo((centerVec+0.2*widthVec+1.2*lengthVec).toPointF(), (centerVec+widthVec-lengthVec*0.5).toPointF(), (centerVec+widthVec+lengthVec).toPointF()); - + painter->drawPath(path); break; } @@ -30979,11 +31031,11 @@ QPointF QCPItemBracket::anchorPixelPosition(int anchorId) const QCPVector2D rightVec(right->pixelPosition()); if (leftVec.toPoint() == rightVec.toPoint()) return leftVec.toPointF(); - + QCPVector2D widthVec = (rightVec-leftVec)*0.5; QCPVector2D lengthVec = widthVec.perpendicular().normalized()*mLength; QCPVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; - + switch (anchorId) { case aiCenter: @@ -31016,10 +31068,10 @@ QPen QCPItemBracket::mainPen() const /*! \class QCPPolarAxisRadial \brief The radial axis inside a radial plot - + \warning In this QCustomPlot version, polar plots are a tech preview. Expect documentation and functionality to be incomplete, as well as changing public interfaces in the future. - + Each axis holds an instance of QCPAxisTicker which is used to generate the tick coordinates and tick labels. You can access the currently installed \ref ticker or set a new one (possibly one of the specialized subclasses, or your own subclass) via \ref setTicker. For details, see the @@ -31052,7 +31104,7 @@ QPen QCPItemBracket::mainPen() const This signal is emitted when the range of this axis has changed. You can connect it to the \ref setRange slot of another axis to communicate the new range to the other axis, in order for it to be synchronized. - + You may also manipulate/correct the range with \ref setRange in a slot connected to this signal. This is useful if for example a maximum range span shall not be exceeded, or if the lower/upper range shouldn't go beyond certain values (see \ref QCPRange::bounded). For example, the following @@ -31064,24 +31116,24 @@ QPen QCPItemBracket::mainPen() const /*! \fn void QCPPolarAxisRadial::rangeChanged(const QCPRange &newRange, const QCPRange &oldRange) \overload - + Additionally to the new range, this signal also provides the previous range held by the axis as \a oldRange. */ /*! \fn void QCPPolarAxisRadial::scaleTypeChanged(QCPPolarAxisRadial::ScaleType scaleType); - + This signal is emitted when the scale type changes, by calls to \ref setScaleType */ /*! \fn void QCPPolarAxisRadial::selectionChanged(QCPPolarAxisRadial::SelectableParts selection) - + This signal is emitted when the selection state of this axis has changed, either by user interaction or by a direct call to \ref setSelectedParts. */ /*! \fn void QCPPolarAxisRadial::selectableChanged(const QCPPolarAxisRadial::SelectableParts &parts); - + This signal is emitted when the selectability changes, by calls to \ref setSelectableParts */ @@ -31089,7 +31141,7 @@ QPen QCPItemBracket::mainPen() const /*! Constructs an Axis instance of Type \a type for the axis rect \a parent. - + Usually it isn't necessary to instantiate axes directly, because you can let QCustomPlot create them for you with \ref QCPAxisRect::addAxis. If you want to use own QCPAxis-subclasses however, create them manually and then inject them also via \ref QCPAxisRect::addAxis. @@ -31148,7 +31200,7 @@ QCPPolarAxisRadial::QCPPolarAxisRadial(QCPPolarAxisAngular *parent) : { setParent(parent); setAntialiased(true); - + setTickLabelPadding(5); setTickLabelRotation(0); setTickLabelMode(lmUpright); @@ -31232,16 +31284,16 @@ void QCPPolarAxisRadial::setRangeZoomFactor(double factor) /*! Sets whether the axis uses a linear scale or a logarithmic scale. - + Note that this method controls the coordinate transformation. For logarithmic scales, you will likely also want to use a logarithmic tick spacing and labeling, which can be achieved by setting the axis ticker to an instance of \ref QCPAxisTickerLog : - + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpaxisticker-log-creation - + See the documentation of \ref QCPAxisTickerLog about the details of logarithmic axis tick creation. - + \ref setNumberPrecision */ void QCPPolarAxisRadial::setScaleType(QCPPolarAxisRadial::ScaleType type) @@ -31258,17 +31310,17 @@ void QCPPolarAxisRadial::setScaleType(QCPPolarAxisRadial::ScaleType type) /*! Sets the range of the axis. - + This slot may be connected with the \ref rangeChanged signal of another axis so this axis is always synchronized with the other axis range, when it changes. - + To invert the direction of an axis, use \ref setRangeReversed. */ void QCPPolarAxisRadial::setRange(const QCPRange &range) { if (range.lower == mRange.lower && range.upper == mRange.upper) return; - + if (!QCPRange::validRange(range)) return; QCPRange oldRange = mRange; if (mScaleType == stLogarithmic) @@ -31285,11 +31337,11 @@ void QCPPolarAxisRadial::setRange(const QCPRange &range) /*! Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface. (When \ref QCustomPlot::setInteractions contains iSelectAxes.) - + However, even when \a selectable is set to a value not allowing the selection of a specific part, it is still possible to set the selection of this part manually, by calling \ref setSelectedParts directly. - + \see SelectablePart, setSelectedParts */ void QCPPolarAxisRadial::setSelectableParts(const SelectableParts &selectable) @@ -31304,15 +31356,15 @@ void QCPPolarAxisRadial::setSelectableParts(const SelectableParts &selectable) /*! Sets the selected state of the respective axis parts described by \ref SelectablePart. When a part is selected, it uses a different pen/font. - + The entire selection mechanism for axes is handled automatically when \ref QCustomPlot::setInteractions contains iSelectAxes. You only need to call this function when you wish to change the selection state manually. - + This function can change the selection state of a part, independent of the \ref setSelectableParts setting. - + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. - + \see SelectablePart, setSelectableParts, selectTest, setSelectedBasePen, setSelectedTickPen, setSelectedSubTickPen, setSelectedTickLabelFont, setSelectedLabelFont, setSelectedTickLabelColor, setSelectedLabelColor */ @@ -31327,18 +31379,18 @@ void QCPPolarAxisRadial::setSelectedParts(const SelectableParts &selected) /*! \overload - + Sets the lower and upper bound of the axis range. - + To invert the direction of an axis, use \ref setRangeReversed. - + There is also a slot to set a range, see \ref setRange(const QCPRange &range). */ void QCPPolarAxisRadial::setRange(double lower, double upper) { if (lower == mRange.lower && upper == mRange.upper) return; - + if (!QCPRange::validRange(lower, upper)) return; QCPRange oldRange = mRange; mRange.lower = lower; @@ -31356,9 +31408,9 @@ void QCPPolarAxisRadial::setRange(double lower, double upper) /*! \overload - + Sets the range of the axis. - + The \a position coordinate indicates together with the \a alignment parameter, where the new range will be positioned. \a size defines the size of the new axis range. \a alignment may be Qt::AlignLeft, Qt::AlignRight or Qt::AlignCenter. This will cause the left border, right border, @@ -31383,7 +31435,7 @@ void QCPPolarAxisRadial::setRangeLower(double lower) { if (mRange.lower == lower) return; - + QCPRange oldRange = mRange; mRange.lower = lower; if (mScaleType == stLogarithmic) @@ -31405,7 +31457,7 @@ void QCPPolarAxisRadial::setRangeUpper(double upper) { if (mRange.upper == upper) return; - + QCPRange oldRange = mRange; mRange.upper = upper; if (mScaleType == stLogarithmic) @@ -31446,14 +31498,14 @@ void QCPPolarAxisRadial::setAngleReference(AngleReference reference) /*! The axis ticker is responsible for generating the tick positions and tick labels. See the documentation of QCPAxisTicker for details on how to work with axis tickers. - + You can change the tick positioning/labeling behaviour of this axis by setting a different QCPAxisTicker subclass using this method. If you only wish to modify the currently installed axis ticker, access it via \ref ticker. - + Since the ticker is stored in the axis as a shared pointer, multiple axes may share the same axis ticker simply by passing the same shared pointer to multiple axes. - + \see ticker */ void QCPPolarAxisRadial::setTicker(QSharedPointer ticker) @@ -31470,7 +31522,7 @@ void QCPPolarAxisRadial::setTicker(QSharedPointer ticker) Note that setting \a show to false does not imply that tick labels are invisible, too. To achieve that, see \ref setTickLabels. - + \see setSubTicks */ void QCPPolarAxisRadial::setTicks(bool show) @@ -31507,7 +31559,7 @@ void QCPPolarAxisRadial::setTickLabelPadding(int padding) /*! Sets the font of the tick labels. - + \see setTickLabels, setTickLabelColor */ void QCPPolarAxisRadial::setTickLabelFont(const QFont &font) @@ -31521,7 +31573,7 @@ void QCPPolarAxisRadial::setTickLabelFont(const QFont &font) /*! Sets the color of the tick labels. - + \see setTickLabels, setTickLabelFont */ void QCPPolarAxisRadial::setTickLabelColor(const QColor &color) @@ -31533,7 +31585,7 @@ void QCPPolarAxisRadial::setTickLabelColor(const QColor &color) Sets the rotation of the tick labels. If \a degrees is zero, the labels are drawn normally. Else, the tick labels are drawn rotated by \a degrees clockwise. The specified angle is bound to values from -90 to 90 degrees. - + If \a degrees is exactly -90, 0 or 90, the tick labels are centered on the tick coordinate. For other angles, the label is drawn with an offset such that it seems to point toward or away from the tick mark. @@ -31556,11 +31608,11 @@ void QCPPolarAxisRadial::setTickLabelMode(LabelMode mode) Sets the number format for the numbers in tick labels. This \a formatCode is an extended version of the format code used e.g. by QString::number() and QLocale::toString(). For reference about that, see the "Argument Formats" section in the detailed description of the QString class. - + \a formatCode is a string of one, two or three characters. The first character is identical to the normal format code used by Qt. In short, this means: 'e'/'E' scientific format, 'f' fixed format, 'g'/'G' scientific or fixed, whichever is shorter. - + The second and third characters are optional and specific to QCustomPlot:\n If the first char was 'e' or 'g', numbers are/might be displayed in the scientific format, e.g. "5.5e9", which is ugly in a plot. So when the second char of \a formatCode is set to 'b' (for @@ -31569,7 +31621,7 @@ void QCPPolarAxisRadial::setTickLabelMode(LabelMode mode) If instead a cross should be shown (as is usual in the USA), the third char of \a formatCode can be set to 'c'. The inserted multiplication signs are the UTF-8 characters 215 (0xD7) for the cross and 183 (0xB7) for the dot. - + Examples for \a formatCode: \li \c g normal format code behaviour. If number is small, fixed format is used, if number is large, normal scientific format is used @@ -31590,7 +31642,7 @@ void QCPPolarAxisRadial::setNumberFormat(const QString &formatCode) return; } //mCachedMarginValid = false; - + // interpret first char as number format char: QString allowedFormatChars(QLatin1String("eEfgG")); if (allowedFormatChars.contains(formatCode.at(0))) @@ -31601,7 +31653,7 @@ void QCPPolarAxisRadial::setNumberFormat(const QString &formatCode) qDebug() << Q_FUNC_INFO << "Invalid number format code (first char not in 'eEfgG'):" << formatCode; return; } - + if (formatCode.length() < 2) { mNumberBeautifulPowers = false; @@ -31613,7 +31665,7 @@ void QCPPolarAxisRadial::setNumberFormat(const QString &formatCode) mNumberBeautifulPowers = true; else qDebug() << Q_FUNC_INFO << "Invalid number format code (second char not 'b' or first char neither 'e' nor 'g'):" << formatCode; - + if (formatCode.length() < 3) { mNumberMultiplyCross = false; @@ -31651,7 +31703,7 @@ void QCPPolarAxisRadial::setNumberPrecision(int precision) plot and \a outside is the length they will reach outside the plot. If \a outside is greater than zero, the tick labels and axis label will increase their distance to the axis accordingly, so they won't collide with the ticks. - + \see setSubTickLength, setTickLengthIn, setTickLengthOut */ void QCPPolarAxisRadial::setTickLength(int inside, int outside) @@ -31663,7 +31715,7 @@ void QCPPolarAxisRadial::setTickLength(int inside, int outside) /*! Sets the length of the inward ticks in pixels. \a inside is the length the ticks will reach inside the plot. - + \see setTickLengthOut, setTickLength, setSubTickLength */ void QCPPolarAxisRadial::setTickLengthIn(int inside) @@ -31678,7 +31730,7 @@ void QCPPolarAxisRadial::setTickLengthIn(int inside) Sets the length of the outward ticks in pixels. \a outside is the length the ticks will reach outside the plot. If \a outside is greater than zero, the tick labels and axis label will increase their distance to the axis accordingly, so they won't collide with the ticks. - + \see setTickLengthIn, setTickLength, setSubTickLength */ void QCPPolarAxisRadial::setTickLengthOut(int outside) @@ -31692,9 +31744,9 @@ void QCPPolarAxisRadial::setTickLengthOut(int outside) /*! Sets whether sub tick marks are displayed. - + Sub ticks are only potentially visible if (major) ticks are also visible (see \ref setTicks) - + \see setTicks */ void QCPPolarAxisRadial::setSubTicks(bool show) @@ -31711,7 +31763,7 @@ void QCPPolarAxisRadial::setSubTicks(bool show) the plot and \a outside is the length they will reach outside the plot. If \a outside is greater than zero, the tick labels and axis label will increase their distance to the axis accordingly, so they won't collide with the ticks. - + \see setTickLength, setSubTickLengthIn, setSubTickLengthOut */ void QCPPolarAxisRadial::setSubTickLength(int inside, int outside) @@ -31723,7 +31775,7 @@ void QCPPolarAxisRadial::setSubTickLength(int inside, int outside) /*! Sets the length of the inward subticks in pixels. \a inside is the length the subticks will reach inside the plot. - + \see setSubTickLengthOut, setSubTickLength, setTickLength */ void QCPPolarAxisRadial::setSubTickLengthIn(int inside) @@ -31738,7 +31790,7 @@ void QCPPolarAxisRadial::setSubTickLengthIn(int inside) Sets the length of the outward subticks in pixels. \a outside is the length the subticks will reach outside the plot. If \a outside is greater than zero, the tick labels will increase their distance to the axis accordingly, so they won't collide with the ticks. - + \see setSubTickLengthIn, setSubTickLength, setTickLength */ void QCPPolarAxisRadial::setSubTickLengthOut(int outside) @@ -31752,7 +31804,7 @@ void QCPPolarAxisRadial::setSubTickLengthOut(int outside) /*! Sets the pen, the axis base line is drawn with. - + \see setTickPen, setSubTickPen */ void QCPPolarAxisRadial::setBasePen(const QPen &pen) @@ -31762,7 +31814,7 @@ void QCPPolarAxisRadial::setBasePen(const QPen &pen) /*! Sets the pen, tick marks will be drawn with. - + \see setTickLength, setBasePen */ void QCPPolarAxisRadial::setTickPen(const QPen &pen) @@ -31772,7 +31824,7 @@ void QCPPolarAxisRadial::setTickPen(const QPen &pen) /*! Sets the pen, subtick marks will be drawn with. - + \see setSubTickCount, setSubTickLength, setBasePen */ void QCPPolarAxisRadial::setSubTickPen(const QPen &pen) @@ -31782,7 +31834,7 @@ void QCPPolarAxisRadial::setSubTickPen(const QPen &pen) /*! Sets the font of the axis label. - + \see setLabelColor */ void QCPPolarAxisRadial::setLabelFont(const QFont &font) @@ -31796,7 +31848,7 @@ void QCPPolarAxisRadial::setLabelFont(const QFont &font) /*! Sets the color of the axis label. - + \see setLabelFont */ void QCPPolarAxisRadial::setLabelColor(const QColor &color) @@ -31819,7 +31871,7 @@ void QCPPolarAxisRadial::setLabel(const QString &str) /*! Sets the distance between the tick labels and the axis label. - + \see setTickLabelPadding, setPadding */ void QCPPolarAxisRadial::setLabelPadding(int padding) @@ -31833,7 +31885,7 @@ void QCPPolarAxisRadial::setLabelPadding(int padding) /*! Sets the font that is used for tick labels when they are selected. - + \see setTickLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions */ void QCPPolarAxisRadial::setSelectedTickLabelFont(const QFont &font) @@ -31847,7 +31899,7 @@ void QCPPolarAxisRadial::setSelectedTickLabelFont(const QFont &font) /*! Sets the font that is used for the axis label when it is selected. - + \see setLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions */ void QCPPolarAxisRadial::setSelectedLabelFont(const QFont &font) @@ -31858,7 +31910,7 @@ void QCPPolarAxisRadial::setSelectedLabelFont(const QFont &font) /*! Sets the color that is used for tick labels when they are selected. - + \see setTickLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions */ void QCPPolarAxisRadial::setSelectedTickLabelColor(const QColor &color) @@ -31871,7 +31923,7 @@ void QCPPolarAxisRadial::setSelectedTickLabelColor(const QColor &color) /*! Sets the color that is used for the axis label when it is selected. - + \see setLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions */ void QCPPolarAxisRadial::setSelectedLabelColor(const QColor &color) @@ -31881,7 +31933,7 @@ void QCPPolarAxisRadial::setSelectedLabelColor(const QColor &color) /*! Sets the pen that is used to draw the axis base line when selected. - + \see setBasePen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions */ void QCPPolarAxisRadial::setSelectedBasePen(const QPen &pen) @@ -31891,7 +31943,7 @@ void QCPPolarAxisRadial::setSelectedBasePen(const QPen &pen) /*! Sets the pen that is used to draw the (major) ticks when selected. - + \see setTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions */ void QCPPolarAxisRadial::setSelectedTickPen(const QPen &pen) @@ -31901,7 +31953,7 @@ void QCPPolarAxisRadial::setSelectedTickPen(const QPen &pen) /*! Sets the pen that is used to draw the subticks when selected. - + \see setSubTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions */ void QCPPolarAxisRadial::setSelectedSubTickPen(const QPen &pen) @@ -31912,7 +31964,7 @@ void QCPPolarAxisRadial::setSelectedSubTickPen(const QPen &pen) /*! If the scale type (\ref setScaleType) is \ref stLinear, \a diff is added to the lower and upper bounds of the range. The range is simply moved by \a diff. - + If the scale type is \ref stLogarithmic, the range bounds are multiplied by \a diff. This corresponds to an apparent "linear" move in logarithmic scaling by a distance of log(diff). */ @@ -31984,7 +32036,7 @@ void QCPPolarAxisRadial::scaleRange(double factor, double center) /*! Changes the axis range such that all plottables associated with this axis are fully visible in that dimension. - + \see QCPAbstractPlottable::rescaleAxes, QCustomPlot::rescaleAxes */ void QCPPolarAxisRadial::rescale(bool onlyVisiblePlottables) @@ -32102,9 +32154,9 @@ double QCPPolarAxisRadial::radiusToCoord(double radius) const Returns the part of the axis that is hit by \a pos (in pixels). The return value of this function is independent of the user-selectable parts defined with \ref setSelectableParts. Further, this function does not change the current selection state of the axis. - + If the axis is not visible (\ref setVisible), this function always returns \ref spNone. - + \see setSelectedParts, setSelectableParts, QCustomPlot::setInteractions */ QCPPolarAxisRadial::SelectablePart QCPPolarAxisRadial::getPartAt(const QPointF &pos) const @@ -32112,7 +32164,7 @@ QCPPolarAxisRadial::SelectablePart QCPPolarAxisRadial::getPartAt(const QPointF & Q_UNUSED(pos) // TODO remove later if (!mVisible) return spNone; - + /* TODO: if (mAxisPainter->axisSelectionBox().contains(pos.toPoint())) @@ -32132,7 +32184,7 @@ double QCPPolarAxisRadial::selectTest(const QPointF &pos, bool onlySelectable, Q SelectablePart part = getPartAt(pos); if ((onlySelectable && !mSelectableParts.testFlag(part)) || part == spNone) return -1; - + if (details) details->setValue(part); return mParentPlot->selectionTolerance()*0.99; @@ -32162,7 +32214,7 @@ void QCPPolarAxisRadial::deselectEvent(bool *selectionStateChanged) } /*! \internal - + This mouse event reimplementation provides the functionality to let the user drag individual axes exclusively, by startig the drag on top of the axis. @@ -32170,9 +32222,9 @@ void QCPPolarAxisRadial::deselectEvent(bool *selectionStateChanged) must be configured accordingly, i.e. it must allow range dragging in the orientation of this axis (\ref QCPAxisRect::setRangeDrag) and this axis must be a draggable axis (\ref QCPAxisRect::setRangeDragAxes) - + \seebaseclassmethod - + \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. */ @@ -32184,7 +32236,7 @@ void QCPPolarAxisRadial::mousePressEvent(QMouseEvent *event, const QVariant &det event->ignore(); return; } - + if (event->buttons() & Qt::LeftButton) { mDragging = true; @@ -32201,15 +32253,15 @@ void QCPPolarAxisRadial::mousePressEvent(QMouseEvent *event, const QVariant &det } /*! \internal - + This mouse event reimplementation provides the functionality to let the user drag individual axes exclusively, by startig the drag on top of the axis. - + \seebaseclassmethod - + \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. - + \see QCPAxis::mousePressEvent */ void QCPPolarAxisRadial::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) @@ -32231,7 +32283,7 @@ void QCPPolarAxisRadial::mouseMoveEvent(QMouseEvent *event, const QPointF &start setRange(mDragStartRange.lower*diff, mDragStartRange.upper*diff); } */ - + if (mParentPlot->noAntialiasingOnDrag()) mParentPlot->setNotAntialiasedElements(QCP::aeAll); mParentPlot->replot(QCustomPlot::rpQueuedReplot); @@ -32239,15 +32291,15 @@ void QCPPolarAxisRadial::mouseMoveEvent(QMouseEvent *event, const QPointF &start } /*! \internal - + This mouse event reimplementation provides the functionality to let the user drag individual axes exclusively, by startig the drag on top of the axis. - + \seebaseclassmethod - + \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. - + \see QCPAxis::mousePressEvent */ void QCPPolarAxisRadial::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) @@ -32263,7 +32315,7 @@ void QCPPolarAxisRadial::mouseReleaseEvent(QMouseEvent *event, const QPointF &st } /*! \internal - + This mouse event reimplementation provides the functionality to let the user zoom individual axes exclusively, by performing the wheel event on top of the axis. @@ -32271,9 +32323,9 @@ void QCPPolarAxisRadial::mouseReleaseEvent(QMouseEvent *event, const QPointF &st must be configured accordingly, i.e. it must allow range zooming in the orientation of this axis (\ref QCPAxisRect::setRangeZoom) and this axis must be a zoomable axis (\ref QCPAxisRect::setRangeZoomAxes) - + \seebaseclassmethod - + \note The zooming of possibly multiple axes at once by performing the wheel event anywhere in the axis rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::wheelEvent. */ @@ -32285,7 +32337,7 @@ void QCPPolarAxisRadial::wheelEvent(QWheelEvent *event) event->ignore(); return; } - + // TODO: //const double wheelSteps = event->delta()/120.0; // a single step delta is +/-120 usually //const double factor = qPow(mRangeZoomFactor, wheelSteps); @@ -32306,13 +32358,13 @@ void QCPPolarAxisRadial::updateGeometry(const QPointF ¢er, double radius) before drawing axis lines. This is the antialiasing state the painter passed to the \ref draw method is in by default. - + This function takes into account the local setting of the antialiasing flag as well as the overrides set with \ref QCustomPlot::setAntialiasedElements and \ref QCustomPlot::setNotAntialiasedElements. - + \seebaseclassmethod - + \see setAntialiased */ void QCPPolarAxisRadial::applyDefaultAntialiasingHint(QCPPainter *painter) const @@ -32321,7 +32373,7 @@ void QCPPolarAxisRadial::applyDefaultAntialiasingHint(QCPPainter *painter) const } /*! \internal - + Draws the axis with the specified \a painter, using the internal QCPAxisPainterPrivate instance. \seebaseclassmethod @@ -32331,11 +32383,11 @@ void QCPPolarAxisRadial::draw(QCPPainter *painter) const double axisAngleRad = (mAngle+(mAngleReference==arAngularAxis ? mAngularAxis->angle() : 0))/180.0*M_PI; const QPointF axisVector(qCos(axisAngleRad), qSin(axisAngleRad)); // semantically should be QCPVector2D, but we save time in loops when we keep it as QPointF const QPointF tickNormal = QCPVector2D(axisVector).perpendicular().toPointF(); // semantically should be QCPVector2D, but we save time in loops when we keep it as QPointF - + // draw baseline: painter->setPen(getBasePen()); painter->drawLine(QLineF(mCenter, mCenter+axisVector*(mRadius-0.5))); - + // draw subticks: if (!mSubTickVector.isEmpty()) { @@ -32346,7 +32398,7 @@ void QCPPolarAxisRadial::draw(QCPPainter *painter) painter->drawLine(QLineF(tickPosition-tickNormal*mSubTickLengthIn, tickPosition+tickNormal*mSubTickLengthOut)); } } - + // draw ticks and labels: if (!mTickVector.isEmpty()) { @@ -32372,10 +32424,10 @@ void QCPPolarAxisRadial::draw(QCPPainter *painter) } /*! \internal - + Prepares the internal tick vector, sub tick vector and tick label vector. This is done by calling QCPAxisTicker::generate on the currently installed ticker. - + If a change in the label text/count is detected, the cached axis margin is invalidated to make sure the next margin calculation recalculates the label sizes and returns an up-to-date value. */ @@ -32383,12 +32435,12 @@ void QCPPolarAxisRadial::setupTickVectors() { if (!mParentPlot) return; if ((!mTicks && !mTickLabels) || mRange.size() <= 0) return; - + mTicker->generate(mRange, mParentPlot->locale(), mNumberFormatChar, mNumberPrecision, mTickVector, mSubTicks ? &mSubTickVector : 0, mTickLabels ? &mTickVectorLabels : 0); } /*! \internal - + Returns the pen that is used to draw the axis base line. Depending on the selection state, this is either mSelectedBasePen or mBasePen. */ @@ -32398,7 +32450,7 @@ QPen QCPPolarAxisRadial::getBasePen() const } /*! \internal - + Returns the pen that is used to draw the (major) ticks. Depending on the selection state, this is either mSelectedTickPen or mTickPen. */ @@ -32408,7 +32460,7 @@ QPen QCPPolarAxisRadial::getTickPen() const } /*! \internal - + Returns the pen that is used to draw the subticks. Depending on the selection state, this is either mSelectedSubTickPen or mSubTickPen. */ @@ -32418,7 +32470,7 @@ QPen QCPPolarAxisRadial::getSubTickPen() const } /*! \internal - + Returns the font that is used to draw the tick labels. Depending on the selection state, this is either mSelectedTickLabelFont or mTickLabelFont. */ @@ -32428,7 +32480,7 @@ QFont QCPPolarAxisRadial::getTickLabelFont() const } /*! \internal - + Returns the font that is used to draw the axis label. Depending on the selection state, this is either mSelectedLabelFont or mLabelFont. */ @@ -32438,7 +32490,7 @@ QFont QCPPolarAxisRadial::getLabelFont() const } /*! \internal - + Returns the color that is used to draw the tick labels. Depending on the selection state, this is either mSelectedTickLabelColor or mTickLabelColor. */ @@ -32448,7 +32500,7 @@ QColor QCPPolarAxisRadial::getTickLabelColor() const } /*! \internal - + Returns the color that is used to draw the axis label. Depending on the selection state, this is either mSelectedLabelColor or mLabelColor. */ @@ -32484,81 +32536,81 @@ QCP::Interaction QCPPolarAxisRadial::selectionCategory() const /* start documentation of inline functions */ /*! \fn QCPLayoutInset *QCPPolarAxisAngular::insetLayout() const - + Returns the inset layout of this axis rect. It can be used to place other layout elements (or even layouts with multiple other elements) inside/on top of an axis rect. - + \see QCPLayoutInset */ /*! \fn int QCPPolarAxisAngular::left() const - + Returns the pixel position of the left border of this axis rect. Margins are not taken into account here, so the returned value is with respect to the inner \ref rect. */ /*! \fn int QCPPolarAxisAngular::right() const - + Returns the pixel position of the right border of this axis rect. Margins are not taken into account here, so the returned value is with respect to the inner \ref rect. */ /*! \fn int QCPPolarAxisAngular::top() const - + Returns the pixel position of the top border of this axis rect. Margins are not taken into account here, so the returned value is with respect to the inner \ref rect. */ /*! \fn int QCPPolarAxisAngular::bottom() const - + Returns the pixel position of the bottom border of this axis rect. Margins are not taken into account here, so the returned value is with respect to the inner \ref rect. */ /*! \fn int QCPPolarAxisAngular::width() const - + Returns the pixel width of this axis rect. Margins are not taken into account here, so the returned value is with respect to the inner \ref rect. */ /*! \fn int QCPPolarAxisAngular::height() const - + Returns the pixel height of this axis rect. Margins are not taken into account here, so the returned value is with respect to the inner \ref rect. */ /*! \fn QSize QCPPolarAxisAngular::size() const - + Returns the pixel size of this axis rect. Margins are not taken into account here, so the returned value is with respect to the inner \ref rect. */ /*! \fn QPoint QCPPolarAxisAngular::topLeft() const - + Returns the top left corner of this axis rect in pixels. Margins are not taken into account here, so the returned value is with respect to the inner \ref rect. */ /*! \fn QPoint QCPPolarAxisAngular::topRight() const - + Returns the top right corner of this axis rect in pixels. Margins are not taken into account here, so the returned value is with respect to the inner \ref rect. */ /*! \fn QPoint QCPPolarAxisAngular::bottomLeft() const - + Returns the bottom left corner of this axis rect in pixels. Margins are not taken into account here, so the returned value is with respect to the inner \ref rect. */ /*! \fn QPoint QCPPolarAxisAngular::bottomRight() const - + Returns the bottom right corner of this axis rect in pixels. Margins are not taken into account here, so the returned value is with respect to the inner \ref rect. */ /*! \fn QPoint QCPPolarAxisAngular::center() const - + Returns the center of this axis rect in pixels. Margins are not taken into account here, so the returned value is with respect to the inner \ref rect. */ @@ -32629,24 +32681,24 @@ QCPPolarAxisAngular::QCPPolarAxisAngular(QCustomPlot *parentPlot) : //mInsetLayout->initializeParentPlot(mParentPlot); //mInsetLayout->setParentLayerable(this); //mInsetLayout->setParent(this); - + if (QCPAxisTickerFixed *fixedTicker = mTicker.dynamicCast().data()) { fixedTicker->setTickStep(30); } setAntialiased(true); setLayer(mParentPlot->currentLayer()); // it's actually on that layer already, but we want it in front of the grid, so we place it on there again - + setTickLabelPadding(5); setTickLabelRotation(0); setTickLabelMode(lmUpright); mLabelPainter.setAnchorReferenceType(QCPLabelPainterPrivate::artNormal); mLabelPainter.setAbbreviateDecimalPowers(false); mLabelPainter.setCacheSize(24); // so we can cache up to 15-degree intervals, polar angular axis uses a bit larger cache than normal axes - + setMinimumSize(50, 50); setMinimumMargins(QMargins(30, 30, 30, 30)); - + addRadialAxis(); mGrid->setRadialAxis(radialAxis()); } @@ -32655,10 +32707,10 @@ QCPPolarAxisAngular::~QCPPolarAxisAngular() { delete mGrid; // delete grid here instead of via parent ~QObject for better defined deletion order mGrid = 0; - + delete mInsetLayout; mInsetLayout = 0; - + QList radialAxesList = radialAxes(); for (int i=0; ior-combination, to get the axes of multiple sides. - + \see axis */ QList QCPPolarAxisAngular::radialAxes() const @@ -32775,9 +32827,9 @@ QCPPolarAxisRadial *QCPPolarAxisAngular::addRadialAxis(QCPPolarAxisRadial *axis) /*! Removes the specified \a axis from the axis rect and deletes it. - + Returns true on success, i.e. if \a axis was a valid axis in this axis rect. - + \see addAxis */ bool QCPPolarAxisAngular::removeRadialAxis(QCPPolarAxisRadial *radialAxis) @@ -32802,7 +32854,7 @@ QRegion QCPPolarAxisAngular::exactClipRegion() const /*! If the scale type (\ref setScaleType) is \ref stLinear, \a diff is added to the lower and upper bounds of the range. The range is simply moved by \a diff. - + If the scale type is \ref stLogarithmic, the range bounds are multiplied by \a diff. This corresponds to an apparent "linear" move in logarithmic scaling by a distance of log(diff). */ @@ -32853,7 +32905,7 @@ void QCPPolarAxisAngular::scaleRange(double factor, double center) /*! Changes the axis range such that all plottables associated with this axis are fully visible in that dimension. - + \see QCPAbstractPlottable::rescaleAxes, QCustomPlot::rescaleAxes */ void QCPPolarAxisAngular::rescale(bool onlyVisiblePlottables) @@ -32921,18 +32973,18 @@ QPointF QCPPolarAxisAngular::coordToPixel(double angleCoord, double radiusCoord) Returns the part of the axis that is hit by \a pos (in pixels). The return value of this function is independent of the user-selectable parts defined with \ref setSelectableParts. Further, this function does not change the current selection state of the axis. - + If the axis is not visible (\ref setVisible), this function always returns \ref spNone. - + \see setSelectedParts, setSelectableParts, QCustomPlot::setInteractions */ QCPPolarAxisAngular::SelectablePart QCPPolarAxisAngular::getPartAt(const QPointF &pos) const { Q_UNUSED(pos) // TODO remove later - + if (!mVisible) return spNone; - + /* TODO: if (mAxisPainter->axisSelectionBox().contains(pos.toPoint())) @@ -32953,17 +33005,17 @@ double QCPPolarAxisAngular::selectTest(const QPointF &pos, bool onlySelectable, SelectablePart part = getPartAt(pos); if ((onlySelectable && !mSelectableParts.testFlag(part)) || part == spNone) return -1; - + if (details) details->setValue(part); return mParentPlot->selectionTolerance()*0.99; */ - + Q_UNUSED(details) - + if (onlySelectable) return -1; - + if (QRectF(mOuterRect).contains(pos)) { if (mParentPlot) @@ -32980,17 +33032,17 @@ double QCPPolarAxisAngular::selectTest(const QPointF &pos, bool onlySelectable, /*! This method is called automatically upon replot and doesn't need to be called by users of QCPPolarAxisAngular. - + Calls the base class implementation to update the margins (see \ref QCPLayoutElement::update), and finally passes the \ref rect to the inset layout (\ref insetLayout) and calls its QCPInsetLayout::update function. - + \seebaseclassmethod */ void QCPPolarAxisAngular::update(UpdatePhase phase) { QCPLayoutElement::update(phase); - + switch (phase) { case upPreparation: @@ -33007,13 +33059,13 @@ void QCPPolarAxisAngular::update(UpdatePhase phase) if (mRadius < 1) mRadius = 1; // prevent cases where radius might become 0 which causes trouble for (int i=0; iupdateGeometry(mCenter, mRadius); - + mInsetLayout->setOuterRect(rect()); break; } default: break; } - + // pass update call on to inset layout (doesn't happen automatically, because QCPPolarAxis doesn't derive from QCPLayout): mInsetLayout->update(phase); } @@ -33038,7 +33090,7 @@ bool QCPPolarAxisAngular::removeGraph(QCPPolarGraph *graph) qDebug() << Q_FUNC_INFO << "graph not in list:" << reinterpret_cast(graph); return false; } - + // remove plottable from legend: graph->removeFromLegend(); // remove plottable: @@ -33057,11 +33109,11 @@ void QCPPolarAxisAngular::applyDefaultAntialiasingHint(QCPPainter *painter) cons void QCPPolarAxisAngular::draw(QCPPainter *painter) { drawBackground(painter, mCenter, mRadius); - + // draw baseline circle: painter->setPen(getBasePen()); painter->drawEllipse(mCenter, mRadius, mRadius); - + // draw subticks: if (!mSubTickVector.isEmpty()) { @@ -33072,7 +33124,7 @@ void QCPPolarAxisAngular::draw(QCPPainter *painter) mCenter+mSubTickVectorCosSin.at(i)*(mRadius+mSubTickLengthOut)); } } - + // draw ticks and labels: if (!mTickVector.isEmpty()) { @@ -33114,7 +33166,7 @@ QCP::Interaction QCPPolarAxisAngular::selectionCategory() const Below the pixmap, the axis rect may be optionally filled with a brush, if specified with \ref setBackground(const QBrush &brush). - + \see setBackgroundScaled, setBackgroundScaledMode, setBackground(const QBrush &brush) */ void QCPPolarAxisAngular::setBackground(const QPixmap &pm) @@ -33124,7 +33176,7 @@ void QCPPolarAxisAngular::setBackground(const QPixmap &pm) } /*! \overload - + Sets \a brush as the background brush. The axis rect background will be filled with this brush. Since axis rects place themselves on the "background" layer by default, the axis rect backgrounds are usually drawn below everything else. @@ -33133,7 +33185,7 @@ void QCPPolarAxisAngular::setBackground(const QPixmap &pm) setBackground(const QPixmap &pm). To disable drawing of a background brush, set \a brush to Qt::NoBrush. - + \see setBackground(const QPixmap &pm) */ void QCPPolarAxisAngular::setBackground(const QBrush &brush) @@ -33142,7 +33194,7 @@ void QCPPolarAxisAngular::setBackground(const QBrush &brush) } /*! \overload - + Allows setting the background pixmap of the axis rect, whether it shall be scaled and how it shall be scaled in one call. @@ -33160,10 +33212,10 @@ void QCPPolarAxisAngular::setBackground(const QPixmap &pm, bool scaled, Qt::Aspe Sets whether the axis background pixmap shall be scaled to fit the axis rect or not. If \a scaled is set to true, you may control whether and how the aspect ratio of the original pixmap is preserved with \ref setBackgroundScaledMode. - + Note that the scaled version of the original pixmap is buffered, so there is no performance penalty on replots. (Except when the axis rect dimensions are changed continuously.) - + \see setBackground, setBackgroundScaledMode */ void QCPPolarAxisAngular::setBackgroundScaled(bool scaled) @@ -33204,17 +33256,17 @@ void QCPPolarAxisAngular::setRangeZoomFactor(double factor) /*! Sets the range of the axis. - + This slot may be connected with the \ref rangeChanged signal of another axis so this axis is always synchronized with the other axis range, when it changes. - + To invert the direction of an axis, use \ref setRangeReversed. */ void QCPPolarAxisAngular::setRange(const QCPRange &range) { if (range.lower == mRange.lower && range.upper == mRange.upper) return; - + if (!QCPRange::validRange(range)) return; QCPRange oldRange = mRange; mRange = range.sanitizedForLinScale(); @@ -33225,11 +33277,11 @@ void QCPPolarAxisAngular::setRange(const QCPRange &range) /*! Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface. (When \ref QCustomPlot::setInteractions contains iSelectAxes.) - + However, even when \a selectable is set to a value not allowing the selection of a specific part, it is still possible to set the selection of this part manually, by calling \ref setSelectedParts directly. - + \see SelectablePart, setSelectedParts */ void QCPPolarAxisAngular::setSelectableParts(const SelectableParts &selectable) @@ -33244,15 +33296,15 @@ void QCPPolarAxisAngular::setSelectableParts(const SelectableParts &selectable) /*! Sets the selected state of the respective axis parts described by \ref SelectablePart. When a part is selected, it uses a different pen/font. - + The entire selection mechanism for axes is handled automatically when \ref QCustomPlot::setInteractions contains iSelectAxes. You only need to call this function when you wish to change the selection state manually. - + This function can change the selection state of a part, independent of the \ref setSelectableParts setting. - + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. - + \see SelectablePart, setSelectableParts, selectTest, setSelectedBasePen, setSelectedTickPen, setSelectedSubTickPen, setSelectedTickLabelFont, setSelectedLabelFont, setSelectedTickLabelColor, setSelectedLabelColor */ @@ -33267,18 +33319,18 @@ void QCPPolarAxisAngular::setSelectedParts(const SelectableParts &selected) /*! \overload - + Sets the lower and upper bound of the axis range. - + To invert the direction of an axis, use \ref setRangeReversed. - + There is also a slot to set a range, see \ref setRange(const QCPRange &range). */ void QCPPolarAxisAngular::setRange(double lower, double upper) { if (lower == mRange.lower && upper == mRange.upper) return; - + if (!QCPRange::validRange(lower, upper)) return; QCPRange oldRange = mRange; mRange.lower = lower; @@ -33290,9 +33342,9 @@ void QCPPolarAxisAngular::setRange(double lower, double upper) /*! \overload - + Sets the range of the axis. - + The \a position coordinate indicates together with the \a alignment parameter, where the new range will be positioned. \a size defines the size of the new axis range. \a alignment may be Qt::AlignLeft, Qt::AlignRight or Qt::AlignCenter. This will cause the left border, right border, @@ -33317,7 +33369,7 @@ void QCPPolarAxisAngular::setRangeLower(double lower) { if (mRange.lower == lower) return; - + QCPRange oldRange = mRange; mRange.lower = lower; mRange = mRange.sanitizedForLinScale(); @@ -33333,7 +33385,7 @@ void QCPPolarAxisAngular::setRangeUpper(double upper) { if (mRange.upper == upper) return; - + QCPRange oldRange = mRange; mRange.upper = upper; mRange = mRange.sanitizedForLinScale(); @@ -33364,14 +33416,14 @@ void QCPPolarAxisAngular::setAngle(double degrees) /*! The axis ticker is responsible for generating the tick positions and tick labels. See the documentation of QCPAxisTicker for details on how to work with axis tickers. - + You can change the tick positioning/labeling behaviour of this axis by setting a different QCPAxisTicker subclass using this method. If you only wish to modify the currently installed axis ticker, access it via \ref ticker. - + Since the ticker is stored in the axis as a shared pointer, multiple axes may share the same axis ticker simply by passing the same shared pointer to multiple axes. - + \see ticker */ void QCPPolarAxisAngular::setTicker(QSharedPointer ticker) @@ -33388,7 +33440,7 @@ void QCPPolarAxisAngular::setTicker(QSharedPointer ticker) Note that setting \a show to false does not imply that tick labels are invisible, too. To achieve that, see \ref setTickLabels. - + \see setSubTicks */ void QCPPolarAxisAngular::setTicks(bool show) @@ -33425,7 +33477,7 @@ void QCPPolarAxisAngular::setTickLabelPadding(int padding) /*! Sets the font of the tick labels. - + \see setTickLabels, setTickLabelColor */ void QCPPolarAxisAngular::setTickLabelFont(const QFont &font) @@ -33435,7 +33487,7 @@ void QCPPolarAxisAngular::setTickLabelFont(const QFont &font) /*! Sets the color of the tick labels. - + \see setTickLabels, setTickLabelFont */ void QCPPolarAxisAngular::setTickLabelColor(const QColor &color) @@ -33447,7 +33499,7 @@ void QCPPolarAxisAngular::setTickLabelColor(const QColor &color) Sets the rotation of the tick labels. If \a degrees is zero, the labels are drawn normally. Else, the tick labels are drawn rotated by \a degrees clockwise. The specified angle is bound to values from -90 to 90 degrees. - + If \a degrees is exactly -90, 0 or 90, the tick labels are centered on the tick coordinate. For other angles, the label is drawn with an offset such that it seems to point toward or away from the tick mark. @@ -33470,11 +33522,11 @@ void QCPPolarAxisAngular::setTickLabelMode(LabelMode mode) Sets the number format for the numbers in tick labels. This \a formatCode is an extended version of the format code used e.g. by QString::number() and QLocale::toString(). For reference about that, see the "Argument Formats" section in the detailed description of the QString class. - + \a formatCode is a string of one, two or three characters. The first character is identical to the normal format code used by Qt. In short, this means: 'e'/'E' scientific format, 'f' fixed format, 'g'/'G' scientific or fixed, whichever is shorter. - + The second and third characters are optional and specific to QCustomPlot:\n If the first char was 'e' or 'g', numbers are/might be displayed in the scientific format, e.g. "5.5e9", which might be visually unappealing in a plot. So when the second char of \a formatCode is set to 'b' (for @@ -33483,7 +33535,7 @@ void QCPPolarAxisAngular::setTickLabelMode(LabelMode mode) If instead a cross should be shown (as is usual in the USA), the third char of \a formatCode can be set to 'c'. The inserted multiplication signs are the UTF-8 characters 215 (0xD7) for the cross and 183 (0xB7) for the dot. - + Examples for \a formatCode: \li \c g normal format code behaviour. If number is small, fixed format is used, if number is large, normal scientific format is used @@ -33504,7 +33556,7 @@ void QCPPolarAxisAngular::setNumberFormat(const QString &formatCode) return; } //mCachedMarginValid = false; - + // interpret first char as number format char: QString allowedFormatChars(QLatin1String("eEfgG")); if (allowedFormatChars.contains(formatCode.at(0))) @@ -33515,7 +33567,7 @@ void QCPPolarAxisAngular::setNumberFormat(const QString &formatCode) qDebug() << Q_FUNC_INFO << "Invalid number format code (first char not in 'eEfgG'):" << formatCode; return; } - + if (formatCode.length() < 2) { mNumberBeautifulPowers = false; @@ -33527,7 +33579,7 @@ void QCPPolarAxisAngular::setNumberFormat(const QString &formatCode) mNumberBeautifulPowers = true; else qDebug() << Q_FUNC_INFO << "Invalid number format code (second char not 'b' or first char neither 'e' nor 'g'):" << formatCode; - + if (formatCode.length() < 3) { mNumberMultiplyCross = false; @@ -33565,7 +33617,7 @@ void QCPPolarAxisAngular::setNumberPrecision(int precision) plot and \a outside is the length they will reach outside the plot. If \a outside is greater than zero, the tick labels and axis label will increase their distance to the axis accordingly, so they won't collide with the ticks. - + \see setSubTickLength, setTickLengthIn, setTickLengthOut */ void QCPPolarAxisAngular::setTickLength(int inside, int outside) @@ -33577,7 +33629,7 @@ void QCPPolarAxisAngular::setTickLength(int inside, int outside) /*! Sets the length of the inward ticks in pixels. \a inside is the length the ticks will reach inside the plot. - + \see setTickLengthOut, setTickLength, setSubTickLength */ void QCPPolarAxisAngular::setTickLengthIn(int inside) @@ -33592,7 +33644,7 @@ void QCPPolarAxisAngular::setTickLengthIn(int inside) Sets the length of the outward ticks in pixels. \a outside is the length the ticks will reach outside the plot. If \a outside is greater than zero, the tick labels and axis label will increase their distance to the axis accordingly, so they won't collide with the ticks. - + \see setTickLengthIn, setTickLength, setSubTickLength */ void QCPPolarAxisAngular::setTickLengthOut(int outside) @@ -33606,9 +33658,9 @@ void QCPPolarAxisAngular::setTickLengthOut(int outside) /*! Sets whether sub tick marks are displayed. - + Sub ticks are only potentially visible if (major) ticks are also visible (see \ref setTicks) - + \see setTicks */ void QCPPolarAxisAngular::setSubTicks(bool show) @@ -33625,7 +33677,7 @@ void QCPPolarAxisAngular::setSubTicks(bool show) the plot and \a outside is the length they will reach outside the plot. If \a outside is greater than zero, the tick labels and axis label will increase their distance to the axis accordingly, so they won't collide with the ticks. - + \see setTickLength, setSubTickLengthIn, setSubTickLengthOut */ void QCPPolarAxisAngular::setSubTickLength(int inside, int outside) @@ -33637,7 +33689,7 @@ void QCPPolarAxisAngular::setSubTickLength(int inside, int outside) /*! Sets the length of the inward subticks in pixels. \a inside is the length the subticks will reach inside the plot. - + \see setSubTickLengthOut, setSubTickLength, setTickLength */ void QCPPolarAxisAngular::setSubTickLengthIn(int inside) @@ -33652,7 +33704,7 @@ void QCPPolarAxisAngular::setSubTickLengthIn(int inside) Sets the length of the outward subticks in pixels. \a outside is the length the subticks will reach outside the plot. If \a outside is greater than zero, the tick labels will increase their distance to the axis accordingly, so they won't collide with the ticks. - + \see setSubTickLengthIn, setSubTickLength, setTickLength */ void QCPPolarAxisAngular::setSubTickLengthOut(int outside) @@ -33666,7 +33718,7 @@ void QCPPolarAxisAngular::setSubTickLengthOut(int outside) /*! Sets the pen, the axis base line is drawn with. - + \see setTickPen, setSubTickPen */ void QCPPolarAxisAngular::setBasePen(const QPen &pen) @@ -33676,7 +33728,7 @@ void QCPPolarAxisAngular::setBasePen(const QPen &pen) /*! Sets the pen, tick marks will be drawn with. - + \see setTickLength, setBasePen */ void QCPPolarAxisAngular::setTickPen(const QPen &pen) @@ -33686,7 +33738,7 @@ void QCPPolarAxisAngular::setTickPen(const QPen &pen) /*! Sets the pen, subtick marks will be drawn with. - + \see setSubTickCount, setSubTickLength, setBasePen */ void QCPPolarAxisAngular::setSubTickPen(const QPen &pen) @@ -33696,7 +33748,7 @@ void QCPPolarAxisAngular::setSubTickPen(const QPen &pen) /*! Sets the font of the axis label. - + \see setLabelColor */ void QCPPolarAxisAngular::setLabelFont(const QFont &font) @@ -33710,7 +33762,7 @@ void QCPPolarAxisAngular::setLabelFont(const QFont &font) /*! Sets the color of the axis label. - + \see setLabelFont */ void QCPPolarAxisAngular::setLabelColor(const QColor &color) @@ -33733,7 +33785,7 @@ void QCPPolarAxisAngular::setLabel(const QString &str) /*! Sets the distance between the tick labels and the axis label. - + \see setTickLabelPadding, setPadding */ void QCPPolarAxisAngular::setLabelPadding(int padding) @@ -33747,7 +33799,7 @@ void QCPPolarAxisAngular::setLabelPadding(int padding) /*! Sets the font that is used for tick labels when they are selected. - + \see setTickLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions */ void QCPPolarAxisAngular::setSelectedTickLabelFont(const QFont &font) @@ -33761,7 +33813,7 @@ void QCPPolarAxisAngular::setSelectedTickLabelFont(const QFont &font) /*! Sets the font that is used for the axis label when it is selected. - + \see setLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions */ void QCPPolarAxisAngular::setSelectedLabelFont(const QFont &font) @@ -33772,7 +33824,7 @@ void QCPPolarAxisAngular::setSelectedLabelFont(const QFont &font) /*! Sets the color that is used for tick labels when they are selected. - + \see setTickLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions */ void QCPPolarAxisAngular::setSelectedTickLabelColor(const QColor &color) @@ -33785,7 +33837,7 @@ void QCPPolarAxisAngular::setSelectedTickLabelColor(const QColor &color) /*! Sets the color that is used for the axis label when it is selected. - + \see setLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions */ void QCPPolarAxisAngular::setSelectedLabelColor(const QColor &color) @@ -33795,7 +33847,7 @@ void QCPPolarAxisAngular::setSelectedLabelColor(const QColor &color) /*! Sets the pen that is used to draw the axis base line when selected. - + \see setBasePen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions */ void QCPPolarAxisAngular::setSelectedBasePen(const QPen &pen) @@ -33805,7 +33857,7 @@ void QCPPolarAxisAngular::setSelectedBasePen(const QPen &pen) /*! Sets the pen that is used to draw the (major) ticks when selected. - + \see setTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions */ void QCPPolarAxisAngular::setSelectedTickPen(const QPen &pen) @@ -33815,7 +33867,7 @@ void QCPPolarAxisAngular::setSelectedTickPen(const QPen &pen) /*! Sets the pen that is used to draw the subticks when selected. - + \see setSubTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions */ void QCPPolarAxisAngular::setSelectedSubTickPen(const QPen &pen) @@ -33824,13 +33876,13 @@ void QCPPolarAxisAngular::setSelectedSubTickPen(const QPen &pen) } /*! \internal - + Draws the background of this axis rect. It may consist of a background fill (a QBrush) and a pixmap. - + If a brush was given via \ref setBackground(const QBrush &brush), this function first draws an according filling inside the axis rect with the provided \a painter. - + Then, if a pixmap was provided via \ref setBackground, this function buffers the scaled version depending on \ref setBackgroundScaled and \ref setBackgroundScaledMode and then draws it inside the axis rect with the provided \a painter. The scaled version is buffered in @@ -33838,7 +33890,7 @@ void QCPPolarAxisAngular::setSelectedSubTickPen(const QPen &pen) the axis rect has changed in a way that requires a rescale of the background pixmap (this is dependent on the \ref setBackgroundScaledMode), or when a differend axis background pixmap was set. - + \see setBackground, setBackgroundScaled, setBackgroundScaledMode */ void QCPPolarAxisAngular::drawBackground(QCPPainter *painter, const QPointF ¢er, double radius) @@ -33850,7 +33902,7 @@ void QCPPolarAxisAngular::drawBackground(QCPPainter *painter, const QPointF &cen ellipsePath.addEllipse(center, radius, radius); painter->fillPath(ellipsePath, mBackgroundBrush); } - + // draw background pixmap (on top of fill, if brush specified): if (!mBackgroundPixmap.isNull()) { @@ -33874,10 +33926,10 @@ void QCPPolarAxisAngular::drawBackground(QCPPainter *painter, const QPointF &cen } /*! \internal - + Prepares the internal tick vector, sub tick vector and tick label vector. This is done by calling QCPAxisTicker::generate on the currently installed ticker. - + If a change in the label text/count is detected, the cached axis margin is invalidated to make sure the next margin calculation recalculates the label sizes and returns an up-to-date value. */ @@ -33885,10 +33937,10 @@ void QCPPolarAxisAngular::setupTickVectors() { if (!mParentPlot) return; if ((!mTicks && !mTickLabels && !mGrid->visible()) || mRange.size() <= 0) return; - + mSubTickVector.clear(); // since we might not pass it to mTicker->generate(), and we don't want old data in there mTicker->generate(mRange, mParentPlot->locale(), mNumberFormatChar, mNumberPrecision, mTickVector, mSubTicks ? &mSubTickVector : 0, mTickLabels ? &mTickVectorLabels : 0); - + // fill cos/sin buffers which will be used by draw() and QCPPolarGrid::draw(), so we don't have to calculate it twice: mTickVectorCosSin.resize(mTickVector.size()); for (int i=0; inoAntialiasingOnDrag()) @@ -34080,13 +34132,13 @@ void QCPPolarAxisAngular::mouseReleaseEvent(QMouseEvent *event, const QPointF &s } /*! \internal - + Event handler for mouse wheel events. If rangeZoom is Qt::Horizontal, Qt::Vertical or both, the ranges of the axes defined as rangeZoomHorzAxis and rangeZoomVertAxis are scaled. The center of the scaling operation is the current cursor position inside the axis rect. The scaling factor is dependent on the mouse wheel delta (which direction the wheel was rotated) to provide a natural zooming feel. The Strength of the zoom can be controlled via \ref setRangeZoomFactor. - + Note, that event->delta() is usually +/-120 for single rotation steps. However, if the mouse wheel is turned rapidly, many steps may bunch up to one event, so the event->delta() may then be multiples of 120. This is taken into account here, by calculating \a wheelSteps and using it as @@ -34145,7 +34197,7 @@ bool QCPPolarAxisAngular::registerPolarGraph(QCPPolarGraph *graph) qDebug() << Q_FUNC_INFO << "plottable not created with this as axis:" << reinterpret_cast(graph); return false; } - + mGraphs.append(graph); // possibly add plottable to legend: if (mParentPlot->autoAddPlottableToLegend()) @@ -34174,7 +34226,7 @@ bool QCPPolarAxisAngular::registerPolarGraph(QCPPolarGraph *graph) /*! Creates a QCPPolarGrid instance and sets default values. - + You shouldn't instantiate grids on their own, since every axis brings its own grid. */ QCPPolarGrid::QCPPolarGrid(QCPPolarAxisAngular *parentAxis) : @@ -34189,14 +34241,14 @@ QCPPolarGrid::QCPPolarGrid(QCPPolarAxisAngular *parentAxis) : setParent(parentAxis); setType(gtAll); setSubGridType(gtNone); - + setAngularPen(QPen(QColor(200,200,200), 0, Qt::DotLine)); setAngularSubGridPen(QPen(QColor(220,220,220), 0, Qt::DotLine)); - + setRadialPen(QPen(QColor(200,200,200), 0, Qt::DotLine)); setRadialSubGridPen(QPen(QColor(220,220,220), 0, Qt::DotLine)); setRadialZeroLinePen(QPen(QColor(200,200,200), 0, Qt::SolidLine)); - + setAntialiased(true); } @@ -34268,11 +34320,11 @@ void QCPPolarGrid::setRadialZeroLinePen(const QPen &pen) before drawing the major grid lines. This is the antialiasing state the painter passed to the \ref draw method is in by default. - + This function takes into account the local setting of the antialiasing flag as well as the overrides set with \ref QCustomPlot::setAntialiasedElements and \ref QCustomPlot::setNotAntialiasedElements. - + \see setAntialiased */ void QCPPolarGrid::applyDefaultAntialiasingHint(QCPPainter *painter) const @@ -34281,17 +34333,17 @@ void QCPPolarGrid::applyDefaultAntialiasingHint(QCPPainter *painter) const } /*! \internal - + Draws grid lines and sub grid lines at the positions of (sub) ticks of the parent axis, spanning over the complete axis rect. Also draws the zero line, if appropriate (\ref setZeroLinePen). */ void QCPPolarGrid::draw(QCPPainter *painter) { if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } - + const QPointF center = mParentAxis->mCenter; const double radius = mParentAxis->mRadius; - + painter->setBrush(Qt::NoBrush); // draw main angular grid: if (mType.testFlag(gtAngular)) @@ -34299,7 +34351,7 @@ void QCPPolarGrid::draw(QCPPainter *painter) // draw main radial grid: if (mType.testFlag(gtRadial) && mRadialAxis) drawRadialGrid(painter, center, mRadialAxis->tickVector(), mRadialPen, mRadialZeroLinePen); - + applyAntialiasingHint(painter, mAntialiasedSubGrid, QCP::aeGrid); // draw sub angular grid: if (mSubGridType.testFlag(gtAngular)) @@ -34315,7 +34367,7 @@ void QCPPolarGrid::drawRadialGrid(QCPPainter *painter, const QPointF ¢er, co if (coords.isEmpty()) return; const bool drawZeroLine = zeroPen != Qt::NoPen; const double zeroLineEpsilon = qAbs(coords.last()-coords.first())*1e-6; - + painter->setPen(pen); for (int i=0; i &ticksCosSin, const QPen &pen) { if (ticksCosSin.isEmpty()) return; - + painter->setPen(pen); for (int i=0; idrawLine(center, center+ticksCosSin.at(i)*radius); @@ -34469,11 +34521,11 @@ QCPPolarGraph::QCPPolarGraph(QCPPolarAxisAngular *keyAxis, QCPPolarAxisRadial *v { if (keyAxis->parentPlot() != valueAxis->parentPlot()) qDebug() << Q_FUNC_INFO << "Parent plot of keyAxis is not the same as that of valueAxis."; - + mKeyAxis->registerPolarGraph(this); - + //setSelectionDecorator(new QCPSelectionDecorator); // TODO - + setPen(QPen(Qt::blue, 0)); setBrush(Qt::NoBrush); setLineStyle(lsLine); @@ -34501,7 +34553,7 @@ void QCPPolarGraph::setName(const QString &name) /*! Sets whether fills of this plottable are drawn antialiased or not. - + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref QCustomPlot::setNotAntialiasedElements. */ @@ -34512,7 +34564,7 @@ void QCPPolarGraph::setAntialiasedFill(bool enabled) /*! Sets whether the scatter symbols of this plottable are drawn antialiased or not. - + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref QCustomPlot::setNotAntialiasedElements. */ @@ -34524,7 +34576,7 @@ void QCPPolarGraph::setAntialiasedScatters(bool enabled) /*! The pen is used to draw basic lines that make up the plottable representation in the plot. - + For example, the \ref QCPGraph subclass draws its graph lines with this pen. \see setBrush @@ -34537,7 +34589,7 @@ void QCPPolarGraph::setPen(const QPen &pen) /*! The brush is used to draw basic fills of the plottable representation in the plot. The Fill can be a color, gradient or texture, see the usage of QBrush. - + For example, the \ref QCPGraph subclass draws the fill under the graph with this brush, when it's not set to Qt::NoBrush. @@ -34558,7 +34610,7 @@ void QCPPolarGraph::setPeriodic(bool enabled) to the plottable's value axis. This function performs no checks to make sure this is the case. The typical mathematical choice is to use the x-axis (QCustomPlot::xAxis) as key axis and the y-axis (QCustomPlot::yAxis) as value axis. - + Normally, the key and value axes are set in the constructor of the plottable (or \ref QCustomPlot::addGraph when working with QCPGraphs through the dedicated graph interface). @@ -34577,7 +34629,7 @@ void QCPPolarGraph::setKeyAxis(QCPPolarAxisAngular *axis) Normally, the key and value axes are set in the constructor of the plottable (or \ref QCustomPlot::addGraph when working with QCPGraphs through the dedicated graph interface). - + \see setKeyAxis */ void QCPPolarGraph::setValueAxis(QCPPolarAxisRadial *axis) @@ -34592,7 +34644,7 @@ void QCPPolarGraph::setValueAxis(QCPPolarAxisRadial *axis) QCustomPlot::setInteractions contains \ref QCP::iSelectPlottables), by dragging a selection rect (When \ref QCustomPlot::setSelectionRectMode is \ref QCP::srmSelect), or programmatically by calling \ref setSelection. - + \see setSelection, QCP::SelectionType */ void QCPPolarGraph::setSelectable(QCP::SelectionType selectable) @@ -34615,18 +34667,18 @@ void QCPPolarGraph::setSelectable(QCP::SelectionType selectable) Sets which data ranges of this plottable are selected. Selected data ranges are drawn differently (e.g. color) in the plot. This can be controlled via the selection decorator (see \ref selectionDecorator). - + The entire selection mechanism for plottables is handled automatically when \ref QCustomPlot::setInteractions contains iSelectPlottables. You only need to call this function when you wish to change the selection state programmatically. - + Using \ref setSelectable you can further specify for each plottable whether and to which granularity it is selectable. If \a selection is not compatible with the current \ref QCP::SelectionType set via \ref setSelectable, the resulting selection will be adjusted accordingly (see \ref QCPDataSelection::enforceType). - + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. - + \see setSelectable, selectTest */ void QCPPolarGraph::setSelection(QCPDataSelection selection) @@ -34641,18 +34693,18 @@ void QCPPolarGraph::setSelection(QCPDataSelection selection) } /*! \overload - + Replaces the current data container with the provided \a data container. - + Since a QSharedPointer is used, multiple QCPPolarGraphs may share the same data container safely. Modifying the data in the container will then affect all graphs that share the container. Sharing can be achieved by simply exchanging the data containers wrapped in shared pointers: \snippet documentation/doc-code-snippets/mainwindow.cpp QCPPolarGraph-datasharing-1 - + If you do not wish to share containers, but create a copy from an existing container, rather use the \ref QCPDataContainer::set method on the graph's data container directly: \snippet documentation/doc-code-snippets/mainwindow.cpp QCPPolarGraph-datasharing-2 - + \see addData */ void QCPPolarGraph::setData(QSharedPointer data) @@ -34661,14 +34713,14 @@ void QCPPolarGraph::setData(QSharedPointer data) } /*! \overload - + Replaces the current data with the provided points in \a keys and \a values. The provided vectors should have equal length. Else, the number of added points will be the size of the smallest vector. - + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you can set \a alreadySorted to true, to improve performance by saving a sorting run. - + \see addData */ void QCPPolarGraph::setData(const QVector &keys, const QVector &values, bool alreadySorted) @@ -34680,7 +34732,7 @@ void QCPPolarGraph::setData(const QVector &keys, const QVector & /*! Sets how the single data points are connected in the plot. For scatter-only plots, set \a ls to \ref lsNone and \ref setScatterStyle to the desired scatter style. - + \see setScatterStyle */ void QCPPolarGraph::setLineStyle(LineStyle ls) @@ -34691,7 +34743,7 @@ void QCPPolarGraph::setLineStyle(LineStyle ls) /*! Sets the visual appearance of single data points in the plot. If set to \ref QCPScatterStyle::ssNone, no scatter points are drawn (e.g. for line-only-plots with appropriate line style). - + \see QCPScatterStyle, setLineStyle */ void QCPPolarGraph::setScatterStyle(const QCPScatterStyle &style) @@ -34727,9 +34779,9 @@ void QCPPolarGraph::addData(double key, double value) Use this method to set an own QCPSelectionDecorator (subclass) instance. This allows you to customize the visual representation of selected data ranges further than by using the default QCPSelectionDecorator. - + The plottable takes ownership of the \a decorator. - + The currently set decorator can be accessed via \ref selectionDecorator. */ /* @@ -34808,7 +34860,7 @@ void QCPPolarGraph::rescaleKeyAxis(bool onlyEnlarge) const { QCPPolarAxisAngular *keyAxis = mKeyAxis.data(); if (!keyAxis) { qDebug() << Q_FUNC_INFO << "invalid key axis"; return; } - + bool foundRange; QCPRange newRange = getKeyRange(foundRange, QCP::sdBoth); if (foundRange) @@ -34830,11 +34882,11 @@ void QCPPolarGraph::rescaleValueAxis(bool onlyEnlarge, bool inKeyRange) const QCPPolarAxisAngular *keyAxis = mKeyAxis.data(); QCPPolarAxisRadial *valueAxis = mValueAxis.data(); if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - + QCP::SignDomain signDomain = QCP::sdBoth; if (valueAxis->scaleType() == QCPPolarAxisRadial::stLogarithmic) signDomain = (valueAxis->range().upper < 0 ? QCP::sdNegative : QCP::sdPositive); - + bool foundRange; QCPRange newRange = getValueRange(foundRange, signDomain, inKeyRange ? keyAxis->range() : QCPRange()); if (foundRange) @@ -34870,7 +34922,7 @@ bool QCPPolarGraph::addToLegend(QCPLegend *legend) qDebug() << Q_FUNC_INFO << "passed legend isn't in the same QCustomPlot as this plottable"; return false; } - + //if (!legend->hasItemWithPlottable(this)) // TODO //{ legend->addItem(new QCPPolarLegendItem(legend, this)); @@ -34894,8 +34946,8 @@ bool QCPPolarGraph::removeFromLegend(QCPLegend *legend) const qDebug() << Q_FUNC_INFO << "passed legend is null"; return false; } - - + + QCPPolarLegendItem *removableItem = 0; for (int i=0; iitemCount(); ++i) // TODO: reduce this to code in QCPAbstractPlottable::removeFromLegend once unified { @@ -34908,7 +34960,7 @@ bool QCPPolarGraph::removeFromLegend(QCPLegend *legend) const } } } - + if (removableItem) return legend->removeItem(removableItem); else @@ -34929,7 +34981,7 @@ double QCPPolarGraph::selectTest(const QPointF &pos, bool onlySelectable, QVaria return -1; if (!mKeyAxis || !mValueAxis) return -1; - + if (mKeyAxis->rect().contains(pos.toPoint())) { QCPGraphDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); @@ -34970,11 +35022,11 @@ void QCPPolarGraph::draw(QCPPainter *painter) if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } if (mKeyAxis.data()->range().size() <= 0 || mDataContainer->isEmpty()) return; if (mLineStyle == lsNone && mScatterStyle.isNone()) return; - + painter->setClipRegion(mKeyAxis->exactClipRegion()); - + QVector lines, scatters; // line and (if necessary) scatter pixel coordinates will be stored here while iterating over segments - + // loop over and draw segments of unselected/selected data: QList selectedSegments, unselectedSegments, allSegments; getDataSegments(selectedSegments, unselectedSegments); @@ -34985,7 +35037,7 @@ void QCPPolarGraph::draw(QCPPainter *painter) // get line pixel points appropriate to line style: QCPDataRange lineDataRange = isSelectedSegment ? allSegments.at(i) : allSegments.at(i).adjusted(-1, 1); // unselected segments extend lines to bordering selected data point (safe to exceed total data bounds in first/last segment, getLines takes care) getLines(&lines, lineDataRange); - + // check data validity if flag set: #ifdef QCUSTOMPLOT_CHECK_DATA QCPGraphDataContainer::const_iterator it; @@ -34995,7 +35047,7 @@ void QCPPolarGraph::draw(QCPPainter *painter) qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "invalid." << "Plottable name:" << name(); } #endif - + // draw fill of graph: //if (isSelectedSegment && mSelectionDecorator) // mSelectionDecorator->applyBrush(painter); @@ -35003,8 +35055,8 @@ void QCPPolarGraph::draw(QCPPainter *painter) painter->setBrush(mBrush); painter->setPen(Qt::NoPen); drawFill(painter, &lines); - - + + // draw line: if (mLineStyle != lsNone) { @@ -35015,9 +35067,9 @@ void QCPPolarGraph::draw(QCPPainter *painter) painter->setBrush(Qt::NoBrush); drawLinePlot(painter, lines); } - + // draw scatters: - + QCPScatterStyle finalScatterStyle = mScatterStyle; //if (isSelectedSegment && mSelectionDecorator) // finalScatterStyle = mSelectionDecorator->getFinalScatterStyle(mScatterStyle); @@ -35027,7 +35079,7 @@ void QCPPolarGraph::draw(QCPPainter *painter) drawScatterPlot(painter, scatters, finalScatterStyle); } } - + // draw other selection decoration that isn't just line/scatter pens and brushes: //if (mSelectionDecorator) // mSelectionDecorator->drawDecoration(painter, selection()); @@ -35047,7 +35099,7 @@ void QCPPolarGraph::applyDefaultAntialiasingHint(QCPPainter *painter) const void QCPPolarGraph::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) { Q_UNUSED(event) - + if (mSelectable != QCP::stNone) { QCPDataSelection newSelection = details.value(); @@ -35087,9 +35139,9 @@ void QCPPolarGraph::deselectEvent(bool *selectionStateChanged) } /*! \internal - + Draws lines between the points in \a lines, given in pixel coordinates. - + \see drawScatterPlot, drawImpulsePlot, QCPAbstractPlottable1D::drawPolyline */ void QCPPolarGraph::drawLinePlot(QCPPainter *painter, const QVector &lines) const @@ -35102,18 +35154,18 @@ void QCPPolarGraph::drawLinePlot(QCPPainter *painter, const QVector &li } /*! \internal - + Draws the fill of the graph using the specified \a painter, with the currently set brush. - + Depending on whether a normal fill or a channel fill (\ref setChannelFillGraph) is needed, \ref getFillPolygon or \ref getChannelFillPolygon are used to find the according fill polygons. - + In order to handle NaN Data points correctly (the fill needs to be split into disjoint areas), this method first determines a list of non-NaN segments with \ref getNonNanSegments, on which to operate. In the channel fill case, \ref getOverlappingSegments is used to consolidate the non-NaN segments of the two involved graphs, before passing the overlapping pairs to \ref getChannelFillPolygon. - + Pass the points of this graph's line as \a lines, in pixel coordinates. \see drawLinePlot, drawImpulsePlot, drawScatterPlot @@ -35191,7 +35243,7 @@ double QCPPolarGraph::pointDistance(const QPointF &pixelPoint, QCPGraphDataConta return -1.0; if (mLineStyle == lsNone && mScatterStyle.isNone()) return -1.0; - + // calculate minimum distances to graph data points and find closestData iterator: double minDistSqr = (std::numeric_limits::max)(); // determine which key range comes into question, taking selection tolerance around pos into account: @@ -35212,7 +35264,7 @@ double QCPPolarGraph::pointDistance(const QPointF &pixelPoint, QCPGraphDataConta closestData = it; } } - + // calculate distance to graph line if there is one (if so, will probably be smaller than distance to closest data point): if (mLineStyle != lsNone) { @@ -35227,7 +35279,7 @@ double QCPPolarGraph::pointDistance(const QPointF &pixelPoint, QCPGraphDataConta minDistSqr = currentDistSqr; } } - + return qSqrt(minDistSqr); } @@ -35356,7 +35408,7 @@ void QCPPolarGraph::getLines(QVector *lines, const QCPDataRange &dataRa lines->clear(); return; } - + QVector lineData; if (mLineStyle != lsNone) getOptimizedLineData(&lineData, begin, end); @@ -35373,7 +35425,7 @@ void QCPPolarGraph::getScatters(QVector *scatters, const QCPDataRange & QCPPolarAxisAngular *keyAxis = mKeyAxis.data(); QCPPolarAxisRadial *valueAxis = mValueAxis.data(); if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - + if (!scatters) return; QCPGraphDataContainer::const_iterator begin, end; getVisibleDataBounds(begin, end, dataRange); @@ -35382,10 +35434,10 @@ void QCPPolarGraph::getScatters(QVector *scatters, const QCPDataRange & scatters->clear(); return; } - + QVector data; getOptimizedScatterData(&data, begin, end); - + scatters->resize(data.size()); for (int i=0; i *scatters, const QCPDataRange & void QCPPolarGraph::getOptimizedLineData(QVector *lineData, const QCPGraphDataContainer::const_iterator &begin, const QCPGraphDataContainer::const_iterator &end) const { lineData->clear(); - + // TODO: fix for log axes and thick line style - + const QCPRange range = mValueAxis->range(); bool reversed = mValueAxis->rangeReversed(); const double clipMargin = range.size()*0.05; // extra distance from visible circle, so optimized outside lines can cover more angle before having to place a dummy point to prevent tangents @@ -35486,7 +35538,7 @@ void QCPPolarGraph::getOptimizedLineData(QVector *lineData, const void QCPPolarGraph::getOptimizedScatterData(QVector *scatterData, QCPGraphDataContainer::const_iterator begin, QCPGraphDataContainer::const_iterator end) const { scatterData->clear(); - + const QCPRange range = mValueAxis->range(); bool reversed = mValueAxis->rangeReversed(); const double clipMargin = range.size()*0.05; @@ -35505,7 +35557,7 @@ void QCPPolarGraph::getOptimizedScatterData(QVector *scatterData, Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel coordinate points which are suitable for drawing the line style \ref lsLine. - + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a getLines if the line style is set accordingly. diff --git a/companion/src/thirdparty/qcustomplot/qcustomplot.h b/companion/src/thirdparty/qcustomplot/qcustomplot.h index 02ed8fb2f35..a05f34b20b6 100644 --- a/companion/src/thirdparty/qcustomplot/qcustomplot.h +++ b/companion/src/thirdparty/qcustomplot/qcustomplot.h @@ -153,12 +153,16 @@ class QCPPolarGraph; /*! The QCP Namespace contains general enums, QFlags and functions used throughout the QCustomPlot library. - + It provides QMetaObject-based reflection of its enums and flags via \a QCP::staticMetaObject. */ // Qt version < 6.2.0: to get metatypes Q_GADGET/Q_ENUMS/Q_FLAGS in namespace we have to make it look like a class during moc-run -#if QT_VERSION >= 0x060200 // don't use QT_VERSION_CHECK here, some moc versions don't understand it +// EdgeTX v3.0 workaround for upgrade to Qt 6.8.2 +// until upsteam solution available +//#if QT_VERSION >= 0x060200 // don't use QT_VERSION_CHECK here, some moc versions don't understand it +#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) +// End EdgeTX v3.0 fix namespace QCP { Q_NAMESPACE // this is how to add the staticMetaObject to namespaces in newer Qt versions #else // Qt version older than 6.2.0 @@ -176,7 +180,7 @@ class QCP { Q_ENUMS(Interaction) Q_ENUMS(SelectionRectMode) Q_ENUMS(SelectionType) - + Q_FLAGS(AntialiasedElements) Q_FLAGS(PlottingHints) Q_FLAGS(MarginSides) @@ -209,7 +213,7 @@ enum ExportPen { epNoCosmetic ///< Cosmetic pens are converted to pens with /*! Represents negative and positive sign domain, e.g. for passing to \ref QCPAbstractPlottable::getKeyRange and \ref QCPAbstractPlottable::getValueRange. - + This is primarily needed when working with logarithmic axis scales, since only one of the sign domains can be visible at a time. */ @@ -220,7 +224,7 @@ enum SignDomain { sdNegative ///< The negative sign domain, i.e. numbers smalle /*! Defines the sides of a rectangular entity to which margins can be applied. - + \see QCPLayoutElement::setAutoMargins, QCPAxisRect::setAutoMargins */ enum MarginSide { msLeft = 0x01 ///< 0x01 left margin @@ -236,9 +240,9 @@ Q_DECLARE_FLAGS(MarginSides, MarginSide) Defines what objects of a plot can be forcibly drawn antialiased/not antialiased. If an object is neither forcibly drawn antialiased nor forcibly drawn not antialiased, it is up to the respective element how it is drawn. Typically it provides a \a setAntialiased function for this. - + \c AntialiasedElements is a flag of or-combined elements of this enum type. - + \see QCustomPlot::setAntialiasedElements, QCustomPlot::setNotAntialiasedElements */ enum AntialiasedElement { aeAxes = 0x0001 ///< 0x0001 Axis base line and tick marks @@ -259,7 +263,7 @@ Q_DECLARE_FLAGS(AntialiasedElements, AntialiasedElement) /*! Defines plotting hints that control various aspects of the quality and speed of plotting. - + \see QCustomPlot::setPlottingHints */ enum PlottingHint { phNone = 0x000 ///< 0x000 No hints are set @@ -273,9 +277,9 @@ Q_DECLARE_FLAGS(PlottingHints, PlottingHint) /*! Defines the mouse interactions possible with QCustomPlot. - + \c Interactions is a flag of or-combined elements of this enum type. - + \see QCustomPlot::setInteractions */ enum Interaction { iNone = 0x000 ///< 0x000 None of the interactions are possible @@ -293,7 +297,7 @@ Q_DECLARE_FLAGS(Interactions, Interaction) /*! Defines the behaviour of the selection rect. - + \see QCustomPlot::setSelectionRectMode, QCustomPlot::selectionRect, QCPSelectionRect */ enum SelectionRectMode { srmNone ///< The selection rect is disabled, and all mouse events are forwarded to the underlying objects, e.g. for axis range dragging @@ -305,7 +309,7 @@ enum SelectionRectMode { srmNone ///< The selection rect is disabled, and all /*! Defines the different ways a plottable can be selected. These images show the effect of the different selection types, when the indicated selection rect was dragged: - +
@@ -317,7 +321,7 @@ enum SelectionRectMode { srmNone ///< The selection rect is disabled, and all
- + \see QCPAbstractPlottable::setSelectable, QCPDataSelection::enforceType */ enum SelectionType { stNone ///< The plottable is not selectable @@ -328,7 +332,7 @@ enum SelectionType { stNone ///< The plottable is not selectable }; /*! \internal - + Returns whether the specified \a value is considered an invalid data value for plottables (i.e. is \e nan or \e +/-inf). This function is used to check data validity upon replots, when the compiler flag \c QCUSTOMPLOT_CHECK_DATA is set. @@ -340,7 +344,7 @@ inline bool isInvalidData(double value) /*! \internal \overload - + Checks two arguments instead of one. */ inline bool isInvalidData(double value1, double value2) @@ -349,9 +353,9 @@ inline bool isInvalidData(double value1, double value2) } /*! \internal - + Sets the specified \a side of \a margins to \a value - + \see getMarginValue */ inline void setMarginValue(QMargins &margins, QCP::MarginSide side, int value) @@ -368,10 +372,10 @@ inline void setMarginValue(QMargins &margins, QCP::MarginSide side, int value) } /*! \internal - + Returns the value of the specified \a side of \a margins. If \a side is \ref QCP::msNone or \ref QCP::msAll, returns 0. - + \see setMarginValue */ inline int getMarginValue(const QMargins &margins, QCP::MarginSide side) @@ -444,24 +448,24 @@ class QCP_LIB_DECL QCPVector2D QCPVector2D(double x, double y); QCPVector2D(const QPoint &point); QCPVector2D(const QPointF &point); - + // getters: double x() const { return mX; } double y() const { return mY; } double &rx() { return mX; } double &ry() { return mY; } - + // setters: void setX(double x) { mX = x; } void setY(double y) { mY = y; } - + // non-virtual methods: double length() const { return qSqrt(mX*mX+mY*mY); } double lengthSquared() const { return mX*mX+mY*mY; } double angle() const { return qAtan2(mY, mX); } QPoint toPoint() const { return QPoint(int(mX), int(mY)); } QPointF toPointF() const { return QPointF(mX, mY); } - + bool isNull() const { return qIsNull(mX) && qIsNull(mY); } void normalize(); QCPVector2D normalized() const; @@ -470,16 +474,16 @@ class QCP_LIB_DECL QCPVector2D double distanceSquaredToLine(const QCPVector2D &start, const QCPVector2D &end) const; double distanceSquaredToLine(const QLineF &line) const; double distanceToStraightLine(const QCPVector2D &base, const QCPVector2D &direction) const; - + QCPVector2D &operator*=(double factor); QCPVector2D &operator/=(double divisor); QCPVector2D &operator+=(const QCPVector2D &vector); QCPVector2D &operator-=(const QCPVector2D &vector); - + private: // property members: double mX, mY; - + friend inline const QCPVector2D operator*(double factor, const QCPVector2D &vec); friend inline const QCPVector2D operator*(const QCPVector2D &vec, double factor); friend inline const QCPVector2D operator/(const QCPVector2D &vec, double divisor); @@ -528,10 +532,10 @@ class QCP_LIB_DECL QCPPainter : public QPainter Q_ENUMS(PainterMode) Q_FLAGS(PainterModes) Q_DECLARE_FLAGS(PainterModes, PainterMode) - + QCPPainter(); explicit QCPPainter(QPaintDevice *device); - + // getters: bool antialiasing() const { return testRenderHint(QPainter::Antialiasing); } PainterModes modes() const { return mModes; } @@ -550,15 +554,15 @@ class QCP_LIB_DECL QCPPainter : public QPainter void drawLine(const QPointF &p1, const QPointF &p2) {drawLine(QLineF(p1, p2));} void save(); void restore(); - + // non-virtual methods: void makeNonCosmetic(); - + protected: // property members: PainterModes mModes; bool mIsAntialiasing; - + // non-property members: QStack mAntialiasingStack; }; @@ -576,31 +580,31 @@ class QCP_LIB_DECL QCPAbstractPaintBuffer public: explicit QCPAbstractPaintBuffer(const QSize &size, double devicePixelRatio); virtual ~QCPAbstractPaintBuffer(); - + // getters: QSize size() const { return mSize; } bool invalidated() const { return mInvalidated; } double devicePixelRatio() const { return mDevicePixelRatio; } - + // setters: void setSize(const QSize &size); void setInvalidated(bool invalidated=true); void setDevicePixelRatio(double ratio); - + // introduced virtual methods: virtual QCPPainter *startPainting() = 0; virtual void donePainting() {} virtual void draw(QCPPainter *painter) const = 0; virtual void clear(const QColor &color) = 0; - + protected: // property members: QSize mSize; double mDevicePixelRatio; - + // non-property members: bool mInvalidated; - + // introduced virtual methods: virtual void reallocateBuffer() = 0; }; @@ -611,16 +615,16 @@ class QCP_LIB_DECL QCPPaintBufferPixmap : public QCPAbstractPaintBuffer public: explicit QCPPaintBufferPixmap(const QSize &size, double devicePixelRatio); virtual ~QCPPaintBufferPixmap() Q_DECL_OVERRIDE; - + // reimplemented virtual methods: virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; void clear(const QColor &color) Q_DECL_OVERRIDE; - + protected: // non-property members: QPixmap mBuffer; - + // reimplemented virtual methods: virtual void reallocateBuffer() Q_DECL_OVERRIDE; }; @@ -632,17 +636,17 @@ class QCP_LIB_DECL QCPPaintBufferGlPbuffer : public QCPAbstractPaintBuffer public: explicit QCPPaintBufferGlPbuffer(const QSize &size, double devicePixelRatio, int multisamples); virtual ~QCPPaintBufferGlPbuffer() Q_DECL_OVERRIDE; - + // reimplemented virtual methods: virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; void clear(const QColor &color) Q_DECL_OVERRIDE; - + protected: // non-property members: QGLPixelBuffer *mGlPBuffer; int mMultisamples; - + // reimplemented virtual methods: virtual void reallocateBuffer() Q_DECL_OVERRIDE; }; @@ -655,19 +659,19 @@ class QCP_LIB_DECL QCPPaintBufferGlFbo : public QCPAbstractPaintBuffer public: explicit QCPPaintBufferGlFbo(const QSize &size, double devicePixelRatio, QWeakPointer glContext, QWeakPointer glPaintDevice); virtual ~QCPPaintBufferGlFbo() Q_DECL_OVERRIDE; - + // reimplemented virtual methods: virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; virtual void donePainting() Q_DECL_OVERRIDE; virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; void clear(const QColor &color) Q_DECL_OVERRIDE; - + protected: // non-property members: QWeakPointer mGlContext; QWeakPointer mGlPaintDevice; QOpenGLFramebufferObject *mGlFrameBuffer; - + // reimplemented virtual methods: virtual void reallocateBuffer() Q_DECL_OVERRIDE; }; @@ -691,7 +695,7 @@ class QCP_LIB_DECL QCPLayer : public QObject Q_PROPERTY(LayerMode mode READ mode WRITE setMode) /// \endcond public: - + /*! Defines the different rendering modes of a layer. Depending on the mode, certain layers can be replotted individually, without the need to replot (possibly complex) layerables on other @@ -703,10 +707,10 @@ class QCP_LIB_DECL QCPLayer : public QObject ,lmBuffered ///< Layer has its own paint buffer and may be replotted individually (see \ref replot). }; Q_ENUMS(LayerMode) - + QCPLayer(QCustomPlot* parentPlot, const QString &layerName); virtual ~QCPLayer(); - + // getters: QCustomPlot *parentPlot() const { return mParentPlot; } QString name() const { return mName; } @@ -714,14 +718,14 @@ class QCP_LIB_DECL QCPLayer : public QObject QList children() const { return mChildren; } bool visible() const { return mVisible; } LayerMode mode() const { return mMode; } - + // setters: void setVisible(bool visible); void setMode(LayerMode mode); - + // non-virtual methods: void replot(); - + protected: // property members: QCustomPlot *mParentPlot; @@ -730,19 +734,19 @@ class QCP_LIB_DECL QCPLayer : public QObject QList mChildren; bool mVisible; LayerMode mMode; - + // non-property members: QWeakPointer mPaintBuffer; - + // non-virtual methods: void draw(QCPPainter *painter); void drawToPaintBuffer(); void addChild(QCPLayerable *layerable, bool prepend); void removeChild(QCPLayerable *layerable); - + private: Q_DISABLE_COPY(QCPLayer) - + friend class QCustomPlot; friend class QCPLayerable; }; @@ -761,29 +765,29 @@ class QCP_LIB_DECL QCPLayerable : public QObject public: QCPLayerable(QCustomPlot *plot, QString targetLayer=QString(), QCPLayerable *parentLayerable=nullptr); virtual ~QCPLayerable(); - + // getters: bool visible() const { return mVisible; } QCustomPlot *parentPlot() const { return mParentPlot; } QCPLayerable *parentLayerable() const { return mParentLayerable.data(); } QCPLayer *layer() const { return mLayer; } bool antialiased() const { return mAntialiased; } - + // setters: void setVisible(bool on); Q_SLOT bool setLayer(QCPLayer *layer); bool setLayer(const QString &layerName); void setAntialiased(bool enabled); - + // introduced virtual methods: virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const; // non-property methods: bool realVisibility() const; - + signals: void layerChanged(QCPLayer *newLayer); - + protected: // property members: bool mVisible; @@ -791,7 +795,7 @@ class QCP_LIB_DECL QCPLayerable : public QObject QPointer mParentLayerable; QCPLayer *mLayer; bool mAntialiased; - + // introduced virtual methods: virtual void parentPlotInitialized(QCustomPlot *parentPlot); virtual QCP::Interaction selectionCategory() const; @@ -807,16 +811,16 @@ class QCP_LIB_DECL QCPLayerable : public QObject virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos); virtual void mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details); virtual void wheelEvent(QWheelEvent *event); - + // non-property methods: void initializeParentPlot(QCustomPlot *parentPlot); void setParentLayerable(QCPLayerable* parentLayerable); bool moveToLayer(QCPLayer *layer, bool prepend); void applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const; - + private: Q_DISABLE_COPY(QCPLayerable) - + friend class QCustomPlot; friend class QCPLayer; friend class QCPAxisRect; @@ -832,13 +836,13 @@ class QCP_LIB_DECL QCPRange { public: double lower, upper; - + QCPRange(); QCPRange(double lower, double upper); - + bool operator==(const QCPRange& other) const { return lower == other.lower && upper == other.upper; } bool operator!=(const QCPRange& other) const { return !(*this == other); } - + QCPRange &operator+=(const double& value) { lower+=value; upper+=value; return *this; } QCPRange &operator-=(const double& value) { lower-=value; upper-=value; return *this; } QCPRange &operator*=(const double& value) { lower*=value; upper*=value; return *this; } @@ -849,7 +853,7 @@ class QCP_LIB_DECL QCPRange friend inline const QCPRange operator*(const QCPRange& range, double value); friend inline const QCPRange operator*(double value, const QCPRange& range); friend inline const QCPRange operator/(const QCPRange& range, double value); - + double size() const { return upper-lower; } double center() const { return (upper+lower)*0.5; } void normalize() { if (lower > upper) qSwap(lower, upper); } @@ -861,12 +865,12 @@ class QCP_LIB_DECL QCPRange QCPRange sanitizedForLogScale() const; QCPRange sanitizedForLinScale() const; bool contains(double value) const { return value >= lower && value <= upper; } - + static bool validRange(double lower, double upper); static bool validRange(const QCPRange &range); static const double minRange; static const double maxRange; - + }; Q_DECLARE_TYPEINFO(QCPRange, Q_MOVABLE_TYPE); @@ -951,20 +955,20 @@ class QCP_LIB_DECL QCPDataRange public: QCPDataRange(); QCPDataRange(int begin, int end); - + bool operator==(const QCPDataRange& other) const { return mBegin == other.mBegin && mEnd == other.mEnd; } bool operator!=(const QCPDataRange& other) const { return !(*this == other); } - + // getters: int begin() const { return mBegin; } int end() const { return mEnd; } int size() const { return mEnd-mBegin; } int length() const { return size(); } - + // setters: void setBegin(int begin) { mBegin = begin; } void setEnd(int end) { mEnd = end; } - + // non-property methods: bool isValid() const { return (mEnd >= mBegin) && (mBegin >= 0); } bool isEmpty() const { return length() == 0; } @@ -974,7 +978,7 @@ class QCP_LIB_DECL QCPDataRange QCPDataRange adjusted(int changeBegin, int changeEnd) const { return QCPDataRange(mBegin+changeBegin, mEnd+changeEnd); } bool intersects(const QCPDataRange &other) const; bool contains(const QCPDataRange &other) const; - + private: // property members: int mBegin, mEnd; @@ -988,7 +992,7 @@ class QCP_LIB_DECL QCPDataSelection public: explicit QCPDataSelection(); explicit QCPDataSelection(const QCPDataRange &range); - + bool operator==(const QCPDataSelection& other) const; bool operator!=(const QCPDataSelection& other) const { return !(*this == other); } QCPDataSelection &operator+=(const QCPDataSelection& other); @@ -1003,14 +1007,14 @@ class QCP_LIB_DECL QCPDataSelection friend inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataSelection& b); friend inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataRange& b); friend inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataRange& b); - + // getters: int dataRangeCount() const { return mDataRanges.size(); } int dataPointCount() const; QCPDataRange dataRange(int index=0) const; QList dataRanges() const { return mDataRanges; } QCPDataRange span() const; - + // non-property methods: void addDataRange(const QCPDataRange &dataRange, bool simplify=true); void clear(); @@ -1021,11 +1025,11 @@ class QCP_LIB_DECL QCPDataSelection QCPDataSelection intersection(const QCPDataRange &other) const; QCPDataSelection intersection(const QCPDataSelection &other) const; QCPDataSelection inverse(const QCPDataRange &outerRange) const; - + private: // property members: QList mDataRanges; - + inline static bool lessThanDataRangeBegin(const QCPDataRange &a, const QCPDataRange &b) { return a.begin() < b.begin(); } }; Q_DECLARE_METATYPE(QCPDataSelection) @@ -1156,27 +1160,27 @@ class QCP_LIB_DECL QCPSelectionRect : public QCPLayerable public: explicit QCPSelectionRect(QCustomPlot *parentPlot); virtual ~QCPSelectionRect() Q_DECL_OVERRIDE; - + // getters: QRect rect() const { return mRect; } QCPRange range(const QCPAxis *axis) const; QPen pen() const { return mPen; } QBrush brush() const { return mBrush; } bool isActive() const { return mActive; } - + // setters: void setPen(const QPen &pen); void setBrush(const QBrush &brush); - + // non-property methods: Q_SLOT void cancel(); - + signals: void started(QMouseEvent *event); void changed(const QRect &rect, QMouseEvent *event); void canceled(const QRect &rect, QInputEvent *event); void accepted(const QRect &rect, QMouseEvent *event); - + protected: // property members: QRect mRect; @@ -1184,17 +1188,17 @@ class QCP_LIB_DECL QCPSelectionRect : public QCPLayerable QBrush mBrush; // non-property members: bool mActive; - + // introduced virtual methods: virtual void startSelection(QMouseEvent *event); virtual void moveSelection(QMouseEvent *event); virtual void endSelection(QMouseEvent *event); virtual void keyPressEvent(QKeyEvent *event); - + // reimplemented virtual methods virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - + friend class QCustomPlot; }; @@ -1210,27 +1214,27 @@ class QCP_LIB_DECL QCPMarginGroup : public QObject public: explicit QCPMarginGroup(QCustomPlot *parentPlot); virtual ~QCPMarginGroup(); - + // non-virtual methods: QList elements(QCP::MarginSide side) const { return mChildren.value(side); } bool isEmpty() const; void clear(); - + protected: // non-property members: QCustomPlot *mParentPlot; QHash > mChildren; - + // introduced virtual methods: virtual int commonMargin(QCP::MarginSide side) const; - + // non-virtual methods: void addChild(QCP::MarginSide side, QCPLayoutElement *element); void removeChild(QCP::MarginSide side, QCPLayoutElement *element); - + private: Q_DISABLE_COPY(QCPMarginGroup) - + friend class QCPLayoutElement; }; @@ -1258,13 +1262,13 @@ class QCP_LIB_DECL QCPLayoutElement : public QCPLayerable ,upLayout ///< Final phase in which the layout system places the rects of the elements }; Q_ENUMS(UpdatePhase) - + /*! Defines to which rect of a layout element the size constraints that can be set via \ref setMinimumSize and \ref setMaximumSize apply. The outer rect (\ref outerRect) includes the margins (e.g. in the case of a QCPAxisRect the axis labels), whereas the inner rect (\ref rect) does not. - + \see setSizeConstraintRect */ enum SizeConstraintRect { scrInnerRect ///< Minimum/Maximum size constraints apply to inner rect @@ -1274,7 +1278,7 @@ class QCP_LIB_DECL QCPLayoutElement : public QCPLayerable explicit QCPLayoutElement(QCustomPlot *parentPlot=nullptr); virtual ~QCPLayoutElement() Q_DECL_OVERRIDE; - + // getters: QCPLayout *layout() const { return mParentLayout; } QRect rect() const { return mRect; } @@ -1287,7 +1291,7 @@ class QCP_LIB_DECL QCPLayoutElement : public QCPLayerable SizeConstraintRect sizeConstraintRect() const { return mSizeConstraintRect; } QCPMarginGroup *marginGroup(QCP::MarginSide side) const { return mMarginGroups.value(side, nullptr); } QHash marginGroups() const { return mMarginGroups; } - + // setters: void setOuterRect(const QRect &rect); void setMargins(const QMargins &margins); @@ -1299,16 +1303,16 @@ class QCP_LIB_DECL QCPLayoutElement : public QCPLayerable void setMaximumSize(int width, int height); void setSizeConstraintRect(SizeConstraintRect constraintRect); void setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group); - + // introduced virtual methods: virtual void update(UpdatePhase phase); virtual QSize minimumOuterSizeHint() const; virtual QSize maximumOuterSizeHint() const; virtual QList elements(bool recursive) const; - + // reimplemented virtual methods: virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; - + protected: // property members: QCPLayout *mParentLayout; @@ -1318,11 +1322,11 @@ class QCP_LIB_DECL QCPLayoutElement : public QCPLayerable QMargins mMargins, mMinimumMargins; QCP::MarginSides mAutoMargins; QHash mMarginGroups; - + // introduced virtual methods: virtual int calculateAutoMargin(QCP::MarginSide side); virtual void layoutChanged(); - + // reimplemented virtual methods: virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE { Q_UNUSED(painter) } virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE { Q_UNUSED(painter) } @@ -1330,7 +1334,7 @@ class QCP_LIB_DECL QCPLayoutElement : public QCPLayerable private: Q_DISABLE_COPY(QCPLayoutElement) - + friend class QCustomPlot; friend class QCPLayout; friend class QCPMarginGroup; @@ -1343,27 +1347,27 @@ class QCP_LIB_DECL QCPLayout : public QCPLayoutElement Q_OBJECT public: explicit QCPLayout(); - + // reimplemented virtual methods: virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; - + // introduced virtual methods: virtual int elementCount() const = 0; virtual QCPLayoutElement* elementAt(int index) const = 0; virtual QCPLayoutElement* takeAt(int index) = 0; virtual bool take(QCPLayoutElement* element) = 0; virtual void simplify(); - + // non-virtual methods: bool removeAt(int index); bool remove(QCPLayoutElement* element); void clear(); - + protected: // introduced virtual methods: virtual void updateLayout(); - + // non-virtual methods: void sizeConstraintsChanged() const; void adoptElement(QCPLayoutElement *el); @@ -1371,7 +1375,7 @@ class QCP_LIB_DECL QCPLayout : public QCPLayoutElement QVector getSectionSizes(QVector maxSizes, QVector minSizes, QVector stretchFactors, int totalSize) const; static QSize getFinalMinimumOuterSize(const QCPLayoutElement *el); static QSize getFinalMaximumOuterSize(const QCPLayoutElement *el); - + private: Q_DISABLE_COPY(QCPLayout) friend class QCPLayoutElement; @@ -1392,7 +1396,7 @@ class QCP_LIB_DECL QCPLayoutGrid : public QCPLayout Q_PROPERTY(int wrap READ wrap WRITE setWrap) /// \endcond public: - + /*! Defines in which direction the grid is filled when using \ref addElement(QCPLayoutElement*). The column/row at which wrapping into the next row/column occurs can be specified with \ref @@ -1404,10 +1408,10 @@ class QCP_LIB_DECL QCPLayoutGrid : public QCPLayout ,foColumnsFirst ///< Columns are filled first, and a new element is wrapped to the next row if the column count would exceed \ref setWrap. }; Q_ENUMS(FillOrder) - + explicit QCPLayoutGrid(); virtual ~QCPLayoutGrid() Q_DECL_OVERRIDE; - + // getters: int rowCount() const { return mElements.size(); } int columnCount() const { return mElements.size() > 0 ? mElements.first().size() : 0; } @@ -1417,7 +1421,7 @@ class QCP_LIB_DECL QCPLayoutGrid : public QCPLayout int rowSpacing() const { return mRowSpacing; } int wrap() const { return mWrap; } FillOrder fillOrder() const { return mFillOrder; } - + // setters: void setColumnStretchFactor(int column, double factor); void setColumnStretchFactors(const QList &factors); @@ -1427,7 +1431,7 @@ class QCP_LIB_DECL QCPLayoutGrid : public QCPLayout void setRowSpacing(int pixels); void setWrap(int count); void setFillOrder(FillOrder order, bool rearrange=true); - + // reimplemented virtual methods: virtual void updateLayout() Q_DECL_OVERRIDE; virtual int elementCount() const Q_DECL_OVERRIDE { return rowCount()*columnCount(); } @@ -1438,7 +1442,7 @@ class QCP_LIB_DECL QCPLayoutGrid : public QCPLayout virtual void simplify() Q_DECL_OVERRIDE; virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE; virtual QSize maximumOuterSizeHint() const Q_DECL_OVERRIDE; - + // non-virtual methods: QCPLayoutElement *element(int row, int column) const; bool addElement(int row, int column, QCPLayoutElement *element); @@ -1449,7 +1453,7 @@ class QCP_LIB_DECL QCPLayoutGrid : public QCPLayout void insertColumn(int newIndex); int rowColToIndex(int row, int column) const; void indexToRowCol(int index, int &row, int &column) const; - + protected: // property members: QList > mElements; @@ -1458,11 +1462,11 @@ class QCP_LIB_DECL QCPLayoutGrid : public QCPLayout int mColumnSpacing, mRowSpacing; int mWrap; FillOrder mFillOrder; - + // non-virtual methods: void getMinimumRowColSizes(QVector *minColWidths, QVector *minRowHeights) const; void getMaximumRowColSizes(QVector *maxColWidths, QVector *maxRowHeights) const; - + private: Q_DISABLE_COPY(QCPLayoutGrid) }; @@ -1480,20 +1484,20 @@ class QCP_LIB_DECL QCPLayoutInset : public QCPLayout ,ipBorderAligned ///< The element is aligned to one of the layout sides, see \ref setInsetAlignment }; Q_ENUMS(InsetPlacement) - + explicit QCPLayoutInset(); virtual ~QCPLayoutInset() Q_DECL_OVERRIDE; - + // getters: InsetPlacement insetPlacement(int index) const; Qt::Alignment insetAlignment(int index) const; QRectF insetRect(int index) const; - + // setters: void setInsetPlacement(int index, InsetPlacement placement); void setInsetAlignment(int index, Qt::Alignment alignment); void setInsetRect(int index, const QRectF &rect); - + // reimplemented virtual methods: virtual void updateLayout() Q_DECL_OVERRIDE; virtual int elementCount() const Q_DECL_OVERRIDE; @@ -1502,18 +1506,18 @@ class QCP_LIB_DECL QCPLayoutInset : public QCPLayout virtual bool take(QCPLayoutElement* element) Q_DECL_OVERRIDE; virtual void simplify() Q_DECL_OVERRIDE {} virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; - + // non-virtual methods: void addElement(QCPLayoutElement *element, Qt::Alignment alignment); void addElement(QCPLayoutElement *element, const QRectF &rect); - + protected: // property members: QList mElements; QList mInsetPlacement; QList mInsetAlignment; QList mInsetRect; - + private: Q_DISABLE_COPY(QCPLayoutInset) }; @@ -1531,13 +1535,13 @@ class QCP_LIB_DECL QCPLineEnding public: /*! Defines the type of ending decoration for line-like items, e.g. an arrow. - + \image html QCPLineEnding.png - + The width and length of these decorations can be controlled with the functions \ref setWidth and \ref setLength. Some decorations like \ref esDisc, \ref esSquare, \ref esDiamond and \ref esBar only support a width, the length property is ignored. - + \see QCPItemLine::setHead, QCPItemLine::setTail, QCPItemCurve::setHead, QCPItemCurve::setTail, QCPAxis::setLowerEnding, QCPAxis::setUpperEnding */ enum EndingStyle { esNone ///< No ending decoration @@ -1552,28 +1556,28 @@ class QCP_LIB_DECL QCPLineEnding ,esSkewedBar ///< A bar that is skewed (skew controllable via \ref setLength) }; Q_ENUMS(EndingStyle) - + QCPLineEnding(); QCPLineEnding(EndingStyle style, double width=8, double length=10, bool inverted=false); - + // getters: EndingStyle style() const { return mStyle; } double width() const { return mWidth; } double length() const { return mLength; } bool inverted() const { return mInverted; } - + // setters: void setStyle(EndingStyle style); void setWidth(double width); void setLength(double length); void setInverted(bool inverted); - + // non-property methods: double boundingDistance() const; double realLength() const; void draw(QCPPainter *painter, const QCPVector2D &pos, const QCPVector2D &dir) const; void draw(QCPPainter *painter, const QCPVector2D &pos, double angle) const; - + protected: // property members: EndingStyle mStyle; @@ -1596,37 +1600,37 @@ class QCPLabelPainterPrivate /*! TODO */ - enum AnchorMode { amRectangular ///< + enum AnchorMode { amRectangular ///< ,amSkewedUpright ///< ,amSkewedRotated ///< }; Q_ENUMS(AnchorMode) - + /*! TODO */ - enum AnchorReferenceType { artNormal ///< + enum AnchorReferenceType { artNormal ///< ,artTangent ///< }; Q_ENUMS(AnchorReferenceType) - + /*! TODO */ - enum AnchorSide { asLeft ///< - ,asRight ///< - ,asTop ///< - ,asBottom ///< + enum AnchorSide { asLeft ///< + ,asRight ///< + ,asTop ///< + ,asBottom ///< ,asTopLeft ,asTopRight ,asBottomRight ,asBottomLeft }; Q_ENUMS(AnchorSide) - + explicit QCPLabelPainterPrivate(QCustomPlot *parentPlot); virtual ~QCPLabelPainterPrivate(); - + // setters: void setAnchorSide(AnchorSide side); void setAnchorMode(AnchorMode mode); @@ -1640,7 +1644,7 @@ class QCPLabelPainterPrivate void setMultiplicationSymbol(QChar symbol); void setAbbreviateDecimalPowers(bool enabled); void setCacheSize(int labelCount); - + // getters: AnchorMode anchorMode() const { return mAnchorMode; } AnchorSide anchorSide() const { return mAnchorSide; } @@ -1654,17 +1658,17 @@ class QCPLabelPainterPrivate QChar multiplicationSymbol() const { return mMultiplicationSymbol; } bool abbreviateDecimalPowers() const { return mAbbreviateDecimalPowers; } int cacheSize() const; - + //virtual int size() const; - - // non-property methods: + + // non-property methods: void drawTickLabel(QCPPainter *painter, const QPointF &tickPos, const QString &text); void clearCache(); - + // constants that may be used with setMultiplicationSymbol: static const QChar SymbolDot; static const QChar SymbolCross; - + protected: struct CachedLabel { @@ -1683,7 +1687,7 @@ class QCPLabelPainterPrivate QFont baseFont, expFont; QColor color; }; - + // property members: AnchorMode mAnchorMode; AnchorSide mAnchorSide; @@ -1702,7 +1706,7 @@ class QCPLabelPainterPrivate QCache mLabelCache; QRect mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox; int mLetterCapHeight, mLetterDescent; - + // introduced virtual methods: virtual void drawLabelMaybeCached(QCPPainter *painter, const QFont &font, const QColor &color, const QPointF &pos, AnchorSide side, double rotation, const QString &text); virtual QByteArray generateLabelParameterHash() const; // TODO: get rid of this in favor of invalidation flag upon setters? @@ -1735,7 +1739,7 @@ class QCP_LIB_DECL QCPAxisTicker public: /*! Defines the strategies that the axis ticker may follow when choosing the size of the tick step. - + \see setTickStepStrategy */ enum TickStepStrategy @@ -1744,29 +1748,29 @@ class QCP_LIB_DECL QCPAxisTicker ,tssMeetTickCount ///< Less readable tick steps are allowed which in turn facilitates getting closer to the requested tick count }; Q_ENUMS(TickStepStrategy) - + QCPAxisTicker(); virtual ~QCPAxisTicker(); - + // getters: TickStepStrategy tickStepStrategy() const { return mTickStepStrategy; } int tickCount() const { return mTickCount; } double tickOrigin() const { return mTickOrigin; } - + // setters: void setTickStepStrategy(TickStepStrategy strategy); void setTickCount(int count); void setTickOrigin(double origin); - + // introduced virtual methods: virtual void generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector &ticks, QVector *subTicks, QVector *tickLabels); - + protected: // property members: TickStepStrategy mTickStepStrategy; int mTickCount; double mTickOrigin; - + // introduced virtual methods: virtual double getTickStep(const QCPRange &range); virtual int getSubTickCount(double tickStep); @@ -1774,16 +1778,16 @@ class QCP_LIB_DECL QCPAxisTicker virtual QVector createTickVector(double tickStep, const QCPRange &range); virtual QVector createSubTickVector(int subTickCount, const QVector &ticks); virtual QVector createLabelVector(const QVector &ticks, const QLocale &locale, QChar formatChar, int precision); - + // non-virtual methods: void trimTicks(const QCPRange &range, QVector &ticks, bool keepOneOutlier) const; double pickClosest(double target, const QVector &candidates) const; double getMantissa(double input, double *magnitude=nullptr) const; double cleanMantissa(double input) const; - + private: Q_DISABLE_COPY(QCPAxisTicker) - + }; Q_DECLARE_METATYPE(QCPAxisTicker::TickStepStrategy) Q_DECLARE_METATYPE(QSharedPointer) @@ -1798,14 +1802,14 @@ class QCP_LIB_DECL QCPAxisTickerDateTime : public QCPAxisTicker { public: QCPAxisTickerDateTime(); - + // getters: QString dateTimeFormat() const { return mDateTimeFormat; } Qt::TimeSpec dateTimeSpec() const { return mDateTimeSpec; } # if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) QTimeZone timeZone() const { return mTimeZone; } #endif - + // setters: void setDateTimeFormat(const QString &format); void setDateTimeSpec(Qt::TimeSpec spec); @@ -1814,12 +1818,12 @@ class QCP_LIB_DECL QCPAxisTickerDateTime : public QCPAxisTicker # endif void setTickOrigin(double origin); // hides base class method but calls baseclass implementation ("using" throws off IDEs and doxygen) void setTickOrigin(const QDateTime &origin); - + // static methods: static QDateTime keyToDateTime(double key); static double dateTimeToKey(const QDateTime &dateTime); static double dateTimeToKey(const QDate &date, Qt::TimeSpec timeSpec=Qt::LocalTime); - + protected: // property members: QString mDateTimeFormat; @@ -1829,7 +1833,7 @@ class QCP_LIB_DECL QCPAxisTickerDateTime : public QCPAxisTicker # endif // non-property members: enum DateStrategy {dsNone, dsUniformTimeInDay, dsUniformDayInMonth} mDateStrategy; - + // reimplemented virtual methods: virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; @@ -1849,7 +1853,7 @@ class QCP_LIB_DECL QCPAxisTickerTime : public QCPAxisTicker public: /*! Defines the logical units in which fractions of time spans can be expressed. - + \see setFieldWidth, setTimeFormat */ enum TimeUnit { tuMilliseconds ///< Milliseconds, one thousandth of a second (%%z in \ref setTimeFormat) @@ -1859,31 +1863,31 @@ class QCP_LIB_DECL QCPAxisTickerTime : public QCPAxisTicker ,tuDays ///< Days (%%d in \ref setTimeFormat) }; Q_ENUMS(TimeUnit) - + QCPAxisTickerTime(); // getters: QString timeFormat() const { return mTimeFormat; } int fieldWidth(TimeUnit unit) const { return mFieldWidth.value(unit); } - + // setters: void setTimeFormat(const QString &format); void setFieldWidth(TimeUnit unit, int width); - + protected: // property members: QString mTimeFormat; QHash mFieldWidth; - + // non-property members: TimeUnit mSmallestUnit, mBiggestUnit; QHash mFormatPattern; - + // reimplemented virtual methods: virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; - + // non-virtual methods: void replaceUnit(QString &text, TimeUnit unit, int value) const; }; @@ -1902,7 +1906,7 @@ class QCP_LIB_DECL QCPAxisTickerFixed : public QCPAxisTicker /*! Defines how the axis ticker may modify the specified tick step (\ref setTickStep) in order to control the number of ticks in the axis range. - + \see setScaleStrategy */ enum ScaleStrategy { ssNone ///< Modifications are not allowed, the specified tick step is absolutely fixed. This might cause a high tick density and overlapping labels if the axis range is zoomed out. @@ -1910,22 +1914,22 @@ class QCP_LIB_DECL QCPAxisTickerFixed : public QCPAxisTicker ,ssPowers ///< An integer power of the specified tick step is allowed. }; Q_ENUMS(ScaleStrategy) - + QCPAxisTickerFixed(); - + // getters: double tickStep() const { return mTickStep; } ScaleStrategy scaleStrategy() const { return mScaleStrategy; } - + // setters: void setTickStep(double step); void setScaleStrategy(ScaleStrategy strategy); - + protected: // property members: double mTickStep; ScaleStrategy mScaleStrategy; - + // reimplemented virtual methods: virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; }; @@ -1941,27 +1945,27 @@ class QCP_LIB_DECL QCPAxisTickerText : public QCPAxisTicker { public: QCPAxisTickerText(); - + // getters: QMap &ticks() { return mTicks; } int subTickCount() const { return mSubTickCount; } - + // setters: void setTicks(const QMap &ticks); void setTicks(const QVector &positions, const QVector &labels); void setSubTickCount(int subTicks); - + // non-virtual methods: void clear(); void addTick(double position, const QString &label); void addTicks(const QMap &ticks); void addTicks(const QVector &positions, const QVector &labels); - + protected: // property members: QMap mTicks; int mSubTickCount; - + // reimplemented virtual methods: virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; @@ -1981,7 +1985,7 @@ class QCP_LIB_DECL QCPAxisTickerPi : public QCPAxisTicker public: /*! Defines how fractions should be displayed in tick labels. - + \see setFractionStyle */ enum FractionStyle { fsFloatingPoint ///< Fractions are displayed as regular decimal floating point numbers, e.g. "0.25" or "0.125". @@ -1989,36 +1993,36 @@ class QCP_LIB_DECL QCPAxisTickerPi : public QCPAxisTicker ,fsUnicodeFractions ///< Fractions are written using sub- and superscript UTF-8 digits and the fraction symbol. }; Q_ENUMS(FractionStyle) - + QCPAxisTickerPi(); - + // getters: QString piSymbol() const { return mPiSymbol; } double piValue() const { return mPiValue; } bool periodicity() const { return mPeriodicity; } FractionStyle fractionStyle() const { return mFractionStyle; } - + // setters: void setPiSymbol(QString symbol); void setPiValue(double pi); void setPeriodicity(int multiplesOfPi); void setFractionStyle(FractionStyle style); - + protected: // property members: QString mPiSymbol; double mPiValue; int mPeriodicity; FractionStyle mFractionStyle; - + // non-property members: double mPiTickStep; // size of one tick step in units of mPiValue - + // reimplemented virtual methods: virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; - + // non-virtual methods: void simplifyFraction(int &numerator, int &denominator) const; QString fractionToString(int numerator, int denominator) const; @@ -2038,23 +2042,23 @@ class QCP_LIB_DECL QCPAxisTickerLog : public QCPAxisTicker { public: QCPAxisTickerLog(); - + // getters: double logBase() const { return mLogBase; } int subTickCount() const { return mSubTickCount; } - + // setters: void setLogBase(double base); void setSubTickCount(int subTicks); - + protected: // property members: double mLogBase; int mSubTickCount; - + // non-property members: double mLogBaseLnInv; - + // reimplemented virtual methods: virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; virtual QVector createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE; @@ -2079,7 +2083,7 @@ class QCP_LIB_DECL QCPGrid :public QCPLayerable /// \endcond public: explicit QCPGrid(QCPAxis *parentAxis); - + // getters: bool subGridVisible() const { return mSubGridVisible; } bool antialiasedSubGrid() const { return mAntialiasedSubGrid; } @@ -2087,7 +2091,7 @@ class QCP_LIB_DECL QCPGrid :public QCPLayerable QPen pen() const { return mPen; } QPen subGridPen() const { return mSubGridPen; } QPen zeroLinePen() const { return mZeroLinePen; } - + // setters: void setSubGridVisible(bool visible); void setAntialiasedSubGrid(bool enabled); @@ -2095,24 +2099,24 @@ class QCP_LIB_DECL QCPGrid :public QCPLayerable void setPen(const QPen &pen); void setSubGridPen(const QPen &pen); void setZeroLinePen(const QPen &pen); - + protected: // property members: bool mSubGridVisible; bool mAntialiasedSubGrid, mAntialiasedZeroLine; QPen mPen, mSubGridPen, mZeroLinePen; - + // non-property members: QCPAxis *mParentAxis; - + // reimplemented virtual methods: virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - + // non-virtual methods: void drawGridLines(QCPPainter *painter) const; void drawSubGridLines(QCPPainter *painter) const; - + friend class QCPAxis; }; @@ -2180,7 +2184,7 @@ class QCP_LIB_DECL QCPAxis : public QCPLayerable Q_DECLARE_FLAGS(AxisTypes, AxisType) /*! Defines on which side of the axis the tick labels (numbers) shall appear. - + \see setTickLabelSide */ enum LabelSide { lsInside ///< Tick labels will be displayed inside the axis rect and clipped to the inner axis rect @@ -2207,10 +2211,10 @@ class QCP_LIB_DECL QCPAxis : public QCPLayerable Q_ENUMS(SelectablePart) Q_FLAGS(SelectableParts) Q_DECLARE_FLAGS(SelectableParts, SelectablePart) - + explicit QCPAxis(QCPAxisRect *parent, AxisType type); virtual ~QCPAxis() Q_DECL_OVERRIDE; - + // getters: AxisType axisType() const { return mAxisType; } QCPAxisRect *axisRect() const { return mAxisRect; } @@ -2255,7 +2259,7 @@ class QCP_LIB_DECL QCPAxis : public QCPLayerable QCPLineEnding lowerEnding() const; QCPLineEnding upperEnding() const; QCPGrid *grid() const { return mGrid; } - + // setters: Q_SLOT void setScaleType(QCPAxis::ScaleType type); Q_SLOT void setRange(const QCPRange &range); @@ -2301,10 +2305,10 @@ class QCP_LIB_DECL QCPAxis : public QCPLayerable Q_SLOT void setSelectedParts(const QCPAxis::SelectableParts &selectedParts); void setLowerEnding(const QCPLineEnding &ending); void setUpperEnding(const QCPLineEnding &ending); - + // reimplemented virtual methods: virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; - + // non-property methods: Qt::Orientation orientation() const { return mOrientation; } int pixelOrientation() const { return rangeReversed() != (orientation()==Qt::Vertical) ? -1 : 1; } @@ -2319,11 +2323,11 @@ class QCP_LIB_DECL QCPAxis : public QCPLayerable QList plottables() const; QList graphs() const; QList items() const; - + static AxisType marginSideToAxisType(QCP::MarginSide side); static Qt::Orientation orientation(AxisType type) { return type==atBottom || type==atTop ? Qt::Horizontal : Qt::Vertical; } static AxisType opposite(AxisType type); - + signals: void rangeChanged(const QCPRange &newRange); void rangeChanged(const QCPRange &newRange, const QCPRange &oldRange); @@ -2367,7 +2371,7 @@ class QCP_LIB_DECL QCPAxis : public QCPLayerable QCPRange mRange; bool mRangeReversed; ScaleType mScaleType; - + // non-property members: QCPGrid *mGrid; QCPAxisPainterPrivate *mAxisPainter; @@ -2380,10 +2384,10 @@ class QCP_LIB_DECL QCPAxis : public QCPLayerable bool mDragging; QCPRange mDragStartRange; QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; - + // introduced virtual methods: virtual int calculateMargin(); - + // reimplemented virtual methods: virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; @@ -2396,7 +2400,7 @@ class QCP_LIB_DECL QCPAxis : public QCPLayerable virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; - + // non-virtual methods: void setupTickVectors(); QPen getBasePen() const; @@ -2406,10 +2410,10 @@ class QCP_LIB_DECL QCPAxis : public QCPLayerable QFont getLabelFont() const; QColor getTickLabelColor() const; QColor getLabelColor() const; - + private: Q_DISABLE_COPY(QCPAxis) - + friend class QCustomPlot; friend class QCPGrid; friend class QCPAxisRect; @@ -2427,15 +2431,15 @@ class QCPAxisPainterPrivate public: explicit QCPAxisPainterPrivate(QCustomPlot *parentPlot); virtual ~QCPAxisPainterPrivate(); - + virtual void draw(QCPPainter *painter); virtual int size(); void clearCache(); - + QRect axisSelectionBox() const { return mAxisSelectionBox; } QRect tickLabelsSelectionBox() const { return mTickLabelsSelectionBox; } QRect labelSelectionBox() const { return mLabelSelectionBox; } - + // public property members: QCPAxis::AxisType type; QPen basePen; @@ -2457,11 +2461,11 @@ class QCPAxisPainterPrivate int offset; // directly accessed by QCPAxis setters/getters bool abbreviateDecimalPowers; bool reversedEndings; - + QVector subTickPositions; QVector tickPositions; QVector tickLabels; - + protected: struct CachedLabel { @@ -2478,9 +2482,9 @@ class QCPAxisPainterPrivate QByteArray mLabelParameterHash; // to determine whether mLabelCache needs to be cleared due to changed parameters QCache mLabelCache; QRect mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox; - + virtual QByteArray generateLabelParameterHash() const; - + virtual void placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize); virtual void drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const; virtual TickLabelData getTickLabelData(const QFont &font, const QString &text) const; @@ -2552,7 +2556,7 @@ class QCP_LIB_DECL QCPScatterStyle QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size); QCPScatterStyle(const QPixmap &pixmap); QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush=Qt::NoBrush, double size=6); - + // getters: double size() const { return mSize; } ScatterShape shape() const { return mShape; } @@ -2586,7 +2590,7 @@ class QCP_LIB_DECL QCPScatterStyle QBrush mBrush; QPixmap mPixmap; QPainterPath mCustomPath; - + // non-property members: bool mPenDefined; }; @@ -2615,17 +2619,17 @@ class QCPDataContainer // no QCP_LIB_DECL, template class ends up in header (cpp public: typedef typename QVector::const_iterator const_iterator; typedef typename QVector::iterator iterator; - + QCPDataContainer(); - + // getters: int size() const { return mData.size()-mPreallocSize; } bool isEmpty() const { return size() == 0; } bool autoSqueeze() const { return mAutoSqueeze; } - + // setters: void setAutoSqueeze(bool enabled); - + // non-virtual methods: void set(const QCPDataContainer &data); void set(const QVector &data, bool alreadySorted=false); @@ -2639,7 +2643,7 @@ class QCPDataContainer // no QCP_LIB_DECL, template class ends up in header (cpp void clear(); void sort(); void squeeze(bool preAllocation=true, bool postAllocation=true); - + const_iterator constBegin() const { return mData.constBegin()+mPreallocSize; } const_iterator constEnd() const { return mData.constEnd(); } iterator begin() { return mData.begin()+mPreallocSize; } @@ -2651,16 +2655,16 @@ class QCPDataContainer // no QCP_LIB_DECL, template class ends up in header (cpp QCPRange valueRange(bool &foundRange, QCP::SignDomain signDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()); QCPDataRange dataRange() const { return QCPDataRange(0, size()); } void limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const; - + protected: // property members: bool mAutoSqueeze; - + // non-property memebers: QVector mData; int mPreallocSize; int mPreallocIteration; - + // non-virtual methods: void preallocateGrow(int minimumPreallocSize); void performAutoSqueeze(); @@ -2743,27 +2747,27 @@ class QCPDataContainer // no QCP_LIB_DECL, template class ends up in header (cpp /* start documentation of inline functions */ /*! \fn int QCPDataContainer::size() const - + Returns the number of data points in the container. */ /*! \fn bool QCPDataContainer::isEmpty() const - + Returns whether this container holds no data points. */ /*! \fn QCPDataContainer::const_iterator QCPDataContainer::constBegin() const - + Returns a const iterator to the first data point in this container. */ /*! \fn QCPDataContainer::const_iterator QCPDataContainer::constEnd() const - + Returns a const iterator to the element past the last data point in this container. */ /*! \fn QCPDataContainer::iterator QCPDataContainer::begin() const - + Returns a non-const iterator to the first data point in this container. You can manipulate the data points in-place through the non-const iterators, but great care must @@ -2772,9 +2776,9 @@ class QCPDataContainer // no QCP_LIB_DECL, template class ends up in header (cpp */ /*! \fn QCPDataContainer::iterator QCPDataContainer::end() const - + Returns a non-const iterator to the element past the last data point in this container. - + You can manipulate the data points in-place through the non-const iterators, but great care must be taken when manipulating the sort key of a data point, see \ref sort, or the detailed description of this class. @@ -2814,7 +2818,7 @@ QCPDataContainer::QCPDataContainer() : Sets whether the container automatically decides when to release memory from its post- and preallocation pools when data points are removed. By default this is enabled and for typical applications shouldn't be changed. - + If auto squeeze is disabled, you can manually decide when to release pre-/postallocation with \ref squeeze. */ @@ -2830,9 +2834,9 @@ void QCPDataContainer::setAutoSqueeze(bool enabled) } /*! \overload - + Replaces the current data in this container with the provided \a data. - + \see add, remove */ template @@ -2843,12 +2847,12 @@ void QCPDataContainer::set(const QCPDataContainer &data) } /*! \overload - + Replaces the current data in this container with the provided \a data If you can guarantee that the data points in \a data have ascending order with respect to the DataType's sort key, set \a alreadySorted to true to avoid an unnecessary sorting run. - + \see add, remove */ template @@ -2862,9 +2866,9 @@ void QCPDataContainer::set(const QVector &data, bool already } /*! \overload - + Adds the provided \a data to the current data in this container. - + \see set, remove */ template @@ -2872,10 +2876,10 @@ void QCPDataContainer::add(const QCPDataContainer &data) { if (data.isEmpty()) return; - + const int n = data.size(); const int oldSize = size(); - + if (oldSize > 0 && !qcpLessThanSortKey(*constBegin(), *(data.constEnd()-1))) // prepend if new data keys are all smaller than or equal to existing ones { if (mPreallocSize < n) @@ -2893,10 +2897,10 @@ void QCPDataContainer::add(const QCPDataContainer &data) /*! Adds the provided data points in \a data to the current data. - + If you can guarantee that the data points in \a data have ascending order with respect to the DataType's sort key, set \a alreadySorted to true to avoid an unnecessary sorting run. - + \see set, remove */ template @@ -2909,10 +2913,10 @@ void QCPDataContainer::add(const QVector &data, bool already set(data, alreadySorted); return; } - + const int n = data.size(); const int oldSize = size(); - + if (alreadySorted && oldSize > 0 && !qcpLessThanSortKey(*constBegin(), *(data.constEnd()-1))) // prepend if new data is sorted and keys are all smaller than or equal to existing ones { if (mPreallocSize < n) @@ -2931,9 +2935,9 @@ void QCPDataContainer::add(const QVector &data, bool already } /*! \overload - + Adds the provided single data point to the current data. - + \see remove */ template @@ -2957,7 +2961,7 @@ void QCPDataContainer::add(const DataType &data) /*! Removes all data points with (sort-)keys smaller than or equal to \a sortKey. - + \see removeAfter, remove, clear */ template @@ -2989,7 +2993,7 @@ void QCPDataContainer::removeAfter(double sortKey) Removes all data points with (sort-)keys between \a sortKeyFrom and \a sortKeyTo. if \a sortKeyFrom is greater or equal to \a sortKeyTo, the function does nothing. To remove a single data point with known (sort-)key, use \ref remove(double sortKey). - + \see removeBefore, removeAfter, clear */ template @@ -2997,7 +3001,7 @@ void QCPDataContainer::remove(double sortKeyFrom, double sortKeyTo) { if (sortKeyFrom >= sortKeyTo || isEmpty()) return; - + QCPDataContainer::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKeyFrom), qcpLessThanSortKey); QCPDataContainer::iterator itEnd = std::upper_bound(it, end(), DataType::fromSortKey(sortKeyTo), qcpLessThanSortKey); mData.erase(it, itEnd); @@ -3006,12 +3010,12 @@ void QCPDataContainer::remove(double sortKeyFrom, double sortKeyTo) } /*! \overload - + Removes a single data point at \a sortKey. If the position is not known with absolute (binary) precision, consider using \ref remove(double sortKeyFrom, double sortKeyTo) with a small fuzziness interval around the suspected position, depeding on the precision with which the (sort-)key is known. - + \see removeBefore, removeAfter, clear */ template @@ -3031,7 +3035,7 @@ void QCPDataContainer::remove(double sortKey) /*! Removes all data points. - + \see remove, removeAfter, removeBefore */ template @@ -3061,11 +3065,11 @@ void QCPDataContainer::sort() /*! Frees all unused memory that is currently in the preallocation and postallocation pools. - + Note that QCPDataContainer automatically decides whether squeezing is necessary, if \ref setAutoSqueeze is left enabled. It should thus not be necessary to use this method for typical applications. - + The parameters \a preAllocation and \a postAllocation control whether pre- and/or post allocation should be freed, respectively. */ @@ -3106,7 +3110,7 @@ typename QCPDataContainer::const_iterator QCPDataContainer:: { if (isEmpty()) return constEnd(); - + QCPDataContainer::const_iterator it = std::lower_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); if (expandedRange && it != constBegin()) // also covers it == constEnd case, and we know --constEnd is valid because mData isn't empty --it; @@ -3133,7 +3137,7 @@ typename QCPDataContainer::const_iterator QCPDataContainer:: { if (isEmpty()) return constEnd(); - + QCPDataContainer::const_iterator it = std::upper_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); if (expandedRange && it != constEnd()) ++it; @@ -3145,14 +3149,14 @@ typename QCPDataContainer::const_iterator QCPDataContainer:: parameter \a foundRange indicates whether a sensible range was found. If this is false, you should not use the returned QCPRange (e.g. the data container is empty or all points have the same key). - + Use \a signDomain to control which sign of the key coordinates should be considered. This is relevant e.g. for logarithmic plots which can mathematically only display one sign domain at a time. - + If the DataType reports that its main key is equal to the sort key (\a sortKeyIsMainKey), as is the case for most plottables, this method uses this fact and finds the range very quickly. - + \see valueRange */ template @@ -3167,7 +3171,7 @@ QCPRange QCPDataContainer::keyRange(bool &foundRange, QCP::SignDomain bool haveLower = false; bool haveUpper = false; double current; - + QCPDataContainer::const_iterator it = constBegin(); QCPDataContainer::const_iterator itEnd = constEnd(); if (signDomain == QCP::sdBoth) // range may be anywhere @@ -3257,7 +3261,7 @@ QCPRange QCPDataContainer::keyRange(bool &foundRange, QCP::SignDomain ++it; } } - + foundRange = haveLower && haveUpper; return range; } @@ -3268,7 +3272,7 @@ QCPRange QCPDataContainer::keyRange(bool &foundRange, QCP::SignDomain output parameter \a foundRange indicates whether a sensible range was found. If this is false, you should not use the returned QCPRange (e.g. the data container is empty or all points have the same value). - + Inf and -Inf data values are ignored. If \a inKeyRange has both lower and upper bound set to zero (is equal to QCPRange()), @@ -3355,7 +3359,7 @@ QCPRange QCPDataContainer::valueRange(bool &foundRange, QCP::SignDomai } } } - + foundRange = haveLower && haveUpper; return range; } @@ -3364,7 +3368,7 @@ QCPRange QCPDataContainer::valueRange(bool &foundRange, QCP::SignDomai Makes sure \a begin and \a end mark a data range that is both within the bounds of this data container's data, as well as within the specified \a dataRange. The initial range described by the passed iterators \a begin and \a end is never expanded, only contracted if necessary. - + This function doesn't require for \a dataRange to be within the bounds of this data container's valid range. */ @@ -3378,11 +3382,11 @@ void QCPDataContainer::limitIteratorsToDataRange(const_iterator &begin } /*! \internal - + Increases the preallocation pool to have a size of at least \a minimumPreallocSize. Depending on the preallocation history, the container will grow by more than requested, to speed up future consecutive size increases. - + if \a minimumPreallocSize is smaller than or equal to the current preallocation pool size, this method does nothing. */ @@ -3391,11 +3395,11 @@ void QCPDataContainer::preallocateGrow(int minimumPreallocSize) { if (minimumPreallocSize <= mPreallocSize) return; - + int newPreallocSize = minimumPreallocSize; newPreallocSize += (1u<::preallocateGrow(int minimumPreallocSize) } /*! \internal - + This method decides, depending on the total allocation size and the size of the unused pre- and postallocation pools, whether it is sensible to reduce the pools in order to free up unused memory. It then possibly calls \ref squeeze to do the deallocation. - + If \ref setAutoSqueeze is enabled, this method is called automatically each time data points are removed from the container (e.g. \ref remove). - + \note when changing the decision parameters, care must be taken not to cause a back-and-forth between squeezing and reallocation due to the growth strategy of the internal QVector and \ref preallocateGrow. The hysteresis between allocation and deallocation should be made high enough @@ -3433,7 +3437,7 @@ void QCPDataContainer::performAutoSqueeze() shrinkPostAllocation = postAllocSize > usedSize*5; shrinkPreAllocation = mPreallocSize > usedSize*1.5; // preallocation can grow into postallocation, so can be smaller } - + if (shrinkPreAllocation || shrinkPostAllocation) squeeze(shrinkPreAllocation, shrinkPostAllocation); } @@ -3451,28 +3455,28 @@ class QCP_LIB_DECL QCPSelectionDecorator public: QCPSelectionDecorator(); virtual ~QCPSelectionDecorator(); - + // getters: QPen pen() const { return mPen; } QBrush brush() const { return mBrush; } QCPScatterStyle scatterStyle() const { return mScatterStyle; } QCPScatterStyle::ScatterProperties usedScatterProperties() const { return mUsedScatterProperties; } - + // setters: void setPen(const QPen &pen); void setBrush(const QBrush &brush); void setScatterStyle(const QCPScatterStyle &scatterStyle, QCPScatterStyle::ScatterProperties usedProperties=QCPScatterStyle::spPen); void setUsedScatterProperties(const QCPScatterStyle::ScatterProperties &properties); - + // non-virtual methods: void applyPen(QCPPainter *painter) const; void applyBrush(QCPPainter *painter) const; QCPScatterStyle getFinalScatterStyle(const QCPScatterStyle &unselectedStyle) const; - + // introduced virtual methods: virtual void copyFrom(const QCPSelectionDecorator *other); virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection); - + protected: // property members: QPen mPen; @@ -3481,10 +3485,10 @@ class QCP_LIB_DECL QCPSelectionDecorator QCPScatterStyle::ScatterProperties mUsedScatterProperties; // non-property members: QCPAbstractPlottable *mPlottable; - + // introduced virtual methods: virtual bool registerWithPlottable(QCPAbstractPlottable *plottable); - + private: Q_DISABLE_COPY(QCPSelectionDecorator) friend class QCPAbstractPlottable; @@ -3510,7 +3514,7 @@ class QCP_LIB_DECL QCPAbstractPlottable : public QCPLayerable public: QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis); virtual ~QCPAbstractPlottable() Q_DECL_OVERRIDE; - + // getters: QString name() const { return mName; } bool antialiasedFill() const { return mAntialiasedFill; } @@ -3523,7 +3527,7 @@ class QCP_LIB_DECL QCPAbstractPlottable : public QCPLayerable bool selected() const { return !mSelection.isEmpty(); } QCPDataSelection selection() const { return mSelection; } QCPSelectionDecorator *selectionDecorator() const { return mSelectionDecorator; } - + // setters: void setName(const QString &name); void setAntialiasedFill(bool enabled); @@ -3541,7 +3545,7 @@ class QCP_LIB_DECL QCPAbstractPlottable : public QCPLayerable virtual QCPPlottableInterface1D *interface1D() { return nullptr; } virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const = 0; virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const = 0; - + // non-property methods: void coordsToPixels(double key, double value, double &x, double &y) const; const QPointF coordsToPixels(double key, double value) const; @@ -3554,12 +3558,12 @@ class QCP_LIB_DECL QCPAbstractPlottable : public QCPLayerable bool addToLegend(); bool removeFromLegend(QCPLegend *legend) const; bool removeFromLegend() const; - + signals: void selectionChanged(bool selected); void selectionChanged(const QCPDataSelection &selection); void selectableChanged(QCP::SelectionType selectable); - + protected: // property members: QString mName; @@ -3570,7 +3574,7 @@ class QCP_LIB_DECL QCPAbstractPlottable : public QCPLayerable QCP::SelectionType mSelectable; QCPDataSelection mSelection; QCPSelectionDecorator *mSelectionDecorator; - + // reimplemented virtual methods: virtual QRect clipRect() const Q_DECL_OVERRIDE; virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; @@ -3579,17 +3583,17 @@ class QCP_LIB_DECL QCPAbstractPlottable : public QCPLayerable // events: virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; - + // introduced virtual methods: virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const = 0; - + // non-virtual methods: void applyFillAntialiasingHint(QCPPainter *painter) const; void applyScattersAntialiasingHint(QCPPainter *painter) const; private: Q_DISABLE_COPY(QCPAbstractPlottable) - + friend class QCustomPlot; friend class QCPAxis; friend class QCPPlottableLegendItem; @@ -3608,33 +3612,33 @@ class QCP_LIB_DECL QCPItemAnchor public: QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name, int anchorId=-1); virtual ~QCPItemAnchor(); - + // getters: QString name() const { return mName; } virtual QPointF pixelPosition() const; - + protected: // property members: QString mName; - + // non-property members: QCustomPlot *mParentPlot; QCPAbstractItem *mParentItem; int mAnchorId; QSet mChildrenX, mChildrenY; - + // introduced virtual methods: virtual QCPItemPosition *toQCPItemPosition() { return nullptr; } - + // non-virtual methods: void addChildX(QCPItemPosition* pos); // called from pos when this anchor is set as parent void removeChildX(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted void addChildY(QCPItemPosition* pos); // called from pos when this anchor is set as parent void removeChildY(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted - + private: Q_DISABLE_COPY(QCPItemAnchor) - + friend class QCPItemPosition; }; @@ -3647,7 +3651,7 @@ class QCP_LIB_DECL QCPItemPosition : public QCPItemAnchor /*! Defines the ways an item position can be specified. Thus it defines what the numbers passed to \ref setCoords actually mean. - + \see setType */ enum PositionType { ptAbsolute ///< Static positioning in pixels, starting from the top left corner of the viewport/widget. @@ -3660,10 +3664,10 @@ class QCP_LIB_DECL QCPItemPosition : public QCPItemAnchor ,ptPlotCoords ///< Dynamic positioning at a plot coordinate defined by two axes (see \ref setAxes). }; Q_ENUMS(PositionType) - + QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name); virtual ~QCPItemPosition() Q_DECL_OVERRIDE; - + // getters: PositionType type() const { return typeX(); } PositionType typeX() const { return mPositionTypeX; } @@ -3678,7 +3682,7 @@ class QCP_LIB_DECL QCPItemPosition : public QCPItemAnchor QCPAxis *valueAxis() const { return mValueAxis.data(); } QCPAxisRect *axisRect() const; virtual QPointF pixelPosition() const Q_DECL_OVERRIDE; - + // setters: void setType(PositionType type); void setTypeX(PositionType type); @@ -3691,7 +3695,7 @@ class QCP_LIB_DECL QCPItemPosition : public QCPItemAnchor void setAxes(QCPAxis* keyAxis, QCPAxis* valueAxis); void setAxisRect(QCPAxisRect *axisRect); void setPixelPosition(const QPointF &pixelPosition); - + protected: // property members: PositionType mPositionTypeX, mPositionTypeY; @@ -3699,13 +3703,13 @@ class QCP_LIB_DECL QCPItemPosition : public QCPItemAnchor QPointer mAxisRect; double mKey, mValue; QCPItemAnchor *mParentAnchorX, *mParentAnchorY; - + // reimplemented virtual methods: virtual QCPItemPosition *toQCPItemPosition() Q_DECL_OVERRIDE { return this; } - + private: Q_DISABLE_COPY(QCPItemPosition) - + }; Q_DECLARE_METATYPE(QCPItemPosition::PositionType) @@ -3722,33 +3726,33 @@ class QCP_LIB_DECL QCPAbstractItem : public QCPLayerable public: explicit QCPAbstractItem(QCustomPlot *parentPlot); virtual ~QCPAbstractItem() Q_DECL_OVERRIDE; - + // getters: bool clipToAxisRect() const { return mClipToAxisRect; } QCPAxisRect *clipAxisRect() const; bool selectable() const { return mSelectable; } bool selected() const { return mSelected; } - + // setters: void setClipToAxisRect(bool clip); void setClipAxisRect(QCPAxisRect *rect); Q_SLOT void setSelectable(bool selectable); Q_SLOT void setSelected(bool selected); - + // reimplemented virtual methods: virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE = 0; - + // non-virtual methods: QList positions() const { return mPositions; } QList anchors() const { return mAnchors; } QCPItemPosition *position(const QString &name) const; QCPItemAnchor *anchor(const QString &name) const; bool hasAnchor(const QString &name) const; - + signals: void selectionChanged(bool selected); void selectableChanged(bool selectable); - + protected: // property members: bool mClipToAxisRect; @@ -3756,7 +3760,7 @@ class QCP_LIB_DECL QCPAbstractItem : public QCPLayerable QList mPositions; QList mAnchors; bool mSelectable, mSelected; - + // reimplemented virtual methods: virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; virtual QRect clipRect() const Q_DECL_OVERRIDE; @@ -3765,18 +3769,18 @@ class QCP_LIB_DECL QCPAbstractItem : public QCPLayerable // events: virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; - + // introduced virtual methods: virtual QPointF anchorPixelPosition(int anchorId) const; - + // non-virtual methods: double rectDistance(const QRectF &rect, const QPointF &pos, bool filledRect) const; QCPItemPosition *createPosition(const QString &name); QCPItemAnchor *createAnchor(const QString &name, int anchorId); - + private: Q_DISABLE_COPY(QCPAbstractItem) - + friend class QCustomPlot; friend class QCPItemAnchor; }; @@ -3812,7 +3816,7 @@ class QCP_LIB_DECL QCustomPlot : public QWidget ,limAbove ///< Layer is inserted above other layer }; Q_ENUMS(LayerInsertMode) - + /*! Defines with what timing the QCustomPlot surface is refreshed after a replot. @@ -3824,10 +3828,10 @@ class QCP_LIB_DECL QCustomPlot : public QWidget ,rpQueuedReplot ///< Queues the entire replot for the next event loop iteration. This way multiple redundant replots can be avoided. The actual replot is then done with \ref rpRefreshHint priority. }; Q_ENUMS(RefreshPriority) - + explicit QCustomPlot(QWidget *parent = nullptr); virtual ~QCustomPlot() Q_DECL_OVERRIDE; - + // getters: QRect viewport() const { return mViewport; } double bufferDevicePixelRatio() const { return mBufferDevicePixelRatio; } @@ -3846,7 +3850,7 @@ class QCP_LIB_DECL QCustomPlot : public QWidget QCP::SelectionRectMode selectionRectMode() const { return mSelectionRectMode; } QCPSelectionRect *selectionRect() const { return mSelectionRect; } bool openGl() const { return mOpenGl; } - + // setters: void setViewport(const QRect &rect); void setBufferDevicePixelRatio(double ratio); @@ -3870,7 +3874,7 @@ class QCP_LIB_DECL QCustomPlot : public QWidget void setSelectionRectMode(QCP::SelectionRectMode mode); void setSelectionRect(QCPSelectionRect *selectionRect); void setOpenGl(bool enabled, int multisampling=16); - + // non-property methods: // plottable interface: QCPAbstractPlottable *plottable(int index); @@ -3884,7 +3888,7 @@ class QCP_LIB_DECL QCustomPlot : public QWidget PlottableType *plottableAt(const QPointF &pos, bool onlySelectable=false, int *dataIndex=nullptr) const; QCPAbstractPlottable *plottableAt(const QPointF &pos, bool onlySelectable=false, int *dataIndex=nullptr) const; bool hasPlottable(QCPAbstractPlottable *plottable) const; - + // specialized interface for QCPGraph: QCPGraph *graph(int index) const; QCPGraph *graph() const; @@ -3907,7 +3911,7 @@ class QCP_LIB_DECL QCustomPlot : public QWidget ItemType *itemAt(const QPointF &pos, bool onlySelectable=false) const; QCPAbstractItem *itemAt(const QPointF &pos, bool onlySelectable=false) const; bool hasItem(QCPAbstractItem *item) const; - + // layer interface: QCPLayer *layer(const QString &name) const; QCPLayer *layer(int index) const; @@ -3918,7 +3922,7 @@ class QCP_LIB_DECL QCustomPlot : public QWidget bool addLayer(const QString &name, QCPLayer *otherLayer=nullptr, LayerInsertMode insertMode=limAbove); bool removeLayer(QCPLayer *layer); bool moveLayer(QCPLayer *layer, QCPLayer *otherLayer, LayerInsertMode insertMode=limAbove); - + // axis rect/layout interface: int axisRectCount() const; QCPAxisRect* axisRect(int index=0) const; @@ -3926,11 +3930,11 @@ class QCP_LIB_DECL QCustomPlot : public QWidget QCPLayoutElement* layoutElementAt(const QPointF &pos) const; QCPAxisRect* axisRectAt(const QPointF &pos) const; Q_SLOT void rescaleAxes(bool onlyVisiblePlottables=false); - + QList selectedAxes() const; QList selectedLegends() const; Q_SLOT void deselectAll(); - + bool savePdf(const QString &fileName, int width=0, int height=0, QCP::ExportPen exportPen=QCP::epAllowCosmetic, const QString &pdfCreator=QString(), const QString &pdfTitle=QString()); bool savePng(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); bool saveJpg(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); @@ -3940,17 +3944,17 @@ class QCP_LIB_DECL QCustomPlot : public QWidget void toPainter(QCPPainter *painter, int width=0, int height=0); Q_SLOT void replot(QCustomPlot::RefreshPriority refreshPriority=QCustomPlot::rpRefreshHint); double replotTime(bool average=false) const; - + QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2; QCPLegend *legend; - + signals: void mouseDoubleClick(QMouseEvent *event); void mousePress(QMouseEvent *event); void mouseMove(QMouseEvent *event); void mouseRelease(QMouseEvent *event); void mouseWheel(QWheelEvent *event); - + void plottableClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event); void plottableDoubleClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event); void itemClick(QCPAbstractItem *item, QMouseEvent *event); @@ -3959,12 +3963,12 @@ class QCP_LIB_DECL QCustomPlot : public QWidget void axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); void legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); void legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); - + void selectionChangedByUser(); void beforeReplot(); void afterLayout(); void afterReplot(); - + protected: // property members: QRect mViewport; @@ -3990,7 +3994,7 @@ class QCP_LIB_DECL QCustomPlot : public QWidget QCP::SelectionRectMode mSelectionRectMode; QCPSelectionRect *mSelectionRect; bool mOpenGl; - + // non-property members: QList > mPaintBuffers; QPoint mMousePressPos; @@ -4010,7 +4014,7 @@ class QCP_LIB_DECL QCustomPlot : public QWidget QSharedPointer mGlSurface; QSharedPointer mGlPaintDevice; #endif - + // reimplemented virtual methods: virtual QSize minimumSizeHint() const Q_DECL_OVERRIDE; virtual QSize sizeHint() const Q_DECL_OVERRIDE; @@ -4021,7 +4025,7 @@ class QCP_LIB_DECL QCustomPlot : public QWidget virtual void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; virtual void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; - + // introduced virtual methods: virtual void draw(QCPPainter *painter); virtual void updateLayout(); @@ -4030,7 +4034,7 @@ class QCP_LIB_DECL QCustomPlot : public QWidget Q_SLOT virtual void processRectSelection(QRect rect, QMouseEvent *event); Q_SLOT virtual void processRectZoom(QRect rect, QMouseEvent *event); Q_SLOT virtual void processPointSelection(QMouseEvent *event); - + // non-virtual methods: bool registerPlottable(QCPAbstractPlottable *plottable); bool registerGraph(QCPGraph *graph); @@ -4044,7 +4048,7 @@ class QCP_LIB_DECL QCustomPlot : public QWidget bool hasInvalidatedPaintBuffers(); bool setupOpenGl(); void freeOpenGl(); - + friend class QCPLegend; friend class QCPAxis; friend class QCPLayer; @@ -4066,15 +4070,15 @@ Q_DECLARE_METATYPE(QCustomPlot::RefreshPriority) Plottables that only consist of single lines (like graphs) have a tolerance band around them, see \ref setSelectionTolerance. If multiple plottables come into consideration, the one closest to \a pos is returned. - + If \a onlySelectable is true, only plottables that are selectable (QCPAbstractPlottable::setSelectable) are considered. - + if \a dataIndex is non-null, it is set to the index of the plottable's data point that is closest to \a pos. If there is no plottable of the specified type at \a pos, returns \c nullptr. - + \see itemAt, layoutElementAt */ template @@ -4083,7 +4087,7 @@ PlottableType *QCustomPlot::plottableAt(const QPointF &pos, bool onlySelectable, PlottableType *resultPlottable = 0; QVariant resultDetails; double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value - + foreach (QCPAbstractPlottable *plottable, mPlottables) { PlottableType *currentPlottable = qobject_cast(plottable); @@ -4101,7 +4105,7 @@ PlottableType *QCustomPlot::plottableAt(const QPointF &pos, bool onlySelectable, } } } - + if (resultPlottable && dataIndex) { QCPDataSelection sel = resultDetails.value(); @@ -4116,12 +4120,12 @@ PlottableType *QCustomPlot::plottableAt(const QPointF &pos, bool onlySelectable, taken into consideration can be specified via the template parameter. Items that only consist of single lines (e.g. \ref QCPItemLine or \ref QCPItemCurve) have a tolerance band around them, see \ref setSelectionTolerance. If multiple items come into consideration, the one closest to \a pos is returned. - + If \a onlySelectable is true, only items that are selectable (QCPAbstractItem::setSelectable) are considered. - + If there is no item at \a pos, returns \c nullptr. - + \see plottableAt, layoutElementAt */ template @@ -4129,7 +4133,7 @@ ItemType *QCustomPlot::itemAt(const QPointF &pos, bool onlySelectable) const { ItemType *resultItem = 0; double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value - + foreach (QCPAbstractItem *item, mItems) { ItemType *currentItem = qobject_cast(item); @@ -4145,7 +4149,7 @@ ItemType *QCustomPlot::itemAt(const QPointF &pos, bool onlySelectable) const } } } - + return resultItem; } @@ -4178,11 +4182,11 @@ template class QCPAbstractPlottable1D : public QCPAbstractPlottable, public QCPPlottableInterface1D // no QCP_LIB_DECL, template class ends up in header (cpp included below) { // No Q_OBJECT macro due to template class - + public: QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis); virtual ~QCPAbstractPlottable1D() Q_DECL_OVERRIDE; - + // virtual methods of 1d plottable interface: virtual int dataCount() const Q_DECL_OVERRIDE; virtual double dataMainKey(int index) const Q_DECL_OVERRIDE; @@ -4194,22 +4198,22 @@ class QCPAbstractPlottable1D : public QCPAbstractPlottable, public QCPPlottableI virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; virtual int findBegin(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; virtual int findEnd(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; - + // reimplemented virtual methods: virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; virtual QCPPlottableInterface1D *interface1D() Q_DECL_OVERRIDE { return this; } - + protected: // property members: QSharedPointer > mDataContainer; - + // helpers for subclasses: void getDataSegments(QList &selectedSegments, QList &unselectedSegments) const; void drawPolyline(QCPPainter *painter, const QVector &lineData) const; private: Q_DISABLE_COPY(QCPAbstractPlottable1D) - + }; @@ -4245,55 +4249,55 @@ class QCPAbstractPlottable1D : public QCPAbstractPlottable, public QCPPlottableI /* start documentation of pure virtual functions */ /*! \fn virtual int QCPPlottableInterface1D::dataCount() const = 0; - + Returns the number of data points of the plottable. */ /*! \fn virtual QCPDataSelection QCPPlottableInterface1D::selectTestRect(const QRectF &rect, bool onlySelectable) const = 0; - + Returns a data selection containing all the data points of this plottable which are contained (or hit by) \a rect. This is used mainly in the selection rect interaction for data selection (\ref dataselection "data selection mechanism"). - + If \a onlySelectable is true, an empty QCPDataSelection is returned if this plottable is not selectable (i.e. if \ref QCPAbstractPlottable::setSelectable is \ref QCP::stNone). - + \note \a rect must be a normalized rect (positive or zero width and height). This is especially important when using the rect of \ref QCPSelectionRect::accepted, which is not necessarily normalized. Use QRect::normalized() when passing a rect which might not be normalized. */ /*! \fn virtual double QCPPlottableInterface1D::dataMainKey(int index) const = 0 - + Returns the main key of the data point at the given \a index. - + What the main key is, is defined by the plottable's data type. See the \ref qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming convention. */ /*! \fn virtual double QCPPlottableInterface1D::dataSortKey(int index) const = 0 - + Returns the sort key of the data point at the given \a index. - + What the sort key is, is defined by the plottable's data type. See the \ref qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming convention. */ /*! \fn virtual double QCPPlottableInterface1D::dataMainValue(int index) const = 0 - + Returns the main value of the data point at the given \a index. - + What the main value is, is defined by the plottable's data type. See the \ref qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming convention. */ /*! \fn virtual QCPRange QCPPlottableInterface1D::dataValueRange(int index) const = 0 - + Returns the value range of the data point at the given \a index. - + What the value range is, is defined by the plottable's data type. See the \ref qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming convention. @@ -4387,10 +4391,10 @@ class QCPAbstractPlottable1D : public QCPAbstractPlottable, public QCPPlottableI /* start documentation of inline functions */ /*! \fn QCPPlottableInterface1D *QCPAbstractPlottable1D::interface1D() - + Returns a \ref QCPPlottableInterface1D pointer to this plottable, providing access to its 1D interface. - + \seebaseclassmethod */ @@ -4526,7 +4530,7 @@ QCPDataSelection QCPAbstractPlottable1D::selectTestRect(const QRectF & return result; if (!mKeyAxis || !mValueAxis) return result; - + // convert rect given in pixels to ranges given in plot coordinates: double key1, value1, key2, value2; pixelsToCoords(rect.topLeft(), key1, value1); @@ -4542,7 +4546,7 @@ QCPDataSelection QCPAbstractPlottable1D::selectTestRect(const QRectF & } if (begin == end) return result; - + int currentSegmentBegin = -1; // -1 means we're currently not in a segment that's contained in rect for (typename QCPDataContainer::const_iterator it=begin; it!=end; ++it) { @@ -4559,7 +4563,7 @@ QCPDataSelection QCPAbstractPlottable1D::selectTestRect(const QRectF & // process potential last segment: if (currentSegmentBegin != -1) result.addDataRange(QCPDataRange(currentSegmentBegin, int(end-mDataContainer->constBegin())), false); - + result.simplify(); return result; } @@ -4589,7 +4593,7 @@ int QCPAbstractPlottable1D::findEnd(double sortKey, bool expandedRange If \a details is not 0, it will be set to a \ref QCPDataSelection, describing the closest data point to \a pos. - + \seebaseclassmethod */ template @@ -4599,11 +4603,11 @@ double QCPAbstractPlottable1D::selectTest(const QPointF &pos, bool onl return -1; if (!mKeyAxis || !mValueAxis) return -1; - + QCPDataSelection selectionResult; double minDistSqr = (std::numeric_limits::max)(); int minDistIndex = mDataContainer->size(); - + typename QCPDataContainer::const_iterator begin = mDataContainer->constBegin(); typename QCPDataContainer::const_iterator end = mDataContainer->constEnd(); if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval: @@ -4637,7 +4641,7 @@ double QCPAbstractPlottable1D::selectTest(const QPointF &pos, bool onl } if (minDistIndex != mDataContainer->size()) selectionResult.addDataRange(QCPDataRange(minDistIndex, minDistIndex+1), false); - + selectionResult.simplify(); if (details) details->setValue(selectionResult); @@ -4755,17 +4759,17 @@ class QCP_LIB_DECL QCPColorGradient public: /*! Defines the color spaces in which color interpolation between gradient stops can be performed. - + \see setColorInterpolation */ enum ColorInterpolation { ciRGB ///< Color channels red, green and blue are linearly interpolated ,ciHSV ///< Color channels hue, saturation and value are linearly interpolated (The hue is interpolated over the shortest angle distance) }; Q_ENUMS(ColorInterpolation) - + /*! Defines how NaN data points shall appear in the plot. - + \see setNanHandling, setNanColor */ enum NanHandling { nhNone ///< NaN data points are not explicitly handled and shouldn't occur in the data (this gives slight performance improvement) @@ -4775,7 +4779,7 @@ class QCP_LIB_DECL QCPColorGradient ,nhNanColor ///< NaN data points appear as the color defined with \ref setNanColor }; Q_ENUMS(NanHandling) - + /*! Defines the available presets that can be loaded with \ref loadPreset. See the documentation there for an image of the presets. @@ -4794,12 +4798,12 @@ class QCP_LIB_DECL QCPColorGradient ,gpHues ///< Full hue cycle, with highest and lowest color red (suitable for periodic data, such as angles and phases, see \ref setPeriodic) }; Q_ENUMS(GradientPreset) - + QCPColorGradient(); QCPColorGradient(GradientPreset preset); bool operator==(const QCPColorGradient &other) const; bool operator!=(const QCPColorGradient &other) const { return !(*this == other); } - + // getters: int levelCount() const { return mLevelCount; } QMap colorStops() const { return mColorStops; } @@ -4807,7 +4811,7 @@ class QCP_LIB_DECL QCPColorGradient NanHandling nanHandling() const { return mNanHandling; } QColor nanColor() const { return mNanColor; } bool periodic() const { return mPeriodic; } - + // setters: void setLevelCount(int n); void setColorStops(const QMap &colorStops); @@ -4816,7 +4820,7 @@ class QCP_LIB_DECL QCPColorGradient void setNanHandling(NanHandling handling); void setNanColor(const QColor &color); void setPeriodic(bool enabled); - + // non-property methods: void colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false); void colorize(const double *data, const unsigned char *alpha, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false); @@ -4824,7 +4828,7 @@ class QCP_LIB_DECL QCPColorGradient void loadPreset(GradientPreset preset); void clearColorStops(); QCPColorGradient inverted() const; - + protected: // property members: int mLevelCount; @@ -4833,11 +4837,11 @@ class QCP_LIB_DECL QCPColorGradient NanHandling mNanHandling; QColor mNanColor; bool mPeriodic; - + // non-property members: QVector mColorBuffer; // have colors premultiplied with alpha (for usage with QImage::Format_ARGB32_Premultiplied) bool mColorBufferInvalidated; - + // non-virtual methods: bool stopsUseAlpha() const; void updateColorBuffer(); @@ -4856,10 +4860,10 @@ class QCP_LIB_DECL QCPSelectionDecoratorBracket : public QCPSelectionDecorator { Q_GADGET public: - + /*! Defines which shape is drawn at the boundaries of selected data ranges. - + Some of the bracket styles further allow specifying a height and/or width, see \ref setBracketHeight and \ref setBracketWidth. */ @@ -4870,10 +4874,10 @@ class QCP_LIB_DECL QCPSelectionDecoratorBracket : public QCPSelectionDecorator ,bsUserStyle ///< Start custom bracket styles at this index when subclassing and reimplementing \ref drawBracket. }; Q_ENUMS(BracketStyle) - + QCPSelectionDecoratorBracket(); virtual ~QCPSelectionDecoratorBracket() Q_DECL_OVERRIDE; - + // getters: QPen bracketPen() const { return mBracketPen; } QBrush bracketBrush() const { return mBracketBrush; } @@ -4882,7 +4886,7 @@ class QCP_LIB_DECL QCPSelectionDecoratorBracket : public QCPSelectionDecorator BracketStyle bracketStyle() const { return mBracketStyle; } bool tangentToData() const { return mTangentToData; } int tangentAverage() const { return mTangentAverage; } - + // setters: void setBracketPen(const QPen &pen); void setBracketBrush(const QBrush &brush); @@ -4891,13 +4895,13 @@ class QCP_LIB_DECL QCPSelectionDecoratorBracket : public QCPSelectionDecorator void setBracketStyle(BracketStyle style); void setTangentToData(bool enabled); void setTangentAverage(int pointCount); - + // introduced virtual methods: virtual void drawBracket(QCPPainter *painter, int direction) const; - + // virtual methods: virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection) Q_DECL_OVERRIDE; - + protected: // property members: QPen mBracketPen; @@ -4907,11 +4911,11 @@ class QCP_LIB_DECL QCPSelectionDecoratorBracket : public QCPSelectionDecorator BracketStyle mBracketStyle; bool mTangentToData; int mTangentAverage; - + // non-virtual methods: double getTangentAngle(const QCPPlottableInterface1D *interface1d, int dataIndex, int direction) const; QPointF getPixelCoordinates(const QCPPlottableInterface1D *interface1d, int dataIndex) const; - + }; Q_DECLARE_METATYPE(QCPSelectionDecoratorBracket::BracketStyle) @@ -4934,7 +4938,7 @@ class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement public: explicit QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes=true); virtual ~QCPAxisRect() Q_DECL_OVERRIDE; - + // getters: QPixmap background() const { return mBackgroundPixmap; } QBrush backgroundBrush() const { return mBackgroundBrush; } @@ -4947,7 +4951,7 @@ class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement QList rangeDragAxes(Qt::Orientation orientation); QList rangeZoomAxes(Qt::Orientation orientation); double rangeZoomFactor(Qt::Orientation orientation); - + // setters: void setBackground(const QPixmap &pm); void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); @@ -4964,7 +4968,7 @@ class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement void setRangeZoomAxes(QList horizontal, QList vertical); void setRangeZoomFactor(double horizontalFactor, double verticalFactor); void setRangeZoomFactor(double factor); - + // non-property methods: int axisCount(QCPAxis::AxisType type) const; QCPAxis *axis(QCPAxis::AxisType type, int index=0) const; @@ -4974,14 +4978,14 @@ class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement QList addAxes(QCPAxis::AxisTypes types); bool removeAxis(QCPAxis *axis); QCPLayoutInset *insetLayout() const { return mInsetLayout; } - + void zoom(const QRectF &pixelRect); void zoom(const QRectF &pixelRect, const QList &affectedAxes); void setupFullAxesBox(bool connectRanges=false); QList plottables() const; QList graphs() const; QList items() const; - + // read-only interface imitating a QRect: int left() const { return mRect.left(); } int right() const { return mRect.right(); } @@ -4995,7 +4999,7 @@ class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement QPoint bottomLeft() const { return mRect.bottomLeft(); } QPoint bottomRight() const { return mRect.bottomRight(); } QPoint center() const { return mRect.center(); } - + // reimplemented virtual methods: virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; @@ -5012,13 +5016,13 @@ class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement QList > mRangeDragHorzAxis, mRangeDragVertAxis; QList > mRangeZoomHorzAxis, mRangeZoomVertAxis; double mRangeZoomFactorHorz, mRangeZoomFactorVert; - + // non-property members: QList mDragStartHorzRange, mDragStartVertRange; QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; bool mDragging; QHash > mAxes; - + // reimplemented virtual methods: virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; @@ -5029,14 +5033,14 @@ class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; - + // non-property methods: void drawBackground(QCPPainter *painter); void updateAxesOffset(QCPAxis::AxisType type); - + private: Q_DISABLE_COPY(QCPAxisRect) - + friend class QCustomPlot; }; @@ -5061,7 +5065,7 @@ class QCP_LIB_DECL QCPAbstractLegendItem : public QCPLayoutElement /// \endcond public: explicit QCPAbstractLegendItem(QCPLegend *parent); - + // getters: QCPLegend *parentLegend() const { return mParentLegend; } QFont font() const { return mFont; } @@ -5070,7 +5074,7 @@ class QCP_LIB_DECL QCPAbstractLegendItem : public QCPLayoutElement QColor selectedTextColor() const { return mSelectedTextColor; } bool selectable() const { return mSelectable; } bool selected() const { return mSelected; } - + // setters: void setFont(const QFont &font); void setTextColor(const QColor &color); @@ -5078,14 +5082,14 @@ class QCP_LIB_DECL QCPAbstractLegendItem : public QCPLayoutElement void setSelectedTextColor(const QColor &color); Q_SLOT void setSelectable(bool selectable); Q_SLOT void setSelected(bool selected); - + // reimplemented virtual methods: virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; - + signals: void selectionChanged(bool selected); void selectableChanged(bool selectable); - + protected: // property members: QCPLegend *mParentLegend; @@ -5094,7 +5098,7 @@ class QCP_LIB_DECL QCPAbstractLegendItem : public QCPLayoutElement QFont mSelectedFont; QColor mSelectedTextColor; bool mSelectable, mSelected; - + // reimplemented virtual methods: virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; @@ -5103,10 +5107,10 @@ class QCP_LIB_DECL QCPAbstractLegendItem : public QCPLayoutElement // events: virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; - + private: Q_DISABLE_COPY(QCPAbstractLegendItem) - + friend class QCPLegend; }; @@ -5116,18 +5120,18 @@ class QCP_LIB_DECL QCPPlottableLegendItem : public QCPAbstractLegendItem Q_OBJECT public: QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable); - + // getters: QCPAbstractPlottable *plottable() { return mPlottable; } - + protected: // property members: QCPAbstractPlottable *mPlottable; - + // reimplemented virtual methods: virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE; - + // non-virtual methods: QPen getIconBorderPen() const; QColor getTextColor() const; @@ -5157,7 +5161,7 @@ class QCP_LIB_DECL QCPLegend : public QCPLayoutGrid public: /*! Defines the selectable parts of a legend - + \see setSelectedParts, setSelectableParts */ enum SelectablePart { spNone = 0x000 ///< 0x000 None @@ -5167,10 +5171,10 @@ class QCP_LIB_DECL QCPLegend : public QCPLayoutGrid Q_ENUMS(SelectablePart) Q_FLAGS(SelectableParts) Q_DECLARE_FLAGS(SelectableParts, SelectablePart) - + explicit QCPLegend(); virtual ~QCPLegend() Q_DECL_OVERRIDE; - + // getters: QPen borderPen() const { return mBorderPen; } QBrush brush() const { return mBrush; } @@ -5186,7 +5190,7 @@ class QCP_LIB_DECL QCPLegend : public QCPLayoutGrid QBrush selectedBrush() const { return mSelectedBrush; } QFont selectedFont() const { return mSelectedFont; } QColor selectedTextColor() const { return mSelectedTextColor; } - + // setters: void setBorderPen(const QPen &pen); void setBrush(const QBrush &brush); @@ -5203,10 +5207,10 @@ class QCP_LIB_DECL QCPLegend : public QCPLayoutGrid void setSelectedBrush(const QBrush &brush); void setSelectedFont(const QFont &font); void setSelectedTextColor(const QColor &color); - + // reimplemented virtual methods: virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; - + // non-virtual methods: QCPAbstractLegendItem *item(int index) const; QCPPlottableLegendItem *itemWithPlottable(const QCPAbstractPlottable *plottable) const; @@ -5218,11 +5222,11 @@ class QCP_LIB_DECL QCPLegend : public QCPLayoutGrid bool removeItem(QCPAbstractLegendItem *item); void clearItems(); QList selectedItems() const; - + signals: void selectionChanged(QCPLegend::SelectableParts parts); void selectableChanged(QCPLegend::SelectableParts parts); - + protected: // property members: QPen mBorderPen, mIconBorderPen; @@ -5236,7 +5240,7 @@ class QCP_LIB_DECL QCPLegend : public QCPLayoutGrid QBrush mSelectedBrush; QFont mSelectedFont; QColor mSelectedTextColor; - + // reimplemented virtual methods: virtual void parentPlotInitialized(QCustomPlot *parentPlot) Q_DECL_OVERRIDE; virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; @@ -5245,14 +5249,14 @@ class QCP_LIB_DECL QCPLegend : public QCPLayoutGrid // events: virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; - + // non-virtual methods: QPen getBorderPen() const; QBrush getBrush() const; - + private: Q_DISABLE_COPY(QCPLegend) - + friend class QCustomPlot; friend class QCPAbstractLegendItem; }; @@ -5283,7 +5287,7 @@ class QCP_LIB_DECL QCPTextElement : public QCPLayoutElement QCPTextElement(QCustomPlot *parentPlot, const QString &text, double pointSize); QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QString &fontFamily, double pointSize); QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QFont &font); - + // getters: QString text() const { return mText; } int textFlags() const { return mTextFlags; } @@ -5293,7 +5297,7 @@ class QCP_LIB_DECL QCPTextElement : public QCPLayoutElement QColor selectedTextColor() const { return mSelectedTextColor; } bool selectable() const { return mSelectable; } bool selected() const { return mSelected; } - + // setters: void setText(const QString &text); void setTextFlags(int flags); @@ -5303,19 +5307,19 @@ class QCP_LIB_DECL QCPTextElement : public QCPLayoutElement void setSelectedTextColor(const QColor &color); Q_SLOT void setSelectable(bool selectable); Q_SLOT void setSelected(bool selected); - + // reimplemented virtual methods: virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; virtual void mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; - + signals: void selectionChanged(bool selected); void selectableChanged(bool selectable); void clicked(QMouseEvent *event); void doubleClicked(QMouseEvent *event); - + protected: // property members: QString mText; @@ -5326,7 +5330,7 @@ class QCP_LIB_DECL QCPTextElement : public QCPLayoutElement QColor mSelectedTextColor; QRect mTextBoundingRect; bool mSelectable, mSelected; - + // reimplemented virtual methods: virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; @@ -5335,11 +5339,11 @@ class QCP_LIB_DECL QCPTextElement : public QCPLayoutElement // events: virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; - + // non-virtual methods: QFont mainFont() const; QColor mainTextColor() const; - + private: Q_DISABLE_COPY(QCPTextElement) }; @@ -5393,7 +5397,7 @@ class QCP_LIB_DECL QCPColorScale : public QCPLayoutElement public: explicit QCPColorScale(QCustomPlot *parentPlot); virtual ~QCPColorScale() Q_DECL_OVERRIDE; - + // getters: QCPAxis *axis() const { return mColorAxis.data(); } QCPAxis::AxisType type() const { return mType; } @@ -5404,7 +5408,7 @@ class QCP_LIB_DECL QCPColorScale : public QCPLayoutElement int barWidth () const { return mBarWidth; } bool rangeDrag() const; bool rangeZoom() const; - + // setters: void setType(QCPAxis::AxisType type); Q_SLOT void setDataRange(const QCPRange &dataRange); @@ -5414,14 +5418,14 @@ class QCP_LIB_DECL QCPColorScale : public QCPLayoutElement void setBarWidth(int width); void setRangeDrag(bool enabled); void setRangeZoom(bool enabled); - + // non-property methods: QList colorMaps() const; void rescaleDataRange(bool onlyVisibleMaps); - + // reimplemented virtual methods: virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; - + signals: void dataRangeChanged(const QCPRange &newRange); void dataScaleTypeChanged(QCPAxis::ScaleType scaleType); @@ -5434,11 +5438,11 @@ class QCP_LIB_DECL QCPColorScale : public QCPLayoutElement QCPAxis::ScaleType mDataScaleType; QCPColorGradient mGradient; int mBarWidth; - + // non-property members: QPointer mAxisRect; QPointer mColorAxis; - + // reimplemented virtual methods: virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; // events: @@ -5446,10 +5450,10 @@ class QCP_LIB_DECL QCPColorScale : public QCPLayoutElement virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; - + private: Q_DISABLE_COPY(QCPColorScale) - + friend class QCPColorScaleAxisRectPrivate; }; @@ -5465,28 +5469,28 @@ class QCP_LIB_DECL QCPGraphData public: QCPGraphData(); QCPGraphData(double key, double value); - + inline double sortKey() const { return key; } inline static QCPGraphData fromSortKey(double sortKey) { return QCPGraphData(sortKey, 0); } inline static bool sortKeyIsMainKey() { return true; } - + inline double mainKey() const { return key; } inline double mainValue() const { return value; } - + inline QCPRange valueRange() const { return QCPRange(value, value); } - + double key, value; }; Q_DECLARE_TYPEINFO(QCPGraphData, Q_PRIMITIVE_TYPE); /*! \typedef QCPGraphDataContainer - + Container for storing \ref QCPGraphData points. The data is stored sorted by \a key. - + This template instantiation is the container in which QCPGraph holds its data. For details about the generic container, see the documentation of the class template \ref QCPDataContainer. - + \see QCPGraphData, QCPGraph::setData */ typedef QCPDataContainer QCPGraphDataContainer; @@ -5516,10 +5520,10 @@ class QCP_LIB_DECL QCPGraph : public QCPAbstractPlottable1D ,lsImpulse ///< each data point is represented by a line parallel to the value axis, which reaches from the data point to the zero-value-line }; Q_ENUMS(LineStyle) - + explicit QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis); virtual ~QCPGraph() Q_DECL_OVERRIDE; - + // getters: QSharedPointer data() const { return mDataContainer; } LineStyle lineStyle() const { return mLineStyle; } @@ -5527,7 +5531,7 @@ class QCP_LIB_DECL QCPGraph : public QCPAbstractPlottable1D int scatterSkip() const { return mScatterSkip; } QCPGraph *channelFillGraph() const { return mChannelFillGraph.data(); } bool adaptiveSampling() const { return mAdaptiveSampling; } - + // setters: void setData(QSharedPointer data); void setData(const QVector &keys, const QVector &values, bool alreadySorted=false); @@ -5536,16 +5540,16 @@ class QCP_LIB_DECL QCPGraph : public QCPAbstractPlottable1D void setScatterSkip(int skip); void setChannelFillGraph(QCPGraph *targetGraph); void setAdaptiveSampling(bool enabled); - + // non-property methods: void addData(const QVector &keys, const QVector &values, bool alreadySorted=false); void addData(double key, double value); - + // reimplemented virtual methods: virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; - + protected: // property members: LineStyle mLineStyle; @@ -5553,20 +5557,20 @@ class QCP_LIB_DECL QCPGraph : public QCPAbstractPlottable1D int mScatterSkip; QPointer mChannelFillGraph; bool mAdaptiveSampling; - + // reimplemented virtual methods: virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; - + // introduced virtual methods: virtual void drawFill(QCPPainter *painter, QVector *lines) const; virtual void drawScatterPlot(QCPPainter *painter, const QVector &scatters, const QCPScatterStyle &style) const; virtual void drawLinePlot(QCPPainter *painter, const QVector &lines) const; virtual void drawImpulsePlot(QCPPainter *painter, const QVector &lines) const; - + virtual void getOptimizedLineData(QVector *lineData, const QCPGraphDataContainer::const_iterator &begin, const QCPGraphDataContainer::const_iterator &end) const; virtual void getOptimizedScatterData(QVector *scatterData, QCPGraphDataContainer::const_iterator begin, QCPGraphDataContainer::const_iterator end) const; - + // non-virtual methods: void getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin, QCPGraphDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const; void getLines(QVector *lines, const QCPDataRange &dataRange) const; @@ -5587,7 +5591,7 @@ class QCP_LIB_DECL QCPGraph : public QCPAbstractPlottable1D int findIndexBelowY(const QVector *data, double y) const; int findIndexAboveY(const QVector *data, double y) const; double pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer::const_iterator &closestData) const; - + friend class QCustomPlot; friend class QCPLegend; }; @@ -5604,29 +5608,29 @@ class QCP_LIB_DECL QCPCurveData public: QCPCurveData(); QCPCurveData(double t, double key, double value); - + inline double sortKey() const { return t; } inline static QCPCurveData fromSortKey(double sortKey) { return QCPCurveData(sortKey, 0, 0); } inline static bool sortKeyIsMainKey() { return false; } - + inline double mainKey() const { return key; } inline double mainValue() const { return value; } - + inline QCPRange valueRange() const { return QCPRange(value, value); } - + double t, key, value; }; Q_DECLARE_TYPEINFO(QCPCurveData, Q_PRIMITIVE_TYPE); /*! \typedef QCPCurveDataContainer - + Container for storing \ref QCPCurveData points. The data is stored sorted by \a t, so the \a sortKey() (returning \a t) is different from \a mainKey() (returning \a key). - + This template instantiation is the container in which QCPCurve holds its data. For details about the generic container, see the documentation of the class template \ref QCPDataContainer. - + \see QCPCurveData, QCPCurve::setData */ typedef QCPDataContainer QCPCurveDataContainer; @@ -5649,16 +5653,16 @@ class QCP_LIB_DECL QCPCurve : public QCPAbstractPlottable1D ,lsLine ///< Data points are connected with a straight line }; Q_ENUMS(LineStyle) - + explicit QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis); virtual ~QCPCurve() Q_DECL_OVERRIDE; - + // getters: QSharedPointer data() const { return mDataContainer; } QCPScatterStyle scatterStyle() const { return mScatterStyle; } int scatterSkip() const { return mScatterSkip; } LineStyle lineStyle() const { return mLineStyle; } - + // setters: void setData(QSharedPointer data); void setData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted=false); @@ -5666,32 +5670,32 @@ class QCP_LIB_DECL QCPCurve : public QCPAbstractPlottable1D void setScatterStyle(const QCPScatterStyle &style); void setScatterSkip(int skip); void setLineStyle(LineStyle style); - + // non-property methods: void addData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted=false); void addData(const QVector &keys, const QVector &values); void addData(double t, double key, double value); void addData(double key, double value); - + // reimplemented virtual methods: virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; - + protected: // property members: QCPScatterStyle mScatterStyle; int mScatterSkip; LineStyle mLineStyle; - + // reimplemented virtual methods: virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; - + // introduced virtual methods: virtual void drawCurveLine(QCPPainter *painter, const QVector &lines) const; virtual void drawScatterPlot(QCPPainter *painter, const QVector &points, const QCPScatterStyle &style) const; - + // non-virtual methods: void getCurveLines(QVector *lines, const QCPDataRange &dataRange, double penWidth) const; void getScatters(QVector *scatters, const QCPDataRange &dataRange, double scatterWidth) const; @@ -5702,7 +5706,7 @@ class QCP_LIB_DECL QCPCurve : public QCPAbstractPlottable1D bool getTraverse(double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin, QPointF &crossA, QPointF &crossB) const; void getTraverseCornerPoints(int prevRegion, int currentRegion, double keyMin, double valueMax, double keyMax, double valueMin, QVector &beforeTraverse, QVector &afterTraverse) const; double pointDistance(const QPointF &pixelPoint, QCPCurveDataContainer::const_iterator &closestData) const; - + friend class QCustomPlot; friend class QCPLegend; }; @@ -5725,7 +5729,7 @@ class QCP_LIB_DECL QCPBarsGroup : public QObject /*! Defines the ways the spacing between bars in the group can be specified. Thus it defines what the number passed to \ref setSpacing actually means. - + \see setSpacingType, setSpacing */ enum SpacingType { stAbsolute ///< Bar spacing is in absolute pixels @@ -5733,18 +5737,18 @@ class QCP_LIB_DECL QCPBarsGroup : public QObject ,stPlotCoords ///< Bar spacing is in key coordinates and thus scales with the key axis range }; Q_ENUMS(SpacingType) - + explicit QCPBarsGroup(QCustomPlot *parentPlot); virtual ~QCPBarsGroup(); - + // getters: SpacingType spacingType() const { return mSpacingType; } double spacing() const { return mSpacing; } - + // setters: void setSpacingType(SpacingType spacingType); void setSpacing(double spacing); - + // non-virtual methods: QList bars() const { return mBars; } QCPBars* bars(int index) const; @@ -5755,25 +5759,25 @@ class QCP_LIB_DECL QCPBarsGroup : public QObject void append(QCPBars *bars); void insert(int i, QCPBars *bars); void remove(QCPBars *bars); - + protected: // non-property members: QCustomPlot *mParentPlot; SpacingType mSpacingType; double mSpacing; QList mBars; - + // non-virtual methods: void registerBars(QCPBars *bars); void unregisterBars(QCPBars *bars); - + // virtual methods: double keyPixelOffset(const QCPBars *bars, double keyCoord); double getPixelSpacing(const QCPBars *bars, double keyCoord); - + private: Q_DISABLE_COPY(QCPBarsGroup) - + friend class QCPBars; }; Q_DECLARE_METATYPE(QCPBarsGroup::SpacingType) @@ -5784,28 +5788,28 @@ class QCP_LIB_DECL QCPBarsData public: QCPBarsData(); QCPBarsData(double key, double value); - + inline double sortKey() const { return key; } inline static QCPBarsData fromSortKey(double sortKey) { return QCPBarsData(sortKey, 0); } - inline static bool sortKeyIsMainKey() { return true; } - + inline static bool sortKeyIsMainKey() { return true; } + inline double mainKey() const { return key; } inline double mainValue() const { return value; } - + inline QCPRange valueRange() const { return QCPRange(value, value); } // note that bar base value isn't held in each QCPBarsData and thus can't/shouldn't be returned here - + double key, value; }; Q_DECLARE_TYPEINFO(QCPBarsData, Q_PRIMITIVE_TYPE); /*! \typedef QCPBarsDataContainer - + Container for storing \ref QCPBarsData points. The data is stored sorted by \a key. - + This template instantiation is the container in which QCPBars holds its data. For details about the generic container, see the documentation of the class template \ref QCPDataContainer. - + \see QCPBarsData, QCPBars::setData */ typedef QCPDataContainer QCPBarsDataContainer; @@ -5826,7 +5830,7 @@ class QCP_LIB_DECL QCPBars : public QCPAbstractPlottable1D /*! Defines the ways the width of the bar can be specified. Thus it defines what the number passed to \ref setWidth actually means. - + \see setWidthType, setWidth */ enum WidthType { wtAbsolute ///< Bar width is in absolute pixels @@ -5834,10 +5838,10 @@ class QCP_LIB_DECL QCPBars : public QCPAbstractPlottable1D ,wtPlotCoords ///< Bar width is in key coordinates and thus scales with the key axis range }; Q_ENUMS(WidthType) - + explicit QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis); virtual ~QCPBars() Q_DECL_OVERRIDE; - + // getters: double width() const { return mWidth; } WidthType widthType() const { return mWidthType; } @@ -5847,7 +5851,7 @@ class QCP_LIB_DECL QCPBars : public QCPAbstractPlottable1D QCPBars *barBelow() const { return mBarBelow.data(); } QCPBars *barAbove() const { return mBarAbove.data(); } QSharedPointer data() const { return mDataContainer; } - + // setters: void setData(QSharedPointer data); void setData(const QVector &keys, const QVector &values, bool alreadySorted=false); @@ -5856,20 +5860,20 @@ class QCP_LIB_DECL QCPBars : public QCPAbstractPlottable1D void setBarsGroup(QCPBarsGroup *barsGroup); void setBaseValue(double baseValue); void setStackingGap(double pixels); - + // non-property methods: void addData(const QVector &keys, const QVector &values, bool alreadySorted=false); void addData(double key, double value); void moveBelow(QCPBars *bars); void moveAbove(QCPBars *bars); - + // reimplemented virtual methods: virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; - + protected: // property members: double mWidth; @@ -5878,18 +5882,18 @@ class QCP_LIB_DECL QCPBars : public QCPAbstractPlottable1D double mBaseValue; double mStackingGap; QPointer mBarBelow, mBarAbove; - + // reimplemented virtual methods: virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; - + // non-virtual methods: void getVisibleDataBounds(QCPBarsDataContainer::const_iterator &begin, QCPBarsDataContainer::const_iterator &end) const; QRectF getBarRect(double key, double value) const; void getPixelWidth(double key, double &lower, double &upper) const; double getStackedBaseValue(double key, bool positive) const; static void connectBars(QCPBars* lower, QCPBars* upper); - + friend class QCustomPlot; friend class QCPLegend; friend class QCPBarsGroup; @@ -5907,14 +5911,14 @@ class QCP_LIB_DECL QCPStatisticalBoxData public: QCPStatisticalBoxData(); QCPStatisticalBoxData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector& outliers=QVector()); - + inline double sortKey() const { return key; } inline static QCPStatisticalBoxData fromSortKey(double sortKey) { return QCPStatisticalBoxData(sortKey, 0, 0, 0, 0, 0); } inline static bool sortKeyIsMainKey() { return true; } - + inline double mainKey() const { return key; } inline double mainValue() const { return median; } - + inline QCPRange valueRange() const { QCPRange result(minimum, maximum); @@ -5922,7 +5926,7 @@ class QCP_LIB_DECL QCPStatisticalBoxData result.expand(*it); return result; } - + double key, minimum, lowerQuartile, median, upperQuartile, maximum; QVector outliers; }; @@ -5930,13 +5934,13 @@ Q_DECLARE_TYPEINFO(QCPStatisticalBoxData, Q_MOVABLE_TYPE); /*! \typedef QCPStatisticalBoxDataContainer - + Container for storing \ref QCPStatisticalBoxData points. The data is stored sorted by \a key. - + This template instantiation is the container in which QCPStatisticalBox holds its data. For details about the generic container, see the documentation of the class template \ref QCPDataContainer. - + \see QCPStatisticalBoxData, QCPStatisticalBox::setData */ typedef QCPDataContainer QCPStatisticalBoxDataContainer; @@ -5955,7 +5959,7 @@ class QCP_LIB_DECL QCPStatisticalBox : public QCPAbstractPlottable1D data() const { return mDataContainer; } double width() const { return mWidth; } @@ -5976,17 +5980,17 @@ class QCP_LIB_DECL QCPStatisticalBox : public QCPAbstractPlottable1D &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted=false); void addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers=QVector()); - + // reimplemented virtual methods: virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; - + protected: // property members: double mWidth; @@ -5995,20 +5999,20 @@ class QCP_LIB_DECL QCPStatisticalBox : public QCPAbstractPlottable1D getWhiskerBackboneLines(QCPStatisticalBoxDataContainer::const_iterator it) const; QVector getWhiskerBarLines(QCPStatisticalBoxDataContainer::const_iterator it) const; - + friend class QCustomPlot; friend class QCPLegend; }; @@ -6026,7 +6030,7 @@ class QCP_LIB_DECL QCPColorMapData ~QCPColorMapData(); QCPColorMapData(const QCPColorMapData &other); QCPColorMapData &operator=(const QCPColorMapData &other); - + // getters: int keySize() const { return mKeySize; } int valueSize() const { return mValueSize; } @@ -6036,7 +6040,7 @@ class QCP_LIB_DECL QCPColorMapData double data(double key, double value); double cell(int keyIndex, int valueIndex); unsigned char alpha(int keyIndex, int valueIndex); - + // setters: void setSize(int keySize, int valueSize); void setKeySize(int keySize); @@ -6047,7 +6051,7 @@ class QCP_LIB_DECL QCPColorMapData void setData(double key, double value, double z); void setCell(int keyIndex, int valueIndex, double z); void setAlpha(int keyIndex, int valueIndex, unsigned char alpha); - + // non-property methods: void recalculateDataBounds(); void clear(); @@ -6057,21 +6061,21 @@ class QCP_LIB_DECL QCPColorMapData bool isEmpty() const { return mIsEmpty; } void coordToCell(double key, double value, int *keyIndex, int *valueIndex) const; void cellToCoord(int keyIndex, int valueIndex, double *key, double *value) const; - + protected: // property members: int mKeySize, mValueSize; QCPRange mKeyRange, mValueRange; bool mIsEmpty; - + // non-property members: double *mData; unsigned char *mAlpha; QCPRange mDataBounds; bool mDataModified; - + bool createAlpha(bool initializeOpaque=true); - + friend class QCPColorMap; }; @@ -6090,7 +6094,7 @@ class QCP_LIB_DECL QCPColorMap : public QCPAbstractPlottable public: explicit QCPColorMap(QCPAxis *keyAxis, QCPAxis *valueAxis); virtual ~QCPColorMap() Q_DECL_OVERRIDE; - + // getters: QCPColorMapData *data() const { return mMapData; } QCPRange dataRange() const { return mDataRange; } @@ -6099,7 +6103,7 @@ class QCP_LIB_DECL QCPColorMap : public QCPAbstractPlottable bool tightBoundary() const { return mTightBoundary; } QCPColorGradient gradient() const { return mGradient; } QCPColorScale *colorScale() const { return mColorScale.data(); } - + // setters: void setData(QCPColorMapData *data, bool copy=false); Q_SLOT void setDataRange(const QCPRange &dataRange); @@ -6108,21 +6112,21 @@ class QCP_LIB_DECL QCPColorMap : public QCPAbstractPlottable void setInterpolate(bool enabled); void setTightBoundary(bool enabled); void setColorScale(QCPColorScale *colorScale); - + // non-property methods: void rescaleDataRange(bool recalculateDataBounds=false); Q_SLOT void updateLegendIcon(Qt::TransformationMode transformMode=Qt::SmoothTransformation, const QSize &thumbSize=QSize(32, 18)); - + // reimplemented virtual methods: virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; - + signals: void dataRangeChanged(const QCPRange &newRange); void dataScaleTypeChanged(QCPAxis::ScaleType scaleType); void gradientChanged(const QCPColorGradient &newGradient); - + protected: // property members: QCPRange mDataRange; @@ -6132,19 +6136,19 @@ class QCP_LIB_DECL QCPColorMap : public QCPAbstractPlottable bool mInterpolate; bool mTightBoundary; QPointer mColorScale; - + // non-property members: QImage mMapImage, mUndersampledMapImage; QPixmap mLegendIcon; bool mMapImageInvalidated; - + // introduced virtual methods: virtual void updateMapImage(); - + // reimplemented virtual methods: virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; - + friend class QCustomPlot; friend class QCPLegend; }; @@ -6160,28 +6164,28 @@ class QCP_LIB_DECL QCPFinancialData public: QCPFinancialData(); QCPFinancialData(double key, double open, double high, double low, double close); - + inline double sortKey() const { return key; } inline static QCPFinancialData fromSortKey(double sortKey) { return QCPFinancialData(sortKey, 0, 0, 0, 0); } - inline static bool sortKeyIsMainKey() { return true; } - + inline static bool sortKeyIsMainKey() { return true; } + inline double mainKey() const { return key; } inline double mainValue() const { return open; } - + inline QCPRange valueRange() const { return QCPRange(low, high); } // open and close must lie between low and high, so we don't need to check them - + double key, open, high, low, close; }; Q_DECLARE_TYPEINFO(QCPFinancialData, Q_PRIMITIVE_TYPE); /*! \typedef QCPFinancialDataContainer - + Container for storing \ref QCPFinancialData points. The data is stored sorted by \a key. - + This template instantiation is the container in which QCPFinancial holds its data. For details about the generic container, see the documentation of the class template \ref QCPDataContainer. - + \see QCPFinancialData, QCPFinancial::setData */ typedef QCPDataContainer QCPFinancialDataContainer; @@ -6211,20 +6215,20 @@ class QCP_LIB_DECL QCPFinancial : public QCPAbstractPlottable1D data() const { return mDataContainer; } ChartStyle chartStyle() const { return mChartStyle; } @@ -6235,7 +6239,7 @@ class QCP_LIB_DECL QCPFinancial : public QCPAbstractPlottable1D data); void setData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted=false); @@ -6247,20 +6251,20 @@ class QCP_LIB_DECL QCPFinancial : public QCPAbstractPlottable1D &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted=false); void addData(double key, double open, double high, double low, double close); - + // reimplemented virtual methods: virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; - + // static methods: static QCPFinancialDataContainer timeSeriesToOhlc(const QVector &time, const QVector &value, double timeBinSize, double timeBinOffset = 0); - + protected: // property members: ChartStyle mChartStyle; @@ -6269,11 +6273,11 @@ class QCP_LIB_DECL QCPFinancial : public QCPAbstractPlottable1D data); void setData(const QVector &error); @@ -6363,13 +6367,13 @@ class QCP_LIB_DECL QCPErrorBars : public QCPAbstractPlottable, public QCPPlottab void setErrorType(ErrorType type); void setWhiskerWidth(double pixels); void setSymbolGap(double pixels); - + // non-property methods: void addData(const QVector &error); void addData(const QVector &errorMinus, const QVector &errorPlus); void addData(double error); void addData(double errorMinus, double errorPlus); - + // virtual methods of 1d plottable interface: virtual int dataCount() const Q_DECL_OVERRIDE; virtual double dataMainKey(int index) const Q_DECL_OVERRIDE; @@ -6381,11 +6385,11 @@ class QCP_LIB_DECL QCPErrorBars : public QCPAbstractPlottable, public QCPPlottab virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; virtual int findBegin(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; virtual int findEnd(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; - + // reimplemented virtual methods: virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; virtual QCPPlottableInterface1D *interface1D() Q_DECL_OVERRIDE { return this; } - + protected: // property members: QSharedPointer mDataContainer; @@ -6393,13 +6397,13 @@ class QCP_LIB_DECL QCPErrorBars : public QCPAbstractPlottable, public QCPPlottab ErrorType mErrorType; double mWhiskerWidth; double mSymbolGap; - + // reimplemented virtual methods: virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; - + // non-virtual methods: void getErrorBarLines(QCPErrorBarsDataContainer::const_iterator it, QVector &backbones, QVector &whiskers) const; void getVisibleDataBounds(QCPErrorBarsDataContainer::const_iterator &begin, QCPErrorBarsDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const; @@ -6408,7 +6412,7 @@ class QCP_LIB_DECL QCPErrorBars : public QCPAbstractPlottable, public QCPPlottab void getDataSegments(QList &selectedSegments, QList &unselectedSegments) const; bool errorBarVisible(int index) const; bool rectIntersectsLine(const QRectF &pixelRect, const QLineF &line) const; - + friend class QCustomPlot; friend class QCPLegend; }; @@ -6429,28 +6433,28 @@ class QCP_LIB_DECL QCPItemStraightLine : public QCPAbstractItem public: explicit QCPItemStraightLine(QCustomPlot *parentPlot); virtual ~QCPItemStraightLine() Q_DECL_OVERRIDE; - + // getters: QPen pen() const { return mPen; } QPen selectedPen() const { return mSelectedPen; } - + // setters; void setPen(const QPen &pen); void setSelectedPen(const QPen &pen); - + // reimplemented virtual methods: virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; - + QCPItemPosition * const point1; QCPItemPosition * const point2; - + protected: // property members: QPen mPen, mSelectedPen; - + // reimplemented virtual methods: virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - + // non-virtual methods: QLineF getRectClippedStraightLine(const QCPVector2D &base, const QCPVector2D &vec, const QRect &rect) const; QPen mainPen() const; @@ -6474,33 +6478,33 @@ class QCP_LIB_DECL QCPItemLine : public QCPAbstractItem public: explicit QCPItemLine(QCustomPlot *parentPlot); virtual ~QCPItemLine() Q_DECL_OVERRIDE; - + // getters: QPen pen() const { return mPen; } QPen selectedPen() const { return mSelectedPen; } QCPLineEnding head() const { return mHead; } QCPLineEnding tail() const { return mTail; } - + // setters; void setPen(const QPen &pen); void setSelectedPen(const QPen &pen); void setHead(const QCPLineEnding &head); void setTail(const QCPLineEnding &tail); - + // reimplemented virtual methods: virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; - + QCPItemPosition * const start; QCPItemPosition * const end; - + protected: // property members: QPen mPen, mSelectedPen; QCPLineEnding mHead, mTail; - + // reimplemented virtual methods: virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - + // non-virtual methods: QLineF getRectClippedLine(const QCPVector2D &start, const QCPVector2D &end, const QRect &rect) const; QPen mainPen() const; @@ -6524,35 +6528,35 @@ class QCP_LIB_DECL QCPItemCurve : public QCPAbstractItem public: explicit QCPItemCurve(QCustomPlot *parentPlot); virtual ~QCPItemCurve() Q_DECL_OVERRIDE; - + // getters: QPen pen() const { return mPen; } QPen selectedPen() const { return mSelectedPen; } QCPLineEnding head() const { return mHead; } QCPLineEnding tail() const { return mTail; } - + // setters; void setPen(const QPen &pen); void setSelectedPen(const QPen &pen); void setHead(const QCPLineEnding &head); void setTail(const QCPLineEnding &tail); - + // reimplemented virtual methods: virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; - + QCPItemPosition * const start; QCPItemPosition * const startDir; QCPItemPosition * const endDir; QCPItemPosition * const end; - + protected: // property members: QPen mPen, mSelectedPen; QCPLineEnding mHead, mTail; - + // reimplemented virtual methods: virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - + // non-virtual methods: QPen mainPen() const; }; @@ -6575,22 +6579,22 @@ class QCP_LIB_DECL QCPItemRect : public QCPAbstractItem public: explicit QCPItemRect(QCustomPlot *parentPlot); virtual ~QCPItemRect() Q_DECL_OVERRIDE; - + // getters: QPen pen() const { return mPen; } QPen selectedPen() const { return mSelectedPen; } QBrush brush() const { return mBrush; } QBrush selectedBrush() const { return mSelectedBrush; } - + // setters; void setPen(const QPen &pen); void setSelectedPen(const QPen &pen); void setBrush(const QBrush &brush); void setSelectedBrush(const QBrush &brush); - + // reimplemented virtual methods: virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; - + QCPItemPosition * const topLeft; QCPItemPosition * const bottomRight; QCPItemAnchor * const top; @@ -6599,18 +6603,18 @@ class QCP_LIB_DECL QCPItemRect : public QCPAbstractItem QCPItemAnchor * const bottom; QCPItemAnchor * const bottomLeft; QCPItemAnchor * const left; - + protected: enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft}; - + // property members: QPen mPen, mSelectedPen; QBrush mBrush, mSelectedBrush; - + // reimplemented virtual methods: virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; - + // non-virtual methods: QPen mainPen() const; QBrush mainBrush() const; @@ -6643,7 +6647,7 @@ class QCP_LIB_DECL QCPItemText : public QCPAbstractItem public: explicit QCPItemText(QCustomPlot *parentPlot); virtual ~QCPItemText() Q_DECL_OVERRIDE; - + // getters: QColor color() const { return mColor; } QColor selectedColor() const { return mSelectedColor; } @@ -6658,7 +6662,7 @@ class QCP_LIB_DECL QCPItemText : public QCPAbstractItem Qt::Alignment textAlignment() const { return mTextAlignment; } double rotation() const { return mRotation; } QMargins padding() const { return mPadding; } - + // setters; void setColor(const QColor &color); void setSelectedColor(const QColor &color); @@ -6673,10 +6677,10 @@ class QCP_LIB_DECL QCPItemText : public QCPAbstractItem void setTextAlignment(Qt::Alignment alignment); void setRotation(double degrees); void setPadding(const QMargins &padding); - + // reimplemented virtual methods: virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; - + QCPItemPosition * const position; QCPItemAnchor * const topLeft; QCPItemAnchor * const top; @@ -6686,10 +6690,10 @@ class QCP_LIB_DECL QCPItemText : public QCPAbstractItem QCPItemAnchor * const bottom; QCPItemAnchor * const bottomLeft; QCPItemAnchor * const left; - + protected: enum AnchorIndex {aiTopLeft, aiTop, aiTopRight, aiRight, aiBottomRight, aiBottom, aiBottomLeft, aiLeft}; - + // property members: QColor mColor, mSelectedColor; QPen mPen, mSelectedPen; @@ -6700,11 +6704,11 @@ class QCP_LIB_DECL QCPItemText : public QCPAbstractItem Qt::Alignment mTextAlignment; double mRotation; QMargins mPadding; - + // reimplemented virtual methods: virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; - + // non-virtual methods: QPointF getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const; QFont mainFont() const; @@ -6731,22 +6735,22 @@ class QCP_LIB_DECL QCPItemEllipse : public QCPAbstractItem public: explicit QCPItemEllipse(QCustomPlot *parentPlot); virtual ~QCPItemEllipse() Q_DECL_OVERRIDE; - + // getters: QPen pen() const { return mPen; } QPen selectedPen() const { return mSelectedPen; } QBrush brush() const { return mBrush; } QBrush selectedBrush() const { return mSelectedBrush; } - + // setters; void setPen(const QPen &pen); void setSelectedPen(const QPen &pen); void setBrush(const QBrush &brush); void setSelectedBrush(const QBrush &brush); - + // reimplemented virtual methods: virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; - + QCPItemPosition * const topLeft; QCPItemPosition * const bottomRight; QCPItemAnchor * const topLeftRim; @@ -6758,18 +6762,18 @@ class QCP_LIB_DECL QCPItemEllipse : public QCPAbstractItem QCPItemAnchor * const bottomLeftRim; QCPItemAnchor * const left; QCPItemAnchor * const center; - + protected: enum AnchorIndex {aiTopLeftRim, aiTop, aiTopRightRim, aiRight, aiBottomRightRim, aiBottom, aiBottomLeftRim, aiLeft, aiCenter}; - + // property members: QPen mPen, mSelectedPen; QBrush mBrush, mSelectedBrush; - + // reimplemented virtual methods: virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; - + // non-virtual methods: QPen mainPen() const; QBrush mainBrush() const; @@ -6795,7 +6799,7 @@ class QCP_LIB_DECL QCPItemPixmap : public QCPAbstractItem public: explicit QCPItemPixmap(QCustomPlot *parentPlot); virtual ~QCPItemPixmap() Q_DECL_OVERRIDE; - + // getters: QPixmap pixmap() const { return mPixmap; } bool scaled() const { return mScaled; } @@ -6803,16 +6807,16 @@ class QCP_LIB_DECL QCPItemPixmap : public QCPAbstractItem Qt::TransformationMode transformationMode() const { return mTransformationMode; } QPen pen() const { return mPen; } QPen selectedPen() const { return mSelectedPen; } - + // setters; void setPixmap(const QPixmap &pixmap); void setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode=Qt::KeepAspectRatio, Qt::TransformationMode transformationMode=Qt::SmoothTransformation); void setPen(const QPen &pen); void setSelectedPen(const QPen &pen); - + // reimplemented virtual methods: virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; - + QCPItemPosition * const topLeft; QCPItemPosition * const bottomRight; QCPItemAnchor * const top; @@ -6821,10 +6825,10 @@ class QCP_LIB_DECL QCPItemPixmap : public QCPAbstractItem QCPItemAnchor * const bottom; QCPItemAnchor * const bottomLeft; QCPItemAnchor * const left; - + protected: enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft}; - + // property members: QPixmap mPixmap; QPixmap mScaledPixmap; @@ -6833,11 +6837,11 @@ class QCP_LIB_DECL QCPItemPixmap : public QCPAbstractItem Qt::AspectRatioMode mAspectRatioMode; Qt::TransformationMode mTransformationMode; QPen mPen, mSelectedPen; - + // reimplemented virtual methods: virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; - + // non-virtual methods: void updateScaledPixmap(QRect finalRect=QRect(), bool flipHorz=false, bool flipVert=false); QRect getFinalRect(bool *flippedHorz=nullptr, bool *flippedVert=nullptr) const; @@ -6867,7 +6871,7 @@ class QCP_LIB_DECL QCPItemTracer : public QCPAbstractItem public: /*! The different visual appearances a tracer item can have. Some styles size may be controlled with \ref setSize. - + \see setStyle */ enum TracerStyle { tsNone ///< The tracer is not visible @@ -6905,7 +6909,7 @@ class QCP_LIB_DECL QCPItemTracer : public QCPAbstractItem // reimplemented virtual methods: virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; - + // non-virtual methods: void updatePosition(); @@ -6949,7 +6953,7 @@ class QCP_LIB_DECL QCPItemBracket : public QCPAbstractItem /*! Defines the various visual shapes of the bracket item. The appearance can be further modified by \ref setLength and \ref setPen. - + \see setStyle */ enum BracketStyle { bsSquare ///< A brace with angled edges @@ -6961,37 +6965,37 @@ class QCP_LIB_DECL QCPItemBracket : public QCPAbstractItem explicit QCPItemBracket(QCustomPlot *parentPlot); virtual ~QCPItemBracket() Q_DECL_OVERRIDE; - + // getters: QPen pen() const { return mPen; } QPen selectedPen() const { return mSelectedPen; } double length() const { return mLength; } BracketStyle style() const { return mStyle; } - + // setters; void setPen(const QPen &pen); void setSelectedPen(const QPen &pen); void setLength(double length); void setStyle(BracketStyle style); - + // reimplemented virtual methods: virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; - + QCPItemPosition * const left; QCPItemPosition * const right; QCPItemAnchor * const center; - + protected: // property members: enum AnchorIndex {aiCenter}; QPen mPen, mSelectedPen; double mLength; BracketStyle mStyle; - + // reimplemented virtual methods: virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; - + // non-virtual methods: QPen mainPen() const; }; @@ -7008,7 +7012,7 @@ class QCP_LIB_DECL QCPPolarAxisRadial : public QCPLayerable { Q_OBJECT /// \cond INCLUDE_QPROPERTIES - + /// \endcond public: /*! @@ -7038,20 +7042,20 @@ class QCP_LIB_DECL QCPPolarAxisRadial : public QCPLayerable Q_ENUMS(SelectablePart) Q_FLAGS(SelectableParts) Q_DECLARE_FLAGS(SelectableParts, SelectablePart) - - enum LabelMode { lmUpright ///< - ,lmRotated ///< + + enum LabelMode { lmUpright ///< + ,lmRotated ///< }; Q_ENUMS(LabelMode) - + explicit QCPPolarAxisRadial(QCPPolarAxisAngular *parent); virtual ~QCPPolarAxisRadial(); - + // getters: bool rangeDrag() const { return mRangeDrag; } bool rangeZoom() const { return mRangeZoom; } double rangeZoomFactor() const { return mRangeZoomFactor; } - + QCPPolarAxisAngular *angularAxis() const { return mAngularAxis; } ScaleType scaleType() const { return mScaleType; } const QCPRange range() const { return mRange; } @@ -7092,12 +7096,12 @@ class QCP_LIB_DECL QCPPolarAxisRadial : public QCPLayerable QPen selectedBasePen() const { return mSelectedBasePen; } QPen selectedTickPen() const { return mSelectedTickPen; } QPen selectedSubTickPen() const { return mSelectedSubTickPen; } - + // setters: void setRangeDrag(bool enabled); void setRangeZoom(bool enabled); void setRangeZoomFactor(double factor); - + Q_SLOT void setScaleType(QCPPolarAxisRadial::ScaleType type); Q_SLOT void setRange(const QCPRange &range); void setRange(double lower, double upper); @@ -7140,10 +7144,10 @@ class QCP_LIB_DECL QCPPolarAxisRadial : public QCPLayerable void setSelectedSubTickPen(const QPen &pen); Q_SLOT void setSelectableParts(const QCPPolarAxisRadial::SelectableParts &selectableParts); Q_SLOT void setSelectedParts(const QCPPolarAxisRadial::SelectableParts &selectedParts); - + // reimplemented virtual methods: virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - + // non-property methods: void moveRange(double diff); void scaleRange(double factor); @@ -7154,7 +7158,7 @@ class QCP_LIB_DECL QCPPolarAxisRadial : public QCPLayerable double coordToRadius(double coord) const; double radiusToCoord(double radius) const; SelectablePart getPartAt(const QPointF &pos) const; - + signals: void rangeChanged(const QCPRange &newRange); void rangeChanged(const QCPRange &newRange, const QCPRange &oldRange); @@ -7167,7 +7171,7 @@ class QCP_LIB_DECL QCPPolarAxisRadial : public QCPLayerable bool mRangeDrag; bool mRangeZoom; double mRangeZoomFactor; - + // axis base: QCPPolarAxisAngular *mAngularAxis; double mAngle; @@ -7199,7 +7203,7 @@ class QCP_LIB_DECL QCPPolarAxisRadial : public QCPLayerable QCPRange mRange; bool mRangeReversed; ScaleType mScaleType; - + // non-property members: QPointF mCenter; double mRadius; @@ -7211,7 +7215,7 @@ class QCP_LIB_DECL QCPPolarAxisRadial : public QCPLayerable QCPRange mDragStartRange; QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; QCPLabelPainterPrivate mLabelPainter; - + // reimplemented virtual methods: virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; @@ -7224,7 +7228,7 @@ class QCP_LIB_DECL QCPPolarAxisRadial : public QCPLayerable virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; - + // non-virtual methods: void updateGeometry(const QPointF ¢er, double radius); void setupTickVectors(); @@ -7235,10 +7239,10 @@ class QCP_LIB_DECL QCPPolarAxisRadial : public QCPLayerable QFont getLabelFont() const; QColor getTickLabelColor() const; QColor getLabelColor() const; - + private: Q_DISABLE_COPY(QCPPolarAxisRadial) - + friend class QCustomPlot; friend class QCPPolarAxisAngular; }; @@ -7259,7 +7263,7 @@ class QCP_LIB_DECL QCPPolarAxisAngular : public QCPLayoutElement { Q_OBJECT /// \cond INCLUDE_QPROPERTIES - + /// \endcond public: /*! @@ -7274,18 +7278,18 @@ class QCP_LIB_DECL QCPPolarAxisAngular : public QCPLayoutElement Q_ENUMS(SelectablePart) Q_FLAGS(SelectableParts) Q_DECLARE_FLAGS(SelectableParts, SelectablePart) - + /*! TODO */ - enum LabelMode { lmUpright ///< - ,lmRotated ///< + enum LabelMode { lmUpright ///< + ,lmRotated ///< }; Q_ENUMS(LabelMode) - + explicit QCPPolarAxisAngular(QCustomPlot *parentPlot); virtual ~QCPPolarAxisAngular(); - + // getters: QPixmap background() const { return mBackgroundPixmap; } QBrush backgroundBrush() const { return mBackgroundBrush; } @@ -7294,7 +7298,7 @@ class QCP_LIB_DECL QCPPolarAxisAngular : public QCPLayoutElement bool rangeDrag() const { return mRangeDrag; } bool rangeZoom() const { return mRangeZoom; } double rangeZoomFactor() const { return mRangeZoomFactor; } - + const QCPRange range() const { return mRange; } bool rangeReversed() const { return mRangeReversed; } double angle() const { return mAngle; } @@ -7332,7 +7336,7 @@ class QCP_LIB_DECL QCPPolarAxisAngular : public QCPLayoutElement QPen selectedTickPen() const { return mSelectedTickPen; } QPen selectedSubTickPen() const { return mSelectedSubTickPen; } QCPPolarGrid *grid() const { return mGrid; } - + // setters: void setBackground(const QPixmap &pm); void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); @@ -7342,7 +7346,7 @@ class QCP_LIB_DECL QCPPolarAxisAngular : public QCPLayoutElement void setRangeDrag(bool enabled); void setRangeZoom(bool enabled); void setRangeZoomFactor(double factor); - + Q_SLOT void setRange(const QCPRange &range); void setRange(double lower, double upper); void setRange(double position, double size, Qt::AlignmentFlag alignment); @@ -7384,12 +7388,12 @@ class QCP_LIB_DECL QCPPolarAxisAngular : public QCPLayoutElement void setSelectedSubTickPen(const QPen &pen); Q_SLOT void setSelectableParts(const QCPPolarAxisAngular::SelectableParts &selectableParts); Q_SLOT void setSelectedParts(const QCPPolarAxisAngular::SelectableParts &selectedParts); - + // reimplemented virtual methods: virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; - + // non-property methods: bool removeGraph(QCPPolarGraph *graph); int radialAxisCount() const; @@ -7399,7 +7403,7 @@ class QCP_LIB_DECL QCPPolarAxisAngular : public QCPLayoutElement bool removeRadialAxis(QCPPolarAxisRadial *axis); QCPLayoutInset *insetLayout() const { return mInsetLayout; } QRegion exactClipRegion() const; - + void moveRange(double diff); void scaleRange(double factor); void scaleRange(double factor, double center); @@ -7409,7 +7413,7 @@ class QCP_LIB_DECL QCPPolarAxisAngular : public QCPLayoutElement void pixelToCoord(QPointF pixelPos, double &angleCoord, double &radiusCoord) const; QPointF coordToPixel(double angleCoord, double radiusCoord) const; SelectablePart getPartAt(const QPointF &pos) const; - + // read-only interface imitating a QRect: int left() const { return mRect.left(); } int right() const { return mRect.right(); } @@ -7424,13 +7428,13 @@ class QCP_LIB_DECL QCPPolarAxisAngular : public QCPLayoutElement QPoint bottomRight() const { return mRect.bottomRight(); } QPointF center() const { return mCenter; } double radius() const { return mRadius; } - + signals: void rangeChanged(const QCPRange &newRange); void rangeChanged(const QCPRange &newRange, const QCPRange &oldRange); void selectionChanged(const QCPPolarAxisAngular::SelectableParts &parts); void selectableChanged(const QCPPolarAxisAngular::SelectableParts &parts); - + protected: // property members: QBrush mBackgroundBrush; @@ -7442,7 +7446,7 @@ class QCP_LIB_DECL QCPPolarAxisAngular : public QCPLayoutElement bool mRangeDrag; bool mRangeZoom; double mRangeZoomFactor; - + // axis base: double mAngle, mAngleRad; SelectableParts mSelectableParts, mSelectedParts; @@ -7471,7 +7475,7 @@ class QCP_LIB_DECL QCPPolarAxisAngular : public QCPLayoutElement // scale and range: QCPRange mRange; bool mRangeReversed; - + // non-property members: QPointF mCenter; double mRadius; @@ -7489,7 +7493,7 @@ class QCP_LIB_DECL QCPPolarAxisAngular : public QCPLayoutElement QList mDragRadialStart; QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; QCPLabelPainterPrivate mLabelPainter; - + // reimplemented virtual methods: virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; @@ -7499,7 +7503,7 @@ class QCP_LIB_DECL QCPPolarAxisAngular : public QCPLayoutElement virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; - + // non-virtual methods: bool registerPolarGraph(QCPPolarGraph *graph); void drawBackground(QCPPainter *painter, const QPointF ¢er, double radius); @@ -7511,10 +7515,10 @@ class QCP_LIB_DECL QCPPolarAxisAngular : public QCPLayoutElement QFont getLabelFont() const; QColor getTickLabelColor() const; QColor getLabelColor() const; - + private: Q_DISABLE_COPY(QCPPolarAxisAngular) - + friend class QCustomPlot; friend class QCPPolarGrid; friend class QCPPolarGraph; @@ -7532,23 +7536,23 @@ class QCP_LIB_DECL QCPPolarGrid :public QCPLayerable { Q_OBJECT /// \cond INCLUDE_QPROPERTIES - + /// \endcond public: /*! TODO */ - enum GridType { gtAngular = 0x01 ///< - ,gtRadial = 0x02 ///< - ,gtAll = 0xFF ///< - ,gtNone = 0x00 ///< + enum GridType { gtAngular = 0x01 ///< + ,gtRadial = 0x02 ///< + ,gtAll = 0xFF ///< + ,gtNone = 0x00 ///< }; Q_ENUMS(GridType) Q_FLAGS(GridTypes) Q_DECLARE_FLAGS(GridTypes, GridType) - + explicit QCPPolarGrid(QCPPolarAxisAngular *parentAxis); - + // getters: QCPPolarAxisRadial *radialAxis() const { return mRadialAxis.data(); } GridTypes type() const { return mType; } @@ -7560,7 +7564,7 @@ class QCP_LIB_DECL QCPPolarGrid :public QCPLayerable QPen radialPen() const { return mRadialPen; } QPen radialSubGridPen() const { return mRadialSubGridPen; } QPen radialZeroLinePen() const { return mRadialZeroLinePen; } - + // setters: void setRadialAxis(QCPPolarAxisRadial *axis); void setType(GridTypes type); @@ -7572,7 +7576,7 @@ class QCP_LIB_DECL QCPPolarGrid :public QCPLayerable void setRadialPen(const QPen &pen); void setRadialSubGridPen(const QPen &pen); void setRadialZeroLinePen(const QPen &pen); - + protected: // property members: GridTypes mType; @@ -7580,22 +7584,22 @@ class QCP_LIB_DECL QCPPolarGrid :public QCPLayerable bool mAntialiasedSubGrid, mAntialiasedZeroLine; QPen mAngularPen, mAngularSubGridPen; QPen mRadialPen, mRadialSubGridPen, mRadialZeroLinePen; - + // non-property members: QCPPolarAxisAngular *mParentAxis; QPointer mRadialAxis; - + // reimplemented virtual methods: virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - + // non-virtual methods: void drawRadialGrid(QCPPainter *painter, const QPointF ¢er, const QVector &coords, const QPen &pen, const QPen &zeroPen=Qt::NoPen); void drawAngularGrid(QCPPainter *painter, const QPointF ¢er, double radius, const QVector &ticksCosSin, const QPen &pen); - + private: Q_DISABLE_COPY(QCPPolarGrid) - + }; Q_DECLARE_OPERATORS_FOR_FLAGS(QCPPolarGrid::GridTypes) @@ -7614,18 +7618,18 @@ class QCP_LIB_DECL QCPPolarLegendItem : public QCPAbstractLegendItem Q_OBJECT public: QCPPolarLegendItem(QCPLegend *parent, QCPPolarGraph *graph); - + // getters: QCPPolarGraph *polarGraph() { return mPolarGraph; } - + protected: // property members: QCPPolarGraph *mPolarGraph; - + // reimplemented virtual methods: virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE; - + // non-virtual methods: QPen getIconBorderPen() const; QColor getTextColor() const; @@ -7637,7 +7641,7 @@ class QCP_LIB_DECL QCPPolarGraph : public QCPLayerable { Q_OBJECT /// \cond INCLUDE_QPROPERTIES - + /// \endcond public: /*! @@ -7650,10 +7654,10 @@ class QCP_LIB_DECL QCPPolarGraph : public QCPLayerable ,lsLine ///< data points are connected by a straight line }; Q_ENUMS(LineStyle) - + QCPPolarGraph(QCPPolarAxisAngular *keyAxis, QCPPolarAxisRadial *valueAxis); virtual ~QCPPolarGraph(); - + // getters: QString name() const { return mName; } bool antialiasedFill() const { return mAntialiasedFill; } @@ -7670,7 +7674,7 @@ class QCP_LIB_DECL QCPPolarGraph : public QCPLayerable QSharedPointer data() const { return mDataContainer; } LineStyle lineStyle() const { return mLineStyle; } QCPScatterStyle scatterStyle() const { return mScatterStyle; } - + // setters: void setName(const QString &name); void setAntialiasedFill(bool enabled); @@ -7702,18 +7706,18 @@ class QCP_LIB_DECL QCPPolarGraph : public QCPLayerable bool addToLegend(); bool removeFromLegend(QCPLegend *legend) const; bool removeFromLegend() const; - + // introduced virtual methods: virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; // actually introduced in QCPLayerable as non-pure, but we want to force reimplementation for plottables virtual QCPPlottableInterface1D *interface1D() { return 0; } // TODO: return this later, when QCPAbstractPolarPlottable is created virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const; virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const; - + signals: void selectionChanged(bool selected); void selectionChanged(const QCPDataSelection &selection); void selectableChanged(QCP::SelectionType selectable); - + protected: // property members: QSharedPointer mDataContainer; @@ -7729,7 +7733,7 @@ class QCP_LIB_DECL QCPPolarGraph : public QCPLayerable QCP::SelectionType mSelectable; QCPDataSelection mSelection; //QCPSelectionDecorator *mSelectionDecorator; - + // introduced virtual methods (later reimplemented TODO from QCPAbstractPolarPlottable): virtual QRect clipRect() const; virtual void draw(QCPPainter *painter); @@ -7742,10 +7746,10 @@ class QCP_LIB_DECL QCPPolarGraph : public QCPLayerable virtual void drawLinePlot(QCPPainter *painter, const QVector &lines) const; virtual void drawFill(QCPPainter *painter, QVector *lines) const; virtual void drawScatterPlot(QCPPainter *painter, const QVector &scatters, const QCPScatterStyle &style) const; - + // introduced virtual methods: virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const; - + // non-virtual methods: void applyFillAntialiasingHint(QCPPainter *painter) const; void applyScattersAntialiasingHint(QCPPainter *painter) const; @@ -7763,7 +7767,7 @@ class QCP_LIB_DECL QCPPolarGraph : public QCPLayerable private: Q_DISABLE_COPY(QCPPolarGraph) - + friend class QCPPolarLegendItem; }; diff --git a/companion/src/translations.cpp b/companion/src/translations.cpp index 3f60eab11f0..72052ae6ade 100644 --- a/companion/src/translations.cpp +++ b/companion/src/translations.cpp @@ -81,8 +81,7 @@ QStringList const Translations::getTranslationPaths() // Then the resource file paths << APP_TRANSLATIONS_RESOURCE_PATH; // Finally the system folder (more likely for Qt translations than Companion ones) - paths << QLibraryInfo::location(QLibraryInfo::TranslationsPath); - + paths << QLibraryInfo::path(QLibraryInfo::TranslationsPath); return paths; } @@ -103,7 +102,8 @@ void Translations::installTranslators() g.locale(""); } } - qDebug() << "Locale name:" << locale.name() << "language:" << locale.nativeLanguageName() << "country:" << locale.nativeCountryName(); + + qDebug() << "Locale name:" << locale.name() << "language:" << locale.nativeLanguageName() << "country:" << locale.nativeTerritoryName(); // Remove any existing translators, this lets us re-translate w/out restart. foreach (QTranslator * t, appTranslators) { @@ -125,10 +125,7 @@ void Translations::installTranslators() // First try to install Qt translations for common GUI elements. QStringList qtFiles = QStringList() << "qt"; - // After Qt5.3 some translation files are broken up into modules. We only need "qtbase" for now. -#if (QT_VERSION >= QT_VERSION_CHECK(5, 3, 0)) qtFiles << "qtbase"; -#endif foreach (const QString & qtfile, qtFiles) { QTranslator * translator = new QTranslator(qApp); diff --git a/companion/src/updates/CMakeLists.txt b/companion/src/updates/CMakeLists.txt index f98a95ae823..cce0e82586f 100644 --- a/companion/src/updates/CMakeLists.txt +++ b/companion/src/updates/CMakeLists.txt @@ -38,7 +38,7 @@ set(${PROJECT_NAME}_MOC updatesdialog.h ) -qt5_wrap_cpp(${PROJECT_NAME}_SRCS +qt_wrap_cpp(${PROJECT_NAME}_SRCS ${${PROJECT_NAME}_MOC} ) diff --git a/companion/src/updates/updateoptionsdialog.cpp b/companion/src/updates/updateoptionsdialog.cpp index aa1d5def4fb..733cace6323 100644 --- a/companion/src/updates/updateoptionsdialog.cpp +++ b/companion/src/updates/updateoptionsdialog.cpp @@ -186,7 +186,7 @@ UpdateOptionsDialog::UpdateOptionsDialog(QWidget * parent, UpdateInterface * ifa leSubFolders << leSubFolder; layout3->addWidget(leSubFolder, 1, 2, 1, 2); - connect(chkDownload, &QCheckBox::stateChanged, [=](const int checked) { + connect(chkDownload, &QCheckBox::checkStateChanged, [=](const int checked) { if (!checked) { chkDecompress->setChecked(false); chkCopy->setChecked(false); @@ -199,7 +199,7 @@ UpdateOptionsDialog::UpdateOptionsDialog(QWidget * parent, UpdateInterface * ifa } }); - connect(chkDecompress, &QCheckBox::stateChanged, [=](const int checked) { + connect(chkDecompress, &QCheckBox::checkStateChanged, [=](const int checked) { if (!checked) { chkCopy->setChecked(false); chkInstall->setChecked(false); @@ -210,7 +210,7 @@ UpdateOptionsDialog::UpdateOptionsDialog(QWidget * parent, UpdateInterface * ifa } }); - connect(chkCopy, &QCheckBox::stateChanged, [=](const int checked) { + connect(chkCopy, &QCheckBox::checkStateChanged, [=](const int checked) { cboCopyFilterType->setEnabled(checked ? (processes & UpdateInterface::UPDFLG_CopyDest) && (!locked) : checked); leCopyFilter->setEnabled(checked ? (processes & UpdateInterface::UPDFLG_CopyDest) && (!locked) : checked); leSubFolder->setEnabled(checked ? (processes & UpdateInterface::UPDFLG_CopyDest) && (!locked) : checked); diff --git a/companion/src/updates/updatesdialog.cpp b/companion/src/updates/updatesdialog.cpp index 9157ca7487b..5c62b7cde0e 100644 --- a/companion/src/updates/updatesdialog.cpp +++ b/companion/src/updates/updatesdialog.cpp @@ -50,8 +50,8 @@ UpdatesDialog::UpdatesDialog(QWidget * parent, UpdateFactories * factories) : ui->chkDelDecompress->setChecked(g.updDelDecompress()); ui->leDownloadDir->setText(g.downloadDir()); - connect(ui->chkDecompressDirUseDwnld, &QCheckBox::stateChanged, [=](const int checked) { - if (!checked) { + connect(ui->chkDecompressDirUseDwnld, &QCheckBox::checkStateChanged, [=](const int checked) { + if (!checked) { ui->leDecompressDir->setText(g.decompressDir()); ui->leDecompressDir->setEnabled(true); ui->btnDecompressSelect->setEnabled(true); @@ -75,8 +75,8 @@ UpdatesDialog::UpdatesDialog(QWidget * parent, UpdateFactories * factories) : ui->chkDecompressDirUseDwnld->setChecked(!ui->chkDecompressDirUseDwnld->isChecked()); ui->chkDecompressDirUseDwnld->setChecked(g.decompressDirUseDwnld()); - connect(ui->chkUpdateDirUseSD, &QCheckBox::stateChanged, [=](const int checked) { - if (!checked) { + connect(ui->chkUpdateDirUseSD, &QCheckBox::checkStateChanged, [=](const int checked) { + if (!checked) { ui->leUpdateDir->setText(g.updateDir()); ui->leUpdateDir->setEnabled(true); ui->btnUpdateSelect->setEnabled(true); @@ -122,7 +122,7 @@ UpdatesDialog::UpdatesDialog(QWidget * parent, UpdateFactories * factories) : } }); - connect(ui->chkDelDecompress, &QCheckBox::stateChanged, [=](const int checked) { + connect(ui->chkDelDecompress, &QCheckBox::checkStateChanged, [=](const int checked) { if (!checked) { if (ui->chkDecompressDirUseDwnld->isChecked()) { ui->chkDelDownloads->setEnabled(false); diff --git a/companion/src/wizarddata.cpp b/companion/src/wizarddata.cpp index e7aac692dac..e992307ac16 100644 --- a/companion/src/wizarddata.cpp +++ b/companion/src/wizarddata.cpp @@ -46,7 +46,8 @@ WizMix::WizMix(const GeneralSettings & settings, unsigned int modelId, const Mod vehicle(NOVEHICLE) { memset(name, 0, sizeof(name)); - strncpy(name, originalModelData.name, sizeof(name)-1); + memcpy(name, originalModelData.name, sizeof(name) - 1); + name[sizeof(name) - 1] = '\0'; } void WizMix::maxMixSwitch(char *name, MixData &mix, int channel, int sw, int weight) @@ -94,9 +95,9 @@ WizMix::operator ModelData() int mixIndex = 0; int timerIndex = 0; - // Safe copy model name memset(model.name, 0, sizeof(model.name)); - strncpy(model.name, name, sizeof(model.name)-1); + memcpy(model.name, name, sizeof(model.name) - 1); + model.name[sizeof(model.name) - 1] = '\0'; // Add the channel mixes for (int i=0; i= QT_VERSION_CHECK(5, 4, 0)) QTimer::singleShot(10, [this, key]() { setKey(key, 0); }); -#else - QTimer *timer = new QTimer(this); - timer->setSingleShot(true); - connect(timer, &QTimer::timeout, [=]() { - setKey(key, 0); - timer->deleteLater(); - } ); - timer->start(10); -#endif #endif // defined(ROTARY_ENCODER_NAVIGATION) } @@ -534,12 +524,12 @@ void OpenTxSimulator::sendTelemetry(const uint8_t module, const uint8_t protocol case SIMU_TELEMETRY_PROTOCOL_FRSKY_SPORT: sportProcessTelemetryPacket(module, (uint8_t *)data.constData(), - data.count()); + data.size()); break; case SIMU_TELEMETRY_PROTOCOL_FRSKY_HUB: frskyDProcessPacket(module, (uint8_t *)data.constData(), - data.count()); + data.size()); break; case SIMU_TELEMETRY_PROTOCOL_FRSKY_HUB_OOB: // FrSky D telemetry is a stream which can span multiple @@ -563,7 +553,7 @@ void OpenTxSimulator::sendTelemetry(const uint8_t module, const uint8_t protocol case SIMU_TELEMETRY_PROTOCOL_CROSSFIRE: processCrossfireTelemetryFrame(module, (uint8_t *)data.constData(), - data.count()); + data.size()); break; default: // Do nothing diff --git a/radio/src/tests/CMakeLists.txt b/radio/src/tests/CMakeLists.txt index e72d14c1285..0e8e226c32c 100644 --- a/radio/src/tests/CMakeLists.txt +++ b/radio/src/tests/CMakeLists.txt @@ -1,6 +1,5 @@ - -if(Qt5Widgets_FOUND) +if(Qt6Widgets_FOUND) add_library(gtests-radio-lib STATIC EXCLUDE_FROM_ALL ${googletest_SOURCE_DIR}/googletest/src/gtest-all.cc ) @@ -45,6 +44,6 @@ if(Qt5Widgets_FOUND) target_compile_options(gtests-radio PRIVATE ${SIMU_SRC_OPTIONS}) add_dependencies(gtests-radio gtests-radio-lib) - target_link_libraries(gtests-radio gtests-radio-lib Qt5::Core Qt5::Widgets) + target_link_libraries(gtests-radio gtests-radio-lib Qt::Core Qt::Widgets) message(STATUS "Added optional gtests target") endif() diff --git a/tools/companion-gen-icons.py b/tools/companion-gen-icons.py index af50739103c..69a3dc6f8c9 100755 --- a/tools/companion-gen-icons.py +++ b/tools/companion-gen-icons.py @@ -81,7 +81,7 @@ def downloadFile(url: str, outFile: str): print("Generate Linux Icons... ", end="") os.chdir(LINUX_ICONS_DIR) -linux_resolutions = [16, 22, 24, 32, 48, 128, 256, 512] +linux_resolutions = [16, 22, 24, 32, 48, 64, 128, 256, 512] for size in linux_resolutions: new_image_folder = os.path.join(LINUX_ICONS_DIR, str(size) + 'x' + str(size)) companion_png = os.path.join(new_image_folder, 'companion.png') diff --git a/tools/msys2_fetch_and_build_all.sh b/tools/msys2_fetch_and_build_all.sh index 56571573cbb..a88ab9db54e 100644 --- a/tools/msys2_fetch_and_build_all.sh +++ b/tools/msys2_fetch_and_build_all.sh @@ -209,8 +209,8 @@ if [[ $PAUSEAFTEREACHLINE == "true" ]]; then fi echo "=== Step $((STEP++)): Running CMake for ${RADIO_TYPE} as an example ===" -cmake -G "MSYS Makefiles" -Wno-dev -DCMAKE_PREFIX_PATH=$HOME/5.12.9/mingw73_64 -DSDL2_LIBRARY_PATH=/mingw64/bin/ ${BUILD_OPTIONS} -DCMAKE_BUILD_TYPE=Release ../ -check_command $? "cmake -G MSYS Makefiles -Wno-dev -DCMAKE_PREFIX_PATH=$HOME/5.12.9/mingw73_64 -DSDL2_LIBRARY_PATH=/mingw64/bin/ ${BUILD_OPTIONS} -DCMAKE_BUILD_TYPE=Release ../" +cmake -G "MSYS Makefiles" -Wno-dev -DCMAKE_PREFIX_PATH=$HOME/6.8.2/mingw_64 -DSDL2_LIBRARY_PATH=/mingw64/bin/ ${BUILD_OPTIONS} -DCMAKE_BUILD_TYPE=Release ../ +check_command $? "cmake -G MSYS Makefiles -Wno-dev -DCMAKE_PREFIX_PATH=$HOME/6.8.2/mingw_64 -DSDL2_LIBRARY_PATH=/mingw64/bin/ ${BUILD_OPTIONS} -DCMAKE_BUILD_TYPE=Release ../" if [[ $PAUSEAFTEREACHLINE == "true" ]]; then echo "Step finished. Please check the output above and press Enter to continue or Ctrl+C to stop." read diff --git a/tools/setup_buildenv_msys2_stage2.sh b/tools/setup_buildenv_msys2_stage2.sh index 3c2e7dae485..4850a4f53eb 100644 --- a/tools/setup_buildenv_msys2_stage2.sh +++ b/tools/setup_buildenv_msys2_stage2.sh @@ -14,7 +14,25 @@ do done echo "=== Step $((STEP++)): Installing packages ===" -pacman -S --noconfirm mingw-w64-x86_64-cmake mingw-w64-x86_64-python-pip mingw-w64-x86_64-python-pillow mingw-w64-x86_64-python-lz4 mingw-w64-x86_64-libjpeg-turbo mingw-w64-x86_64-zlib mingw-w64-x86_64-libtiff mingw-w64-x86_64-freetype mingw-w64-x86_64-lcms2 mingw-w64-x86_64-libwebp mingw-w64-x86_64-openjpeg2 mingw-w64-x86_64-libimagequant mingw-w64-x86_64-libraqm mingw-w64-x86_64-SDL2 mingw-w64-x86_64-nsis mingw-w64-x86_64-clang mingw-w64-x86_64-openssl unzip wget +pacman -S --noconfirm mingw-w64-x86_64-cmake \ + mingw-w64-x86_64-python-pip \ + mingw-w64-x86_64-python-pillow \ + mingw-w64-x86_64-python-lz4 \ + mingw-w64-x86_64-libjpeg-turbo \ + mingw-w64-x86_64-zlib \ + mingw-w64-x86_64-libtiff \ + mingw-w64-x86_64-freetype \ + mingw-w64-x86_64-lcms2 \ + mingw-w64-x86_64-libwebp \ + mingw-w64-x86_64-openjpeg2 \ + mingw-w64-x86_64-libimagequant \ + mingw-w64-x86_64-libraqm \ + mingw-w64-x86_64-SDL2 \ + mingw-w64-x86_64-clang \ + mingw-w64-x86_64-nsis \ + mingw-w64-x86_64-dfu-util \ + mingw-w64-x86_64-openssl + if [[ $PAUSEAFTEREACHLINE == "true" ]]; then echo "Step finished. Please check the output above and press Enter to continue or Ctrl+C to stop." read @@ -43,63 +61,31 @@ if [[ $PAUSEAFTEREACHLINE == "true" ]]; then read fi -echo "=== Step $((STEP++)): Installing Python clang ===" -python -m pip install clang -if [[ $PAUSEAFTEREACHLINE == "true" ]]; then - echo "Step finished. Please check the output above and press Enter to continue or Ctrl+C to stop." - read -fi - -echo "=== Step $((STEP++)): Installing Python jinja2 ===" -python -m pip install jinja2 -if [[ $PAUSEAFTEREACHLINE == "true" ]]; then - echo "Step finished. Please check the output above and press Enter to continue or Ctrl+C to stop." - read -fi - -echo "=== Step $((STEP++)): Installing Python setuptools and wheel ===" -python -m pip install setuptools wheel -if [[ $PAUSEAFTEREACHLINE == "true" ]]; then - echo "Step finished. Please check the output above and press Enter to continue or Ctrl+C to stop." - read -fi - -echo "=== Step $((STEP++)): Fetching and installing Python package bcj-cffi ===" -git clone --recursive https://github.com/miurahr/bcj-cffi.git -cd bcj-cffi -python setup.py install -cd .. -if [[ $PAUSEAFTEREACHLINE == "true" ]]; then - echo "Step finished. Please check the output above and press Enter to continue or Ctrl+C to stop." - read -fi - -echo "=== Step $((STEP++)): Fetching and installing Python package pyppmd ===" -git clone --recursive https://github.com/miurahr/pyppmd.git -cd pyppmd -python setup.py install -cd .. -if [[ $PAUSEAFTEREACHLINE == "true" ]]; then - echo "Step finished. Please check the output above and press Enter to continue or Ctrl+C to stop." - read -fi - -echo "=== Step $((STEP++)): Installing Python package py7zr in version 0.16.1 ===" -python -m pip install py7zr==0.16.1 +echo "=== Step $((STEP++)): Installing Python packages ===" +# Python 3.11 introduced the managed environment breakage aka PEP 668. +# since we are building a self-contained environment the simple fix is to add --break-system-packages to all pip installs +python3 -m pip install --break-system-package -U setuptools && \ +python3 -m pip install --break-system-package \ + asciitree \ + jinja2 \ + pillow \ + clang==14.0.0 \ + lz4 \ + pyelftools if [[ $PAUSEAFTEREACHLINE == "true" ]]; then echo "Step finished. Please check the output above and press Enter to continue or Ctrl+C to stop." read fi -echo "=== Step $((STEP++)): Installing Python package aqtinstall in version 1.2.5 ===" -python -m pip install aqtinstall==1.2.5 +echo "=== Step $((STEP++)): Downloading aqt ===" +wget "https://github.com/miurahr/aqtinstall/releases/download/Continuous/aqt.exe" if [[ $PAUSEAFTEREACHLINE == "true" ]]; then echo "Step finished. Please check the output above and press Enter to continue or Ctrl+C to stop." read fi echo "=== Step $((STEP++)): Installing Qt build environment ===" -python -m aqt install 5.12.9 windows desktop win64_mingw73 +./aqt.exe install-qt windows desktop 6.9.0 win64_mingw -m qtmultimedia qtserialport if [[ $PAUSEAFTEREACHLINE == "true" ]]; then echo "Step finished. Please check the output above and press Enter to continue or Ctrl+C to stop." fi diff --git a/tools/setup_buildenv_ubuntu24.04.sh b/tools/setup_buildenv_ubuntu24.04.sh new file mode 100644 index 00000000000..a75af93d5aa --- /dev/null +++ b/tools/setup_buildenv_ubuntu24.04.sh @@ -0,0 +1,154 @@ +#! /usr/bin/env bash + +set -e + +## Bash script to setup EdgeTX development environment on Ubuntu 24.04 running on bare-metal or in a virtual machine. +## Let it run as normal user and when asked, give sudo credentials + +PAUSEAFTEREACHLINE="false" +STEP=1 +# Parse argument(s) +for arg in "$@" +do + if [[ $arg == "--pause" ]]; then + PAUSEAFTEREACHLINE="true" + fi +done + +if [[ $(lsb_release -rs) != "24.04" ]]; then + echo "ERROR: Not running on Ubuntu 24.04!" + echo "Terminating the script now." + exit 1 +fi + +echo "=== Step $((STEP++)): Checking if i386 requirement is satisfied ===" +OUTPUT=x$(dpkg --print-foreign-architectures 2> /dev/null | grep i386) || : +if [ "$OUTPUT" != "xi386" ]; then + echo "Need to install i386 architecture first." + sudo dpkg --add-architecture i386 +else + echo "i386 requirement satisfied!" +fi +if [[ $PAUSEAFTEREACHLINE == "true" ]]; then + echo "Step finished. Please check the output above and press Enter to continue or Ctrl+C to stop." + read +fi + +echo "=== Step $((STEP++)): Updating Ubuntu package lists. Please provide sudo credentials, when asked ===" +sudo apt-get -y update +if [[ $PAUSEAFTEREACHLINE == "true" ]]; then + echo "Step finished. Please check the output above and press Enter to continue or Ctrl+C to stop." + read +fi + +echo "=== Step $((STEP++)): Installing packages ===" +sudo apt-get -y install build-essential cmake gcc git lib32ncurses-dev lib32z1 libfox-1.6-dev libsdl2-dev software-properties-common wget zip python3-pip-whl python3-pil libgtest-dev python3-pip python3-tk python3-setuptools clang python3-clang libusb-1.0-0-dev stlink-tools openocd npm pv libncurses5:i386 libpython2.7:i386 libclang-dev python-is-python3 +if [[ $PAUSEAFTEREACHLINE == "true" ]]; then + echo "Step finished. Please check the output above and press Enter to continue or Ctrl+C to stop." + read +fi + +echo "=== Step $((STEP++)): Installing Python packages ===" +# Python 3.11 introduced the managed environment breakage aka PEP 668. +# since we are building a self-contained environment the simple fix is to add --break-system-packages to all pip installs +python3 -m pip install --break-system-package -U setuptools && \ +python3 -m pip install --break-system-package \ + filelock \ + asciitree \ + jinja2 \ + pillow \ + clang==14.0.0 \ + future \ + lxml \ + lz4 \ + aqtinstall \ + pyelftools +if [[ $PAUSEAFTEREACHLINE == "true" ]]; then + echo "Step finished. Please check the output above and press Enter to continue or Ctrl+C to stop." + read +fi + +echo "=== Step $((STEP++)): Installing Qt ===" +./aqt install-qt --outputdir qt linux desktop 6.8.2 linux_gcc_64 -m qtmultimedia qtserialport +if [[ $PAUSEAFTEREACHLINE == "true" ]]; then + echo "Step finished. Please press Enter to continue or Ctrl+C to stop." + read +fi + +echo "=== Step $((STEP++)): Fetching GNU Arm Embedded Toolchains ===" +# EdgeTX uses GNU Arm Embedded Toolchain version 14.2.rel1 +wget -q --show-progress --progress=bar:force:noscroll https://developer.arm.com/-/media/Files/downloads/gnu/14.2.rel1/binrel/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi.tar.xz +if [[ $PAUSEAFTEREACHLINE == "true" ]]; then + echo "Step finished. Please press Enter to continue or Ctrl+C to stop." + read +fi + +echo "=== Step $((STEP++)): Unpacking GNU Arm Embedded Toolchains ===" +pv arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi.tar.xz | tar xJf - +if [[ $PAUSEAFTEREACHLINE == "true" ]]; then + echo "Step finished. Please press Enter to continue or Ctrl+C to stop." + read +fi + +echo "=== Step $((STEP++)): Removing the downloaded archives ===" +rm arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi.tar.xz +if [[ $PAUSEAFTEREACHLINE == "true" ]]; then + echo "Step finished. Please press Enter to continue or Ctrl+C to stop." + read +fi + +echo "=== Step $((STEP++)): Moving GNU Arm Embedded Toolchains to /opt ===" +sudo mv arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi /opt/gcc-arm-none-eabi +if [[ $PAUSEAFTEREACHLINE == "true" ]]; then + echo "Step finished. Please press Enter to continue or Ctrl+C to stop." + read +fi + +echo "=== Step $((STEP++)): Adding GNU Arm Embedded Toolchain to PATH of current user ===" +echo 'export PATH="/opt/gcc-arm-none-eabi/bin:$PATH"' >> ~/.bashrc +if [[ $PAUSEAFTEREACHLINE == "true" ]]; then + echo "Step finished. Please press Enter to continue or Ctrl+C to stop." + read +fi + +echo "=== Step $((STEP++)): Removing modemmanager (conflicts with DFU) ===" +sudo apt-get -y remove modemmanager +if [[ $PAUSEAFTEREACHLINE == "true" ]]; then + echo "Step finished. Please check the output above and press Enter to continue or Ctrl+C to stop." + read +fi + +echo "=== Step $((STEP++)): Fetching USB DFU host utility ===" +wget -q --show-progress --progress=bar:force:noscroll http://dfu-util.sourceforge.net/releases/dfu-util-0.11.tar.gz +if [[ $PAUSEAFTEREACHLINE == "true" ]]; then + echo "Step finished. Please check the output above and press Enter to continue or Ctrl+C to stop." + read +fi + +echo "=== Step $((STEP++)): Unpacking USB DFU host utility ===" +pv dfu-util-0.11.tar.gz | tar xzf - +if [[ $PAUSEAFTEREACHLINE == "true" ]]; then + echo "Step finished. Please check the output above and press Enter to continue or Ctrl+C to stop." + read +fi + +echo "=== Step $((STEP++)): Building and Installing USB DFU host utility ===" +cd dfu-util-0.11/ +./configure +make +sudo make install +cd .. +if [[ $PAUSEAFTEREACHLINE == "true" ]]; then + echo "Step finished. Please check the output above and press Enter to continue or Ctrl+C to stop." + read +fi + +echo "=== Step $((STEP++)): Removing the downloaded archive and build folder of USB DFU host utility ===" +rm dfu-util-0.11.tar.gz +rm -rf dfu-util-0.11 +if [[ $PAUSEAFTEREACHLINE == "true" ]]; then + echo "Step finished." +fi + +echo "Finished setting up EdgeTX development environment." +echo "Please execute: source ~/.bashrc"