diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b57c6b..275f12c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,15 +9,81 @@ project(libs) set(PIP_CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/pip/cmake") set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" "${PIP_CMAKE_MODULE_PATH}" "${CMAKE_CURRENT_SOURCE_DIR}/qad/cmake") set(LIBPROJECT 1) +set(_qt_libs ) +set(_qt_apps ) +set(_qt_plugs) include(GenerateExportHeader) include(SDKMacros) +include(QADMacros) include(DeployMacros) + if(NOT DEFINED BUILD_NUMBER) set(BUILD_NUMBER 9999) endif() if("x${BUILD_NUMBER}" STREQUAL "x") set(BUILD_NUMBER 0) endif() + + +if(STATIC_LIB) + set(QAD_LIB_TYPE STATIC) + add_definitions(-DQAD_STATIC_DEFINE) + set(QAD_LIB_TYPE_MSG "Static") +else() + set(QAD_LIB_TYPE SHARED) + set(QAD_LIB_TYPE_MSG "Shared") +endif() + +set(_QAD_MAJOR 1) +set(_QAD_MINOR 9) +set(_QAD_REVISION 0) +set(_QAD_SUFFIX ) +set(_QAD_COMPANY SHS) +set(_QAD_DOMAIN org.SHS) +set(QAD_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/qad/qad_version.h") +set_version(QAD + MAJOR "${_QAD_MAJOR}" + MINOR "${_QAD_MINOR}" + REVISION "${_QAD_REVISION}" + BUILD "${BUILD_NUMBER}" + SUFFIX "${_QAD_SUFFIX}" + OUTPUT "${QAD_VERSION_FILE}") +set_deploy_property(QAD ${QAD_LIB_TYPE} + FULLNAME "${_QAD_DOMAIN}.*" + COMPANY "${_QAD_COMPANY}") + + +if(STATIC_LIB) + set(PIQt_LIB_TYPE STATIC) + add_definitions(-DPIQt_STATIC_DEFINE) + set(PIQt_LIB_TYPE_MSG "Static") +else() + set(PIQt_LIB_TYPE SHARED) + set(PIQt_LIB_TYPE_MSG "Shared") +endif() + +set(_PIQt_MAJOR 1) +set(_PIQt_MINOR 0) +set(_PIQt_REVISION 0) +set(_PIQt_SUFFIX ) +set(_PIQt_COMPANY SHS) +set(_PIQt_DOMAIN org.SHS) +if(NOT DEFINED BUILD_NUMBER) + set(BUILD_NUMBER 9999) +endif() +set(PIQt_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/piqt/piqt_version.h") +set_version(PIQt + MAJOR "${_PIQt_MAJOR}" + MINOR "${_PIQt_MINOR}" + REVISION "${_PIQt_REVISION}" + BUILD "${BUILD_NUMBER}" + SUFFIX "${_PIQt_SUFFIX}" + OUTPUT "${PIQt_VERSION_FILE}") +set_deploy_property(PIQt ${_PIQt_LIB_TYPE} + FULLNAME "${_PIQt_DOMAIN}.*" + COMPANY "${_PIQt_COMPANY}") + + include_directories(${CMAKE_CURRENT_BINARY_DIR}/pip) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/qad) include_directories(${CMAKE_CURRENT_BINARY_DIR}/piqt) @@ -141,11 +207,11 @@ else() endif() endforeach() - if(UTILS) - message(STATUS "Building with utils") - else() - message(STATUS "Building only libraries") - endif() + #if(UTILS) + # message(STATUS "Building with utils") + #else() + # message(STATUS "Building only libraries") + #endif() add_subdirectory(pip) foreach(F ${PIP_MAIN_FOLDERS}) @@ -155,7 +221,7 @@ else() include_directories("${CMAKE_CURRENT_SOURCE_DIR}/cd_utils" "${CMAKE_CURRENT_BINARY_DIR}/cd_utils") set(_DIRS) if (SomeQtFound) - message(STATUS "Building Qt-derived targets for ${QtVersions}") + #message(STATUS "Building Qt-derived targets for ${QtVersions}") add_subdirectory(qad) include_directories(${qad_includes}) add_subdirectory(piqt) @@ -173,6 +239,52 @@ else() list(APPEND QT_MULTILIB_LIST ${_D}) add_subdirectory(${_D}) endforeach(_D) + + macro(align_list _list _out) + set(_max_len 0) + foreach(_m ${_list}) + string(LENGTH "${_m}" _clen) + if (_clen GREATER _max_len) + set(_max_len ${_clen}) + endif() + endforeach() + set(${_out}) + foreach(_m ${_list}) + set(_am "${_m}") + while(TRUE) + string(LENGTH "${_am}" _clen) + if (_clen GREATER_EQUAL ${_max_len}) + break() + endif() + string(APPEND _am " ") + endwhile() + list(APPEND ${_out} "${_am}") + endforeach() + endmacro() + + macro(print_list _list _name) + if (NOT "x${_list}" STREQUAL "x") + message("") + message(" ${_name}:") + #align_list("${_list}" _alist) + foreach(_m ${_list}) + message(" * ${_m}") + endforeach() + endif() + endmacro() + + message("----------QAD-----------") + message(" Build for ${QtVersions}") + message(" QAD Version: ${QAD_VERSION}") + message(" QAD Linkage: ${QAD_LIB_TYPE_MSG}") + message(" PIQt Version: ${PIQt_VERSION}") + message(" PIQt Linkage: ${PIQt_LIB_TYPE_MSG}") + print_list("${_qt_libs}" "Libraries") + print_list("${_qt_apps}" "Applications") + print_list("${_qt_plugs}" "Plugins") + message("-----------------------") + message("") + else() message(STATUS "None of Qt found, skip Qt-derived targets") endif() diff --git a/SDKMacros.cmake b/SDKMacros.cmake index 73f89a7..bdf5a8b 100644 --- a/SDKMacros.cmake +++ b/SDKMacros.cmake @@ -1,99 +1,107 @@ - -macro(sdk_install _DIR IS_APP _TARGET _H_FILES _QM_FILES) - #message("QM=${_QM_FILES}") - if((NOT ${IS_APP}) AND (NOT "${_H_FILES}" STREQUAL "")) - if(LIB) - if(WIN32) - install(FILES ${_H_FILES} DESTINATION ${MINGW_INCLUDE}/${_DIR}) - else() - install(FILES ${_H_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/${_DIR}) - endif() - else() - install(FILES ${_H_FILES} DESTINATION include/${_DIR}) - endif() - endif() - if (NOT "${_TARGET}" STREQUAL "") - if(LIB) - if(WIN32) - if (${IS_APP}) - qt_install(TARGETS ${_TARGET} DESTINATION ${MINGW_BIN}) - qt_install(TARGETS ${_TARGET} DESTINATION QtBin) - else() - qt_install(TARGETS ${_TARGET} ARCHIVE DESTINATION ${MINGW_LIB}) - qt_install(TARGETS ${_TARGET} RUNTIME DESTINATION ${MINGW_BIN}) - qt_install(TARGETS ${_TARGET} RUNTIME DESTINATION QtBin) - endif() - else() - if (${IS_APP}) - qt_install(TARGETS ${_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) - else() - qt_install(TARGETS ${_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) - endif() - endif() - if(NOT "x${_QM_FILES}" STREQUAL "x") - qt_install(LANG ${_QM_FILES} DESTINATION QtLang) - endif() - else() - if(${IS_APP}) - qt_install(TARGETS ${_TARGET} DESTINATION bin) - else() - if(WIN32) - qt_install(TARGETS ${_TARGET} RUNTIME DESTINATION bin) - qt_install(TARGETS ${_TARGET} ARCHIVE DESTINATION lib) - else() - qt_install(TARGETS ${_TARGET} DESTINATION lib) - endif() - endif() - if(NOT "x${_QM_FILES}" STREQUAL "x") - qt_install(LANG ${_QM_FILES} DESTINATION lang) - endif() - endif() - endif() -endmacro() - - -macro(add_directories_with_include multilib_prefix) - set(DIRS) - file(GLOB _dl "[^.]*") - foreach(_d ${_dl}) - if(IS_DIRECTORY ${_d}) - list(APPEND DIRS ${_d}) - endif() - endforeach() - - set(inc_var ${multilib_prefix}includes) - set(${inc_var}) - foreach(_d ${DIRS}) - get_filename_component(_dname "${_d}" NAME) - list(APPEND QT_MULTILIB_LIST ${multilib_prefix}${_dname}) - list(APPEND ${inc_var} "${_d}") - list(APPEND ${inc_var} "${CMAKE_CURRENT_BINARY_DIR}/${_dname}") - endforeach() - - include_directories(${${inc_var}}) - foreach(_d ${DIRS}) - add_subdirectory(${_d}) - endforeach() - - set(QT_MULTILIB_LIST ${QT_MULTILIB_LIST} PARENT_SCOPE) - set(${inc_var} ${${inc_var}} PARENT_SCOPE) - if (LIB) - set(_ALL_TARGETS ${_ALL_TARGETS} PARENT_SCOPE) - endif() -endmacro() - - -macro(add_directories multilib_prefix) - include_directories(${${multilib_prefix}includes}) - file(GLOB _dl "[^.]*") - foreach(_d ${_dl}) - if(IS_DIRECTORY ${_d}) - add_subdirectory(${_d}) - endif() - endforeach() - - if (LIB) - set(_ALL_TARGETS ${_ALL_TARGETS} PARENT_SCOPE) - endif() -endmacro() - + +macro(sdk_install _DIR IS_APP _TARGET _H_FILES _QM_FILES) + #message("QM=${_QM_FILES}") + if((NOT ${IS_APP}) AND (NOT "${_H_FILES}" STREQUAL "")) + if(LIB) + if(WIN32) + install(FILES ${_H_FILES} DESTINATION ${MINGW_INCLUDE}/${_DIR}) + else() + install(FILES ${_H_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/${_DIR}) + endif() + else() + install(FILES ${_H_FILES} DESTINATION include/${_DIR}) + endif() + endif() + if (NOT "${_TARGET}" STREQUAL "") + if(LIB) + if(WIN32) + if (${IS_APP}) + qt_install(TARGETS ${_TARGET} DESTINATION ${MINGW_BIN}) + qt_install(TARGETS ${_TARGET} DESTINATION QtBin) + else() + qt_install(TARGETS ${_TARGET} ARCHIVE DESTINATION ${MINGW_LIB}) + qt_install(TARGETS ${_TARGET} RUNTIME DESTINATION ${MINGW_BIN}) + qt_install(TARGETS ${_TARGET} RUNTIME DESTINATION QtBin) + endif() + else() + if (${IS_APP}) + qt_install(TARGETS ${_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) + else() + qt_install(TARGETS ${_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) + endif() + endif() + if(NOT "x${_QM_FILES}" STREQUAL "x") + qt_install(LANG ${_QM_FILES} DESTINATION QtLang) + endif() + else() + if(${IS_APP}) + qt_install(TARGETS ${_TARGET} DESTINATION bin) + else() + if(WIN32) + qt_install(TARGETS ${_TARGET} RUNTIME DESTINATION bin) + qt_install(TARGETS ${_TARGET} ARCHIVE DESTINATION lib) + else() + qt_install(TARGETS ${_TARGET} DESTINATION lib) + endif() + endif() + if(NOT "x${_QM_FILES}" STREQUAL "x") + qt_install(LANG ${_QM_FILES} DESTINATION lang) + endif() + endif() + endif() +endmacro() + + +macro(copy_to_parent _inc_var) + set(QT_MULTILIB_LIST ${QT_MULTILIB_LIST} PARENT_SCOPE) + set(_qt_libs ${_qt_libs} PARENT_SCOPE) + set(_qt_apps ${_qt_apps} PARENT_SCOPE) + set(_qt_plugs ${_qt_plugs} PARENT_SCOPE) + if (NOT "x${_inc_var}" STREQUAL "x") + set(${_inc_var} ${${_inc_var}} PARENT_SCOPE) + endif() + if (LIB) + set(_ALL_TARGETS ${_ALL_TARGETS} PARENT_SCOPE) + endif() +endmacro() + + +macro(add_directories_with_include multilib_prefix) + set(DIRS) + file(GLOB _dl "[^.]*") + foreach(_d ${_dl}) + if(IS_DIRECTORY ${_d}) + list(APPEND DIRS ${_d}) + endif() + endforeach() + + set(inc_var ${multilib_prefix}includes) + set(${inc_var}) + foreach(_d ${DIRS}) + get_filename_component(_dname "${_d}" NAME) + list(APPEND QT_MULTILIB_LIST ${multilib_prefix}${_dname}) + list(APPEND ${inc_var} "${_d}") + list(APPEND ${inc_var} "${CMAKE_CURRENT_BINARY_DIR}/${_dname}") + endforeach() + + include_directories(${${inc_var}}) + foreach(_d ${DIRS}) + add_subdirectory(${_d}) + endforeach() + + copy_to_parent(${inc_var}) +endmacro() + + +macro(add_directories multilib_prefix) + include_directories(${${multilib_prefix}includes}) + file(GLOB _dl "[^.]*") + foreach(_d ${_dl}) + if(IS_DIRECTORY ${_d}) + add_subdirectory(${_d}) + endif() + endforeach() + + copy_to_parent(${multilib_prefix}includes) +endmacro() + diff --git a/cd_utils/CMakeLists.txt b/cd_utils/CMakeLists.txt index f1c6a5d..e399d88 100644 --- a/cd_utils/CMakeLists.txt +++ b/cd_utils/CMakeLists.txt @@ -1,37 +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() +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() diff --git a/cd_utils/cdtest.h b/cd_utils/cdtest.h index c2e45d6..f707548 100644 --- a/cd_utils/cdtest.h +++ b/cd_utils/cdtest.h @@ -1,10 +1,10 @@ -#ifndef CDTEST_H -#define CDTEST_H - - -enum KDescription { - First, //f Первый - Second, //b Второй -}; - -#endif // CDTEST_H +#ifndef CDTEST_H +#define CDTEST_H + + +enum KDescription { + First, //f Первый + Second, //b Второй +}; + +#endif // CDTEST_H diff --git a/cd_utils/cdutils_c.cpp b/cd_utils/cdutils_c.cpp index 30a5fae..6ff28ac 100644 --- a/cd_utils/cdutils_c.cpp +++ b/cd_utils/cdutils_c.cpp @@ -1,41 +1,41 @@ -#include "cdutils_c.h" -#include "cdutils_core.h" - -using namespace CDUtils; - -CInterface C; - - -CInterface::CInterface(): Interface(CDType::cdC) { -} - - -void CInterface::sendCommand(const CDType & c) { - core->sendCommand(c); -} - - -void CInterface::connect(const CDType & c, PIObject * o, Handler eh) { - core->registerCHandler(c, o, eh); -} - - -void CInterface::autoConnect(PIObject * o, const PIString & prefix) { - if (!o) return; - uint cid = o->classNameID(); - if (!PIObject::__meta_data().contains(cid)) return; - PIMap eh_map; - PIObject::__MetaData & md(PIObject::__meta_data()[cid]); - PIMap::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 cl = C.root().children(); - piForeachC (CDType * c, cl) { - PIString cp = prefix + c->pathString().join("_"); - if (cp.isEmpty()) continue; - if (!eh_map.contains(cp)) continue; - connect(*c, o, eh_map[cp]); - } -} +#include "cdutils_c.h" +#include "cdutils_core.h" + +using namespace CDUtils; + +CInterface C; + + +CInterface::CInterface(): Interface(CDType::cdC) { +} + + +void CInterface::sendCommand(const CDType & c) { + core->sendCommand(c); +} + + +void CInterface::connect(const CDType & c, PIObject * o, Handler eh) { + core->registerCHandler(c, o, eh); +} + + +void CInterface::autoConnect(PIObject * o, const PIString & prefix) { + if (!o) return; + uint cid = o->classNameID(); + if (!PIObject::__meta_data().contains(cid)) return; + PIMap eh_map; + PIObject::__MetaData & md(PIObject::__meta_data()[cid]); + PIMap::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 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]); + } +} diff --git a/cd_utils/cdutils_c.h b/cd_utils/cdutils_c.h index a517e8c..80082f9 100644 --- a/cd_utils/cdutils_c.h +++ b/cd_utils/cdutils_c.h @@ -1,46 +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 . -*/ - -#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 +/* + 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 . +*/ + +#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 diff --git a/cd_utils/cdutils_core.cpp b/cd_utils/cdutils_core.cpp index c03c327..685694d 100644 --- a/cd_utils/cdutils_core.cpp +++ b/cd_utils/cdutils_core.cpp @@ -1,606 +1,606 @@ -#include "cdutils_core.h" -#include "cdutils_parser.h" -#include "piconfig.h" -#include "piiobytearray.h" -#include "piiostring.h" -#include "pifile.h" - -using namespace CDUtils; - -const char CDCore::app_config[] = - "include = cd_ip.conf\n\ - port_rec = 2\n\ - port_send = 1\n\ - [connection]\n\ - device.cd = peer://cd_app:cd_pult #s\n\ - []\n\ - connectionmodel = AAAM2Xja7VXLTttAFD12QpsikKjUSixYlLbKEpIUtVIlVEfqhk2FWuiGRRolUYtoHgrmpYiv6IItf8AveMMH9E/YsG6Ph3sde5hGoQoblLGuPHfunTPjc49nADxDA110+LTYC7FrPCAPeAO+vZu+aX7c/8PGd45WCJC0OGcfT6FDnmfSTPtwhZFt3HjgDs/Qtu5jPbZHtI/x50XfIzMQbdwEolbg9INP4ku++myPaUtCHYRaT2j1ldIh3VP60/Qff8vSfXLu9BP6JX9K/0TVH6jqVe22P1X/fao/oddWu/paDs1vBf9Jv/EZ91clbyHqv7BL6sscDOd4v4WTqs6jzaHGJ8QJerxlpJSpdZ7IWFJvDW7I2JxZqIM62k6A57RZmMQGmlyrxdV+WGBnmR01mXPI267hBKwp4FeBeo9VPtssxyb7rzHg1B7T9nCMU45U8BZlWuVWtIcD/CRGOqtsbW09851tXsHN0UTlLIAdASjSXnLyLn+H7L2+xbGYvC63Ezqg543egkLmn8qnRF6USbM4Qp9godkhzI777Ne5bCIt/5UtGz2o/yGby0nKpjqmbOa1ynkjmyzIrzvIZUeBPjvlUmbh32EFJbGyJZhR8YcvlS+3TpjhqeWSyvUkpbI9plSWtcKLcsK05beOJVEnhaEFfHEH+RwpeMcpn1JKGqWMNOL+G6wZyahlpdVOtufKfbDS+guLke9O\n\ - "; - -const char CDCore::pult_config[] = - "include = cd_ip.conf\n\ - port_rec = 1\n\ - port_send = 2\n\ - [connection]\n\ - device.cd = peer://cd_pult:cd_app #s\n\ - []\n\ - connectionmodel = AAAM2Xja7VXLTttAFD12QpsikKjUSixYlLbKEpIUtVIlVEfqhk2FWuiGRRolUYtoHgrmpYiv6IItf8AveMMH9E/YsG6Ph3sde5hGoQoblLGuPHfunTPjc49nADxDA110+LTYC7FrPCAPeAO+vZu+aX7c/8PGd45WCJC0OGcfT6FDnmfSTPtwhZFt3HjgDs/Qtu5jPbZHtI/x50XfIzMQbdwEolbg9INP4ku++myPaUtCHYRaT2j1ldIh3VP60/Qff8vSfXLu9BP6JX9K/0TVH6jqVe22P1X/fao/oddWu/paDs1vBf9Jv/EZ91clbyHqv7BL6sscDOd4v4WTqs6jzaHGJ8QJerxlpJSpdZ7IWFJvDW7I2JxZqIM62k6A57RZmMQGmlyrxdV+WGBnmR01mXPI267hBKwp4FeBeo9VPtssxyb7rzHg1B7T9nCMU45U8BZlWuVWtIcD/CRGOqtsbW09851tXsHN0UTlLIAdASjSXnLyLn+H7L2+xbGYvC63Ezqg543egkLmn8qnRF6USbM4Qp9godkhzI777Ne5bCIt/5UtGz2o/yGby0nKpjqmbOa1ynkjmyzIrzvIZUeBPjvlUmbh32EFJbGyJZhR8YcvlS+3TpjhqeWSyvUkpbI9plSWtcKLcsK05beOJVEnhaEFfHEH+RwpeMcpn1JKGqWMNOL+G6wZyahlpdVOtufKfbDS+guLke9O\n\ - "; - - -int __Core_Initializer__::count_(0); -CDCore * __Core_Initializer__::__instance__(0); -const uchar header_direct = 0x80; -const uchar header_transfer = 0x81; - - -__Core_Initializer__::__Core_Initializer__() { - count_++; - if (count_ > 1) return; - __instance__ = new CDCore(); -} - - -__Core_Initializer__::~__Core_Initializer__() { - count_--; - if (count_ < 0) { - count_ = 0; - return; - } - if (count_ > 0) return; - if (__instance__) { - delete __instance__; - __instance__ = 0; - } -} - - - - -CDCore::CDCore() { - setName("CDCore"); - x_timer.setName("__S__.CDCore.x_timer"); - datatr.setPacketSize(960); - CONNECTU(&connection, dataReceivedEvent, this, dataReceived); - CONNECTU(PICout::Notifier::object(), finished, this, piCoutFinished); - /*PIString s(app_config); - connection.configureFromString(&s); - connection.start();*/ - need_rebuild_x = x_pult_side = false; - k_.cd_type_ = CDType::cdK; - x_.cd_type_ = CDType::cdX; - c_.cd_type_ = CDType::cdC; - m_.cd_type_ = CDType::cdM; - initRoot(&k_); - initRoot(&x_); - initRoot(&c_); - initRoot(&m_); - - CONNECTU(&sendt, started, this, sendThread) - CONNECTU(&datatr, sendRequest, this, dtSendRequest) - CONNECTU(&datatr, receiveFinished, this, dtReceiveFinished) - CONNECTU(&x_timer, tickEvent, this, xTimerTick) - - /*k_[1] = KType(1, "123", "120+3", "comment"); - k_[2] = KType(2, "1", "2", "comm"); - k_[4] = KType(4, "-0.6", "-6/10", "mment"); - k_.section(10)[5] = KType(5, "8", "2*2*2", "88"); - k_.section(10).section(50)[100] = KType(100, "8", "2*2*2", "88"); - k_.section(11)[3] = KType(3, "1", "1", "88"); - k_.section(11)[4] = KType(4, "0", "0", "88"); - k_.section(11)[6] = KType(6, "0", "0", "88");*/ - //piCout << s; -} - - -CDCore::~CDCore() { - x_timer.stop(true); - datatr.stop(); - sendt.stop(); - sendt.waitForFinish(10); - connection.stop(); -} - - -void CDCore::cd_write(CDSection * cd, PIIODevice * d) { - cd->write(d, PIString()); -} - - -void CDCore::cd_read(CDSection * cd, PIIODevice * d) { - PIConfig conf(d, PIIODevice::ReadOnly); - cd->read(&(conf.rootEntry())); - if (cd->cd_type_ == CDType::cdX) - x_selected = cd->collectX(); - initRoot(cd); - raiseChangedGlobal(cd->cd_type_); - /*PIVector 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 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 & 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 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 & p, x_selected) { - x_[p].x_enabled = true; - } - x_mutex.unlock(); - } break; - case CD_XValues: { - if (!x_pult_side) break; - PIVector > x_vals; - ba >> x_vals; - x_mutex.lock(); - piForeachC (PIDeque & 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 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 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 & p) { - PIString ret; - for (int i = 0; i < p.size_s(); ++i) { - if (!ret.isEmpty()) ret += "."; - ret << p[i]; - } - return ret; -} - - -PIDeque CDCore::stringToPath(const PIString & p) { - PIDeque ret; - PIStringList sl = p.split("."); - piForeachC (PIString & s, sl) - ret << s.toInt(); - return ret; -} - - -void CDUtils::CDCore::dataReceived(const PIString & from, const PIByteArray & data) { - //piCoutObj << "dataReceived" << from << data.size(); - PIIODevice * d = connection.deviceByName("cd"); - if (d && d == connection.deviceByFullPath(from)) { - if (data.size() >= sizeof(4)) { - PIByteArray ba = data; - uchar header = ba.take_front(); - if (header == header_transfer) { - datatr.received(ba); - } - if (header == header_direct) { - procReceivedPacket(ba); - } - } - } -} - - -void CDCore::dtSendRequest(PIByteArray & data) { - data.push_front(header_transfer); - connection.writeByName("cd", data); - //piCoutObj << "send" << data.size() << ret; -} - - -void CDCore::dtReceiveFinished(bool ok) { - if (!ok) return; - PIByteArray ba = datatr.data(); - procReceivedPacket(ba); -} - +#include "cdutils_core.h" +#include "cdutils_parser.h" +#include "piconfig.h" +#include "piiobytearray.h" +#include "piiostring.h" +#include "pifile.h" + +using namespace CDUtils; + +const char CDCore::app_config[] = + "include = cd_ip.conf\n\ + port_rec = 2\n\ + port_send = 1\n\ + [connection]\n\ + device.cd = peer://cd_app:cd_pult #s\n\ + []\n\ + connectionmodel = AAAM2Xja7VXLTttAFD12QpsikKjUSixYlLbKEpIUtVIlVEfqhk2FWuiGRRolUYtoHgrmpYiv6IItf8AveMMH9E/YsG6Ph3sde5hGoQoblLGuPHfunTPjc49nADxDA110+LTYC7FrPCAPeAO+vZu+aX7c/8PGd45WCJC0OGcfT6FDnmfSTPtwhZFt3HjgDs/Qtu5jPbZHtI/x50XfIzMQbdwEolbg9INP4ku++myPaUtCHYRaT2j1ldIh3VP60/Qff8vSfXLu9BP6JX9K/0TVH6jqVe22P1X/fao/oddWu/paDs1vBf9Jv/EZ91clbyHqv7BL6sscDOd4v4WTqs6jzaHGJ8QJerxlpJSpdZ7IWFJvDW7I2JxZqIM62k6A57RZmMQGmlyrxdV+WGBnmR01mXPI267hBKwp4FeBeo9VPtssxyb7rzHg1B7T9nCMU45U8BZlWuVWtIcD/CRGOqtsbW09851tXsHN0UTlLIAdASjSXnLyLn+H7L2+xbGYvC63Ezqg543egkLmn8qnRF6USbM4Qp9godkhzI777Ne5bCIt/5UtGz2o/yGby0nKpjqmbOa1ynkjmyzIrzvIZUeBPjvlUmbh32EFJbGyJZhR8YcvlS+3TpjhqeWSyvUkpbI9plSWtcKLcsK05beOJVEnhaEFfHEH+RwpeMcpn1JKGqWMNOL+G6wZyahlpdVOtufKfbDS+guLke9O\n\ + "; + +const char CDCore::pult_config[] = + "include = cd_ip.conf\n\ + port_rec = 1\n\ + port_send = 2\n\ + [connection]\n\ + device.cd = peer://cd_pult:cd_app #s\n\ + []\n\ + connectionmodel = AAAM2Xja7VXLTttAFD12QpsikKjUSixYlLbKEpIUtVIlVEfqhk2FWuiGRRolUYtoHgrmpYiv6IItf8AveMMH9E/YsG6Ph3sde5hGoQoblLGuPHfunTPjc49nADxDA110+LTYC7FrPCAPeAO+vZu+aX7c/8PGd45WCJC0OGcfT6FDnmfSTPtwhZFt3HjgDs/Qtu5jPbZHtI/x50XfIzMQbdwEolbg9INP4ku++myPaUtCHYRaT2j1ldIh3VP60/Qff8vSfXLu9BP6JX9K/0TVH6jqVe22P1X/fao/oddWu/paDs1vBf9Jv/EZ91clbyHqv7BL6sscDOd4v4WTqs6jzaHGJ8QJerxlpJSpdZ7IWFJvDW7I2JxZqIM62k6A57RZmMQGmlyrxdV+WGBnmR01mXPI267hBKwp4FeBeo9VPtssxyb7rzHg1B7T9nCMU45U8BZlWuVWtIcD/CRGOqtsbW09851tXsHN0UTlLIAdASjSXnLyLn+H7L2+xbGYvC63Ezqg543egkLmn8qnRF6USbM4Qp9godkhzI777Ne5bCIt/5UtGz2o/yGby0nKpjqmbOa1ynkjmyzIrzvIZUeBPjvlUmbh32EFJbGyJZhR8YcvlS+3TpjhqeWSyvUkpbI9plSWtcKLcsK05beOJVEnhaEFfHEH+RwpeMcpn1JKGqWMNOL+G6wZyahlpdVOtufKfbDS+guLke9O\n\ + "; + + +int __Core_Initializer__::count_(0); +CDCore * __Core_Initializer__::__instance__(0); +const uchar header_direct = 0x80; +const uchar header_transfer = 0x81; + + +__Core_Initializer__::__Core_Initializer__() { + count_++; + if (count_ > 1) return; + __instance__ = new CDCore(); +} + + +__Core_Initializer__::~__Core_Initializer__() { + count_--; + if (count_ < 0) { + count_ = 0; + return; + } + if (count_ > 0) return; + if (__instance__) { + delete __instance__; + __instance__ = 0; + } +} + + + + +CDCore::CDCore() { + setName("CDCore"); + x_timer.setName("__S__.CDCore.x_timer"); + datatr.setPacketSize(960); + CONNECTU(&connection, dataReceivedEvent, this, dataReceived); + CONNECTU(PICout::Notifier::object(), finished, this, piCoutFinished); + /*PIString s(app_config); + connection.configureFromString(&s); + connection.start();*/ + need_rebuild_x = x_pult_side = false; + k_.cd_type_ = CDType::cdK; + x_.cd_type_ = CDType::cdX; + c_.cd_type_ = CDType::cdC; + m_.cd_type_ = CDType::cdM; + initRoot(&k_); + initRoot(&x_); + initRoot(&c_); + initRoot(&m_); + + CONNECTU(&sendt, started, this, sendThread) + CONNECTU(&datatr, sendRequest, this, dtSendRequest) + CONNECTU(&datatr, receiveFinished, this, dtReceiveFinished) + CONNECTU(&x_timer, tickEvent, this, xTimerTick) + + /*k_[1] = KType(1, "123", "120+3", "comment"); + k_[2] = KType(2, "1", "2", "comm"); + k_[4] = KType(4, "-0.6", "-6/10", "mment"); + k_.section(10)[5] = KType(5, "8", "2*2*2", "88"); + k_.section(10).section(50)[100] = KType(100, "8", "2*2*2", "88"); + k_.section(11)[3] = KType(3, "1", "1", "88"); + k_.section(11)[4] = KType(4, "0", "0", "88"); + k_.section(11)[6] = KType(6, "0", "0", "88");*/ + //piCout << s; +} + + +CDCore::~CDCore() { + x_timer.stop(true); + datatr.stop(); + sendt.stop(); + sendt.waitForFinish(10); + connection.stop(); +} + + +void CDCore::cd_write(CDSection * cd, PIIODevice * d) { + cd->write(d, PIString()); +} + + +void CDCore::cd_read(CDSection * cd, PIIODevice * d) { + PIConfig conf(d, PIIODevice::ReadOnly); + cd->read(&(conf.rootEntry())); + if (cd->cd_type_ == CDType::cdX) + x_selected = cd->collectX(); + initRoot(cd); + raiseChangedGlobal(cd->cd_type_); + /*PIVector 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 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 & 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 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 & p, x_selected) { + x_[p].x_enabled = true; + } + x_mutex.unlock(); + } break; + case CD_XValues: { + if (!x_pult_side) break; + PIVector > x_vals; + ba >> x_vals; + x_mutex.lock(); + piForeachC (PIDeque & 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 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 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 & p) { + PIString ret; + for (int i = 0; i < p.size_s(); ++i) { + if (!ret.isEmpty()) ret += "."; + ret << p[i]; + } + return ret; +} + + +PIDeque CDCore::stringToPath(const PIString & p) { + PIDeque 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); +} + diff --git a/cd_utils/cdutils_core.h b/cd_utils/cdutils_core.h index a0d4e79..d7c357f 100644 --- a/cd_utils/cdutils_core.h +++ b/cd_utils/cdutils_core.h @@ -1,147 +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 . -*/ - -#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, path, PIString, value); - - EVENT(X_Sended) - EVENT(X_SendFail) - EVENT(X_Received) - EVENT(X_ReceiveFail) - EVENT(X_ChangedGlobal) - EVENT1(X_ReceivedX, PIVector >, 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, 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 & p); - static PIDeque 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 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 > x_selected; - PIMap c_handlers; - bool need_rebuild_x, x_pult_side; - -}; - - -static __Core_Initializer__ __Core_initializer__; - -} - -#endif // CDUTILS_CORE_H +/* + CD Utils - Control-Debug utilites + + Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#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, path, PIString, value); + + EVENT(X_Sended) + EVENT(X_SendFail) + EVENT(X_Received) + EVENT(X_ReceiveFail) + EVENT(X_ChangedGlobal) + EVENT1(X_ReceivedX, PIVector >, 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, 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 & p); + static PIDeque 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 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 > x_selected; + PIMap c_handlers; + bool need_rebuild_x, x_pult_side; + +}; + + +static __Core_Initializer__ __Core_initializer__; + +} + +#endif // CDUTILS_CORE_H diff --git a/cd_utils/cdutils_interface.cpp b/cd_utils/cdutils_interface.cpp index a37d818..e1688c4 100644 --- a/cd_utils/cdutils_interface.cpp +++ b/cd_utils/cdutils_interface.cpp @@ -1,217 +1,217 @@ -#include "cdutils_interface.h" -#include "cdutils_core.h" -#include "piconfig.h" -#include "pifile.h" - -using namespace CDUtils; - - -Interface::Interface(CDType::cdT type_) { - core = CDCore::instance(); - s = core->root(type_); - type = type_; - //piCoutObj << (void*)this << core; - file_ = core->typeLetter(type_) + PIStringAscii(".dat"); - file_size = 0; - switch (type) { - case CDType::cdK: - CONNECTU(core, K_Sended, this, sended); - CONNECTU(core, K_SendFail, this, sendFailed); - CONNECTU(core, K_Received, this, received); - CONNECTU(core, K_ReceiveFail, this, receiveFailed); - CONNECTU(core, K_ChangedGlobal, this, changedGlobal); - break; - case CDType::cdX: - CONNECTU(core, X_Sended, this, sended); - CONNECTU(core, X_SendFail, this, sendFailed); - CONNECTU(core, X_Received, this, received); - CONNECTU(core, X_ReceiveFail, this, receiveFailed); - CONNECTU(core, X_ChangedGlobal, this, changedGlobal); - break; - case CDType::cdC: - CONNECTU(core, C_Sended, this, sended); - CONNECTU(core, C_SendFail, this, sendFailed); - CONNECTU(core, C_Received, this, received); - CONNECTU(core, C_ReceiveFail, this, receiveFailed); - CONNECTU(core, C_ChangedGlobal, this, changedGlobal); - break; - case CDType::cdM: - CONNECTU(core, M_Sended, this, sended); - CONNECTU(core, M_SendFail, this, sendFailed); - CONNECTU(core, M_Received, this, received); - CONNECTU(core, M_ReceiveFail, this, receiveFailed); - CONNECTU(core, M_ChangedGlobal, this, changedGlobal); - break; - default: break; - } -} - - -bool Interface::test(int v) { - return s->test(v); -} - - -CDType & Interface::operator [](const PIString & name_) { - return (*s)[name_]; -} - - -const CDType Interface::operator [](const PIString & name_) const { - return (*s)[name_]; -} - - -CDType & Interface::operator [](const PIDeque & path_) { - return (*s)[path_]; -} - - -const CDType Interface::operator [](const PIDeque & 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 &path) { - PIDeque 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 path) const { - return s->exists(path); -} - - -void Interface::setFileName(const PIString & _file) { - file_ = _file; -} - - -bool Interface::configure(const PIString & config) { - PIConfig conf(config, PIIODevice::ReadOnly); - PIConfig::Entry & e(conf.getValue(core->typeLetter(s->cd_type_))); - bool ret = false; - setFileName(e.getValue("file", file(), &ret).toString()); - return ret; -} - - -void Interface::reinitConnection(const PIString & configuration) { - core->init(configuration); -} - - -void Interface::releaseConnection() { - core->release(); -} - - -void Interface::write(PIIODevice * d) { - core->cd_write(s, d); -} - - -void Interface::read(PIIODevice * d) { - core->cd_read(s, d); -} - - -void Interface::parse(PIIODevice * d) { - core->cd_parse(s, d); -} - - -void Interface::update(PIIODevice * d, UpdateModeFlags mode) { - core->cd_update(s, d, mode); -} - - -void Interface::calculate() { - core->cd_calculate(s); -} - - -PIString Interface::appConfig() { - return core->appConfig(); -} - - -PIString Interface::pultConfig() { - return core->pultConfig(); -} - - -void Interface::readFile() { - if (file_.isEmpty()) return; - PIFile f(file_, PIIODevice::ReadOnly); - read(&f); - file_size = f.size(); -} - - -void Interface::writeFile() { - if (file_.isEmpty()) return; - PIFile f(file_, PIIODevice::ReadWrite); - f.clear(); - write(&f); - file_size = f.size(); -} - - -bool Interface::inProgress() { - return core->inProgress(); -} - - -void Interface::send() { - core->send(type); -} - - -void Interface::request() { - core->request(type); -} +#include "cdutils_interface.h" +#include "cdutils_core.h" +#include "piconfig.h" +#include "pifile.h" + +using namespace CDUtils; + + +Interface::Interface(CDType::cdT type_) { + core = CDCore::instance(); + s = core->root(type_); + type = type_; + //piCoutObj << (void*)this << core; + file_ = core->typeLetter(type_) + PIStringAscii(".dat"); + file_size = 0; + switch (type) { + case CDType::cdK: + CONNECTU(core, K_Sended, this, sended); + CONNECTU(core, K_SendFail, this, sendFailed); + CONNECTU(core, K_Received, this, received); + CONNECTU(core, K_ReceiveFail, this, receiveFailed); + CONNECTU(core, K_ChangedGlobal, this, changedGlobal); + break; + case CDType::cdX: + CONNECTU(core, X_Sended, this, sended); + CONNECTU(core, X_SendFail, this, sendFailed); + CONNECTU(core, X_Received, this, received); + CONNECTU(core, X_ReceiveFail, this, receiveFailed); + CONNECTU(core, X_ChangedGlobal, this, changedGlobal); + break; + case CDType::cdC: + CONNECTU(core, C_Sended, this, sended); + CONNECTU(core, C_SendFail, this, sendFailed); + CONNECTU(core, C_Received, this, received); + CONNECTU(core, C_ReceiveFail, this, receiveFailed); + CONNECTU(core, C_ChangedGlobal, this, changedGlobal); + break; + case CDType::cdM: + CONNECTU(core, M_Sended, this, sended); + CONNECTU(core, M_SendFail, this, sendFailed); + CONNECTU(core, M_Received, this, received); + CONNECTU(core, M_ReceiveFail, this, receiveFailed); + CONNECTU(core, M_ChangedGlobal, this, changedGlobal); + break; + default: break; + } +} + + +bool Interface::test(int v) { + return s->test(v); +} + + +CDType & Interface::operator [](const PIString & name_) { + return (*s)[name_]; +} + + +const CDType Interface::operator [](const PIString & name_) const { + return (*s)[name_]; +} + + +CDType & Interface::operator [](const PIDeque & path_) { + return (*s)[path_]; +} + + +const CDType Interface::operator [](const PIDeque & 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 &path) { + PIDeque 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 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); +} diff --git a/cd_utils/cdutils_interface.h b/cd_utils/cdutils_interface.h index 635ed1d..79f0aa1 100644 --- a/cd_utils/cdutils_interface.h +++ b/cd_utils/cdutils_interface.h @@ -1,96 +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 . -*/ - -#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 & path_); - const CDType operator [](const PIDeque & path_) const; - CDSection & section(int v); - const CDSection section(int v) const; - CDSection & section(const PIDeque & 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 path) const; - - void setFileName(const PIString & _file); - bool configure(const PIString & config); - void reinitConnection(const PIString & configuration); - void releaseConnection(); - void write(PIIODevice * d); - void read(PIIODevice * d); - void parse(PIIODevice * d); - void update(PIIODevice * d, UpdateModeFlags mode = SaveByName); - void calculate(); - - PIString appConfig(); - PIString pultConfig(); - - void readFile(); - void writeFile(); - bool inProgress(); - - EVENT(sended) - EVENT(sendFailed) - EVENT(received) - EVENT(receiveFailed) - EVENT(changedGlobal) - EVENT_HANDLER(void, send); - EVENT_HANDLER(void, request); - -protected: - CDCore * core; - CDSection * s; - CDType::cdT type; - PIString file_; - int file_size; - -}; - - -} - - -#endif // CDUTILS_INTERFACE_H +/* + CD Utils - Control-Debug utilites + + Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#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 & path_); + const CDType operator [](const PIDeque & path_) const; + CDSection & section(int v); + const CDSection section(int v) const; + CDSection & section(const PIDeque & 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 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 diff --git a/cd_utils/cdutils_k.cpp b/cd_utils/cdutils_k.cpp index 6ee850a..313a6fe 100644 --- a/cd_utils/cdutils_k.cpp +++ b/cd_utils/cdutils_k.cpp @@ -1,20 +1,20 @@ -#include "cdutils_k.h" -#include "cdutils_core.h" - -using namespace CDUtils; - -KInterface K; - - -KInterface::KInterface(): Interface(CDType::cdK) { -} - - -void KInterface::directChange(const CDType & k) { - core->K_DirectChange(k.path(), k.value()); -} - - -void KInterface::directChange(const CDType & k, double v) { - core->K_DirectChange(k.path(), PIString::fromNumber(v)); -} +#include "cdutils_k.h" +#include "cdutils_core.h" + +using namespace CDUtils; + +KInterface K; + + +KInterface::KInterface(): Interface(CDType::cdK) { +} + + +void KInterface::directChange(const CDType & k) { + core->K_DirectChange(k.path(), k.value()); +} + + +void KInterface::directChange(const CDType & k, double v) { + core->K_DirectChange(k.path(), PIString::fromNumber(v)); +} diff --git a/cd_utils/cdutils_k.h b/cd_utils/cdutils_k.h index a3190f1..e699f07 100644 --- a/cd_utils/cdutils_k.h +++ b/cd_utils/cdutils_k.h @@ -1,47 +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 . -*/ - -#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 +/* + 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 . +*/ + +#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 diff --git a/cd_utils/cdutils_m.cpp b/cd_utils/cdutils_m.cpp index cd326cd..95c4151 100644 --- a/cd_utils/cdutils_m.cpp +++ b/cd_utils/cdutils_m.cpp @@ -1,22 +1,22 @@ -#include "cdutils_m.h" -#include "cdutils_core.h" - -using namespace CDUtils; - -MInterface M; - - -MInterface::MInterface(): Interface(CDType::cdM) { - CONNECTU(core, M_Message, this, messageReceived); -} - - -void MInterface::messageBox(const CDType & m, const PIString & msg) { - core->sendMessage(m, MessageBox, msg); -} - - -PICout MInterface::createPICout(const CDType & m) const { - PIString * buff = new PIString("[" + CDCore::pathToString(m.path()) + "]"); - return PICout(buff, 1); -} +#include "cdutils_m.h" +#include "cdutils_core.h" + +using namespace CDUtils; + +MInterface M; + + +MInterface::MInterface(): Interface(CDType::cdM) { + CONNECTU(core, M_Message, this, messageReceived); +} + + +void MInterface::messageBox(const CDType & m, const PIString & msg) { + core->sendMessage(m, MessageBox, msg); +} + + +PICout MInterface::createPICout(const CDType & m) const { + PIString * buff = new PIString("[" + CDCore::pathToString(m.path()) + "]"); + return PICout(buff, 1); +} diff --git a/cd_utils/cdutils_m.h b/cd_utils/cdutils_m.h index 2585b66..9d9a00c 100644 --- a/cd_utils/cdutils_m.h +++ b/cd_utils/cdutils_m.h @@ -1,56 +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 . -*/ - -#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 & path_) {return createPICout((*s)[path_]);} - PICout operator [](const PIDeque & path_) const {return createPICout((*s)[path_]);} - - void messageBox(const CDType & m, const PIString & msg); - - EVENT3(messageReceived, PIDeque, path, int, type, PIString, msg) - -private: - PICout createPICout(const CDType & m) const; - -}; - -} - -extern CD_UTILS_EXPORT CDUtils::MInterface M; - -#endif // CDUTILS_M_H +/* + CD Utils - Control-Debug utilites + + Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#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 & path_) {return createPICout((*s)[path_]);} + PICout operator [](const PIDeque & path_) const {return createPICout((*s)[path_]);} + + void messageBox(const CDType & m, const PIString & msg); + + EVENT3(messageReceived, PIDeque, path, int, type, PIString, msg) + +private: + PICout createPICout(const CDType & m) const; + +}; + +} + +extern CD_UTILS_EXPORT CDUtils::MInterface M; + +#endif // CDUTILS_M_H diff --git a/cd_utils/cdutils_parser.cpp b/cd_utils/cdutils_parser.cpp index 50e0600..2a41c07 100644 --- a/cd_utils/cdutils_parser.cpp +++ b/cd_utils/cdutils_parser.cpp @@ -1,196 +1,196 @@ -#include "cdutils_parser.h" -#include "cdutils_types.h" -#include "piiostring.h" -#include "piiobytearray.h" -#include "pifile.h" - -using namespace CDUtils; - -enum Phase { - eName = 1, - eBracketOpen, - eBracketClose, - eMemberName, - eMemberEqual, - eMemberValue, - eMemberComma, - eComment, - eMultiComment -}; - - -void removeComment(PIString & line, PIString * type, PIString * comment) { - int ci = line.find("//"); - if (ci >= 0) { - if (comment) *comment = line.right(line.size_s() - ci - 2); - line.cutRight(line.size_s() - ci).trim(); - if (type && comment && !line.isEmpty()) { - *type = comment->takeLeft(1); - comment->trim(); - } - } -} - - -void parseEnumLine(PIString & line, int * value, PIString * type, PIString * comment) { - removeComment(line, type, comment); - int ci = line.find("="); - if (ci >= 0) { - if (value) *value = line.right(line.size_s() - ci - 1).trim().toInt(); - line.cutRight(line.size_s() - ci).trim(); - } - if (line.trim().endsWith(",")) line.cutRight(1); -} - - -void parseInsert(PIString line, PIString & alias, PIStringList & out) { - out.clear(); - int ci = line.find("="); - if (ci < 0) return; - alias = line.right(line.size_s() - ci - 1).trim(); - line.cutRight(line.size_s() - ci).trim(); - while (line.find("[") > 0) { - int is = line.find("["), ie = line.find("]"); - PIString arr = line.mid(is + 1, ie - is - 1); - out << arr; - line.cutMid(is, ie - is + 1); - } - if (!line.isEmpty()) out.insert(0, line); -} - - -PIVector enumValues(const PIString & e, const PIMap & sections, PIStringList & enames) { - PIVector 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 sections; - PIMap 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 evals = enumValues(a, sections, enames); - //piCout << a << evals; - for (int i = 0; i < evals.size_s(); ++i) { - ts.section(evals[i]) = is; - ts.section(evals[i]).alias = enames[i]; - } - ts.name = is.name; - ts.name.insert(ibpos, PIString("[") << a << "]"); - is = ts; - ts = CDSection(et); - } - is.alias = alias; - cs.section(aval) = is; - } - } - } else { - parseEnumLine(line, &cev, &type, &comment); - //piCout << line << "=" << cev << "//" << type << comment; - ck = CDType(cev, line, type, "", "", comment, et); - if (type == "e") { - if (comment.startsWith("${")) { - comment.cutLeft(1); - PIString en = comment.inBrackets('{', '}'); - comment.cutLeft(en.size_s() + 2).trim(); - ck.setEnumValues(sections.value(en).enumValues()); - ck.setComment(comment); - //piCout << "enum" << en << ck.enumValues(); - } - } - cs[cev] = ck; - //cevalues[line] = cev; - enum_values[line] = cev; - ++cev; - } - } - //piCout << cs.name << cs.k; - sections[cs.name] = cs; -// piCout << "#" << cevalues; -// enum_values << cevalues; - cind += 4; - } -// piCout << "[CDSection] parse end"; - switch (et) { - case CDType::cdK: return sections.value("KDescription"); - case CDType::cdX: return sections.value("XDescription"); - case CDType::cdC: return sections.value("CDescription"); - case CDType::cdM: return sections.value("MDescription"); - default: return CDSection(et); - } - return CDSection(et); -} +#include "cdutils_parser.h" +#include "cdutils_types.h" +#include "piiostring.h" +#include "piiobytearray.h" +#include "pifile.h" + +using namespace CDUtils; + +enum Phase { + eName = 1, + eBracketOpen, + eBracketClose, + eMemberName, + eMemberEqual, + eMemberValue, + eMemberComma, + eComment, + eMultiComment +}; + + +void removeComment(PIString & line, PIString * type, PIString * comment) { + int ci = line.find("//"); + if (ci >= 0) { + if (comment) *comment = line.right(line.size_s() - ci - 2); + line.cutRight(line.size_s() - ci).trim(); + if (type && comment && !line.isEmpty()) { + *type = comment->takeLeft(1); + comment->trim(); + } + } +} + + +void parseEnumLine(PIString & line, int * value, PIString * type, PIString * comment) { + removeComment(line, type, comment); + int ci = line.find("="); + if (ci >= 0) { + if (value) *value = line.right(line.size_s() - ci - 1).trim().toInt(); + line.cutRight(line.size_s() - ci).trim(); + } + if (line.trim().endsWith(",")) line.cutRight(1); +} + + +void parseInsert(PIString line, PIString & alias, PIStringList & out) { + out.clear(); + int ci = line.find("="); + if (ci < 0) return; + alias = line.right(line.size_s() - ci - 1).trim(); + line.cutRight(line.size_s() - ci).trim(); + while (line.find("[") > 0) { + int is = line.find("["), ie = line.find("]"); + PIString arr = line.mid(is + 1, ie - is - 1); + out << arr; + line.cutMid(is, ie - is + 1); + } + if (!line.isEmpty()) out.insert(0, line); +} + + +PIVector enumValues(const PIString & e, const PIMap & sections, PIStringList & enames) { + PIVector 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 sections; + PIMap 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 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); +} diff --git a/cd_utils/cdutils_parser.h b/cd_utils/cdutils_parser.h index 4b23fa3..d85d609 100644 --- a/cd_utils/cdutils_parser.h +++ b/cd_utils/cdutils_parser.h @@ -1,39 +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 . -*/ - -#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 +/* + 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 . +*/ + +#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 diff --git a/cd_utils/cdutils_protocol.h b/cd_utils/cdutils_protocol.h index c9b541c..18b9164 100644 --- a/cd_utils/cdutils_protocol.h +++ b/cd_utils/cdutils_protocol.h @@ -1,73 +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 . -*/ - -#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 path; - PIString value; - }; - -# pragma pack(pop) - - -inline PIByteArray & operator <<(PIByteArray & s, const PacketHeader & v) {s << v.type << v.session_id; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PacketHeader & v) {s >> v.type >> v.session_id; return s;} - -inline PIByteArray & operator <<(PIByteArray & s, const PacketKDirectChange & v) {s << v.path << v.value; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PacketKDirectChange & v) {s >> v.path >> v.value; return s;} - -} - -#endif // CDUTILS_PROTOCOL_H +/* + CD Utils - Control-Debug utilites + + Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#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 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 diff --git a/cd_utils/cdutils_types.cpp b/cd_utils/cdutils_types.cpp index 2000e1e..c722270 100644 --- a/cd_utils/cdutils_types.cpp +++ b/cd_utils/cdutils_types.cpp @@ -1,762 +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 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 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 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::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 & 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 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 prev_cd_f_bi; - PIMap prev_cd_f_bn; - PIMap::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 prev_s_bi; - PIMap prev_s_bn; - PIMap::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 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::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 cd_ids; - PIMap::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::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::iterator i; - for (i = cd.begin(); i != cd.end(); ++i) { - i.value().parent = this; - i.value().calculated = false; - } - PIMap::iterator j; - for (j = s.begin(); j != s.end(); ++j) - j.value().prepareCalculate(); -} - - -void CDSection::calculateRecursive(PIEvaluator * e) { - PIMap::iterator i; - for (i = cd.begin(); i != cd.end(); ++i) - i.value().calculate(e); - PIMap::iterator j; - for (j = s.begin(); j != s.end(); ++j) - j.value().calculateRecursive(e); -} - - -void CDSection::setSelectedX(bool yes) { - PIMap::iterator i; - for (i = cd.begin(); i != cd.end(); ++i) - i.value().x_enabled = yes; - PIMap::iterator j; - for (j = s.begin(); j != s.end(); ++j) - j.value().setSelectedX(yes); -} - - -PIVector > CDSection::collectX() const { - PIVector > ret; - PIMap::const_iterator i; - for (i = cd.begin(); i != cd.end(); ++i) { - if (i.value().x_enabled) - ret << i.value().path(); - } - PIMap::const_iterator j; - for (j = s.constBegin(); j != s.constEnd(); ++j) - ret << j.value().collectX(); - return ret; -} - - -void CDSection::makePath(PIDeque p) { - PIDeque tp; - PIMap::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::iterator j; - for (j = s.begin(); j != s.end(); ++j) { - tp = p; - tp << j.key(); - j.value().makePath(tp); - } -} - - -PIVector CDSection::children(bool recursive) const { - PIVector ret; - PIMap::const_iterator i; - for (i = cd.begin(); i != cd.end(); ++i) - ret << const_cast(&(i.value())); - if (!recursive) return ret; - PIMap::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::const_iterator i; - for (i = cd.constBegin(); i != cd.constEnd(); ++i) - ret << PIVariantTypes::Enumerator(i.key(), i.value().name()); - return ret; -} - - +#include "cdutils_types.h" +#include "piconfig.h" +#include "pifile.h" +#include "pievaluator.h" +#include "cdutils_core.h" + +using namespace CDUtils; + +//int cdtype_debug_cnt = 1; + +const int cd_x_history_max_size = 4000; + +CDType::CDType() { + index_ = -1; + value_d = 0.; + value_i = 0; + value_b = calculated = x_enabled = false; + cd_type_ = cdNull; + parent = 0; + avg_size = 1; + mode_ = rmode_ = X_Current; +// debug_cnt = cdtype_debug_cnt; +// cdtype_debug_cnt++; +// piCout << "[CDType]" << "create Null" << debug_cnt; +} + + + + +CDType::CDType(int i, const PIString & n, const PIString & t, const PIString & v, const PIString & f, const PIString & c, cdT cd_t) { + index_ = i; + name_ = n.trimmed(); + type_ = t.trimmed(); + value_s = v.trimmed(); + formula_ = f.trimmed(); + comment_ = c.trimmed(); + value_d = v.toDouble(); + value_i = v.toInt(); + value_b = v.toBool(); + cd_type_ = cd_t; + calculated = x_enabled = false; + parent = 0; + avg_size = 1; + mode_ = rmode_ = X_Current; + if (type_ == "e") { + enum_values = parseEnumComment(comment_); +// piCout << enum_values.size() << enum_values; + } +// piCout << type_.size() << type_.toUTF8(); +// piCout << formula_.size() << formula_.toUTF8(); +// piCout << comment_.size() << comment_.toUTF8(); +// debug_cnt = cdtype_debug_cnt; +// cdtype_debug_cnt++; +// piCout << "[CDType] create" << name_ << ":" << type_ << ":" << value_s << ":" << value_d << ":" << formula_ << ":" << comment_ << ":" << (cd_type_ == cdK); +} + + +CDType & CDType::operator =(double x) { + value_d = x; + value_i = x; + value_b = x > 0.; + if (mode_ == X_All_Avg) { + avg_h << x; + double val = 0; + if (avg_h.size_s() >= avg_size) { + for (int i = 0; i < avg_h.size_s(); i++) + val += avg_h[i]; + val /= avg_h.size(); + avg_h.clear(); + if (history.size() < cd_x_history_max_size) + history << val; + } + } + return *this; +} + + +PIString CDType::type() const { + if (type_.trimmed().isEmpty()) return "f"; + // piCout << "type =" << type_.trimmed() << ";" << type_ << "#"; + return type_; +} + + +PIString CDType::value() const { + if (type_ == "b") return PIString::fromBool(value_b); + return value_s; +} + + +PIVariant CDType::variantValue() const { + if (type_.isEmpty()) return PIVariant(value()); + switch (type_[0].toAscii()) { + case 'b': return PIVariant(toBool()); break; + case 'n': return PIVariant(toInt()); break; + case 'f': return PIVariant(toDouble()); break; + case 'c': return PIVariant(PIVariantTypes::Color(toInt())); break; + case 'e': { + PIVariantTypes::Enum e = enum_values; + e.selectValue(toInt()); + return PIVariant(e); + break; + } + default: break; + } + return PIVariant(value()); +} + + +void CDType::setValue(const PIString & value_) { + formula_ = value_; + value_d = formula_.toDouble(); + value_i = formula_.toInt(); + value_b = formula_.toBool(); +} + + +void CDType::setVariantValue(const PIVariant & value_) { + setValue(PIString::fromNumber(value_.toDouble())); +} + + +void CDType::setFormula(const PIString & f) { + formula_ = f; + calculated = false; + //PIEvaluator e; + //calculate(&e); +} + + +PIStringList CDType::pathString() const { + PIStringList ret; + CDSection * ps = CDCore::instance()->root(cd_type_); + if (!ps) return ret; + for (int i = 0; i < path_.size_s() - 1; ++i) { + ps = &(ps->section(path_[i])); + if (!ps->alias.isEmpty()) ret << ps->alias; + else ret << PIString::fromNumber(path_[i]); + } + if (!name_.isEmpty()) ret << name_; + else ret << PIString::fromNumber(index_); + return ret; +} + + +void CDType::readX(PIByteArray & ba) { + if (ba.size() < 5) return; + uchar t(0); ba >> t; + rmode_ = (XMode)t; + switch (rmode_) { + case X_Current: + ba >> value_d; + break; + case X_All_Avg: { + PIVector 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 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 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::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 & 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 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 prev_cd_f_bi; + PIMap prev_cd_f_bn; + PIMap::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 prev_s_bi; + PIMap prev_s_bn; + PIMap::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 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::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 cd_ids; + PIMap::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::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::iterator i; + for (i = cd.begin(); i != cd.end(); ++i) { + i.value().parent = this; + i.value().calculated = false; + } + PIMap::iterator j; + for (j = s.begin(); j != s.end(); ++j) + j.value().prepareCalculate(); +} + + +void CDSection::calculateRecursive(PIEvaluator * e) { + PIMap::iterator i; + for (i = cd.begin(); i != cd.end(); ++i) + i.value().calculate(e); + PIMap::iterator j; + for (j = s.begin(); j != s.end(); ++j) + j.value().calculateRecursive(e); +} + + +void CDSection::setSelectedX(bool yes) { + PIMap::iterator i; + for (i = cd.begin(); i != cd.end(); ++i) + i.value().x_enabled = yes; + PIMap::iterator j; + for (j = s.begin(); j != s.end(); ++j) + j.value().setSelectedX(yes); +} + + +PIVector > CDSection::collectX() const { + PIVector > ret; + PIMap::const_iterator i; + for (i = cd.begin(); i != cd.end(); ++i) { + if (i.value().x_enabled) + ret << i.value().path(); + } + PIMap::const_iterator j; + for (j = s.constBegin(); j != s.constEnd(); ++j) + ret << j.value().collectX(); + return ret; +} + + +void CDSection::makePath(PIDeque p) { + PIDeque tp; + PIMap::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::iterator j; + for (j = s.begin(); j != s.end(); ++j) { + tp = p; + tp << j.key(); + j.value().makePath(tp); + } +} + + +PIVector CDSection::children(bool recursive) const { + PIVector ret; + PIMap::const_iterator i; + for (i = cd.begin(); i != cd.end(); ++i) + ret << const_cast(&(i.value())); + if (!recursive) return ret; + PIMap::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::const_iterator i; + for (i = cd.constBegin(); i != cd.constEnd(); ++i) + ret << PIVariantTypes::Enumerator(i.key(), i.value().name()); + return ret; +} + + diff --git a/cd_utils/cdutils_types.h b/cd_utils/cdutils_types.h index 299e4a9..f2fd7fe 100644 --- a/cd_utils/cdutils_types.h +++ b/cd_utils/cdutils_types.h @@ -1,193 +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 . -*/ - -#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 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 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 history; - -protected: - bool calculate(PIEvaluator * e, PIVector stack = PIVector()); - 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 path_; - double value_d; - int value_i; - bool value_b, calculated, x_enabled; - PIVector 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(this)->getByName(name_);} - CDType & operator [](const PIDeque & path_) {return getByPath(path_);} - const CDType operator [](const PIDeque & path_) const {return const_cast(this)->getByPath(path_);} - CDSection & section(int v); - const CDSection section(int v) const; - - bool isEmpty() const {return cd.isEmpty() && s.isEmpty();} - bool exists(PIDeque path) const; - int count(bool recursive = true) const; - int sectionsCount() const; - PIVector indexes() const {return cd.keys();} - PIStringList index_names() const; - void calculate(); - void makePath(PIDeque p = PIDeque()); - PIVector children(bool recursive = true) const; - PIVariantTypes::Enum enumValues() const; - - PIString name; - PIString alias; - -protected: - CDSection(PIMap k_, PIMap s_) { - cd = k_; - s = s_; - } - CDType & getByName(const PIString & name_); - CDType & getByPath(const PIDeque & 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 > collectX() const; - - PIMap cd; - mutable PIMap s; - CDType null; - CDType::cdT cd_type_; -}; - -} - - -inline PICout operator <<(PICout s, const CDUtils::CDType & v) { - s.space(); - s.setControl(0, true); - switch (v.cd_type()) { - case CDUtils::CDType::cdK : s << "K["; break; - case CDUtils::CDType::cdX : s << "X["; break; - case CDUtils::CDType::cdC : s << "C["; break; - case CDUtils::CDType::cdM : s << "M["; break; - default : s << "Null["; break; - } - s << v.name() << "(" << v.index() << ")] = " << v.value(); - s.restoreControl(); - return s; -} - - -#endif // CDUTILS_TYPES_H +/* + CD Utils - Control-Debug utilites + + Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#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 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 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 history; + +protected: + bool calculate(PIEvaluator * e, PIVector stack = PIVector()); + 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 path_; + double value_d; + int value_i; + bool value_b, calculated, x_enabled; + PIVector 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(this)->getByName(name_);} + CDType & operator [](const PIDeque & path_) {return getByPath(path_);} + const CDType operator [](const PIDeque & path_) const {return const_cast(this)->getByPath(path_);} + CDSection & section(int v); + const CDSection section(int v) const; + + bool isEmpty() const {return cd.isEmpty() && s.isEmpty();} + bool exists(PIDeque path) const; + int count(bool recursive = true) const; + int sectionsCount() const; + PIVector indexes() const {return cd.keys();} + PIStringList index_names() const; + void calculate(); + void makePath(PIDeque p = PIDeque()); + PIVector children(bool recursive = true) const; + PIVariantTypes::Enum enumValues() const; + + PIString name; + PIString alias; + +protected: + CDSection(PIMap k_, PIMap s_) { + cd = k_; + s = s_; + } + CDType & getByName(const PIString & name_); + CDType & getByPath(const PIDeque & 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 > collectX() const; + + PIMap cd; + mutable PIMap 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 diff --git a/cd_utils/cdutils_x.cpp b/cd_utils/cdutils_x.cpp index 2b2d24a..e647377 100644 --- a/cd_utils/cdutils_x.cpp +++ b/cd_utils/cdutils_x.cpp @@ -1,55 +1,55 @@ -#include "cdutils_x.h" -#include "cdutils_core.h" - -using namespace CDUtils; - -XInterface X; - - -XInterface::XInterface(): Interface(CDType::cdX) { - CONNECTU(core, X_ReceivedX, this, receivedX); -} - - -void XInterface::setEnabled(const CDType & x, bool en) { - core->x_mutex.lock(); - CDType & t((*s)[x.path()]); - if (t.cd_type() != CDType::cdX) { - core->x_mutex.unlock(); - return; - } - t.x_enabled = en; - //piCout << t << "x_enabled" << en; - core->need_rebuild_x = true; - core->x_mutex.unlock(); -} - - -PIVector > XInterface::enabledList() const { - return CDCore::instance()->x_selected; -} - - -void XInterface::setEnabledList(const PIVector > & l) { - CDCore::instance()->x_selected = l; -} - - -void XInterface::lock() { - CDCore::instance()->x_mutex.lock(); -} - - -void XInterface::unlock() { - CDCore::instance()->x_mutex.unlock(); -} - - -void XInterface::start(double freq) { - core->startX(freq); -} - - -void XInterface::stop() { - core->stopX(); -} +#include "cdutils_x.h" +#include "cdutils_core.h" + +using namespace CDUtils; + +XInterface X; + + +XInterface::XInterface(): Interface(CDType::cdX) { + CONNECTU(core, X_ReceivedX, this, receivedX); +} + + +void XInterface::setEnabled(const CDType & x, bool en) { + core->x_mutex.lock(); + CDType & t((*s)[x.path()]); + if (t.cd_type() != CDType::cdX) { + core->x_mutex.unlock(); + return; + } + t.x_enabled = en; + //piCout << t << "x_enabled" << en; + core->need_rebuild_x = true; + core->x_mutex.unlock(); +} + + +PIVector > XInterface::enabledList() const { + return CDCore::instance()->x_selected; +} + + +void XInterface::setEnabledList(const PIVector > & 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(); +} diff --git a/cd_utils/cdutils_x.h b/cd_utils/cdutils_x.h index b0a8e3c..72e9974 100644 --- a/cd_utils/cdutils_x.h +++ b/cd_utils/cdutils_x.h @@ -1,57 +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 . -*/ - -#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 >, 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 > enabledList() const; - void setEnabledList(const PIVector > & l); - void lock(); - void unlock(); - - void start(double freq = 20.); - void stop(); - -}; - -} - -extern CD_UTILS_EXPORT CDUtils::XInterface X; - -#endif // CDUTILS_X_H +/* + CD Utils - Control-Debug utilites + + Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#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 >, 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 > enabledList() const; + void setEnabledList(const PIVector > & l); + void lock(); + void unlock(); + + void start(double freq = 20.); + void stop(); + +}; + +} + +extern CD_UTILS_EXPORT CDUtils::XInterface X; + +#endif // CDUTILS_X_H diff --git a/cd_utils/cdutilstest.cpp b/cd_utils/cdutilstest.cpp index ff35970..d284b49 100644 --- a/cd_utils/cdutilstest.cpp +++ b/cd_utils/cdutilstest.cpp @@ -1,97 +1,97 @@ -#include "cdutils_k.h" -#include "cdutils_x.h" -#include "cdutils_c.h" -#include "cdutils_m.h" -#include "cdutils_core.h" -#include "cdtest.h" -#include "pip.h" -#include "k_description.h" - -using namespace CDUtils; - -class Core : public PIObject -{ - PIOBJECT(Core) - public: - Core() { - CDCore::instance()->initApp(); -// piCout << "testCore"; - CONNECTU(&timer, tickEvent, this, timerDone); - CONNECTU(&X, received, this, xrecv); - CONNECTU(&C, received, this, crecv); - t = 0.; - } - - void load() { - rf.open("k.dat", PIIODevice::ReadWrite); - K.read(&rf); - rf.close(); - } - - void save() { - rf.open("k_out.txt", PIIODevice::ReadWrite); - rf.resize(0); - K.write(&rf); - rf.close(); -// rf.open("k_out.txt", PIIODevice::ReadWrite); -// K.read(&rf); -// rf.close(); -// rf.open("k_out2.txt", PIIODevice::ReadWrite); -// rf.resize(0); -// K.write(&rf); -// rf.close(); -// rf.open("k_out2.txt", PIIODevice::ReadWrite); -// K.read(&rf); -// rf.close(); -// rf.open("k_out3.txt", PIIODevice::ReadWrite); -// rf.resize(0); -// K.write(&rf); -// rf.close(); - } - - void test() { - X.lock(); - X[KD::Frequency] = 100; - X.section(KD::Spectrometer)[KD::Temperature_default] = sin(t); - t += 0.01; - X.unlock(); - /*piCout << "count" << K.count(); - piCout << K[First]; - piCout << K[Second];*/ - } - - EVENT_HANDLER(void, ksend) {piCout << "sended k";} - EVENT_HANDLER(void, crecv) { - piCout << "received c"; - C.connect(C.section(KD::Logs).section(KD::Spec).section(KD::Formats)[KD::Binary], this, HANDLER(cmd)); - C.autoConnect(this); - } - EVENT_HANDLER(void, xrecv) { - piCout << "received x"; - if (!timer.isRunning()) timer.start(10); - X.start(); - } - EVENT_HANDLER(void, timerDone) {test();} - EVENT_HANDLER(void, cmd) {piCout << "command cmd";} - EVENT_HANDLER(void, c_Pause) { - piCout << "command pause"; - M[KD::Main] << "rec command" << C[KD::Pause]; - M.messageBox(M.root()[KD::Core], "init successfull"); - } - EVENT_HANDLER(void, c_Spectrometer_Connection) {piCout << "command spec_conn";} - -private: - PIFile rf; - PITimer timer; - double t; -}; - - -int main(int argc, char *argv[]) { - X.start(); - piSleep(1); - //CDCore::instance()->destroy(); - piCout << "DELETED"; - return 0; -} - +#include "cdutils_k.h" +#include "cdutils_x.h" +#include "cdutils_c.h" +#include "cdutils_m.h" +#include "cdutils_core.h" +#include "cdtest.h" +#include "pip.h" +#include "k_description.h" + +using namespace CDUtils; + +class Core : public PIObject +{ + PIOBJECT(Core) + public: + Core() { + CDCore::instance()->initApp(); +// piCout << "testCore"; + CONNECTU(&timer, tickEvent, this, timerDone); + CONNECTU(&X, received, this, xrecv); + CONNECTU(&C, received, this, crecv); + t = 0.; + } + + void load() { + rf.open("k.dat", PIIODevice::ReadWrite); + K.read(&rf); + rf.close(); + } + + void save() { + rf.open("k_out.txt", PIIODevice::ReadWrite); + rf.resize(0); + K.write(&rf); + rf.close(); +// rf.open("k_out.txt", PIIODevice::ReadWrite); +// K.read(&rf); +// rf.close(); +// rf.open("k_out2.txt", PIIODevice::ReadWrite); +// rf.resize(0); +// K.write(&rf); +// rf.close(); +// rf.open("k_out2.txt", PIIODevice::ReadWrite); +// K.read(&rf); +// rf.close(); +// rf.open("k_out3.txt", PIIODevice::ReadWrite); +// rf.resize(0); +// K.write(&rf); +// rf.close(); + } + + void test() { + X.lock(); + X[KD::Frequency] = 100; + X.section(KD::Spectrometer)[KD::Temperature_default] = sin(t); + t += 0.01; + X.unlock(); + /*piCout << "count" << K.count(); + piCout << K[First]; + piCout << K[Second];*/ + } + + EVENT_HANDLER(void, ksend) {piCout << "sended k";} + EVENT_HANDLER(void, crecv) { + piCout << "received c"; + C.connect(C.section(KD::Logs).section(KD::Spec).section(KD::Formats)[KD::Binary], this, HANDLER(cmd)); + C.autoConnect(this); + } + EVENT_HANDLER(void, xrecv) { + piCout << "received x"; + if (!timer.isRunning()) timer.start(10); + X.start(); + } + EVENT_HANDLER(void, timerDone) {test();} + EVENT_HANDLER(void, cmd) {piCout << "command cmd";} + EVENT_HANDLER(void, c_Pause) { + piCout << "command pause"; + M[KD::Main] << "rec command" << C[KD::Pause]; + M.messageBox(M.root()[KD::Core], "init successfull"); + } + EVENT_HANDLER(void, c_Spectrometer_Connection) {piCout << "command spec_conn";} + +private: + PIFile rf; + PITimer timer; + double t; +}; + + +int main(int argc, char *argv[]) { + X.start(); + piSleep(1); + //CDCore::instance()->destroy(); + piCout << "DELETED"; + return 0; +} + diff --git a/cmake_android.sh b/cmake_android.sh old mode 100755 new mode 100644 diff --git a/kx_utils/CMakeLists.txt b/kx_utils/CMakeLists.txt index 80da37a..129b848 100644 --- a/kx_utils/CMakeLists.txt +++ b/kx_utils/CMakeLists.txt @@ -1,76 +1,76 @@ -cmake_minimum_required(VERSION 3.0) -project(kx_utils) -if (POLICY CMP0017) - cmake_policy(SET CMP0017 NEW) -endif() -if (NOT LIBPROJECT) - find_package(PIP REQUIRED) -endif () -if (MINGW) - find_package(MinGW REQUIRED) -endif() -include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${PIP_INCLUDES}) -set(KX_PULT_NAME "kx_pult") -option(KX_PULT "Build ${KX_PULT_NAME}" 1) -option(LIB "System install" 1) -option(DEBUG "Build with -g3" 0) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -Wall") -if (DEBUG) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3") -endif() -set(CPPS_UTILS "kx_coeffs.cpp" "piprotocol.cpp") -set(HDRS_UTILS "kx_coeffs.h" "kx_protocol_x.h" "kx_protocol_c.h" "piprotocol.h") -if (DEFINED ENV{QNX_HOST}) - add_library(${PROJECT_NAME} STATIC ${CPPS_UTILS}) -else() - add_library(${PROJECT_NAME} SHARED ${CPPS_UTILS}) -endif() -target_link_libraries(${PROJECT_NAME} ${PIP_LIBRARY}) -message(STATUS "Building ${PROJECT_NAME}") -if (NOT DEFINED ENV{QNX_HOST}) - if (KX_PULT) - find_package(Qt4 REQUIRED) - find_package(QAD REQUIRED) - find_package(OpenGL REQUIRED) - include_directories(${QT_INCLUDES} ${QAD_INCLUDES}) - set(CPPS "kx_pult.cpp" "kx_pult.h" "kx_pult.ui" "main_kx_pult.cpp") - set(MOCS "kx_pult.h") - file(GLOB UIS "*.ui") - file(GLOB RES "*.qrc") - qt4_wrap_cpp(CMOCS ${MOCS} OPTIONS -nw) - qt4_wrap_ui(CUIS ${UIS}) - qt4_add_resources(RESS ${RES}) - add_executable(${KX_PULT_NAME} WIN32 ${CPPS} ${CMOCS} ${CUIS} ${RESS} ${MOCS}) - set(LIBS ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${OPENGL_LIBRARIES} ${PIP_LIBRARY} qad_graphic4 qad_utils4 qad_widgets4) - target_link_libraries(${KX_PULT_NAME} ${LIBS} ${PROJECT_NAME}) - endif() -endif() -if (LIB) - list(APPEND _ALL_TARGETS ${PROJECT_NAME}) - set(_ALL_TARGETS ${_ALL_TARGETS} PARENT_SCOPE) - if (WIN32) - set(CMAKE_INSTALL_PREFIX ${MINGW_DIR}) - install(FILES ${HDRS_UTILS} DESTINATION ${MINGW_INCLUDE}) - install(TARGETS ${PROJECT_NAME} DESTINATION ${MINGW_LIB}) - install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${MINGW_BIN}) - else() - if (DEFINED ANDROID_PLATFORM) - set(CMAKE_INSTALL_PREFIX ${ANDROID_SYSTEM_LIBRARY_PATH}/usr) - else() - set(CMAKE_INSTALL_PREFIX /usr/local) - endif() - install(FILES ${HDRS_UTILS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include) - install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) - endif() - message(STATUS "Install ${PROJECT_NAME} to system \"${CMAKE_INSTALL_PREFIX}\"") -else() - install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin) - install(TARGETS ${PROJECT_NAME} DESTINATION lib) - install(FILES ${HDRS_UTILS} DESTINATION include) - message(STATUS "Install ${PROJECT_NAME} to local \"bin\", \"lib\" and \"include\"") -endif() -if (NOT DEFINED ENV{QNX_HOST}) - if (KX_PULT) - install(TARGETS ${KX_PULT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) - endif() -endif() +cmake_minimum_required(VERSION 3.0) +project(kx_utils) +if (POLICY CMP0017) + cmake_policy(SET CMP0017 NEW) +endif() +if (NOT LIBPROJECT) + find_package(PIP REQUIRED) +endif () +if (MINGW) + find_package(MinGW REQUIRED) +endif() +include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${PIP_INCLUDES}) +set(KX_PULT_NAME "kx_pult") +option(KX_PULT "Build ${KX_PULT_NAME}" 1) +option(LIB "System install" 1) +option(DEBUG "Build with -g3" 0) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -Wall") +if (DEBUG) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3") +endif() +set(CPPS_UTILS "kx_coeffs.cpp" "piprotocol.cpp") +set(HDRS_UTILS "kx_coeffs.h" "kx_protocol_x.h" "kx_protocol_c.h" "piprotocol.h") +if (DEFINED ENV{QNX_HOST}) + add_library(${PROJECT_NAME} STATIC ${CPPS_UTILS}) +else() + add_library(${PROJECT_NAME} SHARED ${CPPS_UTILS}) +endif() +target_link_libraries(${PROJECT_NAME} ${PIP_LIBRARY}) +message(STATUS "Building ${PROJECT_NAME}") +if (NOT DEFINED ENV{QNX_HOST}) + if (KX_PULT) + find_package(Qt4 REQUIRED) + find_package(QAD REQUIRED) + find_package(OpenGL REQUIRED) + include_directories(${QT_INCLUDES} ${QAD_INCLUDES}) + set(CPPS "kx_pult.cpp" "kx_pult.h" "kx_pult.ui" "main_kx_pult.cpp") + set(MOCS "kx_pult.h") + file(GLOB UIS "*.ui") + file(GLOB RES "*.qrc") + qt4_wrap_cpp(CMOCS ${MOCS} OPTIONS -nw) + qt4_wrap_ui(CUIS ${UIS}) + qt4_add_resources(RESS ${RES}) + add_executable(${KX_PULT_NAME} WIN32 ${CPPS} ${CMOCS} ${CUIS} ${RESS} ${MOCS}) + set(LIBS ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${OPENGL_LIBRARIES} ${PIP_LIBRARY} qad_graphic4 qad_utils4 qad_widgets4) + target_link_libraries(${KX_PULT_NAME} ${LIBS} ${PROJECT_NAME}) + endif() +endif() +if (LIB) + list(APPEND _ALL_TARGETS ${PROJECT_NAME}) + set(_ALL_TARGETS ${_ALL_TARGETS} PARENT_SCOPE) + if (WIN32) + set(CMAKE_INSTALL_PREFIX ${MINGW_DIR}) + install(FILES ${HDRS_UTILS} DESTINATION ${MINGW_INCLUDE}) + install(TARGETS ${PROJECT_NAME} DESTINATION ${MINGW_LIB}) + install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${MINGW_BIN}) + else() + if (DEFINED ANDROID_PLATFORM) + set(CMAKE_INSTALL_PREFIX ${ANDROID_SYSTEM_LIBRARY_PATH}/usr) + else() + set(CMAKE_INSTALL_PREFIX /usr/local) + endif() + install(FILES ${HDRS_UTILS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include) + install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) + endif() + message(STATUS "Install ${PROJECT_NAME} to system \"${CMAKE_INSTALL_PREFIX}\"") +else() + install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin) + install(TARGETS ${PROJECT_NAME} DESTINATION lib) + install(FILES ${HDRS_UTILS} DESTINATION include) + message(STATUS "Install ${PROJECT_NAME} to local \"bin\", \"lib\" and \"include\"") +endif() +if (NOT DEFINED ENV{QNX_HOST}) + if (KX_PULT) + install(TARGETS ${KX_PULT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) + endif() +endif() diff --git a/kx_utils/kx_pult.cpp b/kx_utils/kx_pult.cpp index 2e5fab9..a27aadf 100644 --- a/kx_utils/kx_pult.cpp +++ b/kx_utils/kx_pult.cpp @@ -1,848 +1,848 @@ -#include -#include -#include -#include "kx_pult.h" -#include "ui_kx_pult.h" -#include "piqt.h" -#include "qpiconfig.h" - - -bool isNormalDouble(const double & v) { -#ifdef WINDOWS - return true; -#else - return !isnan(v) && !isinf(v); -#endif -} - - -XCheck::XCheck(int index): QWidget() { - index_ = index; - setProperty("index", index); - setMouseTracking(true); - check.setText(QString::number(index + 1) + " "); - check.setAutoFillBackground(true); - spin.setMaximum(KX_X_COUNT - 1); - QBoxLayout * l = new QBoxLayout(QBoxLayout::LeftToRight); - l->setMargin(0); - l->setSpacing(2); - l->addWidget(&check); - l->addWidget(&spin); - setLayout(l); - //check.installEventFilter(this); - //spin.installEventFilter(this); - connect(&spin, SIGNAL(valueChanged(int)), this, SLOT(spinChanged(int))); - connect(&check, SIGNAL(toggled(bool)), this, SLOT(checkChanged_(bool))); -} - - -bool XCheck::eventFilter(QObject * o, QEvent * e) { - if (e->type() == QEvent::Enter) - qApp->postEvent(this, new QEvent(e->type())); - return QWidget::eventFilter(o, e); -} - - - - -KX_Pult::KX_Pult(): QMainWindow(), config_("kx_pult.conf"), name_x("x"), name_c("c"), -config(piqt(config_), QIODevice::ReadWrite), coeffs(config_, "k", true) { - //cout << sizeof(coeffsK.k_protocol->to_k) << endl; - ui = new Ui::KX_Pult(); - ui->setupUi(this); - ui->configWidget->setQPIConfig(&config); - ui->configWidget->expandAll(); - ui->list->viewport()->installEventFilter(this); - ui->treeK->viewport()->installEventFilter(this); - ui->scrollArea->setAutoFillBackground(false); - ui->scrollAreaWidgetContents->setAutoFillBackground(false); - ui->widget->setAutoFillBackground(false); - ui->label_17->setFixedSize(preferredIconSize(1.25, this)); - log_menu.addAction(ui->actionClear); - prot_x = 0; - prot_c = 0; - show_x = config.getValue("show_x", true); - if (!show_x) - ui->tabWidget->removeTab(1); - session.setFile("session_KX_Pult.conf"); - session.addEntry(this); - session.addEntry(ui->tabWidget); - session.addEntry(ui->checkKHideEmpty); - session.addEntry(ui->checkKHideNormal); - session.addEntry(ui->checkKHideExpressions); - session.addEntry(ui->checkKAutoCalculate); - needWrite = isPause = false; - timer = 0; - //x.resize(KX_X_PACKET_NUM); - //k.resize(K_NUM); - QPalette pal = palette(); - QColor col; - ui->graphic->setGraphicsCount(0); - for (int i = 0; i < KX_X_PACKET_NUM; ++i) { - XCheck * xc = new XCheck(i); - xc->installEventFilter(this); - connect(xc, SIGNAL(valueChanged(int, int)), this, SLOT(changedX(int,int))); - connect(xc, SIGNAL(checkChanged(int, bool)), this, SLOT(toggledX(int, bool))); - col = QColor::fromHsv(360 / KX_X_PACKET_NUM * i, 255, 200); - pal.setColor(QPalette::Button, col); - pal.setColor(QPalette::Window, col); - pal.setColor(QPalette::WindowText, invertColor(col)); - xc->check.setPalette(pal); - ui->graphic->addGraphic(QString::number(i), col); - ui->graphic->setGraphicVisible(false, i); - checks << xc; - ((QGridLayout * )(ui->widgetChecks->layout()))->addWidget(xc, (i / 10) * 2, i % 10); - QLabel * lbl = new QLabel("0"); lbl->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); - values << lbl; - ((QGridLayout * )(ui->widgetChecks->layout()))->addWidget(lbl, (i / 10) * 2 + 1, i % 10); - //xc->show(); - } - renew(); - icon_record = QIcon(":/icons/media-record.png"); - icon_stop = QIcon(":/icons/media-playback-stop.png"); - outdir = dir.absolutePath(); - if (!dir.exists()) dir.mkdir(outdir); - outdir += "/"; - ui->treeK->setColumnWidth(0, 60); - ui->treeK->setColumnWidth(1, 250); - ui->treeK->setColumnWidth(3, 100); - ui->treeK->setColumnWidth(4, 100); - //ui->table->setK(coeffsK.k()->data(), coeffsK.count()); - ui->spinSize->setValue(K.size_s()); - addToList(trUtf8("Read K file \"%1\": %2 coeffs, %3 bytes").arg(PI2QString(coeffs.fileName())).arg(K.size_s()).arg(coeffs.k_content.size_s()), Qt::darkMagenta); - CONNECT(void, &coeffs, sendFailed, this, pip_sendFailed); - CONNECT(void, &coeffs, sendSucceed, this, pip_sendSucceed); - CONNECT(void, &coeffs, receiveFailed, this, pip_receiveFailed); - CONNECT(void, &coeffs, receiveSucceed, this, pip_receiveSucceed); - connect(this, SIGNAL(q_k_sendFailed()), this, SLOT(k_sendFailed()), Qt::QueuedConnection); - connect(this, SIGNAL(q_k_sendSucceed()), this, SLOT(k_sendSucceed()), Qt::QueuedConnection); - connect(this, SIGNAL(q_k_receiveFailed()), this, SLOT(k_receiveFailed()), Qt::QueuedConnection); - connect(this, SIGNAL(q_k_receiveSucceed()), this, SLOT(k_receiveSucceed()), Qt::QueuedConnection); - connect(&timer_diag, SIGNAL(timeout()), this, SLOT(updateDiag())); - connect(&session, SIGNAL(loading(QPIConfig&)), this, SLOT(loading(QPIConfig&))); - connect(&session, SIGNAL(saving(QPIConfig&)), this, SLOT(saving(QPIConfig&))); - connect(ui->checkKHideEmpty, SIGNAL(toggled(bool)), this, SLOT(filterTree())); - connect(ui->checkKHideNormal, SIGNAL(toggled(bool)), this, SLOT(filterTree())); - connect(ui->checkKHideExpressions, SIGNAL(toggled(bool)), this, SLOT(filterTree())); - connect(ui->lineKSearch, SIGNAL(textChanged(QString)), this, SLOT(filterTree())); - session.load(); - updateKDesc(); - updateCDesc(); - timer_diag.start(40); - timer_update = startTimer(25); -} - - -KX_Pult::~KX_Pult() { - session.save(); -} - - -void KX_Pult::loading(QPIConfig & conf) { - kdesc_file = conf.getValue("kdesc_file").stringValue(); - cdesc_file = conf.getValue("cdesc_file").stringValue(); -} - - -void KX_Pult::saving(QPIConfig & conf) { - conf.setValue("kdesc_file", kdesc_file); - conf.setValue("cdesc_file", cdesc_file); -} - - -bool KX_Pult::eventFilter(QObject * o, QEvent * e) { - if (o == ui->list->viewport()) { - if (e->type() == QEvent::ContextMenu) { - clear_target = 0; - log_menu.popup(((QContextMenuEvent*)e)->globalPos()); - } - return QMainWindow::eventFilter(o, e); - } - if (o == ui->treeK->viewport()) { - if (e->type() == QEvent::ContextMenu) { - clear_target = 1; - log_menu.popup(((QContextMenuEvent*)e)->globalPos()); - } - return QMainWindow::eventFilter(o, e); - } - int ind = o->property("index").toInt(); - //qDebug() << "event" << i << e->type(); - switch (e->type()) { - case QEvent::Enter: - ui->graphic->setAutoUpdate(false); - for (int i = 0; i < KX_X_PACKET_NUM; ++i) - ui->graphic->setGraphicLineWidth(ind == i ? 3. : 1., i); - ui->graphic->setAutoUpdate(true); - ui->graphic->update(); - break; - case QEvent::Leave: - ui->graphic->setAutoUpdate(false); - for (int i = 0; i < KX_X_PACKET_NUM; ++i) - ui->graphic->setGraphicLineWidth(1., i); - ui->graphic->setAutoUpdate(true); - ui->graphic->update(); - break; - default: break; - } - return QMainWindow::eventFilter(o, e); -} - - -void KX_Pult::timerEvent(QTimerEvent * e) { - if (e->timerId() == timer_update) { - if (need_update) { - need_update = false; - ui->graphic->updateGraphics(); - } - } - if (e->timerId() == timer) { - static QString sPI = QString::number(atan(1) * 4., 'f', 14).leftJustified(14); - static int cnt = 0; - int si = qMax(cnt - 6, 0); - ++cnt; - cnt %= 23; - ui->labelWait->setText(QString(si, QChar(' ')) + sPI.mid(cnt - 6, 6).trimmed()); - if (!coeffs.isReady()) return; - //ui->table->setK(coeffsK.k()->data(), coeffsK.count()); - //ui->table->showK(); - } -} - - -void KX_Pult::setControlsEnable(bool enable) { - foreach (XCheck * i, checks) - i->setEnabled(enable); - ui->buttonShowAll->setEnabled(enable); - ui->buttonHideAll->setEnabled(enable); -} - - -void KX_Pult::setX(const KX_X_Data & data) { - if (!show_x) return; - //ui->graphic->lock(); - for (int i = 0; i < KX_X_PACKET_NUM; ++i) { - if (!isNormalDouble(data.x_data[i])) continue; - ui->graphic->addPoint(data.x_data[i], i, false); - values[i]->setText(QString("(%1): %2").arg(data.x_num[i]).arg(data.x_data[i])); - } - //ui->graphic->unlock(); - if (!isPause) { - need_update = true; - } - if (!needWrite) return; - stream << QString::number(tm.elapsed() / 1000., 'f', 3) << " " << QTime::currentTime().toString("hh:mm:ss") << " " << wcnt++; - for (int i = 0; i < KX_X_PACKET_NUM; ++i) - stream << " " << QString::number(data.x_data[i], 'f', 4); - stream << "\n"; -} - - -void KX_Pult::addToList(const QString & s, const QColor & c) { - ui->list->addItem(QDateTime::currentDateTime().toString("dd/MM/yyyy hh:ss - ") + s); - ui->list->item(ui->list->count() - 1)->setTextColor(c); - ui->list->scrollToBottom(); -} - - -void KX_Pult::on_buttonRecord_clicked() { - static bool isRec = false; - int cinc = 0; - QString str; - isRec = !isRec; - setControlsEnable(!isRec); - if (isRec) { - tm.restart(); - file.close(); - file.setFileName(outdir + getNewFileName(cinc)); - while (file.exists()) - file.setFileName(outdir + getNewFileName(cinc++)); - file.open(QIODevice::ReadWrite); - stream.setDevice(&file); - stream << "T V C"; - for (int i = 0; i < KX_X_PACKET_NUM; ++i) - stream << " X" + QString::number(checks[i]->spin.value()); - stream << "\n"; - wcnt = 0; - needWrite = true; - ui->buttonRecord->setText(trUtf8("Finish record")); - ui->buttonRecord->setIcon(icon_stop); - emit recordStarted(QFileInfo(file).completeBaseName()); - } else { - needWrite = false; - stream.setDevice(0); - file.close(); - ui->buttonRecord->setText(trUtf8("Start record")); - ui->buttonRecord->setIcon(icon_record); - emit recordStopped(QFileInfo(file).completeBaseName()); - } -} - - -void KX_Pult::on_actionClear_triggered() { - switch (clear_target) { - case 0: - ui->list->clear(); - break; - case 1: - clearSelected(); - break; - default: break; - } -} - - -void KX_Pult::clearSelected() { - QList si = ui->treeK->selectedItems(); - ui->treeK->setUpdatesEnabled(false); - ui->treeK->blockSignals(true); - foreach (QTreeWidgetItem * i, si) { - int ki = i->text(0).toInt(); - i->setText(2, ""); - coeffs.setFormula(ki, ""); - } - ui->treeK->blockSignals(false); - ui->treeK->setUpdatesEnabled(true); - if (ui->checkKAutoCalculate->isChecked()) { - QApplication::processEvents(); - calculate(); - } -} - - -QString KX_Pult::typeName(const QString & n) const { - if (n.isEmpty()) return ""; - switch (n[0].toLatin1()) { - case 'l': return trUtf8("list"); break; - case 'b': return trUtf8("bool"); break; - case 'n': return trUtf8("int"); break; - case 'f': return trUtf8("double"); break; - case 'c': return trUtf8("color"); break; - case 'r': return trUtf8("rect"); break; - case 'a': return trUtf8("rect"); break; - case 'p': return trUtf8("point"); break; - case 'v': return trUtf8("vector"); break; - case 'i': return trUtf8("IP"); break; - case 'e': return trUtf8("enum"); break; - case 'F': return trUtf8("file"); break; - case 'D': return trUtf8("dir"); break; - } - return ""; -} - - -void KX_Pult::received(bool ok) { - if (!ok) return; - setX(prot_x->from_x); -} - - -void KX_Pult::on_treeK_itemClicked(QTreeWidgetItem * item, int column) { - Qt::ItemFlags f = Qt::ItemIsEnabled | Qt::ItemIsSelectable; - if (column == 2) f |= Qt::ItemIsEditable; - item->setFlags(f); -} - - -void KX_Pult::on_treeK_itemChanged(QTreeWidgetItem * item, int column) { - if (column != 2) return; - int ki = item->text(0).toInt(); - coeffs.setFormula(ki, piqt(item->text(column))); - if (ui->checkKAutoCalculate->isChecked()) - calculate(); -} - - -QString KX_Pult::getNewFileName(int inc) { - dir.refresh(); - dir.setNameFilters(QStringList("Experiment_*.txt")); - return "Experiment_" + QDateTime::currentDateTime().toString("dd_MM_yy__hh_mm_ss") + "__" + - QString::number(dir.entryList().count() + inc) + ".txt"; -} - - -void KX_Pult::on_buttonSendK_clicked() { - on_buttonWrite_clicked(); - coeffs.sendCoeffs(); - if (timer != 0) killTimer(timer); - timer = startTimer(100); -} - - -void KX_Pult::on_buttonReceiveK_clicked() { - coeffs.receiveCoeffs(); - if (timer != 0) killTimer(timer); - timer = startTimer(100); -} - - -void KX_Pult::on_buttonShowAll_clicked() { - for (int i = 0; i < KX_X_PACKET_NUM; ++i) { - checks[i]->check.setChecked(true); - //ui->graphic->setGraphicVisible(true, i); - } -} - - -void KX_Pult::on_buttonHideAll_clicked() { - for (int i = 0; i < KX_X_PACKET_NUM; ++i) { - checks[i]->check.setChecked(false); - //ui->graphic->setGraphicVisible(false, i); - } -} - - -void KX_Pult::on_buttonRead_clicked() { - coeffs.readCoeffs(); - addToList(trUtf8("Read K file \"%1\": %2 coeffs, %3 bytes").arg(PI2QString(coeffs.fileName())).arg(K.size_s()).arg(coeffs.k_content.size_s()), Qt::darkMagenta); - updateTree(); -} - - -void KX_Pult::on_buttonWrite_clicked() { - coeffs.writeCoeffs(); - addToList(trUtf8("Write K file \"%1\": %2 coeffs, %3 bytes").arg(PI2QString(coeffs.fileName())).arg(K.size_s()).arg(coeffs.k_content.size_s()), Qt::darkMagenta); -} - - -void KX_Pult::on_buttonResize_clicked() { - K.resize(ui->spinSize->value()); - coeffs.formulas.resize(ui->spinSize->value()); - ui->spinSize->setStyleSheet(""); - updateTree(); -} - - -void KX_Pult::on_buttonSetKDesc_clicked() { - QString ret = QFileDialog::getOpenFileName(this, trUtf8("Select *.h file with K description"), kdesc_file, "C/C++ header files(*.h *.hpp);;All files(*)"); - if (ret.isEmpty()) return; - kdesc_file = QDir::current().relativeFilePath(ret); - updateKDesc(true); -} - - -void KX_Pult::on_buttonSetCDesc_clicked() { - QString ret = QFileDialog::getOpenFileName(this, trUtf8("Select *.h file with C description"), cdesc_file, "C/C++ header files(*.h *.hpp);;All files(*)"); - if (ret.isEmpty()) return; - cdesc_file = QDir::current().relativeFilePath(ret); - updateCDesc(); -} - - -void KX_Pult::on_spinSize_valueChanged(int) { - ui->spinSize->setStyleSheet(""); -} - - -void KX_Pult::k_sendFailed() { - stopWait(); - addToList(trUtf8("K not sended"), Qt::darkRed); -} - - -void KX_Pult::k_sendSucceed() { - stopWait(); - addToList(trUtf8("K sended"), Qt::darkGreen); -} - - -void KX_Pult::k_receiveFailed() { - stopWait(); - addToList(trUtf8("K not received"), Qt::darkRed); -} - - -void KX_Pult::k_receiveSucceed() { - stopWait(); - addToList(trUtf8("K received"), Qt::darkGreen); - addToList(trUtf8("Write K file \"%1\": %2 coeffs, %3 bytes").arg(PI2QString(coeffs.fileName())).arg(K.size_s()).arg(coeffs.k_content.size_s()), Qt::darkMagenta); - ui->spinSize->setValue(K.size_s()); - updateTree(); - //ui->table->setK(coeffsK.k()->data(), coeffsK.count()); -} - - -void KX_Pult::on_spinBuffer_editingFinished() { - ui->graphic->setHistorySize(ui->spinBuffer->value()); -} - - -void KX_Pult::stopWait() { - killTimer(timer); - timer = 0; - ui->labelWait->setText(" "); -} - - -void KX_Pult::updateGraph() { - ui->graphic->updateGraphics(); -} - - -void KX_Pult::updateDiag() { - ui->labelKReceiver->setText(piqt(coeffs.k_protocol->receiverDeviceName() + " - " + coeffs.k_protocol->receiverDeviceState())); - ui->labelKSender->setText(piqt(coeffs.k_protocol->senderDeviceName())); - ui->spinKSended->setValue(coeffs.k_protocol->sendCount()); - ui->spinKReceived->setValue(coeffs.k_protocol->receiveCount()); - ui->spinKWrong->setValue(coeffs.k_protocol->wrongCount()); - ui->spinKMissed->setValue(coeffs.k_protocol->missedCount()); - ui->labelKType->setText("0x" + QString::number(coeffs.k_protocol->from_k.type, 16).toUpper().rightJustified(2, '0')); - ui->labelKAddrPult->setText("0x" + QString::number(coeffs.k_protocol->from_k.addr_to, 16).toUpper().rightJustified(2, '0')); - ui->labelKAddr->setText("0x" + QString::number(coeffs.k_protocol->to_k.addr_to, 16).toUpper().rightJustified(2, '0')); - - ui->labelXReceiver->setText(piqt(prot_x->receiverDeviceName() + " - " + prot_x->receiverDeviceState())); - ui->labelXSender->setText(piqt(prot_x->senderDeviceName())); - ui->spinXSended->setValue(prot_x->sendCount()); - ui->spinXReceived->setValue(prot_x->receiveCount()); - ui->spinXWrong->setValue(prot_x->wrongCount()); - ui->spinXMissed->setValue(prot_x->missedCount()); - ui->labelXType->setText("0x" + QString::number(prot_x->from_x.type, 16).toUpper().rightJustified(2, '0')); - ui->labelXAddrPult->setText("0x" + QString::number(prot_x->from_x.addr_to, 16).toUpper().rightJustified(2, '0')); - ui->labelXAddr->setText("0x" + QString::number(prot_x->to_x.addr_to, 16).toUpper().rightJustified(2, '0')); - - ui->labelCReceiver->setText(piqt(prot_c->receiverDeviceName() + " - " + prot_c->receiverDeviceState())); - ui->labelCSender->setText(piqt(prot_c->senderDeviceName())); - ui->spinCSended->setValue(prot_c->sendCount()); - ui->spinCReceived->setValue(prot_c->receiveCount()); - ui->spinCWrong->setValue(prot_c->wrongCount()); - ui->spinCMissed->setValue(prot_c->missedCount()); - ui->labelCType->setText("0x" + QString::number(prot_c->from_c.type, 16).toUpper().rightJustified(2, '0')); - ui->labelCAddrPult->setText("0x" + QString::number(prot_c->from_c.addr_to, 16).toUpper().rightJustified(2, '0')); - ui->labelCAddr->setText("0x" + QString::number(prot_c->to_c.addr_to, 16).toUpper().rightJustified(2, '0')); -} - - -int KX_Pult::parseHeader(const QString & file, QMap & map) { - map.clear(); - QFile f(file); - if (!f.open(QIODevice::ReadOnly)) { - updateTree(); - addToList(trUtf8("Update descriptions from \"%1\": error").arg(file), Qt::darkRed); - return 0; - } - addToList(trUtf8("Update descriptions from \"%1\"").arg(file), Qt::darkMagenta); - QTextStream s(&f); - int cind = -1; - bool found = false; - //qDebug() << "\nparse" << file; - while (!s.atEnd()) { - QString line = s.readLine().trimmed(), num, name, type, comment; - int i = line.indexOf("//"); - if (i >= 0) { - comment = line.right(line.length() - i - 2); - type = comment.left(1); - comment = comment.right(comment.length() - 1).trimmed(); - line = line.left(i).trimmed(); - } - if (line.isEmpty()) continue; - if (line.contains("enum")) { - found = true; - continue; - } - if (!found) continue; - if (line.contains('}')) - break; - line.remove(',').remove(' ').remove('\t'); - i = line.indexOf("="); - if (i >= 0) { - num = line.right(line.length() - i - 1).trimmed(); - line = line.left(i).trimmed(); - } - name = line; - if (num.isEmpty()) - ++cind; - else - cind = Q2PIString(num).toInt(); - KDesc kd; - kd.index = cind; - kd.name = name; - kd.type = type; - kd.comment = comment; - map[kd.index] = kd; - //qDebug() << name << cind << type << comment; - } - cind++; - return cind; -} - - -void KX_Pult::updateKDesc(bool ask_move) { - int cind = parseHeader(kdesc_file, kdesc); - if (K.size_s() < cind) { - ui->spinSize->setValue(cind); - ui->spinSize->setStyleSheet("background-color: rgb(220, 220, 255);"); - } - bool move = false; - if (ask_move) - move = (QMessageBox::question(this, "KX Pult", "Save values at associated names?", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes); - updateTree(move); -} - - -void KX_Pult::updateCDesc() { - parseHeader(cdesc_file, cdesc); - updateCommands(); -} - - -bool stringComp(const QString & s1, const QString & s2) { - if (s1.size() != s2.size()) - return s1.size() > s2.size(); - return s1 > s2; -} - - -void KX_Pult::updateTree(bool move) { - int sp = ui->treeK->verticalScrollBar()->value(); - QApplication::setOverrideCursor(Qt::WaitCursor); - //qDebug() << "fill tree ..."; - QMap prev_val; - if (move) { - for (int i = 0; i < ui->treeK->topLevelItemCount(); ++i) { - QTreeWidgetItem * ti = ui->treeK->topLevelItem(i); - if (!ti->text(1).isEmpty()) - prev_val[ti->text(1)] = ti->text(2); - } - } - ui->treeK->clear(); - ui->treeK->setUpdatesEnabled(false); - eval.clearCustomVariables(); - for (int i = 0; i < K.size_s(); ++i) { - QTreeWidgetItem * ti = new QTreeWidgetItem(); - KDesc kd = kdesc[i]; - QString kn = QString("k%1").arg(i); - knames[kn] = i; - knames_sort << kn; - if (eval.content.findVariable(kn) < 0) - eval.content.addVariable(kn, 0., false); - if (!kd.name.isEmpty()) { - knames[kd.name] = i; - knames_sort << kd.name; - eval.content.addVariable(kd.name, 0., false); - } - if (move && !kd.name.isEmpty()) { - if (prev_val.contains(kd.name)) - coeffs.setFormula(i, Q2PIString(prev_val[kd.name])); - } - ti->setText(0, QString::number(i)); - ti->setText(1, kd.name); - ti->setText(2, PI2QString(coeffs.formula(i))); - ti->setText(3, QString::number(K[i])); - ti->setText(4, typeName(kd.type)); - ti->setText(5, kd.comment); - ui->treeK->addTopLevelItem(ti); - } - eval.content.sortVariables(); - //qDebug() << "fill tree ok"; - //qDebug() << "sort ..."; - qSort(knames_sort.begin(), knames_sort.end(), stringComp); - //qDebug() << "names" << knames_sort; - //qDebug() << "sort ok"; - QApplication::restoreOverrideCursor(); - ui->treeK->setUpdatesEnabled(true); - ui->treeK->verticalScrollBar()->setValue(sp); - calculate(); - filterTree(); -} - - -void KX_Pult::updateCommands() { - while (ui->layoutCommands->count() > 0) - delete ui->layoutCommands->itemAt(0)->widget(); - QMapIterator it(cdesc); - while (it.hasNext()) { - it.next(); - KDesc kd = it.value(); - QPushButton * b = new QPushButton(); - QString text = kd.name; - if (!kd.comment.isEmpty()) - text += QString("\n(%1)").arg(kd.comment); - b->setText(text); - b->setProperty("_command", kd.index); - connect(b, SIGNAL(clicked()), this, SLOT(commandClicked())); - ui->layoutCommands->addWidget(b); - } -} - - -void KX_Pult::filterTree() { - bool he = ui->checkKHideEmpty->isChecked(); - bool hn = ui->checkKHideNormal->isChecked(); - bool hs = ui->checkKHideExpressions->isChecked(); - bool ok = false; - QString fl = ui->lineKSearch->text(); - int lc = ui->treeK->topLevelItemCount(); - for (int i = 0; i < lc; ++i) { - QTreeWidgetItem * ti = ui->treeK->topLevelItem(i); - if (ti->text(1).isEmpty() && he) - ti->setHidden(true); - else - if (fl.isEmpty()) - ti->setHidden(false); - else - ti->setHidden(!ti->text(0).contains(fl, Qt::CaseInsensitive) && - !ti->text(1).contains(fl, Qt::CaseInsensitive) && - !ti->text(2).contains(fl, Qt::CaseInsensitive) && - !ti->text(3).contains(fl, Qt::CaseInsensitive) && - !ti->text(4).contains(fl, Qt::CaseInsensitive)); - if (hn) - if (ti->data(0, Qt::UserRole).toBool()) - ti->setHidden(true); - if (hs) { - ti->data(2, Qt::DisplayRole).toDouble(&ok); - if (!ok) - ti->setHidden(true); - } - } -} - - -void KX_Pult::calculate() { - calculated.clear(); - ui->treeK->setUpdatesEnabled(false); - ui->treeK->blockSignals(true); - QApplication::setOverrideCursor(Qt::WaitCursor); - progress(0, 100); - ui->buttonCalculate->setEnabled(false); - QApplication::processEvents(); - for (int i = 0; i < K.size_s(); ++i) { - ui->treeK->topLevelItem(i)->setToolTip(2, QString()); - ui->treeK->topLevelItem(i)->setToolTip(3, QString()); - } - for (int i = 0; i < K.size_s(); ++i) { - progress(i, K.size_s()); - calculateExpression(i, QVector()); - } - ui->buttonCalculate->setEnabled(true); - ui->progress->setValue(100); - QApplication::restoreOverrideCursor(); - ui->treeK->blockSignals(false); - ui->treeK->setUpdatesEnabled(true); -} - - -bool KX_Pult::calculateExpression(int i, QVector trace) { - if (calculated.contains(i)) return true; - trace << i; - QTreeWidgetItem * ti = ui->treeK->topLevelItem(i); - QString expr = ti->text(2); - if (expr.isEmpty() || expr == "0" || expr == "0,00000000" || expr == "0.00000000") { - markNormal(ti); - calculated << i; - K[i] = 0.; - ti->setText(3, "0"); - return true; - } - //ti->setToolTip(2, QString()); - if (!eval.check(expr)) { - markError(ti, eval.error()); - return false; - } - foreach (const QString & n, knames_sort) { - if (expr.contains(n)) { - int ki = knames.value(n, -1); - if (trace.contains(ki)) { - QString strace; - trace << ki; - for (int j = 0; j < trace.size(); ++j) { - //calculated << trace[j]; - if (j > 0) strace += " -> "; - strace += "k" + QString::number(trace[j]); - } - for (int j = 0; j < trace.size(); ++j) { - QTreeWidgetItem * pti = ui->treeK->topLevelItem(trace[j]); - markError(pti, QString("Circular dependency: %1!").arg(strace)); - } - return false; - } - if (ki < 0) { - markError(ti); - return false; - } - if (calculated.contains(ki)) { - eval.setVariable(n, K[ki]); - } else { - if (calculateExpression(ki, trace)) - eval.setVariable(n, K[ki]); - else { - markError(ti); - return false; - } - } - } - } - markNormal(ti); - calculated << i; - complexd ret = eval.evaluate(); - K[i] = ret.real(); - ti->setText(3, QString::number(K[i])); - return true; -} - - -void KX_Pult::markError(QTreeWidgetItem * item, const QString & tool_tip) { - int cc = item->columnCount(); - for (int i = 0; i < cc; ++i) - item->setBackgroundColor(i, QColor(255, 200, 200)); - if (item->toolTip(2).isEmpty()) - item->setToolTip(2, tool_tip); - if (item->toolTip(3).isEmpty()) - item->setToolTip(3, tool_tip); - item->setData(0, Qt::UserRole, false); - item->setText(3, "Error"); -} - - -void KX_Pult::markNormal(QTreeWidgetItem * item) { - int cc = item->columnCount(); - for (int i = 0; i < cc; ++i) - item->setBackground(i, Qt::NoBrush); - item->setToolTip(2, QString()); - item->setToolTip(3, QString()); - item->setData(0, Qt::UserRole, true); -} - - -void KX_Pult::progress(int val, int max) { - if (ctm.elapsed() < 50) return; - ctm.restart(); - ui->progress->setValue(qRound(val * 100. / max)); - QApplication::processEvents(); -} - - -void KX_Pult::renew(bool write) { - addToList(trUtf8("Update settings from \"%1\"").arg(PI2QString(config_)), Qt::darkMagenta); - dir.setPath(config.getValue("x.output_dir", "./Experiments/").stringValue()); - setWindowTitle(config.getValue("title", "Noname").stringValue() + trUtf8(" - KX Pult")); - //if (write) ui->configWidget->write(); - if (prot_x != 0) { - prot_x->stop(); - delete prot_x; - } - if (prot_c != 0) { - prot_c->stop(); - delete prot_c; - } - prot_x = new __KX_Protocol_X(config_, name_x); - prot_c = new __KX_Protocol_C(config_, name_c); - ui->graphic->setAutoXIncrement(prot_x->expectedFrequency() > 0. ? 1. / prot_x->expectedFrequency() : 1.); - coeffs.renew(); - CONNECT1(void, bool, prot_x, received, this, received); -} - - -void KX_Pult::toggledX(int index, bool on) { - ui->graphic->setGraphicVisible(on, index); -} - - -void KX_Pult::changedX(int index, int num) { - prot_x->to_x.x_num[index] = num; -} - - -void KX_Pult::commandClicked() { - QPushButton * b = qobject_cast(sender()); - if (!b) return; - prot_c->sendCommand(b->property("_command").toInt()); -} +#include +#include +#include +#include "kx_pult.h" +#include "ui_kx_pult.h" +#include "piqt.h" +#include "qpiconfig.h" + + +bool isNormalDouble(const double & v) { +#ifdef WINDOWS + return true; +#else + return !isnan(v) && !isinf(v); +#endif +} + + +XCheck::XCheck(int index): QWidget() { + index_ = index; + setProperty("index", index); + setMouseTracking(true); + check.setText(QString::number(index + 1) + " "); + check.setAutoFillBackground(true); + spin.setMaximum(KX_X_COUNT - 1); + QBoxLayout * l = new QBoxLayout(QBoxLayout::LeftToRight); + l->setMargin(0); + l->setSpacing(2); + l->addWidget(&check); + l->addWidget(&spin); + setLayout(l); + //check.installEventFilter(this); + //spin.installEventFilter(this); + connect(&spin, SIGNAL(valueChanged(int)), this, SLOT(spinChanged(int))); + connect(&check, SIGNAL(toggled(bool)), this, SLOT(checkChanged_(bool))); +} + + +bool XCheck::eventFilter(QObject * o, QEvent * e) { + if (e->type() == QEvent::Enter) + qApp->postEvent(this, new QEvent(e->type())); + return QWidget::eventFilter(o, e); +} + + + + +KX_Pult::KX_Pult(): QMainWindow(), config_("kx_pult.conf"), name_x("x"), name_c("c"), +config(piqt(config_), QIODevice::ReadWrite), coeffs(config_, "k", true) { + //cout << sizeof(coeffsK.k_protocol->to_k) << endl; + ui = new Ui::KX_Pult(); + ui->setupUi(this); + ui->configWidget->setQPIConfig(&config); + ui->configWidget->expandAll(); + ui->list->viewport()->installEventFilter(this); + ui->treeK->viewport()->installEventFilter(this); + ui->scrollArea->setAutoFillBackground(false); + ui->scrollAreaWidgetContents->setAutoFillBackground(false); + ui->widget->setAutoFillBackground(false); + ui->label_17->setFixedSize(preferredIconSize(1.25, this)); + log_menu.addAction(ui->actionClear); + prot_x = 0; + prot_c = 0; + show_x = config.getValue("show_x", true); + if (!show_x) + ui->tabWidget->removeTab(1); + session.setFile("session_KX_Pult.conf"); + session.addEntry(this); + session.addEntry(ui->tabWidget); + session.addEntry(ui->checkKHideEmpty); + session.addEntry(ui->checkKHideNormal); + session.addEntry(ui->checkKHideExpressions); + session.addEntry(ui->checkKAutoCalculate); + needWrite = isPause = false; + timer = 0; + //x.resize(KX_X_PACKET_NUM); + //k.resize(K_NUM); + QPalette pal = palette(); + QColor col; + ui->graphic->setGraphicsCount(0); + for (int i = 0; i < KX_X_PACKET_NUM; ++i) { + XCheck * xc = new XCheck(i); + xc->installEventFilter(this); + connect(xc, SIGNAL(valueChanged(int, int)), this, SLOT(changedX(int,int))); + connect(xc, SIGNAL(checkChanged(int, bool)), this, SLOT(toggledX(int, bool))); + col = QColor::fromHsv(360 / KX_X_PACKET_NUM * i, 255, 200); + pal.setColor(QPalette::Button, col); + pal.setColor(QPalette::Window, col); + pal.setColor(QPalette::WindowText, invertColor(col)); + xc->check.setPalette(pal); + ui->graphic->addGraphic(QString::number(i), col); + ui->graphic->setGraphicVisible(false, i); + checks << xc; + ((QGridLayout * )(ui->widgetChecks->layout()))->addWidget(xc, (i / 10) * 2, i % 10); + QLabel * lbl = new QLabel("0"); lbl->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); + values << lbl; + ((QGridLayout * )(ui->widgetChecks->layout()))->addWidget(lbl, (i / 10) * 2 + 1, i % 10); + //xc->show(); + } + renew(); + icon_record = QIcon(":/icons/media-record.png"); + icon_stop = QIcon(":/icons/media-playback-stop.png"); + outdir = dir.absolutePath(); + if (!dir.exists()) dir.mkdir(outdir); + outdir += "/"; + ui->treeK->setColumnWidth(0, 60); + ui->treeK->setColumnWidth(1, 250); + ui->treeK->setColumnWidth(3, 100); + ui->treeK->setColumnWidth(4, 100); + //ui->table->setK(coeffsK.k()->data(), coeffsK.count()); + ui->spinSize->setValue(K.size_s()); + addToList(trUtf8("Read K file \"%1\": %2 coeffs, %3 bytes").arg(PI2QString(coeffs.fileName())).arg(K.size_s()).arg(coeffs.k_content.size_s()), Qt::darkMagenta); + CONNECT(void, &coeffs, sendFailed, this, pip_sendFailed); + CONNECT(void, &coeffs, sendSucceed, this, pip_sendSucceed); + CONNECT(void, &coeffs, receiveFailed, this, pip_receiveFailed); + CONNECT(void, &coeffs, receiveSucceed, this, pip_receiveSucceed); + connect(this, SIGNAL(q_k_sendFailed()), this, SLOT(k_sendFailed()), Qt::QueuedConnection); + connect(this, SIGNAL(q_k_sendSucceed()), this, SLOT(k_sendSucceed()), Qt::QueuedConnection); + connect(this, SIGNAL(q_k_receiveFailed()), this, SLOT(k_receiveFailed()), Qt::QueuedConnection); + connect(this, SIGNAL(q_k_receiveSucceed()), this, SLOT(k_receiveSucceed()), Qt::QueuedConnection); + connect(&timer_diag, SIGNAL(timeout()), this, SLOT(updateDiag())); + connect(&session, SIGNAL(loading(QPIConfig&)), this, SLOT(loading(QPIConfig&))); + connect(&session, SIGNAL(saving(QPIConfig&)), this, SLOT(saving(QPIConfig&))); + connect(ui->checkKHideEmpty, SIGNAL(toggled(bool)), this, SLOT(filterTree())); + connect(ui->checkKHideNormal, SIGNAL(toggled(bool)), this, SLOT(filterTree())); + connect(ui->checkKHideExpressions, SIGNAL(toggled(bool)), this, SLOT(filterTree())); + connect(ui->lineKSearch, SIGNAL(textChanged(QString)), this, SLOT(filterTree())); + session.load(); + updateKDesc(); + updateCDesc(); + timer_diag.start(40); + timer_update = startTimer(25); +} + + +KX_Pult::~KX_Pult() { + session.save(); +} + + +void KX_Pult::loading(QPIConfig & conf) { + kdesc_file = conf.getValue("kdesc_file").stringValue(); + cdesc_file = conf.getValue("cdesc_file").stringValue(); +} + + +void KX_Pult::saving(QPIConfig & conf) { + conf.setValue("kdesc_file", kdesc_file); + conf.setValue("cdesc_file", cdesc_file); +} + + +bool KX_Pult::eventFilter(QObject * o, QEvent * e) { + if (o == ui->list->viewport()) { + if (e->type() == QEvent::ContextMenu) { + clear_target = 0; + log_menu.popup(((QContextMenuEvent*)e)->globalPos()); + } + return QMainWindow::eventFilter(o, e); + } + if (o == ui->treeK->viewport()) { + if (e->type() == QEvent::ContextMenu) { + clear_target = 1; + log_menu.popup(((QContextMenuEvent*)e)->globalPos()); + } + return QMainWindow::eventFilter(o, e); + } + int ind = o->property("index").toInt(); + //qDebug() << "event" << i << e->type(); + switch (e->type()) { + case QEvent::Enter: + ui->graphic->setAutoUpdate(false); + for (int i = 0; i < KX_X_PACKET_NUM; ++i) + ui->graphic->setGraphicLineWidth(ind == i ? 3. : 1., i); + ui->graphic->setAutoUpdate(true); + ui->graphic->update(); + break; + case QEvent::Leave: + ui->graphic->setAutoUpdate(false); + for (int i = 0; i < KX_X_PACKET_NUM; ++i) + ui->graphic->setGraphicLineWidth(1., i); + ui->graphic->setAutoUpdate(true); + ui->graphic->update(); + break; + default: break; + } + return QMainWindow::eventFilter(o, e); +} + + +void KX_Pult::timerEvent(QTimerEvent * e) { + if (e->timerId() == timer_update) { + if (need_update) { + need_update = false; + ui->graphic->updateGraphics(); + } + } + if (e->timerId() == timer) { + static QString sPI = QString::number(atan(1) * 4., 'f', 14).leftJustified(14); + static int cnt = 0; + int si = qMax(cnt - 6, 0); + ++cnt; + cnt %= 23; + ui->labelWait->setText(QString(si, QChar(' ')) + sPI.mid(cnt - 6, 6).trimmed()); + if (!coeffs.isReady()) return; + //ui->table->setK(coeffsK.k()->data(), coeffsK.count()); + //ui->table->showK(); + } +} + + +void KX_Pult::setControlsEnable(bool enable) { + foreach (XCheck * i, checks) + i->setEnabled(enable); + ui->buttonShowAll->setEnabled(enable); + ui->buttonHideAll->setEnabled(enable); +} + + +void KX_Pult::setX(const KX_X_Data & data) { + if (!show_x) return; + //ui->graphic->lock(); + for (int i = 0; i < KX_X_PACKET_NUM; ++i) { + if (!isNormalDouble(data.x_data[i])) continue; + ui->graphic->addPoint(data.x_data[i], i, false); + values[i]->setText(QString("(%1): %2").arg(data.x_num[i]).arg(data.x_data[i])); + } + //ui->graphic->unlock(); + if (!isPause) { + need_update = true; + } + if (!needWrite) return; + stream << QString::number(tm.elapsed() / 1000., 'f', 3) << " " << QTime::currentTime().toString("hh:mm:ss") << " " << wcnt++; + for (int i = 0; i < KX_X_PACKET_NUM; ++i) + stream << " " << QString::number(data.x_data[i], 'f', 4); + stream << "\n"; +} + + +void KX_Pult::addToList(const QString & s, const QColor & c) { + ui->list->addItem(QDateTime::currentDateTime().toString("dd/MM/yyyy hh:ss - ") + s); + ui->list->item(ui->list->count() - 1)->setTextColor(c); + ui->list->scrollToBottom(); +} + + +void KX_Pult::on_buttonRecord_clicked() { + static bool isRec = false; + int cinc = 0; + QString str; + isRec = !isRec; + setControlsEnable(!isRec); + if (isRec) { + tm.restart(); + file.close(); + file.setFileName(outdir + getNewFileName(cinc)); + while (file.exists()) + file.setFileName(outdir + getNewFileName(cinc++)); + file.open(QIODevice::ReadWrite); + stream.setDevice(&file); + stream << "T V C"; + for (int i = 0; i < KX_X_PACKET_NUM; ++i) + stream << " X" + QString::number(checks[i]->spin.value()); + stream << "\n"; + wcnt = 0; + needWrite = true; + ui->buttonRecord->setText(trUtf8("Finish record")); + ui->buttonRecord->setIcon(icon_stop); + emit recordStarted(QFileInfo(file).completeBaseName()); + } else { + needWrite = false; + stream.setDevice(0); + file.close(); + ui->buttonRecord->setText(trUtf8("Start record")); + ui->buttonRecord->setIcon(icon_record); + emit recordStopped(QFileInfo(file).completeBaseName()); + } +} + + +void KX_Pult::on_actionClear_triggered() { + switch (clear_target) { + case 0: + ui->list->clear(); + break; + case 1: + clearSelected(); + break; + default: break; + } +} + + +void KX_Pult::clearSelected() { + QList si = ui->treeK->selectedItems(); + ui->treeK->setUpdatesEnabled(false); + ui->treeK->blockSignals(true); + foreach (QTreeWidgetItem * i, si) { + int ki = i->text(0).toInt(); + i->setText(2, ""); + coeffs.setFormula(ki, ""); + } + ui->treeK->blockSignals(false); + ui->treeK->setUpdatesEnabled(true); + if (ui->checkKAutoCalculate->isChecked()) { + QApplication::processEvents(); + calculate(); + } +} + + +QString KX_Pult::typeName(const QString & n) const { + if (n.isEmpty()) return ""; + switch (n[0].toLatin1()) { + case 'l': return trUtf8("list"); break; + case 'b': return trUtf8("bool"); break; + case 'n': return trUtf8("int"); break; + case 'f': return trUtf8("double"); break; + case 'c': return trUtf8("color"); break; + case 'r': return trUtf8("rect"); break; + case 'a': return trUtf8("rect"); break; + case 'p': return trUtf8("point"); break; + case 'v': return trUtf8("vector"); break; + case 'i': return trUtf8("IP"); break; + case 'e': return trUtf8("enum"); break; + case 'F': return trUtf8("file"); break; + case 'D': return trUtf8("dir"); break; + } + return ""; +} + + +void KX_Pult::received(bool ok) { + if (!ok) return; + setX(prot_x->from_x); +} + + +void KX_Pult::on_treeK_itemClicked(QTreeWidgetItem * item, int column) { + Qt::ItemFlags f = Qt::ItemIsEnabled | Qt::ItemIsSelectable; + if (column == 2) f |= Qt::ItemIsEditable; + item->setFlags(f); +} + + +void KX_Pult::on_treeK_itemChanged(QTreeWidgetItem * item, int column) { + if (column != 2) return; + int ki = item->text(0).toInt(); + coeffs.setFormula(ki, piqt(item->text(column))); + if (ui->checkKAutoCalculate->isChecked()) + calculate(); +} + + +QString KX_Pult::getNewFileName(int inc) { + dir.refresh(); + dir.setNameFilters(QStringList("Experiment_*.txt")); + return "Experiment_" + QDateTime::currentDateTime().toString("dd_MM_yy__hh_mm_ss") + "__" + + QString::number(dir.entryList().count() + inc) + ".txt"; +} + + +void KX_Pult::on_buttonSendK_clicked() { + on_buttonWrite_clicked(); + coeffs.sendCoeffs(); + if (timer != 0) killTimer(timer); + timer = startTimer(100); +} + + +void KX_Pult::on_buttonReceiveK_clicked() { + coeffs.receiveCoeffs(); + if (timer != 0) killTimer(timer); + timer = startTimer(100); +} + + +void KX_Pult::on_buttonShowAll_clicked() { + for (int i = 0; i < KX_X_PACKET_NUM; ++i) { + checks[i]->check.setChecked(true); + //ui->graphic->setGraphicVisible(true, i); + } +} + + +void KX_Pult::on_buttonHideAll_clicked() { + for (int i = 0; i < KX_X_PACKET_NUM; ++i) { + checks[i]->check.setChecked(false); + //ui->graphic->setGraphicVisible(false, i); + } +} + + +void KX_Pult::on_buttonRead_clicked() { + coeffs.readCoeffs(); + addToList(trUtf8("Read K file \"%1\": %2 coeffs, %3 bytes").arg(PI2QString(coeffs.fileName())).arg(K.size_s()).arg(coeffs.k_content.size_s()), Qt::darkMagenta); + updateTree(); +} + + +void KX_Pult::on_buttonWrite_clicked() { + coeffs.writeCoeffs(); + addToList(trUtf8("Write K file \"%1\": %2 coeffs, %3 bytes").arg(PI2QString(coeffs.fileName())).arg(K.size_s()).arg(coeffs.k_content.size_s()), Qt::darkMagenta); +} + + +void KX_Pult::on_buttonResize_clicked() { + K.resize(ui->spinSize->value()); + coeffs.formulas.resize(ui->spinSize->value()); + ui->spinSize->setStyleSheet(""); + updateTree(); +} + + +void KX_Pult::on_buttonSetKDesc_clicked() { + QString ret = QFileDialog::getOpenFileName(this, trUtf8("Select *.h file with K description"), kdesc_file, "C/C++ header files(*.h *.hpp);;All files(*)"); + if (ret.isEmpty()) return; + kdesc_file = QDir::current().relativeFilePath(ret); + updateKDesc(true); +} + + +void KX_Pult::on_buttonSetCDesc_clicked() { + QString ret = QFileDialog::getOpenFileName(this, trUtf8("Select *.h file with C description"), cdesc_file, "C/C++ header files(*.h *.hpp);;All files(*)"); + if (ret.isEmpty()) return; + cdesc_file = QDir::current().relativeFilePath(ret); + updateCDesc(); +} + + +void KX_Pult::on_spinSize_valueChanged(int) { + ui->spinSize->setStyleSheet(""); +} + + +void KX_Pult::k_sendFailed() { + stopWait(); + addToList(trUtf8("K not sended"), Qt::darkRed); +} + + +void KX_Pult::k_sendSucceed() { + stopWait(); + addToList(trUtf8("K sended"), Qt::darkGreen); +} + + +void KX_Pult::k_receiveFailed() { + stopWait(); + addToList(trUtf8("K not received"), Qt::darkRed); +} + + +void KX_Pult::k_receiveSucceed() { + stopWait(); + addToList(trUtf8("K received"), Qt::darkGreen); + addToList(trUtf8("Write K file \"%1\": %2 coeffs, %3 bytes").arg(PI2QString(coeffs.fileName())).arg(K.size_s()).arg(coeffs.k_content.size_s()), Qt::darkMagenta); + ui->spinSize->setValue(K.size_s()); + updateTree(); + //ui->table->setK(coeffsK.k()->data(), coeffsK.count()); +} + + +void KX_Pult::on_spinBuffer_editingFinished() { + ui->graphic->setHistorySize(ui->spinBuffer->value()); +} + + +void KX_Pult::stopWait() { + killTimer(timer); + timer = 0; + ui->labelWait->setText(" "); +} + + +void KX_Pult::updateGraph() { + ui->graphic->updateGraphics(); +} + + +void KX_Pult::updateDiag() { + ui->labelKReceiver->setText(piqt(coeffs.k_protocol->receiverDeviceName() + " - " + coeffs.k_protocol->receiverDeviceState())); + ui->labelKSender->setText(piqt(coeffs.k_protocol->senderDeviceName())); + ui->spinKSended->setValue(coeffs.k_protocol->sendCount()); + ui->spinKReceived->setValue(coeffs.k_protocol->receiveCount()); + ui->spinKWrong->setValue(coeffs.k_protocol->wrongCount()); + ui->spinKMissed->setValue(coeffs.k_protocol->missedCount()); + ui->labelKType->setText("0x" + QString::number(coeffs.k_protocol->from_k.type, 16).toUpper().rightJustified(2, '0')); + ui->labelKAddrPult->setText("0x" + QString::number(coeffs.k_protocol->from_k.addr_to, 16).toUpper().rightJustified(2, '0')); + ui->labelKAddr->setText("0x" + QString::number(coeffs.k_protocol->to_k.addr_to, 16).toUpper().rightJustified(2, '0')); + + ui->labelXReceiver->setText(piqt(prot_x->receiverDeviceName() + " - " + prot_x->receiverDeviceState())); + ui->labelXSender->setText(piqt(prot_x->senderDeviceName())); + ui->spinXSended->setValue(prot_x->sendCount()); + ui->spinXReceived->setValue(prot_x->receiveCount()); + ui->spinXWrong->setValue(prot_x->wrongCount()); + ui->spinXMissed->setValue(prot_x->missedCount()); + ui->labelXType->setText("0x" + QString::number(prot_x->from_x.type, 16).toUpper().rightJustified(2, '0')); + ui->labelXAddrPult->setText("0x" + QString::number(prot_x->from_x.addr_to, 16).toUpper().rightJustified(2, '0')); + ui->labelXAddr->setText("0x" + QString::number(prot_x->to_x.addr_to, 16).toUpper().rightJustified(2, '0')); + + ui->labelCReceiver->setText(piqt(prot_c->receiverDeviceName() + " - " + prot_c->receiverDeviceState())); + ui->labelCSender->setText(piqt(prot_c->senderDeviceName())); + ui->spinCSended->setValue(prot_c->sendCount()); + ui->spinCReceived->setValue(prot_c->receiveCount()); + ui->spinCWrong->setValue(prot_c->wrongCount()); + ui->spinCMissed->setValue(prot_c->missedCount()); + ui->labelCType->setText("0x" + QString::number(prot_c->from_c.type, 16).toUpper().rightJustified(2, '0')); + ui->labelCAddrPult->setText("0x" + QString::number(prot_c->from_c.addr_to, 16).toUpper().rightJustified(2, '0')); + ui->labelCAddr->setText("0x" + QString::number(prot_c->to_c.addr_to, 16).toUpper().rightJustified(2, '0')); +} + + +int KX_Pult::parseHeader(const QString & file, QMap & map) { + map.clear(); + QFile f(file); + if (!f.open(QIODevice::ReadOnly)) { + updateTree(); + addToList(trUtf8("Update descriptions from \"%1\": error").arg(file), Qt::darkRed); + return 0; + } + addToList(trUtf8("Update descriptions from \"%1\"").arg(file), Qt::darkMagenta); + QTextStream s(&f); + int cind = -1; + bool found = false; + //qDebug() << "\nparse" << file; + while (!s.atEnd()) { + QString line = s.readLine().trimmed(), num, name, type, comment; + int i = line.indexOf("//"); + if (i >= 0) { + comment = line.right(line.length() - i - 2); + type = comment.left(1); + comment = comment.right(comment.length() - 1).trimmed(); + line = line.left(i).trimmed(); + } + if (line.isEmpty()) continue; + if (line.contains("enum")) { + found = true; + continue; + } + if (!found) continue; + if (line.contains('}')) + break; + line.remove(',').remove(' ').remove('\t'); + i = line.indexOf("="); + if (i >= 0) { + num = line.right(line.length() - i - 1).trimmed(); + line = line.left(i).trimmed(); + } + name = line; + if (num.isEmpty()) + ++cind; + else + cind = Q2PIString(num).toInt(); + KDesc kd; + kd.index = cind; + kd.name = name; + kd.type = type; + kd.comment = comment; + map[kd.index] = kd; + //qDebug() << name << cind << type << comment; + } + cind++; + return cind; +} + + +void KX_Pult::updateKDesc(bool ask_move) { + int cind = parseHeader(kdesc_file, kdesc); + if (K.size_s() < cind) { + ui->spinSize->setValue(cind); + ui->spinSize->setStyleSheet("background-color: rgb(220, 220, 255);"); + } + bool move = false; + if (ask_move) + move = (QMessageBox::question(this, "KX Pult", "Save values at associated names?", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes); + updateTree(move); +} + + +void KX_Pult::updateCDesc() { + parseHeader(cdesc_file, cdesc); + updateCommands(); +} + + +bool stringComp(const QString & s1, const QString & s2) { + if (s1.size() != s2.size()) + return s1.size() > s2.size(); + return s1 > s2; +} + + +void KX_Pult::updateTree(bool move) { + int sp = ui->treeK->verticalScrollBar()->value(); + QApplication::setOverrideCursor(Qt::WaitCursor); + //qDebug() << "fill tree ..."; + QMap prev_val; + if (move) { + for (int i = 0; i < ui->treeK->topLevelItemCount(); ++i) { + QTreeWidgetItem * ti = ui->treeK->topLevelItem(i); + if (!ti->text(1).isEmpty()) + prev_val[ti->text(1)] = ti->text(2); + } + } + ui->treeK->clear(); + ui->treeK->setUpdatesEnabled(false); + eval.clearCustomVariables(); + for (int i = 0; i < K.size_s(); ++i) { + QTreeWidgetItem * ti = new QTreeWidgetItem(); + KDesc kd = kdesc[i]; + QString kn = QString("k%1").arg(i); + knames[kn] = i; + knames_sort << kn; + if (eval.content.findVariable(kn) < 0) + eval.content.addVariable(kn, 0., false); + if (!kd.name.isEmpty()) { + knames[kd.name] = i; + knames_sort << kd.name; + eval.content.addVariable(kd.name, 0., false); + } + if (move && !kd.name.isEmpty()) { + if (prev_val.contains(kd.name)) + coeffs.setFormula(i, Q2PIString(prev_val[kd.name])); + } + ti->setText(0, QString::number(i)); + ti->setText(1, kd.name); + ti->setText(2, PI2QString(coeffs.formula(i))); + ti->setText(3, QString::number(K[i])); + ti->setText(4, typeName(kd.type)); + ti->setText(5, kd.comment); + ui->treeK->addTopLevelItem(ti); + } + eval.content.sortVariables(); + //qDebug() << "fill tree ok"; + //qDebug() << "sort ..."; + qSort(knames_sort.begin(), knames_sort.end(), stringComp); + //qDebug() << "names" << knames_sort; + //qDebug() << "sort ok"; + QApplication::restoreOverrideCursor(); + ui->treeK->setUpdatesEnabled(true); + ui->treeK->verticalScrollBar()->setValue(sp); + calculate(); + filterTree(); +} + + +void KX_Pult::updateCommands() { + while (ui->layoutCommands->count() > 0) + delete ui->layoutCommands->itemAt(0)->widget(); + QMapIterator it(cdesc); + while (it.hasNext()) { + it.next(); + KDesc kd = it.value(); + QPushButton * b = new QPushButton(); + QString text = kd.name; + if (!kd.comment.isEmpty()) + text += QString("\n(%1)").arg(kd.comment); + b->setText(text); + b->setProperty("_command", kd.index); + connect(b, SIGNAL(clicked()), this, SLOT(commandClicked())); + ui->layoutCommands->addWidget(b); + } +} + + +void KX_Pult::filterTree() { + bool he = ui->checkKHideEmpty->isChecked(); + bool hn = ui->checkKHideNormal->isChecked(); + bool hs = ui->checkKHideExpressions->isChecked(); + bool ok = false; + QString fl = ui->lineKSearch->text(); + int lc = ui->treeK->topLevelItemCount(); + for (int i = 0; i < lc; ++i) { + QTreeWidgetItem * ti = ui->treeK->topLevelItem(i); + if (ti->text(1).isEmpty() && he) + ti->setHidden(true); + else + if (fl.isEmpty()) + ti->setHidden(false); + else + ti->setHidden(!ti->text(0).contains(fl, Qt::CaseInsensitive) && + !ti->text(1).contains(fl, Qt::CaseInsensitive) && + !ti->text(2).contains(fl, Qt::CaseInsensitive) && + !ti->text(3).contains(fl, Qt::CaseInsensitive) && + !ti->text(4).contains(fl, Qt::CaseInsensitive)); + if (hn) + if (ti->data(0, Qt::UserRole).toBool()) + ti->setHidden(true); + if (hs) { + ti->data(2, Qt::DisplayRole).toDouble(&ok); + if (!ok) + ti->setHidden(true); + } + } +} + + +void KX_Pult::calculate() { + calculated.clear(); + ui->treeK->setUpdatesEnabled(false); + ui->treeK->blockSignals(true); + QApplication::setOverrideCursor(Qt::WaitCursor); + progress(0, 100); + ui->buttonCalculate->setEnabled(false); + QApplication::processEvents(); + for (int i = 0; i < K.size_s(); ++i) { + ui->treeK->topLevelItem(i)->setToolTip(2, QString()); + ui->treeK->topLevelItem(i)->setToolTip(3, QString()); + } + for (int i = 0; i < K.size_s(); ++i) { + progress(i, K.size_s()); + calculateExpression(i, QVector()); + } + ui->buttonCalculate->setEnabled(true); + ui->progress->setValue(100); + QApplication::restoreOverrideCursor(); + ui->treeK->blockSignals(false); + ui->treeK->setUpdatesEnabled(true); +} + + +bool KX_Pult::calculateExpression(int i, QVector trace) { + if (calculated.contains(i)) return true; + trace << i; + QTreeWidgetItem * ti = ui->treeK->topLevelItem(i); + QString expr = ti->text(2); + if (expr.isEmpty() || expr == "0" || expr == "0,00000000" || expr == "0.00000000") { + markNormal(ti); + calculated << i; + K[i] = 0.; + ti->setText(3, "0"); + return true; + } + //ti->setToolTip(2, QString()); + if (!eval.check(expr)) { + markError(ti, eval.error()); + return false; + } + foreach (const QString & n, knames_sort) { + if (expr.contains(n)) { + int ki = knames.value(n, -1); + if (trace.contains(ki)) { + QString strace; + trace << ki; + for (int j = 0; j < trace.size(); ++j) { + //calculated << trace[j]; + if (j > 0) strace += " -> "; + strace += "k" + QString::number(trace[j]); + } + for (int j = 0; j < trace.size(); ++j) { + QTreeWidgetItem * pti = ui->treeK->topLevelItem(trace[j]); + markError(pti, QString("Circular dependency: %1!").arg(strace)); + } + return false; + } + if (ki < 0) { + markError(ti); + return false; + } + if (calculated.contains(ki)) { + eval.setVariable(n, K[ki]); + } else { + if (calculateExpression(ki, trace)) + eval.setVariable(n, K[ki]); + else { + markError(ti); + return false; + } + } + } + } + markNormal(ti); + calculated << i; + complexd ret = eval.evaluate(); + K[i] = ret.real(); + ti->setText(3, QString::number(K[i])); + return true; +} + + +void KX_Pult::markError(QTreeWidgetItem * item, const QString & tool_tip) { + int cc = item->columnCount(); + for (int i = 0; i < cc; ++i) + item->setBackgroundColor(i, QColor(255, 200, 200)); + if (item->toolTip(2).isEmpty()) + item->setToolTip(2, tool_tip); + if (item->toolTip(3).isEmpty()) + item->setToolTip(3, tool_tip); + item->setData(0, Qt::UserRole, false); + item->setText(3, "Error"); +} + + +void KX_Pult::markNormal(QTreeWidgetItem * item) { + int cc = item->columnCount(); + for (int i = 0; i < cc; ++i) + item->setBackground(i, Qt::NoBrush); + item->setToolTip(2, QString()); + item->setToolTip(3, QString()); + item->setData(0, Qt::UserRole, true); +} + + +void KX_Pult::progress(int val, int max) { + if (ctm.elapsed() < 50) return; + ctm.restart(); + ui->progress->setValue(qRound(val * 100. / max)); + QApplication::processEvents(); +} + + +void KX_Pult::renew(bool write) { + addToList(trUtf8("Update settings from \"%1\"").arg(PI2QString(config_)), Qt::darkMagenta); + dir.setPath(config.getValue("x.output_dir", "./Experiments/").stringValue()); + setWindowTitle(config.getValue("title", "Noname").stringValue() + trUtf8(" - KX Pult")); + //if (write) ui->configWidget->write(); + if (prot_x != 0) { + prot_x->stop(); + delete prot_x; + } + if (prot_c != 0) { + prot_c->stop(); + delete prot_c; + } + prot_x = new __KX_Protocol_X(config_, name_x); + prot_c = new __KX_Protocol_C(config_, name_c); + ui->graphic->setAutoXIncrement(prot_x->expectedFrequency() > 0. ? 1. / prot_x->expectedFrequency() : 1.); + coeffs.renew(); + CONNECT1(void, bool, prot_x, received, this, received); +} + + +void KX_Pult::toggledX(int index, bool on) { + ui->graphic->setGraphicVisible(on, index); +} + + +void KX_Pult::changedX(int index, int num) { + prot_x->to_x.x_num[index] = num; +} + + +void KX_Pult::commandClicked() { + QPushButton * b = qobject_cast(sender()); + if (!b) return; + prot_c->sendCommand(b->property("_command").toInt()); +} diff --git a/kx_utils/kx_pult.h b/kx_utils/kx_pult.h index 2e2d21b..b2daff8 100644 --- a/kx_utils/kx_pult.h +++ b/kx_utils/kx_pult.h @@ -1,170 +1,170 @@ -#ifndef KX_PULT_H -#define KX_PULT_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "kx_coeffs.h" -#include "kx_protocol_x.h" -#include "kx_protocol_c.h" -#include "piqt.h" -#include "session_manager.h" -#include "qpievaluator.h" - - -class XCheck: public QWidget { - Q_OBJECT -public: - explicit XCheck(int index); - QCheckBox check; - QSpinBox spin; -private: - bool eventFilter(QObject * o, QEvent * e); - int index_; -private slots: - void spinChanged(int value) {check.setChecked(true); emit valueChanged(index_, value);} - void checkChanged_(bool value) {emit checkChanged(index_, value);} -signals: - void valueChanged(int index, int value); - void checkChanged(int index, bool on); -}; - - -namespace Ui { - class KX_Pult; -}; - -class KX_Pult: public QMainWindow, public PIObject -{ - Q_OBJECT - PIOBJECT(KX_Pult) -public: - KX_Pult(); - ~KX_Pult(); - -private: - struct KDesc { - KDesc() {index = -1;} - int index; - QString name; - QString type; - QString comment; - QString value; - }; - - bool eventFilter(QObject * o, QEvent * e); - void timerEvent(QTimerEvent * ); - void setControlsEnable(bool enable); - void setX(const KX_X_Data & data); - void addToList(const QString & s, const QColor & c); - QString getNewFileName(int inc); - QColor invertColor(QColor col) {return QColor(255 - col.red(), 255 - col.green(), 255 - col.blue());} - void stopWait(); - bool calculateExpression(int i, QVector trace); - void markError(QTreeWidgetItem * item, const QString & tool_tip = QString()); - void markNormal(QTreeWidgetItem * item); - void progress(int val, int max); - void clearSelected(); - QString typeName(const QString & n) const; - int parseHeader(const QString & file, QMap & map); - - EVENT_HANDLER1(void, received, bool, ok); - EVENT_HANDLER(void, pip_sendFailed) {emit q_k_sendFailed();} - EVENT_HANDLER(void, pip_sendSucceed) {emit q_k_sendSucceed();} - EVENT_HANDLER(void, pip_receiveFailed) {emit q_k_receiveFailed();} - EVENT_HANDLER(void, pip_receiveSucceed) {emit q_k_receiveSucceed();} - - QVector checks; - QVector values; - - Ui::KX_Pult * ui; - PIString config_, name_x, name_c; - QDir dir; - QString outdir, kdesc_file, cdesc_file; - QFile file; - QTime tm, ctm; - QIcon icon_record, icon_stop; - QTextStream stream; - QTimer timer_diag; - QMap kdesc, cdesc; - QMap knames; - QSet calculated; - QStringList knames_sort; - QPIEvaluator eval; - SessionManager session; - QPIConfig config; - QMenu log_menu; - //QVector k, x; - KX_Coefficients coeffs; - __KX_Protocol_X * prot_x; - __KX_Protocol_C * prot_c; - int csize, wcnt, timer, timer_update, clear_target; - bool needWrite, isPause, need_update, show_x; - -private slots: - void loading(QPIConfig & conf); - void saving(QPIConfig & conf); - void updateGraph(); - void updateDiag(); - void updateKDesc(bool ask_move = false); - void updateCDesc(); - void updateTree(bool move = false); - void updateCommands(); - void filterTree(); - void calculate(); - void renew(bool write = true); - void toggledX(int index, bool on); - void changedX(int index, int num); - void commandClicked(); - void k_sendFailed(); - void k_sendSucceed(); - void k_receiveFailed(); - void k_receiveSucceed(); - void on_spinBuffer_editingFinished(); - void on_buttonSendK_clicked(); - void on_buttonReceiveK_clicked(); - void on_buttonShowAll_clicked(); - void on_buttonHideAll_clicked(); - void on_buttonRead_clicked(); - void on_buttonWrite_clicked(); - void on_buttonResize_clicked(); - void on_buttonSetKDesc_clicked(); - void on_buttonReparseKDesc_clicked() {updateKDesc(true);} - void on_buttonSetCDesc_clicked(); - void on_buttonReparseCDesc_clicked() {updateCDesc();} - void on_buttonCalculate_clicked() {calculate();} - void on_buttonApply_clicked() {renew();} - void on_spinSize_valueChanged(int); - void on_buttonPause_toggled(bool on) {isPause = on;} - void on_buttonRecord_clicked(); - void on_treeK_itemClicked(QTreeWidgetItem * item, int column); - void on_treeK_itemChanged(QTreeWidgetItem * item, int column); - void on_actionClear_triggered(); - -signals: - void q_k_sendFailed(); - void q_k_sendSucceed(); - void q_k_receiveFailed(); - void q_k_receiveSucceed(); - void recordStarted(const QString & fileName); - void recordStopped(const QString & fileName); - -}; - -#endif // KX_PULT_H - +#ifndef KX_PULT_H +#define KX_PULT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "kx_coeffs.h" +#include "kx_protocol_x.h" +#include "kx_protocol_c.h" +#include "piqt.h" +#include "session_manager.h" +#include "qpievaluator.h" + + +class XCheck: public QWidget { + Q_OBJECT +public: + explicit XCheck(int index); + QCheckBox check; + QSpinBox spin; +private: + bool eventFilter(QObject * o, QEvent * e); + int index_; +private slots: + void spinChanged(int value) {check.setChecked(true); emit valueChanged(index_, value);} + void checkChanged_(bool value) {emit checkChanged(index_, value);} +signals: + void valueChanged(int index, int value); + void checkChanged(int index, bool on); +}; + + +namespace Ui { + class KX_Pult; +}; + +class KX_Pult: public QMainWindow, public PIObject +{ + Q_OBJECT + PIOBJECT(KX_Pult) +public: + KX_Pult(); + ~KX_Pult(); + +private: + struct KDesc { + KDesc() {index = -1;} + int index; + QString name; + QString type; + QString comment; + QString value; + }; + + bool eventFilter(QObject * o, QEvent * e); + void timerEvent(QTimerEvent * ); + void setControlsEnable(bool enable); + void setX(const KX_X_Data & data); + void addToList(const QString & s, const QColor & c); + QString getNewFileName(int inc); + QColor invertColor(QColor col) {return QColor(255 - col.red(), 255 - col.green(), 255 - col.blue());} + void stopWait(); + bool calculateExpression(int i, QVector trace); + void markError(QTreeWidgetItem * item, const QString & tool_tip = QString()); + void markNormal(QTreeWidgetItem * item); + void progress(int val, int max); + void clearSelected(); + QString typeName(const QString & n) const; + int parseHeader(const QString & file, QMap & map); + + EVENT_HANDLER1(void, received, bool, ok); + EVENT_HANDLER(void, pip_sendFailed) {emit q_k_sendFailed();} + EVENT_HANDLER(void, pip_sendSucceed) {emit q_k_sendSucceed();} + EVENT_HANDLER(void, pip_receiveFailed) {emit q_k_receiveFailed();} + EVENT_HANDLER(void, pip_receiveSucceed) {emit q_k_receiveSucceed();} + + QVector checks; + QVector values; + + Ui::KX_Pult * ui; + PIString config_, name_x, name_c; + QDir dir; + QString outdir, kdesc_file, cdesc_file; + QFile file; + QTime tm, ctm; + QIcon icon_record, icon_stop; + QTextStream stream; + QTimer timer_diag; + QMap kdesc, cdesc; + QMap knames; + QSet calculated; + QStringList knames_sort; + QPIEvaluator eval; + SessionManager session; + QPIConfig config; + QMenu log_menu; + //QVector k, x; + KX_Coefficients coeffs; + __KX_Protocol_X * prot_x; + __KX_Protocol_C * prot_c; + int csize, wcnt, timer, timer_update, clear_target; + bool needWrite, isPause, need_update, show_x; + +private slots: + void loading(QPIConfig & conf); + void saving(QPIConfig & conf); + void updateGraph(); + void updateDiag(); + void updateKDesc(bool ask_move = false); + void updateCDesc(); + void updateTree(bool move = false); + void updateCommands(); + void filterTree(); + void calculate(); + void renew(bool write = true); + void toggledX(int index, bool on); + void changedX(int index, int num); + void commandClicked(); + void k_sendFailed(); + void k_sendSucceed(); + void k_receiveFailed(); + void k_receiveSucceed(); + void on_spinBuffer_editingFinished(); + void on_buttonSendK_clicked(); + void on_buttonReceiveK_clicked(); + void on_buttonShowAll_clicked(); + void on_buttonHideAll_clicked(); + void on_buttonRead_clicked(); + void on_buttonWrite_clicked(); + void on_buttonResize_clicked(); + void on_buttonSetKDesc_clicked(); + void on_buttonReparseKDesc_clicked() {updateKDesc(true);} + void on_buttonSetCDesc_clicked(); + void on_buttonReparseCDesc_clicked() {updateCDesc();} + void on_buttonCalculate_clicked() {calculate();} + void on_buttonApply_clicked() {renew();} + void on_spinSize_valueChanged(int); + void on_buttonPause_toggled(bool on) {isPause = on;} + void on_buttonRecord_clicked(); + void on_treeK_itemClicked(QTreeWidgetItem * item, int column); + void on_treeK_itemChanged(QTreeWidgetItem * item, int column); + void on_actionClear_triggered(); + +signals: + void q_k_sendFailed(); + void q_k_sendSucceed(); + void q_k_receiveFailed(); + void q_k_receiveSucceed(); + void recordStarted(const QString & fileName); + void recordStopped(const QString & fileName); + +}; + +#endif // KX_PULT_H + diff --git a/kx_utils/main_kx_pult.cpp b/kx_utils/main_kx_pult.cpp index e5c1786..8655422 100644 --- a/kx_utils/main_kx_pult.cpp +++ b/kx_utils/main_kx_pult.cpp @@ -1,10 +1,10 @@ -#include -#include "kx_pult.h" - - -int main(int argc, char *argv[]) { - QApplication a(argc, argv); - KX_Pult w; - w.show(); - return a.exec(); -} +#include +#include "kx_pult.h" + + +int main(int argc, char *argv[]) { + QApplication a(argc, argv); + KX_Pult w; + w.show(); + return a.exec(); +} diff --git a/make_libs.sh b/make_libs.sh old mode 100755 new mode 100644 diff --git a/pip b/pip index cc580d9..a4b3edb 160000 --- a/pip +++ b/pip @@ -1 +1 @@ -Subproject commit cc580d9385d780cfc0ee34734fbbc1d18d73d961 +Subproject commit a4b3edb3e1226ad7501bdd7a738b13b6d636d779 diff --git a/piqt/CMakeLists.txt b/piqt/CMakeLists.txt index 9366a34..6520202 100644 --- a/piqt/CMakeLists.txt +++ b/piqt/CMakeLists.txt @@ -1,57 +1,21 @@ -cmake_minimum_required(VERSION 3.0) -cmake_policy(SET CMP0017 NEW) # need include() with .cmake -set(_PIQt_MAJOR 1) -set(_PIQt_MINOR 0) -set(_PIQt_REVISION 0) -set(_PIQt_SUFFIX ) -set(_PIQt_COMPANY SHS) -set(_PIQt_DOMAIN org.SHS) -if(NOT DEFINED BUILD_NUMBER) - set(BUILD_NUMBER 9999) -endif() - -include(QADMacros) - -if(STATIC_LIB) - set(PIQt_LIB_TYPE STATIC) - add_definitions(-DPIQt_STATIC_DEFINE) -else() - set(PIQt_LIB_TYPE SHARED) -endif() - -set(PIQt_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/piqt_version.h") -set_version(PIQt - MAJOR "${_PIQt_MAJOR}" - MINOR "${_PIQt_MINOR}" - REVISION "${_PIQt_REVISION}" - BUILD "${BUILD_NUMBER}" - SUFFIX "${_PIQt_SUFFIX}" - OUTPUT "${PIQt_VERSION_FILE}") -set_deploy_property(PIQt ${_PIQt_LIB_TYPE} - FULLNAME "${_PIQt_DOMAIN}.*" - COMPANY "${_PIQt_COMPANY}") - -macro(piqt_library NAME _MODULES _LIBS) - _qt_project(${NAME} FALSE "PIQt" "${_MODULES}" "pip;${_LIBS}" ${ARGN}) - _qt_install(${NAME} FALSE "pip" "out_HDR" "out_QM") -endmacro() - -macro(piqt_application NAME _MODULES _LIBS) - _qt_project(${NAME} TRUE "PIQt" "${_MODULES}" "pip;${_LIBS}" ${ARGN}) - _qt_install(${NAME} TRUE "pip" "" "out_QM") -endmacro() - - -include_directories(${PIP_INCLUDES}) -add_subdirectory(libs) -if (UTILS) - add_subdirectory(utils) -endif() - - -set(QT_MULTILIB_LIST ${QT_MULTILIB_LIST} PARENT_SCOPE) -set(piqt_includes ${piqt_includes} PARENT_SCOPE) -if (LIB) - set(_ALL_TARGETS ${_ALL_TARGETS} PARENT_SCOPE) -endif() - +cmake_minimum_required(VERSION 3.0) +cmake_policy(SET CMP0017 NEW) # need include() with .cmake + +macro(piqt_library NAME _MODULES _LIBS) + _qt_project(${NAME} FALSE "PIQt" "${_MODULES}" "pip;${_LIBS}" ${ARGN}) + _qt_install(${NAME} FALSE "pip" "out_HDR" "out_QM") +endmacro() + +macro(piqt_application NAME _MODULES _LIBS) + _qt_project(${NAME} TRUE "PIQt" "${_MODULES}" "pip;${_LIBS}" ${ARGN}) + _qt_install(${NAME} TRUE "pip" "" "out_QM") +endmacro() + + +include_directories(${PIP_INCLUDES}) +add_subdirectory(libs) +if (UTILS) + add_subdirectory(utils) +endif() + +copy_to_parent(piqt_includes) diff --git a/piqt/libs/qcd/qcd_graphic.ui b/piqt/libs/qcd/qcd_graphic.ui index f08198f..658977d 100644 --- a/piqt/libs/qcd/qcd_graphic.ui +++ b/piqt/libs/qcd/qcd_graphic.ui @@ -32,7 +32,7 @@ - Graphic::Autofit|Graphic::BorderInputs|Graphic::Clear|Graphic::Configure|Graphic::CursorAxis|Graphic::Fullscreen|Graphic::Legend|Graphic::OnlyExpandY|Graphic::Pause|Graphic::Save + Graphic::Autofit|Graphic::BorderInputs|Graphic::Clear|Graphic::Configure|Graphic::CursorAxis|Graphic::Fullscreen|Graphic::Legend|Graphic::Pause|Graphic::Save false diff --git a/piqt/utils/piconnedit/piconnedit.qrc b/piqt/utils/piconnedit/piconnedit.qrc deleted file mode 100644 index d378e6b..0000000 --- a/piqt/utils/piconnedit/piconnedit.qrc +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/qad/utils/qpicalculator/CMakeLists.txt b/piqt/utils/qpicalculator/CMakeLists.txt similarity index 94% rename from qad/utils/qpicalculator/CMakeLists.txt rename to piqt/utils/qpicalculator/CMakeLists.txt index 27ecf2c..9400a12 100644 --- a/qad/utils/qpicalculator/CMakeLists.txt +++ b/piqt/utils/qpicalculator/CMakeLists.txt @@ -7,7 +7,7 @@ else() set(APP_ICON "icons/qpicalculator.png") endif() set(APP_INFO "Small calculator ang grapher") -qad_application(${PROJECT_NAME} "Gui;Widgets" "qad_utils;qad_widgets;qad_graphic") +qad_application(${PROJECT_NAME} "Gui;Widgets" "qad_utils;qad_widgets;qad_graphic;pip;piqt") 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) diff --git a/qad/utils/qpicalculator/icons/qpicalculator.ico b/piqt/utils/qpicalculator/icons/qpicalculator.ico similarity index 100% rename from qad/utils/qpicalculator/icons/qpicalculator.ico rename to piqt/utils/qpicalculator/icons/qpicalculator.ico diff --git a/qad/utils/qpicalculator/icons/qpicalculator.png b/piqt/utils/qpicalculator/icons/qpicalculator.png similarity index 100% rename from qad/utils/qpicalculator/icons/qpicalculator.png rename to piqt/utils/qpicalculator/icons/qpicalculator.png diff --git a/qad/utils/qpicalculator/main.cpp b/piqt/utils/qpicalculator/main.cpp similarity index 100% rename from qad/utils/qpicalculator/main.cpp rename to piqt/utils/qpicalculator/main.cpp diff --git a/qad/utils/qpicalculator/mainwindow.cpp b/piqt/utils/qpicalculator/mainwindow.cpp similarity index 90% rename from qad/utils/qpicalculator/mainwindow.cpp rename to piqt/utils/qpicalculator/mainwindow.cpp index 4381f41..e6825f2 100644 --- a/qad/utils/qpicalculator/mainwindow.cpp +++ b/piqt/utils/qpicalculator/mainwindow.cpp @@ -1,4 +1,5 @@ #include "mainwindow.h" +#include "piqt.h" MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow() { @@ -62,7 +63,7 @@ void MainWindow::redrawGraphics() { graphic->setGraphicName(ti->text(1), i); pol.clear(); if (ti->checkState(0) == Qt::Checked) { - if (evaluator.check(ti->text(1))) { + if (evaluator.check(Q2PIString(ti->text(1)))) { cx = sx; while (cx < fx) { evaluator.setVariable(vi, complexd(cx, 0.)); @@ -140,19 +141,19 @@ void MainWindow::saving(QPIConfig & conf) { void MainWindow::on_lineInput_textChanged(QString text) { - if (evaluator.check(text)) lineInput->setPalette(npal); + if (evaluator.check(Q2PIString(text))) lineInput->setPalette(npal); else lineInput->setPalette(epal); - labelParsed->setText(evaluator.expression()); - labelError->setText(evaluator.error()); + labelParsed->setText(PI2QString(evaluator.expression())); + labelError->setText(PI2QString(evaluator.error())); } void MainWindow::on_lineInput_returnPressed() { - bool ret = evaluator.check(lineInput->text()); + bool ret = evaluator.check(Q2PIString(lineInput->text())); if (ret) lineInput->setPalette(npal); else lineInput->setPalette(epal); - labelParsed->setText(evaluator.expression()); - labelError->setText(evaluator.error()); + labelParsed->setText(PI2QString(evaluator.expression())); + labelError->setText(PI2QString(evaluator.error())); if (!ret) return; complexd val = evaluator.evaluate(); evaluator.setVariable(ans, val); @@ -182,6 +183,16 @@ void MainWindow::on_lineInput_returnPressed() { } +void MainWindow::on_treeGraphics_itemSelectionChanged() { + buttonGraphicDel->setDisabled(treeGraphics->selectedItems().isEmpty()); + if (treeGraphics->currentItem()) { + int ind = treeGraphics->indexOfTopLevelItem(treeGraphics->currentItem()); + if (ind < 0 || ind >= graphic->graphicsCount()) return; + graphic->setCurrentGraphic(ind); + } +} + + void MainWindow::on_treeGraphics_itemDoubleClicked(QTreeWidgetItem * item, int column) { Qt::ItemFlags f = item->flags(); if (column != 1) f &= ~Qt::ItemIsEditable; @@ -254,7 +265,7 @@ void MainWindow::on_tabWidget_currentChanged(int index) { vn = treeVariables->topLevelItem(i)->text(0); vv = treeVariables->topLevelItem(i)->text(1); eval.check(vv); - evaluator.setVariable(vn, eval.evaluate()); + evaluator.setVariable(Q2PIString(vn), eval.evaluate()); } if (index == 0) on_lineInput_returnPressed(); if (index == 2) redrawGraphics(); diff --git a/qad/utils/qpicalculator/mainwindow.h b/piqt/utils/qpicalculator/mainwindow.h similarity index 89% rename from qad/utils/qpicalculator/mainwindow.h rename to piqt/utils/qpicalculator/mainwindow.h index efb44b9..b46c4dd 100644 --- a/qad/utils/qpicalculator/mainwindow.h +++ b/piqt/utils/qpicalculator/mainwindow.h @@ -8,7 +8,7 @@ #include #include #include "ui_mainwindow.h" -#include "qpievaluator.h" +#include "pievaluator.h" #include "session_manager.h" @@ -26,7 +26,7 @@ private: void updateGraphics(); void redrawGraphics(); - QPIEvaluator evaluator; + PIEvaluator evaluator; QPalette npal, epal; SessionManager session; int ans; @@ -39,7 +39,7 @@ private slots: void on_lineInput_returnPressed(); void on_treeHistory_itemDoubleClicked(QTreeWidgetItem * item, int column) {lineInput->setText(item->text(0));} void on_treeVariables_itemSelectionChanged() {buttonVarDel->setDisabled(treeVariables->selectedItems().isEmpty());} - void on_treeGraphics_itemSelectionChanged() {buttonGraphicDel->setDisabled(treeGraphics->selectedItems().isEmpty());} + void on_treeGraphics_itemSelectionChanged(); void on_treeGraphics_itemChanged(QTreeWidgetItem * , int col) { if (active_) redrawGraphics();} void on_treeGraphics_itemDoubleClicked(QTreeWidgetItem * item, int column); void on_buttonVarAdd_clicked(); diff --git a/qad/utils/qpicalculator/mainwindow.ui b/piqt/utils/qpicalculator/mainwindow.ui similarity index 100% rename from qad/utils/qpicalculator/mainwindow.ui rename to piqt/utils/qpicalculator/mainwindow.ui diff --git a/qad/utils/qpicalculator/qpicalculator.qrc b/piqt/utils/qpicalculator/qpicalculator.qrc similarity index 100% rename from qad/utils/qpicalculator/qpicalculator.qrc rename to piqt/utils/qpicalculator/qpicalculator.qrc diff --git a/project_fs/ProjectFilesystemPlugin.json.in b/project_fs/ProjectFilesystemPlugin.json.in index 3ae41ba..017dcd1 100644 --- a/project_fs/ProjectFilesystemPlugin.json.in +++ b/project_fs/ProjectFilesystemPlugin.json.in @@ -1,11 +1,11 @@ -{ - \"Name\" : \"ProjectFilesystemPlugin\", - \"Version\" : \"1.1.0\", - \"CompatVersion\" : \"1.1.0\", - \"Vendor\" : \"Peri4\", - \"Copyright\" : \"(C) Peri4\", - \"License\" : \"LGPLv3\", - \"Description\" : \"LGPLv3\", - \"Url\" : \"\", - $$dependencyList -} +{ + \"Name\" : \"ProjectFilesystemPlugin\", + \"Version\" : \"1.1.0\", + \"CompatVersion\" : \"1.1.0\", + \"Vendor\" : \"Peri4\", + \"Copyright\" : \"(C) Peri4\", + \"License\" : \"LGPLv3\", + \"Description\" : \"LGPLv3\", + \"Url\" : \"\", + $$dependencyList +} diff --git a/project_fs/filterdialog.cpp b/project_fs/filterdialog.cpp index 2137cd1..84e540a 100644 --- a/project_fs/filterdialog.cpp +++ b/project_fs/filterdialog.cpp @@ -1,91 +1,91 @@ -#include "filterdialog.h" -#include -#include - - -FilterDialog::FilterDialog(QWidget * parent): QDialog(parent) { - setupUi(this); - toolButton->setIcon(Utils::Icons::CLEAN.icon()); - toolButton_2->setIcon(Utils::Icons::CLEAN.icon()); - toolButton_3->setIcon(Utils::Icons::CLEAN.icon()); - toolButton_4->setIcon(Utils::Icons::CLEAN.icon()); -} - - -void FilterDialog::changeEvent(QEvent *e) { - QDialog::changeEvent(e); - switch (e->type()) { - case QEvent::LanguageChange: - retranslateUi(this); - break; - default: - break; - } -} - - -FilterDialog::Filter FilterDialog::filter() const { - FilterDialog::Filter ret; - ret.files_show = getFilters(lineFilesShow); - ret.files_hide = getFilters(lineFilesHide); - ret.dirs_show = getFilters(lineDirsShow); - ret.dirs_hide = getFilters(lineDirsHide); - return ret; -} - -void FilterDialog::setFilter(const FilterDialog::Filter & f) { - setFilters(lineFilesShow, f.files_show); - setFilters(lineFilesHide, f.files_hide); - setFilters(lineDirsShow, f.dirs_show); - setFilters(lineDirsHide, f.dirs_hide); -} - - -QStringList FilterDialog::getFilters(QLineEdit * le) const { - if (!le) return QStringList(); - QStringList ret = le->text().split(","); - for (int i = 0; i < ret.size(); ++i) - ret[i] = ret[i].trimmed(); - ret.removeAll(""); - return ret; -} - - -void FilterDialog::setFilters(QLineEdit * le, QStringList f) { - if (!le) return; - le->setText(f.join(",")); -} - - -FilterDialog::Filter::Filter(const QVariant & v) { - QByteArray ba = v.toByteArray(); - if (ba.isEmpty()) return; - QDataStream s(ba); - s >> files_show >> files_hide >> dirs_show >> dirs_hide; -} - - -QVariant FilterDialog::Filter::toVariant() const { - QByteArray ba; - QDataStream s(&ba, QIODevice::ReadWrite); - s << files_show << files_hide << dirs_show << dirs_hide; - return QVariant(ba); -} - - -bool FilterDialog::Filter::filterLogic(const QStringList & fshow, const QStringList & fhide, const QString & path) const { - if (fshow.isEmpty() && fhide.isEmpty()) return true; - if (!fhide.isEmpty()) { - if (QDir::match(fhide, path)) - return false; - else { - if (fshow.isEmpty()) - return true; - else - return QDir::match(fshow, path); - } - } - if (!fshow.isEmpty()) - return QDir::match(fshow, path); - return true; -} +#include "filterdialog.h" +#include +#include + + +FilterDialog::FilterDialog(QWidget * parent): QDialog(parent) { + setupUi(this); + toolButton->setIcon(Utils::Icons::CLEAN.icon()); + toolButton_2->setIcon(Utils::Icons::CLEAN.icon()); + toolButton_3->setIcon(Utils::Icons::CLEAN.icon()); + toolButton_4->setIcon(Utils::Icons::CLEAN.icon()); +} + + +void FilterDialog::changeEvent(QEvent *e) { + QDialog::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + retranslateUi(this); + break; + default: + break; + } +} + + +FilterDialog::Filter FilterDialog::filter() const { + FilterDialog::Filter ret; + ret.files_show = getFilters(lineFilesShow); + ret.files_hide = getFilters(lineFilesHide); + ret.dirs_show = getFilters(lineDirsShow); + ret.dirs_hide = getFilters(lineDirsHide); + return ret; +} + +void FilterDialog::setFilter(const FilterDialog::Filter & f) { + setFilters(lineFilesShow, f.files_show); + setFilters(lineFilesHide, f.files_hide); + setFilters(lineDirsShow, f.dirs_show); + setFilters(lineDirsHide, f.dirs_hide); +} + + +QStringList FilterDialog::getFilters(QLineEdit * le) const { + if (!le) return QStringList(); + QStringList ret = le->text().split(","); + for (int i = 0; i < ret.size(); ++i) + ret[i] = ret[i].trimmed(); + ret.removeAll(""); + return ret; +} + + +void FilterDialog::setFilters(QLineEdit * le, QStringList f) { + if (!le) return; + le->setText(f.join(",")); +} + + +FilterDialog::Filter::Filter(const QVariant & v) { + QByteArray ba = v.toByteArray(); + if (ba.isEmpty()) return; + QDataStream s(ba); + s >> files_show >> files_hide >> dirs_show >> dirs_hide; +} + + +QVariant FilterDialog::Filter::toVariant() const { + QByteArray ba; + QDataStream s(&ba, QIODevice::ReadWrite); + s << files_show << files_hide << dirs_show << dirs_hide; + return QVariant(ba); +} + + +bool FilterDialog::Filter::filterLogic(const QStringList & fshow, const QStringList & fhide, const QString & path) const { + if (fshow.isEmpty() && fhide.isEmpty()) return true; + if (!fhide.isEmpty()) { + if (QDir::match(fhide, path)) + return false; + else { + if (fshow.isEmpty()) + return true; + else + return QDir::match(fshow, path); + } + } + if (!fshow.isEmpty()) + return QDir::match(fshow, path); + return true; +} diff --git a/project_fs/filterdialog.h b/project_fs/filterdialog.h index 0d1e2a3..5113f09 100644 --- a/project_fs/filterdialog.h +++ b/project_fs/filterdialog.h @@ -1,37 +1,37 @@ -#ifndef FILTERDIALOG_H -#define FILTERDIALOG_H - -#include "ui_filterdialog.h" - -class FilterDialog: public QDialog, private Ui::FilterDialog -{ - Q_OBJECT -public: - explicit FilterDialog(QWidget *parent = 0); - - struct Filter { - Filter() {} - Filter(const QVariant & v); - QVariant toVariant() const; - bool filterFile(const QString & path) const {return filterLogic(files_show, files_hide, path);} - bool filterDir(const QString & path) const {return filterLogic(dirs_show, dirs_hide, path);} - QStringList files_show; - QStringList files_hide; - QStringList dirs_show; - QStringList dirs_hide; - private: - bool filterLogic(const QStringList & fshow, const QStringList & fhide, const QString & path) const; - }; - - Filter filter() const; - void setFilter(const Filter & f); - -protected: - void changeEvent(QEvent *e); - - QStringList getFilters(QLineEdit * le) const; - void setFilters(QLineEdit * le, QStringList f); - -}; - -#endif // FILTERDIALOG_H +#ifndef FILTERDIALOG_H +#define FILTERDIALOG_H + +#include "ui_filterdialog.h" + +class FilterDialog: public QDialog, private Ui::FilterDialog +{ + Q_OBJECT +public: + explicit FilterDialog(QWidget *parent = 0); + + struct Filter { + Filter() {} + Filter(const QVariant & v); + QVariant toVariant() const; + bool filterFile(const QString & path) const {return filterLogic(files_show, files_hide, path);} + bool filterDir(const QString & path) const {return filterLogic(dirs_show, dirs_hide, path);} + QStringList files_show; + QStringList files_hide; + QStringList dirs_show; + QStringList dirs_hide; + private: + bool filterLogic(const QStringList & fshow, const QStringList & fhide, const QString & path) const; + }; + + Filter filter() const; + void setFilter(const Filter & f); + +protected: + void changeEvent(QEvent *e); + + QStringList getFilters(QLineEdit * le) const; + void setFilters(QLineEdit * le, QStringList f); + +}; + +#endif // FILTERDIALOG_H diff --git a/project_fs/filterdialog.ui b/project_fs/filterdialog.ui index df38a3f..2327935 100644 --- a/project_fs/filterdialog.ui +++ b/project_fs/filterdialog.ui @@ -1,226 +1,226 @@ - - - FilterDialog - - - - 0 - 0 - 342 - 250 - - - - Project filesystem filters - - - - - - Input filters, separated by ",": - - - - - - - - - Show dirs: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - - - Hide files: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Show files: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - - - Hide dirs: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 0 - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - lineFilesShow - lineFilesHide - lineDirsShow - lineDirsHide - toolButton - toolButton_2 - toolButton_3 - toolButton_4 - - - - - buttonBox - accepted() - FilterDialog - accept() - - - 259 - 238 - - - 157 - 274 - - - - - buttonBox - rejected() - FilterDialog - reject() - - - 327 - 238 - - - 286 - 274 - - - - - toolButton - clicked() - lineFilesShow - clear() - - - 329 - 60 - - - 269 - 58 - - - - - toolButton_2 - clicked() - lineFilesHide - clear() - - - 329 - 93 - - - 295 - 91 - - - - - toolButton_3 - clicked() - lineDirsShow - clear() - - - 329 - 126 - - - 295 - 124 - - - - - toolButton_4 - clicked() - lineDirsHide - clear() - - - 329 - 159 - - - 295 - 157 - - - - - + + + FilterDialog + + + + 0 + 0 + 342 + 250 + + + + Project filesystem filters + + + + + + Input filters, separated by ",": + + + + + + + + + Show dirs: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + Hide files: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Show files: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + Hide dirs: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + lineFilesShow + lineFilesHide + lineDirsShow + lineDirsHide + toolButton + toolButton_2 + toolButton_3 + toolButton_4 + + + + + buttonBox + accepted() + FilterDialog + accept() + + + 259 + 238 + + + 157 + 274 + + + + + buttonBox + rejected() + FilterDialog + reject() + + + 327 + 238 + + + 286 + 274 + + + + + toolButton + clicked() + lineFilesShow + clear() + + + 329 + 60 + + + 269 + 58 + + + + + toolButton_2 + clicked() + lineFilesHide + clear() + + + 329 + 93 + + + 295 + 91 + + + + + toolButton_3 + clicked() + lineDirsShow + clear() + + + 329 + 126 + + + 295 + 124 + + + + + toolButton_4 + clicked() + lineDirsHide + clear() + + + 329 + 159 + + + 295 + 157 + + + + + diff --git a/project_fs/projectfilesystem.qrc b/project_fs/projectfilesystem.qrc index 2b5712f..b85c3a6 100644 --- a/project_fs/projectfilesystem.qrc +++ b/project_fs/projectfilesystem.qrc @@ -1,6 +1,6 @@ - - - icons/edit-find.png - icons/utilities-terminal.png - - + + + icons/edit-find.png + icons/utilities-terminal.png + + diff --git a/project_fs/projectfilesystemplugin.cpp b/project_fs/projectfilesystemplugin.cpp index 37b3c58..6588643 100644 --- a/project_fs/projectfilesystemplugin.cpp +++ b/project_fs/projectfilesystemplugin.cpp @@ -1,89 +1,89 @@ -#include "projectfilesystemplugin.h" -#include "projectfilesystempluginconstants.h" -#include "projectfilesystemwidget.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -namespace ProjectFilesystemPlugin { - namespace Internal { - - ProjectFilesystemPluginPlugin::ProjectFilesystemPluginPlugin() - { - // Create your members - } - - ProjectFilesystemPluginPlugin::~ProjectFilesystemPluginPlugin() - { - // Unregister objects from the plugin manager's object pool - // Delete members - } - - bool ProjectFilesystemPluginPlugin::initialize(const QStringList &arguments, QString *errorString) - { - // Register objects in the plugin manager's object pool - // Load settings - // Add actions to menus - // Connect to other plugins' signals - // In the initialize function, a plugin can be sure that the plugins it - // depends on have initialized their members. - - Q_UNUSED(arguments) - Q_UNUSED(errorString) - - /*auto action = new QAction(tr("ProjectFilesystemPlugin Action"), this); - Core::Command *cmd = Core::ActionManager::registerAction(action, Constants::ACTION_ID, - Core::Context(Core::Constants::C_GLOBAL)); - cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Alt+Meta+A"))); - connect(action, &QAction::triggered, this, &ProjectFilesystemPluginPlugin::triggerAction); - - Core::ActionContainer *menu = Core::ActionManager::createMenu(Constants::MENU_ID); - menu->menu()->setTitle(tr("ProjectFilesystemPlugin")); - menu->addAction(cmd); - Core::ActionManager::actionContainer(Core::Constants::M_TOOLS)->addMenu(menu); - - qDebug() << Core::IContext::widget();*/ - //addAutoReleasedObject(new ProjectFSWidgetFactory()); - (new ProjectFSWidgetFactory())->setParent(this); - - return true; - } - - void ProjectFilesystemPluginPlugin::extensionsInitialized() - { - Utils::globalMacroExpander()->registerPrefix("ProjectFilesystem", "Project filesystem plugin", [](QString v) -> QString {return v;} ); - Utils::globalMacroExpander()->registerFileVariables("ProjectFilesystem", "Selected item", - []() -> QString { return projectfs_menu_target.absoluteFilePath();}); - // Retrieve objects from the plugin manager's object pool - // In the extensionsInitialized function, a plugin can be sure that all - // plugins that depend on it are completely initialized. - } - - ExtensionSystem::IPlugin::ShutdownFlag ProjectFilesystemPluginPlugin::aboutToShutdown() - { - // Save settings - // Disconnect from signals that are not needed during shutdown - // Hide UI (if you add UI that is not in the main window directly) - return SynchronousShutdown; - } - - void ProjectFilesystemPluginPlugin::triggerAction() - { - QMessageBox::information(Core::ICore::mainWindow(), - tr("Action Triggered"), - tr("This is an action from ProjectFilesystemPlugin.")); - } - - } // namespace Internal -} // namespace ProjectFilesystemPlugin +#include "projectfilesystemplugin.h" +#include "projectfilesystempluginconstants.h" +#include "projectfilesystemwidget.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace ProjectFilesystemPlugin { + namespace Internal { + + ProjectFilesystemPluginPlugin::ProjectFilesystemPluginPlugin() + { + // Create your members + } + + ProjectFilesystemPluginPlugin::~ProjectFilesystemPluginPlugin() + { + // Unregister objects from the plugin manager's object pool + // Delete members + } + + bool ProjectFilesystemPluginPlugin::initialize(const QStringList &arguments, QString *errorString) + { + // Register objects in the plugin manager's object pool + // Load settings + // Add actions to menus + // Connect to other plugins' signals + // In the initialize function, a plugin can be sure that the plugins it + // depends on have initialized their members. + + Q_UNUSED(arguments) + Q_UNUSED(errorString) + + /*auto action = new QAction(tr("ProjectFilesystemPlugin Action"), this); + Core::Command *cmd = Core::ActionManager::registerAction(action, Constants::ACTION_ID, + Core::Context(Core::Constants::C_GLOBAL)); + cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Alt+Meta+A"))); + connect(action, &QAction::triggered, this, &ProjectFilesystemPluginPlugin::triggerAction); + + Core::ActionContainer *menu = Core::ActionManager::createMenu(Constants::MENU_ID); + menu->menu()->setTitle(tr("ProjectFilesystemPlugin")); + menu->addAction(cmd); + Core::ActionManager::actionContainer(Core::Constants::M_TOOLS)->addMenu(menu); + + qDebug() << Core::IContext::widget();*/ + //addAutoReleasedObject(new ProjectFSWidgetFactory()); + (new ProjectFSWidgetFactory())->setParent(this); + + return true; + } + + void ProjectFilesystemPluginPlugin::extensionsInitialized() + { + Utils::globalMacroExpander()->registerPrefix("ProjectFilesystem", "Project filesystem plugin", [](QString v) -> QString {return v;} ); + Utils::globalMacroExpander()->registerFileVariables("ProjectFilesystem", "Selected item", + []() -> QString { return projectfs_menu_target.absoluteFilePath();}); + // Retrieve objects from the plugin manager's object pool + // In the extensionsInitialized function, a plugin can be sure that all + // plugins that depend on it are completely initialized. + } + + ExtensionSystem::IPlugin::ShutdownFlag ProjectFilesystemPluginPlugin::aboutToShutdown() + { + // Save settings + // Disconnect from signals that are not needed during shutdown + // Hide UI (if you add UI that is not in the main window directly) + return SynchronousShutdown; + } + + void ProjectFilesystemPluginPlugin::triggerAction() + { + QMessageBox::information(Core::ICore::mainWindow(), + tr("Action Triggered"), + tr("This is an action from ProjectFilesystemPlugin.")); + } + + } // namespace Internal +} // namespace ProjectFilesystemPlugin diff --git a/project_fs/projectfilesystemplugin.h b/project_fs/projectfilesystemplugin.h index 4262865..b04970e 100644 --- a/project_fs/projectfilesystemplugin.h +++ b/project_fs/projectfilesystemplugin.h @@ -1,29 +1,29 @@ -#pragma once - -#include "projectfilesystemplugin_global.h" -#include "projectfilesystemwidgetplugin.h" - -#include - -namespace ProjectFilesystemPlugin { - namespace Internal { - - class ProjectFilesystemPluginPlugin : public ExtensionSystem::IPlugin - { - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "ProjectFilesystemPlugin.json") - - public: - ProjectFilesystemPluginPlugin(); - ~ProjectFilesystemPluginPlugin(); - - bool initialize(const QStringList &arguments, QString *errorString); - void extensionsInitialized(); - ShutdownFlag aboutToShutdown(); - - private: - void triggerAction(); - }; - - } // namespace Internal -} // namespace ProjectFilesystemPlugin +#pragma once + +#include "projectfilesystemplugin_global.h" +#include "projectfilesystemwidgetplugin.h" + +#include + +namespace ProjectFilesystemPlugin { + namespace Internal { + + class ProjectFilesystemPluginPlugin : public ExtensionSystem::IPlugin + { + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "ProjectFilesystemPlugin.json") + + public: + ProjectFilesystemPluginPlugin(); + ~ProjectFilesystemPluginPlugin(); + + bool initialize(const QStringList &arguments, QString *errorString); + void extensionsInitialized(); + ShutdownFlag aboutToShutdown(); + + private: + void triggerAction(); + }; + + } // namespace Internal +} // namespace ProjectFilesystemPlugin diff --git a/project_fs/projectfilesystemplugin.pro b/project_fs/projectfilesystemplugin.pro index ec797d3..aeb9f8c 100644 --- a/project_fs/projectfilesystemplugin.pro +++ b/project_fs/projectfilesystemplugin.pro @@ -1,61 +1,61 @@ -DEFINES += PROJECTFILESYSTEMPLUGIN_LIBRARY - -# ProjectFilesystemPlugin files - -SOURCES += projectfilesystemplugin.cpp \ - projectfilesystemwidget.cpp \ - projectfilesystemwidgetplugin.cpp \ - filterdialog.cpp - -HEADERS += projectfilesystemplugin.h \ - projectfilesystemplugin_global.h \ - projectfilesystempluginconstants.h \ - projectfilesystemwidget.h \ - projectfilesystemwidgetplugin.h \ - filterdialog.h - -FORMS += \ - projectfilesystemwidget.ui \ - filterdialog.ui - -RESOURCES += \ - projectfilesystem.qrc - -#QT += network - -# Qt Creator linking - -## Either set the IDE_SOURCE_TREE when running qmake, -## or set the QTC_SOURCE environment variable, to override the default setting -isEmpty(IDE_SOURCE_TREE): IDE_SOURCE_TREE = $$(SDK_QTCREATOR_SRC) - -## Either set the IDE_BUILD_TREE when running qmake, -## or set the QTC_BUILD environment variable, to override the default setting -isEmpty(IDE_BUILD_TREE): IDE_BUILD_TREE = $$(SDK_QTCREATOR_BUILD) - -## uncomment to build plugin into user config directory -## /plugins/ -## where is e.g. -## "%LOCALAPPDATA%\QtProject\qtcreator" on Windows Vista and later -## "$XDG_DATA_HOME/data/QtProject/qtcreator" or "~/.local/share/data/QtProject/qtcreator" on Linux -## "~/Library/Application Support/QtProject/Qt Creator" on OS X -#USE_USER_DESTDIR = yes - -###### If the plugin can be depended upon by other plugins, this code needs to be outsourced to -###### _dependencies.pri, where is the name of the directory containing the -###### plugin's sources. - -QTC_PLUGIN_NAME = ProjectFilesystemPlugin -QTC_LIB_DEPENDS += \ - # nothing here at this time - -QTC_PLUGIN_DEPENDS += \ - coreplugin \ - projectexplorer - -QTC_PLUGIN_RECOMMENDS += \ - # optional plugin dependencies. nothing here at this time - -###### End _dependencies.pri contents ###### - -include($$IDE_SOURCE_TREE/src/qtcreatorplugin.pri) +DEFINES += PROJECTFILESYSTEMPLUGIN_LIBRARY + +# ProjectFilesystemPlugin files + +SOURCES += projectfilesystemplugin.cpp \ + projectfilesystemwidget.cpp \ + projectfilesystemwidgetplugin.cpp \ + filterdialog.cpp + +HEADERS += projectfilesystemplugin.h \ + projectfilesystemplugin_global.h \ + projectfilesystempluginconstants.h \ + projectfilesystemwidget.h \ + projectfilesystemwidgetplugin.h \ + filterdialog.h + +FORMS += \ + projectfilesystemwidget.ui \ + filterdialog.ui + +RESOURCES += \ + projectfilesystem.qrc + +#QT += network + +# Qt Creator linking + +## Either set the IDE_SOURCE_TREE when running qmake, +## or set the QTC_SOURCE environment variable, to override the default setting +isEmpty(IDE_SOURCE_TREE): IDE_SOURCE_TREE = $$(SDK_QTCREATOR_SRC) + +## Either set the IDE_BUILD_TREE when running qmake, +## or set the QTC_BUILD environment variable, to override the default setting +isEmpty(IDE_BUILD_TREE): IDE_BUILD_TREE = $$(SDK_QTCREATOR_BUILD) + +## uncomment to build plugin into user config directory +## /plugins/ +## where is e.g. +## "%LOCALAPPDATA%\QtProject\qtcreator" on Windows Vista and later +## "$XDG_DATA_HOME/data/QtProject/qtcreator" or "~/.local/share/data/QtProject/qtcreator" on Linux +## "~/Library/Application Support/QtProject/Qt Creator" on OS X +#USE_USER_DESTDIR = yes + +###### If the plugin can be depended upon by other plugins, this code needs to be outsourced to +###### _dependencies.pri, where is the name of the directory containing the +###### plugin's sources. + +QTC_PLUGIN_NAME = ProjectFilesystemPlugin +QTC_LIB_DEPENDS += \ + # nothing here at this time + +QTC_PLUGIN_DEPENDS += \ + coreplugin \ + projectexplorer + +QTC_PLUGIN_RECOMMENDS += \ + # optional plugin dependencies. nothing here at this time + +###### End _dependencies.pri contents ###### + +include($$IDE_SOURCE_TREE/src/qtcreatorplugin.pri) diff --git a/project_fs/projectfilesystemplugin_global.h b/project_fs/projectfilesystemplugin_global.h index f2e22e8..064c4d2 100644 --- a/project_fs/projectfilesystemplugin_global.h +++ b/project_fs/projectfilesystemplugin_global.h @@ -1,9 +1,9 @@ -#pragma once - -#include - -#if defined(PROJECTFILESYSTEMPLUGIN_LIBRARY) -# define PROJECTFILESYSTEMPLUGINSHARED_EXPORT Q_DECL_EXPORT -#else -# define PROJECTFILESYSTEMPLUGINSHARED_EXPORT Q_DECL_IMPORT -#endif +#pragma once + +#include + +#if defined(PROJECTFILESYSTEMPLUGIN_LIBRARY) +# define PROJECTFILESYSTEMPLUGINSHARED_EXPORT Q_DECL_EXPORT +#else +# define PROJECTFILESYSTEMPLUGINSHARED_EXPORT Q_DECL_IMPORT +#endif diff --git a/project_fs/projectfilesystempluginconstants.h b/project_fs/projectfilesystempluginconstants.h index 2fb2893..2b2b7a8 100644 --- a/project_fs/projectfilesystempluginconstants.h +++ b/project_fs/projectfilesystempluginconstants.h @@ -1,10 +1,10 @@ -#pragma once - -namespace ProjectFilesystemPlugin { - namespace Constants { - - const char ACTION_ID[] = "ProjectFilesystemPlugin.Action"; - const char MENU_ID[] = "ProjectFilesystemPlugin.Menu"; - - } // namespace ProjectFilesystemPlugin -} // namespace Constants +#pragma once + +namespace ProjectFilesystemPlugin { + namespace Constants { + + const char ACTION_ID[] = "ProjectFilesystemPlugin.Action"; + const char MENU_ID[] = "ProjectFilesystemPlugin.Menu"; + + } // namespace ProjectFilesystemPlugin +} // namespace Constants diff --git a/project_fs/projectfilesystemwidget.cpp b/project_fs/projectfilesystemwidget.cpp index b858862..9520696 100644 --- a/project_fs/projectfilesystemwidget.cpp +++ b/project_fs/projectfilesystemwidget.cpp @@ -1,328 +1,328 @@ -#include "projectfilesystemwidget.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -QFileInfo projectfs_menu_target; - - -ProjectFilesystemWidget::ProjectFilesystemWidget(QWidget * parent): QWidget(parent) { - setupUi(this); - in_proc = need_rebuild = false; - int is = style()->pixelMetric(QStyle::PM_ButtonIconSize, 0, this); - label->setFixedSize(is, is); - buttonClear->setIcon(Utils::Icons::CLEAN.icon()); - buttonExpand->setIcon(Utils::Icons::EXPAND.icon()); - buttonCollapse->setIcon(Utils::Icons::COLLAPSE.icon()); - actionOpen_here->setIcon(Utils::Icons::OPENFILE.icon()); - actionOpen_external->setIcon(Utils::Icons::OPENFILE.icon()); - actionShow_external->setIcon(Core::FileIconProvider::icon(QFileIconProvider::Folder)); - actionCopy_name->setIcon(Utils::Icons::COPY.icon()); - actionCopy_path->setIcon(Utils::Icons::COPY.icon()); - popup_menu.addActions(QList() << actionOpen_here << actionOpen_external << actionShow_external << actionOpen_terminal); - popup_menu.addSeparator(); - popup_menu.addActions(QList() << actionCopy_name << actionCopy_path); - proj_plug = 0; - //connect(ProjectExplorer::ProjectTree::instance(), SIGNAL(subtreeChanged(ProjectExplorer::FolderNode*)), this, SLOT(projectsChanged())); - connect(ProjectExplorer::SessionManager::instance(), SIGNAL(startupProjectChanged(ProjectExplorer::Project *)), this, SLOT(startupProjectChanged())); - connect(ProjectExplorer::SessionManager::instance(), SIGNAL(projectAdded(ProjectExplorer::Project*)), this, SLOT(projectsChanged())); - connect(ProjectExplorer::SessionManager::instance(), SIGNAL(projectDisplayNameChanged(ProjectExplorer::Project*)), this, SLOT(projectsChanged())); - connect(ProjectExplorer::SessionManager::instance(), SIGNAL(projectRemoved(ProjectExplorer::Project*)), this, SLOT(projectsChanged())); - //connect(ProjectExplorer::SessionManager::instance(), SIGNAL(), this, SLOT(startupProjectChanged())); - connect(Core::EditorManager::instance(), SIGNAL(currentEditorChanged(Core::IEditor*)), this, SLOT(fileChanged())); - projectsChanged(); -} - - -void ProjectFilesystemWidget::setCurrentFilter(const FilterDialog::Filter & v) { - cur_filter = v; - projectsChanged(); -} - - -void ProjectFilesystemWidget::changeEvent(QEvent *e) { - QWidget::changeEvent(e); - switch (e->type()) { - case QEvent::LanguageChange: - retranslateUi(this); - break; - default: - break; - } -} - - -void ProjectFilesystemWidget::createTree(QTreeWidgetItem * ti, const QString & dir) { - QFileInfoList fl = QDir(dir).entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot, QDir::LocaleAware | QDir::DirsFirst); - checkProcEvents(); - for (QFileInfo i: fl) { - QString nit = i.fileName(); - if (i.isDir()) { - if (!cur_filter.filterDir(nit)) - continue; - } else { - if (!cur_filter.filterFile(nit)) - continue; - } - QTreeWidgetItem * ni = new QTreeWidgetItem(); - ni->setText(0, nit); - ni->setIcon(0, Core::FileIconProvider::icon(i)); - ni->setData(0, Qt::UserRole, i.absoluteFilePath()); - ni->setData(0, Qt::UserRole + 1, i.isDir()); - item_map[i.absoluteFilePath()] = ni; - if (i.isDir()) { - createTree(ni, dir + QDir::separator() + i.fileName()); - } - ti->addChild(ni); - } - //if (ti->childCount() == 0) delete ti; -} - - -bool ProjectFilesystemWidget::filterTree(QTreeWidgetItem * ti, const QString & filter) { - bool ret = false; - for (int i = 0; i < ti->childCount(); ++i) { - QTreeWidgetItem * ci = ti->child(i); - QString cit = ci->text(0); - if (ci->data(0, Qt::UserRole + 1).toBool()) { - if (!filterTree(ci, filter)) { - ci->setHidden(true); - continue; - } - ci->setHidden(false); - ret = true; - } else { - bool f = false; - if (filter.isEmpty()) { - f = true; - } else { - f = f || cit.contains(filter); - } - ci->setHidden(!f); - if (f) ret = true; - } - } - return ret; -} - - -void ProjectFilesystemWidget::filter() { - QString f = lineFilter->text(); - for (int i = 0; i < tree->topLevelItemCount(); ++i) { - QTreeWidgetItem * ti = tree->topLevelItem(i); - filterTree(ti, f); - } -} - - -void ProjectFilesystemWidget::rememberExpanded(QTreeWidgetItem * ti) { - //QMessageBox::information(0, ti->data(0, Qt::UserRole).toString(), QString::number(ti->childCount())); - for (int i = 0; i < ti->childCount(); ++i) { - QTreeWidgetItem * ci = ti->child(i); - if (ci->data(0, Qt::UserRole + 1).toBool()) { - if (ci->isExpanded()) - last_expanded << ci->data(0, Qt::UserRole).toString(); - rememberExpanded(ci); - } - } -} - - -void ProjectFilesystemWidget::restoreExpanded(QTreeWidgetItem * ti) { - for (int i = 0; i < ti->childCount(); ++i) { - QTreeWidgetItem * ci = ti->child(i); - if (ci->data(0, Qt::UserRole + 1).toBool()) { - if (last_expanded.contains(ci->data(0, Qt::UserRole).toString())) - ci->setExpanded(true); - restoreExpanded(ci); - } - } -} - - -void ProjectFilesystemWidget::setExtVariable() { -} - - -void ProjectFilesystemWidget::checkProcEvents() { - if (tm.elapsed() < 10) return; - QApplication::processEvents(); - tm.start(); -} - - -void ProjectFilesystemWidget::projectsChanged() { - if (in_proc) { - need_rebuild = true; - return; - } - in_proc = true; - tm.start(); - last_expanded.clear(); - item_map.clear(); - int spos = tree->verticalScrollBar()->value(); - rememberExpanded(tree->invisibleRootItem()); - tree->clear(); - QApplication::setOverrideCursor(Qt::WaitCursor); - QList pl = ProjectExplorer::SessionManager::projects(); - for (ProjectExplorer::Project * p: pl) { - QTreeWidgetItem * ri = new QTreeWidgetItem(); - QString dir = p->projectDirectory().toString(); - ri->setText(0, p->displayName()); - QFile logo(dir + "/logo.png"); - if (logo.exists()) - ri->setIcon(0, QIcon(logo.fileName())); - else - ri->setIcon(0, Core::FileIconProvider::icon(QFileIconProvider::Folder)); - ri->setData(0, Qt::UserRole, dir); - ri->setData(0, Qt::UserRole + 1, true); - createTree(ri, dir); - tree->addTopLevelItem(ri); - } - startupProjectChanged(); - fileChanged(); - filter(); - restoreExpanded(tree->invisibleRootItem()); - QApplication::restoreOverrideCursor(); - qApp->processEvents(); - tree->verticalScrollBar()->setValue(spos); - in_proc = false; - if (need_rebuild) { - need_rebuild = false; - projectsChanged(); - } -} - - -void ProjectFilesystemWidget::filterClicked() { - filter_dialog.setFilter(cur_filter); - if (filter_dialog.exec() == QDialog::Rejected) return; - setCurrentFilter(filter_dialog.filter()); -} - - -void ProjectFilesystemWidget::fileChanged() { - Core::IDocument * cd = Core::EditorManager::instance()->currentDocument(); - if (!cd) return; - QString np = cd->filePath().toString(); - QTreeWidgetItem * ti = item_map.value(np); - if (!ti) return; - tree->setCurrentItem(ti); - tree->expandItem(ti); -} - - -void ProjectFilesystemWidget::startupProjectChanged() { - ProjectExplorer::Project * sp = ProjectExplorer::SessionManager::startupProject(); - QFont f(tree->font()), bf(f); - bf.setBold(true); - for (int i = 0; i < tree->topLevelItemCount(); ++i) { - QTreeWidgetItem * ti = tree->topLevelItem(i); - ti->setFont(0, f); - if (!sp) continue; - if (sp->projectDirectory().toString() == ti->data(0, Qt::UserRole).toString()) - ti->setFont(0, bf); - } -} - - -void ProjectFilesystemWidget::on_tree_itemDoubleClicked(QTreeWidgetItem * item, int) { - if (!item) return; - QString afp = item->data(0, Qt::UserRole).toString(); - bool dir = item->data(0, Qt::UserRole + 1).toBool(); - if (dir) return; - if (afp.isEmpty()) return; - Core::EditorManager::openEditor(afp); -} - - -void ProjectFilesystemWidget::on_lineFilter_textChanged(const QString & ) { - filter(); -} - - -void ProjectFilesystemWidget::on_tree_itemClicked(QTreeWidgetItem * item, int column) { - projectfs_menu_target = QFileInfo(); - if (!item) { - setExtVariable(); - return; - } - projectfs_menu_target = QFileInfo(item->data(0, Qt::UserRole).toString()); - setExtVariable(); -} - - -void ProjectFilesystemWidget::on_tree_customContextMenuRequested(const QPoint & pos) { - projectfs_menu_target = QFileInfo(); - QTreeWidgetItem * item = tree->itemAt(pos); - //QMessageBox::information(this, "", QString::number(index.row())); - if (!item) { - setExtVariable(); - return; - } - projectfs_menu_target = QFileInfo(item->data(0, Qt::UserRole).toString()); - setExtVariable(); - actionOpen_here->setEnabled(!projectfs_menu_target.isDir()); - actionOpen_external->setEnabled(!projectfs_menu_target.isDir()); - popup_menu.popup(tree->mapToGlobal(pos)); -} - - -void ProjectFilesystemWidget::on_actionOpen_here_triggered() { - if (projectfs_menu_target.path().isEmpty()) return; - Core::EditorManager::openEditor(projectfs_menu_target.absoluteFilePath(), Core::Constants::K_DEFAULT_TEXT_EDITOR_ID); -} - - -void ProjectFilesystemWidget::on_actionOpen_external_triggered() { - if (projectfs_menu_target.path().isEmpty()) return; - QString wd = QDir::current().absolutePath(); - QDir::setCurrent(projectfs_menu_target.absoluteDir().path()); - QDesktopServices::openUrl(QUrl::fromLocalFile(projectfs_menu_target.absoluteFilePath())); - QDir::setCurrent(wd); -} - - -void ProjectFilesystemWidget::on_actionShow_external_triggered() { - if (projectfs_menu_target.path().isEmpty()) return; - Core::FileUtils::showInGraphicalShell(Core::ICore::mainWindow(), projectfs_menu_target.absoluteFilePath()); -} - - -void ProjectFilesystemWidget::on_actionOpen_terminal_triggered() { - if (projectfs_menu_target.path().isEmpty()) return; - Core::FileUtils::openTerminal(QDir(projectfs_menu_target.absoluteFilePath()).path()); -} - - -void ProjectFilesystemWidget::on_actionCopy_name_triggered() { - if (projectfs_menu_target.path().isEmpty()) return; - QApplication::clipboard()->setText(projectfs_menu_target.fileName()); -} - - -void ProjectFilesystemWidget::on_actionCopy_path_triggered() { - if (projectfs_menu_target.path().isEmpty()) return; - QApplication::clipboard()->setText(projectfs_menu_target.absoluteFilePath()); -} +#include "projectfilesystemwidget.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QFileInfo projectfs_menu_target; + + +ProjectFilesystemWidget::ProjectFilesystemWidget(QWidget * parent): QWidget(parent) { + setupUi(this); + in_proc = need_rebuild = false; + int is = style()->pixelMetric(QStyle::PM_ButtonIconSize, 0, this); + label->setFixedSize(is, is); + buttonClear->setIcon(Utils::Icons::CLEAN.icon()); + buttonExpand->setIcon(Utils::Icons::EXPAND.icon()); + buttonCollapse->setIcon(Utils::Icons::COLLAPSE.icon()); + actionOpen_here->setIcon(Utils::Icons::OPENFILE.icon()); + actionOpen_external->setIcon(Utils::Icons::OPENFILE.icon()); + actionShow_external->setIcon(Core::FileIconProvider::icon(QFileIconProvider::Folder)); + actionCopy_name->setIcon(Utils::Icons::COPY.icon()); + actionCopy_path->setIcon(Utils::Icons::COPY.icon()); + popup_menu.addActions(QList() << actionOpen_here << actionOpen_external << actionShow_external << actionOpen_terminal); + popup_menu.addSeparator(); + popup_menu.addActions(QList() << actionCopy_name << actionCopy_path); + proj_plug = 0; + //connect(ProjectExplorer::ProjectTree::instance(), SIGNAL(subtreeChanged(ProjectExplorer::FolderNode*)), this, SLOT(projectsChanged())); + connect(ProjectExplorer::SessionManager::instance(), SIGNAL(startupProjectChanged(ProjectExplorer::Project *)), this, SLOT(startupProjectChanged())); + connect(ProjectExplorer::SessionManager::instance(), SIGNAL(projectAdded(ProjectExplorer::Project*)), this, SLOT(projectsChanged())); + connect(ProjectExplorer::SessionManager::instance(), SIGNAL(projectDisplayNameChanged(ProjectExplorer::Project*)), this, SLOT(projectsChanged())); + connect(ProjectExplorer::SessionManager::instance(), SIGNAL(projectRemoved(ProjectExplorer::Project*)), this, SLOT(projectsChanged())); + //connect(ProjectExplorer::SessionManager::instance(), SIGNAL(), this, SLOT(startupProjectChanged())); + connect(Core::EditorManager::instance(), SIGNAL(currentEditorChanged(Core::IEditor*)), this, SLOT(fileChanged())); + projectsChanged(); +} + + +void ProjectFilesystemWidget::setCurrentFilter(const FilterDialog::Filter & v) { + cur_filter = v; + projectsChanged(); +} + + +void ProjectFilesystemWidget::changeEvent(QEvent *e) { + QWidget::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + retranslateUi(this); + break; + default: + break; + } +} + + +void ProjectFilesystemWidget::createTree(QTreeWidgetItem * ti, const QString & dir) { + QFileInfoList fl = QDir(dir).entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot, QDir::LocaleAware | QDir::DirsFirst); + checkProcEvents(); + for (QFileInfo i: fl) { + QString nit = i.fileName(); + if (i.isDir()) { + if (!cur_filter.filterDir(nit)) + continue; + } else { + if (!cur_filter.filterFile(nit)) + continue; + } + QTreeWidgetItem * ni = new QTreeWidgetItem(); + ni->setText(0, nit); + ni->setIcon(0, Core::FileIconProvider::icon(i)); + ni->setData(0, Qt::UserRole, i.absoluteFilePath()); + ni->setData(0, Qt::UserRole + 1, i.isDir()); + item_map[i.absoluteFilePath()] = ni; + if (i.isDir()) { + createTree(ni, dir + QDir::separator() + i.fileName()); + } + ti->addChild(ni); + } + //if (ti->childCount() == 0) delete ti; +} + + +bool ProjectFilesystemWidget::filterTree(QTreeWidgetItem * ti, const QString & filter) { + bool ret = false; + for (int i = 0; i < ti->childCount(); ++i) { + QTreeWidgetItem * ci = ti->child(i); + QString cit = ci->text(0); + if (ci->data(0, Qt::UserRole + 1).toBool()) { + if (!filterTree(ci, filter)) { + ci->setHidden(true); + continue; + } + ci->setHidden(false); + ret = true; + } else { + bool f = false; + if (filter.isEmpty()) { + f = true; + } else { + f = f || cit.contains(filter); + } + ci->setHidden(!f); + if (f) ret = true; + } + } + return ret; +} + + +void ProjectFilesystemWidget::filter() { + QString f = lineFilter->text(); + for (int i = 0; i < tree->topLevelItemCount(); ++i) { + QTreeWidgetItem * ti = tree->topLevelItem(i); + filterTree(ti, f); + } +} + + +void ProjectFilesystemWidget::rememberExpanded(QTreeWidgetItem * ti) { + //QMessageBox::information(0, ti->data(0, Qt::UserRole).toString(), QString::number(ti->childCount())); + for (int i = 0; i < ti->childCount(); ++i) { + QTreeWidgetItem * ci = ti->child(i); + if (ci->data(0, Qt::UserRole + 1).toBool()) { + if (ci->isExpanded()) + last_expanded << ci->data(0, Qt::UserRole).toString(); + rememberExpanded(ci); + } + } +} + + +void ProjectFilesystemWidget::restoreExpanded(QTreeWidgetItem * ti) { + for (int i = 0; i < ti->childCount(); ++i) { + QTreeWidgetItem * ci = ti->child(i); + if (ci->data(0, Qt::UserRole + 1).toBool()) { + if (last_expanded.contains(ci->data(0, Qt::UserRole).toString())) + ci->setExpanded(true); + restoreExpanded(ci); + } + } +} + + +void ProjectFilesystemWidget::setExtVariable() { +} + + +void ProjectFilesystemWidget::checkProcEvents() { + if (tm.elapsed() < 10) return; + QApplication::processEvents(); + tm.start(); +} + + +void ProjectFilesystemWidget::projectsChanged() { + if (in_proc) { + need_rebuild = true; + return; + } + in_proc = true; + tm.start(); + last_expanded.clear(); + item_map.clear(); + int spos = tree->verticalScrollBar()->value(); + rememberExpanded(tree->invisibleRootItem()); + tree->clear(); + QApplication::setOverrideCursor(Qt::WaitCursor); + QList pl = ProjectExplorer::SessionManager::projects(); + for (ProjectExplorer::Project * p: pl) { + QTreeWidgetItem * ri = new QTreeWidgetItem(); + QString dir = p->projectDirectory().toString(); + ri->setText(0, p->displayName()); + QFile logo(dir + "/logo.png"); + if (logo.exists()) + ri->setIcon(0, QIcon(logo.fileName())); + else + ri->setIcon(0, Core::FileIconProvider::icon(QFileIconProvider::Folder)); + ri->setData(0, Qt::UserRole, dir); + ri->setData(0, Qt::UserRole + 1, true); + createTree(ri, dir); + tree->addTopLevelItem(ri); + } + startupProjectChanged(); + fileChanged(); + filter(); + restoreExpanded(tree->invisibleRootItem()); + QApplication::restoreOverrideCursor(); + qApp->processEvents(); + tree->verticalScrollBar()->setValue(spos); + in_proc = false; + if (need_rebuild) { + need_rebuild = false; + projectsChanged(); + } +} + + +void ProjectFilesystemWidget::filterClicked() { + filter_dialog.setFilter(cur_filter); + if (filter_dialog.exec() == QDialog::Rejected) return; + setCurrentFilter(filter_dialog.filter()); +} + + +void ProjectFilesystemWidget::fileChanged() { + Core::IDocument * cd = Core::EditorManager::instance()->currentDocument(); + if (!cd) return; + QString np = cd->filePath().toString(); + QTreeWidgetItem * ti = item_map.value(np); + if (!ti) return; + tree->setCurrentItem(ti); + tree->expandItem(ti); +} + + +void ProjectFilesystemWidget::startupProjectChanged() { + ProjectExplorer::Project * sp = ProjectExplorer::SessionManager::startupProject(); + QFont f(tree->font()), bf(f); + bf.setBold(true); + for (int i = 0; i < tree->topLevelItemCount(); ++i) { + QTreeWidgetItem * ti = tree->topLevelItem(i); + ti->setFont(0, f); + if (!sp) continue; + if (sp->projectDirectory().toString() == ti->data(0, Qt::UserRole).toString()) + ti->setFont(0, bf); + } +} + + +void ProjectFilesystemWidget::on_tree_itemDoubleClicked(QTreeWidgetItem * item, int) { + if (!item) return; + QString afp = item->data(0, Qt::UserRole).toString(); + bool dir = item->data(0, Qt::UserRole + 1).toBool(); + if (dir) return; + if (afp.isEmpty()) return; + Core::EditorManager::openEditor(afp); +} + + +void ProjectFilesystemWidget::on_lineFilter_textChanged(const QString & ) { + filter(); +} + + +void ProjectFilesystemWidget::on_tree_itemClicked(QTreeWidgetItem * item, int column) { + projectfs_menu_target = QFileInfo(); + if (!item) { + setExtVariable(); + return; + } + projectfs_menu_target = QFileInfo(item->data(0, Qt::UserRole).toString()); + setExtVariable(); +} + + +void ProjectFilesystemWidget::on_tree_customContextMenuRequested(const QPoint & pos) { + projectfs_menu_target = QFileInfo(); + QTreeWidgetItem * item = tree->itemAt(pos); + //QMessageBox::information(this, "", QString::number(index.row())); + if (!item) { + setExtVariable(); + return; + } + projectfs_menu_target = QFileInfo(item->data(0, Qt::UserRole).toString()); + setExtVariable(); + actionOpen_here->setEnabled(!projectfs_menu_target.isDir()); + actionOpen_external->setEnabled(!projectfs_menu_target.isDir()); + popup_menu.popup(tree->mapToGlobal(pos)); +} + + +void ProjectFilesystemWidget::on_actionOpen_here_triggered() { + if (projectfs_menu_target.path().isEmpty()) return; + Core::EditorManager::openEditor(projectfs_menu_target.absoluteFilePath(), Core::Constants::K_DEFAULT_TEXT_EDITOR_ID); +} + + +void ProjectFilesystemWidget::on_actionOpen_external_triggered() { + if (projectfs_menu_target.path().isEmpty()) return; + QString wd = QDir::current().absolutePath(); + QDir::setCurrent(projectfs_menu_target.absoluteDir().path()); + QDesktopServices::openUrl(QUrl::fromLocalFile(projectfs_menu_target.absoluteFilePath())); + QDir::setCurrent(wd); +} + + +void ProjectFilesystemWidget::on_actionShow_external_triggered() { + if (projectfs_menu_target.path().isEmpty()) return; + Core::FileUtils::showInGraphicalShell(Core::ICore::mainWindow(), projectfs_menu_target.absoluteFilePath()); +} + + +void ProjectFilesystemWidget::on_actionOpen_terminal_triggered() { + if (projectfs_menu_target.path().isEmpty()) return; + Core::FileUtils::openTerminal(QDir(projectfs_menu_target.absoluteFilePath()).path()); +} + + +void ProjectFilesystemWidget::on_actionCopy_name_triggered() { + if (projectfs_menu_target.path().isEmpty()) return; + QApplication::clipboard()->setText(projectfs_menu_target.fileName()); +} + + +void ProjectFilesystemWidget::on_actionCopy_path_triggered() { + if (projectfs_menu_target.path().isEmpty()) return; + QApplication::clipboard()->setText(projectfs_menu_target.absoluteFilePath()); +} diff --git a/project_fs/projectfilesystemwidget.h b/project_fs/projectfilesystemwidget.h index 0832d95..f9634f0 100644 --- a/project_fs/projectfilesystemwidget.h +++ b/project_fs/projectfilesystemwidget.h @@ -1,68 +1,68 @@ -#ifndef PROJECTFILESYSTEMWIDGET_H -#define PROJECTFILESYSTEMWIDGET_H - -#include "ui_projectfilesystemwidget.h" -#include "filterdialog.h" -#include -#include -#include -#include -#include - -extern QFileInfo projectfs_menu_target; - -class ProjectsModel; - -class ProjectFilesystemWidget: public QWidget, private Ui::ProjectFilesystemWidget -{ - Q_OBJECT -public: - explicit ProjectFilesystemWidget(QWidget * parent = 0); - - FilterDialog::Filter currentFilters() const {return cur_filter;} - QString currentSearch() const {return lineFilter->text();} - - void setCurrentFilter(const FilterDialog::Filter & v); - void setCurrentSearch(QString v) {lineFilter->setText(v);} - -protected: - void changeEvent(QEvent * e); - void createTree(QTreeWidgetItem * ti, const QString & dir); - bool filterTree(QTreeWidgetItem * ti, const QString & filter); - void filter(); - void rememberExpanded(QTreeWidgetItem * ti); - void restoreExpanded(QTreeWidgetItem * ti); - void setExtVariable(); - void checkProcEvents(); - - bool in_proc, need_rebuild; - ExtensionSystem::IPlugin * proj_plug; - QMenu popup_menu; - QMap item_map; - QSet last_expanded; - FilterDialog filter_dialog; - FilterDialog::Filter cur_filter; - QElapsedTimer tm; - -public slots: - void projectsChanged(); - void filterClicked(); - -private slots: - void fileChanged(); - void startupProjectChanged(); - - void on_tree_itemDoubleClicked(QTreeWidgetItem * item, int ); - void on_lineFilter_textChanged(const QString &); - void on_tree_itemClicked(QTreeWidgetItem *item, int column); - void on_tree_customContextMenuRequested(const QPoint & pos); - void on_actionOpen_here_triggered(); - void on_actionOpen_external_triggered(); - void on_actionShow_external_triggered(); - void on_actionOpen_terminal_triggered(); - void on_actionCopy_name_triggered(); - void on_actionCopy_path_triggered(); - -}; - -#endif // PROJECTFILESYSTEMWIDGET_H +#ifndef PROJECTFILESYSTEMWIDGET_H +#define PROJECTFILESYSTEMWIDGET_H + +#include "ui_projectfilesystemwidget.h" +#include "filterdialog.h" +#include +#include +#include +#include +#include + +extern QFileInfo projectfs_menu_target; + +class ProjectsModel; + +class ProjectFilesystemWidget: public QWidget, private Ui::ProjectFilesystemWidget +{ + Q_OBJECT +public: + explicit ProjectFilesystemWidget(QWidget * parent = 0); + + FilterDialog::Filter currentFilters() const {return cur_filter;} + QString currentSearch() const {return lineFilter->text();} + + void setCurrentFilter(const FilterDialog::Filter & v); + void setCurrentSearch(QString v) {lineFilter->setText(v);} + +protected: + void changeEvent(QEvent * e); + void createTree(QTreeWidgetItem * ti, const QString & dir); + bool filterTree(QTreeWidgetItem * ti, const QString & filter); + void filter(); + void rememberExpanded(QTreeWidgetItem * ti); + void restoreExpanded(QTreeWidgetItem * ti); + void setExtVariable(); + void checkProcEvents(); + + bool in_proc, need_rebuild; + ExtensionSystem::IPlugin * proj_plug; + QMenu popup_menu; + QMap item_map; + QSet last_expanded; + FilterDialog filter_dialog; + FilterDialog::Filter cur_filter; + QElapsedTimer tm; + +public slots: + void projectsChanged(); + void filterClicked(); + +private slots: + void fileChanged(); + void startupProjectChanged(); + + void on_tree_itemDoubleClicked(QTreeWidgetItem * item, int ); + void on_lineFilter_textChanged(const QString &); + void on_tree_itemClicked(QTreeWidgetItem *item, int column); + void on_tree_customContextMenuRequested(const QPoint & pos); + void on_actionOpen_here_triggered(); + void on_actionOpen_external_triggered(); + void on_actionShow_external_triggered(); + void on_actionOpen_terminal_triggered(); + void on_actionCopy_name_triggered(); + void on_actionCopy_path_triggered(); + +}; + +#endif // PROJECTFILESYSTEMWIDGET_H diff --git a/project_fs/projectfilesystemwidget.ui b/project_fs/projectfilesystemwidget.ui index c05af68..06dbeb2 100644 --- a/project_fs/projectfilesystemwidget.ui +++ b/project_fs/projectfilesystemwidget.ui @@ -1,183 +1,183 @@ - - - ProjectFilesystemWidget - - - - 0 - 0 - 386 - 390 - - - - - - - - - :/icons/edit-find.png - - - true - - - - - - - - - - - - - Qt::Horizontal - - - QSizePolicy::Preferred - - - - 20 - 20 - - - - - - - - Expand tree - - - - - - - Collapse tree - - - - - - - - - Qt::CustomContextMenu - - - QAbstractItemView::NoEditTriggers - - - Qt::ElideMiddle - - - QAbstractItemView::ScrollPerPixel - - - true - - - true - - - false - - - - Path - - - - - - - - Open as plain - - - - - Open external ... - - - - - Show external ... - - - - - Copy name - - - - - Copy path - - - - - - :/icons/utilities-terminal.png:/icons/utilities-terminal.png - - - Open terminal ... - - - - - - - - - buttonClear - clicked() - lineFilter - clear() - - - 246 - 37 - - - 212 - 35 - - - - - buttonExpand - clicked() - tree - expandAll() - - - 263 - 28 - - - 251 - 58 - - - - - buttonCollapse - clicked() - tree - collapseAll() - - - 307 - 27 - - - 297 - 71 - - - - - + + + ProjectFilesystemWidget + + + + 0 + 0 + 386 + 390 + + + + + + + + + :/icons/edit-find.png + + + true + + + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Preferred + + + + 20 + 20 + + + + + + + + Expand tree + + + + + + + Collapse tree + + + + + + + + + Qt::CustomContextMenu + + + QAbstractItemView::NoEditTriggers + + + Qt::ElideMiddle + + + QAbstractItemView::ScrollPerPixel + + + true + + + true + + + false + + + + Path + + + + + + + + Open as plain + + + + + Open external ... + + + + + Show external ... + + + + + Copy name + + + + + Copy path + + + + + + :/icons/utilities-terminal.png:/icons/utilities-terminal.png + + + Open terminal ... + + + + + + + + + buttonClear + clicked() + lineFilter + clear() + + + 246 + 37 + + + 212 + 35 + + + + + buttonExpand + clicked() + tree + expandAll() + + + 263 + 28 + + + 251 + 58 + + + + + buttonCollapse + clicked() + tree + collapseAll() + + + 307 + 27 + + + 297 + 71 + + + + + diff --git a/project_fs/projectfilesystemwidgetplugin.cpp b/project_fs/projectfilesystemwidgetplugin.cpp index 48f619c..4e28125 100644 --- a/project_fs/projectfilesystemwidgetplugin.cpp +++ b/project_fs/projectfilesystemwidgetplugin.cpp @@ -1,57 +1,57 @@ -#include "projectfilesystemwidgetplugin.h" -#include "projectfilesystemwidget.h" -#include -#include -#include -#include - - -ProjectFSWidgetFactory::ProjectFSWidgetFactory() { - setDisplayName(QString::fromLatin1("Project filesystem")); - setId("project_filesystem"); -} - - -Core::NavigationView ProjectFSWidgetFactory::createWidget() { - Core::NavigationView view; - view.widget = new ProjectFilesystemWidget(); - QToolButton * btn = new QToolButton(); - btn->setIcon(Utils::Icons::RELOAD.icon()); - btn->setToolTip(tr("Reload tree")); - view.dockToolBarWidgets << btn; - connect(btn, SIGNAL(clicked()), view.widget, SLOT(projectsChanged())); - btn = new QToolButton(); - btn->setIcon(Utils::Icons::FILTER.icon()); - btn->setToolTip(tr("Setup filters ...")); - view.dockToolBarWidgets << btn; - connect(btn, SIGNAL(clicked()), view.widget, SLOT(filterClicked())); - return view; -} - - -void ProjectFSWidgetFactory::saveSettings(QSettings * settings, int position, QWidget * widget) { - //QMessageBox::information(0, "", QString::fromLatin1(widget->metaObject()->className())); - ProjectFilesystemWidget * w = qobject_cast(widget); - if (!w) return; - settings->beginGroup("ProjectFilesystem"); - settings->beginWriteArray("widget"); - settings->setArrayIndex(position); - settings->setValue("filters", w->currentFilters().toVariant()); - settings->setValue("search", w->currentSearch()); - settings->endArray(); - settings->endGroup(); - settings->sync(); -} - - -void ProjectFSWidgetFactory::restoreSettings(QSettings * settings, int position, QWidget * widget) { - ProjectFilesystemWidget * w = qobject_cast(widget); - if (!w) return; - settings->beginGroup("ProjectFilesystem"); - settings->beginReadArray("widget"); - settings->setArrayIndex(position); - w->setCurrentFilter(FilterDialog::Filter(settings->value("filters", FilterDialog::Filter().toVariant()))); - w->setCurrentSearch(settings->value("search", QString()).toString()); - settings->endArray(); - settings->endGroup(); -} +#include "projectfilesystemwidgetplugin.h" +#include "projectfilesystemwidget.h" +#include +#include +#include +#include + + +ProjectFSWidgetFactory::ProjectFSWidgetFactory() { + setDisplayName(QString::fromLatin1("Project filesystem")); + setId("project_filesystem"); +} + + +Core::NavigationView ProjectFSWidgetFactory::createWidget() { + Core::NavigationView view; + view.widget = new ProjectFilesystemWidget(); + QToolButton * btn = new QToolButton(); + btn->setIcon(Utils::Icons::RELOAD.icon()); + btn->setToolTip(tr("Reload tree")); + view.dockToolBarWidgets << btn; + connect(btn, SIGNAL(clicked()), view.widget, SLOT(projectsChanged())); + btn = new QToolButton(); + btn->setIcon(Utils::Icons::FILTER.icon()); + btn->setToolTip(tr("Setup filters ...")); + view.dockToolBarWidgets << btn; + connect(btn, SIGNAL(clicked()), view.widget, SLOT(filterClicked())); + return view; +} + + +void ProjectFSWidgetFactory::saveSettings(QSettings * settings, int position, QWidget * widget) { + //QMessageBox::information(0, "", QString::fromLatin1(widget->metaObject()->className())); + ProjectFilesystemWidget * w = qobject_cast(widget); + if (!w) return; + settings->beginGroup("ProjectFilesystem"); + settings->beginWriteArray("widget"); + settings->setArrayIndex(position); + settings->setValue("filters", w->currentFilters().toVariant()); + settings->setValue("search", w->currentSearch()); + settings->endArray(); + settings->endGroup(); + settings->sync(); +} + + +void ProjectFSWidgetFactory::restoreSettings(QSettings * settings, int position, QWidget * widget) { + ProjectFilesystemWidget * w = qobject_cast(widget); + if (!w) return; + settings->beginGroup("ProjectFilesystem"); + settings->beginReadArray("widget"); + settings->setArrayIndex(position); + w->setCurrentFilter(FilterDialog::Filter(settings->value("filters", FilterDialog::Filter().toVariant()))); + w->setCurrentSearch(settings->value("search", QString()).toString()); + settings->endArray(); + settings->endGroup(); +} diff --git a/project_fs/projectfilesystemwidgetplugin.h b/project_fs/projectfilesystemwidgetplugin.h index ccd652d..0cf213a 100644 --- a/project_fs/projectfilesystemwidgetplugin.h +++ b/project_fs/projectfilesystemwidgetplugin.h @@ -1,18 +1,18 @@ -#pragma once - -#include -#include - - -class ProjectFSWidgetFactory: public Core::INavigationWidgetFactory -{ -public: - ProjectFSWidgetFactory(); - ~ProjectFSWidgetFactory() {} - - Core::NavigationView createWidget(); - - void saveSettings(QSettings * settings, int position, QWidget * widget); - void restoreSettings(QSettings * settings, int position, QWidget * widget); - -}; +#pragma once + +#include +#include + + +class ProjectFSWidgetFactory: public Core::INavigationWidgetFactory +{ +public: + ProjectFSWidgetFactory(); + ~ProjectFSWidgetFactory() {} + + Core::NavigationView createWidget(); + + void saveSettings(QSettings * settings, int position, QWidget * widget); + void restoreSettings(QSettings * settings, int position, QWidget * widget); + +}; diff --git a/qad/CMakeLists.txt b/qad/CMakeLists.txt index e23b647..6a09498 100644 --- a/qad/CMakeLists.txt +++ b/qad/CMakeLists.txt @@ -1,89 +1,40 @@ -cmake_minimum_required(VERSION 3.0) -cmake_policy(SET CMP0017 NEW) # need include() with .cmake -project(qad) -set(_QAD_MAJOR 1) -set(_QAD_MINOR 7) -set(_QAD_REVISION 0) -set(_QAD_SUFFIX ) -set(_QAD_COMPANY SHS) -set(_QAD_DOMAIN org.SHS) - -include(QADMacros) -include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) - -if(STATIC_LIB) - set(QAD_LIB_TYPE STATIC) - add_definitions(-DQAD_STATIC_DEFINE) -else() - set(QAD_LIB_TYPE SHARED) -endif() - -if (NOT DEFINED ANDROID_PLATFORM) - find_package(OpenGL REQUIRED) -endif() -if (MINGW) - find_package(MinGW REQUIRED) -endif() - - -# Version -if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/qad_version.h") - file(REMOVE "${CMAKE_CURRENT_SOURCE_DIR}/qad_version.h") -endif() -set(QAD_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/qad_version.h") -set_version(QAD - MAJOR "${_QAD_MAJOR}" - MINOR "${_QAD_MINOR}" - REVISION "${_QAD_REVISION}" - BUILD "${BUILD_NUMBER}" - SUFFIX "${_QAD_SUFFIX}" - OUTPUT "${QAD_VERSION_FILE}") -set_deploy_property(QAD ${QAD_LIB_TYPE} - FULLNAME "${_QAD_DOMAIN}.*" - COMPANY "${_QAD_COMPANY}") -message(STATUS "Building QAD version ${QAD_VERSION} (${QAD_LIB_TYPE})") - - -if (NOT LIBPROJECT) - if (LIB) - if(WIN32) - if(MINGW) - set(CMAKE_INSTALL_PREFIX ${MINGW_DIR}) - endif() - else() - if (DEFINED ANDROID_PLATFORM) - set(CMAKE_INSTALL_PREFIX ${ANDROID_SYSTEM_LIBRARY_PATH}/usr) - else() - set(CMAKE_INSTALL_PREFIX /usr/local) - endif() - endif() - message(STATUS "Install ${PROJECT_NAME} to system \"${CMAKE_INSTALL_PREFIX}\"") - else() - message(STATUS "Install ${PROJECT_NAME} to local \"bin\", \"lib\" and \"include\"") - endif() -endif() - -file(GLOB CMAKES "cmake/*.cmake" "cmake/*.in") - -if (LIB) - install(FILES ${CMAKES} DESTINATION ${CMAKE_ROOT}/Modules) - if (WIN32) - install(FILES ${QAD_VERSION_FILE} DESTINATION ${MINGW_INCLUDE}/qad) - else() - install(FILES ${QAD_VERSION_FILE} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/qad) - endif() -else() - install(FILES ${QAD_VERSION_FILE} DESTINATION include/qad) -endif() - -add_subdirectory(libs) -if (UTILS) - add_subdirectory(utils) -endif() - -set(QT_MULTILIB_LIST ${QT_MULTILIB_LIST} PARENT_SCOPE) -set(qad_includes ${qad_includes} PARENT_SCOPE) -if (LIB) - set(_ALL_TARGETS ${_ALL_TARGETS} PARENT_SCOPE) -endif() - +cmake_minimum_required(VERSION 3.0) +cmake_policy(SET CMP0017 NEW) # need include() with .cmake +project(qad) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +if (NOT DEFINED ANDROID_PLATFORM) + find_package(OpenGL REQUIRED) +endif() +if (MINGW) + find_package(MinGW REQUIRED) +endif() + + +# Version +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/qad_version.h") + file(REMOVE "${CMAKE_CURRENT_SOURCE_DIR}/qad_version.h") +endif() +#message(STATUS "Building QAD version ${QAD_VERSION} (${QAD_LIB_TYPE})") + +file(GLOB CMAKES "cmake/*.cmake" "cmake/*.in") + +if (LIB) + install(FILES ${CMAKES} DESTINATION ${CMAKE_ROOT}/Modules) + if (WIN32) + install(FILES ${QAD_VERSION_FILE} DESTINATION ${MINGW_INCLUDE}/qad) + else() + install(FILES ${QAD_VERSION_FILE} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/qad) + endif() +else() + install(FILES ${QAD_VERSION_FILE} DESTINATION include/qad) +endif() + +add_subdirectory(libs) +if (UTILS) + add_subdirectory(utils) +endif() + +copy_to_parent(qad_includes) + diff --git a/qad/cmake/QADMacros.cmake b/qad/cmake/QADMacros.cmake index 63eb900..3f1b73d 100644 --- a/qad/cmake/QADMacros.cmake +++ b/qad/cmake/QADMacros.cmake @@ -4,10 +4,10 @@ macro(_qt_install _TARGET IS_APP _DIR _HDR_VAR _QM_FILES) endmacro() -macro(qad_plugin NAME _MODULES _LIBS) +macro(_qt_plugin NAME _MODULES _LIBS) if (NOT STATIC_LIB) if(DESIGNER_PLUGINS) - set(PROJ_NAME qad_${NAME}_plugin) + set(PROJ_NAME ${NAME}_plugin) include_directories("..") add_definitions(-DQT_PLUGIN) add_definitions(-DQT_NO_DEBUG) @@ -17,12 +17,14 @@ macro(qad_plugin NAME _MODULES _LIBS) qt_sources(SRC) qt_wrap(${SRC} CPPS out_CPP QMS out_QM) qt_add_library(${PROJ_NAME} SHARED out_CPP) - qt_target_link_libraries(${PROJ_NAME} ${_LIBS} qad_${NAME} ${_${NAME}_PLUGIN_LIBS}) + qt_target_link_libraries(${PROJ_NAME} ${_LIBS} ${_${NAME}_PLUGIN_LIBS}) if (WIN32) qt_install(TARGETS ${PROJ_NAME} RUNTIME DESTINATION QtPlugins/designer) else() qt_install(TARGETS ${PROJ_NAME} DESTINATION QtPlugins/designer) endif() + list(APPEND _qt_plugs ${NAME}) + copy_to_parent("") endif() endif() endmacro() @@ -35,12 +37,14 @@ macro(_qt_project NAME IS_APP DOMAIN _MODULES _LIBS) import_version(${PROJ_NAME} ${DOMAIN}) import_deploy_properties(${PROJ_NAME} ${DOMAIN}) if (${IS_APP}) + list(APPEND _qt_apps ${PROJ_NAME}) set_deploy_property(${PROJ_NAME} LABEL ${PROJ_NAME} FULLNAME "${_${DOMAIN}_DOMAIN}.${PROJ_NAME}" INFO "${APP_INFO}" ICON "${APP_ICON}") else() + list(APPEND _qt_libs ${PROJ_NAME}) set_deploy_property(${PROJ_NAME} SHARED LABEL ${PROJ_NAME} FULLNAME "${_${DOMAIN}_DOMAIN}.${PROJ_NAME}" @@ -55,23 +59,17 @@ macro(_qt_project NAME IS_APP DOMAIN _MODULES _LIBS) if(NOT STATIC_LIB) qt_target_compile_definitions(${PROJ_NAME} PRIVATE ${DOMAIN}_SHARED_DEFINE) endif() - qt_get_target(${PROJ_NAME} _some_target) - qt_get_target(${PROJ_NAME} _targets) - foreach(_t ${_targets}) - set_target_properties(${_t} PROPERTIES DEFINE_SYMBOL ${PROJ_NAME}_EXPORTS) - endforeach() - set_target_properties(${_some_target} PROPERTIES DEFINE_SYMBOL ${PROJ_NAME}_EXPORTS) - generate_export_header(${_some_target} BASE_NAME "${PROJ_NAME}") + qt_generate_export_header(${PROJ_NAME}) list(APPEND out_HDR "${CMAKE_CURRENT_BINARY_DIR}/${PROJ_NAME}_export.h") endif() qt_target_link_libraries(${PROJ_NAME} ${_LIBS}) list(APPEND QT_MULTILIB_LIST ${PROJ_NAME}) - set(QT_MULTILIB_LIST ${QT_MULTILIB_LIST} PARENT_SCOPE) - message(STATUS "Building ${PROJ_NAME}") + #message(STATUS "Building ${PROJ_NAME}") if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/plugin") set(_${NAME}_PLUGIN_LIBS "${_LIBS}") add_subdirectory(plugin) endif() + copy_to_parent("") endmacro() @@ -85,3 +83,8 @@ macro(qad_application NAME _MODULES _LIBS) _qt_project(${NAME} TRUE "QAD" "${_MODULES}" "${_LIBS}") _qt_install(${NAME} TRUE "qad" "" "out_QM") endmacro() + + +macro(qad_plugin NAME _MODULES _LIBS) + _qt_plugin(qad_${NAME} "${_MODULES}" "qad_${NAME};${_LIBS}") +endmacro() diff --git a/qad/cmake/QtWraps.cmake b/qad/cmake/QtWraps.cmake index b25b04d..da1df24 100644 --- a/qad/cmake/QtWraps.cmake +++ b/qad/cmake/QtWraps.cmake @@ -1,793 +1,811 @@ -#[[ - -find_qt([ ...] [Qt4] [Qt5]) - -Find Qt4 or/and Qt5 packages -If Qt4/5 found, set -* Qt<4/5>_ROOT var to Qt root dir -* Qt<4/5>_BIN var to Qt binary dir -* Qt<4/5>_PLUGINS_DIR var to Qt plugins dir -* Qt<4/5>_LANG_DIR var to Qt translations dir - - - - -qt_sources( [NO_DEFAULT] [DIR ] [ ...]) - -Collect all sources, optionally in directory and -Additional filters . By default filter files with regexps -"*.h", "*.hpp", "*.c", "*.cpp", "*.ui", "*.qrc", "*.rc", "*.ts" and "lang/*.ts". -Default filters disabled with option NO_DEFAULT - - - - -qt_wrap( ... [HDRS ] [CPPS ] [QMS ]) - -Prepare sources for compile -Store headers to , all wrapped Qt4 files to _Qt4 and Qt5 files to _Qt5 -version are automatic detected after find_qt() call - - - - -qt_add_executable( [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] source1 [source2 ...]) - -Add executables for founded Qt versions, target names is -All needed Qt includes automatic added to corresponding targets - cant be CPPS variable passed to qt_wrap() or some list or filename - - - - -qt_add_library( [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] source1 [source2 ...]) - -Add library for founded Qt versions, target names is -All needed Qt includes automatic added to corresponding targets - cant be CPPS variable passed to qt_wrap() or some list or filename - - - - -qt_target_link_libraries( ... ...) - -Link targets for founded Qt versions, target names is -All needed Qt libraries automatic added to corresponding targets -if QT_MULTILIB_LIST contains some linking library, to it name automatic -add or individual libname<_SUFFIX_Qt?> - - - - -qt_target_compile_definitions( ...) - -Syntax similar to original "target_compile_definitions()" -Specify compile definitions to use when compiling a given - - - - -qt_target_include_directories( ...) - -Syntax similar to original "target_include_directories()" -Add include directories to a target - - - - -qt_install(...) - -Syntax similar to original "install()" -Install targets for founded Qt versions - -if DESTINATION set to "QtBin" files will be installed -to corresponding Qt binary directory -if DESTINATION set to "QtLang" files will be installed -to corresponding Qt translation directory -if DESTINATION starts with "QtPlugins" files will be installed -to corresponding Qt plugins directory - -Add LANG type for first argument - in this case you should -specify variable name, not variable value! -e.g. "qt_install(LANG my_QM DESTINATION QtLang)" - - - - -qt_install_lang( DESTINATION [PATHS [] [...] ]) - -Search Qt translations for all dependencies -in Qt_LANG_DIR for _LANG languages -and install them to . PATH are additional search paths. -You should use "set_lang()" macro before this action - - - - -qt_get_target( [Qt4 | Qt5]) - -Write real Qt target name to -If Qt4 or Qt5 specified, search for this version, -otherwise returns greatest version - - - - -qt_get_targets( ) - -Write all real Qt target names to - - -]] - - -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 (POLICY CMP0057) - cmake_policy(SET CMP0057 NEW) # Support if() IN_LIST -endif() -if (POLICY CMP0074) - cmake_policy(SET CMP0074 OLD) # ignore _ROOT variables -endif() -set(__qt_bug_modules "UiTools") - - -set(_QT_VERSIONS_ 4 5) -foreach(_v ${_QT_VERSIONS_}) - if (NOT DEFINED TARGET_SUFFIX_Qt${_v}) - set(TARGET_SUFFIX_Qt${_v} "${_v}") - set(MULTILIB_SUFFIX_Qt${_v} "${_v}") - endif() - set(MOC_INC_Qt${_v}) -endforeach() -if (NOT DEFINED QT_MULTILIB_LIST) - set(QT_MULTILIB_LIST) -endif() -#set(TARGET_SUFFIX_Qt4 "") - - -macro(find_qt) - set(_QCOMP) - foreach(_v ${_QT_VERSIONS_}) - set(_NEED${_v} 0) - set(LOCAL_FOUND${_v} 0) - set(MOC_INC_Qt${_v}) - set(Qt${_v}_INCLUDES) - set(Qt${_v}_LIBRARIES) - set(Qt${_v}_ROOT) - set(Qt${_v}_BIN) - set(Qt${_v}_PLUGINS_DIR) - set(Qt${_v}_LANG_DIR) - endforeach() - set(_NEED_SOME 0) - set(_QUIET) - foreach(_i ${ARGN}) - set(_FOUND_NEED 0) - foreach(_v ${_QT_VERSIONS_}) - if ("x${_i}" STREQUAL "xQt${_v}") - set(_NEED${_v} 1) - set(_NEED_SOME 1) - set(_FOUND_NEED 1) - endif() - if ("x${_i}" STREQUAL "xQUIET") - set(_QUIET QUIET) - endif() - endforeach() - if (NOT _FOUND_NEED) - list(APPEND _QCOMP "${_i}") - endif() - endforeach() - if (NOT _NEED_SOME) - foreach(_v ${_QT_VERSIONS_}) - set(_NEED${_v} 1) - endforeach() - endif() - list(REMOVE_DUPLICATES _QCOMP) - if (_NEED4) - find_package(Qt4 ${_QUIET}) - if (Qt4_FOUND) - set(LOCAL_FOUND4 1) - get_filename_component(Qt4_BIN ${QT_QMAKE_EXECUTABLE} PATH) - set(Qt4_INCLUDES ${QT_INCLUDES}) - foreach(m ${_QCOMP}) - string(TOUPPER "${m}" _um) - #message("${QT_QT${_um}_FOUND}") - if (${QT_QT${_um}_FOUND}) - list(APPEND Qt4_LIBRARIES ${QT_QT${_um}_LIBRARY}) - endif() - endforeach() - set(Qt4_PLUGINS_DIR ${QT_PLUGINS_DIR}) - set(Qt4_LANG_DIR ${Qt4_BIN}/../translations) - set(Qt4_ROOT "${Qt4_BIN}/../") - endif() - endif() - if (_NEED5) - #set(_MSG 1) - #if (Qt5_FOUND) - # set(_MSG 0) - #endif() - find_package(Qt5 COMPONENTS Core LinguistTools UiPlugin Widgets ${_QCOMP} ${_QUIET}) - if (DEFINED ANDROID_PLATFORM) - set(CMAKE_SHARED_MODULE_SUFFIX_CXX ".so") - set(CMAKE_SHARED_LIBRARY_SUFFIX_CXX ".so") - set(CMAKE_SHARED_MODULE_SUFFIX_C ".so") - set(CMAKE_SHARED_LIBRARY_SUFFIX_C ".so") - endif() - if (Qt5_FOUND) - set(LOCAL_FOUND5 1) - set(_Qt5Modules) - foreach(m ${_QCOMP}) - if (${Qt5${m}_FOUND}) - set(__lib ${Qt5${m}_LIBRARIES}) - if (DEFINED ANDROID_PLATFORM) - if (m IN_LIST __qt_bug_modules) - get_target_property(__lib Qt5::${m} LOCATION) - endif() - endif() - list(APPEND _Qt5Modules ${m}) - list(APPEND Qt5_INCLUDES ${Qt5${m}_INCLUDE_DIRS}) - list(APPEND Qt5_LIBRARIES ${__lib}) - endif() - endforeach() - #get_property(_up_dir TARGET Qt5::UiPlugin PROPERTY INTERFACE_INCLUDE_DIRECTORIES) - #message("${_up_dir}") - #if (NOT "x${_up_dir}" STREQUAL "x") - # list(APPEND Qt5_INCLUDES ${_up_dir}) - #endif() - get_target_property(_Qt5_qmake Qt5::qmake LOCATION) - get_filename_component(Qt5_BIN ${_Qt5_qmake} PATH) - foreach(_p ${Qt5Gui_PLUGINS}) - get_target_property(_l ${_p} LOCATION) - get_filename_component(_l ${_l} DIRECTORY) - string(FIND "${_l}" "/" _ind REVERSE) - string(SUBSTRING "${_l}" 0 ${_ind} _l) - set(Qt5_PLUGINS_DIR ${_l}) - #message("Qt5: plugins dir: ${Qt5_PLUGINS_DIR}") - break() - endforeach() - string(FIND "${Qt5_BIN}" "/" _ind REVERSE) - string(SUBSTRING "${Qt5_BIN}" 0 ${_ind} Qt5_ROOT) - if ("x${Qt5_PLUGINS_DIR}" STREQUAL "x") - set(Qt5_PLUGINS_DIR "${Qt5_ROOT}/plugins") - endif() - if (APPLE) - list(APPEND MOC_INC_Qt5 "-F${Qt5_ROOT}/lib") - endif() - set(Qt5_LANG_DIR ${Qt5_BIN}/../translations) - if (NOT _QT5_MSG) - message(STATUS "Found Qt5: ${_Qt5_qmake} (version \"${Qt5_VERSION}\")") - set(_QT5_MSG 1 CACHE BOOL "msg_qt5" FORCE) - #message(STATUS "Found Qt5 modules: ${_Qt5Modules}") - endif() - endif() - endif() - foreach(_v ${_QT_VERSIONS_}) - if (LOCAL_FOUND${_v}) - foreach(_p ${Qt${_v}_INCLUDES}) - list(APPEND MOC_INC_Qt${_v} "-I${_p}") - #message("${_p}") - endforeach() - endif() - #message("${MOC_INC_Qt${_v}}") - endforeach() - -endmacro() - - -macro(qt_sources OUT) - set(${OUT}) - set(_DIR "") - set(_IS_DIR 0) - set(_NO_DEFAULT 0) - set(_DEFAULT) - set(_REGEXP) - set(_REGEXP_WD) - foreach(_i ${ARGN}) - if (_IS_DIR) - set(_DIR "${_i}") - set(_IS_DIR 0) - elseif ("x${_i}" STREQUAL "xDIR") - set(_IS_DIR 1) - elseif ("x${_i}" STREQUAL "xNO_DEFAULT") - set(_NO_DEFAULT 1) - else() - list(APPEND _REGEXP ${_i}) - endif() - endforeach() - if (NOT "x${_DIR}" STREQUAL "x") - #file(TO_CMAKE_PATH "${_DIR}//" _DIR) - string(REPLACE "\\" "/" _DIR "${_DIR}/") - string(REPLACE "//" "/" _DIR "${_DIR}") - endif() - foreach(_i ${_REGEXP}) - list(APPEND _REGEXP_WD "${_DIR}${_i}") - endforeach() - if (NOT _NO_DEFAULT) - set(_DEFAULT "${_DIR}*.h" "${_DIR}*.hpp" "${_DIR}*.c" "${_DIR}*.cpp" "${_DIR}*.ui" "${_DIR}*.qrc" "${_DIR}*.rc" "${_DIR}*.ts" "${_DIR}lang/*.ts") - endif() - #message("${_DEFAULT}, ${_REGEXP_WD}") - file(GLOB ${OUT} ${_DEFAULT} ${_REGEXP_WD}) -endmacro() - - -macro(qt_wrap) - set(HDR_VAR) - set(CPP_VAR) - set(QM_VAR) - set(_HDR_ARG 0) - set(_CPP_ARG 0) - set(_QM_ARG 0) - set(WAS_HDR_ARG 0) - set(WAS_CPP_ARG 0) - set(WAS_QM_ARG 0) - set(FILE_LIST) - foreach(_i ${ARGN}) - if (_HDR_ARG) - set(HDR_VAR ${_i}) - set(WAS_HDR_ARG 1) - set(_HDR_ARG 0) - elseif (_CPP_ARG) - set(CPP_VAR ${_i}) - set(WAS_CPP_ARG 1) - set(_CPP_ARG 0) - elseif (_QM_ARG) - set(QM_VAR ${_i}) - set(WAS_QM_ARG 1) - set(_QM_ARG 0) - elseif ("x${_i}" STREQUAL "xHDRS") - set(_HDR_ARG 1) - elseif ("x${_i}" STREQUAL "xCPPS") - set(_CPP_ARG 1) - elseif ("x${_i}" STREQUAL "xQMS") - set(_QM_ARG 1) - else() - list(APPEND FILE_LIST "${_i}") - endif() - endforeach() - foreach(_v ${_QT_VERSIONS_}) - set(CPP${_v}_VAR) - set(QM${_v}_VAR) - if (LOCAL_FOUND${_v}) - if (WAS_CPP_ARG) - set(CPP${_v}_VAR ${CPP_VAR}_Qt${_v}) - endif() - if (WAS_QM_ARG) - set(QM${_v}_VAR ${QM_VAR}_Qt${_v}) - endif() - endif() - endforeach() - #message("found 4: ${LOCAL_FOUND4}, 5: ${LOCAL_FOUND5}") - #message("has HRDS: ${WAS_HDR_ARG}: ${HDR_VAR}") - #message("has CPPS4: ${WAS_CPP_ARG}: ${CPP4_VAR}") - #message("has CPPS5: ${WAS_CPP_ARG}: ${CPP5_VAR}") - #message("files: ${FILE_LIST}") - set(H_LIST) - set(CPP_LIST) - set(UI_LIST) - set(RES_LIST) - set(RC_LIST) - set(TS_LIST) - foreach(_i ${FILE_LIST}) - get_filename_component(_EXT "${_i}" EXT) - #message("${_EXT}") - if (NOT ("x${_EXT}" STREQUAL "x")) - if (("x${_EXT}" STREQUAL "x.h") OR ("x${_EXT}" STREQUAL "x.hpp")) - list(APPEND H_LIST "${_i}") - #message("header") - endif() - if (("x${_EXT}" STREQUAL "x.c") OR ("x${_EXT}" STREQUAL "x.cpp") OR ("x${_EXT}" STREQUAL "x.cxx")) - list(APPEND CPP_LIST "${_i}") - #message("source") - endif() - if ("x${_EXT}" STREQUAL "x.ui") - list(APPEND UI_LIST "${_i}") - endif() - if ("x${_EXT}" STREQUAL "x.qrc") - list(APPEND RES_LIST "${_i}") - endif() - if ("x${_EXT}" STREQUAL "x.rc") - list(APPEND RC_LIST "${_i}") - endif() - if ("x${_EXT}" STREQUAL "x.ts") - list(APPEND TS_LIST "${_i}") - endif() - endif() - endforeach() - if (WAS_HDR_ARG) - set(${HDR_VAR}) - list(APPEND ${HDR_VAR} ${H_LIST}) - endif() - set(SRC_CMAKE_CURRENT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) - foreach(_v ${_QT_VERSIONS_}) - if (LOCAL_FOUND${_v} AND WAS_CPP_ARG) - set(CMAKE_CURRENT_BINARY_DIR ${SRC_CMAKE_CURRENT_BINARY_DIR}/qt${_v}) - set(${CPP${_v}_VAR}) - if (WAS_QM_ARG) - set(${QM${_v}_VAR}) - endif() - set(MOCS${_v}) - set(CUIS${_v}) - set(CRES${_v}) - if (${_v} EQUAL 4) - qt4_wrap_cpp(MOCS${_v} ${H_LIST} OPTIONS -nw ${MOC_INC_Qt4}) - qt4_wrap_ui(CUIS${_v} ${UI_LIST}) - qt4_add_resources(CRES${_v} ${RES_LIST}) - if (WAS_QM_ARG) - set(${QM${_v}_VAR} "") - qt4_add_translation(${QM${_v}_VAR} ${TS_LIST}) - endif() - elseif (${_v} EQUAL 5) - qt5_wrap_cpp(MOCS${_v} ${H_LIST} OPTIONS -nw ${MOC_INC_Qt5}) - qt5_wrap_ui(CUIS${_v} ${UI_LIST}) - qt5_add_resources(CRES${_v} ${RES_LIST}) - if (WAS_QM_ARG) - set(${QM${_v}_VAR} "") - qt5_add_translation(${QM${_v}_VAR} ${TS_LIST}) - endif() - else() - # Qt6 ... - endif() - #message("${${QM${_v}_VAR}}") - list(APPEND ${CPP${_v}_VAR} ${CPP_LIST}) - list(APPEND ${CPP${_v}_VAR} ${RC_LIST}) - list(APPEND ${CPP${_v}_VAR} ${MOCS${_v}}) - list(APPEND ${CPP${_v}_VAR} ${CUIS${_v}}) - list(APPEND ${CPP${_v}_VAR} ${CRES${_v}}) - if (WAS_QM_ARG) - list(APPEND ${CPP${_v}_VAR} ${${QM${_v}_VAR}}) - endif() - #message("${${QM${_v}_VAR}}") - endif() - endforeach() - set(CMAKE_CURRENT_BINARY_DIR ${SRC_CMAKE_CURRENT_BINARY_DIR}) -endmacro() - - -macro(_qt_split_add_args _P _A) - set(${_P}) - set(${_A}) - foreach(_i ${ARGN}) - if (NOT ("x${${_i}_Qt${_v}}" STREQUAL "x")) - list(APPEND ${_A} ${${_i}_Qt${_v}}) - elseif (("x${_i}" STREQUAL "xWIN32") OR - ("x${_i}" STREQUAL "xMACOSX_BUNDLE") OR - ("x${_i}" STREQUAL "xSTATIC") OR - ("x${_i}" STREQUAL "xSHARED") OR - ("x${_i}" STREQUAL "xMODULE") OR - ("x${_i}" STREQUAL "xEXCLUDE_FROM_ALL")) - list(APPEND ${_P} ${_i}) - elseif ("x${${_i}}" STREQUAL "x") - list(APPEND ${_A} ${_i}) - else() - list(APPEND ${_A} ${${_i}}) - endif() - endforeach() -endmacro() - - -macro(__qt_set_defines _NAME _T) - target_compile_definitions(${_T} PRIVATE "__TARGET_NAME__=\"${_NAME}\"") - target_compile_definitions(${_T} PRIVATE "__TARGET_LABEL__=\"${${_NAME}_LABEL}\"") - target_compile_definitions(${_T} PRIVATE "__TARGET_COMPANY__=\"${${_NAME}_COMPANY}\"") - target_compile_definitions(${_T} PRIVATE "__TARGET_VERSION__=\"${${_NAME}_VERSION}\"") -endmacro() - - -macro(qt_add_executable _NAME) - foreach(_v ${_QT_VERSIONS_}) - if (LOCAL_FOUND${_v}) - _qt_split_add_args(_PREF _ARGS ${ARGN}) - if(APPLE) - set(_PREV_CIND "${CMAKE_INSTALL_NAME_DIR}") - set(CMAKE_INSTALL_NAME_DIR "@rpath") - else() - if(NOT WIN32) - set(CMAKE_INSTALL_RPATH "\$ORIGIN;\$ORIGIN/lib") - endif() - endif() - set(_TARGET ${_NAME}${TARGET_SUFFIX_Qt${_v}}) - add_executable(${_TARGET} ${_PREF} ${_ARGS}) - set(_${_NAME}_is_qt 1) - target_include_directories(${_TARGET} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/qt${_v} ${Qt${_v}_INCLUDES}) - __qt_set_defines(${_NAME} ${_TARGET}) - - if(APPLE) - set(CMAKE_INSTALL_NAME_DIR "${_PREV_CIND}") - endif() - # # Apple crosscompiling rpath patch - # if (APPLE AND CMAKE_CROSSCOMPILING AND CMAKE_MACOSX_RPATH) - # foreach(_RP ${CMAKE_INSTALL_RPATH}) - # add_custom_command(TARGET ${_TARGET} POST_BUILD - # COMMAND "${CMAKE_INSTALL_NAME_TOOL}" - # "-add_rpath" "${_RP}" - # "$/$" - # COMMENT "Add to ${_TARGET} rpath \"${_RP}\"") - # endforeach() - # endif() - - #list(APPEND _ALL_TARGETS "${_TARGET}") - #set(_ALL_TARGETS ${_ALL_TARGETS} PARENT_SCOPE) - endif() - endforeach() -endmacro() - - -macro(qt_add_library _NAME) - foreach(_v ${_QT_VERSIONS_}) - if (LOCAL_FOUND${_v}) - _qt_split_add_args(_PREF _ARGS ${ARGN}) - if(APPLE) - set(_PREV_CIND "${CMAKE_INSTALL_NAME_DIR}") - set(CMAKE_INSTALL_NAME_DIR "@rpath") - else() - if(NOT WIN32) - set(CMAKE_INSTALL_RPATH "\$ORIGIN;\$ORIGIN/lib") - endif() - endif() - set(_TARGET ${_NAME}${TARGET_SUFFIX_Qt${_v}}) - add_library(${_TARGET} ${_PREF} ${_ARGS}) - set(_${_NAME}_is_qt 1) - target_include_directories(${_TARGET} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/qt${_v} ${Qt${_v}_INCLUDES}) - __qt_set_defines(${_NAME} ${_TARGET}) - #message("add lib: \"${_TARGET}\"") - - if(APPLE) - set(CMAKE_INSTALL_NAME_DIR "${_PREV_CIND}") - endif() - # # Apple crosscompiling rpath patch - # if (APPLE AND CMAKE_CROSSCOMPILING AND CMAKE_MACOSX_RPATH) - # foreach(_RP ${CMAKE_INSTALL_RPATH}) - # add_custom_command(TARGET ${_TARGET} POST_BUILD - # COMMAND "${CMAKE_INSTALL_NAME_TOOL}" - # "-add_rpath" "${_RP}" - # "$/$" - # COMMENT "Add to ${_TARGET} rpath \"${_RP}\"") - # endforeach() - # endif() - - list(APPEND _ALL_TARGETS "${_TARGET}") - set(_ALL_TARGETS ${_ALL_TARGETS} PARENT_SCOPE) - endif() - endforeach() -endmacro() - - -macro(_qt_multitarget_suffix_ _OUT _IN _v) - string(REPLACE ":" "_" _in_str "${_IN}") - if (NOT "x${MULTILIB_${_in_str}_SUFFIX_Qt${_v}}" STREQUAL "x") - set(${_OUT} "${MULTILIB_${_in_str}_SUFFIX_Qt${_v}}") - else() - set(${_OUT} "${MULTILIB_SUFFIX_Qt${_v}}") - endif() -endmacro() - - -macro(qt_target_link_libraries _NAME) - foreach(_v ${_QT_VERSIONS_}) - if (LOCAL_FOUND${_v}) - set(_TARGET ${_NAME}${TARGET_SUFFIX_Qt${_v}}) - set(_ARGS) - foreach(_i ${ARGN}) - set(_ind -1) - list(FIND QT_MULTILIB_LIST "${_i}" _ind) - if (_ind GREATER -1) - _qt_multitarget_suffix_(_TS ${_i} ${_v}) - #message(STATUS "${_i} in MULTILIB_LIST, suffix = ${_TS}") - list(APPEND _ARGS ${_i}${_TS}) - else() - list(APPEND _ARGS ${_i}) - endif() - endforeach() - target_link_libraries(${_TARGET} ${Qt${_v}_LIBRARIES} ${_ARGS}) - #message("link ${_TARGET}: ${Qt${_v}_LIBRARIES} ${_ARGS}") - endif() - endforeach() -endmacro() - - -macro(qt_target_compile_definitions _NAME) - foreach(_v ${_QT_VERSIONS_}) - if (LOCAL_FOUND${_v}) - set(_TARGET ${_NAME}${TARGET_SUFFIX_Qt${_v}}) - target_compile_definitions(${_TARGET} ${ARGN}) - endif() - endforeach() -endmacro() - - -macro(qt_target_include_directories _NAME) - foreach(_v ${_QT_VERSIONS_}) - if (LOCAL_FOUND${_v}) - set(_TARGET ${_NAME}${TARGET_SUFFIX_Qt${_v}}) - target_include_directories(${_TARGET} ${ARGN}) - endif() - endforeach() -endmacro() - - -macro(qt_install) - set(_prev_inst) - set(__add_args) - #message("command: ${ARGN}") - foreach(_v ${_QT_VERSIONS_}) - if (LOCAL_FOUND${_v}) - set(_INST_LIST) - set(_IS_TARGET 0) - set(_IS_FILES 0) - set(_IS_DEST 0) - set(_IS_LANG 0) - set(_INVALID 0) - foreach(_i ${ARGN}) - if ("x${_i}" STREQUAL "xQtLang") - set(_IS_LANG 1) - endif() - endforeach() - foreach(_i ${ARGN}) - if (_IS_TARGET) - set(_IS_TARGET 0) - set(__target ${_i}) - if (_${_i}_is_qt) - set(__target ${_i}${TARGET_SUFFIX_Qt${_v}}) - endif() - if (DEFINED ANDROID_PLATFORM) - get_target_property(_TT ${__target} TYPE) - if ("x${_TT}" STREQUAL "xEXECUTABLE") - list(APPEND __add_args EXCLUDE_FROM_ALL) - endif() - endif() - list(APPEND _INST_LIST ${__target}) - elseif (_IS_FILES) - set(_IS_FILES 0) - if (_IS_LANG) - if (("x${${_i}_Qt${_v}}" STREQUAL "x") OR ("x${_i}" STREQUAL "xDESTINATION")) - set(_INVALID 1) - else() - list(APPEND _INST_LIST ${${_i}_Qt${_v}}) - endif() - else() - list(APPEND _INST_LIST ${_i}) - endif() - else() - if (_IS_DEST) - set(_IS_DEST 0) - if ("x${_i}" STREQUAL "xQtBin") - list(APPEND _INST_LIST "${Qt${_v}_BIN}") - elseif ("x${_i}" STREQUAL "xQtLang") - list(APPEND _INST_LIST "${Qt${_v}_LANG_DIR}") - else() - set(_ind -1) - string(FIND "${_i}" "QtPlugins" _ind) - if (_ind GREATER -1) - string(REPLACE "QtPlugins" "${Qt${_v}_PLUGINS_DIR}" _o "${_i}") - list(APPEND _INST_LIST "${_o}") - else() - string(REPLACE "\\" "/" _o "${_i}") - list(APPEND _INST_LIST ${_o}) - endif() - endif() - else() - set(_ii ${_i}) - if ("x${_i}" STREQUAL "xTARGETS") - set(_IS_TARGET 1) - elseif ("x${_i}" STREQUAL "xFILES") - set(_IS_FILES 1) - elseif ("x${_i}" STREQUAL "xDESTINATION") - set(_IS_DEST 1) - elseif ("x${_i}" STREQUAL "xLANG") - set(_IS_FILES 1) - set(_IS_LANG 1) - set(_ii "FILES") - endif() - list(APPEND _INST_LIST ${_ii}) - endif() - endif() - endforeach() - if (NOT _INVALID) - if (NOT ("x${_prev_inst}" STREQUAL "x${_INST_LIST}")) - #message("install: ${_INST_LIST}") - install(${_INST_LIST} ${__add_args}) - set(_prev_inst "${_INST_LIST}") - endif() - endif() - endif() - endforeach() -endmacro() - - -macro(qt_install_lang _NAME) - set(_prev_inst) - #message("command: ${ARGN}") - set(_PATHS) - set(_DEST) - if(CMAKE_CROSSCOMPILING) - list(APPEND _PATHS "${CMAKE_PREFIX_PATH}/lang") - endif() - set(_cur_arg) - set(__args "DESTINATION;PATHS") - foreach(_i ${ARGN}) - if (_i IN_LIST __args) - set(_cur_arg "${_i}") - elseif("${_cur_arg}" STREQUAL "DESTINATION") - set(_DEST "${_i}") - elseif("${_cur_arg}" STREQUAL "PATHS") - list(APPEND _PATHS "${_i}") - endif() - endforeach() - foreach(_v ${_QT_VERSIONS_}) - if (LOCAL_FOUND${_v}) - set(_target) - if (_${_NAME}_is_qt) - set(_target ${_NAME}${TARGET_SUFFIX_Qt${_v}}) - endif() - get_target_property(_LL ${_target} LINK_LIBRARIES) - foreach (_L ${_LL}) - get_filename_component(_libname "${_L}" NAME_WE) - #message("depend on ${_libname}") - if ("${_libname}" MATCHES "Qt${_v}::.*") - string(SUBSTRING "${_libname}" 5 -1 _libname) - string(TOLOWER "${_libname}" _libname) - #message("qt lib \"${_libname}\"") - list(APPEND _qt_libs qt${_libname}) - else() - if ("${_libname}" MATCHES "lib.*") - string(LENGTH ${_libname} _sl) - math(EXPR _sl ${_sl}-3) - string(SUBSTRING ${_libname} 3 ${_sl} _libname) - endif() - if ("${_libname}" MATCHES "qad_.*${_v}") - string(LENGTH ${_libname} _sl) - math(EXPR _sl ${_sl}-1) - string(SUBSTRING ${_libname} 0 ${_sl} _libname) - #message("qad lib \"${_libname}\"") - list(APPEND _qt_libs ${_libname}) - endif() - endif() - endforeach() - if (NOT "x${_qt_libs}" STREQUAL "x") - list(APPEND _qt_libs "qtbase") - foreach (_i ${${PROJECT_NAME}_LANG}) - foreach (_l ${_qt_libs}) - unset(_qm_path CACHE) - find_file(_qm_path "${_l}_${_i}.qm" PATHS "${Qt${_v}_LANG_DIR}" ${_PATHS} NO_DEFAULT_PATH) - if (EXISTS "${_qm_path}") - install(FILES ${_qm_path} DESTINATION "${_DEST}") - #message("qm = \"${_qm_path}\"") - endif() - endforeach() - endforeach() - endif() - endif() - endforeach() -endmacro() - - -macro(qt_get_target _NAME _OUT) - set(${_OUT}) - set(_ver) - foreach(_i ${ARGN}) - foreach(_v ${_QT_VERSIONS_}) - if ("x${_i}" STREQUAL "xQt${_v}") - set(_ver ${_v}) - break() - endif() - endforeach() - if (NOT "x${_ver}" STREQUAL "x") - break() - endif() - endforeach() - foreach(_v ${_QT_VERSIONS_}) - if (LOCAL_FOUND${_v} AND (("x${_ver}" STREQUAL "x") OR ((NOT "x${_ver}" STREQUAL "x") AND ("x${_ver}" STREQUAL "x${_v}")))) - set(${_OUT} ${_NAME}${TARGET_SUFFIX_Qt${_v}}) - endif() - endforeach() -endmacro() - - -macro(qt_get_targets _NAME _OUT) - set(${_OUT}) - foreach(_v ${_QT_VERSIONS_}) - if (LOCAL_FOUND${_v}) - list(APPEND ${_OUT} ${_NAME}${TARGET_SUFFIX_Qt${_v}}) - endif() - endforeach() -endmacro() +#[[ + +find_qt([ ...] [Qt4] [Qt5]) + +Find Qt4 or/and Qt5 packages +If Qt4/5 found, set +* Qt<4/5>_ROOT var to Qt root dir +* Qt<4/5>_BIN var to Qt binary dir +* Qt<4/5>_PLUGINS_DIR var to Qt plugins dir +* Qt<4/5>_LANG_DIR var to Qt translations dir + + + + +qt_sources( [NO_DEFAULT] [DIR ] [ ...]) + +Collect all sources, optionally in directory and +Additional filters . By default filter files with regexps +"*.h", "*.hpp", "*.c", "*.cpp", "*.ui", "*.qrc", "*.rc", "*.ts" and "lang/*.ts". +Default filters disabled with option NO_DEFAULT + + + + +qt_wrap( ... [HDRS ] [CPPS ] [QMS ]) + +Prepare sources for compile +Store headers to , all wrapped Qt4 files to _Qt4 and Qt5 files to _Qt5 +version are automatic detected after find_qt() call + + + + +qt_add_executable( [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] source1 [source2 ...]) + +Add executables for founded Qt versions, target names is +All needed Qt includes automatic added to corresponding targets + cant be CPPS variable passed to qt_wrap() or some list or filename + + + + +qt_add_library( [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] source1 [source2 ...]) + +Add library for founded Qt versions, target names is +All needed Qt includes automatic added to corresponding targets + cant be CPPS variable passed to qt_wrap() or some list or filename + + + + +qt_target_link_libraries( ... ...) + +Link targets for founded Qt versions, target names is +All needed Qt libraries automatic added to corresponding targets +if QT_MULTILIB_LIST contains some linking library, to it name automatic +add or individual libname<_SUFFIX_Qt?> + + + + +qt_target_compile_definitions( ...) + +Syntax similar to original "target_compile_definitions()" +Specify compile definitions to use when compiling a given + + + + +qt_target_include_directories( ...) + +Syntax similar to original "target_include_directories()" +Add include directories to a target + + + + +qt_install(...) + +Syntax similar to original "install()" +Install targets for founded Qt versions + +if DESTINATION set to "QtBin" files will be installed +to corresponding Qt binary directory +if DESTINATION set to "QtLang" files will be installed +to corresponding Qt translation directory +if DESTINATION starts with "QtPlugins" files will be installed +to corresponding Qt plugins directory + +Add LANG type for first argument - in this case you should +specify variable name, not variable value! +e.g. "qt_install(LANG my_QM DESTINATION QtLang)" + + + + +qt_install_lang( DESTINATION [PATHS [] [...] ]) + +Search Qt translations for all dependencies +in Qt_LANG_DIR for _LANG languages +and install them to . PATH are additional search paths. +You should use "set_lang()" macro before this action + + + + +qt_get_target( [Qt4 | Qt5]) + +Write real Qt target name to +If Qt4 or Qt5 specified, search for this version, +otherwise returns greatest version + + + + +qt_get_targets( ) + +Write all real Qt target names to + + + + +qt_generate_export_header( ...) + +Call generate_export_header on Qt multitarget + + +]] + + +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 (POLICY CMP0057) + cmake_policy(SET CMP0057 NEW) # Support if() IN_LIST +endif() +if (POLICY CMP0074) + cmake_policy(SET CMP0074 OLD) # ignore _ROOT variables +endif() +set(__qt_bug_modules "UiTools") + + +set(_QT_VERSIONS_ 4 5) +foreach(_v ${_QT_VERSIONS_}) + if (NOT DEFINED TARGET_SUFFIX_Qt${_v}) + set(TARGET_SUFFIX_Qt${_v} "${_v}") + set(MULTILIB_SUFFIX_Qt${_v} "${_v}") + endif() + set(MOC_INC_Qt${_v}) +endforeach() +if (NOT DEFINED QT_MULTILIB_LIST) + set(QT_MULTILIB_LIST) +endif() +#set(TARGET_SUFFIX_Qt4 "") + + +macro(find_qt) + set(_QCOMP) + foreach(_v ${_QT_VERSIONS_}) + set(_NEED${_v} 0) + set(LOCAL_FOUND${_v} 0) + set(MOC_INC_Qt${_v}) + set(Qt${_v}_INCLUDES) + set(Qt${_v}_LIBRARIES) + set(Qt${_v}_ROOT) + set(Qt${_v}_BIN) + set(Qt${_v}_PLUGINS_DIR) + set(Qt${_v}_LANG_DIR) + endforeach() + set(_NEED_SOME 0) + set(_QUIET) + foreach(_i ${ARGN}) + set(_FOUND_NEED 0) + foreach(_v ${_QT_VERSIONS_}) + if ("x${_i}" STREQUAL "xQt${_v}") + set(_NEED${_v} 1) + set(_NEED_SOME 1) + set(_FOUND_NEED 1) + endif() + if ("x${_i}" STREQUAL "xQUIET") + set(_QUIET QUIET) + endif() + endforeach() + if (NOT _FOUND_NEED) + list(APPEND _QCOMP "${_i}") + endif() + endforeach() + if (NOT _NEED_SOME) + foreach(_v ${_QT_VERSIONS_}) + set(_NEED${_v} 1) + endforeach() + endif() + list(REMOVE_DUPLICATES _QCOMP) + if (_NEED4) + find_package(Qt4 ${_QUIET}) + if (Qt4_FOUND) + set(LOCAL_FOUND4 1) + get_filename_component(Qt4_BIN ${QT_QMAKE_EXECUTABLE} PATH) + set(Qt4_INCLUDES ${QT_INCLUDES}) + foreach(m ${_QCOMP}) + string(TOUPPER "${m}" _um) + #message("${QT_QT${_um}_FOUND}") + if (${QT_QT${_um}_FOUND}) + list(APPEND Qt4_LIBRARIES ${QT_QT${_um}_LIBRARY}) + endif() + endforeach() + set(Qt4_PLUGINS_DIR ${QT_PLUGINS_DIR}) + set(Qt4_LANG_DIR ${Qt4_BIN}/../translations) + set(Qt4_ROOT "${Qt4_BIN}/../") + endif() + endif() + if (_NEED5) + #set(_MSG 1) + #if (Qt5_FOUND) + # set(_MSG 0) + #endif() + find_package(Qt5 COMPONENTS Core LinguistTools UiPlugin Widgets ${_QCOMP} ${_QUIET}) + if (DEFINED ANDROID_PLATFORM) + set(CMAKE_SHARED_MODULE_SUFFIX_CXX ".so") + set(CMAKE_SHARED_LIBRARY_SUFFIX_CXX ".so") + set(CMAKE_SHARED_MODULE_SUFFIX_C ".so") + set(CMAKE_SHARED_LIBRARY_SUFFIX_C ".so") + endif() + if (Qt5_FOUND) + set(LOCAL_FOUND5 1) + set(_Qt5Modules) + foreach(m ${_QCOMP}) + if (${Qt5${m}_FOUND}) + set(__lib ${Qt5${m}_LIBRARIES}) + if (DEFINED ANDROID_PLATFORM) + if (m IN_LIST __qt_bug_modules) + get_target_property(__lib Qt5::${m} LOCATION) + endif() + endif() + list(APPEND _Qt5Modules ${m}) + list(APPEND Qt5_INCLUDES ${Qt5${m}_INCLUDE_DIRS}) + list(APPEND Qt5_LIBRARIES ${__lib}) + endif() + endforeach() + #get_property(_up_dir TARGET Qt5::UiPlugin PROPERTY INTERFACE_INCLUDE_DIRECTORIES) + #message("${_up_dir}") + #if (NOT "x${_up_dir}" STREQUAL "x") + # list(APPEND Qt5_INCLUDES ${_up_dir}) + #endif() + get_target_property(_Qt5_qmake Qt5::qmake LOCATION) + get_filename_component(Qt5_BIN ${_Qt5_qmake} PATH) + foreach(_p ${Qt5Gui_PLUGINS}) + get_target_property(_l ${_p} LOCATION) + get_filename_component(_l ${_l} DIRECTORY) + string(FIND "${_l}" "/" _ind REVERSE) + string(SUBSTRING "${_l}" 0 ${_ind} _l) + set(Qt5_PLUGINS_DIR ${_l}) + #message("Qt5: plugins dir: ${Qt5_PLUGINS_DIR}") + break() + endforeach() + string(FIND "${Qt5_BIN}" "/" _ind REVERSE) + string(SUBSTRING "${Qt5_BIN}" 0 ${_ind} Qt5_ROOT) + if ("x${Qt5_PLUGINS_DIR}" STREQUAL "x") + set(Qt5_PLUGINS_DIR "${Qt5_ROOT}/plugins") + endif() + if (APPLE) + list(APPEND MOC_INC_Qt5 "-F${Qt5_ROOT}/lib") + endif() + set(Qt5_LANG_DIR ${Qt5_BIN}/../translations) + if (NOT _QT5_MSG) + message(STATUS "Found Qt5: ${_Qt5_qmake} (version \"${Qt5_VERSION}\")") + set(_QT5_MSG 1 CACHE BOOL "msg_qt5" FORCE) + #message(STATUS "Found Qt5 modules: ${_Qt5Modules}") + endif() + endif() + endif() + foreach(_v ${_QT_VERSIONS_}) + if (LOCAL_FOUND${_v}) + foreach(_p ${Qt${_v}_INCLUDES}) + list(APPEND MOC_INC_Qt${_v} "-I${_p}") + #message("${_p}") + endforeach() + endif() + #message("${MOC_INC_Qt${_v}}") + endforeach() + +endmacro() + + +macro(qt_sources OUT) + set(${OUT}) + set(_DIR "") + set(_IS_DIR 0) + set(_NO_DEFAULT 0) + set(_DEFAULT) + set(_REGEXP) + set(_REGEXP_WD) + foreach(_i ${ARGN}) + if (_IS_DIR) + set(_DIR "${_i}") + set(_IS_DIR 0) + elseif ("x${_i}" STREQUAL "xDIR") + set(_IS_DIR 1) + elseif ("x${_i}" STREQUAL "xNO_DEFAULT") + set(_NO_DEFAULT 1) + else() + list(APPEND _REGEXP ${_i}) + endif() + endforeach() + if (NOT "x${_DIR}" STREQUAL "x") + #file(TO_CMAKE_PATH "${_DIR}//" _DIR) + string(REPLACE "\\" "/" _DIR "${_DIR}/") + string(REPLACE "//" "/" _DIR "${_DIR}") + endif() + foreach(_i ${_REGEXP}) + list(APPEND _REGEXP_WD "${_DIR}${_i}") + endforeach() + if (NOT _NO_DEFAULT) + set(_DEFAULT "${_DIR}*.h" "${_DIR}*.hpp" "${_DIR}*.c" "${_DIR}*.cpp" "${_DIR}*.ui" "${_DIR}*.qrc" "${_DIR}*.rc" "${_DIR}*.ts" "${_DIR}lang/*.ts") + endif() + #message("${_DEFAULT}, ${_REGEXP_WD}") + file(GLOB ${OUT} ${_DEFAULT} ${_REGEXP_WD}) +endmacro() + + +macro(qt_wrap) + set(HDR_VAR) + set(CPP_VAR) + set(QM_VAR) + set(_HDR_ARG 0) + set(_CPP_ARG 0) + set(_QM_ARG 0) + set(WAS_HDR_ARG 0) + set(WAS_CPP_ARG 0) + set(WAS_QM_ARG 0) + set(FILE_LIST) + foreach(_i ${ARGN}) + if (_HDR_ARG) + set(HDR_VAR ${_i}) + set(WAS_HDR_ARG 1) + set(_HDR_ARG 0) + elseif (_CPP_ARG) + set(CPP_VAR ${_i}) + set(WAS_CPP_ARG 1) + set(_CPP_ARG 0) + elseif (_QM_ARG) + set(QM_VAR ${_i}) + set(WAS_QM_ARG 1) + set(_QM_ARG 0) + elseif ("x${_i}" STREQUAL "xHDRS") + set(_HDR_ARG 1) + elseif ("x${_i}" STREQUAL "xCPPS") + set(_CPP_ARG 1) + elseif ("x${_i}" STREQUAL "xQMS") + set(_QM_ARG 1) + else() + list(APPEND FILE_LIST "${_i}") + endif() + endforeach() + foreach(_v ${_QT_VERSIONS_}) + set(CPP${_v}_VAR) + set(QM${_v}_VAR) + if (LOCAL_FOUND${_v}) + if (WAS_CPP_ARG) + set(CPP${_v}_VAR ${CPP_VAR}_Qt${_v}) + endif() + if (WAS_QM_ARG) + set(QM${_v}_VAR ${QM_VAR}_Qt${_v}) + endif() + endif() + endforeach() + #message("found 4: ${LOCAL_FOUND4}, 5: ${LOCAL_FOUND5}") + #message("has HRDS: ${WAS_HDR_ARG}: ${HDR_VAR}") + #message("has CPPS4: ${WAS_CPP_ARG}: ${CPP4_VAR}") + #message("has CPPS5: ${WAS_CPP_ARG}: ${CPP5_VAR}") + #message("files: ${FILE_LIST}") + set(H_LIST) + set(CPP_LIST) + set(UI_LIST) + set(RES_LIST) + set(RC_LIST) + set(TS_LIST) + foreach(_i ${FILE_LIST}) + get_filename_component(_EXT "${_i}" EXT) + #message("${_EXT}") + if (NOT ("x${_EXT}" STREQUAL "x")) + if (("x${_EXT}" STREQUAL "x.h") OR ("x${_EXT}" STREQUAL "x.hpp")) + list(APPEND H_LIST "${_i}") + #message("header") + endif() + if (("x${_EXT}" STREQUAL "x.c") OR ("x${_EXT}" STREQUAL "x.cpp") OR ("x${_EXT}" STREQUAL "x.cxx")) + list(APPEND CPP_LIST "${_i}") + #message("source") + endif() + if ("x${_EXT}" STREQUAL "x.ui") + list(APPEND UI_LIST "${_i}") + endif() + if ("x${_EXT}" STREQUAL "x.qrc") + list(APPEND RES_LIST "${_i}") + endif() + if ("x${_EXT}" STREQUAL "x.rc") + list(APPEND RC_LIST "${_i}") + endif() + if ("x${_EXT}" STREQUAL "x.ts") + list(APPEND TS_LIST "${_i}") + endif() + endif() + endforeach() + if (WAS_HDR_ARG) + set(${HDR_VAR}) + list(APPEND ${HDR_VAR} ${H_LIST}) + endif() + set(SRC_CMAKE_CURRENT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) + foreach(_v ${_QT_VERSIONS_}) + if (LOCAL_FOUND${_v} AND WAS_CPP_ARG) + set(CMAKE_CURRENT_BINARY_DIR ${SRC_CMAKE_CURRENT_BINARY_DIR}/qt${_v}) + set(${CPP${_v}_VAR}) + if (WAS_QM_ARG) + set(${QM${_v}_VAR}) + endif() + set(MOCS${_v}) + set(CUIS${_v}) + set(CRES${_v}) + if (${_v} EQUAL 4) + qt4_wrap_cpp(MOCS${_v} ${H_LIST} OPTIONS -nw ${MOC_INC_Qt4}) + qt4_wrap_ui(CUIS${_v} ${UI_LIST}) + qt4_add_resources(CRES${_v} ${RES_LIST}) + if (WAS_QM_ARG) + set(${QM${_v}_VAR} "") + qt4_add_translation(${QM${_v}_VAR} ${TS_LIST}) + endif() + elseif (${_v} EQUAL 5) + qt5_wrap_cpp(MOCS${_v} ${H_LIST} OPTIONS -nw ${MOC_INC_Qt5}) + qt5_wrap_ui(CUIS${_v} ${UI_LIST}) + qt5_add_resources(CRES${_v} ${RES_LIST}) + if (WAS_QM_ARG) + set(${QM${_v}_VAR} "") + qt5_add_translation(${QM${_v}_VAR} ${TS_LIST}) + endif() + else() + # Qt6 ... + endif() + #message("${${QM${_v}_VAR}}") + list(APPEND ${CPP${_v}_VAR} ${CPP_LIST}) + list(APPEND ${CPP${_v}_VAR} ${RC_LIST}) + list(APPEND ${CPP${_v}_VAR} ${MOCS${_v}}) + list(APPEND ${CPP${_v}_VAR} ${CUIS${_v}}) + list(APPEND ${CPP${_v}_VAR} ${CRES${_v}}) + if (WAS_QM_ARG) + list(APPEND ${CPP${_v}_VAR} ${${QM${_v}_VAR}}) + endif() + #message("${${QM${_v}_VAR}}") + endif() + endforeach() + set(CMAKE_CURRENT_BINARY_DIR ${SRC_CMAKE_CURRENT_BINARY_DIR}) +endmacro() + + +macro(_qt_split_add_args _P _A) + set(${_P}) + set(${_A}) + foreach(_i ${ARGN}) + if (NOT ("x${${_i}_Qt${_v}}" STREQUAL "x")) + list(APPEND ${_A} ${${_i}_Qt${_v}}) + elseif (("x${_i}" STREQUAL "xWIN32") OR + ("x${_i}" STREQUAL "xMACOSX_BUNDLE") OR + ("x${_i}" STREQUAL "xSTATIC") OR + ("x${_i}" STREQUAL "xSHARED") OR + ("x${_i}" STREQUAL "xMODULE") OR + ("x${_i}" STREQUAL "xEXCLUDE_FROM_ALL")) + list(APPEND ${_P} ${_i}) + elseif ("x${${_i}}" STREQUAL "x") + list(APPEND ${_A} ${_i}) + else() + list(APPEND ${_A} ${${_i}}) + endif() + endforeach() +endmacro() + + +macro(__qt_set_defines _NAME _T) + target_compile_definitions(${_T} PRIVATE "__TARGET_NAME__=\"${_NAME}\"") + target_compile_definitions(${_T} PRIVATE "__TARGET_LABEL__=\"${${_NAME}_LABEL}\"") + target_compile_definitions(${_T} PRIVATE "__TARGET_COMPANY__=\"${${_NAME}_COMPANY}\"") + target_compile_definitions(${_T} PRIVATE "__TARGET_VERSION__=\"${${_NAME}_VERSION}\"") +endmacro() + + +macro(qt_add_executable _NAME) + foreach(_v ${_QT_VERSIONS_}) + if (LOCAL_FOUND${_v}) + _qt_split_add_args(_PREF _ARGS ${ARGN}) + if(APPLE) + set(_PREV_CIND "${CMAKE_INSTALL_NAME_DIR}") + set(CMAKE_INSTALL_NAME_DIR "@rpath") + else() + if(NOT WIN32) + set(CMAKE_INSTALL_RPATH "\$ORIGIN;\$ORIGIN/lib") + endif() + endif() + set(_TARGET ${_NAME}${TARGET_SUFFIX_Qt${_v}}) + add_executable(${_TARGET} ${_PREF} ${_ARGS}) + set(_${_NAME}_is_qt 1) + target_include_directories(${_TARGET} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/qt${_v} ${Qt${_v}_INCLUDES}) + __qt_set_defines(${_NAME} ${_TARGET}) + + if(APPLE) + set(CMAKE_INSTALL_NAME_DIR "${_PREV_CIND}") + endif() + # # Apple crosscompiling rpath patch + # if (APPLE AND CMAKE_CROSSCOMPILING AND CMAKE_MACOSX_RPATH) + # foreach(_RP ${CMAKE_INSTALL_RPATH}) + # add_custom_command(TARGET ${_TARGET} POST_BUILD + # COMMAND "${CMAKE_INSTALL_NAME_TOOL}" + # "-add_rpath" "${_RP}" + # "$/$" + # COMMENT "Add to ${_TARGET} rpath \"${_RP}\"") + # endforeach() + # endif() + + #list(APPEND _ALL_TARGETS "${_TARGET}") + #set(_ALL_TARGETS ${_ALL_TARGETS} PARENT_SCOPE) + endif() + endforeach() +endmacro() + + +macro(qt_add_library _NAME) + foreach(_v ${_QT_VERSIONS_}) + if (LOCAL_FOUND${_v}) + _qt_split_add_args(_PREF _ARGS ${ARGN}) + if(APPLE) + set(_PREV_CIND "${CMAKE_INSTALL_NAME_DIR}") + set(CMAKE_INSTALL_NAME_DIR "@rpath") + else() + if(NOT WIN32) + set(CMAKE_INSTALL_RPATH "\$ORIGIN;\$ORIGIN/lib") + endif() + endif() + set(_TARGET ${_NAME}${TARGET_SUFFIX_Qt${_v}}) + add_library(${_TARGET} ${_PREF} ${_ARGS}) + set(_${_NAME}_is_qt 1) + target_include_directories(${_TARGET} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/qt${_v} ${Qt${_v}_INCLUDES}) + __qt_set_defines(${_NAME} ${_TARGET}) + #message("add lib: \"${_TARGET}\"") + + if(APPLE) + set(CMAKE_INSTALL_NAME_DIR "${_PREV_CIND}") + endif() + # # Apple crosscompiling rpath patch + # if (APPLE AND CMAKE_CROSSCOMPILING AND CMAKE_MACOSX_RPATH) + # foreach(_RP ${CMAKE_INSTALL_RPATH}) + # add_custom_command(TARGET ${_TARGET} POST_BUILD + # COMMAND "${CMAKE_INSTALL_NAME_TOOL}" + # "-add_rpath" "${_RP}" + # "$/$" + # COMMENT "Add to ${_TARGET} rpath \"${_RP}\"") + # endforeach() + # endif() + + list(APPEND _ALL_TARGETS "${_TARGET}") + set(_ALL_TARGETS ${_ALL_TARGETS} PARENT_SCOPE) + endif() + endforeach() +endmacro() + + +macro(_qt_multitarget_suffix_ _OUT _IN _v) + string(REPLACE ":" "_" _in_str "${_IN}") + if (NOT "x${MULTILIB_${_in_str}_SUFFIX_Qt${_v}}" STREQUAL "x") + set(${_OUT} "${MULTILIB_${_in_str}_SUFFIX_Qt${_v}}") + else() + set(${_OUT} "${MULTILIB_SUFFIX_Qt${_v}}") + endif() +endmacro() + + +macro(qt_target_link_libraries _NAME) + foreach(_v ${_QT_VERSIONS_}) + if (LOCAL_FOUND${_v}) + set(_TARGET ${_NAME}${TARGET_SUFFIX_Qt${_v}}) + set(_ARGS) + foreach(_i ${ARGN}) + set(_ind -1) + list(FIND QT_MULTILIB_LIST "${_i}" _ind) + if (_ind GREATER -1) + _qt_multitarget_suffix_(_TS ${_i} ${_v}) + #message(STATUS "${_i} in MULTILIB_LIST, suffix = ${_TS}") + list(APPEND _ARGS ${_i}${_TS}) + else() + list(APPEND _ARGS ${_i}) + endif() + endforeach() + target_link_libraries(${_TARGET} ${Qt${_v}_LIBRARIES} ${_ARGS}) + #message("link ${_TARGET}: ${Qt${_v}_LIBRARIES} ${_ARGS}") + endif() + endforeach() +endmacro() + + +macro(qt_target_compile_definitions _NAME) + foreach(_v ${_QT_VERSIONS_}) + if (LOCAL_FOUND${_v}) + set(_TARGET ${_NAME}${TARGET_SUFFIX_Qt${_v}}) + target_compile_definitions(${_TARGET} ${ARGN}) + endif() + endforeach() +endmacro() + + +macro(qt_target_include_directories _NAME) + foreach(_v ${_QT_VERSIONS_}) + if (LOCAL_FOUND${_v}) + set(_TARGET ${_NAME}${TARGET_SUFFIX_Qt${_v}}) + target_include_directories(${_TARGET} ${ARGN}) + endif() + endforeach() +endmacro() + + +macro(qt_install) + set(_prev_inst) + set(__add_args) + #message("command: ${ARGN}") + foreach(_v ${_QT_VERSIONS_}) + if (LOCAL_FOUND${_v}) + set(_INST_LIST) + set(_IS_TARGET 0) + set(_IS_FILES 0) + set(_IS_DEST 0) + set(_IS_LANG 0) + set(_INVALID 0) + foreach(_i ${ARGN}) + if ("x${_i}" STREQUAL "xQtLang") + set(_IS_LANG 1) + endif() + endforeach() + foreach(_i ${ARGN}) + if (_IS_TARGET) + set(_IS_TARGET 0) + set(__target ${_i}) + if (_${_i}_is_qt) + set(__target ${_i}${TARGET_SUFFIX_Qt${_v}}) + endif() + if (DEFINED ANDROID_PLATFORM) + get_target_property(_TT ${__target} TYPE) + if ("x${_TT}" STREQUAL "xEXECUTABLE") + list(APPEND __add_args EXCLUDE_FROM_ALL) + endif() + endif() + list(APPEND _INST_LIST ${__target}) + elseif (_IS_FILES) + set(_IS_FILES 0) + if (_IS_LANG) + if (("x${${_i}_Qt${_v}}" STREQUAL "x") OR ("x${_i}" STREQUAL "xDESTINATION")) + set(_INVALID 1) + else() + list(APPEND _INST_LIST ${${_i}_Qt${_v}}) + endif() + else() + list(APPEND _INST_LIST ${_i}) + endif() + else() + if (_IS_DEST) + set(_IS_DEST 0) + if ("x${_i}" STREQUAL "xQtBin") + list(APPEND _INST_LIST "${Qt${_v}_BIN}") + elseif ("x${_i}" STREQUAL "xQtLang") + list(APPEND _INST_LIST "${Qt${_v}_LANG_DIR}") + else() + set(_ind -1) + string(FIND "${_i}" "QtPlugins" _ind) + if (_ind GREATER -1) + string(REPLACE "QtPlugins" "${Qt${_v}_PLUGINS_DIR}" _o "${_i}") + list(APPEND _INST_LIST "${_o}") + else() + string(REPLACE "\\" "/" _o "${_i}") + list(APPEND _INST_LIST ${_o}) + endif() + endif() + else() + set(_ii ${_i}) + if ("x${_i}" STREQUAL "xTARGETS") + set(_IS_TARGET 1) + elseif ("x${_i}" STREQUAL "xFILES") + set(_IS_FILES 1) + elseif ("x${_i}" STREQUAL "xDESTINATION") + set(_IS_DEST 1) + elseif ("x${_i}" STREQUAL "xLANG") + set(_IS_FILES 1) + set(_IS_LANG 1) + set(_ii "FILES") + endif() + list(APPEND _INST_LIST ${_ii}) + endif() + endif() + endforeach() + if (NOT _INVALID) + if (NOT ("x${_prev_inst}" STREQUAL "x${_INST_LIST}")) + #message("install: ${_INST_LIST}") + install(${_INST_LIST} ${__add_args}) + set(_prev_inst "${_INST_LIST}") + endif() + endif() + endif() + endforeach() +endmacro() + + +macro(qt_install_lang _NAME) + set(_prev_inst) + #message("command: ${ARGN}") + set(_PATHS) + set(_DEST) + if(CMAKE_CROSSCOMPILING) + list(APPEND _PATHS "${CMAKE_PREFIX_PATH}/lang") + endif() + set(_cur_arg) + set(__args "DESTINATION;PATHS") + foreach(_i ${ARGN}) + if (_i IN_LIST __args) + set(_cur_arg "${_i}") + elseif("${_cur_arg}" STREQUAL "DESTINATION") + set(_DEST "${_i}") + elseif("${_cur_arg}" STREQUAL "PATHS") + list(APPEND _PATHS "${_i}") + endif() + endforeach() + foreach(_v ${_QT_VERSIONS_}) + if (LOCAL_FOUND${_v}) + set(_target) + if (_${_NAME}_is_qt) + set(_target ${_NAME}${TARGET_SUFFIX_Qt${_v}}) + endif() + get_target_property(_LL ${_target} LINK_LIBRARIES) + foreach (_L ${_LL}) + get_filename_component(_libname "${_L}" NAME_WE) + #message("depend on ${_libname}") + if ("${_libname}" MATCHES "Qt${_v}::.*") + string(SUBSTRING "${_libname}" 5 -1 _libname) + string(TOLOWER "${_libname}" _libname) + #message("qt lib \"${_libname}\"") + list(APPEND _qt_libs qt${_libname}) + else() + if ("${_libname}" MATCHES "lib.*") + string(LENGTH ${_libname} _sl) + math(EXPR _sl ${_sl}-3) + string(SUBSTRING ${_libname} 3 ${_sl} _libname) + endif() + if ("${_libname}" MATCHES "qad_.*${_v}") + string(LENGTH ${_libname} _sl) + math(EXPR _sl ${_sl}-1) + string(SUBSTRING ${_libname} 0 ${_sl} _libname) + #message("qad lib \"${_libname}\"") + list(APPEND _qt_libs ${_libname}) + endif() + endif() + endforeach() + if (NOT "x${_qt_libs}" STREQUAL "x") + list(APPEND _qt_libs "qtbase") + foreach (_i ${${PROJECT_NAME}_LANG}) + foreach (_l ${_qt_libs}) + unset(_qm_path CACHE) + find_file(_qm_path "${_l}_${_i}.qm" PATHS "${Qt${_v}_LANG_DIR}" ${_PATHS} NO_DEFAULT_PATH) + if (EXISTS "${_qm_path}") + install(FILES ${_qm_path} DESTINATION "${_DEST}") + #message("qm = \"${_qm_path}\"") + endif() + endforeach() + endforeach() + endif() + endif() + endforeach() +endmacro() + + +macro(qt_get_target _NAME _OUT) + set(${_OUT}) + set(_ver) + foreach(_i ${ARGN}) + foreach(_v ${_QT_VERSIONS_}) + if ("x${_i}" STREQUAL "xQt${_v}") + set(_ver ${_v}) + break() + endif() + endforeach() + if (NOT "x${_ver}" STREQUAL "x") + break() + endif() + endforeach() + foreach(_v ${_QT_VERSIONS_}) + if (LOCAL_FOUND${_v} AND (("x${_ver}" STREQUAL "x") OR ((NOT "x${_ver}" STREQUAL "x") AND ("x${_ver}" STREQUAL "x${_v}")))) + set(${_OUT} ${_NAME}${TARGET_SUFFIX_Qt${_v}}) + endif() + endforeach() +endmacro() + + +macro(qt_get_targets _NAME _OUT) + set(${_OUT}) + foreach(_v ${_QT_VERSIONS_}) + if (LOCAL_FOUND${_v}) + list(APPEND ${_OUT} ${_NAME}${TARGET_SUFFIX_Qt${_v}}) + endif() + endforeach() +endmacro() + + +macro(qt_generate_export_header _NAME) + qt_get_target(${_NAME} _some_target) + qt_get_target(${_NAME} _targets) + foreach(_t ${_targets}) + set_target_properties(${_t} PROPERTIES DEFINE_SYMBOL ${_NAME}_EXPORTS) + endforeach() + set_target_properties(${_some_target} PROPERTIES DEFINE_SYMBOL ${_NAME}_EXPORTS) + generate_export_header(${_some_target} BASE_NAME "${_NAME}" ${ARGN}) +endmacro() diff --git a/qad/libs/application/aboutwindow.ui b/qad/libs/application/aboutwindow.ui index b6a1606..8c6fb0d 100644 --- a/qad/libs/application/aboutwindow.ui +++ b/qad/libs/application/aboutwindow.ui @@ -114,7 +114,7 @@ OK - + :/icons/dialog-ok-apply.png:/icons/dialog-ok-apply.png @@ -131,7 +131,6 @@ - diff --git a/qad/libs/application/qad_application.qrc b/qad/libs/application/qad_application.qrc index ad3f2fd..a9ad1dc 100644 --- a/qad/libs/application/qad_application.qrc +++ b/qad/libs/application/qad_application.qrc @@ -1,34 +1,17 @@ - ../../icons/application-exit.png - ../../icons/dialog-close.png + ../../icons/dialog-ok-apply.png ../../icons/configure.png - ../../icons/document-edit.png - ../../icons/document-new.png - ../../icons/document-save.png - ../../icons/document-save-all.png - ../../icons/document-save-as.png - ../../icons/document-open.png - ../../icons/document-open-recent.png - ../../icons/document-close.png ../../icons/edit-clear.png - ../../icons/edit-clear-locationbar-rtl.png ../../icons/edit-find.png - ../../icons/list-add.png - ../../icons/edit-delete.png ../../icons/edit-copy.png - ../../icons/edit-paste.png - ../../icons/edit-undo.png - ../../icons/edit-redo.png - ../../icons/border-line.png ../../icons/edockwidget.png ../../icons/historyview.png + ../../icons/logview.png ../../icons/clear-history.png ../../icons/layer-visible-off.png ../../icons/layer-visible-on.png - ../../icons/logview.png ../../icons/qt.png ../../icons/select-all.png - ../../icons/select-none.png diff --git a/qad/libs/blockview/blockeditor.ui b/qad/libs/blockview/blockeditor.ui index 81e4169..0d9dad6 100644 --- a/qad/libs/blockview/blockeditor.ui +++ b/qad/libs/blockview/blockeditor.ui @@ -194,7 +194,7 @@ Add - + :/icons/list-add.png:/icons/list-add.png @@ -205,7 +205,7 @@ Clone - + :/icons/edit-copy.png:/icons/edit-copy.png @@ -232,7 +232,7 @@ Remove selected - + :/icons/edit-delete.png:/icons/edit-delete.png @@ -243,7 +243,7 @@ Remove all - + :/icons/edit-clear.png:/icons/edit-clear.png @@ -346,7 +346,7 @@ Save - + :/icons/document-save.png:/icons/document-save.png @@ -376,7 +376,7 @@ Save as ... - + :/icons/document-save.png:/icons/document-save.png @@ -406,7 +406,7 @@ Load ... - + :/icons/document-open.png:/icons/document-open.png @@ -433,7 +433,7 @@ Clear - + :/icons/edit-clear.png:/icons/edit-clear.png @@ -443,7 +443,7 @@ - + :/icons/edit-delete.png:/icons/edit-delete.png @@ -467,8 +467,6 @@ - - diff --git a/qad/libs/blockview/drawtools.ui b/qad/libs/blockview/drawtools.ui index 849f997..1977dcb 100644 --- a/qad/libs/blockview/drawtools.ui +++ b/qad/libs/blockview/drawtools.ui @@ -94,7 +94,7 @@ Edit text ... - + :/icons/document-edit.png:/icons/document-edit.png @@ -591,7 +591,7 @@ Load image ... - + :/icons/document-open.png:/icons/document-open.png @@ -814,7 +814,6 @@ - diff --git a/qad/libs/blockview/qad_blockview.qrc b/qad/libs/blockview/qad_blockview.qrc index fd87c3d..155b00d 100644 --- a/qad/libs/blockview/qad_blockview.qrc +++ b/qad/libs/blockview/qad_blockview.qrc @@ -1,39 +1,16 @@ - ../../icons/draw-line.png - ../../icons/align-hor.png - ../../icons/align-ver.png - ../../icons/dialog-close.png - ../../icons/edit-clear.png - ../../icons/edit-guides.png - ../../icons/view-grid.png - ../../icons/zoom-fit-best.png - ../../icons/configure.png - ../../icons/document-save.png - ../../icons/edit-clear-locationbar-rtl.png - ../../icons/edit-find.png - ../../icons/list-add.png - ../../icons/edit-delete.png - ../../icons/item.png - ../../icons/node-add.png - ../../icons/node.png - ../../icons/edit-copy.png - ../../icons/edit-paste.png - ../../icons/expand_s_x.png - ../../icons/expand_s_y.png - ../../icons/expand_x.png - ../../icons/expand_y.png - ../../icons/border-line.png - ../../icons/legend.png ../../icons/blockview.png - ../../icons/view-fullscreen.png + ../../icons/draw-line.png ../../icons/draw-ellipse.png ../../icons/draw-rectangle.png ../../icons/draw-text.png - ../../icons/view-preview.png - ../../icons/format-fill-color.png - ../../icons/format-stroke-color.png - ../../icons/document-open.png + ../../icons/z-bottom.png + ../../icons/z-down.png + ../../icons/z-top.png + ../../icons/z-up.png + ../../icons/align-hor.png + ../../icons/align-ver.png ../../icons/align-bottom-center.png ../../icons/align-bottom-left.png ../../icons/align-bottom-right.png @@ -43,9 +20,15 @@ ../../icons/align-top-center.png ../../icons/align-top-left.png ../../icons/align-top-right.png - ../../icons/z-bottom.png - ../../icons/z-down.png - ../../icons/z-top.png - ../../icons/z-up.png + ../../icons/dialog-close.png + ../../icons/edit-clear.png + ../../icons/edit-delete.png + ../../icons/edit-copy.png + ../../icons/document-save.png + ../../icons/document-open.png + ../../icons/document-edit.png + ../../icons/view-preview.png + ../../icons/format-fill-color.png + ../../icons/format-stroke-color.png diff --git a/qad/libs/doc/CMakeLists.txt b/qad/libs/doc/CMakeLists.txt index 9b9aab6..0457fe1 100644 --- a/qad/libs/doc/CMakeLists.txt +++ b/qad/libs/doc/CMakeLists.txt @@ -17,9 +17,11 @@ else() endif() find_library(MARKDOWN_LIBRARY markdown) if (MARKDOWN_LIBRARY) - if(_mkd_header_found) - qad_library(doc "Core" "${MARKDOWN_LIBRARY}") - else() + qad_library(doc "Core" "${MARKDOWN_LIBRARY}") + if(NOT _mkd_header_found) message(STATUS "Found markdown library, but *.h missing!") endif() +else() + add_definitions("-DNO_MARKDOWN") + qad_library(doc "Core" "") endif() diff --git a/qad/libs/doc/markdown.cpp b/qad/libs/doc/markdown.cpp index dce891f..f218633 100644 --- a/qad/libs/doc/markdown.cpp +++ b/qad/libs/doc/markdown.cpp @@ -1,5 +1,6 @@ #include "markdown.h" #include +#ifndef NO_MARKDOWN extern "C" { #include MARKDOWN_HEADER } @@ -77,3 +78,10 @@ QString md2html(const QByteArray & src) { return ret; } +#else + +QString md2html(const QByteArray & src) { + return src; +} + +#endif diff --git a/qad/libs/graphic/graphic.cpp b/qad/libs/graphic/graphic.cpp index c7b7eb6..5dfd304 100644 --- a/qad/libs/graphic/graphic.cpp +++ b/qad/libs/graphic/graphic.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) # include #endif @@ -37,6 +38,20 @@ Graphic::Graphic(QWidget * parent): QFrame(parent), canvas(0), line_x_min(this), #endif ui = new Ui::Graphic(); ui->setupUi(this); + QActionGroup * agroup = new QActionGroup(this); + agroup->addAction(ui->actionGuidesFree ); + agroup->addAction(ui->actionGuidesTraceX); + agroup->addAction(ui->actionGuidesTraceY); + ui->actionGuidesFree ->setProperty("_value", (int)Free ); + ui->actionGuidesTraceX->setProperty("_value", (int)TraceX); + ui->actionGuidesTraceY->setProperty("_value", (int)TraceY); + ui->actionGuidesFree->setChecked(true); + connect(agroup, SIGNAL(triggered(QAction*)), this, SLOT(actionGuidesTriggered(QAction*))); + ui->checkGuides->addAction(ui->actionGuidesFree ); + ui->checkGuides->addAction(ui->actionGuidesTraceX); + ui->checkGuides->addAction(ui->actionGuidesTraceY); + ui->buttonAutofit->addAction(ui->actionExpandX); + ui->buttonAutofit->addAction(ui->actionExpandY); line_x_min.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); line_x_max.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); ((QBoxLayout * )ui->widgetLY->layout())->insertWidget(0, &line_y_min); @@ -76,6 +91,7 @@ Graphic::Graphic(QWidget * parent): QFrame(parent), canvas(0), line_x_min(this), emaxx = emaxy = DBL_MIN; grad_x = grad_y = Auto; axis_type_x = Numeric; + floating_axis_type = Free; min_repaint_int = 25; inc_x = 1.; buffer = 0; @@ -374,10 +390,7 @@ void Graphic::canvasMousePressEvent(QMouseEvent * e) { emit graphicMousePressEvent(canvas2real(QPointF(e->pos())), e->button()); if (!navigation) return; if (gestures && !need_mouse_pan) return; -#ifdef HAS_GL - canvas_gl->setCursor(guides ? Qt::BlankCursor : Qt::ArrowCursor); -#endif - ui->canvas_raster->setCursor(guides ? Qt::BlankCursor : Qt::ArrowCursor); + setGuidesCursor(); prevpos = e->pos(); startpos = prevpos; startpos_r = canvas2real(startpos); @@ -393,7 +406,7 @@ void Graphic::canvasMousePressEvent(QMouseEvent * e) { return; } else { prevaction = curaction; - curaction = gaMove; + setCurrentAction(gaMove); return; } } @@ -419,10 +432,7 @@ void Graphic::canvasMouseReleaseEvent(QMouseEvent * e) { if (gestures) return; need_mouse_pan = false; if (!navigation) return; -#ifdef HAS_GL - canvas_gl->setCursor(guides ? Qt::BlankCursor : Qt::ArrowCursor); -#endif - ui->canvas_raster->setCursor(guides ? Qt::BlankCursor : Qt::ArrowCursor); + setGuidesCursor(); QPointF tlp, brp; QRect sr; sr = QRect(startpos, curpos).normalized(); @@ -585,18 +595,12 @@ void Graphic::setMaxVisibleTime(double val) { void Graphic::setOnlyExpandY(bool yes) { - only_expand_y = yes; - ui->checkExpandY->blockSignals(true); - ui->checkExpandY->setCheckable(yes); - ui->checkExpandY->blockSignals(false); + ui->actionExpandY->setChecked(yes); } void Graphic::setOnlyExpandX(bool yes) { - only_expand_x = yes; - ui->checkExpandX->blockSignals(true); - ui->checkExpandX->setCheckable(yes); - ui->checkExpandX->blockSignals(false); + ui->actionExpandX->setChecked(yes); } @@ -647,8 +651,6 @@ void Graphic::setButtons(Graphic::Buttons b) { ui->buttonAutofit->setVisible(b.testFlag(Autofit)); ui->checkGrid->setVisible(b.testFlag(Grid)); ui->checkGuides->setVisible(b.testFlag(CursorAxis)); - ui->checkExpandY->setVisible(b.testFlag(OnlyExpandY)); - ui->checkExpandX->setVisible(b.testFlag(OnlyExpandX)); ui->buttonFullscreen->setVisible(b.testFlag(Fullscreen)); ui->checkBorderInputs->setVisible(b.testFlag(BorderInputs)); ui->checkLegend->setVisible(b.testFlag(Legend)); @@ -1149,14 +1151,58 @@ void Graphic::drawGuides() { painter->resetTransform(); painter->setClipping(true); painter->setClipRect(QRect(gridborder.x(), 0, wid - gridborder.x(), hei - gridborder.y())); - painter->drawLine(0, curpos.y(), wid, curpos.y()); - painter->drawLine(curpos.x(), 0, curpos.x(), hei); - QString str = pointCoords(canvas2real(curpos)) + fp_size; + QPoint apos = curpos; + QPointF rpos = canvas2real(apos); + QString str; + str = pointCoords(rpos) + fp_size; + switch (floating_axis_type) { + case TraceX: + if (curGraphic >= 0 && curGraphic < graphics.size()) { + QPolygonF & pol(pause_ ? graphics[curGraphic].polyline_pause : graphics[curGraphic].polyline); + double cursor = rpos.x(), min_dist = -1, dist = 0.; + int index = -1; + for (int i = 0; i < pol.size(); ++i) { + dist = qAbs(pol[i].x() - cursor); + if (min_dist > dist || min_dist < 0) { + min_dist = dist; + index = i; + } + } + if (index >= 0) { + rpos = pol[index]; + apos = real2canvas(rpos).toPoint(); + str = pointCoords(pol[index]) + fp_size; + } + } + break; + case TraceY: + if (curGraphic >= 0 && curGraphic < graphics.size()) { + QPolygonF & pol(pause_ ? graphics[curGraphic].polyline_pause : graphics[curGraphic].polyline); + double cursor = rpos.y(), min_dist = -1, dist = 0.; + int index = -1; + for (int i = 0; i < pol.size(); ++i) { + dist = qAbs(pol[i].y() - cursor); + if (min_dist > dist || min_dist < 0) { + min_dist = dist; + index = i; + } + } + if (index >= 0) { + rpos = pol[index]; + apos = real2canvas(rpos).toPoint(); + str = pointCoords(pol[index]) + fp_size; + } + } + break; + default: break; + } + painter->drawLine(0, apos.y(), wid, apos.y()); + painter->drawLine(apos.x(), 0, apos.x(), hei); + QPoint p = apos + QPoint(font_sz.height() / 4., -font_sz.height() / 4.); QFontMetrics fm(font()); QRect r = fm.boundingRect(str); - QPoint p = curpos + QPoint(font_sz.height() / 4., -font_sz.height() / 4.); - if (r.width() + curpos.x() > wid - font_sz.height() / 2.) p.setX(curpos.x() - r.width() - font_sz.height() / 4.); - if (curpos.y() - r.height() < font_sz.height() / 8.) p.setY(curpos.y() + r.height() - font_sz.height() / 8.); + if (r.width() + apos.x() > wid - font_sz.height() / 2.) p.setX(apos.x() - r.width() - font_sz.height() / 4.); + if (apos.y() - r.height() < font_sz.height() / 8.) p.setY(apos.y() + r.height() - font_sz.height() / 8.); painter->setPen(text_color); painter->drawText(p, str); } @@ -1287,8 +1333,7 @@ void Graphic::setCurrentAction(GraphicAction action) { curaction = action; switch (action) { case gaNone: - if (guides) setCanvasCursor(Qt::BlankCursor); - else setCanvasCursor(Qt::ArrowCursor); + setGuidesCursor(); break; case gaZoomInRect: setCanvasCursor(Qt::CrossCursor); @@ -1314,6 +1359,14 @@ void Graphic::setCanvasCursor(QCursor cursor) { } +void Graphic::setGuidesCursor() { + if (guides) { + setCanvasCursor(floating_axis_type == Free ? Qt::BlankCursor : Qt::CrossCursor); + } else + setCanvasCursor(Qt::ArrowCursor); +} + + void Graphic::swapToBuffer() { QImage timg; #ifdef HAS_GL @@ -1461,8 +1514,7 @@ void Graphic::on_buttonConfigure_clicked() { void Graphic::on_checkGuides_toggled(bool checked) { guides = checked; - if (guides) setCanvasCursor(Qt::BlankCursor); - else setCanvasCursor(Qt::ArrowCursor); + setGuidesCursor(); update(); } @@ -1733,13 +1785,19 @@ void Graphic::setLegendVisible(bool visible) { } -void Graphic::on_checkExpandY_toggled(bool checked) { - only_expand_y = checked; - ui->checkExpandY->setIcon(checked ? icon_exp_y : icon_exp_sy); -} - - -void Graphic::on_checkExpandX_toggled(bool checked) { +void Graphic::on_actionExpandX_triggered(bool checked) { only_expand_x = checked; - ui->checkExpandX->setIcon(checked ? icon_exp_x : icon_exp_sx); + ui->actionExpandX->setIcon(checked ? icon_exp_x : icon_exp_sx); +} + + +void Graphic::on_actionExpandY_triggered(bool checked) { + only_expand_y = checked; + ui->actionExpandY->setIcon(checked ? icon_exp_y : icon_exp_sy); +} + + +void Graphic::actionGuidesTriggered(QAction * a) { + ui->checkGuides->setChecked(true); + setFloatingAxisType((FloatingAxisType)a->property("_value").toInt()); } diff --git a/qad/libs/graphic/graphic.h b/qad/libs/graphic/graphic.h index 199cf54..609ad7a 100644 --- a/qad/libs/graphic/graphic.h +++ b/qad/libs/graphic/graphic.h @@ -53,7 +53,7 @@ class QAD_GRAPHIC_EXPORT Graphic: public QFrame { Q_OBJECT Q_FLAGS(Buttons) - Q_ENUMS(Alignment Graduation AxisType) + Q_ENUMS(Alignment Graduation AxisType FloatingAxisType) Q_PROPERTY(QString caption READ caption WRITE setCaption) Q_PROPERTY(QString labelX READ labelX WRITE setLabelX) @@ -113,6 +113,7 @@ class QAD_GRAPHIC_EXPORT Graphic: public QFrame Q_PROPERTY(double graduationStepX READ graduationStepX WRITE setGraduationStepX) Q_PROPERTY(double graduationStepY READ graduationStepY WRITE setGraduationStepY) Q_PROPERTY(AxisType axisType READ axisType WRITE setAxisType) + Q_PROPERTY(FloatingAxisType floatingAxisType READ floatingAxisType WRITE setFloatingAxisType) Q_PROPERTY(Graphic::GraphicsData graphicsData READ graphicsData WRITE setGraphicsData) Q_PROPERTY(QByteArray graphicsDataRaw READ graphicsDataRaw WRITE setGraphicsDataRaw) @@ -128,8 +129,6 @@ public: Autofit = 0x01, Grid = 0x02, CursorAxis = 0x04, - OnlyExpandY = 0x08, - OnlyExpandX = 0x10, Fullscreen = 0x20, BorderInputs = 0x40, Legend = 0x80, @@ -143,6 +142,7 @@ public: enum Alignment {Left, Right}; enum Graduation {Auto, Fixed}; enum AxisType {Numeric, DateTime}; + enum FloatingAxisType {Free, TraceX, TraceY}; Q_DECLARE_FLAGS(Buttons, Button) QString caption() const; @@ -200,6 +200,7 @@ public: double graduationStepX() const {return gridx;} double graduationStepY() const {return gridy;} AxisType axisType() const {return axis_type_x;} + FloatingAxisType floatingAxisType() const {return floating_axis_type;} QVector graphicData(const int index = 0) const {return graphics[index].polyline;} GraphicsData graphicsData() const; QByteArray graphicsDataRaw() const; @@ -294,6 +295,7 @@ public slots: void setGraduationStepY(double sy) {gridy = sy; if (aupdate) update();} void setGraduationSteps(double sx, double sy) {gridx = sx; gridy = sy; if (aupdate) update();} void setAxisType(AxisType t) {axis_type_x = t; if (aupdate) update();} + void setFloatingAxisType(FloatingAxisType t) {floating_axis_type = t; setGuidesCursor(); if (aupdate) update();} void addPoint(const QPointF & p, int graphic, bool update_ = true); void addPoint(const QPointF & p, bool update = true) {addPoint(p, curGraphic, update);} @@ -346,6 +348,7 @@ protected: void updateLegend(bool es = true); void updateLegendChecks(); void setCanvasCursor(QCursor cursor); + void setGuidesCursor(); void swapToBuffer(); void swapToNormal() {bufferActive = false;} void setRectToLines(); @@ -388,6 +391,7 @@ protected: QImage icon_pause_b, icon_pause_f; Graduation grad_x, grad_y; AxisType axis_type_x; + FloatingAxisType floating_axis_type; double gridx, gridy, history, visible_time, inc_x, grid_numbers_x, grid_numbers_y, LN10; double eminx, eminy, emaxx, emaxy, pause_phase, gesture_angle; int lastw, lasth, min_repaint_int, timer_pause, thick; @@ -417,11 +421,12 @@ protected slots: void on_buttonSave_clicked() {saveImage();} void on_checkGrid_toggled(bool checked) {grid = checked; update();} void on_checkGuides_toggled(bool checked); - void on_checkExpandY_toggled(bool checked); - void on_checkExpandX_toggled(bool checked); + void on_actionExpandX_triggered(bool checked); + void on_actionExpandY_triggered(bool checked); void on_checkBorderInputs_toggled(bool checked) {setBorderInputsVisible(checked);} void on_checkLegend_toggled(bool checked) {setLegendVisible(checked);} void on_checkPause_toggled(bool checked) {setPaused(checked);} + void actionGuidesTriggered(QAction * a); void enterFullscreen(); void leaveFullscreen(); @@ -436,7 +441,6 @@ signals: void cleared(); void visualRectChanged(); void graphicSettingsChanged(); - }; diff --git a/qad/libs/graphic/graphic.ui b/qad/libs/graphic/graphic.ui index 2e58869..096f8a0 100644 --- a/qad/libs/graphic/graphic.ui +++ b/qad/libs/graphic/graphic.ui @@ -64,7 +64,7 @@ Grid - + :/icons/view-grid.png:/icons/view-grid.png @@ -81,7 +81,7 @@ Cursor axis - + :/icons/edit-guides.png:/icons/edit-guides.png @@ -89,41 +89,13 @@ - - - - Only expand Y - - - - :/icons/expand_s_y.png:/icons/expand_s_y.png - - - true - - - - - - - Only expand X - - - - :/icons/expand_s_x.png:/icons/expand_s_x.png - - - true - - - Fullscreen - + :/icons/view-fullscreen.png:/icons/view-fullscreen.png @@ -134,7 +106,7 @@ Border inputs - + :/icons/border-line.png:/icons/border-line.png @@ -151,7 +123,7 @@ Legend - + :/icons/legend.png:/icons/legend.png @@ -182,7 +154,7 @@ Configure ... - + :/icons/configure.png:/icons/configure.png @@ -193,7 +165,7 @@ Save image ... - + :/icons/document-save.png:/icons/document-save.png @@ -220,7 +192,7 @@ Clear - + :/icons/edit-clear.png:/icons/edit-clear.png @@ -231,7 +203,7 @@ Close - + :/icons/dialog-close.png:/icons/dialog-close.png @@ -425,6 +397,49 @@ + + + true + + + Free + + + + + true + + + Trace X + + + + + true + + + Trace Y + + + + + true + + + Only expand X + + + + + true + + + Only expand Y + + + Only expand Y + + @@ -434,9 +449,6 @@ - - - diff --git a/qad/libs/graphic/qad_graphic.qrc b/qad/libs/graphic/qad_graphic.qrc index 437c9e3..800334a 100644 --- a/qad/libs/graphic/qad_graphic.qrc +++ b/qad/libs/graphic/qad_graphic.qrc @@ -1,28 +1,22 @@ + ../../icons/expand_s_x.png + ../../icons/expand_s_y.png + ../../icons/expand_x.png + ../../icons/expand_y.png + ../../icons/pause-back.png + ../../icons/pause-front.png ../../icons/media-playback-pause.png ../../icons/dialog-close.png ../../icons/edit-clear.png ../../icons/edit-guides.png ../../icons/view-grid.png ../../icons/view-autofit.png + ../../icons/view-fullscreen.png ../../icons/configure.png ../../icons/document-save.png - ../../icons/edit-clear-locationbar-rtl.png - ../../icons/edit-find.png - ../../icons/list-add.png - ../../icons/edit-delete.png - ../../icons/edit-copy.png - ../../icons/edit-paste.png - ../../icons/expand_s_x.png - ../../icons/expand_s_y.png - ../../icons/expand_x.png - ../../icons/expand_y.png ../../icons/border-line.png ../../icons/legend.png ../../icons/graphic.png - ../../icons/view-fullscreen.png - ../../icons/pause-back.png - ../../icons/pause-front.png diff --git a/qad/libs/sql_table/qad_sql_table.qrc b/qad/libs/sql_table/qad_sql_table.qrc index 4673462..437d5ad 100644 --- a/qad/libs/sql_table/qad_sql_table.qrc +++ b/qad/libs/sql_table/qad_sql_table.qrc @@ -1,26 +1,11 @@ - ../../icons/edit-table-insert-row-below.png - ../../icons/dialog-close.png - ../../icons/edit-clear.png - ../../icons/edit-guides.png - ../../icons/view-grid.png - ../../icons/zoom-fit-best.png - ../../icons/configure.png - ../../icons/document-save.png - ../../icons/edit-clear-locationbar-rtl.png - ../../icons/edit-find.png - ../../icons/list-add.png - ../../icons/edit-delete.png - ../../icons/item.png - ../../icons/node-add.png - ../../icons/node.png - ../../icons/edit-copy.png - ../../icons/edit-paste.png - ../../icons/expand_s_x.png - ../../icons/expand_s_y.png - ../../icons/expand_x.png - ../../icons/expand_y.png ../../icons/sql_table.png + ../../icons/configure.png + ../../icons/edit-delete.png + ../../icons/edit-table-insert-row-below.png + ../../icons/edit-find.png + ../../icons/edit-clear.png + ../../icons/list-add.png diff --git a/qad/libs/utils/qad_utils.qrc b/qad/libs/utils/qad_utils.qrc deleted file mode 100644 index 4df8988..0000000 --- a/qad/libs/utils/qad_utils.qrc +++ /dev/null @@ -1,17 +0,0 @@ - - - ../../icons/edit-clear.png - ../../icons/document-save.png - ../../icons/edit-clear-locationbar-rtl.png - ../../icons/edit-find.png - ../../icons/list-add.png - ../../icons/edit-delete.png - ../../icons/item-add.png - ../../icons/item.png - ../../icons/node-add.png - ../../icons/node.png - ../../icons/edit-copy.png - ../../icons/edit-paste.png - ../../icons/document-open_16.png - - diff --git a/qad/libs/widgets/chardialog.ui b/qad/libs/widgets/chardialog.ui index 7548b62..09cbfbd 100644 --- a/qad/libs/widgets/chardialog.ui +++ b/qad/libs/widgets/chardialog.ui @@ -14,8 +14,8 @@ Choose symbol - - :/icons/icons/mbricks_128.png:/icons/icons/mbricks_128.png + + :/icons/chardialog.png:/icons/chardialog.png @@ -86,7 +86,7 @@ - + diff --git a/qad/libs/widgets/plugin/imageviewplugin.cpp b/qad/libs/widgets/plugin/imageviewplugin.cpp index f20adc9..e4d0b26 100644 --- a/qad/libs/widgets/plugin/imageviewplugin.cpp +++ b/qad/libs/widgets/plugin/imageviewplugin.cpp @@ -39,7 +39,7 @@ QString ImageViewPlugin::group() const { QIcon ImageViewPlugin::icon() const { - return QIcon(/*":/icons/spinslider.png"*/); + return QIcon(":/icons/view-preview.png"); } diff --git a/qad/libs/widgets/plugin/qpointeditplugin.cpp b/qad/libs/widgets/plugin/qpointeditplugin.cpp index 622c78e..fb4cf8d 100644 --- a/qad/libs/widgets/plugin/qpointeditplugin.cpp +++ b/qad/libs/widgets/plugin/qpointeditplugin.cpp @@ -39,7 +39,7 @@ QString QPointEditPlugin::group() const { QIcon QPointEditPlugin::icon() const { - return QIcon(":/icons/qpointedit.png"); + return QIcon(); } diff --git a/qad/libs/widgets/plugin/qrecteditplugin.cpp b/qad/libs/widgets/plugin/qrecteditplugin.cpp index f64f30c..1ed5a2c 100644 --- a/qad/libs/widgets/plugin/qrecteditplugin.cpp +++ b/qad/libs/widgets/plugin/qrecteditplugin.cpp @@ -39,7 +39,7 @@ QString QRectEditPlugin::group() const { QIcon QRectEditPlugin::icon() const { - return QIcon(":/icons/qrectedit.png"); + return QIcon(); } diff --git a/qad/libs/widgets/qad_widgets.qrc b/qad/libs/widgets/qad_widgets.qrc index 50d5263..1c19139 100644 --- a/qad/libs/widgets/qad_widgets.qrc +++ b/qad/libs/widgets/qad_widgets.qrc @@ -1,46 +1,35 @@ - - ../../icons/go-next.png - ../../icons/go-previous.png - ../../icons/dialog-close.png - ../../icons/edit-clear.png - ../../icons/edit-guides.png - ../../icons/view-grid.png - ../../icons/zoom-fit-best.png - ../../icons/configure.png - ../../icons/alpha.png - ../../icons/document-save.png - ../../icons/edit-clear-locationbar-rtl.png - ../../icons/edit-find.png - ../../icons/list-add.png - ../../icons/edit-delete.png - ../../icons/item-add.png - ../../icons/item.png - ../../icons/node-add.png - ../../icons/node.png - ../../icons/edit-copy.png - ../../icons/edit-paste.png - ../../icons/expand_s_x.png - ../../icons/expand_s_y.png - ../../icons/expand_x.png - ../../icons/expand_y.png - ../../icons/border-line.png - ../../icons/legend.png - ../../icons/chardialog.png - ../../icons/clineedit.png - ../../icons/colorbutton.png - ../../icons/ecombobox.png - ../../icons/qpiconsole.png - ../../icons/spinslider.png - ../../icons/etabwidget.png - ../../icons/qcodeedit.png - ../../icons/qvariantedit.png - ../../icons/code-word.png - ../../icons/f1.png - ../../icons/dialog-ok-apply.png - ../../icons/dialog-warning.png - ../../icons/tools-wizard.png - ../../icons/evalspinbox.png - ../../icons/scroll_spin.png - + + ../../icons/edit-clear-locationbar-rtl.png + ../../icons/edit-copy.png + ../../icons/edit-paste.png + ../../icons/edit-find.png + ../../icons/edit-delete.png + ../../icons/edit-clear.png + ../../icons/dialog-ok-apply.png + ../../icons/dialog-warning.png + ../../icons/tools-wizard.png + ../../icons/go-next.png + ../../icons/go-previous.png + ../../icons/item.png + ../../icons/item-add.png + ../../icons/node.png + ../../icons/node-add.png + ../../icons/list-add.png + ../../icons/document-save.png + ../../icons/document-open.png + ../../icons/alpha.png + ../../icons/chardialog.png + ../../icons/clineedit.png + ../../icons/colorbutton.png + ../../icons/ecombobox.png + ../../icons/evalspinbox.png + ../../icons/qcodeedit.png + ../../icons/qpiconsole.png + ../../icons/qvariantedit.png + ../../icons/spinslider.png + ../../icons/code-word.png + ../../icons/f1.png + ../../icons/scroll_spin.png + diff --git a/qad/libs/widgets/qcodeedit.ui b/qad/libs/widgets/qcodeedit.ui index 8874863..1a53c84 100644 --- a/qad/libs/widgets/qcodeedit.ui +++ b/qad/libs/widgets/qcodeedit.ui @@ -178,7 +178,7 @@ Previous - + :/icons/go-previous.png:/icons/go-previous.png @@ -195,7 +195,7 @@ Next - + :/icons/go-next.png:/icons/go-next.png @@ -311,7 +311,9 @@
ecombobox.h
- + + + buttonSearchNext diff --git a/qad/libs/widgets/scroll_spin_box.ui b/qad/libs/widgets/scroll_spin_box.ui index c398780..89fc077 100644 --- a/qad/libs/widgets/scroll_spin_box.ui +++ b/qad/libs/widgets/scroll_spin_box.ui @@ -64,7 +64,9 @@
evalspinbox.h
- + + + mapChanged() diff --git a/qglengine/CMakeLists.txt b/qglengine/CMakeLists.txt index 93542ec..d852ec4 100644 --- a/qglengine/CMakeLists.txt +++ b/qglengine/CMakeLists.txt @@ -1,92 +1,55 @@ -cmake_minimum_required(VERSION 3.0) -project(qglengine) -find_package(QAD REQUIRED) -set(_DOMAIN "org.SHS") -set(_COMPANY "SHS") -find_qt(Qt5 Core Gui OpenGL Xml) -if (NOT Qt5) - message(WARNING "Building ${PROJECT_NAME} available only on Qt5!") -else() - if (LIBPROJECT) - include(SDKMacros) - else() - option(LIB "System install" 0) - option(DEBUG "Build with -g3" 0) - option(DESIGNER_PLUGINS "Build qt designer plugins" 1) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wall") - if (DEBUG) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3") - endif() - include(DeployMacros) - endif() - if (MINGW) - find_package(MinGW REQUIRED) - endif() - find_package(OpenGL REQUIRED) - set_version(qglengine - MAJOR 1 - MINOR 0 - REVISION 0 - BUILD "${BUILD_NUMBER}" - SUFFIX rc - OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/core/qglengine_version.h") - - qt_sources(SRC) - qt_sources(FSRC DIR "formats") - list(APPEND SRC ${FSRC}) - qt_sources(FSRC DIR "core") - list(APPEND SRC ${FSRC}) - qt_wrap(${SRC} HDRS out_HDR CPPS out_CPP QMS out_QM) - file(GLOB PHS "*_p.h" "formats/*_p.h" "core/*_p.h") - list(REMOVE_ITEM out_HDR "${PHS}") - import_version(qglengine_core qglengine) - set_deploy_property(qglengine_core SHARED - LABEL "QGLEngine core library" - FULLNAME "${_DOMAIN}.qglengine_core" - COMPANY "${_COMPANY}" - INFO "QGLEngine core library") - make_rc(qglengine_core _RC) - qt_add_library(qglengine_core SHARED out_CPP ${_RC}) - qt_target_include_directories(qglengine_core PRIVATE ${QAD_INCLUDES} "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/core") - qt_target_link_libraries(qglengine_core qad_utils qad_widgets assimp ${OPENGL_LIBRARIES}) - message(STATUS "Building QGLEngine version ${qglengine_VERSION} (SHARED)") - list(APPEND QT_MULTILIB_LIST qglengine_core) - add_subdirectory(widgets) - set(QT_MULTILIB_LIST ${QT_MULTILIB_LIST} PARENT_SCOPE) - if (LIBPROJECT) - sdk_install("qglengine" FALSE "qglengine_core" "${out_HDR}" "${out_QM}") - else() - if (LIB) - if (WIN32) - qt_install(FILES ${out_HDR} DESTINATION ${MINGW_INCLUDE}/qglengine) - qt_install(TARGETS qglengine_core ARCHIVE DESTINATION ${MINGW_LIB}) - qt_install(TARGETS qglengine_core RUNTIME DESTINATION ${MINGW_BIN}) - qt_install(TARGETS qglengine_core RUNTIME DESTINATION QtBin) - else() - qt_install(FILES ${out_HDR} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/qglengine) - qt_install(TARGETS qglengine_core DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) - endif() - message(STATUS "Install qglengine_core to system \"${CMAKE_INSTALL_PREFIX}\"") - else() - if(WIN32) - qt_install(TARGETS qglengine_core RUNTIME DESTINATION bin) - qt_install(TARGETS qglengine_core ARCHIVE DESTINATION lib) - else() - qt_install(TARGETS qglengine_core DESTINATION bin/lib) - endif() - qt_install(FILES ${out_HDR} DESTINATION include/qglengine) - message(STATUS "Install qglengine_core to local \"bin\", \"lib\" and \"include\"") - endif() - endif() - if (NOT DEFINED ANDROID_PLATFORM) - if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/plugin") - #add_subdirectory(plugin) - endif() - endif() - - qt_sources(test_SRC DIR "qglview_test") - qt_wrap(${test_SRC} CPPS test_CPP) - qt_add_executable(qglengine_test test_CPP) - qt_target_link_libraries(qglengine_test qglengine_core qglengine_widgets) - qt_target_include_directories(qglengine_test PRIVATE ${QAD_INCLUDES} "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/core" "${CMAKE_CURRENT_SOURCE_DIR}/widgets") -endif() +cmake_minimum_required(VERSION 3.0) +project(qglengine) +find_package(QAD REQUIRED) +set(_DOMAIN "org.SHS") +set(_COMPANY "SHS") +find_qt(Qt5 Core Gui OpenGL Xml) +if (NOT Qt5) + message(WARNING "Building ${PROJECT_NAME} available only on Qt5!") +else() + find_package(OpenGL REQUIRED) + set_version(qglengine + MAJOR 1 + MINOR 0 + REVISION 0 + BUILD "${BUILD_NUMBER}" + SUFFIX rc + OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/core/qglengine_version.h") + + qt_sources(SRC) + qt_sources(FSRC DIR "formats") + list(APPEND SRC ${FSRC}) + qt_sources(FSRC DIR "core") + list(APPEND SRC ${FSRC}) + qt_wrap(${SRC} HDRS out_HDR CPPS out_CPP QMS out_QM) + file(GLOB PHS "*_p.h" "formats/*_p.h" "core/*_p.h") + list(REMOVE_ITEM out_HDR "${PHS}") + import_version(qglengine_core qglengine) + set_deploy_property(qglengine_core SHARED + LABEL "QGLEngine core library" + FULLNAME "${_DOMAIN}.qglengine_core" + COMPANY "${_COMPANY}" + INFO "QGLEngine core library") + make_rc(qglengine_core _RC) + qt_add_library(qglengine_core SHARED out_CPP ${_RC}) + qt_generate_export_header(qglengine_core) + list(APPEND out_HDR "${CMAKE_CURRENT_BINARY_DIR}/qglengine_core_export.h") + qt_target_include_directories(qglengine_core PRIVATE ${QAD_INCLUDES} "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/core") + qt_target_link_libraries(qglengine_core qad_utils qad_widgets assimp ${OPENGL_LIBRARIES}) + message(STATUS "Building QGLEngine version ${qglengine_VERSION} (SHARED)") + list(APPEND QT_MULTILIB_LIST qglengine_core) + add_subdirectory(widgets) + copy_to_parent("") + sdk_install("qglengine" FALSE "qglengine_core" "${out_HDR}" "${out_QM}") + if (NOT DEFINED ANDROID_PLATFORM) + if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/plugin") + #add_subdirectory(plugin) + endif() + endif() + + qt_sources(test_SRC DIR "qglview_test") + qt_wrap(${test_SRC} CPPS test_CPP) + qt_add_executable(qglengine_test test_CPP) + qt_target_link_libraries(qglengine_test qglengine_core qglengine_widgets) + qt_target_include_directories(qglengine_test PRIVATE ${QAD_INCLUDES} "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/core" "${CMAKE_CURRENT_SOURCE_DIR}/widgets") +endif() diff --git a/qglengine/glwidget.cpp b/qglengine/glwidget.cpp index 921652b..29bde34 100644 --- a/qglengine/glwidget.cpp +++ b/qglengine/glwidget.cpp @@ -1,240 +1,240 @@ -/* - QGL GLWidget - Ivan Pelipenko peri4ko@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 . -*/ - -#include "glwidget.h" -#include "qglview.h" -#include - - -GLWidget::GLWidget(QWidget *parent) : QWidget(parent) { - view_ = new QGLView(); - view_->setFlags(windowFlags() | Qt::FramelessWindowHint); - container = QWidget::createWindowContainer(view_, this); - lay = new QVBoxLayout(this); - lay->addWidget(container); - lay->setContentsMargins(0, 0, 0, 0); - lay->setSpacing(0); - setMouseTracking(true); - setWindowIcon(QIcon("://icons/qglview.png")); - connect(view_, &QGLView::doubleClick, this, &GLWidget::viewDoubleClicked); -} - - -QColor GLWidget::backColor() const { - return view_->backColor(); -} - - -qreal GLWidget::lineWidth() const { - return view_->lineWidth(); -} - - -qreal GLWidget::FOV() const { - return view_->FOV(); -} - - -qreal GLWidget::depthStart() const { - return view_->depthStart(); -} - - -QColor GLWidget::ambientColor() const { - return view_->ambientColor(); -} - - -bool GLWidget::isLightEnabled() const { - return view_->isLightEnabled(); -} - - -bool GLWidget::isGrabMouseEnabled() const { - return view_->isGrabMouseEnabled(); -} - - -bool GLWidget::isMouseRotateEnabled() const { - return view_->isMouseRotateEnabled(); -} - - -bool GLWidget::isMouseSelectionEnabled() const { - return view_->isMouseSelectionEnabled(); -} - - -bool GLWidget::isCameraOrbit() const -{ - return view_->isCameraOrbit(); -} - - -bool GLWidget::isHoverHaloEnabled() const { - return view_->isHoverHaloEnabled(); -} - - -QColor GLWidget::hoverHaloColor() const { - return view_->hoverHaloColor(); -} - - -qreal GLWidget::hoverHaloFillAlpha() const { - return view_->hoverHaloFillAlpha(); -} - - -bool GLWidget::isSelectionHaloEnabled() const { - return view_->isSelectionHaloEnabled(); -} - - -QColor GLWidget::selectionHaloColor() const { - return view_->selectionHaloColor(); -} - - -qreal GLWidget::selectionHaloFillAlpha() const { - return view_->selectionHaloFillAlpha(); -} - - -Scene * GLWidget::scene() { - return view_->scene(); -} - - -void GLWidget::addObject(ObjectBase * o) { - view_->scene()->addObject(o); -} - - -QByteArray GLWidget::saveCamera() { - return view_->saveCamera(); -} - - -void GLWidget::restoreCamera(const QByteArray &ba) { - view_->restoreCamera(ba); -} - - -void GLWidget::stop() { - view_->stop(); -} - - -void GLWidget::start(float freq) { - view_->start(freq); -} - - -void GLWidget::setBackColor(const QColor & c) { - view_->setBackColor(c); -} - - -void GLWidget::setLineWidth(const qreal & arg) { - view_->setLineWidth(arg); -} - - -void GLWidget::setFOV(const qreal & arg) { - view_->setFOV(arg); -} - - -void GLWidget::setDepthStart(const qreal & arg) { - view_->setDepthStart(arg); -} - - -void GLWidget::setAmbientColor(const QColor & arg) { - view_->setAmbientColor(arg); -} - - -void GLWidget::setLightEnabled(const bool & arg) { - view_->setLightEnabled(arg); -} - - -void GLWidget::setGrabMouseEnabled(const bool & arg) { - view_->setGrabMouseEnabled(arg); -} - - -void GLWidget::setMouseRotateEnabled(const bool & arg) { - view_->setMouseRotateEnabled(arg); -} - - -void GLWidget::setMouseSelectionEnabled(const bool & arg) { - view_->setMouseSelectionEnabled(arg); -} - - -void GLWidget::setCameraOrbit(const bool & arg) { - view_->setCameraOrbit(arg); -} - - -void GLWidget::setHoverHaloEnabled(const bool & arg) { - view_->setHoverHaloEnabled(arg); -} - - -void GLWidget::setHoverHaloColor(const QColor & arg) { - view_->setHoverHaloColor(arg); -} - - -void GLWidget::setHoverHaloFillAlpha(const qreal & arg) { - view_->setHoverHaloFillAlpha(arg); -} - - -void GLWidget::setSelectionHaloEnabled(const bool & arg) { - view_->setSelectionHaloEnabled(arg); -} - - -void GLWidget::setSelectionHaloColor(const QColor & arg) { - view_->setSelectionHaloColor(arg); -} - - -void GLWidget::setSelectionHaloFillAlpha(const qreal & arg) { - view_->setSelectionHaloFillAlpha(arg); -} - - -void GLWidget::viewDoubleClicked() { - if (view_->windowState() == Qt::WindowFullScreen) { - view_->showNormal(); - container = QWidget::createWindowContainer(view_, this); - lay->addWidget(container); - container->show(); - } else { - view_->setParent(nullptr); - view_->showFullScreen(); - lay->removeWidget(container); - } -} +/* + QGL GLWidget + Ivan Pelipenko peri4ko@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 . +*/ + +#include "glwidget.h" +#include "qglview.h" +#include + + +GLWidget::GLWidget(QWidget *parent) : QWidget(parent) { + view_ = new QGLView(); + view_->setFlags(windowFlags() | Qt::FramelessWindowHint); + container = QWidget::createWindowContainer(view_, this); + lay = new QVBoxLayout(this); + lay->addWidget(container); + lay->setContentsMargins(0, 0, 0, 0); + lay->setSpacing(0); + setMouseTracking(true); + setWindowIcon(QIcon("://icons/qglview.png")); + connect(view_, &QGLView::doubleClick, this, &GLWidget::viewDoubleClicked); +} + + +QColor GLWidget::backColor() const { + return view_->backColor(); +} + + +qreal GLWidget::lineWidth() const { + return view_->lineWidth(); +} + + +qreal GLWidget::FOV() const { + return view_->FOV(); +} + + +qreal GLWidget::depthStart() const { + return view_->depthStart(); +} + + +QColor GLWidget::ambientColor() const { + return view_->ambientColor(); +} + + +bool GLWidget::isLightEnabled() const { + return view_->isLightEnabled(); +} + + +bool GLWidget::isGrabMouseEnabled() const { + return view_->isGrabMouseEnabled(); +} + + +bool GLWidget::isMouseRotateEnabled() const { + return view_->isMouseRotateEnabled(); +} + + +bool GLWidget::isMouseSelectionEnabled() const { + return view_->isMouseSelectionEnabled(); +} + + +bool GLWidget::isCameraOrbit() const +{ + return view_->isCameraOrbit(); +} + + +bool GLWidget::isHoverHaloEnabled() const { + return view_->isHoverHaloEnabled(); +} + + +QColor GLWidget::hoverHaloColor() const { + return view_->hoverHaloColor(); +} + + +qreal GLWidget::hoverHaloFillAlpha() const { + return view_->hoverHaloFillAlpha(); +} + + +bool GLWidget::isSelectionHaloEnabled() const { + return view_->isSelectionHaloEnabled(); +} + + +QColor GLWidget::selectionHaloColor() const { + return view_->selectionHaloColor(); +} + + +qreal GLWidget::selectionHaloFillAlpha() const { + return view_->selectionHaloFillAlpha(); +} + + +Scene * GLWidget::scene() { + return view_->scene(); +} + + +void GLWidget::addObject(ObjectBase * o) { + view_->scene()->addObject(o); +} + + +QByteArray GLWidget::saveCamera() { + return view_->saveCamera(); +} + + +void GLWidget::restoreCamera(const QByteArray &ba) { + view_->restoreCamera(ba); +} + + +void GLWidget::stop() { + view_->stop(); +} + + +void GLWidget::start(float freq) { + view_->start(freq); +} + + +void GLWidget::setBackColor(const QColor & c) { + view_->setBackColor(c); +} + + +void GLWidget::setLineWidth(const qreal & arg) { + view_->setLineWidth(arg); +} + + +void GLWidget::setFOV(const qreal & arg) { + view_->setFOV(arg); +} + + +void GLWidget::setDepthStart(const qreal & arg) { + view_->setDepthStart(arg); +} + + +void GLWidget::setAmbientColor(const QColor & arg) { + view_->setAmbientColor(arg); +} + + +void GLWidget::setLightEnabled(const bool & arg) { + view_->setLightEnabled(arg); +} + + +void GLWidget::setGrabMouseEnabled(const bool & arg) { + view_->setGrabMouseEnabled(arg); +} + + +void GLWidget::setMouseRotateEnabled(const bool & arg) { + view_->setMouseRotateEnabled(arg); +} + + +void GLWidget::setMouseSelectionEnabled(const bool & arg) { + view_->setMouseSelectionEnabled(arg); +} + + +void GLWidget::setCameraOrbit(const bool & arg) { + view_->setCameraOrbit(arg); +} + + +void GLWidget::setHoverHaloEnabled(const bool & arg) { + view_->setHoverHaloEnabled(arg); +} + + +void GLWidget::setHoverHaloColor(const QColor & arg) { + view_->setHoverHaloColor(arg); +} + + +void GLWidget::setHoverHaloFillAlpha(const qreal & arg) { + view_->setHoverHaloFillAlpha(arg); +} + + +void GLWidget::setSelectionHaloEnabled(const bool & arg) { + view_->setSelectionHaloEnabled(arg); +} + + +void GLWidget::setSelectionHaloColor(const QColor & arg) { + view_->setSelectionHaloColor(arg); +} + + +void GLWidget::setSelectionHaloFillAlpha(const qreal & arg) { + view_->setSelectionHaloFillAlpha(arg); +} + + +void GLWidget::viewDoubleClicked() { + if (view_->windowState() == Qt::WindowFullScreen) { + view_->showNormal(); + container = QWidget::createWindowContainer(view_, this); + lay->addWidget(container); + container->show(); + } else { + view_->setParent(nullptr); + view_->showFullScreen(); + lay->removeWidget(container); + } +} diff --git a/qglengine/glwidget.h b/qglengine/glwidget.h index b72265d..edef74a 100644 --- a/qglengine/glwidget.h +++ b/qglengine/glwidget.h @@ -1,104 +1,104 @@ -/* - QGL GLWidget - Ivan Pelipenko peri4ko@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 . -*/ - -#ifndef GLWIDGET_H -#define GLWIDGET_H - -#include - - -class QGLView; -class ObjectBase; -class Scene; - -class GLWidget : public QWidget -{ - Q_OBJECT - Q_PROPERTY (QColor backColor READ backColor WRITE setBackColor) - Q_PROPERTY (qreal lineWidth READ lineWidth WRITE setLineWidth) - Q_PROPERTY (qreal FOV READ FOV WRITE setFOV) - Q_PROPERTY (qreal depthStart READ depthStart WRITE setDepthStart) - Q_PROPERTY (QColor ambientColor READ ambientColor WRITE setAmbientColor) - Q_PROPERTY (bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled) - Q_PROPERTY (bool mouseRotate READ isMouseRotateEnabled WRITE setMouseRotateEnabled) - Q_PROPERTY (bool mouseSelection READ isMouseSelectionEnabled WRITE setMouseSelectionEnabled) - Q_PROPERTY (bool cameraOrbit READ isCameraOrbit WRITE setCameraOrbit) - Q_PROPERTY (bool hoverHalo READ isHoverHaloEnabled WRITE setHoverHaloEnabled) - Q_PROPERTY (QColor hoverHaloColor READ hoverHaloColor WRITE setHoverHaloColor) - Q_PROPERTY (qreal hoverHaloFillAlpha READ hoverHaloFillAlpha WRITE setHoverHaloFillAlpha) - Q_PROPERTY (bool selectionHalo READ isSelectionHaloEnabled WRITE setSelectionHaloEnabled) - Q_PROPERTY (QColor selectionHaloColor READ selectionHaloColor WRITE setSelectionHaloColor) - Q_PROPERTY (qreal selectionHaloFillAlpha READ selectionHaloFillAlpha WRITE setSelectionHaloFillAlpha) -public: - explicit GLWidget(QWidget *parent = nullptr); - QGLView * view() {return view_;} - - QColor backColor() const; - qreal lineWidth() const; - qreal FOV() const; - qreal depthStart() const; - QColor ambientColor() const; - bool isLightEnabled() const; - bool isGrabMouseEnabled() const; - bool isMouseRotateEnabled() const; - bool isMouseSelectionEnabled() const; - bool isCameraOrbit() const; - bool isHoverHaloEnabled() const; - QColor hoverHaloColor() const; - qreal hoverHaloFillAlpha() const; - bool isSelectionHaloEnabled() const; - QColor selectionHaloColor() const; - qreal selectionHaloFillAlpha() const; - Scene * scene(); - - void addObject(ObjectBase * o); - QByteArray saveCamera(); - void restoreCamera(const QByteArray & ba); - -public slots: - void stop(); - void start(float freq = 60.0); - void setBackColor(const QColor & c); - void setLineWidth(const qreal & arg); - void setFOV(const qreal & arg); - void setDepthStart(const qreal & arg); - void setAmbientColor(const QColor & arg); - void setLightEnabled(const bool & arg); - void setGrabMouseEnabled(const bool & arg); - void setMouseRotateEnabled(const bool & arg); - void setMouseSelectionEnabled(const bool & arg); - void setCameraOrbit(const bool & arg); - void setHoverHaloEnabled(const bool & arg); - void setHoverHaloColor(const QColor & arg); - void setHoverHaloFillAlpha(const qreal & arg); - void setSelectionHaloEnabled(const bool & arg); - void setSelectionHaloColor(const QColor & arg); - void setSelectionHaloFillAlpha(const qreal & arg); - -private slots: - void viewDoubleClicked(); - -private: - QWidget * container; - QGLView * view_; - QLayout * lay; - -signals: -}; - -#endif // GLWIDGET_H +/* + QGL GLWidget + Ivan Pelipenko peri4ko@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 . +*/ + +#ifndef GLWIDGET_H +#define GLWIDGET_H + +#include + + +class QGLView; +class ObjectBase; +class Scene; + +class GLWidget : public QWidget +{ + Q_OBJECT + Q_PROPERTY (QColor backColor READ backColor WRITE setBackColor) + Q_PROPERTY (qreal lineWidth READ lineWidth WRITE setLineWidth) + Q_PROPERTY (qreal FOV READ FOV WRITE setFOV) + Q_PROPERTY (qreal depthStart READ depthStart WRITE setDepthStart) + Q_PROPERTY (QColor ambientColor READ ambientColor WRITE setAmbientColor) + Q_PROPERTY (bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled) + Q_PROPERTY (bool mouseRotate READ isMouseRotateEnabled WRITE setMouseRotateEnabled) + Q_PROPERTY (bool mouseSelection READ isMouseSelectionEnabled WRITE setMouseSelectionEnabled) + Q_PROPERTY (bool cameraOrbit READ isCameraOrbit WRITE setCameraOrbit) + Q_PROPERTY (bool hoverHalo READ isHoverHaloEnabled WRITE setHoverHaloEnabled) + Q_PROPERTY (QColor hoverHaloColor READ hoverHaloColor WRITE setHoverHaloColor) + Q_PROPERTY (qreal hoverHaloFillAlpha READ hoverHaloFillAlpha WRITE setHoverHaloFillAlpha) + Q_PROPERTY (bool selectionHalo READ isSelectionHaloEnabled WRITE setSelectionHaloEnabled) + Q_PROPERTY (QColor selectionHaloColor READ selectionHaloColor WRITE setSelectionHaloColor) + Q_PROPERTY (qreal selectionHaloFillAlpha READ selectionHaloFillAlpha WRITE setSelectionHaloFillAlpha) +public: + explicit GLWidget(QWidget *parent = nullptr); + QGLView * view() {return view_;} + + QColor backColor() const; + qreal lineWidth() const; + qreal FOV() const; + qreal depthStart() const; + QColor ambientColor() const; + bool isLightEnabled() const; + bool isGrabMouseEnabled() const; + bool isMouseRotateEnabled() const; + bool isMouseSelectionEnabled() const; + bool isCameraOrbit() const; + bool isHoverHaloEnabled() const; + QColor hoverHaloColor() const; + qreal hoverHaloFillAlpha() const; + bool isSelectionHaloEnabled() const; + QColor selectionHaloColor() const; + qreal selectionHaloFillAlpha() const; + Scene * scene(); + + void addObject(ObjectBase * o); + QByteArray saveCamera(); + void restoreCamera(const QByteArray & ba); + +public slots: + void stop(); + void start(float freq = 60.0); + void setBackColor(const QColor & c); + void setLineWidth(const qreal & arg); + void setFOV(const qreal & arg); + void setDepthStart(const qreal & arg); + void setAmbientColor(const QColor & arg); + void setLightEnabled(const bool & arg); + void setGrabMouseEnabled(const bool & arg); + void setMouseRotateEnabled(const bool & arg); + void setMouseSelectionEnabled(const bool & arg); + void setCameraOrbit(const bool & arg); + void setHoverHaloEnabled(const bool & arg); + void setHoverHaloColor(const QColor & arg); + void setHoverHaloFillAlpha(const qreal & arg); + void setSelectionHaloEnabled(const bool & arg); + void setSelectionHaloColor(const QColor & arg); + void setSelectionHaloFillAlpha(const qreal & arg); + +private slots: + void viewDoubleClicked(); + +private: + QWidget * container; + QGLView * view_; + QLayout * lay; + +signals: +}; + +#endif // GLWIDGET_H diff --git a/qglengine/mouse_controller.cpp b/qglengine/mouse_controller.cpp index ddecef9..b9add13 100644 --- a/qglengine/mouse_controller.cpp +++ b/qglengine/mouse_controller.cpp @@ -1,289 +1,289 @@ -/* - QGL MouseController - Ivan Pelipenko peri4ko@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 . -*/ - -#include "mouse_controller.h" -#include "glmesh.h" -#include "qglview.h" -#include -#include -#include - -using namespace QGLEngineShaders; - - -MouseController::MouseController(QGLView * view_): view(view_) { - app_scale = 1; - lastPos = QPoint(-1, -1); - cur_action = RendererService::haNoAction; - sel_button = Qt::LeftButton; - sel_mod = Qt::ControlModifier; - mouse_first = mouseSelect_ = mouseRotate_ = cameraOrbit_ = canSelect_ = true; - grabMouse_ = mouse_sec = selecting_ = customMouseMove_ = false; -} - - -MouseController::~MouseController() { -} - - -void MouseController::resize() { - mouse_first = true; - app_scale = appScale(); -} - - -void MouseController::mouseReleaseEvent(QMouseEvent * e) { - if (cur_action != RendererService::haNoAction) { - mouseMoveEvent(e); - return; - } - bool add_ts = e->modifiers().testFlag(sel_mod); - if (selecting_) { - selecting_ = false; - canSelect_ = true; - view->renderer_.mouse_rect = QRect(); - view->scene_->selectObjects(hov_objects.toList(), add_ts); - return; - } - if (canSelect_ && mouseSelect_) { - if ((lastPos - downPos).manhattanLength() < QApplication::startDragDistance()) { - if (e->button() == Qt::LeftButton) { - //qDebug() << hov_objects << hov_aims; - if (hov_objects.isEmpty() && hov_aims.isEmpty()) { - view->scene()->clearSelection(); - } else { - if (!hov_objects.isEmpty()) - view->scene_->selectObject(hov_objects[0], add_ts); - if (!hov_aims.isEmpty()) { - view->scene_->selectObject(hov_aims[0], add_ts); - hov_aims[0]->selected_aim = true; - } - } - } - if (e->button() == Qt::RightButton) { - if (view->renderer_.edit_mode && !view->scene()->selectedObjects().isEmpty()) - view->context_menu.popup(e->globalPos()); - } - } - } - canSelect_ = e->buttons() == 0; - emit view->glMouseReleaseEvent(e); -} - - -void MouseController::mousePressEvent(QMouseEvent * e) { - downPos = e->pos(); - if (cur_action != RendererService::haNoAction && e->buttons() == Qt::LeftButton) { - return; - } - if (selecting_) { - selecting_ = false; - view->renderer_.mouse_rect = QRect(); - return; - } - if (!QRect(QPoint(), view->size()).contains(e->pos())) return; - lastPos = e->pos(); - downPos = e->pos(); - emit view->glMousePressEvent(e); -} - - -void MouseController::mouseMoveEvent(QMouseEvent * e) { - QPoint cpos = e->pos(); - if (cur_action != RendererService::haNoAction && (e->buttons() == Qt::LeftButton)) { - RendererService & rs(view->renderer_.rend_service); - ObjectBaseList objects = view->scene_->selectedObjects(true); - QVector axis; - switch (cur_action) { - case RendererService::haMove: - if (cur_handle.testFlag(RendererService::hmMoveX)) axis << 0; - if (cur_handle.testFlag(RendererService::hmMoveY)) axis << 1; - if (cur_handle.testFlag(RendererService::hmMoveZ)) axis << 2; - break; - case RendererService::haRotate: - if (cur_handle.testFlag(RendererService::hmRotateX)) axis << 0; - if (cur_handle.testFlag(RendererService::hmRotateY)) axis << 1; - if (cur_handle.testFlag(RendererService::hmRotateZ)) axis << 2; - break; - case RendererService::haScale: - if (cur_handle.testFlag(RendererService::hmScaleX)) axis << 0; - if (cur_handle.testFlag(RendererService::hmScaleY)) axis << 1; - if (cur_handle.testFlag(RendererService::hmScaleZ)) axis << 2; - break; - default: break; - } - QVector scales; - foreach (int a, axis) { - QVector3D axe_vector; axe_vector[a] = 1.; - QMatrix4x4 axis_mat = view->camera()->fullViewMatrix() * rs.axis_mat; - QVector3D center_screen = axis_mat * rs.selection_center; - QVector3D axe_screen = ((axis_mat * (rs.selection_center + axe_vector)) - center_screen).normalized(); - QVector3D mouse_vector(cpos - lastPos); - mouse_vector[1] *= -1.; - if (cur_action == RendererService::haMove) { - double len_scl = 1. / QVector3D(axe_screen.x(), axe_screen.y(), 1.E-6).length(); - mouse_vector /= QVector3D(view->width(), view->height(), 1); - mouse_vector *= -center_screen.z() * len_scl; - axe_vector *= QVector3D::dotProduct(axe_screen, mouse_vector); - QMatrix4x4 pmat; - foreach (ObjectBase * o, objects) { - pmat.setToIdentity(); - if (o->parent()) - pmat = o->parent()->worldTransform().inverted(); - QVector3D dv = pmat.mapVector(axe_vector); - if (o->selected_aim) { - AimedObject * ao = (AimedObject*)o; - ao->setAim(ao->aim() + dv); - } else - o->move(dv); - } - } - if (cur_action == RendererService::haRotate) { - axe_screen.setZ(0.); - axe_screen.normalize(); - QVector3D norm = QVector3D(axe_screen.y(), -axe_screen.x(), 0.); - axe_vector *= QVector3D::dotProduct(mouse_vector, norm) / 2. / app_scale; - foreach (ObjectBase * o, objects) - o->setRotation(o->rotation() + axe_vector); - } - if (cur_action == RendererService::haScale) { - mouse_vector /= QVector3D(view->width(), view->height(), 1); - mouse_vector *= 3. / app_scale; - axe_vector *= QVector3D::dotProduct(axe_screen, mouse_vector); - scales << axe_vector; - } - } - //if (cur_handle >= RendererService::htScaleX && cur_handle <= RendererService::htScaleZ ) cs = Qt::SplitHCursor; - if (cur_action == RendererService::haScale) { - double sc = 0., max = 0.; - foreach (const QVector3D & s, scales) { - double v = QVector3D::dotProduct(s, QVector3D(1,1,1)); - sc += v; - max = qMax(max, qAbs(v)); - } - sc = max * (sc > 0. ? 1. : -1); - QVector3D axe_vector; - foreach (int a, axis) - axe_vector[a] = 1.; - foreach (ObjectBase * o, objects) - o->scale(QVector3D(1,1,1) + (axe_vector * sc)); - QCursor::setPos(view->mapToGlobal(downPos)); - } else - lastPos = e->pos(); - emit view->objectsPositionChanged(); - return; - } - if (selecting_) { - view->renderer_.mouse_rect = QRect(downPos, cpos).normalized(); - return; - } - if (e->buttons().testFlag(Qt::LeftButton)) { - if ((cpos - downPos).manhattanLength() >= QApplication::startDragDistance()) { - selecting_ = true; - canSelect_ = false; - } - return; - } - QRect g_rect(QPoint(), view->size()); - if (mouseRotate_) { - float dx = e->x() - lastPos.x(); - float dy = e->y() - lastPos.y(); - if (e->buttons().testFlag(Qt::MidButton)) { - if (cameraOrbit_) { - view->camera()->orbitZ (dx / 4.f); - view->camera()->orbitXY(dy / 4.f); - } else { - view->camera()->rotateZ(-dx / 4.f); - view->camera()->rotateX(-dy / 4.f); - } - emit view->cameraPosChanged(view->camera()->pos()); - } else if (e->buttons().testFlag(Qt::RightButton)) { - float ad = view->camera()->distance(); - view->camera()->moveLeft(dx / 1000.f * ad); - view->camera()->moveUp (dy / 1000.f * ad); - emit view->cameraPosChanged(view->camera()->pos()); - } - } - if (customMouseMove_) emit view->customMouseMoveEvent(e->pos(), lastPos, e->buttons()); - lastPos = e->pos(); - if (e->buttons() == 0) { - cur_handle = 0; - cur_action = RendererService::haNoAction; - Qt::CursorShape cs = Qt::CrossCursor; - if (view->renderer_.edit_mode) { - uint hid = view->renderer_.rend_selection.id_hover; - cur_handle = (RendererService::HandleMesh)hid; - if (hid >= RendererService::hmMoveX && hid <= RendererService::hmMaxMove ) { - cur_action = RendererService::haMove; - cs = Qt::SizeAllCursor; - } - if (hid >= RendererService::hmRotateX && hid <= RendererService::hmMaxRotate) { - cur_action = RendererService::haRotate; - cs = Qt::PointingHandCursor; - } - if (hid >= RendererService::hmScaleX && hid <= RendererService::hmMaxScale ) { - cur_action = RendererService::haScale; - cs = Qt::SplitHCursor; - } - } - if (cur_action == RendererService::haNoAction) - cur_handle = 0; - view->setCursor(cs); - view->renderer_.rend_service.current_handle = cur_handle; - } - if (grabMouse_) { - QCursor::setPos(view->mapToGlobal(QRect(QPoint(), view->size()).center())); - if (mouse_sec) { - mouse_sec = false; - return; - } - if (mouse_first) { - mouse_first = false; - mouse_sec = true; - return; - } - lastPos = g_rect.center(); - int dx = e->x() - lastPos.x(); - int dy = e->y() - lastPos.y(); - emit view->glMouseMoveEvent(new QMouseEvent(QEvent::MouseMove, QPoint(dx, dy), e->button(), e->buttons(), e->modifiers())); - return; - } - emit view->glMouseMoveEvent(e); -} - - -void MouseController::wheelEvent(QWheelEvent * e) { - if (mouseRotate_) { - if (e->delta() > 0) view->camera()->flyCloser(0.1f); - if (e->delta() < 0) view->camera()->flyFarer(0.1f); - emit view->cameraPosChanged(view->camera()->pos()); - } - emit view->glWheelEvent(e); -} - - -void MouseController::leaveEvent(QEvent * ) { - lastPos = QPoint(-1, -1); - //qDebug() << lastPos; -} - - -void MouseController::mouseDoubleClickEvent(QMouseEvent * e) { - if (e->buttons().testFlag(Qt::MidButton)) - emit view->doubleClick(); -} +/* + QGL MouseController + Ivan Pelipenko peri4ko@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 . +*/ + +#include "mouse_controller.h" +#include "glmesh.h" +#include "qglview.h" +#include +#include +#include + +using namespace QGLEngineShaders; + + +MouseController::MouseController(QGLView * view_): view(view_) { + app_scale = 1; + lastPos = QPoint(-1, -1); + cur_action = RendererService::haNoAction; + sel_button = Qt::LeftButton; + sel_mod = Qt::ControlModifier; + mouse_first = mouseSelect_ = mouseRotate_ = cameraOrbit_ = canSelect_ = true; + grabMouse_ = mouse_sec = selecting_ = customMouseMove_ = false; +} + + +MouseController::~MouseController() { +} + + +void MouseController::resize() { + mouse_first = true; + app_scale = appScale(); +} + + +void MouseController::mouseReleaseEvent(QMouseEvent * e) { + if (cur_action != RendererService::haNoAction) { + mouseMoveEvent(e); + return; + } + bool add_ts = e->modifiers().testFlag(sel_mod); + if (selecting_) { + selecting_ = false; + canSelect_ = true; + view->renderer_.mouse_rect = QRect(); + view->scene_->selectObjects(hov_objects.toList(), add_ts); + return; + } + if (canSelect_ && mouseSelect_) { + if ((lastPos - downPos).manhattanLength() < QApplication::startDragDistance()) { + if (e->button() == Qt::LeftButton) { + //qDebug() << hov_objects << hov_aims; + if (hov_objects.isEmpty() && hov_aims.isEmpty()) { + view->scene()->clearSelection(); + } else { + if (!hov_objects.isEmpty()) + view->scene_->selectObject(hov_objects[0], add_ts); + if (!hov_aims.isEmpty()) { + view->scene_->selectObject(hov_aims[0], add_ts); + hov_aims[0]->selected_aim = true; + } + } + } + if (e->button() == Qt::RightButton) { + if (view->renderer_.edit_mode && !view->scene()->selectedObjects().isEmpty()) + view->context_menu.popup(e->globalPos()); + } + } + } + canSelect_ = e->buttons() == 0; + emit view->glMouseReleaseEvent(e); +} + + +void MouseController::mousePressEvent(QMouseEvent * e) { + downPos = e->pos(); + if (cur_action != RendererService::haNoAction && e->buttons() == Qt::LeftButton) { + return; + } + if (selecting_) { + selecting_ = false; + view->renderer_.mouse_rect = QRect(); + return; + } + if (!QRect(QPoint(), view->size()).contains(e->pos())) return; + lastPos = e->pos(); + downPos = e->pos(); + emit view->glMousePressEvent(e); +} + + +void MouseController::mouseMoveEvent(QMouseEvent * e) { + QPoint cpos = e->pos(); + if (cur_action != RendererService::haNoAction && (e->buttons() == Qt::LeftButton)) { + RendererService & rs(view->renderer_.rend_service); + ObjectBaseList objects = view->scene_->selectedObjects(true); + QVector axis; + switch (cur_action) { + case RendererService::haMove: + if (cur_handle.testFlag(RendererService::hmMoveX)) axis << 0; + if (cur_handle.testFlag(RendererService::hmMoveY)) axis << 1; + if (cur_handle.testFlag(RendererService::hmMoveZ)) axis << 2; + break; + case RendererService::haRotate: + if (cur_handle.testFlag(RendererService::hmRotateX)) axis << 0; + if (cur_handle.testFlag(RendererService::hmRotateY)) axis << 1; + if (cur_handle.testFlag(RendererService::hmRotateZ)) axis << 2; + break; + case RendererService::haScale: + if (cur_handle.testFlag(RendererService::hmScaleX)) axis << 0; + if (cur_handle.testFlag(RendererService::hmScaleY)) axis << 1; + if (cur_handle.testFlag(RendererService::hmScaleZ)) axis << 2; + break; + default: break; + } + QVector scales; + foreach (int a, axis) { + QVector3D axe_vector; axe_vector[a] = 1.; + QMatrix4x4 axis_mat = view->camera()->fullViewMatrix() * rs.axis_mat; + QVector3D center_screen = axis_mat * rs.selection_center; + QVector3D axe_screen = ((axis_mat * (rs.selection_center + axe_vector)) - center_screen).normalized(); + QVector3D mouse_vector(cpos - lastPos); + mouse_vector[1] *= -1.; + if (cur_action == RendererService::haMove) { + double len_scl = 1. / QVector3D(axe_screen.x(), axe_screen.y(), 1.E-6).length(); + mouse_vector /= QVector3D(view->width(), view->height(), 1); + mouse_vector *= -center_screen.z() * len_scl; + axe_vector *= QVector3D::dotProduct(axe_screen, mouse_vector); + QMatrix4x4 pmat; + foreach (ObjectBase * o, objects) { + pmat.setToIdentity(); + if (o->parent()) + pmat = o->parent()->worldTransform().inverted(); + QVector3D dv = pmat.mapVector(axe_vector); + if (o->selected_aim) { + AimedObject * ao = (AimedObject*)o; + ao->setAim(ao->aim() + dv); + } else + o->move(dv); + } + } + if (cur_action == RendererService::haRotate) { + axe_screen.setZ(0.); + axe_screen.normalize(); + QVector3D norm = QVector3D(axe_screen.y(), -axe_screen.x(), 0.); + axe_vector *= QVector3D::dotProduct(mouse_vector, norm) / 2. / app_scale; + foreach (ObjectBase * o, objects) + o->setRotation(o->rotation() + axe_vector); + } + if (cur_action == RendererService::haScale) { + mouse_vector /= QVector3D(view->width(), view->height(), 1); + mouse_vector *= 3. / app_scale; + axe_vector *= QVector3D::dotProduct(axe_screen, mouse_vector); + scales << axe_vector; + } + } + //if (cur_handle >= RendererService::htScaleX && cur_handle <= RendererService::htScaleZ ) cs = Qt::SplitHCursor; + if (cur_action == RendererService::haScale) { + double sc = 0., max = 0.; + foreach (const QVector3D & s, scales) { + double v = QVector3D::dotProduct(s, QVector3D(1,1,1)); + sc += v; + max = qMax(max, qAbs(v)); + } + sc = max * (sc > 0. ? 1. : -1); + QVector3D axe_vector; + foreach (int a, axis) + axe_vector[a] = 1.; + foreach (ObjectBase * o, objects) + o->scale(QVector3D(1,1,1) + (axe_vector * sc)); + QCursor::setPos(view->mapToGlobal(downPos)); + } else + lastPos = e->pos(); + emit view->objectsPositionChanged(); + return; + } + if (selecting_) { + view->renderer_.mouse_rect = QRect(downPos, cpos).normalized(); + return; + } + if (e->buttons().testFlag(Qt::LeftButton)) { + if ((cpos - downPos).manhattanLength() >= QApplication::startDragDistance()) { + selecting_ = true; + canSelect_ = false; + } + return; + } + QRect g_rect(QPoint(), view->size()); + if (mouseRotate_) { + float dx = e->x() - lastPos.x(); + float dy = e->y() - lastPos.y(); + if (e->buttons().testFlag(Qt::MidButton)) { + if (cameraOrbit_) { + view->camera()->orbitZ (dx / 4.f); + view->camera()->orbitXY(dy / 4.f); + } else { + view->camera()->rotateZ(-dx / 4.f); + view->camera()->rotateX(-dy / 4.f); + } + emit view->cameraPosChanged(view->camera()->pos()); + } else if (e->buttons().testFlag(Qt::RightButton)) { + float ad = view->camera()->distance(); + view->camera()->moveLeft(dx / 1000.f * ad); + view->camera()->moveUp (dy / 1000.f * ad); + emit view->cameraPosChanged(view->camera()->pos()); + } + } + if (customMouseMove_) emit view->customMouseMoveEvent(e->pos(), lastPos, e->buttons()); + lastPos = e->pos(); + if (e->buttons() == 0) { + cur_handle = 0; + cur_action = RendererService::haNoAction; + Qt::CursorShape cs = Qt::CrossCursor; + if (view->renderer_.edit_mode) { + uint hid = view->renderer_.rend_selection.id_hover; + cur_handle = (RendererService::HandleMesh)hid; + if (hid >= RendererService::hmMoveX && hid <= RendererService::hmMaxMove ) { + cur_action = RendererService::haMove; + cs = Qt::SizeAllCursor; + } + if (hid >= RendererService::hmRotateX && hid <= RendererService::hmMaxRotate) { + cur_action = RendererService::haRotate; + cs = Qt::PointingHandCursor; + } + if (hid >= RendererService::hmScaleX && hid <= RendererService::hmMaxScale ) { + cur_action = RendererService::haScale; + cs = Qt::SplitHCursor; + } + } + if (cur_action == RendererService::haNoAction) + cur_handle = 0; + view->setCursor(cs); + view->renderer_.rend_service.current_handle = cur_handle; + } + if (grabMouse_) { + QCursor::setPos(view->mapToGlobal(QRect(QPoint(), view->size()).center())); + if (mouse_sec) { + mouse_sec = false; + return; + } + if (mouse_first) { + mouse_first = false; + mouse_sec = true; + return; + } + lastPos = g_rect.center(); + int dx = e->x() - lastPos.x(); + int dy = e->y() - lastPos.y(); + emit view->glMouseMoveEvent(new QMouseEvent(QEvent::MouseMove, QPoint(dx, dy), e->button(), e->buttons(), e->modifiers())); + return; + } + emit view->glMouseMoveEvent(e); +} + + +void MouseController::wheelEvent(QWheelEvent * e) { + if (mouseRotate_) { + if (e->delta() > 0) view->camera()->flyCloser(0.1f); + if (e->delta() < 0) view->camera()->flyFarer(0.1f); + emit view->cameraPosChanged(view->camera()->pos()); + } + emit view->glWheelEvent(e); +} + + +void MouseController::leaveEvent(QEvent * ) { + lastPos = QPoint(-1, -1); + //qDebug() << lastPos; +} + + +void MouseController::mouseDoubleClickEvent(QMouseEvent * e) { + if (e->buttons().testFlag(Qt::MidButton)) + emit view->doubleClick(); +} diff --git a/qglengine/mouse_controller.h b/qglengine/mouse_controller.h index 2c93986..310fe45 100644 --- a/qglengine/mouse_controller.h +++ b/qglengine/mouse_controller.h @@ -1,84 +1,84 @@ -/* - QGL MouseController - Ivan Pelipenko peri4ko@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 . -*/ - -#ifndef MOUSE_CONTROLLER_H -#define MOUSE_CONTROLLER_H - -#include "glprimitives.h" -#include "glcamera.h" -#include "renderer_service.h" -#include -#include - - -class MouseController: public QObject -{ - friend class QGLView; - friend class RendererSelection; - Q_OBJECT -public: - MouseController(QGLView * view_); - virtual ~MouseController(); - - bool isGrabMouseEnabled() const {return grabMouse_;} - bool isMouseRotateEnabled() const {return mouseRotate_;} - bool isMouseSelectionEnabled() const {return mouseSelect_;} - bool isCameraOrbit() const {return cameraOrbit_;} - - Qt::MouseButton selectionButton() const {return sel_button;} - Qt::KeyboardModifier selectionModifier() const {return sel_mod;} - - void setSelectionButton(Qt::MouseButton v) {sel_button = v;} - void setSelectionModifier(Qt::KeyboardModifier v) {sel_mod = v;} - -protected: - void resize(); - void mousePressEvent(QMouseEvent * e); - void mouseMoveEvent(QMouseEvent * e); - void mouseReleaseEvent(QMouseEvent * e); - void wheelEvent(QWheelEvent * e); - void leaveEvent(QEvent * ); - void mouseDoubleClickEvent(QMouseEvent * e); - -private: - QGLView * view; - QPoint lastPos, downPos; - QSet keys_; - QVector hov_objects, hov_aims; - Qt::MouseButton sel_button; - Qt::KeyboardModifier sel_mod; - RendererService::HandleAction cur_action; - QFlags cur_handle; - float app_scale; - bool grabMouse_, mouse_first, mouseRotate_, mouseSelect_, customMouseMove_, canSelect_; - bool cameraOrbit_, selecting_, mouse_sec; - -private slots: - -public slots: - void setGrabMouseEnabled(const bool & arg) {grabMouse_ = arg; mouse_first = true;} - void setMouseRotateEnabled(const bool & arg) {mouseRotate_ = arg;} - void setMouseSelectionEnabled(const bool & arg) {mouseSelect_ = arg;} - void setCustomMouseMove(const bool & arg) {customMouseMove_ = arg;} - void setCameraOrbit(const bool & arg) {cameraOrbit_ = arg;} - -signals: - -}; - -#endif // QGLVIEW_H +/* + QGL MouseController + Ivan Pelipenko peri4ko@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 . +*/ + +#ifndef MOUSE_CONTROLLER_H +#define MOUSE_CONTROLLER_H + +#include "glprimitives.h" +#include "glcamera.h" +#include "renderer_service.h" +#include +#include + + +class MouseController: public QObject +{ + friend class QGLView; + friend class RendererSelection; + Q_OBJECT +public: + MouseController(QGLView * view_); + virtual ~MouseController(); + + bool isGrabMouseEnabled() const {return grabMouse_;} + bool isMouseRotateEnabled() const {return mouseRotate_;} + bool isMouseSelectionEnabled() const {return mouseSelect_;} + bool isCameraOrbit() const {return cameraOrbit_;} + + Qt::MouseButton selectionButton() const {return sel_button;} + Qt::KeyboardModifier selectionModifier() const {return sel_mod;} + + void setSelectionButton(Qt::MouseButton v) {sel_button = v;} + void setSelectionModifier(Qt::KeyboardModifier v) {sel_mod = v;} + +protected: + void resize(); + void mousePressEvent(QMouseEvent * e); + void mouseMoveEvent(QMouseEvent * e); + void mouseReleaseEvent(QMouseEvent * e); + void wheelEvent(QWheelEvent * e); + void leaveEvent(QEvent * ); + void mouseDoubleClickEvent(QMouseEvent * e); + +private: + QGLView * view; + QPoint lastPos, downPos; + QSet keys_; + QVector hov_objects, hov_aims; + Qt::MouseButton sel_button; + Qt::KeyboardModifier sel_mod; + RendererService::HandleAction cur_action; + QFlags cur_handle; + float app_scale; + bool grabMouse_, mouse_first, mouseRotate_, mouseSelect_, customMouseMove_, canSelect_; + bool cameraOrbit_, selecting_, mouse_sec; + +private slots: + +public slots: + void setGrabMouseEnabled(const bool & arg) {grabMouse_ = arg; mouse_first = true;} + void setMouseRotateEnabled(const bool & arg) {mouseRotate_ = arg;} + void setMouseSelectionEnabled(const bool & arg) {mouseSelect_ = arg;} + void setCustomMouseMove(const bool & arg) {customMouseMove_ = arg;} + void setCameraOrbit(const bool & arg) {cameraOrbit_ = arg;} + +signals: + +}; + +#endif // QGLVIEW_H diff --git a/qglengine/openglwindow.cpp b/qglengine/openglwindow.cpp index 8b29356..96c0b4b 100644 --- a/qglengine/openglwindow.cpp +++ b/qglengine/openglwindow.cpp @@ -1,113 +1,113 @@ -/* - QGL OpenGLWindow - Ivan Pelipenko peri4ko@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 . -*/ - -#include "openglwindow.h" -#include -#include -#include -#include - - -OpenGLWindow::OpenGLWindow(QWindow *parent) - : QWindow(parent) - , m_context(nullptr) - , m_device(nullptr) -{ - setFlags(flags() | Qt::FramelessWindowHint); - setSurfaceType(QWindow::OpenGLSurface); - QSurfaceFormat format = QSurfaceFormat::defaultFormat(); -// qDebug() << format; -#ifdef QT_OPENGL_ES_2 - format.setRenderableType(QSurfaceFormat::OpenGLES); -#else - if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { - format.setVersion(4, 0); - format.setProfile(QSurfaceFormat::CoreProfile); - } -#endif - format.setDepthBufferSize(24); - format.setSamples(8); -// format.setStencilBufferSize(8); - setFormat(format); - QSurfaceFormat::setDefaultFormat(format); -} - - -OpenGLWindow::~OpenGLWindow() { - delete m_device; -} - - -void OpenGLWindow::render(QPainter *painter) { -} - - -void OpenGLWindow::initialize() { -} - - -void OpenGLWindow::render() { -// if (!m_device) m_device = new QOpenGLPaintDevice; -// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); -// m_device->setSize(size() * devicePixelRatio()); -// m_device->setDevicePixelRatio(devicePixelRatio()); -// QPainter painter(m_device); -// render(&painter); -} - - -void OpenGLWindow::renderLater() { - requestUpdate(); -} - - -bool OpenGLWindow::event(QEvent *event) { - switch (event->type()) { - case QEvent::UpdateRequest: - renderNow(); - return true; - default: - return QWindow::event(event); - } -} - - -void OpenGLWindow::exposeEvent(QExposeEvent *event) { - if (isExposed()) renderNow(); -} - - -void OpenGLWindow::renderNow() { - if (!isExposed()) - return; - bool needsInitialize = false; - if (!m_context) { - m_context = new QOpenGLContext(this); - m_context->setFormat(requestedFormat()); - m_context->create(); - needsInitialize = true; - } - m_context->makeCurrent(this); - if (needsInitialize) { - initializeOpenGLFunctions(); - initialize(); - } - render(); - m_context->swapBuffers(this); -} - +/* + QGL OpenGLWindow + Ivan Pelipenko peri4ko@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 . +*/ + +#include "openglwindow.h" +#include +#include +#include +#include + + +OpenGLWindow::OpenGLWindow(QWindow *parent) + : QWindow(parent) + , m_context(nullptr) + , m_device(nullptr) +{ + setFlags(flags() | Qt::FramelessWindowHint); + setSurfaceType(QWindow::OpenGLSurface); + QSurfaceFormat format = QSurfaceFormat::defaultFormat(); +// qDebug() << format; +#ifdef QT_OPENGL_ES_2 + format.setRenderableType(QSurfaceFormat::OpenGLES); +#else + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { + format.setVersion(4, 0); + format.setProfile(QSurfaceFormat::CoreProfile); + } +#endif + format.setDepthBufferSize(24); + format.setSamples(8); +// format.setStencilBufferSize(8); + setFormat(format); + QSurfaceFormat::setDefaultFormat(format); +} + + +OpenGLWindow::~OpenGLWindow() { + delete m_device; +} + + +void OpenGLWindow::render(QPainter *painter) { +} + + +void OpenGLWindow::initialize() { +} + + +void OpenGLWindow::render() { +// if (!m_device) m_device = new QOpenGLPaintDevice; +// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); +// m_device->setSize(size() * devicePixelRatio()); +// m_device->setDevicePixelRatio(devicePixelRatio()); +// QPainter painter(m_device); +// render(&painter); +} + + +void OpenGLWindow::renderLater() { + requestUpdate(); +} + + +bool OpenGLWindow::event(QEvent *event) { + switch (event->type()) { + case QEvent::UpdateRequest: + renderNow(); + return true; + default: + return QWindow::event(event); + } +} + + +void OpenGLWindow::exposeEvent(QExposeEvent *event) { + if (isExposed()) renderNow(); +} + + +void OpenGLWindow::renderNow() { + if (!isExposed()) + return; + bool needsInitialize = false; + if (!m_context) { + m_context = new QOpenGLContext(this); + m_context->setFormat(requestedFormat()); + m_context->create(); + needsInitialize = true; + } + m_context->makeCurrent(this); + if (needsInitialize) { + initializeOpenGLFunctions(); + initialize(); + } + render(); + m_context->swapBuffers(this); +} + diff --git a/qglengine/openglwindow.h b/qglengine/openglwindow.h index 2110b7c..47501f7 100644 --- a/qglengine/openglwindow.h +++ b/qglengine/openglwindow.h @@ -1,54 +1,54 @@ -/* - QGL OpenGLWindow - Ivan Pelipenko peri4ko@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 . -*/ - -#include -#include - -class QPainter; -class QOpenGLContext; -class QOpenGLPaintDevice; - - -class OpenGLWindow: public QWindow, protected QOpenGLExtraFunctions -{ - Q_OBJECT -public: - explicit OpenGLWindow(QWindow *parent = nullptr); - ~OpenGLWindow(); - - virtual void render(QPainter *painter); - virtual void render(); - - virtual void initialize(); - - QOpenGLContext * context() {return m_context;} - -public slots: - void renderLater(); - void renderNow(); - -protected: - bool event(QEvent *event) override; - - void exposeEvent(QExposeEvent *event) override; - -private: - QOpenGLContext *m_context; - QOpenGLPaintDevice *m_device; -}; - +/* + QGL OpenGLWindow + Ivan Pelipenko peri4ko@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 . +*/ + +#include +#include + +class QPainter; +class QOpenGLContext; +class QOpenGLPaintDevice; + + +class OpenGLWindow: public QWindow, protected QOpenGLExtraFunctions +{ + Q_OBJECT +public: + explicit OpenGLWindow(QWindow *parent = nullptr); + ~OpenGLWindow(); + + virtual void render(QPainter *painter); + virtual void render(); + + virtual void initialize(); + + QOpenGLContext * context() {return m_context;} + +public slots: + void renderLater(); + void renderNow(); + +protected: + bool event(QEvent *event) override; + + void exposeEvent(QExposeEvent *event) override; + +private: + QOpenGLContext *m_context; + QOpenGLPaintDevice *m_device; +}; + diff --git a/qglengine/plugin/CMakeLists.txt b/qglengine/plugin/CMakeLists.txt index 22bcdc5..355566a 100644 --- a/qglengine/plugin/CMakeLists.txt +++ b/qglengine/plugin/CMakeLists.txt @@ -1,18 +1,18 @@ -if (DESIGNER_PLUGINS) - if (NOT Qt5) - message(WARNING "Building ${PROJECT_NAME} available only on Qt5!") - else() - project(qglengine_plugin) - include_directories("..") - add_definitions(-DQT_PLUGIN) - add_definitions(-DQT_NO_DEBUG) - add_definitions(-DQT_SHARED) - add_definitions(-DQDESIGNER_EXPORT_WIDGETS) - find_qt(Qt5 Core Designer Gui Widgets OpenGL) - qt_sources(SRC) - qt_wrap(${SRC} CPPS out_CPP QMS out_QM) - qt_add_library(${PROJECT_NAME} SHARED out_CPP) - qt_target_link_libraries(${PROJECT_NAME} qglengine) - qt_install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION QtPlugins/designer) - endif() -endif() +if (DESIGNER_PLUGINS) + if (NOT Qt5) + message(WARNING "Building ${PROJECT_NAME} available only on Qt5!") + else() + project(qglengine_plugin) + include_directories("..") + add_definitions(-DQT_PLUGIN) + add_definitions(-DQT_NO_DEBUG) + add_definitions(-DQT_SHARED) + add_definitions(-DQDESIGNER_EXPORT_WIDGETS) + find_qt(Qt5 Core Designer Gui Widgets OpenGL) + qt_sources(SRC) + qt_wrap(${SRC} CPPS out_CPP QMS out_QM) + qt_add_library(${PROJECT_NAME} SHARED out_CPP) + qt_target_link_libraries(${PROJECT_NAME} qglengine) + qt_install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION QtPlugins/designer) + endif() +endif() diff --git a/qglengine/qglview.cpp b/qglengine/qglview.cpp index cbff22e..d48d666 100644 --- a/qglengine/qglview.cpp +++ b/qglengine/qglview.cpp @@ -1,299 +1,299 @@ -/* - QGLView - Ivan Pelipenko peri4ko@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 . -*/ - -#include "qglview.h" -#include "glmesh.h" -#include "gltexture_manager.h" -#include -#include -#include -#include -#include - -using namespace QGLEngineShaders; - - -QGLView::QGLView(): OpenGLWindow(), renderer_(this), mouse(this) { - setIcon(QIcon(":/icons/qglview.png")); - deleting_ = false; - timer = 0; - need_init_ = is_first_draw = true; - backColor_ = Qt::darkGray; - hoverHaloColor_ = QColor(195, 140, 255); - selectionHaloColor_ = QColor(175, 255, 140); - ambientColor_ = QColor(10, 10, 10); - lineWidth_ = 1.; - max_anisotropic = 1; - max_texture_chanels = 8; - lightEnabled_ = true; - shaders_supported = false; - fps_cnt = 0; - fps_tm = fps_ = 0.; - fogColor_ = Qt::darkGray; - fogDensity_ = 0.; - fogDecay_ = 10.; - hoverHaloFill_ = selectionHaloFill_ = 0.15f; - //lmode = Simple; - setFeature(qglFXAA, false); - setFeature(qglAnisotropicLevel, 8); - setFeature(qglEyeAccomodationEnabled, false); - setFeature(qglEyeAccomodationTime, 16.); - setFeature(qglEyeAccomodationMaxSpeed, 0.2); - setFeature(qglBloomEnabled, false); - setFeature(qglBloomThreshold, 0.9); - setFeature(qglBloomFactor, 1.); - setFeature(qglBloomRadius, 8); - setFeature(qglMotionBlurEnabled, false); - setFeature(qglMotionBlurFactor, 1.); - setFeature(qglMotionBlurSteps, 8); - setFeature(qglShadowsEnabled, false); - setFeature(qglShadowsMapSize, 512); - setFeature(qglShadowsSoftEnabled, true); - setFeature(qglReflectionsEnabled, false); - setFeature(qglReflectionsBlur, true); - setFeature(qglSSAOEnabled, false); - setFeature(qglSSAORadius, 5); - setFeature(qglDepthOfFieldEnabled, false); - setFeature(qglDepthOfFieldAutoFocusEnabled, true); - setFeature(qglDepthOfFieldAutoFocusSpeed, 0.1); - setFeature(qglDepthOfFieldFocus, 1.); - setFeature(qglDepthOfFieldDiaphragm, 8.); - hoverHalo_ = selectionHalo_ = true; - fogEnabled_ = is_init = shaders_bind = changed_ = false; - rmode = ObjectBase::Fill; -// sel_pen = QPen(Qt::black, 1, Qt::DashLine); -// sel_brush = QBrush(QColor(170, 100, 255, 120)); - scene_ = new Scene(); - connect(scene_, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged())); - connect(scene_, SIGNAL(__destroyed()), this, SLOT(__destroyed())); - connect(scene_, SIGNAL(__objectDeleted(ObjectBase*)), this, SLOT(__objectDeleted(ObjectBase*))); - default_camera = new Camera(); - default_camera->setPos(QVector3D(2, 2, 2)); - default_camera->setAim(QVector3D()); - camera_ = default_camera; -// qDebug() << camera_->aim(); - default_camera->setName("Camera"); - emit cameraPosChanged(default_camera->pos()); - //camera().aim_ = camera().pos_; - ktm_.restart(); - - //Mesh * m = Primitive::torus(100, 40, 1., 0.4, 360); - Mesh * m = Primitive::cube(10, 10, 10); - m->flipNormals(); - //QMatrix4x4 mat; - //mat.rotate(90, 0,1,0); - //mat.translate(0, 0, 2); - //mat.rotate(180, 1,0,0); - //m->transformPoints(mat); - ObjectBase * o = new ObjectBase(m); - o->setColor(Qt::cyan); - scene()->addObject(o); - delete m; - -} - - -QGLView::~QGLView() { - deleting_ = true; - stop(); - scene_->clear(); - delete scene_; - delete default_camera; -} - - -void QGLView::stop() { - if (timer) killTimer(timer); -} - - -void QGLView::start(float freq) { - timer = startTimer(freq <= 0.f ? 0 : int(1000.f / freq)); -} - - -QList QGLView::selectedLights() const { - QList ret; - ObjectBaseList sol = scene_->selectedObjects(); - foreach (ObjectBase * o, sol) - if (o->type() == ObjectBase::glLight) - ret << (Light*)o; - return ret; -} - - -QList QGLView::selectedCameras() const { - QList ret; - ObjectBaseList sol = scene_->selectedObjects(); - foreach (ObjectBase * o, sol) - if (o->type() == ObjectBase::glCamera) - ret << (Camera*)o; - return ret; -} - - - -void QGLView::resizeEvent(QResizeEvent * e) { - renderLater(); - mouse.resize(); -} - - -void QGLView::timerEvent(QTimerEvent *) { - renderNow(); - //if (ktm_.elapsed() < QApplication::keyboardInputInterval()) return; - Qt::KeyboardModifiers km = QApplication::keyboardModifiers(); - foreach (int i, keys_) - emit keyEvent((Qt::Key)i, km); -} - - -void QGLView::render() { - resizeGL(width(), height()); - emit glBeginPaint(); - renderer_.mouse_pos = mapFromGlobal(QCursor::pos()); - renderer_.renderScene(); - emit glEndPaint(); - fps_tm += time.elapsed(); - time.restart(); - fps_cnt++; - if (fps_tm < 1000.) return; - fps_ = fps_cnt / fps_tm * 1000.; - fps_tm = 0.; - fps_cnt = 0; -} - - -void QGLView::initialize() { - checkCaps(); - glPixelStorei(GL_PACK_ALIGNMENT, 1); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glDisable(GL_MULTISAMPLE); - glDisable(GL_BLEND); - glEnable(GL_TEXTURE_2D); - glEnable(GL_TEXTURE_CUBE_MAP); - glEnable(GL_TEXTURE_MAX_ANISOTROPY_EXT); - glEnable(GL_CULL_FACE); - glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); - glCullFace(GL_BACK); - renderer_.reloadShaders(); - renderer_.init(width(), height()); - is_init = true; - need_init_ = false; - emit glInitializeDone(); -} - - -void QGLView::checkCaps() { - glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropic); - shaders_supported = QOpenGLShaderProgram::hasOpenGLShaderPrograms(); -} - - -void QGLView::__destroyed() { - renderer_.rend_mat.mat_thumbnails.clear(); - mouse.hov_objects.clear(); -} - - -void QGLView::__objectDeleted(ObjectBase * o) { - if (o == camera_) - setDefaultCamera(); -} - - -void QGLView::resizeGL(int width, int height) { - if (!is_init) return; - if (width <= 0 || height <= 0) return; - if (prev_size == QSize(width, height)) return; - prev_size = QSize(width, height); - aspect = float(width) / float(height); - renderer_.resize(width, height); - //qDebug() << "resize" << width << height; - iaspect = (aspect == 0.f) ? 0. : 1 / aspect; - glViewport(0, 0, width, height); - emit glResize(width, height); -} - - -void QGLView::keyPressEvent(QKeyEvent * e) { - emit glKeyPressEvent(e); - if (e->key() > 0) keys_.insert(e->key()); - if (e->key() == Qt::Key_F11) { - emit doubleClick(); - } -} - - -void QGLView::keyReleaseEvent(QKeyEvent * e) { - emit glKeyReleaseEvent(e); - keys_.remove(e->key()); -} - - -void QGLView::focusOutEvent(QFocusEvent *) { - keys_.clear(); -} - - -void QGLView::focusOn(const Box3D & bb) { - if (bb.isEmpty() || !camera()) return; - double size = qMax(qMax(bb.width, bb.length), bb.height); - camera()->setAim(bb.center()); - camera()->flyToDistance(size * 1.25); -} - - -QByteArray QGLView::saveCamera() { - ChunkStream cs; - const Camera * c = camera(); - cs.add(1, c->pos()).add(2, c->aim()).add(3, c->rotation()).add(4, c->FOV()); - return cs.data(); -} - - -void QGLView::restoreCamera(const QByteArray & ba) { - if (ba.isEmpty()) return; - Camera * c = camera(); - QVector3D pos(c->pos()), aim(c->aim()), ang(c->rotation()); - float fov(c->FOV()); - ChunkStream cs(ba); - cs.readAll(); - cs.get(1, pos).get(2, aim).get(3, ang).get(4, fov); - camera()->setPos(pos); - camera()->setAim(aim); - camera()->setAngles(ang); - camera()->setFOV(fov); -} - - -QByteArray QGLView::saveFeatures() { - QByteArray ba; - QDataStream ds(&ba, QIODevice::WriteOnly); - ds << features_; - return ba; -} - - -void QGLView::restoreFeatures(const QByteArray & ba) { - QHash f; - QDataStream ds(ba); - ds >> f; - features_ = f; -} +/* + QGLView + Ivan Pelipenko peri4ko@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 . +*/ + +#include "qglview.h" +#include "glmesh.h" +#include "gltexture_manager.h" +#include +#include +#include +#include +#include + +using namespace QGLEngineShaders; + + +QGLView::QGLView(): OpenGLWindow(), renderer_(this), mouse(this) { + setIcon(QIcon(":/icons/qglview.png")); + deleting_ = false; + timer = 0; + need_init_ = is_first_draw = true; + backColor_ = Qt::darkGray; + hoverHaloColor_ = QColor(195, 140, 255); + selectionHaloColor_ = QColor(175, 255, 140); + ambientColor_ = QColor(10, 10, 10); + lineWidth_ = 1.; + max_anisotropic = 1; + max_texture_chanels = 8; + lightEnabled_ = true; + shaders_supported = false; + fps_cnt = 0; + fps_tm = fps_ = 0.; + fogColor_ = Qt::darkGray; + fogDensity_ = 0.; + fogDecay_ = 10.; + hoverHaloFill_ = selectionHaloFill_ = 0.15f; + //lmode = Simple; + setFeature(qglFXAA, false); + setFeature(qglAnisotropicLevel, 8); + setFeature(qglEyeAccomodationEnabled, false); + setFeature(qglEyeAccomodationTime, 16.); + setFeature(qglEyeAccomodationMaxSpeed, 0.2); + setFeature(qglBloomEnabled, false); + setFeature(qglBloomThreshold, 0.9); + setFeature(qglBloomFactor, 1.); + setFeature(qglBloomRadius, 8); + setFeature(qglMotionBlurEnabled, false); + setFeature(qglMotionBlurFactor, 1.); + setFeature(qglMotionBlurSteps, 8); + setFeature(qglShadowsEnabled, false); + setFeature(qglShadowsMapSize, 512); + setFeature(qglShadowsSoftEnabled, true); + setFeature(qglReflectionsEnabled, false); + setFeature(qglReflectionsBlur, true); + setFeature(qglSSAOEnabled, false); + setFeature(qglSSAORadius, 5); + setFeature(qglDepthOfFieldEnabled, false); + setFeature(qglDepthOfFieldAutoFocusEnabled, true); + setFeature(qglDepthOfFieldAutoFocusSpeed, 0.1); + setFeature(qglDepthOfFieldFocus, 1.); + setFeature(qglDepthOfFieldDiaphragm, 8.); + hoverHalo_ = selectionHalo_ = true; + fogEnabled_ = is_init = shaders_bind = changed_ = false; + rmode = ObjectBase::Fill; +// sel_pen = QPen(Qt::black, 1, Qt::DashLine); +// sel_brush = QBrush(QColor(170, 100, 255, 120)); + scene_ = new Scene(); + connect(scene_, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged())); + connect(scene_, SIGNAL(__destroyed()), this, SLOT(__destroyed())); + connect(scene_, SIGNAL(__objectDeleted(ObjectBase*)), this, SLOT(__objectDeleted(ObjectBase*))); + default_camera = new Camera(); + default_camera->setPos(QVector3D(2, 2, 2)); + default_camera->setAim(QVector3D()); + camera_ = default_camera; +// qDebug() << camera_->aim(); + default_camera->setName("Camera"); + emit cameraPosChanged(default_camera->pos()); + //camera().aim_ = camera().pos_; + ktm_.restart(); + + //Mesh * m = Primitive::torus(100, 40, 1., 0.4, 360); + Mesh * m = Primitive::cube(10, 10, 10); + m->flipNormals(); + //QMatrix4x4 mat; + //mat.rotate(90, 0,1,0); + //mat.translate(0, 0, 2); + //mat.rotate(180, 1,0,0); + //m->transformPoints(mat); + ObjectBase * o = new ObjectBase(m); + o->setColor(Qt::cyan); + scene()->addObject(o); + delete m; + +} + + +QGLView::~QGLView() { + deleting_ = true; + stop(); + scene_->clear(); + delete scene_; + delete default_camera; +} + + +void QGLView::stop() { + if (timer) killTimer(timer); +} + + +void QGLView::start(float freq) { + timer = startTimer(freq <= 0.f ? 0 : int(1000.f / freq)); +} + + +QList QGLView::selectedLights() const { + QList ret; + ObjectBaseList sol = scene_->selectedObjects(); + foreach (ObjectBase * o, sol) + if (o->type() == ObjectBase::glLight) + ret << (Light*)o; + return ret; +} + + +QList QGLView::selectedCameras() const { + QList ret; + ObjectBaseList sol = scene_->selectedObjects(); + foreach (ObjectBase * o, sol) + if (o->type() == ObjectBase::glCamera) + ret << (Camera*)o; + return ret; +} + + + +void QGLView::resizeEvent(QResizeEvent * e) { + renderLater(); + mouse.resize(); +} + + +void QGLView::timerEvent(QTimerEvent *) { + renderNow(); + //if (ktm_.elapsed() < QApplication::keyboardInputInterval()) return; + Qt::KeyboardModifiers km = QApplication::keyboardModifiers(); + foreach (int i, keys_) + emit keyEvent((Qt::Key)i, km); +} + + +void QGLView::render() { + resizeGL(width(), height()); + emit glBeginPaint(); + renderer_.mouse_pos = mapFromGlobal(QCursor::pos()); + renderer_.renderScene(); + emit glEndPaint(); + fps_tm += time.elapsed(); + time.restart(); + fps_cnt++; + if (fps_tm < 1000.) return; + fps_ = fps_cnt / fps_tm * 1000.; + fps_tm = 0.; + fps_cnt = 0; +} + + +void QGLView::initialize() { + checkCaps(); + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glDisable(GL_MULTISAMPLE); + glDisable(GL_BLEND); + glEnable(GL_TEXTURE_2D); + glEnable(GL_TEXTURE_CUBE_MAP); + glEnable(GL_TEXTURE_MAX_ANISOTROPY_EXT); + glEnable(GL_CULL_FACE); + glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); + glCullFace(GL_BACK); + renderer_.reloadShaders(); + renderer_.init(width(), height()); + is_init = true; + need_init_ = false; + emit glInitializeDone(); +} + + +void QGLView::checkCaps() { + glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropic); + shaders_supported = QOpenGLShaderProgram::hasOpenGLShaderPrograms(); +} + + +void QGLView::__destroyed() { + renderer_.rend_mat.mat_thumbnails.clear(); + mouse.hov_objects.clear(); +} + + +void QGLView::__objectDeleted(ObjectBase * o) { + if (o == camera_) + setDefaultCamera(); +} + + +void QGLView::resizeGL(int width, int height) { + if (!is_init) return; + if (width <= 0 || height <= 0) return; + if (prev_size == QSize(width, height)) return; + prev_size = QSize(width, height); + aspect = float(width) / float(height); + renderer_.resize(width, height); + //qDebug() << "resize" << width << height; + iaspect = (aspect == 0.f) ? 0. : 1 / aspect; + glViewport(0, 0, width, height); + emit glResize(width, height); +} + + +void QGLView::keyPressEvent(QKeyEvent * e) { + emit glKeyPressEvent(e); + if (e->key() > 0) keys_.insert(e->key()); + if (e->key() == Qt::Key_F11) { + emit doubleClick(); + } +} + + +void QGLView::keyReleaseEvent(QKeyEvent * e) { + emit glKeyReleaseEvent(e); + keys_.remove(e->key()); +} + + +void QGLView::focusOutEvent(QFocusEvent *) { + keys_.clear(); +} + + +void QGLView::focusOn(const Box3D & bb) { + if (bb.isEmpty() || !camera()) return; + double size = qMax(qMax(bb.width, bb.length), bb.height); + camera()->setAim(bb.center()); + camera()->flyToDistance(size * 1.25); +} + + +QByteArray QGLView::saveCamera() { + ChunkStream cs; + const Camera * c = camera(); + cs.add(1, c->pos()).add(2, c->aim()).add(3, c->rotation()).add(4, c->FOV()); + return cs.data(); +} + + +void QGLView::restoreCamera(const QByteArray & ba) { + if (ba.isEmpty()) return; + Camera * c = camera(); + QVector3D pos(c->pos()), aim(c->aim()), ang(c->rotation()); + float fov(c->FOV()); + ChunkStream cs(ba); + cs.readAll(); + cs.get(1, pos).get(2, aim).get(3, ang).get(4, fov); + camera()->setPos(pos); + camera()->setAim(aim); + camera()->setAngles(ang); + camera()->setFOV(fov); +} + + +QByteArray QGLView::saveFeatures() { + QByteArray ba; + QDataStream ds(&ba, QIODevice::WriteOnly); + ds << features_; + return ba; +} + + +void QGLView::restoreFeatures(const QByteArray & ba) { + QHash f; + QDataStream ds(ba); + ds >> f; + features_ = f; +} diff --git a/qglengine/qglview.h b/qglengine/qglview.h index 8f4d40e..66a64a5 100644 --- a/qglengine/qglview.h +++ b/qglengine/qglview.h @@ -1,293 +1,293 @@ -/* - QGLView - Ivan Pelipenko peri4ko@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 . -*/ - -#ifndef QGLVIEW_H -#define QGLVIEW_H - -#include "openglwindow.h" -#include "glframebuffer.h" -#include "glprimitives.h" -#include "glcamera.h" -#include "glrendererbase.h" -#include "glscene.h" -#include "renderer.h" -#include "mouse_controller.h" -#include -#include - - -class QGLView: public OpenGLWindow -{ - friend class MouseController; - friend class GLRendererBase; - friend class TextureManager; - friend class ObjectBase; - friend class Scene; - friend class RendererBase; - friend class Renderer; - friend class RendererMaterial; - friend class RendererService; - friend class RendererSelection; - friend class TonemappingProc; - Q_OBJECT - Q_PROPERTY (QColor backColor READ backColor WRITE setBackColor) - Q_PROPERTY (float lineWidth READ lineWidth WRITE setLineWidth) - Q_PROPERTY (float FOV READ FOV WRITE setFOV) - Q_PROPERTY (float depthStart READ depthStart WRITE setDepthStart) - Q_PROPERTY (float gamma READ gamma WRITE setGamma) - Q_PROPERTY (bool autoExposure READ autoExposure WRITE setAutoExposure) - Q_PROPERTY (QColor ambientColor READ ambientColor WRITE setAmbientColor) - Q_PROPERTY (QColor fogColor READ fogColor WRITE setFogColor) - Q_PROPERTY (bool fogEnabled READ isFogEnabled WRITE setFogEnabled) - Q_PROPERTY (float fogDensity READ fogDensity WRITE setFogDensity) - Q_PROPERTY (float fogDecay READ fogDecay WRITE setFogDecay) - Q_PROPERTY (int renderMode READ renderMode WRITE setRenderMode) - Q_PROPERTY (bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled) - Q_PROPERTY (bool mouseRotate READ isMouseRotateEnabled WRITE setMouseRotateEnabled) - Q_PROPERTY (bool mouseSelection READ isMouseSelectionEnabled WRITE setMouseSelectionEnabled) - Q_PROPERTY (bool cameraOrbit READ isCameraOrbit WRITE setCameraOrbit) - Q_PROPERTY (bool hoverHalo READ isHoverHaloEnabled WRITE setHoverHaloEnabled) - Q_PROPERTY (QColor hoverHaloColor READ hoverHaloColor WRITE setHoverHaloColor) - Q_PROPERTY (float hoverHaloFillAlpha READ hoverHaloFillAlpha WRITE setHoverHaloFillAlpha) - Q_PROPERTY (bool selectionHalo READ isSelectionHaloEnabled WRITE setSelectionHaloEnabled) - Q_PROPERTY (QColor selectionHaloColor READ selectionHaloColor WRITE setSelectionHaloColor) - Q_PROPERTY (float selectionHaloFillAlpha READ selectionHaloFillAlpha WRITE setSelectionHaloFillAlpha) - Q_PROPERTY (Qt::MouseButton selectionButton READ selectionButton WRITE setSelectionButton) - Q_PROPERTY (Qt::KeyboardModifier selectionModifier READ selectionModifier WRITE setSelectionModifier) - Q_PROPERTY (Scene::SelectionMode selectionMode READ selectionMode WRITE setSelectionMode) - -public: - QGLView(); - virtual ~QGLView(); - - enum CameraLightMode { - clmOff, - clmAuto, - clmOn, - }; - - enum Feature { - qglFXAA, - qglAnisotropicLevel, - qglEyeAccomodationEnabled, - qglEyeAccomodationTime, - qglEyeAccomodationMaxSpeed, - qglBloomEnabled, - qglBloomThreshold, - qglBloomFactor, - qglBloomRadius, - qglMotionBlurEnabled, - qglMotionBlurFactor, - qglMotionBlurSteps, - qglShadowsEnabled, - qglShadowsMapSize, - qglShadowsSoftEnabled, - qglReflectionsEnabled, - qglReflectionsBlur, - qglSSAOEnabled, - qglSSAORadius, - qglDepthOfFieldEnabled, - qglDepthOfFieldAutoFocusEnabled, - qglDepthOfFieldAutoFocusSpeed, - qglDepthOfFieldFocus, - qglDepthOfFieldDiaphragm - }; - - Q_ENUM(CameraLightMode) - - void stop(); - void start(float freq = 60.); - - QColor backColor() const {return backColor_;} - float lineWidth() const {return lineWidth_;} - float FOV() const {return camera()->fov_;} - float depthStart() const {return camera()->depth_start;} - float currentFPS() const {return fps_;} - float gamma() const {return renderer_.gamma_;} - bool autoExposure() const {return renderer_.tone_proc.enabled;} - int maxAnisotropicLevel() const {return max_anisotropic;} - QString environmentMapFile() const {return renderer_.tex_env.fileHDR();} - - QColor ambientColor() const {return ambientColor_;} - QColor fogColor() const {return fogColor_;} - float fogDensity() const {return fogDensity_;} - float fogDecay() const {return fogDecay_;} - bool isFogEnabled() const {return fogEnabled_;} - bool isLightEnabled() const {return lightEnabled_;} - bool isGrabMouseEnabled() const {return mouse.isGrabMouseEnabled();} - bool isMouseRotateEnabled() const {return mouse.isMouseRotateEnabled();} - bool isMouseSelectionEnabled() const {return mouse.isMouseSelectionEnabled();} - bool isCameraOrbit() const {return mouse.isCameraOrbit();} - bool isHoverHaloEnabled() const {return hoverHalo_;} - QColor hoverHaloColor() const {return hoverHaloColor_;} - float hoverHaloFillAlpha() const {return hoverHaloFill_;} - bool isSelectionHaloEnabled() const {return selectionHalo_;} - QColor selectionHaloColor() const {return selectionHaloColor_;} - float selectionHaloFillAlpha() const {return selectionHaloFill_;} - - QVariant feature(Feature f) const {return features_.value(int(f));} - QVariant setFeature(Feature f, const QVariant & value) {QVariant ret = features_.value(int(f)); features_[int(f)] = value; return ret;} - bool isFeatureEnabled(Feature f) const {return features_[int(f)].toBool();} - - int renderMode() const {return (int)rmode;} - void setRenderMode(int mode) {rmode = (ObjectBase::RenderMode)mode;} - - bool isServiceMode() const {return renderer_.edit_mode;} - void setServiceMode(bool yes) {renderer_.edit_mode = yes;} - - - Scene::SelectionMode selectionMode() const {return scene_->selectionMode();} - Qt::MouseButton selectionButton() const {return mouse.selectionButton();} - Qt::KeyboardModifier selectionModifier() const {return mouse.selectionModifier();} - - void setSelectionMode(Scene::SelectionMode m) {scene_->setSelectionMode(m);} - void setSelectionButton(Qt::MouseButton v) {mouse.setSelectionButton(v);} - void setSelectionModifier(Qt::KeyboardModifier v) {mouse.setSelectionModifier(v);} - - void selectObject(ObjectBase * o, bool add_to_selection = false) {scene_->selectObject(o, add_to_selection);} - void clearSelection() {scene_->clearSelection();} - ObjectBaseList selectedObjects(bool top_only = false) const {return scene_->selectedObjects(top_only);} - QList selectedLights() const; - QList selectedCameras() const; - ObjectBase * selectedObject() const {return scene_->selectedObject();} - - TextureManager * textureManager() {return renderer_.textures_manager;} - void reloadTextures() {renderer_.markReloadTextures();} - - Scene * scene() {return scene_;} - void focusOn(const Box3D & bb); - void setCameraLightMode(CameraLightMode m) {renderer_.setCameraLightMode(m);} - CameraLightMode cameraLightMode() const {return (CameraLightMode)renderer_.cameraLightMode();} - - Camera * camera() {return camera_;} - const Camera * camera() const {return camera_;} - void setCamera(Camera * camera) {camera_ = camera;} - void setDefaultCamera() {camera_ = default_camera;} - QByteArray saveCamera(); - void restoreCamera(const QByteArray & ba); - QByteArray saveFeatures(); - void restoreFeatures(const QByteArray & ba); - - QImage materialThumbnail(Material * m) {return renderer_.materialThumbnail(m);} - void setCurrentAction(RendererService::HandleAction ha) {renderer_.rend_service.setCurrentAction(ha);} - void setContextActions(QList al) {context_menu.clear(); context_menu.addActions(al);} - - GLfloat aspect, iaspect; - Renderer renderer_; - -protected: - void render(); - void resizeEvent(QResizeEvent * e); - - void timerEvent(QTimerEvent * ); - void initialize(); - void resizeGL(int width, int height); - void mousePressEvent(QMouseEvent * e) {mouse.mousePressEvent(e);} - void mouseMoveEvent(QMouseEvent * e) {mouse.mouseMoveEvent(e);} - void mouseReleaseEvent(QMouseEvent * e) {mouse.mouseReleaseEvent(e);} - void wheelEvent(QWheelEvent * e) {mouse.wheelEvent(e);} - void mouseDoubleClickEvent(QMouseEvent * e) {mouse.mouseDoubleClickEvent(e);} - void leaveEvent(QEvent * ); - - void keyPressEvent(QKeyEvent * e); - void keyReleaseEvent(QKeyEvent * e); - void focusOutEvent(QFocusEvent *); - - void checkCaps(); - -private: - void processKeys(); - bool setupViewport(); - - Scene * scene_; - Camera * camera_, * default_camera; - MouseController mouse; - QMenu context_menu; - QSet keys_; - QColor backColor_, fogColor_, ambientColor_, hoverHaloColor_, selectionHaloColor_; - QTime time, ktm_; - GLint max_anisotropic, max_texture_chanels; - ObjectBase::RenderMode rmode; - GLRendererBase::RenderingParameters start_rp; - QHash features_; - QSize prev_size; - float lineWidth_; - float fps_, fps_tm, fogDensity_, fogDecay_; - float hoverHaloFill_, selectionHaloFill_, m_motionBlurFactor; - int timer, fps_cnt, sh_id_loc, deleting_; - bool is_first_draw, is_init, fogEnabled_, lightEnabled_; - bool shaders_supported, changed_, need_init_; - bool hoverHalo_, selectionHalo_, shaders_bind; - -private slots: - void __destroyed(); - void __objectDeleted(ObjectBase * o); - -public slots: - void setBackColor(const QColor & arg) {backColor_ = arg;} - void setLineWidth(const float & arg) {lineWidth_ = arg;} - void setFOV(const float & arg) {camera()->fov_ = arg;} - void setDepthStart(const float & arg) {camera()->depth_start = arg;} - void setGamma(const float & arg) {renderer_.gamma_ = arg;} - void setAutoExposure(bool arg) {renderer_.tone_proc.enabled = arg;} - void setAmbientColor(const QColor & arg) {ambientColor_ = arg;} - void setEnvironmentMapFile(QString file) {renderer_.tex_env.setFileHDR(file); renderer_.recreateMaterialThumbnails(true);} - void setFogColor(const QColor & arg) {fogColor_ = arg;} - void setFogDensity(const float & arg) {fogDensity_ = arg;} - void setFogDecay(const float & arg) {fogDecay_ = arg;} - void setFogEnabled(const bool & arg) {fogEnabled_ = arg;} - void setLightEnabled(const bool & arg) {lightEnabled_ = arg;} - void setGrabMouseEnabled(const bool & arg) {mouse.setGrabMouseEnabled(arg);} - void setMouseRotateEnabled(const bool & arg) {mouse.setMouseRotateEnabled(arg);} - void setMouseSelectionEnabled(const bool & arg) {mouse.setMouseSelectionEnabled(arg);} - void setCustomMouseMove(const bool & arg) {mouse.setCustomMouseMove(arg);} - void setCameraOrbit(const bool & arg) {mouse.setCameraOrbit(arg);} - void setHoverHaloEnabled(const bool & arg) {hoverHalo_ = arg;} - void setHoverHaloColor(const QColor & arg) {hoverHaloColor_ = arg;} - void setHoverHaloFillAlpha(const float & arg) {hoverHaloFill_ = arg;} - void setSelectionHaloEnabled(const bool & arg) {selectionHalo_ = arg;} - void setSelectionHaloColor(const QColor & arg) {selectionHaloColor_ = arg;} - void setSelectionHaloFillAlpha(const float & arg) {selectionHaloFill_ = arg;} - - void reloadShaders() {renderer_.reloadShaders();} - -signals: - void glBeginPaint(); - void glEndPaint(); - void glKeyPressEvent(QKeyEvent * e); - void glKeyReleaseEvent(QKeyEvent * e); - void glMousePressEvent(QMouseEvent * e); - void glMouseMoveEvent(QMouseEvent * e); - void glMouseReleaseEvent(QMouseEvent * e); - void glWheelEvent(QWheelEvent * e); - void glResize(int, int); - void glInitializeDone(); - void cameraPosChanged(QVector3D pos); - void keyEvent(Qt::Key key, Qt::KeyboardModifiers mod); - void customMouseMoveEvent(QPoint curpos, QPoint lastpos, Qt::MouseButtons buttons); - - void hoverChanged(ObjectBase * cur, ObjectBase * prev); - void selectionChanged(); - void objectsPositionChanged(); - void materialsChanged(); - void materialThumbnailCreated(Material*); - void doubleClick(); - -}; - -#endif // QGLVIEW_H +/* + QGLView + Ivan Pelipenko peri4ko@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 . +*/ + +#ifndef QGLVIEW_H +#define QGLVIEW_H + +#include "openglwindow.h" +#include "glframebuffer.h" +#include "glprimitives.h" +#include "glcamera.h" +#include "glrendererbase.h" +#include "glscene.h" +#include "renderer.h" +#include "mouse_controller.h" +#include +#include + + +class QGLView: public OpenGLWindow +{ + friend class MouseController; + friend class GLRendererBase; + friend class TextureManager; + friend class ObjectBase; + friend class Scene; + friend class RendererBase; + friend class Renderer; + friend class RendererMaterial; + friend class RendererService; + friend class RendererSelection; + friend class TonemappingProc; + Q_OBJECT + Q_PROPERTY (QColor backColor READ backColor WRITE setBackColor) + Q_PROPERTY (float lineWidth READ lineWidth WRITE setLineWidth) + Q_PROPERTY (float FOV READ FOV WRITE setFOV) + Q_PROPERTY (float depthStart READ depthStart WRITE setDepthStart) + Q_PROPERTY (float gamma READ gamma WRITE setGamma) + Q_PROPERTY (bool autoExposure READ autoExposure WRITE setAutoExposure) + Q_PROPERTY (QColor ambientColor READ ambientColor WRITE setAmbientColor) + Q_PROPERTY (QColor fogColor READ fogColor WRITE setFogColor) + Q_PROPERTY (bool fogEnabled READ isFogEnabled WRITE setFogEnabled) + Q_PROPERTY (float fogDensity READ fogDensity WRITE setFogDensity) + Q_PROPERTY (float fogDecay READ fogDecay WRITE setFogDecay) + Q_PROPERTY (int renderMode READ renderMode WRITE setRenderMode) + Q_PROPERTY (bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled) + Q_PROPERTY (bool mouseRotate READ isMouseRotateEnabled WRITE setMouseRotateEnabled) + Q_PROPERTY (bool mouseSelection READ isMouseSelectionEnabled WRITE setMouseSelectionEnabled) + Q_PROPERTY (bool cameraOrbit READ isCameraOrbit WRITE setCameraOrbit) + Q_PROPERTY (bool hoverHalo READ isHoverHaloEnabled WRITE setHoverHaloEnabled) + Q_PROPERTY (QColor hoverHaloColor READ hoverHaloColor WRITE setHoverHaloColor) + Q_PROPERTY (float hoverHaloFillAlpha READ hoverHaloFillAlpha WRITE setHoverHaloFillAlpha) + Q_PROPERTY (bool selectionHalo READ isSelectionHaloEnabled WRITE setSelectionHaloEnabled) + Q_PROPERTY (QColor selectionHaloColor READ selectionHaloColor WRITE setSelectionHaloColor) + Q_PROPERTY (float selectionHaloFillAlpha READ selectionHaloFillAlpha WRITE setSelectionHaloFillAlpha) + Q_PROPERTY (Qt::MouseButton selectionButton READ selectionButton WRITE setSelectionButton) + Q_PROPERTY (Qt::KeyboardModifier selectionModifier READ selectionModifier WRITE setSelectionModifier) + Q_PROPERTY (Scene::SelectionMode selectionMode READ selectionMode WRITE setSelectionMode) + +public: + QGLView(); + virtual ~QGLView(); + + enum CameraLightMode { + clmOff, + clmAuto, + clmOn, + }; + + enum Feature { + qglFXAA, + qglAnisotropicLevel, + qglEyeAccomodationEnabled, + qglEyeAccomodationTime, + qglEyeAccomodationMaxSpeed, + qglBloomEnabled, + qglBloomThreshold, + qglBloomFactor, + qglBloomRadius, + qglMotionBlurEnabled, + qglMotionBlurFactor, + qglMotionBlurSteps, + qglShadowsEnabled, + qglShadowsMapSize, + qglShadowsSoftEnabled, + qglReflectionsEnabled, + qglReflectionsBlur, + qglSSAOEnabled, + qglSSAORadius, + qglDepthOfFieldEnabled, + qglDepthOfFieldAutoFocusEnabled, + qglDepthOfFieldAutoFocusSpeed, + qglDepthOfFieldFocus, + qglDepthOfFieldDiaphragm + }; + + Q_ENUM(CameraLightMode) + + void stop(); + void start(float freq = 60.); + + QColor backColor() const {return backColor_;} + float lineWidth() const {return lineWidth_;} + float FOV() const {return camera()->fov_;} + float depthStart() const {return camera()->depth_start;} + float currentFPS() const {return fps_;} + float gamma() const {return renderer_.gamma_;} + bool autoExposure() const {return renderer_.tone_proc.enabled;} + int maxAnisotropicLevel() const {return max_anisotropic;} + QString environmentMapFile() const {return renderer_.tex_env.fileHDR();} + + QColor ambientColor() const {return ambientColor_;} + QColor fogColor() const {return fogColor_;} + float fogDensity() const {return fogDensity_;} + float fogDecay() const {return fogDecay_;} + bool isFogEnabled() const {return fogEnabled_;} + bool isLightEnabled() const {return lightEnabled_;} + bool isGrabMouseEnabled() const {return mouse.isGrabMouseEnabled();} + bool isMouseRotateEnabled() const {return mouse.isMouseRotateEnabled();} + bool isMouseSelectionEnabled() const {return mouse.isMouseSelectionEnabled();} + bool isCameraOrbit() const {return mouse.isCameraOrbit();} + bool isHoverHaloEnabled() const {return hoverHalo_;} + QColor hoverHaloColor() const {return hoverHaloColor_;} + float hoverHaloFillAlpha() const {return hoverHaloFill_;} + bool isSelectionHaloEnabled() const {return selectionHalo_;} + QColor selectionHaloColor() const {return selectionHaloColor_;} + float selectionHaloFillAlpha() const {return selectionHaloFill_;} + + QVariant feature(Feature f) const {return features_.value(int(f));} + QVariant setFeature(Feature f, const QVariant & value) {QVariant ret = features_.value(int(f)); features_[int(f)] = value; return ret;} + bool isFeatureEnabled(Feature f) const {return features_[int(f)].toBool();} + + int renderMode() const {return (int)rmode;} + void setRenderMode(int mode) {rmode = (ObjectBase::RenderMode)mode;} + + bool isServiceMode() const {return renderer_.edit_mode;} + void setServiceMode(bool yes) {renderer_.edit_mode = yes;} + + + Scene::SelectionMode selectionMode() const {return scene_->selectionMode();} + Qt::MouseButton selectionButton() const {return mouse.selectionButton();} + Qt::KeyboardModifier selectionModifier() const {return mouse.selectionModifier();} + + void setSelectionMode(Scene::SelectionMode m) {scene_->setSelectionMode(m);} + void setSelectionButton(Qt::MouseButton v) {mouse.setSelectionButton(v);} + void setSelectionModifier(Qt::KeyboardModifier v) {mouse.setSelectionModifier(v);} + + void selectObject(ObjectBase * o, bool add_to_selection = false) {scene_->selectObject(o, add_to_selection);} + void clearSelection() {scene_->clearSelection();} + ObjectBaseList selectedObjects(bool top_only = false) const {return scene_->selectedObjects(top_only);} + QList selectedLights() const; + QList selectedCameras() const; + ObjectBase * selectedObject() const {return scene_->selectedObject();} + + TextureManager * textureManager() {return renderer_.textures_manager;} + void reloadTextures() {renderer_.markReloadTextures();} + + Scene * scene() {return scene_;} + void focusOn(const Box3D & bb); + void setCameraLightMode(CameraLightMode m) {renderer_.setCameraLightMode(m);} + CameraLightMode cameraLightMode() const {return (CameraLightMode)renderer_.cameraLightMode();} + + Camera * camera() {return camera_;} + const Camera * camera() const {return camera_;} + void setCamera(Camera * camera) {camera_ = camera;} + void setDefaultCamera() {camera_ = default_camera;} + QByteArray saveCamera(); + void restoreCamera(const QByteArray & ba); + QByteArray saveFeatures(); + void restoreFeatures(const QByteArray & ba); + + QImage materialThumbnail(Material * m) {return renderer_.materialThumbnail(m);} + void setCurrentAction(RendererService::HandleAction ha) {renderer_.rend_service.setCurrentAction(ha);} + void setContextActions(QList al) {context_menu.clear(); context_menu.addActions(al);} + + GLfloat aspect, iaspect; + Renderer renderer_; + +protected: + void render(); + void resizeEvent(QResizeEvent * e); + + void timerEvent(QTimerEvent * ); + void initialize(); + void resizeGL(int width, int height); + void mousePressEvent(QMouseEvent * e) {mouse.mousePressEvent(e);} + void mouseMoveEvent(QMouseEvent * e) {mouse.mouseMoveEvent(e);} + void mouseReleaseEvent(QMouseEvent * e) {mouse.mouseReleaseEvent(e);} + void wheelEvent(QWheelEvent * e) {mouse.wheelEvent(e);} + void mouseDoubleClickEvent(QMouseEvent * e) {mouse.mouseDoubleClickEvent(e);} + void leaveEvent(QEvent * ); + + void keyPressEvent(QKeyEvent * e); + void keyReleaseEvent(QKeyEvent * e); + void focusOutEvent(QFocusEvent *); + + void checkCaps(); + +private: + void processKeys(); + bool setupViewport(); + + Scene * scene_; + Camera * camera_, * default_camera; + MouseController mouse; + QMenu context_menu; + QSet keys_; + QColor backColor_, fogColor_, ambientColor_, hoverHaloColor_, selectionHaloColor_; + QTime time, ktm_; + GLint max_anisotropic, max_texture_chanels; + ObjectBase::RenderMode rmode; + GLRendererBase::RenderingParameters start_rp; + QHash features_; + QSize prev_size; + float lineWidth_; + float fps_, fps_tm, fogDensity_, fogDecay_; + float hoverHaloFill_, selectionHaloFill_, m_motionBlurFactor; + int timer, fps_cnt, sh_id_loc, deleting_; + bool is_first_draw, is_init, fogEnabled_, lightEnabled_; + bool shaders_supported, changed_, need_init_; + bool hoverHalo_, selectionHalo_, shaders_bind; + +private slots: + void __destroyed(); + void __objectDeleted(ObjectBase * o); + +public slots: + void setBackColor(const QColor & arg) {backColor_ = arg;} + void setLineWidth(const float & arg) {lineWidth_ = arg;} + void setFOV(const float & arg) {camera()->fov_ = arg;} + void setDepthStart(const float & arg) {camera()->depth_start = arg;} + void setGamma(const float & arg) {renderer_.gamma_ = arg;} + void setAutoExposure(bool arg) {renderer_.tone_proc.enabled = arg;} + void setAmbientColor(const QColor & arg) {ambientColor_ = arg;} + void setEnvironmentMapFile(QString file) {renderer_.tex_env.setFileHDR(file); renderer_.recreateMaterialThumbnails(true);} + void setFogColor(const QColor & arg) {fogColor_ = arg;} + void setFogDensity(const float & arg) {fogDensity_ = arg;} + void setFogDecay(const float & arg) {fogDecay_ = arg;} + void setFogEnabled(const bool & arg) {fogEnabled_ = arg;} + void setLightEnabled(const bool & arg) {lightEnabled_ = arg;} + void setGrabMouseEnabled(const bool & arg) {mouse.setGrabMouseEnabled(arg);} + void setMouseRotateEnabled(const bool & arg) {mouse.setMouseRotateEnabled(arg);} + void setMouseSelectionEnabled(const bool & arg) {mouse.setMouseSelectionEnabled(arg);} + void setCustomMouseMove(const bool & arg) {mouse.setCustomMouseMove(arg);} + void setCameraOrbit(const bool & arg) {mouse.setCameraOrbit(arg);} + void setHoverHaloEnabled(const bool & arg) {hoverHalo_ = arg;} + void setHoverHaloColor(const QColor & arg) {hoverHaloColor_ = arg;} + void setHoverHaloFillAlpha(const float & arg) {hoverHaloFill_ = arg;} + void setSelectionHaloEnabled(const bool & arg) {selectionHalo_ = arg;} + void setSelectionHaloColor(const QColor & arg) {selectionHaloColor_ = arg;} + void setSelectionHaloFillAlpha(const float & arg) {selectionHaloFill_ = arg;} + + void reloadShaders() {renderer_.reloadShaders();} + +signals: + void glBeginPaint(); + void glEndPaint(); + void glKeyPressEvent(QKeyEvent * e); + void glKeyReleaseEvent(QKeyEvent * e); + void glMousePressEvent(QMouseEvent * e); + void glMouseMoveEvent(QMouseEvent * e); + void glMouseReleaseEvent(QMouseEvent * e); + void glWheelEvent(QWheelEvent * e); + void glResize(int, int); + void glInitializeDone(); + void cameraPosChanged(QVector3D pos); + void keyEvent(Qt::Key key, Qt::KeyboardModifiers mod); + void customMouseMoveEvent(QPoint curpos, QPoint lastpos, Qt::MouseButtons buttons); + + void hoverChanged(ObjectBase * cur, ObjectBase * prev); + void selectionChanged(); + void objectsPositionChanged(); + void materialsChanged(); + void materialThumbnailCreated(Material*); + void doubleClick(); + +}; + +#endif // QGLVIEW_H diff --git a/qglengine/shaders.qrc b/qglengine/shaders.qrc index ad92bf9..97e4492 100644 --- a/qglengine/shaders.qrc +++ b/qglengine/shaders.qrc @@ -1,19 +1,19 @@ - - - shaders/ds_final.glsl - shaders/ds_geom.glsl - shaders/ds_light.glsl - shaders/ds_tonemap.glsl - shaders/fxaa.frag - shaders/fxaa.vert - shaders/fxaa_v3.h - shaders/selection.glsl - shaders/selection_apply.glsl - shaders/selection_frame.glsl - shaders/selection_halo.glsl - shaders/service_fill.glsl - shaders/service_frame.glsl - shaders/service_line.glsl - shaders/sum.glsl - - + + + shaders/ds_final.glsl + shaders/ds_geom.glsl + shaders/ds_light.glsl + shaders/ds_tonemap.glsl + shaders/fxaa.frag + shaders/fxaa.vert + shaders/fxaa_v3.h + shaders/selection.glsl + shaders/selection_apply.glsl + shaders/selection_frame.glsl + shaders/selection_halo.glsl + shaders/service_fill.glsl + shaders/service_frame.glsl + shaders/service_line.glsl + shaders/sum.glsl + + diff --git a/qglengine/widgets/CMakeLists.txt b/qglengine/widgets/CMakeLists.txt index 4cf64b1..8055180 100644 --- a/qglengine/widgets/CMakeLists.txt +++ b/qglengine/widgets/CMakeLists.txt @@ -1,49 +1,26 @@ -cmake_minimum_required(VERSION 3.0) -project(qglengine_widgets) -if (POLICY CMP0017) - cmake_policy(SET CMP0017 NEW) -endif() -find_qt(Qt5 Core Gui Widgets) -qt_sources(SRC) -qt_wrap(${SRC} HDRS out_HDR CPPS out_CPP QMS out_QM) -file(GLOB PHS "*_p.h") -list(REMOVE_ITEM out_HDR "${PHS}") -import_version(${PROJECT_NAME} qglengine) -set_deploy_property(${PROJECT_NAME} SHARED - LABEL "QGLEngine widgets library" - FULLNAME "${_DOMAIN}.${PROJECT_NAME}" - COMPANY "${_COMPANY}" - INFO "QGLEngine widgets library") -make_rc(${PROJECT_NAME} _RC) -qt_add_library(${PROJECT_NAME} SHARED out_CPP ${_RC}) -qt_target_link_libraries(${PROJECT_NAME} qad_utils qad_widgets qglengine_core) -qt_target_include_directories(${PROJECT_NAME} PRIVATE ${QAD_INCLUDES} "${CMAKE_CURRENT_SOURCE_DIR}/../" "${CMAKE_CURRENT_SOURCE_DIR}/../core") -list(APPEND QT_MULTILIB_LIST ${PROJECT_NAME}) -set(QT_MULTILIB_LIST ${QT_MULTILIB_LIST} PARENT_SCOPE) -#message(STATUS "Building ${PROJECT_NAME}") -if (LIBPROJECT) - sdk_install("qglengine" FALSE "${PROJECT_NAME}" "${out_HDR}" "${out_QM}") -else() - if (LIB) - if (WIN32) - qt_install(FILES ${out_HDR} DESTINATION ${MINGW_INCLUDE}/qglengine) - qt_install(TARGETS ${PROJECT_NAME} DESTINATION ${MINGW_LIB}) - qt_install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${MINGW_BIN}) - qt_install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION QtBin) - else() - qt_install(FILES ${out_HDR} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/qglengine) - qt_install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) - endif() - message(STATUS "Install ${PROJECT_NAME} to system \"${CMAKE_INSTALL_PREFIX}\"") - else() - if(WIN32) - qt_install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin) - qt_install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION lib) - else() - qt_install(TARGETS ${PROJECT_NAME} DESTINATION bin/lib) - endif() - qt_install(TARGETS ${PROJECT_NAME} DESTINATION lib) - qt_install(FILES ${H} DESTINATION include/qglengine) - message(STATUS "Install ${PROJECT_NAME} to local \"bin\", \"lib\" and \"include\"") - endif() -endif() +cmake_minimum_required(VERSION 3.0) +project(qglengine_widgets) +if (POLICY CMP0017) + cmake_policy(SET CMP0017 NEW) +endif() +find_qt(Qt5 Core Gui Widgets) +qt_sources(SRC) +qt_wrap(${SRC} HDRS out_HDR CPPS out_CPP QMS out_QM) +file(GLOB PHS "*_p.h") +list(REMOVE_ITEM out_HDR "${PHS}") +import_version(${PROJECT_NAME} qglengine) +set_deploy_property(${PROJECT_NAME} SHARED + LABEL "QGLEngine widgets library" + FULLNAME "${_DOMAIN}.${PROJECT_NAME}" + COMPANY "${_COMPANY}" + INFO "QGLEngine widgets library") +make_rc(${PROJECT_NAME} _RC) +qt_add_library(${PROJECT_NAME} SHARED out_CPP ${_RC}) +qt_generate_export_header(${PROJECT_NAME}) +list(APPEND out_HDR "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}_export.h") +qt_target_link_libraries(${PROJECT_NAME} qad_utils qad_widgets qglengine_core) +qt_target_include_directories(${PROJECT_NAME} PRIVATE ${QAD_INCLUDES} "${CMAKE_CURRENT_SOURCE_DIR}/../" "${CMAKE_CURRENT_SOURCE_DIR}/../core") +list(APPEND QT_MULTILIB_LIST ${PROJECT_NAME}) +copy_to_parent("") +#message(STATUS "Building ${PROJECT_NAME}") +sdk_install("qglengine" FALSE "${PROJECT_NAME}" "${out_HDR}" "${out_QM}") diff --git a/qglengine/widgets/primitiveeditor.cpp b/qglengine/widgets/primitiveeditor.cpp index 4613004..bfa3299 100644 --- a/qglengine/widgets/primitiveeditor.cpp +++ b/qglengine/widgets/primitiveeditor.cpp @@ -1,259 +1,259 @@ -/* - QGL PrimitiveEditor - Ivan Pelipenko peri4ko@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 . -*/ - -#include "primitiveeditor.h" -#include "ui_primitiveeditor.h" -#include -#include "glprimitives.h" -#include "glmesh.h" - - -PrimitiveEditor::PrimitiveEditor(QWidget *parent) : QWidget(parent), ui(new Ui::PrimitiveEditor) { - view = 0; - can_replace = false; - ui->setupUi(this); -#if QT_VERSION >= QT_VERSION_CHECK(5,12,0) - ui->spinSegments->setStepType(QAbstractSpinBox::AdaptiveDecimalStepType); - ui->spinSegments2->setStepType(QAbstractSpinBox::AdaptiveDecimalStepType); -#endif - editors[Plane] << ui->widgetWidth; - editors[Plane] << ui->widgetLength; - editors[Cube] << ui->widgetWidth; - editors[Cube] << ui->widgetLength; - editors[Cube] << ui->widgetHeight; - editors[Ellipsoid] << ui->widgetRadius1; - editors[Ellipsoid] << ui->widgetSegments; - editors[Ellipsoid] << ui->widgetSegments2; - editors[Ellipsoid] << ui->widgetAngle; - editors[Disc] << ui->widgetRadius1; - editors[Disc] << ui->widgetSegments; - editors[Disc] << ui->widgetAngle; - editors[Cone] << ui->widgetRadius1; - editors[Cone] << ui->widgetHeight; - editors[Cone] << ui->widgetSegments; - editors[Cylinder] << ui->widgetRadius1; - editors[Cylinder] << ui->widgetHeight; - editors[Cylinder] << ui->widgetSegments; - editors[Cylinder] << ui->widgetAngle; - editors[Torus] << ui->widgetRadius1; - editors[Torus] << ui->widgetRadius2; - editors[Torus] << ui->widgetSegments; - editors[Torus] << ui->widgetSegments2; - editors[Torus] << ui->widgetAngle; - QSet all; - QMetaEnum me = metaObject()->enumerator(0); - for (int i=0; icomboPrimitives->addItem(me.key(i)); - all.unite(editors[(PrimitiveType)me.value(i)].toSet()); - } - all_editors = all.toList(); - foreach (QWidget * w, all_editors) { - if (w->layout()) w->layout()->setContentsMargins(0, layout()->spacing(), 0, 0); - } - - ui->comboPrimitives->setCurrentIndex(Plane); - on_comboPrimitives_currentIndexChanged(ui->comboPrimitives->currentIndex()); -} - - -PrimitiveEditor::~PrimitiveEditor() { - delete ui; -} - - -void PrimitiveEditor::assignQGLView(QGLView * v) { - view = v; - connect(view, SIGNAL(selectionChanged()), this, SLOT(selectionChanged())); - selectionChanged(); -} - - -Mesh * PrimitiveEditor::createMesh(QVariantList & params) { - Mesh * m = 0; - PrimitiveType pt = (PrimitiveType)ui->comboPrimitives->currentIndex(); - params << pt; - switch (pt) { - case Plane: - m = Primitive::plane(ui->spinWidth->value(), - ui->spinLength->value()); - params << ui->spinWidth->value() - << ui->spinLength->value(); - break; - case Cube: - m = Primitive::cube(ui->spinWidth->value(), - ui->spinLength->value(), - ui->spinHeight->value()); - params << ui->spinWidth->value() - << ui->spinLength->value() - << ui->spinHeight->value(); - break; - case Ellipsoid: - m = Primitive::ellipsoid(ui->spinSegments->value(), - ui->spinSegments2->value(), - ui->spinRadius->value(), - ui->spinAngle->value()); - params << ui->spinSegments->value() - << ui->spinSegments2->value() - << ui->spinRadius->value() - << ui->spinAngle->value(); - break; - case Disc: - m = Primitive::disc(ui->spinSegments->value(), - ui->spinRadius->value(), - ui->spinAngle->value()); - params << ui->spinSegments->value() - << ui->spinRadius->value() - << ui->spinAngle->value(); - break; - case Cone: - m = Primitive::cone(ui->spinSegments->value(), - ui->spinRadius->value(), - ui->spinHeight->value()); - params << ui->spinSegments->value() - << ui->spinRadius->value() - << ui->spinHeight->value(); - break; - case Cylinder: - m = Primitive::cylinder(ui->spinSegments->value(), - ui->spinRadius->value(), - ui->spinHeight->value(), - ui->spinAngle->value()); - params << ui->spinSegments->value() - << ui->spinRadius->value() - << ui->spinHeight->value() - << ui->spinAngle->value(); - break; - case Torus: - m = Primitive::torus(ui->spinSegments->value(), - ui->spinSegments2->value(), - ui->spinRadius->value(), - ui->spinRadius2->value(), - ui->spinAngle->value()); - params << ui->spinSegments->value() - << ui->spinSegments2->value() - << ui->spinRadius->value() - << ui->spinRadius2->value() - << ui->spinAngle->value(); - break; - default: return 0; - } - params << ui->flipNormals->isChecked(); - params << ui->colorButton->color(); - if (ui->flipNormals->isChecked()) - m->flipNormals(); - return m; -} - - -void PrimitiveEditor::showEditors() { - foreach (QWidget * w, all_editors) w->hide(); - PrimitiveType pt = (PrimitiveType)ui->comboPrimitives->currentIndex(); - QList wds = editors[pt]; - foreach (QWidget * w, wds) w->show(); -} - - -void PrimitiveEditor::selectionChanged() { - ObjectBase * so = view->selectedObject();\ - can_replace = false; - if (so) { - QVariantList vl = so->property("primitive", &can_replace).toList(); - if (can_replace && !vl.isEmpty()) { - PrimitiveType pt = (PrimitiveType)vl.takeFirst().toInt(); - ui->comboPrimitives->setCurrentIndex(pt); - switch (pt) { - case Plane: - ui->spinWidth->setValue(vl.takeFirst().toDouble()); - ui->spinLength->setValue(vl.takeFirst().toDouble()); - break; - case Cube: - ui->spinWidth->setValue(vl.takeFirst().toDouble()); - ui->spinLength->setValue(vl.takeFirst().toDouble()); - ui->spinHeight->setValue(vl.takeFirst().toDouble()); - break; - case Ellipsoid: - ui->spinSegments->setValue(vl.takeFirst().toDouble()); - ui->spinSegments2->setValue(vl.takeFirst().toDouble()); - ui->spinRadius->setValue(vl.takeFirst().toDouble()); - ui->spinAngle->setValue(vl.takeFirst().toDouble()); - break; - case Disc: - ui->spinSegments->setValue(vl.takeFirst().toDouble()); - ui->spinRadius->setValue(vl.takeFirst().toDouble()); - ui->spinAngle->setValue(vl.takeFirst().toDouble()); - break; - case Cone: - ui->spinSegments->setValue(vl.takeFirst().toDouble()); - ui->spinRadius->setValue(vl.takeFirst().toDouble()); - ui->spinHeight->setValue(vl.takeFirst().toDouble()); - break; - case Cylinder: - ui->spinSegments->setValue(vl.takeFirst().toDouble()); - ui->spinRadius->setValue(vl.takeFirst().toDouble()); - ui->spinHeight->setValue(vl.takeFirst().toDouble()); - ui->spinAngle->setValue(vl.takeFirst().toDouble()); - break; - case Torus: - ui->spinSegments->setValue(vl.takeFirst().toDouble()); - ui->spinSegments2->setValue(vl.takeFirst().toDouble()); - ui->spinRadius->setValue(vl.takeFirst().toDouble()); - ui->spinRadius2->setValue(vl.takeFirst().toDouble()); - ui->spinAngle->setValue(vl.takeFirst().toDouble()); - break; - } - ui->flipNormals->setChecked(vl.takeFirst().toBool()); - ui->colorButton->setColor(vl.takeFirst().value()); - } - } -} - - -void PrimitiveEditor::replaceMesh() { - if (!view) return; - if (!can_replace) return; - ObjectBase * so = view->selectedObject(); - if (!so) return; - QVariantList params; - Mesh * m = createMesh(params); - if (!m) return; - so->setMesh(m); - so->setColor(ui->colorButton->color()); - so->setName(ui->comboPrimitives->currentText()); - so->setProperty("primitive", params); - delete m; -} - - -void PrimitiveEditor::on_buttonAdd_clicked() { - if (!view) return; - QVariantList params; - Mesh * m = createMesh(params); - if (!m) return; - ObjectBase * o = new ObjectBase(m); - o->setColor(ui->colorButton->color()); - o->setName(ui->comboPrimitives->currentText()); - o->setProperty("primitive", params); - view->scene()->addObject(o); - view->scene()->selectObject(o); - delete m; -} - - -void PrimitiveEditor::on_comboPrimitives_currentIndexChanged(int index) { - showEditors(); -} +/* + QGL PrimitiveEditor + Ivan Pelipenko peri4ko@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 . +*/ + +#include "primitiveeditor.h" +#include "ui_primitiveeditor.h" +#include +#include "glprimitives.h" +#include "glmesh.h" + + +PrimitiveEditor::PrimitiveEditor(QWidget *parent) : QWidget(parent), ui(new Ui::PrimitiveEditor) { + view = 0; + can_replace = false; + ui->setupUi(this); +#if QT_VERSION >= QT_VERSION_CHECK(5,12,0) + ui->spinSegments->setStepType(QAbstractSpinBox::AdaptiveDecimalStepType); + ui->spinSegments2->setStepType(QAbstractSpinBox::AdaptiveDecimalStepType); +#endif + editors[Plane] << ui->widgetWidth; + editors[Plane] << ui->widgetLength; + editors[Cube] << ui->widgetWidth; + editors[Cube] << ui->widgetLength; + editors[Cube] << ui->widgetHeight; + editors[Ellipsoid] << ui->widgetRadius1; + editors[Ellipsoid] << ui->widgetSegments; + editors[Ellipsoid] << ui->widgetSegments2; + editors[Ellipsoid] << ui->widgetAngle; + editors[Disc] << ui->widgetRadius1; + editors[Disc] << ui->widgetSegments; + editors[Disc] << ui->widgetAngle; + editors[Cone] << ui->widgetRadius1; + editors[Cone] << ui->widgetHeight; + editors[Cone] << ui->widgetSegments; + editors[Cylinder] << ui->widgetRadius1; + editors[Cylinder] << ui->widgetHeight; + editors[Cylinder] << ui->widgetSegments; + editors[Cylinder] << ui->widgetAngle; + editors[Torus] << ui->widgetRadius1; + editors[Torus] << ui->widgetRadius2; + editors[Torus] << ui->widgetSegments; + editors[Torus] << ui->widgetSegments2; + editors[Torus] << ui->widgetAngle; + QSet all; + QMetaEnum me = metaObject()->enumerator(0); + for (int i=0; icomboPrimitives->addItem(me.key(i)); + all.unite(editors[(PrimitiveType)me.value(i)].toSet()); + } + all_editors = all.toList(); + foreach (QWidget * w, all_editors) { + if (w->layout()) w->layout()->setContentsMargins(0, layout()->spacing(), 0, 0); + } + + ui->comboPrimitives->setCurrentIndex(Plane); + on_comboPrimitives_currentIndexChanged(ui->comboPrimitives->currentIndex()); +} + + +PrimitiveEditor::~PrimitiveEditor() { + delete ui; +} + + +void PrimitiveEditor::assignQGLView(QGLView * v) { + view = v; + connect(view, SIGNAL(selectionChanged()), this, SLOT(selectionChanged())); + selectionChanged(); +} + + +Mesh * PrimitiveEditor::createMesh(QVariantList & params) { + Mesh * m = 0; + PrimitiveType pt = (PrimitiveType)ui->comboPrimitives->currentIndex(); + params << pt; + switch (pt) { + case Plane: + m = Primitive::plane(ui->spinWidth->value(), + ui->spinLength->value()); + params << ui->spinWidth->value() + << ui->spinLength->value(); + break; + case Cube: + m = Primitive::cube(ui->spinWidth->value(), + ui->spinLength->value(), + ui->spinHeight->value()); + params << ui->spinWidth->value() + << ui->spinLength->value() + << ui->spinHeight->value(); + break; + case Ellipsoid: + m = Primitive::ellipsoid(ui->spinSegments->value(), + ui->spinSegments2->value(), + ui->spinRadius->value(), + ui->spinAngle->value()); + params << ui->spinSegments->value() + << ui->spinSegments2->value() + << ui->spinRadius->value() + << ui->spinAngle->value(); + break; + case Disc: + m = Primitive::disc(ui->spinSegments->value(), + ui->spinRadius->value(), + ui->spinAngle->value()); + params << ui->spinSegments->value() + << ui->spinRadius->value() + << ui->spinAngle->value(); + break; + case Cone: + m = Primitive::cone(ui->spinSegments->value(), + ui->spinRadius->value(), + ui->spinHeight->value()); + params << ui->spinSegments->value() + << ui->spinRadius->value() + << ui->spinHeight->value(); + break; + case Cylinder: + m = Primitive::cylinder(ui->spinSegments->value(), + ui->spinRadius->value(), + ui->spinHeight->value(), + ui->spinAngle->value()); + params << ui->spinSegments->value() + << ui->spinRadius->value() + << ui->spinHeight->value() + << ui->spinAngle->value(); + break; + case Torus: + m = Primitive::torus(ui->spinSegments->value(), + ui->spinSegments2->value(), + ui->spinRadius->value(), + ui->spinRadius2->value(), + ui->spinAngle->value()); + params << ui->spinSegments->value() + << ui->spinSegments2->value() + << ui->spinRadius->value() + << ui->spinRadius2->value() + << ui->spinAngle->value(); + break; + default: return 0; + } + params << ui->flipNormals->isChecked(); + params << ui->colorButton->color(); + if (ui->flipNormals->isChecked()) + m->flipNormals(); + return m; +} + + +void PrimitiveEditor::showEditors() { + foreach (QWidget * w, all_editors) w->hide(); + PrimitiveType pt = (PrimitiveType)ui->comboPrimitives->currentIndex(); + QList wds = editors[pt]; + foreach (QWidget * w, wds) w->show(); +} + + +void PrimitiveEditor::selectionChanged() { + ObjectBase * so = view->selectedObject();\ + can_replace = false; + if (so) { + QVariantList vl = so->property("primitive", &can_replace).toList(); + if (can_replace && !vl.isEmpty()) { + PrimitiveType pt = (PrimitiveType)vl.takeFirst().toInt(); + ui->comboPrimitives->setCurrentIndex(pt); + switch (pt) { + case Plane: + ui->spinWidth->setValue(vl.takeFirst().toDouble()); + ui->spinLength->setValue(vl.takeFirst().toDouble()); + break; + case Cube: + ui->spinWidth->setValue(vl.takeFirst().toDouble()); + ui->spinLength->setValue(vl.takeFirst().toDouble()); + ui->spinHeight->setValue(vl.takeFirst().toDouble()); + break; + case Ellipsoid: + ui->spinSegments->setValue(vl.takeFirst().toDouble()); + ui->spinSegments2->setValue(vl.takeFirst().toDouble()); + ui->spinRadius->setValue(vl.takeFirst().toDouble()); + ui->spinAngle->setValue(vl.takeFirst().toDouble()); + break; + case Disc: + ui->spinSegments->setValue(vl.takeFirst().toDouble()); + ui->spinRadius->setValue(vl.takeFirst().toDouble()); + ui->spinAngle->setValue(vl.takeFirst().toDouble()); + break; + case Cone: + ui->spinSegments->setValue(vl.takeFirst().toDouble()); + ui->spinRadius->setValue(vl.takeFirst().toDouble()); + ui->spinHeight->setValue(vl.takeFirst().toDouble()); + break; + case Cylinder: + ui->spinSegments->setValue(vl.takeFirst().toDouble()); + ui->spinRadius->setValue(vl.takeFirst().toDouble()); + ui->spinHeight->setValue(vl.takeFirst().toDouble()); + ui->spinAngle->setValue(vl.takeFirst().toDouble()); + break; + case Torus: + ui->spinSegments->setValue(vl.takeFirst().toDouble()); + ui->spinSegments2->setValue(vl.takeFirst().toDouble()); + ui->spinRadius->setValue(vl.takeFirst().toDouble()); + ui->spinRadius2->setValue(vl.takeFirst().toDouble()); + ui->spinAngle->setValue(vl.takeFirst().toDouble()); + break; + } + ui->flipNormals->setChecked(vl.takeFirst().toBool()); + ui->colorButton->setColor(vl.takeFirst().value()); + } + } +} + + +void PrimitiveEditor::replaceMesh() { + if (!view) return; + if (!can_replace) return; + ObjectBase * so = view->selectedObject(); + if (!so) return; + QVariantList params; + Mesh * m = createMesh(params); + if (!m) return; + so->setMesh(m); + so->setColor(ui->colorButton->color()); + so->setName(ui->comboPrimitives->currentText()); + so->setProperty("primitive", params); + delete m; +} + + +void PrimitiveEditor::on_buttonAdd_clicked() { + if (!view) return; + QVariantList params; + Mesh * m = createMesh(params); + if (!m) return; + ObjectBase * o = new ObjectBase(m); + o->setColor(ui->colorButton->color()); + o->setName(ui->comboPrimitives->currentText()); + o->setProperty("primitive", params); + view->scene()->addObject(o); + view->scene()->selectObject(o); + delete m; +} + + +void PrimitiveEditor::on_comboPrimitives_currentIndexChanged(int index) { + showEditors(); +} diff --git a/qglengine/widgets/primitiveeditor.h b/qglengine/widgets/primitiveeditor.h index d91c77f..7d1b5a4 100644 --- a/qglengine/widgets/primitiveeditor.h +++ b/qglengine/widgets/primitiveeditor.h @@ -1,68 +1,68 @@ -/* - QGL PrimitiveEditor - Ivan Pelipenko peri4ko@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 . -*/ - -#ifndef PRIMITIVEEDITOR_H -#define PRIMITIVEEDITOR_H - -#include -#include "qglview.h" - - -namespace Ui { -class PrimitiveEditor; -} - - -class PrimitiveEditor : public QWidget { - Q_OBJECT -public: - enum PrimitiveType { - Plane, - Cube, - Ellipsoid, - Disc, - Cone, - Cylinder, - Torus - }; - Q_ENUMS(PrimitiveType) - - explicit PrimitiveEditor(QWidget *parent = nullptr); - ~PrimitiveEditor(); - - void assignQGLView(QGLView * v); - -protected: - Mesh * createMesh(QVariantList & params); - void showEditors(); - - Ui::PrimitiveEditor *ui; - QGLView * view; - QMap > editors; - QList all_editors; - bool can_replace; - -private slots: - void selectionChanged(); - void replaceMesh(); - void on_buttonAdd_clicked(); - void on_comboPrimitives_currentIndexChanged(int index); -}; - - -#endif // PRIMITIVEEDITOR_H +/* + QGL PrimitiveEditor + Ivan Pelipenko peri4ko@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 . +*/ + +#ifndef PRIMITIVEEDITOR_H +#define PRIMITIVEEDITOR_H + +#include +#include "qglview.h" + + +namespace Ui { +class PrimitiveEditor; +} + + +class PrimitiveEditor : public QWidget { + Q_OBJECT +public: + enum PrimitiveType { + Plane, + Cube, + Ellipsoid, + Disc, + Cone, + Cylinder, + Torus + }; + Q_ENUMS(PrimitiveType) + + explicit PrimitiveEditor(QWidget *parent = nullptr); + ~PrimitiveEditor(); + + void assignQGLView(QGLView * v); + +protected: + Mesh * createMesh(QVariantList & params); + void showEditors(); + + Ui::PrimitiveEditor *ui; + QGLView * view; + QMap > editors; + QList all_editors; + bool can_replace; + +private slots: + void selectionChanged(); + void replaceMesh(); + void on_buttonAdd_clicked(); + void on_comboPrimitives_currentIndexChanged(int index); +}; + + +#endif // PRIMITIVEEDITOR_H diff --git a/qglengine/widgets/primitiveeditor.ui b/qglengine/widgets/primitiveeditor.ui index 2d2c9d9..9238a84 100644 --- a/qglengine/widgets/primitiveeditor.ui +++ b/qglengine/widgets/primitiveeditor.ui @@ -1,597 +1,597 @@ - - - PrimitiveEditor - - - - 0 - 0 - 360 - 536 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - - - Width: - - - - - - - 1.000000000000000 - - - - - - - - - - - 0 - - - 0 - - - 0 - - - - - Length: - - - - - - - 1.000000000000000 - - - - - - - - - - - 0 - - - 0 - - - 0 - - - - - Height - - - - - - - 1.000000000000000 - - - - - - - - - - - 0 - - - 0 - - - 0 - - - - - Radius 1: - - - - - - - 1.000000000000000 - - - - - - - - - - - 0 - - - 0 - - - 0 - - - - - Radius 2: - - - - - - - 1.000000000000000 - - - - - - - - - - - 0 - - - 0 - - - 0 - - - - - Angle: - - - - - - - 360.000000000000000 - - - 360.000000000000000 - - - 4.500000000000000 - - - 90.000000000000000 - - - ° - - - QSlider::TicksAbove - - - 90 - - - - - - - - - - - 0 - - - 0 - - - 0 - - - - - Segments: - - - - - - - 1 - - - 1000 - - - 1 - - - 16 - - - - - - - - - - - 0 - - - 0 - - - 0 - - - - - Segments 2: - - - - - - - 1 - - - 1000 - - - 1 - - - 16 - - - - - - - - - - - 0 - - - 0 - - - 0 - - - - - Color: - - - - - - - - 255 - 255 - 255 - - - - - - - - - - - - - - Flip normals - - - - - - - Qt::Vertical - - - - 20 - 176 - - - - - - - - - - Add - - - - :/icons/list-add.png:/icons/list-add.png - - - - - - - - - - SpinSlider - QWidget -
spinslider.h
-
- - ColorButton - QPushButton -
colorbutton.h
-
- - EComboBox - QComboBox -
ecombobox.h
-
- - ScrollSpinBox - QWidget -
scroll_spin_box.h
-
-
- - - - - - spinWidth - valueChanged(double) - PrimitiveEditor - replaceMesh() - - - 331 - 51 - - - 368 - 45 - - - - - spinLength - valueChanged(double) - PrimitiveEditor - replaceMesh() - - - 330 - 84 - - - 369 - 82 - - - - - spinHeight - valueChanged(double) - PrimitiveEditor - replaceMesh() - - - 334 - 116 - - - 366 - 114 - - - - - spinRadius - valueChanged(double) - PrimitiveEditor - replaceMesh() - - - 332 - 144 - - - 370 - 145 - - - - - spinRadius2 - valueChanged(double) - PrimitiveEditor - replaceMesh() - - - 334 - 186 - - - 371 - 181 - - - - - spinAngle - valueChanged(double) - PrimitiveEditor - replaceMesh() - - - 335 - 210 - - - 372 - 213 - - - - - spinSegments - valueChanged(int) - PrimitiveEditor - replaceMesh() - - - 329 - 246 - - - 370 - 247 - - - - - spinSegments2 - valueChanged(int) - PrimitiveEditor - replaceMesh() - - - 336 - 284 - - - 372 - 279 - - - - - flipNormals - toggled(bool) - PrimitiveEditor - replaceMesh() - - - 70 - 344 - - - 370 - 341 - - - - - comboPrimitives - currentIndexChanged(int) - PrimitiveEditor - replaceMesh() - - - 348 - 9 - - - 367 - 9 - - - - - colorButton - colorChanged(QColor) - PrimitiveEditor - replaceMesh() - - - 271 - 285 - - - 179 - 267 - - - - - - replaceMesh() - -
+ + + PrimitiveEditor + + + + 0 + 0 + 360 + 536 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + + + 0 + + + 0 + + + + + Width: + + + + + + + 1.000000000000000 + + + + + + + + + + + 0 + + + 0 + + + 0 + + + + + Length: + + + + + + + 1.000000000000000 + + + + + + + + + + + 0 + + + 0 + + + 0 + + + + + Height + + + + + + + 1.000000000000000 + + + + + + + + + + + 0 + + + 0 + + + 0 + + + + + Radius 1: + + + + + + + 1.000000000000000 + + + + + + + + + + + 0 + + + 0 + + + 0 + + + + + Radius 2: + + + + + + + 1.000000000000000 + + + + + + + + + + + 0 + + + 0 + + + 0 + + + + + Angle: + + + + + + + 360.000000000000000 + + + 360.000000000000000 + + + 4.500000000000000 + + + 90.000000000000000 + + + ° + + + QSlider::TicksAbove + + + 90 + + + + + + + + + + + 0 + + + 0 + + + 0 + + + + + Segments: + + + + + + + 1 + + + 1000 + + + 1 + + + 16 + + + + + + + + + + + 0 + + + 0 + + + 0 + + + + + Segments 2: + + + + + + + 1 + + + 1000 + + + 1 + + + 16 + + + + + + + + + + + 0 + + + 0 + + + 0 + + + + + Color: + + + + + + + + 255 + 255 + 255 + + + + + + + + + + + + + + Flip normals + + + + + + + Qt::Vertical + + + + 20 + 176 + + + + + + + + + + Add + + + + :/icons/list-add.png:/icons/list-add.png + + + + + + + + + + SpinSlider + QWidget +
spinslider.h
+
+ + ColorButton + QPushButton +
colorbutton.h
+
+ + EComboBox + QComboBox +
ecombobox.h
+
+ + ScrollSpinBox + QWidget +
scroll_spin_box.h
+
+
+ + + + + + spinWidth + valueChanged(double) + PrimitiveEditor + replaceMesh() + + + 331 + 51 + + + 368 + 45 + + + + + spinLength + valueChanged(double) + PrimitiveEditor + replaceMesh() + + + 330 + 84 + + + 369 + 82 + + + + + spinHeight + valueChanged(double) + PrimitiveEditor + replaceMesh() + + + 334 + 116 + + + 366 + 114 + + + + + spinRadius + valueChanged(double) + PrimitiveEditor + replaceMesh() + + + 332 + 144 + + + 370 + 145 + + + + + spinRadius2 + valueChanged(double) + PrimitiveEditor + replaceMesh() + + + 334 + 186 + + + 371 + 181 + + + + + spinAngle + valueChanged(double) + PrimitiveEditor + replaceMesh() + + + 335 + 210 + + + 372 + 213 + + + + + spinSegments + valueChanged(int) + PrimitiveEditor + replaceMesh() + + + 329 + 246 + + + 370 + 247 + + + + + spinSegments2 + valueChanged(int) + PrimitiveEditor + replaceMesh() + + + 336 + 284 + + + 372 + 279 + + + + + flipNormals + toggled(bool) + PrimitiveEditor + replaceMesh() + + + 70 + 344 + + + 370 + 341 + + + + + comboPrimitives + currentIndexChanged(int) + PrimitiveEditor + replaceMesh() + + + 348 + 9 + + + 367 + 9 + + + + + colorButton + colorChanged(QColor) + PrimitiveEditor + replaceMesh() + + + 271 + 285 + + + 179 + 267 + + + + + + replaceMesh() + +
diff --git a/qglview/CMakeLists.txt b/qglview/CMakeLists.txt index 86e1110..b6fcdf8 100644 --- a/qglview/CMakeLists.txt +++ b/qglview/CMakeLists.txt @@ -1,70 +1,8 @@ -cmake_minimum_required(VERSION 3.0) -project(qglview) -if (IBPROJECT) - include(SDKMacros) -else() - option(LIB "System install" 0) - option(DEBUG "Build with -g3" 0) - option(DESIGNER_PLUGINS "Build qt designer plugins" 1) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wall") - if (DEBUG) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3") - endif() -endif() -if (MINGW) - find_package(MinGW REQUIRED) -endif() -find_package(QAD REQUIRED) -find_package(OpenGL REQUIRED) -include_directories(${QAD_INCLUDES}) -find_qt(Qt5 Core Gui OpenGL Xml) -if (NOT Qt5) - message(WARNING "Building ${PROJECT_NAME} available only on Qt5!") -else() - qt_sources(SRC) - qt_wrap(${SRC} HDRS out_HDR CPPS out_CPP QMS out_QM) - qt_add_library(${PROJECT_NAME} SHARED out_CPP) - qt_target_link_libraries(${PROJECT_NAME} qad_utils qad_widgets ${OPENGL_LIBRARIES}) - qt_target_include_directories(${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}") - message(STATUS "Building ${PROJECT_NAME}") - if (LIBPROJECT) - sdk_install("qad" FALSE "${PROJECT_NAME}" "${out_HDR}" "${out_QM}") - else() - if (LIB) - if (WIN32) - qt_install(FILES ${H} DESTINATION ${MINGW_INCLUDE}/qad) - qt_install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION ${MINGW_LIB}) - qt_install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${MINGW_BIN}) - qt_install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION QtBin) - else() - qt_install(FILES ${H} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/qad) - qt_install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) - endif() - message(STATUS "Install ${PROJECT_NAME} to system \"${CMAKE_INSTALL_PREFIX}\"") - else() - if(WIN32) - qt_install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin) - qt_install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION lib) - else() - qt_install(TARGETS ${PROJECT_NAME} DESTINATION lib) - endif() - qt_install(FILES ${H} DESTINATION include/qad) - message(STATUS "Install ${PROJECT_NAME} to local \"bin\", \"lib\" and \"include\"") - endif() - endif() - foreach(_v ${_QT_VERSIONS_}) - set(MULTILIB_qglview_SUFFIX_Qt${_v} ${_v}) - set(MULTILIB_qglview_SUFFIX_Qt${_v} ${_v} PARENT_SCOPE) - endforeach() - list(APPEND QT_MULTILIB_LIST qglview) - if (NOT DEFINED ANDROID_PLATFORM) - if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/plugin") - add_subdirectory(plugin) - endif() - endif() - - qt_sources(test_SRC DIR "qglview_test") - qt_wrap(${test_SRC} CPPS test_CPP) - qt_add_executable(qglview_test test_CPP) - qt_target_link_libraries(qglview_test ${PROJECT_NAME}) -endif() +find_package(OpenGL REQUIRED) +_qt_project(qglview FALSE "QAD" "Gui;OpenGL;Xml" "qad_widgets;qad_utils;${OPENGL_LIBRARIES}") +_qt_install(qglview FALSE "qad" "out_HDR" "out_QM") + +qt_sources(test_SRC DIR "qglview_test") +qt_wrap(${test_SRC} CPPS test_CPP) +qt_add_executable(qglview_test test_CPP) +qt_target_link_libraries(qglview_test qglview) diff --git a/qglview/glwidget.cpp b/qglview/glwidget.cpp index c6d75f8..22c905a 100644 --- a/qglview/glwidget.cpp +++ b/qglview/glwidget.cpp @@ -1,236 +1,236 @@ -#include "glwidget.h" -#include "renderer_simple.h" -#include "renderer_deferred_shading.h" -#include - - -GLWidget::GLWidget(QWidget *parent) : QWidget(parent) { - view_ = new QGLView(); - view_->setFlags(windowFlags() | Qt::FramelessWindowHint); - container = QWidget::createWindowContainer(view_, this); - lay = new QVBoxLayout(this); - lay->addWidget(container); - lay->setContentsMargins(0, 0, 0, 0); - lay->setSpacing(0); - setMouseTracking(true); - setWindowIcon(QIcon("://icons/qglview.png")); - connect(view_, &QGLView::doubleClick, this, &GLWidget::viewDoubleClicked); -} - - -QColor GLWidget::backColor() const { - return view_->backColor(); -} - - -qreal GLWidget::lineWidth() const { - return view_->lineWidth(); -} - - -qreal GLWidget::FOV() const { - return view_->FOV(); -} - - -qreal GLWidget::depthStart() const { - return view_->depthStart(); -} - - -qreal GLWidget::depthEnd() const { - return view_->depthEnd(); -} - - -QColor GLWidget::ambientColor() const { - return view_->ambientColor(); -} - - -bool GLWidget::isLightEnabled() const { - return view_->isLightEnabled(); -} - - -bool GLWidget::isGrabMouseEnabled() const { - return view_->isGrabMouseEnabled(); -} - - -bool GLWidget::isMouseRotateEnabled() const { - return view_->isMouseRotateEnabled(); -} - - -bool GLWidget::isMouseSelectionEnabled() const { - return view_->isMouseSelectionEnabled(); -} - - -bool GLWidget::isCameraOrbit() const -{ - return view_->isCameraOrbit(); -} - - -bool GLWidget::isHoverHaloEnabled() const { - return view_->isHoverHaloEnabled(); -} - - -QColor GLWidget::hoverHaloColor() const { - return view_->hoverHaloColor(); -} - - -qreal GLWidget::hoverHaloFillAlpha() const { - return view_->hoverHaloFillAlpha(); -} - - -bool GLWidget::isSelectionHaloEnabled() const { - return view_->isSelectionHaloEnabled(); -} - - -QColor GLWidget::selectionHaloColor() const { - return view_->selectionHaloColor(); -} - - -qreal GLWidget::selectionHaloFillAlpha() const { - return view_->selectionHaloFillAlpha(); -} - - -void GLWidget::addObject(GLObjectBase * o) { - view_->addObject(o); -} - - -QByteArray GLWidget::saveCamera() { - return view_->saveCamera(); -} - - -void GLWidget::restoreCamera(const QByteArray &ba) { - view_->restoreCamera(ba); -} - - -void GLWidget::stop() { - view_->stop(); -} - - -void GLWidget::start(float freq, GLRendererBase * r) { - if (r == nullptr) r = new RendererSimple(view_); - GLRendererBase * pr = nullptr; - view_->setRenderer(r, &pr); - if (pr != nullptr && pr != r) delete pr; - view_->start(freq); -} - - -void GLWidget::setBackColor(const QColor & c) { - view_->setBackColor(c); -} - - -void GLWidget::setLineWidth(const qreal & arg) { - view_->setLineWidth(arg); -} - - -void GLWidget::setFOV(const qreal & arg) { - view_->setFOV(arg); -} - - -void GLWidget::setDepthStart(const qreal & arg) { - view_->setDepthStart(arg); -} - - -void GLWidget::setDepthEnd(const qreal & arg) { - view_->setDepthEnd(arg); -} - - -void GLWidget::setAmbientColor(const QColor & arg) { - view_->setAmbientColor(arg); -} - - -void GLWidget::setLightEnabled(const bool & arg) { - view_->setLightEnabled(arg); -} - - -void GLWidget::setGrabMouseEnabled(const bool & arg) { - view_->setGrabMouseEnabled(arg); -} - - -void GLWidget::setMouseRotateEnabled(const bool & arg) { - view_->setMouseRotateEnabled(arg); -} - - -void GLWidget::setMouseSelectionEnabled(const bool & arg) { - view_->setMouseSelectionEnabled(arg); -} - - -void GLWidget::setCameraOrbit(const bool & arg) { - view_->setCameraOrbit(arg); -} - - -void GLWidget::setHoverHaloEnabled(const bool & arg) { - view_->setHoverHaloEnabled(arg); -} - - -void GLWidget::setHoverHaloColor(const QColor & arg) { - view_->setHoverHaloColor(arg); -} - - -void GLWidget::setHoverHaloFillAlpha(const qreal & arg) { - view_->setHoverHaloFillAlpha(arg); -} - - -void GLWidget::setSelectionHaloEnabled(const bool & arg) { - view_->setSelectionHaloEnabled(arg); -} - - -void GLWidget::setSelectionHaloColor(const QColor & arg) { - view_->setSelectionHaloColor(arg); -} - - -void GLWidget::setSelectionHaloFillAlpha(const qreal & arg) { - view_->setSelectionHaloFillAlpha(arg); -} - - -void GLWidget::viewDoubleClicked() { -// qDebug() << "click widget!!"; - if (view_->windowState() == Qt::WindowFullScreen) { -// view_->hide(); - container = QWidget::createWindowContainer(view_, this); - lay->addWidget(container); - container->show(); -// show(); - } else { -// hide(); - view_->setParent(nullptr); - view_->showFullScreen(); - lay->removeWidget(container); - } -// qDebug() << "click widge done!"; -} +#include "glwidget.h" +#include "renderer_simple.h" +#include "renderer_deferred_shading.h" +#include + + +GLWidget::GLWidget(QWidget *parent) : QWidget(parent) { + view_ = new QGLView(); + view_->setFlags(windowFlags() | Qt::FramelessWindowHint); + container = QWidget::createWindowContainer(view_, this); + lay = new QVBoxLayout(this); + lay->addWidget(container); + lay->setContentsMargins(0, 0, 0, 0); + lay->setSpacing(0); + setMouseTracking(true); + setWindowIcon(QIcon("://icons/qglview.png")); + connect(view_, &QGLView::doubleClick, this, &GLWidget::viewDoubleClicked); +} + + +QColor GLWidget::backColor() const { + return view_->backColor(); +} + + +qreal GLWidget::lineWidth() const { + return view_->lineWidth(); +} + + +qreal GLWidget::FOV() const { + return view_->FOV(); +} + + +qreal GLWidget::depthStart() const { + return view_->depthStart(); +} + + +qreal GLWidget::depthEnd() const { + return view_->depthEnd(); +} + + +QColor GLWidget::ambientColor() const { + return view_->ambientColor(); +} + + +bool GLWidget::isLightEnabled() const { + return view_->isLightEnabled(); +} + + +bool GLWidget::isGrabMouseEnabled() const { + return view_->isGrabMouseEnabled(); +} + + +bool GLWidget::isMouseRotateEnabled() const { + return view_->isMouseRotateEnabled(); +} + + +bool GLWidget::isMouseSelectionEnabled() const { + return view_->isMouseSelectionEnabled(); +} + + +bool GLWidget::isCameraOrbit() const +{ + return view_->isCameraOrbit(); +} + + +bool GLWidget::isHoverHaloEnabled() const { + return view_->isHoverHaloEnabled(); +} + + +QColor GLWidget::hoverHaloColor() const { + return view_->hoverHaloColor(); +} + + +qreal GLWidget::hoverHaloFillAlpha() const { + return view_->hoverHaloFillAlpha(); +} + + +bool GLWidget::isSelectionHaloEnabled() const { + return view_->isSelectionHaloEnabled(); +} + + +QColor GLWidget::selectionHaloColor() const { + return view_->selectionHaloColor(); +} + + +qreal GLWidget::selectionHaloFillAlpha() const { + return view_->selectionHaloFillAlpha(); +} + + +void GLWidget::addObject(GLObjectBase * o) { + view_->addObject(o); +} + + +QByteArray GLWidget::saveCamera() { + return view_->saveCamera(); +} + + +void GLWidget::restoreCamera(const QByteArray &ba) { + view_->restoreCamera(ba); +} + + +void GLWidget::stop() { + view_->stop(); +} + + +void GLWidget::start(float freq, GLRendererBase * r) { + if (r == nullptr) r = new RendererSimple(view_); + GLRendererBase * pr = nullptr; + view_->setRenderer(r, &pr); + if (pr != nullptr && pr != r) delete pr; + view_->start(freq); +} + + +void GLWidget::setBackColor(const QColor & c) { + view_->setBackColor(c); +} + + +void GLWidget::setLineWidth(const qreal & arg) { + view_->setLineWidth(arg); +} + + +void GLWidget::setFOV(const qreal & arg) { + view_->setFOV(arg); +} + + +void GLWidget::setDepthStart(const qreal & arg) { + view_->setDepthStart(arg); +} + + +void GLWidget::setDepthEnd(const qreal & arg) { + view_->setDepthEnd(arg); +} + + +void GLWidget::setAmbientColor(const QColor & arg) { + view_->setAmbientColor(arg); +} + + +void GLWidget::setLightEnabled(const bool & arg) { + view_->setLightEnabled(arg); +} + + +void GLWidget::setGrabMouseEnabled(const bool & arg) { + view_->setGrabMouseEnabled(arg); +} + + +void GLWidget::setMouseRotateEnabled(const bool & arg) { + view_->setMouseRotateEnabled(arg); +} + + +void GLWidget::setMouseSelectionEnabled(const bool & arg) { + view_->setMouseSelectionEnabled(arg); +} + + +void GLWidget::setCameraOrbit(const bool & arg) { + view_->setCameraOrbit(arg); +} + + +void GLWidget::setHoverHaloEnabled(const bool & arg) { + view_->setHoverHaloEnabled(arg); +} + + +void GLWidget::setHoverHaloColor(const QColor & arg) { + view_->setHoverHaloColor(arg); +} + + +void GLWidget::setHoverHaloFillAlpha(const qreal & arg) { + view_->setHoverHaloFillAlpha(arg); +} + + +void GLWidget::setSelectionHaloEnabled(const bool & arg) { + view_->setSelectionHaloEnabled(arg); +} + + +void GLWidget::setSelectionHaloColor(const QColor & arg) { + view_->setSelectionHaloColor(arg); +} + + +void GLWidget::setSelectionHaloFillAlpha(const qreal & arg) { + view_->setSelectionHaloFillAlpha(arg); +} + + +void GLWidget::viewDoubleClicked() { +// qDebug() << "click widget!!"; + if (view_->windowState() == Qt::WindowFullScreen) { +// view_->hide(); + container = QWidget::createWindowContainer(view_, this); + lay->addWidget(container); + container->show(); +// show(); + } else { +// hide(); + view_->setParent(nullptr); + view_->showFullScreen(); + lay->removeWidget(container); + } +// qDebug() << "click widge done!"; +} diff --git a/qglview/glwidget.h b/qglview/glwidget.h index 87eb6f1..1f8597e 100644 --- a/qglview/glwidget.h +++ b/qglview/glwidget.h @@ -1,88 +1,88 @@ -#ifndef GLWIDGET_H -#define GLWIDGET_H - -#include - - -class QGLView; -class GLRendererBase; -class GLObjectBase; - -class GLWidget : public QWidget -{ - Q_OBJECT - Q_PROPERTY (QColor backColor READ backColor WRITE setBackColor) - Q_PROPERTY (qreal lineWidth READ lineWidth WRITE setLineWidth) - Q_PROPERTY (qreal FOV READ FOV WRITE setFOV) - Q_PROPERTY (qreal depthStart READ depthStart WRITE setDepthStart) - Q_PROPERTY (qreal depthEnd READ depthEnd WRITE setDepthEnd) - Q_PROPERTY (QColor ambientColor READ ambientColor WRITE setAmbientColor) - Q_PROPERTY (bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled) - Q_PROPERTY (bool mouseRotate READ isMouseRotateEnabled WRITE setMouseRotateEnabled) - Q_PROPERTY (bool mouseSelection READ isMouseSelectionEnabled WRITE setMouseSelectionEnabled) - Q_PROPERTY (bool cameraOrbit READ isCameraOrbit WRITE setCameraOrbit) - Q_PROPERTY (bool hoverHalo READ isHoverHaloEnabled WRITE setHoverHaloEnabled) - Q_PROPERTY (QColor hoverHaloColor READ hoverHaloColor WRITE setHoverHaloColor) - Q_PROPERTY (qreal hoverHaloFillAlpha READ hoverHaloFillAlpha WRITE setHoverHaloFillAlpha) - Q_PROPERTY (bool selectionHalo READ isSelectionHaloEnabled WRITE setSelectionHaloEnabled) - Q_PROPERTY (QColor selectionHaloColor READ selectionHaloColor WRITE setSelectionHaloColor) - Q_PROPERTY (qreal selectionHaloFillAlpha READ selectionHaloFillAlpha WRITE setSelectionHaloFillAlpha) -public: - explicit GLWidget(QWidget *parent = nullptr); - QGLView * view() {return view_;} - - QColor backColor() const; - qreal lineWidth() const; - qreal FOV() const; - qreal depthStart() const; - qreal depthEnd() const; - QColor ambientColor() const; - bool isLightEnabled() const; - bool isGrabMouseEnabled() const; - bool isMouseRotateEnabled() const; - bool isMouseSelectionEnabled() const; - bool isCameraOrbit() const; - bool isHoverHaloEnabled() const; - QColor hoverHaloColor() const; - qreal hoverHaloFillAlpha() const; - bool isSelectionHaloEnabled() const; - QColor selectionHaloColor() const; - qreal selectionHaloFillAlpha() const; - - void addObject(GLObjectBase * o); - QByteArray saveCamera(); - void restoreCamera(const QByteArray & ba); - -public slots: - void stop(); - void start(float freq = 60.0, GLRendererBase * r = nullptr); - void setBackColor(const QColor & c); - void setLineWidth(const qreal & arg); - void setFOV(const qreal & arg); - void setDepthStart(const qreal & arg); - void setDepthEnd(const qreal & arg); - void setAmbientColor(const QColor & arg); - void setLightEnabled(const bool & arg); - void setGrabMouseEnabled(const bool & arg); - void setMouseRotateEnabled(const bool & arg); - void setMouseSelectionEnabled(const bool & arg); - void setCameraOrbit(const bool & arg); - void setHoverHaloEnabled(const bool & arg); - void setHoverHaloColor(const QColor & arg); - void setHoverHaloFillAlpha(const qreal & arg); - void setSelectionHaloEnabled(const bool & arg); - void setSelectionHaloColor(const QColor & arg); - void setSelectionHaloFillAlpha(const qreal & arg); - -private slots: - void viewDoubleClicked(); - -private: - QWidget * container; - QGLView * view_; - QLayout * lay; - -signals: -}; - -#endif // GLWIDGET_H +#ifndef GLWIDGET_H +#define GLWIDGET_H + +#include + + +class QGLView; +class GLRendererBase; +class GLObjectBase; + +class GLWidget : public QWidget +{ + Q_OBJECT + Q_PROPERTY (QColor backColor READ backColor WRITE setBackColor) + Q_PROPERTY (qreal lineWidth READ lineWidth WRITE setLineWidth) + Q_PROPERTY (qreal FOV READ FOV WRITE setFOV) + Q_PROPERTY (qreal depthStart READ depthStart WRITE setDepthStart) + Q_PROPERTY (qreal depthEnd READ depthEnd WRITE setDepthEnd) + Q_PROPERTY (QColor ambientColor READ ambientColor WRITE setAmbientColor) + Q_PROPERTY (bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled) + Q_PROPERTY (bool mouseRotate READ isMouseRotateEnabled WRITE setMouseRotateEnabled) + Q_PROPERTY (bool mouseSelection READ isMouseSelectionEnabled WRITE setMouseSelectionEnabled) + Q_PROPERTY (bool cameraOrbit READ isCameraOrbit WRITE setCameraOrbit) + Q_PROPERTY (bool hoverHalo READ isHoverHaloEnabled WRITE setHoverHaloEnabled) + Q_PROPERTY (QColor hoverHaloColor READ hoverHaloColor WRITE setHoverHaloColor) + Q_PROPERTY (qreal hoverHaloFillAlpha READ hoverHaloFillAlpha WRITE setHoverHaloFillAlpha) + Q_PROPERTY (bool selectionHalo READ isSelectionHaloEnabled WRITE setSelectionHaloEnabled) + Q_PROPERTY (QColor selectionHaloColor READ selectionHaloColor WRITE setSelectionHaloColor) + Q_PROPERTY (qreal selectionHaloFillAlpha READ selectionHaloFillAlpha WRITE setSelectionHaloFillAlpha) +public: + explicit GLWidget(QWidget *parent = nullptr); + QGLView * view() {return view_;} + + QColor backColor() const; + qreal lineWidth() const; + qreal FOV() const; + qreal depthStart() const; + qreal depthEnd() const; + QColor ambientColor() const; + bool isLightEnabled() const; + bool isGrabMouseEnabled() const; + bool isMouseRotateEnabled() const; + bool isMouseSelectionEnabled() const; + bool isCameraOrbit() const; + bool isHoverHaloEnabled() const; + QColor hoverHaloColor() const; + qreal hoverHaloFillAlpha() const; + bool isSelectionHaloEnabled() const; + QColor selectionHaloColor() const; + qreal selectionHaloFillAlpha() const; + + void addObject(GLObjectBase * o); + QByteArray saveCamera(); + void restoreCamera(const QByteArray & ba); + +public slots: + void stop(); + void start(float freq = 60.0, GLRendererBase * r = nullptr); + void setBackColor(const QColor & c); + void setLineWidth(const qreal & arg); + void setFOV(const qreal & arg); + void setDepthStart(const qreal & arg); + void setDepthEnd(const qreal & arg); + void setAmbientColor(const QColor & arg); + void setLightEnabled(const bool & arg); + void setGrabMouseEnabled(const bool & arg); + void setMouseRotateEnabled(const bool & arg); + void setMouseSelectionEnabled(const bool & arg); + void setCameraOrbit(const bool & arg); + void setHoverHaloEnabled(const bool & arg); + void setHoverHaloColor(const QColor & arg); + void setHoverHaloFillAlpha(const qreal & arg); + void setSelectionHaloEnabled(const bool & arg); + void setSelectionHaloColor(const QColor & arg); + void setSelectionHaloFillAlpha(const qreal & arg); + +private slots: + void viewDoubleClicked(); + +private: + QWidget * container; + QGLView * view_; + QLayout * lay; + +signals: +}; + +#endif // GLWIDGET_H diff --git a/qglview/openglwindow.cpp b/qglview/openglwindow.cpp index 375d1fa..cb3bc2a 100644 --- a/qglview/openglwindow.cpp +++ b/qglview/openglwindow.cpp @@ -1,96 +1,96 @@ -#include "openglwindow.h" -#include -#include -#include -#include -#include - - -OpenGLWindow::OpenGLWindow(QWindow *parent) - : QWindow(parent) - , m_context(nullptr) - , m_device(nullptr) -{ - setFlags(flags() | Qt::FramelessWindowHint); - setSurfaceType(QWindow::OpenGLSurface); - QSurfaceFormat format = QSurfaceFormat::defaultFormat(); -// qDebug() << format; -#ifdef QT_OPENGL_ES_2 - format.setRenderableType(QSurfaceFormat::OpenGLES); -#else - if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { - format.setVersion(2, 0); - format.setProfile(QSurfaceFormat::NoProfile); - } -#endif - format.setDepthBufferSize(24); - format.setSamples(8); -// format.setStencilBufferSize(8); - setFormat(format); - QSurfaceFormat::setDefaultFormat(format); -} - - -OpenGLWindow::~OpenGLWindow() { - delete m_device; -} - - -void OpenGLWindow::render(QPainter *painter) { -} - - -void OpenGLWindow::initialize() { -} - - -void OpenGLWindow::render() { -// if (!m_device) m_device = new QOpenGLPaintDevice; -// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); -// m_device->setSize(size() * devicePixelRatio()); -// m_device->setDevicePixelRatio(devicePixelRatio()); -// QPainter painter(m_device); -// render(&painter); -} - - -void OpenGLWindow::renderLater() { - requestUpdate(); -} - - -bool OpenGLWindow::event(QEvent *event) { - switch (event->type()) { - case QEvent::UpdateRequest: - renderNow(); - return true; - default: - return QWindow::event(event); - } -} - - -void OpenGLWindow::exposeEvent(QExposeEvent *event) { - if (isExposed()) renderNow(); -} - - -void OpenGLWindow::renderNow() { - if (!isExposed()) - return; - bool needsInitialize = false; - if (!m_context) { - m_context = new QOpenGLContext(this); - m_context->setFormat(requestedFormat()); - m_context->create(); - needsInitialize = true; - } - m_context->makeCurrent(this); - if (needsInitialize) { - initializeOpenGLFunctions(); - initialize(); - } - render(); - m_context->swapBuffers(this); -} - +#include "openglwindow.h" +#include +#include +#include +#include +#include + + +OpenGLWindow::OpenGLWindow(QWindow *parent) + : QWindow(parent) + , m_context(nullptr) + , m_device(nullptr) +{ + setFlags(flags() | Qt::FramelessWindowHint); + setSurfaceType(QWindow::OpenGLSurface); + QSurfaceFormat format = QSurfaceFormat::defaultFormat(); +// qDebug() << format; +#ifdef QT_OPENGL_ES_2 + format.setRenderableType(QSurfaceFormat::OpenGLES); +#else + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { + format.setVersion(2, 0); + format.setProfile(QSurfaceFormat::NoProfile); + } +#endif + format.setDepthBufferSize(24); + format.setSamples(8); +// format.setStencilBufferSize(8); + setFormat(format); + QSurfaceFormat::setDefaultFormat(format); +} + + +OpenGLWindow::~OpenGLWindow() { + delete m_device; +} + + +void OpenGLWindow::render(QPainter *painter) { +} + + +void OpenGLWindow::initialize() { +} + + +void OpenGLWindow::render() { +// if (!m_device) m_device = new QOpenGLPaintDevice; +// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); +// m_device->setSize(size() * devicePixelRatio()); +// m_device->setDevicePixelRatio(devicePixelRatio()); +// QPainter painter(m_device); +// render(&painter); +} + + +void OpenGLWindow::renderLater() { + requestUpdate(); +} + + +bool OpenGLWindow::event(QEvent *event) { + switch (event->type()) { + case QEvent::UpdateRequest: + renderNow(); + return true; + default: + return QWindow::event(event); + } +} + + +void OpenGLWindow::exposeEvent(QExposeEvent *event) { + if (isExposed()) renderNow(); +} + + +void OpenGLWindow::renderNow() { + if (!isExposed()) + return; + bool needsInitialize = false; + if (!m_context) { + m_context = new QOpenGLContext(this); + m_context->setFormat(requestedFormat()); + m_context->create(); + needsInitialize = true; + } + m_context->makeCurrent(this); + if (needsInitialize) { + initializeOpenGLFunctions(); + initialize(); + } + render(); + m_context->swapBuffers(this); +} + diff --git a/qglview/openglwindow.h b/qglview/openglwindow.h index 6816665..504028c 100644 --- a/qglview/openglwindow.h +++ b/qglview/openglwindow.h @@ -1,36 +1,36 @@ -#include -#include - -class QPainter; -class QOpenGLContext; -class QOpenGLPaintDevice; - - -class OpenGLWindow : public QWindow, protected QOpenGLFunctions -{ - Q_OBJECT -public: - explicit OpenGLWindow(QWindow *parent = nullptr); - ~OpenGLWindow(); - - virtual void render(QPainter *painter); - virtual void render(); - - virtual void initialize(); - - QOpenGLContext * context() {return m_context;} - -public slots: - void renderLater(); - void renderNow(); - -protected: - bool event(QEvent *event) override; - - void exposeEvent(QExposeEvent *event) override; - -private: - QOpenGLContext *m_context; - QOpenGLPaintDevice *m_device; -}; - +#include +#include + +class QPainter; +class QOpenGLContext; +class QOpenGLPaintDevice; + + +class OpenGLWindow : public QWindow, protected QOpenGLFunctions +{ + Q_OBJECT +public: + explicit OpenGLWindow(QWindow *parent = nullptr); + ~OpenGLWindow(); + + virtual void render(QPainter *painter); + virtual void render(); + + virtual void initialize(); + + QOpenGLContext * context() {return m_context;} + +public slots: + void renderLater(); + void renderNow(); + +protected: + bool event(QEvent *event) override; + + void exposeEvent(QExposeEvent *event) override; + +private: + QOpenGLContext *m_context; + QOpenGLPaintDevice *m_device; +}; + diff --git a/qglview/plugin/CMakeLists.txt b/qglview/plugin/CMakeLists.txt index 324c740..4245507 100644 --- a/qglview/plugin/CMakeLists.txt +++ b/qglview/plugin/CMakeLists.txt @@ -1,18 +1 @@ -if (DESIGNER_PLUGINS) - if (NOT Qt5) - message(WARNING "Building ${PROJECT_NAME} available only on Qt5!") - else() - project(qglview_plugin) - include_directories("..") - add_definitions(-DQT_PLUGIN) - add_definitions(-DQT_NO_DEBUG) - add_definitions(-DQT_SHARED) - add_definitions(-DQDESIGNER_EXPORT_WIDGETS) - find_qt(Qt5 Core Designer Gui Widgets OpenGL) - qt_sources(SRC) - qt_wrap(${SRC} CPPS out_CPP QMS out_QM) - qt_add_library(${PROJECT_NAME} SHARED out_CPP) - qt_target_link_libraries(${PROJECT_NAME} qglview) - qt_install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION QtPlugins/designer) - endif() -endif() +_qt_plugin(qglview "Gui;Widgets;OpenGL" "qglview") diff --git a/qglview/qglview.cpp b/qglview/qglview.cpp index 74adf53..1878a40 100644 --- a/qglview/qglview.cpp +++ b/qglview/qglview.cpp @@ -1,846 +1,846 @@ -/* - QGLView - Ivan Pelipenko peri4ko@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 . -*/ - -#include "qglview.h" - -#include -#include - - -QGLView::QGLView(): OpenGLWindow(), fbo_selection(3) { -// setFrameShape(QFrame::NoFrame); -// setViewportUpdateMode(FullViewportUpdate); -// setCacheMode(CacheNone); -// setMouseTracking(true); -// setFocusPolicy(Qt::WheelFocus); -// setScene(new QGraphicsScene()); -// setInteractive(true); - setIcon(QIcon("://icons/qglview.png")); - deleting_ = false; - timer = 0; - need_init_ = is_first_draw = true; - objects_.is_root = true; - objects_.view_ = this; - backColor_ = Qt::darkGray; - hoverHaloColor_ = QColor(195, 140, 255, 96); - selectionHaloColor_ = QColor(175, 255, 140); - ambientColor_ = QColor(10, 10, 10); - lastPos = QPoint(-1, -1); - lineWidth_ = 1.; - max_anisotropic = 1; - max_texture_chanels = 8; - cameraOrbit_ = lightEnabled_ = true; - shaders_supported = selecting_ = customMouseMove_ = false; - sel_button = Qt::LeftButton; - sel_mod = Qt::NoModifier; - renderer_ = nullptr; - fps_cnt = 0; - fps_tm = fps_ = 0.; - sel_obj = hov_obj = nullptr; - fogDensity_ = fogEnd_ = 1.; - fogStart_ = 0.; - fogMode_ = Exp; - hoverHaloFill_ = 0.333f; - selectionHaloFill_ = 0.5f; - //lmode = Simple; - shader_select = shader_halo = nullptr; - setFeature(qglMSAA, false); - setFeature(qglFXAA, false); - setFeature(qglLinearFiltering, true); - setFeature(qglAnisotropicLevel, 8); - setFeature(qglHDR, false); - setFeature(qglEyeAccomodationEnabled, false); - setFeature(qglEyeAccomodationTime, 16.); - setFeature(qglEyeAccomodationMaxSpeed, 0.2); - setFeature(qglBloomEnabled, false); - setFeature(qglBloomThreshold, 0.9); - setFeature(qglBloomFactor, 1.); - setFeature(qglBloomRadius, 8); - setFeature(qglMotionBlurEnabled, false); - setFeature(qglMotionBlurFactor, 1.); - setFeature(qglMotionBlurSteps, 8); - setFeature(qglShadowsEnabled, false); - setFeature(qglShadowsMapSize, 512); - setFeature(qglShadowsSoftEnabled, true); - setFeature(qglReflectionsEnabled, false); - setFeature(qglReflectionsBlur, true); - setFeature(qglSSAOEnabled, false); - setFeature(qglSSAORadius, 5); - setFeature(qglDepthOfFieldEnabled, false); - setFeature(qglDepthOfFieldAutoFocusEnabled, true); - setFeature(qglDepthOfFieldAutoFocusSpeed, 0.1); - setFeature(qglDepthOfFieldFocus, 1.); - setFeature(qglDepthOfFieldDiaphragm, 8.); - mouse_first = mouseSelect_ = hoverHalo_ = selectionHalo_ = true; - mouseRotate_ = true; - fogEnabled_ = is_init = grabMouse_ = shaders_bind = changed_ = false; - rmode = GLObjectBase::Fill; - sel_mode = QGLView::SingleSelection; -// sel_pen = QPen(Qt::black, 1, Qt::DashLine); -// sel_brush = QBrush(QColor(170, 100, 255, 120)); - camera()->setAim(QVector3D()); - camera()->setPos(QVector3D(2, 2, 2)); - camera()->setName("Camera"); - addObject(camera()); - emit cameraPosChanged(camera()->pos()); - //camera().aim_ = camera().pos_; - ktm_.restart(); -} - - -QGLView::~QGLView() { - stop(); - if (shader_select) delete shader_select; - if (shader_halo) delete shader_halo; - deleting_ = true; -} - - -void QGLView::stop() { - if (timer) killTimer(timer); - timer = 0; -} - - -void QGLView::start(float freq) { - stop(); - timer = startTimer(freq <= 0.f ? 0 : int(1000.f / freq)); -} - - -GLRendererBase * QGLView::renderer() { - return renderer_; -} - - -void QGLView::setRenderer(GLRendererBase * r, GLRendererBase ** prev) { - if (prev != nullptr) *prev = renderer_; - renderer_ = r; -} - - -void QGLView::addObject(GLObjectBase * o) { - objects_.addChild(o); - o->setView(this); - collectLights(); - QList cl = o->children(true); - cl << o; - foreach (GLObjectBase * i, cl) { - emit objectAdded(i); - } - if (is_init) { - o->init(); - } -} - - -int QGLView::objectsCount(bool all) { - if (!all) return objects_.childCount(); - int cnt = 0; - objectsCountInternal(&cnt, &objects_); - return cnt; -} - - -void QGLView::removeObject(GLObjectBase * o, bool inChildren) { - o->setView(nullptr); - if (inChildren) - removeObjectInternal(o, &objects_); - else - objects_.removeChild(o); - objectDeleted(o); -} - - -void QGLView::removeObject(GLObjectBase & o, bool inChildren) { - removeObject(&o, inChildren); -} - - -void QGLView::clearObjects(bool deleteAll) { - removeObject(camera_); - objects_.clearChildren(deleteAll); - addObject(camera()); - selectObject(nullptr); - hov_obj = nullptr; -} - - -QList QGLView::objects(bool all) { - return objects_.children(all); -} - - -int QGLView::lightsCount() const { - return lights_.size(); -} - - -void QGLView::removeLight(int index) { - removeObject(lights_.at(index)); - lights_.removeAt(index); -} - - -void QGLView::removeLight(Light * l) { - foreach (Light * i, lights_) - if (i == l) removeObject(i); - lights_.removeAll(l); -} - - -void QGLView::clearLights(bool deleteAll) { - if (deleteAll) - foreach (Light * i, lights_) delete i; - lights_.clear(); -} - - -void QGLView::addTexture(const QString & path) { - textures_manager->addTexture(path); -} - - -void QGLView::addAnimation(const QString & dir, const QString & name) { - textures_manager->addAnimation(dir, name); -} - - -Light * QGLView::light(int index) { - return lights_[index]; -} - - -Light * QGLView::light(const QString & name) { - foreach (Light * i, lights_) - if (i->name_ == name) return i; - return nullptr; -} - - -void QGLView::selectObject(GLObjectBase * o) { - if (o == sel_obj) return; - GLObjectBase * pso = sel_obj; - sel_obj = o; - emit selectionChanged(sel_obj, pso); -} - - -void QGLView::resizeEvent(QResizeEvent * e) { - renderLater(); -} - -void QGLView::timerEvent(QTimerEvent *) { - renderNow(); - if (ktm_.elapsed() < QApplication::keyboardInputInterval()) return; - Qt::KeyboardModifiers km = QApplication::keyboardModifiers(); - foreach (int i, keys_) - emit keyEvent((Qt::Key)i, km); -} - - -void QGLView::render() { - if (!isVisible()) return; - resizeGL(width(), height()); - QRect g_rect(QPoint(), size()); - emit glBeforePaint(); - //qDebug() << "paintGL"; - //QMutexLocker ml_v(&v_mutex); - glEnable(GL_CULL_FACE); - //glDisable(GL_CULL_FACE); - camera()->apply(aspect); - //objects_.preparePos(camera()); - start_rp.cam_offset_matrix = camera()->offsetMatrix(); - start_rp.proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX); - start_rp.view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX); - //objects_.buildTransform(); - - /// Selection detect - //glClearFramebuffer(QColor(100, 0, 0, 0)); - if (mouseSelect_) { - glReleaseTextures(); - glEnableDepth(); - glDisable(GL_TEXTURE_1D); - glDisable(GL_TEXTURE_2D); - glDisable(GL_TEXTURE_CUBE_MAP); - glDisable(GL_MULTISAMPLE); - glDisable(GL_LIGHTING); - glDisable(GL_BLEND); - glDisable(GL_ALPHA_TEST); - glDisable(GL_RESCALE_NORMAL); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - fbo_selection.bind(); - fbo_selection.setWriteBuffer(0); - glClearFramebuffer(QColor(0, 0, 0, 0)); - if (shaders_supported && shader_select->isLinked()) shader_select->bind(); - renderSelection(); - if (shaders_supported && shader_select->isLinked()) shader_select->release(); - uchar cgid[4] = {0, 0, 0, 0}; - uint iid = 0; - GLObjectBase * so = nullptr; - if (!g_rect.contains(lastPos)) { - if (hov_obj != nullptr) { - hov_obj = nullptr; - emit hoverChanged(nullptr, hov_obj); - } - } else { - glReadPixels(lastPos.x(), height() - lastPos.y(), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, cgid); - iid = uint(cgid[0] << 24) | uint(cgid[1] << 16) | uint(cgid[2] << 8) | cgid[3]; - so = ids.value(iid, nullptr); - //qDebug() <name() << cgid[3]; - } - if (selectionHalo_ && sel_obj) { - fbo_selection.setWriteBuffer(2); - renderHalo(sel_obj, qHash((quint64)sel_obj), selectionHaloColor_, selectionHaloFill_); - } - if (hoverHalo_ && hov_obj) { - fbo_selection.setWriteBuffer(1); - renderHalo(hov_obj, iid, hoverHaloColor_, hoverHaloFill_); - } - fbo_selection.release(); - glEnableDepth(); - /*glEnableClientState(GL_NORMAL_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY);*/ - } - - camera()->apply(aspect); - start_rp.cam_offset_matrix = camera()->offsetMatrix(); - cur_mvpm = start_rp.proj_matrix * start_rp.view_matrix * start_rp.cam_offset_matrix; - //objects_.preparePos(camera()); - - static GLRendererBase * prev_rend = nullptr; - glShadeModel(GL_SMOOTH); - if (prev_rend != renderer_) { - prev_rend = renderer_; - if (renderer_ != nullptr) { - renderer_->init(width(), height()); - renderer_->resize(width(), height()); - renderer_->reloadShaders(); - } - } - emit glBeginPaint(); - if (renderer_ != nullptr) { - renderer_->rp.prepare(); - renderer_->prepareScene(); - renderer_->renderScene(); - } - emit glPainting(); - glUseProgram(0); - if (selectionHalo_ || hoverHalo_) { - glReleaseTextures(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - //glClearFramebuffer(Qt::black, false); - - glActiveTexture(GL_TEXTURE0); - glEnable(GL_BLEND); - glDisable(GL_TEXTURE_CUBE_MAP); - glDisable(GL_LIGHTING); - glDisableDepth(); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - if (selectionHalo_ && sel_obj) { - glBindTexture(GL_TEXTURE_2D, fbo_selection.colorTexture(2)); - //qDebug() << "draw sel"; - glDrawQuad(); - } - if (hoverHalo_ && hov_obj) { - glBindTexture(GL_TEXTURE_2D, fbo_selection.colorTexture(1)); - //qDebug() << "draw hover"; - //glBindTexture(GL_TEXTURE_2D, textures_manager->loadTexture("batt_pn.jpg")); - glDrawQuad(); - } - } - - glResetAllTransforms(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glUseProgram(0); - - //glDisable(GL_BLEND); - //glDisable(GL_LIGHTING); - //glActiveTexture(GL_TEXTURE0); - //glBindTexture(GL_TEXTURE_2D, textures_manager->loadTexture("batt_pn.jpg")); - //glDrawQuad(); - - emit glEndPaint(); - - /*releaseShaders(); - glActiveTextureChannel(0); - glBindTexture(GL_TEXTURE_2D, 0); - glDisable(GL_LIGHTING); - glDisable(GL_DEPTH_TEST); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4f(0.3, 0.5, 0.8, 0.5); - glResetAllTransforms(); - glBegin(GL_QUADS); - glTexCoord2f(0.f, 0.f); glVertex2f(-1.f, -1.f); - glTexCoord2f(1.f, 0.f); glVertex2f(1.f, -1.); - glTexCoord2f(1.f, 1.f); glVertex2f(1.f, 1.f); - glTexCoord2f(0.f, 1.f); glVertex2f(-1.f, 1.f); - glEnd();*/ - /* - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glDisable(GL_LIGHTING); - glActiveTextureChannel(0); - glBindTexture(GL_TEXTURE_2D, fbo->texture()); - glDisable(GL_DEPTH_TEST); - glBegin(GL_QUADS); - glColor3f(1.f, 1.f, 1.f); - glTexCoord2f(0.f, 0.f); glVertex2f(-1.f, -1.f); - glTexCoord2f(0.f, 1.f); glVertex2f(-1.f, 1.f); - glTexCoord2f(1.f, 1.f); glVertex2f(1.f, 1.f); - glTexCoord2f(1.f, 0.f); glVertex2f(1.f, -1.); - glEnd(); - glEnable(GL_DEPTH_TEST);*/ - fps_tm += time.elapsed(); - time.restart(); - fps_cnt++; - if (fps_tm < 1000.) return; - fps_ = fps_cnt / fps_tm * 1000.; - fps_tm = 0.; - fps_cnt = 0; -} - - -void QGLView::initialize() { - //initializeOpenGLFunctions(); - glEnable(GL_TEXTURE_MAX_ANISOTROPY_EXT); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glEnableDepth(); - glEnable(GL_CULL_FACE); - glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1); - glActiveTexture(GL_TEXTURE0 + 3); - glEnable(GL_TEXTURE_GEN_S); - glEnable(GL_TEXTURE_GEN_T); - glEnable(GL_TEXTURE_GEN_R); - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); - glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - glActiveTexture(GL_TEXTURE0); - glShadeModel(GL_SMOOTH); - glCullFace(GL_BACK); - glEnable(GL_COLOR_MATERIAL); - glColorMaterial(GL_FRONT, GL_DIFFUSE); - - textures_manager->loadTextures(); - objects_.initInternal(); - checkCaps(); - - shader_select = new QOpenGLShaderProgram(context()); - shader_halo = new QOpenGLShaderProgram(context()); - reloadThisShaders(); - is_init = true; - //resizeGL(width(), height()); - need_init_ = false; - emit glInitializeDone(); -} - - -void QGLView::renderHalo(const GLObjectBase * obj, const uint iid, const QColor & color, const float & fill) { - if (!shaders_supported) return; - if (!shader_halo) return; - if (!shader_halo->isLinked()) return; - if (obj) { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, fbo_selection.colorTexture()); - shader_halo->bind(); - shader_halo->setUniformValue("qgl_ModelViewProjectionMatrix", QMatrix4x4()); - shader_halo->setUniformValue("t0", 0); - shader_halo->setUniformValue("dt", QVector2D(1.f / width(), 1.f / height())); - shader_halo->setUniformValue("selected", QVector4D(float((iid >> 24) & 0xFF) / 255.f, - float((iid >> 16) & 0xFF) / 255.f, - float((iid >> 8) & 0xFF) / 255.f, - float( iid & 0xFF) / 255.f)); - shader_halo->setUniformValue("color", color); - shader_halo->setUniformValue("fill", GLfloat(fill)); - //qDebug() << "render halo" << iid << shader_halo->log() << shader_halo->programId(); - glDisableDepth(); - //glClearFramebuffer(color); - glDrawQuad(shader_halo); - glDepthMask(GL_TRUE); - //glFlush(); - shader_halo->release(); - } else { - glClearFramebuffer(Qt::black, false); - } -} - - -void QGLView::renderSelection() { -// cid = 1; - ids.clear(); - if (shaders_supported) { - if (shader_select) { - if (shader_select->isLinked()) { - sh_id_loc = shader_select->uniformLocation("id"); - shader_select->setUniformValue("z_far", GLfloat(depthEnd())); - shader_select->setUniformValue("z_near", GLfloat(depthStart())); - } - } - } - //qDebug() << sh_id_loc; - start_rp.view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX); - glPushMatrix(); - renderSingleSelection(objects_); - glPopMatrix(); -} - - -void QGLView::renderSingleSelection(GLObjectBase & o) { - if (!o.isInit()) { - o.init(); - o.loadTextures(); - } - if (!o.visible_ || !o.select_) return; - QMatrix4x4 curview = start_rp.view_matrix * start_rp.cam_offset_matrix * o.itransform_; - uint id = qHash((quint64)&o); - ids.insert(id, &o); - glLineWidth(o.line_width > 0.f ? o.line_width : lineWidth_); - glPointSize(o.line_width > 0.f ? o.line_width : lineWidth_); - if (shaders_supported){ - if (shader_select) { - if (shader_select->isLinked()) { - setUniformMatrices(shader_select, start_rp.proj_matrix, curview); - shader_select->setUniformValue(sh_id_loc, QVector4D(float((id >> 24) & 0xFF) / 255.f, - float((id >> 16) & 0xFF) / 255.f, - float((id >> 8) & 0xFF) / 255.f, - float(id & 0xFF) / 255.f)); - } - } - } else { - setGLMatrix(curview); - glColor4f(float((id >> 24) & 0xFF) / 255.f, - float((id >> 16) & 0xFF) / 255.f, - float((id >> 8) & 0xFF) / 255.f, - float(id & 0xFF) / 255.f); - } - //qDebug() << o.name() << "assign to" << sh_id_loc << cid; - //glColor4f(float((cid >> 24) & 0xFF) / 255.f, float((cid >> 16) & 0xFF) / 255.f, float((cid >> 8) & 0xFF) / 255.f, float(cid & 0xFF) / 255.f); -// ++cid; - o.draw(nullptr, true); - foreach (GLObjectBase * i, o.children_) - renderSingleSelection(*i); -} - - -void QGLView::collectLights() { - lights_.clear(); - collectObjectLights(&objects_); -} - - -void QGLView::objectDeleted(GLObjectBase * o) { - if (deleting_) return; - //qDebug() << "del" << o; - if (sel_obj == o) selectObject(nullptr); - if (hov_obj == o) hov_obj = nullptr; - collectLights(); -} - - -void QGLView::collectObjectLights(GLObjectBase * o) { - if (o->type_ == GLObjectBase::glLight) { - lights_ << globject_cast(o); - o->view_ = this; - } - foreach (GLObjectBase * i, o->children()) - collectObjectLights(i); -} - - -void QGLView::objectsCountInternal(int * cnt, GLObjectBase * where) { - ++(*cnt); - foreach (GLObjectBase * i, where->children_) - objectsCountInternal(cnt, i); -} - - -void QGLView::removeObjectInternal(GLObjectBase * o, GLObjectBase * where) { - foreach (GLObjectBase * i, where->children_) { - if (o == i) - where->removeChild(i); - else - removeObjectInternal(o, i); - objectDeleted(i); - } -} - - -void QGLView::checkCaps() { - glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropic); - //glGetIntegerv(GL_MAX_TEXTURE_UNITS, &max_texture_chanels); - //qDebug() << max_texture_chanels; - //qDebug() << max_texture_chanels; - shaders_supported = QOpenGLShaderProgram::hasOpenGLShaderPrograms(); -} - - -void QGLView::reloadThisShaders() { - if (!shaders_supported) return; - loadShaders(shader_select, "selection", "://shaders"); - loadShaders(shader_halo, "selection_halo", "://shaders"); - //loadShaders(shader_rope, "rope", "://shaders"); -} - -void QGLView::glReleaseTextures(int channels) { - for (int i = channels - 1; i >= 0; --i) { - glActiveTexture(GL_TEXTURE0 + i); - glBindTexture(GL_TEXTURE_2D, 0); - glBindTexture(GL_TEXTURE_CUBE_MAP, 0); - } -} - - -void QGLView::applyFog() { - GLfloat fog_col[4] = {float(fogColor_.redF()), float(fogColor_.greenF()), float(fogColor_.blueF()), .0f}; - if (fogEnabled_) { - glEnable(GL_FOG); - glFogf(GL_FOG_DENSITY, fogDensity_); - glFogf(GL_FOG_START, fogStart_); - glFogf(GL_FOG_END, fogEnd_); - glFogi(GL_FOG_MODE, fogMode_); - fog_col[0] = fogColor_.redF(); - fog_col[1] = fogColor_.greenF(); - fog_col[2] = fogColor_.blueF(); - glFogfv(GL_FOG_COLOR, fog_col); - } else glDisable(GL_FOG); -} - - -void QGLView::resizeGL(int width, int height) { - if (!is_init) return; - if (width <= 0 || height <= 0) return; - if (prev_size == QSize(width, height)) return; - prev_size = QSize(width, height); - aspect = float(width) / float(height); - if (renderer_) renderer_->resize(width, height); - mouse_first = true; - //qDebug() << "resize" << width << height; - fbo_selection.resize(width, height); - iaspect = (aspect == 0.f) ? 0. : 1 / aspect; - glViewport(0, 0, width, height); - emit glResize(width, height); -} - - -void QGLView::mouseReleaseEvent(QMouseEvent * e) { -// qDebug() << "mouseReleaseEvent" << e << isActive(); -// QGraphicsView::mouseReleaseEvent(e); - //setCursor(QCursor(Qt::ArrowCursor)); - selecting_ = false; - if (mouseSelect_ && e->button() == Qt::LeftButton) { - if ((lastPos - downPos).manhattanLength() < 8) { - if (sel_obj != hov_obj) - selectObject(hov_obj); - } - } - emit glMouseReleaseEvent(e); -} - - -void QGLView::mousePressEvent(QMouseEvent * e) { -// qDebug() << "mousePressEvent" << e << isActive(); -// QGraphicsView::mousePressEvent(e); -// mouseThis_ = (scene()->itemAt(mapToScene(e->pos()) , QTransform() ) == 0); - selecting_ = false; - if (!QRect(QPoint(), size()).contains(e->pos())) return; - /// TODO select by rect - //if (e->button() == sel_button && e->modifiers() == sel_mod) - // selecting_ = true; - lastPos = e->pos(); - downPos = lastPos; - //qDebug() << mouseThis_; - emit glMousePressEvent(e); -} - - -void QGLView::mouseMoveEvent(QMouseEvent * e) { -// qDebug() << "mouseMoveEvent" << e << isActive(); -// QGraphicsView::mouseMoveEvent(e); - //lastPos = e->pos(); - if (selecting_) { - return; - } -// if (!QRect(QPoint(), size()).contains(e->pos())) return; - //if (scene()->itemAt(mapToScene(e->pos())) != 0) return; - ///qDebug() << e->x() << e->y(); - QRect g_rect(QPoint(), size()); - if (mouseRotate_) { - float dx = e->x() - lastPos.x(); - float dy = e->y() - lastPos.y(); - if (e->buttons() & Qt::LeftButton) { - //camera().angle_z += dx / 4.; - //camera().angle_xy += dy / 4.; - if (cameraOrbit_) { - camera()->orbitZ(dx / 4.f); - camera()->orbitXY(dy / 4.f); - } else { - camera()->rotateZ(dx / 4.f); - camera()->rotateXY(dy / 4.f); - } - emit cameraPosChanged(camera()->pos()); - } else if (e->buttons() & Qt::RightButton) { - float ad = camera()->distance(); - camera()->moveLeft(dx / 1000.f * ad); - camera()->moveUp(dy / 1000.f * ad); - //camera().pos.setX(camera().pos.x() + camera().pos.z() * dx / 500.); - //camera().pos.setY(camera().pos.y() - camera().pos.z() * dy / 500.); - emit cameraPosChanged(camera()->pos()); - } - //lights[0]->pos_ = camera().pos(); - } - if (customMouseMove_) emit customMouseMoveEvent(e->pos(), lastPos, e->buttons()); - lastPos = e->pos(); - if (grabMouse_) { - //if (!isrunning) return; - QCursor::setPos(mapToGlobal(QRect(QPoint(), size()).center())); - static bool mouse_sec = false; - if (mouse_sec) { - mouse_sec = false; - return; - } - if (mouse_first) { - mouse_first = false; - mouse_sec = true; - //qDebug() << "first" << e->pos(); - return; - } - lastPos = g_rect.center(); - int dx = e->x() - lastPos.x(); - int dy = e->y() - lastPos.y(); - emit glMouseMoveEvent(new QMouseEvent(QEvent::MouseMove, QPoint(dx, dy), e->button(), e->buttons(), e->modifiers())); - return; - } - emit glMouseMoveEvent(e); -} - - -void QGLView::wheelEvent(QWheelEvent * e) { - if (mouseRotate_) { - if (e->delta() > 0) camera()->flyCloser(0.1f); //camera().pos.setZ(camera().pos.z() - 0.1 * camera().pos.z()); - if (e->delta() < 0) camera()->flyFarer(0.1f); //camera().pos.setZ(camera().pos.z() + 0.1 * camera().pos.z()); - emit cameraPosChanged(camera()->pos()); - } - emit glWheelEvent(e); -} - - -void QGLView::leaveEvent(QEvent * ) { - lastPos = QPoint(-1, -1); - //qDebug() << lastPos; -} - - -void QGLView::keyPressEvent(QKeyEvent * e) { - emit glKeyPressEvent(e); - if (e->key() > 0) keys_.insert(e->key()); - if (e->key() == Qt::Key_F11) { - emit doubleClick(); - } -} - - -void QGLView::keyReleaseEvent(QKeyEvent * e) { - emit glKeyReleaseEvent(e); - keys_.remove(e->key()); -} - - -void QGLView::focusOutEvent(QFocusEvent *) { - keys_.clear(); -} - - -void QGLView::mouseDoubleClickEvent(QMouseEvent * e) { - if (e->buttons().testFlag(Qt::MidButton)) - emit doubleClick(); -} - - -QByteArray QGLView::saveCamera() { - ChunkStream cs; - const Camera * c = camera(); - cs.add(1, c->posX()); - cs.add(2, c->posY()); - cs.add(3, c->posZ()); - cs.add(4, c->aim().x()); - cs.add(5, c->aim().y()); - cs.add(6, c->aim().z()); - cs.add(7, c->angleZ()); - cs.add(8, c->angleXY()); - cs.add(9, c->angleRoll()); - cs.add(10, c->FOV()); - return cs.data(); -} - - -void QGLView::restoreCamera(const QByteArray &ba) { - if (ba.isEmpty()) return; - ChunkStream cs(ba); - QVector3D pos, aim, ang; - while (!cs.atEnd()) { - switch (cs.read()) { - case 1: pos.setX(cs.getData()); break; - case 2: pos.setY(cs.getData()); break; - case 3: pos.setZ(cs.getData()); break; - case 4: aim.setX(cs.getData()); break; - case 5: aim.setY(cs.getData()); break; - case 6: aim.setZ(cs.getData()); break; - case 7: ang.setZ(cs.getData()); break; - case 8: ang.setY(cs.getData()); break; - case 9: ang.setX(cs.getData()); break; - case 10: setFOV(cs.getData()); break; - default: break; - } - } - camera()->setPos(pos); - camera()->setAim(aim); - camera()->setAngles(ang); -} - - -QByteArray QGLView::saveFeatures() { - QByteArray ba; - QDataStream ds(&ba, QIODevice::WriteOnly); - ds << features_; - return ba; -} - - -void QGLView::restoreFeatures(const QByteArray & ba) { - QHash f; - QDataStream ds(ba); - ds >> f; - features_ = f; -} - +/* + QGLView + Ivan Pelipenko peri4ko@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 . +*/ + +#include "qglview.h" + +#include +#include + + +QGLView::QGLView(): OpenGLWindow(), fbo_selection(3) { +// setFrameShape(QFrame::NoFrame); +// setViewportUpdateMode(FullViewportUpdate); +// setCacheMode(CacheNone); +// setMouseTracking(true); +// setFocusPolicy(Qt::WheelFocus); +// setScene(new QGraphicsScene()); +// setInteractive(true); + setIcon(QIcon("://icons/qglview.png")); + deleting_ = false; + timer = 0; + need_init_ = is_first_draw = true; + objects_.is_root = true; + objects_.view_ = this; + backColor_ = Qt::darkGray; + hoverHaloColor_ = QColor(195, 140, 255, 96); + selectionHaloColor_ = QColor(175, 255, 140); + ambientColor_ = QColor(10, 10, 10); + lastPos = QPoint(-1, -1); + lineWidth_ = 1.; + max_anisotropic = 1; + max_texture_chanels = 8; + cameraOrbit_ = lightEnabled_ = true; + shaders_supported = selecting_ = customMouseMove_ = false; + sel_button = Qt::LeftButton; + sel_mod = Qt::NoModifier; + renderer_ = nullptr; + fps_cnt = 0; + fps_tm = fps_ = 0.; + sel_obj = hov_obj = nullptr; + fogDensity_ = fogEnd_ = 1.; + fogStart_ = 0.; + fogMode_ = Exp; + hoverHaloFill_ = 0.333f; + selectionHaloFill_ = 0.5f; + //lmode = Simple; + shader_select = shader_halo = nullptr; + setFeature(qglMSAA, false); + setFeature(qglFXAA, false); + setFeature(qglLinearFiltering, true); + setFeature(qglAnisotropicLevel, 8); + setFeature(qglHDR, false); + setFeature(qglEyeAccomodationEnabled, false); + setFeature(qglEyeAccomodationTime, 16.); + setFeature(qglEyeAccomodationMaxSpeed, 0.2); + setFeature(qglBloomEnabled, false); + setFeature(qglBloomThreshold, 0.9); + setFeature(qglBloomFactor, 1.); + setFeature(qglBloomRadius, 8); + setFeature(qglMotionBlurEnabled, false); + setFeature(qglMotionBlurFactor, 1.); + setFeature(qglMotionBlurSteps, 8); + setFeature(qglShadowsEnabled, false); + setFeature(qglShadowsMapSize, 512); + setFeature(qglShadowsSoftEnabled, true); + setFeature(qglReflectionsEnabled, false); + setFeature(qglReflectionsBlur, true); + setFeature(qglSSAOEnabled, false); + setFeature(qglSSAORadius, 5); + setFeature(qglDepthOfFieldEnabled, false); + setFeature(qglDepthOfFieldAutoFocusEnabled, true); + setFeature(qglDepthOfFieldAutoFocusSpeed, 0.1); + setFeature(qglDepthOfFieldFocus, 1.); + setFeature(qglDepthOfFieldDiaphragm, 8.); + mouse_first = mouseSelect_ = hoverHalo_ = selectionHalo_ = true; + mouseRotate_ = true; + fogEnabled_ = is_init = grabMouse_ = shaders_bind = changed_ = false; + rmode = GLObjectBase::Fill; + sel_mode = QGLView::SingleSelection; +// sel_pen = QPen(Qt::black, 1, Qt::DashLine); +// sel_brush = QBrush(QColor(170, 100, 255, 120)); + camera()->setAim(QVector3D()); + camera()->setPos(QVector3D(2, 2, 2)); + camera()->setName("Camera"); + addObject(camera()); + emit cameraPosChanged(camera()->pos()); + //camera().aim_ = camera().pos_; + ktm_.restart(); +} + + +QGLView::~QGLView() { + stop(); + if (shader_select) delete shader_select; + if (shader_halo) delete shader_halo; + deleting_ = true; +} + + +void QGLView::stop() { + if (timer) killTimer(timer); + timer = 0; +} + + +void QGLView::start(float freq) { + stop(); + timer = startTimer(freq <= 0.f ? 0 : int(1000.f / freq)); +} + + +GLRendererBase * QGLView::renderer() { + return renderer_; +} + + +void QGLView::setRenderer(GLRendererBase * r, GLRendererBase ** prev) { + if (prev != nullptr) *prev = renderer_; + renderer_ = r; +} + + +void QGLView::addObject(GLObjectBase * o) { + objects_.addChild(o); + o->setView(this); + collectLights(); + QList cl = o->children(true); + cl << o; + foreach (GLObjectBase * i, cl) { + emit objectAdded(i); + } + if (is_init) { + o->init(); + } +} + + +int QGLView::objectsCount(bool all) { + if (!all) return objects_.childCount(); + int cnt = 0; + objectsCountInternal(&cnt, &objects_); + return cnt; +} + + +void QGLView::removeObject(GLObjectBase * o, bool inChildren) { + o->setView(nullptr); + if (inChildren) + removeObjectInternal(o, &objects_); + else + objects_.removeChild(o); + objectDeleted(o); +} + + +void QGLView::removeObject(GLObjectBase & o, bool inChildren) { + removeObject(&o, inChildren); +} + + +void QGLView::clearObjects(bool deleteAll) { + removeObject(camera_); + objects_.clearChildren(deleteAll); + addObject(camera()); + selectObject(nullptr); + hov_obj = nullptr; +} + + +QList QGLView::objects(bool all) { + return objects_.children(all); +} + + +int QGLView::lightsCount() const { + return lights_.size(); +} + + +void QGLView::removeLight(int index) { + removeObject(lights_.at(index)); + lights_.removeAt(index); +} + + +void QGLView::removeLight(Light * l) { + foreach (Light * i, lights_) + if (i == l) removeObject(i); + lights_.removeAll(l); +} + + +void QGLView::clearLights(bool deleteAll) { + if (deleteAll) + foreach (Light * i, lights_) delete i; + lights_.clear(); +} + + +void QGLView::addTexture(const QString & path) { + textures_manager->addTexture(path); +} + + +void QGLView::addAnimation(const QString & dir, const QString & name) { + textures_manager->addAnimation(dir, name); +} + + +Light * QGLView::light(int index) { + return lights_[index]; +} + + +Light * QGLView::light(const QString & name) { + foreach (Light * i, lights_) + if (i->name_ == name) return i; + return nullptr; +} + + +void QGLView::selectObject(GLObjectBase * o) { + if (o == sel_obj) return; + GLObjectBase * pso = sel_obj; + sel_obj = o; + emit selectionChanged(sel_obj, pso); +} + + +void QGLView::resizeEvent(QResizeEvent * e) { + renderLater(); +} + +void QGLView::timerEvent(QTimerEvent *) { + renderNow(); + if (ktm_.elapsed() < QApplication::keyboardInputInterval()) return; + Qt::KeyboardModifiers km = QApplication::keyboardModifiers(); + foreach (int i, keys_) + emit keyEvent((Qt::Key)i, km); +} + + +void QGLView::render() { + if (!isVisible()) return; + resizeGL(width(), height()); + QRect g_rect(QPoint(), size()); + emit glBeforePaint(); + //qDebug() << "paintGL"; + //QMutexLocker ml_v(&v_mutex); + glEnable(GL_CULL_FACE); + //glDisable(GL_CULL_FACE); + camera()->apply(aspect); + //objects_.preparePos(camera()); + start_rp.cam_offset_matrix = camera()->offsetMatrix(); + start_rp.proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX); + start_rp.view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX); + //objects_.buildTransform(); + + /// Selection detect + //glClearFramebuffer(QColor(100, 0, 0, 0)); + if (mouseSelect_) { + glReleaseTextures(); + glEnableDepth(); + glDisable(GL_TEXTURE_1D); + glDisable(GL_TEXTURE_2D); + glDisable(GL_TEXTURE_CUBE_MAP); + glDisable(GL_MULTISAMPLE); + glDisable(GL_LIGHTING); + glDisable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + glDisable(GL_RESCALE_NORMAL); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + fbo_selection.bind(); + fbo_selection.setWriteBuffer(0); + glClearFramebuffer(QColor(0, 0, 0, 0)); + if (shaders_supported && shader_select->isLinked()) shader_select->bind(); + renderSelection(); + if (shaders_supported && shader_select->isLinked()) shader_select->release(); + uchar cgid[4] = {0, 0, 0, 0}; + uint iid = 0; + GLObjectBase * so = nullptr; + if (!g_rect.contains(lastPos)) { + if (hov_obj != nullptr) { + hov_obj = nullptr; + emit hoverChanged(nullptr, hov_obj); + } + } else { + glReadPixels(lastPos.x(), height() - lastPos.y(), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, cgid); + iid = uint(cgid[0] << 24) | uint(cgid[1] << 16) | uint(cgid[2] << 8) | cgid[3]; + so = ids.value(iid, nullptr); + //qDebug() <name() << cgid[3]; + } + if (selectionHalo_ && sel_obj) { + fbo_selection.setWriteBuffer(2); + renderHalo(sel_obj, qHash((quint64)sel_obj), selectionHaloColor_, selectionHaloFill_); + } + if (hoverHalo_ && hov_obj) { + fbo_selection.setWriteBuffer(1); + renderHalo(hov_obj, iid, hoverHaloColor_, hoverHaloFill_); + } + fbo_selection.release(); + glEnableDepth(); + /*glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY);*/ + } + + camera()->apply(aspect); + start_rp.cam_offset_matrix = camera()->offsetMatrix(); + cur_mvpm = start_rp.proj_matrix * start_rp.view_matrix * start_rp.cam_offset_matrix; + //objects_.preparePos(camera()); + + static GLRendererBase * prev_rend = nullptr; + glShadeModel(GL_SMOOTH); + if (prev_rend != renderer_) { + prev_rend = renderer_; + if (renderer_ != nullptr) { + renderer_->init(width(), height()); + renderer_->resize(width(), height()); + renderer_->reloadShaders(); + } + } + emit glBeginPaint(); + if (renderer_ != nullptr) { + renderer_->rp.prepare(); + renderer_->prepareScene(); + renderer_->renderScene(); + } + emit glPainting(); + glUseProgram(0); + if (selectionHalo_ || hoverHalo_) { + glReleaseTextures(); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + //glClearFramebuffer(Qt::black, false); + + glActiveTexture(GL_TEXTURE0); + glEnable(GL_BLEND); + glDisable(GL_TEXTURE_CUBE_MAP); + glDisable(GL_LIGHTING); + glDisableDepth(); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + if (selectionHalo_ && sel_obj) { + glBindTexture(GL_TEXTURE_2D, fbo_selection.colorTexture(2)); + //qDebug() << "draw sel"; + glDrawQuad(); + } + if (hoverHalo_ && hov_obj) { + glBindTexture(GL_TEXTURE_2D, fbo_selection.colorTexture(1)); + //qDebug() << "draw hover"; + //glBindTexture(GL_TEXTURE_2D, textures_manager->loadTexture("batt_pn.jpg")); + glDrawQuad(); + } + } + + glResetAllTransforms(); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glUseProgram(0); + + //glDisable(GL_BLEND); + //glDisable(GL_LIGHTING); + //glActiveTexture(GL_TEXTURE0); + //glBindTexture(GL_TEXTURE_2D, textures_manager->loadTexture("batt_pn.jpg")); + //glDrawQuad(); + + emit glEndPaint(); + + /*releaseShaders(); + glActiveTextureChannel(0); + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(0.3, 0.5, 0.8, 0.5); + glResetAllTransforms(); + glBegin(GL_QUADS); + glTexCoord2f(0.f, 0.f); glVertex2f(-1.f, -1.f); + glTexCoord2f(1.f, 0.f); glVertex2f(1.f, -1.); + glTexCoord2f(1.f, 1.f); glVertex2f(1.f, 1.f); + glTexCoord2f(0.f, 1.f); glVertex2f(-1.f, 1.f); + glEnd();*/ + /* + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glDisable(GL_LIGHTING); + glActiveTextureChannel(0); + glBindTexture(GL_TEXTURE_2D, fbo->texture()); + glDisable(GL_DEPTH_TEST); + glBegin(GL_QUADS); + glColor3f(1.f, 1.f, 1.f); + glTexCoord2f(0.f, 0.f); glVertex2f(-1.f, -1.f); + glTexCoord2f(0.f, 1.f); glVertex2f(-1.f, 1.f); + glTexCoord2f(1.f, 1.f); glVertex2f(1.f, 1.f); + glTexCoord2f(1.f, 0.f); glVertex2f(1.f, -1.); + glEnd(); + glEnable(GL_DEPTH_TEST);*/ + fps_tm += time.elapsed(); + time.restart(); + fps_cnt++; + if (fps_tm < 1000.) return; + fps_ = fps_cnt / fps_tm * 1000.; + fps_tm = 0.; + fps_cnt = 0; +} + + +void QGLView::initialize() { + //initializeOpenGLFunctions(); + glEnable(GL_TEXTURE_MAX_ANISOTROPY_EXT); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glEnableDepth(); + glEnable(GL_CULL_FACE); + glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1); + glActiveTexture(GL_TEXTURE0 + 3); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_GEN_R); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + glActiveTexture(GL_TEXTURE0); + glShadeModel(GL_SMOOTH); + glCullFace(GL_BACK); + glEnable(GL_COLOR_MATERIAL); + glColorMaterial(GL_FRONT, GL_DIFFUSE); + + textures_manager->loadTextures(); + objects_.initInternal(); + checkCaps(); + + shader_select = new QOpenGLShaderProgram(context()); + shader_halo = new QOpenGLShaderProgram(context()); + reloadThisShaders(); + is_init = true; + //resizeGL(width(), height()); + need_init_ = false; + emit glInitializeDone(); +} + + +void QGLView::renderHalo(const GLObjectBase * obj, const uint iid, const QColor & color, const float & fill) { + if (!shaders_supported) return; + if (!shader_halo) return; + if (!shader_halo->isLinked()) return; + if (obj) { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, fbo_selection.colorTexture()); + shader_halo->bind(); + shader_halo->setUniformValue("qgl_ModelViewProjectionMatrix", QMatrix4x4()); + shader_halo->setUniformValue("t0", 0); + shader_halo->setUniformValue("dt", QVector2D(1.f / width(), 1.f / height())); + shader_halo->setUniformValue("selected", QVector4D(float((iid >> 24) & 0xFF) / 255.f, + float((iid >> 16) & 0xFF) / 255.f, + float((iid >> 8) & 0xFF) / 255.f, + float( iid & 0xFF) / 255.f)); + shader_halo->setUniformValue("color", color); + shader_halo->setUniformValue("fill", GLfloat(fill)); + //qDebug() << "render halo" << iid << shader_halo->log() << shader_halo->programId(); + glDisableDepth(); + //glClearFramebuffer(color); + glDrawQuad(shader_halo); + glDepthMask(GL_TRUE); + //glFlush(); + shader_halo->release(); + } else { + glClearFramebuffer(Qt::black, false); + } +} + + +void QGLView::renderSelection() { +// cid = 1; + ids.clear(); + if (shaders_supported) { + if (shader_select) { + if (shader_select->isLinked()) { + sh_id_loc = shader_select->uniformLocation("id"); + shader_select->setUniformValue("z_far", GLfloat(depthEnd())); + shader_select->setUniformValue("z_near", GLfloat(depthStart())); + } + } + } + //qDebug() << sh_id_loc; + start_rp.view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX); + glPushMatrix(); + renderSingleSelection(objects_); + glPopMatrix(); +} + + +void QGLView::renderSingleSelection(GLObjectBase & o) { + if (!o.isInit()) { + o.init(); + o.loadTextures(); + } + if (!o.visible_ || !o.select_) return; + QMatrix4x4 curview = start_rp.view_matrix * start_rp.cam_offset_matrix * o.itransform_; + uint id = qHash((quint64)&o); + ids.insert(id, &o); + glLineWidth(o.line_width > 0.f ? o.line_width : lineWidth_); + glPointSize(o.line_width > 0.f ? o.line_width : lineWidth_); + if (shaders_supported){ + if (shader_select) { + if (shader_select->isLinked()) { + setUniformMatrices(shader_select, start_rp.proj_matrix, curview); + shader_select->setUniformValue(sh_id_loc, QVector4D(float((id >> 24) & 0xFF) / 255.f, + float((id >> 16) & 0xFF) / 255.f, + float((id >> 8) & 0xFF) / 255.f, + float(id & 0xFF) / 255.f)); + } + } + } else { + setGLMatrix(curview); + glColor4f(float((id >> 24) & 0xFF) / 255.f, + float((id >> 16) & 0xFF) / 255.f, + float((id >> 8) & 0xFF) / 255.f, + float(id & 0xFF) / 255.f); + } + //qDebug() << o.name() << "assign to" << sh_id_loc << cid; + //glColor4f(float((cid >> 24) & 0xFF) / 255.f, float((cid >> 16) & 0xFF) / 255.f, float((cid >> 8) & 0xFF) / 255.f, float(cid & 0xFF) / 255.f); +// ++cid; + o.draw(nullptr, true); + foreach (GLObjectBase * i, o.children_) + renderSingleSelection(*i); +} + + +void QGLView::collectLights() { + lights_.clear(); + collectObjectLights(&objects_); +} + + +void QGLView::objectDeleted(GLObjectBase * o) { + if (deleting_) return; + //qDebug() << "del" << o; + if (sel_obj == o) selectObject(nullptr); + if (hov_obj == o) hov_obj = nullptr; + collectLights(); +} + + +void QGLView::collectObjectLights(GLObjectBase * o) { + if (o->type_ == GLObjectBase::glLight) { + lights_ << globject_cast(o); + o->view_ = this; + } + foreach (GLObjectBase * i, o->children()) + collectObjectLights(i); +} + + +void QGLView::objectsCountInternal(int * cnt, GLObjectBase * where) { + ++(*cnt); + foreach (GLObjectBase * i, where->children_) + objectsCountInternal(cnt, i); +} + + +void QGLView::removeObjectInternal(GLObjectBase * o, GLObjectBase * where) { + foreach (GLObjectBase * i, where->children_) { + if (o == i) + where->removeChild(i); + else + removeObjectInternal(o, i); + objectDeleted(i); + } +} + + +void QGLView::checkCaps() { + glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropic); + //glGetIntegerv(GL_MAX_TEXTURE_UNITS, &max_texture_chanels); + //qDebug() << max_texture_chanels; + //qDebug() << max_texture_chanels; + shaders_supported = QOpenGLShaderProgram::hasOpenGLShaderPrograms(); +} + + +void QGLView::reloadThisShaders() { + if (!shaders_supported) return; + loadShaders(shader_select, "selection", "://shaders"); + loadShaders(shader_halo, "selection_halo", "://shaders"); + //loadShaders(shader_rope, "rope", "://shaders"); +} + +void QGLView::glReleaseTextures(int channels) { + for (int i = channels - 1; i >= 0; --i) { + glActiveTexture(GL_TEXTURE0 + i); + glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(GL_TEXTURE_CUBE_MAP, 0); + } +} + + +void QGLView::applyFog() { + GLfloat fog_col[4] = {float(fogColor_.redF()), float(fogColor_.greenF()), float(fogColor_.blueF()), .0f}; + if (fogEnabled_) { + glEnable(GL_FOG); + glFogf(GL_FOG_DENSITY, fogDensity_); + glFogf(GL_FOG_START, fogStart_); + glFogf(GL_FOG_END, fogEnd_); + glFogi(GL_FOG_MODE, fogMode_); + fog_col[0] = fogColor_.redF(); + fog_col[1] = fogColor_.greenF(); + fog_col[2] = fogColor_.blueF(); + glFogfv(GL_FOG_COLOR, fog_col); + } else glDisable(GL_FOG); +} + + +void QGLView::resizeGL(int width, int height) { + if (!is_init) return; + if (width <= 0 || height <= 0) return; + if (prev_size == QSize(width, height)) return; + prev_size = QSize(width, height); + aspect = float(width) / float(height); + if (renderer_) renderer_->resize(width, height); + mouse_first = true; + //qDebug() << "resize" << width << height; + fbo_selection.resize(width, height); + iaspect = (aspect == 0.f) ? 0. : 1 / aspect; + glViewport(0, 0, width, height); + emit glResize(width, height); +} + + +void QGLView::mouseReleaseEvent(QMouseEvent * e) { +// qDebug() << "mouseReleaseEvent" << e << isActive(); +// QGraphicsView::mouseReleaseEvent(e); + //setCursor(QCursor(Qt::ArrowCursor)); + selecting_ = false; + if (mouseSelect_ && e->button() == Qt::LeftButton) { + if ((lastPos - downPos).manhattanLength() < 8) { + if (sel_obj != hov_obj) + selectObject(hov_obj); + } + } + emit glMouseReleaseEvent(e); +} + + +void QGLView::mousePressEvent(QMouseEvent * e) { +// qDebug() << "mousePressEvent" << e << isActive(); +// QGraphicsView::mousePressEvent(e); +// mouseThis_ = (scene()->itemAt(mapToScene(e->pos()) , QTransform() ) == 0); + selecting_ = false; + if (!QRect(QPoint(), size()).contains(e->pos())) return; + /// TODO select by rect + //if (e->button() == sel_button && e->modifiers() == sel_mod) + // selecting_ = true; + lastPos = e->pos(); + downPos = lastPos; + //qDebug() << mouseThis_; + emit glMousePressEvent(e); +} + + +void QGLView::mouseMoveEvent(QMouseEvent * e) { +// qDebug() << "mouseMoveEvent" << e << isActive(); +// QGraphicsView::mouseMoveEvent(e); + //lastPos = e->pos(); + if (selecting_) { + return; + } +// if (!QRect(QPoint(), size()).contains(e->pos())) return; + //if (scene()->itemAt(mapToScene(e->pos())) != 0) return; + ///qDebug() << e->x() << e->y(); + QRect g_rect(QPoint(), size()); + if (mouseRotate_) { + float dx = e->x() - lastPos.x(); + float dy = e->y() - lastPos.y(); + if (e->buttons() & Qt::LeftButton) { + //camera().angle_z += dx / 4.; + //camera().angle_xy += dy / 4.; + if (cameraOrbit_) { + camera()->orbitZ(dx / 4.f); + camera()->orbitXY(dy / 4.f); + } else { + camera()->rotateZ(dx / 4.f); + camera()->rotateXY(dy / 4.f); + } + emit cameraPosChanged(camera()->pos()); + } else if (e->buttons() & Qt::RightButton) { + float ad = camera()->distance(); + camera()->moveLeft(dx / 1000.f * ad); + camera()->moveUp(dy / 1000.f * ad); + //camera().pos.setX(camera().pos.x() + camera().pos.z() * dx / 500.); + //camera().pos.setY(camera().pos.y() - camera().pos.z() * dy / 500.); + emit cameraPosChanged(camera()->pos()); + } + //lights[0]->pos_ = camera().pos(); + } + if (customMouseMove_) emit customMouseMoveEvent(e->pos(), lastPos, e->buttons()); + lastPos = e->pos(); + if (grabMouse_) { + //if (!isrunning) return; + QCursor::setPos(mapToGlobal(QRect(QPoint(), size()).center())); + static bool mouse_sec = false; + if (mouse_sec) { + mouse_sec = false; + return; + } + if (mouse_first) { + mouse_first = false; + mouse_sec = true; + //qDebug() << "first" << e->pos(); + return; + } + lastPos = g_rect.center(); + int dx = e->x() - lastPos.x(); + int dy = e->y() - lastPos.y(); + emit glMouseMoveEvent(new QMouseEvent(QEvent::MouseMove, QPoint(dx, dy), e->button(), e->buttons(), e->modifiers())); + return; + } + emit glMouseMoveEvent(e); +} + + +void QGLView::wheelEvent(QWheelEvent * e) { + if (mouseRotate_) { + if (e->delta() > 0) camera()->flyCloser(0.1f); //camera().pos.setZ(camera().pos.z() - 0.1 * camera().pos.z()); + if (e->delta() < 0) camera()->flyFarer(0.1f); //camera().pos.setZ(camera().pos.z() + 0.1 * camera().pos.z()); + emit cameraPosChanged(camera()->pos()); + } + emit glWheelEvent(e); +} + + +void QGLView::leaveEvent(QEvent * ) { + lastPos = QPoint(-1, -1); + //qDebug() << lastPos; +} + + +void QGLView::keyPressEvent(QKeyEvent * e) { + emit glKeyPressEvent(e); + if (e->key() > 0) keys_.insert(e->key()); + if (e->key() == Qt::Key_F11) { + emit doubleClick(); + } +} + + +void QGLView::keyReleaseEvent(QKeyEvent * e) { + emit glKeyReleaseEvent(e); + keys_.remove(e->key()); +} + + +void QGLView::focusOutEvent(QFocusEvent *) { + keys_.clear(); +} + + +void QGLView::mouseDoubleClickEvent(QMouseEvent * e) { + if (e->buttons().testFlag(Qt::MidButton)) + emit doubleClick(); +} + + +QByteArray QGLView::saveCamera() { + ChunkStream cs; + const Camera * c = camera(); + cs.add(1, c->posX()); + cs.add(2, c->posY()); + cs.add(3, c->posZ()); + cs.add(4, c->aim().x()); + cs.add(5, c->aim().y()); + cs.add(6, c->aim().z()); + cs.add(7, c->angleZ()); + cs.add(8, c->angleXY()); + cs.add(9, c->angleRoll()); + cs.add(10, c->FOV()); + return cs.data(); +} + + +void QGLView::restoreCamera(const QByteArray &ba) { + if (ba.isEmpty()) return; + ChunkStream cs(ba); + QVector3D pos, aim, ang; + while (!cs.atEnd()) { + switch (cs.read()) { + case 1: pos.setX(cs.getData()); break; + case 2: pos.setY(cs.getData()); break; + case 3: pos.setZ(cs.getData()); break; + case 4: aim.setX(cs.getData()); break; + case 5: aim.setY(cs.getData()); break; + case 6: aim.setZ(cs.getData()); break; + case 7: ang.setZ(cs.getData()); break; + case 8: ang.setY(cs.getData()); break; + case 9: ang.setX(cs.getData()); break; + case 10: setFOV(cs.getData()); break; + default: break; + } + } + camera()->setPos(pos); + camera()->setAim(aim); + camera()->setAngles(ang); +} + + +QByteArray QGLView::saveFeatures() { + QByteArray ba; + QDataStream ds(&ba, QIODevice::WriteOnly); + ds << features_; + return ba; +} + + +void QGLView::restoreFeatures(const QByteArray & ba) { + QHash f; + QDataStream ds(ba); + ds >> f; + features_ = f; +} + diff --git a/qglview/qglview.h b/qglview/qglview.h index c9ac9fb..dcb1d0e 100644 --- a/qglview/qglview.h +++ b/qglview/qglview.h @@ -1,301 +1,301 @@ -/* - QGLView - Ivan Pelipenko peri4ko@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 . -*/ - -#ifndef QGLVIEW_H -#define QGLVIEW_H - -#include "openglwindow.h" -#include "glframebuffer.h" -#include "glprimitives.h" -#include "glparticles_system.h" -#include "glrendererbase.h" -#include - - -class QGLView: public OpenGLWindow, public QGLViewBase -{ - friend class GLRendererBase; - friend class GLObjectBase; - Q_OBJECT - Q_PROPERTY (QColor backColor READ backColor WRITE setBackColor) - Q_PROPERTY (float lineWidth READ lineWidth WRITE setLineWidth) - Q_PROPERTY (float FOV READ FOV WRITE setFOV) - Q_PROPERTY (float depthStart READ depthStart WRITE setDepthStart) - Q_PROPERTY (float depthEnd READ depthEnd WRITE setDepthEnd) - Q_PROPERTY (QColor ambientColor READ ambientColor WRITE setAmbientColor) - Q_PROPERTY (QColor fogColor READ fogColor WRITE setFogColor) - Q_PROPERTY (float fogDensity READ fogDensity WRITE setFogDensity) - Q_PROPERTY (float fogStart READ fogStart WRITE setFogStart) - Q_PROPERTY (float fogEnd READ fogEnd WRITE setFogEnd) - Q_PROPERTY (FogMode fogMode READ fogMode WRITE setFogMode) - Q_PROPERTY (bool fogEnabled READ isFogEnabled WRITE setFogEnabled) - Q_PROPERTY (int renderMode READ renderMode WRITE setRenderMode) - Q_PROPERTY (bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled) - Q_PROPERTY (bool mouseRotate READ isMouseRotateEnabled WRITE setMouseRotateEnabled) - Q_PROPERTY (bool mouseSelection READ isMouseSelectionEnabled WRITE setMouseSelectionEnabled) - Q_PROPERTY (bool cameraOrbit READ isCameraOrbit WRITE setCameraOrbit) - Q_PROPERTY (bool hoverHalo READ isHoverHaloEnabled WRITE setHoverHaloEnabled) - Q_PROPERTY (QColor hoverHaloColor READ hoverHaloColor WRITE setHoverHaloColor) - Q_PROPERTY (float hoverHaloFillAlpha READ hoverHaloFillAlpha WRITE setHoverHaloFillAlpha) - Q_PROPERTY (bool selectionHalo READ isSelectionHaloEnabled WRITE setSelectionHaloEnabled) - Q_PROPERTY (QColor selectionHaloColor READ selectionHaloColor WRITE setSelectionHaloColor) - Q_PROPERTY (float selectionHaloFillAlpha READ selectionHaloFillAlpha WRITE setSelectionHaloFillAlpha) - Q_PROPERTY (Qt::MouseButton selectionButton READ selectionButton WRITE setSelectionButton) - Q_PROPERTY (Qt::KeyboardModifier selectionModifier READ selectionModifier WRITE setSelectionModifier) - Q_PROPERTY (SelectionMode selectionMode READ selectionMode WRITE setSelectionMode) - -public: - QGLView(); - virtual ~QGLView(); - - enum FogMode {Linear = GL_LINEAR, Exp = GL_EXP, Exp2 = GL_EXP2}; - enum SelectionMode {NoSelection, SingleSelection, MultiSelection}; - enum Feature { - qglMSAA, - qglFXAA, - qglLinearFiltering, - qglAnisotropicLevel, - qglHDR, - qglEyeAccomodationEnabled, - qglEyeAccomodationTime, - qglEyeAccomodationMaxSpeed, - qglBloomEnabled, - qglBloomThreshold, - qglBloomFactor, - qglBloomRadius, - qglMotionBlurEnabled, - qglMotionBlurFactor, - qglMotionBlurSteps, - qglShadowsEnabled, - qglShadowsMapSize, - qglShadowsSoftEnabled, - qglReflectionsEnabled, - qglReflectionsBlur, - qglSSAOEnabled, - qglSSAORadius, - qglDepthOfFieldEnabled, - qglDepthOfFieldAutoFocusEnabled, - qglDepthOfFieldAutoFocusSpeed, - qglDepthOfFieldFocus, - qglDepthOfFieldDiaphragm - }; - - Q_ENUMS (FogMode) - Q_ENUMS (SelectionMode) - - void stop(); - void start(float freq = 60.); - - GLRendererBase * renderer(); - void setRenderer(GLRendererBase * r, GLRendererBase ** prev = nullptr); - - QColor backColor() const {return backColor_;} - float lineWidth() const {return lineWidth_;} - float FOV() const {return camera()->fov_;} - float depthStart() const {return camera()->depth_start;} - float depthEnd() const {return camera()->depth_end;} - float currentFPS() const {return fps_;} - int maxAnisotropicLevel() const {return max_anisotropic;} - - QColor ambientColor() const {return ambientColor_;} - QColor fogColor() const {return fogColor_;} - float fogDensity() const {return fogDensity_;} - float fogStart() const {return fogStart_;} - float fogEnd() const {return fogEnd_;} - FogMode fogMode() const {return fogMode_;} - bool isFogEnabled() const {return fogEnabled_;} - bool isLightEnabled() const {return lightEnabled_;} - bool isGrabMouseEnabled() const {return grabMouse_;} - bool isMouseRotateEnabled() const {return mouseRotate_;} - bool isMouseSelectionEnabled() const {return mouseSelect_;} - bool isCameraOrbit() const {return cameraOrbit_;} - bool isHoverHaloEnabled() const {return hoverHalo_;} - QColor hoverHaloColor() const {return hoverHaloColor_;} - float hoverHaloFillAlpha() const {return hoverHaloFill_;} - bool isSelectionHaloEnabled() const {return selectionHalo_;} - QColor selectionHaloColor() const {return selectionHaloColor_;} - float selectionHaloFillAlpha() const {return selectionHaloFill_;} - - QVariant feature(Feature f) const {return features_.value(int(f));} - QVariant setFeature(Feature f, const QVariant & value) {QVariant ret = features_.value(int(f)); features_[int(f)] = value; return ret;} - bool isFeatureEnabled(Feature f) const {return features_[int(f)].toBool();} - - int renderMode() const {return (int)rmode;} - void setRenderMode(int mode) {rmode = (GLObjectBase::RenderMode)mode;} - - void addObject(GLObjectBase * o); -// void addObject(GLObjectBase & o) {addObject(&o);} - int objectsCount(bool all = false); - void removeObject(GLObjectBase * o, bool inChildren = true); - void removeObject(GLObjectBase & o, bool inChildren = true); - void clearObjects(bool deleteAll = false); - QList objects(bool all = false); - - int lightsCount() const; - void removeLight(int index); - void removeLight(Light * l); - void clearLights(bool deleteAll = false); - QList lights() {return lights_;} - - void addTexture(const QString & path); - void addAnimation(const QString & dir, const QString & name); - - const GLObjectBase & rootObject() {return objects_;} - GLObjectBase * object(int index) {return objects_.child(index);} - GLObjectBase * object(const QString & name) {return objects_.child(name);} - Light * light(int index); - Light * light(const QString & name); - - SelectionMode selectionMode() const {return sel_mode;} - Qt::MouseButton selectionButton() const {return sel_button;} - Qt::KeyboardModifier selectionModifier() const {return sel_mod;} - - void setSelectionMode(SelectionMode v) {sel_mode = v;} - void setSelectionButton(Qt::MouseButton v) {sel_button = v;} - void setSelectionModifier(Qt::KeyboardModifier v) {sel_mod = v;} - void selectObject(GLObjectBase * o); - GLObjectBase * selectedObject() const {return sel_obj;} - - void glReleaseTextures(int channels = 8); - QByteArray saveCamera(); - void restoreCamera(const QByteArray & ba); - QByteArray saveFeatures(); - void restoreFeatures(const QByteArray & ba); - - - GLfloat aspect, iaspect; - QMatrix4x4 cur_mvpm; - -protected: - void render(); - void resizeEvent(QResizeEvent * e); - - void timerEvent(QTimerEvent * ); - void initialize(); - void resizeGL(int width, int height); - void mousePressEvent(QMouseEvent * e); - void mouseMoveEvent(QMouseEvent * e); - void mouseReleaseEvent(QMouseEvent * e); - void wheelEvent(QWheelEvent * e); - void leaveEvent(QEvent * ); - void mouseDoubleClickEvent(QMouseEvent * e); - - void keyPressEvent(QKeyEvent * e); - void keyReleaseEvent(QKeyEvent * e); - void focusOutEvent(QFocusEvent *); - - void applyFog(); - void renderSelection(); - - void checkCaps(); - void collectLights(); - -private: - void objectDeleted(GLObjectBase * o); - void collectObjectLights(GLObjectBase * o); - void objectsCountInternal(int * cnt, GLObjectBase * where); - void removeObjectInternal(GLObjectBase * o, GLObjectBase * where); - void renderSingleSelection(GLObjectBase & o); - //void renderSingleShadow(GLObjectBase & o); - void renderHalo(const GLObjectBase * obj, const uint iid, const QColor & color, const float & fill); - void reloadThisShaders(); - void processKeys(); - bool setupViewport(); - - QPoint lastPos, downPos; - GLObjectBase objects_; - QList lights_; -// uint cid; - QHash ids; - QSet keys_; - FogMode fogMode_; - QColor backColor_, fogColor_, ambientColor_, hoverHaloColor_, selectionHaloColor_; - QTime time, ktm_; - GLint max_anisotropic, max_texture_chanels; - GLObjectBase::RenderMode rmode; - GLObjectBase * sel_obj, * hov_obj; - GLFramebuffer fbo_selection; - QOpenGLShaderProgram * shader_select, * shader_halo; - GLRendererBase * renderer_; - SelectionMode sel_mode; - Qt::MouseButton sel_button; - Qt::KeyboardModifier sel_mod; - GLRendererBase::RenderingParameters start_rp; - QHash features_; - QSize prev_size; - float lineWidth_; - float fogDensity_, fogStart_, fogEnd_, fps_, fps_tm, hoverHaloFill_, selectionHaloFill_, m_motionBlurFactor; - int timer, fps_cnt, sh_id_loc, deleting_; - bool is_first_draw, is_init, fogEnabled_, lightEnabled_, grabMouse_, mouse_first, mouseRotate_, mouseSelect_, customMouseMove_; - bool shaders_supported, changed_, cameraOrbit_, need_init_; - bool hoverHalo_, selectionHalo_, shaders_bind, selecting_; - -public slots: - void setBackColor(const QColor & arg) {backColor_ = arg;} - void setLineWidth(const float & arg) {lineWidth_ = arg;} - void setFOV(const float & arg) {camera()->fov_ = arg;} - void setDepthStart(const float & arg) {camera()->depth_start = arg;} - void setDepthEnd(const float & arg) {camera()->depth_end = arg;} - void setAmbientColor(const QColor & arg) {ambientColor_ = arg;} - void setFogColor(const QColor & arg) {fogColor_ = arg;} - void setFogDensity(const float & arg) {fogDensity_ = arg;} - void setFogStart(const float & arg) {fogStart_ = arg;} - void setFogEnd(const float & arg) {fogEnd_ = arg;} - void setFogMode(const FogMode & arg) {fogMode_ = arg;} - void setFogEnabled(const bool & arg) {fogEnabled_ = arg;} - void setLightEnabled(const bool & arg) {lightEnabled_ = arg;} - void setGrabMouseEnabled(const bool & arg) {grabMouse_ = arg; mouse_first = true;} - void setMouseRotateEnabled(const bool & arg) {mouseRotate_ = arg;} - void setMouseSelectionEnabled(const bool & arg) {mouseSelect_ = arg;} - void setCustomMouseMove(const bool & arg) {customMouseMove_ = arg;} - void setCameraOrbit(const bool & arg) {cameraOrbit_ = arg;} - void setHoverHaloEnabled(const bool & arg) {hoverHalo_ = arg;} - void setHoverHaloColor(const QColor & arg) {hoverHaloColor_ = arg;} - void setHoverHaloFillAlpha(const float & arg) {hoverHaloFill_ = arg;} - void setSelectionHaloEnabled(const bool & arg) {selectionHalo_ = arg;} - void setSelectionHaloColor(const QColor & arg) {selectionHaloColor_ = arg;} - void setSelectionHaloFillAlpha(const float & arg) {selectionHaloFill_ = arg;} - - void reloadShaders() {if (renderer_ != nullptr) renderer_->reloadShaders(); reloadThisShaders();} - void deselect() {sel_obj = nullptr;} - -signals: - void glBeforePaint(); - void glBeginPaint(); - void glPainting(); - void glEndPaint(); - void glKeyPressEvent(QKeyEvent * e); - void glKeyReleaseEvent(QKeyEvent * e); - void glMousePressEvent(QMouseEvent * e); - void glMouseMoveEvent(QMouseEvent * e); - void glMouseReleaseEvent(QMouseEvent * e); - void glWheelEvent(QWheelEvent * e); - void glResize(int, int); - void glInitializeDone(); - void cameraPosChanged(QVector3D pos); - void keyEvent(Qt::Key key, Qt::KeyboardModifiers mod); - void customMouseMoveEvent(QPoint curpos, QPoint lastpos, Qt::MouseButtons buttons); - - void hoverChanged(GLObjectBase * cur, GLObjectBase * prev); - void selectionChanged(GLObjectBase * cur, GLObjectBase * prev); - void objectAdded(GLObjectBase * ); - void doubleClick(); - -}; - -#endif // QGLVIEW_H +/* + QGLView + Ivan Pelipenko peri4ko@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 . +*/ + +#ifndef QGLVIEW_H +#define QGLVIEW_H + +#include "openglwindow.h" +#include "glframebuffer.h" +#include "glprimitives.h" +#include "glparticles_system.h" +#include "glrendererbase.h" +#include + + +class QGLView: public OpenGLWindow, public QGLViewBase +{ + friend class GLRendererBase; + friend class GLObjectBase; + Q_OBJECT + Q_PROPERTY (QColor backColor READ backColor WRITE setBackColor) + Q_PROPERTY (float lineWidth READ lineWidth WRITE setLineWidth) + Q_PROPERTY (float FOV READ FOV WRITE setFOV) + Q_PROPERTY (float depthStart READ depthStart WRITE setDepthStart) + Q_PROPERTY (float depthEnd READ depthEnd WRITE setDepthEnd) + Q_PROPERTY (QColor ambientColor READ ambientColor WRITE setAmbientColor) + Q_PROPERTY (QColor fogColor READ fogColor WRITE setFogColor) + Q_PROPERTY (float fogDensity READ fogDensity WRITE setFogDensity) + Q_PROPERTY (float fogStart READ fogStart WRITE setFogStart) + Q_PROPERTY (float fogEnd READ fogEnd WRITE setFogEnd) + Q_PROPERTY (FogMode fogMode READ fogMode WRITE setFogMode) + Q_PROPERTY (bool fogEnabled READ isFogEnabled WRITE setFogEnabled) + Q_PROPERTY (int renderMode READ renderMode WRITE setRenderMode) + Q_PROPERTY (bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled) + Q_PROPERTY (bool mouseRotate READ isMouseRotateEnabled WRITE setMouseRotateEnabled) + Q_PROPERTY (bool mouseSelection READ isMouseSelectionEnabled WRITE setMouseSelectionEnabled) + Q_PROPERTY (bool cameraOrbit READ isCameraOrbit WRITE setCameraOrbit) + Q_PROPERTY (bool hoverHalo READ isHoverHaloEnabled WRITE setHoverHaloEnabled) + Q_PROPERTY (QColor hoverHaloColor READ hoverHaloColor WRITE setHoverHaloColor) + Q_PROPERTY (float hoverHaloFillAlpha READ hoverHaloFillAlpha WRITE setHoverHaloFillAlpha) + Q_PROPERTY (bool selectionHalo READ isSelectionHaloEnabled WRITE setSelectionHaloEnabled) + Q_PROPERTY (QColor selectionHaloColor READ selectionHaloColor WRITE setSelectionHaloColor) + Q_PROPERTY (float selectionHaloFillAlpha READ selectionHaloFillAlpha WRITE setSelectionHaloFillAlpha) + Q_PROPERTY (Qt::MouseButton selectionButton READ selectionButton WRITE setSelectionButton) + Q_PROPERTY (Qt::KeyboardModifier selectionModifier READ selectionModifier WRITE setSelectionModifier) + Q_PROPERTY (SelectionMode selectionMode READ selectionMode WRITE setSelectionMode) + +public: + QGLView(); + virtual ~QGLView(); + + enum FogMode {Linear = GL_LINEAR, Exp = GL_EXP, Exp2 = GL_EXP2}; + enum SelectionMode {NoSelection, SingleSelection, MultiSelection}; + enum Feature { + qglMSAA, + qglFXAA, + qglLinearFiltering, + qglAnisotropicLevel, + qglHDR, + qglEyeAccomodationEnabled, + qglEyeAccomodationTime, + qglEyeAccomodationMaxSpeed, + qglBloomEnabled, + qglBloomThreshold, + qglBloomFactor, + qglBloomRadius, + qglMotionBlurEnabled, + qglMotionBlurFactor, + qglMotionBlurSteps, + qglShadowsEnabled, + qglShadowsMapSize, + qglShadowsSoftEnabled, + qglReflectionsEnabled, + qglReflectionsBlur, + qglSSAOEnabled, + qglSSAORadius, + qglDepthOfFieldEnabled, + qglDepthOfFieldAutoFocusEnabled, + qglDepthOfFieldAutoFocusSpeed, + qglDepthOfFieldFocus, + qglDepthOfFieldDiaphragm + }; + + Q_ENUMS (FogMode) + Q_ENUMS (SelectionMode) + + void stop(); + void start(float freq = 60.); + + GLRendererBase * renderer(); + void setRenderer(GLRendererBase * r, GLRendererBase ** prev = nullptr); + + QColor backColor() const {return backColor_;} + float lineWidth() const {return lineWidth_;} + float FOV() const {return camera()->fov_;} + float depthStart() const {return camera()->depth_start;} + float depthEnd() const {return camera()->depth_end;} + float currentFPS() const {return fps_;} + int maxAnisotropicLevel() const {return max_anisotropic;} + + QColor ambientColor() const {return ambientColor_;} + QColor fogColor() const {return fogColor_;} + float fogDensity() const {return fogDensity_;} + float fogStart() const {return fogStart_;} + float fogEnd() const {return fogEnd_;} + FogMode fogMode() const {return fogMode_;} + bool isFogEnabled() const {return fogEnabled_;} + bool isLightEnabled() const {return lightEnabled_;} + bool isGrabMouseEnabled() const {return grabMouse_;} + bool isMouseRotateEnabled() const {return mouseRotate_;} + bool isMouseSelectionEnabled() const {return mouseSelect_;} + bool isCameraOrbit() const {return cameraOrbit_;} + bool isHoverHaloEnabled() const {return hoverHalo_;} + QColor hoverHaloColor() const {return hoverHaloColor_;} + float hoverHaloFillAlpha() const {return hoverHaloFill_;} + bool isSelectionHaloEnabled() const {return selectionHalo_;} + QColor selectionHaloColor() const {return selectionHaloColor_;} + float selectionHaloFillAlpha() const {return selectionHaloFill_;} + + QVariant feature(Feature f) const {return features_.value(int(f));} + QVariant setFeature(Feature f, const QVariant & value) {QVariant ret = features_.value(int(f)); features_[int(f)] = value; return ret;} + bool isFeatureEnabled(Feature f) const {return features_[int(f)].toBool();} + + int renderMode() const {return (int)rmode;} + void setRenderMode(int mode) {rmode = (GLObjectBase::RenderMode)mode;} + + void addObject(GLObjectBase * o); +// void addObject(GLObjectBase & o) {addObject(&o);} + int objectsCount(bool all = false); + void removeObject(GLObjectBase * o, bool inChildren = true); + void removeObject(GLObjectBase & o, bool inChildren = true); + void clearObjects(bool deleteAll = false); + QList objects(bool all = false); + + int lightsCount() const; + void removeLight(int index); + void removeLight(Light * l); + void clearLights(bool deleteAll = false); + QList lights() {return lights_;} + + void addTexture(const QString & path); + void addAnimation(const QString & dir, const QString & name); + + const GLObjectBase & rootObject() {return objects_;} + GLObjectBase * object(int index) {return objects_.child(index);} + GLObjectBase * object(const QString & name) {return objects_.child(name);} + Light * light(int index); + Light * light(const QString & name); + + SelectionMode selectionMode() const {return sel_mode;} + Qt::MouseButton selectionButton() const {return sel_button;} + Qt::KeyboardModifier selectionModifier() const {return sel_mod;} + + void setSelectionMode(SelectionMode v) {sel_mode = v;} + void setSelectionButton(Qt::MouseButton v) {sel_button = v;} + void setSelectionModifier(Qt::KeyboardModifier v) {sel_mod = v;} + void selectObject(GLObjectBase * o); + GLObjectBase * selectedObject() const {return sel_obj;} + + void glReleaseTextures(int channels = 8); + QByteArray saveCamera(); + void restoreCamera(const QByteArray & ba); + QByteArray saveFeatures(); + void restoreFeatures(const QByteArray & ba); + + + GLfloat aspect, iaspect; + QMatrix4x4 cur_mvpm; + +protected: + void render(); + void resizeEvent(QResizeEvent * e); + + void timerEvent(QTimerEvent * ); + void initialize(); + void resizeGL(int width, int height); + void mousePressEvent(QMouseEvent * e); + void mouseMoveEvent(QMouseEvent * e); + void mouseReleaseEvent(QMouseEvent * e); + void wheelEvent(QWheelEvent * e); + void leaveEvent(QEvent * ); + void mouseDoubleClickEvent(QMouseEvent * e); + + void keyPressEvent(QKeyEvent * e); + void keyReleaseEvent(QKeyEvent * e); + void focusOutEvent(QFocusEvent *); + + void applyFog(); + void renderSelection(); + + void checkCaps(); + void collectLights(); + +private: + void objectDeleted(GLObjectBase * o); + void collectObjectLights(GLObjectBase * o); + void objectsCountInternal(int * cnt, GLObjectBase * where); + void removeObjectInternal(GLObjectBase * o, GLObjectBase * where); + void renderSingleSelection(GLObjectBase & o); + //void renderSingleShadow(GLObjectBase & o); + void renderHalo(const GLObjectBase * obj, const uint iid, const QColor & color, const float & fill); + void reloadThisShaders(); + void processKeys(); + bool setupViewport(); + + QPoint lastPos, downPos; + GLObjectBase objects_; + QList lights_; +// uint cid; + QHash ids; + QSet keys_; + FogMode fogMode_; + QColor backColor_, fogColor_, ambientColor_, hoverHaloColor_, selectionHaloColor_; + QTime time, ktm_; + GLint max_anisotropic, max_texture_chanels; + GLObjectBase::RenderMode rmode; + GLObjectBase * sel_obj, * hov_obj; + GLFramebuffer fbo_selection; + QOpenGLShaderProgram * shader_select, * shader_halo; + GLRendererBase * renderer_; + SelectionMode sel_mode; + Qt::MouseButton sel_button; + Qt::KeyboardModifier sel_mod; + GLRendererBase::RenderingParameters start_rp; + QHash features_; + QSize prev_size; + float lineWidth_; + float fogDensity_, fogStart_, fogEnd_, fps_, fps_tm, hoverHaloFill_, selectionHaloFill_, m_motionBlurFactor; + int timer, fps_cnt, sh_id_loc, deleting_; + bool is_first_draw, is_init, fogEnabled_, lightEnabled_, grabMouse_, mouse_first, mouseRotate_, mouseSelect_, customMouseMove_; + bool shaders_supported, changed_, cameraOrbit_, need_init_; + bool hoverHalo_, selectionHalo_, shaders_bind, selecting_; + +public slots: + void setBackColor(const QColor & arg) {backColor_ = arg;} + void setLineWidth(const float & arg) {lineWidth_ = arg;} + void setFOV(const float & arg) {camera()->fov_ = arg;} + void setDepthStart(const float & arg) {camera()->depth_start = arg;} + void setDepthEnd(const float & arg) {camera()->depth_end = arg;} + void setAmbientColor(const QColor & arg) {ambientColor_ = arg;} + void setFogColor(const QColor & arg) {fogColor_ = arg;} + void setFogDensity(const float & arg) {fogDensity_ = arg;} + void setFogStart(const float & arg) {fogStart_ = arg;} + void setFogEnd(const float & arg) {fogEnd_ = arg;} + void setFogMode(const FogMode & arg) {fogMode_ = arg;} + void setFogEnabled(const bool & arg) {fogEnabled_ = arg;} + void setLightEnabled(const bool & arg) {lightEnabled_ = arg;} + void setGrabMouseEnabled(const bool & arg) {grabMouse_ = arg; mouse_first = true;} + void setMouseRotateEnabled(const bool & arg) {mouseRotate_ = arg;} + void setMouseSelectionEnabled(const bool & arg) {mouseSelect_ = arg;} + void setCustomMouseMove(const bool & arg) {customMouseMove_ = arg;} + void setCameraOrbit(const bool & arg) {cameraOrbit_ = arg;} + void setHoverHaloEnabled(const bool & arg) {hoverHalo_ = arg;} + void setHoverHaloColor(const QColor & arg) {hoverHaloColor_ = arg;} + void setHoverHaloFillAlpha(const float & arg) {hoverHaloFill_ = arg;} + void setSelectionHaloEnabled(const bool & arg) {selectionHalo_ = arg;} + void setSelectionHaloColor(const QColor & arg) {selectionHaloColor_ = arg;} + void setSelectionHaloFillAlpha(const float & arg) {selectionHaloFill_ = arg;} + + void reloadShaders() {if (renderer_ != nullptr) renderer_->reloadShaders(); reloadThisShaders();} + void deselect() {sel_obj = nullptr;} + +signals: + void glBeforePaint(); + void glBeginPaint(); + void glPainting(); + void glEndPaint(); + void glKeyPressEvent(QKeyEvent * e); + void glKeyReleaseEvent(QKeyEvent * e); + void glMousePressEvent(QMouseEvent * e); + void glMouseMoveEvent(QMouseEvent * e); + void glMouseReleaseEvent(QMouseEvent * e); + void glWheelEvent(QWheelEvent * e); + void glResize(int, int); + void glInitializeDone(); + void cameraPosChanged(QVector3D pos); + void keyEvent(Qt::Key key, Qt::KeyboardModifiers mod); + void customMouseMoveEvent(QPoint curpos, QPoint lastpos, Qt::MouseButtons buttons); + + void hoverChanged(GLObjectBase * cur, GLObjectBase * prev); + void selectionChanged(GLObjectBase * cur, GLObjectBase * prev); + void objectAdded(GLObjectBase * ); + void doubleClick(); + +}; + +#endif // QGLVIEW_H