option(ENABLE_FLOW "Build with libsigrokflow" FALSE)
option(ENABLE_TESTS "Enable unit tests" FALSE)
option(STATIC_PKGDEPS_LIBS "Statically link to (pkg-config) libraries" FALSE)
+option(ENABLE_TS_UPDATE "Update .ts source files (Qt l10n)" FALSE)
if(WIN32)
# On Windows/MinGW we need to statically link to libraries.
#= Dependencies
#-------------------------------------------------------------------------------
+include(CheckCSourceCompiles)
+include(CheckCXXCompilerFlag)
+include(CheckCXXSourceCompiles)
+include(CMakePushCheckState)
+include(memaccess)
+
+find_package(PkgConfig)
+
+if(CMAKE_VERSION VERSION_EQUAL "3.8.0" OR CMAKE_VERSION VERSION_GREATER "3.8.0")
+ check_cxx_compiler_flag("-std=c++17" HAVE_STD_CXX_17)
+ check_cxx_compiler_flag("-std=c++14" HAVE_STD_CXX_14)
+ check_cxx_compiler_flag("-std=c++11" HAVE_STD_CXX_11)
+ if(HAVE_STD_CXX_17)
+ message(STATUS "Using C++17 for the application build")
+ set(CMAKE_CXX_STANDARD 17)
+ set(REQUIRED_STD_CXX_FLAGS "-std=c++17")
+ elseif(HAVE_STD_CXX_14)
+ message(STATUS "Using C++14 for the application build")
+ set(CMAKE_CXX_STANDARD 14)
+ set(REQUIRED_STD_CXX_FLAGS "-std=c++14")
+ elseif(HAVE_STD_CXX_11)
+ message(STATUS "Using C++11 for the application build")
+ set(CMAKE_CXX_STANDARD 11)
+ set(REQUIRED_STD_CXX_FLAGS "-std=c++11")
+ else()
+ message(FATAL_ERROR "Need modern C++, at least language standard 11")
+ endif()
+else()
+ check_cxx_compiler_flag("-std=c++14" HAVE_STD_CXX_14)
+ check_cxx_compiler_flag("-std=c++11" HAVE_STD_CXX_11)
+ if(HAVE_STD_CXX_14)
+ message(STATUS "Using C++14 for the application build")
+ set(CMAKE_CXX_STANDARD 14)
+ set(REQUIRED_STD_CXX_FLAGS "-std=c++14")
+ elseif(HAVE_STD_CXX_11)
+ message(STATUS "Using C++11 for the application build")
+ set(CMAKE_CXX_STANDARD 11)
+ set(REQUIRED_STD_CXX_FLAGS "-std=c++11")
+ else()
+ message(FATAL_ERROR "Need modern C++, at least language standard 11")
+ endif()
+endif()
+
list(APPEND PKGDEPS glib-2.0>=2.28.0)
-list(APPEND PKGDEPS glibmm-2.4>=2.28.0)
+
+# Try to find the prefered glibmm-2.4. If not found then add glibmm-2.68
+# to the dependency list.
+pkg_check_modules(GLIBMM_2_4 glibmm-2.4>=2.28.0)
+if(GLIBMM_2_4_FOUND)
+ list(APPEND PKGDEPS glibmm-2.4>=2.28.0)
+else()
+ list(APPEND PKGDEPS glibmm-2.68>=2.68.0)
+endif()
if(ENABLE_FLOW)
list(APPEND PKGDEPS gstreamermm-1.0>=1.8.0)
list(APPEND PKGDEPS libsigrokandroidutils>=0.1.0)
endif()
-find_package(PkgConfig)
pkg_check_modules(LIBSRCXX ${LIBSR_CXX_BINDING})
if(NOT LIBSRCXX_FOUND OR NOT LIBSRCXX_VERSION)
message(FATAL_ERROR "libsigrok C++ bindings missing, check libsigrok's 'configure' output (missing dependencies?)")
set(CMAKE_AUTOMOC TRUE)
-find_package(Qt5 5.3 COMPONENTS Core Gui LinguistTools Widgets Svg REQUIRED)
-
-message(STATUS "Qt version: ${Qt5_VERSION}")
+# Check for Qt5, and check for Qt6 if Qt5 is not found.
+set(QT_COMPONENTS Core Gui LinguistTools Widgets Svg)
+find_package(Qt5 5.3 QUIET COMPONENTS Core)
+if(Qt5_FOUND)
+ find_package(Qt5 5.3 COMPONENTS ${QT_COMPONENTS} REQUIRED)
+ message(STATUS "Qt version: ${Qt5_VERSION}")
+else()
+ find_package(Qt6 6.2 COMPONENTS ${QT_COMPONENTS} REQUIRED)
+ message(STATUS "Qt version: ${Qt6_VERSION}")
+endif()
if(WIN32)
- # MXE workaround: Use pkg-config to find Qt5 libs.
+ # MXE workaround: Use pkg-config to find Qt5 and Qt6 libs.
# https://github.com/mxe/mxe/issues/1642
# Not required (and doesn't work) on MSYS2.
if(NOT DEFINED ENV{MSYSTEM})
- pkg_check_modules(QT5ALL REQUIRED Qt5Widgets>=5.3 Qt5Gui>=5.3 Qt5Svg>=5.3)
+ if(Qt5_FOUND)
+ pkg_check_modules(QT5ALL REQUIRED Qt5Widgets>=5.3 Qt5Gui>=5.3 Qt5Svg>=5.3)
+ else()
+ pkg_check_modules(QT6ALL REQUIRED Qt6Widgets>=6.2 Qt6Gui>=6.2 Qt6Svg>=6.2)
+ endif()
endif()
endif()
-set(QT_LIBRARIES Qt5::Gui Qt5::Widgets Qt5::Svg)
+if(Qt5_FOUND)
+ set(QT_LIBRARIES Qt5::Gui Qt5::Widgets Qt5::Svg)
+else()
+ set(QT_LIBRARIES Qt6::Gui Qt6::Widgets Qt6::Svg)
+endif()
set(BOOSTCOMPS filesystem serialization system)
if(ENABLE_TESTS)
# Helper for checking for atomics
function(check_working_cxx_atomics varname additional_lib)
- include(CheckCXXSourceCompiles)
- include(CMakePushCheckState)
- cmake_push_check_state()
- set(CMAKE_REQUIRED_FLAGS "-std=c++11")
- set(CMAKE_REQUIRED_LIBRARIES "${additional_lib}")
- set(CMAKE_REQUIRED_QUIET 1)
- CHECK_CXX_SOURCE_COMPILES("
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_FLAGS "${REQUIRED_STD_CXX_FLAGS}")
+ set(CMAKE_REQUIRED_LIBRARIES "${additional_lib}")
+ set(CMAKE_REQUIRED_QUIET 1)
+ CHECK_CXX_SOURCE_COMPILES("
#include <atomic>
std::atomic<int> x;
int main() {
- return std::atomic_fetch_add_explicit(&x, 1, std::memory_order_seq_cst);
+ return std::atomic_fetch_add_explicit(&x, 1, std::memory_order_seq_cst);
}
" ${varname})
- cmake_pop_check_state()
+ cmake_pop_check_state()
endfunction(check_working_cxx_atomics)
# First check if atomics work without the library.
# If not, check if the library exists, and atomics work with it.
check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB "")
if(HAVE_CXX_ATOMICS_WITHOUT_LIB)
- message(STATUS "Atomics provided by the C-library - yes")
+ message(STATUS "Atomics provided by the C-library - yes")
else()
- message(STATUS "Atomics provided by the C-library - no")
- find_library(LIBATOMIC_LIBRARY NAMES atomic PATH_SUFFIXES lib)
- if(LIBATOMIC_LIBRARY)
- check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB "${LIBATOMIC_LIBRARY}")
- if (HAVE_CXX_ATOMICS_WITH_LIB)
- message(STATUS "Atomics provided by libatomic - yes")
- else()
- message(STATUS "Atomics provided by libatomic - no")
- message(FATAL_ERROR "Compiler must support std::atomic!")
- endif()
- else()
- message(FATAL_ERROR "Compiler appears to require libatomic, but cannot find it.")
- endif()
+ message(STATUS "Atomics provided by the C-library - no")
+ find_library(LIBATOMIC_LIBRARY NAMES atomic PATH_SUFFIXES lib)
+ if(LIBATOMIC_LIBRARY)
+ check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB "${LIBATOMIC_LIBRARY}")
+ if (HAVE_CXX_ATOMICS_WITH_LIB)
+ message(STATUS "Atomics provided by libatomic - yes")
+ else()
+ message(STATUS "Atomics provided by libatomic - no")
+ message(FATAL_ERROR "Compiler must support std::atomic!")
+ endif()
+ else()
+ message(FATAL_ERROR "Compiler appears to require libatomic, but cannot find it.")
+ endif()
+endif()
+
+# Check availability of features which depend on library versions.
+# TODO Ideally use check_symbol_exists() instead, reduce boilerplate.
+if(ENABLE_DECODE)
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_INCLUDES "${PKGDEPS_INCLUDE_DIRS}")
+ set(CMAKE_REQUIRED_LIBRARIES "sigrokdecode")
+ foreach (LPATH ${PKGDEPS_LIBRARY_DIRS})
+ list(APPEND CMAKE_REQUIRED_LINK_OPTIONS "-L${LPATH}")
+ endforeach ()
+ check_c_source_compiles("
+ #include <libsigrokdecode/libsigrokdecode.h>
+ int main(int argc, char *argv[])
+ {
+ (void)argc;
+ (void)argv;
+ return srd_session_send_eof(NULL);
+ }
+ " HAVE_SRD_SESSION_SEND_EOF)
+ cmake_pop_check_state()
endif()
#===============================================================================
#= System Introspection
#-------------------------------------------------------------------------------
-include(memaccess)
memaccess_check_unaligned_le(HAVE_UNALIGNED_LITTLE_ENDIAN_ACCESS)
#===============================================================================
set(PV_TITLE PulseView)
set(PV_VERSION_STRING "0.5.0")
-set(PV_GLIBMM_VERSION ${PKGDEPS_glibmm-2.4_VERSION})
+if(GLIBMM_2_4_FOUND)
+ set(PV_GLIBMM_VERSION ${PKGDEPS_glibmm-2.4_VERSION})
+else()
+ set(PV_GLIBMM_VERSION ${PKGDEPS_glibmm-2.68_VERSION})
+endif()
include(GetGitRevisionDescription)
)
endif()
-qt5_add_resources(pulseview_RESOURCES_RCC ${pulseview_RESOURCES})
+if(Qt5_FOUND)
+ qt5_add_resources(pulseview_RESOURCES_RCC ${pulseview_RESOURCES})
+else()
+ qt6_add_resources(pulseview_RESOURCES_RCC ${pulseview_RESOURCES})
+endif()
#===============================================================================
#= Translations
configure_file("translations.qrc" "translations.qrc" COPYONLY)
endif ()
-qt5_add_translation(QM_FILES ${TS_FILES})
-qt5_create_translation(QM_FILES ${pulseview_SOURCES} ${TS_FILES})
-
-qt5_add_resources(pulseview_RESOURCES_RCC ${CMAKE_BINARY_DIR}/translations.qrc)
+if(Qt5_FOUND)
+ qt5_add_translation(QM_FILES ${TS_FILES})
+ qt5_add_resources(pulseview_RESOURCES_RCC ${CMAKE_BINARY_DIR}/translations.qrc)
+ if (ENABLE_TS_UPDATE)
+ qt5_create_translation(QM_FILES ${pulseview_SOURCES} ${TS_FILES})
+ endif ()
+else()
+ qt6_add_translation(QM_FILES ${TS_FILES})
+ qt6_add_resources(pulseview_RESOURCES_RCC ${CMAKE_BINARY_DIR}/translations.qrc)
+ if (ENABLE_TS_UPDATE)
+ qt6_create_translation(QM_FILES ${pulseview_SOURCES} ${TS_FILES})
+ endif ()
+endif()
#===============================================================================
#= Global Definitions
add_definitions(-DQT_NO_KEYWORDS)
add_definitions(-D__STDC_LIMIT_MACROS)
add_definitions(-Wall -Wextra)
-add_definitions(-std=c++11)
+add_definitions(${REQUIRED_STD_CXX_FLAGS})
+
add_definitions(-DBOOST_MATH_DISABLE_FLOAT128=1)
if(WIN32)
add_definitions(-Wa,-mbig-obj -O3)
# We also need QWindowsIntegrationPlugin, Qt5PlatformSupport (only for
# Qt < 5.8.0), and all Qt libs and their dependencies.
add_definitions(-DQT_STATICPLUGIN)
- list(APPEND PULSEVIEW_LINK_LIBS Qt5::QSvgPlugin)
- list(APPEND PULSEVIEW_LINK_LIBS Qt5::QWindowsIntegrationPlugin)
- if(Qt5Gui_VERSION VERSION_LESS 5.8.0)
- list(APPEND PULSEVIEW_LINK_LIBS -lQt5PlatformSupport)
+ if(Qt5_FOUND)
+ list(APPEND PULSEVIEW_LINK_LIBS Qt5::QSvgPlugin)
+ list(APPEND PULSEVIEW_LINK_LIBS Qt5::QWindowsIntegrationPlugin)
+ if(Qt5Gui_VERSION VERSION_LESS 5.8.0)
+ list(APPEND PULSEVIEW_LINK_LIBS -lQt5PlatformSupport)
+ endif()
+ list(APPEND PULSEVIEW_LINK_LIBS ${QT5ALL_LDFLAGS})
+ else()
+ list(APPEND PULSEVIEW_LINK_LIBS Qt6::QSvgPlugin)
+ list(APPEND PULSEVIEW_LINK_LIBS Qt6::QWindowsIntegrationPlugin)
+ list(APPEND PULSEVIEW_LINK_LIBS ${QT6ALL_LDFLAGS})
endif()
- list(APPEND PULSEVIEW_LINK_LIBS ${QT5ALL_LDFLAGS})
endif()
if(ENABLE_STACKTRACE)
- libglib >= 2.28.0
- glibmm-2.4 (>= 2.28.0)
- Qt5 (>= 5.3), including the following components:
- - Qt5Core, Qt5Gui, Qt5Widgets, Qt5Svg, Qt5LinguistTools
+ - Qt5Core, Qt5Gui, Qt5Widgets, Qt5Svg,
+ Qt5LinguistTools (qttools5-dev, qttools5-dev-tools)
- Qt translation package (optional; needed at runtime, not build time)
- libboost >= 1.55 (including the following libs):
- libboost-system
IRC
---
-You can find the sigrok developers in the #sigrok IRC channel on Freenode.
+You can find the sigrok developers in the #sigrok IRC channel on Libera.Chat.
Website
/* Platform properties */
#cmakedefine HAVE_UNALIGNED_LITTLE_ENDIAN_ACCESS
+/* Presence of features which depend on library versions. */
+#cmakedefine HAVE_SRD_SESSION_SEND_EOF 1
+
#define PV_GLIBMM_VERSION "@PV_GLIBMM_VERSION@"
#endif
.TP
.B "CTRL+w"
Close the current session tab.
+.TP
+.B "SHIFT+mouse wheel"
+Scroll horizontally instead of zooming in/out.
.SH "EXIT STATUS"
.B PulseView
exits with 0 on success, 1 on most failures.
<context>
<name>Application</name>
<message>
- <location filename="../pv/application.cpp" line="129"/>
+ <location filename="../pv/application.cpp" line="137"/>
<source>Some parts of the application may still use the previous language. Re-opening the affected windows or restarting the application will remedy this.</source>
- <translation>Algunas partes de la aplicación aún pueden usar el idioma anterior. Volver a abrir las ventanas afectadas o reiniciar la aplicación solucionará esto.</translation>
+ <translation>Algunas partes de la aplicación podrían seguir usando el idioma anterior. Volver a abrir las ventanas afectadas o reiniciar la aplicación solucionará esto.</translation>
</message>
</context>
<context>
<context>
<name>QHexView</name>
<message>
- <location filename="../pv/views/decoder_binary/QHexView.cpp" line="291"/>
+ <location filename="../pv/views/decoder_binary/QHexView.cpp" line="339"/>
<source>No data available</source>
<translation>Datos no disponibles</translation>
</message>
<context>
<name>QObject</name>
<message>
- <location filename="../main.cpp" line="114"/>
+ <location filename="../main.cpp" line="116"/>
<source>Stack trace of previous crash:</source>
- <translation>Stack trace de crash previo:</translation>
+ <translation>Seguimiento de pila del fallo anterior:</translation>
</message>
<message>
- <location filename="../main.cpp" line="128"/>
+ <location filename="../main.cpp" line="130"/>
<source>Don't show this message again</source>
- <translation>No mostrar este mensaje de nuevo</translation>
+ <translation>No volver a mostrar este mensaje</translation>
</message>
<message>
- <location filename="../main.cpp" line="131"/>
+ <location filename="../main.cpp" line="133"/>
<source>When %1 last crashed, it created a stack trace.
A human-readable form has been saved to disk and was written to the log. You may access it from the settings dialog.</source>
- <translation>Cuando %1 se bloqueó por última vez, creó un stack trace.\nSe guardó un formulario legible en el disco y fue escrito en el log. Puedes acceder a el desde el dialogo de configuración.</translation>
+ <translation>Cuando %1 se bloqueó por última vez, creó un seguimiento de pila.
+Se guardó un formulario legible para humanosen el disco y fue escrito en el log. Puedes acceder a el desde el dialogo de configuración.</translation>
</message>
<message>
<location filename="../pv/devicemanager.cpp" line="65"/>
<translation>PulseView</translation>
</message>
<message>
- <location filename="../pv/mainwindow.cpp" line="279"/>
+ <location filename="../pv/mainwindow.cpp" line="284"/>
<source>Decoder Selector</source>
- <translation>Selección de decoder</translation>
+ <translation>Selección de decodificador</translation>
</message>
<message>
- <location filename="../pv/mainwindow.cpp" line="332"/>
+ <location filename="../pv/mainwindow.cpp" line="337"/>
<source>Session %1</source>
<translation>Sesión %1</translation>
</message>
<message>
- <location filename="../pv/mainwindow.cpp" line="514"/>
+ <location filename="../pv/mainwindow.cpp" line="519"/>
<source>Create New Session</source>
- <translation>Crear Nueva Sesión</translation>
+ <translation>Crear nueva sesión</translation>
</message>
<message>
- <location filename="../pv/mainwindow.cpp" line="520"/>
+ <location filename="../pv/mainwindow.cpp" line="525"/>
<source>Start/Stop Acquisition</source>
- <translation>Iniciar/Detener Adquisición</translation>
+ <translation>Iniciar/Detener adquisición</translation>
</message>
<message>
- <location filename="../pv/mainwindow.cpp" line="528"/>
+ <location filename="../pv/mainwindow.cpp" line="533"/>
<source>Settings</source>
- <translation>Configuraciones</translation>
+ <translation>Ajustes</translation>
</message>
<message>
- <location filename="../pv/mainwindow.cpp" line="580"/>
+ <location filename="../pv/mainwindow.cpp" line="589"/>
<source>Reload</source>
<translation>Recargar</translation>
</message>
<message>
- <location filename="../pv/mainwindow.cpp" line="580"/>
- <location filename="../pv/mainwindow.cpp" line="583"/>
+ <location filename="../pv/mainwindow.cpp" line="589"/>
+ <location filename="../pv/mainwindow.cpp" line="592"/>
<source>Run</source>
<translation>Ejecutar</translation>
</message>
<message>
- <location filename="../pv/mainwindow.cpp" line="589"/>
+ <location filename="../pv/mainwindow.cpp" line="598"/>
<source>Stop</source>
<translation>Detener</translation>
</message>
<message>
- <location filename="../pv/mainwindow.cpp" line="635"/>
- <location filename="../pv/mainwindow.cpp" line="829"/>
- <location filename="../pv/mainwindow.cpp" line="855"/>
+ <location filename="../pv/mainwindow.cpp" line="644"/>
+ <location filename="../pv/mainwindow.cpp" line="867"/>
+ <location filename="../pv/mainwindow.cpp" line="893"/>
<source>Confirmation</source>
<translation>Confirmación</translation>
</message>
<message>
- <location filename="../pv/mainwindow.cpp" line="636"/>
+ <location filename="../pv/mainwindow.cpp" line="645"/>
<source>There is unsaved data. Close anyway?</source>
- <translation>Hay datos sin guardar. Cerrar de todos modos?</translation>
+ <translation>Hay datos sin guardar. ¿Cerrar de todos modos?</translation>
</message>
<message>
- <location filename="../pv/mainwindow.cpp" line="830"/>
- <location filename="../pv/mainwindow.cpp" line="856"/>
+ <location filename="../pv/mainwindow.cpp" line="868"/>
+ <location filename="../pv/mainwindow.cpp" line="894"/>
<source>This session contains unsaved data. Close it anyway?</source>
- <translation>Esta sesión contiene datos sin almacenar. Cerrar de todos modos?</translation>
+ <translation>Esta sesión contiene datos sin guardar. ¿Cerrar de todos modos?</translation>
</message>
</context>
<context>
<name>pv::Session</name>
<message>
- <location filename="../pv/session.cpp" line="521"/>
+ <location filename="../pv/session.cpp" line="559"/>
<source>Failed to select device</source>
+ <translatorcomment>Si en el panel "Sources and forms" la cadena de texto está dentro de "show_session_error(tr("Failed to ..."),e)" traducir "Failed " como "Error"</translatorcomment>
<translation>Error al seleccionar dispositivo</translation>
</message>
<message>
- <location filename="../pv/session.cpp" line="578"/>
+ <location filename="../pv/session.cpp" line="616"/>
<source>Failed to open device</source>
<translation>Error al abrir dispositivo</translation>
</message>
<message>
- <location filename="../pv/session.cpp" line="684"/>
+ <location filename="../pv/session.cpp" line="722"/>
<source>Error</source>
<translation>Error</translation>
</message>
<translation type="vanished">Formato de entrada inesperado: %s</translation>
</message>
<message>
- <location filename="../pv/session.cpp" line="685"/>
+ <location filename="../pv/session.cpp" line="396"/>
+ <source>Can't restore generated signal of unknown type %1 (%2)</source>
+ <translation>No se puede restaurar la señal generada de tipo desconocido %1 ( %2)</translation>
+ </message>
+ <message>
+ <location filename="../pv/session.cpp" line="723"/>
<source>Unexpected input format: %1</source>
- <translation type="unfinished"></translation>
+ <translation>Formato de entrada inesperado: %1</translation>
</message>
<message>
- <location filename="../pv/session.cpp" line="720"/>
+ <location filename="../pv/session.cpp" line="758"/>
<source>Failed to load %1</source>
<translation>Error al cargar %1</translation>
</message>
<message>
- <location filename="../pv/session.cpp" line="759"/>
+ <location filename="../pv/session.cpp" line="797"/>
<source>No active device set, can't start acquisition.</source>
<translation>No hay un dispositivo activo configurado, no se puede iniciar la adquisición.</translation>
</message>
<message>
- <location filename="../pv/session.cpp" line="772"/>
+ <location filename="../pv/session.cpp" line="810"/>
<source>No channels enabled.</source>
<translation>No hay canales habilitados.</translation>
</message>
<message>
- <location filename="../pv/session.cpp" line="1261"/>
+ <location filename="../pv/session.cpp" line="1318"/>
<source>Out of memory, acquisition stopped.</source>
<translation>Sin memoria, la adquisición se detuvo.</translation>
</message>
<message>
- <location filename="../pv/session.cpp" line="1467"/>
+ <location filename="../pv/session.cpp" line="1525"/>
<source>Can't handle more than 64 logic channels.</source>
<translation>No puede manejar más de 64 canales lógicos.</translation>
</message>
<translation>No se puede guardar el rango sin datos de muestra.</translation>
</message>
<message>
- <location filename="../pv/storesession.cpp" line="188"/>
- <location filename="../pv/storesession.cpp" line="295"/>
+ <location filename="../pv/storesession.cpp" line="191"/>
+ <location filename="../pv/storesession.cpp" line="298"/>
+ <location filename="../pv/storesession.cpp" line="313"/>
<source>Error while saving: </source>
<translation>Error al guardar: </translation>
</message>
<context>
<name>pv::binding::Device</name>
<message>
- <location filename="../pv/binding/device.cpp" line="97"/>
+ <location filename="../pv/binding/device.cpp" line="82"/>
+ <source>Note for device developers: Ignoring device configuration capability '%1' as it is missing GET and/or SET</source>
+ <translation>Nota para desarrolladores de dispositivos: Ignorar la capacidad de configuración del dispositivo '%1', ya que falta GET y/o SET</translation>
+ </message>
+ <message>
+ <location filename="../pv/binding/device.cpp" line="107"/>
<source>No Limit</source>
- <translation type="unfinished"></translation>
+ <translation>Sín límite</translation>
</message>
</context>
<context>
<name>pv::data::DecodeSignal</name>
<message>
- <location filename="../pv/data/decodesignal.cpp" line="198"/>
+ <location filename="../pv/data/decodesignal.cpp" line="223"/>
<source>No decoders</source>
<translation>Sin decodificadores</translation>
</message>
<message>
- <location filename="../pv/data/decodesignal.cpp" line="205"/>
+ <location filename="../pv/data/decodesignal.cpp" line="230"/>
<source>There are no channels assigned to this decoder</source>
<translation>No hay canales asignados a este decodificador</translation>
</message>
<message>
- <location filename="../pv/data/decodesignal.cpp" line="219"/>
+ <location filename="../pv/data/decodesignal.cpp" line="244"/>
<source>One or more required channels have not been specified</source>
<translation>No se han especificado uno o más canales requeridos</translation>
</message>
<message>
- <location filename="../pv/data/decodesignal.cpp" line="238"/>
+ <location filename="../pv/data/decodesignal.cpp" line="260"/>
<source>No input data</source>
<translation>Sin datos de entrada</translation>
</message>
<message>
- <location filename="../pv/data/decodesignal.cpp" line="1172"/>
+ <location filename="../pv/data/decodesignal.cpp" line="1325"/>
<source>Decoder reported an error</source>
<translation>El decodificador reportó un error</translation>
</message>
<message>
- <location filename="../pv/data/decodesignal.cpp" line="1308"/>
+ <location filename="../pv/data/decodesignal.cpp" line="1484"/>
<source>Failed to create decoder instance</source>
<translation>Error al crear la instancia del decodificador</translation>
</message>
</context>
+<context>
+ <name>pv::data::MathSignal</name>
+ <message>
+ <location filename="../pv/data/mathsignal.cpp" line="107"/>
+ <source>Math%1</source>
+ <translation>Math%1</translation>
+ </message>
+ <message>
+ <location filename="../pv/data/mathsignal.cpp" line="306"/>
+ <source>No expression defined, nothing to do</source>
+ <translation>Sin expresión definida, nada que hacer</translation>
+ </message>
+ <message>
+ <location filename="../pv/data/mathsignal.cpp" line="345"/>
+ <source>%1 at line %2, column %3: %4</source>
+ <translation>%1 en línea %2, columna %3: %4</translation>
+ </message>
+ <message>
+ <location filename="../pv/data/mathsignal.cpp" line="364"/>
+ <location filename="../pv/data/mathsignal.cpp" line="536"/>
+ <source>"%1" isn't a valid analog signal</source>
+ <translation>"%1" no es una señal analógica válida</translation>
+ </message>
+ <message>
+ <location filename="../pv/data/mathsignal.cpp" line="374"/>
+ <location filename="../pv/data/mathsignal.cpp" line="611"/>
+ <source>No data will be generated as %1 must be enabled</source>
+ <translation>No se generarán datos ya que %1 debe estar habilitado</translation>
+ </message>
+</context>
<context>
<name>pv::data::SignalBase</name>
<message>
- <location filename="../pv/data/signalbase.cpp" line="485"/>
+ <location filename="../pv/data/signalbase.cpp" line="525"/>
<source>Signal average</source>
<translation>Promedio de la señal</translation>
</message>
<message>
- <location filename="../pv/data/signalbase.cpp" line="486"/>
+ <location filename="../pv/data/signalbase.cpp" line="526"/>
<source>0.9V (for 1.8V CMOS)</source>
<translation>0.9V (para 1.8V CMOS)</translation>
</message>
<message>
- <location filename="../pv/data/signalbase.cpp" line="487"/>
+ <location filename="../pv/data/signalbase.cpp" line="527"/>
<source>1.8V (for 3.3V CMOS)</source>
<translation>1.8V (para 3.3V CMOS)</translation>
</message>
<message>
- <location filename="../pv/data/signalbase.cpp" line="488"/>
+ <location filename="../pv/data/signalbase.cpp" line="528"/>
<source>2.5V (for 5.0V CMOS)</source>
<translation>2.5V (para 5.0V CMOS)</translation>
</message>
<message>
- <location filename="../pv/data/signalbase.cpp" line="489"/>
+ <location filename="../pv/data/signalbase.cpp" line="529"/>
<source>1.5V (for TTL)</source>
<translation>1.5V (para TTL)</translation>
</message>
<message>
- <location filename="../pv/data/signalbase.cpp" line="494"/>
+ <location filename="../pv/data/signalbase.cpp" line="534"/>
<source>Signal average +/- 15%</source>
<translation>Promedio de la señal +/- 15%</translation>
</message>
<message>
- <location filename="../pv/data/signalbase.cpp" line="495"/>
+ <location filename="../pv/data/signalbase.cpp" line="535"/>
<source>0.3V/1.2V (for 1.8V CMOS)</source>
<translation>0.3V/1.2V (para 1.8V CMOS)</translation>
</message>
<message>
- <location filename="../pv/data/signalbase.cpp" line="496"/>
+ <location filename="../pv/data/signalbase.cpp" line="536"/>
<source>0.7V/2.5V (for 3.3V CMOS)</source>
<translation>0.7V/2.5V (para 3.3V CMOS)</translation>
</message>
<message>
- <location filename="../pv/data/signalbase.cpp" line="497"/>
+ <location filename="../pv/data/signalbase.cpp" line="537"/>
<source>1.3V/3.7V (for 5.0V CMOS)</source>
<translation>1.3V/3.7V (para 5.0V CMOS)</translation>
</message>
<message>
- <location filename="../pv/data/signalbase.cpp" line="498"/>
+ <location filename="../pv/data/signalbase.cpp" line="538"/>
<source>0.8V/2.0V (for TTL)</source>
<translation>0.8V/2.0V (para TTL)</translation>
</message>
<message>
<location filename="../pv/dialogs/connect.cpp" line="58"/>
<source>&Scan for devices using driver above</source>
- <translation>E&Scanea por dispositivos utilizando el driver de arriba</translation>
+ <translation>E&scanea por dispositivos utilizando el controlador de arriba</translation>
</message>
<message>
<location filename="../pv/dialogs/connect.cpp" line="63"/>
<message>
<location filename="../pv/dialogs/connect.cpp" line="75"/>
<source>Step 1: Choose the driver</source>
- <translation>Paso 1: Elige el driver</translation>
+ <translation>Paso 1: Elige el controlador</translation>
</message>
<message>
<location filename="../pv/dialogs/connect.cpp" line="79"/>
<message>
<location filename="../pv/dialogs/connect.cpp" line="80"/>
<source>Serial &Port</source>
- <translation>&Puerto Serial</translation>
+ <translation>&Puerto serial</translation>
</message>
<message>
<location filename="../pv/dialogs/connect.cpp" line="81"/>
<message>
<location filename="../pv/dialogs/connect.cpp" line="140"/>
<source>Step 3: Scan for devices</source>
- <translation>Paso 3: Escanear por dispositivos</translation>
+ <translation>Paso 3: Escanea por dispositivos</translation>
</message>
<message>
<location filename="../pv/dialogs/connect.cpp" line="146"/>
</message>
<message>
<location filename="../pv/dialogs/settings.cpp" line="153"/>
- <location filename="../pv/dialogs/settings.cpp" line="397"/>
+ <location filename="../pv/dialogs/settings.cpp" line="415"/>
<source>Decoders</source>
<translation>Decodificadores</translation>
</message>
<message>
<location filename="../pv/dialogs/settings.cpp" line="172"/>
<source>Logging</source>
- <translation>Logging</translation>
+ <translation>Registros</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="236"/>
+ <location filename="../pv/dialogs/settings.cpp" line="241"/>
<source>User interface language</source>
- <translation>Lenguaje de la interfaz de usuario</translation>
+ <translation>Idioma de la interfaz de usuario</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="247"/>
+ <location filename="../pv/dialogs/settings.cpp" line="252"/>
<source>User interface theme</source>
<translation>Tema de la interfaz de usuario</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="249"/>
+ <location filename="../pv/dialogs/settings.cpp" line="254"/>
<source>(You may need to restart PulseView for all UI elements to update)</source>
<translation>(Es posible que deba reiniciar PulseView para que se actualicen todos los elementos de la interfaz de usuario)</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="255"/>
+ <location filename="../pv/dialogs/settings.cpp" line="260"/>
<source>System Default</source>
- <translation>Default del sistema</translation>
+ <translation>Por defecto del sistema</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="268"/>
+ <location filename="../pv/dialogs/settings.cpp" line="273"/>
<source>Qt widget style</source>
- <translation>Estilo de Qt widget</translation>
+ <translation>Estilo de widget Qt</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="270"/>
+ <location filename="../pv/dialogs/settings.cpp" line="275"/>
<source>(Dark themes look best with the Fusion style)</source>
<translation>(Los temas oscuros se ven mejor con el estilo Fusion)</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="277"/>
+ <location filename="../pv/dialogs/settings.cpp" line="282"/>
<source>Save session &setup along with .sr file</source>
<translation>Guardar &configuración de sesión junto al archivo .sr</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="291"/>
+ <location filename="../pv/dialogs/settings.cpp" line="286"/>
+ <source>Start acquisition for all open sessions when clicking 'Run'</source>
+ <translation>Iniciar adquisición para todas las sesiones abiertas al dar clic en 'Ejecutar'</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="301"/>
<source>Trace View</source>
- <translation>Vista de trazo</translation>
+ <translation>Vista de señales</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="299"/>
+ <location filename="../pv/dialogs/settings.cpp" line="309"/>
<source>Use colored trace &background</source>
- <translation>Use &fondo de trazas coloreado</translation>
+ <translation>Usar &fondo de trazos coloreado</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="303"/>
+ <location filename="../pv/dialogs/settings.cpp" line="313"/>
<source>Constantly perform &zoom-to-fit during acquisition</source>
<translation>Realizar constantemente zoom para &ajustar durante la adquisición</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="307"/>
+ <location filename="../pv/dialogs/settings.cpp" line="317"/>
<source>Perform a zoom-to-&fit when acquisition stops</source>
- <translation>Realice un zoom para ajustar cuando la adquisición se &detenga</translation>
+ <translation>Realizar un zoom para ajustar cuando la adquisición se &detenga</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="311"/>
<source>Show time zero at the trigger</source>
- <translation>Mostrar el tiempo cero en el trigger</translation>
+ <translation type="vanished">Mostrar el tiempo cero en el trigger</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="315"/>
+ <location filename="../pv/dialogs/settings.cpp" line="325"/>
<source>Always keep &newest samples at the right edge during capture</source>
- <translation>Mantenga siempre las muestras más &recientes en el borde derecho durante la captura</translation>
+ <translation>Mantener siempre las muestras más &recientes en el borde derecho durante la captura</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="319"/>
+ <location filename="../pv/dialogs/settings.cpp" line="333"/>
<source>Show data &sampling points</source>
- <translation>Mostrar puntos de datos &sampleados</translation>
+ <translation>Mostrar puntos de datos mue&streados</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="323"/>
<source>Fill high areas of logic signals</source>
- <translation>Rellenar áreas altas de señales lógicas</translation>
+ <translation type="vanished">Rellenar áreas altas de señales lógicas</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="321"/>
+ <source>Show time zero at the &trigger</source>
+ <translation>Mostrar tiempo cero en el &disparo</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="329"/>
+ <source>Allow &vertical dragging in the view area</source>
+ <translation>Permitir arrastre &vertical in el área de vista</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="337"/>
+ <source>Fill &high areas of logic signals</source>
+ <translation>Llenar áreas en &alto de señales lógicas</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="330"/>
+ <location filename="../pv/dialogs/settings.cpp" line="344"/>
<source>Color to fill high areas of logic signals with</source>
<translation>Color para llenar áreas altas de señales lógicas</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="334"/>
+ <location filename="../pv/dialogs/settings.cpp" line="348"/>
<source>Show analog minor grid in addition to div grid</source>
- <translation>Mostrar cuadrícula menor analogíca además de cuadrícula por div</translation>
+ <translation>Mostrar cuadrícula menor analógica además de cuadrícula por división</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="338"/>
+ <location filename="../pv/dialogs/settings.cpp" line="352"/>
<source>Highlight mouse cursor using a vertical marker line</source>
- <translation>Resalte el cursor del mouse usando una línea de marcador vertical</translation>
+ <translation>Resaltar el cursor del mouse usando una línea de marcador vertical</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="342"/>
- <location filename="../pv/dialogs/settings.cpp" line="368"/>
- <location filename="../pv/dialogs/settings.cpp" line="377"/>
+ <location filename="../pv/dialogs/settings.cpp" line="356"/>
+ <source>Keep active item on ruler selected when editing popup is closed</source>
+ <translation>Mantener el elemento activo seleccionado en la regla cuando se cierre la ventana de edición emergente</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="360"/>
+ <location filename="../pv/dialogs/settings.cpp" line="386"/>
+ <location filename="../pv/dialogs/settings.cpp" line="395"/>
<source> pixels</source>
<translation> píxeles</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="347"/>
+ <location filename="../pv/dialogs/settings.cpp" line="365"/>
<source>Maximum distance from edges before markers snap to them</source>
<translation>Distancia máxima desde los bordes antes de que los marcadores se ajusten a ellos</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="354"/>
+ <location filename="../pv/dialogs/settings.cpp" line="372"/>
<source>Color to fill cursor area with</source>
<translation>Color para llenar el área del cursor</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="357"/>
+ <location filename="../pv/dialogs/settings.cpp" line="375"/>
<source>None</source>
<translation>Ninguna</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="358"/>
+ <location filename="../pv/dialogs/settings.cpp" line="376"/>
<source>Background</source>
<translation>Fondo</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="359"/>
+ <location filename="../pv/dialogs/settings.cpp" line="377"/>
<source>Dots</source>
<translation>Puntos</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="364"/>
+ <location filename="../pv/dialogs/settings.cpp" line="382"/>
<source>Conversion threshold display mode (analog traces only)</source>
- <translation>Modo de visualización del umbral de conversión (solo trazas analógicas)</translation>
+ <translation>Modo de visualización del umbral de conversión (solo trazos analógicos)</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="373"/>
+ <location filename="../pv/dialogs/settings.cpp" line="391"/>
<source>Default analog trace div height</source>
- <translation>Altura de div de trazo análogo por defecto</translation>
+ <translation>Altura de división de trazo analógico por defecto</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="382"/>
+ <location filename="../pv/dialogs/settings.cpp" line="400"/>
<source>Default logic trace height</source>
<translation>Altura de trazo lógico por defecto</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="405"/>
+ <location filename="../pv/dialogs/settings.cpp" line="423"/>
<source>Allow configuration of &initial signal state</source>
<translation>Permitir configuración de estado de señal &inicial</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="409"/>
+ <location filename="../pv/dialogs/settings.cpp" line="427"/>
<source>Always show all &rows, even if no annotation is visible</source>
<translation>Mostrar siempre todas las &filas, incluso si no hay ninguna anotación visible</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="417"/>
+ <location filename="../pv/dialogs/settings.cpp" line="435"/>
<source>Annotation export format</source>
<translation>Formato de exportación de anotaciones</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="418"/>
+ <location filename="../pv/dialogs/settings.cpp" line="436"/>
<source>%s = sample range; %d: decoder name; %r: row name; %c: class name</source>
<translation>%s = rango de muestra; %d: nombre del decodificador; %r: nombre de fila; %c: nombre de clase</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="421"/>
+ <location filename="../pv/dialogs/settings.cpp" line="439"/>
<source>%1: longest annotation text; %a: all annotation texts; %q: use quotation marks</source>
<translation>%1: texto de anotación más largo; %a: todos los textos de anotación; %q: use comillas</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="441"/>
+ <location filename="../pv/dialogs/settings.cpp" line="459"/>
<source>%1<br /><a href="http://%2">%2</a></source>
<translation>%1<br /><a href="http://%2">%2</a></translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="442"/>
+ <location filename="../pv/dialogs/settings.cpp" line="460"/>
<source>GNU GPL, version 3 or later</source>
<translation>GNU GPL, versión 3 o posterior</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="453"/>
+ <location filename="../pv/dialogs/settings.cpp" line="471"/>
<source>Versions, libraries and features:</source>
- <translation>Versiones, librerías y características:</translation>
+ <translation>Versiones, bibliotecas y características:</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="460"/>
+ <location filename="../pv/dialogs/settings.cpp" line="478"/>
<source>Firmware search paths:</source>
<translation>Rutas de búsqueda de firmware:</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="467"/>
+ <location filename="../pv/dialogs/settings.cpp" line="485"/>
<source>Protocol decoder search paths:</source>
<translation>Ruta de búsqueda del decodificador de protocolo:</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="474"/>
+ <location filename="../pv/dialogs/settings.cpp" line="488"/>
+ <source><tr><td colspan="2">(Note: Set environment variable SIGROKDECODE_DIR to add a custom directory)</td></tr></source>
+ <translation><tr> <td colspan = "2"> (Nota: Establecer variable de entorno SIGROKDECODE_DIR para agregar un directorio personalizado) </td> </tr></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="493"/>
<source>Supported hardware drivers:</source>
- <translation>Drivers de hardware soportados:</translation>
+ <translation>Controladores de hardware soportados:</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="481"/>
+ <location filename="../pv/dialogs/settings.cpp" line="500"/>
<source>Supported input formats:</source>
<translation>Formatos de entrada soportados:</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="488"/>
+ <location filename="../pv/dialogs/settings.cpp" line="507"/>
<source>Supported output formats:</source>
<translation>Formatos de salida soportados:</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="496"/>
+ <location filename="../pv/dialogs/settings.cpp" line="515"/>
<source>Supported protocol decoders:</source>
<translation>Decodificadores de protocolo soportados:</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="504"/>
+ <location filename="../pv/dialogs/settings.cpp" line="523"/>
<source>Available Translations:</source>
- <translation type="unfinished"></translation>
+ <translation>Traducciones disponibles:</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="552"/>
+ <location filename="../pv/dialogs/settings.cpp" line="571"/>
<source>Log level:</source>
- <translation>Nivel de log:</translation>
+ <translation>Nivel de registro:</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="557"/>
+ <location filename="../pv/dialogs/settings.cpp" line="576"/>
<source> lines</source>
<translation> líneas</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="566"/>
+ <location filename="../pv/dialogs/settings.cpp" line="585"/>
<source>Length of background buffer:</source>
<translation>Longitud del búfer de fondo:</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="572"/>
+ <location filename="../pv/dialogs/settings.cpp" line="591"/>
<source>&Save to File</source>
<translation>&Guardar en archivo</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="579"/>
+ <location filename="../pv/dialogs/settings.cpp" line="598"/>
<source>&Pop out</source>
- <translation>&Pop out</translation>
+ <translation>Des&plegar</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="648"/>
+ <location filename="../pv/dialogs/settings.cpp" line="667"/>
<source>You selected a dark theme.
Should I set the user-adjustable colors to better suit your choice?
Please keep in mind that PulseView may need a restart to display correctly.</source>
- <translation>Seleccionaste el tema obscuro.\nDebería de establecer los colores ajustables por el usuario que mejor se ajustan a tu elección?\n\nPor favor ten en cuenta que Pulseview tal vez se tenga que reiniciar para mostrar correctamente.</translation>
+ <translation>Seleccionaste un tema oscuro.
+¿Debería de establecer los colores ajustables por el usuario a los que mejor se ajustan a tu elección?
+
+Por favor ten en cuenta que Pulseview tal vez se tenga que reiniciar para mostrarse correctamente.</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="654"/>
+ <location filename="../pv/dialogs/settings.cpp" line="673"/>
<source>You selected a bright theme.
Should I set the user-adjustable colors to better suit your choice?
Please keep in mind that PulseView may need a restart to display correctly.</source>
- <translation>Seleccionaste el tema brillante.\nDebería de establecer los colores ajustables por el usuario que mejor se ajustan a tu elección?\n\nPor favor ten en cuenta que Pulseview tal vez se tenga que reiniciar para mostrar correctamente.</translation>
+ <translation>Seleccionaste un tema claro.
+¿Debería de establecer los colores ajustables por el usuario a los que mejor se ajustan a tu elección?
+
+Por favor ten en cuenta que Pulseview tal vez se tenga que reiniciar para mostrarse correctamente.</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="807"/>
+ <location filename="../pv/dialogs/settings.cpp" line="844"/>
<source>Save Log</source>
- <translation>Guardar log</translation>
+ <translation>Guardar registro</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="807"/>
+ <location filename="../pv/dialogs/settings.cpp" line="844"/>
<source>Log Files (*.txt *.log);;All Files (*)</source>
- <translation>Archivos de log (*.txt *.log);;Todos los archivos (*)</translation>
+ <translation>Archivos de registro (*.txt *.log);;Todos los archivos (*)</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="819"/>
+ <location filename="../pv/dialogs/settings.cpp" line="856"/>
<source>Success</source>
<translation>Éxito</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="819"/>
+ <location filename="../pv/dialogs/settings.cpp" line="856"/>
<source>Log saved to %1.</source>
- <translation>Log guardado en %1.</translation>
+ <translation>Registro guardado en %1.</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="829"/>
+ <location filename="../pv/dialogs/settings.cpp" line="866"/>
<source>Error</source>
<translation>Error</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="829"/>
+ <location filename="../pv/dialogs/settings.cpp" line="866"/>
<source>File %1 could not be written to.</source>
<translation>No se pudo escribir en el archivo%1.</translation>
</message>
<message>
- <location filename="../pv/dialogs/settings.cpp" line="843"/>
+ <location filename="../pv/dialogs/settings.cpp" line="880"/>
<source>%1 Log</source>
<translation>%1 Log</translation>
</message>
<translation>Cancelar</translation>
</message>
<message>
- <location filename="../pv/dialogs/storeprogress.cpp" line="85"/>
+ <location filename="../pv/dialogs/storeprogress.cpp" line="89"/>
<source>Failed to save session.</source>
<translation>Error al guardar sesión.</translation>
</message>
<message>
<location filename="../pv/popups/channels.cpp" line="62"/>
<location filename="../pv/popups/channels.cpp" line="63"/>
- <location filename="../pv/popups/channels.cpp" line="273"/>
- <location filename="../pv/popups/channels.cpp" line="300"/>
+ <location filename="../pv/popups/channels.cpp" line="278"/>
+ <location filename="../pv/popups/channels.cpp" line="305"/>
<source>All</source>
<translation>Todo</translation>
</message>
<location filename="../pv/popups/channels.cpp" line="66"/>
<location filename="../pv/popups/channels.cpp" line="67"/>
<source>Analog</source>
- <translation>Análogo</translation>
+ <translation>Análogico</translation>
</message>
<message>
<location filename="../pv/popups/channels.cpp" line="68"/>
<translation>Habilitar: </translation>
</message>
<message>
- <location filename="../pv/popups/channels.cpp" line="281"/>
- <location filename="../pv/popups/channels.cpp" line="301"/>
+ <location filename="../pv/popups/channels.cpp" line="286"/>
+ <location filename="../pv/popups/channels.cpp" line="306"/>
<source>None</source>
<translation>Ninguna</translation>
</message>
<message>
<location filename="../pv/subwindows/decoder_selector/model.cpp" line="40"/>
<source>Decoder</source>
- <translation>Decoder</translation>
+ <translation>Decodificador</translation>
</message>
<message>
<location filename="../pv/subwindows/decoder_selector/model.cpp" line="41"/>
<message>
<location filename="../pv/subwindows/decoder_selector/model.cpp" line="49"/>
<source>All Decoders</source>
- <translation>Todos los decoders</translation>
+ <translation>Todos los decodificadores</translation>
</message>
</context>
<context>
<message>
<location filename="../pv/subwindows/decoder_selector/subwindow.cpp" line="49"/>
<source>Select a decoder to see its description here.</source>
- <translation>Seleccione un decoder para ver su descripción aquí.</translation>
+ <translation>Selecciona un decodificador para ver su descripción aquí.</translation>
</message>
<message>
- <location filename="../pv/subwindows/decoder_selector/subwindow.cpp" line="247"/>
+ <location filename="../pv/subwindows/decoder_selector/subwindow.cpp" line="248"/>
<source>, %1</source>
<translation>, %1</translation>
</message>
<message>
- <location filename="../pv/subwindows/decoder_selector/subwindow.cpp" line="264"/>
+ <location filename="../pv/subwindows/decoder_selector/subwindow.cpp" line="265"/>
<source><p align='right'>Tags: %1</p></source>
- <translation><p align='right'>Tags: %1</p></translation>
+ <translation><p align='right'>Etiquetas: %1</p></translation>
</message>
<message>
- <location filename="../pv/subwindows/decoder_selector/subwindow.cpp" line="311"/>
+ <location filename="../pv/subwindows/decoder_selector/subwindow.cpp" line="312"/>
<source>Protocol decoder <b>%1</b> requires input type <b>%2</b> which several decoders provide.<br>Choose which one to use:<br></source>
<translation>Decodificador de protocolo <b>%1</b> requiere tipo de entrada <b>%2</b> que proporcionan varios decodificadores.<br>Elige cúal usar:<br></translation>
</message>
<message>
- <location filename="../pv/subwindows/decoder_selector/subwindow.cpp" line="319"/>
+ <location filename="../pv/subwindows/decoder_selector/subwindow.cpp" line="320"/>
<source>Choose Decoder</source>
- <translation>Elige Decoder</translation>
+ <translation>Elige decodificador</translation>
</message>
</context>
<context>
<name>pv::toolbars::MainBar</name>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="121"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="124"/>
<source>New &View</source>
<translation>Nueva &Vista</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="127"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="130"/>
<source>&Open...</source>
<translation>&Abrir...</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="134"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="141"/>
<source>Restore Session Setu&p...</source>
<translation>Restaurar Configu&ración de Sesión...</translation>
</message>
<translation type="vanished">G&uardar Como...</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="138"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="145"/>
<source>&Save...</source>
- <translation type="unfinished">&Guardar...</translation>
+ <translation>&Guardar...</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="145"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="156"/>
<source>Save &As...</source>
- <translation type="unfinished"></translation>
+ <translation>Guardar Como...</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="151"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="162"/>
<source>Save Selected &Range As...</source>
<translation>Guardar &Rango Seleccionado Como...</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="158"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="173"/>
<source>Save Session Setu&p...</source>
<translation>Guardar Confi&guración de Sesión...</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="164"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="179"/>
<source>&Export</source>
- <translation>&Exporta</translation>
+ <translation>&Exportar</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="170"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="185"/>
<source>&Import</source>
- <translation>&Importa</translation>
+ <translation>&Importar</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="174"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="189"/>
<source>&Connect to Device...</source>
- <translation>&Conecta a Dispositivo...</translation>
+ <translation>&Conectar a Dispositivo...</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="236"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="251"/>
<source>Add protocol decoder</source>
<translation>Agregar decodificador de protocolo</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="252"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="261"/>
+ <source>Add math signal</source>
+ <translation>Agregar señal matemática</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="277"/>
<source>Configure Device</source>
- <translation>Configura Dispositivo</translation>
+ <translation>Configurar Dispositivo</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="256"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="281"/>
<source>Configure Channels</source>
- <translation>Configura Canales</translation>
+ <translation>Configurar Canales</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="370"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="395"/>
<source>Failed to get sample rate list:</source>
<translation>Error al obtener la lista de frecuencia de muestreo:</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="433"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="458"/>
<source>Failed to get sample rate:</source>
- <translation>Error al obtener la lista de frecuencia de muestreo:</translation>
+ <translation>Error al obtener la frecuencia de muestreo:</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="474"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="499"/>
<source>Failed to get sample limit list:</source>
<translation>Error al obtener la lista de límites de muestra:</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="564"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="589"/>
<source>Failed to configure samplerate:</source>
<translation>Error al configurar frecuencia de muestreo:</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="591"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="616"/>
<source>Failed to configure sample count:</source>
<translation>Error al configurar cuenta de muestras:</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="629"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="654"/>
<source>Missing Cursors</source>
<translation>Cursores Faltantes</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="629"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="654"/>
<source>You need to set the cursors before you can save the data enclosed by them to a session file (e.g. using the Show Cursors button).</source>
- <translation>Debe configurar los cursores antes de poder guardar los datos encerrados en un archivo de sesión (por ejemplo, usando el botón Mostrar Cursores).</translation>
+ <translation>Debes configurar los cursores antes de poder guardar los datos encerrados en un archivo de sesión (por ejemplo, usando el botón Mostrar Cursores).</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="647"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="672"/>
<source>Invalid Range</source>
<translation>Rango Inválido</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="647"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="672"/>
<source>The cursors don't define a valid range of samples.</source>
<translation>Los cursores no definen un rango válido de muestras.</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="659"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="684"/>
<source>%1 files </source>
<translation>%1 archivos </translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="667"/>
- <location filename="../pv/toolbars/mainbar.cpp" line="717"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="692"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="742"/>
<source>All Files</source>
<translation>Todos los archivos</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="671"/>
- <location filename="../pv/toolbars/mainbar.cpp" line="848"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="696"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="873"/>
<source>Save File</source>
<translation>Guardar Archivo</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="683"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="708"/>
<source>Export %1</source>
- <translation>Exporta %1</translation>
+ <translation>Exportar %1</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="714"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="739"/>
<source>%1 files</source>
<translation>%1 archivos</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="725"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="750"/>
<source>Import File</source>
- <translation>Importa Archivo</translation>
+ <translation>Importar Archivo</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="734"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="759"/>
<source>Import %1</source>
- <translation>Importa %1</translation>
+ <translation>Importar %1</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="807"/>
- <location filename="../pv/toolbars/mainbar.cpp" line="865"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="832"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="890"/>
<source>Open File</source>
<translation>Abrir Archivo</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="807"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="832"/>
<source>sigrok Sessions (*.sr);;All Files (*)</source>
<translation>Sesiones sigrok (*sr);;Todos los archivos (*)</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="848"/>
- <location filename="../pv/toolbars/mainbar.cpp" line="865"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="873"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="890"/>
<source>PulseView Session Setups (*.pvs);;All Files (*)</source>
<translation>Configurciones de Sesión de PulseView (*.pvs);;Todos los Archivos (*)</translation>
</message>
<message>
- <location filename="../pv/toolbars/mainbar.cpp" line="926"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="958"/>
<source>Total sampling time: %1</source>
<translation>Tiempo de muestreo total: %1</translation>
</message>
<message>
<location filename="../pv/views/decoder_binary/view.cpp" line="93"/>
<source>Hexdump</source>
- <translation>Hexdump</translation>
+ <translation>Volcado hexadecimal</translation>
</message>
<message>
<location filename="../pv/views/decoder_binary/view.cpp" line="110"/>
<translation>&Guardar...</translation>
</message>
<message>
- <location filename="../pv/views/decoder_binary/view.cpp" line="258"/>
- <location filename="../pv/views/decoder_binary/view.cpp" line="298"/>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="270"/>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="310"/>
<source>Save Binary Data</source>
<translation>Guardar Datos Binarios</translation>
</message>
<message>
- <location filename="../pv/views/decoder_binary/view.cpp" line="258"/>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="270"/>
<source>Binary Data Files (*.bin);;All Files (*)</source>
- <translation>Archivos de Datos Binarios (*.txt);;Todos los archivos (*)</translation>
+ <translation>Archivos de Datos Binarios (*.bin);;Todos los archivos (*)</translation>
</message>
<message>
- <location filename="../pv/views/decoder_binary/view.cpp" line="277"/>
- <location filename="../pv/views/decoder_binary/view.cpp" line="329"/>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="289"/>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="349"/>
<source>Error</source>
<translation>Error</translation>
</message>
<message>
- <location filename="../pv/views/decoder_binary/view.cpp" line="277"/>
- <location filename="../pv/views/decoder_binary/view.cpp" line="329"/>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="289"/>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="349"/>
<source>File %1 could not be written to.</source>
<translation>No se pudo escribir en el archivo%1.</translation>
</message>
<message>
- <location filename="../pv/views/decoder_binary/view.cpp" line="298"/>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="310"/>
<source>Hex Dumps (*.txt);;All Files (*)</source>
- <translation>Hex Dumps (*.txt);;Todos los archivos (*)</translation>
+ <translation>Volcados hexadecimales (*.txt);;Todos los archivos (*)</translation>
</message>
</context>
<context>
<message>
<location filename="../pv/views/tabular_decoder/model.cpp" line="56"/>
<source>Sample</source>
- <translation type="unfinished"></translation>
+ <translation>Muestra</translation>
</message>
<message>
<location filename="../pv/views/tabular_decoder/model.cpp" line="57"/>
<source>Time</source>
- <translation type="unfinished">Tiempo</translation>
+ <translation>Tiempo</translation>
</message>
<message>
<location filename="../pv/views/tabular_decoder/model.cpp" line="58"/>
<source>Decoder</source>
- <translation type="unfinished">Decoder</translation>
+ <translation>Decodificador</translation>
</message>
<message>
<location filename="../pv/views/tabular_decoder/model.cpp" line="59"/>
<source>Ann Row</source>
- <translation type="unfinished"></translation>
+ <translation>Fila de anotación</translation>
</message>
<message>
<location filename="../pv/views/tabular_decoder/model.cpp" line="60"/>
<source>Ann Class</source>
- <translation type="unfinished"></translation>
+ <translation>Clase de anotación</translation>
</message>
<message>
<location filename="../pv/views/tabular_decoder/model.cpp" line="61"/>
<source>Value</source>
- <translation type="unfinished"></translation>
+ <translation>Valor</translation>
</message>
<message>
<location filename="../pv/views/tabular_decoder/model.cpp" line="83"/>
<source>s</source>
- <translation type="unfinished"></translation>
+ <translation>s</translation>
</message>
<message>
<location filename="../pv/views/tabular_decoder/model.cpp" line="83"/>
<source>sa</source>
- <translation type="unfinished"></translation>
+ <translation>sa</translation>
</message>
</context>
<context>
<message>
<location filename="../pv/views/tabular_decoder/view.cpp" line="176"/>
<source>Decoder:</source>
- <translation type="unfinished">Decodificador:</translation>
+ <translation>Decodificador:</translation>
</message>
<message>
<location filename="../pv/views/tabular_decoder/view.cpp" line="198"/>
<source>Hide Hidden Rows/Classes</source>
- <translation type="unfinished"></translation>
+ <translation>Ocultar Filas/Columnas ocultas</translation>
</message>
<message>
<location filename="../pv/views/tabular_decoder/view.cpp" line="202"/>
<source>&Save...</source>
- <translation type="unfinished">&Guardar...</translation>
+ <translation>&Guardar...</translation>
</message>
<message>
- <location filename="../pv/views/tabular_decoder/view.cpp" line="374"/>
+ <location filename="../pv/views/tabular_decoder/view.cpp" line="378"/>
<source>Save Annotations as CSV</source>
- <translation type="unfinished"></translation>
+ <translation>Guardar anotaciones como CSV</translation>
</message>
<message>
- <location filename="../pv/views/tabular_decoder/view.cpp" line="374"/>
+ <location filename="../pv/views/tabular_decoder/view.cpp" line="378"/>
<source>CSV Files (*.csv);;Text Files (*.txt);;All Files (*)</source>
- <translation type="unfinished"></translation>
+ <translation>Archivos CSV (*.csv);;Archivos de texto (*.txt);;Todos los archivos (*)</translation>
</message>
<message>
- <location filename="../pv/views/tabular_decoder/view.cpp" line="442"/>
+ <location filename="../pv/views/tabular_decoder/view.cpp" line="446"/>
<source>Error</source>
- <translation type="unfinished">Error</translation>
+ <translation>Error</translation>
</message>
<message>
- <location filename="../pv/views/tabular_decoder/view.cpp" line="442"/>
+ <location filename="../pv/views/tabular_decoder/view.cpp" line="446"/>
<source>File %1 could not be written to.</source>
- <translation type="unfinished">No se pudo escribir en el archivo%1.</translation>
+ <translation>No se pudo escribir en el archivo%1.</translation>
</message>
</context>
<context>
<name>pv::views::trace::AnalogSignal</name>
<message>
- <location filename="../pv/views/trace/analogsignal.cpp" line="994"/>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="802"/>
<source>Number of pos vertical divs</source>
- <translation>Número de divisiones verticales pos</translation>
+ <translation>Número de divisiones verticales positivas</translation>
</message>
<message>
- <location filename="../pv/views/trace/analogsignal.cpp" line="1001"/>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="810"/>
<source>Number of neg vertical divs</source>
- <translation>Número de divisiones verticales neg</translation>
+ <translation>Número de divisiones verticales negativas</translation>
</message>
<message>
- <location filename="../pv/views/trace/analogsignal.cpp" line="1006"/>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="815"/>
<source> pixels</source>
<translation> píxeles</translation>
</message>
<message>
- <location filename="../pv/views/trace/analogsignal.cpp" line="1010"/>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="819"/>
<source>Div height</source>
- <translation>Altura de div</translation>
+ <translation>Altura de división</translation>
</message>
<message>
- <location filename="../pv/views/trace/analogsignal.cpp" line="1027"/>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="837"/>
<source>V/div</source>
- <translation>V/div</translation>
+ <translation>V/división</translation>
</message>
<message>
- <location filename="../pv/views/trace/analogsignal.cpp" line="1031"/>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="841"/>
<source>Vertical resolution</source>
<translation>Resolución vertical</translation>
</message>
<message>
- <location filename="../pv/views/trace/analogsignal.cpp" line="1040"/>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="850"/>
<source>Autoranging</source>
<translation>Autorango</translation>
</message>
<message>
- <location filename="../pv/views/trace/analogsignal.cpp" line="1045"/>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="855"/>
<source>none</source>
<translation>ninguna</translation>
</message>
<message>
- <location filename="../pv/views/trace/analogsignal.cpp" line="1047"/>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="857"/>
<source>to logic via threshold</source>
<translation>a nivel lógico a partir de umbral</translation>
</message>
<message>
- <location filename="../pv/views/trace/analogsignal.cpp" line="1049"/>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="859"/>
<source>to logic via schmitt-trigger</source>
- <translation>a nivel lógico a partir de schmitt trigger</translation>
+ <translation>a nivel lógico a partir de schmitt-trigger</translation>
</message>
<message>
- <location filename="../pv/views/trace/analogsignal.cpp" line="1055"/>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="865"/>
<source>Conversion</source>
<translation>Conversión</translation>
</message>
<message>
- <location filename="../pv/views/trace/analogsignal.cpp" line="1064"/>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="874"/>
<source>Conversion threshold(s)</source>
<translation>Umbral(es) de conversión</translation>
</message>
<message>
- <location filename="../pv/views/trace/analogsignal.cpp" line="1074"/>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="884"/>
<source>analog</source>
- <translation>análogo</translation>
+ <translation>señal análogica</translation>
</message>
<message>
- <location filename="../pv/views/trace/analogsignal.cpp" line="1075"/>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="885"/>
<source>converted</source>
- <translation>convertida</translation>
+ <translation>señal convertida</translation>
</message>
<message>
- <location filename="../pv/views/trace/analogsignal.cpp" line="1076"/>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="886"/>
<source>analog+converted</source>
- <translation>Analógico+convertido</translation>
+ <translation>señales analógica + convertida</translation>
</message>
<message>
- <location filename="../pv/views/trace/analogsignal.cpp" line="1081"/>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="891"/>
<source>Show traces for</source>
- <translation>Mostrar trazos para</translation>
+ <translation>Mostrar trazos de</translation>
</message>
</context>
<context>
<message>
<location filename="../pv/views/trace/cursorpair.cpp" line="128"/>
<source>Display interval</source>
- <translation>Muestra intervalo</translation>
+ <translation>Mostrar intervalo</translation>
</message>
<message>
<location filename="../pv/views/trace/cursorpair.cpp" line="140"/>
<source>Display frequency</source>
- <translation>Muestra frecuencia</translation>
+ <translation>Mostrar frecuencia</translation>
</message>
<message>
<location filename="../pv/views/trace/cursorpair.cpp" line="152"/>
<source>Display samples</source>
- <translation>Muestra samples</translation>
+ <translation>Mostrar muestras</translation>
</message>
</context>
<context>
<name>pv::views::trace::DecodeTrace</name>
<message>
- <location filename="../pv/views/trace/decodetrace.cpp" line="449"/>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="456"/>
<source><p><i>No decoders in the stack</i></p></source>
- <translation><p><i>No hay decodificadores en el stack.</i></p></translation>
+ <translation><p><i>No hay decodificadores en la pila.</i></p></translation>
</message>
<message>
- <location filename="../pv/views/trace/decodetrace.cpp" line="460"/>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="467"/>
<source><i>* Required channels</i></source>
<translation><i>* Canales requeridos</i></translation>
</message>
<message>
- <location filename="../pv/views/trace/decodetrace.cpp" line="464"/>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="471"/>
<source>Stack Decoder</source>
- <translation>Decodificadores</translation>
+ <translation>Apilar Decodificador</translation>
</message>
<message>
- <location filename="../pv/views/trace/decodetrace.cpp" line="465"/>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="472"/>
<source>Stack a higher-level decoder on top of this one</source>
<translation>Apilar un decodificador de nivel superior encima de este</translation>
</message>
<message>
- <location filename="../pv/views/trace/decodetrace.cpp" line="479"/>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="486"/>
<source>Delete</source>
<translation>Eliminar</translation>
</message>
<message>
- <location filename="../pv/views/trace/decodetrace.cpp" line="521"/>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="528"/>
<source>Resume decoding</source>
<translation>Reanudar decodificación</translation>
</message>
<message>
- <location filename="../pv/views/trace/decodetrace.cpp" line="528"/>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="535"/>
<source>Pause decoding</source>
<translation>Pausar decodificación</translation>
</message>
<message>
- <location filename="../pv/views/trace/decodetrace.cpp" line="536"/>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="543"/>
<source>Copy annotation text to clipboard</source>
- <translation>Copiar texto de anotación al clipboard</translation>
+ <translation>Copiar texto de anotación al portapapeles</translation>
</message>
<message>
- <location filename="../pv/views/trace/decodetrace.cpp" line="545"/>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="552"/>
<source>Export all annotations</source>
<translation>Exportar todas las anotaciones</translation>
</message>
<message>
- <location filename="../pv/views/trace/decodetrace.cpp" line="552"/>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="559"/>
<source>Export all annotations for this row</source>
<translation>Exportar todas las anotaciones para esta fila</translation>
</message>
<message>
- <location filename="../pv/views/trace/decodetrace.cpp" line="561"/>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="568"/>
<source>Export all annotations, starting here</source>
<translation>Exportar todas las anotaciones, comenzando aquí</translation>
</message>
<message>
- <location filename="../pv/views/trace/decodetrace.cpp" line="568"/>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="575"/>
<source>Export annotations for this row, starting here</source>
<translation>Exportar todas las anotaciones para esta fila, comenzando aquí</translation>
</message>
<message>
- <location filename="../pv/views/trace/decodetrace.cpp" line="577"/>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="584"/>
<source>Export all annotations within cursor range</source>
<translation>Exportar todas las anotaciones dentro del rango del cursor</translation>
</message>
<message>
- <location filename="../pv/views/trace/decodetrace.cpp" line="584"/>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="591"/>
<source>Export annotations for this row within cursor range</source>
<translation>Exportar todas las anotaciones para esta fila dentro del rango del cursor</translation>
</message>
<message>
- <location filename="../pv/views/trace/decodetrace.cpp" line="1076"/>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1079"/>
<source>%1:
%2</source>
<translation>%1\n%2</translation>
</message>
<message>
- <location filename="../pv/views/trace/decodetrace.cpp" line="1120"/>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1123"/>
<source><b>%1</b> (%2) %3</source>
<translation><b>%1</b> (%2) %3</translation>
</message>
<message>
- <location filename="../pv/views/trace/decodetrace.cpp" line="1190"/>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1192"/>
<source>Export annotations</source>
<translation>Exportar anotaciones</translation>
</message>
<message>
- <location filename="../pv/views/trace/decodetrace.cpp" line="1190"/>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1192"/>
<source>Text Files (*.txt);;All Files (*)</source>
- <translation>Archivos de texto (*.txt *.log);;Todos los archivos (*)</translation>
+ <translation>Archivos de texto (*.txt);;Todos los archivos (*)</translation>
</message>
<message>
- <location filename="../pv/views/trace/decodetrace.cpp" line="1255"/>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1257"/>
<source>Error</source>
<translation>Error</translation>
</message>
<message>
- <location filename="../pv/views/trace/decodetrace.cpp" line="1255"/>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1257"/>
<source>File %1 could not be written to.</source>
<translation>No se pudo escribir en el archivo%1.</translation>
</message>
<message>
- <location filename="../pv/views/trace/decodetrace.cpp" line="1308"/>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1324"/>
<source>Show this row</source>
- <translation>Muestra esta fila</translation>
+ <translation>Mostrar esta fila</translation>
</message>
<message>
- <location filename="../pv/views/trace/decodetrace.cpp" line="1319"/>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1335"/>
<source>Show All</source>
- <translation>Muestra todo</translation>
+ <translation>Mostrar todo</translation>
</message>
<message>
- <location filename="../pv/views/trace/decodetrace.cpp" line="1327"/>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1343"/>
<source>Hide All</source>
- <translation>Oculta todo</translation>
+ <translation>Ocultar todo</translation>
</message>
</context>
<context>
<name>pv::views::trace::Flag</name>
<message>
- <location filename="../pv/views/trace/flag.cpp" line="132"/>
+ <location filename="../pv/views/trace/flag.cpp" line="144"/>
<source>Text</source>
<translation>Texto</translation>
</message>
<message>
- <location filename="../pv/views/trace/flag.cpp" line="141"/>
+ <location filename="../pv/views/trace/flag.cpp" line="153"/>
<source>Delete</source>
<translation>Eliminar</translation>
</message>
<message>
- <location filename="../pv/views/trace/flag.cpp" line="146"/>
+ <location filename="../pv/views/trace/flag.cpp" line="158"/>
<source>Disable snapping</source>
- <translation>Deshabilita snapping</translation>
+ <translation>Deshabilitar snapping</translation>
</message>
</context>
<context>
<context>
<name>pv::views::trace::LogicSignal</name>
<message>
- <location filename="../pv/views/trace/logicsignal.cpp" line="451"/>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="423"/>
<source>No trigger</source>
<translation>Sin trigger</translation>
</message>
<message>
- <location filename="../pv/views/trace/logicsignal.cpp" line="456"/>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="428"/>
<source>Trigger on rising edge</source>
<translation>Trigger en flanco de subida</translation>
</message>
<message>
- <location filename="../pv/views/trace/logicsignal.cpp" line="461"/>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="433"/>
<source>Trigger on high level</source>
<translation>Trigger en nivel alto</translation>
</message>
<message>
- <location filename="../pv/views/trace/logicsignal.cpp" line="466"/>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="438"/>
<source>Trigger on falling edge</source>
<translation>Trigger en flanco de bajada</translation>
</message>
<message>
- <location filename="../pv/views/trace/logicsignal.cpp" line="471"/>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="443"/>
<source>Trigger on low level</source>
<translation>Trigger en nivel bajo</translation>
</message>
<message>
- <location filename="../pv/views/trace/logicsignal.cpp" line="476"/>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="448"/>
<source>Trigger on rising or falling edge</source>
<translation>Trigger en flanco de subida o bajada</translation>
</message>
<message>
- <location filename="../pv/views/trace/logicsignal.cpp" line="563"/>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="535"/>
<source> pixels</source>
<translation> pixeles</translation>
</message>
<message>
- <location filename="../pv/views/trace/logicsignal.cpp" line="567"/>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="539"/>
<source>Trace height</source>
<translation>Altura del trazo</translation>
</message>
<message>
- <location filename="../pv/views/trace/logicsignal.cpp" line="591"/>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="563"/>
<source>Trigger</source>
<translation>Trigger</translation>
</message>
</context>
+<context>
+ <name>pv::views::trace::MathEditDialog</name>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="88"/>
+ <source>Math Expression Editor</source>
+ <translation>Editor de expresiones matemáticas</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="93"/>
+ <source>Inputs:</source>
+ <translation>Entradas:</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="99"/>
+ <source>Variables:</source>
+ <translation>Variables:</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="101"/>
+ <source>Basic operators:</source>
+ <translation>Operadores básicos:</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="108"/>
+ <source>Assignments:</source>
+ <translation>Asignaciones:</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="118"/>
+ <source>General purpose functions:</source>
+ <translation>Funciones de propósito general:</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="119"/>
+ <source>abs(x) Absolute value of x</source>
+ <translation>abs(x) Valor absoluto de x</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="120"/>
+ <source>avg(x, y, ...) Average of all input values</source>
+ <translation>avg(x, y, ...) Promedio de todos los valores de entrada</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="121"/>
+ <source>ceil(x) Smallest integer that is greater than or equal to x</source>
+ <translation>ceil(x) Entero más pequeño que es mayor o igual a x</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="122"/>
+ <source>clamp(lb, x, ub) Clamp x in range between lb and ub, where lb < ub</source>
+ <translation>clamp(lb, x, ub) Fija x en el rango entre lb y ub, donde lb < ub</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="123"/>
+ <source>equal(x, y) Equality test between x and y using normalised epsilon</source>
+ <translation>equal(x, y) Prueba de igualdad entre x e y usando epsilon normalizado</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="124"/>
+ <source>erf(x) Error function of x</source>
+ <translation>erf(x) Función error de x</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="125"/>
+ <source>erfc(x) Complimentary error function of x</source>
+ <translation>erfc(x) Función de error complementario de x</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="126"/>
+ <source>exp(x) e to the power of x</source>
+ <translation>exp(x) e a la potencia de x</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="127"/>
+ <source>expm1(x) e to the power of x minus 1, where x is very small.</source>
+ <translation>expm1(x) e a la potencia de x menos 1, donde z es muy pequeño.</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="128"/>
+ <source>floor(x) Largest integer that is less than or equal to x</source>
+ <translation>floor(x) Entero más grande que is menor o igual a x</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="129"/>
+ <source>frac(x) Fractional portion of x</source>
+ <translation>frac(x) Porción fraccional de x</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="130"/>
+ <source>hypot(x) Hypotenuse of x and y (i.e. sqrt(x*x + y*y))</source>
+ <translation>hypot(x) Hipotenusa de x e y (es decir sqrt(x*x + y*y))</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="131"/>
+ <source>iclamp(lb, x, ub) Inverse-clamp x outside of the range lb and ub, where lb < ub.
+ If x is within the range it will snap to the closest bound</source>
+ <translation>iclamp(lb, x, ub) Fijación inversa de x fuera del rango lb y ub, donde lb < ub.
+ Si x está en el rango se fijará al límite más cercano</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="132"/>
+ <source>inrange(lb, x, ub) In-range returns true when x is within the range lb and ub, where lb < ub.</source>
+ <translation>inrange(lb, x, ub) En-rango regresa verdadero cuando x está en el rango lb y ub, donde lb < ub.</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="133"/>
+ <source>log(x) Natural logarithm of x</source>
+ <translation>log(x) Logaritmo natural de x</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="134"/>
+ <source>log10(x) Base 10 logarithm of x</source>
+ <translation>log10(x) Logaritmo base 10 de x</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="138"/>
+ <source>log1p(x) Natural logarithm of 1 + x, where x is very small</source>
+ <translation>log1p(x) Logaritmo natural de 1 + x, donde x es muy pequeño</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="139"/>
+ <source>log2(x) Base 2 logarithm of x</source>
+ <translation>log2(x) Logaritmo base 2 de x</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="140"/>
+ <source>logn(x) Base N logarithm of x, where n is a positive integer</source>
+ <translation>logn(x) Logaritmo base N de x, donde n es un entero positivo</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="141"/>
+ <source>max(x, y, ...) Largest value of all the inputs</source>
+ <translation>max(x, y, ...) Valor más grande de todas las entradas</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="142"/>
+ <source>min(x, y, ...) Smallest value of all the inputs</source>
+ <translation>min(x, y, ...) Valor más pequeño de todas las entradas</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="143"/>
+ <source>mul(x, y, ...) Product of all the inputs</source>
+ <translation>mul(x, y, ...) Producto de todas las entradas</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="144"/>
+ <source>ncdf(x) Normal cumulative distribution function</source>
+ <translation>ncdf(x) Función de distribución acumulativa normal</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="145"/>
+ <source>nequal(x, y) Not-equal test between x and y using normalised epsilon</source>
+ <translation>nequal(x, y) Prueba de no igualdad entre x e y usando epsilon normalizado</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="146"/>
+ <source>pow(x, y) x to the power of y</source>
+ <translation>pow(x, y) x a la potencia de y</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="147"/>
+ <source>root(x, n) Nth-Root of x, where n is a positive integer</source>
+ <translation>root(x, n) Enésima raíz de x, donde n es un entero positivo</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="148"/>
+ <source>round(x) Round x to the nearest integer</source>
+ <translation>round(x) Redondear x al entero más cercano</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="149"/>
+ <source>roundn(x, n) Round x to n decimal places, where n > 0 and is an integer</source>
+ <translation>roundn(x, n) Redondear x a n lugares decimales, donde n > 0 y es un entero</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="150"/>
+ <source>sgn(x) Sign of x; -1 if x < 0, +1 if x > 0, else zero</source>
+ <translation>sgn(x) Sigon de x; -1 si x < 0, +1 si x > 0, otro cero</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="151"/>
+ <source>sqrt(x) Square root of x, where x >= 0</source>
+ <translation>sqrt(x) Raíz cuadrada de x, donde x >= 0</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="152"/>
+ <source>sum(x, y, ..,) Sum of all the inputs</source>
+ <translation>sum(x, y, ..,) Suma de todas las entradas</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="153"/>
+ <source>swap(x, y) Swap the values of the variables x and y and return the current value of y</source>
+ <translation>swap(x, y) Intercambia los valores de las variables x e y y regresa el valor actual de y</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="154"/>
+ <source>trunc(x) Integer portion of x</source>
+ <translation>trunc(x) Porción entera de x</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="158"/>
+ <source>Trigonometry functions:</source>
+ <translation>Funciones trigonométricas:</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="159"/>
+ <source>acos(x) Arc cosine of x expressed in radians. Interval [-1,+1]</source>
+ <translation>acos(x) Arco coseno de x expresado en radianes. Intervalo [-1,+1]</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="160"/>
+ <source>acosh(x) Inverse hyperbolic cosine of x expressed in radians</source>
+ <translation>acosh(x) Coseno hiperbólico inverso de x expresado en radianes</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="161"/>
+ <source>asin(x) Arc sine of x expressed in radians. Interval [-1,+1]</source>
+ <translation>asin(x) Arco seno de x expresado en radianes. Intervalo [-1,+1]</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="162"/>
+ <source>asinh(x) Inverse hyperbolic sine of x expressed in radians</source>
+ <translation>asinh(x) Seno hiperbólico inverso de x expresado en radianes</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="163"/>
+ <source>atan(x) Arc tangent of x expressed in radians. Interval [-1,+1]</source>
+ <translation>atan(x) Arco tangente de x expresado en radianes. Intervalo [-1,+1]</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="164"/>
+ <source>atan2(x, y) Arc tangent of (x / y) expressed in radians. [-pi,+pi] </source>
+ <translation>atan2(x, y) Arco tangente de (x / y) expresado en radianes. [-pi,+pi] </translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="165"/>
+ <source>atanh(x) Inverse hyperbolic tangent of x expressed in radians</source>
+ <translation>atanh(x) Tangente hiperbólica inversa de x expresada en radianes</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="166"/>
+ <source>cos(x) Cosine of x</source>
+ <translation>cos(x) Coseno de x</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="167"/>
+ <source>cosh(x) Hyperbolic cosine of x</source>
+ <translation>cosh(x) Coseno hiperbólico de x</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="168"/>
+ <source>cot(x) Cotangent of x</source>
+ <translation>cot(x) Cotangente de x</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="169"/>
+ <source>csc(x) Cosectant of x</source>
+ <translation>csc(x) Cosecante de x</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="170"/>
+ <source>sec(x) Secant of x</source>
+ <translation>sec(x) Secante de x</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="171"/>
+ <source>sin(x) Sine of x</source>
+ <translation>sin(x) Seno de x</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="172"/>
+ <source>sinc(x) Sine cardinal of x</source>
+ <translation>sinc(x) Seno cardinal de x</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="173"/>
+ <source>sinh(x) Hyperbolic sine of x</source>
+ <translation>sinh(x) Seno hiperbólico de x</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="174"/>
+ <source>tan(x) Tangent of x</source>
+ <translation>tan(x) Tangente de x</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="175"/>
+ <source>tanh(x) Hyperbolic tangent of x</source>
+ <translation>tanh(x) Tangente hiperbólica de x</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="176"/>
+ <source>deg2rad(x) Convert x from degrees to radians</source>
+ <translation>deg2rad(x) Convierte x de grados sexagesimales a radianes</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="177"/>
+ <source>deg2grad(x) Convert x from degrees to gradians</source>
+ <translation>deg2grad(x) Convierte x de grados sexagesimales a grados centesimales</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="178"/>
+ <source>rad2deg(x) Convert x from radians to degrees</source>
+ <translation>rad2deg(x) Convierte x de radianes a grados sexagesimales</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="179"/>
+ <source>grad2deg(x) Convert x from gradians to degrees</source>
+ <translation>grad2deg(x) Convierte x de grados centesimales a grados sexagesimales</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="183"/>
+ <source>Logic operators:</source>
+ <translation>Operadores lógicos:</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="200"/>
+ <source>Comparisons:</source>
+ <translation>Comparaciones:</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="201"/>
+ <source>x = y or x == y True only if x is strictly equal to y</source>
+ <translation>x = y o x == y Verdadero solo si x es estrictemente igual a y</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="202"/>
+ <source>x <> y or x != y True only if x does not equal y</source>
+ <translation>x <> y o x != y Verdadero solo si x no es igual a y</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="203"/>
+ <source>x < y True only if x is less than y</source>
+ <translation>x < y Verdadero solo si x es menor que y</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="204"/>
+ <source>x <= y True only if x is less than or equal to y</source>
+ <translation>x <= y Verdadero solo si x es menor o igual a y</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="205"/>
+ <source>x > y True only if x is greater than y</source>
+ <translation>x > y Verdadero solo si x es mayor que y</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="206"/>
+ <source>x >= y True only if x is greater than or equal to y</source>
+ <translation>x >= y Verdadero solo si x es mayor o igual a y</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="207"/>
+ <source>Flow control:</source>
+ <translation>Fujo de cotrol:</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="208"/>
+ <source>{ ... } Beginning and end of instruction block</source>
+ <translation>{ ... } Inicio y fin de un bloque de instrucciones</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="209"/>
+ <source>if (x, y, z) If x is true then return y else return z
+if (x) y; variant without implied else
+if (x) { y }; variant with an instruction block
+if (x) y; else z; variant with explicit else
+if (x) { y } else { z }; variant with instruction blocks</source>
+ <translation>if (x, y, z) Si x es verdadero entonces regresa y si no regresa z
+if (x) y; variante sin si no implicado
+if (x) { y }; variante con un bloque de instrucción
+if (x) y; else z; variante con si no explícito
+if (x) { y } else { z }; variante con bloques de instrucciones</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="210"/>
+ <source>x ? y : z Ternary operator, equivalent to 'if (x, y, z)'</source>
+ <translation>x ? y : z Operador ternario, equivalente a 'if (x, y, z)'</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="211"/>
+ <source>switch { The first true case condition that is encountered will
+ case x > 1: a; determine the result of the switch. If none of the case
+ case x < 1: b; conditions hold true, the default action is used
+ default: c; to determine the return value
+}</source>
+ <translation>switch { La primera condición de caso verdadera que es encontrada
+ case x > 1: a; determina el resultado del interruptor. Si ninguno de las condiciones de
+ case x < 1: b; los casos se mantienen verdaderas, la acción predeterminada se usa
+ default: c; para determinar el valor de retorno
+}</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="215"/>
+ <source>while (conditon) { Evaluates expression repeatedly as long as condition is true,
+ expression; returning the last value of expression
+}</source>
+ <translation>while (conditon) { Evalúa la expresión repetidamente siempre que la condición sea verdadera,
+expresión; devuelve el último valor de la expresión
+}</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="216"/>
+ <source>repeat Evalues expression repeatedly as long as condition is false,
+ expression; returning the last value of expression
+until (condition)
+</source>
+ <translation>repeat Evalúa la expresión repetidamente siempre que la condición sea falsa
+expresión; devuelve el último valor de la expresión
+hasta que (condición)
+</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="217"/>
+ <source>for (var x := 0; condition; x += 1) { Repeatedly evaluates expression while the condition is true,
+ expression while evaluating the 'increment' expression on each loop
+}</source>
+ <translation>for (var x := 0; condición; x += 1) { Evalua repetidamente la expresión mientras la condición sea verdadera,
+ expresión mientras se evalúa la expresión de 'incremento' en cada bucle
+}</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="218"/>
+ <source>break Terminates the execution of the nearest enclosed loop, returning NaN</source>
+ <translation>break Finaliza la ejecución del bucle cerrado más cercano, devolviendo NaN</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="219"/>
+ <source>break[x] Terminates the execution of the nearest enclosed loop, returning x</source>
+ <translation>break[x] Finaliza la ejecución del bucle cerrado más cercano, devolviendo x</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="220"/>
+ <source>continue Interrupts loop execution and resumes with the next loop iteration</source>
+ <translation>continue Interrumpe la ejecución del bucle y se reanuda con la siguiente iteración de bucle</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="221"/>
+ <source>return[x] Returns immediately from within the current expression, returning x</source>
+ <translation>return[x] Devuelve inmediatamente desde la expresión actual, regresando x</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="222"/>
+ <source>~(expr; expr; ...) Evaluates each sub-expression and returns the value of the last one
+~{expr; expr; ...}</source>
+ <translation>~(expr; expr; ...) Evalúa cada subexpresión y devuelve el valor de la última
+~{expr; expr; ...}</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="234"/>
+ <source>Copy to expression</source>
+ <translation>Copiar a expresión</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="247"/>
+ <source>Basics</source>
+ <translation>Básicas</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="248"/>
+ <source>Functions 1</source>
+ <translation>Funciones 1</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="249"/>
+ <source>Functions 2</source>
+ <translation>Funciones 2</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="250"/>
+ <source>Trigonometry</source>
+ <translation>Trigonometría</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="251"/>
+ <source>Logic</source>
+ <translation>Lógica</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="252"/>
+ <source>Flow Control 1</source>
+ <translation>Flujo de control 1</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="253"/>
+ <source>Flow Control 2</source>
+ <translation>Flujo de control 2</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="254"/>
+ <source>Examples</source>
+ <translation>Ejemplos</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::MathSignal</name>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="317"/>
+ <source>Expression</source>
+ <translation>Espresión</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="321"/>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="331"/>
+ <source>same as session</source>
+ <translation>igual que la sesión</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="322"/>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="332"/>
+ <source>100</source>
+ <translation>100</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="323"/>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="333"/>
+ <source>10000</source>
+ <translation>10000</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="324"/>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="334"/>
+ <source>1000000</source>
+ <translation>1000000</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="327"/>
+ <source>Number of Samples</source>
+ <translation>Número de muestras</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="335"/>
+ <source>Sample rate</source>
+ <translation>Tasa de muestreo</translation>
+ </message>
+</context>
<context>
<name>pv::views::trace::Ruler</name>
<message>
<location filename="../pv/views/trace/ruler.cpp" line="153"/>
<source>Create marker here</source>
- <translation>Crear marcador aqui</translation>
+ <translation>Crear marcador aquí</translation>
</message>
<message>
<location filename="../pv/views/trace/ruler.cpp" line="157"/>
<message>
<location filename="../pv/views/trace/ruler.cpp" line="175"/>
<source>Disable mouse hover marker</source>
- <translation>Deshabilitar marcador de desplazamiento del mouse</translation>
+ <translation>Deshabilitar marcador de desplazamiento del ratón</translation>
</message>
<message>
<location filename="../pv/views/trace/ruler.cpp" line="175"/>
<source>Enable mouse hover marker</source>
- <translation>Habilitar marcador de desplazamiento del mouse</translation>
+ <translation>Habilitar marcador de desplazamiento del ratón</translation>
</message>
</context>
<context>
<translation>Nombre</translation>
</message>
<message>
- <location filename="../pv/views/trace/signal.cpp" line="164"/>
+ <location filename="../pv/views/trace/signal.cpp" line="167"/>
+ <source>Remove</source>
+ <translation>Eliminar</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/signal.cpp" line="169"/>
<source>Disable</source>
<translation>Deshabilitar</translation>
</message>
<message>
<location filename="../pv/views/trace/standardbar.cpp" line="95"/>
<source>Display a single segment</source>
- <translation>Mostrar solo un segmento</translation>
+ <translation>Mostrar un solo segmento</translation>
</message>
</context>
<context>
<name>pv::views::trace::TimeMarker</name>
<message>
- <location filename="../pv/views/trace/timemarker.cpp" line="191"/>
+ <location filename="../pv/views/trace/timemarker.cpp" line="198"/>
<source>Time</source>
<translation>Tiempo</translation>
</message>
<context>
<name>pv::views::trace::Trace</name>
<message>
- <location filename="../pv/views/trace/trace.cpp" line="206"/>
+ <location filename="../pv/views/trace/trace.cpp" line="229"/>
<source>Create marker here</source>
- <translation>Crear marcador aqui</translation>
+ <translation>Crear marcador aquí</translation>
</message>
<message>
- <location filename="../pv/views/trace/trace.cpp" line="315"/>
+ <location filename="../pv/views/trace/trace.cpp" line="338"/>
<source>Color</source>
<translation>Color</translation>
</message>
<message>
- <location filename="../pv/views/trace/trace.cpp" line="380"/>
+ <location filename="../pv/views/trace/trace.cpp" line="403"/>
<source>Name</source>
<translation>Nombre</translation>
</message>
<translation>Desagrupar</translation>
</message>
</context>
+<context>
+ <name>pv::views::trace::View</name>
+ <message>
+ <location filename="../pv/views/trace/view.cpp" line="1610"/>
+ <source>Create marker here</source>
+ <translation>Crear marcador aquí</translation>
+ </message>
+</context>
<context>
<name>pv::widgets::DecoderGroupBox</name>
<message>
<location filename="../pv/widgets/decodergroupbox.cpp" line="48"/>
<source>Show/hide this decoder trace</source>
- <translation>Mostrar / ocultar este trazo de decodificador</translation>
+ <translation>Mostrar/ocultar este trazo de decodificador</translation>
</message>
<message>
<location filename="../pv/widgets/decodergroupbox.cpp" line="58"/>
<context>
<name>pv::widgets::DeviceToolButton</name>
<message>
- <location filename="../pv/widgets/devicetoolbutton.cpp" line="75"/>
- <location filename="../pv/widgets/devicetoolbutton.cpp" line="82"/>
+ <location filename="../pv/widgets/devicetoolbutton.cpp" line="80"/>
+ <location filename="../pv/widgets/devicetoolbutton.cpp" line="87"/>
<source><No Device></source>
<translation><Sin dispositivo></translation>
</message>
<message>
<location filename="../pv/widgets/exportmenu.cpp" line="71"/>
<source>Export %1...</source>
- <translation>Exporta %1...</translation>
+ <translation>Exportar %1...</translation>
</message>
</context>
<context>
<message>
<location filename="../pv/widgets/importmenu.cpp" line="68"/>
<source>Import %1...</source>
- <translation>Importa %1...</translation>
+ <translation>Importar %1...</translation>
</message>
</context>
</TS>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="ja_JP">
+<context>
+ <name>Application</name>
+ <message>
+ <location filename="../pv/application.cpp" line="131"/>
+ <source>Some parts of the application may still use the previous language. Re-opening the affected windows or restarting the application will remedy this.</source>
+ <translation>アプリケーションの一部では、以前の言語が引き続き使用される場合があります。 影響を受けたウィンドウを再度開くか、アプリケーションを再起動すると、これが改善されます。</translation>
+ </message>
+</context>
+<context>
+ <name>QApplication</name>
+ <message>
+ <location filename="../pv/devicemanager.cpp" line="274"/>
+ <source>Error when scanning device driver '%1': %2</source>
+ <translation>デバイスドライバ'%1'をスキャンするときにエラーが発生しました:%2</translation>
+ </message>
+ <message>
+ <location filename="../pv/devices/device.cpp" line="70"/>
+ <source>Querying config key %1 is not allowed</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/devices/device.cpp" line="79"/>
+ <source>Querying config key %1 resulted in %2</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/devices/device.cpp" line="93"/>
+ <source>Unknown type supplied when attempting to query %1</source>
+ <translation></translation>
+ </message>
+</context>
+<context>
+ <name>QHexView</name>
+ <message>
+ <location filename="../pv/views/decoder_binary/QHexView.cpp" line="339"/>
+ <source>No data available</source>
+ <translation>データなし</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="../main.cpp" line="116"/>
+ <source>Stack trace of previous crash:</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../main.cpp" line="130"/>
+ <source>Don't show this message again</source>
+ <translation>このメッセージを二度と表示しない</translation>
+ </message>
+ <message>
+ <location filename="../main.cpp" line="133"/>
+ <source>When %1 last crashed, it created a stack trace.
+A human-readable form has been saved to disk and was written to the log. You may access it from the settings dialog.</source>
+ <translation>%1が最後にクラッシュしたとき、スタックトレースが作成されました。
+人間が読める形式がディスクに保存され、ログに書き込まれました。 設定ダイアログからアクセスできます。</translation>
+ </message>
+ <message>
+ <location filename="../pv/devicemanager.cpp" line="65"/>
+ <source>Cancel</source>
+ <translation>キャンセル</translation>
+ </message>
+ <message>
+ <location filename="../pv/devicemanager.cpp" line="96"/>
+ <source>Scanning for devices that driver %1 can access...</source>
+ <translation>ドライバー %1 がアクセスできるデバイスをスキャンしています...</translation>
+ </message>
+</context>
+<context>
+ <name>pv::MainWindow</name>
+ <message>
+ <location filename="../pv/mainwindow.cpp" line="70"/>
+ <source>PulseView</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/mainwindow.cpp" line="279"/>
+ <source>Decoder Selector</source>
+ <translation>デコーダー選択</translation>
+ </message>
+ <message>
+ <location filename="../pv/mainwindow.cpp" line="332"/>
+ <source>Session %1</source>
+ <translation>セッション %1</translation>
+ </message>
+ <message>
+ <location filename="../pv/mainwindow.cpp" line="514"/>
+ <source>Create New Session</source>
+ <translation>新規セッションを作成</translation>
+ </message>
+ <message>
+ <location filename="../pv/mainwindow.cpp" line="520"/>
+ <source>Start/Stop Acquisition</source>
+ <translation>取得の開始/停止</translation>
+ </message>
+ <message>
+ <location filename="../pv/mainwindow.cpp" line="528"/>
+ <source>Settings</source>
+ <translation>設定</translation>
+ </message>
+ <message>
+ <location filename="../pv/mainwindow.cpp" line="580"/>
+ <source>Reload</source>
+ <translation>再読込</translation>
+ </message>
+ <message>
+ <location filename="../pv/mainwindow.cpp" line="580"/>
+ <location filename="../pv/mainwindow.cpp" line="583"/>
+ <source>Run</source>
+ <translation>実行</translation>
+ </message>
+ <message>
+ <location filename="../pv/mainwindow.cpp" line="589"/>
+ <source>Stop</source>
+ <translation>停止</translation>
+ </message>
+ <message>
+ <location filename="../pv/mainwindow.cpp" line="635"/>
+ <location filename="../pv/mainwindow.cpp" line="860"/>
+ <location filename="../pv/mainwindow.cpp" line="886"/>
+ <source>Confirmation</source>
+ <translation>確認</translation>
+ </message>
+ <message>
+ <location filename="../pv/mainwindow.cpp" line="636"/>
+ <source>There is unsaved data. Close anyway?</source>
+ <translation>保存されていないデータがあります。 閉じますか?</translation>
+ </message>
+ <message>
+ <location filename="../pv/mainwindow.cpp" line="861"/>
+ <location filename="../pv/mainwindow.cpp" line="887"/>
+ <source>This session contains unsaved data. Close it anyway?</source>
+ <translation>このセッションには、保存されていないデータが含まれています。 閉じますか?</translation>
+ </message>
+</context>
+<context>
+ <name>pv::Session</name>
+ <message>
+ <location filename="../pv/session.cpp" line="396"/>
+ <source>Can't restore generated signal of unknown type %1 (%2)</source>
+ <translation>不明なタイプ%1 (%2)の生成された信号を復元できません</translation>
+ </message>
+ <message>
+ <location filename="../pv/session.cpp" line="559"/>
+ <source>Failed to select device</source>
+ <translation>デバイスの選択に失敗しました</translation>
+ </message>
+ <message>
+ <location filename="../pv/session.cpp" line="616"/>
+ <source>Failed to open device</source>
+ <translation>デバイスを開くことができませんでした</translation>
+ </message>
+ <message>
+ <location filename="../pv/session.cpp" line="722"/>
+ <source>Error</source>
+ <translation>エラー</translation>
+ </message>
+ <message>
+ <location filename="../pv/session.cpp" line="723"/>
+ <source>Unexpected input format: %1</source>
+ <translation>予期しない入力形式:%1%</translation>
+ </message>
+ <message>
+ <location filename="../pv/session.cpp" line="758"/>
+ <source>Failed to load %1</source>
+ <translation>%1 のロードに失敗しました</translation>
+ </message>
+ <message>
+ <location filename="../pv/session.cpp" line="797"/>
+ <source>No active device set, can't start acquisition.</source>
+ <translation>アクティブなデバイスが設定されていないため、取得を開始できません。</translation>
+ </message>
+ <message>
+ <location filename="../pv/session.cpp" line="810"/>
+ <source>No channels enabled.</source>
+ <translation>チャネルが有効になっていません。</translation>
+ </message>
+ <message>
+ <location filename="../pv/session.cpp" line="1311"/>
+ <source>Out of memory, acquisition stopped.</source>
+ <translation>メモリが不足しているため、取得が停止しました。</translation>
+ </message>
+ <message>
+ <location filename="../pv/session.cpp" line="1518"/>
+ <source>Can't handle more than 64 logic channels.</source>
+ <translation>64を超えるロジックチャネルを処理することはできません。</translation>
+ </message>
+</context>
+<context>
+ <name>pv::StoreSession</name>
+ <message>
+ <location filename="../pv/storesession.cpp" line="114"/>
+ <source>Can't save logic channel without data.</source>
+ <translation>データなしでロジックチャネルを保存することはできません。</translation>
+ </message>
+ <message>
+ <location filename="../pv/storesession.cpp" line="130"/>
+ <source>Can't save analog channel without data.</source>
+ <translation>データなしでアナログチャンネルを保存することはできません。</translation>
+ </message>
+ <message>
+ <location filename="../pv/storesession.cpp" line="142"/>
+ <source>No channels enabled.</source>
+ <translation>チャネルが有効になっていません。</translation>
+ </message>
+ <message>
+ <location filename="../pv/storesession.cpp" line="167"/>
+ <source>Can't save range without sample data.</source>
+ <translation>サンプルデータなしでは範囲を保存できません。</translation>
+ </message>
+ <message>
+ <location filename="../pv/storesession.cpp" line="188"/>
+ <location filename="../pv/storesession.cpp" line="295"/>
+ <location filename="../pv/storesession.cpp" line="310"/>
+ <source>Error while saving: </source>
+ <translation>保存中のエラー:</translation>
+ </message>
+</context>
+<context>
+ <name>pv::binding::Device</name>
+ <message>
+ <location filename="../pv/binding/device.cpp" line="82"/>
+ <source>Note for device developers: Ignoring device configuration capability '%1' as it is missing GET and/or SET</source>
+ <translation>デバイス開発者への注意:GETやSETがないため、デバイス構成機能'%1'を無視します</translation>
+ </message>
+ <message>
+ <location filename="../pv/binding/device.cpp" line="107"/>
+ <source>No Limit</source>
+ <translation></translation>
+ </message>
+</context>
+<context>
+ <name>pv::data::DecodeSignal</name>
+ <message>
+ <location filename="../pv/data/decodesignal.cpp" line="220"/>
+ <source>No decoders</source>
+ <translation>デコーダーなし</translation>
+ </message>
+ <message>
+ <location filename="../pv/data/decodesignal.cpp" line="227"/>
+ <source>There are no channels assigned to this decoder</source>
+ <translation>このデコーダーに割り当てられたチャネルはありません</translation>
+ </message>
+ <message>
+ <location filename="../pv/data/decodesignal.cpp" line="241"/>
+ <source>One or more required channels have not been specified</source>
+ <translation>1つ以上の必要なチャネルが指定されていません</translation>
+ </message>
+ <message>
+ <location filename="../pv/data/decodesignal.cpp" line="257"/>
+ <source>No input data</source>
+ <translation>入力データなし</translation>
+ </message>
+ <message>
+ <location filename="../pv/data/decodesignal.cpp" line="1310"/>
+ <source>Decoder reported an error</source>
+ <translation>デコーダーがエラーを報告しました</translation>
+ </message>
+ <message>
+ <location filename="../pv/data/decodesignal.cpp" line="1464"/>
+ <source>Failed to create decoder instance</source>
+ <translation>デコーダーインスタンスの作成に失敗しました</translation>
+ </message>
+</context>
+<context>
+ <name>pv::data::MathSignal</name>
+ <message>
+ <location filename="../pv/data/mathsignal.cpp" line="107"/>
+ <source>Math%1</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/data/mathsignal.cpp" line="306"/>
+ <source>No expression defined, nothing to do</source>
+ <translation>式は定義されていません、何もしません</translation>
+ </message>
+ <message>
+ <location filename="../pv/data/mathsignal.cpp" line="345"/>
+ <source>%1 at line %2, column %3: %4</source>
+ <translation>%1 行 %2, 列 %3: %4</translation>
+ </message>
+ <message>
+ <location filename="../pv/data/mathsignal.cpp" line="364"/>
+ <location filename="../pv/data/mathsignal.cpp" line="536"/>
+ <source>"%1" isn't a valid analog signal</source>
+ <translation>"%1" は有効なアナログ信号ではありません</translation>
+ </message>
+ <message>
+ <location filename="../pv/data/mathsignal.cpp" line="374"/>
+ <location filename="../pv/data/mathsignal.cpp" line="611"/>
+ <source>No data will be generated as %1 must be enabled</source>
+ <translation>%1を有効にする必要があるため、データは生成されません</translation>
+ </message>
+</context>
+<context>
+ <name>pv::data::SignalBase</name>
+ <message>
+ <location filename="../pv/data/signalbase.cpp" line="525"/>
+ <source>Signal average</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/data/signalbase.cpp" line="526"/>
+ <source>0.9V (for 1.8V CMOS)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/data/signalbase.cpp" line="527"/>
+ <source>1.8V (for 3.3V CMOS)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/data/signalbase.cpp" line="528"/>
+ <source>2.5V (for 5.0V CMOS)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/data/signalbase.cpp" line="529"/>
+ <source>1.5V (for TTL)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/data/signalbase.cpp" line="534"/>
+ <source>Signal average +/- 15%</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/data/signalbase.cpp" line="535"/>
+ <source>0.3V/1.2V (for 1.8V CMOS)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/data/signalbase.cpp" line="536"/>
+ <source>0.7V/2.5V (for 3.3V CMOS)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/data/signalbase.cpp" line="537"/>
+ <source>1.3V/3.7V (for 5.0V CMOS)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/data/signalbase.cpp" line="538"/>
+ <source>0.8V/2.0V (for TTL)</source>
+ <translation></translation>
+ </message>
+</context>
+<context>
+ <name>pv::dialogs::Connect</name>
+ <message>
+ <location filename="../pv/dialogs/connect.cpp" line="58"/>
+ <source>&Scan for devices using driver above</source>
+ <translation>上記のドライバーを使用してデバイスをスキャンする</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/connect.cpp" line="63"/>
+ <source>Connect to Device</source>
+ <translation>デバイスに接続</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/connect.cpp" line="75"/>
+ <source>Step 1: Choose the driver</source>
+ <translation>ステップ1:ドライバーを選択</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/connect.cpp" line="79"/>
+ <source>&USB</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/connect.cpp" line="80"/>
+ <source>Serial &Port</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/connect.cpp" line="81"/>
+ <source>&TCP/IP</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/connect.cpp" line="116"/>
+ <source>Protocol:</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/connect.cpp" line="134"/>
+ <source>Step 2: Choose the interface</source>
+ <translation>ステップ2:インターフェースを選択</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/connect.cpp" line="140"/>
+ <source>Step 3: Scan for devices</source>
+ <translation>ステップ3:デバイスをスキャン</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/connect.cpp" line="146"/>
+ <source>Step 4: Select the device</source>
+ <translation>ステップ4:デバイスを選択</translation>
+ </message>
+</context>
+<context>
+ <name>pv::dialogs::Settings</name>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="134"/>
+ <location filename="../pv/dialogs/settings.cpp" line="213"/>
+ <source>General</source>
+ <translation>全般</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="143"/>
+ <source>Views</source>
+ <translation>表示</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="153"/>
+ <location filename="../pv/dialogs/settings.cpp" line="406"/>
+ <source>Decoders</source>
+ <translation>デコーダー</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="163"/>
+ <source>About</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="172"/>
+ <source>Logging</source>
+ <translation>ロギング</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="236"/>
+ <source>User interface language</source>
+ <translation>表示言語</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="247"/>
+ <source>User interface theme</source>
+ <translation>表示のテーマ</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="249"/>
+ <source>(You may need to restart PulseView for all UI elements to update)</source>
+ <translation>(すべてのUI要素を更新するには、PulseViewを再起動する必要がある場合があります)</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="255"/>
+ <source>System Default</source>
+ <translation>システムのデフォルト</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="268"/>
+ <source>Qt widget style</source>
+ <translation>Qt widget スタイル</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="270"/>
+ <source>(Dark themes look best with the Fusion style)</source>
+ <translation>(ダークテーマはFusionスタイルで最もよく見えます)</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="277"/>
+ <source>Save session &setup along with .sr file</source>
+ <translation>セッション設定を.srファイルと一緒に保存します</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="281"/>
+ <source>Start acquisition for all open sessions when clicking 'Run'</source>
+ <translation>[実行]をクリックすると、開いているすべてのセッションの取得を開始します</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="296"/>
+ <source>Trace View</source>
+ <translation>トレースビュー</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="304"/>
+ <source>Use colored trace &background</source>
+ <translation>色付きのトレースと背景を使用する(&b)</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="308"/>
+ <source>Constantly perform &zoom-to-fit during acquisition</source>
+ <translation>取得中は常にズームツーフィットを実行します(&z)</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="312"/>
+ <source>Perform a zoom-to-&fit when acquisition stops</source>
+ <translation>取得が停止したときにズームツーフィットする(&f)</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="316"/>
+ <source>Show time zero at the &trigger</source>
+ <translation>トリガーで時間ゼロを表示する(&t)</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="320"/>
+ <source>Always keep &newest samples at the right edge during capture</source>
+ <translation>キャプチャ中は常に最新のサンプルを右端に保持(&n)</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="324"/>
+ <source>Allow &vertical dragging in the view area</source>
+ <translation>ビューエリアでの垂直方向のドラッグを許可する(&v)</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="328"/>
+ <source>Show data &sampling points</source>
+ <translation>データサンプリングポイントを表示する(&s)</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="332"/>
+ <source>Fill &high areas of logic signals</source>
+ <translation>ロジック信号の高い領域を埋める(&h)</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="339"/>
+ <source>Color to fill high areas of logic signals with</source>
+ <translation>論理信号の高い領域を塗りつぶす色</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="343"/>
+ <source>Show analog minor grid in addition to div grid</source>
+ <translation>divグリッドに加えてアナログマイナーグリッドを表示する</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="347"/>
+ <source>Highlight mouse cursor using a vertical marker line</source>
+ <translation>垂直マーカーラインを使用してマウスカーソルを強調表示します</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="351"/>
+ <location filename="../pv/dialogs/settings.cpp" line="377"/>
+ <location filename="../pv/dialogs/settings.cpp" line="386"/>
+ <source> pixels</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="356"/>
+ <source>Maximum distance from edges before markers snap to them</source>
+ <translation>マーカーがエッジにスナップする前のエッジからの最大距離</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="363"/>
+ <source>Color to fill cursor area with</source>
+ <translation>カーソル領域を塗りつぶす色</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="366"/>
+ <source>None</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="367"/>
+ <source>Background</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="368"/>
+ <source>Dots</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="373"/>
+ <source>Conversion threshold display mode (analog traces only)</source>
+ <translation>変換閾値表示モード(アナログトレースのみ)</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="382"/>
+ <source>Default analog trace div height</source>
+ <translation>デフォルトのアナログトレースdivの高さ</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="391"/>
+ <source>Default logic trace height</source>
+ <translation>デフォルトのロジックトレースの高さ</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="414"/>
+ <source>Allow configuration of &initial signal state</source>
+ <translation>初期信号状態の構成を許可する(&i)</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="418"/>
+ <source>Always show all &rows, even if no annotation is visible</source>
+ <translation>注釈が表示されていない場合でも、常にすべての行を表示します(&r)</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="426"/>
+ <source>Annotation export format</source>
+ <translation>注釈のエクスポート形式</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="427"/>
+ <source>%s = sample range; %d: decoder name; %r: row name; %c: class name</source>
+ <translation>%s = サンプル範囲; %d: デコーダー名; %r: 行名; %c: クラス名</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="430"/>
+ <source>%1: longest annotation text; %a: all annotation texts; %q: use quotation marks</source>
+ <translation>%1: 最長の注釈テキスト; %a: すべての注釈テキスト; %q: 引用符を使用</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="450"/>
+ <source>%1<br /><a href="http://%2">%2</a></source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="451"/>
+ <source>GNU GPL, version 3 or later</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="462"/>
+ <source>Versions, libraries and features:</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="469"/>
+ <source>Firmware search paths:</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="476"/>
+ <source>Protocol decoder search paths:</source>
+ <translation>プロトコルデコーダの検索パス:</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="479"/>
+ <source><tr><td colspan="2">(Note: Set environment variable SIGROKDECODE_DIR to add a custom directory)</td></tr></source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="484"/>
+ <source>Supported hardware drivers:</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="491"/>
+ <source>Supported input formats:</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="498"/>
+ <source>Supported output formats:</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="506"/>
+ <source>Supported protocol decoders:</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="514"/>
+ <source>Available Translations:</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="562"/>
+ <source>Log level:</source>
+ <translation>ログレベル:</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="567"/>
+ <source> lines</source>
+ <translation>行数</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="576"/>
+ <source>Length of background buffer:</source>
+ <translation>バックグラウンドバッファの長さ:</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="582"/>
+ <source>&Save to File</source>
+ <translation>ファイルに保存(&S)</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="589"/>
+ <source>&Pop out</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="658"/>
+ <source>You selected a dark theme.
+Should I set the user-adjustable colors to better suit your choice?
+
+Please keep in mind that PulseView may need a restart to display correctly.</source>
+ <translation>ダークテーマを選択しました。
+選択に合わせてユーザー調整可能な色を設定する必要があります
+
+正しく表示するには、PulseViewを再起動する必要がある場合があることに注意してください。</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="664"/>
+ <source>You selected a bright theme.
+Should I set the user-adjustable colors to better suit your choice?
+
+Please keep in mind that PulseView may need a restart to display correctly.</source>
+ <translation>明るいテーマを選択しました。
+選択に合わせてユーザー調整可能な色を設定する必要があります
+
+正しく表示するには、PulseViewを再起動する必要がある場合があることに注意してください。</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="829"/>
+ <source>Save Log</source>
+ <translation>ログ保存</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="829"/>
+ <source>Log Files (*.txt *.log);;All Files (*)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="841"/>
+ <source>Success</source>
+ <translation>成功</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="841"/>
+ <source>Log saved to %1.</source>
+ <translation>ログは %1 に保存されました。</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="851"/>
+ <source>Error</source>
+ <translation>エラー</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="851"/>
+ <source>File %1 could not be written to.</source>
+ <translation>ファイル %1 に書き込めませんでした。</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="865"/>
+ <source>%1 Log</source>
+ <translation>%1 ログ</translation>
+ </message>
+</context>
+<context>
+ <name>pv::dialogs::StoreProgress</name>
+ <message>
+ <location filename="../pv/dialogs/storeprogress.cpp" line="44"/>
+ <source>Saving...</source>
+ <translation>保存中...</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/storeprogress.cpp" line="44"/>
+ <source>Cancel</source>
+ <translation>キャンセル</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/storeprogress.cpp" line="89"/>
+ <source>Failed to save session.</source>
+ <translation>セッションの保存に失敗しました。</translation>
+ </message>
+</context>
+<context>
+ <name>pv::popups::Channels</name>
+ <message>
+ <location filename="../pv/popups/channels.cpp" line="62"/>
+ <location filename="../pv/popups/channels.cpp" line="63"/>
+ <location filename="../pv/popups/channels.cpp" line="273"/>
+ <location filename="../pv/popups/channels.cpp" line="300"/>
+ <source>All</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/popups/channels.cpp" line="64"/>
+ <location filename="../pv/popups/channels.cpp" line="65"/>
+ <source>Logic</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/popups/channels.cpp" line="66"/>
+ <location filename="../pv/popups/channels.cpp" line="67"/>
+ <source>Analog</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/popups/channels.cpp" line="68"/>
+ <source>Named</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/popups/channels.cpp" line="69"/>
+ <source>Unnamed</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/popups/channels.cpp" line="70"/>
+ <source>Changing</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/popups/channels.cpp" line="71"/>
+ <source>Non-changing</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/popups/channels.cpp" line="141"/>
+ <source>Disable: </source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/popups/channels.cpp" line="149"/>
+ <source>Enable: </source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/popups/channels.cpp" line="281"/>
+ <location filename="../pv/popups/channels.cpp" line="301"/>
+ <source>None</source>
+ <translation></translation>
+ </message>
+</context>
+<context>
+ <name>pv::prop::Bool</name>
+ <message>
+ <location filename="../pv/prop/bool.cpp" line="51"/>
+ <location filename="../pv/prop/bool.cpp" line="82"/>
+ <source>Querying config key %1 resulted in %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>pv::prop::Double</name>
+ <message>
+ <location filename="../pv/prop/double.cpp" line="65"/>
+ <location filename="../pv/prop/double.cpp" line="96"/>
+ <source>Querying config key %1 resulted in %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>pv::prop::Enum</name>
+ <message>
+ <location filename="../pv/prop/enum.cpp" line="113"/>
+ <location filename="../pv/prop/enum.cpp" line="176"/>
+ <source>Querying config key %1 resulted in %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>pv::prop::Int</name>
+ <message>
+ <location filename="../pv/prop/int.cpp" line="63"/>
+ <location filename="../pv/prop/int.cpp" line="127"/>
+ <source>Querying config key %1 resulted in %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>pv::prop::String</name>
+ <message>
+ <location filename="../pv/prop/string.cpp" line="59"/>
+ <location filename="../pv/prop/string.cpp" line="84"/>
+ <source>Querying config key %1 resulted in %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>pv::subwindows::decoder_selector::DecoderCollectionModel</name>
+ <message>
+ <location filename="../pv/subwindows/decoder_selector/model.cpp" line="40"/>
+ <source>Decoder</source>
+ <translation>デコーダー</translation>
+ </message>
+ <message>
+ <location filename="../pv/subwindows/decoder_selector/model.cpp" line="41"/>
+ <source>Name</source>
+ <translation>名前</translation>
+ </message>
+ <message>
+ <location filename="../pv/subwindows/decoder_selector/model.cpp" line="42"/>
+ <source>ID</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/subwindows/decoder_selector/model.cpp" line="49"/>
+ <source>All Decoders</source>
+ <translation></translation>
+ </message>
+</context>
+<context>
+ <name>pv::subwindows::decoder_selector::SubWindow</name>
+ <message>
+ <location filename="../pv/subwindows/decoder_selector/subwindow.cpp" line="49"/>
+ <source>Select a decoder to see its description here.</source>
+ <translation>ここに説明を表示するには、デコーダーを選択してください。</translation>
+ </message>
+ <message>
+ <location filename="../pv/subwindows/decoder_selector/subwindow.cpp" line="248"/>
+ <source>, %1</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/subwindows/decoder_selector/subwindow.cpp" line="265"/>
+ <source><p align='right'>Tags: %1</p></source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/subwindows/decoder_selector/subwindow.cpp" line="312"/>
+ <source>Protocol decoder <b>%1</b> requires input type <b>%2</b> which several decoders provide.<br>Choose which one to use:<br></source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/subwindows/decoder_selector/subwindow.cpp" line="320"/>
+ <source>Choose Decoder</source>
+ <translation>デコーダーを選択</translation>
+ </message>
+</context>
+<context>
+ <name>pv::toolbars::MainBar</name>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="124"/>
+ <source>New &View</source>
+ <translation>新しいビュー(&V)</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="130"/>
+ <source>&Open...</source>
+ <translation>開く(&O)...</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="137"/>
+ <source>Restore Session Setu&p...</source>
+ <translation>セッション設定を復元(&p)...</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="141"/>
+ <source>&Save...</source>
+ <translation>保存(&S)...</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="148"/>
+ <source>Save &As...</source>
+ <translation>名前をつけて保存(&A)...</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="154"/>
+ <source>Save Selected &Range As...</source>
+ <translation>選択した範囲を名前を付けて保存(&R)...</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="161"/>
+ <source>Save Session Setu&p...</source>
+ <translation>セッション設定を保存(&p)...</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="167"/>
+ <source>&Export</source>
+ <translation>エクスポート(&E)</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="173"/>
+ <source>&Import</source>
+ <translation>インポート(&I)</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="177"/>
+ <source>&Connect to Device...</source>
+ <translation>デバイスへ接続(&C)...</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="239"/>
+ <source>Add protocol decoder</source>
+ <translation>プロトコルデコーダーを追加</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="249"/>
+ <source>Add math signal</source>
+ <translation>math信号を追加</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="265"/>
+ <source>Configure Device</source>
+ <translation>デバイスの構成</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="269"/>
+ <source>Configure Channels</source>
+ <translation>チャンネルの構成</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="383"/>
+ <source>Failed to get sample rate list:</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="446"/>
+ <source>Failed to get sample rate:</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="487"/>
+ <source>Failed to get sample limit list:</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="577"/>
+ <source>Failed to configure samplerate:</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="604"/>
+ <source>Failed to configure sample count:</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="642"/>
+ <source>Missing Cursors</source>
+ <translation>カーソルがありません</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="642"/>
+ <source>You need to set the cursors before you can save the data enclosed by them to a session file (e.g. using the Show Cursors button).</source>
+ <translation>カーソルで囲まれたデータをセッションファイルに保存する前に、カーソルを設定する必要があります(たとえば、[カーソルの表示]ボタンを使用)。</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="660"/>
+ <source>Invalid Range</source>
+ <translation>範囲が無効です</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="660"/>
+ <source>The cursors don't define a valid range of samples.</source>
+ <translation>カーソルはサンプルの有効な範囲を定義していません。</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="672"/>
+ <source>%1 files </source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="680"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="730"/>
+ <source>All Files</source>
+ <translation>すべてのファイル</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="684"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="861"/>
+ <source>Save File</source>
+ <translation>ファイル保存</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="696"/>
+ <source>Export %1</source>
+ <translation>エクスポート %1</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="727"/>
+ <source>%1 files</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="738"/>
+ <source>Import File</source>
+ <translation>インポートファイル</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="747"/>
+ <source>Import %1</source>
+ <translation>インポート %1</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="820"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="878"/>
+ <source>Open File</source>
+ <translation>ファイルを開く</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="820"/>
+ <source>sigrok Sessions (*.sr);;All Files (*)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="861"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="878"/>
+ <source>PulseView Session Setups (*.pvs);;All Files (*)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="946"/>
+ <source>Total sampling time: %1</source>
+ <translation>総サンプリング時間: %1</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::decoder_binary::View</name>
+ <message>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="83"/>
+ <source>Decoder:</source>
+ <translation>デコーダー:</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="87"/>
+ <source>Show data as</source>
+ <translation>データ表示形式</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="93"/>
+ <source>Hexdump</source>
+ <translation>16進ダンプ</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="110"/>
+ <source>&Save...</source>
+ <translation>保存(&S)</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="266"/>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="306"/>
+ <source>Save Binary Data</source>
+ <translation>バイナリデータを保存</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="266"/>
+ <source>Binary Data Files (*.bin);;All Files (*)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="285"/>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="337"/>
+ <source>Error</source>
+ <translation>エラー</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="285"/>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="337"/>
+ <source>File %1 could not be written to.</source>
+ <translation>ファイル%1に書き込めませんでした。</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="306"/>
+ <source>Hex Dumps (*.txt);;All Files (*)</source>
+ <translation></translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::tabular_decoder::AnnotationCollectionModel</name>
+ <message>
+ <location filename="../pv/views/tabular_decoder/model.cpp" line="56"/>
+ <source>Sample</source>
+ <translation>サンプル</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/model.cpp" line="57"/>
+ <source>Time</source>
+ <translation>時間</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/model.cpp" line="58"/>
+ <source>Decoder</source>
+ <translation>デコーダー</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/model.cpp" line="59"/>
+ <source>Ann Row</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/model.cpp" line="60"/>
+ <source>Ann Class</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/model.cpp" line="61"/>
+ <source>Value</source>
+ <translation>値</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/model.cpp" line="83"/>
+ <source>s</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/model.cpp" line="83"/>
+ <source>sa</source>
+ <translation></translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::tabular_decoder::View</name>
+ <message>
+ <location filename="../pv/views/tabular_decoder/view.cpp" line="176"/>
+ <source>Decoder:</source>
+ <translation>デコーダー:</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/view.cpp" line="198"/>
+ <source>Hide Hidden Rows/Classes</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/view.cpp" line="202"/>
+ <source>&Save...</source>
+ <translation>保存(&S)</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/view.cpp" line="374"/>
+ <source>Save Annotations as CSV</source>
+ <translation>注釈をCSVとして保存</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/view.cpp" line="374"/>
+ <source>CSV Files (*.csv);;Text Files (*.txt);;All Files (*)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/view.cpp" line="442"/>
+ <source>Error</source>
+ <translation>エラー</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/view.cpp" line="442"/>
+ <source>File %1 could not be written to.</source>
+ <translation>ファイル%1に書き込めませんでした。</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::AnalogSignal</name>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="802"/>
+ <source>Number of pos vertical divs</source>
+ <translation>正の垂直divの数</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="810"/>
+ <source>Number of neg vertical divs</source>
+ <translation>負の垂直divの数</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="815"/>
+ <source> pixels</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="819"/>
+ <source>Div height</source>
+ <translation>Divの高さ</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="837"/>
+ <source>V/div</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="841"/>
+ <source>Vertical resolution</source>
+ <translation>垂直解像度</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="850"/>
+ <source>Autoranging</source>
+ <translation>オートレンジ</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="855"/>
+ <source>none</source>
+ <translation>なし</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="857"/>
+ <source>to logic via threshold</source>
+ <translation>閾値でロジック変換</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="859"/>
+ <source>to logic via schmitt-trigger</source>
+ <translation>シュミットトリガーでロジック変換</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="865"/>
+ <source>Conversion</source>
+ <translation>変換</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="874"/>
+ <source>Conversion threshold(s)</source>
+ <translation>変換閾値</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="884"/>
+ <source>analog</source>
+ <translation>アナログ</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="885"/>
+ <source>converted</source>
+ <translation>変換済</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="886"/>
+ <source>analog+converted</source>
+ <translation>アナログ+変換済</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="891"/>
+ <source>Show traces for</source>
+ <translation>トレースを表示</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::Cursor</name>
+ <message>
+ <location filename="../pv/views/trace/cursor.cpp" line="97"/>
+ <source>Disable snapping</source>
+ <translation>スナップを無効にする</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::CursorPair</name>
+ <message>
+ <location filename="../pv/views/trace/cursorpair.cpp" line="128"/>
+ <source>Display interval</source>
+ <translation>間隔表示</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/cursorpair.cpp" line="140"/>
+ <source>Display frequency</source>
+ <translation>周波数表示</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/cursorpair.cpp" line="152"/>
+ <source>Display samples</source>
+ <translation>サンプル数表示</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::DecodeTrace</name>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="446"/>
+ <source><p><i>No decoders in the stack</i></p></source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="457"/>
+ <source><i>* Required channels</i></source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="461"/>
+ <source>Stack Decoder</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="462"/>
+ <source>Stack a higher-level decoder on top of this one</source>
+ <translation>この上に高レベルのデコーダーをスタック</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="476"/>
+ <source>Delete</source>
+ <translation>削除</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="518"/>
+ <source>Resume decoding</source>
+ <translation>デコードを再開</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="525"/>
+ <source>Pause decoding</source>
+ <translation>デコードを一時中断</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="533"/>
+ <source>Copy annotation text to clipboard</source>
+ <translation>注釈テキストをクリップボードにコピー</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="542"/>
+ <source>Export all annotations</source>
+ <translation>すべての注釈をエクスポート</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="549"/>
+ <source>Export all annotations for this row</source>
+ <translation>この行のすべての注釈をエクスポート</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="558"/>
+ <source>Export all annotations, starting here</source>
+ <translation>ここから始めて、すべての注釈をエクスポート</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="565"/>
+ <source>Export annotations for this row, starting here</source>
+ <translation>ここから始めて、この行の注釈をエクスポート</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="574"/>
+ <source>Export all annotations within cursor range</source>
+ <translation>カーソル範囲内のすべての注釈をエクスポート</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="581"/>
+ <source>Export annotations for this row within cursor range</source>
+ <translation>カーソル範囲内のこの行の注釈をエクスポート</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1060"/>
+ <source>%1:
+%2</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1104"/>
+ <source><b>%1</b> (%2) %3</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1173"/>
+ <source>Export annotations</source>
+ <translation>注釈をエクスポート</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1173"/>
+ <source>Text Files (*.txt);;All Files (*)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1238"/>
+ <source>Error</source>
+ <translation>エラー</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1238"/>
+ <source>File %1 could not be written to.</source>
+ <translation>ファイル%1に書き込めませんでした。</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1291"/>
+ <source>Show this row</source>
+ <translation>この行を表示</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1302"/>
+ <source>Show All</source>
+ <translation>すべて表示</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1310"/>
+ <source>Hide All</source>
+ <translation>すべて非表示</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::Flag</name>
+ <message>
+ <location filename="../pv/views/trace/flag.cpp" line="132"/>
+ <source>Text</source>
+ <translation>テキスト</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/flag.cpp" line="141"/>
+ <source>Delete</source>
+ <translation>削除</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/flag.cpp" line="146"/>
+ <source>Disable snapping</source>
+ <translation>スナップを無効</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::Header</name>
+ <message>
+ <location filename="../pv/views/trace/header.cpp" line="137"/>
+ <source>Group</source>
+ <translation>グループ</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::LogicSignal</name>
+ <message>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="423"/>
+ <source>No trigger</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="428"/>
+ <source>Trigger on rising edge</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="433"/>
+ <source>Trigger on high level</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="438"/>
+ <source>Trigger on falling edge</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="443"/>
+ <source>Trigger on low level</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="448"/>
+ <source>Trigger on rising or falling edge</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="535"/>
+ <source> pixels</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="539"/>
+ <source>Trace height</source>
+ <translation>トレースの高さ</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="563"/>
+ <source>Trigger</source>
+ <translation>トリガー</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::MathEditDialog</name>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="88"/>
+ <source>Math Expression Editor</source>
+ <translation>数式エディタ</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="93"/>
+ <source>Inputs:</source>
+ <translation>入力:</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="99"/>
+ <source>Variables:</source>
+ <translation>変数:</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="101"/>
+ <source>Basic operators:</source>
+ <translation>基本的な演算子:</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="108"/>
+ <source>Assignments:</source>
+ <translation>割り当て:</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="118"/>
+ <source>General purpose functions:</source>
+ <translation>汎用機能:</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="119"/>
+ <source>abs(x) Absolute value of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="120"/>
+ <source>avg(x, y, ...) Average of all input values</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="121"/>
+ <source>ceil(x) Smallest integer that is greater than or equal to x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="122"/>
+ <source>clamp(lb, x, ub) Clamp x in range between lb and ub, where lb < ub</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="123"/>
+ <source>equal(x, y) Equality test between x and y using normalised epsilon</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="124"/>
+ <source>erf(x) Error function of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="125"/>
+ <source>erfc(x) Complimentary error function of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="126"/>
+ <source>exp(x) e to the power of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="127"/>
+ <source>expm1(x) e to the power of x minus 1, where x is very small.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="128"/>
+ <source>floor(x) Largest integer that is less than or equal to x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="129"/>
+ <source>frac(x) Fractional portion of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="130"/>
+ <source>hypot(x) Hypotenuse of x and y (i.e. sqrt(x*x + y*y))</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="131"/>
+ <source>iclamp(lb, x, ub) Inverse-clamp x outside of the range lb and ub, where lb < ub.
+ If x is within the range it will snap to the closest bound</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="132"/>
+ <source>inrange(lb, x, ub) In-range returns true when x is within the range lb and ub, where lb < ub.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="133"/>
+ <source>log(x) Natural logarithm of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="134"/>
+ <source>log10(x) Base 10 logarithm of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="138"/>
+ <source>log1p(x) Natural logarithm of 1 + x, where x is very small</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="139"/>
+ <source>log2(x) Base 2 logarithm of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="140"/>
+ <source>logn(x) Base N logarithm of x, where n is a positive integer</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="141"/>
+ <source>max(x, y, ...) Largest value of all the inputs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="142"/>
+ <source>min(x, y, ...) Smallest value of all the inputs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="143"/>
+ <source>mul(x, y, ...) Product of all the inputs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="144"/>
+ <source>ncdf(x) Normal cumulative distribution function</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="145"/>
+ <source>nequal(x, y) Not-equal test between x and y using normalised epsilon</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="146"/>
+ <source>pow(x, y) x to the power of y</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="147"/>
+ <source>root(x, n) Nth-Root of x, where n is a positive integer</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="148"/>
+ <source>round(x) Round x to the nearest integer</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="149"/>
+ <source>roundn(x, n) Round x to n decimal places, where n > 0 and is an integer</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="150"/>
+ <source>sgn(x) Sign of x; -1 if x < 0, +1 if x > 0, else zero</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="151"/>
+ <source>sqrt(x) Square root of x, where x >= 0</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="152"/>
+ <source>sum(x, y, ..,) Sum of all the inputs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="153"/>
+ <source>swap(x, y) Swap the values of the variables x and y and return the current value of y</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="154"/>
+ <source>trunc(x) Integer portion of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="158"/>
+ <source>Trigonometry functions:</source>
+ <translation>三角関数:</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="159"/>
+ <source>acos(x) Arc cosine of x expressed in radians. Interval [-1,+1]</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="160"/>
+ <source>acosh(x) Inverse hyperbolic cosine of x expressed in radians</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="161"/>
+ <source>asin(x) Arc sine of x expressed in radians. Interval [-1,+1]</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="162"/>
+ <source>asinh(x) Inverse hyperbolic sine of x expressed in radians</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="163"/>
+ <source>atan(x) Arc tangent of x expressed in radians. Interval [-1,+1]</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="164"/>
+ <source>atan2(x, y) Arc tangent of (x / y) expressed in radians. [-pi,+pi] </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="165"/>
+ <source>atanh(x) Inverse hyperbolic tangent of x expressed in radians</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="166"/>
+ <source>cos(x) Cosine of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="167"/>
+ <source>cosh(x) Hyperbolic cosine of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="168"/>
+ <source>cot(x) Cotangent of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="169"/>
+ <source>csc(x) Cosectant of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="170"/>
+ <source>sec(x) Secant of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="171"/>
+ <source>sin(x) Sine of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="172"/>
+ <source>sinc(x) Sine cardinal of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="173"/>
+ <source>sinh(x) Hyperbolic sine of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="174"/>
+ <source>tan(x) Tangent of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="175"/>
+ <source>tanh(x) Hyperbolic tangent of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="176"/>
+ <source>deg2rad(x) Convert x from degrees to radians</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="177"/>
+ <source>deg2grad(x) Convert x from degrees to gradians</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="178"/>
+ <source>rad2deg(x) Convert x from radians to degrees</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="179"/>
+ <source>grad2deg(x) Convert x from gradians to degrees</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="183"/>
+ <source>Logic operators:</source>
+ <translation>論理演算子:</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="200"/>
+ <source>Comparisons:</source>
+ <translation>比較:</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="201"/>
+ <source>x = y or x == y True only if x is strictly equal to y</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="202"/>
+ <source>x <> y or x != y True only if x does not equal y</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="203"/>
+ <source>x < y True only if x is less than y</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="204"/>
+ <source>x <= y True only if x is less than or equal to y</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="205"/>
+ <source>x > y True only if x is greater than y</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="206"/>
+ <source>x >= y True only if x is greater than or equal to y</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="207"/>
+ <source>Flow control:</source>
+ <translation>フロー制御:</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="208"/>
+ <source>{ ... } Beginning and end of instruction block</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="209"/>
+ <source>if (x, y, z) If x is true then return y else return z
+if (x) y; variant without implied else
+if (x) { y }; variant with an instruction block
+if (x) y; else z; variant with explicit else
+if (x) { y } else { z }; variant with instruction blocks</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="210"/>
+ <source>x ? y : z Ternary operator, equivalent to 'if (x, y, z)'</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="211"/>
+ <source>switch { The first true case condition that is encountered will
+ case x > 1: a; determine the result of the switch. If none of the case
+ case x < 1: b; conditions hold true, the default action is used
+ default: c; to determine the return value
+}</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="215"/>
+ <source>while (conditon) { Evaluates expression repeatedly as long as condition is true,
+ expression; returning the last value of expression
+}</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="216"/>
+ <source>repeat Evalues expression repeatedly as long as condition is false,
+ expression; returning the last value of expression
+until (condition)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="217"/>
+ <source>for (var x := 0; condition; x += 1) { Repeatedly evaluates expression while the condition is true,
+ expression while evaluating the 'increment' expression on each loop
+}</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="218"/>
+ <source>break Terminates the execution of the nearest enclosed loop, returning NaN</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="219"/>
+ <source>break[x] Terminates the execution of the nearest enclosed loop, returning x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="220"/>
+ <source>continue Interrupts loop execution and resumes with the next loop iteration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="221"/>
+ <source>return[x] Returns immediately from within the current expression, returning x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="222"/>
+ <source>~(expr; expr; ...) Evaluates each sub-expression and returns the value of the last one
+~{expr; expr; ...}</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="234"/>
+ <source>Copy to expression</source>
+ <translation>式にコピー</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="247"/>
+ <source>Basics</source>
+ <translation>基本</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="248"/>
+ <source>Functions 1</source>
+ <translation>関数 1</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="249"/>
+ <source>Functions 2</source>
+ <translation>関数 2</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="250"/>
+ <source>Trigonometry</source>
+ <translation>三角関数</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="251"/>
+ <source>Logic</source>
+ <translation>論理</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="252"/>
+ <source>Flow Control 1</source>
+ <translation>フロー制御 1</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="253"/>
+ <source>Flow Control 2</source>
+ <translation>フロー制御 2</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="254"/>
+ <source>Examples</source>
+ <translation>例</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::MathSignal</name>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="313"/>
+ <source>Expression</source>
+ <translation>式</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="317"/>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="327"/>
+ <source>same as session</source>
+ <translation>セッションと同じ</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="318"/>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="328"/>
+ <source>100</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="319"/>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="329"/>
+ <source>10000</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="320"/>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="330"/>
+ <source>1000000</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="323"/>
+ <source>Number of Samples</source>
+ <translation>サンプル数</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="331"/>
+ <source>Sample rate</source>
+ <translation>サンプルレート</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::Ruler</name>
+ <message>
+ <location filename="../pv/views/trace/ruler.cpp" line="153"/>
+ <source>Create marker here</source>
+ <translation>ここでマーカーを作成</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/ruler.cpp" line="157"/>
+ <source>Set as zero point</source>
+ <translation>ゼロポイントとして設定</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/ruler.cpp" line="162"/>
+ <source>Reset zero point</source>
+ <translation>ゼロポイントをリセット</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/ruler.cpp" line="175"/>
+ <source>Disable mouse hover marker</source>
+ <translation>マウスホバーマーカーを無効</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/ruler.cpp" line="175"/>
+ <source>Enable mouse hover marker</source>
+ <translation>マウスホバーマーカーを有効</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::Signal</name>
+ <message>
+ <location filename="../pv/views/trace/signal.cpp" line="153"/>
+ <source>Name</source>
+ <translation>名前</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/signal.cpp" line="167"/>
+ <source>Remove</source>
+ <translation>削除</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/signal.cpp" line="169"/>
+ <source>Disable</source>
+ <translation>無効</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::StandardBar</name>
+ <message>
+ <location filename="../pv/views/trace/standardbar.cpp" line="54"/>
+ <source>Zoom &In</source>
+ <translation>ズームイン(&I)</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/standardbar.cpp" line="62"/>
+ <source>Zoom &Out</source>
+ <translation>ズームアウト(&O)</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/standardbar.cpp" line="70"/>
+ <source>Zoom to &Fit</source>
+ <translation>ウインドウに合わせる(&F)</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/standardbar.cpp" line="82"/>
+ <source>Show &Cursors</source>
+ <translation>カーソル表示(&C)</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/standardbar.cpp" line="85"/>
+ <source>Display last segment only</source>
+ <translation>最後のセグメントのみ表示</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/standardbar.cpp" line="90"/>
+ <source>Display last complete segment only</source>
+ <translation>最後の完全なセグメントのみ表示</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/standardbar.cpp" line="95"/>
+ <source>Display a single segment</source>
+ <translation>単一のセグメントを表示</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::TimeMarker</name>
+ <message>
+ <location filename="../pv/views/trace/timemarker.cpp" line="191"/>
+ <source>Time</source>
+ <translation>時間</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::Trace</name>
+ <message>
+ <location filename="../pv/views/trace/trace.cpp" line="229"/>
+ <source>Create marker here</source>
+ <translation>ここにマーカーを作成</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/trace.cpp" line="338"/>
+ <source>Color</source>
+ <translation>色</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/trace.cpp" line="403"/>
+ <source>Name</source>
+ <translation>名前</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::TraceGroup</name>
+ <message>
+ <location filename="../pv/views/trace/tracegroup.cpp" line="140"/>
+ <source>Ungroup</source>
+ <translation>グループ解除</translation>
+ </message>
+</context>
+<context>
+ <name>pv::widgets::DecoderGroupBox</name>
+ <message>
+ <location filename="../pv/widgets/decodergroupbox.cpp" line="48"/>
+ <source>Show/hide this decoder trace</source>
+ <translation>このデコーダートレースを表示/非表示</translation>
+ </message>
+ <message>
+ <location filename="../pv/widgets/decodergroupbox.cpp" line="58"/>
+ <source>Delete this decoder trace</source>
+ <translation>このデコーダートレースを削除</translation>
+ </message>
+</context>
+<context>
+ <name>pv::widgets::DeviceToolButton</name>
+ <message>
+ <location filename="../pv/widgets/devicetoolbutton.cpp" line="75"/>
+ <location filename="../pv/widgets/devicetoolbutton.cpp" line="82"/>
+ <source><No Device></source>
+ <translation></translation>
+ </message>
+</context>
+<context>
+ <name>pv::widgets::ExportMenu</name>
+ <message>
+ <location filename="../pv/widgets/exportmenu.cpp" line="71"/>
+ <source>Export %1...</source>
+ <translation>エクスポート %1...</translation>
+ </message>
+</context>
+<context>
+ <name>pv::widgets::ImportMenu</name>
+ <message>
+ <location filename="../pv/widgets/importmenu.cpp" line="68"/>
+ <source>Import %1...</source>
+ <translation>インポート %1...</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="zh_CN" sourcelanguage="en">
+<context>
+ <name>Application</name>
+ <message>
+ <location filename="../pv/application.cpp" line="135"/>
+ <source>Some parts of the application may still use the previous language. Re-opening the affected windows or restarting the application will remedy this.</source>
+ <translation>应用程序的某些部分可能仍然使用以前的语言。重新打开受影响的窗口或重新启动应用程序将解决此问题。</translation>
+ </message>
+</context>
+<context>
+ <name>QApplication</name>
+ <message>
+ <location filename="../pv/devicemanager.cpp" line="274"/>
+ <source>Error when scanning device driver '%1': %2</source>
+ <translation>扫描设备驱动程序时出错 '%1': %2</translation>
+ </message>
+ <message>
+ <location filename="../pv/devices/device.cpp" line="70"/>
+ <source>Querying config key %1 is not allowed</source>
+ <translation>不允许查询 %1 配置</translation>
+ </message>
+ <message>
+ <location filename="../pv/devices/device.cpp" line="79"/>
+ <source>Querying config key %1 resulted in %2</source>
+ <translation>查询配置 '%1': %2</translation>
+ </message>
+ <message>
+ <location filename="../pv/devices/device.cpp" line="93"/>
+ <source>Unknown type supplied when attempting to query %1</source>
+ <translation>查询 %1 时 返回未知类型</translation>
+ </message>
+</context>
+<context>
+ <name>QHexView</name>
+ <message>
+ <location filename="../pv/views/decoder_binary/QHexView.cpp" line="339"/>
+ <source>No data available</source>
+ <translation>无可用数据</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="../main.cpp" line="116"/>
+ <source>Stack trace of previous crash:</source>
+ <translation>跟踪上次崩溃日志:</translation>
+ </message>
+ <message>
+ <location filename="../main.cpp" line="130"/>
+ <source>Don't show this message again</source>
+ <translation>不再显示此消息</translation>
+ </message>
+ <message>
+ <location filename="../main.cpp" line="133"/>
+ <source>When %1 last crashed, it created a stack trace.
+A human-readable form has been saved to disk and was written to the log. You may access it from the settings dialog.</source>
+ <translation>上次崩溃时 %1 ,创建了日志文件。
+可在 设置\Logging 中查看。</translation>
+ </message>
+ <message>
+ <location filename="../pv/devicemanager.cpp" line="65"/>
+ <source>Cancel</source>
+ <translation>取消</translation>
+ </message>
+ <message>
+ <location filename="../pv/devicemanager.cpp" line="96"/>
+ <source>Scanning for devices that driver %1 can access...</source>
+ <translation>正在扫描驱动程序 %1 可以访问的设备...</translation>
+ </message>
+</context>
+<context>
+ <name>pv::MainWindow</name>
+ <message>
+ <location filename="../pv/mainwindow.cpp" line="70"/>
+ <source>PulseView</source>
+ <translation>PulseView</translation>
+ </message>
+ <message>
+ <location filename="../pv/mainwindow.cpp" line="284"/>
+ <source>Decoder Selector</source>
+ <translation>协议解码器</translation>
+ </message>
+ <message>
+ <location filename="../pv/mainwindow.cpp" line="337"/>
+ <source>Session %1</source>
+ <translation>会话 %1</translation>
+ </message>
+ <message>
+ <location filename="../pv/mainwindow.cpp" line="519"/>
+ <source>Create New Session</source>
+ <translation>创建新会话</translation>
+ </message>
+ <message>
+ <location filename="../pv/mainwindow.cpp" line="525"/>
+ <source>Start/Stop Acquisition</source>
+ <translation>开始/停止 采集</translation>
+ </message>
+ <message>
+ <location filename="../pv/mainwindow.cpp" line="533"/>
+ <source>Settings</source>
+ <translation>设置</translation>
+ </message>
+ <message>
+ <location filename="../pv/mainwindow.cpp" line="589"/>
+ <source>Reload</source>
+ <translation>重新加载</translation>
+ </message>
+ <message>
+ <location filename="../pv/mainwindow.cpp" line="589"/>
+ <location filename="../pv/mainwindow.cpp" line="592"/>
+ <source>Run</source>
+ <translation>开始</translation>
+ </message>
+ <message>
+ <location filename="../pv/mainwindow.cpp" line="598"/>
+ <source>Stop</source>
+ <translation>停止</translation>
+ </message>
+ <message>
+ <location filename="../pv/mainwindow.cpp" line="644"/>
+ <location filename="../pv/mainwindow.cpp" line="867"/>
+ <location filename="../pv/mainwindow.cpp" line="893"/>
+ <source>Confirmation</source>
+ <translation>确认</translation>
+ </message>
+ <message>
+ <location filename="../pv/mainwindow.cpp" line="645"/>
+ <source>There is unsaved data. Close anyway?</source>
+ <translation>数据未保存。是否关闭?</translation>
+ </message>
+ <message>
+ <location filename="../pv/mainwindow.cpp" line="868"/>
+ <location filename="../pv/mainwindow.cpp" line="894"/>
+ <source>This session contains unsaved data. Close it anyway?</source>
+ <translation>此会话数据未保存。是否关闭?</translation>
+ </message>
+</context>
+<context>
+ <name>pv::Session</name>
+ <message>
+ <location filename="../pv/session.cpp" line="396"/>
+ <source>Can't restore generated signal of unknown type %1 (%2)</source>
+ <translation>无法还原生成的未知类型的信号 %1 (%2)</translation>
+ </message>
+ <message>
+ <location filename="../pv/session.cpp" line="559"/>
+ <source>Failed to select device</source>
+ <translation>无法选择的设备</translation>
+ </message>
+ <message>
+ <location filename="../pv/session.cpp" line="616"/>
+ <source>Failed to open device</source>
+ <translation>无法打开的设备</translation>
+ </message>
+ <message>
+ <location filename="../pv/session.cpp" line="722"/>
+ <source>Error</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/session.cpp" line="723"/>
+ <source>Unexpected input format: %1</source>
+ <translation>不支持的输入格式: %1</translation>
+ </message>
+ <message>
+ <location filename="../pv/session.cpp" line="758"/>
+ <source>Failed to load %1</source>
+ <translation>无法加载 %1</translation>
+ </message>
+ <message>
+ <location filename="../pv/session.cpp" line="797"/>
+ <source>No active device set, can't start acquisition.</source>
+ <translation>未设置活动设备,无法采集。</translation>
+ </message>
+ <message>
+ <location filename="../pv/session.cpp" line="810"/>
+ <source>No channels enabled.</source>
+ <translation>未启用任何通道。</translation>
+ </message>
+ <message>
+ <location filename="../pv/session.cpp" line="1311"/>
+ <source>Out of memory, acquisition stopped.</source>
+ <translation>内存不足,采集停止。</translation>
+ </message>
+ <message>
+ <location filename="../pv/session.cpp" line="1518"/>
+ <source>Can't handle more than 64 logic channels.</source>
+ <translation>无法处理超过64个逻辑通道。</translation>
+ </message>
+</context>
+<context>
+ <name>pv::StoreSession</name>
+ <message>
+ <location filename="../pv/storesession.cpp" line="114"/>
+ <source>Can't save logic channel without data.</source>
+ <translation>无法保存,逻辑通道内没有数据。</translation>
+ </message>
+ <message>
+ <location filename="../pv/storesession.cpp" line="130"/>
+ <source>Can't save analog channel without data.</source>
+ <translation>无法保存,模拟通道内没有数据。</translation>
+ </message>
+ <message>
+ <location filename="../pv/storesession.cpp" line="142"/>
+ <source>No channels enabled.</source>
+ <translation>未启用任何通道。</translation>
+ </message>
+ <message>
+ <location filename="../pv/storesession.cpp" line="167"/>
+ <source>Can't save range without sample data.</source>
+ <translation>无法保存,光标范围内没有数据。</translation>
+ </message>
+ <message>
+ <location filename="../pv/storesession.cpp" line="192"/>
+ <location filename="../pv/storesession.cpp" line="299"/>
+ <location filename="../pv/storesession.cpp" line="314"/>
+ <source>Error while saving: </source>
+ <translation>保存时出错: </translation>
+ </message>
+</context>
+<context>
+ <name>pv::binding::Device</name>
+ <message>
+ <location filename="../pv/binding/device.cpp" line="82"/>
+ <source>Note for device developers: Ignoring device configuration capability '%1' as it is missing GET and/or SET</source>
+ <translation>设备开发人员注意:缺少 GET/SET,忽略该设备配置功能 '%1'</translation>
+ </message>
+ <message>
+ <location filename="../pv/binding/device.cpp" line="107"/>
+ <source>No Limit</source>
+ <translation>没有限制</translation>
+ </message>
+</context>
+<context>
+ <name>pv::data::DecodeSignal</name>
+ <message>
+ <location filename="../pv/data/decodesignal.cpp" line="223"/>
+ <source>No decoders</source>
+ <translation>没有解码器</translation>
+ </message>
+ <message>
+ <location filename="../pv/data/decodesignal.cpp" line="230"/>
+ <source>There are no channels assigned to this decoder</source>
+ <translation>解码器没有选择通道</translation>
+ </message>
+ <message>
+ <location filename="../pv/data/decodesignal.cpp" line="244"/>
+ <source>One or more required channels have not been specified</source>
+ <translation>解码器缺少一个或多个通道</translation>
+ </message>
+ <message>
+ <location filename="../pv/data/decodesignal.cpp" line="260"/>
+ <source>No input data</source>
+ <translation>无数据输入</translation>
+ </message>
+ <message>
+ <location filename="../pv/data/decodesignal.cpp" line="1325"/>
+ <source>Decoder reported an error</source>
+ <translation>解码器解码错误</translation>
+ </message>
+ <message>
+ <location filename="../pv/data/decodesignal.cpp" line="1484"/>
+ <source>Failed to create decoder instance</source>
+ <translation>无法创建的解码器实例</translation>
+ </message>
+</context>
+<context>
+ <name>pv::data::MathSignal</name>
+ <message>
+ <location filename="../pv/data/mathsignal.cpp" line="107"/>
+ <source>Math%1</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/data/mathsignal.cpp" line="306"/>
+ <source>No expression defined, nothing to do</source>
+ <translation>未定义表达式,不执行任何操作</translation>
+ </message>
+ <message>
+ <location filename="../pv/data/mathsignal.cpp" line="345"/>
+ <source>%1 at line %2, column %3: %4</source>
+ <translation>%1 行 %2, 列 %3: %4</translation>
+ </message>
+ <message>
+ <location filename="../pv/data/mathsignal.cpp" line="364"/>
+ <location filename="../pv/data/mathsignal.cpp" line="536"/>
+ <source>"%1" isn't a valid analog signal</source>
+ <translation>"%1" 不是有效的模拟信号</translation>
+ </message>
+ <message>
+ <location filename="../pv/data/mathsignal.cpp" line="374"/>
+ <location filename="../pv/data/mathsignal.cpp" line="611"/>
+ <source>No data will be generated as %1 must be enabled</source>
+ <translation>不会生成数据,因为必须启用 %1</translation>
+ </message>
+</context>
+<context>
+ <name>pv::data::SignalBase</name>
+ <message>
+ <location filename="../pv/data/signalbase.cpp" line="525"/>
+ <source>Signal average</source>
+ <translation>平均信号电平</translation>
+ </message>
+ <message>
+ <location filename="../pv/data/signalbase.cpp" line="526"/>
+ <source>0.9V (for 1.8V CMOS)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/data/signalbase.cpp" line="527"/>
+ <source>1.8V (for 3.3V CMOS)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/data/signalbase.cpp" line="528"/>
+ <source>2.5V (for 5.0V CMOS)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/data/signalbase.cpp" line="529"/>
+ <source>1.5V (for TTL)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/data/signalbase.cpp" line="534"/>
+ <source>Signal average +/- 15%</source>
+ <translation>平均信号电平 +/- 15%</translation>
+ </message>
+ <message>
+ <location filename="../pv/data/signalbase.cpp" line="535"/>
+ <source>0.3V/1.2V (for 1.8V CMOS)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/data/signalbase.cpp" line="536"/>
+ <source>0.7V/2.5V (for 3.3V CMOS)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/data/signalbase.cpp" line="537"/>
+ <source>1.3V/3.7V (for 5.0V CMOS)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/data/signalbase.cpp" line="538"/>
+ <source>0.8V/2.0V (for TTL)</source>
+ <translation></translation>
+ </message>
+</context>
+<context>
+ <name>pv::dialogs::Connect</name>
+ <message>
+ <location filename="../pv/dialogs/connect.cpp" line="58"/>
+ <source>&Scan for devices using driver above</source>
+ <translation>使用上述驱动程序扫描设备</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/connect.cpp" line="63"/>
+ <source>Connect to Device</source>
+ <translation>连接到设备</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/connect.cpp" line="75"/>
+ <source>Step 1: Choose the driver</source>
+ <translation>步骤1:选择驱动程序</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/connect.cpp" line="79"/>
+ <source>&USB</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/connect.cpp" line="80"/>
+ <source>Serial &Port</source>
+ <translation>串行和端口</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/connect.cpp" line="81"/>
+ <source>&TCP/IP</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/connect.cpp" line="116"/>
+ <source>Protocol:</source>
+ <translation>协议:</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/connect.cpp" line="134"/>
+ <source>Step 2: Choose the interface</source>
+ <translation>步骤2:选择接口</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/connect.cpp" line="140"/>
+ <source>Step 3: Scan for devices</source>
+ <translation>步骤3:扫描设备</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/connect.cpp" line="146"/>
+ <source>Step 4: Select the device</source>
+ <translation>步骤4:选择设备</translation>
+ </message>
+</context>
+<context>
+ <name>pv::dialogs::Settings</name>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="134"/>
+ <location filename="../pv/dialogs/settings.cpp" line="213"/>
+ <source>General</source>
+ <translation>常规</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="143"/>
+ <source>Views</source>
+ <translation>显示</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="153"/>
+ <location filename="../pv/dialogs/settings.cpp" line="411"/>
+ <source>Decoders</source>
+ <translation>解码器</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="163"/>
+ <source>About</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="172"/>
+ <source>Logging</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="241"/>
+ <source>User interface language</source>
+ <translation>语言</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="252"/>
+ <source>User interface theme</source>
+ <translation>主题</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="254"/>
+ <source>(You may need to restart PulseView for all UI elements to update)</source>
+ <translation>(您可能需要重新启动PulseView才能更新所有UI元素)</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="260"/>
+ <source>System Default</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="273"/>
+ <source>Qt widget style</source>
+ <translation>QT 软件界面风格</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="275"/>
+ <source>(Dark themes look best with the Fusion style)</source>
+ <translation>(深色主题与Fusion风格搭配效果最佳)</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="282"/>
+ <source>Save session &setup along with .sr file</source>
+ <translation>将会话设置与 .sr文件一起保存</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="286"/>
+ <source>Start acquisition for all open sessions when clicking 'Run'</source>
+ <translation>单击“开始”时启动所有打开会话的采集</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="301"/>
+ <source>Trace View</source>
+ <translation>采集视图</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="309"/>
+ <source>Use colored trace &background</source>
+ <translation>使用彩色通道背景</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="313"/>
+ <source>Constantly perform &zoom-to-fit during acquisition</source>
+ <translation>采集数据过程中不断调整和缩放以适应窗口 ( &Z )</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="317"/>
+ <source>Perform a zoom-to-&fit when acquisition stops</source>
+ <translation>采集停止时执行调整和缩放以适应窗口 ( &A )</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="321"/>
+ <source>Show time zero at the &trigger</source>
+ <translation>在触发器处显示时间零点 ( &T )</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="325"/>
+ <source>Always keep &newest samples at the right edge during capture</source>
+ <translation>采集过程中始终跟踪右侧最新数据 ( &Q )</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="329"/>
+ <source>Allow &vertical dragging in the view area</source>
+ <translation>允许在视图区域中垂直拖动</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="333"/>
+ <source>Show data &sampling points</source>
+ <translation>显示数据采样点</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="337"/>
+ <source>Fill &high areas of logic signals</source>
+ <translation>填充逻辑信号高电平的区域 ( &H )</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="344"/>
+ <source>Color to fill high areas of logic signals with</source>
+ <translation>填充逻辑信号高电平区域的颜色</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="348"/>
+ <source>Show analog minor grid in addition to div grid</source>
+ <translation>模拟通道除了div网格之外,还显示更多垂直细分网格</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="352"/>
+ <source>Highlight mouse cursor using a vertical marker line</source>
+ <translation>用竖线突出显示鼠标光标位置</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="356"/>
+ <location filename="../pv/dialogs/settings.cpp" line="382"/>
+ <location filename="../pv/dialogs/settings.cpp" line="391"/>
+ <source> pixels</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="361"/>
+ <source>Maximum distance from edges before markers snap to them</source>
+ <translation>光标吸附到边沿前的最大距离</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="368"/>
+ <source>Color to fill cursor area with</source>
+ <translation>填充光标范围内的颜色</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="371"/>
+ <source>None</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="372"/>
+ <source>Background</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="373"/>
+ <source>Dots</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="378"/>
+ <source>Conversion threshold display mode (analog traces only)</source>
+ <translation>转换阈值显示模式(仅限模拟通道)</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="387"/>
+ <source>Default analog trace div height</source>
+ <translation>模拟通道垂直高度</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="396"/>
+ <source>Default logic trace height</source>
+ <translation>逻辑通道垂直高度</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="419"/>
+ <source>Allow configuration of &initial signal state</source>
+ <translation>允许配置初始信号状态</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="423"/>
+ <source>Always show all &rows, even if no annotation is visible</source>
+ <translation>始终显示所有解码,即使未解码</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="431"/>
+ <source>Annotation export format</source>
+ <translation>解码数据导出格式</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="432"/>
+ <source>%s = sample range; %d: decoder name; %r: row name; %c: class name</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="435"/>
+ <source>%1: longest annotation text; %a: all annotation texts; %q: use quotation marks</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="455"/>
+ <source>%1<br /><a href="http://%2">%2</a></source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="456"/>
+ <source>GNU GPL, version 3 or later</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="467"/>
+ <source>Versions, libraries and features:</source>
+ <translation>版本、库和功能:</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="474"/>
+ <source>Firmware search paths:</source>
+ <translation>固件搜索路径:</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="481"/>
+ <source>Protocol decoder search paths:</source>
+ <translation>协议解码器搜索路径:</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="484"/>
+ <source><tr><td colspan="2">(Note: Set environment variable SIGROKDECODE_DIR to add a custom directory)</td></tr></source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="489"/>
+ <source>Supported hardware drivers:</source>
+ <translation>支持的硬件驱动程序:</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="496"/>
+ <source>Supported input formats:</source>
+ <translation>支持的输入格式:</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="503"/>
+ <source>Supported output formats:</source>
+ <translation>支持的输出格式:</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="511"/>
+ <source>Supported protocol decoders:</source>
+ <translation>支持的协议解码器:</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="519"/>
+ <source>Available Translations:</source>
+ <translation>可用翻译:</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="567"/>
+ <source>Log level:</source>
+ <translation>日志级别:</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="572"/>
+ <source> lines</source>
+ <translation> 行</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="581"/>
+ <source>Length of background buffer:</source>
+ <translation>日志缓存长度:</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="587"/>
+ <source>&Save to File</source>
+ <translation>保存到文件</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="594"/>
+ <source>&Pop out</source>
+ <translation>独立弹出日志窗口</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="663"/>
+ <source>You selected a dark theme.
+Should I set the user-adjustable colors to better suit your choice?
+
+Please keep in mind that PulseView may need a restart to display correctly.</source>
+ <translation>您选择了一个深色主题。
+是否相应地调整特定的颜色,以更好地协调?
+PulseView可能需要重新启动才能正确显示。</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="669"/>
+ <source>You selected a bright theme.
+Should I set the user-adjustable colors to better suit your choice?
+
+Please keep in mind that PulseView may need a restart to display correctly.</source>
+ <translation>您选择了一个明亮主题。
+是否相应地调整特定的颜色,以更好地协调?
+PulseView可能需要重新启动才能正确显示。</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="834"/>
+ <source>Save Log</source>
+ <translation>保存日志</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="834"/>
+ <source>Log Files (*.txt *.log);;All Files (*)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="846"/>
+ <source>Success</source>
+ <translation>成功</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="846"/>
+ <source>Log saved to %1.</source>
+ <translation>日志已保存到 %1。</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="856"/>
+ <source>Error</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="856"/>
+ <source>File %1 could not be written to.</source>
+ <translation>文件 %1 无法保存。</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/settings.cpp" line="870"/>
+ <source>%1 Log</source>
+ <translation></translation>
+ </message>
+</context>
+<context>
+ <name>pv::dialogs::StoreProgress</name>
+ <message>
+ <location filename="../pv/dialogs/storeprogress.cpp" line="44"/>
+ <source>Saving...</source>
+ <translation>保存中...</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/storeprogress.cpp" line="44"/>
+ <source>Cancel</source>
+ <translation>取消</translation>
+ </message>
+ <message>
+ <location filename="../pv/dialogs/storeprogress.cpp" line="89"/>
+ <source>Failed to save session.</source>
+ <translation>未能保存会话。</translation>
+ </message>
+</context>
+<context>
+ <name>pv::popups::Channels</name>
+ <message>
+ <location filename="../pv/popups/channels.cpp" line="62"/>
+ <location filename="../pv/popups/channels.cpp" line="63"/>
+ <location filename="../pv/popups/channels.cpp" line="278"/>
+ <location filename="../pv/popups/channels.cpp" line="305"/>
+ <source>All</source>
+ <translation>全部</translation>
+ </message>
+ <message>
+ <location filename="../pv/popups/channels.cpp" line="64"/>
+ <location filename="../pv/popups/channels.cpp" line="65"/>
+ <source>Logic</source>
+ <translation>逻辑</translation>
+ </message>
+ <message>
+ <location filename="../pv/popups/channels.cpp" line="66"/>
+ <location filename="../pv/popups/channels.cpp" line="67"/>
+ <source>Analog</source>
+ <translation>模拟</translation>
+ </message>
+ <message>
+ <location filename="../pv/popups/channels.cpp" line="68"/>
+ <source>Named</source>
+ <translation>更名过</translation>
+ </message>
+ <message>
+ <location filename="../pv/popups/channels.cpp" line="69"/>
+ <source>Unnamed</source>
+ <translation>未更名</translation>
+ </message>
+ <message>
+ <location filename="../pv/popups/channels.cpp" line="70"/>
+ <source>Changing</source>
+ <translation>有数据的</translation>
+ </message>
+ <message>
+ <location filename="../pv/popups/channels.cpp" line="71"/>
+ <source>Non-changing</source>
+ <translation>无数据的</translation>
+ </message>
+ <message>
+ <location filename="../pv/popups/channels.cpp" line="141"/>
+ <source>Disable: </source>
+ <translation>禁用: </translation>
+ </message>
+ <message>
+ <location filename="../pv/popups/channels.cpp" line="149"/>
+ <source>Enable: </source>
+ <translation>启用: </translation>
+ </message>
+ <message>
+ <location filename="../pv/popups/channels.cpp" line="286"/>
+ <location filename="../pv/popups/channels.cpp" line="306"/>
+ <source>None</source>
+ <translation>全关</translation>
+ </message>
+</context>
+<context>
+ <name>pv::prop::Bool</name>
+ <message>
+ <location filename="../pv/prop/bool.cpp" line="51"/>
+ <location filename="../pv/prop/bool.cpp" line="82"/>
+ <source>Querying config key %1 resulted in %2</source>
+ <translation>查询配置 '%1': %2</translation>
+ </message>
+</context>
+<context>
+ <name>pv::prop::Double</name>
+ <message>
+ <location filename="../pv/prop/double.cpp" line="65"/>
+ <location filename="../pv/prop/double.cpp" line="96"/>
+ <source>Querying config key %1 resulted in %2</source>
+ <translation>查询配置 '%1': %2</translation>
+ </message>
+</context>
+<context>
+ <name>pv::prop::Enum</name>
+ <message>
+ <location filename="../pv/prop/enum.cpp" line="113"/>
+ <location filename="../pv/prop/enum.cpp" line="176"/>
+ <source>Querying config key %1 resulted in %2</source>
+ <translation>查询配置 '%1': %2</translation>
+ </message>
+</context>
+<context>
+ <name>pv::prop::Int</name>
+ <message>
+ <location filename="../pv/prop/int.cpp" line="63"/>
+ <location filename="../pv/prop/int.cpp" line="127"/>
+ <source>Querying config key %1 resulted in %2</source>
+ <translation>查询配置 '%1': %2</translation>
+ </message>
+</context>
+<context>
+ <name>pv::prop::String</name>
+ <message>
+ <location filename="../pv/prop/string.cpp" line="59"/>
+ <location filename="../pv/prop/string.cpp" line="84"/>
+ <source>Querying config key %1 resulted in %2</source>
+ <translation>查询配置 '%1': %2</translation>
+ </message>
+</context>
+<context>
+ <name>pv::subwindows::decoder_selector::DecoderCollectionModel</name>
+ <message>
+ <location filename="../pv/subwindows/decoder_selector/model.cpp" line="40"/>
+ <source>Decoder</source>
+ <translation>解码器</translation>
+ </message>
+ <message>
+ <location filename="../pv/subwindows/decoder_selector/model.cpp" line="41"/>
+ <source>Name</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/subwindows/decoder_selector/model.cpp" line="42"/>
+ <source>ID</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/subwindows/decoder_selector/model.cpp" line="49"/>
+ <source>All Decoders</source>
+ <translation>所有解码器</translation>
+ </message>
+</context>
+<context>
+ <name>pv::subwindows::decoder_selector::SubWindow</name>
+ <message>
+ <location filename="../pv/subwindows/decoder_selector/subwindow.cpp" line="49"/>
+ <source>Select a decoder to see its description here.</source>
+ <translation>选择解码器以在此处查看其说明。</translation>
+ </message>
+ <message>
+ <location filename="../pv/subwindows/decoder_selector/subwindow.cpp" line="248"/>
+ <source>, %1</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/subwindows/decoder_selector/subwindow.cpp" line="265"/>
+ <source><p align='right'>Tags: %1</p></source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/subwindows/decoder_selector/subwindow.cpp" line="312"/>
+ <source>Protocol decoder <b>%1</b> requires input type <b>%2</b> which several decoders provide.<br>Choose which one to use:<br></source>
+ <translation>协议解码器 <b>%1</b> 有不同的<b>%2</b> 协议类型。<br>选择要使用的:<br></translation>
+ </message>
+ <message>
+ <location filename="../pv/subwindows/decoder_selector/subwindow.cpp" line="320"/>
+ <source>Choose Decoder</source>
+ <translation>选择解码器</translation>
+ </message>
+</context>
+<context>
+ <name>pv::toolbars::MainBar</name>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="124"/>
+ <source>New &View</source>
+ <translation>新建视图</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="130"/>
+ <source>&Open...</source>
+ <translation>打开... ( &O )</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="141"/>
+ <source>Restore Session Setu&p...</source>
+ <translation>从文件打开会话设置...</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="145"/>
+ <source>&Save...</source>
+ <translation>保存... ( &S )</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="156"/>
+ <source>Save &As...</source>
+ <translation>另存为... ( &A )</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="162"/>
+ <source>Save Selected &Range As...</source>
+ <translation>将所选范围另存为... ( &R )</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="173"/>
+ <source>Save Session Setu&p...</source>
+ <translation>保存会话设置...</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="179"/>
+ <source>&Export</source>
+ <translation>导出</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="185"/>
+ <source>&Import</source>
+ <translation>导入</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="189"/>
+ <source>&Connect to Device...</source>
+ <translation>连接到设备...</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="251"/>
+ <source>Add protocol decoder</source>
+ <translation>添加协议解码器</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="261"/>
+ <source>Add math signal</source>
+ <translation>添加 math 信号</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="277"/>
+ <source>Configure Device</source>
+ <translation>设备配置</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="281"/>
+ <source>Configure Channels</source>
+ <translation>通道配置</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="395"/>
+ <source>Failed to get sample rate list:</source>
+ <translation>无法获取采样率列表:</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="458"/>
+ <source>Failed to get sample rate:</source>
+ <translation>无法获取采样率:</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="499"/>
+ <source>Failed to get sample limit list:</source>
+ <translation>无法获取采样限制列表:</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="589"/>
+ <source>Failed to configure samplerate:</source>
+ <translation>无法配置采样率:</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="616"/>
+ <source>Failed to configure sample count:</source>
+ <translation>无法配置采样计数:</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="654"/>
+ <source>Missing Cursors</source>
+ <translation>缺少光标</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="654"/>
+ <source>You need to set the cursors before you can save the data enclosed by them to a session file (e.g. using the Show Cursors button).</source>
+ <translation>您需要设置光标,然后才能将光标范围内的数据保存到会话文件中(例如,使用“显示光标”按钮)。</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="672"/>
+ <source>Invalid Range</source>
+ <translation>无效的范围</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="672"/>
+ <source>The cursors don't define a valid range of samples.</source>
+ <translation>光标没有定义有效的采样范围。</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="684"/>
+ <source>%1 files </source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="692"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="742"/>
+ <source>All Files</source>
+ <translation>所有文件</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="696"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="873"/>
+ <source>Save File</source>
+ <translation>保存文件</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="708"/>
+ <source>Export %1</source>
+ <translation>导出 %1</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="739"/>
+ <source>%1 files</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="750"/>
+ <source>Import File</source>
+ <translation>导入文件</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="759"/>
+ <source>Import %1</source>
+ <translation>导入 %1</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="832"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="890"/>
+ <source>Open File</source>
+ <translation>打开文件</translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="832"/>
+ <source>sigrok Sessions (*.sr);;All Files (*)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="873"/>
+ <location filename="../pv/toolbars/mainbar.cpp" line="890"/>
+ <source>PulseView Session Setups (*.pvs);;All Files (*)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/toolbars/mainbar.cpp" line="958"/>
+ <source>Total sampling time: %1</source>
+ <translation>总采样时间: %1</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::decoder_binary::View</name>
+ <message>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="83"/>
+ <source>Decoder:</source>
+ <translation>解码器:</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="87"/>
+ <source>Show data as</source>
+ <translation>数据显示格式</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="93"/>
+ <source>Hexdump</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="110"/>
+ <source>&Save...</source>
+ <translation>保存... ( &S )</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="270"/>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="310"/>
+ <source>Save Binary Data</source>
+ <translation>保存二进制数据</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="270"/>
+ <source>Binary Data Files (*.bin);;All Files (*)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="289"/>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="349"/>
+ <source>Error</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="289"/>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="349"/>
+ <source>File %1 could not be written to.</source>
+ <translation>文件 %1 无法保存。</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/decoder_binary/view.cpp" line="310"/>
+ <source>Hex Dumps (*.txt);;All Files (*)</source>
+ <translation></translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::tabular_decoder::AnnotationCollectionModel</name>
+ <message>
+ <location filename="../pv/views/tabular_decoder/model.cpp" line="56"/>
+ <source>Sample</source>
+ <translation>采样</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/model.cpp" line="57"/>
+ <source>Time</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/model.cpp" line="58"/>
+ <source>Decoder</source>
+ <translation>解码器</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/model.cpp" line="59"/>
+ <source>Ann Row</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/model.cpp" line="60"/>
+ <source>Ann Class</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/model.cpp" line="61"/>
+ <source>Value</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/model.cpp" line="83"/>
+ <source>s</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/model.cpp" line="83"/>
+ <source>sa</source>
+ <translation></translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::tabular_decoder::View</name>
+ <message>
+ <location filename="../pv/views/tabular_decoder/view.cpp" line="176"/>
+ <source>Decoder:</source>
+ <translation>解码器:</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/view.cpp" line="198"/>
+ <source>Hide Hidden Rows/Classes</source>
+ <translation>隐藏隐藏的行/列</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/view.cpp" line="202"/>
+ <source>&Save...</source>
+ <translation>保存... ( &S )</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/view.cpp" line="378"/>
+ <source>Save Annotations as CSV</source>
+ <translation>将解码数据另存为CSV</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/view.cpp" line="378"/>
+ <source>CSV Files (*.csv);;Text Files (*.txt);;All Files (*)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/view.cpp" line="446"/>
+ <source>Error</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/tabular_decoder/view.cpp" line="446"/>
+ <source>File %1 could not be written to.</source>
+ <translation>文件 %1 无法保存。</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::AnalogSignal</name>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="802"/>
+ <source>Number of pos vertical divs</source>
+ <translation>正区间div垂直细分网格数</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="810"/>
+ <source>Number of neg vertical divs</source>
+ <translation>负区间div垂直细分网格数</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="815"/>
+ <source> pixels</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="819"/>
+ <source>Div height</source>
+ <translation>Div高度</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="837"/>
+ <source>V/div</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="841"/>
+ <source>Vertical resolution</source>
+ <translation>垂直分辨率</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="850"/>
+ <source>Autoranging</source>
+ <translation>自动量程</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="855"/>
+ <source>none</source>
+ <translation>无</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="857"/>
+ <source>to logic via threshold</source>
+ <translation>通过阈值转换为逻辑</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="859"/>
+ <source>to logic via schmitt-trigger</source>
+ <translation>通过施密特触发器转换为逻辑</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="865"/>
+ <source>Conversion</source>
+ <translation>转换</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="874"/>
+ <source>Conversion threshold(s)</source>
+ <translation>转换阈值</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="884"/>
+ <source>analog</source>
+ <translation>模拟</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="885"/>
+ <source>converted</source>
+ <translation>转换</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="886"/>
+ <source>analog+converted</source>
+ <translation>模拟+转换</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/analogsignal.cpp" line="891"/>
+ <source>Show traces for</source>
+ <translation>显示采集</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::Cursor</name>
+ <message>
+ <location filename="../pv/views/trace/cursor.cpp" line="97"/>
+ <source>Disable snapping</source>
+ <translation>禁用捕捉</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::CursorPair</name>
+ <message>
+ <location filename="../pv/views/trace/cursorpair.cpp" line="128"/>
+ <source>Display interval</source>
+ <translation>显示间隔</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/cursorpair.cpp" line="140"/>
+ <source>Display frequency</source>
+ <translation>显示频率</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/cursorpair.cpp" line="152"/>
+ <source>Display samples</source>
+ <translation>显示采样</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::DecodeTrace</name>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="456"/>
+ <source><p><i>No decoders in the stack</i></p></source>
+ <translation><p><i>堆叠中没有解码器</i></p></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="467"/>
+ <source><i>* Required channels</i></source>
+ <translation><i>* 所需通道</i></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="471"/>
+ <source>Stack Decoder</source>
+ <translation>堆叠解码器</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="472"/>
+ <source>Stack a higher-level decoder on top of this one</source>
+ <translation>在这之上面堆叠一个更高级别的解码器</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="486"/>
+ <source>Delete</source>
+ <translation>删除</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="528"/>
+ <source>Resume decoding</source>
+ <translation>继续解码</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="535"/>
+ <source>Pause decoding</source>
+ <translation>暂停解码</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="543"/>
+ <source>Copy annotation text to clipboard</source>
+ <translation>将解码数据复制到剪贴板</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="552"/>
+ <source>Export all annotations</source>
+ <translation>导出所有解码数据</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="559"/>
+ <source>Export all annotations for this row</source>
+ <translation>导出此行的解码数据</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="568"/>
+ <source>Export all annotations, starting here</source>
+ <translation>导出从这以后所有的解码数据</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="575"/>
+ <source>Export annotations for this row, starting here</source>
+ <translation>导出从这以后此行的解码数据</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="584"/>
+ <source>Export all annotations within cursor range</source>
+ <translation>导出光标范围内所有的解码数据</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="591"/>
+ <source>Export annotations for this row within cursor range</source>
+ <translation>导出光标范围内此行的解码数据</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1079"/>
+ <source>%1:
+%2</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1123"/>
+ <source><b>%1</b> (%2) %3</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1192"/>
+ <source>Export annotations</source>
+ <translation>导出解码数据</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1192"/>
+ <source>Text Files (*.txt);;All Files (*)</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1257"/>
+ <source>Error</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1257"/>
+ <source>File %1 could not be written to.</source>
+ <translation>文件 %1 无法保存。</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1324"/>
+ <source>Show this row</source>
+ <translation>显示此行</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1335"/>
+ <source>Show All</source>
+ <translation>全部显示</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/decodetrace.cpp" line="1343"/>
+ <source>Hide All</source>
+ <translation>全部隐藏</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::Flag</name>
+ <message>
+ <location filename="../pv/views/trace/flag.cpp" line="132"/>
+ <source>Text</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/flag.cpp" line="141"/>
+ <source>Delete</source>
+ <translation>删除</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/flag.cpp" line="146"/>
+ <source>Disable snapping</source>
+ <translation>禁用捕捉</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::Header</name>
+ <message>
+ <location filename="../pv/views/trace/header.cpp" line="137"/>
+ <source>Group</source>
+ <translation>组</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::LogicSignal</name>
+ <message>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="423"/>
+ <source>No trigger</source>
+ <translation>无触发</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="428"/>
+ <source>Trigger on rising edge</source>
+ <translation>上升沿触发</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="433"/>
+ <source>Trigger on high level</source>
+ <translation>高电平触发</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="438"/>
+ <source>Trigger on falling edge</source>
+ <translation>下降沿触发</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="443"/>
+ <source>Trigger on low level</source>
+ <translation>低电平触发</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="448"/>
+ <source>Trigger on rising or falling edge</source>
+ <translation>上升沿或下降沿触发</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="535"/>
+ <source> pixels</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="539"/>
+ <source>Trace height</source>
+ <translation>通道高度</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/logicsignal.cpp" line="563"/>
+ <source>Trigger</source>
+ <translation>触发</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::MathEditDialog</name>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="88"/>
+ <source>Math Expression Editor</source>
+ <translation>Math 表达式编辑器</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="93"/>
+ <source>Inputs:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="99"/>
+ <source>Variables:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="101"/>
+ <source>Basic operators:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="108"/>
+ <source>Assignments:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="118"/>
+ <source>General purpose functions:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="119"/>
+ <source>abs(x) Absolute value of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="120"/>
+ <source>avg(x, y, ...) Average of all input values</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="121"/>
+ <source>ceil(x) Smallest integer that is greater than or equal to x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="122"/>
+ <source>clamp(lb, x, ub) Clamp x in range between lb and ub, where lb < ub</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="123"/>
+ <source>equal(x, y) Equality test between x and y using normalised epsilon</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="124"/>
+ <source>erf(x) Error function of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="125"/>
+ <source>erfc(x) Complimentary error function of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="126"/>
+ <source>exp(x) e to the power of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="127"/>
+ <source>expm1(x) e to the power of x minus 1, where x is very small.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="128"/>
+ <source>floor(x) Largest integer that is less than or equal to x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="129"/>
+ <source>frac(x) Fractional portion of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="130"/>
+ <source>hypot(x) Hypotenuse of x and y (i.e. sqrt(x*x + y*y))</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="131"/>
+ <source>iclamp(lb, x, ub) Inverse-clamp x outside of the range lb and ub, where lb < ub.
+ If x is within the range it will snap to the closest bound</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="132"/>
+ <source>inrange(lb, x, ub) In-range returns true when x is within the range lb and ub, where lb < ub.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="133"/>
+ <source>log(x) Natural logarithm of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="134"/>
+ <source>log10(x) Base 10 logarithm of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="138"/>
+ <source>log1p(x) Natural logarithm of 1 + x, where x is very small</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="139"/>
+ <source>log2(x) Base 2 logarithm of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="140"/>
+ <source>logn(x) Base N logarithm of x, where n is a positive integer</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="141"/>
+ <source>max(x, y, ...) Largest value of all the inputs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="142"/>
+ <source>min(x, y, ...) Smallest value of all the inputs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="143"/>
+ <source>mul(x, y, ...) Product of all the inputs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="144"/>
+ <source>ncdf(x) Normal cumulative distribution function</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="145"/>
+ <source>nequal(x, y) Not-equal test between x and y using normalised epsilon</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="146"/>
+ <source>pow(x, y) x to the power of y</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="147"/>
+ <source>root(x, n) Nth-Root of x, where n is a positive integer</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="148"/>
+ <source>round(x) Round x to the nearest integer</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="149"/>
+ <source>roundn(x, n) Round x to n decimal places, where n > 0 and is an integer</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="150"/>
+ <source>sgn(x) Sign of x; -1 if x < 0, +1 if x > 0, else zero</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="151"/>
+ <source>sqrt(x) Square root of x, where x >= 0</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="152"/>
+ <source>sum(x, y, ..,) Sum of all the inputs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="153"/>
+ <source>swap(x, y) Swap the values of the variables x and y and return the current value of y</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="154"/>
+ <source>trunc(x) Integer portion of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="158"/>
+ <source>Trigonometry functions:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="159"/>
+ <source>acos(x) Arc cosine of x expressed in radians. Interval [-1,+1]</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="160"/>
+ <source>acosh(x) Inverse hyperbolic cosine of x expressed in radians</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="161"/>
+ <source>asin(x) Arc sine of x expressed in radians. Interval [-1,+1]</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="162"/>
+ <source>asinh(x) Inverse hyperbolic sine of x expressed in radians</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="163"/>
+ <source>atan(x) Arc tangent of x expressed in radians. Interval [-1,+1]</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="164"/>
+ <source>atan2(x, y) Arc tangent of (x / y) expressed in radians. [-pi,+pi] </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="165"/>
+ <source>atanh(x) Inverse hyperbolic tangent of x expressed in radians</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="166"/>
+ <source>cos(x) Cosine of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="167"/>
+ <source>cosh(x) Hyperbolic cosine of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="168"/>
+ <source>cot(x) Cotangent of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="169"/>
+ <source>csc(x) Cosectant of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="170"/>
+ <source>sec(x) Secant of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="171"/>
+ <source>sin(x) Sine of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="172"/>
+ <source>sinc(x) Sine cardinal of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="173"/>
+ <source>sinh(x) Hyperbolic sine of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="174"/>
+ <source>tan(x) Tangent of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="175"/>
+ <source>tanh(x) Hyperbolic tangent of x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="176"/>
+ <source>deg2rad(x) Convert x from degrees to radians</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="177"/>
+ <source>deg2grad(x) Convert x from degrees to gradians</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="178"/>
+ <source>rad2deg(x) Convert x from radians to degrees</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="179"/>
+ <source>grad2deg(x) Convert x from gradians to degrees</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="183"/>
+ <source>Logic operators:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="200"/>
+ <source>Comparisons:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="201"/>
+ <source>x = y or x == y True only if x is strictly equal to y</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="202"/>
+ <source>x <> y or x != y True only if x does not equal y</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="203"/>
+ <source>x < y True only if x is less than y</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="204"/>
+ <source>x <= y True only if x is less than or equal to y</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="205"/>
+ <source>x > y True only if x is greater than y</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="206"/>
+ <source>x >= y True only if x is greater than or equal to y</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="207"/>
+ <source>Flow control:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="208"/>
+ <source>{ ... } Beginning and end of instruction block</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="209"/>
+ <source>if (x, y, z) If x is true then return y else return z
+if (x) y; variant without implied else
+if (x) { y }; variant with an instruction block
+if (x) y; else z; variant with explicit else
+if (x) { y } else { z }; variant with instruction blocks</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="210"/>
+ <source>x ? y : z Ternary operator, equivalent to 'if (x, y, z)'</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="211"/>
+ <source>switch { The first true case condition that is encountered will
+ case x > 1: a; determine the result of the switch. If none of the case
+ case x < 1: b; conditions hold true, the default action is used
+ default: c; to determine the return value
+}</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="215"/>
+ <source>while (conditon) { Evaluates expression repeatedly as long as condition is true,
+ expression; returning the last value of expression
+}</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="216"/>
+ <source>repeat Evalues expression repeatedly as long as condition is false,
+ expression; returning the last value of expression
+until (condition)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="217"/>
+ <source>for (var x := 0; condition; x += 1) { Repeatedly evaluates expression while the condition is true,
+ expression while evaluating the 'increment' expression on each loop
+}</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="218"/>
+ <source>break Terminates the execution of the nearest enclosed loop, returning NaN</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="219"/>
+ <source>break[x] Terminates the execution of the nearest enclosed loop, returning x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="220"/>
+ <source>continue Interrupts loop execution and resumes with the next loop iteration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="221"/>
+ <source>return[x] Returns immediately from within the current expression, returning x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="222"/>
+ <source>~(expr; expr; ...) Evaluates each sub-expression and returns the value of the last one
+~{expr; expr; ...}</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="234"/>
+ <source>Copy to expression</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="247"/>
+ <source>Basics</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="248"/>
+ <source>Functions 1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="249"/>
+ <source>Functions 2</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="250"/>
+ <source>Trigonometry</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="251"/>
+ <source>Logic</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="252"/>
+ <source>Flow Control 1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="253"/>
+ <source>Flow Control 2</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="254"/>
+ <source>Examples</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::MathSignal</name>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="317"/>
+ <source>Expression</source>
+ <translation>表达式</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="321"/>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="331"/>
+ <source>same as session</source>
+ <translation>与会话相同</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="322"/>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="332"/>
+ <source>100</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="323"/>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="333"/>
+ <source>10000</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="324"/>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="334"/>
+ <source>1000000</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="327"/>
+ <source>Number of Samples</source>
+ <translation>采样数</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/mathsignal.cpp" line="335"/>
+ <source>Sample rate</source>
+ <translation>采样率</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::Ruler</name>
+ <message>
+ <location filename="../pv/views/trace/ruler.cpp" line="153"/>
+ <source>Create marker here</source>
+ <translation>在此处创建标记</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/ruler.cpp" line="157"/>
+ <source>Set as zero point</source>
+ <translation>设为零点</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/ruler.cpp" line="162"/>
+ <source>Reset zero point</source>
+ <translation>重置零点</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/ruler.cpp" line="175"/>
+ <source>Disable mouse hover marker</source>
+ <translation>禁用鼠标位置标记</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/ruler.cpp" line="175"/>
+ <source>Enable mouse hover marker</source>
+ <translation>启用鼠标位置标记</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::Signal</name>
+ <message>
+ <location filename="../pv/views/trace/signal.cpp" line="153"/>
+ <source>Name</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/signal.cpp" line="167"/>
+ <source>Remove</source>
+ <translation>删除</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/signal.cpp" line="169"/>
+ <source>Disable</source>
+ <translation>关闭</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::StandardBar</name>
+ <message>
+ <location filename="../pv/views/trace/standardbar.cpp" line="54"/>
+ <source>Zoom &In</source>
+ <translation>放大</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/standardbar.cpp" line="62"/>
+ <source>Zoom &Out</source>
+ <translation>缩小</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/standardbar.cpp" line="70"/>
+ <source>Zoom to &Fit</source>
+ <translation>适应窗口</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/standardbar.cpp" line="82"/>
+ <source>Show &Cursors</source>
+ <translation>显示光标</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/standardbar.cpp" line="85"/>
+ <source>Display last segment only</source>
+ <translation>仅显示最后一段</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/standardbar.cpp" line="90"/>
+ <source>Display last complete segment only</source>
+ <translation>仅显示最后一个完整分段</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/standardbar.cpp" line="95"/>
+ <source>Display a single segment</source>
+ <translation>仅显示一段</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::TimeMarker</name>
+ <message>
+ <location filename="../pv/views/trace/timemarker.cpp" line="191"/>
+ <source>Time</source>
+ <translation></translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::Trace</name>
+ <message>
+ <location filename="../pv/views/trace/trace.cpp" line="229"/>
+ <source>Create marker here</source>
+ <translation>在此处创建标记</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/trace.cpp" line="338"/>
+ <source>Color</source>
+ <translation>颜色</translation>
+ </message>
+ <message>
+ <location filename="../pv/views/trace/trace.cpp" line="403"/>
+ <source>Name</source>
+ <translation></translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::TraceGroup</name>
+ <message>
+ <location filename="../pv/views/trace/tracegroup.cpp" line="140"/>
+ <source>Ungroup</source>
+ <translation>取消组合</translation>
+ </message>
+</context>
+<context>
+ <name>pv::views::trace::View</name>
+ <message>
+ <location filename="../pv/views/trace/view.cpp" line="1610"/>
+ <source>Create marker here</source>
+ <translation>在此处创建标记</translation>
+ </message>
+</context>
+<context>
+ <name>pv::widgets::DecoderGroupBox</name>
+ <message>
+ <location filename="../pv/widgets/decodergroupbox.cpp" line="48"/>
+ <source>Show/hide this decoder trace</source>
+ <translation>显示/隐藏此解码器采集</translation>
+ </message>
+ <message>
+ <location filename="../pv/widgets/decodergroupbox.cpp" line="58"/>
+ <source>Delete this decoder trace</source>
+ <translation>删除此解码器采集</translation>
+ </message>
+</context>
+<context>
+ <name>pv::widgets::DeviceToolButton</name>
+ <message>
+ <location filename="../pv/widgets/devicetoolbutton.cpp" line="80"/>
+ <location filename="../pv/widgets/devicetoolbutton.cpp" line="87"/>
+ <source><No Device></source>
+ <translation></translation>
+ </message>
+</context>
+<context>
+ <name>pv::widgets::ExportMenu</name>
+ <message>
+ <location filename="../pv/widgets/exportmenu.cpp" line="71"/>
+ <source>Export %1...</source>
+ <translation>导出 %1...</translation>
+ </message>
+</context>
+<context>
+ <name>pv::widgets::ImportMenu</name>
+ <message>
+ <location filename="../pv/widgets/importmenu.cpp" line="68"/>
+ <source>Import %1...</source>
+ <translation>导入 %1...</translation>
+ </message>
+</context>
+</TS>
#ifdef _WIN32
#include <QtPlugin>
+#ifdef QT_STATIC
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)
Q_IMPORT_PLUGIN(QSvgPlugin)
#endif
+#endif
using std::exception;
using std::ifstream;
// Create the device manager, initialise the drivers
pv::DeviceManager device_manager(context, driver, do_scan);
- a.collect_version_info(context);
+ a.collect_version_info(device_manager);
if (show_version) {
a.print_version_info();
} else {
cmake_minimum_required(VERSION 2.8.12)
+project(PV_MANUAL)
+
# External dependencies, required and optional tools.
find_program(ASCIIDOCTOR_EXECUTABLE NAMES asciidoctor)
find_program(ASCIIDOCTOR_PDF_EXECUTABLE NAMES asciidoctor-pdf)
set(MANUAL_OUT_HTML "${CMAKE_CURRENT_BINARY_DIR}/manual.html")
set(MANUAL_OUT_PDF "${CMAKE_CURRENT_BINARY_DIR}/manual.pdf")
+# Make in-source images/ content available to the output hierarchy for
+# the inspection of created output documents during development in the
+# case of out-of-source build configurations.
+if (NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/images")
+ message(STATUS "creating symlink for manual's images/ subdirectory")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E create_symlink
+ "${CMAKE_CURRENT_SOURCE_DIR}/images"
+ "${CMAKE_CURRENT_BINARY_DIR}/images"
+ RESULT_VARIABLE IMAGES_LINK_RESULT
+ )
+ if (NOT IMAGES_LINK_RESULT EQUAL 0)
+ message(WARNING "manual rendering will lack images")
+ endif ()
+endif ()
+
# Manual related make(1) targets.
add_custom_target(manual-html
COMMAND ${ASCIIDOCTOR_EXECUTABLE}
BYPRODUCTS ${MANUAL_OUT_PDF}
DEPENDS ${MANUAL_SRC}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- COMMENT "Generating manual, HTML output"
+ COMMENT "Generating manual, PDF output"
)
else ()
add_custom_target(manual-pdf
PulseView User Manual
=====================
-unreleased development snapshot, dated 2020-02-29
+unreleased pulseview development snapshot, manual last changed 2020-02-29
:doctype: book
:imagesdir: ./images
:sectnums:
const QStringList Application::get_languages() const
{
- QStringList files = QDir(":/l10n/").entryList(QStringList("*.qm"), QDir::Files);
+ const QStringList files = QDir(":/l10n/").entryList(QStringList("*.qm"), QDir::Files);
QStringList result;
result << "en"; // Add default language to the set
const QString Application::get_language_editors(const QString& language) const
{
if (language == "de") return "Sören Apel, Uwe Hermann";
- if (language == "es_mx") return "Carlos Diaz";
+ if (language == "es_MX") return "Carlos Diaz, Ulices Avila Hernandez";
+ if (language == "ja_jp") return "Yukari Shoji";
+ if (language == "zh_cn") return "ZtyPro";
return QString();
}
qWarning() << "Translation resource" << resource << "not found";
// Qt translations
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ QString tr_path(QLibraryInfo::path(QLibraryInfo::TranslationsPath));
+#else
QString tr_path(QLibraryInfo::location(QLibraryInfo::TranslationsPath));
+#endif
if (qt_translator_.load("qt_" + language, tr_path))
installTranslator(&qt_translator_);
switch_language(value.toString());
}
-void Application::collect_version_info(shared_ptr<sigrok::Context> context)
+void Application::collect_version_info(pv::DeviceManager &device_manager)
{
// Library versions and features
version_info_.emplace_back(applicationName(), applicationVersion());
#endif
// Device drivers
- for (auto& entry : context->drivers())
- driver_list_.emplace_back(QString::fromUtf8(entry.first.c_str()),
- QString::fromUtf8(entry.second->long_name().c_str()));
+ for (auto& entry : device_manager.context()->drivers())
+ if (device_manager.driver_supported(entry.second))
+ driver_list_.emplace_back(QString::fromUtf8(entry.first.c_str()),
+ QString::fromUtf8(entry.second->long_name().c_str()));
// Input formats
- for (auto& entry : context->input_formats())
+ for (auto& entry : device_manager.context()->input_formats())
input_format_list_.emplace_back(QString::fromUtf8(entry.first.c_str()),
QString::fromUtf8(entry.second->description().c_str()));
// Output formats
- for (auto& entry : context->output_formats())
+ for (auto& entry : device_manager.context()->output_formats())
output_format_list_.emplace_back(QString::fromUtf8(entry.first.c_str()),
QString::fromUtf8(entry.second->description().c_str()));
#include <libsigrokcxx/libsigrokcxx.hpp>
+#include "devicemanager.hpp"
#include "globalsettings.hpp"
using std::shared_ptr;
void on_setting_changed(const QString &key, const QVariant &value);
- void collect_version_info(shared_ptr<sigrok::Context> context);
+ void collect_version_info(pv::DeviceManager &device_manager);
void print_version_info();
vector< pair<QString, QString> > get_version_info() const;
// Ignore common read-only keys
if ((key->id() == SR_CONF_CONTINUOUS) || (key->id() == SR_CONF_TRIGGER_MATCH) ||
- (key->id() == SR_CONF_CONN) || (key->id() == SR_CONF_SERIALCOMM))
+ (key->id() == SR_CONF_CONN) || (key->id() == SR_CONF_SERIALCOMM) || (key->id() == SR_CONF_NUM_LOGIC_CHANNELS) ||
+ (key->id() == SR_CONF_NUM_ANALOG_CHANNELS) || (key->id() == SR_CONF_SESSIONFILE) || (key->id() == SR_CONF_CAPTUREFILE) ||
+ (key->id() == SR_CONF_CAPTURE_UNITSIZE))
continue;
qDebug() << QString(tr("Note for device developers: Ignoring device configuration capability '%1' " \
case SR_CONF_RLE:
case SR_CONF_POWER_OFF:
case SR_CONF_AVERAGING:
+ case SR_CONF_CONTINUOUS:
bind_bool(descr, "", get, set);
break;
void Analog::clear()
{
- segments_.clear();
+ if (!segments_.empty()) {
+ segments_.clear();
- samples_cleared();
+ samples_cleared();
+ }
}
void Analog::set_samplerate(double value)
void min_max_changed(float min, float max);
- void segment_completed();
-
private Q_SLOTS:
void on_segment_completed();
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-extern "C" {
#include <libsigrokdecode/libsigrokdecode.h>
-}
#include <cassert>
#include <vector>
annotation_visibility_changed();
}
+bool Decoder::has_logic_output() const
+{
+ return (srd_decoder_->logic_output_channels != nullptr);
+}
+
+const vector<DecoderLogicOutputChannel> Decoder::logic_output_channels() const
+{
+ vector<DecoderLogicOutputChannel> result;
+
+ for (GSList *l = srd_decoder_->logic_output_channels; l; l = l->next) {
+ const srd_decoder_logic_output_channel* ch_data =
+ (srd_decoder_logic_output_channel*)l->data;
+
+ result.emplace_back(QString::fromUtf8(ch_data->id),
+ QString::fromUtf8(ch_data->desc));
+ }
+
+ return result;
+}
+
} // namespace decode
} // namespace data
} // namespace pv
const srd_channel *pdch_;
};
+struct DecoderLogicOutputChannel {
+ DecoderLogicOutputChannel (QString id, QString desc) :
+ id(id), desc(desc) {};
+ QString id, desc;
+};
+
struct DecodeBinaryClassInfo
{
uint32_t bin_class_id;
uint32_t get_binary_class_count() const;
const DecodeBinaryClassInfo* get_binary_class(uint32_t id) const;
+ bool has_logic_output() const;
+ const vector<DecoderLogicOutputChannel> logic_output_channels() const;
+
Q_SIGNALS:
void annotation_visibility_changed();
*/
#include <cassert>
+#include <QDebug>
#include "decoder.hpp"
#include "row.hpp"
const QColor Row::get_class_color(uint32_t ann_class_id) const
{
- return ann_class_color_.at(ann_class_id);
+ try {
+ return ann_class_color_.at(ann_class_id);
+ } catch (std::out_of_range &e) {
+ qWarning() << "Warning: annotation type" << decoder_->get_ann_class_by_id(ann_class_id)->name
+ << "(" << ann_class_id << ")" << "not assigned to any annotation row!";
+ return QColor(20, 20, 20);
+ }
}
const QColor Row::get_bright_class_color(uint32_t ann_class_id) const
{
- return ann_bright_class_color_.at(ann_class_id);
+ try {
+ return ann_bright_class_color_.at(ann_class_id);
+ } catch (std::out_of_range &e) {
+ return QColor(20, 20, 20);
+ }
}
const QColor Row::get_dark_class_color(uint32_t ann_class_id) const
{
- return ann_dark_class_color_.at(ann_class_id);
+ try {
+ return ann_dark_class_color_.at(ann_class_id);
+ } catch (std::out_of_range &e) {
+ return QColor(20, 20, 20);
+ }
}
bool Row::has_hidden_classes() const
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "config.h"
+
#include <cstring>
#include <forward_list>
#include <limits>
#include <QDebug>
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+#include <QRegularExpression>
+#endif
#include "logic.hpp"
#include "logicsegment.hpp"
#include <pv/globalsettings.hpp>
#include <pv/session.hpp>
+using std::dynamic_pointer_cast;
using std::lock_guard;
using std::make_shared;
using std::min;
reset_decode(true);
}
+void DecodeSignal::set_name(QString name)
+{
+ SignalBase::set_name(name);
+
+ update_output_signals();
+}
+
+void DecodeSignal::set_color(QColor color)
+{
+ SignalBase::set_color(color);
+
+ update_output_signals();
+}
+
const vector< shared_ptr<Decoder> >& DecodeSignal::decoder_stack() const
{
return stack_;
stack_config_changed_ = true;
auto_assign_signals(dec);
commit_decoder_channels();
+ update_output_signals();
decoder_stacked((void*)dec.get());
current_segment_id_ = 0;
segments_.clear();
+ for (const shared_ptr<decode::Decoder>& dec : stack_)
+ if (dec->has_logic_output())
+ output_logic_[dec->get_srd_decoder()]->clear();
+
logic_mux_data_.reset();
logic_mux_data_invalid_ = true;
logic_mux_data_ = make_shared<Logic>(ch_count);
}
- // Receive notifications when new sample data is available
- connect_input_notifiers();
-
if (get_input_segment_count() == 0)
set_error_message(tr("No input data"));
{
bool new_assignment = false;
+ // Disconnect all input signal notifications so we don't have duplicate connections
+ disconnect_input_notifiers();
+
// Try to auto-select channels that don't have signals assigned yet
for (decode::DecodeChannel& ch : channels_) {
// If a decoder is given, auto-assign only its channels
continue;
QString ch_name = ch.name.toLower();
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ ch_name = ch_name.replace(QRegularExpression("[-_.]"), " ");
+#else
ch_name = ch_name.replace(QRegExp("[-_.]"), " ");
+#endif
shared_ptr<data::SignalBase> match;
for (const shared_ptr<data::SignalBase>& s : session_.signalbases()) {
continue;
QString s_name = s->name().toLower();
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ s_name = s_name.replace(QRegularExpression("[-_.]"), " ");
+#else
s_name = s_name.replace(QRegExp("[-_.]"), " ");
+#endif
if (s->logic_data() &&
((ch_name.contains(s_name)) || (s_name.contains(ch_name)))) {
}
if (new_assignment) {
+ // Receive notifications when new sample data is available
+ connect_input_notifiers();
+
logic_mux_data_invalid_ = true;
stack_config_changed_ = true;
commit_decoder_channels();
void DecodeSignal::assign_signal(const uint16_t channel_id, shared_ptr<const SignalBase> signal)
{
+ // Disconnect all input signal notifications so we don't have duplicate connections
+ disconnect_input_notifiers();
+
for (decode::DecodeChannel& ch : channels_)
if (ch.id == channel_id) {
ch.assigned_signal = signal;
logic_mux_data_invalid_ = true;
}
+ // Receive notifications when new sample data is available
+ connect_input_notifiers();
+
stack_config_changed_ = true;
commit_decoder_channels();
channels_updated();
[](decode::DecodeChannel ch) { return ch.assigned_signal.get(); });
}
+void DecodeSignal::update_output_signals()
+{
+ for (const shared_ptr<decode::Decoder>& dec : stack_) {
+ assert(dec);
+
+ if (dec->has_logic_output()) {
+ const vector<decode::DecoderLogicOutputChannel> logic_channels =
+ dec->logic_output_channels();
+
+ // All signals of a decoder share the same LogicSegment, so it's
+ // sufficient to check for only the first channel
+ const decode::DecoderLogicOutputChannel& first_ch = logic_channels[0];
+
+ bool ch_exists = false;
+ for (const shared_ptr<SignalBase>& signal : output_signals_)
+ if (signal->internal_name() == first_ch.id)
+ ch_exists = true;
+
+ if (!ch_exists) {
+ shared_ptr<Logic> logic_data = make_shared<Logic>(logic_channels.size());
+ logic_data->set_samplerate(get_samplerate());
+ output_logic_[dec->get_srd_decoder()] = logic_data;
+ output_logic_muxed_data_[dec->get_srd_decoder()] = vector<uint8_t>();
+
+ shared_ptr<LogicSegment> logic_segment = make_shared<data::LogicSegment>(
+ *logic_data, 0, (logic_data->num_channels() + 7) / 8, get_samplerate());
+ logic_data->push_segment(logic_segment);
+
+ uint index = 0;
+ for (const decode::DecoderLogicOutputChannel& logic_ch : logic_channels) {
+ shared_ptr<data::SignalBase> signal =
+ make_shared<data::SignalBase>(nullptr, LogicChannel);
+ signal->set_internal_name(logic_ch.id);
+ signal->set_index(index);
+ signal->set_data(logic_data);
+ output_signals_.push_back(signal);
+ session_.add_generated_signal(signal);
+ index++;
+ }
+ } else {
+ shared_ptr<Logic> logic_data = output_logic_[dec->get_srd_decoder()];
+ logic_data->set_samplerate(get_samplerate());
+ for (shared_ptr<LogicSegment>& segment : logic_data->logic_segments())
+ segment->set_samplerate(get_samplerate());
+ }
+ }
+ }
+
+ for (shared_ptr<SignalBase> s : output_signals_) {
+ s->set_name(s->internal_name() + " (" + name() + ")");
+ s->set_color(color());
+ }
+
+ // TODO Assert that all sample rates are the same as the session's
+}
+
void DecodeSignal::set_initial_pin_state(const uint16_t channel_id, const int init_state)
{
for (decode::DecodeChannel& ch : channels_)
return rows;
}
-
uint64_t DecodeSignal::get_annotation_count(const Row* row, uint32_t segment_id) const
{
if (segment_id >= segments_.size())
for (const shared_ptr<Decoder>& decoder : stack_) {
settings.beginGroup("decoder" + QString::number(decoder_idx++));
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ settings.setValue("id", (const char *)decoder->get_srd_decoder()->id);
+#else
settings.setValue("id", decoder->get_srd_decoder()->id);
+#endif
settings.setValue("visible", decoder->visible());
// Save decoder options
settings.endGroup();
}
+
+ // TODO Save logic output signal settings
}
void DecodeSignal::restore_settings(QSettings &settings)
settings.endGroup();
}
+ connect_input_notifiers();
+
// Update the internal structures
stack_config_changed_ = true;
update_channel_list();
commit_decoder_channels();
+ update_output_signals();
+
+ // TODO Restore logic output signal settings
begin_decode();
}
output_segment->set_complete();
if (segment_id < get_input_segment_count() - 1) {
+
// Process next segment
segment_id++;
unique_lock<mutex> logic_mux_lock(logic_mux_mutex_);
logic_mux_cond_.wait(logic_mux_lock);
}
+ } else {
+ // Input segments aren't all complete yet but samples_to_process is 0, wait for more input data
+ unique_lock<mutex> logic_mux_lock(logic_mux_mutex_);
+ logic_mux_cond_.wait(logic_mux_lock);
}
}
} while (!logic_mux_interrupt_);
// If the input segment is complete, we've exhausted this segment
if (input_segment->is_complete()) {
+#if defined HAVE_SRD_SESSION_SEND_EOF && HAVE_SRD_SESSION_SEND_EOF
+ // Tell protocol decoders about the end of
+ // the input data, which may result in more
+ // annotations being emitted
+ (void)srd_session_send_eof(srd_session_);
+ new_annotations();
+#endif
+
if (current_segment_id_ < (logic_mux_data_->logic_segments().size() - 1)) {
// Process next segment
current_segment_id_++;
unique_lock<mutex> input_wait_lock(input_mutex_);
decode_input_cond_.wait(input_wait_lock);
}
+ } else {
+ // Input segment isn't complete yet but samples_to_process is 0, wait for more input data
+ unique_lock<mutex> input_wait_lock(input_mutex_);
+ decode_input_cond_.wait(input_wait_lock);
}
}
return;
}
+ // Update the samplerates for the output logic channels
+ update_output_signals();
+
// Create the session
srd_session_new(&srd_session_);
assert(srd_session_);
srd_pd_output_callback_add(srd_session_, SRD_OUTPUT_BINARY,
DecodeSignal::binary_callback, this);
+ srd_pd_output_callback_add(srd_session_, SRD_OUTPUT_LOGIC,
+ DecodeSignal::logic_output_callback, this);
+
srd_session_start(srd_session_);
// We just recreated the srd session, so all stack changes are applied now
// those stacks which still are processing data while the
// application no longer wants them to.
if (srd_session_) {
+#if defined HAVE_SRD_SESSION_SEND_EOF && HAVE_SRD_SESSION_SEND_EOF
+ (void)srd_session_send_eof(srd_session_);
+#endif
srd_session_terminate_reset(srd_session_);
// Metadata is cleared also, so re-set it
void DecodeSignal::connect_input_notifiers()
{
- // Disconnect the notification slot from the previous set of signals
- disconnect(this, SLOT(on_data_cleared()));
- disconnect(this, SLOT(on_data_received()));
-
// Connect the currently used signals to our slot
for (decode::DecodeChannel& ch : channels_) {
if (!ch.assigned_signal)
continue;
+ const data::SignalBase *signal = ch.assigned_signal.get();
+ connect(signal, SIGNAL(samples_cleared()),
+ this, SLOT(on_data_cleared()), Qt::UniqueConnection);
+ connect(signal, SIGNAL(samples_added(uint64_t, uint64_t, uint64_t)),
+ this, SLOT(on_data_received()), Qt::UniqueConnection);
+
+ if (signal->logic_data())
+ connect(signal->logic_data().get(), SIGNAL(segment_completed()),
+ this, SLOT(on_input_segment_completed()), Qt::UniqueConnection);
+ }
+}
+
+void DecodeSignal::disconnect_input_notifiers()
+{
+ // Disconnect the notification slot from the previous set of signals
+ for (decode::DecodeChannel& ch : channels_) {
+ if (!ch.assigned_signal)
+ continue;
const data::SignalBase *signal = ch.assigned_signal.get();
- connect(signal, &data::SignalBase::samples_cleared,
- this, &DecodeSignal::on_data_cleared);
- connect(signal, &data::SignalBase::samples_added,
- this, &DecodeSignal::on_data_received);
+ disconnect(signal, nullptr, this, SLOT(on_data_cleared()));
+ disconnect(signal, nullptr, this, SLOT(on_data_received()));
+
+ if (signal->logic_data())
+ disconnect(signal->logic_data().get(), nullptr, this, SLOT(on_input_segment_completed()));
}
}
ds->new_binary_data(ds->current_segment_id_, (void*)dec, pdb->bin_class);
}
+void DecodeSignal::logic_output_callback(srd_proto_data *pdata, void *decode_signal)
+{
+ assert(pdata);
+ assert(decode_signal);
+
+ DecodeSignal *const ds = (DecodeSignal*)decode_signal;
+ assert(ds);
+
+ if (ds->decode_interrupt_)
+ return;
+
+ lock_guard<mutex> lock(ds->output_mutex_);
+
+ assert(pdata->pdo);
+ assert(pdata->pdo->di);
+ const srd_decoder *const decc = pdata->pdo->di->decoder;
+ assert(decc);
+
+ const srd_proto_data_logic *const pdl = (const srd_proto_data_logic*)pdata->data;
+ assert(pdl);
+
+ // FIXME Only one group supported for now
+ if (pdl->logic_group > 0) {
+ qWarning() << "Received logic output state change for group" << pdl->logic_group << "from decoder" \
+ << QString::fromUtf8(decc->name) << "but only group 0 is currently supported";
+ return;
+ }
+
+ shared_ptr<Logic> output_logic = ds->output_logic_.at(decc);
+
+ vector< shared_ptr<Segment> > segments = output_logic->segments();
+
+ shared_ptr<LogicSegment> last_segment;
+
+ if (!segments.empty())
+ last_segment = dynamic_pointer_cast<LogicSegment>(segments.back());
+ else {
+ // Happens when the data was cleared - all segments are gone then
+ // segment_id is always 0 as it's the first segment
+ last_segment = make_shared<data::LogicSegment>(
+ *output_logic, 0, (output_logic->num_channels() + 7) / 8, output_logic->get_samplerate());
+ output_logic->push_segment(last_segment);
+ }
+
+ if (pdata->start_sample < pdata->end_sample) {
+ vector<uint8_t> data;
+ const unsigned int unit_size = last_segment->unit_size();
+ data.resize(unit_size * (1 + pdl->repeat_count));
+
+ if (unit_size == 1)
+ for (unsigned int i = 0; i <= pdl->repeat_count; i++)
+ data.data()[i * unit_size] = *((uint8_t*)pdl->data);
+ else if (unit_size == 2)
+ for (unsigned int i = 0; i <= pdl->repeat_count; i++)
+ data.data()[i * unit_size] = *((uint16_t*)pdl->data);
+ else if (unit_size <= 4)
+ for (unsigned int i = 0; i <= pdl->repeat_count; i++)
+ data.data()[i * unit_size] = *((uint32_t*)pdl->data);
+ else if (unit_size <= 8)
+ for (unsigned int i = 0; i <= pdl->repeat_count; i++)
+ data.data()[i * unit_size] = *((uint64_t*)pdl->data);
+ else
+ for (unsigned int i = 0; i <= pdl->repeat_count; i++)
+ memcpy((void*)&data.data()[i * unit_size], (void*)pdl->data, unit_size);
+
+ last_segment->append_payload(data.data(), data.size());
+ } else
+ qWarning() << "Ignoring malformed logic output state change for group" << pdl->logic_group << "from decoder" \
+ << QString::fromUtf8(decc->name) << "from" << pdata->start_sample << "to" << pdata->end_sample;
+}
+
void DecodeSignal::on_capture_state_changed(int state)
{
// If a new acquisition was started, we need to start decoding from scratch
void DecodeSignal::on_data_received()
{
// If we detected a lack of input data when trying to start decoding,
- // we have set an error message. Only try again if we now have data
+ // we have set an error message. Bail out if we still don't have data
// to work with
if ((!error_message_.isEmpty()) && (get_input_segment_count() == 0))
return;
- else {
+
+ if (!error_message_.isEmpty()) {
error_message_.clear();
// TODO Emulate noquote()
- qDebug().nospace() << name() << ": Error cleared";
+ qDebug().nospace() << name() << ": Input data available, error cleared";
}
if (!logic_mux_thread_.joinable())
logic_mux_cond_.notify_one();
}
+void DecodeSignal::on_input_segment_completed()
+{
+ if (!logic_mux_thread_.joinable())
+ logic_mux_cond_.notify_one();
+}
+
void DecodeSignal::on_annotation_visibility_changed()
{
annotation_visibility_changed();
DecodeSignal(pv::Session &session);
virtual ~DecodeSignal();
+ /**
+ * Sets the name of the signal.
+ */
+ virtual void set_name(QString name);
+
+ /**
+ * Set the color of the signal.
+ */
+ virtual void set_color(QColor color);
+
bool is_decode_signal() const;
const vector< shared_ptr<Decoder> >& decoder_stack() const;
void assign_signal(const uint16_t channel_id, shared_ptr<const SignalBase> signal);
int get_assigned_signal_count() const;
+ void update_output_signals();
+
void set_initial_pin_state(const uint16_t channel_id, const int init_state);
virtual double get_samplerate() const;
void stop_srd_session();
void connect_input_notifiers();
+ void disconnect_input_notifiers();
void create_decode_segment();
static void annotation_callback(srd_proto_data *pdata, void *decode_signal);
static void binary_callback(srd_proto_data *pdata, void *decode_signal);
+ static void logic_output_callback(srd_proto_data *pdata, void *decode_signal);
Q_SIGNALS:
void decoder_stacked(void* decoder); ///< decoder is of type decode::Decoder*
void on_capture_state_changed(int state);
void on_data_cleared();
void on_data_received();
+ void on_input_segment_completed();
void on_annotation_visibility_changed();
atomic<bool> decode_interrupt_, logic_mux_interrupt_;
bool decode_paused_;
+
+ map<const srd_decoder*, shared_ptr<Logic>> output_logic_;
+ map<const srd_decoder*, vector<uint8_t>> output_logic_muxed_data_;
+ vector< shared_ptr<SignalBase>> output_signals_;
};
} // namespace data
if ((samplerate_ == 1) && (segment->samplerate() > 1))
samplerate_ = segment->samplerate();
+
+ connect(segment.get(), SIGNAL(completed()), this, SLOT(on_segment_completed()));
}
const deque< shared_ptr<LogicSegment> >& Logic::logic_segments() const
void Logic::clear()
{
- segments_.clear();
+ if (!segments_.empty()) {
+ segments_.clear();
- samples_cleared();
+ samples_cleared();
+ }
}
void Logic::set_samplerate(double value)
samples_added(segment, start_sample, end_sample);
}
+void Logic::on_segment_completed()
+{
+ segment_completed();
+}
+
} // namespace data
} // namespace pv
void samples_added(SharedPtrToSegment segment, uint64_t start_sample,
uint64_t end_sample);
+private Q_SLOTS:
+ void on_segment_completed();
+
private:
double samplerate_;
const unsigned int num_channels_;
prev_sample_count + 1, prev_sample_count + 1);
}
+void LogicSegment::append_subsignal_payload(unsigned int index, void *data,
+ uint64_t data_size, vector<uint8_t>& destination)
+{
+ if (index == 0)
+ destination.resize(data_size * unit_size_, 0);
+
+ // Set the bits for this sub-signal where needed
+ // Note: the bytes in *data must either be 0 or 1, nothing else
+ unsigned int index_byte_offs = index / 8;
+ uint8_t* output_data = destination.data() + index_byte_offs;
+ uint8_t* input_data = (uint8_t*)data;
+
+ for (uint64_t i = 0; i < data_size; i++) {
+ assert((i * unit_size_ + index_byte_offs) < destination.size());
+ *output_data |= (input_data[i] << index);
+ output_data += unit_size_;
+ }
+
+ if (index == owner_.num_channels() - 1) {
+ // We gathered sample data of all sub-signals, let's append it
+ append_payload(destination.data(), destination.size());
+ destination.clear();
+ }
+}
+
void LogicSegment::get_samples(int64_t start_sample,
int64_t end_sample, uint8_t* dest) const
{
else if (unit_size_ == 4)
downsampleT<uint32_t>(src_ptr, dest_ptr, count);
else if (unit_size_ == 8)
- downsampleT<uint8_t>(src_ptr, dest_ptr, count);
+ downsampleT<uint64_t>(src_ptr, dest_ptr, count);
else
downsampleGeneric(src_ptr, dest_ptr, count);
len_sample -= count;
void append_payload(shared_ptr<sigrok::Logic> logic);
void append_payload(void *data, uint64_t data_size);
+ /**
+ * Appends sample data for a single channel where each byte
+ * represents one sample - if it's 0 the state is low, if 1 high.
+ * Other values are not permitted.
+ * Assumes that all channels are having samples added and in the
+ * order of 0..n, not n..0.
+ * Also assumes the the number of samples added for each channel
+ * is constant for every invokation for 0..n. The number of samples
+ * hence may only change when index is 0.
+ */
+ void append_subsignal_payload(unsigned int index, void *data,
+ uint64_t data_size, vector<uint8_t>& destination);
+
void get_samples(int64_t start_sample, int64_t end_sample, uint8_t* dest) const;
/**
return;
}
- disconnect(this, SLOT(on_data_received()));
- disconnect(this, SLOT(on_enabled_changed()));
+ disconnect(&session_, SIGNAL(data_received()), this, SLOT(on_data_received()));
+
+ for (const shared_ptr<SignalBase>& sb : session_.signalbases()) {
+ if (sb->analog_data())
+ disconnect(sb->analog_data().get(), nullptr, this, SLOT(on_data_received()));
+ disconnect(sb.get(), nullptr, this, SLOT(on_enabled_changed()));
+ }
fnc_sample_ = new fnc_sample<double>(*this);
if (error_message_.isEmpty()) {
// Connect to the session data notification if we have no input signals
if (input_signals_.empty())
- connect(&session_, SIGNAL(data_received()),
- this, SLOT(on_data_received()));
+ connect(&session_, SIGNAL(data_received()), this, SLOT(on_data_received()));
gen_interrupt_ = false;
gen_thread_ = std::thread(&MathSignal::generation_proc, this);
bool all_input_signals_enabled(QString &disabled_signals) const;
Q_SIGNALS:
- void samples_cleared();
-
- void samples_added(uint64_t segment_id, uint64_t start_sample,
- uint64_t end_sample);
-
- void min_max_changed(float min, float max);
-
void expression_changed(QString expression);
private Q_SLOTS:
#include "pv/util.hpp"
#include <atomic>
+#include <memory>
#include <mutex>
#include <thread>
#include <deque>
conversion_type_(NoConversion),
min_value_(0),
max_value_(0),
+ index_(0),
error_message_("")
{
if (channel_) {
- internal_name_ = QString::fromStdString(channel_->name());
- index_ = channel_->index();
+ set_internal_name(QString::fromStdString(channel_->name()));
+ set_index(channel_->index());
}
connect(&delayed_conversion_starter_, SIGNAL(timeout()),
void SignalBase::set_internal_name(QString internal_name)
{
internal_name_ = internal_name;
+
+ // Use this name also for the QObject instance
+ setObjectName(internal_name);
}
QString SignalBase::display_name() const
if (!data_)
return nullptr;
- shared_ptr<Logic> result = dynamic_pointer_cast<Logic>(data_);
+ shared_ptr<Logic> result;
if (((conversion_type_ == A2LConversionByThreshold) ||
(conversion_type_ == A2LConversionBySchmittTrigger)))
result = dynamic_pointer_cast<Logic>(converted_data_);
+ else
+ result = dynamic_pointer_cast<Logic>(data_);
return result;
}
+shared_ptr<pv::data::SignalData> SignalBase::data() const
+{
+ return data_;
+}
+
bool SignalBase::segment_is_complete(uint32_t segment_id) const
{
bool result = true;
QVariant value = settings.value("color");
// Workaround for Qt QColor serialization bug on OSX
- if ((QMetaType::Type)(value.type()) == QMetaType::QColor)
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ bool is_qcolor = (QMetaType::Type)(value.typeId()) == QMetaType::QColor;
+#else
+ bool is_qcolor = (QMetaType::Type)(value.type()) == QMetaType::QColor;
+#endif
+ if (is_qcolor)
set_color(value.value<QColor>());
else
set_color(QColor::fromRgba(value.value<uint32_t>()));
delete[] lsamples;
delete[] asamples;
}
+
+ samples_added(lsegment->segment_id(), start_sample, end_sample);
}
void SignalBase::convert_single_segment(shared_ptr<AnalogSegment> asegment,
// we do another round of sample conversion.
} while ((complete_state != old_complete_state) ||
(end_sample - old_end_sample >= ConversionBlockSize));
+
+ if (complete_state)
+ lsegment->set_complete();
}
void SignalBase::conversion_thread_proc()
shared_ptr<AnalogSegment> asegment = analog_data->analog_segments().front();
assert(asegment);
+ connect(asegment.get(), SIGNAL(completed()), this, SLOT(on_input_segment_completed()));
const shared_ptr<Logic> logic_data = dynamic_pointer_cast<Logic>(converted_data_);
assert(logic_data);
if (asegment->is_complete() &&
analog_data->analog_segments().size() > logic_data->logic_segments().size()) {
+ disconnect(asegment.get(), SIGNAL(completed()), this, SLOT(on_input_segment_completed()));
+
// There are more segments to process
segment_id++;
try {
asegment = analog_data->analog_segments().at(segment_id);
+ disconnect(asegment.get(), SIGNAL(completed()), this, SLOT(on_input_segment_completed()));
+ connect(asegment.get(), SIGNAL(completed()), this, SLOT(on_input_segment_completed()));
} catch (out_of_range&) {
qDebug() << "Conversion error for" << name() << ": no analog segment" \
<< segment_id << ", segments size is" << analog_data->analog_segments().size();
logic_data->push_segment(new_segment);
lsegment = logic_data->logic_segments().back();
- }
-
- // No more samples/segments to process, wait for data or interrupt
- if (!conversion_interrupt_) {
- unique_lock<mutex> input_lock(conversion_input_mutex_);
- conversion_input_cond_.wait(input_lock);
+ } else {
+ // No more samples/segments to process, wait for data or interrupt
+ if (!conversion_interrupt_) {
+ unique_lock<mutex> input_lock(conversion_input_mutex_);
+ conversion_input_cond_.wait(input_lock);
+ }
}
} while (!conversion_interrupt_);
+
+ disconnect(asegment.get(), SIGNAL(completed()), this, SLOT(on_input_segment_completed()));
}
void SignalBase::start_conversion(bool delayed_start)
stop_conversion();
- if (converted_data_)
+ if (converted_data_ && (converted_data_->get_segment_count() > 0)) {
converted_data_->clear();
-
- samples_cleared();
+ samples_cleared();
+ }
conversion_interrupt_ = false;
conversion_thread_ = std::thread(&SignalBase::conversion_thread_proc, this);
void SignalBase::on_samples_cleared()
{
- if (converted_data_)
+ if (converted_data_ && (converted_data_->get_segment_count() > 0)) {
converted_data_->clear();
-
- samples_cleared();
+ samples_cleared();
+ }
}
void SignalBase::on_samples_added(SharedPtrToSegment segment, uint64_t start_sample,
samples_added(segment->segment_id(), start_sample, end_sample);
}
+void SignalBase::on_input_segment_completed()
+{
+ if (conversion_type_ != NoConversion)
+ if (conversion_thread_.joinable()) {
+ // Notify the conversion thread since it's running
+ conversion_input_cond_.notify_one();
+ }
+}
+
void SignalBase::on_min_max_changed(float min, float max)
{
// Restart conversion if one is enabled and uses a calculated threshold
class SignalBase : public QObject, public enable_shared_from_this<SignalBase>
{
Q_OBJECT
- Q_PROPERTY(QString error_message READ get_error_message)
+ Q_PROPERTY(QString error_message READ get_error_message NOTIFY error_message_changed)
public:
enum ChannelType {
/**
* Set the color of the signal.
*/
- void set_color(QColor color);
+ virtual void set_color(QColor color);
/**
* Get the background color of the signal.
*/
shared_ptr<pv::data::Logic> logic_data() const;
+ /**
+ * Get the primary internal data object, i.e. the data that was acquired from the device.
+ */
+ shared_ptr<pv::data::SignalData> data() const;
+
/**
* Determines whether a given segment is complete (i.e. end-of-frame has
* been seen). It only considers the original data, not the converted data.
void enabled_changed(const bool &value);
void name_changed(const QString &name);
void color_changed(const QColor &color);
- void error_message_changed(const QString &msg);
+ void error_message_changed(QString msg);
void conversion_type_changed(const ConversionType t);
void samples_cleared();
void on_samples_added(SharedPtrToSegment segment, uint64_t start_sample,
uint64_t end_sample);
+ void on_input_segment_completed();
+
void on_min_max_changed(float min, float max);
void on_capture_state_changed(int state);
virtual void set_samplerate(double value) = 0;
virtual double get_samplerate() const = 0;
+
+Q_SIGNALS:
+ void segment_completed();
};
} // namespace data
};
Settings::Settings(DeviceManager &device_manager, QWidget *parent) :
- QDialog(parent, nullptr),
+ QDialog(parent),
device_manager_(device_manager)
{
resize(600, 400);
QComboBox *language_cb = new QComboBox();
Application* a = qobject_cast<Application*>(QApplication::instance());
- QString current_language = settings.value(GlobalSettings::Key_General_Language).toString();
+ QString current_language = settings.value(GlobalSettings::Key_General_Language, "en").toString();
for (const QString& language : a->get_languages()) {
const QLocale locale = QLocale(language);
const QString desc = locale.languageToString(locale.language());
language_cb->setCurrentIndex(index);
}
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ connect(language_cb, SIGNAL(currentTextChanged(const QString&)),
+ this, SLOT(on_general_language_changed(const QString&)));
+#else
connect(language_cb, SIGNAL(currentIndexChanged(const QString&)),
this, SLOT(on_general_language_changed(const QString&)));
+#endif
general_layout->addRow(tr("User interface language"), language_cb);
// Theme combobox
if (current_style.isEmpty())
style_cb->setCurrentIndex(0);
else
- style_cb->setCurrentIndex(style_cb->findText(current_style, nullptr));
+ style_cb->setCurrentIndex(style_cb->findText(current_style));
connect(style_cb, SIGNAL(currentIndexChanged(int)),
this, SLOT(on_general_style_changed(int)));
cb = create_checkbox(GlobalSettings::Key_View_TriggerIsZeroTime,
SLOT(on_view_triggerIsZero_changed(int)));
- trace_view_layout->addRow(tr("Show time zero at the trigger"), cb);
+ trace_view_layout->addRow(tr("Show time zero at the &trigger"), cb);
cb = create_checkbox(GlobalSettings::Key_View_StickyScrolling,
SLOT(on_view_stickyScrolling_changed(int)));
trace_view_layout->addRow(tr("Always keep &newest samples at the right edge during capture"), cb);
+ cb = create_checkbox(GlobalSettings::Key_View_AllowVerticalDragging,
+ SLOT(on_view_allowVerticalDragging_changed(int)));
+ trace_view_layout->addRow(tr("Allow &vertical dragging in the view area"), cb);
+
cb = create_checkbox(GlobalSettings::Key_View_ShowSamplingPoints,
SLOT(on_view_showSamplingPoints_changed(int)));
trace_view_layout->addRow(tr("Show data &sampling points"), cb);
cb = create_checkbox(GlobalSettings::Key_View_FillSignalHighAreas,
SLOT(on_view_fillSignalHighAreas_changed(int)));
- trace_view_layout->addRow(tr("Fill high areas of logic signals"), cb);
+ trace_view_layout->addRow(tr("Fill &high areas of logic signals"), cb);
ColorButton* high_fill_cb = new ColorButton(parent);
high_fill_cb->set_color(QColor::fromRgba(
SLOT(on_view_showHoverMarker_changed(int)));
trace_view_layout->addRow(tr("Highlight mouse cursor using a vertical marker line"), cb);
+ cb = create_checkbox(GlobalSettings::Key_View_KeepRulerItemSelected,
+ SLOT(on_view_keepRulerItemSelected_changed(int)));
+ trace_view_layout->addRow(tr("Keep active item on ruler selected when editing popup is closed"), cb);
+
QSpinBox *snap_distance_sb = new QSpinBox();
snap_distance_sb->setRange(0, 1000);
snap_distance_sb->setSuffix(tr(" pixels"));
settings.setValue(GlobalSettings::Key_View_StickyScrolling, state ? true : false);
}
+void Settings::on_view_allowVerticalDragging_changed(int state)
+{
+ GlobalSettings settings;
+ settings.setValue(GlobalSettings::Key_View_AllowVerticalDragging, state ? true : false);
+}
+
void Settings::on_view_showSamplingPoints_changed(int state)
{
GlobalSettings settings;
settings.setValue(GlobalSettings::Key_View_ShowHoverMarker, state ? true : false);
}
+void Settings::on_view_keepRulerItemSelected_changed(int state)
+{
+ GlobalSettings settings;
+ settings.setValue(GlobalSettings::Key_View_KeepRulerItemSelected, state ? true : false);
+}
+
void Settings::on_view_snapDistance_changed(int value)
{
GlobalSettings settings;
void on_view_triggerIsZero_changed(int state);
void on_view_coloredBG_changed(int state);
void on_view_stickyScrolling_changed(int state);
+ void on_view_allowVerticalDragging_changed(int state);
void on_view_showSamplingPoints_changed(int state);
void on_view_fillSignalHighAreas_changed(int state);
void on_view_fillSignalHighAreaColor_changed(QColor color);
void on_view_showAnalogMinorGrid_changed(int state);
void on_view_showHoverMarker_changed(int state);
+ void on_view_keepRulerItemSelected_changed(int state);
void on_view_snapDistance_changed(int value);
void on_view_cursorFillColor_changed(QColor color);
void on_view_conversionThresholdDispMode_changed(int state);
this, SLOT(on_progress_updated()));
connect(&session_, SIGNAL(store_successful()),
&session, SLOT(on_data_saved()));
+ connect(this, SIGNAL(canceled()), this, SLOT(on_cancel()));
// Since we're not setting any progress in case of an error, the dialog
// will pop up after the minimumDuration time has been reached - 4000 ms
setMaximum(p.second);
} else {
const QString err = session_.error();
- if (!err.isEmpty() && !showing_error_)
+ if (err.isEmpty())
+ close();
+ else if (!showing_error_)
show_error();
}
}
+void StoreProgress::on_cancel()
+{
+ session_.cancel();
+}
+
} // namespace dialogs
} // namespace pv
private Q_SLOTS:
void on_progress_updated();
+ void on_cancel();
private:
pv::StoreSession session_;
std::string data_;
};
- static const std::string reserved_words[] =
+ const std::string reserved_words[] =
{
"break", "case", "continue", "default", "false", "for",
"if", "else", "ilike", "in", "like", "and", "nand", "nor",
static const std::size_t reserved_words_size = sizeof(reserved_words) / sizeof(std::string);
- static const std::string reserved_symbols[] =
+ const std::string reserved_symbols[] =
{
"abs", "acos", "acosh", "and", "asin", "asinh", "atan",
"atanh", "atan2", "avg", "break", "case", "ceil", "clamp",
static const std::size_t reserved_symbols_size = sizeof(reserved_symbols) / sizeof(std::string);
- static const std::string base_function_list[] =
+ const std::string base_function_list[] =
{
"abs", "acos", "acosh", "asin", "asinh", "atan", "atanh",
"atan2", "avg", "ceil", "clamp", "cos", "cosh", "cot",
static const std::size_t base_function_list_size = sizeof(base_function_list) / sizeof(std::string);
- static const std::string logic_ops_list[] =
+ const std::string logic_ops_list[] =
{
"and", "nand", "nor", "not", "or", "xnor", "xor", "&", "|"
};
static const std::size_t logic_ops_list_size = sizeof(logic_ops_list) / sizeof(std::string);
- static const std::string cntrl_struct_list[] =
+ const std::string cntrl_struct_list[] =
{
"if", "switch", "for", "while", "repeat", "return"
};
static const std::size_t cntrl_struct_list_size = sizeof(cntrl_struct_list) / sizeof(std::string);
- static const std::string arithmetic_ops_list[] =
+ const std::string arithmetic_ops_list[] =
{
"+", "-", "*", "/", "%", "^"
};
static const std::size_t arithmetic_ops_list_size = sizeof(arithmetic_ops_list) / sizeof(std::string);
- static const std::string assignment_ops_list[] =
+ const std::string assignment_ops_list[] =
{
":=", "+=", "-=",
"*=", "/=", "%="
static const std::size_t assignment_ops_list_size = sizeof(assignment_ops_list) / sizeof(std::string);
- static const std::string inequality_ops_list[] =
+ const std::string inequality_ops_list[] =
{
"<", "<=", "==",
"=", "!=", "<>",
const QString GlobalSettings::Key_View_TriggerIsZeroTime = "View_TriggerIsZeroTime";
const QString GlobalSettings::Key_View_ColoredBG = "View_ColoredBG";
const QString GlobalSettings::Key_View_StickyScrolling = "View_StickyScrolling";
+const QString GlobalSettings::Key_View_AllowVerticalDragging = "View_AllowVerticalDragging";
const QString GlobalSettings::Key_View_ShowSamplingPoints = "View_ShowSamplingPoints";
const QString GlobalSettings::Key_View_FillSignalHighAreas = "View_FillSignalHighAreas";
const QString GlobalSettings::Key_View_FillSignalHighAreaColor = "View_FillSignalHighAreaColor";
const QString GlobalSettings::Key_View_DefaultDivHeight = "View_DefaultDivHeight";
const QString GlobalSettings::Key_View_DefaultLogicHeight = "View_DefaultLogicHeight";
const QString GlobalSettings::Key_View_ShowHoverMarker = "View_ShowHoverMarker";
+const QString GlobalSettings::Key_View_KeepRulerItemSelected = "View_KeepRulerItemSelected";
const QString GlobalSettings::Key_View_SnapDistance = "View_SnapDistance";
const QString GlobalSettings::Key_View_CursorFillColor = "View_CursorFillColor";
const QString GlobalSettings::Key_View_CursorShowFrequency = "View_CursorShowFrequency";
if (!contains(Key_View_ZoomToFitAfterAcq))
setValue(Key_View_ZoomToFitAfterAcq, true);
+ // Allow vertical dragging by default
+ if (!contains(Key_View_AllowVerticalDragging))
+ setValue(Key_View_AllowVerticalDragging, true);
+
// Enable colored trace backgrounds by default
if (!contains(Key_View_ColoredBG))
setValue(Key_View_ColoredBG, true);
if (!contains(Key_View_ShowHoverMarker))
setValue(Key_View_ShowHoverMarker, true);
+ if (!contains(Key_View_KeepRulerItemSelected))
+ setValue(Key_View_KeepRulerItemSelected, false);
+
if (!contains(Key_View_SnapDistance))
setValue(Key_View_SnapDistance, 15);
g_variant_get_size(v));
settings.setValue("value", var_data);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ settings.setValue("type", (const char *)var_type_str);
+#else
settings.setValue("type", var_type_str);
+#endif
g_free(var_type_str);
}
QByteArray data = settings.value("value").toByteArray();
- gpointer var_data = g_memdup((gconstpointer)data.constData(),
- (guint)data.size());
+#if GLIB_CHECK_VERSION(2, 67, 3) // See https://discourse.gnome.org/t/port-your-module-from-g-memdup-to-g-memdup2-now/5538
+ gpointer var_data = g_memdup2((gconstpointer)data.constData(), (gsize)data.size());
+#else
+ gpointer var_data = g_memdup((gconstpointer)data.constData(), (guint)data.size());
+#endif
GVariant *value = g_variant_new_from_data(var_type, var_data,
data.size(), false, g_free, var_data);
QByteArray data = settings.value("value").toByteArray();
- gpointer var_data = g_memdup((gconstpointer)data.constData(),
- (guint)data.size());
+#if GLIB_CHECK_VERSION(2, 67, 3) // See https://discourse.gnome.org/t/port-your-module-from-g-memdup-to-g-memdup2-now/5538
+ gpointer var_data = g_memdup2((gconstpointer)data.constData(), (gsize)data.size());
+#else
+ gpointer var_data = g_memdup((gconstpointer)data.constData(), (guint)data.size());
+#endif
GVariant *value = g_variant_new_from_data(var_type, var_data,
data.size(), false, g_free, var_data);
static const QString Key_View_TriggerIsZeroTime;
static const QString Key_View_ColoredBG;
static const QString Key_View_StickyScrolling;
+ static const QString Key_View_AllowVerticalDragging;
static const QString Key_View_ShowSamplingPoints;
static const QString Key_View_FillSignalHighAreas;
static const QString Key_View_FillSignalHighAreaColor;
static const QString Key_View_DefaultDivHeight;
static const QString Key_View_DefaultLogicHeight;
static const QString Key_View_ShowHoverMarker;
+ static const QString Key_View_KeepRulerItemSelected;
static const QString Key_View_SnapDistance;
static const QString Key_View_CursorFillColor;
static const QString Key_View_CursorShowInterval;
char *text = g_strdup_vprintf(format, args);
QString s = QString::fromUtf8(text);
+#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
+ for (QString& substring : s.split("\n", Qt::SkipEmptyParts))
+ logging.log(substring, LogSource_srd);
+#else
for (QString& substring : s.split("\n", QString::SkipEmptyParts))
logging.log(substring, LogSource_srd);
+#endif
g_free(text);
return SR_OK;
{
setup_ui();
restore_ui_settings();
+ connect(this, SIGNAL(session_error_raised(const QString, const QString)),
+ this, SLOT(on_session_error_raised(const QString, const QString)));
}
MainWindow::~MainWindow()
void MainWindow::show_session_error(const QString text, const QString info_text)
{
// TODO Emulate noquote()
- qDebug() << "Notifying user of session error:" << info_text;
+ qDebug() << "Notifying user of session error: " << text << "; " << info_text;
QMessageBox msg;
msg.setText(text + "\n\n" + info_text);
qobject_cast<views::ViewBase*>(v.get()),
SLOT(trigger_event(int, util::Timestamp)));
+ connect(&session, SIGNAL(session_error_raised(const QString, const QString)),
+ this, SLOT(on_session_error_raised(const QString, const QString)));
+
if (type == views::ViewTypeTrace) {
views::trace::View *tv =
qobject_cast<views::trace::View*>(v.get());
session_selector_.setCornerWidget(static_tab_widget_, Qt::TopLeftCorner);
session_selector_.setTabsClosable(true);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ close_application_shortcut_ = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q), this, SLOT(close()));
+ close_current_tab_shortcut_ = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_W), this, SLOT(on_close_current_tab()));
+#else
close_application_shortcut_ = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q), this, SLOT(close()));
- close_application_shortcut_->setAutoRepeat(false);
-
close_current_tab_shortcut_ = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_W), this, SLOT(on_close_current_tab()));
+#endif
+ close_application_shortcut_->setAutoRepeat(false);
connect(new_session_button_, SIGNAL(clicked(bool)),
this, SLOT(on_new_session_clicked()));
vector< shared_ptr<Session> > hw_sessions;
// Make a list of all sessions where a hardware device is used
- for (shared_ptr<Session> s : sessions_) {
+ for (const shared_ptr<Session>& s : sessions_) {
shared_ptr<devices::HardwareDevice> hw_device =
dynamic_pointer_cast< devices::HardwareDevice >(s->device());
if (!hw_device)
if (any_running)
s->stop_capture();
else
- s->start_capture([&](QString message) {
- show_session_error("Capture failed", message); });
+ s->start_capture([&](QString message) {Q_EMIT session_error_raised("Capture failed", message);});
} else {
shared_ptr<Session> session = last_focused_session_;
switch (session->get_capture_state()) {
case Session::Stopped:
- session->start_capture([&](QString message) {
- show_session_error("Capture failed", message); });
+ session->start_capture([&](QString message) {Q_EMIT session_error_raised("Capture failed", message);});
break;
case Session::AwaitingTrigger:
case Session::Running:
on_tab_close_requested(tab);
}
+void MainWindow::on_session_error_raised(const QString text, const QString info_text) {
+ MainWindow::show_session_error(text, info_text);
+}
+
} // namespace pv
virtual bool restoreState(const QByteArray &state, int version = 0);
+Q_SIGNALS:
+ void session_error_raised(const QString text, const QString info_text);
+
public Q_SLOTS:
void on_run_stop_clicked();
+ void on_session_error_raised(const QString text, const QString info_text);
private Q_SLOTS:
void on_add_view(ViewType type, Session *session);
layout_.addRow(&filter_buttons_bar_);
// Connect the check-box signal mapper
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ connect(&check_box_mapper_, SIGNAL(mappedObject(QObject*)),
+ this, SLOT(on_channel_checked(QObject*)));
+#else
connect(&check_box_mapper_, SIGNAL(mapped(QWidget*)),
this, SLOT(on_channel_checked(QWidget*)));
+#endif
}
void Channels::set_all_channels(bool set)
updating_channels_ = false;
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+void Channels::on_channel_checked(QObject *widget)
+#else
void Channels::on_channel_checked(QWidget *widget)
+#endif
{
if (updating_channels_)
return;
void showEvent(QShowEvent *event);
private Q_SLOTS:
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ void on_channel_checked(QObject *widget);
+#else
void on_channel_checked(QWidget *widget);
+#endif
void enable_all_channels();
void disable_all_channels();
cur_samplerate_(0),
data_saved_(true)
{
+ // Use this name also for the QObject instance
+ setObjectName(name_);
}
Session::~Session()
name_ = name;
+ // Use this name also for the QObject instance
+ setObjectName(name_);
+
name_changed();
}
} catch (const QString &e) {
device_.reset();
MainWindow::show_session_error(tr("Failed to open device"), e);
+ } catch (const sigrok::Error &e) {
+ device_.reset();
+ MainWindow::show_session_error(tr("Failed to open device"), QString(e.what()));
}
if (device_) {
file_name.toStdString())));
} catch (Error& e) {
MainWindow::show_session_error(tr("Failed to load %1").arg(file_name), e.what());
- set_default_device();
- main_bar_->update_device_list();
+ return;
+ }
+
+ if (!device_) {
+ MainWindow::show_session_error(errorMessage, "");
return;
}
main_bar_->update_device_list();
start_capture([&, errorMessage](QString infoMessage) {
- MainWindow::show_session_error(errorMessage, infoMessage); });
+ Q_EMIT session_error_raised(errorMessage, infoMessage); });
// Only set save path if we loaded an srzip file
if (dynamic_pointer_cast<devices::SessionFile>(device_))
name_changed();
}
+ acq_start_time_ = Glib::DateTime::create_now_local();
+
// Begin the session
sampling_thread_ = std::thread(&Session::sample_thread_proc, this, error_handler);
}
return samplerate;
}
+Glib::DateTime Session::get_acquisition_start_time() const
+{
+ return acq_start_time_;
+}
+
uint32_t Session::get_highest_segment_id() const
{
return highest_segment_id_;
#include <thread>
#include <vector>
+#include <glibmm/datetime.h>
+
#include <QObject>
#include <QSettings>
#include <QString>
void stop_capture();
double get_samplerate() const;
+ Glib::DateTime get_acquisition_start_time() const;
uint32_t get_highest_segment_id() const;
uint64_t get_segment_sample_count(uint32_t segment_id) const;
void data_received();
void add_view(ViewType type, Session *session);
+ void session_error_raised(const QString text, const QString info_text);
public Q_SLOTS:
void on_data_saved();
bool frame_began_;
QElapsedTimer acq_time_;
+ Glib::DateTime acq_start_time_;
MetadataObjManager metadata_obj_manager_;
{{ConfigKey::SAMPLERATE, Glib::Variant<guint64>::create(
any_segment->samplerate())}});
output_->receive(meta);
+
+ auto header = context->create_header_packet(session_.get_acquisition_start_time());
+ output_->receive(header);
} catch (Error& error) {
error_ = tr("Error while saving: ") + error.what();
return false;
units_stored_ = unit_count_ - (sample_count_ >> progress_scale);
}
- auto dfend = context->create_end_packet();
- const string ldata_str = output_->receive(dfend);
- if (output_stream_.is_open())
- output_stream_ << ldata_str;
+ try {
+ auto dfend = context->create_end_packet();
+ const string ldata_str = output_->receive(dfend);
+ if (output_stream_.is_open())
+ output_stream_ << ldata_str;
+ } catch (Error& error) {
+ error_ = tr("Error while saving: ") + error.what();
+ }
// Zeroing the progress variables indicates completion
units_stored_ = unit_count_ = 0;
Qt::ItemFlags DecoderCollectionModel::flags(const QModelIndex& index) const
{
if (!index.isValid())
- return nullptr;
+ return Qt::NoItemFlags;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
const QModelIndex& previous)
{
QTreeView::currentChanged(current, previous);
- currentChanged(current);
+
+ current_changed(current);
}
connect(filter, SIGNAL(returnPressed()),
this, SLOT(on_filter_return_pressed()));
- connect(tree_view_, SIGNAL(currentChanged(const QModelIndex&)),
+ connect(tree_view_, SIGNAL(current_changed(const QModelIndex&)),
this, SLOT(on_item_changed(const QModelIndex&)));
connect(tree_view_, SIGNAL(activated(const QModelIndex&)),
this, SLOT(on_item_activated(const QModelIndex&)));
void currentChanged(const QModelIndex& current, const QModelIndex& previous);
Q_SIGNALS:
- void currentChanged(const QModelIndex& current);
+ void current_changed(const QModelIndex& current);
};
class SubWindow : public SubWindowBase
action_open_->setText(tr("&Open..."));
action_open_->setIcon(QIcon::fromTheme("document-open",
QIcon(":/icons/document-open.png")));
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ action_open_->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_O));
+#else
action_open_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_O));
+#endif
connect(action_open_, SIGNAL(triggered(bool)),
this, SLOT(on_actionOpen_triggered()));
action_save_->setText(tr("&Save..."));
action_save_->setIcon(QIcon::fromTheme("document-save-as",
QIcon(":/icons/document-save-as.png")));
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ action_save_->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_S));
+#else
action_save_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_S));
+#endif
connect(action_save_, SIGNAL(triggered(bool)),
this, SLOT(on_actionSave_triggered()));
action_save_selection_as_->setText(tr("Save Selected &Range As..."));
action_save_selection_as_->setIcon(QIcon::fromTheme("document-save-as",
QIcon(":/icons/document-save-as.png")));
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ action_save_selection_as_->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_R));
+#else
action_save_selection_as_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_R));
+#endif
connect(action_save_selection_as_, SIGNAL(triggered(bool)),
this, SLOT(on_actionSaveSelectionAs_triggered()));
sample_count_supported_ = true;
// Add notification of reconfigure events
- disconnect(this, SLOT(on_config_changed()));
+ // Note: No need to disconnect the previous signal as that QObject instance is destroyed
connect(&opts->binding(), SIGNAL(config_changed()),
this, SLOT(on_config_changed()));
* SOFTWARE.
*/
+#include <limits>
+
#include <QApplication>
#include <QClipboard>
#include <QDebug>
#include "QHexView.hpp"
+using std::make_pair;
+
const unsigned int BYTES_PER_LINE = 16;
const unsigned int HEXCHARS_IN_LINE = BYTES_PER_LINE * 3 - 1;
const unsigned int GAP_ADR_HEX = 10;
data_(nullptr),
selectBegin_(0),
selectEnd_(0),
- cursorPos_(0)
+ cursorPos_(0),
+ visible_range_(0, 0),
+ highlighted_sample_(std::numeric_limits<uint64_t>::max())
{
setFont(QFont("Courier", 10));
chunk_colors_.emplace_back(100, 149, 237); // QColorConstants::Svg::cornflowerblue
chunk_colors_.emplace_back(60, 179, 113); // QColorConstants::Svg::mediumseagreen
chunk_colors_.emplace_back(210, 180, 140); // QColorConstants::Svg::tan
+ visible_range_color_ = QColor("#fff5ee"); // QColorConstants::Svg::seashell
} else {
// Color is dark
- chunk_colors_.emplace_back(0, 0, 139); // QColorConstants::Svg::darkblue
- chunk_colors_.emplace_back(34, 139, 34); // QColorConstants::Svg::forestgreen
- chunk_colors_.emplace_back(160, 82, 45); // QColorConstants::Svg::sienna
+ chunk_colors_.emplace_back(0, 0, 139); // QColorConstants::Svg::darkblue
+ chunk_colors_.emplace_back(34, 139, 34); // QColorConstants::Svg::forestgreen
+ chunk_colors_.emplace_back(160, 82, 45); // QColorConstants::Svg::sienna
+ visible_range_color_ = QColor("#fff5ee"); // QColorConstants::Svg::seashell
}
}
viewport()->update();
}
+void QHexView::set_visible_sample_range(uint64_t start, uint64_t end)
+{
+ visible_range_ = make_pair(start, end);
+
+ viewport()->update();
+}
+
+void QHexView::set_highlighted_data_sample(uint64_t sample)
+{
+ highlighted_sample_ = sample;
+
+ viewport()->update();
+}
+
unsigned int QHexView::get_bytes_per_line() const
{
return BYTES_PER_LINE;
data_ = nullptr;
data_size_ = 0;
+ highlighted_sample_ = std::numeric_limits<uint64_t>::max();
+
viewport()->update();
}
if (current_chunk_id_ < data_->chunks.size())
current_chunk_ = data_->chunks[current_chunk_id_];
+
+ current_chunk_sample_ = current_chunk_.sample;
+
+ // Obtain sample of next chunk if there is one
+ if ((current_chunk_id_ + 1) < data_->chunks.size())
+ next_chunk_sample_ = data_->chunks[current_chunk_id_ + 1].sample;
+ else
+ next_chunk_sample_ = std::numeric_limits<uint64_t>::max();
}
-uint8_t QHexView::get_next_byte(bool* is_next_chunk)
+uint8_t QHexView::get_next_byte(bool* is_new_chunk)
{
- if (is_next_chunk != nullptr)
- *is_next_chunk = (current_chunk_offset_ == 0);
+ if (is_new_chunk != nullptr)
+ *is_new_chunk = (current_chunk_offset_ == 0);
uint8_t v = 0;
if (current_chunk_offset_ < current_chunk_.data.size())
v = current_chunk_.data[current_chunk_offset_];
+ current_chunk_sample_ = current_chunk_.sample;
+
+ if (is_new_chunk) {
+ // Obtain sample of next chunk if there is one
+ if ((current_chunk_id_ + 1) < data_->chunks.size())
+ next_chunk_sample_ = data_->chunks[current_chunk_id_ + 1].sample;
+ else
+ next_chunk_sample_ = std::numeric_limits<uint64_t>::max();
+ }
+
current_offset_++;
current_chunk_offset_++;
{
QPainter painter(viewport());
+ QFont normal_font = painter.font();
+ QFont bold_font = painter.font();
+ bold_font.setWeight(QFont::Bold);
+
+ bool bold_font_was_used = false;
+
// Calculate and update the widget and paint area sizes
QSize widgetSize = getFullSize();
setMinimumWidth(widgetSize.width());
charHeight_ - 3, QString::number(offset, 16).toUpper());
// Paint hex values
- QBrush regular = palette().buttonText();
- QBrush selected = palette().highlight();
+ QBrush regular_brush = palette().buttonText();
+ QBrush selected_brush = palette().highlight();
+ QBrush visible_range_brush = QBrush(visible_range_color_);
bool multiple_chunks = (data_->chunks.size() > 1);
unsigned int chunk_color = 0;
initialize_byte_iterator(firstLineIdx * BYTES_PER_LINE);
+
yStart = 2 * charHeight_;
for (size_t lineIdx = firstLineIdx, y = yStart; lineIdx < lastLineIdx; lineIdx++) {
size_t pos = (lineIdx * BYTES_PER_LINE + i) * 2;
// Fetch byte
- bool is_next_chunk;
- uint8_t byte_value = get_next_byte(&is_next_chunk);
+ bool is_new_chunk;
+ uint8_t byte_value = get_next_byte(&is_new_chunk);
- if (is_next_chunk) {
+ if (is_new_chunk) {
chunk_color++;
if (chunk_color == chunk_colors_.size())
chunk_color = 0;
+
+ // New chunk means also new chunk sample, so check for required changes
+ if (bold_font_was_used)
+ painter.setFont(normal_font);
+ if ((highlighted_sample_ >= current_chunk_sample_) && (highlighted_sample_ < next_chunk_sample_)) {
+ painter.setFont(bold_font);
+ bold_font_was_used = true;
+ }
+ }
+
+ // Restore default paint style
+ painter.setBackground(regular_brush);
+ painter.setBackgroundMode(Qt::TransparentMode);
+ if (!multiple_chunks)
+ painter.setPen(palette().color(QPalette::Text));
+ else
+ painter.setPen(chunk_colors_[chunk_color]);
+
+ // Highlight needed because it's the range visible in main view?
+ if ((current_chunk_sample_ >= visible_range_.first) && (current_chunk_sample_ < visible_range_.second)) {
+ painter.setBackgroundMode(Qt::OpaqueMode);
+ painter.setBackground(visible_range_brush);
}
+ // Highlight for selection range needed? (takes priority over visible range highlight)
if ((pos >= selectBegin_) && (pos < selectEnd_)) {
painter.setBackgroundMode(Qt::OpaqueMode);
- painter.setBackground(selected);
+ painter.setBackground(selected_brush);
painter.setPen(palette().color(QPalette::HighlightedText));
- } else {
- painter.setBackground(regular);
- painter.setBackgroundMode(Qt::TransparentMode);
- if (!multiple_chunks)
- painter.setPen(palette().color(QPalette::Text));
- else
- painter.setPen(chunk_colors_[chunk_color]);
}
// First nibble
val = QString::number((byte_value & 0xF), 16).toUpper();
painter.drawText(x + charWidth_, y, val);
- if ((pos >= selectBegin_) && (pos < selectEnd_ - 1) && (i < BYTES_PER_LINE - 1))
+ if ((i < BYTES_PER_LINE - 1) && (current_offset_ < data_size_))
painter.drawText(x + 2 * charWidth_, y, QString(' '));
x += 3 * charWidth_;
int x = posAscii_;
for (size_t i = 0; (i < BYTES_PER_LINE) && (current_offset_ < data_size_); i++) {
// Fetch byte
- uint8_t ch = get_next_byte();
+ bool is_new_chunk;
+ uint8_t ch = get_next_byte(&is_new_chunk);
+
+ if (is_new_chunk) {
+ // New chunk means also new chunk sample, so check for required changes
+ if (bold_font_was_used)
+ painter.setFont(normal_font);
+ if ((highlighted_sample_ >= current_chunk_sample_) && (highlighted_sample_ < next_chunk_sample_)) {
+ painter.setFont(bold_font);
+ bold_font_was_used = true;
+ }
+ }
if ((ch < 0x20) || (ch > 0x7E))
ch = '.';
+ // Restore default paint style
+ painter.setBackgroundMode(Qt::TransparentMode);
+ painter.setBackground(regular_brush);
+ painter.setPen(palette().color(QPalette::Text));
+
+ // Highlight needed because it's the range visible in main view?
+ if ((current_chunk_sample_ >= visible_range_.first) && (current_chunk_sample_ < visible_range_.second)) {
+ painter.setBackgroundMode(Qt::OpaqueMode);
+ painter.setBackground(visible_range_brush);
+ }
+
+ // Highlight for selection range needed? (takes priority over visible range highlight)
size_t pos = (lineIdx * BYTES_PER_LINE + i) * 2;
if ((pos >= selectBegin_) && (pos < selectEnd_)) {
painter.setBackgroundMode(Qt::OpaqueMode);
- painter.setBackground(selected);
+ painter.setBackground(selected_brush);
painter.setPen(palette().color(QPalette::HighlightedText));
- } else {
- painter.setBackgroundMode(Qt::TransparentMode);
- painter.setBackground(regular);
- painter.setPen(palette().color(QPalette::Text));
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ painter.drawText(x, y, QString(QChar(ch)));
+#else
painter.drawText(x, y, QString(ch));
+#endif
x += charWidth_;
}
y += charHeight_;
}
+ // Restore painter defaults
+ painter.setBackgroundMode(Qt::TransparentMode);
+ painter.setBackground(regular_brush);
+
// Paint cursor
if (hasFocus()) {
int x = (cursorPos_ % (2 * BYTES_PER_LINE));
void set_mode(Mode m);
void set_data(const DecodeBinaryClass* data);
+
+ /* Sets range of samples that are visible in the main view */
+ void set_visible_sample_range(uint64_t start, uint64_t end);
+
+ /* Sets sample whose associated data we should highlight */
+ void set_highlighted_data_sample(uint64_t sample);
+
unsigned int get_bytes_per_line() const;
void clear();
protected:
void initialize_byte_iterator(size_t offset);
- uint8_t get_next_byte(bool* is_next_chunk = nullptr);
+ uint8_t get_next_byte(bool* is_new_chunk = nullptr);
void paintEvent(QPaintEvent *event);
void keyPressEvent(QKeyEvent *event);
size_t current_chunk_id_, current_chunk_offset_, current_offset_;
DecodeBinaryDataChunk current_chunk_; // Cache locally so that we're not messed up when the vector is re-allocating its data
+ uint64_t current_chunk_sample_, next_chunk_sample_;
+
+ pair<uint64_t, uint64_t> visible_range_;
+ uint64_t highlighted_sample_;
vector<QColor> chunk_colors_;
+ QColor visible_range_color_;
};
#endif // PULSEVIEW_PV_VIEWS_DECODER_BINARY_QHEXVIEW_HPP
save_action_->setText(tr("&Save..."));
save_action_->setIcon(QIcon::fromTheme("document-save-as",
QIcon(":/icons/document-save-as.png")));
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ save_action_->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_S));
+#else
save_action_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_S));
+#endif
connect(save_action_, SIGNAL(triggered(bool)),
this, SLOT(on_actionSave_triggered()));
parent->setSizePolicy(hex_view_->sizePolicy()); // TODO Must be updated when selected widget changes
+ // Set up metadata event handler
+ session_.metadata_obj_manager()->add_observer(this);
+
reset_view_state();
}
+View::~View()
+{
+ session_.metadata_obj_manager()->remove_observer(this);
+}
+
ViewType View::get_type() const
{
return ViewTypeDecoderBinary;
while (offset < selection.second) {
size_t end = std::min((uint64_t)(selection.second), offset + n);
offset = hex_view_->create_hex_line(offset, end, &s, with_offset, with_ascii);
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+ out_stream << s << Qt::endl;
+#else
out_stream << s << endl;
+#endif
}
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+ out_stream << Qt::endl;
+#else
out_stream << endl;
+#endif
if (out_stream.status() != QTextStream::Ok) {
QMessageBox msg(parent_);
}
}
+void View::on_metadata_object_changed(MetadataObject* obj,
+ MetadataValueType value_type)
+{
+ // Check if we need to update the model's data range. We only work on the
+ // end sample value because the start sample value is updated first and
+ // we need both
+ if ((obj->type() == MetadataObjMainViewRange) &&
+ (value_type == MetadataValueEndSample)) {
+
+ int64_t start_sample = obj->value(MetadataValueStartSample).toLongLong();
+ int64_t end_sample = obj->value(MetadataValueEndSample).toLongLong();
+
+ hex_view_->set_visible_sample_range(start_sample, end_sample);
+ }
+
+ if (obj->type() == MetadataObjMousePos)
+ hex_view_->set_highlighted_data_sample(obj->value(MetadataValueStartSample).toLongLong());
+}
+
void View::perform_delayed_view_update()
{
if (signal_ && !binary_data_exists_)
#include <QStackedWidget>
#include <QToolButton>
-#include <pv/views/viewbase.hpp>
-#include <pv/data/decodesignal.hpp>
+#include "pv/metadata_obj.hpp"
+#include "pv/views/viewbase.hpp"
+#include "pv/data/decodesignal.hpp"
#include "QHexView.hpp"
extern const char* SaveTypeNames[SaveTypeCount];
-class View : public ViewBase
+class View : public ViewBase, public MetadataObjObserverInterface
{
Q_OBJECT
public:
explicit View(Session &session, bool is_main_view=false, QMainWindow *parent = nullptr);
+ ~View();
virtual ViewType get_type() const;
void on_actionSave_triggered(QAction* action = nullptr);
+ virtual void on_metadata_object_changed(MetadataObject* obj,
+ MetadataValueType value_type);
+
virtual void perform_delayed_view_update();
private:
return;
}
- disconnect(this, SLOT(on_annotation_visibility_changed()));
+ if (signal_)
+ for (const shared_ptr<Decoder>& dec : signal_->decoder_stack())
+ disconnect(dec.get(), nullptr, this, SLOT(on_annotation_visibility_changed()));
all_annotations_ = signal->get_all_annotations_by_segment(current_segment);
signal_ = signal;
save_action_->setText(tr("&Save..."));
save_action_->setIcon(QIcon::fromTheme("document-save-as",
QIcon(":/icons/document-save-as.png")));
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ save_action_->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_S));
+#else
save_action_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_S));
+#endif
connect(save_action_, SIGNAL(triggered(bool)),
this, SLOT(on_actionSave_triggered()));
// Check if we need to update the model's data range. We only work on the
// end sample value because the start sample value is updated first and
// we don't want to update the model twice
-
if ((view_mode_selector_->currentIndex() == ViewModeVisible) &&
(obj->type() == MetadataObjMainViewRange) &&
(value_type == MetadataValueEndSample)) {
const QColor AnalogSignal::GridMajorColor = QColor(0, 0, 0, 40 * 256 / 100);
const QColor AnalogSignal::GridMinorColor = QColor(0, 0, 0, 20 * 256 / 100);
-const QColor AnalogSignal::SamplingPointColor(0x77, 0x77, 0x77);
const QColor AnalogSignal::SamplingPointColorLo = QColor(200, 0, 0, 80 * 256 / 100);
const QColor AnalogSignal::SamplingPointColorNe = QColor(0, 0, 0, 80 * 256 / 100);
const QColor AnalogSignal::SamplingPointColorHi = QColor(0, 200, 0, 80 * 256 / 100);
const int AnalogSignal::InfoTextMarginRight = 20;
const int AnalogSignal::InfoTextMarginBottom = 5;
-AnalogSignal::AnalogSignal(
- pv::Session &session,
- shared_ptr<data::SignalBase> base) :
- Signal(session, base),
+AnalogSignal::AnalogSignal(pv::Session &session, shared_ptr<data::SignalBase> base) :
+ LogicSignal(session, base),
value_at_hover_pos_(std::numeric_limits<float>::quiet_NaN()),
scale_index_(4), // 20 per div
pos_vdivs_(1),
neg_vdivs_(1),
resolution_(0),
- display_type_(DisplayBoth),
+ display_type_(DisplayAnalog),
autoranging_(true)
{
axis_pen_ = AxisPen;
pv::data::Analog* analog_data =
- dynamic_cast<pv::data::Analog*>(data().get());
+ dynamic_cast<pv::data::Analog*>(base_->analog_data().get());
connect(analog_data, SIGNAL(min_max_changed(float, float)),
this, SLOT(on_min_max_changed(float, float)));
settings.value(GlobalSettings::Key_View_ConversionThresholdDispMode).toInt();
div_height_ = settings.value(GlobalSettings::Key_View_DefaultDivHeight).toInt();
+ update_logic_level_offsets();
update_scale();
}
-shared_ptr<pv::data::SignalData> AnalogSignal::data() const
-{
- return base_->analog_data();
-}
-
std::map<QString, QVariant> AnalogSignal::save_settings() const
{
+ LogicSignal::save_settings();
+
std::map<QString, QVariant> result;
result["pos_vdivs"] = pos_vdivs_;
result["neg_vdivs"] = neg_vdivs_;
result["scale_index"] = scale_index_;
result["display_type"] = display_type_;
- result["autoranging"] = pos_vdivs_;
+ result["autoranging"] = autoranging_;
result["div_height"] = div_height_;
return result;
void AnalogSignal::restore_settings(std::map<QString, QVariant> settings)
{
+ LogicSignal::restore_settings(settings);
+
auto entry = settings.find("pos_vdivs");
if (entry != settings.end())
pos_vdivs_ = settings["pos_vdivs"].toInt();
const int old_height = div_height_;
div_height_ = settings["div_height"].toInt();
+ update_logic_level_offsets();
+ update_scale();
+
if ((div_height_ != old_height) && owner_) {
// Call order is important, otherwise the lazy event handler won't work
owner_->extents_changed(false, true);
{
const int ph = pos_vdivs_ * div_height_;
const int nh = neg_vdivs_ * div_height_;
+
return make_pair(-ph, nh);
}
}
if ((display_type_ == DisplayConverted) || (display_type_ == DisplayBoth))
- paint_logic_mid(p, pp);
+ if (base_->logic_data())
+ LogicSignal::paint_mid(p, pp);
const QString err = base_->get_error_message();
if (!err.isEmpty())
v_extents().second - v_extents().first - InfoTextMarginBottom);
p.drawText(bounding_rect, Qt::AlignRight | Qt::AlignBottom, infotext);
+
+ if (show_hover_marker_)
+ paint_hover_marker(p);
}
- if (show_hover_marker_)
- paint_hover_marker(p);
+ if ((display_type_ == DisplayConverted) || (display_type_ == DisplayBoth))
+ LogicSignal::paint_fore(p, pp);
}
void AnalogSignal::paint_grid(QPainter &p, int y, int left, int right)
delete[] e.samples;
}
-void AnalogSignal::paint_logic_mid(QPainter &p, ViewItemPaintParams &pp)
-{
- QLineF *line;
-
- vector< pair<int64_t, bool> > edges;
-
- assert(base_);
-
- const int y = get_visual_y();
-
- if (!base_->enabled() || !base_->logic_data())
- return;
-
- const int signal_margin =
- QFontMetrics(QApplication::font()).height() / 2;
-
- const int ph = min(pos_vdivs_, 1) * div_height_;
- const int nh = min(neg_vdivs_, 1) * div_height_;
- const float high_offset = y - ph + signal_margin + 0.5f;
- const float low_offset = y + nh - signal_margin - 0.5f;
- const float signal_height = low_offset - high_offset;
-
- shared_ptr<pv::data::LogicSegment> segment = get_logic_segment_to_paint();
- if (!segment || (segment->get_sample_count() == 0))
- return;
-
- double samplerate = segment->samplerate();
-
- // Show sample rate as 1Hz when it is unknown
- if (samplerate == 0.0)
- samplerate = 1.0;
-
- const double pixels_offset = pp.pixels_offset();
- const pv::util::Timestamp& start_time = segment->start_time();
- const int64_t last_sample = (int64_t)segment->get_sample_count() - 1;
- const double samples_per_pixel = samplerate * pp.scale();
- const double pixels_per_sample = 1 / samples_per_pixel;
- const pv::util::Timestamp start = samplerate * (pp.offset() - start_time);
- const pv::util::Timestamp end = start + samples_per_pixel * pp.width();
-
- const int64_t start_sample = min(max(floor(start).convert_to<int64_t>(),
- (int64_t)0), last_sample);
- const uint64_t end_sample = min(max(ceil(end).convert_to<int64_t>(),
- (int64_t)0), last_sample);
-
- segment->get_subsampled_edges(edges, start_sample, end_sample,
- samples_per_pixel / LogicSignal::Oversampling, 0);
- assert(edges.size() >= 2);
-
- const float first_sample_x =
- pp.left() + (edges.front().first / samples_per_pixel - pixels_offset);
- const float last_sample_x =
- pp.left() + (edges.back().first / samples_per_pixel - pixels_offset);
-
- // Check whether we need to paint the sampling points
- const bool show_sampling_points = show_sampling_points_ && (samples_per_pixel < 0.25);
- vector<QRectF> sampling_points;
- float sampling_point_x = first_sample_x;
- int64_t sampling_point_sample = start_sample;
- const int w = 2;
-
- if (show_sampling_points)
- sampling_points.reserve(end_sample - start_sample + 1);
-
- vector<QRectF> high_rects;
- float rising_edge_x;
- bool rising_edge_seen = false;
-
- // Paint the edges
- const unsigned int edge_count = edges.size() - 2;
- QLineF *const edge_lines = new QLineF[edge_count];
- line = edge_lines;
-
- if (edges.front().second) {
- // Beginning of trace is high
- rising_edge_x = first_sample_x;
- rising_edge_seen = true;
- }
-
- for (auto i = edges.cbegin() + 1; i != edges.cend() - 1; i++) {
- // Note: multiple edges occupying a single pixel are represented by an edge
- // with undefined logic level. This means that only the first falling edge
- // after a rising edge corresponds to said rising edge - and vice versa. If
- // more edges with the same logic level follow, they denote multiple edges.
-
- const float x = pp.left() + ((*i).first / samples_per_pixel - pixels_offset);
- *line++ = QLineF(x, high_offset, x, low_offset);
-
- if (fill_high_areas_) {
- // Any edge terminates a high area
- if (rising_edge_seen) {
- const int width = x - rising_edge_x;
- if (width > 0)
- high_rects.emplace_back(rising_edge_x, high_offset,
- width, signal_height);
- rising_edge_seen = false;
- }
-
- // Only rising edges start high areas
- if ((*i).second) {
- rising_edge_x = x;
- rising_edge_seen = true;
- }
- }
-
- if (show_sampling_points)
- while (sampling_point_sample < (*i).first) {
- const float y = (*i).second ? low_offset : high_offset;
- sampling_points.emplace_back(
- QRectF(sampling_point_x - (w / 2), y - (w / 2), w, w));
- sampling_point_sample++;
- sampling_point_x += pixels_per_sample;
- };
- }
-
- // Calculate the sample points from the last edge to the end of the trace
- if (show_sampling_points)
- while ((uint64_t)sampling_point_sample <= end_sample) {
- // Signal changed after the last edge, so the level is inverted
- const float y = (edges.cend() - 1)->second ? high_offset : low_offset;
- sampling_points.emplace_back(
- QRectF(sampling_point_x - (w / 2), y - (w / 2), w, w));
- sampling_point_sample++;
- sampling_point_x += pixels_per_sample;
- };
-
- if (fill_high_areas_) {
- // Add last high rectangle if the signal is still high at the end of the trace
- if (rising_edge_seen && (edges.cend() - 1)->second)
- high_rects.emplace_back(rising_edge_x, high_offset,
- last_sample_x - rising_edge_x, signal_height);
-
- p.setPen(high_fill_color_);
- p.setBrush(high_fill_color_);
- p.drawRects((const QRectF*)(high_rects.data()), high_rects.size());
- }
-
- p.setPen(LogicSignal::EdgeColor);
- p.drawLines(edge_lines, edge_count);
- delete[] edge_lines;
-
- // Paint the caps
- const unsigned int max_cap_line_count = edges.size();
- QLineF *const cap_lines = new QLineF[max_cap_line_count];
-
- p.setPen(LogicSignal::HighColor);
- paint_logic_caps(p, cap_lines, edges, true, samples_per_pixel,
- pixels_offset, pp.left(), high_offset);
- p.setPen(LogicSignal::LowColor);
- paint_logic_caps(p, cap_lines, edges, false, samples_per_pixel,
- pixels_offset, pp.left(), low_offset);
-
- delete[] cap_lines;
-
- // Paint the sampling points
- if (show_sampling_points) {
- p.setPen(SamplingPointColor);
- p.drawRects(sampling_points.data(), sampling_points.size());
- }
-}
-
-void AnalogSignal::paint_logic_caps(QPainter &p, QLineF *const lines,
- vector< pair<int64_t, bool> > &edges, bool level,
- double samples_per_pixel, double pixels_offset, float x_offset,
- float y_offset)
-{
- QLineF *line = lines;
-
- for (auto i = edges.begin(); i != (edges.end() - 1); i++)
- if ((*i).second == level) {
- *line++ = QLineF(
- ((*i).first / samples_per_pixel -
- pixels_offset) + x_offset, y_offset,
- ((*(i+1)).first / samples_per_pixel -
- pixels_offset) + x_offset, y_offset);
- }
-
- p.drawLines(lines, line - lines);
-}
-
shared_ptr<pv::data::AnalogSegment> AnalogSignal::get_analog_segment_to_paint() const
{
shared_ptr<pv::data::AnalogSegment> segment;
segment = segments.back();
if ((segment_display_mode_ == ShowSingleSegmentOnly) ||
- (segment_display_mode_ == ShowLastCompleteSegmentOnly)) {
+ (segment_display_mode_ == ShowLastCompleteSegmentOnly)) {
try {
segment = segments.at(current_segment_);
} catch (out_of_range&) {
return segment;
}
-shared_ptr<pv::data::LogicSegment> AnalogSignal::get_logic_segment_to_paint() const
-{
- shared_ptr<pv::data::LogicSegment> segment;
-
- const deque< shared_ptr<pv::data::LogicSegment> > &segments =
- base_->logic_data()->logic_segments();
-
- if (!segments.empty()) {
- if (segment_display_mode_ == ShowLastSegmentOnly)
- segment = segments.back();
-
- if ((segment_display_mode_ == ShowSingleSegmentOnly) ||
- (segment_display_mode_ == ShowLastCompleteSegmentOnly)) {
- try {
- segment = segments.at(current_segment_);
- } catch (out_of_range&) {
- qDebug() << "Current logic segment out of range for signal" << base_->name() << ":" << current_segment_;
- }
- }
- }
-
- return segment;
-}
-
float AnalogSignal::get_resolution(int scale_index)
{
const float seq[] = {1.0f, 2.0f, 5.0f};
scale_ = div_height_ / resolution_;
}
+void AnalogSignal::update_logic_level_offsets()
+{
+ const int signal_margin = QFontMetrics(QApplication::font()).height() / 2;
+
+ const int ph = min(pos_vdivs_, 1) * div_height_;
+ const int nh = min(neg_vdivs_, 1) * div_height_;
+
+ high_level_offset_ = -ph + signal_margin + 0.5f;
+ low_level_offset_ = nh - signal_margin - 0.5f;
+}
+
void AnalogSignal::update_conversion_widgets()
{
SignalBase::ConversionType conv_type = base_->get_conversion_type();
}
}
+ const bool showing_logic = (display_type_ == DisplayConverted) || (display_type_ == DisplayBoth);
+
// If there is still no positive div when we need it, add one
// (this can happen when pos_vdivs==neg_vdivs==0)
- if ((max > 0) && (pos_vdivs_ == 0)) {
+ if (((max > 0) && (pos_vdivs_ == 0)) || showing_logic) {
pos_vdivs_ = 1;
owner_->extents_changed(false, true);
}
// If there is still no negative div when we need it, add one
// (this can happen when pos_vdivs was 0 or 1 when trying to split)
- if ((min < 0) && (neg_vdivs_ == 0)) {
+ if (((min < 0) && (neg_vdivs_ == 0)) || showing_logic) {
neg_vdivs_ = 1;
owner_->extents_changed(false, true);
}
pvdiv_sb_ = new QSpinBox(parent);
pvdiv_sb_->setRange(0, MaximumVDivs);
pvdiv_sb_->setValue(pos_vdivs_);
+ pvdiv_sb_->setEnabled(!autoranging_);
connect(pvdiv_sb_, SIGNAL(valueChanged(int)),
this, SLOT(on_pos_vdivs_changed(int)));
form->addRow(tr("Number of pos vertical divs"), pvdiv_sb_);
nvdiv_sb_ = new QSpinBox(parent);
nvdiv_sb_->setRange(0, MaximumVDivs);
nvdiv_sb_->setValue(neg_vdivs_);
+ nvdiv_sb_->setEnabled(!autoranging_);
connect(nvdiv_sb_, SIGNAL(valueChanged(int)),
this, SLOT(on_neg_vdivs_changed(int)));
form->addRow(tr("Number of neg vertical divs"), nvdiv_sb_);
// Add the vertical resolution
resolution_cb_ = new QComboBox(parent);
+ resolution_cb_->setEnabled(!autoranging_);
for (int i = MinScaleIndex; i < MaxScaleIndex; i++) {
const QString label = QString("%1").arg(get_resolution(i));
}
}
+ update_logic_level_offsets();
+
if (owner_) {
// Call order is important, otherwise the lazy event handler won't work
owner_->extents_changed(false, true);
}
}
+ update_logic_level_offsets();
+
if (owner_) {
// Call order is important, otherwise the lazy event handler won't work
owner_->extents_changed(false, true);
void AnalogSignal::on_div_height_changed(int height)
{
div_height_ = height;
+ update_logic_level_offsets();
update_scale();
if (owner_) {
{
autoranging_ = (state == Qt::Checked);
+ if (pvdiv_sb_)
+ pvdiv_sb_->setEnabled(!autoranging_);
+ if (nvdiv_sb_)
+ nvdiv_sb_->setEnabled(!autoranging_);
+ if (resolution_cb_)
+ resolution_cb_->setEnabled(!autoranging_);
+
if (autoranging_)
perform_autoranging(false, true);
base_->set_conversion_type(conv_type);
update_conversion_widgets();
+ if (conv_type == SignalBase::ConversionType::NoConversion)
+ on_display_type_changed(DisplayType::DisplayAnalog);
+ else
+ on_display_type_changed(DisplayType::DisplayBoth);
+
if (owner_)
owner_->row_item_appearance_changed(false, true);
}
// https://txt2re.com/index-c++.php3?s=0.1V&1&-13
QString re1 = "([+-]?\\d*[\\.,]?\\d*)"; // Float value
QString re2 = "([a-zA-Z]*)"; // SI unit
- QRegExp regex(re1 + re2);
-
const QString text = conv_threshold_cb_->currentText();
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ QRegularExpression regex(re1 + re2);
+ if (!regex.match(text).hasMatch())
+ return; // String doesn't match the regex
+
+ QStringList tokens = regex.match(text).capturedTexts();
+#else
+ QRegExp regex(re1 + re2);
if (!regex.exactMatch(text))
return; // String doesn't match the regex
QStringList tokens = regex.capturedTexts();
+#endif
// For now, we simply assume that the unit is volt without modifiers
const double thr = tokens.at(1).toDouble();
QString re3 = "\\/"; // Forward slash, not captured
QString re4 = "([+-]?\\d*[\\.,]?\\d*)"; // Float value
QString re5 = "([a-zA-Z]*)"; // SI unit
+ const QString text = conv_threshold_cb_->currentText();
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ QRegularExpression regex(re1 + re2 + re3 + re4 + re5);
+
+ if (!regex.match(text).hasMatch())
+ return; // String doesn't match the regex
+
+ QStringList tokens = regex.match(text).capturedTexts();
+#else
QRegExp regex(re1 + re2 + re3 + re4 + re5);
- const QString text = conv_threshold_cb_->currentText();
if (!regex.exactMatch(text))
return; // String doesn't match the regex
QStringList tokens = regex.capturedTexts();
+#endif
// For now, we simply assume that the unit is volt without modifiers
const double low_thr = tokens.at(1).toDouble();
void AnalogSignal::on_display_type_changed(int index)
{
+ const bool prev_showing_logic = (display_type_ == DisplayConverted) || (display_type_ == DisplayBoth);
+
display_type_ = (DisplayType)(display_type_cb_->itemData(index).toInt());
+ const bool showing_logic = (display_type_ == DisplayConverted) || (display_type_ == DisplayBoth);
+
+ // If we show a logic trace, make sure we have at least one div for each
+ // polarity as that's where we paint it
+ if (showing_logic && !prev_showing_logic) {
+ if (pos_vdivs_ == 0)
+ on_pos_vdivs_changed(1);
+ if (neg_vdivs_ == 0)
+ on_neg_vdivs_changed(1);
+ }
+
if (owner_)
owner_->row_item_appearance_changed(false, true);
}
#include <QSpinBox>
#include <pv/views/trace/signal.hpp>
+#include <pv/views/trace/logicsignal.hpp>
using std::pair;
using std::shared_ptr;
namespace views {
namespace trace {
-class AnalogSignal : public Signal
+class AnalogSignal : public LogicSignal
{
Q_OBJECT
private:
static const QPen AxisPen;
static const QColor GridMajorColor, GridMinorColor;
- static const QColor SamplingPointColor;
static const QColor SamplingPointColorLo;
static const QColor SamplingPointColorNe;
static const QColor SamplingPointColorHi;
public:
AnalogSignal(pv::Session &session, shared_ptr<data::SignalBase> base);
- shared_ptr<pv::data::SignalData> data() const;
-
virtual std::map<QString, QVariant> save_settings() const;
virtual void restore_settings(std::map<QString, QVariant> settings);
* Computes the vertical extents of the contents of this row item.
* @return A pair containing the minimum and maximum y-values.
*/
- pair<int, int> v_extents() const;
+ virtual pair<int, int> v_extents() const;
/**
* Paints the background layer of the signal with a QPainter
* @param p the QPainter to paint into.
* @param pp the painting parameters object to paint with..
*/
- void paint_back(QPainter &p, ViewItemPaintParams &pp);
+ virtual void paint_back(QPainter &p, ViewItemPaintParams &pp);
/**
* Paints the mid-layer of the signal with a QPainter
* @param p the QPainter to paint into.
* @param pp the painting parameters object to paint with..
*/
- void paint_mid(QPainter &p, ViewItemPaintParams &pp);
+ virtual void paint_mid(QPainter &p, ViewItemPaintParams &pp);
/**
* Paints the foreground layer of the item with a QPainter
* @param p the QPainter to paint into.
* @param pp the painting parameters object to paint with.
*/
- void paint_fore(QPainter &p, ViewItemPaintParams &pp);
+ virtual void paint_fore(QPainter &p, ViewItemPaintParams &pp);
private:
void paint_grid(QPainter &p, int y, int left, int right);
int y, int left, const int64_t start, const int64_t end,
const double pixels_offset, const double samples_per_pixel);
- void paint_logic_mid(QPainter &p, ViewItemPaintParams &pp);
-
- void paint_logic_caps(QPainter &p, QLineF *const lines,
- vector< pair<int64_t, bool> > &edges,
- bool level, double samples_per_pixel, double pixels_offset,
- float x_offset, float y_offset);
-
shared_ptr<pv::data::AnalogSegment> get_analog_segment_to_paint() const;
- shared_ptr<pv::data::LogicSegment> get_logic_segment_to_paint() const;
/**
* Computes the scale factor from the scale index and vdiv settings.
float get_resolution(int scale_index);
void update_scale();
+ virtual void update_logic_level_offsets();
void update_conversion_widgets();
const float x = get_x();
QFontMetrics m(QApplication::font());
- QSize text_size = m.boundingRect(get_text()).size();
+ QSize text_size = m.boundingRect(get_display_text()).size();
const QSizeF label_size(
text_size.width() + LabelPadding.width() * 2,
text_size_ = p.boundingRect(QRectF(), 0, text).size();
+ /* Currently, selecting the middle section between two cursors doesn't do
+ * anything, so don't highlight it when selected
if (selected()) {
p.setBrush(Qt::transparent);
p.setPen(highlight_pen());
p.drawRoundedRect(delta_rect, radius, radius);
- }
+ } */
p.setBrush(hover ? Cursor::FillColor.lighter() : Cursor::FillColor);
p.setPen(Cursor::FillColor.darker());
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-extern "C" {
#include <libsigrokdecode/libsigrokdecode.h>
-}
#include <limits>
#include <mutex>
this, SLOT(on_decode_finished()));
connect(decode_signal_.get(), SIGNAL(channels_updated()),
this, SLOT(on_channels_updated()));
-
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ connect(&delete_mapper_, SIGNAL(mappedInt(int)),
+ this, SLOT(on_delete_decoder(int)));
+ connect(&show_hide_mapper_, SIGNAL(mappedInt(int)),
+ this, SLOT(on_show_hide_decoder(int)));
+ connect(&row_show_hide_mapper_, SIGNAL(mappedInt(int)),
+ this, SLOT(on_show_hide_row(int)));
+ connect(&class_show_hide_mapper_, SIGNAL(mappedObject(QObject*)),
+ this, SLOT(on_show_hide_class(QObject*)));
+#else
connect(&delete_mapper_, SIGNAL(mapped(int)),
this, SLOT(on_delete_decoder(int)));
connect(&show_hide_mapper_, SIGNAL(mapped(int)),
this, SLOT(on_show_hide_row(int)));
connect(&class_show_hide_mapper_, SIGNAL(mapped(QWidget*)),
this, SLOT(on_show_hide_class(QWidget*)));
+#endif
connect(&delayed_trace_updater_, SIGNAL(timeout()),
this, SLOT(on_delayed_trace_update()));
continue;
unsigned int y = get_row_y(&r);
- if ((event->x() > 0) && (event->x() <= (int)(ArrowSize + 3 + r.title_width)) &&
- (event->y() > (int)(y - (default_row_height_ / 2))) &&
- (event->y() <= (int)(y + (default_row_height_ / 2)))) {
-
+ bool need_anim = true;
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ need_anim &= event->position().x() > 0;
+ need_anim &= event->position().x() <= (int)(ArrowSize + 3 + r.title_width);
+ need_anim &= event->position().y() > (int)(y - (default_row_height_ / 2));
+ need_anim &= event->position().y() <= (int)(y + (default_row_height_ / 2));
+#else
+ need_anim &= event->x() > 0;
+ need_anim &= event->x() <= (int)(ArrowSize + 3 + r.title_width);
+ need_anim &= event->y() > (int)(y - (default_row_height_ / 2));
+ need_anim &= event->y() <= (int)(y + (default_row_height_ / 2));
+#endif
+ if (need_anim) {
if (r.expanded) {
r.collapsing = true;
r.expanded = false;
QPalette header_palette = owner_->view()->palette();
QPalette selector_palette = owner_->view()->palette();
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
+ if (GlobalSettings::current_theme_is_dark()) {
+ header_palette.setColor(QPalette::Window,
+ QColor(255, 255, 255, ExpansionAreaHeaderAlpha));
+ selector_palette.setColor(QPalette::Window,
+ QColor(255, 255, 255, ExpansionAreaAlpha));
+ } else {
+ header_palette.setColor(QPalette::Window,
+ QColor(0, 0, 0, ExpansionAreaHeaderAlpha));
+ selector_palette.setColor(QPalette::Window,
+ QColor(0, 0, 0, ExpansionAreaAlpha));
+ }
+#else
if (GlobalSettings::current_theme_is_dark()) {
header_palette.setColor(QPalette::Background,
QColor(255, 255, 255, ExpansionAreaHeaderAlpha));
selector_palette.setColor(QPalette::Background,
QColor(0, 0, 0, ExpansionAreaAlpha));
}
+#endif
const int w = m.boundingRect(r->decode_row->title()).width() + RowTitleMargin;
r->title_width = w;
owner_->row_item_appearance_changed(false, true);
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+void DecodeTrace::on_show_hide_class(QObject* sender)
+#else
void DecodeTrace::on_show_hide_class(QWidget* sender)
+#endif
{
void* ann_class_ptr = sender->property("ann_class_ptr").value<void*>();
assert(ann_class_ptr);
void on_show_hide_decoder(int index);
void on_show_hide_row(int row_id);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ void on_show_hide_class(QObject* sender);
+#else
void on_show_hide_class(QWidget* sender);
+#endif
void on_show_all_classes();
void on_hide_all_classes();
void on_row_container_resized(QWidget* sender);
return true;
}
-QString Flag::get_text() const
+/**
+ * Returns the text used to display this flag item. This is not necessarily the
+ * name that the user has given it.
+ */
+QString Flag::get_display_text() const
{
QString s;
return s;
}
+/**
+ * Returns the text of this flag item, i.e. the user-editable name.
+ */
+QString Flag::get_text() const
+{
+ return text_;
+}
+
void Flag::set_text(const QString &text)
{
text_ = text;
const float x = get_x();
QFontMetrics m(QApplication::font());
- QSize text_size = m.boundingRect(get_text()).size();
+ QSize text_size = m.boundingRect(get_display_text()).size();
const QSizeF label_size(
text_size.width() + LabelPadding.width() * 2,
virtual bool enabled() const override;
/**
- * Gets the text to show in the marker.
+ * Gets the current text to show in the marker - this may be dynamic.
+ */
+ virtual QString get_display_text() const override;
+
+ /**
+ * Gets the default text used to show the marker - e.g. the user-editable
+ * name.
*/
virtual QString get_text() const override;
QCache<QString, const QIcon> LogicSignal::icon_cache_;
QCache<QString, const QPixmap> LogicSignal::pixmap_cache_;
-LogicSignal::LogicSignal(
- pv::Session &session,
- shared_ptr<devices::Device> device,
- shared_ptr<data::SignalBase> base) :
+LogicSignal::LogicSignal(pv::Session &session, shared_ptr<data::SignalBase> base) :
Signal(session, base),
- device_(device),
trigger_types_(get_trigger_types()),
trigger_none_(nullptr),
trigger_rising_(nullptr),
trigger_low_(nullptr),
trigger_change_(nullptr)
{
- shared_ptr<Trigger> trigger;
-
GlobalSettings settings;
signal_height_ = settings.value(GlobalSettings::Key_View_DefaultLogicHeight).toInt();
show_sampling_points_ =
high_fill_color_ = QColor::fromRgba(settings.value(
GlobalSettings::Key_View_FillSignalHighAreaColor).value<uint32_t>());
+ update_logic_level_offsets();
+
/* Populate this channel's trigger setting with whatever we
* find in the current session trigger, if anything. */
trigger_match_ = nullptr;
- if ((trigger = session_.session()->trigger()))
+ if (shared_ptr<Trigger> trigger = session_.session()->trigger())
for (auto stage : trigger->stages())
for (auto match : stage->matches())
if (match->channel() == base_->channel())
trigger_match_ = match->type();
}
-shared_ptr<pv::data::SignalData> LogicSignal::data() const
-{
- return base_->logic_data();
-}
-
-shared_ptr<pv::data::Logic> LogicSignal::logic_data() const
-{
- return base_->logic_data();
-}
-
std::map<QString, QVariant> LogicSignal::save_settings() const
{
std::map<QString, QVariant> result;
signal_height_ = settings["trace_height"].toInt();
if ((signal_height_ != old_height) && owner_) {
+ update_logic_level_offsets();
+
// Call order is important, otherwise the lazy event handler won't work
owner_->extents_changed(false, true);
owner_->row_item_appearance_changed(false, true);
if (!base_->enabled())
return;
- const float low_offset = y + 0.5f;
- const float high_offset = low_offset - signal_height_;
+ const float low_offset = y + low_level_offset_;
+ const float high_offset = y + high_level_offset_;
+ const float fill_height = low_offset - high_offset;
shared_ptr<LogicSegment> segment = get_logic_segment_to_paint();
if (!segment || (segment->get_sample_count() == 0))
(int64_t)0), last_sample);
segment->get_subsampled_edges(edges, start_sample, end_sample,
- samples_per_pixel / Oversampling, base_->index());
+ samples_per_pixel / Oversampling, base_->logic_bit_index());
assert(edges.size() >= 2);
const float first_sample_x =
if (rising_edge_seen) {
const int width = x - rising_edge_x;
if (width > 0)
- high_rects.emplace_back(rising_edge_x, high_offset,
- width, signal_height_);
+ high_rects.emplace_back(rising_edge_x, high_offset, width, fill_height);
rising_edge_seen = false;
}
base_->logic_data()->logic_segments();
if (!segments.empty()) {
- if (segment_display_mode_ == ShowLastSegmentOnly) {
+ if (segment_display_mode_ == ShowLastSegmentOnly)
segment = segments.back();
- }
- if ((segment_display_mode_ == ShowSingleSegmentOnly) ||
- (segment_display_mode_ == ShowLastCompleteSegmentOnly)) {
+ if ((segment_display_mode_ == ShowSingleSegmentOnly) ||
+ (segment_display_mode_ == ShowLastCompleteSegmentOnly)) {
try {
segment = segments.at(current_segment_);
} catch (out_of_range&) {
const vector<int32_t> LogicSignal::get_trigger_types() const
{
// We may not be associated with a device
- if (!device_)
+ if (!session_.device())
return vector<int32_t>();
- const auto sr_dev = device_->device();
+ const auto sr_dev = session_.device()->device();
if (sr_dev->config_check(ConfigKey::TRIGGER_MATCH, Capability::LIST)) {
const Glib::VariantContainerBase gvar =
sr_dev->config_list(ConfigKey::TRIGGER_MATCH);
return pixmap_cache_.take(path);
}
+void LogicSignal::update_logic_level_offsets()
+{
+ low_level_offset_ = 0.5f;
+ high_level_offset_ = low_level_offset_ - signal_height_;
+}
+
void LogicSignal::on_setting_changed(const QString &key, const QVariant &value)
{
Signal::on_setting_changed(key, value);
signal_height_ = height;
if (owner_) {
+ update_logic_level_offsets();
+
// Call order is important, otherwise the lazy event handler won't work
owner_->extents_changed(false, true);
owner_->row_item_appearance_changed(false, true);
static const int TriggerMarkerPadding;
static const char* TriggerMarkerIcons[8];
- LogicSignal(pv::Session &session,
- shared_ptr<devices::Device> device,
- shared_ptr<data::SignalBase> base);
+ LogicSignal(pv::Session &session, shared_ptr<data::SignalBase> base);
virtual ~LogicSignal() = default;
- shared_ptr<pv::data::SignalData> data() const;
-
- shared_ptr<pv::data::Logic> logic_data() const;
-
virtual std::map<QString, QVariant> save_settings() const;
virtual void restore_settings(std::map<QString, QVariant> settings);
* Computes the vertical extents of the contents of this row item.
* @return A pair containing the minimum and maximum y-values.
*/
- pair<int, int> v_extents() const;
+ virtual pair<int, int> v_extents() const;
/**
* Paints the mid-layer of the signal with a QPainter
* @param p the QPainter to paint into.
* @param pp the painting parameters object to paint with..
*/
- void paint_mid(QPainter &p, ViewItemPaintParams &pp);
+ virtual void paint_mid(QPainter &p, ViewItemPaintParams &pp);
/**
* Paints the foreground layer of the signal with a QPainter
*/
virtual vector<data::LogicSegment::EdgePair> get_nearest_level_changes(uint64_t sample_pos);
-private:
+protected:
void paint_caps(QPainter &p, QLineF *const lines,
vector< pair<int64_t, bool> > &edges,
bool level, double samples_per_pixel, double pixels_offset,
static const QIcon* get_icon(const char *path);
static const QPixmap* get_pixmap(const char *path);
-private Q_SLOTS:
+ virtual void update_logic_level_offsets();
+
+protected Q_SLOTS:
void on_setting_changed(const QString &key, const QVariant &value);
void on_trigger();
void on_signal_height_changed(int height);
-private:
+protected:
QColor high_fill_color_;
bool show_sampling_points_, fill_high_areas_;
-
- shared_ptr<pv::devices::Device> device_;
+ float high_level_offset_, low_level_offset_; // y offsets relative to trace
QSpinBox *signal_height_sb_;
{
pv::widgets::Popup *const p = item->create_popup(this);
- connect(p, SIGNAL(closed()), this, SLOT(on_popup_closed()));
-
- if (p)
+ if (p) {
+ connect(p, SIGNAL(closed()), this, SLOT(on_popup_closed()));
p->show();
+ }
}
void MarginWidget::contextMenuEvent(QContextMenuEvent *event)
root_layout->addWidget(button_box);
// Set tab width to 4 characters
+#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
+ expr_edit_->setTabStopDistance(util::text_width(QFontMetrics(font()), "XXXX"));
+#else
expr_edit_->setTabStopWidth(util::text_width(QFontMetrics(font()), "XXXX"));
+#endif
connect(button_box, SIGNAL(accepted()), this, SLOT(accept()));
connect(button_box, SIGNAL(rejected()), this, SLOT(reject()));
void Ruler::mouseDoubleClickEvent(QMouseEvent *event)
{
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ hover_item_ = view_.add_flag(get_absolute_time_from_x_pos(event->pos().x()));
+#else
hover_item_ = view_.add_flag(get_absolute_time_from_x_pos(event->x()));
+#endif
}
void Ruler::paintEvent(QPaintEvent*)
"TX",
"RX",
"SDA",
- "SCL"
+ "SCL",
"SCLK",
"MOSI",
"MISO",
void Signal::on_disable()
{
+ // For generated signals, "disable" means "remove"
if (base_->is_generated())
session_.remove_generated_signal(base_);
else
*/
virtual void set_name(QString name);
- virtual shared_ptr<pv::data::SignalData> data() const = 0;
-
/**
* Determines the closest level change (i.e. edge) to a given sample, which
* is useful for e.g. the "snap to edge" functionality.
{
QFontMetrics m(QApplication::font());
const QSizeF text_size(
- max(m.boundingRect(get_text()).size().width(), ArrowSize),
+ max(m.boundingRect(get_display_text()).size().width(), ArrowSize),
m.height());
const QSizeF label_size(text_size + LabelPadding * 2);
const float top = rect.height() - label_size.height() -
return QRectF(x - h / 2.0f, pp.top(), h, pp.height());
}
+QString TimeMarker::get_display_text() const
+{
+ return get_text();
+}
+
void TimeMarker::set_text(const QString &text)
{
(void)text;
p.drawPolygon(points, countof(points));
p.setPen(select_text_color(color_));
- p.drawText(r, Qt::AlignCenter | Qt::AlignVCenter, get_text());
+ p.drawText(r, Qt::AlignCenter | Qt::AlignVCenter, get_display_text());
}
void TimeMarker::paint_fore(QPainter &p, ViewItemPaintParams &pp)
popup->set_position(parent->mapToGlobal(
drag_point(parent->rect())), Popup::Bottom);
+ connect(popup, SIGNAL(closed()), this, SLOT(on_popup_closed()));
+
QFormLayout *const form = new QFormLayout(popup);
popup->setLayout(form);
return popup;
}
+void TimeMarker::on_popup_closed()
+{
+ GlobalSettings settings;
+ if (!settings.value(GlobalSettings::Key_View_KeepRulerItemSelected).toBool())
+ select(false);
+}
+
void TimeMarker::on_value_changed(const pv::util::Timestamp& value)
{
set_time(view_.ruler()->get_absolute_time_from_ruler_time(value));
QRectF hit_box_rect(const ViewItemPaintParams &pp) const override;
/**
- * Gets the text to show in the marker.
+ * Gets the current text to show in the marker - this may be dynamic.
+ */
+ virtual QString get_display_text() const;
+
+ /**
+ * Gets the default text used to show the marker - e.g. the user-editable
+ * name.
*/
virtual QString get_text() const = 0;
virtual pv::widgets::Popup* create_popup(QWidget *parent) override;
private Q_SLOTS:
+ void on_popup_closed();
+
void on_value_changed(const pv::util::Timestamp& value);
protected:
void Trace::on_nameedit_changed(const QString &name)
{
/* This event handler notifies SignalBase that the name changed */
- base_->set_name(name);
+ if (!name.isEmpty())
+ base_->set_name(name);
}
void Trace::on_coloredit_changed(const QColor &color)
QMenu *const menu = new QMenu(parent);
QAction *const ungroup = new QAction(tr("Ungroup"), this);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ ungroup->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_U));
+#else
ungroup->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_U));
+#endif
connect(ungroup, SIGNAL(triggered()), this, SLOT(on_ungroup()));
menu->addAction(ungroup);
namespace trace {
const Timestamp View::MaxScale("1e9");
-const Timestamp View::MinScale("1e-12");
+const Timestamp View::MinScale("1e-14");
const int View::MaxScrollValue = INT_MAX / 2;
switch (signalbase->type()) {
case SignalBase::LogicChannel:
- signal = shared_ptr<Signal>(new LogicSignal(session_, session_.device(), signalbase));
+ signal = shared_ptr<Signal>(new LogicSignal(session_, signalbase));
break;
case SignalBase::AnalogChannel:
vector< shared_ptr<SignalData> > visible_data;
for (const shared_ptr<Signal>& sig : signals_)
if (sig->enabled())
- visible_data.push_back(sig->data());
+ visible_data.push_back(sig->base()->data());
return visible_data;
}
if (signals_.size() == 0)
return make_pair(0, 0);
- for (shared_ptr<Signal> s : signals_)
- if (s->data() && (s->data()->segments().size() > 0))
- data.push_back(s->data());
+ for (const shared_ptr<Signal>& s : signals_)
+ if (s->base()->data() && (s->base()->data()->segments().size() > 0))
+ data.push_back(s->base()->data());
for (const shared_ptr<SignalData>& d : data) {
const vector< shared_ptr<Segment> > segments = d->segments();
if (time_unit_ == util::TimeUnit::Samples) {
// Check all signals but...
for (const shared_ptr<Signal>& signal : signals_) {
- const shared_ptr<SignalData> data = signal->data();
+ const shared_ptr<SignalData> data = signal->base()->data();
// ...only check first segment of each
const vector< shared_ptr<Segment> > segments = data->segments();
else if (object == ruler_)
hover_point_ = mouse_event->pos();
else if (object == header_)
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ hover_point_ = QPoint(0, mouse_event->pos().y());
+#else
hover_point_ = QPoint(0, mouse_event->y());
+#endif
else
hover_point_ = QPoint(-1, -1);
QPoint pos = event->pos() - QPoint(0, ruler_->sizeHint().height());
const shared_ptr<ViewItem> r = viewport_->get_mouse_over_item(pos);
- if (!r)
- return;
- QMenu *menu = r->create_view_context_menu(this, pos);
+ QMenu* menu = nullptr;
+
+ if (!r) {
+ context_menu_x_pos_ = pos.x();
+
+ // No view item under cursor, use generic menu
+ menu = new QMenu(this);
+
+ QAction *const create_marker_here = new QAction(tr("Create marker here"), this);
+ connect(create_marker_here, SIGNAL(triggered()), this, SLOT(on_create_marker_here()));
+ menu->addAction(create_marker_here);
+ } else {
+ menu = r->create_view_context_menu(this, pos);
+ }
+
if (menu)
menu->popup(event->globalPos());
}
}
}
+void View::on_create_marker_here()
+{
+ const QPoint p = ruler_->mapFrom(this, QPoint(context_menu_x_pos_, 0));
+
+ add_flag(ruler_->get_absolute_time_from_x_pos(p.x()));
+}
+
void View::on_settingViewTriggerIsZeroTime_changed(const QVariant new_value)
{
(void)new_value;
void on_settingViewTriggerIsZeroTime_changed(const QVariant new_value);
+ void on_create_marker_here();
+
virtual void perform_delayed_view_update();
void process_sticky_events();
// These are used to determine whether the view was altered after acq started
double scale_at_acq_start_;
pv::util::Timestamp offset_at_acq_start_;
+
+ // X coordinate of mouse cursor where the user clicked to open a context menu
+ uint32_t context_menu_x_pos_;
};
} // namespace trace
{
setAutoFillBackground(true);
setBackgroundRole(QPalette::Base);
+
+ // Set up settings and event handlers
+ GlobalSettings settings;
+ allow_vertical_dragging_ = settings.value(GlobalSettings::Key_View_AllowVerticalDragging).toBool();
+
+ GlobalSettings::add_change_handler(this);
+}
+
+Viewport::~Viewport()
+{
+ GlobalSettings::remove_change_handler(this);
}
shared_ptr<ViewItem> Viewport::get_mouse_over_item(const QPoint &pt)
void Viewport::drag()
{
drag_offset_ = view_.offset();
- drag_v_offset_ = view_.owner_visual_v_offset();
+
+ if (allow_vertical_dragging_)
+ drag_v_offset_ = view_.owner_visual_v_offset();
}
void Viewport::drag_by(const QPoint &delta)
view_.set_scale_offset(view_.scale(),
(*drag_offset_ - delta.x() * view_.scale()));
- view_.set_v_offset(-drag_v_offset_ - delta.y());
+ if (allow_vertical_dragging_)
+ view_.set_v_offset(-drag_v_offset_ - delta.y());
}
void Viewport::drag_release()
bool Viewport::touch_event(QTouchEvent *event)
{
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ QList<QEventPoint> touchPoints = event->points();
+#else
QList<QTouchEvent::TouchPoint> touchPoints = event->touchPoints();
+#endif
if (touchPoints.count() != 2) {
pinch_zoom_active_ = false;
return false;
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ if (event->device()->type() == QInputDevice::DeviceType::TouchPad) {
+ return false;
+ }
+
+ const QEventPoint &touchPoint0 = touchPoints.first();
+ const QEventPoint &touchPoint1 = touchPoints.last();
+
+ if (!pinch_zoom_active_ ||
+ (event->touchPointStates() & QEventPoint::Pressed)) {
+ pinch_offset0_ = (view_.offset() + view_.scale() * touchPoint0.position().x()).convert_to<double>();
+ pinch_offset1_ = (view_.offset() + view_.scale() * touchPoint1.position().x()).convert_to<double>();
+ pinch_zoom_active_ = true;
+ }
+
+ double w = touchPoint1.position().x() - touchPoint0.position().x();
+ if (abs(w) >= 1.0) {
+ const double scale =
+ fabs((pinch_offset1_ - pinch_offset0_) / w);
+ double offset = pinch_offset0_ - touchPoint0.position().x() * scale;
+ if (scale > 0)
+ view_.set_scale_offset(scale, offset);
+ }
+#else
if (event->device()->type() == QTouchDevice::TouchPad) {
return false;
}
if (scale > 0)
view_.set_scale_offset(scale, offset);
}
+#endif
if (event->touchPointStates() & Qt::TouchPointReleased) {
pinch_zoom_active_ = false;
} else {
// Update the mouse down fields so that continued
// dragging with the primary touch will work correctly
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ mouse_down_point_ = touchPoint0.position().toPoint();
+#else
mouse_down_point_ = touchPoint0.pos().toPoint();
+#endif
drag();
}
}
{
assert(event);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ if (event->buttons() & Qt::LeftButton)
+ view_.zoom(2.0, event->position().x());
+ else if (event->buttons() & Qt::RightButton)
+ view_.zoom(-2.0, event->position().x());
+#else
if (event->buttons() & Qt::LeftButton)
view_.zoom(2.0, event->x());
else if (event->buttons() & Qt::RightButton)
view_.zoom(-2.0, event->x());
+#endif
}
void Viewport::wheelEvent(QWheelEvent *event)
{
assert(event);
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
+ int delta = (event->angleDelta().x() != 0) ? event->angleDelta().x() : event->angleDelta().y();
+#else
+ int delta = event->delta();
+#endif
+
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
+ if (event->angleDelta().y() != 0) {
+#else
if (event->orientation() == Qt::Vertical) {
+#endif
if (event->modifiers() & Qt::ControlModifier) {
// Vertical scrolling with the control key pressed
// is intrepretted as vertical scrolling
view_.set_v_offset(-view_.owner_visual_v_offset() -
- (event->delta() * height()) / (8 * 120));
+ (delta * height()) / (8 * 120));
+ } else if (event->modifiers() & Qt::ShiftModifier) {
+ // Vertical scrolling with the shift key pressed
+ // acts as horizontal scrolling like in Gimp
+ // and Inkscape.
+ view_.set_scale_offset(view_.scale(),
+ - delta * view_.scale() + view_.offset());
} else {
// Vertical scrolling is interpreted as zooming in/out
- view_.zoom(event->delta() / 120.0, event->x());
+#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
+ view_.zoom(delta / 120.0, event->position().x());
+#else
+ view_.zoom(delta / 120.0, event->x());
+#endif
}
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
+ } else if (event->angleDelta().x() != 0) {
+#else
} else if (event->orientation() == Qt::Horizontal) {
+#endif
// Horizontal scrolling is interpreted as moving left/right
view_.set_scale_offset(view_.scale(),
- event->delta() * view_.scale() + view_.offset());
+ delta * view_.scale() + view_.offset());
}
}
+void Viewport::on_setting_changed(const QString &key, const QVariant &value)
+{
+ if (key == GlobalSettings::Key_View_AllowVerticalDragging)
+ allow_vertical_dragging_ = value.toBool();
+}
+
} // namespace trace
} // namespace views
} // namespace pv
#include <QTimer>
#include <QTouchEvent>
+#include <pv/globalsettings.hpp>
+
#include "pv/util.hpp"
#include "viewwidget.hpp"
class View;
-class Viewport : public ViewWidget
+class Viewport : public ViewWidget, public GlobalSettingsInterface
{
Q_OBJECT
public:
explicit Viewport(View &parent);
+ ~Viewport();
/**
* Gets the first view item which has a hit-box that contains @c pt .
*/
bool touch_event(QTouchEvent *event);
-private:
void paintEvent(QPaintEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
+
void wheelEvent(QWheelEvent *event);
+ void on_setting_changed(const QString &key, const QVariant &value);
+
private:
boost::optional<pv::util::Timestamp> drag_offset_;
int drag_v_offset_;
+ bool allow_vertical_dragging_;
double pinch_offset0_;
double pinch_offset1_;
vector< shared_ptr<data::SignalBase> > signalbases() const;
virtual void clear_signalbases();
-
virtual void add_signalbase(const shared_ptr<data::SignalBase> signalbase);
virtual void remove_signalbase(const shared_ptr<data::SignalBase> signalbase);
#ifdef ENABLE_DECODE
virtual void clear_decode_signals();
-
virtual void add_decode_signal(shared_ptr<data::DecodeSignal> signal);
-
virtual void remove_decode_signal(shared_ptr<data::DecodeSignal> signal);
#endif
}
g_slist_free(li);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ connect(&mapper_, SIGNAL(mappedObject(QObject*)), this, SLOT(on_action(QObject*)));
+#else
connect(&mapper_, SIGNAL(mapped(QObject*)), this, SLOT(on_action(QObject*)));
+#endif
}
int DecoderMenu::decoder_name_cmp(const void *a, const void *b)
setDefaultAction(connect_action_);
setMinimumWidth(QFontMetrics(font()).averageCharWidth() * 24);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ connect(&mapper_, SIGNAL(mappedObject(QObject*)),
+ this, SLOT(on_action(QObject*)));
+#else
connect(&mapper_, SIGNAL(mapped(QObject*)),
this, SLOT(on_action(QObject*)));
+#endif
connect(&menu_, SIGNAL(hovered(QAction*)),
this, SLOT(on_menu_hovered(QAction*)));
connect(action, SIGNAL(triggered()), &mapper_, SLOT(map()));
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ connect(&mapper_, SIGNAL(mappedObject(QObject*)),
+ this, SLOT(on_action(QObject*)));
+#else
connect(&mapper_, SIGNAL(mapped(QObject*)),
this, SLOT(on_action(QObject*)));
+#endif
}
void ExportMenu::on_action(QObject *action)
size.setHeight(h);
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ int left, top, right, bottom;
+ getContentsMargins(&left, &top, &right, &bottom);
+ size += QSize(left + right, top + bottom);
+#else
size += QSize(2 * margin(), 2 * margin());
+#endif
return size;
}
connect(action, SIGNAL(triggered()), &mapper_, SLOT(map()));
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ connect(&mapper_, SIGNAL(mappedObject(QObject*)),
+ this, SLOT(on_action(QObject*)));
+#else
connect(&mapper_, SIGNAL(mapped(QObject*)),
this, SLOT(on_action(QObject*)));
+#endif
}
void ImportMenu::on_action(QObject *action)
#include <cassert>
#include <QApplication>
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+#include <QScreen>
+#else
#include <QDesktopWidget>
+#endif
#include <QLineEdit>
#include <QScrollBar>
#include <QStyle>
{
QPoint o;
+#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
+ const QRect screen_rect = QApplication::screenAt(point_)->availableGeometry();
+#else
const QRect screen_rect = QApplication::desktop()->availableGeometry(
QApplication::desktop()->screenNumber(point_));
+#endif
if (pos_ == Right || pos_ == Left)
o.ry() = -height() / 2;
this, SIGNAL(value_changed()));
setLayout(&layout_);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ layout_.setContentsMargins(0, 0, 0, 0);
+#else
layout_.setMargin(0);
+#endif
layout_.addWidget(&list_);
layout_.addWidget(&value_);
#include "timestampspinbox.hpp"
#include <QLineEdit>
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+#include <QRegularExpression>
+#else
#include <QRegExp>
+#endif
namespace pv {
namespace widgets {
void TimestampSpinBox::on_editingFinished()
{
- QRegExp re(R"(\s*([-+]?)\s*([0-9]+\.?[0-9]*).*)");
+ static const auto re_pattern = R"(\s*([-+]?)\s*([0-9]+\.?[0-9]*).*)";
+
+ bool has_match;
+ QStringList captures;
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ QRegularExpression re(re_pattern);
+ has_match = re.match(text()).hasMatch();
+ if (has_match) {
+ captures = re.match(text()).capturedTexts();
+ }
+#else
+ QRegExp re(re_pattern);
+ has_match = re.exactMatch(text());
+ if (has_match) {
+ captures = re.capturedTexts();
+ }
+#endif
- if (re.exactMatch(text())) {
- QStringList captures = re.capturedTexts();
+ if (has_match) {
captures.removeFirst(); // remove entire match
QString str = captures.join("");
setValue(pv::util::Timestamp(str.toStdString()));
<qresource prefix="/">
<file>l10n/de.qm</file>
<file>l10n/es_MX.qm</file>
+ <file>l10n/ja_jp.qm</file>
+ <file>l10n/zh_cn.qm</file>
</qresource>
</RCC>