73 Commits

Author SHA1 Message Date
75c6b5abcc fix QCodeEdit code complete popup size 2020-09-04 18:06:52 +03:00
235eb2acb8 remove graphic expand buttons, update pip 2020-08-31 18:35:32 +03:00
bd5579b8f1 qrc refactoring 2020-08-27 14:29:02 +03:00
7f820c8f67 new Graphic feature - floatingAxisType: Free, TraceX/Y
qpicalculator moved to PIEvaluator
2020-08-26 23:44:50 +03:00
9130496887 restore my error 2020-08-25 22:38:34 +03:00
cca2e0f2d7 moved qpicalculator 2020-08-25 22:29:59 +03:00
b92a1fa558 moved to shstk 2020-08-25 22:24:02 +03:00
d4f1c78a6e pip 2020-08-24 13:23:50 +03:00
274fb20103 microchange 2020-08-22 01:04:46 +03:00
acef4db1db QAD and PIQt overall messages (as at recent PIP) 2020-08-22 00:58:46 +03:00
9f84e5c3df new "qt_generate_export_header" macro 2020-08-21 22:13:06 +03:00
aa009c36b0 work with QGL* 2020-08-21 20:16:02 +03:00
e4340a7215 qglengine/CMakeLists.txt fix 2020-08-20 13:25:37 +03:00
f7eabd1a85 export headers for QAD, PIQt and cd_utils 2020-08-19 22:42:37 +03:00
3ca32f4972 Merge branch 'master' of https://git.shs.tools/SHS/libs 2020-08-19 19:55:42 +03:00
68512b6c08 move qpiconnection 2020-08-19 19:55:32 +03:00
5d32c02b5f forget cd_utils
fixed dangling piconnedit
2020-08-19 17:27:22 +03:00
d0148bf460 tree changes 2020-08-19 16:22:10 +03:00
76d9604282 missing CMakeLists.txt on previous commit 2020-08-19 00:48:38 +03:00
3e1768b418 tree changes 2020-08-19 00:47:44 +03:00
4b7c513f7f flags() 2020-08-18 17:03:13 +03:00
0f6bc121aa ImageView fix 2020-08-18 17:02:14 +03:00
0ec173d9bb improve ImageView quality 2020-08-18 16:59:58 +03:00
cabacdd908 BlockView trace fix 2020-08-17 12:10:13 +03:00
f66138593c BlockView tracing fix 2020-08-17 00:57:44 +03:00
c49454bb03 another version of tracing across buses 2020-08-17 00:32:59 +03:00
efb5cbe484 blockview migrate to "deploy*" 2020-08-16 16:36:46 +03:00
ddc4da54be pip
BlockBusItem paint fix
2020-08-14 18:00:58 +03:00
d6cc5f0033 QAD 1.7.0
backport PIChunkStream optimizations to ChunkStream
2020-08-14 14:18:20 +03:00
055b8a9480 bus joint paint now configured with BlockView::setBusSquareNodes(), square or round. By default round 2020-08-14 14:08:31 +03:00
8fbed9f427 revert busitem paint 2020-08-13 18:09:04 +03:00
e43ae02e48 Merge branch 'master' of https://git.signalmodelling.ru/SHS/libs 2020-08-13 18:04:02 +03:00
a9b9061475 binlog and PathEdit fixes 2020-08-13 18:03:52 +03:00
b37318a5a5 BlockView draw bus joint changed 2020-08-13 14:13:23 +03:00
6f97d849e9 Merge branch 'master' of https://git.shs.tools/SHS/libs 2020-08-13 13:00:59 +03:00
58432fa62e version 1.6.0
QAD::File add "is_save" flag
2020-08-13 13:00:52 +03:00
aa2ea1eda6 binlog user header 2020-08-12 20:01:46 +03:00
11e665c419 pip 2020-08-11 21:19:02 +03:00
1312f950c7 pip 2020-08-11 20:59:25 +03:00
56b3dcad7c Merge remote-tracking branch 'remotes/origin/release' 2020-08-11 20:20:24 +03:00
75464792ba Merge remote-tracking branch 'remotes/origin/master' into release
Some checks failed
SHS Gitea/libs/pipeline/head There was a failure building this commit
2020-08-11 20:16:10 +03:00
8b86f93e38 pip 2.0.0 2020-08-11 20:11:10 +03:00
3e0ec72e7d Blockview changes:
1) Теперь для создания сегмента не надо держать Shift, а перемешение шины теперь с нажатой клавишей Shift
2) Режим трассировки шин теперь пытается проложить маршрут с возможностью пересечения шины под прямым углом
3) Теперь рисуются точки соединения сегментов если их больше 2х
4) Обновлена подсказка в tooltip

p.s. update pip)
2020-08-11 17:35:18 +03:00
b45bfca826 getSaveFileName for QAD::File editor 2020-08-11 10:15:09 +03:00
6a9b1751ac android docker
All checks were successful
SHS Gitea/libs/pipeline/head This commit looks good
2020-08-10 22:13:31 +03:00
ede780249a android docker 2020-08-10 22:12:52 +03:00
067839f02b Dockerfile ENV patch
All checks were successful
SHS Gitea/libs/pipeline/head This commit looks good
2020-08-10 17:55:07 +03:00
da9237e74b Dockerfile ENV patch 2020-08-10 17:48:35 +03:00
905eb77091 windows PIP -> QtBin install fix 2020-08-05 12:06:56 +03:00
2974967790 TouchButtFrame fix 2020-08-04 17:57:11 +03:00
4a567dbba4 pip 2020-08-03 09:05:06 +03:00
0c7619d00b new pip 2020-08-03 01:43:47 +03:00
fa4634b0c7 last pip 2020-08-02 12:16:14 +03:00
0f1825bf33 merged to PIP 1.99.3 2020-08-01 21:30:25 +03:00
562cb280f7 Merge branch 'master' of https://git.shs.tools/SHS/libs 2020-07-30 00:25:33 +03:00
5ec9c22d46 pip 2020-07-30 00:25:24 +03:00
d78a1f532b Merge branch 'master' of https://git.signalmodelling.ru/SHS/libs 2020-07-29 14:36:30 +03:00
0d9ecc9ceb Dockerfile, clone only one branch 2020-07-29 14:36:21 +03:00
7baa7916f7 pip v2 2020-07-29 01:32:19 +03:00
7ecf33a908 Merge branch 'master' of https://git.shs.tools/SHS/libs 2020-07-24 21:54:44 +03:00
c3f921ea6a FindQAD.cmake patch for piqt and piqt_utils 2020-07-24 21:54:38 +03:00
2251caf12c clean qglengine/qglview.h 2020-07-23 17:14:22 +03:00
c76608abf0 QGLEngine license 2020-07-22 11:24:42 +03:00
06c99dd105 Merge pull request 'pip' (#55) from master into release
Some checks failed
SHS Gitea/libs/pipeline/head There was a failure building this commit
2020-07-16 13:59:20 +03:00
caf149ed28 pip 2020-07-16 13:59:07 +03:00
13a543bfd5 Merge pull request 'pip 24' (#54) from master into release
Some checks failed
SHS Gitea/libs/pipeline/head There was a failure building this commit
2020-07-16 13:51:49 +03:00
16e52701be pip 2020-07-16 13:44:26 +03:00
09ed9a9907 compile fixes 2020-07-16 13:41:50 +03:00
a5d75fec09 includes 2020-07-16 13:05:49 +03:00
afd15e20f6 fix warning 2020-07-16 12:58:31 +03:00
77c2296320 pip 24 2020-07-16 12:52:59 +03:00
1c8d2d5c5f Merge branch 'master' of https://git.signalmodelling.ru/SHS/libs 2020-07-16 12:50:49 +03:00
f6a9e44805 piSwap 2020-07-16 12:50:24 +03:00
747 changed files with 21132 additions and 22058 deletions

View File

@@ -9,18 +9,84 @@ project(libs)
set(PIP_CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/pip/cmake")
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" "${PIP_CMAKE_MODULE_PATH}" "${CMAKE_CURRENT_SOURCE_DIR}/qad/cmake")
set(LIBPROJECT 1)
set(_qt_libs )
set(_qt_apps )
set(_qt_plugs)
include(GenerateExportHeader)
include(SDKMacros)
include(QADMacros)
include(DeployMacros)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
if(NOT DEFINED BUILD_NUMBER)
set(BUILD_NUMBER 9999)
endif()
if("x${BUILD_NUMBER}" STREQUAL "x")
set(BUILD_NUMBER 0)
endif()
set(_COMPANY SHS)
set(_DOMAIN org.SHS)
if(STATIC_LIB)
set(QAD_LIB_TYPE STATIC)
add_definitions(-DQAD_STATIC_DEFINE)
set(QAD_LIB_TYPE_MSG "Static")
else()
set(QAD_LIB_TYPE SHARED)
set(QAD_LIB_TYPE_MSG "Shared")
endif()
set(_QAD_MAJOR 1)
set(_QAD_MINOR 9)
set(_QAD_REVISION 0)
set(_QAD_SUFFIX )
set(_QAD_COMPANY SHS)
set(_QAD_DOMAIN org.SHS)
set(QAD_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/qad/qad_version.h")
set_version(QAD
MAJOR "${_QAD_MAJOR}"
MINOR "${_QAD_MINOR}"
REVISION "${_QAD_REVISION}"
BUILD "${BUILD_NUMBER}"
SUFFIX "${_QAD_SUFFIX}"
OUTPUT "${QAD_VERSION_FILE}")
set_deploy_property(QAD ${QAD_LIB_TYPE}
FULLNAME "${_QAD_DOMAIN}.*"
COMPANY "${_QAD_COMPANY}")
if(STATIC_LIB)
set(PIQt_LIB_TYPE STATIC)
add_definitions(-DPIQt_STATIC_DEFINE)
set(PIQt_LIB_TYPE_MSG "Static")
else()
set(PIQt_LIB_TYPE SHARED)
set(PIQt_LIB_TYPE_MSG "Shared")
endif()
set(_PIQt_MAJOR 1)
set(_PIQt_MINOR 0)
set(_PIQt_REVISION 0)
set(_PIQt_SUFFIX )
set(_PIQt_COMPANY SHS)
set(_PIQt_DOMAIN org.SHS)
if(NOT DEFINED BUILD_NUMBER)
set(BUILD_NUMBER 9999)
endif()
set(PIQt_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/piqt/piqt_version.h")
set_version(PIQt
MAJOR "${_PIQt_MAJOR}"
MINOR "${_PIQt_MINOR}"
REVISION "${_PIQt_REVISION}"
BUILD "${BUILD_NUMBER}"
SUFFIX "${_PIQt_SUFFIX}"
OUTPUT "${PIQt_VERSION_FILE}")
set_deploy_property(PIQt ${_PIQt_LIB_TYPE}
FULLNAME "${_PIQt_DOMAIN}.*"
COMPANY "${_PIQt_COMPANY}")
include_directories(${CMAKE_CURRENT_BINARY_DIR}/pip)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/qad)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/piqt)
if(MINGW)
find_package(MinGW REQUIRED)
else()
@@ -45,21 +111,22 @@ if (DEFINED ANDROID_PLATFORM)
#message("${ANDROID_NDK}/sysroot/usr/include")
endif()
set(INSTALL_PREFIX "")
set(_plugins_default_ 1)
set(_plugins_default_ ON)
if(CMAKE_CROSSCOMPILING)
if (DEFINED ANDROID_PLATFORM)
set(_plugins_default_ 0)
set(_plugins_default_ OFF)
set(INSTALL_PREFIX "${CMAKE_FIND_ROOT_PATH}/")
else()
set(INSTALL_PREFIX "${CMAKE_STAGING_PREFIX}")
endif()
endif()
option(CROSSTOOLS "Crosstools minimal build" 0)
option(LIB "System install" 1)
option(QGLVIEW "Build QGLview library and utils" 0)
option(QGLENGINE "Build QGLENGINE library and utils" 0)
option(CROSSTOOLS "Crosstools minimal build" OFF)
option(LIB "System install" ON)
option(QGLVIEW "Build QGLview library and utils" OFF)
option(QGLENGINE "Build QGLENGINE library and utils" OFF)
option(UTILS "Build various utils" ${_plugins_default_})
option(DESIGNER_PLUGINS "Build qt designer plugins" ${_plugins_default_})
option(STATIC_LIB OFF)
if (CROSSTOOLS)
set(LIB 1)
set(QGLVIEW 0)
@@ -77,7 +144,6 @@ endif()
set(CMAKE_CXX_STANDARD 11)
set(PIP_LIBRARY pip)
set(PIP_FOLDERS "." "core" "containers" "thread" "system" "io_devices" "io_utils" "console" "math" "code" "geo" "resources" "opencl" "crypt" "introspection" "concurrent" "cloud")
set(PIP_INCLUDES)
if(LIB)
@@ -101,9 +167,6 @@ else()
message(STATUS "Install ${PROJECT_NAME} to local \"bin\", \"lib\" and \"include\"")
endif()
foreach(F ${PIP_FOLDERS})
list(APPEND PIP_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/pip/lib/main/${F}")
endforeach(F)
#message(${PIP_INCLUDES})
if(CMAKE_CROSSCOMPILING OR (DEFINED ANDROID_PLATFORM))
set(PIP_CMG "pip_cmg")
@@ -119,6 +182,7 @@ if(WIN32)
endif()
set(QAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/qad)
set(ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
if (CROSSTOOLS)
@@ -143,20 +207,27 @@ else()
endif()
endforeach()
if(UTILS)
message(STATUS "Building with utils")
else()
message(STATUS "Building only libraries")
endif()
#if(UTILS)
# message(STATUS "Building with utils")
#else()
# message(STATUS "Building only libraries")
#endif()
add_subdirectory(pip)
foreach(F ${PIP_MAIN_FOLDERS})
list(APPEND PIP_INCLUDES "${F}")
endforeach(F)
add_subdirectory(cd_utils)
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/cd_utils" "${CMAKE_CURRENT_BINARY_DIR}/cd_utils")
set(_DIRS)
if (SomeQtFound)
message(STATUS "Building Qt-derived targets for ${QtVersions}")
#message(STATUS "Building Qt-derived targets for ${QtVersions}")
add_subdirectory(qad)
set(_DIRS piqt piqt_utils qcd_utils)
include_directories(${qad_includes})
add_subdirectory(piqt)
include_directories(${piqt_includes})
set(_DIRS)
if (Qt5)
list(APPEND _DIRS)
if (QGLVIEW)
list(APPEND _DIRS qglview)
endif()
@@ -166,21 +237,62 @@ else()
endif()
foreach(_D ${_DIRS})
list(APPEND QT_MULTILIB_LIST ${_D})
add_subdirectory(${_D})
endforeach(_D)
include_directories(piqt)
macro(align_list _list _out)
set(_max_len 0)
foreach(_m ${_list})
string(LENGTH "${_m}" _clen)
if (_clen GREATER _max_len)
set(_max_len ${_clen})
endif()
endforeach()
set(${_out})
foreach(_m ${_list})
set(_am "${_m}")
while(TRUE)
string(LENGTH "${_am}" _clen)
if (_clen GREATER_EQUAL ${_max_len})
break()
endif()
string(APPEND _am " ")
endwhile()
list(APPEND ${_out} "${_am}")
endforeach()
endmacro()
macro(print_list _list _name)
if (NOT "x${_list}" STREQUAL "x")
message("")
message(" ${_name}:")
#align_list("${_list}" _alist)
foreach(_m ${_list})
message(" * ${_m}")
endforeach()
endif()
endmacro()
message("----------QAD-----------")
message(" Build for ${QtVersions}")
message(" QAD Version: ${QAD_VERSION}")
message(" QAD Linkage: ${QAD_LIB_TYPE_MSG}")
message(" PIQt Version: ${PIQt_VERSION}")
message(" PIQt Linkage: ${PIQt_LIB_TYPE_MSG}")
print_list("${_qt_libs}" "Libraries")
print_list("${_qt_apps}" "Applications")
print_list("${_qt_plugs}" "Plugins")
message("-----------------------")
message("")
else()
message(STATUS "None of Qt found, skip Qt-derived targets")
endif()
include_directories(cd_utils)
list(INSERT _DIRS 0 cd_utils)
foreach(_D ${_DIRS})
add_subdirectory(${_D})
endforeach(_D)
endif()
if(WIN32)
foreach(PIP_LT ${PIP_LIBS_TARGETS})
foreach(PIP_LT ${PIP_MODULES})
if (SomeQtFound)
qt_install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pip/lib${PIP_LT}.dll" DESTINATION QtBin)
endif()

View File

@@ -1,35 +1,107 @@
macro(sdk_install _DIR _TARGET _H_FILES _QM_FILES)
#message("QM=${_QM_FILES}")
if(LIB)
if(WIN32)
if(NOT "x${_H_FILES}" STREQUAL "x")
install(FILES ${_H_FILES} DESTINATION ${MINGW_INCLUDE}/${_DIR})
endif()
qt_install(TARGETS ${_TARGET} ARCHIVE DESTINATION ${MINGW_LIB})
qt_install(TARGETS ${_TARGET} RUNTIME DESTINATION ${MINGW_BIN})
qt_install(TARGETS ${_TARGET} RUNTIME DESTINATION QtBin)
else()
if (NOT "x${_H_FILES}" STREQUAL "x")
install(FILES ${_H_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/${_DIR})
endif()
qt_install(TARGETS ${_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
endif()
if(NOT "x${_QM_FILES}" STREQUAL "x")
qt_install(LANG ${_QM_FILES} DESTINATION QtLang)
endif()
else()
if(NOT "x${_H_FILES}" STREQUAL "x")
install(FILES ${_H_FILES} DESTINATION include/${_DIR})
endif()
if(WIN32)
qt_install(TARGETS ${_TARGET} RUNTIME DESTINATION bin)
qt_install(TARGETS ${_TARGET} ARCHIVE DESTINATION lib)
else()
qt_install(TARGETS ${_TARGET} DESTINATION lib)
endif()
if(NOT "x${_QM_FILES}" STREQUAL "x")
qt_install(LANG ${_QM_FILES} DESTINATION lang)
endif()
endif()
endmacro()
macro(sdk_install _DIR IS_APP _TARGET _H_FILES _QM_FILES)
#message("QM=${_QM_FILES}")
if((NOT ${IS_APP}) AND (NOT "${_H_FILES}" STREQUAL ""))
if(LIB)
if(WIN32)
install(FILES ${_H_FILES} DESTINATION ${MINGW_INCLUDE}/${_DIR})
else()
install(FILES ${_H_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/${_DIR})
endif()
else()
install(FILES ${_H_FILES} DESTINATION include/${_DIR})
endif()
endif()
if (NOT "${_TARGET}" STREQUAL "")
if(LIB)
if(WIN32)
if (${IS_APP})
qt_install(TARGETS ${_TARGET} DESTINATION ${MINGW_BIN})
qt_install(TARGETS ${_TARGET} DESTINATION QtBin)
else()
qt_install(TARGETS ${_TARGET} ARCHIVE DESTINATION ${MINGW_LIB})
qt_install(TARGETS ${_TARGET} RUNTIME DESTINATION ${MINGW_BIN})
qt_install(TARGETS ${_TARGET} RUNTIME DESTINATION QtBin)
endif()
else()
if (${IS_APP})
qt_install(TARGETS ${_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
else()
qt_install(TARGETS ${_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
endif()
endif()
if(NOT "x${_QM_FILES}" STREQUAL "x")
qt_install(LANG ${_QM_FILES} DESTINATION QtLang)
endif()
else()
if(${IS_APP})
qt_install(TARGETS ${_TARGET} DESTINATION bin)
else()
if(WIN32)
qt_install(TARGETS ${_TARGET} RUNTIME DESTINATION bin)
qt_install(TARGETS ${_TARGET} ARCHIVE DESTINATION lib)
else()
qt_install(TARGETS ${_TARGET} DESTINATION lib)
endif()
endif()
if(NOT "x${_QM_FILES}" STREQUAL "x")
qt_install(LANG ${_QM_FILES} DESTINATION lang)
endif()
endif()
endif()
endmacro()
macro(copy_to_parent _inc_var)
set(QT_MULTILIB_LIST ${QT_MULTILIB_LIST} PARENT_SCOPE)
set(_qt_libs ${_qt_libs} PARENT_SCOPE)
set(_qt_apps ${_qt_apps} PARENT_SCOPE)
set(_qt_plugs ${_qt_plugs} PARENT_SCOPE)
if (NOT "x${_inc_var}" STREQUAL "x")
set(${_inc_var} ${${_inc_var}} PARENT_SCOPE)
endif()
if (LIB)
set(_ALL_TARGETS ${_ALL_TARGETS} PARENT_SCOPE)
endif()
endmacro()
macro(add_directories_with_include multilib_prefix)
set(DIRS)
file(GLOB _dl "[^.]*")
foreach(_d ${_dl})
if(IS_DIRECTORY ${_d})
list(APPEND DIRS ${_d})
endif()
endforeach()
set(inc_var ${multilib_prefix}includes)
set(${inc_var})
foreach(_d ${DIRS})
get_filename_component(_dname "${_d}" NAME)
list(APPEND QT_MULTILIB_LIST ${multilib_prefix}${_dname})
list(APPEND ${inc_var} "${_d}")
list(APPEND ${inc_var} "${CMAKE_CURRENT_BINARY_DIR}/${_dname}")
endforeach()
include_directories(${${inc_var}})
foreach(_d ${DIRS})
add_subdirectory(${_d})
endforeach()
copy_to_parent(${inc_var})
endmacro()
macro(add_directories multilib_prefix)
include_directories(${${multilib_prefix}includes})
file(GLOB _dl "[^.]*")
foreach(_d ${_dl})
if(IS_DIRECTORY ${_d})
add_subdirectory(${_d})
endif()
endforeach()
copy_to_parent(${multilib_prefix}includes)
endmacro()

View File

@@ -1,6 +0,0 @@
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY FIRST)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE FIRST)
set(CMAKE_PREFIX_PATH /soft/android/${ANDROID_ABI})
list(APPEND CMAKE_FIND_ROOT_PATH ${CMAKE_PREFIX_PATH}/lib)
include_directories(${CMAKE_PREFIX_PATH}/include)

View File

@@ -1,86 +1,37 @@
cmake_minimum_required(VERSION 3.0)
project(cd_utils)
if (NOT LIBPROJECT)
find_package(PIP REQUIRED)
option(LIB "System install" 1)
option(DEBUG "Build with -g3" 0)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wall")
if (DEBUG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3")
endif()
endif()
if (MINGW)
find_package(MinGW REQUIRED)
endif()
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${PIP_INCLUDES})
#file(GLOB HDRS_UTILS "*.h")
#file(GLOB CPPS_UTILS "*.cpp")
file(GLOB CPPS_UTILS "cdutils_*.cpp")
file(GLOB HDRS_UTILS "cdutils_*.h")
if (DEFINED ENV{QNX_HOST})
add_library(${PROJECT_NAME} STATIC ${CPPS_UTILS} ${HDRS_UTILS})
else()
add_library(${PROJECT_NAME} SHARED ${CPPS_UTILS} ${HDRS_UTILS})
endif()
target_link_libraries(${PROJECT_NAME} ${PIP_LIBRARY})
# # Apple crosscompiling rpath patch
# if (APPLE AND CMAKE_CROSSCOMPILING AND CMAKE_MACOSX_RPATH)
# foreach(_RP ${CMAKE_INSTALL_RPATH})
# add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
# COMMAND "${CMAKE_INSTALL_NAME_TOOL}"
# "-add_rpath" "${_RP}"
# "$<TARGET_FILE_DIR:${PROJECT_NAME}>/$<TARGET_FILE_NAME:${PROJECT_NAME}>"
# COMMENT "Add to ${PROJECT_NAME} rpath \"${_RP}\"")
# endforeach()
# endif()
add_executable(cdutilstest "cdutilstest.cpp" "cdtest.h")
target_link_libraries(cdutilstest ${PIP_LIBRARY} ${PROJECT_NAME})
message(STATUS "Building ${PROJECT_NAME}")
if(NOT LIBPROJECT)
if(LIB)
if(WIN32)
if(MINGW)
set(CMAKE_INSTALL_PREFIX ${MINGW_DIR})
endif()
else()
if (DEFINED ANDROID_PLATFORM)
set(CMAKE_INSTALL_PREFIX ${ANDROID_SYSTEM_LIBRARY_PATH}/usr)
else()
if(CMAKE_CROSSCOMPILING)
set(CMAKE_INSTALL_PREFIX ${CMAKE_STAGING_PREFIX})
else()
set(CMAKE_INSTALL_PREFIX ${INSTALL_PREFIX}/usr/local)
endif()
endif()
endif()
message(STATUS "Install ${PROJECT_NAME} to system \"${CMAKE_INSTALL_PREFIX}\"")
else()
message(STATUS "Install ${PROJECT_NAME} to local \"bin\", \"lib\" and \"include\"")
endif()
endif()
if(LIB)
list(APPEND _ALL_TARGETS ${PROJECT_NAME})
set(_ALL_TARGETS ${_ALL_TARGETS} PARENT_SCOPE)
if(WIN32)
install(FILES ${HDRS_UTILS} DESTINATION ${MINGW_INCLUDE})
install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION ${MINGW_LIB})
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${MINGW_BIN})
else()
install(FILES ${HDRS_UTILS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include)
install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
endif()
#message(STATUS "Install ${PROJECT_NAME} to system \"${CMAKE_INSTALL_PREFIX}\"")
else()
if(WIN32)
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION lib)
else()
install(TARGETS ${PROJECT_NAME} DESTINATION lib)
endif()
install(FILES ${HDRS_UTILS} DESTINATION include)
#message(STATUS "Install ${PROJECT_NAME} to local \"bin\"")
endif()
cmake_minimum_required(VERSION 3.0)
project(cd_utils)
find_package(MinGW REQUIRED)
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${PIP_INCLUDES})
file(GLOB CPPS_UTILS "cdutils_*.cpp")
file(GLOB HDRS_UTILS "cdutils_*.h")
add_library(${PROJECT_NAME} SHARED ${CPPS_UTILS} ${HDRS_UTILS})
target_link_libraries(${PROJECT_NAME} ${PIP_LIBRARY})
generate_export_header(${PROJECT_NAME})
list(APPEND HDRS_UTILS "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}_export.h")
add_executable(cdutilstest "cdutilstest.cpp" "cdtest.h")
target_link_libraries(cdutilstest ${PIP_LIBRARY} ${PROJECT_NAME})
message(STATUS "Building ${PROJECT_NAME}")
if(LIB)
list(APPEND _ALL_TARGETS ${PROJECT_NAME})
set(_ALL_TARGETS ${_ALL_TARGETS} PARENT_SCOPE)
if(WIN32)
install(FILES ${HDRS_UTILS} DESTINATION ${MINGW_INCLUDE})
install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION ${MINGW_LIB})
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${MINGW_BIN})
else()
install(FILES ${HDRS_UTILS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include)
install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
endif()
#message(STATUS "Install ${PROJECT_NAME} to system \"${CMAKE_INSTALL_PREFIX}\"")
else()
if(WIN32)
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION lib)
else()
install(TARGETS ${PROJECT_NAME} DESTINATION lib)
endif()
install(FILES ${HDRS_UTILS} DESTINATION include)
#message(STATUS "Install ${PROJECT_NAME} to local \"bin\"")
endif()

View File

@@ -1,10 +1,10 @@
#ifndef CDTEST_H
#define CDTEST_H
enum KDescription {
First, //f Первый
Second, //b Второй
};
#endif // CDTEST_H
#ifndef CDTEST_H
#define CDTEST_H
enum KDescription {
First, //f Первый
Second, //b Второй
};
#endif // CDTEST_H

View File

@@ -1,41 +1,41 @@
#include "cdutils_c.h"
#include "cdutils_core.h"
using namespace CDUtils;
CInterface C;
CInterface::CInterface(): Interface(CDType::cdC) {
}
void CInterface::sendCommand(const CDType & c) {
core->sendCommand(c);
}
void CInterface::connect(const CDType & c, PIObject * o, Handler eh) {
core->registerCHandler(c, o, eh);
}
void CInterface::autoConnect(PIObject * o, const PIString & prefix) {
if (!o) return;
uint cid = o->classNameID();
if (!PIObject::__meta_data().contains(cid)) return;
PIMap<PIString, Handler> eh_map;
PIObject::__MetaData & md(PIObject::__meta_data()[cid]);
PIMap<const void * , __MetaFunc>::const_iterator it;
for (it = md.eh_func.constBegin(); it != md.eh_func.constEnd(); ++it) {
eh_map[it.value().func_name] = (Handler)it.value().addr;
//piCout << "func" << it.value().func_name;
}
PIVector<CDType * > cl = C.root().children();
piForeachC (CDType * c, cl) {
PIString cp = prefix + c->pathString().join("_");
if (cp.isEmpty()) continue;
if (!eh_map.contains(cp)) continue;
connect(*c, o, eh_map[cp]);
}
}
#include "cdutils_c.h"
#include "cdutils_core.h"
using namespace CDUtils;
CInterface C;
CInterface::CInterface(): Interface(CDType::cdC) {
}
void CInterface::sendCommand(const CDType & c) {
core->sendCommand(c);
}
void CInterface::connect(const CDType & c, PIObject * o, Handler eh) {
core->registerCHandler(c, o, eh);
}
void CInterface::autoConnect(PIObject * o, const PIString & prefix) {
if (!o) return;
uint cid = o->classNameID();
if (!PIObject::__meta_data().contains(cid)) return;
PIMap<PIString, Handler> eh_map;
PIObject::__MetaData & md(PIObject::__meta_data()[cid]);
PIMap<const void * , __MetaFunc>::const_iterator it;
for (it = md.eh_func.constBegin(); it != md.eh_func.constEnd(); ++it) {
eh_map[it.value().func_name] = (Handler)it.value().addr;
//piCout << "func" << it.value().func_name;
}
PIVector<CDType * > cl = C.root().children();
piForeachC (CDType * c, cl) {
PIString cp = prefix + c->pathString().join("_");
if (cp.isEmpty()) continue;
if (!eh_map.contains(cp)) continue;
connect(*c, o, eh_map[cp]);
}
}

View File

@@ -1,45 +1,46 @@
/*
CD Utils - Control-Debug utilites
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CDUTILS_C_H
#define CDUTILS_C_H
#include "cdutils_interface.h"
namespace CDUtils {
class CInterface: public Interface
{
PIOBJECT_SUBCLASS(CInterface, Interface)
public:
CInterface();
void sendCommand(const CDType & c);
void connect(const CDType & c, PIObject * o, Handler eh);
void autoConnect(PIObject * o, const PIString & prefix = PIStringAscii("c_"));
};
}
extern CDUtils::CInterface C;
#endif // CDUTILS_C_H
/*
CD Utils - Control-Debug utilites
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CDUTILS_C_H
#define CDUTILS_C_H
#include "cdutils_interface.h"
#include "cd_utils_export.h"
namespace CDUtils {
class CD_UTILS_EXPORT CInterface: public Interface
{
PIOBJECT_SUBCLASS(CInterface, Interface)
public:
CInterface();
void sendCommand(const CDType & c);
void connect(const CDType & c, PIObject * o, Handler eh);
void autoConnect(PIObject * o, const PIString & prefix = PIStringAscii("c_"));
};
}
extern CD_UTILS_EXPORT CDUtils::CInterface C;
#endif // CDUTILS_C_H

View File

@@ -1,606 +1,606 @@
#include "cdutils_core.h"
#include "cdutils_parser.h"
#include "piconfig.h"
#include "piiobytearray.h"
#include "piiostring.h"
#include "pifile.h"
using namespace CDUtils;
const char CDCore::app_config[] =
"include = cd_ip.conf\n\
port_rec = 2\n\
port_send = 1\n\
[connection]\n\
device.cd = peer://cd_app:cd_pult #s\n\
[]\n\
connectionmodel = AAAM2Xja7VXLTttAFD12QpsikKjUSixYlLbKEpIUtVIlVEfqhk2FWuiGRRolUYtoHgrmpYiv6IItf8AveMMH9E/YsG6Ph3sde5hGoQoblLGuPHfunTPjc49nADxDA110+LTYC7FrPCAPeAO+vZu+aX7c/8PGd45WCJC0OGcfT6FDnmfSTPtwhZFt3HjgDs/Qtu5jPbZHtI/x50XfIzMQbdwEolbg9INP4ku++myPaUtCHYRaT2j1ldIh3VP60/Qff8vSfXLu9BP6JX9K/0TVH6jqVe22P1X/fao/oddWu/paDs1vBf9Jv/EZ91clbyHqv7BL6sscDOd4v4WTqs6jzaHGJ8QJerxlpJSpdZ7IWFJvDW7I2JxZqIM62k6A57RZmMQGmlyrxdV+WGBnmR01mXPI267hBKwp4FeBeo9VPtssxyb7rzHg1B7T9nCMU45U8BZlWuVWtIcD/CRGOqtsbW09851tXsHN0UTlLIAdASjSXnLyLn+H7L2+xbGYvC63Ezqg543egkLmn8qnRF6USbM4Qp9godkhzI777Ne5bCIt/5UtGz2o/yGby0nKpjqmbOa1ynkjmyzIrzvIZUeBPjvlUmbh32EFJbGyJZhR8YcvlS+3TpjhqeWSyvUkpbI9plSWtcKLcsK05beOJVEnhaEFfHEH+RwpeMcpn1JKGqWMNOL+G6wZyahlpdVOtufKfbDS+guLke9O\n\
";
const char CDCore::pult_config[] =
"include = cd_ip.conf\n\
port_rec = 1\n\
port_send = 2\n\
[connection]\n\
device.cd = peer://cd_pult:cd_app #s\n\
[]\n\
connectionmodel = AAAM2Xja7VXLTttAFD12QpsikKjUSixYlLbKEpIUtVIlVEfqhk2FWuiGRRolUYtoHgrmpYiv6IItf8AveMMH9E/YsG6Ph3sde5hGoQoblLGuPHfunTPjc49nADxDA110+LTYC7FrPCAPeAO+vZu+aX7c/8PGd45WCJC0OGcfT6FDnmfSTPtwhZFt3HjgDs/Qtu5jPbZHtI/x50XfIzMQbdwEolbg9INP4ku++myPaUtCHYRaT2j1ldIh3VP60/Qff8vSfXLu9BP6JX9K/0TVH6jqVe22P1X/fao/oddWu/paDs1vBf9Jv/EZ91clbyHqv7BL6sscDOd4v4WTqs6jzaHGJ8QJerxlpJSpdZ7IWFJvDW7I2JxZqIM62k6A57RZmMQGmlyrxdV+WGBnmR01mXPI267hBKwp4FeBeo9VPtssxyb7rzHg1B7T9nCMU45U8BZlWuVWtIcD/CRGOqtsbW09851tXsHN0UTlLIAdASjSXnLyLn+H7L2+xbGYvC63Ezqg543egkLmn8qnRF6USbM4Qp9godkhzI777Ne5bCIt/5UtGz2o/yGby0nKpjqmbOa1ynkjmyzIrzvIZUeBPjvlUmbh32EFJbGyJZhR8YcvlS+3TpjhqeWSyvUkpbI9plSWtcKLcsK05beOJVEnhaEFfHEH+RwpeMcpn1JKGqWMNOL+G6wZyahlpdVOtufKfbDS+guLke9O\n\
";
int __Core_Initializer__::count_(0);
CDCore * __Core_Initializer__::__instance__(0);
const uchar header_direct = 0x80;
const uchar header_transfer = 0x81;
__Core_Initializer__::__Core_Initializer__() {
count_++;
if (count_ > 1) return;
__instance__ = new CDCore();
}
__Core_Initializer__::~__Core_Initializer__() {
count_--;
if (count_ < 0) {
count_ = 0;
return;
}
if (count_ > 0) return;
if (__instance__) {
delete __instance__;
__instance__ = 0;
}
}
CDCore::CDCore() {
setName("CDCore");
x_timer.setName("__S__.CDCore.x_timer");
datatr.setPacketSize(960);
CONNECTU(&connection, dataReceivedEvent, this, dataReceived);
CONNECTU(PICout::Notifier::object(), finished, this, piCoutFinished);
/*PIString s(app_config);
connection.configureFromString(&s);
connection.start();*/
need_rebuild_x = x_pult_side = false;
k_.cd_type_ = CDType::cdK;
x_.cd_type_ = CDType::cdX;
c_.cd_type_ = CDType::cdC;
m_.cd_type_ = CDType::cdM;
initRoot(&k_);
initRoot(&x_);
initRoot(&c_);
initRoot(&m_);
CONNECTU(&sendt, started, this, sendThread)
CONNECTU(&datatr, sendRequest, this, dtSendRequest)
CONNECTU(&datatr, receiveFinished, this, dtReceiveFinished)
CONNECTU(&x_timer, tickEvent, this, xTimerTick)
/*k_[1] = KType(1, "123", "120+3", "comment");
k_[2] = KType(2, "1", "2", "comm");
k_[4] = KType(4, "-0.6", "-6/10", "mment");
k_.section(10)[5] = KType(5, "8", "2*2*2", "88");
k_.section(10).section(50)[100] = KType(100, "8", "2*2*2", "88");
k_.section(11)[3] = KType(3, "1", "1", "88");
k_.section(11)[4] = KType(4, "0", "0", "88");
k_.section(11)[6] = KType(6, "0", "0", "88");*/
//piCout << s;
}
CDCore::~CDCore() {
x_timer.stop(true);
datatr.stop();
sendt.stop();
sendt.waitForFinish(10);
connection.stop();
}
void CDCore::cd_write(CDSection * cd, PIIODevice * d) {
cd->write(d, PIString());
}
void CDCore::cd_read(CDSection * cd, PIIODevice * d) {
PIConfig conf(d, PIIODevice::ReadOnly);
cd->read(&(conf.rootEntry()));
if (cd->cd_type_ == CDType::cdX)
x_selected = cd->collectX();
initRoot(cd);
raiseChangedGlobal(cd->cd_type_);
/*PIVector<PIIODevice * > ds = connection.allDevices();
piForeach(PIIODevice * d, ds) {
if (d)
piCoutObj << d->constructFullPath() << d->isOpened();
}*/
}
void CDCore::cd_parse(CDSection * cd, PIIODevice * d) {
*cd = CDParser::parse(d, cd->cd_type_);
initRoot(cd);
raiseChangedGlobal(cd->cd_type_);
}
void CDCore::cd_update(CDSection * cd, PIIODevice * d, UpdateModeFlags mode) {
CDSection ucd = *cd;
cd_parse(cd, d);
/*bool kn = true;
if (!ucd.isEmpty())
if (!ucd.isSameStructure(k_)) {
piCout << "ask for save names";
K_KeepNamesRequest(&kn);
}*/
ucd.update(*cd, mode);
//piCout << k_.count() << ucd.count();
*cd = ucd;
initRoot(cd);
raiseChangedGlobal(cd->cd_type_);
}
void CDCore::cd_calculate(CDSection * cd) {
cd->calculate();
raiseChangedGlobal(cd->cd_type_);
}
void CDCore::cd_send(CDSection * cd, CDPacketType pt, bool direct) {
if (!cd) return;
PIByteArray ba, sba;
PIIOByteArray iob(&ba, PIIODevice::ReadWrite);
cd_write(cd, &iob);
//piCoutObj << PIString(ba);
sba = makeHeader(pt, 0);
sba << ba;
if (direct)
sendDirect(sba);
else
sendThreaded(sba);
}
void CDCore::send(CDType::cdT cdt) {
CDPacketType pt = CD_Ping;
switch (cdt) {
case CDType::cdK: pt = CD_KSend; break;
case CDType::cdX: pt = CD_XSend; break;
case CDType::cdC: pt = CD_CSend; break;
case CDType::cdM: pt = CD_MSend; break;
default: break;
}
piCoutObj << "send" << typeLetter(cdt);
cd_send(root(cdt), pt);
}
void CDCore::request(CDType::cdT cdt) {
CDPacketType pt = CD_Ping;
switch (cdt) {
case CDType::cdK: pt = CD_KQuery; break;
case CDType::cdX: pt = CD_XQuery; break;
case CDType::cdC: pt = CD_CQuery; break;
case CDType::cdM: pt = CD_MQuery; break;
default: break;
}
piCoutObj << "request" << typeLetter(cdt);
PIByteArray sba = makeHeader(pt, 0);
sendThreaded(sba);
}
void CDCore::initApp() {
init(appConfig(), false);
}
void CDCore::initPult() {
init(pultConfig(), true);
}
void CDCore::init(const PIString & configuration, bool pult) {
PIString c = configuration;
//piCoutObj << "init" << c;
connection.stop();
connection.removeAllDevices();
connection.configureFromString(&c);
connection.start();
x_pult_side = pult;
}
void CDCore::stop() {
x_timer.stop();
x_timer.waitForFinish(1000);
connection.stop();
}
void CDCore::release() {
stop();
connection.removeAllDevices();
}
void CDCore::startX(double freq) {
//piCout << "start x" << x_timer.isRunning() << freq;
if (!x_timer.isRunning())
x_timer.start(1000. / piMaxd(freq, 0.01));
}
void CDCore::stopX() {
x_timer.stop();
x_timer.waitForFinish(1000);
}
void CDCore::sendCommand(const CDType & c) {
//piCoutObj << "C_sendCommand" << c;
PIByteArray sba = makeHeader(CD_Command, 0);
sba << c.path();
sendDirect(sba);
}
void CDCore::registerCHandler(const CDType & c, PIObject * o, Handler h) {
PIString sp = pathToString(c.path());
if (sp.isEmpty() || !h) return;
//piCout << "register" << sp;
c_handlers[sp] = OHPair(o, h);
}
void CDCore::sendMessage(const CDType & m, MessageType mt, const PIString & msg) {
if (msg.isEmpty() || (m.cd_type() != CDType::cdM)) return;
PIByteArray sba = makeHeader(CD_Message, 0);
sba << m.path() << int(mt) << msg;
sendDirect(sba);
}
CDSection * CDCore::root(CDType::cdT cdt) {
switch (cdt) {
case CDType::cdK: return &k_; break;
case CDType::cdX: return &x_; break;
case CDType::cdC: return &c_; break;
case CDType::cdM: return &m_; break;
default: break;
}
return 0;
}
PIString CDCore::typeLetter(CDType::cdT cdt) {
switch (cdt) {
case CDType::cdK: return PIStringAscii("k"); break;
case CDType::cdX: return PIStringAscii("x"); break;
case CDType::cdC: return PIStringAscii("c"); break;
case CDType::cdM: return PIStringAscii("m"); break;
default: break;
}
return PIString();
}
CDCore * CDCore::instance() {
/*static CDCore * ret = new CDCore();
return ret;*/
return __Core_Initializer__::__instance__;
}
bool CDCore::destroy() {
if (!__Core_Initializer__::__instance__) return false;
// piCout << "delete Core ...";
delete __Core_Initializer__::__instance__;
// piCout << "delete Core ok";
__Core_Initializer__::__instance__ = 0;
__Core_Initializer__::count_ = 0;
return true;
}
void CDUtils::CDCore::K_DirectChange(PIDeque<int> path, PIString value) {
// piCoutObj << "K_DirectChange";
PacketKDirectChange p;
p.path = path;
p.value = value;
PIByteArray sba = makeHeader(CD_KDirectChange, 0);
sba << p;
sendDirect(sba);
}
void CDCore::sendThread() {
if (send_data.size_s() < 4) return;
PacketHeader h;
memcpy(&h, send_data.data(), sizeof(h));
bool ok = datatr.send(send_data);
switch (h.type) {
case CD_KSend:
if (ok) K_Sended();
else K_SendFail();
break;
case CD_KQuery:
if (!ok) K_ReceiveFail();
break;
case CD_XSend:
if (ok) X_Sended();
else X_SendFail();
break;
case CD_XQuery:
if (!ok) X_ReceiveFail();
break;
case CD_CSend:
if (ok) C_Sended();
else C_SendFail();
break;
case CD_CQuery:
if (!ok) C_ReceiveFail();
break;
case CD_MSend:
if (ok) M_Sended();
else M_SendFail();
break;
case CD_MQuery:
if (!ok) M_ReceiveFail();
break;
default: break;
}
}
void CDCore::xTimerTick() {
//piCout << "x tick" << x_pult_side;
PIByteArray ba;
x_mutex.lock();
if (x_pult_side) {
ba = makeHeader(CD_XRequest, 0);
if (need_rebuild_x) {
x_selected = x_.collectX();
//piCout << "collectX" << x_selected.size();
need_rebuild_x = false;
}
ba << x_selected;
//piCout << "x pult send" << x_selected.size();
} else {
ba = makeHeader(CD_XValues, 0);
ba << x_selected;
piForeachC (PIDeque<int> & p, x_selected) {
x_[p].writeX(ba);
}
//piCout << "x app" << x_selected.size();
}
x_mutex.unlock();
sendDirect(ba);
}
void CDCore::piCoutFinished(int id, PIString * buffer) {
if (!buffer || !(id == 1)) return;
PIString sp = buffer->takeRange("[", "]");
PIDeque<int> p = CDCore::stringToPath(sp);
sendMessage(m_[p], Log, *buffer);
delete buffer;
}
void CDCore::initRoot(CDSection * r) {
r->name = "__root__";
r->alias = "root";
r->makePath();
r->calculate();
}
PIByteArray CDCore::makeHeader(CDPacketType type, int session_id) const {
PacketHeader h;
h.type = type;
h.session_id = session_id;
PIByteArray ret; ret << h;
return ret;
}
void CDCore::sendDirect(PIByteArray & ba) {
ba.push_front(header_direct);
connection.writeByName("cd", ba);
}
void CDCore::sendThreaded(PIByteArray & ba) {
if (sendt.isRunning()) {
piCoutObj << "Send in process, abort";
return;
}
send_data = ba;
sendt.startOnce();
}
void CDCore::procReceivedPacket(PIByteArray & ba) {
PacketHeader h;
ba >> h;
switch(h.type) {
case CD_Ping:
//piCoutObj << "ping";
break;
case CD_KQuery:
send(CDType::cdK);
break;
case CD_KSend: {
PIByteArray k;
ba >> k;
k << uchar(0);
PIString s = PIString::fromUTF8((const char *)k.data());
PIIOString ios(&s);
cd_read(&k_, &ios);
K_Received();
piCoutObj << "K received";
} break;
case CD_KDirectChange: {
PacketKDirectChange p;
ba >> p;
k_[p.path].setValue(p.value);
} break;
case CD_XQuery:
send(CDType::cdX);
break;
case CD_XSend: {
PIByteArray x;
ba >> x;
x << uchar(0);
PIString s = PIString::fromUTF8((const char *)x.data());
PIIOString ios(&s);
cd_read(&x_, &ios);
x_selected = x_.collectX();
X_Received();
piCoutObj << "X received";
} break;
case CD_XRequest: {
if (x_pult_side) break;
//break;
x_mutex.lock();
x_selected.clear();
ba >> x_selected;
//piCout << "X req" << x_selected.size();
x_.setSelectedX(false);
piForeachC (PIDeque<int> & p, x_selected) {
x_[p].x_enabled = true;
}
x_mutex.unlock();
} break;
case CD_XValues: {
if (!x_pult_side) break;
PIVector<PIDeque<int> > x_vals;
ba >> x_vals;
x_mutex.lock();
piForeachC (PIDeque<int> & p, x_vals) {
x_[p].readX(ba);
}
x_mutex.unlock();
X_ReceivedX(x_vals);
} break;
case CD_CQuery:
send(CDType::cdC);
break;
case CD_CSend: {
piCoutObj << "C received";
PIByteArray c;
ba >> c;
c << uchar(0);
PIString s = PIString::fromUTF8((const char *)c.data());
PIIOString ios(&s);
cd_read(&c_, &ios);
C_Received();
} break;
case CD_Command: {
piCoutObj << "C command";
PIDeque<int> p;
ba >> p;
if (p.isEmpty()) return;
PIString sp = pathToString(p);
OHPair h = c_handlers.value(sp, OHPair(0, 0));
//piCoutObj << "found" << sp << h.first;
if (h.first && h.second) h.second(h.first);
} break;
case CD_MQuery:
send(CDType::cdM);
break;
case CD_MSend: {
piCoutObj << "M received";
PIByteArray c;
ba >> c;
c << uchar(0);
PIString s = PIString::fromUTF8((const char *)c.data());
PIIOString ios(&s);
cd_read(&m_, &ios);
M_Received();
} break;
case CD_Message: {
PIDeque<int> p;
ba >> p;
piCoutObj << "M message" << p;
if (p.isEmpty()) return;
int t = 0;
PIString msg;
ba >> t >> msg;
//piCoutObj << "found" << sp << h.first;
//piCoutObj << "M message invoke";
M_Message(p, t, msg);
} break;
default: break;
}
}
void CDCore::raiseChangedGlobal(CDType::cdT cdt) {
switch (cdt) {
case CDType::cdK: K_ChangedGlobal(); break;
case CDType::cdX: X_ChangedGlobal(); break;
case CDType::cdC: C_ChangedGlobal(); break;
case CDType::cdM: M_ChangedGlobal(); break;
default: break;
}
}
PIString CDCore::pathToString(const PIDeque<int> & p) {
PIString ret;
for (int i = 0; i < p.size_s(); ++i) {
if (!ret.isEmpty()) ret += ".";
ret << p[i];
}
return ret;
}
PIDeque<int> CDCore::stringToPath(const PIString & p) {
PIDeque<int> ret;
PIStringList sl = p.split(".");
piForeachC (PIString & s, sl)
ret << s.toInt();
return ret;
}
void CDUtils::CDCore::dataReceived(const PIString & from, const PIByteArray & data) {
//piCoutObj << "dataReceived" << from << data.size();
PIIODevice * d = connection.deviceByName("cd");
if (d && d == connection.deviceByFullPath(from)) {
if (data.size() >= sizeof(4)) {
PIByteArray ba = data;
uchar header = ba.take_front();
if (header == header_transfer) {
datatr.received(ba);
}
if (header == header_direct) {
procReceivedPacket(ba);
}
}
}
}
void CDCore::dtSendRequest(PIByteArray & data) {
data.push_front(header_transfer);
connection.writeByName("cd", data);
//piCoutObj << "send" << data.size() << ret;
}
void CDCore::dtReceiveFinished(bool ok) {
if (!ok) return;
PIByteArray ba = datatr.data();
procReceivedPacket(ba);
}
#include "cdutils_core.h"
#include "cdutils_parser.h"
#include "piconfig.h"
#include "piiobytearray.h"
#include "piiostring.h"
#include "pifile.h"
using namespace CDUtils;
const char CDCore::app_config[] =
"include = cd_ip.conf\n\
port_rec = 2\n\
port_send = 1\n\
[connection]\n\
device.cd = peer://cd_app:cd_pult #s\n\
[]\n\
connectionmodel = AAAM2Xja7VXLTttAFD12QpsikKjUSixYlLbKEpIUtVIlVEfqhk2FWuiGRRolUYtoHgrmpYiv6IItf8AveMMH9E/YsG6Ph3sde5hGoQoblLGuPHfunTPjc49nADxDA110+LTYC7FrPCAPeAO+vZu+aX7c/8PGd45WCJC0OGcfT6FDnmfSTPtwhZFt3HjgDs/Qtu5jPbZHtI/x50XfIzMQbdwEolbg9INP4ku++myPaUtCHYRaT2j1ldIh3VP60/Qff8vSfXLu9BP6JX9K/0TVH6jqVe22P1X/fao/oddWu/paDs1vBf9Jv/EZ91clbyHqv7BL6sscDOd4v4WTqs6jzaHGJ8QJerxlpJSpdZ7IWFJvDW7I2JxZqIM62k6A57RZmMQGmlyrxdV+WGBnmR01mXPI267hBKwp4FeBeo9VPtssxyb7rzHg1B7T9nCMU45U8BZlWuVWtIcD/CRGOqtsbW09851tXsHN0UTlLIAdASjSXnLyLn+H7L2+xbGYvC63Ezqg543egkLmn8qnRF6USbM4Qp9godkhzI777Ne5bCIt/5UtGz2o/yGby0nKpjqmbOa1ynkjmyzIrzvIZUeBPjvlUmbh32EFJbGyJZhR8YcvlS+3TpjhqeWSyvUkpbI9plSWtcKLcsK05beOJVEnhaEFfHEH+RwpeMcpn1JKGqWMNOL+G6wZyahlpdVOtufKfbDS+guLke9O\n\
";
const char CDCore::pult_config[] =
"include = cd_ip.conf\n\
port_rec = 1\n\
port_send = 2\n\
[connection]\n\
device.cd = peer://cd_pult:cd_app #s\n\
[]\n\
connectionmodel = AAAM2Xja7VXLTttAFD12QpsikKjUSixYlLbKEpIUtVIlVEfqhk2FWuiGRRolUYtoHgrmpYiv6IItf8AveMMH9E/YsG6Ph3sde5hGoQoblLGuPHfunTPjc49nADxDA110+LTYC7FrPCAPeAO+vZu+aX7c/8PGd45WCJC0OGcfT6FDnmfSTPtwhZFt3HjgDs/Qtu5jPbZHtI/x50XfIzMQbdwEolbg9INP4ku++myPaUtCHYRaT2j1ldIh3VP60/Qff8vSfXLu9BP6JX9K/0TVH6jqVe22P1X/fao/oddWu/paDs1vBf9Jv/EZ91clbyHqv7BL6sscDOd4v4WTqs6jzaHGJ8QJerxlpJSpdZ7IWFJvDW7I2JxZqIM62k6A57RZmMQGmlyrxdV+WGBnmR01mXPI267hBKwp4FeBeo9VPtssxyb7rzHg1B7T9nCMU45U8BZlWuVWtIcD/CRGOqtsbW09851tXsHN0UTlLIAdASjSXnLyLn+H7L2+xbGYvC63Ezqg543egkLmn8qnRF6USbM4Qp9godkhzI777Ne5bCIt/5UtGz2o/yGby0nKpjqmbOa1ynkjmyzIrzvIZUeBPjvlUmbh32EFJbGyJZhR8YcvlS+3TpjhqeWSyvUkpbI9plSWtcKLcsK05beOJVEnhaEFfHEH+RwpeMcpn1JKGqWMNOL+G6wZyahlpdVOtufKfbDS+guLke9O\n\
";
int __Core_Initializer__::count_(0);
CDCore * __Core_Initializer__::__instance__(0);
const uchar header_direct = 0x80;
const uchar header_transfer = 0x81;
__Core_Initializer__::__Core_Initializer__() {
count_++;
if (count_ > 1) return;
__instance__ = new CDCore();
}
__Core_Initializer__::~__Core_Initializer__() {
count_--;
if (count_ < 0) {
count_ = 0;
return;
}
if (count_ > 0) return;
if (__instance__) {
delete __instance__;
__instance__ = 0;
}
}
CDCore::CDCore() {
setName("CDCore");
x_timer.setName("__S__.CDCore.x_timer");
datatr.setPacketSize(960);
CONNECTU(&connection, dataReceivedEvent, this, dataReceived);
CONNECTU(PICout::Notifier::object(), finished, this, piCoutFinished);
/*PIString s(app_config);
connection.configureFromString(&s);
connection.start();*/
need_rebuild_x = x_pult_side = false;
k_.cd_type_ = CDType::cdK;
x_.cd_type_ = CDType::cdX;
c_.cd_type_ = CDType::cdC;
m_.cd_type_ = CDType::cdM;
initRoot(&k_);
initRoot(&x_);
initRoot(&c_);
initRoot(&m_);
CONNECTU(&sendt, started, this, sendThread)
CONNECTU(&datatr, sendRequest, this, dtSendRequest)
CONNECTU(&datatr, receiveFinished, this, dtReceiveFinished)
CONNECTU(&x_timer, tickEvent, this, xTimerTick)
/*k_[1] = KType(1, "123", "120+3", "comment");
k_[2] = KType(2, "1", "2", "comm");
k_[4] = KType(4, "-0.6", "-6/10", "mment");
k_.section(10)[5] = KType(5, "8", "2*2*2", "88");
k_.section(10).section(50)[100] = KType(100, "8", "2*2*2", "88");
k_.section(11)[3] = KType(3, "1", "1", "88");
k_.section(11)[4] = KType(4, "0", "0", "88");
k_.section(11)[6] = KType(6, "0", "0", "88");*/
//piCout << s;
}
CDCore::~CDCore() {
x_timer.stop(true);
datatr.stop();
sendt.stop();
sendt.waitForFinish(10);
connection.stop();
}
void CDCore::cd_write(CDSection * cd, PIIODevice * d) {
cd->write(d, PIString());
}
void CDCore::cd_read(CDSection * cd, PIIODevice * d) {
PIConfig conf(d, PIIODevice::ReadOnly);
cd->read(&(conf.rootEntry()));
if (cd->cd_type_ == CDType::cdX)
x_selected = cd->collectX();
initRoot(cd);
raiseChangedGlobal(cd->cd_type_);
/*PIVector<PIIODevice * > ds = connection.allDevices();
piForeach(PIIODevice * d, ds) {
if (d)
piCoutObj << d->constructFullPath() << d->isOpened();
}*/
}
void CDCore::cd_parse(CDSection * cd, PIIODevice * d) {
*cd = CDParser::parse(d, cd->cd_type_);
initRoot(cd);
raiseChangedGlobal(cd->cd_type_);
}
void CDCore::cd_update(CDSection * cd, PIIODevice * d, UpdateModeFlags mode) {
CDSection ucd = *cd;
cd_parse(cd, d);
/*bool kn = true;
if (!ucd.isEmpty())
if (!ucd.isSameStructure(k_)) {
piCout << "ask for save names";
K_KeepNamesRequest(&kn);
}*/
ucd.update(*cd, mode);
//piCout << k_.count() << ucd.count();
*cd = ucd;
initRoot(cd);
raiseChangedGlobal(cd->cd_type_);
}
void CDCore::cd_calculate(CDSection * cd) {
cd->calculate();
raiseChangedGlobal(cd->cd_type_);
}
void CDCore::cd_send(CDSection * cd, CDPacketType pt, bool direct) {
if (!cd) return;
PIByteArray ba, sba;
PIIOByteArray iob(&ba, PIIODevice::ReadWrite);
cd_write(cd, &iob);
//piCoutObj << PIString(ba);
sba = makeHeader(pt, 0);
sba << ba;
if (direct)
sendDirect(sba);
else
sendThreaded(sba);
}
void CDCore::send(CDType::cdT cdt) {
CDPacketType pt = CD_Ping;
switch (cdt) {
case CDType::cdK: pt = CD_KSend; break;
case CDType::cdX: pt = CD_XSend; break;
case CDType::cdC: pt = CD_CSend; break;
case CDType::cdM: pt = CD_MSend; break;
default: break;
}
piCoutObj << "send" << typeLetter(cdt);
cd_send(root(cdt), pt);
}
void CDCore::request(CDType::cdT cdt) {
CDPacketType pt = CD_Ping;
switch (cdt) {
case CDType::cdK: pt = CD_KQuery; break;
case CDType::cdX: pt = CD_XQuery; break;
case CDType::cdC: pt = CD_CQuery; break;
case CDType::cdM: pt = CD_MQuery; break;
default: break;
}
piCoutObj << "request" << typeLetter(cdt);
PIByteArray sba = makeHeader(pt, 0);
sendThreaded(sba);
}
void CDCore::initApp() {
init(appConfig(), false);
}
void CDCore::initPult() {
init(pultConfig(), true);
}
void CDCore::init(const PIString & configuration, bool pult) {
PIString c = configuration;
//piCoutObj << "init" << c;
connection.stop();
connection.removeAllDevices();
connection.configureFromString(&c);
connection.start();
x_pult_side = pult;
}
void CDCore::stop() {
x_timer.stop();
x_timer.waitForFinish(1000);
connection.stop();
}
void CDCore::release() {
stop();
connection.removeAllDevices();
}
void CDCore::startX(double freq) {
//piCout << "start x" << x_timer.isRunning() << freq;
if (!x_timer.isRunning())
x_timer.start(1000. / piMaxd(freq, 0.01));
}
void CDCore::stopX() {
x_timer.stop();
x_timer.waitForFinish(1000);
}
void CDCore::sendCommand(const CDType & c) {
//piCoutObj << "C_sendCommand" << c;
PIByteArray sba = makeHeader(CD_Command, 0);
sba << c.path();
sendDirect(sba);
}
void CDCore::registerCHandler(const CDType & c, PIObject * o, Handler h) {
PIString sp = pathToString(c.path());
if (sp.isEmpty() || !h) return;
//piCout << "register" << sp;
c_handlers[sp] = OHPair(o, h);
}
void CDCore::sendMessage(const CDType & m, MessageType mt, const PIString & msg) {
if (msg.isEmpty() || (m.cd_type() != CDType::cdM)) return;
PIByteArray sba = makeHeader(CD_Message, 0);
sba << m.path() << int(mt) << msg;
sendDirect(sba);
}
CDSection * CDCore::root(CDType::cdT cdt) {
switch (cdt) {
case CDType::cdK: return &k_; break;
case CDType::cdX: return &x_; break;
case CDType::cdC: return &c_; break;
case CDType::cdM: return &m_; break;
default: break;
}
return 0;
}
PIString CDCore::typeLetter(CDType::cdT cdt) {
switch (cdt) {
case CDType::cdK: return PIStringAscii("k"); break;
case CDType::cdX: return PIStringAscii("x"); break;
case CDType::cdC: return PIStringAscii("c"); break;
case CDType::cdM: return PIStringAscii("m"); break;
default: break;
}
return PIString();
}
CDCore * CDCore::instance() {
/*static CDCore * ret = new CDCore();
return ret;*/
return __Core_Initializer__::__instance__;
}
bool CDCore::destroy() {
if (!__Core_Initializer__::__instance__) return false;
// piCout << "delete Core ...";
delete __Core_Initializer__::__instance__;
// piCout << "delete Core ok";
__Core_Initializer__::__instance__ = 0;
__Core_Initializer__::count_ = 0;
return true;
}
void CDUtils::CDCore::K_DirectChange(PIDeque<int> path, PIString value) {
// piCoutObj << "K_DirectChange";
PacketKDirectChange p;
p.path = path;
p.value = value;
PIByteArray sba = makeHeader(CD_KDirectChange, 0);
sba << p;
sendDirect(sba);
}
void CDCore::sendThread() {
if (send_data.size_s() < 4) return;
PacketHeader h;
memcpy(&h, send_data.data(), sizeof(h));
bool ok = datatr.send(send_data);
switch (h.type) {
case CD_KSend:
if (ok) K_Sended();
else K_SendFail();
break;
case CD_KQuery:
if (!ok) K_ReceiveFail();
break;
case CD_XSend:
if (ok) X_Sended();
else X_SendFail();
break;
case CD_XQuery:
if (!ok) X_ReceiveFail();
break;
case CD_CSend:
if (ok) C_Sended();
else C_SendFail();
break;
case CD_CQuery:
if (!ok) C_ReceiveFail();
break;
case CD_MSend:
if (ok) M_Sended();
else M_SendFail();
break;
case CD_MQuery:
if (!ok) M_ReceiveFail();
break;
default: break;
}
}
void CDCore::xTimerTick() {
//piCout << "x tick" << x_pult_side;
PIByteArray ba;
x_mutex.lock();
if (x_pult_side) {
ba = makeHeader(CD_XRequest, 0);
if (need_rebuild_x) {
x_selected = x_.collectX();
//piCout << "collectX" << x_selected.size();
need_rebuild_x = false;
}
ba << x_selected;
//piCout << "x pult send" << x_selected.size();
} else {
ba = makeHeader(CD_XValues, 0);
ba << x_selected;
piForeachC (PIDeque<int> & p, x_selected) {
x_[p].writeX(ba);
}
//piCout << "x app" << x_selected.size();
}
x_mutex.unlock();
sendDirect(ba);
}
void CDCore::piCoutFinished(int id, PIString * buffer) {
if (!buffer || !(id == 1)) return;
PIString sp = buffer->takeRange("[", "]");
PIDeque<int> p = CDCore::stringToPath(sp);
sendMessage(m_[p], Log, *buffer);
delete buffer;
}
void CDCore::initRoot(CDSection * r) {
r->name = "__root__";
r->alias = "root";
r->makePath();
r->calculate();
}
PIByteArray CDCore::makeHeader(CDPacketType type, int session_id) const {
PacketHeader h;
h.type = type;
h.session_id = session_id;
PIByteArray ret; ret << h;
return ret;
}
void CDCore::sendDirect(PIByteArray & ba) {
ba.push_front(header_direct);
connection.writeByName("cd", ba);
}
void CDCore::sendThreaded(PIByteArray & ba) {
if (sendt.isRunning()) {
piCoutObj << "Send in process, abort";
return;
}
send_data = ba;
sendt.startOnce();
}
void CDCore::procReceivedPacket(PIByteArray & ba) {
PacketHeader h;
ba >> h;
switch(h.type) {
case CD_Ping:
//piCoutObj << "ping";
break;
case CD_KQuery:
send(CDType::cdK);
break;
case CD_KSend: {
PIByteArray k;
ba >> k;
k << uchar(0);
PIString s = PIString::fromUTF8((const char *)k.data());
PIIOString ios(&s);
cd_read(&k_, &ios);
K_Received();
piCoutObj << "K received";
} break;
case CD_KDirectChange: {
PacketKDirectChange p;
ba >> p;
k_[p.path].setValue(p.value);
} break;
case CD_XQuery:
send(CDType::cdX);
break;
case CD_XSend: {
PIByteArray x;
ba >> x;
x << uchar(0);
PIString s = PIString::fromUTF8((const char *)x.data());
PIIOString ios(&s);
cd_read(&x_, &ios);
x_selected = x_.collectX();
X_Received();
piCoutObj << "X received";
} break;
case CD_XRequest: {
if (x_pult_side) break;
//break;
x_mutex.lock();
x_selected.clear();
ba >> x_selected;
//piCout << "X req" << x_selected.size();
x_.setSelectedX(false);
piForeachC (PIDeque<int> & p, x_selected) {
x_[p].x_enabled = true;
}
x_mutex.unlock();
} break;
case CD_XValues: {
if (!x_pult_side) break;
PIVector<PIDeque<int> > x_vals;
ba >> x_vals;
x_mutex.lock();
piForeachC (PIDeque<int> & p, x_vals) {
x_[p].readX(ba);
}
x_mutex.unlock();
X_ReceivedX(x_vals);
} break;
case CD_CQuery:
send(CDType::cdC);
break;
case CD_CSend: {
piCoutObj << "C received";
PIByteArray c;
ba >> c;
c << uchar(0);
PIString s = PIString::fromUTF8((const char *)c.data());
PIIOString ios(&s);
cd_read(&c_, &ios);
C_Received();
} break;
case CD_Command: {
piCoutObj << "C command";
PIDeque<int> p;
ba >> p;
if (p.isEmpty()) return;
PIString sp = pathToString(p);
OHPair h = c_handlers.value(sp, OHPair(0, 0));
//piCoutObj << "found" << sp << h.first;
if (h.first && h.second) h.second(h.first);
} break;
case CD_MQuery:
send(CDType::cdM);
break;
case CD_MSend: {
piCoutObj << "M received";
PIByteArray c;
ba >> c;
c << uchar(0);
PIString s = PIString::fromUTF8((const char *)c.data());
PIIOString ios(&s);
cd_read(&m_, &ios);
M_Received();
} break;
case CD_Message: {
PIDeque<int> p;
ba >> p;
piCoutObj << "M message" << p;
if (p.isEmpty()) return;
int t = 0;
PIString msg;
ba >> t >> msg;
//piCoutObj << "found" << sp << h.first;
//piCoutObj << "M message invoke";
M_Message(p, t, msg);
} break;
default: break;
}
}
void CDCore::raiseChangedGlobal(CDType::cdT cdt) {
switch (cdt) {
case CDType::cdK: K_ChangedGlobal(); break;
case CDType::cdX: X_ChangedGlobal(); break;
case CDType::cdC: C_ChangedGlobal(); break;
case CDType::cdM: M_ChangedGlobal(); break;
default: break;
}
}
PIString CDCore::pathToString(const PIDeque<int> & p) {
PIString ret;
for (int i = 0; i < p.size_s(); ++i) {
if (!ret.isEmpty()) ret += ".";
ret << p[i];
}
return ret;
}
PIDeque<int> CDCore::stringToPath(const PIString & p) {
PIDeque<int> ret;
PIStringList sl = p.split(".");
piForeachC (PIString & s, sl)
ret << s.toInt();
return ret;
}
void CDUtils::CDCore::dataReceived(const PIString & from, const PIByteArray & data) {
//piCoutObj << "dataReceived" << from << data.size();
PIIODevice * d = connection.deviceByName("cd");
if (d && d == connection.deviceByFullPath(from)) {
if (data.size() >= sizeof(4)) {
PIByteArray ba = data;
uchar header = ba.take_front();
if (header == header_transfer) {
datatr.received(ba);
}
if (header == header_direct) {
procReceivedPacket(ba);
}
}
}
}
void CDCore::dtSendRequest(PIByteArray & data) {
data.push_front(header_transfer);
connection.writeByName("cd", data);
//piCoutObj << "send" << data.size() << ret;
}
void CDCore::dtReceiveFinished(bool ok) {
if (!ok) return;
PIByteArray ba = datatr.data();
procReceivedPacket(ba);
}

View File

@@ -1,146 +1,147 @@
/*
CD Utils - Control-Debug utilites
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CDUTILS_CORE_H
#define CDUTILS_CORE_H
#include "cdutils_types.h"
#include "cdutils_protocol.h"
#include "piconnection.h"
#include "pidatatransfer.h"
namespace CDUtils {
class CDCore;
class __Core_Initializer__ {
public:
__Core_Initializer__();
~__Core_Initializer__();
static int count_;
static CDCore * __instance__;
};
class CDCore: public PIObject
{
PIOBJECT(CDUtils::CDCore)
friend class __Core_Initializer__;
friend class CDSection;
friend class Interface;
friend class XInterface;
public:
static CDCore * instance();
static bool destroy();
EVENT(K_Sended)
EVENT(K_SendFail)
EVENT(K_Received)
EVENT(K_ReceiveFail)
EVENT(K_ChangedGlobal)
EVENT_HANDLER2(void, K_DirectChange, PIDeque<int>, path, PIString, value);
EVENT(X_Sended)
EVENT(X_SendFail)
EVENT(X_Received)
EVENT(X_ReceiveFail)
EVENT(X_ChangedGlobal)
EVENT1(X_ReceivedX, PIVector<PIDeque<int> >, pathes)
EVENT(C_Sended)
EVENT(C_SendFail)
EVENT(C_Received)
EVENT(C_ReceiveFail)
EVENT(C_ChangedGlobal)
EVENT(M_Sended)
EVENT(M_SendFail)
EVENT(M_Received)
EVENT(M_ReceiveFail)
EVENT(M_ChangedGlobal)
EVENT3(M_Message, PIDeque<int>, path, int, type, PIString, msg)
void cd_write (CDSection * cd, PIIODevice * d);
void cd_read (CDSection * cd, PIIODevice * d);
void cd_parse (CDSection * cd, PIIODevice * d);
void cd_update (CDSection * cd, PIIODevice * d, UpdateModeFlags mode);
void cd_calculate(CDSection * cd);
void cd_send (CDSection * cd, CDPacketType pt, bool direct = false);
void send(CDType::cdT cdt);
void request(CDType::cdT cdt);
void initApp();
void initPult();
void init(const PIString & configuration, bool pult = false);
void stop();
void release();
void startX(double freq = 20.);
void stopX();
void sendCommand(const CDType & c);
void registerCHandler(const CDType & c, PIObject * o, Handler h);
bool inProgress() {return sendt.isRunning();}
void sendMessage(const CDType & m, MessageType mt, const PIString & msg);
CDSection * root(CDType::cdT cdt);
PIString typeLetter(CDType::cdT cdt);
static PIString pathToString(const PIDeque<int> & p);
static PIDeque<int> stringToPath(const PIString & p);
static PIString pultConfig() {return PIString(pult_config);}
static PIString appConfig() {return PIString(app_config);}
private:
CDCore();
~CDCore();
EVENT_HANDLER2(void, dataReceived, const PIString &, from, const PIByteArray &, data);
EVENT_HANDLER1(void, dtSendRequest, PIByteArray &, data);
EVENT_HANDLER1(void, dtReceiveFinished, bool, ok);
EVENT_HANDLER(void, sendThread);
EVENT_HANDLER(void, xTimerTick);
EVENT_HANDLER2(void, piCoutFinished, int, id, PIString*, buffer);
void initRoot(CDSection * r);
PIByteArray makeHeader(CDPacketType type, int session_id = 0) const;
void sendDirect(PIByteArray & ba);
void sendThreaded(PIByteArray & ba);
void procReceivedPacket(PIByteArray & ba);
void raiseChangedGlobal(CDType::cdT cdt);
typedef PIPair<PIObject * , Handler> OHPair;
static const char app_config[], pult_config[];
PIConnection connection;
PIDataTransfer datatr;
PIByteArray send_data;
PIThread sendt;
PITimer x_timer;
CDSection k_, x_, c_, m_;
PIMutex x_mutex;
PIVector<PIDeque<int> > x_selected;
PIMap<PIString, OHPair> c_handlers;
bool need_rebuild_x, x_pult_side;
};
static __Core_Initializer__ __Core_initializer__;
}
#endif // CDUTILS_CORE_H
/*
CD Utils - Control-Debug utilites
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CDUTILS_CORE_H
#define CDUTILS_CORE_H
#include "cdutils_types.h"
#include "cdutils_protocol.h"
#include "piconnection.h"
#include "pidatatransfer.h"
#include "cd_utils_export.h"
namespace CDUtils {
class CDCore;
class CD_UTILS_EXPORT __Core_Initializer__ {
public:
__Core_Initializer__();
~__Core_Initializer__();
static int count_;
static CDCore * __instance__;
};
class CD_UTILS_EXPORT CDCore: public PIObject
{
PIOBJECT(CDUtils::CDCore)
friend class __Core_Initializer__;
friend class CDSection;
friend class Interface;
friend class XInterface;
public:
static CDCore * instance();
static bool destroy();
EVENT(K_Sended)
EVENT(K_SendFail)
EVENT(K_Received)
EVENT(K_ReceiveFail)
EVENT(K_ChangedGlobal)
EVENT_HANDLER2(void, K_DirectChange, PIDeque<int>, path, PIString, value);
EVENT(X_Sended)
EVENT(X_SendFail)
EVENT(X_Received)
EVENT(X_ReceiveFail)
EVENT(X_ChangedGlobal)
EVENT1(X_ReceivedX, PIVector<PIDeque<int> >, pathes)
EVENT(C_Sended)
EVENT(C_SendFail)
EVENT(C_Received)
EVENT(C_ReceiveFail)
EVENT(C_ChangedGlobal)
EVENT(M_Sended)
EVENT(M_SendFail)
EVENT(M_Received)
EVENT(M_ReceiveFail)
EVENT(M_ChangedGlobal)
EVENT3(M_Message, PIDeque<int>, path, int, type, PIString, msg)
void cd_write (CDSection * cd, PIIODevice * d);
void cd_read (CDSection * cd, PIIODevice * d);
void cd_parse (CDSection * cd, PIIODevice * d);
void cd_update (CDSection * cd, PIIODevice * d, UpdateModeFlags mode);
void cd_calculate(CDSection * cd);
void cd_send (CDSection * cd, CDPacketType pt, bool direct = false);
void send(CDType::cdT cdt);
void request(CDType::cdT cdt);
void initApp();
void initPult();
void init(const PIString & configuration, bool pult = false);
void stop();
void release();
void startX(double freq = 20.);
void stopX();
void sendCommand(const CDType & c);
void registerCHandler(const CDType & c, PIObject * o, Handler h);
bool inProgress() {return sendt.isRunning();}
void sendMessage(const CDType & m, MessageType mt, const PIString & msg);
CDSection * root(CDType::cdT cdt);
PIString typeLetter(CDType::cdT cdt);
static PIString pathToString(const PIDeque<int> & p);
static PIDeque<int> stringToPath(const PIString & p);
static PIString pultConfig() {return PIString(pult_config);}
static PIString appConfig() {return PIString(app_config);}
private:
CDCore();
~CDCore();
EVENT_HANDLER2(void, dataReceived, const PIString &, from, const PIByteArray &, data);
EVENT_HANDLER1(void, dtSendRequest, PIByteArray &, data);
EVENT_HANDLER1(void, dtReceiveFinished, bool, ok);
EVENT_HANDLER(void, sendThread);
EVENT_HANDLER(void, xTimerTick);
EVENT_HANDLER2(void, piCoutFinished, int, id, PIString*, buffer);
void initRoot(CDSection * r);
PIByteArray makeHeader(CDPacketType type, int session_id = 0) const;
void sendDirect(PIByteArray & ba);
void sendThreaded(PIByteArray & ba);
void procReceivedPacket(PIByteArray & ba);
void raiseChangedGlobal(CDType::cdT cdt);
typedef PIPair<PIObject * , Handler> OHPair;
static const char app_config[], pult_config[];
PIConnection connection;
PIDataTransfer datatr;
PIByteArray send_data;
PIThread sendt;
PITimer x_timer;
CDSection k_, x_, c_, m_;
PIMutex x_mutex;
PIVector<PIDeque<int> > x_selected;
PIMap<PIString, OHPair> c_handlers;
bool need_rebuild_x, x_pult_side;
};
static __Core_Initializer__ __Core_initializer__;
}
#endif // CDUTILS_CORE_H

View File

@@ -1,217 +1,217 @@
#include "cdutils_interface.h"
#include "cdutils_core.h"
#include "piconfig.h"
#include "pifile.h"
using namespace CDUtils;
Interface::Interface(CDType::cdT type_) {
core = CDCore::instance();
s = core->root(type_);
type = type_;
//piCoutObj << (void*)this << core;
file_ = core->typeLetter(type_) + PIStringAscii(".dat");
file_size = 0;
switch (type) {
case CDType::cdK:
CONNECTU(core, K_Sended, this, sended);
CONNECTU(core, K_SendFail, this, sendFailed);
CONNECTU(core, K_Received, this, received);
CONNECTU(core, K_ReceiveFail, this, receiveFailed);
CONNECTU(core, K_ChangedGlobal, this, changedGlobal);
break;
case CDType::cdX:
CONNECTU(core, X_Sended, this, sended);
CONNECTU(core, X_SendFail, this, sendFailed);
CONNECTU(core, X_Received, this, received);
CONNECTU(core, X_ReceiveFail, this, receiveFailed);
CONNECTU(core, X_ChangedGlobal, this, changedGlobal);
break;
case CDType::cdC:
CONNECTU(core, C_Sended, this, sended);
CONNECTU(core, C_SendFail, this, sendFailed);
CONNECTU(core, C_Received, this, received);
CONNECTU(core, C_ReceiveFail, this, receiveFailed);
CONNECTU(core, C_ChangedGlobal, this, changedGlobal);
break;
case CDType::cdM:
CONNECTU(core, M_Sended, this, sended);
CONNECTU(core, M_SendFail, this, sendFailed);
CONNECTU(core, M_Received, this, received);
CONNECTU(core, M_ReceiveFail, this, receiveFailed);
CONNECTU(core, M_ChangedGlobal, this, changedGlobal);
break;
default: break;
}
}
bool Interface::test(int v) {
return s->test(v);
}
CDType & Interface::operator [](const PIString & name_) {
return (*s)[name_];
}
const CDType Interface::operator [](const PIString & name_) const {
return (*s)[name_];
}
CDType & Interface::operator [](const PIDeque<int> & path_) {
return (*s)[path_];
}
const CDType Interface::operator [](const PIDeque<int> & path_) const {
return (*s)[path_];
}
CDType & Interface::operator [](int v) {
//piCout << (void*)this << "[]" << core;
return (*s)[v];
}
const CDType Interface::operator [](int v) const {
//piCout << (void*)this << "[]" << core;
return (*s)[v];
}
CDSection & Interface::section(int v) {
// CDSection & ret = s->section(v);
// piCout << "[get section]" << v << ret.name;
return s->section(v);
}
const CDSection Interface::section(int v) const {
return s->section(v);
}
CDSection & Interface::section(const PIDeque<int> &path) {
PIDeque<int> spath = path;
CDSection * rs = s;
while (!spath.isEmpty()) {
rs = &(rs->section(spath.take_front()));
}
return *rs;
}
CDSection & Interface::root() {
return *s;
}
const CDSection & Interface::root() const {
return *s;
}
int Interface::count(bool recursive) const {
return s->count(recursive);
}
bool Interface::exists(PIDeque<int> path) const {
return s->exists(path);
}
void Interface::setFileName(const PIString & _file) {
file_ = _file;
}
bool Interface::configure(const PIString & config) {
PIConfig conf(config, PIIODevice::ReadOnly);
PIConfig::Entry & e(conf.getValue(core->typeLetter(s->cd_type_)));
bool ret = false;
setFileName(e.getValue("file", file(), &ret).toString());
return ret;
}
void Interface::reinitConnection(const PIString & configuration) {
core->init(configuration);
}
void Interface::releaseConnection() {
core->release();
}
void Interface::write(PIIODevice * d) {
core->cd_write(s, d);
}
void Interface::read(PIIODevice * d) {
core->cd_read(s, d);
}
void Interface::parse(PIIODevice * d) {
core->cd_parse(s, d);
}
void Interface::update(PIIODevice * d, UpdateModeFlags mode) {
core->cd_update(s, d, mode);
}
void Interface::calculate() {
core->cd_calculate(s);
}
PIString Interface::appConfig() {
return core->appConfig();
}
PIString Interface::pultConfig() {
return core->pultConfig();
}
void Interface::readFile() {
if (file_.isEmpty()) return;
PIFile f(file_, PIIODevice::ReadOnly);
read(&f);
file_size = f.size();
}
void Interface::writeFile() {
if (file_.isEmpty()) return;
PIFile f(file_, PIIODevice::ReadWrite);
f.clear();
write(&f);
file_size = f.size();
}
bool Interface::inProgress() {
return core->inProgress();
}
void Interface::send() {
core->send(type);
}
void Interface::request() {
core->request(type);
}
#include "cdutils_interface.h"
#include "cdutils_core.h"
#include "piconfig.h"
#include "pifile.h"
using namespace CDUtils;
Interface::Interface(CDType::cdT type_) {
core = CDCore::instance();
s = core->root(type_);
type = type_;
//piCoutObj << (void*)this << core;
file_ = core->typeLetter(type_) + PIStringAscii(".dat");
file_size = 0;
switch (type) {
case CDType::cdK:
CONNECTU(core, K_Sended, this, sended);
CONNECTU(core, K_SendFail, this, sendFailed);
CONNECTU(core, K_Received, this, received);
CONNECTU(core, K_ReceiveFail, this, receiveFailed);
CONNECTU(core, K_ChangedGlobal, this, changedGlobal);
break;
case CDType::cdX:
CONNECTU(core, X_Sended, this, sended);
CONNECTU(core, X_SendFail, this, sendFailed);
CONNECTU(core, X_Received, this, received);
CONNECTU(core, X_ReceiveFail, this, receiveFailed);
CONNECTU(core, X_ChangedGlobal, this, changedGlobal);
break;
case CDType::cdC:
CONNECTU(core, C_Sended, this, sended);
CONNECTU(core, C_SendFail, this, sendFailed);
CONNECTU(core, C_Received, this, received);
CONNECTU(core, C_ReceiveFail, this, receiveFailed);
CONNECTU(core, C_ChangedGlobal, this, changedGlobal);
break;
case CDType::cdM:
CONNECTU(core, M_Sended, this, sended);
CONNECTU(core, M_SendFail, this, sendFailed);
CONNECTU(core, M_Received, this, received);
CONNECTU(core, M_ReceiveFail, this, receiveFailed);
CONNECTU(core, M_ChangedGlobal, this, changedGlobal);
break;
default: break;
}
}
bool Interface::test(int v) {
return s->test(v);
}
CDType & Interface::operator [](const PIString & name_) {
return (*s)[name_];
}
const CDType Interface::operator [](const PIString & name_) const {
return (*s)[name_];
}
CDType & Interface::operator [](const PIDeque<int> & path_) {
return (*s)[path_];
}
const CDType Interface::operator [](const PIDeque<int> & path_) const {
return (*s)[path_];
}
CDType & Interface::operator [](int v) {
//piCout << (void*)this << "[]" << core;
return (*s)[v];
}
const CDType Interface::operator [](int v) const {
//piCout << (void*)this << "[]" << core;
return (*s)[v];
}
CDSection & Interface::section(int v) {
// CDSection & ret = s->section(v);
// piCout << "[get section]" << v << ret.name;
return s->section(v);
}
const CDSection Interface::section(int v) const {
return s->section(v);
}
CDSection & Interface::section(const PIDeque<int> &path) {
PIDeque<int> spath = path;
CDSection * rs = s;
while (!spath.isEmpty()) {
rs = &(rs->section(spath.take_front()));
}
return *rs;
}
CDSection & Interface::root() {
return *s;
}
const CDSection & Interface::root() const {
return *s;
}
int Interface::count(bool recursive) const {
return s->count(recursive);
}
bool Interface::exists(PIDeque<int> path) const {
return s->exists(path);
}
void Interface::setFileName(const PIString & _file) {
file_ = _file;
}
bool Interface::configure(const PIString & config) {
PIConfig conf(config, PIIODevice::ReadOnly);
PIConfig::Entry & e(conf.getValue(core->typeLetter(s->cd_type_)));
bool ret = false;
setFileName(e.getValue("file", file(), &ret).toString());
return ret;
}
void Interface::reinitConnection(const PIString & configuration) {
core->init(configuration);
}
void Interface::releaseConnection() {
core->release();
}
void Interface::write(PIIODevice * d) {
core->cd_write(s, d);
}
void Interface::read(PIIODevice * d) {
core->cd_read(s, d);
}
void Interface::parse(PIIODevice * d) {
core->cd_parse(s, d);
}
void Interface::update(PIIODevice * d, UpdateModeFlags mode) {
core->cd_update(s, d, mode);
}
void Interface::calculate() {
core->cd_calculate(s);
}
PIString Interface::appConfig() {
return core->appConfig();
}
PIString Interface::pultConfig() {
return core->pultConfig();
}
void Interface::readFile() {
if (file_.isEmpty()) return;
PIFile f(file_, PIIODevice::ReadOnly);
read(&f);
file_size = f.size();
}
void Interface::writeFile() {
if (file_.isEmpty()) return;
PIFile f(file_, PIIODevice::ReadWrite);
f.clear();
write(&f);
file_size = f.size();
}
bool Interface::inProgress() {
return core->inProgress();
}
void Interface::send() {
core->send(type);
}
void Interface::request() {
core->request(type);
}

View File

@@ -1,95 +1,96 @@
/*
CD Utils - Control-Debug utilites
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CDUTILS_INTERFACE_H
#define CDUTILS_INTERFACE_H
#include "cdutils_types.h"
#include "piobject.h"
namespace CDUtils {
class CDCore;
class Interface: public PIObject
{
PIOBJECT(CDUtils::Interface)
public:
Interface(CDType::cdT type_);
bool test(int v);
CDType & operator [](int v);
const CDType operator [](int v) const;
CDType & operator [](const PIString & name_);
const CDType operator [](const PIString & name_) const;
CDType & operator [](const PIDeque<int> & path_);
const CDType operator [](const PIDeque<int> & path_) const;
CDSection & section(int v);
const CDSection section(int v) const;
CDSection & section(const PIDeque<int> & path);
CDSection & root();
const CDSection & root() const;
int count(bool recursive = true) const;
const PIString file() const {return file_;}
int fileSize() const {return file_size;}
CDType::cdT cdType() const {return type;}
bool exists(PIDeque<int> path) const;
void setFileName(const PIString & _file);
bool configure(const PIString & config);
void reinitConnection(const PIString & configuration);
void releaseConnection();
void write(PIIODevice * d);
void read(PIIODevice * d);
void parse(PIIODevice * d);
void update(PIIODevice * d, UpdateModeFlags mode = SaveByName);
void calculate();
PIString appConfig();
PIString pultConfig();
void readFile();
void writeFile();
bool inProgress();
EVENT(sended)
EVENT(sendFailed)
EVENT(received)
EVENT(receiveFailed)
EVENT(changedGlobal)
EVENT_HANDLER(void, send);
EVENT_HANDLER(void, request);
protected:
CDCore * core;
CDSection * s;
CDType::cdT type;
PIString file_;
int file_size;
};
}
#endif // CDUTILS_INTERFACE_H
/*
CD Utils - Control-Debug utilites
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CDUTILS_INTERFACE_H
#define CDUTILS_INTERFACE_H
#include "cdutils_types.h"
#include "piobject.h"
#include "cd_utils_export.h"
namespace CDUtils {
class CDCore;
class CD_UTILS_EXPORT Interface: public PIObject
{
PIOBJECT(CDUtils::Interface)
public:
Interface(CDType::cdT type_);
bool test(int v);
CDType & operator [](int v);
const CDType operator [](int v) const;
CDType & operator [](const PIString & name_);
const CDType operator [](const PIString & name_) const;
CDType & operator [](const PIDeque<int> & path_);
const CDType operator [](const PIDeque<int> & path_) const;
CDSection & section(int v);
const CDSection section(int v) const;
CDSection & section(const PIDeque<int> & path);
CDSection & root();
const CDSection & root() const;
int count(bool recursive = true) const;
const PIString file() const {return file_;}
int fileSize() const {return file_size;}
CDType::cdT cdType() const {return type;}
bool exists(PIDeque<int> path) const;
void setFileName(const PIString & _file);
bool configure(const PIString & config);
void reinitConnection(const PIString & configuration);
void releaseConnection();
void write(PIIODevice * d);
void read(PIIODevice * d);
void parse(PIIODevice * d);
void update(PIIODevice * d, UpdateModeFlags mode = SaveByName);
void calculate();
PIString appConfig();
PIString pultConfig();
void readFile();
void writeFile();
bool inProgress();
EVENT(sended)
EVENT(sendFailed)
EVENT(received)
EVENT(receiveFailed)
EVENT(changedGlobal)
EVENT_HANDLER(void, send);
EVENT_HANDLER(void, request);
protected:
CDCore * core;
CDSection * s;
CDType::cdT type;
PIString file_;
int file_size;
};
}
#endif // CDUTILS_INTERFACE_H

View File

@@ -1,20 +1,20 @@
#include "cdutils_k.h"
#include "cdutils_core.h"
using namespace CDUtils;
KInterface K;
KInterface::KInterface(): Interface(CDType::cdK) {
}
void KInterface::directChange(const CDType & k) {
core->K_DirectChange(k.path(), k.value());
}
void KInterface::directChange(const CDType & k, double v) {
core->K_DirectChange(k.path(), PIString::fromNumber(v));
}
#include "cdutils_k.h"
#include "cdutils_core.h"
using namespace CDUtils;
KInterface K;
KInterface::KInterface(): Interface(CDType::cdK) {
}
void KInterface::directChange(const CDType & k) {
core->K_DirectChange(k.path(), k.value());
}
void KInterface::directChange(const CDType & k, double v) {
core->K_DirectChange(k.path(), PIString::fromNumber(v));
}

View File

@@ -1,46 +1,47 @@
/*
CD Utils - Control-Debug utilites
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CDUTILS_K_H
#define CDUTILS_K_H
#include "cdutils_interface.h"
namespace CDUtils {
class KInterface: public Interface
{
PIOBJECT_SUBCLASS(KInterface, Interface)
public:
KInterface();
EVENT1(keepNamesRequest, bool*, kn)
void directChange(const CDType & k);
void directChange(const CDType & k, double v);
};
}
extern CDUtils::KInterface K;
#endif // CDUTILS_K_H
/*
CD Utils - Control-Debug utilites
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CDUTILS_K_H
#define CDUTILS_K_H
#include "cdutils_interface.h"
#include "cd_utils_export.h"
namespace CDUtils {
class CD_UTILS_EXPORT KInterface: public Interface
{
PIOBJECT_SUBCLASS(KInterface, Interface)
public:
KInterface();
EVENT1(keepNamesRequest, bool*, kn)
void directChange(const CDType & k);
void directChange(const CDType & k, double v);
};
}
extern CD_UTILS_EXPORT CDUtils::KInterface K;
#endif // CDUTILS_K_H

View File

@@ -1,22 +1,22 @@
#include "cdutils_m.h"
#include "cdutils_core.h"
using namespace CDUtils;
MInterface M;
MInterface::MInterface(): Interface(CDType::cdM) {
CONNECTU(core, M_Message, this, messageReceived);
}
void MInterface::messageBox(const CDType & m, const PIString & msg) {
core->sendMessage(m, MessageBox, msg);
}
PICout MInterface::createPICout(const CDType & m) const {
PIString * buff = new PIString("[" + CDCore::pathToString(m.path()) + "]");
return PICout(buff, 1);
}
#include "cdutils_m.h"
#include "cdutils_core.h"
using namespace CDUtils;
MInterface M;
MInterface::MInterface(): Interface(CDType::cdM) {
CONNECTU(core, M_Message, this, messageReceived);
}
void MInterface::messageBox(const CDType & m, const PIString & msg) {
core->sendMessage(m, MessageBox, msg);
}
PICout MInterface::createPICout(const CDType & m) const {
PIString * buff = new PIString("[" + CDCore::pathToString(m.path()) + "]");
return PICout(buff, 1);
}

View File

@@ -1,55 +1,56 @@
/*
CD Utils - Control-Debug utilites
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CDUTILS_M_H
#define CDUTILS_M_H
#include "cdutils_interface.h"
namespace CDUtils {
class MInterface: public Interface
{
PIOBJECT_SUBCLASS(MInterface, Interface)
public:
MInterface();
PICout operator [](int v) {return createPICout((*s)[v]);}
PICout operator [](int v) const {return createPICout((*s)[v]);}
PICout operator [](const PIString & name_) {return createPICout((*s)[name_]);}
PICout operator [](const PIString & name_) const {return createPICout((*s)[name_]);}
PICout operator [](const PIDeque<int> & path_) {return createPICout((*s)[path_]);}
PICout operator [](const PIDeque<int> & path_) const {return createPICout((*s)[path_]);}
void messageBox(const CDType & m, const PIString & msg);
EVENT3(messageReceived, PIDeque<int>, path, int, type, PIString, msg)
private:
PICout createPICout(const CDType & m) const;
};
}
extern CDUtils::MInterface M;
#endif // CDUTILS_M_H
/*
CD Utils - Control-Debug utilites
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CDUTILS_M_H
#define CDUTILS_M_H
#include "cdutils_interface.h"
#include "cd_utils_export.h"
namespace CDUtils {
class CD_UTILS_EXPORT MInterface: public Interface
{
PIOBJECT_SUBCLASS(MInterface, Interface)
public:
MInterface();
PICout operator [](int v) {return createPICout((*s)[v]);}
PICout operator [](int v) const {return createPICout((*s)[v]);}
PICout operator [](const PIString & name_) {return createPICout((*s)[name_]);}
PICout operator [](const PIString & name_) const {return createPICout((*s)[name_]);}
PICout operator [](const PIDeque<int> & path_) {return createPICout((*s)[path_]);}
PICout operator [](const PIDeque<int> & path_) const {return createPICout((*s)[path_]);}
void messageBox(const CDType & m, const PIString & msg);
EVENT3(messageReceived, PIDeque<int>, path, int, type, PIString, msg)
private:
PICout createPICout(const CDType & m) const;
};
}
extern CD_UTILS_EXPORT CDUtils::MInterface M;
#endif // CDUTILS_M_H

View File

@@ -1,196 +1,196 @@
#include "cdutils_parser.h"
#include "cdutils_types.h"
#include "piiostring.h"
#include "piiobytearray.h"
#include "pifile.h"
using namespace CDUtils;
enum Phase {
eName = 1,
eBracketOpen,
eBracketClose,
eMemberName,
eMemberEqual,
eMemberValue,
eMemberComma,
eComment,
eMultiComment
};
void removeComment(PIString & line, PIString * type, PIString * comment) {
int ci = line.find("//");
if (ci >= 0) {
if (comment) *comment = line.right(line.size_s() - ci - 2);
line.cutRight(line.size_s() - ci).trim();
if (type && comment && !line.isEmpty()) {
*type = comment->takeLeft(1);
comment->trim();
}
}
}
void parseEnumLine(PIString & line, int * value, PIString * type, PIString * comment) {
removeComment(line, type, comment);
int ci = line.find("=");
if (ci >= 0) {
if (value) *value = line.right(line.size_s() - ci - 1).trim().toInt();
line.cutRight(line.size_s() - ci).trim();
}
if (line.trim().endsWith(",")) line.cutRight(1);
}
void parseInsert(PIString line, PIString & alias, PIStringList & out) {
out.clear();
int ci = line.find("=");
if (ci < 0) return;
alias = line.right(line.size_s() - ci - 1).trim();
line.cutRight(line.size_s() - ci).trim();
while (line.find("[") > 0) {
int is = line.find("["), ie = line.find("]");
PIString arr = line.mid(is + 1, ie - is - 1);
out << arr;
line.cutMid(is, ie - is + 1);
}
if (!line.isEmpty()) out.insert(0, line);
}
PIVector<int> enumValues(const PIString & e, const PIMap<PIString, CDSection> & sections, PIStringList & enames) {
PIVector<int> ret;
enames.clear();
if (sections.contains(e)) {
ret = sections[e].indexes();
enames = sections[e].index_names();
} else {
int v = e.toInt();
if (v < 2) return ret;
for (int i = 0; i < v; ++i) {
ret << i;
enames << "";//PIString::fromNumber(i);
}
}
return ret;
}
CDSection CDParser::parse(PIIODevice * d, int cdsection_type) {
CDType::cdT et = (CDType::cdT)cdsection_type;
if (!d) return CDSection(et);
if (!d->canRead()) return CDSection(et);
//piCout << "[CDSection] parse start";
CDSection cs(et);
CDType ck;
PIMap<PIString, CDSection> sections;
PIMap<PIString, int> enum_values;
PIString content, line, alias, type, comment;
PIStringList iarr;
if (PIStringAscii(d->className()) == PIStringAscii("PIFile")) {
PIByteArray c = ((PIFile*)d)->readAll();
c << uchar(0);
content = PIString::fromUTF8((const char *)c.data());
}
if (PIStringAscii(d->className()) == PIStringAscii("PIIOString")) content = *(((PIIOString*)d)->string());
if (PIStringAscii(d->className()) == PIStringAscii("PIIOByteArray")) content = PIString(*(((PIIOByteArray*)d)->byteArray()));
PIIOString ios(&content);
//int phase = 0;
int cind = -1;
while ((cind = content.find("enum", cind)) >= 0) {
ios.seek(cind);
line = ios.readLine().trim();
type.clear();
comment.clear();
removeComment(line, &type, &comment);
if (line.find("{") < 0) {
cind += 4;
continue;
}
line.cutLeft(line.find("enum") + 4).trim();
line.cutRight(line.size_s() - line.find("{")).trim();
if (line.isEmpty()) {
cind += 4;
continue;
}
cs = CDSection(et);
cs.name = line;
//piCout << "enum" << cs.name;
int cev = 0;
// cevalues.clear();
while (!ios.isEnd()) {
line = ios.readLine().trim();
comment.clear();
removeComment(line, &type, &comment);
if (line.find("}") >= 0) break;
if (line.isEmpty()) {
if (comment.find("=") >= 0) {
parseInsert(comment, alias, iarr);
if (!iarr.isEmpty()) {
// piCout << "#" << enum_values;
if (!enum_values.contains(alias)) {
piCout << "Parse error: can`t find section alias \"" << alias << "\"!";
return CDSection(et);
}
if (!sections.contains(iarr.front())) {
piCout << "Parse error: can`t find section \"" << iarr.front() << "\"!";
return CDSection(et);
}
//piCout << "insert" << alias << iarr;
int aval = enum_values.value(alias);
CDSection is = sections.value(iarr.take_front()), ts;
int ibpos = is.name.size_s();
piForeachRC (PIString & a, iarr) {
PIStringList enames;
PIVector<int> evals = enumValues(a, sections, enames);
//piCout << a << evals;
for (int i = 0; i < evals.size_s(); ++i) {
ts.section(evals[i]) = is;
ts.section(evals[i]).alias = enames[i];
}
ts.name = is.name;
ts.name.insert(ibpos, PIString("[") << a << "]");
is = ts;
ts = CDSection(et);
}
is.alias = alias;
cs.section(aval) = is;
}
}
} else {
parseEnumLine(line, &cev, &type, &comment);
//piCout << line << "=" << cev << "//" << type << comment;
ck = CDType(cev, line, type, "", "", comment, et);
if (type == "e") {
if (comment.startsWith("${")) {
comment.cutLeft(1);
PIString en = comment.inBrackets('{', '}');
comment.cutLeft(en.size_s() + 2).trim();
ck.setEnumValues(sections.value(en).enumValues());
ck.setComment(comment);
//piCout << "enum" << en << ck.enumValues();
}
}
cs[cev] = ck;
//cevalues[line] = cev;
enum_values[line] = cev;
++cev;
}
}
//piCout << cs.name << cs.k;
sections[cs.name] = cs;
// piCout << "#" << cevalues;
// enum_values << cevalues;
cind += 4;
}
// piCout << "[CDSection] parse end";
switch (et) {
case CDType::cdK: return sections.value("KDescription");
case CDType::cdX: return sections.value("XDescription");
case CDType::cdC: return sections.value("CDescription");
case CDType::cdM: return sections.value("MDescription");
default: return CDSection(et);
}
return CDSection(et);
}
#include "cdutils_parser.h"
#include "cdutils_types.h"
#include "piiostring.h"
#include "piiobytearray.h"
#include "pifile.h"
using namespace CDUtils;
enum Phase {
eName = 1,
eBracketOpen,
eBracketClose,
eMemberName,
eMemberEqual,
eMemberValue,
eMemberComma,
eComment,
eMultiComment
};
void removeComment(PIString & line, PIString * type, PIString * comment) {
int ci = line.find("//");
if (ci >= 0) {
if (comment) *comment = line.right(line.size_s() - ci - 2);
line.cutRight(line.size_s() - ci).trim();
if (type && comment && !line.isEmpty()) {
*type = comment->takeLeft(1);
comment->trim();
}
}
}
void parseEnumLine(PIString & line, int * value, PIString * type, PIString * comment) {
removeComment(line, type, comment);
int ci = line.find("=");
if (ci >= 0) {
if (value) *value = line.right(line.size_s() - ci - 1).trim().toInt();
line.cutRight(line.size_s() - ci).trim();
}
if (line.trim().endsWith(",")) line.cutRight(1);
}
void parseInsert(PIString line, PIString & alias, PIStringList & out) {
out.clear();
int ci = line.find("=");
if (ci < 0) return;
alias = line.right(line.size_s() - ci - 1).trim();
line.cutRight(line.size_s() - ci).trim();
while (line.find("[") > 0) {
int is = line.find("["), ie = line.find("]");
PIString arr = line.mid(is + 1, ie - is - 1);
out << arr;
line.cutMid(is, ie - is + 1);
}
if (!line.isEmpty()) out.insert(0, line);
}
PIVector<int> enumValues(const PIString & e, const PIMap<PIString, CDSection> & sections, PIStringList & enames) {
PIVector<int> ret;
enames.clear();
if (sections.contains(e)) {
ret = sections[e].indexes();
enames = sections[e].index_names();
} else {
int v = e.toInt();
if (v < 2) return ret;
for (int i = 0; i < v; ++i) {
ret << i;
enames << "";//PIString::fromNumber(i);
}
}
return ret;
}
CDSection CDParser::parse(PIIODevice * d, int cdsection_type) {
CDType::cdT et = (CDType::cdT)cdsection_type;
if (!d) return CDSection(et);
if (!d->canRead()) return CDSection(et);
//piCout << "[CDSection] parse start";
CDSection cs(et);
CDType ck;
PIMap<PIString, CDSection> sections;
PIMap<PIString, int> enum_values;
PIString content, line, alias, type, comment;
PIStringList iarr;
if (PIStringAscii(d->className()) == PIStringAscii("PIFile")) {
PIByteArray c = ((PIFile*)d)->readAll();
c << uchar(0);
content = PIString::fromUTF8((const char *)c.data());
}
if (PIStringAscii(d->className()) == PIStringAscii("PIIOString")) content = *(((PIIOString*)d)->string());
if (PIStringAscii(d->className()) == PIStringAscii("PIIOByteArray")) content = PIString(*(((PIIOByteArray*)d)->byteArray()));
PIIOString ios(&content);
//int phase = 0;
int cind = -1;
while ((cind = content.find("enum", cind)) >= 0) {
ios.seek(cind);
line = ios.readLine().trim();
type.clear();
comment.clear();
removeComment(line, &type, &comment);
if (line.find("{") < 0) {
cind += 4;
continue;
}
line.cutLeft(line.find("enum") + 4).trim();
line.cutRight(line.size_s() - line.find("{")).trim();
if (line.isEmpty()) {
cind += 4;
continue;
}
cs = CDSection(et);
cs.name = line;
//piCout << "enum" << cs.name;
int cev = 0;
// cevalues.clear();
while (!ios.isEnd()) {
line = ios.readLine().trim();
comment.clear();
removeComment(line, &type, &comment);
if (line.find("}") >= 0) break;
if (line.isEmpty()) {
if (comment.find("=") >= 0) {
parseInsert(comment, alias, iarr);
if (!iarr.isEmpty()) {
// piCout << "#" << enum_values;
if (!enum_values.contains(alias)) {
piCout << "Parse error: can`t find section alias \"" << alias << "\"!";
return CDSection(et);
}
if (!sections.contains(iarr.front())) {
piCout << "Parse error: can`t find section \"" << iarr.front() << "\"!";
return CDSection(et);
}
//piCout << "insert" << alias << iarr;
int aval = enum_values.value(alias);
CDSection is = sections.value(iarr.take_front()), ts;
int ibpos = is.name.size_s();
piForeachRC (PIString & a, iarr) {
PIStringList enames;
PIVector<int> evals = enumValues(a, sections, enames);
//piCout << a << evals;
for (int i = 0; i < evals.size_s(); ++i) {
ts.section(evals[i]) = is;
ts.section(evals[i]).alias = enames[i];
}
ts.name = is.name;
ts.name.insert(ibpos, PIString("[") << a << "]");
is = ts;
ts = CDSection(et);
}
is.alias = alias;
cs.section(aval) = is;
}
}
} else {
parseEnumLine(line, &cev, &type, &comment);
//piCout << line << "=" << cev << "//" << type << comment;
ck = CDType(cev, line, type, "", "", comment, et);
if (type == "e") {
if (comment.startsWith("${")) {
comment.cutLeft(1);
PIString en = comment.inBrackets('{', '}');
comment.cutLeft(en.size_s() + 2).trim();
ck.setEnumValues(sections.value(en).enumValues());
ck.setComment(comment);
//piCout << "enum" << en << ck.enumValues();
}
}
cs[cev] = ck;
//cevalues[line] = cev;
enum_values[line] = cev;
++cev;
}
}
//piCout << cs.name << cs.k;
sections[cs.name] = cs;
// piCout << "#" << cevalues;
// enum_values << cevalues;
cind += 4;
}
// piCout << "[CDSection] parse end";
switch (et) {
case CDType::cdK: return sections.value("KDescription");
case CDType::cdX: return sections.value("XDescription");
case CDType::cdC: return sections.value("CDescription");
case CDType::cdM: return sections.value("MDescription");
default: return CDSection(et);
}
return CDSection(et);
}

View File

@@ -1,38 +1,39 @@
/*
CD Utils - Control-Debug utilites
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CDUTILS_PARSER_H
#define CDUTILS_PARSER_H
class PIIODevice;
namespace CDUtils {
class CDSection;
namespace CDParser {
CDSection parse(PIIODevice * d, int cdsection_type);
}
}
#endif // CDUTILS_PARSER_H
/*
CD Utils - Control-Debug utilites
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CDUTILS_PARSER_H
#define CDUTILS_PARSER_H
#include "cd_utils_export.h"
class PIIODevice;
namespace CDUtils {
class CDSection;
namespace CDParser {
CD_UTILS_EXPORT CDSection parse(PIIODevice * d, int cdsection_type);
}
}
#endif // CDUTILS_PARSER_H

View File

@@ -1,72 +1,73 @@
/*
CD Utils - Control-Debug utilites
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CDUTILS_PROTOCOL_H
#define CDUTILS_PROTOCOL_H
#include "pibytearray.h"
namespace CDUtils {
enum CDPacketType {
CD_Ping,
CD_Pong,
CD_KQuery,
CD_KSend,
CD_KDirectChange,
CD_XQuery,
CD_XSend,
CD_XRequest,
CD_XValues,
CD_CQuery,
CD_CSend,
CD_Command,
CD_MQuery,
CD_MSend,
CD_Message,
};
# pragma pack(push,1)
struct PacketHeader {
int type; // CDPacketType
int session_id;
};
struct PacketKDirectChange {
PIDeque<int> path;
PIString value;
};
# pragma pack(pop)
inline PIByteArray & operator <<(PIByteArray & s, const PacketHeader & v) {s << v.type << v.session_id; return s;}
inline PIByteArray & operator >>(PIByteArray & s, PacketHeader & v) {s >> v.type >> v.session_id; return s;}
inline PIByteArray & operator <<(PIByteArray & s, const PacketKDirectChange & v) {s << v.path << v.value; return s;}
inline PIByteArray & operator >>(PIByteArray & s, PacketKDirectChange & v) {s >> v.path >> v.value; return s;}
}
#endif // CDUTILS_PROTOCOL_H
/*
CD Utils - Control-Debug utilites
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CDUTILS_PROTOCOL_H
#define CDUTILS_PROTOCOL_H
#include "pistring.h"
#include "cd_utils_export.h"
namespace CDUtils {
enum CDPacketType {
CD_Ping,
CD_Pong,
CD_KQuery,
CD_KSend,
CD_KDirectChange,
CD_XQuery,
CD_XSend,
CD_XRequest,
CD_XValues,
CD_CQuery,
CD_CSend,
CD_Command,
CD_MQuery,
CD_MSend,
CD_Message,
};
# pragma pack(push,1)
struct CD_UTILS_EXPORT PacketHeader {
int type; // CDPacketType
int session_id;
};
struct CD_UTILS_EXPORT PacketKDirectChange {
PIDeque<int> path;
PIString value;
};
# pragma pack(pop)
inline PIByteArray & operator <<(PIByteArray & s, const PacketHeader & v) {s << v.type << v.session_id; return s;}
inline PIByteArray & operator >>(PIByteArray & s, PacketHeader & v) {s >> v.type >> v.session_id; return s;}
inline PIByteArray & operator <<(PIByteArray & s, const PacketKDirectChange & v) {s << v.path << v.value; return s;}
inline PIByteArray & operator >>(PIByteArray & s, PacketKDirectChange & v) {s >> v.path >> v.value; return s;}
}
#endif // CDUTILS_PROTOCOL_H

View File

@@ -1,763 +1,762 @@
#include "cdutils_types.h"
#include "piconfig.h"
#include "pifile.h"
#include "pievaluator.h"
#include "cdutils_core.h"
using namespace CDUtils;
//int cdtype_debug_cnt = 1;
const int cd_x_history_max_size = 4000;
CDType::CDType() {
index_ = -1;
value_d = 0.;
value_i = 0;
value_b = calculated = x_enabled = false;
cd_type_ = cdNull;
parent = 0;
avg_size = 1;
mode_ = rmode_ = X_Current;
// debug_cnt = cdtype_debug_cnt;
// cdtype_debug_cnt++;
// piCout << "[CDType]" << "create Null" << debug_cnt;
}
CDType::CDType(int i, const PIString & n, const PIString & t, const PIString & v, const PIString & f, const PIString & c, cdT cd_t) {
index_ = i;
name_ = n.trimmed();
type_ = t.trimmed();
value_s = v.trimmed();
formula_ = f.trimmed();
comment_ = c.trimmed();
value_d = v.toDouble();
value_i = v.toInt();
value_b = v.toBool();
cd_type_ = cd_t;
calculated = x_enabled = false;
parent = 0;
avg_size = 1;
mode_ = rmode_ = X_Current;
if (type_ == "e") {
enum_values = parseEnumComment(comment_);
// piCout << enum_values.size() << enum_values;
}
// piCout << type_.size() << type_.toUTF8();
// piCout << formula_.size() << formula_.toUTF8();
// piCout << comment_.size() << comment_.toUTF8();
// debug_cnt = cdtype_debug_cnt;
// cdtype_debug_cnt++;
// piCout << "[CDType] create" << name_ << ":" << type_ << ":" << value_s << ":" << value_d << ":" << formula_ << ":" << comment_ << ":" << (cd_type_ == cdK);
}
CDType & CDType::operator =(double x) {
value_d = x;
value_i = x;
value_b = x > 0.;
if (mode_ == X_All_Avg) {
avg_h << x;
double val = 0;
if (avg_h.size_s() >= avg_size) {
for (int i = 0; i < avg_h.size_s(); i++)
val += avg_h[i];
val /= avg_h.size();
avg_h.clear();
if (history.size() < cd_x_history_max_size)
history << val;
}
}
return *this;
}
PIString CDType::type() const {
if (type_.trimmed().isEmpty()) return "f";
// piCout << "type =" << type_.trimmed() << ";" << type_ << "#";
return type_;
}
PIString CDType::value() const {
if (type_ == "b") return PIString::fromBool(value_b);
return value_s;
}
PIVariant CDType::variantValue() const {
if (type_.isEmpty()) return PIVariant(value());
switch (type_[0].toAscii()) {
case 'b': return PIVariant(toBool()); break;
case 'n': return PIVariant(toInt()); break;
case 'f': return PIVariant(toDouble()); break;
case 'c': return PIVariant(PIVariantTypes::Color(toInt())); break;
case 'e': {
PIVariantTypes::Enum e = enum_values;
e.selectValue(toInt());
return PIVariant(e);
break;
}
default: break;
}
return PIVariant(value());
}
void CDType::setValue(const PIString & value_) {
formula_ = value_;
value_d = formula_.toDouble();
value_i = formula_.toInt();
value_b = formula_.toBool();
}
void CDType::setVariantValue(const PIVariant & value_) {
setValue(PIString::fromNumber(value_.toDouble()));
}
void CDType::setFormula(const PIString & f) {
formula_ = f;
calculated = false;
//PIEvaluator e;
//calculate(&e);
}
PIStringList CDType::pathString() const {
PIStringList ret;
CDSection * ps = CDCore::instance()->root(cd_type_);
if (!ps) return ret;
for (int i = 0; i < path_.size_s() - 1; ++i) {
ps = &(ps->section(path_[i]));
if (!ps->alias.isEmpty()) ret << ps->alias;
else ret << PIString::fromNumber(path_[i]);
}
if (!name_.isEmpty()) ret << name_;
else ret << PIString::fromNumber(index_);
return ret;
}
void CDType::readX(PIByteArray & ba) {
if (ba.size() < 5) return;
uchar t(0); ba >> t;
rmode_ = (XMode)t;
switch (rmode_) {
case X_Current:
ba >> value_d;
break;
case X_All_Avg: {
PIVector<double> ah;
ba >> ah;
history << ah;
if (!history.isEmpty())
value_d = history.back();
} break;
default: break;
}
value_i = value_d;
value_b = value_d > 0.;
}
void CDType::writeX(PIByteArray & ba) {
ba << uchar(mode_);
switch (mode_) {
case X_Current:
ba << value_d;
break;
case X_All_Avg:
ba << history;
history.clear();
break;
default: break;
}
}
bool CDType::calculate(PIEvaluator * e, PIVector<const CDType * > stack) {
if (stack.contains(this)) {
error_ = "Circular dependencies: ";
piForeachC (CDType * k, stack)
error_ << k->name() << " -> ";
error_ << name();
//piCout << error_;
return false;
}
stack << this;
if (calculated) return true;
calculated = true;
error_.clear();
if (!parent) return true;
//piCout << "calc" << name_ << (parent ? parent->alias : "root");
value_s = formula_.trimmed();
for (;;) {
int ki = value_s.find("K[");
if (ki < 0) break;
int ke = value_s.find("]", ki + 2);
if (ke < 0) break;
PIString kp = value_s.mid(ki + 2, ke - ki - 2);
//piCout << kp;
CDType & k((*parent)[kp]);
k.calculate(e, stack);
value_s.replace(ki, ke - ki + 1, PIString::fromNumber(k.value_d));
}
value_d = formula_.toDouble();
value_i = formula_.toInt();
value_b = formula_.toBool();
double ev = 0.;
if (!e->check(value_s) && value_d == 0. && value_i == 0 && !value_b) {
PIString f = formula_.trimmed().toLowerCase();
if (f != "off" && f != "false" && f != "no" && !value_b) {
error_ = e->error();
return false;
}
} else
if (e->isCorrect())
ev = e->evaluate().real();
//piCout << value_s << value_i << value_d << ev;
//if ((value_d == 0.) || (piAbsd(value_d) < piAbsd(ev))) value_d = ev;
//if ((value_i == 0) || (piAbsd(value_i) < piAbsd(ev))) value_i = int(ev);
if ((value_d == 0.) || (ev != 0.)) value_d = ev;
if ((value_i == 0) || (ev != 0.)) value_i = int(ev);
value_b = value_b || (ev > 0.);
if (value_i != 0) {
if (value_d == 0.) value_d = value_i;
value_b = value_i > 0;
}
if (value_d != 0.) {
if (value_i == 0) value_i = value_d;
value_b = value_d > 0.;
}
if (value_b) {
if (value_d == 0.) value_d = 1.;
if (value_i == 0) value_i = 1;
}
value_s = PIString::fromNumber(value_d);
return true;
}
PIVariantTypes::Enum CDType::parseEnumComment(PIString c) {
PIVariantTypes::Enum ret;
if (c.isEmpty()) return ret;
if (type_ == "e") {
PIStringList sl = c.inBrackets('{', '}').split(",");
int cval = 0;
piForeach (PIString & s, sl) {
s.trim();
if (s.isEmpty()) continue;
if (s[0].isDigit()) {
int ind = s.find("-");
if (ind > 0) {
cval = s.left(ind).toInt();
s.cutLeft(ind + 1).trim();
}
}
ret << PIVariantTypes::Enumerator(cval, s);
++cval;
}
}
//piCout << c << "=" << ret;
return ret;
}
//CDType::CDType(const CDType &cdt) {
// index_ = cdt.index_;
// name_ = cdt.name_;
// type_ = cdt.type_;
// value_s = cdt.value_s;
// formula_ = cdt.formula_;
// comment_ = cdt.comment_;
// value_d = cdt.value_d;
// value_i = cdt.value_i;
// value_b = cdt.value_b;
// cd_type_ = cdt.cd_type_;
// debug_cnt = cdtype_debug_cnt;
// cdtype_debug_cnt++;
// piCout << "[CDType] copy" << debug_cnt << "->" << cdt.debug_cnt << index_ << ":" << name_ << ":" << type_ << ":" << value_s << ":" << value_d << ":" << formula_ << ":" << comment_ << ":" << (cd_type_ == cdK);
//}
//CDType &CDType::operator =(const CDType &cdt) {
// index_ = cdt.index_;
// name_ = cdt.name_;
// type_ = cdt.type_;
// value_s = cdt.value_s;
// formula_ = cdt.formula_;
// comment_ = cdt.comment_;
// value_d = cdt.value_d;
// value_i = cdt.value_i;
// value_b = cdt.value_b;
// cd_type_ = cdt.cd_type_;
// piCout << "[CDType] assign" << debug_cnt << "=" << cdt.debug_cnt << index_ << ":" << name_ << ":" << type_ << ":" << value_s << ":" << value_d << ":" << formula_ << ":" << comment_ << ":" << (cd_type_ == cdK);
// //debug_cnt = cdt.debug_cnt;
// return *this;
//}
//CDType::~CDType() {
// piCout << "[CDType] delete" << debug_cnt << index_ << ":" << name_ << ":" << type_ << ":" << value_s << ":" << value_d << ":" << formula_ << ":" << comment_ << ":" << (cd_type_ == cdK);
//}
CDSection::CDSection(CDType::cdT type_) {
cd_type_ = type_;
null.cd_type_ = type_;
}
CDSection & CDSection::section(int v) {
CDSection & ret(s[v]);
ret.cd_type_ = cd_type_;
return ret;
}
const CDSection CDSection::section(int v) const {
CDSection & ret(s[v]);
ret.cd_type_ = cd_type_;
return s[v];
}
bool CDSection::exists(PIDeque<int> path) const {
if (path.isEmpty()) return false;
if (path.size_s() == 1) return cd.contains(path[0]);
int si = path[0];
if (!s.contains(si)) return false;
path.remove(0, 1);
return s[si].exists(path);
}
int CDSection::count(bool recursive) const {
int ret = cd.size_s();
if (recursive) {
PIMap<int, CDSection>::const_iterator i;
for (i = s.constBegin(); i != s.constEnd(); ++i)
ret += i->second.count(recursive);
}
return ret;
}
int CDSection::sectionsCount() const {
return s.size();
}
PIStringList CDSection::index_names() const {
PIStringList ret;
PIMap<int, CDType>::const_iterator i;
for (i = cd.begin(); i != cd.end(); ++i)
ret << i->second.name();
return ret;
}
void CDSection::calculate() {
prepareCalculate();
if (cd_type_ != CDType::cdK) return;
PIEvaluator e;
calculateRecursive(&e);
}
CDType & CDSection::getByName(const PIString & name_) {
PIStringList np = name_.split(".");
if (np.isEmpty()) return null;
//piCout << np;
CDSection * cs = this, * ns = 0;
if (np.front().isEmpty()) {
if (np.size_s() < 2) return null;
cs = CDCore::instance()->root(cd_type_);
np.pop_front();
}
for (int i = 0; i < np.size_s() - 1; ++i) {
if (np[i].isEmpty()) return null;
bool isd = np[i][0].isDigit() || (np[i][0] == '-');
int dv = 0;
if (isd) dv = np[i].toInt();
ns = 0;
PIMap<int, CDSection>::iterator it;
//piCout << np[i] << isd << dv;
for (it = cs->s.begin(); it != cs->s.end(); ++it) {
bool f = false;
if (isd) f = (dv == it.key());
else f = (np[i] == it.value().alias);
//piCout << "s..." << it.key() << it.value().alias << f;
if (f) {
ns = &(it.value());
break;
}
}
//piCout << ns;
if (!ns) return null;
cs = ns;
}
PIMap<int, CDType>::iterator it;
if (np.back().isEmpty()) return null;
bool isd = np.back()[0].isDigit() || (np.back()[0] == '-');
int dv = 0;
if (isd) dv = np.back().toInt();
//piCout << np.back() << isd << dv;
for (it = cs->cd.begin(); it != cs->cd.end(); ++it) {
bool f = false;
if (isd) f = (dv == it.key());
else f = (np.back() == it.value().name());
//piCout << "k..." << it.key() << it.value().name() << f;
if (f)
return cs->cd[it.key()];
}
return null;
}
CDType & CDSection::getByPath(const PIDeque<int> & path_) {
if (path_.isEmpty()) return null;
CDSection * s = this;
for (int i = 0; i < path_.size_s() - 1; ++i)
s = &(s->section(path_[i]));
if (!s) return null;
return (*s)[path_.back()];
}
void CDSection::write(PIIODevice * d, const PIString & prefix) {
if (!d) return;
if (cd.isEmpty() && s.isEmpty()) return;
// piCout << "[CDSection] write start";
PIString l;
PIStringList cdtl;
cdtl << "null" << "k" << "x" << "c" << "m";
if (prefix.isEmpty()) l = "[" + cdtl[cd_type_] + "]";
else l = "[" + prefix + "." + cdtl[cd_type_] + "]";
l += "\n";
d->write(l.toUTF8());
l = "name = " + name + " \n";
d->write(l.toUTF8());
l = "alias = " + alias + " \n";
d->write(l.toUTF8());
PIMap<int, CDType>::iterator i;
for (i = cd.begin(); i != cd.end(); ++i) {
CDType & ck(i.value());
if (ck.cd_type() != cd_type_) continue;
switch (cd_type_) {
case CDType::cdNull: break;
case CDType::cdK:
l.clear(); l << ck.index() << ".f = " << ck.formula() << " #s " << ck.comment() << " \n";
d->write(l.toUTF8());
l.clear(); l << ck.index() << ".v = " << ck.value() << " #" << ck.type() << " " << ck.name() << " \n";
d->write(l.toUTF8());
if (!ck.enumValues().enum_list.isEmpty()) {
l.clear(); l << ck.index() << ".ev = {";
//PIVector<CDType::Enumerator> el = ck.enumValues();
piForeachC (PIVariantTypes::Enumerator & e, ck.enumValues().enum_list)
l << e.value << " - " << e.name << ", ";
l.cutRight(2);
l << "} \n";
d->write(l.toUTF8());
}
break;
case CDType::cdX:
l.clear(); l << ck.index() << ".name = " << ck.name() << " #s " << ck.comment() << " \n";
d->write(l.toUTF8());
l.clear(); l << ck.index() << ".mode = " << ck.xmode() << " #e (0 - cur, 1 - all_avg) " << "\n";
d->write(l.toUTF8());
l.clear(); l << ck.index() << ".avg = " << ck.avg() << " #n " << "\n";
d->write(l.toUTF8());
l.clear(); l << ck.index() << ".sel = " << (ck.isSelectedX() ? "1" : "0") << " #n " << "\n";
d->write(l.toUTF8());
break;
case CDType::cdC:
case CDType::cdM:
l.clear(); l << ck.index() << ".name = " << ck.name() << " #s " << ck.comment() << " \n";
d->write(l.toUTF8());
break;
}
}
if (!s.isEmpty()) {
if (prefix.isEmpty()) l = "s";
else l = prefix + ".s";
PIMap<int, CDSection>::iterator j;
for (j = s.begin(); j != s.end(); ++j) {
j.value().write(d, l + "." + PIString::fromNumber(j.key()));
}
}
if (prefix.isEmpty()) {
l = "[]\n";
d->write(l.toUTF8());
}
// piCout << "[CDSection] write end";
}
void CDSection::read(const void * ep) {
// piCout << "[CDSection] read start";
PIStringList cdtl;
cdtl << "null" << "k" << "x" << "c" << "m";
cd.clear();
s.clear();
PIConfig::Entry & e(*(PIConfig::Entry*)ep);
name = e.getValue(cdtl[cd_type_] + ".name").value();
alias = e.getValue(cdtl[cd_type_] + ".alias").value();
PIConfig::Entry & cdl = e.getValue(cdtl[cd_type_]);
for (int i = 0; i < cdl.childCount(); ++i) {
const PIConfig::Entry * e(cdl.child(i));
bool ok = false;
int id = e->name().toInt(-1, &ok);
// piCout << "[read]" << ke->name() << ke->value() << ok;
// PIString n = ke->getValue("v").comment();
// PIString t = n.takeLeft(1);
if (ok) {
CDType c;
PIString ev;
switch (cd_type_) {
case CDType::cdNull: break;
case CDType::cdK:
c = CDType(id, e->getValue("v").comment(), e->getValue("v").type(), e->getValue("v").value(), e->getValue("f").value(), e->getValue("f").comment(), cd_type_);
ev = e->getValue("ev", "").value();
if (!ev.isEmpty())
c.enum_values = c.parseEnumComment(ev);
break;
case CDType::cdX:
c = CDType(id, e->getValue("name").value(), PIString(), PIString(), PIString() , e->getValue("name").comment(), cd_type_);
c.setXMode((CDType::XMode)e->getValue("mode", int(CDType::X_Current)).value().toInt());
c.setAvg((CDType::XMode)e->getValue("avg", 1).value().toInt());
c.x_enabled = e->getValue("sel", false).value().toBool();
break;
case CDType::cdC:
case CDType::cdM:
c = CDType(id, e->getValue("name").value(), PIString(), PIString(), PIString() , e->getValue("name").comment(), cd_type_);
break;
}
cd[id] = c;
}
}
PIConfig::Entry & sl = e.getValue("s");
for (int i = 0; i < sl.childCount(); ++i) {
const PIConfig::Entry * se(sl.child(i));
int sid = se->name().toInt();
CDSection & rs(s[sid]);
rs.cd_type_ = cd_type_;
rs.read(se);
}
// piCout << "[CDSection] read end";
}
void CDSection::update(CDSection & v, UpdateModeFlags mode) {
if (mode[SaveByIndex] && mode[SaveByName]) {
piCout << "[CDSection] update error: SaveByIndex | SaveByName mode is denied!";
return;
}
//piCout << "[CDSection] update start";
//piCout << "before" << k.size() << v.k.size();
PIMap<int, PIString> prev_cd_f_bi;
PIMap<PIString, PIString> prev_cd_f_bn;
PIMap<int, CDType>::iterator i;
if (mode[SaveByIndex]) {
for (i = cd.begin(); i != cd.end(); ++i)
prev_cd_f_bi[i.key()] = i.value().formula();
}
if (mode[SaveByName]) {
for (i = cd.begin(); i != cd.end(); ++i)
prev_cd_f_bn[i.value().name_] = i.value().formula();
}
if (!mode[Merge])
cd.clear();
for (i = v.cd.begin(); i != v.cd.end(); ++i) {
int id = i.key();
PIString n = i.value().name();
cd[id] = i.value();
if (mode[SaveByIndex]) {
if (prev_cd_f_bi.contains(id))
cd[id].setFormula(prev_cd_f_bi[id]);
}
if (mode[SaveByName]) {
if (prev_cd_f_bn.contains(n))
cd[id].setFormula(prev_cd_f_bn[n]);
}
}
PIMap<int, CDSection> prev_s_bi;
PIMap<PIString, CDSection> prev_s_bn;
PIMap<int, CDSection>::iterator j;
if (mode[SaveByIndex]) {
for (j = s.begin(); j != s.end(); ++j)
prev_s_bi[j.key()] = j.value();
}
if (mode[SaveByName]) {
for (j = s.begin(); j != s.end(); ++j)
prev_s_bn[j.value().alias] = j.value();
}
if (!mode[Merge])
s.clear();
for (j = v.s.begin(); j != v.s.end(); ++j) {
int id = j.key();
PIString n = j.value().alias;
s[id] = j.value();
if (mode[SaveByIndex]) {
if (prev_s_bi.contains(id))
s[id] = prev_s_bi[id];
}
if (mode[SaveByName]) {
if (prev_s_bn.contains(n))
s[id] = prev_s_bn[n];
}
s[id].update(j.value(), mode);
}
/*PISet<int> used;
for (i = k.begin(); i != k.end(); ++i) {
if (v.k.contains(i.key())) {
PIString f = k[i.key()].formula_;
CDType & cdt = v.k[i.key()];
cdt.formula_ = f;
k[i.key()] = cdt;
used << i.key();
}
if (mode) {
CDType & ck(k[i.key()]);
if (prev_k_f_bn.contains(ck.name_))
ck.setFormula(prev_k_f_bn[ck.name_]);
}
}
//piCout << " after" << k.size();
for (i = v.k.begin(); i != v.k.end(); ++i) {
if (!used.contains(i.key()))
k[i.key()] = i.value();
CDType & ck(k[i.key()]);
ck.setFormula(prev_k_f_bn.value(ck.name_));
}
used.clear();
PIMap<int, CDSection>::iterator j;
for (j = s.begin(); j != s.end(); ++j) {
if (v.s.contains(j.key()))
j.value().update(v.s[j.key()], mode);
used << j.key();
}
for (j = v.s.begin(); j != v.s.end(); ++j) {
if (!used.contains(j.key()))
s[j.key()] = j.value();
}*/
// piCout << "[CDSection] update end";
}
bool CDSection::isSameStructure(CDSection & v) {
PIMap<PIString, int> cd_ids;
PIMap<int, CDType>::iterator i;
for (i = cd.begin(); i != cd.end(); ++i)
cd_ids[i.value().name()] = i.key();
for (i = v.cd.begin(); i != v.cd.end(); ++i) {
if (!cd_ids.contains(i.value().name())) continue;
//piCout << i.key() << k[i.key()].name() << i.value().name();
if (cd[cd_ids[i.value().name()]].index() != i.key())
return false;
}
PIMap<int, CDSection>::iterator j;
for (j = v.s.begin(); j != v.s.end(); ++j) {
if (!s.contains(j.key())) continue;
if (!s[j.key()].isSameStructure(j.value()))
return false;
}
return true;
}
void CDSection::prepareCalculate() {
PIMap<int, CDType>::iterator i;
for (i = cd.begin(); i != cd.end(); ++i) {
i.value().parent = this;
i.value().calculated = false;
}
PIMap<int, CDSection>::iterator j;
for (j = s.begin(); j != s.end(); ++j)
j.value().prepareCalculate();
}
void CDSection::calculateRecursive(PIEvaluator * e) {
PIMap<int, CDType>::iterator i;
for (i = cd.begin(); i != cd.end(); ++i)
i.value().calculate(e);
PIMap<int, CDSection>::iterator j;
for (j = s.begin(); j != s.end(); ++j)
j.value().calculateRecursive(e);
}
void CDSection::setSelectedX(bool yes) {
PIMap<int, CDType>::iterator i;
for (i = cd.begin(); i != cd.end(); ++i)
i.value().x_enabled = yes;
PIMap<int, CDSection>::iterator j;
for (j = s.begin(); j != s.end(); ++j)
j.value().setSelectedX(yes);
}
PIVector<PIDeque<int> > CDSection::collectX() const {
PIVector<PIDeque<int> > ret;
PIMap<int, CDType>::const_iterator i;
for (i = cd.begin(); i != cd.end(); ++i) {
if (i.value().x_enabled)
ret << i.value().path();
}
PIMap<int, CDSection>::const_iterator j;
for (j = s.constBegin(); j != s.constEnd(); ++j)
ret << j.value().collectX();
return ret;
}
void CDSection::makePath(PIDeque<int> p) {
PIDeque<int> tp;
PIMap<int, CDType>::iterator i;
for (i = cd.begin(); i != cd.end(); ++i) {
tp = p;
tp << i.key();
i.value().path_ = tp;
//piCout << "path for" << i.value().name() << tp;
}
PIMap<int, CDSection>::iterator j;
for (j = s.begin(); j != s.end(); ++j) {
tp = p;
tp << j.key();
j.value().makePath(tp);
}
}
PIVector<CDType * > CDSection::children(bool recursive) const {
PIVector<CDType * > ret;
PIMap<int, CDType>::const_iterator i;
for (i = cd.begin(); i != cd.end(); ++i)
ret << const_cast<CDType * >(&(i.value()));
if (!recursive) return ret;
PIMap<int, CDSection>::const_iterator j;
for (j = s.constBegin(); j != s.constEnd(); ++j)
ret << j.value().children(true);
return ret;
}
PIVariantTypes::Enum CDSection::enumValues() const {
PIVariantTypes::Enum ret;
PIMap<int, CDType>::const_iterator i;
for (i = cd.constBegin(); i != cd.constEnd(); ++i)
ret << PIVariantTypes::Enumerator(i.key(), i.value().name());
return ret;
}
#include "cdutils_types.h"
#include "piconfig.h"
#include "pifile.h"
#include "pievaluator.h"
#include "cdutils_core.h"
using namespace CDUtils;
//int cdtype_debug_cnt = 1;
const int cd_x_history_max_size = 4000;
CDType::CDType() {
index_ = -1;
value_d = 0.;
value_i = 0;
value_b = calculated = x_enabled = false;
cd_type_ = cdNull;
parent = 0;
avg_size = 1;
mode_ = rmode_ = X_Current;
// debug_cnt = cdtype_debug_cnt;
// cdtype_debug_cnt++;
// piCout << "[CDType]" << "create Null" << debug_cnt;
}
CDType::CDType(int i, const PIString & n, const PIString & t, const PIString & v, const PIString & f, const PIString & c, cdT cd_t) {
index_ = i;
name_ = n.trimmed();
type_ = t.trimmed();
value_s = v.trimmed();
formula_ = f.trimmed();
comment_ = c.trimmed();
value_d = v.toDouble();
value_i = v.toInt();
value_b = v.toBool();
cd_type_ = cd_t;
calculated = x_enabled = false;
parent = 0;
avg_size = 1;
mode_ = rmode_ = X_Current;
if (type_ == "e") {
enum_values = parseEnumComment(comment_);
// piCout << enum_values.size() << enum_values;
}
// piCout << type_.size() << type_.toUTF8();
// piCout << formula_.size() << formula_.toUTF8();
// piCout << comment_.size() << comment_.toUTF8();
// debug_cnt = cdtype_debug_cnt;
// cdtype_debug_cnt++;
// piCout << "[CDType] create" << name_ << ":" << type_ << ":" << value_s << ":" << value_d << ":" << formula_ << ":" << comment_ << ":" << (cd_type_ == cdK);
}
CDType & CDType::operator =(double x) {
value_d = x;
value_i = x;
value_b = x > 0.;
if (mode_ == X_All_Avg) {
avg_h << x;
double val = 0;
if (avg_h.size_s() >= avg_size) {
for (int i = 0; i < avg_h.size_s(); i++)
val += avg_h[i];
val /= avg_h.size();
avg_h.clear();
if (history.size() < cd_x_history_max_size)
history << val;
}
}
return *this;
}
PIString CDType::type() const {
if (type_.trimmed().isEmpty()) return "f";
// piCout << "type =" << type_.trimmed() << ";" << type_ << "#";
return type_;
}
PIString CDType::value() const {
if (type_ == "b") return PIString::fromBool(value_b);
return value_s;
}
PIVariant CDType::variantValue() const {
if (type_.isEmpty()) return PIVariant(value());
switch (type_[0].toAscii()) {
case 'b': return PIVariant(toBool()); break;
case 'n': return PIVariant(toInt()); break;
case 'f': return PIVariant(toDouble()); break;
case 'c': return PIVariant(PIVariantTypes::Color(toInt())); break;
case 'e': {
PIVariantTypes::Enum e = enum_values;
e.selectValue(toInt());
return PIVariant(e);
break;
}
default: break;
}
return PIVariant(value());
}
void CDType::setValue(const PIString & value_) {
formula_ = value_;
value_d = formula_.toDouble();
value_i = formula_.toInt();
value_b = formula_.toBool();
}
void CDType::setVariantValue(const PIVariant & value_) {
setValue(PIString::fromNumber(value_.toDouble()));
}
void CDType::setFormula(const PIString & f) {
formula_ = f;
calculated = false;
//PIEvaluator e;
//calculate(&e);
}
PIStringList CDType::pathString() const {
PIStringList ret;
CDSection * ps = CDCore::instance()->root(cd_type_);
if (!ps) return ret;
for (int i = 0; i < path_.size_s() - 1; ++i) {
ps = &(ps->section(path_[i]));
if (!ps->alias.isEmpty()) ret << ps->alias;
else ret << PIString::fromNumber(path_[i]);
}
if (!name_.isEmpty()) ret << name_;
else ret << PIString::fromNumber(index_);
return ret;
}
void CDType::readX(PIByteArray & ba) {
if (ba.size() < 5) return;
uchar t(0); ba >> t;
rmode_ = (XMode)t;
switch (rmode_) {
case X_Current:
ba >> value_d;
break;
case X_All_Avg: {
PIVector<double> ah;
ba >> ah;
history << ah;
if (!history.isEmpty())
value_d = history.back();
} break;
default: break;
}
value_i = value_d;
value_b = value_d > 0.;
}
void CDType::writeX(PIByteArray & ba) {
ba << uchar(mode_);
switch (mode_) {
case X_Current:
ba << value_d;
break;
case X_All_Avg:
ba << history;
history.clear();
break;
default: break;
}
}
bool CDType::calculate(PIEvaluator * e, PIVector<const CDType * > stack) {
if (stack.contains(this)) {
error_ = "Circular dependencies: ";
piForeachC (CDType * k, stack)
error_ << k->name() << " -> ";
error_ << name();
//piCout << error_;
return false;
}
stack << this;
if (calculated) return true;
calculated = true;
error_.clear();
if (!parent) return true;
//piCout << "calc" << name_ << (parent ? parent->alias : "root");
value_s = formula_.trimmed();
for (;;) {
int ki = value_s.find("K[");
if (ki < 0) break;
int ke = value_s.find("]", ki + 2);
if (ke < 0) break;
PIString kp = value_s.mid(ki + 2, ke - ki - 2);
//piCout << kp;
CDType & k((*parent)[kp]);
k.calculate(e, stack);
value_s.replace(ki, ke - ki + 1, PIString::fromNumber(k.value_d));
}
value_d = formula_.toDouble();
value_i = formula_.toInt();
value_b = formula_.toBool();
double ev = 0.;
if (!e->check(value_s) && value_d == 0. && value_i == 0 && !value_b) {
PIString f = formula_.trimmed().toLowerCase();
if (f != "off" && f != "false" && f != "no" && !value_b) {
error_ = e->error();
return false;
}
} else
if (e->isCorrect())
ev = e->evaluate().real();
//piCout << value_s << value_i << value_d << ev;
//if ((value_d == 0.) || (piAbsd(value_d) < piAbsd(ev))) value_d = ev;
//if ((value_i == 0) || (piAbsd(value_i) < piAbsd(ev))) value_i = int(ev);
if ((value_d == 0.) || (ev != 0.)) value_d = ev;
if ((value_i == 0) || (ev != 0.)) value_i = int(ev);
value_b = value_b || (ev > 0.);
if (value_i != 0) {
if (value_d == 0.) value_d = value_i;
value_b = value_i > 0;
}
if (value_d != 0.) {
if (value_i == 0) value_i = value_d;
value_b = value_d > 0.;
}
if (value_b) {
if (value_d == 0.) value_d = 1.;
if (value_i == 0) value_i = 1;
}
value_s = PIString::fromNumber(value_d);
return true;
}
PIVariantTypes::Enum CDType::parseEnumComment(PIString c) {
PIVariantTypes::Enum ret;
if (c.isEmpty()) return ret;
if (type_ == "e") {
PIStringList sl = c.inBrackets('{', '}').split(",");
int cval = 0;
piForeach (PIString & s, sl) {
s.trim();
if (s.isEmpty()) continue;
if (s[0].isDigit()) {
int ind = s.find("-");
if (ind > 0) {
cval = s.left(ind).toInt();
s.cutLeft(ind + 1).trim();
}
}
ret << PIVariantTypes::Enumerator(cval, s);
++cval;
}
}
//piCout << c << "=" << ret;
return ret;
}
//CDType::CDType(const CDType &cdt) {
// index_ = cdt.index_;
// name_ = cdt.name_;
// type_ = cdt.type_;
// value_s = cdt.value_s;
// formula_ = cdt.formula_;
// comment_ = cdt.comment_;
// value_d = cdt.value_d;
// value_i = cdt.value_i;
// value_b = cdt.value_b;
// cd_type_ = cdt.cd_type_;
// debug_cnt = cdtype_debug_cnt;
// cdtype_debug_cnt++;
// piCout << "[CDType] copy" << debug_cnt << "->" << cdt.debug_cnt << index_ << ":" << name_ << ":" << type_ << ":" << value_s << ":" << value_d << ":" << formula_ << ":" << comment_ << ":" << (cd_type_ == cdK);
//}
//CDType &CDType::operator =(const CDType &cdt) {
// index_ = cdt.index_;
// name_ = cdt.name_;
// type_ = cdt.type_;
// value_s = cdt.value_s;
// formula_ = cdt.formula_;
// comment_ = cdt.comment_;
// value_d = cdt.value_d;
// value_i = cdt.value_i;
// value_b = cdt.value_b;
// cd_type_ = cdt.cd_type_;
// piCout << "[CDType] assign" << debug_cnt << "=" << cdt.debug_cnt << index_ << ":" << name_ << ":" << type_ << ":" << value_s << ":" << value_d << ":" << formula_ << ":" << comment_ << ":" << (cd_type_ == cdK);
// //debug_cnt = cdt.debug_cnt;
// return *this;
//}
//CDType::~CDType() {
// piCout << "[CDType] delete" << debug_cnt << index_ << ":" << name_ << ":" << type_ << ":" << value_s << ":" << value_d << ":" << formula_ << ":" << comment_ << ":" << (cd_type_ == cdK);
//}
CDSection::CDSection(CDType::cdT type_) {
cd_type_ = type_;
null.cd_type_ = type_;
}
CDSection & CDSection::section(int v) {
CDSection & ret(s[v]);
ret.cd_type_ = cd_type_;
return ret;
}
const CDSection CDSection::section(int v) const {
CDSection & ret(s[v]);
ret.cd_type_ = cd_type_;
return s[v];
}
bool CDSection::exists(PIDeque<int> path) const {
if (path.isEmpty()) return false;
if (path.size_s() == 1) return cd.contains(path[0]);
int si = path[0];
if (!s.contains(si)) return false;
path.remove(0, 1);
return s[si].exists(path);
}
int CDSection::count(bool recursive) const {
int ret = cd.size_s();
if (recursive) {
PIMap<int, CDSection>::const_iterator i;
for (i = s.constBegin(); i != s.constEnd(); ++i)
ret += i->second.count(recursive);
}
return ret;
}
int CDSection::sectionsCount() const {
return s.size();
}
PIStringList CDSection::index_names() const {
PIStringList ret;
auto i = cd.makeIterator();
while (i.next())
ret << i.value().name();
return ret;
}
void CDSection::calculate() {
prepareCalculate();
if (cd_type_ != CDType::cdK) return;
PIEvaluator e;
calculateRecursive(&e);
}
CDType & CDSection::getByName(const PIString & name_) {
PIStringList np = name_.split(".");
if (np.isEmpty()) return null;
//piCout << np;
CDSection * cs = this, * ns = 0;
if (np.front().isEmpty()) {
if (np.size_s() < 2) return null;
cs = CDCore::instance()->root(cd_type_);
np.pop_front();
}
for (int i = 0; i < np.size_s() - 1; ++i) {
if (np[i].isEmpty()) return null;
bool isd = np[i][0].isDigit() || (np[i][0] == '-');
int dv = 0;
if (isd) dv = np[i].toInt();
ns = 0;
auto it = cs->s.makeIterator();
while (it.next()) {
bool f = false;
if (isd) f = (dv == it.key());
else f = (np[i] == it.value().alias);
//piCout << "s..." << it.key() << it.value().alias << f;
if (f) {
ns = &(it.valueRef());
break;
}
}
//piCout << ns;
if (!ns) return null;
cs = ns;
}
if (np.back().isEmpty()) return null;
bool isd = np.back()[0].isDigit() || (np.back()[0] == '-');
int dv = 0;
if (isd) dv = np.back().toInt();
//piCout << np.back() << isd << dv;
auto it = cs->cd.makeIterator();
while (it.next()) {
bool f = false;
if (isd) f = (dv == it.key());
else f = (np.back() == it.value().name());
//piCout << "k..." << it.key() << it.value().name() << f;
if (f)
return cs->cd[it.key()];
}
return null;
}
CDType & CDSection::getByPath(const PIDeque<int> & path_) {
if (path_.isEmpty()) return null;
CDSection * s = this;
for (int i = 0; i < path_.size_s() - 1; ++i)
s = &(s->section(path_[i]));
if (!s) return null;
return (*s)[path_.back()];
}
void CDSection::write(PIIODevice * d, const PIString & prefix) {
if (!d) return;
if (cd.isEmpty() && s.isEmpty()) return;
// piCout << "[CDSection] write start";
PIString l;
PIStringList cdtl;
cdtl << "null" << "k" << "x" << "c" << "m";
if (prefix.isEmpty()) l = "[" + cdtl[cd_type_] + "]";
else l = "[" + prefix + "." + cdtl[cd_type_] + "]";
l += "\n";
d->write(l.toUTF8());
l = "name = " + name + " \n";
d->write(l.toUTF8());
l = "alias = " + alias + " \n";
d->write(l.toUTF8());
auto i = cd.makeIterator();
while (i.next()) {
const CDType & ck(i.value());
if (ck.cd_type() != cd_type_) continue;
switch (cd_type_) {
case CDType::cdNull: break;
case CDType::cdK:
l.clear(); l << ck.index() << ".f = " << ck.formula() << " #s " << ck.comment() << " \n";
d->write(l.toUTF8());
l.clear(); l << ck.index() << ".v = " << ck.value() << " #" << ck.type() << " " << ck.name() << " \n";
d->write(l.toUTF8());
if (!ck.enumValues().enum_list.isEmpty()) {
l.clear(); l << ck.index() << ".ev = {";
//PIVector<CDType::Enumerator> el = ck.enumValues();
piForeachC (PIVariantTypes::Enumerator & e, ck.enumValues().enum_list)
l << e.value << " - " << e.name << ", ";
l.cutRight(2);
l << "} \n";
d->write(l.toUTF8());
}
break;
case CDType::cdX:
l.clear(); l << ck.index() << ".name = " << ck.name() << " #s " << ck.comment() << " \n";
d->write(l.toUTF8());
l.clear(); l << ck.index() << ".mode = " << ck.xmode() << " #e (0 - cur, 1 - all_avg) " << "\n";
d->write(l.toUTF8());
l.clear(); l << ck.index() << ".avg = " << ck.avg() << " #n " << "\n";
d->write(l.toUTF8());
l.clear(); l << ck.index() << ".sel = " << (ck.isSelectedX() ? "1" : "0") << " #n " << "\n";
d->write(l.toUTF8());
break;
case CDType::cdC:
case CDType::cdM:
l.clear(); l << ck.index() << ".name = " << ck.name() << " #s " << ck.comment() << " \n";
d->write(l.toUTF8());
break;
}
}
if (!s.isEmpty()) {
if (prefix.isEmpty()) l = "s";
else l = prefix + ".s";
auto j = s.makeIterator();
while (j.next()) {
j.valueRef().write(d, l + "." + PIString::fromNumber(j.key()));
}
}
if (prefix.isEmpty()) {
l = "[]\n";
d->write(l.toUTF8());
}
// piCout << "[CDSection] write end";
}
void CDSection::read(const void * ep) {
// piCout << "[CDSection] read start";
PIStringList cdtl;
cdtl << "null" << "k" << "x" << "c" << "m";
cd.clear();
s.clear();
PIConfig::Entry & e(*(PIConfig::Entry*)ep);
name = e.getValue(cdtl[cd_type_] + ".name").value();
alias = e.getValue(cdtl[cd_type_] + ".alias").value();
PIConfig::Entry & cdl = e.getValue(cdtl[cd_type_]);
for (int i = 0; i < cdl.childCount(); ++i) {
const PIConfig::Entry * e(cdl.child(i));
bool ok = false;
int id = e->name().toInt(-1, &ok);
// piCout << "[read]" << ke->name() << ke->value() << ok;
// PIString n = ke->getValue("v").comment();
// PIString t = n.takeLeft(1);
if (ok) {
CDType c;
PIString ev;
switch (cd_type_) {
case CDType::cdNull: break;
case CDType::cdK:
c = CDType(id, e->getValue("v").comment(), e->getValue("v").type(), e->getValue("v").value(), e->getValue("f").value(), e->getValue("f").comment(), cd_type_);
ev = e->getValue("ev", "").value();
if (!ev.isEmpty())
c.enum_values = c.parseEnumComment(ev);
break;
case CDType::cdX:
c = CDType(id, e->getValue("name").value(), PIString(), PIString(), PIString() , e->getValue("name").comment(), cd_type_);
c.setXMode((CDType::XMode)e->getValue("mode", int(CDType::X_Current)).value().toInt());
c.setAvg((CDType::XMode)e->getValue("avg", 1).value().toInt());
c.x_enabled = e->getValue("sel", false).value().toBool();
break;
case CDType::cdC:
case CDType::cdM:
c = CDType(id, e->getValue("name").value(), PIString(), PIString(), PIString() , e->getValue("name").comment(), cd_type_);
break;
}
cd[id] = c;
}
}
PIConfig::Entry & sl = e.getValue("s");
for (int i = 0; i < sl.childCount(); ++i) {
const PIConfig::Entry * se(sl.child(i));
int sid = se->name().toInt();
CDSection & rs(s[sid]);
rs.cd_type_ = cd_type_;
rs.read(se);
}
// piCout << "[CDSection] read end";
}
void CDSection::update(CDSection & v, UpdateModeFlags mode) {
if (mode[SaveByIndex] && mode[SaveByName]) {
piCout << "[CDSection] update error: SaveByIndex | SaveByName mode is denied!";
return;
}
//piCout << "[CDSection] update start";
//piCout << "before" << k.size() << v.k.size();
PIMap<int, PIString> prev_cd_f_bi;
PIMap<PIString, PIString> prev_cd_f_bn;
PIMap<int, CDType>::iterator i;
if (mode[SaveByIndex]) {
for (i = cd.begin(); i != cd.end(); ++i)
prev_cd_f_bi[i.key()] = i.value().formula();
}
if (mode[SaveByName]) {
for (i = cd.begin(); i != cd.end(); ++i)
prev_cd_f_bn[i.value().name_] = i.value().formula();
}
if (!mode[Merge])
cd.clear();
for (i = v.cd.begin(); i != v.cd.end(); ++i) {
int id = i.key();
PIString n = i.value().name();
cd[id] = i.value();
if (mode[SaveByIndex]) {
if (prev_cd_f_bi.contains(id))
cd[id].setFormula(prev_cd_f_bi[id]);
}
if (mode[SaveByName]) {
if (prev_cd_f_bn.contains(n))
cd[id].setFormula(prev_cd_f_bn[n]);
}
}
PIMap<int, CDSection> prev_s_bi;
PIMap<PIString, CDSection> prev_s_bn;
PIMap<int, CDSection>::iterator j;
if (mode[SaveByIndex]) {
for (j = s.begin(); j != s.end(); ++j)
prev_s_bi[j.key()] = j.value();
}
if (mode[SaveByName]) {
for (j = s.begin(); j != s.end(); ++j)
prev_s_bn[j.value().alias] = j.value();
}
if (!mode[Merge])
s.clear();
for (j = v.s.begin(); j != v.s.end(); ++j) {
int id = j.key();
PIString n = j.value().alias;
s[id] = j.value();
if (mode[SaveByIndex]) {
if (prev_s_bi.contains(id))
s[id] = prev_s_bi[id];
}
if (mode[SaveByName]) {
if (prev_s_bn.contains(n))
s[id] = prev_s_bn[n];
}
s[id].update(j.value(), mode);
}
/*PISet<int> used;
for (i = k.begin(); i != k.end(); ++i) {
if (v.k.contains(i.key())) {
PIString f = k[i.key()].formula_;
CDType & cdt = v.k[i.key()];
cdt.formula_ = f;
k[i.key()] = cdt;
used << i.key();
}
if (mode) {
CDType & ck(k[i.key()]);
if (prev_k_f_bn.contains(ck.name_))
ck.setFormula(prev_k_f_bn[ck.name_]);
}
}
//piCout << " after" << k.size();
for (i = v.k.begin(); i != v.k.end(); ++i) {
if (!used.contains(i.key()))
k[i.key()] = i.value();
CDType & ck(k[i.key()]);
ck.setFormula(prev_k_f_bn.value(ck.name_));
}
used.clear();
PIMap<int, CDSection>::iterator j;
for (j = s.begin(); j != s.end(); ++j) {
if (v.s.contains(j.key()))
j.value().update(v.s[j.key()], mode);
used << j.key();
}
for (j = v.s.begin(); j != v.s.end(); ++j) {
if (!used.contains(j.key()))
s[j.key()] = j.value();
}*/
// piCout << "[CDSection] update end";
}
bool CDSection::isSameStructure(CDSection & v) {
PIMap<PIString, int> cd_ids;
PIMap<int, CDType>::iterator i;
for (i = cd.begin(); i != cd.end(); ++i)
cd_ids[i.value().name()] = i.key();
for (i = v.cd.begin(); i != v.cd.end(); ++i) {
if (!cd_ids.contains(i.value().name())) continue;
//piCout << i.key() << k[i.key()].name() << i.value().name();
if (cd[cd_ids[i.value().name()]].index() != i.key())
return false;
}
PIMap<int, CDSection>::iterator j;
for (j = v.s.begin(); j != v.s.end(); ++j) {
if (!s.contains(j.key())) continue;
if (!s[j.key()].isSameStructure(j.value()))
return false;
}
return true;
}
void CDSection::prepareCalculate() {
PIMap<int, CDType>::iterator i;
for (i = cd.begin(); i != cd.end(); ++i) {
i.value().parent = this;
i.value().calculated = false;
}
PIMap<int, CDSection>::iterator j;
for (j = s.begin(); j != s.end(); ++j)
j.value().prepareCalculate();
}
void CDSection::calculateRecursive(PIEvaluator * e) {
PIMap<int, CDType>::iterator i;
for (i = cd.begin(); i != cd.end(); ++i)
i.value().calculate(e);
PIMap<int, CDSection>::iterator j;
for (j = s.begin(); j != s.end(); ++j)
j.value().calculateRecursive(e);
}
void CDSection::setSelectedX(bool yes) {
PIMap<int, CDType>::iterator i;
for (i = cd.begin(); i != cd.end(); ++i)
i.value().x_enabled = yes;
PIMap<int, CDSection>::iterator j;
for (j = s.begin(); j != s.end(); ++j)
j.value().setSelectedX(yes);
}
PIVector<PIDeque<int> > CDSection::collectX() const {
PIVector<PIDeque<int> > ret;
PIMap<int, CDType>::const_iterator i;
for (i = cd.begin(); i != cd.end(); ++i) {
if (i.value().x_enabled)
ret << i.value().path();
}
PIMap<int, CDSection>::const_iterator j;
for (j = s.constBegin(); j != s.constEnd(); ++j)
ret << j.value().collectX();
return ret;
}
void CDSection::makePath(PIDeque<int> p) {
PIDeque<int> tp;
PIMap<int, CDType>::iterator i;
for (i = cd.begin(); i != cd.end(); ++i) {
tp = p;
tp << i.key();
i.value().path_ = tp;
//piCout << "path for" << i.value().name() << tp;
}
PIMap<int, CDSection>::iterator j;
for (j = s.begin(); j != s.end(); ++j) {
tp = p;
tp << j.key();
j.value().makePath(tp);
}
}
PIVector<CDType * > CDSection::children(bool recursive) const {
PIVector<CDType * > ret;
PIMap<int, CDType>::const_iterator i;
for (i = cd.begin(); i != cd.end(); ++i)
ret << const_cast<CDType * >(&(i.value()));
if (!recursive) return ret;
PIMap<int, CDSection>::const_iterator j;
for (j = s.constBegin(); j != s.constEnd(); ++j)
ret << j.value().children(true);
return ret;
}
PIVariantTypes::Enum CDSection::enumValues() const {
PIVariantTypes::Enum ret;
PIMap<int, CDType>::const_iterator i;
for (i = cd.constBegin(); i != cd.constEnd(); ++i)
ret << PIVariantTypes::Enumerator(i.key(), i.value().name());
return ret;
}

View File

@@ -1,192 +1,193 @@
/*
CD Utils - Control-Debug utilites
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CDUTILS_TYPES_H
#define CDUTILS_TYPES_H
#include "pistring.h"
#include "pimap.h"
#include "pivariant.h"
class PIIODevice;
class PIEvaluator;
class CD_Pult;
class CDItem;
class CDItemModel;
namespace CDUtils {
class CDSection;
enum UpdateMode {
SaveByIndex = 0x01,
SaveByName = 0x02,
Merge = 0x04
};
enum MessageType {
Log = 1,
MessageBox,
};
typedef PIFlags<UpdateMode> UpdateModeFlags;
class CDType {
friend class CDSection;
friend class CDCore;
friend class Interface;
friend class XInterface;
public:
enum cdT {cdNull, cdK, cdX, cdC, cdM};
enum XMode {X_Current, X_All_Avg};
CDType();
CDType(int i, const PIString & n, const PIString & t, const PIString & v, const PIString & f, const PIString & c, cdT cd_t);
CDType & operator =(double x);
int index() const {return index_;}
PIString name() const {return name_;}
PIString type() const;
PIString value() const;
PIVariant variantValue() const;
PIString formula() const {return formula_;}
PIString comment() const {return comment_;}
double toDouble() const {return value_d;}
int toInt() const {return value_i;}
bool toBool() const {return value_b;}
cdT cd_type() const {return cd_type_;}
void setValue(const PIString & value_);
void setVariantValue(const PIVariant & value_);
void setFormula(const PIString & formula);
void setComment(const PIString & comment) {comment_ = comment;}
operator double() const {return value_d;}
const PIVariantTypes::Enum & enumValues() const {return enum_values;}
void setEnumValues(const PIVariantTypes::Enum & ev) {enum_values = ev;}
const PIString & errorString() const {return error_;}
PIDeque<int> path() const {return path_;}
PIStringList pathString() const;
void setXMode(XMode mode) {mode_ = mode;}
void setAvg(int avg) {avg_size = avg;}
XMode xmode() const {return mode_;}
XMode xmode_rec() const {return rmode_;}
int avg() const {return avg_size;}
bool isSelectedX() const {return x_enabled;}
void readX(PIByteArray & ba);
void writeX(PIByteArray & ba);
PIVector<double> history;
protected:
bool calculate(PIEvaluator * e, PIVector<const CDType * > stack = PIVector<const CDType * >());
PIVariantTypes::Enum parseEnumComment(PIString c);
cdT cd_type_;
int index_;
PIString name_, type_;
PIString value_s, formula_, comment_, error_;
PIVariantTypes::Enum enum_values;
CDSection * parent;
PIDeque<int> path_;
double value_d;
int value_i;
bool value_b, calculated, x_enabled;
PIVector<double> avg_h;
int avg_size;
XMode mode_, rmode_;
};
class CDSection {
friend class CDCore;
friend class Interface;
friend class XInterface;
friend class ::CD_Pult;
friend class ::CDItem;
friend class ::CDItemModel;
public:
CDSection(CDType::cdT type_ = CDType::cdNull);
bool test(int v) {return cd.value(v).toBool();}
// CDType & operator [](int v) {if (!k.contains(v)) k[v].index_ = v; return k[v];}
CDType & operator [](int v) {return cd[v];}
const CDType operator [](int v) const {return cd[v];}
CDType & operator [](const PIString & name_) {return getByName(name_);}
const CDType operator [](const PIString & name_) const {return const_cast<CDSection*>(this)->getByName(name_);}
CDType & operator [](const PIDeque<int> & path_) {return getByPath(path_);}
const CDType operator [](const PIDeque<int> & path_) const {return const_cast<CDSection*>(this)->getByPath(path_);}
CDSection & section(int v);
const CDSection section(int v) const;
bool isEmpty() const {return cd.isEmpty() && s.isEmpty();}
bool exists(PIDeque<int> path) const;
int count(bool recursive = true) const;
int sectionsCount() const;
PIVector<int> indexes() const {return cd.keys();}
PIStringList index_names() const;
void calculate();
void makePath(PIDeque<int> p = PIDeque<int>());
PIVector<CDType * > children(bool recursive = true) const;
PIVariantTypes::Enum enumValues() const;
PIString name;
PIString alias;
protected:
CDSection(PIMap<int, CDType> k_, PIMap<int, CDSection> s_) {
cd = k_;
s = s_;
}
CDType & getByName(const PIString & name_);
CDType & getByPath(const PIDeque<int> & path_);
void write(PIIODevice * d, const PIString & prefix = PIString());
void read(const void * ep);
void update(CDSection & v, UpdateModeFlags mode = SaveByName);
bool isSameStructure(CDSection & v);
void prepareCalculate();
void calculateRecursive(PIEvaluator * e);
void setSelectedX(bool yes);
PIVector<PIDeque<int> > collectX() const;
PIMap<int, CDType> cd;
mutable PIMap<int, CDSection> s;
CDType null;
CDType::cdT cd_type_;
};
}
inline PICout operator <<(PICout s, const CDUtils::CDType & v) {
s.space();
s.setControl(0, true);
switch (v.cd_type()) {
case CDUtils::CDType::cdK : s << "K["; break;
case CDUtils::CDType::cdX : s << "X["; break;
case CDUtils::CDType::cdC : s << "C["; break;
case CDUtils::CDType::cdM : s << "M["; break;
default : s << "Null["; break;
}
s << v.name() << "(" << v.index() << ")] = " << v.value();
s.restoreControl();
return s;
}
#endif // CDUTILS_TYPES_H
/*
CD Utils - Control-Debug utilites
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CDUTILS_TYPES_H
#define CDUTILS_TYPES_H
#include "pistring.h"
#include "pimap.h"
#include "pivariant.h"
#include "cd_utils_export.h"
class PIIODevice;
class PIEvaluator;
class CD_Pult;
class CDItem;
class CDItemModel;
namespace CDUtils {
class CDSection;
enum UpdateMode {
SaveByIndex = 0x01,
SaveByName = 0x02,
Merge = 0x04
};
enum MessageType {
Log = 1,
MessageBox,
};
typedef PIFlags<UpdateMode> UpdateModeFlags;
class CD_UTILS_EXPORT CDType {
friend class CDSection;
friend class CDCore;
friend class Interface;
friend class XInterface;
public:
enum cdT {cdNull, cdK, cdX, cdC, cdM};
enum XMode {X_Current, X_All_Avg};
CDType();
CDType(int i, const PIString & n, const PIString & t, const PIString & v, const PIString & f, const PIString & c, cdT cd_t);
CDType & operator =(double x);
int index() const {return index_;}
PIString name() const {return name_;}
PIString type() const;
PIString value() const;
PIVariant variantValue() const;
PIString formula() const {return formula_;}
PIString comment() const {return comment_;}
double toDouble() const {return value_d;}
int toInt() const {return value_i;}
bool toBool() const {return value_b;}
cdT cd_type() const {return cd_type_;}
void setValue(const PIString & value_);
void setVariantValue(const PIVariant & value_);
void setFormula(const PIString & formula);
void setComment(const PIString & comment) {comment_ = comment;}
operator double() const {return value_d;}
const PIVariantTypes::Enum & enumValues() const {return enum_values;}
void setEnumValues(const PIVariantTypes::Enum & ev) {enum_values = ev;}
const PIString & errorString() const {return error_;}
PIDeque<int> path() const {return path_;}
PIStringList pathString() const;
void setXMode(XMode mode) {mode_ = mode;}
void setAvg(int avg) {avg_size = avg;}
XMode xmode() const {return mode_;}
XMode xmode_rec() const {return rmode_;}
int avg() const {return avg_size;}
bool isSelectedX() const {return x_enabled;}
void readX(PIByteArray & ba);
void writeX(PIByteArray & ba);
PIVector<double> history;
protected:
bool calculate(PIEvaluator * e, PIVector<const CDType * > stack = PIVector<const CDType * >());
PIVariantTypes::Enum parseEnumComment(PIString c);
cdT cd_type_;
int index_;
PIString name_, type_;
PIString value_s, formula_, comment_, error_;
PIVariantTypes::Enum enum_values;
CDSection * parent;
PIDeque<int> path_;
double value_d;
int value_i;
bool value_b, calculated, x_enabled;
PIVector<double> avg_h;
int avg_size;
XMode mode_, rmode_;
};
class CD_UTILS_EXPORT CDSection {
friend class CDCore;
friend class Interface;
friend class XInterface;
friend class ::CD_Pult;
friend class ::CDItem;
friend class ::CDItemModel;
public:
CDSection(CDType::cdT type_ = CDType::cdNull);
bool test(int v) {return cd.value(v).toBool();}
// CDType & operator [](int v) {if (!k.contains(v)) k[v].index_ = v; return k[v];}
CDType & operator [](int v) {return cd[v];}
const CDType operator [](int v) const {return cd[v];}
CDType & operator [](const PIString & name_) {return getByName(name_);}
const CDType operator [](const PIString & name_) const {return const_cast<CDSection*>(this)->getByName(name_);}
CDType & operator [](const PIDeque<int> & path_) {return getByPath(path_);}
const CDType operator [](const PIDeque<int> & path_) const {return const_cast<CDSection*>(this)->getByPath(path_);}
CDSection & section(int v);
const CDSection section(int v) const;
bool isEmpty() const {return cd.isEmpty() && s.isEmpty();}
bool exists(PIDeque<int> path) const;
int count(bool recursive = true) const;
int sectionsCount() const;
PIVector<int> indexes() const {return cd.keys();}
PIStringList index_names() const;
void calculate();
void makePath(PIDeque<int> p = PIDeque<int>());
PIVector<CDType * > children(bool recursive = true) const;
PIVariantTypes::Enum enumValues() const;
PIString name;
PIString alias;
protected:
CDSection(PIMap<int, CDType> k_, PIMap<int, CDSection> s_) {
cd = k_;
s = s_;
}
CDType & getByName(const PIString & name_);
CDType & getByPath(const PIDeque<int> & path_);
void write(PIIODevice * d, const PIString & prefix = PIString());
void read(const void * ep);
void update(CDSection & v, UpdateModeFlags mode = SaveByName);
bool isSameStructure(CDSection & v);
void prepareCalculate();
void calculateRecursive(PIEvaluator * e);
void setSelectedX(bool yes);
PIVector<PIDeque<int> > collectX() const;
PIMap<int, CDType> cd;
mutable PIMap<int, CDSection> s;
CDType null;
CDType::cdT cd_type_;
};
}
inline PICout operator <<(PICout s, const CDUtils::CDType & v) {
s.space();
s.setControl(0, true);
switch (v.cd_type()) {
case CDUtils::CDType::cdK : s << "K["; break;
case CDUtils::CDType::cdX : s << "X["; break;
case CDUtils::CDType::cdC : s << "C["; break;
case CDUtils::CDType::cdM : s << "M["; break;
default : s << "Null["; break;
}
s << v.name() << "(" << v.index() << ")] = " << v.value();
s.restoreControl();
return s;
}
#endif // CDUTILS_TYPES_H

View File

@@ -1,55 +1,55 @@
#include "cdutils_x.h"
#include "cdutils_core.h"
using namespace CDUtils;
XInterface X;
XInterface::XInterface(): Interface(CDType::cdX) {
CONNECTU(core, X_ReceivedX, this, receivedX);
}
void XInterface::setEnabled(const CDType & x, bool en) {
core->x_mutex.lock();
CDType & t((*s)[x.path()]);
if (t.cd_type() != CDType::cdX) {
core->x_mutex.unlock();
return;
}
t.x_enabled = en;
//piCout << t << "x_enabled" << en;
core->need_rebuild_x = true;
core->x_mutex.unlock();
}
PIVector<PIDeque<int> > XInterface::enabledList() const {
return CDCore::instance()->x_selected;
}
void XInterface::setEnabledList(const PIVector<PIDeque<int> > & l) {
CDCore::instance()->x_selected = l;
}
void XInterface::lock() {
CDCore::instance()->x_mutex.lock();
}
void XInterface::unlock() {
CDCore::instance()->x_mutex.unlock();
}
void XInterface::start(double freq) {
core->startX(freq);
}
void XInterface::stop() {
core->stopX();
}
#include "cdutils_x.h"
#include "cdutils_core.h"
using namespace CDUtils;
XInterface X;
XInterface::XInterface(): Interface(CDType::cdX) {
CONNECTU(core, X_ReceivedX, this, receivedX);
}
void XInterface::setEnabled(const CDType & x, bool en) {
core->x_mutex.lock();
CDType & t((*s)[x.path()]);
if (t.cd_type() != CDType::cdX) {
core->x_mutex.unlock();
return;
}
t.x_enabled = en;
//piCout << t << "x_enabled" << en;
core->need_rebuild_x = true;
core->x_mutex.unlock();
}
PIVector<PIDeque<int> > XInterface::enabledList() const {
return CDCore::instance()->x_selected;
}
void XInterface::setEnabledList(const PIVector<PIDeque<int> > & l) {
CDCore::instance()->x_selected = l;
}
void XInterface::lock() {
CDCore::instance()->x_mutex.lock();
}
void XInterface::unlock() {
CDCore::instance()->x_mutex.unlock();
}
void XInterface::start(double freq) {
core->startX(freq);
}
void XInterface::stop() {
core->stopX();
}

View File

@@ -1,56 +1,57 @@
/*
CD Utils - Control-Debug utilites
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CDUTILS_X_H
#define CDUTILS_X_H
#include "cdutils_interface.h"
namespace CDUtils {
class XInterface: public Interface
{
PIOBJECT_SUBCLASS(XInterface, Interface)
public:
XInterface();
EVENT1(keepNamesRequest, bool*, xn)
EVENT1(receivedX, PIVector<PIDeque<int> >, pathes)
void enable(const CDType & x) {setEnabled(x, true);}
void disable(const CDType & x) {setEnabled(x, false);}
void setEnabled(const CDType & x, bool en);
void setDisabled(const CDType & x, bool dis) {setEnabled(x, !dis);}
PIVector<PIDeque<int> > enabledList() const;
void setEnabledList(const PIVector<PIDeque<int> > & l);
void lock();
void unlock();
void start(double freq = 20.);
void stop();
};
}
extern CDUtils::XInterface X;
#endif // CDUTILS_X_H
/*
CD Utils - Control-Debug utilites
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CDUTILS_X_H
#define CDUTILS_X_H
#include "cdutils_interface.h"
#include "cd_utils_export.h"
namespace CDUtils {
class CD_UTILS_EXPORT XInterface: public Interface
{
PIOBJECT_SUBCLASS(XInterface, Interface)
public:
XInterface();
EVENT1(keepNamesRequest, bool*, xn)
EVENT1(receivedX, PIVector<PIDeque<int> >, pathes)
void enable(const CDType & x) {setEnabled(x, true);}
void disable(const CDType & x) {setEnabled(x, false);}
void setEnabled(const CDType & x, bool en);
void setDisabled(const CDType & x, bool dis) {setEnabled(x, !dis);}
PIVector<PIDeque<int> > enabledList() const;
void setEnabledList(const PIVector<PIDeque<int> > & l);
void lock();
void unlock();
void start(double freq = 20.);
void stop();
};
}
extern CD_UTILS_EXPORT CDUtils::XInterface X;
#endif // CDUTILS_X_H

View File

@@ -1,97 +1,97 @@
#include "cdutils_k.h"
#include "cdutils_x.h"
#include "cdutils_c.h"
#include "cdutils_m.h"
#include "cdutils_core.h"
#include "cdtest.h"
#include "pip.h"
#include "k_description.h"
using namespace CDUtils;
class Core : public PIObject
{
PIOBJECT(Core)
public:
Core() {
CDCore::instance()->initApp();
// piCout << "testCore";
CONNECTU(&timer, tickEvent, this, timerDone);
CONNECTU(&X, received, this, xrecv);
CONNECTU(&C, received, this, crecv);
t = 0.;
}
void load() {
rf.open("k.dat", PIIODevice::ReadWrite);
K.read(&rf);
rf.close();
}
void save() {
rf.open("k_out.txt", PIIODevice::ReadWrite);
rf.resize(0);
K.write(&rf);
rf.close();
// rf.open("k_out.txt", PIIODevice::ReadWrite);
// K.read(&rf);
// rf.close();
// rf.open("k_out2.txt", PIIODevice::ReadWrite);
// rf.resize(0);
// K.write(&rf);
// rf.close();
// rf.open("k_out2.txt", PIIODevice::ReadWrite);
// K.read(&rf);
// rf.close();
// rf.open("k_out3.txt", PIIODevice::ReadWrite);
// rf.resize(0);
// K.write(&rf);
// rf.close();
}
void test() {
X.lock();
X[KD::Frequency] = 100;
X.section(KD::Spectrometer)[KD::Temperature_default] = sin(t);
t += 0.01;
X.unlock();
/*piCout << "count" << K.count();
piCout << K[First];
piCout << K[Second];*/
}
EVENT_HANDLER(void, ksend) {piCout << "sended k";}
EVENT_HANDLER(void, crecv) {
piCout << "received c";
C.connect(C.section(KD::Logs).section(KD::Spec).section(KD::Formats)[KD::Binary], this, HANDLER(cmd));
C.autoConnect(this);
}
EVENT_HANDLER(void, xrecv) {
piCout << "received x";
if (!timer.isRunning()) timer.start(10);
X.start();
}
EVENT_HANDLER(void, timerDone) {test();}
EVENT_HANDLER(void, cmd) {piCout << "command cmd";}
EVENT_HANDLER(void, c_Pause) {
piCout << "command pause";
M[KD::Main] << "rec command" << C[KD::Pause];
M.messageBox(M.root()[KD::Core], "init successfull");
}
EVENT_HANDLER(void, c_Spectrometer_Connection) {piCout << "command spec_conn";}
private:
PIFile rf;
PITimer timer;
double t;
};
int main(int argc, char *argv[]) {
X.start();
piSleep(1);
//CDCore::instance()->destroy();
piCout << "DELETED";
return 0;
}
#include "cdutils_k.h"
#include "cdutils_x.h"
#include "cdutils_c.h"
#include "cdutils_m.h"
#include "cdutils_core.h"
#include "cdtest.h"
#include "pip.h"
#include "k_description.h"
using namespace CDUtils;
class Core : public PIObject
{
PIOBJECT(Core)
public:
Core() {
CDCore::instance()->initApp();
// piCout << "testCore";
CONNECTU(&timer, tickEvent, this, timerDone);
CONNECTU(&X, received, this, xrecv);
CONNECTU(&C, received, this, crecv);
t = 0.;
}
void load() {
rf.open("k.dat", PIIODevice::ReadWrite);
K.read(&rf);
rf.close();
}
void save() {
rf.open("k_out.txt", PIIODevice::ReadWrite);
rf.resize(0);
K.write(&rf);
rf.close();
// rf.open("k_out.txt", PIIODevice::ReadWrite);
// K.read(&rf);
// rf.close();
// rf.open("k_out2.txt", PIIODevice::ReadWrite);
// rf.resize(0);
// K.write(&rf);
// rf.close();
// rf.open("k_out2.txt", PIIODevice::ReadWrite);
// K.read(&rf);
// rf.close();
// rf.open("k_out3.txt", PIIODevice::ReadWrite);
// rf.resize(0);
// K.write(&rf);
// rf.close();
}
void test() {
X.lock();
X[KD::Frequency] = 100;
X.section(KD::Spectrometer)[KD::Temperature_default] = sin(t);
t += 0.01;
X.unlock();
/*piCout << "count" << K.count();
piCout << K[First];
piCout << K[Second];*/
}
EVENT_HANDLER(void, ksend) {piCout << "sended k";}
EVENT_HANDLER(void, crecv) {
piCout << "received c";
C.connect(C.section(KD::Logs).section(KD::Spec).section(KD::Formats)[KD::Binary], this, HANDLER(cmd));
C.autoConnect(this);
}
EVENT_HANDLER(void, xrecv) {
piCout << "received x";
if (!timer.isRunning()) timer.start(10);
X.start();
}
EVENT_HANDLER(void, timerDone) {test();}
EVENT_HANDLER(void, cmd) {piCout << "command cmd";}
EVENT_HANDLER(void, c_Pause) {
piCout << "command pause";
M[KD::Main] << "rec command" << C[KD::Pause];
M.messageBox(M.root()[KD::Core], "init successfull");
}
EVENT_HANDLER(void, c_Spectrometer_Connection) {piCout << "command spec_conn";}
private:
PIFile rf;
PITimer timer;
double t;
};
int main(int argc, char *argv[]) {
X.start();
piSleep(1);
//CDCore::instance()->destroy();
piCout << "DELETED";
return 0;
}

0
cmake_android.sh Executable file → Normal file
View File

View File

@@ -3,9 +3,14 @@ FROM ${DOCKER_PREFIX}android
ARG LIBS_BUILD_NUMBER=9999
ARG JOBS_COUNT=4
ENV PATH=/opt/cmake/bin:$PATH
ENV ANDROID_HOME=/usr/lib/android-sdk
ENV ANDROID_NDK_HOME=${ANDROID_HOME}/ndk-bundle
ENV ANDROID_TOOLCHAIN=${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake
ENV NDK_PLATFORM="android-21"
WORKDIR /soft
RUN git clone -b release --depth 1 --recursive https://git.shs.tools/SHS/libs.git
RUN git clone -b release --single-branch --depth 1 --recursive https://git.shs.tools/SHS/libs.git
WORKDIR /soft/libs_build_host
RUN cmake -DICU=0 -DCROSSTOOLS=1 -DBUILD_NUMBER=${LIBS_BUILD_NUMBER} ../libs \

View File

@@ -3,9 +3,10 @@ FROM ${DOCKER_PREFIX}debian
ARG LIBS_BUILD_NUMBER=9999
ARG JOBS_COUNT=4
ENV PATH=/opt/cmake/bin:$PATH
WORKDIR /soft
RUN git clone -b release --depth 1 --recursive https://git.shs.tools/SHS/libs.git
RUN git clone -b release --single-branch --depth 1 --recursive https://git.shs.tools/SHS/libs.git
WORKDIR /soft/libs_build_debian
RUN cmake -DICU=0 -DLIB=1 -DQGLENGINE=1 -DQGLVIEW=1 -DBUILD_NUMBER=${LIBS_BUILD_NUMBER} ../libs \

View File

@@ -3,9 +3,10 @@ FROM ${DOCKER_PREFIX}osx
ARG LIBS_BUILD_NUMBER=9999
ARG JOBS_COUNT=4
ENV PATH=/soft/osxcross/target/bin:/opt/cmake/bin:$PATH
WORKDIR /soft
RUN git clone -b release --depth 1 --recursive https://git.shs.tools/SHS/libs.git
RUN git clone -b release --single-branch --depth 1 --recursive https://git.shs.tools/SHS/libs.git
WORKDIR /soft/libs_build_host
RUN cmake -DICU=0 -DCROSSTOOLS=1 -DBUILD_NUMBER=${LIBS_BUILD_NUMBER} ../libs \

View File

@@ -3,9 +3,10 @@ FROM ${DOCKER_PREFIX}pi
ARG LIBS_BUILD_NUMBER=9999
ARG JOBS_COUNT=4
ENV PATH=/opt/cmake/bin:$PATH
WORKDIR /soft
RUN git clone -b release --depth 1 --recursive https://git.shs.tools/SHS/libs.git
RUN git clone -b release --single-branch --depth 1 --recursive https://git.shs.tools/SHS/libs.git
WORKDIR /soft/libs_build_host
RUN cmake -DICU=0 -DCROSSTOOLS=1 -DBUILD_NUMBER=${LIBS_BUILD_NUMBER} ../libs \

View File

@@ -3,9 +3,10 @@ FROM ${DOCKER_PREFIX}windows
ARG LIBS_BUILD_NUMBER=9999
ARG JOBS_COUNT=4
ENV PATH=/opt/cmake/bin:$PATH
WORKDIR /soft
RUN git clone -b release --depth 1 --recursive https://git.shs.tools/SHS/libs.git
RUN git clone -b release --single-branch --depth 1 --recursive https://git.shs.tools/SHS/libs.git
WORKDIR /soft/libs_build_host
RUN cmake -DICU=0 -DCROSSTOOLS=1 -DBUILD_NUMBER=${LIBS_BUILD_NUMBER} ../libs \

View File

@@ -1,76 +1,76 @@
cmake_minimum_required(VERSION 3.0)
project(kx_utils)
if (POLICY CMP0017)
cmake_policy(SET CMP0017 NEW)
endif()
if (NOT LIBPROJECT)
find_package(PIP REQUIRED)
endif ()
if (MINGW)
find_package(MinGW REQUIRED)
endif()
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${PIP_INCLUDES})
set(KX_PULT_NAME "kx_pult")
option(KX_PULT "Build ${KX_PULT_NAME}" 1)
option(LIB "System install" 1)
option(DEBUG "Build with -g3" 0)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -Wall")
if (DEBUG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3")
endif()
set(CPPS_UTILS "kx_coeffs.cpp" "piprotocol.cpp")
set(HDRS_UTILS "kx_coeffs.h" "kx_protocol_x.h" "kx_protocol_c.h" "piprotocol.h")
if (DEFINED ENV{QNX_HOST})
add_library(${PROJECT_NAME} STATIC ${CPPS_UTILS})
else()
add_library(${PROJECT_NAME} SHARED ${CPPS_UTILS})
endif()
target_link_libraries(${PROJECT_NAME} ${PIP_LIBRARY})
message(STATUS "Building ${PROJECT_NAME}")
if (NOT DEFINED ENV{QNX_HOST})
if (KX_PULT)
find_package(Qt4 REQUIRED)
find_package(QAD REQUIRED)
find_package(OpenGL REQUIRED)
include_directories(${QT_INCLUDES} ${QAD_INCLUDES})
set(CPPS "kx_pult.cpp" "kx_pult.h" "kx_pult.ui" "main_kx_pult.cpp")
set(MOCS "kx_pult.h")
file(GLOB UIS "*.ui")
file(GLOB RES "*.qrc")
qt4_wrap_cpp(CMOCS ${MOCS} OPTIONS -nw)
qt4_wrap_ui(CUIS ${UIS})
qt4_add_resources(RESS ${RES})
add_executable(${KX_PULT_NAME} WIN32 ${CPPS} ${CMOCS} ${CUIS} ${RESS} ${MOCS})
set(LIBS ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${OPENGL_LIBRARIES} ${PIP_LIBRARY} qad_graphic4 qad_utils4 qad_widgets4)
target_link_libraries(${KX_PULT_NAME} ${LIBS} ${PROJECT_NAME})
endif()
endif()
if (LIB)
list(APPEND _ALL_TARGETS ${PROJECT_NAME})
set(_ALL_TARGETS ${_ALL_TARGETS} PARENT_SCOPE)
if (WIN32)
set(CMAKE_INSTALL_PREFIX ${MINGW_DIR})
install(FILES ${HDRS_UTILS} DESTINATION ${MINGW_INCLUDE})
install(TARGETS ${PROJECT_NAME} DESTINATION ${MINGW_LIB})
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${MINGW_BIN})
else()
if (DEFINED ANDROID_PLATFORM)
set(CMAKE_INSTALL_PREFIX ${ANDROID_SYSTEM_LIBRARY_PATH}/usr)
else()
set(CMAKE_INSTALL_PREFIX /usr/local)
endif()
install(FILES ${HDRS_UTILS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include)
install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
endif()
message(STATUS "Install ${PROJECT_NAME} to system \"${CMAKE_INSTALL_PREFIX}\"")
else()
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
install(TARGETS ${PROJECT_NAME} DESTINATION lib)
install(FILES ${HDRS_UTILS} DESTINATION include)
message(STATUS "Install ${PROJECT_NAME} to local \"bin\", \"lib\" and \"include\"")
endif()
if (NOT DEFINED ENV{QNX_HOST})
if (KX_PULT)
install(TARGETS ${KX_PULT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
endif()
endif()
cmake_minimum_required(VERSION 3.0)
project(kx_utils)
if (POLICY CMP0017)
cmake_policy(SET CMP0017 NEW)
endif()
if (NOT LIBPROJECT)
find_package(PIP REQUIRED)
endif ()
if (MINGW)
find_package(MinGW REQUIRED)
endif()
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${PIP_INCLUDES})
set(KX_PULT_NAME "kx_pult")
option(KX_PULT "Build ${KX_PULT_NAME}" 1)
option(LIB "System install" 1)
option(DEBUG "Build with -g3" 0)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -Wall")
if (DEBUG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3")
endif()
set(CPPS_UTILS "kx_coeffs.cpp" "piprotocol.cpp")
set(HDRS_UTILS "kx_coeffs.h" "kx_protocol_x.h" "kx_protocol_c.h" "piprotocol.h")
if (DEFINED ENV{QNX_HOST})
add_library(${PROJECT_NAME} STATIC ${CPPS_UTILS})
else()
add_library(${PROJECT_NAME} SHARED ${CPPS_UTILS})
endif()
target_link_libraries(${PROJECT_NAME} ${PIP_LIBRARY})
message(STATUS "Building ${PROJECT_NAME}")
if (NOT DEFINED ENV{QNX_HOST})
if (KX_PULT)
find_package(Qt4 REQUIRED)
find_package(QAD REQUIRED)
find_package(OpenGL REQUIRED)
include_directories(${QT_INCLUDES} ${QAD_INCLUDES})
set(CPPS "kx_pult.cpp" "kx_pult.h" "kx_pult.ui" "main_kx_pult.cpp")
set(MOCS "kx_pult.h")
file(GLOB UIS "*.ui")
file(GLOB RES "*.qrc")
qt4_wrap_cpp(CMOCS ${MOCS} OPTIONS -nw)
qt4_wrap_ui(CUIS ${UIS})
qt4_add_resources(RESS ${RES})
add_executable(${KX_PULT_NAME} WIN32 ${CPPS} ${CMOCS} ${CUIS} ${RESS} ${MOCS})
set(LIBS ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${OPENGL_LIBRARIES} ${PIP_LIBRARY} qad_graphic4 qad_utils4 qad_widgets4)
target_link_libraries(${KX_PULT_NAME} ${LIBS} ${PROJECT_NAME})
endif()
endif()
if (LIB)
list(APPEND _ALL_TARGETS ${PROJECT_NAME})
set(_ALL_TARGETS ${_ALL_TARGETS} PARENT_SCOPE)
if (WIN32)
set(CMAKE_INSTALL_PREFIX ${MINGW_DIR})
install(FILES ${HDRS_UTILS} DESTINATION ${MINGW_INCLUDE})
install(TARGETS ${PROJECT_NAME} DESTINATION ${MINGW_LIB})
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${MINGW_BIN})
else()
if (DEFINED ANDROID_PLATFORM)
set(CMAKE_INSTALL_PREFIX ${ANDROID_SYSTEM_LIBRARY_PATH}/usr)
else()
set(CMAKE_INSTALL_PREFIX /usr/local)
endif()
install(FILES ${HDRS_UTILS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include)
install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
endif()
message(STATUS "Install ${PROJECT_NAME} to system \"${CMAKE_INSTALL_PREFIX}\"")
else()
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
install(TARGETS ${PROJECT_NAME} DESTINATION lib)
install(FILES ${HDRS_UTILS} DESTINATION include)
message(STATUS "Install ${PROJECT_NAME} to local \"bin\", \"lib\" and \"include\"")
endif()
if (NOT DEFINED ENV{QNX_HOST})
if (KX_PULT)
install(TARGETS ${KX_PULT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
endif()
endif()

View File

@@ -1,848 +1,848 @@
#include <QScrollBar>
#include <QMessageBox>
#include <math.h>
#include "kx_pult.h"
#include "ui_kx_pult.h"
#include "piqt.h"
#include "qpiconfig.h"
bool isNormalDouble(const double & v) {
#ifdef WINDOWS
return true;
#else
return !isnan(v) && !isinf(v);
#endif
}
XCheck::XCheck(int index): QWidget() {
index_ = index;
setProperty("index", index);
setMouseTracking(true);
check.setText(QString::number(index + 1) + " ");
check.setAutoFillBackground(true);
spin.setMaximum(KX_X_COUNT - 1);
QBoxLayout * l = new QBoxLayout(QBoxLayout::LeftToRight);
l->setMargin(0);
l->setSpacing(2);
l->addWidget(&check);
l->addWidget(&spin);
setLayout(l);
//check.installEventFilter(this);
//spin.installEventFilter(this);
connect(&spin, SIGNAL(valueChanged(int)), this, SLOT(spinChanged(int)));
connect(&check, SIGNAL(toggled(bool)), this, SLOT(checkChanged_(bool)));
}
bool XCheck::eventFilter(QObject * o, QEvent * e) {
if (e->type() == QEvent::Enter)
qApp->postEvent(this, new QEvent(e->type()));
return QWidget::eventFilter(o, e);
}
KX_Pult::KX_Pult(): QMainWindow(), config_("kx_pult.conf"), name_x("x"), name_c("c"),
config(piqt(config_), QIODevice::ReadWrite), coeffs(config_, "k", true) {
//cout << sizeof(coeffsK.k_protocol->to_k) << endl;
ui = new Ui::KX_Pult();
ui->setupUi(this);
ui->configWidget->setQPIConfig(&config);
ui->configWidget->expandAll();
ui->list->viewport()->installEventFilter(this);
ui->treeK->viewport()->installEventFilter(this);
ui->scrollArea->setAutoFillBackground(false);
ui->scrollAreaWidgetContents->setAutoFillBackground(false);
ui->widget->setAutoFillBackground(false);
ui->label_17->setFixedSize(preferredIconSize(1.25, this));
log_menu.addAction(ui->actionClear);
prot_x = 0;
prot_c = 0;
show_x = config.getValue("show_x", true);
if (!show_x)
ui->tabWidget->removeTab(1);
session.setFile("session_KX_Pult.conf");
session.addEntry(this);
session.addEntry(ui->tabWidget);
session.addEntry(ui->checkKHideEmpty);
session.addEntry(ui->checkKHideNormal);
session.addEntry(ui->checkKHideExpressions);
session.addEntry(ui->checkKAutoCalculate);
needWrite = isPause = false;
timer = 0;
//x.resize(KX_X_PACKET_NUM);
//k.resize(K_NUM);
QPalette pal = palette();
QColor col;
ui->graphic->setGraphicsCount(0);
for (int i = 0; i < KX_X_PACKET_NUM; ++i) {
XCheck * xc = new XCheck(i);
xc->installEventFilter(this);
connect(xc, SIGNAL(valueChanged(int, int)), this, SLOT(changedX(int,int)));
connect(xc, SIGNAL(checkChanged(int, bool)), this, SLOT(toggledX(int, bool)));
col = QColor::fromHsv(360 / KX_X_PACKET_NUM * i, 255, 200);
pal.setColor(QPalette::Button, col);
pal.setColor(QPalette::Window, col);
pal.setColor(QPalette::WindowText, invertColor(col));
xc->check.setPalette(pal);
ui->graphic->addGraphic(QString::number(i), col);
ui->graphic->setGraphicVisible(false, i);
checks << xc;
((QGridLayout * )(ui->widgetChecks->layout()))->addWidget(xc, (i / 10) * 2, i % 10);
QLabel * lbl = new QLabel("0"); lbl->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
values << lbl;
((QGridLayout * )(ui->widgetChecks->layout()))->addWidget(lbl, (i / 10) * 2 + 1, i % 10);
//xc->show();
}
renew();
icon_record = QIcon(":/icons/media-record.png");
icon_stop = QIcon(":/icons/media-playback-stop.png");
outdir = dir.absolutePath();
if (!dir.exists()) dir.mkdir(outdir);
outdir += "/";
ui->treeK->setColumnWidth(0, 60);
ui->treeK->setColumnWidth(1, 250);
ui->treeK->setColumnWidth(3, 100);
ui->treeK->setColumnWidth(4, 100);
//ui->table->setK(coeffsK.k()->data(), coeffsK.count());
ui->spinSize->setValue(K.size_s());
addToList(trUtf8("Read K file \"%1\": %2 coeffs, %3 bytes").arg(PI2QString(coeffs.fileName())).arg(K.size_s()).arg(coeffs.k_content.size_s()), Qt::darkMagenta);
CONNECT(void, &coeffs, sendFailed, this, pip_sendFailed);
CONNECT(void, &coeffs, sendSucceed, this, pip_sendSucceed);
CONNECT(void, &coeffs, receiveFailed, this, pip_receiveFailed);
CONNECT(void, &coeffs, receiveSucceed, this, pip_receiveSucceed);
connect(this, SIGNAL(q_k_sendFailed()), this, SLOT(k_sendFailed()), Qt::QueuedConnection);
connect(this, SIGNAL(q_k_sendSucceed()), this, SLOT(k_sendSucceed()), Qt::QueuedConnection);
connect(this, SIGNAL(q_k_receiveFailed()), this, SLOT(k_receiveFailed()), Qt::QueuedConnection);
connect(this, SIGNAL(q_k_receiveSucceed()), this, SLOT(k_receiveSucceed()), Qt::QueuedConnection);
connect(&timer_diag, SIGNAL(timeout()), this, SLOT(updateDiag()));
connect(&session, SIGNAL(loading(QPIConfig&)), this, SLOT(loading(QPIConfig&)));
connect(&session, SIGNAL(saving(QPIConfig&)), this, SLOT(saving(QPIConfig&)));
connect(ui->checkKHideEmpty, SIGNAL(toggled(bool)), this, SLOT(filterTree()));
connect(ui->checkKHideNormal, SIGNAL(toggled(bool)), this, SLOT(filterTree()));
connect(ui->checkKHideExpressions, SIGNAL(toggled(bool)), this, SLOT(filterTree()));
connect(ui->lineKSearch, SIGNAL(textChanged(QString)), this, SLOT(filterTree()));
session.load();
updateKDesc();
updateCDesc();
timer_diag.start(40);
timer_update = startTimer(25);
}
KX_Pult::~KX_Pult() {
session.save();
}
void KX_Pult::loading(QPIConfig & conf) {
kdesc_file = conf.getValue("kdesc_file").stringValue();
cdesc_file = conf.getValue("cdesc_file").stringValue();
}
void KX_Pult::saving(QPIConfig & conf) {
conf.setValue("kdesc_file", kdesc_file);
conf.setValue("cdesc_file", cdesc_file);
}
bool KX_Pult::eventFilter(QObject * o, QEvent * e) {
if (o == ui->list->viewport()) {
if (e->type() == QEvent::ContextMenu) {
clear_target = 0;
log_menu.popup(((QContextMenuEvent*)e)->globalPos());
}
return QMainWindow::eventFilter(o, e);
}
if (o == ui->treeK->viewport()) {
if (e->type() == QEvent::ContextMenu) {
clear_target = 1;
log_menu.popup(((QContextMenuEvent*)e)->globalPos());
}
return QMainWindow::eventFilter(o, e);
}
int ind = o->property("index").toInt();
//qDebug() << "event" << i << e->type();
switch (e->type()) {
case QEvent::Enter:
ui->graphic->setAutoUpdate(false);
for (int i = 0; i < KX_X_PACKET_NUM; ++i)
ui->graphic->setGraphicLineWidth(ind == i ? 3. : 1., i);
ui->graphic->setAutoUpdate(true);
ui->graphic->update();
break;
case QEvent::Leave:
ui->graphic->setAutoUpdate(false);
for (int i = 0; i < KX_X_PACKET_NUM; ++i)
ui->graphic->setGraphicLineWidth(1., i);
ui->graphic->setAutoUpdate(true);
ui->graphic->update();
break;
default: break;
}
return QMainWindow::eventFilter(o, e);
}
void KX_Pult::timerEvent(QTimerEvent * e) {
if (e->timerId() == timer_update) {
if (need_update) {
need_update = false;
ui->graphic->updateGraphics();
}
}
if (e->timerId() == timer) {
static QString sPI = QString::number(atan(1) * 4., 'f', 14).leftJustified(14);
static int cnt = 0;
int si = qMax<int>(cnt - 6, 0);
++cnt;
cnt %= 23;
ui->labelWait->setText(QString(si, QChar(' ')) + sPI.mid(cnt - 6, 6).trimmed());
if (!coeffs.isReady()) return;
//ui->table->setK(coeffsK.k()->data(), coeffsK.count());
//ui->table->showK();
}
}
void KX_Pult::setControlsEnable(bool enable) {
foreach (XCheck * i, checks)
i->setEnabled(enable);
ui->buttonShowAll->setEnabled(enable);
ui->buttonHideAll->setEnabled(enable);
}
void KX_Pult::setX(const KX_X_Data & data) {
if (!show_x) return;
//ui->graphic->lock();
for (int i = 0; i < KX_X_PACKET_NUM; ++i) {
if (!isNormalDouble(data.x_data[i])) continue;
ui->graphic->addPoint(data.x_data[i], i, false);
values[i]->setText(QString("(%1): %2").arg(data.x_num[i]).arg(data.x_data[i]));
}
//ui->graphic->unlock();
if (!isPause) {
need_update = true;
}
if (!needWrite) return;
stream << QString::number(tm.elapsed() / 1000., 'f', 3) << " " << QTime::currentTime().toString("hh:mm:ss") << " " << wcnt++;
for (int i = 0; i < KX_X_PACKET_NUM; ++i)
stream << " " << QString::number(data.x_data[i], 'f', 4);
stream << "\n";
}
void KX_Pult::addToList(const QString & s, const QColor & c) {
ui->list->addItem(QDateTime::currentDateTime().toString("dd/MM/yyyy hh:ss - ") + s);
ui->list->item(ui->list->count() - 1)->setTextColor(c);
ui->list->scrollToBottom();
}
void KX_Pult::on_buttonRecord_clicked() {
static bool isRec = false;
int cinc = 0;
QString str;
isRec = !isRec;
setControlsEnable(!isRec);
if (isRec) {
tm.restart();
file.close();
file.setFileName(outdir + getNewFileName(cinc));
while (file.exists())
file.setFileName(outdir + getNewFileName(cinc++));
file.open(QIODevice::ReadWrite);
stream.setDevice(&file);
stream << "T V C";
for (int i = 0; i < KX_X_PACKET_NUM; ++i)
stream << " X" + QString::number(checks[i]->spin.value());
stream << "\n";
wcnt = 0;
needWrite = true;
ui->buttonRecord->setText(trUtf8("Finish record"));
ui->buttonRecord->setIcon(icon_stop);
emit recordStarted(QFileInfo(file).completeBaseName());
} else {
needWrite = false;
stream.setDevice(0);
file.close();
ui->buttonRecord->setText(trUtf8("Start record"));
ui->buttonRecord->setIcon(icon_record);
emit recordStopped(QFileInfo(file).completeBaseName());
}
}
void KX_Pult::on_actionClear_triggered() {
switch (clear_target) {
case 0:
ui->list->clear();
break;
case 1:
clearSelected();
break;
default: break;
}
}
void KX_Pult::clearSelected() {
QList<QTreeWidgetItem * > si = ui->treeK->selectedItems();
ui->treeK->setUpdatesEnabled(false);
ui->treeK->blockSignals(true);
foreach (QTreeWidgetItem * i, si) {
int ki = i->text(0).toInt();
i->setText(2, "");
coeffs.setFormula(ki, "");
}
ui->treeK->blockSignals(false);
ui->treeK->setUpdatesEnabled(true);
if (ui->checkKAutoCalculate->isChecked()) {
QApplication::processEvents();
calculate();
}
}
QString KX_Pult::typeName(const QString & n) const {
if (n.isEmpty()) return "";
switch (n[0].toLatin1()) {
case 'l': return trUtf8("list"); break;
case 'b': return trUtf8("bool"); break;
case 'n': return trUtf8("int"); break;
case 'f': return trUtf8("double"); break;
case 'c': return trUtf8("color"); break;
case 'r': return trUtf8("rect"); break;
case 'a': return trUtf8("rect"); break;
case 'p': return trUtf8("point"); break;
case 'v': return trUtf8("vector"); break;
case 'i': return trUtf8("IP"); break;
case 'e': return trUtf8("enum"); break;
case 'F': return trUtf8("file"); break;
case 'D': return trUtf8("dir"); break;
}
return "";
}
void KX_Pult::received(bool ok) {
if (!ok) return;
setX(prot_x->from_x);
}
void KX_Pult::on_treeK_itemClicked(QTreeWidgetItem * item, int column) {
Qt::ItemFlags f = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
if (column == 2) f |= Qt::ItemIsEditable;
item->setFlags(f);
}
void KX_Pult::on_treeK_itemChanged(QTreeWidgetItem * item, int column) {
if (column != 2) return;
int ki = item->text(0).toInt();
coeffs.setFormula(ki, piqt(item->text(column)));
if (ui->checkKAutoCalculate->isChecked())
calculate();
}
QString KX_Pult::getNewFileName(int inc) {
dir.refresh();
dir.setNameFilters(QStringList("Experiment_*.txt"));
return "Experiment_" + QDateTime::currentDateTime().toString("dd_MM_yy__hh_mm_ss") + "__" +
QString::number(dir.entryList().count() + inc) + ".txt";
}
void KX_Pult::on_buttonSendK_clicked() {
on_buttonWrite_clicked();
coeffs.sendCoeffs();
if (timer != 0) killTimer(timer);
timer = startTimer(100);
}
void KX_Pult::on_buttonReceiveK_clicked() {
coeffs.receiveCoeffs();
if (timer != 0) killTimer(timer);
timer = startTimer(100);
}
void KX_Pult::on_buttonShowAll_clicked() {
for (int i = 0; i < KX_X_PACKET_NUM; ++i) {
checks[i]->check.setChecked(true);
//ui->graphic->setGraphicVisible(true, i);
}
}
void KX_Pult::on_buttonHideAll_clicked() {
for (int i = 0; i < KX_X_PACKET_NUM; ++i) {
checks[i]->check.setChecked(false);
//ui->graphic->setGraphicVisible(false, i);
}
}
void KX_Pult::on_buttonRead_clicked() {
coeffs.readCoeffs();
addToList(trUtf8("Read K file \"%1\": %2 coeffs, %3 bytes").arg(PI2QString(coeffs.fileName())).arg(K.size_s()).arg(coeffs.k_content.size_s()), Qt::darkMagenta);
updateTree();
}
void KX_Pult::on_buttonWrite_clicked() {
coeffs.writeCoeffs();
addToList(trUtf8("Write K file \"%1\": %2 coeffs, %3 bytes").arg(PI2QString(coeffs.fileName())).arg(K.size_s()).arg(coeffs.k_content.size_s()), Qt::darkMagenta);
}
void KX_Pult::on_buttonResize_clicked() {
K.resize(ui->spinSize->value());
coeffs.formulas.resize(ui->spinSize->value());
ui->spinSize->setStyleSheet("");
updateTree();
}
void KX_Pult::on_buttonSetKDesc_clicked() {
QString ret = QFileDialog::getOpenFileName(this, trUtf8("Select *.h file with K description"), kdesc_file, "C/C++ header files(*.h *.hpp);;All files(*)");
if (ret.isEmpty()) return;
kdesc_file = QDir::current().relativeFilePath(ret);
updateKDesc(true);
}
void KX_Pult::on_buttonSetCDesc_clicked() {
QString ret = QFileDialog::getOpenFileName(this, trUtf8("Select *.h file with C description"), cdesc_file, "C/C++ header files(*.h *.hpp);;All files(*)");
if (ret.isEmpty()) return;
cdesc_file = QDir::current().relativeFilePath(ret);
updateCDesc();
}
void KX_Pult::on_spinSize_valueChanged(int) {
ui->spinSize->setStyleSheet("");
}
void KX_Pult::k_sendFailed() {
stopWait();
addToList(trUtf8("K not sended"), Qt::darkRed);
}
void KX_Pult::k_sendSucceed() {
stopWait();
addToList(trUtf8("K sended"), Qt::darkGreen);
}
void KX_Pult::k_receiveFailed() {
stopWait();
addToList(trUtf8("K not received"), Qt::darkRed);
}
void KX_Pult::k_receiveSucceed() {
stopWait();
addToList(trUtf8("K received"), Qt::darkGreen);
addToList(trUtf8("Write K file \"%1\": %2 coeffs, %3 bytes").arg(PI2QString(coeffs.fileName())).arg(K.size_s()).arg(coeffs.k_content.size_s()), Qt::darkMagenta);
ui->spinSize->setValue(K.size_s());
updateTree();
//ui->table->setK(coeffsK.k()->data(), coeffsK.count());
}
void KX_Pult::on_spinBuffer_editingFinished() {
ui->graphic->setHistorySize(ui->spinBuffer->value());
}
void KX_Pult::stopWait() {
killTimer(timer);
timer = 0;
ui->labelWait->setText(" ");
}
void KX_Pult::updateGraph() {
ui->graphic->updateGraphics();
}
void KX_Pult::updateDiag() {
ui->labelKReceiver->setText(piqt(coeffs.k_protocol->receiverDeviceName() + " - " + coeffs.k_protocol->receiverDeviceState()));
ui->labelKSender->setText(piqt(coeffs.k_protocol->senderDeviceName()));
ui->spinKSended->setValue(coeffs.k_protocol->sendCount());
ui->spinKReceived->setValue(coeffs.k_protocol->receiveCount());
ui->spinKWrong->setValue(coeffs.k_protocol->wrongCount());
ui->spinKMissed->setValue(coeffs.k_protocol->missedCount());
ui->labelKType->setText("0x" + QString::number(coeffs.k_protocol->from_k.type, 16).toUpper().rightJustified(2, '0'));
ui->labelKAddrPult->setText("0x" + QString::number(coeffs.k_protocol->from_k.addr_to, 16).toUpper().rightJustified(2, '0'));
ui->labelKAddr->setText("0x" + QString::number(coeffs.k_protocol->to_k.addr_to, 16).toUpper().rightJustified(2, '0'));
ui->labelXReceiver->setText(piqt(prot_x->receiverDeviceName() + " - " + prot_x->receiverDeviceState()));
ui->labelXSender->setText(piqt(prot_x->senderDeviceName()));
ui->spinXSended->setValue(prot_x->sendCount());
ui->spinXReceived->setValue(prot_x->receiveCount());
ui->spinXWrong->setValue(prot_x->wrongCount());
ui->spinXMissed->setValue(prot_x->missedCount());
ui->labelXType->setText("0x" + QString::number(prot_x->from_x.type, 16).toUpper().rightJustified(2, '0'));
ui->labelXAddrPult->setText("0x" + QString::number(prot_x->from_x.addr_to, 16).toUpper().rightJustified(2, '0'));
ui->labelXAddr->setText("0x" + QString::number(prot_x->to_x.addr_to, 16).toUpper().rightJustified(2, '0'));
ui->labelCReceiver->setText(piqt(prot_c->receiverDeviceName() + " - " + prot_c->receiverDeviceState()));
ui->labelCSender->setText(piqt(prot_c->senderDeviceName()));
ui->spinCSended->setValue(prot_c->sendCount());
ui->spinCReceived->setValue(prot_c->receiveCount());
ui->spinCWrong->setValue(prot_c->wrongCount());
ui->spinCMissed->setValue(prot_c->missedCount());
ui->labelCType->setText("0x" + QString::number(prot_c->from_c.type, 16).toUpper().rightJustified(2, '0'));
ui->labelCAddrPult->setText("0x" + QString::number(prot_c->from_c.addr_to, 16).toUpper().rightJustified(2, '0'));
ui->labelCAddr->setText("0x" + QString::number(prot_c->to_c.addr_to, 16).toUpper().rightJustified(2, '0'));
}
int KX_Pult::parseHeader(const QString & file, QMap<int, KX_Pult::KDesc> & map) {
map.clear();
QFile f(file);
if (!f.open(QIODevice::ReadOnly)) {
updateTree();
addToList(trUtf8("Update descriptions from \"%1\": error").arg(file), Qt::darkRed);
return 0;
}
addToList(trUtf8("Update descriptions from \"%1\"").arg(file), Qt::darkMagenta);
QTextStream s(&f);
int cind = -1;
bool found = false;
//qDebug() << "\nparse" << file;
while (!s.atEnd()) {
QString line = s.readLine().trimmed(), num, name, type, comment;
int i = line.indexOf("//");
if (i >= 0) {
comment = line.right(line.length() - i - 2);
type = comment.left(1);
comment = comment.right(comment.length() - 1).trimmed();
line = line.left(i).trimmed();
}
if (line.isEmpty()) continue;
if (line.contains("enum")) {
found = true;
continue;
}
if (!found) continue;
if (line.contains('}'))
break;
line.remove(',').remove(' ').remove('\t');
i = line.indexOf("=");
if (i >= 0) {
num = line.right(line.length() - i - 1).trimmed();
line = line.left(i).trimmed();
}
name = line;
if (num.isEmpty())
++cind;
else
cind = Q2PIString(num).toInt();
KDesc kd;
kd.index = cind;
kd.name = name;
kd.type = type;
kd.comment = comment;
map[kd.index] = kd;
//qDebug() << name << cind << type << comment;
}
cind++;
return cind;
}
void KX_Pult::updateKDesc(bool ask_move) {
int cind = parseHeader(kdesc_file, kdesc);
if (K.size_s() < cind) {
ui->spinSize->setValue(cind);
ui->spinSize->setStyleSheet("background-color: rgb(220, 220, 255);");
}
bool move = false;
if (ask_move)
move = (QMessageBox::question(this, "KX Pult", "Save values at associated names?", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes);
updateTree(move);
}
void KX_Pult::updateCDesc() {
parseHeader(cdesc_file, cdesc);
updateCommands();
}
bool stringComp(const QString & s1, const QString & s2) {
if (s1.size() != s2.size())
return s1.size() > s2.size();
return s1 > s2;
}
void KX_Pult::updateTree(bool move) {
int sp = ui->treeK->verticalScrollBar()->value();
QApplication::setOverrideCursor(Qt::WaitCursor);
//qDebug() << "fill tree ...";
QMap<QString, QString> prev_val;
if (move) {
for (int i = 0; i < ui->treeK->topLevelItemCount(); ++i) {
QTreeWidgetItem * ti = ui->treeK->topLevelItem(i);
if (!ti->text(1).isEmpty())
prev_val[ti->text(1)] = ti->text(2);
}
}
ui->treeK->clear();
ui->treeK->setUpdatesEnabled(false);
eval.clearCustomVariables();
for (int i = 0; i < K.size_s(); ++i) {
QTreeWidgetItem * ti = new QTreeWidgetItem();
KDesc kd = kdesc[i];
QString kn = QString("k%1").arg(i);
knames[kn] = i;
knames_sort << kn;
if (eval.content.findVariable(kn) < 0)
eval.content.addVariable(kn, 0., false);
if (!kd.name.isEmpty()) {
knames[kd.name] = i;
knames_sort << kd.name;
eval.content.addVariable(kd.name, 0., false);
}
if (move && !kd.name.isEmpty()) {
if (prev_val.contains(kd.name))
coeffs.setFormula(i, Q2PIString(prev_val[kd.name]));
}
ti->setText(0, QString::number(i));
ti->setText(1, kd.name);
ti->setText(2, PI2QString(coeffs.formula(i)));
ti->setText(3, QString::number(K[i]));
ti->setText(4, typeName(kd.type));
ti->setText(5, kd.comment);
ui->treeK->addTopLevelItem(ti);
}
eval.content.sortVariables();
//qDebug() << "fill tree ok";
//qDebug() << "sort ...";
qSort(knames_sort.begin(), knames_sort.end(), stringComp);
//qDebug() << "names" << knames_sort;
//qDebug() << "sort ok";
QApplication::restoreOverrideCursor();
ui->treeK->setUpdatesEnabled(true);
ui->treeK->verticalScrollBar()->setValue(sp);
calculate();
filterTree();
}
void KX_Pult::updateCommands() {
while (ui->layoutCommands->count() > 0)
delete ui->layoutCommands->itemAt(0)->widget();
QMapIterator<int, KDesc> it(cdesc);
while (it.hasNext()) {
it.next();
KDesc kd = it.value();
QPushButton * b = new QPushButton();
QString text = kd.name;
if (!kd.comment.isEmpty())
text += QString("\n(%1)").arg(kd.comment);
b->setText(text);
b->setProperty("_command", kd.index);
connect(b, SIGNAL(clicked()), this, SLOT(commandClicked()));
ui->layoutCommands->addWidget(b);
}
}
void KX_Pult::filterTree() {
bool he = ui->checkKHideEmpty->isChecked();
bool hn = ui->checkKHideNormal->isChecked();
bool hs = ui->checkKHideExpressions->isChecked();
bool ok = false;
QString fl = ui->lineKSearch->text();
int lc = ui->treeK->topLevelItemCount();
for (int i = 0; i < lc; ++i) {
QTreeWidgetItem * ti = ui->treeK->topLevelItem(i);
if (ti->text(1).isEmpty() && he)
ti->setHidden(true);
else
if (fl.isEmpty())
ti->setHidden(false);
else
ti->setHidden(!ti->text(0).contains(fl, Qt::CaseInsensitive) &&
!ti->text(1).contains(fl, Qt::CaseInsensitive) &&
!ti->text(2).contains(fl, Qt::CaseInsensitive) &&
!ti->text(3).contains(fl, Qt::CaseInsensitive) &&
!ti->text(4).contains(fl, Qt::CaseInsensitive));
if (hn)
if (ti->data(0, Qt::UserRole).toBool())
ti->setHidden(true);
if (hs) {
ti->data(2, Qt::DisplayRole).toDouble(&ok);
if (!ok)
ti->setHidden(true);
}
}
}
void KX_Pult::calculate() {
calculated.clear();
ui->treeK->setUpdatesEnabled(false);
ui->treeK->blockSignals(true);
QApplication::setOverrideCursor(Qt::WaitCursor);
progress(0, 100);
ui->buttonCalculate->setEnabled(false);
QApplication::processEvents();
for (int i = 0; i < K.size_s(); ++i) {
ui->treeK->topLevelItem(i)->setToolTip(2, QString());
ui->treeK->topLevelItem(i)->setToolTip(3, QString());
}
for (int i = 0; i < K.size_s(); ++i) {
progress(i, K.size_s());
calculateExpression(i, QVector<int>());
}
ui->buttonCalculate->setEnabled(true);
ui->progress->setValue(100);
QApplication::restoreOverrideCursor();
ui->treeK->blockSignals(false);
ui->treeK->setUpdatesEnabled(true);
}
bool KX_Pult::calculateExpression(int i, QVector<int> trace) {
if (calculated.contains(i)) return true;
trace << i;
QTreeWidgetItem * ti = ui->treeK->topLevelItem(i);
QString expr = ti->text(2);
if (expr.isEmpty() || expr == "0" || expr == "0,00000000" || expr == "0.00000000") {
markNormal(ti);
calculated << i;
K[i] = 0.;
ti->setText(3, "0");
return true;
}
//ti->setToolTip(2, QString());
if (!eval.check(expr)) {
markError(ti, eval.error());
return false;
}
foreach (const QString & n, knames_sort) {
if (expr.contains(n)) {
int ki = knames.value(n, -1);
if (trace.contains(ki)) {
QString strace;
trace << ki;
for (int j = 0; j < trace.size(); ++j) {
//calculated << trace[j];
if (j > 0) strace += " -> ";
strace += "k" + QString::number(trace[j]);
}
for (int j = 0; j < trace.size(); ++j) {
QTreeWidgetItem * pti = ui->treeK->topLevelItem(trace[j]);
markError(pti, QString("Circular dependency: %1!").arg(strace));
}
return false;
}
if (ki < 0) {
markError(ti);
return false;
}
if (calculated.contains(ki)) {
eval.setVariable(n, K[ki]);
} else {
if (calculateExpression(ki, trace))
eval.setVariable(n, K[ki]);
else {
markError(ti);
return false;
}
}
}
}
markNormal(ti);
calculated << i;
complexd ret = eval.evaluate();
K[i] = ret.real();
ti->setText(3, QString::number(K[i]));
return true;
}
void KX_Pult::markError(QTreeWidgetItem * item, const QString & tool_tip) {
int cc = item->columnCount();
for (int i = 0; i < cc; ++i)
item->setBackgroundColor(i, QColor(255, 200, 200));
if (item->toolTip(2).isEmpty())
item->setToolTip(2, tool_tip);
if (item->toolTip(3).isEmpty())
item->setToolTip(3, tool_tip);
item->setData(0, Qt::UserRole, false);
item->setText(3, "Error");
}
void KX_Pult::markNormal(QTreeWidgetItem * item) {
int cc = item->columnCount();
for (int i = 0; i < cc; ++i)
item->setBackground(i, Qt::NoBrush);
item->setToolTip(2, QString());
item->setToolTip(3, QString());
item->setData(0, Qt::UserRole, true);
}
void KX_Pult::progress(int val, int max) {
if (ctm.elapsed() < 50) return;
ctm.restart();
ui->progress->setValue(qRound(val * 100. / max));
QApplication::processEvents();
}
void KX_Pult::renew(bool write) {
addToList(trUtf8("Update settings from \"%1\"").arg(PI2QString(config_)), Qt::darkMagenta);
dir.setPath(config.getValue("x.output_dir", "./Experiments/").stringValue());
setWindowTitle(config.getValue("title", "Noname").stringValue() + trUtf8(" - KX Pult"));
//if (write) ui->configWidget->write();
if (prot_x != 0) {
prot_x->stop();
delete prot_x;
}
if (prot_c != 0) {
prot_c->stop();
delete prot_c;
}
prot_x = new __KX_Protocol_X(config_, name_x);
prot_c = new __KX_Protocol_C(config_, name_c);
ui->graphic->setAutoXIncrement(prot_x->expectedFrequency() > 0. ? 1. / prot_x->expectedFrequency() : 1.);
coeffs.renew();
CONNECT1(void, bool, prot_x, received, this, received);
}
void KX_Pult::toggledX(int index, bool on) {
ui->graphic->setGraphicVisible(on, index);
}
void KX_Pult::changedX(int index, int num) {
prot_x->to_x.x_num[index] = num;
}
void KX_Pult::commandClicked() {
QPushButton * b = qobject_cast<QPushButton*>(sender());
if (!b) return;
prot_c->sendCommand(b->property("_command").toInt());
}
#include <QScrollBar>
#include <QMessageBox>
#include <math.h>
#include "kx_pult.h"
#include "ui_kx_pult.h"
#include "piqt.h"
#include "qpiconfig.h"
bool isNormalDouble(const double & v) {
#ifdef WINDOWS
return true;
#else
return !isnan(v) && !isinf(v);
#endif
}
XCheck::XCheck(int index): QWidget() {
index_ = index;
setProperty("index", index);
setMouseTracking(true);
check.setText(QString::number(index + 1) + " ");
check.setAutoFillBackground(true);
spin.setMaximum(KX_X_COUNT - 1);
QBoxLayout * l = new QBoxLayout(QBoxLayout::LeftToRight);
l->setMargin(0);
l->setSpacing(2);
l->addWidget(&check);
l->addWidget(&spin);
setLayout(l);
//check.installEventFilter(this);
//spin.installEventFilter(this);
connect(&spin, SIGNAL(valueChanged(int)), this, SLOT(spinChanged(int)));
connect(&check, SIGNAL(toggled(bool)), this, SLOT(checkChanged_(bool)));
}
bool XCheck::eventFilter(QObject * o, QEvent * e) {
if (e->type() == QEvent::Enter)
qApp->postEvent(this, new QEvent(e->type()));
return QWidget::eventFilter(o, e);
}
KX_Pult::KX_Pult(): QMainWindow(), config_("kx_pult.conf"), name_x("x"), name_c("c"),
config(piqt(config_), QIODevice::ReadWrite), coeffs(config_, "k", true) {
//cout << sizeof(coeffsK.k_protocol->to_k) << endl;
ui = new Ui::KX_Pult();
ui->setupUi(this);
ui->configWidget->setQPIConfig(&config);
ui->configWidget->expandAll();
ui->list->viewport()->installEventFilter(this);
ui->treeK->viewport()->installEventFilter(this);
ui->scrollArea->setAutoFillBackground(false);
ui->scrollAreaWidgetContents->setAutoFillBackground(false);
ui->widget->setAutoFillBackground(false);
ui->label_17->setFixedSize(preferredIconSize(1.25, this));
log_menu.addAction(ui->actionClear);
prot_x = 0;
prot_c = 0;
show_x = config.getValue("show_x", true);
if (!show_x)
ui->tabWidget->removeTab(1);
session.setFile("session_KX_Pult.conf");
session.addEntry(this);
session.addEntry(ui->tabWidget);
session.addEntry(ui->checkKHideEmpty);
session.addEntry(ui->checkKHideNormal);
session.addEntry(ui->checkKHideExpressions);
session.addEntry(ui->checkKAutoCalculate);
needWrite = isPause = false;
timer = 0;
//x.resize(KX_X_PACKET_NUM);
//k.resize(K_NUM);
QPalette pal = palette();
QColor col;
ui->graphic->setGraphicsCount(0);
for (int i = 0; i < KX_X_PACKET_NUM; ++i) {
XCheck * xc = new XCheck(i);
xc->installEventFilter(this);
connect(xc, SIGNAL(valueChanged(int, int)), this, SLOT(changedX(int,int)));
connect(xc, SIGNAL(checkChanged(int, bool)), this, SLOT(toggledX(int, bool)));
col = QColor::fromHsv(360 / KX_X_PACKET_NUM * i, 255, 200);
pal.setColor(QPalette::Button, col);
pal.setColor(QPalette::Window, col);
pal.setColor(QPalette::WindowText, invertColor(col));
xc->check.setPalette(pal);
ui->graphic->addGraphic(QString::number(i), col);
ui->graphic->setGraphicVisible(false, i);
checks << xc;
((QGridLayout * )(ui->widgetChecks->layout()))->addWidget(xc, (i / 10) * 2, i % 10);
QLabel * lbl = new QLabel("0"); lbl->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
values << lbl;
((QGridLayout * )(ui->widgetChecks->layout()))->addWidget(lbl, (i / 10) * 2 + 1, i % 10);
//xc->show();
}
renew();
icon_record = QIcon(":/icons/media-record.png");
icon_stop = QIcon(":/icons/media-playback-stop.png");
outdir = dir.absolutePath();
if (!dir.exists()) dir.mkdir(outdir);
outdir += "/";
ui->treeK->setColumnWidth(0, 60);
ui->treeK->setColumnWidth(1, 250);
ui->treeK->setColumnWidth(3, 100);
ui->treeK->setColumnWidth(4, 100);
//ui->table->setK(coeffsK.k()->data(), coeffsK.count());
ui->spinSize->setValue(K.size_s());
addToList(trUtf8("Read K file \"%1\": %2 coeffs, %3 bytes").arg(PI2QString(coeffs.fileName())).arg(K.size_s()).arg(coeffs.k_content.size_s()), Qt::darkMagenta);
CONNECT(void, &coeffs, sendFailed, this, pip_sendFailed);
CONNECT(void, &coeffs, sendSucceed, this, pip_sendSucceed);
CONNECT(void, &coeffs, receiveFailed, this, pip_receiveFailed);
CONNECT(void, &coeffs, receiveSucceed, this, pip_receiveSucceed);
connect(this, SIGNAL(q_k_sendFailed()), this, SLOT(k_sendFailed()), Qt::QueuedConnection);
connect(this, SIGNAL(q_k_sendSucceed()), this, SLOT(k_sendSucceed()), Qt::QueuedConnection);
connect(this, SIGNAL(q_k_receiveFailed()), this, SLOT(k_receiveFailed()), Qt::QueuedConnection);
connect(this, SIGNAL(q_k_receiveSucceed()), this, SLOT(k_receiveSucceed()), Qt::QueuedConnection);
connect(&timer_diag, SIGNAL(timeout()), this, SLOT(updateDiag()));
connect(&session, SIGNAL(loading(QPIConfig&)), this, SLOT(loading(QPIConfig&)));
connect(&session, SIGNAL(saving(QPIConfig&)), this, SLOT(saving(QPIConfig&)));
connect(ui->checkKHideEmpty, SIGNAL(toggled(bool)), this, SLOT(filterTree()));
connect(ui->checkKHideNormal, SIGNAL(toggled(bool)), this, SLOT(filterTree()));
connect(ui->checkKHideExpressions, SIGNAL(toggled(bool)), this, SLOT(filterTree()));
connect(ui->lineKSearch, SIGNAL(textChanged(QString)), this, SLOT(filterTree()));
session.load();
updateKDesc();
updateCDesc();
timer_diag.start(40);
timer_update = startTimer(25);
}
KX_Pult::~KX_Pult() {
session.save();
}
void KX_Pult::loading(QPIConfig & conf) {
kdesc_file = conf.getValue("kdesc_file").stringValue();
cdesc_file = conf.getValue("cdesc_file").stringValue();
}
void KX_Pult::saving(QPIConfig & conf) {
conf.setValue("kdesc_file", kdesc_file);
conf.setValue("cdesc_file", cdesc_file);
}
bool KX_Pult::eventFilter(QObject * o, QEvent * e) {
if (o == ui->list->viewport()) {
if (e->type() == QEvent::ContextMenu) {
clear_target = 0;
log_menu.popup(((QContextMenuEvent*)e)->globalPos());
}
return QMainWindow::eventFilter(o, e);
}
if (o == ui->treeK->viewport()) {
if (e->type() == QEvent::ContextMenu) {
clear_target = 1;
log_menu.popup(((QContextMenuEvent*)e)->globalPos());
}
return QMainWindow::eventFilter(o, e);
}
int ind = o->property("index").toInt();
//qDebug() << "event" << i << e->type();
switch (e->type()) {
case QEvent::Enter:
ui->graphic->setAutoUpdate(false);
for (int i = 0; i < KX_X_PACKET_NUM; ++i)
ui->graphic->setGraphicLineWidth(ind == i ? 3. : 1., i);
ui->graphic->setAutoUpdate(true);
ui->graphic->update();
break;
case QEvent::Leave:
ui->graphic->setAutoUpdate(false);
for (int i = 0; i < KX_X_PACKET_NUM; ++i)
ui->graphic->setGraphicLineWidth(1., i);
ui->graphic->setAutoUpdate(true);
ui->graphic->update();
break;
default: break;
}
return QMainWindow::eventFilter(o, e);
}
void KX_Pult::timerEvent(QTimerEvent * e) {
if (e->timerId() == timer_update) {
if (need_update) {
need_update = false;
ui->graphic->updateGraphics();
}
}
if (e->timerId() == timer) {
static QString sPI = QString::number(atan(1) * 4., 'f', 14).leftJustified(14);
static int cnt = 0;
int si = qMax<int>(cnt - 6, 0);
++cnt;
cnt %= 23;
ui->labelWait->setText(QString(si, QChar(' ')) + sPI.mid(cnt - 6, 6).trimmed());
if (!coeffs.isReady()) return;
//ui->table->setK(coeffsK.k()->data(), coeffsK.count());
//ui->table->showK();
}
}
void KX_Pult::setControlsEnable(bool enable) {
foreach (XCheck * i, checks)
i->setEnabled(enable);
ui->buttonShowAll->setEnabled(enable);
ui->buttonHideAll->setEnabled(enable);
}
void KX_Pult::setX(const KX_X_Data & data) {
if (!show_x) return;
//ui->graphic->lock();
for (int i = 0; i < KX_X_PACKET_NUM; ++i) {
if (!isNormalDouble(data.x_data[i])) continue;
ui->graphic->addPoint(data.x_data[i], i, false);
values[i]->setText(QString("(%1): %2").arg(data.x_num[i]).arg(data.x_data[i]));
}
//ui->graphic->unlock();
if (!isPause) {
need_update = true;
}
if (!needWrite) return;
stream << QString::number(tm.elapsed() / 1000., 'f', 3) << " " << QTime::currentTime().toString("hh:mm:ss") << " " << wcnt++;
for (int i = 0; i < KX_X_PACKET_NUM; ++i)
stream << " " << QString::number(data.x_data[i], 'f', 4);
stream << "\n";
}
void KX_Pult::addToList(const QString & s, const QColor & c) {
ui->list->addItem(QDateTime::currentDateTime().toString("dd/MM/yyyy hh:ss - ") + s);
ui->list->item(ui->list->count() - 1)->setTextColor(c);
ui->list->scrollToBottom();
}
void KX_Pult::on_buttonRecord_clicked() {
static bool isRec = false;
int cinc = 0;
QString str;
isRec = !isRec;
setControlsEnable(!isRec);
if (isRec) {
tm.restart();
file.close();
file.setFileName(outdir + getNewFileName(cinc));
while (file.exists())
file.setFileName(outdir + getNewFileName(cinc++));
file.open(QIODevice::ReadWrite);
stream.setDevice(&file);
stream << "T V C";
for (int i = 0; i < KX_X_PACKET_NUM; ++i)
stream << " X" + QString::number(checks[i]->spin.value());
stream << "\n";
wcnt = 0;
needWrite = true;
ui->buttonRecord->setText(trUtf8("Finish record"));
ui->buttonRecord->setIcon(icon_stop);
emit recordStarted(QFileInfo(file).completeBaseName());
} else {
needWrite = false;
stream.setDevice(0);
file.close();
ui->buttonRecord->setText(trUtf8("Start record"));
ui->buttonRecord->setIcon(icon_record);
emit recordStopped(QFileInfo(file).completeBaseName());
}
}
void KX_Pult::on_actionClear_triggered() {
switch (clear_target) {
case 0:
ui->list->clear();
break;
case 1:
clearSelected();
break;
default: break;
}
}
void KX_Pult::clearSelected() {
QList<QTreeWidgetItem * > si = ui->treeK->selectedItems();
ui->treeK->setUpdatesEnabled(false);
ui->treeK->blockSignals(true);
foreach (QTreeWidgetItem * i, si) {
int ki = i->text(0).toInt();
i->setText(2, "");
coeffs.setFormula(ki, "");
}
ui->treeK->blockSignals(false);
ui->treeK->setUpdatesEnabled(true);
if (ui->checkKAutoCalculate->isChecked()) {
QApplication::processEvents();
calculate();
}
}
QString KX_Pult::typeName(const QString & n) const {
if (n.isEmpty()) return "";
switch (n[0].toLatin1()) {
case 'l': return trUtf8("list"); break;
case 'b': return trUtf8("bool"); break;
case 'n': return trUtf8("int"); break;
case 'f': return trUtf8("double"); break;
case 'c': return trUtf8("color"); break;
case 'r': return trUtf8("rect"); break;
case 'a': return trUtf8("rect"); break;
case 'p': return trUtf8("point"); break;
case 'v': return trUtf8("vector"); break;
case 'i': return trUtf8("IP"); break;
case 'e': return trUtf8("enum"); break;
case 'F': return trUtf8("file"); break;
case 'D': return trUtf8("dir"); break;
}
return "";
}
void KX_Pult::received(bool ok) {
if (!ok) return;
setX(prot_x->from_x);
}
void KX_Pult::on_treeK_itemClicked(QTreeWidgetItem * item, int column) {
Qt::ItemFlags f = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
if (column == 2) f |= Qt::ItemIsEditable;
item->setFlags(f);
}
void KX_Pult::on_treeK_itemChanged(QTreeWidgetItem * item, int column) {
if (column != 2) return;
int ki = item->text(0).toInt();
coeffs.setFormula(ki, piqt(item->text(column)));
if (ui->checkKAutoCalculate->isChecked())
calculate();
}
QString KX_Pult::getNewFileName(int inc) {
dir.refresh();
dir.setNameFilters(QStringList("Experiment_*.txt"));
return "Experiment_" + QDateTime::currentDateTime().toString("dd_MM_yy__hh_mm_ss") + "__" +
QString::number(dir.entryList().count() + inc) + ".txt";
}
void KX_Pult::on_buttonSendK_clicked() {
on_buttonWrite_clicked();
coeffs.sendCoeffs();
if (timer != 0) killTimer(timer);
timer = startTimer(100);
}
void KX_Pult::on_buttonReceiveK_clicked() {
coeffs.receiveCoeffs();
if (timer != 0) killTimer(timer);
timer = startTimer(100);
}
void KX_Pult::on_buttonShowAll_clicked() {
for (int i = 0; i < KX_X_PACKET_NUM; ++i) {
checks[i]->check.setChecked(true);
//ui->graphic->setGraphicVisible(true, i);
}
}
void KX_Pult::on_buttonHideAll_clicked() {
for (int i = 0; i < KX_X_PACKET_NUM; ++i) {
checks[i]->check.setChecked(false);
//ui->graphic->setGraphicVisible(false, i);
}
}
void KX_Pult::on_buttonRead_clicked() {
coeffs.readCoeffs();
addToList(trUtf8("Read K file \"%1\": %2 coeffs, %3 bytes").arg(PI2QString(coeffs.fileName())).arg(K.size_s()).arg(coeffs.k_content.size_s()), Qt::darkMagenta);
updateTree();
}
void KX_Pult::on_buttonWrite_clicked() {
coeffs.writeCoeffs();
addToList(trUtf8("Write K file \"%1\": %2 coeffs, %3 bytes").arg(PI2QString(coeffs.fileName())).arg(K.size_s()).arg(coeffs.k_content.size_s()), Qt::darkMagenta);
}
void KX_Pult::on_buttonResize_clicked() {
K.resize(ui->spinSize->value());
coeffs.formulas.resize(ui->spinSize->value());
ui->spinSize->setStyleSheet("");
updateTree();
}
void KX_Pult::on_buttonSetKDesc_clicked() {
QString ret = QFileDialog::getOpenFileName(this, trUtf8("Select *.h file with K description"), kdesc_file, "C/C++ header files(*.h *.hpp);;All files(*)");
if (ret.isEmpty()) return;
kdesc_file = QDir::current().relativeFilePath(ret);
updateKDesc(true);
}
void KX_Pult::on_buttonSetCDesc_clicked() {
QString ret = QFileDialog::getOpenFileName(this, trUtf8("Select *.h file with C description"), cdesc_file, "C/C++ header files(*.h *.hpp);;All files(*)");
if (ret.isEmpty()) return;
cdesc_file = QDir::current().relativeFilePath(ret);
updateCDesc();
}
void KX_Pult::on_spinSize_valueChanged(int) {
ui->spinSize->setStyleSheet("");
}
void KX_Pult::k_sendFailed() {
stopWait();
addToList(trUtf8("K not sended"), Qt::darkRed);
}
void KX_Pult::k_sendSucceed() {
stopWait();
addToList(trUtf8("K sended"), Qt::darkGreen);
}
void KX_Pult::k_receiveFailed() {
stopWait();
addToList(trUtf8("K not received"), Qt::darkRed);
}
void KX_Pult::k_receiveSucceed() {
stopWait();
addToList(trUtf8("K received"), Qt::darkGreen);
addToList(trUtf8("Write K file \"%1\": %2 coeffs, %3 bytes").arg(PI2QString(coeffs.fileName())).arg(K.size_s()).arg(coeffs.k_content.size_s()), Qt::darkMagenta);
ui->spinSize->setValue(K.size_s());
updateTree();
//ui->table->setK(coeffsK.k()->data(), coeffsK.count());
}
void KX_Pult::on_spinBuffer_editingFinished() {
ui->graphic->setHistorySize(ui->spinBuffer->value());
}
void KX_Pult::stopWait() {
killTimer(timer);
timer = 0;
ui->labelWait->setText(" ");
}
void KX_Pult::updateGraph() {
ui->graphic->updateGraphics();
}
void KX_Pult::updateDiag() {
ui->labelKReceiver->setText(piqt(coeffs.k_protocol->receiverDeviceName() + " - " + coeffs.k_protocol->receiverDeviceState()));
ui->labelKSender->setText(piqt(coeffs.k_protocol->senderDeviceName()));
ui->spinKSended->setValue(coeffs.k_protocol->sendCount());
ui->spinKReceived->setValue(coeffs.k_protocol->receiveCount());
ui->spinKWrong->setValue(coeffs.k_protocol->wrongCount());
ui->spinKMissed->setValue(coeffs.k_protocol->missedCount());
ui->labelKType->setText("0x" + QString::number(coeffs.k_protocol->from_k.type, 16).toUpper().rightJustified(2, '0'));
ui->labelKAddrPult->setText("0x" + QString::number(coeffs.k_protocol->from_k.addr_to, 16).toUpper().rightJustified(2, '0'));
ui->labelKAddr->setText("0x" + QString::number(coeffs.k_protocol->to_k.addr_to, 16).toUpper().rightJustified(2, '0'));
ui->labelXReceiver->setText(piqt(prot_x->receiverDeviceName() + " - " + prot_x->receiverDeviceState()));
ui->labelXSender->setText(piqt(prot_x->senderDeviceName()));
ui->spinXSended->setValue(prot_x->sendCount());
ui->spinXReceived->setValue(prot_x->receiveCount());
ui->spinXWrong->setValue(prot_x->wrongCount());
ui->spinXMissed->setValue(prot_x->missedCount());
ui->labelXType->setText("0x" + QString::number(prot_x->from_x.type, 16).toUpper().rightJustified(2, '0'));
ui->labelXAddrPult->setText("0x" + QString::number(prot_x->from_x.addr_to, 16).toUpper().rightJustified(2, '0'));
ui->labelXAddr->setText("0x" + QString::number(prot_x->to_x.addr_to, 16).toUpper().rightJustified(2, '0'));
ui->labelCReceiver->setText(piqt(prot_c->receiverDeviceName() + " - " + prot_c->receiverDeviceState()));
ui->labelCSender->setText(piqt(prot_c->senderDeviceName()));
ui->spinCSended->setValue(prot_c->sendCount());
ui->spinCReceived->setValue(prot_c->receiveCount());
ui->spinCWrong->setValue(prot_c->wrongCount());
ui->spinCMissed->setValue(prot_c->missedCount());
ui->labelCType->setText("0x" + QString::number(prot_c->from_c.type, 16).toUpper().rightJustified(2, '0'));
ui->labelCAddrPult->setText("0x" + QString::number(prot_c->from_c.addr_to, 16).toUpper().rightJustified(2, '0'));
ui->labelCAddr->setText("0x" + QString::number(prot_c->to_c.addr_to, 16).toUpper().rightJustified(2, '0'));
}
int KX_Pult::parseHeader(const QString & file, QMap<int, KX_Pult::KDesc> & map) {
map.clear();
QFile f(file);
if (!f.open(QIODevice::ReadOnly)) {
updateTree();
addToList(trUtf8("Update descriptions from \"%1\": error").arg(file), Qt::darkRed);
return 0;
}
addToList(trUtf8("Update descriptions from \"%1\"").arg(file), Qt::darkMagenta);
QTextStream s(&f);
int cind = -1;
bool found = false;
//qDebug() << "\nparse" << file;
while (!s.atEnd()) {
QString line = s.readLine().trimmed(), num, name, type, comment;
int i = line.indexOf("//");
if (i >= 0) {
comment = line.right(line.length() - i - 2);
type = comment.left(1);
comment = comment.right(comment.length() - 1).trimmed();
line = line.left(i).trimmed();
}
if (line.isEmpty()) continue;
if (line.contains("enum")) {
found = true;
continue;
}
if (!found) continue;
if (line.contains('}'))
break;
line.remove(',').remove(' ').remove('\t');
i = line.indexOf("=");
if (i >= 0) {
num = line.right(line.length() - i - 1).trimmed();
line = line.left(i).trimmed();
}
name = line;
if (num.isEmpty())
++cind;
else
cind = Q2PIString(num).toInt();
KDesc kd;
kd.index = cind;
kd.name = name;
kd.type = type;
kd.comment = comment;
map[kd.index] = kd;
//qDebug() << name << cind << type << comment;
}
cind++;
return cind;
}
void KX_Pult::updateKDesc(bool ask_move) {
int cind = parseHeader(kdesc_file, kdesc);
if (K.size_s() < cind) {
ui->spinSize->setValue(cind);
ui->spinSize->setStyleSheet("background-color: rgb(220, 220, 255);");
}
bool move = false;
if (ask_move)
move = (QMessageBox::question(this, "KX Pult", "Save values at associated names?", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes);
updateTree(move);
}
void KX_Pult::updateCDesc() {
parseHeader(cdesc_file, cdesc);
updateCommands();
}
bool stringComp(const QString & s1, const QString & s2) {
if (s1.size() != s2.size())
return s1.size() > s2.size();
return s1 > s2;
}
void KX_Pult::updateTree(bool move) {
int sp = ui->treeK->verticalScrollBar()->value();
QApplication::setOverrideCursor(Qt::WaitCursor);
//qDebug() << "fill tree ...";
QMap<QString, QString> prev_val;
if (move) {
for (int i = 0; i < ui->treeK->topLevelItemCount(); ++i) {
QTreeWidgetItem * ti = ui->treeK->topLevelItem(i);
if (!ti->text(1).isEmpty())
prev_val[ti->text(1)] = ti->text(2);
}
}
ui->treeK->clear();
ui->treeK->setUpdatesEnabled(false);
eval.clearCustomVariables();
for (int i = 0; i < K.size_s(); ++i) {
QTreeWidgetItem * ti = new QTreeWidgetItem();
KDesc kd = kdesc[i];
QString kn = QString("k%1").arg(i);
knames[kn] = i;
knames_sort << kn;
if (eval.content.findVariable(kn) < 0)
eval.content.addVariable(kn, 0., false);
if (!kd.name.isEmpty()) {
knames[kd.name] = i;
knames_sort << kd.name;
eval.content.addVariable(kd.name, 0., false);
}
if (move && !kd.name.isEmpty()) {
if (prev_val.contains(kd.name))
coeffs.setFormula(i, Q2PIString(prev_val[kd.name]));
}
ti->setText(0, QString::number(i));
ti->setText(1, kd.name);
ti->setText(2, PI2QString(coeffs.formula(i)));
ti->setText(3, QString::number(K[i]));
ti->setText(4, typeName(kd.type));
ti->setText(5, kd.comment);
ui->treeK->addTopLevelItem(ti);
}
eval.content.sortVariables();
//qDebug() << "fill tree ok";
//qDebug() << "sort ...";
qSort(knames_sort.begin(), knames_sort.end(), stringComp);
//qDebug() << "names" << knames_sort;
//qDebug() << "sort ok";
QApplication::restoreOverrideCursor();
ui->treeK->setUpdatesEnabled(true);
ui->treeK->verticalScrollBar()->setValue(sp);
calculate();
filterTree();
}
void KX_Pult::updateCommands() {
while (ui->layoutCommands->count() > 0)
delete ui->layoutCommands->itemAt(0)->widget();
QMapIterator<int, KDesc> it(cdesc);
while (it.hasNext()) {
it.next();
KDesc kd = it.value();
QPushButton * b = new QPushButton();
QString text = kd.name;
if (!kd.comment.isEmpty())
text += QString("\n(%1)").arg(kd.comment);
b->setText(text);
b->setProperty("_command", kd.index);
connect(b, SIGNAL(clicked()), this, SLOT(commandClicked()));
ui->layoutCommands->addWidget(b);
}
}
void KX_Pult::filterTree() {
bool he = ui->checkKHideEmpty->isChecked();
bool hn = ui->checkKHideNormal->isChecked();
bool hs = ui->checkKHideExpressions->isChecked();
bool ok = false;
QString fl = ui->lineKSearch->text();
int lc = ui->treeK->topLevelItemCount();
for (int i = 0; i < lc; ++i) {
QTreeWidgetItem * ti = ui->treeK->topLevelItem(i);
if (ti->text(1).isEmpty() && he)
ti->setHidden(true);
else
if (fl.isEmpty())
ti->setHidden(false);
else
ti->setHidden(!ti->text(0).contains(fl, Qt::CaseInsensitive) &&
!ti->text(1).contains(fl, Qt::CaseInsensitive) &&
!ti->text(2).contains(fl, Qt::CaseInsensitive) &&
!ti->text(3).contains(fl, Qt::CaseInsensitive) &&
!ti->text(4).contains(fl, Qt::CaseInsensitive));
if (hn)
if (ti->data(0, Qt::UserRole).toBool())
ti->setHidden(true);
if (hs) {
ti->data(2, Qt::DisplayRole).toDouble(&ok);
if (!ok)
ti->setHidden(true);
}
}
}
void KX_Pult::calculate() {
calculated.clear();
ui->treeK->setUpdatesEnabled(false);
ui->treeK->blockSignals(true);
QApplication::setOverrideCursor(Qt::WaitCursor);
progress(0, 100);
ui->buttonCalculate->setEnabled(false);
QApplication::processEvents();
for (int i = 0; i < K.size_s(); ++i) {
ui->treeK->topLevelItem(i)->setToolTip(2, QString());
ui->treeK->topLevelItem(i)->setToolTip(3, QString());
}
for (int i = 0; i < K.size_s(); ++i) {
progress(i, K.size_s());
calculateExpression(i, QVector<int>());
}
ui->buttonCalculate->setEnabled(true);
ui->progress->setValue(100);
QApplication::restoreOverrideCursor();
ui->treeK->blockSignals(false);
ui->treeK->setUpdatesEnabled(true);
}
bool KX_Pult::calculateExpression(int i, QVector<int> trace) {
if (calculated.contains(i)) return true;
trace << i;
QTreeWidgetItem * ti = ui->treeK->topLevelItem(i);
QString expr = ti->text(2);
if (expr.isEmpty() || expr == "0" || expr == "0,00000000" || expr == "0.00000000") {
markNormal(ti);
calculated << i;
K[i] = 0.;
ti->setText(3, "0");
return true;
}
//ti->setToolTip(2, QString());
if (!eval.check(expr)) {
markError(ti, eval.error());
return false;
}
foreach (const QString & n, knames_sort) {
if (expr.contains(n)) {
int ki = knames.value(n, -1);
if (trace.contains(ki)) {
QString strace;
trace << ki;
for (int j = 0; j < trace.size(); ++j) {
//calculated << trace[j];
if (j > 0) strace += " -> ";
strace += "k" + QString::number(trace[j]);
}
for (int j = 0; j < trace.size(); ++j) {
QTreeWidgetItem * pti = ui->treeK->topLevelItem(trace[j]);
markError(pti, QString("Circular dependency: %1!").arg(strace));
}
return false;
}
if (ki < 0) {
markError(ti);
return false;
}
if (calculated.contains(ki)) {
eval.setVariable(n, K[ki]);
} else {
if (calculateExpression(ki, trace))
eval.setVariable(n, K[ki]);
else {
markError(ti);
return false;
}
}
}
}
markNormal(ti);
calculated << i;
complexd ret = eval.evaluate();
K[i] = ret.real();
ti->setText(3, QString::number(K[i]));
return true;
}
void KX_Pult::markError(QTreeWidgetItem * item, const QString & tool_tip) {
int cc = item->columnCount();
for (int i = 0; i < cc; ++i)
item->setBackgroundColor(i, QColor(255, 200, 200));
if (item->toolTip(2).isEmpty())
item->setToolTip(2, tool_tip);
if (item->toolTip(3).isEmpty())
item->setToolTip(3, tool_tip);
item->setData(0, Qt::UserRole, false);
item->setText(3, "Error");
}
void KX_Pult::markNormal(QTreeWidgetItem * item) {
int cc = item->columnCount();
for (int i = 0; i < cc; ++i)
item->setBackground(i, Qt::NoBrush);
item->setToolTip(2, QString());
item->setToolTip(3, QString());
item->setData(0, Qt::UserRole, true);
}
void KX_Pult::progress(int val, int max) {
if (ctm.elapsed() < 50) return;
ctm.restart();
ui->progress->setValue(qRound(val * 100. / max));
QApplication::processEvents();
}
void KX_Pult::renew(bool write) {
addToList(trUtf8("Update settings from \"%1\"").arg(PI2QString(config_)), Qt::darkMagenta);
dir.setPath(config.getValue("x.output_dir", "./Experiments/").stringValue());
setWindowTitle(config.getValue("title", "Noname").stringValue() + trUtf8(" - KX Pult"));
//if (write) ui->configWidget->write();
if (prot_x != 0) {
prot_x->stop();
delete prot_x;
}
if (prot_c != 0) {
prot_c->stop();
delete prot_c;
}
prot_x = new __KX_Protocol_X(config_, name_x);
prot_c = new __KX_Protocol_C(config_, name_c);
ui->graphic->setAutoXIncrement(prot_x->expectedFrequency() > 0. ? 1. / prot_x->expectedFrequency() : 1.);
coeffs.renew();
CONNECT1(void, bool, prot_x, received, this, received);
}
void KX_Pult::toggledX(int index, bool on) {
ui->graphic->setGraphicVisible(on, index);
}
void KX_Pult::changedX(int index, int num) {
prot_x->to_x.x_num[index] = num;
}
void KX_Pult::commandClicked() {
QPushButton * b = qobject_cast<QPushButton*>(sender());
if (!b) return;
prot_c->sendCommand(b->property("_command").toInt());
}

View File

@@ -1,170 +1,170 @@
#ifndef KX_PULT_H
#define KX_PULT_H
#include <QDialog>
#include <QSpinBox>
#include <QFont>
#include <QRect>
#include <QFile>
#include <QVector>
#include <QDir>
#include <QTextStream>
#include <QDebug>
#include <QBoxLayout>
#include <QCheckBox>
#include <QMainWindow>
#include <QTimer>
#include <QTime>
#include <QMenu>
#include <QMetaObject>
#include <QTreeWidgetItem>
#include <QLabel>
#include "kx_coeffs.h"
#include "kx_protocol_x.h"
#include "kx_protocol_c.h"
#include "piqt.h"
#include "session_manager.h"
#include "qpievaluator.h"
class XCheck: public QWidget {
Q_OBJECT
public:
explicit XCheck(int index);
QCheckBox check;
QSpinBox spin;
private:
bool eventFilter(QObject * o, QEvent * e);
int index_;
private slots:
void spinChanged(int value) {check.setChecked(true); emit valueChanged(index_, value);}
void checkChanged_(bool value) {emit checkChanged(index_, value);}
signals:
void valueChanged(int index, int value);
void checkChanged(int index, bool on);
};
namespace Ui {
class KX_Pult;
};
class KX_Pult: public QMainWindow, public PIObject
{
Q_OBJECT
PIOBJECT(KX_Pult)
public:
KX_Pult();
~KX_Pult();
private:
struct KDesc {
KDesc() {index = -1;}
int index;
QString name;
QString type;
QString comment;
QString value;
};
bool eventFilter(QObject * o, QEvent * e);
void timerEvent(QTimerEvent * );
void setControlsEnable(bool enable);
void setX(const KX_X_Data & data);
void addToList(const QString & s, const QColor & c);
QString getNewFileName(int inc);
QColor invertColor(QColor col) {return QColor(255 - col.red(), 255 - col.green(), 255 - col.blue());}
void stopWait();
bool calculateExpression(int i, QVector<int> trace);
void markError(QTreeWidgetItem * item, const QString & tool_tip = QString());
void markNormal(QTreeWidgetItem * item);
void progress(int val, int max);
void clearSelected();
QString typeName(const QString & n) const;
int parseHeader(const QString & file, QMap<int, KDesc> & map);
EVENT_HANDLER1(void, received, bool, ok);
EVENT_HANDLER(void, pip_sendFailed) {emit q_k_sendFailed();}
EVENT_HANDLER(void, pip_sendSucceed) {emit q_k_sendSucceed();}
EVENT_HANDLER(void, pip_receiveFailed) {emit q_k_receiveFailed();}
EVENT_HANDLER(void, pip_receiveSucceed) {emit q_k_receiveSucceed();}
QVector<XCheck * > checks;
QVector<QLabel * > values;
Ui::KX_Pult * ui;
PIString config_, name_x, name_c;
QDir dir;
QString outdir, kdesc_file, cdesc_file;
QFile file;
QTime tm, ctm;
QIcon icon_record, icon_stop;
QTextStream stream;
QTimer timer_diag;
QMap<int, KDesc> kdesc, cdesc;
QMap<QString, int> knames;
QSet<int> calculated;
QStringList knames_sort;
QPIEvaluator eval;
SessionManager session;
QPIConfig config;
QMenu log_menu;
//QVector<float> k, x;
KX_Coefficients coeffs;
__KX_Protocol_X * prot_x;
__KX_Protocol_C * prot_c;
int csize, wcnt, timer, timer_update, clear_target;
bool needWrite, isPause, need_update, show_x;
private slots:
void loading(QPIConfig & conf);
void saving(QPIConfig & conf);
void updateGraph();
void updateDiag();
void updateKDesc(bool ask_move = false);
void updateCDesc();
void updateTree(bool move = false);
void updateCommands();
void filterTree();
void calculate();
void renew(bool write = true);
void toggledX(int index, bool on);
void changedX(int index, int num);
void commandClicked();
void k_sendFailed();
void k_sendSucceed();
void k_receiveFailed();
void k_receiveSucceed();
void on_spinBuffer_editingFinished();
void on_buttonSendK_clicked();
void on_buttonReceiveK_clicked();
void on_buttonShowAll_clicked();
void on_buttonHideAll_clicked();
void on_buttonRead_clicked();
void on_buttonWrite_clicked();
void on_buttonResize_clicked();
void on_buttonSetKDesc_clicked();
void on_buttonReparseKDesc_clicked() {updateKDesc(true);}
void on_buttonSetCDesc_clicked();
void on_buttonReparseCDesc_clicked() {updateCDesc();}
void on_buttonCalculate_clicked() {calculate();}
void on_buttonApply_clicked() {renew();}
void on_spinSize_valueChanged(int);
void on_buttonPause_toggled(bool on) {isPause = on;}
void on_buttonRecord_clicked();
void on_treeK_itemClicked(QTreeWidgetItem * item, int column);
void on_treeK_itemChanged(QTreeWidgetItem * item, int column);
void on_actionClear_triggered();
signals:
void q_k_sendFailed();
void q_k_sendSucceed();
void q_k_receiveFailed();
void q_k_receiveSucceed();
void recordStarted(const QString & fileName);
void recordStopped(const QString & fileName);
};
#endif // KX_PULT_H
#ifndef KX_PULT_H
#define KX_PULT_H
#include <QDialog>
#include <QSpinBox>
#include <QFont>
#include <QRect>
#include <QFile>
#include <QVector>
#include <QDir>
#include <QTextStream>
#include <QDebug>
#include <QBoxLayout>
#include <QCheckBox>
#include <QMainWindow>
#include <QTimer>
#include <QTime>
#include <QMenu>
#include <QMetaObject>
#include <QTreeWidgetItem>
#include <QLabel>
#include "kx_coeffs.h"
#include "kx_protocol_x.h"
#include "kx_protocol_c.h"
#include "piqt.h"
#include "session_manager.h"
#include "qpievaluator.h"
class XCheck: public QWidget {
Q_OBJECT
public:
explicit XCheck(int index);
QCheckBox check;
QSpinBox spin;
private:
bool eventFilter(QObject * o, QEvent * e);
int index_;
private slots:
void spinChanged(int value) {check.setChecked(true); emit valueChanged(index_, value);}
void checkChanged_(bool value) {emit checkChanged(index_, value);}
signals:
void valueChanged(int index, int value);
void checkChanged(int index, bool on);
};
namespace Ui {
class KX_Pult;
};
class KX_Pult: public QMainWindow, public PIObject
{
Q_OBJECT
PIOBJECT(KX_Pult)
public:
KX_Pult();
~KX_Pult();
private:
struct KDesc {
KDesc() {index = -1;}
int index;
QString name;
QString type;
QString comment;
QString value;
};
bool eventFilter(QObject * o, QEvent * e);
void timerEvent(QTimerEvent * );
void setControlsEnable(bool enable);
void setX(const KX_X_Data & data);
void addToList(const QString & s, const QColor & c);
QString getNewFileName(int inc);
QColor invertColor(QColor col) {return QColor(255 - col.red(), 255 - col.green(), 255 - col.blue());}
void stopWait();
bool calculateExpression(int i, QVector<int> trace);
void markError(QTreeWidgetItem * item, const QString & tool_tip = QString());
void markNormal(QTreeWidgetItem * item);
void progress(int val, int max);
void clearSelected();
QString typeName(const QString & n) const;
int parseHeader(const QString & file, QMap<int, KDesc> & map);
EVENT_HANDLER1(void, received, bool, ok);
EVENT_HANDLER(void, pip_sendFailed) {emit q_k_sendFailed();}
EVENT_HANDLER(void, pip_sendSucceed) {emit q_k_sendSucceed();}
EVENT_HANDLER(void, pip_receiveFailed) {emit q_k_receiveFailed();}
EVENT_HANDLER(void, pip_receiveSucceed) {emit q_k_receiveSucceed();}
QVector<XCheck * > checks;
QVector<QLabel * > values;
Ui::KX_Pult * ui;
PIString config_, name_x, name_c;
QDir dir;
QString outdir, kdesc_file, cdesc_file;
QFile file;
QTime tm, ctm;
QIcon icon_record, icon_stop;
QTextStream stream;
QTimer timer_diag;
QMap<int, KDesc> kdesc, cdesc;
QMap<QString, int> knames;
QSet<int> calculated;
QStringList knames_sort;
QPIEvaluator eval;
SessionManager session;
QPIConfig config;
QMenu log_menu;
//QVector<float> k, x;
KX_Coefficients coeffs;
__KX_Protocol_X * prot_x;
__KX_Protocol_C * prot_c;
int csize, wcnt, timer, timer_update, clear_target;
bool needWrite, isPause, need_update, show_x;
private slots:
void loading(QPIConfig & conf);
void saving(QPIConfig & conf);
void updateGraph();
void updateDiag();
void updateKDesc(bool ask_move = false);
void updateCDesc();
void updateTree(bool move = false);
void updateCommands();
void filterTree();
void calculate();
void renew(bool write = true);
void toggledX(int index, bool on);
void changedX(int index, int num);
void commandClicked();
void k_sendFailed();
void k_sendSucceed();
void k_receiveFailed();
void k_receiveSucceed();
void on_spinBuffer_editingFinished();
void on_buttonSendK_clicked();
void on_buttonReceiveK_clicked();
void on_buttonShowAll_clicked();
void on_buttonHideAll_clicked();
void on_buttonRead_clicked();
void on_buttonWrite_clicked();
void on_buttonResize_clicked();
void on_buttonSetKDesc_clicked();
void on_buttonReparseKDesc_clicked() {updateKDesc(true);}
void on_buttonSetCDesc_clicked();
void on_buttonReparseCDesc_clicked() {updateCDesc();}
void on_buttonCalculate_clicked() {calculate();}
void on_buttonApply_clicked() {renew();}
void on_spinSize_valueChanged(int);
void on_buttonPause_toggled(bool on) {isPause = on;}
void on_buttonRecord_clicked();
void on_treeK_itemClicked(QTreeWidgetItem * item, int column);
void on_treeK_itemChanged(QTreeWidgetItem * item, int column);
void on_actionClear_triggered();
signals:
void q_k_sendFailed();
void q_k_sendSucceed();
void q_k_receiveFailed();
void q_k_receiveSucceed();
void recordStarted(const QString & fileName);
void recordStopped(const QString & fileName);
};
#endif // KX_PULT_H

View File

@@ -1,10 +1,10 @@
#include <QtGui/QApplication>
#include "kx_pult.h"
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
KX_Pult w;
w.show();
return a.exec();
}
#include <QtGui/QApplication>
#include "kx_pult.h"
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
KX_Pult w;
w.show();
return a.exec();
}

0
make_libs.sh Executable file → Normal file
View File

2
pip

Submodule pip updated: 614370096c...a4b3edb3e1

View File

@@ -1,49 +1,21 @@
cmake_minimum_required(VERSION 3.0)
project(piqt)
if(NOT LIBPROJECT)
find_package(PIP REQUIRED)
option(LIB "System install" 0)
option(DEBUG "Build with -g3" 0)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wall")
if(DEBUG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3")
endif()
endif()
find_package(QAD REQUIRED)
list(APPEND QT_MULTILIB_LIST ${PROJECT_NAME})
set(QT_MULTILIB_LIST ${QT_MULTILIB_LIST} PARENT_SCOPE)
include_directories(${PIP_INCLUDES} ${QAD_INCLUDES})
file(GLOB SRC "*.h" "*.cpp" "*.ui" "*.qrc" "lang/*.ts")
find_qt(${QtVersions} Core Gui Positioning)
qt_wrap(${SRC} HDRS out_HDR CPPS out_CPP QMS out_QM)
qt_add_library(${PROJECT_NAME} SHARED out_CPP)
qt_target_link_libraries(${PROJECT_NAME} pip qad_utils qad_widgets)
message(STATUS "Building ${PROJECT_NAME}")
if(LIBPROJECT)
sdk_install("pip" "${PROJECT_NAME}" "${out_HDR}" "${out_QM}")
else()
if(LIB)
if(WIN32)
install(FILES ${out_HDR} DESTINATION ${MINGW_INCLUDE}/pip)
if(NOT "x${out_QM}" STREQUAL "x")
qt_install(FILES ${out_QM} DESTINATION QtLang)
endif()
qt_install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION ${MINGW_LIB})
qt_install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${MINGW_BIN})
qt_install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION QtBin)
else()
install(FILES ${out_HDR} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/pip)
qt_install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
endif()
message(STATUS "Install ${PROJECT_NAME} to system \"${CMAKE_INSTALL_PREFIX}\"")
else()
if(WIN32)
qt_install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
qt_install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION lib)
else()
qt_install(TARGETS ${PROJECT_NAME} DESTINATION lib)
endif()
install(FILES ${out_HDR} DESTINATION include/pip)
message(STATUS "Install ${PROJECT_NAME} to local \"bin\", \"lib\" and \"include\"")
endif()
endif()
cmake_minimum_required(VERSION 3.0)
cmake_policy(SET CMP0017 NEW) # need include() with .cmake
macro(piqt_library NAME _MODULES _LIBS)
_qt_project(${NAME} FALSE "PIQt" "${_MODULES}" "pip;${_LIBS}" ${ARGN})
_qt_install(${NAME} FALSE "pip" "out_HDR" "out_QM")
endmacro()
macro(piqt_application NAME _MODULES _LIBS)
_qt_project(${NAME} TRUE "PIQt" "${_MODULES}" "pip;${_LIBS}" ${ARGN})
_qt_install(${NAME} TRUE "pip" "" "out_QM")
endmacro()
include_directories(${PIP_INCLUDES})
add_subdirectory(libs)
if (UTILS)
add_subdirectory(utils)
endif()
copy_to_parent(piqt_includes)

1
piqt/libs/CMakeLists.txt Normal file
View File

@@ -0,0 +1 @@
add_directories_with_include("piqt_")

View File

@@ -0,0 +1 @@
piqt_library(piqt "Gui;Positioning" "qad_utils;qad_widgets")

View File

@@ -106,7 +106,7 @@ const QAD::IODevice PI2QADIODevice(const PIVariantTypes::IODevice & v) {
const QAD::File PI2QADFile(const PIVariantTypes::File & v) {
return QAD::File(PI2QString(v.file), PI2QString(v.filter), v.is_abs);
return QAD::File(PI2QString(v.file), PI2QString(v.filter), v.is_abs, v.is_save);
}
@@ -116,7 +116,7 @@ const QAD::Dir PI2QADDir(const PIVariantTypes::Dir & v) {
const PIVariantTypes::File QAD2PIFile(const QAD::File & v) {
return PIVariantTypes::File(Q2PIString(v.file), Q2PIString(v.filter), v.is_abs);
return PIVariantTypes::File(Q2PIString(v.file), Q2PIString(v.filter), v.is_abs, v.is_save);
}

View File

@@ -29,13 +29,14 @@
#if QT_VERSION >= 0x050200
# include "pigeoposition.h"
#endif
#include "piqt_export.h"
class QGeoCoordinate;
const QVariant PI2QVariant(const PIVariant & v);
const PIVariant Q2PIVariant(const QVariant & v);
PIQT_EXPORT const QVariant PI2QVariant(const PIVariant & v);
PIQT_EXPORT const PIVariant Q2PIVariant(const QVariant & v);
//inline const QString PI2QString(const PIString & v) {return QString::fromLocal8Bit(v.data());}
inline const QString PI2QString(const PIString & v) {return QString::fromUtf8(v.dataUTF8());}
@@ -124,20 +125,20 @@ inline PropertyStorage PI2QPropertyStorage(const PIPropertyStorage & props) {
}
const QAD::Enum PI2QADEnum(const PIVariantTypes::Enum & el);
const QAD::File PI2QADFile(const PIVariantTypes::File & v);
const QAD::Dir PI2QADDir(const PIVariantTypes::Dir & v);
const QAD::IODevice PI2QADIODevice(const PIVariantTypes::IODevice & v);
const PIVariantTypes::Enum QAD2PIEnum(const QAD::Enum & el);
const PIVariantTypes::File QAD2PIFile(const QAD::File & v);
const PIVariantTypes::Dir QAD2PIDir(const QAD::Dir & v);
const PIVariantTypes::IODevice QAD2PIIODevice(const QAD::IODevice & v);
PIQT_EXPORT const QAD::Enum PI2QADEnum(const PIVariantTypes::Enum & el);
PIQT_EXPORT const QAD::File PI2QADFile(const PIVariantTypes::File & v);
PIQT_EXPORT const QAD::Dir PI2QADDir(const PIVariantTypes::Dir & v);
PIQT_EXPORT const QAD::IODevice PI2QADIODevice(const PIVariantTypes::IODevice & v);
PIQT_EXPORT const PIVariantTypes::Enum QAD2PIEnum(const QAD::Enum & el);
PIQT_EXPORT const PIVariantTypes::File QAD2PIFile(const QAD::File & v);
PIQT_EXPORT const PIVariantTypes::Dir QAD2PIDir(const QAD::Dir & v);
PIQT_EXPORT const PIVariantTypes::IODevice QAD2PIIODevice(const QAD::IODevice & v);
//inline const PIVariant QString2PIVariant(const QString & v) {return PIVariant::readFromString(QString2PIString(v));}
#if QT_VERSION >= 0x050200
const QGeoCoordinate PI2QGeoPosition(const PIGeoPosition & v);
const PIGeoPosition Q2PIGeoPosition(const QGeoCoordinate & v);
PIQT_EXPORT const QGeoCoordinate PI2QGeoPosition(const PIGeoPosition & v);
PIQT_EXPORT const PIGeoPosition Q2PIGeoPosition(const QGeoCoordinate & v);
#endif
template <typename From>

View File

@@ -25,8 +25,10 @@
#include "piconnection.h"
#include "qpiconfig.h"
#include "piqt.h"
#include "piqt_export.h"
class QPIConnection: public QObject, public PIConnection {
class PIQT_EXPORT QPIConnection: public QObject, public PIConnection {
Q_OBJECT
PIOBJECT_SUBCLASS(QPIConnection, PIConnection)
public:

View File

@@ -0,0 +1 @@
piqt_library(qcd_utils "Gui" "pip;qad_utils;qad_widgets;qad_graphic;cd_utils;piqt")

View File

@@ -1,297 +1,297 @@
#include "qcd_core.h"
#include "cdutils_k.h"
#include "cdutils_core.h"
#include "piqt.h"
#include <QWidget>
#include <QCheckBox>
#include <QGroupBox>
#include <QSpinBox>
#include <QSlider>
#include <QScrollBar>
#include <QDoubleSpinBox>
#include <QLineEdit>
#include <spinslider.h>
#include <clineedit.h>
#include <evalspinbox.h>
#include <qvariantedit.h>
#include <qcd_view.h>
using namespace CDUtils;
int __QCore_Initializer__::count_(0);
QCDCore * __QCore_Initializer__::__instance__(0);
__QCore_Initializer__::__QCore_Initializer__() {
count_++;
if (count_ > 1) return;
__instance__ = new QCDCore();
}
__QCore_Initializer__::~__QCore_Initializer__() {
count_--;
if (count_ > 0) return;
if (__instance__ != 0) {
delete __instance__;
__instance__ = 0;
}
}
QCDCore::QCDCore() {
setObjectName("QCDCore");
setName("QCDCore");
CONNECTU(&K, changedGlobal, this, K_ChangedGlobal);
updating = direct_on = false;
}
QCDCore::~QCDCore() {
}
void QCDCore::K_ChangedGlobal() {
QMetaObject::invokeMethod(this, "updateBindedWidgets", Qt::QueuedConnection);
}
void QCDCore::slotBool(bool v) {
QWidget * w = (QWidget*)sender();
if (!w || updating) return;
QList<PIDeque<int> > pathes = binded_widgets.values(w);
foreach (const PIDeque<int> & path, pathes)
K[path].setValue(PIString::fromBool(v));
K.calculate();
emit updateViewRequest();
}
void QCDCore::slotInt(int v) {
QWidget * w = (QWidget*)sender();
if (!w || updating) return;
QList<PIDeque<int> > pathes = binded_widgets.values(w);
foreach (const PIDeque<int> & path, pathes)
K[path].setValue(PIString::fromNumber(v));
finishEdit(pathes);
}
void QCDCore::slotDouble(double v) {
QWidget * w = (QWidget*)sender();
if (!w || updating) return;
QList<PIDeque<int> > pathes = binded_widgets.values(w);
foreach (const PIDeque<int> & path, pathes)
K[path].setValue(PIString::fromNumber(v));
finishEdit(pathes);
}
void QCDCore::slotText(QString v) {
QWidget * w = (QWidget*)sender();
if (!w || updating) return;
QList<PIDeque<int> > pathes = binded_widgets.values(w);
foreach (const PIDeque<int> & path, pathes)
K[path].setValue(Q2PIString(v));
finishEdit(pathes);
}
void QCDCore::slotVariant(QVariant v) {
QWidget * w = (QWidget*)sender();
if (!w || updating) return;
QList<PIDeque<int> > pathes = binded_widgets.values(w);
foreach (const PIDeque<int> & path, pathes)
K[path].setVariantValue(Q2PIVariant(v));
finishEdit(pathes);
}
void QCDCore::slotDestroyed(QObject * o) {
if (!o) return;
if (!binded_widgets.contains((QWidget*)o)) return;
binded_widgets.remove((QWidget*)o);
}
int QCDCore::bindWindow(QWidget * wnd) {
if (!wnd) return 0;
//K.root().makePath();
return bindWidgets(wnd->findChildren<QWidget * >());
}
int QCDCore::bindWidgets(QList<QWidget * > wl) {
int ret = 0;
foreach (QWidget * w, wl)
if (bindWidget(w)) ++ret;
return ret;
}
bool QCDCore::bindWidget(QWidget * w) {
if (!w) return false;
QString on = w->objectName();
QString cn = w->metaObject()->className();
if (cn == "CDView") {
bindView(w);
return false;
}
PIVector<CDType * > ak = K.root().children();
piForeachC (CDType * k, ak) {
if (!on.endsWith(PI2QString(k->pathString().join("_")))) continue;
if (bindWidget(w, *k)) return true;
}
return false;
}
bool QCDCore::bindWidget(QWidget * w, const CDType & k) {
if (!w) return false;
//piCout << "bind..." << k.name() << k.path();
QString cn = w->metaObject()->className();
bool ok = false;
if (cn == "QCheckBox" || cn == "QGroupBox") {
connect(w, SIGNAL(toggled(bool)), this, SLOT(slotBool(bool)), Qt::UniqueConnection);
ok = true;
}
if (cn == "QSpinBox" || cn == "QSlider" || cn == "QScrollBar") {
connect(w, SIGNAL(valueChanged(int)), this, SLOT(slotInt(int)), Qt::UniqueConnection);
ok = true;
}
if (cn == "QDoubleSpinBox" || cn == "SpinSlider" || cn == "EvalSpinBox") {
connect(w, SIGNAL(valueChanged(double)), this, SLOT(slotDouble(double)), Qt::UniqueConnection);
ok = true;
}
if (cn == "QLineEdit" || cn == "CLineEdit") {
connect(w, SIGNAL(textChanged(QString)), this, SLOT(slotText(QString)), Qt::UniqueConnection);
ok = true;
}
if (cn == "QVariantEdit") {
connect(w, SIGNAL(valueChanged(QVariant)), this, SLOT(slotVariant(QVariant)), Qt::UniqueConnection);
ok = true;
}
if (cn == "CDView") {
bindView(w);
}
connect(w, SIGNAL(destroyed(QObject*)), this, SLOT(slotDestroyed(QObject*)), Qt::UniqueConnection);
setWidgetValue(w, k);
if (!ok) return false;
//piCout << k.name() << k.path() << "ok";
binded_widgets.insert(w, k.path());
return true;
}
void QCDCore::updateBindedWidgets() {
QMapIterator<QWidget * , PIDeque<int> > it(binded_widgets);
QWidgetList to_remove;
updating = true;
while (it.hasNext()) {
QWidget * w = it.next().key();
if (!K.exists(it.value()))
to_remove << w;
else
setWidgetValue(w, K[it.value()]);
}
foreach (QWidget * w, to_remove)
unbindWidget(w);
updating = false;
}
void QCDCore::bindView(QWidget * v) {
CDView * w = qobject_cast<CDView * >(v);
if (!w) return;
connect(this, SIGNAL(updateViewRequest()), w, SLOT(refreshValues()), Qt::UniqueConnection);
}
void QCDCore::setWidgetValue(QWidget * w, const CDType & k) {
if (!w) return;
QString cn = w->metaObject()->className();
if (cn == "QCheckBox") qobject_cast<QCheckBox*>(w)->setChecked(k.toBool());
if (cn == "QGroupBox") qobject_cast<QGroupBox*>(w)->setChecked(k.toBool());
if (cn == "QSpinBox") qobject_cast<QSpinBox*>(w)->setValue(k.toInt());
if (cn == "QSlider") qobject_cast<QSlider*>(w)->setValue(k.toInt());
if (cn == "QScrollBar") qobject_cast<QScrollBar*>(w)->setValue(k.toInt());
if (cn == "QDoubleSpinBox") qobject_cast<QDoubleSpinBox*>(w)->setValue(k.toDouble());
if (cn == "SpinSlider") qobject_cast<SpinSlider*>(w)->setValue(k.toDouble());
if (cn == "QLineEdit") qobject_cast<QLineEdit*>(w)->setText(PI2QString(k.value()));
if (cn == "CLineEdit") qobject_cast<CLineEdit*>(w)->setText(PI2QString(k.value()));
if (cn == "EvalSpinBox") qobject_cast<EvalSpinBox*>(w)->setValue(k.toDouble());
if (cn == "QVariantEdit") qobject_cast<QVariantEdit*>(w)->setValue(PI2QVariant(k.variantValue()));
}
void QCDCore::finishEdit(const QList<PIDeque<int> > & pathes) {
K.calculate();
if (direct_on) {
foreach (const PIDeque<int> & path, pathes)
K.directChange(K[path]);
}
emit updateViewRequest();
}
int QCDCore::unbindWindow(QWidget * wnd) {
if (!wnd) return 0;
return unbindWidgets(wnd->findChildren<QWidget * >());
}
int QCDCore::unbindWidgets(QList<QWidget * > wl) {
int ret = 0;
foreach (QWidget * w, wl)
if (unbindWidget(w)) ++ret;
return ret;
}
bool QCDCore::unbindWidget(QWidget * w) {
if (!w) return false;
//qDebug() << "unbind" << w;
if (!binded_widgets.contains(w)) return false;
QString cn = w->metaObject()->className();
if (cn == "QCheckBox" || cn == "QGroupBox")
disconnect(w, SIGNAL(toggled(bool)), this, SLOT(slotBool(bool)));
if (cn == "QSpinBox" || cn == "QSlider" || cn == "QScrollBar")
disconnect(w, SIGNAL(valueChanged(int)), this, SLOT(slotInt(int)));
if (cn == "QDoubleSpinBox" || cn == "SpinSlider" || cn == "EvalSpinBox")
disconnect(w, SIGNAL(valueChanged(double)), this, SLOT(slotDouble(double)));
if (cn == "QLineEdit" || cn == "CLineEdit")
disconnect(w, SIGNAL(textChanged(QString)), this, SLOT(slotText(QString)));
if (cn == "QVariantEdit")
disconnect(w, SIGNAL(valueChanged(QVariant)), this, SLOT(slotVariant(QVariant)));
//qDebug() << "remove b" << binded_widgets.size();
binded_widgets.remove(w);
//qDebug() << "remove a" << binded_widgets.size();
return true;
}
void QCDCore::unbindAllWidgets() {
QMap<QWidget * , PIDeque<int> > bwm = binded_widgets;
QMapIterator<QWidget * , PIDeque<int> > it(bwm);
while (it.hasNext()) {
QWidget * w = it.next().key();
unbindWidget(w);
}
binded_widgets.clear();
}
void QCDCore::updateBindedWidget(const CDType & k_) {
QMapIterator<QWidget * , PIDeque<int> > it(binded_widgets);
updating = true;
while (it.hasNext()) {
QWidget * w = it.next().key();
const CDType & k(K[it.value()]);
if (k.path() != k_.path()) continue;
setWidgetValue(w, k);
}
updating = false;
}
#include "qcd_core.h"
#include "cdutils_k.h"
#include "cdutils_core.h"
#include "piqt.h"
#include <QWidget>
#include <QCheckBox>
#include <QGroupBox>
#include <QSpinBox>
#include <QSlider>
#include <QScrollBar>
#include <QDoubleSpinBox>
#include <QLineEdit>
#include <spinslider.h>
#include <clineedit.h>
#include <evalspinbox.h>
#include <qvariantedit.h>
#include <qcd_view.h>
using namespace CDUtils;
int __QCore_Initializer__::count_(0);
QCDCore * __QCore_Initializer__::__instance__(0);
__QCore_Initializer__::__QCore_Initializer__() {
count_++;
if (count_ > 1) return;
__instance__ = new QCDCore();
}
__QCore_Initializer__::~__QCore_Initializer__() {
count_--;
if (count_ > 0) return;
if (__instance__ != 0) {
delete __instance__;
__instance__ = 0;
}
}
QCDCore::QCDCore() {
setObjectName("QCDCore");
setName("QCDCore");
CONNECTU(&K, changedGlobal, this, K_ChangedGlobal);
updating = direct_on = false;
}
QCDCore::~QCDCore() {
}
void QCDCore::K_ChangedGlobal() {
QMetaObject::invokeMethod(this, "updateBindedWidgets", Qt::QueuedConnection);
}
void QCDCore::slotBool(bool v) {
QWidget * w = (QWidget*)sender();
if (!w || updating) return;
QList<PIDeque<int> > pathes = binded_widgets.values(w);
foreach (const PIDeque<int> & path, pathes)
K[path].setValue(PIString::fromBool(v));
K.calculate();
emit updateViewRequest();
}
void QCDCore::slotInt(int v) {
QWidget * w = (QWidget*)sender();
if (!w || updating) return;
QList<PIDeque<int> > pathes = binded_widgets.values(w);
foreach (const PIDeque<int> & path, pathes)
K[path].setValue(PIString::fromNumber(v));
finishEdit(pathes);
}
void QCDCore::slotDouble(double v) {
QWidget * w = (QWidget*)sender();
if (!w || updating) return;
QList<PIDeque<int> > pathes = binded_widgets.values(w);
foreach (const PIDeque<int> & path, pathes)
K[path].setValue(PIString::fromNumber(v));
finishEdit(pathes);
}
void QCDCore::slotText(QString v) {
QWidget * w = (QWidget*)sender();
if (!w || updating) return;
QList<PIDeque<int> > pathes = binded_widgets.values(w);
foreach (const PIDeque<int> & path, pathes)
K[path].setValue(Q2PIString(v));
finishEdit(pathes);
}
void QCDCore::slotVariant(QVariant v) {
QWidget * w = (QWidget*)sender();
if (!w || updating) return;
QList<PIDeque<int> > pathes = binded_widgets.values(w);
foreach (const PIDeque<int> & path, pathes)
K[path].setVariantValue(Q2PIVariant(v));
finishEdit(pathes);
}
void QCDCore::slotDestroyed(QObject * o) {
if (!o) return;
if (!binded_widgets.contains((QWidget*)o)) return;
binded_widgets.remove((QWidget*)o);
}
int QCDCore::bindWindow(QWidget * wnd) {
if (!wnd) return 0;
//K.root().makePath();
return bindWidgets(wnd->findChildren<QWidget * >());
}
int QCDCore::bindWidgets(QList<QWidget * > wl) {
int ret = 0;
foreach (QWidget * w, wl)
if (bindWidget(w)) ++ret;
return ret;
}
bool QCDCore::bindWidget(QWidget * w) {
if (!w) return false;
QString on = w->objectName();
QString cn = w->metaObject()->className();
if (cn == "CDView") {
bindView(w);
return false;
}
PIVector<CDType * > ak = K.root().children();
piForeachC (CDType * k, ak) {
if (!on.endsWith(PI2QString(k->pathString().join("_")))) continue;
if (bindWidget(w, *k)) return true;
}
return false;
}
bool QCDCore::bindWidget(QWidget * w, const CDType & k) {
if (!w) return false;
//piCout << "bind..." << k.name() << k.path();
QString cn = w->metaObject()->className();
bool ok = false;
if (cn == "QCheckBox" || cn == "QGroupBox") {
connect(w, SIGNAL(toggled(bool)), this, SLOT(slotBool(bool)), Qt::UniqueConnection);
ok = true;
}
if (cn == "QSpinBox" || cn == "QSlider" || cn == "QScrollBar") {
connect(w, SIGNAL(valueChanged(int)), this, SLOT(slotInt(int)), Qt::UniqueConnection);
ok = true;
}
if (cn == "QDoubleSpinBox" || cn == "SpinSlider" || cn == "EvalSpinBox") {
connect(w, SIGNAL(valueChanged(double)), this, SLOT(slotDouble(double)), Qt::UniqueConnection);
ok = true;
}
if (cn == "QLineEdit" || cn == "CLineEdit") {
connect(w, SIGNAL(textChanged(QString)), this, SLOT(slotText(QString)), Qt::UniqueConnection);
ok = true;
}
if (cn == "QVariantEdit") {
connect(w, SIGNAL(valueChanged(QVariant)), this, SLOT(slotVariant(QVariant)), Qt::UniqueConnection);
ok = true;
}
if (cn == "CDView") {
bindView(w);
}
connect(w, SIGNAL(destroyed(QObject*)), this, SLOT(slotDestroyed(QObject*)), Qt::UniqueConnection);
setWidgetValue(w, k);
if (!ok) return false;
//piCout << k.name() << k.path() << "ok";
binded_widgets.insert(w, k.path());
return true;
}
void QCDCore::updateBindedWidgets() {
QMapIterator<QWidget * , PIDeque<int> > it(binded_widgets);
QWidgetList to_remove;
updating = true;
while (it.hasNext()) {
QWidget * w = it.next().key();
if (!K.exists(it.value()))
to_remove << w;
else
setWidgetValue(w, K[it.value()]);
}
foreach (QWidget * w, to_remove)
unbindWidget(w);
updating = false;
}
void QCDCore::bindView(QWidget * v) {
CDView * w = qobject_cast<CDView * >(v);
if (!w) return;
connect(this, SIGNAL(updateViewRequest()), w, SLOT(refreshValues()), Qt::UniqueConnection);
}
void QCDCore::setWidgetValue(QWidget * w, const CDType & k) {
if (!w) return;
QString cn = w->metaObject()->className();
if (cn == "QCheckBox") qobject_cast<QCheckBox*>(w)->setChecked(k.toBool());
if (cn == "QGroupBox") qobject_cast<QGroupBox*>(w)->setChecked(k.toBool());
if (cn == "QSpinBox") qobject_cast<QSpinBox*>(w)->setValue(k.toInt());
if (cn == "QSlider") qobject_cast<QSlider*>(w)->setValue(k.toInt());
if (cn == "QScrollBar") qobject_cast<QScrollBar*>(w)->setValue(k.toInt());
if (cn == "QDoubleSpinBox") qobject_cast<QDoubleSpinBox*>(w)->setValue(k.toDouble());
if (cn == "SpinSlider") qobject_cast<SpinSlider*>(w)->setValue(k.toDouble());
if (cn == "QLineEdit") qobject_cast<QLineEdit*>(w)->setText(PI2QString(k.value()));
if (cn == "CLineEdit") qobject_cast<CLineEdit*>(w)->setText(PI2QString(k.value()));
if (cn == "EvalSpinBox") qobject_cast<EvalSpinBox*>(w)->setValue(k.toDouble());
if (cn == "QVariantEdit") qobject_cast<QVariantEdit*>(w)->setValue(PI2QVariant(k.variantValue()));
}
void QCDCore::finishEdit(const QList<PIDeque<int> > & pathes) {
K.calculate();
if (direct_on) {
foreach (const PIDeque<int> & path, pathes)
K.directChange(K[path]);
}
emit updateViewRequest();
}
int QCDCore::unbindWindow(QWidget * wnd) {
if (!wnd) return 0;
return unbindWidgets(wnd->findChildren<QWidget * >());
}
int QCDCore::unbindWidgets(QList<QWidget * > wl) {
int ret = 0;
foreach (QWidget * w, wl)
if (unbindWidget(w)) ++ret;
return ret;
}
bool QCDCore::unbindWidget(QWidget * w) {
if (!w) return false;
//qDebug() << "unbind" << w;
if (!binded_widgets.contains(w)) return false;
QString cn = w->metaObject()->className();
if (cn == "QCheckBox" || cn == "QGroupBox")
disconnect(w, SIGNAL(toggled(bool)), this, SLOT(slotBool(bool)));
if (cn == "QSpinBox" || cn == "QSlider" || cn == "QScrollBar")
disconnect(w, SIGNAL(valueChanged(int)), this, SLOT(slotInt(int)));
if (cn == "QDoubleSpinBox" || cn == "SpinSlider" || cn == "EvalSpinBox")
disconnect(w, SIGNAL(valueChanged(double)), this, SLOT(slotDouble(double)));
if (cn == "QLineEdit" || cn == "CLineEdit")
disconnect(w, SIGNAL(textChanged(QString)), this, SLOT(slotText(QString)));
if (cn == "QVariantEdit")
disconnect(w, SIGNAL(valueChanged(QVariant)), this, SLOT(slotVariant(QVariant)));
//qDebug() << "remove b" << binded_widgets.size();
binded_widgets.remove(w);
//qDebug() << "remove a" << binded_widgets.size();
return true;
}
void QCDCore::unbindAllWidgets() {
QMap<QWidget * , PIDeque<int> > bwm = binded_widgets;
QMapIterator<QWidget * , PIDeque<int> > it(bwm);
while (it.hasNext()) {
QWidget * w = it.next().key();
unbindWidget(w);
}
binded_widgets.clear();
}
void QCDCore::updateBindedWidget(const CDType & k_) {
QMapIterator<QWidget * , PIDeque<int> > it(binded_widgets);
updating = true;
while (it.hasNext()) {
QWidget * w = it.next().key();
const CDType & k(K[it.value()]);
if (k.path() != k_.path()) continue;
setWidgetValue(w, k);
}
updating = false;
}

View File

@@ -1,96 +1,97 @@
/*
QCD Utils - Qt bindings/utilites for CD Utils
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QCD_CORE_H
#define QCD_CORE_H
#include <QObject>
#include <QMultiMap>
#include <QVariant>
#include "piobject.h"
#include "cdutils_types.h"
class QCDCore;
class __QCore_Initializer__ {
public:
__QCore_Initializer__();
~__QCore_Initializer__();
static int count_;
static QCDCore * __instance__;
};
class QCDCore: public QObject, public PIObject
{
Q_OBJECT
PIOBJECT(QCDCore)
friend class __QCore_Initializer__;
public:
static QCDCore * instance() {return __QCore_Initializer__::__instance__;}
int bindWindow(QWidget * wnd);
int bindWidgets(QList<QWidget * > wl);
bool bindWidget(QWidget * w);
bool bindWidget(QWidget * w, const CDUtils::CDType & k);
int unbindWindow(QWidget * wnd);
int unbindWidgets(QList<QWidget * > wl);
bool unbindWidget(QWidget * w);
void unbindAllWidgets();
void updateBindedWidget(const CDUtils::CDType & k_);
void setDirectKEnabled(bool yes) {direct_on = yes;}
bool isDirectKEnabled() const {return direct_on;}
private:
QCDCore();
~QCDCore();
void bindView(QWidget * v);
void setWidgetValue(QWidget * w, const CDUtils::CDType & k);
void finishEdit(const QList<PIDeque<int> > & pathes);
EVENT_HANDLER(void, K_ChangedGlobal);
QMultiMap<QWidget * , PIDeque<int> > binded_widgets;
bool updating, direct_on;
private slots:
void slotBool(bool v);
void slotInt(int v);
void slotDouble(double v);
void slotText(QString v);
void slotVariant(QVariant v);
void slotDestroyed(QObject * );
public slots:
void updateBindedWidgets();
signals:
void updateViewRequest();
};
static __QCore_Initializer__ __QCore_initializer__;
#endif // QCD_CORE_H
/*
QCD Utils - Qt bindings/utilites for CD Utils
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QCD_CORE_H
#define QCD_CORE_H
#include <QObject>
#include <QMultiMap>
#include <QVariant>
#include "piobject.h"
#include "cdutils_types.h"
#include "qcd_utils_export.h"
class QCDCore;
class QCD_UTILS_EXPORT __QCore_Initializer__ {
public:
__QCore_Initializer__();
~__QCore_Initializer__();
static int count_;
static QCDCore * __instance__;
};
class QCD_UTILS_EXPORT QCDCore: public QObject, public PIObject
{
Q_OBJECT
PIOBJECT(QCDCore)
friend class __QCore_Initializer__;
public:
static QCDCore * instance() {return __QCore_Initializer__::__instance__;}
int bindWindow(QWidget * wnd);
int bindWidgets(QList<QWidget * > wl);
bool bindWidget(QWidget * w);
bool bindWidget(QWidget * w, const CDUtils::CDType & k);
int unbindWindow(QWidget * wnd);
int unbindWidgets(QList<QWidget * > wl);
bool unbindWidget(QWidget * w);
void unbindAllWidgets();
void updateBindedWidget(const CDUtils::CDType & k_);
void setDirectKEnabled(bool yes) {direct_on = yes;}
bool isDirectKEnabled() const {return direct_on;}
private:
QCDCore();
~QCDCore();
void bindView(QWidget * v);
void setWidgetValue(QWidget * w, const CDUtils::CDType & k);
void finishEdit(const QList<PIDeque<int> > & pathes);
EVENT_HANDLER(void, K_ChangedGlobal);
QMultiMap<QWidget * , PIDeque<int> > binded_widgets;
bool updating, direct_on;
private slots:
void slotBool(bool v);
void slotInt(int v);
void slotDouble(double v);
void slotText(QString v);
void slotVariant(QVariant v);
void slotDestroyed(QObject * );
public slots:
void updateBindedWidgets();
signals:
void updateViewRequest();
};
static __QCore_Initializer__ __QCore_initializer__;
#endif // QCD_CORE_H

View File

@@ -1,40 +1,40 @@
#include "qcd_graphic.h"
#include "ui_qcd_graphic.h"
#include "cdutils_core.h"
#include "cdutils_x.h"
#include "graphic.h"
#include "piqt.h"
using namespace CDUtils;
CDGraphicWidget::CDGraphicWidget(QWidget * p): QWidget(p) {
ui = new Ui::CDGraphicWidget();
ui->setupUi(this);
ui->graphic->setGraphicsCount(0);
}
Graphic * CDGraphicWidget::graphic() const {
return ui->graphic;
}
void CDGraphicWidget::setConfigVisible(bool on) {
ui->widgetConfig->setVisible(on);
}
bool CDGraphicWidget::isConfigVisible() const {
return ui->widgetConfig->isVisible();
}
EvalSpinBox * CDGraphicWidget::evalSpinBoxHistory() {
return ui->evalHistory;
}
EvalSpinBox * CDGraphicWidget::evalSpinBoxVisible() {
return ui->evalVisible;
}
#include "qcd_graphic.h"
#include "ui_qcd_graphic.h"
#include "cdutils_core.h"
#include "cdutils_x.h"
#include "graphic.h"
#include "piqt.h"
using namespace CDUtils;
CDGraphicWidget::CDGraphicWidget(QWidget * p): QWidget(p) {
ui = new Ui::CDGraphicWidget();
ui->setupUi(this);
ui->graphic->setGraphicsCount(0);
}
Graphic * CDGraphicWidget::graphic() const {
return ui->graphic;
}
void CDGraphicWidget::setConfigVisible(bool on) {
ui->widgetConfig->setVisible(on);
}
bool CDGraphicWidget::isConfigVisible() const {
return ui->widgetConfig->isVisible();
}
EvalSpinBox * CDGraphicWidget::evalSpinBoxHistory() {
return ui->evalHistory;
}
EvalSpinBox * CDGraphicWidget::evalSpinBoxVisible() {
return ui->evalVisible;
}

View File

@@ -1,66 +1,67 @@
/*
QCD Utils - Qt bindings/utilites for CD Utils
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QCD_GRAPHIC_H
#define QCD_GRAPHIC_H
#include <QWidget>
#include <evalspinbox.h>
#include <pistring.h>
namespace CDUtils {
class CDType;
class CDSection;
}
namespace Ui {
class CDGraphicWidget;
}
class Graphic;
class Graphic;
class CDGraphicWidget: public QWidget {
Q_OBJECT
friend class CDGraphics;
friend class GDockWidget;
public:
CDGraphicWidget(QWidget * p = 0);
Graphic * graphic() const;
bool isConfigVisible() const;
EvalSpinBox * evalSpinBoxHistory();
EvalSpinBox * evalSpinBoxVisible();
public slots:
void setConfigVisible(bool on);
private:
Ui::CDGraphicWidget * ui;
private slots:
signals:
};
#endif // QCD_GRAPHIC_H
/*
QCD Utils - Qt bindings/utilites for CD Utils
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QCD_GRAPHIC_H
#define QCD_GRAPHIC_H
#include <QWidget>
#include <evalspinbox.h>
#include <pistring.h>
#include "qcd_utils_export.h"
namespace CDUtils {
class CDType;
class CDSection;
}
namespace Ui {
class CDGraphicWidget;
}
class Graphic;
class Graphic;
class QCD_UTILS_EXPORT CDGraphicWidget: public QWidget {
Q_OBJECT
friend class CDGraphics;
friend class GDockWidget;
public:
CDGraphicWidget(QWidget * p = 0);
Graphic * graphic() const;
bool isConfigVisible() const;
EvalSpinBox * evalSpinBoxHistory();
EvalSpinBox * evalSpinBoxVisible();
public slots:
void setConfigVisible(bool on);
private:
Ui::CDGraphicWidget * ui;
private slots:
signals:
};
#endif // QCD_GRAPHIC_H

View File

@@ -1,169 +1,169 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CDGraphicWidget</class>
<widget class="QWidget" name="CDGraphicWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>470</width>
<height>380</height>
</rect>
</property>
<property name="windowTitle">
<string>CD Pult</string>
</property>
<layout class="QVBoxLayout" name="layoutMain">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="Graphic" name="graphic">
<property name="buttons">
<set>Graphic::Autofit|Graphic::BorderInputs|Graphic::Clear|Graphic::Configure|Graphic::CursorAxis|Graphic::Fullscreen|Graphic::Legend|Graphic::OnlyExpandY|Graphic::Pause|Graphic::Save</set>
</property>
<property name="borderInputsVisible">
<bool>false</bool>
</property>
<property name="statusVisible">
<bool>false</bool>
</property>
<property name="historySize">
<double>100.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="widgetConfig" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>History:</string>
</property>
</widget>
</item>
<item>
<widget class="EvalSpinBox" name="evalHistory">
<property name="value">
<double>100.000000000000000</double>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Visible:</string>
</property>
</widget>
</item>
<item>
<widget class="EvalSpinBox" name="evalVisible">
<property name="value">
<double>-1.000000000000000</double>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Graphic</class>
<extends>QFrame</extends>
<header>graphic.h</header>
</customwidget>
<customwidget>
<class>EvalSpinBox</class>
<extends>QWidget</extends>
<header>evalspinbox.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>evalHistory</sender>
<signal>valueChanged(double)</signal>
<receiver>graphic</receiver>
<slot>setHistorySize(double)</slot>
<hints>
<hint type="sourcelabel">
<x>148</x>
<y>363</y>
</hint>
<hint type="destinationlabel">
<x>156</x>
<y>297</y>
</hint>
</hints>
</connection>
<connection>
<sender>evalVisible</sender>
<signal>valueChanged(double)</signal>
<receiver>graphic</receiver>
<slot>setMaxVisibleTime(double)</slot>
<hints>
<hint type="sourcelabel">
<x>345</x>
<y>361</y>
</hint>
<hint type="destinationlabel">
<x>342</x>
<y>337</y>
</hint>
</hints>
</connection>
</connections>
</ui>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CDGraphicWidget</class>
<widget class="QWidget" name="CDGraphicWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>470</width>
<height>380</height>
</rect>
</property>
<property name="windowTitle">
<string>CD Pult</string>
</property>
<layout class="QVBoxLayout" name="layoutMain">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="Graphic" name="graphic">
<property name="buttons">
<set>Graphic::Autofit|Graphic::BorderInputs|Graphic::Clear|Graphic::Configure|Graphic::CursorAxis|Graphic::Fullscreen|Graphic::Legend|Graphic::Pause|Graphic::Save</set>
</property>
<property name="borderInputsVisible">
<bool>false</bool>
</property>
<property name="statusVisible">
<bool>false</bool>
</property>
<property name="historySize">
<double>100.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="widgetConfig" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>History:</string>
</property>
</widget>
</item>
<item>
<widget class="EvalSpinBox" name="evalHistory">
<property name="value">
<double>100.000000000000000</double>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Visible:</string>
</property>
</widget>
</item>
<item>
<widget class="EvalSpinBox" name="evalVisible">
<property name="value">
<double>-1.000000000000000</double>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Graphic</class>
<extends>QFrame</extends>
<header>graphic.h</header>
</customwidget>
<customwidget>
<class>EvalSpinBox</class>
<extends>QWidget</extends>
<header>evalspinbox.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>evalHistory</sender>
<signal>valueChanged(double)</signal>
<receiver>graphic</receiver>
<slot>setHistorySize(double)</slot>
<hints>
<hint type="sourcelabel">
<x>148</x>
<y>363</y>
</hint>
<hint type="destinationlabel">
<x>156</x>
<y>297</y>
</hint>
</hints>
</connection>
<connection>
<sender>evalVisible</sender>
<signal>valueChanged(double)</signal>
<receiver>graphic</receiver>
<slot>setMaxVisibleTime(double)</slot>
<hints>
<hint type="sourcelabel">
<x>345</x>
<y>361</y>
</hint>
<hint type="destinationlabel">
<x>342</x>
<y>337</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -1,46 +1,46 @@
#include "qcd_modedialog.h"
#include "ui_qcd_modedialog.h"
QCDModeDialog::QCDModeDialog(QWidget * parent): QDialog(parent) {
ui = new Ui::QCDModeDialog();
ui->setupUi(this);
}
QCDModeDialog::~QCDModeDialog() {
delete ui;
}
CDUtils::UpdateModeFlags QCDModeDialog::mode() const {
CDUtils::UpdateModeFlags ret = 0;
if (ui->checkSaveIndex->isChecked()) ret |= CDUtils::SaveByIndex;
if (ui->checkSaveName->isChecked()) ret |= CDUtils::SaveByName;
if (ui->checkMerge->isChecked()) ret |= CDUtils::Merge;
return ret;
}
void QCDModeDialog::changeEvent(QEvent *e) {
QDialog::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
void QCDModeDialog::on_checkSaveIndex_clicked(bool checked) {
if (!checked) return;
ui->checkSaveName->setChecked(false);
}
void QCDModeDialog::on_checkSaveName_clicked(bool checked) {
if (!checked) return;
ui->checkSaveIndex->setChecked(false);
}
#include "qcd_modedialog.h"
#include "ui_qcd_modedialog.h"
QCDModeDialog::QCDModeDialog(QWidget * parent): QDialog(parent) {
ui = new Ui::QCDModeDialog();
ui->setupUi(this);
}
QCDModeDialog::~QCDModeDialog() {
delete ui;
}
CDUtils::UpdateModeFlags QCDModeDialog::mode() const {
CDUtils::UpdateModeFlags ret = 0;
if (ui->checkSaveIndex->isChecked()) ret |= CDUtils::SaveByIndex;
if (ui->checkSaveName->isChecked()) ret |= CDUtils::SaveByName;
if (ui->checkMerge->isChecked()) ret |= CDUtils::Merge;
return ret;
}
void QCDModeDialog::changeEvent(QEvent *e) {
QDialog::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
void QCDModeDialog::on_checkSaveIndex_clicked(bool checked) {
if (!checked) return;
ui->checkSaveName->setChecked(false);
}
void QCDModeDialog::on_checkSaveName_clicked(bool checked) {
if (!checked) return;
ui->checkSaveIndex->setChecked(false);
}

View File

@@ -1,50 +1,51 @@
/*
QCD Utils - Qt bindings/utilites for CD Utils
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QCD_MODEDIALOG_H
#define QCD_MODEDIALOG_H
#include <QDialog>
#include <cdutils_types.h>
namespace Ui {
class QCDModeDialog;
}
class QCDModeDialog: public QDialog
{
Q_OBJECT
public:
explicit QCDModeDialog(QWidget * parent = 0);
~QCDModeDialog();
CDUtils::UpdateModeFlags mode() const;
protected:
void changeEvent(QEvent *e);
Ui::QCDModeDialog * ui;
private slots:
void on_checkSaveIndex_clicked(bool checked);
void on_checkSaveName_clicked(bool checked);
};
#endif // QCD_MODEDIALOG_H
/*
QCD Utils - Qt bindings/utilites for CD Utils
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QCD_MODEDIALOG_H
#define QCD_MODEDIALOG_H
#include <QDialog>
#include <cdutils_types.h>
#include "qcd_utils_export.h"
namespace Ui {
class QCDModeDialog;
}
class QCD_UTILS_EXPORT QCDModeDialog: public QDialog
{
Q_OBJECT
public:
explicit QCDModeDialog(QWidget * parent = 0);
~QCDModeDialog();
CDUtils::UpdateModeFlags mode() const;
protected:
void changeEvent(QEvent *e);
Ui::QCDModeDialog * ui;
private slots:
void on_checkSaveIndex_clicked(bool checked);
void on_checkSaveName_clicked(bool checked);
};
#endif // QCD_MODEDIALOG_H

View File

@@ -1,98 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QCDModeDialog</class>
<widget class="QDialog" name="QCDModeDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>251</width>
<height>152</height>
</rect>
</property>
<property name="windowTitle">
<string>Update description mode</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="checkSaveIndex">
<property name="text">
<string>Save by index</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkSaveName">
<property name="text">
<string>Save by name</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkMerge">
<property name="text">
<string>Merge</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>1</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>QCDModeDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>106</x>
<y>131</y>
</hint>
<hint type="destinationlabel">
<x>101</x>
<y>146</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>QCDModeDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>182</x>
<y>127</y>
</hint>
<hint type="destinationlabel">
<x>169</x>
<y>146</y>
</hint>
</hints>
</connection>
</connections>
</ui>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QCDModeDialog</class>
<widget class="QDialog" name="QCDModeDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>251</width>
<height>152</height>
</rect>
</property>
<property name="windowTitle">
<string>Update description mode</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="checkSaveIndex">
<property name="text">
<string>Save by index</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkSaveName">
<property name="text">
<string>Save by name</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkMerge">
<property name="text">
<string>Merge</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>1</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>QCDModeDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>106</x>
<y>131</y>
</hint>
<hint type="destinationlabel">
<x>101</x>
<y>146</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>QCDModeDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>182</x>
<y>127</y>
</hint>
<hint type="destinationlabel">
<x>169</x>
<y>146</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -1,460 +1,460 @@
#include "qcd_model.h"
#include "cdutils_interface.h"
#include "cdutils_core.h"
#include "cdutils_x.h"
#include "piqt.h"
#include <QDebug>
#include <QBrush>
#include <QColor>
#include <QMimeData>
#include "qvariantedit.h"
#include "qad_types.h"
using namespace CDUtils;
// CDKItem
CDItem::CDItem(CDUtils::Interface * i, int _index, CDItem::CDItemType type, CDItem *parent) {
interface = i;
index_ = _index;
parent_ = parent;
type_ = type;
item_count = 0;
expanded = true;
}
CDItem::~CDItem() {
qDeleteAll(childs);
}
QVariant CDItem::data(int column, int role) const {
if (role == Qt::BackgroundRole) {
switch (type_) {
case ItemCDType: {
CDType & t(interface->section(buildPath())[index_]);
if (t.errorString().isEmpty()) return QBrush(QColor(255, 250, 230));
else return QBrush(QColor(255, 128, 128));
}
case ItemCDSection: return QBrush(QColor(230, 250, 230));
}
}
if (role == Qt::CheckStateRole && type_ == ItemCDType) {
CDType & t(interface->section(buildPath())[index_]);
if (column == cValue && t.cd_type() == CDType::cdK) {
if (t.type() == "b") return t.toBool() ? Qt::Checked : Qt::Unchecked;
else QVariant();
}
if (column == cName_Cmd && t.cd_type() == CDType::cdX) {
return t.isSelectedX() ? Qt::Checked : Qt::Unchecked;
}
}
if (role == Qt::ToolTipRole && type_ == ItemCDType) {
CDType & t(interface->section(buildPath())[index_]);
return PI2QString(t.errorString());
}
if (role != Qt::DisplayRole && role != Qt::EditRole) return QVariant();
PIDeque<int> path = buildPath();
CDSection & rs = interface->section(path);
CDSection s;
switch (type_) {
case ItemCDType:
switch (column) {
case cID: return QString::number(index_);
case cName_Cmd: return PI2QString(rs[index_].name());
case cType: return stringType(rs[index_].type());
case cXMode: return QVariant::fromValue(xModeEnum(rs[index_].xmode()));
case cXAvg: return rs[index_].avg();
case cExpression: return PI2QString(rs[index_].formula());
case cValue: return value(rs[index_], role);
case cComment: return PI2QString(rs[index_].comment());
default: break;
}
break;
case ItemCDSection:
s = rs.section(index_);
// piCout << rs.name << rs.alias << s.name << s.alias;
switch (column) {
case cID: return QString("[") + QString::number(index_) + QString("]");
case cName_Cmd: return PI2QString(s.alias);
case cType: return PI2QString(s.name);
default: break;
}
break;
}
return QVariant();
}
QVariant CDItem::value(CDType & t, int role) const {
if (t.type() == "f") return t.toDouble();
if (t.type() == "n") return t.toInt();
if (t.type() == "b") return t.toBool();
if (t.type() == "e") {
QAD::Enum et = PI2QADEnum(t.enumValues());
et.selectValue(t.toInt());
if (role == Qt::EditRole) return QVariant::fromValue<QAD::Enum>(et);
else return et.selectedName();
}
return PI2QString(t.value());
}
bool CDItem::setData(int column, const QVariant & value) {
if (type_ == ItemCDType) {
CDType & t(interface->section(buildPath())[index_]);
if ((column == cExpression || column == cValue) && (t.cd_type() == CDType::cdK)) {
interface->section(buildPath())[index_].setValue(Q2PIString(value.toString()));
interface->calculate();
return true;
}
if (t.cd_type() == CDType::cdX) {
switch (column) {
case cName_Cmd:
X.setEnabled(t, value.toBool());
return true;
case cXMode:
t.setXMode((CDType::XMode)value.toInt());
return true;
case cXAvg:
t.setAvg(piMax(value.toInt(), 1));
return true;
default: break;
}
}
}
return false;
}
PIDeque<int> CDItem::buildPath() const {
PIDeque<int> path;
CDItem * p = parent_;
while (p) {
path.push_front(p->index_);
p = p->parent_;
}
path.take_front();
return path;
}
QString CDItem::stringType(const PIString & t) const {
QString n = PI2QString(t);
if (n.isEmpty()) return QString("");
switch (n[0].toLatin1()) {
case 'l': return QString("list"); break;
case 'b': return QString("bool"); break;
case 'n': return QString("int"); break;
case 'f': return QString("double"); break;
case 'c': return QString("color"); break;
case 'r': return QString("rect"); break;
case 'a': return QString("rect"); break;
case 'p': return QString("point"); break;
case 'v': return QString("vector"); break;
case 'i': return QString("IP"); break;
case 'e': return QString("enum"); break;
case 'F': return QString("file"); break;
case 'D': return QString("dir"); break;
}
return QString("string");
}
QAD::Enum CDItem::xModeEnum(int v) const {
QAD::Enum ret;
ret << QAD::Enumerator(CDType::X_Current, "Current")
<< QAD::Enumerator(CDType::X_All_Avg, "All, Averaging");
ret.selectValue(v);
return ret;
}
// CDKDelegate
CDDelegate::CDDelegate(QObject *parent) : QStyledItemDelegate(parent) {
}
void CDDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const {
CDItem * item = ((CDItemModel*)index.model())->getItem(index);
if (item) {
if (item->itemType() == CDItem::ItemCDType && item->interface->cdType() == CDType::cdC) {
QStyleOptionButton bo;
bo.direction = option.direction;
bo.fontMetrics = option.fontMetrics;
bo.palette = option.palette;
bo.rect = option.rect;
bo.state = option.state;// & ~(QStyle::State_HasFocus | QStyle::State_MouseOver);
bo.text = item->data(1, Qt::DisplayRole).toString();
QWidget * v = (QWidget*)(painter->device());
if (v) {
QPoint cp = v->mapFromGlobal(QCursor::pos());
if (bo.rect.contains(cp, true)) {
//bo.state |= QStyle::State_MouseOver;
if (qApp->mouseButtons().testFlag(Qt::LeftButton))
bo.state |= QStyle::State_On;
}
}
qApp->style()->drawControl(QStyle::CE_PushButton, &bo, painter);
return;
}
}
QStyledItemDelegate::paint(painter, option, index);
}
QWidget * CDDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const {
return new QVariantEdit(parent);
}
void CDDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const {
QVariantEdit *edit = static_cast<QVariantEdit*>(editor);
edit->setValue(index.model()->data(index, Qt::EditRole));
}
void CDDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const {
QVariantEdit *edit = static_cast<QVariantEdit*>(editor);
QVariant v = edit->value();
if (v.canConvert<QAD::Enum>()) {
QAD::Enum et = v.value<QAD::Enum>();
model->setData(index, et.selectedValue(), Qt::EditRole);
} else model->setData(index, v, Qt::EditRole);
}
void CDDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const {
editor->setGeometry(option.rect);
}
QSize CDDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const {
QSize s = QStyledItemDelegate::sizeHint(option, index);
s.setWidth(s.width() + 20);
return s;
}
// CDItemModel
CDItemModel::CDItemModel(int type_, QObject *parent) : QAbstractItemModel(parent) {
interface = new Interface((CDType::cdT)type_);
root = 0;
internalRebuild();
}
CDItemModel::~CDItemModel() {
delete root;
delete interface;
}
QVariant CDItemModel::data(const QModelIndex &index, int role) const {
if (!index.isValid()) return QVariant();
CDItem * item = getItem(index);
return item->data(index.column(), role);
}
QVariant CDItemModel::headerData(int section, Qt::Orientation orientation, int role) const {
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
switch (section) {
case cID: return tr("Index");
case cName_Cmd: return interface->cdType() == CDType::cdC ? tr("Command") : tr("Name");
case cType: return tr("Type");
case cXMode: return tr("Mode");
case cXAvg: return tr("Averaging");
case cExpression: return tr("Expression");
case cValue: return tr("Value");
case cComment: return tr("Comment");
}
}
return QVariant();
}
QModelIndex CDItemModel::index(int row, int column, const QModelIndex &parent) const {
if (parent.isValid() && parent.column() != cID) return QModelIndex();
CDItem * p = getItem(parent);
CDItem * c = p->childs.value(row, 0);
if (c) return createIndex(row, column, c);
else return QModelIndex();
}
QModelIndex CDItemModel::parent(const QModelIndex &index) const {
if (!index.isValid()) return QModelIndex();
CDItem * c = getItem(index);
CDItem * p = c->parent_;
if (p == root) return QModelIndex();
return createIndex(p->parent_->childs.indexOf(p), cID, p);
}
int CDItemModel::rowCount(const QModelIndex &parent) const {
CDItem * p = getItem(parent);
return p->childs.count();
}
int CDItemModel::columnCount(const QModelIndex &parent) const {
return cLastColumn;
}
Qt::ItemFlags CDItemModel::flags(const QModelIndex & index) const {
if (!index.isValid()) return 0;
Qt::ItemFlags f = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
CDItem * item = getItem(index);
if (!item) return 0;
if (item->type_ == CDItem::ItemCDType) {
CDType & t(interface->section(item->buildPath())[item->index_]);
if (t.cd_type() == CDType::cdK) {
if (index.column() == cExpression || index.column() == cValue)
f |= Qt::ItemIsEditable;
if (index.column() == cValue && t.type() == "b")
f |= Qt::ItemIsUserCheckable;
if (index.column() == cName_Cmd)
f |= Qt::ItemIsDragEnabled;
}
if (t.cd_type() == CDType::cdX) {
if (index.column() == cXMode || index.column() == cXAvg)
f |= Qt::ItemIsEditable;
if (index.column() == cName_Cmd)
f |= Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled;
}
}
return f;
}
bool CDItemModel::setData(const QModelIndex & index, const QVariant & value, int role) {
if (role == Qt::CheckStateRole && (index.column() == cName_Cmd || index.column() == cValue)) {
CDItem * item = getItem(index);
if (item->type_ == CDItem::ItemCDType) {
CDType & t(interface->section(item->buildPath())[item->index_]);
if (index.column() == cValue && (t.cd_type() == CDType::cdK)) {
if (t.type() == "b") {
bool result = item->setData(index.column(), PI2QString(PIString::fromBool(value.toBool())));
QModelIndex rin(CDItemModel::index(index.row(), cExpression, index.parent()));
emit dataChanged(rin, rin);
return result;
}
}
if (index.column() == cName_Cmd && (t.cd_type() == CDType::cdX)) {
bool result = item->setData(index.column(), value);
//QModelIndex rin(CDItemModel::index(index.row(), 1, index.parent()));
//emit dataChanged(rin, rin);
return result;
}
}
}
if (role != Qt::EditRole) return false;
CDItem * item = getItem(index);
bool result = item->setData(index.column(), value);
if (result) {
QModelIndex rin(CDItemModel::index(index.row(), cExpression, index.parent()));
emit dataChanged(rin, rin);
emit dataChanged(index, index);
}
return result;
}
QMimeData * CDItemModel::mimeData(const QModelIndexList & indexes) const {
if (indexes.size() == 1) {
QModelIndex index = indexes[0];
if (index.isValid()/* && interface->cdType() == CDType::cdX*/) {
CDItem * item = getItem(index);
if (item) {
CDType & t(interface->section(item->buildPath())[item->index_]);
QMimeData * mime = new QMimeData();
mime->setText(PI2QString(CDCore::instance()->typeLetter(interface->cdType()) +
CDCore::pathToString(t.path())));
return mime;
}
}
}
return QAbstractItemModel::mimeData(indexes);
}
void CDItemModel::rebuildModel() {
beginResetModel();
internalRebuild();
endResetModel();
}
void CDItemModel::buildItem(CDItem * it, CDSection & r) {
//piCout << "build item" << r.name << r.alias;
PIMap<int, CDType>::iterator i;
for (i = r.cd.begin(); i != r.cd.end(); ++i) {
it->childs << new CDItem(interface, i.key(), CDItem::ItemCDType, it);
}
it->item_count = it->childs.size();
PIMap<int, CDSection>::iterator j;
for (j = r.s.begin(); j != r.s.end(); ++j) {
it->childs << new CDItem(interface, j.key(), CDItem::ItemCDSection, it);
buildItem(it->childs.back(), j.value());
}
}
void CDItemModel::updateModel() {
beginResetModel();
endResetModel();
}
void CDItemModel::internalRebuild() {
//qDebug() << "[CDKItemModel]" << "internalRebuild()";
if (root) delete root;
root = new CDItem(interface, 0, CDItem::ItemCDSection, 0);
CDSection & r = interface->root();
buildItem(root, r);
}
CDItem * CDItemModel::getItem(const QModelIndex &index) const {
if (index.isValid()) {
CDItem * item = static_cast<CDItem*>(index.internalPointer());
if (item) return item;
}
return root;
}
QModelIndex CDItemModel::indexByPath(const PIDeque<int> & path, int column) const {
if (path.isEmpty()) return QModelIndex();
CDItem * item = root;
//piCout << path << "...";
bool ok = false;
for (int i = 0; i < path.size_s() - 1; ++i) {
ok = false;
foreach (CDItem * j, item->childs)
if (j->type_ == CDItem::ItemCDSection && j->index_ == path[i]) {
item = j;
ok = true;
break;
}
if (!ok) return QModelIndex();
}
ok = false;
foreach (CDItem * j, item->childs)
if (j->type_ == CDItem::ItemCDType && j->index_ == path.back()) {
item = j;
ok = true;
break;
}
if (!ok || !item->parent_) return QModelIndex();
QModelIndex ret = createIndex(item->parent_->childs.indexOf(item), column, item);
//piCout << path << Q2PIString(item->data(cName_Cmd, Qt::DisplayRole).toString()) << getItem(ret)->buildPath();
return ret;
}
#include "qcd_model.h"
#include "cdutils_interface.h"
#include "cdutils_core.h"
#include "cdutils_x.h"
#include "piqt.h"
#include <QDebug>
#include <QBrush>
#include <QColor>
#include <QMimeData>
#include "qvariantedit.h"
#include "qad_types.h"
using namespace CDUtils;
// CDKItem
CDItem::CDItem(CDUtils::Interface * i, int _index, CDItem::CDItemType type, CDItem *parent) {
interface = i;
index_ = _index;
parent_ = parent;
type_ = type;
item_count = 0;
expanded = true;
}
CDItem::~CDItem() {
qDeleteAll(childs);
}
QVariant CDItem::data(int column, int role) const {
if (role == Qt::BackgroundRole) {
switch (type_) {
case ItemCDType: {
CDType & t(interface->section(buildPath())[index_]);
if (t.errorString().isEmpty()) return QBrush(QColor(255, 250, 230));
else return QBrush(QColor(255, 128, 128));
}
case ItemCDSection: return QBrush(QColor(230, 250, 230));
}
}
if (role == Qt::CheckStateRole && type_ == ItemCDType) {
CDType & t(interface->section(buildPath())[index_]);
if (column == cValue && t.cd_type() == CDType::cdK) {
if (t.type() == "b") return t.toBool() ? Qt::Checked : Qt::Unchecked;
else QVariant();
}
if (column == cName_Cmd && t.cd_type() == CDType::cdX) {
return t.isSelectedX() ? Qt::Checked : Qt::Unchecked;
}
}
if (role == Qt::ToolTipRole && type_ == ItemCDType) {
CDType & t(interface->section(buildPath())[index_]);
return PI2QString(t.errorString());
}
if (role != Qt::DisplayRole && role != Qt::EditRole) return QVariant();
PIDeque<int> path = buildPath();
CDSection & rs = interface->section(path);
CDSection s;
switch (type_) {
case ItemCDType:
switch (column) {
case cID: return QString::number(index_);
case cName_Cmd: return PI2QString(rs[index_].name());
case cType: return stringType(rs[index_].type());
case cXMode: return QVariant::fromValue(xModeEnum(rs[index_].xmode()));
case cXAvg: return rs[index_].avg();
case cExpression: return PI2QString(rs[index_].formula());
case cValue: return value(rs[index_], role);
case cComment: return PI2QString(rs[index_].comment());
default: break;
}
break;
case ItemCDSection:
s = rs.section(index_);
// piCout << rs.name << rs.alias << s.name << s.alias;
switch (column) {
case cID: return QString("[") + QString::number(index_) + QString("]");
case cName_Cmd: return PI2QString(s.alias);
case cType: return PI2QString(s.name);
default: break;
}
break;
}
return QVariant();
}
QVariant CDItem::value(CDType & t, int role) const {
if (t.type() == "f") return t.toDouble();
if (t.type() == "n") return t.toInt();
if (t.type() == "b") return t.toBool();
if (t.type() == "e") {
QAD::Enum et = PI2QADEnum(t.enumValues());
et.selectValue(t.toInt());
if (role == Qt::EditRole) return QVariant::fromValue<QAD::Enum>(et);
else return et.selectedName();
}
return PI2QString(t.value());
}
bool CDItem::setData(int column, const QVariant & value) {
if (type_ == ItemCDType) {
CDType & t(interface->section(buildPath())[index_]);
if ((column == cExpression || column == cValue) && (t.cd_type() == CDType::cdK)) {
interface->section(buildPath())[index_].setValue(Q2PIString(value.toString()));
interface->calculate();
return true;
}
if (t.cd_type() == CDType::cdX) {
switch (column) {
case cName_Cmd:
X.setEnabled(t, value.toBool());
return true;
case cXMode:
t.setXMode((CDType::XMode)value.toInt());
return true;
case cXAvg:
t.setAvg(piMax(value.toInt(), 1));
return true;
default: break;
}
}
}
return false;
}
PIDeque<int> CDItem::buildPath() const {
PIDeque<int> path;
CDItem * p = parent_;
while (p) {
path.push_front(p->index_);
p = p->parent_;
}
path.take_front();
return path;
}
QString CDItem::stringType(const PIString & t) const {
QString n = PI2QString(t);
if (n.isEmpty()) return QString("");
switch (n[0].toLatin1()) {
case 'l': return QString("list"); break;
case 'b': return QString("bool"); break;
case 'n': return QString("int"); break;
case 'f': return QString("double"); break;
case 'c': return QString("color"); break;
case 'r': return QString("rect"); break;
case 'a': return QString("rect"); break;
case 'p': return QString("point"); break;
case 'v': return QString("vector"); break;
case 'i': return QString("IP"); break;
case 'e': return QString("enum"); break;
case 'F': return QString("file"); break;
case 'D': return QString("dir"); break;
}
return QString("string");
}
QAD::Enum CDItem::xModeEnum(int v) const {
QAD::Enum ret;
ret << QAD::Enumerator(CDType::X_Current, "Current")
<< QAD::Enumerator(CDType::X_All_Avg, "All, Averaging");
ret.selectValue(v);
return ret;
}
// CDKDelegate
CDDelegate::CDDelegate(QObject *parent) : QStyledItemDelegate(parent) {
}
void CDDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const {
CDItem * item = ((CDItemModel*)index.model())->getItem(index);
if (item) {
if (item->itemType() == CDItem::ItemCDType && item->interface->cdType() == CDType::cdC) {
QStyleOptionButton bo;
bo.direction = option.direction;
bo.fontMetrics = option.fontMetrics;
bo.palette = option.palette;
bo.rect = option.rect;
bo.state = option.state;// & ~(QStyle::State_HasFocus | QStyle::State_MouseOver);
bo.text = item->data(1, Qt::DisplayRole).toString();
QWidget * v = (QWidget*)(painter->device());
if (v) {
QPoint cp = v->mapFromGlobal(QCursor::pos());
if (bo.rect.contains(cp, true)) {
//bo.state |= QStyle::State_MouseOver;
if (qApp->mouseButtons().testFlag(Qt::LeftButton))
bo.state |= QStyle::State_On;
}
}
qApp->style()->drawControl(QStyle::CE_PushButton, &bo, painter);
return;
}
}
QStyledItemDelegate::paint(painter, option, index);
}
QWidget * CDDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const {
return new QVariantEdit(parent);
}
void CDDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const {
QVariantEdit *edit = static_cast<QVariantEdit*>(editor);
edit->setValue(index.model()->data(index, Qt::EditRole));
}
void CDDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const {
QVariantEdit *edit = static_cast<QVariantEdit*>(editor);
QVariant v = edit->value();
if (v.canConvert<QAD::Enum>()) {
QAD::Enum et = v.value<QAD::Enum>();
model->setData(index, et.selectedValue(), Qt::EditRole);
} else model->setData(index, v, Qt::EditRole);
}
void CDDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const {
editor->setGeometry(option.rect);
}
QSize CDDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const {
QSize s = QStyledItemDelegate::sizeHint(option, index);
s.setWidth(s.width() + 20);
return s;
}
// CDItemModel
CDItemModel::CDItemModel(int type_, QObject *parent) : QAbstractItemModel(parent) {
interface = new Interface((CDType::cdT)type_);
root = 0;
internalRebuild();
}
CDItemModel::~CDItemModel() {
delete root;
delete interface;
}
QVariant CDItemModel::data(const QModelIndex &index, int role) const {
if (!index.isValid()) return QVariant();
CDItem * item = getItem(index);
return item->data(index.column(), role);
}
QVariant CDItemModel::headerData(int section, Qt::Orientation orientation, int role) const {
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
switch (section) {
case cID: return tr("Index");
case cName_Cmd: return interface->cdType() == CDType::cdC ? tr("Command") : tr("Name");
case cType: return tr("Type");
case cXMode: return tr("Mode");
case cXAvg: return tr("Averaging");
case cExpression: return tr("Expression");
case cValue: return tr("Value");
case cComment: return tr("Comment");
}
}
return QVariant();
}
QModelIndex CDItemModel::index(int row, int column, const QModelIndex &parent) const {
if (parent.isValid() && parent.column() != cID) return QModelIndex();
CDItem * p = getItem(parent);
CDItem * c = p->childs.value(row, 0);
if (c) return createIndex(row, column, c);
else return QModelIndex();
}
QModelIndex CDItemModel::parent(const QModelIndex &index) const {
if (!index.isValid()) return QModelIndex();
CDItem * c = getItem(index);
CDItem * p = c->parent_;
if (p == root) return QModelIndex();
return createIndex(p->parent_->childs.indexOf(p), cID, p);
}
int CDItemModel::rowCount(const QModelIndex &parent) const {
CDItem * p = getItem(parent);
return p->childs.count();
}
int CDItemModel::columnCount(const QModelIndex &parent) const {
return cLastColumn;
}
Qt::ItemFlags CDItemModel::flags(const QModelIndex & index) const {
if (!index.isValid()) return Qt::ItemFlags();
Qt::ItemFlags f = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
CDItem * item = getItem(index);
if (!item) return Qt::ItemFlags();
if (item->type_ == CDItem::ItemCDType) {
CDType & t(interface->section(item->buildPath())[item->index_]);
if (t.cd_type() == CDType::cdK) {
if (index.column() == cExpression || index.column() == cValue)
f |= Qt::ItemIsEditable;
if (index.column() == cValue && t.type() == "b")
f |= Qt::ItemIsUserCheckable;
if (index.column() == cName_Cmd)
f |= Qt::ItemIsDragEnabled;
}
if (t.cd_type() == CDType::cdX) {
if (index.column() == cXMode || index.column() == cXAvg)
f |= Qt::ItemIsEditable;
if (index.column() == cName_Cmd)
f |= Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled;
}
}
return f;
}
bool CDItemModel::setData(const QModelIndex & index, const QVariant & value, int role) {
if (role == Qt::CheckStateRole && (index.column() == cName_Cmd || index.column() == cValue)) {
CDItem * item = getItem(index);
if (item->type_ == CDItem::ItemCDType) {
CDType & t(interface->section(item->buildPath())[item->index_]);
if (index.column() == cValue && (t.cd_type() == CDType::cdK)) {
if (t.type() == "b") {
bool result = item->setData(index.column(), PI2QString(PIString::fromBool(value.toBool())));
QModelIndex rin(CDItemModel::index(index.row(), cExpression, index.parent()));
emit dataChanged(rin, rin);
return result;
}
}
if (index.column() == cName_Cmd && (t.cd_type() == CDType::cdX)) {
bool result = item->setData(index.column(), value);
//QModelIndex rin(CDItemModel::index(index.row(), 1, index.parent()));
//emit dataChanged(rin, rin);
return result;
}
}
}
if (role != Qt::EditRole) return false;
CDItem * item = getItem(index);
bool result = item->setData(index.column(), value);
if (result) {
QModelIndex rin(CDItemModel::index(index.row(), cExpression, index.parent()));
emit dataChanged(rin, rin);
emit dataChanged(index, index);
}
return result;
}
QMimeData * CDItemModel::mimeData(const QModelIndexList & indexes) const {
if (indexes.size() == 1) {
QModelIndex index = indexes[0];
if (index.isValid()/* && interface->cdType() == CDType::cdX*/) {
CDItem * item = getItem(index);
if (item) {
CDType & t(interface->section(item->buildPath())[item->index_]);
QMimeData * mime = new QMimeData();
mime->setText(PI2QString(CDCore::instance()->typeLetter(interface->cdType()) +
CDCore::pathToString(t.path())));
return mime;
}
}
}
return QAbstractItemModel::mimeData(indexes);
}
void CDItemModel::rebuildModel() {
beginResetModel();
internalRebuild();
endResetModel();
}
void CDItemModel::buildItem(CDItem * it, CDSection & r) {
//piCout << "build item" << r.name << r.alias;
auto i = r.cd.makeIterator();
while (i.next()) {
it->childs << new CDItem(interface, i.key(), CDItem::ItemCDType, it);
}
it->item_count = it->childs.size();
auto j = r.s.makeIterator();
while (j.next()) {
it->childs << new CDItem(interface, j.key(), CDItem::ItemCDSection, it);
buildItem(it->childs.back(), j.valueRef());
}
}
void CDItemModel::updateModel() {
beginResetModel();
endResetModel();
}
void CDItemModel::internalRebuild() {
//qDebug() << "[CDKItemModel]" << "internalRebuild()";
if (root) delete root;
root = new CDItem(interface, 0, CDItem::ItemCDSection, 0);
CDSection & r = interface->root();
buildItem(root, r);
}
CDItem * CDItemModel::getItem(const QModelIndex &index) const {
if (index.isValid()) {
CDItem * item = static_cast<CDItem*>(index.internalPointer());
if (item) return item;
}
return root;
}
QModelIndex CDItemModel::indexByPath(const PIDeque<int> & path, int column) const {
if (path.isEmpty()) return QModelIndex();
CDItem * item = root;
//piCout << path << "...";
bool ok = false;
for (int i = 0; i < path.size_s() - 1; ++i) {
ok = false;
foreach (CDItem * j, item->childs)
if (j->type_ == CDItem::ItemCDSection && j->index_ == path[i]) {
item = j;
ok = true;
break;
}
if (!ok) return QModelIndex();
}
ok = false;
foreach (CDItem * j, item->childs)
if (j->type_ == CDItem::ItemCDType && j->index_ == path.back()) {
item = j;
ok = true;
break;
}
if (!ok || !item->parent_) return QModelIndex();
QModelIndex ret = createIndex(item->parent_->childs.indexOf(item), column, item);
//piCout << path << Q2PIString(item->data(cName_Cmd, Qt::DisplayRole).toString()) << getItem(ret)->buildPath();
return ret;
}

View File

@@ -1,132 +1,133 @@
/*
QCD Utils - Qt bindings/utilites for CD Utils
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QCD_MODEL_H
#define QCD_MODEL_H
#include <QAbstractItemModel>
#include <QItemDelegate>
#include <QStyledItemDelegate>
#include "pistring.h"
namespace CDUtils {
class CDType;
class CDSection;
class Interface;
enum Column {
cID ,
cName_Cmd ,
cType ,
cXMode ,
cXAvg ,
cExpression,
cValue ,
cComment ,
cLastColumn,
};
}
namespace QAD {
struct Enum;
}
class CDItemModel;
class CDItem {
friend class CDItemModel;
friend class CDView;
public:
enum CDItemType{ItemCDType, ItemCDSection};
CDItem(CDUtils::Interface * interface, int _index, CDItemType type, CDItem * parent);
~CDItem();
QVariant data(int column, int role) const;
QVariant value(CDUtils::CDType & t, int role) const;
bool setData(int column, const QVariant & value);
CDItemType itemType() const {return type_;}
PIDeque<int> buildPath() const;
int index() const {return index_;}
CDUtils::Interface * interface;
bool expanded;
private:
QString stringType(const PIString & t) const;
QAD::Enum xModeEnum(int v) const;
CDItem * parent_;
int index_, item_count;
CDItemType type_;
QList<CDItem *> childs;
};
class CDDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
CDDelegate(QObject *parent = 0);
void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void setEditorData(QWidget *editor, const QModelIndex &index) const;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
};
class CDItemModel : public QAbstractItemModel {
Q_OBJECT
friend class CDView;
public:
explicit CDItemModel(int type_, QObject *parent = 0);
~CDItemModel();
QVariant data(const QModelIndex & index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex &index) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
QMimeData * mimeData(const QModelIndexList & indexes) const;
CDItem * getItem(const QModelIndex & index) const;
QModelIndex indexByPath(const PIDeque<int> & path, int column = CDUtils::cID) const;
void buildItem(CDItem * it, CDUtils::CDSection &r);
public slots:
void rebuildModel();
void updateModel();
private:
void internalRebuild();
CDUtils::Interface * interface;
CDItem * root;
signals:
};
#endif // QCD_MODEL_H
/*
QCD Utils - Qt bindings/utilites for CD Utils
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QCD_MODEL_H
#define QCD_MODEL_H
#include <QAbstractItemModel>
#include <QItemDelegate>
#include <QStyledItemDelegate>
#include "pistring.h"
#include "qcd_utils_export.h"
namespace CDUtils {
class CDType;
class CDSection;
class Interface;
enum Column {
cID ,
cName_Cmd ,
cType ,
cXMode ,
cXAvg ,
cExpression,
cValue ,
cComment ,
cLastColumn,
};
}
namespace QAD {
struct Enum;
}
class CDItemModel;
class QCD_UTILS_EXPORT CDItem {
friend class CDItemModel;
friend class CDView;
public:
enum CDItemType{ItemCDType, ItemCDSection};
CDItem(CDUtils::Interface * interface, int _index, CDItemType type, CDItem * parent);
~CDItem();
QVariant data(int column, int role) const;
QVariant value(CDUtils::CDType & t, int role) const;
bool setData(int column, const QVariant & value);
CDItemType itemType() const {return type_;}
PIDeque<int> buildPath() const;
int index() const {return index_;}
CDUtils::Interface * interface;
bool expanded;
private:
QString stringType(const PIString & t) const;
QAD::Enum xModeEnum(int v) const;
CDItem * parent_;
int index_, item_count;
CDItemType type_;
QList<CDItem *> childs;
};
class QCD_UTILS_EXPORT CDDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
CDDelegate(QObject *parent = 0);
void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void setEditorData(QWidget *editor, const QModelIndex &index) const;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
};
class QCD_UTILS_EXPORT CDItemModel : public QAbstractItemModel {
Q_OBJECT
friend class CDView;
public:
explicit CDItemModel(int type_, QObject *parent = 0);
~CDItemModel();
QVariant data(const QModelIndex & index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex &index) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
QMimeData * mimeData(const QModelIndexList & indexes) const;
CDItem * getItem(const QModelIndex & index) const;
QModelIndex indexByPath(const PIDeque<int> & path, int column = CDUtils::cID) const;
void buildItem(CDItem * it, CDUtils::CDSection &r);
public slots:
void rebuildModel();
void updateModel();
private:
void internalRebuild();
CDUtils::Interface * interface;
CDItem * root;
signals:
};
#endif // QCD_MODEL_H

View File

@@ -1,371 +1,371 @@
#include <QDir>
#include <QMouseEvent>
#include <QSortFilterProxyModel>
#include "cdutils_k.h"
#include "cdutils_x.h"
#include "cdutils_c.h"
#include "cdutils_m.h"
#include "cdutils_core.h"
#include "qcd_view.h"
#include "qcd_model.h"
#include "piqt.h"
#include "pifile.h"
using namespace CDUtils;
CDView::CDView(QWidget * parent) : QTreeView(parent) {
type_ = -1;
model_ = 0;
proxy_ = 0;
connect(this, SIGNAL(clicked(QModelIndex)), this, SLOT(indexClicked(QModelIndex)));
connect(this, SIGNAL(_qcd_sendFailed()), this, SLOT(cd_sendFailed()), Qt::QueuedConnection);
connect(this, SIGNAL(_qcd_sendSucceed()), this, SLOT(cd_sendSucceed()), Qt::QueuedConnection);
connect(this, SIGNAL(_qcd_receiveFailed()), this, SLOT(cd_receiveFailed()), Qt::QueuedConnection);
connect(this, SIGNAL(_qcd_receiveSucceed()), this, SLOT(cd_receiveSucceed()), Qt::QueuedConnection);
connect(this, SIGNAL(_qcd_receivedX()), this, SLOT(cd_receivedX()), Qt::QueuedConnection);
connect(this, SIGNAL(_qcd_changedGlobal()), this, SLOT(cd_changedGlobal()), Qt::QueuedConnection);
}
CDView::~CDView() {
if (model_) {
delete model_;
delete proxy_;
}
model_ = 0;
proxy_ = 0;
}
void CDView::setType(int cdt) {
if (cdt < 0) return;
if (type_ >= 0) return;
type_ = cdt;
switch ((CDType::cdT)type_) {
case CDType::cdK:
CONNECTU(&K, sended, this, pi_cd_sendSucceed);
CONNECTU(&K, sendFailed, this, pi_cd_sendFailed);
CONNECTU(&K, received, this, pi_cd_receiveSucceed);
CONNECTU(&K, receiveFailed, this, pi_cd_receiveFailed);
CONNECTU(&K, changedGlobal, this, pi_cd_changedGlobal);
break;
case CDType::cdX:
CONNECTU(&X, sended, this, pi_cd_sendSucceed);
CONNECTU(&X, sendFailed, this, pi_cd_sendFailed);
CONNECTU(&X, received, this, pi_cd_receiveSucceed);
CONNECTU(&X, receiveFailed, this, pi_cd_receiveFailed);
CONNECTU(&X, receivedX, this, pi_cd_receivedX);
CONNECTU(&X, changedGlobal, this, pi_cd_changedGlobal);
break;
case CDType::cdC:
CONNECTU(&C, sended, this, pi_cd_sendSucceed);
CONNECTU(&C, sendFailed, this, pi_cd_sendFailed);
CONNECTU(&C, received, this, pi_cd_receiveSucceed);
CONNECTU(&C, receiveFailed, this, pi_cd_receiveFailed);
CONNECTU(&C, changedGlobal, this, pi_cd_changedGlobal);
break;
case CDType::cdM:
CONNECTU(&M, sended, this, pi_cd_sendSucceed);
CONNECTU(&M, sendFailed, this, pi_cd_sendFailed);
CONNECTU(&M, received, this, pi_cd_receiveSucceed);
CONNECTU(&M, receiveFailed, this, pi_cd_receiveFailed);
CONNECTU(&M, changedGlobal, this, pi_cd_changedGlobal);
CONNECTU(&M, messageReceived, this, pi_cd_messageReceived);
break;
default: break;
}
}
void CDView::mousePressEvent(QMouseEvent * e) {
if (type_ == CDType::cdC) {
QModelIndex i = indexAt(e->pos());
if (i.isValid() && i.column() == cName_Cmd)
update(i);
}
QTreeView::mousePressEvent(e);
}
void CDView::mouseReleaseEvent(QMouseEvent * e) {
if (type_ == CDType::cdC) {
QModelIndex i = indexAt(e->pos());
if (i.isValid() && i.column() == cName_Cmd)
update(i);
}
QTreeView::mouseReleaseEvent(e);
}
void CDView::currentChanged(const QModelIndex & cur, const QModelIndex & prev) {
if (type_ == CDType::cdC) {
if (prev.isValid() && prev.column() == cName_Cmd)
update(prev);
}
QTreeView::currentChanged(cur, prev);
}
void CDView::refresh() {
if (type_ < 0) return;
if (!model_) {
model_ = new CDItemModel(type_);
proxy_ = new QSortFilterProxyModel();
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
proxy_->setRecursiveFilteringEnabled(true);
#endif
proxy_->setFilterKeyColumn(-1);
proxy_->setFilterCaseSensitivity(Qt::CaseInsensitive);
proxy_->setSourceModel(model_);
setModel(proxy_);
setItemDelegateForColumn(type_ == CDType::cdC ? cName_Cmd : cValue, new CDDelegate());
if (type_ == CDType::cdX)
setItemDelegateForColumn(cXMode, new CDDelegate());
}
model_->rebuildModel();
switch ((CDType::cdT)type_) {
case CDType::cdK:
setColumnHidden(cXMode, true);
setColumnHidden(cXAvg, true);
break;
case CDType::cdX:
setColumnHidden(cExpression, true);
break;
case CDType::cdC:
case CDType::cdM:
setColumnHidden(cType, true);
setColumnHidden(cXMode, true);
setColumnHidden(cXAvg, true);
setColumnHidden(cExpression, true);
setColumnHidden(cValue, true);
break;
default: break;
}
expandAll();
for (int i = 0; i < model_->columnCount(); i++) resizeColumnToContents(i);
}
void CDView::refreshValues() {
if (!model_) return;
model_->dataChanged(model_->index(0, 0), model_->index(model_->columnCount() - 1, model_->rowCount() - 1));
}
void CDView::setFile(const QString & filename) {
switch ((CDType::cdT)type_) {
case CDType::cdK: K.setFileName(Q2PIString(filename)); break;
case CDType::cdX: X.setFileName(Q2PIString(filename)); break;
case CDType::cdC: C.setFileName(Q2PIString(filename)); break;
case CDType::cdM: M.setFileName(Q2PIString(filename)); break;
default: break;
}
}
bool CDView::inProgress() const {
switch ((CDType::cdT)type_) {
case CDType::cdK: return K.inProgress(); break;
case CDType::cdX: return X.inProgress(); break;
case CDType::cdC: return C.inProgress(); break;
case CDType::cdM: return M.inProgress(); break;
default: break;
}
return false;
}
void CDView::startX(double freq) {
switch ((CDType::cdT)type_) {
case CDType::cdX: X.start(freq); break;
default: break;
}
}
CDSection * CDView::root() {
return CDCore::instance()->root((CDType::cdT)type_);
}
QString CDView::typeLetter() const {
return PI2QString(CDCore::instance()->typeLetter((CDType::cdT)type_));
}
void CDView::send() {
busyStatusChanged(true);
switch ((CDType::cdT)type_) {
case CDType::cdK: K.send(); break;
case CDType::cdX: X.send(); break;
case CDType::cdC: C.send(); break;
case CDType::cdM: M.send(); break;
default: break;
}
}
void CDView::receive() {
busyStatusChanged(true);
switch ((CDType::cdT)type_) {
case CDType::cdK: K.request(); break;
case CDType::cdX: X.request(); break;
case CDType::cdC: C.request(); break;
case CDType::cdM: M.request(); break;
default: break;
}
}
void CDView::save() {
switch ((CDType::cdT)type_) {
case CDType::cdK: K.writeFile(); break;
case CDType::cdX: X.writeFile(); break;
case CDType::cdC: C.writeFile(); break;
case CDType::cdM: M.writeFile(); break;
default: break;
}
}
void CDView::load() {
switch ((CDType::cdT)type_) {
case CDType::cdK:
K.readFile();
K.calculate();
break;
case CDType::cdX:
X.readFile();
X.calculate();
break;
case CDType::cdC:
C.readFile();
C.calculate();
break;
case CDType::cdM:
M.readFile();
M.calculate();
break;
default: break;
}
refresh();
}
void CDView::clear() {
//piCout << "clearK";
switch ((CDType::cdT)type_) {
case CDType::cdK: K.root() = CDSection(); break;
case CDType::cdX: X.root() = CDSection(); break;
case CDType::cdC: C.root() = CDSection(); break;
case CDType::cdM: M.root() = CDSection(); break;
default: break;
}
refresh();
}
void CDView::buildFromHeader(const QString & description, int mode) {
if (description.isEmpty()) return;
PIString desc_file = Q2PIString(QDir::current().relativeFilePath(description));
PIFile f(desc_file, PIIODevice::ReadOnly);
switch ((CDType::cdT)type_) {
case CDType::cdK: K.update(&f, mode); break;
case CDType::cdX: X.update(&f, mode); break;
case CDType::cdC: C.update(&f, mode); break;
case CDType::cdM: M.update(&f, mode); break;
default: break;
}
refresh();
}
void CDView::calculate() {
switch ((CDType::cdT)type_) {
case CDType::cdK: K.calculate(); break;
case CDType::cdX: X.calculate(); break;
case CDType::cdC: C.calculate(); break;
case CDType::cdM: M.calculate(); break;
default: break;
}
}
void CDView::filter(const QString & f) {
proxy_->setFilterRegExp(QRegExp(f, Qt::CaseInsensitive));
}
void CDView::indexClicked(const QModelIndex & i) {
if (!model_ || !i.isValid() || type_ != CDType::cdC || i.column() != cName_Cmd) return;
CDItem * item = model_->getItem(i);
if (!item) return;
if (item->itemType() != CDItem::ItemCDType) return;
CDType & t(model_->interface->section(item->buildPath())[item->index()]);
C.sendCommand(t);
emit commandSended(PI2QString(t.pathString().join(".")));
//piCout << t;
qDebug() << PI2QString(t.pathString().join("."));
}
void CDView::cd_sendFailed() {
busyStatusChanged(false);
emit messageStatus("send failed");
emit sendFailed();
}
void CDView::cd_sendSucceed() {
busyStatusChanged(false);
emit messageStatus("send success");
emit sendSucceed();
}
void CDView::cd_receiveFailed() {
busyStatusChanged(false);
emit messageStatus("receive failed");
emit receiveFailed();
}
void CDView::cd_receiveSucceed() {
refresh();
busyStatusChanged(false);
emit messageStatus("receive success");
emit receiveSucceed();
}
void CDView::cd_receivedX() {
X.lock();
PIVector<PIDeque<int> > xl = X.enabledList();
//piCout << "X" << xl.size();
piForeachC (PIDeque<int> & x, xl) {
CDType & t(X[x]);
//piCout << t;
//piCout << t.path();
if (t.cd_type() != CDType::cdX) continue;
update(model_->indexByPath(t.path(), cValue));
//piCout << CDCore::pathToString(t.path()) << t.toDouble() << "model";
//qDebug() << "val" << model_->data(model_->indexByPath(t.path(), cValue), Qt::DisplayRole).toDouble();
}
X.unlock();
emit receivedX();
}
void CDView::cd_changedGlobal() {
emit changedGlobal();
}
void CDView::pi_cd_messageReceived(PIDeque<int> path, int type, PIString msg) {
QMetaObject::invokeMethod(this, "messageReceived", Qt::QueuedConnection,
Q_ARG(QString, PI2QString(CDCore::pathToString(path))),
Q_ARG(int, type),
Q_ARG(QString, PI2QString(msg)));
}
#include <QDir>
#include <QMouseEvent>
#include <QSortFilterProxyModel>
#include "cdutils_k.h"
#include "cdutils_x.h"
#include "cdutils_c.h"
#include "cdutils_m.h"
#include "cdutils_core.h"
#include "qcd_view.h"
#include "qcd_model.h"
#include "piqt.h"
#include "pifile.h"
using namespace CDUtils;
CDView::CDView(QWidget * parent) : QTreeView(parent) {
type_ = -1;
model_ = 0;
proxy_ = 0;
connect(this, SIGNAL(clicked(QModelIndex)), this, SLOT(indexClicked(QModelIndex)));
connect(this, SIGNAL(_qcd_sendFailed()), this, SLOT(cd_sendFailed()), Qt::QueuedConnection);
connect(this, SIGNAL(_qcd_sendSucceed()), this, SLOT(cd_sendSucceed()), Qt::QueuedConnection);
connect(this, SIGNAL(_qcd_receiveFailed()), this, SLOT(cd_receiveFailed()), Qt::QueuedConnection);
connect(this, SIGNAL(_qcd_receiveSucceed()), this, SLOT(cd_receiveSucceed()), Qt::QueuedConnection);
connect(this, SIGNAL(_qcd_receivedX()), this, SLOT(cd_receivedX()), Qt::QueuedConnection);
connect(this, SIGNAL(_qcd_changedGlobal()), this, SLOT(cd_changedGlobal()), Qt::QueuedConnection);
}
CDView::~CDView() {
if (model_) {
delete model_;
delete proxy_;
}
model_ = 0;
proxy_ = 0;
}
void CDView::setType(int cdt) {
if (cdt < 0) return;
if (type_ >= 0) return;
type_ = cdt;
switch ((CDType::cdT)type_) {
case CDType::cdK:
CONNECTU(&K, sended, this, pi_cd_sendSucceed);
CONNECTU(&K, sendFailed, this, pi_cd_sendFailed);
CONNECTU(&K, received, this, pi_cd_receiveSucceed);
CONNECTU(&K, receiveFailed, this, pi_cd_receiveFailed);
CONNECTU(&K, changedGlobal, this, pi_cd_changedGlobal);
break;
case CDType::cdX:
CONNECTU(&X, sended, this, pi_cd_sendSucceed);
CONNECTU(&X, sendFailed, this, pi_cd_sendFailed);
CONNECTU(&X, received, this, pi_cd_receiveSucceed);
CONNECTU(&X, receiveFailed, this, pi_cd_receiveFailed);
CONNECTU(&X, receivedX, this, pi_cd_receivedX);
CONNECTU(&X, changedGlobal, this, pi_cd_changedGlobal);
break;
case CDType::cdC:
CONNECTU(&C, sended, this, pi_cd_sendSucceed);
CONNECTU(&C, sendFailed, this, pi_cd_sendFailed);
CONNECTU(&C, received, this, pi_cd_receiveSucceed);
CONNECTU(&C, receiveFailed, this, pi_cd_receiveFailed);
CONNECTU(&C, changedGlobal, this, pi_cd_changedGlobal);
break;
case CDType::cdM:
CONNECTU(&M, sended, this, pi_cd_sendSucceed);
CONNECTU(&M, sendFailed, this, pi_cd_sendFailed);
CONNECTU(&M, received, this, pi_cd_receiveSucceed);
CONNECTU(&M, receiveFailed, this, pi_cd_receiveFailed);
CONNECTU(&M, changedGlobal, this, pi_cd_changedGlobal);
CONNECTU(&M, messageReceived, this, pi_cd_messageReceived);
break;
default: break;
}
}
void CDView::mousePressEvent(QMouseEvent * e) {
if (type_ == CDType::cdC) {
QModelIndex i = indexAt(e->pos());
if (i.isValid() && i.column() == cName_Cmd)
update(i);
}
QTreeView::mousePressEvent(e);
}
void CDView::mouseReleaseEvent(QMouseEvent * e) {
if (type_ == CDType::cdC) {
QModelIndex i = indexAt(e->pos());
if (i.isValid() && i.column() == cName_Cmd)
update(i);
}
QTreeView::mouseReleaseEvent(e);
}
void CDView::currentChanged(const QModelIndex & cur, const QModelIndex & prev) {
if (type_ == CDType::cdC) {
if (prev.isValid() && prev.column() == cName_Cmd)
update(prev);
}
QTreeView::currentChanged(cur, prev);
}
void CDView::refresh() {
if (type_ < 0) return;
if (!model_) {
model_ = new CDItemModel(type_);
proxy_ = new QSortFilterProxyModel();
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
proxy_->setRecursiveFilteringEnabled(true);
#endif
proxy_->setFilterKeyColumn(-1);
proxy_->setFilterCaseSensitivity(Qt::CaseInsensitive);
proxy_->setSourceModel(model_);
setModel(proxy_);
setItemDelegateForColumn(type_ == CDType::cdC ? cName_Cmd : cValue, new CDDelegate());
if (type_ == CDType::cdX)
setItemDelegateForColumn(cXMode, new CDDelegate());
}
model_->rebuildModel();
switch ((CDType::cdT)type_) {
case CDType::cdK:
setColumnHidden(cXMode, true);
setColumnHidden(cXAvg, true);
break;
case CDType::cdX:
setColumnHidden(cExpression, true);
break;
case CDType::cdC:
case CDType::cdM:
setColumnHidden(cType, true);
setColumnHidden(cXMode, true);
setColumnHidden(cXAvg, true);
setColumnHidden(cExpression, true);
setColumnHidden(cValue, true);
break;
default: break;
}
expandAll();
for (int i = 0; i < model_->columnCount(); i++) resizeColumnToContents(i);
}
void CDView::refreshValues() {
if (!model_) return;
model_->dataChanged(model_->index(0, 0), model_->index(model_->columnCount() - 1, model_->rowCount() - 1));
}
void CDView::setFile(const QString & filename) {
switch ((CDType::cdT)type_) {
case CDType::cdK: K.setFileName(Q2PIString(filename)); break;
case CDType::cdX: X.setFileName(Q2PIString(filename)); break;
case CDType::cdC: C.setFileName(Q2PIString(filename)); break;
case CDType::cdM: M.setFileName(Q2PIString(filename)); break;
default: break;
}
}
bool CDView::inProgress() const {
switch ((CDType::cdT)type_) {
case CDType::cdK: return K.inProgress(); break;
case CDType::cdX: return X.inProgress(); break;
case CDType::cdC: return C.inProgress(); break;
case CDType::cdM: return M.inProgress(); break;
default: break;
}
return false;
}
void CDView::startX(double freq) {
switch ((CDType::cdT)type_) {
case CDType::cdX: X.start(freq); break;
default: break;
}
}
CDSection * CDView::root() {
return CDCore::instance()->root((CDType::cdT)type_);
}
QString CDView::typeLetter() const {
return PI2QString(CDCore::instance()->typeLetter((CDType::cdT)type_));
}
void CDView::send() {
busyStatusChanged(true);
switch ((CDType::cdT)type_) {
case CDType::cdK: K.send(); break;
case CDType::cdX: X.send(); break;
case CDType::cdC: C.send(); break;
case CDType::cdM: M.send(); break;
default: break;
}
}
void CDView::receive() {
busyStatusChanged(true);
switch ((CDType::cdT)type_) {
case CDType::cdK: K.request(); break;
case CDType::cdX: X.request(); break;
case CDType::cdC: C.request(); break;
case CDType::cdM: M.request(); break;
default: break;
}
}
void CDView::save() {
switch ((CDType::cdT)type_) {
case CDType::cdK: K.writeFile(); break;
case CDType::cdX: X.writeFile(); break;
case CDType::cdC: C.writeFile(); break;
case CDType::cdM: M.writeFile(); break;
default: break;
}
}
void CDView::load() {
switch ((CDType::cdT)type_) {
case CDType::cdK:
K.readFile();
K.calculate();
break;
case CDType::cdX:
X.readFile();
X.calculate();
break;
case CDType::cdC:
C.readFile();
C.calculate();
break;
case CDType::cdM:
M.readFile();
M.calculate();
break;
default: break;
}
refresh();
}
void CDView::clear() {
//piCout << "clearK";
switch ((CDType::cdT)type_) {
case CDType::cdK: K.root() = CDSection(); break;
case CDType::cdX: X.root() = CDSection(); break;
case CDType::cdC: C.root() = CDSection(); break;
case CDType::cdM: M.root() = CDSection(); break;
default: break;
}
refresh();
}
void CDView::buildFromHeader(const QString & description, int mode) {
if (description.isEmpty()) return;
PIString desc_file = Q2PIString(QDir::current().relativeFilePath(description));
PIFile f(desc_file, PIIODevice::ReadOnly);
switch ((CDType::cdT)type_) {
case CDType::cdK: K.update(&f, mode); break;
case CDType::cdX: X.update(&f, mode); break;
case CDType::cdC: C.update(&f, mode); break;
case CDType::cdM: M.update(&f, mode); break;
default: break;
}
refresh();
}
void CDView::calculate() {
switch ((CDType::cdT)type_) {
case CDType::cdK: K.calculate(); break;
case CDType::cdX: X.calculate(); break;
case CDType::cdC: C.calculate(); break;
case CDType::cdM: M.calculate(); break;
default: break;
}
}
void CDView::filter(const QString & f) {
proxy_->setFilterRegExp(QRegExp(f, Qt::CaseInsensitive));
}
void CDView::indexClicked(const QModelIndex & i) {
if (!model_ || !i.isValid() || type_ != CDType::cdC || i.column() != cName_Cmd) return;
CDItem * item = model_->getItem(i);
if (!item) return;
if (item->itemType() != CDItem::ItemCDType) return;
CDType & t(model_->interface->section(item->buildPath())[item->index()]);
C.sendCommand(t);
emit commandSended(PI2QString(t.pathString().join(".")));
//piCout << t;
qDebug() << PI2QString(t.pathString().join("."));
}
void CDView::cd_sendFailed() {
busyStatusChanged(false);
emit messageStatus("send failed");
emit sendFailed();
}
void CDView::cd_sendSucceed() {
busyStatusChanged(false);
emit messageStatus("send success");
emit sendSucceed();
}
void CDView::cd_receiveFailed() {
busyStatusChanged(false);
emit messageStatus("receive failed");
emit receiveFailed();
}
void CDView::cd_receiveSucceed() {
refresh();
busyStatusChanged(false);
emit messageStatus("receive success");
emit receiveSucceed();
}
void CDView::cd_receivedX() {
X.lock();
PIVector<PIDeque<int> > xl = X.enabledList();
//piCout << "X" << xl.size();
piForeachC (PIDeque<int> & x, xl) {
CDType & t(X[x]);
//piCout << t;
//piCout << t.path();
if (t.cd_type() != CDType::cdX) continue;
update(model_->indexByPath(t.path(), cValue));
//piCout << CDCore::pathToString(t.path()) << t.toDouble() << "model";
//qDebug() << "val" << model_->data(model_->indexByPath(t.path(), cValue), Qt::DisplayRole).toDouble();
}
X.unlock();
emit receivedX();
}
void CDView::cd_changedGlobal() {
emit changedGlobal();
}
void CDView::pi_cd_messageReceived(PIDeque<int> path, int type, PIString msg) {
QMetaObject::invokeMethod(this, "messageReceived", Qt::QueuedConnection,
Q_ARG(QString, PI2QString(CDCore::pathToString(path))),
Q_ARG(int, type),
Q_ARG(QString, PI2QString(msg)));
}

View File

@@ -1,112 +1,113 @@
/*
QCD Utils - Qt bindings/utilites for CD Utils
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QCD_VIEW_H
#define QCD_VIEW_H
#include "piobject.h"
#include <QTreeView>
namespace CDUtils {
class CDType;
class CDSection;
}
class CDItemModel;
class QSortFilterProxyModel;
class CDView: public QTreeView, public PIObject
{
Q_OBJECT
PIOBJECT(CDView)
public:
explicit CDView(QWidget *parent = 0);
~CDView();
void setType(int cdt);
void setFile(const QString & filename);
bool inProgress() const;
void startX(double freq = 20.);
CDUtils::CDSection * root();
QString typeLetter() const;
CDItemModel * CDModel() {return model_;}
protected:
void mousePressEvent(QMouseEvent * );
void mouseReleaseEvent(QMouseEvent * );
void currentChanged(const QModelIndex & cur, const QModelIndex & prev);
public slots:
void refresh();
void refreshValues();
void send();
void receive();
void save();
void load();
void clear();
void buildFromHeader(const QString & description, int mode = 2);
void calculate();
void filter(const QString & f);
private slots:
void indexClicked(const QModelIndex & i);
void cd_sendFailed();
void cd_sendSucceed();
void cd_receiveFailed();
void cd_receiveSucceed();
void cd_receivedX();
void cd_changedGlobal();
private:
bool filterTree(const QModelIndex & ti, const QString & filter);
EVENT_HANDLER(void, pi_cd_sendFailed) {emit _qcd_sendFailed();}
EVENT_HANDLER(void, pi_cd_sendSucceed) {emit _qcd_sendSucceed();}
EVENT_HANDLER(void, pi_cd_receiveFailed) {emit _qcd_receiveFailed();}
EVENT_HANDLER(void, pi_cd_receiveSucceed) {emit _qcd_receiveSucceed();}
EVENT_HANDLER(void, pi_cd_receivedX) {emit _qcd_receivedX();}
EVENT_HANDLER(void, pi_cd_changedGlobal) {emit _qcd_changedGlobal();}
EVENT_HANDLER3(void, pi_cd_messageReceived, PIDeque<int>, path, int, type, PIString, msg);
CDItemModel * model_;
QSortFilterProxyModel * proxy_;
int type_;
signals:
void sendFailed();
void sendSucceed();
void receiveFailed();
void receiveSucceed();
void receivedX();
void changedGlobal();
void messageStatus(QString msg);
void commandSended(QString msg);
void messageReceived(QString path, int type, QString msg);
void busyStatusChanged(bool busy);
void _qcd_sendFailed(); // PRIVATE
void _qcd_sendSucceed(); // PRIVATE
void _qcd_receiveFailed(); // PRIVATE
void _qcd_receiveSucceed(); // PRIVATE
void _qcd_receivedX(); // PRIVATE
void _qcd_changedGlobal(); // PRIVATE
};
#endif // QCD_VIEW_H
/*
QCD Utils - Qt bindings/utilites for CD Utils
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QCD_VIEW_H
#define QCD_VIEW_H
#include <QTreeView>
#include "piobject.h"
#include "qcd_utils_export.h"
namespace CDUtils {
class CDType;
class CDSection;
}
class CDItemModel;
class QSortFilterProxyModel;
class QCD_UTILS_EXPORT CDView: public QTreeView, public PIObject
{
Q_OBJECT
PIOBJECT(CDView)
public:
explicit CDView(QWidget *parent = 0);
~CDView();
void setType(int cdt);
void setFile(const QString & filename);
bool inProgress() const;
void startX(double freq = 20.);
CDUtils::CDSection * root();
QString typeLetter() const;
CDItemModel * CDModel() {return model_;}
protected:
void mousePressEvent(QMouseEvent * );
void mouseReleaseEvent(QMouseEvent * );
void currentChanged(const QModelIndex & cur, const QModelIndex & prev);
public slots:
void refresh();
void refreshValues();
void send();
void receive();
void save();
void load();
void clear();
void buildFromHeader(const QString & description, int mode = 2);
void calculate();
void filter(const QString & f);
private slots:
void indexClicked(const QModelIndex & i);
void cd_sendFailed();
void cd_sendSucceed();
void cd_receiveFailed();
void cd_receiveSucceed();
void cd_receivedX();
void cd_changedGlobal();
private:
bool filterTree(const QModelIndex & ti, const QString & filter);
EVENT_HANDLER(void, pi_cd_sendFailed) {emit _qcd_sendFailed();}
EVENT_HANDLER(void, pi_cd_sendSucceed) {emit _qcd_sendSucceed();}
EVENT_HANDLER(void, pi_cd_receiveFailed) {emit _qcd_receiveFailed();}
EVENT_HANDLER(void, pi_cd_receiveSucceed) {emit _qcd_receiveSucceed();}
EVENT_HANDLER(void, pi_cd_receivedX) {emit _qcd_receivedX();}
EVENT_HANDLER(void, pi_cd_changedGlobal) {emit _qcd_changedGlobal();}
EVENT_HANDLER3(void, pi_cd_messageReceived, PIDeque<int>, path, int, type, PIString, msg);
CDItemModel * model_;
QSortFilterProxyModel * proxy_;
int type_;
signals:
void sendFailed();
void sendSucceed();
void receiveFailed();
void receiveSucceed();
void receivedX();
void changedGlobal();
void messageStatus(QString msg);
void commandSended(QString msg);
void messageReceived(QString path, int type, QString msg);
void busyStatusChanged(bool busy);
void _qcd_sendFailed(); // PRIVATE
void _qcd_sendSucceed(); // PRIVATE
void _qcd_receiveFailed(); // PRIVATE
void _qcd_receiveSucceed(); // PRIVATE
void _qcd_receivedX(); // PRIVATE
void _qcd_changedGlobal(); // PRIVATE
};
#endif // QCD_VIEW_H

View File

@@ -0,0 +1,9 @@
include(PIPMacros)
pip_code_model(CCM "${ROOT_DIR}/pip/libs/main/io_devices/piiodevice.h" "${ROOT_DIR}/pip/libs/main/io_utils/pipacketextractor.h" OPTIONS "-DPIP_EXPORT" "-Es")
piqt_library(piqt_utils "Gui" "qad_utils;qad_widgets;qad_blockview;piqt" ${CCM})
foreach(_v ${_QT_VERSIONS_})
if (LOCAL_FOUND${_v})
add_dependencies(piqt_utils${_v} pip_cmg)
endif()
endforeach()

View File

@@ -22,6 +22,8 @@
#include <QDialog>
#include "piconnection.h"
#include "piqt_utils_export.h"
namespace Ui {
class ConnectionEdit;
@@ -31,7 +33,7 @@ class FilterItem;
class DeviceItem;
class SenderItem;
class ConnectionEdit: public QDialog {
class PIQT_UTILS_EXPORT ConnectionEdit: public QDialog {
Q_OBJECT
public:
explicit ConnectionEdit(QWidget * parent = 0);

View File

@@ -22,14 +22,20 @@
<widget class="QWidget" name="layoutWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QWidget" name="widget" native="true">
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
@@ -268,7 +274,7 @@
<string>Add</string>
</property>
<property name="icon">
<iconset>
<iconset resource="../../../qad/libs/application/qad_application.qrc">
<normaloff>:/icons/list-add.png</normaloff>:/icons/list-add.png</iconset>
</property>
</widget>
@@ -282,8 +288,8 @@
<string>Modify</string>
</property>
<property name="icon">
<iconset resource="piconnedit/piconnedit.qrc">
<normaloff>:/icons/document-save-.png</normaloff>:/icons/document-save-.png</iconset>
<iconset resource="../../../qad/libs/application/qad_application.qrc">
<normaloff>:/icons/document-save.png</normaloff>:/icons/document-save.png</iconset>
</property>
</widget>
</item>
@@ -330,7 +336,16 @@
<bool>false</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@@ -371,7 +386,16 @@
<bool>false</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@@ -400,7 +424,16 @@
<bool>false</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@@ -451,7 +484,16 @@
<bool>false</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@@ -500,7 +542,16 @@
<item>
<widget class="QWidget" name="widgetDT" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_12">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@@ -535,7 +586,16 @@
<bool>false</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_13">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
</layout>
@@ -622,7 +682,7 @@
<string>Add</string>
</property>
<property name="icon">
<iconset>
<iconset resource="../../../qad/libs/application/qad_application.qrc">
<normaloff>:/icons/list-add.png</normaloff>:/icons/list-add.png</iconset>
</property>
</widget>
@@ -636,7 +696,7 @@
<string>Modify</string>
</property>
<property name="icon">
<iconset resource="piconnedit/piconnedit.qrc">
<iconset>
<normaloff>:/icons/document-save-.png</normaloff>:/icons/document-save-.png</iconset>
</property>
</widget>
@@ -727,7 +787,7 @@
<string>Add</string>
</property>
<property name="icon">
<iconset>
<iconset resource="../../../qad/libs/application/qad_application.qrc">
<normaloff>:/icons/list-add.png</normaloff>:/icons/list-add.png</iconset>
</property>
</widget>
@@ -741,7 +801,7 @@
<string>Modify</string>
</property>
<property name="icon">
<iconset resource="piconnedit/piconnedit.qrc">
<iconset>
<normaloff>:/icons/document-save-.png</normaloff>:/icons/document-save-.png</iconset>
</property>
</widget>
@@ -764,7 +824,7 @@
<string>Remove</string>
</property>
<property name="icon">
<iconset>
<iconset resource="../../../qad/libs/application/qad_application.qrc">
<normaloff>:/icons/edit-delete.png</normaloff>:/icons/edit-delete.png</iconset>
</property>
</widget>
@@ -775,8 +835,8 @@
<string>Clear</string>
</property>
<property name="icon">
<iconset resource="piconnedit/piconnedit.qrc">
<normaloff>:/icons/edit-clear-.png</normaloff>:/icons/edit-clear-.png</iconset>
<iconset resource="../../../qad/libs/application/qad_application.qrc">
<normaloff>:/icons/edit-clear.png</normaloff>:/icons/edit-clear.png</iconset>
</property>
</widget>
</item>
@@ -840,7 +900,7 @@
</customwidget>
</customwidgets>
<resources>
<include location="piconnedit/piconnedit.qrc"/>
<include location="../../../qad/libs/application/qad_application.qrc"/>
</resources>
<connections>
<connection>
@@ -875,22 +935,6 @@
</hint>
</hints>
</connection>
<connection>
<sender>lineName</sender>
<signal>editingFinished()</signal>
<receiver>ConnectionEdit</receiver>
<slot>recreateConnection()</slot>
<hints>
<hint type="sourcelabel">
<x>644</x>
<y>29</y>
</hint>
<hint type="destinationlabel">
<x>662</x>
<y>-5</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>recreateConnection()</slot>

View File

@@ -74,7 +74,7 @@ void FilterItem::rename() {
piForeachC (PICodeInfo::EnumeratorInfo & i, ei->members)
if (i.value == mode()) {
ms = PI2QString(i.name);
piBreak;
break;
}
}
text_mode->setText(ms);

View File

@@ -22,13 +22,14 @@
#include "blockview.h"
#include "piconnection.h"
#include "piqt_utils_export.h"
const int __CV_Device = 1;
const int __CV_Filter = 2;
const int __CV_Sender = 3;
class DeviceItem: public BlockItem {
class PIQT_UTILS_EXPORT DeviceItem: public BlockItem {
public:
DeviceItem();
@@ -54,7 +55,7 @@ protected:
};
class FilterItem: public BlockItem {
class PIQT_UTILS_EXPORT FilterItem: public BlockItem {
public:
FilterItem();
@@ -84,7 +85,7 @@ protected:
};
class SenderItem: public BlockItem {
class PIQT_UTILS_EXPORT SenderItem: public BlockItem {
public:
SenderItem();
@@ -104,7 +105,7 @@ protected:
};
class ConnectionView: public BlockView {
class PIQT_UTILS_EXPORT ConnectionView: public BlockView {
Q_OBJECT
public:
explicit ConnectionView(QWidget * parent = 0);

View File

@@ -23,10 +23,11 @@
#include <QSyntaxHighlighter>
#include <QTextCursor>
#include <QTextCharFormat>
#include "piqt_utils_export.h"
class QTextDocument;
class ConfigHighlighter : public QSyntaxHighlighter
class PIQT_UTILS_EXPORT ConfigHighlighter : public QSyntaxHighlighter
{
Q_OBJECT
public:
@@ -37,7 +38,7 @@ public:
private:
void highlightBlock(const QString &text);
struct HighlightingRule {
struct PIQT_UTILS_EXPORT HighlightingRule {
QRegExp pattern;
QTextCharFormat format;
};

View File

@@ -22,13 +22,14 @@
#include <QWidget>
#include "qad_types.h"
#include "piqt_utils_export.h"
class QLineEdit;
class QToolButton;
class IODeviceEditDialog;
class IODeviceEdit: public QWidget {
class PIQT_UTILS_EXPORT IODeviceEdit: public QWidget {
Q_OBJECT
Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged)
Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly)
@@ -60,12 +61,14 @@ signals:
};
class __IODeviceEditRegistrator__ {
class PIQT_UTILS_EXPORT __IODeviceEditRegistrator__ {
public:
__IODeviceEditRegistrator__();
};
static __IODeviceEditRegistrator__ __iodeviceeditregistrator__;
void QAD_IODevice_toString(const QVariant & v, QString & r);
PIQT_UTILS_EXPORT void QAD_IODevice_toString(const QVariant & v, QString & r);
#endif // PIQT_IODEVICE_EDIT_H

View File

@@ -23,12 +23,13 @@
#include <QDialog>
#include "qad_types.h"
#include "propertystorage.h"
#include "piqt_utils_export.h"
namespace Ui {
class IODeviceEditDialog;
}
class IODeviceEditDialog: public QDialog {
class PIQT_UTILS_EXPORT IODeviceEditDialog: public QDialog {
Q_OBJECT
public:
explicit IODeviceEditDialog(QWidget * parent = 0);

View File

@@ -0,0 +1 @@
add_directories("piqt_")

View File

@@ -0,0 +1,14 @@
project(cd_pult)
if(APPLE)
set(APP_ICON "")
elseif(WIN32)
set(APP_ICON "")
else()
set(APP_ICON "")
endif()
set(APP_INFO "CD Pult")
piqt_application(${PROJECT_NAME} "Gui;Widgets" "qad_utils;qad_widgets;qad_graphic;qad_application;qcd_utils;piqt_utils")
if (Qt5_FOUND)
import_version(${PROJ_NAME}5 ${PROJECT_NAME})
deploy_target(${PROJECT_NAME}5 DEPLOY_DIR ${CMAKE_CURRENT_BINARY_DIR} DESTINATION ${ROOT_DIR}/release)
endif()

View File

@@ -1,312 +1,312 @@
#include "cddirectk.h"
#include "ui_cddirectk_type_dialog.h"
#include "cdutils_core.h"
#include "cdutils_k.h"
#include "qcd_core.h"
#include "qcd_model.h"
#include "graphic.h"
#include "piqt.h"
#include "qvariantedit.h"
#include <QFormLayout>
#include <QMimeData>
#include <QDragEnterEvent>
#include <QDragMoveEvent>
#include <QDropEvent>
#include <QMainWindow>
#include <QDockWidget>
#include <QInputDialog>
using namespace CDUtils;
KDockWidget::KDockWidget(QString title, QMainWindow * p): QDockWidget(title, p) {
da = p;
menu = new QMenu(this);
QAction * a = new QAction(QIcon(":/icons/document-edit.png"), "Rename ...", this);
connect(a, SIGNAL(triggered(bool)), this, SLOT(rename()));
dactions << a;
a = new QAction(QIcon(":/icons/edit-delete.png"), "Remove", this);
connect(a, SIGNAL(triggered(bool)), this, SIGNAL(removeRequest()));
dactions << a;
menu_k = new QMenu(this);
menu_k->setTitle(tr("Remove K"));
lay = new QFormLayout();
lay->setContentsMargins(0, qApp->style()->pixelMetric(QStyle::PM_LayoutTopMargin), 0, 0);
lay->setLabelAlignment(Qt::AlignRight | Qt::AlignVCenter);
QWidget * w = new QWidget();
w->setAcceptDrops(true);
w->installEventFilter(this);
w->setLayout(lay);
setWidget(w);
type_dialog = new CDDirectKTypeDialog();
}
void KDockWidget::addK(const CDType & t, CDDirectKTypeDialog::TypeInfo ti) {
if (t.cd_type() != CDType::cdK) return;
PIDeque<int> xp = t.path();
if (k_list.contains(xp)) return;
k_list << xp;
info_list << ti;
//piCout << "add" << xp;
QWidget * ve = ti.create();
//qDebug() << "add" << ve;
lay->addRow(PI2QString(t.pathString().join(".")) + ":", ve);
QCDCore::instance()->bindWidget(ve, t);
//ve->setValue();
}
QByteArray KDockWidget::save() const {
ChunkStream cs;
cs.add(1, windowTitle())
.add(2, getList(k_list))
.add(3, info_list);
return cs.data();
}
void KDockWidget::load(QByteArray ba) {
clear();
if (ba.isEmpty()) return;
ChunkStream cs(ba);
PIVector<PIDeque<int> > list;
QVector<CDDirectKTypeDialog::TypeInfo> ilist;
while (!cs.atEnd()) {
switch (cs.read()) {
case 1: setWindowTitle(cs.getData<QString>()); break;
case 2: list = setList(cs.getData<QStringList>()); break;
case 3: ilist = cs.getData<QVector<CDDirectKTypeDialog::TypeInfo> >(); break;
default: break;
}
}
ilist.resize(list.size());
for (int i = 0; i < list.size_s(); ++i) {
addK(K[list[i]], ilist[i]);
}
}
void KDockWidget::clear() {
while (lay->rowCount() > 0)
removeRow(0);
k_list.clear();
info_list.clear();
}
void KDockWidget::changedGlobal() {
//piCout << "changedGlobal ..." << k_list.size_s() << info_list.size() << lay->count() << lay->rowCount();
for (int i = 0; i < k_list.size_s(); ++i) {
//piCout << "update" << i << "0";
if (!K.exists(k_list[i])) {
k_list.remove(i);
info_list.remove(i);
removeRow(i);
--i;
continue;
}
//piCout << "update" << i << "1";
QLabel * lbl = qobject_cast<QLabel*>(lay->itemAt(i, QFormLayout::LabelRole)->widget());
//piCout << "update" << i << "2";
if (lbl) lbl->setText(PI2QString(K[k_list[i]].pathString().join(".")) + ":");
//piCout << "update" << i << "3";
}
//piCout << "changedGlobal ok";
}
bool KDockWidget::eventFilter(QObject * o, QEvent * e) {
//if (o == graphic->viewport()) {
switch (e->type()) {
case QEvent::DragMove: {
QDragMoveEvent * de = (QDragMoveEvent*)e;
const QMimeData * mime = de->mimeData();
if (!mime) break;
if (!mime->text().startsWith("k")) break;
de->setDropAction(Qt::CopyAction);
de->accept();
return true;
} break;
case QEvent::DragEnter: {
QDragEnterEvent * de = (QDragEnterEvent*)e;
const QMimeData * mime = de->mimeData();
if (!mime) break;
if (!mime->text().startsWith("k")) break;
de->setDropAction(Qt::CopyAction);
de->accept();
return true;
} break;
case QEvent::Drop: {
QDropEvent * de = (QDropEvent*)e;
const QMimeData * mime = de->mimeData();
if (!mime) break;
//qDebug() << "drop" << mime->text();
if (!mime->text().startsWith("k")) break;
CDDirectKTypeDialog::TypeInfo ti;
CDType & k(K[CDCore::stringToPath(Q2PIString(mime->text().mid(1)))]);
if (k.type().left(1) == "n" || k.type().left(1) == "f") {
if (type_dialog->exec() == QDialog::Accepted)
ti = type_dialog->getType();
else
return true;
}
addK(k, ti);
de->accept();
return true;
} break;
default: break;
}
//}
return QWidget::eventFilter(o, e);
}
void KDockWidget::contextMenuEvent(QContextMenuEvent * e) {
qDeleteAll(menu_k->actions());
menu_k->clear();
for (int i = 0; i < k_list.size_s(); ++i) {
QAction * a = new QAction(PI2QString(K[k_list[i]].pathString().join(".")), this);
a->setData(i);
connect(a, SIGNAL(triggered(bool)), this, SLOT(removeK()));
menu_k->addAction(a);
}
QMenu * mwm = da->createPopupMenu();
menu->clear();
menu->addActions(dactions);
menu->addMenu(menu_k);
menu->addSeparator();
menu->addActions(mwm->actions());
menu->popup(e->globalPos());
mwm->deleteLater();
}
void KDockWidget::removeRow(int r) {
if (r < 0 || r >= lay->rowCount()) return;
#if QT_VERSION >= 0x050800
QFormLayout::TakeRowResult rr = lay->takeRow(r);
if (rr.fieldItem) {delete rr.fieldItem->widget(); delete rr.fieldItem;}
if (rr.labelItem) {delete rr.labelItem->widget(); delete rr.labelItem;}
#else
piForTimes (2) {
QLayoutItem * i = lay->itemAt(r+r);
lay->removeItem(i);
if (i) {delete i->widget(); delete i;}
}
#endif
}
void KDockWidget::rename() {
QString nn = QInputDialog::getText(this, tr("Rename area"), tr("New area name:"),
QLineEdit::Normal, windowTitle());
if (nn.isEmpty()) return;
setWindowTitle(nn);
}
void KDockWidget::removeK() {
QAction * a = qobject_cast<QAction * >(sender());
if (!a) return;
int ind = a->data().toInt();
if (ind < 0 || ind >= k_list.size_s()) return;
k_list.remove(ind);
if (ind >= 0 && ind < info_list.size())
info_list.remove(ind);
removeRow(ind);
}
CDDirectK::CDDirectK(QWidget * parent) : QWidget(parent), Ui::CDDirectK() {
setupUi(this);
da = new QMainWindow();
da->setWindowFlags(frame->windowFlags());
da->setDockNestingEnabled(true);
layoutMain->addWidget(da);
}
CDDirectK::~CDDirectK() {
}
void CDDirectK::reset() {
qDeleteAll(docks);
docks.clear();
}
QByteArray CDDirectK::save() const {
ChunkStream cs;
QVector<QByteArray> dstates;
foreach (KDockWidget * d, docks) {
dstates << d->save();
}
cs.add(1, docks.size())
.add(2, dstates)
.add(3, da->saveState());
return cs.data();
}
void CDDirectK::load(QByteArray ba) {
reset();
if (ba.isEmpty()) return;
ChunkStream cs(ba);
while (!cs.atEnd()) {
switch (cs.read()) {
case 1: {
int s = cs.getData<int>();
piForTimes (s)
addArea();
} break;
case 2: {
QVector<QByteArray> dstates = cs.getData<QVector<QByteArray> >();
for (int i = 0; i < piMini(dstates.size(), docks.size()); ++i)
docks[i]->load(dstates[i]);
} break;
case 3: da->restoreState(cs.getData<QByteArray>()); break;
default: break;
}
}
}
void CDDirectK::addArea() {
KDockWidget * dw = new KDockWidget(QString("area %1").arg(docks.size()), da);
connect(dw, SIGNAL(removeRequest()), this, SLOT(removeArea()));
da->addDockWidget(Qt::RightDockWidgetArea, dw);
docks << dw;
for (int i = 0; i < docks.size(); ++i)
docks[i]->setObjectName(QString("dock_%1").arg(i));
}
void CDDirectK::changedGlobal() {
foreach (KDockWidget * d, docks)
d->changedGlobal();
}
void CDDirectK::removeArea() {
KDockWidget * d = qobject_cast<KDockWidget * >(sender());
if (!d) return;
docks.removeAll(d);
d->deleteLater();
for (int i = 0; i < docks.size(); ++i)
docks[i]->setObjectName(QString("dock_%1").arg(i));
}
void CDDirectK::on_buttonAdd_clicked() {
addArea();
}
void CDDirectK::on_buttonRemoveAll_clicked() {
qDeleteAll(docks);
docks.clear();
}
#include "cddirectk.h"
#include "ui_cddirectk_type_dialog.h"
#include "cdutils_core.h"
#include "cdutils_k.h"
#include "qcd_core.h"
#include "qcd_model.h"
#include "graphic.h"
#include "piqt.h"
#include "qvariantedit.h"
#include <QFormLayout>
#include <QMimeData>
#include <QDragEnterEvent>
#include <QDragMoveEvent>
#include <QDropEvent>
#include <QMainWindow>
#include <QDockWidget>
#include <QInputDialog>
using namespace CDUtils;
KDockWidget::KDockWidget(QString title, QMainWindow * p): QDockWidget(title, p) {
da = p;
menu = new QMenu(this);
QAction * a = new QAction(QIcon(":/icons/document-edit.png"), "Rename ...", this);
connect(a, SIGNAL(triggered(bool)), this, SLOT(rename()));
dactions << a;
a = new QAction(QIcon(":/icons/edit-delete.png"), "Remove", this);
connect(a, SIGNAL(triggered(bool)), this, SIGNAL(removeRequest()));
dactions << a;
menu_k = new QMenu(this);
menu_k->setTitle(tr("Remove K"));
lay = new QFormLayout();
lay->setContentsMargins(0, qApp->style()->pixelMetric(QStyle::PM_LayoutTopMargin), 0, 0);
lay->setLabelAlignment(Qt::AlignRight | Qt::AlignVCenter);
QWidget * w = new QWidget();
w->setAcceptDrops(true);
w->installEventFilter(this);
w->setLayout(lay);
setWidget(w);
type_dialog = new CDDirectKTypeDialog();
}
void KDockWidget::addK(const CDType & t, CDDirectKTypeDialog::TypeInfo ti) {
if (t.cd_type() != CDType::cdK) return;
PIDeque<int> xp = t.path();
if (k_list.contains(xp)) return;
k_list << xp;
info_list << ti;
//piCout << "add" << xp;
QWidget * ve = ti.create();
//qDebug() << "add" << ve;
lay->addRow(PI2QString(t.pathString().join(".")) + ":", ve);
QCDCore::instance()->bindWidget(ve, t);
//ve->setValue();
}
QByteArray KDockWidget::save() const {
ChunkStream cs;
cs.add(1, windowTitle())
.add(2, getList(k_list))
.add(3, info_list);
return cs.data();
}
void KDockWidget::load(QByteArray ba) {
clear();
if (ba.isEmpty()) return;
ChunkStream cs(ba);
PIVector<PIDeque<int> > list;
QVector<CDDirectKTypeDialog::TypeInfo> ilist;
while (!cs.atEnd()) {
switch (cs.read()) {
case 1: setWindowTitle(cs.getData<QString>()); break;
case 2: list = setList(cs.getData<QStringList>()); break;
case 3: ilist = cs.getData<QVector<CDDirectKTypeDialog::TypeInfo> >(); break;
default: break;
}
}
ilist.resize(list.size());
for (int i = 0; i < list.size_s(); ++i) {
addK(K[list[i]], ilist[i]);
}
}
void KDockWidget::clear() {
while (lay->rowCount() > 0)
removeRow(0);
k_list.clear();
info_list.clear();
}
void KDockWidget::changedGlobal() {
//piCout << "changedGlobal ..." << k_list.size_s() << info_list.size() << lay->count() << lay->rowCount();
for (int i = 0; i < k_list.size_s(); ++i) {
//piCout << "update" << i << "0";
if (!K.exists(k_list[i])) {
k_list.remove(i);
info_list.remove(i);
removeRow(i);
--i;
continue;
}
//piCout << "update" << i << "1";
QLabel * lbl = qobject_cast<QLabel*>(lay->itemAt(i, QFormLayout::LabelRole)->widget());
//piCout << "update" << i << "2";
if (lbl) lbl->setText(PI2QString(K[k_list[i]].pathString().join(".")) + ":");
//piCout << "update" << i << "3";
}
//piCout << "changedGlobal ok";
}
bool KDockWidget::eventFilter(QObject * o, QEvent * e) {
//if (o == graphic->viewport()) {
switch (e->type()) {
case QEvent::DragMove: {
QDragMoveEvent * de = (QDragMoveEvent*)e;
const QMimeData * mime = de->mimeData();
if (!mime) break;
if (!mime->text().startsWith("k")) break;
de->setDropAction(Qt::CopyAction);
de->accept();
return true;
} break;
case QEvent::DragEnter: {
QDragEnterEvent * de = (QDragEnterEvent*)e;
const QMimeData * mime = de->mimeData();
if (!mime) break;
if (!mime->text().startsWith("k")) break;
de->setDropAction(Qt::CopyAction);
de->accept();
return true;
} break;
case QEvent::Drop: {
QDropEvent * de = (QDropEvent*)e;
const QMimeData * mime = de->mimeData();
if (!mime) break;
//qDebug() << "drop" << mime->text();
if (!mime->text().startsWith("k")) break;
CDDirectKTypeDialog::TypeInfo ti;
CDType & k(K[CDCore::stringToPath(Q2PIString(mime->text().mid(1)))]);
if (k.type().left(1) == "n" || k.type().left(1) == "f") {
if (type_dialog->exec() == QDialog::Accepted)
ti = type_dialog->getType();
else
return true;
}
addK(k, ti);
de->accept();
return true;
} break;
default: break;
}
//}
return QWidget::eventFilter(o, e);
}
void KDockWidget::contextMenuEvent(QContextMenuEvent * e) {
qDeleteAll(menu_k->actions());
menu_k->clear();
for (int i = 0; i < k_list.size_s(); ++i) {
QAction * a = new QAction(PI2QString(K[k_list[i]].pathString().join(".")), this);
a->setData(i);
connect(a, SIGNAL(triggered(bool)), this, SLOT(removeK()));
menu_k->addAction(a);
}
QMenu * mwm = da->createPopupMenu();
menu->clear();
menu->addActions(dactions);
menu->addMenu(menu_k);
menu->addSeparator();
menu->addActions(mwm->actions());
menu->popup(e->globalPos());
mwm->deleteLater();
}
void KDockWidget::removeRow(int r) {
if (r < 0 || r >= lay->rowCount()) return;
#if QT_VERSION >= 0x050800
QFormLayout::TakeRowResult rr = lay->takeRow(r);
if (rr.fieldItem) {delete rr.fieldItem->widget(); delete rr.fieldItem;}
if (rr.labelItem) {delete rr.labelItem->widget(); delete rr.labelItem;}
#else
piForTimes (2) {
QLayoutItem * i = lay->itemAt(r+r);
lay->removeItem(i);
if (i) {delete i->widget(); delete i;}
}
#endif
}
void KDockWidget::rename() {
QString nn = QInputDialog::getText(this, tr("Rename area"), tr("New area name:"),
QLineEdit::Normal, windowTitle());
if (nn.isEmpty()) return;
setWindowTitle(nn);
}
void KDockWidget::removeK() {
QAction * a = qobject_cast<QAction * >(sender());
if (!a) return;
int ind = a->data().toInt();
if (ind < 0 || ind >= k_list.size_s()) return;
k_list.remove(ind);
if (ind >= 0 && ind < info_list.size())
info_list.remove(ind);
removeRow(ind);
}
CDDirectK::CDDirectK(QWidget * parent) : QWidget(parent), Ui::CDDirectK() {
setupUi(this);
da = new QMainWindow();
da->setWindowFlags(frame->windowFlags());
da->setDockNestingEnabled(true);
layoutMain->addWidget(da);
}
CDDirectK::~CDDirectK() {
}
void CDDirectK::reset() {
qDeleteAll(docks);
docks.clear();
}
QByteArray CDDirectK::save() const {
ChunkStream cs;
QVector<QByteArray> dstates;
foreach (KDockWidget * d, docks) {
dstates << d->save();
}
cs.add(1, docks.size())
.add(2, dstates)
.add(3, da->saveState());
return cs.data();
}
void CDDirectK::load(QByteArray ba) {
reset();
if (ba.isEmpty()) return;
ChunkStream cs(ba);
while (!cs.atEnd()) {
switch (cs.read()) {
case 1: {
int s = cs.getData<int>();
piForTimes (s)
addArea();
} break;
case 2: {
QVector<QByteArray> dstates = cs.getData<QVector<QByteArray> >();
for (int i = 0; i < piMini(dstates.size(), docks.size()); ++i)
docks[i]->load(dstates[i]);
} break;
case 3: da->restoreState(cs.getData<QByteArray>()); break;
default: break;
}
}
}
void CDDirectK::addArea() {
KDockWidget * dw = new KDockWidget(QString("area %1").arg(docks.size()), da);
connect(dw, SIGNAL(removeRequest()), this, SLOT(removeArea()));
da->addDockWidget(Qt::RightDockWidgetArea, dw);
docks << dw;
for (int i = 0; i < docks.size(); ++i)
docks[i]->setObjectName(QString("dock_%1").arg(i));
}
void CDDirectK::changedGlobal() {
foreach (KDockWidget * d, docks)
d->changedGlobal();
}
void CDDirectK::removeArea() {
KDockWidget * d = qobject_cast<KDockWidget * >(sender());
if (!d) return;
docks.removeAll(d);
d->deleteLater();
for (int i = 0; i < docks.size(); ++i)
docks[i]->setObjectName(QString("dock_%1").arg(i));
}
void CDDirectK::on_buttonAdd_clicked() {
addArea();
}
void CDDirectK::on_buttonRemoveAll_clicked() {
qDeleteAll(docks);
docks.clear();
}

View File

@@ -1,77 +1,77 @@
#ifndef CDDIRECTK_H
#define CDDIRECTK_H
#include "cdgraphics.h"
#include "ui_cddirectk.h"
#include "cddirectk_type_dialog.h"
class QFormLayout;
class KDockWidget: public QDockWidget {
Q_OBJECT
public:
KDockWidget(QString title = QString(), QMainWindow * p = 0);
void addK(const CDUtils::CDType & t, CDDirectKTypeDialog::TypeInfo ti);
QByteArray save() const;
void load(QByteArray ba);
void clear();
void changedGlobal();
QFormLayout * lay;
private:
bool eventFilter(QObject * o, QEvent * e);
void contextMenuEvent(QContextMenuEvent * e);
void removeRow(int r);
QMenu * menu, * menu_k;
QList<QAction*> dactions;
QMainWindow * da;
CDDirectKTypeDialog * type_dialog;
PIVector<PIDeque<int> > k_list;
QVector<CDDirectKTypeDialog::TypeInfo> info_list;
private slots:
void rename();
void removeK();
signals:
void removeRequest();
};
class CDDirectK: public QWidget, public Ui::CDDirectK
{
Q_OBJECT
public:
explicit CDDirectK(QWidget *parent = 0);
~CDDirectK();
void reset();
QByteArray save() const;
void load(QByteArray ba);
private:
void addArea();
QList<KDockWidget * > docks;
QMainWindow * da;
public slots:
void changedGlobal();
private slots:
void removeArea();
void on_buttonAdd_clicked();
void on_buttonRemoveAll_clicked();
signals:
};
#endif // CDDIRECTK_H
#ifndef CDDIRECTK_H
#define CDDIRECTK_H
#include "cdgraphics.h"
#include "ui_cddirectk.h"
#include "cddirectk_type_dialog.h"
class QFormLayout;
class KDockWidget: public QDockWidget {
Q_OBJECT
public:
KDockWidget(QString title = QString(), QMainWindow * p = 0);
void addK(const CDUtils::CDType & t, CDDirectKTypeDialog::TypeInfo ti);
QByteArray save() const;
void load(QByteArray ba);
void clear();
void changedGlobal();
QFormLayout * lay;
private:
bool eventFilter(QObject * o, QEvent * e);
void contextMenuEvent(QContextMenuEvent * e);
void removeRow(int r);
QMenu * menu, * menu_k;
QList<QAction*> dactions;
QMainWindow * da;
CDDirectKTypeDialog * type_dialog;
PIVector<PIDeque<int> > k_list;
QVector<CDDirectKTypeDialog::TypeInfo> info_list;
private slots:
void rename();
void removeK();
signals:
void removeRequest();
};
class CDDirectK: public QWidget, public Ui::CDDirectK
{
Q_OBJECT
public:
explicit CDDirectK(QWidget *parent = 0);
~CDDirectK();
void reset();
QByteArray save() const;
void load(QByteArray ba);
private:
void addArea();
QList<KDockWidget * > docks;
QMainWindow * da;
public slots:
void changedGlobal();
private slots:
void removeArea();
void on_buttonAdd_clicked();
void on_buttonRemoveAll_clicked();
signals:
};
#endif // CDDIRECTK_H

View File

@@ -1,85 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CDDirectK</class>
<widget class="QWidget" name="CDDirectK">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>624</width>
<height>411</height>
</rect>
</property>
<property name="windowTitle">
<string>CD Pult</string>
</property>
<layout class="QVBoxLayout" name="layoutMain" stretch="0">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="buttonAdd">
<property name="toolTip">
<string>Add new</string>
</property>
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/list-add.png</normaloff>:/icons/list-add.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonRemoveAll">
<property name="toolTip">
<string>Remove all</string>
</property>
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/edit-delete.png</normaloff>:/icons/edit-delete.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../qad/application/qad_application.qrc"/>
</resources>
<connections/>
</ui>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CDDirectK</class>
<widget class="QWidget" name="CDDirectK">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>624</width>
<height>411</height>
</rect>
</property>
<property name="windowTitle">
<string>CD Pult</string>
</property>
<layout class="QVBoxLayout" name="layoutMain" stretch="0">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="buttonAdd">
<property name="toolTip">
<string>Add new</string>
</property>
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/list-add.png</normaloff>:/icons/list-add.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonRemoveAll">
<property name="toolTip">
<string>Remove all</string>
</property>
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/edit-delete.png</normaloff>:/icons/edit-delete.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../qad/application/qad_application.qrc"/>
</resources>
<connections/>
</ui>

View File

@@ -1,76 +1,76 @@
#include "cddirectk_type_dialog.h"
#include "cdutils_core.h"
#include "qcd_core.h"
#include "qcd_model.h"
#include "piqt.h"
#include "spinslider.h"
#include "qvariantedit.h"
CDDirectKTypeDialog::CDDirectKTypeDialog(QWidget * parent) : QDialog(parent), Ui::CDDirectKTypeDialog() {
setupUi(this);
}
CDDirectKTypeDialog::~CDDirectKTypeDialog() {
}
CDDirectKTypeDialog::TypeInfo CDDirectKTypeDialog::getType() const {
if (!groupBox->isChecked()) return TypeInfo();
TypeInfo ret;
ret.type = comboType->currentIndex();
ret.params_d[0] = evalMin->value();
ret.params_d[1] = evalMax->value();
ret.params_d[2] = spinDecimals->value();
ret.params_d[3] = evalStep->value();
ret.params_s[0] = linePrefix->text();
ret.params_s[1] = lineSuffix->text();
return ret;
}
CDDirectKTypeDialog::TypeInfo::TypeInfo(int type_) {
type = type_;
params_d.resize(4);
params_s.resize(2);
}
QWidget * CDDirectKTypeDialog::TypeInfo::create() {
params_d.resize(4);
params_s.resize(2);
switch (type) {
case 0: {
QDoubleSpinBox * ret = new QDoubleSpinBox();
ret->setMinimum(params_d[0]);
ret->setMaximum(params_d[1]);
ret->setDecimals(params_d[2]);
ret->setSingleStep(params_d[3]);
ret->setPrefix(params_s[0]);
ret->setSuffix(params_s[1]);
return ret;
} break;
case 1: {
QSlider * ret = new QSlider(Qt::Horizontal);
ret->setMinimum(params_d[0]);
ret->setMaximum(params_d[1]);
ret->setSingleStep(params_d[3]);
return ret;
} break;
case 2: {
SpinSlider * ret = new SpinSlider();
ret->setMinimum(params_d[0]);
ret->setMaximum(params_d[1]);
ret->setDecimals(params_d[2]);
ret->setSingleStep(params_d[3]);
ret->setPrefix(params_s[0]);
ret->setSuffix(params_s[1]);
return ret;
} break;
default: break;
}
return new QVariantEdit();
}
#include "cddirectk_type_dialog.h"
#include "cdutils_core.h"
#include "qcd_core.h"
#include "qcd_model.h"
#include "piqt.h"
#include "spinslider.h"
#include "qvariantedit.h"
CDDirectKTypeDialog::CDDirectKTypeDialog(QWidget * parent) : QDialog(parent), Ui::CDDirectKTypeDialog() {
setupUi(this);
}
CDDirectKTypeDialog::~CDDirectKTypeDialog() {
}
CDDirectKTypeDialog::TypeInfo CDDirectKTypeDialog::getType() const {
if (!groupBox->isChecked()) return TypeInfo();
TypeInfo ret;
ret.type = comboType->currentIndex();
ret.params_d[0] = evalMin->value();
ret.params_d[1] = evalMax->value();
ret.params_d[2] = spinDecimals->value();
ret.params_d[3] = evalStep->value();
ret.params_s[0] = linePrefix->text();
ret.params_s[1] = lineSuffix->text();
return ret;
}
CDDirectKTypeDialog::TypeInfo::TypeInfo(int type_) {
type = type_;
params_d.resize(4);
params_s.resize(2);
}
QWidget * CDDirectKTypeDialog::TypeInfo::create() {
params_d.resize(4);
params_s.resize(2);
switch (type) {
case 0: {
QDoubleSpinBox * ret = new QDoubleSpinBox();
ret->setMinimum(params_d[0]);
ret->setMaximum(params_d[1]);
ret->setDecimals(params_d[2]);
ret->setSingleStep(params_d[3]);
ret->setPrefix(params_s[0]);
ret->setSuffix(params_s[1]);
return ret;
} break;
case 1: {
QSlider * ret = new QSlider(Qt::Horizontal);
ret->setMinimum(params_d[0]);
ret->setMaximum(params_d[1]);
ret->setSingleStep(params_d[3]);
return ret;
} break;
case 2: {
SpinSlider * ret = new SpinSlider();
ret->setMinimum(params_d[0]);
ret->setMaximum(params_d[1]);
ret->setDecimals(params_d[2]);
ret->setSingleStep(params_d[3]);
ret->setPrefix(params_s[0]);
ret->setSuffix(params_s[1]);
return ret;
} break;
default: break;
}
return new QVariantEdit();
}

View File

@@ -1,44 +1,44 @@
#ifndef CDDIRECTK_TYPE_DIALOG_H
#define CDDIRECTK_TYPE_DIALOG_H
#include <QDialog>
#include "ui_cddirectk_type_dialog.h"
class CDDirectKTypeDialog: public QDialog, public Ui::CDDirectKTypeDialog
{
Q_OBJECT
public:
explicit CDDirectKTypeDialog(QWidget * parent = 0);
~CDDirectKTypeDialog();
struct TypeInfo {
TypeInfo(int type_ = -1);
QWidget * create();
int type;
QVector<double> params_d;
QVector<QString> params_s;
};
TypeInfo getType() const;
private:
public slots:
private slots:
signals:
};
inline QDataStream & operator <<(QDataStream & s, const CDDirectKTypeDialog::TypeInfo & v) {
s << v.type << v.params_d << v.params_s;
return s;
}
inline QDataStream & operator >>(QDataStream & s, CDDirectKTypeDialog::TypeInfo & v) {
s >> v.type >> v.params_d >> v.params_s;
return s;
}
#endif // CDDIRECTK_TYPE_DIALOG_H
#ifndef CDDIRECTK_TYPE_DIALOG_H
#define CDDIRECTK_TYPE_DIALOG_H
#include <QDialog>
#include "ui_cddirectk_type_dialog.h"
class CDDirectKTypeDialog: public QDialog, public Ui::CDDirectKTypeDialog
{
Q_OBJECT
public:
explicit CDDirectKTypeDialog(QWidget * parent = 0);
~CDDirectKTypeDialog();
struct TypeInfo {
TypeInfo(int type_ = -1);
QWidget * create();
int type;
QVector<double> params_d;
QVector<QString> params_s;
};
TypeInfo getType() const;
private:
public slots:
private slots:
signals:
};
inline QDataStream & operator <<(QDataStream & s, const CDDirectKTypeDialog::TypeInfo & v) {
s << v.type << v.params_d << v.params_s;
return s;
}
inline QDataStream & operator >>(QDataStream & s, CDDirectKTypeDialog::TypeInfo & v) {
s >> v.type >> v.params_d >> v.params_s;
return s;
}
#endif // CDDIRECTK_TYPE_DIALOG_H

View File

@@ -1,232 +1,232 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CDDirectKTypeDialog</class>
<widget class="QDialog" name="CDDirectKTypeDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>275</width>
<height>310</height>
</rect>
</property>
<property name="windowTitle">
<string>CD Pult</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Custom</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<property name="labelAlignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Type:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboType">
<item>
<property name="text">
<string>Spin</string>
</property>
</item>
<item>
<property name="text">
<string>Slider</string>
</property>
</item>
<item>
<property name="text">
<string>SpinSlider</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Min:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="EvalSpinBox" name="evalMin"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Max:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="EvalSpinBox" name="evalMax">
<property name="value">
<double>100.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Decimals:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="spinDecimals"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Single step:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="EvalSpinBox" name="evalStep">
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Prefix:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="CLineEdit" name="linePrefix"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Suffix:</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="CLineEdit" name="lineSuffix"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>1</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>CLineEdit</class>
<extends>QLineEdit</extends>
<header>clineedit.h</header>
</customwidget>
<customwidget>
<class>EvalSpinBox</class>
<extends>QWidget</extends>
<header>evalspinbox.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>groupBox</sender>
<signal>toggled(bool)</signal>
<receiver>widget</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>86</x>
<y>49</y>
</hint>
<hint type="destinationlabel">
<x>94</x>
<y>91</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>CDDirectKTypeDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>297</x>
<y>285</y>
</hint>
<hint type="destinationlabel">
<x>315</x>
<y>280</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>CDDirectKTypeDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>281</x>
<y>290</y>
</hint>
<hint type="destinationlabel">
<x>283</x>
<y>307</y>
</hint>
</hints>
</connection>
</connections>
</ui>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CDDirectKTypeDialog</class>
<widget class="QDialog" name="CDDirectKTypeDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>275</width>
<height>310</height>
</rect>
</property>
<property name="windowTitle">
<string>CD Pult</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Custom</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<property name="labelAlignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Type:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboType">
<item>
<property name="text">
<string>Spin</string>
</property>
</item>
<item>
<property name="text">
<string>Slider</string>
</property>
</item>
<item>
<property name="text">
<string>SpinSlider</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Min:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="EvalSpinBox" name="evalMin"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Max:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="EvalSpinBox" name="evalMax">
<property name="value">
<double>100.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Decimals:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="spinDecimals"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Single step:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="EvalSpinBox" name="evalStep">
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Prefix:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="CLineEdit" name="linePrefix"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Suffix:</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="CLineEdit" name="lineSuffix"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>1</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>CLineEdit</class>
<extends>QLineEdit</extends>
<header>clineedit.h</header>
</customwidget>
<customwidget>
<class>EvalSpinBox</class>
<extends>QWidget</extends>
<header>evalspinbox.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>groupBox</sender>
<signal>toggled(bool)</signal>
<receiver>widget</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>86</x>
<y>49</y>
</hint>
<hint type="destinationlabel">
<x>94</x>
<y>91</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>CDDirectKTypeDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>297</x>
<y>285</y>
</hint>
<hint type="destinationlabel">
<x>315</x>
<y>280</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>CDDirectKTypeDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>281</x>
<y>290</y>
</hint>
<hint type="destinationlabel">
<x>283</x>
<y>307</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -1,354 +1,354 @@
#include "cdgraphics.h"
//#include "ui_qcd_graphic.h"
#include "cdutils_core.h"
#include "cdutils_x.h"
#include "qcd_core.h"
#include "qcd_model.h"
#include "qcd_graphic.h"
#include "graphic.h"
#include "piqt.h"
#include <QMimeData>
#include <QDragEnterEvent>
#include <QDragMoveEvent>
#include <QDropEvent>
#include <QMainWindow>
#include <QDockWidget>
#include <QInputDialog>
using namespace CDUtils;
QStringList CDUtils::getList(const PIVector<PIDeque<int> > & x_list) {
QStringList ret;
piForeachC (PIDeque<int> & p, x_list)
ret << PI2QString(CDCore::pathToString(p));
return ret;
}
PIVector<PIDeque<int> > CDUtils::setList(const QStringList & l) {
PIVector<PIDeque<int> > ret;
foreach (QString s, l)
ret << CDCore::stringToPath(Q2PIString(s));
return ret;
}
GDockWidget::GDockWidget(QString title, QMainWindow * p): QDockWidget(title, p) {
da = p;
menu = new QMenu(this);
QAction * a = new QAction(QIcon(":/icons/document-edit.png"), "Rename ...", this);
connect(a, SIGNAL(triggered(bool)), this, SLOT(rename()));
dactions << a;
a = new QAction(QIcon(":/icons/edit-delete.png"), "Remove", this);
connect(a, SIGNAL(triggered(bool)), this, SIGNAL(removeRequest()));
dactions << a;
menu_x = new QMenu(this);
menu_x->setTitle(tr("Remove X"));
graphic = new CDGraphicWidget();
graphic->graphic()->viewport()->setAcceptDrops(true);
graphic->graphic()->viewport()->installEventFilter(this);
setWidget(graphic);
}
void GDockWidget::addX(const CDType & t) {
if (t.cd_type() != CDType::cdX) return;
PIDeque<int> xp = t.path();
if (x_list.contains(xp)) return;
x_list << xp;
int gind = graphic->graphic()->graphicsCount();
graphic->graphic()->setGraphicsCount(gind + 1);
graphic->graphic()->setGraphicName(PI2QString(t.pathString().join(".")), gind);
}
void GDockWidget::drawX(const PIMap<PIString, PIVector<double> > & data) {
for (int i = 0; i < x_list.size_s(); ++i) {
PIString sp = CDCore::pathToString(x_list[i]);
const PIVector<double> & ch(data[sp]);
for (int j = 0; j < ch.size_s(); ++j)
graphic->graphic()->addPoint(ch[j], i, false);
}
graphic->graphic()->updateGraphics();
}
QByteArray GDockWidget::save() const {
ChunkStream cs;
cs.add(1, windowTitle())
.add(2, getList(x_list))
.add(3, graphic->graphic()->save())
.add(4, graphic->evalSpinBoxHistory()->expression())
.add(5, graphic->evalSpinBoxVisible()->expression());
return cs.data();
}
void GDockWidget::load(QByteArray ba) {
if (ba.isEmpty()) return;
ChunkStream cs(ba);
while (!cs.atEnd()) {
switch (cs.read()) {
case 1: setWindowTitle(cs.getData<QString>()); break;
case 2: x_list = setList(cs.getData<QStringList>()); break;
case 3: graphic->graphic()->load(cs.getData<QByteArray>()); break;
case 4: graphic->evalSpinBoxHistory()->setExpression(cs.getData<QString>()); break;
case 5: graphic->evalSpinBoxVisible()->setExpression(cs.getData<QString>()); break;
default: break;
}
}
}
void GDockWidget::changedGlobal() {
for (int i = 0; i < x_list.size_s(); ++i) {
if (!X.exists(x_list[i])) {
x_list.remove(i);
graphic->graphic()->removeGraphic(i);
--i;
continue;
}
graphic->graphic()->setGraphicName(PI2QString(X[x_list[i]].pathString().join(".")), i);
}
}
bool GDockWidget::eventFilter(QObject * o, QEvent * e) {
//if (o == graphic->viewport()) {
switch (e->type()) {
case QEvent::DragMove: {
QDragMoveEvent * de = (QDragMoveEvent*)e;
const QMimeData * mime = de->mimeData();
//qDebug() << "enter" << mime;
if (!mime) break;
if (!mime->text().startsWith("x")) break;
de->setDropAction(Qt::CopyAction);
de->accept();
return true;
} break;
case QEvent::DragEnter: {
QDragEnterEvent * de = (QDragEnterEvent*)e;
const QMimeData * mime = de->mimeData();
//qDebug() << "enter" << mime;
if (!mime) break;
if (!mime->text().startsWith("x")) break;
de->setDropAction(Qt::CopyAction);
de->accept();
return true;
} break;
case QEvent::Drop: {
QDropEvent * de = (QDropEvent*)e;
const QMimeData * mime = de->mimeData();
if (!mime) break;
//qDebug() << "drop" << mime->text();
if (!mime->text().startsWith("x")) break;
addX(X[CDCore::stringToPath(Q2PIString(mime->text().mid(1)))]);
de->accept();
return true;
} break;
default: break;
}
//}
return QWidget::eventFilter(o, e);
}
void GDockWidget::contextMenuEvent(QContextMenuEvent * e) {
if (graphic->graphic()->underMouse()) return;
qDeleteAll(menu_x->actions());
menu_x->clear();
for (int i = 0; i < graphic->graphic()->graphicsCount(); ++i) {
QPixmap icon(da->iconSize());
icon.fill(graphic->graphic()->graphic(i).pen.color());
QAction * a = new QAction(QIcon(icon), graphic->graphic()->graphic(i).name, this);
a->setData(i);
connect(a, SIGNAL(triggered(bool)), this, SLOT(removeX()));
menu_x->addAction(a);
}
QMenu * mwm = da->createPopupMenu();
menu->clear();
menu->addActions(dactions);
menu->addMenu(menu_x);
menu->addSeparator();
menu->addActions(mwm->actions());
menu->popup(e->globalPos());
mwm->deleteLater();
}
CDGraphicWidget * GDockWidget::viewportGraphic(QObject * o) const {
if (!o) return 0;
while (!qobject_cast<CDGraphicWidget*>(o) && o)
o = o->parent();
return qobject_cast<CDGraphicWidget*>(o);
}
void GDockWidget::rename() {
QString nn = QInputDialog::getText(this, tr("Rename area"), tr("New area name:"),
QLineEdit::Normal, windowTitle());
if (nn.isEmpty()) return;
setWindowTitle(nn);
}
void GDockWidget::removeX() {
QAction * a = qobject_cast<QAction * >(sender());
if (!a) return;
int ind = a->data().toInt();
if (ind < 0 || ind >= x_list.size_s()) return;
x_list.remove(ind);
graphic->graphic()->removeGraphic(ind);
}
CDGraphics::CDGraphics(QWidget * parent) : QWidget(parent), Ui::CDGraphics() {
setupUi(this);
da = new QMainWindow();
da->setWindowFlags(frame->windowFlags());
da->setDockNestingEnabled(true);
layoutMain->addWidget(da);
}
CDGraphics::~CDGraphics() {
}
void CDGraphics::reset() {
qDeleteAll(docks);
docks.clear();
}
QByteArray CDGraphics::save() const {
ChunkStream cs;
QVector<QByteArray> dstates;
foreach (GDockWidget * d, docks) {
dstates << d->save();
}
cs.add(1, docks.size())
.add(2, dstates)
.add(3, da->saveState());
X.lock();
cs.add(4, getList(X.enabledList()));
X.unlock();
cs.add(5, buttonConfigVisible->isChecked());
return cs.data();
}
void CDGraphics::load(QByteArray ba) {
reset();
if (ba.isEmpty()) return;
ChunkStream cs(ba);
while (!cs.atEnd()) {
switch (cs.read()) {
case 1: {
int s = cs.getData<int>();
piForTimes (s)
addGraphic();
} break;
case 2: {
QVector<QByteArray> dstates = cs.getData<QVector<QByteArray> >();
for (int i = 0; i < piMini(dstates.size(), docks.size()); ++i)
docks[i]->load(dstates[i]);
} break;
case 3: da->restoreState(cs.getData<QByteArray>()); break;
case 4:
X.lock();
X.setEnabledList(setList(cs.getData<QStringList>()));
X.unlock();
break;
case 5:
buttonConfigVisible->setChecked(cs.getData<bool>());
break;
default: break;
}
}
}
GDockWidget * CDGraphics::graphicDock(Graphic * o) const {
if (!o) return 0;
foreach (GDockWidget * d, docks)
if (d->widget() == o)
return d;
return 0;
}
void CDGraphics::addGraphic() {
GDockWidget * dw = new GDockWidget(QString("area %1").arg(docks.size()), da);
connect(dw, SIGNAL(removeRequest()), this, SLOT(removeGraphic()));
connect(buttonConfigVisible, SIGNAL(toggled(bool)), dw->graphic, SLOT(setConfigVisible(bool)));
connect(buttonLegendVisible, SIGNAL(clicked(bool)), dw->graphic->graphic(), SLOT(setLegendVisible(bool)));
connect(buttonBorderInputsVisible, SIGNAL(clicked(bool)), dw->graphic->graphic(), SLOT(setBorderInputsVisible(bool)));
connect(buttonPause, SIGNAL(clicked(bool)), dw->graphic->graphic(), SLOT(setPaused(bool)));
dw->graphic->setConfigVisible(buttonConfigVisible->isChecked());
dw->graphic->graphic()->setLegendVisible(buttonLegendVisible->isChecked());
dw->graphic->graphic()->setBorderInputsVisible(buttonBorderInputsVisible->isChecked());
da->addDockWidget(Qt::RightDockWidgetArea, dw);
docks << dw;
for (int i = 0; i < docks.size(); ++i)
docks[i]->setObjectName(QString("dock_%1").arg(i));
}
void CDGraphics::receivedX() {
PIMap<PIString, PIVector<double> > data;
X.lock();
PIVector<PIDeque<int> > x_list = X.enabledList();
PIVector<double> ch;
piForeachC (PIDeque<int> & p, x_list) {
CDType & t(X[p]);
if (t.xmode_rec() == CDType::X_Current)
ch.resize(1).fill(t.toDouble());
else
ch = t.history;
t.history.clear();
data[CDCore::pathToString(t.path())] = ch;
}
//piCout << data;
X.unlock();
foreach (GDockWidget * d, docks)
d->drawX(data);
}
void CDGraphics::changedGlobal() {
foreach (GDockWidget * d, docks)
d->changedGlobal();
}
void CDGraphics::removeGraphic() {
GDockWidget * d = qobject_cast<GDockWidget * >(sender());
if (!d) return;
docks.removeAll(d);
d->deleteLater();
for (int i = 0; i < docks.size(); ++i)
docks[i]->setObjectName(QString("dock_%1").arg(i));
}
void CDGraphics::on_buttonAdd_clicked() {
addGraphic();
}
void CDGraphics::on_buttonClear_clicked() {
foreach (GDockWidget * d, docks)
d->graphic->graphic()->clear();
}
void CDGraphics::on_buttonRemoveAll_clicked() {
qDeleteAll(docks);
docks.clear();
}
#include "cdgraphics.h"
//#include "ui_qcd_graphic.h"
#include "cdutils_core.h"
#include "cdutils_x.h"
#include "qcd_core.h"
#include "qcd_model.h"
#include "qcd_graphic.h"
#include "graphic.h"
#include "piqt.h"
#include <QMimeData>
#include <QDragEnterEvent>
#include <QDragMoveEvent>
#include <QDropEvent>
#include <QMainWindow>
#include <QDockWidget>
#include <QInputDialog>
using namespace CDUtils;
QStringList CDUtils::getList(const PIVector<PIDeque<int> > & x_list) {
QStringList ret;
piForeachC (PIDeque<int> & p, x_list)
ret << PI2QString(CDCore::pathToString(p));
return ret;
}
PIVector<PIDeque<int> > CDUtils::setList(const QStringList & l) {
PIVector<PIDeque<int> > ret;
foreach (QString s, l)
ret << CDCore::stringToPath(Q2PIString(s));
return ret;
}
GDockWidget::GDockWidget(QString title, QMainWindow * p): QDockWidget(title, p) {
da = p;
menu = new QMenu(this);
QAction * a = new QAction(QIcon(":/icons/document-edit.png"), "Rename ...", this);
connect(a, SIGNAL(triggered(bool)), this, SLOT(rename()));
dactions << a;
a = new QAction(QIcon(":/icons/edit-delete.png"), "Remove", this);
connect(a, SIGNAL(triggered(bool)), this, SIGNAL(removeRequest()));
dactions << a;
menu_x = new QMenu(this);
menu_x->setTitle(tr("Remove X"));
graphic = new CDGraphicWidget();
graphic->graphic()->viewport()->setAcceptDrops(true);
graphic->graphic()->viewport()->installEventFilter(this);
setWidget(graphic);
}
void GDockWidget::addX(const CDType & t) {
if (t.cd_type() != CDType::cdX) return;
PIDeque<int> xp = t.path();
if (x_list.contains(xp)) return;
x_list << xp;
int gind = graphic->graphic()->graphicsCount();
graphic->graphic()->setGraphicsCount(gind + 1);
graphic->graphic()->setGraphicName(PI2QString(t.pathString().join(".")), gind);
}
void GDockWidget::drawX(const PIMap<PIString, PIVector<double> > & data) {
for (int i = 0; i < x_list.size_s(); ++i) {
PIString sp = CDCore::pathToString(x_list[i]);
const PIVector<double> & ch(data[sp]);
for (int j = 0; j < ch.size_s(); ++j)
graphic->graphic()->addPoint(ch[j], i, false);
}
graphic->graphic()->updateGraphics();
}
QByteArray GDockWidget::save() const {
ChunkStream cs;
cs.add(1, windowTitle())
.add(2, getList(x_list))
.add(3, graphic->graphic()->save())
.add(4, graphic->evalSpinBoxHistory()->expression())
.add(5, graphic->evalSpinBoxVisible()->expression());
return cs.data();
}
void GDockWidget::load(QByteArray ba) {
if (ba.isEmpty()) return;
ChunkStream cs(ba);
while (!cs.atEnd()) {
switch (cs.read()) {
case 1: setWindowTitle(cs.getData<QString>()); break;
case 2: x_list = setList(cs.getData<QStringList>()); break;
case 3: graphic->graphic()->load(cs.getData<QByteArray>()); break;
case 4: graphic->evalSpinBoxHistory()->setExpression(cs.getData<QString>()); break;
case 5: graphic->evalSpinBoxVisible()->setExpression(cs.getData<QString>()); break;
default: break;
}
}
}
void GDockWidget::changedGlobal() {
for (int i = 0; i < x_list.size_s(); ++i) {
if (!X.exists(x_list[i])) {
x_list.remove(i);
graphic->graphic()->removeGraphic(i);
--i;
continue;
}
graphic->graphic()->setGraphicName(PI2QString(X[x_list[i]].pathString().join(".")), i);
}
}
bool GDockWidget::eventFilter(QObject * o, QEvent * e) {
//if (o == graphic->viewport()) {
switch (e->type()) {
case QEvent::DragMove: {
QDragMoveEvent * de = (QDragMoveEvent*)e;
const QMimeData * mime = de->mimeData();
//qDebug() << "enter" << mime;
if (!mime) break;
if (!mime->text().startsWith("x")) break;
de->setDropAction(Qt::CopyAction);
de->accept();
return true;
} break;
case QEvent::DragEnter: {
QDragEnterEvent * de = (QDragEnterEvent*)e;
const QMimeData * mime = de->mimeData();
//qDebug() << "enter" << mime;
if (!mime) break;
if (!mime->text().startsWith("x")) break;
de->setDropAction(Qt::CopyAction);
de->accept();
return true;
} break;
case QEvent::Drop: {
QDropEvent * de = (QDropEvent*)e;
const QMimeData * mime = de->mimeData();
if (!mime) break;
//qDebug() << "drop" << mime->text();
if (!mime->text().startsWith("x")) break;
addX(X[CDCore::stringToPath(Q2PIString(mime->text().mid(1)))]);
de->accept();
return true;
} break;
default: break;
}
//}
return QWidget::eventFilter(o, e);
}
void GDockWidget::contextMenuEvent(QContextMenuEvent * e) {
if (graphic->graphic()->underMouse()) return;
qDeleteAll(menu_x->actions());
menu_x->clear();
for (int i = 0; i < graphic->graphic()->graphicsCount(); ++i) {
QPixmap icon(da->iconSize());
icon.fill(graphic->graphic()->graphic(i).pen.color());
QAction * a = new QAction(QIcon(icon), graphic->graphic()->graphic(i).name, this);
a->setData(i);
connect(a, SIGNAL(triggered(bool)), this, SLOT(removeX()));
menu_x->addAction(a);
}
QMenu * mwm = da->createPopupMenu();
menu->clear();
menu->addActions(dactions);
menu->addMenu(menu_x);
menu->addSeparator();
menu->addActions(mwm->actions());
menu->popup(e->globalPos());
mwm->deleteLater();
}
CDGraphicWidget * GDockWidget::viewportGraphic(QObject * o) const {
if (!o) return 0;
while (!qobject_cast<CDGraphicWidget*>(o) && o)
o = o->parent();
return qobject_cast<CDGraphicWidget*>(o);
}
void GDockWidget::rename() {
QString nn = QInputDialog::getText(this, tr("Rename area"), tr("New area name:"),
QLineEdit::Normal, windowTitle());
if (nn.isEmpty()) return;
setWindowTitle(nn);
}
void GDockWidget::removeX() {
QAction * a = qobject_cast<QAction * >(sender());
if (!a) return;
int ind = a->data().toInt();
if (ind < 0 || ind >= x_list.size_s()) return;
x_list.remove(ind);
graphic->graphic()->removeGraphic(ind);
}
CDGraphics::CDGraphics(QWidget * parent) : QWidget(parent), Ui::CDGraphics() {
setupUi(this);
da = new QMainWindow();
da->setWindowFlags(frame->windowFlags());
da->setDockNestingEnabled(true);
layoutMain->addWidget(da);
}
CDGraphics::~CDGraphics() {
}
void CDGraphics::reset() {
qDeleteAll(docks);
docks.clear();
}
QByteArray CDGraphics::save() const {
ChunkStream cs;
QVector<QByteArray> dstates;
foreach (GDockWidget * d, docks) {
dstates << d->save();
}
cs.add(1, docks.size())
.add(2, dstates)
.add(3, da->saveState());
X.lock();
cs.add(4, getList(X.enabledList()));
X.unlock();
cs.add(5, buttonConfigVisible->isChecked());
return cs.data();
}
void CDGraphics::load(QByteArray ba) {
reset();
if (ba.isEmpty()) return;
ChunkStream cs(ba);
while (!cs.atEnd()) {
switch (cs.read()) {
case 1: {
int s = cs.getData<int>();
piForTimes (s)
addGraphic();
} break;
case 2: {
QVector<QByteArray> dstates = cs.getData<QVector<QByteArray> >();
for (int i = 0; i < piMini(dstates.size(), docks.size()); ++i)
docks[i]->load(dstates[i]);
} break;
case 3: da->restoreState(cs.getData<QByteArray>()); break;
case 4:
X.lock();
X.setEnabledList(setList(cs.getData<QStringList>()));
X.unlock();
break;
case 5:
buttonConfigVisible->setChecked(cs.getData<bool>());
break;
default: break;
}
}
}
GDockWidget * CDGraphics::graphicDock(Graphic * o) const {
if (!o) return 0;
foreach (GDockWidget * d, docks)
if (d->widget() == o)
return d;
return 0;
}
void CDGraphics::addGraphic() {
GDockWidget * dw = new GDockWidget(QString("area %1").arg(docks.size()), da);
connect(dw, SIGNAL(removeRequest()), this, SLOT(removeGraphic()));
connect(buttonConfigVisible, SIGNAL(toggled(bool)), dw->graphic, SLOT(setConfigVisible(bool)));
connect(buttonLegendVisible, SIGNAL(clicked(bool)), dw->graphic->graphic(), SLOT(setLegendVisible(bool)));
connect(buttonBorderInputsVisible, SIGNAL(clicked(bool)), dw->graphic->graphic(), SLOT(setBorderInputsVisible(bool)));
connect(buttonPause, SIGNAL(clicked(bool)), dw->graphic->graphic(), SLOT(setPaused(bool)));
dw->graphic->setConfigVisible(buttonConfigVisible->isChecked());
dw->graphic->graphic()->setLegendVisible(buttonLegendVisible->isChecked());
dw->graphic->graphic()->setBorderInputsVisible(buttonBorderInputsVisible->isChecked());
da->addDockWidget(Qt::RightDockWidgetArea, dw);
docks << dw;
for (int i = 0; i < docks.size(); ++i)
docks[i]->setObjectName(QString("dock_%1").arg(i));
}
void CDGraphics::receivedX() {
PIMap<PIString, PIVector<double> > data;
X.lock();
PIVector<PIDeque<int> > x_list = X.enabledList();
PIVector<double> ch;
piForeachC (PIDeque<int> & p, x_list) {
CDType & t(X[p]);
if (t.xmode_rec() == CDType::X_Current)
ch.resize(1).fill(t.toDouble());
else
ch = t.history;
t.history.clear();
data[CDCore::pathToString(t.path())] = ch;
}
//piCout << data;
X.unlock();
foreach (GDockWidget * d, docks)
d->drawX(data);
}
void CDGraphics::changedGlobal() {
foreach (GDockWidget * d, docks)
d->changedGlobal();
}
void CDGraphics::removeGraphic() {
GDockWidget * d = qobject_cast<GDockWidget * >(sender());
if (!d) return;
docks.removeAll(d);
d->deleteLater();
for (int i = 0; i < docks.size(); ++i)
docks[i]->setObjectName(QString("dock_%1").arg(i));
}
void CDGraphics::on_buttonAdd_clicked() {
addGraphic();
}
void CDGraphics::on_buttonClear_clicked() {
foreach (GDockWidget * d, docks)
d->graphic->graphic()->clear();
}
void CDGraphics::on_buttonRemoveAll_clicked() {
qDeleteAll(docks);
docks.clear();
}

View File

@@ -1,92 +1,92 @@
#ifndef CDGRAPHICS_H
#define CDGRAPHICS_H
#include <QWidget>
#include <QDockWidget>
#include <QMenu>
#include "ui_cdgraphics.h"
#include "qcd_graphic.h"
#include <pistring.h>
namespace CDUtils {
class CDType;
class CDSection;
QStringList getList(const PIVector<PIDeque<int> > & x_list);
PIVector<PIDeque<int> > setList(const QStringList & l);
}
class QMainWindow;
class Graphic;
class GDockWidget: public QDockWidget {
Q_OBJECT
public:
GDockWidget(QString title = QString(), QMainWindow * p = 0);
void addX(const CDUtils::CDType & t);
void drawX(const PIMap<PIString, PIVector<double> > & data);
QByteArray save() const;
void load(QByteArray ba);
void changedGlobal();
CDGraphicWidget * graphic;
private:
bool eventFilter(QObject * o, QEvent * e);
void contextMenuEvent(QContextMenuEvent * e);
CDGraphicWidget * viewportGraphic(QObject * o) const;
QMenu * menu, * menu_x;
QList<QAction*> dactions;
QMainWindow * da;
PIVector<PIDeque<int> > x_list;
private slots:
void rename();
void removeX();
signals:
void removeRequest();
};
class CDGraphics : public QWidget, public Ui::CDGraphics
{
Q_OBJECT
public:
explicit CDGraphics(QWidget *parent = 0);
~CDGraphics();
void reset();
QByteArray save() const;
void load(QByteArray ba);
private:
GDockWidget * graphicDock(Graphic * o) const;
void addXToGraphic(const QString & xp, Graphic * g);
void addGraphic();
QList<GDockWidget * > docks;
QMainWindow * da;
public slots:
void receivedX();
void changedGlobal();
private slots:
void removeGraphic();
void on_buttonAdd_clicked();
void on_buttonClear_clicked();
void on_buttonRemoveAll_clicked();
signals:
};
#endif // CDGRAPHICS_H
#ifndef CDGRAPHICS_H
#define CDGRAPHICS_H
#include <QWidget>
#include <QDockWidget>
#include <QMenu>
#include "ui_cdgraphics.h"
#include "qcd_graphic.h"
#include <pistring.h>
namespace CDUtils {
class CDType;
class CDSection;
QStringList getList(const PIVector<PIDeque<int> > & x_list);
PIVector<PIDeque<int> > setList(const QStringList & l);
}
class QMainWindow;
class Graphic;
class GDockWidget: public QDockWidget {
Q_OBJECT
public:
GDockWidget(QString title = QString(), QMainWindow * p = 0);
void addX(const CDUtils::CDType & t);
void drawX(const PIMap<PIString, PIVector<double> > & data);
QByteArray save() const;
void load(QByteArray ba);
void changedGlobal();
CDGraphicWidget * graphic;
private:
bool eventFilter(QObject * o, QEvent * e);
void contextMenuEvent(QContextMenuEvent * e);
CDGraphicWidget * viewportGraphic(QObject * o) const;
QMenu * menu, * menu_x;
QList<QAction*> dactions;
QMainWindow * da;
PIVector<PIDeque<int> > x_list;
private slots:
void rename();
void removeX();
signals:
void removeRequest();
};
class CDGraphics : public QWidget, public Ui::CDGraphics
{
Q_OBJECT
public:
explicit CDGraphics(QWidget *parent = 0);
~CDGraphics();
void reset();
QByteArray save() const;
void load(QByteArray ba);
private:
GDockWidget * graphicDock(Graphic * o) const;
void addXToGraphic(const QString & xp, Graphic * g);
void addGraphic();
QList<GDockWidget * > docks;
QMainWindow * da;
public slots:
void receivedX();
void changedGlobal();
private slots:
void removeGraphic();
void on_buttonAdd_clicked();
void on_buttonClear_clicked();
void on_buttonRemoveAll_clicked();
signals:
};
#endif // CDGRAPHICS_H

View File

@@ -1,168 +1,168 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CDGraphics</class>
<widget class="QWidget" name="CDGraphics">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>624</width>
<height>411</height>
</rect>
</property>
<property name="windowTitle">
<string>CD Pult</string>
</property>
<layout class="QVBoxLayout" name="layoutMain" stretch="0">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="buttonAdd">
<property name="toolTip">
<string>Add new</string>
</property>
<property name="icon">
<iconset resource="../../qad/utils/qad_utils.qrc">
<normaloff>:/icons/list-add.png</normaloff>:/icons/list-add.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonClear">
<property name="toolTip">
<string>Clear all</string>
</property>
<property name="icon">
<iconset resource="../../qad/utils/qad_utils.qrc">
<normaloff>:/icons/edit-clear.png</normaloff>:/icons/edit-clear.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonRemoveAll">
<property name="toolTip">
<string>Remove all</string>
</property>
<property name="icon">
<iconset resource="../../qad/utils/qad_utils.qrc">
<normaloff>:/icons/edit-delete.png</normaloff>:/icons/edit-delete.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonConfigVisible">
<property name="toolTip">
<string>Remove all</string>
</property>
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/layer-visible-off.png</normaloff>
<normalon>:/icons/layer-visible-on.png</normalon>:/icons/layer-visible-off.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonLegendVisible">
<property name="toolTip">
<string>Remove all</string>
</property>
<property name="icon">
<iconset resource="../../qad/widgets/qad_widgets.qrc">
<normaloff>:/icons/legend.png</normaloff>:/icons/legend.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonPause">
<property name="toolTip">
<string>Remove all</string>
</property>
<property name="icon">
<iconset resource="../../qad/graphic/qad_graphic.qrc">
<normaloff>:/icons/media-playback-pause.png</normaloff>:/icons/media-playback-pause.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonBorderInputsVisible">
<property name="toolTip">
<string>Remove all</string>
</property>
<property name="icon">
<iconset resource="../../qad/widgets/qad_widgets.qrc">
<normaloff>:/icons/border-line.png</normaloff>:/icons/border-line.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../qad/utils/qad_utils.qrc"/>
<include location="../../qad/widgets/qad_widgets.qrc"/>
<include location="../../qad/application/qad_application.qrc"/>
<include location="../../qad/graphic/qad_graphic.qrc"/>
</resources>
<connections/>
</ui>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CDGraphics</class>
<widget class="QWidget" name="CDGraphics">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>624</width>
<height>411</height>
</rect>
</property>
<property name="windowTitle">
<string>CD Pult</string>
</property>
<layout class="QVBoxLayout" name="layoutMain" stretch="0">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="buttonAdd">
<property name="toolTip">
<string>Add new</string>
</property>
<property name="icon">
<iconset resource="../../qad/utils/qad_utils.qrc">
<normaloff>:/icons/list-add.png</normaloff>:/icons/list-add.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonClear">
<property name="toolTip">
<string>Clear all</string>
</property>
<property name="icon">
<iconset resource="../../qad/utils/qad_utils.qrc">
<normaloff>:/icons/edit-clear.png</normaloff>:/icons/edit-clear.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonRemoveAll">
<property name="toolTip">
<string>Remove all</string>
</property>
<property name="icon">
<iconset resource="../../qad/utils/qad_utils.qrc">
<normaloff>:/icons/edit-delete.png</normaloff>:/icons/edit-delete.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonConfigVisible">
<property name="toolTip">
<string>Remove all</string>
</property>
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/layer-visible-off.png</normaloff>
<normalon>:/icons/layer-visible-on.png</normalon>:/icons/layer-visible-off.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonLegendVisible">
<property name="toolTip">
<string>Remove all</string>
</property>
<property name="icon">
<iconset resource="../../qad/widgets/qad_widgets.qrc">
<normaloff>:/icons/legend.png</normaloff>:/icons/legend.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonPause">
<property name="toolTip">
<string>Remove all</string>
</property>
<property name="icon">
<iconset resource="../../qad/graphic/qad_graphic.qrc">
<normaloff>:/icons/media-playback-pause.png</normaloff>:/icons/media-playback-pause.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonBorderInputsVisible">
<property name="toolTip">
<string>Remove all</string>
</property>
<property name="icon">
<iconset resource="../../qad/widgets/qad_widgets.qrc">
<normaloff>:/icons/border-line.png</normaloff>:/icons/border-line.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../qad/utils/qad_utils.qrc"/>
<include location="../../qad/widgets/qad_widgets.qrc"/>
<include location="../../qad/application/qad_application.qrc"/>
<include location="../../qad/graphic/qad_graphic.qrc"/>
</resources>
<connections/>
</ui>

View File

@@ -0,0 +1,16 @@
<RCC>
<qresource prefix="/">
<file>../../../qad/icons/dialog-information.png</file>
<file>../../../qad/icons/dialog-cancel.png</file>
<file>../../../qad/icons/dialog-ok-apply.png</file>
<file>../../../qad/icons/document-revert.png</file>
<file>../../../qad/icons/view-refresh.png</file>
<file>../../../qad/icons/format-stroke-color.png</file>
<file>icons/db-export.png</file>
<file>icons/db-import.png</file>
<file>icons/timer.png</file>
<file>icons/flame.png</file>
<file>icons/Apps-accessories-calculator-icon.png</file>
<file>icons/accessories-text-editor.png</file>
</qresource>
</RCC>

View File

@@ -1,292 +1,292 @@
#include "edockwidget.h"
#include "cdpultwindow.h"
#include "cdutils_core.h"
#include "cdutils_k.h"
#include "cdutils_x.h"
#include "cdutils_m.h"
#include "qcd_core.h"
#include "qcd_view.h"
#include "qcd_model.h"
#include "qcd_modedialog.h"
#include "chunkstream.h"
#include "qvariantedit.h"
#include "piqt.h"
#include "piqt_highlighter.h"
#include "qcodeedit.h"
#include <QFileDialog>
#include <QScrollBar>
#include <QImageReader>
#include <QMessageBox>
using namespace CDUtils;
CDPultWindow::CDPultWindow(QWidget *parent) : EMainWindow(parent), Ui::CDPultWindow() {
setupUi(this);
centralWidget()->hide();
setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
CDCore::instance()->initPult();
def_config = codeConfig->text();
checkDefaultConfig->setChecked(true);
new ConfigHighlighter(codeConfig->document());
widgetK->setType(CDUtils::CDType::cdK);
widgetX->setType(CDUtils::CDType::cdX);
widgetC->setType(CDUtils::CDType::cdC);
widgetM->setType(CDUtils::CDType::cdM);
editFileK->setValue(QVariant::fromValue(QAD::File("", "*.dat")));
editFileX->setValue(QVariant::fromValue(QAD::File("", "*.dat")));
editFileC->setValue(QVariant::fromValue(QAD::File("", "*.dat")));
editFileM->setValue(QVariant::fromValue(QAD::File("", "*.dat")));
log_icons[CDViewWidget::OKIcon] = QIcon(":/icons/dialog-ok-apply.png");
log_icons[CDViewWidget::FailIcon] = QIcon(":/icons/dialog-cancel.png");
log_icons[CDViewWidget::WaitIcon] = QIcon(":/icons/timer.png");
setRecentMenu(menuOpen_recent);
ribbon = new Ribbon(this);
session.setFile("session_cdpult.conf");
session.addEntry(this);
session.addEntry(ribbon->tabWidget());
session.load();
reset();
connect(widgetK, SIGNAL(addToLog(CDViewWidget::LogIcon,QString)), this, SLOT(addToLog(CDViewWidget::LogIcon,QString)));
connect(widgetX, SIGNAL(addToLog(CDViewWidget::LogIcon,QString)), this, SLOT(addToLog(CDViewWidget::LogIcon,QString)));
connect(widgetC, SIGNAL(addToLog(CDViewWidget::LogIcon,QString)), this, SLOT(addToLog(CDViewWidget::LogIcon,QString)));
connect(widgetM, SIGNAL(addToLog(CDViewWidget::LogIcon,QString)), this, SLOT(addToLog(CDViewWidget::LogIcon,QString)));
connect(widgetK->view, SIGNAL(changedGlobal()), widgetDirectK, SLOT(changedGlobal()));
connect(widgetX->view, SIGNAL(changedGlobal()), widgetGraphics, SLOT(changedGlobal()));
connect(widgetX->view, SIGNAL(receivedX()), widgetGraphics, SLOT(receivedX()));
connect(widgetM->view, SIGNAL(messageReceived(QString,int,QString)), this, SLOT(messageReceived(QString,int,QString)));
QCDCore::instance()->bindWidget(widgetK->view);
QCDCore::instance()->setDirectKEnabled(true);
X.start();
if (windowState() == Qt::WindowMinimized)
setWindowState(Qt::WindowNoState);
}
CDPultWindow::~CDPultWindow() {
}
void CDPultWindow::loadFile(const QString & fp) {
load(fp);
}
void CDPultWindow::apply(bool sessions) {
CDCore::instance()->stop();
widgetK->setFile(editFileK->value().value<QAD::File>().file);
widgetX->setFile(editFileX->value().value<QAD::File>().file);
widgetC->setFile(editFileC->value().value<QAD::File>().file);
widgetM->setFile(editFileM->value().value<QAD::File>().file);
if (checkDefaultConfig->isChecked())
CDCore::instance()->initPult();
else
CDCore::instance()->init(Q2PIString(codeConfig->text()), true);
widgetX->view->startX();
if (sessions) {
widgetGraphics->load(session_gr);
widgetDirectK->load(session_dk);
if (!session_mw.isEmpty())
restoreState(session_mw);
X.lock();
PIVector<PIDeque<int> > x_list = X.enabledList();
X.unlock();
piForeachC (PIDeque<int> & p, x_list)
X.enable(X[p]);
((CDItemModel*)widgetX->view->model())->updateModel();
widgetX->view->expandAll();
}
dockCDKView->setVisible(checkHasK->isChecked());
dockCDXView->setVisible(checkHasX->isChecked());
dockCDCView->setVisible(checkHasC->isChecked());
dockCDMView->setVisible(checkHasM->isChecked());
QMetaObject::invokeMethod(this, "changedDock", Qt::QueuedConnection);
}
void CDPultWindow::closeEvent(QCloseEvent *e) {
EMainWindow::closeEvent(e);
if (!e->isAccepted())
return;
QApplication::closeAllWindows();
session.save();
session.setFile(QString());
}
void CDPultWindow::reset(bool full) {
setWindowTitle(QString("CD Pult"));
widgetK->reset();
setChanged(false);
}
bool CDPultWindow::load(const QString & path) {
qApp->setOverrideCursor(Qt::WaitCursor);
QPIConfig conf(path, QIODevice::ReadOnly);
QAD::File f = editFileK->value().value<QAD::File>();
checkSyncFiles->setChecked(false);
editFileK->setValue(QVariant::fromValue(QAD::File(conf.getValue("file_k").toString(), f.filter)));
editFileX->setValue(QVariant::fromValue(QAD::File(conf.getValue("file_x").toString(), f.filter)));
editFileC->setValue(QVariant::fromValue(QAD::File(conf.getValue("file_c").toString(), f.filter)));
editFileM->setValue(QVariant::fromValue(QAD::File(conf.getValue("file_m").toString(), f.filter)));
checkSyncFiles->setChecked(conf.getValue("sync_files").toBool());
lineSessionName->setText(conf.getValue("session_name").toString());
last_icon = conf.getValue("icon_path").toString();
setAppIcon(conf.getValue("icon").toByteArray());
checkHasK->setChecked(conf.getValue("has_k").toBool());
checkHasX->setChecked(conf.getValue("has_x").toBool());
checkHasC->setChecked(conf.getValue("has_c").toBool());
checkHasM->setChecked(conf.getValue("has_m").toBool());
checkDefaultConfig->setChecked(conf.getValue("default_config").toBool());
codeConfig->setText(QByteArray2QString(conf.getValue("config").toByteArray()));
if (codeConfig->text().isEmpty())
codeConfig->setText(def_config);
session_gr = conf.getValue("session_gr").toByteArray();
session_dk = conf.getValue("session_dk").toByteArray();
session_mw = conf.getValue("session_mw").toByteArray();
setChanged(false);
file_name = path;
apply(true);
qApp->restoreOverrideCursor();
return true;
}
bool CDPultWindow::save(const QString & path) {
session_gr = widgetGraphics->save();
session_dk = widgetDirectK->save();
session_mw = saveState();
QPIConfig conf(path, QIODevice::ReadWrite);
conf.clear();
conf.setValue("file_k", editFileK->value().value<QAD::File>().file);
conf.setValue("file_x", editFileX->value().value<QAD::File>().file);
conf.setValue("file_c", editFileC->value().value<QAD::File>().file);
conf.setValue("file_m", editFileM->value().value<QAD::File>().file);
conf.setValue("sync_files", checkSyncFiles->isChecked());
conf.setValue("session_name", lineSessionName->text());
conf.setValue("icon_path", last_icon);
conf.setValue("icon", appIcon());
conf.setValue("has_k", checkHasK->isChecked());
conf.setValue("has_x", checkHasX->isChecked());
conf.setValue("has_c", checkHasC->isChecked());
conf.setValue("has_m", checkHasM->isChecked());
conf.setValue("default_config", checkDefaultConfig->isChecked());
conf.setValue("config", QString2QByteArray(codeConfig->text()));
conf.setValue("session_gr", session_gr);
conf.setValue("session_dk", session_dk);
conf.setValue("session_mw", session_mw);
file_name = path;
return true;
//widgetK->setFile(path);
//widgetK->save();
}
void CDPultWindow::loadingSession(QPIConfig & conf) {
setRecentFiles(conf.getValue("recent files").toStringList());
}
void CDPultWindow::savingSession(QPIConfig & conf) {
conf.setValue("recent files", recentFiles());
}
QByteArray CDPultWindow::appIcon() const {
QByteArray ret;
if (icon.isNull()) return ret;
QBuffer buff(&ret);
buff.open(QIODevice::WriteOnly);
icon.save(&buff, "png");
//qDebug() << "s" << ret.size();
return ret;
}
void CDPultWindow::setAppIcon(QByteArray ba) {
if (ba.isEmpty()) {
icon = QImage();
setWindowIcon(QIcon());
return;
}
//qDebug() << "l" << ba.size();
icon = QImage::fromData(ba);
setWindowIcon(QIcon(QPixmap::fromImage(icon)));
//qDebug() << QApplication::windowIcon().availableSizes();
}
void CDPultWindow::addToLog(CDViewWidget::LogIcon icon, const QString & msg) {
QListWidgetItem * ni = new QListWidgetItem(log_icons[icon], "(" + QTime::currentTime().toString() + ") " + msg);
bool s = listLog->verticalScrollBar()->value() == listLog->verticalScrollBar()->maximum();
listLog->addItem(ni);
if (s) listLog->scrollToBottom();
}
void CDPultWindow::messageReceived(QString path, int type, QString msg) {
MessageType mt = (MessageType)type;
const CDType & t(M.root()[CDCore::stringToPath(Q2PIString(path))]);
if (t.cd_type() != CDType::cdM) return;
if (mt == MessageBox)
QMessageBox::information(this, windowTitle(), QString("[%1]\n%2").arg(PI2QString(t.name()), msg));
}
void CDPultWindow::on_editFileK_valueChanged(const QVariant & p) {
if (!checkSyncFiles->isChecked()) return;
QFileInfo fi(p.value<QAD::File>().file);
if (fi.path().isEmpty()) return;
QString n = fi.baseName();
QString xn(n), cn(n), mn(n);
if (n.contains("k")) {
xn.replace(n.indexOf("k"), 1, "x");
cn.replace(n.indexOf("k"), 1, "c");
mn.replace(n.indexOf("k"), 1, "m");
} else {
xn += "_x";
cn += "_c";
mn += "_m";
}
QString ext = fi.suffix(), dot, dir;
QString kfn(fi.filePath());
if (!ext.isEmpty()) {
kfn.chop(ext.size());
if (kfn.endsWith(".")) {
kfn.chop(1);
dot = ".";
}
}
if (!fi.path().isEmpty() && fi.path() != ".") {
dir = fi.path();
if (!dir.endsWith("/"))
dir += "/";
}
QAD::File f = editFileK->value().value<QAD::File>();
f.file = dir + xn + dot + ext; editFileX->setValue(QVariant::fromValue(f));
f.file = dir + cn + dot + ext; editFileC->setValue(QVariant::fromValue(f));
f.file = dir + mn + dot + ext; editFileM->setValue(QVariant::fromValue(f));
}
void CDPultWindow::on_buttonSessionApply_clicked() {
apply(false);
}
void CDPultWindow::on_lineSessionName_textChanged(const QString & t) {
setWindowTitle(QString("CD Pult - %1").arg(t));
}
void CDPultWindow::on_buttonIcon_clicked() {
QList<QByteArray> ifl = QImageReader::supportedImageFormats();
QStringList sfl; foreach (QByteArray s, ifl) sfl << ("*." + QString(s).toLower());
QString f = QFileDialog::getOpenFileName(this, tr("Select icon"), last_icon, tr("Images") + " (" + sfl.join(" ") + ")");
if (f.isEmpty()) return;
last_icon = f;
icon = QImage(last_icon);
setWindowIcon(QIcon(QPixmap::fromImage(icon)));
}
#include "edockwidget.h"
#include "cdpultwindow.h"
#include "cdutils_core.h"
#include "cdutils_k.h"
#include "cdutils_x.h"
#include "cdutils_m.h"
#include "qcd_core.h"
#include "qcd_view.h"
#include "qcd_model.h"
#include "qcd_modedialog.h"
#include "chunkstream.h"
#include "qvariantedit.h"
#include "piqt.h"
#include "piqt_highlighter.h"
#include "qcodeedit.h"
#include <QFileDialog>
#include <QScrollBar>
#include <QImageReader>
#include <QMessageBox>
using namespace CDUtils;
CDPultWindow::CDPultWindow(QWidget *parent) : EMainWindow(parent), Ui::CDPultWindow() {
setupUi(this);
centralWidget()->hide();
setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
CDCore::instance()->initPult();
def_config = codeConfig->text();
checkDefaultConfig->setChecked(true);
new ConfigHighlighter(codeConfig->document());
widgetK->setType(CDUtils::CDType::cdK);
widgetX->setType(CDUtils::CDType::cdX);
widgetC->setType(CDUtils::CDType::cdC);
widgetM->setType(CDUtils::CDType::cdM);
editFileK->setValue(QVariant::fromValue(QAD::File("", "*.dat")));
editFileX->setValue(QVariant::fromValue(QAD::File("", "*.dat")));
editFileC->setValue(QVariant::fromValue(QAD::File("", "*.dat")));
editFileM->setValue(QVariant::fromValue(QAD::File("", "*.dat")));
log_icons[CDViewWidget::OKIcon] = QIcon(":/icons/dialog-ok-apply.png");
log_icons[CDViewWidget::FailIcon] = QIcon(":/icons/dialog-cancel.png");
log_icons[CDViewWidget::WaitIcon] = QIcon(":/icons/timer.png");
setRecentMenu(menuOpen_recent);
ribbon = new Ribbon(this);
session.setFile("session_cdpult.conf");
session.addEntry(this);
session.addEntry(ribbon->tabWidget());
session.load();
reset();
connect(widgetK, SIGNAL(addToLog(CDViewWidget::LogIcon,QString)), this, SLOT(addToLog(CDViewWidget::LogIcon,QString)));
connect(widgetX, SIGNAL(addToLog(CDViewWidget::LogIcon,QString)), this, SLOT(addToLog(CDViewWidget::LogIcon,QString)));
connect(widgetC, SIGNAL(addToLog(CDViewWidget::LogIcon,QString)), this, SLOT(addToLog(CDViewWidget::LogIcon,QString)));
connect(widgetM, SIGNAL(addToLog(CDViewWidget::LogIcon,QString)), this, SLOT(addToLog(CDViewWidget::LogIcon,QString)));
connect(widgetK->view, SIGNAL(changedGlobal()), widgetDirectK, SLOT(changedGlobal()));
connect(widgetX->view, SIGNAL(changedGlobal()), widgetGraphics, SLOT(changedGlobal()));
connect(widgetX->view, SIGNAL(receivedX()), widgetGraphics, SLOT(receivedX()));
connect(widgetM->view, SIGNAL(messageReceived(QString,int,QString)), this, SLOT(messageReceived(QString,int,QString)));
QCDCore::instance()->bindWidget(widgetK->view);
QCDCore::instance()->setDirectKEnabled(true);
X.start();
if (windowState() == Qt::WindowMinimized)
setWindowState(Qt::WindowNoState);
}
CDPultWindow::~CDPultWindow() {
}
void CDPultWindow::loadFile(const QString & fp) {
load(fp);
}
void CDPultWindow::apply(bool sessions) {
CDCore::instance()->stop();
widgetK->setFile(editFileK->value().value<QAD::File>().file);
widgetX->setFile(editFileX->value().value<QAD::File>().file);
widgetC->setFile(editFileC->value().value<QAD::File>().file);
widgetM->setFile(editFileM->value().value<QAD::File>().file);
if (checkDefaultConfig->isChecked())
CDCore::instance()->initPult();
else
CDCore::instance()->init(Q2PIString(codeConfig->text()), true);
widgetX->view->startX();
if (sessions) {
widgetGraphics->load(session_gr);
widgetDirectK->load(session_dk);
if (!session_mw.isEmpty())
restoreState(session_mw);
X.lock();
PIVector<PIDeque<int> > x_list = X.enabledList();
X.unlock();
piForeachC (PIDeque<int> & p, x_list)
X.enable(X[p]);
((CDItemModel*)widgetX->view->model())->updateModel();
widgetX->view->expandAll();
}
dockCDKView->setVisible(checkHasK->isChecked());
dockCDXView->setVisible(checkHasX->isChecked());
dockCDCView->setVisible(checkHasC->isChecked());
dockCDMView->setVisible(checkHasM->isChecked());
QMetaObject::invokeMethod(this, "changedDock", Qt::QueuedConnection);
}
void CDPultWindow::closeEvent(QCloseEvent *e) {
EMainWindow::closeEvent(e);
if (!e->isAccepted())
return;
QApplication::closeAllWindows();
session.save();
session.setFile(QString());
}
void CDPultWindow::reset(bool full) {
setWindowTitle(QString("CD Pult"));
widgetK->reset();
setChanged(false);
}
bool CDPultWindow::load(const QString & path) {
qApp->setOverrideCursor(Qt::WaitCursor);
QPIConfig conf(path, QIODevice::ReadOnly);
QAD::File f = editFileK->value().value<QAD::File>();
checkSyncFiles->setChecked(false);
editFileK->setValue(QVariant::fromValue(QAD::File(conf.getValue("file_k").toString(), f.filter)));
editFileX->setValue(QVariant::fromValue(QAD::File(conf.getValue("file_x").toString(), f.filter)));
editFileC->setValue(QVariant::fromValue(QAD::File(conf.getValue("file_c").toString(), f.filter)));
editFileM->setValue(QVariant::fromValue(QAD::File(conf.getValue("file_m").toString(), f.filter)));
checkSyncFiles->setChecked(conf.getValue("sync_files").toBool());
lineSessionName->setText(conf.getValue("session_name").toString());
last_icon = conf.getValue("icon_path").toString();
setAppIcon(conf.getValue("icon").toByteArray());
checkHasK->setChecked(conf.getValue("has_k").toBool());
checkHasX->setChecked(conf.getValue("has_x").toBool());
checkHasC->setChecked(conf.getValue("has_c").toBool());
checkHasM->setChecked(conf.getValue("has_m").toBool());
checkDefaultConfig->setChecked(conf.getValue("default_config").toBool());
codeConfig->setText(QByteArray2QString(conf.getValue("config").toByteArray()));
if (codeConfig->text().isEmpty())
codeConfig->setText(def_config);
session_gr = conf.getValue("session_gr").toByteArray();
session_dk = conf.getValue("session_dk").toByteArray();
session_mw = conf.getValue("session_mw").toByteArray();
setChanged(false);
file_name = path;
apply(true);
qApp->restoreOverrideCursor();
return true;
}
bool CDPultWindow::save(const QString & path) {
session_gr = widgetGraphics->save();
session_dk = widgetDirectK->save();
session_mw = saveState();
QPIConfig conf(path, QIODevice::ReadWrite);
conf.clear();
conf.setValue("file_k", editFileK->value().value<QAD::File>().file);
conf.setValue("file_x", editFileX->value().value<QAD::File>().file);
conf.setValue("file_c", editFileC->value().value<QAD::File>().file);
conf.setValue("file_m", editFileM->value().value<QAD::File>().file);
conf.setValue("sync_files", checkSyncFiles->isChecked());
conf.setValue("session_name", lineSessionName->text());
conf.setValue("icon_path", last_icon);
conf.setValue("icon", appIcon());
conf.setValue("has_k", checkHasK->isChecked());
conf.setValue("has_x", checkHasX->isChecked());
conf.setValue("has_c", checkHasC->isChecked());
conf.setValue("has_m", checkHasM->isChecked());
conf.setValue("default_config", checkDefaultConfig->isChecked());
conf.setValue("config", QString2QByteArray(codeConfig->text()));
conf.setValue("session_gr", session_gr);
conf.setValue("session_dk", session_dk);
conf.setValue("session_mw", session_mw);
file_name = path;
return true;
//widgetK->setFile(path);
//widgetK->save();
}
void CDPultWindow::loadingSession(QPIConfig & conf) {
setRecentFiles(conf.getValue("recent files").toStringList());
}
void CDPultWindow::savingSession(QPIConfig & conf) {
conf.setValue("recent files", recentFiles());
}
QByteArray CDPultWindow::appIcon() const {
QByteArray ret;
if (icon.isNull()) return ret;
QBuffer buff(&ret);
buff.open(QIODevice::WriteOnly);
icon.save(&buff, "png");
//qDebug() << "s" << ret.size();
return ret;
}
void CDPultWindow::setAppIcon(QByteArray ba) {
if (ba.isEmpty()) {
icon = QImage();
setWindowIcon(QIcon());
return;
}
//qDebug() << "l" << ba.size();
icon = QImage::fromData(ba);
setWindowIcon(QIcon(QPixmap::fromImage(icon)));
//qDebug() << QApplication::windowIcon().availableSizes();
}
void CDPultWindow::addToLog(CDViewWidget::LogIcon icon, const QString & msg) {
QListWidgetItem * ni = new QListWidgetItem(log_icons[icon], "(" + QTime::currentTime().toString() + ") " + msg);
bool s = listLog->verticalScrollBar()->value() == listLog->verticalScrollBar()->maximum();
listLog->addItem(ni);
if (s) listLog->scrollToBottom();
}
void CDPultWindow::messageReceived(QString path, int type, QString msg) {
MessageType mt = (MessageType)type;
const CDType & t(M.root()[CDCore::stringToPath(Q2PIString(path))]);
if (t.cd_type() != CDType::cdM) return;
if (mt == MessageBox)
QMessageBox::information(this, windowTitle(), QString("[%1]\n%2").arg(PI2QString(t.name()), msg));
}
void CDPultWindow::on_editFileK_valueChanged(const QVariant & p) {
if (!checkSyncFiles->isChecked()) return;
QFileInfo fi(p.value<QAD::File>().file);
if (fi.path().isEmpty()) return;
QString n = fi.baseName();
QString xn(n), cn(n), mn(n);
if (n.contains("k")) {
xn.replace(n.indexOf("k"), 1, "x");
cn.replace(n.indexOf("k"), 1, "c");
mn.replace(n.indexOf("k"), 1, "m");
} else {
xn += "_x";
cn += "_c";
mn += "_m";
}
QString ext = fi.suffix(), dot, dir;
QString kfn(fi.filePath());
if (!ext.isEmpty()) {
kfn.chop(ext.size());
if (kfn.endsWith(".")) {
kfn.chop(1);
dot = ".";
}
}
if (!fi.path().isEmpty() && fi.path() != ".") {
dir = fi.path();
if (!dir.endsWith("/"))
dir += "/";
}
QAD::File f = editFileK->value().value<QAD::File>();
f.file = dir + xn + dot + ext; editFileX->setValue(QVariant::fromValue(f));
f.file = dir + cn + dot + ext; editFileC->setValue(QVariant::fromValue(f));
f.file = dir + mn + dot + ext; editFileM->setValue(QVariant::fromValue(f));
}
void CDPultWindow::on_buttonSessionApply_clicked() {
apply(false);
}
void CDPultWindow::on_lineSessionName_textChanged(const QString & t) {
setWindowTitle(QString("CD Pult - %1").arg(t));
}
void CDPultWindow::on_buttonIcon_clicked() {
QList<QByteArray> ifl = QImageReader::supportedImageFormats();
QStringList sfl; foreach (QByteArray s, ifl) sfl << ("*." + QString(s).toLower());
QString f = QFileDialog::getOpenFileName(this, tr("Select icon"), last_icon, tr("Images") + " (" + sfl.join(" ") + ")");
if (f.isEmpty()) return;
last_icon = f;
icon = QImage(last_icon);
setWindowIcon(QIcon(QPixmap::fromImage(icon)));
}

View File

@@ -1,53 +1,53 @@
#ifndef CDPULTWINDOW_H
#define CDPULTWINDOW_H
#include "emainwindow.h"
#include "ui_cdpultwindow.h"
#include "cdviewwidget.h"
#include "ribbon.h"
#include "piobject.h"
class CDPultWindow : public EMainWindow, public Ui::CDPultWindow
{
Q_OBJECT
Q_ENUMS(LogIcon)
public:
explicit CDPultWindow(QWidget *parent = 0);
~CDPultWindow();
void loadFile(const QString & fp);
void apply(bool sessions);
private:
void closeEvent(QCloseEvent *);
void reset(bool full = false);
bool load(const QString & path);
bool save(const QString & path);
QString loadFilter() {return "Pult session(*.conf)";}
QString saveFilter() {return loadFilter();}
void loadingSession(QPIConfig & conf);
void savingSession(QPIConfig & conf);
QByteArray appIcon() const;
void setAppIcon(QByteArray ba);
Ribbon * ribbon;
QMap<CDViewWidget::LogIcon, QIcon> log_icons;
QByteArray session_gr, session_dk, session_mw;
QString def_config, last_icon;
QImage icon;
private slots:
void addToLog(CDViewWidget::LogIcon icon, const QString & msg);
void messageReceived(QString path, int type, QString msg);
void on_editFileK_valueChanged(const QVariant & p);
void on_buttonSessionApply_clicked();
void on_lineSessionName_textChanged(const QString & t);
void on_buttonIcon_clicked();
};
#endif // CDPULTWINDOW_H
#ifndef CDPULTWINDOW_H
#define CDPULTWINDOW_H
#include "emainwindow.h"
#include "ui_cdpultwindow.h"
#include "cdviewwidget.h"
#include "ribbon.h"
#include "piobject.h"
class CDPultWindow : public EMainWindow, public Ui::CDPultWindow
{
Q_OBJECT
Q_ENUMS(LogIcon)
public:
explicit CDPultWindow(QWidget *parent = 0);
~CDPultWindow();
void loadFile(const QString & fp);
void apply(bool sessions);
private:
void closeEvent(QCloseEvent *);
void reset(bool full = false);
bool load(const QString & path);
bool save(const QString & path);
QString loadFilter() {return "Pult session(*.conf)";}
QString saveFilter() {return loadFilter();}
void loadingSession(QPIConfig & conf);
void savingSession(QPIConfig & conf);
QByteArray appIcon() const;
void setAppIcon(QByteArray ba);
Ribbon * ribbon;
QMap<CDViewWidget::LogIcon, QIcon> log_icons;
QByteArray session_gr, session_dk, session_mw;
QString def_config, last_icon;
QImage icon;
private slots:
void addToLog(CDViewWidget::LogIcon icon, const QString & msg);
void messageReceived(QString path, int type, QString msg);
void on_editFileK_valueChanged(const QVariant & p);
void on_buttonSessionApply_clicked();
void on_lineSessionName_textChanged(const QString & t);
void on_buttonIcon_clicked();
};
#endif // CDPULTWINDOW_H

View File

@@ -1,612 +1,612 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CDPultWindow</class>
<widget class="EMainWindow" name="CDPultWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>798</width>
<height>593</height>
</rect>
</property>
<property name="windowTitle">
<string>CD Pult</string>
</property>
<property name="dockNestingEnabled">
<bool>true</bool>
</property>
<property name="dockOptions">
<set>QMainWindow::AllowNestedDocks|QMainWindow::AllowTabbedDocks|QMainWindow::AnimatedDocks</set>
</property>
<widget class="QWidget" name="central"/>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>798</width>
<height>24</height>
</rect>
</property>
<widget class="QMenu" name="menuMain">
<property name="title">
<string>Main</string>
</property>
<widget class="QMenu" name="menuOpen_recent">
<property name="title">
<string>Open recent</string>
</property>
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/document-open-recent.png</normaloff>:/icons/document-open-recent.png</iconset>
</property>
</widget>
<addaction name="actionOpen"/>
<addaction name="menuOpen_recent"/>
<addaction name="actionSave"/>
<addaction name="actionSaveAs"/>
</widget>
<addaction name="menuMain"/>
</widget>
<widget class="EDockWidget" name="dockCDKView">
<property name="windowIcon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/document-edit.png</normaloff>:/icons/document-edit.png</iconset>
</property>
<property name="windowTitle">
<string>K</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="CDViewWidget" name="widgetK" native="true"/>
</item>
</layout>
</widget>
</widget>
<widget class="EDockWidget" name="dockLog">
<property name="windowIcon">
<iconset resource="cdpult.qrc">
<normaloff>:/icons/dialog-information.png</normaloff>:/icons/dialog-information.png</iconset>
</property>
<property name="windowTitle">
<string>Log</string>
</property>
<attribute name="dockWidgetArea">
<number>8</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_2">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QListWidget" name="listLog">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="EDockWidget" name="dockCDXView">
<property name="windowIcon">
<iconset resource="../../qad/widgets/qad_widgets.qrc">
<normaloff>:/icons/qvariantedit.png</normaloff>:/icons/qvariantedit.png</iconset>
</property>
<property name="windowTitle">
<string>X</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_3">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="CDViewWidget" name="widgetX" native="true"/>
</item>
</layout>
</widget>
</widget>
<widget class="EDockWidget" name="dockSession">
<property name="windowIcon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/configure.png</normaloff>:/icons/configure.png</iconset>
</property>
<property name="windowTitle">
<string>Session</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_4">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QPushButton" name="buttonSessionApply">
<property name="text">
<string>Apply</string>
</property>
<property name="icon">
<iconset resource="../../qad/widgets/qad_widgets.qrc">
<normaloff>:/icons/dialog-ok-apply.png</normaloff>:/icons/dialog-ok-apply.png</iconset>
</property>
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<property name="labelAlignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="CLineEdit" name="lineSessionName"/>
</item>
<item>
<widget class="QPushButton" name="buttonIcon">
<property name="toolTip">
<string>Select icon...</string>
</property>
<property name="icon">
<iconset resource="../../qad/blockview/qad_blockview.qrc">
<normaloff>:/icons/view-preview.png</normaloff>:/icons/view-preview.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>K file:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QVariantEdit" name="editFileK"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>X file:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QVariantEdit" name="editFileX"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>C file:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QVariantEdit" name="editFileC"/>
</item>
<item row="5" column="0" colspan="2">
<widget class="QCheckBox" name="checkSyncFiles">
<property name="text">
<string>Sync files</string>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QCheckBox" name="checkHasK">
<property name="text">
<string>K</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkHasX">
<property name="text">
<string>X</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkHasC">
<property name="text">
<string>C</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkHasM">
<property name="text">
<string>M</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="7" column="0" colspan="2">
<widget class="QCheckBox" name="checkDefaultConfig">
<property name="text">
<string>Default config</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>M file:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QVariantEdit" name="editFileM"/>
</item>
</layout>
</item>
<item>
<widget class="QCodeEdit" name="codeConfig">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>include = ip.conf
[connection]
device.cd = eth://udp:${ip.pult}:27002:${ip.app}:27001 #s
[]
</string>
</property>
<property name="editorFont">
<font>
<family>DejaVu Sans Mono</family>
<pointsize>9</pointsize>
</font>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="EDockWidget" name="dockCDCView">
<property name="windowIcon">
<iconset resource="../../qad/blockview/qad_blockview.qrc">
<normaloff>:/icons/legend.png</normaloff>:/icons/legend.png</iconset>
</property>
<property name="windowTitle">
<string>C</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_5">
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="CDViewWidget" name="widgetC" native="true"/>
</item>
</layout>
</widget>
</widget>
<widget class="EDockWidget" name="dockGraphics">
<property name="windowIcon">
<iconset resource="../../qad/blockview/qad_blockview.qrc">
<normaloff>:/icons/format-stroke-color.png</normaloff>:/icons/format-stroke-color.png</iconset>
</property>
<property name="windowTitle">
<string>Graphics</string>
</property>
<attribute name="dockWidgetArea">
<number>8</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_6">
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="CDGraphics" name="widgetGraphics" native="true"/>
</item>
</layout>
</widget>
</widget>
<widget class="EDockWidget" name="dockDirectK">
<property name="windowIcon">
<iconset resource="../../qad/widgets/qad_widgets.qrc">
<normaloff>:/icons/tools-wizard.png</normaloff>:/icons/tools-wizard.png</iconset>
</property>
<property name="windowTitle">
<string>Direct K</string>
</property>
<attribute name="dockWidgetArea">
<number>8</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_7">
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="CDDirectK" name="widgetDirectK" native="true"/>
</item>
</layout>
</widget>
</widget>
<widget class="EDockWidget" name="dockCDMView">
<property name="windowIcon">
<iconset resource="cdpult.qrc">
<normaloff>:/icons/accessories-text-editor.png</normaloff>:/icons/accessories-text-editor.png</iconset>
</property>
<property name="windowTitle">
<string>M</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_8">
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="CDViewWidget" name="widgetM" native="true"/>
</item>
</layout>
</widget>
</widget>
<action name="actionOpen">
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/document-open.png</normaloff>:/icons/document-open.png</iconset>
</property>
<property name="text">
<string>Open...</string>
</property>
<property name="shortcut">
<string>Ctrl+O</string>
</property>
</action>
<action name="actionSave">
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/document-save.png</normaloff>:/icons/document-save.png</iconset>
</property>
<property name="text">
<string>Save</string>
</property>
<property name="shortcut">
<string>Ctrl+S</string>
</property>
</action>
<action name="actionSaveAs">
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/document-save-as.png</normaloff>:/icons/document-save-as.png</iconset>
</property>
<property name="text">
<string>Save As...</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+S</string>
</property>
</action>
<addaction name="actionOpen"/>
<addaction name="actionSave"/>
<addaction name="actionSaveAs"/>
<addaction name="menuMain"/>
<addaction name="menuOpen_recent"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
</widget>
<customwidgets>
<customwidget>
<class>EMainWindow</class>
<extends>QMainWindow</extends>
<header>emainwindow.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>CLineEdit</class>
<extends>QLineEdit</extends>
<header>clineedit.h</header>
</customwidget>
<customwidget>
<class>QCodeEdit</class>
<extends>QWidget</extends>
<header>qcodeedit.h</header>
</customwidget>
<customwidget>
<class>QVariantEdit</class>
<extends>QWidget</extends>
<header>qvariantedit.h</header>
</customwidget>
<customwidget>
<class>EDockWidget</class>
<extends>QDockWidget</extends>
<header>edockwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>CDViewWidget</class>
<extends>QWidget</extends>
<header>cdviewwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>CDGraphics</class>
<extends>QWidget</extends>
<header>cdgraphics.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>CDDirectK</class>
<extends>QWidget</extends>
<header>cddirectk.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../../qad/application/qad_application.qrc"/>
<include location="../../qad/blockview/qad_blockview.qrc"/>
<include location="../../qad/widgets/qad_widgets.qrc"/>
<include location="cdpult.qrc"/>
</resources>
<connections>
<connection>
<sender>actionSave</sender>
<signal>triggered()</signal>
<receiver>CDPultWindow</receiver>
<slot>saveFile()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>399</x>
<y>299</y>
</hint>
</hints>
</connection>
<connection>
<sender>actionSaveAs</sender>
<signal>triggered()</signal>
<receiver>CDPultWindow</receiver>
<slot>saveAsFile()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>399</x>
<y>299</y>
</hint>
</hints>
</connection>
<connection>
<sender>actionOpen</sender>
<signal>triggered()</signal>
<receiver>CDPultWindow</receiver>
<slot>openFile()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>399</x>
<y>299</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkSyncFiles</sender>
<signal>toggled(bool)</signal>
<receiver>editFileX</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>786</x>
<y>220</y>
</hint>
<hint type="destinationlabel">
<x>786</x>
<y>151</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkSyncFiles</sender>
<signal>toggled(bool)</signal>
<receiver>editFileC</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>786</x>
<y>220</y>
</hint>
<hint type="destinationlabel">
<x>786</x>
<y>172</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkDefaultConfig</sender>
<signal>toggled(bool)</signal>
<receiver>codeConfig</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>786</x>
<y>276</y>
</hint>
<hint type="destinationlabel">
<x>581</x>
<y>304</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkSyncFiles</sender>
<signal>toggled(bool)</signal>
<receiver>editFileM</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>767</x>
<y>205</y>
</hint>
<hint type="destinationlabel">
<x>767</x>
<y>187</y>
</hint>
</hints>
</connection>
</connections>
</ui>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CDPultWindow</class>
<widget class="EMainWindow" name="CDPultWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>798</width>
<height>593</height>
</rect>
</property>
<property name="windowTitle">
<string>CD Pult</string>
</property>
<property name="dockNestingEnabled">
<bool>true</bool>
</property>
<property name="dockOptions">
<set>QMainWindow::AllowNestedDocks|QMainWindow::AllowTabbedDocks|QMainWindow::AnimatedDocks</set>
</property>
<widget class="QWidget" name="central"/>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>798</width>
<height>24</height>
</rect>
</property>
<widget class="QMenu" name="menuMain">
<property name="title">
<string>Main</string>
</property>
<widget class="QMenu" name="menuOpen_recent">
<property name="title">
<string>Open recent</string>
</property>
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/document-open-recent.png</normaloff>:/icons/document-open-recent.png</iconset>
</property>
</widget>
<addaction name="actionOpen"/>
<addaction name="menuOpen_recent"/>
<addaction name="actionSave"/>
<addaction name="actionSaveAs"/>
</widget>
<addaction name="menuMain"/>
</widget>
<widget class="EDockWidget" name="dockCDKView">
<property name="windowIcon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/document-edit.png</normaloff>:/icons/document-edit.png</iconset>
</property>
<property name="windowTitle">
<string>K</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="CDViewWidget" name="widgetK" native="true"/>
</item>
</layout>
</widget>
</widget>
<widget class="EDockWidget" name="dockLog">
<property name="windowIcon">
<iconset resource="cdpult.qrc">
<normaloff>:/icons/dialog-information.png</normaloff>:/icons/dialog-information.png</iconset>
</property>
<property name="windowTitle">
<string>Log</string>
</property>
<attribute name="dockWidgetArea">
<number>8</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_2">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QListWidget" name="listLog">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="EDockWidget" name="dockCDXView">
<property name="windowIcon">
<iconset resource="../../qad/widgets/qad_widgets.qrc">
<normaloff>:/icons/qvariantedit.png</normaloff>:/icons/qvariantedit.png</iconset>
</property>
<property name="windowTitle">
<string>X</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_3">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="CDViewWidget" name="widgetX" native="true"/>
</item>
</layout>
</widget>
</widget>
<widget class="EDockWidget" name="dockSession">
<property name="windowIcon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/configure.png</normaloff>:/icons/configure.png</iconset>
</property>
<property name="windowTitle">
<string>Session</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_4">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QPushButton" name="buttonSessionApply">
<property name="text">
<string>Apply</string>
</property>
<property name="icon">
<iconset resource="../../qad/widgets/qad_widgets.qrc">
<normaloff>:/icons/dialog-ok-apply.png</normaloff>:/icons/dialog-ok-apply.png</iconset>
</property>
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<property name="labelAlignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="CLineEdit" name="lineSessionName"/>
</item>
<item>
<widget class="QPushButton" name="buttonIcon">
<property name="toolTip">
<string>Select icon...</string>
</property>
<property name="icon">
<iconset resource="../../qad/blockview/qad_blockview.qrc">
<normaloff>:/icons/view-preview.png</normaloff>:/icons/view-preview.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>K file:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QVariantEdit" name="editFileK"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>X file:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QVariantEdit" name="editFileX"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>C file:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QVariantEdit" name="editFileC"/>
</item>
<item row="5" column="0" colspan="2">
<widget class="QCheckBox" name="checkSyncFiles">
<property name="text">
<string>Sync files</string>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QCheckBox" name="checkHasK">
<property name="text">
<string>K</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkHasX">
<property name="text">
<string>X</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkHasC">
<property name="text">
<string>C</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkHasM">
<property name="text">
<string>M</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="7" column="0" colspan="2">
<widget class="QCheckBox" name="checkDefaultConfig">
<property name="text">
<string>Default config</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>M file:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QVariantEdit" name="editFileM"/>
</item>
</layout>
</item>
<item>
<widget class="QCodeEdit" name="codeConfig">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>include = ip.conf
[connection]
device.cd = eth://udp:${ip.pult}:27002:${ip.app}:27001 #s
[]
</string>
</property>
<property name="editorFont">
<font>
<family>DejaVu Sans Mono</family>
<pointsize>9</pointsize>
</font>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="EDockWidget" name="dockCDCView">
<property name="windowIcon">
<iconset resource="../../qad/blockview/qad_blockview.qrc">
<normaloff>:/icons/legend.png</normaloff>:/icons/legend.png</iconset>
</property>
<property name="windowTitle">
<string>C</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_5">
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="CDViewWidget" name="widgetC" native="true"/>
</item>
</layout>
</widget>
</widget>
<widget class="EDockWidget" name="dockGraphics">
<property name="windowIcon">
<iconset resource="../../qad/blockview/qad_blockview.qrc">
<normaloff>:/icons/format-stroke-color.png</normaloff>:/icons/format-stroke-color.png</iconset>
</property>
<property name="windowTitle">
<string>Graphics</string>
</property>
<attribute name="dockWidgetArea">
<number>8</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_6">
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="CDGraphics" name="widgetGraphics" native="true"/>
</item>
</layout>
</widget>
</widget>
<widget class="EDockWidget" name="dockDirectK">
<property name="windowIcon">
<iconset resource="../../qad/widgets/qad_widgets.qrc">
<normaloff>:/icons/tools-wizard.png</normaloff>:/icons/tools-wizard.png</iconset>
</property>
<property name="windowTitle">
<string>Direct K</string>
</property>
<attribute name="dockWidgetArea">
<number>8</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_7">
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="CDDirectK" name="widgetDirectK" native="true"/>
</item>
</layout>
</widget>
</widget>
<widget class="EDockWidget" name="dockCDMView">
<property name="windowIcon">
<iconset resource="cdpult.qrc">
<normaloff>:/icons/accessories-text-editor.png</normaloff>:/icons/accessories-text-editor.png</iconset>
</property>
<property name="windowTitle">
<string>M</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_8">
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="CDViewWidget" name="widgetM" native="true"/>
</item>
</layout>
</widget>
</widget>
<action name="actionOpen">
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/document-open.png</normaloff>:/icons/document-open.png</iconset>
</property>
<property name="text">
<string>Open...</string>
</property>
<property name="shortcut">
<string>Ctrl+O</string>
</property>
</action>
<action name="actionSave">
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/document-save.png</normaloff>:/icons/document-save.png</iconset>
</property>
<property name="text">
<string>Save</string>
</property>
<property name="shortcut">
<string>Ctrl+S</string>
</property>
</action>
<action name="actionSaveAs">
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/document-save-as.png</normaloff>:/icons/document-save-as.png</iconset>
</property>
<property name="text">
<string>Save As...</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+S</string>
</property>
</action>
<addaction name="actionOpen"/>
<addaction name="actionSave"/>
<addaction name="actionSaveAs"/>
<addaction name="menuMain"/>
<addaction name="menuOpen_recent"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
</widget>
<customwidgets>
<customwidget>
<class>EMainWindow</class>
<extends>QMainWindow</extends>
<header>emainwindow.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>CLineEdit</class>
<extends>QLineEdit</extends>
<header>clineedit.h</header>
</customwidget>
<customwidget>
<class>QCodeEdit</class>
<extends>QWidget</extends>
<header>qcodeedit.h</header>
</customwidget>
<customwidget>
<class>QVariantEdit</class>
<extends>QWidget</extends>
<header>qvariantedit.h</header>
</customwidget>
<customwidget>
<class>EDockWidget</class>
<extends>QDockWidget</extends>
<header>edockwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>CDViewWidget</class>
<extends>QWidget</extends>
<header>cdviewwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>CDGraphics</class>
<extends>QWidget</extends>
<header>cdgraphics.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>CDDirectK</class>
<extends>QWidget</extends>
<header>cddirectk.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../../qad/application/qad_application.qrc"/>
<include location="../../qad/blockview/qad_blockview.qrc"/>
<include location="../../qad/widgets/qad_widgets.qrc"/>
<include location="cdpult.qrc"/>
</resources>
<connections>
<connection>
<sender>actionSave</sender>
<signal>triggered()</signal>
<receiver>CDPultWindow</receiver>
<slot>saveFile()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>399</x>
<y>299</y>
</hint>
</hints>
</connection>
<connection>
<sender>actionSaveAs</sender>
<signal>triggered()</signal>
<receiver>CDPultWindow</receiver>
<slot>saveAsFile()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>399</x>
<y>299</y>
</hint>
</hints>
</connection>
<connection>
<sender>actionOpen</sender>
<signal>triggered()</signal>
<receiver>CDPultWindow</receiver>
<slot>openFile()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>399</x>
<y>299</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkSyncFiles</sender>
<signal>toggled(bool)</signal>
<receiver>editFileX</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>786</x>
<y>220</y>
</hint>
<hint type="destinationlabel">
<x>786</x>
<y>151</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkSyncFiles</sender>
<signal>toggled(bool)</signal>
<receiver>editFileC</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>786</x>
<y>220</y>
</hint>
<hint type="destinationlabel">
<x>786</x>
<y>172</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkDefaultConfig</sender>
<signal>toggled(bool)</signal>
<receiver>codeConfig</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>786</x>
<y>276</y>
</hint>
<hint type="destinationlabel">
<x>581</x>
<y>304</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkSyncFiles</sender>
<signal>toggled(bool)</signal>
<receiver>editFileM</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>767</x>
<y>205</y>
</hint>
<hint type="destinationlabel">
<x>767</x>
<y>187</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -1,78 +1,78 @@
#include "cdviewwidget.h"
#include "cdutils_core.h"
#include "qcd_core.h"
#include "qcd_model.h"
#include "qcd_modedialog.h"
#include "qvariantedit.h"
#include <QFileDialog>
CDViewWidget::CDViewWidget(QWidget * parent) : QWidget(parent), Ui::CDViewWidget() {
qRegisterMetaType<CDViewWidget::LogIcon>("CDViewWidget::LogIcon");
setupUi(this);
connect(view, SIGNAL(sendSucceed()), this, SLOT(sended()));
connect(view, SIGNAL(receiveSucceed()), this, SLOT(received()));
connect(view, SIGNAL(sendFailed()), this, SLOT(sendFailed()));
connect(view, SIGNAL(receiveFailed()), this, SLOT(receiveFailed()));
}
CDViewWidget::~CDViewWidget() {
}
void CDViewWidget::reset() {
setFile("");
}
void CDViewWidget::setType(int t) {
view->setType((CDUtils::CDType::cdT)t);
tl_u = view->typeLetter().toUpper();
tl_l = view->typeLetter().toLower();
view->refresh();
}
void CDViewWidget::setFile(const QString & f) {
view->setFile(f);
view->load();
}
void CDViewWidget::on_buttonSend_clicked() {
if (view->inProgress()) {addToLog(WaitIcon, "processing..."); return;}
addToLog(WaitIcon, "Sending " + tl_u + "...");
view->send();
}
void CDViewWidget::on_buttonReceive_clicked() {
if (view->inProgress()) {addToLog(WaitIcon, "processing..."); return;}
addToLog(WaitIcon, "Receiving " + tl_u + "...");
view->receive();
}
void CDViewWidget::on_buttonLoad_clicked() {
view->load();
}
void CDViewWidget::on_buttonSave_clicked() {
view->save();
}
void CDViewWidget::on_buttonParse_clicked() {
QString path = QFileDialog::getOpenFileName(this, "Select header file", "",
QString("%1 Description(%2_description.h);;Headers(*.h)").arg(tl_u, tl_l));
if (path.isEmpty()) return;
CDUtils::UpdateModeFlags mode = CDUtils::SaveByName;
if (!view->root()->isEmpty()) {
QCDModeDialog cdm;
if (cdm.exec() != QDialog::Accepted) return;
mode = cdm.mode();
}
view->buildFromHeader(path, mode);
}
#include "cdviewwidget.h"
#include "cdutils_core.h"
#include "qcd_core.h"
#include "qcd_model.h"
#include "qcd_modedialog.h"
#include "qvariantedit.h"
#include <QFileDialog>
CDViewWidget::CDViewWidget(QWidget * parent) : QWidget(parent), Ui::CDViewWidget() {
qRegisterMetaType<CDViewWidget::LogIcon>("CDViewWidget::LogIcon");
setupUi(this);
connect(view, SIGNAL(sendSucceed()), this, SLOT(sended()));
connect(view, SIGNAL(receiveSucceed()), this, SLOT(received()));
connect(view, SIGNAL(sendFailed()), this, SLOT(sendFailed()));
connect(view, SIGNAL(receiveFailed()), this, SLOT(receiveFailed()));
}
CDViewWidget::~CDViewWidget() {
}
void CDViewWidget::reset() {
setFile("");
}
void CDViewWidget::setType(int t) {
view->setType((CDUtils::CDType::cdT)t);
tl_u = view->typeLetter().toUpper();
tl_l = view->typeLetter().toLower();
view->refresh();
}
void CDViewWidget::setFile(const QString & f) {
view->setFile(f);
view->load();
}
void CDViewWidget::on_buttonSend_clicked() {
if (view->inProgress()) {addToLog(WaitIcon, "processing..."); return;}
addToLog(WaitIcon, "Sending " + tl_u + "...");
view->send();
}
void CDViewWidget::on_buttonReceive_clicked() {
if (view->inProgress()) {addToLog(WaitIcon, "processing..."); return;}
addToLog(WaitIcon, "Receiving " + tl_u + "...");
view->receive();
}
void CDViewWidget::on_buttonLoad_clicked() {
view->load();
}
void CDViewWidget::on_buttonSave_clicked() {
view->save();
}
void CDViewWidget::on_buttonParse_clicked() {
QString path = QFileDialog::getOpenFileName(this, "Select header file", "",
QString("%1 Description(%2_description.h);;Headers(*.h)").arg(tl_u, tl_l));
if (path.isEmpty()) return;
CDUtils::UpdateModeFlags mode = CDUtils::SaveByName;
if (!view->root()->isEmpty()) {
QCDModeDialog cdm;
if (cdm.exec() != QDialog::Accepted) return;
mode = cdm.mode();
}
view->buildFromHeader(path, mode);
}

View File

@@ -1,41 +1,41 @@
#ifndef CDVIEWWIDGET_H
#define CDVIEWWIDGET_H
#include <QWidget>
#include "ui_cdviewwidget.h"
class CDViewWidget : public QWidget, public Ui::CDViewWidget
{
Q_OBJECT
public:
explicit CDViewWidget(QWidget *parent = 0);
~CDViewWidget();
enum LogIcon {NoIcon, OKIcon, FailIcon, WaitIcon};
void reset();
void setType(int t);
void setFile(const QString & f);
private:
QString tl_u, tl_l;
private slots:
void sended() {addToLog(OKIcon, tl_u + " " + tr("sended succesfull"));}
void received() {addToLog(OKIcon, tl_u + " " + tr("received succesfull"));}
void sendFailed() {addToLog(FailIcon, tl_u + " " + tr("NOT sended"));}
void receiveFailed() {addToLog(FailIcon, tl_u + " " + tr("NOT received"));}
void on_buttonSend_clicked();
void on_buttonReceive_clicked();
void on_buttonLoad_clicked();
void on_buttonSave_clicked();
void on_buttonParse_clicked();
//void on_buttonCalculate_clicked();
signals:
void addToLog(CDViewWidget::LogIcon icon, const QString & msg);
};
#endif // CDVIEWWIDGET_H
#ifndef CDVIEWWIDGET_H
#define CDVIEWWIDGET_H
#include <QWidget>
#include "ui_cdviewwidget.h"
class CDViewWidget : public QWidget, public Ui::CDViewWidget
{
Q_OBJECT
public:
explicit CDViewWidget(QWidget *parent = 0);
~CDViewWidget();
enum LogIcon {NoIcon, OKIcon, FailIcon, WaitIcon};
void reset();
void setType(int t);
void setFile(const QString & f);
private:
QString tl_u, tl_l;
private slots:
void sended() {addToLog(OKIcon, tl_u + " " + tr("sended succesfull"));}
void received() {addToLog(OKIcon, tl_u + " " + tr("received succesfull"));}
void sendFailed() {addToLog(FailIcon, tl_u + " " + tr("NOT sended"));}
void receiveFailed() {addToLog(FailIcon, tl_u + " " + tr("NOT received"));}
void on_buttonSend_clicked();
void on_buttonReceive_clicked();
void on_buttonLoad_clicked();
void on_buttonSave_clicked();
void on_buttonParse_clicked();
//void on_buttonCalculate_clicked();
signals:
void addToLog(CDViewWidget::LogIcon icon, const QString & msg);
};
#endif // CDVIEWWIDGET_H

View File

@@ -1,176 +1,176 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CDViewWidget</class>
<widget class="QWidget" name="CDViewWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>689</width>
<height>459</height>
</rect>
</property>
<property name="windowTitle">
<string>CD Pult</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="buttonSend">
<property name="text">
<string>Send</string>
</property>
<property name="icon">
<iconset resource="cdpult.qrc">
<normaloff>:/icons/flame.png</normaloff>:/icons/flame.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonReceive">
<property name="text">
<string>Receive</string>
</property>
<property name="icon">
<iconset resource="cdpult.qrc">
<normaloff>:/icons/document-revert.png</normaloff>:/icons/document-revert.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="buttonLoad">
<property name="text">
<string>Load</string>
</property>
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/document-open.png</normaloff>:/icons/document-open.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonSave">
<property name="text">
<string>Save</string>
</property>
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/document-save.png</normaloff>:/icons/document-save.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="buttonParse">
<property name="text">
<string>Update description ...</string>
</property>
<property name="icon">
<iconset resource="cdpult.qrc">
<normaloff>:/icons/view-refresh.png</normaloff>:/icons/view-refresh.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="CDView" name="view">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed</set>
</property>
<property name="dragEnabled">
<bool>true</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DragOnly</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>CDView</class>
<extends>QTreeView</extends>
<header>qcd_view.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../../qad/application/qad_application.qrc"/>
<include location="cdpult.qrc"/>
</resources>
<connections/>
</ui>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CDViewWidget</class>
<widget class="QWidget" name="CDViewWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>689</width>
<height>459</height>
</rect>
</property>
<property name="windowTitle">
<string>CD Pult</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="buttonSend">
<property name="text">
<string>Send</string>
</property>
<property name="icon">
<iconset resource="cdpult.qrc">
<normaloff>:/icons/flame.png</normaloff>:/icons/flame.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonReceive">
<property name="text">
<string>Receive</string>
</property>
<property name="icon">
<iconset resource="cdpult.qrc">
<normaloff>:/icons/document-revert.png</normaloff>:/icons/document-revert.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="buttonLoad">
<property name="text">
<string>Load</string>
</property>
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/document-open.png</normaloff>:/icons/document-open.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonSave">
<property name="text">
<string>Save</string>
</property>
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/document-save.png</normaloff>:/icons/document-save.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="buttonParse">
<property name="text">
<string>Update description ...</string>
</property>
<property name="icon">
<iconset resource="cdpult.qrc">
<normaloff>:/icons/view-refresh.png</normaloff>:/icons/view-refresh.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="CDView" name="view">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed</set>
</property>
<property name="dragEnabled">
<bool>true</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DragOnly</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>CDView</class>
<extends>QTreeView</extends>
<header>qcd_view.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../../qad/application/qad_application.qrc"/>
<include location="cdpult.qrc"/>
</resources>
<connections/>
</ui>

View File

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

@@ -1,373 +1,373 @@
#include <QApplication>
#include "cdpultwindow.h"
template <typename Key, typename T>
class PIHash {
//template <typename Key1, typename T1> friend PIByteArray & operator >>(PIByteArray & s, PIHash<Key1, T1> & v);
//template <typename Key1, typename T1> friend PIByteArray & operator <<(PIByteArray & s, const PIHash<Key1, T1> & v);
public:
PIHash() {;}
PIHash(const PIHash<Key, T> & other) {*this = other;}
virtual ~PIHash() {;}
PIHash<Key, T> & operator =(const PIHash<Key, T> & other) {
if (this == &other) return *this;
clear();
pih_content = other.pih_content;
return *this;
}
typedef T mapped_type;
typedef Key key_type;
typedef PIPair<Key, T> value_type;
/*
class iterator {
friend class PIHash<Key, T>;
private:
iterator(const PIHash<Key, T> * v, ssize_t p): parent(v), pos(p) {}
const PIHash<Key, T> * parent;
ssize_t pos;
public:
iterator(): parent(0), pos(0) {}
const Key & key() const {return const_cast<PIHash<Key, T> * >(parent)->_key(pos);}
T & value() {return const_cast<PIHash<Key, T> * >(parent)->_value(pos);}
void operator ++() {++pos;}
void operator ++(int) {++pos;}
void operator --() {--pos;}
void operator --(int) {--pos;}
bool operator ==(const iterator & it) const {return (pos == it.pos);}
bool operator !=(const iterator & it) const {return (pos != it.pos);}
};
class reverse_iterator {
friend class PIHash<Key, T>;
private:
reverse_iterator(const PIHash<Key, T> * v, ssize_t p): parent(v), pos(p) {}
const PIHash<Key, T> * parent;
ssize_t pos;
public:
reverse_iterator(): parent(0), pos(0) {}
const Key & key() const {return const_cast<PIHash<Key, T> * >(parent)->_key(pos);}
T & value() const {return const_cast<PIHash<Key, T> * >(parent)->_value(pos);}
void operator ++() {--pos;}
void operator ++(int) {--pos;}
void operator --() {++pos;}
void operator --(int) {++pos;}
bool operator ==(const reverse_iterator & it) const {return (pos == it.pos);}
bool operator !=(const reverse_iterator & it) const {return (pos != it.pos);}
};
*/
class const_iterator {
friend class PIHash<Key, T>;
private:
const_iterator(const PIHash<Key, T> * v, ssize_t p): parent(v), pos(p), bpos(0) {
if (pos == 0) {
pos = -1;
nextPos();
}
}
void nextPos() {
while (++pos < parent->pih_content.size_s()) {
if (!parent->pih_content[pos].isEmpty())
return;
}
}
const PIHash<Key, T> * parent;
ssize_t pos, bpos;
public:
const_iterator(): parent(0), pos(0) {}
//const value_type operator *() const {return parent->_pair(pos);}
//const value_type* operator ->() const {cval = parent->_pair(pos); return &cval;}
const Key & key() const {return const_cast<PIHash<Key, T> * >(parent)->pih_content[pos][bpos].key;}
const T & value() const {return const_cast<PIHash<Key, T> * >(parent)->pih_content[pos][bpos].value;}
void operator ++() {
if (pos < parent->pih_content.size_s()) {
if (bpos >= parent->pih_content[pos].size_s() - 1) {
bpos = 0;
nextPos();
} else
++bpos;
} else {
bpos = 0;
++pos;
}
printf(" ++: %d %d\n", pos, bpos);
}
//void operator ++(int) {++pos;}
void operator --() {
--pos;
}
//void operator --(int) {--pos;}
bool operator ==(const const_iterator & it) const {return (pos == it.pos && bpos == it.bpos);}
bool operator !=(const const_iterator & it) const {return !(*this == it);}
mutable value_type cval;
};
/*
class const_reverse_iterator {
friend class PIHash<Key, T>;
private:
const_reverse_iterator(const PIHash<Key, T> * v, ssize_t p): parent(v), pos(p) {}
const PIHash<Key, T> * parent;
ssize_t pos;
public:
const_reverse_iterator(): parent(0), pos(0) {}
const value_type operator *() const {return parent->_pair(pos);}
const value_type* operator ->() const {cval = parent->_pair(pos); return &cval;}
void operator ++() {--pos;}
void operator ++(int) {--pos;}
void operator --() {++pos;}
void operator --(int) {++pos;}
bool operator ==(const const_reverse_iterator & it) const {return (pos == it.pos);}
bool operator !=(const const_reverse_iterator & it) const {return (pos != it.pos);}
mutable value_type cval;
};
*/
//iterator begin() {return iterator(this, 0);}
//iterator end() {return iterator(this, size());}
const_iterator begin() const {return const_iterator(this, 0);}
const_iterator end() const {return const_iterator(this, size());}
const_iterator constBegin() const {return const_iterator(this, 0);}
const_iterator constEnd() const {return const_iterator(this, size());}
//reverse_iterator rbegin() {return reverse_iterator(this, size() - 1);}
//reverse_iterator rend() {return reverse_iterator(this, -1);}
//const_reverse_iterator rbegin() const {return const_reverse_iterator(this, size() - 1);}
//const_reverse_iterator rend() const {return const_reverse_iterator(this, -1);}
//const_reverse_iterator constRbegin() const {return const_reverse_iterator(this, size() - 1);}
//const_reverse_iterator constRend() const {return const_reverse_iterator(this, -1);}
size_t size() const {return pih_content.size();}
int size_s() const {return pih_content.size_s();}
size_t length() const {return pih_content.size();}
size_t capacity() const {return pih_content.size();}
bool isEmpty() const {return (pih_content.size() == 0);}
T & operator [](const Key & key) {
if (pih_content.isEmpty()) _rehash(1);
uint k = piHash(key);
int i = _index(k);
if (i < pih_content.size_s()) {
PIVector<HashEntry> & hv(pih_content[i]);
if (hv.size_s() == 1) {
if (hv[0].key == k)
return hv[0].value;
}
for (int j = 0; j < hv.size_s(); ++j)
if (hv[j].key == k)
return hv[j].value;
}
if (pih_content[i].size_s() >= 4)
_rehash(pih_content.size_s() * 2);
i = _index(k);
pih_content[i] << HashEntry(k);
return pih_content[i].back().value;
}
const T operator [](const Key & key) const {return value(key);}
T & at(const Key & key) {return (*this)[key];}
const T at(const Key & key) const {return (*this)[key];}
PIHash<Key, T> & operator <<(const PIHash<Key, T> & other) {
if (other.isEmpty()) return *this;
for (int i = 0; i < other.pih_content.size_s(); ++i)
for (int j = 0; j < other.pih_content[i].size_s(); ++j)
insert(other.pih_content[i][j].key, other.pih_content[i][j].value);
return *this;
}
bool operator ==(const PIHash<Key, T> & t) const {return (pih_content == t.pih_content);}
bool operator !=(const PIHash<Key, T> & t) const {return (pih_content != t.pih_content);}
bool contains(const Key & key) const {
bool f(false);
_find(key, f);
return f;
}
PIHash<Key, T> & reserve(size_t new_size) {_rehash(new_size); return *this;}
PIHash<Key, T> & remove(const Key & key) {
uint k = piHash(key);
int i = _index(k);
if (i >= pih_content.size_s()) return *this;
PIVector<HashEntry> & hv(pih_content[i]);
for (int j = 0; j < hv.size_s(); ++j)
if (hv[j].key == k) {
hv.remove(j);
--j;
}
return *this;
}
PIHash<Key, T> & erase(const Key & key) {return remove(key);}
PIHash<Key, T> & clear() {pih_content.clear(); return *this;}
void swap(PIHash<Key, T> & other) {
piSwapBinary<PIVector<PIVector<HashEntry> > >(pih_content, other.pih_content);
}
PIHash<Key, T> & insert(const Key & key, const T & value) {
(*this)[key] = value;
return *this;
}
const T value(const Key & key, const T & default_ = T()) const {
uint k = piHash(key);
int i = _index(k);
if (i >= pih_content.size_s()) return default_;
const PIVector<HashEntry> & hv(pih_content[i]);
for (int j = 0; j < hv.size_s(); ++j)
if (hv[j].key == k)
return hv[j].value;
return default_;
}
PIVector<T> values() const {
PIVector<T> ret;
for (int i = 0; i < pih_content.size_s(); ++i)
for (int j = 0; j < pih_content[i].size_s(); ++j)
ret << pih_content[i][j].value;
return ret;
}
/*Key key(const T & value_, const Key & default_ = Key()) const {
for (int i = 0; i < pih_content.size_s(); ++i)
for (int j = 0; j < pih_content[i].size_s(); ++j)
if (pih_content[i][j].value == value_)
return pih_content[i][j].key;
return default_;
}
PIVector<Key> keys() const {
PIVector<Key> ret;
for (int i = 0; i < pih_content.size_s(); ++i)
for (int j = 0; j < pih_content[i].size_s(); ++j)
ret << pih_content[i][j].key;
return ret;
}*/
/*void dump() {
piCout << "PIHash" << size() << "entries" << PICoutManipulators::NewLine << "content:";
for (size_t i = 0; i < pih_content.size(); ++i)
piCout << PICoutManipulators::Tab << i << ":" << pih_content[i];
piCout << "index:";
for (size_t i = 0; i < pim_index.size(); ++i)
piCout << PICoutManipulators::Tab << i << ":" << pim_index[i].key << "->" << pim_index[i].index;
}*/
protected:
struct HashEntry {
HashEntry(uint k = 0, const T & v = T()): key(k), value(v) {;}
uint key;
T value;
bool operator ==(const HashEntry & s) const {return key == s.key;}
bool operator !=(const HashEntry & s) const {return key != s.key;}
bool operator <(const HashEntry & s) const {return key < s.key;}
bool operator >(const HashEntry & s) const {return key > s.key;}
};
/*template <typename Key1, typename T1> friend PIByteArray & operator >>(PIByteArray & s, PIDeque<typename PIHash<Key1, T1>::HashEntry> & v);
template <typename Key1, typename T1> friend PIByteArray & operator <<(PIByteArray & s, const PIDeque<typename PIHash<Key1, T1>::HashEntry> & v);
const value_type _pair(ssize_t index) const {
if (index < 0 || index >= pim_index.size_s())
return value_type();
//piCout << "_pair" << index << pim_index[index].index;
return value_type(pim_index[index].key, pih_content[pim_index[index].index]);
}
Key & _key(ssize_t index) {return pim_index[index].key;}
T & _value(ssize_t index) {return pih_content[pim_index[index].index];}*/
inline size_t asize(size_t s) {
if (s == 0) return 0;
if (pih_content.size() + pih_content.size() >= s && pih_content.size() < s)
return pih_content.size() + pih_content.size();
ssize_t t = 0, s_ = s - 1;
while (s_ >> t) ++t;
return (1 << t);
}
int _index(const uint & k) const {
return k % pih_content.size_s();
}
void _rehash(int ns) {
ns = asize(ns);
if (pih_content.size_s() == ns) return;
PIVector<PIVector<HashEntry> > nhc;
nhc.resize(ns);
for (int i = 0; i < pih_content.size_s(); ++i) {
for (int j = 0; j < pih_content[i].size_s(); ++j) {
HashEntry & e(pih_content[i][j]);
int ni = e.key % ns;
nhc[ni] << e;
}
}
pih_content.swap(nhc);
}
PIVector<PIVector<HashEntry> > pih_content;
};
uint qHash(const PIString & v, uint seed = 0) {return piHash(v);}
#include "logview.h"
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
#if QT_VERSION >= 0x050000
a.setAttribute(Qt::AA_UseHighDpiPixmaps, true);
#endif
//################################
/*QHash<PIString, PIString> h2;
QMap<PIString, PIString> m2;
PIString prefix = "1234567890";
PITimeMeasurer tm;
double el = 0.;
tm.reset();
for (int i=0; i<10000; ++i) {
h2[prefix + PIString::fromNumber(i)+"1234567890"] = PIString::fromNumber(randomi());
}
el = tm.elapsed_m(); piCout << el << h2.capacity();
tm.reset();
for (int i=0; i<10000; ++i) {
m2[prefix + PIString::fromNumber(i)+"1234567890"] = PIString::fromNumber(randomi());
}
el = tm.elapsed_m(); piCout << el;
piCout << "*********";
PIString _s;
tm.reset();
for (int i=0; i<10000; ++i) {
_s = h2.value(prefix + PIString::fromNumber(i)+"1234567890");
}
el = tm.elapsed_m(); piCout << el << h2.capacity();
tm.reset();
for (int i=0; i<10000; ++i) {
_s = m2.value(prefix + PIString::fromNumber(i)+"1234567890");
}
el = tm.elapsed_m(); piCout << el;
return 0;*/
//################################
//1245hghgfhfdgshrgnhdsgfhjshdszdgsdgnjedghrbnlcvleabjmbassfdggfhbnsjkgnfdvfdsdfojbwasv213443gr2t4sfth
/*LogView lw;
lw.setLogFont(QFont("dejavu sans mono", 9));
lw.registerCategory("Warning", "Warning", QImage(":/icons/flame.png"), Qt::darkYellow);
lw.registerCategory("Error", "Error", QImage(":/icons/dialog-cancel.png"), Qt::darkRed, true);
//lw.setLinesLimit(12);
lw.show();
piForTimes(100)
lw.addText(QString("row %1").arg(_i100));
lw.addText("-- Up-to-date: C:/sdk/MinGW/x32/i686-w64-mingw32/include/qglengine/scene_tree.h");
lw.addText("-- Up-to-date: C:/sdk/MinGW/x32/i686-w64-mingw32/include/qglengine/scene_tree.h");
lw.addText("-- Up-to-date: C:/sdk/MinGW/x32/i686-w64-mingw32/include/qglengine/view_editor.h");
lw.addText("-- Up-to-date: C:/sdk/MinGW/x32/i686-w64-mingw32/include/qglengine/material_map_editor.h\n"
"-- Up-to-date: C:/sdk/MinGW/x32/i686-w64-mingw32/include/qglengine/materials_editor\n"
"-- Up-to-date: C:/sdk/MinGW/x32/i686-w64-mingw32/include/qglengine/object_editor.h");
lw.addText("[Warning] sdfkjhdfgj");
lw.addText("[Error] gbflknwed");
QLineEdit * le = new QLineEdit();
QObject::connect(le, &QLineEdit::returnPressed, [&](){lw.addText(le->text());});
le->show();
return a.exec();*/
CDPultWindow w;
w.show();
if (a.arguments().size() > 1)
w.loadFile(a.arguments()[1]);
return a.exec();
}
#include <QApplication>
#include "cdpultwindow.h"
template <typename Key, typename T>
class PIHash {
//template <typename Key1, typename T1> friend PIByteArray & operator >>(PIByteArray & s, PIHash<Key1, T1> & v);
//template <typename Key1, typename T1> friend PIByteArray & operator <<(PIByteArray & s, const PIHash<Key1, T1> & v);
public:
PIHash() {;}
PIHash(const PIHash<Key, T> & other) {*this = other;}
virtual ~PIHash() {;}
PIHash<Key, T> & operator =(const PIHash<Key, T> & other) {
if (this == &other) return *this;
clear();
pih_content = other.pih_content;
return *this;
}
typedef T mapped_type;
typedef Key key_type;
typedef PIPair<Key, T> value_type;
/*
class iterator {
friend class PIHash<Key, T>;
private:
iterator(const PIHash<Key, T> * v, ssize_t p): parent(v), pos(p) {}
const PIHash<Key, T> * parent;
ssize_t pos;
public:
iterator(): parent(0), pos(0) {}
const Key & key() const {return const_cast<PIHash<Key, T> * >(parent)->_key(pos);}
T & value() {return const_cast<PIHash<Key, T> * >(parent)->_value(pos);}
void operator ++() {++pos;}
void operator ++(int) {++pos;}
void operator --() {--pos;}
void operator --(int) {--pos;}
bool operator ==(const iterator & it) const {return (pos == it.pos);}
bool operator !=(const iterator & it) const {return (pos != it.pos);}
};
class reverse_iterator {
friend class PIHash<Key, T>;
private:
reverse_iterator(const PIHash<Key, T> * v, ssize_t p): parent(v), pos(p) {}
const PIHash<Key, T> * parent;
ssize_t pos;
public:
reverse_iterator(): parent(0), pos(0) {}
const Key & key() const {return const_cast<PIHash<Key, T> * >(parent)->_key(pos);}
T & value() const {return const_cast<PIHash<Key, T> * >(parent)->_value(pos);}
void operator ++() {--pos;}
void operator ++(int) {--pos;}
void operator --() {++pos;}
void operator --(int) {++pos;}
bool operator ==(const reverse_iterator & it) const {return (pos == it.pos);}
bool operator !=(const reverse_iterator & it) const {return (pos != it.pos);}
};
*/
class const_iterator {
friend class PIHash<Key, T>;
private:
const_iterator(const PIHash<Key, T> * v, ssize_t p): parent(v), pos(p), bpos(0) {
if (pos == 0) {
pos = -1;
nextPos();
}
}
void nextPos() {
while (++pos < parent->pih_content.size_s()) {
if (!parent->pih_content[pos].isEmpty())
return;
}
}
const PIHash<Key, T> * parent;
ssize_t pos, bpos;
public:
const_iterator(): parent(0), pos(0) {}
//const value_type operator *() const {return parent->_pair(pos);}
//const value_type* operator ->() const {cval = parent->_pair(pos); return &cval;}
const Key & key() const {return const_cast<PIHash<Key, T> * >(parent)->pih_content[pos][bpos].key;}
const T & value() const {return const_cast<PIHash<Key, T> * >(parent)->pih_content[pos][bpos].value;}
void operator ++() {
if (pos < parent->pih_content.size_s()) {
if (bpos >= parent->pih_content[pos].size_s() - 1) {
bpos = 0;
nextPos();
} else
++bpos;
} else {
bpos = 0;
++pos;
}
printf(" ++: %d %d\n", pos, bpos);
}
//void operator ++(int) {++pos;}
void operator --() {
--pos;
}
//void operator --(int) {--pos;}
bool operator ==(const const_iterator & it) const {return (pos == it.pos && bpos == it.bpos);}
bool operator !=(const const_iterator & it) const {return !(*this == it);}
mutable value_type cval;
};
/*
class const_reverse_iterator {
friend class PIHash<Key, T>;
private:
const_reverse_iterator(const PIHash<Key, T> * v, ssize_t p): parent(v), pos(p) {}
const PIHash<Key, T> * parent;
ssize_t pos;
public:
const_reverse_iterator(): parent(0), pos(0) {}
const value_type operator *() const {return parent->_pair(pos);}
const value_type* operator ->() const {cval = parent->_pair(pos); return &cval;}
void operator ++() {--pos;}
void operator ++(int) {--pos;}
void operator --() {++pos;}
void operator --(int) {++pos;}
bool operator ==(const const_reverse_iterator & it) const {return (pos == it.pos);}
bool operator !=(const const_reverse_iterator & it) const {return (pos != it.pos);}
mutable value_type cval;
};
*/
//iterator begin() {return iterator(this, 0);}
//iterator end() {return iterator(this, size());}
const_iterator begin() const {return const_iterator(this, 0);}
const_iterator end() const {return const_iterator(this, size());}
const_iterator constBegin() const {return const_iterator(this, 0);}
const_iterator constEnd() const {return const_iterator(this, size());}
//reverse_iterator rbegin() {return reverse_iterator(this, size() - 1);}
//reverse_iterator rend() {return reverse_iterator(this, -1);}
//const_reverse_iterator rbegin() const {return const_reverse_iterator(this, size() - 1);}
//const_reverse_iterator rend() const {return const_reverse_iterator(this, -1);}
//const_reverse_iterator constRbegin() const {return const_reverse_iterator(this, size() - 1);}
//const_reverse_iterator constRend() const {return const_reverse_iterator(this, -1);}
size_t size() const {return pih_content.size();}
int size_s() const {return pih_content.size_s();}
size_t length() const {return pih_content.size();}
size_t capacity() const {return pih_content.size();}
bool isEmpty() const {return (pih_content.size() == 0);}
T & operator [](const Key & key) {
if (pih_content.isEmpty()) _rehash(1);
uint k = piHash(key);
int i = _index(k);
if (i < pih_content.size_s()) {
PIVector<HashEntry> & hv(pih_content[i]);
if (hv.size_s() == 1) {
if (hv[0].key == k)
return hv[0].value;
}
for (int j = 0; j < hv.size_s(); ++j)
if (hv[j].key == k)
return hv[j].value;
}
if (pih_content[i].size_s() >= 4)
_rehash(pih_content.size_s() * 2);
i = _index(k);
pih_content[i] << HashEntry(k);
return pih_content[i].back().value;
}
const T operator [](const Key & key) const {return value(key);}
T & at(const Key & key) {return (*this)[key];}
const T at(const Key & key) const {return (*this)[key];}
PIHash<Key, T> & operator <<(const PIHash<Key, T> & other) {
if (other.isEmpty()) return *this;
for (int i = 0; i < other.pih_content.size_s(); ++i)
for (int j = 0; j < other.pih_content[i].size_s(); ++j)
insert(other.pih_content[i][j].key, other.pih_content[i][j].value);
return *this;
}
bool operator ==(const PIHash<Key, T> & t) const {return (pih_content == t.pih_content);}
bool operator !=(const PIHash<Key, T> & t) const {return (pih_content != t.pih_content);}
bool contains(const Key & key) const {
bool f(false);
_find(key, f);
return f;
}
PIHash<Key, T> & reserve(size_t new_size) {_rehash(new_size); return *this;}
PIHash<Key, T> & remove(const Key & key) {
uint k = piHash(key);
int i = _index(k);
if (i >= pih_content.size_s()) return *this;
PIVector<HashEntry> & hv(pih_content[i]);
for (int j = 0; j < hv.size_s(); ++j)
if (hv[j].key == k) {
hv.remove(j);
--j;
}
return *this;
}
PIHash<Key, T> & erase(const Key & key) {return remove(key);}
PIHash<Key, T> & clear() {pih_content.clear(); return *this;}
void swap(PIHash<Key, T> & other) {
pih_content.swap(other.pih_content);
}
PIHash<Key, T> & insert(const Key & key, const T & value) {
(*this)[key] = value;
return *this;
}
const T value(const Key & key, const T & default_ = T()) const {
uint k = piHash(key);
int i = _index(k);
if (i >= pih_content.size_s()) return default_;
const PIVector<HashEntry> & hv(pih_content[i]);
for (int j = 0; j < hv.size_s(); ++j)
if (hv[j].key == k)
return hv[j].value;
return default_;
}
PIVector<T> values() const {
PIVector<T> ret;
for (int i = 0; i < pih_content.size_s(); ++i)
for (int j = 0; j < pih_content[i].size_s(); ++j)
ret << pih_content[i][j].value;
return ret;
}
/*Key key(const T & value_, const Key & default_ = Key()) const {
for (int i = 0; i < pih_content.size_s(); ++i)
for (int j = 0; j < pih_content[i].size_s(); ++j)
if (pih_content[i][j].value == value_)
return pih_content[i][j].key;
return default_;
}
PIVector<Key> keys() const {
PIVector<Key> ret;
for (int i = 0; i < pih_content.size_s(); ++i)
for (int j = 0; j < pih_content[i].size_s(); ++j)
ret << pih_content[i][j].key;
return ret;
}*/
/*void dump() {
piCout << "PIHash" << size() << "entries" << PICoutManipulators::NewLine << "content:";
for (size_t i = 0; i < pih_content.size(); ++i)
piCout << PICoutManipulators::Tab << i << ":" << pih_content[i];
piCout << "index:";
for (size_t i = 0; i < pim_index.size(); ++i)
piCout << PICoutManipulators::Tab << i << ":" << pim_index[i].key << "->" << pim_index[i].index;
}*/
protected:
struct HashEntry {
HashEntry(uint k = 0, const T & v = T()): key(k), value(v) {;}
uint key;
T value;
bool operator ==(const HashEntry & s) const {return key == s.key;}
bool operator !=(const HashEntry & s) const {return key != s.key;}
bool operator <(const HashEntry & s) const {return key < s.key;}
bool operator >(const HashEntry & s) const {return key > s.key;}
};
/*template <typename Key1, typename T1> friend PIByteArray & operator >>(PIByteArray & s, PIDeque<typename PIHash<Key1, T1>::HashEntry> & v);
template <typename Key1, typename T1> friend PIByteArray & operator <<(PIByteArray & s, const PIDeque<typename PIHash<Key1, T1>::HashEntry> & v);
const value_type _pair(ssize_t index) const {
if (index < 0 || index >= pim_index.size_s())
return value_type();
//piCout << "_pair" << index << pim_index[index].index;
return value_type(pim_index[index].key, pih_content[pim_index[index].index]);
}
Key & _key(ssize_t index) {return pim_index[index].key;}
T & _value(ssize_t index) {return pih_content[pim_index[index].index];}*/
inline size_t asize(size_t s) {
if (s == 0) return 0;
if (pih_content.size() + pih_content.size() >= s && pih_content.size() < s)
return pih_content.size() + pih_content.size();
ssize_t t = 0, s_ = s - 1;
while (s_ >> t) ++t;
return (1 << t);
}
int _index(const uint & k) const {
return k % pih_content.size_s();
}
void _rehash(int ns) {
ns = asize(ns);
if (pih_content.size_s() == ns) return;
PIVector<PIVector<HashEntry> > nhc;
nhc.resize(ns);
for (int i = 0; i < pih_content.size_s(); ++i) {
for (int j = 0; j < pih_content[i].size_s(); ++j) {
HashEntry & e(pih_content[i][j]);
int ni = e.key % ns;
nhc[ni] << e;
}
}
pih_content.swap(nhc);
}
PIVector<PIVector<HashEntry> > pih_content;
};
uint qHash(const PIString & v, uint seed = 0) {return piHash(v);}
#include "logview.h"
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
#if QT_VERSION >= 0x050000
a.setAttribute(Qt::AA_UseHighDpiPixmaps, true);
#endif
//################################
/*QHash<PIString, PIString> h2;
QMap<PIString, PIString> m2;
PIString prefix = "1234567890";
PITimeMeasurer tm;
double el = 0.;
tm.reset();
for (int i=0; i<10000; ++i) {
h2[prefix + PIString::fromNumber(i)+"1234567890"] = PIString::fromNumber(randomi());
}
el = tm.elapsed_m(); piCout << el << h2.capacity();
tm.reset();
for (int i=0; i<10000; ++i) {
m2[prefix + PIString::fromNumber(i)+"1234567890"] = PIString::fromNumber(randomi());
}
el = tm.elapsed_m(); piCout << el;
piCout << "*********";
PIString _s;
tm.reset();
for (int i=0; i<10000; ++i) {
_s = h2.value(prefix + PIString::fromNumber(i)+"1234567890");
}
el = tm.elapsed_m(); piCout << el << h2.capacity();
tm.reset();
for (int i=0; i<10000; ++i) {
_s = m2.value(prefix + PIString::fromNumber(i)+"1234567890");
}
el = tm.elapsed_m(); piCout << el;
return 0;*/
//################################
//1245hghgfhfdgshrgnhdsgfhjshdszdgsdgnjedghrbnlcvleabjmbassfdggfhbnsjkgnfdvfdsdfojbwasv213443gr2t4sfth
/*LogView lw;
lw.setLogFont(QFont("dejavu sans mono", 9));
lw.registerCategory("Warning", "Warning", QImage(":/icons/flame.png"), Qt::darkYellow);
lw.registerCategory("Error", "Error", QImage(":/icons/dialog-cancel.png"), Qt::darkRed, true);
//lw.setLinesLimit(12);
lw.show();
piForTimes(100)
lw.addText(QString("row %1").arg(_i100));
lw.addText("-- Up-to-date: C:/sdk/MinGW/x32/i686-w64-mingw32/include/qglengine/scene_tree.h");
lw.addText("-- Up-to-date: C:/sdk/MinGW/x32/i686-w64-mingw32/include/qglengine/scene_tree.h");
lw.addText("-- Up-to-date: C:/sdk/MinGW/x32/i686-w64-mingw32/include/qglengine/view_editor.h");
lw.addText("-- Up-to-date: C:/sdk/MinGW/x32/i686-w64-mingw32/include/qglengine/material_map_editor.h\n"
"-- Up-to-date: C:/sdk/MinGW/x32/i686-w64-mingw32/include/qglengine/materials_editor\n"
"-- Up-to-date: C:/sdk/MinGW/x32/i686-w64-mingw32/include/qglengine/object_editor.h");
lw.addText("[Warning] sdfkjhdfgj");
lw.addText("[Error] gbflknwed");
QLineEdit * le = new QLineEdit();
QObject::connect(le, &QLineEdit::returnPressed, [&](){lw.addText(le->text());});
le->show();
return a.exec();*/
CDPultWindow w;
w.show();
if (a.arguments().size() > 1)
w.loadFile(a.arguments()[1]);
return a.exec();
}

View File

@@ -0,0 +1,10 @@
project(piconnedit)
if(APPLE)
set(APP_ICON "")
elseif(WIN32)
set(APP_ICON "")
else()
set(APP_ICON "")
endif()
set(APP_INFO "PIConnection GUI editor")
piqt_application(${PROJECT_NAME} "Gui;Widgets" "qad_utils;qad_widgets;qad_blockview;piqt_utils")

View File

@@ -30,5 +30,5 @@ int main(int argc, char * argv[]) {
}
}
}
return a.exec();
return 0;
}

View File

@@ -0,0 +1,10 @@
project(pidumper)
if(APPLE)
set(APP_ICON "")
elseif(WIN32)
set(APP_ICON "")
else()
set(APP_ICON "")
endif()
set(APP_INFO "PIConnection GUI editor")
piqt_application(${PROJECT_NAME} "Gui;Widgets" "qad_utils;qad_widgets;piqt_utils")

Some files were not shown because too many files have changed in this diff Show More