initial commit
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/.svn
|
||||||
|
CMakeLists.txt.user*
|
||||||
2
AUTHORS.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
peri4 = Пелипенко Иван <peri4ko@yandex.ru>
|
||||||
|
andrey = Бычков Андрей <andrey@signalmodelling.ru>
|
||||||
76
CMakeLists.txt
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.0)
|
||||||
|
cmake_policy(SET CMP0017 NEW) # need include() with .cmake
|
||||||
|
project(qad)
|
||||||
|
set(qad_MAJOR 1)
|
||||||
|
set(qad_MINOR 9)
|
||||||
|
set(qad_REVISION 0)
|
||||||
|
set(qad_SUFFIX )
|
||||||
|
set(qad_COMPANY SHS)
|
||||||
|
set(qad_DOMAIN org.SHS)
|
||||||
|
|
||||||
|
if ("x${CMAKE_MODULE_PATH}" STREQUAL "x")
|
||||||
|
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(SHSTKMacros)
|
||||||
|
include(QtWraps)
|
||||||
|
shstk_begin_project(qad QAD)
|
||||||
|
include(SHSTKQtMacros)
|
||||||
|
|
||||||
|
shstk_qt_founded(QtVersions)
|
||||||
|
foreach(_v ${_QT_VERSIONS_})
|
||||||
|
#message("Qt ${_v} -> ${QtVersions}")
|
||||||
|
option(Qt${_v} "Build for Qt${_v}" ON)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
if (NOT DEFINED ANDROID_PLATFORM)
|
||||||
|
find_package(OpenGL REQUIRED)
|
||||||
|
endif()
|
||||||
|
#include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
|
option(UTILS "Build various utils" ${_plugins_default_})
|
||||||
|
option(DESIGNER_PLUGINS "Build Qt designer plugins" ${_plugins_default_})
|
||||||
|
|
||||||
|
macro(qad_library NAME _MODULES _LIBS)
|
||||||
|
shstk_qt_project(qad_${NAME} FALSE "qad" "${_MODULES}" "${_LIBS}" ${ARGN})
|
||||||
|
shstk_qt_install("qad" FALSE qad_${NAME} "${out_HDR}" "${out_QM}")
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(qad_application NAME _MODULES _LIBS)
|
||||||
|
shstk_qt_project(${NAME} TRUE "qad" "${_MODULES}" "${_LIBS}" ${ARGN})
|
||||||
|
shstk_qt_install("qad" TRUE ${NAME} "" "${out_QM}")
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(qad_plugin NAME _MODULES _LIBS)
|
||||||
|
shstk_qt_plugin(qad_${NAME} "${_MODULES}" "qad_${NAME};${_LIBS}")
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
shstk_install(qad FALSE "" "${QAD_VERSION_FILE}")
|
||||||
|
if (NOT LOCAL)
|
||||||
|
file(GLOB CMAKES "cmake/*.cmake" "cmake/*.in")
|
||||||
|
install(FILES ${CMAKES} DESTINATION ${CMAKE_ROOT}/Modules)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(libs)
|
||||||
|
if (UTILS)
|
||||||
|
add_subdirectory(utils)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message("----------QAD----------")
|
||||||
|
message(" Build for ${QtVersions}")
|
||||||
|
message(" Linkage: ${qad_LIB_TYPE_MSG}")
|
||||||
|
message(" Type : ${qad_BUILD_TYPE}")
|
||||||
|
message(" Install: \"${CMAKE_INSTALL_PREFIX}\"")
|
||||||
|
message("")
|
||||||
|
print_list("${_qt_libs}" " Libraries:" " * ")
|
||||||
|
if (NOT "x${_qt_plugs}" STREQUAL "x")
|
||||||
|
message("")
|
||||||
|
print_list("${_qt_plugs}" " Plugins:" " * ")
|
||||||
|
endif()
|
||||||
|
if (NOT "x${_qt_apps}" STREQUAL "x")
|
||||||
|
message("")
|
||||||
|
print_list("${_qt_apps}" " Applications:" " * ")
|
||||||
|
endif()
|
||||||
|
message("-----------------------")
|
||||||
|
|
||||||
|
shstk_copy_to_parent()
|
||||||
165
LICENSE.txt
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
|
||||||
|
This version of the GNU Lesser General Public License incorporates
|
||||||
|
the terms and conditions of version 3 of the GNU General Public
|
||||||
|
License, supplemented by the additional permissions listed below.
|
||||||
|
|
||||||
|
0. Additional Definitions.
|
||||||
|
|
||||||
|
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||||
|
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
"The Library" refers to a covered work governed by this License,
|
||||||
|
other than an Application or a Combined Work as defined below.
|
||||||
|
|
||||||
|
An "Application" is any work that makes use of an interface provided
|
||||||
|
by the Library, but which is not otherwise based on the Library.
|
||||||
|
Defining a subclass of a class defined by the Library is deemed a mode
|
||||||
|
of using an interface provided by the Library.
|
||||||
|
|
||||||
|
A "Combined Work" is a work produced by combining or linking an
|
||||||
|
Application with the Library. The particular version of the Library
|
||||||
|
with which the Combined Work was made is also called the "Linked
|
||||||
|
Version".
|
||||||
|
|
||||||
|
The "Minimal Corresponding Source" for a Combined Work means the
|
||||||
|
Corresponding Source for the Combined Work, excluding any source code
|
||||||
|
for portions of the Combined Work that, considered in isolation, are
|
||||||
|
based on the Application, and not on the Linked Version.
|
||||||
|
|
||||||
|
The "Corresponding Application Code" for a Combined Work means the
|
||||||
|
object code and/or source code for the Application, including any data
|
||||||
|
and utility programs needed for reproducing the Combined Work from the
|
||||||
|
Application, but excluding the System Libraries of the Combined Work.
|
||||||
|
|
||||||
|
1. Exception to Section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
You may convey a covered work under sections 3 and 4 of this License
|
||||||
|
without being bound by section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
2. Conveying Modified Versions.
|
||||||
|
|
||||||
|
If you modify a copy of the Library, and, in your modifications, a
|
||||||
|
facility refers to a function or data to be supplied by an Application
|
||||||
|
that uses the facility (other than as an argument passed when the
|
||||||
|
facility is invoked), then you may convey a copy of the modified
|
||||||
|
version:
|
||||||
|
|
||||||
|
a) under this License, provided that you make a good faith effort to
|
||||||
|
ensure that, in the event an Application does not supply the
|
||||||
|
function or data, the facility still operates, and performs
|
||||||
|
whatever part of its purpose remains meaningful, or
|
||||||
|
|
||||||
|
b) under the GNU GPL, with none of the additional permissions of
|
||||||
|
this License applicable to that copy.
|
||||||
|
|
||||||
|
3. Object Code Incorporating Material from Library Header Files.
|
||||||
|
|
||||||
|
The object code form of an Application may incorporate material from
|
||||||
|
a header file that is part of the Library. You may convey such object
|
||||||
|
code under terms of your choice, provided that, if the incorporated
|
||||||
|
material is not limited to numerical parameters, data structure
|
||||||
|
layouts and accessors, or small macros, inline functions and templates
|
||||||
|
(ten or fewer lines in length), you do both of the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the object code that the
|
||||||
|
Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
4. Combined Works.
|
||||||
|
|
||||||
|
You may convey a Combined Work under terms of your choice that,
|
||||||
|
taken together, effectively do not restrict modification of the
|
||||||
|
portions of the Library contained in the Combined Work and reverse
|
||||||
|
engineering for debugging such modifications, if you also do each of
|
||||||
|
the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the Combined Work that
|
||||||
|
the Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
c) For a Combined Work that displays copyright notices during
|
||||||
|
execution, include the copyright notice for the Library among
|
||||||
|
these notices, as well as a reference directing the user to the
|
||||||
|
copies of the GNU GPL and this license document.
|
||||||
|
|
||||||
|
d) Do one of the following:
|
||||||
|
|
||||||
|
0) Convey the Minimal Corresponding Source under the terms of this
|
||||||
|
License, and the Corresponding Application Code in a form
|
||||||
|
suitable for, and under terms that permit, the user to
|
||||||
|
recombine or relink the Application with a modified version of
|
||||||
|
the Linked Version to produce a modified Combined Work, in the
|
||||||
|
manner specified by section 6 of the GNU GPL for conveying
|
||||||
|
Corresponding Source.
|
||||||
|
|
||||||
|
1) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (a) uses at run time
|
||||||
|
a copy of the Library already present on the user's computer
|
||||||
|
system, and (b) will operate properly with a modified version
|
||||||
|
of the Library that is interface-compatible with the Linked
|
||||||
|
Version.
|
||||||
|
|
||||||
|
e) Provide Installation Information, but only if you would otherwise
|
||||||
|
be required to provide such information under section 6 of the
|
||||||
|
GNU GPL, and only to the extent that such information is
|
||||||
|
necessary to install and execute a modified version of the
|
||||||
|
Combined Work produced by recombining or relinking the
|
||||||
|
Application with a modified version of the Linked Version. (If
|
||||||
|
you use option 4d0, the Installation Information must accompany
|
||||||
|
the Minimal Corresponding Source and Corresponding Application
|
||||||
|
Code. If you use option 4d1, you must provide the Installation
|
||||||
|
Information in the manner specified by section 6 of the GNU GPL
|
||||||
|
for conveying Corresponding Source.)
|
||||||
|
|
||||||
|
5. Combined Libraries.
|
||||||
|
|
||||||
|
You may place library facilities that are a work based on the
|
||||||
|
Library side by side in a single library together with other library
|
||||||
|
facilities that are not Applications and are not covered by this
|
||||||
|
License, and convey such a combined library under terms of your
|
||||||
|
choice, if you do both of the following:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based
|
||||||
|
on the Library, uncombined with any other library facilities,
|
||||||
|
conveyed under the terms of this License.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library that part of it
|
||||||
|
is a work based on the Library, and explaining where to find the
|
||||||
|
accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
6. Revised Versions of the GNU Lesser General Public License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the GNU Lesser General Public License from time to time. Such new
|
||||||
|
versions will be similar in spirit to the present version, but may
|
||||||
|
differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Library as you received it specifies that a certain numbered version
|
||||||
|
of the GNU Lesser General Public License "or any later version"
|
||||||
|
applies to it, you have the option of following the terms and
|
||||||
|
conditions either of that published version or of any later version
|
||||||
|
published by the Free Software Foundation. If the Library as you
|
||||||
|
received it does not specify a version number of the GNU Lesser
|
||||||
|
General Public License, you may choose any version of the GNU Lesser
|
||||||
|
General Public License ever published by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Library as you received it specifies that a proxy can decide
|
||||||
|
whether future versions of the GNU Lesser General Public License shall
|
||||||
|
apply, that proxy's public statement of acceptance of any version is
|
||||||
|
permanent authorization for you to choose that version for the
|
||||||
|
Library.
|
||||||
141
cmake/FindCD.cmake
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
#[[
|
||||||
|
|
||||||
|
Create imported targets:
|
||||||
|
* QAD::Utils
|
||||||
|
* QAD::Widgets
|
||||||
|
* QAD::Application
|
||||||
|
* QAD::Blockview
|
||||||
|
* QAD::Graphic
|
||||||
|
* QAD::SQLTable
|
||||||
|
* QAD::TouchWidgets
|
||||||
|
* QAD::Doc
|
||||||
|
* QAD::PIQt
|
||||||
|
* QAD::PIQtUtils
|
||||||
|
|
||||||
|
These targets include directories and dependencies
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
cmake_policy(SET CMP0011 NEW) # don`t affect includer policies
|
||||||
|
cmake_policy(SET CMP0020 NEW) # Automatically link Qt executables to qtmain target on Windows
|
||||||
|
if(NOT BUILDING_qad)
|
||||||
|
find_package(PIP QUIET)
|
||||||
|
include(QtWraps)
|
||||||
|
include(SHSTKMacros)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
shstk_is_parent_exists(hasParent PARENT_DIRECTORY)
|
||||||
|
set(_SEARCH_DIR)
|
||||||
|
if(WIN32)
|
||||||
|
find_package(MinGW REQUIRED)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
shstk_set_find_dirs(qad)
|
||||||
|
|
||||||
|
if (NOT BUILDING_qad)
|
||||||
|
|
||||||
|
find_file(QAD_H_INCLUDE "qad_types.h" HINTS ${PIP_DIR}/include/qad ${qad_INCDIR} $ENV{SMSDK_DIR}/include/qad)
|
||||||
|
#if (DEFINED ANDROID_PLATFORM)
|
||||||
|
# set(QAD_INCLUDES ${ANDROID_SYSTEM_LIBRARY_PATH}/usr/include/qad)
|
||||||
|
#else()
|
||||||
|
get_filename_component(QAD_INCLUDES ${QAD_H_INCLUDE} PATH)
|
||||||
|
#endif()
|
||||||
|
set(_SEARCH_DIR ${qad_LIBDIR} $ENV{SMSDK_DIR}/lib)
|
||||||
|
shstk_find_header(QAD "qad_version.h" "")
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(QAD_FIND_VERSION VERSION_GREATER QAD_VERSION)
|
||||||
|
message(FATAL_ERROR "QAD version ${QAD_VERSION} is available, but ${QAD_FIND_VERSION} requested!")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(__libs "utils;widgets;application;blockview;graphic;sql_table;touch_widgets;doc")
|
||||||
|
if (PIP_FOUND OR BUILDING_pip)
|
||||||
|
list(APPEND __libs "piqt;piqt_utils")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(__module_utils Utils )
|
||||||
|
set(__module_widgets Widgets )
|
||||||
|
set(__module_application Application )
|
||||||
|
set(__module_blockview Blockview )
|
||||||
|
set(__module_graphic Graphic )
|
||||||
|
set(__module_sql_table SQLTable )
|
||||||
|
set(__module_touch_widgets TouchWidgets )
|
||||||
|
set(__module_doc Doc )
|
||||||
|
set(__module_piqt PIQt )
|
||||||
|
set(__module_piqt_utils PIQtUtils )
|
||||||
|
|
||||||
|
foreach (_l ${__libs})
|
||||||
|
set( __inc_${_l} "")
|
||||||
|
set(__deps_${_l} "")
|
||||||
|
set(__libs_${_l} "")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
set(__deps_widgets "QAD::Utils")
|
||||||
|
set(__deps_application "QAD::Widgets")
|
||||||
|
set(__deps_blockview "QAD::Widgets")
|
||||||
|
set(__deps_graphic "QAD::Widgets")
|
||||||
|
set(__deps_sql_table "QAD::Widgets")
|
||||||
|
set(__deps_piqt "QAD::Widgets;PIP")
|
||||||
|
set(__deps_piqt_utils "QAD::Blockview;QAD::PIQt")
|
||||||
|
|
||||||
|
#message("find QAD ${BUILDING_qad}")
|
||||||
|
|
||||||
|
if (BUILDING_qad)
|
||||||
|
|
||||||
|
if (NOT SET_TARGETS_qad)
|
||||||
|
set(SET_TARGETS_qad ON CACHE BOOL "")
|
||||||
|
#message("create aliases")
|
||||||
|
foreach(_l ${__libs})
|
||||||
|
foreach(_v ${_QT_VERSIONS_})
|
||||||
|
set(_m ${__module_${_l}})
|
||||||
|
string(REPLACE ":" "_" _m_str "${_m}")
|
||||||
|
if((NOT TARGET QAD::${_m}${_v}) AND TARGET qad_${_l}${_v})
|
||||||
|
#message("alias QAD::${_m}${_v} = qad_${_l}${_v}")
|
||||||
|
set(MULTILIB_qad_${_l}_SUFFIX_Qt${_v} ${_v} CACHE STRING "")
|
||||||
|
add_library(QAD::${_m}${_v} ALIAS qad_${_l}${_v})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
list(APPEND QT_MULTILIB_LIST QAD::${_m})
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(QAD_FOUND ON CACHE BOOL "")
|
||||||
|
|
||||||
|
else()
|
||||||
|
|
||||||
|
#message("create interfaces")
|
||||||
|
foreach(_l ${__libs})
|
||||||
|
foreach(_v ${_QT_VERSIONS_})
|
||||||
|
set(_m ${__module_${_l}})
|
||||||
|
string(REPLACE ":" "_" _m_str "${_m}")
|
||||||
|
find_library(QAD_LIBRARY_${_l}${_v} qad_${_l}${_v} HINTS ${qad_LIBDIR})
|
||||||
|
#message("found ${_l}${_v} = ${QAD_LIBRARY_${_l}${_v}}")
|
||||||
|
if((NOT TARGET QAD::${_m}${_v}) AND QAD_LIBRARY_${_l}${_v})
|
||||||
|
#message("imported QAD::${_m}${_v} = ${QAD_LIBRARY_${_l}${_v}}")
|
||||||
|
set(MULTILIB_qad_${_l}_SUFFIX_Qt${_v} ${_v} CACHE STRING "")
|
||||||
|
add_library(QAD::${_m}${_v} UNKNOWN IMPORTED)
|
||||||
|
set(_deps)
|
||||||
|
foreach (_d ${__deps_${_l}})
|
||||||
|
if (${_d} MATCHES "QAD::*")
|
||||||
|
list(APPEND _deps ${_d}${_v})
|
||||||
|
else()
|
||||||
|
list(APPEND _deps ${_d})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
set_target_properties(QAD::${_m}${_v} PROPERTIES
|
||||||
|
IMPORTED_LOCATION "${QAD_LIBRARY_${_l}${_v}}"
|
||||||
|
INTERFACE_INCLUDE_DIRECTORIES "${QAD_INCLUDES}"
|
||||||
|
INTERFACE_LINK_LIBRARIES "${_deps}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
list(APPEND QT_MULTILIB_LIST QAD::${_m})
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(hasParent)
|
||||||
|
set(QT_MULTILIB_LIST ${QT_MULTILIB_LIST} PARENT_SCOPE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(QAD_FOUND ON CACHE BOOL "")
|
||||||
1
libs/CMakeLists.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
add_directories_with_include("qad_")
|
||||||
37
libs/cd_utils/CMakeLists.txt
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
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()
|
||||||
10
libs/cd_utils/cdtest.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef CDTEST_H
|
||||||
|
#define CDTEST_H
|
||||||
|
|
||||||
|
|
||||||
|
enum KDescription {
|
||||||
|
First, //f Первый
|
||||||
|
Second, //b Второй
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CDTEST_H
|
||||||
41
libs/cd_utils/cdutils_c.cpp
Normal file
@@ -0,0 +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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
46
libs/cd_utils/cdutils_c.h
Normal file
@@ -0,0 +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"
|
||||||
|
#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
|
||||||
606
libs/cd_utils/cdutils_core.cpp
Normal file
@@ -0,0 +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);
|
||||||
|
}
|
||||||
|
|
||||||
147
libs/cd_utils/cdutils_core.h
Normal file
@@ -0,0 +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"
|
||||||
|
#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
|
||||||
217
libs/cd_utils/cdutils_interface.cpp
Normal file
@@ -0,0 +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);
|
||||||
|
}
|
||||||
96
libs/cd_utils/cdutils_interface.h
Normal file
@@ -0,0 +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"
|
||||||
|
#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
|
||||||
20
libs/cd_utils/cdutils_k.cpp
Normal file
@@ -0,0 +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));
|
||||||
|
}
|
||||||
47
libs/cd_utils/cdutils_k.h
Normal file
@@ -0,0 +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"
|
||||||
|
#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
|
||||||
22
libs/cd_utils/cdutils_m.cpp
Normal file
@@ -0,0 +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);
|
||||||
|
}
|
||||||
56
libs/cd_utils/cdutils_m.h
Normal file
@@ -0,0 +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"
|
||||||
|
#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
|
||||||
196
libs/cd_utils/cdutils_parser.cpp
Normal file
@@ -0,0 +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);
|
||||||
|
}
|
||||||
39
libs/cd_utils/cdutils_parser.h
Normal file
@@ -0,0 +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
|
||||||
|
|
||||||
|
#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
|
||||||
73
libs/cd_utils/cdutils_protocol.h
Normal file
@@ -0,0 +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 "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
|
||||||
762
libs/cd_utils/cdutils_types.cpp
Normal file
@@ -0,0 +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;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
193
libs/cd_utils/cdutils_types.h
Normal file
@@ -0,0 +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"
|
||||||
|
#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
|
||||||
55
libs/cd_utils/cdutils_x.cpp
Normal file
@@ -0,0 +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();
|
||||||
|
}
|
||||||
57
libs/cd_utils/cdutils_x.h
Normal file
@@ -0,0 +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"
|
||||||
|
#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
|
||||||
97
libs/cd_utils/cdutilstest.cpp
Normal file
@@ -0,0 +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;
|
||||||
|
}
|
||||||
|
|
||||||
147
libs/cd_utils/k_description.h
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
#ifndef K_DESCRIPTION_H
|
||||||
|
#define K_DESCRIPTION_H
|
||||||
|
|
||||||
|
namespace KD {
|
||||||
|
|
||||||
|
enum Sections {
|
||||||
|
Startup,
|
||||||
|
Spectrometer,
|
||||||
|
Switch,
|
||||||
|
Formats,
|
||||||
|
Logs,
|
||||||
|
Detector,
|
||||||
|
CoreOutput,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum LogFormat {
|
||||||
|
Text, //b text
|
||||||
|
Binary, //b binary
|
||||||
|
};
|
||||||
|
|
||||||
|
enum LogType {
|
||||||
|
Data, //b write data logs
|
||||||
|
Spec, //b write spectrogram logs
|
||||||
|
ARINC, //b ARINC
|
||||||
|
};
|
||||||
|
|
||||||
|
enum KLogConfig {
|
||||||
|
// LogFormat = Formats
|
||||||
|
StartupWrite, //b
|
||||||
|
ApplyBinaryLogHeader, //b Apply settings under ID = 255 for binary log
|
||||||
|
MaximumWriteFrequency, //f Maximum frequency for log in Hz, or 0 for unlimited
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SwitchType {
|
||||||
|
BaySpec,
|
||||||
|
DiCon,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SpectrometerConnection {
|
||||||
|
TCP,
|
||||||
|
USB,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PeakSearchMode {
|
||||||
|
Left,
|
||||||
|
Max,
|
||||||
|
Right,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CoreMode {
|
||||||
|
ModeSpectrometer,
|
||||||
|
ModePlayer,
|
||||||
|
ModePeaks,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum KSpectrometer {
|
||||||
|
Connection, //e ${SpectrometerConnection}
|
||||||
|
Temperature_compensation, //b Use temperature sensor or default temperature witout compensation
|
||||||
|
Temperature_default, //f Default temperature using if compensation disabled
|
||||||
|
};
|
||||||
|
|
||||||
|
enum KSwitch {
|
||||||
|
Enabled, //b 0 or 1 Use optical switch or not
|
||||||
|
Wait, //n Delay after switching channel, ms
|
||||||
|
Autoscan, //e {0 - scan with our forces, 1 - SDK autoscan}
|
||||||
|
Autoscan_offset, //n Offset for SDK autoscan
|
||||||
|
Type, //e ${SwitchType}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum KDetector {
|
||||||
|
Threshold_Min, //f
|
||||||
|
Threshold_Max, //f
|
||||||
|
SideSize, //f
|
||||||
|
SideOffset, //f
|
||||||
|
PeaksSearch, //e ${PeakSearchMode}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum KCoreOutput {
|
||||||
|
SendSpectrum, //b Send spectrum data or empty vector
|
||||||
|
SendOnlyCurrentValue, //b Send current values or all stored in 20Hz
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CoreOutputChannel {
|
||||||
|
GUI,
|
||||||
|
SecGUI,
|
||||||
|
ThirdGUI,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum KDescription {
|
||||||
|
// KSpectrometer = Spectrometer
|
||||||
|
// KSwitch = Switch
|
||||||
|
// KDetector = Detector
|
||||||
|
// KCoreOutput[CoreOutputChannel] = CoreOutput
|
||||||
|
// KLogConfig[LogType] = Logs
|
||||||
|
Gratings_history, //n Gratings peak values history, count
|
||||||
|
Amplitude_history_size, //n Count of history values to calculate sensors amplitude
|
||||||
|
Fourier_enabled, //b Global fourier enable flag
|
||||||
|
Fourier_size, //n Size of fourier window, in counts
|
||||||
|
Fourier_YScale, //f scale for fourier amplitude
|
||||||
|
Fourier_Max_or_Density, //n 0 - Maximum in fourier window, 1 - Density of fourier window
|
||||||
|
Mode, //e ${CoreMode} Work mode
|
||||||
|
SynchronizationEnabled, //b When enabled, start logs and reset time when sync signal received
|
||||||
|
SynchronizationMode, //e {0 - disabled, 1 - new file, 2 - column in log}
|
||||||
|
LambdasAutoReset, //b Set lambdas_0 to grating values on first data receive
|
||||||
|
Gauss_size, //n
|
||||||
|
//Peak_max_offset, //f in pixels
|
||||||
|
//Peak_LF_coeff, //f 1. - no filtering
|
||||||
|
GratingOverloadMax, //n
|
||||||
|
GratingOverloadMin, //n
|
||||||
|
SendLED, //b Send to LED Arduino serial port current state
|
||||||
|
SynchronizationClearValues, //b clear gratings and sensors values and history on sync
|
||||||
|
PeaksModeFrequency, //f
|
||||||
|
PeaksModeAdditionNm_1, //f Addition nm to peaks in ModePeaks, channel 1
|
||||||
|
PeaksModeAdditionNm_2, //f Addition nm to peaks in ModePeaks, channel 2
|
||||||
|
PeaksModeAdditionNm_3, //f Addition nm to peaks in ModePeaks, channel 3
|
||||||
|
PeaksModeAdditionNm_4, //f Addition nm to peaks in ModePeaks, channel 4
|
||||||
|
};
|
||||||
|
|
||||||
|
enum XDescription {
|
||||||
|
// KSpectrometer = Spectrometer
|
||||||
|
// KSwitch = Switch
|
||||||
|
// KDetector = Detector
|
||||||
|
// KCoreOutput[CoreOutputChannel] = CoreOutput
|
||||||
|
// KLogConfig[LogType] = Logs
|
||||||
|
State, //b
|
||||||
|
Frequency, //n cur freq
|
||||||
|
//Fourier_enabled, //b Global fourier enable flag
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CDescription {
|
||||||
|
// KSpectrometer = Spectrometer
|
||||||
|
// KCoreOutput[CoreOutputChannel] = CoreOutput
|
||||||
|
// KLogConfig[LogType] = Logs
|
||||||
|
Halt, //b
|
||||||
|
Reboot, //n cur freq
|
||||||
|
Pause, //b Global fourier enable flag
|
||||||
|
};
|
||||||
|
|
||||||
|
enum MDescription {
|
||||||
|
Main, //b
|
||||||
|
Core, //s
|
||||||
|
Warnings, //b Global fourier enable flag
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // K_DESCRIPTION_H
|
||||||
1
libs/qcd_utils/CMakeLists.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
piqt_library(qcd_utils "Gui" "pip;qad_utils;qad_widgets;qad_graphic;cd_utils;piqt")
|
||||||
297
libs/qcd_utils/qcd_core.cpp
Normal file
@@ -0,0 +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;
|
||||||
|
}
|
||||||
97
libs/qcd_utils/qcd_core.h
Normal file
@@ -0,0 +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"
|
||||||
|
#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
|
||||||
40
libs/qcd_utils/qcd_graphic.cpp
Normal file
@@ -0,0 +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;
|
||||||
|
}
|
||||||
67
libs/qcd_utils/qcd_graphic.h
Normal file
@@ -0,0 +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>
|
||||||
|
#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
|
||||||
169
libs/qcd_utils/qcd_graphic.ui
Normal file
@@ -0,0 +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::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>
|
||||||
46
libs/qcd_utils/qcd_modedialog.cpp
Normal file
@@ -0,0 +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);
|
||||||
|
}
|
||||||
51
libs/qcd_utils/qcd_modedialog.h
Normal file
@@ -0,0 +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>
|
||||||
|
#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
|
||||||
98
libs/qcd_utils/qcd_modedialog.ui
Normal file
@@ -0,0 +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>
|
||||||
460
libs/qcd_utils/qcd_model.cpp
Normal file
@@ -0,0 +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 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;
|
||||||
|
}
|
||||||
133
libs/qcd_utils/qcd_model.h
Normal file
@@ -0,0 +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"
|
||||||
|
#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
|
||||||
371
libs/qcd_utils/qcd_view.cpp
Normal file
@@ -0,0 +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)));
|
||||||
|
}
|
||||||
113
libs/qcd_utils/qcd_view.h
Normal file
@@ -0,0 +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 <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
|
||||||
1
utils/CMakeLists.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
add_directories("qad_")
|
||||||
14
utils/cd_pult/CMakeLists.txt
Normal 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()
|
||||||
312
utils/cd_pult/cddirectk.cpp
Normal file
@@ -0,0 +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();
|
||||||
|
}
|
||||||
77
utils/cd_pult/cddirectk.h
Normal file
@@ -0,0 +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
|
||||||
85
utils/cd_pult/cddirectk.ui
Normal file
@@ -0,0 +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>
|
||||||
76
utils/cd_pult/cddirectk_type_dialog.cpp
Normal file
@@ -0,0 +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();
|
||||||
|
}
|
||||||
44
utils/cd_pult/cddirectk_type_dialog.h
Normal file
@@ -0,0 +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
|
||||||
232
utils/cd_pult/cddirectk_type_dialog.ui
Normal file
@@ -0,0 +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>
|
||||||
354
utils/cd_pult/cdgraphics.cpp
Normal file
@@ -0,0 +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();
|
||||||
|
}
|
||||||
92
utils/cd_pult/cdgraphics.h
Normal file
@@ -0,0 +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
|
||||||
168
utils/cd_pult/cdgraphics.ui
Normal file
@@ -0,0 +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>
|
||||||
10
utils/cd_pult/cdpult.qrc
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/">
|
||||||
|
<file>icons/db-export.png</file>
|
||||||
|
<file>icons/db-import.png</file>
|
||||||
|
<file>icons/timer.png</file>
|
||||||
|
<file>icons/flame.png</file>
|
||||||
|
<file>icons/accessories-calculator.png</file>
|
||||||
|
<file>icons/accessories-text-editor.png</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
||||||
292
utils/cd_pult/cdpultwindow.cpp
Normal file
@@ -0,0 +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)));
|
||||||
|
}
|
||||||
53
utils/cd_pult/cdpultwindow.h
Normal file
@@ -0,0 +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
|
||||||
612
utils/cd_pult/cdpultwindow.ui
Normal file
@@ -0,0 +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>
|
||||||
78
utils/cd_pult/cdviewwidget.cpp
Normal file
@@ -0,0 +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);
|
||||||
|
}
|
||||||
41
utils/cd_pult/cdviewwidget.h
Normal file
@@ -0,0 +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
|
||||||
176
utils/cd_pult/cdviewwidget.ui
Normal file
@@ -0,0 +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>
|
||||||
BIN
utils/cd_pult/icons/accessories-calculator.png
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
BIN
utils/cd_pult/icons/accessories-text-editor.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
utils/cd_pult/icons/db-export.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
utils/cd_pult/icons/db-import.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
utils/cd_pult/icons/flame.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
utils/cd_pult/icons/pult.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
utils/cd_pult/icons/timer.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
373
utils/cd_pult/main.cpp
Normal file
@@ -0,0 +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) {
|
||||||
|
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();
|
||||||
|
}
|
||||||