diff --git a/.hgignore b/.hgignore index 4a0311dcc..1fbad60fd 100644 --- a/.hgignore +++ b/.hgignore @@ -144,6 +144,8 @@ external external_stlport 3rdParty .svn +thumbs.db +Thumbs.db # build code/nel/build/* @@ -206,3 +208,5 @@ code/ryzom/server/src/ryzom_admin_service/ryzom_admin_service code/ryzom/server/src/ryzom_naming_service/ryzom_naming_service code/ryzom/server/src/ryzom_welcome_service/ryzom_welcome_service code/ryzom/server/src/tick_service/tick_service +# WebTT temp dir +code/ryzom/tools/server/www/webtt/app/tmp diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 630ff4414..b73545d14 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -91,6 +91,7 @@ NL_CONFIGURE_CHECKS() #Platform specifics SETUP_EXTERNAL() +NL_GEN_REVISION_H() IF(WIN32) SET(WINSOCK2_LIB ws2_32.lib) @@ -143,11 +144,11 @@ IF(WITH_RYZOM) ENDIF(WITH_RYZOM) IF(WITH_NELNS) -# ADD_SUBDIRECTORY(nelns) + ADD_SUBDIRECTORY(nelns) ENDIF(WITH_NELNS) IF(WITH_SNOWBALLS) -# ADD_SUBDIRECTORY(snowballs2) + ADD_SUBDIRECTORY(snowballs2) ENDIF(WITH_SNOWBALLS) IF(WITH_TOOLS) @@ -256,7 +257,7 @@ IF(WIN32) IF(WITH_TOOLS) SET(CMAKE_INSTALL_MFC_LIBRARIES TRUE) ENDIF(WITH_TOOLS) - INCLUDE(InstallRequiredSystemLibraries) + #INCLUDE(InstallRequiredSystemLibraries) ENDIF(WIN32) INCLUDE(CPack) diff --git a/code/CMakeModules/Find3dsMaxSDK.cmake b/code/CMakeModules/Find3dsMaxSDK.cmake index 52c4cc011..ddec22f90 100644 --- a/code/CMakeModules/Find3dsMaxSDK.cmake +++ b/code/CMakeModules/Find3dsMaxSDK.cmake @@ -12,32 +12,35 @@ endif(MAXSDK_INCLUDE_DIR) find_path(MAXSDK_INCLUDE_DIR max.h PATHS + "$ENV{ADSK_3DSMAX_SDK_2012}/maxsdk/include" + "$ENV{3DSMAX_2011_SDK_PATH}/maxsdk/include" "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2010 SDK/maxsdk/include" "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2009 SDK/maxsdk/include" "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2008 SDK/maxsdk/include" "$ENV{PROGRAMFILES}/Autodesk/3ds Max 9 SDK/maxsdk/include" - "$ENV{3DSMAX_2011_SDK_PATH}/maxsdk/include" ) find_path(MAXSDK_CS_INCLUDE_DIR bipexp.h PATHS + "$ENV{ADSK_3DSMAX_SDK_2012}/maxsdk/include/CS" + "$ENV{3DSMAX_2011_SDK_PATH}/maxsdk/include/CS" "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2010 SDK/maxsdk/include/CS" "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2009 SDK/maxsdk/include/CS" "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2008 SDK/maxsdk/include/CS" "$ENV{PROGRAMFILES}/Autodesk/3ds Max 9 SDK/maxsdk/include/CS" - "$ENV{3DSMAX_2011_SDK_PATH}/maxsdk/include/CS" ) MACRO(FIND_3DS_LIBRARY MYLIBRARY MYLIBRARYNAME) FIND_LIBRARY(${MYLIBRARY} NAMES ${MYLIBRARYNAME} PATHS + "$ENV{ADSK_3DSMAX_SDK_2012}/maxsdk/lib" + "$ENV{3DSMAX_2011_SDK_PATH}/maxsdk/lib" "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2010 SDK/maxsdk/lib" "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2009 SDK/maxsdk/lib" "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2008 SDK/maxsdk/lib" "$ENV{PROGRAMFILES}/Autodesk/3ds Max 9 SDK/maxsdk/lib" - "$ENV{3DSMAX_2011_SDK_PATH}/maxsdk/lib" - ) + ) ENDMACRO(FIND_3DS_LIBRARY MYLIBRARY MYLIBRARYNAME) FIND_3DS_LIBRARY(MAXSDK_CORE_LIBRARY core) diff --git a/code/CMakeModules/FindDirectXSDK.cmake b/code/CMakeModules/FindDirectXSDK.cmake index 1f832cf95..9947778db 100644 --- a/code/CMakeModules/FindDirectXSDK.cmake +++ b/code/CMakeModules/FindDirectXSDK.cmake @@ -14,17 +14,22 @@ FIND_PATH(DXSDK_DIR "Include/dxsdkver.h" PATHS "$ENV{DXSDK_DIR}" + "C:/Program Files (x86)/Microsoft DirectX SDK (June 2010)" + "C:/Program Files/Microsoft DirectX SDK (June 2010)" + "C:/Program Files (x86)/Microsoft DirectX SDK (February 2010)" + "C:/Program Files/Microsoft DirectX SDK (February 2010)" + "C:/Program Files (x86)/Microsoft DirectX SDK (November 2007)" + "C:/Program Files/Microsoft DirectX SDK (November 2007)" + "C:/Program Files (x86)/Microsoft DirectX SDK" + "C:/Program Files/Microsoft DirectX SDK" ) MACRO(FIND_DXSDK_LIBRARY MYLIBRARY MYLIBRARYNAME) FIND_LIBRARY(${MYLIBRARY} NAMES ${MYLIBRARYNAME} PATHS - "${DXSDK_LIBRARY_DIR}" - "$ENV{DXSDK_DIR}" - "$ENV{DXSDK_DIR}/Lib" - "$ENV{DXSDK_DIR}/Lib/x86" - ) + "${DXSDK_LIBRARY_DIR}" + ) ENDMACRO(FIND_DXSDK_LIBRARY MYLIBRARY MYLIBRARYNAME) IF(DXSDK_DIR) diff --git a/code/CMakeModules/FindExternal.cmake b/code/CMakeModules/FindExternal.cmake index fae4af92d..5d6086bc6 100644 --- a/code/CMakeModules/FindExternal.cmake +++ b/code/CMakeModules/FindExternal.cmake @@ -8,7 +8,7 @@ # EXTERNAL_FOUND - True if the external libraries are available SET(EXTERNAL_TEMP_PATH ${CMAKE_CURRENT_SOURCE_DIR}/external ${CMAKE_CURRENT_SOURCE_DIR}/../external ${CMAKE_CURRENT_SOURCE_DIR}/3rdParty ${CMAKE_CURRENT_SOURCE_DIR}/../3rdParty ${EXTERNAL_PATH}) -SET(EXTERNAL_TEMP_FILE "include/zlib.h") +SET(EXTERNAL_TEMP_FILE "include/wwwconf.h") SET(EXTERNAL_NAME "external") # If using STLport preprend external_stlport @@ -36,18 +36,18 @@ IF(EXTERNAL_PATH) SET(EXTERNAL_INCLUDE_PATH "${EXTERNAL_PATH}/include") # Using 32 or 64 bits binaries - IF(TARGET_X64) + IF(TARGET_X64 AND WIN32) SET(EXTERNAL_BINARY_PATH "${EXTERNAL_PATH}/bin64") - ELSE(TARGET_X64) + ELSE(TARGET_X64 AND WIN32) SET(EXTERNAL_BINARY_PATH "${EXTERNAL_PATH}/bin") - ENDIF(TARGET_X64) - + ENDIF(TARGET_X64 AND WIN32) + # Using 32 or 64 bits libraries - IF(TARGET_X64) + IF(TARGET_X64 AND WIN32) SET(EXTERNAL_LIBRARY_PATH "${EXTERNAL_PATH}/lib64") - ELSE(TARGET_X64) + ELSE(TARGET_X64 AND WIN32) SET(EXTERNAL_LIBRARY_PATH "${EXTERNAL_PATH}/lib") - ENDIF(TARGET_X64) + ENDIF(TARGET_X64 AND WIN32) SET(CMAKE_INCLUDE_PATH "${EXTERNAL_INCLUDE_PATH};${CMAKE_INCLUDE_PATH}") # Stupid hack for FindOpenAL.cmake diff --git a/code/CMakeModules/FindFreeType.cmake b/code/CMakeModules/FindFreeType.cmake index 0ba439fb9..4f3c84cbe 100644 --- a/code/CMakeModules/FindFreeType.cmake +++ b/code/CMakeModules/FindFreeType.cmake @@ -41,7 +41,7 @@ IF(FREETYPE_ADDITIONAL_INCLUDE_DIR) ENDIF(FREETYPE_ADDITIONAL_INCLUDE_DIR) FIND_LIBRARY(FREETYPE_LIBRARY - NAMES freetype libfreetype freetype219 + NAMES freetype libfreetype freetype219 freetype246 PATHS $ENV{FREETYPE_DIR}/lib /usr/local/lib @@ -57,6 +57,13 @@ FIND_LIBRARY(FREETYPE_LIBRARY IF(FREETYPE_LIBRARY AND FREETYPE_INCLUDE_DIRS) SET(FREETYPE_FOUND "YES") + IF(WITH_STATIC_EXTERNAL AND APPLE) + FIND_PACKAGE(BZip2) + IF(BZIP2_FOUND) + SET(FREETYPE_INCLUDE_DIRS ${FREETYPE_INCLUDE_DIRS} ${BZIP2_INCLUDE_DIR}) + SET(FREETYPE_LIBRARY ${FREETYPE_LIBRARY} ${BZIP2_LIBRARIES}) + ENDIF(BZIP2_FOUND) + ENDIF(WITH_STATIC_EXTERNAL AND APPLE) IF(NOT FREETYPE_FIND_QUIETLY) MESSAGE(STATUS "Found FreeType: ${FREETYPE_LIBRARY}") ENDIF(NOT FREETYPE_FIND_QUIETLY) diff --git a/code/CMakeModules/FindGTK2.cmake b/code/CMakeModules/FindGTK2.cmake index 7aa65e100..e3e91ed21 100644 --- a/code/CMakeModules/FindGTK2.cmake +++ b/code/CMakeModules/FindGTK2.cmake @@ -66,6 +66,7 @@ else (GTK2_LIBRARIES AND GTK2_INCLUDE_DIRS) /usr/lib64/glib-2.0/include /usr/lib/glib-2.0/include /sw/lib/glib-2.0/include + /usr/lib/x86_64-linux-gnu/glib-2.0/include ) gtk2_debug_message("GTK2_GLIBCONFIG_INCLUDE_DIR is ${GTK2_GLIBCONFIG_INCLUDE_DIR}") @@ -95,9 +96,25 @@ else (GTK2_LIBRARIES AND GTK2_INCLUDE_DIRS) /usr/lib/gtk-2.0/include /usr/lib64/gtk-2.0/include /sw/lib/gtk-2.0/include + /usr/lib/x86_64-linux-gnu/gtk-2.0/include ) gtk2_debug_message("GTK2_GDK_INCLUDE_DIR is ${GTK2_GDK_INCLUDE_DIR}") + find_path(GTK2_GDK_PIXBUF_INCLUDE_DIR + NAMES + gdk-pixbuf/gdk-pixbuf.h + PATHS + ${_GDK2IncDir} + /opt/gnome/lib/gtk-2.0/include + /opt/gnome/lib64/gtk-2.0/include + /opt/lib/gtk-2.0/include + /usr/lib/gtk-2.0/include + /usr/lib64/gtk-2.0/include + /sw/lib/gtk-2.0/include + /usr/include/gdk-pixbuf-2.0 + ) + gtk2_debug_message("GTK2_GDK_PIXBUF_INCLUDE_DIR is ${GTK2_GDK_PIXBUF_INCLUDE_DIR}") + find_path(GTK2_GTKGL_INCLUDE_DIR NAMES gtkgl/gtkglarea.h @@ -357,6 +374,7 @@ else (GTK2_LIBRARIES AND GTK2_INCLUDE_DIRS) ${GTK2_GLIBCONFIG_INCLUDE_DIR} ${GTK2_GLIB_INCLUDE_DIR} ${GTK2_GDK_INCLUDE_DIR} + ${GTK2_GDK_PIXBUF_INCLUDE_DIR} ${GTK2_GLADE_INCLUDE_DIR} ${GTK2_PANGO_INCLUDE_DIR} ${GTK2_CAIRO_INCLUDE_DIR} @@ -364,7 +382,7 @@ else (GTK2_LIBRARIES AND GTK2_INCLUDE_DIRS) ) if (GTK2_GTK_LIBRARY AND GTK2_GTK_INCLUDE_DIR) - if (GTK2_GDK_LIBRARY AND GTK2_GDK_PIXBUF_LIBRARY AND GTK2_GDK_INCLUDE_DIR) + if (GTK2_GDK_LIBRARY AND GTK2_GDK_PIXBUF_LIBRARY AND GTK2_GDK_INCLUDE_DIR AND GTK2_GDK_PIXBUF_INCLUDE_DIR) if (GTK2_GMODULE_LIBRARY) if (GTK2_GTHREAD_LIBRARY) if (GTK2_GOBJECT_LIBRARY) @@ -423,9 +441,9 @@ else (GTK2_LIBRARIES AND GTK2_INCLUDE_DIRS) else (GTK2_GMODULE_LIBRARY) message(SEND_ERROR "Could not find GMODULE") endif (GTK2_GMODULE_LIBRARY) - else (GTK2_GDK_LIBRARY AND GTK2_GDK_PIXBUF_LIBRARY AND GTK2_GDK_INCLUDE_DIR) + else (GTK2_GDK_LIBRARY AND GTK2_GDK_PIXBUF_LIBRARY AND GTK2_GDK_INCLUDE_DIR AND GTK2_GDK_PIXBUF_INCLUDE_DIR) message(SEND_ERROR "Could not find GDK (GDK_PIXBUF)") - endif (GTK2_GDK_LIBRARY AND GTK2_GDK_PIXBUF_LIBRARY AND GTK2_GDK_INCLUDE_DIR) + endif (GTK2_GDK_LIBRARY AND GTK2_GDK_PIXBUF_LIBRARY AND GTK2_GDK_INCLUDE_DIR AND GTK2_GDK_PIXBUF_INCLUDE_DIR) else (GTK2_GTK_LIBRARY AND GTK2_GTK_INCLUDE_DIR) message(SEND_ERROR "Could not find GTK2-X11") endif (GTK2_GTK_LIBRARY AND GTK2_GTK_INCLUDE_DIR) diff --git a/code/CMakeModules/FindLibwww.cmake b/code/CMakeModules/FindLibwww.cmake index 8f1c1c02a..77140492e 100644 --- a/code/CMakeModules/FindLibwww.cmake +++ b/code/CMakeModules/FindLibwww.cmake @@ -6,6 +6,8 @@ # LIBWWW_LIBRARY, where to find the LibWWW library. # LIBWWW_FOUND, If false, do not try to use LibWWW. +OPTION(WITH_LIBWWW_STATIC "Use only static libraries for libwww" OFF) + SET(LIBWWW_FIND_QUIETLY ${Libwww_FIND_QUIETLY}) # also defined, but not for general use are @@ -46,6 +48,11 @@ ENDIF(LIBWWW_ADDITIONAL_INCLUDE_DIR) # helper to find all the libwww sub libraries MACRO(FIND_WWW_LIBRARY MYLIBRARY OPTION) + IF(WITH_LIBWWW_STATIC AND UNIX AND NOT APPLE AND NOT WITH_STATIC_EXTERNAL) + SET(CMAKE_FIND_LIBRARY_SUFFIXES_OLD ${CMAKE_FIND_LIBRARY_SUFFIXES}) + SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a") + ENDIF(WITH_LIBWWW_STATIC AND UNIX AND NOT APPLE AND NOT WITH_STATIC_EXTERNAL) + FIND_LIBRARY(${MYLIBRARY} NAMES ${ARGN} PATHS @@ -60,21 +67,27 @@ MACRO(FIND_WWW_LIBRARY MYLIBRARY OPTION) /usr/freeware/lib64 ) + IF(CMAKE_FIND_LIBRARY_SUFFIXES_OLD) + SET(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_OLD}) + ENDIF(CMAKE_FIND_LIBRARY_SUFFIXES_OLD) + IF(${MYLIBRARY}) - IF(${OPTION} STREQUAL REQUIRED OR WITH_STATIC) + IF(${OPTION} STREQUAL REQUIRED OR WITH_STATIC OR WITH_LIBWWW_STATIC) SET(LIBWWW_LIBRARIES ${LIBWWW_LIBRARIES} ${${MYLIBRARY}}) - ENDIF(${OPTION} STREQUAL REQUIRED OR WITH_STATIC) + ENDIF(${OPTION} STREQUAL REQUIRED OR WITH_STATIC OR WITH_LIBWWW_STATIC) ELSE(${MYLIBRARY}) - IF(NOT LIBWWW_FIND_QUIETLY) + IF(NOT LIBWWW_FIND_QUIETLY AND NOT WIN32) MESSAGE(STATUS "Warning: Libwww: Library not found: ${MYLIBRARY}") - ENDIF(NOT LIBWWW_FIND_QUIETLY) + ENDIF(NOT LIBWWW_FIND_QUIETLY AND NOT WIN32) ENDIF(${MYLIBRARY}) MARK_AS_ADVANCED(${MYLIBRARY}) ENDMACRO(FIND_WWW_LIBRARY) MACRO(LINK_WWW_LIBRARY MYLIBRARY OTHERLIBRARY SYMBOL) - LINK_DEPENDS(LIBWWW_LIBRARIES ${MYLIBRARY} ${OTHERLIBRARY} ${SYMBOL}) + IF(NOT WITH_LIBWWW_STATIC AND NOT WITH_STATIC_EXTERNAL) + LINK_DEPENDS(LIBWWW_LIBRARIES ${MYLIBRARY} ${OTHERLIBRARY} ${SYMBOL}) + ENDIF(NOT WITH_LIBWWW_STATIC AND NOT WITH_STATIC_EXTERNAL) ENDMACRO(LINK_WWW_LIBRARY) # Find and link required libs for static or dynamic diff --git a/code/CMakeModules/FindMercurial.cmake b/code/CMakeModules/FindMercurial.cmake new file mode 100644 index 000000000..9c252ad17 --- /dev/null +++ b/code/CMakeModules/FindMercurial.cmake @@ -0,0 +1,108 @@ +# - Extract information from a subversion working copy +# The module defines the following variables: +# Mercurial_HG_EXECUTABLE - path to hg command line client +# Mercurial_VERSION_HG - version of hg command line client +# Mercurial_FOUND - true if the command line client was found +# MERCURIAL_FOUND - same as Mercurial_FOUND, set for compatiblity reasons +# +# The minimum required version of Mercurial can be specified using the +# standard syntax, e.g. FIND_PACKAGE(Mercurial 1.4) +# +# If the command line client executable is found two macros are defined: +# Mercurial_WC_INFO( ) +# Mercurial_WC_LOG( ) +# Mercurial_WC_INFO extracts information of a subversion working copy at +# a given location. This macro defines the following variables: +# _WC_URL - url of the repository (at ) +# _WC_ROOT - root url of the repository +# _WC_REVISION - current revision +# _WC_LAST_CHANGED_AUTHOR - author of last commit +# _WC_LAST_CHANGED_DATE - date of last commit +# _WC_LAST_CHANGED_REV - revision of last commit +# _WC_INFO - output of command `hg info ' +# Mercurial_WC_LOG retrieves the log message of the base revision of a +# subversion working copy at a given location. This macro defines the +# variable: +# _LAST_CHANGED_LOG - last log of base revision +# Example usage: +# FIND_PACKAGE(Mercurial) +# IF(MERCURIAL_FOUND) +# Mercurial_WC_INFO(${PROJECT_SOURCE_DIR} Project) +# MESSAGE("Current revision is ${Project_WC_REVISION}") +# Mercurial_WC_LOG(${PROJECT_SOURCE_DIR} Project) +# MESSAGE("Last changed log is ${Project_LAST_CHANGED_LOG}") +# ENDIF(MERCURIAL_FOUND) + +#============================================================================= +# Copyright 2006-2009 Kitware, Inc. +# Copyright 2006 Tristan Carel +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +FIND_PROGRAM(Mercurial_HG_EXECUTABLE hg + DOC "mercurial command line client") +MARK_AS_ADVANCED(Mercurial_HG_EXECUTABLE) + +IF(Mercurial_HG_EXECUTABLE) + EXECUTE_PROCESS(COMMAND ${Mercurial_HG_EXECUTABLE} --version + OUTPUT_VARIABLE Mercurial_VERSION_HG + OUTPUT_STRIP_TRAILING_WHITESPACE) + + STRING(REGEX REPLACE ".*version ([\\.0-9]+).*" + "\\1" Mercurial_VERSION_HG "${Mercurial_VERSION_HG}") + + MACRO(Mercurial_WC_INFO dir prefix) + EXECUTE_PROCESS(COMMAND ${Mercurial_HG_EXECUTABLE} tip + WORKING_DIRECTORY ${dir} + OUTPUT_VARIABLE ${prefix}_WC_INFO + ERROR_VARIABLE Mercurial_hg_info_error + RESULT_VARIABLE Mercurial_hg_info_result + OUTPUT_STRIP_TRAILING_WHITESPACE) + + IF(NOT ${Mercurial_hg_info_result} EQUAL 0) + MESSAGE(SEND_ERROR "Command \"${Mercurial_HG_EXECUTABLE} tip\" failed with output:\n${Mercurial_hg_info_error}") + ELSE(NOT ${Mercurial_hg_info_result} EQUAL 0) + + STRING(REGEX REPLACE "^(.*\n)?Repository Root: ([^\n]+).*" + "\\2" ${prefix}_WC_ROOT "${${prefix}_WC_INFO}") + STRING(REGEX REPLACE "^(.*\n)?changeset: *([0-9]+).*" + "\\2" ${prefix}_WC_REVISION "${${prefix}_WC_INFO}") + STRING(REGEX REPLACE "^(.*\n)?Last Changed Author: ([^\n]+).*" + "\\2" ${prefix}_WC_LAST_CHANGED_AUTHOR "${${prefix}_WC_INFO}") + STRING(REGEX REPLACE "^(.*\n)?Last Changed Rev: ([^\n]+).*" + "\\2" ${prefix}_WC_LAST_CHANGED_REV "${${prefix}_WC_INFO}") + STRING(REGEX REPLACE "^(.*\n)?Last Changed Date: ([^\n]+).*" + "\\2" ${prefix}_WC_LAST_CHANGED_DATE "${${prefix}_WC_INFO}") + + ENDIF(NOT ${Mercurial_hg_info_result} EQUAL 0) + + ENDMACRO(Mercurial_WC_INFO) + + MACRO(Mercurial_WC_LOG dir prefix) + # This macro can block if the certificate is not signed: + # hg ask you to accept the certificate and wait for your answer + # This macro requires a hg server network access (Internet most of the time) + # and can also be slow since it access the hg server + EXECUTE_PROCESS(COMMAND + ${Mercurial_HG_EXECUTABLE} --non-interactive log -r BASE ${dir} + OUTPUT_VARIABLE ${prefix}_LAST_CHANGED_LOG + ERROR_VARIABLE Mercurial_hg_log_error + RESULT_VARIABLE Mercurial_hg_log_result + OUTPUT_STRIP_TRAILING_WHITESPACE) + + IF(NOT ${Mercurial_hg_log_result} EQUAL 0) + MESSAGE(SEND_ERROR "Command \"${Mercurial_HG_EXECUTABLE} log -r BASE ${dir}\" failed with output:\n${Mercurial_hg_log_error}") + ENDIF(NOT ${Mercurial_hg_log_result} EQUAL 0) + ENDMACRO(Mercurial_WC_LOG) +ENDIF(Mercurial_HG_EXECUTABLE) + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Mercurial DEFAULT_MSG Mercurial_HG_EXECUTABLE) diff --git a/code/CMakeModules/FindMySQL.cmake b/code/CMakeModules/FindMySQL.cmake index b9970f63c..a00e36992 100644 --- a/code/CMakeModules/FindMySQL.cmake +++ b/code/CMakeModules/FindMySQL.cmake @@ -54,10 +54,14 @@ ELSE(MYSQL_INCLUDE_DIR AND MYSQL_LIBRARIES) IF(MYSQL_INCLUDE_DIR) IF(MYSQL_LIBRARY_RELEASE) - SET(MYSQL_LIBRARIES "optimized;${MYSQL_LIBRARY_RELEASE}") + SET(MYSQL_LIBRARIES optimized ${MYSQL_LIBRARY_RELEASE}) IF(MYSQL_LIBRARY_DEBUG) - SET(MYSQL_LIBRARIES "${MYSQL_LIBRARIES};debug;${MYSQL_LIBRARY_DEBUG}") + SET(MYSQL_LIBRARIES ${MYSQL_LIBRARIES} debug ${MYSQL_LIBRARY_DEBUG}) ENDIF(MYSQL_LIBRARY_DEBUG) + FIND_PACKAGE(OpenSSL) + IF(OPENSSL_FOUND) + SET(MYSQL_LIBRARIES ${MYSQL_LIBRARIES} ${OPENSSL_LIBRARIES}) + ENDIF(OPENSSL_FOUND) ENDIF(MYSQL_LIBRARY_RELEASE) ENDIF(MYSQL_INCLUDE_DIR) diff --git a/code/CMakeModules/FindWindowsSDK.cmake b/code/CMakeModules/FindWindowsSDK.cmake index 30e507f85..25903be14 100644 --- a/code/CMakeModules/FindWindowsSDK.cmake +++ b/code/CMakeModules/FindWindowsSDK.cmake @@ -33,6 +33,12 @@ FIND_PATH(WINSDK_INCLUDE_DIR Windows.h ${WINSDKCURRENT_DIR}/Include ) +FIND_PROGRAM(WINSDK_SIGNTOOL signtool + PATHS + ${WINSDK71_DIR}/Bin + ${WINSDKCURRENT_DIR}/Bin +) + IF(WINSDK_INCLUDE_DIR) SET(WINSDK_FOUND TRUE) ELSE(WINSDK_INCLUDE_DIR) diff --git a/code/CMakeModules/GetRevision.cmake b/code/CMakeModules/GetRevision.cmake new file mode 100644 index 000000000..d38215aba --- /dev/null +++ b/code/CMakeModules/GetRevision.cmake @@ -0,0 +1,60 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6.3) + +# ROOT_DIR should be set to root of the repository (where to find the .svn or .hg directory) +# SOURCE_DIR should be set to root of your code (where to find CMakeLists.txt) + +# Replace spaces by semi-columns +IF(CMAKE_MODULE_PATH) + STRING(REPLACE " " ";" CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}) +ENDIF(CMAKE_MODULE_PATH) + +SET(CMAKE_MODULE_PATH ${SOURCE_DIR}/CMakeModules ${CMAKE_MODULE_PATH}) + +IF(NOT ROOT_DIR AND SOURCE_DIR) + SET(ROOT_DIR ${SOURCE_DIR}) +ENDIF(NOT ROOT_DIR AND SOURCE_DIR) + +IF(NOT SOURCE_DIR AND ROOT_DIR) + SET(SOURCE_DIR ${ROOT_DIR}) +ENDIF(NOT SOURCE_DIR AND ROOT_DIR) + +MACRO(NOW RESULT) + IF (WIN32) + EXECUTE_PROCESS(COMMAND "wmic" "os" "get" "localdatetime" OUTPUT_VARIABLE DATETIME) + IF(NOT DATETIME MATCHES "ERROR") + STRING(REGEX REPLACE ".*\n([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9]).*" "\\1-\\2-\\3 \\4:\\5:\\6" ${RESULT} "${DATETIME}") + ENDIF(NOT DATETIME MATCHES "ERROR") + ELSEIF(UNIX) + EXECUTE_PROCESS(COMMAND "date" "+%Y-%m-%d %H:%M:%S" OUTPUT_VARIABLE DATETIME) + STRING(REGEX REPLACE "([0-9: -]+).*" "\\1" ${RESULT} "${DATETIME}") + ELSE (WIN32) + MESSAGE(SEND_ERROR "date not implemented") + SET(${RESULT} "0000-00-00 00:00:00") + ENDIF (WIN32) +ENDMACRO(NOW) + +IF(EXISTS "${ROOT_DIR}/.svn/") + FIND_PACKAGE(Subversion) + + IF(SUBVERSION_FOUND) + Subversion_WC_INFO(${ROOT_DIR} ER) + SET(REVISION ${ER_WC_REVISION}) + ENDIF(SUBVERSION_FOUND) +ENDIF(EXISTS "${ROOT_DIR}/.svn/") + +IF(EXISTS "${ROOT_DIR}/.hg/") + FIND_PACKAGE(Mercurial) + + IF(MERCURIAL_FOUND) + Mercurial_WC_INFO(${ROOT_DIR} ER) + SET(REVISION ${ER_WC_REVISION}) + ENDIF(MERCURIAL_FOUND) +ENDIF(EXISTS "${ROOT_DIR}/.hg/") + +IF(REVISION) + IF(EXISTS ${SOURCE_DIR}/revision.h.in) + NOW(BUILD_DATE) + CONFIGURE_FILE(${SOURCE_DIR}/revision.h.in revision.h.txt) + EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E copy revision.h.txt revision.h) # copy_if_different + ENDIF(EXISTS ${SOURCE_DIR}/revision.h.in) +ENDIF(REVISION) diff --git a/code/CMakeModules/PCHSupport.cmake b/code/CMakeModules/PCHSupport.cmake index bb34aebfe..ae5b30ee2 100644 --- a/code/CMakeModules/PCHSupport.cmake +++ b/code/CMakeModules/PCHSupport.cmake @@ -8,44 +8,40 @@ # ADD_PRECOMPILED_HEADER_TO_TARGET _targetName _input _pch_output_to_use # ADD_NATIVE_PRECOMPILED_HEADER _targetName _inputh _inputcpp -IF(CMAKE_COMPILER_IS_GNUCXX) +IF(MSVC) + SET(PCHSupport_FOUND TRUE) + SET(_PCH_include_prefix "/I") +ELSE(MSVC) + IF(CMAKE_COMPILER_IS_GNUCXX) + EXEC_PROGRAM(${CMAKE_CXX_COMPILER} + ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion + OUTPUT_VARIABLE gcc_compiler_version) - EXEC_PROGRAM( - ${CMAKE_CXX_COMPILER} - ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion - OUTPUT_VARIABLE gcc_compiler_version) - - IF(gcc_compiler_version MATCHES "4\\.[0-9]\\.[0-9]") - SET(PCHSupport_FOUND TRUE) - ELSE(gcc_compiler_version MATCHES "4\\.[0-9]\\.[0-9]") - IF(gcc_compiler_version MATCHES "3\\.4\\.[0-9]") + IF(gcc_compiler_version MATCHES "4\\.[0-9]\\.[0-9]") SET(PCHSupport_FOUND TRUE) - ENDIF(gcc_compiler_version MATCHES "3\\.4\\.[0-9]") - ENDIF(gcc_compiler_version MATCHES "4\\.[0-9]\\.[0-9]") + ELSE(gcc_compiler_version MATCHES "4\\.[0-9]\\.[0-9]") + IF(gcc_compiler_version MATCHES "3\\.4\\.[0-9]") + SET(PCHSupport_FOUND TRUE) + ENDIF(gcc_compiler_version MATCHES "3\\.4\\.[0-9]") + ENDIF(gcc_compiler_version MATCHES "4\\.[0-9]\\.[0-9]") + ELSE(CMAKE_COMPILER_IS_GNUCXX) + # TODO: make tests for other compilers than GCC + SET(PCHSupport_FOUND TRUE) + ENDIF(CMAKE_COMPILER_IS_GNUCXX) SET(_PCH_include_prefix "-I") - -ELSE(CMAKE_COMPILER_IS_GNUCXX) - - IF(WIN32) - SET(PCHSupport_FOUND TRUE) # for experimental msvc support - SET(_PCH_include_prefix "/I") - ELSE(WIN32) - SET(PCHSupport_FOUND FALSE) - ENDIF(WIN32) - -ENDIF(CMAKE_COMPILER_IS_GNUCXX) +ENDIF(MSVC) MACRO(_PCH_GET_COMPILE_FLAGS _out_compile_flags) STRING(TOUPPER "CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}" _flags_var_name) SET(${_out_compile_flags} ${${_flags_var_name}} ) - IF(CMAKE_COMPILER_IS_GNUCXX) + IF(NOT MSVC) GET_TARGET_PROPERTY(_targetType ${_PCH_current_target} TYPE) IF(${_targetType} STREQUAL SHARED_LIBRARY OR ${_targetType} STREQUAL MODULE_LIBRARY) LIST(APPEND ${_out_compile_flags} "-fPIC") ENDIF(${_targetType} STREQUAL SHARED_LIBRARY OR ${_targetType} STREQUAL MODULE_LIBRARY) - ENDIF(CMAKE_COMPILER_IS_GNUCXX) + ENDIF(NOT MSVC) GET_DIRECTORY_PROPERTY(DIRINC INCLUDE_DIRECTORIES ) FOREACH(item ${DIRINC}) @@ -100,17 +96,13 @@ MACRO(_PCH_GET_COMPILE_COMMAND out_command _input _inputcpp _output) SET(pchsupport_compiler_cxx_arg1 "") ENDIF(CMAKE_CXX_COMPILER_ARG1) - IF(CMAKE_COMPILER_IS_GNUCXX) - SET(${out_command} - ${CMAKE_CXX_COMPILER} ${pchsupport_compiler_cxx_arg1} ${_compile_FLAGS} -x c++-header -o ${_output} -c ${_input} - ) - ELSE(CMAKE_COMPILER_IS_GNUCXX) + IF(MSVC) _PCH_GET_PDB_FILENAME(PDB_FILE ${_PCH_current_target}) - SET(${out_command} - ${CMAKE_CXX_COMPILER} ${pchsupport_compiler_cxx_arg1} ${_compile_FLAGS} /Yc /Fp\"${_output}\" ${_inputcpp} /c /Fd\"${PDB_FILE}\" - ) - ENDIF(CMAKE_COMPILER_IS_GNUCXX) -ENDMACRO(_PCH_GET_COMPILE_COMMAND ) + SET(${out_command} ${CMAKE_CXX_COMPILER} ${pchsupport_compiler_cxx_arg1} ${_compile_FLAGS} /Yc /Fp\"${_output}\" ${_inputcpp} /c /Fd\"${PDB_FILE}\") + ELSE(MSVC) + SET(${out_command} ${CMAKE_CXX_COMPILER} ${pchsupport_compiler_cxx_arg1} ${_compile_FLAGS} -x c++-header -o ${_output} -c ${_input}) + ENDIF(MSVC) +ENDMACRO(_PCH_GET_COMPILE_COMMAND) MACRO(GET_PRECOMPILED_HEADER_OUTPUT _targetName _input _output) IF(MSVC) @@ -128,7 +120,9 @@ MACRO(ADD_PRECOMPILED_HEADER_TO_TARGET _targetName _input _pch_output_to_use ) SET(oldProps "") ENDIF(${oldProps} MATCHES NOTFOUND) - IF(CMAKE_COMPILER_IS_GNUCXX) + IF(MSVC) + SET(_target_cflags "${oldProps} /Yu\"${_input}\" /FI\"${_input}\" /Fp\"${_pch_output_to_use}\"") + ELSE(MSVC) # to do: test whether compiler flags match between target _targetName # and _pch_output_to_use FILE(TO_NATIVE_PATH ${_pch_output_to_use} _native_pch_path) @@ -137,11 +131,7 @@ MACRO(ADD_PRECOMPILED_HEADER_TO_TARGET _targetName _input _pch_output_to_use ) # on all remote machines set # PCH_ADDITIONAL_COMPILER_FLAGS to -fpch-preprocess SET(_target_cflags "${oldProps} ${PCH_ADDITIONAL_COMPILER_FLAGS}-include ${_input} -Winvalid-pch") - ELSE(CMAKE_COMPILER_IS_GNUCXX) - IF(MSVC) - SET(_target_cflags "${oldProps} /Yu\"${_input}\" /FI\"${_input}\" /Fp\"${_pch_output_to_use}\"") - ENDIF(MSVC) - ENDIF(CMAKE_COMPILER_IS_GNUCXX) + ENDIF(MSVC) SET_TARGET_PROPERTIES(${_targetName} PROPERTIES COMPILE_FLAGS ${_target_cflags}) IF(oldProps) @@ -184,8 +174,31 @@ MACRO(ADD_PRECOMPILED_HEADER _targetName _inputh _inputcpp) ADD_PRECOMPILED_HEADER_TO_TARGET(${_targetName} ${_inputh} ${_output}) ENDMACRO(ADD_PRECOMPILED_HEADER) +# Macro to move PCH creation file to the front of files list +MACRO(FIX_PRECOMPILED_HEADER _files _pch) + # Remove .cpp creating PCH from the list + LIST(REMOVE_ITEM ${_files} ${_pch}) + # Prepend .cpp creating PCH to the list + LIST(INSERT ${_files} 0 ${_pch}) +ENDMACRO(FIX_PRECOMPILED_HEADER) + MACRO(ADD_NATIVE_PRECOMPILED_HEADER _targetName _inputh _inputcpp) - IF(CMAKE_GENERATOR MATCHES Visual*) + SET(PCH_METHOD 0) + + # 0 => creating a new target for PCH, works for all makefiles + # 1 => setting PCH for VC++ project, works for VC++ projects + # 2 => setting PCH for XCode project, works for XCode projects + IF(CMAKE_GENERATOR MATCHES "Visual Studio") + SET(PCH_METHOD 1) + ELSEIF(CMAKE_GENERATOR MATCHES "NMake Makefiles" AND MFC_FOUND AND CMAKE_MFC_FLAG) + # To fix a bug with MFC + # Don't forget to use FIX_PRECOMPILED_HEADER before creating the target +# SET(PCH_METHOD 1) + ELSEIF(CMAKE_GENERATOR MATCHES "Xcode") + SET(PCH_METHOD 2) + ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio") + + IF(PCH_METHOD EQUAL 1) # Auto include the precompile (useful for moc processing, since the use of # precompiled is specified at the target level # and I don't want to specifiy /F- for each moc/res/ui generated files (using Qt) @@ -200,26 +213,24 @@ MACRO(ADD_NATIVE_PRECOMPILED_HEADER _targetName _inputh _inputcpp) #also inlude ${oldProps} to have the same compile options SET_SOURCE_FILES_PROPERTIES(${_inputcpp} PROPERTIES COMPILE_FLAGS "${oldProps} /Yc\"${_inputh}\"") - ELSE(CMAKE_GENERATOR MATCHES Visual*) - IF(CMAKE_GENERATOR MATCHES Xcode) - # For Xcode, cmake needs my patch to process - # GCC_PREFIX_HEADER and GCC_PRECOMPILE_PREFIX_HEADER as target properties + ELSEIF(PCH_METHOD EQUAL 2) + # For Xcode, cmake needs my patch to process + # GCC_PREFIX_HEADER and GCC_PRECOMPILE_PREFIX_HEADER as target properties - GET_TARGET_PROPERTY(oldProps ${_targetName} COMPILE_FLAGS) - IF(${oldProps} MATCHES NOTFOUND) - SET(oldProps "") - ENDIF(${oldProps} MATCHES NOTFOUND) + GET_TARGET_PROPERTY(oldProps ${_targetName} COMPILE_FLAGS) + IF(${oldProps} MATCHES NOTFOUND) + SET(oldProps "") + ENDIF(${oldProps} MATCHES NOTFOUND) - # When buiding out of the tree, precompiled may not be located - # Use full path instead. - GET_FILENAME_COMPONENT(fullPath ${_inputh} ABSOLUTE) + # When buiding out of the tree, precompiled may not be located + # Use full path instead. + GET_FILENAME_COMPONENT(fullPath ${_inputh} ABSOLUTE) - SET_TARGET_PROPERTIES(${_targetName} PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${fullPath}") - SET_TARGET_PROPERTIES(${_targetName} PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "YES") - ELSE(CMAKE_GENERATOR MATCHES Xcode) - #Fallback to the "old" precompiled suppport - ADD_PRECOMPILED_HEADER(${_targetName} ${_inputh} ${_inputcpp}) - ENDIF(CMAKE_GENERATOR MATCHES Xcode) - ENDIF(CMAKE_GENERATOR MATCHES Visual*) + SET_TARGET_PROPERTIES(${_targetName} PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${fullPath}") + SET_TARGET_PROPERTIES(${_targetName} PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "YES") + ELSE(PCH_METHOD EQUAL 1) + #Fallback to the "old" precompiled suppport + ADD_PRECOMPILED_HEADER(${_targetName} ${_inputh} ${_inputcpp}) + ENDIF(PCH_METHOD EQUAL 1) ENDMACRO(ADD_NATIVE_PRECOMPILED_HEADER) diff --git a/code/CMakeModules/nel.cmake b/code/CMakeModules/nel.cmake index fbd70c842..e6bf57101 100644 --- a/code/CMakeModules/nel.cmake +++ b/code/CMakeModules/nel.cmake @@ -1,14 +1,53 @@ +# Force Release configuration for compiler checks +SET(CMAKE_TRY_COMPILE_CONFIGURATION "Release") + +# Force Release configuration by default +IF(NOT CMAKE_BUILD_TYPE) + SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE) +ENDIF(NOT CMAKE_BUILD_TYPE) + ### # Helper macro that generates .pc and installs it. # Argument: name - the name of the .pc package, e.g. "nel-pacs.pc" ### MACRO(NL_GEN_PC name) - IF(NOT WIN32) + IF(NOT WIN32 AND WITH_INSTALL_LIBRARIES) CONFIGURE_FILE(${name}.in "${CMAKE_CURRENT_BINARY_DIR}/${name}") - INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/${name}" DESTINATION lib/pkgconfig) - ENDIF(NOT WIN32) + IF(CMAKE_LIBRARY_ARCHITECTURE) + INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/${name}" DESTINATION lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig) + ELSE(CMAKE_LIBRARY_ARCHITECTURE) + INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/${name}" DESTINATION lib/pkgconfig) + ENDIF(CMAKE_LIBRARY_ARCHITECTURE) + ENDIF(NOT WIN32 AND WITH_INSTALL_LIBRARIES) ENDMACRO(NL_GEN_PC) +### +# Helper macro that generates revision.h from revision.h.in +### +MACRO(NL_GEN_REVISION_H) + IF(EXISTS ${CMAKE_SOURCE_DIR}/revision.h.in) + INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}) + ADD_DEFINITIONS(-DHAVE_REVISION_H) + SET(HAVE_REVISION_H ON) + + # a custom target that is always built + ADD_CUSTOM_TARGET(revision ALL + DEPENDS ${CMAKE_BINARY_DIR}/revision.h) + + # creates revision.h using cmake script + ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_BINARY_DIR}/revision.h + COMMAND ${CMAKE_COMMAND} + -DSOURCE_DIR=${CMAKE_SOURCE_DIR} + -DROOT_DIR=${CMAKE_SOURCE_DIR}/.. + -P ${CMAKE_SOURCE_DIR}/CMakeModules/GetRevision.cmake) + + # revision.h is a generated file + SET_SOURCE_FILES_PROPERTIES(${CMAKE_BINARY_DIR}/revision.h + PROPERTIES GENERATED TRUE + HEADER_FILE_ONLY TRUE) + ENDIF(EXISTS ${CMAKE_SOURCE_DIR}/revision.h.in) +ENDMACRO(NL_GEN_REVISION_H) + ### # ### @@ -37,9 +76,10 @@ ENDMACRO(NL_TARGET_DRIVER) # Argument: ### MACRO(NL_DEFAULT_PROPS name label) - IF(NOT MSVC10) - SET_TARGET_PROPERTIES(${name} PROPERTIES PROJECT_LABEL ${label}) - ENDIF(NOT MSVC10) + # Note: This is just a workaround for a CMake bug generating VS10 files with a colon in the project name. + # CMake Bug ID: http://www.cmake.org/Bug/view.php?id=11819 + STRING(REGEX REPLACE "\\:" " -" proj_label ${label}) + SET_TARGET_PROPERTIES(${name} PROPERTIES PROJECT_LABEL ${proj_label}) GET_TARGET_PROPERTY(type ${name} TYPE) IF(${type} STREQUAL SHARED_LIBRARY) # Set versions only if target is a shared library @@ -49,6 +89,15 @@ MACRO(NL_DEFAULT_PROPS name label) SET_TARGET_PROPERTIES(${name} PROPERTIES INSTALL_NAME_DIR ${NL_LIB_PREFIX}) ENDIF(NL_LIB_PREFIX) ENDIF(${type} STREQUAL SHARED_LIBRARY) + + IF(${type} STREQUAL EXECUTABLE AND WIN32) + SET_TARGET_PROPERTIES(${name} PROPERTIES + VERSION ${NL_VERSION} + SOVERSION ${NL_VERSION_MAJOR} + COMPILE_FLAGS "/GA" + LINK_FLAGS "/VERSION:${NL_VERSION}") + ENDIF(${type} STREQUAL EXECUTABLE AND WIN32) + IF(WITH_STLPORT AND WIN32) SET_TARGET_PROPERTIES(${name} PROPERTIES COMPILE_FLAGS "/X") ENDIF(WITH_STLPORT AND WIN32) @@ -149,7 +198,7 @@ Remove the CMakeCache.txt file and try again from another folder, e.g.: rm CMakeCache.txt mkdir cmake cd cmake - cmake -G \"Unix Makefiles\" .. + cmake .. ") ENDIF(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) @@ -171,6 +220,13 @@ MACRO(NL_SETUP_DEFAULT_OPTIONS) OPTION(WITH_STATIC "With static libraries." OFF) ENDIF(WIN32) OPTION(WITH_STATIC_DRIVERS "With static drivers." OFF) + IF(WIN32) + OPTION(WITH_EXTERNAL "With provided external." ON ) + ELSE(WIN32) + OPTION(WITH_EXTERNAL "With provided external." OFF) + ENDIF(WIN32) + OPTION(WITH_STATIC_EXTERNAL "With static external libraries" OFF) + OPTION(WITH_INSTALL_LIBRARIES "Install development files." ON ) ### # GUI toolkits @@ -187,6 +243,17 @@ MACRO(NL_SETUP_DEFAULT_OPTIONS) ### # Optional support ### + + # Check if CMake is launched from a Debian packaging script + SET(DEB_HOST_GNU_CPU $ENV{DEB_HOST_GNU_CPU}) + + # Don't strip if generating a .deb + IF(DEB_HOST_GNU_CPU) + OPTION(WITH_SYMBOLS "Keep debug symbols in binaries" ON ) + ELSE(DEB_HOST_GNU_CPU) + OPTION(WITH_SYMBOLS "Keep debug symbols in binaries" OFF) + ENDIF(DEB_HOST_GNU_CPU) + IF(WIN32) OPTION(WITH_STLPORT "With STLport support." ON ) ELSE(WIN32) @@ -195,10 +262,10 @@ MACRO(NL_SETUP_DEFAULT_OPTIONS) OPTION(BUILD_DASHBOARD "Build to the CDash dashboard" OFF) - OPTION(WITH_NEL "Build NeL (nearly always required)." ON ) - OPTION(WITH_NELNS "Build NeL Network Services." OFF) - OPTION(WITH_RYZOM "Build Ryzom Core." ON ) - OPTION(WITH_SNOWBALLS "Build Snowballs." OFF) + OPTION(WITH_NEL "Build NeL (nearly always required)." ON ) + OPTION(WITH_NELNS "Build NeL Network Services." OFF) + OPTION(WITH_RYZOM "Build Ryzom Core." ON ) + OPTION(WITH_SNOWBALLS "Build Snowballs." OFF) ENDMACRO(NL_SETUP_DEFAULT_OPTIONS) MACRO(NL_SETUP_NEL_DEFAULT_OPTIONS) @@ -288,44 +355,104 @@ MACRO(NL_SETUP_BUILD) ENDIF(CMAKE_BUILD_TYPE MATCHES "Release") ENDIF(CMAKE_BUILD_TYPE MATCHES "Debug") - # Determine target CPU -# IF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86") - IF(NOT CMAKE_SIZEOF_VOID_P) - INCLUDE (CheckTypeSize) - CHECK_TYPE_SIZE("void*" CMAKE_SIZEOF_VOID_P) - ENDIF(NOT CMAKE_SIZEOF_VOID_P) + SET(HOST_CPU ${CMAKE_SYSTEM_PROCESSOR}) - # Using 32 or 64 bits libraries - SET(TARGET_X86 1) - IF(CMAKE_SIZEOF_VOID_P EQUAL 8) - SET(ARCH "x86_64") - SET(TARGET_X64 1) - ADD_DEFINITIONS(-DHAVE_X86_64) - ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8) - SET(ARCH "x86") - ADD_DEFINITIONS(-DHAVE_X86) - ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8) -# ADD_DEFINITIONS(-DHAVE_IA64) -# ENDIF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86") + IF(HOST_CPU MATCHES "amd64") + SET(HOST_CPU "x86_64") + ELSEIF(HOST_CPU MATCHES "i.86") + SET(HOST_CPU "x86") + ENDIF(HOST_CPU MATCHES "amd64") - IF(WIN32) + # Determine target CPU + IF(NOT TARGET_CPU) + SET(TARGET_CPU $ENV{DEB_HOST_GNU_CPU}) + ENDIF(NOT TARGET_CPU) + + # If not specified, use the same CPU as host + IF(NOT TARGET_CPU) + SET(TARGET_CPU ${CMAKE_SYSTEM_PROCESSOR}) + ENDIF(NOT TARGET_CPU) + + IF(TARGET_CPU MATCHES "amd64") + SET(TARGET_CPU "x86_64") + ELSEIF(TARGET_CPU MATCHES "i.86") + SET(TARGET_CPU "x86") + ENDIF(TARGET_CPU MATCHES "amd64") + + # DEB_HOST_ARCH_ENDIAN is 'little' or 'big' + # DEB_HOST_ARCH_BITS is '32' or '64' + + # If target and host CPU are the same + IF("${HOST_CPU}" STREQUAL "${TARGET_CPU}") + # x86-compatible CPU + IF(HOST_CPU MATCHES "x86") + IF(NOT CMAKE_SIZEOF_VOID_P) + INCLUDE (CheckTypeSize) + CHECK_TYPE_SIZE("void*" CMAKE_SIZEOF_VOID_P) + ENDIF(NOT CMAKE_SIZEOF_VOID_P) + + # Using 32 or 64 bits libraries + IF(CMAKE_SIZEOF_VOID_P EQUAL 8) + SET(TARGET_CPU "x86_64") + ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8) + SET(TARGET_CPU "x86") + ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8) + ENDIF(HOST_CPU MATCHES "x86") + # TODO: add checks for ARM and PPC + ELSE("${HOST_CPU}" STREQUAL "${TARGET_CPU}") + MESSAGE(STATUS "Compiling on ${HOST_CPU} for ${TARGET_CPU}") + ENDIF("${HOST_CPU}" STREQUAL "${TARGET_CPU}") + + IF(TARGET_CPU STREQUAL "x86_64") + SET(TARGET_X64 1) + SET(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} -DHAVE_X86_64") + ELSEIF(TARGET_CPU STREQUAL "x86") + SET(TARGET_X86 1) + SET(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} -DHAVE_X86") + ENDIF(TARGET_CPU STREQUAL "x86_64") + + # Fix library paths suffixes for Debian MultiArch + SET(DEBIAN_MULTIARCH $ENV{DEB_HOST_MULTIARCH}) + + IF(DEBIAN_MULTIARCH) + SET(CMAKE_LIBRARY_ARCHITECTURE ${DEBIAN_MULTIARCH}) + ENDIF(DEBIAN_MULTIARCH) + + IF(CMAKE_LIBRARY_ARCHITECTURE) + SET(CMAKE_LIBRARY_PATH /lib/${CMAKE_LIBRARY_ARCHITECTURE} /usr/lib/${CMAKE_LIBRARY_ARCHITECTURE} ${CMAKE_LIBRARY_PATH}) + IF(TARGET_X64) + SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} /lib64 /usr/lib64) + ENDIF(TARGET_X64) + IF(TARGET_X86) + SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} /lib32 /usr/lib32) + ENDIF(TARGET_X86) + ENDIF(CMAKE_LIBRARY_ARCHITECTURE) + + IF(MSVC) IF(MSVC10) # /Ox is working with VC++ 2010, but custom optimizations don't exist SET(SPEED_OPTIMIZATIONS "/Ox /GF /GS-") # without inlining it's unusable, use custom optimizations again SET(MIN_OPTIMIZATIONS "/Od /Ob1") - ELSE(MSVC10) + ELSEIF(MSVC90) # don't use a /O[012x] flag if you want custom optimizations SET(SPEED_OPTIMIZATIONS "/Ob2 /Oi /Ot /Oy /GT /GF /GS-") # without inlining it's unusable, use custom optimizations again SET(MIN_OPTIMIZATIONS "/Ob1") + ELSEIF(MSVC80) + # don't use a /O[012x] flag if you want custom optimizations + SET(SPEED_OPTIMIZATIONS "/Ox /GF /GS-") + # without inlining it's unusable, use custom optimizations again + SET(MIN_OPTIMIZATIONS "/Od /Ob1") + ELSE(MSVC10) + MESSAGE(FATAL_ERROR "Can't determine compiler version ${MSVC_VERSION}") ENDIF(MSVC10) - SET(PLATFORM_CFLAGS "/D_CRT_SECURE_NO_WARNINGS /D_CRT_NONSTDC_NO_WARNINGS /DWIN32 /D_WINDOWS /W3 /Zi /Zm1000 /MP /Gy-") + SET(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} /D_CRT_SECURE_NO_WARNINGS /D_CRT_NONSTDC_NO_WARNINGS /DWIN32 /D_WINDOWS /W3 /Zm1000 /MP /Gy-") # Common link flags - SET(PLATFORM_LINKFLAGS "-DEBUG") - + SET(PLATFORM_LINKFLAGS "") + IF(TARGET_X64) # Fix a bug with Intellisense SET(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} /D_WIN64") @@ -339,12 +466,32 @@ MACRO(NL_SETUP_BUILD) # Exceptions are only set for C++ SET(PLATFORM_CXXFLAGS "${PLATFORM_CFLAGS} /EHa") - SET(NL_DEBUG_CFLAGS "/MDd /RTC1 /D_DEBUG ${MIN_OPTIMIZATIONS}") - SET(NL_RELEASE_CFLAGS "/MD /D NDEBUG ${SPEED_OPTIMIZATIONS}") - SET(NL_DEBUG_LINKFLAGS "/NODEFAULTLIB:msvcrt /INCREMENTAL:YES") - SET(NL_RELEASE_LINKFLAGS "/OPT:REF /OPT:ICF /INCREMENTAL:NO") - ELSE(WIN32) - SET(PLATFORM_CFLAGS "-g -pipe -ftemplate-depth-48 -D_REENTRANT -Wall -ansi -W -Wpointer-arith -Wsign-compare -Wno-deprecated-declarations -Wno-multichar -Wno-unused -fno-strict-aliasing") + IF(WITH_SYMBOLS) + SET(NL_RELEASE_CFLAGS "/Zi ${NL_RELEASE_CFLAGS}") + SET(NL_RELEASE_LINKFLAGS "/DEBUG ${NL_RELEASE_LINKFLAGS}") + ELSE(WITH_SYMBOLS) + SET(NL_RELEASE_LINKFLAGS "/RELEASE ${NL_RELEASE_LINKFLAGS}") + ENDIF(WITH_SYMBOLS) + + SET(NL_DEBUG_CFLAGS "/Zi /MDd /RTC1 /D_DEBUG ${MIN_OPTIMIZATIONS} ${NL_DEBUG_CFLAGS}") + SET(NL_RELEASE_CFLAGS "/MD /DNDEBUG ${SPEED_OPTIMIZATIONS} ${NL_RELEASE_CFLAGS}") + SET(NL_DEBUG_LINKFLAGS "/DEBUG /OPT:NOREF /OPT:NOICF /NODEFAULTLIB:msvcrt /INCREMENTAL:YES ${NL_DEBUG_LINKFLAGS}") + SET(NL_RELEASE_LINKFLAGS "/OPT:REF /OPT:ICF /INCREMENTAL:NO ${NL_RELEASE_LINKFLAGS}") + ELSE(MSVC) + IF(HOST_CPU STREQUAL "x86_64" AND TARGET_CPU STREQUAL "x86") + SET(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} -m32 -march=i686") + ENDIF(HOST_CPU STREQUAL "x86_64" AND TARGET_CPU STREQUAL "x86") + + IF(HOST_CPU STREQUAL "x86" AND TARGET_CPU STREQUAL "x86_64") + SET(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} -m64") + ENDIF(HOST_CPU STREQUAL "x86" AND TARGET_CPU STREQUAL "x86_64") + + SET(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} -D_REENTRANT -pipe -ftemplate-depth-48 -Wall -W -Wpointer-arith -Wsign-compare -Wno-deprecated-declarations -Wno-multichar -Wno-unused -fno-strict-aliasing") + + IF(NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") + SET(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} -ansi") + ENDIF(NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") + IF(WITH_COVERAGE) SET(PLATFORM_CFLAGS "-fprofile-arcs -ftest-coverage ${PLATFORM_CFLAGS}") ENDIF(WITH_COVERAGE) @@ -353,15 +500,28 @@ MACRO(NL_SETUP_BUILD) SET(PLATFORM_CFLAGS "-gdwarf-2 ${PLATFORM_CFLAGS}") ENDIF(APPLE) + # Fix "relocation R_X86_64_32 against.." error on x64 platforms + IF(TARGET_X64 AND WITH_STATIC AND NOT WITH_STATIC_DRIVERS) + SET(PLATFORM_CFLAGS "-fPIC ${PLATFORM_CFLAGS}") + ENDIF(TARGET_X64 AND WITH_STATIC AND NOT WITH_STATIC_DRIVERS) + SET(PLATFORM_CXXFLAGS ${PLATFORM_CFLAGS}) IF(NOT APPLE) - SET(PLATFORM_LINKFLAGS "-Wl,--no-undefined -Wl,--as-needed") + SET(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -Wl,--no-undefined -Wl,--as-needed") ENDIF(NOT APPLE) - SET(NL_DEBUG_CFLAGS "-DNL_DEBUG -D_DEBUG") - SET(NL_RELEASE_CFLAGS "-DNL_RELEASE -DNDEBUG -O6") - ENDIF(WIN32) + IF(WITH_SYMBOLS) + SET(NL_RELEASE_CFLAGS "${NL_RELEASE_CFLAGS} -g") + ELSE(WITH_SYMBOLS) + IF(NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") + SET(NL_RELEASE_LINKFLAGS "-Wl,-s ${NL_RELEASE_LINKFLAGS}") + ENDIF(NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") + ENDIF(WITH_SYMBOLS) + + SET(NL_DEBUG_CFLAGS "-DNL_DEBUG -D_DEBUG ${NL_DEBUG_CFLAGS}") + SET(NL_RELEASE_CFLAGS "-DNL_RELEASE -DNDEBUG -O3 ${NL_RELEASE_CFLAGS}") + ENDIF(MSVC) ENDMACRO(NL_SETUP_BUILD) MACRO(NL_SETUP_BUILD_FLAGS) @@ -425,7 +585,11 @@ MACRO(NL_SETUP_PREFIX_PATHS) IF(WIN32) SET(NL_LIB_PREFIX "../lib" CACHE PATH "Installation path for libraries.") ELSE(WIN32) - SET(NL_LIB_PREFIX "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation path for libraries.") + IF(CMAKE_LIBRARY_ARCHITECTURE) + SET(NL_LIB_PREFIX "${CMAKE_INSTALL_PREFIX}/lib/${CMAKE_LIBRARY_ARCHITECTURE}" CACHE PATH "Installation path for libraries.") + ELSE(CMAKE_LIBRARY_ARCHITECTURE) + SET(NL_LIB_PREFIX "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation path for libraries.") + ENDIF(CMAKE_LIBRARY_ARCHITECTURE) ENDIF(WIN32) ENDIF(NOT NL_LIB_PREFIX) @@ -434,7 +598,11 @@ MACRO(NL_SETUP_PREFIX_PATHS) IF(WIN32) SET(NL_DRIVER_PREFIX "../lib" CACHE PATH "Installation path for drivers.") ELSE(WIN32) - SET(NL_DRIVER_PREFIX "${CMAKE_INSTALL_PREFIX}/lib/nel" CACHE PATH "Installation path for drivers.") + IF(CMAKE_LIBRARY_ARCHITECTURE) + SET(NL_DRIVER_PREFIX "${CMAKE_INSTALL_PREFIX}/lib/${CMAKE_LIBRARY_ARCHITECTURE}/nel" CACHE PATH "Installation path for drivers.") + ELSE(CMAKE_LIBRARY_ARCHITECTURE) + SET(NL_DRIVER_PREFIX "${CMAKE_INSTALL_PREFIX}/lib/nel" CACHE PATH "Installation path for drivers.") + ENDIF(CMAKE_LIBRARY_ARCHITECTURE) ENDIF(WIN32) ENDIF(NOT NL_DRIVER_PREFIX) @@ -455,85 +623,115 @@ MACRO(RYZOM_SETUP_PREFIX_PATHS) IF(WIN32) SET(RYZOM_ETC_PREFIX "." CACHE PATH "Installation path for configurations") ELSE(WIN32) - SET(RYZOM_ETC_PREFIX "${CMAKE_INSTALL_PREFIX}/etc/ryzom" CACHE PATH "Installation path for configurations") + SET(RYZOM_ETC_PREFIX "${RYZOM_PREFIX}/etc/ryzom" CACHE PATH "Installation path for configurations") ENDIF(WIN32) ENDIF(NOT RYZOM_ETC_PREFIX) ## Allow override of install_prefix/share path. IF(NOT RYZOM_SHARE_PREFIX) IF(WIN32) - SET(RYZOM_SHARE_PREFIX "." CACHE PATH "Installation path for data.") - ELSE(WIN32) - SET(RYZOM_SHARE_PREFIX "${CMAKE_INSTALL_PREFIX}/share/ryzom" CACHE PATH "Installation path for data.") - ENDIF(WIN32) + SET(RYZOM_SHARE_PREFIX "." CACHE PATH "Installation path for data.") + ELSE(WIN32) + SET(RYZOM_SHARE_PREFIX "${RYZOM_PREFIX}/share/ryzom" CACHE PATH "Installation path for data.") + ENDIF(WIN32) ENDIF(NOT RYZOM_SHARE_PREFIX) ## Allow override of install_prefix/sbin path. IF(NOT RYZOM_SBIN_PREFIX) - IF(WIN32) - SET(RYZOM_SBIN_PREFIX "." CACHE PATH "Installation path for admin tools and services.") - ELSE(WIN32) - SET(RYZOM_SBIN_PREFIX "${CMAKE_INSTALL_PREFIX}/sbin" CACHE PATH "Installation path for admin tools and services.") - ENDIF(WIN32) + IF(WIN32) + SET(RYZOM_SBIN_PREFIX "." CACHE PATH "Installation path for admin tools and services.") + ELSE(WIN32) + SET(RYZOM_SBIN_PREFIX "${RYZOM_PREFIX}/sbin" CACHE PATH "Installation path for admin tools and services.") + ENDIF(WIN32) ENDIF(NOT RYZOM_SBIN_PREFIX) ## Allow override of install_prefix/bin path. IF(NOT RYZOM_BIN_PREFIX) IF(WIN32) - SET(RYZOM_BIN_PREFIX "." CACHE PATH "Installation path for tools and applications.") + SET(RYZOM_BIN_PREFIX "." CACHE PATH "Installation path for tools and applications.") ELSE(WIN32) - SET(RYZOM_BIN_PREFIX "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation path for tools.") + SET(RYZOM_BIN_PREFIX "${RYZOM_PREFIX}/bin" CACHE PATH "Installation path for tools.") ENDIF(WIN32) ENDIF(NOT RYZOM_BIN_PREFIX) ## Allow override of install_prefix/games path. IF(NOT RYZOM_GAMES_PREFIX) IF(WIN32) - SET(RYZOM_GAMES_PREFIX "." CACHE PATH "Installation path for tools and applications.") + SET(RYZOM_GAMES_PREFIX "." CACHE PATH "Installation path for tools and applications.") ELSE(WIN32) - SET(RYZOM_GAMES_PREFIX "${CMAKE_INSTALL_PREFIX}/games" CACHE PATH "Installation path for client.") + SET(RYZOM_GAMES_PREFIX "${RYZOM_PREFIX}/games" CACHE PATH "Installation path for client.") ENDIF(WIN32) ENDIF(NOT RYZOM_GAMES_PREFIX) ENDMACRO(RYZOM_SETUP_PREFIX_PATHS) MACRO(SETUP_EXTERNAL) + IF(WITH_EXTERNAL) + FIND_PACKAGE(External REQUIRED) + ENDIF(WITH_EXTERNAL) + IF(WIN32) FIND_PACKAGE(External REQUIRED) - INCLUDE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake) IF(MSVC10) - GET_FILENAME_COMPONENT(VC_ROOT_DIR "[HKEY_CURRENT_USER\\Software\\Microsoft\\VisualStudio\\10.0_Config;InstallDir]" ABSOLUTE) - # VC_ROOT_DIR is set to "registry" when a key is not found - IF(VC_ROOT_DIR MATCHES "registry") - GET_FILENAME_COMPONENT(VC_ROOT_DIR "[HKEY_CURRENT_USER\\Software\\Microsoft\\VCExpress\\10.0_Config;InstallDir]" ABSOLUTE) - IF(VC_ROOT_DIR MATCHES "registry") - MESSAGE(FATAL_ERROR "Unable to find VC++ 2010 directory!") - ENDIF(VC_ROOT_DIR MATCHES "registry") - ENDIF(VC_ROOT_DIR MATCHES "registry") - # convert IDE fullpath to VC++ path - STRING(REGEX REPLACE "Common7/.*" "VC" VC_DIR ${VC_ROOT_DIR}) - ELSE(MSVC10) - IF(${CMAKE_MAKE_PROGRAM} MATCHES "Common7") + IF(NOT MSVC10_REDIST_DIR) + # If you have VC++ 2010 Express, put x64/Microsoft.VC100.CRT/*.dll in ${EXTERNAL_PATH}/redist + SET(MSVC10_REDIST_DIR "${EXTERNAL_PATH}/redist") + ENDIF(NOT MSVC10_REDIST_DIR) + + IF(NOT VC_DIR) + IF(NOT VC_ROOT_DIR) + GET_FILENAME_COMPONENT(VC_ROOT_DIR "[HKEY_CURRENT_USER\\Software\\Microsoft\\VisualStudio\\10.0_Config;InstallDir]" ABSOLUTE) + # VC_ROOT_DIR is set to "registry" when a key is not found + IF(VC_ROOT_DIR MATCHES "registry") + GET_FILENAME_COMPONENT(VC_ROOT_DIR "[HKEY_CURRENT_USER\\Software\\Microsoft\\VCExpress\\10.0_Config;InstallDir]" ABSOLUTE) + IF(VC_ROOT_DIR MATCHES "registry") + FILE(TO_CMAKE_PATH $ENV{VS100COMNTOOLS} VC_ROOT_DIR) + IF(NOT VC_ROOT_DIR) + MESSAGE(FATAL_ERROR "Unable to find VC++ 2010 directory!") + ENDIF(NOT VC_ROOT_DIR) + ENDIF(VC_ROOT_DIR MATCHES "registry") + ENDIF(VC_ROOT_DIR MATCHES "registry") + ENDIF(NOT VC_ROOT_DIR) # convert IDE fullpath to VC++ path - STRING(REGEX REPLACE "Common7/.*" "VC" VC_DIR ${CMAKE_MAKE_PROGRAM}) - ELSE(${CMAKE_MAKE_PROGRAM} MATCHES "Common7") - # convert compiler fullpath to VC++ path - STRING(REGEX REPLACE "VC/bin/.+" "VC" VC_DIR ${CMAKE_CXX_COMPILER}) - ENDIF(${CMAKE_MAKE_PROGRAM} MATCHES "Common7") + STRING(REGEX REPLACE "Common7/.*" "VC" VC_DIR ${VC_ROOT_DIR}) + ENDIF(NOT VC_DIR) + ELSE(MSVC10) + IF(NOT VC_DIR) + IF(${CMAKE_MAKE_PROGRAM} MATCHES "Common7") + # convert IDE fullpath to VC++ path + STRING(REGEX REPLACE "Common7/.*" "VC" VC_DIR ${CMAKE_MAKE_PROGRAM}) + ELSE(${CMAKE_MAKE_PROGRAM} MATCHES "Common7") + # convert compiler fullpath to VC++ path + STRING(REGEX REPLACE "VC/bin/.+" "VC" VC_DIR ${CMAKE_CXX_COMPILER}) + ENDIF(${CMAKE_MAKE_PROGRAM} MATCHES "Common7") + ENDIF(NOT VC_DIR) ENDIF(MSVC10) + ELSE(WIN32) + IF(APPLE) + IF(WITH_STATIC_EXTERNAL) + SET(CMAKE_FIND_LIBRARY_SUFFIXES .a .dylib .so) + ELSE(WITH_STATIC_EXTERNAL) + SET(CMAKE_FIND_LIBRARY_SUFFIXES .dylib .so .a) + ENDIF(WITH_STATIC_EXTERNAL) + ELSE(APPLE) + IF(WITH_STATIC_EXTERNAL) + SET(CMAKE_FIND_LIBRARY_SUFFIXES .a .so) + ELSE(WITH_STATIC_EXTERNAL) + SET(CMAKE_FIND_LIBRARY_SUFFIXES .so .a) + ENDIF(WITH_STATIC_EXTERNAL) + ENDIF(APPLE) ENDIF(WIN32) IF(WITH_STLPORT) FIND_PACKAGE(STLport REQUIRED) INCLUDE_DIRECTORIES(${STLPORT_INCLUDE_DIR}) - IF(WIN32) + IF(MSVC) SET(VC_INCLUDE_DIR "${VC_DIR}/include") FIND_PACKAGE(WindowsSDK REQUIRED) # use VC++ and Windows SDK include paths INCLUDE_DIRECTORIES(${VC_INCLUDE_DIR} ${WINSDK_INCLUDE_DIR}) - ENDIF(WIN32) + ENDIF(MSVC) ENDIF(WITH_STLPORT) - ENDMACRO(SETUP_EXTERNAL) diff --git a/code/acinclude.m4 b/code/acinclude.m4 deleted file mode 100644 index 1f9286bf9..000000000 --- a/code/acinclude.m4 +++ /dev/null @@ -1,1396 +0,0 @@ -# ========================================================================= -# -# Macros used by Nevrax in configure.in files. -# -# $Id: acinclude.m4,v 1.20 2005-04-04 10:07:29 cado Exp $ -# -# ========================================================================= - -# ========================================================================= -# WARNING: The original version of this file is placed in the $CVSROOT/code -# directory. -# There is links in the $CVSROOT/code sub-directories to that file -# (ex: $CVSROOT/code/nel), so be careful of the consequences of -# any modification of that file. -# ========================================================================= - -# ========================================================================= -# Macros available in that file. -# -# -# AM_NEL_DEBUG -# -# Option: none. -# Description: manage the different debug and the release mode by setting -# correctly the CFLAGS and CXXFLAGS variables. -# -# -# AM_PATH_NEL -# -# Option: none. -# Description: check the instalation of the NeL library and set the -# CXXFLAGS and LIBS variables to use it. -# -# -# AM_PATH_STLPORT -# -# Option: none. -# Description: check the instalation of the STLPort library and set the -# CXXFLAGS and LIBS variables to use it. -# -# -# AM_PATH_OPENGL -# -# Option: "yes" if the use of the OpenGL library is mandatory. -# Description: check the instalation of the OpenGL library and set the -# OPENGL_CFLAGS and OPENGL_LIBS variables to use it. -# -# -# AM_PATH_FREETYPE -# -# Option: "yes" if the use of the Freetype library is mandatory. -# Description: check the instalation of the OpenGL library and set the -# FREETYPE_CFLAGS and FREETYPE_LIBS variables to use it. -# -# -# AM_PATH_XF86VIDMODE -# -# Option: none. -# Description: check the instalation of the OpenGL library and set the -# XF86VIDMODE_CFLAGS and XF86VIDMODE_LIBS variables to use it. -# -# -# AM_PATH_OPENAL -# -# Option: "yes" if the use of the OpenAL library is mandatory. -# Description: check the instalation of the OpenGL library and set the -# OPENAL_CFLAGS and OPENAL_LIBS variables to use it. -# -# -# AM_PATH_PYTHON -# -# Option: "yes" if the use of the Python library is mandatory. -# Description: check the instalation of the OpenGL library and set the -# PYTHON_CFLAGS and PYTHON_LIBS variables to use it. -# -# AM_PATH_CCACHE -# -# Option: none. -# Description: check the instalation of the Ccache utility. -# -# ========================================================================= - - -# ========================================================================= -# AM_NEL_DEBUG - -AC_DEFUN([AM_NEL_DEBUG], -[ - -MAX_C_OPTIMIZE="-O6" - -STL_DEBUG="-D__STL_DEBUG" - -NL_DEBUG="-DNL_DEBUG" -NL_DEBUG_FAST="-DNL_DEBUG_FAST" -NL_RELEASE_DEBUG="-DNL_RELEASE_DEBUG" -NL_RELEASE="-DNL_RELEASE_DEBUG" - -AC_ARG_WITH(debug, - [ --with-debug[=full|medium|fast] - Build a debug version (huge libraries). - Full mode set only NeL and STL debug flags. - Medium mode set NeL debug flags with inline - optimization (default mode). - Fast mode is like the Medium mode with some basic - optimization. - --without-debug Build without debugging code (default)], - [with_debug=$withval], - [with_debug=no]) - -# Build optimized or debug version ? -# First check for gcc and g++ -if test "$ac_cv_prog_gcc" = "yes" -then - DEBUG_CFLAGS="-g" - DEBUG_OPTIMIZE_CC="-O" - OPTIMIZE_CFLAGS="$MAX_C_OPTIMIZE" -else - DEBUG_CFLAGS="-g" - DEBUG_OPTIMIZE_CC="" - OPTIMIZE_CFLAGS="" -fi - -if test "$ac_cv_prog_cxx_g" = "yes" -then - DEBUG_CXXFLAGS="-g" - DEBUG_OPTIMIZE_CXX="-O" - OPTIMIZE_CXXFLAGS="-O3" - OPTIMIZE_INLINE_CXXFLAGS="-finline-functions" -else - DEBUG_CXXFLAGS="-g" - DEBUG_OPTIMIZE_CXX="" - OPTIMIZE_CXXFLAGS="" - OPTIMIZE_INLINE_CXXFLAGS="" -fi - -if test "$with_debug" = "yes" -o "$with_debug" = "medium" -then - # Medium debug. Inline optimization - CFLAGS="$DEBUG_CFLAGS $OPTIMIZE_INLINE_CFLAGS $NL_DEBUG $NL_DEBUG_FAST $CFLAGS" - CXXFLAGS="$DEBUG_CXXFLAGS $OPTIMIZE_INLINE_CXXFLAGS $NL_DEBUG $NL_DEBUG_FAST $CXXFLAGS" -else - if test "$with_debug" = "full" - then - # Full debug. Very slow in some cases - CFLAGS="$DEBUG_CFLAGS $NL_DEBUG $STL_DEBUG $CFLAGS" - CXXFLAGS="$DEBUG_CXXFLAGS $NL_DEBUG $STL_DEBUG $CXXFLAGS" - else - if test "$with_debug" = "fast" - then - # Fast debug. - CFLAGS="$DEBUG_CFLAGS $DEBUG_OPTIMIZE_CC $OPTIMIZE_INLINE_CFLAGS $NL_DEBUG $CFLAGS" - CXXFLAGS="$DEBUG_CXXFLAGS $DEBUG_OPTIMIZE_CXX $OPTIMIZE_INLINE_CXXFLAGS $NL_DEBUG $CXXFLAGS" - else - # Optimized version. No debug - CFLAGS="$OPTIMIZE_CFLAGS $NL_RELEASE_DEBUG $CFLAGS" - CXXFLAGS="$OPTIMIZE_CXXFLAGS $NL_RELEASE_DEBUG $CXXFLAGS" - fi - fi -fi - -# AC_MSG_RESULT([CFLAGS = $CFLAGS]) -# AC_MSG_RESULT([CXXGLAGS = $CXXFLAGS]) - -]) - - -# ========================================================================= -# MY_NEL_HEADER_CHK : NeL header files checking macros - -AC_DEFUN([MY_NEL_HEADER_CHK], -[ AC_REQUIRE_CPP() - -chk_message_obj="$1" -header="$2" -macro="$3" -is_mandatory="$4" - -if test $is_mandatory = "yes" -then - - _CPPFLAGS="$CPPFLAGS" - - CPPFLAGS="$CXXFLAGS $NEL_CFLAGS" - - AC_MSG_CHECKING(for $header) - - AC_EGREP_CPP( yo_header, -[#include <$header> -#ifdef $macro - yo_header -#endif], - have_header="yes", - have_header="no") - - CPPFLAGS="$_CPPFLAGS" - - if test "$have_header" = "yes" - then - AC_MSG_RESULT(yes) - else - if test "$is_mandatory" = "yes" - then - AC_MSG_ERROR([$chk_message_obj must be installed (http://www.nevrax.org).]) - else - AC_MSG_RESULT(no) - fi - fi -fi - - -]) - - -# ========================================================================= -# MY_NEL_LIB_CHK : NeL library checking macros - -AC_DEFUN([MY_NEL_LIB_CHK], -[ AC_REQUIRE_CPP() - -chk_message_obj="$1" -nel_test_lib="$2" -is_mandatory="$3" - -if test $is_mandatory = "yes" -then - - AC_CHECK_LIB($nel_test_lib, main,,[AC_MSG_ERROR([$chk_message_obj must be installed (http://www.nevrax.org).])]) -fi -]) - - -# ========================================================================= -# AM_PATH_NEL : NeL checking macros -AC_DEFUN([AM_PATH_NEL], -[ AC_REQUIRE_CPP() - -AC_ARG_WITH( nel, - [ --with-nel= path to the NeL install files directory. - e.g. /usr/local/nel]) - -AC_ARG_WITH( nel-include, - [ --with-nel-include= - path to the NeL header files directory. - e.g. /usr/local/nel/include]) - -AC_ARG_WITH( nel-lib, - [ --with-nel-lib= - path to the NeL library files directory. - e.g. /usr/local/nel/lib]) - - -nelmisc_is_mandatory="$1" -nelnet_is_mandatory="$2" -nel3d_is_mandatory="$3" -nelpacs_is_mandatory="$4" -nelsound_is_mandatory="$5" -nelai_is_mandatory="$6" -nelgeorges_is_mandatory="$7" - -# Check for nel-config -AC_PATH_PROG(NEL_CONFIG, nel-config, no) - -# -# Configure options (--with-nel*) have precendence -# over nel-config only set variables if they are not -# specified -# -if test "$NEL_CONFIG" != "no" -then - if test -z "$with_nel" -a -z "$with_nel_include" - then - CXXFLAGS="$CXXFLAGS `nel-config --cflags`" - fi - - if test -z "$with_nel" -a -z "$with_nel_lib" - then - LDFLAGS="`nel-config --ldflags` $LDFLAGS" - fi -fi - -# -# Set nel_libraries and nel_includes according to -# user specification (--with-nel*) if any. -# --with-nel-include and --with-nel-lib have precendence -# over --with-nel -# -if test "$with_nel" = "no" -then - # The user explicitly disabled the use of the NeL - AC_MSG_ERROR([NeL is mandatory: do not specify --without-nel]) -else - if test "$with_nel" -a "$with_nel" != "yes" - then - nel_includes="$with_nel/include" - nel_libraries="$with_nel/lib" - fi -fi - -if test "$with_nel_include" -then - nel_includes="$with_nel_include" -fi - -if test "$with_nel_lib" -then - nel_libraries="$with_nel_lib" -fi - -# -# Set compilation variables -# -if test "$nel_includes" -then - CXXFLAGS="$CXXFLAGS -I$nel_includes" -fi - -if test "$nel_libraries" -then - LDFLAGS="-L$nel_libraries $LDFLAGS" -fi - -# -# Collect headers information and bark if missing and -# mandatory -# - -MY_NEL_HEADER_CHK([NeL Misc], [nel/misc/types_nl.h], [NL_TYPES_H], $nelmisc_is_mandatory) -MY_NEL_HEADER_CHK([NeL Network], [nel/net/sock.h], [NL_SOCK_H], $nelnet_is_mandatory) -MY_NEL_HEADER_CHK([NeL 3D], [nel/3d/u_camera.h], [NL_U_CAMERA_H], $nel3d_is_mandatory) -MY_NEL_HEADER_CHK([NeL PACS], [nel/pacs/u_global_position.h], [NL_U_GLOBAL_POSITION_H], $nelpacs_is_mandatory) -MY_NEL_HEADER_CHK([NeL Sound], [nel/sound/u_source.h], [NL_U_SOURCE_H], $nelsound_is_mandatory) -MY_NEL_HEADER_CHK([NeL AI], [nel/ai/nl_ai.h], [_IA_NEL_H], $nelai_is_mandatory) -MY_NEL_HEADER_CHK([NeL Georges], [nel/georges/common.h], [NLGEORGES_COMMON_H], $nelgeorges_is_mandatory) - -# -# Collect libraries information and bark if missing and -# mandatory -# - -MY_NEL_LIB_CHK([NeL Misc], [nelmisc], $nelmisc_is_mandatory) -MY_NEL_LIB_CHK([NeL Network], [nelnet], $nelnet_is_mandatory) -MY_NEL_LIB_CHK([NeL 3D], [nel3d], $nel3d_is_mandatory) -MY_NEL_LIB_CHK([NeL PACS], [nelpacs], $nelpacs_is_mandatory) -MY_NEL_LIB_CHK([NeL Sound], [nelsnd], $nelsound_is_mandatory) -MY_NEL_LIB_CHK([NeL AI], [nelai], $nelai_is_mandatory) -MY_NEL_LIB_CHK([NeL Georges], [nelgeorges], $nelgeorges_is_mandatory) - -]) - - -# ========================================================================= -# AM_PATH_STLPORT : STLPort checking macros - -AC_DEFUN([AM_PATH_STLPORT], -[ AC_REQUIRE_CPP() - -AC_ARG_WITH( stlport, - [ --with-stlport= path to the STLPort install files directory. - e.g. /usr/local/stlport]) - -AC_ARG_WITH( stlport-include, - [ --with-stlport-include= - path to the STLPort header files directory. - e.g. /usr/local/stlport/stlport]) - -AC_ARG_WITH( stlport-lib, - [ --with-stlport-lib= - path to the STLPort library files directory. - e.g. /usr/local/stlport/lib]) - -if test "$with_debug" = "full" -then - stlport_lib="stlport_gcc_debug" -else - stlport_lib="stlport_gcc" -fi - -if test "$with_debug" = "full" -then - stlport_lib2="stlport_gcc_debug" -else - stlport_lib2="stlport_gcc" -fi - -if test "$with_stlport" = no -then - # The user explicitly disabled the use of the STLPorts - AC_MSG_ERROR([STLPort is mandatory: do not specify --without-stlport]) -else - stlport_includes="/usr/include/stlport" - if test "$with_stlport" -a "$with_stlport" != yes - then - stlport_includes="$with_stlport/stlport" - stlport_libraries="$with_stlport/lib" - - if test ! -d "$stlport_includes" - then - stlport_includes="$with_stlport/include/stlport" - fi - fi -fi - -if test "$with_stlport_include" -then - stlport_includes="$with_stlport_include" -fi - -if test "$with_stlport_lib" -then - stlport_libraries="$with_stlport_lib" -fi - -# Check for the 'pthread' library. SLTPort needs it. -AC_CHECK_LIB(pthread, main, , [AC_MSG_ERROR([cannot find the pthread library.])]) -AC_CHECK_LIB(dl, dlopen, , [AC_MSG_ERROR([cannot find the dl library.])]) - -AC_LANG_SAVE -AC_LANG_CPLUSPLUS - -# Put STLPorts includes in CXXFLAGS -if test "$stlport_includes" -then - CXXFLAGS="$CXXFLAGS -I$stlport_includes" -fi - -# Put STLPorts libraries directory in LIBS -if test "$stlport_libraries" -then - LIBS="-L$stlport_libraries $LIBS" -else - stlport_libraries='default' -fi - -# Put STLPort GCC libraries directory in LIBS -if test "$stlport_libraries2" -then - LIBS="-L$stlport_libraries2 $LIBS" -else - stlport_libraries2='default' -fi - -# Test the headers - -AC_CHECK_HEADER(algorithm, - have_stlport_headers="yes", - have_stlport_headers="no" ) - -AC_MSG_CHECKING(for STLPort headers) - -if test "$have_stlport_headers" = "yes" -then - AC_MSG_RESULT([$stlport_includes]) -else - AC_MSG_RESULT(no) -fi - -AC_CHECK_LIB($stlport_lib, main,, have_stlport_libraries="no") - -AC_MSG_CHECKING(for STLPort library) - -if test "$have_stlport_libraries" != "no" -then - AC_MSG_RESULT([$stlport_libraries]) -else - AC_MSG_RESULT(no) -fi - -AC_CHECK_LIB($stlport_lib2, main,, have_stlport_libraries="no") - -AC_MSG_CHECKING(for STLPort GCC library) - -if test "$have_stlport_libraries2" != "no" -then - AC_MSG_RESULT([$stlport_libraries2]) -else - AC_MSG_RESULT(no) -fi - -if test "$have_stlport_headers" = "yes" && - (test "$have_stlport_libraries" != "no" || test "$have_stlport_libraries2" != "no") -then - have_stlport="yes" -else - have_stlport="no" -fi - -if test "$have_stlport" = "no" -then - AC_MSG_ERROR([STLPort must be installed (http://www.stlport.org).]) -fi - -AC_LANG_RESTORE - -]) - - -# ========================================================================= -# AM_PATH_OPENGL : OpenGL checking macros - -AC_DEFUN([AM_PATH_OPENGL], -[ AC_MSG_CHECKING(for OpenGL headers and GL Version >= 1.2) - -is_mandatory="$1" - -AC_REQUIRE_CPP() - -AC_ARG_WITH( opengl, - [ --with-opengl= path to the OpenGL install files directory. - e.g. /usr/local]) - -AC_ARG_WITH( opengl-include, - [ --with-opengl-include= - path to the OpenGL header files directory. - e.g. /usr/local/include]) - -AC_ARG_WITH( opengl-lib, - [ --with-opengl-lib= - path to the OpenGL library files directory. - e.g. /usr/local/lib]) - -opengl_lib="GL" - -if test "$with_opengl" -then - opengl_includes="$with_opengl/include" - opengl_libraries="$with_opengl/lib" -fi - -if test "$with_opengl_include" -then - opengl_includes="$with_opengl_include" -fi - -if test "$with_opengl_lib" -then - opengl_libraries="$with_opengl_lib" -fi - -# Set OPENGL_CFLAGS -if test "$opengl_includes" -then - OPENGL_CFLAGS="-I$opengl_includes" -fi - -# Set OPENGL_LIBS -if test "$opengl_libraries" -then - OPENGL_LIBS="-L$opengl_libraries" -fi -OPENGL_LIBS="$OPENGL_LIBS -l$opengl_lib" - -# Test the headers -_CPPFLAGS="$CPPFLAGS" - -CPPFLAGS="$CXXFLAGS $OPENGL_CFLAGS" - -AC_EGREP_CPP( yo_opengl, -[#include -#if defined(GL_VERSION_1_2) - yo_opengl -#endif], - have_opengl_headers="yes", - have_opengl_headers="no" ) - -if test "$have_opengl_headers" = "yes" -then - if test "$opengl_includes" - then - AC_MSG_RESULT([$opengl_includes]) - else - AC_MSG_RESULT(yes) - fi -else - AC_MSG_RESULT(no) -fi - -# Checking the GLEXT version >= 7 -AC_MSG_CHECKING(for and GLEXT version >= 7) - -AC_EGREP_CPP( yo_glext_version, -[#include -#ifdef GL_GLEXT_VERSION -#if GL_GLEXT_VERSION >= 7 - yo_glext_version -#endif -#endif], - have_glext="yes", - have_glext="no" ) - -if test "$have_glext" = "yes" -then - AC_MSG_RESULT(yes) -else - AC_MSG_RESULT([no, can be downloaded from http://oss.sgi.com/projects/ogl-sample/ABI/]) -fi - -# Test the libraries -AC_MSG_CHECKING(for OpenGL libraries) - -CPPFLAGS="$CXXFLAGS $OPENGL_LIBS" - -AC_TRY_LINK( , , have_opengl_libraries="yes", have_opengl_libraries="no") - -CPPFLAGS="$_CPPFLAGS" - -if test "$have_opengl_libraries" = "yes" -then - if test "$opengl_libraries" - then - AC_MSG_RESULT([$opengl_libraries]) - else - AC_MSG_RESULT(yes) - fi -else - AC_MSG_RESULT(no) -fi - -opengl_libraries="$opengl_libraries" - -if test "$have_opengl_headers" = "yes" \ - -a "$have_glext" = "yes" \ - -a "$have_opengl_libraries" = "yes" -then - have_opengl="yes" -else - have_opengl="no" -fi - -if test "$have_opengl" = "no" -a "$is_mandatory" = "yes" -then - AC_MSG_ERROR([OpenGL >= 1.2 must be installed (http://www.mesa3d.org)]) -fi - -AC_SUBST(OPENGL_CFLAGS) -AC_SUBST(OPENGL_LIBS) - -]) - - -# ========================================================================= -# AM_PATH_FREETYPE : FreeType checking macros - -AC_DEFUN([AM_PATH_FREETYPE], -[ is_mandatory="$1" - -AC_REQUIRE_CPP() - -AC_ARG_WITH( freetype, - [ --with-freetype= path to the FreeType install files directory. - e.g. /usr/local/freetype]) - -AC_ARG_WITH( freetype-include, - [ --with-freetype-include= - path to the FreeType header files directory. - e.g. /usr/local/freetype/include]) - -AC_ARG_WITH( freetype-lib, - [ --with-freetype-lib= - path to the FreeType library files directory. - e.g. /usr/local/freetype/lib]) - -freetype_lib="freetype" - - -AC_PATH_PROG(FREETYPE_CONFIG, freetype-config, no) - -if test "$FREETYPE_CONFIG" = "no" -then - have_freetype_config="no" -else - FREETYPE_CFLAGS=`freetype-config --cflags` - FREETYPE_LIBS=`freetype-config --libs` - have_freetype_config="yes" -fi - -if test "$with_freetype" -then - freetype_includes="$with_freetype/include" - freetype_libraries="$with_freetype/lib" -fi - -if test "$with_freetype_include" -then - freetype_includes="$with_freetype_include" -fi - -if test "$with_freetype_lib" -then - freetype_libraries="$with_freetype_lib" -fi - -if test "$freetype_includes" -then - FREETYPE_CFLAGS="-I$freetype_includes" -fi - -# Checking the FreeType 2 instalation -_CPPFLAGS="$CPPFLAGS" -CPPFLAGS=" $FREETYPE_CFLAGS $CXXFLAGS" - -AC_MSG_CHECKING(for FreeType version = 2) - -AC_EGREP_CPP( yo_freetype2, -[#include -#if FREETYPE_MAJOR == 2 - yo_freetype2 -#endif], - have_freetype2="yes", - have_freetype2="no") - -if test "$have_freetype2" = "yes" -then - AC_MSG_RESULT(yes) -else - AC_MSG_RESULT(no) -fi - -# Test the libraries -AC_MSG_CHECKING(for FreeType libraries) - -if test $freetype_libraries -then - FREETYPE_LIBS="-L$freetype_libraries -l$freetype_lib" -fi - -CPPFLAGS="$FREETYPE_LIBS $CXXFLAGS" - -AC_TRY_LINK( , , have_freetype_libraries="yes", have_freetype_libraries="no") - -CPPFLAGS="$_CPPFLAGS" - -if test "$have_freetype_libraries" = "yes" -then - if test "$freetype_libraries" - then - AC_MSG_RESULT([$freetype_libraries]) - else - AC_MSG_RESULT(yes) - fi -else - AC_MSG_RESULT(no) -fi - -if test "$have_freetype2" = "yes" && test "$have_freetype_libraries" = "yes" -then - have_freetype="yes" -else - have_freetype="no" -fi - -if test "$have_freetype" = "no" && test "$is_mandatory" = "yes" -then - AC_MSG_ERROR([FreeType 2 must be installed (http://freetype.sourceforge.net)]) -fi - -AC_SUBST(FREETYPE_CFLAGS) -AC_SUBST(FREETYPE_LIBS) - -]) - - -# ========================================================================= -# AM_PATH_XF86VIDMODE : XF86VidMode checking macros - -AC_DEFUN([AM_PATH_XF86VIDMODE], -[ AC_MSG_CHECKING(for XF86VidMode extension) - -AC_REQUIRE_CPP() - -AC_ARG_WITH( xf86vidmode-lib, - [ --with-xf86vidmode-lib= - path to the XF86VidMode library. - e.g. /usr/X11R6/lib] ) - -xf86vidmode_lib="Xxf86vm" - -if test "$with_xf86vidmode_lib" = no -then - # The user explicitly disabled the use of XF86VidMode - have_xf86vidmode="disabled" - AC_MSG_RESULT(disabled) -else - if test "$with_xf86vidmode_lib" - then - xf86vidmode_libraries="$with_xf86vidmode_lib" - fi - - XF86VIDMODE_CFLAGS="-DXF86VIDMODE" -fi - -if test -z "$have_xf86vidmode" -# -a "$with_xf86vidmode_lib" -then - if test "$xf86vidmode_libraries" - then - XF86VIDMODE_LIBS="-L$xf86vidmode_libraries" - fi - - XF86VIDMODE_LIBS="$XF86VIDMODE_LIBS -l$xf86vidmode_lib" - - _CPPFLAGS="$CPPFLAGS" - - CPPFLAGS="$CXXFLAGS $XF86VIDMODE_LIBS" - - AC_TRY_LINK( , , have_xf86vidmode_libraries="yes", have_xf86vidmode_libraries="no") - - CPPFLAGS="$_CPPFLAGS" - - if test "$have_xf86vidmode_libraries" = "yes" - then - have_xf86vidmode="yes" - if test "$xf86vidmode_libraries" - then - AC_MSG_RESULT($xf86vidmode_libraries) - else - AC_MSG_RESULT(yes) - fi - else - have_xf86vidmode="no" - AC_MSG_RESULT(no, no fullscreen support available.) - fi - - xf86vidmode_libraries="$xf86vidmode_libraries" - -fi - -AC_SUBST(XF86VIDMODE_CFLAGS) -AC_SUBST(XF86VIDMODE_LIBS) - -]) - - -# ========================================================================= -# AM_PATH_OPENAL : OpenAL checking macros - -AC_DEFUN([AM_PATH_OPENAL], -[ is_mandatory="$1" - -AC_REQUIRE_CPP() - -# Get from the user option the path to the OpenAL files location -AC_ARG_WITH( openal, - [ --with-openal= path to the OpenAL install files directory. - e.g. /usr/local]) - -AC_ARG_WITH( openal-include, - [ --with-openal-include= - path to the OpenAL header files directory. - e.g. /usr/local/include]) - -AC_ARG_WITH( openal-lib, - [ --with-openal-lib= - path to the OpenAL library files directory. - e.g. /usr/local/lib]) - -openal_lib="openal" - -if test $with_openal -then - openal_includes="$with_openal/include" - openal_libraries="$with_openal/lib" -fi - -if test "$with_openal_include" -then - openal_includes="$with_openal_include" -fi - -if test "$with_openal_lib" -then - openal_libraries="$with_openal_lib" -fi - - -# Set OPENAL_CFLAGS -if test "$openal_includes" -then - OPENAL_CFLAGS="-I$openal_includes" -fi - -# Set OPENAL_LIBS -if test "$openal_libraries" -then - OPENAL_LIBS="-L$openal_libraries" -fi -OPENAL_LIBS="$OPENAL_LIBS -l$openal_lib" - -_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CXXFLAGS $OPENAL_CFLAGS" - -AC_MSG_CHECKING(for OpenAL headers) -AC_EGREP_CPP( yo_openal, -[#include -#ifdef AL_VERSION - yo_openal -#endif], - have_openal_headers="yes", - have_openal_headers="no" ) - -if test "$have_openal_headers" = "yes" -then - if test "$openal_includes" - then - AC_MSG_RESULT([$openal_includes]) - else - AC_MSG_RESULT(yes) - fi -else - AC_MSG_RESULT(no) -fi - -# Test the libraries -AC_MSG_CHECKING(for OpenAL libraries) - -CPPFLAGS="$CXXFLAGS $OPENAL_LIBS" - -AC_TRY_LINK( , , have_openal_libraries="yes", have_openal_libraries="no") - -CPPFLAGS="$_CPPFLAGS" - -if test "$have_openal_libraries" = "yes" -then - if test "$openal_libraries" - then - AC_MSG_RESULT([$openal_libraries]) - else - AC_MSG_RESULT(yes) - fi -else - AC_MSG_RESULT(no) -fi - -openal_libraries="$openal_libraries" - -if test "$have_openal_headers" = "yes" \ - && test "$have_openal_libraries" = "yes" -then - have_openal="yes" -else - have_openal="no" -fi - -if test "$have_openal" = "no" -a "$is_mandatory" = "yes" -then - AC_MSG_ERROR([OpenAL is needed to compile NeL (http://www.openal.org).]) -fi - -AC_SUBST(OPENAL_CFLAGS) -AC_SUBST(OPENAL_LIBS) - - -]) - - -# ========================================================================= -# AM_PATH_PYTHON : Python checking macros - -AC_DEFUN([AM_PATH_PYTHON], -[ python_version_required="$1" - -is_mandatory="$2" - -AC_REQUIRE_CPP() - -# Get from the user option the path to the Python files location -AC_ARG_WITH( python, - [ --with-python= path to the Python prefix installation directory. - e.g. /usr/local], - [ PYTHON_PREFIX=$with_python ] -) - -AC_ARG_WITH( python-version, - [ --with-python-version= - Python version to use, e.g. 1.5], - [ PYTHON_VERSION=$with_python_version ] -) - -if test ! "$PYTHON_PREFIX" = "" -then - PATH="$PYTHON_PREFIX/bin:$PATH" -fi - -if test ! "$PYTHON_VERSION" = "" -then - PYTHON_EXEC="python$PYTHON_VERSION" -else - PYTHON_EXEC="python python2.1 python2.0 python1.5" -fi - -AC_PATH_PROGS(PYTHON, $PYTHON_EXEC, no, $PATH) - -if test "$PYTHON" != "no" -then - PYTHON_PREFIX=`$PYTHON -c 'import sys; print "%s" % (sys.prefix)'` - PYTHON_VERSION=`$PYTHON -c 'import sys; print "%s" % (sys.version[[:3]])'` - - is_python_version_enough=`expr $python_version_required \<= $PYTHON_VERSION` -fi - - -if test "$PYTHON" = "no" || test "$is_python_version_enough" != "1" -then - - if test "$is_mandatory" = "yes" - then - AC_MSG_ERROR([Python $python_version_required must be installed (http://www.python.org)]) - else - have_python="no" - fi - -else - - python_includes="$PYTHON_PREFIX/include/python$PYTHON_VERSION" - python_libraries="$PYTHON_PREFIX/lib/python$PYTHON_VERSION/config" - python_lib="python$PYTHON_VERSION" - - PYTHON_CFLAGS="-I$python_includes" - PYTHON_LIBS="-L$python_libraries -l$python_lib" - - _CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CXXFLAGS ${PYTHON_CFLAGS}" - - # Test the headers - AC_MSG_CHECKING(for Python headers) - - AC_EGREP_CPP( yo_python, - [#include - yo_python - ], - have_python_headers="yes", - have_python_headers="no" ) - - if test "$have_python_headers" = "yes" - then - AC_MSG_RESULT([$python_includes]) - else - AC_MSG_RESULT(no) - fi - - # Test the libraries - AC_MSG_CHECKING(for Python libraries) - - CPPFLAGS="$CXXFLAGS $PYTHON_CFLAGS" - - AC_TRY_LINK( , , have_python_libraries="yes", have_python_libraries="no") - - CPPFLAGS="$_CPPFLAGS" - - if test "$have_python_libraries" = "yes" - then - if test "$python_libraries" - then - AC_MSG_RESULT([$python_libraries]) - else - AC_MSG_RESULT(yes) - fi - else - AC_MSG_RESULT(no) - fi - - if test "$have_python_headers" = "yes" \ - && test "$have_python_libraries" = "yes" - then - have_python="yes" - else - have_python="no" - fi - - if test "$have_python" = "no" -a "$is_mandatory" = "yes" - then - AC_MSG_ERROR([Python is needed to compile NeL (http://www.python.org).]) - fi - - AC_SUBST(PYTHON_CFLAGS) - AC_SUBST(PYTHON_LIBS) - -fi - -]) - - -# ========================================================================= -# AM_PATH_CCACHE : Ccache checking macros - -AC_DEFUN([AM_PATH_CCACHE], -[ - -AC_ARG_WITH( ccache, - [ --with-ccache use ccache for compiling.], - [ using_ccache=$with_ccache ] -) - -AC_PATH_PROG(CCACHE, ccache) -if test "$CCACHE" -a "$using_ccache" = "yes" -then - CC="ccache $CC" - CXX="ccache $CXX" -fi - -]) - -# ========================================================================= -# AM_PATH_MYSQL : MySQL library - -# AM_PATH_MYSQL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) -# Test for MYSQL, and define MYSQL_CFLAGS and MYSQL_LIBS -# -AC_DEFUN([AM_PATH_MYSQL], -[# -# Get the cflags and libraries from the mysql_config script -# -AC_ARG_WITH(mysql-prefix,[ --with-mysql-prefix=PFX Prefix where MYSQL is installed (optional)], - mysql_prefix="$withval", mysql_prefix="") -AC_ARG_WITH(mysql-exec-prefix,[ --with-mysql-exec-prefix=PFX Exec prefix where MYSQL is installed (optional)], - mysql_exec_prefix="$withval", mysql_exec_prefix="") -AC_ARG_ENABLE(mysqltest, [ --disable-mysqltest Do not try to compile and run a test MYSQL program], - , enable_mysqltest=yes) - - if test x$mysql_exec_prefix != x ; then - mysql_args="$mysql_args --exec-prefix=$mysql_exec_prefix" - if test x${MYSQL_CONFIG+set} != xset ; then - MYSQL_CONFIG=$mysql_exec_prefix/bin/mysql_config - fi - fi - if test x$mysql_prefix != x ; then - mysql_args="$mysql_args --prefix=$mysql_prefix" - if test x${MYSQL_CONFIG+set} != xset ; then - MYSQL_CONFIG=$mysql_prefix/bin/mysql_config - fi - fi - - AC_REQUIRE([AC_CANONICAL_TARGET]) - AC_PATH_PROG(MYSQL_CONFIG, mysql_config, no) - min_mysql_version=ifelse([$1], ,0.11.0,$1) - AC_MSG_CHECKING(for MYSQL - version >= $min_mysql_version) - no_mysql="" - if test "$MYSQL_CONFIG" = "no" ; then - no_mysql=yes - else - MYSQL_CFLAGS=`$MYSQL_CONFIG $mysqlconf_args --cflags | sed -e "s/'//g"` - MYSQL_LIBS=`$MYSQL_CONFIG $mysqlconf_args --libs | sed -e "s/'//g"` - - mysql_major_version=`$MYSQL_CONFIG $mysql_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` - mysql_minor_version=`$MYSQL_CONFIG $mysql_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` - mysql_micro_version=`$MYSQL_CONFIG $mysql_config_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` - if test "x$enable_mysqltest" = "xyes" ; then - ac_save_CFLAGS="$CFLAGS" - ac_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $MYSQL_CFLAGS" - LIBS="$LIBS $MYSQL_LIBS" -# -# Now check if the installed MYSQL is sufficiently new. (Also sanity -# checks the results of mysql_config to some extent -# - rm -f conf.mysqltest - AC_TRY_RUN([ -#include -#include -#include -#include - -char* -my_strdup (char *str) -{ - char *new_str; - - if (str) - { - new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char)); - strcpy (new_str, str); - } - else - new_str = NULL; - - return new_str; -} - -int main (int argc, char *argv[]) -{ - int major, minor, micro; - char *tmp_version; - - /* This hangs on some systems (?) - system ("touch conf.mysqltest"); - */ - { FILE *fp = fopen("conf.mysqltest", "a"); if ( fp ) fclose(fp); } - - /* HP/UX 9 (%@#!) writes to sscanf strings */ - tmp_version = my_strdup("$min_mysql_version"); - if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { - printf("%s, bad version string\n", "$min_mysql_version"); - exit(1); - } - - if (($mysql_major_version > major) || - (($mysql_major_version == major) && ($mysql_minor_version > minor)) || - (($mysql_major_version == major) && ($mysql_minor_version == minor) && ($mysql_micro_version >= micro))) - { - return 0; - } - else - { - printf("\n*** 'mysql_config --version' returned %d.%d.%d, but the minimum version\n", $mysql_major_version, $mysql_minor_version, $mysql_micro_version); - printf("*** of MYSQL required is %d.%d.%d. If mysql_config is correct, then it is\n", major, minor, micro); - printf("*** best to upgrade to the required version.\n"); - printf("*** If mysql_config was wrong, set the environment variable MYSQL_CONFIG\n"); - printf("*** to point to the correct copy of mysql_config, and remove the file\n"); - printf("*** config.cache before re-running configure\n"); - return 1; - } -} - -],, no_mysql=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - fi - fi - if test "x$no_mysql" = x ; then - AC_MSG_RESULT(yes) - ifelse([$2], , :, [$2]) - else - AC_MSG_RESULT(no) - if test "$MYSQL_CONFIG" = "no" ; then - echo "*** The mysql_config script installed by MYSQL could not be found" - echo "*** If MYSQL was installed in PREFIX, make sure PREFIX/bin is in" - echo "*** your path, or set the MYSQL_CONFIG environment variable to the" - echo "*** full path to mysql_config." - else - if test -f conf.mysqltest ; then - : - else - echo "*** Could not run MYSQL test program, checking why..." - CFLAGS="$CFLAGS $MYSQL_CFLAGS" - LIBS="$LIBS $MYSQL_LIBS" - AC_TRY_LINK([ -#include -#include - -int main(int argc, char *argv[]) -{ return 0; } -#undef main -#define main K_and_R_C_main -], [ return 0; ], - [ echo "*** The test program compiled, but did not run. This usually means" - echo "*** that the run-time linker is not finding MYSQL or finding the wrong" - echo "*** version of MYSQL. If it is not finding MYSQL, you'll need to set your" - echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" - echo "*** to the installed location Also, make sure you have run ldconfig if that" - echo "*** is required on your system" - echo "***" - echo "*** If you have an old version installed, it is best to remove it, although" - echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], - [ echo "*** The test program failed to compile or link. See the file config.log for the" - echo "*** exact error that occured. This usually means MYSQL was incorrectly installed" - echo "*** or that you have moved MYSQL since it was installed. In the latter case, you" - echo "*** may want to edit the mysql_config script: $MYSQL_CONFIG" ]) - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - fi - fi - MYSQL_CFLAGS="" - MYSQL_LIBS="" - ifelse([$3], , :, [$3]) - fi - AC_SUBST(MYSQL_CFLAGS) - AC_SUBST(MYSQL_LIBS) - rm -f conf.mysqltest -]) - -# ========================================================================= -# AM_PATH_FMOD : FMOD checking macros - -AC_DEFUN([AM_PATH_FMOD], -[ is_mandatory="$1" - -AC_REQUIRE_CPP() - -# Get from the user option the path to the FMOD files location -AC_ARG_WITH( fmod, - [ --with-fmod= path to the FMOD install files directory. - e.g. /usr/local]) - -AC_ARG_WITH( fmod-include, - [ --with-fmod-include= - path to the FMOD header files directory. - e.g. /usr/local/include]) - -AC_ARG_WITH( fmod-lib, - [ --with-fmod-lib= - path to the FMOD library files directory. - e.g. /usr/local/lib]) - -fmod_lib="fmod" - -if test $with_fmod -then - fmod_includes="$with_fmod/include" - fmod_libraries="$with_fmod/lib" -fi - -if test "$with_fmod_include" -then - fmod_includes="$with_fmod_include" -fi - -if test "$with_fmod_lib" -then - fmod_libraries="$with_fmod_lib" -fi - - -# Set FMOD_CFLAGS -if test "$fmod_includes" -then - FMOD_CFLAGS="-I$fmod_includes" -fi - -# Set FMOD_LIBS -if test "$fmod_libraries" -then - FMOD_LIBS="-L$fmod_libraries" -fi -FMOD_LIBS="$FMOD_LIBS -l$fmod_lib" - -_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CXXFLAGS $FMOD_CFLAGS" - -AC_MSG_CHECKING(for FMOD headers) -AC_EGREP_CPP( yo_fmod, -[#include -#ifdef FMOD_VERSION - yo_fmod -#endif], - have_fmod_headers="yes", - have_fmod_headers="no" ) - -if test "$have_fmod_headers" = "yes" -then - if test "$fmod_includes" - then - AC_MSG_RESULT([$fmod_includes]) - else - AC_MSG_RESULT(yes) - fi -else - AC_MSG_RESULT(no) -fi - -# Test the libraries -AC_MSG_CHECKING(for FMOD libraries) - -CPPFLAGS="$CXXFLAGS $FMOD_LIBS" - -AC_TRY_LINK( , , have_fmod_libraries="yes", have_fmod_libraries="no") - -CPPFLAGS="$_CPPFLAGS" - -if test "$have_fmod_libraries" = "yes" -then - if test "$fmod_libraries" - then - AC_MSG_RESULT([$fmod_libraries]) - else - AC_MSG_RESULT(yes) - fi -else - AC_MSG_RESULT(no) -fi - -fmod_libraries="$fmod_libraries" - -if test "$have_fmod_headers" = "yes" \ - && test "$have_fmod_libraries" = "yes" -then - have_fmod="yes" -else - have_fmod="no" -fi - -if test "$have_fmod" = "no" -a "$is_mandatory" = "yes" -then - AC_MSG_ERROR([FMOD is needed to compile NeL (http://www.fmod.org).]) -fi - -AC_SUBST(FMOD_CFLAGS) -AC_SUBST(FMOD_LIBS) - -]) - -# ========================================================================= -# End of file - diff --git a/code/nel/CMakeLists.txt b/code/nel/CMakeLists.txt index ead484a2d..57f7edd44 100644 --- a/code/nel/CMakeLists.txt +++ b/code/nel/CMakeLists.txt @@ -54,24 +54,27 @@ IF(WITH_GTK) FIND_PACKAGE(GTK2) ENDIF(WITH_GTK) -IF(UNIX) - SET(prefix ${CMAKE_INSTALL_PREFIX}) - SET(exec_prefix ${CMAKE_INSTALL_PREFIX}/bin) - SET(libdir ${CMAKE_INSTALL_PREFIX}/lib) - SET(includedir ${CMAKE_INSTALL_PREFIX}/include) - SET(enable_ligo ${WITH_LIGO}) - SET(enable_logic ${WITH_LOGIC}) - SET(enable_georges ${WITH_GEORGES}) - SET(enable_net ${WITH_NET}) - SET(enable_3d ${WITH_3D}) - SET(enable_pacs ${WITH_PACS}) - SET(enable_sound ${WITH_SOUND}) - CONFIGURE_FILE(nel-config.in ${CMAKE_CURRENT_BINARY_DIR}/nel-config) +IF(WITH_INSTALL_LIBRARIES) + IF(UNIX) + SET(prefix ${CMAKE_INSTALL_PREFIX}) + SET(exec_prefix ${CMAKE_INSTALL_PREFIX}/bin) + SET(libdir ${CMAKE_INSTALL_PREFIX}/lib) + SET(includedir ${CMAKE_INSTALL_PREFIX}/include) + SET(enable_ligo ${WITH_LIGO}) + SET(enable_logic ${WITH_LOGIC}) + SET(enable_georges ${WITH_GEORGES}) + SET(enable_net ${WITH_NET}) + SET(enable_3d ${WITH_3D}) + SET(enable_pacs ${WITH_PACS}) + SET(enable_sound ${WITH_SOUND}) + CONFIGURE_FILE(nel-config.in ${CMAKE_CURRENT_BINARY_DIR}/nel-config) - INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/nel-config DESTINATION bin) -ENDIF(UNIX) + INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/nel-config DESTINATION bin) + ENDIF(UNIX) + + ADD_SUBDIRECTORY(include) +ENDIF(WITH_INSTALL_LIBRARIES) -ADD_SUBDIRECTORY(include) ADD_SUBDIRECTORY(src) IF(WITH_NEL_SAMPLES) diff --git a/code/nel/Makefile.am b/code/nel/Makefile.am deleted file mode 100644 index f2af0b6d0..000000000 --- a/code/nel/Makefile.am +++ /dev/null @@ -1,46 +0,0 @@ -# -# - -MAINTAINERCLEANFILES = Makefile.in \ - configure \ - libtool \ - config.guess \ - config.sub \ - ltconfig \ - aclocal.m4 \ - config.h.in \ - install-sh \ - missing \ - mkinstalldirs \ - ltmain.sh \ - include/nelconfig.h \ - include/nelconfig.h.in \ - include/nel/nelconfig.h - -DISTCLEANFILES = include/stamp-h \ - include/stamp-h.in - -SUBDIRS = include src @TOOLS_SUBDIR@ @SAMPLE_SUBDIR@ - -bin_SCRIPTS = nel-config - -EXTRA_DIST = nel.dsw \ - nel.sln \ - nel_8.sln \ - autogen.sh \ - nel.m4 \ - automacros \ - doc \ - kdevelop \ - tools \ - samples - -dist-hook: - find $(distdir) -name CVS -print | xargs rm -fr - find $(distdir) -name .svn -print | xargs rm -fr - -m4datadir = $(datadir)/aclocal -m4data_DATA = nel.m4 - -# End of Makefile.am - diff --git a/code/nel/acinclude.m4 b/code/nel/acinclude.m4 deleted file mode 100644 index 7a6655bff..000000000 --- a/code/nel/acinclude.m4 +++ /dev/null @@ -1,1214 +0,0 @@ -# ========================================================================= -# -# Macros used by Nevrax in configure.in files. -# -# -# ========================================================================= - -# ========================================================================= -# WARNING: The original version of this file is placed in the $CVSROOT/code -# directory. -# There is links in the $CVSROOT/code sub-directories to that file -# (ex: $CVSROOT/code/nel), so be careful of the consequences of -# any modification of that file. -# ========================================================================= - -# ========================================================================= -# Macros available in that file. -# -# -# AM_NEL_DEBUG -# -# Option: none. -# Description: manage the different debug and the release mode by setting -# correctly the CFLAGS and CXXFLAGS variables. -# -# -# AM_PATH_NEL -# -# Option: none. -# Description: check the instalation of the NeL library and set the -# CXXFLAGS and LIBS variables to use it. -# -# -# AM_PATH_OPENGL -# -# Option: "yes" if the use of the OpenGL library is mandatory. -# Description: check the instalation of the OpenGL library and set the -# OPENGL_CFLAGS and OPENGL_LIBS variables to use it. -# -# -# AM_PATH_FREETYPE -# -# Option: "yes" if the use of the Freetype library is mandatory. -# Description: check the instalation of the OpenGL library and set the -# FREETYPE_CFLAGS and FREETYPE_LIBS variables to use it. -# -# -# AM_PATH_XF86VIDMODE -# -# Option: none. -# Description: check the instalation of the OpenGL library and set the -# XF86VIDMODE_CFLAGS and XF86VIDMODE_LIBS variables to use it. -# -# -# AM_PATH_OPENAL -# -# Option: "yes" if the use of the OpenAL library is mandatory. -# Description: check the instalation of the OpenGL library and set the -# OPENAL_CFLAGS and OPENAL_LIBS variables to use it. -# -# -# AM_PATH_PYTHON -# -# Option: "yes" if the use of the Python library is mandatory. -# Description: check the instalation of the OpenGL library and set the -# PYTHON_CFLAGS and PYTHON_LIBS variables to use it. -# -# ========================================================================= - - -# ========================================================================= -# AM_NEL_DEBUG - -AC_DEFUN([AM_NEL_DEBUG], -[ - -MAX_C_OPTIMIZE="-O6" - -NL_DEBUG="-DNL_DEBUG" -NL_RELEASE="-DNL_RELEASE" - -AC_ARG_WITH(debug, - [ --with-debug[=full|medium|fast] - Build a debug version (huge libraries). - Full mode set no optimization. - Medium mode set NeL debug flags with inline - optimization (default mode). - Fast mode is like the Medium mode with some basic - optimization. - --without-debug Build without debugging code (default)], - [with_debug=$withval], - [with_debug=no]) - -# Build optimized or debug version ? -# First check for gcc and g++ -if test "$ac_cv_prog_gcc" = "yes" -then - DEBUG_CFLAGS="-g -O0" - DEBUG_OPTIMIZE_CC="-O" - OPTIMIZE_CFLAGS="$MAX_C_OPTIMIZE" -else - DEBUG_CFLAGS="" - DEBUG_OPTIMIZE_CC="" - OPTIMIZE_CFLAGS="" -fi - -if test "$ac_cv_prog_cxx_g" = "yes" -then - DEBUG_CXXFLAGS="-g -O0" - DEBUG_OPTIMIZE_CXX="-O" - OPTIMIZE_CXXFLAGS="-O3" - OPTIMIZE_INLINE_CXXFLAGS="-finline-functions" -else - DEBUG_CXXFLAGS="" - DEBUG_OPTIMIZE_CXX="" - OPTIMIZE_CXXFLAGS="" - OPTIMIZE_INLINE_CXXFLAGS="" -fi - -if test "$with_debug" = "yes" -o "$with_debug" = "medium" -then - # Medium debug. Inline optimization - CFLAGS="$DEBUG_CFLAGS $OPTIMIZE_INLINE_CFLAGS $NL_DEBUG $CFLAGS" - CXXFLAGS="$DEBUG_CXXFLAGS $OPTIMIZE_INLINE_CXXFLAGS $NL_DEBUG $CXXFLAGS" -else - if test "$with_debug" = "full" - then - # Full debug. Very slow in some cases - CFLAGS="$DEBUG_CFLAGS $NL_DEBUG $CFLAGS" - CXXFLAGS="$DEBUG_CXXFLAGS $NL_DEBUG $CXXFLAGS" - else - if test "$with_debug" = "fast" - then - # Fast debug. - CFLAGS="$DEBUG_CFLAGS $DEBUG_OPTIMIZE_CC $OPTIMIZE_INLINE_CFLAGS $NL_DEBUG $CFLAGS" - CXXFLAGS="$DEBUG_CXXFLAGS $DEBUG_OPTIMIZE_CXX $OPTIMIZE_INLINE_CXXFLAGS $NL_DEBUG $CXXFLAGS" - else - # Optimized version. No debug - CFLAGS="$OPTIMIZE_CFLAGS $NL_RELEASE $CFLAGS" - CXXFLAGS="$OPTIMIZE_CXXFLAGS $NL_RELEASE $CXXFLAGS" - fi - fi -fi - -# AC_MSG_RESULT([CFLAGS = $CFLAGS]) -# AC_MSG_RESULT([CXXGLAGS = $CXXFLAGS]) - -]) - - -# ========================================================================= -# MY_NEL_HEADER_CHK : NeL header files checking macros - -AC_DEFUN([MY_NEL_HEADER_CHK], -[ AC_REQUIRE_CPP() - -chk_message_obj="$1" -header="$2" -macro="$3" -is_mandatory="$4" - -if test $is_mandatory = "yes" -then - - _CPPFLAGS="$CPPFLAGS" - - CPPFLAGS="$CXXFLAGS $NEL_CFLAGS" - - AC_MSG_CHECKING(for $header) - - AC_EGREP_CPP( yo_header, -[#include <$header> -#ifdef $macro - yo_header -#endif], - have_header="yes", - have_header="no") - - CPPFLAGS="$_CPPFLAGS" - - if test "$have_header" = "yes" - then - AC_MSG_RESULT(yes) - else - if test "$is_mandatory" = "yes" - then - AC_MSG_ERROR([$chk_message_obj must be installed (http://dev.ryzom.com).]) - else - AC_MSG_RESULT(no) - fi - fi -fi - - -]) - - -# ========================================================================= -# MY_NEL_LIB_CHK : NeL library checking macros - -AC_DEFUN([MY_NEL_LIB_CHK], -[ AC_REQUIRE_CPP() - -chk_message_obj="$1" -nel_test_lib="$2" -is_mandatory="$3" - -if test $is_mandatory = "yes" -then - - AC_CHECK_LIB($nel_test_lib, main,,[AC_MSG_ERROR([$chk_message_obj must be installed (http://dev.ryzom.com).])]) -fi -]) - - -# ========================================================================= -# AM_PATH_NEL : NeL checking macros -AC_DEFUN([AM_PATH_NEL], -[ AC_REQUIRE_CPP() - -AC_ARG_WITH( nel, - [ --with-nel= path to the NeL install files directory. - e.g. /usr/local/nel]) - -AC_ARG_WITH( nel-include, - [ --with-nel-include= - path to the NeL header files directory. - e.g. /usr/local/nel/include]) - -AC_ARG_WITH( nel-lib, - [ --with-nel-lib= - path to the NeL library files directory. - e.g. /usr/local/nel/lib]) - - -nelmisc_is_mandatory="$1" -nelnet_is_mandatory="$2" -nel3d_is_mandatory="$3" -nelpacs_is_mandatory="$4" -nelsound_is_mandatory="$5" -nelai_is_mandatory="$6" -nelgeorges_is_mandatory="$7" - -# Check for nel-config -AC_PATH_PROG(NEL_CONFIG, nel-config, no) - -# -# Configure options (--with-nel*) have precendence -# over nel-config only set variables if they are not -# specified -# -if test "$NEL_CONFIG" != "no" -then - if test -z "$with_nel" -a -z "$with_nel_include" - then - CXXFLAGS="$CXXFLAGS `nel-config --cflags`" - fi - - if test -z "$with_nel" -a -z "$with_nel_lib" - then - LDFLAGS="`nel-config --ldflags` $LDFLAGS" - fi -fi - -# -# Set nel_libraries and nel_includes according to -# user specification (--with-nel*) if any. -# --with-nel-include and --with-nel-lib have precendence -# over --with-nel -# -if test "$with_nel" = "no" -then - # The user explicitly disabled the use of the NeL - AC_MSG_ERROR([NeL is mandatory: do not specify --without-nel]) -else - if test "$with_nel" -a "$with_nel" != "yes" - then - nel_includes="$with_nel/include" - nel_libraries="$with_nel/lib" - fi -fi - -if test "$with_nel_include" -then - nel_includes="$with_nel_include" -fi - -if test "$with_nel_lib" -then - nel_libraries="$with_nel_lib" -fi - -# -# Set compilation variables -# -if test "$nel_includes" -then - CXXFLAGS="$CXXFLAGS -I$nel_includes" -fi - -if test "$nel_libraries" -then - LDFLAGS="-L$nel_libraries $LDFLAGS" -fi - -# -# Collect headers information and bark if missing and -# mandatory -# - -MY_NEL_HEADER_CHK([NeL Misc], [nel/misc/types_nl.h], [NL_TYPES_H], $nelmisc_is_mandatory) -MY_NEL_HEADER_CHK([NeL Network], [nel/net/sock.h], [NL_SOCK_H], $nelnet_is_mandatory) -MY_NEL_HEADER_CHK([NeL 3D], [nel/3d/u_camera.h], [NL_U_CAMERA_H], $nel3d_is_mandatory) -MY_NEL_HEADER_CHK([NeL PACS], [nel/pacs/u_global_position.h], [NL_U_GLOBAL_POSITION_H], $nelpacs_is_mandatory) -MY_NEL_HEADER_CHK([NeL Sound], [nel/sound/u_source.h], [NL_U_SOURCE_H], $nelsound_is_mandatory) -MY_NEL_HEADER_CHK([NeL AI], [nel/ai/nl_ai.h], [_IA_NEL_H], $nelai_is_mandatory) -MY_NEL_HEADER_CHK([NeL Georges], [nel/georges/common.h], [NLGEORGES_COMMON_H], $nelgeorges_is_mandatory) - -# -# Collect libraries information and bark if missing and -# mandatory -# - -MY_NEL_LIB_CHK([NeL Misc], [nelmisc], $nelmisc_is_mandatory) -MY_NEL_LIB_CHK([NeL Network], [nelnet], $nelnet_is_mandatory) -MY_NEL_LIB_CHK([NeL 3D], [nel3d], $nel3d_is_mandatory) -MY_NEL_LIB_CHK([NeL PACS], [nelpacs], $nelpacs_is_mandatory) -MY_NEL_LIB_CHK([NeL Sound], [nelsnd], $nelsound_is_mandatory) -MY_NEL_LIB_CHK([NeL AI], [nelai], $nelai_is_mandatory) -MY_NEL_LIB_CHK([NeL Georges], [nelgeorges], $nelgeorges_is_mandatory) - -]) - -# ========================================================================= -# AM_PATH_OPENGL : OpenGL checking macros - -AC_DEFUN([AM_PATH_OPENGL], -[ AC_MSG_CHECKING(for OpenGL headers and GL Version >= 1.2) - -is_mandatory="$1" - -AC_REQUIRE_CPP() - -AC_ARG_WITH( opengl, - [ --with-opengl= path to the OpenGL install files directory. - e.g. /usr/local]) - -AC_ARG_WITH( opengl-include, - [ --with-opengl-include= - path to the OpenGL header files directory. - e.g. /usr/local/include]) - -AC_ARG_WITH( opengl-lib, - [ --with-opengl-lib= - path to the OpenGL library files directory. - e.g. /usr/local/lib]) - -opengl_lib="GL" - -if test "$with_opengl" -then - opengl_includes="$with_opengl/include" - opengl_libraries="$with_opengl/lib" -fi - -if test "$with_opengl_include" -then - opengl_includes="$with_opengl_include" -fi - -if test "$with_opengl_lib" -then - opengl_libraries="$with_opengl_lib" -fi - -# Set OPENGL_CFLAGS -if test "$opengl_includes" -then - OPENGL_CFLAGS="-I$opengl_includes" -fi - -# Set OPENGL_LIBS -if test "$opengl_libraries" -then - OPENGL_LIBS="-L$opengl_libraries" -fi -OPENGL_LIBS="$OPENGL_LIBS -l$opengl_lib" - -# Test the headers -_CPPFLAGS="$CPPFLAGS" - -CPPFLAGS="$CXXFLAGS $OPENGL_CFLAGS" - -AC_EGREP_CPP( yo_opengl, -[#include -#if defined(GL_VERSION_1_2) - yo_opengl -#endif], - have_opengl_headers="yes", - have_opengl_headers="no" ) - -if test "$have_opengl_headers" = "yes" -then - if test "$opengl_includes" - then - AC_MSG_RESULT([$opengl_includes]) - else - AC_MSG_RESULT(yes) - fi -else - AC_MSG_RESULT(no) -fi - -# Checking the GLEXT version >= 7 -AC_MSG_CHECKING(for and GLEXT version >= 7) - -AC_EGREP_CPP( yo_glext_version, -[#include -#ifdef GL_GLEXT_VERSION -#if GL_GLEXT_VERSION >= 7 - yo_glext_version -#endif -#endif], - have_glext="yes", - have_glext="no" ) - -if test "$have_glext" = "yes" -then - AC_MSG_RESULT(yes) -else - AC_MSG_RESULT([no, can be downloaded from http://www.opengl.org/registry/]) -fi - -# Test the libraries -AC_MSG_CHECKING(for OpenGL libraries) - -CPPFLAGS="$CXXFLAGS $OPENGL_LIBS" - -AC_TRY_LINK( , , have_opengl_libraries="yes", have_opengl_libraries="no") - -CPPFLAGS="$_CPPFLAGS" - -if test "$have_opengl_libraries" = "yes" -then - if test "$opengl_libraries" - then - AC_MSG_RESULT([$opengl_libraries]) - else - AC_MSG_RESULT(yes) - fi -else - AC_MSG_RESULT(no) -fi - -opengl_libraries="$opengl_libraries" - -if test "$have_opengl_headers" = "yes" \ - -a "$have_glext" = "yes" \ - -a "$have_opengl_libraries" = "yes" -then - have_opengl="yes" -else - have_opengl="no" -fi - -if test "$have_opengl" = "no" -a "$is_mandatory" = "yes" -then - AC_MSG_ERROR([OpenGL >= 1.2 must be installed (http://www.mesa3d.org)]) -fi - -AC_SUBST(OPENGL_CFLAGS) -AC_SUBST(OPENGL_LIBS) - -]) - - -# ========================================================================= -# AM_PATH_FREETYPE : FreeType checking macros - -AC_DEFUN([AM_PATH_FREETYPE], -[ is_mandatory="$1" - -AC_REQUIRE_CPP() - -AC_ARG_WITH( freetype, - [ --with-freetype= path to the FreeType install files directory. - e.g. /usr/local/freetype]) - -AC_ARG_WITH( freetype-include, - [ --with-freetype-include= - path to the FreeType header files directory. - e.g. /usr/local/freetype/include]) - -AC_ARG_WITH( freetype-lib, - [ --with-freetype-lib= - path to the FreeType library files directory. - e.g. /usr/local/freetype/lib]) - -freetype_lib="freetype" - - -AC_PATH_PROG(FREETYPE_CONFIG, freetype-config, no) - -if test "$FREETYPE_CONFIG" = "no" -then - have_freetype_config="no" -else - FREETYPE_CFLAGS=`freetype-config --cflags` - FREETYPE_LIBS=`freetype-config --libs` - have_freetype_config="yes" -fi - -if test "$with_freetype" -then - freetype_includes="$with_freetype/include" - freetype_libraries="$with_freetype/lib" -fi - -if test "$with_freetype_include" -then - freetype_includes="$with_freetype_include" -fi - -if test "$with_freetype_lib" -then - freetype_libraries="$with_freetype_lib" -fi - -if test "$freetype_includes" -then - FREETYPE_CFLAGS="-I$freetype_includes" -fi - -# Checking the FreeType 2 instalation -_CPPFLAGS="$CPPFLAGS" -CPPFLAGS=" $FREETYPE_CFLAGS $CXXFLAGS" - -AC_MSG_CHECKING(for FreeType version = 2) - -AC_EGREP_CPP( yo_freetype2, -[#include -#if FREETYPE_MAJOR == 2 - yo_freetype2 -#endif], - have_freetype2="yes", - have_freetype2="no") - -if test "$have_freetype2" = "yes" -then - AC_MSG_RESULT(yes) -else - AC_MSG_RESULT(no) -fi - -# Test the libraries -AC_MSG_CHECKING(for FreeType libraries) - -if test $freetype_libraries -then - FREETYPE_LIBS="-L$freetype_libraries -l$freetype_lib" -fi - -CPPFLAGS="$FREETYPE_LIBS $CXXFLAGS" - -AC_TRY_LINK( , , have_freetype_libraries="yes", have_freetype_libraries="no") - -CPPFLAGS="$_CPPFLAGS" - -if test "$have_freetype_libraries" = "yes" -then - if test "$freetype_libraries" - then - AC_MSG_RESULT([$freetype_libraries]) - else - AC_MSG_RESULT(yes) - fi -else - AC_MSG_RESULT(no) -fi - -if test "$have_freetype2" = "yes" && test "$have_freetype_libraries" = "yes" -then - have_freetype="yes" -else - have_freetype="no" -fi - -if test "$have_freetype" = "no" && test "$is_mandatory" = "yes" -then - AC_MSG_ERROR([FreeType 2 must be installed (http://freetype.sourceforge.net)]) -fi - -AC_SUBST(FREETYPE_CFLAGS) -AC_SUBST(FREETYPE_LIBS) - -]) - - -# ========================================================================= -# AM_PATH_XF86VIDMODE : XF86VidMode checking macros - -AC_DEFUN([AM_PATH_XF86VIDMODE], -[ AC_MSG_CHECKING(for XF86VidMode extension) - -AC_REQUIRE_CPP() - -AC_ARG_WITH( xf86vidmode-lib, - [ --with-xf86vidmode-lib= - path to the XF86VidMode library. - e.g. /usr/X11R6/lib] ) - -xf86vidmode_lib="Xxf86vm" - -if test "$with_xf86vidmode_lib" = no -then - # The user explicitly disabled the use of XF86VidMode - have_xf86vidmode="disabled" - AC_MSG_RESULT(disabled) -else - if test "$with_xf86vidmode_lib" - then - xf86vidmode_libraries="$with_xf86vidmode_lib" - fi - - XF86VIDMODE_CFLAGS="-DXF86VIDMODE" -fi - -if test -z "$have_xf86vidmode" -# -a "$with_xf86vidmode_lib" -then - if test "$xf86vidmode_libraries" - then - XF86VIDMODE_LIBS="-L$xf86vidmode_libraries" - fi - - XF86VIDMODE_LIBS="$XF86VIDMODE_LIBS -l$xf86vidmode_lib" - - _CPPFLAGS="$CPPFLAGS" - - CPPFLAGS="$CXXFLAGS $XF86VIDMODE_LIBS" - - AC_TRY_LINK( , , have_xf86vidmode_libraries="yes", have_xf86vidmode_libraries="no") - - CPPFLAGS="$_CPPFLAGS" - - if test "$have_xf86vidmode_libraries" = "yes" - then - have_xf86vidmode="yes" - if test "$xf86vidmode_libraries" - then - AC_MSG_RESULT($xf86vidmode_libraries) - else - AC_MSG_RESULT(yes) - fi - else - have_xf86vidmode="no" - AC_MSG_RESULT(no, no fullscreen support available.) - fi - - xf86vidmode_libraries="$xf86vidmode_libraries" - -fi - -AC_SUBST(XF86VIDMODE_CFLAGS) -AC_SUBST(XF86VIDMODE_LIBS) - -]) - - -# ========================================================================= -# AM_PATH_OPENAL : OpenAL checking macros - -AC_DEFUN([AM_PATH_OPENAL], -[ is_mandatory="$1" - -AC_REQUIRE_CPP() - -# Get from the user option the path to the OpenAL files location -AC_ARG_WITH( openal, - [ --with-openal= path to the OpenAL install files directory. - e.g. /usr/local]) - -AC_ARG_WITH( openal-include, - [ --with-openal-include= - path to the OpenAL header files directory. - e.g. /usr/local/include]) - -AC_ARG_WITH( openal-lib, - [ --with-openal-lib= - path to the OpenAL library files directory. - e.g. /usr/local/lib]) - -openal_lib="openal" -alut_lib="alut" - -if test $with_openal -then - openal_includes="$with_openal/include" - openal_libraries="$with_openal/lib" -fi - -if test "$with_openal_include" -then - openal_includes="$with_openal_include" -fi - -if test "$with_openal_lib" -then - openal_libraries="$with_openal_lib" -fi - - -# Set OPENAL_CFLAGS -if test "$openal_includes" -then - OPENAL_CFLAGS="-I$openal_includes" -fi - -# Set OPENAL_LIBS -if test "$openal_libraries" -then - OPENAL_LIBS="-L$openal_libraries" -fi -OPENAL_LIBS="$OPENAL_LIBS -l$openal_lib -l$alut_lib" - -_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CXXFLAGS $OPENAL_CFLAGS" - -AC_MSG_CHECKING(for OpenAL headers) -AC_EGREP_CPP( yo_openal, -[#include -#include -#ifdef AL_VERSION - yo_openal -#endif], - have_openal_headers="yes", - have_openal_headers="no" ) - -if test "$have_openal_headers" = "yes" -then - if test "$openal_includes" - then - AC_MSG_RESULT([$openal_includes]) - else - AC_MSG_RESULT(yes) - fi -else - AC_MSG_RESULT(no) -fi - -# Test the libraries -AC_MSG_CHECKING(for OpenAL libraries) - -CPPFLAGS="$CXXFLAGS $OPENAL_LIBS" - -AC_TRY_LINK( , , have_openal_libraries="yes", have_openal_libraries="no") - -CPPFLAGS="$_CPPFLAGS" - -if test "$have_openal_libraries" = "yes" -then - if test "$openal_libraries" - then - AC_MSG_RESULT([$openal_libraries]) - else - AC_MSG_RESULT(yes) - fi -else - AC_MSG_RESULT(no) -fi - -openal_libraries="$openal_libraries" - -if test "$have_openal_headers" = "yes" \ - && test "$have_openal_libraries" = "yes" -then - have_openal="yes" -else - have_openal="no" -fi - -if test "$have_openal" = "no" -a "$is_mandatory" = "yes" -then - AC_MSG_ERROR([OpenAL is needed to compile NeL (http://www.openal.org).]) -fi - -AC_SUBST(OPENAL_CFLAGS) -AC_SUBST(OPENAL_LIBS) -AC_SUBST([have_openal]) - -]) - - -# ========================================================================= -# AM_PATH_PYTHON : Python checking macros - -AC_DEFUN([AM_PATH_PYTHON], -[ python_version_required="$1" - -is_mandatory="$2" - -AC_REQUIRE_CPP() - -# Get from the user option the path to the Python files location -AC_ARG_WITH( python, - [ --with-python= path to the Python prefix installation directory. - e.g. /usr/local], - [ PYTHON_PREFIX=$with_python ] -) - -AC_ARG_WITH( python-version, - [ --with-python-version= - Python version to use, e.g. 1.5], - [ PYTHON_VERSION=$with_python_version ] -) - -if test ! "$PYTHON_PREFIX" = "" -then - PATH="$PYTHON_PREFIX/bin:$PATH" -fi - -if test ! "$PYTHON_VERSION" = "" -then - PYTHON_EXEC="python$PYTHON_VERSION" -else - PYTHON_EXEC="python python2.1 python2.0 python1.5" -fi - -AC_PATH_PROGS(PYTHON, $PYTHON_EXEC, no, $PATH) - -if test "$PYTHON" != "no" -then - PYTHON_PREFIX=`$PYTHON -c 'import sys; print "%s" % (sys.prefix)'` - PYTHON_VERSION=`$PYTHON -c 'import sys; print "%s" % (sys.version[[:3]])'` - - is_python_version_enough=`expr $python_version_required \<= $PYTHON_VERSION` -fi - - -if test "$PYTHON" = "no" || test "$is_python_version_enough" != "1" -then - - if test "$is_mandatory" = "yes" - then - AC_MSG_ERROR([Python $python_version_required must be installed (http://www.python.org)]) - else - have_python="no" - fi - -else - - python_includes="$PYTHON_PREFIX/include/python$PYTHON_VERSION" - python_libraries="$PYTHON_PREFIX/lib/python$PYTHON_VERSION/config" - python_lib="python$PYTHON_VERSION" - - PYTHON_CFLAGS="-I$python_includes" - PYTHON_LIBS="-L$python_libraries -l$python_lib" - - _CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CXXFLAGS ${PYTHON_CFLAGS}" - - # Test the headers - AC_MSG_CHECKING(for Python headers) - - AC_EGREP_CPP( yo_python, - [#include - yo_python - ], - have_python_headers="yes", - have_python_headers="no" ) - - if test "$have_python_headers" = "yes" - then - AC_MSG_RESULT([$python_includes]) - else - AC_MSG_RESULT(no) - fi - - # Test the libraries - AC_MSG_CHECKING(for Python libraries) - - CPPFLAGS="$CXXFLAGS $PYTHON_CFLAGS" - - AC_TRY_LINK( , , have_python_libraries="yes", have_python_libraries="no") - - CPPFLAGS="$_CPPFLAGS" - - if test "$have_python_libraries" = "yes" - then - if test "$python_libraries" - then - AC_MSG_RESULT([$python_libraries]) - else - AC_MSG_RESULT(yes) - fi - else - AC_MSG_RESULT(no) - fi - - if test "$have_python_headers" = "yes" \ - && test "$have_python_libraries" = "yes" - then - have_python="yes" - else - have_python="no" - fi - - if test "$have_python" = "no" -a "$is_mandatory" = "yes" - then - AC_MSG_ERROR([Python is needed to compile NeL (http://www.python.org).]) - fi - - AC_SUBST(PYTHON_CFLAGS) - AC_SUBST(PYTHON_LIBS) - -fi - -]) - -# ========================================================================= -# AM_PATH_MYSQL : MySQL library - -# AM_PATH_MYSQL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) -# Test for MYSQL, and define MYSQL_CFLAGS and MYSQL_LIBS -# -AC_DEFUN([AM_PATH_MYSQL], -[# -# Get the cflags and libraries from the mysql_config script -# -AC_ARG_WITH(mysql-prefix,[ --with-mysql-prefix=PFX Prefix where MYSQL is installed (optional)], - mysql_prefix="$withval", mysql_prefix="") -AC_ARG_WITH(mysql-exec-prefix,[ --with-mysql-exec-prefix=PFX Exec prefix where MYSQL is installed (optional)], - mysql_exec_prefix="$withval", mysql_exec_prefix="") -AC_ARG_ENABLE(mysqltest, [ --disable-mysqltest Do not try to compile and run a test MYSQL program], - , enable_mysqltest=yes) - - if test x$mysql_exec_prefix != x ; then - mysql_args="$mysql_args --exec-prefix=$mysql_exec_prefix" - if test x${MYSQL_CONFIG+set} != xset ; then - MYSQL_CONFIG=$mysql_exec_prefix/bin/mysql_config - fi - fi - if test x$mysql_prefix != x ; then - mysql_args="$mysql_args --prefix=$mysql_prefix" - if test x${MYSQL_CONFIG+set} != xset ; then - MYSQL_CONFIG=$mysql_prefix/bin/mysql_config - fi - fi - - AC_REQUIRE([AC_CANONICAL_TARGET]) - AC_PATH_PROG(MYSQL_CONFIG, mysql_config, no) - min_mysql_version=ifelse([$1], ,0.11.0,$1) - AC_MSG_CHECKING(for MYSQL - version >= $min_mysql_version) - no_mysql="" - if test "$MYSQL_CONFIG" = "no" ; then - no_mysql=yes - else - MYSQL_CFLAGS=`$MYSQL_CONFIG $mysqlconf_args --cflags | sed -e "s/'//g"` - MYSQL_LIBS=`$MYSQL_CONFIG $mysqlconf_args --libs | sed -e "s/'//g"` - - mysql_major_version=`$MYSQL_CONFIG $mysql_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` - mysql_minor_version=`$MYSQL_CONFIG $mysql_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` - mysql_micro_version=`$MYSQL_CONFIG $mysql_config_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` - if test "x$enable_mysqltest" = "xyes" ; then - ac_save_CFLAGS="$CFLAGS" - ac_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $MYSQL_CFLAGS" - LIBS="$LIBS $MYSQL_LIBS" -# -# Now check if the installed MYSQL is sufficiently new. (Also sanity -# checks the results of mysql_config to some extent -# - rm -f conf.mysqltest - AC_TRY_RUN([ -#include -#include -#include -#include - -char* -my_strdup (char *str) -{ - char *new_str; - - if (str) - { - new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char)); - strcpy (new_str, str); - } - else - new_str = NULL; - - return new_str; -} - -int main (int argc, char *argv[]) -{ - int major, minor, micro; - char *tmp_version; - - /* This hangs on some systems (?) - system ("touch conf.mysqltest"); - */ - { FILE *fp = fopen("conf.mysqltest", "a"); if ( fp ) fclose(fp); } - - /* HP/UX 9 (%@#!) writes to sscanf strings */ - tmp_version = my_strdup("$min_mysql_version"); - if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { - printf("%s, bad version string\n", "$min_mysql_version"); - exit(1); - } - - if (($mysql_major_version > major) || - (($mysql_major_version == major) && ($mysql_minor_version > minor)) || - (($mysql_major_version == major) && ($mysql_minor_version == minor) && ($mysql_micro_version >= micro))) - { - return 0; - } - else - { - printf("\n*** 'mysql_config --version' returned %d.%d.%d, but the minimum version\n", $mysql_major_version, $mysql_minor_version, $mysql_micro_version); - printf("*** of MYSQL required is %d.%d.%d. If mysql_config is correct, then it is\n", major, minor, micro); - printf("*** best to upgrade to the required version.\n"); - printf("*** If mysql_config was wrong, set the environment variable MYSQL_CONFIG\n"); - printf("*** to point to the correct copy of mysql_config, and remove the file\n"); - printf("*** config.cache before re-running configure\n"); - return 1; - } -} - -],, no_mysql=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - fi - fi - if test "x$no_mysql" = x ; then - AC_MSG_RESULT(yes) - ifelse([$2], , :, [$2]) - else - AC_MSG_RESULT(no) - if test "$MYSQL_CONFIG" = "no" ; then - echo "*** The mysql_config script installed by MYSQL could not be found" - echo "*** If MYSQL was installed in PREFIX, make sure PREFIX/bin is in" - echo "*** your path, or set the MYSQL_CONFIG environment variable to the" - echo "*** full path to mysql_config." - else - if test -f conf.mysqltest ; then - : - else - echo "*** Could not run MYSQL test program, checking why..." - CFLAGS="$CFLAGS $MYSQL_CFLAGS" - LIBS="$LIBS $MYSQL_LIBS" - AC_TRY_LINK([ -#include -#include - -int main(int argc, char *argv[]) -{ return 0; } -#undef main -#define main K_and_R_C_main -], [ return 0; ], - [ echo "*** The test program compiled, but did not run. This usually means" - echo "*** that the run-time linker is not finding MYSQL or finding the wrong" - echo "*** version of MYSQL. If it is not finding MYSQL, you'll need to set your" - echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" - echo "*** to the installed location Also, make sure you have run ldconfig if that" - echo "*** is required on your system" - echo "***" - echo "*** If you have an old version installed, it is best to remove it, although" - echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], - [ echo "*** The test program failed to compile or link. See the file config.log for the" - echo "*** exact error that occured. This usually means MYSQL was incorrectly installed" - echo "*** or that you have moved MYSQL since it was installed. In the latter case, you" - echo "*** may want to edit the mysql_config script: $MYSQL_CONFIG" ]) - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - fi - fi - MYSQL_CFLAGS="" - MYSQL_LIBS="" - ifelse([$3], , :, [$3]) - fi - AC_SUBST(MYSQL_CFLAGS) - AC_SUBST(MYSQL_LIBS) - rm -f conf.mysqltest -]) - -# ========================================================================= -# AM_PATH_FMOD : FMOD checking macros - -AC_DEFUN([AM_PATH_FMOD], -[ is_mandatory="$1" - -AC_REQUIRE_CPP() - -# Get from the user option the path to the FMOD files location -AC_ARG_WITH( fmod, - [ --with-fmod= path to the FMOD install files directory. - e.g. /usr/local]) - -AC_ARG_WITH( fmod-include, - [ --with-fmod-include= - path to the FMOD header files directory. - e.g. /usr/local/include]) - -AC_ARG_WITH( fmod-lib, - [ --with-fmod-lib= - path to the FMOD library files directory. - e.g. /usr/local/lib]) - -fmod_lib="fmod" - -if test $with_fmod -then - fmod_includes="$with_fmod/include" - fmod_libraries="$with_fmod/lib" -fi - -if test "$with_fmod_include" -then - fmod_includes="$with_fmod_include" -fi - -if test "$with_fmod_lib" -then - fmod_libraries="$with_fmod_lib" -fi - - -# Set FMOD_CFLAGS -if test "$fmod_includes" -then - FMOD_CFLAGS="-I$fmod_includes" -fi - -# Set FMOD_LIBS -if test "$fmod_libraries" -then - FMOD_LIBS="-L$fmod_libraries" -fi -FMOD_LIBS="$FMOD_LIBS -l$fmod_lib" - -_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CXXFLAGS $FMOD_CFLAGS" - -AC_MSG_CHECKING(for FMOD headers) -AC_EGREP_CPP( yo_fmod, -[#include -#ifdef FMOD_VERSION - yo_fmod -#endif], - have_fmod_headers="yes", - have_fmod_headers="no" ) - -if test "$have_fmod_headers" = "yes" -then - if test "$fmod_includes" - then - AC_MSG_RESULT([$fmod_includes]) - else - AC_MSG_RESULT(yes) - fi -else - AC_MSG_RESULT(no) -fi - -# Test the libraries -AC_MSG_CHECKING(for FMOD libraries) - -CPPFLAGS="$CXXFLAGS $FMOD_LIBS" - -AC_TRY_LINK( , , have_fmod_libraries="yes", have_fmod_libraries="no") - -CPPFLAGS="$_CPPFLAGS" - -if test "$have_fmod_libraries" = "yes" -then - if test "$fmod_libraries" - then - AC_MSG_RESULT([$fmod_libraries]) - else - AC_MSG_RESULT(yes) - fi -else - AC_MSG_RESULT(no) -fi - -fmod_libraries="$fmod_libraries" - -if test "$have_fmod_headers" = "yes" \ - && test "$have_fmod_libraries" = "yes" -then - have_fmod="yes" -else - have_fmod="no" -fi - -if test "$have_fmod" = "no" -a "$is_mandatory" = "yes" -then - AC_MSG_ERROR([FMOD is needed to compile NeL (http://www.fmod.org).]) -fi - -AC_SUBST(FMOD_CFLAGS) -AC_SUBST(FMOD_LIBS) -AC_SUBST([have_fmod]) - -]) - -# ========================================================================= -# End of file - diff --git a/code/nel/autogen.sh b/code/nel/autogen.sh deleted file mode 100755 index b863e1067..000000000 --- a/code/nel/autogen.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh - - -WANT_AUTOMAKE="1.6" - -case `uname -s` in -Darwin) - LIBTOOLIZE=glibtoolize - ;; -*) - LIBTOOLIZE=libtoolize - ;; -esac - -# be able to customize the aclocal (for example to add extra param) -if test "x$ACLOCAL" = "x" -then - ACLOCAL=aclocal -fi - -echo "Creating macros..." && \ -$ACLOCAL -I automacros/ && \ -echo "Creating library tools..." && \ -$LIBTOOLIZE --force && \ -echo "Creating header templates..." && \ -autoheader && \ -echo "Creating Makefile templates..." && \ -automake --gnu --add-missing && \ -echo "Creating 'configure'..." && \ -autoconf && \ -echo "" && \ -echo "Run: ./configure; make; make install" && \ -echo "" diff --git a/code/nel/automacros/gtk-2.0.m4 b/code/nel/automacros/gtk-2.0.m4 deleted file mode 100644 index 3deba01be..000000000 --- a/code/nel/automacros/gtk-2.0.m4 +++ /dev/null @@ -1,196 +0,0 @@ -# Configure paths for GTK+ -# Owen Taylor 1997-2001 - -dnl AM_PATH_GTK_2_0([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, MODULES]]]]) -dnl Test for GTK+, and define GTK_CFLAGS and GTK_LIBS, if gthread is specified in MODULES, -dnl pass to pkg-config -dnl -AC_DEFUN([AM_PATH_GTK_2_0], -[dnl -dnl Get the cflags and libraries from pkg-config -dnl -AC_ARG_ENABLE(gtktest, [ --disable-gtktest do not try to compile and run a test GTK+ program], - , enable_gtktest=yes) - - pkg_config_args=gtk+-2.0 - for module in . $4 - do - case "$module" in - gthread) - pkg_config_args="$pkg_config_args gthread-2.0" - ;; - esac - done - - no_gtk="" - - AC_PATH_PROG(PKG_CONFIG, pkg-config, no) - - if test x$PKG_CONFIG != xno ; then - if pkg-config --atleast-pkgconfig-version 0.7 ; then - : - else - echo "*** pkg-config too old; version 0.7 or better required." - no_gtk=yes - PKG_CONFIG=no - fi - else - no_gtk=yes - fi - - min_gtk_version=ifelse([$1], ,2.0.0,$1) - AC_MSG_CHECKING(for GTK+ - version >= $min_gtk_version) - - if test x$PKG_CONFIG != xno ; then - ## don't try to run the test against uninstalled libtool libs - if $PKG_CONFIG --uninstalled $pkg_config_args; then - echo "Will use uninstalled version of GTK+ found in PKG_CONFIG_PATH" - enable_gtktest=no - fi - - if $PKG_CONFIG --atleast-version $min_gtk_version $pkg_config_args; then - : - else - no_gtk=yes - fi - fi - - if test x"$no_gtk" = x ; then - GTK_CFLAGS=`$PKG_CONFIG $pkg_config_args --cflags` - GTK_LIBS=`$PKG_CONFIG $pkg_config_args --libs` - gtk_config_major_version=`$PKG_CONFIG --modversion gtk+-2.0 | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` - gtk_config_minor_version=`$PKG_CONFIG --modversion gtk+-2.0 | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` - gtk_config_micro_version=`$PKG_CONFIG --modversion gtk+-2.0 | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` - if test "x$enable_gtktest" = "xyes" ; then - ac_save_CFLAGS="$CFLAGS" - ac_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $GTK_CFLAGS" - LIBS="$GTK_LIBS $LIBS" -dnl -dnl Now check if the installed GTK+ is sufficiently new. (Also sanity -dnl checks the results of pkg-config to some extent) -dnl - rm -f conf.gtktest - AC_TRY_RUN([ -#include -#include -#include - -int -main () -{ - int major, minor, micro; - char *tmp_version; - - system ("touch conf.gtktest"); - - /* HP/UX 9 (%@#!) writes to sscanf strings */ - tmp_version = g_strdup("$min_gtk_version"); - if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { - printf("%s, bad version string\n", "$min_gtk_version"); - exit(1); - } - - if ((gtk_major_version != $gtk_config_major_version) || - (gtk_minor_version != $gtk_config_minor_version) || - (gtk_micro_version != $gtk_config_micro_version)) - { - printf("\n*** 'pkg-config --modversion gtk+-2.0' returned %d.%d.%d, but GTK+ (%d.%d.%d)\n", - $gtk_config_major_version, $gtk_config_minor_version, $gtk_config_micro_version, - gtk_major_version, gtk_minor_version, gtk_micro_version); - printf ("*** was found! If pkg-config was correct, then it is best\n"); - printf ("*** to remove the old version of GTK+. You may also be able to fix the error\n"); - printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n"); - printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n"); - printf("*** required on your system.\n"); - printf("*** If pkg-config was wrong, set the environment variable PKG_CONFIG_PATH\n"); - printf("*** to point to the correct configuration files\n"); - } - else if ((gtk_major_version != GTK_MAJOR_VERSION) || - (gtk_minor_version != GTK_MINOR_VERSION) || - (gtk_micro_version != GTK_MICRO_VERSION)) - { - printf("*** GTK+ header files (version %d.%d.%d) do not match\n", - GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION); - printf("*** library (version %d.%d.%d)\n", - gtk_major_version, gtk_minor_version, gtk_micro_version); - } - else - { - if ((gtk_major_version > major) || - ((gtk_major_version == major) && (gtk_minor_version > minor)) || - ((gtk_major_version == major) && (gtk_minor_version == minor) && (gtk_micro_version >= micro))) - { - return 0; - } - else - { - printf("\n*** An old version of GTK+ (%d.%d.%d) was found.\n", - gtk_major_version, gtk_minor_version, gtk_micro_version); - printf("*** You need a version of GTK+ newer than %d.%d.%d. The latest version of\n", - major, minor, micro); - printf("*** GTK+ is always available from ftp://ftp.gtk.org.\n"); - printf("***\n"); - printf("*** If you have already installed a sufficiently new version, this error\n"); - printf("*** probably means that the wrong copy of the pkg-config shell script is\n"); - printf("*** being found. The easiest way to fix this is to remove the old version\n"); - printf("*** of GTK+, but you can also set the PKG_CONFIG environment to point to the\n"); - printf("*** correct copy of pkg-config. (In this case, you will have to\n"); - printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n"); - printf("*** so that the correct libraries are found at run-time))\n"); - } - } - return 1; -} -],, no_gtk=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - fi - fi - if test "x$no_gtk" = x ; then - AC_MSG_RESULT(yes (version $gtk_config_major_version.$gtk_config_minor_version.$gtk_config_micro_version)) - ifelse([$2], , :, [$2]) - else - AC_MSG_RESULT(no) - if test "$PKG_CONFIG" = "no" ; then - echo "*** A new enough version of pkg-config was not found." - echo "*** See http://pkgconfig.sourceforge.net" - else - if test -f conf.gtktest ; then - : - else - echo "*** Could not run GTK+ test program, checking why..." - ac_save_CFLAGS="$CFLAGS" - ac_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $GTK_CFLAGS" - LIBS="$LIBS $GTK_LIBS" - AC_TRY_LINK([ -#include -#include -], [ return ((gtk_major_version) || (gtk_minor_version) || (gtk_micro_version)); ], - [ echo "*** The test program compiled, but did not run. This usually means" - echo "*** that the run-time linker is not finding GTK+ or finding the wrong" - echo "*** version of GTK+. If it is not finding GTK+, you'll need to set your" - echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" - echo "*** to the installed location Also, make sure you have run ldconfig if that" - echo "*** is required on your system" - echo "***" - echo "*** If you have an old version installed, it is best to remove it, although" - echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" ], - [ echo "*** The test program failed to compile or link. See the file config.log for the" - echo "*** exact error that occured. This usually means GTK+ is incorrectly installed."]) - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - fi - fi - GTK_CFLAGS="" - GTK_LIBS="" - ifelse([$3], , :, [$3]) - fi - AC_SUBST(GTK_CFLAGS) - AC_SUBST(GTK_LIBS) - rm -f conf.gtktest -]) diff --git a/code/nel/automacros/ogg.m4 b/code/nel/automacros/ogg.m4 deleted file mode 100644 index 0e1f1abf5..000000000 --- a/code/nel/automacros/ogg.m4 +++ /dev/null @@ -1,102 +0,0 @@ -# Configure paths for libogg -# Jack Moffitt 10-21-2000 -# Shamelessly stolen from Owen Taylor and Manish Singh - -dnl XIPH_PATH_OGG([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) -dnl Test for libogg, and define OGG_CFLAGS and OGG_LIBS -dnl -AC_DEFUN([XIPH_PATH_OGG], -[dnl -dnl Get the cflags and libraries -dnl -AC_ARG_WITH(ogg,[ --with-ogg=PFX Prefix where libogg is installed (optional)], ogg_prefix="$withval", ogg_prefix="") -AC_ARG_WITH(ogg-libraries,[ --with-ogg-libraries=DIR Directory where libogg library is installed (optional)], ogg_libraries="$withval", ogg_libraries="") -AC_ARG_WITH(ogg-includes,[ --with-ogg-includes=DIR Directory where libogg header files are installed (optional)], ogg_includes="$withval", ogg_includes="") -AC_ARG_ENABLE(oggtest, [ --disable-oggtest Do not try to compile and run a test Ogg program],, enable_oggtest=yes) - - if test "x$ogg_libraries" != "x" ; then - OGG_LIBS="-L$ogg_libraries" - elif test "x$ogg_prefix" != "x" ; then - OGG_LIBS="-L$ogg_prefix/lib" - elif test "x$prefix" != "xNONE" ; then - OGG_LIBS="-L$prefix/lib" - fi - - OGG_LIBS="$OGG_LIBS -logg" - - if test "x$ogg_includes" != "x" ; then - OGG_CFLAGS="-I$ogg_includes" - elif test "x$ogg_prefix" != "x" ; then - OGG_CFLAGS="-I$ogg_prefix/include" - elif test "x$prefix" != "xNONE"; then - OGG_CFLAGS="-I$prefix/include" - fi - - AC_MSG_CHECKING(for Ogg) - no_ogg="" - - - if test "x$enable_oggtest" = "xyes" ; then - ac_save_CFLAGS="$CFLAGS" - ac_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $OGG_CFLAGS" - LIBS="$LIBS $OGG_LIBS" -dnl -dnl Now check if the installed Ogg is sufficiently new. -dnl - rm -f conf.oggtest - AC_TRY_RUN([ -#include -#include -#include -#include - -int main () -{ - system("touch conf.oggtest"); - return 0; -} - -],, no_ogg=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - fi - - if test "x$no_ogg" = "x" ; then - AC_MSG_RESULT(yes) - ifelse([$1], , :, [$1]) - else - AC_MSG_RESULT(no) - if test -f conf.oggtest ; then - : - else - echo "*** Could not run Ogg test program, checking why..." - CFLAGS="$CFLAGS $OGG_CFLAGS" - LIBS="$LIBS $OGG_LIBS" - AC_TRY_LINK([ -#include -#include -], [ return 0; ], - [ echo "*** The test program compiled, but did not run. This usually means" - echo "*** that the run-time linker is not finding Ogg or finding the wrong" - echo "*** version of Ogg. If it is not finding Ogg, you'll need to set your" - echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" - echo "*** to the installed location Also, make sure you have run ldconfig if that" - echo "*** is required on your system" - echo "***" - echo "*** If you have an old version installed, it is best to remove it, although" - echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], - [ echo "*** The test program failed to compile or link. See the file config.log for the" - echo "*** exact error that occured. This usually means Ogg was incorrectly installed" - echo "*** or that you have moved Ogg since it was installed." ]) - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - fi - OGG_CFLAGS="" - OGG_LIBS="" - ifelse([$2], , :, [$2]) - fi - AC_SUBST(OGG_CFLAGS) - AC_SUBST(OGG_LIBS) - rm -f conf.oggtest -]) diff --git a/code/nel/automacros/pkg.m4 b/code/nel/automacros/pkg.m4 deleted file mode 100644 index c29b6c057..000000000 --- a/code/nel/automacros/pkg.m4 +++ /dev/null @@ -1,157 +0,0 @@ -# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -# -# Copyright © 2004 Scott James Remnant . -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 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 -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# PKG_PROG_PKG_CONFIG([MIN-VERSION]) -# ---------------------------------- -AC_DEFUN([PKG_PROG_PKG_CONFIG], -[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) -m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) -AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl -if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then - AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) -fi -if test -n "$PKG_CONFIG"; then - _pkg_min_version=m4_default([$1], [0.9.0]) - AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) - if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - PKG_CONFIG="" - fi - -fi[]dnl -])# PKG_PROG_PKG_CONFIG - -# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -# -# Check to see whether a particular set of modules exists. Similar -# to PKG_CHECK_MODULES(), but does not set variables or print errors. -# -# -# Similar to PKG_CHECK_MODULES, make sure that the first instance of -# this or PKG_CHECK_MODULES is called, or make sure to call -# PKG_CHECK_EXISTS manually -# -------------------------------------------------------------- -AC_DEFUN([PKG_CHECK_EXISTS], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -if test -n "$PKG_CONFIG" && \ - AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then - m4_ifval([$2], [$2], [:]) -m4_ifvaln([$3], [else - $3])dnl -fi]) - - -# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) -# --------------------------------------------- -m4_define([_PKG_CONFIG], -[if test -n "$PKG_CONFIG"; then - if test -n "$$1"; then - pkg_cv_[]$1="$$1" - else - PKG_CHECK_EXISTS([$3], - [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], - [pkg_failed=yes]) - fi -else - pkg_failed=untried -fi[]dnl -])# _PKG_CONFIG - -# _PKG_SHORT_ERRORS_SUPPORTED -# ----------------------------- -AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi[]dnl -])# _PKG_SHORT_ERRORS_SUPPORTED - - -# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], -# [ACTION-IF-NOT-FOUND]) -# -# -# Note that if there is a possibility the first call to -# PKG_CHECK_MODULES might not happen, you should be sure to include an -# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac -# -# -# -------------------------------------------------------------- -AC_DEFUN([PKG_CHECK_MODULES], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl -AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl - -pkg_failed=no -AC_MSG_CHECKING([for $1]) - -_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) -_PKG_CONFIG([$1][_LIBS], [libs], [$2]) - -m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS -and $1[]_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details.]) - -if test $pkg_failed = yes; then - _PKG_SHORT_ERRORS_SUPPORTED - if test $_pkg_short_errors_supported = yes; then - $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"` - else - $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` - fi - # Put the nasty error message in config.log where it belongs - echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD - - ifelse([$4], , [AC_MSG_ERROR(dnl -[Package requirements ($2) were not met: - -$$1_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -_PKG_TEXT -])], - [AC_MSG_RESULT([no]) - $4]) -elif test $pkg_failed = untried; then - ifelse([$4], , [AC_MSG_FAILURE(dnl -[The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -_PKG_TEXT - -To get pkg-config, see .])], - [$4]) -else - $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS - $1[]_LIBS=$pkg_cv_[]$1[]_LIBS - AC_MSG_RESULT([yes]) - ifelse([$3], , :, [$3]) -fi[]dnl -])# PKG_CHECK_MODULES diff --git a/code/nel/automacros/vorbis.m4 b/code/nel/automacros/vorbis.m4 deleted file mode 100644 index 300cc6c7d..000000000 --- a/code/nel/automacros/vorbis.m4 +++ /dev/null @@ -1,122 +0,0 @@ -# Configure paths for libvorbis -# Jack Moffitt 10-21-2000 -# Shamelessly stolen from Owen Taylor and Manish Singh -# thomasvs added check for vorbis_bitrate_addblock which is new in rc3 - -dnl XIPH_PATH_VORBIS([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) -dnl Test for libvorbis, and define VORBIS_CFLAGS and VORBIS_LIBS -dnl -AC_DEFUN([XIPH_PATH_VORBIS], -[dnl -dnl Get the cflags and libraries -dnl -AC_ARG_WITH(vorbis,[ --with-vorbis=PFX Prefix where libvorbis is installed (optional)], vorbis_prefix="$withval", vorbis_prefix="") -AC_ARG_WITH(vorbis-libraries,[ --with-vorbis-libraries=DIR Directory where libvorbis library is installed (optional)], vorbis_libraries="$withval", vorbis_libraries="") -AC_ARG_WITH(vorbis-includes,[ --with-vorbis-includes=DIR Directory where libvorbis header files are installed (optional)], vorbis_includes="$withval", vorbis_includes="") -AC_ARG_ENABLE(vorbistest, [ --disable-vorbistest Do not try to compile and run a test Vorbis program],, enable_vorbistest=yes) - - if test "x$vorbis_libraries" != "x" ; then - VORBIS_LIBS="-L$vorbis_libraries" - elif test "x$vorbis_prefix" != "x" ; then - VORBIS_LIBS="-L$vorbis_prefix/lib" - elif test "x$prefix" != "xNONE"; then - VORBIS_LIBS="-L$prefix/lib" - fi - - VORBIS_LIBS="$VORBIS_LIBS -lvorbis -lm" - VORBISFILE_LIBS="-lvorbisfile" - VORBISENC_LIBS="-lvorbisenc" - - if test "x$vorbis_includes" != "x" ; then - VORBIS_CFLAGS="-I$vorbis_includes" - elif test "x$vorbis_prefix" != "x" ; then - VORBIS_CFLAGS="-I$vorbis_prefix/include" - elif test "x$prefix" != "xNONE"; then - VORBIS_CFLAGS="-I$prefix/include" - fi - - - AC_MSG_CHECKING(for Vorbis) - no_vorbis="" - - - if test "x$enable_vorbistest" = "xyes" ; then - ac_save_CFLAGS="$CFLAGS" - ac_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $VORBIS_CFLAGS $OGG_CFLAGS" - LIBS="$LIBS $VORBIS_LIBS $VORBISENC_LIBS $OGG_LIBS" -dnl -dnl Now check if the installed Vorbis is sufficiently new. -dnl - rm -f conf.vorbistest - AC_TRY_RUN([ -#include -#include -#include -#include -#include - -int main () -{ - vorbis_block vb; - vorbis_dsp_state vd; - vorbis_info vi; - - vorbis_info_init (&vi); - vorbis_encode_init (&vi, 2, 44100, -1, 128000, -1); - vorbis_analysis_init (&vd, &vi); - vorbis_block_init (&vd, &vb); - /* this function was added in 1.0rc3, so this is what we're testing for */ - vorbis_bitrate_addblock (&vb); - - system("touch conf.vorbistest"); - return 0; -} - -],, no_vorbis=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - fi - - if test "x$no_vorbis" = "x" ; then - AC_MSG_RESULT(yes) - ifelse([$1], , :, [$1]) - else - AC_MSG_RESULT(no) - if test -f conf.vorbistest ; then - : - else - echo "*** Could not run Vorbis test program, checking why..." - CFLAGS="$CFLAGS $VORBIS_CFLAGS" - LIBS="$LIBS $VORBIS_LIBS $OGG_LIBS" - AC_TRY_LINK([ -#include -#include -], [ return 0; ], - [ echo "*** The test program compiled, but did not run. This usually means" - echo "*** that the run-time linker is not finding Vorbis or finding the wrong" - echo "*** version of Vorbis. If it is not finding Vorbis, you'll need to set your" - echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" - echo "*** to the installed location Also, make sure you have run ldconfig if that" - echo "*** is required on your system" - echo "***" - echo "*** If you have an old version installed, it is best to remove it, although" - echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], - [ echo "*** The test program failed to compile or link. See the file config.log for the" - echo "*** exact error that occured. This usually means Vorbis was incorrectly installed" - echo "*** or that you have moved Vorbis since it was installed." ]) - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - fi - VORBIS_CFLAGS="" - VORBIS_LIBS="" - VORBISFILE_LIBS="" - VORBISENC_LIBS="" - ifelse([$2], , :, [$2]) - fi - AC_SUBST(VORBIS_CFLAGS) - AC_SUBST(VORBIS_LIBS) - AC_SUBST(VORBISFILE_LIBS) - AC_SUBST(VORBISENC_LIBS) - rm -f conf.vorbistest -]) diff --git a/code/nel/configure.ac b/code/nel/configure.ac deleted file mode 100644 index 84edccc05..000000000 --- a/code/nel/configure.ac +++ /dev/null @@ -1,599 +0,0 @@ -# ==================================================================== -# Configuration script for NeL -# ==================================================================== -# -# $Id: configure.ac,v 1.8 2005/04/14 15:54:32 cado Exp $ -# - -# ==================================================================== -# Process this file with autoconf to produce a configure script. -# ==================================================================== - -# If you want to change the version, must must change AC_INIT -# *and* AC_SUBST(LIBTOOL_VERSION) - -AC_PREREQ(2.57) -AC_INIT([nel],[0.8.0],[nel-all@nevrax.org]) -AM_INIT_AUTOMAKE([tar-ustar]) - -AC_CONFIG_SRCDIR(include/nel/misc/types_nl.h) -AM_CONFIG_HEADER(include/nelconfig.h) - -AC_SUBST(LIBTOOL_VERSION, [0:7:0]) - -# Checks for programs. -AC_CANONICAL_HOST -AC_PROG_CXX -AC_PROG_CPP -AC_PROG_YACC -AC_PROG_LEX -AC_PROG_INSTALL -AC_PROG_LN_S -AC_PROG_MAKE_SET -AC_PROG_LIBTOOL -AM_PROG_LIBTOOL -AM_SANITY_CHECK - -AC_SYS_LARGEFILE - -AM_MAINTAINER_MODE - - -# Template needed to generate the nelconfig.h.in -AH_TEMPLATE([NEL_DEFAULT_DISPLAYER],[Define to 1 if you want log on standard output]) -AH_TEMPLATE([NEL_LOG_IN_FILE],[Define to 1 if you want a debug log.log file in the current directory]) -AH_TEMPLATE([HAVE_X86],[Define to 1 if you are on a INTEL compatible processor]) -AH_TEMPLATE([HAVE_X86_64],[Define to 1 if you are on AMD opteron 64bits processor]) -AH_TEMPLATE([NL_USE_GTK], [Define to 1 if you want GTK support]) - -# Get host type info -if test "$host_cpu" = "i386" -o "$host_cpu" = "i486" -o "$host_cpu" = "i586" \ - -o "$host_cpu" = "i686" -o "$host_cpu" = "i786" -o "$host_cpu" = "x86_64" -then - AC_DEFINE([HAVE_X86]) -fi - -if test "$host_cpu" = "x86_64" -then - AC_DEFINE([HAVE_X86_64]) -fi - -# The following hack should ensure that configure doesnt add optimizing -# or debugging flags to CFLAGS or CXXFLAGS -CXXFLAGS="$CXXFLAGS -fno-strict-aliasing -ftemplate-depth-24 -fno-stack-protector" - - -# ==================================================================== -# Checks NeL modules (net, 3d) to install / Disable -# ==================================================================== - -# The misc is mandatory, it is use by the other modules. - -NEL_SUBDIRS="misc" - -# NeL libraries that are enabled by default - -# Network library -AC_ARG_ENABLE([net], - AC_HELP_STRING([--disable-net], - [disable compilation and install of NeL Network]), - [], - [enable_net=yes]) - -if test "$enable_net" = "no" -then - AC_MSG_RESULT([disable NeL Network]) -else - NEL_SUBDIRS="$NEL_SUBDIRS net" -fi - -# 3D library -AC_ARG_ENABLE([3d], - AC_HELP_STRING([--disable-3d], - [disable compilation and install of NeL 3D]), - [], - [enable_3d=yes]) - -if test "$enable_3d" = "no" -then - AC_MSG_RESULT([disable NeL 3D]) -else - NEL_SUBDIRS="$NEL_SUBDIRS 3d" -fi - -# PACS library -AC_ARG_ENABLE([pacs], - AC_HELP_STRING([--disable-pacs], - [disable compilation and install of NeL PACS]), - [], - [enable_pacs=yes]) - -if test "$enable_pacs" = "no" -then - AC_MSG_RESULT([disable NeL PACS]) -else - NEL_SUBDIRS="$NEL_SUBDIRS pacs" -fi - -# Georges library -AC_ARG_ENABLE([georges], - AC_HELP_STRING([--disable-georges], - [disable compilation and install of NeL Georges]), - [], - [enable_georges=yes]) - -if test "$enable_georges" = "no" -then - AC_MSG_RESULT([disable NeL Georges]) -else - NEL_SUBDIRS="$NEL_SUBDIRS georges" -fi - -# Ligo library -AC_ARG_ENABLE([ligo], - AC_HELP_STRING([--disable-ligo], - [disable compilation and install of NeL Ligo]), - [], - [enable_ligo=yes]) - -if test "$enable_ligo" = "no" -then - AC_MSG_RESULT([disable NeL Ligo]) -else - NEL_SUBDIRS="$NEL_SUBDIRS ligo" -fi - - -# NeL libraries that are disabled by default - -# Sound library -AC_ARG_ENABLE([sound], - AC_HELP_STRING([--enable-sound], - [enable compilation and install of NeL Sound]), - [], - [enable_sound=no]) - -if test "$enable_sound" = "yes" -then - AC_MSG_RESULT([enable NeL Sound]) - NEL_SUBDIRS="$NEL_SUBDIRS sound" -fi - -# CEGUI Renderer library -AC_ARG_ENABLE([cegui], - AC_HELP_STRING([--enable-cegui], - [enable compilation and install of NeL CEGUI Renderer]), - [], - [enable_cegui=no]) - -CEGUI_SUBDIR="" -if test "$enable_cegui" = "yes" -then - AC_MSG_RESULT([enable NeL CEGUI Renderer]) - NEL_SUBDIRS="$NEL_SUBDIRS cegui" - CEGUI_SUBDIR="cegui" -fi - -# Unit Tests -AC_ARG_ENABLE([tests], - AC_HELP_STRING([--enable-tests], - [enable unit tests of NeL]), - [], - [enable_tests=no]) - -if test "$enable_tests" = "yes" -then - AC_MSG_RESULT([enable NeL Unit Tests]) -fi - -# Code Coverage -AC_ARG_ENABLE([coverage], - AC_HELP_STRING([--enable-coverage], - [enable code coverage generation]), - [] - [enable_coverage=no]) - -if test "$enable_coverage" = "yes" -then - AC_MSG_RESULT([enable Code Coverage generation]) - - CXXFLAGS="$CXXFLAGS -fprofile-arcs -ftest-coverage" -fi - -# Enable/disable samples compilation. -AC_ARG_ENABLE([samples], - AC_HELP_STRING([--disable-samples], - [disable sample code]), - [], - [enable_samples="yes"]) - -if test "$enable_samples" = "no" -then - AC_MSG_RESULT([disable sample code.]) - SAMPLE_SUBDIR="" -else - SAMPLE_SUBDIR="samples" -fi - -# Enable/disable tools compilation. -AC_ARG_ENABLE([tools], - AC_HELP_STRING([--disable-tools], - [disable tools code]), - [], - [enable_tools="yes"]) - -if test "$enable_tools" = "no" -then - AC_MSG_RESULT([disable tools code.]) - TOOLS_SUBDIR="" -else - TOOLS_SUBDIR="tools" -fi - -AC_SUBST([enable_net]) -AC_SUBST([enable_3d]) -AC_SUBST([enable_pacs]) -AC_SUBST([enable_sound]) -AC_SUBST([enable_georges]) -AC_SUBST([enable_ligo]) -AC_SUBST([enable_cegui]) - -AC_SUBST([NEL_SUBDIRS]) -AC_SUBST([SAMPLE_SUBDIR]) -AC_SUBST([TOOLS_SUBDIR]) -AC_SUBST([CEGUI_SUBDIR]) - -# ==================================================================== -# Checks for programs. -# ==================================================================== - -# ==================================================================== -# Configure Settings -# ==================================================================== - -# Disable the static linking by default -# AC_DISABLE_STATIC - -# Use C++ compiler as a default for the compilation tests. -AC_LANG([C++]) - - -# ==================================================================== -# Debug/optimized compilation mode -# ==================================================================== - -AM_NEL_DEBUG - -AC_ARG_WITH([logging], - AC_HELP_STRING([--without-logging], - [be silent on stdout and in no log.log]), - [], - [with_logging=yes]) - -if test "$with_logging" = "yes" -then - AC_DEFINE([NEL_DEFAULT_DISPLAYER], 1) - AC_DEFINE([NEL_LOG_IN_FILE], 1) -fi - -# ==================================================================== -# Checks for typedefs, structures, and compiler characteristics. -# ==================================================================== - -# Test endianness -AC_C_BIGENDIAN - -# Supress GCC "multi-character character constant" warnings. -if test "$ac_cv_cxx_compiler_gnu" = "yes"; -then - if test "$with_debug" = "yes" - then - # - # When debugging variables are declared for the sole purpose of - # inspecting their content with a debugger. They are not used - # in the code itself and this is legitimate, hence the -Wno-unused - # - CXXFLAGS="$CXXFLAGS -Wno-unused" - fi -fi - -# Add some common define -if test "$ac_cv_cxx_compiler_gnu" = "yes"; -then - CXXFLAGS="$CXXFLAGS -D_REENTRANT -Wall -ansi -W -Wpointer-arith -Wsign-compare -Wno-deprecated-declarations -Wno-multichar -Wno-long-long -Wno-unused" -fi - - -# ==================================================================== -# Checks for header and lib files. -# ==================================================================== - -AC_FUNC_ALLOCA -AC_HEADER_DIRENT -AC_HEADER_STDC -AC_HEADER_TIME -AC_CHECK_HEADERS([arpa/inet.h fcntl.h float.h malloc.h netdb.h netinet/in.h stddef.h stdlib.h string.h sys/ioctl.h sys/socket.h unistd.h sys/time.h]) -AC_CHECK_LIB([pthread], [pthread_create]) -AC_CHECK_LIB([dl], [dlopen]) - - -# ==================================================================== -# Checks for typedefs, structures, and compiler characteristics. -# ==================================================================== - -AC_HEADER_STDBOOL -AC_C_CONST -AC_C_INLINE -AC_TYPE_SIZE_T -AC_HEADER_TIME -AC_STRUCT_TM -AC_C_VOLATILE -AC_CHECK_TYPES([ptrdiff_t]) -AC_CHECK_TYPES([size_t]) -AC_CHECK_TYPES([uintptr_t]) - - -# ==================================================================== -# Checks for library functions. -# ==================================================================== - -AC_FUNC_CLOSEDIR_VOID -AC_FUNC_ERROR_AT_LINE -AC_PROG_GCC_TRADITIONAL -AC_FUNC_MALLOC -AC_FUNC_MEMCMP -AC_FUNC_REALLOC -AC_FUNC_SELECT_ARGTYPES -AC_TYPE_SIGNAL -AC_FUNC_STAT -AC_FUNC_STRFTIME -AC_FUNC_FORK -AC_FUNC_VPRINTF -AC_CHECK_FUNCS([floor getcwd gethostbyaddr gethostbyname gethostname gettimeofday inet_ntoa memmove memset mkdir pow select socket sqrt strcasecmp strchr strdup strerror strrchr strstr strtoul sys/time.h]) - - -# ==================================================================== -# X11 - -AC_PATH_X - -if test ! "$no_x" = "yes" -then - if test ! X"$x_libraries" = X - then - LIBS="$LIBS -L$x_libraries" - fi - - if test ! X"$x_includes" = X - then - CXXFLAGS="$CXXFLAGS -I$x_includes" - fi -else - if test "$enable_3d" = "yes" - then - AC_MSG_ERROR([X11 must be installed for NeL 3d library, use --disable-3d if you don't need NeL 3d library]) - fi -fi - -# ==================================================================== -# LibXML - -# Use C compiler as a default for the libxml tests. -AC_LANG([C]) - -AM_PATH_XML2([2.0.0], [], [AC_MSG_ERROR([libxml2 must be installed])]) - -CXXFLAGS="$CXXFLAGS $XML_CFLAGS $XML_CPPFLAGS" - -LIBS="$LIBS $XML_LIBS" - -# Use C++ compiler as a default for the compilation tests. -AC_LANG([C++]) - -# ==================================================================== -# libpng - -AC_CHECK_HEADER(png.h, [], AC_MSG_ERROR([libpng must be installed])) - -# ==================================================================== -# libjpeg - -AC_CHECK_HEADER(jpeglib.h, [], AC_MSG_ERROR([libjpeg must be installed])) - -# ==================================================================== -# Checks for libraries. -# ==================================================================== - -# ==================================================================== -# GTK 2.0+ - -AC_ARG_WITH([gtk], - AC_HELP_STRING([--with-gtk], - [add GTK dependent code like GTK displayer]), - [], - [with_gtk=no]) - -if test "$with_gtk" = "yes" -then - AC_LANG([C]) - - AM_PATH_GTK_2_0([2.0.0], - CXXFLAGS="$CXXFLAGS $GTK_CFLAGS" - LIBS="$LIBS $GTK_LIBS" - AC_DEFINE(NL_USE_GTK, [], [Undef if you don't want to use anything GTK based like the GTK Displayer] -) - ) - - AC_LANG([C++]) - - AC_SUBST([with_gtk]) -fi - -# ==================================================================== -# CEGUI - -if test "$enable_cegui" = "yes" -then - PKG_CHECK_MODULES(CEGUI, CEGUI >= 0.4, - [], - [ - AC_MSG_ERROR([Couldn't find CEGUI or tests failed: -$CEGUI_PKG_ERRORS -Please go to http://crayzedsgui.sourceforge.net to get the latest, or check -config.log to see why the tests failed, and fix it.]) - ]) -fi - -# ==================================================================== -# FreeType 2 - -AM_PATH_FREETYPE($enable_3d) - - -# ==================================================================== -# OpenGL - -AM_PATH_OPENGL($enable_3d) - - -# ==================================================================== -# Check for XF86VidMode extension (-lXxf86vm) - -AM_PATH_XF86VIDMODE - - -# ==================================================================== -# FMOD, OpenAL - -if test "$enable_sound" = "yes" -then - AM_PATH_FMOD("no") - AM_PATH_OPENAL("no") - if test "$have_fmod" = "no" -a "$have_openal" = "no" - then - AC_MSG_ERROR([Either FMod or OpenAL must be installed to use sound.]) - fi - if test "$have_fmod" = "yes" - then - SOUND_SUBDIRS="fmod" - else - SOUND_SUBDIRS="" - fi - if test "$have_openal" = "yes" - then - SOUND_SUBDIRS="$SOUND_SUBDIRS openal" - - XIPH_PATH_OGG([], AC_MSG_ERROR([Driver OpenAL Requires libogg!])) - XIPH_PATH_VORBIS([], AC_MSG_ERROR([Driver OpenAL Requires libvorbis!])) - fi - AC_SUBST([SOUND_SUBDIRS]) -fi - - -# ==================================================================== -# CppTest - -#AM_PATH_CPPTEST($enable_tests) - -# ==================================================================== -# Arrange for the include directory to be in the search path even when -# build is done outside the source tree -# Put the nelconfig.h define -CXXFLAGS="$CXXFLAGS -I\${top_srcdir}/include -DHAVE_NELCONFIG_H" - -# ==================================================================== -# Checks for library functions. -# ==================================================================== - - -# ==================================================================== -# Output files to generate. -# ==================================================================== - -AC_CONFIG_FILES([Makefile \ - include/Makefile \ - include/nel/Makefile \ - include/nel/ligo/Makefile \ - include/nel/misc/Makefile \ - include/nel/net/Makefile \ - include/nel/3d/Makefile \ - include/nel/pacs/Makefile \ - include/nel/sound/Makefile \ - include/nel/georges/Makefile \ - include/nel/cegui/Makefile \ - src/Makefile \ - src/misc/Makefile \ - src/misc/nel-misc.pc \ - src/misc/config_file/Makefile \ - src/net/Makefile \ - src/3d/Makefile \ - src/3d/nel-3d.pc \ - src/3d/driver/Makefile \ - src/3d/driver/opengl/Makefile \ - src/3d/driver/opengl/nel-driverogl.pc \ - src/pacs/Makefile \ - src/sound/Makefile \ - src/sound/driver/Makefile \ - src/sound/driver/fmod/Makefile \ - src/sound/driver/openal/Makefile \ - src/georges/Makefile \ - src/ligo/Makefile \ - src/cegui/Makefile \ - tools/Makefile \ - tools/3d/Makefile \ - tools/3d/build_coarse_mesh/Makefile \ - tools/3d/build_far_bank/Makefile \ - tools/3d/build_smallbank/Makefile \ - tools/3d/ig_lighter/Makefile \ - tools/3d/ig_lighter_lib/Makefile \ - tools/3d/panoply_maker/Makefile \ - tools/3d/zone_dependencies/Makefile \ - tools/3d/zone_ig_lighter/Makefile \ - tools/3d/zone_lib/Makefile \ - tools/3d/zone_lighter/Makefile \ - tools/3d/zone_welder/Makefile \ - tools/misc/Makefile \ - tools/misc/bnp_make/Makefile \ - tools/misc/disp_sheet_id/Makefile \ - tools/misc/make_sheet_id/Makefile \ - tools/misc/xml_packer/Makefile \ - tools/pacs/Makefile \ - tools/pacs/build_ig_boxes/Makefile \ - tools/pacs/build_indoor_rbank/Makefile \ - tools/pacs/build_rbank/Makefile \ - samples/Makefile \ - samples/sound_sources/Makefile \ - samples/pacs/Makefile \ - samples/georges/Makefile \ - samples/3d/Makefile \ - samples/3d/font/Makefile \ - samples/3d/cluster_viewer/Makefile \ - samples/3d/cluster_viewer/shapes/Makefile \ - samples/3d/cluster_viewer/groups/Makefile \ - samples/3d/cluster_viewer/fonts/Makefile \ - samples/3d/cegui/Makefile \ - samples/misc/Makefile \ - samples/misc/command/Makefile \ - samples/misc/configfile/Makefile \ - samples/misc/debug/Makefile \ - samples/misc/i18n/Makefile \ - samples/misc/log/Makefile \ - samples/misc/strings/Makefile \ - samples/misc/types_check/Makefile \ - samples/net/Makefile \ - samples/net/chat/Makefile \ - samples/net/udp/Makefile \ - samples/net/login_system/Makefile \ - nel-config - -]) -AC_OUTPUT - -# samples/net/class_transport/Makefile \ -# tools/nel_unit_test/Makefile \ -# tools/nel_unit_test/misc_ut/Makefile \ -# tools/nel_unit_test/ligo_ut/Makefile \ -# tools/nel_unit_test/net_ut/Makefile \ -# tools/nel_unit_test/net_ut/net_service_lib_test/Makefile \ -# tools/nel_unit_test/net_ut/net_module_lib_test/Makefile \ -# End of configure.in diff --git a/code/nel/include/Makefile.am b/code/nel/include/Makefile.am deleted file mode 100644 index 193d2e405..000000000 --- a/code/nel/include/Makefile.am +++ /dev/null @@ -1,10 +0,0 @@ -# -# - -MAINTAINERCLEANFILES = Makefile.in - -SUBDIRS = nel - -pkginclude_HEADERS = nelconfig.h - -# End of Makefile.am diff --git a/code/nel/include/nel/3d/Makefile.am b/code/nel/include/nel/3d/Makefile.am deleted file mode 100644 index 8118d8348..000000000 --- a/code/nel/include/nel/3d/Makefile.am +++ /dev/null @@ -1,343 +0,0 @@ -# -# - -MAINTAINERCLEANFILES = Makefile.in - -includedir = ${prefix}/include/nel/3d - -include_HEADERS = \ -animatable.h \ -animated_lightmap.h \ -animated_material.h \ -animated_morph.h \ -animated_value.h \ -animation.h \ -animation_optimizer.h \ -animation_playlist.h \ -animation_set.h \ -animation_set_user.h \ -animation_time.h \ -anim_ctrl.h \ -anim_detail_trav.h \ -async_file_manager_3d.h \ -async_texture_block.h \ -async_texture_manager.h \ -bezier_patch.h \ -bloom_effect.h \ -bone.h \ -bsp_tree.h \ -camera_col.h \ -camera.h \ -channel_mixer.h \ -clip_trav.h \ -cloud.h \ -cloud_scape.h \ -cloud_scape_user.h \ -cluster.h \ -coarse_mesh_build.h \ -coarse_mesh_manager.h \ -computed_string.h \ -cube_grid.h \ -cube_map_builder.h \ -debug_vb.h \ -deform_2d.h \ -driver.h \ -driver_material_inline.h \ -driver_user.h \ -dru.h \ -event_mouse_listener.h \ -fasthls_modifier.h \ -fast_ptr_list.h \ -flare_model.h \ -flare_shape.h \ -font_generator.h \ -font_manager.h \ -frustum.h \ -heat_haze.h \ -height_map.h \ -hls_color_texture.h \ -hls_texture_bank.h \ -hls_texture_manager.h \ -hrc_trav.h \ -ig_surface_light_build.h \ -ig_surface_light.h \ -index_buffer.h \ -init_3d.h \ -instance_group_user.h \ -instance_lighter.h \ -key.h \ -landscape_collision_grid.h \ -landscape_def.h \ -landscape_face_vector_manager.h \ -landscape.h \ -landscapeig_manager.h \ -landscape_model.h \ -landscape_profile.h \ -landscape_user.h \ -landscapevb_allocator.h \ -landscapevb_info.h \ -landscape_vegetable_block.h \ -layered_ordering_table.h \ -light_contribution.h \ -light.h \ -light_influence_interpolator.h \ -lighting_manager.h \ -light_trav.h \ -light_user.h \ -load_balancing_trav.h \ -lod_character_builder.h \ -lod_character_instance.h \ -lod_character_manager.h \ -lod_character_shape_bank.h \ -lod_character_shape.h \ -lod_character_texture.h \ -logic_info.h \ -material.h \ -matrix_3x4.h \ -mesh_base.h \ -mesh_base_instance.h \ -mesh_blender.h \ -mesh_block_manager.h \ -mesh_geom.h \ -mesh.h \ -mesh_instance.h \ -mesh_morpher.h \ -mesh_mrm.h \ -mesh_mrm_instance.h \ -mesh_mrm_skinned.h \ -mesh_mrm_skinned_instance.h \ -mesh_multi_lod.h \ -mesh_multi_lod_instance.h \ -mesh_vertex_program.h \ -meshvp_per_pixel_light.h \ -meshvp_wind_tree.h \ -mini_col.h \ -motion_blur.h \ -mrm_builder.h \ -mrm_internal.h \ -mrm_level_detail.h \ -mrm_mesh.h \ -mrm_parameters.h \ -nelu.h \ -noise_3d.h \ -occlusion_query.h \ -ordering_table.h \ -packed_world.h \ -packed_zone.h \ -particle_system.h \ -particle_system_manager.h \ -particle_system_model.h \ -particle_system_process.h \ -particle_system_shape.h \ -patchdlm_context.h \ -patch.h \ -patch_rdr_pass.h \ -patchuv_locator.h \ -play_list_manager.h \ -play_list_manager_user.h \ -play_list_user.h \ -point_light.h \ -point_light_influence.h \ -point_light_model.h \ -point_light_named_array.h \ -point_light_named.h \ -portal.h \ -primitive_profile.h \ -ps_allocator.h \ -ps_attrib.h \ -ps_attrib_maker_bin_op.h \ -ps_attrib_maker_bin_op_inline.h \ -ps_attrib_maker.h \ -ps_attrib_maker_helper.h \ -ps_attrib_maker_iterators.h \ -ps_attrib_maker_template.h \ -ps_color.h \ -ps_direction.h \ -ps_dot.h \ -ps_edit.h \ -ps_emitter.h \ -ps_face.h \ -ps_face_look_at.h \ -ps_fan_light.h \ -ps_float.h \ -ps_force.h \ -ps_int.h \ -ps_iterator.h \ -ps_light.h \ -ps_located.h \ -ps_lod.h \ -ps_macro.h \ -ps_mesh.h \ -ps_misc.h \ -ps_particle2.h \ -ps_particle_basic.h \ -ps_particle.h \ -ps_plane_basis.h \ -ps_plane_basis_maker.h \ -ps_quad.h \ -ps_register_color_attribs.h \ -ps_register_float_attribs.h \ -ps_register_int_attribs.h \ -ps_register_plane_basis_attribs.h \ -ps_ribbon_base.h \ -ps_ribbon.h \ -ps_ribbon_look_at.h \ -ps_shockwave.h \ -ps_sound.h \ -ps_spawn_info.h \ -ps_tail_dot.h \ -ps_util.h \ -ps_zone.h \ -ptr_set.h \ -quad_effect.h \ -quad_grid_clip_cluster.h \ -quad_grid_clip_manager.h \ -quad_grid.h \ -quad_tree.h \ -radix_sort.h \ -raw_skin.h \ -raw_skinned.h \ -ray_mesh.h \ -register_3d.h \ -render_trav.h \ -root_model.h \ -scene_group.h \ -scene.h \ -scene_user.h \ -scissor.h \ -seg_remanence.h \ -seg_remanence_shape.h \ -shader.h \ -shadow_map.h \ -shadow_map_manager.h \ -shadow_poly_receiver.h \ -shadow_skin.h \ -shape_bank.h \ -shape_bank_user.h \ -shape.h \ -shape_info.h \ -shifted_triangle_cache.h \ -skeleton_model.h \ -skeleton_shape.h \ -skeleton_spawn_script.h \ -skeleton_weight.h \ -static_quad_grid.h \ -stripifier.h \ -surface_light_grid.h \ -tangent_space_build.h \ -target_anim_ctrl.h \ -tess_block.h \ -tessellation.h \ -tess_face_priority_list.h \ -tess_list.h \ -text_context.h \ -text_context_user.h \ -texture_blank.h \ -texture_blend.h \ -texture_bloom.h \ -texture_bump.h \ -texture_cube.h \ -texture_dlm.h \ -texture_emboss.h \ -texture_far.h \ -texture_file.h \ -texture_font.h \ -texture_grouped.h \ -texture.h \ -texture_mem.h \ -texture_multi_file.h \ -texture_near.h \ -texture_user.h \ -tile_bank.h \ -tile_color.h \ -tile_element.h \ -tile_far_bank.h \ -tile_light_influence.h \ -tile_lumel.h \ -tile_noise_map.h \ -tile_vegetable_desc.h \ -track_bezier.h \ -track.h \ -track_keyframer.h \ -track_sampled_common.h \ -track_sampled_quat.h \ -track_sampled_quat_small_header.h \ -track_sampled_vector.h \ -track_tcb.h \ -transformable.h \ -transform.h \ -transform_shape.h \ -trav_scene.h \ -u_3d_mouse_listener.h \ -u_animation.h \ -u_animation_set.h \ -u_bone.h \ -u_camera.h \ -u_cloud_scape.h \ -u_driver.h \ -u_instance_group.h \ -u_instance.h \ -u_instance_material.h \ -u_landscape.h \ -u_light.h \ -u_material.h \ -u_particle_system_instance.h \ -u_particle_system_sound.h \ -u_play_list.h \ -u_play_list_manager.h \ -u_point_light.h \ -u_ps_sound_impl.h \ -u_ps_sound_interface.h \ -u_scene.h \ -u_shape_bank.h \ -u_shape.h \ -u_skeleton.h \ -u_text_context.h \ -u_texture.h \ -u_track.h \ -u_transformable.h \ -u_transform.h \ -u_visual_collision_entity.h \ -u_visual_collision_manager.h \ -u_visual_collision_mesh.h \ -u_water_env_map.h \ -u_water.h \ -vegetable_blend_layer_model.h \ -vegetable_clip_block.h \ -vegetable_def.h \ -vegetable.h \ -vegetable_instance_group.h \ -vegetable_light_ex.h \ -vegetable_manager.h \ -vegetable_quadrant.h \ -vegetable_shape.h \ -vegetable_sort_block.h \ -vegetable_uv8.h \ -vegetablevb_allocator.h \ -vertex_buffer.h \ -vertex_buffer_heap.h \ -vertex_program.h \ -vertex_program_parse.h \ -vertex_stream_manager.h \ -viewport.h \ -visual_collision_entity.h \ -visual_collision_entity_user.h \ -visual_collision_manager.h \ -visual_collision_manager_user.h \ -visual_collision_mesh.h \ -water_env_map.h \ -water_env_map_user.h \ -water_height_map.h \ -water_model.h \ -water_pool_manager.h \ -water_shape.h \ -zone_corner_smoother.h \ -zone.h \ -zone_lighter.h \ -zone_manager.h \ -zone_search.h \ -zone_smoother.h \ -zone_symmetrisation.h \ -zone_tgt_smoother.h - -# End of Makefile.am diff --git a/code/nel/include/nel/3d/computed_string.h b/code/nel/include/nel/3d/computed_string.h index 16fe70fcb..914fa324e 100644 --- a/code/nel/include/nel/3d/computed_string.h +++ b/code/nel/include/nel/3d/computed_string.h @@ -27,12 +27,16 @@ #include #include +namespace NLMISC { + +class CMatrix; + +} namespace NL3D { class CTextureFont; -class CMatrix; struct CComputedString; // *************************************************************************** diff --git a/code/nel/include/nel/3d/cube_grid.h b/code/nel/include/nel/3d/cube_grid.h index 427aed624..483ea8000 100644 --- a/code/nel/include/nel/3d/cube_grid.h +++ b/code/nel/include/nel/3d/cube_grid.h @@ -227,7 +227,7 @@ void CCubeGrid::compile() // build the _StaticGrid _StaticGrids[i].build(_Grids[i]); // And reset the grid. contReset is necessary to clean the CBlockMemory. - contReset(_Grids[i]); + NLMISC::contReset(_Grids[i]); } // done diff --git a/code/nel/include/nel/3d/index_buffer.h b/code/nel/include/nel/3d/index_buffer.h index 320a06020..7beaafe0b 100644 --- a/code/nel/include/nel/3d/index_buffer.h +++ b/code/nel/include/nel/3d/index_buffer.h @@ -782,7 +782,7 @@ inline void CIndexBuffer::lock (CIndexBufferRead &accessor, uint first, uint las // *************************************************************************** -inline void CIndexBuffer::unlock (uint first, uint end) +inline void CIndexBuffer::unlock (uint /* first */, uint /* end */) { nlassertex (_LockCounter!=0, ("Index buffer not locked")); nlassert (_LockedBuffer || (!isResident() && _NonResidentIndexes.empty())); diff --git a/code/nel/include/nel/3d/instance_lighter.h b/code/nel/include/nel/3d/instance_lighter.h index 7b1dbb6e7..8b1ccf80a 100644 --- a/code/nel/include/nel/3d/instance_lighter.h +++ b/code/nel/include/nel/3d/instance_lighter.h @@ -147,7 +147,7 @@ public: static void addTriangles (const IShape &shape, const NLMISC::CMatrix& modelMT, std::vector& triangleArray, sint instanceId); // Progress callback - virtual void progress (const char *message, float progress) {} + virtual void progress (const char * /* message */, float /* progress */) {} /// \name Static PointLights mgt. diff --git a/code/nel/include/nel/3d/ps_attrib.h b/code/nel/include/nel/3d/ps_attrib.h index fc17dc787..83549a7b0 100644 --- a/code/nel/include/nel/3d/ps_attrib.h +++ b/code/nel/include/nel/3d/ps_attrib.h @@ -96,7 +96,7 @@ public: try { newStart = new uint8[sizeof(T) * capacity + (1 << snapPower)]; - T *newTab = (T *) ( (uint) (newStart + (1 << snapPower)) & ~((1 << snapPower) - 1)); // snap to a page + T *newTab = (T *) ( (size_t) (newStart + (1 << snapPower)) & ~((1 << snapPower) - 1)); // snap to a page diff --git a/code/nel/include/nel/3d/ps_attrib_maker_bin_op.h b/code/nel/include/nel/3d/ps_attrib_maker_bin_op.h index 4370fdeaa..285fa9b26 100644 --- a/code/nel/include/nel/3d/ps_attrib_maker_bin_op.h +++ b/code/nel/include/nel/3d/ps_attrib_maker_bin_op.h @@ -157,7 +157,7 @@ public: } /// return true if an operation is supported. The default support all ops - bool supportOp(CPSBinOp::BinOp op) { return true; } + bool supportOp(CPSBinOp::BinOp /* op */) { return true; } /// get the current operator CPSBinOp::BinOp getOp(void) const { return _Op; } diff --git a/code/nel/include/nel/3d/ps_attrib_maker_bin_op_inline.h b/code/nel/include/nel/3d/ps_attrib_maker_bin_op_inline.h index c25c051a5..8d98a1544 100644 --- a/code/nel/include/nel/3d/ps_attrib_maker_bin_op_inline.h +++ b/code/nel/include/nel/3d/ps_attrib_maker_bin_op_inline.h @@ -57,13 +57,13 @@ inline CPlaneBasis PSBinOpModulate(CPlaneBasis p1, CPlaneBasis p2) } template <> -inline CPlaneBasis PSBinOpAdd(CPlaneBasis p1, CPlaneBasis p2) +inline CPlaneBasis PSBinOpAdd(CPlaneBasis /* p1 */, CPlaneBasis /* p2 */) { nlassert(0); // not allowed for now return CPlaneBasis(NLMISC::CVector::Null); } template <> -inline CPlaneBasis PSBinOpSubtract(CPlaneBasis p1, CPlaneBasis p2) +inline CPlaneBasis PSBinOpSubtract(CPlaneBasis /* p1 */, CPlaneBasis /* p2 */) { nlassert(0); // not allowed for now return CPlaneBasis(NLMISC::CVector::Null); diff --git a/code/nel/include/nel/3d/ps_attrib_maker_iterators.h b/code/nel/include/nel/3d/ps_attrib_maker_iterators.h index 8729ffb10..d9cfbcdd3 100644 --- a/code/nel/include/nel/3d/ps_attrib_maker_iterators.h +++ b/code/nel/include/nel/3d/ps_attrib_maker_iterators.h @@ -60,7 +60,7 @@ namespace NL3D { GET_INLINE float get() const { return float(rand() * (1 / double(RAND_MAX))); } // this may be optimized with a table... void advance() {} - void advance(uint quantity) {} + void advance(uint /* quantity */) {} }; /// this iterator just return the same value @@ -69,7 +69,7 @@ namespace NL3D float Value; GET_INLINE float get() const { return Value; } void advance() {} - void advance(uint quantity) {} + void advance(uint /* quantity */) {} }; /// iterator that use dist to compute the value diff --git a/code/nel/include/nel/3d/ps_direction.h b/code/nel/include/nel/3d/ps_direction.h index 609278a80..eb8bbd827 100644 --- a/code/nel/include/nel/3d/ps_direction.h +++ b/code/nel/include/nel/3d/ps_direction.h @@ -38,7 +38,7 @@ public : /** The direction is taken from a global vector defined in the particle system * NULL or an empty string as a name disable the use of a global value */ - virtual void enableGlobalVectorValue(const std::string &name) {} + virtual void enableGlobalVectorValue(const std::string &/* name */) {} virtual std::string getGlobalVectorValueName() const { return ""; } }; diff --git a/code/nel/include/nel/3d/ps_edit.h b/code/nel/include/nel/3d/ps_edit.h index d3e1a53de..8342868f8 100644 --- a/code/nel/include/nel/3d/ps_edit.h +++ b/code/nel/include/nel/3d/ps_edit.h @@ -65,13 +65,13 @@ struct IPSMover virtual bool supportNonUniformScaling(void) const { NL_PS_FUNC(supportNonUniformScaling); return false ; } // set the scale of the object (uniform scale). The default does nothing - virtual void setScale(uint32 index, float scale) {} ; + virtual void setScale(uint32 /* index */, float /* scale */) {} // set a non uniform scale (if supported) - virtual void setScale(uint32 index, const NLMISC::CVector &s) { NL_PS_FUNC(setScale); } + virtual void setScale(uint32 /* index */, const NLMISC::CVector &/* s */) { NL_PS_FUNC(setScale); } // get the scale of the object - virtual NLMISC::CVector getScale(uint32 index) const { NL_PS_FUNC(getScale); return NLMISC::CVector(1.f, 1.f, 1.f) ; } + virtual NLMISC::CVector getScale(uint32 /* index */) const { NL_PS_FUNC(getScale); return NLMISC::CVector(1.f, 1.f, 1.f) ; } /** some object may not store a whole matrix (e.g planes) * this return true if only a normal is needed to set the orientation of the object @@ -79,10 +79,10 @@ struct IPSMover virtual bool onlyStoreNormal(void) const { NL_PS_FUNC(onlyStoreNormal); return false ; } /// if the object only needs a normal, this return the normal. If not, is return (0, 0, 0) - virtual NLMISC::CVector getNormal(uint32 index) { NL_PS_FUNC(getNormal); return NLMISC::CVector::Null ; } + virtual NLMISC::CVector getNormal(uint32 /* index */) { NL_PS_FUNC(getNormal); return NLMISC::CVector::Null ; } /// if the object only stores a normal, this set the normal of the object. Otherwise it has no effect - virtual void setNormal(uint32 index, NLMISC::CVector n) { NL_PS_FUNC(setNormal); } + virtual void setNormal(uint32 /* index */, NLMISC::CVector /* n */) { NL_PS_FUNC(setNormal); } // set a new orthogonal matrix for the object virtual void setMatrix(uint32 index, const NLMISC::CMatrix &m) = 0 ; diff --git a/code/nel/include/nel/3d/ps_force.h b/code/nel/include/nel/3d/ps_force.h index 5e961dc43..15e28948a 100644 --- a/code/nel/include/nel/3d/ps_force.h +++ b/code/nel/include/nel/3d/ps_force.h @@ -87,9 +87,9 @@ public: * 'accumulate' set to false. * NB : works only with integrable forces */ - virtual void integrate(float date, CPSLocated *src, uint32 startIndex, uint32 numObjects, NLMISC::CVector *destPos = NULL, NLMISC::CVector *destSpeed = NULL, - bool accumulate = false, - uint posStride = sizeof(NLMISC::CVector), uint speedStride = sizeof(NLMISC::CVector) + virtual void integrate(float /* date */, CPSLocated * /* src */, uint32 /* startIndex */, uint32 /* numObjects */, NLMISC::CVector * /* destPos */ = NULL, NLMISC::CVector * /* destSpeed */ = NULL, + bool /* accumulate */ = false, + uint /* posStride */ = sizeof(NLMISC::CVector), uint /* speedStride */ = sizeof(NLMISC::CVector) ) const { nlassert(0); // not an integrable force @@ -100,11 +100,11 @@ public: * If the start date is lower than the creation date, the initial position is used * NB : works only with integrable forces */ - virtual void integrateSingle(float startDate, float deltaT, uint numStep, - const CPSLocated *src, uint32 indexInLocated, - NLMISC::CVector *destPos, - bool accumulate = false, - uint posStride = sizeof(NLMISC::CVector)) const + virtual void integrateSingle(float /* startDate */, float /* deltaT */, uint /* numStep */, + const CPSLocated * /* src */, uint32 /* indexInLocated */, + NLMISC::CVector * /* destPos */, + bool /* accumulate */ = false, + uint /* posStride */ = sizeof(NLMISC::CVector)) const { nlassert(0); // not an integrable force } @@ -170,7 +170,7 @@ public: virtual void setIntensityScheme(CPSAttribMaker *scheme); // deriver have here the opportunity to setup the functor object. The default does nothing - virtual void setupFunctor(uint32 indexInLocated) { } + virtual void setupFunctor(uint32 /* indexInLocated */) { } /// get the attribute maker for a non constant intensity CPSAttribMaker *getIntensityScheme(void) { return _IntensityScheme; } @@ -493,22 +493,22 @@ public: #ifdef NL_OS_WINDOWS __forceinline #endif - void operator() (const NLMISC::CVector &pos, NLMISC::CVector &speed, float invMass) - { + void operator() (const NLMISC::CVector &/* pos */, NLMISC::CVector &speed, float invMass) + { speed -= (CParticleSystem::EllapsedTime * _K * invMass * speed); - } + } - virtual void serial(NLMISC::IStream &f) throw(NLMISC::EStream) - { - f.serialVersion(1); - // we don't save intensity info : it is saved by the owning object (and set before each use of this functor) - } + virtual void serial(NLMISC::IStream &f) throw(NLMISC::EStream) + { + f.serialVersion(1); + // we don't save intensity info : it is saved by the owning object (and set before each use of this functor) + } - // get the friction coefficient - float getK(void) const { return _K; } + // get the friction coefficient + float getK(void) const { return _K; } - // set the friction coefficient - void setK(float coeff) { _K = coeff; } + // set the friction coefficient + void setK(float coeff) { _K = coeff; } protected: // the friction coeff float _K; @@ -630,7 +630,7 @@ struct CPSTurbulForceFunc #ifdef NL_OS_WINDOWS __forceinline #endif - void operator() (const NLMISC::CVector &pos, NLMISC::CVector &speed, float invMass) + void operator() (const NLMISC::CVector &/* pos */, NLMISC::CVector &/* speed */, float /* invMass */) { nlassert(0); diff --git a/code/nel/include/nel/3d/static_quad_grid.h b/code/nel/include/nel/3d/static_quad_grid.h index 7890e12f4..5a0383c9e 100644 --- a/code/nel/include/nel/3d/static_quad_grid.h +++ b/code/nel/include/nel/3d/static_quad_grid.h @@ -172,7 +172,7 @@ template void CStaticQuadGrid::build(CQuadGrid &quadGrid) { clear(); - contReset(_Grid); + NLMISC::contReset(_Grid); // Copy from quadGrid, and init quads _Size= quadGrid.getSize(); diff --git a/code/nel/include/nel/3d/track_tcb.h b/code/nel/include/nel/3d/track_tcb.h index 8daf5cc2a..fc9c227e4 100644 --- a/code/nel/include/nel/3d/track_tcb.h +++ b/code/nel/include/nel/3d/track_tcb.h @@ -218,7 +218,7 @@ protected: date*= previous->OODeltaTime; NLMISC::clamp(date, 0,1); - date = ease(previous, date); + date = this->ease(previous, date); float hb[4]; this->computeHermiteBasis(date, hb); @@ -242,7 +242,7 @@ protected: ITrackKeyFramer::compile(); // Ease Precompute. - compileTCBEase(this->_MapKey, this->getLoopMode()); + this->compileTCBEase(this->_MapKey, this->getLoopMode()); // Tangents Precompute. @@ -314,7 +314,7 @@ private: float ksm,ksp,kdm,kdp; // compute tangents factors. - computeTCBFactors(key, timeBefore, time, timeAfter, rangeDelta, firstKey, endKey, isLoop, ksm,ksp,kdm,kdp); + this->computeTCBFactors(key, timeBefore, time, timeAfter, rangeDelta, firstKey, endKey, isLoop, ksm,ksp,kdm,kdp); // Delta. TKeyValueType delm, delp; @@ -413,7 +413,7 @@ public: ITrackKeyFramer::compile(); // Ease Precompute. - compileTCBEase(_MapKey, getLoopMode()); + this->compileTCBEase(_MapKey, getLoopMode()); TMapTimeCKey::iterator it; TMapTimeCKey::iterator itNext; diff --git a/code/nel/include/nel/3d/vertex_buffer.h b/code/nel/include/nel/3d/vertex_buffer.h index 83b2b90ea..a64ec0c2c 100644 --- a/code/nel/include/nel/3d/vertex_buffer.h +++ b/code/nel/include/nel/3d/vertex_buffer.h @@ -1223,7 +1223,7 @@ inline void CVertexBuffer::lock (CVertexBufferRead &accessor, uint first, uint l // -------------------------------------------------- -inline void CVertexBuffer::unlock (uint first, uint end) +inline void CVertexBuffer::unlock (uint /* first */, uint /* end */) { nlassertex (_LockCounter!=0, ("Vertex buffer not locked")); nlassert (_LockedBuffer || (!isResident() && _NonResidentVertices.empty())); diff --git a/code/nel/include/nel/Makefile.am b/code/nel/include/nel/Makefile.am deleted file mode 100644 index 7e4686f14..000000000 --- a/code/nel/include/nel/Makefile.am +++ /dev/null @@ -1,13 +0,0 @@ -# -# - -MAINTAINERCLEANFILES = Makefile.in - -DIST_SUBDIRS = net 3d pacs sound misc georges ligo - -SUBDIRS = @NEL_SUBDIRS@ - -includedir = ${prefix}/include/nel - -# End of Makefile.am - diff --git a/code/nel/include/nel/cegui/Makefile.am b/code/nel/include/nel/cegui/Makefile.am deleted file mode 100644 index ba2530dff..000000000 --- a/code/nel/include/nel/cegui/Makefile.am +++ /dev/null @@ -1,11 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2001-08-01 08:45:06 valignat Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -includedir = ${prefix}/include/nel/cegui - -include_HEADERS = nelrenderer.h nelresourceprovider.h neltexture.h - -# End of Makefile.am diff --git a/code/nel/include/nel/georges/Makefile.am b/code/nel/include/nel/georges/Makefile.am deleted file mode 100644 index 153e9b102..000000000 --- a/code/nel/include/nel/georges/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ -# -# - -MAINTAINERCLEANFILES = Makefile.in - -includedir = ${prefix}/include/nel/georges - -include_HEADERS = load_form.h \ - u_form_dfn.h \ - u_form_elm.h \ - u_form.h \ - u_form_loader.h \ - u_type.h - -# End of Makefile.am diff --git a/code/nel/include/nel/ligo/Makefile.am b/code/nel/include/nel/ligo/Makefile.am deleted file mode 100644 index 48fb3c54b..000000000 --- a/code/nel/include/nel/ligo/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -# -# - -MAINTAINERCLEANFILES = Makefile.in - -includedir = ${prefix}/include/nel/ligo - -include_HEADERS = ligo_config.h \ - primitive_class.h \ - primitive_configuration.h \ - primitive.h \ - primitive_utils.h - -# End of Makefile.am diff --git a/code/nel/include/nel/misc/Makefile.am b/code/nel/include/nel/misc/Makefile.am deleted file mode 100644 index 75bde6b95..000000000 --- a/code/nel/include/nel/misc/Makefile.am +++ /dev/null @@ -1,143 +0,0 @@ -# -# - -MAINTAINERCLEANFILES = Makefile.in - -includedir = ${prefix}/include/nel/misc - -include_HEADERS = aabbox.h \ - algo.h \ - app_context.h \ - array_2d.h \ - async_file_manager.h \ - big_file.h \ - bitmap.h \ - bit_mem_stream.h \ - bit_set.h \ - block_memory.h \ - bsphere.h \ - buf_fifo.h \ - check_fpu.h \ - class_id.h \ - class_registry.h \ - command.h \ - common.h \ - config_file.h \ - contiguous_block_allocator.h \ - co_task.h \ - cpu_time_stat.h \ - debug.h \ - di_event_emitter.h \ - diff_tool.h \ - displayer.h \ - dummy_window.h \ - dynloadlib.h \ - eid_translator.h \ - entity_id.h \ - enum_bitset.h \ - eval_num_expr.h \ - event_emitter.h \ - event_emitter_multi.h \ - event_listener.h \ - event_server.h \ - events.h \ - factory.h \ - fast_floor.h \ - fast_mem.h \ - file.h \ - fixed_size_allocator.h \ - game_device_events.h \ - game_device.h \ - geom_ext.h \ - grid_traversal.h \ - gtk_displayer.h \ - heap_memory.h \ - hierarchical_timer.h \ - historic.h \ - i18n.h \ - input_device.h \ - input_device_manager.h \ - input_device_server.h \ - inter_window_msg_queue.h \ - i_xml.h \ - keyboard_device.h \ - line.h \ - log.h \ - matrix.h \ - md5.h \ - mem_displayer.h \ - mem_stream.h \ - mouse_device.h \ - mouse_smoother.h \ - mutable_container.h \ - mutex.h \ - noise_value.h \ - object_arena_allocator.h \ - object_vector.h \ - o_xml.h \ - path.h \ - plane.h \ - plane_inline.h \ - polygon.h \ - pool_memory.h \ - progress_callback.h \ - p_thread.h \ - quad.h \ - quat.h \ - random.h \ - reader_writer.h \ - rect.h \ - report.h \ - resource_ptr.h \ - resource_ptr_inline.h \ - rgba.h \ - sha1.h \ - shared_memory.h \ - sheet_id.h \ - singleton.h \ - smart_ptr.h \ - smart_ptr_inline.h \ - speaker_listener.h \ - sstring.h \ - static_map.h \ - stl_block_allocator.h \ - stl_block_list.h \ - stop_watch.h \ - stream.h \ - stream_inline.h \ - string_common.h \ - string_conversion.h \ - string_id_array.h \ - string_mapper.h \ - string_stream.h \ - system_info.h \ - task_manager.h \ - tds.h \ - thread.h \ - time_nl.h \ - timeout_assertion_thread.h \ - traits_nl.h \ - triangle.h \ - twin_map.h \ - types_nl.h \ - ucstring.h \ - uv.h \ - value_smoother.h \ - variable.h \ - vector_2d.h \ - vector_2f.h \ - vectord.h \ - vectord_inline.h \ - vector.h \ - vector_h.h \ - vector_inline.h \ - win32_util.h \ - win_displayer.h \ - window_displayer.h \ - win_event_emitter.h \ - win_thread.h \ - win_tray.h \ - words_dictionary.h \ - xml_pack.h - -# End of Makefile.am diff --git a/code/nel/include/nel/misc/bit_mem_stream.h b/code/nel/include/nel/misc/bit_mem_stream.h index 8a1af34cc..b294d5454 100644 --- a/code/nel/include/nel/misc/bit_mem_stream.h +++ b/code/nel/include/nel/misc/bit_mem_stream.h @@ -209,6 +209,8 @@ public: { #ifdef NL_DEBUG std::swap(_DbgData, other._DbgData); +#else + nlunreferenced(other); #endif } @@ -225,6 +227,10 @@ public: TBMSSerialInfo serialItem( bitpos, size, type, _DbgData->NextSymbol ); _DbgData->List.push_back( serialItem ); _DbgData->NextSymbol = NULL; +#else + nlunreferenced(bitpos); + nlunreferenced(size); + nlunreferenced(type); #endif } @@ -258,6 +264,10 @@ public: nlwarning( "Missing reserve() corresponding to poke()" ); } _DbgData->NextSymbol = NULL; +#else + nlunreferenced(bitpos); + nlunreferenced(size); + nlunreferenced(type); #endif } @@ -266,6 +276,8 @@ public: { #ifdef NL_DEBUG _DbgData->NextSymbol = symbol; +#else + nlunreferenced(symbol); #endif } @@ -308,6 +320,8 @@ public: } //nlassert( bitpos < (*_List)[_CurrentBrowsedItem].BitPos ); // occurs if stream overflow } +#else + nlunreferenced(bitpos); #endif *eventId = -1; return std::string(); @@ -380,7 +394,7 @@ public: * If you are using the stream only in output mode, you can use this method as a faster version * of clear() *if you don't serialize pointers*. */ - void resetBufPos() + virtual void resetBufPos() { // This is ensured in CMemStream::CMemStream() and CMemStream::clear() //if ( (!isReading()) && _Buffer.empty() ) @@ -463,7 +477,7 @@ public: } /// See doc in CMemStream::bufferToFill() - uint8 *bufferToFill( uint32 msgsize ) + virtual uint8 *bufferToFill( uint32 msgsize ) { _FreeBits = 8; _DbgInfo.clear(); @@ -640,7 +654,7 @@ public: virtual void serial(ucstring &b); virtual void serial(CBitMemStream &b) { serialMemStream(b); } - virtual void serialMemStream(CBitMemStream &b); + virtual void serialMemStream(CMemStream &b); //@} @@ -787,11 +801,7 @@ void displayBitStream( const CBitMemStream& msg, sint beginbitpos, sint endbitpo inline std::string CBMSDbgInfo::getEventLegendAtBitPos( CBitMemStream& bms, sint32 eventId ) { #ifdef NL_DEBUG - if ( eventId == -1 ) - { - return std::string(); - } - else + if ( eventId != -1 ) { nlassert( eventId < (sint32)_DbgData->List.size() ); TBMSSerialInfo& serialItem = _DbgData->List[eventId]; // works only with a vector! @@ -800,8 +810,11 @@ inline std::string CBMSDbgInfo::getEventLegendAtBitPos( CBitMemStream& bms, sint bms.getSerialItem( serialItem ).c_str(), (serialItem.Symbol!=NULL)?serialItem.Symbol:"" ); } #else - return std::string(); + nlunreferenced(bms); + nlunreferenced(eventId); #endif + + return std::string(); } diff --git a/code/nel/include/nel/misc/common.h b/code/nel/include/nel/misc/common.h index 42bf56d3b..fa9272386 100644 --- a/code/nel/include/nel/misc/common.h +++ b/code/nel/include/nel/misc/common.h @@ -342,6 +342,8 @@ std::string secondsToHumanReadable (uint32 time); /// Get a bytes or time in string format and convert it in seconds or bytes uint32 fromHumanReadable (const std::string &str); +/// Add digit grouping seperator to if value >= 10 000. Assumes input is numerical string. +std::string formatThousands(const std::string& s); /// This function executes a program in the background and returns instantly (used for example to launch services in AES). /// The program will be launched in the current directory diff --git a/code/nel/include/nel/misc/diff_tool.h b/code/nel/include/nel/misc/diff_tool.h index 64989fcaf..2f291c6a0 100644 --- a/code/nel/include/nel/misc/diff_tool.h +++ b/code/nel/include/nel/misc/diff_tool.h @@ -501,8 +501,8 @@ namespace STRING_MANAGER // callback->onSwap(it - context.Reference.begin(), refCount, context); callback->onSwap(index, refCount, context); -// swap(*it, context.Reference[refCount]); - swap(context.Reference[index], context.Reference[refCount]); +// std::swap(*it, context.Reference[refCount]); + std::swap(context.Reference[index], context.Reference[refCount]); } } else if (getHashValue(context.Addition, addCount) != getHashValue(context.Reference, refCount)) diff --git a/code/nel/include/nel/misc/eid_translator.h b/code/nel/include/nel/misc/eid_translator.h index 695f7724e..9937b72fd 100644 --- a/code/nel/include/nel/misc/eid_translator.h +++ b/code/nel/include/nel/misc/eid_translator.h @@ -146,6 +146,8 @@ public: TAdditionalInfoCb EntityInfoCallback; + static void removeShardFromName(ucstring& name); + private: // get all eid for a user using the user name or the user id void getByUser (uint32 uid, std::vector &res); diff --git a/code/nel/include/nel/misc/event_emitter.h b/code/nel/include/nel/misc/event_emitter.h index e678c2674..5c547d07f 100644 --- a/code/nel/include/nel/misc/event_emitter.h +++ b/code/nel/include/nel/misc/event_emitter.h @@ -49,7 +49,7 @@ public: * \param server */ virtual void submitEvents(CEventServer & server, bool allWindows) = 0; - + /** * Instruct the event emitter to send CGDMouseMove instead of CEventMouseMove. * diff --git a/code/nel/include/nel/misc/fast_id_map.h b/code/nel/include/nel/misc/fast_id_map.h new file mode 100644 index 000000000..dbd05bc76 --- /dev/null +++ b/code/nel/include/nel/misc/fast_id_map.h @@ -0,0 +1,151 @@ +/** + * \file fast_id_map.h + * \brief CFastIdMap + * \date 2012-04-10 19:28GMT + * \author Jan Boon (Kaetemi) + * CFastIdMap + */ + +/* + * Copyright (C) 2012 by authors + * + * This file is part of RYZOM CORE. + * RYZOM CORE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * RYZOM CORE 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with RYZOM CORE. If not, see + * . + */ + +#ifndef NLMISC_FAST_ID_MAP_H +#define NLMISC_FAST_ID_MAP_H +#include + +// STL includes + +// NeL includes +#include + +// Project includes + +namespace NLMISC { + +/** + * \brief CFastIdMap + * \date 2012-04-10 19:28GMT + * \author Jan Boon (Kaetemi) + * This template allows for assigning unique uint32 identifiers to pointers. + * Useful when externally only exposing an identifier, when pointers may have been deleted. + * The identifier is made from two uint16's, one being the direct index in the identifier vector, + * and the other being a verification value that is increased when the identifier index is re-used. + * TId must be a typedef of uint32. + * TValue should be a pointer. + */ +template +class CFastIdMap +{ +protected: + struct CIdInfo + { + CIdInfo() { } + CIdInfo(uint16 verification, uint16 next, TValue value) : + Verification(verification), Next(next), Value(value) { } + uint16 Verification; + uint16 Next; + TValue Value; + }; + /// ID memory + std::vector m_Ids; + /// Nb of assigned IDs + uint m_Size; + /// Assigned IDs + uint16 m_Next; + +public: + CFastIdMap(TValue defaultValue) : m_Size(0), m_Next(0) + { + // Id 0 will contain the last available unused id, and be 0 if no more unused id's are available + // defaultValue will be returned when the ID is not found + m_Ids.push_back(CIdInfo(0, 0, defaultValue)); + } + + virtual ~CFastIdMap() { } + + void clear() + { + m_Ids.resize(1); + m_Ids[0].Next = 0; + } + + TId insert(TValue value) + { + // get next unused index + uint16 idx = m_Ids[0].Next; + if (idx == 0) + { + // size of used elements must be equal to the vector size minus one, when everything is allocated + nlassert((m_Ids.size() - 1) == m_Size); + + idx = m_Ids.size(); + uint16 verification = rand(); + m_Ids.push_back(CIdInfo(verification, m_Next, value)); + m_Next = idx; + return (TId)(((uint32)verification) << 16) & idx; + } + else + { + m_Ids[0].Next = m_Ids[idx].Next; // restore the last unused id + m_Ids[idx].Value = value; + return (TId)(((uint32)m_Ids[idx].Verification) << 16) & idx; + } + } + + void erase(TId id) + { + uint32 idx = ((uint32)id) & 0xFFFF; + uint16 verification = (uint16)(((uint32)id) >> 16); + if (m_Ids[idx].Verification == verification) + { + m_Ids[idx].Value = m_Ids[0].Value; // clean value for safety + m_Ids[idx].Verification = (uint16)(((uint32)m_Ids[idx].Verification + 1) & 0xFFFF); // change verification value, allow overflow :) + m_Ids[idx].Next = m_Ids[0].Next; // store the last unused id + m_Ids[0].Next = (uint16)idx; // set this as last unused id + } + else + { + nlwarning("Invalid ID"); + } + } + + TValue get(TId id) + { + uint32 idx = ((uint32)id) & 0xFFFF; + uint16 verification = (uint16)(((uint32)id) >> 16); + if (m_Ids[idx].Verification == verification) + { + return m_Ids[idx].Value; + } + else + { + nldebug("Invalid ID"); + return m_Ids[0].Value; + } + } + + inline uint size() { return m_Size; } + +}; /* class CFastIdMap */ + +} /* namespace NLMISC */ + +#endif /* #ifndef NLMISC_FAST_ID_MAP_H */ + +/* end of file */ diff --git a/code/nel/include/nel/misc/mem_stream.h b/code/nel/include/nel/misc/mem_stream.h index 2102129dd..1da99a48d 100644 --- a/code/nel/include/nel/misc/mem_stream.h +++ b/code/nel/include/nel/misc/mem_stream.h @@ -301,7 +301,7 @@ public: * If you are using the stream only in output mode, you can use this method as a faster version * of clear() *if you don't serialize pointers*. */ - void resetBufPos() { _Buffer.Pos = 0; } + virtual void resetBufPos() { _Buffer.Pos = 0; } /** * Resize the message buffer and fill data at position 0. @@ -340,7 +340,7 @@ public: * fill it with raw data using any filling function (warning: don't fill more than 'msgsize' * bytes!), then you are ready to read, using serial(), the data you've just filled. */ - uint8 *bufferToFill( uint32 msgsize ) + virtual uint8 *bufferToFill( uint32 msgsize ) { #ifdef NL_DEBUG nlassert( isReading() ); diff --git a/code/nel/include/nel/misc/mutex.h b/code/nel/include/nel/misc/mutex.h index e2205d666..1c01a6134 100644 --- a/code/nel/include/nel/misc/mutex.h +++ b/code/nel/include/nel/misc/mutex.h @@ -717,11 +717,11 @@ class CAutoMutex TMutex &_Mutex; // forbeden copy or assignent - CAutoMutex(const CAutoMutex &other) + CAutoMutex(const CAutoMutex &/* other */) { } - CAutoMutex &operator = (const CAutoMutex &other) + CAutoMutex &operator = (const CAutoMutex &/* other */) { return *this; } diff --git a/code/nel/include/nel/misc/p_thread.h b/code/nel/include/nel/misc/p_thread.h index cd027aa37..7e6a4d5a5 100644 --- a/code/nel/include/nel/misc/p_thread.h +++ b/code/nel/include/nel/misc/p_thread.h @@ -36,6 +36,12 @@ namespace NLMISC { class CPThread : public IThread { public: + enum TThreadState + { + ThreadStateNone, + ThreadStateRunning, + ThreadStateFinished, + }; /// Constructor CPThread( IRunnable *runnable, uint32 stackSize); @@ -48,6 +54,7 @@ public: virtual void wait(); virtual bool setCPUMask(uint64 cpuMask); virtual uint64 getCPUMask(); + virtual void setPriority(TThreadPriority priority); virtual std::string getUserName(); virtual IRunnable *getRunnable() @@ -58,10 +65,11 @@ public: /// Internal use IRunnable *Runnable; -private: - uint8 _State; // 0=not created, 1=started, 2=finished - uint32 _StackSize; + TThreadState _State; pthread_t _ThreadHandle; + +private: + uint32 _StackSize; }; /** diff --git a/code/nel/include/nel/misc/speaker_listener.h b/code/nel/include/nel/misc/speaker_listener.h index 7481e12c8..5f9f86352 100644 --- a/code/nel/include/nel/misc/speaker_listener.h +++ b/code/nel/include/nel/misc/speaker_listener.h @@ -118,7 +118,7 @@ namespace NLMISC _Speaker->registerListener(this); } - void unregisterListener(ISpeaker *speaker) + void unregisterListener(ISpeaker * /* speaker */) { nlassert(_Speaker != NULL); _Speaker->unregisterListener(this); diff --git a/code/nel/include/nel/misc/sstring.h b/code/nel/include/nel/misc/sstring.h index 513c681c9..fc17d67f5 100644 --- a/code/nel/include/nel/misc/sstring.h +++ b/code/nel/include/nel/misc/sstring.h @@ -55,7 +55,7 @@ public: /// ctor CSString(int i,const char *fmt="%d"); /// ctor - CSString(unsigned u,const char *fmt="%u"); + CSString(uint32 u,const char *fmt="%u"); /// ctor CSString(double d,const char *fmt="%f"); /// ctor @@ -76,14 +76,14 @@ public: char back() const; /// Return the n left hand most characters of a string - CSString left(unsigned count) const; + CSString left(uint32 count) const; /// Return the n right hand most characters of a string - CSString right(unsigned count) const; + CSString right(uint32 count) const; /// Return the string minus the n left hand most characters of a string - CSString leftCrop(unsigned count) const; + CSString leftCrop(uint32 count) const; /// Return the string minus the n right hand most characters of a string - CSString rightCrop(unsigned count) const; + CSString rightCrop(uint32 count) const; /// Return sub string up to but not including first instance of given character, starting at 'iterator' /// on exit 'iterator' indexes first character after extracted string segment @@ -116,9 +116,9 @@ public: /// Return sub string remaining after the first word CSString tailFromFirstWord() const; /// Count the number of words in a string - unsigned countWords() const; + uint32 countWords() const; /// Extract the given word - CSString word(unsigned idx) const; + CSString word(uint32 idx) const; /// Return first word or quote-encompassed sub-string - can remove extracted sub-string from source string CSString firstWordOrWords(bool truncateThis=false,bool useSlashStringEscape=true,bool useRepeatQuoteStringEscape=true); @@ -127,9 +127,9 @@ public: /// Return sub string following first word (or quote-encompassed sub-string) CSString tailFromFirstWordOrWords(bool useSlashStringEscape=true,bool useRepeatQuoteStringEscape=true) const; /// Count the number of words (or quote delimited sub-strings) in a string - unsigned countWordOrWords(bool useSlashStringEscape=true,bool useRepeatQuoteStringEscape=true) const; + uint32 countWordOrWords(bool useSlashStringEscape=true,bool useRepeatQuoteStringEscape=true) const; /// Extract the given words (or quote delimited sub-strings) - CSString wordOrWords(unsigned idx,bool useSlashStringEscape=true,bool useRepeatQuoteStringEscape=true) const; + CSString wordOrWords(uint32 idx,bool useSlashStringEscape=true,bool useRepeatQuoteStringEscape=true) const; /// Return first line - can remove extracted line from source string CSString firstLine(bool truncateThis=false); @@ -138,9 +138,9 @@ public: /// Return sub string remaining after the first line CSString tailFromFirstLine() const; /// Count the number of lines in a string - unsigned countLines() const; + uint32 countLines() const; /// Extract the given line - CSString line(unsigned idx) const; + CSString line(uint32 idx) const; /// A handy utility routine for knowing if a character is a white space character or not (' ','\t','\n','\r',26) static bool isWhiteSpace(char c); @@ -377,7 +377,7 @@ public: /// assignment operator CSString& operator=(int i); /// assignment operator - CSString& operator=(unsigned u); + CSString& operator=(uint32 u); /// assignment operator CSString& operator=(double d); @@ -561,7 +561,7 @@ inline CSString::CSString(int i,const char *fmt) *this=buf; } -inline CSString::CSString(unsigned u,const char *fmt) +inline CSString::CSString(uint32 u,const char *fmt) { char buf[1024]; sprintf(buf,fmt,u); @@ -611,26 +611,26 @@ inline char CSString::back() const return (*this)[size()-1]; } -inline CSString CSString::right(unsigned count) const +inline CSString CSString::right(uint32 count) const { if (count>=size()) return *this; return substr(size()-count); } -inline CSString CSString::rightCrop(unsigned count) const +inline CSString CSString::rightCrop(uint32 count) const { if (count>=size()) return CSString(); return substr(0,size()-count); } -inline CSString CSString::left(unsigned count) const +inline CSString CSString::left(uint32 count) const { return substr(0,count); } -inline CSString CSString::leftCrop(unsigned count) const +inline CSString CSString::leftCrop(uint32 count) const { if (count>=size()) return CSString(); @@ -639,7 +639,7 @@ inline CSString CSString::leftCrop(unsigned count) const inline CSString CSString::splitToWithIterator(char c,uint32& iterator) const { - unsigned i; + uint32 i; CSString result; for (i=iterator;i !!! - CSTLBlockAllocator(CBlockMemory *bm) + CSTLBlockAllocator(CBlockMemory * /* bm */) { } /// copy ctor diff --git a/code/nel/include/nel/misc/thread.h b/code/nel/include/nel/misc/thread.h index 82ef78a13..983e6b12a 100644 --- a/code/nel/include/nel/misc/thread.h +++ b/code/nel/include/nel/misc/thread.h @@ -68,6 +68,16 @@ public: } }; +/// Thread priorities, numbering follows Win32 for now +enum TThreadPriority +{ + ThreadPriorityLowest = -2, + ThreadPriorityLow = -1, + ThreadPriorityNormal = 0, + ThreadPriorityHigh = 1, + ThreadPriorityHighest = 2, +}; + /** * Thread base interface, must be implemented for all OS * \author Vianney Lecroart @@ -119,6 +129,9 @@ public: */ virtual uint64 getCPUMask()=0; + /// Set the thread priority. Thread must have been started before. + virtual void setPriority(TThreadPriority priority) = 0; + /** * Get the thread user name. * Under Linux return thread owner, under windows return the name of the logon user. diff --git a/code/nel/include/nel/misc/win_thread.h b/code/nel/include/nel/misc/win_thread.h index a2e8b5389..628942dde 100644 --- a/code/nel/include/nel/misc/win_thread.h +++ b/code/nel/include/nel/misc/win_thread.h @@ -49,6 +49,7 @@ public: virtual void wait(); virtual bool setCPUMask(uint64 cpuMask); virtual uint64 getCPUMask(); + virtual void setPriority(TThreadPriority priority); virtual std::string getUserName(); virtual IRunnable *getRunnable() @@ -69,8 +70,7 @@ public: void suspend(); // Resume the thread. No-op if already resumed void resume(); - // set priority as defined by "SetThreadpriority" - void setPriority(int priority); + // Priority boost void enablePriorityBoost(bool enabled); /// private use diff --git a/code/nel/include/nel/net/Makefile.am b/code/nel/include/nel/net/Makefile.am deleted file mode 100644 index 7a5dfe1be..000000000 --- a/code/nel/include/nel/net/Makefile.am +++ /dev/null @@ -1,48 +0,0 @@ -# -# - -MAINTAINERCLEANFILES = Makefile.in - -includedir = ${prefix}/include/nel/net - -include_HEADERS = admin.h \ - buf_client.h \ - buf_net_base.h \ - buf_server.h \ - buf_sock.h \ - callback_client.h \ - callback_net_base.h \ - callback_server.h \ - cvar_log_filter.h \ - dummy_tcp_sock.h \ - email.h \ - inet_address.h \ - listen_sock.h \ - login_client.h \ - login_cookie.h \ - login_server.h \ - message.h \ - message_recorder.h \ - module_builder_parts.h \ - module_common.h \ - module_gateway.h \ - module.h \ - module_manager.h \ - module_message.h \ - module_socket.h \ - naming_client.h \ - net_displayer.h \ - net_log.h \ - net_manager.h \ - pacs_client.h \ - service.h \ - sock.h \ - tcp_sock.h \ - transport_class.h \ - udp_sim_sock.h \ - udp_sock.h \ - unified_network.h \ - unitime.h \ - varpath.h - -# End of Makefile.am diff --git a/code/nel/include/nel/net/module_builder_parts.h b/code/nel/include/nel/net/module_builder_parts.h index b080e521f..d2e653315 100644 --- a/code/nel/include/nel/net/module_builder_parts.h +++ b/code/nel/include/nel/net/module_builder_parts.h @@ -188,8 +188,8 @@ namespace NLNET // unused interceptors std::string fwdBuildModuleManifest() const { return std::string(); } - void fwdOnModuleSecurityChange(NLNET::IModuleProxy *moduleProxy) {} - bool fwdOnProcessModuleMessage(NLNET::IModuleProxy *sender, const NLNET::CMessage &message) {return false;} + void fwdOnModuleSecurityChange(NLNET::IModuleProxy * /* moduleProxy */) {} + bool fwdOnProcessModuleMessage(NLNET::IModuleProxy * /* sender */, const NLNET::CMessage &/* message */) {return false;} // check module up void fwdOnModuleUp(NLNET::IModuleProxy *moduleProxy) diff --git a/code/nel/include/nel/net/transport_class.h b/code/nel/include/nel/net/transport_class.h index 11161d7cd..f1110e492 100644 --- a/code/nel/include/nel/net/transport_class.h +++ b/code/nel/include/nel/net/transport_class.h @@ -75,7 +75,7 @@ public: enum TProp { PropUInt8, PropUInt16, PropUInt32, PropUInt64, PropSInt8, PropSInt16, PropSInt32, PropSInt64, - PropBool, PropFloat, PropDouble, PropString, PropDataSetRow, PropSheetId, PropUKN }; + PropBool, PropFloat, PropDouble, PropString, PropDataSetRow, PropSheetId, PropUCString, PropUKN }; // PropBool, PropFloat, PropDouble, PropString, PropDataSetRow, PropEntityId, PropSheetId, PropUKN }; @@ -160,6 +160,7 @@ public: case PropString: nlassert(sizeof(T) == sizeof (std::string)); break; // case PropEntityId: nlassert(sizeof(T) == sizeof (NLMISC::CEntityId)); break; case PropSheetId: nlassert(sizeof(T) == sizeof (NLMISC::CSheetId)); break; + case PropUCString: nlassert(sizeof(T) == sizeof (ucstring)); break; default: nlerror ("property %s have unknown type %d", name.c_str(), type); } @@ -334,7 +335,7 @@ protected: T *Value; - virtual void serialDefaultValue (NLMISC::IStream &f) + virtual void serialDefaultValue (NLMISC::IStream &/* f */) { // nothing } diff --git a/code/nel/include/nel/pacs/Makefile.am b/code/nel/include/nel/pacs/Makefile.am deleted file mode 100644 index 7160ec65c..000000000 --- a/code/nel/include/nel/pacs/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -# -# - -MAINTAINERCLEANFILES = Makefile.in - -includedir = ${prefix}/include/nel/pacs - -include_HEADERS = u_collision_desc.h \ - u_global_position.h \ - u_global_retriever.h \ - u_move_container.h \ - u_move_primitive.h \ - u_primitive_block.h \ - u_retriever_bank.h - -# End of Makefile.am - diff --git a/code/nel/include/nel/sound/Makefile.am b/code/nel/include/nel/sound/Makefile.am deleted file mode 100644 index 77dd246a6..000000000 --- a/code/nel/include/nel/sound/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ -# -# - -MAINTAINERCLEANFILES = Makefile.in - -includedir = ${prefix}/include/nel/sound - -include_HEADERS = sound_animation.h \ - sound_anim_manager.h \ - sound_anim_marker.h \ - u_audio_mixer.h \ - u_listener.h \ - u_source.h - -# End of Makefile.am diff --git a/code/nel/include/nel/sound/audio_decoder.h b/code/nel/include/nel/sound/audio_decoder.h new file mode 100644 index 000000000..3babc1de1 --- /dev/null +++ b/code/nel/include/nel/sound/audio_decoder.h @@ -0,0 +1,107 @@ +/** + * \file audio_decoder.h + * \brief IAudioDecoder + * \date 2012-04-11 09:34GMT + * \author Jan Boon (Kaetemi) + * IAudioDecoder + */ + +/* + * Copyright (C) 2008-2012 by authors + * + * This file is part of RYZOM CORE. + * RYZOM CORE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * RYZOM CORE 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with RYZOM CORE. If not, see + * . + */ + +#ifndef NLSOUND_AUDIO_DECODER_H +#define NLSOUND_AUDIO_DECODER_H +#include + +// STL includes + +// NeL includes + +// Project includes + +namespace NLSOUND { + +/** + * \brief IAudioDecoder + * \date 2008-08-30 11:38GMT + * \author Jan Boon (Kaetemi) + * IAudioDecoder is only used by the driver implementation to stream + * music files into a readable format (it's a simple decoder interface). + * You should not call these functions (getSongTitle) on nlsound or user level, + * as a driver might have additional music types implemented. + * TODO: Split IAudioDecoder into IAudioDecoder (actual decoding) and IMediaDemuxer (stream splitter), and change the interface to make more sense. + * TODO: Allow user application to register more decoders. + * TODO: Look into libavcodec for decoding audio? + */ +class IAudioDecoder +{ +private: + // pointers + /// Stream from file created by IAudioDecoder + NLMISC::IStream *_InternalStream; + +public: + IAudioDecoder(); + virtual ~IAudioDecoder(); + + /// Create a new music buffer, may return NULL if unknown type, destroy with delete. Filepath lookup done here. If async is true, it will stream from hd, else it will load in memory first. + static IAudioDecoder *createAudioDecoder(const std::string &filepath, bool async, bool loop); + + /// Create a new music buffer from a stream, type is file extension like "ogg" etc. + static IAudioDecoder *createAudioDecoder(const std::string &type, NLMISC::IStream *stream, bool loop); + + /// Get information on a music file (only artist and title at the moment). + static bool getInfo(const std::string &filepath, std::string &artist, std::string &title); + + /// Get audio/container extensions that are currently supported by the nel sound library. + static void getMusicExtensions(std::vector &extensions); + + /// Return if a music extension is supported by the nel sound library. + static bool isMusicExtensionSupported(const std::string &extension); + + /// Get how many bytes the music buffer requires for output minimum. + virtual uint32 getRequiredBytes() = 0; + + /// Get an amount of bytes between minimum and maximum (can be lower than minimum if at end). + virtual uint32 getNextBytes(uint8 *buffer, uint32 minimum, uint32 maximum) = 0; + + /// Get the amount of channels (2 is stereo) in output. + virtual uint8 getChannels() = 0; + + /// Get the samples per second (often 44100) in output. + virtual uint getSamplesPerSec() = 0; + + /// Get the bits per sample (often 16) in output. + virtual uint8 getBitsPerSample() = 0; + + /// Get if the music has ended playing (never true if loop). + virtual bool isMusicEnded() = 0; + + /// Get the total time in seconds. + virtual float getLength() = 0; + + /// Set looping + virtual void setLooping(bool loop) = 0; +}; /* class IAudioDecoder */ + +} /* namespace NLSOUND */ + +#endif /* #ifndef NLSOUND_AUDIO_DECODER_H */ + +/* end of file */ diff --git a/code/nel/include/nel/sound/driver/music_buffer_vorbis.h b/code/nel/include/nel/sound/audio_decoder_vorbis.h similarity index 50% rename from code/nel/include/nel/sound/driver/music_buffer_vorbis.h rename to code/nel/include/nel/sound/audio_decoder_vorbis.h index 978f393da..bd7e45019 100644 --- a/code/nel/include/nel/sound/driver/music_buffer_vorbis.h +++ b/code/nel/include/nel/sound/audio_decoder_vorbis.h @@ -1,21 +1,33 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero 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 Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . +/** + * \file audio_decoder_vorbis.h + * \brief CAudioDecoderVorbis + * \date 2012-04-11 09:35GMT + * \author Jan Boon (Kaetemi) + * CAudioDecoderVorbis + */ -#ifndef NLSOUND_MUSIC_BUFFER_VORBIS_H -#define NLSOUND_MUSIC_BUFFER_VORBIS_H +/* + * Copyright (C) 2008-2012 by authors + * + * This file is part of RYZOM CORE. + * RYZOM CORE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * RYZOM CORE 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with RYZOM CORE. If not, see + * . + */ + +#ifndef NLSOUND_AUDIO_DECODER_VORBIS_H +#define NLSOUND_AUDIO_DECODER_VORBIS_H +#include // STL includes @@ -30,21 +42,20 @@ #endif // NeL includes +#include // Project includes -#include "music_buffer.h" -namespace NLSOUND -{ +namespace NLSOUND { /** - * \brief CMusicBufferVorbis + * \brief CAudioDecoderVorbis * \date 2008-08-30 11:38GMT * \author Jan Boon (Kaetemi) - * CMusicBufferVorbis - * Create trough IMusicBuffer, type "ogg" + * CAudioDecoderVorbis + * Create trough IAudioDecoder, type "ogg" */ -class CMusicBufferVorbis : public IMusicBuffer +class CAudioDecoderVorbis : public IAudioDecoder { protected: // outside pointers @@ -59,8 +70,8 @@ protected: sint32 _StreamOffset; sint32 _StreamSize; public: - CMusicBufferVorbis(NLMISC::IStream *stream, bool loop); - virtual ~CMusicBufferVorbis(); + CAudioDecoderVorbis(NLMISC::IStream *stream, bool loop); + virtual ~CAudioDecoderVorbis(); inline NLMISC::IStream *getStream() { return _Stream; } inline sint32 getStreamSize() { return _StreamSize; } inline sint32 getStreamOffset() { return _StreamOffset; } @@ -78,7 +89,7 @@ public: virtual uint8 getChannels(); /// Get the samples per second (often 44100) in output. - virtual uint32 getSamplesPerSec(); + virtual uint getSamplesPerSec(); /// Get the bits per sample (often 16) in output. virtual uint8 getBitsPerSample(); @@ -89,12 +100,12 @@ public: /// Get the total time in seconds. virtual float getLength(); - /// Get the size of uncompressed data in bytes. - virtual uint getUncompressedSize(); -}; /* class CMusicBufferVorbis */ + /// Set looping + virtual void setLooping(bool loop); +}; /* class CAudioDecoderVorbis */ } /* namespace NLSOUND */ -#endif /* #ifndef NLSOUND_MUSIC_BUFFER_VORBIS_H */ +#endif /* #ifndef NLSOUND_AUDIO_DECODER_VORBIS_H */ /* end of file */ diff --git a/code/nel/include/nel/sound/audio_mixer_user.h b/code/nel/include/nel/sound/audio_mixer_user.h index 7cd0de051..9c9fd5c86 100644 --- a/code/nel/include/nel/sound/audio_mixer_user.h +++ b/code/nel/include/nel/sound/audio_mixer_user.h @@ -34,6 +34,11 @@ #include "nel/sound/mixing_track.h" #include "nel/sound/sound.h" #include "nel/sound/music_channel_fader.h" +#include "nel/sound/group_controller_root.h" + +// Current version is 2, Ryzom Live uses 1 +// Provided to allow compatibility with old binary files +#define NLSOUND_SHEET_VERSION_BUILT 1 namespace NLLIGO { class CLigoConfig; @@ -51,26 +56,6 @@ namespace NLSOUND { class CMusicSoundManager; class IReverbEffect; -/// Hasher functor for hashed container with pointer key. -template -struct THashPtr : public std::unary_function -{ - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; - size_t operator () (const Pointer &ptr) const - { - //CHashSet::hasher h; - // transtype the pointer into int then hash it - //return h.operator()(uint(uintptr_t(ptr))); - return (size_t)(uintptr_t)ptr; - } - inline bool operator() (const Pointer &ptr1, const Pointer &ptr2) const - { - // delegate the work to someone else as well? - return (uintptr_t)ptr1 < (uintptr_t)ptr2; - } -}; - /** * Implementation of UAudioMixer * @@ -197,6 +182,9 @@ public: /// Get a TSoundId from a name (returns NULL if not found) virtual TSoundId getSoundId( const NLMISC::TStringId &name ); + /// Gets the group controller for the given group tree path with separator '/', if it doesn't exist yet it will be created. + /// Examples: "music", "effects", "dialog", "music/background", "music/loading", "music/player", etcetera + virtual UGroupController *getGroupController(const std::string &path); /** Add a logical sound source (returns NULL if name not found). * If spawn is true, the source will auto-delete after playing. If so, the return USource* pointer @@ -204,9 +192,9 @@ public: * pass a callback function that will be called (if not NULL) just before deleting the spawned * source. */ - virtual USource *createSource( const NLMISC::TStringId &name, bool spawn=false, TSpawnEndCallback cb=NULL, void *cbUserParam = NULL, NL3D::CCluster *cluster = 0, CSoundContext *context = 0 ); + virtual USource *createSource( const NLMISC::TStringId &name, bool spawn=false, TSpawnEndCallback cb=NULL, void *cbUserParam = NULL, NL3D::CCluster *cluster = 0, CSoundContext *context = 0, UGroupController *groupController = NULL); /// Add a logical sound source (by sound id). To remove a source, just delete it. See createSource(const char*) - virtual USource *createSource( TSoundId id, bool spawn=false, TSpawnEndCallback cb=NULL, void *cbUserParam = NULL, NL3D::CCluster *cluster = 0, CSoundContext *context = 0 ); + virtual USource *createSource( TSoundId id, bool spawn=false, TSpawnEndCallback cb=NULL, void *cbUserParam = NULL, NL3D::CCluster *cluster = 0, CSoundContext *context = 0, UGroupController *groupController = NULL); /// Add a source which was created by an EnvSound void addSource( CSourceCommon *source ); /** Delete a logical sound source. If you don't call it, the source will be auto-deleted @@ -242,6 +230,8 @@ public: virtual uint getSourcesInstanceCount() const { return (uint)_Sources.size(); } /// Return the number of playing sources (slow) virtual uint getPlayingSourcesCount() const; + uint countPlayingSimpleSources() const; // debug + uint countSimpleSources() const; // debug /// Return the number of available tracks virtual uint getAvailableTracksCount() const; /// Return the number of used tracks @@ -415,6 +405,7 @@ public: /// Add a source for play as possible (for non discadable sound) void addSourceWaitingForPlay(CSourceCommon *source); + void removeSourceWaitingForPlay(CSourceCommon *source); /// Read all user controled var sheets void initUserVar(); @@ -431,8 +422,6 @@ private: // utility function for automatic sample bank loading. bool tryToLoadSampleBank(const std::string &sampleName); - - typedef CHashSet > TSourceContainer; typedef CHashSet > TMixerUpdateContainer; typedef CHashMap, THashPtr > TBufferToSourceContainer; // typedef std::multimap TTimedEventContainer; @@ -565,6 +554,9 @@ private: // Instance of the background music manager CMusicSoundManager *_BackgroundMusicManager; + /// Group controller + CGroupControllerRoot _GroupController; + public: struct TSampleBankHeader { diff --git a/code/nel/include/nel/sound/background_source.h b/code/nel/include/nel/sound/background_source.h index cdf044776..14ea1cf53 100644 --- a/code/nel/include/nel/sound/background_source.h +++ b/code/nel/include/nel/sound/background_source.h @@ -36,7 +36,7 @@ class CBackgroundSource : public CSourceCommon , public CAudioMixerUser::IMixerU { public: /// Constructor - CBackgroundSource (CBackgroundSound *backgroundSound=NULL, bool spawn=false, TSpawnEndCallback cb=0, void *cbUserParam = 0, NL3D::CCluster *cluster = 0); + CBackgroundSource (CBackgroundSound *backgroundSound=NULL, bool spawn=false, TSpawnEndCallback cb=0, void *cbUserParam = 0, NL3D::CCluster *cluster = 0, CGroupController *groupController = NULL); /// Destructor ~CBackgroundSource (); diff --git a/code/nel/include/nel/sound/complex_source.h b/code/nel/include/nel/sound/complex_source.h index d27b5af5b..d1135b1ad 100644 --- a/code/nel/include/nel/sound/complex_source.h +++ b/code/nel/include/nel/sound/complex_source.h @@ -34,7 +34,7 @@ class CComplexSource : public CSourceCommon, public CAudioMixerUser::IMixerEvent { public: /// Constructor - CComplexSource (CComplexSound *soundPattern=NULL, bool spawn=false, TSpawnEndCallback cb=0, void *cbUserParam = 0, NL3D::CCluster *cluster = 0); + CComplexSource (CComplexSound *soundPattern=NULL, bool spawn=false, TSpawnEndCallback cb=0, void *cbUserParam = 0, NL3D::CCluster *cluster = 0, CGroupController *groupController = NULL); /// Destructor ~CComplexSource (); diff --git a/code/nel/include/nel/sound/containers.h b/code/nel/include/nel/sound/containers.h new file mode 100644 index 000000000..bd4fe7fb9 --- /dev/null +++ b/code/nel/include/nel/sound/containers.h @@ -0,0 +1,67 @@ +/** + * \file containers.h + * \brief CContainers + * \date 2012-04-10 13:57GMT + * \author Unknown (Unknown) + * CContainers + */ + +/* + * Copyright (C) 2012 by authors + * + * This file is part of RYZOM CORE. + * RYZOM CORE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * RYZOM CORE 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with RYZOM CORE. If not, see + * . + */ + +#ifndef NLSOUND_CONTAINERS_H +#define NLSOUND_CONTAINERS_H +#include + +// STL includes + +// NeL includes + +// Project includes + +namespace NLSOUND { + class CSourceCommon; + +/// Hasher functor for hashed container with pointer key. +template +struct THashPtr : public std::unary_function +{ + static const size_t bucket_size = 4; + static const size_t min_buckets = 8; + size_t operator () (const Pointer &ptr) const + { + //CHashSet::hasher h; + // transtype the pointer into int then hash it + //return h.operator()(uint(uintptr_t(ptr))); + return (size_t)(uintptr_t)ptr; + } + inline bool operator() (const Pointer &ptr1, const Pointer &ptr2) const + { + // delegate the work to someone else as well? + return (uintptr_t)ptr1 < (uintptr_t)ptr2; + } +}; + +typedef CHashSet > TSourceContainer; + +} /* namespace NLSOUND */ + +#endif /* #ifndef NLSOUND_CONTAINERS_H */ + +/* end of file */ diff --git a/code/nel/include/nel/sound/driver/buffer.h b/code/nel/include/nel/sound/driver/buffer.h index 5d488f1c7..27a8d9f00 100644 --- a/code/nel/include/nel/sound/driver/buffer.h +++ b/code/nel/include/nel/sound/driver/buffer.h @@ -48,6 +48,8 @@ public: /// Intel/DVI ADPCM format, only available for 1 channel at 16 bits per sample, encoded at 4 bits per sample. /// This is only implemented in the DSound and XAudio2 driver. FormatDviAdpcm = 11, + /// No format set. Used when a TBufferFormat value has not been set to any value yet. + FormatNotSet = (~0), }; /// The storage mode of this buffer. Also controls the X-RAM extension of OpenAL. enum TStorageMode diff --git a/code/nel/include/nel/sound/driver/music_buffer.h b/code/nel/include/nel/sound/driver/music_buffer.h deleted file mode 100644 index 571e27a31..000000000 --- a/code/nel/include/nel/sound/driver/music_buffer.h +++ /dev/null @@ -1,119 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero 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 Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef NLSOUND_MUSIC_BUFFER_H -#define NLSOUND_MUSIC_BUFFER_H - -namespace NLMISC -{ - class IStream; - class CIFile; -} - -namespace NLSOUND -{ - - /* - * TODO: Streaming - * Some kind of decent streaming functionality, to get rid of the current music implementation. Audio decoding should be done on nlsound level. IBuffer needs a writable implementation, it allocates and owns the data memory, which can be written to by nlsound. When buffer is written, a function needs to be called to 'finalize' the buffer (so it can be submitted to OpenAL for example). - * Required interface functions, IBuffer: - * /// Allocate a new writable buffer. If this buffer was already allocated, the previous data is released. - * /// May return NULL if the format or frequency is not supported by the driver. - * uint8 *IBuffer::openWritable(uint size, TBufferFormat bufferFormat, uint8 channels, uint8 bitsPerSample, uint32 frequency); - * /// Tell that you are done writing to this buffer, so it can be copied over to hardware if needed. - * /// If keepLocal is true, a local copy of the buffer will be kept (so allocation can be re-used later). - * /// keepLocal overrides the OptionLocalBufferCopy flag. The buffer can use this function internally. - * void IBuffer::lockWritable(bool keepLocal); - * Required interface functions, ISource: - * /// Enable or disable the streaming facilities. - * void ISource::setStreaming(bool streaming); - * /// Submits a new buffer to the stream. A buffer of 100ms length is optimal for streaming. - * /// Should be called by a thread which checks countStreamingBuffers every 100ms - * void ISource::submitStreamingBuffer(IBuffer *buffer); - * /// Returns the number of buffers that are queued (includes playing buffer). 3 buffers is optimal. - * uint ISource::countStreamingBuffers(); - * Other required interface functions, ISource: - * /// Enable or disable 3d calculations (to send directly to speakers). - * void ISource::set3DMode(bool enable); - * For compatibility with music trough fmod, ISoundDriver: - * /// Returns true if the sound driver has a native implementation of IMusicChannel (bad!). - * /// If this returns false, use the nlsound music channel, which goes trough Ctrack/ISource, - * /// The nlsound music channel requires support for IBuffer/ISource streaming. - * bool ISoundDriver::hasMusicChannel(); - */ - -/** - * \brief IMusicBuffer - * \date 2008-08-30 11:38GMT - * \author Jan Boon (Kaetemi) - * IMusicBuffer is only used by the driver implementation to stream - * music files into a readable format (it's a simple decoder interface). - * You should not call these functions (getSongTitle) on nlsound or user level, - * as a driver might have additional music types implemented. - * TODO: Change IMusicBuffer to IAudioDecoder, and change the interface to make more sense. - * TODO: Allow user application to register more decoders. - * TODO: Look into libavcodec for decoding audio. - */ -class IMusicBuffer -{ -private: - // pointers - /// Stream from file created by IMusicBuffer - NLMISC::IStream *_InternalStream; - -public: - IMusicBuffer(); - virtual ~IMusicBuffer(); - - /// Create a new music buffer, may return NULL if unknown type, destroy with delete. Filepath lookup done here. If async is true, it will stream from hd, else it will load in memory first. - static IMusicBuffer *createMusicBuffer(const std::string &filepath, bool async, bool loop); - - /// Create a new music buffer from a stream, type is file extension like "ogg" etc. - static IMusicBuffer *createMusicBuffer(const std::string &type, NLMISC::IStream *stream, bool loop); - - /// Get information on a music file (only artist and title at the moment). - static bool getInfo(const std::string &filepath, std::string &artist, std::string &title); - - /// Get how many bytes the music buffer requires for output minimum. - virtual uint32 getRequiredBytes() =0; - - /// Get an amount of bytes between minimum and maximum (can be lower than minimum if at end). - virtual uint32 getNextBytes(uint8 *buffer, uint32 minimum, uint32 maximum) =0; - - /// Get the amount of channels (2 is stereo) in output. - virtual uint8 getChannels() =0; - - /// Get the samples per second (often 44100) in output. - virtual uint32 getSamplesPerSec() =0; - - /// Get the bits per sample (often 16) in output. - virtual uint8 getBitsPerSample() =0; - - /// Get if the music has ended playing (never true if loop). - virtual bool isMusicEnded() =0; - - /// Get the total time in seconds. - virtual float getLength() =0; - - /// Get the size of uncompressed data in bytes. - virtual uint getUncompressedSize() =0; -}; /* class IMusicBuffer */ - -} /* namespace NLSOUND */ - -#endif /* #ifndef NLSOUND_MUSIC_BUFFER_H */ - -/* end of file */ diff --git a/code/nel/include/nel/sound/driver/music_channel.h b/code/nel/include/nel/sound/driver/music_channel.h index 9878744c5..116865628 100644 --- a/code/nel/include/nel/sound/driver/music_channel.h +++ b/code/nel/include/nel/sound/driver/music_channel.h @@ -45,6 +45,9 @@ public: /// Stop the music previously loaded and played (the Memory is also freed) virtual void stop() =0; + /// Makes sure any resources are freed, but keeps available for next play call + virtual void reset() =0; + /// Pause the music previously loaded and played (the Memory is not freed) virtual void pause() =0; diff --git a/code/nel/include/nel/sound/driver/sound_driver.h b/code/nel/include/nel/sound/driver/sound_driver.h index 193026a42..c9551f16b 100644 --- a/code/nel/include/nel/sound/driver/sound_driver.h +++ b/code/nel/include/nel/sound/driver/sound_driver.h @@ -39,9 +39,11 @@ namespace NLSOUND #endif /* - * Sound sample format + * Deprecated sound sample format. + * For compatibility with old code. + * Do not modify. */ -enum TSampleFormat { SampleFormatUnknown, Mono8, Mono16ADPCM, Mono16, Stereo8, Stereo16 }; +enum TSampleFormat { Mono8, Mono16ADPCM, Mono16, Stereo8, Stereo16, SampleFormatUnknown = (~0) }; /** * Abstract sound driver (implemented in sound driver dynamic library) diff --git a/code/nel/include/nel/sound/driver/source.h b/code/nel/include/nel/sound/driver/source.h index 1858e6f24..b43c83914 100644 --- a/code/nel/include/nel/sound/driver/source.h +++ b/code/nel/include/nel/sound/driver/source.h @@ -353,7 +353,7 @@ public: * In streaming mode, the time spent during buffer outruns is not * counted towards the playback time, and the playback time is * be the current time position in the entire submitted queue. - * When using static buffers, the result is the tot time that the + * When using static buffers, the result is the total time that the * attached buffer has been playing. If the source is looping, the * time will be the total of all playbacks of the buffer. * When the source is stopped, this will return the time where the @@ -397,7 +397,7 @@ public: virtual void setSourceRelativeMode(bool mode = true) = 0; /// Get the source relative mode virtual bool getSourceRelativeMode() const = 0; - /// Set the min and max distances (default: 1, MAX_FLOAT) (3D mode only) + /// Set the min and max distances (default: 1, sqrt(MAX_FLOAT)) (3D mode only) virtual void setMinMaxDistances(float mindist, float maxdist, bool deferred = true) = 0; /// Get the min and max distances virtual void getMinMaxDistances(float& mindist, float& maxdist) const = 0; diff --git a/code/nel/include/nel/sound/group_controller.h b/code/nel/include/nel/sound/group_controller.h new file mode 100644 index 000000000..25b7034b6 --- /dev/null +++ b/code/nel/include/nel/sound/group_controller.h @@ -0,0 +1,102 @@ +/** + * \file group_controller.h + * \brief CGroupController + * \date 2012-04-10 09:29GMT + * \author Jan Boon (Kaetemi) + * CGroupController + */ + +/* + * Copyright (C) 2012 by authors + * + * This file is part of RYZOM CORE. + * RYZOM CORE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * RYZOM CORE 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with RYZOM CORE. If not, see + * . + */ + +#ifndef NLSOUND_GROUP_CONTROLLER_H +#define NLSOUND_GROUP_CONTROLLER_H +#include + +// STL includes +#include +#include + +// NeL includes +#include +#include +#include + +// Project includes + +namespace NLSOUND { + class CGroupControllerRoot; + +/** + * \brief CGroupController + * \date 2012-04-10 09:29GMT + * \author Jan Boon (Kaetemi) + * CGroupController + */ +class CGroupController : public UGroupController +{ +public: + friend class CGroupControllerRoot; + +private: + CGroupController *m_Parent; + std::map m_Children; + + /// Gain as set by the interface + float m_Gain; + + /// Gain including parent gain + float m_FinalGain; + + int m_NbSourcesInclChild; + TSourceContainer m_Sources; + +public: + CGroupController(CGroupController *parent); + + /// \name UGroupController + //@{ + virtual void setGain(float gain) { NLMISC::clamp(gain, 0.0f, 1.0f); if (m_Gain != gain) { m_Gain = gain; updateSourceGain(); } } + virtual float getGain() { return m_Gain; } + //@} + + inline float getFinalGain() const { return m_FinalGain; } + + void addSource(CSourceCommon *source); + void removeSource(CSourceCommon *source); + + virtual std::string getPath(); + +protected: + virtual ~CGroupController(); // subnodes can only be deleted by the root + +private: + inline float calculateTotalGain() { return m_Gain; } + virtual void calculateFinalGain(); + virtual void increaseSources(); + virtual void decreaseSources(); + void updateSourceGain(); + +}; /* class CGroupController */ + +} /* namespace NLSOUND */ + +#endif /* #ifndef NLSOUND_GROUP_CONTROLLER_H */ + +/* end of file */ diff --git a/code/nel/include/nel/sound/group_controller_root.h b/code/nel/include/nel/sound/group_controller_root.h new file mode 100644 index 000000000..2081fa28a --- /dev/null +++ b/code/nel/include/nel/sound/group_controller_root.h @@ -0,0 +1,70 @@ +/** + * \file group_controller_root.h + * \brief CGroupControllerRoot + * \date 2012-04-10 09:44GMT + * \author Jan Boon (Kaetemi) + * CGroupControllerRoot + */ + +/* + * Copyright (C) 2012 by authors + * + * This file is part of RYZOM CORE. + * RYZOM CORE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * RYZOM CORE 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with RYZOM CORE. If not, see + * . + */ + +#ifndef NLSOUND_GROUP_CONTROLLER_ROOT_H +#define NLSOUND_GROUP_CONTROLLER_ROOT_H +#include + +// STL includes + +// NeL includes +#include + +// Project includes +#include + +namespace NLSOUND { + +/** + * \brief CGroupControllerRoot + * \date 2012-04-10 09:44GMT + * \author Jan Boon (Kaetemi) + * CGroupControllerRoot + */ +class CGroupControllerRoot : public CGroupController, public NLMISC::CManualSingleton +{ +public: + CGroupControllerRoot(); + virtual ~CGroupControllerRoot(); + + /// Gets the group controller in a certain path with separator '/', if it doesn't exist yet it will be created. + CGroupController *getGroupController(const std::string &path); + +protected: + virtual std::string getPath(); + virtual void calculateFinalGain(); + virtual void increaseSources(); + virtual void decreaseSources(); + static bool isReservedName(const std::string &nodeName); + +}; /* class CGroupControllerRoot */ + +} /* namespace NLSOUND */ + +#endif /* #ifndef NLSOUND_GROUP_CONTROLLER_ROOT_H */ + +/* end of file */ diff --git a/code/nel/include/nel/sound/music_channel_fader.h b/code/nel/include/nel/sound/music_channel_fader.h index 4e6d35de4..8513c21e5 100644 --- a/code/nel/include/nel/sound/music_channel_fader.h +++ b/code/nel/include/nel/sound/music_channel_fader.h @@ -87,6 +87,8 @@ public: void init(ISoundDriver *soundDriver); void release(); + void reset(); + void update(); // time in seconds inline bool isInitOk() { return _SoundDriver != NULL; } diff --git a/code/nel/include/nel/sound/music_source.h b/code/nel/include/nel/sound/music_source.h index a23547c6c..be09c1837 100644 --- a/code/nel/include/nel/sound/music_source.h +++ b/code/nel/include/nel/sound/music_source.h @@ -35,7 +35,7 @@ class CMusicSource : public CSourceCommon { public: /// Constructor - CMusicSource (class CMusicSound *sound=NULL, bool spawn=false, TSpawnEndCallback cb=0, void *cbUserParam = 0, NL3D::CCluster *cluster = 0); + CMusicSource (class CMusicSound *sound=NULL, bool spawn=false, TSpawnEndCallback cb=0, void *cbUserParam = 0, NL3D::CCluster *cluster = 0, CGroupController *groupController = NULL); /// Destructor ~CMusicSource (); diff --git a/code/nel/include/nel/sound/simple_source.h b/code/nel/include/nel/sound/simple_source.h index ac2af0099..c330fd7fa 100644 --- a/code/nel/include/nel/sound/simple_source.h +++ b/code/nel/include/nel/sound/simple_source.h @@ -40,7 +40,7 @@ class CSimpleSource : public CSourceCommon, public CAudioMixerUser::IMixerEvent { public: /// Constructor - CSimpleSource(CSimpleSound *simpleSound = NULL, bool spawn = false, TSpawnEndCallback cb = 0, void *cbUserParam = 0, NL3D::CCluster *cluster = 0); + CSimpleSource(CSimpleSound *simpleSound = NULL, bool spawn = false, TSpawnEndCallback cb = 0, void *cbUserParam = 0, NL3D::CCluster *cluster = 0, CGroupController *groupController = NULL); /// Destructor virtual ~CSimpleSource(); @@ -97,14 +97,7 @@ public: * 1.0 -> no attenuation * values > 1 (amplification) not supported by most drivers */ - virtual void setGain( float gain ); - /** Set the gain amount (value inside [0, 1]) to map between 0 and the nominal gain - * (which is getSource()->getGain()). Does nothing if getSource() is null. - */ - virtual void setRelativeGain( float gain ); - /** Shift the frequency. 1.0f equals identity, each reduction of 50% equals a pitch shift - * of one octave. 0 is not a legal value. - */ + virtual void updateFinalGain(); virtual void setPitch( float pitch ); /// Set the source relative mode. If true, positions are interpreted relative to the listener position (default: false) virtual void setSourceRelativeMode( bool mode ); @@ -149,6 +142,8 @@ private: /// True when the sound is played muted and until the mixer event notifying the end. bool _PlayMuted; + bool _WaitingForPlay; + }; diff --git a/code/nel/include/nel/sound/sound.h b/code/nel/include/nel/sound/sound.h index 2112a0e73..e9d4f755c 100644 --- a/code/nel/include/nel/sound/sound.h +++ b/code/nel/include/nel/sound/sound.h @@ -30,6 +30,7 @@ namespace NLSOUND { class ISoundDriver; class IBuffer; class CSound; +class CGroupController; /// Sound names hash map @@ -60,8 +61,9 @@ public: SOUND_COMPLEX, SOUND_BACKGROUND, SOUND_CONTEXT, - SOUND_MUSIC, - SOUND_STREAM + SOUND_MUSIC, // soon to be deprecated hopefully + SOUND_STREAM, + SOUND_STREAM_FILE }; @@ -104,6 +106,8 @@ public: /// Return the max distance (if detailed()) virtual float getMaxDistance() const { return _MaxDist; } + inline CGroupController *getGroupController() const { return _GroupController; } + /// Set looping void setLooping( bool looping ) { _Looping = looping; } @@ -142,6 +146,9 @@ protected: /// An optional user var controler. NLMISC::TStringId _UserVarControler; + /// The group controller, always exists, owned by the audio mixer + CGroupController *_GroupController; + }; diff --git a/code/nel/include/nel/sound/source_common.h b/code/nel/include/nel/sound/source_common.h index 7781cfb02..1180fd68e 100644 --- a/code/nel/include/nel/sound/source_common.h +++ b/code/nel/include/nel/sound/source_common.h @@ -22,7 +22,7 @@ #include "nel/sound/u_stream_source.h" #include "nel/3d/cluster.h" #include "nel/sound/sound.h" - +#include "nel/sound/group_controller.h" namespace NLSOUND { @@ -36,11 +36,13 @@ public: SOURCE_SIMPLE, SOURCE_COMPLEX, SOURCE_BACKGROUND, - SOURCE_MUSIC, - SOURCE_STREAM + SOURCE_MUSIC, // DEPRECATED + SOURCE_STREAM, + SOURCE_STREAM_FILE }; - CSourceCommon(TSoundId id, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster); + /// When groupController is NULL it will use the groupcontroller specified in the TSoundId. You should manually specify the groupController if this source is a child of another source, so that the parent source controller of the user-specified .sound file is the one that will be used. + CSourceCommon(TSoundId id, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster, CGroupController *groupController); ~CSourceCommon(); @@ -63,6 +65,8 @@ public: void setGain( float gain ); void setRelativeGain( float gain ); float getRelativeGain() const; + /// Called whenever the gain is changed trough setGain, setRelativeGain or the group controller's gain settings change. + virtual void updateFinalGain() { } void setSourceRelativeMode( bool mode ); /// return the user param for the user callback void *getCallbackUserParam(void) const { return _CbUserParam; } @@ -74,6 +78,8 @@ public: virtual void getDirection( NLMISC::CVector& dir ) const { dir = _Direction; } /// Get the gain virtual float getGain() const { return _Gain; } + /// Get the final gain, including group controller changes. Use this when setting the physical source output gain. + inline float getFinalGain() const { return _Gain * _GroupController->getFinalGain(); } /// Get the pitch virtual float getPitch() const { return _Pitch; } /// Get the source relative mode @@ -99,15 +105,15 @@ public: /// \name Streaming source controls //@{ /// Set the sample format. (channels = 1, 2, ...; bitsPerSample = 8, 16; frequency = samples per second, 44100, ...) - virtual void setFormat(uint8 channels, uint8 bitsPerSample, uint32 frequency) { nlassert(false); } + virtual void setFormat(uint8 /* channels */, uint8 /* bitsPerSample */, uint32 /* frequency */) { nlassert(false); } /// Return the sample format information. - virtual void getFormat(uint8 &channels, uint8 &bitsPerSample, uint32 &frequency) const { nlassert(false); } + virtual void getFormat(uint8 &/* channels */, uint8 &/* bitsPerSample */, uint32 &/* frequency */) const { nlassert(false); } /// Get a writable pointer to the buffer of specified size. Use capacity to specify the required bytes. Returns NULL when all the buffer space is already filled. Call setFormat() first. - virtual uint8 *lock(uint capacity) { nlassert(false); return NULL; } + virtual uint8 *lock(uint /* capacity */) { nlassert(false); return NULL; } /// Notify that you are done writing to the locked buffer, so it can be copied over to hardware if needed. Set size to the number of bytes actually written to the buffer. Returns true if ok. - virtual bool unlock(uint size) { nlassert(false); return false; } + virtual bool unlock(uint /* size */) { nlassert(false); return false; } /// Get the recommended buffer size to use with lock()/unlock() - virtual void getRecommendedBufferSize(uint &samples, uint &bytes) const { nlassert(false); } + virtual void getRecommendedBufferSize(uint &/* samples */, uint &/* bytes */) const { nlassert(false); } /// Get the recommended sleep time based on the size of the last submitted buffer and the available buffer space virtual uint32 getRecommendedSleepTime() const { nlassert(false); return 0; } /// Return if there are still buffers available for playback. @@ -145,6 +151,9 @@ protected: /// An optional user var controler. NLMISC::TStringId _UserVarControler; + /// Group controller for gain + CGroupController *_GroupController; + }; } // NLSOUND diff --git a/code/nel/include/nel/sound/source_music_channel.h b/code/nel/include/nel/sound/source_music_channel.h new file mode 100644 index 000000000..7ec71fb66 --- /dev/null +++ b/code/nel/include/nel/sound/source_music_channel.h @@ -0,0 +1,100 @@ +/** + * \file source_music_channel.h + * \brief CSourceMusicChannel + * \date 2012-04-11 16:08GMT + * \author Jan Boon (Kaetemi) + * CSourceMusicChannel + */ + +/* + * Copyright (C) 2012 by authors + * + * This file is part of RYZOM CORE. + * RYZOM CORE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * RYZOM CORE 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with RYZOM CORE. If not, see + * . + */ + +#ifndef NLSOUND_SOURCE_MUSIC_CHANNEL_H +#define NLSOUND_SOURCE_MUSIC_CHANNEL_H +#include + +// STL includes + +// NeL includes +#include +#include + +// Project includes + +namespace NLSOUND { + class CStreamFileSource; + +/** + * \brief CSourceMusicChannel + * \date 2012-04-11 16:08GMT + * \author Jan Boon (Kaetemi) + * CSourceMusicChannel + */ +class CSourceMusicChannel : public IMusicChannel +{ +public: + CSourceMusicChannel(); + virtual ~CSourceMusicChannel(); + + /** Play some music (.ogg etc...) + * NB: if an old music was played, it is first stop with stopMusic() + * \param filepath file path, CPath::lookup is done here + * \param async stream music from hard disk, preload in memory if false + * \param loop must be true to play the music in loop. + */ + virtual bool play(const std::string &filepath, bool async, bool loop); + + /// Stop the music previously loaded and played (the Memory is also freed) + virtual void stop(); + + /// Makes sure any resources are freed, but keeps available for next play call + virtual void reset(); + + /// Pause the music previously loaded and played (the Memory is not freed) + virtual void pause(); + + /// Resume the music previously paused + virtual void resume(); + + /// Return true if a song is finished. + virtual bool isEnded(); + + /// Return true if the song is still loading asynchronously and hasn't started playing yet (false if not async), used to delay fading + virtual bool isLoadingAsync(); + + /// Return the total length (in second) of the music currently played + virtual float getLength(); + + /** Set the music volume (if any music played). (volume value inside [0 , 1]) (default: 1) + * NB: the volume of music is NOT affected by IListener::setGain() + */ + virtual void setVolume(float gain); + +private: + CStreamFileSound m_Sound; + CStreamFileSource *m_Source; + float m_Gain; + +}; /* class CSourceMusicChannel */ + +} /* namespace NLSOUND */ + +#endif /* #ifndef NLSOUND_SOURCE_MUSIC_CHANNEL_H */ + +/* end of file */ diff --git a/code/nel/include/nel/sound/stream_file_sound.h b/code/nel/include/nel/sound/stream_file_sound.h new file mode 100644 index 000000000..8c1cc1634 --- /dev/null +++ b/code/nel/include/nel/sound/stream_file_sound.h @@ -0,0 +1,94 @@ +/** + * \file stream_file_sound.h + * \brief CStreamFileSound + * \date 2012-04-11 09:57GMT + * \author Jan Boon (Kaetemi) + * CStreamFileSound + */ + +/* + * Copyright (C) 2012 by authors + * + * This file is part of RYZOM CORE. + * RYZOM CORE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * RYZOM CORE 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with RYZOM CORE. If not, see + * . + */ + +#ifndef NLSOUND_STREAM_FILE_SOUND_H +#define NLSOUND_STREAM_FILE_SOUND_H +#include + +// STL includes + +// NeL includes + +// Project includes +#include + +namespace NLSOUND { + class CSourceMusicChannel; + +/** + * \brief CStreamFileSound + * \date 2012-04-11 09:57GMT + * \author Jan Boon (Kaetemi) + * CStreamFileSound + */ +class CStreamFileSound : public CStreamSound +{ +public: + friend class CSourceMusicChannel; + +public: + CStreamFileSound(); + virtual ~CStreamFileSound(); + + /// Get the type of the sound. + virtual TSOUND_TYPE getSoundType() { return SOUND_STREAM_FILE; } + + /// Load the sound parameters from georges' form + virtual void importForm(const std::string& filename, NLGEORGES::UFormElm& formRoot); + + /// Used by the george sound plugin to check sound recursion (ie sound 'toto' use sound 'titi' witch also use sound 'toto' ...). + virtual void getSubSoundList(std::vector > &/* subsounds */) const { } + + /// Serialize the sound data. + virtual void serial(NLMISC::IStream &s); + + /// Return the length of the sound in ms + virtual uint32 getDuration() { return 0; } + + inline bool getAsync() { return m_Async; } + + inline const std::string &getFilePath() { return m_FilePath; } + +private: + /// Used by CSourceMusicChannel to set the filePath and default settings on other parameters. + void setMusicFilePath(const std::string &filePath, bool async = true, bool loop = false); + +private: + CStreamFileSound(const CStreamFileSound &); + CStreamFileSound &operator=(const CStreamFileSound &); + +private: + bool m_Async; + std::string m_FilePath; + +}; /* class CStreamFileSound */ + +} /* namespace NLSOUND */ + +#endif /* #ifndef NLSOUND_STREAM_FILE_SOUND_H */ + +/* end of file */ diff --git a/code/nel/include/nel/sound/stream_file_source.h b/code/nel/include/nel/sound/stream_file_source.h new file mode 100644 index 000000000..0cfee14d1 --- /dev/null +++ b/code/nel/include/nel/sound/stream_file_source.h @@ -0,0 +1,110 @@ +/** + * \file stream_file_source.h + * \brief CStreamFileSource + * \date 2012-04-11 09:57GMT + * \author Jan Boon (Kaetemi) + * CStreamFileSource + */ + +/* + * Copyright (C) 2012 by authors + * + * This file is part of RYZOM CORE. + * RYZOM CORE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * RYZOM CORE 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with RYZOM CORE. If not, see + * . + */ + +#ifndef NLSOUND_STREAM_FILE_SOURCE_H +#define NLSOUND_STREAM_FILE_SOURCE_H +#include + +// STL includes + +// NeL includes +#include + +// Project includes +#include +#include + +namespace NLSOUND { + class IAudioDecoder; + +/** + * \brief CStreamFileSource + * \date 2012-04-11 09:57GMT + * \author Jan Boon (Kaetemi) + * CStreamFileSource + */ +class CStreamFileSource : public CStreamSource, private NLMISC::IRunnable +{ +public: + CStreamFileSource(CStreamFileSound *streamFileSound = NULL, bool spawn = false, TSpawnEndCallback cb = 0, void *cbUserParam = 0, NL3D::CCluster *cluster = 0, CGroupController *groupController = NULL); + virtual ~CStreamFileSource(); + + /// Return the source type + TSOURCE_TYPE getType() const { return SOURCE_STREAM_FILE; } + + /// \name Playback control + //@{ + /// Play + virtual void play(); + /// Stop playing + virtual void stop(); + /// Get playing state. Return false even if the source has stopped on its own. + virtual bool isPlaying(); + /// Pause (following legacy music channel implementation) + void pause(); + /// Resume (following legacy music channel implementation) + void resume(); + /// check if song ended (following legacy music channel implementation) + bool isEnded(); + /// (following legacy music channel implementation) + float getLength(); + /// check if still loading (following legacy music channel implementation) + bool isLoadingAsync(); + //@} + + /// \name Decoding thread + //@{ + virtual void getName (std::string &result) const { result = "CStreamFileSource"; } + virtual void run(); + //@} + + // TODO: getTime + +private: + bool prepareDecoder(); + inline bool bufferMore(uint bytes); + +private: + CStreamFileSource(const CStreamFileSource &); + CStreamFileSource &operator=(const CStreamFileSource &); + +private: + inline CStreamFileSound *getStreamFileSound() { return static_cast(m_StreamSound); } + + NLMISC::IThread *m_Thread; + + IAudioDecoder *m_AudioDecoder; + + bool m_Paused; + +}; /* class CStreamFileSource */ + +} /* namespace NLSOUND */ + +#endif /* #ifndef NLSOUND_STREAM_FILE_SOURCE_H */ + +/* end of file */ diff --git a/code/nel/include/nel/sound/stream_sound.h b/code/nel/include/nel/sound/stream_sound.h index 39e6c733c..4b0debe0c 100644 --- a/code/nel/include/nel/sound/stream_sound.h +++ b/code/nel/include/nel/sound/stream_sound.h @@ -46,7 +46,7 @@ public: virtual void importForm(const std::string& filename, NLGEORGES::UFormElm& formRoot); /// Used by the george sound plugin to check sound recursion (ie sound 'toto' use sound 'titi' witch also use sound 'toto' ...). - virtual void getSubSoundList(std::vector > &subsounds) const { } + virtual void getSubSoundList(std::vector > &/* subsounds */) const { } /// Serialize the sound data. virtual void serial(NLMISC::IStream &s); diff --git a/code/nel/include/nel/sound/stream_source.h b/code/nel/include/nel/sound/stream_source.h index a5ac7c9f8..40ed82e11 100644 --- a/code/nel/include/nel/sound/stream_source.h +++ b/code/nel/include/nel/sound/stream_source.h @@ -41,7 +41,7 @@ namespace NLSOUND { class CStreamSource : public CSourceCommon { public: - CStreamSource(CStreamSound *streamSound = NULL, bool spawn = false, TSpawnEndCallback cb = 0, void *cbUserParam = 0, NL3D::CCluster *cluster = 0); + CStreamSource(CStreamSound *streamSound = NULL, bool spawn = false, TSpawnEndCallback cb = 0, void *cbUserParam = 0, NL3D::CCluster *cluster = 0, CGroupController *groupController = NULL); virtual ~CStreamSource(); /// Return the sound binded to the source (or NULL if there is no sound) @@ -55,6 +55,9 @@ public: virtual void setLooping(bool l); /// Play virtual void play(); +protected: + void stopInt(); +public: /// Stop playing virtual void stop(); /// Get playing state. Return false even if the source has stopped on its own. @@ -80,18 +83,7 @@ public: virtual void setVelocity(const NLMISC::CVector& vel); /// Set the direction vector (3D mode only, ignored in stereo mode) (default: (0,0,0) as non-directional) virtual void setDirection(const NLMISC::CVector& dir); - /** Set the gain (volume value inside [0 , 1]). (default: 1) - * 0.0 -> silence - * 0.5 -> -6dB - * 1.0 -> no attenuation - * values > 1 (amplification) not supported by most drivers - */ - virtual void setGain(float gain); - - /** Set the gain amount (value inside [0, 1]) to map between 0 and the nominal gain - * (which is getSource()->getGain()). Does nothing if getSource() is null. - */ - virtual void setRelativeGain(float gain); + virtual void updateFinalGain(); /** Shift the frequency. 1.0f equals identity, each reduction of 50% equals a pitch shift * of one octave. 0 is not a legal value. */ @@ -118,6 +110,9 @@ public: virtual bool hasFilledBuffersAvailable() const; //@} + /// Prepare the buffers in this stream for the given maximum capacity. (TODO: Move this into UStreamSource) + void preAllocate(uint capacity); + /// Return the track CTrack *getTrack() { return m_Track; } @@ -125,7 +120,7 @@ private: CStreamSource(const CStreamSource &); CStreamSource &operator=(const CStreamSource &); -private: +protected: /// Return the source type TSOURCE_TYPE getType() const { return SOURCE_STREAM; } @@ -173,7 +168,13 @@ private: /// The bytes per second according to the buffer format uint m_BytesPerSecond; - + + /// Waiting for play for high priority sources + bool m_WaitingForPlay; + + /// Inverse pitch + float m_PitchInv; + }; /* class CStreamSource */ } /* namespace NLSOUND */ diff --git a/code/nel/include/nel/sound/u_audio_mixer.h b/code/nel/include/nel/sound/u_audio_mixer.h index e1c2a274e..c4702c3f8 100644 --- a/code/nel/include/nel/sound/u_audio_mixer.h +++ b/code/nel/include/nel/sound/u_audio_mixer.h @@ -20,6 +20,7 @@ #include "nel/misc/types_nl.h" #include "nel/misc/string_mapper.h" #include "nel/sound/u_source.h" +#include "nel/sound/u_group_controller.h" #include "nel/ligo/primitive.h" #include @@ -285,15 +286,19 @@ public: /// Get a TSoundId from a name (returns NULL if not found) virtual TSoundId getSoundId( const NLMISC::TStringId &name ) = 0; + /// Gets the group controller for the given group tree path with separator '/', if it doesn't exist yet it will be created. + /// Examples: "music", "effects", "dialog", "music/background", "music/loading", "music/player", etcetera + virtual UGroupController *getGroupController(const std::string &path) = 0; + /** Add a logical sound source (returns NULL if name not found). * If spawn is true, the source will auto-delete after playing. If so, the return USource* pointer * is valid only before the time when calling play() plus the duration of the sound. You can * pass a callback function that will be called (if not NULL) just before deleting the spawned * source. */ - virtual USource *createSource( const NLMISC::TStringId &name, bool spawn=false, TSpawnEndCallback cb=NULL, void *callbackUserParam = NULL, NL3D::CCluster *cluster = 0, CSoundContext *context=0) = 0; + virtual USource *createSource(const NLMISC::TStringId &name, bool spawn=false, TSpawnEndCallback cb=NULL, void *callbackUserParam = NULL, NL3D::CCluster *cluster = 0, CSoundContext *context = 0, UGroupController *groupController = NULL) = 0; /// Add a logical sound source (by sound id). To remove a source, just delete it. See createSource(const char*) - virtual USource *createSource( TSoundId id, bool spawn=false, TSpawnEndCallback cb=NULL, void *callbackUserParam = NULL, NL3D::CCluster *cluster = 0, CSoundContext *context=0 ) = 0; + virtual USource *createSource(TSoundId id, bool spawn=false, TSpawnEndCallback cb=NULL, void *callbackUserParam = NULL, NL3D::CCluster *cluster = 0, CSoundContext *context = 0, UGroupController *groupController = NULL) = 0; /** Use this method to set the listener position instead of using getListener->setPos(); * It's because we have to update the background sounds in this case. diff --git a/code/nel/include/nel/sound/u_group_controller.h b/code/nel/include/nel/sound/u_group_controller.h new file mode 100644 index 000000000..5aadeb25c --- /dev/null +++ b/code/nel/include/nel/sound/u_group_controller.h @@ -0,0 +1,65 @@ +/** + * \file u_group_controller.h + * \brief UGroupController + * \date 2012-04-10 12:49GMT + * \author Jan Boon (Kaetemi) + * UGroupController + */ + +/* + * Copyright (C) 2012 by authors + * + * This file is part of RYZOM CORE. + * RYZOM CORE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * RYZOM CORE 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with RYZOM CORE. If not, see + * . + */ + +#ifndef NLSOUND_U_GROUP_CONTROLLER_H +#define NLSOUND_U_GROUP_CONTROLLER_H +#include + +// STL includes + +// NeL includes + +// Project includes + +#define NLSOUND_SHEET_V1_DEFAULT_SOUND_GROUP_CONTROLLER "sound:effects:game" +#define NLSOUND_SHEET_V1_DEFAULT_SOUND_MUSIC_GROUP_CONTROLLER "sound:music:game" +#define NLSOUND_SHEET_V1_DEFAULT_SOUND_STREAM_GROUP_CONTROLLER "sound:dialog:game" + +namespace NLSOUND { + +/** + * \brief UGroupController + * \date 2012-04-10 12:49GMT + * \author Jan Boon (Kaetemi) + * UGroupController + */ +class UGroupController +{ +public: + virtual void setGain(float gain) = 0; + virtual float getGain() = 0; + +protected: + virtual ~UGroupController() { } + +}; /* class UGroupController */ + +} /* namespace NLSOUND */ + +#endif /* #ifndef NLSOUND_U_GROUP_CONTROLLER_H */ + +/* end of file */ diff --git a/code/nel/samples/3d/Makefile.am b/code/nel/samples/3d/Makefile.am deleted file mode 100644 index d00e99366..000000000 --- a/code/nel/samples/3d/Makefile.am +++ /dev/null @@ -1,11 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2005/04/04 09:45:05 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -SUBDIRS = font cluster_viewer @CEGUI_SUBDIR@ - - -# End of Makefile.am - diff --git a/code/nel/samples/3d/cegui/Makefile.am b/code/nel/samples/3d/cegui/Makefile.am deleted file mode 100644 index afc817166..000000000 --- a/code/nel/samples/3d/cegui/Makefile.am +++ /dev/null @@ -1,22 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2005-04-04 09:45:06 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = demonel_8.sln demonel_8.vcproj demonel.rc demonel.sln demonel.vcproj icon1.ico datafiles - -bin_PROGRAMS = nel_sample_cegui - -nel_sample_cegui_SOURCES = main.cpp NeLDriver.cpp - -AM_CXXFLAGS = -I$(top_srcdir)/src @CEGUI_CFLAGS@ - -nel_sample_cegui_LDADD = ../../../src/misc/libnelmisc.la \ - ../../../src/3d/libnel3d.la \ - ../../../src/cegui/libnelceguirenderer.la \ - @CEGUI_LIBS@ - - -# End of Makefile.am - diff --git a/code/nel/samples/3d/cluster_viewer/Makefile.am b/code/nel/samples/3d/cluster_viewer/Makefile.am deleted file mode 100644 index 5814a0394..000000000 --- a/code/nel/samples/3d/cluster_viewer/Makefile.am +++ /dev/null @@ -1,24 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2005/04/04 09:45:06 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -SUBDIRS = shapes groups fonts - -bin_PROGRAMS = cluster_viewer - -cluster_viewer_SOURCES = main.cpp - -cluster_viewerdir = $(datadir)/nel/samples/cluster_viewer - -cluster_viewer_DATA = readme.txt main.cvs - -AM_CXXFLAGS = -DCV_DIR="\"$(cluster_viewerdir)\"" -I$(top_srcdir)/src - -cluster_viewer_LDADD = ../../../src/misc/libnelmisc.la \ - ../../../src/3d/libnel3d.la - - -# End of Makefile.am - diff --git a/code/nel/samples/3d/cluster_viewer/fonts/Makefile.am b/code/nel/samples/3d/cluster_viewer/fonts/Makefile.am deleted file mode 100644 index 11e9a8f31..000000000 --- a/code/nel/samples/3d/cluster_viewer/fonts/Makefile.am +++ /dev/null @@ -1,12 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2005-04-04 09:45:06 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -cluster_viewerdir = $(datadir)/nel/samples/cluster_viewer/fonts/ - -cluster_viewer_DATA = n019003l.pfb - -# End of Makefile.am - diff --git a/code/nel/samples/3d/cluster_viewer/groups/Makefile.am b/code/nel/samples/3d/cluster_viewer/groups/Makefile.am deleted file mode 100644 index 54cdb5867..000000000 --- a/code/nel/samples/3d/cluster_viewer/groups/Makefile.am +++ /dev/null @@ -1,12 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2005-04-04 09:45:06 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -cluster_viewerdir = $(datadir)/nel/samples/cluster_viewer/groups/ - -cluster_viewer_DATA = street.ig - -# End of Makefile.am - diff --git a/code/nel/samples/3d/cluster_viewer/shapes/Makefile.am b/code/nel/samples/3d/cluster_viewer/shapes/Makefile.am deleted file mode 100644 index 3b251867a..000000000 --- a/code/nel/samples/3d/cluster_viewer/shapes/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2005-04-04 09:45:06 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -cluster_viewerdir = $(datadir)/nel/samples/cluster_viewer/shapes/ - -cluster_viewer_DATA = box02.shape \ - sphere01.shape \ - sphere02.shape \ - sphere03.shape \ - sphere04.shape \ - sphere05.shape \ - sphere06.shape \ - sphere07.shape \ - sphere08.shape - -# End of Makefile.am - diff --git a/code/nel/samples/3d/font/Makefile.am b/code/nel/samples/3d/font/Makefile.am deleted file mode 100644 index 5548ec8f6..000000000 --- a/code/nel/samples/3d/font/Makefile.am +++ /dev/null @@ -1,21 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2005/04/04 09:45:06 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -bin_PROGRAMS = font - -font_SOURCES = main.cpp - -fontdir = $(datadir)/nel/samples/font -font_DATA = beteckna.ttf - -AM_CXXFLAGS = -DFONT_DIR="\"$(fontdir)\"" -I$(top_srcdir)/src - -font_LDADD = ../../../src/misc/libnelmisc.la \ - ../../../src/3d/libnel3d.la - - -# End of Makefile.am - diff --git a/code/nel/samples/CMakeLists.txt b/code/nel/samples/CMakeLists.txt index 4f38264a0..5abcd985a 100644 --- a/code/nel/samples/CMakeLists.txt +++ b/code/nel/samples/CMakeLists.txt @@ -17,5 +17,5 @@ IF(WITH_PACS) ENDIF(WITH_PACS) IF(WITH_SOUND) - ADD_SUBDIRECTORY(sound_sources) + ADD_SUBDIRECTORY(sound) ENDIF(WITH_SOUND) diff --git a/code/nel/samples/Makefile.am b/code/nel/samples/Makefile.am deleted file mode 100644 index 98edb586d..000000000 --- a/code/nel/samples/Makefile.am +++ /dev/null @@ -1,12 +0,0 @@ -# -# $Id: Makefile.am,v 1.2 2005/04/13 12:37:26 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -DIST_SUBDIRS = sound_sources pacs georges 3d net misc - -SUBDIRS = pacs georges 3d net misc - -# End of Makefile.am - diff --git a/code/nel/samples/georges/Makefile.am b/code/nel/samples/georges/Makefile.am deleted file mode 100644 index bf2c83d5f..000000000 --- a/code/nel/samples/georges/Makefile.am +++ /dev/null @@ -1,24 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2005/04/04 09:45:06 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = georges_sample_8.vcproj georges_sample.sln georges_sample.vcproj - -bin_PROGRAMS = georges - -georges_SOURCES = main.cpp - -georgesdir = $(datadir)/nel/samples/georges - -georges_DATA = boolean.typ coolfilesinfo.dfn default.sample_config int.typ positiondata.dfn sample_config.dfn string.typ - -AM_CXXFLAGS = -DGF_DIR="\"$(georgesdir)\"" -I$(top_srcdir)/src - - -georges_LDADD = ../../src/misc/libnelmisc.la \ - ../../src/georges/libnelgeorges.la - - -# End of Makefile.am diff --git a/code/nel/samples/misc/Makefile.am b/code/nel/samples/misc/Makefile.am deleted file mode 100644 index 0e13cb6f1..000000000 --- a/code/nel/samples/misc/Makefile.am +++ /dev/null @@ -1,10 +0,0 @@ -# -# $Id: Makefile.am,v 1.2 2005-04-13 12:37:26 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -SUBDIRS = command configfile debug i18n log strings - -# End of Makefile.am - diff --git a/code/nel/samples/misc/command/Makefile.am b/code/nel/samples/misc/command/Makefile.am deleted file mode 100644 index 890a9fa18..000000000 --- a/code/nel/samples/misc/command/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2005-04-04 09:45:06 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = command_8.vcproj main.dsp main.dsw - -bin_PROGRAMS = command - -command_SOURCES = main.cpp - -commanddir = $(datadir)/nel/samples/command - -AM_CXXFLAGS = -I$(top_srcdir)/src - -command_LDADD = ../../../src/misc/libnelmisc.la - -# End of Makefile.am - diff --git a/code/nel/samples/misc/configfile/Makefile.am b/code/nel/samples/misc/configfile/Makefile.am deleted file mode 100644 index 538d3af28..000000000 --- a/code/nel/samples/misc/configfile/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2005-04-04 09:45:06 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = configfile_8.vcproj main.dsp main.dsw - -bin_PROGRAMS = configfile - -configfile_SOURCES = main.cpp - -configfiledir = $(datadir)/nel/samples/configfile - -configfile_DATA = simpletest.txt - -AM_CXXFLAGS = -DCF_DIR="\"$(configfiledir)\"" -I$(top_srcdir)/src - -configfile_LDADD = ../../../src/misc/libnelmisc.la - - -# End of Makefile.am - diff --git a/code/nel/samples/misc/debug/Makefile.am b/code/nel/samples/misc/debug/Makefile.am deleted file mode 100644 index d8d2c733a..000000000 --- a/code/nel/samples/misc/debug/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2005-04-04 09:45:06 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = debug_8.vcproj main.dsp main.dsw - -bin_PROGRAMS = debug - -debug_SOURCES = main.cpp - -debugdir = $(datadir)/nel/samples/debug - -AM_CXXFLAGS = -I$(top_srcdir)/src - -debug_LDADD = ../../../src/misc/libnelmisc.la - -# End of Makefile.am - diff --git a/code/nel/samples/misc/i18n/Makefile.am b/code/nel/samples/misc/i18n/Makefile.am deleted file mode 100644 index 6c9c574c9..000000000 --- a/code/nel/samples/misc/i18n/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2005-04-04 09:45:06 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = i18n_8.vcproj main.dsp main.dsw - -bin_PROGRAMS = i18n - -i18n_SOURCES = main.cpp - -i18ndir = $(datadir)/nel/samples/i18n - -i18n_DATA = en.uxt fr.uxt de.uxt - -AM_CXXFLAGS = -DI18N_DIR="\"$(i18ndir)\"" -I$(top_srcdir)/src - -i18n_LDADD = ../../../src/misc/libnelmisc.la - - -# End of Makefile.am - diff --git a/code/nel/samples/misc/log/Makefile.am b/code/nel/samples/misc/log/Makefile.am deleted file mode 100644 index 3d57e533d..000000000 --- a/code/nel/samples/misc/log/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2005-04-04 09:45:06 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = log_8.vcproj main.dsp main.dsw - -bin_PROGRAMS = log - -log_SOURCES = main.cpp - -logdir = $(datadir)/nel/samples/log - -AM_CXXFLAGS = -I$(top_srcdir)/src - -log_LDADD = ../../../src/misc/libnelmisc.la - -# End of Makefile.am - diff --git a/code/nel/samples/misc/strings/Makefile.am b/code/nel/samples/misc/strings/Makefile.am deleted file mode 100644 index 151e8ef32..000000000 --- a/code/nel/samples/misc/strings/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2005-04-04 09:45:06 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = main.dsp main.dsw strings_8.vcproj - -bin_PROGRAMS = strings - -strings_SOURCES = main.cpp - -stringsdir = $(datadir)/nel/samples/strings - -AM_CXXFLAGS = -I$(top_srcdir)/src - -strings_LDADD = ../../../src/misc/libnelmisc.la - -# End of Makefile.am - diff --git a/code/nel/samples/misc/types_check/Makefile.am b/code/nel/samples/misc/types_check/Makefile.am deleted file mode 100644 index 9c79d6aa2..000000000 --- a/code/nel/samples/misc/types_check/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2005-04-04 09:45:06 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = main.dsp main.dsw types_check_8.vcproj - -bin_PROGRAMS = types_check - -types_check_SOURCES = main.cpp - -types_checkdir = $(datadir)/nel/samples/types_check - -AM_CXXFLAGS = -I$(top_srcdir)/src - -types_check_LDADD = ../../../src/misc/libnelmisc.la - -# End of Makefile.am - diff --git a/code/nel/samples/net/Makefile.am b/code/nel/samples/net/Makefile.am deleted file mode 100644 index ad7388761..000000000 --- a/code/nel/samples/net/Makefile.am +++ /dev/null @@ -1,11 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2005/04/13 12:37:26 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -SUBDIRS = chat udp login_system - - -# End of Makefile.am - diff --git a/code/nel/samples/net/chat/Makefile.am b/code/nel/samples/net/chat/Makefile.am deleted file mode 100644 index bc2df9ef9..000000000 --- a/code/nel/samples/net/chat/Makefile.am +++ /dev/null @@ -1,27 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2005/04/13 12:37:26 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -bin_PROGRAMS = chatserver chatclient - -chatserver_SOURCES = server.cpp - -chatclient_SOURCES = client.cpp kbhit.h kbhit.cpp - -chatserverdir=$(datadir)/nel/samples/net/chat -chatserver_DATA=chat_service.cfg - -chatclientdir=$(datadir)/nel/samples/net/chat -chatclient_DATA=client.cfg - -AM_CXXFLAGS = -DCHAT_DIR="\"$(chatclientdir)\"" -I$(top_srcdir)/src - -chatserver_LDADD = ../../../src/misc/libnelmisc.la \ - ../../../src/net/libnelnet.la - -chatclient_LDADD = ../../../src/misc/libnelmisc.la \ - ../../../src/net/libnelnet.la - -# End of Makefile.am diff --git a/code/nel/samples/net/login_system/Makefile.am b/code/nel/samples/net/login_system/Makefile.am deleted file mode 100644 index 5ef4fe26c..000000000 --- a/code/nel/samples/net/login_system/Makefile.am +++ /dev/null @@ -1,30 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2005-04-13 12:37:26 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = main.dsw client.dsp client.cfg frontend_service.cfg frontend_service.dsp - -bin_PROGRAMS = nls_login_client nls_frontend_service - -nls_frontend_service_SOURCES = frontend_service.cpp - -nls_login_client_SOURCES = client.cpp - -nls_frontend_servicedir=$(datadir)/nel/samples/net/udp -nls_frontend_service_DATA=frontend_service.cfg - -nls_login_clientdir=$(datadir)/nel/samples/net/udp -nls_login_client_DATA=client.cfg - -AM_CXXFLAGS = -DLC_DIR="\"$(nls_login_clientdir)\"" -I$(top_srcdir)/src - -nls_frontend_service_LDADD = ../../../src/misc/libnelmisc.la \ - ../../../src/net/libnelnet.la - -nls_login_client_LDADD = ../../../src/misc/libnelmisc.la \ - ../../../src/net/libnelnet.la - -# End of Makefile.am - diff --git a/code/nel/samples/net/udp/Makefile.am b/code/nel/samples/net/udp/Makefile.am deleted file mode 100644 index 07a131fd8..000000000 --- a/code/nel/samples/net/udp/Makefile.am +++ /dev/null @@ -1,32 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2005-04-13 12:37:26 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = main.dsw main.sln bench_service_8.vcproj bench_service.vcproj bench_service.dsp client_8.vcproj client.dsp client.vcproj readme.txt - -bin_PROGRAMS = udp_bench_service udp_bench_client - -udp_bench_service_SOURCES = bench_service.cpp receive_task.cpp receive_task.h - -udp_bench_client_SOURCES = client.cpp graph.cpp graph.h simlag.cpp simlag.h - -noinst_HEADERS = receive_task.h graph.h simlag.h - -udp_bench_servicedir=$(datadir)/nel/samples/net/udp -udp_bench_service_DATA= bench_service.cfg - -udp_bench_clientdir=$(datadir)/nel/samples/net/udp -udp_bench_client_DATA=client.cfg - -AM_CXXFLAGS = -DUDP_DIR="\"$(udp_bench_clientdir)\"" -I$(top_srcdir)/src - -udp_bench_service_LDADD = ../../../src/misc/libnelmisc.la \ - ../../../src/net/libnelnet.la - -udp_bench_client_LDADD = ../../../src/misc/libnelmisc.la \ - ../../../src/net/libnelnet.la - -# End of Makefile.am - diff --git a/code/nel/samples/pacs/Makefile.am b/code/nel/samples/pacs/Makefile.am deleted file mode 100644 index d7a552769..000000000 --- a/code/nel/samples/pacs/Makefile.am +++ /dev/null @@ -1,19 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2005/04/04 09:45:06 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -bin_PROGRAMS = pacs_sample - -pacs_sample_SOURCES = main.cpp object.cpp object.h - -AM_CXXFLAGS = -I$(top_srcdir)/src - -pacs_sample_LDADD = ../../src/misc/libnelmisc.la \ - ../../src/3d/libnel3d.la \ - ../../src/pacs/libnelpacs.la - - -# End of Makefile.am - diff --git a/code/nel/samples/sound/CMakeLists.txt b/code/nel/samples/sound/CMakeLists.txt new file mode 100644 index 000000000..6a7696fa4 --- /dev/null +++ b/code/nel/samples/sound/CMakeLists.txt @@ -0,0 +1,5 @@ + +ADD_SUBDIRECTORY(sound_sources) +ADD_SUBDIRECTORY(stream_file) +ADD_SUBDIRECTORY(stream_ogg_vorbis) + diff --git a/code/nel/samples/sound_sources/CMakeLists.txt b/code/nel/samples/sound/sound_sources/CMakeLists.txt similarity index 85% rename from code/nel/samples/sound_sources/CMakeLists.txt rename to code/nel/samples/sound/sound_sources/CMakeLists.txt index 4cf1ea427..b0f481e7c 100644 --- a/code/nel/samples/sound_sources/CMakeLists.txt +++ b/code/nel/samples/sound/sound_sources/CMakeLists.txt @@ -7,7 +7,7 @@ ADD_DEFINITIONS(-DNL_SOUND_DATA="\\"${NL_SHARE_PREFIX}/nl_sample_sound/\\"" ${LI INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR}) TARGET_LINK_LIBRARIES(nl_sample_sound_sources nelmisc nelsound) -NL_DEFAULT_PROPS(nl_sample_sound_sources "NeL, Samples: Sound System") +NL_DEFAULT_PROPS(nl_sample_sound_sources "NeL, Samples: Sound: Sound Sources") NL_ADD_RUNTIME_FLAGS(nl_sample_sound_sources) INSTALL(TARGETS nl_sample_sound_sources RUNTIME DESTINATION bin COMPONENT samplessound) diff --git a/code/nel/samples/sound_sources/data/DFN/alpha.typ b/code/nel/samples/sound/sound_sources/data/DFN/alpha.typ similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/alpha.typ rename to code/nel/samples/sound/sound_sources/data/DFN/alpha.typ diff --git a/code/nel/samples/sound_sources/data/DFN/angle.typ b/code/nel/samples/sound/sound_sources/data/DFN/angle.typ similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/angle.typ rename to code/nel/samples/sound/sound_sources/data/DFN/angle.typ diff --git a/code/nel/samples/sound_sources/data/DFN/backgound_sound_item.dfn b/code/nel/samples/sound/sound_sources/data/DFN/backgound_sound_item.dfn similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/backgound_sound_item.dfn rename to code/nel/samples/sound/sound_sources/data/DFN/backgound_sound_item.dfn diff --git a/code/nel/samples/sound_sources/data/DFN/background_flag_config.dfn b/code/nel/samples/sound/sound_sources/data/DFN/background_flag_config.dfn similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/background_flag_config.dfn rename to code/nel/samples/sound/sound_sources/data/DFN/background_flag_config.dfn diff --git a/code/nel/samples/sound_sources/data/DFN/background_sound.dfn b/code/nel/samples/sound/sound_sources/data/DFN/background_sound.dfn similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/background_sound.dfn rename to code/nel/samples/sound/sound_sources/data/DFN/background_sound.dfn diff --git a/code/nel/samples/sound_sources/data/DFN/basics/_typ.dfn b/code/nel/samples/sound/sound_sources/data/DFN/basics/_typ.dfn similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/basics/_typ.dfn rename to code/nel/samples/sound/sound_sources/data/DFN/basics/_typ.dfn diff --git a/code/nel/samples/sound_sources/data/DFN/basics/_type.typ b/code/nel/samples/sound/sound_sources/data/DFN/basics/_type.typ similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/basics/_type.typ rename to code/nel/samples/sound/sound_sources/data/DFN/basics/_type.typ diff --git a/code/nel/samples/sound_sources/data/DFN/basics/boolean.typ b/code/nel/samples/sound/sound_sources/data/DFN/basics/boolean.typ similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/basics/boolean.typ rename to code/nel/samples/sound/sound_sources/data/DFN/basics/boolean.typ diff --git a/code/nel/samples/sound_sources/data/DFN/basics/filename.typ b/code/nel/samples/sound/sound_sources/data/DFN/basics/filename.typ similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/basics/filename.typ rename to code/nel/samples/sound/sound_sources/data/DFN/basics/filename.typ diff --git a/code/nel/samples/sound_sources/data/DFN/basics/float.typ b/code/nel/samples/sound/sound_sources/data/DFN/basics/float.typ similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/basics/float.typ rename to code/nel/samples/sound/sound_sources/data/DFN/basics/float.typ diff --git a/code/nel/samples/sound_sources/data/DFN/basics/iboolean.typ b/code/nel/samples/sound/sound_sources/data/DFN/basics/iboolean.typ similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/basics/iboolean.typ rename to code/nel/samples/sound/sound_sources/data/DFN/basics/iboolean.typ diff --git a/code/nel/samples/sound_sources/data/DFN/basics/int.typ b/code/nel/samples/sound/sound_sources/data/DFN/basics/int.typ similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/basics/int.typ rename to code/nel/samples/sound/sound_sources/data/DFN/basics/int.typ diff --git a/code/nel/samples/sound_sources/data/DFN/basics/string.typ b/code/nel/samples/sound/sound_sources/data/DFN/basics/string.typ similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/basics/string.typ rename to code/nel/samples/sound/sound_sources/data/DFN/basics/string.typ diff --git a/code/nel/samples/sound_sources/data/DFN/basics/typ.dfn b/code/nel/samples/sound/sound_sources/data/DFN/basics/typ.dfn similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/basics/typ.dfn rename to code/nel/samples/sound/sound_sources/data/DFN/basics/typ.dfn diff --git a/code/nel/samples/sound_sources/data/DFN/complex_sound.dfn b/code/nel/samples/sound/sound_sources/data/DFN/complex_sound.dfn similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/complex_sound.dfn rename to code/nel/samples/sound/sound_sources/data/DFN/complex_sound.dfn diff --git a/code/nel/samples/sound_sources/data/DFN/context_sound.dfn b/code/nel/samples/sound/sound_sources/data/DFN/context_sound.dfn similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/context_sound.dfn rename to code/nel/samples/sound/sound_sources/data/DFN/context_sound.dfn diff --git a/code/nel/samples/sound_sources/data/DFN/direction.dfn b/code/nel/samples/sound/sound_sources/data/DFN/direction.dfn similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/direction.dfn rename to code/nel/samples/sound/sound_sources/data/DFN/direction.dfn diff --git a/code/nel/samples/sound_sources/data/DFN/distance.typ b/code/nel/samples/sound/sound_sources/data/DFN/distance.typ similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/distance.typ rename to code/nel/samples/sound/sound_sources/data/DFN/distance.typ diff --git a/code/nel/samples/sound_sources/data/DFN/doppler.typ b/code/nel/samples/sound/sound_sources/data/DFN/doppler.typ similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/doppler.typ rename to code/nel/samples/sound/sound_sources/data/DFN/doppler.typ diff --git a/code/nel/samples/sound_sources/data/DFN/gain.typ b/code/nel/samples/sound/sound_sources/data/DFN/gain.typ similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/gain.typ rename to code/nel/samples/sound/sound_sources/data/DFN/gain.typ diff --git a/code/nel/samples/sound_sources/data/DFN/listener.dfn b/code/nel/samples/sound/sound_sources/data/DFN/listener.dfn similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/listener.dfn rename to code/nel/samples/sound/sound_sources/data/DFN/listener.dfn diff --git a/code/nel/samples/sound_sources/data/DFN/mixer_config.dfn b/code/nel/samples/sound/sound_sources/data/DFN/mixer_config.dfn similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/mixer_config.dfn rename to code/nel/samples/sound/sound_sources/data/DFN/mixer_config.dfn diff --git a/code/nel/samples/sound_sources/data/DFN/music_sound.dfn b/code/nel/samples/sound/sound_sources/data/DFN/music_sound.dfn similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/music_sound.dfn rename to code/nel/samples/sound/sound_sources/data/DFN/music_sound.dfn diff --git a/code/nel/samples/sound_sources/data/DFN/parameter_id.typ b/code/nel/samples/sound/sound_sources/data/DFN/parameter_id.typ similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/parameter_id.typ rename to code/nel/samples/sound/sound_sources/data/DFN/parameter_id.typ diff --git a/code/nel/samples/sound_sources/data/DFN/pattern_mode.typ b/code/nel/samples/sound/sound_sources/data/DFN/pattern_mode.typ similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/pattern_mode.typ rename to code/nel/samples/sound/sound_sources/data/DFN/pattern_mode.typ diff --git a/code/nel/samples/sound_sources/data/DFN/priority.typ b/code/nel/samples/sound/sound_sources/data/DFN/priority.typ similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/priority.typ rename to code/nel/samples/sound/sound_sources/data/DFN/priority.typ diff --git a/code/nel/samples/sound_sources/data/DFN/rolloff.typ b/code/nel/samples/sound/sound_sources/data/DFN/rolloff.typ similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/rolloff.typ rename to code/nel/samples/sound/sound_sources/data/DFN/rolloff.typ diff --git a/code/nel/samples/sound_sources/data/DFN/simple_sound.dfn b/code/nel/samples/sound/sound_sources/data/DFN/simple_sound.dfn similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/simple_sound.dfn rename to code/nel/samples/sound/sound_sources/data/DFN/simple_sound.dfn diff --git a/code/nel/samples/sound_sources/data/DFN/sound.dfn b/code/nel/samples/sound/sound_sources/data/DFN/sound.dfn similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/sound.dfn rename to code/nel/samples/sound/sound_sources/data/DFN/sound.dfn diff --git a/code/nel/samples/sound_sources/data/DFN/sound_group.dfn b/code/nel/samples/sound/sound_sources/data/DFN/sound_group.dfn similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/sound_group.dfn rename to code/nel/samples/sound/sound_sources/data/DFN/sound_group.dfn diff --git a/code/nel/samples/sound_sources/data/DFN/sound_group_item.dfn b/code/nel/samples/sound/sound_sources/data/DFN/sound_group_item.dfn similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/sound_group_item.dfn rename to code/nel/samples/sound/sound_sources/data/DFN/sound_group_item.dfn diff --git a/code/nel/samples/sound_sources/data/DFN/soundbank.dfn b/code/nel/samples/sound/sound_sources/data/DFN/soundbank.dfn similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/soundbank.dfn rename to code/nel/samples/sound/sound_sources/data/DFN/soundbank.dfn diff --git a/code/nel/samples/sound_sources/data/DFN/transposition.typ b/code/nel/samples/sound/sound_sources/data/DFN/transposition.typ similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/transposition.typ rename to code/nel/samples/sound/sound_sources/data/DFN/transposition.typ diff --git a/code/nel/samples/sound_sources/data/DFN/user_var_binding.dfn b/code/nel/samples/sound/sound_sources/data/DFN/user_var_binding.dfn similarity index 100% rename from code/nel/samples/sound_sources/data/DFN/user_var_binding.dfn rename to code/nel/samples/sound/sound_sources/data/DFN/user_var_binding.dfn diff --git a/code/nel/samples/sound_sources/data/animations/readme.txt b/code/nel/samples/sound/sound_sources/data/animations/readme.txt similarity index 100% rename from code/nel/samples/sound_sources/data/animations/readme.txt rename to code/nel/samples/sound/sound_sources/data/animations/readme.txt diff --git a/code/nel/samples/sound_sources/data/animations/test_anim.sound_anim b/code/nel/samples/sound/sound_sources/data/animations/test_anim.sound_anim similarity index 100% rename from code/nel/samples/sound_sources/data/animations/test_anim.sound_anim rename to code/nel/samples/sound/sound_sources/data/animations/test_anim.sound_anim diff --git a/code/nel/samples/sound_sources/data/background_sounds/background_sound.primitive b/code/nel/samples/sound/sound_sources/data/background_sounds/background_sound.primitive similarity index 100% rename from code/nel/samples/sound_sources/data/background_sounds/background_sound.primitive rename to code/nel/samples/sound/sound_sources/data/background_sounds/background_sound.primitive diff --git a/code/nel/samples/sound_sources/data/background_sounds/readme.txt b/code/nel/samples/sound/sound_sources/data/background_sounds/readme.txt similarity index 100% rename from code/nel/samples/sound_sources/data/background_sounds/readme.txt rename to code/nel/samples/sound/sound_sources/data/background_sounds/readme.txt diff --git a/code/nel/samples/sound_sources/data/cluster_sound/readme.txt b/code/nel/samples/sound/sound_sources/data/cluster_sound/readme.txt similarity index 100% rename from code/nel/samples/sound_sources/data/cluster_sound/readme.txt rename to code/nel/samples/sound/sound_sources/data/cluster_sound/readme.txt diff --git a/code/nel/samples/sound_sources/data/cluster_sound/test_clusters.sound_group b/code/nel/samples/sound/sound_sources/data/cluster_sound/test_clusters.sound_group similarity index 100% rename from code/nel/samples/sound_sources/data/cluster_sound/test_clusters.sound_group rename to code/nel/samples/sound/sound_sources/data/cluster_sound/test_clusters.sound_group diff --git a/code/nel/samples/sound_sources/data/default.mixer_config b/code/nel/samples/sound/sound_sources/data/default.mixer_config similarity index 100% rename from code/nel/samples/sound_sources/data/default.mixer_config rename to code/nel/samples/sound/sound_sources/data/default.mixer_config diff --git a/code/nel/samples/sound_sources/data/samplebank/base_samples/beep.wav b/code/nel/samples/sound/sound_sources/data/samplebank/base_samples/beep.wav similarity index 100% rename from code/nel/samples/sound_sources/data/samplebank/base_samples/beep.wav rename to code/nel/samples/sound/sound_sources/data/samplebank/base_samples/beep.wav diff --git a/code/nel/samples/sound_sources/data/samplebank/base_samples/tuut.wav b/code/nel/samples/sound/sound_sources/data/samplebank/base_samples/tuut.wav similarity index 100% rename from code/nel/samples/sound_sources/data/samplebank/base_samples/tuut.wav rename to code/nel/samples/sound/sound_sources/data/samplebank/base_samples/tuut.wav diff --git a/code/nel/samples/sound_sources/data/soundbank/beep.sound b/code/nel/samples/sound/sound_sources/data/soundbank/beep.sound similarity index 100% rename from code/nel/samples/sound_sources/data/soundbank/beep.sound rename to code/nel/samples/sound/sound_sources/data/soundbank/beep.sound diff --git a/code/nel/samples/sound_sources/data/soundbank/tuut.sound b/code/nel/samples/sound/sound_sources/data/soundbank/tuut.sound similarity index 100% rename from code/nel/samples/sound_sources/data/soundbank/tuut.sound rename to code/nel/samples/sound/sound_sources/data/soundbank/tuut.sound diff --git a/code/nel/samples/sound_sources/data/world_editor_classes.xml b/code/nel/samples/sound/sound_sources/data/world_editor_classes.xml similarity index 100% rename from code/nel/samples/sound_sources/data/world_editor_classes.xml rename to code/nel/samples/sound/sound_sources/data/world_editor_classes.xml diff --git a/code/nel/samples/sound_sources/main.cpp b/code/nel/samples/sound/sound_sources/main.cpp similarity index 100% rename from code/nel/samples/sound_sources/main.cpp rename to code/nel/samples/sound/sound_sources/main.cpp diff --git a/code/nel/samples/sound/stream_file/CMakeLists.txt b/code/nel/samples/sound/stream_file/CMakeLists.txt new file mode 100644 index 000000000..0552387cb --- /dev/null +++ b/code/nel/samples/sound/stream_file/CMakeLists.txt @@ -0,0 +1,12 @@ +FILE(GLOB SRC *.cpp *.h) + +ADD_EXECUTABLE(nl_sample_stream_file ${SRC}) + +INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR}) + +TARGET_LINK_LIBRARIES(nl_sample_stream_file nelmisc nelsound) +NL_DEFAULT_PROPS(nl_sample_stream_file "NeL, Samples: Sound: Stream File") +NL_ADD_RUNTIME_FLAGS(nl_sample_stream_file) + +INSTALL(TARGETS nl_sample_stream_file RUNTIME DESTINATION bin COMPONENT samplessound) + diff --git a/code/nel/samples/sound/stream_file/base_samples.sample_bank b/code/nel/samples/sound/stream_file/base_samples.sample_bank new file mode 100644 index 000000000..8e9b5b898 Binary files /dev/null and b/code/nel/samples/sound/stream_file/base_samples.sample_bank differ diff --git a/code/nel/samples/sound/stream_file/data/DFN/basics/_typ.dfn b/code/nel/samples/sound/stream_file/data/DFN/basics/_typ.dfn new file mode 100644 index 000000000..2f8971932 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/basics/_typ.dfn @@ -0,0 +1,6 @@ + + + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/basics/_type.typ b/code/nel/samples/sound/stream_file/data/DFN/basics/_type.typ new file mode 100644 index 000000000..233beca79 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/basics/_type.typ @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/basics/boolean.typ b/code/nel/samples/sound/stream_file/data/DFN/basics/boolean.typ new file mode 100644 index 000000000..fb6821f08 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/basics/boolean.typ @@ -0,0 +1,6 @@ + + + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/basics/filename.typ b/code/nel/samples/sound/stream_file/data/DFN/basics/filename.typ new file mode 100644 index 000000000..bdad39a48 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/basics/filename.typ @@ -0,0 +1,4 @@ + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/basics/float.typ b/code/nel/samples/sound/stream_file/data/DFN/basics/float.typ new file mode 100644 index 000000000..250620f5e --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/basics/float.typ @@ -0,0 +1,4 @@ + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/basics/iboolean.typ b/code/nel/samples/sound/stream_file/data/DFN/basics/iboolean.typ new file mode 100644 index 000000000..d29217bed --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/basics/iboolean.typ @@ -0,0 +1,6 @@ + + + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/basics/int.typ b/code/nel/samples/sound/stream_file/data/DFN/basics/int.typ new file mode 100644 index 000000000..5b88c4fc4 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/basics/int.typ @@ -0,0 +1,4 @@ + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/basics/sint16.typ b/code/nel/samples/sound/stream_file/data/DFN/basics/sint16.typ new file mode 100644 index 000000000..0adba3ad0 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/basics/sint16.typ @@ -0,0 +1,4 @@ + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/basics/sint32.typ b/code/nel/samples/sound/stream_file/data/DFN/basics/sint32.typ new file mode 100644 index 000000000..ce470d5fe --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/basics/sint32.typ @@ -0,0 +1,4 @@ + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/basics/sint64.typ b/code/nel/samples/sound/stream_file/data/DFN/basics/sint64.typ new file mode 100644 index 000000000..5b88c4fc4 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/basics/sint64.typ @@ -0,0 +1,4 @@ + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/basics/sint8.typ b/code/nel/samples/sound/stream_file/data/DFN/basics/sint8.typ new file mode 100644 index 000000000..462eab92c --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/basics/sint8.typ @@ -0,0 +1,4 @@ + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/basics/string.typ b/code/nel/samples/sound/stream_file/data/DFN/basics/string.typ new file mode 100644 index 000000000..89191b1eb --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/basics/string.typ @@ -0,0 +1,4 @@ + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/basics/typ.dfn b/code/nel/samples/sound/stream_file/data/DFN/basics/typ.dfn new file mode 100644 index 000000000..d3c9e1757 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/basics/typ.dfn @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/basics/uint16.typ b/code/nel/samples/sound/stream_file/data/DFN/basics/uint16.typ new file mode 100644 index 000000000..d0e98aad1 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/basics/uint16.typ @@ -0,0 +1,4 @@ + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/basics/uint32.typ b/code/nel/samples/sound/stream_file/data/DFN/basics/uint32.typ new file mode 100644 index 000000000..60dc00b3c --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/basics/uint32.typ @@ -0,0 +1,4 @@ + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/basics/uint64.typ b/code/nel/samples/sound/stream_file/data/DFN/basics/uint64.typ new file mode 100644 index 000000000..936a619c8 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/basics/uint64.typ @@ -0,0 +1,4 @@ + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/basics/uint8.typ b/code/nel/samples/sound/stream_file/data/DFN/basics/uint8.typ new file mode 100644 index 000000000..3dee1c5c8 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/basics/uint8.typ @@ -0,0 +1,4 @@ + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/alpha.typ b/code/nel/samples/sound/stream_file/data/DFN/sound/alpha.typ new file mode 100644 index 000000000..a6f7d3bff --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/alpha.typ @@ -0,0 +1,2 @@ + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/angle.typ b/code/nel/samples/sound/stream_file/data/DFN/sound/angle.typ new file mode 100644 index 000000000..db94698e0 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/angle.typ @@ -0,0 +1,2 @@ + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/backgound_sound_item.dfn b/code/nel/samples/sound/stream_file/data/DFN/sound/backgound_sound_item.dfn new file mode 100644 index 000000000..bbdfdf82a --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/backgound_sound_item.dfn @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Tue Oct 08 14:39:12 2002 (boucher) Dfn Structure = +Tue Oct 08 15:03:40 2002 (boucher) Dfn Structure = +Mon Oct 14 16:09:48 2002 (boucher) Dfn Structure = +Wed Oct 16 18:22:30 2002 (boucher) Dfn Structure = +Thu Dec 19 16:26:49 2002 (boucher) Dfn Structure = +Wed Apr 09 19:38:51 2003 (AmazingSound) Dfn Structure = + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/background_flag_config.dfn b/code/nel/samples/sound/stream_file/data/DFN/sound/background_flag_config.dfn new file mode 100644 index 000000000..bce6d82a8 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/background_flag_config.dfn @@ -0,0 +1,9 @@ + + + + + + + + Thu Jan 02 14:38:32 2003 (boucher) Dfn Structure = + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/background_sound.dfn b/code/nel/samples/sound/stream_file/data/DFN/sound/background_sound.dfn new file mode 100644 index 000000000..41288d7b8 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/background_sound.dfn @@ -0,0 +1,5 @@ + + + + Tue Oct 08 14:55:03 2002 (boucher) Dfn Structure = + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/complex_sound.dfn b/code/nel/samples/sound/stream_file/data/DFN/sound/complex_sound.dfn new file mode 100644 index 000000000..8164b9d7a --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/complex_sound.dfn @@ -0,0 +1,19 @@ + + + + + + + + + + + Tue Oct 08 14:29:42 2002 (boucher) Dfn Structure = +Tue Oct 08 14:35:40 2002 (boucher) Dfn Structure = +Thu Oct 10 16:15:18 2002 (boucher) Dfn Structure = +Fri Oct 11 10:26:17 2002 (boucher) Dfn Structure = +Fri Oct 11 11:14:25 2002 (boucher) Dfn Structure = +Fri Oct 11 11:15:41 2002 (boucher) Dfn Structure = +Fri Oct 11 16:01:43 2002 (boucher) Dfn Structure = +Wed Oct 16 11:36:41 2002 (boucher) Dfn Structure = + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/context_sound.dfn b/code/nel/samples/sound/stream_file/data/DFN/sound/context_sound.dfn new file mode 100644 index 000000000..f8d05e697 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/context_sound.dfn @@ -0,0 +1,5 @@ + + + + Thu Nov 07 14:01:21 2002 (boucher) Dfn Structure = + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/direction.dfn b/code/nel/samples/sound/stream_file/data/DFN/sound/direction.dfn new file mode 100644 index 000000000..190223cc1 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/direction.dfn @@ -0,0 +1,6 @@ + + + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/distance.typ b/code/nel/samples/sound/stream_file/data/DFN/sound/distance.typ new file mode 100644 index 000000000..0981c09a0 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/distance.typ @@ -0,0 +1,2 @@ + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/doppler.typ b/code/nel/samples/sound/stream_file/data/DFN/sound/doppler.typ new file mode 100644 index 000000000..2419f2d6c --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/doppler.typ @@ -0,0 +1,2 @@ + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/gain.typ b/code/nel/samples/sound/stream_file/data/DFN/sound/gain.typ new file mode 100644 index 000000000..2000b2652 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/gain.typ @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/listener.dfn b/code/nel/samples/sound/stream_file/data/DFN/sound/listener.dfn new file mode 100644 index 000000000..ba52b5af0 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/listener.dfn @@ -0,0 +1,5 @@ + + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/mixer_config.dfn b/code/nel/samples/sound/stream_file/data/DFN/sound/mixer_config.dfn new file mode 100644 index 000000000..61daec64b --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/mixer_config.dfn @@ -0,0 +1,14 @@ + + + + + + + + + + + Thu Jan 02 14:33:42 2003 (boucher) Dfn Structure = +Thu Jan 02 14:40:05 2003 (boucher) Dfn Structure = +Thu Jan 02 14:41:32 2003 (boucher) Dfn Structure = + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/music_sound.dfn b/code/nel/samples/sound/stream_file/data/DFN/sound/music_sound.dfn new file mode 100644 index 000000000..1935511b2 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/music_sound.dfn @@ -0,0 +1,13 @@ + + + + + + + + Tue Nov 02 11:28:10 2004 (berenguier) Dfn Structure = +Tue Nov 02 11:30:14 2004 (berenguier) Dfn Structure = +Tue Nov 02 11:40:09 2004 (berenguier) Dfn Structure = +Tue Nov 02 11:40:29 2004 (berenguier) Dfn Structure = +Wed Nov 03 10:54:07 2004 (berenguier) Dfn Structure = + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/parameter_id.typ b/code/nel/samples/sound/stream_file/data/DFN/sound/parameter_id.typ new file mode 100644 index 000000000..bc284afb2 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/parameter_id.typ @@ -0,0 +1,8 @@ + + + + + Mon Feb 10 17:31:53 2003 (boucher) Type Predef = +Mon Feb 10 17:31:53 2003 (boucher) Type Type = String +Mon Feb 10 17:31:53 2003 (boucher) Type UI = NonEditableCombo + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/pattern_mode.typ b/code/nel/samples/sound/stream_file/data/DFN/sound/pattern_mode.typ new file mode 100644 index 000000000..b0ac96de5 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/pattern_mode.typ @@ -0,0 +1,10 @@ + + + + + + Tue Oct 08 14:27:39 2002 (boucher) Type Default = Chained +Tue Oct 08 14:27:39 2002 (boucher) Type Predef = +Tue Oct 08 14:27:39 2002 (boucher) Type Type = String +Tue Oct 08 14:27:39 2002 (boucher) Type UI = NonEditableCombo + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/priority.typ b/code/nel/samples/sound/stream_file/data/DFN/sound/priority.typ new file mode 100644 index 000000000..d9bdbbd07 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/priority.typ @@ -0,0 +1,7 @@ + + + + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/rolloff.typ b/code/nel/samples/sound/stream_file/data/DFN/sound/rolloff.typ new file mode 100644 index 000000000..a5818a1a6 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/rolloff.typ @@ -0,0 +1,2 @@ + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/simple_sound.dfn b/code/nel/samples/sound/stream_file/data/DFN/sound/simple_sound.dfn new file mode 100644 index 000000000..60e97cc35 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/simple_sound.dfn @@ -0,0 +1,12 @@ + + + + + + + Wed Apr 09 21:13:23 2003 (AmazingSound) Dfn Structure = +Thu Apr 10 15:38:18 2003 (AmazingSound) Dfn Structure = +Thu Apr 10 16:24:05 2003 (AmazingSound) Dfn Structure = +Wed Apr 30 12:44:51 2003 (AmazingSound) Dfn Structure = +Wed Apr 30 12:45:39 2003 (AmazingSound) Dfn Structure = + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/sound.dfn b/code/nel/samples/sound/stream_file/data/DFN/sound/sound.dfn new file mode 100644 index 000000000..a8c336b0b --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/sound.dfn @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + Tue Oct 08 12:33:33 2002 (boucher) Dfn Structure = +Tue Oct 08 14:35:19 2002 (boucher) Dfn Structure = + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/sound_group.dfn b/code/nel/samples/sound/stream_file/data/DFN/sound/sound_group.dfn new file mode 100644 index 000000000..b058b36ff --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/sound_group.dfn @@ -0,0 +1,8 @@ + + + + Thu Jan 09 11:48:30 2003 (boucher) Dfn Structure = +Thu Jan 09 11:51:28 2003 (boucher) Dfn Structure = +Thu Jan 09 11:52:03 2003 (boucher) Dfn Structure = +Thu Jan 09 11:52:08 2003 (boucher) Dfn Structure = + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/sound_group_item.dfn b/code/nel/samples/sound/stream_file/data/DFN/sound/sound_group_item.dfn new file mode 100644 index 000000000..00420dbb9 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/sound_group_item.dfn @@ -0,0 +1,7 @@ + + + + + Thu Jan 09 11:47:55 2003 (boucher) Dfn Structure = +Thu Jan 09 11:53:15 2003 (boucher) Dfn Structure = + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/soundbank.dfn b/code/nel/samples/sound/stream_file/data/DFN/sound/soundbank.dfn new file mode 100644 index 000000000..38a60a89a --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/soundbank.dfn @@ -0,0 +1,4 @@ + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/stream_file_sound.dfn b/code/nel/samples/sound/stream_file/data/DFN/sound/stream_file_sound.dfn new file mode 100644 index 000000000..7293fc854 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/stream_file_sound.dfn @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/stream_sound.dfn b/code/nel/samples/sound/stream_file/data/DFN/sound/stream_sound.dfn new file mode 100644 index 000000000..82eaa9a6d --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/stream_sound.dfn @@ -0,0 +1,7 @@ + + + + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/transposition.typ b/code/nel/samples/sound/stream_file/data/DFN/sound/transposition.typ new file mode 100644 index 000000000..2d05a4471 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/transposition.typ @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/code/nel/samples/sound/stream_file/data/DFN/sound/user_var_binding.dfn b/code/nel/samples/sound/stream_file/data/DFN/sound/user_var_binding.dfn new file mode 100644 index 000000000..d2740f489 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/DFN/sound/user_var_binding.dfn @@ -0,0 +1,9 @@ + + + + + + Mon Feb 10 17:32:55 2003 (boucher) Dfn Structure = +Mon Feb 10 17:34:17 2003 (boucher) Dfn Structure = +Tue Feb 11 09:49:09 2003 (boucher) Dfn Structure = + diff --git a/code/nel/samples/sound/stream_file/data/animations/readme.txt b/code/nel/samples/sound/stream_file/data/animations/readme.txt new file mode 100644 index 000000000..43c7f150a --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/animations/readme.txt @@ -0,0 +1,3 @@ +This folder contains the sound track for animation. + +Put here all the .sound_anim file generated with NeL Object Viewer. \ No newline at end of file diff --git a/code/nel/samples/sound/stream_file/data/animations/test_anim.sound_anim b/code/nel/samples/sound/stream_file/data/animations/test_anim.sound_anim new file mode 100644 index 000000000..4377e81b6 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/animations/test_anim.sound_anim @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/code/nel/samples/sound/stream_file/data/background_sounds/background_sound.primitive b/code/nel/samples/sound/stream_file/data/background_sounds/background_sound.primitive new file mode 100644 index 000000000..26ff875f1 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/background_sounds/background_sound.primitive @@ -0,0 +1,144 @@ + + + + + + + + + class + audio + + + name + test_audio + + + + + class + sounds + + + name + sounds + + + + + + + + + class + sound_zone + + + name + test_zone + + + sound + beep.sound + + + + + + + + + + + class + sound_path + + + name + test_path + + + sound + tuut.sound + + + + + + + class + sound_point + + + name + test_point + + + sound + tuut.sound + + + + + + + class + sample_banks + + + name + sample_banks + + + + + + + + + bank_names + base_samples + + + class + sample_bank_zone + + + name + base_sample_zone + + + + + + + class + env_fx + + + name + env_fx + + + + + + + + + class + env_fx_zone + + + fx_name + BATHROOM + + + name + test_fx + + + + + + diff --git a/code/nel/samples/sound/stream_file/data/background_sounds/readme.txt b/code/nel/samples/sound/stream_file/data/background_sounds/readme.txt new file mode 100644 index 000000000..6103b141c --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/background_sounds/readme.txt @@ -0,0 +1 @@ +This folder contains the background sound primitive files. \ No newline at end of file diff --git a/code/nel/samples/sound/stream_file/data/cluster_sound/readme.txt b/code/nel/samples/sound/stream_file/data/cluster_sound/readme.txt new file mode 100644 index 000000000..2668e737a --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/cluster_sound/readme.txt @@ -0,0 +1,11 @@ +This folder contains Georges sheets that link sound group defined in +the cluster system (edited in 3DS Max) to a sound sheet. + +This allow to put sound inside the cluster systems. + +Each sheet can contains any number of association. +It is a good practice to merge into a single sheet all +the sound groups/sound sheets thet belong the the +same building. + + \ No newline at end of file diff --git a/code/nel/samples/sound/stream_file/data/cluster_sound/test_clusters.sound_group b/code/nel/samples/sound/stream_file/data/cluster_sound/test_clusters.sound_group new file mode 100644 index 000000000..0ee91ba18 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/cluster_sound/test_clusters.sound_group @@ -0,0 +1,19 @@ + +
+ + + + + + + + + + + + + + + + + diff --git a/code/nel/samples/sound/stream_file/data/default.mixer_config b/code/nel/samples/sound/stream_file/data/default.mixer_config new file mode 100644 index 000000000..fd9ca5a59 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/default.mixer_config @@ -0,0 +1,54 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Fri Oct 15 15:26:53 2004 (boucher) .SampleBanks[0] = base_samples + diff --git a/code/nel/samples/sound/stream_file/data/samplebank/base_samples/beep.wav b/code/nel/samples/sound/stream_file/data/samplebank/base_samples/beep.wav new file mode 100644 index 000000000..8b4108a4c Binary files /dev/null and b/code/nel/samples/sound/stream_file/data/samplebank/base_samples/beep.wav differ diff --git a/code/nel/samples/sound/stream_file/data/samplebank/base_samples/tuut.wav b/code/nel/samples/sound/stream_file/data/samplebank/base_samples/tuut.wav new file mode 100644 index 000000000..bae70bc0f Binary files /dev/null and b/code/nel/samples/sound/stream_file/data/samplebank/base_samples/tuut.wav differ diff --git a/code/nel/samples/sound/stream_file/data/soundbank/beep.sound b/code/nel/samples/sound/stream_file/data/soundbank/beep.sound new file mode 100644 index 000000000..dbda3735c --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/soundbank/beep.sound @@ -0,0 +1,19 @@ + +
+ + + + + + + + + + + + Fri Oct 15 15:23:46 2004 (boucher) .SoundType = simple_sound.dfn +Fri Oct 15 15:23:46 2004 (boucher) .SoundType.Filename = beep.wav +Fri Oct 15 15:23:46 2004 (boucher) .SoundType.MaxDistance = 1000 +Fri Oct 15 15:23:46 2004 (boucher) .SoundType.MinDistance = 1.2 +Fri Oct 15 15:27:24 2004 (boucher) .SoundType.Alpha = + diff --git a/code/nel/samples/sound/stream_file/data/soundbank/default_stream.sound b/code/nel/samples/sound/stream_file/data/soundbank/default_stream.sound new file mode 100644 index 000000000..c757128fc --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/soundbank/default_stream.sound @@ -0,0 +1,20 @@ + +
+ + + + + + + + + + + + + Thu Jan 28 23:30:44 2010 (Kaetemi) .AbsolutePosition = false +Thu Jan 28 23:30:44 2010 (Kaetemi) .Priority = Highest +Thu Jan 28 23:30:44 2010 (Kaetemi) .SoundType = stream_sound.dfn +Thu Jan 28 23:30:44 2010 (Kaetemi) .SoundType.MaxDistance = 100000 +Thu Jan 28 23:30:44 2010 (Kaetemi) .SoundType.MinDistance = 200000 + diff --git a/code/nel/samples/sound/stream_file/data/soundbank/stream_file.sound b/code/nel/samples/sound/stream_file/data/soundbank/stream_file.sound new file mode 100644 index 000000000..a98ae3a3c --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/soundbank/stream_file.sound @@ -0,0 +1,18 @@ + +
+ + + + + + + + + + + + + + + + diff --git a/code/nel/samples/sound/stream_file/data/soundbank/tuut.sound b/code/nel/samples/sound/stream_file/data/soundbank/tuut.sound new file mode 100644 index 000000000..c45cfba63 --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/soundbank/tuut.sound @@ -0,0 +1,20 @@ + +
+ + + + + + + + + + + + + Fri Oct 15 15:24:54 2004 (boucher) .SoundType = simple_sound.dfn +Fri Oct 15 15:24:54 2004 (boucher) .SoundType.Alpha = 0.5 +Fri Oct 15 15:24:54 2004 (boucher) .SoundType.Filename = tuut.wav +Fri Oct 15 15:24:54 2004 (boucher) .SoundType.MaxDistance = 50 +Fri Oct 15 15:24:54 2004 (boucher) .SoundType.MinDistance = 5 + diff --git a/code/nel/samples/sound/stream_file/data/world_editor_classes.xml b/code/nel/samples/sound/stream_file/data/world_editor_classes.xml new file mode 100644 index 000000000..68ba22ace --- /dev/null +++ b/code/nel/samples/sound/stream_file/data/world_editor_classes.xml @@ -0,0 +1,382 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/code/nel/samples/sound/stream_file/stream_file.cpp b/code/nel/samples/sound/stream_file/stream_file.cpp new file mode 100644 index 000000000..623ee4ff0 --- /dev/null +++ b/code/nel/samples/sound/stream_file/stream_file.cpp @@ -0,0 +1,184 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include + +// STL includes +#include +#ifdef NL_OS_WINDOWS +# include +#else +# include +#endif + +// NeL includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// For direct play/pause control. +// You should never include this! +#include + +// Project includes + +#ifndef NL_SOUND_DATA +#define NL_SOUND_DATA "." +#endif // NL_SOUND_DATA + +#define RYZOM_DATA "P:/data" +#define SAMPLE_OGG "Pyr Entrance.ogg" + +using namespace std; +using namespace NLMISC; +using namespace NLSOUND; + +namespace NLSAMPLE { + +static UAudioMixer *s_AudioMixer = NULL; +static USource *s_Source = NULL; +static CStreamFileSource *s_StreamFileSource = NULL; +static UGroupController *s_GroupController = NULL; + +static void initSample() +{ + if (!INelContext::isContextInitialised()) + new CApplicationContext(); + CPath::addSearchPath(NL_SOUND_DATA"/data", true, false); + + printf("Sample demonstrating OGG playback using stream file .sound sheets."); + printf("\n\n"); + + s_AudioMixer = UAudioMixer::createAudioMixer(); + + // Set the sample path before init, this allow the mixer to build the sample banks + s_AudioMixer->setSamplePath(NL_SOUND_DATA"/data/samplebank"); + // Packed sheet option, this mean we want packed sheet generated in 'data' folder + s_AudioMixer->setPackedSheetOption(NL_SOUND_DATA"/data", true); + + printf("Select NLSOUND Driver:\n"); + printf(" [1] FMod\n"); + printf(" [2] OpenAl\n"); + printf(" [3] DSound\n"); + printf(" [4] XAudio2\n"); + printf("> "); + int selection = getchar(); getchar(); + printf("\n"); + + // init with 8 tracks, EAX enabled, no ADPCM, and automatic sample bank loading + s_AudioMixer->init(8, true, false, NULL, true, (UAudioMixer::TDriver)(selection - '0')); + s_AudioMixer->setLowWaterMark(1); + + CVector initpos(0.0f, 0.0f, 0.0f); + CVector frontvec(0.0f, 1.0f, 0.0f); + CVector upvec(0.0f, 0.0f, 1.0f); + s_AudioMixer->getListener()->setPos(initpos); + s_AudioMixer->getListener()->setOrientation(frontvec, upvec); + + CPath::addSearchPath(RYZOM_DATA, true, false); + + //NLMISC::CHTimer::startBench(); + + s_Source = s_AudioMixer->createSource(CStringMapper::map("stream_file")); + nlassert(s_Source); + s_StreamFileSource = dynamic_cast(s_Source); + nlassert(s_StreamFileSource); + // s_Source->setSourceRelativeMode(true); + // s_Source->setPitch(2.0f); + + s_GroupController = s_AudioMixer->getGroupController("sound:dialog"); +} + +static void runSample() +{ + s_Source->play(); + + printf("Change volume with - and +\n"); + printf("Press ANY other key to exit\n"); + for (; ; ) + { +#ifdef NL_OS_WINDOWS + if (_kbhit()) + { + switch (_getch()) +#else + char ch; + if (read(0, &ch, 1)) + { + switch (ch) +#endif + { + case '+': + s_GroupController->setGain(s_GroupController->getGain() + 0.1f); + break; + case '-': + s_GroupController->setGain(s_GroupController->getGain() - 0.1f); + break; + case 'x': + s_Source->stop(); + break; + case 's': + s_Source->play(); + break; + case 'p': + s_StreamFileSource->pause(); + break; + case 'r': + s_StreamFileSource->resume(); + break; + case 'e': + s_AudioMixer->playMusic(SAMPLE_OGG, 1000, true, false); + break; + default: + return; + } + } + + s_AudioMixer->update(); + + nlSleep(40); + } +} + +static void releaseSample() +{ + //NLMISC::CHTimer::clear(); + s_GroupController = NULL; + s_StreamFileSource = NULL; + delete s_Source; s_Source = NULL; + delete s_AudioMixer; s_AudioMixer = NULL; +} + + + +} /* namespace NLSAMPLE */ + +int main() +{ + NLSAMPLE::initSample(); + NLSAMPLE::runSample(); + NLSAMPLE::releaseSample(); + return 0; +} + +/* end of file */ diff --git a/code/nel/samples/sound/stream_ogg_vorbis/CMakeLists.txt b/code/nel/samples/sound/stream_ogg_vorbis/CMakeLists.txt new file mode 100644 index 000000000..db978fc88 --- /dev/null +++ b/code/nel/samples/sound/stream_ogg_vorbis/CMakeLists.txt @@ -0,0 +1,12 @@ +FILE(GLOB SRC *.cpp *.h) + +ADD_EXECUTABLE(nl_sample_stream_ogg_vorbis ${SRC}) + +INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR}) + +TARGET_LINK_LIBRARIES(nl_sample_stream_ogg_vorbis nelmisc nelsound) +NL_DEFAULT_PROPS(nl_sample_stream_ogg_vorbis "NeL, Samples: Sound: Stream OGG Vorbis") +NL_ADD_RUNTIME_FLAGS(nl_sample_stream_ogg_vorbis) + +INSTALL(TARGETS nl_sample_stream_ogg_vorbis RUNTIME DESTINATION bin COMPONENT samplessound) + diff --git a/code/nel/samples/sound/stream_ogg_vorbis/stream_ogg_vorbis.cpp b/code/nel/samples/sound/stream_ogg_vorbis/stream_ogg_vorbis.cpp index 441eee932..e0f0df705 100644 --- a/code/nel/samples/sound/stream_ogg_vorbis/stream_ogg_vorbis.cpp +++ b/code/nel/samples/sound/stream_ogg_vorbis/stream_ogg_vorbis.cpp @@ -18,16 +18,10 @@ // STL includes #include -#include - -// 3rd Party includes #ifdef NL_OS_WINDOWS -# pragma warning( push ) -# pragma warning( disable : 4244 ) -#endif -#include -#ifdef NL_OS_WINDOWS -# pragma warning( pop ) +# include +#else +# include #endif // NeL includes @@ -40,6 +34,8 @@ #include #include #include +#include +#include #include // Project includes @@ -48,7 +44,7 @@ #define NL_SOUND_DATA "." #endif // NL_SOUND_DATA -#define SAMPLE_OGG "O:/src/samples/music_stream/data/aeon_1_10_mystic_river.ogg" +#define SAMPLE_OGG "D:/source/kaetemi/toverhex/src/samples/music_stream/data/aeon_1_10_mystic_river.ogg" using namespace std; using namespace NLMISC; @@ -56,275 +52,10 @@ using namespace NLSOUND; namespace NLSAMPLE { -/** - * \brief IAudioDecoder - * \date 2008-08-30 11:38GMT - * \author Jan Boon (Kaetemi) - * IAudioDecoder is only used by the driver implementation to stream - * music files into a readable format (it's a simple decoder interface). - * You should not call these functions (getSongTitle) on nlsound or user level, - * as a driver might have additional music types implemented. - * TODO: Split IAudioDecoder into IAudioDecoder (actual decoding) and IMediaDemuxer (stream splitter), and change the interface to make more sense. - * TODO: Allow user application to register more decoders. - * TODO: Look into libavcodec for decoding audio? - */ -class IAudioDecoder -{ -private: - // pointers - /// Stream from file created by IAudioDecoder - NLMISC::IStream *_InternalStream; - -public: - IAudioDecoder(); - virtual ~IAudioDecoder(); - - /// Create a new music buffer, may return NULL if unknown type, destroy with delete. Filepath lookup done here. If async is true, it will stream from hd, else it will load in memory first. - static IAudioDecoder *createAudioDecoder(const std::string &filepath, bool async, bool loop); - - /// Create a new music buffer from a stream, type is file extension like "ogg" etc. - static IAudioDecoder *createAudioDecoder(const std::string &type, NLMISC::IStream *stream, bool loop); - - /// Get information on a music file (only artist and title at the moment). - static bool getInfo(const std::string &filepath, std::string &artist, std::string &title); - - /// Get audio/container extensions that are currently supported by the nel sound library. - static void getMusicExtensions(std::vector &extensions); - - /// Return if a music extension is supported by the nel sound library. - static bool isMusicExtensionSupported(const std::string &extension); - - /// Get how many bytes the music buffer requires for output minimum. - virtual uint32 getRequiredBytes() = 0; - - /// Get an amount of bytes between minimum and maximum (can be lower than minimum if at end). - virtual uint32 getNextBytes(uint8 *buffer, uint32 minimum, uint32 maximum) = 0; - - /// Get the amount of channels (2 is stereo) in output. - virtual uint8 getChannels() = 0; - - /// Get the samples per second (often 44100) in output. - virtual uint getSamplesPerSec() = 0; - - /// Get the bits per sample (often 16) in output. - virtual uint8 getBitsPerSample() = 0; - - /// Get if the music has ended playing (never true if loop). - virtual bool isMusicEnded() = 0; - - /// Get the total time in seconds. - virtual float getLength() = 0; -}; /* class IAudioDecoder */ - -/** - * \brief CAudioDecoderVorbis - * \date 2008-08-30 11:38GMT - * \author Jan Boon (Kaetemi) - * CAudioDecoderVorbis - * Create trough IAudioDecoder, type "ogg" - */ -class CAudioDecoderVorbis : public IAudioDecoder -{ -protected: - // outside pointers - NLMISC::IStream *_Stream; - - // pointers - - // instances - OggVorbis_File _OggVorbisFile; - bool _Loop; - bool _IsMusicEnded; - sint32 _StreamOffset; - sint32 _StreamSize; -public: - CAudioDecoderVorbis(NLMISC::IStream *stream, bool loop); - virtual ~CAudioDecoderVorbis(); - inline NLMISC::IStream *getStream() { return _Stream; } - inline sint32 getStreamSize() { return _StreamSize; } - inline sint32 getStreamOffset() { return _StreamOffset; } - - /// Get information on a music file (only artist and title at the moment). - static bool getInfo(NLMISC::IStream *stream, std::string &artist, std::string &title); - - /// Get how many bytes the music buffer requires for output minimum. - virtual uint32 getRequiredBytes(); - - /// Get an amount of bytes between minimum and maximum (can be lower than minimum if at end). - virtual uint32 getNextBytes(uint8 *buffer, uint32 minimum, uint32 maximum); - - /// Get the amount of channels (2 is stereo) in output. - virtual uint8 getChannels(); - - /// Get the samples per second (often 44100) in output. - virtual uint getSamplesPerSec(); - - /// Get the bits per sample (often 16) in output. - virtual uint8 getBitsPerSample(); - - /// Get if the music has ended playing (never true if loop). - virtual bool isMusicEnded(); - - /// Get the total time in seconds. - virtual float getLength(); -}; /* class CAudioDecoderVorbis */ - -IAudioDecoder::IAudioDecoder() : _InternalStream(NULL) -{ - -} - -IAudioDecoder::~IAudioDecoder() -{ - if (_InternalStream) { delete _InternalStream; _InternalStream = NULL; } -} - -IAudioDecoder *IAudioDecoder::createAudioDecoder(const std::string &filepath, bool async, bool loop) -{ - string lookup = CPath::lookup(filepath, false); - if (lookup.empty()) - { - nlwarning("Music file %s does not exist!", filepath.c_str()); - return NULL; - } - string type = CFile::getExtension(filepath); - - CIFile *ifile = new CIFile(); - ifile->setCacheFileOnOpen(!async); - ifile->allowBNPCacheFileOnOpen(!async); - ifile->open(lookup); - - IAudioDecoder *mb = createAudioDecoder(type, ifile, loop); - - if (mb) mb->_InternalStream = ifile; - else delete ifile; - - return mb; -} - -IAudioDecoder *IAudioDecoder::createAudioDecoder(const std::string &type, NLMISC::IStream *stream, bool loop) -{ - if (!stream) - { - nlwarning("Stream is NULL"); - return NULL; - } - string type_lower = toLower(type); - if (type_lower == "ogg") - { - return new CAudioDecoderVorbis(stream, loop); - } - else - { - nlwarning("Music file type unknown: '%s'", type_lower.c_str()); - return NULL; - } -} - -bool IAudioDecoder::getInfo(const std::string &filepath, std::string &artist, std::string &title) -{ - string lookup = CPath::lookup(filepath, false); - if (lookup.empty()) - { - nlwarning("Music file %s does not exist!", filepath.c_str()); - return false; - } - string type = CFile::getExtension(filepath); - string type_lower = toLower(type); - - if (type_lower == "ogg") - { - CIFile ifile; - ifile.setCacheFileOnOpen(false); - ifile.allowBNPCacheFileOnOpen(false); - ifile.open(lookup); - return CAudioDecoderVorbis::getInfo(&ifile, artist, title); - } - else - { - nlwarning("Music file type unknown: '%s'", type_lower.c_str()); - artist.clear(); title.clear(); - return false; - } -} - -/// Get audio/container extensions that are currently supported by the nel sound library. -void IAudioDecoder::getMusicExtensions(std::vector &extensions) -{ - extensions.push_back("ogg"); - // extensions.push_back("wav"); // TODO: Easy. -} - -/// Return if a music extension is supported by the nel sound library. -bool IAudioDecoder::isMusicExtensionSupported(const std::string &extension) -{ - return (extension == "ogg"); -} - -size_t vorbisReadFunc(void *ptr, size_t size, size_t nmemb, void *datasource) -{ - CAudioDecoderVorbis *audio_decoder_vorbis = (CAudioDecoderVorbis *)datasource; - NLMISC::IStream *stream = audio_decoder_vorbis->getStream(); - nlassert(stream->isReading()); - sint32 length = (sint32)(size * nmemb); - if (length > audio_decoder_vorbis->getStreamSize() - stream->getPos()) - length = audio_decoder_vorbis->getStreamSize() - stream->getPos(); - stream->serialBuffer((uint8 *)ptr, length); - return length; -} - -int vorbisSeekFunc(void *datasource, ogg_int64_t offset, int whence) -{ - if (whence == SEEK_CUR && offset == 0) - { - // nlwarning(NLSOUND_XAUDIO2_PREFIX "This seek call doesn't do a damn thing, wtf."); - return 0; // ooookkaaaaaayyy - } - - CAudioDecoderVorbis *audio_decoder_vorbis = (CAudioDecoderVorbis *)datasource; - - NLMISC::IStream::TSeekOrigin origin; - switch (whence) - { - case SEEK_SET: - origin = NLMISC::IStream::begin; - break; - case SEEK_CUR: - origin = NLMISC::IStream::current; - break; - case SEEK_END: - origin = NLMISC::IStream::end; - break; - default: - // nlwarning(NLSOUND_XAUDIO2_PREFIX "Seeking to fake origin."); - return -1; - } - - if (audio_decoder_vorbis->getStream()->seek(SEEK_SET ? audio_decoder_vorbis->getStreamOffset() + (sint32)offset : (sint32)offset, origin)) return 0; - else return -1; -} - -//int vorbisCloseFunc(void *datasource) -//{ -// //CAudioDecoderVorbis *audio_decoder_vorbis = (CAudioDecoderVorbis *)datasource; -//} - -long vorbisTellFunc(void *datasource) -{ - CAudioDecoderVorbis *audio_decoder_vorbis = (CAudioDecoderVorbis *)datasource; - return (long)(audio_decoder_vorbis->getStream()->getPos() - audio_decoder_vorbis->getStreamOffset()); -} - -static ov_callbacks OV_CALLBACKS_NLMISC_STREAM = { - (size_t (*)(void *, size_t, size_t, void *)) vorbisReadFunc, - (int (*)(void *, ogg_int64_t, int)) vorbisSeekFunc, - (int (*)(void *)) NULL, //vorbisCloseFunc, - (long (*)(void *)) vorbisTellFunc -}; - static UAudioMixer *s_AudioMixer = NULL; static UStreamSource *s_StreamSource = NULL; static IAudioDecoder *s_AudioDecoder = NULL; +static UGroupController *s_GroupController = NULL; static void initSample() { @@ -367,6 +98,9 @@ static void initSample() string sample = SAMPLE_OGG; s_AudioDecoder = IAudioDecoder::createAudioDecoder(sample, false, false); s_StreamSource->setFormat(s_AudioDecoder->getChannels(), s_AudioDecoder->getBitsPerSample(), (uint32)s_AudioDecoder->getSamplesPerSec()); + //s_StreamSource->setPitch(2.0f); + + s_GroupController = s_AudioMixer->getGroupController("sound:dialog"); } //CMutex *s_Mutex = NULL; @@ -404,15 +138,33 @@ static void runSample() s_StreamSource->play(); - printf("Press ANY key to exit\n"); + printf("Change volume with - and +\n"); + printf("Press ANY other key to exit\n"); while (!s_AudioDecoder->isMusicEnded()) { +#ifdef NL_OS_WINDOWS if (_kbhit()) { - _getch(); - return; + switch (_getch()) +#else + char ch; + if (read(0, &ch, 1)) + { + switch (ch) +#endif + { + case '+': + s_GroupController->setGain(s_GroupController->getGain() + 0.1f); + break; + case '-': + s_GroupController->setGain(s_GroupController->getGain() - 0.1f); + break; + default: + return; + } } bufferMore(bytes); + s_AudioMixer->update(); //if (!s_StreamSource->asUSource()->isst) //{ // printf("*!playing!*"); @@ -424,122 +176,32 @@ static void runSample() while (s_StreamSource->hasFilledBuffersAvailable()) { nlSleep(40); + s_AudioMixer->update(); } s_StreamSource->stop(); printf("End of song\n"); printf("Press ANY key to exit\n"); - while (!_kbhit()) { s_AudioMixer->update(); Sleep(10); } _getch(); +#ifdef NL_OS_WINDOWS + while (!_kbhit()) +#else + char ch; + while (!read(0, &ch, 1)) +#endif + { s_AudioMixer->update(); nlSleep(10); } return; } static void releaseSample() { //NLMISC::CHTimer::clear(); + s_GroupController = NULL; delete s_AudioDecoder; s_AudioDecoder = NULL; delete s_StreamSource; s_StreamSource = NULL; delete s_AudioMixer; s_AudioMixer = NULL; } -CAudioDecoderVorbis::CAudioDecoderVorbis(NLMISC::IStream *stream, bool loop) -: _Stream(stream), _Loop(loop), _StreamSize(0), _IsMusicEnded(false) -{ - _StreamOffset = stream->getPos(); - stream->seek(0, NLMISC::IStream::end); - _StreamSize = stream->getPos(); - stream->seek(_StreamOffset, NLMISC::IStream::begin); - ov_open_callbacks(this, &_OggVorbisFile, NULL, 0, OV_CALLBACKS_NLMISC_STREAM); -} - -CAudioDecoderVorbis::~CAudioDecoderVorbis() -{ - ov_clear(&_OggVorbisFile); -} - -/// Get information on a music file (only artist and title at the moment). -bool CAudioDecoderVorbis::getInfo(NLMISC::IStream *stream, std::string &artist, std::string &title) -{ - CAudioDecoderVorbis mbv(stream, false); // just opens and closes the oggvorbisfile thing :) - vorbis_comment *vc = ov_comment(&mbv._OggVorbisFile, -1); - char *title_c = vorbis_comment_query(vc, "title", 0); - if (title_c) title = title_c; else title.clear(); - char *artist_c = vorbis_comment_query(vc, "artist", 0); - if (artist_c) artist = artist_c; else artist.clear(); - return true; -} - -uint32 CAudioDecoderVorbis::getRequiredBytes() -{ - return 0; // no minimum requirement of bytes to buffer out -} - -uint32 CAudioDecoderVorbis::getNextBytes(uint8 *buffer, uint32 minimum, uint32 maximum) -{ - int current_section = 0; // ??? - if (_IsMusicEnded) return 0; - nlassert(minimum <= maximum); // can't have this.. - uint32 bytes_read = 0; - do - { - // signed 16-bit or unsigned 8-bit little-endian samples - int br = ov_read(&_OggVorbisFile, (char *)&buffer[bytes_read], maximum - bytes_read, - 0, // Specifies big or little endian byte packing. 0 for little endian, 1 for b ig endian. Typical value is 0. - getBitsPerSample() == 8 ? 1 : 2, - getBitsPerSample() == 8 ? 0 : 1, // Signed or unsigned data. 0 for unsigned, 1 for signed. Typically 1. - ¤t_section); - // nlinfo(NLSOUND_XAUDIO2_PREFIX "current_section: %i", current_section); - if (br <= 0) - { - if (br == 0) - { - if (_Loop) - { - ov_pcm_seek(&_OggVorbisFile, 0); - //_Stream->seek(0, NLMISC::IStream::begin); - } - else - { - _IsMusicEnded = true; - break; - } - } - else - { - nlwarning("ov_read: %i", br); - } - } - else bytes_read += (uint32)br; - } while (bytes_read < minimum); - return bytes_read; -} - -uint8 CAudioDecoderVorbis::getChannels() -{ - vorbis_info *vi = ov_info(&_OggVorbisFile, -1); - return (uint8)vi->channels; -} - -uint CAudioDecoderVorbis::getSamplesPerSec() -{ - vorbis_info *vi = ov_info(&_OggVorbisFile, -1); - return (uint)vi->rate; -} - -uint8 CAudioDecoderVorbis::getBitsPerSample() -{ - return 16; -} - -bool CAudioDecoderVorbis::isMusicEnded() -{ - return _IsMusicEnded; -} - -float CAudioDecoderVorbis::getLength() -{ - return (float)ov_time_total(&_OggVorbisFile, -1); -} } /* namespace NLSAMPLE */ diff --git a/code/nel/samples/sound_sources/Makefile.am b/code/nel/samples/sound_sources/Makefile.am deleted file mode 100644 index 1e05afa90..000000000 --- a/code/nel/samples/sound_sources/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2005/04/04 09:45:06 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -bin_PROGRAMS = sound_sources - -sound_sources_SOURCES = main.cpp - -AM_CXXFLAGS = -I$(top_srcdir)/src - -sound_sources_LDADD = ../../src/misc/libnelmisc.la \ - ../../src/sound/libnelsnd.la \ - ../../src/sound/driver/libnelsnd_lowlevel.la \ - ../../src/sound/driver/fmod/libnel_drv_fmod.la \ - ../../src/ligo/libnelligo.la \ - ../../src/georges/libnelgeorges.la \ - ../../src/3d/libnel3d.la - - -# End of Makefile.am - diff --git a/code/nel/src/3d/CMakeLists.txt b/code/nel/src/3d/CMakeLists.txt index 3888be211..45b38fcbd 100644 --- a/code/nel/src/3d/CMakeLists.txt +++ b/code/nel/src/3d/CMakeLists.txt @@ -706,6 +706,9 @@ IF(WITH_PCH) ENDIF(WITH_PCH) NL_GEN_PC(nel-3d.pc) -INSTALL(TARGETS nel3d LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries) + +IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) + INSTALL(TARGETS nel3d LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries) +ENDIF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) ADD_SUBDIRECTORY(driver) diff --git a/code/nel/src/3d/Makefile.am b/code/nel/src/3d/Makefile.am deleted file mode 100644 index 441c4ee47..000000000 --- a/code/nel/src/3d/Makefile.am +++ /dev/null @@ -1,616 +0,0 @@ -# -# - -MAINTAINERCLEANFILES = Makefile.in - -SUBDIRS = driver - -lib_LTLIBRARIES = libnel3d.la - -EXTRA_DIST = mesh_mrm_skin_template.cpp mesh_mrm_skinned_template.cpp - -libnel3d_la_SOURCES = \ - anim_ctrl.cpp \ - anim_detail_trav.cpp \ - anim_detail_trav.h \ - animatable.cpp \ - animatable.h \ - animated_lightmap.cpp \ - animated_lightmap.h \ - animated_material.cpp \ - animated_material.h \ - animated_morph.cpp \ - animated_morph.h \ - animated_value.cpp \ - animated_value.h \ - animation.cpp \ - animation.h \ - animation_optimizer.cpp \ - animation_optimizer.h \ - animation_playlist.cpp \ - animation_playlist.h \ - animation_set.cpp \ - animation_set.h \ - animation_set_user.cpp \ - animation_set_user.h \ - animation_time.cpp \ - async_file_manager_3d.cpp \ - async_file_manager_3d.h \ - async_texture_block.cpp \ - async_texture_block.h \ - async_texture_manager.cpp \ - async_texture_manager.h \ - bezier_patch.cpp \ - bezier_patch.h \ - bloom_effect.cpp \ - bloom_effect.h \ - bone.cpp \ - bone.h \ - bsp_tree.h \ - camera.cpp \ - camera.h \ - camera_col.cpp \ - camera_col.h \ - channel_mixer.cpp \ - channel_mixer.h \ - clip_trav.cpp \ - clip_trav.h \ - cloud.cpp \ - cloud.h \ - cloud_scape.cpp \ - cloud_scape.h \ - cloud_scape_user.cpp \ - cloud_scape_user.h \ - cluster.cpp \ - cluster.h \ - coarse_mesh_build.cpp \ - coarse_mesh_build.h \ - coarse_mesh_manager.cpp \ - coarse_mesh_manager.h \ - computed_string.cpp \ - computed_string.h \ - cube_grid.cpp \ - cube_grid.h \ - cube_map_builder.cpp \ - cube_map_builder.h \ - debug_vb.cpp \ - debug_vb.h \ - deform_2d.cpp \ - deform_2d.h \ - driver.cpp \ - driver.h \ - driver_material_inline.h \ - driver_user.cpp \ - driver_user.h \ - driver_user2.cpp \ - dru.cpp \ - dru.h \ - event_mouse_listener.cpp \ - event_mouse_listener.h \ - fast_ptr_list.cpp \ - fast_ptr_list.h \ - fasthls_modifier.cpp \ - fasthls_modifier.h \ - flare_model.cpp \ - flare_model.h \ - flare_shape.cpp \ - flare_shape.h \ - font_generator.cpp \ - font_generator.h \ - font_manager.cpp \ - font_manager.h \ - frustum.cpp \ - heat_haze.cpp \ - heat_haze.h \ - height_map.cpp \ - hls_color_texture.cpp \ - hls_color_texture.h \ - hls_texture_bank.cpp \ - hls_texture_bank.h \ - hls_texture_manager.cpp \ - hls_texture_manager.h \ - hrc_trav.cpp \ - hrc_trav.h \ - ig_surface_light.cpp \ - ig_surface_light.h \ - ig_surface_light_build.cpp \ - ig_surface_light_build.h \ - index_buffer.cpp \ - index_buffer.h \ - init_3d.cpp \ - init_3d.h \ - instance_group_user.cpp \ - instance_group_user.h \ - instance_lighter.cpp \ - instance_lighter.h \ - key.cpp \ - key.h \ - landscape.cpp \ - landscape.h \ - landscape_collision_grid.cpp \ - landscape_collision_grid.h \ - landscape_def.cpp \ - landscape_def.h \ - landscape_face_vector_manager.cpp \ - landscape_face_vector_manager.h \ - landscape_model.cpp \ - landscape_model.h \ - landscape_profile.cpp \ - landscape_profile.h \ - landscape_user.cpp \ - landscape_user.h \ - landscape_vegetable_block.cpp \ - landscape_vegetable_block.h \ - landscapeig_manager.cpp \ - landscapevb_allocator.cpp \ - landscapevb_allocator.h \ - landscapevb_info.cpp \ - landscapevb_info.h \ - layered_ordering_table.h \ - light.cpp \ - light.h \ - light_contribution.cpp \ - light_contribution.h \ - light_influence_interpolator.cpp \ - light_influence_interpolator.h \ - light_trav.cpp \ - light_trav.h \ - light_user.cpp \ - light_user.h \ - lighting_manager.cpp \ - lighting_manager.h \ - load_balancing_trav.cpp \ - load_balancing_trav.h \ - lod_character_builder.cpp \ - lod_character_builder.h \ - lod_character_instance.cpp \ - lod_character_instance.h \ - lod_character_manager.cpp \ - lod_character_manager.h \ - lod_character_shape.cpp \ - lod_character_shape.h \ - lod_character_shape_bank.cpp \ - lod_character_shape_bank.h \ - lod_character_texture.cpp \ - lod_character_texture.h \ - logic_info.cpp \ - material.cpp \ - material.h \ - matrix_3x4.cpp \ - matrix_3x4.h \ - mesh.cpp \ - mesh.h \ - mesh_base.cpp \ - mesh_base.h \ - mesh_base_instance.cpp \ - mesh_base_instance.h \ - mesh_blender.cpp \ - mesh_blender.h \ - mesh_block_manager.cpp \ - mesh_block_manager.h \ - mesh_geom.cpp \ - mesh_geom.h \ - mesh_instance.cpp \ - mesh_instance.h \ - mesh_morpher.cpp \ - mesh_morpher.h \ - mesh_mrm.cpp \ - mesh_mrm.h \ - mesh_mrm_instance.cpp \ - mesh_mrm_instance.h \ - mesh_mrm_skin.cpp \ - mesh_mrm_skin_template.cpp \ - mesh_mrm_skinned.cpp \ - mesh_mrm_skinned.h \ - mesh_mrm_skinned_instance.cpp \ - mesh_mrm_skinned_instance.h \ - mesh_mrm_skinned_template.cpp \ - mesh_multi_lod.cpp \ - mesh_multi_lod.h \ - mesh_multi_lod_instance.cpp \ - mesh_multi_lod_instance.h \ - mesh_vertex_program.cpp \ - mesh_vertex_program.h \ - meshvp_per_pixel_light.cpp \ - meshvp_per_pixel_light.h \ - meshvp_wind_tree.cpp \ - meshvp_wind_tree.h \ - mini_col.cpp \ - mini_col.h \ - motion_blur.cpp \ - motion_blur.h \ - mrm_builder.cpp \ - mrm_builder.h \ - mrm_internal.cpp \ - mrm_internal.h \ - mrm_level_detail.cpp \ - mrm_level_detail.h \ - mrm_mesh.cpp \ - mrm_mesh.h \ - mrm_parameters.cpp \ - mrm_parameters.h \ - nelu.cpp \ - nelu.h \ - noise_3d.cpp \ - noise_3d.h \ - occlusion_query.h \ - ordering_table.h \ - packed_zone.cpp \ - packed_zone.h \ - packed_world.cpp \ - packed_world.h \ - particle_system.cpp \ - particle_system.h \ - particle_system_manager.cpp \ - particle_system_manager.h \ - particle_system_model.cpp \ - particle_system_model.h \ - particle_system_process.cpp \ - particle_system_process.h \ - particle_system_shape.cpp \ - particle_system_shape.h \ - particle_system_sound_user.cpp \ - patch.cpp \ - patch.h \ - patch_lightmap.cpp \ - patch_noise.cpp \ - patch_rdr_pass.cpp \ - patch_rdr_pass.h \ - patch_render.cpp \ - patch_vegetable.cpp \ - patchdlm_context.cpp \ - patchdlm_context.h \ - patchuv_locator.cpp \ - patchuv_locator.h \ - play_list_manager.cpp \ - play_list_manager.h \ - play_list_manager_user.cpp \ - play_list_manager_user.h \ - play_list_user.cpp \ - play_list_user.h \ - point_light.cpp \ - point_light.h \ - point_light_model.cpp \ - point_light_model.h \ - point_light_named.cpp \ - point_light_named.h \ - point_light_named_array.cpp \ - point_light_named_array.h \ - portal.cpp \ - portal.h \ - primitive_profile.cpp \ - ps_allocator.cpp \ - ps_allocator.h \ - ps_attrib.h \ - ps_attrib_maker.h \ - ps_attrib_maker_bin_op.cpp \ - ps_attrib_maker_bin_op.h \ - ps_attrib_maker_bin_op_inline.h \ - ps_attrib_maker_helper.cpp \ - ps_attrib_maker_helper.h \ - ps_attrib_maker_iterators.h \ - ps_attrib_maker_template.cpp \ - ps_attrib_maker_template.h \ - ps_color.cpp \ - ps_color.h \ - ps_direction.h \ - ps_dot.cpp \ - ps_dot.h \ - ps_edit.h \ - ps_emitter.cpp \ - ps_emitter.h \ - ps_face.cpp \ - ps_face.h \ - ps_face_look_at.cpp \ - ps_face_look_at.h \ - ps_fan_light.cpp \ - ps_fan_light.h \ - ps_float.cpp \ - ps_float.h \ - ps_force.cpp \ - ps_force.h \ - ps_int.cpp \ - ps_int.h \ - ps_iterator.h \ - ps_light.cpp \ - ps_light.h \ - ps_located.cpp \ - ps_located.h \ - ps_lod.h \ - ps_macro.h \ - ps_mesh.cpp \ - ps_mesh.h \ - ps_misc.h \ - ps_particle.cpp \ - ps_particle.h \ - ps_particle2.cpp \ - ps_particle2.h \ - ps_particle_basic.cpp \ - ps_particle_basic.h \ - ps_plane_basis.h \ - ps_plane_basis_maker.cpp \ - ps_plane_basis_maker.h \ - ps_quad.cpp \ - ps_quad.h \ - ps_register_attribs.cpp \ - ps_register_color_attribs.h \ - ps_register_emitters.cpp \ - ps_register_float_attribs.h \ - ps_register_forces.cpp \ - ps_register_int_attribs.h \ - ps_register_particles.cpp \ - ps_register_plane_basis_attribs.h \ - ps_register_zones.cpp \ - ps_ribbon.cpp \ - ps_ribbon.h \ - ps_ribbon_base.cpp \ - ps_ribbon_base.h \ - ps_ribbon_look_at.cpp \ - ps_ribbon_look_at.h \ - ps_shockwave.cpp \ - ps_shockwave.h \ - ps_spawn_info.h \ - ps_sound.cpp \ - ps_sound.h \ - ps_tail_dot.cpp \ - ps_tail_dot.h \ - ps_util.cpp \ - ps_util.h \ - ps_zone.cpp \ - ps_zone.h \ - ptr_set.cpp \ - ptr_set.h \ - quad_effect.cpp \ - quad_effect.h \ - quad_grid.cpp \ - quad_grid.h \ - quad_grid_clip_cluster.cpp \ - quad_grid_clip_cluster.h \ - quad_grid_clip_manager.cpp \ - quad_grid_clip_manager.h \ - radix_sort.cpp \ - radix_sort.h \ - raw_skin.cpp \ - raw_skin.h \ - raw_skinned.cpp \ - raw_skinned.h \ - ray_mesh.cpp \ - ray_mesh.h \ - register_3d.cpp \ - register_3d.h \ - render_trav.cpp \ - render_trav.h \ - root_model.cpp \ - root_model.h \ - scene.cpp \ - scene.h \ - scene_group.cpp \ - scene_group.h \ - scene_user.cpp \ - scene_user.h \ - scissor.cpp \ - seg_remanence.cpp \ - seg_remanence.h \ - seg_remanence_shape.cpp \ - seg_remanence_shape.h \ - shader.cpp \ - shader.h \ - shadow_map.cpp \ - shadow_map.h \ - shadow_map_manager.cpp \ - shadow_map_manager.h \ - shadow_poly_receiver.cpp \ - shadow_poly_receiver.h \ - shadow_skin.cpp \ - shadow_skin.h \ - shape.cpp \ - shape.h \ - shape_bank.cpp \ - shape_bank.h \ - shape_bank_user.cpp \ - shape_bank_user.h \ - shape_info.cpp \ - shape_info.h \ - shifted_triangle_cache.cpp \ - shifted_triangle_cache.h \ - skeleton_model.cpp \ - skeleton_model.h \ - skeleton_shape.cpp \ - skeleton_shape.h \ - skeleton_spawn_script.cpp \ - skeleton_spawn_script.h \ - skeleton_weight.cpp \ - skeleton_weight.h \ - static_quad_grid.cpp \ - static_quad_grid.h \ - std3d.cpp \ - std3d.h \ - stripifier.cpp \ - stripifier.h \ - surface_light_grid.cpp \ - surface_light_grid.h \ - tangent_space_build.cpp \ - tangent_space_build.h \ - target_anim_ctrl.cpp \ - tess_block.cpp \ - tess_block.h \ - tess_face_priority_list.cpp \ - tess_face_priority_list.h \ - tess_list.cpp \ - tess_list.h \ - tessellation.cpp \ - tessellation.h \ - text_context.cpp \ - text_context.h \ - text_context_user.cpp \ - text_context_user.h \ - texture.cpp \ - texture.h \ - texture_blank.cpp \ - texture_blank.h \ - texture_bloom.cpp \ - texture_bloom.h \ - texture_blend.cpp \ - texture_blend.h \ - texture_bump.cpp \ - texture_bump.h \ - texture_cube.cpp \ - texture_cube.h \ - texture_dlm.cpp \ - texture_dlm.h \ - texture_emboss.cpp \ - texture_emboss.h \ - texture_far.cpp \ - texture_far.h \ - texture_file.cpp \ - texture_file.h \ - texture_font.cpp \ - texture_font.h \ - texture_grouped.cpp \ - texture_grouped.h \ - texture_mem.cpp \ - texture_mem.h \ - texture_multi_file.cpp \ - texture_multi_file.h \ - texture_near.cpp \ - texture_near.h \ - texture_user.cpp \ - texture_user.h \ - tile_bank.cpp \ - tile_bank.h \ - tile_color.cpp \ - tile_color.h \ - tile_element.cpp \ - tile_element.h \ - tile_far_bank.cpp \ - tile_far_bank.h \ - tile_light_influence.cpp \ - tile_light_influence.h \ - tile_lumel.cpp \ - tile_lumel.h \ - tile_noise_map.cpp \ - tile_noise_map.h \ - tile_vegetable_desc.cpp \ - tile_vegetable_desc.h \ - track.cpp \ - track.h \ - track_bezier.h \ - track_keyframer.cpp \ - track_keyframer.h \ - track_sampled_common.cpp \ - track_sampled_common.h \ - track_sampled_quat.cpp \ - track_sampled_quat.h \ - track_sampled_quat_small_header.cpp \ - track_sampled_quat_small_header.h \ - track_sampled_vector.cpp \ - track_sampled_vector.h \ - track_tcb.h \ - transform.cpp \ - transform.h \ - transform_shape.cpp \ - transform_shape.h \ - transformable.cpp \ - transformable.h \ - trav_scene.cpp \ - trav_scene.h \ - u_bone.cpp \ - u_camera.cpp \ - u_instance.cpp \ - u_instance_material.cpp \ - u_material.cpp \ - u_particle_system_instance.cpp \ - u_point_light.cpp \ - u_shape.cpp \ - u_skeleton.cpp \ - u_transform.cpp \ - u_transformable.cpp \ - u_visual_collision_mesh.cpp \ - u_water.cpp \ - vegetable.cpp \ - vegetable.h \ - vegetable_blend_layer_model.cpp \ - vegetable_blend_layer_model.h \ - vegetable_clip_block.cpp \ - vegetable_clip_block.h \ - vegetable_def.cpp \ - vegetable_def.h \ - vegetable_instance_group.cpp \ - vegetable_instance_group.h \ - vegetable_light_ex.cpp \ - vegetable_light_ex.h \ - vegetable_manager.cpp \ - vegetable_manager.h \ - vegetable_quadrant.cpp \ - vegetable_quadrant.h \ - vegetable_shape.cpp \ - vegetable_shape.h \ - vegetable_sort_block.cpp \ - vegetable_sort_block.h \ - vegetable_uv8.cpp \ - vegetable_uv8.h \ - vegetablevb_allocator.cpp \ - vegetablevb_allocator.h \ - vertex_buffer.cpp \ - vertex_buffer.h \ - vertex_buffer_heap.cpp \ - vertex_buffer_heap.h \ - vertex_program.cpp \ - vertex_program.h \ - vertex_program_parse.cpp \ - vertex_program_parse.h \ - vertex_stream_manager.cpp \ - vertex_stream_manager.h \ - viewport.cpp \ - visual_collision_entity.cpp \ - visual_collision_entity.h \ - visual_collision_entity_user.cpp \ - visual_collision_entity_user.h \ - visual_collision_manager.cpp \ - visual_collision_manager.h \ - visual_collision_manager_user.cpp \ - visual_collision_manager_user.h \ - visual_collision_mesh.cpp \ - visual_collision_mesh.h \ - water_env_map.cpp \ - water_env_map.h \ - water_env_map_user.cpp \ - water_env_map_user.h \ - water_height_map.cpp \ - water_height_map.h \ - water_model.cpp \ - water_model.h \ - water_pool_manager.cpp \ - water_pool_manager.h \ - water_shape.cpp \ - water_shape.h \ - zone.cpp \ - zone.h \ - zone_corner_smoother.cpp \ - zone_corner_smoother.h \ - zone_lighter.cpp \ - zone_lighter.h \ - zone_manager.cpp \ - zone_manager.h \ - zone_search.cpp \ - zone_search.h \ - zone_smoother.cpp \ - zone_smoother.h \ - zone_symmetrisation.cpp \ - zone_symmetrisation.h \ - zone_tgt_smoother.cpp \ - zone_tgt_smoother.h - -noinst_HEADERS = std3d.h -# mesh_vertex_program.h meshvp_wind_tree.h - -AM_CXXFLAGS = -I$(top_srcdir)/src @FREETYPE_CFLAGS@ - -libnel3d_la_LIBADD = @FREETYPE_LIBS@ -lc -ldl -lpthread - -libnel3d_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = nel-3d.pc - -# End of Makefile.am diff --git a/code/nel/src/3d/driver/Makefile.am b/code/nel/src/3d/driver/Makefile.am deleted file mode 100644 index 0603c2362..000000000 --- a/code/nel/src/3d/driver/Makefile.am +++ /dev/null @@ -1,10 +0,0 @@ -# -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = direct3d - -SUBDIRS = opengl - -# End of Makefile.am diff --git a/code/nel/src/3d/driver/direct3d/CMakeLists.txt b/code/nel/src/3d/driver/direct3d/CMakeLists.txt index 5011c3c45..cc61fa9bd 100644 --- a/code/nel/src/3d/driver/direct3d/CMakeLists.txt +++ b/code/nel/src/3d/driver/direct3d/CMakeLists.txt @@ -16,7 +16,9 @@ IF(WITH_PCH) ADD_NATIVE_PRECOMPILED_HEADER(nel_drv_direct3d_win ${CMAKE_CURRENT_SOURCE_DIR}/stddirect3d.h ${CMAKE_CURRENT_SOURCE_DIR}/stddirect3d.cpp) ENDIF(WITH_PCH) -INSTALL(TARGETS nel_drv_direct3d_win LIBRARY DESTINATION ${NL_DRIVER_PREFIX} ARCHIVE DESTINATION lib RUNTIME DESTINATION bin COMPONENT drivers3d) -IF(WITH_MAXPLUGIN) - INSTALL(TARGETS nel_drv_direct3d_win RUNTIME DESTINATION maxplugin COMPONENT drivers3d) -ENDIF(WITH_MAXPLUGIN) +IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC_DRIVERS) OR NOT WITH_STATIC_DRIVERS) + INSTALL(TARGETS nel_drv_direct3d_win LIBRARY DESTINATION ${NL_DRIVER_PREFIX} ARCHIVE DESTINATION lib RUNTIME DESTINATION bin COMPONENT drivers3d) + IF(WITH_MAXPLUGIN) + INSTALL(TARGETS nel_drv_direct3d_win RUNTIME DESTINATION maxplugin COMPONENT drivers3d) + ENDIF(WITH_MAXPLUGIN) +ENDIF((WITH_INSTALL_LIBRARIES AND WITH_STATIC_DRIVERS) OR NOT WITH_STATIC_DRIVERS) diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp index 5ac1d2906..bfbd3fdb7 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp @@ -1228,7 +1228,7 @@ bool CDriverD3D::init (uint windowIcon, emptyProc exitFunc) ExitFunc = exitFunc; createCursors(); - + // Register a window class WNDCLASSW wc; diff --git a/code/nel/src/3d/driver/opengl/CMakeLists.txt b/code/nel/src/3d/driver/opengl/CMakeLists.txt index 6fdecab71..d90c7e0b3 100644 --- a/code/nel/src/3d/driver/opengl/CMakeLists.txt +++ b/code/nel/src/3d/driver/opengl/CMakeLists.txt @@ -61,7 +61,9 @@ IF(NOT APPLE AND WITH_PCH) ADD_NATIVE_PRECOMPILED_HEADER(${NLDRV_OGL_LIB} ${CMAKE_CURRENT_SOURCE_DIR}/stdopengl.h ${CMAKE_CURRENT_SOURCE_DIR}/stdopengl.cpp) ENDIF(NOT APPLE AND WITH_PCH) -INSTALL(TARGETS ${NLDRV_OGL_LIB} LIBRARY DESTINATION ${NL_DRIVER_PREFIX} ARCHIVE DESTINATION lib RUNTIME DESTINATION bin COMPONENT drivers3d) -IF(WITH_MAXPLUGIN) - INSTALL(TARGETS ${NLDRV_OGL_LIB} RUNTIME DESTINATION maxplugin COMPONENT drivers3d) -ENDIF(WITH_MAXPLUGIN) +IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC_DRIVERS) OR NOT WITH_STATIC_DRIVERS) + INSTALL(TARGETS ${NLDRV_OGL_LIB} LIBRARY DESTINATION ${NL_DRIVER_PREFIX} ARCHIVE DESTINATION lib RUNTIME DESTINATION bin COMPONENT drivers3d) + IF(WITH_MAXPLUGIN) + INSTALL(TARGETS ${NLDRV_OGL_LIB} RUNTIME DESTINATION maxplugin COMPONENT drivers3d) + ENDIF(WITH_MAXPLUGIN) +ENDIF((WITH_INSTALL_LIBRARIES AND WITH_STATIC_DRIVERS) OR NOT WITH_STATIC_DRIVERS) diff --git a/code/nel/src/3d/driver/opengl/Makefile.am b/code/nel/src/3d/driver/opengl/Makefile.am deleted file mode 100644 index 744801217..000000000 --- a/code/nel/src/3d/driver/opengl/Makefile.am +++ /dev/null @@ -1,47 +0,0 @@ -# -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = driver_opengl_8.vcproj \ - driver_opengl.vcproj \ - driver_opengl.dsp \ - driver_opengl.def - -lib_LTLIBRARIES = libnel_drv_opengl.la - -libnel_drv_opengl_la_SOURCES = driver_opengl.cpp \ - driver_opengl.h \ - driver_opengl_extension.cpp \ - driver_opengl_extension.h \ - driver_opengl_extension_def.h \ - driver_opengl_light.cpp \ - driver_opengl_mac.cpp \ - driver_opengl_material.cpp \ - driver_opengl_matrix.cpp \ - driver_opengl_states.cpp \ - driver_opengl_states.h \ - driver_opengl_texture.cpp \ - driver_opengl_vertex.cpp \ - driver_opengl_vertex_buffer_hard.cpp \ - driver_opengl_vertex_buffer_hard.h \ - driver_opengl_vertex_program.cpp \ - stdopengl.cpp \ - stdopengl.h \ - unix_event_emitter.cpp \ - unix_event_emitter.h - - -noinst_HEADERS = stdopengl.h - -AM_CXXFLAGS = -I$(top_srcdir)/src \ - @OPENGL_CFLAGS@ @XF86VIDMODE_CFLAGS@ - -libnel_drv_opengl_la_LIBADD = @OPENGL_LIBS@ @XF86VIDMODE_LIBS@ -lXmu -libnel_drv_opengl_la_LDFLAGS = -no-undefined - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = nel-driverogl.pc - -# End of Makefile.am - diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_light.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_light.cpp index e5c3cff6e..2fc25f94a 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_light.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_light.cpp @@ -138,7 +138,7 @@ void CDriverGL::setLightInternal(uint8 num, const CLight& light) } else { - // Deactivate spot properties + // Disable spot properties #ifdef USE_OPENGLES glLightf (lightNum, GL_SPOT_CUTOFF, 180.f); glLightf (lightNum, GL_SPOT_EXPONENT, 0.f); diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp index 502c971f1..7241d499b 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp @@ -978,7 +978,7 @@ void CDriverGL::setupGlArraysStd(CVertexBufferInfo &vb) // Check type nlassert (vb.Type[CVertexBuffer::Normal]==CVertexBuffer::Float3); _DriverGLStates.enableNormalArray(true); - nglArrayObjectATI(GL_NORMAL_ARRAY, 3, GL_FLOAT, vb.VertexSize, vb.VertexObjectId, (ptrdiff_t) vb.ValuePtr[CVertexBuffer::Normal]); + nglArrayObjectATI(GL_NORMAL_ARRAY, 3, GL_FLOAT, vb.VertexSize, vb.VertexObjectId, (ptrdiff_t) vb.ValuePtr[CVertexBuffer::Normal]); } else { diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp index 6501d70c4..6ebcff4c7 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -188,6 +188,9 @@ bool GlWndProc(CDriverGL *driver, const void* e) static Atom XA_WM_STATE = 0; static Atom XA_WM_STATE_FULLSCREEN = 0; static Atom XA_WM_ICON = 0; +static Atom XA_WM_WINDOW_TYPE = 0; +static Atom XA_WM_WINDOW_TYPE_NORMAL = 0; +static Atom XA_FRAME_EXTENTS = 0; sint nelXErrorsHandler(Display *dpy, XErrorEvent *e) { @@ -233,7 +236,7 @@ bool GlWndProc(CDriverGL *driver, XEvent &e) break; case Expose: - nlwarning("Expose event"); +// nlwarning("Expose event"); break; case ConfigureNotify: @@ -243,20 +246,36 @@ bool GlWndProc(CDriverGL *driver, XEvent &e) // first time setting decoration sizes if ((driver->_DecorationWidth == -1) || (driver->_DecorationWidth == 0)) { - driver->_DecorationWidth = e.xconfigure.x - driver->_WindowX; - driver->_DecorationHeight = e.xconfigure.y - driver->_WindowY; + Atom type_return = 0; + int format_return = 0; + unsigned long nitems_return = 0; + unsigned long bytes_after_return = 0; + long *data = NULL; + + int status = XGetWindowProperty(driver->_dpy, driver->_win, XA_FRAME_EXTENTS, 0, 4, False, XA_CARDINAL, &type_return, &format_return, &nitems_return, &bytes_after_return, (unsigned char**)&data); - nlwarning("Decoration size x = %d, y = %d", driver->_DecorationWidth, driver->_DecorationHeight); + // succeeded to retrieve decoration size + if (status == Success && type_return == XA_CARDINAL && format_return == 32 && nitems_return == 4 && data) + { + driver->_DecorationWidth = data[0]; + driver->_DecorationHeight = data[2]; + } + else + { + // use difference between current position and previous one (set by application) + driver->_DecorationWidth = e.xconfigure.x - driver->_WindowX; + driver->_DecorationHeight = e.xconfigure.y - driver->_WindowY; + } + + // don't allow negative decoration sizes + if (driver->_DecorationWidth < 0) driver->_DecorationWidth = 0; + if (driver->_DecorationHeight < 0) driver->_DecorationHeight = 0; } driver->_CurrentMode.Width = e.xconfigure.width; driver->_CurrentMode.Height = e.xconfigure.height; driver->_WindowX = e.xconfigure.x - driver->_DecorationWidth; driver->_WindowY = e.xconfigure.y - driver->_DecorationHeight; - - XConfigureEvent event = e.xconfigure; - - nlwarning("Configure x = %d, y = %d, width = %d, height = %d, send event = %d", event.x, event.y, event.width, event.height, event.send_event); } break; @@ -401,6 +420,9 @@ bool CDriverGL::init (uint windowIcon, emptyProc exitFunc) XA_WM_STATE = XInternAtom(_dpy, "_NET_WM_STATE", False); XA_WM_STATE_FULLSCREEN = XInternAtom(_dpy, "_NET_WM_STATE_FULLSCREEN", False); XA_WM_ICON = XInternAtom(_dpy, "_NET_WM_ICON", False); + XA_WM_WINDOW_TYPE = XInternAtom(_dpy, "_NET_WM_WINDOW_TYPE", False); + XA_WM_WINDOW_TYPE_NORMAL = XInternAtom(_dpy, "_NET_WM_WINDOW_TYPE_NORMAL", False); + XA_FRAME_EXTENTS = XInternAtom(_dpy, "_NET_FRAME_EXTENTS", False); #endif @@ -1528,6 +1550,42 @@ bool CDriverGL::createWindow(const GfxMode &mode) return false; } + // normal window type + XChangeProperty(_dpy, window, XA_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (const unsigned char*)&XA_WM_WINDOW_TYPE_NORMAL, 1); + + // set WM hints + XWMHints *wm_hints = XAllocWMHints(); + + if (wm_hints) + { + wm_hints->flags = StateHint | InputHint; + wm_hints->initial_state = NormalState; + wm_hints->input = True; + + XSetWMHints(_dpy, window, wm_hints); + XFree(wm_hints); + } + else + { + nlwarning("3D: Couldn't allocate XWMHints"); + } + + // set class hints + XClassHint *class_hints = XAllocClassHint(); + + if (class_hints) + { + class_hints->res_name = (char*)"NeL"; + class_hints->res_class = (char*)"nel"; + + XSetClassHint(_dpy, window, class_hints); + XFree(class_hints); + } + else + { + nlwarning("3D: Couldn't allocate XClassHint"); + } + #endif // NL_OS_UNIX _win = window; @@ -2201,11 +2259,19 @@ void CDriverGL::setWindowTitle(const ucstring &title) #elif defined (NL_OS_UNIX) #ifdef X_HAVE_UTF8_STRING + // UTF8 properties Xutf8SetWMProperties (_dpy, _win, (char*)title.toUtf8().c_str(), (char*)title.toUtf8().c_str(), NULL, 0, NULL, NULL, NULL); #else + // standard properties XTextProperty text_property; - XStringListToTextProperty((char**)&title.toUtf8().c_str(), 1, &text_property); - XSetWMProperties (_dpy, _win, &text_property, &text_property, 0, 0, NULL, 0, 0); + if (XStringListToTextProperty((char**)&title.toUtf8().c_str(), 1, &text_property) != 0) + { + XSetWMProperties (_dpy, _win, &text_property, &text_property, NULL, 0, NULL, NULL, NULL); + } + else + { + nlwarning("3D: Can't convert title to TextProperty"); + } #endif #endif // NL_OS_WINDOWS diff --git a/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.cpp b/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.cpp index 95c713021..15bb40d28 100644 --- a/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.cpp +++ b/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.cpp @@ -149,14 +149,28 @@ static NLMISC::TKey virtualKeycodeToNelKey(unsigned short keycode) bool CCocoaEventEmitter::pasteTextFromClipboard(ucstring &text) { -#warning "OpenGL Driver: Missing Mac Implementation for pasteTextFromClipboard" + NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; + NSArray *classArray = [NSArray arrayWithObject:[NSString class]]; + NSDictionary *options = [NSDictionary dictionary]; + + BOOL ok = [pasteboard canReadObjectForClasses:classArray options:options]; + if (ok) + { + NSArray *objectsToPaste = [pasteboard readObjectsForClasses:classArray options:options]; + NSString *nstext = [objectsToPaste objectAtIndex:0]; + text.fromUtf8([nstext UTF8String]); + return true; + } return false; } bool CCocoaEventEmitter::copyTextToClipboard(const ucstring &text) { -#warning "OpenGL Driver: Missing Mac Implementation for copyTextToClipboard" - return false; + NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; + [pasteboard clearContents]; + NSArray *copiedObjects = [NSArray arrayWithObject:[NSString stringWithUTF8String:text.toUtf8().c_str()]]; + [pasteboard writeObjects:copiedObjects]; + return true; } /// convert modifier key state to nel internal modifier key state diff --git a/code/nel/src/3d/driver/opengl/mac/glext.h b/code/nel/src/3d/driver/opengl/mac/glext.h index 7d222aa19..6bcd8c238 100644 --- a/code/nel/src/3d/driver/opengl/mac/glext.h +++ b/code/nel/src/3d/driver/opengl/mac/glext.h @@ -4851,8 +4851,10 @@ typedef ptrdiff_t GLsizeiptrARB; #ifndef GL_ARB_shader_objects /* GL types for program/shader text and shader object handles */ typedef char GLcharARB; +#if !defined(MAC_OS_X_VERSION_10_7) typedef unsigned int GLhandleARB; #endif +#endif /* GL type for "half" precision (s10e5) float data in host memory */ #ifndef GL_ARB_half_float_pixel diff --git a/code/nel/src/3d/nelu.cpp b/code/nel/src/3d/nelu.cpp index 80ef89ec4..3d143bce1 100644 --- a/code/nel/src/3d/nelu.cpp +++ b/code/nel/src/3d/nelu.cpp @@ -58,7 +58,7 @@ bool CNELU::initDriver (uint w, uint h, uint bpp, bool windowed, nlWindow syst CNELU::Driver = NULL; // Init driver. -#if defined(NL_OS_WINDOWS) +#ifdef NL_OS_WINDOWS if (direct3d) { CNELU::Driver= CDRU::createD3DDriver(); @@ -75,6 +75,7 @@ bool CNELU::initDriver (uint w, uint h, uint bpp, bool windowed, nlWindow syst nlwarning ("CNELU::initDriver: no driver found"); return false; } + if (!CNELU::Driver->init()) { nlwarning ("CNELU::initDriver: init() failed"); diff --git a/code/nel/src/3d/particle_system_shape.cpp b/code/nel/src/3d/particle_system_shape.cpp index 5e41ba530..fb7aaa405 100644 --- a/code/nel/src/3d/particle_system_shape.cpp +++ b/code/nel/src/3d/particle_system_shape.cpp @@ -39,7 +39,11 @@ namespace NL3D { using NLMISC::CIFile; +namespace { +NLMISC::CMutex s_PSSMutex; + +} /* anonymous namespace */ // private usage : macro to check the memory integrity #if defined(NL_DEBUG) && defined(NL_OS_WINDOWS) @@ -220,9 +224,8 @@ CParticleSystem *CParticleSystemShape::instanciatePS(CScene &scene, NLMISC::CCon return _SharedSystem; } - // avoid prb with concurent thread (may append if an instance group containing ps is loaded in background) - NLMISC::CMutex mutex; - mutex.enter(); + // avoid prb with concurrent thread (may happen if an instance group containing ps is loaded in background) + s_PSSMutex.enter(); #ifdef PS_FAST_ALLOC @@ -295,7 +298,7 @@ CParticleSystem *CParticleSystemShape::instanciatePS(CScene &scene, NLMISC::CCon } #endif - mutex.leave(); + s_PSSMutex.leave(); /*NLMISC::TTicks end = NLMISC::CTime::getPerformanceTime(); nlinfo("instanciation time = %.2f", (float) (1000 * NLMISC::CTime::ticksToSecond(end - start))); */ @@ -390,8 +393,7 @@ void CParticleSystemShape::flushTextures(IDriver &driver, uint selectedTexture) } else { - NLMISC::CMutex mutex; - mutex.enter(); + s_PSSMutex.enter(); // must create an instance just to flush the textures CParticleSystem *myInstance = NULL; @@ -436,7 +438,7 @@ void CParticleSystemShape::flushTextures(IDriver &driver, uint selectedTexture) #ifdef PS_FAST_ALLOC PSBlockAllocator = NULL; #endif - mutex.leave(); + s_PSSMutex.leave(); } for(uint k = 0; k < _CachedTex.size(); ++k) { diff --git a/code/nel/src/3d/patchdlm_context.cpp b/code/nel/src/3d/patchdlm_context.cpp index f5a5b578d..e50f1befe 100644 --- a/code/nel/src/3d/patchdlm_context.cpp +++ b/code/nel/src/3d/patchdlm_context.cpp @@ -1018,8 +1018,8 @@ void CPatchDLMContext::computeTextureFar() // compute src pixel const CRGBA *srcPixel= pTile->getPixels(CTileFarBank::diffuse, CTileFarBank::order1); // compute src info, for this tile rot and 256x256 context. - sint srcDeltaX; - sint srcDeltaY; + sint srcDeltaX = 0; + sint srcDeltaY = 0; srcPixel= computeTileFarSrcDeltas(nRot, is256x256, uvOff, srcPixel, srcDeltaX, srcDeltaY); // compute dst coordinate. start writing at pixel (1,1) diff --git a/code/nel/src/Makefile.am b/code/nel/src/Makefile.am deleted file mode 100644 index dbedcae88..000000000 --- a/code/nel/src/Makefile.am +++ /dev/null @@ -1,19 +0,0 @@ -# -# - -MAINTAINERCLEANFILES = Makefile.in - -DIST_SUBDIRS = net 3d pacs sound misc georges ligo - -SUBDIRS = @NEL_SUBDIRS@ - -EXTRA_DIST = 3d.vcproj \ - georges.vcproj \ - ligo.vcproj \ - logic.vcproj \ - misc.vcproj \ - net.vcproj \ - pacs.vcproj \ - sound.vcproj - -# End of Makefile.am diff --git a/code/nel/src/Rules.mk b/code/nel/src/Rules.mk deleted file mode 100644 index cb5d3dc57..000000000 --- a/code/nel/src/Rules.mk +++ /dev/null @@ -1,56 +0,0 @@ -############################################################################# -# A few basic default rules and intrinsic rules - -# Load objects dependencies -ifeq (Dependencies.mk,$(wildcard Dependencies.mk)) -include Dependencies.mk -check-deps: - @echo - @echo Dependencies found [OK] - @echo -else -check-deps: - @echo - @echo "No dependencies found [ERROR]" - @echo "You should try 'make update' first" - @echo - @exit 1 -endif - -# Start off by over-riding the default build rules with our own intrinsics -.SUFFIXES: -.SUFFIXES: .cpp .o -.cpp.o: - $(CXX) -c $(CXXFLAGS) $< -o $@ - -# remove object files and core (if any) -clean: - find . -name "core*" -exec $(RM) {} \; - find . -name "*.o" -exec $(RM) {} \; - find . -name "*~" -exec $(RM) {} \; - find . -name "Dependencies.mk" -exec $(RM) {} \; - -# remove object files, core dump, and executable (if any) -distclean: - $(MAKE) clean - $(RM) $(TARGETS) - $(RM) $(TARGETS)_debug - -# make the thing again from scratch -again: - $(MAKE) distclean - $(MAKE) $(TARGETS) - -UPDATE_OBJS=`cat ../$(DSP_TARGET) | grep SOURCE | sed -e 's/\r$$//' | grep "\.cpp$$" | cut -d\\\\ -f3- | tr '\n' ' ' | sed -e 's/=/..\\\\/g' | tr '\n' ' ' | sed -e 's/\\\\/\\//g' | sed -e 's/\.cpp /\.o /g'` - -UPDATE_SRCS=`cat ../$(DSP_TARGET) | grep SOURCE | sed -e 's/\r$$//' | grep "\.cpp$$" | cut -d\\\\ -f3- | tr '\n' ' ' | sed -e 's/=/..\\\\/g' | tr '\n' ' ' | sed -e 's/\\\\/\\//g'` - -dep: update - -update: - ../gen_deps.sh $(CXX) $(CXXFLAGS) -- $(UPDATE_SRCS) > Dependencies.mk - echo "OBJS=$(UPDATE_OBJS)" > Objects.mk - -touch: - $(RM) $(TARGETS) - $(RM) $(TARGETS)_debug diff --git a/code/nel/src/Variables.mk b/code/nel/src/Variables.mk deleted file mode 100644 index 216b4b1c8..000000000 --- a/code/nel/src/Variables.mk +++ /dev/null @@ -1,20 +0,0 @@ -############################################################################# -# Setting up the global compiler settings... - -# The names of the executables -CXX = c++ -RM = rm -f -MAKE = make - -DBG = off - -FLAGS_CMN = -g -pipe -Wno-ctor-dtor-privacy -Wno-multichar -D_REENTRANT -DHAVE_X86 - -FLAGS_DBG_on = -O0 -finline-functions -DNL_DEBUG -DNL_DEBUG_FAST -FLAGS_DBG_off = -O3 -ftemplate-depth-24 -funroll-loops -DNL_RELEASE_DEBUG -DIR_DBG_on = debug -DIR_DBG_off = release - -ifeq (Objects.mk,$(wildcard Objects.mk)) -include Objects.mk -endif diff --git a/code/nel/src/cegui/CMakeLists.txt b/code/nel/src/cegui/CMakeLists.txt index 99fcfedf3..342e08780 100644 --- a/code/nel/src/cegui/CMakeLists.txt +++ b/code/nel/src/cegui/CMakeLists.txt @@ -11,4 +11,6 @@ NL_ADD_LIB_SUFFIX(nelceguirenderer) ADD_DEFINITIONS(${LIBXML2_DEFINITIONS} -DNEL_CEGUIRENDERER_EXPORTS) -INSTALL(TARGETS nelceguirenderer RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries) +IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) + INSTALL(TARGETS nelceguirenderer RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries) +ENDIF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) diff --git a/code/nel/src/cegui/Makefile.am b/code/nel/src/cegui/Makefile.am deleted file mode 100644 index 43786d8e8..000000000 --- a/code/nel/src/cegui/Makefile.am +++ /dev/null @@ -1,19 +0,0 @@ -# -# $Id: Makefile.am,v 1.7 2002-06-10 17:02:05 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -lib_LTLIBRARIES = libnelceguirenderer.la - -libnelceguirenderer_la_SOURCES = nelrenderer.cpp nelresourceprovider.cpp neltexture.cpp - -AM_CXXFLAGS = -I$(top_srcdir)/src @CEGUI_CFLAGS@ - -libnelceguirenderer_la_LIBADD = -lc -lpthread @CEGUI_LIBS@ - -libnelceguirenderer_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ - - -# End of Makefile.am - diff --git a/code/nel/src/gen_deps.sh b/code/nel/src/gen_deps.sh deleted file mode 100755 index 45f41e17f..000000000 --- a/code/nel/src/gen_deps.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh - -command='' -sources='' -phase=0 -for arg in $* -do - if [ "$phase" == 0 ] && [ "$arg" == '--' ] - then - phase=1 - elif [ "$phase" == 0 ] - then - command="$command $arg" - elif [ "$phase" == 1 ] - then - sources="$sources $arg" - fi -done - -for src in $sources -do - obj=`echo $src | sed -e 's/.cpp$/.o/'` - $command -MT $obj -M $src -done - diff --git a/code/nel/src/georges/CMakeLists.txt b/code/nel/src/georges/CMakeLists.txt index d3c0199d7..6954bb87b 100644 --- a/code/nel/src/georges/CMakeLists.txt +++ b/code/nel/src/georges/CMakeLists.txt @@ -21,4 +21,7 @@ IF(WITH_PCH) ENDIF(WITH_PCH) NL_GEN_PC(nel-georges.pc) -INSTALL(TARGETS nelgeorges LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries) + +IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) + INSTALL(TARGETS nelgeorges LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries) +ENDIF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) diff --git a/code/nel/src/georges/Makefile.am b/code/nel/src/georges/Makefile.am deleted file mode 100644 index 389110b9f..000000000 --- a/code/nel/src/georges/Makefile.am +++ /dev/null @@ -1,34 +0,0 @@ -# -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = georges_file_format.txt - -lib_LTLIBRARIES = libnelgeorges.la - -libnelgeorges_la_SOURCES = form.cpp \ - form.h \ - form_loader.cpp \ - form_loader.h \ - form_dfn.cpp \ - form_dfn.h \ - form_elm.cpp \ - form_elm.h \ - stdgeorges.cpp \ - stdgeorges.h \ - header.cpp \ - header.h \ - load_form.cpp \ - type.cpp \ - type.h - -AM_CXXFLAGS = -I$(top_srcdir)/src - -libnelgeorges_la_LIBADD = -lc -lpthread - -libnelgeorges_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ - - -# End of Makefile.am - diff --git a/code/nel/src/ligo/CMakeLists.txt b/code/nel/src/ligo/CMakeLists.txt index f600637b7..4d8d49f3d 100644 --- a/code/nel/src/ligo/CMakeLists.txt +++ b/code/nel/src/ligo/CMakeLists.txt @@ -19,4 +19,7 @@ IF(WITH_PCH) ENDIF(WITH_PCH) NL_GEN_PC(nel-ligo.pc) -INSTALL(TARGETS nelligo LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries) + +IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) + INSTALL(TARGETS nelligo LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries) +ENDIF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) diff --git a/code/nel/src/ligo/Makefile.am b/code/nel/src/ligo/Makefile.am deleted file mode 100644 index db6e5d423..000000000 --- a/code/nel/src/ligo/Makefile.am +++ /dev/null @@ -1,36 +0,0 @@ -# -# - -MAINTAINERCLEANFILES = Makefile.in - -lib_LTLIBRARIES = libnelligo.la - -libnelligo_la_SOURCES = ligo_config.cpp \ - ligo_error.cpp \ - ligo_error.h \ - ligo_material.cpp \ - ligo_material.h \ - primitive.cpp \ - primitive_class.cpp \ - primitive_configuration.cpp \ - transition.cpp \ - transition.h \ - zone_bank.cpp \ - zone_bank.h \ - zone_edge.cpp \ - zone_edge.h \ - zone_region.cpp \ - zone_region.h \ - zone_template.cpp \ - zone_template.h \ - primitive_utils.cpp - -AM_CXXFLAGS = -I$(top_srcdir)/src - -libnelligo_la_LIBADD = -lc -lpthread - -libnelligo_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ - - -# End of Makefile.am - diff --git a/code/nel/src/ligo/primitive.cpp b/code/nel/src/ligo/primitive.cpp index ff8c71c18..62c4ab9d6 100644 --- a/code/nel/src/ligo/primitive.cpp +++ b/code/nel/src/ligo/primitive.cpp @@ -2118,7 +2118,7 @@ bool CPrimAlias::read (xmlNodePtr xmlNode, const char *filename, uint version, C xmlNodePtr ptNode = CIXml::getFirstChildNode (xmlNode, "ALIAS"); if (ptNode) { - int val; + sint val = 0; if (ReadInt ("VALUE", val, filename, ptNode)) { _Alias = uint32(val); diff --git a/code/nel/src/logic/CMakeLists.txt b/code/nel/src/logic/CMakeLists.txt index 107c57850..c84e8d18e 100644 --- a/code/nel/src/logic/CMakeLists.txt +++ b/code/nel/src/logic/CMakeLists.txt @@ -14,4 +14,6 @@ NL_ADD_LIB_SUFFIX(nellogic) ADD_DEFINITIONS(${LIBXML2_DEFINITIONS}) -INSTALL(TARGETS nellogic LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries) +IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) + INSTALL(TARGETS nellogic LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries) +ENDIF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) diff --git a/code/nel/src/misc/CMakeLists.txt b/code/nel/src/misc/CMakeLists.txt index 1710e5b6b..38d291552 100644 --- a/code/nel/src/misc/CMakeLists.txt +++ b/code/nel/src/misc/CMakeLists.txt @@ -53,4 +53,7 @@ IF(WITH_PCH) ENDIF(WITH_PCH) NL_GEN_PC(nel-misc.pc) -INSTALL(TARGETS nelmisc LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries) + +IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) + INSTALL(TARGETS nelmisc LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries) +ENDIF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) diff --git a/code/nel/src/misc/Makefile.am b/code/nel/src/misc/Makefile.am deleted file mode 100644 index 345a210c4..000000000 --- a/code/nel/src/misc/Makefile.am +++ /dev/null @@ -1,142 +0,0 @@ -# -# - -MAINTAINERCLEANFILES = Makefile.in - -SUBDIRS = config_file - -lib_LTLIBRARIES = libnelmisc.la - -libnelmisc_la_SOURCES = \ - aabbox.cpp \ - app_context.cpp \ - algo.cpp \ - async_file_manager.cpp \ - big_file.cpp \ - bit_mem_stream.cpp \ - bit_set.cpp \ - bitmap.cpp \ - bitmap_jpeg.cpp \ - bitmap_png.cpp \ - block_memory.cpp \ - bsphere.cpp \ - buf_fifo.cpp \ - class_id.cpp \ - class_registry.cpp \ - command.cpp \ - common.cpp \ - contiguous_block_allocator.cpp \ - cpu_time_stat.cpp \ - debug.cpp \ - di_event_emitter.cpp \ - di_game_device.cpp \ - di_game_device.h \ - di_keyboard_device.cpp \ - di_keyboard_device.h \ - di_mouse_device.cpp \ - di_mouse_device.h \ - diff_tool.cpp \ - displayer.cpp \ - eid_translator.cpp \ - entity_id.cpp \ - eval_num_expr.cpp \ - event_emitter.cpp \ - event_emitter_multi.cpp \ - event_listener.cpp \ - event_server.cpp \ - events.cpp \ - fast_floor.cpp \ - fast_mem.cpp \ - file.cpp \ - fixed_size_allocator.cpp \ - game_device.cpp \ - game_device_events.cpp \ - geom_ext.cpp \ - grid_traversal.cpp \ - gtk_displayer.cpp \ - heap_memory.cpp \ - hierarchical_timer.cpp \ - i18n.cpp \ - i_xml.cpp \ - input_device.cpp \ - input_device_server.cpp \ - keyboard_device.cpp \ - line.cpp \ - log.cpp \ - matrix.cpp \ - md5.cpp \ - mem_displayer.cpp \ - mem_stream.cpp \ - mouse_smoother.cpp \ - mutex.cpp \ - noise_value.cpp \ - o_xml.cpp \ - object_arena_allocator.cpp \ - object_vector.cpp \ - p_thread.cpp \ - path.cpp \ - plane.cpp \ - polygon.cpp \ - progress_callback.cpp \ - quad.cpp \ - quat.cpp \ - reader_writer.cpp \ - rect.cpp \ - report.cpp \ - rgba.cpp \ - sha1.cpp \ - shared_memory.cpp \ - sheet_id.cpp \ - smart_ptr.cpp \ - stdmisc.cpp \ - stdmisc.h \ - stl_block_allocator.cpp \ - stl_block_list.cpp \ - stop_watch.cpp \ - stream.cpp \ - string_common.cpp \ - string_id_array.cpp \ - string_mapper.cpp \ - system_info.cpp \ - system_utils.cpp \ - task_manager.cpp \ - tds.cpp \ - time_nl.cpp \ - triangle.cpp \ - uv.cpp \ - unicode.cpp \ - value_smoother.cpp \ - variable.cpp \ - vector.cpp \ - vector_2d.cpp \ - vector_2f.cpp \ - vector_h.cpp \ - vectord.cpp \ - win_displayer.cpp \ - win_event_emitter.cpp \ - win_thread.cpp \ - window_displayer.cpp \ - words_dictionary.cpp \ - dynloadlib.cpp \ - sstring.cpp \ - co_task.cpp \ - xml_pack.cpp \ - inter_window_msg_queue.cpp \ - win32_util.cpp - - -noinst_HEADERS = di_game_device.h \ - di_keyboard_device.h \ - di_mouse_device.h \ - stdmisc.h - - -libnelmisc_la_LIBADD = config_file/libconfig.la -lc -lpthread -lrt -ldl -lpng -ljpeg - -libnelmisc_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = nel-misc.pc - -# End of Makefile.am - diff --git a/code/nel/src/misc/bit_mem_stream.cpp b/code/nel/src/misc/bit_mem_stream.cpp index c050d9c61..007b95cbc 100644 --- a/code/nel/src/misc/bit_mem_stream.cpp +++ b/code/nel/src/misc/bit_mem_stream.cpp @@ -599,7 +599,7 @@ void CBitMemStream::append( const CBitMemStream& newBits ) /* * Serial bitmemstream */ -void CBitMemStream::serialMemStream(CBitMemStream &b) +void CBitMemStream::serialMemStream(CMemStream &b) { #ifdef LOG_ALL_TRAFFIC sint32 bitpos = getPosInBit(); diff --git a/code/nel/src/misc/bitmap_jpeg.cpp b/code/nel/src/misc/bitmap_jpeg.cpp index 835110d86..a4eaaa0b9 100644 --- a/code/nel/src/misc/bitmap_jpeg.cpp +++ b/code/nel/src/misc/bitmap_jpeg.cpp @@ -109,7 +109,7 @@ static void jpgDecompressSkip(j_decompress_ptr cinfo, long num_bytes) } } -static void jpgDecompressTerm(j_decompress_ptr cinfo) +static void jpgDecompressTerm(j_decompress_ptr /* cinfo */) { } diff --git a/code/nel/src/misc/co_task.cpp b/code/nel/src/misc/co_task.cpp index 1880be06c..c66941a40 100644 --- a/code/nel/src/misc/co_task.cpp +++ b/code/nel/src/misc/co_task.cpp @@ -237,12 +237,15 @@ namespace NLMISC _PImpl = new TCoTaskData(this); // _PImpl->_TaskThreadId = 0; // _PImpl->_ParentThreadId = 0; + nlunreferenced(stackSize); #else //NL_USE_THREAD_COTASK // allocate platform specific data storage _PImpl = new TCoTaskData; + nlunreferenced(stackSize); #if defined (NL_OS_WINDOWS) _PImpl->_Fiber = NULL; _PImpl->_ParentFiber = NULL; + nlunreferenced(stackSize); #elif defined(NL_OS_UNIX) // allocate the stack _PImpl->_Stack = new uint8[stackSize]; diff --git a/code/nel/src/misc/command.cpp b/code/nel/src/misc/command.cpp index 80d074386..f2b422d69 100644 --- a/code/nel/src/misc/command.cpp +++ b/code/nel/src/misc/command.cpp @@ -650,6 +650,9 @@ ICommand *CCommandRegistry::getCommand(const std::string &commandName) NLMISC_CATEGORISED_COMMAND(nel,help,"display help on a specific variable/commands or on all variables and commands", "[|]") { + nlunreferenced(rawCommandString); + nlunreferenced(quiet); + nlunreferenced(human); // nlassert (_Commands != NULL); // make sure we have a valid number of parameters diff --git a/code/nel/src/misc/common.cpp b/code/nel/src/misc/common.cpp index fb9a9c6f5..d89708c4e 100644 --- a/code/nel/src/misc/common.cpp +++ b/code/nel/src/misc/common.cpp @@ -30,6 +30,7 @@ #include "nel/misc/command.h" #include "nel/misc/path.h" +#include "nel/misc/i18n.h" using namespace std; @@ -372,6 +373,10 @@ uint32 humanReadableToBytes (const string &str) NLMISC_CATEGORISED_COMMAND(nel,btohr, "Convert a bytes number into an human readable number", "") { + nlunreferenced(rawCommandString); + nlunreferenced(quiet); + nlunreferenced(human); + if (args.size() != 1) return false; @@ -383,6 +388,10 @@ NLMISC_CATEGORISED_COMMAND(nel,btohr, "Convert a bytes number into an human read NLMISC_CATEGORISED_COMMAND(nel,hrtob, "Convert a human readable number into a bytes number", "
") { + nlunreferenced(rawCommandString); + nlunreferenced(quiet); + nlunreferenced(human); + if (args.size() != 1) return false; @@ -445,6 +454,10 @@ uint32 fromHumanReadable (const std::string &str) NLMISC_CATEGORISED_COMMAND(nel,stohr, "Convert a second number into an human readable time", "") { + nlunreferenced(rawCommandString); + nlunreferenced(quiet); + nlunreferenced(human); + if (args.size() != 1) return false; @@ -526,6 +539,31 @@ void toUpper(char *str) } } +std::string formatThousands(const std::string& s) +{ + sint i, k; + sint remaining = (sint)s.length() - 1; + static std::string separator = NLMISC::CI18N::get("uiThousandsSeparator").toUtf8(); + + // Don't add separator if the number is < 10k + if (remaining < 4) return s; + + std::string ns; + + do + { + for (i = remaining, k = 0; i >= 0 && k < 3; --i, ++k ) + { + ns = s[i] + ns; // New char is added to front of ns + if ( i > 0 && k == 2) ns = separator + ns; // j > 0 means still more digits + } + + remaining -= 3; + } + while (remaining >= 0); + + return ns; +} // // Exceptions @@ -803,6 +841,7 @@ int nlfseek64( FILE *stream, sint64 offset, int origin ) return fsetpos (stream, &pos64); #else // NL_OS_WINDOWS + // TODO: to fix for Linux and Mac OS X // This code doesn't work under windows : fseek() implementation uses a signed 32 bits offset. What ever we do, it can't seek more than 2 Go. // For the moment, i don't know if it works under linux for seek of more than 2 Go. @@ -845,6 +884,9 @@ sint64 nlftell64(FILE *stream) } else return -1; #else + nlunreferenced(stream); + + // TODO: implement for Linux and Mac OS X nlerror("Not implemented"); return -1; #endif @@ -859,9 +901,14 @@ sint64 nlftell64(FILE *stream) NLMISC_CATEGORISED_COMMAND(nel, sleep, "Freeze the service for N seconds (for debug purpose)", "") { + nlunreferenced(rawCommandString); + nlunreferenced(quiet); + nlunreferenced(human); + if(args.size() != 1) return false; - sint32 n = atoi (args[0].c_str()); + sint32 n; + fromString(args[0], n); log.displayNL ("Sleeping during %d seconds", n); @@ -871,6 +918,10 @@ NLMISC_CATEGORISED_COMMAND(nel, sleep, "Freeze the service for N seconds (for de NLMISC_CATEGORISED_COMMAND(nel, system, "Execute the command line using system() function call (wait until the end of the command)", "") { + nlunreferenced(rawCommandString); + nlunreferenced(quiet); + nlunreferenced(human); + if(args.size() != 1) return false; string cmd = args[0]; @@ -889,6 +940,10 @@ NLMISC_CATEGORISED_COMMAND(nel, system, "Execute the command line using system() NLMISC_CATEGORISED_COMMAND(nel, launchProgram, "Execute the command line using launcProgram() function call (launch in background task without waiting the end of the execution)", " ") { + nlunreferenced(rawCommandString); + nlunreferenced(quiet); + nlunreferenced(human); + if(args.size() != 2) return false; string cmd = args[0]; @@ -901,6 +956,10 @@ NLMISC_CATEGORISED_COMMAND(nel, launchProgram, "Execute the command line using l NLMISC_CATEGORISED_COMMAND(nel, killProgram, "kill a program given the pid", "") { + nlunreferenced(rawCommandString); + nlunreferenced(quiet); + nlunreferenced(human); + if(args.size() != 1) return false; uint32 pid; fromString(args[0], pid); @@ -1004,6 +1063,9 @@ bool openDoc (const char *document) } else return true; +#else + // TODO: implement for Linux and Mac OS X + nlunreferenced(document); #endif // NL_OS_WINDOWS return false; } diff --git a/code/nel/src/misc/config_file/Makefile.am b/code/nel/src/misc/config_file/Makefile.am deleted file mode 100644 index ee72fe42c..000000000 --- a/code/nel/src/misc/config_file/Makefile.am +++ /dev/null @@ -1,21 +0,0 @@ -# -# - -MAINTAINERCLEANFILES = Makefile.in - -noinst_LTLIBRARIES = libconfig.la - -AM_YFLAGS = --defines=cf_gramatical.h -p cf - -AM_LFLAGS = -f -8 -Pcf -olex.yy.c - -EXTRA_DIST = cf_gramatical.h cf_bison.simple cf_flex.skl do.bat - -libconfig_la_SOURCES = cf_lexical.lpp \ - cf_gramatical.ypp \ - config_file.cpp - -#libconfig_la_SOURCES = config_file.cpp - -# End of Makefile.am - diff --git a/code/nel/src/misc/eid_translator.cpp b/code/nel/src/misc/eid_translator.cpp index 36ea84247..e254831c4 100644 --- a/code/nel/src/misc/eid_translator.cpp +++ b/code/nel/src/misc/eid_translator.cpp @@ -417,6 +417,17 @@ void CEntityIdTranslator::checkEntity (const CEntityId &eid, const ucstring &ent } } +void CEntityIdTranslator::removeShardFromName(ucstring& name) +{ + // The string must contain a '(' and a ')' + ucstring::size_type p0= name.find('('); + ucstring::size_type p1= name.find(')'); + if (p0 == ucstring::npos || p1 == ucstring::npos || p1 <= p0) + return; + + name = name.substr(0, p0) + name.substr(p1 + 1); +} + // this callback is call when the file is changed void cbInvalidEntityNamesFilename(const std::string &invalidEntityNamesFilename) { diff --git a/code/nel/src/misc/events.cpp b/code/nel/src/misc/events.cpp index 4d3979416..7cef02f44 100644 --- a/code/nel/src/misc/events.cpp +++ b/code/nel/src/misc/events.cpp @@ -178,7 +178,7 @@ static const CStringConversion::CPair stringTable [] = { "KeyZOOM", KeyZOOM }, { "KeyNONAME", KeyNONAME }, { "KeyPA1", KeyPA1 }, - { "KeyOEM_CLEAR", KeyOEM_CLEAR }, + { "KeyOEM_CLEAR", KeyOEM_CLEAR } }; diff --git a/code/nel/src/misc/fast_id_map.cpp b/code/nel/src/misc/fast_id_map.cpp new file mode 100644 index 000000000..f32d6edd8 --- /dev/null +++ b/code/nel/src/misc/fast_id_map.cpp @@ -0,0 +1,44 @@ +/** + * \file fast_id_map.cpp + * \brief CFastIdMap + * \date 2012-04-10 19:28GMT + * \author Jan Boon (Kaetemi) + * CFastIdMap + */ + +/* + * Copyright (C) 2012 by authors + * + * This file is part of RYZOM CORE. + * RYZOM CORE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * RYZOM CORE 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with RYZOM CORE. If not, see + * . + */ + +#include +#include + +// STL includes + +// NeL includes +// #include + +// Project includes + +namespace NLMISC { + +void dummytoavoidthecompilerwarningfastidmap() { } + +} /* namespace NLMISC */ + +/* end of file */ diff --git a/code/nel/src/misc/noise_value.cpp b/code/nel/src/misc/noise_value.cpp index 89b9a8ad4..4b7cade1f 100644 --- a/code/nel/src/misc/noise_value.cpp +++ b/code/nel/src/misc/noise_value.cpp @@ -18,7 +18,7 @@ #include "nel/misc/noise_value.h" #include "nel/misc/fast_floor.h" - +#include "nel/misc/random.h" namespace NLMISC @@ -45,7 +45,8 @@ public: CRandomGrid3D() { //seed - srand(0); + CRandom Random; + Random.srand(0); // init the grid for(uint z=0; z> 5; + uint v= Random.rand() >> 5; _Texture3d[id]= v&255; } } @@ -80,9 +81,9 @@ public: // init LevelPhases. for(i=0; iRunnable->run(); + { + pthread_t thread_self = pthread_self(); + // Make sure the parent still cares + // If this thread was replaced with a new thread (which should not happen), + // and the IThread object has been deleted, this will likely crash. + if (parent->_ThreadHandle == thread_self) + parent->_State = CPThread::ThreadStateFinished; + else + throw EThread("Thread ended after being detached, this should not happen"); + } + // Allow some clean // pthread_exit(0); return NULL; @@ -96,7 +107,7 @@ static void *ProxyFunc( void *arg ) */ CPThread::CPThread(IRunnable *runnable, uint32 stackSize) : Runnable(runnable), - _State(0), + _State(ThreadStateNone), _StackSize(stackSize) {} @@ -106,10 +117,9 @@ CPThread::CPThread(IRunnable *runnable, uint32 stackSize) */ CPThread::~CPThread() { - if(_State == 1) - terminate(); // force the end of the thread if not already ended + terminate(); // force the end of the thread if not already ended - if(_State > 0) + if (_State != ThreadStateNone) pthread_detach(_ThreadHandle); // free allocated resources only if it was created } @@ -119,26 +129,51 @@ CPThread::~CPThread() void CPThread::start() { pthread_attr_t tattr; - pthread_t tid; int ret; - /* initialized with default attributes */ - ret = pthread_attr_init(&tattr); + if (_StackSize != 0) + { + /* initialized with default attributes */ + ret = pthread_attr_init(&tattr); - /* setting the size of the stack also */ - ret = pthread_attr_setstacksize(&tattr, _StackSize); + /* setting the size of the stack also */ + ret = pthread_attr_setstacksize(&tattr, _StackSize); + } + + bool detach_old_thread = false; + pthread_t old_thread_handle; + if (_State != ThreadStateNone) + { + if (_State == ThreadStateRunning) + { + // I don't know if this behaviour is allowed, but neither thread implementations + // check the start function, and both simply let the existing running thread for what it is... + // From now on, this is not allowed. + throw EThread("Starting a thread that is already started, existing thread will continue running, this should not happen"); + } + detach_old_thread = true; + old_thread_handle = _ThreadHandle; + } - if(pthread_create(&_ThreadHandle, _StackSize != 0 ? &tattr : 0, ProxyFunc, this) != 0) + if (pthread_create(&_ThreadHandle, _StackSize != 0 ? &tattr : NULL, ProxyFunc, this) != 0) { throw EThread("Cannot start new thread"); } - _State = 1; + _State = ThreadStateRunning; + + if (detach_old_thread) + { + // Docs don't say anything about what happens when pthread_create is called with existing handle referenced. + if (old_thread_handle == _ThreadHandle) + throw EThread("Thread handle did not change, this should not happen"); + // Don't care about old thread, free resources when it terminates. + pthread_detach(old_thread_handle); + } } bool CPThread::isRunning() { - // TODO : need a real implementation here that check thread status - return _State == 1; + return _State == ThreadStateRunning; } /* @@ -146,11 +181,11 @@ bool CPThread::isRunning() */ void CPThread::terminate() { - if(_State == 1) + if (_State == ThreadStateRunning) { // cancel only if started pthread_cancel(_ThreadHandle); - _State = 2; // set to finished + _State = ThreadStateFinished; // set to finished } } @@ -159,13 +194,24 @@ void CPThread::terminate() */ void CPThread::wait () { - if(_State == 1) + if (_State == ThreadStateRunning) { - if(pthread_join(_ThreadHandle, 0) != 0) + int error = pthread_join(_ThreadHandle, 0); + switch (error) { - throw EThread( "Cannot join with thread" ); + case 0: + break; + case EINVAL: + throw EThread("Thread is not joinable"); + case ESRCH: + throw EThread("No thread found with this id"); + case EDEADLK: + throw EThread("Deadlock detected or calling thread waits for itself"); + default: + throw EThread("Unknown thread join error"); } - _State = 2; // set to finished + if(_State != ThreadStateFinished) + throw EThread("Thread did not finish, this should not happen"); } } @@ -207,6 +253,34 @@ uint64 CPThread::getCPUMask() return cpuMask; } +void CPThread::setPriority(TThreadPriority priority) +{ + // TODO: Test this + sched_param sp; + switch (priority) + { + case ThreadPriorityHigh: + { + int minPrio = sched_get_priority_min(SCHED_FIFO); + int maxPrio = sched_get_priority_max(SCHED_FIFO); + sp.sched_priority = ((maxPrio - minPrio) / 4) + minPrio; + pthread_setschedparam(_ThreadHandle, SCHED_FIFO, &sp); + break; + } + case ThreadPriorityHighest: + { + int minPrio = sched_get_priority_min(SCHED_FIFO); + int maxPrio = sched_get_priority_max(SCHED_FIFO); + sp.sched_priority = ((maxPrio - minPrio) / 2) + minPrio; + pthread_setschedparam(_ThreadHandle, SCHED_FIFO, &sp); + break; + } + default: + sp.sched_priority = 0; + pthread_setschedparam(_ThreadHandle, SCHED_OTHER, &sp); + } +} + /* * getUserName */ diff --git a/code/nel/src/misc/rgba.cpp b/code/nel/src/misc/rgba.cpp index 844a100cf..598d8eb53 100644 --- a/code/nel/src/misc/rgba.cpp +++ b/code/nel/src/misc/rgba.cpp @@ -643,6 +643,8 @@ bool CRGBA::convertToHLS(float &h, float &l, float &s) const { h = 2.f + (b - r) / diff; } +#if defined(GCC_VERSION) && (GCC_VERSION == 40204) + // use the fix only if using the specific GCC version else if (maxV == b) { h = 4.f + (r - g) / diff; @@ -652,6 +654,12 @@ bool CRGBA::convertToHLS(float &h, float &l, float &s) const // this case is to fix a compiler bug h = (g - b) / diff; } +#else + else + { + h = 4.f + (r - g) / diff; + } +#endif h *= 60.f; // scale to [0..360] diff --git a/code/nel/src/misc/sheet_id.cpp b/code/nel/src/misc/sheet_id.cpp index 0eaad3a7a..617c994b7 100644 --- a/code/nel/src/misc/sheet_id.cpp +++ b/code/nel/src/misc/sheet_id.cpp @@ -592,7 +592,7 @@ uint32 CSheetId::typeFromFileExtension(const std::string &fileExtension) { if (!_Initialised) init(false); - unsigned i; + uint i; for (i=0;i<_FileExtensions.size();i++) if (toLower(fileExtension)==_FileExtensions[i]) return i; diff --git a/code/nel/src/misc/sstring.cpp b/code/nel/src/misc/sstring.cpp index 4c37b1f1a..ef1584361 100644 --- a/code/nel/src/misc/sstring.cpp +++ b/code/nel/src/misc/sstring.cpp @@ -37,14 +37,14 @@ namespace NLMISC return token; } - unsigned int i; + uint i; CSString result; // skip leading junk for (i=0;ipostEvent (new CEventKeyDown ((NLMISC::TKey)wParam, getKeyButton(_AltButton, _ShiftButton, _CtrlButton), true, this)); + } + // Post the message if (wParam < KeyCount) server->postEvent (new CEventKeyUp ((NLMISC::TKey)wParam, getKeyButton(_AltButton, _ShiftButton, _CtrlButton), this)); diff --git a/code/nel/src/misc/win_thread.cpp b/code/nel/src/misc/win_thread.cpp index 4192e927b..c9bfc90a1 100644 --- a/code/nel/src/misc/win_thread.cpp +++ b/code/nel/src/misc/win_thread.cpp @@ -73,6 +73,20 @@ CWinThread::CWinThread (IRunnable *runnable, uint32 stackSize) _MainThread = false; } +namespace { +class CWinCriticalSection +{ +private: + CRITICAL_SECTION cs; +public: + CWinCriticalSection() { InitializeCriticalSection(&cs); } + ~CWinCriticalSection() { DeleteCriticalSection(&cs); } + inline void enter() { EnterCriticalSection(&cs); } + inline void leave() { LeaveCriticalSection(&cs); } +}; +CWinCriticalSection s_CS; +}/* anonymous namespace */ + CWinThread::CWinThread (void* threadHandle, uint32 threadId) { // Main thread @@ -99,14 +113,11 @@ CWinThread::CWinThread (void* threadHandle, uint32 threadId) nlassert(0); // WARNING: following code has not tested! don't know if it work fo real ... // This is just a suggestion of a possible solution, should this situation one day occur ... // Ensure that this thread don't get deleted, or we could suspend the main thread - CRITICAL_SECTION cs; - InitializeCriticalSection(&cs); - EnterCriticalSection(&cs); + s_CS.enter(); // the 2 following statement must be executed atomicaly among the threads of the current process ! SuspendThread(threadHandle); _SuspendCount = ResumeThread(threadHandle); - LeaveCriticalSection(&cs); - DeleteCriticalSection(&cs); + s_CS.leave(); } } @@ -148,10 +159,10 @@ void CWinThread::resume() } } -void CWinThread::setPriority(int priority) +void CWinThread::setPriority(TThreadPriority priority) { nlassert(ThreadHandle); // 'start' was not called !! - BOOL result = SetThreadPriority(ThreadHandle, priority); + BOOL result = SetThreadPriority(ThreadHandle, (int)priority); nlassert(result); } @@ -179,6 +190,9 @@ CWinThread::~CWinThread () void CWinThread::start () { + if (isRunning()) + throw EThread("Starting a thread that is already started, existing thread will continue running, this should not happen"); + // ThreadHandle = (void *) ::CreateThread (NULL, _StackSize, ProxyFunc, this, 0, (DWORD *)&ThreadId); ThreadHandle = (void *) ::CreateThread (NULL, 0, ProxyFunc, this, 0, (DWORD *)&ThreadId); // nldebug("NLMISC: thread %x started for runnable '%x'", typeid( Runnable ).name()); diff --git a/code/nel/src/net/CMakeLists.txt b/code/nel/src/net/CMakeLists.txt index ea68efe32..c24a94215 100644 --- a/code/nel/src/net/CMakeLists.txt +++ b/code/nel/src/net/CMakeLists.txt @@ -24,4 +24,7 @@ IF(WITH_PCH) ENDIF(WITH_PCH) NL_GEN_PC(nel-net.pc) -INSTALL(TARGETS nelnet LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries) + +IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) + INSTALL(TARGETS nelnet LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries) +ENDIF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) diff --git a/code/nel/src/net/Makefile.am b/code/nel/src/net/Makefile.am deleted file mode 100644 index ef0d956be..000000000 --- a/code/nel/src/net/Makefile.am +++ /dev/null @@ -1,60 +0,0 @@ -# -# - -MAINTAINERCLEANFILES = Makefile.in - -lib_LTLIBRARIES = libnelnet.la - -libnelnet_la_SOURCES = buf_client.cpp \ - buf_net_base.cpp \ - buf_server.cpp \ - buf_sock.cpp \ - callback_client.cpp \ - callback_net_base.cpp \ - callback_server.cpp \ - dummy_tcp_sock.cpp \ - inet_address.cpp \ - listen_sock.cpp \ - login_client.cpp \ - login_cookie.cpp \ - login_server.cpp \ - message.cpp \ - message_recorder.cpp \ - naming_client.cpp \ - net_displayer.cpp \ - net_log.cpp \ - service.cpp \ - sock.cpp \ - tcp_sock.cpp \ - udp_sock.cpp \ - udp_sim_sock.cpp \ - unitime.cpp \ - unified_network.cpp \ - varpath.cpp \ - transport_class.cpp \ - email.cpp \ - admin.cpp \ - stdin_monitor_thread.cpp \ - stdin_monitor_thread.h \ - module.cpp \ - module_common.cpp \ - module_gateway.cpp \ - module_manager.cpp \ - module_message.cpp \ - module_socket.cpp \ - module_gateway_transport.cpp \ - module_l5_transport.cpp \ - module_local_gateway.cpp \ - stdnet.cpp - -noinst_HEADERS = stdnet.h - -AM_CXXFLAGS = -I$(top_srcdir)/src - -libnelnet_la_LIBADD = -lc -lpthread - -libnelnet_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ - - -# End of Makefile.am - diff --git a/code/nel/src/net/transport_class.cpp b/code/nel/src/net/transport_class.cpp index a5f826728..dca866916 100644 --- a/code/nel/src/net/transport_class.cpp +++ b/code/nel/src/net/transport_class.cpp @@ -77,7 +77,7 @@ string typeToString (CTransportClass::TProp type) string conv[] = { "PropUInt8", "PropUInt16", "PropUInt32", "PropUInt64", "PropSInt8", "PropSInt16", "PropSInt32", "PropSInt64", - "PropBool", "PropFloat", "PropDouble", "PropString", "PropDataSetRow", "PropSheetId", "PropUKN" }; + "PropBool", "PropFloat", "PropDouble", "PropString", "PropDataSetRow", "PropSheetId", "PropUCString", "PropUKN" }; // "PropBool", "PropFloat", "PropDouble", "PropString", "PropDataSetRow", "PropEntityId", "PropSheetId", "PropUKN" }; if (type > CTransportClass::PropUKN) @@ -352,6 +352,7 @@ void CTransportClass::init () // nlassert (PropDataSetRow < PropUKN); DummyProp[PropDataSetRow] = new CTransportClass::CRegisteredProp; // nlassert (PropEntityId < PropUKN); DummyProp[PropEntityId] = new CTransportClass::CRegisteredProp; nlassert (PropSheetId < PropUKN); DummyProp[PropSheetId] = new CTransportClass::CRegisteredProp; + nlassert (PropUCString < PropUKN); DummyProp[PropUCString] = new CTransportClass::CRegisteredProp; // we have to know when a service comes, so add callback (put the callback before all other one because we have to send this message first) CUnifiedNetwork::getInstance()->setServiceUpCallback("*", cbTCUpService, NULL, false); diff --git a/code/nel/src/pacs/CMakeLists.txt b/code/nel/src/pacs/CMakeLists.txt index 0fa059d68..62a809407 100644 --- a/code/nel/src/pacs/CMakeLists.txt +++ b/code/nel/src/pacs/CMakeLists.txt @@ -19,4 +19,7 @@ IF(WITH_PCH) ENDIF(WITH_PCH) NL_GEN_PC(nel-pacs.pc) -INSTALL(TARGETS nelpacs LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries) + +IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) + INSTALL(TARGETS nelpacs LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries) +ENDIF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) diff --git a/code/nel/src/pacs/Makefile.am b/code/nel/src/pacs/Makefile.am deleted file mode 100644 index 0b05a2ed6..000000000 --- a/code/nel/src/pacs/Makefile.am +++ /dev/null @@ -1,69 +0,0 @@ -# -# - -MAINTAINERCLEANFILES = Makefile.in - -lib_LTLIBRARIES = libnelpacs.la - -libnelpacs_la_SOURCES = chain.cpp \ - chain.h \ - chain_quad.cpp \ - chain_quad.h \ - collision_callback.cpp \ - collision_callback.h \ - collision_desc.cpp \ - collision_desc.h \ - collision_mesh_build.h \ - collision_ot.cpp \ - collision_ot.h \ - collision_surface_temp.cpp \ - collision_surface_temp.h \ - edge_collide.cpp \ - edge_collide.h \ - edge_quad.cpp \ - edge_quad.h \ - exterior_mesh.cpp \ - exterior_mesh.h \ - global_retriever.cpp \ - global_retriever.h \ - local_retriever.cpp \ - local_retriever.h \ - move_cell.cpp \ - move_cell.h \ - move_container.cpp \ - move_container.h \ - move_container_inline.h \ - move_element.cpp \ - move_element.h \ - move_element_inline.h \ - move_primitive.cpp \ - move_primitive.h \ - primitive_world_image.cpp \ - primitive_world_image.h \ - primitive_block_pacs.cpp \ - primitive_block.h \ - retrievable_surface.cpp \ - retrievable_surface.h \ - retriever_bank.cpp \ - retriever_bank.h \ - retriever_instance.cpp \ - retriever_instance.h \ - stdpacs.cpp \ - surface_quad.cpp \ - surface_quad.h \ - vector_2s.cpp \ - vector_2s.h \ - build_indoor.cpp \ - build_indoor.h - -AM_CXXFLAGS = -I$(top_srcdir)/src - -noinst_HEADERS = stdpacs.h face_grid.h quad_grid.h - -libnelpacs_la_LIBADD = -lc - -libnelpacs_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ - - -# End of Makefile.am - diff --git a/code/nel/src/sound/CMakeLists.txt b/code/nel/src/sound/CMakeLists.txt index 9497357ee..e73d0828e 100644 --- a/code/nel/src/sound/CMakeLists.txt +++ b/code/nel/src/sound/CMakeLists.txt @@ -1,8 +1,101 @@ + FILE(GLOB SRC *.cpp *.h) FILE(GLOB HEADERS ../../include/nel/sound/*.h) + +FILE(GLOB ANIMATION + sound_anim_manager.cpp ../../include/nel/sound/sound_anim_manager.h + sound_anim_marker.cpp ../../include/nel/sound/sound_anim_marker.h + sound_animation.cpp ../../include/nel/sound/sound_animation.h +) + +FILE(GLOB BACKGROUND_SOUND + background_sound.cpp ../../include/nel/sound/background_sound.h + background_sound_manager.cpp ../../include/nel/sound/background_sound_manager.h + background_source.cpp ../../include/nel/sound/background_source.h + clustered_sound.cpp ../../include/nel/sound/clustered_sound.h + context_sound.cpp ../../include/nel/sound/context_sound.h +) + +FILE(GLOB BANKS + async_file_manager_sound.cpp ../../include/nel/sound/async_file_manager_sound.h + sample_bank.cpp ../../include/nel/sound/sample_bank.h + sample_bank_manager.cpp ../../include/nel/sound/sample_bank_manager.h + sound_bank.cpp ../../include/nel/sound/sound_bank.h +) + +FILE(GLOB MIXER + audio_mixer_user.cpp ../../include/nel/sound/audio_mixer_user.h + ../../include/nel/sound/containers.h + group_controller.cpp ../../include/nel/sound/group_controller.h + group_controller_root.cpp ../../include/nel/sound/group_controller_root.h + listener_user.cpp ../../include/nel/sound/listener_user.h + mixing_track.cpp ../../include/nel/sound/mixing_track.h +) + +FILE(GLOB MUSIC + music_channel_fader.cpp ../../include/nel/sound/music_channel_fader.h + music_sound.cpp ../../include/nel/sound/music_sound.h + music_sound_manager.cpp ../../include/nel/sound/music_sound_manager.h + music_source.cpp ../../include/nel/sound/music_source.h + source_music_channel.cpp ../../include/nel/sound/source_music_channel.h +) + +FILE(GLOB SOUND + complex_sound.cpp ../../include/nel/sound/complex_sound.h + complex_source.cpp ../../include/nel/sound/complex_source.h + simple_sound.cpp ../../include/nel/sound/simple_sound.h + simple_source.cpp ../../include/nel/sound/simple_source.h + sound.cpp ../../include/nel/sound/sound.h + ../../include/nel/sound/sound_pattern.h + source_common.cpp ../../include/nel/sound/source_common.h +) + +FILE(GLOB STREAM + stream_sound.cpp ../../include/nel/sound/stream_sound.h + stream_source.cpp ../../include/nel/sound/stream_source.h +) + +FILE(GLOB STREAM_FILE + audio_decoder.cpp ../../include/nel/sound/audio_decoder.h + audio_decoder_vorbis.cpp ../../include/nel/sound/audio_decoder_vorbis.h + stream_file_sound.cpp ../../include/nel/sound/stream_file_sound.h + stream_file_source.cpp ../../include/nel/sound/stream_file_source.h +) + +FILE(GLOB USER_CLASSES + ../../include/nel/sound/u_audio_mixer.h + ../../include/nel/sound/u_group_controller.h + ../../include/nel/sound/u_listener.h + ../../include/nel/sound/u_source.h + ../../include/nel/sound/u_stream_source.h +) + +SOURCE_GROUP("" FILES ${SRC} ${HEADERS}) +SOURCE_GROUP("animation" FILES ${ANIMATION}) +SOURCE_GROUP("background_sound" FILES ${BACKGROUND_SOUND}) +SOURCE_GROUP("banks" FILES ${BANKS}) +SOURCE_GROUP("mixer" FILES ${MIXER}) +SOURCE_GROUP("music_deprecated" FILES ${MUSIC}) +SOURCE_GROUP("sound" FILES ${SOUND}) +SOURCE_GROUP("stream" FILES ${STREAM}) +SOURCE_GROUP("stream_file" FILES ${STREAM_FILE}) +SOURCE_GROUP("user_classes" FILES ${USER_CLASSES}) + + NL_TARGET_LIB(nelsound ${HEADERS} ${SRC}) + +INCLUDE_DIRECTORIES(${VORBIS_INCLUDE_DIR}) + +TARGET_LINK_LIBRARIES(nelsound ${VORBISFILE_LIBRARY} ${VORBIS_LIBRARY}) + +IF(WITH_STATIC) + # Add libogg dependency only if target is static because to libvorbisfile + TARGET_LINK_LIBRARIES(nelsound ${OGG_LIBRARY}) +ENDIF(WITH_STATIC) + + INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR}) TARGET_LINK_LIBRARIES(nelsound ${LIBXML2_LIBRARIES} nelmisc nelligo nelgeorges nel3d nelsnd_lowlevel) @@ -19,6 +112,9 @@ IF(WITH_PCH) ENDIF(WITH_PCH) NL_GEN_PC(nel-sound.pc) -INSTALL(TARGETS nelsound LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries) + +IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) + INSTALL(TARGETS nelsound LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries) +ENDIF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) ADD_SUBDIRECTORY(driver) diff --git a/code/nel/src/sound/Makefile.am b/code/nel/src/sound/Makefile.am deleted file mode 100644 index b919e10c4..000000000 --- a/code/nel/src/sound/Makefile.am +++ /dev/null @@ -1,75 +0,0 @@ -# -# - -MAINTAINERCLEANFILES = Makefile.in - -SUBDIRS = driver - -lib_LTLIBRARIES = libnelsnd.la - -libnelsnd_la_SOURCES = async_file_manager_sound.cpp \ - async_file_manager_sound.h \ - audio_mixer_user.cpp \ - audio_mixer_user.h \ - background_sound.cpp \ - background_sound.h \ - background_sound_manager.cpp \ - background_sound_manager.h \ - background_source.cpp \ - background_source.h \ - clustered_sound.cpp \ - clustered_sound.h \ - complex_sound.cpp \ - complex_sound.h \ - complex_source.cpp \ - complex_source.h \ - context_sound.cpp \ - context_sound.h \ - listener_user.cpp \ - listener_user.h \ - mixing_track.cpp \ - mixing_track.h \ - music_channel_fader.h \ - music_channel_fader.cpp \ - music_sound.cpp \ - music_sound.h \ - music_sound_manager.cpp \ - music_sound_manager.h \ - music_source.cpp \ - music_source.h \ - sample_bank.cpp \ - sample_bank.h \ - sample_bank_manager.cpp \ - sample_bank_manager.h \ - simple_sound.cpp \ - simple_sound.h \ - simple_source.cpp \ - simple_source.h \ - sound_animation.cpp \ - sound_anim_manager.cpp \ - sound_anim_marker.cpp \ - sound_bank.cpp \ - sound_bank.h \ - sound.cpp \ - sound.h \ - sound_pattern.h \ - source_common.cpp \ - source_common.h \ - stdsound.cpp \ - stdsound.h \ - stream_source.cpp \ - stream_source.h \ - stream_sound.cpp \ - stream_sound.h - -AM_CXXFLAGS = -I$(top_srcdir)/src - -noinst_HEADERS = stdsound.h - -libnelsnd_la_LIBADD = driver/libnelsnd_lowlevel.la - -libnelsnd_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ - - -# End of Makefile.am - diff --git a/code/nel/src/sound/audio_decoder.cpp b/code/nel/src/sound/audio_decoder.cpp new file mode 100644 index 000000000..eef031417 --- /dev/null +++ b/code/nel/src/sound/audio_decoder.cpp @@ -0,0 +1,139 @@ +/** + * \file audio_decoder.cpp + * \brief IAudioDecoder + * \date 2012-04-11 09:34GMT + * \author Jan Boon (Kaetemi) + * IAudioDecoder + */ + +/* + * Copyright (C) 2008-2012 by authors + * + * This file is part of RYZOM CORE. + * RYZOM CORE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * RYZOM CORE 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with RYZOM CORE. If not, see + * . + */ + +#include "stdsound.h" +#include + +// STL includes + +// NeL includes +#include +#include + +// Project includes +#include + +using namespace std; +using namespace NLMISC; + +namespace NLSOUND { + +IAudioDecoder::IAudioDecoder() : _InternalStream(NULL) +{ + +} + +IAudioDecoder::~IAudioDecoder() +{ + if (_InternalStream) { delete _InternalStream; _InternalStream = NULL; } +} + +IAudioDecoder *IAudioDecoder::createAudioDecoder(const std::string &filepath, bool async, bool loop) +{ + std::string lookup = CPath::lookup(filepath, false); + if (lookup.empty()) + { + nlwarning("Music file %s does not exist!", filepath.c_str()); + return NULL; + } + std::string type = CFile::getExtension(filepath); + + CIFile *ifile = new CIFile(); + ifile->setCacheFileOnOpen(!async); + ifile->allowBNPCacheFileOnOpen(!async); + ifile->open(lookup); + + IAudioDecoder *mb = createAudioDecoder(type, ifile, loop); + + if (mb) mb->_InternalStream = ifile; + else delete ifile; + + return mb; +} + +IAudioDecoder *IAudioDecoder::createAudioDecoder(const std::string &type, NLMISC::IStream *stream, bool loop) +{ + if (!stream) + { + nlwarning("Stream is NULL"); + return NULL; + } + std::string type_lower = toLower(type); + if (type_lower == "ogg") + { + return new CAudioDecoderVorbis(stream, loop); + } + else + { + nlwarning("Music file type unknown: '%s'", type_lower.c_str()); + return NULL; + } +} + +bool IAudioDecoder::getInfo(const std::string &filepath, std::string &artist, std::string &title) +{ + std::string lookup = CPath::lookup(filepath, false); + if (lookup.empty()) + { + nlwarning("Music file %s does not exist!", filepath.c_str()); + return false; + } + std::string type = CFile::getExtension(filepath); + std::string type_lower = NLMISC::toLower(type); + + if (type_lower == "ogg") + { + CIFile ifile; + ifile.setCacheFileOnOpen(false); + ifile.allowBNPCacheFileOnOpen(false); + ifile.open(lookup); + return CAudioDecoderVorbis::getInfo(&ifile, artist, title); + } + else + { + nlwarning("Music file type unknown: '%s'", type_lower.c_str()); + artist.clear(); title.clear(); + return false; + } +} + +/// Get audio/container extensions that are currently supported by the nel sound library. +void IAudioDecoder::getMusicExtensions(std::vector &extensions) +{ + extensions.push_back("ogg"); + // extensions.push_back("wav"); // TODO: Easy. +} + +/// Return if a music extension is supported by the nel sound library. +bool IAudioDecoder::isMusicExtensionSupported(const std::string &extension) +{ + return (extension == "ogg"); +} + +} /* namespace NLSOUND */ + +/* end of file */ diff --git a/code/nel/src/sound/driver/music_buffer_vorbis.cpp b/code/nel/src/sound/audio_decoder_vorbis.cpp similarity index 53% rename from code/nel/src/sound/driver/music_buffer_vorbis.cpp rename to code/nel/src/sound/audio_decoder_vorbis.cpp index 9d5543c62..e0b950fc4 100644 --- a/code/nel/src/sound/driver/music_buffer_vorbis.cpp +++ b/code/nel/src/sound/audio_decoder_vorbis.cpp @@ -1,38 +1,53 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero 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 Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . +/** + * \file audio_decoder_vorbis.cpp + * \brief CAudioDecoderVorbis + * \date 2012-04-11 09:35GMT + * \author Jan Boon (Kaetemi) + * CAudioDecoderVorbis + */ -#include "stdsound_lowlevel.h" +/* + * Copyright (C) 2008-2012 by authors + * + * This file is part of RYZOM CORE. + * RYZOM CORE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * RYZOM CORE 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with RYZOM CORE. If not, see + * . + */ + +#include "stdsound.h" +#include + +// STL includes + +// NeL includes +#include // Project includes -#include "nel/sound/driver/music_buffer_vorbis.h" using namespace std; using namespace NLMISC; -namespace NLSOUND -{ +namespace NLSOUND { size_t vorbisReadFunc(void *ptr, size_t size, size_t nmemb, void *datasource) { - CMusicBufferVorbis *music_buffer_vorbis = (CMusicBufferVorbis *)datasource; - NLMISC::IStream *stream = music_buffer_vorbis->getStream(); + CAudioDecoderVorbis *audio_decoder_vorbis = (CAudioDecoderVorbis *)datasource; + NLMISC::IStream *stream = audio_decoder_vorbis->getStream(); nlassert(stream->isReading()); sint32 length = (sint32)(size * nmemb); - if (length > music_buffer_vorbis->getStreamSize() - stream->getPos()) - length = music_buffer_vorbis->getStreamSize() - stream->getPos(); + if (length > audio_decoder_vorbis->getStreamSize() - stream->getPos()) + length = audio_decoder_vorbis->getStreamSize() - stream->getPos(); stream->serialBuffer((uint8 *)ptr, length); return length; } @@ -45,7 +60,7 @@ int vorbisSeekFunc(void *datasource, ogg_int64_t offset, int whence) return 0; // ooookkaaaaaayyy } - CMusicBufferVorbis *music_buffer_vorbis = (CMusicBufferVorbis *)datasource; + CAudioDecoderVorbis *audio_decoder_vorbis = (CAudioDecoderVorbis *)datasource; NLMISC::IStream::TSeekOrigin origin; switch (whence) @@ -64,19 +79,19 @@ int vorbisSeekFunc(void *datasource, ogg_int64_t offset, int whence) return -1; } - if (music_buffer_vorbis->getStream()->seek(SEEK_SET ? music_buffer_vorbis->getStreamOffset() + (sint32)offset : (sint32)offset, origin)) return 0; + if (audio_decoder_vorbis->getStream()->seek(SEEK_SET ? audio_decoder_vorbis->getStreamOffset() + (sint32)offset : (sint32)offset, origin)) return 0; else return -1; } //int vorbisCloseFunc(void *datasource) //{ -// //CMusicBufferVorbis *music_buffer_vorbis = (CMusicBufferVorbis *)datasource; +// //CAudioDecoderVorbis *audio_decoder_vorbis = (CAudioDecoderVorbis *)datasource; //} long vorbisTellFunc(void *datasource) { - CMusicBufferVorbis *music_buffer_vorbis = (CMusicBufferVorbis *)datasource; - return (long)(music_buffer_vorbis->getStream()->getPos() - music_buffer_vorbis->getStreamOffset()); + CAudioDecoderVorbis *audio_decoder_vorbis = (CAudioDecoderVorbis *)datasource; + return (long)(audio_decoder_vorbis->getStream()->getPos() - audio_decoder_vorbis->getStreamOffset()); } static ov_callbacks OV_CALLBACKS_NLMISC_STREAM = { @@ -86,8 +101,8 @@ static ov_callbacks OV_CALLBACKS_NLMISC_STREAM = { (long (*)(void *)) vorbisTellFunc }; -CMusicBufferVorbis::CMusicBufferVorbis(NLMISC::IStream *stream, bool loop) -: _Stream(stream), _Loop(loop), _IsMusicEnded(false) +CAudioDecoderVorbis::CAudioDecoderVorbis(NLMISC::IStream *stream, bool loop) +: _Stream(stream), _Loop(loop), _IsMusicEnded(false), _StreamSize(0) { _StreamOffset = stream->getPos(); stream->seek(0, NLMISC::IStream::end); @@ -96,15 +111,15 @@ CMusicBufferVorbis::CMusicBufferVorbis(NLMISC::IStream *stream, bool loop) ov_open_callbacks(this, &_OggVorbisFile, NULL, 0, OV_CALLBACKS_NLMISC_STREAM); } -CMusicBufferVorbis::~CMusicBufferVorbis() +CAudioDecoderVorbis::~CAudioDecoderVorbis() { ov_clear(&_OggVorbisFile); } /// Get information on a music file (only artist and title at the moment). -bool CMusicBufferVorbis::getInfo(NLMISC::IStream *stream, std::string &artist, std::string &title) +bool CAudioDecoderVorbis::getInfo(NLMISC::IStream *stream, std::string &artist, std::string &title) { - CMusicBufferVorbis mbv(stream, false); // just opens and closes the oggvorbisfile thing :) + CAudioDecoderVorbis mbv(stream, false); // just opens and closes the oggvorbisfile thing :) vorbis_comment *vc = ov_comment(&mbv._OggVorbisFile, -1); char *title_c = vorbis_comment_query(vc, "title", 0); if (title_c) title = title_c; else title.clear(); @@ -113,29 +128,27 @@ bool CMusicBufferVorbis::getInfo(NLMISC::IStream *stream, std::string &artist, s return true; } -uint32 CMusicBufferVorbis::getRequiredBytes() +uint32 CAudioDecoderVorbis::getRequiredBytes() { return 0; // no minimum requirement of bytes to buffer out } -uint32 CMusicBufferVorbis::getNextBytes(uint8 *buffer, uint32 minimum, uint32 maximum) +uint32 CAudioDecoderVorbis::getNextBytes(uint8 *buffer, uint32 minimum, uint32 maximum) { sint current_section = 0; // ??? if (_IsMusicEnded) return 0; nlassert(minimum <= maximum); // can't have this.. uint32 bytes_read = 0; - #ifdef NL_BIG_ENDIAN sint endianness = 1; #else sint endianness = 0; #endif - do { // signed 16-bit or unsigned 8-bit little-endian samples sint br = ov_read(&_OggVorbisFile, (char *)&buffer[bytes_read], maximum - bytes_read, - endianness, // Specifies big or little endian byte packing. 0 for little endian, 1 for big endian. Typical value is 0. + endianness, // Specifies big or little endian byte packing. 0 for little endian, 1 for b ig endian. Typical value is 0. getBitsPerSample() == 8 ? 1 : 2, getBitsPerSample() == 8 ? 0 : 1, // Signed or unsigned data. 0 for unsigned, 1 for signed. Typically 1. ¤t_section); @@ -162,58 +175,53 @@ uint32 CMusicBufferVorbis::getNextBytes(uint8 *buffer, uint32 minimum, uint32 ma // error switch(br) { - case OV_HOLE: + case OV_HOLE: nlwarning("ov_read returned OV_HOLE"); break; - - case OV_EINVAL: + case OV_EINVAL: nlwarning("ov_read returned OV_EINVAL"); break; - - case OV_EBADLINK: + case OV_EBADLINK: nlwarning("ov_read returned OV_EBADLINK"); break; - - default: + default: nlwarning("ov_read returned %d", br); } - - return 0; } } while (bytes_read < minimum); return bytes_read; } -uint8 CMusicBufferVorbis::getChannels() +uint8 CAudioDecoderVorbis::getChannels() { vorbis_info *vi = ov_info(&_OggVorbisFile, -1); return (uint8)vi->channels; } -uint32 CMusicBufferVorbis::getSamplesPerSec() +uint CAudioDecoderVorbis::getSamplesPerSec() { vorbis_info *vi = ov_info(&_OggVorbisFile, -1); - return vi->rate; + return (uint)vi->rate; } -uint8 CMusicBufferVorbis::getBitsPerSample() +uint8 CAudioDecoderVorbis::getBitsPerSample() { return 16; } -bool CMusicBufferVorbis::isMusicEnded() +bool CAudioDecoderVorbis::isMusicEnded() { return _IsMusicEnded; } -float CMusicBufferVorbis::getLength() +float CAudioDecoderVorbis::getLength() { return (float)ov_time_total(&_OggVorbisFile, -1); } -uint CMusicBufferVorbis::getUncompressedSize() +void CAudioDecoderVorbis::setLooping(bool loop) { - return (uint)ov_pcm_total(&_OggVorbisFile, -1) * (getBitsPerSample() / 2) * getChannels(); + _Loop = loop; } } /* namespace NLSOUND */ diff --git a/code/nel/src/sound/audio_mixer_user.cpp b/code/nel/src/sound/audio_mixer_user.cpp index 367abd0e1..1a6c2d322 100644 --- a/code/nel/src/sound/audio_mixer_user.cpp +++ b/code/nel/src/sound/audio_mixer_user.cpp @@ -45,12 +45,15 @@ #include "nel/sound/context_sound.h" #include "nel/sound/music_source.h" #include "nel/sound/stream_source.h" +#include "nel/sound/stream_file_source.h" #include "nel/sound/simple_sound.h" #include "nel/sound/music_sound.h" #include "nel/sound/stream_sound.h" #include "nel/sound/sample_bank_manager.h" #include "nel/sound/sample_bank.h" #include "nel/sound/sound_bank.h" +#include "nel/sound/group_controller.h" +#include "nel/sound/containers.h" using namespace std; using namespace NLMISC; @@ -218,6 +221,7 @@ void CAudioMixerUser::writeProfile(std::string& out) */ out += "Sound mixer: \n"; out += "\tPlaying sources: " + toString (getPlayingSourcesCount()) + " \n"; + out += "\tPlaying simple sources: " + toString(countPlayingSimpleSources()) + " / " + toString(countSimpleSources()) + " \n"; out += "\tAvailable tracks: " + toString (getAvailableTracksCount()) + " \n"; out += "\tUsed tracks: " + toString (getUsedTracksCount()) + " \n"; // out << "\tMuted sources: " << nb << " \n"; @@ -248,6 +252,16 @@ void CAudioMixerUser::addSourceWaitingForPlay(CSourceCommon *source) _SourceWaitingForPlay.push_back(source); } +// ****************************************************************** + +void CAudioMixerUser::removeSourceWaitingForPlay(CSourceCommon *source) +{ + std::list::iterator it = find(_SourceWaitingForPlay.begin(), _SourceWaitingForPlay.end(), source); + if (it != _SourceWaitingForPlay.end()) + { + _SourceWaitingForPlay.erase(it); + } +} // ****************************************************************** @@ -256,8 +270,9 @@ void CAudioMixerUser::reset() _Leaving = true; _SourceWaitingForPlay.clear(); - - /* TODO: Stop music channels */ + + for (uint i = 0; i < _NbMusicChannelFaders; ++i) + _MusicChannelFaders[i].reset(); // Stop tracks uint i; @@ -1638,6 +1653,7 @@ void CAudioMixerUser::update() _MusicChannelFaders[i].update(); // Check all playing track and stop any terminated buffer. + std::list::size_type nbWaitingSources = _Sources.size(); for (i=0; i<_Tracks.size(); ++i) { if (!_Tracks[i]->isPlaying()) @@ -1649,13 +1665,14 @@ void CAudioMixerUser::update() } // try to play any waiting source. - if (!_SourceWaitingForPlay.empty()) + if (!_SourceWaitingForPlay.empty() && nbWaitingSources) { // check if the source still exist before trying to play it if (_Sources.find(_SourceWaitingForPlay.front()) != _Sources.end()) _SourceWaitingForPlay.front()->play(); // nldebug("Before POP Sources waiting : %u", _SourceWaitingForPlay.size()); _SourceWaitingForPlay.pop_front(); + --nbWaitingSources; // nldebug("After POP Sources waiting : %u", _SourceWaitingForPlay.size()); } } @@ -1689,7 +1706,7 @@ void CAudioMixerUser::update() // _Tracks[i]->DrvSource->setPos(source->getPos() * (1-css->PosAlpha) + css->Position*(css->PosAlpha)); _Tracks[i]->getPhysicalSource()->setPos(source->getPos() * (1-css->PosAlpha) + vpos*(css->PosAlpha)); // update the relative gain - _Tracks[i]->getPhysicalSource()->setGain(source->getRelativeGain()*source->getGain()*css->Gain); + _Tracks[i]->getPhysicalSource()->setGain(source->getFinalGain() * css->Gain); #if EAX_AVAILABLE == 1 if (_UseEax) { @@ -1826,10 +1843,14 @@ bool CAudioMixerUser::tryToLoadSampleBank(const std::string &sampleName) } } +UGroupController *CAudioMixerUser::getGroupController(const std::string &path) +{ + return static_cast(_GroupController.getGroupController(path)); +} // ****************************************************************** -USource *CAudioMixerUser::createSource( TSoundId id, bool spawn, TSpawnEndCallback cb, void *userParam, NL3D::CCluster *cluster, CSoundContext *context ) +USource *CAudioMixerUser::createSource( TSoundId id, bool spawn, TSpawnEndCallback cb, void *userParam, NL3D::CCluster *cluster, CSoundContext *context, UGroupController *groupController ) { #if NL_PROFILE_MIXER TTicks start = CTime::getPerformanceTime(); @@ -1915,7 +1936,7 @@ retrySound: } // Create source - CSimpleSource *source = new CSimpleSource( simpleSound, spawn, cb, userParam, cluster); + CSimpleSource *source = new CSimpleSource( simpleSound, spawn, cb, userParam, cluster, static_cast(groupController)); // nldebug("Mixer : source %p created", source); @@ -1939,28 +1960,35 @@ retrySound: { CStreamSound *streamSound = static_cast(id); // This is a stream thingy. - ret = new CStreamSource(streamSound, spawn, cb, userParam, cluster); + ret = new CStreamSource(streamSound, spawn, cb, userParam, cluster, static_cast(groupController)); + } + break; + case CSound::SOUND_STREAM_FILE: + { + CStreamFileSound *streamFileSound = static_cast(id); + // This is a stream file thingy. + ret = new CStreamFileSource(streamFileSound, spawn, cb, userParam, cluster, static_cast(groupController)); } break; case CSound::SOUND_COMPLEX: { CComplexSound *complexSound = static_cast(id); // This is a pattern sound. - ret = new CComplexSource(complexSound, spawn, cb, userParam, cluster); + ret = new CComplexSource(complexSound, spawn, cb, userParam, cluster, static_cast(groupController)); } break; case CSound::SOUND_BACKGROUND: { // This is a background sound. CBackgroundSound *bgSound = static_cast(id); - ret = new CBackgroundSource(bgSound, spawn, cb, userParam, cluster); + ret = new CBackgroundSource(bgSound, spawn, cb, userParam, cluster, static_cast(groupController)); } break; case CSound::SOUND_MUSIC: { // This is a background music sound CMusicSound *music_sound= static_cast(id); - ret = new CMusicSource(music_sound, spawn, cb, userParam, cluster); + ret = new CMusicSource(music_sound, spawn, cb, userParam, cluster, static_cast(groupController)); } break; case CSound::SOUND_CONTEXT: @@ -1974,7 +2002,7 @@ retrySound: CSound *sound = ctxSound->getContextSound(*context); if (sound != 0) { - ret = createSource(sound, spawn, cb, userParam, cluster); + ret = createSource(sound, spawn, cb, userParam, cluster, NULL, static_cast(groupController)); // Set the volume of the source according to the context volume if (ret != 0) { @@ -2007,9 +2035,9 @@ retrySound: // ****************************************************************** -USource *CAudioMixerUser::createSource( const NLMISC::TStringId &name, bool spawn, TSpawnEndCallback cb, void *userParam, NL3D::CCluster *cluster, CSoundContext *context) +USource *CAudioMixerUser::createSource( const NLMISC::TStringId &name, bool spawn, TSpawnEndCallback cb, void *userParam, NL3D::CCluster *cluster, CSoundContext *context, UGroupController *groupController) { - return createSource( getSoundId( name ), spawn, cb, userParam, cluster, context); + return createSource( getSoundId( name ), spawn, cb, userParam, cluster, context, groupController); } @@ -2147,6 +2175,32 @@ uint CAudioMixerUser::getPlayingSourcesCount() const return _PlayingSources; } + +// ****************************************************************** + +uint CAudioMixerUser::countPlayingSimpleSources() const +{ + uint count = 0; + for (TSourceContainer::const_iterator it(_Sources.begin()), end(_Sources.end()); it != end; ++it) + { + if ((*it)->getType() == CSourceCommon::SOURCE_SIMPLE && (*it)->isPlaying()) + ++count; + } + return count; +} + +uint CAudioMixerUser::countSimpleSources() const +{ + uint count = 0; + for (TSourceContainer::const_iterator it(_Sources.begin()), end(_Sources.end()); it != end; ++it) + { + if ((*it)->getType() == CSourceCommon::SOURCE_SIMPLE) + ++count; + } + return count; +} + + // ****************************************************************** uint CAudioMixerUser::getAvailableTracksCount() const diff --git a/code/nel/src/sound/background_source.cpp b/code/nel/src/sound/background_source.cpp index c2cb5206a..dbb14242a 100644 --- a/code/nel/src/sound/background_source.cpp +++ b/code/nel/src/sound/background_source.cpp @@ -26,8 +26,8 @@ namespace NLSOUND { -CBackgroundSource::CBackgroundSource(CBackgroundSound *backgroundSound, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster) -: CSourceCommon(backgroundSound, spawn, cb, cbUserParam, cluster) +CBackgroundSource::CBackgroundSource(CBackgroundSound *backgroundSound, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster, CGroupController *groupController) +: CSourceCommon(backgroundSound, spawn, cb, cbUserParam, cluster, groupController) { _BackgroundSound = backgroundSound; } @@ -119,7 +119,7 @@ void CBackgroundSource::play() for (; first != last; ++first) { TSubSource subSource; - subSource.Source = mixer->createSource(first->SoundName, false, 0, 0, _Cluster, 0); + subSource.Source = mixer->createSource(first->SoundName, false, 0, 0, _Cluster, NULL, _GroupController); if (subSource.Source != NULL) subSource.Source->setPriority(_Priority); subSource.Filter = first->Filter; diff --git a/code/nel/src/sound/complex_source.cpp b/code/nel/src/sound/complex_source.cpp index cd3d2925d..8fad61a53 100644 --- a/code/nel/src/sound/complex_source.cpp +++ b/code/nel/src/sound/complex_source.cpp @@ -25,8 +25,8 @@ using namespace NLMISC; namespace NLSOUND { -CComplexSource::CComplexSource (CComplexSound *soundPattern, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster) -: CSourceCommon(soundPattern, spawn, cb, cbUserParam, cluster), +CComplexSource::CComplexSource (CComplexSound *soundPattern, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster, CGroupController *groupController) +: CSourceCommon(soundPattern, spawn, cb, cbUserParam, cluster, groupController), _Source1(NULL), _Source2(NULL) { @@ -117,7 +117,7 @@ void CComplexSource::playStuf() else _FadeLength = 0; - _Source2 = mixer->createSource(sound, false, 0, 0, _Cluster); + _Source2 = mixer->createSource(sound, false, 0, 0, _Cluster, NULL, _GroupController); if (_Source2 == NULL) return; _Source2->setPriority(_Priority); @@ -155,7 +155,7 @@ void CComplexSource::playStuf() { CSound *sound = mixer->getSoundId(_PatternSound->getSound(soundSeq[_SoundSeqIndex++])); - _Source1 = mixer->createSource(sound, false, 0, 0, _Cluster); + _Source1 = mixer->createSource(sound, false, 0, 0, _Cluster, NULL, _GroupController); if (_Source1 == NULL) return; _Source1->setPriority(_Priority); @@ -202,7 +202,7 @@ void CComplexSource::playStuf() CSound *sound = mixer->getSoundId(*first); if (sound != NULL) { - USource *source = mixer->createSource(sound, false, 0, 0, _Cluster); + USource *source = mixer->createSource(sound, false, 0, 0, _Cluster, NULL, _GroupController); if (source != NULL) { source->setPriority(_Priority); @@ -512,7 +512,7 @@ void CComplexSource::onUpdate() // determine the XFade length (if next sound is too short. _FadeLength = minof(uint32(_PatternSound->getFadeLength()/_TickPerSecond), (sound2->getDuration()) / 2, (_Source1->getSound()->getDuration())/2); - _Source2 = mixer->createSource(sound2, false, 0, 0, _Cluster); + _Source2 = mixer->createSource(sound2, false, 0, 0, _Cluster, NULL, _GroupController); if (_Source2) { _Source2->setPriority(_Priority); @@ -641,7 +641,7 @@ void CComplexSource::onEvent() CSound *sound = mixer->getSoundId(_PatternSound->getSound(soundSeq[_SoundSeqIndex++])); - _Source1 = mixer->createSource(sound, false, 0, 0, _Cluster); + _Source1 = mixer->createSource(sound, false, 0, 0, _Cluster, NULL, _GroupController); if (_Source1 == NULL) { stop(); diff --git a/code/nel/src/sound/driver/CMakeLists.txt b/code/nel/src/sound/driver/CMakeLists.txt index c2ae80606..90fbbb562 100644 --- a/code/nel/src/sound/driver/CMakeLists.txt +++ b/code/nel/src/sound/driver/CMakeLists.txt @@ -3,14 +3,7 @@ FILE(GLOB HEADERS ../../../include/nel/sound/driver/*.h) NL_TARGET_LIB(nelsnd_lowlevel ${HEADERS} ${SRC}) -INCLUDE_DIRECTORIES(${VORBIS_INCLUDE_DIR}) - -TARGET_LINK_LIBRARIES(nelsnd_lowlevel nelmisc ${VORBISFILE_LIBRARY} ${VORBIS_LIBRARY}) - -IF(WITH_STATIC) - # Add libogg dependency only if target is static because to libvorbisfile - TARGET_LINK_LIBRARIES(nelsnd_lowlevel ${OGG_LIBRARY}) -ENDIF(WITH_STATIC) +TARGET_LINK_LIBRARIES(nelsnd_lowlevel nelmisc) SET_TARGET_PROPERTIES(nelsnd_lowlevel PROPERTIES LINK_INTERFACE_LIBRARIES "") NL_DEFAULT_PROPS(nelsnd_lowlevel "NeL, Library: Sound Lowlevel") @@ -23,7 +16,9 @@ IF(WITH_PCH) ADD_NATIVE_PRECOMPILED_HEADER(nelsnd_lowlevel ${CMAKE_CURRENT_SOURCE_DIR}/stdsound_lowlevel.h ${CMAKE_CURRENT_SOURCE_DIR}/stdsound_lowlevel.cpp) ENDIF(WITH_PCH) -INSTALL(TARGETS nelsnd_lowlevel LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries) +IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) + INSTALL(TARGETS nelsnd_lowlevel LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries) +ENDIF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) IF(WITH_DRIVER_OPENAL) ADD_SUBDIRECTORY(openal) diff --git a/code/nel/src/sound/driver/Makefile.am b/code/nel/src/sound/driver/Makefile.am deleted file mode 100644 index 0e7325b29..000000000 --- a/code/nel/src/sound/driver/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -# -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = fmod openal dsound - -SUBDIRS = @SOUND_SUBDIRS@ - -noinst_LTLIBRARIES = libnelsnd_lowlevel.la - -libnelsnd_lowlevel_la_SOURCES = buffer.cpp \ - buffer.h \ - effect.h \ - effect.cpp \ - listener.cpp \ - listener.h \ - sound_driver.cpp \ - sound_driver.h \ - source.cpp \ - source.h - -AM_CXXFLAGS = -I$(top_srcdir)/src - -# End of Makefile.am - diff --git a/code/nel/src/sound/driver/dsound/CMakeLists.txt b/code/nel/src/sound/driver/dsound/CMakeLists.txt index f2d13d785..c2fc934dc 100644 --- a/code/nel/src/sound/driver/dsound/CMakeLists.txt +++ b/code/nel/src/sound/driver/dsound/CMakeLists.txt @@ -13,7 +13,9 @@ IF(WITH_PCH) ADD_NATIVE_PRECOMPILED_HEADER(nel_drv_dsound_win ${CMAKE_CURRENT_SOURCE_DIR}/stddsound.h ${CMAKE_CURRENT_SOURCE_DIR}/stddsound.cpp) ENDIF(WITH_PCH) -INSTALL(TARGETS nel_drv_dsound_win RUNTIME DESTINATION bin LIBRARY DESTINATION ${NL_DRIVER_PREFIX} ARCHIVE DESTINATION lib COMPONENT driverssound) -IF(WITH_MAXPLUGIN) - INSTALL(TARGETS nel_drv_dsound_win RUNTIME DESTINATION maxplugin COMPONENT driverssound) -ENDIF(WITH_MAXPLUGIN) +IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC_DRIVERS) OR NOT WITH_STATIC_DRIVERS) + INSTALL(TARGETS nel_drv_dsound_win RUNTIME DESTINATION bin LIBRARY DESTINATION ${NL_DRIVER_PREFIX} ARCHIVE DESTINATION lib COMPONENT driverssound) + IF(WITH_MAXPLUGIN) + INSTALL(TARGETS nel_drv_dsound_win RUNTIME DESTINATION maxplugin COMPONENT driverssound) + ENDIF(WITH_MAXPLUGIN) +ENDIF((WITH_INSTALL_LIBRARIES AND WITH_STATIC_DRIVERS) OR NOT WITH_STATIC_DRIVERS) diff --git a/code/nel/src/sound/driver/fmod/CMakeLists.txt b/code/nel/src/sound/driver/fmod/CMakeLists.txt index 049d8b627..e641a9277 100644 --- a/code/nel/src/sound/driver/fmod/CMakeLists.txt +++ b/code/nel/src/sound/driver/fmod/CMakeLists.txt @@ -13,7 +13,9 @@ IF(WITH_PCH) ADD_NATIVE_PRECOMPILED_HEADER(nel_drv_fmod_win ${CMAKE_CURRENT_SOURCE_DIR}/stdfmod.h ${CMAKE_CURRENT_SOURCE_DIR}/stdfmod.cpp) ENDIF(WITH_PCH) -INSTALL(TARGETS nel_drv_fmod_win RUNTIME DESTINATION bin LIBRARY DESTINATION ${NL_DRIVER_PREFIX} ARCHIVE DESTINATION lib COMPONENT driverssound) -IF(WITH_MAXPLUGIN) - INSTALL(TARGETS nel_drv_fmod_win RUNTIME DESTINATION maxplugin COMPONENT driverssound) -ENDIF(WITH_MAXPLUGIN) +IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC_DRIVERS) OR NOT WITH_STATIC_DRIVERS) + INSTALL(TARGETS nel_drv_fmod_win RUNTIME DESTINATION bin LIBRARY DESTINATION ${NL_DRIVER_PREFIX} ARCHIVE DESTINATION lib COMPONENT driverssound) + IF(WITH_MAXPLUGIN) + INSTALL(TARGETS nel_drv_fmod_win RUNTIME DESTINATION maxplugin COMPONENT driverssound) + ENDIF(WITH_MAXPLUGIN) +ENDIF((WITH_INSTALL_LIBRARIES AND WITH_STATIC_DRIVERS) OR NOT WITH_STATIC_DRIVERS) diff --git a/code/nel/src/sound/driver/fmod/Makefile.am b/code/nel/src/sound/driver/fmod/Makefile.am deleted file mode 100644 index 505c77173..000000000 --- a/code/nel/src/sound/driver/fmod/Makefile.am +++ /dev/null @@ -1,32 +0,0 @@ -# -# - -MAINTAINERCLEANFILES = Makefile.in - -lib_LTLIBRARIES = libnel_drv_fmod.la - -libnel_drv_fmod_la_SOURCES = buffer_fmod.cpp \ - buffer_fmod.h \ - listener_fmod.cpp \ - listener_fmod.h \ - music_channel_fmod.cpp \ - music_channel_fmod.h \ - sound_driver_fmod.cpp \ - sound_driver_fmod.h \ - source_fmod.cpp \ - source_fmod.h \ - stdfmod.cpp \ - stdfmod.h - - -AM_CXXFLAGS = -I$(top_srcdir)/src @FMOD_CFLAGS@ - -noinst_HEADERS = stdfmod.h - -libnel_drv_fmod_la_LIBADD = @FMOD_LIBS@ - -libnel_drv_fmod_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ - - -# End of Makefile.am - diff --git a/code/nel/src/sound/driver/fmod/music_channel_fmod.cpp b/code/nel/src/sound/driver/fmod/music_channel_fmod.cpp index 9c502ea1a..a64dddcfe 100644 --- a/code/nel/src/sound/driver/fmod/music_channel_fmod.cpp +++ b/code/nel/src/sound/driver/fmod/music_channel_fmod.cpp @@ -249,6 +249,12 @@ void CMusicChannelFMod::stop() _CallBackEnded = false; } +void CMusicChannelFMod::reset() +{ + // don't care + stop(); +} + /** Pause the music previously loaded and played (the Memory is not freed) */ void CMusicChannelFMod::pause() diff --git a/code/nel/src/sound/driver/fmod/music_channel_fmod.h b/code/nel/src/sound/driver/fmod/music_channel_fmod.h index d9a17fd99..e91e38a8b 100644 --- a/code/nel/src/sound/driver/fmod/music_channel_fmod.h +++ b/code/nel/src/sound/driver/fmod/music_channel_fmod.h @@ -87,6 +87,9 @@ public: /// Stop the music previously loaded and played (the Memory is also freed) virtual void stop(); + /// Makes sure any resources are freed, but keeps available for next play call + virtual void reset(); + /// Pause the music previously loaded and played (the Memory is not freed) virtual void pause(); diff --git a/code/nel/src/sound/driver/fmod/source_fmod.cpp b/code/nel/src/sound/driver/fmod/source_fmod.cpp index 2ae9a0ea1..4ef2f89d5 100644 --- a/code/nel/src/sound/driver/fmod/source_fmod.cpp +++ b/code/nel/src/sound/driver/fmod/source_fmod.cpp @@ -413,6 +413,13 @@ bool CSourceFMod::getSourceRelativeMode() const // ****************************************************************** void CSourceFMod::setMinMaxDistances( float mindist, float maxdist, bool /* deferred */ ) { + static float maxSqrt = sqrt(std::numeric_limits::max()); + if (maxdist >= maxSqrt) + { + nlwarning("SOUND_DEV (FMod): Ridiculously high max distance set on source"); + maxdist = maxSqrt; + } + _MinDist= mindist; _MaxDist= maxdist; if(_FModChannel!=-1) diff --git a/code/nel/src/sound/driver/music_buffer.cpp b/code/nel/src/sound/driver/music_buffer.cpp deleted file mode 100644 index 40088d49e..000000000 --- a/code/nel/src/sound/driver/music_buffer.cpp +++ /dev/null @@ -1,108 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero 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 Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "stdsound_lowlevel.h" - -#include "nel/sound/driver/music_buffer_vorbis.h" -#include "nel/sound/driver/music_buffer.h" - -using namespace std; -using namespace NLMISC; - -namespace NLSOUND -{ - -IMusicBuffer::IMusicBuffer() : _InternalStream(NULL) -{ - -} - -IMusicBuffer::~IMusicBuffer() -{ - if (_InternalStream) { delete _InternalStream; _InternalStream = NULL; } -} - -IMusicBuffer *IMusicBuffer::createMusicBuffer(const std::string &filepath, bool async, bool loop) -{ - string lookup = CPath::lookup(filepath, false); - if (lookup.empty()) - { - nlwarning("Music file %s does not exist!", filepath.c_str()); - return NULL; - } - string type = CFile::getExtension(filepath); - - CIFile *ifile = new CIFile(); - ifile->setAsyncLoading(async); - ifile->open(lookup); - - IMusicBuffer *mb = createMusicBuffer(type, ifile, loop); - - if (mb) mb->_InternalStream = ifile; - else delete ifile; - - return mb; -} - -IMusicBuffer *IMusicBuffer::createMusicBuffer(const std::string &type, NLMISC::IStream *stream, bool loop) -{ - if (!stream) - { - nlwarning("Stream is NULL"); - return NULL; - } - string type_lower = toLower(type); - if (type_lower == "ogg") - { - return new CMusicBufferVorbis(stream, loop); - } - else - { - nlwarning("Music file type unknown: '%s'", type_lower.c_str()); - return NULL; - } -} - -bool IMusicBuffer::getInfo(const std::string &filepath, std::string &artist, std::string &title) -{ - string lookup = CPath::lookup(filepath, false); - if (lookup.empty()) - { - nlwarning("Music file %s does not exist!", filepath.c_str()); - return false; - } - string type = CFile::getExtension(filepath); - string type_lower = toLower(type); - - if (type_lower == "ogg") - { - CIFile ifile; - ifile.setCacheFileOnOpen(false); - ifile.allowBNPCacheFileOnOpen(false); - ifile.open(lookup); - return CMusicBufferVorbis::getInfo(&ifile, artist, title); - } - else - { - nlwarning("Music file type unknown: '%s'", type_lower.c_str()); - artist.clear(); title.clear(); - return false; - } -} - -} /* namespace NLSOUND */ - -/* end of file */ diff --git a/code/nel/src/sound/driver/openal/CMakeLists.txt b/code/nel/src/sound/driver/openal/CMakeLists.txt index 53b0c8c2a..47ce5b24f 100644 --- a/code/nel/src/sound/driver/openal/CMakeLists.txt +++ b/code/nel/src/sound/driver/openal/CMakeLists.txt @@ -44,7 +44,9 @@ IF(WITH_PCH) ADD_NATIVE_PRECOMPILED_HEADER(${NLDRV_AL_LIB} ${CMAKE_CURRENT_SOURCE_DIR}/stdopenal.h ${CMAKE_CURRENT_SOURCE_DIR}/stdopenal.cpp) ENDIF(WITH_PCH) -INSTALL(TARGETS ${NLDRV_AL_LIB} RUNTIME DESTINATION bin LIBRARY DESTINATION ${NL_DRIVER_PREFIX} ARCHIVE DESTINATION lib COMPONENT driverssound) -IF(WITH_MAXPLUGIN) - INSTALL(TARGETS ${NLDRV_AL_LIB} RUNTIME DESTINATION maxplugin COMPONENT driverssound) -ENDIF(WITH_MAXPLUGIN) +IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC_DRIVERS) OR NOT WITH_STATIC_DRIVERS) + INSTALL(TARGETS ${NLDRV_AL_LIB} RUNTIME DESTINATION ${NL_DRIVER_PREFIX} LIBRARY DESTINATION ${NL_DRIVER_PREFIX} ARCHIVE DESTINATION lib COMPONENT driverssound) + IF(WITH_MAXPLUGIN) + INSTALL(TARGETS ${NLDRV_AL_LIB} RUNTIME DESTINATION maxplugin COMPONENT driverssound) + ENDIF(WITH_MAXPLUGIN) +ENDIF((WITH_INSTALL_LIBRARIES AND WITH_STATIC_DRIVERS) OR NOT WITH_STATIC_DRIVERS) diff --git a/code/nel/src/sound/driver/openal/Makefile.am b/code/nel/src/sound/driver/openal/Makefile.am deleted file mode 100644 index 559a26370..000000000 --- a/code/nel/src/sound/driver/openal/Makefile.am +++ /dev/null @@ -1,30 +0,0 @@ -# -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = driver_openal.def driver_openal.dsp driver_openal.vcproj - -lib_LTLIBRARIES = libnel_drv_openal.la - -libnel_drv_openal_la_SOURCES = buffer_al.cpp \ - buffer_al.h \ - listener_al.cpp \ - listener_al.h \ - sound_driver_al.cpp \ - sound_driver_al.h \ - source_al.cpp \ - source_al.h \ - stdopenal.h - -AM_CXXFLAGS = -I$(top_srcdir)/src @OPENAL_CFLAGS@ @OGG_CFLAGS@ @VORBIS_CFLAGS@ - -noinst_HEADERS = stdopenal.h - -libnel_drv_openal_la_LIBADD = @OPENAL_LIBS@ @OGG_LIBS@ @VORBIS_LIBS@ - -libnel_drv_openal_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ - - -# End of Makefile.am - diff --git a/code/nel/src/sound/driver/openal/listener_al.cpp b/code/nel/src/sound/driver/openal/listener_al.cpp index 67eaf2478..da7e6bc31 100644 --- a/code/nel/src/sound/driver/openal/listener_al.cpp +++ b/code/nel/src/sound/driver/openal/listener_al.cpp @@ -145,9 +145,8 @@ void CListenerAL::getOrientation( NLMISC::CVector& front, NLMISC::CVector& u */ void CListenerAL::setGain( float gain ) { - CSoundDriverAL::getInstance()->setGain(gain); -// alListenerf( AL_GAIN, gain ); -// alTestError(); + alListenerf( AL_GAIN, gain ); + alTestError(); } @@ -156,15 +155,14 @@ void CListenerAL::setGain( float gain ) */ float CListenerAL::getGain() const { - return CSoundDriverAL::getInstance()->getGain(); -// ALfloat gain; -//#ifdef NL_OS_WINDOWS -// alGetListenerf( AL_GAIN, &gain ); -//#else -// alGetListenerfv( AL_GAIN, &gain ); -//#endif -// alTestError(); -// return gain; + ALfloat gain; +#ifdef NL_OS_WINDOWS + alGetListenerf( AL_GAIN, &gain ); +#else + alGetListenerfv( AL_GAIN, &gain ); +#endif + alTestError(); + return gain; } diff --git a/code/nel/src/sound/driver/openal/music_channel_al.cpp b/code/nel/src/sound/driver/openal/music_channel_al.cpp deleted file mode 100644 index b1849b33e..000000000 --- a/code/nel/src/sound/driver/openal/music_channel_al.cpp +++ /dev/null @@ -1,328 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero 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 Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "stdopenal.h" - -// Project includes -#include "sound_driver_al.h" -#include "source_al.h" -#include "buffer_al.h" -#include "music_channel_al.h" - -using namespace std; -using namespace NLMISC; - -namespace NLSOUND -{ - -CMusicChannelAL::CMusicChannelAL(CSoundDriverAL *soundDriver) -: _SoundDriver(soundDriver), _MusicBuffer(NULL), _Thread(NULL), _Buffer(NULL), _Source(NULL), _Playing(false), _Async(false), _Gain(1.0) -{ - // create a default source for music streaming - _Source = static_cast(_SoundDriver->createSource()); - _Source->setType(SourceMusic); - _Source->setStreamingBufferSize(32768); -} - -CMusicChannelAL::~CMusicChannelAL() -{ - release(); - if (_SoundDriver) { _SoundDriver->removeMusicChannel(this); _SoundDriver = NULL; } -} - -void CMusicChannelAL::release() -{ - // stop thread before deleting it - stop(); - - // delete thread - if (_Thread) - { - delete _Thread; - _Thread = NULL; - } - - // delete source - if (_Source) - { - delete _Source; - _Source = NULL; - } -} - -/// Fill IBuffer with data from IMusicBuffer -bool CMusicChannelAL::fillBuffer(IBuffer *buffer, uint length) -{ - if (!buffer || !length) - { - nlwarning("AL: No data to stream"); - return false; - } - - // fill buffer with music data - uint8 *tmp = buffer->lock(length); - if (tmp == NULL) - { - nlwarning("AL: Can't allocate %u bytes for buffer", length); - return false; - } - - uint32 size = _MusicBuffer->getNextBytes(tmp, length, length); - buffer->unlock(size); - - return size > 0; -} - -/// Use buffer format from IMusicBuffer -void CMusicChannelAL::setBufferFormat(IBuffer *buffer) -{ - if (!buffer) - { - nlwarning("AL: No buffer specified"); - return; - } - - // use the same format as music for buffers - buffer->setFormat(IBuffer::FormatPcm, _MusicBuffer->getChannels(), - _MusicBuffer->getBitsPerSample(), _MusicBuffer->getSamplesPerSec()); -} - -void CMusicChannelAL::run() -{ - bool first = true; - - // use queued buffers - do - { - // buffers to update - std::vector buffers; - - if (first) - { - // get all buffers to queue - _Source->getStreamingBuffers(buffers); - - // set format for each buffer - for(uint i = 0; i < buffers.size(); ++i) - setBufferFormat(buffers[i]); - } - else - { - // get unqueued buffers - _Source->getProcessedStreamingBuffers(buffers); - } - - // fill buffers - for(uint i = 0; i < buffers.size(); ++i) - { - if (!fillBuffer(buffers[i], _Source->getStreamingBufferSize())) - break; - - // add buffer to streaming buffers queue - _Source->submitStreamingBuffer(buffers[i]); - } - - // play the source - if (first) - { - _Source->play(); - first = false; - } - - // wait 100ms before rechecking buffers - nlSleep(100); - } - while(!_MusicBuffer->isMusicEnded() && _Playing); - - - // music finished without interruption - if (_Playing) - { - // wait until source is not playing - while(_Source->isPlaying() && _Playing) nlSleep(1000); - - _Source->stop(); - - _Playing = false; - } -} - -/// Play sync music -bool CMusicChannelAL::playSync() -{ - // use an unique buffer managed by CMusicChannelAL - _Buffer = _SoundDriver->createBuffer(); - - // set format - setBufferFormat(_Buffer); - - // fill data - fillBuffer(_Buffer, _MusicBuffer->getUncompressedSize()); - - // we don't need _MusicBuffer anymore because all is loaded into memory - if (_MusicBuffer) - { - delete _MusicBuffer; - _MusicBuffer = NULL; - } - - // delete previous queued buffers - _Source->setStreamingBuffersMax(0); - - // use this buffer as source - _Source->setStaticBuffer(_Buffer); - - // play the source - return _Source->play(); -} - -/** Play some music (.ogg etc...) - * NB: if an old music was played, it is first stop with stopMusic() - * \param filepath file path, CPath::lookup is done here - * \param async stream music from hard disk, preload in memory if false - * \param loop must be true to play the music in loop. - */ -bool CMusicChannelAL::play(const std::string &filepath, bool async, bool loop) -{ - // stop a previous music - stop(); - - // when not using async, we must load the whole file once - _MusicBuffer = IMusicBuffer::createMusicBuffer(filepath, async, async ? loop:false); - - if (_MusicBuffer) - { - _Async = async; - _Playing = true; - - _Source->setSourceRelativeMode(true); - - if (_Async) - { - // create the thread if it's not yet created - if (!_Thread) _Thread = IThread::create(this); - - if (!_Thread) - { - nlwarning("AL: Can't create a new thread"); - return false; - } - - // use 4 queued buffers - _Source->setStreamingBuffersMax(4); - - // we need to loop the source only if not async - _Source->setLooping(false); - - // start the thread - _Thread->start(); - } - else - { - // we need to loop the source only if not async - _Source->setLooping(loop); - - return playSync(); - } - } - else - { - nlwarning("AL: Can't stream file %s", filepath.c_str()); - return false; - } - - return true; -} - -/// Stop the music previously loaded and played (the Memory is also freed) -void CMusicChannelAL::stop() -{ - _Playing = false; - - _Source->stop(); - - // if not using async streaming, we manage static buffer ourself - if (!_Async && _Buffer) - { - _Source->setStaticBuffer(NULL); - delete _Buffer; - _Buffer = NULL; - } - - // wait until thread is finished - if (_Thread) - _Thread->wait(); - - if (_MusicBuffer) - { - delete _MusicBuffer; - _MusicBuffer = NULL; - } -} - -/// Pause the music previously loaded and played (the Memory is not freed) -void CMusicChannelAL::pause() -{ - _Source->pause(); -} - -/// Resume the music previously paused -void CMusicChannelAL::resume() -{ - _Source->play(); -} - -/// Return true if a song is finished. -bool CMusicChannelAL::isEnded() -{ - return !_Playing; -} - -/// Return true if the song is still loading asynchronously and hasn't started playing yet (false if not async), used to delay fading -bool CMusicChannelAL::isLoadingAsync() -{ - return _Async && _Playing && !_Source->isPlaying(); -} - -/// Return the total length (in second) of the music currently played -float CMusicChannelAL::getLength() -{ - if (_MusicBuffer) return _MusicBuffer->getLength(); - else return .0f; -} - -/** Set the music volume (if any music played). (volume value inside [0 , 1]) (default: 1) - * NB: in OpenAL driver, the volume of music IS affected by IListener::setGain() - */ -void CMusicChannelAL::setVolume(float gain) -{ - _Gain = gain; - _Source->setGain(gain); -} - -/// Update music -void CMusicChannelAL::update() -{ - // stop sync music once finished playing - if (_Playing && !_Async && !_Source->isPlaying()) - { - stop(); - } -} - -} /* namespace NLSOUND */ - -/* end of file */ diff --git a/code/nel/src/sound/driver/openal/music_channel_al.h b/code/nel/src/sound/driver/openal/music_channel_al.h deleted file mode 100644 index 157c18810..000000000 --- a/code/nel/src/sound/driver/openal/music_channel_al.h +++ /dev/null @@ -1,106 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero 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 Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef NLSOUND_MUSIC_CHANNEL_AL_H -#define NLSOUND_MUSIC_CHANNEL_AL_H - -#include "nel/sound/driver/music_channel.h" - -namespace NLSOUND -{ - class CSoundDriverAL; - class IMusicBuffer; - -/** - * \brief CMusicChannelAL - * \date 2010-07-27 16:56GMT - * \author Kervala - * CMusicChannelAL is an implementation of the IMusicChannel interface to run on OpenAL. - */ -class CMusicChannelAL : public IMusicChannel, public NLMISC::IRunnable -{ -protected: - // outside pointers - CSoundDriverAL* _SoundDriver; - - // pointers - IMusicBuffer* _MusicBuffer; - NLMISC::IThread* _Thread; - - IBuffer* _Buffer; - CSourceAL* _Source; - bool _Playing; - bool _Async; - - float _Gain; - - /// Fill IBuffer with data from IMusicBuffer - bool fillBuffer(IBuffer *buffer, uint length); - - /// Use buffer format from IMusicBuffer - void setBufferFormat(IBuffer *buffer); - - /// Declared in NLMISC::IRunnable interface - virtual void run(); - -public: - CMusicChannelAL(CSoundDriverAL *soundDriver); - virtual ~CMusicChannelAL(); - void release(); - - /** Play some music (.ogg etc...) - * NB: if an old music was played, it is first stop with stopMusic() - * \param filepath file path, CPath::lookup is done here - * \param async stream music from hard disk, preload in memory if false - * \param loop must be true to play the music in loop. - */ - virtual bool play(const std::string &filepath, bool async, bool loop); - - /// Stop the music previously loaded and played (the Memory is also freed) - virtual void stop(); - - /// Pause the music previously loaded and played (the Memory is not freed) - virtual void pause(); - - /// Resume the music previously paused - virtual void resume(); - - /// Return true if a song is finished. - virtual bool isEnded(); - - /// Return true if the song is still loading asynchronously and hasn't started playing yet (false if not async), used to delay fading - virtual bool isLoadingAsync(); - - /// Return the total length (in second) of the music currently played - virtual float getLength(); - - /** Set the music volume (if any music played). (volume value inside [0 , 1]) (default: 1) - * NB: in OpenAL driver, the volume of music IS affected by IListener::setGain() - */ - virtual void setVolume(float gain); - - /// Play sync music - bool playSync(); - - /// Update music - void update(); -}; /* class CMusicChannelAL */ - -} /* namespace NLSOUND */ - -#endif /* #ifndef NLSOUND_MUSIC_CHANNEL_AL_H */ - -/* end of file */ diff --git a/code/nel/src/sound/driver/openal/sound_driver_al.cpp b/code/nel/src/sound/driver/openal/sound_driver_al.cpp index e94755c63..e7eaca3f6 100644 --- a/code/nel/src/sound/driver/openal/sound_driver_al.cpp +++ b/code/nel/src/sound/driver/openal/sound_driver_al.cpp @@ -16,7 +16,6 @@ #include "stdopenal.h" #include "sound_driver_al.h" -#include "music_channel_al.h" #include "buffer_al.h" #include "listener_al.h" #include "source_al.h" @@ -174,7 +173,7 @@ uint32 NLSOUND_interfaceVersion () */ CSoundDriverAL::CSoundDriverAL(ISoundDriver::IStringMapperProvider *stringMapper) : _StringMapper(stringMapper), _AlDevice(NULL), _AlContext(NULL), -_NbExpBuffers(0), _NbExpSources(0), _RolloffFactor(1.f), _MasterGain(1.f) +_NbExpBuffers(0), _NbExpSources(0), _RolloffFactor(1.f) { alExtInit(); } @@ -184,21 +183,16 @@ _NbExpBuffers(0), _NbExpSources(0), _RolloffFactor(1.f), _MasterGain(1.f) */ CSoundDriverAL::~CSoundDriverAL() { - // Release internal resources of all remaining IMusicChannel instances - if (_MusicChannels.size()) - { - nlwarning("AL: _MusicChannels.size(): '%u'", (uint32)_MusicChannels.size()); - set::iterator it(_MusicChannels.begin()), end(_MusicChannels.end()); - for (; it != end; ++it) delete *it; - _MusicChannels.clear(); - } + // WARNING: Only internal resources are released here, + // the created instances must still be released by the user! + // Remove the allocated (but not exported) source and buffer names- // Release internal resources of all remaining ISource instances if (_Sources.size()) { nlwarning("AL: _Sources.size(): '%u'", (uint32)_Sources.size()); set::iterator it(_Sources.begin()), end(_Sources.end()); - for (; it != end; ++it) delete *it; + for (; it != end; ++it) (*it)->release(); // CSourceAL will be deleted by user _Sources.clear(); } if (!_Buffers.empty()) alDeleteBuffers(compactAliveNames(_Buffers, alIsBuffer), &*_Buffers.begin()); @@ -207,7 +201,7 @@ CSoundDriverAL::~CSoundDriverAL() { nlwarning("AL: _Effects.size(): '%u'", (uint32)_Effects.size()); set::iterator it(_Effects.begin()), end(_Effects.end()); - for (; it != end; ++it) delete *it; + for (; it != end; ++it) (*it)->release(); // CEffectAL will be deleted by user _Effects.clear(); } @@ -619,16 +613,9 @@ void CSoundDriverAL::commit3DChanges() // Sync up sources & listener 3d position. if (getOption(OptionManualRolloff)) { - set::iterator it = _Sources.begin(), iend = _Sources.end(); - while(it != iend) - { + for (std::set::iterator it(_Sources.begin()), end(_Sources.end()); it != end; ++it) (*it)->updateManualRolloff(); - ++it; - } } - - // update the music (XFade etc...) - updateMusic(); } /// Write information about the driver to the output stream. @@ -656,23 +643,6 @@ void CSoundDriverAL::displayBench(NLMISC::CLog *log) NLMISC::CHTimer::display(log, CHTimer::TotalTime); } -/** Get music info. Returns false if the song is not found or the function is not implemented. - * \param filepath path to file, CPath::lookup done by driver - * \param artist returns the song artist (empty if not available) - * \param title returns the title (empty if not available) - */ -bool CSoundDriverAL::getMusicInfo(const std::string &filepath, std::string &artist, std::string &title) -{ - // add support for additional non-standard music file types info here - return IMusicBuffer::getInfo(filepath, artist, title); -} - -void CSoundDriverAL::updateMusic() -{ - set::iterator it(_MusicChannels.begin()), end(_MusicChannels.end()); - for (; it != end; ++it) (*it)->update(); -} - /// Remove a buffer void CSoundDriverAL::removeBuffer(CBufferAL *buffer) { @@ -695,35 +665,6 @@ void CSoundDriverAL::removeEffect(CEffectAL *effect) else nlwarning("AL: removeEffect already called"); } -/// Create a music channel -IMusicChannel *CSoundDriverAL::createMusicChannel() -{ - CMusicChannelAL *music_channel = new CMusicChannelAL(this); - _MusicChannels.insert(music_channel); - return static_cast(music_channel); -} - -/// (Internal) Remove a music channel (should be called by the destructor of the music channel class). -void CSoundDriverAL::removeMusicChannel(CMusicChannelAL *musicChannel) -{ - if (_MusicChannels.find(musicChannel) != _MusicChannels.end()) _MusicChannels.erase(musicChannel); - else nlwarning("AL: removeMusicChannel already called"); -} - -/// Set the gain -void CSoundDriverAL::setGain( float gain ) -{ - clamp(gain, 0.f, 1.f); - _MasterGain= gain; - // TODO: update all sources in not using manual rollof ? -} - -/// Get the gain -float CSoundDriverAL::getGain() -{ - return _MasterGain; -} - /// Delete a buffer or a source bool CSoundDriverAL::deleteItem( ALuint name, TDeleteFunctionAL aldeletefunc, vector& names ) { diff --git a/code/nel/src/sound/driver/openal/sound_driver_al.h b/code/nel/src/sound/driver/openal/sound_driver_al.h index 50bffa379..154bc6d78 100644 --- a/code/nel/src/sound/driver/openal/sound_driver_al.h +++ b/code/nel/src/sound/driver/openal/sound_driver_al.h @@ -19,13 +19,11 @@ #include -namespace NLSOUND -{ +namespace NLSOUND { class CBufferAL; class CListenerAL; class CSourceAL; class CEffectAL; - class CMusicChannelAL; // alGenBuffers, alGenSources //typedef ALAPI ALvoid ALAPIENTRY (*TGenFunctionAL) ( ALsizei, ALuint* ); @@ -82,8 +80,6 @@ private: std::set _Sources; // Allocated effects std::set _Effects; - /// Array with the allocated music channels created by client code. - std::set _MusicChannels; // Number of exported buffers (including any deleted buffers) uint _NbExpBuffers; // Number of exported sources (including any deleted sources) @@ -101,6 +97,10 @@ public: /// Destructor virtual ~CSoundDriverAL(); + inline ALCdevice *getAlDevice() { return _AlDevice; } + inline ALCcontext *getAlContext() { return _AlContext; } + inline float getRolloffFactor() { return _RolloffFactor; } + /// Return a list of available devices for the user. The value at index 0 is empty, and is used for automatic device selection. virtual void getDevices(std::vector &devices); /// Initialize the driver with a user selected device. If device.empty(), the default or most appropriate device is used. @@ -111,73 +111,46 @@ public: /// Return if an option is enabled (including those that cannot be disabled on this driver). virtual bool getOption(TSoundOptions option); - /// Commit all the changes made to 3D settings of listener and sources - virtual void commit3DChanges(); - + /// Create a sound buffer + virtual IBuffer *createBuffer(); /// Create the listener instance virtual IListener *createListener(); - /// Create a source, destroy with delete + /// Create a source virtual ISource *createSource(); - /// Create a sound buffer, destroy with delete - virtual IBuffer *createBuffer(); /// Create a reverb effect virtual IReverbEffect *createReverbEffect(); /// Return the maximum number of sources that can created virtual uint countMaxSources(); /// Return the maximum number of effects that can be created virtual uint countMaxEffects(); - - /// Write information about the driver to the output stream. - virtual void writeProfile(std::string& /* out */); - + virtual void startBench(); virtual void endBench(); virtual void displayBench(NLMISC::CLog * /* log */); - /// Create a music channel, destroy with destroyMusicChannel. - virtual IMusicChannel *createMusicChannel(); - - /** Get music info. Returns false if the song is not found or the function is not implemented. - * \param filepath path to file, CPath::lookup done by driver - * \param artist returns the song artist (empty if not available) - * \param title returns the title (empty if not available) - */ - virtual bool getMusicInfo(const std::string &filepath, std::string &artist, std::string &title); - - /// Get audio/container extensions that are supported natively by the driver implementation. - virtual void getMusicExtensions(std::vector & /* extensions */) const { } - /// Return if a music extension is supported by the driver's music channel. - virtual bool isMusicExtensionSupported(const std::string & /* extension */) const { return false; } - - ALCdevice *getAlDevice() { return _AlDevice; } - ALCcontext *getAlContext() { return _AlContext; } - float getRolloffFactor() { return _RolloffFactor; } /// Change the rolloff factor and apply to all sources void applyRolloffFactor(float f); + /// Commit all the changes made to 3D settings of listener and sources + virtual void commit3DChanges(); + + /// Write information about the driver to the output stream. + virtual void writeProfile(std::string& /* out */); + /// Remove a buffer void removeBuffer(CBufferAL *buffer); /// Remove a source void removeSource(CSourceAL *source); /// Remove an effect void removeEffect(CEffectAL *effect); - /// (Internal) Remove music channel (should be called by the destructor of the music channel class). - void removeMusicChannel(CMusicChannelAL *musicChannel); - /** Set the gain (volume value inside [0 , 1]). (default: 1) - * 0.0 -> silence - * 0.5 -> -6dB - * 1.0 -> no attenuation - * values > 1 (amplification) not supported by most drivers - */ - void setGain( float gain ); - - /// Get the gain - float getGain(); + /// Get audio/container extensions that are supported natively by the driver implementation. + virtual void getMusicExtensions(std::vector & /* extensions */) const { } + /// Return if a music extension is supported by the driver's music channel. + virtual bool isMusicExtensionSupported(const std::string & /* extension */) const { return false; } protected: - void updateMusic(); /// Allocate nb new buffers or sources void allocateNewItems( TGenFunctionAL algenfunc, TTestFunctionAL altestfunc, @@ -195,9 +168,6 @@ protected: /// Delete a buffer or a source bool deleteItem( ALuint name, TDeleteFunctionAL aldeletefunc, std::vector& names ); - - /// Master Volume [0,1] - float _MasterGain; }; diff --git a/code/nel/src/sound/driver/openal/source_al.cpp b/code/nel/src/sound/driver/openal/source_al.cpp index fe2dcb086..dab3123b1 100644 --- a/code/nel/src/sound/driver/openal/source_al.cpp +++ b/code/nel/src/sound/driver/openal/source_al.cpp @@ -15,55 +15,38 @@ // along with this program. If not, see . #include "stdopenal.h" -#include "source_al.h" #include "sound_driver_al.h" #include "listener_al.h" #include "effect_al.h" #include "buffer_al.h" +#include "source_al.h" #include "ext_al.h" +// #define NLSOUND_DEBUG_GAIN + using namespace std; using namespace NLMISC; -namespace NLSOUND +namespace NLSOUND { + +CSourceAL::CSourceAL(CSoundDriverAL *soundDriver) : +_SoundDriver(NULL), _Buffer(NULL), _Source(AL_NONE), +_DirectFilter(AL_FILTER_NULL), _EffectFilter(AL_FILTER_NULL), +_IsPlaying(false), _IsPaused(false), _StartTime(0), _IsStreaming(false), _RelativeMode(false), +_Pos(0.0f, 0.0f, 0.0f), _Gain(NLSOUND_DEFAULT_GAIN), _Alpha(1.0), +_MinDistance(1.0f), _MaxDistance(sqrt(numeric_limits::max())), +_Effect(NULL), _Direct(true), +_DirectGain(NLSOUND_DEFAULT_DIRECT_GAIN), _EffectGain(NLSOUND_DEFAULT_EFFECT_GAIN), +_DirectFilterType(ISource::FilterLowPass), _EffectFilterType(ISource::FilterLowPass), +_DirectFilterEnabled(false), _EffectFilterEnabled(false), +_DirectFilterPassGain(NLSOUND_DEFAULT_FILTER_PASS_GAIN), _EffectFilterPassGain(NLSOUND_DEFAULT_FILTER_PASS_GAIN) { - -CSourceAL::CSourceAL(CSoundDriverAL *soundDriver):ISource(), _SoundDriver(NULL), _Source(AL_NONE), - _DirectFilter(AL_FILTER_NULL), _EffectFilter(AL_FILTER_NULL) -{ - _IsPlaying = false; - _IsPaused = false; - _StartTime = 0; - - _Type = SourceSound; - _Buffer = NULL; - _BuffersMax = 0; - _BufferSize = 32768; - - _PosRelative = false; - _Gain = NLSOUND_DEFAULT_GAIN; - _Alpha = 0.0; - _Pos = CVector::Null; - _MinDistance = 1.0f; - _MaxDistance = numeric_limits::max(); - - _Effect = NULL; - _Direct = true; - _DirectGain = NLSOUND_DEFAULT_DIRECT_GAIN; - _EffectGain = NLSOUND_DEFAULT_EFFECT_GAIN; - _DirectFilterType = ISource::FilterLowPass; - _EffectFilterType = ISource::FilterLowPass; - _DirectFilterEnabled = false; - _EffectFilterEnabled = false; - _DirectFilterPassGain = NLSOUND_DEFAULT_FILTER_PASS_GAIN; - _EffectFilterPassGain = NLSOUND_DEFAULT_FILTER_PASS_GAIN; - // create the al source alGenSources(1, &_Source); alTestError(); - + // configure rolloff - if (!soundDriver || soundDriver->getOption(ISoundDriver::OptionManualRolloff)) + if (soundDriver->getOption(ISoundDriver::OptionManualRolloff)) { alSourcef(_Source, AL_ROLLOFF_FACTOR, 0); alTestError(); @@ -73,16 +56,15 @@ CSourceAL::CSourceAL(CSoundDriverAL *soundDriver):ISource(), _SoundDriver(NULL), alSourcef(_Source, AL_ROLLOFF_FACTOR, soundDriver->getRolloffFactor()); alTestError(); } - + // create filters - if (soundDriver && soundDriver->getOption(ISoundDriver::OptionEnvironmentEffects)) + if (soundDriver->getOption(ISoundDriver::OptionEnvironmentEffects)) { alGenFilters(1, &_DirectFilter); alFilteri(_DirectFilter, AL_FILTER_TYPE, AL_FILTER_LOWPASS); alFilterf(_DirectFilter, AL_LOWPASS_GAIN, NLSOUND_DEFAULT_DIRECT_GAIN); alFilterf(_DirectFilter, AL_LOWPASS_GAINHF, NLSOUND_DEFAULT_FILTER_PASS_GAIN); alTestError(); - alGenFilters(1, &_EffectFilter); alFilteri(_EffectFilter, AL_FILTER_TYPE, AL_FILTER_LOWPASS); alFilterf(_EffectFilter, AL_LOWPASS_GAIN, NLSOUND_DEFAULT_EFFECT_GAIN); @@ -103,8 +85,6 @@ CSourceAL::~CSourceAL() void CSourceAL::release() { - unqueueBuffers(); - removeBuffers(); if (_Source != AL_NONE) { alDeleteSources(1, &_Source); _Source = AL_NONE; } if (_DirectFilter != AL_FILTER_NULL) { alDeleteFilters(1, &_DirectFilter); _DirectFilter = AL_FILTER_NULL; } if (_EffectFilter != AL_FILTER_NULL) { alDeleteFilters(1, &_EffectFilter); _EffectFilter = AL_FILTER_NULL; } @@ -114,39 +94,21 @@ void CSourceAL::release() /// (Internal) Update the 3d changes. void CSourceAL::updateManualRolloff() { - CVector pos = getPos(); - - // make relative to listener (if not already!) - if (!_PosRelative) - pos -= CListenerAL::getInstance()->getPos(); - - float sqrdist = pos.sqrnorm(); - float rolloff = ISource::computeManualRolloff(_Alpha, sqrdist, _MinDistance, _MaxDistance); - float volume = _Gain * rolloff; - - // apply SFX volume - if (_SoundDriver && _Type == SourceSound) - volume *= _SoundDriver->getGain(); - - // set the attenuated volume - alSourcef(_Source, AL_GAIN, volume); + CVector distanceVector = _RelativeMode ? _Pos : (_Pos - CListenerAL::getInstance()->getPos()); + float distanceSquare = distanceVector.sqrnorm(); + float rolloff = ISource::computeManualRolloff(_Alpha, distanceSquare, _MinDistance, _MaxDistance); + alSourcef(_Source, AL_GAIN, _Gain * rolloff); alTestError(); -} - -/// Set type of the source -void CSourceAL::setType(TSourceType type) -{ - _Type = type; -} - -/// Get type of the source -TSourceType CSourceAL::getType() const -{ - return _Type; +#ifdef NLSOUND_DEBUG_GAIN + ALfloat gain; + alGetSourcef(_Source, AL_GAIN, &gain); + nlwarning("Called updateManualRolloff(), physical gain is %f, configured gain is %f, distanceSquare is %f, rolloff is %f", gain, _Gain, distanceSquare, rolloff); + alTestError(); +#endif } /// Enable or disable streaming mode. Source must be stopped to call this. -void CSourceAL::setStreaming(bool /* streaming */) +void CSourceAL::setStreaming(bool streaming) { nlassert(isStopped()); @@ -154,6 +116,7 @@ void CSourceAL::setStreaming(bool /* streaming */) alSourcei(_Source, AL_BUFFER, AL_NONE); alTestError(); _Buffer = NULL; + _IsStreaming = streaming; } /* Set the buffer that will be played (no streaming) @@ -199,11 +162,10 @@ void CSourceAL::submitStreamingBuffer(IBuffer *buffer) CBufferAL *bufferAL = static_cast(buffer); ALuint bufferName = bufferAL->bufferName(); nlassert(bufferName); - - // queue the buffer alSourceQueueBuffers(_Source, 1, &bufferName); alTestError(); - + _QueuedBuffers.push(bufferAL); + // Resume playback if the internal OpenAL source stopped due to buffer underrun. ALint srcstate; alGetSourcei(_Source, AL_SOURCE_STATE, &srcstate); @@ -218,11 +180,23 @@ void CSourceAL::submitStreamingBuffer(IBuffer *buffer) /// Return the amount of buffers in the queue (playing and waiting). 3 buffers is optimal. uint CSourceAL::countStreamingBuffers() const { + // a bit ugly here, but makes a much easier/simpler implementation on both drivers + ALint buffersProcessed; + alGetSourcei(_Source, AL_BUFFERS_PROCESSED, &buffersProcessed); + while (buffersProcessed) + { + ALuint bufferName = _QueuedBuffers.front()->bufferName(); + alSourceUnqueueBuffers(_Source, 1, &bufferName); + alTestError(); + const_cast &>(_QueuedBuffers).pop(); + --buffersProcessed; + } // return how many are left in the queue - ALint buffersQueued; - alGetSourcei(_Source, AL_BUFFERS_QUEUED, &buffersQueued); - alTestError(); - return (uint)buffersQueued; + //ALint buffersQueued; + //alGetSourcei(_SourceName, AL_BUFFERS_QUEUED, &buffersQueued); + //alTestError(); + //return (uint)buffersQueued; + return (uint)_QueuedBuffers.size(); } /// Set looping on/off for future playbacks (default: off) @@ -244,28 +218,44 @@ bool CSourceAL::getLooping() const /// Play the static buffer (or stream in and play) bool CSourceAL::play() { - if ( _Buffer != NULL ) +#ifdef NLSOUND_DEBUG_GAIN + if (_IsStreaming) + { + nlwarning("Called play on a streaming source"); + } +#endif + + // Commit 3D changes before starting play + if (_SoundDriver->getOption(ISoundDriver::OptionManualRolloff)) + updateManualRolloff(); + + if (_Buffer) { // Static playing mode _IsPaused = false; alSourcePlay(_Source); - _IsPlaying = alGetError() == AL_NO_ERROR; + _IsPlaying = (alGetError() == AL_NO_ERROR); if (_IsPlaying) _StartTime = CTime::getLocalTime(); return _IsPlaying; } - else + else if (_IsStreaming) { - // TODO: Verify streaming mode? _IsPaused = false; alSourcePlay(_Source); - _IsPlaying = true; - _StartTime = CTime::getLocalTime(); - return true; + _IsPlaying = (alGetError() == AL_NO_ERROR); + if (_IsPlaying) + _StartTime = CTime::getLocalTime(); // TODO: Played time should freeze when buffering fails, and be calculated based on the number of buffers played plus passed time. This is necessary for synchronizing animation with sound. + return _IsPlaying; // Streaming mode //nlwarning("AL: Cannot play null buffer; streaming not implemented" ); //nlstop; } + else + { + nlwarning("Invalid play call, not streaming and no static buffer assigned"); + return false; + } } /// Stop playing @@ -288,8 +278,14 @@ void CSourceAL::stop() _IsPaused = false; alSourceStop(_Source); alTestError(); - - unqueueBuffers(); + // unqueue buffers + while (_QueuedBuffers.size()) + { + ALuint bufferName = _QueuedBuffers.front()->bufferName(); + alSourceUnqueueBuffers(_Source, 1, &bufferName); + _QueuedBuffers.pop(); + alTestError(); + } // Streaming mode //nlwarning("AL: Cannot stop null buffer; streaming not implemented" ); //nlstop; @@ -379,8 +375,7 @@ bool CSourceAL::isPaused() const uint32 CSourceAL::getTime() { if (!_StartTime) return 0; - - return (uint32)(CTime::getLocalTime() - _StartTime); + return (uint32)(CTime::getLocalTime() - _StartTime); } /// Set the position vector. @@ -438,27 +433,28 @@ void CSourceAL::getDirection( NLMISC::CVector& dir ) const void CSourceAL::setGain(float gain) { _Gain = std::min(std::max(gain, NLSOUND_MIN_GAIN), NLSOUND_MAX_GAIN); - - if ((_SoundDriver == NULL) || !_SoundDriver->getOption(ISoundDriver::OptionManualRolloff)) + if (!_SoundDriver->getOption(ISoundDriver::OptionManualRolloff)) { - float gain = _Gain; - - // apply SFX volume - if (_SoundDriver && _Type == SourceSound) - gain *= _SoundDriver->getGain(); - - alSourcef(_Source, AL_GAIN, gain); + alSourcef(_Source, AL_GAIN, _Gain); alTestError(); } +#ifdef NLSOUND_DEBUG_GAIN + else + { + nlwarning("Called setGain(), manual rolloff, commit deferred to play or update, physical gain is %f, configured gain is %f", gain, _Gain); + } +#endif } /// Get the gain float CSourceAL::getGain() const { - //ALfloat gain; - //alGetSourcef(_Source, AL_GAIN, &gain); - //alTestError(); - //return gain; +#ifdef NLSOUND_DEBUG_GAIN + ALfloat gain; + alGetSourcef(_Source, AL_GAIN, &gain); + nlwarning("Called getGain(), physical gain is %f, configured gain is %f", gain, _Gain); + alTestError(); +#endif return _Gain; } @@ -481,7 +477,7 @@ float CSourceAL::getPitch() const /// Set the source relative mode. If true, positions are interpreted relative to the listener position. void CSourceAL::setSourceRelativeMode( bool mode ) { - _PosRelative = mode; + _RelativeMode = mode; alSourcei(_Source, AL_SOURCE_RELATIVE, mode?AL_TRUE:AL_FALSE ); alTestError(); } @@ -489,21 +485,28 @@ void CSourceAL::setSourceRelativeMode( bool mode ) /// Get the source relative mode (3D mode only) bool CSourceAL::getSourceRelativeMode() const { - return _PosRelative; -// ALint b; -// alGetSourcei(_Source, AL_SOURCE_RELATIVE, &b ); -// alTestError(); -// return (b==AL_TRUE); + //ALint b; + //alGetSourcei(_Source, AL_SOURCE_RELATIVE, &b ); + //alTestError(); + //return (b==AL_TRUE); + return _RelativeMode; } /// Set the min and max distances (3D mode only) void CSourceAL::setMinMaxDistances( float mindist, float maxdist, bool /* deferred */) { nlassert( (mindist >= 0.0f) && (maxdist >= 0.0f) ); + + static float maxSqrt = sqrt(std::numeric_limits::max()); + if (maxdist >= maxSqrt) + { + nlwarning("SOUND_DEV (OpenAL): Ridiculously high max distance set on source"); + maxdist = maxSqrt; + } + _MinDistance = mindist; _MaxDistance = maxdist; - - if (!_SoundDriver || !_SoundDriver->getOption(ISoundDriver::OptionManualRolloff)) + if (!_SoundDriver->getOption(ISoundDriver::OptionManualRolloff)) { alSourcef(_Source, AL_REFERENCE_DISTANCE, mindist); alSourcef(_Source, AL_MAX_DISTANCE, maxdist); @@ -805,122 +808,4 @@ float CSourceAL::getEffectFilterPassGain() const return _EffectFilterPassGain; } -/// Get already processed buffers and unqueue them -void CSourceAL::getProcessedStreamingBuffers(std::vector &buffers) -{ - // get the number of processed buffers - ALint buffersProcessed; - alGetSourcei(_Source, AL_BUFFERS_PROCESSED, &buffersProcessed); - alTestError(); - - // exit if more processed buffer than allocated ones - if ((uint)buffersProcessed > _BuffersMax) return; - - // unqueue all previously processed buffers and get their name - alSourceUnqueueBuffers(_Source, buffersProcessed, &(_BuffersName[0])); - alTestError(); - - // add each processed buffer to the array - for(uint i = 0; i < (uint)buffersProcessed; ++i) - { - // if buffer is found, return it - std::map::const_iterator it = _Buffers.find(_BuffersName[i]); - if (it != _Buffers.end()) - buffers.push_back(it->second); - } -} - -/// Get all existing buffers -void CSourceAL::getStreamingBuffers(std::vector &buffers) -{ - std::map::const_iterator it = _Buffers.begin(), iend = _Buffers.end(); - while(it != iend) - { - buffers.push_back(it->second); - ++it; - } -} - -/// Unqueue all buffers -void CSourceAL::unqueueBuffers() -{ - // get count of buffers in queue - uint count = countStreamingBuffers(); - - if (count > 0) - { - // unqueue all of them - alSourceUnqueueBuffers(_Source, count, &(_BuffersName[0])); - alTestError(); - } -} - -/// Delete all allocated buffers -void CSourceAL::removeBuffers() -{ - // delete each buffer - std::map::const_iterator it = _Buffers.begin(), iend = _Buffers.end(); - while(it != iend) - { - delete it->second; - ++it; - } - - _Buffers.clear(); -} - -/// Get available streaming buffers count -uint CSourceAL::getStreamingBuffersMax() const -{ - return _BuffersMax; -} - -/// Set available streaming buffers count and allocate them -void CSourceAL::setStreamingBuffersMax(uint buffers) -{ - // remember previous value - uint oldBuffersMax = _BuffersMax; - - _BuffersMax = buffers; - - // resize the temporary buffer names array - _BuffersName.resize(buffers); - - // remove all buffers - unqueueBuffers(); - removeBuffers(); - - for(uint i = 0; i < _BuffersMax; ++i) - { - try - { - // create a new buffer - CBufferAL *buffer = static_cast(_SoundDriver->createBuffer()); - // use StorageSoftware because buffers will be reused - // deleting and recreating them is a waste of time - buffer->setStorageMode(IBuffer::StorageSoftware); - _Buffers[buffer->bufferName()] = buffer; - } - catch(const ESoundDriverGenBuf &e) - { - nlwarning("Cannot create %d buffers. openal fails after %d buffers", buffers, i); - _BuffersMax = i; - _BuffersName.resize(i); - break; - } - } -} - -/// Set the default size for streaming buffers -void CSourceAL::setStreamingBufferSize(uint size) -{ - _BufferSize = size; -} - -/// Get the default size for streaming buffers -uint CSourceAL::getStreamingBufferSize() const -{ - return _BufferSize; -} - } // NLSOUND diff --git a/code/nel/src/sound/driver/openal/source_al.h b/code/nel/src/sound/driver/openal/source_al.h index b5611b997..53c77cb7f 100644 --- a/code/nel/src/sound/driver/openal/source_al.h +++ b/code/nel/src/sound/driver/openal/source_al.h @@ -17,17 +17,14 @@ #ifndef NL_SOURCE_AL_H #define NL_SOURCE_AL_H -#include "nel/sound/driver/source.h" +#include -namespace NLSOUND -{ +namespace NLSOUND { class IBuffer; class CBufferAL; class CSoundDriverAL; class CEffectAL; - enum TSourceType { SourceSound, SourceMusic }; - /** * OpenAL sound source * @@ -50,29 +47,22 @@ private: /// Sound driver CSoundDriverAL *_SoundDriver; + /// Assigned buffer object + CBufferAL *_Buffer; + std::queue _QueuedBuffers; + /// AL Handles ALuint _Source; ALuint _DirectFilter, _EffectFilter; - - /// Assigned buffer object - CBufferAL *_Buffer; - /// Queued buffers map (uint is buffer name) - std::map _Buffers; - - /// Temporary queued buffers array - std::vector _BuffersName; - /// Max count of queued buffers allowed - uint _BuffersMax; - /// Default size of a buffer - uint _BufferSize; - - /// Position is relative to listener - bool _PosRelative; - + /// Playing status bool _IsPlaying; bool _IsPaused; - NLMISC::TTime _StartTime; + NLMISC::TTime _StartTime; + + bool _IsStreaming; + bool _RelativeMode; + NLMISC::CVector _Pos; float _Gain; double _Alpha; @@ -90,9 +80,6 @@ private: TFilter _DirectFilterType, _EffectFilterType; bool _DirectFilterEnabled, _EffectFilterEnabled; float _DirectFilterPassGain, _EffectFilterPassGain; - - /// Source type can be SourceSound or SourceMusic - TSourceType _Type; public: /// Constructor @@ -104,13 +91,8 @@ public: void release(); /// Return the OpenAL source name - ALuint getSource() const { return _Source; } - - /// Set type of the source - void setType(TSourceType type); - /// Get type of the source - TSourceType getType() const; - + inline ALuint getSource() const { return _Source; } + /// (Internal) Set the effect send for this source, NULL to disable. void setEffect(CEffectAL *effect); /// (Internal) Setup the direct send filter. @@ -275,22 +257,6 @@ public: virtual float getEffectFilterPassGain() const; //@} - /// Get already processed buffers and unqueue them - void getProcessedStreamingBuffers(std::vector &buffers); - /// Get all existing buffers - void getStreamingBuffers(std::vector &buffers); - /// Unqueue all buffers - void unqueueBuffers(); - /// Delete all allocated buffers - void removeBuffers(); - /// Get available streaming buffers count - uint getStreamingBuffersMax() const; - /// Set available streaming buffers count and allocate them - void setStreamingBuffersMax(uint max); - /// Set the default size for streaming buffers - void setStreamingBufferSize(uint size); - /// Get the default size for streaming buffers - uint getStreamingBufferSize() const; }; } // NLSOUND diff --git a/code/nel/src/sound/driver/openal/stdopenal.h b/code/nel/src/sound/driver/openal/stdopenal.h index 12960d57f..1661ef6fe 100644 --- a/code/nel/src/sound/driver/openal/stdopenal.h +++ b/code/nel/src/sound/driver/openal/stdopenal.h @@ -58,6 +58,5 @@ #include "nel/sound/driver/source.h" #include "nel/sound/driver/listener.h" #include "nel/sound/driver/effect.h" -#include "nel/sound/driver/music_buffer.h" /* end of file */ diff --git a/code/nel/src/sound/driver/source.cpp b/code/nel/src/sound/driver/source.cpp index ace98ff81..2f96d74d8 100644 --- a/code/nel/src/sound/driver/source.cpp +++ b/code/nel/src/sound/driver/source.cpp @@ -26,15 +26,12 @@ namespace NLSOUND // common method used only with OptionManualRolloff. return the volume in 1/100th DB ( = mB) modified sint32 ISource::computeManualRollOff(sint32 volumeMB, sint32 mbMin, sint32 mbMax, double alpha, float sqrdist, float distMin, float distMax) { - // root square of max float value - static float maxSqrt = sqrt(std::numeric_limits::max()); - if (sqrdist < distMin * distMin) { // no attenuation return volumeMB; } - else if ((distMax < maxSqrt) && (sqrdist > distMax * distMax)) + else if (sqrdist > distMax * distMax) { // full attenuation return mbMin; diff --git a/code/nel/src/sound/driver/xaudio2/CMakeLists.txt b/code/nel/src/sound/driver/xaudio2/CMakeLists.txt index 5e45a9809..eb342a4df 100644 --- a/code/nel/src/sound/driver/xaudio2/CMakeLists.txt +++ b/code/nel/src/sound/driver/xaudio2/CMakeLists.txt @@ -40,7 +40,9 @@ IF(WITH_PCH) ADD_NATIVE_PRECOMPILED_HEADER(nel_drv_xaudio2_win ${CMAKE_CURRENT_SOURCE_DIR}/stdxaudio2.h ${CMAKE_CURRENT_SOURCE_DIR}/stdxaudio2.cpp) ENDIF(WITH_PCH) -INSTALL(TARGETS nel_drv_xaudio2_win RUNTIME DESTINATION bin LIBRARY DESTINATION ${NL_DRIVER_PREFIX} ARCHIVE DESTINATION lib COMPONENT driverssound) -IF(WITH_MAXPLUGIN) - INSTALL(TARGETS nel_drv_xaudio2_win RUNTIME DESTINATION maxplugin COMPONENT driverssound) -ENDIF(WITH_MAXPLUGIN) +IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC_DRIVERS) OR NOT WITH_STATIC_DRIVERS) + INSTALL(TARGETS nel_drv_xaudio2_win RUNTIME DESTINATION bin LIBRARY DESTINATION ${NL_DRIVER_PREFIX} ARCHIVE DESTINATION lib COMPONENT driverssound) + IF(WITH_MAXPLUGIN) + INSTALL(TARGETS nel_drv_xaudio2_win RUNTIME DESTINATION maxplugin COMPONENT driverssound) + ENDIF(WITH_MAXPLUGIN) +ENDIF((WITH_INSTALL_LIBRARIES AND WITH_STATIC_DRIVERS) OR NOT WITH_STATIC_DRIVERS) diff --git a/code/nel/src/sound/driver/xaudio2/music_channel_xaudio2.cpp b/code/nel/src/sound/driver/xaudio2/music_channel_xaudio2.cpp deleted file mode 100644 index 4110ecf41..000000000 --- a/code/nel/src/sound/driver/xaudio2/music_channel_xaudio2.cpp +++ /dev/null @@ -1,248 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero 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 Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "stdxaudio2.h" - -// Project includes -#include "sound_driver_xaudio2.h" -#include "music_channel_xaudio2.h" - -using namespace std; -using namespace NLMISC; - -namespace NLSOUND { - -CMusicChannelXAudio2::CMusicChannelXAudio2(CSoundDriverXAudio2 *soundDriver) -: _MusicBuffer(NULL), _SourceVoice(NULL), _BufferPos(0), _SoundDriver(soundDriver), _Gain(1.0) -{ - nlwarning(NLSOUND_XAUDIO2_PREFIX "Initializing CMusicChannelXAudio2"); - - stop(); -} - -CMusicChannelXAudio2::~CMusicChannelXAudio2() -{ - release(); - if (_SoundDriver) { _SoundDriver->removeMusicChannel(this); _SoundDriver = NULL; } - - nlwarning(NLSOUND_XAUDIO2_PREFIX "Destroying CMusicChannelXAudio2"); -} - -void CMusicChannelXAudio2::release() -{ - nlwarning(NLSOUND_XAUDIO2_PREFIX "Releasing CMusicChannelXAudio2"); - - stop(); -} - -/** Play some music (.ogg etc...) - * NB: if an old music was played, it is first stop with stopMusic() - * \param filepath file path, CPath::lookup is done here - * \param async stream music from hard disk, preload in memory if false - * \param loop must be true to play the music in loop. - */ -bool CMusicChannelXAudio2::play(const std::string &filepath, bool async, bool loop) -{ - // nlinfo(NLSOUND_XAUDIO2_PREFIX "play %s %u", filepath.c_str(), (uint32)loop); - - _SoundDriver->performanceIncreaseMusicPlayCounter(); - - HRESULT hr; - - stop(); - - _MusicBuffer = IMusicBuffer::createMusicBuffer(filepath, async, loop); - - if (_MusicBuffer) - { - WAVEFORMATEX wfe; - wfe.cbSize = 0; - wfe.wFormatTag = WAVE_FORMAT_PCM; // todo: getFormat(); - wfe.nChannels = _MusicBuffer->getChannels(); - wfe.wBitsPerSample = _MusicBuffer->getBitsPerSample(); - wfe.nSamplesPerSec = _MusicBuffer->getSamplesPerSec(); - wfe.nBlockAlign = wfe.nChannels * wfe.wBitsPerSample / 8; - wfe.nAvgBytesPerSec = wfe.nSamplesPerSec * wfe.nBlockAlign; - - XAUDIO2_VOICE_DETAILS voice_details; - _SoundDriver->getMasteringVoice()->GetVoiceDetails(&voice_details); - - // nlinfo(NLSOUND_XAUDIO2_PREFIX "Creating music voice with %u channels, %u bits per sample, %u samples per sec, " - // "on mastering voice with %u channels, %u samples per sec", - // (uint32)wfe.nChannels, (uint32)wfe.wBitsPerSample, (uint32)wfe.nSamplesPerSec, - // (uint32)voice_details.InputChannels, (uint32)voice_details.InputSampleRate); - - if (FAILED(hr = _SoundDriver->getXAudio2()->CreateSourceVoice(&_SourceVoice, &wfe, XAUDIO2_VOICE_NOPITCH, 1.0f, this, NULL, NULL))) - { - nlwarning(NLSOUND_XAUDIO2_PREFIX "FAILED CreateSourceVoice"); - stop(); return false; - } - - _SourceVoice->SetVolume(_Gain); - _SourceVoice->Start(0); - } - else - { - nlwarning(NLSOUND_XAUDIO2_PREFIX "no _MusicBuffer"); - return false; - } - - return true; -} - -/// Stop the music previously loaded and played (the Memory is also freed) -void CMusicChannelXAudio2::stop() -{ - if (_SourceVoice) { _SourceVoice->DestroyVoice(); _SourceVoice = NULL; } - if (_MusicBuffer) { delete _MusicBuffer; _MusicBuffer = NULL; } - // memset(_Buffer, 0, sizeof(_Buffer)); - _BufferPos = 0; -} - -/** Pause the music previously loaded and played (the Memory is not freed) - */ -void CMusicChannelXAudio2::pause() -{ - if (_SourceVoice) _SourceVoice->Stop(0); -} - -/// Resume the music previously paused -void CMusicChannelXAudio2::resume() -{ - if (_SourceVoice) _SourceVoice->Start(0); -} - -/// Return true if a song is finished. -bool CMusicChannelXAudio2::isEnded() -{ - if (_MusicBuffer) - { - if (!_MusicBuffer->isMusicEnded()) - return false; - } - if (_SourceVoice) - { - XAUDIO2_VOICE_STATE voice_state; - _SourceVoice->GetState(&voice_state); - if (voice_state.BuffersQueued) - { - // nldebug(NLSOUND_XAUDIO2_PREFIX "isEnded() -> voice_state.BuffersQueued, wait ..."); - return false; - } - } - // nldebug(NLSOUND_XAUDIO2_PREFIX "isEnded() -> stop()"); - stop(); - return true; -} - -/// Return true if the song is still loading asynchronously and hasn't started playing yet (false if not async), used to delay fading -bool CMusicChannelXAudio2::isLoadingAsync() -{ - return false; -} - -/// Return the total length (in second) of the music currently played -float CMusicChannelXAudio2::getLength() -{ - if (_MusicBuffer) return _MusicBuffer->getLength(); - else return .0f; -} - -/** Set the music volume (if any music played). (volume value inside [0 , 1]) (default: 1) - * NB: the volume of music is NOT affected by IListener::setGain() - */ -void CMusicChannelXAudio2::setVolume(float gain) -{ - _Gain = gain; - if (_SourceVoice) _SourceVoice->SetVolume(gain); -} - -void CMusicChannelXAudio2::OnVoiceProcessingPassStart(UINT32 BytesRequired) -{ - if (BytesRequired > 0) - { - // nlwarning(NLSOUND_XAUDIO2_PREFIX "Bytes Required: %u", BytesRequired); // byte req to not have disruption - - if (_MusicBuffer) - { - uint32 minimum = BytesRequired * 2; // give some more than required :p - if (_MusicBuffer->getRequiredBytes() > minimum) minimum = _MusicBuffer->getRequiredBytes(); - if (minimum > sizeof(_Buffer) - _BufferPos) _BufferPos = 0; - uint32 maximum = sizeof(_Buffer) - _BufferPos; - uint8 *buffer = &_Buffer[_BufferPos]; - uint32 length = _MusicBuffer->getNextBytes(buffer, minimum, maximum); - _BufferPos += length; - - if (length) - { - XAUDIO2_BUFFER xbuffer; - xbuffer.AudioBytes = length; - xbuffer.Flags = 0; - xbuffer.LoopBegin = 0; - xbuffer.LoopCount = 0; - xbuffer.LoopLength = 0; - xbuffer.pAudioData = buffer; - xbuffer.pContext = NULL; // nothing here for now - xbuffer.PlayBegin = 0; - xbuffer.PlayLength = 0; - - _SourceVoice->SubmitSourceBuffer(&xbuffer); - } - else - { - // nldebug(NLSOUND_XAUDIO2_PREFIX "!length -> delete _MusicBuffer"); - // set member var to null before deleting it to avoid crashing main thread - IMusicBuffer *music_buffer = _MusicBuffer; - _MusicBuffer = NULL; delete music_buffer; - _SourceVoice->Discontinuity(); - } - } - } -} - -void CMusicChannelXAudio2::OnVoiceProcessingPassEnd() -{ - -} - -void CMusicChannelXAudio2::OnStreamEnd() -{ - -} - -void CMusicChannelXAudio2::OnBufferStart(void * /* pBufferContext */) -{ - -} - -void CMusicChannelXAudio2::OnBufferEnd(void * /* pBufferContext */) -{ - -} - -void CMusicChannelXAudio2::OnLoopEnd(void * /* pBufferContext */) -{ - -} - -void CMusicChannelXAudio2::OnVoiceError(void * /* pBufferContext */, HRESULT /* Error */) -{ - -} - -} /* namespace NLSOUND */ - -/* end of file */ diff --git a/code/nel/src/sound/driver/xaudio2/music_channel_xaudio2.h b/code/nel/src/sound/driver/xaudio2/music_channel_xaudio2.h deleted file mode 100644 index ade13e25f..000000000 --- a/code/nel/src/sound/driver/xaudio2/music_channel_xaudio2.h +++ /dev/null @@ -1,117 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero 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 Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef NLSOUND_MUSIC_CHANNEL_XAUDIO2_H -#define NLSOUND_MUSIC_CHANNEL_XAUDIO2_H - -#include - -namespace NLSOUND { - class CSoundDriverXAudio2; - class IMusicBuffer; - -/** - * \brief CMusicChannelXAudio2 - * \date 2008-08-30 13:31GMT - * \author Jan Boon (Kaetemi) - * CMusicChannelXAudio2 is an implementation of the IMusicChannel interface to run on XAudio2. - * TODO: Properly decode the audio on a seperate thread. - * TODO: Change IMusicChannel to IAudioStream, and fix the interface to make more sense. - */ -class CMusicChannelXAudio2 : public IMusicChannel, IXAudio2VoiceCallback -{ -protected: - // outside pointers - CSoundDriverXAudio2 *_SoundDriver; - - // pointers - IMusicBuffer *_MusicBuffer; - IXAudio2SourceVoice *_SourceVoice; - // todo: thread for async loading of music buffer and source voice - // isasyncloading checks if thread exists - // isended checks if not async loading too - - // instances - uint8 _Buffer[64 * 1024]; // no specific reason, lol - uint32 _BufferPos; // 0 - float _Gain; - -public: - CMusicChannelXAudio2(CSoundDriverXAudio2 *soundDriver); - virtual ~CMusicChannelXAudio2(); - void release(); - -private: - // XAudio2 Callbacks - // Called just before this voice's processing pass begins. - STDMETHOD_(void, OnVoiceProcessingPassStart) (THIS_ UINT32 BytesRequired); - // Called just after this voice's processing pass ends. - STDMETHOD_(void, OnVoiceProcessingPassEnd) (THIS); - // Called when this voice has just finished playing a buffer stream - // (as marked with the XAUDIO2_END_OF_STREAM flag on the last buffer). - STDMETHOD_(void, OnStreamEnd) (THIS); - // Called when this voice is about to start processing a new buffer. - STDMETHOD_(void, OnBufferStart) (THIS_ void* pBufferContext); - // Called when this voice has just finished processing a buffer. - // The buffer can now be reused or destroyed. - STDMETHOD_(void, OnBufferEnd) (THIS_ void* pBufferContext); - // Called when this voice has just reached the end position of a loop. - STDMETHOD_(void, OnLoopEnd) (THIS_ void* pBufferContext); - // Called in the event of a critical error during voice processing, - // such as a failing XAPO or an error from the hardware XMA decoder. - // The voice may have to be destroyed and re-created to recover from - // the error. The callback arguments report which buffer was being - // processed when the error occurred, and its HRESULT code. - STDMETHOD_(void, OnVoiceError) (THIS_ void* pBufferContext, HRESULT Error); - -public: - /** Play some music (.ogg etc...) - * NB: if an old music was played, it is first stop with stopMusic() - * \param filepath file path, CPath::lookup is done here - * \param async stream music from hard disk, preload in memory if false - * \param loop must be true to play the music in loop. - */ - virtual bool play(const std::string &filepath, bool async, bool loop); - - /// Stop the music previously loaded and played (the Memory is also freed) - virtual void stop(); - - /// Pause the music previously loaded and played (the Memory is not freed) - virtual void pause(); - - /// Resume the music previously paused - virtual void resume(); - - /// Return true if a song is finished. - virtual bool isEnded(); - - /// Return true if the song is still loading asynchronously and hasn't started playing yet (false if not async), used to delay fading - virtual bool isLoadingAsync(); - - /// Return the total length (in second) of the music currently played - virtual float getLength(); - - /** Set the music volume (if any music played). (volume value inside [0 , 1]) (default: 1) - * NB: the volume of music is NOT affected by IListener::setGain() - */ - virtual void setVolume(float gain); -}; /* class CMusicChannelXAudio2 */ - -} /* namespace NLSOUND */ - -#endif /* #ifndef NLSOUND_MUSIC_CHANNEL_XAUDIO2_H */ - -/* end of file */ diff --git a/code/nel/src/sound/driver/xaudio2/sound_driver_xaudio2.cpp b/code/nel/src/sound/driver/xaudio2/sound_driver_xaudio2.cpp index 826f9973b..7c4ea9bbf 100644 --- a/code/nel/src/sound/driver/xaudio2/sound_driver_xaudio2.cpp +++ b/code/nel/src/sound/driver/xaudio2/sound_driver_xaudio2.cpp @@ -19,7 +19,6 @@ // Project includes #include "listener_xaudio2.h" #include "source_xaudio2.h" -#include "music_channel_xaudio2.h" #include "effect_xaudio2.h" #include "sound_driver_xaudio2.h" @@ -132,8 +131,7 @@ CSoundDriverXAudio2::CSoundDriverXAudio2(ISoundDriver::IStringMapperProvider * / : _XAudio2(NULL), _MasteringVoice(NULL), _Listener(NULL), _SoundDriverOk(false), _CoInitOk(false), _OperationSetCounter(65536), _PerformanceCommit3DCounter(0), _PerformanceADPCMBufferSize(0), - _PerformancePCMBufferSize(0), _PerformanceMusicPlayCounter(0), - _PerformanceSourcePlayCounter(0) + _PerformancePCMBufferSize(0), _PerformanceSourcePlayCounter(0) { nlwarning(NLSOUND_XAUDIO2_PREFIX "Creating CSoundDriverXAudio2"); @@ -200,14 +198,6 @@ void CSoundDriverXAudio2::release() // WARNING: Only internal resources are released here, // the created instances must still be released by the user! - // Release internal resources of all remaining IMusicChannel instances - if (_MusicChannels.size()) - { - nlwarning(NLSOUND_XAUDIO2_PREFIX "_MusicChannels.size(): '%u'", (uint32)_MusicChannels.size()); - set::iterator it(_MusicChannels.begin()), end(_MusicChannels.end()); - for (; it != end; ++it) (*it)->release(); - _MusicChannels.clear(); - } // Release internal resources of all remaining ISource instances if (_Sources.size()) { @@ -396,14 +386,6 @@ void CSoundDriverXAudio2::destroySourceVoice(IXAudio2SourceVoice *sourceVoice) if (sourceVoice) sourceVoice->DestroyVoice(); } -/// Create a music channel -IMusicChannel *CSoundDriverXAudio2::createMusicChannel() -{ - CMusicChannelXAudio2 *music_channel = new CMusicChannelXAudio2(this); - _MusicChannels.insert(music_channel); - return static_cast(music_channel); -} - /// Create the listener instance IListener *CSoundDriverXAudio2::createListener() { @@ -481,7 +463,6 @@ void CSoundDriverXAudio2::writeProfile(std::string& out) + "\n\tPCMBufferSize: " + toString(_PerformancePCMBufferSize) + "\n\tADPCMBufferSize: " + toString(_PerformanceADPCMBufferSize) + "\n\tSourcePlayCounter: " + toString(_PerformanceSourcePlayCounter) - + "\n\tMusicPlayCounter: " + toString(_PerformanceMusicPlayCounter) + "\n\tCommit3DCounter: " + toString(_PerformanceCommit3DCounter) + "\nXAUDIO2_PERFORMANCE_DATA" + "\n\tAudioCyclesSinceLastQuery: " + toString(performance.AudioCyclesSinceLastQuery) @@ -519,17 +500,6 @@ void CSoundDriverXAudio2::displayBench(NLMISC::CLog *log) NLMISC::CHTimer::display(log, CHTimer::TotalTime); } -/** Get music info. Returns false if the song is not found or the function is not implemented. - * \param filepath path to file, CPath::lookup done by driver - * \param artist returns the song artist (empty if not available) - * \param title returns the title (empty if not available) - */ -bool CSoundDriverXAudio2::getMusicInfo(const std::string &filepath, std::string &artist, std::string &title) -{ - // add support for additional non-standard music file types info here - return IMusicBuffer::getInfo(filepath, artist, title); -} - /// Remove a buffer (should be called by the friend destructor of the buffer class) void CSoundDriverXAudio2::removeBuffer(CBufferXAudio2 *buffer) { @@ -543,13 +513,6 @@ void CSoundDriverXAudio2::removeSource(CSourceXAudio2 *source) if (_Sources.find(source) != _Sources.end()) _Sources.erase(source); else nlwarning("removeSource already called"); } - -/// (Internal) Remove a source (should be called by the destructor of the source class). -void CSoundDriverXAudio2::removeMusicChannel(CMusicChannelXAudio2 *musicChannel) -{ - if (_MusicChannels.find(musicChannel) != _MusicChannels.end()) _MusicChannels.erase(musicChannel); - else nlwarning("removeMusicChannel already called"); -} /// (Internal) Remove an effect (should be called by the destructor of the effect class) void CSoundDriverXAudio2::removeEffect(CEffectXAudio2 *effect) diff --git a/code/nel/src/sound/driver/xaudio2/sound_driver_xaudio2.h b/code/nel/src/sound/driver/xaudio2/sound_driver_xaudio2.h index 681d36254..bcf847a5f 100644 --- a/code/nel/src/sound/driver/xaudio2/sound_driver_xaudio2.h +++ b/code/nel/src/sound/driver/xaudio2/sound_driver_xaudio2.h @@ -62,8 +62,6 @@ protected: std::set _Sources; /// Array with the allocated effects created by client code. std::set _Effects; - /// Array with the allocated music channels created by client code. - std::set _MusicChannels; /// Initialization Handle of X3DAudio. X3DAUDIO_HANDLE _X3DAudioHandle; //I /// Operation set counter @@ -73,7 +71,6 @@ protected: uint _PerformancePCMBufferSize; uint _PerformanceADPCMBufferSize; uint _PerformanceSourcePlayCounter; - uint _PerformanceMusicPlayCounter; uint _PerformanceCommit3DCounter; // user init vars @@ -108,8 +105,6 @@ public: } /// (Internal) Increase the source play counter by one. inline void performanceIncreaseSourcePlayCounter() { ++_PerformanceSourcePlayCounter; } - /// (Internal) Increase the music play counter by one. - inline void performanceIncreaseMusicPlayCounter() { ++_PerformanceMusicPlayCounter; } /// (Internal) Increase the commit 3d counter by one. inline void performanceIncreaseCommit3DCounter() { ++_PerformanceCommit3DCounter; } @@ -172,16 +167,6 @@ public: virtual void startBench(); virtual void endBench(); virtual void displayBench(NLMISC::CLog *log); - - /// Create a music channel, destroy with destroyMusicChannel. - virtual IMusicChannel *createMusicChannel(); - - /** Get music info. Returns false if the song is not found or the function is not implemented. - * \param filepath path to file, CPath::lookup done by driver - * \param artist returns the song artist (empty if not available) - * \param title returns the title (empty if not available) - */ - virtual bool getMusicInfo(const std::string &filepath, std::string &artist, std::string &title); /// Get audio/container extensions that are supported natively by the driver implementation. virtual void getMusicExtensions(std::vector & /* extensions */) const { } @@ -192,8 +177,6 @@ public: void removeBuffer(CBufferXAudio2 *buffer); /// (Internal) Remove a source (should be called by the destructor of the source class). void removeSource(CSourceXAudio2 *source); - /// (Internal) Remove a source (should be called by the destructor of the music channel class). - void removeMusicChannel(CMusicChannelXAudio2 *musicChannel); /// (Internal) Remove the listener (should be called by the destructor of the listener class) inline void removeListener(CListenerXAudio2 *listener) { nlassert(_Listener == listener); _Listener = NULL; } /// (Internal) Remove an effect (should be called by the destructor of the effect class) diff --git a/code/nel/src/sound/driver/xaudio2/source_xaudio2.cpp b/code/nel/src/sound/driver/xaudio2/source_xaudio2.cpp index 9c34beaf8..318a65a1a 100644 --- a/code/nel/src/sound/driver/xaudio2/source_xaudio2.cpp +++ b/code/nel/src/sound/driver/xaudio2/source_xaudio2.cpp @@ -42,7 +42,7 @@ _DirectFilterPassGain(NLSOUND_DEFAULT_FILTER_PASS_GAIN), _EffectFilterPassGain(N _DirectFilterLowFrequency(NLSOUND_DEFAULT_FILTER_PASS_LF), _DirectFilterHighFrequency(NLSOUND_DEFAULT_FILTER_PASS_HF), _EffectFilterLowFrequency(NLSOUND_DEFAULT_FILTER_PASS_LF), _EffectFilterHighFrequency(NLSOUND_DEFAULT_FILTER_PASS_HF), _IsPlaying(false), _IsPaused(false), _IsLooping(false), _Pitch(1.0f), -_Gain(1.0f), _MinDistance(1.0f), _MaxDistance(numeric_limits::max()), +_Gain(1.0f), _MinDistance(1.0f), _MaxDistance(sqrt(numeric_limits::max())), _AdpcmUtility(NULL), _Channels(0), _BitsPerSample(0), _BufferStreaming(false) { // nlwarning(NLSOUND_XAUDIO2_PREFIX "Inititializing CSourceXAudio2"); @@ -121,8 +121,7 @@ void CSourceXAudio2::commit3DChanges() { nlassert(_SourceVoice); - // Only mono buffers get 3d sound, multi-channel buffers go directly to the speakers (calculate rolloff too!!). - // Todo: stereo buffers calculate distance ? + // Only mono buffers get 3d sound, multi-channel buffers go directly to the speakers without any distance rolloff. if (_Channels > 1) { // _SoundDriver->getDSPSettings()->DstChannelCount = 1; @@ -494,8 +493,10 @@ bool CSourceXAudio2::initFormat(IBuffer::TBufferFormat bufferFormat, uint8 chann _SourceVoice->SetVolume(_Gain, _OperationSet); setupVoiceSends(); _SoundDriver->getXAudio2()->CommitChanges(_OperationSet); - - + + // Also commit any 3D settings that were already done + commit3DChanges(); + // test //XAUDIO2_VOICE_DETAILS voice_details; //_SourceVoice->GetVoiceDetails(&voice_details); @@ -535,7 +536,7 @@ bool CSourceXAudio2::preparePlay(IBuffer::TBufferFormat bufferFormat, uint8 chan // destroy adpcm utility (if it exists) delete _AdpcmUtility; _AdpcmUtility = NULL; // reset current stuff - _Format = (IBuffer::TBufferFormat)~0; + _Format = IBuffer::FormatNotSet; _Channels = 0; _BitsPerSample = 0; } @@ -582,6 +583,11 @@ bool CSourceXAudio2::play() { // nldebug(NLSOUND_XAUDIO2_PREFIX "play"); + // Commit 3D changes before starting play + if (_SourceVoice) + commit3DChanges(); + // else it is commit by the preparePlay > initFormat function + if (_IsPaused) { if (SUCCEEDED(_SourceVoice->Start(0))) _IsPaused = false; @@ -793,7 +799,14 @@ bool CSourceXAudio2::getSourceRelativeMode() const void CSourceXAudio2::setMinMaxDistances(float mindist, float maxdist, bool /* deferred */) { // nldebug(NLSOUND_XAUDIO2_PREFIX "setMinMaxDistances %f, %f", mindist, maxdist); - + + static float maxSqrt = sqrt(std::numeric_limits::max()); + if (maxdist >= maxSqrt) + { + nlwarning("SOUND_DEV (XAudio2): Ridiculously high max distance set on source"); + maxdist = maxSqrt; + } + _Emitter.InnerRadius = mindist; _MinDistance = mindist; _MaxDistance = maxdist; diff --git a/code/nel/src/sound/driver/xaudio2/stdxaudio2.h b/code/nel/src/sound/driver/xaudio2/stdxaudio2.h index c043f3949..1a1d766e7 100644 --- a/code/nel/src/sound/driver/xaudio2/stdxaudio2.h +++ b/code/nel/src/sound/driver/xaudio2/stdxaudio2.h @@ -57,7 +57,6 @@ #include "nel/sound/driver/listener.h" #include "nel/sound/driver/sound_driver.h" #include "nel/sound/driver/source.h" -#include "nel/sound/driver/music_buffer.h" // Defines #define NLSOUND_XAUDIO2_NAME "NeLSound XAudio2 Driver" diff --git a/code/nel/src/sound/group_controller.cpp b/code/nel/src/sound/group_controller.cpp new file mode 100644 index 000000000..d01e29252 --- /dev/null +++ b/code/nel/src/sound/group_controller.cpp @@ -0,0 +1,129 @@ +/** + * \file group_controller.cpp + * \brief CGroupController + * \date 2012-04-10 09:29GMT + * \author Jan Boon (Kaetemi) + * CGroupController + */ + +/* + * Copyright (C) 2012 by authors + * + * This file is part of RYZOM CORE. + * RYZOM CORE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * RYZOM CORE 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with RYZOM CORE. If not, see + * . + */ + +#include "stdsound.h" +#include + +// STL includes + +// NeL includes +// #include +#include + +// Project includes + +using namespace std; +// using namespace NLMISC; + +namespace NLSOUND { + +CGroupController::CGroupController(CGroupController *parent) : + m_Parent(parent), m_Gain(1.0f), m_NbSourcesInclChild(0) +{ + +} + +CGroupController::~CGroupController() +{ + // If m_Sources is not empty, a crash is very likely. + nlassert(m_Sources.empty()); + + for (std::map::iterator it(m_Children.begin()), end(m_Children.end()); it != end; ++it) + { + delete it->second; + it->second = NULL; + } + m_Parent = NULL; +} + +void CGroupController::addSource(CSourceCommon *source) +{ + nlassert(this); + + m_Sources.insert(source); + increaseSources(); +} + +void CGroupController::removeSource(CSourceCommon *source) +{ + decreaseSources(); + m_Sources.erase(source); +} + +std::string CGroupController::getPath() // overridden by root +{ + for (std::map::iterator it(m_Parent->m_Children.begin()), end(m_Parent->m_Children.end()); it != end; ++it) + { + if (it->second == this) + { + const std::string &name = it->first; + std::string returnPath = m_Parent->getPath() + ":" + name; + return returnPath; + } + } + nlerror("Group Controller not child of parent"); + return ""; +} + +void CGroupController::calculateFinalGain() // overridden by root +{ + m_FinalGain = calculateTotalGain() * m_Parent->getFinalGain(); +} + +void CGroupController::updateSourceGain() +{ + // Dont update source gain when this controller is inactive. + if (m_NbSourcesInclChild) + { + calculateFinalGain(); + for (TSourceContainer::iterator it(m_Sources.begin()), end(m_Sources.end()); it != end; ++it) + (*it)->updateFinalGain(); + for (std::map::iterator it(m_Children.begin()), end(m_Children.end()); it != end; ++it) + (*it).second->updateSourceGain(); + } +} + +void CGroupController::increaseSources() // overridden by root +{ + ++m_NbSourcesInclChild; + m_Parent->increaseSources(); + + // Update source gain when this controller was inactive before but the parent was active before. + // Thus, when this controller was the root of inactive controllers. + if (m_NbSourcesInclChild == 1 && m_Parent->m_NbSourcesInclChild > 1) + updateSourceGain(); +} + +void CGroupController::decreaseSources() // overridden by root +{ + --m_NbSourcesInclChild; + m_Parent->decreaseSources(); +} + +} /* namespace NLSOUND */ + +/* end of file */ diff --git a/code/nel/src/sound/group_controller_root.cpp b/code/nel/src/sound/group_controller_root.cpp new file mode 100644 index 000000000..0f1c58e63 --- /dev/null +++ b/code/nel/src/sound/group_controller_root.cpp @@ -0,0 +1,127 @@ +/** + * \file group_controller_root.cpp + * \brief CGroupControllerRoot + * \date 2012-04-10 09:44GMT + * \author Jan Boon (Kaetemi) + * CGroupControllerRoot + */ + +/* + * Copyright (C) 2012 by authors + * + * This file is part of RYZOM CORE. + * RYZOM CORE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * RYZOM CORE 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with RYZOM CORE. If not, see + * . + */ + +#include "stdsound.h" +#include + +// STL includes + +// NeL includes +// #include +#include + +// Project includes + +using namespace std; +// using namespace NLMISC; + +#define NLSOUND_GROUP_CONTROLLER_ROOT_PATH "sound" + +namespace NLSOUND { + +CGroupControllerRoot::CGroupControllerRoot() : CGroupController(NULL) +{ + +} + +CGroupControllerRoot::~CGroupControllerRoot() +{ + +} + +std::string CGroupControllerRoot::getPath() +{ + // The root node is always called sound + return NLSOUND_GROUP_CONTROLLER_ROOT_PATH; +} + +void CGroupControllerRoot::calculateFinalGain() +{ + m_FinalGain = calculateTotalGain(); +} + +void CGroupControllerRoot::increaseSources() +{ + ++m_NbSourcesInclChild; + + // Update source gain when this controller was inactive before. + if (m_NbSourcesInclChild == 1) + updateSourceGain(); +} + +void CGroupControllerRoot::decreaseSources() +{ + --m_NbSourcesInclChild; +} + +bool CGroupControllerRoot::isReservedName(const std::string &nodeName) +{ + // These node names are reserved, in case these category controllers can be integrated with CDB. + // I do not forsee any functionality for changing environment effect settings for entire categories. + // The nodeName parameter is already lowercase, see CGroupControllerRoot::getGroupController. + if (nodeName == NLSOUND_GROUP_CONTROLLER_ROOT_PATH) return true; // Root node name can only used by root. + if (nodeName == "gain") return true; + if (nodeName == "pitch") return true; + if (nodeName == "enable" || nodeName == "enabled") return true; + return false; +} + +CGroupController *CGroupControllerRoot::getGroupController(const std::string &path) +{ + std::vector pathNodes; + NLMISC::splitString(NLMISC::toLower(path), ":", pathNodes); + CGroupController *active = this; + if (pathNodes[0] != NLSOUND_GROUP_CONTROLLER_ROOT_PATH) + { + nlerror("Root node for group controller must always be 'sound', invalid group '%s' requested", path.c_str()); + } + for (std::vector::iterator it(pathNodes.begin() + 1), end(pathNodes.end()); it != end; ++it) + { + if (!(*it).empty()) + { + if (isReservedName(*it)) + { + nlerror("Attempt to use reserved node name '%s' in group controller path '%s'", (*it).c_str(), path.c_str()); + } + std::map::iterator found = active->m_Children.find(*it); + if (found == active->m_Children.end()) + { + active = new CGroupController(active); + active->m_Parent->m_Children[*it] = active; + } + else + { + active = (*found).second; + } + } + } + return active; +} + +} /* namespace NLSOUND */ + +/* end of file */ diff --git a/code/nel/src/sound/music_channel_fader.cpp b/code/nel/src/sound/music_channel_fader.cpp index ced739093..2fe9fb13c 100644 --- a/code/nel/src/sound/music_channel_fader.cpp +++ b/code/nel/src/sound/music_channel_fader.cpp @@ -20,6 +20,7 @@ // Project includes #include "nel/sound/driver/sound_driver.h" #include "nel/sound/driver/music_channel.h" +#include "nel/sound/source_music_channel.h" using namespace std; using namespace NLMISC; @@ -49,9 +50,16 @@ void CMusicChannelFader::init(ISoundDriver *soundDriver) _MusicFader[i].MusicChannel = _SoundDriver->createMusicChannel(); if (!_MusicFader[i].MusicChannel) { - release(); - nlwarning("No music channel available!"); - return; + if (_SoundDriver->getOption(ISoundDriver::OptionHasBufferStreaming)) + { + _MusicFader[i].MusicChannel = new CSourceMusicChannel(); + } + else + { + release(); + nlwarning("No music channel available!"); + return; + } } } } @@ -69,6 +77,15 @@ void CMusicChannelFader::release() } } +void CMusicChannelFader::reset() +{ + for (uint i = 0; i < _MaxMusicFader; ++i) if (_MusicFader[i].MusicChannel) + { + if (_MusicFader[i].MusicChannel) + _MusicFader[i].MusicChannel->reset(); + } +} + void CMusicChannelFader::update() { TTime current_time = CTime::getLocalTime(); diff --git a/code/nel/src/sound/music_sound.cpp b/code/nel/src/sound/music_sound.cpp index 2b192c3c6..803103dd9 100644 --- a/code/nel/src/sound/music_sound.cpp +++ b/code/nel/src/sound/music_sound.cpp @@ -20,6 +20,9 @@ #include "nel/misc/path.h" #include "nel/georges/u_form_elm.h" +#if NLSOUND_SHEET_VERSION_BUILT < 2 +# include "nel/sound/group_controller_root.h" +#endif using namespace std; using namespace NLMISC; @@ -72,6 +75,10 @@ void CMusicSound::importForm(const std::string& filename, NLGEORGES::UFormElm& root.getValueByName(_MinimumPlayTime, ".SoundType.MinimumPlayTime"); root.getValueByName(_TimeBeforeCanReplay, ".SoundType.TimeBeforeCanReplay"); +#if NLSOUND_SHEET_VERSION_BUILT < 2 + _GroupController = CGroupControllerRoot::getInstance()->getGroupController(NLSOUND_SHEET_V1_DEFAULT_SOUND_MUSIC_GROUP_CONTROLLER); +#endif + } // *************************************************************************** @@ -97,6 +104,11 @@ void CMusicSound::serial(NLMISC::IStream &s) CStringMapper::serialString(s, _FileName); s.serial(_FadeInLength, _FadeOutLength); s.serial(_MinimumPlayTime, _TimeBeforeCanReplay); + +#if NLSOUND_SHEET_VERSION_BUILT < 2 + if (s.isReading()) _GroupController = CGroupControllerRoot::getInstance()->getGroupController(NLSOUND_SHEET_V1_DEFAULT_SOUND_MUSIC_GROUP_CONTROLLER); +#endif + } // *************************************************************************** diff --git a/code/nel/src/sound/music_source.cpp b/code/nel/src/sound/music_source.cpp index a47914dde..e5595d9f4 100644 --- a/code/nel/src/sound/music_source.cpp +++ b/code/nel/src/sound/music_source.cpp @@ -26,8 +26,8 @@ namespace NLSOUND { // *************************************************************************** -CMusicSource::CMusicSource(CMusicSound *musicSound, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster) - : CSourceCommon(musicSound, spawn, cb, cbUserParam, cluster) +CMusicSource::CMusicSource(CMusicSound *musicSound, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster, CGroupController *groupController) + : CSourceCommon(musicSound, spawn, cb, cbUserParam, cluster, groupController) { _MusicSound= musicSound; } diff --git a/code/nel/src/sound/simple_source.cpp b/code/nel/src/sound/simple_source.cpp index fb0b7bc85..cce62cffd 100644 --- a/code/nel/src/sound/simple_source.cpp +++ b/code/nel/src/sound/simple_source.cpp @@ -28,11 +28,12 @@ using namespace NLMISC; namespace NLSOUND { -CSimpleSource::CSimpleSource(CSimpleSound *simpleSound, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster) - : CSourceCommon(simpleSound, spawn, cb, cbUserParam, cluster), +CSimpleSource::CSimpleSource(CSimpleSound *simpleSound, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster, CGroupController *groupController) + : CSourceCommon(simpleSound, spawn, cb, cbUserParam, cluster, groupController), _SimpleSound(simpleSound), _Track(NULL), - _PlayMuted(false) + _PlayMuted(false), + _WaitingForPlay(false) { nlassert(_SimpleSound != 0); @@ -133,6 +134,7 @@ void CSimpleSource::play() || (_RelativeMode ? getPos().sqrnorm() : (mixer->getListenPosVector() - getPos()).sqrnorm()) > _SimpleSound->getMaxDistance() * _SimpleSound->getMaxDistance()) { // The sample buffer is not available, don't play (we don't know the length) + _WaitingForPlay = false; if (_Spawn) { if (_SpawnEndCb != 0) @@ -166,7 +168,7 @@ void CSimpleSource::play() setDirection(_Direction); // because there is a workaround inside pSource->setVelocity(_Velocity); } - pSource->setGain(_Gain); + pSource->setGain(getFinalGain()); pSource->setSourceRelativeMode(_RelativeMode); pSource->setLooping(_Looping); pSource->setPitch(_Pitch); @@ -174,7 +176,14 @@ void CSimpleSource::play() // and play the sound bool play = pSource->play(); + +#ifdef NL_DEBUG nlassert(play); +#else + if (!play) + nlwarning("Failed to play physical sound source. This is a serious error"); +#endif + // nldebug("CSimpleSource %p : REAL play done", (CAudioMixerUser::IMixerEvent*)this); } else @@ -183,6 +192,7 @@ void CSimpleSource::play() { // This sound is not discardable, add it in waiting playlist mixer->addSourceWaitingForPlay(this); + _WaitingForPlay = true; return; } // there is no available track, just do a 'muted' play @@ -193,6 +203,7 @@ void CSimpleSource::play() } CSourceCommon::play(); + _WaitingForPlay = false; } /// Mixer event call when doing muted play @@ -219,6 +230,13 @@ void CSimpleSource::stop() // nldebug("CSimpleSource %p : stop", (CAudioMixerUser::IMixerEvent*)this); // nlassert(_Playing); + if (_WaitingForPlay) + { + nlassert(!_Playing); // cannot already be playing if waiting for play + CAudioMixerUser *mixer = CAudioMixerUser::instance(); + mixer->removeSourceWaitingForPlay(this); + } + if (!_Playing) return; @@ -312,36 +330,13 @@ void CSimpleSource::setDirection(const NLMISC::CVector& dir) } } - -/* Set the gain (volume value inside [0 , 1]). (default: 1) - * 0.0 -> silence - * 0.5 -> -6dB - * 1.0 -> no attenuation - * values > 1 (amplification) not supported by most drivers - */ -void CSimpleSource::setGain(float gain) +void CSimpleSource::updateFinalGain() { - CSourceCommon::setGain(gain); - // Set the gain if (hasPhysicalSource()) - { - getPhysicalSource()->setGain(gain); - } + getPhysicalSource()->setGain(getFinalGain()); } -void CSimpleSource::setRelativeGain(float gain) -{ - CSourceCommon::setRelativeGain(gain); - - // Set the gain - if (hasPhysicalSource()) - { - getPhysicalSource()->setGain(_Gain); - } -} - - /* Shift the frequency. 1.0f equals identity, each reduction of 50% equals a pitch shift * of one octave. 0 is not a legal value. */ diff --git a/code/nel/src/sound/sound.cpp b/code/nel/src/sound/sound.cpp index eed318cca..b1b644ed2 100644 --- a/code/nel/src/sound/sound.cpp +++ b/code/nel/src/sound/sound.cpp @@ -26,6 +26,10 @@ #include "nel/sound/context_sound.h" #include "nel/sound/music_sound.h" #include "nel/sound/stream_sound.h" +#include "nel/sound/stream_file_sound.h" + +#include "nel/sound/group_controller.h" +#include "nel/sound/group_controller_root.h" using namespace std; using namespace NLMISC; @@ -81,6 +85,11 @@ CSound *CSound::createSound(const std::string &filename, NLGEORGES::UFormElm& fo ret = new CStreamSound(); ret->importForm(filename, formRoot); } + else if (dfnName == "stream_file_sound.dfn") + { + ret = new CStreamFileSound(); + ret->importForm(filename, formRoot); + } else { nlassertex(false, ("SoundType unsuported : %s", dfnName.c_str())); @@ -106,7 +115,8 @@ CSound::CSound() : _Looping(false), _MinDist(1.0f), _MaxDist(1000000.0f), - _UserVarControler(CStringMapper::emptyId()) + _UserVarControler(CStringMapper::emptyId()), + _GroupController(NULL) { } @@ -134,6 +144,23 @@ void CSound::serial(NLMISC::IStream &s) std::string name = CStringMapper::unmap(_Name); s.serial(name); } + + nlassert(CGroupControllerRoot::getInstance()); // not sure +#if NLSOUND_SHEET_VERSION_BUILT < 2 + if (s.isReading()) _GroupController = static_cast(CAudioMixerUser::instance()->getGroupController(NLSOUND_SHEET_V1_DEFAULT_SOUND_GROUP_CONTROLLER)); +#else + if (s.isReading()) + { + std::string groupControllerPath; + s.serial(groupControllerPath); + _GroupController = static_cast(CAudioMixerUser::instance()->getGroupController(groupControllerPath)); + } + else + { + std::string groupControllerPath = _GroupController->getPath(); + s.serial(groupControllerPath); + } +#endif } @@ -225,6 +252,16 @@ void CSound::importForm(const std::string& filename, NLGEORGES::UFormElm& roo default: _Priority = MidPri; } + + nlassert(CGroupControllerRoot::getInstance()); // not sure +#if NLSOUND_SHEET_VERSION_BUILT < 2 + _GroupController = CGroupControllerRoot::getInstance()->getGroupController(NLSOUND_SHEET_V1_DEFAULT_SOUND_GROUP_CONTROLLER); +#else + std::string groupControllerPath; + root.getValueByName(groupControllerPath, ".GroupControllerPath"); + _GroupController = CGroupControllerRoot::getInstance()->getGroupController(groupControllerPath); +#endif + } diff --git a/code/nel/src/sound/sound_bank.cpp b/code/nel/src/sound/sound_bank.cpp index b4031b571..dd2076a72 100644 --- a/code/nel/src/sound/sound_bank.cpp +++ b/code/nel/src/sound/sound_bank.cpp @@ -23,6 +23,7 @@ #include "nel/sound/background_sound.h" #include "nel/sound/music_sound.h" #include "nel/sound/stream_sound.h" +#include "nel/sound/stream_file_sound.h" #include "nel/georges/u_form_loader.h" #include "nel/georges/u_form_elm.h" @@ -194,6 +195,9 @@ public: case CSound::SOUND_STREAM: Sound = new CStreamSound(); break; + case CSound::SOUND_STREAM_FILE: + Sound = new CStreamFileSound(); + break; default: Sound = 0; } diff --git a/code/nel/src/sound/source_common.cpp b/code/nel/src/sound/source_common.cpp index ce2b7e210..7b27deb03 100644 --- a/code/nel/src/sound/source_common.cpp +++ b/code/nel/src/sound/source_common.cpp @@ -25,7 +25,7 @@ using namespace NLMISC; namespace NLSOUND { -CSourceCommon::CSourceCommon(TSoundId id, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster) +CSourceCommon::CSourceCommon(TSoundId id, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster, CGroupController *groupController) : _Priority(MidPri), _Playing(false), _Looping(false), @@ -41,9 +41,11 @@ CSourceCommon::CSourceCommon(TSoundId id, bool spawn, TSpawnEndCallback cb, void _SpawnEndCb(cb), _CbUserParam(cbUserParam), _Cluster(cluster), - _UserVarControler(id->getUserVarControler()) + _UserVarControler(id->getUserVarControler()), + _GroupController(groupController ? groupController : id->getGroupController()) { CAudioMixerUser::instance()->addSource(this); + _GroupController->addSource(this); // get a local copy of the sound parameter _InitialGain = _Gain = id->getGain(); @@ -51,11 +53,11 @@ CSourceCommon::CSourceCommon(TSoundId id, bool spawn, TSpawnEndCallback cb, void _Looping = id->getLooping(); _Priority = id->getPriority(); _Direction = id->getDirectionVector(); - } CSourceCommon::~CSourceCommon() { + _GroupController->removeSource(this); CAudioMixerUser::instance()->removeSource(this); } @@ -177,6 +179,7 @@ void CSourceCommon::setGain( float gain ) { clamp(gain, 0.0f, 1.0f); _InitialGain = _Gain = gain; + updateFinalGain(); } /* Set the gain amount (value inside [0, 1]) to map between 0 and the nominal gain @@ -185,8 +188,8 @@ void CSourceCommon::setGain( float gain ) void CSourceCommon::setRelativeGain( float gain ) { clamp(gain, 0.0f, 1.0f); - _Gain = _InitialGain * gain; + updateFinalGain(); } /* diff --git a/code/nel/src/sound/source_music_channel.cpp b/code/nel/src/sound/source_music_channel.cpp new file mode 100644 index 000000000..34735f113 --- /dev/null +++ b/code/nel/src/sound/source_music_channel.cpp @@ -0,0 +1,140 @@ +/** + * \file source_music_channel.cpp + * \brief CSourceMusicChannel + * \date 2012-04-11 16:08GMT + * \author Jan Boon (Kaetemi) + * CSourceMusicChannel + */ + +/* + * Copyright (C) 2012 by authors + * + * This file is part of RYZOM CORE. + * RYZOM CORE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * RYZOM CORE 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with RYZOM CORE. If not, see + * . + */ + +#include "stdsound.h" +#include + +// STL includes + +// NeL includes +// #include +#include + +// Project includes + +using namespace std; +// using namespace NLMISC; + +namespace NLSOUND { + +CSourceMusicChannel::CSourceMusicChannel() : m_Source(NULL), m_Gain(1.0f) +{ + +} + +CSourceMusicChannel::~CSourceMusicChannel() +{ + nlassert(!m_Source); + delete m_Source; + m_Source = NULL; +} + +bool CSourceMusicChannel::play(const std::string &filepath, bool async, bool loop) +{ + // delete previous source if any + // note that this waits for the source's thread to finish if the source was still playing + if (m_Source) + delete m_Source; + + m_Sound.setMusicFilePath(filepath, async, loop); + + m_Source = new CStreamFileSource(&m_Sound, false, NULL, NULL, NULL, NULL); + m_Source->setSourceRelativeMode(true); + m_Source->setPos(NLMISC::CVector::Null); + m_Source->setRelativeGain(m_Gain); + + m_Source->play(); + + return m_Source->isPlaying(); +} + +void CSourceMusicChannel::stop() +{ + // stop but don't delete the source, deleting source may cause waiting for thread + if (m_Source) + m_Source->stop(); +} + +void CSourceMusicChannel::reset() +{ + // forces the source to be deleted, happens when audio mixer is reset + delete m_Source; + m_Source = NULL; +} + +void CSourceMusicChannel::pause() +{ + if (m_Source) + m_Source->pause(); +} + +void CSourceMusicChannel::resume() +{ + if (m_Source) + m_Source->resume(); +} + +bool CSourceMusicChannel::isEnded() +{ + if (m_Source) + { + if (m_Source->isEnded()) + { + // we can delete the source now without worrying about thread wait + delete m_Source; + m_Source = NULL; + return true; + } + return false; + } + return true; +} + +bool CSourceMusicChannel::isLoadingAsync() +{ + if (m_Source) + return m_Source->isLoadingAsync(); + return false; +} + +float CSourceMusicChannel::getLength() +{ + if (m_Source) + return m_Source->getLength(); + return 0.0f; +} + +void CSourceMusicChannel::setVolume(float gain) +{ + m_Gain = gain; + if (m_Source) + m_Source->setRelativeGain(gain); +} + +} /* namespace NLSOUND */ + +/* end of file */ diff --git a/code/nel/src/sound/stream_file_sound.cpp b/code/nel/src/sound/stream_file_sound.cpp new file mode 100644 index 000000000..44da5a31d --- /dev/null +++ b/code/nel/src/sound/stream_file_sound.cpp @@ -0,0 +1,98 @@ +/** + * \file stream_file_sound.cpp + * \brief CStreamFileSound + * \date 2012-04-11 09:57GMT + * \author Jan Boon (Kaetemi) + * CStreamFileSound + */ + +/* + * Copyright (C) 2012 by authors + * + * This file is part of RYZOM CORE. + * RYZOM CORE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * RYZOM CORE 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with RYZOM CORE. If not, see + * . + */ + +#include "stdsound.h" +#include + +// STL includes + +// NeL includes +// #include +#include + +// Project includes + +using namespace std; +// using namespace NLMISC; + +namespace NLSOUND { + +CStreamFileSound::CStreamFileSound() +{ + +} + +CStreamFileSound::~CStreamFileSound() +{ + +} + +void CStreamFileSound::importForm(const std::string &filename, NLGEORGES::UFormElm &root) +{ + // Call the base class + CStreamSound::importForm(filename, root); + + // Async + root.getValueByName(m_Async, ".SoundType.Async"); + + // FilePath + root.getValueByName(m_FilePath, ".SoundType.FilePath"); +} + +void CStreamFileSound::serial(NLMISC::IStream &s) +{ + CStreamSound::serial(s); + + s.serial(m_Async); + s.serial(m_FilePath); +} + +void CStreamFileSound::setMusicFilePath(const std::string &filePath, bool async, bool loop) +{ +#if !FINAL_VERSION + _Name = NLMISC::CStringMapper::map(std::string(""); +#else + _Name = NLMISC::CStringMapper::map(""); +#endif + _ConeInnerAngle = NLMISC::Pi * 2; + _ConeOuterAngle = NLMISC::Pi * 2; + _Looping = loop; + _Gain = 1.0f; + _ConeOuterGain = 1.0f; + _Direction = NLMISC::CVector(0.f, 0.f, 0.f); + _Pitch = 1.0f; + _Priority = HighestPri; + _MaxDist = 9000.0f; + _MinDist = 1000.0f; + m_Async = async; + m_FilePath = filePath; + _GroupController = CGroupControllerRoot::getInstance()->getGroupController(NLSOUND_SHEET_V1_DEFAULT_SOUND_MUSIC_GROUP_CONTROLLER); +} + +} /* namespace NLSOUND */ + +/* end of file */ diff --git a/code/nel/src/sound/stream_file_source.cpp b/code/nel/src/sound/stream_file_source.cpp new file mode 100644 index 000000000..87164a9cd --- /dev/null +++ b/code/nel/src/sound/stream_file_source.cpp @@ -0,0 +1,384 @@ +/** + * \file stream_file_source.cpp + * \brief CStreamFileSource + * \date 2012-04-11 09:57GMT + * \author Jan Boon (Kaetemi) + * CStreamFileSource + */ + +/* + * Copyright (C) 2012 by authors + * + * This file is part of RYZOM CORE. + * RYZOM CORE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * RYZOM CORE 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with RYZOM CORE. If not, see + * . + */ + +#include "stdsound.h" +#include + +// STL includes + +// NeL includes +// #include + +// Project includes +#include +#include + +using namespace std; +// using namespace NLMISC; + +// #define NLSOUND_STREAM_FILE_DEBUG + +namespace NLSOUND { + +CStreamFileSource::CStreamFileSource(CStreamFileSound *streamFileSound, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster, CGroupController *groupController) +: CStreamSource(streamFileSound, spawn, cb, cbUserParam, cluster, groupController), m_AudioDecoder(NULL), m_Paused(false) +{ + m_Thread = NLMISC::IThread::create(this); +} + +CStreamFileSource::~CStreamFileSource() +{ + stop(); + m_Thread->wait(); // thread must have stopped for delete! + delete m_Thread; + m_Thread = NULL; + delete m_AudioDecoder; + m_AudioDecoder = NULL; +} + +void CStreamFileSource::play() +{ + // note: CStreamSource will assert crash if already physically playing! + + + if (m_WaitingForPlay) + { + if (m_Thread->isRunning()) + { + if (m_NextBuffer || !m_FreeBuffers) + { +#ifdef NLSOUND_STREAM_FILE_DEBUG + nldebug("play waiting, play stream %s", getStreamFileSound()->getFilePath().c_str()); +#endif + CStreamSource::play(); + if (!_Playing && !m_WaitingForPlay) + { + nldebug("Stream file source playback not possible or necessary for some reason"); + } + } + else + { +#ifdef NLSOUND_STREAM_FILE_DEBUG + nldebug("play waiting, hop onto waiting list %s", getStreamFileSound()->getFilePath().c_str()); +#endif + m_WaitingForPlay = true; + CAudioMixerUser *mixer = CAudioMixerUser::instance(); + mixer->addSourceWaitingForPlay(this); + } + } + else + { + // thread went kaboom while not started playing yet, probably the audiodecoder cannot be started + // don't play + m_WaitingForPlay = false; + } + } + else if (!_Playing) + { +#ifdef NLSOUND_STREAM_FILE_DEBUG + nldebug("play go %s", getStreamFileSound()->getFilePath().c_str()); +#endif + //if (!m_WaitingForPlay) + //{ + // thread may be stopping from stop call + m_Thread->wait(); + //} + //else + //{ + // nlwarning("Already waiting for play"); + //} + if (!getStreamFileSound()->getAsync()) + { + if (!prepareDecoder()) + { + return; + } + } + // else load audiodecoder in thread + m_WaitingForPlay = true; + m_Thread->start(); + m_Thread->setPriority(NLMISC::ThreadPriorityHighest); + if (!getStreamFileSound()->getAsync()) + { + // wait until at least one buffer is ready + while (!(m_NextBuffer || !m_FreeBuffers) && m_WaitingForPlay && m_Thread->isRunning()) + { +#ifdef NLSOUND_STREAM_FILE_DEBUG + nldebug("wait buffer"); +#endif + NLMISC::nlSleep(100); + } + if (m_WaitingForPlay && m_Thread->isRunning()) + { + CStreamSource::play(); + if (!_Playing) + { + nlwarning("Failed to synchronously start playing a file stream source. This happens when all physical tracks are in use. Use a Highest Priority sound"); + } + } + } + else + { + CAudioMixerUser *mixer = CAudioMixerUser::instance(); + mixer->addSourceWaitingForPlay(this); + } + } + else + { + nlwarning("Already playing"); + } + + + /*if (!m_WaitingForPlay) + { + m_WaitingForPlay = true; + + m_Thread->wait(); // thread must have stopped to restart it! + + m_Thread->start(); + m_Thread->setPriority(NLMISC::ThreadPriorityHighest); + } + + CStreamSource::play();*/ +} + +void CStreamFileSource::stop() +{ +#ifdef NLSOUND_STREAM_FILE_DEBUG + nldebug("stop %s", getStreamFileSound()->getFilePath().c_str()); +#endif + + CStreamSource::stopInt(); + +#ifdef NLSOUND_STREAM_FILE_DEBUG + nldebug("stopInt ok"); +#endif + + if (_Spawn) + { + if (_SpawnEndCb != NULL) + _SpawnEndCb(this, _CbUserParam); + m_Thread->wait(); + delete this; + } + +#ifdef NLSOUND_STREAM_FILE_DEBUG + nldebug("stop ok"); +#endif + + // thread will check _Playing to stop +} + +bool CStreamFileSource::isPlaying() +{ +#ifdef NLSOUND_STREAM_FILE_DEBUG + nldebug("isPlaying"); +#endif + + return m_Thread->isRunning(); +} + +void CStreamFileSource::pause() +{ +#ifdef NLSOUND_STREAM_FILE_DEBUG + nldebug("pause"); +#endif + + if (!m_Paused) + { + // thread checks for this to not delete the audio decoder + m_Paused = true; + + // stop the underlying system + CStreamSource::stop(); + + // thread will check _Playing to stop + } + else + { + nlwarning("Already paused"); + } +} + +void CStreamFileSource::resume() +{ +#ifdef NLSOUND_STREAM_FILE_DEBUG + nldebug("resume"); +#endif + + if (m_Paused) + { + m_Thread->wait(); // thread must have stopped to restart it! + + play(); + } + else + { + nlwarning("Not paused"); + } +} + +bool CStreamFileSource::isEnded() +{ + return (!m_Thread->isRunning() && !_Playing && !m_WaitingForPlay && !m_Paused); +} + +float CStreamFileSource::getLength() +{ + return m_AudioDecoder->getLength(); +} + +bool CStreamFileSource::isLoadingAsync() +{ + return m_WaitingForPlay; +} + +bool CStreamFileSource::prepareDecoder() +{ + // creates a new decoder or keeps going with the current decoder if the stream was paused + + if (m_Paused) + { + // handle paused! + m_Paused = false; + } + else if (m_AudioDecoder) // audio decoder should normally not exist when not paused and starting the thread + { + nlwarning("CAudioDecoder already exists, possible thread race bug with pause"); + delete m_AudioDecoder; + m_AudioDecoder = NULL; + } + if (!m_AudioDecoder) + { + // load the file + m_AudioDecoder = IAudioDecoder::createAudioDecoder(getStreamFileSound()->getFilePath(), getStreamFileSound()->getAsync(), getStreamFileSound()->getLooping()); + if (!m_AudioDecoder) + { + nlwarning("Failed to create IAudioDecoder, likely invalid format"); + return false; + } + this->setFormat(m_AudioDecoder->getChannels(), m_AudioDecoder->getBitsPerSample(), (uint32)m_AudioDecoder->getSamplesPerSec()); + } + uint samples, bytes; + this->getRecommendedBufferSize(samples, bytes); + this->preAllocate(bytes * 2); + + return true; +} + +inline bool CStreamFileSource::bufferMore(uint bytes) // buffer from bytes (minimum) to bytes * 2 (maximum) +{ + uint8 *buffer = this->lock(bytes * 2); + if (buffer) + { + uint32 result = m_AudioDecoder->getNextBytes(buffer, bytes, bytes * 2); + this->unlock(result); + return true; + } + return false; +} + +void CStreamFileSource::run() +{ +#ifdef NLSOUND_STREAM_FILE_DEBUG + nldebug("run %s", getStreamFileSound()->getFilePath().c_str()); + uint dumpI = 0; +#endif + + bool looping = _Looping; + if (getStreamFileSound()->getAsync()) + { + if (!prepareDecoder()) + return; + } + uint samples, bytes; + this->getRecommendedBufferSize(samples, bytes); + uint32 recSleep = 40; + uint32 doSleep = 10; + while (_Playing || m_WaitingForPlay) + { + if (!m_AudioDecoder->isMusicEnded()) + { +#ifdef NLSOUND_STREAM_FILE_DEBUG + ++dumpI; + if (!(dumpI % 100)) + { + nldebug("buffer %s %s %s", _Playing ? "PLAYING" : "NP", m_WaitingForPlay ? "WAITING" : "NW", getStreamFileSound()->getFilePath().c_str()); + nldebug("gain %f", hasPhysicalSource() ? getPhysicalSource()->getGain() : -1.0f); + } +#endif + + bool newLooping = _Looping; + if (looping != newLooping) + { + m_AudioDecoder->setLooping(looping); + looping = newLooping; + } + + // reduce sleeping time if nothing was buffered + if (bufferMore(bytes)) recSleep = doSleep = this->getRecommendedSleepTime(); + else doSleep = recSleep >> 2; // /4 + NLMISC::nlSleep(doSleep); + } + else + { + // wait until done playing buffers + while (this->hasFilledBuffersAvailable() && (_Playing || m_WaitingForPlay)) + { +#ifdef NLSOUND_STREAM_FILE_DEBUG + nldebug("music ended, wait until done %s", getStreamFileSound()->getFilePath().c_str()); +#endif + NLMISC::nlSleep(40); + } + // stop the physical source + // if (hasPhysicalSource()) + // getPhysicalSource()->stop(); + // the audio mixer will call stop on the logical source + break; + } + } + if (m_Paused) + { + // don't delete anything + } + else + { + delete m_AudioDecoder; + m_AudioDecoder = NULL; + } + // drop buffers + m_FreeBuffers = 3; + m_NextBuffer = 0; + +#ifdef NLSOUND_STREAM_FILE_DEBUG + nldebug("run end %s", getStreamFileSound()->getFilePath().c_str()); +#endif +} + +} /* namespace NLSOUND */ + +/* end of file */ diff --git a/code/nel/src/sound/stream_sound.cpp b/code/nel/src/sound/stream_sound.cpp index 347fae987..e16158d4d 100644 --- a/code/nel/src/sound/stream_sound.cpp +++ b/code/nel/src/sound/stream_sound.cpp @@ -17,6 +17,10 @@ #include "stdsound.h" #include "nel/sound/stream_sound.h" +#if NLSOUND_SHEET_VERSION_BUILT < 2 +# include "nel/sound/group_controller_root.h" +#endif + namespace NLSOUND { CStreamSound::CStreamSound() @@ -31,14 +35,15 @@ CStreamSound::~CStreamSound() void CStreamSound::importForm(const std::string &filename, NLGEORGES::UFormElm &root) { - NLGEORGES::UFormElm *psoundType; + // cannot do this debug check because used also by CStreamFileSound + /*NLGEORGES::UFormElm *psoundType; std::string dfnName; // some basic checking. root.getNodeByName(&psoundType, ".SoundType"); nlassert(psoundType != NULL); psoundType->getDfnName(dfnName); - nlassert(dfnName == "stream_sound.dfn"); + nlassert(dfnName == "stream_sound.dfn");*/ // Call the base class CSound::importForm(filename, root); @@ -51,6 +56,11 @@ void CStreamSound::importForm(const std::string &filename, NLGEORGES::UFormElm & // Alpha root.getValueByName(m_Alpha, ".SoundType.Alpha"); + +#if NLSOUND_SHEET_VERSION_BUILT < 2 + _GroupController = CGroupControllerRoot::getInstance()->getGroupController(NLSOUND_SHEET_V1_DEFAULT_SOUND_STREAM_GROUP_CONTROLLER); +#endif + } void CStreamSound::serial(NLMISC::IStream &s) @@ -59,6 +69,11 @@ void CStreamSound::serial(NLMISC::IStream &s) s.serial(_MinDist); s.serial(m_Alpha); + +#if NLSOUND_SHEET_VERSION_BUILT < 2 + if (s.isReading()) _GroupController = CGroupControllerRoot::getInstance()->getGroupController(NLSOUND_SHEET_V1_DEFAULT_SOUND_STREAM_GROUP_CONTROLLER); +#endif + } } /* namespace NLSOUND */ diff --git a/code/nel/src/sound/stream_source.cpp b/code/nel/src/sound/stream_source.cpp index a5b167c8f..221b0529e 100644 --- a/code/nel/src/sound/stream_source.cpp +++ b/code/nel/src/sound/stream_source.cpp @@ -26,29 +26,37 @@ // using namespace std; using namespace NLMISC; +// #define NLSOUND_DEBUG_STREAM + namespace NLSOUND { -CStreamSource::CStreamSource(CStreamSound *streamSound, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster) - : CSourceCommon(streamSound, spawn, cb, cbUserParam, cluster), +CStreamSource::CStreamSource(CStreamSound *streamSound, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster, CGroupController *groupController) + : CSourceCommon(streamSound, spawn, cb, cbUserParam, cluster, groupController), m_StreamSound(streamSound), m_Alpha(0.0f), m_Track(NULL), m_FreeBuffers(3), m_NextBuffer(0), m_LastSize(0), - m_BytesPerSecond(0) + m_BytesPerSecond(0), + m_WaitingForPlay(false), + m_PitchInv(1.0f) { nlassert(m_StreamSound != 0); // get a local copy of the stream sound parameter m_Alpha = m_StreamSound->getAlpha();//m_Buffers + m_PitchInv = 1.0f / _Pitch; // create the three buffer objects CAudioMixerUser *mixer = CAudioMixerUser::instance(); ISoundDriver *driver = mixer->getSoundDriver(); m_Buffers[0] = driver->createBuffer(); + m_Buffers[0]->setStorageMode(IBuffer::StorageSoftware); m_Buffers[1] = driver->createBuffer(); + m_Buffers[1]->setStorageMode(IBuffer::StorageSoftware); m_Buffers[2] = driver->createBuffer(); + m_Buffers[2]->setStorageMode(IBuffer::StorageSoftware); } CStreamSource::~CStreamSource() @@ -107,6 +115,8 @@ bool CStreamSource::isPlaying() /// Set looping on/off for future playbacks (default: off) void CStreamSource::setLooping(bool l) { + CSourceCommon::setLooping(l); + //CAutoMutex autoMutex(m_BufferMutex); // //CSourceCommon::setLooping(l); @@ -146,13 +156,16 @@ void CStreamSource::play() if ((_RelativeMode ? getPos().sqrnorm() : (mixer->getListenPosVector() - getPos()).sqrnorm()) > m_StreamSound->getMaxDistance() * m_StreamSound->getMaxDistance()) { // Source is too far to play + m_WaitingForPlay = false; if (_Spawn) { if (_SpawnEndCb != NULL) _SpawnEndCb(this, _CbUserParam); delete this; } - // nldebug("CStreamSource %p : play FAILED !", (CAudioMixerUser::IMixerEvent*)this); +#ifdef NLSOUND_DEBUG_STREAM + nldebug("CStreamSource %p : play FAILED, source is too far away !", (CAudioMixerUser::IMixerEvent*)this); +#endif return; } @@ -166,24 +179,33 @@ void CStreamSource::play() ISource *pSource = getPhysicalSource(); nlassert(pSource != NULL); - for (uint i = 0; i < m_NextBuffer; ++i) + uint nbS = m_NextBuffer; + if (!m_NextBuffer && !m_FreeBuffers) nbS = 3; + for (uint i = 0; i < nbS; ++i) pSource->submitStreamingBuffer(m_Buffers[i]); // pSource->setPos( _Position, false); pSource->setPos(getVirtualPos(), false); + pSource->setMinMaxDistances(m_StreamSound->getMinDistance(), m_StreamSound->getMaxDistance(), false); if (!m_Buffers[0]->isStereo()) { - pSource->setMinMaxDistances(m_StreamSound->getMinDistance(), m_StreamSound->getMaxDistance(), false); setDirection(_Direction); // because there is a workaround inside pSource->setVelocity(_Velocity); } - pSource->setGain(_Gain); + else + { + pSource->setDirection(NLMISC::CVector::I); + pSource->setCone(float(Pi * 2), float(Pi * 2), 1.0f); + pSource->setVelocity(NLMISC::CVector::Null); + } + pSource->setGain(getFinalGain()); pSource->setSourceRelativeMode(_RelativeMode); // pSource->setLooping(_Looping); pSource->setPitch(_Pitch); pSource->setAlpha(m_Alpha); // and play the sound + nlassert(nbS); // must have buffered already! play = pSource->play(); // nldebug("CStreamSource %p : REAL play done", (CAudioMixerUser::IMixerEvent*)this); } @@ -193,11 +215,13 @@ void CStreamSource::play() { // This sound is not discardable, add it in waiting playlist mixer->addSourceWaitingForPlay(this); + m_WaitingForPlay = true; return; } else { // No source available, kill. + m_WaitingForPlay = false; if (_Spawn) { if (_SpawnEndCb != NULL) @@ -209,22 +233,67 @@ void CStreamSource::play() } if (play) + { CSourceCommon::play(); + m_WaitingForPlay = false; +#ifdef NLSOUND_DEBUG_STREAM + // Dump source info + nlwarning("--- DUMP SOURCE INFO ---"); + nlwarning(" * getLooping: %s", getPhysicalSource()->getLooping() ? "YES" : "NO"); + nlwarning(" * isPlaying: %s", getPhysicalSource()->isPlaying() ? "YES" : "NO"); + nlwarning(" * isStopped: %s", getPhysicalSource()->isStopped() ? "YES" : "NO"); + nlwarning(" * isPaused: %s", getPhysicalSource()->isPaused() ? "YES" : "NO"); + nlwarning(" * getPos: %f, %f, %f", getPhysicalSource()->getPos().x, getPhysicalSource()->getPos().y, getPhysicalSource()->getPos().z); + NLMISC::CVector v; + getPhysicalSource()->getVelocity(v); + nlwarning(" * getVelocity: %f, %f, %f", v.x, v.y, v.z); + getPhysicalSource()->getDirection(v); + nlwarning(" * getDirection: %f, %f, %f", v.x, v.y, v.z); + nlwarning(" * getGain: %f", getPhysicalSource()->getGain()); + nlwarning(" * getPitch: %f", getPhysicalSource()->getPitch()); + nlwarning(" * getSourceRelativeMode: %s", getPhysicalSource()->getSourceRelativeMode() ? "YES" : "NO"); + float a, b, c; + getPhysicalSource()->getMinMaxDistances(a, b); + nlwarning(" * getMinMaxDistances: %f, %f", a, b); + getPhysicalSource()->getCone(a, b, c); + nlwarning(" * getCone: %f, %f", a, b, c); + nlwarning(" * getDirect: %s", getPhysicalSource()->getDirect() ? "YES" : "NO"); + nlwarning(" * getDirectGain: %f", getPhysicalSource()->getDirectGain()); + nlwarning(" * isDirectFilterEnabled: %s", getPhysicalSource()->isDirectFilterEnabled() ? "YES" : "NO"); + nlwarning(" * getEffect: %s", getPhysicalSource()->getEffect() ? "YES" : "NO"); + nlwarning(" * getEffectGain: %f", getPhysicalSource()->getEffectGain()); + nlwarning(" * isEffectFilterEnabled: %s", getPhysicalSource()->isEffectFilterEnabled() ? "YES" : "NO"); +#endif + } } +#ifdef NL_DEBUG nlassert(play); +#else + if (!play) + nlwarning("Failed to play physical sound source. This is a serious error"); +#endif } -/// Stop playing -void CStreamSource::stop() +void CStreamSource::stopInt() { CAutoMutex autoMutex(m_BufferMutex); // nldebug("CStreamSource %p : stop", (CAudioMixerUser::IMixerEvent*)this); // nlassert(_Playing); + + if (m_WaitingForPlay) + { + nlassert(!_Playing); // cannot already be playing if waiting for play + CAudioMixerUser *mixer = CAudioMixerUser::instance(); + mixer->removeSourceWaitingForPlay(this); + } if (!_Playing) + { + m_WaitingForPlay = false; return; + } if (hasPhysicalSource()) releasePhysicalSource(); @@ -234,6 +303,14 @@ void CStreamSource::stop() m_FreeBuffers = 3; m_NextBuffer = 0; + m_WaitingForPlay = false; +} + +/// Stop playing +void CStreamSource::stop() +{ + stopInt(); + if (_Spawn) { if (_SpawnEndCb != NULL) @@ -294,28 +371,18 @@ void CStreamSource::setDirection(const NLMISC::CVector& dir) } } -void CStreamSource::setGain(float gain) +void CStreamSource::updateFinalGain() { CAutoMutex autoMutex(m_BufferMutex); - - CSourceCommon::setGain(gain); + if (hasPhysicalSource()) - getPhysicalSource()->setGain(gain); -} - -void CStreamSource::setRelativeGain(float gain) -{ - CAutoMutex autoMutex(m_BufferMutex); - - CSourceCommon::setRelativeGain(gain); - if (hasPhysicalSource()) - getPhysicalSource()->setGain(_Gain); + getPhysicalSource()->setGain(getFinalGain()); } void CStreamSource::setPitch(float pitch) { CAutoMutex autoMutex(m_BufferMutex); - + m_PitchInv = 1.0f / pitch; CSourceCommon::setPitch(pitch); if (hasPhysicalSource()) getPhysicalSource()->setPitch(pitch); @@ -382,7 +449,9 @@ bool CStreamSource::unlock(uint size) ++m_NextBuffer; m_NextBuffer %= 3; --m_FreeBuffers; if (hasPhysicalSource()) + { getPhysicalSource()->submitStreamingBuffer(buffer); + } m_LastSize = size; } @@ -406,8 +475,8 @@ void CStreamSource::getRecommendedBufferSize(uint &samples, uint &bytes) const uint32 CStreamSource::getRecommendedSleepTime() const { if (m_FreeBuffers > 0) return 0; - uint32 sleepTime = (uint32)((1000.0f * ((float)m_LastSize) / (float)m_BytesPerSecond) / _Pitch); - clamp(sleepTime, (uint32)0, (uint32)1000); + uint32 sleepTime = (uint32)((1000.0f * ((float)m_LastSize) / (float)m_BytesPerSecond) * m_PitchInv); + clamp(sleepTime, (uint32)0, (uint32)80); return sleepTime; } @@ -418,6 +487,19 @@ bool CStreamSource::hasFilledBuffersAvailable() const return m_FreeBuffers < 3; } +void CStreamSource::preAllocate(uint capacity) +{ + uint8 *b0 = m_Buffers[0]->lock(capacity); + memset(b0, 0, capacity); + m_Buffers[0]->unlock(capacity); + uint8 *b1 = m_Buffers[1]->lock(capacity); + memset(b1, 0, capacity); + m_Buffers[1]->unlock(capacity); + uint8 *b2 = m_Buffers[2]->lock(capacity); + memset(b2, 0, capacity); + m_Buffers[2]->unlock(capacity); +} + } /* namespace NLSOUND */ /* end of file */ diff --git a/code/nel/tools/3d/Makefile.am b/code/nel/tools/3d/Makefile.am deleted file mode 100644 index 7cde91464..000000000 --- a/code/nel/tools/3d/Makefile.am +++ /dev/null @@ -1,32 +0,0 @@ -# -# $Id: Makefile.am,v 1.2 2002/05/14 13:33:59 valignat Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -DIST_SUBDIRS = build_coarse_mesh \ - build_far_bank \ - build_smallbank \ - ig_lighter_lib \ - ig_lighter \ - panoply_maker \ - zone_lib \ - zone_dependencies \ - zone_ig_lighter \ - zone_lighter \ - zone_welder - -SUBDIRS = build_coarse_mesh \ - build_far_bank \ - build_smallbank \ - ig_lighter_lib \ - ig_lighter \ - zone_lib \ - zone_dependencies \ - zone_ig_lighter \ - zone_lighter \ - zone_welder - - -# End of Makefile.am - diff --git a/code/nel/tools/3d/build_coarse_mesh/Makefile.am b/code/nel/tools/3d/build_coarse_mesh/Makefile.am deleted file mode 100644 index b161e1b59..000000000 --- a/code/nel/tools/3d/build_coarse_mesh/Makefile.am +++ /dev/null @@ -1,21 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2002/05/13 15:44:57 valignat Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = build.cfg \ - build_coarse_mesh.dsp - -bin_PROGRAMS = build_coarse_mesh - -build_coarse_mesh_SOURCES = build_coarse_mesh.cpp - -AM_CXXFLAGS = -I$(top_srcdir)/src - -build_coarse_mesh_LDADD = ../../../src/misc/libnelmisc.la \ - ../../../src/3d/libnel3d.la - - -# End of Makefile.am - diff --git a/code/nel/tools/3d/build_far_bank/Makefile.am b/code/nel/tools/3d/build_far_bank/Makefile.am deleted file mode 100644 index 9dd0eadec..000000000 --- a/code/nel/tools/3d/build_far_bank/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2002/05/13 15:44:57 valignat Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = build_far_bank.dsp - -bin_PROGRAMS = build_far_bank - -build_far_bank_SOURCES = build_far_bank.cpp - -AM_CXXFLAGS = -I$(top_srcdir)/src - -build_far_bank_LDADD = ../../../src/misc/libnelmisc.la \ - ../../../src/3d/libnel3d.la - - -# End of Makefile.am - diff --git a/code/nel/tools/3d/build_smallbank/Makefile.am b/code/nel/tools/3d/build_smallbank/Makefile.am deleted file mode 100644 index f70258cb6..000000000 --- a/code/nel/tools/3d/build_smallbank/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2002/05/13 15:44:57 valignat Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = build_smallbank.dsp - -bin_PROGRAMS = build_smallbank - -build_smallbank_SOURCES = build_smallbank.cpp - -AM_CXXFLAGS = -I$(top_srcdir)/src - -build_smallbank_LDADD = ../../../src/misc/libnelmisc.la \ - ../../../src/3d/libnel3d.la - - -# End of Makefile.am - diff --git a/code/nel/tools/3d/ig_lighter/Makefile.am b/code/nel/tools/3d/ig_lighter/Makefile.am deleted file mode 100644 index ccde76fd0..000000000 --- a/code/nel/tools/3d/ig_lighter/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2002/05/13 15:44:57 valignat Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = config.cfg \ - ig_lighter.dsp - -bin_PROGRAMS = ig_lighter - -ig_lighter_SOURCES = ig_lighter.cpp - -AM_CXXFLAGS = -I$(top_srcdir)/src - -ig_lighter_LDADD = ../../../src/misc/libnelmisc.la \ - ../../../src/3d/libnel3d.la \ - ../../../src/pacs/libnelpacs.la \ - ../ig_lighter_lib/libig_lighter.la - - -# End of Makefile.am - diff --git a/code/nel/tools/3d/ig_lighter_lib/Makefile.am b/code/nel/tools/3d/ig_lighter_lib/Makefile.am deleted file mode 100644 index e66b9a94b..000000000 --- a/code/nel/tools/3d/ig_lighter_lib/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2002/05/13 15:44:57 valignat Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = ig_lighter_lib.dsp - -noinst_LTLIBRARIES = libig_lighter.la - -libig_lighter_la_SOURCES = ig_lighter_lib.cpp - -noinst_HEADERS = ig_lighter_lib.h - -AM_CXXFLAGS = -I$(top_srcdir)/src - -libig_lighter_la_LIBADD = ../../../src/misc/libnelmisc.la \ - ../../../src/3d/libnel3d.la \ - ../../../src/pacs/libnelpacs.la - - -# End of Makefile.am - diff --git a/code/nel/tools/3d/ligo/plugin_max/DllEntry.cpp b/code/nel/tools/3d/ligo/plugin_max/DllEntry.cpp index 3cf88f4a7..ee9964566 100644 --- a/code/nel/tools/3d/ligo/plugin_max/DllEntry.cpp +++ b/code/nel/tools/3d/ligo/plugin_max/DllEntry.cpp @@ -18,6 +18,7 @@ #include "nel/misc/app_context.h" #include #include "../../plugin_max/nel_3dsmax_shared/nel_3dsmax_shared.h" +#include extern ClassDesc2* GetLigoscapeDesc(); @@ -44,7 +45,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved) if (!controlsInit) { controlsInit = TRUE; +#if MAX_VERSION_MAJOR < 14 InitCustomControls(hInstance); // Initialize MAX's custom controls +#endif InitCommonControls(); // Initialize Win95 controls } diff --git a/code/nel/tools/3d/ligo/plugin_max/max_to_ligo.cpp b/code/nel/tools/3d/ligo/plugin_max/max_to_ligo.cpp index 7500b027b..eb4951991 100644 --- a/code/nel/tools/3d/ligo/plugin_max/max_to_ligo.cpp +++ b/code/nel/tools/3d/ligo/plugin_max/max_to_ligo.cpp @@ -17,7 +17,12 @@ #include // From MAXSDK -#include +#include +#if MAX_VERSION_MAJOR >= 14 +# include +#else +# include +#endif #include "max_to_ligo.h" diff --git a/code/nel/tools/3d/ligo/plugin_max/script.cpp b/code/nel/tools/3d/ligo/plugin_max/script.cpp index 5d6381303..b00de5fe4 100644 --- a/code/nel/tools/3d/ligo/plugin_max/script.cpp +++ b/code/nel/tools/3d/ligo/plugin_max/script.cpp @@ -19,17 +19,30 @@ #include // Various MAX and MXS includes -#include -#include -#include -#include -#include -#include -#include -#include +#include +#if MAX_VERSION_MAJOR >= 14 +# include +# include +# include +# include +# include +# include +# include +# include +# include +#else +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif #include #include -#include // Visual #include diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/CMakeLists.txt new file mode 100644 index 000000000..2caaa1be7 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/CMakeLists.txt @@ -0,0 +1 @@ +ADD_SUBDIRECTORY(qtpropertybrowser) diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/CMakeLists.txt new file mode 100644 index 000000000..f4ed13e0a --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/CMakeLists.txt @@ -0,0 +1,98 @@ +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${QT_INCLUDES}) +INCLUDE(${QT_USE_FILE}) + +FILE(GLOB SRC *.cpp *.h) + +SET(QT_PROPERTY_EDITOR_HDR qtpropertybrowser.h + qtpropertymanager.h + qteditorfactory.h + qtvariantproperty.h + qttreepropertybrowser.h + qtbuttonpropertybrowser.h + qtgroupboxpropertybrowser.h + qtpropertybrowserutils_p.h) + +SET(QT_PROPERTY_EDITOR_RCS qtpropertybrowser.qrc) + +SET(QT_USE_QTGUI TRUE) + +QT4_ADD_RESOURCES(QT_PROPERTY_EDITOR_RC_SRCS ${QT_PROPERTY_EDITOR_RCS}) +QT4_WRAP_CPP(QT_PROPERTY_EDITOR_MOC_SRC ${QT_PROPERTY_EDITOR_HDR}) + +SOURCE_GROUP(QtResources FILES ${QT_PROPERTY_EDITOR_RCS}) +SOURCE_GROUP(QtGeneratedMocSrc FILES ${QT_PROPERTY_EDITOR_MOC_SRC}) +SOURCE_GROUP("Qt Property Editor Source" FILES ${SRC}) + +qt4_generate_moc(qtpropertymanager.cpp ${CMAKE_CURRENT_BINARY_DIR}/qtpropertymanager.moc) +qt4_generate_moc(qteditorfactory.cpp ${CMAKE_CURRENT_BINARY_DIR}/qteditorfactory.moc) +qt4_generate_moc(qttreepropertybrowser.cpp ${CMAKE_CURRENT_BINARY_DIR}/qttreepropertybrowser.moc) + +# Need to remove these so that they are not linked as they are inline included. +LIST(REMOVE_ITEM QT_PROPERTY_EDITOR_MOC_SRC ${CMAKE_CURRENT_BINARY_DIR}/moc_qtbuttonpropertybrowser.cxx + ${CMAKE_CURRENT_BINARY_DIR}/moc_qteditorfactory.cxx + ${CMAKE_CURRENT_BINARY_DIR}/moc_qtgroupboxpropertybrowser.cxx + ${CMAKE_CURRENT_BINARY_DIR}/moc_qtpropertybrowser.cxx + ${CMAKE_CURRENT_BINARY_DIR}/moc_qtpropertymanager.cxx + ${CMAKE_CURRENT_BINARY_DIR}/moc_qttreepropertybrowser.cxx + ${CMAKE_CURRENT_BINARY_DIR}/moc_qtvariantproperty.cxx) + +# We need to add new depencencies on removed files because we need them to be still generated +SET_PROPERTY(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/qtbuttonpropertybrowser.cpp APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/moc_qtbuttonpropertybrowser.cxx) +SET_PROPERTY(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/qteditorfactory.cpp APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/moc_qteditorfactory.cxx) +SET_PROPERTY(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/qtgroupboxpropertybrowser.cpp APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/moc_qtgroupboxpropertybrowser.cxx) +SET_PROPERTY(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/qtpropertybrowser.cpp APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/moc_qtpropertybrowser.cxx) +SET_PROPERTY(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/qtpropertymanager.cpp APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/moc_qtpropertymanager.cxx) +SET_PROPERTY(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/qttreepropertybrowser.cpp APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/moc_qttreepropertybrowser.cxx) +SET_PROPERTY(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/qtvariantproperty.cpp APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/moc_qtvariantproperty.cxx) + +#set( +# qtpropertyeditor_HEADERS_ONLY_MOC +# ${CMAKE_CURRENT_BINARY_DIR}/moc_qtpropertybrowser.cpp +# ${CMAKE_CURRENT_BINARY_DIR}/moc_qtpropertymanager.cpp +# ${CMAKE_CURRENT_BINARY_DIR}/moc_qteditorfactory.cpp +# ${CMAKE_CURRENT_BINARY_DIR}/moc_qtvariantproperty.cpp +# ${CMAKE_CURRENT_BINARY_DIR}/moc_qttreepropertybrowser.cpp +# ${CMAKE_CURRENT_BINARY_DIR}/moc_qtbuttonpropertybrowser.cpp +# ${CMAKE_CURRENT_BINARY_DIR}/moc_qtgroupboxpropertybrowser.cpp +# ${CMAKE_CURRENT_BINARY_DIR}/qtpropertymanager.moc +# ${CMAKE_CURRENT_BINARY_DIR}/qteditorfactory.moc +# ${CMAKE_CURRENT_BINARY_DIR}/qttreepropertybrowser.moc +#) +# +#set_source_files_properties( +# ${qtpropertyeditor_HEADERS_ONLY_MOC} +# PROPERTIES +# HEADER_FILE_ONLY true +#) +# + +#set( +# qtpropertyeditor_HEADERS_MOC +# ${CMAKE_CURRENT_BINARY_DIR}/moc_qtpropertybrowserutils_p.cpp +#) + +#set( +# qtpropertyeditor_MOC +# ${qtpropertyeditor_HEADERS_MOC} +# ${qtpropertyeditor_HEADERS_ONLY_MOC} +#) + +ADD_LIBRARY(qt_property_browser SHARED ${SRC} + ${QT_PROPERTY_EDITOR_MOC_SRC} + ${QT_PROPERTY_EDITOR_RC_SRCS} + ${CMAKE_CURRENT_BINARY_DIR}/qtpropertymanager.moc + ${CMAKE_CURRENT_BINARY_DIR}/qttreepropertybrowser.moc + ${CMAKE_CURRENT_BINARY_DIR}/qteditorfactory.moc) + +TARGET_LINK_LIBRARIES(qt_property_browser ${QT_LIBRARIES}) + +ADD_DEFINITIONS(${QT_DEFINITIONS}) +ADD_DEFINITIONS(-DQT_DLL) +ADD_DEFINITIONS(-DQT_QTPROPERTYBROWSER_EXPORT) +ADD_DEFINITIONS(-DQT_PLUGIN) +#ADD_DEFINITIONS(-DQT_NO_DEBUG) +ADD_DEFINITIONS(-DQT_SHARED) + +NL_DEFAULT_PROPS(qt_property_browser "3rdParty: Qt Property Browser 2.5") +NL_ADD_RUNTIME_FLAGS(qt_property_browser) +NL_ADD_LIB_SUFFIX(qt_property_browser) diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/LGPL_EXCEPTION.txt b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/LGPL_EXCEPTION.txt new file mode 100644 index 000000000..0b56ff1ef --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/LGPL_EXCEPTION.txt @@ -0,0 +1,10 @@ +Nokia Qt LGPL Exception version 1.0 + +As a special exception to the GNU Lesser General Public License +version 2.1, the object code form of a "work that uses the Library" +may incorporate material from a header file that is part of the +Library. You may distribute such object code under terms of your +choice, provided that the incorporated material (i) does not exceed +more than 5% of the total size of the Library; and (ii) is limited to +numerical parameters, data structure layouts, accessors, macros, +inline functions and templates. diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/LICENSE.GPL3 b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/LICENSE.GPL3 new file mode 100644 index 000000000..94a9ed024 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/LICENSE.GPL3 @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/LICENSE.LGPL b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/LICENSE.LGPL new file mode 100644 index 000000000..5ab7695ab --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/LICENSE.LGPL @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library 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 2.1 of the License, or (at your option) any later version. + + This library 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 library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtAbstractEditorFactoryBase b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtAbstractEditorFactoryBase new file mode 100644 index 000000000..ab4e7104a --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtAbstractEditorFactoryBase @@ -0,0 +1 @@ +#include "qtpropertybrowser.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtAbstractPropertyBrowser b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtAbstractPropertyBrowser new file mode 100644 index 000000000..ab4e7104a --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtAbstractPropertyBrowser @@ -0,0 +1 @@ +#include "qtpropertybrowser.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtAbstractPropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtAbstractPropertyManager new file mode 100644 index 000000000..ab4e7104a --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtAbstractPropertyManager @@ -0,0 +1 @@ +#include "qtpropertybrowser.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtBoolPropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtBoolPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtBoolPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtBrowserItem b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtBrowserItem new file mode 100644 index 000000000..ab4e7104a --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtBrowserItem @@ -0,0 +1 @@ +#include "qtpropertybrowser.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtButtonPropertyBrowser b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtButtonPropertyBrowser new file mode 100644 index 000000000..56e089704 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtButtonPropertyBrowser @@ -0,0 +1 @@ +#include "qtbuttonpropertybrowser.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtCharEditorFactory b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtCharEditorFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtCharEditorFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtCharPropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtCharPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtCharPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtCheckBoxFactory b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtCheckBoxFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtCheckBoxFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtColorEditorFactory b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtColorEditorFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtColorEditorFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtColorPropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtColorPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtColorPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtCursorEditorFactory b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtCursorEditorFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtCursorEditorFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtCursorPropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtCursorPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtCursorPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtDateEditFactory b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtDateEditFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtDateEditFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtDatePropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtDatePropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtDatePropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtDateTimeEditFactory b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtDateTimeEditFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtDateTimeEditFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtDateTimePropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtDateTimePropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtDateTimePropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtDoublePropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtDoublePropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtDoublePropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtDoubleSpinBoxFactory b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtDoubleSpinBoxFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtDoubleSpinBoxFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtEnumEditorFactory b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtEnumEditorFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtEnumEditorFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtEnumPropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtEnumPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtEnumPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtFlagPropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtFlagPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtFlagPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtFontEditorFactory b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtFontEditorFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtFontEditorFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtFontPropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtFontPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtFontPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtGroupBoxPropertyBrowser b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtGroupBoxPropertyBrowser new file mode 100644 index 000000000..27964c080 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtGroupBoxPropertyBrowser @@ -0,0 +1 @@ +#include "qtgroupboxpropertybrowser.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtGroupPropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtGroupPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtGroupPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtIntPropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtIntPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtIntPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtKeySequenceEditorFactory b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtKeySequenceEditorFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtKeySequenceEditorFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtKeySequencePropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtKeySequencePropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtKeySequencePropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtLineEditFactory b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtLineEditFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtLineEditFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtLocalePropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtLocalePropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtLocalePropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtPointFPropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtPointFPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtPointFPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtPointPropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtPointPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtPointPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtProperty b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtProperty new file mode 100644 index 000000000..ab4e7104a --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtProperty @@ -0,0 +1 @@ +#include "qtpropertybrowser.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtRectFPropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtRectFPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtRectFPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtRectPropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtRectPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtRectPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtScrollBarFactory b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtScrollBarFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtScrollBarFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtSizeFPropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtSizeFPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtSizeFPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtSizePolicyPropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtSizePolicyPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtSizePolicyPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtSizePropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtSizePropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtSizePropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtSliderFactory b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtSliderFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtSliderFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtSpinBoxFactory b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtSpinBoxFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtSpinBoxFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtStringPropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtStringPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtStringPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtTimeEditFactory b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtTimeEditFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtTimeEditFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtTimePropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtTimePropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtTimePropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtTreePropertyBrowser b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtTreePropertyBrowser new file mode 100644 index 000000000..aab106c75 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtTreePropertyBrowser @@ -0,0 +1 @@ +#include "qttreepropertybrowser.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtVariantEditorFactory b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtVariantEditorFactory new file mode 100644 index 000000000..8118190d5 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtVariantEditorFactory @@ -0,0 +1 @@ +#include "qtvariantproperty.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtVariantProperty b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtVariantProperty new file mode 100644 index 000000000..8118190d5 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtVariantProperty @@ -0,0 +1 @@ +#include "qtvariantproperty.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtVariantPropertyManager b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtVariantPropertyManager new file mode 100644 index 000000000..8118190d5 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/QtVariantPropertyManager @@ -0,0 +1 @@ +#include "qtvariantproperty.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/README.TXT b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/README.TXT new file mode 100644 index 000000000..d9452cfc1 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/README.TXT @@ -0,0 +1,19 @@ +Property Browser v2.5 + +A property browser framework enabling the user to edit a set of +properties. + +The framework provides a browser widget that displays the given +properties with labels and corresponding editing widgets (e.g. +line edits or comboboxes). The various types of editing widgets +are provided by the framework's editor factories: For each +property type, the framework provides a property manager (e.g. +QtIntPropertyManager and QtStringPropertyManager) which can be +associated with the preferred editor factory (e.g. +QtSpinBoxFactory and QtLineEditFactory). The framework also +provides a variant based property type with corresponding variant +manager and factory. Finally, the framework provides three +ready-made implementations of the browser widget: +QtTreePropertyBrowser, QtButtonPropertyBrowser and +QtGroupBoxPropertyBrowser. + diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-arrow.png b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-arrow.png new file mode 100644 index 000000000..a69ef4eb6 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-arrow.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-busy.png b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-busy.png new file mode 100644 index 000000000..53717e499 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-busy.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-closedhand.png b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-closedhand.png new file mode 100644 index 000000000..b78dd1dac Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-closedhand.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-cross.png b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-cross.png new file mode 100644 index 000000000..fe38e7448 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-cross.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-forbidden.png b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-forbidden.png new file mode 100644 index 000000000..2b08c4e2a Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-forbidden.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-hand.png b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-hand.png new file mode 100644 index 000000000..d2004aefa Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-hand.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-hsplit.png b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-hsplit.png new file mode 100644 index 000000000..a5667e3ff Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-hsplit.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-ibeam.png b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-ibeam.png new file mode 100644 index 000000000..097fc5fa7 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-ibeam.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-openhand.png b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-openhand.png new file mode 100644 index 000000000..9181c859e Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-openhand.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-sizeall.png b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-sizeall.png new file mode 100644 index 000000000..69f13eb34 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-sizeall.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-sizeb.png b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-sizeb.png new file mode 100644 index 000000000..f37d7b91e Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-sizeb.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-sizef.png b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-sizef.png new file mode 100644 index 000000000..3b127a05d Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-sizef.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-sizeh.png b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-sizeh.png new file mode 100644 index 000000000..a9f40cbc3 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-sizeh.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-sizev.png b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-sizev.png new file mode 100644 index 000000000..1edbab27a Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-sizev.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-uparrow.png b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-uparrow.png new file mode 100644 index 000000000..d3e70ef4c Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-uparrow.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-vsplit.png b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-vsplit.png new file mode 100644 index 000000000..1beda2570 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-vsplit.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-wait.png b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-wait.png new file mode 100644 index 000000000..69056c479 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-wait.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-whatsthis.png b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-whatsthis.png new file mode 100644 index 000000000..b47601c37 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/cursor-whatsthis.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtbuttonpropertybrowser.cpp b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtbuttonpropertybrowser.cpp new file mode 100644 index 000000000..d5ebd4fc2 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtbuttonpropertybrowser.cpp @@ -0,0 +1,676 @@ +/**************************************************************************** +** +** This file is part of a Qt Solutions component. +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtbuttonpropertybrowser.h" +#include +#include +#include +#include +#include +#include +#include + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +class QtButtonPropertyBrowserPrivate +{ + QtButtonPropertyBrowser *q_ptr; + Q_DECLARE_PUBLIC(QtButtonPropertyBrowser) +public: + + void init(QWidget *parent); + + void propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex); + void propertyRemoved(QtBrowserItem *index); + void propertyChanged(QtBrowserItem *index); + QWidget *createEditor(QtProperty *property, QWidget *parent) const + { return q_ptr->createEditor(property, parent); } + + void slotEditorDestroyed(); + void slotUpdate(); + void slotToggled(bool checked); + + struct WidgetItem + { + WidgetItem() : widget(0), label(0), widgetLabel(0), + button(0), container(0), layout(0), /*line(0), */parent(0), expanded(false) { } + QWidget *widget; // can be null + QLabel *label; // main label with property name + QLabel *widgetLabel; // label substitute showing the current value if there is no widget + QToolButton *button; // expandable button for items with children + QWidget *container; // container which is expanded when the button is clicked + QGridLayout *layout; // layout in container + WidgetItem *parent; + QList children; + bool expanded; + }; +private: + void updateLater(); + void updateItem(WidgetItem *item); + void insertRow(QGridLayout *layout, int row) const; + void removeRow(QGridLayout *layout, int row) const; + int gridRow(WidgetItem *item) const; + int gridSpan(WidgetItem *item) const; + void setExpanded(WidgetItem *item, bool expanded); + QToolButton *createButton(QWidget *panret = 0) const; + + QMap m_indexToItem; + QMap m_itemToIndex; + QMap m_widgetToItem; + QMap m_buttonToItem; + QGridLayout *m_mainLayout; + QList m_children; + QList m_recreateQueue; +}; + +QToolButton *QtButtonPropertyBrowserPrivate::createButton(QWidget *parent) const +{ + QToolButton *button = new QToolButton(parent); + button->setCheckable(true); + button->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed)); + button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + button->setArrowType(Qt::DownArrow); + button->setIconSize(QSize(3, 16)); + /* + QIcon icon; + icon.addPixmap(q_ptr->style()->standardPixmap(QStyle::SP_ArrowDown), QIcon::Normal, QIcon::Off); + icon.addPixmap(q_ptr->style()->standardPixmap(QStyle::SP_ArrowUp), QIcon::Normal, QIcon::On); + button->setIcon(icon); + */ + return button; +} + +int QtButtonPropertyBrowserPrivate::gridRow(WidgetItem *item) const +{ + QList siblings; + if (item->parent) + siblings = item->parent->children; + else + siblings = m_children; + + int row = 0; + QListIterator it(siblings); + while (it.hasNext()) { + WidgetItem *sibling = it.next(); + if (sibling == item) + return row; + row += gridSpan(sibling); + } + return -1; +} + +int QtButtonPropertyBrowserPrivate::gridSpan(WidgetItem *item) const +{ + if (item->container && item->expanded) + return 2; + return 1; +} + +void QtButtonPropertyBrowserPrivate::init(QWidget *parent) +{ + m_mainLayout = new QGridLayout(); + parent->setLayout(m_mainLayout); + QLayoutItem *item = new QSpacerItem(0, 0, + QSizePolicy::Fixed, QSizePolicy::Expanding); + m_mainLayout->addItem(item, 0, 0); +} + +void QtButtonPropertyBrowserPrivate::slotEditorDestroyed() +{ + QWidget *editor = qobject_cast(q_ptr->sender()); + if (!editor) + return; + if (!m_widgetToItem.contains(editor)) + return; + m_widgetToItem[editor]->widget = 0; + m_widgetToItem.remove(editor); +} + +void QtButtonPropertyBrowserPrivate::slotUpdate() +{ + QListIterator itItem(m_recreateQueue); + while (itItem.hasNext()) { + WidgetItem *item = itItem.next(); + + WidgetItem *parent = item->parent; + QWidget *w = 0; + QGridLayout *l = 0; + const int oldRow = gridRow(item); + if (parent) { + w = parent->container; + l = parent->layout; + } else { + w = q_ptr; + l = m_mainLayout; + } + + int span = 1; + if (!item->widget && !item->widgetLabel) + span = 2; + item->label = new QLabel(w); + item->label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + l->addWidget(item->label, oldRow, 0, 1, span); + + updateItem(item); + } + m_recreateQueue.clear(); +} + +void QtButtonPropertyBrowserPrivate::setExpanded(WidgetItem *item, bool expanded) +{ + if (item->expanded == expanded) + return; + + if (!item->container) + return; + + item->expanded = expanded; + const int row = gridRow(item); + WidgetItem *parent = item->parent; + QGridLayout *l = 0; + if (parent) + l = parent->layout; + else + l = m_mainLayout; + + if (expanded) { + insertRow(l, row + 1); + l->addWidget(item->container, row + 1, 0, 1, 2); + item->container->show(); + } else { + l->removeWidget(item->container); + item->container->hide(); + removeRow(l, row + 1); + } + + item->button->setChecked(expanded); + item->button->setArrowType(expanded ? Qt::UpArrow : Qt::DownArrow); +} + +void QtButtonPropertyBrowserPrivate::slotToggled(bool checked) +{ + WidgetItem *item = m_buttonToItem.value(q_ptr->sender()); + if (!item) + return; + + setExpanded(item, checked); + + if (checked) + emit q_ptr->expanded(m_itemToIndex.value(item)); + else + emit q_ptr->collapsed(m_itemToIndex.value(item)); +} + +void QtButtonPropertyBrowserPrivate::updateLater() +{ + QTimer::singleShot(0, q_ptr, SLOT(slotUpdate())); +} + +void QtButtonPropertyBrowserPrivate::propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex) +{ + WidgetItem *afterItem = m_indexToItem.value(afterIndex); + WidgetItem *parentItem = m_indexToItem.value(index->parent()); + + WidgetItem *newItem = new WidgetItem(); + newItem->parent = parentItem; + + QGridLayout *layout = 0; + QWidget *parentWidget = 0; + int row = -1; + if (!afterItem) { + row = 0; + if (parentItem) + parentItem->children.insert(0, newItem); + else + m_children.insert(0, newItem); + } else { + row = gridRow(afterItem) + gridSpan(afterItem); + if (parentItem) + parentItem->children.insert(parentItem->children.indexOf(afterItem) + 1, newItem); + else + m_children.insert(m_children.indexOf(afterItem) + 1, newItem); + } + + if (!parentItem) { + layout = m_mainLayout; + parentWidget = q_ptr; + } else { + if (!parentItem->container) { + m_recreateQueue.removeAll(parentItem); + WidgetItem *grandParent = parentItem->parent; + QWidget *w = 0; + QGridLayout *l = 0; + const int oldRow = gridRow(parentItem); + if (grandParent) { + w = grandParent->container; + l = grandParent->layout; + } else { + w = q_ptr; + l = m_mainLayout; + } + QFrame *container = new QFrame(); + container->setFrameShape(QFrame::Panel); + container->setFrameShadow(QFrame::Raised); + parentItem->container = container; + parentItem->button = createButton(); + m_buttonToItem[parentItem->button] = parentItem; + q_ptr->connect(parentItem->button, SIGNAL(toggled(bool)), q_ptr, SLOT(slotToggled(bool))); + parentItem->layout = new QGridLayout(); + container->setLayout(parentItem->layout); + if (parentItem->label) { + l->removeWidget(parentItem->label); + delete parentItem->label; + parentItem->label = 0; + } + int span = 1; + if (!parentItem->widget && !parentItem->widgetLabel) + span = 2; + l->addWidget(parentItem->button, oldRow, 0, 1, span); + updateItem(parentItem); + } + layout = parentItem->layout; + parentWidget = parentItem->container; + } + + newItem->label = new QLabel(parentWidget); + newItem->label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + newItem->widget = createEditor(index->property(), parentWidget); + if (newItem->widget) { + QObject::connect(newItem->widget, SIGNAL(destroyed()), q_ptr, SLOT(slotEditorDestroyed())); + m_widgetToItem[newItem->widget] = newItem; + } else if (index->property()->hasValue()) { + newItem->widgetLabel = new QLabel(parentWidget); + newItem->widgetLabel->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed)); + } + + insertRow(layout, row); + int span = 1; + if (newItem->widget) + layout->addWidget(newItem->widget, row, 1); + else if (newItem->widgetLabel) + layout->addWidget(newItem->widgetLabel, row, 1); + else + span = 2; + layout->addWidget(newItem->label, row, 0, span, 1); + + m_itemToIndex[newItem] = index; + m_indexToItem[index] = newItem; + + updateItem(newItem); +} + +void QtButtonPropertyBrowserPrivate::propertyRemoved(QtBrowserItem *index) +{ + WidgetItem *item = m_indexToItem.value(index); + + m_indexToItem.remove(index); + m_itemToIndex.remove(item); + + WidgetItem *parentItem = item->parent; + + const int row = gridRow(item); + + if (parentItem) + parentItem->children.removeAt(parentItem->children.indexOf(item)); + else + m_children.removeAt(m_children.indexOf(item)); + + const int colSpan = gridSpan(item); + + m_buttonToItem.remove(item->button); + + if (item->widget) + delete item->widget; + if (item->label) + delete item->label; + if (item->widgetLabel) + delete item->widgetLabel; + if (item->button) + delete item->button; + if (item->container) + delete item->container; + + if (!parentItem) { + removeRow(m_mainLayout, row); + if (colSpan > 1) + removeRow(m_mainLayout, row); + } else if (parentItem->children.count() != 0) { + removeRow(parentItem->layout, row); + if (colSpan > 1) + removeRow(parentItem->layout, row); + } else { + const WidgetItem *grandParent = parentItem->parent; + QGridLayout *l = 0; + if (grandParent) { + l = grandParent->layout; + } else { + l = m_mainLayout; + } + + const int parentRow = gridRow(parentItem); + const int parentSpan = gridSpan(parentItem); + + l->removeWidget(parentItem->button); + l->removeWidget(parentItem->container); + delete parentItem->button; + delete parentItem->container; + parentItem->button = 0; + parentItem->container = 0; + parentItem->layout = 0; + if (!m_recreateQueue.contains(parentItem)) + m_recreateQueue.append(parentItem); + if (parentSpan > 1) + removeRow(l, parentRow + 1); + + updateLater(); + } + m_recreateQueue.removeAll(item); + + delete item; +} + +void QtButtonPropertyBrowserPrivate::insertRow(QGridLayout *layout, int row) const +{ + QMap itemToPos; + int idx = 0; + while (idx < layout->count()) { + int r, c, rs, cs; + layout->getItemPosition(idx, &r, &c, &rs, &cs); + if (r >= row) { + itemToPos[layout->takeAt(idx)] = QRect(r + 1, c, rs, cs); + } else { + idx++; + } + } + + const QMap::ConstIterator icend = itemToPos.constEnd(); + for(QMap::ConstIterator it = itemToPos.constBegin(); it != icend; ++it) { + const QRect r = it.value(); + layout->addItem(it.key(), r.x(), r.y(), r.width(), r.height()); + } +} + +void QtButtonPropertyBrowserPrivate::removeRow(QGridLayout *layout, int row) const +{ + QMap itemToPos; + int idx = 0; + while (idx < layout->count()) { + int r, c, rs, cs; + layout->getItemPosition(idx, &r, &c, &rs, &cs); + if (r > row) { + itemToPos[layout->takeAt(idx)] = QRect(r - 1, c, rs, cs); + } else { + idx++; + } + } + + const QMap::ConstIterator icend = itemToPos.constEnd(); + for(QMap::ConstIterator it = itemToPos.constBegin(); it != icend; ++it) { + const QRect r = it.value(); + layout->addItem(it.key(), r.x(), r.y(), r.width(), r.height()); + } +} + +void QtButtonPropertyBrowserPrivate::propertyChanged(QtBrowserItem *index) +{ + WidgetItem *item = m_indexToItem.value(index); + + updateItem(item); +} + +void QtButtonPropertyBrowserPrivate::updateItem(WidgetItem *item) +{ + QtProperty *property = m_itemToIndex[item]->property(); + if (item->button) { + QFont font = item->button->font(); + font.setUnderline(property->isModified()); + item->button->setFont(font); + item->button->setText(property->propertyName()); + item->button->setToolTip(property->toolTip()); + item->button->setStatusTip(property->statusTip()); + item->button->setWhatsThis(property->whatsThis()); + item->button->setEnabled(property->isEnabled()); + } + if (item->label) { + QFont font = item->label->font(); + font.setUnderline(property->isModified()); + item->label->setFont(font); + item->label->setText(property->propertyName()); + item->label->setToolTip(property->toolTip()); + item->label->setStatusTip(property->statusTip()); + item->label->setWhatsThis(property->whatsThis()); + item->label->setEnabled(property->isEnabled()); + } + if (item->widgetLabel) { + QFont font = item->widgetLabel->font(); + font.setUnderline(false); + item->widgetLabel->setFont(font); + item->widgetLabel->setText(property->valueText()); + item->widgetLabel->setToolTip(property->valueText()); + item->widgetLabel->setEnabled(property->isEnabled()); + } + if (item->widget) { + QFont font = item->widget->font(); + font.setUnderline(false); + item->widget->setFont(font); + item->widget->setEnabled(property->isEnabled()); + item->widget->setToolTip(property->valueText()); + } +} + + + +/*! + \class QtButtonPropertyBrowser + + \brief The QtButtonPropertyBrowser class provides a drop down QToolButton + based property browser. + + A property browser is a widget that enables the user to edit a + given set of properties. Each property is represented by a label + specifying the property's name, and an editing widget (e.g. a line + edit or a combobox) holding its value. A property can have zero or + more subproperties. + + QtButtonPropertyBrowser provides drop down button for all nested + properties, i.e. subproperties are enclosed by a container associated with + the drop down button. The parent property's name is displayed as button text. For example: + + \image qtbuttonpropertybrowser.png + + Use the QtAbstractPropertyBrowser API to add, insert and remove + properties from an instance of the QtButtonPropertyBrowser + class. The properties themselves are created and managed by + implementations of the QtAbstractPropertyManager class. + + \sa QtTreePropertyBrowser, QtAbstractPropertyBrowser +*/ + +/*! + \fn void QtButtonPropertyBrowser::collapsed(QtBrowserItem *item) + + This signal is emitted when the \a item is collapsed. + + \sa expanded(), setExpanded() +*/ + +/*! + \fn void QtButtonPropertyBrowser::expanded(QtBrowserItem *item) + + This signal is emitted when the \a item is expanded. + + \sa collapsed(), setExpanded() +*/ + +/*! + Creates a property browser with the given \a parent. +*/ +QtButtonPropertyBrowser::QtButtonPropertyBrowser(QWidget *parent) + : QtAbstractPropertyBrowser(parent) +{ + d_ptr = new QtButtonPropertyBrowserPrivate; + d_ptr->q_ptr = this; + + d_ptr->init(this); +} + +/*! + Destroys this property browser. + + Note that the properties that were inserted into this browser are + \e not destroyed since they may still be used in other + browsers. The properties are owned by the manager that created + them. + + \sa QtProperty, QtAbstractPropertyManager +*/ +QtButtonPropertyBrowser::~QtButtonPropertyBrowser() +{ + const QMap::ConstIterator icend = d_ptr->m_itemToIndex.constEnd(); + for (QMap::ConstIterator it = d_ptr->m_itemToIndex.constBegin(); it != icend; ++it) + delete it.key(); + delete d_ptr; +} + +/*! + \reimp +*/ +void QtButtonPropertyBrowser::itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem) +{ + d_ptr->propertyInserted(item, afterItem); +} + +/*! + \reimp +*/ +void QtButtonPropertyBrowser::itemRemoved(QtBrowserItem *item) +{ + d_ptr->propertyRemoved(item); +} + +/*! + \reimp +*/ +void QtButtonPropertyBrowser::itemChanged(QtBrowserItem *item) +{ + d_ptr->propertyChanged(item); +} + +/*! + Sets the \a item to either collapse or expanded, depending on the value of \a expanded. + + \sa isExpanded(), expanded(), collapsed() +*/ + +void QtButtonPropertyBrowser::setExpanded(QtBrowserItem *item, bool expanded) +{ + QtButtonPropertyBrowserPrivate::WidgetItem *itm = d_ptr->m_indexToItem.value(item); + if (itm) + d_ptr->setExpanded(itm, expanded); +} + +/*! + Returns true if the \a item is expanded; otherwise returns false. + + \sa setExpanded() +*/ + +bool QtButtonPropertyBrowser::isExpanded(QtBrowserItem *item) const +{ + QtButtonPropertyBrowserPrivate::WidgetItem *itm = d_ptr->m_indexToItem.value(item); + if (itm) + return itm->expanded; + return false; +} + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +#include "moc_qtbuttonpropertybrowser.cxx" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtbuttonpropertybrowser.h b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtbuttonpropertybrowser.h new file mode 100644 index 000000000..518e047e8 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtbuttonpropertybrowser.h @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** This file is part of a Qt Solutions component. +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTBUTTONPROPERTYBROWSER_H +#define QTBUTTONPROPERTYBROWSER_H + +#include "qtpropertybrowser.h" + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +class QtButtonPropertyBrowserPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtButtonPropertyBrowser : public QtAbstractPropertyBrowser +{ + Q_OBJECT +public: + + QtButtonPropertyBrowser(QWidget *parent = 0); + ~QtButtonPropertyBrowser(); + + void setExpanded(QtBrowserItem *item, bool expanded); + bool isExpanded(QtBrowserItem *item) const; + +Q_SIGNALS: + + void collapsed(QtBrowserItem *item); + void expanded(QtBrowserItem *item); + +protected: + virtual void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem); + virtual void itemRemoved(QtBrowserItem *item); + virtual void itemChanged(QtBrowserItem *item); + +private: + + QtButtonPropertyBrowserPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtButtonPropertyBrowser) + Q_DISABLE_COPY(QtButtonPropertyBrowser) + Q_PRIVATE_SLOT(d_func(), void slotUpdate()) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed()) + Q_PRIVATE_SLOT(d_func(), void slotToggled(bool)) + +}; + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +#endif diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.cpp b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.cpp new file mode 100644 index 000000000..e619cf8cb --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.cpp @@ -0,0 +1,2609 @@ +/**************************************************************************** +** +** This file is part of a Qt Solutions component. +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qteditorfactory.h" +#include "qtpropertybrowserutils_p.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(Q_CC_MSVC) +# pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */ +#endif + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +// Set a hard coded left margin to account for the indentation +// of the tree view icon when switching to an editor + +static inline void setupTreeViewEditorMargin(QLayout *lt) +{ + enum { DecorationMargin = 4 }; + if (QApplication::layoutDirection() == Qt::LeftToRight) + lt->setContentsMargins(DecorationMargin, 0, 0, 0); + else + lt->setContentsMargins(0, 0, DecorationMargin, 0); +} + +// ---------- EditorFactoryPrivate : +// Base class for editor factory private classes. Manages mapping of properties to editors and vice versa. + +template +class EditorFactoryPrivate +{ +public: + + typedef QList EditorList; + typedef QMap PropertyToEditorListMap; + typedef QMap EditorToPropertyMap; + + Editor *createEditor(QtProperty *property, QWidget *parent); + void initializeEditor(QtProperty *property, Editor *e); + void slotEditorDestroyed(QObject *object); + + PropertyToEditorListMap m_createdEditors; + EditorToPropertyMap m_editorToProperty; +}; + +template +Editor *EditorFactoryPrivate::createEditor(QtProperty *property, QWidget *parent) +{ + Editor *editor = new Editor(parent); + initializeEditor(property, editor); + return editor; +} + +template +void EditorFactoryPrivate::initializeEditor(QtProperty *property, Editor *editor) +{ + Q_TYPENAME PropertyToEditorListMap::iterator it = m_createdEditors.find(property); + if (it == m_createdEditors.end()) + it = m_createdEditors.insert(property, EditorList()); + it.value().append(editor); + m_editorToProperty.insert(editor, property); +} + +template +void EditorFactoryPrivate::slotEditorDestroyed(QObject *object) +{ + const Q_TYPENAME EditorToPropertyMap::iterator ecend = m_editorToProperty.end(); + for (Q_TYPENAME EditorToPropertyMap::iterator itEditor = m_editorToProperty.begin(); itEditor != ecend; ++itEditor) { + if (itEditor.key() == object) { + Editor *editor = itEditor.key(); + QtProperty *property = itEditor.value(); + const Q_TYPENAME PropertyToEditorListMap::iterator pit = m_createdEditors.find(property); + if (pit != m_createdEditors.end()) { + pit.value().removeAll(editor); + if (pit.value().empty()) + m_createdEditors.erase(pit); + } + m_editorToProperty.erase(itEditor); + return; + } + } +} + +// ------------ QtSpinBoxFactory + +class QtSpinBoxFactoryPrivate : public EditorFactoryPrivate +{ + QtSpinBoxFactory *q_ptr; + Q_DECLARE_PUBLIC(QtSpinBoxFactory) +public: + + void slotPropertyChanged(QtProperty *property, int value); + void slotRangeChanged(QtProperty *property, int min, int max); + void slotSingleStepChanged(QtProperty *property, int step); + void slotSetValue(int value); +}; + +void QtSpinBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, int value) +{ + if (!m_createdEditors.contains(property)) + return; + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QSpinBox *editor = itEditor.next(); + if (editor->value() != value) { + editor->blockSignals(true); + editor->setValue(value); + editor->blockSignals(false); + } + } +} + +void QtSpinBoxFactoryPrivate::slotRangeChanged(QtProperty *property, int min, int max) +{ + if (!m_createdEditors.contains(property)) + return; + + QtIntPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QSpinBox *editor = itEditor.next(); + editor->blockSignals(true); + editor->setRange(min, max); + editor->setValue(manager->value(property)); + editor->blockSignals(false); + } +} + +void QtSpinBoxFactoryPrivate::slotSingleStepChanged(QtProperty *property, int step) +{ + if (!m_createdEditors.contains(property)) + return; + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QSpinBox *editor = itEditor.next(); + editor->blockSignals(true); + editor->setSingleStep(step); + editor->blockSignals(false); + } +} + +void QtSpinBoxFactoryPrivate::slotSetValue(int value) +{ + QObject *object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) { + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtIntPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } + } +} + +/*! + \class QtSpinBoxFactory + + \brief The QtSpinBoxFactory class provides QSpinBox widgets for + properties created by QtIntPropertyManager objects. + + \sa QtAbstractEditorFactory, QtIntPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtSpinBoxFactory::QtSpinBoxFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtSpinBoxFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtSpinBoxFactory::~QtSpinBoxFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtSpinBoxFactory::connectPropertyManager(QtIntPropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotPropertyChanged(QtProperty *, int))); + connect(manager, SIGNAL(rangeChanged(QtProperty *, int, int)), + this, SLOT(slotRangeChanged(QtProperty *, int, int))); + connect(manager, SIGNAL(singleStepChanged(QtProperty *, int)), + this, SLOT(slotSingleStepChanged(QtProperty *, int))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtSpinBoxFactory::createEditor(QtIntPropertyManager *manager, QtProperty *property, + QWidget *parent) +{ + QSpinBox *editor = d_ptr->createEditor(property, parent); + editor->setSingleStep(manager->singleStep(property)); + editor->setRange(manager->minimum(property), manager->maximum(property)); + editor->setValue(manager->value(property)); + editor->setKeyboardTracking(false); + + connect(editor, SIGNAL(valueChanged(int)), this, SLOT(slotSetValue(int))); + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtSpinBoxFactory::disconnectPropertyManager(QtIntPropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotPropertyChanged(QtProperty *, int))); + disconnect(manager, SIGNAL(rangeChanged(QtProperty *, int, int)), + this, SLOT(slotRangeChanged(QtProperty *, int, int))); + disconnect(manager, SIGNAL(singleStepChanged(QtProperty *, int)), + this, SLOT(slotSingleStepChanged(QtProperty *, int))); +} + +// QtSliderFactory + +class QtSliderFactoryPrivate : public EditorFactoryPrivate +{ + QtSliderFactory *q_ptr; + Q_DECLARE_PUBLIC(QtSliderFactory) +public: + void slotPropertyChanged(QtProperty *property, int value); + void slotRangeChanged(QtProperty *property, int min, int max); + void slotSingleStepChanged(QtProperty *property, int step); + void slotSetValue(int value); +}; + +void QtSliderFactoryPrivate::slotPropertyChanged(QtProperty *property, int value) +{ + if (!m_createdEditors.contains(property)) + return; + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QSlider *editor = itEditor.next(); + editor->blockSignals(true); + editor->setValue(value); + editor->blockSignals(false); + } +} + +void QtSliderFactoryPrivate::slotRangeChanged(QtProperty *property, int min, int max) +{ + if (!m_createdEditors.contains(property)) + return; + + QtIntPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QSlider *editor = itEditor.next(); + editor->blockSignals(true); + editor->setRange(min, max); + editor->setValue(manager->value(property)); + editor->blockSignals(false); + } +} + +void QtSliderFactoryPrivate::slotSingleStepChanged(QtProperty *property, int step) +{ + if (!m_createdEditors.contains(property)) + return; + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QSlider *editor = itEditor.next(); + editor->blockSignals(true); + editor->setSingleStep(step); + editor->blockSignals(false); + } +} + +void QtSliderFactoryPrivate::slotSetValue(int value) +{ + QObject *object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor ) { + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtIntPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } + } +} + +/*! + \class QtSliderFactory + + \brief The QtSliderFactory class provides QSlider widgets for + properties created by QtIntPropertyManager objects. + + \sa QtAbstractEditorFactory, QtIntPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtSliderFactory::QtSliderFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtSliderFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtSliderFactory::~QtSliderFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtSliderFactory::connectPropertyManager(QtIntPropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotPropertyChanged(QtProperty *, int))); + connect(manager, SIGNAL(rangeChanged(QtProperty *, int, int)), + this, SLOT(slotRangeChanged(QtProperty *, int, int))); + connect(manager, SIGNAL(singleStepChanged(QtProperty *, int)), + this, SLOT(slotSingleStepChanged(QtProperty *, int))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtSliderFactory::createEditor(QtIntPropertyManager *manager, QtProperty *property, + QWidget *parent) +{ + QSlider *editor = new QSlider(Qt::Horizontal, parent); + d_ptr->initializeEditor(property, editor); + editor->setSingleStep(manager->singleStep(property)); + editor->setRange(manager->minimum(property), manager->maximum(property)); + editor->setValue(manager->value(property)); + + connect(editor, SIGNAL(valueChanged(int)), this, SLOT(slotSetValue(int))); + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtSliderFactory::disconnectPropertyManager(QtIntPropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotPropertyChanged(QtProperty *, int))); + disconnect(manager, SIGNAL(rangeChanged(QtProperty *, int, int)), + this, SLOT(slotRangeChanged(QtProperty *, int, int))); + disconnect(manager, SIGNAL(singleStepChanged(QtProperty *, int)), + this, SLOT(slotSingleStepChanged(QtProperty *, int))); +} + +// QtSliderFactory + +class QtScrollBarFactoryPrivate : public EditorFactoryPrivate +{ + QtScrollBarFactory *q_ptr; + Q_DECLARE_PUBLIC(QtScrollBarFactory) +public: + void slotPropertyChanged(QtProperty *property, int value); + void slotRangeChanged(QtProperty *property, int min, int max); + void slotSingleStepChanged(QtProperty *property, int step); + void slotSetValue(int value); +}; + +void QtScrollBarFactoryPrivate::slotPropertyChanged(QtProperty *property, int value) +{ + if (!m_createdEditors.contains(property)) + return; + + QListIterator itEditor( m_createdEditors[property]); + while (itEditor.hasNext()) { + QScrollBar *editor = itEditor.next(); + editor->blockSignals(true); + editor->setValue(value); + editor->blockSignals(false); + } +} + +void QtScrollBarFactoryPrivate::slotRangeChanged(QtProperty *property, int min, int max) +{ + if (!m_createdEditors.contains(property)) + return; + + QtIntPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + + QListIterator itEditor( m_createdEditors[property]); + while (itEditor.hasNext()) { + QScrollBar *editor = itEditor.next(); + editor->blockSignals(true); + editor->setRange(min, max); + editor->setValue(manager->value(property)); + editor->blockSignals(false); + } +} + +void QtScrollBarFactoryPrivate::slotSingleStepChanged(QtProperty *property, int step) +{ + if (!m_createdEditors.contains(property)) + return; + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QScrollBar *editor = itEditor.next(); + editor->blockSignals(true); + editor->setSingleStep(step); + editor->blockSignals(false); + } +} + +void QtScrollBarFactoryPrivate::slotSetValue(int value) +{ + QObject *object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtIntPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtScrollBarFactory + + \brief The QtScrollBarFactory class provides QScrollBar widgets for + properties created by QtIntPropertyManager objects. + + \sa QtAbstractEditorFactory, QtIntPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtScrollBarFactory::QtScrollBarFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtScrollBarFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtScrollBarFactory::~QtScrollBarFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtScrollBarFactory::connectPropertyManager(QtIntPropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotPropertyChanged(QtProperty *, int))); + connect(manager, SIGNAL(rangeChanged(QtProperty *, int, int)), + this, SLOT(slotRangeChanged(QtProperty *, int, int))); + connect(manager, SIGNAL(singleStepChanged(QtProperty *, int)), + this, SLOT(slotSingleStepChanged(QtProperty *, int))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtScrollBarFactory::createEditor(QtIntPropertyManager *manager, QtProperty *property, + QWidget *parent) +{ + QScrollBar *editor = new QScrollBar(Qt::Horizontal, parent); + d_ptr->initializeEditor(property, editor); + editor->setSingleStep(manager->singleStep(property)); + editor->setRange(manager->minimum(property), manager->maximum(property)); + editor->setValue(manager->value(property)); + connect(editor, SIGNAL(valueChanged(int)), this, SLOT(slotSetValue(int))); + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtScrollBarFactory::disconnectPropertyManager(QtIntPropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotPropertyChanged(QtProperty *, int))); + disconnect(manager, SIGNAL(rangeChanged(QtProperty *, int, int)), + this, SLOT(slotRangeChanged(QtProperty *, int, int))); + disconnect(manager, SIGNAL(singleStepChanged(QtProperty *, int)), + this, SLOT(slotSingleStepChanged(QtProperty *, int))); +} + +// QtCheckBoxFactory + +class QtCheckBoxFactoryPrivate : public EditorFactoryPrivate +{ + QtCheckBoxFactory *q_ptr; + Q_DECLARE_PUBLIC(QtCheckBoxFactory) +public: + void slotPropertyChanged(QtProperty *property, bool value); + void slotSetValue(bool value); +}; + +void QtCheckBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, bool value) +{ + if (!m_createdEditors.contains(property)) + return; + + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QtBoolEdit *editor = itEditor.next(); + editor->blockCheckBoxSignals(true); + editor->setChecked(value); + editor->blockCheckBoxSignals(false); + } +} + +void QtCheckBoxFactoryPrivate::slotSetValue(bool value) +{ + QObject *object = q_ptr->sender(); + + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtBoolPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtCheckBoxFactory + + \brief The QtCheckBoxFactory class provides QCheckBox widgets for + properties created by QtBoolPropertyManager objects. + + \sa QtAbstractEditorFactory, QtBoolPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtCheckBoxFactory::QtCheckBoxFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtCheckBoxFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtCheckBoxFactory::~QtCheckBoxFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtCheckBoxFactory::connectPropertyManager(QtBoolPropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, bool)), + this, SLOT(slotPropertyChanged(QtProperty *, bool))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtCheckBoxFactory::createEditor(QtBoolPropertyManager *manager, QtProperty *property, + QWidget *parent) +{ + QtBoolEdit *editor = d_ptr->createEditor(property, parent); + editor->setChecked(manager->value(property)); + + connect(editor, SIGNAL(toggled(bool)), this, SLOT(slotSetValue(bool))); + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtCheckBoxFactory::disconnectPropertyManager(QtBoolPropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, bool)), + this, SLOT(slotPropertyChanged(QtProperty *, bool))); +} + +// QtDoubleSpinBoxFactory + +class QtDoubleSpinBoxFactoryPrivate : public EditorFactoryPrivate +{ + QtDoubleSpinBoxFactory *q_ptr; + Q_DECLARE_PUBLIC(QtDoubleSpinBoxFactory) +public: + + void slotPropertyChanged(QtProperty *property, double value); + void slotRangeChanged(QtProperty *property, double min, double max); + void slotSingleStepChanged(QtProperty *property, double step); + void slotDecimalsChanged(QtProperty *property, int prec); + void slotSetValue(double value); +}; + +void QtDoubleSpinBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, double value) +{ + QList editors = m_createdEditors[property]; + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QDoubleSpinBox *editor = itEditor.next(); + if (editor->value() != value) { + editor->blockSignals(true); + editor->setValue(value); + editor->blockSignals(false); + } + } +} + +void QtDoubleSpinBoxFactoryPrivate::slotRangeChanged(QtProperty *property, + double min, double max) +{ + if (!m_createdEditors.contains(property)) + return; + + QtDoublePropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + + QList editors = m_createdEditors[property]; + QListIterator itEditor(editors); + while (itEditor.hasNext()) { + QDoubleSpinBox *editor = itEditor.next(); + editor->blockSignals(true); + editor->setRange(min, max); + editor->setValue(manager->value(property)); + editor->blockSignals(false); + } +} + +void QtDoubleSpinBoxFactoryPrivate::slotSingleStepChanged(QtProperty *property, double step) +{ + if (!m_createdEditors.contains(property)) + return; + + QtDoublePropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + + QList editors = m_createdEditors[property]; + QListIterator itEditor(editors); + while (itEditor.hasNext()) { + QDoubleSpinBox *editor = itEditor.next(); + editor->blockSignals(true); + editor->setSingleStep(step); + editor->blockSignals(false); + } +} + +void QtDoubleSpinBoxFactoryPrivate::slotDecimalsChanged(QtProperty *property, int prec) +{ + if (!m_createdEditors.contains(property)) + return; + + QtDoublePropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + + QList editors = m_createdEditors[property]; + QListIterator itEditor(editors); + while (itEditor.hasNext()) { + QDoubleSpinBox *editor = itEditor.next(); + editor->blockSignals(true); + editor->setDecimals(prec); + editor->setValue(manager->value(property)); + editor->blockSignals(false); + } +} + +void QtDoubleSpinBoxFactoryPrivate::slotSetValue(double value) +{ + QObject *object = q_ptr->sender(); + const QMap::ConstIterator itcend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != itcend; ++itEditor) { + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtDoublePropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } + } +} + +/*! \class QtDoubleSpinBoxFactory + + \brief The QtDoubleSpinBoxFactory class provides QDoubleSpinBox + widgets for properties created by QtDoublePropertyManager objects. + + \sa QtAbstractEditorFactory, QtDoublePropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtDoubleSpinBoxFactory::QtDoubleSpinBoxFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtDoubleSpinBoxFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtDoubleSpinBoxFactory::~QtDoubleSpinBoxFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtDoubleSpinBoxFactory::connectPropertyManager(QtDoublePropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, double)), + this, SLOT(slotPropertyChanged(QtProperty *, double))); + connect(manager, SIGNAL(rangeChanged(QtProperty *, double, double)), + this, SLOT(slotRangeChanged(QtProperty *, double, double))); + connect(manager, SIGNAL(singleStepChanged(QtProperty *, double)), + this, SLOT(slotSingleStepChanged(QtProperty *, double))); + connect(manager, SIGNAL(decimalsChanged(QtProperty *, int)), + this, SLOT(slotDecimalsChanged(QtProperty *, int))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtDoubleSpinBoxFactory::createEditor(QtDoublePropertyManager *manager, + QtProperty *property, QWidget *parent) +{ + QDoubleSpinBox *editor = d_ptr->createEditor(property, parent); + editor->setSingleStep(manager->singleStep(property)); + editor->setDecimals(6); + editor->setRange(manager->minimum(property), manager->maximum(property)); + editor->setValue(manager->value(property)); + editor->setKeyboardTracking(false); + + connect(editor, SIGNAL(valueChanged(double)), this, SLOT(slotSetValue(double))); + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtDoubleSpinBoxFactory::disconnectPropertyManager(QtDoublePropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, double)), + this, SLOT(slotPropertyChanged(QtProperty *, double))); + disconnect(manager, SIGNAL(rangeChanged(QtProperty *, double, double)), + this, SLOT(slotRangeChanged(QtProperty *, double, double))); + disconnect(manager, SIGNAL(singleStepChanged(QtProperty *, double)), + this, SLOT(slotSingleStepChanged(QtProperty *, double))); + disconnect(manager, SIGNAL(decimalsChanged(QtProperty *, int)), + this, SLOT(slotDecimalsChanged(QtProperty *, int))); +} + +// QtLineEditFactory + +class QtLineEditFactoryPrivate : public EditorFactoryPrivate +{ + QtLineEditFactory *q_ptr; + Q_DECLARE_PUBLIC(QtLineEditFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QString &value); + void slotRegExpChanged(QtProperty *property, const QRegExp ®Exp); + void slotSetValue(const QString &value); + void slotEditingFinished(); +}; + +void QtLineEditFactoryPrivate::slotPropertyChanged(QtProperty *property, + const QString &value) +{ + if (!m_createdEditors.contains(property)) + return; + + QListIterator itEditor( m_createdEditors[property]); + while (itEditor.hasNext()) { + QLineEdit *editor = itEditor.next(); + if (editor->text() != value) + editor->setText(value); + } +} + +void QtLineEditFactoryPrivate::slotRegExpChanged(QtProperty *property, + const QRegExp ®Exp) +{ + if (!m_createdEditors.contains(property)) + return; + + QtStringPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QLineEdit *editor = itEditor.next(); + editor->blockSignals(true); + const QValidator *oldValidator = editor->validator(); + QValidator *newValidator = 0; + if (regExp.isValid()) { + newValidator = new QRegExpValidator(regExp, editor); + } + editor->setValidator(newValidator); + if (oldValidator) + delete oldValidator; + editor->blockSignals(false); + } +} + +void QtLineEditFactoryPrivate::slotSetValue(const QString &value) +{ + QObject *object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtStringPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +void QtLineEditFactoryPrivate::slotEditingFinished() +{ + QObject *object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtStringPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + QString value = static_cast(itEditor.key())->text(); + manager->setValue(property, value); + return; + } +} + +/*! + \class QtLineEditFactory + + \brief The QtLineEditFactory class provides QLineEdit widgets for + properties created by QtStringPropertyManager objects. + + \sa QtAbstractEditorFactory, QtStringPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtLineEditFactory::QtLineEditFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtLineEditFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtLineEditFactory::~QtLineEditFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtLineEditFactory::connectPropertyManager(QtStringPropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, const QString &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QString &))); + connect(manager, SIGNAL(regExpChanged(QtProperty *, const QRegExp &)), + this, SLOT(slotRegExpChanged(QtProperty *, const QRegExp &))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtLineEditFactory::createEditor(QtStringPropertyManager *manager, + QtProperty *property, QWidget *parent) +{ + + QLineEdit *editor = d_ptr->createEditor(property, parent); + QRegExp regExp = manager->regExp(property); + if (regExp.isValid()) { + QValidator *validator = new QRegExpValidator(regExp, editor); + editor->setValidator(validator); + } + editor->setText(manager->value(property)); + + connect(editor, SIGNAL(editingFinished()), + this, SLOT(slotEditingFinished())); + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtLineEditFactory::disconnectPropertyManager(QtStringPropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QString &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QString &))); + disconnect(manager, SIGNAL(regExpChanged(QtProperty *, const QRegExp &)), + this, SLOT(slotRegExpChanged(QtProperty *, const QRegExp &))); +} + +// QtDateEditFactory + +class QtDateEditFactoryPrivate : public EditorFactoryPrivate +{ + QtDateEditFactory *q_ptr; + Q_DECLARE_PUBLIC(QtDateEditFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QDate &value); + void slotRangeChanged(QtProperty *property, const QDate &min, const QDate &max); + void slotSetValue(const QDate &value); +}; + +void QtDateEditFactoryPrivate::slotPropertyChanged(QtProperty *property, const QDate &value) +{ + if (!m_createdEditors.contains(property)) + return; + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QDateEdit *editor = itEditor.next(); + editor->blockSignals(true); + editor->setDate(value); + editor->blockSignals(false); + } +} + +void QtDateEditFactoryPrivate::slotRangeChanged(QtProperty *property, + const QDate &min, const QDate &max) +{ + if (!m_createdEditors.contains(property)) + return; + + QtDatePropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QDateEdit *editor = itEditor.next(); + editor->blockSignals(true); + editor->setDateRange(min, max); + editor->setDate(manager->value(property)); + editor->blockSignals(false); + } +} + +void QtDateEditFactoryPrivate::slotSetValue(const QDate &value) +{ + QObject *object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtDatePropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtDateEditFactory + + \brief The QtDateEditFactory class provides QDateEdit widgets for + properties created by QtDatePropertyManager objects. + + \sa QtAbstractEditorFactory, QtDatePropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtDateEditFactory::QtDateEditFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtDateEditFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtDateEditFactory::~QtDateEditFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtDateEditFactory::connectPropertyManager(QtDatePropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, const QDate &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QDate &))); + connect(manager, SIGNAL(rangeChanged(QtProperty *, const QDate &, const QDate &)), + this, SLOT(slotRangeChanged(QtProperty *, const QDate &, const QDate &))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtDateEditFactory::createEditor(QtDatePropertyManager *manager, QtProperty *property, + QWidget *parent) +{ + QDateEdit *editor = d_ptr->createEditor(property, parent); + editor->setCalendarPopup(true); + editor->setDateRange(manager->minimum(property), manager->maximum(property)); + editor->setDate(manager->value(property)); + + connect(editor, SIGNAL(dateChanged(const QDate &)), + this, SLOT(slotSetValue(const QDate &))); + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtDateEditFactory::disconnectPropertyManager(QtDatePropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QDate &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QDate &))); + disconnect(manager, SIGNAL(rangeChanged(QtProperty *, const QDate &, const QDate &)), + this, SLOT(slotRangeChanged(QtProperty *, const QDate &, const QDate &))); +} + +// QtTimeEditFactory + +class QtTimeEditFactoryPrivate : public EditorFactoryPrivate +{ + QtTimeEditFactory *q_ptr; + Q_DECLARE_PUBLIC(QtTimeEditFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QTime &value); + void slotSetValue(const QTime &value); +}; + +void QtTimeEditFactoryPrivate::slotPropertyChanged(QtProperty *property, const QTime &value) +{ + if (!m_createdEditors.contains(property)) + return; + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QTimeEdit *editor = itEditor.next(); + editor->blockSignals(true); + editor->setTime(value); + editor->blockSignals(false); + } +} + +void QtTimeEditFactoryPrivate::slotSetValue(const QTime &value) +{ + QObject *object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtTimePropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtTimeEditFactory + + \brief The QtTimeEditFactory class provides QTimeEdit widgets for + properties created by QtTimePropertyManager objects. + + \sa QtAbstractEditorFactory, QtTimePropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtTimeEditFactory::QtTimeEditFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtTimeEditFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtTimeEditFactory::~QtTimeEditFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtTimeEditFactory::connectPropertyManager(QtTimePropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, const QTime &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QTime &))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtTimeEditFactory::createEditor(QtTimePropertyManager *manager, QtProperty *property, + QWidget *parent) +{ + QTimeEdit *editor = d_ptr->createEditor(property, parent); + editor->setTime(manager->value(property)); + + connect(editor, SIGNAL(timeChanged(const QTime &)), + this, SLOT(slotSetValue(const QTime &))); + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtTimeEditFactory::disconnectPropertyManager(QtTimePropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QTime &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QTime &))); +} + +// QtDateTimeEditFactory + +class QtDateTimeEditFactoryPrivate : public EditorFactoryPrivate +{ + QtDateTimeEditFactory *q_ptr; + Q_DECLARE_PUBLIC(QtDateTimeEditFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QDateTime &value); + void slotSetValue(const QDateTime &value); + +}; + +void QtDateTimeEditFactoryPrivate::slotPropertyChanged(QtProperty *property, + const QDateTime &value) +{ + if (!m_createdEditors.contains(property)) + return; + + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QDateTimeEdit *editor = itEditor.next(); + editor->blockSignals(true); + editor->setDateTime(value); + editor->blockSignals(false); + } +} + +void QtDateTimeEditFactoryPrivate::slotSetValue(const QDateTime &value) +{ + QObject *object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtDateTimePropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtDateTimeEditFactory + + \brief The QtDateTimeEditFactory class provides QDateTimeEdit + widgets for properties created by QtDateTimePropertyManager objects. + + \sa QtAbstractEditorFactory, QtDateTimePropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtDateTimeEditFactory::QtDateTimeEditFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtDateTimeEditFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtDateTimeEditFactory::~QtDateTimeEditFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtDateTimeEditFactory::connectPropertyManager(QtDateTimePropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, const QDateTime &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QDateTime &))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtDateTimeEditFactory::createEditor(QtDateTimePropertyManager *manager, + QtProperty *property, QWidget *parent) +{ + QDateTimeEdit *editor = d_ptr->createEditor(property, parent); + editor->setDateTime(manager->value(property)); + + connect(editor, SIGNAL(dateTimeChanged(const QDateTime &)), + this, SLOT(slotSetValue(const QDateTime &))); + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtDateTimeEditFactory::disconnectPropertyManager(QtDateTimePropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QDateTime &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QDateTime &))); +} + +// QtKeySequenceEditorFactory + +class QtKeySequenceEditorFactoryPrivate : public EditorFactoryPrivate +{ + QtKeySequenceEditorFactory *q_ptr; + Q_DECLARE_PUBLIC(QtKeySequenceEditorFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QKeySequence &value); + void slotSetValue(const QKeySequence &value); +}; + +void QtKeySequenceEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, + const QKeySequence &value) +{ + if (!m_createdEditors.contains(property)) + return; + + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QtKeySequenceEdit *editor = itEditor.next(); + editor->blockSignals(true); + editor->setKeySequence(value); + editor->blockSignals(false); + } +} + +void QtKeySequenceEditorFactoryPrivate::slotSetValue(const QKeySequence &value) +{ + QObject *object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtKeySequencePropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtKeySequenceEditorFactory + + \brief The QtKeySequenceEditorFactory class provides editor + widgets for properties created by QtKeySequencePropertyManager objects. + + \sa QtAbstractEditorFactory +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtKeySequenceEditorFactory::QtKeySequenceEditorFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtKeySequenceEditorFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtKeySequenceEditorFactory::~QtKeySequenceEditorFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtKeySequenceEditorFactory::connectPropertyManager(QtKeySequencePropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, const QKeySequence &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QKeySequence &))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtKeySequenceEditorFactory::createEditor(QtKeySequencePropertyManager *manager, + QtProperty *property, QWidget *parent) +{ + QtKeySequenceEdit *editor = d_ptr->createEditor(property, parent); + editor->setKeySequence(manager->value(property)); + + connect(editor, SIGNAL(keySequenceChanged(const QKeySequence &)), + this, SLOT(slotSetValue(const QKeySequence &))); + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtKeySequenceEditorFactory::disconnectPropertyManager(QtKeySequencePropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QKeySequence &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QKeySequence &))); +} + +// QtCharEdit + +class QtCharEdit : public QWidget +{ + Q_OBJECT +public: + QtCharEdit(QWidget *parent = 0); + + QChar value() const; + bool eventFilter(QObject *o, QEvent *e); +public Q_SLOTS: + void setValue(const QChar &value); +Q_SIGNALS: + void valueChanged(const QChar &value); +protected: + void focusInEvent(QFocusEvent *e); + void focusOutEvent(QFocusEvent *e); + void keyPressEvent(QKeyEvent *e); + void keyReleaseEvent(QKeyEvent *e); + bool event(QEvent *e); +private slots: + void slotClearChar(); +private: + void handleKeyEvent(QKeyEvent *e); + + QChar m_value; + QLineEdit *m_lineEdit; +}; + +QtCharEdit::QtCharEdit(QWidget *parent) + : QWidget(parent), m_lineEdit(new QLineEdit(this)) +{ + QHBoxLayout *layout = new QHBoxLayout(this); + layout->addWidget(m_lineEdit); + layout->setMargin(0); + m_lineEdit->installEventFilter(this); + m_lineEdit->setReadOnly(true); + m_lineEdit->setFocusProxy(this); + setFocusPolicy(m_lineEdit->focusPolicy()); + setAttribute(Qt::WA_InputMethodEnabled); +} + +bool QtCharEdit::eventFilter(QObject *o, QEvent *e) +{ + if (o == m_lineEdit && e->type() == QEvent::ContextMenu) { + QContextMenuEvent *c = static_cast(e); + QMenu *menu = m_lineEdit->createStandardContextMenu(); + QList actions = menu->actions(); + QListIterator itAction(actions); + while (itAction.hasNext()) { + QAction *action = itAction.next(); + action->setShortcut(QKeySequence()); + QString actionString = action->text(); + const int pos = actionString.lastIndexOf(QLatin1Char('\t')); + if (pos > 0) + actionString = actionString.remove(pos, actionString.length() - pos); + action->setText(actionString); + } + QAction *actionBefore = 0; + if (actions.count() > 0) + actionBefore = actions[0]; + QAction *clearAction = new QAction(tr("Clear Char"), menu); + menu->insertAction(actionBefore, clearAction); + menu->insertSeparator(actionBefore); + clearAction->setEnabled(!m_value.isNull()); + connect(clearAction, SIGNAL(triggered()), this, SLOT(slotClearChar())); + menu->exec(c->globalPos()); + delete menu; + e->accept(); + return true; + } + + return QWidget::eventFilter(o, e); +} + +void QtCharEdit::slotClearChar() +{ + if (m_value.isNull()) + return; + setValue(QChar()); + emit valueChanged(m_value); +} + +void QtCharEdit::handleKeyEvent(QKeyEvent *e) +{ + const int key = e->key(); + switch (key) { + case Qt::Key_Control: + case Qt::Key_Shift: + case Qt::Key_Meta: + case Qt::Key_Alt: + case Qt::Key_Super_L: + case Qt::Key_Return: + return; + default: + break; + } + + const QString text = e->text(); + if (text.count() != 1) + return; + + const QChar c = text.at(0); + if (!c.isPrint()) + return; + + if (m_value == c) + return; + + m_value = c; + const QString str = m_value.isNull() ? QString() : QString(m_value); + m_lineEdit->setText(str); + e->accept(); + emit valueChanged(m_value); +} + +void QtCharEdit::setValue(const QChar &value) +{ + if (value == m_value) + return; + + m_value = value; + QString str = value.isNull() ? QString() : QString(value); + m_lineEdit->setText(str); +} + +QChar QtCharEdit::value() const +{ + return m_value; +} + +void QtCharEdit::focusInEvent(QFocusEvent *e) +{ + m_lineEdit->event(e); + m_lineEdit->selectAll(); + QWidget::focusInEvent(e); +} + +void QtCharEdit::focusOutEvent(QFocusEvent *e) +{ + m_lineEdit->event(e); + QWidget::focusOutEvent(e); +} + +void QtCharEdit::keyPressEvent(QKeyEvent *e) +{ + handleKeyEvent(e); + e->accept(); +} + +void QtCharEdit::keyReleaseEvent(QKeyEvent *e) +{ + m_lineEdit->event(e); +} + +bool QtCharEdit::event(QEvent *e) +{ + switch(e->type()) { + case QEvent::Shortcut: + case QEvent::ShortcutOverride: + case QEvent::KeyRelease: + e->accept(); + return true; + default: + break; + } + return QWidget::event(e); +} + +// QtCharEditorFactory + +class QtCharEditorFactoryPrivate : public EditorFactoryPrivate +{ + QtCharEditorFactory *q_ptr; + Q_DECLARE_PUBLIC(QtCharEditorFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QChar &value); + void slotSetValue(const QChar &value); + +}; + +void QtCharEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, + const QChar &value) +{ + if (!m_createdEditors.contains(property)) + return; + + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QtCharEdit *editor = itEditor.next(); + editor->blockSignals(true); + editor->setValue(value); + editor->blockSignals(false); + } +} + +void QtCharEditorFactoryPrivate::slotSetValue(const QChar &value) +{ + QObject *object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtCharPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtCharEditorFactory + + \brief The QtCharEditorFactory class provides editor + widgets for properties created by QtCharPropertyManager objects. + + \sa QtAbstractEditorFactory +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtCharEditorFactory::QtCharEditorFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtCharEditorFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtCharEditorFactory::~QtCharEditorFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtCharEditorFactory::connectPropertyManager(QtCharPropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, const QChar &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QChar &))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtCharEditorFactory::createEditor(QtCharPropertyManager *manager, + QtProperty *property, QWidget *parent) +{ + QtCharEdit *editor = d_ptr->createEditor(property, parent); + editor->setValue(manager->value(property)); + + connect(editor, SIGNAL(valueChanged(const QChar &)), + this, SLOT(slotSetValue(const QChar &))); + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtCharEditorFactory::disconnectPropertyManager(QtCharPropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QChar &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QChar &))); +} + +// QtEnumEditorFactory + +class QtEnumEditorFactoryPrivate : public EditorFactoryPrivate +{ + QtEnumEditorFactory *q_ptr; + Q_DECLARE_PUBLIC(QtEnumEditorFactory) +public: + + void slotPropertyChanged(QtProperty *property, int value); + void slotEnumNamesChanged(QtProperty *property, const QStringList &); + void slotEnumIconsChanged(QtProperty *property, const QMap &); + void slotSetValue(int value); +}; + +void QtEnumEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, int value) +{ + if (!m_createdEditors.contains(property)) + return; + + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QComboBox *editor = itEditor.next(); + editor->blockSignals(true); + editor->setCurrentIndex(value); + editor->blockSignals(false); + } +} + +void QtEnumEditorFactoryPrivate::slotEnumNamesChanged(QtProperty *property, + const QStringList &enumNames) +{ + if (!m_createdEditors.contains(property)) + return; + + QtEnumPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + + QMap enumIcons = manager->enumIcons(property); + + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QComboBox *editor = itEditor.next(); + editor->blockSignals(true); + editor->clear(); + editor->addItems(enumNames); + const int nameCount = enumNames.count(); + for (int i = 0; i < nameCount; i++) + editor->setItemIcon(i, enumIcons.value(i)); + editor->setCurrentIndex(manager->value(property)); + editor->blockSignals(false); + } +} + +void QtEnumEditorFactoryPrivate::slotEnumIconsChanged(QtProperty *property, + const QMap &enumIcons) +{ + if (!m_createdEditors.contains(property)) + return; + + QtEnumPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + + const QStringList enumNames = manager->enumNames(property); + QListIterator itEditor(m_createdEditors[property]); + while (itEditor.hasNext()) { + QComboBox *editor = itEditor.next(); + editor->blockSignals(true); + const int nameCount = enumNames.count(); + for (int i = 0; i < nameCount; i++) + editor->setItemIcon(i, enumIcons.value(i)); + editor->setCurrentIndex(manager->value(property)); + editor->blockSignals(false); + } +} + +void QtEnumEditorFactoryPrivate::slotSetValue(int value) +{ + QObject *object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtEnumPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtEnumEditorFactory + + \brief The QtEnumEditorFactory class provides QComboBox widgets for + properties created by QtEnumPropertyManager objects. + + \sa QtAbstractEditorFactory, QtEnumPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtEnumEditorFactory::QtEnumEditorFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtEnumEditorFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtEnumEditorFactory::~QtEnumEditorFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtEnumEditorFactory::connectPropertyManager(QtEnumPropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotPropertyChanged(QtProperty *, int))); + connect(manager, SIGNAL(enumNamesChanged(QtProperty *, const QStringList &)), + this, SLOT(slotEnumNamesChanged(QtProperty *, const QStringList &))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtEnumEditorFactory::createEditor(QtEnumPropertyManager *manager, QtProperty *property, + QWidget *parent) +{ + QComboBox *editor = d_ptr->createEditor(property, parent); + editor->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); + editor->view()->setTextElideMode(Qt::ElideRight); + QStringList enumNames = manager->enumNames(property); + editor->addItems(enumNames); + QMap enumIcons = manager->enumIcons(property); + const int enumNamesCount = enumNames.count(); + for (int i = 0; i < enumNamesCount; i++) + editor->setItemIcon(i, enumIcons.value(i)); + editor->setCurrentIndex(manager->value(property)); + + connect(editor, SIGNAL(currentIndexChanged(int)), this, SLOT(slotSetValue(int))); + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtEnumEditorFactory::disconnectPropertyManager(QtEnumPropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotPropertyChanged(QtProperty *, int))); + disconnect(manager, SIGNAL(enumNamesChanged(QtProperty *, const QStringList &)), + this, SLOT(slotEnumNamesChanged(QtProperty *, const QStringList &))); +} + +// QtCursorEditorFactory + +Q_GLOBAL_STATIC(QtCursorDatabase, cursorDatabase) + +class QtCursorEditorFactoryPrivate +{ + QtCursorEditorFactory *q_ptr; + Q_DECLARE_PUBLIC(QtCursorEditorFactory) +public: + QtCursorEditorFactoryPrivate(); + + void slotPropertyChanged(QtProperty *property, const QCursor &cursor); + void slotEnumChanged(QtProperty *property, int value); + void slotEditorDestroyed(QObject *object); + + QtEnumEditorFactory *m_enumEditorFactory; + QtEnumPropertyManager *m_enumPropertyManager; + + QMap m_propertyToEnum; + QMap m_enumToProperty; + QMap > m_enumToEditors; + QMap m_editorToEnum; + bool m_updatingEnum; +}; + +QtCursorEditorFactoryPrivate::QtCursorEditorFactoryPrivate() + : m_updatingEnum(false) +{ + +} + +void QtCursorEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, const QCursor &cursor) +{ + // update enum property + QtProperty *enumProp = m_propertyToEnum.value(property); + if (!enumProp) + return; + + m_updatingEnum = true; + m_enumPropertyManager->setValue(enumProp, cursorDatabase()->cursorToValue(cursor)); + m_updatingEnum = false; +} + +void QtCursorEditorFactoryPrivate::slotEnumChanged(QtProperty *property, int value) +{ + if (m_updatingEnum) + return; + // update cursor property + QtProperty *prop = m_enumToProperty.value(property); + if (!prop) + return; + QtCursorPropertyManager *cursorManager = q_ptr->propertyManager(prop); + if (!cursorManager) + return; +#ifndef QT_NO_CURSOR + cursorManager->setValue(prop, QCursor(cursorDatabase()->valueToCursor(value))); +#endif +} + +void QtCursorEditorFactoryPrivate::slotEditorDestroyed(QObject *object) +{ + // remove from m_editorToEnum map; + // remove from m_enumToEditors map; + // if m_enumToEditors doesn't contains more editors delete enum property; + const QMap::ConstIterator ecend = m_editorToEnum.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToEnum.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QWidget *editor = itEditor.key(); + QtProperty *enumProp = itEditor.value(); + m_editorToEnum.remove(editor); + m_enumToEditors[enumProp].removeAll(editor); + if (m_enumToEditors[enumProp].isEmpty()) { + m_enumToEditors.remove(enumProp); + QtProperty *property = m_enumToProperty.value(enumProp); + m_enumToProperty.remove(enumProp); + m_propertyToEnum.remove(property); + delete enumProp; + } + return; + } +} + +/*! + \class QtCursorEditorFactory + + \brief The QtCursorEditorFactory class provides QComboBox widgets for + properties created by QtCursorPropertyManager objects. + + \sa QtAbstractEditorFactory, QtCursorPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtCursorEditorFactory::QtCursorEditorFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtCursorEditorFactoryPrivate(); + d_ptr->q_ptr = this; + + d_ptr->m_enumEditorFactory = new QtEnumEditorFactory(this); + d_ptr->m_enumPropertyManager = new QtEnumPropertyManager(this); + connect(d_ptr->m_enumPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotEnumChanged(QtProperty *, int))); + d_ptr->m_enumEditorFactory->addPropertyManager(d_ptr->m_enumPropertyManager); +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtCursorEditorFactory::~QtCursorEditorFactory() +{ + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtCursorEditorFactory::connectPropertyManager(QtCursorPropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, const QCursor &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QCursor &))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtCursorEditorFactory::createEditor(QtCursorPropertyManager *manager, QtProperty *property, + QWidget *parent) +{ + QtProperty *enumProp = 0; + if (d_ptr->m_propertyToEnum.contains(property)) { + enumProp = d_ptr->m_propertyToEnum[property]; + } else { + enumProp = d_ptr->m_enumPropertyManager->addProperty(property->propertyName()); + d_ptr->m_enumPropertyManager->setEnumNames(enumProp, cursorDatabase()->cursorShapeNames()); + d_ptr->m_enumPropertyManager->setEnumIcons(enumProp, cursorDatabase()->cursorShapeIcons()); +#ifndef QT_NO_CURSOR + d_ptr->m_enumPropertyManager->setValue(enumProp, cursorDatabase()->cursorToValue(manager->value(property))); +#endif + d_ptr->m_propertyToEnum[property] = enumProp; + d_ptr->m_enumToProperty[enumProp] = property; + } + QtAbstractEditorFactoryBase *af = d_ptr->m_enumEditorFactory; + QWidget *editor = af->createEditor(enumProp, parent); + d_ptr->m_enumToEditors[enumProp].append(editor); + d_ptr->m_editorToEnum[editor] = enumProp; + connect(editor, SIGNAL(destroyed(QObject *)), + this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtCursorEditorFactory::disconnectPropertyManager(QtCursorPropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QCursor &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QCursor &))); +} + +// QtColorEditWidget + +class QtColorEditWidget : public QWidget { + Q_OBJECT + +public: + QtColorEditWidget(QWidget *parent); + + bool eventFilter(QObject *obj, QEvent *ev); + +public Q_SLOTS: + void setValue(const QColor &value); + +private Q_SLOTS: + void buttonClicked(); + +Q_SIGNALS: + void valueChanged(const QColor &value); + +private: + QColor m_color; + QLabel *m_pixmapLabel; + QLabel *m_label; + QToolButton *m_button; +}; + +QtColorEditWidget::QtColorEditWidget(QWidget *parent) : + QWidget(parent), + m_pixmapLabel(new QLabel), + m_label(new QLabel), + m_button(new QToolButton) +{ + QHBoxLayout *lt = new QHBoxLayout(this); + setupTreeViewEditorMargin(lt); + lt->setSpacing(0); + lt->addWidget(m_pixmapLabel); + lt->addWidget(m_label); + lt->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored)); + + m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored); + m_button->setFixedWidth(20); + setFocusProxy(m_button); + setFocusPolicy(m_button->focusPolicy()); + m_button->setText(tr("...")); + m_button->installEventFilter(this); + connect(m_button, SIGNAL(clicked()), this, SLOT(buttonClicked())); + lt->addWidget(m_button); + m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::brushValuePixmap(QBrush(m_color))); + m_label->setText(QtPropertyBrowserUtils::colorValueText(m_color)); +} + +void QtColorEditWidget::setValue(const QColor &c) +{ + if (m_color != c) { + m_color = c; + m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::brushValuePixmap(QBrush(c))); + m_label->setText(QtPropertyBrowserUtils::colorValueText(c)); + } +} + +void QtColorEditWidget::buttonClicked() +{ + bool ok = false; + QRgb oldRgba = m_color.rgba(); + QRgb newRgba = QColorDialog::getRgba(oldRgba, &ok, this); + if (ok && newRgba != oldRgba) { + setValue(QColor::fromRgba(newRgba)); + emit valueChanged(m_color); + } +} + +bool QtColorEditWidget::eventFilter(QObject *obj, QEvent *ev) +{ + if (obj == m_button) { + switch (ev->type()) { + case QEvent::KeyPress: + case QEvent::KeyRelease: { // Prevent the QToolButton from handling Enter/Escape meant control the delegate + switch (static_cast(ev)->key()) { + case Qt::Key_Escape: + case Qt::Key_Enter: + case Qt::Key_Return: + ev->ignore(); + return true; + default: + break; + } + } + break; + default: + break; + } + } + return QWidget::eventFilter(obj, ev); +} + +// QtColorEditorFactoryPrivate + +class QtColorEditorFactoryPrivate : public EditorFactoryPrivate +{ + QtColorEditorFactory *q_ptr; + Q_DECLARE_PUBLIC(QtColorEditorFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QColor &value); + void slotSetValue(const QColor &value); +}; + +void QtColorEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, + const QColor &value) +{ + const PropertyToEditorListMap::iterator it = m_createdEditors.find(property); + if (it == m_createdEditors.end()) + return; + QListIterator itEditor(it.value()); + + while (itEditor.hasNext()) + itEditor.next()->setValue(value); +} + +void QtColorEditorFactoryPrivate::slotSetValue(const QColor &value) +{ + QObject *object = q_ptr->sender(); + const EditorToPropertyMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (EditorToPropertyMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtColorPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtColorEditorFactory + + \brief The QtColorEditorFactory class provides color editing for + properties created by QtColorPropertyManager objects. + + \sa QtAbstractEditorFactory, QtColorPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtColorEditorFactory::QtColorEditorFactory(QObject *parent) : + QtAbstractEditorFactory(parent), + d_ptr(new QtColorEditorFactoryPrivate()) +{ + d_ptr->q_ptr = this; +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtColorEditorFactory::~QtColorEditorFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtColorEditorFactory::connectPropertyManager(QtColorPropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty*,QColor)), + this, SLOT(slotPropertyChanged(QtProperty*,QColor))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtColorEditorFactory::createEditor(QtColorPropertyManager *manager, + QtProperty *property, QWidget *parent) +{ + QtColorEditWidget *editor = d_ptr->createEditor(property, parent); + editor->setValue(manager->value(property)); + connect(editor, SIGNAL(valueChanged(QColor)), this, SLOT(slotSetValue(QColor))); + connect(editor, SIGNAL(destroyed(QObject *)), this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtColorEditorFactory::disconnectPropertyManager(QtColorPropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty*,QColor)), this, SLOT(slotPropertyChanged(QtProperty*,QColor))); +} + +// QtFontEditWidget + +class QtFontEditWidget : public QWidget { + Q_OBJECT + +public: + QtFontEditWidget(QWidget *parent); + + bool eventFilter(QObject *obj, QEvent *ev); + +public Q_SLOTS: + void setValue(const QFont &value); + +private Q_SLOTS: + void buttonClicked(); + +Q_SIGNALS: + void valueChanged(const QFont &value); + +private: + QFont m_font; + QLabel *m_pixmapLabel; + QLabel *m_label; + QToolButton *m_button; +}; + +QtFontEditWidget::QtFontEditWidget(QWidget *parent) : + QWidget(parent), + m_pixmapLabel(new QLabel), + m_label(new QLabel), + m_button(new QToolButton) +{ + QHBoxLayout *lt = new QHBoxLayout(this); + setupTreeViewEditorMargin(lt); + lt->setSpacing(0); + lt->addWidget(m_pixmapLabel); + lt->addWidget(m_label); + lt->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored)); + + m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored); + m_button->setFixedWidth(20); + setFocusProxy(m_button); + setFocusPolicy(m_button->focusPolicy()); + m_button->setText(tr("...")); + m_button->installEventFilter(this); + connect(m_button, SIGNAL(clicked()), this, SLOT(buttonClicked())); + lt->addWidget(m_button); + m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::fontValuePixmap(m_font)); + m_label->setText(QtPropertyBrowserUtils::fontValueText(m_font)); +} + +void QtFontEditWidget::setValue(const QFont &f) +{ + if (m_font != f) { + m_font = f; + m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::fontValuePixmap(f)); + m_label->setText(QtPropertyBrowserUtils::fontValueText(f)); + } +} + +void QtFontEditWidget::buttonClicked() +{ + bool ok = false; + QFont newFont = QFontDialog::getFont(&ok, m_font, this, tr("Select Font")); + if (ok && newFont != m_font) { + QFont f = m_font; + // prevent mask for unchanged attributes, don't change other attributes (like kerning, etc...) + if (m_font.family() != newFont.family()) + f.setFamily(newFont.family()); + if (m_font.pointSize() != newFont.pointSize()) + f.setPointSize(newFont.pointSize()); + if (m_font.bold() != newFont.bold()) + f.setBold(newFont.bold()); + if (m_font.italic() != newFont.italic()) + f.setItalic(newFont.italic()); + if (m_font.underline() != newFont.underline()) + f.setUnderline(newFont.underline()); + if (m_font.strikeOut() != newFont.strikeOut()) + f.setStrikeOut(newFont.strikeOut()); + setValue(f); + emit valueChanged(m_font); + } +} + +bool QtFontEditWidget::eventFilter(QObject *obj, QEvent *ev) +{ + if (obj == m_button) { + switch (ev->type()) { + case QEvent::KeyPress: + case QEvent::KeyRelease: { // Prevent the QToolButton from handling Enter/Escape meant control the delegate + switch (static_cast(ev)->key()) { + case Qt::Key_Escape: + case Qt::Key_Enter: + case Qt::Key_Return: + ev->ignore(); + return true; + default: + break; + } + } + break; + default: + break; + } + } + return QWidget::eventFilter(obj, ev); +} + +// QtFontEditorFactoryPrivate + +class QtFontEditorFactoryPrivate : public EditorFactoryPrivate +{ + QtFontEditorFactory *q_ptr; + Q_DECLARE_PUBLIC(QtFontEditorFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QFont &value); + void slotSetValue(const QFont &value); +}; + +void QtFontEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, + const QFont &value) +{ + const PropertyToEditorListMap::iterator it = m_createdEditors.find(property); + if (it == m_createdEditors.end()) + return; + QListIterator itEditor(it.value()); + + while (itEditor.hasNext()) + itEditor.next()->setValue(value); +} + +void QtFontEditorFactoryPrivate::slotSetValue(const QFont &value) +{ + QObject *object = q_ptr->sender(); + const EditorToPropertyMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (EditorToPropertyMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtFontPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtFontEditorFactory + + \brief The QtFontEditorFactory class provides font editing for + properties created by QtFontPropertyManager objects. + + \sa QtAbstractEditorFactory, QtFontPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtFontEditorFactory::QtFontEditorFactory(QObject *parent) : + QtAbstractEditorFactory(parent), + d_ptr(new QtFontEditorFactoryPrivate()) +{ + d_ptr->q_ptr = this; +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtFontEditorFactory::~QtFontEditorFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtFontEditorFactory::connectPropertyManager(QtFontPropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty*,QFont)), + this, SLOT(slotPropertyChanged(QtProperty*,QFont))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtFontEditorFactory::createEditor(QtFontPropertyManager *manager, + QtProperty *property, QWidget *parent) +{ + QtFontEditWidget *editor = d_ptr->createEditor(property, parent); + editor->setValue(manager->value(property)); + connect(editor, SIGNAL(valueChanged(QFont)), this, SLOT(slotSetValue(QFont))); + connect(editor, SIGNAL(destroyed(QObject *)), this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtFontEditorFactory::disconnectPropertyManager(QtFontPropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty*,QFont)), this, SLOT(slotPropertyChanged(QtProperty*,QFont))); +} + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +#include "moc_qteditorfactory.cxx" +#include "qteditorfactory.moc" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.h b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.h new file mode 100644 index 000000000..47e7b507f --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.h @@ -0,0 +1,448 @@ +/**************************************************************************** +** +** This file is part of a Qt Solutions component. +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTEDITORFACTORY_H +#define QTEDITORFACTORY_H + +#include "qtpropertymanager.h" + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +class QtSpinBoxFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtSpinBoxFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtSpinBoxFactory(QObject *parent = 0); + ~QtSpinBoxFactory(); +protected: + void connectPropertyManager(QtIntPropertyManager *manager); + QWidget *createEditor(QtIntPropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtIntPropertyManager *manager); +private: + QtSpinBoxFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtSpinBoxFactory) + Q_DISABLE_COPY(QtSpinBoxFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, int, int)) + Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(int)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtSliderFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtSliderFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtSliderFactory(QObject *parent = 0); + ~QtSliderFactory(); +protected: + void connectPropertyManager(QtIntPropertyManager *manager); + QWidget *createEditor(QtIntPropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtIntPropertyManager *manager); +private: + QtSliderFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtSliderFactory) + Q_DISABLE_COPY(QtSliderFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, int, int)) + Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(int)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtScrollBarFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtScrollBarFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtScrollBarFactory(QObject *parent = 0); + ~QtScrollBarFactory(); +protected: + void connectPropertyManager(QtIntPropertyManager *manager); + QWidget *createEditor(QtIntPropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtIntPropertyManager *manager); +private: + QtScrollBarFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtScrollBarFactory) + Q_DISABLE_COPY(QtScrollBarFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, int, int)) + Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(int)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtCheckBoxFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtCheckBoxFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtCheckBoxFactory(QObject *parent = 0); + ~QtCheckBoxFactory(); +protected: + void connectPropertyManager(QtBoolPropertyManager *manager); + QWidget *createEditor(QtBoolPropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtBoolPropertyManager *manager); +private: + QtCheckBoxFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtCheckBoxFactory) + Q_DISABLE_COPY(QtCheckBoxFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, bool)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(bool)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtDoubleSpinBoxFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtDoubleSpinBoxFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtDoubleSpinBoxFactory(QObject *parent = 0); + ~QtDoubleSpinBoxFactory(); +protected: + void connectPropertyManager(QtDoublePropertyManager *manager); + QWidget *createEditor(QtDoublePropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtDoublePropertyManager *manager); +private: + QtDoubleSpinBoxFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtDoubleSpinBoxFactory) + Q_DISABLE_COPY(QtDoubleSpinBoxFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, double)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, double, double)) + Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, double)) + Q_PRIVATE_SLOT(d_func(), void slotDecimalsChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(double)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtLineEditFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtLineEditFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtLineEditFactory(QObject *parent = 0); + ~QtLineEditFactory(); +protected: + void connectPropertyManager(QtStringPropertyManager *manager); + QWidget *createEditor(QtStringPropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtStringPropertyManager *manager); +private: + QtLineEditFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtLineEditFactory) + Q_DISABLE_COPY(QtLineEditFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QString &)) + Q_PRIVATE_SLOT(d_func(), void slotRegExpChanged(QtProperty *, const QRegExp &)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QString &)) + Q_PRIVATE_SLOT(d_func(), void slotEditingFinished()) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtDateEditFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtDateEditFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtDateEditFactory(QObject *parent = 0); + ~QtDateEditFactory(); +protected: + void connectPropertyManager(QtDatePropertyManager *manager); + QWidget *createEditor(QtDatePropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtDatePropertyManager *manager); +private: + QtDateEditFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtDateEditFactory) + Q_DISABLE_COPY(QtDateEditFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QDate &)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, + const QDate &, const QDate &)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QDate &)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtTimeEditFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtTimeEditFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtTimeEditFactory(QObject *parent = 0); + ~QtTimeEditFactory(); +protected: + void connectPropertyManager(QtTimePropertyManager *manager); + QWidget *createEditor(QtTimePropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtTimePropertyManager *manager); +private: + QtTimeEditFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtTimeEditFactory) + Q_DISABLE_COPY(QtTimeEditFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QTime &)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QTime &)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtDateTimeEditFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtDateTimeEditFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtDateTimeEditFactory(QObject *parent = 0); + ~QtDateTimeEditFactory(); +protected: + void connectPropertyManager(QtDateTimePropertyManager *manager); + QWidget *createEditor(QtDateTimePropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtDateTimePropertyManager *manager); +private: + QtDateTimeEditFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtDateTimeEditFactory) + Q_DISABLE_COPY(QtDateTimeEditFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QDateTime &)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QDateTime &)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtKeySequenceEditorFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtKeySequenceEditorFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtKeySequenceEditorFactory(QObject *parent = 0); + ~QtKeySequenceEditorFactory(); +protected: + void connectPropertyManager(QtKeySequencePropertyManager *manager); + QWidget *createEditor(QtKeySequencePropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtKeySequencePropertyManager *manager); +private: + QtKeySequenceEditorFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtKeySequenceEditorFactory) + Q_DISABLE_COPY(QtKeySequenceEditorFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QKeySequence &)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QKeySequence &)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtCharEditorFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtCharEditorFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtCharEditorFactory(QObject *parent = 0); + ~QtCharEditorFactory(); +protected: + void connectPropertyManager(QtCharPropertyManager *manager); + QWidget *createEditor(QtCharPropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtCharPropertyManager *manager); +private: + QtCharEditorFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtCharEditorFactory) + Q_DISABLE_COPY(QtCharEditorFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QChar &)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QChar &)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtEnumEditorFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtEnumEditorFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtEnumEditorFactory(QObject *parent = 0); + ~QtEnumEditorFactory(); +protected: + void connectPropertyManager(QtEnumPropertyManager *manager); + QWidget *createEditor(QtEnumPropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtEnumPropertyManager *manager); +private: + QtEnumEditorFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtEnumEditorFactory) + Q_DISABLE_COPY(QtEnumEditorFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotEnumNamesChanged(QtProperty *, + const QStringList &)) + Q_PRIVATE_SLOT(d_func(), void slotEnumIconsChanged(QtProperty *, + const QMap &)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(int)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtCursorEditorFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtCursorEditorFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtCursorEditorFactory(QObject *parent = 0); + ~QtCursorEditorFactory(); +protected: + void connectPropertyManager(QtCursorPropertyManager *manager); + QWidget *createEditor(QtCursorPropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtCursorPropertyManager *manager); +private: + QtCursorEditorFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtCursorEditorFactory) + Q_DISABLE_COPY(QtCursorEditorFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QCursor &)) + Q_PRIVATE_SLOT(d_func(), void slotEnumChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtColorEditorFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtColorEditorFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtColorEditorFactory(QObject *parent = 0); + ~QtColorEditorFactory(); +protected: + void connectPropertyManager(QtColorPropertyManager *manager); + QWidget *createEditor(QtColorPropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtColorPropertyManager *manager); +private: + QtColorEditorFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtColorEditorFactory) + Q_DISABLE_COPY(QtColorEditorFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QColor &)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QColor &)) +}; + +class QtFontEditorFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtFontEditorFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtFontEditorFactory(QObject *parent = 0); + ~QtFontEditorFactory(); +protected: + void connectPropertyManager(QtFontPropertyManager *manager); + QWidget *createEditor(QtFontPropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtFontPropertyManager *manager); +private: + QtFontEditorFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtFontEditorFactory) + Q_DISABLE_COPY(QtFontEditorFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QFont &)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QFont &)) +}; + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +#endif diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtgroupboxpropertybrowser.cpp b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtgroupboxpropertybrowser.cpp new file mode 100644 index 000000000..d789c8695 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtgroupboxpropertybrowser.cpp @@ -0,0 +1,578 @@ +/**************************************************************************** +** +** This file is part of a Qt Solutions component. +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtgroupboxpropertybrowser.h" +#include +#include +#include +#include +#include +#include + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +class QtGroupBoxPropertyBrowserPrivate +{ + QtGroupBoxPropertyBrowser *q_ptr; + Q_DECLARE_PUBLIC(QtGroupBoxPropertyBrowser) +public: + + void init(QWidget *parent); + + void propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex); + void propertyRemoved(QtBrowserItem *index); + void propertyChanged(QtBrowserItem *index); + QWidget *createEditor(QtProperty *property, QWidget *parent) const + { return q_ptr->createEditor(property, parent); } + + void slotEditorDestroyed(); + void slotUpdate(); + + struct WidgetItem + { + WidgetItem() : widget(0), label(0), widgetLabel(0), + groupBox(0), layout(0), line(0), parent(0) { } + QWidget *widget; // can be null + QLabel *label; + QLabel *widgetLabel; + QGroupBox *groupBox; + QGridLayout *layout; + QFrame *line; + WidgetItem *parent; + QList children; + }; +private: + void updateLater(); + void updateItem(WidgetItem *item); + void insertRow(QGridLayout *layout, int row) const; + void removeRow(QGridLayout *layout, int row) const; + + bool hasHeader(WidgetItem *item) const; + + QMap m_indexToItem; + QMap m_itemToIndex; + QMap m_widgetToItem; + QGridLayout *m_mainLayout; + QList m_children; + QList m_recreateQueue; +}; + +void QtGroupBoxPropertyBrowserPrivate::init(QWidget *parent) +{ + m_mainLayout = new QGridLayout(); + parent->setLayout(m_mainLayout); + QLayoutItem *item = new QSpacerItem(0, 0, + QSizePolicy::Fixed, QSizePolicy::Expanding); + m_mainLayout->addItem(item, 0, 0); +} + +void QtGroupBoxPropertyBrowserPrivate::slotEditorDestroyed() +{ + QWidget *editor = qobject_cast(q_ptr->sender()); + if (!editor) + return; + if (!m_widgetToItem.contains(editor)) + return; + m_widgetToItem[editor]->widget = 0; + m_widgetToItem.remove(editor); +} + +void QtGroupBoxPropertyBrowserPrivate::slotUpdate() +{ + QListIterator itItem(m_recreateQueue); + while (itItem.hasNext()) { + WidgetItem *item = itItem.next(); + + WidgetItem *par = item->parent; + QWidget *w = 0; + QGridLayout *l = 0; + int oldRow = -1; + if (!par) { + w = q_ptr; + l = m_mainLayout; + oldRow = m_children.indexOf(item); + } else { + w = par->groupBox; + l = par->layout; + oldRow = par->children.indexOf(item); + if (hasHeader(par)) + oldRow += 2; + } + + if (item->widget) { + item->widget->setParent(w); + } else if (item->widgetLabel) { + item->widgetLabel->setParent(w); + } else { + item->widgetLabel = new QLabel(w); + } + int span = 1; + if (item->widget) + l->addWidget(item->widget, oldRow, 1, 1, 1); + else if (item->widgetLabel) + l->addWidget(item->widgetLabel, oldRow, 1, 1, 1); + else + span = 2; + item->label = new QLabel(w); + item->label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + l->addWidget(item->label, oldRow, 0, 1, span); + + updateItem(item); + } + m_recreateQueue.clear(); +} + +void QtGroupBoxPropertyBrowserPrivate::updateLater() +{ + QTimer::singleShot(0, q_ptr, SLOT(slotUpdate())); +} + +void QtGroupBoxPropertyBrowserPrivate::propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex) +{ + WidgetItem *afterItem = m_indexToItem.value(afterIndex); + WidgetItem *parentItem = m_indexToItem.value(index->parent()); + + WidgetItem *newItem = new WidgetItem(); + newItem->parent = parentItem; + + QGridLayout *layout = 0; + QWidget *parentWidget = 0; + int row = -1; + if (!afterItem) { + row = 0; + if (parentItem) + parentItem->children.insert(0, newItem); + else + m_children.insert(0, newItem); + } else { + if (parentItem) { + row = parentItem->children.indexOf(afterItem) + 1; + parentItem->children.insert(row, newItem); + } else { + row = m_children.indexOf(afterItem) + 1; + m_children.insert(row, newItem); + } + } + if (parentItem && hasHeader(parentItem)) + row += 2; + + if (!parentItem) { + layout = m_mainLayout; + parentWidget = q_ptr;; + } else { + if (!parentItem->groupBox) { + m_recreateQueue.removeAll(parentItem); + WidgetItem *par = parentItem->parent; + QWidget *w = 0; + QGridLayout *l = 0; + int oldRow = -1; + if (!par) { + w = q_ptr; + l = m_mainLayout; + oldRow = m_children.indexOf(parentItem); + } else { + w = par->groupBox; + l = par->layout; + oldRow = par->children.indexOf(parentItem); + if (hasHeader(par)) + oldRow += 2; + } + parentItem->groupBox = new QGroupBox(w); + parentItem->layout = new QGridLayout(); + parentItem->groupBox->setLayout(parentItem->layout); + if (parentItem->label) { + l->removeWidget(parentItem->label); + delete parentItem->label; + parentItem->label = 0; + } + if (parentItem->widget) { + l->removeWidget(parentItem->widget); + parentItem->widget->setParent(parentItem->groupBox); + parentItem->layout->addWidget(parentItem->widget, 0, 0, 1, 2); + parentItem->line = new QFrame(parentItem->groupBox); + } else if (parentItem->widgetLabel) { + l->removeWidget(parentItem->widgetLabel); + delete parentItem->widgetLabel; + parentItem->widgetLabel = 0; + } + if (parentItem->line) { + parentItem->line->setFrameShape(QFrame::HLine); + parentItem->line->setFrameShadow(QFrame::Sunken); + parentItem->layout->addWidget(parentItem->line, 1, 0, 1, 2); + } + l->addWidget(parentItem->groupBox, oldRow, 0, 1, 2); + updateItem(parentItem); + } + layout = parentItem->layout; + parentWidget = parentItem->groupBox; + } + + newItem->label = new QLabel(parentWidget); + newItem->label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + newItem->widget = createEditor(index->property(), parentWidget); + if (!newItem->widget) { + newItem->widgetLabel = new QLabel(parentWidget); + } else { + QObject::connect(newItem->widget, SIGNAL(destroyed()), q_ptr, SLOT(slotEditorDestroyed())); + m_widgetToItem[newItem->widget] = newItem; + } + + insertRow(layout, row); + int span = 1; + if (newItem->widget) + layout->addWidget(newItem->widget, row, 1); + else if (newItem->widgetLabel) + layout->addWidget(newItem->widgetLabel, row, 1); + else + span = 2; + layout->addWidget(newItem->label, row, 0, 1, span); + + m_itemToIndex[newItem] = index; + m_indexToItem[index] = newItem; + + updateItem(newItem); +} + +void QtGroupBoxPropertyBrowserPrivate::propertyRemoved(QtBrowserItem *index) +{ + WidgetItem *item = m_indexToItem.value(index); + + m_indexToItem.remove(index); + m_itemToIndex.remove(item); + + WidgetItem *parentItem = item->parent; + + int row = -1; + + if (parentItem) { + row = parentItem->children.indexOf(item); + parentItem->children.removeAt(row); + if (hasHeader(parentItem)) + row += 2; + } else { + row = m_children.indexOf(item); + m_children.removeAt(row); + } + + if (item->widget) + delete item->widget; + if (item->label) + delete item->label; + if (item->widgetLabel) + delete item->widgetLabel; + if (item->groupBox) + delete item->groupBox; + + if (!parentItem) { + removeRow(m_mainLayout, row); + } else if (parentItem->children.count() != 0) { + removeRow(parentItem->layout, row); + } else { + WidgetItem *par = parentItem->parent; + QWidget *w = 0; + QGridLayout *l = 0; + int oldRow = -1; + if (!par) { + w = q_ptr; + l = m_mainLayout; + oldRow = m_children.indexOf(parentItem); + } else { + w = par->groupBox; + l = par->layout; + oldRow = par->children.indexOf(parentItem); + if (hasHeader(par)) + oldRow += 2; + } + + if (parentItem->widget) { + parentItem->widget->hide(); + parentItem->widget->setParent(0); + } else if (parentItem->widgetLabel) { + parentItem->widgetLabel->hide(); + parentItem->widgetLabel->setParent(0); + } else { + //parentItem->widgetLabel = new QLabel(w); + } + l->removeWidget(parentItem->groupBox); + delete parentItem->groupBox; + parentItem->groupBox = 0; + parentItem->line = 0; + parentItem->layout = 0; + if (!m_recreateQueue.contains(parentItem)) + m_recreateQueue.append(parentItem); + updateLater(); + } + m_recreateQueue.removeAll(item); + + delete item; +} + +void QtGroupBoxPropertyBrowserPrivate::insertRow(QGridLayout *layout, int row) const +{ + QMap itemToPos; + int idx = 0; + while (idx < layout->count()) { + int r, c, rs, cs; + layout->getItemPosition(idx, &r, &c, &rs, &cs); + if (r >= row) { + itemToPos[layout->takeAt(idx)] = QRect(r + 1, c, rs, cs); + } else { + idx++; + } + } + + const QMap::ConstIterator icend = itemToPos.constEnd(); + for (QMap::ConstIterator it = itemToPos.constBegin(); it != icend; ++it) { + const QRect r = it.value(); + layout->addItem(it.key(), r.x(), r.y(), r.width(), r.height()); + } +} + +void QtGroupBoxPropertyBrowserPrivate::removeRow(QGridLayout *layout, int row) const +{ + QMap itemToPos; + int idx = 0; + while (idx < layout->count()) { + int r, c, rs, cs; + layout->getItemPosition(idx, &r, &c, &rs, &cs); + if (r > row) { + itemToPos[layout->takeAt(idx)] = QRect(r - 1, c, rs, cs); + } else { + idx++; + } + } + + const QMap::ConstIterator icend = itemToPos.constEnd(); + for (QMap::ConstIterator it = itemToPos.constBegin(); it != icend; ++it) { + const QRect r = it.value(); + layout->addItem(it.key(), r.x(), r.y(), r.width(), r.height()); + } +} + +bool QtGroupBoxPropertyBrowserPrivate::hasHeader(WidgetItem *item) const +{ + if (item->widget) + return true; + return false; +} + +void QtGroupBoxPropertyBrowserPrivate::propertyChanged(QtBrowserItem *index) +{ + WidgetItem *item = m_indexToItem.value(index); + + updateItem(item); +} + +void QtGroupBoxPropertyBrowserPrivate::updateItem(WidgetItem *item) +{ + QtProperty *property = m_itemToIndex[item]->property(); + if (item->groupBox) { + QFont font = item->groupBox->font(); + font.setUnderline(property->isModified()); + item->groupBox->setFont(font); + item->groupBox->setTitle(property->propertyName()); + item->groupBox->setToolTip(property->toolTip()); + item->groupBox->setStatusTip(property->statusTip()); + item->groupBox->setWhatsThis(property->whatsThis()); + item->groupBox->setEnabled(property->isEnabled()); + } + if (item->label) { + QFont font = item->label->font(); + font.setUnderline(property->isModified()); + item->label->setFont(font); + item->label->setText(property->propertyName()); + item->label->setToolTip(property->toolTip()); + item->label->setStatusTip(property->statusTip()); + item->label->setWhatsThis(property->whatsThis()); + item->label->setEnabled(property->isEnabled()); + } + if (item->widgetLabel) { + QFont font = item->widgetLabel->font(); + font.setUnderline(false); + item->widgetLabel->setFont(font); + item->widgetLabel->setText(property->valueText()); + item->widgetLabel->setEnabled(property->isEnabled()); + } + if (item->widget) { + QFont font = item->widget->font(); + font.setUnderline(false); + item->widget->setFont(font); + item->widget->setEnabled(property->isEnabled()); + item->widget->setToolTip(property->valueText()); + } + //item->setIcon(1, property->valueIcon()); +} + + + +/*! + \class QtGroupBoxPropertyBrowser + + \brief The QtGroupBoxPropertyBrowser class provides a QGroupBox + based property browser. + + A property browser is a widget that enables the user to edit a + given set of properties. Each property is represented by a label + specifying the property's name, and an editing widget (e.g. a line + edit or a combobox) holding its value. A property can have zero or + more subproperties. + + QtGroupBoxPropertyBrowser provides group boxes for all nested + properties, i.e. subproperties are enclosed by a group box with + the parent property's name as its title. For example: + + \image qtgroupboxpropertybrowser.png + + Use the QtAbstractPropertyBrowser API to add, insert and remove + properties from an instance of the QtGroupBoxPropertyBrowser + class. The properties themselves are created and managed by + implementations of the QtAbstractPropertyManager class. + + \sa QtTreePropertyBrowser, QtAbstractPropertyBrowser +*/ + +/*! + Creates a property browser with the given \a parent. +*/ +QtGroupBoxPropertyBrowser::QtGroupBoxPropertyBrowser(QWidget *parent) + : QtAbstractPropertyBrowser(parent) +{ + d_ptr = new QtGroupBoxPropertyBrowserPrivate; + d_ptr->q_ptr = this; + + d_ptr->init(this); +} + +/*! + Destroys this property browser. + + Note that the properties that were inserted into this browser are + \e not destroyed since they may still be used in other + browsers. The properties are owned by the manager that created + them. + + \sa QtProperty, QtAbstractPropertyManager +*/ +QtGroupBoxPropertyBrowser::~QtGroupBoxPropertyBrowser() +{ + const QMap::ConstIterator icend = d_ptr->m_itemToIndex.constEnd(); + for (QMap::ConstIterator it = d_ptr->m_itemToIndex.constBegin(); it != icend; ++it) + delete it.key(); + delete d_ptr; +} + +/*! + \reimp +*/ +void QtGroupBoxPropertyBrowser::itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem) +{ + d_ptr->propertyInserted(item, afterItem); +} + +/*! + \reimp +*/ +void QtGroupBoxPropertyBrowser::itemRemoved(QtBrowserItem *item) +{ + d_ptr->propertyRemoved(item); +} + +/*! + \reimp +*/ +void QtGroupBoxPropertyBrowser::itemChanged(QtBrowserItem *item) +{ + d_ptr->propertyChanged(item); +} + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +#include "moc_qtgroupboxpropertybrowser.cxx" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtgroupboxpropertybrowser.h b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtgroupboxpropertybrowser.h new file mode 100644 index 000000000..075f3286e --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtgroupboxpropertybrowser.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** This file is part of a Qt Solutions component. +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTGROUPBOXPROPERTYBROWSER_H +#define QTGROUPBOXPROPERTYBROWSER_H + +#include "qtpropertybrowser.h" + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +class QtGroupBoxPropertyBrowserPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtGroupBoxPropertyBrowser : public QtAbstractPropertyBrowser +{ + Q_OBJECT +public: + + QtGroupBoxPropertyBrowser(QWidget *parent = 0); + ~QtGroupBoxPropertyBrowser(); + +protected: + virtual void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem); + virtual void itemRemoved(QtBrowserItem *item); + virtual void itemChanged(QtBrowserItem *item); + +private: + + QtGroupBoxPropertyBrowserPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtGroupBoxPropertyBrowser) + Q_DISABLE_COPY(QtGroupBoxPropertyBrowser) + Q_PRIVATE_SLOT(d_func(), void slotUpdate()) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed()) + +}; + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +#endif diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowser.cpp b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowser.cpp new file mode 100644 index 000000000..e8c103d9b --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowser.cpp @@ -0,0 +1,2053 @@ +/**************************************************************************** +** +** This file is part of a Qt Solutions component. +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtpropertybrowser.h" +#include +#include +#include + +#if defined(Q_CC_MSVC) +# pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */ +#endif + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +class QtPropertyPrivate +{ +public: + QtPropertyPrivate(QtAbstractPropertyManager *manager) : m_enabled(true), m_modified(false), m_bold(false), m_manager(manager) {} + QtProperty *q_ptr; + + QSet m_parentItems; + QList m_subItems; + + QString m_toolTip; + QString m_statusTip; + QString m_whatsThis; + QString m_name; + bool m_enabled; + bool m_modified; + bool m_bold; + + QtAbstractPropertyManager * const m_manager; +}; + +class QtAbstractPropertyManagerPrivate +{ + QtAbstractPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtAbstractPropertyManager) +public: + void propertyDestroyed(QtProperty *property); + void propertyChanged(QtProperty *property) const; + void propertyRemoved(QtProperty *property, + QtProperty *parentProperty) const; + void propertyInserted(QtProperty *property, QtProperty *parentProperty, + QtProperty *afterProperty) const; + + QSet m_properties; +}; + +/*! + \class QtProperty + + \brief The QtProperty class encapsulates an instance of a property. + + Properties are created by objects of QtAbstractPropertyManager + subclasses; a manager can create properties of a given type, and + is used in conjunction with the QtAbstractPropertyBrowser class. A + property is always owned by the manager that created it, which can + be retrieved using the propertyManager() function. + + QtProperty contains the most common property attributes, and + provides functions for retrieving as well as setting their values: + + \table + \header \o Getter \o Setter + \row + \o propertyName() \o setPropertyName() + \row + \o statusTip() \o setStatusTip() + \row + \o toolTip() \o setToolTip() + \row + \o whatsThis() \o setWhatsThis() + \row + \o isEnabled() \o setEnabled() + \row + \o isModified() \o setModified() + \row + \o valueText() \o Nop + \row + \o valueIcon() \o Nop + \endtable + + It is also possible to nest properties: QtProperty provides the + addSubProperty(), insertSubProperty() and removeSubProperty() functions to + manipulate the set of subproperties. Use the subProperties() + function to retrieve a property's current set of subproperties. + Note that nested properties are not owned by the parent property, + i.e. each subproperty is owned by the manager that created it. + + \sa QtAbstractPropertyManager, QtBrowserItem +*/ + +/*! + Creates a property with the given \a manager. + + This constructor is only useful when creating a custom QtProperty + subclass (e.g. QtVariantProperty). To create a regular QtProperty + object, use the QtAbstractPropertyManager::addProperty() + function instead. + + \sa QtAbstractPropertyManager::addProperty() +*/ +QtProperty::QtProperty(QtAbstractPropertyManager *manager) +{ + d_ptr = new QtPropertyPrivate(manager); + d_ptr->q_ptr = this; +} + +/*! + Destroys this property. + + Note that subproperties are detached but not destroyed, i.e. they + can still be used in another context. + + \sa QtAbstractPropertyManager::clear() + +*/ +QtProperty::~QtProperty() +{ + QSetIterator itParent(d_ptr->m_parentItems); + while (itParent.hasNext()) { + QtProperty *property = itParent.next(); + property->d_ptr->m_manager->d_ptr->propertyRemoved(this, property); + } + + d_ptr->m_manager->d_ptr->propertyDestroyed(this); + + QListIterator itChild(d_ptr->m_subItems); + while (itChild.hasNext()) { + QtProperty *property = itChild.next(); + property->d_ptr->m_parentItems.remove(this); + } + + itParent.toFront(); + while (itParent.hasNext()) { + QtProperty *property = itParent.next(); + property->d_ptr->m_subItems.removeAll(this); + } + delete d_ptr; +} + +/*! + Returns the set of subproperties. + + Note that subproperties are not owned by \e this property, but by + the manager that created them. + + \sa insertSubProperty(), removeSubProperty() +*/ +QList QtProperty::subProperties() const +{ + return d_ptr->m_subItems; +} + +/*! + Returns a pointer to the manager that owns this property. +*/ +QtAbstractPropertyManager *QtProperty::propertyManager() const +{ + return d_ptr->m_manager; +} + +/*! + Returns the property's tool tip. + + \sa setToolTip() +*/ +QString QtProperty::toolTip() const +{ + return d_ptr->m_toolTip; +} + +/*! + Returns the property's status tip. + + \sa setStatusTip() +*/ +QString QtProperty::statusTip() const +{ + return d_ptr->m_statusTip; +} + +/*! + Returns the property's "What's This" help text. + + \sa setWhatsThis() +*/ +QString QtProperty::whatsThis() const +{ + return d_ptr->m_whatsThis; +} + +/*! + Returns the property's name. + + \sa setPropertyName() +*/ +QString QtProperty::propertyName() const +{ + return d_ptr->m_name; +} + +/*! + Returns whether the property is enabled. + + \sa setEnabled() +*/ +bool QtProperty::isEnabled() const +{ + return d_ptr->m_enabled; +} + +/*! + Returns whether the property is modified. + + \sa setModified() +*/ +bool QtProperty::isModified() const +{ + return d_ptr->m_modified; +} + +/*! + Returns whether the property is displayed as bold. + + \sa setBold() +*/ +bool QtProperty::isBold() const +{ + return d_ptr->m_bold; +} + +/*! + Returns whether the property has a value. + + \sa QtAbstractPropertyManager::hasValue() +*/ +bool QtProperty::hasValue() const +{ + return d_ptr->m_manager->hasValue(this); +} + +/*! + Returns an icon representing the current state of this property. + + If the given property type can not generate such an icon, this + function returns an invalid icon. + + \sa QtAbstractPropertyManager::valueIcon() +*/ +QIcon QtProperty::valueIcon() const +{ + return d_ptr->m_manager->valueIcon(this); +} + +/*! + Returns a string representing the current state of this property. + + If the given property type can not generate such a string, this + function returns an empty string. + + \sa QtAbstractPropertyManager::valueText() +*/ +QString QtProperty::valueText() const +{ + return d_ptr->m_manager->valueText(this); +} + +/*! + Sets the property's tool tip to the given \a text. + + \sa toolTip() +*/ +void QtProperty::setToolTip(const QString &text) +{ + if (d_ptr->m_toolTip == text) + return; + + d_ptr->m_toolTip = text; + propertyChanged(); +} + +/*! + Sets the property's status tip to the given \a text. + + \sa statusTip() +*/ +void QtProperty::setStatusTip(const QString &text) +{ + if (d_ptr->m_statusTip == text) + return; + + d_ptr->m_statusTip = text; + propertyChanged(); +} + +/*! + Sets the property's "What's This" help text to the given \a text. + + \sa whatsThis() +*/ +void QtProperty::setWhatsThis(const QString &text) +{ + if (d_ptr->m_whatsThis == text) + return; + + d_ptr->m_whatsThis = text; + propertyChanged(); +} + +/*! + \fn void QtProperty::setPropertyName(const QString &name) + + Sets the property's name to the given \a name. + + \sa propertyName() +*/ +void QtProperty::setPropertyName(const QString &text) +{ + if (d_ptr->m_name == text) + return; + + d_ptr->m_name = text; + propertyChanged(); +} + +/*! + Enables or disables the property according to the passed \a enable value. + + \sa isEnabled() +*/ +void QtProperty::setEnabled(bool enable) +{ + if (d_ptr->m_enabled == enable) + return; + + d_ptr->m_enabled = enable; + propertyChanged(); +} + +/*! + Sets the property's modified state according to the passed \a modified value. + + \sa isModified() +*/ +void QtProperty::setModified(bool modified) +{ + if (d_ptr->m_modified == modified) + return; + + d_ptr->m_modified = modified; + propertyChanged(); +} + +/*! + Sets the property's bold state according to the passed \a bold value. + + \sa isBold() +*/ +void QtProperty::setBold(bool bold) +{ + if (d_ptr->m_bold == bold) + return; + + d_ptr->m_bold = bold; + propertyChanged(); +} + +/*! + Appends the given \a property to this property's subproperties. + + If the given \a property already is added, this function does + nothing. + + \sa insertSubProperty(), removeSubProperty() +*/ +void QtProperty::addSubProperty(QtProperty *property) +{ + QtProperty *after = 0; + if (d_ptr->m_subItems.count() > 0) + after = d_ptr->m_subItems.last(); + insertSubProperty(property, after); +} + +/*! + \fn void QtProperty::insertSubProperty(QtProperty *property, QtProperty *precedingProperty) + + Inserts the given \a property after the specified \a + precedingProperty into this property's list of subproperties. If + \a precedingProperty is 0, the specified \a property is inserted + at the beginning of the list. + + If the given \a property already is inserted, this function does + nothing. + + \sa addSubProperty(), removeSubProperty() +*/ +void QtProperty::insertSubProperty(QtProperty *property, + QtProperty *afterProperty) +{ + if (!property) + return; + + if (property == this) + return; + + // traverse all children of item. if this item is a child of item then cannot add. + QList pendingList = property->subProperties(); + QMap visited; + while (!pendingList.isEmpty()) { + QtProperty *i = pendingList.first(); + if (i == this) + return; + pendingList.removeFirst(); + if (visited.contains(i)) + continue; + visited[i] = true; + pendingList += i->subProperties(); + } + + pendingList = subProperties(); + int pos = 0; + int newPos = 0; + QtProperty *properAfterProperty = 0; + while (pos < pendingList.count()) { + QtProperty *i = pendingList.at(pos); + if (i == property) + return; // if item is already inserted in this item then cannot add. + if (i == afterProperty) { + newPos = pos + 1; + properAfterProperty = afterProperty; + } + pos++; + } + + d_ptr->m_subItems.insert(newPos, property); + property->d_ptr->m_parentItems.insert(this); + + d_ptr->m_manager->d_ptr->propertyInserted(property, this, properAfterProperty); +} + +/*! + Removes the given \a property from the list of subproperties + without deleting it. + + \sa addSubProperty(), insertSubProperty() +*/ +void QtProperty::removeSubProperty(QtProperty *property) +{ + if (!property) + return; + + d_ptr->m_manager->d_ptr->propertyRemoved(property, this); + + QList pendingList = subProperties(); + int pos = 0; + while (pos < pendingList.count()) { + if (pendingList.at(pos) == property) { + d_ptr->m_subItems.removeAt(pos); + property->d_ptr->m_parentItems.remove(this); + + return; + } + pos++; + } +} + +/*! + \internal +*/ +void QtProperty::propertyChanged() +{ + d_ptr->m_manager->d_ptr->propertyChanged(this); +} + +//////////////////////////////// + +void QtAbstractPropertyManagerPrivate::propertyDestroyed(QtProperty *property) +{ + if (m_properties.contains(property)) { + emit q_ptr->propertyDestroyed(property); + q_ptr->uninitializeProperty(property); + m_properties.remove(property); + } +} + +void QtAbstractPropertyManagerPrivate::propertyChanged(QtProperty *property) const +{ + emit q_ptr->propertyChanged(property); +} + +void QtAbstractPropertyManagerPrivate::propertyRemoved(QtProperty *property, + QtProperty *parentProperty) const +{ + emit q_ptr->propertyRemoved(property, parentProperty); +} + +void QtAbstractPropertyManagerPrivate::propertyInserted(QtProperty *property, + QtProperty *parentProperty, QtProperty *afterProperty) const +{ + emit q_ptr->propertyInserted(property, parentProperty, afterProperty); +} + +/*! + \class QtAbstractPropertyManager + + \brief The QtAbstractPropertyManager provides an interface for + property managers. + + A manager can create and manage properties of a given type, and is + used in conjunction with the QtAbstractPropertyBrowser class. + + When using a property browser widget, the properties are created + and managed by implementations of the QtAbstractPropertyManager + class. To ensure that the properties' values will be displayed + using suitable editing widgets, the managers are associated with + objects of QtAbstractEditorFactory subclasses. The property browser + will use these associations to determine which factories it should + use to create the preferred editing widgets. + + The QtAbstractPropertyManager class provides common functionality + like creating a property using the addProperty() function, and + retrieving the properties created by the manager using the + properties() function. The class also provides signals that are + emitted when the manager's properties change: propertyInserted(), + propertyRemoved(), propertyChanged() and propertyDestroyed(). + + QtAbstractPropertyManager subclasses are supposed to provide their + own type specific API. Note that several ready-made + implementations are available: + + \list + \o QtBoolPropertyManager + \o QtColorPropertyManager + \o QtDatePropertyManager + \o QtDateTimePropertyManager + \o QtDoublePropertyManager + \o QtEnumPropertyManager + \o QtFlagPropertyManager + \o QtFontPropertyManager + \o QtGroupPropertyManager + \o QtIntPropertyManager + \o QtPointPropertyManager + \o QtRectPropertyManager + \o QtSizePropertyManager + \o QtSizePolicyPropertyManager + \o QtStringPropertyManager + \o QtTimePropertyManager + \o QtVariantPropertyManager + \endlist + + \sa QtAbstractEditorFactoryBase, QtAbstractPropertyBrowser, QtProperty +*/ + +/*! + \fn void QtAbstractPropertyManager::propertyInserted(QtProperty *newProperty, + QtProperty *parentProperty, QtProperty *precedingProperty) + + This signal is emitted when a new subproperty is inserted into an + existing property, passing pointers to the \a newProperty, \a + parentProperty and \a precedingProperty as parameters. + + If \a precedingProperty is 0, the \a newProperty was inserted at + the beginning of the \a parentProperty's subproperties list. + + Note that signal is emitted only if the \a parentProperty is created + by this manager. + + \sa QtAbstractPropertyBrowser::itemInserted() +*/ + +/*! + \fn void QtAbstractPropertyManager::propertyChanged(QtProperty *property) + + This signal is emitted whenever a property's data changes, passing + a pointer to the \a property as parameter. + + Note that signal is only emitted for properties that are created by + this manager. + + \sa QtAbstractPropertyBrowser::itemChanged() +*/ + +/*! + \fn void QtAbstractPropertyManager::propertyRemoved(QtProperty *property, QtProperty *parent) + + This signal is emitted when a subproperty is removed, passing + pointers to the removed \a property and the \a parent property as + parameters. + + Note that signal is emitted only when the \a parent property is + created by this manager. + + \sa QtAbstractPropertyBrowser::itemRemoved() +*/ + +/*! + \fn void QtAbstractPropertyManager::propertyDestroyed(QtProperty *property) + + This signal is emitted when the specified \a property is about to + be destroyed. + + Note that signal is only emitted for properties that are created + by this manager. + + \sa clear(), uninitializeProperty() +*/ + +/*! + \fn void QtAbstractPropertyBrowser::currentItemChanged(QtBrowserItem *current) + + This signal is emitted when the current item changes. The current item is specified by \a current. + + \sa QtAbstractPropertyBrowser::setCurrentItem() +*/ + +/*! + Creates an abstract property manager with the given \a parent. +*/ +QtAbstractPropertyManager::QtAbstractPropertyManager(QObject *parent) + : QObject(parent) +{ + d_ptr = new QtAbstractPropertyManagerPrivate; + d_ptr->q_ptr = this; + +} + +/*! + Destroys the manager. All properties created by the manager are + destroyed. +*/ +QtAbstractPropertyManager::~QtAbstractPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Destroys all the properties that this manager has created. + + \sa propertyDestroyed(), uninitializeProperty() +*/ +void QtAbstractPropertyManager::clear() const +{ + while (!properties().isEmpty()) { + QSetIterator itProperty(properties()); + QtProperty *prop = itProperty.next(); + delete prop; + } +} + +/*! + Returns the set of properties created by this manager. + + \sa addProperty() +*/ +QSet QtAbstractPropertyManager::properties() const +{ + return d_ptr->m_properties; +} + +/*! + Returns whether the given \a property has a value. + + The default implementation of this function returns true. + + \sa QtProperty::hasValue() +*/ +bool QtAbstractPropertyManager::hasValue(const QtProperty *property) const +{ + Q_UNUSED(property) + return true; +} + +/*! + Returns an icon representing the current state of the given \a + property. + + The default implementation of this function returns an invalid + icon. + + \sa QtProperty::valueIcon() +*/ +QIcon QtAbstractPropertyManager::valueIcon(const QtProperty *property) const +{ + Q_UNUSED(property) + return QIcon(); +} + +/*! + Returns a string representing the current state of the given \a + property. + + The default implementation of this function returns an empty + string. + + \sa QtProperty::valueText() +*/ +QString QtAbstractPropertyManager::valueText(const QtProperty *property) const +{ + Q_UNUSED(property) + return QString(); +} + +/*! + Creates a property with the given \a name which then is owned by this manager. + + Internally, this function calls the createProperty() and + initializeProperty() functions. + + \sa initializeProperty(), properties() +*/ +QtProperty *QtAbstractPropertyManager::addProperty(const QString &name) +{ + QtProperty *property = createProperty(); + if (property) { + property->setPropertyName(name); + d_ptr->m_properties.insert(property); + initializeProperty(property); + } + return property; +} + +/*! + Creates a property. + + The base implementation produce QtProperty instances; Reimplement + this function to make this manager produce objects of a QtProperty + subclass. + + \sa addProperty(), initializeProperty() +*/ +QtProperty *QtAbstractPropertyManager::createProperty() +{ + return new QtProperty(this); +} + +/*! + \fn void QtAbstractPropertyManager::initializeProperty(QtProperty *property) = 0 + + This function is called whenever a new valid property pointer has + been created, passing the pointer as parameter. + + The purpose is to let the manager know that the \a property has + been created so that it can provide additional attributes for the + new property, e.g. QtIntPropertyManager adds \l + {QtIntPropertyManager::value()}{value}, \l + {QtIntPropertyManager::minimum()}{minimum} and \l + {QtIntPropertyManager::maximum()}{maximum} attributes. Since each manager + subclass adds type specific attributes, this function is pure + virtual and must be reimplemented when deriving from the + QtAbstractPropertyManager class. + + \sa addProperty(), createProperty() +*/ + +/*! + This function is called just before the specified \a property is destroyed. + + The purpose is to let the property manager know that the \a + property is being destroyed so that it can remove the property's + additional attributes. + + \sa clear(), propertyDestroyed() +*/ +void QtAbstractPropertyManager::uninitializeProperty(QtProperty *property) +{ + Q_UNUSED(property) +} + +//////////////////////////////////// + +/*! + \class QtAbstractEditorFactoryBase + + \brief The QtAbstractEditorFactoryBase provides an interface for + editor factories. + + An editor factory is a class that is able to create an editing + widget of a specified type (e.g. line edits or comboboxes) for a + given QtProperty object, and it is used in conjunction with the + QtAbstractPropertyManager and QtAbstractPropertyBrowser classes. + + When using a property browser widget, the properties are created + and managed by implementations of the QtAbstractPropertyManager + class. To ensure that the properties' values will be displayed + using suitable editing widgets, the managers are associated with + objects of QtAbstractEditorFactory subclasses. The property browser + will use these associations to determine which factories it should + use to create the preferred editing widgets. + + Typically, an editor factory is created by subclassing the + QtAbstractEditorFactory template class which inherits + QtAbstractEditorFactoryBase. But note that several ready-made + implementations are available: + + \list + \o QtCheckBoxFactory + \o QtDateEditFactory + \o QtDateTimeEditFactory + \o QtDoubleSpinBoxFactory + \o QtEnumEditorFactory + \o QtLineEditFactory + \o QtScrollBarFactory + \o QtSliderFactory + \o QtSpinBoxFactory + \o QtTimeEditFactory + \o QtVariantEditorFactory + \endlist + + \sa QtAbstractPropertyManager, QtAbstractPropertyBrowser +*/ + +/*! + \fn virtual QWidget *QtAbstractEditorFactoryBase::createEditor(QtProperty *property, + QWidget *parent) = 0 + + Creates an editing widget (with the given \a parent) for the given + \a property. + + This function is reimplemented in QtAbstractEditorFactory template class + which also provides a pure virtual convenience overload of this + function enabling access to the property's manager. + + \sa QtAbstractEditorFactory::createEditor() +*/ + +/*! + \fn QtAbstractEditorFactoryBase::QtAbstractEditorFactoryBase(QObject *parent = 0) + + Creates an abstract editor factory with the given \a parent. +*/ + +/*! + \fn virtual void QtAbstractEditorFactoryBase::breakConnection(QtAbstractPropertyManager *manager) = 0 + + \internal + + Detaches property manager from factory. + This method is reimplemented in QtAbstractEditorFactory template subclass. + You don't need to reimplement it in your subclasses. Instead implement more convenient + QtAbstractEditorFactory::disconnectPropertyManager() which gives you access to particular manager subclass. +*/ + +/*! + \fn virtual void QtAbstractEditorFactoryBase::managerDestroyed(QObject *manager) = 0 + + \internal + + This method is called when property manager is being destroyed. + Basically it notifies factory not to produce editors for properties owned by \a manager. + You don't need to reimplement it in your subclass. This method is implemented in + QtAbstractEditorFactory template subclass. +*/ + +/*! + \class QtAbstractEditorFactory + + \brief The QtAbstractEditorFactory is the base template class for editor + factories. + + An editor factory is a class that is able to create an editing + widget of a specified type (e.g. line edits or comboboxes) for a + given QtProperty object, and it is used in conjunction with the + QtAbstractPropertyManager and QtAbstractPropertyBrowser classes. + + Note that the QtAbstractEditorFactory functions are using the + PropertyManager template argument class which can be any + QtAbstractPropertyManager subclass. For example: + + \code + QtSpinBoxFactory *factory; + QSet managers = factory->propertyManagers(); + \endcode + + Note that QtSpinBoxFactory by definition creates editing widgets + \e only for properties created by QtIntPropertyManager. + + When using a property browser widget, the properties are created + and managed by implementations of the QtAbstractPropertyManager + class. To ensure that the properties' values will be displayed + using suitable editing widgets, the managers are associated with + objects of QtAbstractEditorFactory subclasses. The property browser will + use these associations to determine which factories it should use + to create the preferred editing widgets. + + A QtAbstractEditorFactory object is capable of producing editors for + several property managers at the same time. To create an + association between this factory and a given manager, use the + addPropertyManager() function. Use the removePropertyManager() function to make + this factory stop producing editors for a given property + manager. Use the propertyManagers() function to retrieve the set of + managers currently associated with this factory. + + Several ready-made implementations of the QtAbstractEditorFactory class + are available: + + \list + \o QtCheckBoxFactory + \o QtDateEditFactory + \o QtDateTimeEditFactory + \o QtDoubleSpinBoxFactory + \o QtEnumEditorFactory + \o QtLineEditFactory + \o QtScrollBarFactory + \o QtSliderFactory + \o QtSpinBoxFactory + \o QtTimeEditFactory + \o QtVariantEditorFactory + \endlist + + When deriving from the QtAbstractEditorFactory class, several pure virtual + functions must be implemented: the connectPropertyManager() function is + used by the factory to connect to the given manager's signals, the + createEditor() function is supposed to create an editor for the + given property controlled by the given manager, and finally the + disconnectPropertyManager() function is used by the factory to disconnect + from the specified manager's signals. + + \sa QtAbstractEditorFactoryBase, QtAbstractPropertyManager +*/ + +/*! + \fn QtAbstractEditorFactory::QtAbstractEditorFactory(QObject *parent = 0) + + Creates an editor factory with the given \a parent. + + \sa addPropertyManager() +*/ + +/*! + \fn QWidget *QtAbstractEditorFactory::createEditor(QtProperty *property, QWidget *parent) + + Creates an editing widget (with the given \a parent) for the given + \a property. +*/ + +/*! + \fn void QtAbstractEditorFactory::addPropertyManager(PropertyManager *manager) + + Adds the given \a manager to this factory's set of managers, + making this factory produce editing widgets for properties created + by the given manager. + + The PropertyManager type is a template argument class, and represents the chosen + QtAbstractPropertyManager subclass. + + \sa propertyManagers(), removePropertyManager() +*/ + +/*! + \fn void QtAbstractEditorFactory::removePropertyManager(PropertyManager *manager) + + Removes the given \a manager from this factory's set of + managers. The PropertyManager type is a template argument class, and may be + any QtAbstractPropertyManager subclass. + + \sa propertyManagers(), addPropertyManager() +*/ + +/*! + \fn virtual void QtAbstractEditorFactory::connectPropertyManager(PropertyManager *manager) = 0 + + Connects this factory to the given \a manager's signals. The + PropertyManager type is a template argument class, and represents + the chosen QtAbstractPropertyManager subclass. + + This function is used internally by the addPropertyManager() function, and + makes it possible to update an editing widget when the associated + property's data changes. This is typically done in custom slots + responding to the signals emitted by the property's manager, + e.g. QtIntPropertyManager::valueChanged() and + QtIntPropertyManager::rangeChanged(). + + \sa propertyManagers(), disconnectPropertyManager() +*/ + +/*! + \fn virtual QWidget *QtAbstractEditorFactory::createEditor(PropertyManager *manager, QtProperty *property, + QWidget *parent) = 0 + + Creates an editing widget with the given \a parent for the + specified \a property created by the given \a manager. The + PropertyManager type is a template argument class, and represents + the chosen QtAbstractPropertyManager subclass. + + This function must be implemented in derived classes: It is + recommended to store a pointer to the widget and map it to the + given \a property, since the widget must be updated whenever the + associated property's data changes. This is typically done in + custom slots responding to the signals emitted by the property's + manager, e.g. QtIntPropertyManager::valueChanged() and + QtIntPropertyManager::rangeChanged(). + + \sa connectPropertyManager() +*/ + +/*! + \fn virtual void QtAbstractEditorFactory::disconnectPropertyManager(PropertyManager *manager) = 0 + + Disconnects this factory from the given \a manager's signals. The + PropertyManager type is a template argument class, and represents + the chosen QtAbstractPropertyManager subclass. + + This function is used internally by the removePropertyManager() function. + + \sa propertyManagers(), connectPropertyManager() +*/ + +/*! + \fn QSet QtAbstractEditorFactory::propertyManagers() const + + Returns the factory's set of associated managers. The + PropertyManager type is a template argument class, and represents + the chosen QtAbstractPropertyManager subclass. + + \sa addPropertyManager(), removePropertyManager() +*/ + +/*! + \fn PropertyManager *QtAbstractEditorFactory::propertyManager(QtProperty *property) const + + Returns the property manager for the given \a property, or 0 if + the given \a property doesn't belong to any of this factory's + registered managers. + + The PropertyManager type is a template argument class, and represents the chosen + QtAbstractPropertyManager subclass. + + \sa propertyManagers() +*/ + +/*! + \fn virtual void QtAbstractEditorFactory::managerDestroyed(QObject *manager) + + \internal + \reimp +*/ + +//////////////////////////////////// +class QtBrowserItemPrivate +{ +public: + QtBrowserItemPrivate(QtAbstractPropertyBrowser *browser, QtProperty *property, QtBrowserItem *parent) + : m_browser(browser), m_property(property), m_parent(parent), q_ptr(0) {} + + void addChild(QtBrowserItem *index, QtBrowserItem *after); + void removeChild(QtBrowserItem *index); + + QtAbstractPropertyBrowser * const m_browser; + QtProperty *m_property; + QtBrowserItem *m_parent; + + QtBrowserItem *q_ptr; + + QList m_children; + +}; + +void QtBrowserItemPrivate::addChild(QtBrowserItem *index, QtBrowserItem *after) +{ + if (m_children.contains(index)) + return; + int idx = m_children.indexOf(after) + 1; // we insert after returned idx, if it was -1 then we set idx to 0; + m_children.insert(idx, index); +} + +void QtBrowserItemPrivate::removeChild(QtBrowserItem *index) +{ + m_children.removeAll(index); +} + + +/*! + \class QtBrowserItem + + \brief The QtBrowserItem class represents a property in + a property browser instance. + + Browser items are created whenever a QtProperty is inserted to the + property browser. A QtBrowserItem uniquely identifies a + browser's item. Thus, if the same QtProperty is inserted multiple + times, each occurrence gets its own unique QtBrowserItem. The + items are owned by QtAbstractPropertyBrowser and automatically + deleted when they are removed from the browser. + + You can traverse a browser's properties by calling parent() and + children(). The property and the browser associated with an item + are available as property() and browser(). + + \sa QtAbstractPropertyBrowser, QtProperty +*/ + +/*! + Returns the property which is accosiated with this item. Note that + several items can be associated with the same property instance in + the same property browser. + + \sa QtAbstractPropertyBrowser::items() +*/ + +QtProperty *QtBrowserItem::property() const +{ + return d_ptr->m_property; +} + +/*! + Returns the parent item of \e this item. Returns 0 if \e this item + is associated with top-level property in item's property browser. + + \sa children() +*/ + +QtBrowserItem *QtBrowserItem::parent() const +{ + return d_ptr->m_parent; +} + +/*! + Returns the children items of \e this item. The properties + reproduced from children items are always the same as + reproduced from associated property' children, for example: + + \code + QtBrowserItem *item; + QList childrenItems = item->children(); + + QList childrenProperties = item->property()->subProperties(); + \endcode + + The \e childrenItems list represents the same list as \e childrenProperties. +*/ + +QList QtBrowserItem::children() const +{ + return d_ptr->m_children; +} + +/*! + Returns the property browser which owns \e this item. +*/ + +QtAbstractPropertyBrowser *QtBrowserItem::browser() const +{ + return d_ptr->m_browser; +} + +QtBrowserItem::QtBrowserItem(QtAbstractPropertyBrowser *browser, QtProperty *property, QtBrowserItem *parent) +{ + d_ptr = new QtBrowserItemPrivate(browser, property, parent); + d_ptr->q_ptr = this; +} + +QtBrowserItem::~QtBrowserItem() +{ + delete d_ptr; +} + + +//////////////////////////////////// + +typedef QMap > Map1; +typedef QMap > > Map2; +Q_GLOBAL_STATIC(Map1, m_viewToManagerToFactory) +Q_GLOBAL_STATIC(Map2, m_managerToFactoryToViews) + +class QtAbstractPropertyBrowserPrivate +{ + QtAbstractPropertyBrowser *q_ptr; + Q_DECLARE_PUBLIC(QtAbstractPropertyBrowser) +public: + QtAbstractPropertyBrowserPrivate(); + + void insertSubTree(QtProperty *property, + QtProperty *parentProperty); + void removeSubTree(QtProperty *property, + QtProperty *parentProperty); + void createBrowserIndexes(QtProperty *property, QtProperty *parentProperty, QtProperty *afterProperty); + void removeBrowserIndexes(QtProperty *property, QtProperty *parentProperty); + QtBrowserItem *createBrowserIndex(QtProperty *property, QtBrowserItem *parentIndex, QtBrowserItem *afterIndex); + void removeBrowserIndex(QtBrowserItem *index); + void clearIndex(QtBrowserItem *index); + + void slotPropertyInserted(QtProperty *property, + QtProperty *parentProperty, QtProperty *afterProperty); + void slotPropertyRemoved(QtProperty *property, QtProperty *parentProperty); + void slotPropertyDestroyed(QtProperty *property); + void slotPropertyDataChanged(QtProperty *property); + + QList m_subItems; + QMap > m_managerToProperties; + QMap > m_propertyToParents; + + QMap m_topLevelPropertyToIndex; + QList m_topLevelIndexes; + QMap > m_propertyToIndexes; + + QtBrowserItem *m_currentItem; +}; + +QtAbstractPropertyBrowserPrivate::QtAbstractPropertyBrowserPrivate() : + m_currentItem(0) +{ +} + +void QtAbstractPropertyBrowserPrivate::insertSubTree(QtProperty *property, + QtProperty *parentProperty) +{ + if (m_propertyToParents.contains(property)) { + // property was already inserted, so its manager is connected + // and all its children are inserted and theirs managers are connected + // we just register new parent (parent has to be new). + m_propertyToParents[property].append(parentProperty); + // don't need to update m_managerToProperties map since + // m_managerToProperties[manager] already contains property. + return; + } + QtAbstractPropertyManager *manager = property->propertyManager(); + if (m_managerToProperties[manager].isEmpty()) { + // connect manager's signals + q_ptr->connect(manager, SIGNAL(propertyInserted(QtProperty *, + QtProperty *, QtProperty *)), + q_ptr, SLOT(slotPropertyInserted(QtProperty *, + QtProperty *, QtProperty *))); + q_ptr->connect(manager, SIGNAL(propertyRemoved(QtProperty *, + QtProperty *)), + q_ptr, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + q_ptr->connect(manager, SIGNAL(propertyDestroyed(QtProperty *)), + q_ptr, SLOT(slotPropertyDestroyed(QtProperty *))); + q_ptr->connect(manager, SIGNAL(propertyChanged(QtProperty *)), + q_ptr, SLOT(slotPropertyDataChanged(QtProperty *))); + } + m_managerToProperties[manager].append(property); + m_propertyToParents[property].append(parentProperty); + + QList subList = property->subProperties(); + QListIterator itSub(subList); + while (itSub.hasNext()) { + QtProperty *subProperty = itSub.next(); + insertSubTree(subProperty, property); + } +} + +void QtAbstractPropertyBrowserPrivate::removeSubTree(QtProperty *property, + QtProperty *parentProperty) +{ + if (!m_propertyToParents.contains(property)) { + // ASSERT + return; + } + + m_propertyToParents[property].removeAll(parentProperty); + if (!m_propertyToParents[property].isEmpty()) + return; + + m_propertyToParents.remove(property); + QtAbstractPropertyManager *manager = property->propertyManager(); + m_managerToProperties[manager].removeAll(property); + if (m_managerToProperties[manager].isEmpty()) { + // disconnect manager's signals + q_ptr->disconnect(manager, SIGNAL(propertyInserted(QtProperty *, + QtProperty *, QtProperty *)), + q_ptr, SLOT(slotPropertyInserted(QtProperty *, + QtProperty *, QtProperty *))); + q_ptr->disconnect(manager, SIGNAL(propertyRemoved(QtProperty *, + QtProperty *)), + q_ptr, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + q_ptr->disconnect(manager, SIGNAL(propertyDestroyed(QtProperty *)), + q_ptr, SLOT(slotPropertyDestroyed(QtProperty *))); + q_ptr->disconnect(manager, SIGNAL(propertyChanged(QtProperty *)), + q_ptr, SLOT(slotPropertyDataChanged(QtProperty *))); + + m_managerToProperties.remove(manager); + } + + QList subList = property->subProperties(); + QListIterator itSub(subList); + while (itSub.hasNext()) { + QtProperty *subProperty = itSub.next(); + removeSubTree(subProperty, property); + } +} + +void QtAbstractPropertyBrowserPrivate::createBrowserIndexes(QtProperty *property, QtProperty *parentProperty, QtProperty *afterProperty) +{ + QMap parentToAfter; + if (afterProperty) { + QMap >::ConstIterator it = + m_propertyToIndexes.find(afterProperty); + if (it == m_propertyToIndexes.constEnd()) + return; + + QList indexes = it.value(); + QListIterator itIndex(indexes); + while (itIndex.hasNext()) { + QtBrowserItem *idx = itIndex.next(); + QtBrowserItem *parentIdx = idx->parent(); + if ((parentProperty && parentIdx && parentIdx->property() == parentProperty) || (!parentProperty && !parentIdx)) + parentToAfter[idx->parent()] = idx; + } + } else if (parentProperty) { + QMap >::ConstIterator it = + m_propertyToIndexes.find(parentProperty); + if (it == m_propertyToIndexes.constEnd()) + return; + + QList indexes = it.value(); + QListIterator itIndex(indexes); + while (itIndex.hasNext()) { + QtBrowserItem *idx = itIndex.next(); + parentToAfter[idx] = 0; + } + } else { + parentToAfter[0] = 0; + } + + const QMap::ConstIterator pcend = parentToAfter.constEnd(); + for (QMap::ConstIterator it = parentToAfter.constBegin(); it != pcend; ++it) + createBrowserIndex(property, it.key(), it.value()); +} + +QtBrowserItem *QtAbstractPropertyBrowserPrivate::createBrowserIndex(QtProperty *property, + QtBrowserItem *parentIndex, QtBrowserItem *afterIndex) +{ + QtBrowserItem *newIndex = new QtBrowserItem(q_ptr, property, parentIndex); + if (parentIndex) { + parentIndex->d_ptr->addChild(newIndex, afterIndex); + } else { + m_topLevelPropertyToIndex[property] = newIndex; + m_topLevelIndexes.insert(m_topLevelIndexes.indexOf(afterIndex) + 1, newIndex); + } + m_propertyToIndexes[property].append(newIndex); + + q_ptr->itemInserted(newIndex, afterIndex); + + QList subItems = property->subProperties(); + QListIterator itChild(subItems); + QtBrowserItem *afterChild = 0; + while (itChild.hasNext()) { + QtProperty *child = itChild.next(); + afterChild = createBrowserIndex(child, newIndex, afterChild); + } + return newIndex; +} + +void QtAbstractPropertyBrowserPrivate::removeBrowserIndexes(QtProperty *property, QtProperty *parentProperty) +{ + QList toRemove; + QMap >::ConstIterator it = + m_propertyToIndexes.find(property); + if (it == m_propertyToIndexes.constEnd()) + return; + + QList indexes = it.value(); + QListIterator itIndex(indexes); + while (itIndex.hasNext()) { + QtBrowserItem *idx = itIndex.next(); + QtBrowserItem *parentIdx = idx->parent(); + if ((parentProperty && parentIdx && parentIdx->property() == parentProperty) || (!parentProperty && !parentIdx)) + toRemove.append(idx); + } + + QListIterator itRemove(toRemove); + while (itRemove.hasNext()) { + QtBrowserItem *index = itRemove.next(); + removeBrowserIndex(index); + } +} + +void QtAbstractPropertyBrowserPrivate::removeBrowserIndex(QtBrowserItem *index) +{ + QList children = index->children(); + for (int i = children.count(); i > 0; i--) { + removeBrowserIndex(children.at(i - 1)); + } + + q_ptr->itemRemoved(index); + + if (index->parent()) { + index->parent()->d_ptr->removeChild(index); + } else { + m_topLevelPropertyToIndex.remove(index->property()); + m_topLevelIndexes.removeAll(index); + } + + QtProperty *property = index->property(); + + m_propertyToIndexes[property].removeAll(index); + if (m_propertyToIndexes[property].isEmpty()) + m_propertyToIndexes.remove(property); + + delete index; +} + +void QtAbstractPropertyBrowserPrivate::clearIndex(QtBrowserItem *index) +{ + QList children = index->children(); + QListIterator itChild(children); + while (itChild.hasNext()) { + clearIndex(itChild.next()); + } + delete index; +} + +void QtAbstractPropertyBrowserPrivate::slotPropertyInserted(QtProperty *property, + QtProperty *parentProperty, QtProperty *afterProperty) +{ + if (!m_propertyToParents.contains(parentProperty)) + return; + createBrowserIndexes(property, parentProperty, afterProperty); + insertSubTree(property, parentProperty); + //q_ptr->propertyInserted(property, parentProperty, afterProperty); +} + +void QtAbstractPropertyBrowserPrivate::slotPropertyRemoved(QtProperty *property, + QtProperty *parentProperty) +{ + if (!m_propertyToParents.contains(parentProperty)) + return; + removeSubTree(property, parentProperty); // this line should be probably moved down after propertyRemoved call + //q_ptr->propertyRemoved(property, parentProperty); + removeBrowserIndexes(property, parentProperty); +} + +void QtAbstractPropertyBrowserPrivate::slotPropertyDestroyed(QtProperty *property) +{ + if (!m_subItems.contains(property)) + return; + q_ptr->removeProperty(property); +} + +void QtAbstractPropertyBrowserPrivate::slotPropertyDataChanged(QtProperty *property) +{ + if (!m_propertyToParents.contains(property)) + return; + + QMap >::ConstIterator it = + m_propertyToIndexes.find(property); + if (it == m_propertyToIndexes.constEnd()) + return; + + QList indexes = it.value(); + QListIterator itIndex(indexes); + while (itIndex.hasNext()) { + QtBrowserItem *idx = itIndex.next(); + q_ptr->itemChanged(idx); + } + //q_ptr->propertyChanged(property); +} + +/*! + \class QtAbstractPropertyBrowser + + \brief QtAbstractPropertyBrowser provides a base class for + implementing property browsers. + + A property browser is a widget that enables the user to edit a + given set of properties. Each property is represented by a label + specifying the property's name, and an editing widget (e.g. a line + edit or a combobox) holding its value. A property can have zero or + more subproperties. + + \image qtpropertybrowser.png + + The top level properties can be retrieved using the + properties() function. To traverse each property's + subproperties, use the QtProperty::subProperties() function. In + addition, the set of top level properties can be manipulated using + the addProperty(), insertProperty() and removeProperty() + functions. Note that the QtProperty class provides a corresponding + set of functions making it possible to manipulate the set of + subproperties as well. + + To remove all the properties from the property browser widget, use + the clear() function. This function will clear the editor, but it + will not delete the properties since they can still be used in + other editors. + + The properties themselves are created and managed by + implementations of the QtAbstractPropertyManager class. A manager + can handle (i.e. create and manage) properties of a given type. In + the property browser the managers are associated with + implementations of the QtAbstractEditorFactory: A factory is a + class able to create an editing widget of a specified type. + + When using a property browser widget, managers must be created for + each of the required property types before the properties + themselves can be created. To ensure that the properties' values + will be displayed using suitable editing widgets, the managers + must be associated with objects of the preferred factory + implementations using the setFactoryForManager() function. The + property browser will use these associations to determine which + factory it should use to create the preferred editing widget. + + Note that a factory can be associated with many managers, but a + manager can only be associated with one single factory within the + context of a single property browser. The associations between + managers and factories can at any time be removed using the + unsetFactoryForManager() function. + + Whenever the property data changes or a property is inserted or + removed, the itemChanged(), itemInserted() or + itemRemoved() functions are called, respectively. These + functions must be reimplemented in derived classes in order to + update the property browser widget. Be aware that some property + instances can appear several times in an abstract tree + structure. For example: + + \table 100% + \row + \o + \code + QtProperty *property1, *property2, *property3; + + property2->addSubProperty(property1); + property3->addSubProperty(property2); + + QtAbstractPropertyBrowser *editor; + + editor->addProperty(property1); + editor->addProperty(property2); + editor->addProperty(property3); + \endcode + \o \image qtpropertybrowser-duplicate.png + \endtable + + The addProperty() function returns a QtBrowserItem that uniquely + identifies the created item. + + To make a property editable in the property browser, the + createEditor() function must be called to provide the + property with a suitable editing widget. + + Note that there are two ready-made property browser + implementations: + + \list + \o QtGroupBoxPropertyBrowser + \o QtTreePropertyBrowser + \endlist + + \sa QtAbstractPropertyManager, QtAbstractEditorFactoryBase +*/ + +/*! + \fn void QtAbstractPropertyBrowser::setFactoryForManager(PropertyManager *manager, + QtAbstractEditorFactory *factory) + + Connects the given \a manager to the given \a factory, ensuring + that properties of the \a manager's type will be displayed with an + editing widget suitable for their value. + + For example: + + \code + QtIntPropertyManager *intManager; + QtDoublePropertyManager *doubleManager; + + QtProperty *myInteger = intManager->addProperty(); + QtProperty *myDouble = doubleManager->addProperty(); + + QtSpinBoxFactory *spinBoxFactory; + QtDoubleSpinBoxFactory *doubleSpinBoxFactory; + + QtAbstractPropertyBrowser *editor; + editor->setFactoryForManager(intManager, spinBoxFactory); + editor->setFactoryForManager(doubleManager, doubleSpinBoxFactory); + + editor->addProperty(myInteger); + editor->addProperty(myDouble); + \endcode + + In this example the \c myInteger property's value is displayed + with a QSpinBox widget, while the \c myDouble property's value is + displayed with a QDoubleSpinBox widget. + + Note that a factory can be associated with many managers, but a + manager can only be associated with one single factory. If the + given \a manager already is associated with another factory, the + old association is broken before the new one established. + + This function ensures that the given \a manager and the given \a + factory are compatible, and it automatically calls the + QtAbstractEditorFactory::addPropertyManager() function if necessary. + + \sa unsetFactoryForManager() +*/ + +/*! + \fn virtual void QtAbstractPropertyBrowser::itemInserted(QtBrowserItem *insertedItem, + QtBrowserItem *precedingItem) = 0 + + This function is called to update the widget whenever a property + is inserted or added to the property browser, passing pointers to + the \a insertedItem of property and the specified + \a precedingItem as parameters. + + If \a precedingItem is 0, the \a insertedItem was put at + the beginning of its parent item's list of subproperties. If + the parent of \a insertedItem is 0, the \a insertedItem was added as a top + level property of \e this property browser. + + This function must be reimplemented in derived classes. Note that + if the \a insertedItem's property has subproperties, this + method will be called for those properties as soon as the current call is finished. + + \sa insertProperty(), addProperty() +*/ + +/*! + \fn virtual void QtAbstractPropertyBrowser::itemRemoved(QtBrowserItem *item) = 0 + + This function is called to update the widget whenever a property + is removed from the property browser, passing the pointer to the + \a item of the property as parameters. The passed \a item is + deleted just after this call is finished. + + If the the parent of \a item is 0, the removed \a item was a + top level property in this editor. + + This function must be reimplemented in derived classes. Note that + if the removed \a item's property has subproperties, this + method will be called for those properties just before the current call is started. + + \sa removeProperty() +*/ + +/*! + \fn virtual void QtAbstractPropertyBrowser::itemChanged(QtBrowserItem *item) = 0 + + This function is called whenever a property's data changes, + passing a pointer to the \a item of property as parameter. + + This function must be reimplemented in derived classes in order to + update the property browser widget whenever a property's name, + tool tip, status tip, "what's this" text, value text or value icon + changes. + + Note that if the property browser contains several occurrences of + the same property, this method will be called once for each + occurrence (with a different item each time). + + \sa QtProperty, items() +*/ + +/*! + Creates an abstract property browser with the given \a parent. +*/ +QtAbstractPropertyBrowser::QtAbstractPropertyBrowser(QWidget *parent) + : QWidget(parent) +{ + d_ptr = new QtAbstractPropertyBrowserPrivate; + d_ptr->q_ptr = this; + +} + +/*! + Destroys the property browser, and destroys all the items that were + created by this property browser. + + Note that the properties that were displayed in the editor are not + deleted since they still can be used in other editors. Neither + does the destructor delete the property managers and editor + factories that were used by this property browser widget unless + this widget was their parent. + + \sa QtAbstractPropertyManager::~QtAbstractPropertyManager() +*/ +QtAbstractPropertyBrowser::~QtAbstractPropertyBrowser() +{ + QList indexes = topLevelItems(); + QListIterator itItem(indexes); + while (itItem.hasNext()) + d_ptr->clearIndex(itItem.next()); + delete d_ptr; +} + +/*! + Returns the property browser's list of top level properties. + + To traverse the subproperties, use the QtProperty::subProperties() + function. + + \sa addProperty(), insertProperty(), removeProperty() +*/ +QList QtAbstractPropertyBrowser::properties() const +{ + return d_ptr->m_subItems; +} + +/*! + Returns the property browser's list of all items associated + with the given \a property. + + There is one item per instance of the property in the browser. + + \sa topLevelItem() +*/ + +QList QtAbstractPropertyBrowser::items(QtProperty *property) const +{ + return d_ptr->m_propertyToIndexes.value(property); +} + +/*! + Returns the top-level items associated with the given \a property. + + Returns 0 if \a property wasn't inserted into this property + browser or isn't a top-level one. + + \sa topLevelItems(), items() +*/ + +QtBrowserItem *QtAbstractPropertyBrowser::topLevelItem(QtProperty *property) const +{ + return d_ptr->m_topLevelPropertyToIndex.value(property); +} + +/*! + Returns the list of top-level items. + + \sa topLevelItem() +*/ + +QList QtAbstractPropertyBrowser::topLevelItems() const +{ + return d_ptr->m_topLevelIndexes; +} + +/*! + Removes all the properties from the editor, but does not delete + them since they can still be used in other editors. + + \sa removeProperty(), QtAbstractPropertyManager::clear() +*/ +void QtAbstractPropertyBrowser::clear() +{ + QList subList = properties(); + QListIterator itSub(subList); + itSub.toBack(); + while (itSub.hasPrevious()) { + QtProperty *property = itSub.previous(); + removeProperty(property); + } +} + +/*! + Appends the given \a property (and its subproperties) to the + property browser's list of top level properties. Returns the item + created by property browser which is associated with the \a property. + In order to get all children items created by the property + browser in this call, the returned item should be traversed. + + If the specified \a property is already added, this function does + nothing and returns 0. + + \sa insertProperty(), QtProperty::addSubProperty(), properties() +*/ +QtBrowserItem *QtAbstractPropertyBrowser::addProperty(QtProperty *property) +{ + QtProperty *afterProperty = 0; + if (d_ptr->m_subItems.count() > 0) + afterProperty = d_ptr->m_subItems.last(); + return insertProperty(property, afterProperty); +} + +/*! + \fn QtBrowserItem *QtAbstractPropertyBrowser::insertProperty(QtProperty *property, + QtProperty *afterProperty) + + Inserts the given \a property (and its subproperties) after + the specified \a afterProperty in the browser's list of top + level properties. Returns item created by property browser which + is associated with the \a property. In order to get all children items + created by the property browser in this call returned item should be traversed. + + If the specified \a afterProperty is 0, the given \a property is + inserted at the beginning of the list. If \a property is + already inserted, this function does nothing and returns 0. + + \sa addProperty(), QtProperty::insertSubProperty(), properties() +*/ +QtBrowserItem *QtAbstractPropertyBrowser::insertProperty(QtProperty *property, + QtProperty *afterProperty) +{ + if (!property) + return 0; + + // if item is already inserted in this item then cannot add. + QList pendingList = properties(); + int pos = 0; + int newPos = 0; + QtProperty *properAfterProperty = 0; + while (pos < pendingList.count()) { + QtProperty *prop = pendingList.at(pos); + if (prop == property) + return 0; + if (prop == afterProperty) { + newPos = pos + 1; + properAfterProperty = afterProperty; + } + pos++; + } + d_ptr->createBrowserIndexes(property, 0, afterProperty); + + // traverse inserted subtree and connect to manager's signals + d_ptr->insertSubTree(property, 0); + + d_ptr->m_subItems.insert(newPos, property); + //propertyInserted(property, 0, properAfterProperty); + return topLevelItem(property); +} + +/*! + Removes the specified \a property (and its subproperties) from the + property browser's list of top level properties. All items + that were associated with the given \a property and its children + are deleted. + + Note that the properties are \e not deleted since they can still + be used in other editors. + + \sa clear(), QtProperty::removeSubProperty(), properties() +*/ +void QtAbstractPropertyBrowser::removeProperty(QtProperty *property) +{ + if (!property) + return; + + QList pendingList = properties(); + int pos = 0; + while (pos < pendingList.count()) { + if (pendingList.at(pos) == property) { + d_ptr->m_subItems.removeAt(pos); //perhaps this two lines + d_ptr->removeSubTree(property, 0); //should be moved down after propertyRemoved call. + //propertyRemoved(property, 0); + + d_ptr->removeBrowserIndexes(property, 0); + + // when item is deleted, item will call removeItem for top level items, + // and itemRemoved for nested items. + + return; + } + pos++; + } +} + +/*! + Creates an editing widget (with the given \a parent) for the given + \a property according to the previously established associations + between property managers and editor factories. + + If the property is created by a property manager which was not + associated with any of the existing factories in \e this property + editor, the function returns 0. + + To make a property editable in the property browser, the + createEditor() function must be called to provide the + property with a suitable editing widget. + + Reimplement this function to provide additional decoration for the + editing widgets created by the installed factories. + + \sa setFactoryForManager() +*/ +QWidget *QtAbstractPropertyBrowser::createEditor(QtProperty *property, + QWidget *parent) +{ + QtAbstractEditorFactoryBase *factory = 0; + QtAbstractPropertyManager *manager = property->propertyManager(); + + if (m_viewToManagerToFactory()->contains(this) && + (*m_viewToManagerToFactory())[this].contains(manager)) { + factory = (*m_viewToManagerToFactory())[this][manager]; + } + + if (!factory) + return 0; + return factory->createEditor(property, parent); +} + +bool QtAbstractPropertyBrowser::addFactory(QtAbstractPropertyManager *abstractManager, + QtAbstractEditorFactoryBase *abstractFactory) +{ + bool connectNeeded = false; + if (!m_managerToFactoryToViews()->contains(abstractManager) || + !(*m_managerToFactoryToViews())[abstractManager].contains(abstractFactory)) { + connectNeeded = true; + } else if ((*m_managerToFactoryToViews())[abstractManager][abstractFactory] + .contains(this)) { + return connectNeeded; + } + + if (m_viewToManagerToFactory()->contains(this) && + (*m_viewToManagerToFactory())[this].contains(abstractManager)) { + unsetFactoryForManager(abstractManager); + } + + (*m_managerToFactoryToViews())[abstractManager][abstractFactory].append(this); + (*m_viewToManagerToFactory())[this][abstractManager] = abstractFactory; + + return connectNeeded; +} + +/*! + Removes the association between the given \a manager and the + factory bound to it, automatically calling the + QtAbstractEditorFactory::removePropertyManager() function if necessary. + + \sa setFactoryForManager() +*/ +void QtAbstractPropertyBrowser::unsetFactoryForManager(QtAbstractPropertyManager *manager) +{ + if (!m_viewToManagerToFactory()->contains(this) || + !(*m_viewToManagerToFactory())[this].contains(manager)) { + return; + } + + QtAbstractEditorFactoryBase *abstractFactory = + (*m_viewToManagerToFactory())[this][manager]; + (*m_viewToManagerToFactory())[this].remove(manager); + if ((*m_viewToManagerToFactory())[this].isEmpty()) { + (*m_viewToManagerToFactory()).remove(this); + } + + (*m_managerToFactoryToViews())[manager][abstractFactory].removeAll(this); + if ((*m_managerToFactoryToViews())[manager][abstractFactory].isEmpty()) { + (*m_managerToFactoryToViews())[manager].remove(abstractFactory); + abstractFactory->breakConnection(manager); + if ((*m_managerToFactoryToViews())[manager].isEmpty()) { + (*m_managerToFactoryToViews()).remove(manager); + } + } +} + +/*! + Returns the current item in the property browser. + + \sa setCurrentItem() +*/ +QtBrowserItem *QtAbstractPropertyBrowser::currentItem() const +{ + return d_ptr->m_currentItem; +} + +/*! + Sets the current item in the property browser to \a item. + + \sa currentItem(), currentItemChanged() +*/ +void QtAbstractPropertyBrowser::setCurrentItem(QtBrowserItem *item) +{ + QtBrowserItem *oldItem = d_ptr->m_currentItem; + d_ptr->m_currentItem = item; + if (oldItem != item) + emit currentItemChanged(item); +} + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +#include "moc_qtpropertybrowser.cxx" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowser.h b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowser.h new file mode 100644 index 000000000..35b7ac0f8 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowser.h @@ -0,0 +1,379 @@ +/**************************************************************************** +** +** This file is part of a Qt Solutions component. +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTPROPERTYBROWSER_H +#define QTPROPERTYBROWSER_H + +#include +#include + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +#if defined(Q_WS_WIN) +# if !defined(QT_QTPROPERTYBROWSER_EXPORT) && !defined(QT_QTPROPERTYBROWSER_IMPORT) +# define QT_QTPROPERTYBROWSER_EXPORT +# elif defined(QT_QTPROPERTYBROWSER_IMPORT) +# if defined(QT_QTPROPERTYBROWSER_EXPORT) +# undef QT_QTPROPERTYBROWSER_EXPORT +# endif +# define QT_QTPROPERTYBROWSER_EXPORT __declspec(dllimport) +# elif defined(QT_QTPROPERTYBROWSER_EXPORT) +# undef QT_QTPROPERTYBROWSER_EXPORT +# define QT_QTPROPERTYBROWSER_EXPORT __declspec(dllexport) +# endif +#else +# define QT_QTPROPERTYBROWSER_EXPORT +#endif + + +class QtAbstractPropertyManager; +class QtPropertyPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtProperty +{ +public: + virtual ~QtProperty(); + + QList subProperties() const; + + QtAbstractPropertyManager *propertyManager() const; + + QString toolTip() const; + QString statusTip() const; + QString whatsThis() const; + QString propertyName() const; + + bool isEnabled() const; + bool isModified() const; + bool isBold() const; + + bool hasValue() const; + QIcon valueIcon() const; + QString valueText() const; + + void setToolTip(const QString &text); + void setStatusTip(const QString &text); + void setWhatsThis(const QString &text); + void setPropertyName(const QString &text); + void setEnabled(bool enable); + void setModified(bool modified); + void setBold(bool bold); + + void addSubProperty(QtProperty *property); + void insertSubProperty(QtProperty *property, QtProperty *afterProperty); + void removeSubProperty(QtProperty *property); +protected: + explicit QtProperty(QtAbstractPropertyManager *manager); + void propertyChanged(); +private: + friend class QtAbstractPropertyManager; + QtPropertyPrivate *d_ptr; +}; + +class QtAbstractPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtAbstractPropertyManager : public QObject +{ + Q_OBJECT +public: + + explicit QtAbstractPropertyManager(QObject *parent = 0); + ~QtAbstractPropertyManager(); + + QSet properties() const; + void clear() const; + + QtProperty *addProperty(const QString &name = QString()); +Q_SIGNALS: + + void propertyInserted(QtProperty *property, + QtProperty *parent, QtProperty *after); + void propertyChanged(QtProperty *property); + void propertyRemoved(QtProperty *property, QtProperty *parent); + void propertyDestroyed(QtProperty *property); +protected: + virtual bool hasValue(const QtProperty *property) const; + virtual QIcon valueIcon(const QtProperty *property) const; + virtual QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property) = 0; + virtual void uninitializeProperty(QtProperty *property); + virtual QtProperty *createProperty(); +private: + friend class QtProperty; + QtAbstractPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtAbstractPropertyManager) + Q_DISABLE_COPY(QtAbstractPropertyManager) +}; + +class QT_QTPROPERTYBROWSER_EXPORT QtAbstractEditorFactoryBase : public QObject +{ + Q_OBJECT +public: + virtual QWidget *createEditor(QtProperty *property, QWidget *parent) = 0; +protected: + explicit QtAbstractEditorFactoryBase(QObject *parent = 0) + : QObject(parent) {} + + virtual void breakConnection(QtAbstractPropertyManager *manager) = 0; +protected Q_SLOTS: + virtual void managerDestroyed(QObject *manager) = 0; + + friend class QtAbstractPropertyBrowser; +}; + +template +class QtAbstractEditorFactory : public QtAbstractEditorFactoryBase +{ +public: + explicit QtAbstractEditorFactory(QObject *parent) : QtAbstractEditorFactoryBase(parent) {} + QWidget *createEditor(QtProperty *property, QWidget *parent) + { + QSetIterator it(m_managers); + while (it.hasNext()) { + PropertyManager *manager = it.next(); + if (manager == property->propertyManager()) { + return createEditor(manager, property, parent); + } + } + return 0; + } + void addPropertyManager(PropertyManager *manager) + { + if (m_managers.contains(manager)) + return; + m_managers.insert(manager); + connectPropertyManager(manager); + connect(manager, SIGNAL(destroyed(QObject *)), + this, SLOT(managerDestroyed(QObject *))); + } + void removePropertyManager(PropertyManager *manager) + { + if (!m_managers.contains(manager)) + return; + disconnect(manager, SIGNAL(destroyed(QObject *)), + this, SLOT(managerDestroyed(QObject *))); + disconnectPropertyManager(manager); + m_managers.remove(manager); + } + QSet propertyManagers() const + { + return m_managers; + } + PropertyManager *propertyManager(QtProperty *property) const + { + QtAbstractPropertyManager *manager = property->propertyManager(); + QSetIterator itManager(m_managers); + while (itManager.hasNext()) { + PropertyManager *m = itManager.next(); + if (m == manager) { + return m; + } + } + return 0; + } +protected: + virtual void connectPropertyManager(PropertyManager *manager) = 0; + virtual QWidget *createEditor(PropertyManager *manager, QtProperty *property, + QWidget *parent) = 0; + virtual void disconnectPropertyManager(PropertyManager *manager) = 0; + void managerDestroyed(QObject *manager) + { + QSetIterator it(m_managers); + while (it.hasNext()) { + PropertyManager *m = it.next(); + if (m == manager) { + m_managers.remove(m); + return; + } + } + } +private: + void breakConnection(QtAbstractPropertyManager *manager) + { + QSetIterator it(m_managers); + while (it.hasNext()) { + PropertyManager *m = it.next(); + if (m == manager) { + removePropertyManager(m); + return; + } + } + } +private: + QSet m_managers; + friend class QtAbstractPropertyEditor; +}; + +class QtAbstractPropertyBrowser; +class QtBrowserItemPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtBrowserItem +{ +public: + QtProperty *property() const; + QtBrowserItem *parent() const; + QList children() const; + QtAbstractPropertyBrowser *browser() const; +private: + explicit QtBrowserItem(QtAbstractPropertyBrowser *browser, QtProperty *property, QtBrowserItem *parent); + ~QtBrowserItem(); + QtBrowserItemPrivate *d_ptr; + friend class QtAbstractPropertyBrowserPrivate; +}; + +class QtAbstractPropertyBrowserPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtAbstractPropertyBrowser : public QWidget +{ + Q_OBJECT +public: + + explicit QtAbstractPropertyBrowser(QWidget *parent = 0); + ~QtAbstractPropertyBrowser(); + + QList properties() const; + QList items(QtProperty *property) const; + QtBrowserItem *topLevelItem(QtProperty *property) const; + QList topLevelItems() const; + void clear(); + + template + void setFactoryForManager(PropertyManager *manager, + QtAbstractEditorFactory *factory) { + QtAbstractPropertyManager *abstractManager = manager; + QtAbstractEditorFactoryBase *abstractFactory = factory; + + if (addFactory(abstractManager, abstractFactory)) + factory->addPropertyManager(manager); + } + + void unsetFactoryForManager(QtAbstractPropertyManager *manager); + + QtBrowserItem *currentItem() const; + void setCurrentItem(QtBrowserItem *); + +Q_SIGNALS: + void currentItemChanged(QtBrowserItem *); + +public Q_SLOTS: + + QtBrowserItem *addProperty(QtProperty *property); + QtBrowserItem *insertProperty(QtProperty *property, QtProperty *afterProperty); + void removeProperty(QtProperty *property); + +protected: + + virtual void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem) = 0; + virtual void itemRemoved(QtBrowserItem *item) = 0; + // can be tooltip, statustip, whatsthis, name, icon, text. + virtual void itemChanged(QtBrowserItem *item) = 0; + + virtual QWidget *createEditor(QtProperty *property, QWidget *parent); +private: + + bool addFactory(QtAbstractPropertyManager *abstractManager, + QtAbstractEditorFactoryBase *abstractFactory); + + QtAbstractPropertyBrowserPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtAbstractPropertyBrowser) + Q_DISABLE_COPY(QtAbstractPropertyBrowser) + Q_PRIVATE_SLOT(d_func(), void slotPropertyInserted(QtProperty *, + QtProperty *, QtProperty *)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyRemoved(QtProperty *, + QtProperty *)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDataChanged(QtProperty *)) + +}; + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +#endif // QTPROPERTYBROWSER_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowser.pri b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowser.pri new file mode 100644 index 000000000..6a6050c75 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowser.pri @@ -0,0 +1,30 @@ +include(../common.pri) +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD + +qtpropertybrowser-uselib:!qtpropertybrowser-buildlib { + LIBS += -L$$QTPROPERTYBROWSER_LIBDIR -l$$QTPROPERTYBROWSER_LIBNAME +} else { + SOURCES += $$PWD/qtpropertybrowser.cpp \ + $$PWD/qtpropertymanager.cpp \ + $$PWD/qteditorfactory.cpp \ + $$PWD/qtvariantproperty.cpp \ + $$PWD/qttreepropertybrowser.cpp \ + $$PWD/qtbuttonpropertybrowser.cpp \ + $$PWD/qtgroupboxpropertybrowser.cpp \ + $$PWD/qtpropertybrowserutils.cpp + HEADERS += $$PWD/qtpropertybrowser.h \ + $$PWD/qtpropertymanager.h \ + $$PWD/qteditorfactory.h \ + $$PWD/qtvariantproperty.h \ + $$PWD/qttreepropertybrowser.h \ + $$PWD/qtbuttonpropertybrowser.h \ + $$PWD/qtgroupboxpropertybrowser.h \ + $$PWD/qtpropertybrowserutils_p.h + RESOURCES += $$PWD/qtpropertybrowser.qrc +} + +win32 { + contains(TEMPLATE, lib):contains(CONFIG, shared):DEFINES += QT_QTPROPERTYBROWSER_EXPORT + else:qtpropertybrowser-uselib:DEFINES += QT_QTPROPERTYBROWSER_IMPORT +} diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowser.qrc b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowser.qrc new file mode 100644 index 000000000..4f91ab782 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowser.qrc @@ -0,0 +1,23 @@ + + + images/cursor-arrow.png + images/cursor-busy.png + images/cursor-closedhand.png + images/cursor-cross.png + images/cursor-forbidden.png + images/cursor-hand.png + images/cursor-hsplit.png + images/cursor-ibeam.png + images/cursor-openhand.png + images/cursor-sizeall.png + images/cursor-sizeb.png + images/cursor-sizef.png + images/cursor-sizeh.png + images/cursor-sizev.png + images/cursor-uparrow.png + images/cursor-vsplit.png + images/cursor-wait.png + images/cursor-whatsthis.png + + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowserutils.cpp b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowserutils.cpp new file mode 100644 index 000000000..ce198bfca --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowserutils.cpp @@ -0,0 +1,477 @@ +/**************************************************************************** +** +** This file is part of a Qt Solutions component. +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtpropertybrowserutils_p.h" +#include +#include +#include +#include +#include +#include +#include + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +QtCursorDatabase::QtCursorDatabase() +{ + appendCursor(Qt::ArrowCursor, QApplication::translate("QtCursorDatabase", "Arrow", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-arrow.png"))); + appendCursor(Qt::UpArrowCursor, QApplication::translate("QtCursorDatabase", "Up Arrow", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-uparrow.png"))); + appendCursor(Qt::CrossCursor, QApplication::translate("QtCursorDatabase", "Cross", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-cross.png"))); + appendCursor(Qt::WaitCursor, QApplication::translate("QtCursorDatabase", "Wait", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-wait.png"))); + appendCursor(Qt::IBeamCursor, QApplication::translate("QtCursorDatabase", "IBeam", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-ibeam.png"))); + appendCursor(Qt::SizeVerCursor, QApplication::translate("QtCursorDatabase", "Size Vertical", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-sizev.png"))); + appendCursor(Qt::SizeHorCursor, QApplication::translate("QtCursorDatabase", "Size Horizontal", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-sizeh.png"))); + appendCursor(Qt::SizeFDiagCursor, QApplication::translate("QtCursorDatabase", "Size Backslash", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-sizef.png"))); + appendCursor(Qt::SizeBDiagCursor, QApplication::translate("QtCursorDatabase", "Size Slash", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-sizeb.png"))); + appendCursor(Qt::SizeAllCursor, QApplication::translate("QtCursorDatabase", "Size All", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-sizeall.png"))); + appendCursor(Qt::BlankCursor, QApplication::translate("QtCursorDatabase", "Blank", 0, + QApplication::UnicodeUTF8), QIcon()); + appendCursor(Qt::SplitVCursor, QApplication::translate("QtCursorDatabase", "Split Vertical", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-vsplit.png"))); + appendCursor(Qt::SplitHCursor, QApplication::translate("QtCursorDatabase", "Split Horizontal", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-hsplit.png"))); + appendCursor(Qt::PointingHandCursor, QApplication::translate("QtCursorDatabase", "Pointing Hand", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-hand.png"))); + appendCursor(Qt::ForbiddenCursor, QApplication::translate("QtCursorDatabase", "Forbidden", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-forbidden.png"))); + appendCursor(Qt::OpenHandCursor, QApplication::translate("QtCursorDatabase", "Open Hand", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-openhand.png"))); + appendCursor(Qt::ClosedHandCursor, QApplication::translate("QtCursorDatabase", "Closed Hand", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-closedhand.png"))); + appendCursor(Qt::WhatsThisCursor, QApplication::translate("QtCursorDatabase", "What's This", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-whatsthis.png"))); + appendCursor(Qt::BusyCursor, QApplication::translate("QtCursorDatabase", "Busy", 0, + QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-busy.png"))); +} + +void QtCursorDatabase::appendCursor(Qt::CursorShape shape, const QString &name, const QIcon &icon) +{ + if (m_cursorShapeToValue.contains(shape)) + return; + int value = m_cursorNames.count(); + m_cursorNames.append(name); + m_cursorIcons[value] = icon; + m_valueToCursorShape[value] = shape; + m_cursorShapeToValue[shape] = value; +} + +QStringList QtCursorDatabase::cursorShapeNames() const +{ + return m_cursorNames; +} + +QMap QtCursorDatabase::cursorShapeIcons() const +{ + return m_cursorIcons; +} + +QString QtCursorDatabase::cursorToShapeName(const QCursor &cursor) const +{ + int val = cursorToValue(cursor); + if (val >= 0) + return m_cursorNames.at(val); + return QString(); +} + +QIcon QtCursorDatabase::cursorToShapeIcon(const QCursor &cursor) const +{ + int val = cursorToValue(cursor); + return m_cursorIcons.value(val); +} + +int QtCursorDatabase::cursorToValue(const QCursor &cursor) const +{ +#ifndef QT_NO_CURSOR + Qt::CursorShape shape = cursor.shape(); + if (m_cursorShapeToValue.contains(shape)) + return m_cursorShapeToValue[shape]; +#endif + return -1; +} + +#ifndef QT_NO_CURSOR +QCursor QtCursorDatabase::valueToCursor(int value) const +{ + if (m_valueToCursorShape.contains(value)) + return QCursor(m_valueToCursorShape[value]); + return QCursor(); +} +#endif + +QPixmap QtPropertyBrowserUtils::brushValuePixmap(const QBrush &b) +{ + QImage img(16, 16, QImage::Format_ARGB32_Premultiplied); + img.fill(0); + + QPainter painter(&img); + painter.setCompositionMode(QPainter::CompositionMode_Source); + painter.fillRect(0, 0, img.width(), img.height(), b); + QColor color = b.color(); + if (color.alpha() != 255) { // indicate alpha by an inset + QBrush opaqueBrush = b; + color.setAlpha(255); + opaqueBrush.setColor(color); + painter.fillRect(img.width() / 4, img.height() / 4, + img.width() / 2, img.height() / 2, opaqueBrush); + } + painter.end(); + return QPixmap::fromImage(img); +} + +QIcon QtPropertyBrowserUtils::brushValueIcon(const QBrush &b) +{ + return QIcon(brushValuePixmap(b)); +} + +QString QtPropertyBrowserUtils::colorValueText(const QColor &c) +{ + return QApplication::translate("QtPropertyBrowserUtils", "[%1, %2, %3] (%4)", 0, QApplication::UnicodeUTF8) + .arg(QString::number(c.red())) + .arg(QString::number(c.green())) + .arg(QString::number(c.blue())) + .arg(QString::number(c.alpha())); +} + +QPixmap QtPropertyBrowserUtils::fontValuePixmap(const QFont &font) +{ + QFont f = font; + QImage img(16, 16, QImage::Format_ARGB32_Premultiplied); + img.fill(0); + QPainter p(&img); + p.setRenderHint(QPainter::TextAntialiasing, true); + p.setRenderHint(QPainter::Antialiasing, true); + f.setPointSize(13); + p.setFont(f); + QTextOption t; + t.setAlignment(Qt::AlignCenter); + p.drawText(QRect(0, 0, 16, 16), QString(QLatin1Char('A')), t); + return QPixmap::fromImage(img); +} + +QIcon QtPropertyBrowserUtils::fontValueIcon(const QFont &f) +{ + return QIcon(fontValuePixmap(f)); +} + +QString QtPropertyBrowserUtils::fontValueText(const QFont &f) +{ + return QApplication::translate("QtPropertyBrowserUtils", "[%1, %2]", 0, QApplication::UnicodeUTF8) + .arg(f.family()) + .arg(f.pointSize()); +} + + +QtBoolEdit::QtBoolEdit(QWidget *parent) : + QWidget(parent), + m_checkBox(new QCheckBox(this)), + m_textVisible(true) +{ + QHBoxLayout *lt = new QHBoxLayout; + if (QApplication::layoutDirection() == Qt::LeftToRight) + lt->setContentsMargins(4, 0, 0, 0); + else + lt->setContentsMargins(0, 0, 4, 0); + lt->addWidget(m_checkBox); + setLayout(lt); + connect(m_checkBox, SIGNAL(toggled(bool)), this, SIGNAL(toggled(bool))); + setFocusProxy(m_checkBox); + m_checkBox->setText(QString()); +} + +void QtBoolEdit::setTextVisible(bool textVisible) +{ + if (m_textVisible == textVisible) + return; + + m_textVisible = textVisible; + m_checkBox->setText(QString()); +} + +Qt::CheckState QtBoolEdit::checkState() const +{ + return m_checkBox->checkState(); +} + +void QtBoolEdit::setCheckState(Qt::CheckState state) +{ + m_checkBox->setCheckState(state); +} + +bool QtBoolEdit::isChecked() const +{ + return m_checkBox->isChecked(); +} + +void QtBoolEdit::setChecked(bool c) +{ + m_checkBox->setChecked(c); + if (!m_textVisible) + return; + m_checkBox->setText(QString()); +} + +bool QtBoolEdit::blockCheckBoxSignals(bool block) +{ + return m_checkBox->blockSignals(block); +} + +void QtBoolEdit::mousePressEvent(QMouseEvent *event) +{ + if (event->buttons() == Qt::LeftButton) { + m_checkBox->click(); + event->accept(); + } else { + QWidget::mousePressEvent(event); + } +} + + +QtKeySequenceEdit::QtKeySequenceEdit(QWidget *parent) + : QWidget(parent), m_num(0), m_lineEdit(new QLineEdit(this)) +{ + QHBoxLayout *layout = new QHBoxLayout(this); + layout->addWidget(m_lineEdit); + layout->setMargin(0); + m_lineEdit->installEventFilter(this); + m_lineEdit->setReadOnly(true); + m_lineEdit->setFocusProxy(this); + setFocusPolicy(m_lineEdit->focusPolicy()); + setAttribute(Qt::WA_InputMethodEnabled); +} + +bool QtKeySequenceEdit::eventFilter(QObject *o, QEvent *e) +{ + if (o == m_lineEdit && e->type() == QEvent::ContextMenu) { + QContextMenuEvent *c = static_cast(e); + QMenu *menu = m_lineEdit->createStandardContextMenu(); + const QList actions = menu->actions(); + QListIterator itAction(actions); + while (itAction.hasNext()) { + QAction *action = itAction.next(); + action->setShortcut(QKeySequence()); + QString actionString = action->text(); + const int pos = actionString.lastIndexOf(QLatin1Char('\t')); + if (pos > 0) + actionString.remove(pos, actionString.length() - pos); + action->setText(actionString); + } + QAction *actionBefore = 0; + if (actions.count() > 0) + actionBefore = actions[0]; + QAction *clearAction = new QAction(tr("Clear Shortcut"), menu); + menu->insertAction(actionBefore, clearAction); + menu->insertSeparator(actionBefore); + clearAction->setEnabled(!m_keySequence.isEmpty()); + connect(clearAction, SIGNAL(triggered()), this, SLOT(slotClearShortcut())); + menu->exec(c->globalPos()); + delete menu; + e->accept(); + return true; + } + + return QWidget::eventFilter(o, e); +} + +void QtKeySequenceEdit::slotClearShortcut() +{ + if (m_keySequence.isEmpty()) + return; + setKeySequence(QKeySequence()); + emit keySequenceChanged(m_keySequence); +} + +void QtKeySequenceEdit::handleKeyEvent(QKeyEvent *e) +{ + int nextKey = e->key(); + if (nextKey == Qt::Key_Control || nextKey == Qt::Key_Shift || + nextKey == Qt::Key_Meta || nextKey == Qt::Key_Alt || + nextKey == Qt::Key_Super_L || nextKey == Qt::Key_AltGr) + return; + + nextKey |= translateModifiers(e->modifiers(), e->text()); + int k0 = m_keySequence[0]; + int k1 = m_keySequence[1]; + int k2 = m_keySequence[2]; + int k3 = m_keySequence[3]; + switch (m_num) { + case 0: k0 = nextKey; k1 = 0; k2 = 0; k3 = 0; break; + case 1: k1 = nextKey; k2 = 0; k3 = 0; break; + case 2: k2 = nextKey; k3 = 0; break; + case 3: k3 = nextKey; break; + default: break; + } + ++m_num; + if (m_num > 3) + m_num = 0; + m_keySequence = QKeySequence(k0, k1, k2, k3); + m_lineEdit->setText(m_keySequence.toString(QKeySequence::NativeText)); + e->accept(); + emit keySequenceChanged(m_keySequence); +} + +void QtKeySequenceEdit::setKeySequence(const QKeySequence &sequence) +{ + if (sequence == m_keySequence) + return; + m_num = 0; + m_keySequence = sequence; + m_lineEdit->setText(m_keySequence.toString(QKeySequence::NativeText)); +} + +QKeySequence QtKeySequenceEdit::keySequence() const +{ + return m_keySequence; +} + +int QtKeySequenceEdit::translateModifiers(Qt::KeyboardModifiers state, const QString &text) const +{ + int result = 0; + if ((state & Qt::ShiftModifier) && (text.size() == 0 || !text.at(0).isPrint() || text.at(0).isLetter() || text.at(0).isSpace())) + result |= Qt::SHIFT; + if (state & Qt::ControlModifier) + result |= Qt::CTRL; + if (state & Qt::MetaModifier) + result |= Qt::META; + if (state & Qt::AltModifier) + result |= Qt::ALT; + return result; +} + +void QtKeySequenceEdit::focusInEvent(QFocusEvent *e) +{ + m_lineEdit->event(e); + m_lineEdit->selectAll(); + QWidget::focusInEvent(e); +} + +void QtKeySequenceEdit::focusOutEvent(QFocusEvent *e) +{ + m_num = 0; + m_lineEdit->event(e); + QWidget::focusOutEvent(e); +} + +void QtKeySequenceEdit::keyPressEvent(QKeyEvent *e) +{ + handleKeyEvent(e); + e->accept(); +} + +void QtKeySequenceEdit::keyReleaseEvent(QKeyEvent *e) +{ + m_lineEdit->event(e); +} + +bool QtKeySequenceEdit::event(QEvent *e) +{ + if (e->type() == QEvent::Shortcut || + e->type() == QEvent::ShortcutOverride || + e->type() == QEvent::KeyRelease) { + e->accept(); + return true; + } + return QWidget::event(e); +} + + + + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowserutils_p.h b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowserutils_p.h new file mode 100644 index 000000000..dca4b8c37 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowserutils_p.h @@ -0,0 +1,207 @@ +/**************************************************************************** +** +** This file is part of a Qt Solutions component. +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of Qt Designer. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + +#ifndef QTPROPERTYBROWSERUTILS_H +#define QTPROPERTYBROWSERUTILS_H + +#include +#include +#include +#include + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +class QMouseEvent; +class QCheckBox; +class QLineEdit; + +class QtCursorDatabase +{ +public: + QtCursorDatabase(); + + QStringList cursorShapeNames() const; + QMap cursorShapeIcons() const; + QString cursorToShapeName(const QCursor &cursor) const; + QIcon cursorToShapeIcon(const QCursor &cursor) const; + int cursorToValue(const QCursor &cursor) const; +#ifndef QT_NO_CURSOR + QCursor valueToCursor(int value) const; +#endif +private: + void appendCursor(Qt::CursorShape shape, const QString &name, const QIcon &icon); + QStringList m_cursorNames; + QMap m_cursorIcons; + QMap m_valueToCursorShape; + QMap m_cursorShapeToValue; +}; + +class QtPropertyBrowserUtils +{ +public: + static QPixmap brushValuePixmap(const QBrush &b); + static QIcon brushValueIcon(const QBrush &b); + static QString colorValueText(const QColor &c); + static QPixmap fontValuePixmap(const QFont &f); + static QIcon fontValueIcon(const QFont &f); + static QString fontValueText(const QFont &f); +}; + +class QtBoolEdit : public QWidget { + Q_OBJECT +public: + QtBoolEdit(QWidget *parent = 0); + + bool textVisible() const { return m_textVisible; } + void setTextVisible(bool textVisible); + + Qt::CheckState checkState() const; + void setCheckState(Qt::CheckState state); + + bool isChecked() const; + void setChecked(bool c); + + bool blockCheckBoxSignals(bool block); + +Q_SIGNALS: + void toggled(bool); + +protected: + void mousePressEvent(QMouseEvent * event); + +private: + QCheckBox *m_checkBox; + bool m_textVisible; +}; + +class QtKeySequenceEdit : public QWidget +{ + Q_OBJECT +public: + QtKeySequenceEdit(QWidget *parent = 0); + + QKeySequence keySequence() const; + bool eventFilter(QObject *o, QEvent *e); +public Q_SLOTS: + void setKeySequence(const QKeySequence &sequence); +Q_SIGNALS: + void keySequenceChanged(const QKeySequence &sequence); +protected: + void focusInEvent(QFocusEvent *e); + void focusOutEvent(QFocusEvent *e); + void keyPressEvent(QKeyEvent *e); + void keyReleaseEvent(QKeyEvent *e); + bool event(QEvent *e); +private slots: + void slotClearShortcut(); +private: + void handleKeyEvent(QKeyEvent *e); + int translateModifiers(Qt::KeyboardModifiers state, const QString &text) const; + + int m_num; + QKeySequence m_keySequence; + QLineEdit *m_lineEdit; +}; + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +#endif diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.cpp b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.cpp new file mode 100644 index 000000000..20de19786 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.cpp @@ -0,0 +1,6465 @@ +/**************************************************************************** +** +** This file is part of a Qt Solutions component. +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtpropertymanager.h" +#include "qtpropertybrowserutils_p.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#if defined(Q_CC_MSVC) +# pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */ +#endif + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +template +static void setSimpleMinimumData(PrivateData *data, const Value &minVal) +{ + data->minVal = minVal; + if (data->maxVal < data->minVal) + data->maxVal = data->minVal; + + if (data->val < data->minVal) + data->val = data->minVal; +} + +template +static void setSimpleMaximumData(PrivateData *data, const Value &maxVal) +{ + data->maxVal = maxVal; + if (data->minVal > data->maxVal) + data->minVal = data->maxVal; + + if (data->val > data->maxVal) + data->val = data->maxVal; +} + +template +static void setSizeMinimumData(PrivateData *data, const Value &newMinVal) +{ + data->minVal = newMinVal; + if (data->maxVal.width() < data->minVal.width()) + data->maxVal.setWidth(data->minVal.width()); + if (data->maxVal.height() < data->minVal.height()) + data->maxVal.setHeight(data->minVal.height()); + + if (data->val.width() < data->minVal.width()) + data->val.setWidth(data->minVal.width()); + if (data->val.height() < data->minVal.height()) + data->val.setHeight(data->minVal.height()); +} + +template +static void setSizeMaximumData(PrivateData *data, const Value &newMaxVal) +{ + data->maxVal = newMaxVal; + if (data->minVal.width() > data->maxVal.width()) + data->minVal.setWidth(data->maxVal.width()); + if (data->minVal.height() > data->maxVal.height()) + data->minVal.setHeight(data->maxVal.height()); + + if (data->val.width() > data->maxVal.width()) + data->val.setWidth(data->maxVal.width()); + if (data->val.height() > data->maxVal.height()) + data->val.setHeight(data->maxVal.height()); +} + +template +static SizeValue qBoundSize(const SizeValue &minVal, const SizeValue &val, const SizeValue &maxVal) +{ + SizeValue croppedVal = val; + if (minVal.width() > val.width()) + croppedVal.setWidth(minVal.width()); + else if (maxVal.width() < val.width()) + croppedVal.setWidth(maxVal.width()); + + if (minVal.height() > val.height()) + croppedVal.setHeight(minVal.height()); + else if (maxVal.height() < val.height()) + croppedVal.setHeight(maxVal.height()); + + return croppedVal; +} + +// Match the exact signature of qBound for VS 6. +QSize qBound(QSize minVal, QSize val, QSize maxVal) +{ + return qBoundSize(minVal, val, maxVal); +} + +QSizeF qBound(QSizeF minVal, QSizeF val, QSizeF maxVal) +{ + return qBoundSize(minVal, val, maxVal); +} + +namespace { + +namespace { +template +void orderBorders(Value &minVal, Value &maxVal) +{ + if (minVal > maxVal) + qSwap(minVal, maxVal); +} + +template +static void orderSizeBorders(Value &minVal, Value &maxVal) +{ + Value fromSize = minVal; + Value toSize = maxVal; + if (fromSize.width() > toSize.width()) { + fromSize.setWidth(maxVal.width()); + toSize.setWidth(minVal.width()); + } + if (fromSize.height() > toSize.height()) { + fromSize.setHeight(maxVal.height()); + toSize.setHeight(minVal.height()); + } + minVal = fromSize; + maxVal = toSize; +} + +void orderBorders(QSize &minVal, QSize &maxVal) +{ + orderSizeBorders(minVal, maxVal); +} + +void orderBorders(QSizeF &minVal, QSizeF &maxVal) +{ + orderSizeBorders(minVal, maxVal); +} + +} +} +//////// + +template +static Value getData(const QMap &propertyMap, + Value PrivateData::*data, + const QtProperty *property, const Value &defaultValue = Value()) +{ + typedef QMap PropertyToData; + typedef Q_TYPENAME PropertyToData::const_iterator PropertyToDataConstIterator; + const PropertyToDataConstIterator it = propertyMap.constFind(property); + if (it == propertyMap.constEnd()) + return defaultValue; + return it.value().*data; +} + +template +static Value getValue(const QMap &propertyMap, + const QtProperty *property, const Value &defaultValue = Value()) +{ + return getData(propertyMap, &PrivateData::val, property, defaultValue); +} + +template +static Value getMinimum(const QMap &propertyMap, + const QtProperty *property, const Value &defaultValue = Value()) +{ + return getData(propertyMap, &PrivateData::minVal, property, defaultValue); +} + +template +static Value getMaximum(const QMap &propertyMap, + const QtProperty *property, const Value &defaultValue = Value()) +{ + return getData(propertyMap, &PrivateData::maxVal, property, defaultValue); +} + +template +static void setSimpleValue(QMap &propertyMap, + PropertyManager *manager, + void (PropertyManager::*propertyChangedSignal)(QtProperty *), + void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter), + QtProperty *property, const Value &val) +{ + typedef QMap PropertyToData; + typedef Q_TYPENAME PropertyToData::iterator PropertyToDataIterator; + const PropertyToDataIterator it = propertyMap.find(property); + if (it == propertyMap.end()) + return; + + if (it.value() == val) + return; + + it.value() = val; + + emit (manager->*propertyChangedSignal)(property); + emit (manager->*valueChangedSignal)(property, val); +} + +template +static void setValueInRange(PropertyManager *manager, PropertyManagerPrivate *managerPrivate, + void (PropertyManager::*propertyChangedSignal)(QtProperty *), + void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter), + QtProperty *property, const Value &val, + void (PropertyManagerPrivate::*setSubPropertyValue)(QtProperty *, ValueChangeParameter)) +{ + typedef Q_TYPENAME PropertyManagerPrivate::Data PrivateData; + typedef QMap PropertyToData; + typedef Q_TYPENAME PropertyToData::iterator PropertyToDataIterator; + const PropertyToDataIterator it = managerPrivate->m_values.find(property); + if (it == managerPrivate->m_values.end()) + return; + + PrivateData &data = it.value(); + + if (data.val == val) + return; + + const Value oldVal = data.val; + + data.val = qBound(data.minVal, val, data.maxVal); + + if (data.val == oldVal) + return; + + if (setSubPropertyValue) + (managerPrivate->*setSubPropertyValue)(property, data.val); + + emit (manager->*propertyChangedSignal)(property); + emit (manager->*valueChangedSignal)(property, data.val); +} + +template +static void setBorderValues(PropertyManager *manager, PropertyManagerPrivate *managerPrivate, + void (PropertyManager::*propertyChangedSignal)(QtProperty *), + void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter), + void (PropertyManager::*rangeChangedSignal)(QtProperty *, ValueChangeParameter, ValueChangeParameter), + QtProperty *property, const Value &minVal, const Value &maxVal, + void (PropertyManagerPrivate::*setSubPropertyRange)(QtProperty *, + ValueChangeParameter, ValueChangeParameter, ValueChangeParameter)) +{ + typedef Q_TYPENAME PropertyManagerPrivate::Data PrivateData; + typedef QMap PropertyToData; + typedef Q_TYPENAME PropertyToData::iterator PropertyToDataIterator; + const PropertyToDataIterator it = managerPrivate->m_values.find(property); + if (it == managerPrivate->m_values.end()) + return; + + Value fromVal = minVal; + Value toVal = maxVal; + orderBorders(fromVal, toVal); + + PrivateData &data = it.value(); + + if (data.minVal == fromVal && data.maxVal == toVal) + return; + + const Value oldVal = data.val; + + data.setMinimumValue(fromVal); + data.setMaximumValue(toVal); + + emit (manager->*rangeChangedSignal)(property, data.minVal, data.maxVal); + + if (setSubPropertyRange) + (managerPrivate->*setSubPropertyRange)(property, data.minVal, data.maxVal, data.val); + + if (data.val == oldVal) + return; + + emit (manager->*propertyChangedSignal)(property); + emit (manager->*valueChangedSignal)(property, data.val); +} + +template +static void setBorderValue(PropertyManager *manager, PropertyManagerPrivate *managerPrivate, + void (PropertyManager::*propertyChangedSignal)(QtProperty *), + void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter), + void (PropertyManager::*rangeChangedSignal)(QtProperty *, ValueChangeParameter, ValueChangeParameter), + QtProperty *property, + Value (PrivateData::*getRangeVal)() const, + void (PrivateData::*setRangeVal)(ValueChangeParameter), const Value &borderVal, + void (PropertyManagerPrivate::*setSubPropertyRange)(QtProperty *, + ValueChangeParameter, ValueChangeParameter, ValueChangeParameter)) +{ + typedef QMap PropertyToData; + typedef Q_TYPENAME PropertyToData::iterator PropertyToDataIterator; + const PropertyToDataIterator it = managerPrivate->m_values.find(property); + if (it == managerPrivate->m_values.end()) + return; + + PrivateData &data = it.value(); + + if ((data.*getRangeVal)() == borderVal) + return; + + const Value oldVal = data.val; + + (data.*setRangeVal)(borderVal); + + emit (manager->*rangeChangedSignal)(property, data.minVal, data.maxVal); + + if (setSubPropertyRange) + (managerPrivate->*setSubPropertyRange)(property, data.minVal, data.maxVal, data.val); + + if (data.val == oldVal) + return; + + emit (manager->*propertyChangedSignal)(property); + emit (manager->*valueChangedSignal)(property, data.val); +} + +template +static void setMinimumValue(PropertyManager *manager, PropertyManagerPrivate *managerPrivate, + void (PropertyManager::*propertyChangedSignal)(QtProperty *), + void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter), + void (PropertyManager::*rangeChangedSignal)(QtProperty *, ValueChangeParameter, ValueChangeParameter), + QtProperty *property, const Value &minVal) +{ + void (PropertyManagerPrivate::*setSubPropertyRange)(QtProperty *, + ValueChangeParameter, ValueChangeParameter, ValueChangeParameter) = 0; + setBorderValue(manager, managerPrivate, + propertyChangedSignal, valueChangedSignal, rangeChangedSignal, + property, &PropertyManagerPrivate::Data::minimumValue, &PropertyManagerPrivate::Data::setMinimumValue, minVal, setSubPropertyRange); +} + +template +static void setMaximumValue(PropertyManager *manager, PropertyManagerPrivate *managerPrivate, + void (PropertyManager::*propertyChangedSignal)(QtProperty *), + void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter), + void (PropertyManager::*rangeChangedSignal)(QtProperty *, ValueChangeParameter, ValueChangeParameter), + QtProperty *property, const Value &maxVal) +{ + void (PropertyManagerPrivate::*setSubPropertyRange)(QtProperty *, + ValueChangeParameter, ValueChangeParameter, ValueChangeParameter) = 0; + setBorderValue(manager, managerPrivate, + propertyChangedSignal, valueChangedSignal, rangeChangedSignal, + property, &PropertyManagerPrivate::Data::maximumValue, &PropertyManagerPrivate::Data::setMaximumValue, maxVal, setSubPropertyRange); +} + +class QtMetaEnumWrapper : public QObject +{ + Q_OBJECT + Q_PROPERTY(QSizePolicy::Policy policy READ policy) +public: + QSizePolicy::Policy policy() const { return QSizePolicy::Ignored; } +private: + QtMetaEnumWrapper(QObject *parent) : QObject(parent) {} +}; + +class QtMetaEnumProvider +{ +public: + QtMetaEnumProvider(); + + QStringList policyEnumNames() const { return m_policyEnumNames; } + QStringList languageEnumNames() const { return m_languageEnumNames; } + QStringList countryEnumNames(QLocale::Language language) const { return m_countryEnumNames.value(language); } + + QSizePolicy::Policy indexToSizePolicy(int index) const; + int sizePolicyToIndex(QSizePolicy::Policy policy) const; + + void indexToLocale(int languageIndex, int countryIndex, QLocale::Language *language, QLocale::Country *country) const; + void localeToIndex(QLocale::Language language, QLocale::Country country, int *languageIndex, int *countryIndex) const; + +private: + void initLocale(); + + QStringList m_policyEnumNames; + QStringList m_languageEnumNames; + QMap m_countryEnumNames; + QMap m_indexToLanguage; + QMap m_languageToIndex; + QMap > m_indexToCountry; + QMap > m_countryToIndex; + QMetaEnum m_policyEnum; +}; + +#if QT_VERSION < 0x040300 + +static QList countriesForLanguage(QLocale::Language language) +{ + QList countries; + QLocale::Country country = QLocale::AnyCountry; + while (country <= QLocale::LastCountry) { + QLocale locale(language, country); + if (locale.language() == language && !countries.contains(locale.country())) + countries << locale.country(); + country = (QLocale::Country)((uint)country + 1); // ++country + } + return countries; +} + +#endif + +static QList sortCountries(const QList &countries) +{ + QMultiMap nameToCountry; + QListIterator itCountry(countries); + while (itCountry.hasNext()) { + QLocale::Country country = itCountry.next(); + nameToCountry.insert(QLocale::countryToString(country), country); + } + return nameToCountry.values(); +} + +void QtMetaEnumProvider::initLocale() +{ + QMultiMap nameToLanguage; + QLocale::Language language = QLocale::C; + while (language <= QLocale::LastLanguage) { + QLocale locale(language); + if (locale.language() == language) + nameToLanguage.insert(QLocale::languageToString(language), language); + language = (QLocale::Language)((uint)language + 1); // ++language + } + + const QLocale system = QLocale::system(); + if (!nameToLanguage.contains(QLocale::languageToString(system.language()))) + nameToLanguage.insert(QLocale::languageToString(system.language()), system.language()); + + QList languages = nameToLanguage.values(); + QListIterator itLang(languages); + while (itLang.hasNext()) { + QLocale::Language language = itLang.next(); + QList countries; +#if QT_VERSION < 0x040300 + countries = countriesForLanguage(language); +#else + countries = QLocale::countriesForLanguage(language); +#endif + if (countries.isEmpty() && language == system.language()) + countries << system.country(); + + if (!countries.isEmpty() && !m_languageToIndex.contains(language)) { + countries = sortCountries(countries); + int langIdx = m_languageEnumNames.count(); + m_indexToLanguage[langIdx] = language; + m_languageToIndex[language] = langIdx; + QStringList countryNames; + QListIterator it(countries); + int countryIdx = 0; + while (it.hasNext()) { + QLocale::Country country = it.next(); + countryNames << QLocale::countryToString(country); + m_indexToCountry[langIdx][countryIdx] = country; + m_countryToIndex[language][country] = countryIdx; + ++countryIdx; + } + m_languageEnumNames << QLocale::languageToString(language); + m_countryEnumNames[language] = countryNames; + } + } +} + +QtMetaEnumProvider::QtMetaEnumProvider() +{ + QMetaProperty p; + + p = QtMetaEnumWrapper::staticMetaObject.property( + QtMetaEnumWrapper::staticMetaObject.propertyOffset() + 0); + m_policyEnum = p.enumerator(); + const int keyCount = m_policyEnum.keyCount(); + for (int i = 0; i < keyCount; i++) + m_policyEnumNames << QLatin1String(m_policyEnum.key(i)); + + initLocale(); +} + +QSizePolicy::Policy QtMetaEnumProvider::indexToSizePolicy(int index) const +{ + return static_cast(m_policyEnum.value(index)); +} + +int QtMetaEnumProvider::sizePolicyToIndex(QSizePolicy::Policy policy) const +{ + const int keyCount = m_policyEnum.keyCount(); + for (int i = 0; i < keyCount; i++) + if (indexToSizePolicy(i) == policy) + return i; + return -1; +} + +void QtMetaEnumProvider::indexToLocale(int languageIndex, int countryIndex, QLocale::Language *language, QLocale::Country *country) const +{ + QLocale::Language l = QLocale::C; + QLocale::Country c = QLocale::AnyCountry; + if (m_indexToLanguage.contains(languageIndex)) { + l = m_indexToLanguage[languageIndex]; + if (m_indexToCountry.contains(languageIndex) && m_indexToCountry[languageIndex].contains(countryIndex)) + c = m_indexToCountry[languageIndex][countryIndex]; + } + if (language) + *language = l; + if (country) + *country = c; +} + +void QtMetaEnumProvider::localeToIndex(QLocale::Language language, QLocale::Country country, int *languageIndex, int *countryIndex) const +{ + int l = -1; + int c = -1; + if (m_languageToIndex.contains(language)) { + l = m_languageToIndex[language]; + if (m_countryToIndex.contains(language) && m_countryToIndex[language].contains(country)) + c = m_countryToIndex[language][country]; + } + + if (languageIndex) + *languageIndex = l; + if (countryIndex) + *countryIndex = c; +} + +Q_GLOBAL_STATIC(QtMetaEnumProvider, metaEnumProvider) + +// QtGroupPropertyManager + +/*! + \class QtGroupPropertyManager + + \brief The QtGroupPropertyManager provides and manages group properties. + + This class is intended to provide a grouping element without any value. + + \sa QtAbstractPropertyManager +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtGroupPropertyManager::QtGroupPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtGroupPropertyManager::~QtGroupPropertyManager() +{ + +} + +/*! + \reimp +*/ +bool QtGroupPropertyManager::hasValue(const QtProperty *property) const +{ + Q_UNUSED(property) + return false; +} + +/*! + \reimp +*/ +void QtGroupPropertyManager::initializeProperty(QtProperty *property) +{ + Q_UNUSED(property) +} + +/*! + \reimp +*/ +void QtGroupPropertyManager::uninitializeProperty(QtProperty *property) +{ + Q_UNUSED(property) +} + +// QtIntPropertyManager + +class QtIntPropertyManagerPrivate +{ + QtIntPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtIntPropertyManager) +public: + + struct Data + { + Data() : val(0), minVal(-INT_MAX), maxVal(INT_MAX), singleStep(1) {} + int val; + int minVal; + int maxVal; + int singleStep; + int minimumValue() const { return minVal; } + int maximumValue() const { return maxVal; } + void setMinimumValue(int newMinVal) { setSimpleMinimumData(this, newMinVal); } + void setMaximumValue(int newMaxVal) { setSimpleMaximumData(this, newMaxVal); } + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; +}; + +/*! + \class QtIntPropertyManager + + \brief The QtIntPropertyManager provides and manages int properties. + + An int property has a current value, and a range specifying the + valid values. The range is defined by a minimum and a maximum + value. + + The property's value and range can be retrieved using the value(), + minimum() and maximum() functions, and can be set using the + setValue(), setMinimum() and setMaximum() slots. Alternatively, + the range can be defined in one go using the setRange() slot. + + In addition, QtIntPropertyManager provides the valueChanged() signal which + is emitted whenever a property created by this manager changes, + and the rangeChanged() signal which is emitted whenever such a + property changes its range of valid values. + + \sa QtAbstractPropertyManager, QtSpinBoxFactory, QtSliderFactory, QtScrollBarFactory +*/ + +/*! + \fn void QtIntPropertyManager::valueChanged(QtProperty *property, int value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtIntPropertyManager::rangeChanged(QtProperty *property, int minimum, int maximum) + + This signal is emitted whenever a property created by this manager + changes its range of valid values, passing a pointer to the + \a property and the new \a minimum and \a maximum values. + + \sa setRange() +*/ + +/*! + \fn void QtIntPropertyManager::singleStepChanged(QtProperty *property, int step) + + This signal is emitted whenever a property created by this manager + changes its single step property, passing a pointer to the + \a property and the new \a step value + + \sa setSingleStep() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtIntPropertyManager::QtIntPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtIntPropertyManagerPrivate; + d_ptr->q_ptr = this; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtIntPropertyManager::~QtIntPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the given \a property's value. + + If the given property is not managed by this manager, this + function returns 0. + + \sa setValue() +*/ +int QtIntPropertyManager::value(const QtProperty *property) const +{ + return getValue(d_ptr->m_values, property, 0); +} + +/*! + Returns the given \a property's minimum value. + + \sa setMinimum(), maximum(), setRange() +*/ +int QtIntPropertyManager::minimum(const QtProperty *property) const +{ + return getMinimum(d_ptr->m_values, property, 0); +} + +/*! + Returns the given \a property's maximum value. + + \sa setMaximum(), minimum(), setRange() +*/ +int QtIntPropertyManager::maximum(const QtProperty *property) const +{ + return getMaximum(d_ptr->m_values, property, 0); +} + +/*! + Returns the given \a property's step value. + + The step is typically used to increment or decrement a property value while pressing an arrow key. + + \sa setSingleStep() +*/ +int QtIntPropertyManager::singleStep(const QtProperty *property) const +{ + return getData(d_ptr->m_values, &QtIntPropertyManagerPrivate::Data::singleStep, property, 0); +} + +/*! + \reimp +*/ +QString QtIntPropertyManager::valueText(const QtProperty *property) const +{ + const QtIntPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + return QString::number(it.value().val); +} + +/*! + \fn void QtIntPropertyManager::setValue(QtProperty *property, int value) + + Sets the value of the given \a property to \a value. + + If the specified \a value is not valid according to the given \a + property's range, the \a value is adjusted to the nearest valid + value within the range. + + \sa value(), setRange(), valueChanged() +*/ +void QtIntPropertyManager::setValue(QtProperty *property, int val) +{ + void (QtIntPropertyManagerPrivate::*setSubPropertyValue)(QtProperty *, int) = 0; + setValueInRange(this, d_ptr, + &QtIntPropertyManager::propertyChanged, + &QtIntPropertyManager::valueChanged, + property, val, setSubPropertyValue); +} + +/*! + Sets the minimum value for the given \a property to \a minVal. + + When setting the minimum value, the maximum and current values are + adjusted if necessary (ensuring that the range remains valid and + that the current value is within the range). + + \sa minimum(), setRange(), rangeChanged() +*/ +void QtIntPropertyManager::setMinimum(QtProperty *property, int minVal) +{ + setMinimumValue(this, d_ptr, + &QtIntPropertyManager::propertyChanged, + &QtIntPropertyManager::valueChanged, + &QtIntPropertyManager::rangeChanged, + property, minVal); +} + +/*! + Sets the maximum value for the given \a property to \a maxVal. + + When setting maximum value, the minimum and current values are + adjusted if necessary (ensuring that the range remains valid and + that the current value is within the range). + + \sa maximum(), setRange(), rangeChanged() +*/ +void QtIntPropertyManager::setMaximum(QtProperty *property, int maxVal) +{ + setMaximumValue(this, d_ptr, + &QtIntPropertyManager::propertyChanged, + &QtIntPropertyManager::valueChanged, + &QtIntPropertyManager::rangeChanged, + property, maxVal); +} + +/*! + \fn void QtIntPropertyManager::setRange(QtProperty *property, int minimum, int maximum) + + Sets the range of valid values. + + This is a convenience function defining the range of valid values + in one go; setting the \a minimum and \a maximum values for the + given \a property with a single function call. + + When setting a new range, the current value is adjusted if + necessary (ensuring that the value remains within range). + + \sa setMinimum(), setMaximum(), rangeChanged() +*/ +void QtIntPropertyManager::setRange(QtProperty *property, int minVal, int maxVal) +{ + void (QtIntPropertyManagerPrivate::*setSubPropertyRange)(QtProperty *, int, int, int) = 0; + setBorderValues(this, d_ptr, + &QtIntPropertyManager::propertyChanged, + &QtIntPropertyManager::valueChanged, + &QtIntPropertyManager::rangeChanged, + property, minVal, maxVal, setSubPropertyRange); +} + +/*! + Sets the step value for the given \a property to \a step. + + The step is typically used to increment or decrement a property value while pressing an arrow key. + + \sa singleStep() +*/ +void QtIntPropertyManager::setSingleStep(QtProperty *property, int step) +{ + const QtIntPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtIntPropertyManagerPrivate::Data data = it.value(); + + if (step < 0) + step = 0; + + if (data.singleStep == step) + return; + + data.singleStep = step; + + it.value() = data; + + emit singleStepChanged(property, data.singleStep); +} + +/*! + \reimp +*/ +void QtIntPropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QtIntPropertyManagerPrivate::Data(); +} + +/*! + \reimp +*/ +void QtIntPropertyManager::uninitializeProperty(QtProperty *property) +{ + d_ptr->m_values.remove(property); +} + +// QtDoublePropertyManager + +class QtDoublePropertyManagerPrivate +{ + QtDoublePropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtDoublePropertyManager) +public: + + struct Data + { + Data() : val(0), minVal(-INT_MAX), maxVal(INT_MAX), singleStep(1), decimals(2) {} + double val; + double minVal; + double maxVal; + double singleStep; + int decimals; + double minimumValue() const { return minVal; } + double maximumValue() const { return maxVal; } + void setMinimumValue(double newMinVal) { setSimpleMinimumData(this, newMinVal); } + void setMaximumValue(double newMaxVal) { setSimpleMaximumData(this, newMaxVal); } + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; +}; + +/*! + \class QtDoublePropertyManager + + \brief The QtDoublePropertyManager provides and manages double properties. + + A double property has a current value, and a range specifying the + valid values. The range is defined by a minimum and a maximum + value. + + The property's value and range can be retrieved using the value(), + minimum() and maximum() functions, and can be set using the + setValue(), setMinimum() and setMaximum() slots. + Alternatively, the range can be defined in one go using the + setRange() slot. + + In addition, QtDoublePropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes, and the rangeChanged() signal which is emitted whenever + such a property changes its range of valid values. + + \sa QtAbstractPropertyManager, QtDoubleSpinBoxFactory +*/ + +/*! + \fn void QtDoublePropertyManager::valueChanged(QtProperty *property, double value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtDoublePropertyManager::rangeChanged(QtProperty *property, double minimum, double maximum) + + This signal is emitted whenever a property created by this manager + changes its range of valid values, passing a pointer to the + \a property and the new \a minimum and \a maximum values + + \sa setRange() +*/ + +/*! + \fn void QtDoublePropertyManager::decimalsChanged(QtProperty *property, int prec) + + This signal is emitted whenever a property created by this manager + changes its precision of value, passing a pointer to the + \a property and the new \a prec value + + \sa setDecimals() +*/ + +/*! + \fn void QtDoublePropertyManager::singleStepChanged(QtProperty *property, double step) + + This signal is emitted whenever a property created by this manager + changes its single step property, passing a pointer to the + \a property and the new \a step value + + \sa setSingleStep() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtDoublePropertyManager::QtDoublePropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtDoublePropertyManagerPrivate; + d_ptr->q_ptr = this; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtDoublePropertyManager::~QtDoublePropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the given \a property's value. + + If the given property is not managed by this manager, this + function returns 0. + + \sa setValue() +*/ +double QtDoublePropertyManager::value(const QtProperty *property) const +{ + return getValue(d_ptr->m_values, property, 0.0); +} + +/*! + Returns the given \a property's minimum value. + + \sa maximum(), setRange() +*/ +double QtDoublePropertyManager::minimum(const QtProperty *property) const +{ + return getMinimum(d_ptr->m_values, property, 0.0); +} + +/*! + Returns the given \a property's maximum value. + + \sa minimum(), setRange() +*/ +double QtDoublePropertyManager::maximum(const QtProperty *property) const +{ + return getMaximum(d_ptr->m_values, property, 0.0); +} + +/*! + Returns the given \a property's step value. + + The step is typically used to increment or decrement a property value while pressing an arrow key. + + \sa setSingleStep() +*/ +double QtDoublePropertyManager::singleStep(const QtProperty *property) const +{ + return getData(d_ptr->m_values, &QtDoublePropertyManagerPrivate::Data::singleStep, property, 0); +} + +/*! + Returns the given \a property's precision, in decimals. + + \sa setDecimals() +*/ +int QtDoublePropertyManager::decimals(const QtProperty *property) const +{ + return getData(d_ptr->m_values, &QtDoublePropertyManagerPrivate::Data::decimals, property, 0); +} + +/*! + \reimp +*/ +QString QtDoublePropertyManager::valueText(const QtProperty *property) const +{ + const QtDoublePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + + return QString("%1").arg(it.value().val); +} + +/*! + \fn void QtDoublePropertyManager::setValue(QtProperty *property, double value) + + Sets the value of the given \a property to \a value. + + If the specified \a value is not valid according to the given + \a property's range, the \a value is adjusted to the nearest valid value + within the range. + + \sa value(), setRange(), valueChanged() +*/ +void QtDoublePropertyManager::setValue(QtProperty *property, double val) +{ + void (QtDoublePropertyManagerPrivate::*setSubPropertyValue)(QtProperty *, double) = 0; + setValueInRange(this, d_ptr, + &QtDoublePropertyManager::propertyChanged, + &QtDoublePropertyManager::valueChanged, + property, val, setSubPropertyValue); +} + +/*! + Sets the step value for the given \a property to \a step. + + The step is typically used to increment or decrement a property value while pressing an arrow key. + + \sa singleStep() +*/ +void QtDoublePropertyManager::setSingleStep(QtProperty *property, double step) +{ + const QtDoublePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtDoublePropertyManagerPrivate::Data data = it.value(); + + if (step < 0) + step = 0; + + if (data.singleStep == step) + return; + + data.singleStep = step; + + it.value() = data; + + emit singleStepChanged(property, data.singleStep); +} + +/*! + \fn void QtDoublePropertyManager::setDecimals(QtProperty *property, int prec) + + Sets the precision of the given \a property to \a prec. + + The valid decimal range is 0-13. The default is 2. + + \sa decimals() +*/ +void QtDoublePropertyManager::setDecimals(QtProperty *property, int prec) +{ + const QtDoublePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtDoublePropertyManagerPrivate::Data data = it.value(); + + if (prec > 13) + prec = 13; + else if (prec < 0) + prec = 0; + + if (data.decimals == prec) + return; + + data.decimals = prec; + + it.value() = data; + + emit decimalsChanged(property, data.decimals); +} + +/*! + Sets the minimum value for the given \a property to \a minVal. + + When setting the minimum value, the maximum and current values are + adjusted if necessary (ensuring that the range remains valid and + that the current value is within in the range). + + \sa minimum(), setRange(), rangeChanged() +*/ +void QtDoublePropertyManager::setMinimum(QtProperty *property, double minVal) +{ + setMinimumValue(this, d_ptr, + &QtDoublePropertyManager::propertyChanged, + &QtDoublePropertyManager::valueChanged, + &QtDoublePropertyManager::rangeChanged, + property, minVal); +} + +/*! + Sets the maximum value for the given \a property to \a maxVal. + + When setting the maximum value, the minimum and current values are + adjusted if necessary (ensuring that the range remains valid and + that the current value is within in the range). + + \sa maximum(), setRange(), rangeChanged() +*/ +void QtDoublePropertyManager::setMaximum(QtProperty *property, double maxVal) +{ + setMaximumValue(this, d_ptr, + &QtDoublePropertyManager::propertyChanged, + &QtDoublePropertyManager::valueChanged, + &QtDoublePropertyManager::rangeChanged, + property, maxVal); +} + +/*! + \fn void QtDoublePropertyManager::setRange(QtProperty *property, double minimum, double maximum) + + Sets the range of valid values. + + This is a convenience function defining the range of valid values + in one go; setting the \a minimum and \a maximum values for the + given \a property with a single function call. + + When setting a new range, the current value is adjusted if + necessary (ensuring that the value remains within range). + + \sa setMinimum(), setMaximum(), rangeChanged() +*/ +void QtDoublePropertyManager::setRange(QtProperty *property, double minVal, double maxVal) +{ + void (QtDoublePropertyManagerPrivate::*setSubPropertyRange)(QtProperty *, double, double, double) = 0; + setBorderValues(this, d_ptr, + &QtDoublePropertyManager::propertyChanged, + &QtDoublePropertyManager::valueChanged, + &QtDoublePropertyManager::rangeChanged, + property, minVal, maxVal, setSubPropertyRange); +} + +/*! + \reimp +*/ +void QtDoublePropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QtDoublePropertyManagerPrivate::Data(); +} + +/*! + \reimp +*/ +void QtDoublePropertyManager::uninitializeProperty(QtProperty *property) +{ + d_ptr->m_values.remove(property); +} + +// QtStringPropertyManager + +class QtStringPropertyManagerPrivate +{ + QtStringPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtStringPropertyManager) +public: + + struct Data + { + Data() : regExp(QString(QLatin1Char('*')), Qt::CaseSensitive, QRegExp::Wildcard) + { + } + QString val; + QRegExp regExp; + }; + + typedef QMap PropertyValueMap; + QMap m_values; +}; + +/*! + \class QtStringPropertyManager + + \brief The QtStringPropertyManager provides and manages QString properties. + + A string property's value can be retrieved using the value() + function, and set using the setValue() slot. + + The current value can be checked against a regular expression. To + set the regular expression use the setRegExp() slot, use the + regExp() function to retrieve the currently set expression. + + In addition, QtStringPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes, and the regExpChanged() signal which is emitted whenever + such a property changes its currently set regular expression. + + \sa QtAbstractPropertyManager, QtLineEditFactory +*/ + +/*! + \fn void QtStringPropertyManager::valueChanged(QtProperty *property, const QString &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtStringPropertyManager::regExpChanged(QtProperty *property, const QRegExp ®Exp) + + This signal is emitted whenever a property created by this manager + changes its currenlty set regular expression, passing a pointer to + the \a property and the new \a regExp as parameters. + + \sa setRegExp() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtStringPropertyManager::QtStringPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtStringPropertyManagerPrivate; + d_ptr->q_ptr = this; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtStringPropertyManager::~QtStringPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the given \a property's value. + + If the given property is not managed by this manager, this + function returns an empty string. + + \sa setValue() +*/ +QString QtStringPropertyManager::value(const QtProperty *property) const +{ + return getValue(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's currently set regular expression. + + If the given \a property is not managed by this manager, this + function returns an empty expression. + + \sa setRegExp() +*/ +QRegExp QtStringPropertyManager::regExp(const QtProperty *property) const +{ + return getData(d_ptr->m_values, &QtStringPropertyManagerPrivate::Data::regExp, property, QRegExp()); +} + +/*! + \reimp +*/ +QString QtStringPropertyManager::valueText(const QtProperty *property) const +{ + const QtStringPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + return it.value().val; +} + +/*! + \fn void QtStringPropertyManager::setValue(QtProperty *property, const QString &value) + + Sets the value of the given \a property to \a value. + + If the specified \a value doesn't match the given \a property's + regular expression, this function does nothing. + + \sa value(), setRegExp(), valueChanged() +*/ +void QtStringPropertyManager::setValue(QtProperty *property, const QString &val) +{ + const QtStringPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtStringPropertyManagerPrivate::Data data = it.value(); + + if (data.val == val) + return; + + if (data.regExp.isValid() && !data.regExp.exactMatch(val)) + return; + + data.val = val; + + it.value() = data; + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + Sets the regular expression of the given \a property to \a regExp. + + \sa regExp(), setValue(), regExpChanged() +*/ +void QtStringPropertyManager::setRegExp(QtProperty *property, const QRegExp ®Exp) +{ + const QtStringPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtStringPropertyManagerPrivate::Data data = it.value() ; + + if (data.regExp == regExp) + return; + + data.regExp = regExp; + + it.value() = data; + + emit regExpChanged(property, data.regExp); +} + +/*! + \reimp +*/ +void QtStringPropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QtStringPropertyManagerPrivate::Data(); +} + +/*! + \reimp +*/ +void QtStringPropertyManager::uninitializeProperty(QtProperty *property) +{ + d_ptr->m_values.remove(property); +} + +// QtBoolPropertyManager + +class QtBoolPropertyManagerPrivate +{ + QtBoolPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtBoolPropertyManager) +public: + + QMap m_values; +}; + +/*! + \class QtBoolPropertyManager + + \brief The QtBoolPropertyManager class provides and manages boolean properties. + + The property's value can be retrieved using the value() function, + and set using the setValue() slot. + + In addition, QtBoolPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes. + + \sa QtAbstractPropertyManager, QtCheckBoxFactory +*/ + +/*! + \fn void QtBoolPropertyManager::valueChanged(QtProperty *property, bool value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtBoolPropertyManager::QtBoolPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtBoolPropertyManagerPrivate; + d_ptr->q_ptr = this; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtBoolPropertyManager::~QtBoolPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by \e this manager, this + function returns false. + + \sa setValue() +*/ +bool QtBoolPropertyManager::value(const QtProperty *property) const +{ + return d_ptr->m_values.value(property, false); +} + +/*! + \reimp +*/ +QString QtBoolPropertyManager::valueText(const QtProperty *property) const +{ + return QString(); +} + +// Return an icon containing a check box indicator +static QIcon drawCheckBox(bool value) +{ + QStyleOptionButton opt; + opt.state |= value ? QStyle::State_On : QStyle::State_Off; + opt.state |= QStyle::State_Enabled; + const QStyle *style = QApplication::style(); + // Figure out size of an indicator and make sure it is not scaled down in a list view item + // by making the pixmap as big as a list view icon and centering the indicator in it. + // (if it is smaller, it can't be helped) + const int indicatorWidth = style->pixelMetric(QStyle::PM_IndicatorWidth, &opt); + const int indicatorHeight = style->pixelMetric(QStyle::PM_IndicatorHeight, &opt); + const int listViewIconSize = indicatorWidth; + const int pixmapWidth = indicatorWidth; + const int pixmapHeight = qMax(indicatorHeight, listViewIconSize); + + opt.rect = QRect(0, 0, indicatorWidth, indicatorHeight); + QPixmap pixmap = QPixmap(pixmapWidth, pixmapHeight); + pixmap.fill(Qt::transparent); + { + // Center? + const int xoff = (pixmapWidth > indicatorWidth) ? (pixmapWidth - indicatorWidth) / 2 : 0; + const int yoff = (pixmapHeight > indicatorHeight) ? (pixmapHeight - indicatorHeight) / 2 : 0; + QPainter painter(&pixmap); + painter.translate(xoff, yoff); + style->drawPrimitive(QStyle::PE_IndicatorCheckBox, &opt, &painter); + } + return QIcon(pixmap); +} + +/*! + \reimp +*/ +QIcon QtBoolPropertyManager::valueIcon(const QtProperty *property) const +{ + const QMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QIcon(); + + static const QIcon checkedIcon = drawCheckBox(true); + static const QIcon uncheckedIcon = drawCheckBox(false); + return it.value() ? checkedIcon : uncheckedIcon; +} + +/*! + \fn void QtBoolPropertyManager::setValue(QtProperty *property, bool value) + + Sets the value of the given \a property to \a value. + + \sa value() +*/ +void QtBoolPropertyManager::setValue(QtProperty *property, bool val) +{ + setSimpleValue(d_ptr->m_values, this, + &QtBoolPropertyManager::propertyChanged, + &QtBoolPropertyManager::valueChanged, + property, val); +} + +/*! + \reimp +*/ +void QtBoolPropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = false; +} + +/*! + \reimp +*/ +void QtBoolPropertyManager::uninitializeProperty(QtProperty *property) +{ + d_ptr->m_values.remove(property); +} + +// QtDatePropertyManager + +class QtDatePropertyManagerPrivate +{ + QtDatePropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtDatePropertyManager) +public: + + struct Data + { + Data() : val(QDate::currentDate()), minVal(QDate(1752, 9, 14)), + maxVal(QDate(7999, 12, 31)) {} + QDate val; + QDate minVal; + QDate maxVal; + QDate minimumValue() const { return minVal; } + QDate maximumValue() const { return maxVal; } + void setMinimumValue(const QDate &newMinVal) { setSimpleMinimumData(this, newMinVal); } + void setMaximumValue(const QDate &newMaxVal) { setSimpleMaximumData(this, newMaxVal); } + }; + + QString m_format; + + typedef QMap PropertyValueMap; + QMap m_values; +}; + +/*! + \class QtDatePropertyManager + + \brief The QtDatePropertyManager provides and manages QDate properties. + + A date property has a current value, and a range specifying the + valid dates. The range is defined by a minimum and a maximum + value. + + The property's values can be retrieved using the minimum(), + maximum() and value() functions, and can be set using the + setMinimum(), setMaximum() and setValue() slots. Alternatively, + the range can be defined in one go using the setRange() slot. + + In addition, QtDatePropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes, and the rangeChanged() signal which is emitted whenever + such a property changes its range of valid dates. + + \sa QtAbstractPropertyManager, QtDateEditFactory, QtDateTimePropertyManager +*/ + +/*! + \fn void QtDatePropertyManager::valueChanged(QtProperty *property, const QDate &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtDatePropertyManager::rangeChanged(QtProperty *property, const QDate &minimum, const QDate &maximum) + + This signal is emitted whenever a property created by this manager + changes its range of valid dates, passing a pointer to the \a + property and the new \a minimum and \a maximum dates. + + \sa setRange() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtDatePropertyManager::QtDatePropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtDatePropertyManagerPrivate; + d_ptr->q_ptr = this; + + QLocale loc; + d_ptr->m_format = loc.dateFormat(QLocale::ShortFormat); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtDatePropertyManager::~QtDatePropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by \e this manager, this + function returns an invalid date. + + \sa setValue() +*/ +QDate QtDatePropertyManager::value(const QtProperty *property) const +{ + return getValue(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's minimum date. + + \sa maximum(), setRange() +*/ +QDate QtDatePropertyManager::minimum(const QtProperty *property) const +{ + return getMinimum(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's maximum date. + + \sa minimum(), setRange() +*/ +QDate QtDatePropertyManager::maximum(const QtProperty *property) const +{ + return getMaximum(d_ptr->m_values, property); +} + +/*! + \reimp +*/ +QString QtDatePropertyManager::valueText(const QtProperty *property) const +{ + const QtDatePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + return it.value().val.toString(d_ptr->m_format); +} + +/*! + \fn void QtDatePropertyManager::setValue(QtProperty *property, const QDate &value) + + Sets the value of the given \a property to \a value. + + If the specified \a value is not a valid date according to the + given \a property's range, the value is adjusted to the nearest + valid value within the range. + + \sa value(), setRange(), valueChanged() +*/ +void QtDatePropertyManager::setValue(QtProperty *property, const QDate &val) +{ + void (QtDatePropertyManagerPrivate::*setSubPropertyValue)(QtProperty *, const QDate &) = 0; + setValueInRange(this, d_ptr, + &QtDatePropertyManager::propertyChanged, + &QtDatePropertyManager::valueChanged, + property, val, setSubPropertyValue); +} + +/*! + Sets the minimum value for the given \a property to \a minVal. + + When setting the minimum value, the maximum and current values are + adjusted if necessary (ensuring that the range remains valid and + that the current value is within in the range). + + \sa minimum(), setRange() +*/ +void QtDatePropertyManager::setMinimum(QtProperty *property, const QDate &minVal) +{ + setMinimumValue(this, d_ptr, + &QtDatePropertyManager::propertyChanged, + &QtDatePropertyManager::valueChanged, + &QtDatePropertyManager::rangeChanged, + property, minVal); +} + +/*! + Sets the maximum value for the given \a property to \a maxVal. + + When setting the maximum value, the minimum and current + values are adjusted if necessary (ensuring that the range remains + valid and that the current value is within in the range). + + \sa maximum(), setRange() +*/ +void QtDatePropertyManager::setMaximum(QtProperty *property, const QDate &maxVal) +{ + setMaximumValue(this, d_ptr, + &QtDatePropertyManager::propertyChanged, + &QtDatePropertyManager::valueChanged, + &QtDatePropertyManager::rangeChanged, + property, maxVal); +} + +/*! + \fn void QtDatePropertyManager::setRange(QtProperty *property, const QDate &minimum, const QDate &maximum) + + Sets the range of valid dates. + + This is a convenience function defining the range of valid dates + in one go; setting the \a minimum and \a maximum values for the + given \a property with a single function call. + + When setting a new date range, the current value is adjusted if + necessary (ensuring that the value remains in date range). + + \sa setMinimum(), setMaximum(), rangeChanged() +*/ +void QtDatePropertyManager::setRange(QtProperty *property, const QDate &minVal, const QDate &maxVal) +{ + void (QtDatePropertyManagerPrivate::*setSubPropertyRange)(QtProperty *, const QDate &, + const QDate &, const QDate &) = 0; + setBorderValues(this, d_ptr, + &QtDatePropertyManager::propertyChanged, + &QtDatePropertyManager::valueChanged, + &QtDatePropertyManager::rangeChanged, + property, minVal, maxVal, setSubPropertyRange); +} + +/*! + \reimp +*/ +void QtDatePropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QtDatePropertyManagerPrivate::Data(); +} + +/*! + \reimp +*/ +void QtDatePropertyManager::uninitializeProperty(QtProperty *property) +{ + d_ptr->m_values.remove(property); +} + +// QtTimePropertyManager + +class QtTimePropertyManagerPrivate +{ + QtTimePropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtTimePropertyManager) +public: + + QString m_format; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; +}; + +/*! + \class QtTimePropertyManager + + \brief The QtTimePropertyManager provides and manages QTime properties. + + A time property's value can be retrieved using the value() + function, and set using the setValue() slot. + + In addition, QtTimePropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes. + + \sa QtAbstractPropertyManager, QtTimeEditFactory +*/ + +/*! + \fn void QtTimePropertyManager::valueChanged(QtProperty *property, const QTime &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. + + \sa setValue() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtTimePropertyManager::QtTimePropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtTimePropertyManagerPrivate; + d_ptr->q_ptr = this; + + QLocale loc; + d_ptr->m_format = loc.timeFormat(QLocale::ShortFormat); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtTimePropertyManager::~QtTimePropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the given \a property's value. + + If the given property is not managed by this manager, this + function returns an invalid time object. + + \sa setValue() +*/ +QTime QtTimePropertyManager::value(const QtProperty *property) const +{ + return d_ptr->m_values.value(property, QTime()); +} + +/*! + \reimp +*/ +QString QtTimePropertyManager::valueText(const QtProperty *property) const +{ + const QtTimePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + return it.value().toString(d_ptr->m_format); +} + +/*! + \fn void QtTimePropertyManager::setValue(QtProperty *property, const QTime &value) + + Sets the value of the given \a property to \a value. + + \sa value(), valueChanged() +*/ +void QtTimePropertyManager::setValue(QtProperty *property, const QTime &val) +{ + setSimpleValue(d_ptr->m_values, this, + &QtTimePropertyManager::propertyChanged, + &QtTimePropertyManager::valueChanged, + property, val); +} + +/*! + \reimp +*/ +void QtTimePropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QTime::currentTime(); +} + +/*! + \reimp +*/ +void QtTimePropertyManager::uninitializeProperty(QtProperty *property) +{ + d_ptr->m_values.remove(property); +} + +// QtDateTimePropertyManager + +class QtDateTimePropertyManagerPrivate +{ + QtDateTimePropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtDateTimePropertyManager) +public: + + QString m_format; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; +}; + +/*! \class QtDateTimePropertyManager + + \brief The QtDateTimePropertyManager provides and manages QDateTime properties. + + A date and time property has a current value which can be + retrieved using the value() function, and set using the setValue() + slot. In addition, QtDateTimePropertyManager provides the + valueChanged() signal which is emitted whenever a property created + by this manager changes. + + \sa QtAbstractPropertyManager, QtDateTimeEditFactory, QtDatePropertyManager +*/ + +/*! + \fn void QtDateTimePropertyManager::valueChanged(QtProperty *property, const QDateTime &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtDateTimePropertyManager::QtDateTimePropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtDateTimePropertyManagerPrivate; + d_ptr->q_ptr = this; + + QLocale loc; + d_ptr->m_format = loc.dateFormat(QLocale::ShortFormat); + d_ptr->m_format += QLatin1Char(' '); + d_ptr->m_format += loc.timeFormat(QLocale::ShortFormat); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtDateTimePropertyManager::~QtDateTimePropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns an invalid QDateTime object. + + \sa setValue() +*/ +QDateTime QtDateTimePropertyManager::value(const QtProperty *property) const +{ + return d_ptr->m_values.value(property, QDateTime()); +} + +/*! + \reimp +*/ +QString QtDateTimePropertyManager::valueText(const QtProperty *property) const +{ + const QtDateTimePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + return it.value().toString(d_ptr->m_format); +} + +/*! + \fn void QtDateTimePropertyManager::setValue(QtProperty *property, const QDateTime &value) + + Sets the value of the given \a property to \a value. + + \sa value(), valueChanged() +*/ +void QtDateTimePropertyManager::setValue(QtProperty *property, const QDateTime &val) +{ + setSimpleValue(d_ptr->m_values, this, + &QtDateTimePropertyManager::propertyChanged, + &QtDateTimePropertyManager::valueChanged, + property, val); +} + +/*! + \reimp +*/ +void QtDateTimePropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QDateTime::currentDateTime(); +} + +/*! + \reimp +*/ +void QtDateTimePropertyManager::uninitializeProperty(QtProperty *property) +{ + d_ptr->m_values.remove(property); +} + +// QtKeySequencePropertyManager + +class QtKeySequencePropertyManagerPrivate +{ + QtKeySequencePropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtKeySequencePropertyManager) +public: + + QString m_format; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; +}; + +/*! \class QtKeySequencePropertyManager + + \brief The QtKeySequencePropertyManager provides and manages QKeySequence properties. + + A key sequence's value can be retrieved using the value() + function, and set using the setValue() slot. + + In addition, QtKeySequencePropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes. + + \sa QtAbstractPropertyManager +*/ + +/*! + \fn void QtKeySequencePropertyManager::valueChanged(QtProperty *property, const QKeySequence &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtKeySequencePropertyManager::QtKeySequencePropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtKeySequencePropertyManagerPrivate; + d_ptr->q_ptr = this; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtKeySequencePropertyManager::~QtKeySequencePropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns an empty QKeySequence object. + + \sa setValue() +*/ +QKeySequence QtKeySequencePropertyManager::value(const QtProperty *property) const +{ + return d_ptr->m_values.value(property, QKeySequence()); +} + +/*! + \reimp +*/ +QString QtKeySequencePropertyManager::valueText(const QtProperty *property) const +{ + const QtKeySequencePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + return it.value().toString(QKeySequence::NativeText); +} + +/*! + \fn void QtKeySequencePropertyManager::setValue(QtProperty *property, const QKeySequence &value) + + Sets the value of the given \a property to \a value. + + \sa value(), valueChanged() +*/ +void QtKeySequencePropertyManager::setValue(QtProperty *property, const QKeySequence &val) +{ + setSimpleValue(d_ptr->m_values, this, + &QtKeySequencePropertyManager::propertyChanged, + &QtKeySequencePropertyManager::valueChanged, + property, val); +} + +/*! + \reimp +*/ +void QtKeySequencePropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QKeySequence(); +} + +/*! + \reimp +*/ +void QtKeySequencePropertyManager::uninitializeProperty(QtProperty *property) +{ + d_ptr->m_values.remove(property); +} + +// QtCharPropertyManager + +class QtCharPropertyManagerPrivate +{ + QtCharPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtCharPropertyManager) +public: + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; +}; + +/*! \class QtCharPropertyManager + + \brief The QtCharPropertyManager provides and manages QChar properties. + + A char's value can be retrieved using the value() + function, and set using the setValue() slot. + + In addition, QtCharPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes. + + \sa QtAbstractPropertyManager +*/ + +/*! + \fn void QtCharPropertyManager::valueChanged(QtProperty *property, const QChar &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtCharPropertyManager::QtCharPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtCharPropertyManagerPrivate; + d_ptr->q_ptr = this; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtCharPropertyManager::~QtCharPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns an null QChar object. + + \sa setValue() +*/ +QChar QtCharPropertyManager::value(const QtProperty *property) const +{ + return d_ptr->m_values.value(property, QChar()); +} + +/*! + \reimp +*/ +QString QtCharPropertyManager::valueText(const QtProperty *property) const +{ + const QtCharPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + const QChar c = it.value(); + return c.isNull() ? QString() : QString(c); +} + +/*! + \fn void QtCharPropertyManager::setValue(QtProperty *property, const QChar &value) + + Sets the value of the given \a property to \a value. + + \sa value(), valueChanged() +*/ +void QtCharPropertyManager::setValue(QtProperty *property, const QChar &val) +{ + setSimpleValue(d_ptr->m_values, this, + &QtCharPropertyManager::propertyChanged, + &QtCharPropertyManager::valueChanged, + property, val); +} + +/*! + \reimp +*/ +void QtCharPropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QChar(); +} + +/*! + \reimp +*/ +void QtCharPropertyManager::uninitializeProperty(QtProperty *property) +{ + d_ptr->m_values.remove(property); +} + +// QtLocalePropertyManager + +class QtLocalePropertyManagerPrivate +{ + QtLocalePropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtLocalePropertyManager) +public: + + QtLocalePropertyManagerPrivate(); + + void slotEnumChanged(QtProperty *property, int value); + void slotPropertyDestroyed(QtProperty *property); + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtEnumPropertyManager *m_enumPropertyManager; + + QMap m_propertyToLanguage; + QMap m_propertyToCountry; + + QMap m_languageToProperty; + QMap m_countryToProperty; +}; + +QtLocalePropertyManagerPrivate::QtLocalePropertyManagerPrivate() +{ +} + +void QtLocalePropertyManagerPrivate::slotEnumChanged(QtProperty *property, int value) +{ + if (QtProperty *prop = m_languageToProperty.value(property, 0)) { + const QLocale loc = m_values[prop]; + QLocale::Language newLanguage = loc.language(); + QLocale::Country newCountry = loc.country(); + metaEnumProvider()->indexToLocale(value, 0, &newLanguage, 0); + QLocale newLoc(newLanguage, newCountry); + q_ptr->setValue(prop, newLoc); + } else if (QtProperty *prop = m_countryToProperty.value(property, 0)) { + const QLocale loc = m_values[prop]; + QLocale::Language newLanguage = loc.language(); + QLocale::Country newCountry = loc.country(); + metaEnumProvider()->indexToLocale(m_enumPropertyManager->value(m_propertyToLanguage.value(prop)), value, &newLanguage, &newCountry); + QLocale newLoc(newLanguage, newCountry); + q_ptr->setValue(prop, newLoc); + } +} + +void QtLocalePropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property) +{ + if (QtProperty *subProp = m_languageToProperty.value(property, 0)) { + m_propertyToLanguage[subProp] = 0; + m_languageToProperty.remove(property); + } else if (QtProperty *subProp = m_countryToProperty.value(property, 0)) { + m_propertyToCountry[subProp] = 0; + m_countryToProperty.remove(property); + } +} + +/*! + \class QtLocalePropertyManager + + \brief The QtLocalePropertyManager provides and manages QLocale properties. + + A locale property has nested \e language and \e country + subproperties. The top-level property's value can be retrieved + using the value() function, and set using the setValue() slot. + + The subproperties are created by QtEnumPropertyManager object. + These submanager can be retrieved using the subEnumPropertyManager() + function. In order to provide editing widgets for the subproperties + in a property browser widget, this manager must be associated with editor factory. + + In addition, QtLocalePropertyManager provides the valueChanged() + signal which is emitted whenever a property created by this + manager changes. + + \sa QtAbstractPropertyManager, QtEnumPropertyManager +*/ + +/*! + \fn void QtLocalePropertyManager::valueChanged(QtProperty *property, const QLocale &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. + + \sa setValue() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtLocalePropertyManager::QtLocalePropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtLocalePropertyManagerPrivate; + d_ptr->q_ptr = this; + + d_ptr->m_enumPropertyManager = new QtEnumPropertyManager(this); + connect(d_ptr->m_enumPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotEnumChanged(QtProperty *, int))); + + connect(d_ptr->m_enumPropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtLocalePropertyManager::~QtLocalePropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the manager that creates the nested \e language + and \e country subproperties. + + In order to provide editing widgets for the mentioned subproperties + in a property browser widget, this manager must be associated with + an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtEnumPropertyManager *QtLocalePropertyManager::subEnumPropertyManager() const +{ + return d_ptr->m_enumPropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given property is not managed by this manager, this + function returns the default locale. + + \sa setValue() +*/ +QLocale QtLocalePropertyManager::value(const QtProperty *property) const +{ + return d_ptr->m_values.value(property, QLocale()); +} + +/*! + \reimp +*/ +QString QtLocalePropertyManager::valueText(const QtProperty *property) const +{ + const QtLocalePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + + QLocale loc = it.value(); + + int langIdx = 0; + int countryIdx = 0; + metaEnumProvider()->localeToIndex(loc.language(), loc.country(), &langIdx, &countryIdx); + QString str = tr("%1, %2") + .arg(metaEnumProvider()->languageEnumNames().at(langIdx)) + .arg(metaEnumProvider()->countryEnumNames(loc.language()).at(countryIdx)); + return str; +} + +/*! + \fn void QtLocalePropertyManager::setValue(QtProperty *property, const QLocale &value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + \sa value(), valueChanged() +*/ +void QtLocalePropertyManager::setValue(QtProperty *property, const QLocale &val) +{ + const QtLocalePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + const QLocale loc = it.value(); + if (loc == val) + return; + + it.value() = val; + + int langIdx = 0; + int countryIdx = 0; + metaEnumProvider()->localeToIndex(val.language(), val.country(), &langIdx, &countryIdx); + if (loc.language() != val.language()) { + d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToLanguage.value(property), langIdx); + d_ptr->m_enumPropertyManager->setEnumNames(d_ptr->m_propertyToCountry.value(property), + metaEnumProvider()->countryEnumNames(val.language())); + } + d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToCountry.value(property), countryIdx); + + emit propertyChanged(property); + emit valueChanged(property, val); +} + +/*! + \reimp +*/ +void QtLocalePropertyManager::initializeProperty(QtProperty *property) +{ + QLocale val; + d_ptr->m_values[property] = val; + + int langIdx = 0; + int countryIdx = 0; + metaEnumProvider()->localeToIndex(val.language(), val.country(), &langIdx, &countryIdx); + + QtProperty *languageProp = d_ptr->m_enumPropertyManager->addProperty(); + languageProp->setPropertyName(tr("Language")); + d_ptr->m_enumPropertyManager->setEnumNames(languageProp, metaEnumProvider()->languageEnumNames()); + d_ptr->m_enumPropertyManager->setValue(languageProp, langIdx); + d_ptr->m_propertyToLanguage[property] = languageProp; + d_ptr->m_languageToProperty[languageProp] = property; + property->addSubProperty(languageProp); + + QtProperty *countryProp = d_ptr->m_enumPropertyManager->addProperty(); + countryProp->setPropertyName(tr("Country")); + d_ptr->m_enumPropertyManager->setEnumNames(countryProp, metaEnumProvider()->countryEnumNames(val.language())); + d_ptr->m_enumPropertyManager->setValue(countryProp, countryIdx); + d_ptr->m_propertyToCountry[property] = countryProp; + d_ptr->m_countryToProperty[countryProp] = property; + property->addSubProperty(countryProp); +} + +/*! + \reimp +*/ +void QtLocalePropertyManager::uninitializeProperty(QtProperty *property) +{ + QtProperty *languageProp = d_ptr->m_propertyToLanguage[property]; + if (languageProp) { + d_ptr->m_languageToProperty.remove(languageProp); + delete languageProp; + } + d_ptr->m_propertyToLanguage.remove(property); + + QtProperty *countryProp = d_ptr->m_propertyToCountry[property]; + if (countryProp) { + d_ptr->m_countryToProperty.remove(countryProp); + delete countryProp; + } + d_ptr->m_propertyToCountry.remove(property); + + d_ptr->m_values.remove(property); +} + +// QtPointPropertyManager + +class QtPointPropertyManagerPrivate +{ + QtPointPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtPointPropertyManager) +public: + + void slotIntChanged(QtProperty *property, int value); + void slotPropertyDestroyed(QtProperty *property); + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtIntPropertyManager *m_intPropertyManager; + + QMap m_propertyToX; + QMap m_propertyToY; + + QMap m_xToProperty; + QMap m_yToProperty; +}; + +void QtPointPropertyManagerPrivate::slotIntChanged(QtProperty *property, int value) +{ + if (QtProperty *xprop = m_xToProperty.value(property, 0)) { + QPoint p = m_values[xprop]; + p.setX(value); + q_ptr->setValue(xprop, p); + } else if (QtProperty *yprop = m_yToProperty.value(property, 0)) { + QPoint p = m_values[yprop]; + p.setY(value); + q_ptr->setValue(yprop, p); + } +} + +void QtPointPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property) +{ + if (QtProperty *pointProp = m_xToProperty.value(property, 0)) { + m_propertyToX[pointProp] = 0; + m_xToProperty.remove(property); + } else if (QtProperty *pointProp = m_yToProperty.value(property, 0)) { + m_propertyToY[pointProp] = 0; + m_yToProperty.remove(property); + } +} + +/*! \class QtPointPropertyManager + + \brief The QtPointPropertyManager provides and manages QPoint properties. + + A point property has nested \e x and \e y subproperties. The + top-level property's value can be retrieved using the value() + function, and set using the setValue() slot. + + The subproperties are created by a QtIntPropertyManager object. This + manager can be retrieved using the subIntPropertyManager() function. In + order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + In addition, QtPointPropertyManager provides the valueChanged() signal which + is emitted whenever a property created by this manager changes. + + \sa QtAbstractPropertyManager, QtIntPropertyManager, QtPointFPropertyManager +*/ + +/*! + \fn void QtPointPropertyManager::valueChanged(QtProperty *property, const QPoint &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. + + \sa setValue() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtPointPropertyManager::QtPointPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtPointPropertyManagerPrivate; + d_ptr->q_ptr = this; + + d_ptr->m_intPropertyManager = new QtIntPropertyManager(this); + connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotIntChanged(QtProperty *, int))); + connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtPointPropertyManager::~QtPointPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the manager that creates the nested \e x and \e y + subproperties. + + In order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtIntPropertyManager *QtPointPropertyManager::subIntPropertyManager() const +{ + return d_ptr->m_intPropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns a point with coordinates (0, 0). + + \sa setValue() +*/ +QPoint QtPointPropertyManager::value(const QtProperty *property) const +{ + return d_ptr->m_values.value(property, QPoint()); +} + +/*! + \reimp +*/ +QString QtPointPropertyManager::valueText(const QtProperty *property) const +{ + const QtPointPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + const QPoint v = it.value(); + return QString(tr("(%1, %2)").arg(QString::number(v.x())) + .arg(QString::number(v.y()))); +} + +/*! + \fn void QtPointPropertyManager::setValue(QtProperty *property, const QPoint &value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + \sa value(), valueChanged() +*/ +void QtPointPropertyManager::setValue(QtProperty *property, const QPoint &val) +{ + const QtPointPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + if (it.value() == val) + return; + + it.value() = val; + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToX[property], val.x()); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToY[property], val.y()); + + emit propertyChanged(property); + emit valueChanged(property, val); +} + +/*! + \reimp +*/ +void QtPointPropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QPoint(0, 0); + + QtProperty *xProp = d_ptr->m_intPropertyManager->addProperty(); + xProp->setPropertyName(tr("X")); + d_ptr->m_intPropertyManager->setValue(xProp, 0); + d_ptr->m_propertyToX[property] = xProp; + d_ptr->m_xToProperty[xProp] = property; + property->addSubProperty(xProp); + + QtProperty *yProp = d_ptr->m_intPropertyManager->addProperty(); + yProp->setPropertyName(tr("Y")); + d_ptr->m_intPropertyManager->setValue(yProp, 0); + d_ptr->m_propertyToY[property] = yProp; + d_ptr->m_yToProperty[yProp] = property; + property->addSubProperty(yProp); +} + +/*! + \reimp +*/ +void QtPointPropertyManager::uninitializeProperty(QtProperty *property) +{ + QtProperty *xProp = d_ptr->m_propertyToX[property]; + if (xProp) { + d_ptr->m_xToProperty.remove(xProp); + delete xProp; + } + d_ptr->m_propertyToX.remove(property); + + QtProperty *yProp = d_ptr->m_propertyToY[property]; + if (yProp) { + d_ptr->m_yToProperty.remove(yProp); + delete yProp; + } + d_ptr->m_propertyToY.remove(property); + + d_ptr->m_values.remove(property); +} + +// QtPointFPropertyManager + +class QtPointFPropertyManagerPrivate +{ + QtPointFPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtPointFPropertyManager) +public: + + struct Data + { + Data() : decimals(2) {} + QPointF val; + int decimals; + }; + + void slotDoubleChanged(QtProperty *property, double value); + void slotPropertyDestroyed(QtProperty *property); + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtDoublePropertyManager *m_doublePropertyManager; + + QMap m_propertyToX; + QMap m_propertyToY; + + QMap m_xToProperty; + QMap m_yToProperty; +}; + +void QtPointFPropertyManagerPrivate::slotDoubleChanged(QtProperty *property, double value) +{ + if (QtProperty *prop = m_xToProperty.value(property, 0)) { + QPointF p = m_values[prop].val; + p.setX(value); + q_ptr->setValue(prop, p); + } else if (QtProperty *prop = m_yToProperty.value(property, 0)) { + QPointF p = m_values[prop].val; + p.setY(value); + q_ptr->setValue(prop, p); + } +} + +void QtPointFPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property) +{ + if (QtProperty *pointProp = m_xToProperty.value(property, 0)) { + m_propertyToX[pointProp] = 0; + m_xToProperty.remove(property); + } else if (QtProperty *pointProp = m_yToProperty.value(property, 0)) { + m_propertyToY[pointProp] = 0; + m_yToProperty.remove(property); + } +} + +/*! \class QtPointFPropertyManager + + \brief The QtPointFPropertyManager provides and manages QPointF properties. + + A point property has nested \e x and \e y subproperties. The + top-level property's value can be retrieved using the value() + function, and set using the setValue() slot. + + The subproperties are created by a QtDoublePropertyManager object. This + manager can be retrieved using the subDoublePropertyManager() function. In + order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + In addition, QtPointFPropertyManager provides the valueChanged() signal which + is emitted whenever a property created by this manager changes. + + \sa QtAbstractPropertyManager, QtDoublePropertyManager, QtPointPropertyManager +*/ + +/*! + \fn void QtPointFPropertyManager::valueChanged(QtProperty *property, const QPointF &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtPointFPropertyManager::decimalsChanged(QtProperty *property, int prec) + + This signal is emitted whenever a property created by this manager + changes its precision of value, passing a pointer to the + \a property and the new \a prec value + + \sa setDecimals() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtPointFPropertyManager::QtPointFPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtPointFPropertyManagerPrivate; + d_ptr->q_ptr = this; + + d_ptr->m_doublePropertyManager = new QtDoublePropertyManager(this); + connect(d_ptr->m_doublePropertyManager, SIGNAL(valueChanged(QtProperty *, double)), + this, SLOT(slotDoubleChanged(QtProperty *, double))); + connect(d_ptr->m_doublePropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtPointFPropertyManager::~QtPointFPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the manager that creates the nested \e x and \e y + subproperties. + + In order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtDoublePropertyManager *QtPointFPropertyManager::subDoublePropertyManager() const +{ + return d_ptr->m_doublePropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns a point with coordinates (0, 0). + + \sa setValue() +*/ +QPointF QtPointFPropertyManager::value(const QtProperty *property) const +{ + return getValue(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's precision, in decimals. + + \sa setDecimals() +*/ +int QtPointFPropertyManager::decimals(const QtProperty *property) const +{ + return getData(d_ptr->m_values, &QtPointFPropertyManagerPrivate::Data::decimals, property, 0); +} + +/*! + \reimp +*/ +QString QtPointFPropertyManager::valueText(const QtProperty *property) const +{ + const QtPointFPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + const QPointF v = it.value().val; + const int dec = it.value().decimals; + return QString(tr("(%1, %2)").arg(QString::number(v.x(), 'f', dec)) + .arg(QString::number(v.y(), 'f', dec))); +} + +/*! + \fn void QtPointFPropertyManager::setValue(QtProperty *property, const QPointF &value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + \sa value(), valueChanged() +*/ +void QtPointFPropertyManager::setValue(QtProperty *property, const QPointF &val) +{ + const QtPointFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + if (it.value().val == val) + return; + + it.value().val = val; + d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToX[property], val.x()); + d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToY[property], val.y()); + + emit propertyChanged(property); + emit valueChanged(property, val); +} + +/*! + \fn void QtPointFPropertyManager::setDecimals(QtProperty *property, int prec) + + Sets the precision of the given \a property to \a prec. + + The valid decimal range is 0-13. The default is 2. + + \sa decimals() +*/ +void QtPointFPropertyManager::setDecimals(QtProperty *property, int prec) +{ + const QtPointFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtPointFPropertyManagerPrivate::Data data = it.value(); + + if (prec > 13) + prec = 13; + else if (prec < 0) + prec = 0; + + if (data.decimals == prec) + return; + + data.decimals = prec; + d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToX[property], prec); + d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToY[property], prec); + + it.value() = data; + + emit decimalsChanged(property, data.decimals); +} + +/*! + \reimp +*/ +void QtPointFPropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QtPointFPropertyManagerPrivate::Data(); + + QtProperty *xProp = d_ptr->m_doublePropertyManager->addProperty(); + xProp->setPropertyName(tr("X")); + d_ptr->m_doublePropertyManager->setDecimals(xProp, decimals(property)); + d_ptr->m_doublePropertyManager->setValue(xProp, 0); + d_ptr->m_propertyToX[property] = xProp; + d_ptr->m_xToProperty[xProp] = property; + property->addSubProperty(xProp); + + QtProperty *yProp = d_ptr->m_doublePropertyManager->addProperty(); + yProp->setPropertyName(tr("Y")); + d_ptr->m_doublePropertyManager->setDecimals(yProp, decimals(property)); + d_ptr->m_doublePropertyManager->setValue(yProp, 0); + d_ptr->m_propertyToY[property] = yProp; + d_ptr->m_yToProperty[yProp] = property; + property->addSubProperty(yProp); +} + +/*! + \reimp +*/ +void QtPointFPropertyManager::uninitializeProperty(QtProperty *property) +{ + QtProperty *xProp = d_ptr->m_propertyToX[property]; + if (xProp) { + d_ptr->m_xToProperty.remove(xProp); + delete xProp; + } + d_ptr->m_propertyToX.remove(property); + + QtProperty *yProp = d_ptr->m_propertyToY[property]; + if (yProp) { + d_ptr->m_yToProperty.remove(yProp); + delete yProp; + } + d_ptr->m_propertyToY.remove(property); + + d_ptr->m_values.remove(property); +} + +// QtSizePropertyManager + +class QtSizePropertyManagerPrivate +{ + QtSizePropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtSizePropertyManager) +public: + + void slotIntChanged(QtProperty *property, int value); + void slotPropertyDestroyed(QtProperty *property); + void setValue(QtProperty *property, const QSize &val); + void setRange(QtProperty *property, + const QSize &minVal, const QSize &maxVal, const QSize &val); + + struct Data + { + Data() : val(QSize(0, 0)), minVal(QSize(0, 0)), maxVal(QSize(INT_MAX, INT_MAX)) {} + QSize val; + QSize minVal; + QSize maxVal; + QSize minimumValue() const { return minVal; } + QSize maximumValue() const { return maxVal; } + void setMinimumValue(const QSize &newMinVal) { setSizeMinimumData(this, newMinVal); } + void setMaximumValue(const QSize &newMaxVal) { setSizeMaximumData(this, newMaxVal); } + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtIntPropertyManager *m_intPropertyManager; + + QMap m_propertyToW; + QMap m_propertyToH; + + QMap m_wToProperty; + QMap m_hToProperty; +}; + +void QtSizePropertyManagerPrivate::slotIntChanged(QtProperty *property, int value) +{ + if (QtProperty *prop = m_wToProperty.value(property, 0)) { + QSize s = m_values[prop].val; + s.setWidth(value); + q_ptr->setValue(prop, s); + } else if (QtProperty *prop = m_hToProperty.value(property, 0)) { + QSize s = m_values[prop].val; + s.setHeight(value); + q_ptr->setValue(prop, s); + } +} + +void QtSizePropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property) +{ + if (QtProperty *pointProp = m_wToProperty.value(property, 0)) { + m_propertyToW[pointProp] = 0; + m_wToProperty.remove(property); + } else if (QtProperty *pointProp = m_hToProperty.value(property, 0)) { + m_propertyToH[pointProp] = 0; + m_hToProperty.remove(property); + } +} + +void QtSizePropertyManagerPrivate::setValue(QtProperty *property, const QSize &val) +{ + m_intPropertyManager->setValue(m_propertyToW.value(property), val.width()); + m_intPropertyManager->setValue(m_propertyToH.value(property), val.height()); +} + +void QtSizePropertyManagerPrivate::setRange(QtProperty *property, + const QSize &minVal, const QSize &maxVal, const QSize &val) +{ + QtProperty *wProperty = m_propertyToW.value(property); + QtProperty *hProperty = m_propertyToH.value(property); + m_intPropertyManager->setRange(wProperty, minVal.width(), maxVal.width()); + m_intPropertyManager->setValue(wProperty, val.width()); + m_intPropertyManager->setRange(hProperty, minVal.height(), maxVal.height()); + m_intPropertyManager->setValue(hProperty, val.height()); +} + +/*! + \class QtSizePropertyManager + + \brief The QtSizePropertyManager provides and manages QSize properties. + + A size property has nested \e width and \e height + subproperties. The top-level property's value can be retrieved + using the value() function, and set using the setValue() slot. + + The subproperties are created by a QtIntPropertyManager object. This + manager can be retrieved using the subIntPropertyManager() function. In + order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + A size property also has a range of valid values defined by a + minimum size and a maximum size. These sizes can be retrieved + using the minimum() and the maximum() functions, and set using the + setMinimum() and setMaximum() slots. Alternatively, the range can + be defined in one go using the setRange() slot. + + In addition, QtSizePropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes, and the rangeChanged() signal which is emitted whenever + such a property changes its range of valid sizes. + + \sa QtAbstractPropertyManager, QtIntPropertyManager, QtSizeFPropertyManager +*/ + +/*! + \fn void QtSizePropertyManager::valueChanged(QtProperty *property, const QSize &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtSizePropertyManager::rangeChanged(QtProperty *property, const QSize &minimum, const QSize &maximum) + + This signal is emitted whenever a property created by this manager + changes its range of valid sizes, passing a pointer to the \a + property and the new \a minimum and \a maximum sizes. + + \sa setRange() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtSizePropertyManager::QtSizePropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtSizePropertyManagerPrivate; + d_ptr->q_ptr = this; + + d_ptr->m_intPropertyManager = new QtIntPropertyManager(this); + connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotIntChanged(QtProperty *, int))); + connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtSizePropertyManager::~QtSizePropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the manager that creates the nested \e width and \e height + subproperties. + + In order to provide editing widgets for the \e width and \e height + properties in a property browser widget, this manager must be + associated with an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtIntPropertyManager *QtSizePropertyManager::subIntPropertyManager() const +{ + return d_ptr->m_intPropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns an invalid size + + \sa setValue() +*/ +QSize QtSizePropertyManager::value(const QtProperty *property) const +{ + return getValue(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's minimum size value. + + \sa setMinimum(), maximum(), setRange() +*/ +QSize QtSizePropertyManager::minimum(const QtProperty *property) const +{ + return getMinimum(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's maximum size value. + + \sa setMaximum(), minimum(), setRange() +*/ +QSize QtSizePropertyManager::maximum(const QtProperty *property) const +{ + return getMaximum(d_ptr->m_values, property); +} + +/*! + \reimp +*/ +QString QtSizePropertyManager::valueText(const QtProperty *property) const +{ + const QtSizePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + const QSize v = it.value().val; + return QString(tr("%1 x %2").arg(QString::number(v.width())) + .arg(QString::number(v.height()))); +} + +/*! + \fn void QtSizePropertyManager::setValue(QtProperty *property, const QSize &value) + + Sets the value of the given \a property to \a value. + + If the specified \a value is not valid according to the given \a + property's size range, the \a value is adjusted to the nearest + valid value within the size range. + + \sa value(), setRange(), valueChanged() +*/ +void QtSizePropertyManager::setValue(QtProperty *property, const QSize &val) +{ + setValueInRange(this, d_ptr, + &QtSizePropertyManager::propertyChanged, + &QtSizePropertyManager::valueChanged, + property, val, &QtSizePropertyManagerPrivate::setValue); +} + +/*! + Sets the minimum size value for the given \a property to \a minVal. + + When setting the minimum size value, the maximum and current + values are adjusted if necessary (ensuring that the size range + remains valid and that the current value is within the range). + + \sa minimum(), setRange(), rangeChanged() +*/ +void QtSizePropertyManager::setMinimum(QtProperty *property, const QSize &minVal) +{ + setBorderValue(this, d_ptr, + &QtSizePropertyManager::propertyChanged, + &QtSizePropertyManager::valueChanged, + &QtSizePropertyManager::rangeChanged, + property, + &QtSizePropertyManagerPrivate::Data::minimumValue, + &QtSizePropertyManagerPrivate::Data::setMinimumValue, + minVal, &QtSizePropertyManagerPrivate::setRange); +} + +/*! + Sets the maximum size value for the given \a property to \a maxVal. + + When setting the maximum size value, the minimum and current + values are adjusted if necessary (ensuring that the size range + remains valid and that the current value is within the range). + + \sa maximum(), setRange(), rangeChanged() +*/ +void QtSizePropertyManager::setMaximum(QtProperty *property, const QSize &maxVal) +{ + setBorderValue(this, d_ptr, + &QtSizePropertyManager::propertyChanged, + &QtSizePropertyManager::valueChanged, + &QtSizePropertyManager::rangeChanged, + property, + &QtSizePropertyManagerPrivate::Data::maximumValue, + &QtSizePropertyManagerPrivate::Data::setMaximumValue, + maxVal, &QtSizePropertyManagerPrivate::setRange); +} + +/*! + \fn void QtSizePropertyManager::setRange(QtProperty *property, const QSize &minimum, const QSize &maximum) + + Sets the range of valid values. + + This is a convenience function defining the range of valid values + in one go; setting the \a minimum and \a maximum values for the + given \a property with a single function call. + + When setting a new range, the current value is adjusted if + necessary (ensuring that the value remains within the range). + + \sa setMinimum(), setMaximum(), rangeChanged() +*/ +void QtSizePropertyManager::setRange(QtProperty *property, const QSize &minVal, const QSize &maxVal) +{ + setBorderValues(this, d_ptr, + &QtSizePropertyManager::propertyChanged, + &QtSizePropertyManager::valueChanged, + &QtSizePropertyManager::rangeChanged, + property, minVal, maxVal, &QtSizePropertyManagerPrivate::setRange); +} + +/*! + \reimp +*/ +void QtSizePropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QtSizePropertyManagerPrivate::Data(); + + QtProperty *wProp = d_ptr->m_intPropertyManager->addProperty(); + wProp->setPropertyName(tr("Width")); + d_ptr->m_intPropertyManager->setValue(wProp, 0); + d_ptr->m_intPropertyManager->setMinimum(wProp, 0); + d_ptr->m_propertyToW[property] = wProp; + d_ptr->m_wToProperty[wProp] = property; + property->addSubProperty(wProp); + + QtProperty *hProp = d_ptr->m_intPropertyManager->addProperty(); + hProp->setPropertyName(tr("Height")); + d_ptr->m_intPropertyManager->setValue(hProp, 0); + d_ptr->m_intPropertyManager->setMinimum(hProp, 0); + d_ptr->m_propertyToH[property] = hProp; + d_ptr->m_hToProperty[hProp] = property; + property->addSubProperty(hProp); +} + +/*! + \reimp +*/ +void QtSizePropertyManager::uninitializeProperty(QtProperty *property) +{ + QtProperty *wProp = d_ptr->m_propertyToW[property]; + if (wProp) { + d_ptr->m_wToProperty.remove(wProp); + delete wProp; + } + d_ptr->m_propertyToW.remove(property); + + QtProperty *hProp = d_ptr->m_propertyToH[property]; + if (hProp) { + d_ptr->m_hToProperty.remove(hProp); + delete hProp; + } + d_ptr->m_propertyToH.remove(property); + + d_ptr->m_values.remove(property); +} + +// QtSizeFPropertyManager + +class QtSizeFPropertyManagerPrivate +{ + QtSizeFPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtSizeFPropertyManager) +public: + + void slotDoubleChanged(QtProperty *property, double value); + void slotPropertyDestroyed(QtProperty *property); + void setValue(QtProperty *property, const QSizeF &val); + void setRange(QtProperty *property, + const QSizeF &minVal, const QSizeF &maxVal, const QSizeF &val); + + struct Data + { + Data() : val(QSizeF(0, 0)), minVal(QSizeF(0, 0)), maxVal(QSizeF(INT_MAX, INT_MAX)), decimals(2) {} + QSizeF val; + QSizeF minVal; + QSizeF maxVal; + int decimals; + QSizeF minimumValue() const { return minVal; } + QSizeF maximumValue() const { return maxVal; } + void setMinimumValue(const QSizeF &newMinVal) { setSizeMinimumData(this, newMinVal); } + void setMaximumValue(const QSizeF &newMaxVal) { setSizeMaximumData(this, newMaxVal); } + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtDoublePropertyManager *m_doublePropertyManager; + + QMap m_propertyToW; + QMap m_propertyToH; + + QMap m_wToProperty; + QMap m_hToProperty; +}; + +void QtSizeFPropertyManagerPrivate::slotDoubleChanged(QtProperty *property, double value) +{ + if (QtProperty *prop = m_wToProperty.value(property, 0)) { + QSizeF s = m_values[prop].val; + s.setWidth(value); + q_ptr->setValue(prop, s); + } else if (QtProperty *prop = m_hToProperty.value(property, 0)) { + QSizeF s = m_values[prop].val; + s.setHeight(value); + q_ptr->setValue(prop, s); + } +} + +void QtSizeFPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property) +{ + if (QtProperty *pointProp = m_wToProperty.value(property, 0)) { + m_propertyToW[pointProp] = 0; + m_wToProperty.remove(property); + } else if (QtProperty *pointProp = m_hToProperty.value(property, 0)) { + m_propertyToH[pointProp] = 0; + m_hToProperty.remove(property); + } +} + +void QtSizeFPropertyManagerPrivate::setValue(QtProperty *property, const QSizeF &val) +{ + m_doublePropertyManager->setValue(m_propertyToW.value(property), val.width()); + m_doublePropertyManager->setValue(m_propertyToH.value(property), val.height()); +} + +void QtSizeFPropertyManagerPrivate::setRange(QtProperty *property, + const QSizeF &minVal, const QSizeF &maxVal, const QSizeF &val) +{ + m_doublePropertyManager->setRange(m_propertyToW[property], minVal.width(), maxVal.width()); + m_doublePropertyManager->setValue(m_propertyToW[property], val.width()); + m_doublePropertyManager->setRange(m_propertyToH[property], minVal.height(), maxVal.height()); + m_doublePropertyManager->setValue(m_propertyToH[property], val.height()); +} + +/*! + \class QtSizeFPropertyManager + + \brief The QtSizeFPropertyManager provides and manages QSizeF properties. + + A size property has nested \e width and \e height + subproperties. The top-level property's value can be retrieved + using the value() function, and set using the setValue() slot. + + The subproperties are created by a QtDoublePropertyManager object. This + manager can be retrieved using the subDoublePropertyManager() function. In + order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + A size property also has a range of valid values defined by a + minimum size and a maximum size. These sizes can be retrieved + using the minimum() and the maximum() functions, and set using the + setMinimum() and setMaximum() slots. Alternatively, the range can + be defined in one go using the setRange() slot. + + In addition, QtSizeFPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes, and the rangeChanged() signal which is emitted whenever + such a property changes its range of valid sizes. + + \sa QtAbstractPropertyManager, QtDoublePropertyManager, QtSizePropertyManager +*/ + +/*! + \fn void QtSizeFPropertyManager::valueChanged(QtProperty *property, const QSizeF &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtSizeFPropertyManager::rangeChanged(QtProperty *property, const QSizeF &minimum, const QSizeF &maximum) + + This signal is emitted whenever a property created by this manager + changes its range of valid sizes, passing a pointer to the \a + property and the new \a minimum and \a maximum sizes. + + \sa setRange() +*/ + +/*! + \fn void QtSizeFPropertyManager::decimalsChanged(QtProperty *property, int prec) + + This signal is emitted whenever a property created by this manager + changes its precision of value, passing a pointer to the + \a property and the new \a prec value + + \sa setDecimals() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtSizeFPropertyManager::QtSizeFPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtSizeFPropertyManagerPrivate; + d_ptr->q_ptr = this; + + d_ptr->m_doublePropertyManager = new QtDoublePropertyManager(this); + connect(d_ptr->m_doublePropertyManager, SIGNAL(valueChanged(QtProperty *, double)), + this, SLOT(slotDoubleChanged(QtProperty *, double))); + connect(d_ptr->m_doublePropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtSizeFPropertyManager::~QtSizeFPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the manager that creates the nested \e width and \e height + subproperties. + + In order to provide editing widgets for the \e width and \e height + properties in a property browser widget, this manager must be + associated with an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtDoublePropertyManager *QtSizeFPropertyManager::subDoublePropertyManager() const +{ + return d_ptr->m_doublePropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns an invalid size + + \sa setValue() +*/ +QSizeF QtSizeFPropertyManager::value(const QtProperty *property) const +{ + return getValue(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's precision, in decimals. + + \sa setDecimals() +*/ +int QtSizeFPropertyManager::decimals(const QtProperty *property) const +{ + return getData(d_ptr->m_values, &QtSizeFPropertyManagerPrivate::Data::decimals, property, 0); +} + +/*! + Returns the given \a property's minimum size value. + + \sa setMinimum(), maximum(), setRange() +*/ +QSizeF QtSizeFPropertyManager::minimum(const QtProperty *property) const +{ + return getMinimum(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's maximum size value. + + \sa setMaximum(), minimum(), setRange() +*/ +QSizeF QtSizeFPropertyManager::maximum(const QtProperty *property) const +{ + return getMaximum(d_ptr->m_values, property); +} + +/*! + \reimp +*/ +QString QtSizeFPropertyManager::valueText(const QtProperty *property) const +{ + const QtSizeFPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + const QSizeF v = it.value().val; + const int dec = it.value().decimals; + return QString(tr("%1 x %2").arg(QString::number(v.width(), 'f', dec)) + .arg(QString::number(v.height(), 'f', dec))); +} + +/*! + \fn void QtSizeFPropertyManager::setValue(QtProperty *property, const QSizeF &value) + + Sets the value of the given \a property to \a value. + + If the specified \a value is not valid according to the given \a + property's size range, the \a value is adjusted to the nearest + valid value within the size range. + + \sa value(), setRange(), valueChanged() +*/ +void QtSizeFPropertyManager::setValue(QtProperty *property, const QSizeF &val) +{ + setValueInRange(this, d_ptr, + &QtSizeFPropertyManager::propertyChanged, + &QtSizeFPropertyManager::valueChanged, + property, val, &QtSizeFPropertyManagerPrivate::setValue); +} + +/*! + \fn void QtSizeFPropertyManager::setDecimals(QtProperty *property, int prec) + + Sets the precision of the given \a property to \a prec. + + The valid decimal range is 0-13. The default is 2. + + \sa decimals() +*/ +void QtSizeFPropertyManager::setDecimals(QtProperty *property, int prec) +{ + const QtSizeFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtSizeFPropertyManagerPrivate::Data data = it.value(); + + if (prec > 13) + prec = 13; + else if (prec < 0) + prec = 0; + + if (data.decimals == prec) + return; + + data.decimals = prec; + d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToW[property], prec); + d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToH[property], prec); + + it.value() = data; + + emit decimalsChanged(property, data.decimals); +} + +/*! + Sets the minimum size value for the given \a property to \a minVal. + + When setting the minimum size value, the maximum and current + values are adjusted if necessary (ensuring that the size range + remains valid and that the current value is within the range). + + \sa minimum(), setRange(), rangeChanged() +*/ +void QtSizeFPropertyManager::setMinimum(QtProperty *property, const QSizeF &minVal) +{ + setBorderValue(this, d_ptr, + &QtSizeFPropertyManager::propertyChanged, + &QtSizeFPropertyManager::valueChanged, + &QtSizeFPropertyManager::rangeChanged, + property, + &QtSizeFPropertyManagerPrivate::Data::minimumValue, + &QtSizeFPropertyManagerPrivate::Data::setMinimumValue, + minVal, &QtSizeFPropertyManagerPrivate::setRange); +} + +/*! + Sets the maximum size value for the given \a property to \a maxVal. + + When setting the maximum size value, the minimum and current + values are adjusted if necessary (ensuring that the size range + remains valid and that the current value is within the range). + + \sa maximum(), setRange(), rangeChanged() +*/ +void QtSizeFPropertyManager::setMaximum(QtProperty *property, const QSizeF &maxVal) +{ + setBorderValue(this, d_ptr, + &QtSizeFPropertyManager::propertyChanged, + &QtSizeFPropertyManager::valueChanged, + &QtSizeFPropertyManager::rangeChanged, + property, + &QtSizeFPropertyManagerPrivate::Data::maximumValue, + &QtSizeFPropertyManagerPrivate::Data::setMaximumValue, + maxVal, &QtSizeFPropertyManagerPrivate::setRange); +} + +/*! + \fn void QtSizeFPropertyManager::setRange(QtProperty *property, const QSizeF &minimum, const QSizeF &maximum) + + Sets the range of valid values. + + This is a convenience function defining the range of valid values + in one go; setting the \a minimum and \a maximum values for the + given \a property with a single function call. + + When setting a new range, the current value is adjusted if + necessary (ensuring that the value remains within the range). + + \sa setMinimum(), setMaximum(), rangeChanged() +*/ +void QtSizeFPropertyManager::setRange(QtProperty *property, const QSizeF &minVal, const QSizeF &maxVal) +{ + setBorderValues(this, d_ptr, + &QtSizeFPropertyManager::propertyChanged, + &QtSizeFPropertyManager::valueChanged, + &QtSizeFPropertyManager::rangeChanged, + property, minVal, maxVal, &QtSizeFPropertyManagerPrivate::setRange); +} + +/*! + \reimp +*/ +void QtSizeFPropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QtSizeFPropertyManagerPrivate::Data(); + + QtProperty *wProp = d_ptr->m_doublePropertyManager->addProperty(); + wProp->setPropertyName(tr("Width")); + d_ptr->m_doublePropertyManager->setDecimals(wProp, decimals(property)); + d_ptr->m_doublePropertyManager->setValue(wProp, 0); + d_ptr->m_doublePropertyManager->setMinimum(wProp, 0); + d_ptr->m_propertyToW[property] = wProp; + d_ptr->m_wToProperty[wProp] = property; + property->addSubProperty(wProp); + + QtProperty *hProp = d_ptr->m_doublePropertyManager->addProperty(); + hProp->setPropertyName(tr("Height")); + d_ptr->m_doublePropertyManager->setDecimals(hProp, decimals(property)); + d_ptr->m_doublePropertyManager->setValue(hProp, 0); + d_ptr->m_doublePropertyManager->setMinimum(hProp, 0); + d_ptr->m_propertyToH[property] = hProp; + d_ptr->m_hToProperty[hProp] = property; + property->addSubProperty(hProp); +} + +/*! + \reimp +*/ +void QtSizeFPropertyManager::uninitializeProperty(QtProperty *property) +{ + QtProperty *wProp = d_ptr->m_propertyToW[property]; + if (wProp) { + d_ptr->m_wToProperty.remove(wProp); + delete wProp; + } + d_ptr->m_propertyToW.remove(property); + + QtProperty *hProp = d_ptr->m_propertyToH[property]; + if (hProp) { + d_ptr->m_hToProperty.remove(hProp); + delete hProp; + } + d_ptr->m_propertyToH.remove(property); + + d_ptr->m_values.remove(property); +} + +// QtRectPropertyManager + +class QtRectPropertyManagerPrivate +{ + QtRectPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtRectPropertyManager) +public: + + void slotIntChanged(QtProperty *property, int value); + void slotPropertyDestroyed(QtProperty *property); + void setConstraint(QtProperty *property, const QRect &constraint, const QRect &val); + + struct Data + { + Data() : val(0, 0, 0, 0) {} + QRect val; + QRect constraint; + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtIntPropertyManager *m_intPropertyManager; + + QMap m_propertyToX; + QMap m_propertyToY; + QMap m_propertyToW; + QMap m_propertyToH; + + QMap m_xToProperty; + QMap m_yToProperty; + QMap m_wToProperty; + QMap m_hToProperty; +}; + +void QtRectPropertyManagerPrivate::slotIntChanged(QtProperty *property, int value) +{ + if (QtProperty *prop = m_xToProperty.value(property, 0)) { + QRect r = m_values[prop].val; + r.moveLeft(value); + q_ptr->setValue(prop, r); + } else if (QtProperty *prop = m_yToProperty.value(property)) { + QRect r = m_values[prop].val; + r.moveTop(value); + q_ptr->setValue(prop, r); + } else if (QtProperty *prop = m_wToProperty.value(property, 0)) { + Data data = m_values[prop]; + QRect r = data.val; + r.setWidth(value); + if (!data.constraint.isNull() && data.constraint.x() + data.constraint.width() < r.x() + r.width()) { + r.moveLeft(data.constraint.left() + data.constraint.width() - r.width()); + } + q_ptr->setValue(prop, r); + } else if (QtProperty *prop = m_hToProperty.value(property, 0)) { + Data data = m_values[prop]; + QRect r = data.val; + r.setHeight(value); + if (!data.constraint.isNull() && data.constraint.y() + data.constraint.height() < r.y() + r.height()) { + r.moveTop(data.constraint.top() + data.constraint.height() - r.height()); + } + q_ptr->setValue(prop, r); + } +} + +void QtRectPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property) +{ + if (QtProperty *pointProp = m_xToProperty.value(property, 0)) { + m_propertyToX[pointProp] = 0; + m_xToProperty.remove(property); + } else if (QtProperty *pointProp = m_yToProperty.value(property, 0)) { + m_propertyToY[pointProp] = 0; + m_yToProperty.remove(property); + } else if (QtProperty *pointProp = m_wToProperty.value(property, 0)) { + m_propertyToW[pointProp] = 0; + m_wToProperty.remove(property); + } else if (QtProperty *pointProp = m_hToProperty.value(property, 0)) { + m_propertyToH[pointProp] = 0; + m_hToProperty.remove(property); + } +} + +void QtRectPropertyManagerPrivate::setConstraint(QtProperty *property, + const QRect &constraint, const QRect &val) +{ + const bool isNull = constraint.isNull(); + const int left = isNull ? INT_MIN : constraint.left(); + const int right = isNull ? INT_MAX : constraint.left() + constraint.width(); + const int top = isNull ? INT_MIN : constraint.top(); + const int bottom = isNull ? INT_MAX : constraint.top() + constraint.height(); + const int width = isNull ? INT_MAX : constraint.width(); + const int height = isNull ? INT_MAX : constraint.height(); + + m_intPropertyManager->setRange(m_propertyToX[property], left, right); + m_intPropertyManager->setRange(m_propertyToY[property], top, bottom); + m_intPropertyManager->setRange(m_propertyToW[property], 0, width); + m_intPropertyManager->setRange(m_propertyToH[property], 0, height); + + m_intPropertyManager->setValue(m_propertyToX[property], val.x()); + m_intPropertyManager->setValue(m_propertyToY[property], val.y()); + m_intPropertyManager->setValue(m_propertyToW[property], val.width()); + m_intPropertyManager->setValue(m_propertyToH[property], val.height()); +} + +/*! + \class QtRectPropertyManager + + \brief The QtRectPropertyManager provides and manages QRect properties. + + A rectangle property has nested \e x, \e y, \e width and \e height + subproperties. The top-level property's value can be retrieved + using the value() function, and set using the setValue() slot. + + The subproperties are created by a QtIntPropertyManager object. This + manager can be retrieved using the subIntPropertyManager() function. In + order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + A rectangle property also has a constraint rectangle which can be + retrieved using the constraint() function, and set using the + setConstraint() slot. + + In addition, QtRectPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes, and the constraintChanged() signal which is emitted + whenever such a property changes its constraint rectangle. + + \sa QtAbstractPropertyManager, QtIntPropertyManager, QtRectFPropertyManager +*/ + +/*! + \fn void QtRectPropertyManager::valueChanged(QtProperty *property, const QRect &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtRectPropertyManager::constraintChanged(QtProperty *property, const QRect &constraint) + + This signal is emitted whenever property changes its constraint + rectangle, passing a pointer to the \a property and the new \a + constraint rectangle as parameters. + + \sa setConstraint() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtRectPropertyManager::QtRectPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtRectPropertyManagerPrivate; + d_ptr->q_ptr = this; + + d_ptr->m_intPropertyManager = new QtIntPropertyManager(this); + connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotIntChanged(QtProperty *, int))); + connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtRectPropertyManager::~QtRectPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the manager that creates the nested \e x, \e y, \e width + and \e height subproperties. + + In order to provide editing widgets for the mentioned + subproperties in a property browser widget, this manager must be + associated with an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtIntPropertyManager *QtRectPropertyManager::subIntPropertyManager() const +{ + return d_ptr->m_intPropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns an invalid rectangle. + + \sa setValue(), constraint() +*/ +QRect QtRectPropertyManager::value(const QtProperty *property) const +{ + return getValue(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's constraining rectangle. If returned value is null QRect it means there is no constraint applied. + + \sa value(), setConstraint() +*/ +QRect QtRectPropertyManager::constraint(const QtProperty *property) const +{ + return getData(d_ptr->m_values, &QtRectPropertyManagerPrivate::Data::constraint, property, QRect()); +} + +/*! + \reimp +*/ +QString QtRectPropertyManager::valueText(const QtProperty *property) const +{ + const QtRectPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + const QRect v = it.value().val; + return QString(tr("[(%1, %2), %3 x %4]").arg(QString::number(v.x())) + .arg(QString::number(v.y())) + .arg(QString::number(v.width())) + .arg(QString::number(v.height()))); +} + +/*! + \fn void QtRectPropertyManager::setValue(QtProperty *property, const QRect &value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + If the specified \a value is not inside the given \a property's + constraining rectangle, the value is adjusted accordingly to fit + within the constraint. + + \sa value(), setConstraint(), valueChanged() +*/ +void QtRectPropertyManager::setValue(QtProperty *property, const QRect &val) +{ + const QtRectPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtRectPropertyManagerPrivate::Data data = it.value(); + + QRect newRect = val.normalized(); + if (!data.constraint.isNull() && !data.constraint.contains(newRect)) { + const QRect r1 = data.constraint; + const QRect r2 = newRect; + newRect.setLeft(qMax(r1.left(), r2.left())); + newRect.setRight(qMin(r1.right(), r2.right())); + newRect.setTop(qMax(r1.top(), r2.top())); + newRect.setBottom(qMin(r1.bottom(), r2.bottom())); + if (newRect.width() < 0 || newRect.height() < 0) + return; + } + + if (data.val == newRect) + return; + + data.val = newRect; + + it.value() = data; + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToX[property], newRect.x()); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToY[property], newRect.y()); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToW[property], newRect.width()); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToH[property], newRect.height()); + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + Sets the given \a property's constraining rectangle to \a + constraint. + + When setting the constraint, the current value is adjusted if + necessary (ensuring that the current rectangle value is inside the + constraint). In order to reset the constraint pass a null QRect value. + + \sa setValue(), constraint(), constraintChanged() +*/ +void QtRectPropertyManager::setConstraint(QtProperty *property, const QRect &constraint) +{ + const QtRectPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtRectPropertyManagerPrivate::Data data = it.value(); + + QRect newConstraint = constraint.normalized(); + if (data.constraint == newConstraint) + return; + + const QRect oldVal = data.val; + + data.constraint = newConstraint; + + if (!data.constraint.isNull() && !data.constraint.contains(oldVal)) { + QRect r1 = data.constraint; + QRect r2 = data.val; + + if (r2.width() > r1.width()) + r2.setWidth(r1.width()); + if (r2.height() > r1.height()) + r2.setHeight(r1.height()); + if (r2.left() < r1.left()) + r2.moveLeft(r1.left()); + else if (r2.right() > r1.right()) + r2.moveRight(r1.right()); + if (r2.top() < r1.top()) + r2.moveTop(r1.top()); + else if (r2.bottom() > r1.bottom()) + r2.moveBottom(r1.bottom()); + + data.val = r2; + } + + it.value() = data; + + emit constraintChanged(property, data.constraint); + + d_ptr->setConstraint(property, data.constraint, data.val); + + if (data.val == oldVal) + return; + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + \reimp +*/ +void QtRectPropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QtRectPropertyManagerPrivate::Data(); + + QtProperty *xProp = d_ptr->m_intPropertyManager->addProperty(); + xProp->setPropertyName(tr("X")); + d_ptr->m_intPropertyManager->setValue(xProp, 0); + d_ptr->m_propertyToX[property] = xProp; + d_ptr->m_xToProperty[xProp] = property; + property->addSubProperty(xProp); + + QtProperty *yProp = d_ptr->m_intPropertyManager->addProperty(); + yProp->setPropertyName(tr("Y")); + d_ptr->m_intPropertyManager->setValue(yProp, 0); + d_ptr->m_propertyToY[property] = yProp; + d_ptr->m_yToProperty[yProp] = property; + property->addSubProperty(yProp); + + QtProperty *wProp = d_ptr->m_intPropertyManager->addProperty(); + wProp->setPropertyName(tr("Width")); + d_ptr->m_intPropertyManager->setValue(wProp, 0); + d_ptr->m_intPropertyManager->setMinimum(wProp, 0); + d_ptr->m_propertyToW[property] = wProp; + d_ptr->m_wToProperty[wProp] = property; + property->addSubProperty(wProp); + + QtProperty *hProp = d_ptr->m_intPropertyManager->addProperty(); + hProp->setPropertyName(tr("Height")); + d_ptr->m_intPropertyManager->setValue(hProp, 0); + d_ptr->m_intPropertyManager->setMinimum(hProp, 0); + d_ptr->m_propertyToH[property] = hProp; + d_ptr->m_hToProperty[hProp] = property; + property->addSubProperty(hProp); +} + +/*! + \reimp +*/ +void QtRectPropertyManager::uninitializeProperty(QtProperty *property) +{ + QtProperty *xProp = d_ptr->m_propertyToX[property]; + if (xProp) { + d_ptr->m_xToProperty.remove(xProp); + delete xProp; + } + d_ptr->m_propertyToX.remove(property); + + QtProperty *yProp = d_ptr->m_propertyToY[property]; + if (yProp) { + d_ptr->m_yToProperty.remove(yProp); + delete yProp; + } + d_ptr->m_propertyToY.remove(property); + + QtProperty *wProp = d_ptr->m_propertyToW[property]; + if (wProp) { + d_ptr->m_wToProperty.remove(wProp); + delete wProp; + } + d_ptr->m_propertyToW.remove(property); + + QtProperty *hProp = d_ptr->m_propertyToH[property]; + if (hProp) { + d_ptr->m_hToProperty.remove(hProp); + delete hProp; + } + d_ptr->m_propertyToH.remove(property); + + d_ptr->m_values.remove(property); +} + +// QtRectFPropertyManager + +class QtRectFPropertyManagerPrivate +{ + QtRectFPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtRectFPropertyManager) +public: + + void slotDoubleChanged(QtProperty *property, double value); + void slotPropertyDestroyed(QtProperty *property); + void setConstraint(QtProperty *property, const QRectF &constraint, const QRectF &val); + + struct Data + { + Data() : val(0, 0, 0, 0), decimals(2) {} + QRectF val; + QRectF constraint; + int decimals; + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtDoublePropertyManager *m_doublePropertyManager; + + QMap m_propertyToX; + QMap m_propertyToY; + QMap m_propertyToW; + QMap m_propertyToH; + + QMap m_xToProperty; + QMap m_yToProperty; + QMap m_wToProperty; + QMap m_hToProperty; +}; + +void QtRectFPropertyManagerPrivate::slotDoubleChanged(QtProperty *property, double value) +{ + if (QtProperty *prop = m_xToProperty.value(property, 0)) { + QRectF r = m_values[prop].val; + r.moveLeft(value); + q_ptr->setValue(prop, r); + } else if (QtProperty *prop = m_yToProperty.value(property, 0)) { + QRectF r = m_values[prop].val; + r.moveTop(value); + q_ptr->setValue(prop, r); + } else if (QtProperty *prop = m_wToProperty.value(property, 0)) { + Data data = m_values[prop]; + QRectF r = data.val; + r.setWidth(value); + if (!data.constraint.isNull() && data.constraint.x() + data.constraint.width() < r.x() + r.width()) { + r.moveLeft(data.constraint.left() + data.constraint.width() - r.width()); + } + q_ptr->setValue(prop, r); + } else if (QtProperty *prop = m_hToProperty.value(property, 0)) { + Data data = m_values[prop]; + QRectF r = data.val; + r.setHeight(value); + if (!data.constraint.isNull() && data.constraint.y() + data.constraint.height() < r.y() + r.height()) { + r.moveTop(data.constraint.top() + data.constraint.height() - r.height()); + } + q_ptr->setValue(prop, r); + } +} + +void QtRectFPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property) +{ + if (QtProperty *pointProp = m_xToProperty.value(property, 0)) { + m_propertyToX[pointProp] = 0; + m_xToProperty.remove(property); + } else if (QtProperty *pointProp = m_yToProperty.value(property, 0)) { + m_propertyToY[pointProp] = 0; + m_yToProperty.remove(property); + } else if (QtProperty *pointProp = m_wToProperty.value(property, 0)) { + m_propertyToW[pointProp] = 0; + m_wToProperty.remove(property); + } else if (QtProperty *pointProp = m_hToProperty.value(property, 0)) { + m_propertyToH[pointProp] = 0; + m_hToProperty.remove(property); + } +} + +void QtRectFPropertyManagerPrivate::setConstraint(QtProperty *property, + const QRectF &constraint, const QRectF &val) +{ + const bool isNull = constraint.isNull(); + const float left = isNull ? FLT_MIN : constraint.left(); + const float right = isNull ? FLT_MAX : constraint.left() + constraint.width(); + const float top = isNull ? FLT_MIN : constraint.top(); + const float bottom = isNull ? FLT_MAX : constraint.top() + constraint.height(); + const float width = isNull ? FLT_MAX : constraint.width(); + const float height = isNull ? FLT_MAX : constraint.height(); + + m_doublePropertyManager->setRange(m_propertyToX[property], left, right); + m_doublePropertyManager->setRange(m_propertyToY[property], top, bottom); + m_doublePropertyManager->setRange(m_propertyToW[property], 0, width); + m_doublePropertyManager->setRange(m_propertyToH[property], 0, height); + + m_doublePropertyManager->setValue(m_propertyToX[property], val.x()); + m_doublePropertyManager->setValue(m_propertyToY[property], val.y()); + m_doublePropertyManager->setValue(m_propertyToW[property], val.width()); + m_doublePropertyManager->setValue(m_propertyToH[property], val.height()); +} + +/*! + \class QtRectFPropertyManager + + \brief The QtRectFPropertyManager provides and manages QRectF properties. + + A rectangle property has nested \e x, \e y, \e width and \e height + subproperties. The top-level property's value can be retrieved + using the value() function, and set using the setValue() slot. + + The subproperties are created by a QtDoublePropertyManager object. This + manager can be retrieved using the subDoublePropertyManager() function. In + order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + A rectangle property also has a constraint rectangle which can be + retrieved using the constraint() function, and set using the + setConstraint() slot. + + In addition, QtRectFPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes, and the constraintChanged() signal which is emitted + whenever such a property changes its constraint rectangle. + + \sa QtAbstractPropertyManager, QtDoublePropertyManager, QtRectPropertyManager +*/ + +/*! + \fn void QtRectFPropertyManager::valueChanged(QtProperty *property, const QRectF &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtRectFPropertyManager::constraintChanged(QtProperty *property, const QRectF &constraint) + + This signal is emitted whenever property changes its constraint + rectangle, passing a pointer to the \a property and the new \a + constraint rectangle as parameters. + + \sa setConstraint() +*/ + +/*! + \fn void QtRectFPropertyManager::decimalsChanged(QtProperty *property, int prec) + + This signal is emitted whenever a property created by this manager + changes its precision of value, passing a pointer to the + \a property and the new \a prec value + + \sa setDecimals() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtRectFPropertyManager::QtRectFPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtRectFPropertyManagerPrivate; + d_ptr->q_ptr = this; + + d_ptr->m_doublePropertyManager = new QtDoublePropertyManager(this); + connect(d_ptr->m_doublePropertyManager, SIGNAL(valueChanged(QtProperty *, double)), + this, SLOT(slotDoubleChanged(QtProperty *, double))); + connect(d_ptr->m_doublePropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtRectFPropertyManager::~QtRectFPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the manager that creates the nested \e x, \e y, \e width + and \e height subproperties. + + In order to provide editing widgets for the mentioned + subproperties in a property browser widget, this manager must be + associated with an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtDoublePropertyManager *QtRectFPropertyManager::subDoublePropertyManager() const +{ + return d_ptr->m_doublePropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns an invalid rectangle. + + \sa setValue(), constraint() +*/ +QRectF QtRectFPropertyManager::value(const QtProperty *property) const +{ + return getValue(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's precision, in decimals. + + \sa setDecimals() +*/ +int QtRectFPropertyManager::decimals(const QtProperty *property) const +{ + return getData(d_ptr->m_values, &QtRectFPropertyManagerPrivate::Data::decimals, property, 0); +} + +/*! + Returns the given \a property's constraining rectangle. If returned value is null QRectF it means there is no constraint applied. + + \sa value(), setConstraint() +*/ +QRectF QtRectFPropertyManager::constraint(const QtProperty *property) const +{ + return getData(d_ptr->m_values, &QtRectFPropertyManagerPrivate::Data::constraint, property, QRect()); +} + +/*! + \reimp +*/ +QString QtRectFPropertyManager::valueText(const QtProperty *property) const +{ + const QtRectFPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + const QRectF v = it.value().val; + const int dec = it.value().decimals; + return QString(tr("[(%1, %2), %3 x %4]").arg(QString::number(v.x(), 'f', dec)) + .arg(QString::number(v.y(), 'f', dec)) + .arg(QString::number(v.width(), 'f', dec)) + .arg(QString::number(v.height(), 'f', dec))); +} + +/*! + \fn void QtRectFPropertyManager::setValue(QtProperty *property, const QRectF &value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + If the specified \a value is not inside the given \a property's + constraining rectangle, the value is adjusted accordingly to fit + within the constraint. + + \sa value(), setConstraint(), valueChanged() +*/ +void QtRectFPropertyManager::setValue(QtProperty *property, const QRectF &val) +{ + const QtRectFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtRectFPropertyManagerPrivate::Data data = it.value(); + + QRectF newRect = val.normalized(); + if (!data.constraint.isNull() && !data.constraint.contains(newRect)) { + const QRectF r1 = data.constraint; + const QRectF r2 = newRect; + newRect.setLeft(qMax(r1.left(), r2.left())); + newRect.setRight(qMin(r1.right(), r2.right())); + newRect.setTop(qMax(r1.top(), r2.top())); + newRect.setBottom(qMin(r1.bottom(), r2.bottom())); + if (newRect.width() < 0 || newRect.height() < 0) + return; + } + + if (data.val == newRect) + return; + + data.val = newRect; + + it.value() = data; + d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToX[property], newRect.x()); + d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToY[property], newRect.y()); + d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToW[property], newRect.width()); + d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToH[property], newRect.height()); + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + Sets the given \a property's constraining rectangle to \a + constraint. + + When setting the constraint, the current value is adjusted if + necessary (ensuring that the current rectangle value is inside the + constraint). In order to reset the constraint pass a null QRectF value. + + \sa setValue(), constraint(), constraintChanged() +*/ +void QtRectFPropertyManager::setConstraint(QtProperty *property, const QRectF &constraint) +{ + const QtRectFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtRectFPropertyManagerPrivate::Data data = it.value(); + + QRectF newConstraint = constraint.normalized(); + if (data.constraint == newConstraint) + return; + + const QRectF oldVal = data.val; + + data.constraint = newConstraint; + + if (!data.constraint.isNull() && !data.constraint.contains(oldVal)) { + QRectF r1 = data.constraint; + QRectF r2 = data.val; + + if (r2.width() > r1.width()) + r2.setWidth(r1.width()); + if (r2.height() > r1.height()) + r2.setHeight(r1.height()); + if (r2.left() < r1.left()) + r2.moveLeft(r1.left()); + else if (r2.right() > r1.right()) + r2.moveRight(r1.right()); + if (r2.top() < r1.top()) + r2.moveTop(r1.top()); + else if (r2.bottom() > r1.bottom()) + r2.moveBottom(r1.bottom()); + + data.val = r2; + } + + it.value() = data; + + emit constraintChanged(property, data.constraint); + + d_ptr->setConstraint(property, data.constraint, data.val); + + if (data.val == oldVal) + return; + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + \fn void QtRectFPropertyManager::setDecimals(QtProperty *property, int prec) + + Sets the precision of the given \a property to \a prec. + + The valid decimal range is 0-13. The default is 2. + + \sa decimals() +*/ +void QtRectFPropertyManager::setDecimals(QtProperty *property, int prec) +{ + const QtRectFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtRectFPropertyManagerPrivate::Data data = it.value(); + + if (prec > 13) + prec = 13; + else if (prec < 0) + prec = 0; + + if (data.decimals == prec) + return; + + data.decimals = prec; + d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToX[property], prec); + d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToY[property], prec); + d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToW[property], prec); + d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToH[property], prec); + + it.value() = data; + + emit decimalsChanged(property, data.decimals); +} + +/*! + \reimp +*/ +void QtRectFPropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QtRectFPropertyManagerPrivate::Data(); + + QtProperty *xProp = d_ptr->m_doublePropertyManager->addProperty(); + xProp->setPropertyName(tr("X")); + d_ptr->m_doublePropertyManager->setDecimals(xProp, decimals(property)); + d_ptr->m_doublePropertyManager->setValue(xProp, 0); + d_ptr->m_propertyToX[property] = xProp; + d_ptr->m_xToProperty[xProp] = property; + property->addSubProperty(xProp); + + QtProperty *yProp = d_ptr->m_doublePropertyManager->addProperty(); + yProp->setPropertyName(tr("Y")); + d_ptr->m_doublePropertyManager->setDecimals(yProp, decimals(property)); + d_ptr->m_doublePropertyManager->setValue(yProp, 0); + d_ptr->m_propertyToY[property] = yProp; + d_ptr->m_yToProperty[yProp] = property; + property->addSubProperty(yProp); + + QtProperty *wProp = d_ptr->m_doublePropertyManager->addProperty(); + wProp->setPropertyName(tr("Width")); + d_ptr->m_doublePropertyManager->setDecimals(wProp, decimals(property)); + d_ptr->m_doublePropertyManager->setValue(wProp, 0); + d_ptr->m_doublePropertyManager->setMinimum(wProp, 0); + d_ptr->m_propertyToW[property] = wProp; + d_ptr->m_wToProperty[wProp] = property; + property->addSubProperty(wProp); + + QtProperty *hProp = d_ptr->m_doublePropertyManager->addProperty(); + hProp->setPropertyName(tr("Height")); + d_ptr->m_doublePropertyManager->setDecimals(hProp, decimals(property)); + d_ptr->m_doublePropertyManager->setValue(hProp, 0); + d_ptr->m_doublePropertyManager->setMinimum(hProp, 0); + d_ptr->m_propertyToH[property] = hProp; + d_ptr->m_hToProperty[hProp] = property; + property->addSubProperty(hProp); +} + +/*! + \reimp +*/ +void QtRectFPropertyManager::uninitializeProperty(QtProperty *property) +{ + QtProperty *xProp = d_ptr->m_propertyToX[property]; + if (xProp) { + d_ptr->m_xToProperty.remove(xProp); + delete xProp; + } + d_ptr->m_propertyToX.remove(property); + + QtProperty *yProp = d_ptr->m_propertyToY[property]; + if (yProp) { + d_ptr->m_yToProperty.remove(yProp); + delete yProp; + } + d_ptr->m_propertyToY.remove(property); + + QtProperty *wProp = d_ptr->m_propertyToW[property]; + if (wProp) { + d_ptr->m_wToProperty.remove(wProp); + delete wProp; + } + d_ptr->m_propertyToW.remove(property); + + QtProperty *hProp = d_ptr->m_propertyToH[property]; + if (hProp) { + d_ptr->m_hToProperty.remove(hProp); + delete hProp; + } + d_ptr->m_propertyToH.remove(property); + + d_ptr->m_values.remove(property); +} + +// QtEnumPropertyManager + +class QtEnumPropertyManagerPrivate +{ + QtEnumPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtEnumPropertyManager) +public: + + struct Data + { + Data() : val(-1) {} + int val; + QStringList enumNames; + QMap enumIcons; + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; +}; + +/*! + \class QtEnumPropertyManager + + \brief The QtEnumPropertyManager provides and manages enum properties. + + Each enum property has an associated list of enum names which can + be retrieved using the enumNames() function, and set using the + corresponding setEnumNames() function. An enum property's value is + represented by an index in this list, and can be retrieved and set + using the value() and setValue() slots respectively. + + Each enum value can also have an associated icon. The mapping from + values to icons can be set using the setEnumIcons() function and + queried with the enumIcons() function. + + In addition, QtEnumPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes. The enumNamesChanged() or enumIconsChanged() signal is emitted + whenever the list of enum names or icons is altered. + + \sa QtAbstractPropertyManager, QtEnumEditorFactory +*/ + +/*! + \fn void QtEnumPropertyManager::valueChanged(QtProperty *property, int value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtEnumPropertyManager::enumNamesChanged(QtProperty *property, const QStringList &names) + + This signal is emitted whenever a property created by this manager + changes its enum names, passing a pointer to the \a property and + the new \a names as parameters. + + \sa setEnumNames() +*/ + +/*! + \fn void QtEnumPropertyManager::enumIconsChanged(QtProperty *property, const QMap &icons) + + This signal is emitted whenever a property created by this manager + changes its enum icons, passing a pointer to the \a property and + the new mapping of values to \a icons as parameters. + + \sa setEnumIcons() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtEnumPropertyManager::QtEnumPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtEnumPropertyManagerPrivate; + d_ptr->q_ptr = this; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtEnumPropertyManager::~QtEnumPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the given \a property's value which is an index in the + list returned by enumNames() + + If the given property is not managed by this manager, this + function returns -1. + + \sa enumNames(), setValue() +*/ +int QtEnumPropertyManager::value(const QtProperty *property) const +{ + return getValue(d_ptr->m_values, property, -1); +} + +/*! + Returns the given \a property's list of enum names. + + \sa value(), setEnumNames() +*/ +QStringList QtEnumPropertyManager::enumNames(const QtProperty *property) const +{ + return getData(d_ptr->m_values, &QtEnumPropertyManagerPrivate::Data::enumNames, property, QStringList()); +} + +/*! + Returns the given \a property's map of enum values to their icons. + + \sa value(), setEnumIcons() +*/ +QMap QtEnumPropertyManager::enumIcons(const QtProperty *property) const +{ + return getData >(d_ptr->m_values, &QtEnumPropertyManagerPrivate::Data::enumIcons, property, QMap()); +} + +/*! + \reimp +*/ +QString QtEnumPropertyManager::valueText(const QtProperty *property) const +{ + const QtEnumPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + + const QtEnumPropertyManagerPrivate::Data &data = it.value(); + + const int v = data.val; + if (v >= 0 && v < data.enumNames.count()) + return data.enumNames.at(v); + return QString(); +} + +/*! + \reimp +*/ +QIcon QtEnumPropertyManager::valueIcon(const QtProperty *property) const +{ + const QtEnumPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QIcon(); + + const QtEnumPropertyManagerPrivate::Data &data = it.value(); + + const int v = data.val; + return data.enumIcons.value(v); +} + +/*! + \fn void QtEnumPropertyManager::setValue(QtProperty *property, int value) + + Sets the value of the given \a property to \a value. + + The specified \a value must be less than the size of the given \a + property's enumNames() list, and larger than (or equal to) 0. + + \sa value(), valueChanged() +*/ +void QtEnumPropertyManager::setValue(QtProperty *property, int val) +{ + const QtEnumPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtEnumPropertyManagerPrivate::Data data = it.value(); + + if (val >= data.enumNames.count()) + return; + + if (val < 0 && data.enumNames.count() > 0) + return; + + if (val < 0) + val = -1; + + if (data.val == val) + return; + + data.val = val; + + it.value() = data; + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + Sets the given \a property's list of enum names to \a + enumNames. The \a property's current value is reset to 0 + indicating the first item of the list. + + If the specified \a enumNames list is empty, the \a property's + current value is set to -1. + + \sa enumNames(), enumNamesChanged() +*/ +void QtEnumPropertyManager::setEnumNames(QtProperty *property, const QStringList &enumNames) +{ + const QtEnumPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtEnumPropertyManagerPrivate::Data data = it.value(); + + if (data.enumNames == enumNames) + return; + + data.enumNames = enumNames; + + data.val = -1; + + if (enumNames.count() > 0) + data.val = 0; + + it.value() = data; + + emit enumNamesChanged(property, data.enumNames); + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + Sets the given \a property's map of enum values to their icons to \a + enumIcons. + + Each enum value can have associated icon. This association is represented with passed \a enumIcons map. + + \sa enumNames(), enumNamesChanged() +*/ +void QtEnumPropertyManager::setEnumIcons(QtProperty *property, const QMap &enumIcons) +{ + const QtEnumPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + it.value().enumIcons = enumIcons; + + emit enumIconsChanged(property, it.value().enumIcons); + + emit propertyChanged(property); +} + +/*! + \reimp +*/ +void QtEnumPropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QtEnumPropertyManagerPrivate::Data(); +} + +/*! + \reimp +*/ +void QtEnumPropertyManager::uninitializeProperty(QtProperty *property) +{ + d_ptr->m_values.remove(property); +} + +// QtFlagPropertyManager + +class QtFlagPropertyManagerPrivate +{ + QtFlagPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtFlagPropertyManager) +public: + + void slotBoolChanged(QtProperty *property, bool value); + void slotPropertyDestroyed(QtProperty *property); + + struct Data + { + Data() : val(-1) {} + int val; + QStringList flagNames; + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtBoolPropertyManager *m_boolPropertyManager; + + QMap > m_propertyToFlags; + + QMap m_flagToProperty; +}; + +void QtFlagPropertyManagerPrivate::slotBoolChanged(QtProperty *property, bool value) +{ + QtProperty *prop = m_flagToProperty.value(property, 0); + if (prop == 0) + return; + + QListIterator itProp(m_propertyToFlags[prop]); + int level = 0; + while (itProp.hasNext()) { + QtProperty *p = itProp.next(); + if (p == property) { + int v = m_values[prop].val; + if (value) { + v |= (1 << level); + } else { + v &= ~(1 << level); + } + q_ptr->setValue(prop, v); + return; + } + level++; + } +} + +void QtFlagPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property) +{ + QtProperty *flagProperty = m_flagToProperty.value(property, 0); + if (flagProperty == 0) + return; + + m_propertyToFlags[flagProperty].replace(m_propertyToFlags[flagProperty].indexOf(property), 0); + m_flagToProperty.remove(property); +} + +/*! + \class QtFlagPropertyManager + + \brief The QtFlagPropertyManager provides and manages flag properties. + + Each flag property has an associated list of flag names which can + be retrieved using the flagNames() function, and set using the + corresponding setFlagNames() function. + + The flag manager provides properties with nested boolean + subproperties representing each flag, i.e. a flag property's value + is the binary combination of the subproperties' values. A + property's value can be retrieved and set using the value() and + setValue() slots respectively. The combination of flags is represented + by single int value - that's why it's possible to store up to + 32 independent flags in one flag property. + + The subproperties are created by a QtBoolPropertyManager object. This + manager can be retrieved using the subBoolPropertyManager() function. In + order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + In addition, QtFlagPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes, and the flagNamesChanged() signal which is emitted + whenever the list of flag names is altered. + + \sa QtAbstractPropertyManager, QtBoolPropertyManager +*/ + +/*! + \fn void QtFlagPropertyManager::valueChanged(QtProperty *property, int value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtFlagPropertyManager::flagNamesChanged(QtProperty *property, const QStringList &names) + + This signal is emitted whenever a property created by this manager + changes its flag names, passing a pointer to the \a property and the + new \a names as parameters. + + \sa setFlagNames() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtFlagPropertyManager::QtFlagPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtFlagPropertyManagerPrivate; + d_ptr->q_ptr = this; + + d_ptr->m_boolPropertyManager = new QtBoolPropertyManager(this); + connect(d_ptr->m_boolPropertyManager, SIGNAL(valueChanged(QtProperty *, bool)), + this, SLOT(slotBoolChanged(QtProperty *, bool))); + connect(d_ptr->m_boolPropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtFlagPropertyManager::~QtFlagPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the manager that produces the nested boolean subproperties + representing each flag. + + In order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtBoolPropertyManager *QtFlagPropertyManager::subBoolPropertyManager() const +{ + return d_ptr->m_boolPropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given property is not managed by this manager, this + function returns 0. + + \sa flagNames(), setValue() +*/ +int QtFlagPropertyManager::value(const QtProperty *property) const +{ + return getValue(d_ptr->m_values, property, 0); +} + +/*! + Returns the given \a property's list of flag names. + + \sa value(), setFlagNames() +*/ +QStringList QtFlagPropertyManager::flagNames(const QtProperty *property) const +{ + return getData(d_ptr->m_values, &QtFlagPropertyManagerPrivate::Data::flagNames, property, QStringList()); +} + +/*! + \reimp +*/ +QString QtFlagPropertyManager::valueText(const QtProperty *property) const +{ + const QtFlagPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + + const QtFlagPropertyManagerPrivate::Data &data = it.value(); + + QString str; + int level = 0; + const QChar bar = QLatin1Char('|'); + const QStringList::const_iterator fncend = data.flagNames.constEnd(); + for (QStringList::const_iterator it = data.flagNames.constBegin(); it != fncend; ++it) { + if (data.val & (1 << level)) { + if (!str.isEmpty()) + str += bar; + str += *it; + } + + level++; + } + return str; +} + +/*! + \fn void QtFlagPropertyManager::setValue(QtProperty *property, int value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + The specified \a value must be less than the binary combination of + the property's flagNames() list size (i.e. less than 2\sup n, + where \c n is the size of the list) and larger than (or equal to) + 0. + + \sa value(), valueChanged() +*/ +void QtFlagPropertyManager::setValue(QtProperty *property, int val) +{ + const QtFlagPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtFlagPropertyManagerPrivate::Data data = it.value(); + + if (data.val == val) + return; + + if (val > (1 << data.flagNames.count()) - 1) + return; + + if (val < 0) + return; + + data.val = val; + + it.value() = data; + + QListIterator itProp(d_ptr->m_propertyToFlags[property]); + int level = 0; + while (itProp.hasNext()) { + QtProperty *prop = itProp.next(); + if (prop) + d_ptr->m_boolPropertyManager->setValue(prop, val & (1 << level)); + level++; + } + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + Sets the given \a property's list of flag names to \a flagNames. The + property's current value is reset to 0 indicating the first item + of the list. + + \sa flagNames(), flagNamesChanged() +*/ +void QtFlagPropertyManager::setFlagNames(QtProperty *property, const QStringList &flagNames) +{ + const QtFlagPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtFlagPropertyManagerPrivate::Data data = it.value(); + + if (data.flagNames == flagNames) + return; + + data.flagNames = flagNames; + data.val = 0; + + it.value() = data; + + QListIterator itProp(d_ptr->m_propertyToFlags[property]); + while (itProp.hasNext()) { + QtProperty *prop = itProp.next(); + if (prop) { + delete prop; + d_ptr->m_flagToProperty.remove(prop); + } + } + d_ptr->m_propertyToFlags[property].clear(); + + QStringListIterator itFlag(flagNames); + while (itFlag.hasNext()) { + const QString flagName = itFlag.next(); + QtProperty *prop = d_ptr->m_boolPropertyManager->addProperty(); + prop->setPropertyName(flagName); + property->addSubProperty(prop); + d_ptr->m_propertyToFlags[property].append(prop); + d_ptr->m_flagToProperty[prop] = property; + } + + emit flagNamesChanged(property, data.flagNames); + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + \reimp +*/ +void QtFlagPropertyManager::initializeProperty(QtProperty *property) +{ + d_ptr->m_values[property] = QtFlagPropertyManagerPrivate::Data(); + + d_ptr->m_propertyToFlags[property] = QList(); +} + +/*! + \reimp +*/ +void QtFlagPropertyManager::uninitializeProperty(QtProperty *property) +{ + QListIterator itProp(d_ptr->m_propertyToFlags[property]); + while (itProp.hasNext()) { + QtProperty *prop = itProp.next(); + if (prop) { + delete prop; + d_ptr->m_flagToProperty.remove(prop); + } + } + d_ptr->m_propertyToFlags.remove(property); + + d_ptr->m_values.remove(property); +} + +// QtSizePolicyPropertyManager + +class QtSizePolicyPropertyManagerPrivate +{ + QtSizePolicyPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtSizePolicyPropertyManager) +public: + + QtSizePolicyPropertyManagerPrivate(); + + void slotIntChanged(QtProperty *property, int value); + void slotEnumChanged(QtProperty *property, int value); + void slotPropertyDestroyed(QtProperty *property); + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtIntPropertyManager *m_intPropertyManager; + QtEnumPropertyManager *m_enumPropertyManager; + + QMap m_propertyToHPolicy; + QMap m_propertyToVPolicy; + QMap m_propertyToHStretch; + QMap m_propertyToVStretch; + + QMap m_hPolicyToProperty; + QMap m_vPolicyToProperty; + QMap m_hStretchToProperty; + QMap m_vStretchToProperty; +}; + +QtSizePolicyPropertyManagerPrivate::QtSizePolicyPropertyManagerPrivate() +{ +} + +void QtSizePolicyPropertyManagerPrivate::slotIntChanged(QtProperty *property, int value) +{ + if (QtProperty *prop = m_hStretchToProperty.value(property, 0)) { + QSizePolicy sp = m_values[prop]; + sp.setHorizontalStretch(value); + q_ptr->setValue(prop, sp); + } else if (QtProperty *prop = m_vStretchToProperty.value(property, 0)) { + QSizePolicy sp = m_values[prop]; + sp.setVerticalStretch(value); + q_ptr->setValue(prop, sp); + } +} + +void QtSizePolicyPropertyManagerPrivate::slotEnumChanged(QtProperty *property, int value) +{ + if (QtProperty *prop = m_hPolicyToProperty.value(property, 0)) { + QSizePolicy sp = m_values[prop]; + sp.setHorizontalPolicy(metaEnumProvider()->indexToSizePolicy(value)); + q_ptr->setValue(prop, sp); + } else if (QtProperty *prop = m_vPolicyToProperty.value(property, 0)) { + QSizePolicy sp = m_values[prop]; + sp.setVerticalPolicy(metaEnumProvider()->indexToSizePolicy(value)); + q_ptr->setValue(prop, sp); + } +} + +void QtSizePolicyPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property) +{ + if (QtProperty *pointProp = m_hStretchToProperty.value(property, 0)) { + m_propertyToHStretch[pointProp] = 0; + m_hStretchToProperty.remove(property); + } else if (QtProperty *pointProp = m_vStretchToProperty.value(property, 0)) { + m_propertyToVStretch[pointProp] = 0; + m_vStretchToProperty.remove(property); + } else if (QtProperty *pointProp = m_hPolicyToProperty.value(property, 0)) { + m_propertyToHPolicy[pointProp] = 0; + m_hPolicyToProperty.remove(property); + } else if (QtProperty *pointProp = m_vPolicyToProperty.value(property, 0)) { + m_propertyToVPolicy[pointProp] = 0; + m_vPolicyToProperty.remove(property); + } +} + +/*! + \class QtSizePolicyPropertyManager + + \brief The QtSizePolicyPropertyManager provides and manages QSizePolicy properties. + + A size policy property has nested \e horizontalPolicy, \e + verticalPolicy, \e horizontalStretch and \e verticalStretch + subproperties. The top-level property's value can be retrieved + using the value() function, and set using the setValue() slot. + + The subproperties are created by QtIntPropertyManager and QtEnumPropertyManager + objects. These managers can be retrieved using the subIntPropertyManager() + and subEnumPropertyManager() functions respectively. In order to provide + editing widgets for the subproperties in a property browser widget, + these managers must be associated with editor factories. + + In addition, QtSizePolicyPropertyManager provides the valueChanged() + signal which is emitted whenever a property created by this + manager changes. + + \sa QtAbstractPropertyManager, QtIntPropertyManager, QtEnumPropertyManager +*/ + +/*! + \fn void QtSizePolicyPropertyManager::valueChanged(QtProperty *property, const QSizePolicy &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. + + \sa setValue() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtSizePolicyPropertyManager::QtSizePolicyPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtSizePolicyPropertyManagerPrivate; + d_ptr->q_ptr = this; + + d_ptr->m_intPropertyManager = new QtIntPropertyManager(this); + connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotIntChanged(QtProperty *, int))); + d_ptr->m_enumPropertyManager = new QtEnumPropertyManager(this); + connect(d_ptr->m_enumPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotEnumChanged(QtProperty *, int))); + + connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); + connect(d_ptr->m_enumPropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtSizePolicyPropertyManager::~QtSizePolicyPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the manager that creates the nested \e horizontalStretch + and \e verticalStretch subproperties. + + In order to provide editing widgets for the mentioned subproperties + in a property browser widget, this manager must be associated with + an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtIntPropertyManager *QtSizePolicyPropertyManager::subIntPropertyManager() const +{ + return d_ptr->m_intPropertyManager; +} + +/*! + Returns the manager that creates the nested \e horizontalPolicy + and \e verticalPolicy subproperties. + + In order to provide editing widgets for the mentioned subproperties + in a property browser widget, this manager must be associated with + an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtEnumPropertyManager *QtSizePolicyPropertyManager::subEnumPropertyManager() const +{ + return d_ptr->m_enumPropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given property is not managed by this manager, this + function returns the default size policy. + + \sa setValue() +*/ +QSizePolicy QtSizePolicyPropertyManager::value(const QtProperty *property) const +{ + return d_ptr->m_values.value(property, QSizePolicy()); +} + +/*! + \reimp +*/ +QString QtSizePolicyPropertyManager::valueText(const QtProperty *property) const +{ + const QtSizePolicyPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + + const QSizePolicy sp = it.value(); + const QtMetaEnumProvider *mep = metaEnumProvider(); + const int hIndex = mep->sizePolicyToIndex(sp.horizontalPolicy()); + const int vIndex = mep->sizePolicyToIndex(sp.verticalPolicy()); + //! Unknown size policy on reading invalid uic3 files + const QString hPolicy = hIndex != -1 ? mep->policyEnumNames().at(hIndex) : tr(""); + const QString vPolicy = vIndex != -1 ? mep->policyEnumNames().at(vIndex) : tr(""); + const QString str = tr("[%1, %2, %3, %4]").arg(hPolicy, vPolicy).arg(sp.horizontalStretch()).arg(sp.verticalStretch()); + return str; +} + +/*! + \fn void QtSizePolicyPropertyManager::setValue(QtProperty *property, const QSizePolicy &value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + \sa value(), valueChanged() +*/ +void QtSizePolicyPropertyManager::setValue(QtProperty *property, const QSizePolicy &val) +{ + const QtSizePolicyPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + if (it.value() == val) + return; + + it.value() = val; + + d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToHPolicy[property], + metaEnumProvider()->sizePolicyToIndex(val.horizontalPolicy())); + d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToVPolicy[property], + metaEnumProvider()->sizePolicyToIndex(val.verticalPolicy())); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToHStretch[property], + val.horizontalStretch()); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToVStretch[property], + val.verticalStretch()); + + emit propertyChanged(property); + emit valueChanged(property, val); +} + +/*! + \reimp +*/ +void QtSizePolicyPropertyManager::initializeProperty(QtProperty *property) +{ + QSizePolicy val; + d_ptr->m_values[property] = val; + + QtProperty *hPolicyProp = d_ptr->m_enumPropertyManager->addProperty(); + hPolicyProp->setPropertyName(tr("Horizontal Policy")); + d_ptr->m_enumPropertyManager->setEnumNames(hPolicyProp, metaEnumProvider()->policyEnumNames()); + d_ptr->m_enumPropertyManager->setValue(hPolicyProp, + metaEnumProvider()->sizePolicyToIndex(val.horizontalPolicy())); + d_ptr->m_propertyToHPolicy[property] = hPolicyProp; + d_ptr->m_hPolicyToProperty[hPolicyProp] = property; + property->addSubProperty(hPolicyProp); + + QtProperty *vPolicyProp = d_ptr->m_enumPropertyManager->addProperty(); + vPolicyProp->setPropertyName(tr("Vertical Policy")); + d_ptr->m_enumPropertyManager->setEnumNames(vPolicyProp, metaEnumProvider()->policyEnumNames()); + d_ptr->m_enumPropertyManager->setValue(vPolicyProp, + metaEnumProvider()->sizePolicyToIndex(val.verticalPolicy())); + d_ptr->m_propertyToVPolicy[property] = vPolicyProp; + d_ptr->m_vPolicyToProperty[vPolicyProp] = property; + property->addSubProperty(vPolicyProp); + + QtProperty *hStretchProp = d_ptr->m_intPropertyManager->addProperty(); + hStretchProp->setPropertyName(tr("Horizontal Stretch")); + d_ptr->m_intPropertyManager->setValue(hStretchProp, val.horizontalStretch()); + d_ptr->m_intPropertyManager->setRange(hStretchProp, 0, 0xff); + d_ptr->m_propertyToHStretch[property] = hStretchProp; + d_ptr->m_hStretchToProperty[hStretchProp] = property; + property->addSubProperty(hStretchProp); + + QtProperty *vStretchProp = d_ptr->m_intPropertyManager->addProperty(); + vStretchProp->setPropertyName(tr("Vertical Stretch")); + d_ptr->m_intPropertyManager->setValue(vStretchProp, val.verticalStretch()); + d_ptr->m_intPropertyManager->setRange(vStretchProp, 0, 0xff); + d_ptr->m_propertyToVStretch[property] = vStretchProp; + d_ptr->m_vStretchToProperty[vStretchProp] = property; + property->addSubProperty(vStretchProp); + +} + +/*! + \reimp +*/ +void QtSizePolicyPropertyManager::uninitializeProperty(QtProperty *property) +{ + QtProperty *hPolicyProp = d_ptr->m_propertyToHPolicy[property]; + if (hPolicyProp) { + d_ptr->m_hPolicyToProperty.remove(hPolicyProp); + delete hPolicyProp; + } + d_ptr->m_propertyToHPolicy.remove(property); + + QtProperty *vPolicyProp = d_ptr->m_propertyToVPolicy[property]; + if (vPolicyProp) { + d_ptr->m_vPolicyToProperty.remove(vPolicyProp); + delete vPolicyProp; + } + d_ptr->m_propertyToVPolicy.remove(property); + + QtProperty *hStretchProp = d_ptr->m_propertyToHStretch[property]; + if (hStretchProp) { + d_ptr->m_hStretchToProperty.remove(hStretchProp); + delete hStretchProp; + } + d_ptr->m_propertyToHStretch.remove(property); + + QtProperty *vStretchProp = d_ptr->m_propertyToVStretch[property]; + if (vStretchProp) { + d_ptr->m_vStretchToProperty.remove(vStretchProp); + delete vStretchProp; + } + d_ptr->m_propertyToVStretch.remove(property); + + d_ptr->m_values.remove(property); +} + +// QtFontPropertyManager: +// QtFontPropertyManagerPrivate has a mechanism for reacting +// to QApplication::fontDatabaseChanged() [4.5], which is emitted +// when someone loads an application font. The signals are compressed +// using a timer with interval 0, which then causes the family +// enumeration manager to re-set its strings and index values +// for each property. + +Q_GLOBAL_STATIC(QFontDatabase, fontDatabase) + +class QtFontPropertyManagerPrivate +{ + QtFontPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtFontPropertyManager) +public: + + QtFontPropertyManagerPrivate(); + + void slotIntChanged(QtProperty *property, int value); + void slotEnumChanged(QtProperty *property, int value); + void slotBoolChanged(QtProperty *property, bool value); + void slotPropertyDestroyed(QtProperty *property); + void slotFontDatabaseChanged(); + void slotFontDatabaseDelayedChange(); + + QStringList m_familyNames; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtIntPropertyManager *m_intPropertyManager; + QtEnumPropertyManager *m_enumPropertyManager; + QtBoolPropertyManager *m_boolPropertyManager; + + QMap m_propertyToFamily; + QMap m_propertyToPointSize; + QMap m_propertyToBold; + QMap m_propertyToItalic; + QMap m_propertyToUnderline; + QMap m_propertyToStrikeOut; + QMap m_propertyToKerning; + + QMap m_familyToProperty; + QMap m_pointSizeToProperty; + QMap m_boldToProperty; + QMap m_italicToProperty; + QMap m_underlineToProperty; + QMap m_strikeOutToProperty; + QMap m_kerningToProperty; + + bool m_settingValue; + QTimer *m_fontDatabaseChangeTimer; +}; + +QtFontPropertyManagerPrivate::QtFontPropertyManagerPrivate() : + m_settingValue(false), + m_fontDatabaseChangeTimer(0) +{ +} + +void QtFontPropertyManagerPrivate::slotIntChanged(QtProperty *property, int value) +{ + if (m_settingValue) + return; + if (QtProperty *prop = m_pointSizeToProperty.value(property, 0)) { + QFont f = m_values[prop]; + f.setPointSize(value); + q_ptr->setValue(prop, f); + } +} + +void QtFontPropertyManagerPrivate::slotEnumChanged(QtProperty *property, int value) +{ + if (m_settingValue) + return; + if (QtProperty *prop = m_familyToProperty.value(property, 0)) { + QFont f = m_values[prop]; + f.setFamily(m_familyNames.at(value)); + q_ptr->setValue(prop, f); + } +} + +void QtFontPropertyManagerPrivate::slotBoolChanged(QtProperty *property, bool value) +{ + if (m_settingValue) + return; + if (QtProperty *prop = m_boldToProperty.value(property, 0)) { + QFont f = m_values[prop]; + f.setBold(value); + q_ptr->setValue(prop, f); + } else if (QtProperty *prop = m_italicToProperty.value(property, 0)) { + QFont f = m_values[prop]; + f.setItalic(value); + q_ptr->setValue(prop, f); + } else if (QtProperty *prop = m_underlineToProperty.value(property, 0)) { + QFont f = m_values[prop]; + f.setUnderline(value); + q_ptr->setValue(prop, f); + } else if (QtProperty *prop = m_strikeOutToProperty.value(property, 0)) { + QFont f = m_values[prop]; + f.setStrikeOut(value); + q_ptr->setValue(prop, f); + } else if (QtProperty *prop = m_kerningToProperty.value(property, 0)) { + QFont f = m_values[prop]; + f.setKerning(value); + q_ptr->setValue(prop, f); + } +} + +void QtFontPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property) +{ + if (QtProperty *pointProp = m_pointSizeToProperty.value(property, 0)) { + m_propertyToPointSize[pointProp] = 0; + m_pointSizeToProperty.remove(property); + } else if (QtProperty *pointProp = m_familyToProperty.value(property, 0)) { + m_propertyToFamily[pointProp] = 0; + m_familyToProperty.remove(property); + } else if (QtProperty *pointProp = m_boldToProperty.value(property, 0)) { + m_propertyToBold[pointProp] = 0; + m_boldToProperty.remove(property); + } else if (QtProperty *pointProp = m_italicToProperty.value(property, 0)) { + m_propertyToItalic[pointProp] = 0; + m_italicToProperty.remove(property); + } else if (QtProperty *pointProp = m_underlineToProperty.value(property, 0)) { + m_propertyToUnderline[pointProp] = 0; + m_underlineToProperty.remove(property); + } else if (QtProperty *pointProp = m_strikeOutToProperty.value(property, 0)) { + m_propertyToStrikeOut[pointProp] = 0; + m_strikeOutToProperty.remove(property); + } else if (QtProperty *pointProp = m_kerningToProperty.value(property, 0)) { + m_propertyToKerning[pointProp] = 0; + m_kerningToProperty.remove(property); + } +} + +void QtFontPropertyManagerPrivate::slotFontDatabaseChanged() +{ + if (!m_fontDatabaseChangeTimer) { + m_fontDatabaseChangeTimer = new QTimer(q_ptr); + m_fontDatabaseChangeTimer->setInterval(0); + m_fontDatabaseChangeTimer->setSingleShot(true); + QObject::connect(m_fontDatabaseChangeTimer, SIGNAL(timeout()), q_ptr, SLOT(slotFontDatabaseDelayedChange())); + } + if (!m_fontDatabaseChangeTimer->isActive()) + m_fontDatabaseChangeTimer->start(); +} + +void QtFontPropertyManagerPrivate::slotFontDatabaseDelayedChange() +{ + typedef QMap PropertyPropertyMap; + // rescan available font names + const QStringList oldFamilies = m_familyNames; + m_familyNames = fontDatabase()->families(); + + // Adapt all existing properties + if (!m_propertyToFamily.empty()) { + PropertyPropertyMap::const_iterator cend = m_propertyToFamily.constEnd(); + for (PropertyPropertyMap::const_iterator it = m_propertyToFamily.constBegin(); it != cend; ++it) { + QtProperty *familyProp = it.value(); + const int oldIdx = m_enumPropertyManager->value(familyProp); + int newIdx = m_familyNames.indexOf(oldFamilies.at(oldIdx)); + if (newIdx < 0) + newIdx = 0; + m_enumPropertyManager->setEnumNames(familyProp, m_familyNames); + m_enumPropertyManager->setValue(familyProp, newIdx); + } + } +} + +/*! + \class QtFontPropertyManager + + \brief The QtFontPropertyManager provides and manages QFont properties. + + A font property has nested \e family, \e pointSize, \e bold, \e + italic, \e underline, \e strikeOut and \e kerning subproperties. The top-level + property's value can be retrieved using the value() function, and + set using the setValue() slot. + + The subproperties are created by QtIntPropertyManager, QtEnumPropertyManager and + QtBoolPropertyManager objects. These managers can be retrieved using the + corresponding subIntPropertyManager(), subEnumPropertyManager() and + subBoolPropertyManager() functions. In order to provide editing widgets + for the subproperties in a property browser widget, these managers + must be associated with editor factories. + + In addition, QtFontPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes. + + \sa QtAbstractPropertyManager, QtEnumPropertyManager, QtIntPropertyManager, QtBoolPropertyManager +*/ + +/*! + \fn void QtFontPropertyManager::valueChanged(QtProperty *property, const QFont &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. + + \sa setValue() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtFontPropertyManager::QtFontPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtFontPropertyManagerPrivate; + d_ptr->q_ptr = this; +#if QT_VERSION >= 0x040500 + QObject::connect(qApp, SIGNAL(fontDatabaseChanged()), this, SLOT(slotFontDatabaseChanged())); +#endif + + d_ptr->m_intPropertyManager = new QtIntPropertyManager(this); + connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotIntChanged(QtProperty *, int))); + d_ptr->m_enumPropertyManager = new QtEnumPropertyManager(this); + connect(d_ptr->m_enumPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotEnumChanged(QtProperty *, int))); + d_ptr->m_boolPropertyManager = new QtBoolPropertyManager(this); + connect(d_ptr->m_boolPropertyManager, SIGNAL(valueChanged(QtProperty *, bool)), + this, SLOT(slotBoolChanged(QtProperty *, bool))); + + connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); + connect(d_ptr->m_enumPropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); + connect(d_ptr->m_boolPropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtFontPropertyManager::~QtFontPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the manager that creates the \e pointSize subproperty. + + In order to provide editing widgets for the \e pointSize property + in a property browser widget, this manager must be associated + with an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtIntPropertyManager *QtFontPropertyManager::subIntPropertyManager() const +{ + return d_ptr->m_intPropertyManager; +} + +/*! + Returns the manager that create the \e family subproperty. + + In order to provide editing widgets for the \e family property + in a property browser widget, this manager must be associated + with an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtEnumPropertyManager *QtFontPropertyManager::subEnumPropertyManager() const +{ + return d_ptr->m_enumPropertyManager; +} + +/*! + Returns the manager that creates the \e bold, \e italic, \e underline, + \e strikeOut and \e kerning subproperties. + + In order to provide editing widgets for the mentioned properties + in a property browser widget, this manager must be associated with + an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtBoolPropertyManager *QtFontPropertyManager::subBoolPropertyManager() const +{ + return d_ptr->m_boolPropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given property is not managed by this manager, this + function returns a font object that uses the application's default + font. + + \sa setValue() +*/ +QFont QtFontPropertyManager::value(const QtProperty *property) const +{ + return d_ptr->m_values.value(property, QFont()); +} + +/*! + \reimp +*/ +QString QtFontPropertyManager::valueText(const QtProperty *property) const +{ + const QtFontPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + + return QtPropertyBrowserUtils::fontValueText(it.value()); +} + +/*! + \reimp +*/ +QIcon QtFontPropertyManager::valueIcon(const QtProperty *property) const +{ + const QtFontPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QIcon(); + + return QtPropertyBrowserUtils::fontValueIcon(it.value()); +} + +/*! + \fn void QtFontPropertyManager::setValue(QtProperty *property, const QFont &value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + \sa value(), valueChanged() +*/ +void QtFontPropertyManager::setValue(QtProperty *property, const QFont &val) +{ + const QtFontPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + const QFont oldVal = it.value(); + if (oldVal == val && oldVal.resolve() == val.resolve()) + return; + + it.value() = val; + + int idx = d_ptr->m_familyNames.indexOf(val.family()); + if (idx == -1) + idx = 0; + bool settingValue = d_ptr->m_settingValue; + d_ptr->m_settingValue = true; + d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToFamily[property], idx); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToPointSize[property], val.pointSize()); + d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToBold[property], val.bold()); + d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToItalic[property], val.italic()); + d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToUnderline[property], val.underline()); + d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToStrikeOut[property], val.strikeOut()); + d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToKerning[property], val.kerning()); + d_ptr->m_settingValue = settingValue; + + emit propertyChanged(property); + emit valueChanged(property, val); +} + +/*! + \reimp +*/ +void QtFontPropertyManager::initializeProperty(QtProperty *property) +{ + QFont val; + d_ptr->m_values[property] = val; + + QtProperty *familyProp = d_ptr->m_enumPropertyManager->addProperty(); + familyProp->setPropertyName(tr("Family")); + if (d_ptr->m_familyNames.empty()) + d_ptr->m_familyNames = fontDatabase()->families(); + d_ptr->m_enumPropertyManager->setEnumNames(familyProp, d_ptr->m_familyNames); + int idx = d_ptr->m_familyNames.indexOf(val.family()); + if (idx == -1) + idx = 0; + d_ptr->m_enumPropertyManager->setValue(familyProp, idx); + d_ptr->m_propertyToFamily[property] = familyProp; + d_ptr->m_familyToProperty[familyProp] = property; + property->addSubProperty(familyProp); + + QtProperty *pointSizeProp = d_ptr->m_intPropertyManager->addProperty(); + pointSizeProp->setPropertyName(tr("Point Size")); + d_ptr->m_intPropertyManager->setValue(pointSizeProp, val.pointSize()); + d_ptr->m_intPropertyManager->setMinimum(pointSizeProp, 1); + d_ptr->m_propertyToPointSize[property] = pointSizeProp; + d_ptr->m_pointSizeToProperty[pointSizeProp] = property; + property->addSubProperty(pointSizeProp); + + QtProperty *boldProp = d_ptr->m_boolPropertyManager->addProperty(); + boldProp->setPropertyName(tr("Bold")); + d_ptr->m_boolPropertyManager->setValue(boldProp, val.bold()); + d_ptr->m_propertyToBold[property] = boldProp; + d_ptr->m_boldToProperty[boldProp] = property; + property->addSubProperty(boldProp); + + QtProperty *italicProp = d_ptr->m_boolPropertyManager->addProperty(); + italicProp->setPropertyName(tr("Italic")); + d_ptr->m_boolPropertyManager->setValue(italicProp, val.italic()); + d_ptr->m_propertyToItalic[property] = italicProp; + d_ptr->m_italicToProperty[italicProp] = property; + property->addSubProperty(italicProp); + + QtProperty *underlineProp = d_ptr->m_boolPropertyManager->addProperty(); + underlineProp->setPropertyName(tr("Underline")); + d_ptr->m_boolPropertyManager->setValue(underlineProp, val.underline()); + d_ptr->m_propertyToUnderline[property] = underlineProp; + d_ptr->m_underlineToProperty[underlineProp] = property; + property->addSubProperty(underlineProp); + + QtProperty *strikeOutProp = d_ptr->m_boolPropertyManager->addProperty(); + strikeOutProp->setPropertyName(tr("Strikeout")); + d_ptr->m_boolPropertyManager->setValue(strikeOutProp, val.strikeOut()); + d_ptr->m_propertyToStrikeOut[property] = strikeOutProp; + d_ptr->m_strikeOutToProperty[strikeOutProp] = property; + property->addSubProperty(strikeOutProp); + + QtProperty *kerningProp = d_ptr->m_boolPropertyManager->addProperty(); + kerningProp->setPropertyName(tr("Kerning")); + d_ptr->m_boolPropertyManager->setValue(kerningProp, val.kerning()); + d_ptr->m_propertyToKerning[property] = kerningProp; + d_ptr->m_kerningToProperty[kerningProp] = property; + property->addSubProperty(kerningProp); +} + +/*! + \reimp +*/ +void QtFontPropertyManager::uninitializeProperty(QtProperty *property) +{ + QtProperty *familyProp = d_ptr->m_propertyToFamily[property]; + if (familyProp) { + d_ptr->m_familyToProperty.remove(familyProp); + delete familyProp; + } + d_ptr->m_propertyToFamily.remove(property); + + QtProperty *pointSizeProp = d_ptr->m_propertyToPointSize[property]; + if (pointSizeProp) { + d_ptr->m_pointSizeToProperty.remove(pointSizeProp); + delete pointSizeProp; + } + d_ptr->m_propertyToPointSize.remove(property); + + QtProperty *boldProp = d_ptr->m_propertyToBold[property]; + if (boldProp) { + d_ptr->m_boldToProperty.remove(boldProp); + delete boldProp; + } + d_ptr->m_propertyToBold.remove(property); + + QtProperty *italicProp = d_ptr->m_propertyToItalic[property]; + if (italicProp) { + d_ptr->m_italicToProperty.remove(italicProp); + delete italicProp; + } + d_ptr->m_propertyToItalic.remove(property); + + QtProperty *underlineProp = d_ptr->m_propertyToUnderline[property]; + if (underlineProp) { + d_ptr->m_underlineToProperty.remove(underlineProp); + delete underlineProp; + } + d_ptr->m_propertyToUnderline.remove(property); + + QtProperty *strikeOutProp = d_ptr->m_propertyToStrikeOut[property]; + if (strikeOutProp) { + d_ptr->m_strikeOutToProperty.remove(strikeOutProp); + delete strikeOutProp; + } + d_ptr->m_propertyToStrikeOut.remove(property); + + QtProperty *kerningProp = d_ptr->m_propertyToKerning[property]; + if (kerningProp) { + d_ptr->m_kerningToProperty.remove(kerningProp); + delete kerningProp; + } + d_ptr->m_propertyToKerning.remove(property); + + d_ptr->m_values.remove(property); +} + +// QtColorPropertyManager + +class QtColorPropertyManagerPrivate +{ + QtColorPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtColorPropertyManager) +public: + + void slotIntChanged(QtProperty *property, int value); + void slotPropertyDestroyed(QtProperty *property); + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtIntPropertyManager *m_intPropertyManager; + + QMap m_propertyToR; + QMap m_propertyToG; + QMap m_propertyToB; + QMap m_propertyToA; + + QMap m_rToProperty; + QMap m_gToProperty; + QMap m_bToProperty; + QMap m_aToProperty; +}; + +void QtColorPropertyManagerPrivate::slotIntChanged(QtProperty *property, int value) +{ + if (QtProperty *prop = m_rToProperty.value(property, 0)) { + QColor c = m_values[prop]; + c.setRed(value); + q_ptr->setValue(prop, c); + } else if (QtProperty *prop = m_gToProperty.value(property, 0)) { + QColor c = m_values[prop]; + c.setGreen(value); + q_ptr->setValue(prop, c); + } else if (QtProperty *prop = m_bToProperty.value(property, 0)) { + QColor c = m_values[prop]; + c.setBlue(value); + q_ptr->setValue(prop, c); + } else if (QtProperty *prop = m_aToProperty.value(property, 0)) { + QColor c = m_values[prop]; + c.setAlpha(value); + q_ptr->setValue(prop, c); + } +} + +void QtColorPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property) +{ + if (QtProperty *pointProp = m_rToProperty.value(property, 0)) { + m_propertyToR[pointProp] = 0; + m_rToProperty.remove(property); + } else if (QtProperty *pointProp = m_gToProperty.value(property, 0)) { + m_propertyToG[pointProp] = 0; + m_gToProperty.remove(property); + } else if (QtProperty *pointProp = m_bToProperty.value(property, 0)) { + m_propertyToB[pointProp] = 0; + m_bToProperty.remove(property); + } else if (QtProperty *pointProp = m_aToProperty.value(property, 0)) { + m_propertyToA[pointProp] = 0; + m_aToProperty.remove(property); + } +} + +/*! + \class QtColorPropertyManager + + \brief The QtColorPropertyManager provides and manages QColor properties. + + A color property has nested \e red, \e green and \e blue + subproperties. The top-level property's value can be retrieved + using the value() function, and set using the setValue() slot. + + The subproperties are created by a QtIntPropertyManager object. This + manager can be retrieved using the subIntPropertyManager() function. In + order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + In addition, QtColorPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes. + + \sa QtAbstractPropertyManager, QtAbstractPropertyBrowser, QtIntPropertyManager +*/ + +/*! + \fn void QtColorPropertyManager::valueChanged(QtProperty *property, const QColor &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtColorPropertyManager::QtColorPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtColorPropertyManagerPrivate; + d_ptr->q_ptr = this; + + d_ptr->m_intPropertyManager = new QtIntPropertyManager(this); + connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotIntChanged(QtProperty *, int))); + + connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty *)), + this, SLOT(slotPropertyDestroyed(QtProperty *))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtColorPropertyManager::~QtColorPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the manager that produces the nested \e red, \e green and + \e blue subproperties. + + In order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtIntPropertyManager *QtColorPropertyManager::subIntPropertyManager() const +{ + return d_ptr->m_intPropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by \e this manager, this + function returns an invalid color. + + \sa setValue() +*/ +QColor QtColorPropertyManager::value(const QtProperty *property) const +{ + return d_ptr->m_values.value(property, QColor()); +} + +/*! + \reimp +*/ + +QString QtColorPropertyManager::valueText(const QtProperty *property) const +{ + const QtColorPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + + return QtPropertyBrowserUtils::colorValueText(it.value()); +} + +/*! + \reimp +*/ + +QIcon QtColorPropertyManager::valueIcon(const QtProperty *property) const +{ + const QtColorPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QIcon(); + return QtPropertyBrowserUtils::brushValueIcon(QBrush(it.value())); +} + +/*! + \fn void QtColorPropertyManager::setValue(QtProperty *property, const QColor &value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + \sa value(), valueChanged() +*/ +void QtColorPropertyManager::setValue(QtProperty *property, const QColor &val) +{ + const QtColorPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + if (it.value() == val) + return; + + it.value() = val; + + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToR[property], val.red()); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToG[property], val.green()); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToB[property], val.blue()); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToA[property], val.alpha()); + + emit propertyChanged(property); + emit valueChanged(property, val); +} + +/*! + \reimp +*/ +void QtColorPropertyManager::initializeProperty(QtProperty *property) +{ + QColor val; + d_ptr->m_values[property] = val; + + QtProperty *rProp = d_ptr->m_intPropertyManager->addProperty(); + rProp->setPropertyName(tr("Red")); + d_ptr->m_intPropertyManager->setValue(rProp, val.red()); + d_ptr->m_intPropertyManager->setRange(rProp, 0, 0xFF); + d_ptr->m_propertyToR[property] = rProp; + d_ptr->m_rToProperty[rProp] = property; + property->addSubProperty(rProp); + + QtProperty *gProp = d_ptr->m_intPropertyManager->addProperty(); + gProp->setPropertyName(tr("Green")); + d_ptr->m_intPropertyManager->setValue(gProp, val.green()); + d_ptr->m_intPropertyManager->setRange(gProp, 0, 0xFF); + d_ptr->m_propertyToG[property] = gProp; + d_ptr->m_gToProperty[gProp] = property; + property->addSubProperty(gProp); + + QtProperty *bProp = d_ptr->m_intPropertyManager->addProperty(); + bProp->setPropertyName(tr("Blue")); + d_ptr->m_intPropertyManager->setValue(bProp, val.blue()); + d_ptr->m_intPropertyManager->setRange(bProp, 0, 0xFF); + d_ptr->m_propertyToB[property] = bProp; + d_ptr->m_bToProperty[bProp] = property; + property->addSubProperty(bProp); + + QtProperty *aProp = d_ptr->m_intPropertyManager->addProperty(); + aProp->setPropertyName(tr("Alpha")); + d_ptr->m_intPropertyManager->setValue(aProp, val.alpha()); + d_ptr->m_intPropertyManager->setRange(aProp, 0, 0xFF); + d_ptr->m_propertyToA[property] = aProp; + d_ptr->m_aToProperty[aProp] = property; + property->addSubProperty(aProp); +} + +/*! + \reimp +*/ +void QtColorPropertyManager::uninitializeProperty(QtProperty *property) +{ + QtProperty *rProp = d_ptr->m_propertyToR[property]; + if (rProp) { + d_ptr->m_rToProperty.remove(rProp); + delete rProp; + } + d_ptr->m_propertyToR.remove(property); + + QtProperty *gProp = d_ptr->m_propertyToG[property]; + if (gProp) { + d_ptr->m_gToProperty.remove(gProp); + delete gProp; + } + d_ptr->m_propertyToG.remove(property); + + QtProperty *bProp = d_ptr->m_propertyToB[property]; + if (bProp) { + d_ptr->m_bToProperty.remove(bProp); + delete bProp; + } + d_ptr->m_propertyToB.remove(property); + + QtProperty *aProp = d_ptr->m_propertyToA[property]; + if (aProp) { + d_ptr->m_aToProperty.remove(aProp); + delete aProp; + } + d_ptr->m_propertyToA.remove(property); + + d_ptr->m_values.remove(property); +} + +// QtCursorPropertyManager + +Q_GLOBAL_STATIC(QtCursorDatabase, cursorDatabase) + +class QtCursorPropertyManagerPrivate +{ + QtCursorPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtCursorPropertyManager) +public: + typedef QMap PropertyValueMap; + PropertyValueMap m_values; +}; + +/*! + \class QtCursorPropertyManager + + \brief The QtCursorPropertyManager provides and manages QCursor properties. + + A cursor property has a current value which can be + retrieved using the value() function, and set using the setValue() + slot. In addition, QtCursorPropertyManager provides the + valueChanged() signal which is emitted whenever a property created + by this manager changes. + + \sa QtAbstractPropertyManager +*/ + +/*! + \fn void QtCursorPropertyManager::valueChanged(QtProperty *property, const QCursor &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtCursorPropertyManager::QtCursorPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtCursorPropertyManagerPrivate; + d_ptr->q_ptr = this; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtCursorPropertyManager::~QtCursorPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns a default QCursor object. + + \sa setValue() +*/ +#ifndef QT_NO_CURSOR +QCursor QtCursorPropertyManager::value(const QtProperty *property) const +{ + return d_ptr->m_values.value(property, QCursor()); +} +#endif + +/*! + \reimp +*/ +QString QtCursorPropertyManager::valueText(const QtProperty *property) const +{ + const QtCursorPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + + return cursorDatabase()->cursorToShapeName(it.value()); +} + +/*! + \reimp +*/ +QIcon QtCursorPropertyManager::valueIcon(const QtProperty *property) const +{ + const QtCursorPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QIcon(); + + return cursorDatabase()->cursorToShapeIcon(it.value()); +} + +/*! + \fn void QtCursorPropertyManager::setValue(QtProperty *property, const QCursor &value) + + Sets the value of the given \a property to \a value. + + \sa value(), valueChanged() +*/ +void QtCursorPropertyManager::setValue(QtProperty *property, const QCursor &value) +{ +#ifndef QT_NO_CURSOR + const QtCursorPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + if (it.value().shape() == value.shape() && value.shape() != Qt::BitmapCursor) + return; + + it.value() = value; + + emit propertyChanged(property); + emit valueChanged(property, value); +#endif +} + +/*! + \reimp +*/ +void QtCursorPropertyManager::initializeProperty(QtProperty *property) +{ +#ifndef QT_NO_CURSOR + d_ptr->m_values[property] = QCursor(); +#endif +} + +/*! + \reimp +*/ +void QtCursorPropertyManager::uninitializeProperty(QtProperty *property) +{ + d_ptr->m_values.remove(property); +} + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +#include "moc_qtpropertymanager.cxx" +#include "qtpropertymanager.moc" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.h b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.h new file mode 100644 index 000000000..709f2abf7 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.h @@ -0,0 +1,796 @@ +/**************************************************************************** +** +** This file is part of a Qt Solutions component. +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTPROPERTYMANAGER_H +#define QTPROPERTYMANAGER_H + +#include "qtpropertybrowser.h" + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +class QDate; +class QTime; +class QDateTime; +class QLocale; + +class QT_QTPROPERTYBROWSER_EXPORT QtGroupPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtGroupPropertyManager(QObject *parent = 0); + ~QtGroupPropertyManager(); + +protected: + virtual bool hasValue(const QtProperty *property) const; + + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +}; + +class QtIntPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtIntPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtIntPropertyManager(QObject *parent = 0); + ~QtIntPropertyManager(); + + int value(const QtProperty *property) const; + int minimum(const QtProperty *property) const; + int maximum(const QtProperty *property) const; + int singleStep(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, int val); + void setMinimum(QtProperty *property, int minVal); + void setMaximum(QtProperty *property, int maxVal); + void setRange(QtProperty *property, int minVal, int maxVal); + void setSingleStep(QtProperty *property, int step); +Q_SIGNALS: + void valueChanged(QtProperty *property, int val); + void rangeChanged(QtProperty *property, int minVal, int maxVal); + void singleStepChanged(QtProperty *property, int step); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtIntPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtIntPropertyManager) + Q_DISABLE_COPY(QtIntPropertyManager) +}; + +class QtBoolPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtBoolPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtBoolPropertyManager(QObject *parent = 0); + ~QtBoolPropertyManager(); + + bool value(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, bool val); +Q_SIGNALS: + void valueChanged(QtProperty *property, bool val); +protected: + QString valueText(const QtProperty *property) const; + QIcon valueIcon(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtBoolPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtBoolPropertyManager) + Q_DISABLE_COPY(QtBoolPropertyManager) +}; + +class QtDoublePropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtDoublePropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtDoublePropertyManager(QObject *parent = 0); + ~QtDoublePropertyManager(); + + double value(const QtProperty *property) const; + double minimum(const QtProperty *property) const; + double maximum(const QtProperty *property) const; + double singleStep(const QtProperty *property) const; + int decimals(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, double val); + void setMinimum(QtProperty *property, double minVal); + void setMaximum(QtProperty *property, double maxVal); + void setRange(QtProperty *property, double minVal, double maxVal); + void setSingleStep(QtProperty *property, double step); + void setDecimals(QtProperty *property, int prec); +Q_SIGNALS: + void valueChanged(QtProperty *property, double val); + void rangeChanged(QtProperty *property, double minVal, double maxVal); + void singleStepChanged(QtProperty *property, double step); + void decimalsChanged(QtProperty *property, int prec); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtDoublePropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtDoublePropertyManager) + Q_DISABLE_COPY(QtDoublePropertyManager) +}; + +class QtStringPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtStringPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtStringPropertyManager(QObject *parent = 0); + ~QtStringPropertyManager(); + + QString value(const QtProperty *property) const; + QRegExp regExp(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QString &val); + void setRegExp(QtProperty *property, const QRegExp ®Exp); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QString &val); + void regExpChanged(QtProperty *property, const QRegExp ®Exp); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtStringPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtStringPropertyManager) + Q_DISABLE_COPY(QtStringPropertyManager) +}; + +class QtDatePropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtDatePropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtDatePropertyManager(QObject *parent = 0); + ~QtDatePropertyManager(); + + QDate value(const QtProperty *property) const; + QDate minimum(const QtProperty *property) const; + QDate maximum(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QDate &val); + void setMinimum(QtProperty *property, const QDate &minVal); + void setMaximum(QtProperty *property, const QDate &maxVal); + void setRange(QtProperty *property, const QDate &minVal, const QDate &maxVal); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QDate &val); + void rangeChanged(QtProperty *property, const QDate &minVal, const QDate &maxVal); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtDatePropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtDatePropertyManager) + Q_DISABLE_COPY(QtDatePropertyManager) +}; + +class QtTimePropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtTimePropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtTimePropertyManager(QObject *parent = 0); + ~QtTimePropertyManager(); + + QTime value(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QTime &val); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QTime &val); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtTimePropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtTimePropertyManager) + Q_DISABLE_COPY(QtTimePropertyManager) +}; + +class QtDateTimePropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtDateTimePropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtDateTimePropertyManager(QObject *parent = 0); + ~QtDateTimePropertyManager(); + + QDateTime value(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QDateTime &val); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QDateTime &val); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtDateTimePropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtDateTimePropertyManager) + Q_DISABLE_COPY(QtDateTimePropertyManager) +}; + +class QtKeySequencePropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtKeySequencePropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtKeySequencePropertyManager(QObject *parent = 0); + ~QtKeySequencePropertyManager(); + + QKeySequence value(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QKeySequence &val); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QKeySequence &val); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtKeySequencePropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtKeySequencePropertyManager) + Q_DISABLE_COPY(QtKeySequencePropertyManager) +}; + +class QtCharPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtCharPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtCharPropertyManager(QObject *parent = 0); + ~QtCharPropertyManager(); + + QChar value(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QChar &val); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QChar &val); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtCharPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtCharPropertyManager) + Q_DISABLE_COPY(QtCharPropertyManager) +}; + +class QtEnumPropertyManager; +class QtLocalePropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtLocalePropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtLocalePropertyManager(QObject *parent = 0); + ~QtLocalePropertyManager(); + + QtEnumPropertyManager *subEnumPropertyManager() const; + + QLocale value(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QLocale &val); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QLocale &val); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtLocalePropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtLocalePropertyManager) + Q_DISABLE_COPY(QtLocalePropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotEnumChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) +}; + +class QtPointPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtPointPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtPointPropertyManager(QObject *parent = 0); + ~QtPointPropertyManager(); + + QtIntPropertyManager *subIntPropertyManager() const; + + QPoint value(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QPoint &val); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QPoint &val); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtPointPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtPointPropertyManager) + Q_DISABLE_COPY(QtPointPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) +}; + +class QtPointFPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtPointFPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtPointFPropertyManager(QObject *parent = 0); + ~QtPointFPropertyManager(); + + QtDoublePropertyManager *subDoublePropertyManager() const; + + QPointF value(const QtProperty *property) const; + int decimals(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QPointF &val); + void setDecimals(QtProperty *property, int prec); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QPointF &val); + void decimalsChanged(QtProperty *property, int prec); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtPointFPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtPointFPropertyManager) + Q_DISABLE_COPY(QtPointFPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotDoubleChanged(QtProperty *, double)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) +}; + +class QtSizePropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtSizePropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtSizePropertyManager(QObject *parent = 0); + ~QtSizePropertyManager(); + + QtIntPropertyManager *subIntPropertyManager() const; + + QSize value(const QtProperty *property) const; + QSize minimum(const QtProperty *property) const; + QSize maximum(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QSize &val); + void setMinimum(QtProperty *property, const QSize &minVal); + void setMaximum(QtProperty *property, const QSize &maxVal); + void setRange(QtProperty *property, const QSize &minVal, const QSize &maxVal); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QSize &val); + void rangeChanged(QtProperty *property, const QSize &minVal, const QSize &maxVal); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtSizePropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtSizePropertyManager) + Q_DISABLE_COPY(QtSizePropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) +}; + +class QtSizeFPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtSizeFPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtSizeFPropertyManager(QObject *parent = 0); + ~QtSizeFPropertyManager(); + + QtDoublePropertyManager *subDoublePropertyManager() const; + + QSizeF value(const QtProperty *property) const; + QSizeF minimum(const QtProperty *property) const; + QSizeF maximum(const QtProperty *property) const; + int decimals(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QSizeF &val); + void setMinimum(QtProperty *property, const QSizeF &minVal); + void setMaximum(QtProperty *property, const QSizeF &maxVal); + void setRange(QtProperty *property, const QSizeF &minVal, const QSizeF &maxVal); + void setDecimals(QtProperty *property, int prec); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QSizeF &val); + void rangeChanged(QtProperty *property, const QSizeF &minVal, const QSizeF &maxVal); + void decimalsChanged(QtProperty *property, int prec); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtSizeFPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtSizeFPropertyManager) + Q_DISABLE_COPY(QtSizeFPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotDoubleChanged(QtProperty *, double)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) +}; + +class QtRectPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtRectPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtRectPropertyManager(QObject *parent = 0); + ~QtRectPropertyManager(); + + QtIntPropertyManager *subIntPropertyManager() const; + + QRect value(const QtProperty *property) const; + QRect constraint(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QRect &val); + void setConstraint(QtProperty *property, const QRect &constraint); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QRect &val); + void constraintChanged(QtProperty *property, const QRect &constraint); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtRectPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtRectPropertyManager) + Q_DISABLE_COPY(QtRectPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) +}; + +class QtRectFPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtRectFPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtRectFPropertyManager(QObject *parent = 0); + ~QtRectFPropertyManager(); + + QtDoublePropertyManager *subDoublePropertyManager() const; + + QRectF value(const QtProperty *property) const; + QRectF constraint(const QtProperty *property) const; + int decimals(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QRectF &val); + void setConstraint(QtProperty *property, const QRectF &constraint); + void setDecimals(QtProperty *property, int prec); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QRectF &val); + void constraintChanged(QtProperty *property, const QRectF &constraint); + void decimalsChanged(QtProperty *property, int prec); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtRectFPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtRectFPropertyManager) + Q_DISABLE_COPY(QtRectFPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotDoubleChanged(QtProperty *, double)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) +}; + +class QtEnumPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtEnumPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtEnumPropertyManager(QObject *parent = 0); + ~QtEnumPropertyManager(); + + int value(const QtProperty *property) const; + QStringList enumNames(const QtProperty *property) const; + QMap enumIcons(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, int val); + void setEnumNames(QtProperty *property, const QStringList &names); + void setEnumIcons(QtProperty *property, const QMap &icons); +Q_SIGNALS: + void valueChanged(QtProperty *property, int val); + void enumNamesChanged(QtProperty *property, const QStringList &names); + void enumIconsChanged(QtProperty *property, const QMap &icons); +protected: + QString valueText(const QtProperty *property) const; + QIcon valueIcon(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtEnumPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtEnumPropertyManager) + Q_DISABLE_COPY(QtEnumPropertyManager) +}; + +class QtFlagPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtFlagPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtFlagPropertyManager(QObject *parent = 0); + ~QtFlagPropertyManager(); + + QtBoolPropertyManager *subBoolPropertyManager() const; + + int value(const QtProperty *property) const; + QStringList flagNames(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, int val); + void setFlagNames(QtProperty *property, const QStringList &names); +Q_SIGNALS: + void valueChanged(QtProperty *property, int val); + void flagNamesChanged(QtProperty *property, const QStringList &names); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtFlagPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtFlagPropertyManager) + Q_DISABLE_COPY(QtFlagPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotBoolChanged(QtProperty *, bool)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) +}; + +class QtSizePolicyPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtSizePolicyPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtSizePolicyPropertyManager(QObject *parent = 0); + ~QtSizePolicyPropertyManager(); + + QtIntPropertyManager *subIntPropertyManager() const; + QtEnumPropertyManager *subEnumPropertyManager() const; + + QSizePolicy value(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QSizePolicy &val); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QSizePolicy &val); +protected: + QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtSizePolicyPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtSizePolicyPropertyManager) + Q_DISABLE_COPY(QtSizePolicyPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotEnumChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) +}; + +class QtFontPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtFontPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtFontPropertyManager(QObject *parent = 0); + ~QtFontPropertyManager(); + + QtIntPropertyManager *subIntPropertyManager() const; + QtEnumPropertyManager *subEnumPropertyManager() const; + QtBoolPropertyManager *subBoolPropertyManager() const; + + QFont value(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QFont &val); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QFont &val); +protected: + QString valueText(const QtProperty *property) const; + QIcon valueIcon(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtFontPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtFontPropertyManager) + Q_DISABLE_COPY(QtFontPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotEnumChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotBoolChanged(QtProperty *, bool)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) + Q_PRIVATE_SLOT(d_func(), void slotFontDatabaseChanged()) + Q_PRIVATE_SLOT(d_func(), void slotFontDatabaseDelayedChange()) +}; + +class QtColorPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtColorPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtColorPropertyManager(QObject *parent = 0); + ~QtColorPropertyManager(); + + QtIntPropertyManager *subIntPropertyManager() const; + + QColor value(const QtProperty *property) const; + +public Q_SLOTS: + void setValue(QtProperty *property, const QColor &val); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QColor &val); +protected: + QString valueText(const QtProperty *property) const; + QIcon valueIcon(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtColorPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtColorPropertyManager) + Q_DISABLE_COPY(QtColorPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) +}; + +class QtCursorPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtCursorPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtCursorPropertyManager(QObject *parent = 0); + ~QtCursorPropertyManager(); + +#ifndef QT_NO_CURSOR + QCursor value(const QtProperty *property) const; +#endif + +public Q_SLOTS: + void setValue(QtProperty *property, const QCursor &val); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QCursor &val); +protected: + QString valueText(const QtProperty *property) const; + QIcon valueIcon(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); +private: + QtCursorPropertyManagerPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtCursorPropertyManager) + Q_DISABLE_COPY(QtCursorPropertyManager) +}; + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +#endif diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qttreepropertybrowser.cpp b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qttreepropertybrowser.cpp new file mode 100644 index 000000000..eb9b37515 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qttreepropertybrowser.cpp @@ -0,0 +1,1095 @@ +/**************************************************************************** +** +** This file is part of a Qt Solutions component. +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qttreepropertybrowser.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +class QtPropertyEditorView; + +class QtTreePropertyBrowserPrivate +{ + QtTreePropertyBrowser *q_ptr; + Q_DECLARE_PUBLIC(QtTreePropertyBrowser) + +public: + QtTreePropertyBrowserPrivate(); + void init(QWidget *parent); + + void propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex); + void propertyRemoved(QtBrowserItem *index); + void propertyChanged(QtBrowserItem *index); + QWidget *createEditor(QtProperty *property, QWidget *parent) const + { return q_ptr->createEditor(property, parent); } + QtProperty *indexToProperty(const QModelIndex &index) const; + QTreeWidgetItem *indexToItem(const QModelIndex &index) const; + QtBrowserItem *indexToBrowserItem(const QModelIndex &index) const; + bool lastColumn(int column) const; + void disableItem(QTreeWidgetItem *item) const; + void enableItem(QTreeWidgetItem *item) const; + bool hasValue(QTreeWidgetItem *item) const; + + void slotCollapsed(const QModelIndex &index); + void slotExpanded(const QModelIndex &index); + + QColor calculatedBackgroundColor(QtBrowserItem *item) const; + + QtPropertyEditorView *treeWidget() const { return m_treeWidget; } + bool markPropertiesWithoutValue() const { return m_markPropertiesWithoutValue; } + + QtBrowserItem *currentItem() const; + void setCurrentItem(QtBrowserItem *browserItem, bool block); + void editItem(QtBrowserItem *browserItem); + + void slotCurrentBrowserItemChanged(QtBrowserItem *item); + void slotCurrentTreeItemChanged(QTreeWidgetItem *newItem, QTreeWidgetItem *); + + QTreeWidgetItem *editedItem() const; + +private: + void updateItem(QTreeWidgetItem *item); + + QMap m_indexToItem; + QMap m_itemToIndex; + + QMap m_indexToBackgroundColor; + + QtPropertyEditorView *m_treeWidget; + + bool m_headerVisible; + QtTreePropertyBrowser::ResizeMode m_resizeMode; + class QtPropertyEditorDelegate *m_delegate; + bool m_markPropertiesWithoutValue; + bool m_browserChangedBlocked; + QIcon m_expandIcon; +}; + +// ------------ QtPropertyEditorView +class QtPropertyEditorView : public QTreeWidget +{ + Q_OBJECT +public: + QtPropertyEditorView(QWidget *parent = 0); + + void setEditorPrivate(QtTreePropertyBrowserPrivate *editorPrivate) + { m_editorPrivate = editorPrivate; } + + QTreeWidgetItem *indexToItem(const QModelIndex &index) const + { return itemFromIndex(index); } + +protected: + void keyPressEvent(QKeyEvent *event); + void mousePressEvent(QMouseEvent *event); + void drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + +private: + QtTreePropertyBrowserPrivate *m_editorPrivate; +}; + +QtPropertyEditorView::QtPropertyEditorView(QWidget *parent) : + QTreeWidget(parent), + m_editorPrivate(0) +{ + connect(header(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(resizeColumnToContents(int))); +} + +void QtPropertyEditorView::drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QStyleOptionViewItemV3 opt = option; + bool hasValue = true; + if (m_editorPrivate) { + QtProperty *property = m_editorPrivate->indexToProperty(index); + if (property) + { + hasValue = property->hasValue(); + opt.font.setBold(property->isBold()); + } + } + if (!hasValue && m_editorPrivate->markPropertiesWithoutValue()) { + const QColor c = option.palette.color(QPalette::Dark); + painter->fillRect(option.rect, c); + opt.palette.setColor(QPalette::AlternateBase, c); + } else { + const QColor c = m_editorPrivate->calculatedBackgroundColor(m_editorPrivate->indexToBrowserItem(index)); + if (c.isValid()) { + painter->fillRect(option.rect, c); + opt.palette.setColor(QPalette::AlternateBase, c.lighter(112)); + } + } + + QTreeWidget::drawRow(painter, opt, index); + QColor color = static_cast(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor, &opt)); + painter->save(); + painter->setPen(QPen(color)); + painter->drawLine(opt.rect.x(), opt.rect.bottom(), opt.rect.right(), opt.rect.bottom()); + painter->restore(); +} + +void QtPropertyEditorView::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Return: + case Qt::Key_Enter: + case Qt::Key_Space: // Trigger Edit + if (!m_editorPrivate->editedItem()) + if (const QTreeWidgetItem *item = currentItem()) + if (item->columnCount() >= 2 && ((item->flags() & (Qt::ItemIsEditable | Qt::ItemIsEnabled)) == (Qt::ItemIsEditable | Qt::ItemIsEnabled))) { + event->accept(); + // If the current position is at column 0, move to 1. + QModelIndex index = currentIndex(); + if (index.column() == 0) { + index = index.sibling(index.row(), 1); + setCurrentIndex(index); + } + edit(index); + return; + } + break; + default: + break; + } + QTreeWidget::keyPressEvent(event); +} + +void QtPropertyEditorView::mousePressEvent(QMouseEvent *event) +{ + QTreeWidget::mousePressEvent(event); + QTreeWidgetItem *item = itemAt(event->pos()); + + if (item) { + if ((item != m_editorPrivate->editedItem()) && (event->button() == Qt::LeftButton) + && (header()->logicalIndexAt(event->pos().x()) == 1) + && ((item->flags() & (Qt::ItemIsEditable | Qt::ItemIsEnabled)) == (Qt::ItemIsEditable | Qt::ItemIsEnabled))) { + editItem(item, 1); + } else if (!m_editorPrivate->hasValue(item) && m_editorPrivate->markPropertiesWithoutValue() && !rootIsDecorated()) { + if (event->pos().x() + header()->offset() < 20) + item->setExpanded(!item->isExpanded()); + } + } +} + +// ------------ QtPropertyEditorDelegate +class QtPropertyEditorDelegate : public QItemDelegate +{ + Q_OBJECT +public: + QtPropertyEditorDelegate(QObject *parent = 0) + : QItemDelegate(parent), m_editorPrivate(0), m_editedItem(0), m_editedWidget(0) + {} + + void setEditorPrivate(QtTreePropertyBrowserPrivate *editorPrivate) + { m_editorPrivate = editorPrivate; } + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; + + void setModelData(QWidget *, QAbstractItemModel *, + const QModelIndex &) const {} + + void setEditorData(QWidget *, const QModelIndex &) const {} + + bool eventFilter(QObject *object, QEvent *event); + void closeEditor(QtProperty *property); + + QTreeWidgetItem *editedItem() const { return m_editedItem; } + +private slots: + void slotEditorDestroyed(QObject *object); + +private: + int indentation(const QModelIndex &index) const; + + typedef QMap EditorToPropertyMap; + mutable EditorToPropertyMap m_editorToProperty; + + typedef QMap PropertyToEditorMap; + mutable PropertyToEditorMap m_propertyToEditor; + QtTreePropertyBrowserPrivate *m_editorPrivate; + mutable QTreeWidgetItem *m_editedItem; + mutable QWidget *m_editedWidget; +}; + +int QtPropertyEditorDelegate::indentation(const QModelIndex &index) const +{ + if (!m_editorPrivate) + return 0; + + QTreeWidgetItem *item = m_editorPrivate->indexToItem(index); + int indent = 0; + while (item->parent()) { + item = item->parent(); + ++indent; + } + if (m_editorPrivate->treeWidget()->rootIsDecorated()) + ++indent; + return indent * m_editorPrivate->treeWidget()->indentation(); +} + +void QtPropertyEditorDelegate::slotEditorDestroyed(QObject *object) +{ + if (QWidget *w = qobject_cast(object)) { + const EditorToPropertyMap::iterator it = m_editorToProperty.find(w); + if (it != m_editorToProperty.end()) { + m_propertyToEditor.remove(it.value()); + m_editorToProperty.erase(it); + } + if (m_editedWidget == w) { + m_editedWidget = 0; + m_editedItem = 0; + } + } +} + +void QtPropertyEditorDelegate::closeEditor(QtProperty *property) +{ + if (QWidget *w = m_propertyToEditor.value(property, 0)) + w->deleteLater(); +} + +QWidget *QtPropertyEditorDelegate::createEditor(QWidget *parent, + const QStyleOptionViewItem &, const QModelIndex &index) const +{ + if (index.column() == 1 && m_editorPrivate) { + QtProperty *property = m_editorPrivate->indexToProperty(index); + QTreeWidgetItem *item = m_editorPrivate->indexToItem(index); + if (property && item && (item->flags() & Qt::ItemIsEnabled)) { + QWidget *editor = m_editorPrivate->createEditor(property, parent); + if (editor) { + editor->setAutoFillBackground(true); + editor->installEventFilter(const_cast(this)); + connect(editor, SIGNAL(destroyed(QObject *)), this, SLOT(slotEditorDestroyed(QObject *))); + m_propertyToEditor[property] = editor; + m_editorToProperty[editor] = property; + m_editedItem = item; + m_editedWidget = editor; + } + return editor; + } + } + return 0; +} + +void QtPropertyEditorDelegate::updateEditorGeometry(QWidget *editor, + const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(index) + editor->setGeometry(option.rect.adjusted(0, 0, 0, -1)); +} + +void QtPropertyEditorDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + bool hasValue = true; + if (m_editorPrivate) { + QtProperty *property = m_editorPrivate->indexToProperty(index); + if (property) + hasValue = property->hasValue(); + } + QStyleOptionViewItemV3 opt = option; + if ((m_editorPrivate && index.column() == 0) || !hasValue) { + QtProperty *property = m_editorPrivate->indexToProperty(index); + if (property && property->isModified()) { + opt.font.setBold(true); + opt.fontMetrics = QFontMetrics(opt.font); + } + } + QColor c; + if (!hasValue && m_editorPrivate->markPropertiesWithoutValue()) { + c = opt.palette.color(QPalette::Dark); + opt.palette.setColor(QPalette::Text, opt.palette.color(QPalette::BrightText)); + } else { + c = m_editorPrivate->calculatedBackgroundColor(m_editorPrivate->indexToBrowserItem(index)); + if (c.isValid() && (opt.features & QStyleOptionViewItemV2::Alternate)) + c = c.lighter(112); + } + if (c.isValid()) + painter->fillRect(option.rect, c); + opt.state &= ~QStyle::State_HasFocus; + QItemDelegate::paint(painter, opt, index); + + opt.palette.setCurrentColorGroup(QPalette::Active); + QColor color = static_cast(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor, &opt)); + painter->save(); + painter->setPen(QPen(color)); + if (!m_editorPrivate || (!m_editorPrivate->lastColumn(index.column()) && hasValue)) { + int right = (option.direction == Qt::LeftToRight) ? option.rect.right() : option.rect.left(); + painter->drawLine(right, option.rect.y(), right, option.rect.bottom()); + } + painter->restore(); +} + +QSize QtPropertyEditorDelegate::sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + return QItemDelegate::sizeHint(option, index) + QSize(3, 4); +} + +bool QtPropertyEditorDelegate::eventFilter(QObject *object, QEvent *event) +{ + if (event->type() == QEvent::FocusOut) { + QFocusEvent *fe = static_cast(event); + if (fe->reason() == Qt::ActiveWindowFocusReason) + return false; + } + return QItemDelegate::eventFilter(object, event); +} + +// -------- QtTreePropertyBrowserPrivate implementation +QtTreePropertyBrowserPrivate::QtTreePropertyBrowserPrivate() : + m_treeWidget(0), + m_headerVisible(true), + m_resizeMode(QtTreePropertyBrowser::Stretch), + m_delegate(0), + m_markPropertiesWithoutValue(false), + m_browserChangedBlocked(false) +{ +} + +// Draw an icon indicating opened/closing branches +static QIcon drawIndicatorIcon(const QPalette &palette, QStyle *style) +{ + QPixmap pix(14, 14); + pix.fill(Qt::transparent); + QStyleOption branchOption; + QRect r(QPoint(0, 0), pix.size()); + branchOption.rect = QRect(2, 2, 9, 9); // ### hardcoded in qcommonstyle.cpp + branchOption.palette = palette; + branchOption.state = QStyle::State_Children; + + QPainter p; + // Draw closed state + p.begin(&pix); + style->drawPrimitive(QStyle::PE_IndicatorBranch, &branchOption, &p); + p.end(); + QIcon rc = pix; + rc.addPixmap(pix, QIcon::Selected, QIcon::Off); + // Draw opened state + branchOption.state |= QStyle::State_Open; + pix.fill(Qt::transparent); + p.begin(&pix); + style->drawPrimitive(QStyle::PE_IndicatorBranch, &branchOption, &p); + p.end(); + + rc.addPixmap(pix, QIcon::Normal, QIcon::On); + rc.addPixmap(pix, QIcon::Selected, QIcon::On); + return rc; +} + +void QtTreePropertyBrowserPrivate::init(QWidget *parent) +{ + QHBoxLayout *layout = new QHBoxLayout(parent); + layout->setMargin(0); + m_treeWidget = new QtPropertyEditorView(parent); + m_treeWidget->setEditorPrivate(this); + m_treeWidget->setIconSize(QSize(18, 18)); + layout->addWidget(m_treeWidget); + + m_treeWidget->setColumnCount(2); + QStringList labels; + labels.append(QApplication::translate("QtTreePropertyBrowser", "Property", 0, QApplication::UnicodeUTF8)); + labels.append(QApplication::translate("QtTreePropertyBrowser", "Value", 0, QApplication::UnicodeUTF8)); + m_treeWidget->setHeaderLabels(labels); + m_treeWidget->setAlternatingRowColors(true); + m_treeWidget->setEditTriggers(QAbstractItemView::EditKeyPressed); + m_delegate = new QtPropertyEditorDelegate(parent); + m_delegate->setEditorPrivate(this); + m_treeWidget->setItemDelegate(m_delegate); + m_treeWidget->header()->setMovable(false); + m_treeWidget->header()->setResizeMode(QHeaderView::Stretch); + + m_expandIcon = drawIndicatorIcon(q_ptr->palette(), q_ptr->style()); + + QObject::connect(m_treeWidget, SIGNAL(collapsed(const QModelIndex &)), q_ptr, SLOT(slotCollapsed(const QModelIndex &))); + QObject::connect(m_treeWidget, SIGNAL(expanded(const QModelIndex &)), q_ptr, SLOT(slotExpanded(const QModelIndex &))); + QObject::connect(m_treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), q_ptr, SLOT(slotCurrentTreeItemChanged(QTreeWidgetItem*,QTreeWidgetItem*))); +} + +QtBrowserItem *QtTreePropertyBrowserPrivate::currentItem() const +{ + if (QTreeWidgetItem *treeItem = m_treeWidget->currentItem()) + return m_itemToIndex.value(treeItem); + return 0; +} + +void QtTreePropertyBrowserPrivate::setCurrentItem(QtBrowserItem *browserItem, bool block) +{ + const bool blocked = block ? m_treeWidget->blockSignals(true) : false; + if (browserItem == 0) + m_treeWidget->setCurrentItem(0); + else + m_treeWidget->setCurrentItem(m_indexToItem.value(browserItem)); + if (block) + m_treeWidget->blockSignals(blocked); +} + +QtProperty *QtTreePropertyBrowserPrivate::indexToProperty(const QModelIndex &index) const +{ + QTreeWidgetItem *item = m_treeWidget->indexToItem(index); + QtBrowserItem *idx = m_itemToIndex.value(item); + if (idx) + return idx->property(); + return 0; +} + +QtBrowserItem *QtTreePropertyBrowserPrivate::indexToBrowserItem(const QModelIndex &index) const +{ + QTreeWidgetItem *item = m_treeWidget->indexToItem(index); + return m_itemToIndex.value(item); +} + +QTreeWidgetItem *QtTreePropertyBrowserPrivate::indexToItem(const QModelIndex &index) const +{ + return m_treeWidget->indexToItem(index); +} + +bool QtTreePropertyBrowserPrivate::lastColumn(int column) const +{ + return m_treeWidget->header()->visualIndex(column) == m_treeWidget->columnCount() - 1; +} + +void QtTreePropertyBrowserPrivate::disableItem(QTreeWidgetItem *item) const +{ + Qt::ItemFlags flags = item->flags(); + if (flags & Qt::ItemIsEnabled) { + flags &= ~Qt::ItemIsEnabled; + item->setFlags(flags); + m_delegate->closeEditor(m_itemToIndex[item]->property()); + const int childCount = item->childCount(); + for (int i = 0; i < childCount; i++) { + QTreeWidgetItem *child = item->child(i); + disableItem(child); + } + } +} + +void QtTreePropertyBrowserPrivate::enableItem(QTreeWidgetItem *item) const +{ + Qt::ItemFlags flags = item->flags(); + flags |= Qt::ItemIsEnabled; + item->setFlags(flags); + const int childCount = item->childCount(); + for (int i = 0; i < childCount; i++) { + QTreeWidgetItem *child = item->child(i); + QtProperty *property = m_itemToIndex[child]->property(); + if (property->isEnabled()) { + enableItem(child); + } + } +} + +bool QtTreePropertyBrowserPrivate::hasValue(QTreeWidgetItem *item) const +{ + QtBrowserItem *browserItem = m_itemToIndex.value(item); + if (browserItem) + return browserItem->property()->hasValue(); + return false; +} + +void QtTreePropertyBrowserPrivate::propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex) +{ + QTreeWidgetItem *afterItem = m_indexToItem.value(afterIndex); + QTreeWidgetItem *parentItem = m_indexToItem.value(index->parent()); + + QTreeWidgetItem *newItem = 0; + if (parentItem) { + newItem = new QTreeWidgetItem(parentItem, afterItem); + } else { + newItem = new QTreeWidgetItem(m_treeWidget, afterItem); + } + m_itemToIndex[newItem] = index; + m_indexToItem[index] = newItem; + + newItem->setFlags(newItem->flags() | Qt::ItemIsEditable); + m_treeWidget->setItemExpanded(newItem, true); + + updateItem(newItem); +} + +void QtTreePropertyBrowserPrivate::propertyRemoved(QtBrowserItem *index) +{ + QTreeWidgetItem *item = m_indexToItem.value(index); + + if (m_treeWidget->currentItem() == item) { + m_treeWidget->setCurrentItem(0); + } + + delete item; + + m_indexToItem.remove(index); + m_itemToIndex.remove(item); + m_indexToBackgroundColor.remove(index); +} + +void QtTreePropertyBrowserPrivate::propertyChanged(QtBrowserItem *index) +{ + QTreeWidgetItem *item = m_indexToItem.value(index); + + updateItem(item); +} + +void QtTreePropertyBrowserPrivate::updateItem(QTreeWidgetItem *item) +{ + QtProperty *property = m_itemToIndex[item]->property(); + QIcon expandIcon; + if (property->hasValue()) { + QString toolTip = property->toolTip(); + if (toolTip.isEmpty()) + toolTip = property->valueText(); + item->setToolTip(1, toolTip); + item->setIcon(1, property->valueIcon()); + item->setText(1, property->valueText()); + } else if (markPropertiesWithoutValue() && !m_treeWidget->rootIsDecorated()) { + expandIcon = m_expandIcon; + } + item->setIcon(0, expandIcon); + item->setFirstColumnSpanned(!property->hasValue()); + item->setToolTip(0, property->propertyName()); + item->setStatusTip(0, property->statusTip()); + item->setWhatsThis(0, property->whatsThis()); + item->setText(0, property->propertyName()); + bool wasEnabled = item->flags() & Qt::ItemIsEnabled; + bool isEnabled = wasEnabled; + if (property->isEnabled()) { + QTreeWidgetItem *parent = item->parent(); + if (!parent || (parent->flags() & Qt::ItemIsEnabled)) + isEnabled = true; + else + isEnabled = false; + } else { + isEnabled = false; + } + if (wasEnabled != isEnabled) { + if (isEnabled) + enableItem(item); + else + disableItem(item); + } + m_treeWidget->viewport()->update(); +} + +QColor QtTreePropertyBrowserPrivate::calculatedBackgroundColor(QtBrowserItem *item) const +{ + QtBrowserItem *i = item; + const QMap::const_iterator itEnd = m_indexToBackgroundColor.constEnd(); + while (i) { + QMap::const_iterator it = m_indexToBackgroundColor.constFind(i); + if (it != itEnd) + return it.value(); + i = i->parent(); + } + return QColor(); +} + +void QtTreePropertyBrowserPrivate::slotCollapsed(const QModelIndex &index) +{ + QTreeWidgetItem *item = indexToItem(index); + QtBrowserItem *idx = m_itemToIndex.value(item); + if (item) + emit q_ptr->collapsed(idx); +} + +void QtTreePropertyBrowserPrivate::slotExpanded(const QModelIndex &index) +{ + QTreeWidgetItem *item = indexToItem(index); + QtBrowserItem *idx = m_itemToIndex.value(item); + if (item) + emit q_ptr->expanded(idx); +} + +void QtTreePropertyBrowserPrivate::slotCurrentBrowserItemChanged(QtBrowserItem *item) +{ + if (!m_browserChangedBlocked && item != currentItem()) + setCurrentItem(item, true); +} + +void QtTreePropertyBrowserPrivate::slotCurrentTreeItemChanged(QTreeWidgetItem *newItem, QTreeWidgetItem *) +{ + QtBrowserItem *browserItem = newItem ? m_itemToIndex.value(newItem) : 0; + m_browserChangedBlocked = true; + q_ptr->setCurrentItem(browserItem); + m_browserChangedBlocked = false; +} + +QTreeWidgetItem *QtTreePropertyBrowserPrivate::editedItem() const +{ + return m_delegate->editedItem(); +} + +void QtTreePropertyBrowserPrivate::editItem(QtBrowserItem *browserItem) +{ + if (QTreeWidgetItem *treeItem = m_indexToItem.value(browserItem, 0)) { + m_treeWidget->setCurrentItem (treeItem, 1); + m_treeWidget->editItem(treeItem, 1); + } +} + +/*! + \class QtTreePropertyBrowser + + \brief The QtTreePropertyBrowser class provides QTreeWidget based + property browser. + + A property browser is a widget that enables the user to edit a + given set of properties. Each property is represented by a label + specifying the property's name, and an editing widget (e.g. a line + edit or a combobox) holding its value. A property can have zero or + more subproperties. + + QtTreePropertyBrowser provides a tree based view for all nested + properties, i.e. properties that have subproperties can be in an + expanded (subproperties are visible) or collapsed (subproperties + are hidden) state. For example: + + \image qttreepropertybrowser.png + + Use the QtAbstractPropertyBrowser API to add, insert and remove + properties from an instance of the QtTreePropertyBrowser class. + The properties themselves are created and managed by + implementations of the QtAbstractPropertyManager class. + + \sa QtGroupBoxPropertyBrowser, QtAbstractPropertyBrowser +*/ + +/*! + \fn void QtTreePropertyBrowser::collapsed(QtBrowserItem *item) + + This signal is emitted when the \a item is collapsed. + + \sa expanded(), setExpanded() +*/ + +/*! + \fn void QtTreePropertyBrowser::expanded(QtBrowserItem *item) + + This signal is emitted when the \a item is expanded. + + \sa collapsed(), setExpanded() +*/ + +/*! + Creates a property browser with the given \a parent. +*/ +QtTreePropertyBrowser::QtTreePropertyBrowser(QWidget *parent) + : QtAbstractPropertyBrowser(parent) +{ + d_ptr = new QtTreePropertyBrowserPrivate; + d_ptr->q_ptr = this; + + d_ptr->init(this); + connect(this, SIGNAL(currentItemChanged(QtBrowserItem*)), this, SLOT(slotCurrentBrowserItemChanged(QtBrowserItem*))); +} + +/*! + Destroys this property browser. + + Note that the properties that were inserted into this browser are + \e not destroyed since they may still be used in other + browsers. The properties are owned by the manager that created + them. + + \sa QtProperty, QtAbstractPropertyManager +*/ +QtTreePropertyBrowser::~QtTreePropertyBrowser() +{ + delete d_ptr; +} + +/*! + \property QtTreePropertyBrowser::indentation + \brief indentation of the items in the tree view. +*/ +int QtTreePropertyBrowser::indentation() const +{ + return d_ptr->m_treeWidget->indentation(); +} + +void QtTreePropertyBrowser::setIndentation(int i) +{ + d_ptr->m_treeWidget->setIndentation(i); +} + +/*! + \property QtTreePropertyBrowser::rootIsDecorated + \brief whether to show controls for expanding and collapsing root items. +*/ +bool QtTreePropertyBrowser::rootIsDecorated() const +{ + return d_ptr->m_treeWidget->rootIsDecorated(); +} + +void QtTreePropertyBrowser::setRootIsDecorated(bool show) +{ + d_ptr->m_treeWidget->setRootIsDecorated(show); + QMapIterator it(d_ptr->m_itemToIndex); + while (it.hasNext()) { + QtProperty *property = it.next().value()->property(); + if (!property->hasValue()) + d_ptr->updateItem(it.key()); + } +} + +/*! + \property QtTreePropertyBrowser::alternatingRowColors + \brief whether to draw the background using alternating colors. + By default this property is set to true. +*/ +bool QtTreePropertyBrowser::alternatingRowColors() const +{ + return d_ptr->m_treeWidget->alternatingRowColors(); +} + +void QtTreePropertyBrowser::setAlternatingRowColors(bool enable) +{ + d_ptr->m_treeWidget->setAlternatingRowColors(enable); + QMapIterator it(d_ptr->m_itemToIndex); +} + +/*! + \property QtTreePropertyBrowser::headerVisible + \brief whether to show the header. +*/ +bool QtTreePropertyBrowser::isHeaderVisible() const +{ + return d_ptr->m_headerVisible; +} + +void QtTreePropertyBrowser::setHeaderVisible(bool visible) +{ + if (d_ptr->m_headerVisible == visible) + return; + + d_ptr->m_headerVisible = visible; + d_ptr->m_treeWidget->header()->setVisible(visible); +} + +/*! + \enum QtTreePropertyBrowser::ResizeMode + + The resize mode specifies the behavior of the header sections. + + \value Interactive The user can resize the sections. + The sections can also be resized programmatically using setSplitterPosition(). + + \value Fixed The user cannot resize the section. + The section can only be resized programmatically using setSplitterPosition(). + + \value Stretch QHeaderView will automatically resize the section to fill the available space. + The size cannot be changed by the user or programmatically. + + \value ResizeToContents QHeaderView will automatically resize the section to its optimal + size based on the contents of the entire column. + The size cannot be changed by the user or programmatically. + + \sa setResizeMode() +*/ + +/*! + \property QtTreePropertyBrowser::resizeMode + \brief the resize mode of setions in the header. +*/ + +QtTreePropertyBrowser::ResizeMode QtTreePropertyBrowser::resizeMode() const +{ + return d_ptr->m_resizeMode; +} + +void QtTreePropertyBrowser::setResizeMode(QtTreePropertyBrowser::ResizeMode mode) +{ + if (d_ptr->m_resizeMode == mode) + return; + + d_ptr->m_resizeMode = mode; + QHeaderView::ResizeMode m = QHeaderView::Stretch; + switch (mode) { + case QtTreePropertyBrowser::Interactive: m = QHeaderView::Interactive; break; + case QtTreePropertyBrowser::Fixed: m = QHeaderView::Fixed; break; + case QtTreePropertyBrowser::ResizeToContents: m = QHeaderView::ResizeToContents; break; + case QtTreePropertyBrowser::Stretch: + default: m = QHeaderView::Stretch; break; + } + d_ptr->m_treeWidget->header()->setResizeMode(m); +} + +/*! + \property QtTreePropertyBrowser::splitterPosition + \brief the position of the splitter between the colunms. +*/ + +int QtTreePropertyBrowser::splitterPosition() const +{ + return d_ptr->m_treeWidget->header()->sectionSize(0); +} + +void QtTreePropertyBrowser::setSplitterPosition(int position) +{ + d_ptr->m_treeWidget->header()->resizeSection(0, position); +} + +/*! + Sets the \a item to either collapse or expanded, depending on the value of \a expanded. + + \sa isExpanded(), expanded(), collapsed() +*/ + +void QtTreePropertyBrowser::setExpanded(QtBrowserItem *item, bool expanded) +{ + QTreeWidgetItem *treeItem = d_ptr->m_indexToItem.value(item); + if (treeItem) + treeItem->setExpanded(expanded); +} + +/*! + Returns true if the \a item is expanded; otherwise returns false. + + \sa setExpanded() +*/ + +bool QtTreePropertyBrowser::isExpanded(QtBrowserItem *item) const +{ + QTreeWidgetItem *treeItem = d_ptr->m_indexToItem.value(item); + if (treeItem) + return treeItem->isExpanded(); + return false; +} + +/*! + Returns true if the \a item is visible; otherwise returns false. + + \sa setItemVisible() + \since 4.5 +*/ + +bool QtTreePropertyBrowser::isItemVisible(QtBrowserItem *item) const +{ + if (const QTreeWidgetItem *treeItem = d_ptr->m_indexToItem.value(item)) + return !treeItem->isHidden(); + return false; +} + +/*! + Sets the \a item to be visible, depending on the value of \a visible. + + \sa isItemVisible() + \since 4.5 +*/ + +void QtTreePropertyBrowser::setItemVisible(QtBrowserItem *item, bool visible) +{ + if (QTreeWidgetItem *treeItem = d_ptr->m_indexToItem.value(item)) + treeItem->setHidden(!visible); +} + +/*! + Sets the \a item's background color to \a color. Note that while item's background + is rendered every second row is being drawn with alternate color (which is a bit lighter than items \a color) + + \sa backgroundColor(), calculatedBackgroundColor() +*/ + +void QtTreePropertyBrowser::setBackgroundColor(QtBrowserItem *item, const QColor &color) +{ + if (!d_ptr->m_indexToItem.contains(item)) + return; + if (color.isValid()) + d_ptr->m_indexToBackgroundColor[item] = color; + else + d_ptr->m_indexToBackgroundColor.remove(item); + d_ptr->m_treeWidget->viewport()->update(); +} + +/*! + Returns the \a item's color. If there is no color set for item it returns invalid color. + + \sa calculatedBackgroundColor(), setBackgroundColor() +*/ + +QColor QtTreePropertyBrowser::backgroundColor(QtBrowserItem *item) const +{ + return d_ptr->m_indexToBackgroundColor.value(item); +} + +/*! + Returns the \a item's color. If there is no color set for item it returns parent \a item's + color (if there is no color set for parent it returns grandparent's color and so on). In case + the color is not set for \a item and it's top level item it returns invalid color. + + \sa backgroundColor(), setBackgroundColor() +*/ + +QColor QtTreePropertyBrowser::calculatedBackgroundColor(QtBrowserItem *item) const +{ + return d_ptr->calculatedBackgroundColor(item); +} + +/*! + \property QtTreePropertyBrowser::propertiesWithoutValueMarked + \brief whether to enable or disable marking properties without value. + + When marking is enabled the item's background is rendered in dark color and item's + foreground is rendered with light color. + + \sa propertiesWithoutValueMarked() +*/ +void QtTreePropertyBrowser::setPropertiesWithoutValueMarked(bool mark) +{ + if (d_ptr->m_markPropertiesWithoutValue == mark) + return; + + d_ptr->m_markPropertiesWithoutValue = mark; + QMapIterator it(d_ptr->m_itemToIndex); + while (it.hasNext()) { + QtProperty *property = it.next().value()->property(); + if (!property->hasValue()) + d_ptr->updateItem(it.key()); + } + d_ptr->m_treeWidget->viewport()->update(); +} + +bool QtTreePropertyBrowser::propertiesWithoutValueMarked() const +{ + return d_ptr->m_markPropertiesWithoutValue; +} + +/*! + \reimp +*/ +void QtTreePropertyBrowser::itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem) +{ + d_ptr->propertyInserted(item, afterItem); +} + +/*! + \reimp +*/ +void QtTreePropertyBrowser::itemRemoved(QtBrowserItem *item) +{ + d_ptr->propertyRemoved(item); +} + +/*! + \reimp +*/ +void QtTreePropertyBrowser::itemChanged(QtBrowserItem *item) +{ + d_ptr->propertyChanged(item); +} + +/*! + Sets the current item to \a item and opens the relevant editor for it. +*/ +void QtTreePropertyBrowser::editItem(QtBrowserItem *item) +{ + d_ptr->editItem(item); +} + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +#include "moc_qttreepropertybrowser.cxx" +#include "qttreepropertybrowser.moc" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qttreepropertybrowser.h b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qttreepropertybrowser.h new file mode 100644 index 000000000..f664609d7 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qttreepropertybrowser.h @@ -0,0 +1,184 @@ +/**************************************************************************** +** +** This file is part of a Qt Solutions component. +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTTREEPROPERTYBROWSER_H +#define QTTREEPROPERTYBROWSER_H + +#include "qtpropertybrowser.h" + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +class QTreeWidgetItem; +class QtTreePropertyBrowserPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtTreePropertyBrowser : public QtAbstractPropertyBrowser +{ + Q_OBJECT + Q_ENUMS(ResizeMode) + Q_PROPERTY(int indentation READ indentation WRITE setIndentation) + Q_PROPERTY(bool rootIsDecorated READ rootIsDecorated WRITE setRootIsDecorated) + Q_PROPERTY(bool alternatingRowColors READ alternatingRowColors WRITE setAlternatingRowColors) + Q_PROPERTY(bool headerVisible READ isHeaderVisible WRITE setHeaderVisible) + Q_PROPERTY(ResizeMode resizeMode READ resizeMode WRITE setResizeMode) + Q_PROPERTY(int splitterPosition READ splitterPosition WRITE setSplitterPosition) + Q_PROPERTY(bool propertiesWithoutValueMarked READ propertiesWithoutValueMarked WRITE setPropertiesWithoutValueMarked) +public: + + enum ResizeMode + { + Interactive, + Stretch, + Fixed, + ResizeToContents + }; + + QtTreePropertyBrowser(QWidget *parent = 0); + ~QtTreePropertyBrowser(); + + int indentation() const; + void setIndentation(int i); + + bool rootIsDecorated() const; + void setRootIsDecorated(bool show); + + bool alternatingRowColors() const; + void setAlternatingRowColors(bool enable); + + bool isHeaderVisible() const; + void setHeaderVisible(bool visible); + + ResizeMode resizeMode() const; + void setResizeMode(ResizeMode mode); + + int splitterPosition() const; + void setSplitterPosition(int position); + + void setExpanded(QtBrowserItem *item, bool expanded); + bool isExpanded(QtBrowserItem *item) const; + + bool isItemVisible(QtBrowserItem *item) const; + void setItemVisible(QtBrowserItem *item, bool visible); + + void setBackgroundColor(QtBrowserItem *item, const QColor &color); + QColor backgroundColor(QtBrowserItem *item) const; + QColor calculatedBackgroundColor(QtBrowserItem *item) const; + + void setPropertiesWithoutValueMarked(bool mark); + bool propertiesWithoutValueMarked() const; + + void editItem(QtBrowserItem *item); + +Q_SIGNALS: + + void collapsed(QtBrowserItem *item); + void expanded(QtBrowserItem *item); + +protected: + virtual void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem); + virtual void itemRemoved(QtBrowserItem *item); + virtual void itemChanged(QtBrowserItem *item); + +private: + + QtTreePropertyBrowserPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtTreePropertyBrowser) + Q_DISABLE_COPY(QtTreePropertyBrowser) + + Q_PRIVATE_SLOT(d_func(), void slotCollapsed(const QModelIndex &)) + Q_PRIVATE_SLOT(d_func(), void slotExpanded(const QModelIndex &)) + Q_PRIVATE_SLOT(d_func(), void slotCurrentBrowserItemChanged(QtBrowserItem *)) + Q_PRIVATE_SLOT(d_func(), void slotCurrentTreeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)) + +}; + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +#endif diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtvariantproperty.cpp b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtvariantproperty.cpp new file mode 100644 index 000000000..820e6e2f1 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtvariantproperty.cpp @@ -0,0 +1,2329 @@ +/**************************************************************************** +** +** This file is part of a Qt Solutions component. +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtvariantproperty.h" +#include "qtpropertymanager.h" +#include "qteditorfactory.h" +#include +#include +#include +#include + +#if defined(Q_CC_MSVC) +# pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */ +#endif + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +class QtEnumPropertyType +{ +}; + + +class QtFlagPropertyType +{ +}; + + +class QtGroupPropertyType +{ +}; + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +Q_DECLARE_METATYPE(QtEnumPropertyType) +Q_DECLARE_METATYPE(QtFlagPropertyType) +Q_DECLARE_METATYPE(QtGroupPropertyType) + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +/*! + Returns the type id for an enum property. + + Note that the property's value type can be retrieved using the + valueType() function (which is QVariant::Int for the enum property + type). + + \sa propertyType(), valueType() +*/ +int QtVariantPropertyManager::enumTypeId() +{ + return qMetaTypeId(); +} + +/*! + Returns the type id for a flag property. + + Note that the property's value type can be retrieved using the + valueType() function (which is QVariant::Int for the flag property + type). + + \sa propertyType(), valueType() +*/ +int QtVariantPropertyManager::flagTypeId() +{ + return qMetaTypeId(); +} + +/*! + Returns the type id for a group property. + + Note that the property's value type can be retrieved using the + valueType() function (which is QVariant::Invalid for the group + property type, since it doesn't provide any value). + + \sa propertyType(), valueType() +*/ +int QtVariantPropertyManager::groupTypeId() +{ + return qMetaTypeId(); +} + +/*! + Returns the type id for a icon map attribute. + + Note that the property's attribute type can be retrieved using the + attributeType() function. + + \sa attributeType(), QtEnumPropertyManager::enumIcons() +*/ +int QtVariantPropertyManager::iconMapTypeId() +{ + return qMetaTypeId(); +} + +typedef QMap PropertyMap; +Q_GLOBAL_STATIC(PropertyMap, propertyToWrappedProperty) + +static QtProperty *wrappedProperty(QtProperty *property) +{ + return propertyToWrappedProperty()->value(property, 0); +} + +class QtVariantPropertyPrivate +{ + QtVariantProperty *q_ptr; +public: + QtVariantPropertyPrivate(QtVariantPropertyManager *m) : manager(m) {} + + QtVariantPropertyManager *manager; +}; + +/*! + \class QtVariantProperty + + \brief The QtVariantProperty class is a convenience class handling + QVariant based properties. + + QtVariantProperty provides additional API: A property's type, + value type, attribute values and current value can easily be + retrieved using the propertyType(), valueType(), attributeValue() + and value() functions respectively. In addition, the attribute + values and the current value can be set using the corresponding + setValue() and setAttribute() functions. + + For example, instead of writing: + + \code + QtVariantPropertyManager *variantPropertyManager; + QtProperty *property; + + variantPropertyManager->setValue(property, 10); + \endcode + + you can write: + + \code + QtVariantPropertyManager *variantPropertyManager; + QtVariantProperty *property; + + property->setValue(10); + \endcode + + QtVariantProperty instances can only be created by the + QtVariantPropertyManager class. + + \sa QtProperty, QtVariantPropertyManager, QtVariantEditorFactory +*/ + +/*! + Creates a variant property using the given \a manager. + + Do not use this constructor to create variant property instances; + use the QtVariantPropertyManager::addProperty() function + instead. This constructor is used internally by the + QtVariantPropertyManager::createProperty() function. + + \sa QtVariantPropertyManager +*/ +QtVariantProperty::QtVariantProperty(QtVariantPropertyManager *manager) + : QtProperty(manager), d_ptr(new QtVariantPropertyPrivate(manager)) +{ + +} + +/*! + Destroys this property. + + \sa QtProperty::~QtProperty() +*/ +QtVariantProperty::~QtVariantProperty() +{ + delete d_ptr; +} + +/*! + Returns the property's current value. + + \sa valueType(), setValue() +*/ +QVariant QtVariantProperty::value() const +{ + return d_ptr->manager->value(this); +} + +/*! + Returns this property's value for the specified \a attribute. + + QtVariantPropertyManager provides a couple of related functions: + \l{QtVariantPropertyManager::attributes()}{attributes()} and + \l{QtVariantPropertyManager::attributeType()}{attributeType()}. + + \sa setAttribute() +*/ +QVariant QtVariantProperty::attributeValue(const QString &attribute) const +{ + return d_ptr->manager->attributeValue(this, attribute); +} + +/*! + Returns the type of this property's value. + + \sa propertyType() +*/ +int QtVariantProperty::valueType() const +{ + return d_ptr->manager->valueType(this); +} + +/*! + Returns this property's type. + + QtVariantPropertyManager provides several related functions: + \l{QtVariantPropertyManager::enumTypeId()}{enumTypeId()}, + \l{QtVariantPropertyManager::flagTypeId()}{flagTypeId()} and + \l{QtVariantPropertyManager::groupTypeId()}{groupTypeId()}. + + \sa valueType() +*/ +int QtVariantProperty::propertyType() const +{ + return d_ptr->manager->propertyType(this); +} + +/*! + Sets the value of this property to \a value. + + The specified \a value must be of the type returned by + valueType(), or of a type that can be converted to valueType() + using the QVariant::canConvert() function; otherwise this function + does nothing. + + \sa value() +*/ +void QtVariantProperty::setValue(const QVariant &value) +{ + d_ptr->manager->setValue(this, value); +} + +/*! + Sets the \a attribute of property to \a value. + + QtVariantPropertyManager provides the related + \l{QtVariantPropertyManager::setAttribute()}{setAttribute()} + function. + + \sa attributeValue() +*/ +void QtVariantProperty::setAttribute(const QString &attribute, const QVariant &value) +{ + d_ptr->manager->setAttribute(this, attribute, value); +} + +class QtVariantPropertyManagerPrivate +{ + QtVariantPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtVariantPropertyManager) +public: + QtVariantPropertyManagerPrivate(); + + bool m_creatingProperty; + bool m_creatingSubProperties; + bool m_destroyingSubProperties; + int m_propertyType; + + void slotValueChanged(QtProperty *property, int val); + void slotRangeChanged(QtProperty *property, int min, int max); + void slotSingleStepChanged(QtProperty *property, int step); + void slotValueChanged(QtProperty *property, double val); + void slotRangeChanged(QtProperty *property, double min, double max); + void slotSingleStepChanged(QtProperty *property, double step); + void slotDecimalsChanged(QtProperty *property, int prec); + void slotValueChanged(QtProperty *property, bool val); + void slotValueChanged(QtProperty *property, const QString &val); + void slotRegExpChanged(QtProperty *property, const QRegExp ®Exp); + void slotValueChanged(QtProperty *property, const QDate &val); + void slotRangeChanged(QtProperty *property, const QDate &min, const QDate &max); + void slotValueChanged(QtProperty *property, const QTime &val); + void slotValueChanged(QtProperty *property, const QDateTime &val); + void slotValueChanged(QtProperty *property, const QKeySequence &val); + void slotValueChanged(QtProperty *property, const QChar &val); + void slotValueChanged(QtProperty *property, const QLocale &val); + void slotValueChanged(QtProperty *property, const QPoint &val); + void slotValueChanged(QtProperty *property, const QPointF &val); + void slotValueChanged(QtProperty *property, const QSize &val); + void slotRangeChanged(QtProperty *property, const QSize &min, const QSize &max); + void slotValueChanged(QtProperty *property, const QSizeF &val); + void slotRangeChanged(QtProperty *property, const QSizeF &min, const QSizeF &max); + void slotValueChanged(QtProperty *property, const QRect &val); + void slotConstraintChanged(QtProperty *property, const QRect &val); + void slotValueChanged(QtProperty *property, const QRectF &val); + void slotConstraintChanged(QtProperty *property, const QRectF &val); + void slotValueChanged(QtProperty *property, const QColor &val); + void slotEnumChanged(QtProperty *property, int val); + void slotEnumNamesChanged(QtProperty *property, const QStringList &enumNames); + void slotEnumIconsChanged(QtProperty *property, const QMap &enumIcons); + void slotValueChanged(QtProperty *property, const QSizePolicy &val); + void slotValueChanged(QtProperty *property, const QFont &val); + void slotValueChanged(QtProperty *property, const QCursor &val); + void slotFlagChanged(QtProperty *property, int val); + void slotFlagNamesChanged(QtProperty *property, const QStringList &flagNames); + void slotPropertyInserted(QtProperty *property, QtProperty *parent, QtProperty *after); + void slotPropertyRemoved(QtProperty *property, QtProperty *parent); + + void valueChanged(QtProperty *property, const QVariant &val); + + int internalPropertyToType(QtProperty *property) const; + QtVariantProperty *createSubProperty(QtVariantProperty *parent, QtVariantProperty *after, + QtProperty *internal); + void removeSubProperty(QtVariantProperty *property); + + QMap m_typeToPropertyManager; + QMap > m_typeToAttributeToAttributeType; + + QMap > m_propertyToType; + + QMap m_typeToValueType; + + + QMap m_internalToProperty; + + const QString m_constraintAttribute; + const QString m_singleStepAttribute; + const QString m_decimalsAttribute; + const QString m_enumIconsAttribute; + const QString m_enumNamesAttribute; + const QString m_flagNamesAttribute; + const QString m_maximumAttribute; + const QString m_minimumAttribute; + const QString m_regExpAttribute; +}; + +QtVariantPropertyManagerPrivate::QtVariantPropertyManagerPrivate() : + m_constraintAttribute(QLatin1String("constraint")), + m_singleStepAttribute(QLatin1String("singleStep")), + m_decimalsAttribute(QLatin1String("decimals")), + m_enumIconsAttribute(QLatin1String("enumIcons")), + m_enumNamesAttribute(QLatin1String("enumNames")), + m_flagNamesAttribute(QLatin1String("flagNames")), + m_maximumAttribute(QLatin1String("maximum")), + m_minimumAttribute(QLatin1String("minimum")), + m_regExpAttribute(QLatin1String("regExp")) +{ +} + +int QtVariantPropertyManagerPrivate::internalPropertyToType(QtProperty *property) const +{ + int type = 0; + QtAbstractPropertyManager *internPropertyManager = property->propertyManager(); + if (qobject_cast(internPropertyManager)) + type = QVariant::Int; + else if (qobject_cast(internPropertyManager)) + type = QtVariantPropertyManager::enumTypeId(); + else if (qobject_cast(internPropertyManager)) + type = QVariant::Bool; + else if (qobject_cast(internPropertyManager)) + type = QVariant::Double; + return type; +} + +QtVariantProperty *QtVariantPropertyManagerPrivate::createSubProperty(QtVariantProperty *parent, + QtVariantProperty *after, QtProperty *internal) +{ + int type = internalPropertyToType(internal); + if (!type) + return 0; + + bool wasCreatingSubProperties = m_creatingSubProperties; + m_creatingSubProperties = true; + + QtVariantProperty *varChild = q_ptr->addProperty(type, internal->propertyName()); + + m_creatingSubProperties = wasCreatingSubProperties; + + varChild->setPropertyName(internal->propertyName()); + varChild->setToolTip(internal->toolTip()); + varChild->setStatusTip(internal->statusTip()); + varChild->setWhatsThis(internal->whatsThis()); + + parent->insertSubProperty(varChild, after); + + m_internalToProperty[internal] = varChild; + propertyToWrappedProperty()->insert(varChild, internal); + return varChild; +} + +void QtVariantPropertyManagerPrivate::removeSubProperty(QtVariantProperty *property) +{ + QtProperty *internChild = wrappedProperty(property); + bool wasDestroyingSubProperties = m_destroyingSubProperties; + m_destroyingSubProperties = true; + delete property; + m_destroyingSubProperties = wasDestroyingSubProperties; + m_internalToProperty.remove(internChild); + propertyToWrappedProperty()->remove(property); +} + +void QtVariantPropertyManagerPrivate::slotPropertyInserted(QtProperty *property, + QtProperty *parent, QtProperty *after) +{ + if (m_creatingProperty) + return; + + QtVariantProperty *varParent = m_internalToProperty.value(parent, 0); + if (!varParent) + return; + + QtVariantProperty *varAfter = 0; + if (after) { + varAfter = m_internalToProperty.value(after, 0); + if (!varAfter) + return; + } + + createSubProperty(varParent, varAfter, property); +} + +void QtVariantPropertyManagerPrivate::slotPropertyRemoved(QtProperty *property, QtProperty *parent) +{ + Q_UNUSED(parent) + + QtVariantProperty *varProperty = m_internalToProperty.value(property, 0); + if (!varProperty) + return; + + removeSubProperty(varProperty); +} + +void QtVariantPropertyManagerPrivate::valueChanged(QtProperty *property, const QVariant &val) +{ + QtVariantProperty *varProp = m_internalToProperty.value(property, 0); + if (!varProp) + return; + emit q_ptr->valueChanged(varProp, val); + emit q_ptr->propertyChanged(varProp); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, int val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, int min, int max) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) { + emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min)); + emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max)); + } +} + +void QtVariantPropertyManagerPrivate::slotSingleStepChanged(QtProperty *property, int step) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) + emit q_ptr->attributeChanged(varProp, m_singleStepAttribute, QVariant(step)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, double val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, double min, double max) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) { + emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min)); + emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max)); + } +} + +void QtVariantPropertyManagerPrivate::slotSingleStepChanged(QtProperty *property, double step) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) + emit q_ptr->attributeChanged(varProp, m_singleStepAttribute, QVariant(step)); +} + +void QtVariantPropertyManagerPrivate::slotDecimalsChanged(QtProperty *property, int prec) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) + emit q_ptr->attributeChanged(varProp, m_decimalsAttribute, QVariant(prec)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, bool val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QString &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotRegExpChanged(QtProperty *property, const QRegExp ®Exp) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) + emit q_ptr->attributeChanged(varProp, m_regExpAttribute, QVariant(regExp)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QDate &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, const QDate &min, const QDate &max) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) { + emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min)); + emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max)); + } +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QTime &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QDateTime &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QKeySequence &val) +{ + QVariant v; + qVariantSetValue(v, val); + valueChanged(property, v); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QChar &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QLocale &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QPoint &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QPointF &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QSize &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, const QSize &min, const QSize &max) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) { + emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min)); + emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max)); + } +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QSizeF &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, const QSizeF &min, const QSizeF &max) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) { + emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min)); + emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max)); + } +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QRect &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotConstraintChanged(QtProperty *property, const QRect &constraint) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) + emit q_ptr->attributeChanged(varProp, m_constraintAttribute, QVariant(constraint)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QRectF &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotConstraintChanged(QtProperty *property, const QRectF &constraint) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) + emit q_ptr->attributeChanged(varProp, m_constraintAttribute, QVariant(constraint)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QColor &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotEnumNamesChanged(QtProperty *property, const QStringList &enumNames) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) + emit q_ptr->attributeChanged(varProp, m_enumNamesAttribute, QVariant(enumNames)); +} + +void QtVariantPropertyManagerPrivate::slotEnumIconsChanged(QtProperty *property, const QMap &enumIcons) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) { + QVariant v; + qVariantSetValue(v, enumIcons); + emit q_ptr->attributeChanged(varProp, m_enumIconsAttribute, v); + } +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QSizePolicy &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QFont &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QCursor &val) +{ +#ifndef QT_NO_CURSOR + valueChanged(property, QVariant(val)); +#endif +} + +void QtVariantPropertyManagerPrivate::slotFlagNamesChanged(QtProperty *property, const QStringList &flagNames) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) + emit q_ptr->attributeChanged(varProp, m_flagNamesAttribute, QVariant(flagNames)); +} + +/*! + \class QtVariantPropertyManager + + \brief The QtVariantPropertyManager class provides and manages QVariant based properties. + + QtVariantPropertyManager provides the addProperty() function which + creates QtVariantProperty objects. The QtVariantProperty class is + a convenience class handling QVariant based properties inheriting + QtProperty. A QtProperty object created by a + QtVariantPropertyManager instance can be converted into a + QtVariantProperty object using the variantProperty() function. + + The property's value can be retrieved using the value(), and set + using the setValue() slot. In addition the property's type, and + the type of its value, can be retrieved using the propertyType() + and valueType() functions respectively. + + A property's type is a QVariant::Type enumerator value, and + usually a property's type is the same as its value type. But for + some properties the types differ, for example for enums, flags and + group types in which case QtVariantPropertyManager provides the + enumTypeId(), flagTypeId() and groupTypeId() functions, + respectively, to identify their property type (the value types are + QVariant::Int for the enum and flag types, and QVariant::Invalid + for the group type). + + Use the isPropertyTypeSupported() function to check if a particular + property type is supported. The currently supported property types + are: + + \table + \header + \o Property Type + \o Property Type Id + \row + \o int + \o QVariant::Int + \row + \o double + \o QVariant::Double + \row + \o bool + \o QVariant::Bool + \row + \o QString + \o QVariant::String + \row + \o QDate + \o QVariant::Date + \row + \o QTime + \o QVariant::Time + \row + \o QDateTime + \o QVariant::DateTime + \row + \o QKeySequence + \o QVariant::KeySequence + \row + \o QChar + \o QVariant::Char + \row + \o QLocale + \o QVariant::Locale + \row + \o QPoint + \o QVariant::Point + \row + \o QPointF + \o QVariant::PointF + \row + \o QSize + \o QVariant::Size + \row + \o QSizeF + \o QVariant::SizeF + \row + \o QRect + \o QVariant::Rect + \row + \o QRectF + \o QVariant::RectF + \row + \o QColor + \o QVariant::Color + \row + \o QSizePolicy + \o QVariant::SizePolicy + \row + \o QFont + \o QVariant::Font + \row + \o QCursor + \o QVariant::Cursor + \row + \o enum + \o enumTypeId() + \row + \o flag + \o flagTypeId() + \row + \o group + \o groupTypeId() + \endtable + + Each property type can provide additional attributes, + e.g. QVariant::Int and QVariant::Double provides minimum and + maximum values. The currently supported attributes are: + + \table + \header + \o Property Type + \o Attribute Name + \o Attribute Type + \row + \o \c int + \o minimum + \o QVariant::Int + \row + \o + \o maximum + \o QVariant::Int + \row + \o + \o singleStep + \o QVariant::Int + \row + \o \c double + \o minimum + \o QVariant::Double + \row + \o + \o maximum + \o QVariant::Double + \row + \o + \o singleStep + \o QVariant::Double + \row + \o + \o decimals + \o QVariant::Int + \row + \o QString + \o regExp + \o QVariant::RegExp + \row + \o QDate + \o minimum + \o QVariant::Date + \row + \o + \o maximum + \o QVariant::Date + \row + \o QPointF + \o decimals + \o QVariant::Int + \row + \o QSize + \o minimum + \o QVariant::Size + \row + \o + \o maximum + \o QVariant::Size + \row + \o QSizeF + \o minimum + \o QVariant::SizeF + \row + \o + \o maximum + \o QVariant::SizeF + \row + \o + \o decimals + \o QVariant::Int + \row + \o QRect + \o constraint + \o QVariant::Rect + \row + \o QRectF + \o constraint + \o QVariant::RectF + \row + \o + \o decimals + \o QVariant::Int + \row + \o \c enum + \o enumNames + \o QVariant::StringList + \row + \o + \o enumIcons + \o iconMapTypeId() + \row + \o \c flag + \o flagNames + \o QVariant::StringList + \endtable + + The attributes for a given property type can be retrieved using + the attributes() function. Each attribute has a value type which + can be retrieved using the attributeType() function, and a value + accessible through the attributeValue() function. In addition, the + value can be set using the setAttribute() slot. + + QtVariantManager also provides the valueChanged() signal which is + emitted whenever a property created by this manager change, and + the attributeChanged() signal which is emitted whenever an + attribute of such a property changes. + + \sa QtVariantProperty, QtVariantEditorFactory +*/ + +/*! + \fn void QtVariantPropertyManager::valueChanged(QtProperty *property, const QVariant &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtVariantPropertyManager::attributeChanged(QtProperty *property, + const QString &attribute, const QVariant &value) + + This signal is emitted whenever an attribute of a property created + by this manager changes its value, passing a pointer to the \a + property, the \a attribute and the new \a value as parameters. + + \sa setAttribute() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtVariantPropertyManager::QtVariantPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent) +{ + d_ptr = new QtVariantPropertyManagerPrivate; + d_ptr->q_ptr = this; + + d_ptr->m_creatingProperty = false; + d_ptr->m_creatingSubProperties = false; + d_ptr->m_destroyingSubProperties = false; + d_ptr->m_propertyType = 0; + + // IntPropertyManager + QtIntPropertyManager *intPropertyManager = new QtIntPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Int] = intPropertyManager; + d_ptr->m_typeToAttributeToAttributeType[QVariant::Int][d_ptr->m_minimumAttribute] = QVariant::Int; + d_ptr->m_typeToAttributeToAttributeType[QVariant::Int][d_ptr->m_maximumAttribute] = QVariant::Int; + d_ptr->m_typeToAttributeToAttributeType[QVariant::Int][d_ptr->m_singleStepAttribute] = QVariant::Int; + d_ptr->m_typeToValueType[QVariant::Int] = QVariant::Int; + connect(intPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotValueChanged(QtProperty *, int))); + connect(intPropertyManager, SIGNAL(rangeChanged(QtProperty *, int, int)), + this, SLOT(slotRangeChanged(QtProperty *, int, int))); + connect(intPropertyManager, SIGNAL(singleStepChanged(QtProperty *, int)), + this, SLOT(slotSingleStepChanged(QtProperty *, int))); + // DoublePropertyManager + QtDoublePropertyManager *doublePropertyManager = new QtDoublePropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Double] = doublePropertyManager; + d_ptr->m_typeToAttributeToAttributeType[QVariant::Double][d_ptr->m_minimumAttribute] = + QVariant::Double; + d_ptr->m_typeToAttributeToAttributeType[QVariant::Double][d_ptr->m_maximumAttribute] = + QVariant::Double; + d_ptr->m_typeToAttributeToAttributeType[QVariant::Double][d_ptr->m_singleStepAttribute] = + QVariant::Double; + d_ptr->m_typeToAttributeToAttributeType[QVariant::Double][d_ptr->m_decimalsAttribute] = + QVariant::Int; + d_ptr->m_typeToValueType[QVariant::Double] = QVariant::Double; + connect(doublePropertyManager, SIGNAL(valueChanged(QtProperty *, double)), + this, SLOT(slotValueChanged(QtProperty *, double))); + connect(doublePropertyManager, SIGNAL(rangeChanged(QtProperty *, double, double)), + this, SLOT(slotRangeChanged(QtProperty *, double, double))); + connect(doublePropertyManager, SIGNAL(singleStepChanged(QtProperty *, double)), + this, SLOT(slotSingleStepChanged(QtProperty *, double))); + connect(doublePropertyManager, SIGNAL(decimalsChanged(QtProperty *, int)), + this, SLOT(slotDecimalsChanged(QtProperty *, int))); + // BoolPropertyManager + QtBoolPropertyManager *boolPropertyManager = new QtBoolPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Bool] = boolPropertyManager; + d_ptr->m_typeToValueType[QVariant::Bool] = QVariant::Bool; + connect(boolPropertyManager, SIGNAL(valueChanged(QtProperty *, bool)), + this, SLOT(slotValueChanged(QtProperty *, bool))); + // StringPropertyManager + QtStringPropertyManager *stringPropertyManager = new QtStringPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::String] = stringPropertyManager; + d_ptr->m_typeToValueType[QVariant::String] = QVariant::String; + d_ptr->m_typeToAttributeToAttributeType[QVariant::String][d_ptr->m_regExpAttribute] = + QVariant::RegExp; + connect(stringPropertyManager, SIGNAL(valueChanged(QtProperty *, const QString &)), + this, SLOT(slotValueChanged(QtProperty *, const QString &))); + connect(stringPropertyManager, SIGNAL(regExpChanged(QtProperty *, const QRegExp &)), + this, SLOT(slotRegExpChanged(QtProperty *, const QRegExp &))); + // DatePropertyManager + QtDatePropertyManager *datePropertyManager = new QtDatePropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Date] = datePropertyManager; + d_ptr->m_typeToValueType[QVariant::Date] = QVariant::Date; + d_ptr->m_typeToAttributeToAttributeType[QVariant::Date][d_ptr->m_minimumAttribute] = + QVariant::Date; + d_ptr->m_typeToAttributeToAttributeType[QVariant::Date][d_ptr->m_maximumAttribute] = + QVariant::Date; + connect(datePropertyManager, SIGNAL(valueChanged(QtProperty *, const QDate &)), + this, SLOT(slotValueChanged(QtProperty *, const QDate &))); + connect(datePropertyManager, SIGNAL(rangeChanged(QtProperty *, const QDate &, const QDate &)), + this, SLOT(slotRangeChanged(QtProperty *, const QDate &, const QDate &))); + // TimePropertyManager + QtTimePropertyManager *timePropertyManager = new QtTimePropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Time] = timePropertyManager; + d_ptr->m_typeToValueType[QVariant::Time] = QVariant::Time; + connect(timePropertyManager, SIGNAL(valueChanged(QtProperty *, const QTime &)), + this, SLOT(slotValueChanged(QtProperty *, const QTime &))); + // DateTimePropertyManager + QtDateTimePropertyManager *dateTimePropertyManager = new QtDateTimePropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::DateTime] = dateTimePropertyManager; + d_ptr->m_typeToValueType[QVariant::DateTime] = QVariant::DateTime; + connect(dateTimePropertyManager, SIGNAL(valueChanged(QtProperty *, const QDateTime &)), + this, SLOT(slotValueChanged(QtProperty *, const QDateTime &))); + // KeySequencePropertyManager + QtKeySequencePropertyManager *keySequencePropertyManager = new QtKeySequencePropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::KeySequence] = keySequencePropertyManager; + d_ptr->m_typeToValueType[QVariant::KeySequence] = QVariant::KeySequence; + connect(keySequencePropertyManager, SIGNAL(valueChanged(QtProperty *, const QKeySequence &)), + this, SLOT(slotValueChanged(QtProperty *, const QKeySequence &))); + // CharPropertyManager + QtCharPropertyManager *charPropertyManager = new QtCharPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Char] = charPropertyManager; + d_ptr->m_typeToValueType[QVariant::Char] = QVariant::Char; + connect(charPropertyManager, SIGNAL(valueChanged(QtProperty *, const QChar &)), + this, SLOT(slotValueChanged(QtProperty *, const QChar &))); + // LocalePropertyManager + QtLocalePropertyManager *localePropertyManager = new QtLocalePropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Locale] = localePropertyManager; + d_ptr->m_typeToValueType[QVariant::Locale] = QVariant::Locale; + connect(localePropertyManager, SIGNAL(valueChanged(QtProperty *, const QLocale &)), + this, SLOT(slotValueChanged(QtProperty *, const QLocale &))); + connect(localePropertyManager->subEnumPropertyManager(), SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotValueChanged(QtProperty *, int))); + connect(localePropertyManager, SIGNAL(propertyInserted(QtProperty *, QtProperty *, QtProperty *)), + this, SLOT(slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *))); + connect(localePropertyManager, SIGNAL(propertyRemoved(QtProperty *, QtProperty *)), + this, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + // PointPropertyManager + QtPointPropertyManager *pointPropertyManager = new QtPointPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Point] = pointPropertyManager; + d_ptr->m_typeToValueType[QVariant::Point] = QVariant::Point; + connect(pointPropertyManager, SIGNAL(valueChanged(QtProperty *, const QPoint &)), + this, SLOT(slotValueChanged(QtProperty *, const QPoint &))); + connect(pointPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotValueChanged(QtProperty *, int))); + connect(pointPropertyManager, SIGNAL(propertyInserted(QtProperty *, QtProperty *, QtProperty *)), + this, SLOT(slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *))); + connect(pointPropertyManager, SIGNAL(propertyRemoved(QtProperty *, QtProperty *)), + this, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + // PointFPropertyManager + QtPointFPropertyManager *pointFPropertyManager = new QtPointFPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::PointF] = pointFPropertyManager; + d_ptr->m_typeToValueType[QVariant::PointF] = QVariant::PointF; + d_ptr->m_typeToAttributeToAttributeType[QVariant::PointF][d_ptr->m_decimalsAttribute] = + QVariant::Int; + connect(pointFPropertyManager, SIGNAL(valueChanged(QtProperty *, const QPointF &)), + this, SLOT(slotValueChanged(QtProperty *, const QPointF &))); + connect(pointFPropertyManager, SIGNAL(decimalsChanged(QtProperty *, int)), + this, SLOT(slotDecimalsChanged(QtProperty *, int))); + connect(pointFPropertyManager->subDoublePropertyManager(), SIGNAL(valueChanged(QtProperty *, double)), + this, SLOT(slotValueChanged(QtProperty *, double))); + connect(pointFPropertyManager, SIGNAL(propertyInserted(QtProperty *, QtProperty *, QtProperty *)), + this, SLOT(slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *))); + connect(pointFPropertyManager, SIGNAL(propertyRemoved(QtProperty *, QtProperty *)), + this, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + // SizePropertyManager + QtSizePropertyManager *sizePropertyManager = new QtSizePropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Size] = sizePropertyManager; + d_ptr->m_typeToValueType[QVariant::Size] = QVariant::Size; + d_ptr->m_typeToAttributeToAttributeType[QVariant::Size][d_ptr->m_minimumAttribute] = + QVariant::Size; + d_ptr->m_typeToAttributeToAttributeType[QVariant::Size][d_ptr->m_maximumAttribute] = + QVariant::Size; + connect(sizePropertyManager, SIGNAL(valueChanged(QtProperty *, const QSize &)), + this, SLOT(slotValueChanged(QtProperty *, const QSize &))); + connect(sizePropertyManager, SIGNAL(rangeChanged(QtProperty *, const QSize &, const QSize &)), + this, SLOT(slotRangeChanged(QtProperty *, const QSize &, const QSize &))); + connect(sizePropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotValueChanged(QtProperty *, int))); + connect(sizePropertyManager->subIntPropertyManager(), SIGNAL(rangeChanged(QtProperty *, int, int)), + this, SLOT(slotRangeChanged(QtProperty *, int, int))); + connect(sizePropertyManager, SIGNAL(propertyInserted(QtProperty *, QtProperty *, QtProperty *)), + this, SLOT(slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *))); + connect(sizePropertyManager, SIGNAL(propertyRemoved(QtProperty *, QtProperty *)), + this, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + // SizeFPropertyManager + QtSizeFPropertyManager *sizeFPropertyManager = new QtSizeFPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::SizeF] = sizeFPropertyManager; + d_ptr->m_typeToValueType[QVariant::SizeF] = QVariant::SizeF; + d_ptr->m_typeToAttributeToAttributeType[QVariant::SizeF][d_ptr->m_minimumAttribute] = + QVariant::SizeF; + d_ptr->m_typeToAttributeToAttributeType[QVariant::SizeF][d_ptr->m_maximumAttribute] = + QVariant::SizeF; + d_ptr->m_typeToAttributeToAttributeType[QVariant::SizeF][d_ptr->m_decimalsAttribute] = + QVariant::Int; + connect(sizeFPropertyManager, SIGNAL(valueChanged(QtProperty *, const QSizeF &)), + this, SLOT(slotValueChanged(QtProperty *, const QSizeF &))); + connect(sizeFPropertyManager, SIGNAL(rangeChanged(QtProperty *, const QSizeF &, const QSizeF &)), + this, SLOT(slotRangeChanged(QtProperty *, const QSizeF &, const QSizeF &))); + connect(sizeFPropertyManager, SIGNAL(decimalsChanged(QtProperty *, int)), + this, SLOT(slotDecimalsChanged(QtProperty *, int))); + connect(sizeFPropertyManager->subDoublePropertyManager(), SIGNAL(valueChanged(QtProperty *, double)), + this, SLOT(slotValueChanged(QtProperty *, double))); + connect(sizeFPropertyManager->subDoublePropertyManager(), SIGNAL(rangeChanged(QtProperty *, double, double)), + this, SLOT(slotRangeChanged(QtProperty *, double, double))); + connect(sizeFPropertyManager, SIGNAL(propertyInserted(QtProperty *, QtProperty *, QtProperty *)), + this, SLOT(slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *))); + connect(sizeFPropertyManager, SIGNAL(propertyRemoved(QtProperty *, QtProperty *)), + this, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + // RectPropertyManager + QtRectPropertyManager *rectPropertyManager = new QtRectPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Rect] = rectPropertyManager; + d_ptr->m_typeToValueType[QVariant::Rect] = QVariant::Rect; + d_ptr->m_typeToAttributeToAttributeType[QVariant::Rect][d_ptr->m_constraintAttribute] = + QVariant::Rect; + connect(rectPropertyManager, SIGNAL(valueChanged(QtProperty *, const QRect &)), + this, SLOT(slotValueChanged(QtProperty *, const QRect &))); + connect(rectPropertyManager, SIGNAL(constraintChanged(QtProperty *, const QRect &)), + this, SLOT(slotConstraintChanged(QtProperty *, const QRect &))); + connect(rectPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotValueChanged(QtProperty *, int))); + connect(rectPropertyManager->subIntPropertyManager(), SIGNAL(rangeChanged(QtProperty *, int, int)), + this, SLOT(slotRangeChanged(QtProperty *, int, int))); + connect(rectPropertyManager, SIGNAL(propertyInserted(QtProperty *, QtProperty *, QtProperty *)), + this, SLOT(slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *))); + connect(rectPropertyManager, SIGNAL(propertyRemoved(QtProperty *, QtProperty *)), + this, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + // RectFPropertyManager + QtRectFPropertyManager *rectFPropertyManager = new QtRectFPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::RectF] = rectFPropertyManager; + d_ptr->m_typeToValueType[QVariant::RectF] = QVariant::RectF; + d_ptr->m_typeToAttributeToAttributeType[QVariant::RectF][d_ptr->m_constraintAttribute] = + QVariant::RectF; + d_ptr->m_typeToAttributeToAttributeType[QVariant::RectF][d_ptr->m_decimalsAttribute] = + QVariant::Int; + connect(rectFPropertyManager, SIGNAL(valueChanged(QtProperty *, const QRectF &)), + this, SLOT(slotValueChanged(QtProperty *, const QRectF &))); + connect(rectFPropertyManager, SIGNAL(constraintChanged(QtProperty *, const QRectF &)), + this, SLOT(slotConstraintChanged(QtProperty *, const QRectF &))); + connect(rectFPropertyManager, SIGNAL(decimalsChanged(QtProperty *, int)), + this, SLOT(slotDecimalsChanged(QtProperty *, int))); + connect(rectFPropertyManager->subDoublePropertyManager(), SIGNAL(valueChanged(QtProperty *, double)), + this, SLOT(slotValueChanged(QtProperty *, double))); + connect(rectFPropertyManager->subDoublePropertyManager(), SIGNAL(rangeChanged(QtProperty *, double, double)), + this, SLOT(slotRangeChanged(QtProperty *, double, double))); + connect(rectFPropertyManager, SIGNAL(propertyInserted(QtProperty *, QtProperty *, QtProperty *)), + this, SLOT(slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *))); + connect(rectFPropertyManager, SIGNAL(propertyRemoved(QtProperty *, QtProperty *)), + this, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + // ColorPropertyManager + QtColorPropertyManager *colorPropertyManager = new QtColorPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Color] = colorPropertyManager; + d_ptr->m_typeToValueType[QVariant::Color] = QVariant::Color; + connect(colorPropertyManager, SIGNAL(valueChanged(QtProperty *, const QColor &)), + this, SLOT(slotValueChanged(QtProperty *, const QColor &))); + connect(colorPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotValueChanged(QtProperty *, int))); + connect(colorPropertyManager, SIGNAL(propertyInserted(QtProperty *, QtProperty *, QtProperty *)), + this, SLOT(slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *))); + connect(colorPropertyManager, SIGNAL(propertyRemoved(QtProperty *, QtProperty *)), + this, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + // EnumPropertyManager + int enumId = enumTypeId(); + QtEnumPropertyManager *enumPropertyManager = new QtEnumPropertyManager(this); + d_ptr->m_typeToPropertyManager[enumId] = enumPropertyManager; + d_ptr->m_typeToValueType[enumId] = QVariant::Int; + d_ptr->m_typeToAttributeToAttributeType[enumId][d_ptr->m_enumNamesAttribute] = + QVariant::StringList; + d_ptr->m_typeToAttributeToAttributeType[enumId][d_ptr->m_enumIconsAttribute] = + iconMapTypeId(); + connect(enumPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotValueChanged(QtProperty *, int))); + connect(enumPropertyManager, SIGNAL(enumNamesChanged(QtProperty *, const QStringList &)), + this, SLOT(slotEnumNamesChanged(QtProperty *, const QStringList &))); + connect(enumPropertyManager, SIGNAL(enumIconsChanged(QtProperty *, const QMap &)), + this, SLOT(slotEnumIconsChanged(QtProperty *, const QMap &))); + // SizePolicyPropertyManager + QtSizePolicyPropertyManager *sizePolicyPropertyManager = new QtSizePolicyPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::SizePolicy] = sizePolicyPropertyManager; + d_ptr->m_typeToValueType[QVariant::SizePolicy] = QVariant::SizePolicy; + connect(sizePolicyPropertyManager, SIGNAL(valueChanged(QtProperty *, const QSizePolicy &)), + this, SLOT(slotValueChanged(QtProperty *, const QSizePolicy &))); + connect(sizePolicyPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotValueChanged(QtProperty *, int))); + connect(sizePolicyPropertyManager->subIntPropertyManager(), SIGNAL(rangeChanged(QtProperty *, int, int)), + this, SLOT(slotRangeChanged(QtProperty *, int, int))); + connect(sizePolicyPropertyManager->subEnumPropertyManager(), SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotValueChanged(QtProperty *, int))); + connect(sizePolicyPropertyManager->subEnumPropertyManager(), + SIGNAL(enumNamesChanged(QtProperty *, const QStringList &)), + this, SLOT(slotEnumNamesChanged(QtProperty *, const QStringList &))); + connect(sizePolicyPropertyManager, SIGNAL(propertyInserted(QtProperty *, QtProperty *, QtProperty *)), + this, SLOT(slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *))); + connect(sizePolicyPropertyManager, SIGNAL(propertyRemoved(QtProperty *, QtProperty *)), + this, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + // FontPropertyManager + QtFontPropertyManager *fontPropertyManager = new QtFontPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Font] = fontPropertyManager; + d_ptr->m_typeToValueType[QVariant::Font] = QVariant::Font; + connect(fontPropertyManager, SIGNAL(valueChanged(QtProperty *, const QFont &)), + this, SLOT(slotValueChanged(QtProperty *, const QFont &))); + connect(fontPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotValueChanged(QtProperty *, int))); + connect(fontPropertyManager->subIntPropertyManager(), SIGNAL(rangeChanged(QtProperty *, int, int)), + this, SLOT(slotRangeChanged(QtProperty *, int, int))); + connect(fontPropertyManager->subEnumPropertyManager(), SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotValueChanged(QtProperty *, int))); + connect(fontPropertyManager->subEnumPropertyManager(), + SIGNAL(enumNamesChanged(QtProperty *, const QStringList &)), + this, SLOT(slotEnumNamesChanged(QtProperty *, const QStringList &))); + connect(fontPropertyManager->subBoolPropertyManager(), SIGNAL(valueChanged(QtProperty *, bool)), + this, SLOT(slotValueChanged(QtProperty *, bool))); + connect(fontPropertyManager, SIGNAL(propertyInserted(QtProperty *, QtProperty *, QtProperty *)), + this, SLOT(slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *))); + connect(fontPropertyManager, SIGNAL(propertyRemoved(QtProperty *, QtProperty *)), + this, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + // CursorPropertyManager + QtCursorPropertyManager *cursorPropertyManager = new QtCursorPropertyManager(this); + d_ptr->m_typeToPropertyManager[QVariant::Cursor] = cursorPropertyManager; + d_ptr->m_typeToValueType[QVariant::Cursor] = QVariant::Cursor; + connect(cursorPropertyManager, SIGNAL(valueChanged(QtProperty *, const QCursor &)), + this, SLOT(slotValueChanged(QtProperty *, const QCursor &))); + // FlagPropertyManager + int flagId = flagTypeId(); + QtFlagPropertyManager *flagPropertyManager = new QtFlagPropertyManager(this); + d_ptr->m_typeToPropertyManager[flagId] = flagPropertyManager; + d_ptr->m_typeToValueType[flagId] = QVariant::Int; + d_ptr->m_typeToAttributeToAttributeType[flagId][d_ptr->m_flagNamesAttribute] = + QVariant::StringList; + connect(flagPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), + this, SLOT(slotValueChanged(QtProperty *, int))); + connect(flagPropertyManager, SIGNAL(flagNamesChanged(QtProperty *, const QStringList &)), + this, SLOT(slotFlagNamesChanged(QtProperty *, const QStringList &))); + connect(flagPropertyManager->subBoolPropertyManager(), SIGNAL(valueChanged(QtProperty *, bool)), + this, SLOT(slotValueChanged(QtProperty *, bool))); + connect(flagPropertyManager, SIGNAL(propertyInserted(QtProperty *, QtProperty *, QtProperty *)), + this, SLOT(slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *))); + connect(flagPropertyManager, SIGNAL(propertyRemoved(QtProperty *, QtProperty *)), + this, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *))); + // FlagPropertyManager + int groupId = groupTypeId(); + QtGroupPropertyManager *groupPropertyManager = new QtGroupPropertyManager(this); + d_ptr->m_typeToPropertyManager[groupId] = groupPropertyManager; + d_ptr->m_typeToValueType[groupId] = QVariant::Invalid; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtVariantPropertyManager::~QtVariantPropertyManager() +{ + clear(); + delete d_ptr; +} + +/*! + Returns the given \a property converted into a QtVariantProperty. + + If the \a property was not created by this variant manager, the + function returns 0. + + \sa createProperty() +*/ +QtVariantProperty *QtVariantPropertyManager::variantProperty(const QtProperty *property) const +{ + const QMap >::const_iterator it = d_ptr->m_propertyToType.constFind(property); + if (it == d_ptr->m_propertyToType.constEnd()) + return 0; + return it.value().first; +} + +/*! + Returns true if the given \a propertyType is supported by this + variant manager; otherwise false. + + \sa propertyType() +*/ +bool QtVariantPropertyManager::isPropertyTypeSupported(int propertyType) const +{ + if (d_ptr->m_typeToValueType.contains(propertyType)) + return true; + return false; +} + +/*! + Creates and returns a variant property of the given \a propertyType + with the given \a name. + + If the specified \a propertyType is not supported by this variant + manager, this function returns 0. + + Do not use the inherited + QtAbstractPropertyManager::addProperty() function to create a + variant property (that function will always return 0 since it will + not be clear what type the property should have). + + \sa isPropertyTypeSupported() +*/ +QtVariantProperty *QtVariantPropertyManager::addProperty(int propertyType, const QString &name) +{ + if (!isPropertyTypeSupported(propertyType)) + return 0; + + bool wasCreating = d_ptr->m_creatingProperty; + d_ptr->m_creatingProperty = true; + d_ptr->m_propertyType = propertyType; + QtProperty *property = QtAbstractPropertyManager::addProperty(name); + d_ptr->m_creatingProperty = wasCreating; + d_ptr->m_propertyType = 0; + + if (!property) + return 0; + + return variantProperty(property); +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns an invalid variant. + + \sa setValue() +*/ +QVariant QtVariantPropertyManager::value(const QtProperty *property) const +{ + QtProperty *internProp = propertyToWrappedProperty()->value(property, 0); + if (internProp == 0) + return QVariant(); + + QtAbstractPropertyManager *manager = internProp->propertyManager(); + if (QtIntPropertyManager *intManager = qobject_cast(manager)) { + return intManager->value(internProp); + } else if (QtDoublePropertyManager *doubleManager = qobject_cast(manager)) { + return doubleManager->value(internProp); + } else if (QtBoolPropertyManager *boolManager = qobject_cast(manager)) { + return boolManager->value(internProp); + } else if (QtStringPropertyManager *stringManager = qobject_cast(manager)) { + return stringManager->value(internProp); + } else if (QtDatePropertyManager *dateManager = qobject_cast(manager)) { + return dateManager->value(internProp); + } else if (QtTimePropertyManager *timeManager = qobject_cast(manager)) { + return timeManager->value(internProp); + } else if (QtDateTimePropertyManager *dateTimeManager = qobject_cast(manager)) { + return dateTimeManager->value(internProp); + } else if (QtKeySequencePropertyManager *keySequenceManager = qobject_cast(manager)) { + return keySequenceManager->value(internProp); + } else if (QtCharPropertyManager *charManager = qobject_cast(manager)) { + return charManager->value(internProp); + } else if (QtLocalePropertyManager *localeManager = qobject_cast(manager)) { + return localeManager->value(internProp); + } else if (QtPointPropertyManager *pointManager = qobject_cast(manager)) { + return pointManager->value(internProp); + } else if (QtPointFPropertyManager *pointFManager = qobject_cast(manager)) { + return pointFManager->value(internProp); + } else if (QtSizePropertyManager *sizeManager = qobject_cast(manager)) { + return sizeManager->value(internProp); + } else if (QtSizeFPropertyManager *sizeFManager = qobject_cast(manager)) { + return sizeFManager->value(internProp); + } else if (QtRectPropertyManager *rectManager = qobject_cast(manager)) { + return rectManager->value(internProp); + } else if (QtRectFPropertyManager *rectFManager = qobject_cast(manager)) { + return rectFManager->value(internProp); + } else if (QtColorPropertyManager *colorManager = qobject_cast(manager)) { + return colorManager->value(internProp); + } else if (QtEnumPropertyManager *enumManager = qobject_cast(manager)) { + return enumManager->value(internProp); + } else if (QtSizePolicyPropertyManager *sizePolicyManager = + qobject_cast(manager)) { + return sizePolicyManager->value(internProp); + } else if (QtFontPropertyManager *fontManager = qobject_cast(manager)) { + return fontManager->value(internProp); +#ifndef QT_NO_CURSOR + } else if (QtCursorPropertyManager *cursorManager = qobject_cast(manager)) { + return cursorManager->value(internProp); +#endif + } else if (QtFlagPropertyManager *flagManager = qobject_cast(manager)) { + return flagManager->value(internProp); + } + return QVariant(); +} + +/*! + Returns the given \a property's value type. + + \sa propertyType() +*/ +int QtVariantPropertyManager::valueType(const QtProperty *property) const +{ + int propType = propertyType(property); + return valueType(propType); +} + +/*! + \overload + + Returns the value type associated with the given \a propertyType. +*/ +int QtVariantPropertyManager::valueType(int propertyType) const +{ + if (d_ptr->m_typeToValueType.contains(propertyType)) + return d_ptr->m_typeToValueType[propertyType]; + return 0; +} + +/*! + Returns the given \a property's type. + + \sa valueType() +*/ +int QtVariantPropertyManager::propertyType(const QtProperty *property) const +{ + const QMap >::const_iterator it = d_ptr->m_propertyToType.constFind(property); + if (it == d_ptr->m_propertyToType.constEnd()) + return 0; + return it.value().second; +} + +/*! + Returns the given \a property's value for the specified \a + attribute + + If the given \a property was not created by \e this manager, or if + the specified \a attribute does not exist, this function returns + an invalid variant. + + \sa attributes(), attributeType(), setAttribute() +*/ +QVariant QtVariantPropertyManager::attributeValue(const QtProperty *property, const QString &attribute) const +{ + int propType = propertyType(property); + if (!propType) + return QVariant(); + + QMap >::ConstIterator it = + d_ptr->m_typeToAttributeToAttributeType.find(propType); + if (it == d_ptr->m_typeToAttributeToAttributeType.constEnd()) + return QVariant(); + + QMap attributes = it.value(); + QMap::ConstIterator itAttr = attributes.find(attribute); + if (itAttr == attributes.constEnd()) + return QVariant(); + + QtProperty *internProp = propertyToWrappedProperty()->value(property, 0); + if (internProp == 0) + return QVariant(); + + QtAbstractPropertyManager *manager = internProp->propertyManager(); + if (QtIntPropertyManager *intManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + return intManager->maximum(internProp); + if (attribute == d_ptr->m_minimumAttribute) + return intManager->minimum(internProp); + if (attribute == d_ptr->m_singleStepAttribute) + return intManager->singleStep(internProp); + return QVariant(); + } else if (QtDoublePropertyManager *doubleManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + return doubleManager->maximum(internProp); + if (attribute == d_ptr->m_minimumAttribute) + return doubleManager->minimum(internProp); + if (attribute == d_ptr->m_singleStepAttribute) + return doubleManager->singleStep(internProp); + if (attribute == d_ptr->m_decimalsAttribute) + return doubleManager->decimals(internProp); + return QVariant(); + } else if (QtStringPropertyManager *stringManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_regExpAttribute) + return stringManager->regExp(internProp); + return QVariant(); + } else if (QtDatePropertyManager *dateManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + return dateManager->maximum(internProp); + if (attribute == d_ptr->m_minimumAttribute) + return dateManager->minimum(internProp); + return QVariant(); + } else if (QtPointFPropertyManager *pointFManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_decimalsAttribute) + return pointFManager->decimals(internProp); + return QVariant(); + } else if (QtSizePropertyManager *sizeManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + return sizeManager->maximum(internProp); + if (attribute == d_ptr->m_minimumAttribute) + return sizeManager->minimum(internProp); + return QVariant(); + } else if (QtSizeFPropertyManager *sizeFManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + return sizeFManager->maximum(internProp); + if (attribute == d_ptr->m_minimumAttribute) + return sizeFManager->minimum(internProp); + if (attribute == d_ptr->m_decimalsAttribute) + return sizeFManager->decimals(internProp); + return QVariant(); + } else if (QtRectPropertyManager *rectManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_constraintAttribute) + return rectManager->constraint(internProp); + return QVariant(); + } else if (QtRectFPropertyManager *rectFManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_constraintAttribute) + return rectFManager->constraint(internProp); + if (attribute == d_ptr->m_decimalsAttribute) + return rectFManager->decimals(internProp); + return QVariant(); + } else if (QtEnumPropertyManager *enumManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_enumNamesAttribute) + return enumManager->enumNames(internProp); + if (attribute == d_ptr->m_enumIconsAttribute) { + QVariant v; + qVariantSetValue(v, enumManager->enumIcons(internProp)); + return v; + } + return QVariant(); + } else if (QtFlagPropertyManager *flagManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_flagNamesAttribute) + return flagManager->flagNames(internProp); + return QVariant(); + } + return QVariant(); +} + +/*! + Returns a list of the given \a propertyType 's attributes. + + \sa attributeValue(), attributeType() +*/ +QStringList QtVariantPropertyManager::attributes(int propertyType) const +{ + QMap >::ConstIterator it = + d_ptr->m_typeToAttributeToAttributeType.find(propertyType); + if (it == d_ptr->m_typeToAttributeToAttributeType.constEnd()) + return QStringList(); + return it.value().keys(); +} + +/*! + Returns the type of the specified \a attribute of the given \a + propertyType. + + If the given \a propertyType is not supported by \e this manager, + or if the given \a propertyType does not possess the specified \a + attribute, this function returns QVariant::Invalid. + + \sa attributes(), valueType() +*/ +int QtVariantPropertyManager::attributeType(int propertyType, const QString &attribute) const +{ + QMap >::ConstIterator it = + d_ptr->m_typeToAttributeToAttributeType.find(propertyType); + if (it == d_ptr->m_typeToAttributeToAttributeType.constEnd()) + return 0; + + QMap attributes = it.value(); + QMap::ConstIterator itAttr = attributes.find(attribute); + if (itAttr == attributes.constEnd()) + return 0; + return itAttr.value(); +} + +/*! + \fn void QtVariantPropertyManager::setValue(QtProperty *property, const QVariant &value) + + Sets the value of the given \a property to \a value. + + The specified \a value must be of a type returned by valueType(), + or of type that can be converted to valueType() using the + QVariant::canConvert() function, otherwise this function does + nothing. + + \sa value(), QtVariantProperty::setValue(), valueChanged() +*/ +void QtVariantPropertyManager::setValue(QtProperty *property, const QVariant &val) +{ + int propType = val.userType(); + if (!propType) + return; + + int valType = valueType(property); + + if (propType != valType && !val.canConvert(static_cast(valType))) + return; + + QtProperty *internProp = propertyToWrappedProperty()->value(property, 0); + if (internProp == 0) + return; + + + QtAbstractPropertyManager *manager = internProp->propertyManager(); + if (QtIntPropertyManager *intManager = qobject_cast(manager)) { + intManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtDoublePropertyManager *doubleManager = qobject_cast(manager)) { + doubleManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtBoolPropertyManager *boolManager = qobject_cast(manager)) { + boolManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtStringPropertyManager *stringManager = qobject_cast(manager)) { + stringManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtDatePropertyManager *dateManager = qobject_cast(manager)) { + dateManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtTimePropertyManager *timeManager = qobject_cast(manager)) { + timeManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtDateTimePropertyManager *dateTimeManager = qobject_cast(manager)) { + dateTimeManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtKeySequencePropertyManager *keySequenceManager = qobject_cast(manager)) { + keySequenceManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtCharPropertyManager *charManager = qobject_cast(manager)) { + charManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtLocalePropertyManager *localeManager = qobject_cast(manager)) { + localeManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtPointPropertyManager *pointManager = qobject_cast(manager)) { + pointManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtPointFPropertyManager *pointFManager = qobject_cast(manager)) { + pointFManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtSizePropertyManager *sizeManager = qobject_cast(manager)) { + sizeManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtSizeFPropertyManager *sizeFManager = qobject_cast(manager)) { + sizeFManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtRectPropertyManager *rectManager = qobject_cast(manager)) { + rectManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtRectFPropertyManager *rectFManager = qobject_cast(manager)) { + rectFManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtColorPropertyManager *colorManager = qobject_cast(manager)) { + colorManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtEnumPropertyManager *enumManager = qobject_cast(manager)) { + enumManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtSizePolicyPropertyManager *sizePolicyManager = + qobject_cast(manager)) { + sizePolicyManager->setValue(internProp, qVariantValue(val)); + return; + } else if (QtFontPropertyManager *fontManager = qobject_cast(manager)) { + fontManager->setValue(internProp, qVariantValue(val)); + return; +#ifndef QT_NO_CURSOR + } else if (QtCursorPropertyManager *cursorManager = qobject_cast(manager)) { + cursorManager->setValue(internProp, qVariantValue(val)); + return; +#endif + } else if (QtFlagPropertyManager *flagManager = qobject_cast(manager)) { + flagManager->setValue(internProp, qVariantValue(val)); + return; + } +} + +/*! + Sets the value of the specified \a attribute of the given \a + property, to \a value. + + The new \a value's type must be of the type returned by + attributeType(), or of a type that can be converted to + attributeType() using the QVariant::canConvert() function, + otherwise this function does nothing. + + \sa attributeValue(), QtVariantProperty::setAttribute(), attributeChanged() +*/ +void QtVariantPropertyManager::setAttribute(QtProperty *property, + const QString &attribute, const QVariant &value) +{ + QVariant oldAttr = attributeValue(property, attribute); + if (!oldAttr.isValid()) + return; + + int attrType = value.userType(); + if (!attrType) + return; + + if (attrType != attributeType(propertyType(property), attribute) && + !value.canConvert((QVariant::Type)attrType)) + return; + + QtProperty *internProp = propertyToWrappedProperty()->value(property, 0); + if (internProp == 0) + return; + + QtAbstractPropertyManager *manager = internProp->propertyManager(); + if (QtIntPropertyManager *intManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + intManager->setMaximum(internProp, qVariantValue(value)); + else if (attribute == d_ptr->m_minimumAttribute) + intManager->setMinimum(internProp, qVariantValue(value)); + else if (attribute == d_ptr->m_singleStepAttribute) + intManager->setSingleStep(internProp, qVariantValue(value)); + return; + } else if (QtDoublePropertyManager *doubleManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + doubleManager->setMaximum(internProp, qVariantValue(value)); + if (attribute == d_ptr->m_minimumAttribute) + doubleManager->setMinimum(internProp, qVariantValue(value)); + if (attribute == d_ptr->m_singleStepAttribute) + doubleManager->setSingleStep(internProp, qVariantValue(value)); + if (attribute == d_ptr->m_decimalsAttribute) + doubleManager->setDecimals(internProp, qVariantValue(value)); + return; + } else if (QtStringPropertyManager *stringManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_regExpAttribute) + stringManager->setRegExp(internProp, qVariantValue(value)); + return; + } else if (QtDatePropertyManager *dateManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + dateManager->setMaximum(internProp, qVariantValue(value)); + if (attribute == d_ptr->m_minimumAttribute) + dateManager->setMinimum(internProp, qVariantValue(value)); + return; + } else if (QtPointFPropertyManager *pointFManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_decimalsAttribute) + pointFManager->setDecimals(internProp, qVariantValue(value)); + return; + } else if (QtSizePropertyManager *sizeManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + sizeManager->setMaximum(internProp, qVariantValue(value)); + if (attribute == d_ptr->m_minimumAttribute) + sizeManager->setMinimum(internProp, qVariantValue(value)); + return; + } else if (QtSizeFPropertyManager *sizeFManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + sizeFManager->setMaximum(internProp, qVariantValue(value)); + if (attribute == d_ptr->m_minimumAttribute) + sizeFManager->setMinimum(internProp, qVariantValue(value)); + if (attribute == d_ptr->m_decimalsAttribute) + sizeFManager->setDecimals(internProp, qVariantValue(value)); + return; + } else if (QtRectPropertyManager *rectManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_constraintAttribute) + rectManager->setConstraint(internProp, qVariantValue(value)); + return; + } else if (QtRectFPropertyManager *rectFManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_constraintAttribute) + rectFManager->setConstraint(internProp, qVariantValue(value)); + if (attribute == d_ptr->m_decimalsAttribute) + rectFManager->setDecimals(internProp, qVariantValue(value)); + return; + } else if (QtEnumPropertyManager *enumManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_enumNamesAttribute) + enumManager->setEnumNames(internProp, qVariantValue(value)); + if (attribute == d_ptr->m_enumIconsAttribute) + enumManager->setEnumIcons(internProp, qVariantValue(value)); + return; + } else if (QtFlagPropertyManager *flagManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_flagNamesAttribute) + flagManager->setFlagNames(internProp, qVariantValue(value)); + return; + } +} + +/*! + \reimp +*/ +bool QtVariantPropertyManager::hasValue(const QtProperty *property) const +{ + if (propertyType(property) == groupTypeId()) + return false; + return true; +} + +/*! + \reimp +*/ +QString QtVariantPropertyManager::valueText(const QtProperty *property) const +{ + const QtProperty *internProp = propertyToWrappedProperty()->value(property, 0); + return internProp ? internProp->valueText() : QString(); +} + +/*! + \reimp +*/ +QIcon QtVariantPropertyManager::valueIcon(const QtProperty *property) const +{ + const QtProperty *internProp = propertyToWrappedProperty()->value(property, 0); + return internProp ? internProp->valueIcon() : QIcon(); +} + +/*! + \reimp +*/ +void QtVariantPropertyManager::initializeProperty(QtProperty *property) +{ + QtVariantProperty *varProp = variantProperty(property); + if (!varProp) + return; + + QMap::ConstIterator it = + d_ptr->m_typeToPropertyManager.find(d_ptr->m_propertyType); + if (it != d_ptr->m_typeToPropertyManager.constEnd()) { + QtProperty *internProp = 0; + if (!d_ptr->m_creatingSubProperties) { + QtAbstractPropertyManager *manager = it.value(); + internProp = manager->addProperty(); + d_ptr->m_internalToProperty[internProp] = varProp; + } + propertyToWrappedProperty()->insert(varProp, internProp); + if (internProp) { + QList children = internProp->subProperties(); + QListIterator itChild(children); + QtVariantProperty *lastProperty = 0; + while (itChild.hasNext()) { + QtVariantProperty *prop = d_ptr->createSubProperty(varProp, lastProperty, itChild.next()); + lastProperty = prop ? prop : lastProperty; + } + } + } +} + +/*! + \reimp +*/ +void QtVariantPropertyManager::uninitializeProperty(QtProperty *property) +{ + const QMap >::iterator type_it = d_ptr->m_propertyToType.find(property); + if (type_it == d_ptr->m_propertyToType.end()) + return; + + PropertyMap::iterator it = propertyToWrappedProperty()->find(property); + if (it != propertyToWrappedProperty()->end()) { + QtProperty *internProp = it.value(); + if (internProp) { + d_ptr->m_internalToProperty.remove(internProp); + if (!d_ptr->m_destroyingSubProperties) { + delete internProp; + } + } + propertyToWrappedProperty()->erase(it); + } + d_ptr->m_propertyToType.erase(type_it); +} + +/*! + \reimp +*/ +QtProperty *QtVariantPropertyManager::createProperty() +{ + if (!d_ptr->m_creatingProperty) + return 0; + + QtVariantProperty *property = new QtVariantProperty(this); + d_ptr->m_propertyToType.insert(property, qMakePair(property, d_ptr->m_propertyType)); + + return property; +} + +///////////////////////////// + +class QtVariantEditorFactoryPrivate +{ + QtVariantEditorFactory *q_ptr; + Q_DECLARE_PUBLIC(QtVariantEditorFactory) +public: + + QtSpinBoxFactory *m_spinBoxFactory; + QtDoubleSpinBoxFactory *m_doubleSpinBoxFactory; + QtCheckBoxFactory *m_checkBoxFactory; + QtLineEditFactory *m_lineEditFactory; + QtDateEditFactory *m_dateEditFactory; + QtTimeEditFactory *m_timeEditFactory; + QtDateTimeEditFactory *m_dateTimeEditFactory; + QtKeySequenceEditorFactory *m_keySequenceEditorFactory; + QtCharEditorFactory *m_charEditorFactory; + QtEnumEditorFactory *m_comboBoxFactory; + QtCursorEditorFactory *m_cursorEditorFactory; + QtColorEditorFactory *m_colorEditorFactory; + QtFontEditorFactory *m_fontEditorFactory; + + QMap m_factoryToType; + QMap m_typeToFactory; +}; + +/*! + \class QtVariantEditorFactory + + \brief The QtVariantEditorFactory class provides widgets for properties + created by QtVariantPropertyManager objects. + + The variant factory provides the following widgets for the + specified property types: + + \table + \header + \o Property Type + \o Widget + \row + \o \c int + \o QSpinBox + \row + \o \c double + \o QDoubleSpinBox + \row + \o \c bool + \o QCheckBox + \row + \o QString + \o QLineEdit + \row + \o QDate + \o QDateEdit + \row + \o QTime + \o QTimeEdit + \row + \o QDateTime + \o QDateTimeEdit + \row + \o QKeySequence + \o customized editor + \row + \o QChar + \o customized editor + \row + \o \c enum + \o QComboBox + \row + \o QCursor + \o QComboBox + \endtable + + Note that QtVariantPropertyManager supports several additional property + types for which the QtVariantEditorFactory class does not provide + editing widgets, e.g. QPoint and QSize. To provide widgets for other + types using the variant approach, derive from the QtVariantEditorFactory + class. + + \sa QtAbstractEditorFactory, QtVariantPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtVariantEditorFactory::QtVariantEditorFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtVariantEditorFactoryPrivate(); + d_ptr->q_ptr = this; + + d_ptr->m_spinBoxFactory = new QtSpinBoxFactory(this); + d_ptr->m_factoryToType[d_ptr->m_spinBoxFactory] = QVariant::Int; + d_ptr->m_typeToFactory[QVariant::Int] = d_ptr->m_spinBoxFactory; + + d_ptr->m_doubleSpinBoxFactory = new QtDoubleSpinBoxFactory(this); + d_ptr->m_factoryToType[d_ptr->m_doubleSpinBoxFactory] = QVariant::Double; + d_ptr->m_typeToFactory[QVariant::Double] = d_ptr->m_doubleSpinBoxFactory; + + d_ptr->m_checkBoxFactory = new QtCheckBoxFactory(this); + d_ptr->m_factoryToType[d_ptr->m_checkBoxFactory] = QVariant::Bool; + d_ptr->m_typeToFactory[QVariant::Bool] = d_ptr->m_checkBoxFactory; + + d_ptr->m_lineEditFactory = new QtLineEditFactory(this); + d_ptr->m_factoryToType[d_ptr->m_lineEditFactory] = QVariant::String; + d_ptr->m_typeToFactory[QVariant::String] = d_ptr->m_lineEditFactory; + + d_ptr->m_dateEditFactory = new QtDateEditFactory(this); + d_ptr->m_factoryToType[d_ptr->m_dateEditFactory] = QVariant::Date; + d_ptr->m_typeToFactory[QVariant::Date] = d_ptr->m_dateEditFactory; + + d_ptr->m_timeEditFactory = new QtTimeEditFactory(this); + d_ptr->m_factoryToType[d_ptr->m_timeEditFactory] = QVariant::Time; + d_ptr->m_typeToFactory[QVariant::Time] = d_ptr->m_timeEditFactory; + + d_ptr->m_dateTimeEditFactory = new QtDateTimeEditFactory(this); + d_ptr->m_factoryToType[d_ptr->m_dateTimeEditFactory] = QVariant::DateTime; + d_ptr->m_typeToFactory[QVariant::DateTime] = d_ptr->m_dateTimeEditFactory; + + d_ptr->m_keySequenceEditorFactory = new QtKeySequenceEditorFactory(this); + d_ptr->m_factoryToType[d_ptr->m_keySequenceEditorFactory] = QVariant::KeySequence; + d_ptr->m_typeToFactory[QVariant::KeySequence] = d_ptr->m_keySequenceEditorFactory; + + d_ptr->m_charEditorFactory = new QtCharEditorFactory(this); + d_ptr->m_factoryToType[d_ptr->m_charEditorFactory] = QVariant::Char; + d_ptr->m_typeToFactory[QVariant::Char] = d_ptr->m_charEditorFactory; + + d_ptr->m_cursorEditorFactory = new QtCursorEditorFactory(this); + d_ptr->m_factoryToType[d_ptr->m_cursorEditorFactory] = QVariant::Cursor; + d_ptr->m_typeToFactory[QVariant::Cursor] = d_ptr->m_cursorEditorFactory; + + d_ptr->m_colorEditorFactory = new QtColorEditorFactory(this); + d_ptr->m_factoryToType[d_ptr->m_colorEditorFactory] = QVariant::Color; + d_ptr->m_typeToFactory[QVariant::Color] = d_ptr->m_colorEditorFactory; + + d_ptr->m_fontEditorFactory = new QtFontEditorFactory(this); + d_ptr->m_factoryToType[d_ptr->m_fontEditorFactory] = QVariant::Font; + d_ptr->m_typeToFactory[QVariant::Font] = d_ptr->m_fontEditorFactory; + + d_ptr->m_comboBoxFactory = new QtEnumEditorFactory(this); + const int enumId = QtVariantPropertyManager::enumTypeId(); + d_ptr->m_factoryToType[d_ptr->m_comboBoxFactory] = enumId; + d_ptr->m_typeToFactory[enumId] = d_ptr->m_comboBoxFactory; +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtVariantEditorFactory::~QtVariantEditorFactory() +{ + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtVariantEditorFactory::connectPropertyManager(QtVariantPropertyManager *manager) +{ + QList intPropertyManagers = qFindChildren(manager); + QListIterator itInt(intPropertyManagers); + while (itInt.hasNext()) + d_ptr->m_spinBoxFactory->addPropertyManager(itInt.next()); + + QList doublePropertyManagers = qFindChildren(manager); + QListIterator itDouble(doublePropertyManagers); + while (itDouble.hasNext()) + d_ptr->m_doubleSpinBoxFactory->addPropertyManager(itDouble.next()); + + QList boolPropertyManagers = qFindChildren(manager); + QListIterator itBool(boolPropertyManagers); + while (itBool.hasNext()) + d_ptr->m_checkBoxFactory->addPropertyManager(itBool.next()); + + QList stringPropertyManagers = qFindChildren(manager); + QListIterator itString(stringPropertyManagers); + while (itString.hasNext()) + d_ptr->m_lineEditFactory->addPropertyManager(itString.next()); + + QList datePropertyManagers = qFindChildren(manager); + QListIterator itDate(datePropertyManagers); + while (itDate.hasNext()) + d_ptr->m_dateEditFactory->addPropertyManager(itDate.next()); + + QList timePropertyManagers = qFindChildren(manager); + QListIterator itTime(timePropertyManagers); + while (itTime.hasNext()) + d_ptr->m_timeEditFactory->addPropertyManager(itTime.next()); + + QList dateTimePropertyManagers = qFindChildren(manager); + QListIterator itDateTime(dateTimePropertyManagers); + while (itDateTime.hasNext()) + d_ptr->m_dateTimeEditFactory->addPropertyManager(itDateTime.next()); + + QList keySequencePropertyManagers = qFindChildren(manager); + QListIterator itKeySequence(keySequencePropertyManagers); + while (itKeySequence.hasNext()) + d_ptr->m_keySequenceEditorFactory->addPropertyManager(itKeySequence.next()); + + QList charPropertyManagers = qFindChildren(manager); + QListIterator itChar(charPropertyManagers); + while (itChar.hasNext()) + d_ptr->m_charEditorFactory->addPropertyManager(itChar.next()); + + QList localePropertyManagers = qFindChildren(manager); + QListIterator itLocale(localePropertyManagers); + while (itLocale.hasNext()) + d_ptr->m_comboBoxFactory->addPropertyManager(itLocale.next()->subEnumPropertyManager()); + + QList pointPropertyManagers = qFindChildren(manager); + QListIterator itPoint(pointPropertyManagers); + while (itPoint.hasNext()) + d_ptr->m_spinBoxFactory->addPropertyManager(itPoint.next()->subIntPropertyManager()); + + QList pointFPropertyManagers = qFindChildren(manager); + QListIterator itPointF(pointFPropertyManagers); + while (itPointF.hasNext()) + d_ptr->m_doubleSpinBoxFactory->addPropertyManager(itPointF.next()->subDoublePropertyManager()); + + QList sizePropertyManagers = qFindChildren(manager); + QListIterator itSize(sizePropertyManagers); + while (itSize.hasNext()) + d_ptr->m_spinBoxFactory->addPropertyManager(itSize.next()->subIntPropertyManager()); + + QList sizeFPropertyManagers = qFindChildren(manager); + QListIterator itSizeF(sizeFPropertyManagers); + while (itSizeF.hasNext()) + d_ptr->m_doubleSpinBoxFactory->addPropertyManager(itSizeF.next()->subDoublePropertyManager()); + + QList rectPropertyManagers = qFindChildren(manager); + QListIterator itRect(rectPropertyManagers); + while (itRect.hasNext()) + d_ptr->m_spinBoxFactory->addPropertyManager(itRect.next()->subIntPropertyManager()); + + QList rectFPropertyManagers = qFindChildren(manager); + QListIterator itRectF(rectFPropertyManagers); + while (itRectF.hasNext()) + d_ptr->m_doubleSpinBoxFactory->addPropertyManager(itRectF.next()->subDoublePropertyManager()); + + QList colorPropertyManagers = qFindChildren(manager); + QListIterator itColor(colorPropertyManagers); + while (itColor.hasNext()) { + QtColorPropertyManager *manager = itColor.next(); + d_ptr->m_colorEditorFactory->addPropertyManager(manager); + d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager()); + } + + QList enumPropertyManagers = qFindChildren(manager); + QListIterator itEnum(enumPropertyManagers); + while (itEnum.hasNext()) + d_ptr->m_comboBoxFactory->addPropertyManager(itEnum.next()); + + QList sizePolicyPropertyManagers = qFindChildren(manager); + QListIterator itSizePolicy(sizePolicyPropertyManagers); + while (itSizePolicy.hasNext()) { + QtSizePolicyPropertyManager *manager = itSizePolicy.next(); + d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager()); + d_ptr->m_comboBoxFactory->addPropertyManager(manager->subEnumPropertyManager()); + } + + QList fontPropertyManagers = qFindChildren(manager); + QListIterator itFont(fontPropertyManagers); + while (itFont.hasNext()) { + QtFontPropertyManager *manager = itFont.next(); + d_ptr->m_fontEditorFactory->addPropertyManager(manager); + d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager()); + d_ptr->m_comboBoxFactory->addPropertyManager(manager->subEnumPropertyManager()); + d_ptr->m_checkBoxFactory->addPropertyManager(manager->subBoolPropertyManager()); + } + + QList cursorPropertyManagers = qFindChildren(manager); + QListIterator itCursor(cursorPropertyManagers); + while (itCursor.hasNext()) + d_ptr->m_cursorEditorFactory->addPropertyManager(itCursor.next()); + + QList flagPropertyManagers = qFindChildren(manager); + QListIterator itFlag(flagPropertyManagers); + while (itFlag.hasNext()) + d_ptr->m_checkBoxFactory->addPropertyManager(itFlag.next()->subBoolPropertyManager()); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtVariantEditorFactory::createEditor(QtVariantPropertyManager *manager, QtProperty *property, + QWidget *parent) +{ + const int propType = manager->propertyType(property); + QtAbstractEditorFactoryBase *factory = d_ptr->m_typeToFactory.value(propType, 0); + if (!factory) + return 0; + return factory->createEditor(wrappedProperty(property), parent); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtVariantEditorFactory::disconnectPropertyManager(QtVariantPropertyManager *manager) +{ + QList intPropertyManagers = qFindChildren(manager); + QListIterator itInt(intPropertyManagers); + while (itInt.hasNext()) + d_ptr->m_spinBoxFactory->removePropertyManager(itInt.next()); + + QList doublePropertyManagers = qFindChildren(manager); + QListIterator itDouble(doublePropertyManagers); + while (itDouble.hasNext()) + d_ptr->m_doubleSpinBoxFactory->removePropertyManager(itDouble.next()); + + QList boolPropertyManagers = qFindChildren(manager); + QListIterator itBool(boolPropertyManagers); + while (itBool.hasNext()) + d_ptr->m_checkBoxFactory->removePropertyManager(itBool.next()); + + QList stringPropertyManagers = qFindChildren(manager); + QListIterator itString(stringPropertyManagers); + while (itString.hasNext()) + d_ptr->m_lineEditFactory->removePropertyManager(itString.next()); + + QList datePropertyManagers = qFindChildren(manager); + QListIterator itDate(datePropertyManagers); + while (itDate.hasNext()) + d_ptr->m_dateEditFactory->removePropertyManager(itDate.next()); + + QList timePropertyManagers = qFindChildren(manager); + QListIterator itTime(timePropertyManagers); + while (itTime.hasNext()) + d_ptr->m_timeEditFactory->removePropertyManager(itTime.next()); + + QList dateTimePropertyManagers = qFindChildren(manager); + QListIterator itDateTime(dateTimePropertyManagers); + while (itDateTime.hasNext()) + d_ptr->m_dateTimeEditFactory->removePropertyManager(itDateTime.next()); + + QList keySequencePropertyManagers = qFindChildren(manager); + QListIterator itKeySequence(keySequencePropertyManagers); + while (itKeySequence.hasNext()) + d_ptr->m_keySequenceEditorFactory->removePropertyManager(itKeySequence.next()); + + QList charPropertyManagers = qFindChildren(manager); + QListIterator itChar(charPropertyManagers); + while (itChar.hasNext()) + d_ptr->m_charEditorFactory->removePropertyManager(itChar.next()); + + QList localePropertyManagers = qFindChildren(manager); + QListIterator itLocale(localePropertyManagers); + while (itLocale.hasNext()) + d_ptr->m_comboBoxFactory->removePropertyManager(itLocale.next()->subEnumPropertyManager()); + + QList pointPropertyManagers = qFindChildren(manager); + QListIterator itPoint(pointPropertyManagers); + while (itPoint.hasNext()) + d_ptr->m_spinBoxFactory->removePropertyManager(itPoint.next()->subIntPropertyManager()); + + QList pointFPropertyManagers = qFindChildren(manager); + QListIterator itPointF(pointFPropertyManagers); + while (itPointF.hasNext()) + d_ptr->m_doubleSpinBoxFactory->removePropertyManager(itPointF.next()->subDoublePropertyManager()); + + QList sizePropertyManagers = qFindChildren(manager); + QListIterator itSize(sizePropertyManagers); + while (itSize.hasNext()) + d_ptr->m_spinBoxFactory->removePropertyManager(itSize.next()->subIntPropertyManager()); + + QList sizeFPropertyManagers = qFindChildren(manager); + QListIterator itSizeF(sizeFPropertyManagers); + while (itSizeF.hasNext()) + d_ptr->m_doubleSpinBoxFactory->removePropertyManager(itSizeF.next()->subDoublePropertyManager()); + + QList rectPropertyManagers = qFindChildren(manager); + QListIterator itRect(rectPropertyManagers); + while (itRect.hasNext()) + d_ptr->m_spinBoxFactory->removePropertyManager(itRect.next()->subIntPropertyManager()); + + QList rectFPropertyManagers = qFindChildren(manager); + QListIterator itRectF(rectFPropertyManagers); + while (itRectF.hasNext()) + d_ptr->m_doubleSpinBoxFactory->removePropertyManager(itRectF.next()->subDoublePropertyManager()); + + QList colorPropertyManagers = qFindChildren(manager); + QListIterator itColor(colorPropertyManagers); + while (itColor.hasNext()) { + QtColorPropertyManager *manager = itColor.next(); + d_ptr->m_colorEditorFactory->removePropertyManager(manager); + d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager()); + } + + QList enumPropertyManagers = qFindChildren(manager); + QListIterator itEnum(enumPropertyManagers); + while (itEnum.hasNext()) + d_ptr->m_comboBoxFactory->removePropertyManager(itEnum.next()); + + QList sizePolicyPropertyManagers = qFindChildren(manager); + QListIterator itSizePolicy(sizePolicyPropertyManagers); + while (itSizePolicy.hasNext()) { + QtSizePolicyPropertyManager *manager = itSizePolicy.next(); + d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager()); + d_ptr->m_comboBoxFactory->removePropertyManager(manager->subEnumPropertyManager()); + } + + QList fontPropertyManagers = qFindChildren(manager); + QListIterator itFont(fontPropertyManagers); + while (itFont.hasNext()) { + QtFontPropertyManager *manager = itFont.next(); + d_ptr->m_fontEditorFactory->removePropertyManager(manager); + d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager()); + d_ptr->m_comboBoxFactory->removePropertyManager(manager->subEnumPropertyManager()); + d_ptr->m_checkBoxFactory->removePropertyManager(manager->subBoolPropertyManager()); + } + + QList cursorPropertyManagers = qFindChildren(manager); + QListIterator itCursor(cursorPropertyManagers); + while (itCursor.hasNext()) + d_ptr->m_cursorEditorFactory->removePropertyManager(itCursor.next()); + + QList flagPropertyManagers = qFindChildren(manager); + QListIterator itFlag(flagPropertyManagers); + while (itFlag.hasNext()) + d_ptr->m_checkBoxFactory->removePropertyManager(itFlag.next()->subBoolPropertyManager()); +} + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +#include "moc_qtvariantproperty.cxx" diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtvariantproperty.h b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtvariantproperty.h new file mode 100644 index 000000000..9f20d3dd4 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtvariantproperty.h @@ -0,0 +1,232 @@ +/**************************************************************************** +** +** This file is part of a Qt Solutions component. +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTVARIANTPROPERTY_H +#define QTVARIANTPROPERTY_H + +#include "qtpropertybrowser.h" +#include +#include + +#if QT_VERSION >= 0x040400 +QT_BEGIN_NAMESPACE +#endif + +typedef QMap QtIconMap; + +class QtVariantPropertyManager; +class QtVariantPropertyPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtVariantProperty : public QtProperty +{ +public: + ~QtVariantProperty(); + QVariant value() const; + QVariant attributeValue(const QString &attribute) const; + int valueType() const; + int propertyType() const; + + void setValue(const QVariant &value); + void setAttribute(const QString &attribute, const QVariant &value); +protected: + QtVariantProperty(QtVariantPropertyManager *manager); +private: + friend class QtVariantPropertyManager; + QtVariantPropertyPrivate *d_ptr; +}; + +class QtVariantPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtVariantPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtVariantPropertyManager(QObject *parent = 0); + ~QtVariantPropertyManager(); + + virtual QtVariantProperty *addProperty(int propertyType, const QString &name = QString()); + + int propertyType(const QtProperty *property) const; + int valueType(const QtProperty *property) const; + QtVariantProperty *variantProperty(const QtProperty *property) const; + + virtual bool isPropertyTypeSupported(int propertyType) const; + virtual int valueType(int propertyType) const; + virtual QStringList attributes(int propertyType) const; + virtual int attributeType(int propertyType, const QString &attribute) const; + + virtual QVariant value(const QtProperty *property) const; + virtual QVariant attributeValue(const QtProperty *property, const QString &attribute) const; + + static int enumTypeId(); + static int flagTypeId(); + static int groupTypeId(); + static int iconMapTypeId(); +public Q_SLOTS: + virtual void setValue(QtProperty *property, const QVariant &val); + virtual void setAttribute(QtProperty *property, + const QString &attribute, const QVariant &value); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QVariant &val); + void attributeChanged(QtProperty *property, + const QString &attribute, const QVariant &val); +protected: + virtual bool hasValue(const QtProperty *property) const; + QString valueText(const QtProperty *property) const; + QIcon valueIcon(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property); + virtual void uninitializeProperty(QtProperty *property); + virtual QtProperty *createProperty(); +private: + QtVariantPropertyManagerPrivate *d_ptr; + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, int, int)) + Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, double)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, double, double)) + Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, double)) + Q_PRIVATE_SLOT(d_func(), void slotDecimalsChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, bool)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QString &)) + Q_PRIVATE_SLOT(d_func(), void slotRegExpChanged(QtProperty *, const QRegExp &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QDate &)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, const QDate &, const QDate &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QTime &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QDateTime &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QKeySequence &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QChar &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QLocale &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QPoint &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QPointF &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QSize &)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, const QSize &, const QSize &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QSizeF &)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, const QSizeF &, const QSizeF &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QRect &)) + Q_PRIVATE_SLOT(d_func(), void slotConstraintChanged(QtProperty *, const QRect &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QRectF &)) + Q_PRIVATE_SLOT(d_func(), void slotConstraintChanged(QtProperty *, const QRectF &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QColor &)) + Q_PRIVATE_SLOT(d_func(), void slotEnumNamesChanged(QtProperty *, const QStringList &)) + Q_PRIVATE_SLOT(d_func(), void slotEnumIconsChanged(QtProperty *, const QMap &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QSizePolicy &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QFont &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QCursor &)) + Q_PRIVATE_SLOT(d_func(), void slotFlagNamesChanged(QtProperty *, const QStringList &)) + + Q_PRIVATE_SLOT(d_func(), void slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyRemoved(QtProperty *, QtProperty *)) + Q_DECLARE_PRIVATE(QtVariantPropertyManager) + Q_DISABLE_COPY(QtVariantPropertyManager) +}; + +class QtVariantEditorFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtVariantEditorFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtVariantEditorFactory(QObject *parent = 0); + ~QtVariantEditorFactory(); +protected: + void connectPropertyManager(QtVariantPropertyManager *manager); + QWidget *createEditor(QtVariantPropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtVariantPropertyManager *manager); +private: + QtVariantEditorFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtVariantEditorFactory) + Q_DISABLE_COPY(QtVariantEditorFactory) +}; + +#if QT_VERSION >= 0x040400 +QT_END_NAMESPACE +#endif + +Q_DECLARE_METATYPE(QIcon) +Q_DECLARE_METATYPE(QtIconMap) +#endif diff --git a/code/nel/tools/3d/object_viewer_qt/src/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/CMakeLists.txt index 3cbe745af..7dc1445bb 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/CMakeLists.txt @@ -1,3 +1,5 @@ +ADD_SUBDIRECTORY(3rdparty) + INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${LIBXML2_INCLUDE_DIR} ${NEL_INCLUDE_DIR} ${QT_INCLUDES}) INCLUDE( ${QT_USE_FILE} ) diff --git a/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin.h b/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin.h index fc2e0736b..973f80e14 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin.h +++ b/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin.h @@ -95,16 +95,10 @@ public: @endcode */ virtual void setNelContext(NLMISC::INelContext *nelContext) = 0; - - virtual QString name() const = 0; - virtual QString version() const = 0; - virtual QString vendor() const = 0; - virtual QString description() const = 0; - virtual QStringList dependencies() const = 0; }; }; //namespace ExtensionSystem -Q_DECLARE_INTERFACE(ExtensionSystem::IPlugin, "dev.ryzom.com.ObjectViewerQt.IPlugin/0.9.1") +Q_DECLARE_INTERFACE(ExtensionSystem::IPlugin, "dev.ryzom.com.ObjectViewerQt.IPlugin/0.9.2") #endif // IPLUGIN_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin_manager.h b/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin_manager.h index 05d4b832c..e38748e77 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin_manager.h +++ b/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin_manager.h @@ -98,7 +98,7 @@ public: { QList all = allObjects(); QObject *result = 0; - Q_FOREACH (QObject *qobj, all) + Q_FOREACH(QObject *qobj, all) { if (qobj->objectName() == name) { diff --git a/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin_spec.h b/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin_spec.h index f0c62fec7..2aefbb894 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin_spec.h +++ b/code/nel/tools/3d/object_viewer_qt/src/extension_system/iplugin_spec.h @@ -37,8 +37,8 @@ struct State { Invalid = 1, Read, - Loaded, Resolved, + Loaded, Initialized, Running, Stopped, @@ -71,9 +71,13 @@ public: virtual IPlugin *plugin() const = 0; // state - virtual int getState() const = 0; + virtual int state() const = 0; virtual bool hasError() const = 0; virtual QString errorString() const = 0; + + /// Enables/disables load this plugin after restart the program + virtual void setEnabled(bool enabled) = 0; + virtual bool isEnabled() const = 0; }; } // namespace ExtensionSystem diff --git a/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_manager.cpp b/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_manager.cpp index be5f18c74..8be6fcd93 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_manager.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_manager.cpp @@ -26,20 +26,22 @@ namespace ExtensionSystem { -CPluginManager::CPluginManager(QObject *parent) +PluginManager::PluginManager(QObject *parent) :IPluginManager(parent), - m_settings(0) + m_settings(0), + m_extension("xml") { } -CPluginManager::~CPluginManager() +PluginManager::~PluginManager() { + writeSettings(); stopAll(); deleteAll(); qDeleteAll(m_pluginSpecs); } -void CPluginManager::addObject(QObject *obj) +void PluginManager::addObject(QObject *obj) { QWriteLocker lock(&m_lock); if (obj == 0) @@ -59,7 +61,7 @@ void CPluginManager::addObject(QObject *obj) Q_EMIT objectAdded(obj); } -void CPluginManager::removeObject(QObject *obj) +void PluginManager::removeObject(QObject *obj) { if (obj == 0) { @@ -79,25 +81,25 @@ void CPluginManager::removeObject(QObject *obj) m_allObjects.removeAll(obj); } -QList CPluginManager::allObjects() const +QList PluginManager::allObjects() const { return m_allObjects; } -void CPluginManager::loadPlugins() +void PluginManager::loadPlugins() { - Q_FOREACH (CPluginSpec *spec, m_pluginSpecs) - setPluginState(spec, State::Loaded); - - Q_FOREACH (CPluginSpec *spec, m_pluginSpecs) + Q_FOREACH (PluginSpec *spec, m_pluginSpecs) setPluginState(spec, State::Resolved); - QList queue = loadQueue(); + QList queue = loadQueue(); - Q_FOREACH (CPluginSpec *spec, queue) + Q_FOREACH (PluginSpec *spec, queue) + setPluginState(spec, State::Loaded); + + Q_FOREACH (PluginSpec *spec, queue) setPluginState(spec, State::Initialized); - QListIterator it(queue); + QListIterator it(queue); it.toBack(); while (it.hasPrevious()) setPluginState(it.previous(), State::Running); @@ -105,41 +107,72 @@ void CPluginManager::loadPlugins() Q_EMIT pluginsChanged(); } -QStringList CPluginManager::getPluginPaths() const +QStringList PluginManager::getPluginPaths() const { return m_pluginPaths; } -void CPluginManager::setPluginPaths(const QStringList &paths) +void PluginManager::setPluginPaths(const QStringList &paths) { m_pluginPaths = paths; readPluginPaths(); + readSettings(); } -QList CPluginManager::plugins() const +QList PluginManager::plugins() const { return m_ipluginSpecs; } -void CPluginManager::setSettings(QSettings *settings) +void PluginManager::setSettings(QSettings *settings) { m_settings = settings; } -QSettings *CPluginManager::settings() const +QSettings *PluginManager::settings() const { return m_settings; } -void CPluginManager::readSettings() +void PluginManager::readSettings() { + if (m_settings) + { + QStringList blackList; + m_settings->beginGroup("PluginManager"); + blackList = m_settings->value("BlackList").toStringList(); + m_settings->endGroup(); + Q_FOREACH (PluginSpec *spec, m_pluginSpecs) + { + QString pluginName = spec->fileName(); + + if (blackList.contains(pluginName)) + { + spec->setEnabled(false); + spec->setEnabledStartup(false); + } + } + } } -void CPluginManager::writeSettings() +void PluginManager::writeSettings() { + if (m_settings) + { + QStringList blackList; + Q_FOREACH(PluginSpec *spec, m_pluginSpecs) + { + if (!spec->isEnabled()) + blackList.push_back(spec->fileName()); + } + m_settings->beginGroup("PluginManager"); + m_settings->setValue("BlackList", blackList); + m_settings->endGroup(); + m_settings->sync(); + } } -void CPluginManager::readPluginPaths() +void PluginManager::readPluginPaths() { qDeleteAll(m_pluginSpecs); m_pluginSpecs.clear(); @@ -150,11 +183,7 @@ void CPluginManager::readPluginPaths() while (!searchPaths.isEmpty()) { const QDir dir(searchPaths.takeFirst()); -#ifdef Q_OS_WIN - const QFileInfoList files = dir.entryInfoList(QStringList() << QString("ovqt_plugin_*.dll"), QDir::Files); -#else - const QFileInfoList files = dir.entryInfoList(QStringList() << QString("libovqt_plugin_*.so"), QDir::Files); -#endif + const QFileInfoList files = dir.entryInfoList(QStringList() << QString("ovqt_plugin_*.%1").arg(m_extension), QDir::Files); Q_FOREACH (const QFileInfo &file, files) pluginsList << file.absoluteFilePath(); const QFileInfoList dirs = dir.entryInfoList(QDir::Dirs|QDir::NoDotAndDotDot); @@ -164,9 +193,9 @@ void CPluginManager::readPluginPaths() Q_FOREACH (const QString &pluginFile, pluginsList) { - CPluginSpec *spec = new CPluginSpec; - spec->setFileName(pluginFile); + PluginSpec *spec = new PluginSpec; spec->m_pluginManager = this; + spec->setSpecFileName(pluginFile); m_pluginSpecs.append(spec); m_ipluginSpecs.append(spec); } @@ -174,16 +203,17 @@ void CPluginManager::readPluginPaths() Q_EMIT pluginsChanged(); } -void CPluginManager::setPluginState(CPluginSpec *spec, int destState) +void PluginManager::setPluginState(PluginSpec *spec, int destState) { - if (spec->hasError() || spec->getState() != destState-1) + if (spec->hasError() || spec->state() != destState-1) + return; + + // plugin in black list + if (!spec->isEnabledStartup()) return; switch (destState) { - case State::Loaded: - spec->loadLibrary(); - return; case State::Resolved: spec->resolveDependencies(m_pluginSpecs); return; @@ -196,18 +226,21 @@ void CPluginManager::setPluginState(CPluginSpec *spec, int destState) default: break; } - Q_FOREACH (const CPluginSpec *depSpec, spec->dependencySpecs()) + Q_FOREACH (const PluginSpec *depSpec, spec->dependencySpecs()) { - if (depSpec->getState() != destState) + if (depSpec->state() != destState) { spec->m_hasError = true; - spec->m_errorString = tr("Cannot initializing plugin because dependency failed to load: %1\nReason: %2") - .arg(depSpec->name()).arg(depSpec->errorString()); + spec->m_errorString = tr("Cannot load plugin because dependency failed to load: %1") + .arg(depSpec->name()); return; } } switch (destState) { + case State::Loaded: + spec->loadLibrary(); + return; case State::Initialized: spec->initializePlugin(); break; @@ -219,19 +252,19 @@ void CPluginManager::setPluginState(CPluginSpec *spec, int destState) } } -QList CPluginManager::loadQueue() +QList PluginManager::loadQueue() { - QList queue; - Q_FOREACH(CPluginSpec *spec, m_pluginSpecs) + QList queue; + Q_FOREACH(PluginSpec *spec, m_pluginSpecs) { - QList circularityCheckQueue; + QList circularityCheckQueue; loadQueue(spec, queue, circularityCheckQueue); } return queue; } -bool CPluginManager::loadQueue(CPluginSpec *spec, QList &queue, - QList &circularityCheckQueue) +bool PluginManager::loadQueue(PluginSpec *spec, QList &queue, + QList &circularityCheckQueue) { if (queue.contains(spec)) return true; @@ -251,14 +284,14 @@ bool CPluginManager::loadQueue(CPluginSpec *spec, QList &queue, } circularityCheckQueue.append(spec); // check if we have the dependencies - if (spec->getState() == State::Invalid || spec->getState() == State::Read) + if (spec->state() == State::Invalid || spec->state() == State::Read) { queue.append(spec); return false; } // add dependencies - Q_FOREACH (CPluginSpec *depSpec, spec->dependencySpecs()) + Q_FOREACH (PluginSpec *depSpec, spec->dependencySpecs()) { if (!loadQueue(depSpec, queue, circularityCheckQueue)) { @@ -274,17 +307,17 @@ bool CPluginManager::loadQueue(CPluginSpec *spec, QList &queue, return true; } -void CPluginManager::stopAll() +void PluginManager::stopAll() { - QList queue = loadQueue(); - Q_FOREACH (CPluginSpec *spec, queue) + QList queue = loadQueue(); + Q_FOREACH (PluginSpec *spec, queue) setPluginState(spec, State::Stopped); } -void CPluginManager::deleteAll() +void PluginManager::deleteAll() { - QList queue = loadQueue(); - QListIterator it(queue); + QList queue = loadQueue(); + QListIterator it(queue); it.toBack(); while (it.hasPrevious()) { diff --git a/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_manager.h b/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_manager.h index 4ef3b2208..9ab1ae135 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_manager.h +++ b/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_manager.h @@ -29,15 +29,15 @@ namespace ExtensionSystem { class IPlugin; -class CPluginSpec; +class PluginSpec; -class CPluginManager : public IPluginManager +class PluginManager : public IPluginManager { Q_OBJECT public: - CPluginManager(QObject *parent = 0); - ~CPluginManager(); + PluginManager(QObject *parent = 0); + ~PluginManager(); // Object pool operations virtual void addObject(QObject *obj); @@ -49,7 +49,7 @@ public: virtual QStringList getPluginPaths() const; virtual void setPluginPaths(const QStringList &paths); virtual QList plugins() const; - QList loadQueue(); + QList loadQueue(); // Settings virtual void setSettings(QSettings *settings); @@ -58,21 +58,22 @@ public: void writeSettings(); private: - void setPluginState(CPluginSpec *spec, int destState); + void setPluginState(PluginSpec *spec, int destState); void readPluginPaths(); - bool loadQueue(CPluginSpec *spec, QList &queue, QList &circularityCheckQueue); + bool loadQueue(PluginSpec *spec, QList &queue, QList &circularityCheckQueue); void stopAll(); void deleteAll(); mutable QReadWriteLock m_lock; QSettings *m_settings; - QList m_pluginSpecs; + QString m_extension; + QList m_pluginSpecs; QList m_ipluginSpecs; QStringList m_pluginPaths; QList m_allObjects; -}; // class CPluginManager +}; // class PluginManager } // namespace ExtensionSystem diff --git a/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_spec.cpp b/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_spec.cpp index d77d90962..1e3ec0182 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_spec.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_spec.cpp @@ -16,12 +16,15 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . +// Project includes #include "plugin_spec.h" #include "iplugin.h" #include "iplugin_manager.h" #include "nel/misc/app_context.h" +#include "nel/misc/debug.h" +// Qt includes #include #include #include @@ -30,8 +33,17 @@ namespace ExtensionSystem { +const char *const PLUGIN_SPEC_NAME = "name"; +const char *const PLUGIN_SPEC_VENDOR = "vendor"; +const char *const PLUGIN_SPEC_VERSION = "version"; +const char *const PLUGIN_SPEC_LIBRARY_NAME = "library-name"; +const char *const PLUGIN_SPEC_DESCRIPTION = "description"; +const char *const PLUGIN_SPEC_DEPENDENCIES = "dependencies"; +const char *const PLUGIN_SPEC_DEPENDENCY = "dependency"; +const char *const PLUGIN_SPEC_DEPENDENCY_NAME = "plugin-name"; +const char *const PLUGIN_SPEC_DEPENDENCY_VERSION = "version"; -CPluginSpec::CPluginSpec() +PluginSpec::PluginSpec() : m_location(""), m_filePath(""), m_fileName(""), @@ -39,100 +51,210 @@ CPluginSpec::CPluginSpec() m_version(""), m_vendor(""), m_description(""), + m_nameSpecFile(""), + m_suffix(""), m_state(State::Invalid), + m_enabled(true), + m_enabledStartup(true), m_hasError(false), m_errorString(""), m_plugin(0), m_pluginManager(0) { +// Compilation mode specific suffixes +#ifdef NL_OS_WINDOWS +# if defined(NL_DEBUG) + m_suffix = "_d.dll"; +# elif defined(NL_RELEASE) + m_suffix = "_r.dll"; +# else +# error "Unknown compilation mode, can't build suffix" +# endif +#elif defined (NL_OS_UNIX) + m_suffix = ".so"; +#else +# error "You must define the lib suffix for your platform" +#endif } -QString CPluginSpec::name() const +QString PluginSpec::name() const { return m_name; } -QString CPluginSpec::version() const +QString PluginSpec::version() const { return m_version; } -QString CPluginSpec::vendor() const +QString PluginSpec::vendor() const { return m_vendor; } -QString CPluginSpec::description() const +QString PluginSpec::description() const { return m_description; } -QString CPluginSpec::location() const +QString PluginSpec::location() const { return m_location; } -QString CPluginSpec::filePath() const +QString PluginSpec::filePath() const { return m_filePath; } -QString CPluginSpec::fileName() const +QString PluginSpec::fileName() const { return m_fileName; } -IPlugin* CPluginSpec::plugin() const +IPlugin *PluginSpec::plugin() const { return m_plugin; } -int CPluginSpec::getState() const +int PluginSpec::state() const { return m_state; } -bool CPluginSpec::hasError() const +bool PluginSpec::hasError() const { return m_hasError; } -QString CPluginSpec::errorString() const +QString PluginSpec::errorString() const { return m_errorString; } -QList CPluginSpec::dependencySpecs() const +QList PluginSpec::dependencySpecs() const { return m_dependencySpecs; } -bool CPluginSpec::setFileName(const QString &fileName) +bool PluginSpec::setFileName(const QString &fileName) { - QFile file(fileName); + m_fileName = fileName + m_suffix; + m_filePath = m_location + "/" + m_fileName; + + nlinfo(m_filePath.toStdString().c_str()); + QFile file(m_filePath); if (!file.exists()) - return reportError(QCoreApplication::translate("CPluginSpec", "File does not exist: %1").arg(file.fileName())); + return reportError(QCoreApplication::translate("PluginSpec", "File does not exist: %1").arg(file.fileName())); if (!file.open(QIODevice::ReadOnly)) - return reportError(QCoreApplication::translate("CPluginSpec", "Could not open file for read: %1").arg(file.fileName())); + return reportError(QCoreApplication::translate("PluginSpec", "Could not open file for read: %1").arg(file.fileName())); + return true; +} + +bool PluginSpec::setSpecFileName(const QString &specFileName) +{ + m_nameSpecFile = specFileName; + + QFile file(specFileName); + if (!file.exists()) + return reportError(QCoreApplication::translate("PluginSpec", "Spec file does not exist: %1").arg(file.fileName())); QFileInfo fileInfo(file); m_location = fileInfo.absolutePath(); - m_filePath = fileInfo.absoluteFilePath(); - m_fileName = fileInfo.fileName(); + readSpec(); + return true; +} +bool PluginSpec::readSpec() +{ + QFile file(m_nameSpecFile); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + return reportError(QCoreApplication::translate("PluginSpec", "Could not open spec file for read: %1").arg(file.fileName())); + + QXmlStreamReader reader(&file); + while (!reader.atEnd()) + { + if (reader.isStartElement()) + parseSpec(reader); + reader.readNext(); + } + if (reader.hasError()) + return reportError(QCoreApplication::translate("PluginSpec", "Error parsing file %1: %2, at line %3, column %4") + .arg(file.fileName()) + .arg(reader.errorString()) + .arg(reader.lineNumber()) + .arg(reader.columnNumber())); m_state = State::Read; return true; } -bool CPluginSpec::loadLibrary() +void PluginSpec::parseSpec(QXmlStreamReader &reader) +{ + QString elemName = reader.name().toString(); + reader.readNext(); + if (reader.isCharacters()) + { + QString elemText = reader.text().toString(); + if (elemName == PLUGIN_SPEC_LIBRARY_NAME) + setFileName(elemText); + if (elemName == PLUGIN_SPEC_NAME) + m_name = elemText; + if (elemName == PLUGIN_SPEC_VERSION) + m_version = elemText; + if (elemName == PLUGIN_SPEC_VENDOR) + m_vendor = elemText; + if (elemName == PLUGIN_SPEC_DESCRIPTION) + m_description = elemText; + if (elemName == PLUGIN_SPEC_DEPENDENCIES) + parseDependency(reader); + } +} + +void PluginSpec::parseDependency(QXmlStreamReader &reader) +{ + QString elemName; + while (!reader.atEnd() && (elemName != PLUGIN_SPEC_DEPENDENCIES)) + { + reader.readNext(); + elemName = reader.name().toString(); + if (reader.isStartElement() && (elemName == PLUGIN_SPEC_DEPENDENCY)) + { + // Read name dependency plugin + QString dependencyName = reader.attributes().value(PLUGIN_SPEC_DEPENDENCY_NAME).toString(); + if (dependencyName.isEmpty()) + { + reader.raiseError(QCoreApplication::translate("CPluginSpec", "'%1' misses attribute '%2'") + .arg(PLUGIN_SPEC_DEPENDENCY) + .arg(PLUGIN_SPEC_DEPENDENCY_NAME)); + return; + } + // TODO: Read version dependency plugin + QString dependencyVersion = reader.attributes().value(PLUGIN_SPEC_DEPENDENCY_VERSION).toString(); + + m_dependencies.push_back(dependencyName); + } + } +} + +void PluginSpec::setEnabled(bool enabled) +{ + m_enabled = enabled; +} + +bool PluginSpec::isEnabled() const +{ + return m_enabled; +} + +bool PluginSpec::loadLibrary() { if (m_hasError) return false; - if (m_state != State::Read) + if (m_state != State::Resolved) { if (m_state == State::Loaded) return true; - return reportError(QCoreApplication::translate("CPluginSpec", "Loading the library failed because state != Resolved")); + return reportError(QCoreApplication::translate("PluginSpec", "Loading the library failed because state != Resolved")); } QPluginLoader loader(m_filePath); @@ -143,38 +265,32 @@ bool CPluginSpec::loadLibrary() if (!pluginObject) { loader.unload(); - return reportError(QCoreApplication::translate("CPluginSpec", "Plugin is not valid (does not derive from IPlugin)")); + return reportError(QCoreApplication::translate("PluginSpec", "Plugin is not valid (does not derive from IPlugin)")); } pluginObject->setNelContext(&NLMISC::INelContext::getInstance()); - m_name = pluginObject->name(); - m_version = pluginObject->version(); - m_vendor = pluginObject->vendor(); - m_description = pluginObject->description(); - m_state = State::Loaded; m_plugin = pluginObject; return true; } -bool CPluginSpec::resolveDependencies(const QList &specs) +bool PluginSpec::resolveDependencies(const QList &specs) { if (m_hasError) return false; - if (m_state != State::Loaded) + if (m_state != State::Read) { - m_errorString = QCoreApplication::translate("CPluginSpec", "Resolving dependencies failed because state != Read"); + m_errorString = QCoreApplication::translate("PluginSpec", "Resolving dependencies failed because state != Read"); m_hasError = true; return false; } - QList resolvedDependencies; - QStringList dependencies = m_plugin->dependencies(); - Q_FOREACH(const QString &dependency, dependencies) + QList resolvedDependencies; + Q_FOREACH(const QString &dependency, m_dependencies) { - CPluginSpec *found = 0; + PluginSpec *found = 0; - Q_FOREACH(CPluginSpec *spec, specs) + Q_FOREACH(PluginSpec *spec, specs) { if (QString::compare(dependency, spec->name(), Qt::CaseInsensitive) == 0) { @@ -187,7 +303,7 @@ bool CPluginSpec::resolveDependencies(const QList &specs) m_hasError = true; if (!m_errorString.isEmpty()) m_errorString.append(QLatin1Char('\n')); - m_errorString.append(QCoreApplication::translate("CPluginSpec", "Could not resolve dependency '%1'") + m_errorString.append(QCoreApplication::translate("PluginSpec", "Could not resolve dependency '%1'") .arg(dependency)); continue; } @@ -197,34 +313,32 @@ bool CPluginSpec::resolveDependencies(const QList &specs) return false; m_dependencySpecs = resolvedDependencies; - m_state = State::Resolved; - return true; } -bool CPluginSpec::initializePlugin() +bool PluginSpec::initializePlugin() { if (m_hasError) return false; - if (m_state != State::Resolved) + if (m_state != State::Loaded) { if (m_state == State::Initialized) return true; - return reportError(QCoreApplication::translate("CPluginSpec", "Initializing the plugin failed because state != Resolved)")); + return reportError(QCoreApplication::translate("PluginSpec", "Initializing the plugin failed because state != Loaded)")); } if (!m_plugin) - return reportError(QCoreApplication::translate("CPluginSpec", "Internal error: have no plugin instance to initialize")); + return reportError(QCoreApplication::translate("PluginSpec", "Internal error: have no plugin instance to initialize")); QString err; if (!m_plugin->initialize(m_pluginManager, &err)) - return reportError(QCoreApplication::translate("CPluginSpec", "Plugin initialization failed: %1").arg(err)); + return reportError(QCoreApplication::translate("PluginSpec", "Plugin initialization failed: %1").arg(err)); m_state = State::Initialized; return true; } -bool CPluginSpec::initializeExtensions() +bool PluginSpec::initializeExtensions() { if (m_hasError) return false; @@ -232,17 +346,17 @@ bool CPluginSpec::initializeExtensions() { if (m_state == State::Running) return true; - return reportError(QCoreApplication::translate("CPluginSpec", "Cannot perform extensionsInitialized because state != Initialized")); + return reportError(QCoreApplication::translate("PluginSpec", "Cannot perform extensionsInitialized because state != Initialized")); } if (!m_plugin) - return reportError(QCoreApplication::translate("CPluginSpec", "Internal error: have no plugin instance to perform extensionsInitialized")); + return reportError(QCoreApplication::translate("PluginSpec", "Internal error: have no plugin instance to perform extensionsInitialized")); m_plugin->extensionsInitialized(); m_state = State::Running; return true; } -void CPluginSpec::stop() +void PluginSpec::stop() { if (!m_plugin) return; @@ -250,7 +364,7 @@ void CPluginSpec::stop() m_state = State::Stopped; } -void CPluginSpec::kill() +void PluginSpec::kill() { if (!m_plugin) return; @@ -259,7 +373,17 @@ void CPluginSpec::kill() m_state = State::Deleted; } -bool CPluginSpec::reportError(const QString &err) +void PluginSpec::setEnabledStartup(bool enabled) +{ + m_enabledStartup = enabled; +} + +bool PluginSpec::isEnabledStartup() const +{ + return m_enabledStartup; +} + +bool PluginSpec::reportError(const QString &err) { m_errorString = err; m_hasError = true; diff --git a/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_spec.h b/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_spec.h index 0cc895ada..c28980d69 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_spec.h +++ b/code/nel/tools/3d/object_viewer_qt/src/extension_system/plugin_spec.h @@ -21,12 +21,14 @@ #include "iplugin_spec.h" -#include "QtCore/QList" +#include +#include +#include namespace ExtensionSystem { -class CPluginSpec: public IPluginSpec +class PluginSpec: public IPluginSpec { public: virtual QString name() const; @@ -41,22 +43,35 @@ public: virtual IPlugin *plugin() const; // state - virtual int getState() const; + virtual int state() const; virtual bool hasError() const; virtual QString errorString() const; - QList dependencySpecs() const; + QList dependencySpecs() const; + + /// Enables/disables load this plugin after restart the program + virtual void setEnabled(bool enabled); + virtual bool isEnabled() const; private: - CPluginSpec(); + PluginSpec(); bool setFileName(const QString &fileName); + bool setSpecFileName(const QString &specFileName); + bool readSpec(); + void parseSpec(QXmlStreamReader &reader); + void parseDependency(QXmlStreamReader &reader); bool loadLibrary(); - bool resolveDependencies(const QList &specs); + bool resolveDependencies(const QList &specs); bool initializePlugin(); bool initializeExtensions(); void stop(); void kill(); + /// Enables/disables load this plugin on startup the program + /// Method is used for disabling startup plugin by pluginmanager + void setEnabledStartup(bool enabled); + bool isEnabledStartup() const; + bool reportError(const QString &err); QString m_location; @@ -68,15 +83,19 @@ private: QString m_vendor; QString m_description; + QString m_nameSpecFile; + QString m_suffix; int m_state; + bool m_enabled, m_enabledStartup; bool m_hasError; QString m_errorString; + QStringList m_dependencies; IPlugin *m_plugin; IPluginManager *m_pluginManager; - QList m_dependencySpecs; + QList m_dependencySpecs; - friend class CPluginManager; + friend class PluginManager; }; } // namespace ExtensionSystem diff --git a/code/nel/tools/3d/object_viewer_qt/src/main.cpp b/code/nel/tools/3d/object_viewer_qt/src/main.cpp index 15173fa5c..4b904bdc6 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/main.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/main.cpp @@ -124,6 +124,7 @@ sint main(int argc, char **argv) nlinfo("Welcome to NeL Object Viewer Qt!"); } + QApplication::setGraphicsSystem("raster"); QApplication app(argc, argv); QSplashScreen *splash = new QSplashScreen(); splash->setPixmap(QPixmap(":/images/nel_ide_load.png")); @@ -131,7 +132,7 @@ sint main(int argc, char **argv) QSettings::setDefaultFormat(QSettings::IniFormat); QSettings *settings = new QSettings(QSettings::IniFormat, QSettings::UserScope, - QLatin1String("RyzomCore"), QLatin1String(appNameC)); + QLatin1String("RyzomCore"), QLatin1String(appNameC)); QTranslator translator; QTranslator qtTranslator; @@ -147,7 +148,7 @@ sint main(int argc, char **argv) NLMISC::CLibrary::addLibPath((qApp->applicationDirPath() + QString("/../PlugIns/nel")).toStdString()); #endif - ExtensionSystem::CPluginManager pluginManager; + ExtensionSystem::PluginManager pluginManager; pluginManager.setSettings(settings); QStringList pluginPaths; #if !defined(NL_OS_MAC) @@ -161,17 +162,8 @@ sint main(int argc, char **argv) splash->hide(); - const QList plugins = pluginManager.plugins(); - ExtensionSystem::IPluginSpec *corePlugin = 0; - Q_FOREACH(ExtensionSystem::IPluginSpec *spec, plugins) - { - if (spec->name() == QLatin1String("Core")) - { - corePlugin = spec; - break; - } - } - + ExtensionSystem::IPluginSpec *corePlugin = pluginManager.pluginByName("Core"); + if (!corePlugin) { QDir absolutePluginPaths(pluginPaths.join(QLatin1String(","))); @@ -182,8 +174,8 @@ sint main(int argc, char **argv) QString newPath = QFileDialog::getExistingDirectory(0, QCoreApplication::translate("Application", "Change the plugins path"), QDir::homePath()); bool ok; QString text = QInputDialog::getText(0, QCoreApplication::translate("Application", "Enter the plugins path"), - QCoreApplication::translate("Application", "Plugin path:"), QLineEdit::Normal, - newPath, &ok); + QCoreApplication::translate("Application", "Plugin path:"), QLineEdit::Normal, + newPath, &ok); if (ok && !text.isEmpty()) settings->setValue("PluginPath", text); settings->sync(); @@ -202,7 +194,7 @@ sint main(int argc, char **argv) if (!errors.isEmpty()) QMessageBox::warning(0, QCoreApplication::translate("Application", "Object Viewer Qt - Plugin loader messages"), - errors.join(QString::fromLatin1("\n\n"))); + errors.join(QString::fromLatin1("\n\n"))); int result = app.exec(); return result; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/CMakeLists.txt index bec71cf94..467b00876 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/CMakeLists.txt @@ -1,9 +1,16 @@ ADD_SUBDIRECTORY(core) ADD_SUBDIRECTORY(example) ADD_SUBDIRECTORY(ovqt_sheet_builder) -ADD_SUBDIRECTORY(landscape_editor) +ADD_SUBDIRECTORY(landscape_editor) ADD_SUBDIRECTORY(log) ADD_SUBDIRECTORY(disp_sheet_id) ADD_SUBDIRECTORY(object_viewer) -ADD_SUBDIRECTORY(zone_painter) ADD_SUBDIRECTORY(georges_editor) +ADD_SUBDIRECTORY(translation_manager) +ADD_SUBDIRECTORY(bnp_manager) +# Note: Temporarily disabled until development continues. +#ADD_SUBDIRECTORY(zone_painter) +# Ryzom Specific Plugins +IF(WITH_RYZOM AND WITH_RYZOM_TOOLS) + ADD_SUBDIRECTORY(mission_compiler) +ENDIF(WITH_RYZOM AND WITH_RYZOM_TOOLS) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/CMakeLists.txt new file mode 100644 index 000000000..7ecfd7396 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/CMakeLists.txt @@ -0,0 +1,47 @@ +INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} + ${LIBXML2_INCLUDE_DIR} + ${QT_INCLUDES}) + +FILE(GLOB SRC *.cpp *.h) +SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin.h + ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin_manager.h + ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin_spec.h) + +SET(OVQT_PLUG_BNP_MANAGER_HDR bnp_manager_plugin.h + bnp_manager_window.h + bnp_dirtree_dialog.h + bnp_filesystem_model.h + bnp_file.h + bnp_filelist_dialog.h + bnp_proxy_model.h + ) +SET(OVQT_PLUG_BNP_MANAGER_UIS bnp_dirtree_form.ui + bnp_filelist_dialog.ui + ) + +SET(OVQT_PLUGIN_BNP_MANAGER_RCS bnp_manager.qrc) + +SET(QT_USE_QTGUI TRUE) + +QT4_ADD_RESOURCES(OVQT_PLUGIN_BNP_MANAGER_RC_SRCS ${OVQT_PLUGIN_BNP_MANAGER_RCS}) +QT4_WRAP_CPP(OVQT_PLUG_BNP_MANAGER_MOC_SRC ${OVQT_PLUG_BNP_MANAGER_HDR}) +QT4_WRAP_UI(OVQT_PLUG_BNP_MANAGER_UI_HDRS ${OVQT_PLUG_BNP_MANAGER_UIS}) + +SOURCE_GROUP(QtResources FILES ${OVQT_PLUG_BNP_MANAGER_UIS} ${OVQT_PLUGIN_BNP_MANAGER_RCS}) +SOURCE_GROUP(QtGeneratedUiHdr FILES ${OVQT_PLUG_BNP_MANAGER_UI_HDRS}) +SOURCE_GROUP(QtGeneratedMocSrc FILES ${OVQT_PLUG_BNP_MANAGER_MOC_SRC}) +SOURCE_GROUP("BNP Manager Plugin" FILES ${SRC}) +SOURCE_GROUP("OVQT Extension System" FILES ${OVQT_EXT_SYS_SRC}) + +ADD_LIBRARY(ovqt_plugin_bnp_manager MODULE ${SRC} ${OVQT_PLUG_BNP_MANAGER_MOC_SRC} ${OVQT_EXT_SYS_SRC} ${OVQT_PLUGIN_BNP_MANAGER_RC_SRCS} ${OVQT_PLUG_BNP_MANAGER_UI_HDRS}) + +TARGET_LINK_LIBRARIES(ovqt_plugin_bnp_manager ovqt_plugin_core nelmisc nelgeorges ${QT_LIBRARIES}) + +NL_DEFAULT_PROPS(ovqt_plugin_bnp_manager "NeL, Tools, 3D: Object Viewer Qt Plugin: BNP Manager") +NL_ADD_RUNTIME_FLAGS(ovqt_plugin_bnp_manager) +NL_ADD_LIB_SUFFIX(ovqt_plugin_bnp_manager) + +ADD_DEFINITIONS(${LIBXML2_DEFINITIONS} -DQT_PLUGIN -DQT_SHARED ${QT_DEFINITIONS}) + +INSTALL(TARGETS ovqt_plugin_bnp_manager LIBRARY DESTINATION lib RUNTIME DESTINATION bin ARCHIVE DESTINATION lib COMPONENT tools3d) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_dirtree_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_dirtree_dialog.cpp new file mode 100644 index 000000000..a19f4550e --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_dirtree_dialog.cpp @@ -0,0 +1,93 @@ +// Object Viewer Qt - BNP Manager Plugin - MMORPG Framework +// Copyright (C) 2011 Roland Winklmeier +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Project includes +#include "bnp_dirtree_dialog.h" +#include "bnp_filesystem_model.h" +#include "bnp_proxy_model.h" + +// Qt includes +#include + +// NeL includes +#include + +namespace BNPManager +{ + +CBnpDirTreeDialog::CBnpDirTreeDialog(QString bnpPath, QWidget *parent) + : QDockWidget(parent), + m_DataPath(bnpPath) +{ + // Setup the dialog + m_ui.setupUi(this); + + // Filter settings to only display files with bnp extension. + // Could be changed to display all files and react according to the extension: + // Bnp file: opened and displayed + // all other files: added to the currently opened bnp file + QStringList filter; + filter << tr("*.bnp"); + + // Setup the directory tree model + m_dirModel= new BNPFileSystemModel(); + m_proxyModel = new BNPSortProxyModel(); + m_ui.dirTree->setSortingEnabled(true); + m_dirModel->setRootPath(m_DataPath); + m_dirModel->setFilter(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::AllEntries); + m_dirModel->setNameFilters(filter); + m_dirModel->setNameFilterDisables(0); + + m_proxyModel->setSourceModel(m_dirModel); + + m_ui.dirTree->setModel(m_proxyModel); + + m_ui.dirTree->setRootIndex( m_proxyModel->mapFromSource (m_dirModel->index(m_DataPath) ) ); + + // Trigger if one filename is activated + // In future drag&drop should be also possible + connect(m_ui.dirTree, SIGNAL(activated(QModelIndex)), + this, SLOT(fileSelected(QModelIndex))); +} +// *************************************************************************** +CBnpDirTreeDialog::~CBnpDirTreeDialog() +{ + +} +// *************************************************************************** +void CBnpDirTreeDialog::fileSelected(QModelIndex index) +{ + QModelIndex source = m_proxyModel->mapToSource(index); + if (source.isValid() && !m_dirModel->isDir(source)) + { + // emit the according signal to BNPManagerWindow class + Q_EMIT selectedFile(m_dirModel->fileInfo(source).filePath()); + } +} +// *************************************************************************** +void CBnpDirTreeDialog::changeFile(QString file) +{ + +} +// *************************************************************************** +void CBnpDirTreeDialog::BnpPathChanged(QString path) +{ + +} +// *************************************************************************** +} + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_dirtree_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_dirtree_dialog.h new file mode 100644 index 000000000..737085185 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_dirtree_dialog.h @@ -0,0 +1,83 @@ +// Object Viewer Qt - BNP Manager Plugin - MMORPG Framework +// Copyright (C) 2011 Roland Winklmeier +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef BNP_DIRTREE_DIALOG_H +#define BNP_DIRTREE_DIALOG_H + +// Qt includes +#include + +// STL includes + +// NeL includes + +// Project includes +#include "ui_bnp_dirtree_form.h" + +namespace BNPManager +{ + +class BNPFileSystemModel; +class BNPSortProxyModel; + +class CBnpDirTreeDialog : public QDockWidget +{ + Q_OBJECT +public: + + /** + * Constructor + * \param path to root directory, which should be displayed + */ + CBnpDirTreeDialog(QString bnpPath, QWidget *parent = 0); + + /** + * Destructor + */ + ~CBnpDirTreeDialog(); + + /** + * Change the root path for the dir tree view + * \param data path to the new directory + */ + void BnpPathChanged(QString); + +private: + + Ui::CBnpDirTreeDialog m_ui; + + // path ro data root directory + QString m_DataPath; + + BNPFileSystemModel *m_dirModel; + + BNPSortProxyModel *m_proxyModel; + +Q_SIGNALS: + void selectedFile(const QString); + +private Q_SLOTS: + /** + * Triggered if the user activates (double klick on windows) + * a file name in the dir tree view + * \param selected ModelIndex (filename) + */ + void fileSelected(QModelIndex index); + + void changeFile(QString file); +}; +} +#endif \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_dirtree_form.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_dirtree_form.ui new file mode 100644 index 000000000..44b39dc54 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_dirtree_form.ui @@ -0,0 +1,61 @@ + + + CBnpDirTreeDialog + + + + 0 + 0 + 400 + 300 + + + + + 0 + 0 + + + + + 200 + 141 + + + + QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable + + + BNP Datapath + + + + + 50 + 0 + + + + + + + + 0 + 0 + + + + true + + + + + + + + + + + + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_file.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_file.cpp new file mode 100644 index 000000000..e00f777ba --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_file.cpp @@ -0,0 +1,324 @@ +// Object Viewer Qt - BNP Manager Plugin - MMORPG Framework +// Copyright (C) 2011 Roland Winklmeier +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Project includes +#include "bnp_file.h" + +// Nel includes +#include +#include +#include +#include +#include + +// Qt includes + +using namespace NLMISC; +using namespace std; + + +namespace BNPManager +{ + +PackedFile::PackedFile() +{ + m_size = 0; + m_pos = 0; +} + +NLMISC_SAFE_SINGLETON_IMPL(BNPFileHandle); + +BNPFileHandle::BNPFileHandle() +{ + m_offsetFromBeginning = 0; +} +// *************************************************************************** +BNPFileHandle::~BNPFileHandle() +{ + // Erase the list + m_packedFiles.clear(); +} +// *************************************************************************** +void BNPFileHandle::releaseInstance() +{ + if (_Instance) + { + NLMISC::INelContext::getInstance().releaseSingletonPointer("BNPFileHandle", _Instance); + delete _Instance; + _Instance = NULL; + } +} +// *************************************************************************** +void BNPFileHandle::createFile(string filePath) +{ + // Only set the filepath. Header will be created after files have been added + m_openedBNPFile = filePath; + m_packedFiles.clear(); + + nlinfo("Created file %s.", filePath.c_str() ); +} +// *************************************************************************** +bool BNPFileHandle::unpack(const string &dirName, const vector& fileList) +{ + CIFile bnp; + bnp.open(m_openedBNPFile); + + TPackedFilesList::iterator it_files = m_packedFiles.begin(); + + for (it_files; it_files != m_packedFiles.end(); it_files++) + { + // Check if the file should be unpacked or not + if (find(fileList.begin(), fileList.end(), it_files->m_name) != fileList.end()) + { + string filename = dirName + "/" + it_files->m_name; + + COFile out; + if ( out.open(filename) ) + { + bnp.seek(it_files->m_pos, IStream::begin); + uint8 *ptr = new uint8[it_files->m_size]; + bnp.serialBuffer(ptr,it_files->m_size); + out.serialBuffer(ptr,it_files->m_size); + delete [] ptr; + } + out.close(); + } + } + + bnp.close(); + return true; +} +// *************************************************************************** +// Read the header from a big file +bool BNPFileHandle::readHeader(const std::string &filePath) +{ + m_packedFiles.clear(); + + m_openedBNPFile = filePath; + + CIFile bnp; + bnp.open (filePath); + + bnp.seek(0, IStream::end); + uint32 nFileSize = bnp.getFileSize(); + bnp.seek(nFileSize-sizeof(uint32), IStream::begin); + + uint32 nOffsetFromBegining; + + bnp.serial(nOffsetFromBegining); + + if ( !bnp.seek (nOffsetFromBegining, IStream::begin) ) + { + nlwarning("Could not read offset from begining"); + bnp.close(); + return false; + } + + uint32 nNbFile; + bnp.serial(nNbFile); + + for (uint32 i = 0; i < nNbFile; ++i) + { + uint8 nStringSize; + char sName[256]; + + bnp.serial(nStringSize); + bnp.serialBuffer( (uint8*)sName, nStringSize); + sName[nStringSize] = 0; + + PackedFile tmpPackedFile; + tmpPackedFile.m_name = sName; + tmpPackedFile.m_path = m_openedBNPFile; + + bnp.serial(tmpPackedFile.m_size); + bnp.serial(tmpPackedFile.m_pos); + + m_packedFiles.push_back (tmpPackedFile); + } + + bnp.close(); + return true; +} +// *************************************************************************** +void BNPFileHandle::list(TPackedFilesList& FileList) +{ + PackedFile tmpFile; + TPackedFilesList::iterator it = m_packedFiles.begin(); + while (it != m_packedFiles.end() ) + { + tmpFile.m_name = it->m_name; + tmpFile.m_pos = it->m_pos; + tmpFile.m_size = it->m_size; + tmpFile.m_path = it->m_path; + FileList.push_back(tmpFile); + it++; + } +} +// *************************************************************************** +bool BNPFileHandle::writeHeader( const std::string &filePath, uint32 offset ) +{ + COFile bnp; + bnp.open(filePath, true); + if ( !bnp.isOpen() ) + return false; + + uint32 nNbFile = (uint32)m_packedFiles.size(); + bnp.serial(nNbFile); + + for (uint32 i = 0; i < nNbFile; ++i) + { + uint8 nStringSize = (uint8)m_packedFiles[i].m_name.size(); + bnp.serial( nStringSize ); + bnp.serialBuffer( (uint8*)m_packedFiles[i].m_name.c_str(), nStringSize ); + bnp.serial(m_packedFiles[i].m_size); + bnp.serial(m_packedFiles[i].m_pos); + } + + bnp.serial(offset); + + bnp.close(); + + return true; +} +// *************************************************************************** +void BNPFileHandle::fileNames(std::vector &fileNames) +{ + TPackedFilesList::iterator it = m_packedFiles.begin(); + while (it != m_packedFiles.end() ) + { + fileNames.push_back(it->m_name); + it++; + } +} +// *************************************************************************** +void BNPFileHandle::addFiles( const vector &filePathes) +{ + uint32 OffsetFromBegining = 0; + + // create packed files and add them to the private vector + vector::const_iterator it_vec = filePathes.begin(); + while (it_vec != filePathes.end() ) + { + PackedFile tmpFile; + tmpFile.m_name = CFile::getFilename (*it_vec); + // Leave position to 0 and set the value during the new bnp file is creating + // We need the position only for the header at the end + tmpFile.m_pos = 0; + tmpFile.m_size = CFile::getFileSize(*it_vec); + tmpFile.m_path = *it_vec; + m_packedFiles.push_back( tmpFile ); + + it_vec++; + } + + // sort packed files alphabetic + std::sort ( m_packedFiles.begin(), m_packedFiles.end(), compare ); + + // create a new temporary bnp file with extension *.tmp + TPackedFilesList::iterator it_packed = m_packedFiles.begin(); + while (it_packed != m_packedFiles.end() ) + { + append(m_openedBNPFile + ".tmp", *it_packed); + // Set now the new offset for the new header + it_packed->m_pos = OffsetFromBegining; + OffsetFromBegining += it_packed->m_size; + + it_packed++; + } + + writeHeader(m_openedBNPFile + ".tmp", OffsetFromBegining); + + // Delete any previous existing file + if (CFile::fileExists( m_openedBNPFile )) + CFile::deleteFile( m_openedBNPFile ); + string src = m_openedBNPFile + ".tmp"; + CFile::moveFile( m_openedBNPFile.c_str(), src.c_str() ); +} +// *************************************************************************** +void BNPFileHandle::deleteFiles( const vector& fileNames) +{ + vector::const_iterator it_vec; + TPackedFilesList::iterator it_packed; + uint32 OffsetFromBegining = 0; + string tmpFile = m_openedBNPFile + ".tmp"; + + // create a new temporary bnp file with extension *.tmp + it_packed = m_packedFiles.begin(); + while (it_packed != m_packedFiles.end() ) + { + // check each packed file if it should be deleted + it_vec = find (fileNames.begin(), fileNames.end(), it_packed->m_name ); + if ( it_vec != fileNames.end() ) + { + nlinfo("Deleting file %s.", it_packed->m_name.c_str() ); + it_packed = m_packedFiles.erase(it_packed); + } + else + { + append(tmpFile, *it_packed); + // Set now the new offset for the new header + it_packed->m_pos = OffsetFromBegining; + OffsetFromBegining += it_packed->m_size; + + it_packed++; + } + } + + writeHeader(tmpFile, OffsetFromBegining); + + CFile::deleteFile( m_openedBNPFile ); + string src = m_openedBNPFile + ".tmp"; + CFile::moveFile( m_openedBNPFile.c_str(), src.c_str() ); +} +// *************************************************************************** +void BNPFileHandle::append(const string &destination, const PackedFile &source) +{ + // check if the file exists and create one if not + if ( !CFile::fileExists(destination) ) + CFile::createEmptyFile( destination ); + + COFile bnpfile; + CIFile packedfile; + bnpfile.open(destination, true); + packedfile.open(source.m_path); + if ( !bnpfile.isOpen() ) return; + + + uint8 *ptr = new uint8[source.m_size]; + + // check if the source is a bnp file. + if ( nlstricmp( CFile::getExtension(source.m_path), "bnp" ) == 0 ) + { + // Jump to the file position inside the bnp + packedfile.seek(source.m_pos, IStream::begin); + } + // Read the source + packedfile.serialBuffer(ptr, source.m_size); + + // Append the data to the destination + bnpfile.serialBuffer(ptr, source.m_size); + + delete [] ptr; + + packedfile.close(); + bnpfile.close(); +} +// *************************************************************************** +bool BNPFileHandle::compare(const PackedFile &left, const PackedFile &right) +{ + return nlstricmp (left.m_name.c_str(), right.m_name.c_str()) < 0; +} +} // namespace BNPManager \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_file.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_file.h new file mode 100644 index 000000000..7695ebc2f --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_file.h @@ -0,0 +1,145 @@ +// Object Viewer Qt - BNP Manager Plugin - MMORPG Framework +// Copyright (C) 2011 Roland Winklmeier +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef BNP_FILE_H +#define BNP_FILE_H + +// Project includes + +// Nel includes +#include "nel/misc/types_nl.h" +#include + +// Qt includes +#include + + +namespace BNPManager +{ + +struct PackedFile +{ + PackedFile(); + std::string m_name; + uint32 m_size; + uint32 m_pos; + std::string m_path; +}; + +typedef std::vector TPackedFilesList; + +class BNPFileHandle +{ + NLMISC_SAFE_SINGLETON_DECL(BNPFileHandle) + + /** + * Private constructor + */ + BNPFileHandle(); + + /** + * Private destructor + */ + ~BNPFileHandle(); + +public: + // release memory + static void releaseInstance(); + + /*void append (const QString destFilename, const QString origFilename, uint32 sizeToRead); + void packRecurse();*/ + + /** + * Read the header from the bnp file and create a filelist + * \param filename (consisting the whole path) + */ + bool readHeader (const std::string &filePath); + + bool writeHeader (const std::string &filePath, uint32 offset); + + /** + * Append the header to a created bnp file + * \param filename (consisting the whole path) + */ + void appendHeader (const std::string &filename) {} + + /** + * Create a vector of all packed files inside the bnp file + * \param reference to the vector, which has to be filled + */ + void list (TPackedFilesList& FileList); + + /** + * Create a vector of all file names inside the bnp file + * \param reference to the vector, which has to be filled + */ + void fileNames( std::vector& fileNames ); + + /** + * Create a new bnp file + * \param string file path + */ + void createFile( std::string filePath ); + + /** + * Add files to the current aktive bnp file + * \param vector of file pathes to add + */ + void addFiles( const std::vector& filePathes ); + + /** + * Delete files from the current aktive bnp file + * \param vector of files names + */ + void deleteFiles (const std::vector& fileNames); + + /** + * Unpack the selected packed files into user defined dir + * \param directory path, where the files should be unpacked + * \param list of files, which has to be unpacked + */ + bool unpack (const std::string &dirName, const std::vector& fileList); + + /** + * Compares two filenames + * \param left: left packed file + * \param right: right packed file + * \return: TODO + */ + static bool compare(const PackedFile &left, const PackedFile &right); + +private: + + /** + * Append one file to an existing bnp file + * \param destination: the active bnp file to append the file + * \param source: the source file to pack + */ + void append( const std::string& destination, const PackedFile& source ); + + TPackedFilesList m_packedFiles; + + // currently opened and displayed bnp file + std::string m_openedBNPFile; + + // offset where the header of the bnp file begins + uint32 m_offsetFromBeginning; + +}; + +} + +#endif \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_filelist_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_filelist_dialog.cpp new file mode 100644 index 000000000..261175902 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_filelist_dialog.cpp @@ -0,0 +1,132 @@ +// Object Viewer Qt - BNP Manager Plugin - MMORPG Framework +// Copyright (C) 2011 Roland Winklmeier +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Project includes +#include "bnp_filelist_dialog.h" +#include "bnp_file.h" + +// Qt includes +#include + +// NeL includes +#include + +using namespace std; + +namespace BNPManager +{ + +BnpFileListDialog::BnpFileListDialog(QString bnpPath, QWidget *parent) + : QDockWidget(parent), + m_DataPath(bnpPath) +{ + m_ui.setupUi(this); +} +// *************************************************************************** +BnpFileListDialog::~BnpFileListDialog() +{ + +} +// *************************************************************************** +void BnpFileListDialog::setupTable(int nbrows) +{ + // delete all old entries + m_ui.tableWidget->clear(); + + // set 2 colums: filename and size + m_ui.tableWidget->setColumnCount(2); + + // set number of rows according to the number of files in the bnp file + m_ui.tableWidget->setRowCount(nbrows); + + // only entire rows can be selected + m_ui.tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); + + // set the horizontal headers + QStringList labels; + labels << tr("Filename") << tr("Size"); + m_ui.tableWidget->setHorizontalHeaderLabels(labels); + + m_ui.tableWidget->horizontalHeader()->setResizeMode(0, QHeaderView::Interactive); + m_ui.tableWidget->horizontalHeader()->setResizeMode(1, QHeaderView::Stretch ); + m_ui.tableWidget->verticalHeader()->hide(); + + // set vertical size a little bit smaller + m_ui.tableWidget->verticalHeader()->setDefaultSectionSize(15); + m_ui.tableWidget->setShowGrid(false); + m_ui.tableWidget->setObjectName("tablewidget"); +} +// *************************************************************************** +bool BnpFileListDialog::loadTable(const QString filePath) +{ + // reference to the BNPFileHandle singletone instance + BNPFileHandle& myBNPFileHandle = BNPFileHandle::getInstance(); + // string vector of all packed files inside a bnp + TPackedFilesList filelist; + int row = 0; + + // read the header from the bnp file + if (!myBNPFileHandle.readHeader( filePath.toStdString()) ) + { + return false; + } + myBNPFileHandle.list( filelist ); + + // create table with number of rows + setupTable(filelist.size()); + + // fill the table items + TPackedFilesList::iterator it = filelist.begin(); + while (it != filelist.end() ) + { + QTableWidgetItem *nameItem = new QTableWidgetItem (it->m_name.c_str() ); + QTableWidgetItem *sizeItem = new QTableWidgetItem (tr("%1 KB").arg(it->m_size)); + m_ui.tableWidget->setItem(row, 0, nameItem); + m_ui.tableWidget->setItem(row, 1, sizeItem); + it++; + row++; + } + + // Set the file path as the widgets title + setWindowTitle(filePath); + + return true; +} +// *************************************************************************** +void BnpFileListDialog::clearTable() +{ + // create emtpy table + setupTable(0); + + setWindowTitle("BNP File List"); +} +// *************************************************************************** +void BnpFileListDialog::getSelections(TSelectionList& SelectionList) +{ + QModelIndex index; + QAbstractItemModel *model = m_ui.tableWidget->model(); + QItemSelectionModel *selection = m_ui.tableWidget->selectionModel(); + QModelIndexList indexes = selection->selectedRows(); + + Q_FOREACH(index, indexes) + { + QVariant data = model->data(index); + QString filename = data.toString(); + SelectionList.push_back( filename.toStdString() ); + } +} + +} // namespace BNPManager \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_filelist_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_filelist_dialog.h new file mode 100644 index 000000000..dbf007fc2 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_filelist_dialog.h @@ -0,0 +1,85 @@ +// Object Viewer Qt - BNP Manager Plugin - MMORPG Framework +// Copyright (C) 2011 Roland Winklmeier +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef BNP_FILELIST_DIALOG_H +#define BNP_FILELIST_DIALOG_H + +// Qt includes +#include + +// STL includes +#include +#include + +// NeL includes + +// Project includes +#include "ui_bnp_filelist_dialog.h" + +namespace BNPManager +{ + +typedef std::vector TSelectionList; + +class BnpFileListDialog : public QDockWidget +{ + Q_OBJECT + +public: + + // Constructor + BnpFileListDialog(QString bnpPath, QWidget *parent = 0); + + // Destructor + ~BnpFileListDialog(); + + /** + * Load the bnp file and setup the table view + * \param Filename + * \return true if everything went well + */ + bool loadTable(const QString filePath); + + /** + * Set the dimension of the table + * \param number of rows + */ + void setupTable(int nbrows); + + /** + * When BNP files is closed, clear the filelist table + */ + void clearTable(); + + /** + * Fill the files selected in the table view to + * unpack them. + * \param reference to a vector of filenames. + * \return true if everything went well + */ + void getSelections(TSelectionList& SelectionList); + +private: + Ui::BnpFileListDialog m_ui; + + // common data path as root folder for the dirtree view + QString m_DataPath; + +}; + +} + +#endif diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_filelist_dialog.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_filelist_dialog.ui new file mode 100644 index 000000000..9f62ff7c0 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_filelist_dialog.ui @@ -0,0 +1,70 @@ + + + BnpFileListDialog + + + + 0 + 0 + 400 + 300 + + + + + 0 + 0 + + + + + 200 + 141 + + + + true + + + QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable + + + BNP File List + + + + + 50 + 0 + + + + + + + true + + + QAbstractItemView::NoEditTriggers + + + QAbstractItemView::SelectRows + + + false + + + 15 + + + + + + + + + + + + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_filesystem_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_filesystem_model.cpp new file mode 100644 index 000000000..75ef031ff --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_filesystem_model.cpp @@ -0,0 +1,51 @@ +// Object Viewer Qt - BNP Manager Plugin - MMORPG Framework +// Copyright (C) 2011 Roland Winklmeier +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see + +#include "bnp_filesystem_model.h" + +#include +#include + +namespace BNPManager +{ + +BNPFileSystemModel::BNPFileSystemModel(QObject *parent) + : QFileSystemModel(parent) +{ +} +// *************************************************************************** +BNPFileSystemModel::~BNPFileSystemModel() +{ + +} +// *************************************************************************** +int BNPFileSystemModel::columnCount(const QModelIndex &) const +{ + return 1; +} +// *************************************************************************** +QVariant BNPFileSystemModel::data(const QModelIndex& index, int role) const +{ + + if (role == Qt::DecorationRole) + { + if (isDir(index)) + return QApplication::style()->standardIcon(QStyle::SP_DirIcon); + } + return QFileSystemModel::data(index, role); +} +// *************************************************************************** +} // namespace BNPManager diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_filesystem_model.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_filesystem_model.h new file mode 100644 index 000000000..2ca086b39 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_filesystem_model.h @@ -0,0 +1,49 @@ +// Object Viewer Qt - BNP Manager Plugin - MMORPG Framework +// Copyright (C) 2011 Roland Winklmeier +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see + +#ifndef BNP_FILESYSTEM_MODEL_H +#define BNP_FILESYSTEM_MODEL_H + +#include + +namespace BNPManager +{ + +class BNPFileSystemModel : public QFileSystemModel +{ + Q_OBJECT + +public: + + /** + * Constructor + */ + BNPFileSystemModel(QObject *parent = 0); + + /** + * Destructor + */ + ~BNPFileSystemModel(); + + int columnCount(const QModelIndex &) const; + + QVariant data(const QModelIndex& index, int role) const ; + +}; + +} + +#endif \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_manager.qrc b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_manager.qrc new file mode 100644 index 000000000..bf32595d6 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_manager.qrc @@ -0,0 +1,9 @@ + + + images/ic_nel_bnp_make.png + images/ic_nel_delete_item.png + images/ic_nel_add_item.png + images/ic_nel_export.png + images/ic_nel_reset_all.png + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_manager_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_manager_constants.h new file mode 100644 index 000000000..609305b7e --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_manager_constants.h @@ -0,0 +1,38 @@ +// Object Viewer Qt - BNP Manager Plugin - MMORPG Framework +// Copyright (C) 2011 Roland Winklmeier +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef BNP_MANAGER_CONSTANTS_H +#define BNP_MANAGER_CONSTANTS_H + +namespace BNPManager +{ +namespace Constants +{ +//settings +const char * const BNP_MANAGER_SECTION = "BNPManager"; + +//resources +const char *const ICON_NEW = ":/images/ic_nel_new.png"; +const char *const ICON_ADD = ":/images/ic_nel_add_item.png"; +const char *const ICON_DELETE = ":/images/ic_nel_delete_item.png"; +const char *const ICON_UNPACK = ":/images/ic_nel_export.png"; +const char *const ICON_CLOSE = ":/images/ic_nel_reset_all.png"; + + +} // namespace Constants +} // namespace Plugin + +#endif diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_manager_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_manager_plugin.cpp new file mode 100644 index 000000000..70015773b --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_manager_plugin.cpp @@ -0,0 +1,89 @@ +// Object Viewer Qt - BNP Manager Plugin - MMORPG Framework +// Copyright (C) 2011 Roland Winklmeier +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Project includes +#include "bnp_manager_plugin.h" +#include "bnp_manager_window.h" + +#include "../core/icore.h" +#include "../core/core_constants.h" +#include "../core/menu_manager.h" + +// NeL includes +#include "nel/misc/debug.h" + +// Qt includes +#include +#include + +namespace BNPManager +{ + + BNPManagerPlugin::BNPManagerPlugin() + { + } + + BNPManagerPlugin::~BNPManagerPlugin() + { + Q_FOREACH(QObject *obj, m_autoReleaseObjects) + { + m_plugMan->removeObject(obj); + } + qDeleteAll(m_autoReleaseObjects); + m_autoReleaseObjects.clear(); + } + +bool BNPManagerPlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString) +{ + Q_UNUSED(errorString); + m_plugMan = pluginManager; + + addAutoReleasedObject(new BNPManagerContext(this)); + return true; +} + +void BNPManagerPlugin::extensionsInitialized() +{ +} + +void BNPManagerPlugin::shutdown() +{ + +} + +void BNPManagerPlugin::setNelContext(NLMISC::INelContext *nelContext) +{ +#ifdef NL_OS_WINDOWS + // Ensure that a context doesn't exist yet. + // This only applies to platforms without PIC, e.g. Windows. + nlassert(!NLMISC::INelContext::isContextInitialised()); +#endif // NL_OS_WINDOWS + m_libContext = new NLMISC::CLibraryContext(*nelContext); +} + +void BNPManagerPlugin::addAutoReleasedObject(QObject *obj) +{ + m_plugMan->addObject(obj); + m_autoReleaseObjects.prepend(obj); +} + +/*void BNPManagerContext::open() +{ + m_BnpManagerWindow->open(); +}*/ +} + +Q_EXPORT_PLUGIN(BNPManager::BNPManagerPlugin) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_manager_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_manager_plugin.h new file mode 100644 index 000000000..55e2e8444 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_manager_plugin.h @@ -0,0 +1,130 @@ +// Object Viewer Qt - BNP Manager Plugin - MMORPG Framework +// Copyright (C) 2011 Roland Winklmeier +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef BNP_MANAGER_PLUGIN_H +#define BNP_MANAGER_PLUGIN_H + +// Project includes +#include "../../extension_system/iplugin.h" +#include "../core/icontext.h" +#include "bnp_manager_window.h" + +// NeL includes +#include "nel/misc/app_context.h" +#include + +// Qt includes +#include +#include + +namespace NLMISC +{ +class CLibraryContext; +} + +namespace ExtensionSystem +{ +class IPluginSpec; +} + +namespace BNPManager +{ +class m_BnpManagerWindow; + +class BNPManagerPlugin : public QObject, public ExtensionSystem::IPlugin +{ + Q_OBJECT + Q_INTERFACES(ExtensionSystem::IPlugin) + +public: + BNPManagerPlugin(); + virtual ~BNPManagerPlugin(); + + virtual bool initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString); + virtual void extensionsInitialized(); + virtual void shutdown(); + virtual void setNelContext(NLMISC::INelContext *nelContext); + + void addAutoReleasedObject(QObject *obj); + +protected: + + NLMISC::CLibraryContext *m_libContext; + +private: + + ExtensionSystem::IPluginManager *m_plugMan; + QList m_autoReleaseObjects; +}; + +/** + * Implementation of the IContext interface + * + * \date 2011 + */ + +class BNPManagerContext : public Core::IContext +{ + Q_OBJECT + +public: + // Constructor + BNPManagerContext(QObject *parent = 0) : IContext(parent) + { + // run new manager window app + m_BnpManagerWindow = new BNPManagerWindow(); + } + + // Destructor + virtual ~BNPManagerContext() {} + + virtual QString id() const + { + return QLatin1String("BNPManagerContext"); + } + virtual QString trName() const + { + return tr("BNP Manager"); + } + virtual QIcon icon() const + { + return QIcon(":/images/ic_nel_bnp_make.png"); + } + + virtual void open() + { + m_BnpManagerWindow->open(); + } + + virtual QUndoStack *undoStack() + { + return m_BnpManagerWindow->m_undoStack; + } + + virtual QWidget *widget() + { + return m_BnpManagerWindow; + } + + BNPManagerWindow *m_BnpManagerWindow; + +}; + +} // namespace Plugin + + + +#endif // BNP_MANAGER_PLUGIN_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_manager_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_manager_window.cpp new file mode 100644 index 000000000..3990e70ce --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_manager_window.cpp @@ -0,0 +1,444 @@ +// Object Viewer Qt - BNP Manager Plugin - MMORPG Framework +// Copyright (C) 2011 Roland Winklmeier +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Project includes +#include "bnp_manager_window.h" +#include "bnp_manager_constants.h" +#include "bnp_dirtree_dialog.h" +#include "bnp_filelist_dialog.h" +#include "bnp_file.h" + +#include "../core/icore.h" +#include "../core/menu_manager.h" +#include "../core/core_constants.h" +#include "../../extension_system/iplugin_spec.h" + +// NeL includes +#include +#include + +// STL includes +#include +#include + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace NLMISC; + + +namespace BNPManager +{ + +BNPManagerWindow::BNPManagerWindow(QWidget *parent) + : QMainWindow(parent) +{ + // add new mainwindow for sheet dockwidgets + QTableWidget* hideWidget = new QTableWidget(0,0,this); + setCentralWidget(hideWidget); + hideWidget->hide(); + + setAcceptDrops(true); + + // Read the settings + readSettings(); + + // create main dialogs and display them + createDialogs(); + + // create actions like open, close, add etc. + createActions(); + + // create a toolbar with icons + createToolBars(); + + // this SLOT is triggered if the user activates a bnp files in the + // dirtree view + connect(m_BnpDirTreeDialog, SIGNAL(selectedFile(const QString)), + this, SLOT(loadFile(const QString))); + + // not used + m_undoStack = new QUndoStack(this); +} +// *************************************************************************** +BNPManagerWindow::~BNPManagerWindow() +{ + writeSettings(); +} +// *************************************************************************** +void BNPManagerWindow::createDialogs() +{ + // create dialog to list the contents of the specified + // bnp data file directory + m_BnpDirTreeDialog = new CBnpDirTreeDialog(tr(m_DataPath.toStdString().c_str()),this); + addDockWidget(Qt::LeftDockWidgetArea, m_BnpDirTreeDialog); + m_BnpDirTreeDialog->setVisible(true); + restoreDockWidget(m_BnpDirTreeDialog); + + // create dialog to list the packed file contents of bnp files on + // the right hand side + m_BnpFileListDialog = new BnpFileListDialog(m_DataPath,this); + addDockWidget(Qt::RightDockWidgetArea, m_BnpFileListDialog); + m_BnpFileListDialog->setVisible(true); + restoreDockWidget(m_BnpFileListDialog); +} +// *************************************************************************** +void BNPManagerWindow::createActions() +{ + // new action + m_newAction = new QAction(tr("&New..."), this); + m_newAction->setIcon(QIcon(Core::Constants::ICON_NEW)); + m_newAction->setStatusTip(tr("New file")); + connect(m_newAction, SIGNAL(triggered()), this, SLOT( newFile() )); + + // open action + m_openAction = new QAction(tr("&Open..."), this); + m_openAction->setIcon(QIcon(Core::Constants::ICON_OPEN)); + m_openAction->setStatusTip(tr("Open file")); + connect(m_openAction, SIGNAL(triggered()), this, SLOT( open() )); + + // close action + m_closeAction = new QAction(tr("&Close..."), this); + m_closeAction->setIcon(QIcon(Constants::ICON_CLOSE)); + m_closeAction->setStatusTip(tr("Close the BNP File")); + connect(m_closeAction, SIGNAL(triggered()), this, SLOT( close() )); + + // add files into the bnp file + m_addFilesAction = new QAction(tr("&Add..."), this); + m_addFilesAction->setIcon(QIcon(Constants::ICON_ADD)); + m_addFilesAction->setStatusTip(tr("Add Files to BNP")); + connect(m_addFilesAction, SIGNAL(triggered()), this, SLOT( addFiles() )); + + // delete files from the bnp file + m_deleteFilesAction = new QAction(tr("&Delete..."), this); + m_deleteFilesAction->setIcon(QIcon(Constants::ICON_DELETE)); + m_deleteFilesAction->setStatusTip(tr("Delete Files")); + connect(m_deleteFilesAction, SIGNAL(triggered()), this, SLOT( deleteFiles() )); + + // unpack selected files into user defined dir + m_unpackFilesAction = new QAction(tr("&Unpack..."), this); + m_unpackFilesAction->setIcon(QIcon(Constants::ICON_UNPACK)); + m_unpackFilesAction->setStatusTip(tr("Unpack Files")); + connect(m_unpackFilesAction, SIGNAL(triggered()), this, SLOT( unpackFiles() )); +} +// *************************************************************************** +void BNPManagerWindow::createToolBars() +{ + m_fileToolBar = addToolBar(tr("&File")); + m_fileToolBar->addAction(m_newAction); + m_fileToolBar->addAction(m_openAction); + m_fileToolBar->addAction(m_closeAction); + + m_toolsBar = addToolBar(tr("&Tools")); + m_toolsBar->addAction(m_addFilesAction); + m_toolsBar->addAction(m_deleteFilesAction); + m_toolsBar->addAction(m_unpackFilesAction); +} +// *************************************************************************** +bool BNPManagerWindow::loadFile(const QString fileName) +{ + // Store the filename for later use + m_openedBNPFile = fileName; + m_BnpFileListDialog->loadTable(fileName); + return true; +} +// *************************************************************************** +void BNPManagerWindow::newFile() +{ + // reference to the BNPFileHandle singletone instance + BNPFileHandle& myBNPFileHandle = BNPFileHandle::getInstance(); + + m_openedBNPFile = ""; + m_BnpFileListDialog->clearTable(); + + QString filePath = QFileDialog::getSaveFileName(this, tr("Create File"),QDir::currentPath(), + tr("BNP File (*.bnp)")); + + if (filePath.isEmpty() ) + return; + + if ( !filePath.endsWith(".bnp", Qt::CaseInsensitive) ) + filePath.append(".bnp"); + + m_openedBNPFile = filePath; + m_BnpFileListDialog->setWindowTitle (filePath); + + myBNPFileHandle.createFile ( filePath.toStdString() ); + +} +// *************************************************************************** +void BNPManagerWindow::open() +{ + QString fileName; + // file dialog to select with file should be opened + fileName = QFileDialog::getOpenFileName(this, + tr("Open BNP file"), tr(m_DataPath.toStdString().c_str()), tr("BNP Files (*.bnp)")); + + // Check if filename is empty + if (fileName.isNull()) + return; + + loadFile(fileName); +} +// *************************************************************************** +void BNPManagerWindow::close() +{ + m_openedBNPFile = ""; + m_BnpFileListDialog->clearTable(); +} +// *************************************************************************** +void BNPManagerWindow::addFiles() +{ + // reference to the BNPFileHandle singletone instance + BNPFileHandle& myBNPFileHandle = BNPFileHandle::getInstance(); + + // vector of all current packed filenames + vector currentFiles; + + // vector of files to add + vector addFiles; + + // open a file dialog and to add files + QStringList FileList; + + FileList = QFileDialog::getOpenFileNames(this,tr("Add Files..."), + QDir::currentPath(), tr("All Files (*.*)") ); + + // get all current filenames from the opened bnp file + myBNPFileHandle.fileNames(currentFiles); + + QStringList::iterator it_list = FileList.begin(); + while (it_list != FileList.end() ) + { + string fileName = CFile::getFilename (it_list->toStdString() ); + if ( std::find(currentFiles.begin(), currentFiles.end(), fileName ) != currentFiles.end() ) + { + // Ask the user if he wants to override the existing file + // atm only warn the user and do not override + QMessageBox::warning(this, tr("BNP Manager"), + tr("File is already in the list!"), + QMessageBox::Ok, + QMessageBox::Ok); + } + else + { + addFiles.push_back( it_list->toStdString() ); + // log it + nlinfo("Add file %s", fileName.c_str() ); + } + it_list++; + } + + if ( !addFiles.empty() ) + { + myBNPFileHandle.addFiles( addFiles ); + } + loadFile(m_openedBNPFile); +} +// *************************************************************************** +void BNPManagerWindow::addFiles( QStringList FileList ) +{ + // reference to the BNPFileHandle singletone instance + BNPFileHandle& myBNPFileHandle = BNPFileHandle::getInstance(); + + // vector of all current packed filenames + vector currentFiles; + + // vector of files to add + vector addFiles; + + // get all current filenames from the opened bnp file + myBNPFileHandle.fileNames(currentFiles); + + QStringList::iterator it_list = FileList.begin(); + while (it_list != FileList.end() ) + { + string fileName = CFile::getFilename (it_list->toStdString() ); + if ( std::find(currentFiles.begin(), currentFiles.end(), fileName ) != currentFiles.end() ) + { + // Ask the user if he wants to override the existing file + // atm only warn the user and do not override + QMessageBox::warning(this, tr("BNP Manager"), + tr("File is already in the list!"), + QMessageBox::Ok, + QMessageBox::Ok); + } + else + { + addFiles.push_back( it_list->toStdString() ); + // log it + nlinfo("Add file %s", fileName.c_str() ); + } + it_list++; + } + + if ( !addFiles.empty() ) + { + myBNPFileHandle.addFiles( addFiles ); + } + loadFile(m_openedBNPFile); +} +// *************************************************************************** +void BNPManagerWindow::deleteFiles() +{ + QFileDialog filedialog(this); + BNPFileHandle& myBNPFileHandle = BNPFileHandle::getInstance(); + vector selectedRows; + + m_BnpFileListDialog->getSelections(selectedRows); + + // Check if files were selected. If not, inform the user. + if (selectedRows.empty()) + { + QMessageBox::information(this, tr("BNP Manager"), + tr("No files selected!"), + QMessageBox::Ok, + QMessageBox::Ok); + return; + } + + myBNPFileHandle.deleteFiles(selectedRows); + loadFile(m_openedBNPFile); +} +// *************************************************************************** +void BNPManagerWindow::unpackFiles() +{ + QFileDialog filedialog(this); + BNPFileHandle& myBNPFileHandle = BNPFileHandle::getInstance(); + vector selectedrows; + + m_BnpFileListDialog->getSelections(selectedrows); + + // Check if files were selected. If not, inform the user. + // TODO: Ask the user if nothing was selected, if he wants to unpack all + // files. This is more like Winzip. + if (selectedrows.empty()) + { + QMessageBox::information(this, tr("BNP Manager"), + tr("No files selected!"), + QMessageBox::Ok, + QMessageBox::Ok); + return; + } + + QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"), + tr(m_DataPath.toStdString().c_str()), + QFileDialog::ShowDirsOnly + | QFileDialog::DontResolveSymlinks); + + // If anything went wrong or the user pressed "cancel" + if ( dir.isEmpty() ) + return; + + if (myBNPFileHandle.unpack(dir.toStdString(),selectedrows)) + { + QMessageBox::information(this, tr("BNP Manager"), + tr("All files has been exported successfully."), + QMessageBox::Ok, + QMessageBox::Ok); + } +} +// *************************************************************************** +void BNPManagerWindow::readSettings() +{ + QSettings *settings = Core::ICore::instance()->settings(); + + settings->beginGroup(Core::Constants::DATA_PATH_SECTION); + m_DataPath = settings->value(Core::Constants::ASSETS_PATH, "w:/database").toString(); + settings->endGroup(); +} +// *************************************************************************** +void BNPManagerWindow::writeSettings() +{ +} + +// *************************************************************************** +void BNPManagerWindow::dragEnterEvent(QDragEnterEvent *event) +{ + // Accept only one file + // In the future a tabbed FileListDialog would accept more + if ( event->mimeData()->hasUrls() ) + event->acceptProposedAction(); +} +// *************************************************************************** +void BNPManagerWindow::dropEvent(QDropEvent *event) +{ + // reference to the BNPFileHandle singletone instance + BNPFileHandle& myBNPFileHandle = BNPFileHandle::getInstance(); + + // Excraft the local file url from the drop object and fill the table + const QMimeData *mimeData = event->mimeData(); + QList urlList = mimeData->urls(); + QString filePath; + QStringList fileList; + + if ( urlList.count() == 1 ) + { + // If it is a bnp file, open it + // If it is not a bnp file add it + + filePath = urlList.first().toLocalFile(); + if ( filePath.endsWith(".bnp", Qt::CaseInsensitive) ) + { + loadFile(filePath); + } + else + { + if ( m_openedBNPFile == "") + newFile(); + // Create a QStringList and pass it to addfiles + fileList.push_back( filePath ); + addFiles( fileList ); + // Reload current bnp + loadFile(m_openedBNPFile); + } + } + else if ( urlList.count() > 1 ) + { + // Dont accept any bnp file + QList::iterator it = urlList.begin(); + while ( it != urlList.end() ) + { + filePath = it->toLocalFile(); + if ( filePath.endsWith(".bnp") ) + { + nlwarning("Could not add a bnp file!", filePath.toStdString().c_str() ); + } + else + { + fileList.push_back( filePath ); + } + ++it; + } + if ( m_openedBNPFile == "") + newFile(); + addFiles( fileList ); + // Reload current bnp + loadFile(m_openedBNPFile); + } +} +} // namespace BNPManager diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_manager_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_manager_window.h new file mode 100644 index 000000000..89bd68a16 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_manager_window.h @@ -0,0 +1,156 @@ +// Object Viewer Qt - BNP Manager Plugin - MMORPG Framework +// Copyright (C) 2011 Roland Winklmeier +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef BNP_MANAGER_WINDOW_H +#define BNP_MANAGER_WINDOW_H + +// Project includes +//#include "ui_bnp_manager_window.h" + +// Qt includes +#include +#include +#include +#include + + +namespace BNPManager +{ + +class CBnpDirTreeDialog; +class BnpFileListDialog; +class BNPFileHandle; + +/** + * Main window class. Derived from QMainWindow and implements + * the basic layout like menue, toolbars and dialogs. + * + * \date 2011 + */ + +class BNPManagerWindow : public QMainWindow +{ + Q_OBJECT + +public: + + // Constructor + BNPManagerWindow(QWidget *parent = 0); + + //Destructor + ~BNPManagerWindow(); + + + QUndoStack *m_undoStack; + +public Q_SLOTS: + + /** + * Create a new file + * \return Filename string + */ + void newFile(); + + /** + * Open a file dialog to choose which file should be opened. + */ + void open(); + + /** + * Load a certain bnp file into the manager + * \param Filename + * \return true if everything went well + */ + bool loadFile(const QString fileName); + + /** + * close an opened bnp file and reset all views + */ + void close(); + + /** + * Add files into an opened bnp file. + * \param Filelist + */ + void addFiles(); + void addFiles( QStringList FileList ); + + /** + * Unpack the files marked in the filelist dialog into user defined + * directory. + * \param TBD + * \return true if everything went well + */ + void unpackFiles(); + + /** + * Delete marked files from the bnp file + * \param TBD + */ + void deleteFiles(); + +protected: + void dragEnterEvent (QDragEnterEvent *event); + void dropEvent(QDropEvent *event); + +private: + + /** + * Read plugin settings and set the window accordingly + */ + void readSettings(); + + /** + * Write plugin settings + */ + void writeSettings(); + + /** + * Create all plugin dialogs + */ + void createDialogs(); + + /** + * Create all plugin actions + */ + void createActions(); + + /** + * Create the plugin toolbar + */ + void createToolBars(); + + QToolBar *m_fileToolBar; + QToolBar *m_toolsBar; + + QAction *m_newAction; + QAction *m_openAction; + QAction *m_closeAction; + QAction *m_addFilesAction; + QAction *m_unpackFilesAction; + QAction *m_deleteFilesAction; + + CBnpDirTreeDialog *m_BnpDirTreeDialog; + BnpFileListDialog *m_BnpFileListDialog; + + QString m_DataPath; + QString m_openedBNPFile; + +}; /* class BNPManagerWindow */ + +} /* namespace Plugin */ + +#endif diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_manager_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_manager_window.ui new file mode 100644 index 000000000..4e695f72c --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_manager_window.ui @@ -0,0 +1,50 @@ + + + BNPManagerWindow + + + + 0 + 0 + 800 + 600 + + + + BNP Manager + + + + + + + QWidget#centralwidget { + image: url(:/images/ic_nel_georges_editor.png); + } + + + + + + + + + + + + + toolBar + + + TopToolBarArea + + + false + + + + + + + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_proxy_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_proxy_model.cpp new file mode 100644 index 000000000..d3657d13b --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_proxy_model.cpp @@ -0,0 +1,56 @@ +// Object Viewer Qt - BNP Manager Plugin - MMORPG Framework +// Copyright (C) 2011 Roland Winklmeier +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see + +// NeL includes +#include + +// project includes +#include "bnp_proxy_model.h" + +namespace BNPManager +{ + +bool BNPSortProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const +{ + if ( sourceModel()->hasChildren(left) ) + { + if ( !sourceModel()->hasChildren(right) ) + { + return true; + } + else + { + QString leftString = sourceModel()->data( left ).toString(); + QString rightString = sourceModel()->data( right ).toString(); + return QString::localeAwareCompare(leftString, rightString) < 0; + } + } + else + { + if ( sourceModel()->hasChildren(right) ) + return false; + else + { + QString leftString = sourceModel()->data( left ).toString(); + QString rightString = sourceModel()->data( right ).toString(); + return QString::localeAwareCompare(leftString, rightString) < 0; + } + } +} + +} /* namespace Plugin */ + +/* end of file */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_proxy_model.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_proxy_model.h new file mode 100644 index 000000000..ed2da5966 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/bnp_proxy_model.h @@ -0,0 +1,44 @@ +// Object Viewer Qt - BNP Manager Plugin - MMORPG Framework +// Copyright (C) 2011 Roland Winklmeier +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see + +#ifndef BNP_PROXY_MODEL_H +#define BNP_PROXY_MODEL_H + +// Qt includes +#include + +namespace BNPManager +{ + + class BNPSortProxyModel : public QSortFilterProxyModel + { + + public: + BNPSortProxyModel(QObject *parent = 0): QSortFilterProxyModel(parent) + { + } + ~BNPSortProxyModel() + { + } + + protected: + virtual bool lessThan ( const QModelIndex & left, const QModelIndex & right ) const; + + };/* class BNPSortProxyModel */ + +} // BNPManager + +#endif // BNP_PROXY_MODEL_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/images/ic_nel_add_item.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/images/ic_nel_add_item.png new file mode 100644 index 000000000..bde338f78 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/images/ic_nel_add_item.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/images/ic_nel_bnp_make.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/images/ic_nel_bnp_make.png new file mode 100644 index 000000000..19b749b1d Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/images/ic_nel_bnp_make.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/images/ic_nel_delete_item.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/images/ic_nel_delete_item.png new file mode 100644 index 000000000..a5a1787d5 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/images/ic_nel_delete_item.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/images/ic_nel_export.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/images/ic_nel_export.png new file mode 100644 index 000000000..9fc71c09d Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/images/ic_nel_export.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/images/ic_nel_new.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/images/ic_nel_new.png new file mode 100644 index 000000000..d45dcb467 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/images/ic_nel_new.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/images/ic_nel_reset_all.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/images/ic_nel_reset_all.png new file mode 100644 index 000000000..c67287408 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/images/ic_nel_reset_all.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/ovqt_plugin_bnp_manager.xml b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/ovqt_plugin_bnp_manager.xml new file mode 100644 index 000000000..43cea2022 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/bnp_manager/ovqt_plugin_bnp_manager.xml @@ -0,0 +1,10 @@ + + ovqt_plugin_bnp_manager + BNPManager + 0.1 + Krolock + Edit BNP Files + + + + \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/CMakeLists.txt index 3140f02fb..927e35eaa 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/CMakeLists.txt @@ -11,7 +11,6 @@ SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin. SET(OVQT_CORE_PLUGIN_HDR icore.h icontext.h - imenu_manager.h icore_listener.h ioptions_page.h core_plugin.h diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/context_manager.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/context_manager.cpp index 68e28429d..d82cdb63b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/context_manager.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/context_manager.cpp @@ -78,6 +78,18 @@ Core::IContext *ContextManager::context(const QString &id) const return 0; } +void ContextManager::registerUndoStack(QUndoStack *stack) +{ + nlassert(stack); + d->m_mainWindow->undoGroup()->addStack(stack); +} + +void ContextManager::unregisterUndoStack(QUndoStack *stack) +{ + nlassert(stack); + d->m_mainWindow->undoGroup()->removeStack(stack); +} + void ContextManager::activateContext(const QString &id) { const int index = indexOf(id); @@ -85,6 +97,11 @@ void ContextManager::activateContext(const QString &id) d->m_tabWidget->setCurrentIndex(index); } +void ContextManager::updateCurrentContext() +{ + d->m_mainWindow->updateContext(currentContext()); +} + void ContextManager::objectAdded(QObject *obj) { IContext *context = qobject_cast(obj); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/context_manager.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/context_manager.h index 7a3658fff..8151648e7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/context_manager.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/context_manager.h @@ -26,6 +26,7 @@ QT_BEGIN_NAMESPACE class QTabWidget; +class QUndoStack; QT_END_NAMESPACE namespace Core @@ -45,12 +46,17 @@ public: Core::IContext *currentContext() const; Core::IContext *context(const QString &id) const; + // temporary solution for multiple undo stacks per context + void registerUndoStack(QUndoStack *stack); + void unregisterUndoStack(QUndoStack *stack); + Q_SIGNALS: // the default argument '=0' is important for connects without the oldContext argument. void currentContextChanged(Core::IContext *context, Core::IContext *oldContext = 0); public Q_SLOTS: void activateContext(const QString &id); + void updateCurrentContext(); private Q_SLOTS: void objectAdded(QObject *obj); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.cpp index fa61b5700..b21d934c8 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.cpp @@ -17,7 +17,6 @@ // along with this program. If not, see . #include "core.h" -#include "imenu_manager.h" #include "context_manager.h" #include "main_window.h" #include "../../extension_system/iplugin_manager.h" @@ -50,7 +49,7 @@ bool CoreImpl::showOptionsDialog(const QString &group, return m_mainWindow->showOptionsDialog(group, page, parent); } -IMenuManager *CoreImpl::menuManager() const +MenuManager *CoreImpl::menuManager() const { return m_mainWindow->menuManager(); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.h index 2613a06a5..f34dd6ae6 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.h @@ -30,14 +30,14 @@ class CoreImpl : public ICore Q_OBJECT public: - CoreImpl(MainWindow *mainWindow); + explicit CoreImpl(MainWindow *mainWindow); virtual ~CoreImpl(); virtual bool showOptionsDialog(const QString &group = QString(), const QString &page = QString(), QWidget *parent = 0); - virtual IMenuManager *menuManager() const; + virtual MenuManager *menuManager() const; virtual ContextManager *contextManager() const; virtual QSettings *settings() const; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.qrc b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.qrc index a4c87d29c..68b6ad141 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.qrc +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.qrc @@ -1,6 +1,8 @@ icons/ic_nel_add_item.png + icons/ic_nel_redo.png + icons/ic_nel_undo.png icons/ic_nel_crash.png icons/ic_nel_delete_item.png icons/ic_nel_down_item.png diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_constants.h index 2acf4f731..18f3690a0 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_constants.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_constants.h @@ -23,93 +23,97 @@ namespace Core namespace Constants { -const char * const OVQT_VERSION_LONG = "0.1"; -const char * const OVQT_VENDOR = "Ryzom Core"; -const char * const OVQT_YEAR = "2010, 2011"; -const char * const OVQT_CORE_PLUGIN = "Core"; +const char *const OVQT_VERSION_LONG = "0.8"; +const char *const OVQT_VENDOR = "Ryzom Core"; +const char *const OVQT_YEAR = "2010, 2011"; +const char *const OVQT_CORE_PLUGIN = "Core"; //mainwindow -const char * const MAIN_WINDOW = "ObjectViewerQt.MainWindow"; +const char *const MAIN_WINDOW = "ObjectViewerQt.MainWindow"; //menubar -const char * const MENU_BAR = "ObjectViewerQt.MenuBar"; +const char *const MENU_BAR = "ObjectViewerQt.MenuBar"; //menus -const char * const M_FILE = "ObjectViewerQt.Menu.File"; -const char * const M_EDIT = "ObjectViewerQt.Menu.Edit"; -const char * const M_VIEW = "ObjectViewerQt.Menu.View"; -const char * const M_SCENE = "ObjectViewerQt.Menu.Scene"; -const char * const M_TOOLS = "ObjectViewerQt.Menu.Tools"; -const char * const M_WINDOW = "ObjectViewerQt.Menu.Window"; -const char * const M_HELP = "ObjectViewerQt.Menu.Help"; +const char *const M_FILE = "ObjectViewerQt.Menu.File"; +const char *const M_EDIT = "ObjectViewerQt.Menu.Edit"; +const char *const M_VIEW = "ObjectViewerQt.Menu.View"; +const char *const M_SCENE = "ObjectViewerQt.Menu.Scene"; +const char *const M_TOOLS = "ObjectViewerQt.Menu.Tools"; +const char *const M_WINDOW = "ObjectViewerQt.Menu.Window"; +const char *const M_HELP = "ObjectViewerQt.Menu.Help"; -const char * const M_FILE_RECENTFILES = "ObjectViewerQt.Menu.File.RecentFiles"; -const char * const M_SHEET = "ObjectViewerQt.Menu.Sheet"; +const char *const M_FILE_RECENTFILES = "ObjectViewerQt.Menu.File.RecentFiles"; +const char *const M_SHEET = "ObjectViewerQt.Menu.Sheet"; //actions -const char * const NEW = "ObjectViewerQt.New"; -const char * const OPEN = "ObjectViewerQt.Open"; -const char * const SAVE = "ObjectViewerQt.Save"; -const char * const SAVE_AS = "ObjectViewerQt.SaveAs"; -const char * const SAVE_ALL = "ObjectViewerQt.SaveAll"; -const char * const EXIT = "ObjectViewerQt.Exit"; +const char *const NEW = "ObjectViewerQt.New"; +const char *const OPEN = "ObjectViewerQt.Open"; +const char *const SAVE = "ObjectViewerQt.Save"; +const char *const SAVE_AS = "ObjectViewerQt.SaveAs"; +const char *const SAVE_ALL = "ObjectViewerQt.SaveAll"; +const char *const EXIT = "ObjectViewerQt.Exit"; -const char * const UNDO = "ObjectViewerQt.Undo"; -const char * const REDO = "ObjectViewerQt.Redo"; -const char * const CUT = "ObjectViewerQt.Cut"; -const char * const COPY = "ObjectViewerQt.Copy"; -const char * const PASTE = "ObjectViewerQt.Paste"; -const char * const DEL = "ObjectViewerQt.Del"; -const char * const FIND = "ObjectViewerQt.Find"; -const char * const SELECT_ALL = "ObjectViewerQt.SelectAll"; -const char * const GOTO_POS = "ObjectViewerQt.Goto"; +const char *const UNDO = "ObjectViewerQt.Undo"; +const char *const REDO = "ObjectViewerQt.Redo"; +const char *const CUT = "ObjectViewerQt.Cut"; +const char *const COPY = "ObjectViewerQt.Copy"; +const char *const PASTE = "ObjectViewerQt.Paste"; +const char *const DEL = "ObjectViewerQt.Del"; +const char *const FIND = "ObjectViewerQt.Find"; +const char *const SELECT_ALL = "ObjectViewerQt.SelectAll"; +const char *const GOTO_POS = "ObjectViewerQt.Goto"; -const char * const SETTINGS = "ObjectViewerQt.Settings"; -const char * const TOGGLE_FULLSCREEN = "ObjectViewerQt.ToggleFullScreen"; +const char *const SETTINGS = "ObjectViewerQt.Settings"; +const char *const TOGGLE_FULLSCREEN = "ObjectViewerQt.ToggleFullScreen"; -const char * const CLOSE = "ObjectViewerQt.Close"; -const char * const CLOSEALL = "ObjectViewerQt.CloseAll"; -const char * const CLOSEOTHERS = "ObjectViewerQt.CloseOthers"; -const char * const ABOUT = "ObjectViewerQt.About"; -const char * const ABOUT_PLUGINS = "ObjectViewerQt.AboutPlugins"; -const char * const ABOUT_QT = "ObjectViewerQt.AboutQt"; +const char *const CLOSE = "ObjectViewerQt.Close"; +const char *const CLOSEALL = "ObjectViewerQt.CloseAll"; +const char *const CLOSEOTHERS = "ObjectViewerQt.CloseOthers"; +const char *const ABOUT = "ObjectViewerQt.About"; +const char *const ABOUT_PLUGINS = "ObjectViewerQt.AboutPlugins"; +const char *const ABOUT_QT = "ObjectViewerQt.AboutQt"; //settings -const char * const SETTINGS_CATEGORY_GENERAL = "general"; -const char * const SETTINGS_CATEGORY_GENERAL_ICON = ":/icons/ic_nel_generic_settings.png"; -const char * const SETTINGS_TR_CATEGORY_GENERAL = QT_TR_NOOP("General"); +const char *const SETTINGS_CATEGORY_GENERAL = "general"; +const char *const SETTINGS_CATEGORY_GENERAL_ICON = ":/icons/ic_nel_generic_settings.png"; +const char *const SETTINGS_TR_CATEGORY_GENERAL = QT_TR_NOOP("General"); -const char * const MAIN_WINDOW_SECTION = "MainWindow"; -const char * const MAIN_WINDOW_STATE = "WindowState"; -const char * const MAIN_WINDOW_GEOMETRY = "WindowGeometry"; -const char * const QT_STYLE = "QtStyle"; -const char * const QT_PALETTE = "QtPalette"; +const char *const MAIN_WINDOW_SECTION = "MainWindow"; +const char *const MAIN_WINDOW_STATE = "WindowState"; +const char *const MAIN_WINDOW_GEOMETRY = "WindowGeometry"; +const char *const QT_STYLE = "QtStyle"; +const char *const QT_PALETTE = "QtPalette"; -const char * const LANGUAGE = "Language"; -const char * const PLUGINS_PATH = "PluginPath"; -const char * const DATA_PATH_SECTION = "DataPath"; -const char * const SEARCH_PATHS = "SearchPaths"; -const char * const RECURSIVE_SEARCH_PATHS = "RecursiveSearchPathes"; -const char * const LEVELDESIGN_PATH = "LevelDesignPath"; -const char * const ASSETS_PATH = "AssetsPath"; -const char * const REMAP_EXTENSIONS = "RemapExtensions"; +const char *const LANGUAGE = "Language"; +const char *const PLUGINS_PATH = "PluginPath"; +const char *const DATA_PATH_SECTION = "DataPath"; +const char *const SEARCH_PATHS = "SearchPaths"; +const char *const RECURSIVE_SEARCH_PATHS = "RecursiveSearchPathes"; +const char *const LEVELDESIGN_PATH = "LevelDesignPath"; +const char *const PRIMITIVES_PATH = "PrimitivesPath"; +const char *const ASSETS_PATH = "AssetsPath"; +const char *const LIGOCONFIG_FILE = "LigoConfigFile"; +const char *const REMAP_EXTENSIONS = "RemapExtensions"; -const char * const LOG_SECTION = "LogSettings"; -const char * const LOG_ERROR = "LogError"; -const char * const LOG_WARNING = "LogWarning"; -const char * const LOG_DEBUG = "LogDebug"; -const char * const LOG_ASSERT = "LogAssert"; -const char * const LOG_INFO = "LogInfo"; +const char *const LOG_SECTION = "LogSettings"; +const char *const LOG_ERROR = "LogError"; +const char *const LOG_WARNING = "LogWarning"; +const char *const LOG_DEBUG = "LogDebug"; +const char *const LOG_ASSERT = "LogAssert"; +const char *const LOG_INFO = "LogInfo"; //resources -const char * const ICON_NEL = ":/core/images/nel.png"; -const char * const ICON_SETTINGS = ":/core/images/preferences.png"; -const char * const ICON_PILL = ":/core/icons/ic_nel_pill.png"; -const char * const ICON_OPEN = ":/core/icons/ic_nel_open.png"; -const char * const ICON_NEW = ":/core/icons/ic_nel_new.png"; -const char * const ICON_SAVE = ":/core/icons/ic_nel_save.png"; -const char * const ICON_SAVE_AS = ":/core/icons/ic_nel_save_as.png"; -const char * const ICON_CRASH = ":/core/icons/ic_nel_crash.png"; +const char *const ICON_NEL = ":/core/images/nel.png"; +const char *const ICON_SETTINGS = ":/core/images/preferences.png"; +const char *const ICON_PILL = ":/core/icons/ic_nel_pill.png"; +const char *const ICON_OPEN = ":/core/icons/ic_nel_open.png"; +const char *const ICON_NEW = ":/core/icons/ic_nel_new.png"; +const char *const ICON_SAVE = ":/core/icons/ic_nel_save.png"; +const char *const ICON_SAVE_AS = ":/core/icons/ic_nel_save_as.png"; +const char *const ICON_CRASH = ":/core/icons/ic_nel_crash.png"; +const char *const ICON_UNDO = ":/core/icons/ic_nel_undo.png"; +const char *const ICON_REDO = ":/core/icons/ic_nel_redo.png"; } // namespace Constants } // namespace Core diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.cpp index 92e776068..55633feaf 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.cpp @@ -37,6 +37,8 @@ using namespace Core; CorePlugin::CorePlugin() + : m_plugMan(0), + m_mainWindow(0) { } @@ -49,7 +51,8 @@ CorePlugin::~CorePlugin() qDeleteAll(m_autoReleaseObjects); m_autoReleaseObjects.clear(); - delete m_mainWindow; + if (m_mainWindow) + delete m_mainWindow; } bool CorePlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString) @@ -61,8 +64,8 @@ bool CorePlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QStr bool success = m_mainWindow->initialize(errorString); GeneralSettingsPage *generalSettings = new GeneralSettingsPage(this); - CSearchPathsSettingsPage *searchPathPage = new CSearchPathsSettingsPage(false, this); - CSearchPathsSettingsPage *recureseSearchPathPage = new CSearchPathsSettingsPage(true, this); + SearchPathsSettingsPage *searchPathPage = new SearchPathsSettingsPage(false, this); + SearchPathsSettingsPage *recureseSearchPathPage = new SearchPathsSettingsPage(true, this); generalSettings->applyGeneralSettings(); searchPathPage->applySearchPaths(); @@ -92,31 +95,6 @@ void CorePlugin::setNelContext(NLMISC::INelContext *nelContext) m_libContext = new NLMISC::CLibraryContext(*nelContext); } -QString CorePlugin::name() const -{ - return QLatin1String(Constants::OVQT_CORE_PLUGIN); -} - -QString CorePlugin::version() const -{ - return Constants::OVQT_VERSION_LONG; -} - -QString CorePlugin::vendor() const -{ - return Constants::OVQT_VENDOR; -} - -QString CorePlugin::description() const -{ - return "Core plugin."; -} - -QStringList CorePlugin::dependencies() const -{ - return QStringList(); -} - void CorePlugin::addAutoReleasedObject(QObject *obj) { m_plugMan->addObject(obj); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.h index 5c95d22c9..5062227e3 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.h @@ -53,12 +53,6 @@ public: void setNelContext(NLMISC::INelContext *nelContext); - QString name() const; - QString version() const; - QString vendor() const; - QString description() const; - QStringList dependencies() const; - void addAutoReleasedObject(QObject *obj); ExtensionSystem::IPluginManager *pluginManager() const diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/general_settings_page.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/general_settings_page.cpp index 51da80f67..b1ef3b659 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/general_settings_page.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/general_settings_page.cpp @@ -82,6 +82,17 @@ void GeneralSettingsPage::applyGeneralSettings() else QApplication::setPalette(m_originalPalette); settings->endGroup(); + + // Add primitives path and ligo config file to CPath + settings->beginGroup(Core::Constants::DATA_PATH_SECTION); + QString primitivePath = settings->value(Core::Constants::PRIMITIVES_PATH, "l:/primitives").toString(); + QString ligoConfigFile = settings->value(Core::Constants::LIGOCONFIG_FILE, "l:/leveldesign/world_editor_files/world_editor_classes.xml").toString(); + QString leveldesignPath = settings->value(Core::Constants::LEVELDESIGN_PATH, "l:/leveldesign").toString(); + NLMISC::CPath::addSearchPath(primitivePath.toStdString(), true, false); + NLMISC::CPath::display(); + NLMISC::CPath::addSearchFile(ligoConfigFile.toStdString()); + NLMISC::CPath::addSearchPath(leveldesignPath.toStdString(), true, false); + settings->endGroup(); } QWidget *GeneralSettingsPage::createPage(QWidget *parent) @@ -94,6 +105,8 @@ QWidget *GeneralSettingsPage::createPage(QWidget *parent) connect(m_ui.pluginsPathButton, SIGNAL(clicked()), this, SLOT(setPluginsPath())); connect(m_ui.leveldesignPathButton, SIGNAL(clicked()), this, SLOT(setLevelDesignPath())); connect(m_ui.assetsPathButton, SIGNAL(clicked()), this, SLOT(setAssetsPath())); + connect(m_ui.primitivesPathButton, SIGNAL(clicked()), this, SLOT(setPrimitivesPath())); + connect(m_ui.ligoConfigFileButton, SIGNAL(clicked()), this, SLOT(setLigoConfigFile())); return m_page; } @@ -135,6 +148,27 @@ void GeneralSettingsPage::setLevelDesignPath() } } +void GeneralSettingsPage::setPrimitivesPath() +{ + QString newPath = QFileDialog::getExistingDirectory(0, tr("Set the primitives path"), + m_ui.primitivesPathLineEdit->text()); + if (!newPath.isEmpty()) + { + m_ui.primitivesPathLineEdit->setText(newPath); + } +} + +void GeneralSettingsPage::setLigoConfigFile() +{ + QString newFile = QFileDialog::getOpenFileName(0, tr("Set the ligo config file"), + m_ui.ligoConfigFileLineEdit->text()); + if (!newFile.isEmpty()) + { + m_ui.ligoConfigFileLineEdit->setText(newFile); + } +} + + void GeneralSettingsPage::setAssetsPath() { QString newPath = QFileDialog::getExistingDirectory(0, tr("Set the assets path"), @@ -165,6 +199,8 @@ void GeneralSettingsPage::readSettings() settings->beginGroup(Core::Constants::DATA_PATH_SECTION); m_ui.leveldesignPathLineEdit->setText(settings->value(Core::Constants::LEVELDESIGN_PATH, "l:/leveldesign").toString()); m_ui.assetsPathLineEdit->setText(settings->value(Core::Constants::ASSETS_PATH, "w:/database").toString()); + m_ui.primitivesPathLineEdit->setText(settings->value(Core::Constants::PRIMITIVES_PATH, "l:/primitives").toString()); + m_ui.ligoConfigFileLineEdit->setText(settings->value(Core::Constants::LIGOCONFIG_FILE, "l:/leveldesign/world_editor_files/world_editor_classes.xml").toString()); settings->endGroup(); } @@ -185,6 +221,8 @@ void GeneralSettingsPage::writeSettings() settings->beginGroup(Core::Constants::DATA_PATH_SECTION); settings->setValue(Core::Constants::LEVELDESIGN_PATH, m_ui.leveldesignPathLineEdit->text()); settings->setValue(Core::Constants::ASSETS_PATH, m_ui.assetsPathLineEdit->text()); + settings->setValue(Core::Constants::PRIMITIVES_PATH, m_ui.primitivesPathLineEdit->text()); + settings->setValue(Core::Constants::LIGOCONFIG_FILE, m_ui.ligoConfigFileLineEdit->text()); settings->endGroup(); settings->sync(); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/general_settings_page.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/general_settings_page.h index 2fbcb842a..66eacd189 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/general_settings_page.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/general_settings_page.h @@ -37,7 +37,7 @@ class GeneralSettingsPage : public Core::IOptionsPage Q_OBJECT public: - GeneralSettingsPage(QObject *parent = 0); + explicit GeneralSettingsPage(QObject *parent = 0); ~GeneralSettingsPage(); QString id() const; @@ -57,6 +57,8 @@ private Q_SLOTS: void setPluginsPath(); void setLevelDesignPath(); void setAssetsPath(); + void setPrimitivesPath(); + void setLigoConfigFile(); private: void readSettings(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/general_settings_page.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/general_settings_page.ui index d2aa042e3..7d40b65df 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/general_settings_page.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/general_settings_page.ui @@ -105,7 +105,7 @@ - Plugins path: + Plugins @@ -129,7 +129,7 @@ - Level design path: + Sheets @@ -153,7 +153,7 @@ - Assets path: + Assets Database: @@ -174,6 +174,40 @@ + + + + Primitives + + + + + + + + + + ... + + + + + + + + + + Ligo Config File + + + + + + + ... + + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/icons/ic_nel_redo.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/icons/ic_nel_redo.png new file mode 100644 index 000000000..19ccf20f1 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/icons/ic_nel_redo.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/icons/ic_nel_undo.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/icons/ic_nel_undo.png new file mode 100644 index 000000000..d605e4602 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/icons/ic_nel_undo.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/icore.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/icore.h index 13b22bfa5..4f1ee474f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/icore.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/icore.h @@ -35,7 +35,7 @@ class IPluginManager; namespace Core { -class IMenuManager; +class MenuManager; class ContextManager; class CORE_EXPORT ICore : public QObject @@ -52,7 +52,7 @@ public: const QString &page = QString(), QWidget *parent = 0) = 0; - virtual IMenuManager *menuManager() const = 0; + virtual MenuManager *menuManager() const = 0; virtual ContextManager *contextManager() const = 0; virtual QSettings *settings() const = 0; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/imenu_manager.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/imenu_manager.h deleted file mode 100644 index be80dbbc4..000000000 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/imenu_manager.h +++ /dev/null @@ -1,62 +0,0 @@ -// Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// Copyright (C) 2011 Dzmitry Kamiahin -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero 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 Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef IMENU_MANAGER_H -#define IMENU_MANAGER_H - -#include "core_global.h" - -#include -#include - -QT_BEGIN_NAMESPACE -class QMenu; -class QAction; -class QString; -class QMenuBar; -QT_END_NAMESPACE - -namespace Core -{ -/* -@interface IMenuManager -@brief The IMenuManager is an interface for providing a registration of menus and menu item. -@details The IMenuManager provides centralized access to menus and menu items. -All menus and menu items should be registered in the IMenuManager. -*/ -class CORE_EXPORT IMenuManager : public QObject -{ - Q_OBJECT -public: - IMenuManager(QObject *parent = 0): QObject(parent) {} - virtual ~IMenuManager() {} - - virtual void registerMenu(QMenu *menu, const QString &id) = 0; - virtual void registerAction(QAction *action, const QString &id) = 0; - - virtual QMenu *menu(const QString &id) const = 0; - virtual QAction *action(const QString &id) const = 0; - - virtual void unregisterMenu(const QString &id) = 0; - virtual void unregisterAction(const QString &id) = 0; - - virtual QMenuBar *menuBar() const = 0; -}; - -} // namespace Core - -#endif // IMENU_MANAGER_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/main_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/main_window.cpp index 21334f7ea..6e409e75d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/main_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/main_window.cpp @@ -30,6 +30,7 @@ // Qt includes #include +#include #include namespace Core @@ -64,8 +65,7 @@ MainWindow::MainWindow(ExtensionSystem::IPluginManager *pluginManager, QWidget * setMenuBar(m_menuBar); #endif - m_menuManager = new MenuManager(this); - m_menuManager->setMenuBar(m_menuBar); + m_menuManager = new MenuManager(m_menuBar, this); m_tabWidget = new QTabWidget(this); m_tabWidget->setTabPosition(QTabWidget::South); @@ -106,14 +106,14 @@ bool MainWindow::initialize(QString *errorString) void MainWindow::extensionsInitialized() { readSettings(); - connect(m_contextManager, SIGNAL(currentContextChanged(Core::IContext*)), - this, SLOT(updateContext(Core::IContext*))); + connect(m_contextManager, SIGNAL(currentContextChanged(Core::IContext *)), + this, SLOT(updateContext(Core::IContext *))); if (m_contextManager->currentContext() != NULL) updateContext(m_contextManager->currentContext()); show(); } -IMenuManager *MainWindow::menuManager() const +MenuManager *MainWindow::menuManager() const { return m_menuManager; } @@ -128,6 +128,11 @@ QSettings *MainWindow::settings() const return m_settings; } +QUndoGroup *MainWindow::undoGroup() const +{ + return m_undoGroup; +} + ExtensionSystem::IPluginManager *MainWindow::pluginManager() const { return m_pluginManager; @@ -135,12 +140,16 @@ ExtensionSystem::IPluginManager *MainWindow::pluginManager() const void MainWindow::addContextObject(IContext *context) { - m_undoGroup->addStack(context->undoStack()); + QUndoStack *stack = context->undoStack(); + if (stack) + m_undoGroup->addStack(stack); } void MainWindow::removeContextObject(IContext *context) { - m_undoGroup->removeStack(context->undoStack()); + QUndoStack *stack = context->undoStack(); + if (stack) + m_undoGroup->removeStack(stack); } void MainWindow::open() @@ -204,7 +213,7 @@ bool MainWindow::showOptionsDialog(const QString &group, { if (!parent) parent = this; - CSettingsDialog settingsDialog(m_pluginManager, group, page, parent); + SettingsDialog settingsDialog(m_pluginManager, group, page, parent); settingsDialog.show(); bool ok = settingsDialog.execDialog(); if (ok) @@ -382,8 +391,17 @@ void MainWindow::createMenus() m_fileMenu->addAction(m_exitAction); m_editMenu = m_menuBar->addMenu(tr("&Edit")); - m_editMenu->addAction(m_undoGroup->createUndoAction(this)); - m_editMenu->addAction(m_undoGroup->createRedoAction(this)); + QAction *undoAction = m_undoGroup->createUndoAction(this); + menuManager()->registerAction(undoAction, Constants::UNDO); + undoAction->setIcon(QIcon(Constants::ICON_UNDO)); + undoAction->setShortcut(QKeySequence::Undo); + QAction *redoAction = m_undoGroup->createRedoAction(this); + menuManager()->registerAction(redoAction, Constants::REDO); + redoAction->setIcon(QIcon(Constants::ICON_REDO)); + redoAction->setShortcut(QKeySequence::Redo); + m_editMenu->addAction(undoAction); + m_editMenu->addAction(redoAction); + m_editMenu->addSeparator(); m_editMenu->addAction(m_cutAction); m_editMenu->addAction(m_copyAction); @@ -398,6 +416,7 @@ void MainWindow::createMenus() m_viewMenu = m_menuBar->addMenu(tr("&View")); m_viewMenu->addAction(m_fullscreenAction); + m_viewMenu->addAction(m_dockWidget->toggleViewAction()); menuManager()->registerMenu(m_viewMenu, Constants::M_VIEW); m_toolsMenu = m_menuBar->addMenu(tr("&Tools")); @@ -426,7 +445,14 @@ void MainWindow::createStatusBar() void MainWindow::createDialogs() { - m_pluginView = new ExtensionSystem::CPluginView(m_pluginManager, this); + m_pluginView = new PluginView(m_pluginManager, this); + + // Create undo/redo command list + m_dockWidget = new QDockWidget("Command List", this); + m_dockWidget->setObjectName(QString::fromUtf8("UndoRedoCommandDockWidget")); + QUndoView *undoView = new QUndoView(m_undoGroup, m_dockWidget); + m_dockWidget->setWidget(undoView); + addDockWidget(Qt::RightDockWidgetArea, m_dockWidget); } void MainWindow::readSettings() diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/main_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/main_window.h index ce439b885..a75126823 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/main_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/main_window.h @@ -34,7 +34,6 @@ namespace Core class CSettingsDialog; class CorePlugin; class IContext; -class IMenuManager; class MenuManager; class ContextManager; class CoreImpl; @@ -50,9 +49,10 @@ public: bool initialize(QString *errorString); void extensionsInitialized(); - IMenuManager *menuManager() const; + MenuManager *menuManager() const; ContextManager *contextManager() const; QSettings *settings() const; + QUndoGroup *undoGroup() const; ExtensionSystem::IPluginManager *pluginManager() const; @@ -63,6 +63,7 @@ public Q_SLOTS: bool showOptionsDialog(const QString &group = QString(), const QString &page = QString(), QWidget *parent = 0); + void updateContext(Core::IContext *context); private Q_SLOTS: void open(); @@ -78,7 +79,6 @@ private Q_SLOTS: void gotoPos(); void setFullScreen(bool enabled); void about(); - void updateContext(Core::IContext *context); protected: virtual void closeEvent(QCloseEvent *event); @@ -93,7 +93,7 @@ private: void writeSettings(); ExtensionSystem::IPluginManager *m_pluginManager; - ExtensionSystem::CPluginView *m_pluginView; + PluginView *m_pluginView; MenuManager *m_menuManager; ContextManager *m_contextManager; CoreImpl *m_coreImpl; @@ -101,6 +101,7 @@ private: QPalette m_originalPalette; QString m_lastDir; + QDockWidget *m_dockWidget; QUndoGroup *m_undoGroup; QSettings *m_settings; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/menu_manager.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/menu_manager.cpp index 4bd80a616..76a4d7d91 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/menu_manager.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/menu_manager.cpp @@ -21,74 +21,76 @@ // NeL includes #include -// Qt includes -#include -#include -#include - namespace Core { -MenuManager::MenuManager(QObject *parent) - : IMenuManager(parent), - _menuBar(0) +struct MenuManagerPrivate { + MenuManagerPrivate(): m_menuBar(0) {} + QMenuBar *m_menuBar; + typedef QHash IdMenuMap; + IdMenuMap m_menuMap; + typedef QHash IdActionMap; + IdActionMap m_actionMap; +}; + +MenuManager::MenuManager(QMenuBar *menuBar, QObject *parent) + : QObject(parent), + d(new MenuManagerPrivate()) +{ + d->m_menuBar = menuBar; } MenuManager::~MenuManager() { - _menuMap.clear(); + d->m_menuMap.clear(); + delete d; } void MenuManager::registerMenu(QMenu *menu, const QString &id) { menu->setObjectName(id); - _menuMap.insert(id, menu); + d->m_menuMap.insert(id, menu); } void MenuManager::registerAction(QAction *action, const QString &id) { action->setObjectName(id); - _actionMap.insert(id, action); + d->m_actionMap.insert(id, action); } QMenu *MenuManager::menu(const QString &id) const { QMenu *result = 0; - if (!_menuMap.contains(id)) + if (!d->m_menuMap.contains(id)) nlwarning("QMenu %s not found", id.toStdString().c_str()); else - result = _menuMap.value(id); + result = d->m_menuMap.value(id); return result; } QAction *MenuManager::action(const QString &id) const { QAction *result = 0; - if (!_actionMap.contains(id)) + if (!d->m_actionMap.contains(id)) nlwarning("QAction %s not found", id.toStdString().c_str()); else - result = _actionMap.value(id); + result = d->m_actionMap.value(id); return result; } void MenuManager::unregisterMenu(const QString &id) { - _menuMap.remove(id); + d->m_menuMap.remove(id); } void MenuManager::unregisterAction(const QString &id) { - _actionMap.remove(id); + d->m_actionMap.remove(id); } QMenuBar *MenuManager::menuBar() const { - return _menuBar; -} - -void MenuManager::setMenuBar(QMenuBar *menuBar) -{ - _menuBar = menuBar; + return d->m_menuBar; } } /* namespace Core */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/menu_manager.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/menu_manager.h index aab603355..fd6af8f3a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/menu_manager.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/menu_manager.h @@ -19,39 +19,47 @@ #define MENU_MANAGER_H // Project includes -#include "imenu_manager.h" +#include "core_global.h" // Qt includes #include +#include +#include +#include +#include +#include namespace Core { +struct MenuManagerPrivate; -class MenuManager : public IMenuManager +/* +@interface MenuManager +@brief The MenuManager provide the interface for registration of menus and menu item. +@details The MenuManager provides centralized access to menus and menu items. +All menus and menu items should be registered in the MenuManager. +*/ +class CORE_EXPORT MenuManager: public QObject { Q_OBJECT public: - MenuManager(QObject *parent = 0); + MenuManager(QMenuBar *menuBar, QObject *parent = 0); virtual ~MenuManager(); - virtual void registerMenu(QMenu *menu, const QString &id); - virtual void registerAction(QAction *action, const QString &id); + void registerMenu(QMenu *menu, const QString &id); + void registerAction(QAction *action, const QString &id); - virtual QMenu *menu(const QString &id) const; - virtual QAction *action(const QString &id) const; + QMenu *menu(const QString &id) const; + QAction *action(const QString &id) const; - virtual void unregisterMenu(const QString &id); - virtual void unregisterAction(const QString &id); + void unregisterMenu(const QString &id); + void unregisterAction(const QString &id); - virtual QMenuBar *menuBar() const; - void setMenuBar(QMenuBar *menuBar); + QMenuBar *menuBar() const; private: - QMenuBar *_menuBar; - typedef QHash IdMenuMap; - IdMenuMap _menuMap; - typedef QHash IdActionMap; - IdActionMap _actionMap; + + MenuManagerPrivate *d; }; } // namespace Core diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/ovqt_plugin_core.xml b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/ovqt_plugin_core.xml new file mode 100644 index 000000000..c0d38aa75 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/ovqt_plugin_core.xml @@ -0,0 +1,7 @@ + + ovqt_plugin_core + Core + 0.8 + Ryzom Core + Core plugin. + \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/plugin_view_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/plugin_view_dialog.cpp index b45d46418..175902d39 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/plugin_view_dialog.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/plugin_view_dialog.cpp @@ -16,11 +16,12 @@ // along with this program. If not, see . #include "plugin_view_dialog.h" +#include "core_constants.h" + +#include "nel/misc/debug.h" // Qt includes #include -#include -#include #include #include #include @@ -29,45 +30,79 @@ #include "../../extension_system/iplugin_spec.h" #include "../../extension_system/iplugin_manager.h" -namespace ExtensionSystem +namespace Core { -CPluginView::CPluginView(IPluginManager *pluginManager, QWidget *parent) - : QDialog(parent) +PluginView::PluginView(ExtensionSystem::IPluginManager *pluginManager, QWidget *parent) + : QDialog(parent), + m_checkStateColumn(0) { - _ui.setupUi(this); - _pluginManager = pluginManager; + m_ui.setupUi(this); + m_pluginManager = pluginManager; - connect(_pluginManager, SIGNAL(pluginsChanged()), this, SLOT(updateList())); + connect(m_pluginManager, SIGNAL(pluginsChanged()), this, SLOT(updateList())); + connect(this, SIGNAL(accepted()), this, SLOT(updateSettings())); + // WhiteList is list of plugins which can not disable. + m_whiteList << Constants::OVQT_CORE_PLUGIN; updateList(); } -CPluginView::~CPluginView() +PluginView::~PluginView() { } -void CPluginView::updateList() +void PluginView::updateList() { static QIcon okIcon = QApplication::style()->standardIcon(QStyle::SP_DialogApplyButton); static QIcon errorIcon = QApplication::style()->standardIcon(QStyle::SP_DialogCancelButton); + static QIcon notLoadedIcon = QApplication::style()->standardIcon(QStyle::SP_DialogResetButton); + + m_specToItem.clear(); QList items; - Q_FOREACH (IPluginSpec *spec, _pluginManager->plugins()) + Q_FOREACH (ExtensionSystem::IPluginSpec *spec, m_pluginManager->plugins()) { QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() - << "" << spec->name() << QString("%1").arg(spec->version()) << spec->vendor() << QDir::toNativeSeparators(spec->filePath())); - item->setIcon(0, spec->hasError() ? errorIcon : okIcon); + + bool ok = !spec->hasError(); + QIcon icon = ok ? okIcon : errorIcon; + if (ok && (spec->state() != ExtensionSystem::State::Running)) + icon = notLoadedIcon; + + item->setIcon(m_checkStateColumn, icon); + + if (!m_whiteList.contains(spec->name())) + item->setCheckState(m_checkStateColumn, spec->isEnabled() ? Qt::Checked : Qt::Unchecked); + items.append(item); + m_specToItem.insert(spec, item); } - _ui.pluginTreeWidget->clear(); + m_ui.pluginTreeWidget->clear(); if (!items.isEmpty()) - _ui.pluginTreeWidget->addTopLevelItems(items); + m_ui.pluginTreeWidget->addTopLevelItems(items); + + m_ui.pluginTreeWidget->resizeColumnToContents(m_checkStateColumn); } -} /* namespace NLQT */ \ No newline at end of file +void PluginView::updateSettings() +{ + Q_FOREACH (ExtensionSystem::IPluginSpec *spec, m_pluginManager->plugins()) + { + if (m_specToItem.contains(spec) && (!m_whiteList.contains(spec->name()))) + { + QTreeWidgetItem *item = m_specToItem.value(spec); + if (item->checkState(m_checkStateColumn) == Qt::Checked) + spec->setEnabled(true); + else + spec->setEnabled(false); + } + } +} + +} /* namespace Core */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/plugin_view_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/plugin_view_dialog.h index 0f12b64a3..aae16749d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/plugin_view_dialog.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/plugin_view_dialog.h @@ -20,28 +20,39 @@ #include "ui_plugin_view_dialog.h" +#include +#include + namespace ExtensionSystem { - class IPluginManager; +class IPluginSpec; +} -class CPluginView: public QDialog +namespace Core +{ + +class PluginView: public QDialog { Q_OBJECT public: - CPluginView(IPluginManager *pluginManager, QWidget *parent = 0); - ~CPluginView(); + PluginView(ExtensionSystem::IPluginManager *pluginManager, QWidget *parent = 0); + ~PluginView(); private Q_SLOTS: void updateList(); + void updateSettings(); private: - IPluginManager *_pluginManager; - Ui::CPluginView _ui; -}; /* class CPluginView */ + const int m_checkStateColumn; + QMap m_specToItem; + QStringList m_whiteList; + ExtensionSystem::IPluginManager *m_pluginManager; + Ui::PluginView m_ui; +}; /* class PluginView */ -} /* namespace NLQT */ +} /* namespace Core */ #endif // PLUGIN_VIEW_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/plugin_view_dialog.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/plugin_view_dialog.ui index 2fb0f568e..9d7d395be 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/plugin_view_dialog.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/plugin_view_dialog.ui @@ -1,13 +1,13 @@ - CPluginView - + PluginView + 0 0 - 691 - 249 + 756 + 296 @@ -37,14 +37,6 @@ true - - 100 - - - - State - - Name @@ -120,13 +112,13 @@ - + closePushButton clicked() - CPluginView + PluginView accept() diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/qtwin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/qtwin.cpp index dc0fb6cf0..2ebb69134 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/qtwin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/qtwin.cpp @@ -40,9 +40,9 @@ typedef struct _MARGINS int cyBottomHeight; } MARGINS, *PMARGINS; -typedef HRESULT (WINAPI *PtrDwmIsCompositionEnabled)(BOOL* pfEnabled); -typedef HRESULT (WINAPI *PtrDwmExtendFrameIntoClientArea)(HWND hWnd, const MARGINS* pMarInset); -typedef HRESULT (WINAPI *PtrDwmEnableBlurBehindWindow)(HWND hWnd, const DWM_BLURBEHIND* pBlurBehind); +typedef HRESULT (WINAPI *PtrDwmIsCompositionEnabled)(BOOL *pfEnabled); +typedef HRESULT (WINAPI *PtrDwmExtendFrameIntoClientArea)(HWND hWnd, const MARGINS *pMarInset); +typedef HRESULT (WINAPI *PtrDwmEnableBlurBehindWindow)(HWND hWnd, const DWM_BLURBEHIND *pBlurBehind); typedef HRESULT (WINAPI *PtrDwmGetColorizationColor)(DWORD *pcrColorization, BOOL *pfOpaqueBlend); static PtrDwmIsCompositionEnabled pDwmIsCompositionEnabled= 0; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/search_paths_settings_page.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/search_paths_settings_page.cpp index 355a9c0e3..7fca0f252 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/search_paths_settings_page.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/search_paths_settings_page.cpp @@ -33,18 +33,18 @@ namespace Core QString lastDir = "."; -CSearchPathsSettingsPage::CSearchPathsSettingsPage(bool recurse, QObject *parent) +SearchPathsSettingsPage::SearchPathsSettingsPage(bool recurse, QObject *parent) : IOptionsPage(parent), m_recurse(recurse), m_page(0) { } -CSearchPathsSettingsPage::~CSearchPathsSettingsPage() +SearchPathsSettingsPage::~SearchPathsSettingsPage() { } -QString CSearchPathsSettingsPage::id() const +QString SearchPathsSettingsPage::id() const { if (m_recurse) return QLatin1String("search_recurse_paths"); @@ -52,7 +52,7 @@ QString CSearchPathsSettingsPage::id() const return QLatin1String("search_paths"); } -QString CSearchPathsSettingsPage::trName() const +QString SearchPathsSettingsPage::trName() const { if (m_recurse) return tr("Search Recurse Paths"); @@ -60,22 +60,22 @@ QString CSearchPathsSettingsPage::trName() const return tr("Search Paths"); } -QString CSearchPathsSettingsPage::category() const +QString SearchPathsSettingsPage::category() const { return QLatin1String(Constants::SETTINGS_CATEGORY_GENERAL); } -QString CSearchPathsSettingsPage::trCategory() const +QString SearchPathsSettingsPage::trCategory() const { return tr(Constants::SETTINGS_TR_CATEGORY_GENERAL); } -QIcon CSearchPathsSettingsPage::categoryIcon() const +QIcon SearchPathsSettingsPage::categoryIcon() const { return QIcon(); } -QWidget *CSearchPathsSettingsPage::createPage(QWidget *parent) +QWidget *SearchPathsSettingsPage::createPage(QWidget *parent) { m_page = new QWidget(parent); m_ui.setupUi(m_page); @@ -90,19 +90,19 @@ QWidget *CSearchPathsSettingsPage::createPage(QWidget *parent) return m_page; } -void CSearchPathsSettingsPage::apply() +void SearchPathsSettingsPage::apply() { writeSettings(); applySearchPaths(); } -void CSearchPathsSettingsPage::finish() +void SearchPathsSettingsPage::finish() { delete m_page; m_page = 0; } -void CSearchPathsSettingsPage::applySearchPaths() +void SearchPathsSettingsPage::applySearchPaths() { QStringList paths, remapExt; QSettings *settings = Core::ICore::instance()->settings(); @@ -124,7 +124,7 @@ void CSearchPathsSettingsPage::applySearchPaths() } } -void CSearchPathsSettingsPage::addPath() +void SearchPathsSettingsPage::addPath() { QString newPath = QFileDialog::getExistingDirectory(m_page, "", lastDir); if (!newPath.isEmpty()) @@ -139,7 +139,7 @@ void CSearchPathsSettingsPage::addPath() checkEnabledButton(); } -void CSearchPathsSettingsPage::delPath() +void SearchPathsSettingsPage::delPath() { QListWidgetItem *removeItem = m_ui.pathsListWidget->takeItem(m_ui.pathsListWidget->currentRow()); if (!removeItem) @@ -148,7 +148,7 @@ void CSearchPathsSettingsPage::delPath() checkEnabledButton(); } -void CSearchPathsSettingsPage::upPath() +void SearchPathsSettingsPage::upPath() { int currentRow = m_ui.pathsListWidget->currentRow(); if (!(currentRow == 0)) @@ -159,7 +159,7 @@ void CSearchPathsSettingsPage::upPath() } } -void CSearchPathsSettingsPage::downPath() +void SearchPathsSettingsPage::downPath() { int currentRow = m_ui.pathsListWidget->currentRow(); if (!(currentRow == m_ui.pathsListWidget->count()-1)) @@ -170,7 +170,7 @@ void CSearchPathsSettingsPage::downPath() } } -void CSearchPathsSettingsPage::readSettings() +void SearchPathsSettingsPage::readSettings() { QStringList paths; QSettings *settings = Core::ICore::instance()->settings(); @@ -189,7 +189,7 @@ void CSearchPathsSettingsPage::readSettings() } } -void CSearchPathsSettingsPage::writeSettings() +void SearchPathsSettingsPage::writeSettings() { QStringList paths; for (int i = 0; i < m_ui.pathsListWidget->count(); ++i) @@ -205,7 +205,7 @@ void CSearchPathsSettingsPage::writeSettings() settings->sync(); } -void CSearchPathsSettingsPage::checkEnabledButton() +void SearchPathsSettingsPage::checkEnabledButton() { bool bEnabled = true; if (m_ui.pathsListWidget->count() == 0) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/search_paths_settings_page.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/search_paths_settings_page.h index c7d4c9734..c45b29571 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/search_paths_settings_page.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/search_paths_settings_page.h @@ -30,15 +30,15 @@ class QWidget; namespace Core { /** -@class CSearchPathsSettingsPage +@class SearchPathsSettingsPage */ -class CSearchPathsSettingsPage : public Core::IOptionsPage +class SearchPathsSettingsPage : public Core::IOptionsPage { Q_OBJECT public: - explicit CSearchPathsSettingsPage(bool recurse, QObject *parent = 0); - ~CSearchPathsSettingsPage(); + explicit SearchPathsSettingsPage(bool recurse, QObject *parent = 0); + ~SearchPathsSettingsPage(); QString id() const; QString trName() const; @@ -66,7 +66,7 @@ private: bool m_recurse; QWidget *m_page; - Ui::CSearchPathsSettingsPage m_ui; + Ui::SearchPathsSettingsPage m_ui; }; } // namespace Core diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/search_paths_settings_page.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/search_paths_settings_page.ui index 79a6b2141..cf47314b8 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/search_paths_settings_page.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/search_paths_settings_page.ui @@ -1,7 +1,7 @@ - CSearchPathsSettingsPage - + SearchPathsSettingsPage + 0 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/settings_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/settings_dialog.cpp index 30fd7835e..960644599 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/settings_dialog.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/settings_dialog.cpp @@ -35,33 +35,33 @@ Q_DECLARE_METATYPE(PageData); namespace Core { -CSettingsDialog::CSettingsDialog(ExtensionSystem::IPluginManager *pluginManager, - const QString &categoryId, - const QString &pageId, - QWidget *parent) +SettingsDialog::SettingsDialog(ExtensionSystem::IPluginManager *pluginManager, + const QString &categoryId, + const QString &pageId, + QWidget *parent) : QDialog(parent), - _applied(false) + m_applied(false) { - _ui.setupUi(this); + m_ui.setupUi(this); - _plugMan = pluginManager; + m_plugMan = pluginManager; QString initialCategory = categoryId; QString initialPage = pageId; - _ui.buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); + m_ui.buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); - connect(_ui.buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(apply())); + connect(m_ui.buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(apply())); - _ui.splitter->setCollapsible(1, false); - _ui.pageTree->header()->setVisible(false); + m_ui.splitter->setCollapsible(1, false); + m_ui.pageTree->header()->setVisible(false); - connect(_ui.pageTree, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), + connect(m_ui.pageTree, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(pageSelected())); QMap categories; - QList pages = _plugMan->getObjects(); + QList pages = m_plugMan->getObjects(); int index = 0; Q_FOREACH(IOptionsPage *page, pages) @@ -82,7 +82,7 @@ CSettingsDialog::CSettingsDialog(ExtensionSystem::IPluginManager *pluginManager, QTreeWidgetItem *treeitem; if (!categories.contains(currentCategory)) { - treeitem = new QTreeWidgetItem(_ui.pageTree); + treeitem = new QTreeWidgetItem(m_ui.pageTree); treeitem->setText(0, trCategories.at(0)); treeitem->setData(0, Qt::UserRole, qVariantFromValue(pageData)); categories.insert(currentCategory, treeitem); @@ -108,13 +108,13 @@ CSettingsDialog::CSettingsDialog(ExtensionSystem::IPluginManager *pluginManager, categories.value(currentCategory)->addChild(item); - _pages.append(page); - _ui.stackedPages->addWidget(page->createPage(_ui.stackedPages)); + m_pages.append(page); + m_ui.stackedPages->addWidget(page->createPage(m_ui.stackedPages)); if (page->id() == initialPage && currentCategory == initialCategory) { - _ui.stackedPages->setCurrentIndex(_ui.stackedPages->count()); - _ui.pageTree->setCurrentItem(item); + m_ui.stackedPages->setCurrentIndex(m_ui.stackedPages->count()); + m_ui.pageTree->setCurrentItem(item); } index++; @@ -122,30 +122,30 @@ CSettingsDialog::CSettingsDialog(ExtensionSystem::IPluginManager *pluginManager, QList sizes; sizes << 150 << 300; - _ui.splitter->setSizes(sizes); + m_ui.splitter->setSizes(sizes); - _ui.splitter->setStretchFactor(_ui.splitter->indexOf(_ui.pageTree), 0); - _ui.splitter->setStretchFactor(_ui.splitter->indexOf(_ui.layoutWidget), 1); + m_ui.splitter->setStretchFactor(m_ui.splitter->indexOf(m_ui.pageTree), 0); + m_ui.splitter->setStretchFactor(m_ui.splitter->indexOf(m_ui.layoutWidget), 1); } -CSettingsDialog::~CSettingsDialog() +SettingsDialog::~SettingsDialog() { } -void CSettingsDialog::pageSelected() +void SettingsDialog::pageSelected() { - QTreeWidgetItem *item = _ui.pageTree->currentItem(); + QTreeWidgetItem *item = m_ui.pageTree->currentItem(); PageData data = item->data(0, Qt::UserRole).value(); int index = data.index; - _currentCategory = data.category; - _currentPage = data.id; - _ui.stackedPages->setCurrentIndex(index); + m_currentCategory = data.category; + m_currentPage = data.id; + m_ui.stackedPages->setCurrentIndex(index); } -void CSettingsDialog::accept() +void SettingsDialog::accept() { - _applied = true; - Q_FOREACH(IOptionsPage *page, _pages) + m_applied = true; + Q_FOREACH(IOptionsPage *page, m_pages) { page->apply(); page->finish(); @@ -153,28 +153,28 @@ void CSettingsDialog::accept() done(QDialog::Accepted); } -void CSettingsDialog::reject() +void SettingsDialog::reject() { - Q_FOREACH(IOptionsPage *page, _pages) + Q_FOREACH(IOptionsPage *page, m_pages) page->finish(); done(QDialog::Rejected); } -void CSettingsDialog::apply() +void SettingsDialog::apply() { - Q_FOREACH(IOptionsPage *page, _pages) + Q_FOREACH(IOptionsPage *page, m_pages) page->apply(); - _applied = true; + m_applied = true; } -bool CSettingsDialog::execDialog() +bool SettingsDialog::execDialog() { - _applied = false; + m_applied = false; exec(); - return _applied; + return m_applied; } -void CSettingsDialog::done(int val) +void SettingsDialog::done(int val) { QDialog::done(val); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/settings_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/settings_dialog.h index 07adc7fee..9e1c86444 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/settings_dialog.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/settings_dialog.h @@ -35,17 +35,17 @@ class IOptionsPage; @class CSettingsDialog @brief Settings dialog */ -class CSettingsDialog: public QDialog +class SettingsDialog: public QDialog { Q_OBJECT public: - CSettingsDialog(ExtensionSystem::IPluginManager *pluginManager, - const QString &initialCategory = QString(), - const QString &initialPage = QString(), - QWidget *parent = 0); + SettingsDialog(ExtensionSystem::IPluginManager *pluginManager, + const QString &initialCategory = QString(), + const QString &initialPage = QString(), + QWidget *parent = 0); - ~CSettingsDialog(); + ~SettingsDialog(); /// Run the dialog and return true if 'Ok' was choosen or 'Apply' was invoked at least once bool execDialog(); @@ -60,14 +60,14 @@ private Q_SLOTS: void apply(); private: - QList _pages; - bool _applied; - QString _currentCategory; - QString _currentPage; + QList m_pages; + bool m_applied; + QString m_currentCategory; + QString m_currentPage; - ExtensionSystem::IPluginManager *_plugMan; + ExtensionSystem::IPluginManager *m_plugMan; - Ui::CSettingsDialog _ui; + Ui::SettingsDialog m_ui; }; /* class CSettingsDialog */ } /* namespace Core */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/settings_dialog.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/settings_dialog.ui index e536f0dc2..8e9780c9a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/settings_dialog.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/settings_dialog.ui @@ -1,7 +1,7 @@ - CSettingsDialog - + SettingsDialog + 0 @@ -93,7 +93,7 @@ buttonBox accepted() - CSettingsDialog + SettingsDialog accept() @@ -109,7 +109,7 @@ buttonBox rejected() - CSettingsDialog + SettingsDialog reject() diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/disp_sheet_id/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/disp_sheet_id/CMakeLists.txt index 34c65c178..6152b8fdd 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/disp_sheet_id/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/disp_sheet_id/CMakeLists.txt @@ -28,7 +28,7 @@ SOURCE_GROUP("OVQT Extension System" FILES ${OVQT_EXT_SYS_SRC}) ADD_LIBRARY(ovqt_plugin_disp_sheet_id MODULE ${SRC} ${OVQT_DISP_SHEET_ID_PLUGIN_MOC_SRC} ${OVQT_EXT_SYS_SRC} ${OVQT_DISP_SHEET_ID_PLUGIN_UI_HDRS}) -TARGET_LINK_LIBRARIES(ovqt_plugin_disp_sheet_id ovqt_plugin_core nelmisc nel3d ${QT_LIBRARIES}) +TARGET_LINK_LIBRARIES(ovqt_plugin_disp_sheet_id ovqt_plugin_core nelmisc ${QT_LIBRARIES}) IF(WITH_STLPORT) TARGET_LINK_LIBRARIES(ovqt_plugin_disp_sheet_id ${CMAKE_THREAD_LIBS_INIT}) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/disp_sheet_id/disp_sheet_id_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/disp_sheet_id/disp_sheet_id_plugin.cpp index 54cba53a6..9e37b803b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/disp_sheet_id/disp_sheet_id_plugin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/disp_sheet_id/disp_sheet_id_plugin.cpp @@ -18,7 +18,7 @@ #include "disp_sheet_id_plugin.h" #include "sheet_id_view.h" #include "../core/icore.h" -#include "../core/imenu_manager.h" +#include "../core/menu_manager.h" #include "../core/core_constants.h" // Qt includes @@ -37,13 +37,13 @@ using namespace SheetIdViewPlugin; bool DispSheetIdPlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString) { Q_UNUSED(errorString); - _plugMan = pluginManager; + m_plugMan = pluginManager; return true; } void DispSheetIdPlugin::extensionsInitialized() { - Core::IMenuManager *menuManager = Core::ICore::instance()->menuManager(); + Core::MenuManager *menuManager = Core::ICore::instance()->menuManager(); QMenu *sheetMenu = menuManager->menu(Core::Constants::M_SHEET); QAction *sheetIdViewAction = sheetMenu->addAction(tr("Sheet id view")); @@ -67,34 +67,7 @@ void DispSheetIdPlugin::setNelContext(NLMISC::INelContext *nelContext) // This only applies to platforms without PIC, e.g. Windows. nlassert(!NLMISC::INelContext::isContextInitialised()); #endif // NL_OS_WINDOWS - _LibContext = new NLMISC::CLibraryContext(*nelContext); -} - -QString DispSheetIdPlugin::name() const -{ - return "Display sheet id"; -} - -QString DispSheetIdPlugin::version() const -{ - return "1.0"; -} - -QString DispSheetIdPlugin::vendor() const -{ - return "pemeon"; -} - -QString DispSheetIdPlugin::description() const -{ - return "Display sheet id"; -} - -QStringList DispSheetIdPlugin::dependencies() const -{ - QStringList list; - list.append(Core::Constants::OVQT_CORE_PLUGIN); - return list; + m_LibContext = new NLMISC::CLibraryContext(*nelContext); } Q_EXPORT_PLUGIN(DispSheetIdPlugin) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/disp_sheet_id/disp_sheet_id_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/disp_sheet_id/disp_sheet_id_plugin.h index 75a25b724..8eaf3ead9 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/disp_sheet_id/disp_sheet_id_plugin.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/disp_sheet_id/disp_sheet_id_plugin.h @@ -28,11 +28,6 @@ namespace NLMISC class CLibraryContext; } -namespace NLQT -{ -class IPluginSpec; -} - namespace SheetIdViewPlugin { @@ -44,23 +39,16 @@ public: bool initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString); void extensionsInitialized(); - void setNelContext(NLMISC::INelContext *nelContext); - QString name() const; - QString version() const; - QString vendor() const; - QString description() const; - QStringList dependencies() const; - private Q_SLOTS: void execMessageBox(); protected: - NLMISC::CLibraryContext *_LibContext; + NLMISC::CLibraryContext *m_LibContext; private: - ExtensionSystem::IPluginManager *_plugMan; + ExtensionSystem::IPluginManager *m_plugMan; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/disp_sheet_id/ovqt_plugin_disp_sheet_id.xml b/code/nel/tools/3d/object_viewer_qt/src/plugins/disp_sheet_id/ovqt_plugin_disp_sheet_id.xml new file mode 100644 index 000000000..012029810 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/disp_sheet_id/ovqt_plugin_disp_sheet_id.xml @@ -0,0 +1,10 @@ + + ovqt_plugin_disp_sheet_id + DisplaySheetId + 1.0 + pemeon + Display sheet id. + + + + \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/disp_sheet_id/sheet_id_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/disp_sheet_id/sheet_id_view.cpp index 64fb05701..f05060a9c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/disp_sheet_id/sheet_id_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/disp_sheet_id/sheet_id_view.cpp @@ -65,8 +65,8 @@ void SheetIdView::pushToTable() m_ui.table->setColumnCount(2); for (size_t i = 0; i < m_sheetList.size(); i++) { - QTableWidgetItem* item1 = new QTableWidgetItem(QString(m_sheetList[i].toString().c_str())); - QTableWidgetItem* item2 = new QTableWidgetItem(QString("%1").arg(m_sheetList[i].asInt())); + QTableWidgetItem *item1 = new QTableWidgetItem(QString(m_sheetList[i].toString().c_str())); + QTableWidgetItem *item2 = new QTableWidgetItem(QString("%1").arg(m_sheetList[i].asInt())); m_ui.table->setItem(i,1,item1); m_ui.table->setItem(i,2,item2); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/CMakeLists.txt index 41d22804c..fbe617c43 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/CMakeLists.txt @@ -9,10 +9,10 @@ SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin. ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin_manager.h ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin_spec.h) -SET(OVQT_PLUG_EXAMPLE_HDR plugin1.h - qnel_widget.h - simple_viewer.h - example_settings_page.h) +SET(OVQT_PLUG_EXAMPLE_HDR example_plugin.h + qnel_widget.h + simple_viewer.h + example_settings_page.h) SET(OVQT_PLUG_EXAMPLE_UIS example_settings_page.ui) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_plugin.cpp new file mode 100644 index 000000000..5e442a5ee --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_plugin.cpp @@ -0,0 +1,83 @@ +// Project includes +#include "example_plugin.h" +#include "example_settings_page.h" +#include "simple_viewer.h" + +#include "../core/icore.h" +#include "../core/core_constants.h" +#include "../core/menu_manager.h" + +#include "../../extension_system/iplugin_spec.h" + +// NeL includes +#include "nel/misc/debug.h" + +// Qt includes +#include +#include +#include +#include +#include +#include + +namespace Plugin +{ + +ExamplePlugin::ExamplePlugin() +{ +} + +ExamplePlugin::~ExamplePlugin() +{ + Q_FOREACH(QObject *obj, m_autoReleaseObjects) + { + m_plugMan->removeObject(obj); + } + qDeleteAll(m_autoReleaseObjects); + m_autoReleaseObjects.clear(); +} + +bool ExamplePlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString) +{ + Q_UNUSED(errorString); + m_plugMan = pluginManager; + + addAutoReleasedObject(new ExampleSettingsPage(this)); + addAutoReleasedObject(new ExampleContext(this)); + addAutoReleasedObject(new ExampleCoreListener(this)); + return true; +} + +void ExamplePlugin::extensionsInitialized() +{ + Core::ICore *core = Core::ICore::instance(); + Core::MenuManager *menuManager = core->menuManager(); + QAction *exampleAction1 = new QAction("Example1", this); + QAction *exampleAction2 = new QAction("Example2", this); + QAction *aboutQtAction = menuManager->action(Core::Constants::ABOUT_QT); + QMenu *helpMenu = menuManager->menu(Core::Constants::M_HELP); + helpMenu->insertAction(aboutQtAction, exampleAction1); + helpMenu->addSeparator(); + helpMenu->addAction(exampleAction2); + menuManager->menuBar()->addMenu("ExampleMenu"); +} + +void ExamplePlugin::setNelContext(NLMISC::INelContext *nelContext) +{ +#ifdef NL_OS_WINDOWS + // Ensure that a context doesn't exist yet. + // This only applies to platforms without PIC, e.g. Windows. + nlassert(!NLMISC::INelContext::isContextInitialised()); +#endif // NL_OS_WINDOWS + m_LibContext = new NLMISC::CLibraryContext(*nelContext); +} + +void ExamplePlugin::addAutoReleasedObject(QObject *obj) +{ + m_plugMan->addObject(obj); + m_autoReleaseObjects.prepend(obj); +} + +} + +Q_EXPORT_PLUGIN(Plugin::ExamplePlugin) \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_plugin.h similarity index 59% rename from code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.h rename to code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_plugin.h index 5077ff59e..bfb400651 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_plugin.h @@ -18,56 +18,41 @@ namespace NLMISC class CLibraryContext; } -namespace ExtensionSystem -{ -class IPluginSpec; -} - namespace Plugin { -class MyPlugin : public QObject, public ExtensionSystem::IPlugin +class ExamplePlugin : public QObject, public ExtensionSystem::IPlugin { Q_OBJECT Q_INTERFACES(ExtensionSystem::IPlugin) public: - - virtual ~MyPlugin(); + ExamplePlugin(); + virtual ~ExamplePlugin(); bool initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString); void extensionsInitialized(); - void setNelContext(NLMISC::INelContext *nelContext); - QString name() const; - QString version() const; - QString vendor() const; - QString description() const; - QStringList dependencies() const; - void addAutoReleasedObject(QObject *obj); - QObject *objectByName(const QString &name) const; - ExtensionSystem::IPluginSpec *pluginByName(const QString &name) const; - protected: - NLMISC::CLibraryContext *_LibContext; + NLMISC::CLibraryContext *m_LibContext; private: - ExtensionSystem::IPluginManager *_plugMan; - QList _autoReleaseObjects; + ExtensionSystem::IPluginManager *m_plugMan; + QList m_autoReleaseObjects; }; -class CExampleContext: public Core::IContext +class ExampleContext: public Core::IContext { Q_OBJECT public: - CExampleContext(QObject *parent = 0): IContext(parent) + ExampleContext(QObject *parent = 0): IContext(parent) { - m_simpleViewer = new CSimpleViewer(); + m_simpleViewer = new SimpleViewer(); } - virtual ~CExampleContext() {} + virtual ~ExampleContext() {} virtual QString id() const { @@ -95,7 +80,7 @@ public: { } - CSimpleViewer *m_simpleViewer; + SimpleViewer *m_simpleViewer; }; } // namespace Plugin diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_settings_page.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_settings_page.cpp index 50e7c9db5..6cea967db 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_settings_page.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_settings_page.cpp @@ -27,45 +27,45 @@ namespace Plugin { -CExampleSettingsPage::CExampleSettingsPage(QObject *parent) +ExampleSettingsPage::ExampleSettingsPage(QObject *parent) : IOptionsPage(parent), - _currentPage(NULL) + m_currentPage(0) { } -QString CExampleSettingsPage::id() const +QString ExampleSettingsPage::id() const { return QLatin1String("ExamplePage"); } -QString CExampleSettingsPage::trName() const +QString ExampleSettingsPage::trName() const { return tr("Example page"); } -QString CExampleSettingsPage::category() const +QString ExampleSettingsPage::category() const { - return QLatin1String("General"); + return QLatin1String("Example"); } -QString CExampleSettingsPage::trCategory() const +QString ExampleSettingsPage::trCategory() const { - return tr("General"); + return tr("Example"); } -QIcon CExampleSettingsPage::categoryIcon() const +QIcon ExampleSettingsPage::categoryIcon() const { return QIcon(); } -QWidget *CExampleSettingsPage::createPage(QWidget *parent) +QWidget *ExampleSettingsPage::createPage(QWidget *parent) { - _currentPage = new QWidget(parent); - _ui.setupUi(_currentPage); - return _currentPage; + m_currentPage = new QWidget(parent); + m_ui.setupUi(m_currentPage); + return m_currentPage; } -void CExampleSettingsPage::apply() +void ExampleSettingsPage::apply() { } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_settings_page.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_settings_page.h index 3475f843f..8a1a7cef1 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_settings_page.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_settings_page.h @@ -29,15 +29,13 @@ class QWidget; namespace Plugin { -/** -@class CExampleSettingsPage -*/ -class CExampleSettingsPage : public Core::IOptionsPage + +class ExampleSettingsPage : public Core::IOptionsPage { Q_OBJECT public: - CExampleSettingsPage(QObject *parent = 0); - virtual ~CExampleSettingsPage() {} + ExampleSettingsPage(QObject *parent = 0); + virtual ~ExampleSettingsPage() {} virtual QString id() const; virtual QString trName() const; @@ -50,8 +48,8 @@ public: virtual void finish() {} private: - QWidget *_currentPage; - Ui::CExampleSettingsPage _ui; + QWidget *m_currentPage; + Ui::ExampleSettingsPage m_ui; }; } // namespace Plugin diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_settings_page.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_settings_page.ui index b839d98ce..0d98ad6ab 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_settings_page.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/example_settings_page.ui @@ -1,7 +1,7 @@ - CExampleSettingsPage - + ExampleSettingsPage + 0 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/ovqt_plugin_example.xml b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/ovqt_plugin_example.xml new file mode 100644 index 000000000..43656a87b --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/ovqt_plugin_example.xml @@ -0,0 +1,10 @@ + + ovqt_plugin_example + ExamplePlugin + 0.2 + dnk-88 + Example ovqt plugin. + + + + \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.cpp deleted file mode 100644 index f218c3230..000000000 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.cpp +++ /dev/null @@ -1,120 +0,0 @@ -// Project includes -#include "plugin1.h" -#include "example_settings_page.h" -#include "simple_viewer.h" -#include "../core/icore.h" -#include "../core/core_constants.h" -#include "../core/imenu_manager.h" -#include "../../extension_system/iplugin_spec.h" - -// NeL includes -#include "nel/misc/debug.h" - -// Qt includes -#include -#include -#include -#include -#include -#include - -namespace Plugin -{ -MyPlugin::~MyPlugin() -{ - Q_FOREACH(QObject *obj, _autoReleaseObjects) - { - _plugMan->removeObject(obj); - } - qDeleteAll(_autoReleaseObjects); - _autoReleaseObjects.clear(); -} - -bool MyPlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString) -{ - Q_UNUSED(errorString); - _plugMan = pluginManager; - - addAutoReleasedObject(new CExampleSettingsPage(this)); - addAutoReleasedObject(new CExampleContext(this)); - addAutoReleasedObject(new CCoreListener(this)); - return true; -} - -void MyPlugin::extensionsInitialized() -{ - Core::ICore *core = Core::ICore::instance(); - Core::IMenuManager *menuManager = core->menuManager(); - //menuManager = _plugMan->getObject(); - QAction *exampleAction1 = new QAction("Example1", this); - QAction *exampleAction2 = new QAction("Example2", this); - QAction *aboutQtAction = menuManager->action(Core::Constants::ABOUT_QT); - QMenu *helpMenu = menuManager->menu(Core::Constants::M_HELP); - helpMenu->insertAction(aboutQtAction, exampleAction1); - helpMenu->addSeparator(); - helpMenu->addAction(exampleAction2); - menuManager->menuBar()->addMenu("ExampleMenu"); -} - -void MyPlugin::setNelContext(NLMISC::INelContext *nelContext) -{ -#ifdef NL_OS_WINDOWS - // Ensure that a context doesn't exist yet. - // This only applies to platforms without PIC, e.g. Windows. - nlassert(!NLMISC::INelContext::isContextInitialised()); -#endif // NL_OS_WINDOWS - _LibContext = new NLMISC::CLibraryContext(*nelContext); -} - -QString MyPlugin::name() const -{ - return "ExamplePlugin"; -} - -QString MyPlugin::version() const -{ - return "0.2"; -} - -QString MyPlugin::vendor() const -{ - return "dnk-88"; -} - -QString MyPlugin::description() const -{ - return "Example ovqt plugin."; -} - -QStringList MyPlugin::dependencies() const -{ - QStringList list; - list.append(Core::Constants::OVQT_CORE_PLUGIN); - return list; -} - -void MyPlugin::addAutoReleasedObject(QObject *obj) -{ - _plugMan->addObject(obj); - _autoReleaseObjects.prepend(obj); -} - -QObject* MyPlugin::objectByName(const QString &name) const -{ - Q_FOREACH (QObject *qobj, _plugMan->allObjects()) - if (qobj->objectName() == name) - return qobj; - return 0; -} - -ExtensionSystem::IPluginSpec *MyPlugin::pluginByName(const QString &name) const -{ - Q_FOREACH (ExtensionSystem::IPluginSpec *spec, _plugMan->plugins()) - if (spec->name() == name) - return spec; - return 0; -} - -} - -Q_EXPORT_PLUGIN(Plugin::MyPlugin) \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/qnel_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/qnel_widget.h index a54e6bb8a..59bb9ecda 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/qnel_widget.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/qnel_widget.h @@ -82,7 +82,7 @@ public: return m_driver; } - virtual QPaintEngine* paintEngine() const + virtual QPaintEngine *paintEngine() const { return NULL; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/simple_viewer.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/simple_viewer.cpp index 1f6df9117..601909047 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/simple_viewer.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/simple_viewer.cpp @@ -29,19 +29,19 @@ namespace Plugin { -CSimpleViewer::CSimpleViewer(QWidget *parent) +SimpleViewer::SimpleViewer(QWidget *parent) : QWidget(parent) { QGridLayout *gridLayout = new QGridLayout(this); gridLayout->setObjectName(QString::fromUtf8("gridLayoutSimpleViewer")); gridLayout->setContentsMargins(0, 0, 0, 0); - NLQT::QNLWidget *_nelWidget = new NLQT::QNLWidget(this); - gridLayout->addWidget(_nelWidget, 0, 0, 1, 1); + NLQT::QNLWidget *m_nelWidget = new NLQT::QNLWidget(this); + gridLayout->addWidget(m_nelWidget, 0, 0, 1, 1); m_undoStack = new QUndoStack(this); } -bool CCoreListener::closeMainWindow() const +bool ExampleCoreListener::closeMainWindow() const { int ret = QMessageBox::question(0, tr("Example close event hook"), tr("Do you want to close window?"), diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/simple_viewer.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/simple_viewer.h index 14b782c22..793b0745e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/simple_viewer.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/simple_viewer.h @@ -31,22 +31,22 @@ class QWidget; namespace Plugin { -class CSimpleViewer : public QWidget +class SimpleViewer : public QWidget { Q_OBJECT public: - CSimpleViewer(QWidget *parent = 0); - virtual ~CSimpleViewer() {} + SimpleViewer(QWidget *parent = 0); + virtual ~SimpleViewer() {} QUndoStack *m_undoStack; }; -class CCoreListener : public Core::ICoreListener +class ExampleCoreListener : public Core::ICoreListener { Q_OBJECT public: - CCoreListener(QObject *parent = 0): ICoreListener(parent) {} - virtual ~CCoreListener() {} + ExampleCoreListener(QObject *parent = 0): ICoreListener(parent) {} + virtual ~ExampleCoreListener() {} virtual bool closeMainWindow() const; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/CMakeLists.txt index d1dd346ba..b29f32152 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/CMakeLists.txt @@ -10,10 +10,14 @@ SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin SET(OVQT_PLUG_GEORGES_EDITOR_HDR georges_editor_plugin.h georges_editor_form.h - georges_dirtree_dialog.h) + georges_dirtree_dialog.h + georges_filesystem_model.h + georges_treeview_dialog.h + expandable_headerview.h) SET(OVQT_PLUG_GEORGES_EDITOR_UIS georges_editor_form.ui - georges_dirtree_form.ui) + georges_dirtree_form.ui + georges_treeview_form.ui) SET(OVQT_PLUGIN_GEORGES_EDITOR_RCS georges_editor.qrc) @@ -32,7 +36,7 @@ SOURCE_GROUP("OVQT Extension System" FILES ${OVQT_EXT_SYS_SRC}) ADD_LIBRARY(ovqt_plugin_georges_editor MODULE ${SRC} ${OVQT_PLUG_GEORGES_EDITOR_MOC_SRC} ${OVQT_EXT_SYS_SRC} ${OVQT_PLUG_GEORGES_EDITOR_UI_HDRS} ${OVQT_PLUGIN_GEORGES_EDITOR_RC_SRCS}) -TARGET_LINK_LIBRARIES(ovqt_plugin_georges_editor ovqt_plugin_core nelmisc ${QT_LIBRARIES}) +TARGET_LINK_LIBRARIES(ovqt_plugin_georges_editor ovqt_plugin_core nelmisc nelgeorges ${QT_LIBRARIES}) NL_DEFAULT_PROPS(ovqt_plugin_georges_editor "NeL, Tools, 3D: Object Viewer Qt Plugin: Georges Editor") NL_ADD_RUNTIME_FLAGS(ovqt_plugin_georges_editor) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/expandable_headerview.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/expandable_headerview.cpp new file mode 100644 index 000000000..2967be435 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/expandable_headerview.cpp @@ -0,0 +1,143 @@ +// Object Viewer Qt - Georges Editor Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Project includes +#include "expandable_headerview.h" + +// Qt includes +#include +#include +#include + +namespace GeorgesQt +{ + + ExpandableHeaderView::ExpandableHeaderView(Qt::Orientation orientation, QWidget * parent) + : QHeaderView(orientation, parent), + m_expanded(true), + m_inDecoration(false) + { + } + + void ExpandableHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const + { + painter->save(); + QHeaderView::paintSection(painter, rect, logicalIndex); + painter->restore(); + + if (logicalIndex == 0) + { + QRect sectionRect = this->orientation() == Qt::Horizontal ? + QRect(this->sectionPosition(logicalIndex), 0, + this->sectionSize(logicalIndex), this->height()): + QRect(0, this->sectionPosition(logicalIndex), + this->width(), this->sectionSize(logicalIndex)); + + QStyleOptionHeader opt; + initStyleOption(&opt); + opt.iconAlignment = Qt::AlignVCenter; + + QVariant variant = this->model()->headerData(logicalIndex, this->orientation(), + Qt::DecorationRole); + opt.icon = qvariant_cast(variant); + if (opt.icon.isNull()) + { + opt.icon = qvariant_cast(variant); + } + QRect headerLabelRect = this->style()->subElementRect(QStyle::SE_HeaderLabel, &opt, this); + + QPixmap pixmap + = opt.icon.pixmap(this->style()->pixelMetric(QStyle::PM_SmallIconSize), + (opt.state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled); + QRect aligned = this->style()->alignedRect(opt.direction, QFlag(opt.iconAlignment), + pixmap.size(), headerLabelRect); + QRect inter = aligned.intersected(headerLabelRect); + + QStyleOption option; + option.rect = QRect(inter.x()-2,inter.y(),inter.width(),inter.height()); + if (m_expanded) + option.state = QStyle::State_Children | QStyle::State_Open; + else + option.state = QStyle::State_Children; + if (m_inDecoration) + option.state |= QStyle::State_MouseOver; + QApplication::style()->drawPrimitive(QStyle::PE_IndicatorBranch, &option, painter); + } + } + + void ExpandableHeaderView::mousePressEvent(QMouseEvent *e) + { + int section = logicalIndexAt(e->x()); + + if (section == 0 && m_inDecoration) { + if (m_expanded) + m_expanded = false; + else + m_expanded = true; + this->QHeaderView::mousePressEvent(e); + Q_EMIT headerClicked(section); + } + } + + void ExpandableHeaderView::mouseMoveEvent(QMouseEvent *e) + { + int section = this->logicalIndexAt(e->x()); + + if (section != 0) + return; + + bool tmp = m_inDecoration; + if (isPointInDecoration(section, e->pos())) + m_inDecoration = true; + else + m_inDecoration = false; + + if (m_inDecoration != tmp) + updateSection(0); + } + + bool ExpandableHeaderView::isPointInDecoration(int section, QPoint pos)const + { + QRect sectionRect = this->orientation() == Qt::Horizontal ? + QRect(this->sectionPosition(section), 0, + this->sectionSize(section), this->height()): + QRect(0, this->sectionPosition(section), + this->width(), this->sectionSize(section)); + QStyleOptionHeader opt; + this->initStyleOption(&opt); + opt.iconAlignment = Qt::AlignVCenter; + QVariant variant = this->model()->headerData(section, this->orientation(), + Qt::DecorationRole); + opt.icon = qvariant_cast(variant); + if (opt.icon.isNull()) + { + opt.icon = qvariant_cast(variant); + } + QRect headerLabelRect = this->style()->subElementRect(QStyle::SE_HeaderLabel, &opt, this); + // from qcommonstyle.cpp + if (opt.icon.isNull()) + { + return false; + } + QPixmap pixmap + = opt.icon.pixmap(this->style()->pixelMetric(QStyle::PM_SmallIconSize), + (opt.state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled); + QRect aligned = this->style()->alignedRect(opt.direction, QFlag(opt.iconAlignment), + pixmap.size(), headerLabelRect); + QRect inter = aligned.intersected(headerLabelRect); + return inter.contains(pos); + } +} diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/expandable_headerview.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/expandable_headerview.h new file mode 100644 index 000000000..f7f26eafc --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/expandable_headerview.h @@ -0,0 +1,49 @@ +// Object Viewer Qt - Georges Editor Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef EXPANDABLE_HEADERVIEW_H +#define EXPANDABLE_HEADERVIEW_H + +// Qt includes +#include + +namespace GeorgesQt +{ + class ExpandableHeaderView : public QHeaderView + { + Q_OBJECT + public: + ExpandableHeaderView(Qt::Orientation orientation, QWidget * parent = 0); + + bool* expanded() { return &m_expanded; } + + protected: + void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const; + bool isPointInDecoration(int section, QPoint pos)const; + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + + private: + bool m_expanded; + bool m_inDecoration; + +Q_SIGNALS: + void headerClicked(int); + }; + +} /* namespace NLQT */ + +#endif // EXPANDABLE_HEADERVIEW_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/formdelegate.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/formdelegate.cpp new file mode 100644 index 000000000..be358d065 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/formdelegate.cpp @@ -0,0 +1,278 @@ +// Object Viewer Qt - Georges Editor Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "formdelegate.h" + +// NeL includes +#include +#include +#include + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Project includes +#include "georgesform_model.h" +#include "georgesform_proxy_model.h" +#include "formitem.h" + +namespace GeorgesQt +{ + + FormDelegate::FormDelegate(QObject *parent) + : QStyledItemDelegate(parent) + { + } + + QWidget *FormDelegate::createEditor(QWidget *parent, + const QStyleOptionViewItem & option , + const QModelIndex &index) const + { + const CGeorgesFormProxyModel * mp = dynamic_cast(index.model()); + const CGeorgesFormModel * m = dynamic_cast(mp->sourceModel()); + CFormItem *item = static_cast(mp->mapToSource(index).internalPointer()); + QString value = item->data(1).toString(); + + if (value.isEmpty() || !mp || !m) + return 0; + + CFormItem* curItem = m->getItem(mp->mapToSource(index)); + NLGEORGES::UFormElm *curElm = curItem->getFormElm(); + if (!curElm) { + // TODO: create new Element + return 0; + } + const NLGEORGES::UType *type = curElm->getType(); + if(type) + { + int numDefinitions = type->getNumDefinition(); + + if (numDefinitions) + { + std::string l, v; + QString label,value; + + QComboBox *editor = new QComboBox(parent); + for (int i = 0; i < numDefinitions; i++) + { + type->getDefinition(i,l,v); + label = l.c_str(); + value = v.c_str(); + editor->addItem(label); + } + return editor; + } + else + { + switch (type->getType()) + { + case NLGEORGES::UType::UnsignedInt: + case NLGEORGES::UType::SignedInt: + { + QSpinBox *editor = new QSpinBox(parent); + + //QString min = QString(type->getMin().c_str()); + //QString max = QString(type->getMax().c_str()); + //QString inc = QString(type->getIncrement().c_str()); + //nldebug(QString("min %1 max %2 inc %3").arg(min).arg(max).arg(inc).toStdString().c_str()); + + // TODO: use saved min/max values + editor->setMinimum(-99999); + editor->setMaximum(99999); + editor->setSingleStep(1); + return editor; + } + case NLGEORGES::UType::Double: + { + QDoubleSpinBox *editor = new QDoubleSpinBox(parent); + + //QString min = QString(type->getMin().c_str()); + //QString max = QString(type->getMax().c_str()); + //QString inc = QString(type->getIncrement().c_str()); + //nldebug(QString("min %1 max %2 inc %3").arg(min).arg(max).arg(inc).toStdString().c_str()); + + // TODO: use saved min/max values + editor->setMinimum(-99999); + editor->setMaximum(99999); + editor->setSingleStep(0.1); + editor->setDecimals(1); + return editor; + } + case NLGEORGES::UType::Color: + { + return new QColorDialog(); + } + default: // UType::String + { + QLineEdit *editor = new QLineEdit(parent); + return editor; + } + } + } + } + return 0; + } + + void FormDelegate::setEditorData(QWidget *editor, + const QModelIndex &index) const + { + const CGeorgesFormProxyModel * mp = dynamic_cast(index.model()); + const CGeorgesFormModel * m = dynamic_cast(mp->sourceModel()); + + const NLGEORGES::UType *type = m->getItem(mp->mapToSource(index))->getFormElm()->getType(); + int numDefinitions = type->getNumDefinition(); + QString value = index.model()->data(index, Qt::DisplayRole).toString(); + + if (numDefinitions) + { + QComboBox *cb = static_cast(editor); + cb->setCurrentIndex(cb->findText(value)); + } + else + { + switch (type->getType()) + { + case NLGEORGES::UType::UnsignedInt: + case NLGEORGES::UType::SignedInt: + { + QSpinBox *spinBox = static_cast(editor); + spinBox->setValue((int)value.toDouble()); + break; + } + case NLGEORGES::UType::Double: + { + QDoubleSpinBox *spinBox = static_cast(editor); + spinBox->setValue(value.toDouble()); + break; + } + case NLGEORGES::UType::Color: + { + break; + } + default: + { + QLineEdit *textEdit = static_cast(editor); + textEdit->setText(value); + break; + } + } + } + } + + void FormDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const + { + const CGeorgesFormProxyModel * mp = dynamic_cast(index.model()); + const CGeorgesFormModel * m = dynamic_cast(mp->sourceModel()); + + const NLGEORGES::UType *type = m->getItem(mp->mapToSource(index))->getFormElm()->getType(); + int numDefinitions = type->getNumDefinition(); + + if (numDefinitions) + { + QComboBox *comboBox = static_cast(editor); + QString value = comboBox->currentText(); + QString oldValue = index.model()->data(index, Qt::DisplayRole).toString(); + if (value == oldValue) + { + // nothing's changed + } + else + { + nldebug(QString("setModelData from %1 to %2") + .arg(oldValue).arg(value).toStdString().c_str()); + model->setData(index, value, Qt::EditRole); + } + } + else + { + switch (type->getType()) + { + case NLGEORGES::UType::UnsignedInt: + case NLGEORGES::UType::SignedInt: + { + QSpinBox *spinBox = static_cast(editor); + int value = spinBox->value(); + QString oldValue = index.model()->data(index, Qt::DisplayRole).toString(); + if (QString("%1").arg(value) == oldValue) + { + // nothing's changed + } + else + { + nldebug(QString("setModelData from %1 to %2") + .arg(oldValue).arg(value).toStdString().c_str()); + model->setData(index, value, Qt::EditRole); + } + break; + } + case NLGEORGES::UType::Double: + { + QDoubleSpinBox *spinBox = static_cast(editor); + double value = spinBox->value(); + QString oldValue = index.model()->data(index, Qt::DisplayRole).toString(); + if (QString("%1").arg(value) == oldValue) + { + // nothing's changed + } + else + { + nldebug(QString("setModelData from %1 to %2") + .arg(oldValue).arg(value).toStdString().c_str()); + model->setData(index, value, Qt::EditRole); + } + break; + } + case NLGEORGES::UType::Color: + { + break; // TODO + } + default: // UType::String + { + QLineEdit *textEdit = static_cast(editor); + QString value = textEdit->text(); + QString oldValue = index.model()->data(index, Qt::DisplayRole).toString(); + if (value == oldValue) + { + // nothing's changed + } + else + { + nldebug(QString("setModelData from %1 to %2") + .arg(oldValue).arg(value).toStdString().c_str()); + model->setData(index, value, Qt::EditRole); + } + break; + } + } + } + } + + void FormDelegate::updateEditorGeometry(QWidget *editor, + const QStyleOptionViewItem &option, const QModelIndex &index) const + { + QRect r = option.rect; + editor->setGeometry(r); + } +} /* namespace GeorgesQt */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/formdelegate.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/formdelegate.h new file mode 100644 index 000000000..486308536 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/formdelegate.h @@ -0,0 +1,41 @@ +// Object Viewer Qt - Georges Editor Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef FORMDELEGATE_H +#define FORMDELEGATE_H + +#include + +namespace GeorgesQt +{ + + class FormDelegate : public QStyledItemDelegate + { + + public: + FormDelegate(QObject *parent = 0); + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const; + void setEditorData(QWidget *editor, const QModelIndex &index) const; + void setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const; + void updateEditorGeometry(QWidget *editor, + const QStyleOptionViewItem &option, const QModelIndex &index) const; + }; + +} +#endif // FORMDELEGATE_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/formitem.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/formitem.cpp new file mode 100644 index 000000000..68f29064d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/formitem.cpp @@ -0,0 +1,162 @@ +// Object Viewer Qt - Georges Editor Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "formitem.h" + +// Qt includes + +// NeL includes +#include +#include +#include + +namespace GeorgesQt +{ + + CFormItem::CFormItem(NLGEORGES::UFormElm* elm, const QList &data, CFormItem *parent, + NLGEORGES::UFormElm::TWhereIsValue wV, NLGEORGES::UFormElm::TWhereIsNode wN) + { + parentItem = parent; + itemData = data; + formElm = elm; + whereV = wV; + whereN = wN; + } + + CFormItem::~CFormItem() + { + qDeleteAll(childItems); + } + + void CFormItem::appendChild(CFormItem *item) + { + childItems.append(item); + } + + CFormItem *CFormItem::child(int row) + { + return childItems.value(row); + } + + int CFormItem::childCount() const + { + return childItems.count(); + } + + int CFormItem::columnCount() const + { + //nlinfo("columnCount %d",itemData.count()); + return itemData.count(); + } + + QVariant CFormItem::data(int column) const + { + return itemData.value(column); + } + + CFormItem *CFormItem::parent() + { + return parentItem; + } + + int CFormItem::row() const + { + if (parentItem) + return parentItem->childItems.indexOf(const_cast(this)); + + return 0; + } + + bool CFormItem::setData(int column, const QVariant &value) + { + if (column < 0 || column >= itemData.size()) + return false; + + // TODO: default values + if (!formElm) + return false; + + itemData[column] = value; + if (formElm->isAtom()) + { + const NLGEORGES::UType *type = formElm->getType(); + if (type) + { + switch (type->getType()) + { + case NLGEORGES::UType::UnsignedInt: + case NLGEORGES::UType::SignedInt: + case NLGEORGES::UType::Double: + case NLGEORGES::UType::String: + if (parentItem->formElm->isArray()) + { + //((NLGEORGES::CFormElm*)parentItem->formElm);//->arrayInsertNodeByName( + //if(parentItem->formElm->getArrayNode(elmName, num)) + //{ + //} + + bool ok; + // TODO: the node can be renamed from eg "#0" to "foobar" + int arrayIndex = itemData[0].toString().remove("#").toInt(&ok); + if(ok) + { + NLGEORGES::UFormElm *elmt = 0; + if(parentItem->formElm->getArrayNode(&elmt, arrayIndex) && elmt) + { + if (elmt->isAtom()) + { + ((NLGEORGES::CFormElmAtom*)elmt)->setValue(value.toString().toStdString().c_str()); + nldebug(QString("array element string %1 %2") + .arg(itemData[0].toString()).arg(value.toString()) + .toStdString().c_str()); + } + } + } + } + else + { + if(parentItem->formElm->setValueByName( + value.toString().toStdString().c_str(), + itemData[0].toString().toStdString().c_str())) + { + nldebug(QString("string %1 %2") + .arg(itemData[0].toString()).arg(value.toString()) + .toStdString().c_str()); + } + else + { + nldebug(QString("FAILED string %1 %2") + .arg(itemData[0].toString()).arg(value.toString()) + .toStdString().c_str()); + } + } + break; + case NLGEORGES::UType::Color: + nldebug("Color is TODO"); + break; + default: + break; + } + } + } + else + { + nldebug("setting sth other than Atom"); + } + //formElm->setValueByName(); + return true; + } +} diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/formitem.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/formitem.h new file mode 100644 index 000000000..80efce5d5 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/formitem.h @@ -0,0 +1,69 @@ +// Object Viewer Qt - Georges Editor Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef FORMITEM_H +#define FORMITEM_H + +// NeL includes +#include + +// Qt includes +#include +#include + +namespace GeorgesQt +{ + + class CFormItem + + { + public: + CFormItem(NLGEORGES::UFormElm *elm, const QList &data, + CFormItem *parent = 0, + NLGEORGES::UFormElm::TWhereIsValue = NLGEORGES::UFormElm::ValueForm, + NLGEORGES::UFormElm::TWhereIsNode = NLGEORGES::UFormElm::NodeForm); + ~CFormItem(); + + void appendChild(CFormItem *child); + + CFormItem *child(int row); + int childCount() const; + int columnCount() const; + QVariant data(int column) const; + int row() const; + CFormItem *parent(); + bool setData(int column, const QVariant &value); + NLGEORGES::UFormElm* getFormElm() {return formElm;} + NLGEORGES::UFormElm::TWhereIsValue valueFrom() + { + return whereV; + } + NLGEORGES::UFormElm::TWhereIsNode nodeFrom() + { + return whereN; + } + + private: + QList childItems; + QList itemData; + CFormItem *parentItem; + NLGEORGES::UFormElm* formElm; + NLGEORGES::UFormElm::TWhereIsValue whereV; + NLGEORGES::UFormElm::TWhereIsNode whereN; + }; // CFormItem + +} +#endif // FORMITEM_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges.cpp new file mode 100644 index 000000000..50e007d90 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges.cpp @@ -0,0 +1,64 @@ +// Object Viewer Qt - Georges Editor Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "georges.h" +#include "nel/misc/o_xml.h" + +// STL includes + +// NeL includes +#include +#include +#include + +// Project includes + +using namespace NLGEORGES; + +namespace GeorgesQt +{ + + CGeorges::CGeorges(): FormLoader(0) + { + FormLoader = UFormLoader::createLoader(); + } + + CGeorges::~CGeorges() + { + } + + UForm *CGeorges::loadForm(std::string formName) + { + UForm *form = FormLoader->loadForm(formName.c_str()); + + return form; + } + + UFormDfn *CGeorges::loadFormDfn(std::string formName) + { + UFormDfn *formdfn = FormLoader->loadFormDfn(formName.c_str()); + + return formdfn; + } + + UType *CGeorges::loadFormType(std::string formName) + { + UType *type = FormLoader->loadFormType(formName.c_str()); + + return type; + } + +} /* namespace GeorgesQt */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges.h new file mode 100644 index 000000000..6d7455d3b --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges.h @@ -0,0 +1,69 @@ +// Object Viewer Qt - Georges Editor Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef GEORGES_H +#define GEORGES_H + +// Misc + +// STL includes +#include + +// NeL includes + +// Qt includes + +// Project includes + +namespace NLGEORGES +{ + class UType; + class UForm; + class UFormDfn; + class UFormLoader; +} + +using namespace NLGEORGES; + +namespace GeorgesQt +{ + + /** + @class CGeorges + A CGeorges class loading and viewing sheets. + */ + class CGeorges + { + public: + /// Default constructor. + CGeorges(); + virtual ~CGeorges(); + + // Load the given form root + UForm* loadForm(std::string formName); + // Load a dfn + UFormDfn* loadFormDfn(std::string formName); + // Load a type + UType *loadFormType (std::string formName); + + // A form loader + UFormLoader *FormLoader; + + };/* class CGeorges */ + +} /* namespace GeorgesQt */ + +#endif // GEORGES_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_dirtree_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_dirtree_dialog.cpp index f7e250cce..163ec7877 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_dirtree_dialog.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_dirtree_dialog.cpp @@ -23,20 +23,30 @@ // NeL includes -//using namespace NLMISC; - -namespace Plugin +namespace GeorgesQt { CGeorgesDirTreeDialog::CGeorgesDirTreeDialog(QString ldPath, QWidget *parent) - :QDockWidget(parent), m_ldPath(ldPath) + :QDockWidget(parent), + m_ldPath(ldPath) { m_ui.setupUi(this); + m_ui.filterResetButton->setIcon( + QApplication::style()->standardIcon(QStyle::SP_DialogCancelButton)); + m_dirModel = new CGeorgesFileSystemModel(m_ldPath); + //m_proxyModel = new CGeorgesFileSystemProxyModel(this); + + //m_proxyModel->setSourceModel(m_dirModel); m_ui.dirTree->setModel(m_dirModel); + // TODO: filtering in tree model is ... complicated - so hide it for now + m_ui.filterLineEdit->hide(); + m_ui.filterResetButton->hide(); + m_ui.label->hide(); + if (m_dirModel->isCorrectLDPath()) { m_dirModel->setRootPath(m_ldPath); @@ -61,7 +71,6 @@ CGeorgesDirTreeDialog::~CGeorgesDirTreeDialog() void CGeorgesDirTreeDialog::fileSelected(QModelIndex index) { - QString name; if (index.isValid() && !m_dirModel->isDir(index)) { Q_EMIT selectedForm(m_dirModel->fileName(index)); @@ -81,8 +90,12 @@ void CGeorgesDirTreeDialog::ldPathChanged(QString path) m_ldPath = path; delete m_dirModel; + //delete m_proxyModel; m_dirModel = new CGeorgesFileSystemModel(m_ldPath); + //m_proxyModel = new CGeorgesFileSystemProxyModel(this); + + //m_proxyModel->setSourceModel(m_dirModel); m_ui.dirTree->setModel(m_dirModel); if (m_dirModel->isCorrectLDPath()) @@ -96,4 +109,4 @@ void CGeorgesDirTreeDialog::ldPathChanged(QString path) } } -} /* namespace NLQT */ \ No newline at end of file +} /* namespace GeorgesQt */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_dirtree_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_dirtree_dialog.h index 3079f76c2..dc717617e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_dirtree_dialog.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_dirtree_dialog.h @@ -28,7 +28,7 @@ #include "ui_georges_dirtree_form.h" #include "georges_filesystem_model.h" -namespace Plugin +namespace GeorgesQt { class CGeorgesDirTreeDialog: public QDockWidget @@ -45,6 +45,7 @@ private: Ui::CGeorgesDirTreeDialog m_ui; CGeorgesFileSystemModel *m_dirModel; + //CGeorgesFileSystemProxyModel *m_proxyModel; QString m_ldPath; Q_SIGNALS: @@ -54,9 +55,8 @@ private Q_SLOTS: void fileSelected(QModelIndex index); void changeFile(QString file); - friend class CMainWindow; }; /* CGEorgesDirTreeDialog */ -} /* namespace NLQT */ +} /* namespace GeorgesQt */ #endif // GEORGES_DIRTREE_DIALOG_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_dirtree_form.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_dirtree_form.ui index 8731d1ca8..e14857e89 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_dirtree_form.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_dirtree_form.ui @@ -19,7 +19,7 @@ 200 - 111 + 141 @@ -36,7 +36,7 @@ - + @@ -44,11 +44,42 @@ 0 + + true + + + + + + + + + + ... + + + + :/images/ic_nel_georges_editor.png:/images/ic_nel_georges_editor.png + + + true + + + + + + + Filter + - + + + + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_constants.h index bb9fe3306..cccede9fc 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_constants.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_constants.h @@ -17,7 +17,7 @@ #ifndef GEORGES_EDITOR_CONSTANTS_H #define GEORGES_EDITOR_CONSTANTS_H -namespace Plugin +namespace GeorgesQt { namespace Constants { @@ -26,6 +26,6 @@ const char * const GEORGES_EDITOR_SECTION = "GeorgesEditor"; } // namespace Constants -} // namespace Plugin +} // namespace GeorgesQt #endif // GEORGES_EDITOR_CONSTANTS_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_form.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_form.cpp index aa614a161..5cf3eb9ce 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_form.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_form.cpp @@ -18,9 +18,10 @@ #include "georges_editor_form.h" #include "georges_editor_constants.h" #include "georges_dirtree_dialog.h" +#include "georges_treeview_dialog.h" #include "../core/icore.h" -#include "../core/imenu_manager.h" +#include "../core/menu_manager.h" #include "../core/core_constants.h" // NeL includes @@ -30,110 +31,246 @@ #include #include #include +#include -namespace Plugin +namespace GeorgesQt { -GeorgesEditorForm::GeorgesEditorForm(QWidget *parent) - : QMainWindow(parent), - m_georgesDirTreeDialog(0) -{ - m_ui.setupUi(this); - - m_undoStack = new QUndoStack(this); - - _openAction = new QAction(tr("&Open..."), this); - _openAction->setIcon(QIcon(Core::Constants::ICON_OPEN)); - _openAction->setShortcut(QKeySequence::Open); - _openAction->setStatusTip(tr("Open an existing file")); - connect(_openAction, SIGNAL(triggered()), this, SLOT(open())); - - _newAction = new QAction(tr("&New..."), this); - _newAction->setIcon(QIcon(Core::Constants::ICON_NEW)); - _newAction->setShortcut(QKeySequence::New); - _newAction->setStatusTip(tr("Create a new file")); - connect(_newAction, SIGNAL(triggered()), this, SLOT(newFile())); - - _saveAction = new QAction(tr("&Save..."), this); - _saveAction->setIcon(QIcon(Core::Constants::ICON_SAVE)); - _saveAction->setShortcut(QKeySequence::Save); - _saveAction->setStatusTip(tr("Save the current file")); - connect(_saveAction, SIGNAL(triggered()), this, SLOT(save())); - - _fileToolBar = addToolBar(tr("&File")); - _fileToolBar->addAction(_openAction); - _fileToolBar->addAction(_newAction); - _fileToolBar->addAction(_saveAction); - - readSettings(); - - // create leveldesign directory tree dockwidget - m_georgesDirTreeDialog = new CGeorgesDirTreeDialog(m_leveldesignPath, this); - addDockWidget(Qt::LeftDockWidgetArea, m_georgesDirTreeDialog); - //m_georgesDirTreeDialog->setVisible(false); - connect(Core::ICore::instance(), SIGNAL(changeSettings()), - this, SLOT(settingsChanged())); -} - -GeorgesEditorForm::~GeorgesEditorForm() -{ - writeSettings(); -} - -QUndoStack *GeorgesEditorForm::undoStack() const -{ - return m_undoStack; -} - -void GeorgesEditorForm::open() -{ - // TODO: FileDialog & loadFile(); - //QString fileName = QFileDialog::getOpenFileName(); - //loadFile(fileName); -} - -void GeorgesEditorForm::newFile() -{ - -} - -void GeorgesEditorForm::save() -{ - -} - -void GeorgesEditorForm::readSettings() -{ - QSettings *settings = Core::ICore::instance()->settings(); - settings->beginGroup(Constants::GEORGES_EDITOR_SECTION); - settings->endGroup(); - - settings->beginGroup(Core::Constants::DATA_PATH_SECTION); - m_leveldesignPath = settings->value(Core::Constants::LEVELDESIGN_PATH, "l:/leveldesign").toString(); - settings->endGroup(); -} - -void GeorgesEditorForm::writeSettings() -{ - QSettings *settings = Core::ICore::instance()->settings(); - settings->beginGroup(Constants::GEORGES_EDITOR_SECTION); - settings->endGroup(); - settings->sync(); -} - -void GeorgesEditorForm::settingsChanged() -{ - QSettings *settings = Core::ICore::instance()->settings(); - - settings->beginGroup(Core::Constants::DATA_PATH_SECTION); - QString oldLDPath = m_leveldesignPath; - m_leveldesignPath = settings->value(Core::Constants::LEVELDESIGN_PATH, "l:/leveldesign").toString(); - settings->endGroup(); - - if (oldLDPath != m_leveldesignPath) + GeorgesEditorForm::GeorgesEditorForm(QWidget *parent) + : QMainWindow(parent), + m_georgesDirTreeDialog(0), + m_mainDock(0), + m_lastActiveDock(0) { - m_georgesDirTreeDialog->ldPathChanged(m_leveldesignPath); - } -} + m_ui.setupUi(this); -} /* namespace Plugin */ + // background for the mainwindow + QString css = "QWidget#centralwidget {"; + css += "image: url(:/images/ic_nel_georges_editor.png);"; + css += "}"; + + // add new mainwindow for sheet dockwidgets + QWidget *widget = new QWidget(this); + widget->setObjectName("centralwidget"); + widget->setStyleSheet(css); + setCentralWidget(widget); + QGridLayout *layout = new QGridLayout(widget); + layout->setContentsMargins(0,0,0,0); + widget->setLayout(layout); + m_mainDock = new QMainWindow(this); + m_mainDock->setDockNestingEnabled(true); + layout->addWidget(m_mainDock); + + m_undoStack = new QUndoStack(this); + + Core::MenuManager *menuManager = Core::ICore::instance()->menuManager(); + m_openAction = menuManager->action(Core::Constants::OPEN); + + m_newAction = new QAction(tr("&New..."), this); + m_newAction->setIcon(QIcon(Core::Constants::ICON_NEW)); + m_newAction->setShortcut(QKeySequence::New); + m_newAction->setStatusTip(tr("Create a new file")); + connect(m_newAction, SIGNAL(triggered()), this, SLOT(newFile())); + + m_saveAction = new QAction(tr("&Save..."), this); + m_saveAction->setIcon(QIcon(Core::Constants::ICON_SAVE)); + m_saveAction->setShortcut(QKeySequence::Save); + m_saveAction->setStatusTip(tr("Save the current file")); + connect(m_saveAction, SIGNAL(triggered()), this, SLOT(save())); + + m_fileToolBar = addToolBar(tr("&File")); + m_fileToolBar->addAction(m_openAction); + m_fileToolBar->addAction(m_newAction); + m_fileToolBar->addAction(m_saveAction); + + m_saveAction->setEnabled(false); + + readSettings(); + + // create leveldesign directory tree dockwidget + m_georgesDirTreeDialog = new CGeorgesDirTreeDialog(m_leveldesignPath, this); + addDockWidget(Qt::LeftDockWidgetArea, m_georgesDirTreeDialog); + restoreDockWidget(m_georgesDirTreeDialog); + + connect(Core::ICore::instance(), SIGNAL(changeSettings()), + this, SLOT(settingsChanged())); + connect(m_georgesDirTreeDialog, SIGNAL(selectedForm(const QString)), + this, SLOT(loadFile(const QString))); + connect(qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), + this, SLOT(focusChanged(QWidget*, QWidget*))); + } + + GeorgesEditorForm::~GeorgesEditorForm() + { + writeSettings(); + } + + QUndoStack *GeorgesEditorForm::undoStack() const + { + return m_undoStack; + } + + void GeorgesEditorForm::open() + { + QString fileName = QFileDialog::getOpenFileName(this, tr("Open Form")); + if(!fileName.isNull()) + loadFile(fileName); + } + + void GeorgesEditorForm::newFile() + { + + } + + void GeorgesEditorForm::save() + { + m_lastActiveDock->write(); + m_saveAction->setEnabled(false); + + } + + void GeorgesEditorForm::readSettings() + { + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup(Constants::GEORGES_EDITOR_SECTION); + + restoreGeometry(settings->value("geometry").toByteArray()); + restoreState(settings->value("windowState").toByteArray()); + + settings->endGroup(); + + settings->beginGroup(Core::Constants::DATA_PATH_SECTION); + m_leveldesignPath = settings->value(Core::Constants::LEVELDESIGN_PATH, "l:/leveldesign").toString(); + settings->endGroup(); + } + + void GeorgesEditorForm::writeSettings() + { + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup(Constants::GEORGES_EDITOR_SECTION); + + settings->setValue("geometry", saveGeometry()); + settings->setValue("windowState", saveState()); + + settings->endGroup(); + settings->sync(); + } + + void GeorgesEditorForm::settingsChanged() + { + QSettings *settings = Core::ICore::instance()->settings(); + + settings->beginGroup(Core::Constants::DATA_PATH_SECTION); + QString oldLDPath = m_leveldesignPath; + m_leveldesignPath = settings->value(Core::Constants::LEVELDESIGN_PATH, "l:/leveldesign").toString(); + settings->endGroup(); + + if (oldLDPath != m_leveldesignPath) + { + m_georgesDirTreeDialog->ldPathChanged(m_leveldesignPath); + } + } + + void GeorgesEditorForm::loadFile(const QString fileName) + { + QFileInfo info(fileName); + + if (!m_dockedWidgets.size()) + { + CGeorgesTreeViewDialog *dock = new CGeorgesTreeViewDialog(m_mainDock); + dock->setUndoStack(m_undoStack); + m_lastActiveDock = dock; + m_dockedWidgets.append(dock); + + m_mainDock->addDockWidget(Qt::RightDockWidgetArea, m_dockedWidgets.last()); + connect(m_dockedWidgets.last(), SIGNAL(closing()), + this, SLOT(closingTreeView())); + connect(m_dockedWidgets.last(), SIGNAL(visibilityChanged(bool)), + m_dockedWidgets.last(), SLOT(checkVisibility(bool))); + } + else + { + + Q_FOREACH(CGeorgesTreeViewDialog *wgt, m_dockedWidgets) + { + if (info.fileName() == wgt->loadedForm) + { + wgt->raise(); + return; + } + } + CGeorgesTreeViewDialog *dock = new CGeorgesTreeViewDialog(m_mainDock); + dock->setUndoStack(m_undoStack); + m_dockedWidgets.append(dock); + + connect(m_dockedWidgets.last(), SIGNAL(closing()), + this, SLOT(closingTreeView())); + connect(m_dockedWidgets.last(), SIGNAL(visibilityChanged(bool)), + m_dockedWidgets.last(), SLOT(checkVisibility(bool))); + Q_ASSERT(m_dockedWidgets.size() > 1); + m_mainDock->tabifyDockWidget(m_dockedWidgets.at(m_dockedWidgets.size() - 2), m_dockedWidgets.last()); + } + CForm *form = m_dockedWidgets.last()->getFormByName(info.fileName()); + if (form) + { + m_dockedWidgets.last()->setForm(form); + m_dockedWidgets.last()->loadFormIntoDialog(form); + QApplication::processEvents(); + connect(m_dockedWidgets.last(), SIGNAL(modified()), + this, SLOT(setModified())); + m_dockedWidgets.last()->raise(); + connect(m_dockedWidgets.last(), SIGNAL(changeFile(QString)), + m_georgesDirTreeDialog, SLOT(changeFile(QString))); + } + else + { + m_dockedWidgets.last()->close(); + } + } + + void GeorgesEditorForm::closingTreeView() + { + //qDebug() << "closingTreeView"; + m_dockedWidgets.removeAll(qobject_cast(sender())); + if (qobject_cast(sender()) == m_lastActiveDock) + m_lastActiveDock = 0; + } + + void GeorgesEditorForm::setModified () + { + qDebug() << "setModified"; + if (m_lastActiveDock) + m_saveAction->setEnabled(m_lastActiveDock->isModified()); + else + m_saveAction->setEnabled(false); + } + + void GeorgesEditorForm::focusChanged ( QWidget * old, QWidget * now ) + { + if (now) + { + // ugly, UGLY hack for compensating QDockWidgets failure in focus API + if (now->objectName() == "treeView" || + now->objectName() == "checkBoxDefaults" || + now->objectName() == "checkBoxParent" || + now->objectName() == "commentEdit") + { + QWidget *dlg = 0; + QApplication::focusWidget()? + QApplication::focusWidget()->parentWidget()? + QApplication::focusWidget()->parentWidget()->parentWidget()? + QApplication::focusWidget()->parentWidget()->parentWidget()->parentWidget()? + QApplication::focusWidget()->parentWidget()->parentWidget()->parentWidget()->parentWidget()? + QApplication::focusWidget()->parentWidget()->parentWidget()->parentWidget()->parentWidget()->parentWidget()? + dlg=QApplication::focusWidget()->parentWidget()->parentWidget()->parentWidget()->parentWidget()->parentWidget():dlg=0:dlg=0:dlg=0:dlg=0:dlg=0:dlg=0; + CGeorgesTreeViewDialog *active = qobject_cast(dlg); + if(active) + { + //qDebug() << "focusChanged" << active->loadedForm; + m_lastActiveDock = active; + m_saveAction->setEnabled(active->isModified()); + } + } + } + } +} /* namespace GeorgesQt */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_form.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_form.h index 96fceb4ed..c991f8b9f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_form.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_form.h @@ -23,10 +23,11 @@ // Qt includes #include -namespace Plugin +namespace GeorgesQt { class CGeorgesDirTreeDialog; +class CGeorgesTreeViewDialog; class GeorgesEditorForm: public QMainWindow { Q_OBJECT @@ -39,9 +40,14 @@ public: public Q_SLOTS: void open(); + void loadFile(const QString fileName); void newFile(); void save(); void settingsChanged(); + void closingTreeView(); + void setModified(); + + void focusChanged(QWidget *old, QWidget *now); private: void readSettings(); @@ -51,14 +57,19 @@ private: Ui::GeorgesEditorForm m_ui; CGeorgesDirTreeDialog *m_georgesDirTreeDialog; - QToolBar *_fileToolBar; - QAction *_openAction; - QAction *_newAction; - QAction *_saveAction; + QToolBar *m_fileToolBar; + QAction *m_openAction; + QAction *m_newAction; + QAction *m_saveAction; QString m_leveldesignPath; + + QMainWindow *m_mainDock; + + QList m_dockedWidgets; + CGeorgesTreeViewDialog *m_lastActiveDock; }; /* class GeorgesEditorForm */ -} /* namespace Plugin */ +} /* namespace GeorgesQt */ #endif // GEORGES_EDITOR_FORM_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_form.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_form.ui index 905814cc7..3f8cde0f7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_form.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_form.ui @@ -13,12 +13,16 @@ Georges Editor + + + QWidget#centralwidget { image: url(:/images/ic_nel_georges_editor.png); } + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_plugin.cpp index a97188751..7dd0be5cd 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_plugin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_plugin.cpp @@ -27,7 +27,7 @@ // Qt includes #include -namespace Plugin +namespace GeorgesQt { GeorgesEditorPlugin::~GeorgesEditorPlugin() @@ -67,34 +67,6 @@ void GeorgesEditorPlugin::setNelContext(NLMISC::INelContext *nelContext) m_libContext = new NLMISC::CLibraryContext(*nelContext); } -QString GeorgesEditorPlugin::name() const -{ - return tr("Georges Editor"); -} - -QString GeorgesEditorPlugin::version() const -{ - return "0.2"; -} - -QString GeorgesEditorPlugin::vendor() const -{ - return "aquiles"; -} - -QString GeorgesEditorPlugin::description() const -{ - return tr("Tool to create & edit sheets or forms."); -} - -QStringList GeorgesEditorPlugin::dependencies() const -{ - QStringList list; - list.append(Core::Constants::OVQT_CORE_PLUGIN); - list.append("ObjectViewer"); // TODO - return list; -} - void GeorgesEditorPlugin::addAutoReleasedObject(QObject *obj) { m_plugMan->addObject(obj); @@ -125,4 +97,4 @@ QWidget *GeorgesEditorContext::widget() } -Q_EXPORT_PLUGIN(Plugin::GeorgesEditorPlugin) \ No newline at end of file +Q_EXPORT_PLUGIN(GeorgesQt::GeorgesEditorPlugin) \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_plugin.h index 7cc93dfb4..e21d8c57a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_plugin.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_editor_plugin.h @@ -38,7 +38,7 @@ namespace ExtensionSystem class IPluginSpec; } -namespace Plugin +namespace GeorgesQt { class GeorgesEditorForm; class GeorgesEditorPlugin : public QObject, public ExtensionSystem::IPlugin @@ -52,15 +52,8 @@ public: bool initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString); void extensionsInitialized(); void shutdown(); - void setNelContext(NLMISC::INelContext *nelContext); - QString name() const; - QString version() const; - QString vendor() const; - QString description() const; - QStringList dependencies() const; - void addAutoReleasedObject(QObject *obj); protected: @@ -100,6 +93,6 @@ public: GeorgesEditorForm *m_georgesEditorForm; }; -} // namespace Plugin +} // namespace GeorgesQt #endif // LANDSCAPE_EDITOR_PLUGIN_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_filesystem_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_filesystem_model.cpp index 20cb30b33..7f405fb75 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_filesystem_model.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_filesystem_model.cpp @@ -19,7 +19,7 @@ #include #include -namespace Plugin +namespace GeorgesQt { CGeorgesFileSystemModel::CGeorgesFileSystemModel(QString ldPath, QObject *parent) @@ -28,6 +28,10 @@ CGeorgesFileSystemModel::CGeorgesFileSystemModel(QString ldPath, QObject *parent m_correct(false) { checkLDPath(); + + // this yielded no relevant performance boost on my observations + //connect(this, SIGNAL(directoryLoaded(QString)), + // this, SLOT(dir(const QString))); } CGeorgesFileSystemModel::~CGeorgesFileSystemModel() @@ -35,6 +39,23 @@ CGeorgesFileSystemModel::~CGeorgesFileSystemModel() } +void CGeorgesFileSystemModel::dir(const QString &dir) +{ + // in theory this should prefetch all directory entries for the + // filesystem model to speed up later work + QModelIndex i = index(dir); + + if (hasChildren(i)) { + int childCount = rowCount(i); + for (int c=0; cnode(parent); +// return (!indexNode->populatedChildren);*/ +//} + +//CGeorgesFileSystemProxyModel::CGeorgesFileSystemProxyModel(QObject *parent) : QSortFilterProxyModel(parent) +//{ +// setFilterCaseSensitivity(Qt::CaseInsensitive); +//} + +//bool CGeorgesFileSystemProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const +//{ + // TODO this is not perfect as it could be + // eg it should filter all dirs which have no entry + //QModelIndex idx = sourceModel()->index(source_row, 0, source_parent); + //if (sourceModel()->hasChildren(idx)) + //{ + // QString d = sourceModel()->data(idx).toString(); + // //QModelIndex i = mapFromSource(source_parent); + // //if (hasChildren(i)) { + // int childCount = sourceModel()->rowCount(idx); + // for (int c=0; cindex(c, 0, idx); + // if (child.isValid()) { + // bool test = filterAcceptsRow(c, child); + // }*/ + // } + // return true; + //} + //return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); +//} + +//QVariant CGeorgesFileSystemProxyModel::data ( const QModelIndex & index, int role ) const +//{ +// if (role == Qt::DisplayRole) +// { +// QString test = QSortFilterProxyModel::data(index, role).toString(); +// return test.append(QString(" (%1/%2)")). +// arg(rowCount(index)). +// arg(sourceModel()->rowCount(mapToSource(index))); +// } +// return QSortFilterProxyModel::data(index, role); +//} +} /* namespace GeorgesQt */ /* end of file */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_filesystem_model.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_filesystem_model.h index 775dcb18d..6c7a26055 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_filesystem_model.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_filesystem_model.h @@ -18,33 +18,62 @@ #define GEORGES_FILESYSTEM_MODEL_H #include +#include -namespace Plugin +namespace GeorgesQt { -class CGeorgesFileSystemModel : public QFileSystemModel -{ - QString m_ldPath; - -public: - CGeorgesFileSystemModel(QString ldPath, QObject *parent = 0); - ~CGeorgesFileSystemModel(); - - int columnCount(const QModelIndex &/*parent*/) const; - int rowCount(const QModelIndex &/*parent*/) const; - - QVariant data(const QModelIndex& index, int role) const ; - - bool isCorrectLDPath() + class CGeorgesFileSystemModel : public QFileSystemModel { - return m_correct; - } - void checkLDPath(); + Q_OBJECT -private: - bool m_correct; -};/* class CGeorgesFileSystemModel */ + public: + CGeorgesFileSystemModel(QString ldPath, QObject *parent = 0); + ~CGeorgesFileSystemModel(); -} /* namespace NLQT */ + int columnCount(const QModelIndex &/*parent*/) const; + int rowCount(const QModelIndex &/*parent*/) const; + + QVariant data(const QModelIndex& index, int role) const ; + + bool isCorrectLDPath() + { + return m_correct; + } + bool isInitialized() + { + return m_initialized; + } + void setInitialized( bool init) + { + m_initialized = init; + } + void checkLDPath(); + + private: + bool m_correct; + bool m_initialized; + QString m_ldPath; + +private Q_SLOTS: + void dir(const QString&); + };/* class CGeorgesFileSystemModel */ + + // A modified QSortFilterProxyModel that always accepts the root nodes in the tree + // so filtering is only done on the children. + //class CGeorgesFileSystemProxyModel : public QSortFilterProxyModel + //{ + // Q_OBJECT + + //public: + // CGeorgesFileSystemProxyModel(QObject *parent = 0); + + //QVariant data(const QModelIndex& index, int role) const ; + + //protected: + // bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; + //}; + +} /* namespace GeorgesQt */ #endif // GEORGES_FILESYSTEM_MODEL_H \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_treeview_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_treeview_dialog.cpp new file mode 100644 index 000000000..f7386cd60 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_treeview_dialog.cpp @@ -0,0 +1,549 @@ +// Object Viewer Qt - Georges Editor Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "georges_treeview_dialog.h" + +// Qt includes +#include +#include +#include +#include +#include + +// NeL includes +#include +#include +#include +#include +#include +#include +#include + +// OVQT Includes +#include "../core/icore.h" +#include "../core/core_constants.h" + +// Project includes +#include "georges.h" +#include "georgesform_model.h" +#include "georgesform_proxy_model.h" +#include "formitem.h" +#include "formdelegate.h" +#include "expandable_headerview.h" + +using namespace NLMISC; +using namespace NLGEORGES; + +namespace GeorgesQt +{ + + CGeorgesTreeViewDialog::CGeorgesTreeViewDialog(QWidget *parent /*= 0*/) + : QDockWidget(parent), + m_header(0), + m_modified(false) + { + m_georges = new CGeorges; + + loadedForm = ""; + // Set the default sheet dir dir to the level design path. + m_lastSheetDir = "."; + QSettings *settings = Core::ICore::instance()->settings(); + m_lastSheetDir = settings->value(Core::Constants::LEVELDESIGN_PATH, "l:/leveldesign").toString(); + settings->endGroup(); + + m_ui.setupUi(this); + m_header = new ExpandableHeaderView(Qt::Horizontal, m_ui.treeView); + m_ui.treeView->setHeader(m_header); + m_ui.treeView->header()->setResizeMode(QHeaderView::ResizeToContents); + m_ui.treeView->header()->setStretchLastSection(true); + m_ui.treeViewTabWidget->setTabEnabled (2,false); + + m_ui.checkBoxParent->setStyleSheet("background-color: rgba(0,255,0,30)"); + m_ui.checkBoxDefaults->setStyleSheet("background-color: rgba(255,0,0,30)"); + m_form = 0; + + FormDelegate *formdelegate = new FormDelegate(this); + m_ui.treeView->setItemDelegateForColumn(1, formdelegate); + + // Set up custom context menu. + setContextMenuPolicy(Qt::CustomContextMenu); + connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showContextMenu(const QPoint&))); + + connect(m_ui.treeView, SIGNAL(doubleClicked (QModelIndex)), + this, SLOT(doubleClicked (QModelIndex))); + connect(m_ui.checkBoxParent, SIGNAL(toggled(bool)), + this, SLOT(filterRows())); + connect(m_ui.checkBoxDefaults, SIGNAL(toggled(bool)), + this, SLOT(filterRows())); + connect(m_header, SIGNAL(headerClicked(int)), + this, SLOT(headerClicked(int))); + } + + CGeorgesTreeViewDialog::~CGeorgesTreeViewDialog() + { + delete m_form; + qDebug() << "DTOR"; + } + + void CGeorgesTreeViewDialog::headerClicked(int section) + { + if (section == 0) + { + if (*(m_header->expanded())) + m_ui.treeView->expandAll(); + else + m_ui.treeView->collapseAll(); + } + } + + void CGeorgesTreeViewDialog::setForm(const CForm *form) + { + m_form = (UForm*)form; + } + + CForm* CGeorgesTreeViewDialog::getFormByName(const QString formName) + { + if(NLMISC::CPath::exists(formName.toStdString())) + { + return (CForm*)m_georges->loadForm(formName.toStdString()); + } + //else + //{ + // CForm *form = 0; + // // Load the DFN + // std::string extStr = NLMISC::CFile::getExtension( formName.toStdString() ); + // QString dfnName = QString("%1.dfn").arg(extStr.c_str()); + // UFormDfn *formdfn; + // if (NLMISC::CPath::exists(dfnName.toStdString())) + // { + // formdfn = _georges->loadFormDfn (dfnName.toStdString()); + // if (!formdfn) + // { + // nlwarning("Failed to load dfn: %s", dfnName.toStdString().c_str()); + // return 0; + // } + // } + // else + // { + // nlwarning("Cannot find dfn: %s", dfnName.toStdString().c_str()); + // return 0; + // } + + // form = new CForm; + + // // Build the root element + // ((CFormElmStruct*)&form->getRootNode())->build((CFormDfn*)formdfn); + + // uint i; + // for (i=0; iHeldElements[i]))->build ((CFormDfn*)formdfn); + // } + // return form; + //} + return 0; + } + + void CGeorgesTreeViewDialog::loadFormIntoDialog(CForm *form) + { + + if(form) + m_form = form; + else + return; + + UFormElm *root = 0; + root = &m_form->getRootNode(); + + QStringList parents; + for (uint i = 0; i < m_form->getNumParent(); i++) + { + UForm *u = m_form->getParentForm(i); + parents << u->getFilename().c_str(); + } + + QString comments; + comments = m_form->getComment().c_str(); + + if (!comments.isEmpty()) + { + m_ui.treeViewTabWidget->setTabEnabled (1,true); + m_ui.commentEdit->setPlainText(comments); + } + + QStringList strList; + std::set dependencies; + m_form->getDependencies(dependencies); + + QMap< QString, QStringList> deps; + Q_FOREACH(std::string str, dependencies) + { + QString file = str.c_str(); + if (str == m_form->getFilename()) continue; + deps[file.remove(0,file.indexOf(".")+1)] << str.c_str(); + } + nlinfo("typ's %d",deps["typ"].count()); + nlinfo("dfn's %d",deps["dfn"].count()); + + //nlwarning(strList.join(";").toStdString().c_str()); + if (root) + { + loadedForm = m_form->getFilename().c_str(); + + CGeorgesFormModel *model = new CGeorgesFormModel(root,deps,comments,parents,m_header->expanded()); + CGeorgesFormProxyModel *proxyModel = new CGeorgesFormProxyModel(); + proxyModel->setSourceModel(model); + m_ui.treeView->setModel(proxyModel); + m_ui.treeView->expandAll(); + // this is a debug output row + m_ui.treeView->hideColumn(3); + + filterRows(); + + // //_ui.treeView->setRowHidden(0,QModelIndex(),true); + connect(model, SIGNAL(dataChanged(const QModelIndex, const QModelIndex)), + this, SLOT(modifiedFile())); + + setWindowTitle(loadedForm); + // //Modules::mainWin().getTabBar(); + } + } + + void CGeorgesTreeViewDialog::addParentForm(QString parentFormNm) + { + // Try to load the form + NLGEORGES::UForm *uParentForm = m_georges->loadForm(parentFormNm.toStdString()); + NLGEORGES::CForm *parentForm = dynamic_cast(uParentForm); + NLGEORGES::CForm *mainForm = static_cast(m_form); + + CGeorgesFormProxyModel * proxyModel = dynamic_cast(m_ui.treeView->model()); + CGeorgesFormModel *model = dynamic_cast(proxyModel->sourceModel()); + + if(parentForm) + { + if (mainForm != parentForm) + { + // Check it is the same dfn + if (parentForm->Elements.FormDfn == mainForm->Elements.FormDfn) + { + // This is the parent form selector + if(!mainForm->insertParent(mainForm->getParentCount(),parentFormNm.toStdString().c_str(), parentForm)) + nlwarning("Failed to add parent form: %s", parentFormNm.toStdString().c_str()); + else + { + nlinfo("Successfullyadded parent form: %s", parentFormNm.toStdString().c_str()); + model->addParentForm(parentFormNm); + } + } + } + } + } + + void CGeorgesTreeViewDialog::modifiedFile( ) + { + if (!m_modified) + { + m_modified = true; + setWindowTitle(windowTitle() + "*"); + } + Q_EMIT modified(); + } + + void CGeorgesTreeViewDialog::write( ) + { + + NLMISC::COFile file; + std::string s = NLMISC::CPath::lookup(loadedForm.toStdString(), false); + if(file.open (s)) + { + try + { + // if (loadedForm.contains(".typ")) + // { + // //nlassert (Type != NULL); + + // //// Write the file + // //// Modified ? + // //if (IsModified ()) + // //{ + // // Type->Header.MinorVersion++; + // // flushValueChange (); + // //} + // //Type->write (xmlStream.getDocument (), theApp.Georges4CVS); + // //modify (NULL, NULL, false); + // //flushValueChange (); + // //UpdateAllViews (NULL); + // //return TRUE; + // } + // else if (loadedForm.contains(".dfn")) + // { + // //nlassert (Dfn != NULL); + + // //// Write the file + // //if (IsModified ()) + // //{ + // // Dfn->Header.MinorVersion++; + // // flushValueChange (); + // //} + // //Dfn->write (xmlStream.getDocument (), lpszPathName, theApp.Georges4CVS); + // //modify (NULL, NULL, false); + // //UpdateAllViews (NULL); + // //return TRUE; + // } + // else + // { + nlassert (m_form != NULL); + + // Write the file + // /*if (IsModified ()) + // { + // ((CForm*)(UForm*)Form)->Header.MinorVersion++; + // }*/ + // //((CForm*)(UForm*)Form)->write (xmlStream.getDocument (), lpszPathName, theApp.Georges4CVS); + m_form->write(file, false); + setWindowTitle(windowTitle().remove("*")); + m_modified = false; + // //if (strcmp (xmlStream.getErrorString (), "") != 0) + // //{ + // // char message[512]; + // // smprintf (message, 512, "Error while saving file: %s", xmlStream.getErrorString ()); + // //theApp.outputError (message); + // //} + // //modify (NULL, NULL, false); + // //flushValueChange (); + // //UpdateAllViews (NULL); + + // // Get the left view + // //CView* pView = getLeftView (); + // } + } + catch (Exception &e) + { + nlerror("Error while loading file: %s", e.what()); + } + } + else + { + nlerror("Can't open the file %s for writing.", s.c_str()); + } + } + + void CGeorgesTreeViewDialog::doubleClicked ( const QModelIndex & index ) + { + // TODO: this is messy :( perhaps this can be done better + CGeorgesFormProxyModel * proxyModel = + dynamic_cast(m_ui.treeView->model()); + CGeorgesFormModel *model = + dynamic_cast(proxyModel->sourceModel()); + QModelIndex sourceIndex = proxyModel->mapToSource(index); + + CFormItem *item = model->getItem(sourceIndex); + + if (item->parent() && item->parent()->data(0) == "parents") + { + Q_EMIT changeFile(CPath::lookup(item->data(0).toString().toStdString(),false).c_str()); + } + + //// col containing additional stuff like icons + //if (index.column() == 2) + //{ + // QModelIndex in2 = m->index(in.row(),in.column()-1,in.parent()); + // CFormItem *item = m->getItem(in2); + // QString value = item->data(1).toString(); + + // QString path = CPath::lookup(value.toStdString(),false).c_str(); + + // if(value.contains(".tga") || value.contains(".png")) + // { + // QString file = QFileDialog::getOpenFileName( + // this, + // "Select a new image", + // path, + // "Images (*.png *.tga)" + // ); + // if (file.isNull()) + // return; + // QFileInfo info = QFileInfo(file); + + // // TODO? + // // right way would be another delegate but im too lazy :) + // // so for now i just call it directly + // m->setData(in2, info.fileName()); + // return; + // } + // else + // { + // if (path.contains(".shape") || path.contains(".ps")) + // { + // if (Modules::objViewInt()) + // { + // Modules::objViewInt()->resetScene(); + // //Modules::config().configRemapExtensions(); + // Modules::objViewInt()->loadMesh(path.toStdString(),""); + // } + // return; + // } + // } + + // // open eg parent files + // if (!path.isEmpty()) + // Q_EMIT changeFile(path); + + //} + } + + void CGeorgesTreeViewDialog::closeEvent(QCloseEvent *event) + { + Q_EMIT closing(); + deleteLater(); + } + + void CGeorgesTreeViewDialog::checkVisibility(bool visible) { + // this prevents invisible docks from getting tab focus + qDebug() << "checkVisibility" << visible; + setEnabled(visible); + //if (visible) + Q_EMIT modified(); + } + + void CGeorgesTreeViewDialog::filterRows() + { + CGeorgesFormProxyModel * mp = dynamic_cast(m_ui.treeView->model()); + CGeorgesFormModel *m = dynamic_cast(mp->sourceModel()); + if (m) { + m->setShowParents(m_ui.checkBoxParent->isChecked()); + m->setShowDefaults(m_ui.checkBoxDefaults->isChecked()); + } + } + + void CGeorgesTreeViewDialog::showContextMenu(const QPoint &pos) + { + QMenu contextMenu; + QMenu *structContext = NULL; + QPoint globalPos = this->mapToGlobal(pos); + + // Fisrt we're going to see if we've right clicked on a new item and select it. + const QModelIndex &index = this->m_ui.treeView->currentIndex(); + + if(!index.isValid()) + return; + + CGeorgesFormProxyModel * mp = dynamic_cast(m_ui.treeView->model()); + CGeorgesFormModel *m = dynamic_cast(mp->sourceModel()); + QModelIndex sourceIndex = mp->mapToSource(index); + + if (m) + { + + CFormItem *item = m->getItem(sourceIndex); + + // Right click on the "parents" item + if (item->data(0) == "parents") + contextMenu.addAction("Add parent..."); + // Right click on a parent item + else if(item->parent() && item->parent()->data(0) == "parents") + { + contextMenu.addAction("Add parent..."); + contextMenu.addAction("Remove parent"); + } + else if(item->getFormElm()->isArray()) + contextMenu.addAction("Add array entry..."); + else if(item->getFormElm()->isStruct()) + { + QMenu *structContext = new QMenu("Add struct element...", this); + contextMenu.addMenu(structContext); + + NLGEORGES::UFormDfn *defn = item->getFormElm()->getStructDfn(); + if(defn) + { + for(uint defnNum=0; defnNum < defn->getNumEntry(); defnNum++) + { + std::string entryName; + std::string dummy; + UFormElm::TWhereIsValue *whereV = new UFormElm::TWhereIsValue; + bool result = defn->getEntryName(defnNum, entryName); + bool result2 = item->getFormElm()->getValueByName(dummy, entryName.c_str(), NLGEORGES::UFormElm::Eval, whereV); + + + if(result2 && *whereV != UFormElm::ValueForm) + { + structContext->addAction(entryName.c_str()); + } + delete whereV; + } + } + } + else if(item->getFormElm()->isAtom() && item->valueFrom() == NLGEORGES::UFormElm::ValueForm) + contextMenu.addAction("Revert to parent/default..."); + + QAction *selectedItem = contextMenu.exec(globalPos); + if(selectedItem) + { + if(selectedItem->text() == "Add parent...") + { + // Get the file extension of the form so we can build a dialog pattern. + QString file = m_form->getFilename().c_str(); + file = file.remove(0,file.indexOf(".")+1); + QString filePattern = "Parent Sheets (*."+file+")"; + + nlinfo("parent defn name '%s'", file.toStdString().c_str()); + QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Select parent sheets..."), m_lastSheetDir, filePattern); + if(!fileNames.isEmpty()) + { + Q_FOREACH(QString fileToParent, fileNames) + { + // Get just the filename. Georges doesn't want the path. + QFileInfo pathInfo( fileToParent ); + QString tmpFileName( pathInfo.fileName() ); + + nlinfo("requesting to add parent form '%s'", tmpFileName.toStdString().c_str()); + + // Call to add the form and load it into the Georges form. + addParentForm(tmpFileName); + + // Save the file lookup path for future dialog boxes. + m_lastSheetDir = pathInfo.absolutePath(); + } + } + m_ui.treeView->expandAll(); + } + else if(selectedItem->text() == "Remove parent") + { + NLGEORGES::CForm *form = static_cast(m_form); + QString parentFileName = item->data(0).toString(); + + for(uint num = 0; num < form->getParentCount(); num++) + { + QString curParentName = form->getParent(num)->getFilename().c_str(); + if(parentFileName == curParentName) + { + form->removeParent(num); + m->removeParentForm(parentFileName); + break; + } + } + + m_ui.treeView->expandAll(); + } + + } // if selected context menu item is valid. + } // if 'm' model valid. + + if(structContext) + delete structContext; + } + +} /* namespace GeorgesQt */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_treeview_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_treeview_dialog.h new file mode 100644 index 000000000..a7ff4c375 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_treeview_dialog.h @@ -0,0 +1,109 @@ +// Object Viewer Qt - Georges Editor Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef GEORGES_TREEVIEWER_DIALOG_H +#define GEORGES_TREEVIEWER_DIALOG_H + +#include "ui_georges_treeview_form.h" +#include "expandable_headerview.h" + +// Qt includes +#include +#include +#include + + +// STL includes + +// NeL includes + +// Project includes + +namespace NLGEORGES +{ + class UForm; + class CForm; +} + +using namespace NLGEORGES; + +namespace GeorgesQt +{ + + class CGeorges; + + class CGeorgesTreeViewDialog: public QDockWidget + { + Q_OBJECT + + public: + CGeorgesTreeViewDialog(QWidget *parent = 0); + ~CGeorgesTreeViewDialog(); + + bool isModified() {return m_modified;} + void setModified(bool m) {m_modified = m;} + + CForm* getFormByName(const QString); + void addParentForm(QString parentFormNm); + + void write ( ); + + QTabWidget* tabWidget() { return m_ui.treeViewTabWidget; } + + void setUndoStack(QUndoStack *stack) { + m_undoStack = stack; + } + + QString loadedForm; + + protected: + void closeEvent(QCloseEvent *event); + + Q_SIGNALS: + void changeFile(QString); + void modified(); + void closing(); + + public Q_SLOTS: + void setForm(const CForm*); + void loadFormIntoDialog(CForm *form = 0); + void modifiedFile( ); + void checkVisibility(bool); + void showContextMenu(const QPoint &pos); + + private Q_SLOTS: + void doubleClicked ( const QModelIndex & index ); + void filterRows(); + void headerClicked(int); + + private: + Ui::CGeorgesTreeViewDialog m_ui; + ExpandableHeaderView *m_header; + UForm *m_form; + CGeorges *m_georges; + + QUndoStack *m_undoStack; + + /// Contains a record of the last directory a sheet file dialog was opened for. + QString m_lastSheetDir; + + bool m_modified; + + }; /* CGeorgesTreeViewDialog */ + +} /* namespace GeorgesQt */ + +#endif // GEORGES_TREEVIEWER_DIALOG_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_treeview_form.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_treeview_form.ui new file mode 100644 index 000000000..8d53bfdd6 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georges_treeview_form.ui @@ -0,0 +1,133 @@ + + + CGeorgesTreeViewDialog + + + + 0 + 0 + 400 + 300 + + + + + 0 + 0 + + + + + 199 + 165 + + + + Qt::NoFocus + + + + + + + + + + QTabWidget::West + + + 0 + + + + Qt::NoFocus + + + Form + + + + 0 + + + + + + 0 + 0 + + + + + 0 + 0 + + + + true + + + + + + + Parent + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Defaults + + + + + + + + Comment + + + + + + false + + + + + + + + Log + + + + + + + + + + + + + + + + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georgesform_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georgesform_model.cpp new file mode 100644 index 000000000..ca016e052 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georgesform_model.cpp @@ -0,0 +1,695 @@ +// Object Viewer Qt - Georges Editor Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "georgesform_model.h" + +// NeL includes +#include +#include +#include +#include +#include +#include + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// project includes +#include "formitem.h" + +using namespace NLGEORGES; + +namespace GeorgesQt +{ + + CGeorgesFormModel::CGeorgesFormModel(UFormElm *rootElm, QMap< QString, QStringList> deps, + QString comment, QStringList parents, bool *expanded, QObject *parent) : QAbstractItemModel(parent) + { + + m_rootData << "Value" << "Data" << "Extra";// << "Type"; + m_rootElm = rootElm; + m_rootItem = new CFormItem(m_rootElm, m_rootData); + m_dependencies = deps; + m_comments = comment; + m_parents = parents; + m_parentRows = new QList; + m_expanded = expanded; + + setupModelData(); + } + + CGeorgesFormModel::~CGeorgesFormModel() + { + delete m_rootItem; + } + + /******************************************************************************/ + + QVariant CGeorgesFormModel::data(const QModelIndex &p_index, int p_role) const + { + if (!p_index.isValid()) + return QVariant(); + + switch (p_role) + { + case Qt::DisplayRole: + { + return getItem(p_index)->data(p_index.column()); + } + case Qt::BackgroundRole: + { + QBrush defaultBrush = QBrush(QColor(255,0,0,30)); + QBrush parentBrush = QBrush(QColor(0,255,0,30)); + + // if elm not existing it must be some kind of default or type value + if(!getItem(p_index)->getFormElm()) + { + return defaultBrush; + } + + // else it might be some parent elm + switch (getItem(p_index)->nodeFrom()) + { + case NLGEORGES::UFormElm::NodeParentForm: + { + return parentBrush; + } + case NLGEORGES::UFormElm::NodeForm: + { + switch (getItem(p_index)->valueFrom()) + { + case NLGEORGES::UFormElm::ValueParentForm: + { + return parentBrush; + } + default: + { + // parent status test kindof ugly, testing only 2 steps deep + // only needed for colorization as treeview default hides childs + // when parent is hidden + CFormItem *parent = getItem(p_index)->parent(); + if (parent) + { + if (parent->nodeFrom() == NLGEORGES::UFormElm::NodeParentForm) + { + return parentBrush; + } + + CFormItem *parentParent = parent->parent(); + if (parentParent) + { + if (parentParent->nodeFrom() == NLGEORGES::UFormElm::NodeParentForm) + { + return parentBrush; + } + } // endif parentParent + } // endif parent + } // end default + } // end switch valueFrom + } // end case nodeForm + } // end switch nodeFrom + return QVariant(); + } + case Qt::DecorationRole: + { + if (p_index.column() == 2) + { + //p_index. + QModelIndex in = index(p_index.row(),p_index.column()-1,p_index.parent()); + CFormItem *item = getItem(in); + + QString value = item->data(1).toString(); + //QString path = NLMISC::CPath::lookup(value.toStdString(),false).c_str(); + + /*if (value.contains(".shape")) + { + if (Modules::objViewInt()) + { + QIcon *icon = Modules::objViewInt()->saveOneImage(value.toStdString()); + if (icon) + { + if(icon->isNull()) + return QIcon(":/images/pqrticles.png"); + else + return QIcon(*icon); + } + else + { + return QIcon(); + } + } + }*/ + if(value.contains(".tga") || value.contains(".png")) + { + QString path = NLMISC::CPath::lookup(value.toStdString(),false).c_str(); + if(path.isEmpty()) + { + path = ":/images/pqrticles.png"; + } + return QIcon(path); + } + } + return QVariant(); + break; + } + case Qt::ToolTipRole: + { + if (p_index.column() == 2) + { + QModelIndex in = index(p_index.row(),p_index.column()-1,p_index.parent()); + CFormItem *item = getItem(in); + QString value = item->data(1).toString(); + + /*if (value.contains(".shape")) + { + if (Modules::objViewInt()) + { + QIcon *icon = Modules::objViewInt()->saveOneImage(value.toStdString()); + if (icon) + { + if(icon->isNull()) + return QIcon(":/images/pqrticles.png"); + else + return QIcon(*icon); + } + else + { + return QIcon(); + } + } + }*/ + if(value.contains(".tga") || value.contains(".png")) + { + QString path = NLMISC::CPath::lookup(value.toStdString(),false).c_str(); + if(path.isEmpty()) + { + path = ":/images/pqrticles.png"; + } + + QString imageTooltip = QString("").arg(path); + + return imageTooltip; + } + } + return QVariant(); + break; + } + default: + return QVariant(); + } + } + + /******************************************************************************/ + + CFormItem *CGeorgesFormModel::getItem(const QModelIndex &index) const + { + if (index.isValid()) + { + CFormItem *item = static_cast(index.internalPointer()); + if (item) + return item; + } + return m_rootItem; + } + + /******************************************************************************/ + + bool CGeorgesFormModel::setData(const QModelIndex &index, const QVariant &value, + int role) + { + + if (role != Qt::EditRole) + return false; + + CFormItem *item = getItem(index); + bool result = item->setData(index.column(), value); + + Q_EMIT dataChanged(index, index); + + //setupModelData(); + return result; + } + + /******************************************************************************/ + + Qt::ItemFlags CGeorgesFormModel::flags(const QModelIndex& index) const { + + if (!index.isValid()) + return 0; + + Qt::ItemFlags returnValue = Qt::ItemIsSelectable | Qt::ItemIsEnabled; + + if(index.column() == 1) + returnValue |= Qt::ItemIsEditable; + + return returnValue; + + } + + /******************************************************************************/ + + QVariant CGeorgesFormModel::headerData(int section, + Qt::Orientation orientation, int role) const + { + if (orientation == Qt::Horizontal) + { + if (role == Qt::DisplayRole) + return m_rootItem->data(section); + if (role == Qt::TextAlignmentRole) + return Qt::AlignLeft; + if (section == 0 && role == Qt::DecorationRole) + { + // transparent pixmap as we paint it ourself with tree brach + // if we extend the HeaderView::paintSection for the CE_HeaderLabel + // we could drop this + QPixmap pixmap = QPixmap( + QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize), + QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize)); + // Create new picture for transparent + QPixmap transparent(pixmap.size()); + + // Do transparency + transparent.fill(Qt::transparent); + QPainter p(&transparent); + p.setCompositionMode(QPainter::CompositionMode_Source); + p.drawPixmap(0, 0, pixmap); + p.setCompositionMode(QPainter::CompositionMode_DestinationIn); + // Set transparency level to 150 (possible values are 0-255) + // The alpha channel of a color specifies the transparency effect, + // 0 represents a fully transparent color, while 255 represents + // a fully opaque color. + p.fillRect(transparent.rect(), QColor(0, 0, 0, 0)); + p.end(); + + // Set original picture's reference to new transparent one + pixmap = transparent; + return pixmap; + } + } + return QVariant(); + } + + /******************************************************************************/ + + QModelIndex CGeorgesFormModel::index(int row, int column, const QModelIndex &parent) + const + { + if (!hasIndex(row, column, parent)) + return QModelIndex(); + + CFormItem *parentItem; + + if (!parent.isValid()) + parentItem = m_rootItem; + else + parentItem = static_cast(parent.internalPointer()); + + CFormItem *childItem = parentItem->child(row); + if (childItem) + return createIndex(row, column, childItem); + else + return QModelIndex(); + } + + /******************************************************************************/ + + QModelIndex CGeorgesFormModel::parent(const QModelIndex &index) const + { + if (!index.isValid()) + return QModelIndex(); + + CFormItem *childItem = static_cast(index.internalPointer()); + CFormItem *parentItem = childItem->parent(); + + if (parentItem == m_rootItem) + return QModelIndex(); + + return createIndex(parentItem->row(), 0, parentItem); + } + + /******************************************************************************/ + + int CGeorgesFormModel::rowCount(const QModelIndex &parent) const { + + CFormItem *parentItem; + if (parent.column() > 0) + return 0; + + if (!parent.isValid()) + parentItem = m_rootItem; + else + parentItem = static_cast(parent.internalPointer()); + + return parentItem->childCount(); + + } + + /******************************************************************************/ + + int CGeorgesFormModel::columnCount(const QModelIndex &parent) const { + + if (parent.isValid()) + return static_cast(parent.internalPointer())->columnCount(); + else + return m_rootItem->columnCount(); + + } + + /******************************************************************************/ + + void CGeorgesFormModel::loadFormData(UFormElm *root, CFormItem *parent) { + + if (!root) + return; + + uint num = 0; + + + if (root->isStruct()) + { + //((CFormElm*)root)->getForm()->getComment(); + uint structSize = 0; + root->getStructSize(structSize); + while (num < structSize) + { + UFormElm::TWhereIsNode *whereN = new UFormElm::TWhereIsNode; + UFormElm::TWhereIsValue *whereV = new UFormElm::TWhereIsValue; + // Append a new item to the current parent's list of children. + std::string elmName; + if(root->getStructNodeName(num, elmName)) + { + QList columnData; + //QVariant value; + std::string value; + //NLMISC::CRGBA value_color; + //uint value_uint; + //sint value_sint; + //double value_double; + QString elmtType = ""; + UFormElm *elmt = 0; + if(root->getNodeByName(&elmt, elmName.c_str(), whereN, true)) + { + if (elmt) + { + if (elmt->isArray()) + elmtType = "Array"; + if (elmt->isStruct()) + elmtType = "Struct"; + if (elmt->isAtom()) + { + elmtType = "Atom"; + uint numDefinitions = 0; + const UType *type = elmt->getType(); + if (type) + { + numDefinitions = type->getNumDefinition(); + root->getValueByName(value, elmName.c_str(),UFormElm::Eval,whereV); + switch (type->getType()) + { + case UType::UnsignedInt: + value = QString("%1").arg(QString("%1").arg(value.c_str()).toDouble()).toStdString(); + elmtType.append("_uint");break; + case UType::SignedInt: + value = QString("%1").arg(QString("%1").arg(value.c_str()).toDouble()).toStdString(); + elmtType.append("_sint");break; + case UType::Double: + value = QString("%1").arg(QString("%1").arg(value.c_str()).toDouble(),0,'f',1).toStdString(); + elmtType.append("_double");break; + case UType::String: + elmtType.append("_string");break; + case UType::Color: + elmtType.append("_color");break; + default: + elmtType.append("_unknownType"); + } + } + else + { + elmtType.append("_noType"); + } + + if (numDefinitions) + { + std::string l, v; + QString tmpLabel, tmpValue; + for (uint i = 0; i < numDefinitions; i++) + { + type->getDefinition(i,l,v); + tmpLabel = l.c_str(); + tmpValue = v.c_str(); + if (type->getType() == UType::SignedInt) + { + if (QString("%1").arg(value.c_str()).toDouble() == tmpValue.toDouble()) { + value = l; + break; + } + } + if (type->getType() == UType::String) + { + if (QString(value.c_str()) == tmpValue) + { + value = l; + break; + } + } + } + } + } + if (elmt->isVirtualStruct()) + { + root->getValueByName(value, elmName.c_str(),UFormElm::Eval,whereV); + elmtType = "VirtualStruct"; + } + switch (*whereN) + { + case UFormElm::NodeForm: + elmtType.append("_fromForm"); break; + case UFormElm::NodeParentForm: + elmtType.append("_fromParentForm"); break; + case UFormElm::NodeDfn: + elmtType.append("_isDFN"); break; + case UFormElm::NodeType: + elmtType.append("_isType"); break; + default: + elmtType.append("_noNode"); + } + switch (*whereV) + { + case UFormElm::ValueForm: + elmtType.append("_formValue"); break; + case UFormElm::ValueParentForm: + elmtType.append("_parentValue"); break; + case UFormElm::ValueDefaultDfn: + elmtType.append("_dfnValue"); break; + case UFormElm::ValueDefaultType: + elmtType.append("_typeValue"); break; + default: + elmtType.append("_noValue"); + } + columnData << QString(elmName.c_str()) << QString(value.c_str()) << "";// << elmtType; + parent->appendChild(new CFormItem(elmt, columnData, parent, *whereV, *whereN)); + //if (parents.last()->childCount() > 0) { + // parents << parents.last()->child(parents.last()->childCount()-1); + //} + loadFormData(elmt, parent->child(parent->childCount()-1)); + } + else + { + // add Defaults + // TODO: spams warnings for non ATOM values but i dont get type of non existing nodes + bool success = root->getValueByName(value, elmName.c_str(),UFormElm::Eval,whereV); + switch (*whereN) + { + case UFormElm::NodeForm: + elmtType.append("_fromForm"); break; + case UFormElm::NodeParentForm: + elmtType.append("_fromParentForm"); break; + case UFormElm::NodeDfn: + elmtType.append("_isDFN"); break; + case UFormElm::NodeType: + elmtType.append("_isType"); break; + default: + elmtType.append("_noNode"); + } + switch (*whereV) + { + case UFormElm::ValueForm: + elmtType.append("_formValue"); break; + case UFormElm::ValueParentForm: + elmtType.append("_parentValue"); break; + case UFormElm::ValueDefaultDfn: + elmtType.append("_dfnValue"); break; + case UFormElm::ValueDefaultType: + elmtType.append("_typeValue"); break; + default: + elmtType.append("_noValue"); + } + + columnData << QString(elmName.c_str()) << QString(value.c_str()) << "";// << elmtType; + parent->appendChild(new CFormItem(elmt, columnData, parent, *whereV, *whereN)); + } + } + else + { + nlinfo("getNodeByName returned false"); + } + } + num++; + } + } + if (root->isArray()) + { + uint arraySize = 0; + root->getArraySize(arraySize); + while (num < arraySize) + { + std::string elmName; + if(root->getArrayNodeName(elmName, num)) + { + QList columnData; + std::string value; + QString elmtType = ""; + + UFormElm *elmt = 0; + if(root->getArrayNode(&elmt,0) && elmt) + { + if (elmt->isArray()) + elmtType = "Array"; + if (elmt->isStruct()) { + elmtType = "Struct"; + } + if (elmt->isAtom()) + { + elmt->getValue(value); + elmtType = "Atom"; + } + if (elmt->isVirtualStruct()) + elmtType = "VirtualStruct"; + + elmtType.append("_arrayValue"); + columnData << QString(elmName.c_str()) << QString(value.c_str()) << "";// << elmtType; + parent->appendChild(new CFormItem(elmt, columnData, parent)); + loadFormData(elmt, parent->child(parent->childCount()-1)); + } + } + num++; + } + } + } + + /******************************************************************************/ + + void CGeorgesFormModel::loadFormHeader() + { + + if (m_parents.size()) + { + CFormItem *fi_pars = new CFormItem(m_rootElm, QList() << "parents" << "" << "", m_rootItem); + m_rootItem->appendChild(fi_pars); + + Q_FOREACH(QString str, m_parents) + { + fi_pars->appendChild(new CFormItem(m_rootElm, QList() << str << "" << "", fi_pars)); + } + } + + /*QStringList dfns = _dependencies["dfn"]; + QStringList typs = _dependencies["typ"]; + + _dependencies.remove("dfn"); + _dependencies.remove("typ"); + + CFormItem *fi_dep = new CFormItem(_rootElm, QList() << "dependencies", _rootItem); + _rootItem->appendChild(fi_dep); + + if (!dfns.isEmpty()) { + CFormItem *fi_dfn = new CFormItem(_rootElm, QList() << "dfn", fi_dep); + fi_dep->appendChild(fi_dfn); + foreach(QString str, dfns) { + fi_dfn->appendChild(new CFormItem(_rootElm, QList() << str, fi_dfn)); + } + } + if (!typs.isEmpty()) { + CFormItem *fi_typ = new CFormItem(_rootElm, QList() << "typ", fi_dep); + fi_dep->appendChild(fi_typ); + foreach(QString str, typs) { + fi_typ->appendChild(new CFormItem(_rootElm, QList() << str, fi_typ)); + } + } + if (!_dependencies.isEmpty()) { + CFormItem *fi_other = new CFormItem(_rootElm, QList() << "other", fi_dep); + fi_dep->appendChild(fi_other); + foreach(QStringList list, _dependencies) { + foreach(QString str, list) { + fi_other->appendChild(new CFormItem(_rootElm, QList() << str, fi_other)); + } + } + }*/ + } + + /******************************************************************************/ + + void CGeorgesFormModel::setupModelData() + { + loadFormHeader(); + loadFormData(m_rootElm, m_rootItem); + } + + /******************************************************************************/ + + void CGeorgesFormModel::setShowParents( bool show ) { + m_showParents = show; + Q_EMIT layoutAboutToBeChanged(); + Q_EMIT layoutChanged(); + } + void CGeorgesFormModel::setShowDefaults( bool show ) + { + m_showDefaults = show; + Q_EMIT layoutAboutToBeChanged(); + Q_EMIT layoutChanged(); + } + + void CGeorgesFormModel::addParentForm(QString parentForm) + { + beginResetModel(); + m_parents.push_back(parentForm); + delete m_rootItem; + m_rootItem = new CFormItem(m_rootElm, m_rootData); + setupModelData(); + endResetModel(); + } + + void CGeorgesFormModel::removeParentForm(QString parentForm) + { + beginResetModel(); + m_parents.removeOne(parentForm); + + delete m_rootItem; + m_rootItem = new CFormItem(m_rootElm, m_rootData); + setupModelData(); + endResetModel(); + } +} /* namespace GeorgesQt */ + +/* end of file */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georgesform_model.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georgesform_model.h new file mode 100644 index 000000000..05fadc498 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georgesform_model.h @@ -0,0 +1,84 @@ +// Object Viewer Qt - Georges Editor Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef GEORGESFORM_MODEL_H +#define GEORGESFORM_MODEL_H + +// Qt includes +#include +#include +#include +#include + +// project includes + +namespace NLGEORGES { + class UFormElm; +} + +namespace GeorgesQt +{ + + class CFormItem; + + class CGeorgesFormModel : public QAbstractItemModel + { + + public: + CGeorgesFormModel(NLGEORGES::UFormElm *root, QMap< QString, QStringList> deps, + QString comment, QStringList parents, bool* expanded, QObject *parent = 0); + ~CGeorgesFormModel(); + + QVariant data(const QModelIndex &index, int role) const; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &index) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + CFormItem *getItem(const QModelIndex &index) const; + CGeorgesFormModel *model() { return this; } + bool showParents() { return m_showParents;} + bool showDefaults() { return m_showDefaults;} + void setShowParents( bool show ); + void setShowDefaults( bool show ); + void addParentForm(QString parentForm); + void removeParentForm(QString parentForm); + NLGEORGES::UFormElm *getRootForm() { return m_rootElm; } + + private: + void setupModelData(); + void loadFormData(NLGEORGES::UFormElm *rootElm, CFormItem *parent); + void loadFormHeader(); + + CFormItem* m_rootItem; + NLGEORGES::UFormElm* m_rootElm; + QList m_rootData; + QMap< QString, QStringList> m_dependencies; + QString m_comments; + QStringList m_parents; + QList* m_parentRows; + + bool m_showParents; + bool m_showDefaults; + bool *m_expanded; + + };/* class CGeorgesFormModel */ + +} /* namespace GeorgesQt */ + +#endif // GEORGESFORM_MODEL_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georgesform_proxy_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georgesform_proxy_model.cpp new file mode 100644 index 000000000..a99997925 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georgesform_proxy_model.cpp @@ -0,0 +1,81 @@ +// Object Viewer Qt - Georges Editor Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// NeL includes +#include +#include + +// project includes +#include "formitem.h" +#include "georgesform_proxy_model.h" +#include "georgesform_model.h" + +namespace GeorgesQt +{ + + bool CGeorgesFormProxyModel::filterAcceptsRow(int sourceRow, + const QModelIndex &sourceParent) const + { + // column doesnt matter for item + CGeorgesFormModel *smodel = dynamic_cast(sourceModel()); + QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); + CFormItem *item = smodel->getItem(index); + + // if elm not existing it must be some kind of default or type value + if(!item->getFormElm()) + { + return smodel->showDefaults(); + } + + // else it might be some parent elm + switch (item->nodeFrom()) + { + case NLGEORGES::UFormElm::NodeParentForm: + { + return smodel->showParents(); + } + case NLGEORGES::UFormElm::NodeForm: + { + switch (item->valueFrom()) + { + case NLGEORGES::UFormElm::ValueParentForm: + { + return smodel->showParents(); + } + default: + { + CFormItem *parent = item->parent(); + if (parent && (parent->nodeFrom() == NLGEORGES::UFormElm::NodeParentForm)) + { + return smodel->showParents(); + } + } + } + } + } + return true; + } + +/******************************************************************************/ + + bool CGeorgesFormProxyModel::filterAcceptsColumn(int sourceRow, + const QModelIndex &sourceParent) const + { + return QSortFilterProxyModel::filterAcceptsColumn(sourceRow, sourceParent); + } +} /* namespace GeorgesQt */ + +/* end of file */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georgesform_proxy_model.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georgesform_proxy_model.h new file mode 100644 index 000000000..73c384a99 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/georgesform_proxy_model.h @@ -0,0 +1,45 @@ +// Object Viewer Qt - Georges Editor Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef GEORGESFORM_PROXY_MODEL_H +#define GEORGESFORM_PROXY_MODEL_H + +// Qt includes +#include + +namespace GeorgesQt +{ + + class CGeorgesFormProxyModel : public QSortFilterProxyModel + { + + public: + CGeorgesFormProxyModel(QObject *parent = 0): QSortFilterProxyModel(parent) + { + } + ~CGeorgesFormProxyModel() + { + } + + protected: + virtual bool filterAcceptsColumn ( int source_column, const QModelIndex & source_parent ) const ; + virtual bool filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const ; + + };/* class CGeorgesFormProxyModel */ + +} /* namespace GeorgesQt */ + +#endif // GEORGESFORM_PROXY_MODEL_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/ovqt_plugin_georges_editor.xml b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/ovqt_plugin_georges_editor.xml new file mode 100644 index 000000000..2b9b163da --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/ovqt_plugin_georges_editor.xml @@ -0,0 +1,10 @@ + + ovqt_plugin_georges_editor + GeorgesEditor + 0.4 + aquiles + Tool to create and edit sheets or forms. + + + + \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp index 4b075adfc..0bb482c72 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -20,7 +20,6 @@ #include "landscape_editor_constants.h" #include "../core/icore.h" -#include "../core/imenu_manager.h" #include "../core/core_constants.h" // NeL includes @@ -72,7 +71,6 @@ void LandscapeEditorWindow::open() void LandscapeEditorWindow::createMenus() { - Core::IMenuManager *menuManager = Core::ICore::instance()->menuManager(); } void LandscapeEditorWindow::readSettings() diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_plugin.cpp index 2f88200ec..5a8c64f93 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_plugin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_plugin.cpp @@ -21,7 +21,7 @@ #include "../core/icore.h" #include "../core/core_constants.h" -#include "../core/imenu_manager.h" +#include "../core/menu_manager.h" #include "../../extension_system/iplugin_spec.h" // Qt includes @@ -68,7 +68,7 @@ namespace Plugin { Q_UNUSED(errorString); m_plugMan = pluginManager; - m_logSettingsPage = new CLogSettingsPage(this); + m_logSettingsPage = new CLogSettingsPage(this, this); addAutoReleasedObject(m_logSettingsPage); return true; } @@ -78,7 +78,7 @@ namespace Plugin setDisplayers(); Core::ICore *core = Core::ICore::instance(); - Core::IMenuManager *menuManager = core->menuManager(); + Core::MenuManager *menuManager = core->menuManager(); QMenu *viewMenu = menuManager->menu(Core::Constants::M_VIEW); QMainWindow *wnd = Core::ICore::instance()->mainWindow(); @@ -103,7 +103,7 @@ namespace Plugin QString CLogPlugin::name() const { - return "NeL Log"; + return "LogPlugin"; } QString CLogPlugin::version() const diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_settings_page.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_settings_page.cpp index f75d6ab37..3aba359a5 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_settings_page.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_settings_page.cpp @@ -38,8 +38,9 @@ namespace Plugin class CLogPlugin; - CLogSettingsPage::CLogSettingsPage(QObject *parent) + CLogSettingsPage::CLogSettingsPage(CLogPlugin *logPlugin, QObject *parent) : IOptionsPage(parent), + m_logPlugin(logPlugin), m_currentPage(NULL), m_error(true), m_warning(true), @@ -98,13 +99,7 @@ namespace Plugin m_info = m_ui.infoCheck->isChecked(); writeSettings(); - ExtensionSystem::IPluginManager *p = Core::ICore::instance()->pluginManager(); - ExtensionSystem::IPlugin *plugin = p->pluginByName("LogPlugin")->plugin(); - CLogPlugin* lp = dynamic_cast(plugin); - if (lp) - { - lp->setDisplayers(); - } + m_logPlugin->setDisplayers(); } void CLogSettingsPage::readSettings() diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_settings_page.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_settings_page.h index 2c0c5ed98..b8a5fd604 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_settings_page.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_settings_page.h @@ -29,6 +29,8 @@ class QWidget; namespace Plugin { + class CLogPlugin; + /** @class CLogSettingsPage */ @@ -36,7 +38,7 @@ namespace Plugin { Q_OBJECT public: - CLogSettingsPage(QObject *parent = 0); + CLogSettingsPage(CLogPlugin *logPlugin, QObject *parent = 0); virtual ~CLogSettingsPage() {} virtual QString id() const; @@ -53,6 +55,7 @@ namespace Plugin void readSettings(); void writeSettings(); + CLogPlugin *m_logPlugin; QWidget *m_currentPage; Ui::CLogSettingsPage m_ui; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/ovqt_plugin_log.xml b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/ovqt_plugin_log.xml new file mode 100644 index 000000000..f1fbd7ad0 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/ovqt_plugin_log.xml @@ -0,0 +1,10 @@ + + ovqt_plugin_log + LogPlugin + 1.1 + aquiles + DockWidget to display all log messages from NeL. + + + + \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/CMakeLists.txt new file mode 100644 index 000000000..f277a4b14 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/CMakeLists.txt @@ -0,0 +1,49 @@ +INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} + ${LIBXML2_INCLUDE_DIR} + ${QT_INCLUDES}) + +FILE(GLOB SRC *.cpp *.h) + +SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin.h + ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin_manager.h + ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin_spec.h) + +SET(OVQT_PLUG_MISSION_COMPILER_HDR mission_compiler_plugin.h + mission_compiler_main_window.h + mission_compiler_settings_page.h + server_entry_dialog.h) + +SET(OVQT_PLUG_MISSION_COMPILER_UIS mission_compiler_main_window.ui server_entry_dialog.ui mission_compiler_settings_page.ui) + +SET(OVQT_PLUG_MISSION_COMPILER_RCS mission_compiler.qrc) + +SET(QT_USE_QTGUI TRUE) + +QT4_WRAP_CPP(OVQT_PLUG_MISSION_COMPILER_MOC_SRC ${OVQT_PLUG_MISSION_COMPILER_HDR}) +QT4_ADD_RESOURCES( OVQT_PLUG_MISSION_COMPILER_RC_SRCS ${OVQT_PLUG_MISSION_COMPILER_RCS}) +QT4_WRAP_UI(OVQT_PLUG_MISSION_COMPILER_UI_HDRS ${OVQT_PLUG_MISSION_COMPILER_UIS}) + +SOURCE_GROUP(QtResources FILES ${OVQT_PLUG_MISSION_COMPILER_UIS} ${OVQT_PLUG_MISSION_COMPILER_RCS}) +SOURCE_GROUP(QtGeneratedUiHdr FILES ${OVQT_PLUG_MISSION_COMPILER_UI_HDRS}) +SOURCE_GROUP(QtGeneratedMocSrc FILES ${OVQT_PLUG_MISSION_COMPILER_MOC_SRC} ${OVQT_PLUG_MISSION_COMPILER_RC_SRCS}) +SOURCE_GROUP("Mission Compiler Plugin" FILES ${SRC}) +SOURCE_GROUP("OVQT Extension System" FILES ${OVQT_EXT_SYS_SRC}) + +# Mission Compiler Library +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/ryzom/tools/leveldesign/mission_compiler_lib) + +# Game Share Library +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/common/src) + +ADD_LIBRARY(ovqt_plugin_mission_compiler MODULE ${SRC} ${OVQT_PLUG_MISSION_COMPILER_MOC_SRC} ${OVQT_PLUG_MISSION_COMPILER_RC_SRCS} ${OVQT_EXT_SYS_SRC} ${OVQT_PLUG_MISSION_COMPILER_UI_HDRS}) + +TARGET_LINK_LIBRARIES(ovqt_plugin_mission_compiler ovqt_plugin_core nelmisc nelligo ryzom_mission_compiler_lib ${QT_LIBRARIES} ${QT_QTOPENGL_LIBRARY}) + +NL_DEFAULT_PROPS(ovqt_plugin_mission_compiler "NeL, Tools, 3D: Object Viewer Qt Plugin: Mission Compiler") +NL_ADD_RUNTIME_FLAGS(ovqt_plugin_mission_compiler) +NL_ADD_LIB_SUFFIX(ovqt_plugin_mission_compiler) + +ADD_DEFINITIONS(${LIBXML2_DEFINITIONS} -DQT_PLUGIN -DQT_SHARED ${QT_DEFINITIONS}) + +INSTALL(TARGETS ovqt_plugin_mission_compiler LIBRARY DESTINATION lib RUNTIME DESTINATION bin ARCHIVE DESTINATION lib COMPONENT tools3d) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/arrow-left-2.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/arrow-left-2.png new file mode 100644 index 000000000..8f153292c Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/arrow-left-2.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/arrow-left-double-2.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/arrow-left-double-2.png new file mode 100644 index 000000000..8b6d62c7a Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/arrow-left-double-2.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/arrow-right-2.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/arrow-right-2.png new file mode 100644 index 000000000..d4016e2c7 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/arrow-right-2.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/arrow-right-double-2.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/arrow-right-double-2.png new file mode 100644 index 000000000..1fe9feb28 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/arrow-right-double-2.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/document-export-4.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/document-export-4.png new file mode 100644 index 000000000..bc7688858 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/document-export-4.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/ic_nel_add_item.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/ic_nel_add_item.png new file mode 100644 index 000000000..bde338f78 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/ic_nel_add_item.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/ic_nel_delete_item.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/ic_nel_delete_item.png new file mode 100644 index 000000000..a5a1787d5 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/ic_nel_delete_item.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/ic_nel_down_item.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/ic_nel_down_item.png new file mode 100644 index 000000000..fc86c4f6d Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/ic_nel_down_item.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/ic_nel_generic_settings.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/ic_nel_generic_settings.png new file mode 100644 index 000000000..799bacb28 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/ic_nel_generic_settings.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/ic_nel_reset_all.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/ic_nel_reset_all.png new file mode 100644 index 000000000..aea193c70 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/ic_nel_reset_all.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/ic_nel_up_item.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/ic_nel_up_item.png new file mode 100644 index 000000000..ee471023e Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/ic_nel_up_item.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/news-subscribe-2.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/news-subscribe-2.png new file mode 100644 index 000000000..d5259a76b Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/news-subscribe-2.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/run-build-2.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/run-build-2.png new file mode 100644 index 000000000..5fea6c540 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/images/run-build-2.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler.qrc b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler.qrc new file mode 100644 index 000000000..eed07d969 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler.qrc @@ -0,0 +1,17 @@ + + + images/ic_nel_reset_all.png + images/ic_nel_add_item.png + images/ic_nel_delete_item.png + images/ic_nel_down_item.png + images/ic_nel_generic_settings.png + images/ic_nel_up_item.png + images/arrow-left-2.png + images/arrow-left-double-2.png + images/arrow-right-2.png + images/arrow-right-double-2.png + images/document-export-4.png + images/news-subscribe-2.png + images/run-build-2.png + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_main_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_main_window.cpp new file mode 100644 index 000000000..df909f31a --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_main_window.cpp @@ -0,0 +1,510 @@ +#include "mission_compiler_main_window.h" +#include "ui_mission_compiler_main_window.h" +#include "validation_file.h" +#include "mission_compiler.h" +#include "mission_compiler_plugin_constants.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../core/icore.h" +#include "../core/menu_manager.h" +#include "../core/core_constants.h" + +#include + +#include +#include +#include +#include + +#include + +using namespace MissionCompiler::Constants; + +MissionCompilerMainWindow::MissionCompilerMainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MissionCompilerMainWindow) +{ + ui->setupUi(this); + + m_lastDir = "."; + m_compileLog = ""; + updateCompileLog(); + + // Load the settings. + loadConfig(); + + m_undoStack = new QUndoStack(this); + + m_regexpFilter = new QRegExp(); + m_regexpFilter->setPatternSyntax(QRegExp::FixedString); + m_regexpFilter->setCaseSensitivity(Qt::CaseInsensitive); + + m_allPrimitivesModel = new QStringListModel(this); + m_filteredProxyModel = new QSortFilterProxyModel(this); + m_filteredProxyModel->setSourceModel(m_allPrimitivesModel); + m_filteredProxyModel->setDynamicSortFilter(true); + m_filteredProxyModel->setFilterRegExp(*m_regexpFilter); + ui->allPrimitivesList->setModel(m_filteredProxyModel); + m_selectedPrimitivesModel = new QStringListModel(this); + ui->selectedPrimitivesList->setModel(m_selectedPrimitivesModel); + + // Connections for toolbar buttons. + connect(ui->actionValidate, SIGNAL(triggered()), this, SLOT(handleValidation())); + connect(ui->actionCompile, SIGNAL(triggered()), this, SLOT(handleCompile())); + connect(ui->actionPublish, SIGNAL(triggered()), this, SLOT(handlePublish())); + + // Connections for selected item moves. + connect(ui->allPrimitivesList, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(handleAllDoubleClick(const QModelIndex &))); + connect(ui->selectedPrimitivesList, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(handleSelDoubleClick(const QModelIndex &))); + connect(ui->addSelectedButton, SIGNAL(clicked()), this, SLOT(handleMoveSelectedRight())); + connect(ui->removeSelectedButton, SIGNAL(clicked()), this, SLOT(handleMoveSelectedLeft())); + connect(ui->addAllButton, SIGNAL(clicked()), this, SLOT(handleMoveAllRight())); + connect(ui->removeAllButton, SIGNAL(clicked()), this, SLOT(handleMoveAllLeft())); + + // Connections for the filter group box. + connect(ui->dataDirButton, SIGNAL(clicked()), this, SLOT(handleDataDirButton())); + connect(ui->dataDirEdit, SIGNAL(textChanged(const QString &)), this, SLOT(handleDataDirChanged(const QString &))); + connect(ui->filterEdit, SIGNAL(textEdited(const QString&)), this, SLOT(handleFilterChanged(const QString&))); + connect(ui->resetFiltersButton, SIGNAL(clicked()), this, SLOT(handleResetFiltersButton())); + + // Connect for settings changes. + connect(Core::ICore::instance(), SIGNAL(changeSettings()), this, SLOT(handleChangedSettings())); + + // Set the default data dir to the primitives path. + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup(Core::Constants::DATA_PATH_SECTION); + m_lastDir = settings->value(Core::Constants::PRIMITIVES_PATH).toString(); + ui->dataDirEdit->setText(m_lastDir); + populateAllPrimitives(m_lastDir); + settings->endGroup(); + + NLLIGO::Register(); + // TODO try/catch exception. Crashes if path invalid. + m_ligoConfig.readPrimitiveClass(NLMISC::CPath::lookup("world_editor_classes.xml").c_str(), false); + NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig = &m_ligoConfig; +} + +void MissionCompilerMainWindow::populateAllPrimitives(const QString &dataDir) +{ + // First we need to clear out the models entirely. + QStringList emptyList; + m_selectedPrimitivesModel->setStringList(emptyList); + m_allPrimitivesModel->setStringList(emptyList); + + + // Populate the "all" primitives box. + QStringList list; + + // Filter for only primitive files. + QStringList filters; + filters << "*.primitive"; + + QDirIterator it(dataDir, filters, QDir::Files, QDirIterator::Subdirectories|QDirIterator::FollowSymlinks); + while(it.hasNext()) + { + it.next(); + list << it.fileName(); + } + + m_allPrimitivesModel->setStringList(list); +} + +void MissionCompilerMainWindow::handleResetFiltersButton() +{ + handleDataDirChanged(m_lastDir); + ui->filterEdit->setText(""); + handleFilterChanged(""); +} + +void MissionCompilerMainWindow::handleDataDirChanged(const QString &text) +{ + populateAllPrimitives(text); +} + +void MissionCompilerMainWindow::handleDataDirButton() +{ + QString newPath = QFileDialog::getExistingDirectory(this, "", m_lastDir); + if(!newPath.isEmpty()) + { + ui->dataDirEdit->setText(newPath); + m_lastDir = newPath; + populateAllPrimitives(newPath); + } +} + +void MissionCompilerMainWindow::handleFilterChanged(const QString &text) +{ + m_regexpFilter->setPattern(text); + m_filteredProxyModel->setFilterRegExp(*m_regexpFilter); +} + +void MissionCompilerMainWindow::handleCompile() +{ + compileMission(); +} + +void MissionCompilerMainWindow::handlePublish() +{ + compileMission(true); +} + +void MissionCompilerMainWindow::handleMoveSelectedRight() +{ + QModelIndexList indexes = ui->allPrimitivesList->selectionModel()->selectedIndexes(); + while(!indexes.isEmpty()) + { + const QModelIndex index = indexes.takeFirst(); + moveSelectedItem(index, m_allPrimitivesModel, m_selectedPrimitivesModel); + indexes = ui->allPrimitivesList->selectionModel()->selectedIndexes(); + } +} + +void MissionCompilerMainWindow::handleMoveAllRight() +{ + ui->allPrimitivesList->selectAll(); + handleMoveSelectedRight(); +} + +void MissionCompilerMainWindow::handleMoveSelectedLeft() +{ + QModelIndexList indexes = ui->selectedPrimitivesList->selectionModel()->selectedIndexes(); + while(!indexes.isEmpty()) + { + const QModelIndex index = indexes.takeFirst(); + moveSelectedItem(index, m_selectedPrimitivesModel, m_allPrimitivesModel); + indexes = ui->selectedPrimitivesList->selectionModel()->selectedIndexes(); + } +} + +void MissionCompilerMainWindow::handleMoveAllLeft() +{ + ui->selectedPrimitivesList->selectAll(); + handleMoveSelectedLeft(); +} + +void MissionCompilerMainWindow::moveSelectedItem(const QModelIndex &index, QStringListModel *from, QStringListModel *to) +{ + QString item = from->data(index, Qt::DisplayRole).toString(); + + from->removeRows(index.row(),1); + QStringList list = to->stringList(); + list << item; + to->setStringList(list); +} + +void MissionCompilerMainWindow::handleAllDoubleClick(const QModelIndex &index) +{ + moveSelectedItem(index, m_allPrimitivesModel, m_selectedPrimitivesModel); +} + +void MissionCompilerMainWindow::handleSelDoubleClick(const QModelIndex &index) +{ + moveSelectedItem(index, m_selectedPrimitivesModel, m_allPrimitivesModel); +} + +void MissionCompilerMainWindow::compileMission(bool publish) +{ + uint nbMission = 0; + + // First switch toolbox pages to show the compilation output. + ui->toolBox->setCurrentIndex(2); + + m_compileLog.append("Begin mission compilation.\n"); + updateCompileLog(); + + // Go through each file. + QStringList list = m_selectedPrimitivesModel->stringList(); + QStringListIterator itr(list); + while(itr.hasNext()) + { + QString filename = itr.next(); + m_compileLog.append("Compiling '"+filename+"'...\n"); + updateCompileLog(); + + NLLIGO::CPrimitives primDoc; + NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = &primDoc; + NLLIGO::loadXmlPrimitiveFile(primDoc, NLMISC::CPath::lookup(filename.toAscii().data(), false), m_ligoConfig); + NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL; + + try + { + CMissionCompiler mc; + mc.compileMissions(primDoc.RootNode, filename.toStdString()); + m_compileLog.append("Found "+QString::number(mc.getMissionsCount())+" valid missions\n"); + updateCompileLog(); + + mc.installCompiledMission(m_ligoConfig, filename.toStdString()); + nbMission += mc.getMissionsCount(); + + // publish files to selected servers + if (publish) + { + m_compileLog.append("Begin publishing missions...\n"); + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup(MISSION_COMPILER_SECTION); + + // Retrieve the local text path. + QString localPath = settings->value(SETTING_LOCAL_TEXT_PATH).toString(); + settings->endGroup(); + QStringList checkedServers; + for(int i = 0; ipublishServersList->count(); i++) + { + + // Retrieve each checked server. + QListWidgetItem *item = ui->publishServersList->item(i); + if(item->checkState() == Qt::Checked) + checkedServers << item->text(); + } + + Q_FOREACH(QString checkedServer, checkedServers) + { + m_compileLog.append("Processing publication configuration for '"+checkedServer+"'\n"); + QStringList items = settings->value(SETTING_SERVERS_TABLE_ITEMS).toStringList(); + int column = 0; + int row = 0; + QString servName; + QString primPath; + QString textPath; + Q_FOREACH(QString var, items) + { + // Check to see if we're starting a new row. + if(column > 2) + { + column = 0; + row++; + } + if(column == 0) + servName = var; + else if(column == 1) + textPath = var; + else if(column == 2) + { + primPath = var; + + m_compileLog.append("Publishing to "+servName+" ...\n"); + for (uint j=0 ; jtoolBox->setCurrentIndex(2); + + m_compileLog.append("Begin mission validation.\n"); + updateCompileLog(); + + // Load existing validation + CValidationFile validation; + validation.loadMissionValidationFile("mission_validation.cfg"); + + // Go through each file. + QStringList list = m_selectedPrimitivesModel->stringList(); + QStringListIterator itr(list); + while(itr.hasNext()) + { + QString filename = itr.next(); + m_compileLog.append("Parsing '"+filename+"'...\n"); + updateCompileLog(); + + TMissionContainer missions; + NLLIGO::CPrimitives primDoc; + NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = &primDoc; + NLLIGO::loadXmlPrimitiveFile(primDoc, NLMISC::CPath::lookup(filename.toAscii().data(), false), m_ligoConfig); + parsePrimForMissions(primDoc.RootNode, missions); + + // Parse missions to check modification + std::map::iterator itMission, itMissionEnd = missions.end(); + for (itMission=missions.begin(); itMission!=itMissionEnd; ++itMission) + { + CValidationFile::TMissionStateContainer::iterator itMissionValidation = validation._MissionStates.find(itMission->first); + if (itMissionValidation!=validation._MissionStates.end()) + { + // Mission already registered, check hash key + if (itMissionValidation->second.hashKey!=itMission->second.hashKey) + { + itMissionValidation->second.hashKey = itMission->second.hashKey; + itMissionValidation->second.state = validation.defaultState(); + } + } + else + { + // New mission + validation.insertMission(itMission->first, itMission->second.hashKey); + } + m_compileLog.append("Mission: '"+QString(itMission->first.c_str())+"->"+QString(itMission->second.hashKey.c_str())+"\n"); + updateCompileLog(); + } + } + validation.saveMissionValidationFile("mission_validation.cfg"); + + m_compileLog.append("Validation finished"); + updateCompileLog(); +} + +bool MissionCompilerMainWindow::parsePrimForMissions(NLLIGO::IPrimitive const *prim, TMissionContainer &missions) +{ + std::string value; + // if the node is a mission parse it + if (prim->getPropertyByName("class",value) && !NLMISC::stricmp(value.c_str(),"mission") ) + { + std::string name; + prim->getPropertyByName("name",name); + + m_compileLog.append(" ** Parsing mission '"+QString(name.c_str())+"'\n"); + updateCompileLog(); + + // parse the mission and put it in our manager + CMission mission(value, ""); + if (!mission.parsePrim(prim) ) + { + m_compileLog.append(" ** Previous errors in mission '"+QString(name.c_str())+"'"); + updateCompileLog(); + return false; + } + missions.insert(make_pair(name, mission)); + return true; + } + else + { + //this is not a mission node, so lookup recursively in the children + bool ok = true; + for (uint i=0;igetNumChildren();++i) + { + const NLLIGO::IPrimitive *child; + if ( !prim->getChild(child,i) || !parsePrimForMissions(child, missions) ) + ok = false; + } + return ok; + } +} + +void MissionCompilerMainWindow::updateCompileLog() +{ + ui->compileOutputText->setPlainText(m_compileLog); + QCoreApplication::processEvents(); +} + +void MissionCompilerMainWindow::loadConfig() { + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup(MISSION_COMPILER_SECTION); + + // Retrieve the local text path. + QString localPath = settings->value(SETTING_LOCAL_TEXT_PATH).toString(); + QListWidgetItem *item = new QListWidgetItem("Local"); + item->setForeground(Qt::blue); + item->setCheckState(Qt::Unchecked); + ui->publishServersList->addItem(item); + + QStringList items = settings->value(SETTING_SERVERS_TABLE_ITEMS).toStringList(); + int column = 0; + int row = 0; + Q_FOREACH(QString var, items) + { + // Check to see if we're starting a new row. + if(column > 2) + { + column = 0; + row++; + } + if(column == 0) + { + item = new QListWidgetItem(var); + item->setCheckState(Qt::Unchecked); + ui->publishServersList->addItem(item); + } + + column++; + } + + // Reapply the checkboxes for servers we had checked previously. + QStringList servers = settings->value(SETTING_PUBLISH_SERVER_CHECKS).toStringList(); + applyCheckboxes(servers); + + settings->endGroup(); +} + +void MissionCompilerMainWindow::saveConfig() { + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup(MISSION_COMPILER_SECTION); + + QStringList servers; + for(int row = 0; row < ui->publishServersList->count(); row++) + { + QListWidgetItem *item = ui->publishServersList->item(row); + if(item->checkState() == Qt::Checked) + servers << item->text(); + } + + settings->setValue(SETTING_PUBLISH_SERVER_CHECKS, servers); + + settings->endGroup(); + settings->sync(); +} + +void MissionCompilerMainWindow::handleChangedSettings() +{ + QStringList servers; + for(int row = 0; row < ui->publishServersList->count(); row++) + { + QListWidgetItem *item = ui->publishServersList->item(row); + if(item->checkState() == Qt::Checked) + servers << item->text(); + } + ui->publishServersList->clear(); + loadConfig(); + + applyCheckboxes(servers); +} + +void MissionCompilerMainWindow::applyCheckboxes(const QStringList &servers) +{ + Q_FOREACH(QString server, servers) + { + QList items = ui->publishServersList->findItems(server, Qt::MatchExactly); + if(items.size() != 1) + continue; + items.at(0)->setCheckState(Qt::Checked); + } +} + +MissionCompilerMainWindow::~MissionCompilerMainWindow() +{ + saveConfig(); + delete ui; +} diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_main_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_main_window.h new file mode 100644 index 000000000..1dffea313 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_main_window.h @@ -0,0 +1,75 @@ +#ifndef MISSION_COMPILER_MAIN_WINDOW_H +#define MISSION_COMPILER_MAIN_WINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace Ui { + class MissionCompilerMainWindow; +} + +struct CMission; + +class MissionCompilerMainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MissionCompilerMainWindow(QWidget *parent = 0); + ~MissionCompilerMainWindow(); + + void loadConfig(); + void saveConfig(); + QUndoStack *getUndoStack() { return m_undoStack; } + + typedef std::map TMissionContainer; + +public Q_SLOTS: + void handleFilterChanged(const QString &text); + void handleValidation(); + void handleCompile(); + void handlePublish(); + void handleAllDoubleClick(const QModelIndex &index); + void handleSelDoubleClick(const QModelIndex &index); + void handleMoveSelectedRight(); + void handleMoveSelectedLeft(); + void handleMoveAllRight(); + void handleMoveAllLeft(); + void handleDataDirButton(); + void handleDataDirChanged(const QString &text); + void handleResetFiltersButton(); + void handleChangedSettings(); + +private: + Ui::MissionCompilerMainWindow *ui; + + void updateCompileLog(); + void populateAllPrimitives(const QString &dataDir = QString()); + bool parsePrimForMissions(NLLIGO::IPrimitive const *prim, TMissionContainer &missions); + void compileMission(bool publish=false); + void moveSelectedItem(const QModelIndex &index, QStringListModel *from, QStringListModel *to); + void applyCheckboxes(const QStringList &servers); + + + QMenu *_toolModeMenu; + QUndoStack *m_undoStack; + QStringListModel *m_allPrimitivesModel; + QStringListModel *m_selectedPrimitivesModel; + QSortFilterProxyModel *m_filteredProxyModel; + QRegExp *m_regexpFilter; + QString m_compileLog; + QString m_lastDir; + + NLLIGO::CLigoConfig m_ligoConfig; +}; + +#endif // MISSION_COMPILER_MAIN_WINDOW_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_main_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_main_window.ui new file mode 100644 index 000000000..dace315ab --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_main_window.ui @@ -0,0 +1,374 @@ + + + MissionCompilerMainWindow + + + + 0 + 0 + 794 + 600 + + + + MainWindow + + + + + + + 0 + + + + + 0 + 0 + 776 + 426 + + + + Mission Compiler Options + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Add Selected + + + + + + + :/buttons/images/arrow-right-2.png:/buttons/images/arrow-right-2.png + + + + + + + Add All + + + + + + + :/buttons/images/arrow-right-double-2.png:/buttons/images/arrow-right-double-2.png + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Remove All + + + + + + + :/buttons/images/arrow-left-double-2.png:/buttons/images/arrow-left-double-2.png + + + + + + + Remove Selected + + + + + + + :/buttons/images/arrow-left-2.png:/buttons/images/arrow-left-2.png + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + true + + + QAbstractItemView::NoEditTriggers + + + true + + + QAbstractItemView::DragDrop + + + Qt::MoveAction + + + true + + + QAbstractItemView::ExtendedSelection + + + + + + + true + + + QAbstractItemView::NoEditTriggers + + + true + + + QAbstractItemView::DragDrop + + + Qt::MoveAction + + + true + + + QAbstractItemView::ExtendedSelection + + + + + + + All Primitives + + + + + + + Selected Primitives + + + + + + + Filter Criteria + + + + + + + + Data Directory + + + + + + + + + + ... + + + + + + + + + + + Filter + + + + + + + + + + + + Blanks out the filter and reloads all files from the data directory. + + + Reset + + + + + + + horizontalLayoutWidget + dataDirLabel + horizontalLayoutWidget + + + + + + + + + 0 + 0 + 776 + 426 + + + + Publish Options + + + + + + + + + + + 0 + 0 + 776 + 426 + + + + Compilation Output + + + + + + true + + + + + + + + + + + + + 0 + 0 + 794 + 21 + + + + + + + toolBar + + + TopToolBarArea + + + false + + + + + + + + + :/buttons/images/run-build-2.png:/buttons/images/run-build-2.png + + + Compile + + + Compile + + + + + + :/buttons/images/news-subscribe-2.png:/buttons/images/news-subscribe-2.png + + + Validate + + + Validate + + + + + + :/buttons/images/document-export-4.png:/buttons/images/document-export-4.png + + + Publish + + + Compile and Publish + + + + + + + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_plugin.cpp new file mode 100644 index 000000000..9e92cb90c --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_plugin.cpp @@ -0,0 +1,76 @@ +// Project includes +#include "mission_compiler_plugin.h" +#include "../core/icore.h" +#include "../core/core_constants.h" +#include "../core/menu_manager.h" +#include "../../extension_system/iplugin_spec.h" + +// NeL includes +#include +#include + +// Qt includes +#include +#include +#include +#include +#include +#include + +#include "mission_compiler_settings_page.h" + +namespace MissionCompiler +{ + +MissionCompilerPlugin::~MissionCompilerPlugin() +{ + Q_FOREACH(QObject *obj, m_autoReleaseObjects) + { + m_plugMan->removeObject(obj); + } + qDeleteAll(m_autoReleaseObjects); + m_autoReleaseObjects.clear(); +} + +bool MissionCompilerPlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString) +{ + Q_UNUSED(errorString); + m_plugMan = pluginManager; + + addAutoReleasedObject(new MissionCompilerSettingsPage(this)); + addAutoReleasedObject(new CMissionCompilerContext(this)); + //addAutoReleasedObject(new CCoreListener(this)); + return true; +} + +void MissionCompilerPlugin::extensionsInitialized() +{ + Core::ICore *core = Core::ICore::instance(); + QSettings *settings = Core::ICore::instance()->settings(); + Core::MenuManager *menuManager = core->menuManager(); + + // Initialize Ligo. + //settings->beginGroup(Core::Constants::DATA_PATH_SECTION); + //QString ligoConfigFile = settings->value(Core::Constants::DATA_PATH_SECTION).toString(); + //settings->beginGroup(Core::Constants::DATA_PATH_SECTION); +} + +void MissionCompilerPlugin::setNelContext(NLMISC::INelContext *nelContext) +{ +#ifdef NL_OS_WINDOWS + // Ensure that a context doesn't exist yet. + // This only applies to platforms without PIC, e.g. Windows. + nlassert(!NLMISC::INelContext::isContextInitialised()); +#endif // NL_OS_WINDOWS + m_LibContext = new NLMISC::CLibraryContext(*nelContext); +} + +void MissionCompilerPlugin::addAutoReleasedObject(QObject *obj) +{ + m_plugMan->addObject(obj); + m_autoReleaseObjects.prepend(obj); +} + +} + +Q_EXPORT_PLUGIN(MissionCompiler::MissionCompilerPlugin) \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_plugin.h new file mode 100644 index 000000000..2ad92b40f --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_plugin.h @@ -0,0 +1,91 @@ +#ifndef MISSION_COMPILER_PLUGIN_H +#define MISSION_COMPILER_PLUGIN_H + +// Project includes +#include "../../extension_system/iplugin.h" +#include "../core/icontext.h" +#include "mission_compiler_main_window.h" + +// NeL includes +#include +#include + +// Qt includes +#include +#include + +namespace NLMISC +{ +class CLibraryContext; +} + +namespace ExtensionSystem +{ +class IPluginSpec; +} + +namespace MissionCompiler +{ + +class MissionCompilerPlugin : public QObject, public ExtensionSystem::IPlugin +{ + Q_OBJECT + Q_INTERFACES(ExtensionSystem::IPlugin) +public: + + virtual ~MissionCompilerPlugin(); + + bool initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString); + void extensionsInitialized(); + void setNelContext(NLMISC::INelContext *nelContext); + + void addAutoReleasedObject(QObject *obj); + +protected: + NLMISC::CLibraryContext *m_LibContext; + +private: + ExtensionSystem::IPluginManager *m_plugMan; + QList m_autoReleaseObjects; +}; + +class CMissionCompilerContext: public Core::IContext +{ + Q_OBJECT +public: + CMissionCompilerContext(QObject *parent = 0): IContext(parent) + { + m_missionCompilerMainWindow = new MissionCompilerMainWindow(); + } + virtual ~CMissionCompilerContext() {} + + virtual QString id() const + { + return QLatin1String("MissionCompilerContext"); + } + virtual QString trName() const + { + return tr("Mission Compiler"); + } + virtual QIcon icon() const + { + return QIcon(); + } + virtual QWidget *widget() + { + return m_missionCompilerMainWindow; + } + + virtual QUndoStack *undoStack() + { + return m_missionCompilerMainWindow->getUndoStack(); + } + virtual void open() {} + + + MissionCompilerMainWindow *m_missionCompilerMainWindow; +}; + +} // namespace MissionCompiler + +#endif // MISSION_COMPILER_PLUGIN_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_plugin_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_plugin_constants.h new file mode 100644 index 000000000..bfa71ceb1 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_plugin_constants.h @@ -0,0 +1,17 @@ +#ifndef MISSION_COMPILER_PLUGIN_CONSTANTS_H +#define MISSION_COMPILER_PLUGIN_CONSTANTS_H + +namespace MissionCompiler +{ +namespace Constants +{ +//settings +const char * const MISSION_COMPILER_SECTION = "MissionCompiler"; +const char * const SETTING_LOCAL_TEXT_PATH = "LocalTextPath"; +const char * const SETTING_SERVERS_TABLE_ITEMS = "ServersTableItems"; +const char * const SETTING_PUBLISH_SERVER_CHECKS = "PublishServerChecks"; + +} // namespace Constants +} // namespace MissionCompiler + +#endif // MISSION_COMPILER_PLUGIN_CONSTANTS_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_settings_page.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_settings_page.cpp new file mode 100644 index 000000000..2f75aa4ab --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_settings_page.cpp @@ -0,0 +1,203 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Project includes +#include "mission_compiler_settings_page.h" +#include "mission_compiler_plugin_constants.h" +#include "../core/core_constants.h" +#include "../core/icore.h" + +#include "server_entry_dialog.h" + +// NeL includes +#include + +// Qt includes +#include +#include +#include +#include + +namespace MissionCompiler +{ + +QString lastDir = "."; + +MissionCompilerSettingsPage::MissionCompilerSettingsPage(QObject *parent) + : IOptionsPage(parent), + m_page(0) +{ +} + +MissionCompilerSettingsPage::~MissionCompilerSettingsPage() +{ +} + +QString MissionCompilerSettingsPage::id() const +{ + return QLatin1String("mission_compiler_settings"); +} + +QString MissionCompilerSettingsPage::trName() const +{ + return tr("Mission Compiler Settings"); +} + +QString MissionCompilerSettingsPage::category() const +{ + return QLatin1String("Mission Compiler"); +} + +QString MissionCompilerSettingsPage::trCategory() const +{ + return tr("Mission Compiler"); +} + +QIcon MissionCompilerSettingsPage::categoryIcon() const +{ + return QIcon(); +} + +QWidget *MissionCompilerSettingsPage::createPage(QWidget *parent) +{ + m_page = new QWidget(parent); + m_ui.setupUi(m_page); + + readSettings(); + connect(m_ui.addToolButton, SIGNAL(clicked()), this, SLOT(addServer())); + connect(m_ui.removeToolButton, SIGNAL(clicked()), this, SLOT(delServer())); + connect(m_ui.serversTableWidget, SIGNAL(cellDoubleClicked(int,int)), this, SLOT(editServer(int,int))); + return m_page; +} + +void MissionCompilerSettingsPage::apply() +{ + writeSettings(); +} + +void MissionCompilerSettingsPage::finish() +{ + delete m_page; + m_page = 0; +} + +void MissionCompilerSettingsPage::editServer(int row, int column) +{ + ServerEntryDialog serverEntryDialog; + serverEntryDialog.setModal(true); + serverEntryDialog.show(); + + // Copy the values from the row to the dialog. + QTableWidgetItem *item1 = m_ui.serversTableWidget->item(row,0); + QTableWidgetItem *item2 = m_ui.serversTableWidget->item(row,1); + QTableWidgetItem *item3 = m_ui.serversTableWidget->item(row,2); + serverEntryDialog.setServerName(item1->text()); + serverEntryDialog.setTextPath(item2->text()); + serverEntryDialog.setPrimPath(item3->text()); + + if(serverEntryDialog.exec()) + { + item1->setText(serverEntryDialog.getServerName()); + item2->setText(serverEntryDialog.getTextPath()); + item3->setText(serverEntryDialog.getPrimPath()); + } +} + +void MissionCompilerSettingsPage::addServer() +{ + ServerEntryDialog serverEntryDialog; + serverEntryDialog.setModal(true); + serverEntryDialog.show(); + + + if(serverEntryDialog.exec()) + { + int row = m_ui.serversTableWidget->rowCount(); + m_ui.serversTableWidget->insertRow(row); + QTableWidgetItem *item1 = new QTableWidgetItem(serverEntryDialog.getServerName()); + QTableWidgetItem *item2 = new QTableWidgetItem(serverEntryDialog.getTextPath()); + QTableWidgetItem *item3 = new QTableWidgetItem(serverEntryDialog.getPrimPath()); + + m_ui.serversTableWidget->setItem(row, 0, item1); + m_ui.serversTableWidget->setItem(row, 1, item2); + m_ui.serversTableWidget->setItem(row, 2, item3); + } +} + +void MissionCompilerSettingsPage::delServer() +{ + QList selectedItems = m_ui.serversTableWidget->selectedItems(); + while(selectedItems.size() > 0) + { + m_ui.serversTableWidget->removeRow(selectedItems.back()->row()); + selectedItems = m_ui.serversTableWidget->selectedItems(); + } +} + +void MissionCompilerSettingsPage::readSettings() +{ + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup(Constants::MISSION_COMPILER_SECTION); + + // Retrieve the local text path. + m_ui.localPathEdit->setText(settings->value(Constants::SETTING_LOCAL_TEXT_PATH).toString()); + + QStringList items = settings->value(Constants::SETTING_SERVERS_TABLE_ITEMS).toStringList(); + int column = 0; + int row = 0; + m_ui.serversTableWidget->insertRow(row); + Q_FOREACH(QString var, items) + { + // Check to see if we're starting a new row. + if(column > 2) + { + column = 0; + row++; + m_ui.serversTableWidget->insertRow(row); + } + + QTableWidgetItem *item = new QTableWidgetItem(var); + m_ui.serversTableWidget->setItem(row, column, item); + + column++; + } + settings->endGroup(); +} + +void MissionCompilerSettingsPage::writeSettings() +{ + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup(Constants::MISSION_COMPILER_SECTION); + + // Save the local text path. + settings->setValue(Constants::SETTING_LOCAL_TEXT_PATH, m_ui.localPathEdit->text()); + + QStringList items; + for(int row = 0; row < m_ui.serversTableWidget->rowCount(); row++) + { + for(int column = 0; column < m_ui.serversTableWidget->columnCount(); column++) + { + items << m_ui.serversTableWidget->item(row, column)->text(); + } + } + + settings->setValue(Constants::SETTING_SERVERS_TABLE_ITEMS, items); + settings->endGroup(); + settings->sync(); +} + +} /* namespace MissionCompiler */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_settings_page.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_settings_page.h new file mode 100644 index 000000000..71996e442 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_settings_page.h @@ -0,0 +1,68 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#ifndef MISSION_COMPILER_SETTINGS_PAGE_H +#define MISSION_COMPILER_SETTINGS_PAGE_H + +#include + +#include "../core/ioptions_page.h" + +#include "ui_mission_compiler_settings_page.h" + +class QWidget; + +namespace MissionCompiler +{ +/** +@class MissionCompilerSettingsPage +*/ +class MissionCompilerSettingsPage : public Core::IOptionsPage +{ + Q_OBJECT + +public: + MissionCompilerSettingsPage(QObject *parent = 0); + ~MissionCompilerSettingsPage(); + + QString id() const; + QString trName() const; + QString category() const; + QString trCategory() const; + QIcon categoryIcon() const; + QWidget *createPage(QWidget *parent); + + void apply(); + void finish(); + +private Q_SLOTS: + void addServer(); + void delServer(); + void editServer(int row, int column); + +private: + void readSettings(); + void writeSettings(); + + QWidget *m_page; + Ui::MissionCompilerSettingsPage m_ui; +}; + +} // namespace MissionCompiler + +#endif // MISSION_COMPILER_SETTINGS_PAGE_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_settings_page.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_settings_page.ui new file mode 100644 index 000000000..2ee2c2bce --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_settings_page.ui @@ -0,0 +1,210 @@ + + + MissionCompilerSettingsPage + + + + 0 + 0 + 496 + 544 + + + + Form + + + + 6 + + + 3 + + + + + Publication Servers + + + + + + + + + 0 + 0 + + + + Delete + + + + + + + :/buttons/images/ic_nel_delete_item.png:/buttons/images/ic_nel_delete_item.png + + + + 20 + 20 + + + + true + + + + + + + + 0 + 0 + + + + Add + + + + + + + :/buttons/images/ic_nel_add_item.png:/buttons/images/ic_nel_add_item.png + + + + 20 + 20 + + + + true + + + + + + + Reset + + + + + + + :/buttons/images/ic_nel_reset_all.png:/buttons/images/ic_nel_reset_all.png + + + + 20 + 20 + + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QAbstractItemView::NoEditTriggers + + + true + + + 100 + + + true + + + + Server Name + + + + + Server Text Path + + + + + Server Primitive Path + + + + + + + + + + + General Settings + + + + + + Local Text Path + + + + + + + Local path for compiled mission texts. + + + + + + + ... + + + + + + + + + + + + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/ovqt_plugin_mission_compiler.xml b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/ovqt_plugin_mission_compiler.xml new file mode 100644 index 000000000..f6ef5b5c6 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/ovqt_plugin_mission_compiler.xml @@ -0,0 +1,10 @@ + + ovqt_plugin_mission_compiler + MissionCompiler + 0.1 + Ryzom Core + Mission Compiler Plugin + + + + \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/server_entry_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/server_entry_dialog.cpp new file mode 100644 index 000000000..a9ef08f50 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/server_entry_dialog.cpp @@ -0,0 +1,89 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Project includes +#include "server_entry_dialog.h" + +#include "ui_server_entry_dialog.h" + +// NeL includes + +// Qt includes +#include + +namespace MissionCompiler +{ + +ServerEntryDialog::ServerEntryDialog(QWidget *parent) + : QDialog(parent), + m_ui(new Ui::ServerEntryDialog) +{ + m_ui->setupUi(this); + + connect(m_ui->serverTextPathButton, SIGNAL(clicked()), this, SLOT(lookupTextPath())); + connect(m_ui->serverPrimPathButton, SIGNAL(clicked()), this, SLOT(lookupPrimPath())); +} + +ServerEntryDialog::~ServerEntryDialog() +{ + delete m_ui; +} + +QString ServerEntryDialog::getServerName() +{ + return m_ui->serverNameEdit->text(); +} + +QString ServerEntryDialog::getTextPath() +{ + return m_ui->serverTextPathEdit->text(); +} + +QString ServerEntryDialog::getPrimPath() +{ + return m_ui->serverPrimPathEdit->text(); +} + +void ServerEntryDialog::setServerName(QString name) +{ + m_ui->serverNameEdit->setText(name); +} + +void ServerEntryDialog::setTextPath(QString path) +{ + m_ui->serverTextPathEdit->setText(path); +} + +void ServerEntryDialog::setPrimPath(QString path) +{ + m_ui->serverPrimPathEdit->setText(path); +} + +void ServerEntryDialog::lookupTextPath() +{ + QString curPath = m_ui->serverTextPathEdit->text(); + QString path = QFileDialog::getExistingDirectory(this, "", curPath); + m_ui->serverTextPathEdit->setText(path); +} + +void ServerEntryDialog::lookupPrimPath() +{ + QString curPath = m_ui->serverPrimPathEdit->text(); + QString path = QFileDialog::getExistingDirectory(this, "", curPath); + m_ui->serverPrimPathEdit->setText(path); +} +} /* namespace MissionCompiler */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/server_entry_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/server_entry_dialog.h new file mode 100644 index 000000000..98a086cd0 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/server_entry_dialog.h @@ -0,0 +1,59 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#ifndef SERVER_ENTRY_DIALOG_H +#define SERVER_ENTRY_DIALOG_H + +#include + +namespace Ui { + class ServerEntryDialog; +} + +namespace MissionCompiler +{ +/** +@class ServerEntryDialog +*/ +class ServerEntryDialog : public QDialog +{ + Q_OBJECT + +public: + explicit ServerEntryDialog(QWidget *parent = 0); + ~ServerEntryDialog(); + + QString getServerName(); + QString getTextPath(); + QString getPrimPath(); + + void setServerName(QString name); + void setTextPath(QString path); + void setPrimPath(QString path); + +public Q_SLOTS: + void lookupTextPath(); + void lookupPrimPath(); + +private: + Ui::ServerEntryDialog *m_ui; +}; + +} // namespace MissionCompiler + +#endif // SERVER_ENTRY_DIALOG_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/server_entry_dialog.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/server_entry_dialog.ui new file mode 100644 index 000000000..002af82eb --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/server_entry_dialog.ui @@ -0,0 +1,130 @@ + + + ServerEntryDialog + + + + 0 + 0 + 488 + 175 + + + + Dialog + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + Server Settings + + + + + + Server Name + + + + + + + + + + Server Text Path + + + + + + + + + + ... + + + + + + + Server Primitive Path + + + + + + + + + + ... + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + buttonBox + accepted() + ServerEntryDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + ServerEntryDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/validation_file.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/validation_file.cpp new file mode 100644 index 000000000..3e166da6b --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/validation_file.cpp @@ -0,0 +1,133 @@ +#include "validation_file.h" + +#include +#include + +void CValidationFile::loadMissionValidationFile(std::string filename) +{ + // load the configuration file + NLMISC::CConfigFile cf; + std::string pathName = NLMISC::CPath::lookup(filename, false); + + if (pathName.empty()) + { + nlwarning("Can't find index file '%s' in search path, no mission will be valid", filename.c_str()); + return; + } + cf.load(pathName); + + // get the variable + NLMISC::CConfigFile::CVar* var = cf.getVarPtr("AuthorizedStates"); + if (var) + { + for (uint i=0; isize(); ++i) + _AuthorizedStates.push_back(var->asString(i)); + } + int missionStatesFields = 3; + var = cf.getVarPtr("MissionStatesFields"); + if (var) + missionStatesFields = var->asInt(); + else + nlwarning("Mission validation file does not contain MissionStatesFields variable. Parsing may fail and corrupt data."); + + var = cf.getVarPtr("MissionStates"); + if (var) + { + for (uint i=0; isize()/missionStatesFields; ++i) + { + std::string mission = var->asString(i*missionStatesFields); + std::string stateName = var->asString(i*missionStatesFields+1); + std::string hashKey = var->asString(i*missionStatesFields+2); + _MissionStates.insert(std::make_pair(mission, CMissionState(mission, stateName, hashKey))); + } + } +} + +void CValidationFile::saveMissionValidationFile(std::string filename) +{ + // load the configuration file + std::string pathName = NLMISC::CPath::lookup(filename, false); + + if (pathName.empty()) + { + nlwarning("Can't find index file '%s' in search path, no mission will be valid", filename.c_str()); + return; + } + FILE* file = fopen(pathName.c_str(), "w"); + nlassert(file!=NULL); + + // AuthorizedStates + fprintf(file, "%s", + "// AuthorizedStates contains the list of authorized states. EGS mission\n" + "// manager can accept any number of states. Default state is the first one.\n" + "AuthorizedStates = {\n"); + std::deque::iterator itAuth, itAuthEnd = _AuthorizedStates.end(); + for (itAuth=_AuthorizedStates.begin(); itAuth!=itAuthEnd; ++itAuth) + fprintf(file, "\t\"%s\",\n", itAuth->c_str()); + fprintf(file, "%s", "};\n\n"); + + // MissionStatesFields + fprintf(file, "%s", + "// MissionStatesFields contains the number of fields in MissionStates, for\n" + "// future compatibility purpose.\n" + "MissionStatesFields = "); + fprintf(file, "%d", 3); // 3 fields: name, state, hash key + fprintf(file, "%s", ";\n\n"); + + // MissionStates + fprintf(file, "%s", + "// MissionStates contains a list of mission with for each the state of the\n" + "// mission and its hash key. The tool will add new missions with the default\n" + "// state. It will flag missions with a modified hash key with default state to\n" + "// prevent untested modified missions to be published.\n" + "// :NOTE: You can add a field to this structure without the need to modify EGS\n" + "// code. Simply update MissionStatesFields.\n" + "MissionStates = {\n"); + TMissionStateContainer::iterator itMission, itMissionEnd = _MissionStates.end(); + for (itMission=_MissionStates.begin(); itMission!=itMissionEnd; ++itMission) + fprintf(file, "\t%-42s %-12s \"%s\",\n", ("\""+itMission->second.name+"\",").c_str(), ("\""+itMission->second.state+"\",").c_str(), itMission->second.hashKey.c_str()); + fprintf(file, "};\n\n"); + + fclose(file); +} + +// :NOTE: This function exists in mission_template.cpp. If you change it here modify the other file. +std::string buildHashKey(std::string const& content) +{ + uint32 sum = 0; + size_t size = content.length()/4; + for (size_t i=0; i>1 | 0x80000000; + else + sum = sum>>1; + } + return NLMISC::toString("0x%08X", sum); +} + +bool CMission::parsePrim(NLLIGO::IPrimitive const* prim) +{ + // init default values + std::vector* params; + // get the mission script + if (!prim->getPropertyByName("script", params) || !params) + { + nlwarning("ERROR : cant find mission script!!!!!!"); + return false; + } + + // parse them + std::string content; + std::vector::iterator itParam, itParamEnd = params->end(); + for (itParam=params->begin(); itParam!=itParamEnd; ++itParam) + { + content += *itParam + "\n"; + } + hashKey = buildHashKey(content); + return true; +} \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/validation_file.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/validation_file.h new file mode 100644 index 000000000..73d661a26 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/validation_file.h @@ -0,0 +1,51 @@ +#ifndef VALIDATION_FILE_H +#define VALIDATION_FILE_H + +#include +#include +#include + +#include + +struct CMissionState +{ + std::string name; + std::string state; + std::string hashKey; + CMissionState(std::string _name, std::string _state, std::string _hashKey) + : name(_name), state(_state), hashKey(_hashKey) { } +}; + +struct CMission +{ + std::string name; + std::string hashKey; + CMission(std::string _name, std::string _hashKey) + : name(_name), hashKey(_hashKey) { } + bool parsePrim(NLLIGO::IPrimitive const* prim); +}; + +class CValidationFile +{ +public: + typedef std::map TMissionStateContainer; + std::deque _AuthorizedStates; + TMissionStateContainer _MissionStates; +public: + // CValidationFile() { } + void loadMissionValidationFile(std::string filename); + void saveMissionValidationFile(std::string filename); + void insertMission(std::string const& mission, std::string const& hashKey) + { + _MissionStates.insert(std::make_pair(mission, CMissionState(mission, defaultState(), hashKey))); + } + std::string defaultState() + { + if (!_AuthorizedStates.empty()) + return _AuthorizedStates.front(); + else + return ""; + } +}; + +#endif // VALIDATION_FILE_H \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/attrib_form.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/attrib_form.ui index 77c4b895f..404444fc0 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/attrib_form.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/attrib_form.ui @@ -91,7 +91,7 @@ - false + true diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/attrib_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/attrib_widget.cpp index 648e0e1a5..e00d07cec 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/attrib_widget.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/attrib_widget.cpp @@ -186,12 +186,11 @@ void CAttribWidget::changeUseScheme(int index) void CAttribWidget::openSchemeBankDialog() { - CSchemeBankDialog *dialog = new CSchemeBankDialog(this); - dialog->setModal(true); - dialog->show(); - dialog->exec(); - delete dialog; - //updateUi(); + CSchemeBankDialog dialog(this); + dialog.setModal(true); + dialog.show(); + dialog.exec(); + updateUi(); } void CAttribWidget::inputValueUpdate(void) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/attrib_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/attrib_widget.h index 7bd929d72..da308aba7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/attrib_widget.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/attrib_widget.h @@ -58,7 +58,7 @@ public: /// Force to update dialog content void updateUi(); - /// Сonnects all the slots with signals + /// Connects all the slots with signals void init(); /// Sets the pointer CWorkspaceNode* in the wrappers. @@ -192,6 +192,7 @@ protected: QDialog *_SchemeWidget; Ui::CAttribWidget _ui; + friend class CSchemeBankDialog; }; /* class CAttribWidget */ /** diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/bin_op_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/bin_op_dialog.h index 061edafd4..3180e5d84 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/bin_op_dialog.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/bin_op_dialog.h @@ -97,7 +97,7 @@ public: _AttrbDlg[k]->init(); } - static const char * const operators[] = + static const char *const operators[] = { QT_TR_NOOP("Select Arg1"), QT_TR_NOOP("Select Arg2"), diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/entity.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/entity.h index 88338f214..a322363be 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/entity.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/entity.h @@ -141,7 +141,7 @@ public: float getAnimLength(std::string name); /// Get slot infomation - void setSlotInfo(uint num, CSlotInfo& slotInfo) + void setSlotInfo(uint num, CSlotInfo &slotInfo) { _SlotInfo[num] = slotInfo; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_viewport.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_viewport.cpp index 93bc1043e..d8e36e785 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_viewport.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_viewport.cpp @@ -135,7 +135,7 @@ bool CGraphicsViewport::winEvent(MSG *message, long *result) { winProc proc = (winProc)driver->getWindowProc(); - // TODO: shouldn't it return false like the others? + // TODO: shouldn't it return false like the others? // see macEvent() and x11Event() below return proc(driver, message->hwnd, message->message, message->wParam, message->lParam); } @@ -163,7 +163,7 @@ bool CGraphicsViewport::macEvent(EventHandlerCallRef caller, EventRef event) } } - // return false to let Qt handle the event as well, + // return false to let Qt handle the event as well, // else the widget would never get focus return false; } @@ -184,7 +184,7 @@ bool CGraphicsViewport::x11Event(XEvent *event) } } - // return false to let Qt handle the event as well, + // return false to let Qt handle the event as well, // else the widget would never get focus // TODO: test me please, i have no linux at hand (rti) return false; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_viewport.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_viewport.h index d810d8c01..0c01fa1ad 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_viewport.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_viewport.h @@ -59,7 +59,7 @@ public: CGraphicsViewport(QWidget *parent); virtual ~CGraphicsViewport(); - virtual QPaintEngine* paintEngine() const + virtual QPaintEngine *paintEngine() const { return NULL; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/hoverpoints.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/hoverpoints.cpp index fe0751082..a2556c08d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/hoverpoints.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/hoverpoints.cpp @@ -161,7 +161,7 @@ bool HoverPoints::eventFilter(QObject *object, QEvent *event) case QEvent::TouchBegin: case QEvent::TouchUpdate: { - const QTouchEvent *const touchEvent = static_cast(event); + const QTouchEvent *const touchEvent = static_cast(event); const QList points = touchEvent->touchPoints(); const qreal pointSize = qMax(m_pointSize.width(), m_pointSize.height()); Q_FOREACH (const QTouchEvent::TouchPoint &touchPoint, points) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/icons/ic_nel_pill.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/icons/ic_nel_pill.png new file mode 100644 index 000000000..e748b8190 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/icons/ic_nel_pill.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/main_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/main_window.cpp index e1962cf5b..a65f510c4 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/main_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/main_window.cpp @@ -52,7 +52,7 @@ #include "object_viewer_constants.h" #include "../core/icore.h" -#include "../core/imenu_manager.h" +#include "../core/menu_manager.h" #include "../core/core_constants.h" using namespace std; @@ -259,7 +259,7 @@ void CMainWindow::createActions() void CMainWindow::createMenus() { - Core::IMenuManager *menuManager = Core::ICore::instance()->menuManager(); + Core::MenuManager *menuManager = Core::ICore::instance()->menuManager(); _openAction = menuManager->action(Core::Constants::OPEN); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/morph_mesh_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/morph_mesh_dialog.cpp index d125277e4..de88d14c8 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/morph_mesh_dialog.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/morph_mesh_dialog.cpp @@ -91,7 +91,7 @@ QString CMorphMeshDialog::getShapeDescStr(uint shapeIndex, sint numVerts) const } else { - QString error = qobject_cast(QObject::parent())->getShapeErrorString(numVerts); + QString error = qobject_cast(QObject::parent())->getShapeErrorString(numVerts); QString result = _CM->getShape(shapeIndex).c_str() + QString(" (%1)").arg(error); return result; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer.cpp index dc248e563..4b0509018 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer.cpp @@ -435,7 +435,7 @@ void CObjectViewer::setCurrentObject(const std::string &name) nlinfo("set current entity %s", _CurrentInstance.c_str()); } -CEntity& CObjectViewer::getEntity(const std::string &name) +CEntity &CObjectViewer::getEntity(const std::string &name) { if ( _Entities.count(name) == 0) nlerror("Entity %s not found", name.c_str()); EIT eit = _Entities.find (name); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer.h index dc96f5cdf..5e978d7e0 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer.h @@ -152,7 +152,7 @@ public: /// Get entity from the scene /// @return ref Entity - CEntity& getEntity(const std::string &name); + CEntity &getEntity(const std::string &name); /// Get full list instances from the scene /// @param listObj - ref of return list instances diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer.qrc b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer.qrc index ac9647047..b088a5e28 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer.qrc +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer.qrc @@ -33,6 +33,7 @@ icons/ic_nel_water.png icons/ic_nel_wind.png icons/ic_nel_workspace_item.png + icons/ic_nel_pill.png images/nel.png icons/particles_system_24/ic_nel_collision_zone_item_24.png icons/particles_system_24/ic_nel_emitter_item_24.png diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_constants.h index 30a9b4c45..deb0c84ce 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_constants.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_constants.h @@ -22,76 +22,76 @@ namespace NLQT { namespace Constants { -const char * const OBJECT_VIEWER_PLUGIN = "ObjectViewer"; +const char *const OBJECT_VIEWER_PLUGIN = "ObjectViewer"; //mainwindow -const char * const MAIN_WINDOW = "ObjectViewer.MainWindow"; +const char *const MAIN_WINDOW = "ObjectViewer.MainWindow"; //settings -const char * const OBJECT_VIEWER_SECTION = "ObjectViewer"; -const char * const GRAPHICS_DRIVER = "GraphicsDriver"; -const char * const ENABLE_BLOOM = "EnableBloom"; -const char * const ENABLE_SQUARE_BLOOM = "EnableSquareBloom"; -const char * const BLOOM_DENSITY = "BloomDensity"; -const char * const QT_STYLE = "QtStyle"; -const char * const QT_PALETTE = "QtPalette"; -const char * const FONT = "Font"; +const char *const OBJECT_VIEWER_SECTION = "ObjectViewer"; +const char *const GRAPHICS_DRIVER = "GraphicsDriver"; +const char *const ENABLE_BLOOM = "EnableBloom"; +const char *const ENABLE_SQUARE_BLOOM = "EnableSquareBloom"; +const char *const BLOOM_DENSITY = "BloomDensity"; +const char *const QT_STYLE = "QtStyle"; +const char *const QT_PALETTE = "QtPalette"; +const char *const FONT = "Font"; -const char * const SOUND_ENABLE = "SoundEnable"; -const char * const SOUND_DRIVER = "SoundDriver"; -const char * const SOUND_DEVICE = "SoundDevice"; -const char * const SOUND_AUTO_LOAD_SAMPLE = "SoundAutoLoadSample"; -const char * const SOUND_ENABLE_OCCLUDE_OBSTRUCT = "SoundEnableOccludeObstruct"; -const char * const SOUND_ENABLE_REVERB = "SoundEnableReverb"; -const char * const SOUND_MANUAL_ROLL_OFF = "SoundManualRolloff"; -const char * const SOUND_FORCE_SOFTWARE = "SoundForceSoftware"; -const char * const SOUND_USE_ADCPM = "SoundUseADPCM"; -const char * const SOUND_MAX_TRACK = "SoundMaxTrack"; -const char * const SOUND_PACKED_SHEET_PATH = "SoundPackedSheetPath"; -const char * const SOUND_SAMPLE_PATH = "SoundSamplePath"; +const char *const SOUND_ENABLE = "SoundEnable"; +const char *const SOUND_DRIVER = "SoundDriver"; +const char *const SOUND_DEVICE = "SoundDevice"; +const char *const SOUND_AUTO_LOAD_SAMPLE = "SoundAutoLoadSample"; +const char *const SOUND_ENABLE_OCCLUDE_OBSTRUCT = "SoundEnableOccludeObstruct"; +const char *const SOUND_ENABLE_REVERB = "SoundEnableReverb"; +const char *const SOUND_MANUAL_ROLL_OFF = "SoundManualRolloff"; +const char *const SOUND_FORCE_SOFTWARE = "SoundForceSoftware"; +const char *const SOUND_USE_ADCPM = "SoundUseADPCM"; +const char *const SOUND_MAX_TRACK = "SoundMaxTrack"; +const char *const SOUND_PACKED_SHEET_PATH = "SoundPackedSheetPath"; +const char *const SOUND_SAMPLE_PATH = "SoundSamplePath"; -const char * const VEGET_TILE_BANK = "VegetTileBank"; -const char * const VEGET_TILE_FAR_BANK = "VegetTileFarBank"; -const char * const VEGET_TEXTURE = "VegetTexture"; -const char * const VEGET_LANDSCAPE_ZONES = "VegetLandscapeZones"; -const char * const COARSE_MESH_TEXTURE = "CoarseMeshTexture"; +const char *const VEGET_TILE_BANK = "VegetTileBank"; +const char *const VEGET_TILE_FAR_BANK = "VegetTileFarBank"; +const char *const VEGET_TEXTURE = "VegetTexture"; +const char *const VEGET_LANDSCAPE_ZONES = "VegetLandscapeZones"; +const char *const COARSE_MESH_TEXTURE = "CoarseMeshTexture"; -const char * const ICON_ADD_ITEM = ":/icons/ic_nel_add_item.png"; -const char * const ICON_INSERT_ITEM = ":/icons/ic_nel_insert_item.png"; -const char * const ICON_DELETE_ITEM = ":/icons/ic_nel_delete_item.png"; -const char * const ICON_DOWN_ITEM = ":/icons/ic_nel_down_item.png"; -const char * const ICON_UP_ITEM = ":/icons/ic_nel_up_item.png"; -const char * const ICON_CAMERA_ADD = ":/icons/ic_nel_camera_add.png"; -const char * const ICON_CAMERA_DEL = ":/icons/ic_nel_camera_del.png"; -const char * const ICON_CAMERA_3DEDIT = ":/icons/ic_nel_camera_3dedit.png"; -const char * const ICON_CAMERA_FPS = ":/icons/ic_nel_camera_fps.png"; -const char * const ICON_RESET_CAMERA = ":/icons/ic_nel_reset_camera.png"; -const char * const ICON_ANIM = ":/icons/ic_nel_anim.png"; -const char * const ICON_ANIMSET = ":/icons/ic_nel_animset.png"; -const char * const ICON_BGCOLOR = ":/icons/ic_nel_bgcolor.png"; -const char * const ICON_DAYNIGHT = ":/icons/ic_nel_daynight.png"; -const char * const ICON_FRAMEDELAY = ":/icons/ic_nel_framedelay.png"; -const char * const ICON_MIXER = ":/icons/ic_nel_mixer.png"; -const char * const ICON_MRM_MESH = ":/icons/ic_nel_mrm_mesh.png"; -const char * const ICON_PARTICLES = ":/icons/ic_nel_particles.png"; -const char * const ICON_SKELSCALE = ":/icons/ic_nel_skelscale.png"; -const char * const ICON_VEGET = ":/icons/ic_nel_veget.png"; -const char * const ICON_VEGETSET = ":/icons/ic_nel_vegetset.png"; -const char * const ICON_WATER = ":/icons/ic_nel_water.png"; -const char * const ICON_WIND = ":/icons/ic_nel_wind.png"; +const char *const ICON_ADD_ITEM = ":/icons/ic_nel_add_item.png"; +const char *const ICON_INSERT_ITEM = ":/icons/ic_nel_insert_item.png"; +const char *const ICON_DELETE_ITEM = ":/icons/ic_nel_delete_item.png"; +const char *const ICON_DOWN_ITEM = ":/icons/ic_nel_down_item.png"; +const char *const ICON_UP_ITEM = ":/icons/ic_nel_up_item.png"; +const char *const ICON_CAMERA_ADD = ":/icons/ic_nel_camera_add.png"; +const char *const ICON_CAMERA_DEL = ":/icons/ic_nel_camera_del.png"; +const char *const ICON_CAMERA_3DEDIT = ":/icons/ic_nel_camera_3dedit.png"; +const char *const ICON_CAMERA_FPS = ":/icons/ic_nel_camera_fps.png"; +const char *const ICON_RESET_CAMERA = ":/icons/ic_nel_reset_camera.png"; +const char *const ICON_ANIM = ":/icons/ic_nel_anim.png"; +const char *const ICON_ANIMSET = ":/icons/ic_nel_animset.png"; +const char *const ICON_BGCOLOR = ":/icons/ic_nel_bgcolor.png"; +const char *const ICON_DAYNIGHT = ":/icons/ic_nel_daynight.png"; +const char *const ICON_FRAMEDELAY = ":/icons/ic_nel_framedelay.png"; +const char *const ICON_MIXER = ":/icons/ic_nel_mixer.png"; +const char *const ICON_MRM_MESH = ":/icons/ic_nel_mrm_mesh.png"; +const char *const ICON_PARTICLES = ":/icons/ic_nel_particles.png"; +const char *const ICON_SKELSCALE = ":/icons/ic_nel_skelscale.png"; +const char *const ICON_VEGET = ":/icons/ic_nel_veget.png"; +const char *const ICON_VEGETSET = ":/icons/ic_nel_vegetset.png"; +const char *const ICON_WATER = ":/icons/ic_nel_water.png"; +const char *const ICON_WIND = ":/icons/ic_nel_wind.png"; -const char * const ICON_COLLISION_ZONE_ITEM_SMALL = ":/icons/particles_system_24/ic_nel_collision_zone_item_24.png"; -const char * const ICON_EMITTER_ITEM_SMALL = ":/icons/particles_system_24/ic_nel_emitter_item_24.png"; -const char * const ICON_FORCE_ITEM_SMALL = ":/icons/particles_system_24/ic_nel_force_item_24.png"; -const char * const ICON_INSTANCE_ITEM_SMALL = ":/icons/particles_system_24/ic_nel_instance_item_24.png"; -const char * const ICON_LIGHT_ITEM_SMALL = ":/icons/particles_system_24/ic_nel_light_item_24.png"; -const char * const ICON_LOCATED_ITEM_SMALL = ":/icons/particles_system_24/ic_nel_located_item_24.png"; -const char * const ICON_PARTICLE_ITEM_SMALL = ":/icons/particles_system_24/ic_nel_particle_item_24.png"; -const char * const ICON_PARTICLE_SYSTEM_SMALL = ":/icons/particles_system_24/ic_nel_particle_system_24.png"; -const char * const ICON_PARTICLE_SYSTEM_CLOSE_SMALL = ":/icons/particles_system_24/ic_nel_particle_system_close_24.png"; -const char * const ICON_PARTICLES_SMALL = ":/icons/particles_system_24/ic_nel_particles_24.png"; -const char * const ICON_SOUND_ITEM_SMALL = ":/icons/particles_system_24/ic_nel_sound_item_24.png"; -const char * const ICON_WORKSPACE_ITEM_SMALL = ":/icons/particles_system_24/ic_nel_workspace_item_24.png"; +const char *const ICON_COLLISION_ZONE_ITEM_SMALL = ":/icons/particles_system_24/ic_nel_collision_zone_item_24.png"; +const char *const ICON_EMITTER_ITEM_SMALL = ":/icons/particles_system_24/ic_nel_emitter_item_24.png"; +const char *const ICON_FORCE_ITEM_SMALL = ":/icons/particles_system_24/ic_nel_force_item_24.png"; +const char *const ICON_INSTANCE_ITEM_SMALL = ":/icons/particles_system_24/ic_nel_instance_item_24.png"; +const char *const ICON_LIGHT_ITEM_SMALL = ":/icons/particles_system_24/ic_nel_light_item_24.png"; +const char *const ICON_LOCATED_ITEM_SMALL = ":/icons/particles_system_24/ic_nel_located_item_24.png"; +const char *const ICON_PARTICLE_ITEM_SMALL = ":/icons/particles_system_24/ic_nel_particle_item_24.png"; +const char *const ICON_PARTICLE_SYSTEM_SMALL = ":/icons/particles_system_24/ic_nel_particle_system_24.png"; +const char *const ICON_PARTICLE_SYSTEM_CLOSE_SMALL = ":/icons/particles_system_24/ic_nel_particle_system_close_24.png"; +const char *const ICON_PARTICLES_SMALL = ":/icons/particles_system_24/ic_nel_particles_24.png"; +const char *const ICON_SOUND_ITEM_SMALL = ":/icons/particles_system_24/ic_nel_sound_item_24.png"; +const char *const ICON_WORKSPACE_ITEM_SMALL = ":/icons/particles_system_24/ic_nel_workspace_item_24.png"; } // namespace Constants } // namespace NLQT diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.cpp index f82789e66..ec21cef33 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.cpp @@ -56,33 +56,6 @@ void ObjectViewerPlugin::setNelContext(NLMISC::INelContext *nelContext) _LibContext = new NLMISC::CLibraryContext(*nelContext); } -QString ObjectViewerPlugin::name() const -{ - return "ObjectViewer"; -} - -QString ObjectViewerPlugin::version() const -{ - return "0.8"; -} - -QString ObjectViewerPlugin::vendor() const -{ - return Core::Constants::OVQT_VENDOR; -} - -QString ObjectViewerPlugin::description() const -{ - return "Object Viewer plugin."; -} - -QStringList ObjectViewerPlugin::dependencies() const -{ - QStringList list; - list.append(Core::Constants::OVQT_CORE_PLUGIN); - return list; -} - void ObjectViewerPlugin::addAutoReleasedObject(QObject *obj) { _plugMan->addObject(obj); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.h index b5f9c2881..5018501bf 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.h @@ -36,15 +36,8 @@ public: bool initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString); void extensionsInitialized(); void shutdown(); - void setNelContext(NLMISC::INelContext *nelContext); - QString name() const; - QString version() const; - QString vendor() const; - QString description() const; - QStringList dependencies() const; - void addAutoReleasedObject(QObject *obj); protected: @@ -74,7 +67,7 @@ public: virtual QIcon icon() const { - return QIcon(); + return QIcon(":/icons/ic_nel_pill.png"); } virtual QUndoStack *undoStack(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/ovqt_plugin_object_viewer.xml b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/ovqt_plugin_object_viewer.xml new file mode 100644 index 000000000..cc951cdcb --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/ovqt_plugin_object_viewer.xml @@ -0,0 +1,10 @@ + + ovqt_plugin_object_viewer + ObjectViewer + 0.8 + Ryzom Core + Object Viewer plugin. + + + + \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_editor.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_editor.cpp index d03cdab3d..12ea96c8a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_editor.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_editor.cpp @@ -73,11 +73,14 @@ void CParticleEditor::release() { stop(); closeWorkspace(); + delete _SchemeManager; } void CParticleEditor::setActiveNode(CWorkspaceNode *node) { if (node == _ActiveNode) return; + if (node == 0) + _ActiveNode->getPSModel()->hide(); _ActiveNode = node; bool wasRunning = _State == State::RunningSingle; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_force_page.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_force_page.h index 1bc23224f..1518bdd63 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_force_page.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_force_page.h @@ -43,7 +43,7 @@ namespace NLQT class CLocatedItem: public QListWidgetItem { public: - CLocatedItem ( const QString & text, QListWidget *parent = 0, int type = UserType ): + CLocatedItem ( const QString &text, QListWidget *parent = 0, int type = UserType ): QListWidgetItem(text, parent, type), _loc(NULL) {} void setUserData(NL3D::CPSLocated *loc) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_node.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_node.cpp index 3dfc1ce2c..15761c505 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_node.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_node.cpp @@ -378,6 +378,7 @@ void CParticleWorkspace::removeNode(uint index) { nlassert(index < _Nodes.size()); _Nodes[index] = NULL; // delete the smart-ptr target + delete _Nodes[index]; _Nodes.erase(_Nodes.begin() + index); touch(); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_node.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_node.h index acf7dfcd6..e9da65b5c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_node.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_node.h @@ -332,7 +332,7 @@ public: /// Restick all objects, useful after loading void restickAllObjects(); - TNodeVect& getNodeList() + TNodeVect &getNodeList() { return _Nodes; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_tree_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_tree_model.cpp index 77286ed32..2daebd6e4 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_tree_model.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_tree_model.cpp @@ -404,7 +404,7 @@ bool CParticleTreeModel::insertRows(NL3D::CPSLocated *loc, int position, const Q bool CParticleTreeModel::insertRow(NL3D::CPSLocated *loc, uint32 index, int position, const QModelIndex &parent) { beginInsertRows(parent, position, position); - createItemFromLocatedInstance(loc, index, static_cast(parent.internalPointer())); + createItemFromLocatedInstance(loc, index, static_cast(parent.internalPointer())); endInsertRows(); return true; } @@ -424,7 +424,7 @@ bool CParticleTreeModel::removeRows(int position, const QModelIndex &parent) removeRows(0, parent.child(position, 0)); beginRemoveRows(parent, position, position); - static_cast(parent.internalPointer())->deleteChild(position); + static_cast(parent.internalPointer())->deleteChild(position); endRemoveRows(); return false; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_workspace_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_workspace_dialog.cpp index 858922af1..74182120c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_workspace_dialog.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_workspace_dialog.cpp @@ -46,7 +46,7 @@ namespace NLQT { -static const char * const LocatedBindable[] = +static const char *const LocatedBindable[] = { QT_TR_NOOP("Point"), QT_TR_NOOP("LookAt"), @@ -220,7 +220,7 @@ void CParticleWorkspaceDialog::touchPSState(CParticleTreeItem *item) } } -void CParticleWorkspaceDialog::clickedItem(const QModelIndex & index) +void CParticleWorkspaceDialog::clickedItem(const QModelIndex &index) { if (_currentItem != 0) _treeModel->getOwnerNode(_currentItem)->getPSPointer()->setCurrentEditedElement(NULL); @@ -305,6 +305,8 @@ void CParticleWorkspaceDialog::customContextMenu() _instanciateAction->setEnabled(stopped); _savePSAction->setEnabled(stopped); _saveAsPSAction->setEnabled(stopped); + _removeFromWSAction->setEnabled(stopped); + _clearContentAction->setEnabled(stopped); popurMenu->exec(QCursor::pos()); delete popurMenu; @@ -369,13 +371,14 @@ void CParticleWorkspaceDialog::clearContent() void CParticleWorkspaceDialog::removePS() { - if (_treeModel->getOwnerNode(_currentItem) == Modules::psEdit().getActiveNode()) + CWorkspaceNode *node = _currentItem->getNode(); + if (node == Modules::psEdit().getActiveNode()) Modules::psEdit().setActiveNode(NULL); QModelIndex index = _ui.treeView->currentIndex(); _ui.treeView->setCurrentIndex(index.parent()); clickedItem(index.parent()); - Modules::psEdit().getParticleWorkspace()->removeNode(static_cast(index.internalPointer())->getNode()); + Modules::psEdit().getParticleWorkspace()->removeNode(node); _treeModel->removeRows(index.row(), index.parent()); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_workspace_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_workspace_dialog.h index 3a317adc7..c7aa0e52b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_workspace_dialog.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_workspace_dialog.h @@ -59,7 +59,7 @@ Q_SIGNALS: void changeActiveNode(); private Q_SLOTS: - void clickedItem(const QModelIndex & index); + void clickedItem(const QModelIndex &index); void customContextMenu(); void setActiveNode(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/ps_mover_page.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/ps_mover_page.h index a548b789a..74caadc5c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/ps_mover_page.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/ps_mover_page.h @@ -44,7 +44,7 @@ namespace NLQT class CLocatedBindableItem: public QListWidgetItem { public: - CLocatedBindableItem ( const QString & text, QListWidget * parent = 0, int type = UserType ): + CLocatedBindableItem ( const QString &text, QListWidget *parent = 0, int type = UserType ): QListWidgetItem(text, parent, type), _lb(NULL) {} void setUserData(NL3D::CPSLocatedBindable *loc) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/scheme_bank_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/scheme_bank_dialog.cpp index 66deb2a17..bca0f4879 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/scheme_bank_dialog.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/scheme_bank_dialog.cpp @@ -1,24 +1,33 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero 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 Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . // Project includes #include "stdpch.h" #include "scheme_bank_dialog.h" +#include "scheme_manager.h" #include "modules.h" +// NeL includes +#include + +// Qt includes +#include +#include +#include + namespace NLQT { @@ -27,6 +36,16 @@ CSchemeBankDialog::CSchemeBankDialog(CAttribWidget *attribWidget, QWidget *paren { _ui.setupUi(this); _attribWidget = attribWidget; + + connect(_ui.createButton, SIGNAL(clicked()), this, SLOT(createScheme())); + connect(_ui.currentButton, SIGNAL(clicked()), this, SLOT(setCurrentScheme())); + connect(_ui.removeButton, SIGNAL(clicked()), this, SLOT(removeScheme())); + connect(_ui.loadButton, SIGNAL(clicked()), this, SLOT(loadBank())); + connect(_ui.saveButton, SIGNAL(clicked()), this, SLOT(saveBank())); + connect(_ui.listWidget, SIGNAL(itemSelectionChanged()), this, SLOT(enableButtons())); + connect(_ui.listWidget, SIGNAL(itemChanged(QListWidgetItem *)), this, SLOT(changeNameScheme(QListWidgetItem *))); + + buildList(); } CSchemeBankDialog::~CSchemeBankDialog() @@ -35,27 +54,125 @@ CSchemeBankDialog::~CSchemeBankDialog() void CSchemeBankDialog::createScheme() { + bool ok; + QString text = QInputDialog::getText(this, tr("Insert new scheme"), + tr("Set name:"), QLineEdit::Normal, + "new scheme", &ok); + if (ok && !text.isEmpty()) + { + NL3D::CPSAttribMakerBase *attribMakerBase = _attribWidget->getCurrentSchemePtr()->clone(); + Modules::psEdit().getSchemeManager()->insertScheme(text.toStdString(), attribMakerBase); + + CSchemeItem *item = new CSchemeItem(text, _ui.listWidget); + item->setUserData(attribMakerBase); + item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled); + } } void CSchemeBankDialog::setCurrentScheme() { - //SchemeManager.insertScheme(cn.getName(), getCurrentSchemePtr()->clone()); + CSchemeItem *item = dynamic_cast(_ui.listWidget->currentItem()); + + NL3D::CPSAttribMakerBase *attrib = item->getUserData(); + nlassert(attrib); + + _attribWidget->setCurrentSchemePtr(attrib->clone()); + _attribWidget->updateUi(); } void CSchemeBankDialog::removeScheme() { + CSchemeItem *item = dynamic_cast(_ui.listWidget->currentItem()); + + NL3D::CPSAttribMakerBase *attrib = item->getUserData(); + nlassert(attrib); + Modules::psEdit().getSchemeManager()->remove(attrib); + _ui.listWidget->removeItemWidget(item); + delete item; + + if (_ui.listWidget->count() == 0) + { + _ui.currentButton->setEnabled(false); + _ui.removeButton->setEnabled(false); + } } void CSchemeBankDialog::saveBank() { + QString fileName = QFileDialog::getSaveFileName(this, + tr("Save scheme bank file"), ".", + tr("Scheme bank files (*.scb)")); + + if (!fileName.isEmpty()) + { + try + { + NLMISC::COFile iF; + iF.open(fileName.toStdString()); + NLQT::CSchemeManager *schemeManager = Modules::psEdit().getSchemeManager(); + iF.serial(*schemeManager); + } + catch (std::exception &e) + { + QMessageBox::critical(this, "Scheme manager", tr("Error saving scheme bank : %1").arg(e.what())); + return; + } + } } void CSchemeBankDialog::loadBank() { + QString fileName = QFileDialog::getOpenFileName(this, + tr("Open scheme bank file"), ".", + tr("Scheme bank files (*.scb)")); + + if (!fileName.isEmpty()) + { + NLQT::CSchemeManager sm; + try + { + NLMISC::CIFile iF; + iF.open(fileName.toStdString()); + iF.serial(sm); + Modules::psEdit().getSchemeManager()->swap(sm); + } + catch (std::exception &e) + { + QMessageBox::critical(this, "Scheme manager", tr("Error loading scheme bank : %1").arg(e.what())); + return; + } + buildList(); + } } -void CSchemeBankDialog::buildList() +void CSchemeBankDialog::changeNameScheme(QListWidgetItem *item) { + CSchemeItem *schemeItem = dynamic_cast(item); + + NL3D::CPSAttribMakerBase *attrib = schemeItem->getUserData(); + nlassert(attrib); + + Modules::psEdit().getSchemeManager()->rename(attrib, item->text().toStdString()); +} + +void CSchemeBankDialog::enableButtons() +{ + _ui.currentButton->setEnabled(true); + _ui.removeButton->setEnabled(true); +} + +void CSchemeBankDialog::buildList() +{ + _ui.listWidget->clear(); + typedef std::vector TSchemeVect; + static TSchemeVect schemes; + Modules::psEdit().getSchemeManager()->getSchemes(_attribWidget->getCurrentSchemePtr()->getType(), schemes); + for (TSchemeVect::const_iterator it = schemes.begin(); it != schemes.end(); ++it) + { + CSchemeItem *item = new CSchemeItem(it->first.c_str(), _ui.listWidget); + item->setUserData(it->second); + item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled); + } } } /* namespace NLQT */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/scheme_bank_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/scheme_bank_dialog.h index a02406468..8f9f300b8 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/scheme_bank_dialog.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/scheme_bank_dialog.h @@ -1,17 +1,17 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero 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 Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #ifndef SCHEME_BANK_DIALOG_H @@ -27,12 +27,37 @@ #include "nel/3d/particle_system.h" // Project includes +#include "attrib_widget.h" #include "ps_wrapper.h" namespace NLQT { class CAttribWidget; +/** +@class CSchemeItem +@brief Contain pointer to NL3D::CPSAttribMakerBase. +*/ +class CSchemeItem: public QListWidgetItem +{ +public: + CSchemeItem(const QString &text, QListWidget *parent = 0, int type = UserType ): + QListWidgetItem(text, parent, type), _attrib(NULL) {} + + void setUserData(NL3D::CPSAttribMakerBase *attrib) + { + _attrib = attrib; + } + NL3D::CPSAttribMakerBase *getUserData() const + { + return _attrib; + } + +private: + + NL3D::CPSAttribMakerBase *_attrib; +}; /* class CSchemeItem */ + class CSchemeBankDialog: public QDialog { Q_OBJECT @@ -47,9 +72,11 @@ private Q_SLOTS: void removeScheme(); void saveBank(); void loadBank(); + void enableButtons(); + void changeNameScheme(QListWidgetItem *item); private: - void buildList(); + void buildList(); CAttribWidget *_attribWidget; Ui::CSchemeBankDialog _ui; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/scheme_bank_form.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/scheme_bank_form.ui index e7dd281f8..f8fa10865 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/scheme_bank_form.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/scheme_bank_form.ui @@ -14,31 +14,27 @@ Sceme bank - + - Create + Put current - - - Rename - - - - + + false + Remove - + Qt::Vertical @@ -51,24 +47,33 @@ - + + + true + Load bank - + + + true + Save bank - + + + false + 0 @@ -105,7 +110,10 @@ - + + + false + Set current diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/scheme_manager.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/scheme_manager.cpp index 62e847a73..c00422af5 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/scheme_manager.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/scheme_manager.cpp @@ -18,7 +18,7 @@ #include "scheme_manager.h" #include "nel/3d/ps_attrib_maker.h" -namespace NLQT +namespace NLQT { CSchemeManager::~CSchemeManager() @@ -34,7 +34,7 @@ void CSchemeManager::insertScheme(const std::string &name, NL3D::CPSAttribMakerB { nlassert(scheme); TSchemeInfo si(std::string(name), scheme); - _SchemeMap.insert(TSchemeMap::value_type(std::string(scheme->getType()), si)); + _SchemeMap.insert(TSchemeMap::value_type(std::string(scheme->getType()), si)); } void CSchemeManager::getSchemes(const std::string &type, std::vector &dest) @@ -49,30 +49,30 @@ void CSchemeManager::getSchemes(const std::string &type, std::vectorsecond.first); // name f.serialPolyPtr(smIt->second.second); // scheme - } + } } else { _SchemeMap.clear(); - + std::string name; NL3D::CPSAttribMakerBase *scheme = NULL; sint32 size; f.serial(size); for (sint32 k = 0; k < size; ++k) - { + { f.serial(name); f.serialPolyPtr(scheme); insertScheme(name, scheme); @@ -80,12 +80,12 @@ void CSchemeManager::serial(NLMISC::IStream &f) throw(NLMISC::EStream) } } -void CSchemeManager::swap(CSchemeManager &other) +void CSchemeManager::swap(CSchemeManager &other) { this->_SchemeMap.swap(other._SchemeMap); } -void CSchemeManager::remove(NL3D::CPSAttribMakerBase *am) +void CSchemeManager::remove(NL3D::CPSAttribMakerBase *am) { TSchemeMap::iterator smIt; for (smIt = _SchemeMap.begin(); smIt != _SchemeMap.end(); ++smIt) @@ -101,7 +101,7 @@ void CSchemeManager::remove(NL3D::CPSAttribMakerBase *am) } // rename a scheme, given a pointer on it -void CSchemeManager::rename(NL3D::CPSAttribMakerBase *am, const std::string &newName) +void CSchemeManager::rename(NL3D::CPSAttribMakerBase *am, const std::string &newName) { TSchemeMap::iterator smIt; for (smIt = _SchemeMap.begin(); smIt != _SchemeMap.end(); ++smIt) @@ -110,7 +110,7 @@ void CSchemeManager::rename(NL3D::CPSAttribMakerBase *am, const std::string &ne } if (smIt != _SchemeMap.end()) { - smIt->second.first = newName; + smIt->second.first = newName; } } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/scheme_manager.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/scheme_manager.h index 8348fae0c..7b06734f2 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/scheme_manager.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/scheme_manager.h @@ -25,7 +25,7 @@ namespace NL3D { -class CPSAttribMakerBase; + class CPSAttribMakerBase; } namespace NLQT @@ -50,11 +50,12 @@ public: void remove(NL3D::CPSAttribMakerBase *am); // rename a scheme, given a pointer on it void rename(NL3D::CPSAttribMakerBase *am, const std::string &newName); -protected: +protected: + // typedef std::pair TSchemeInfo; typedef std::multimap TSchemeMap; - TSchemeMap _SchemeMap; + TSchemeMap _SchemeMap; }; } /* namespace NLQT */ -#endif \ No newline at end of file +#endif diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/sound_system.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/sound_system.cpp index ba64d834e..a8a204c96 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/sound_system.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/sound_system.cpp @@ -107,6 +107,9 @@ void CSoundSystem::init() std::string mess = std::string("Unable to init sound :") + e.what(); nlwarning ("Init sound: %s", mess.c_str()); _AudioMixer = NULL; + QSettings *settings = Core::ICore::instance()->settings(); + if (settings->group() == Constants::OBJECT_VIEWER_SECTION) + settings->endGroup(); return; } @@ -187,7 +190,7 @@ NLSOUND::USource *CSoundSystem::create(const std::string &soundName) return NULL; } -void CSoundSystem::playAnimation(std::string& name, float lastTime, float curTime, NLSOUND::CSoundContext &context) +void CSoundSystem::playAnimation(std::string &name, float lastTime, float curTime, NLSOUND::CSoundContext &context) { if (_AnimManager == NULL) { diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/sound_system.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/sound_system.h index 4add4b9db..79ea68a46 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/sound_system.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/sound_system.h @@ -61,13 +61,13 @@ public: } /// Sets the path which contains samples - void setSamplePath(std::string& path) + void setSamplePath(std::string &path) { _SamplePath = NLMISC::CPath::standardizePath(path, true); } /// Sets the path which contains packed sheet - void setPackedSheetPath(std::string& path) + void setPackedSheetPath(std::string &path) { _PackedSheetPath = NLMISC::CPath::standardizePath(path, true); } @@ -88,13 +88,13 @@ public: NLSOUND::USource *create(const std::string &soundName); /// Load the sound animation with the specified name - void loadAnimation(std::string& name) + void loadAnimation(std::string &name) { _AnimManager->loadAnimation(name); } /// Start playing a sound animation. - void playAnimation(std::string& name, float lastTime, float curTime, NLSOUND::CSoundContext &context); + void playAnimation(std::string &name, float lastTime, float curTime, NLSOUND::CSoundContext &context); // Update the sound animations. //static void updateAnimations(float lastTime, float curTime) { _AnimManager->update(lastTime, curTime); }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/vegetable_appearance_page.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/vegetable_appearance_page.cpp index 9c49871b3..0366bc11f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/vegetable_appearance_page.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/vegetable_appearance_page.cpp @@ -60,7 +60,7 @@ CVegetableApperancePage::CVegetableApperancePage(QWidget *parent) connect(_ui.removePushButton, SIGNAL(clicked()), this, SLOT(removeColor())); connect(_ui.getListPushButton, SIGNAL(clicked()), this, SLOT(getFromListColors())); - connect(_ui.listWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(browseColor(QListWidgetItem*))); + connect(_ui.listWidget, SIGNAL(itemDoubleClicked(QListWidgetItem *)), this, SLOT(browseColor(QListWidgetItem *))); setEnabled(false); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/workspace_form.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/workspace_form.ui index 28705f097..b8bec17b7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/workspace_form.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/workspace_form.ui @@ -6,8 +6,8 @@ 0 0 - 337 - 232 + 235 + 293 @@ -130,7 +130,51 @@ - + + + + false + + + + 0 + 0 + + + + + 55 + 0 + + + + + 16777215 + 16777215 + + + + Unload + + + + :/icons/ic_nel_particle_system_close.png:/icons/ic_nel_particle_system_close.png + + + + 32 + 32 + + + + Qt::ToolButtonTextUnderIcon + + + true + + + + false @@ -177,7 +221,7 @@ - + false @@ -221,50 +265,6 @@ - - - - false - - - - 0 - 0 - - - - - 55 - 0 - - - - - 16777215 - 16777215 - - - - Unload - - - - :/icons/ic_nel_particle_system_close.png:/icons/ic_nel_particle_system_close.png - - - - 32 - 32 - - - - Qt::ToolButtonTextUnderIcon - - - true - - - diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/ovqt_sheet_builder/ovqt_plugin_sheet_builder.xml b/code/nel/tools/3d/object_viewer_qt/src/plugins/ovqt_sheet_builder/ovqt_plugin_sheet_builder.xml new file mode 100644 index 000000000..14965e86e --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/ovqt_sheet_builder/ovqt_plugin_sheet_builder.xml @@ -0,0 +1,10 @@ + + ovqt_plugin_sheet_builder + SheetBuilder + 1.0 + kharvd + make_sheet_id equivalent + + + + \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/ovqt_sheet_builder/ovqt_sheet_builder.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/ovqt_sheet_builder/ovqt_sheet_builder.cpp index 18e77fbcc..4fd7dfb11 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/ovqt_sheet_builder/ovqt_sheet_builder.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/ovqt_sheet_builder/ovqt_sheet_builder.cpp @@ -19,7 +19,7 @@ #include "sheetbuilderdialog.h" #include "sheetbuilderconfgdialog.h" #include "../core/icore.h" -#include "../core/imenu_manager.h" +#include "../core/menu_manager.h" #include "../core/core_constants.h" // NeL includes @@ -38,14 +38,14 @@ using namespace Plugin; bool SheetBuilderPlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString) { Q_UNUSED(errorString); - _plugMan = pluginManager; + m_plugMan = pluginManager; return true; } void SheetBuilderPlugin::extensionsInitialized() { - Core::IMenuManager *menuManager = Core::ICore::instance()->menuManager(); + Core::MenuManager *menuManager = Core::ICore::instance()->menuManager(); QMenu *sheetMenu = menuManager->menu(Core::Constants::M_SHEET); QAction *sheetBuilderAction = sheetMenu->addAction(tr("Sheet builder")); @@ -69,34 +69,7 @@ void SheetBuilderPlugin::setNelContext(NLMISC::INelContext *nelContext) // This only applies to platforms without PIC, e.g. Windows. nlassert(!NLMISC::INelContext::isContextInitialised()); #endif // NL_OS_WINDOWS - _LibContext = new NLMISC::CLibraryContext(*nelContext); -} - -QString SheetBuilderPlugin::name() const -{ - return "Sheet builder"; -} - -QString SheetBuilderPlugin::version() const -{ - return "1.0"; -} - -QString SheetBuilderPlugin::vendor() const -{ - return "kharvd"; -} - -QString SheetBuilderPlugin::description() const -{ - return "make_sheet_id equivalent"; -} - -QStringList SheetBuilderPlugin::dependencies() const -{ - QStringList list; - list.append(Core::Constants::OVQT_CORE_PLUGIN); - return list; + m_LibContext = new NLMISC::CLibraryContext(*nelContext); } Q_EXPORT_PLUGIN(SheetBuilderPlugin) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/ovqt_sheet_builder/ovqt_sheet_builder.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/ovqt_sheet_builder/ovqt_sheet_builder.h index f1299dfba..504d0914d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/ovqt_sheet_builder/ovqt_sheet_builder.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/ovqt_sheet_builder/ovqt_sheet_builder.h @@ -28,11 +28,6 @@ namespace NLMISC class CLibraryContext; } -namespace ExtensionSystem -{ -class IPluginSpec; -} - namespace Plugin { @@ -43,25 +38,18 @@ class SheetBuilderPlugin : public QObject, public ExtensionSystem::IPlugin public: bool initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString); void extensionsInitialized(); - void setNelContext(NLMISC::INelContext *nelContext); - QString name() const; - QString version() const; - QString vendor() const; - QString description() const; - QStringList dependencies() const; - void buildSheet(bool clean); private Q_SLOTS: void execBuilderDialog(); protected: - NLMISC::CLibraryContext *_LibContext; + NLMISC::CLibraryContext *m_LibContext; private: - ExtensionSystem::IPluginManager *_plugMan; + ExtensionSystem::IPluginManager *m_plugMan; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/ovqt_sheet_builder/sheetbuilder.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/ovqt_sheet_builder/sheetbuilder.h index aac097c9b..eb9b3bc22 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/ovqt_sheet_builder/sheetbuilder.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/ovqt_sheet_builder/sheetbuilder.h @@ -54,7 +54,7 @@ union TFormId } }; -bool operator<(const TFormId& fid1, const TFormId& fid2) +bool operator<(const TFormId &fid1, const TFormId &fid2) { return fid1.Id(outputLine.data())),(uint)outputLine.size()); + output.serialBuffer((uint8 *)(const_cast(outputLine.data())),(uint)outputLine.size()); } displayInfo (tr("------------- results ----------------")); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/CMakeLists.txt new file mode 100644 index 000000000..272c7b962 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/CMakeLists.txt @@ -0,0 +1,51 @@ +INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} + ${LIBXML2_INCLUDE_DIR} + ${QT_INCLUDES}) + +FILE(GLOB SRC *.cpp *.h) + +SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin.h + ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin_manager.h + ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin_spec.h) + +SET(OVQT_PLUG_TRANSLATION_MANAGER_HDR translation_manager_plugin.h + translation_manager_main_window.h + translation_manager_settings_page.h + translation_manager_editor.h + source_selection.h + ftp_selection.h + editor_worksheet.h + editor_phrase.h +) + +SET(OVQT_PLUG_TRANSLATION_MANAGER_UIS translation_manager_settings_page.ui + translation_manager_main_window.ui + source_selection.ui + ftp_selection.ui) + +SET(OVQT_PLUG_TRANSLATION_MANAGER_RCS ftp_selection.qrc) + +SET(QT_USE_QTGUI TRUE) +SET(QT_USE_QTNETWORK TRUE) + +QT4_WRAP_CPP(OVQT_PLUG_TRANSLATION_MANAGER_MOC_SRC ${OVQT_PLUG_TRANSLATION_MANAGER_HDR}) +QT4_WRAP_UI(OVQT_PLUG_TRANSLATION_MANAGER_UI_HDRS ${OVQT_PLUG_TRANSLATION_MANAGER_UIS}) + +SOURCE_GROUP(QtResources FILES ${OVQT_PLUG_TRANSLATION_MANAGER_UIS}) +SOURCE_GROUP(QtGeneratedUiHdr FILES ${OVQT_PLUG_TRANSLATION_MANAGER_UI_HDRS}) +SOURCE_GROUP(QtGeneratedMocSrc FILES ${OVQT_PLUG_TRANSLATION_MANAGER_MOC_SRC}) +SOURCE_GROUP("Translation Manager Plugin" FILES ${SRC}) +SOURCE_GROUP("OVQT Extension System" FILES ${OVQT_EXT_SYS_SRC}) + +ADD_LIBRARY(ovqt_plugin_translation_manager MODULE ${SRC} ${OVQT_PLUG_TRANSLATION_MANAGER_MOC_SRC} ${OVQT_EXT_SYS_SRC} ${OVQT_PLUG_TRANSLATION_MANAGER_UI_HDRS}) + +TARGET_LINK_LIBRARIES(ovqt_plugin_translation_manager ovqt_plugin_core nelmisc nelligo nelgeorges ${QT_LIBRARIES} ${QT_QTOPENGL_LIBRARY} ${QT_QTNETWORK_LIBRARY} ) + +NL_DEFAULT_PROPS(ovqt_plugin_translation_manager "NeL, Tools, 3D: Object Viewer Qt Plugin: Translation Manager") +NL_ADD_RUNTIME_FLAGS(ovqt_plugin_translation_manager) +NL_ADD_LIB_SUFFIX(ovqt_plugin_translation_manager) + +ADD_DEFINITIONS(${LIBXML2_DEFINITIONS} -DQT_PLUGIN -DQT_SHARED ${QT_DEFINITIONS}) + +INSTALL(TARGETS ovqt_plugin_translation_manager LIBRARY DESTINATION lib RUNTIME DESTINATION bin ARCHIVE DESTINATION lib COMPONENT tools3d) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/README b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/README index c5c895519..b182bfdcf 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/README +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/README @@ -1,3 +1,5 @@ -OVQT Translation Manager plugin --------------------------------- +Translation Manager Plugin +-------------------------- +GSoC 2011 Project http://dev.ryzom.com/wiki/ryzom/OVQTTranslationPluginGSoc2011 + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/editor_phrase.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/editor_phrase.cpp new file mode 100644 index 000000000..a1c59a11f --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/editor_phrase.cpp @@ -0,0 +1,134 @@ +// Translation Manager Plugin - OVQT Plugin +// Copyright (C) 2011 Emanuel Costea +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Project includes +#include "editor_phrase.h" +#include "translation_manager_constants.h" + +// Nel includes +#include "nel/misc/path.h" +#include "nel/misc/diff_tool.h" + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +namespace TranslationManager +{ + +void CEditorPhrase::open(QString filename) +{ + std::vector phrases; + if(readPhraseFile(filename.toStdString(), phrases, false)) + { + text_edit = new CTextEdit(this); + text_edit->setUndoStack(current_stack); + SyntaxHighlighter *highlighter = new SyntaxHighlighter(text_edit); + text_edit->setUndoRedoEnabled(true); + text_edit->document()->setUndoRedoEnabled(true); + setWidget(text_edit); + // read the file content + QFile file(filename); + file.open(QIODevice::ReadOnly | QIODevice::Text); + QTextStream in(&file); + // set the file content to the text edit + QString data = in.readAll(); + text_edit->append(data); + // window settings + setCurrentFile(filename); + setAttribute(Qt::WA_DeleteOnClose); + editor_type = Constants::ED_PHRASE; + current_file = filename; + connect(text_edit->document(), SIGNAL(contentsChanged()), this, SLOT(docContentsChanged())); + connect(text_edit->document(), SIGNAL(undoCommandAdded()), this, SLOT(newUndoCommandAdded())); + } + else + { + QErrorMessage error; + error.showMessage("This file is not a phrase file."); + error.exec(); + } +} + +void CEditorPhrase::newUndoCommandAdded() +{ + current_stack->push(new CUndoPhraseNewCommand(text_edit)); +} + +void CEditorPhrase::docContentsChanged() +{ + setWindowModified(true); +} + +void CEditorPhrase::activateWindow() +{ + showMaximized(); +} + +void CEditorPhrase::save() +{ + saveAs(current_file); +} + +void CEditorPhrase::saveAs(QString filename) +{ + QFile file(filename); + file.open(QIODevice::WriteOnly | QIODevice::Text); + QTextStream out(&file); + out.setCodec("UTF-8"); + out.setGenerateByteOrderMark(true); + out << text_edit->toPlainText(); + current_file = filename; + setCurrentFile(current_file); +} + +void CEditorPhrase::closeEvent(QCloseEvent *event) +{ + if(isWindowModified()) + { + QMessageBox msgBox; + msgBox.setIcon(QMessageBox::Question); + msgBox.setText(tr("The document has been modified.")); + msgBox.setInformativeText(tr("Do you want to save your changes?")); + msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); + msgBox.setDefaultButton(QMessageBox::Save); + + int ret = msgBox.exec(); + switch (ret) + { + case QMessageBox::Save: + save(); + break; + case QMessageBox::Discard: + break; + case QMessageBox::Cancel: + event->ignore(); + return; + } + } + event->accept(); + close(); +} + +} \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/editor_phrase.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/editor_phrase.h new file mode 100644 index 000000000..b9955fa48 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/editor_phrase.h @@ -0,0 +1,200 @@ +// Translation Manager Plugin - OVQT Plugin +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Emanuel Costea +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef EDITOR_PHRASE_H +#define EDITOR_PHRASE_H + +// Project includes +#include "translation_manager_editor.h" + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace TranslationManager +{ + +class CTextEdit : public QTextEdit +{ + Q_OBJECT + +private: + QUndoStack *m_undoStack; + +public: + CTextEdit(QWidget *parent = 0) : QTextEdit(parent) + { + setUndoRedoEnabled(true); + } + //void keyPressEvent(QKeyEvent *event); + void setUndoStack(QUndoStack *undoStack) + { + m_undoStack = undoStack; + } +}; + +class CEditorPhrase : public CEditor +{ + Q_OBJECT + +public: + CEditorPhrase(QMdiArea *parent) : CEditor(parent) {} + CEditorPhrase() : CEditor() {} + void open(QString filename); + void save(); + void saveAs(QString filename); + void activateWindow(); + void closeEvent(QCloseEvent *event); + +public Q_SLOTS: + void docContentsChanged(); + void newUndoCommandAdded(); + +private: + CTextEdit *text_edit; +}; + +class CUndoPhraseNewCommand : public QUndoCommand +{ +public: + CUndoPhraseNewCommand(CTextEdit *textEdit, QUndoCommand *parent = 0) + : QUndoCommand("Inserting/Removing characters", parent), + m_textEdit(textEdit) + {} + + ~CUndoPhraseNewCommand() {} + + void undo() + { + m_textEdit->undo(); + } + + void redo() + { + m_textEdit->redo(); + } + +private: + CTextEdit *m_textEdit; +}; + +class SyntaxHighlighter : public QSyntaxHighlighter +{ +public: + SyntaxHighlighter(QTextEdit *parent) : QSyntaxHighlighter(parent) + { + HighlightingRule rule; + + translateStringFormat.setFontWeight(QFont::Bold); + translateStringFormat.setForeground(Qt::darkMagenta); + rule.pattern = QRegExp("\\[.+\\]"); + rule.format = translateStringFormat; + highlightingRules.append(rule); + + singleLineCommentFormat.setForeground(Qt::red); + rule.pattern = QRegExp("//[^\n]*"); + rule.format = singleLineCommentFormat; + highlightingRules.append(rule); + + multiLineCommentFormat.setForeground(Qt::red); + + quotationFormat.setForeground(Qt::darkGreen); + rule.pattern = QRegExp("\".*\""); + rule.format = quotationFormat; + highlightingRules.append(rule); + + functionFormat.setFontItalic(true); + functionFormat.setForeground(Qt::blue); + rule.pattern = QRegExp("\\(.+\\)"); + rule.format = functionFormat; + highlightingRules.append(rule); + + commentStartExpression = QRegExp("/\\*"); + commentEndExpression = QRegExp("\\*/"); + } + + void highlightBlock(const QString &text) + { + Q_FOREACH(const HighlightingRule &rule, highlightingRules) + { + QRegExp expression(rule.pattern); + int index = expression.indexIn(text); + while (index >= 0) + { + int length = expression.matchedLength(); + setFormat(index, length, rule.format); + index = expression.indexIn(text, index + length); + } + } + setCurrentBlockState(0); + + int startIndex = 0; + if (previousBlockState() != 1) + startIndex = commentStartExpression.indexIn(text); + + while (startIndex >= 0) + { + int endIndex = commentEndExpression.indexIn(text, startIndex); + int commentLength; + if (endIndex == -1) + { + setCurrentBlockState(1); + commentLength = text.length() - startIndex; + } + else + { + commentLength = endIndex - startIndex + + commentEndExpression.matchedLength(); + } + setFormat(startIndex, commentLength, multiLineCommentFormat); + startIndex = commentStartExpression.indexIn(text, startIndex + commentLength); + } + } + +private: + struct HighlightingRule + { + QRegExp pattern; + QTextCharFormat format; + }; + QVector highlightingRules; + + QRegExp commentStartExpression; + QRegExp commentEndExpression; + + QTextCharFormat keywordFormat; + QTextCharFormat classFormat; + QTextCharFormat singleLineCommentFormat; + QTextCharFormat multiLineCommentFormat; + QTextCharFormat quotationFormat; + QTextCharFormat functionFormat; + QTextCharFormat translateStringFormat; +}; + +} + +#endif /* EDITOR_PHRASE_H */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/editor_worksheet.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/editor_worksheet.cpp new file mode 100644 index 000000000..7041a5178 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/editor_worksheet.cpp @@ -0,0 +1,526 @@ +// Translation Manager Plugin - OVQT Plugin +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Emanuel Costea +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Project includes +#include "editor_worksheet.h" +#include "extract_bot_names.h" +#include "translation_manager_constants.h" + +// Qt includes +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +namespace TranslationManager +{ + +void CEditorWorksheet::open(QString filename) +{ + STRING_MANAGER::TWorksheet wk_file; + if(loadExcelSheet(filename.toStdString(), wk_file, true) == true) + { + bool hasHashValue = false; + table_editor = new QTableWidget(); + if(wk_file.getData(0, 0) == ucstring("*HASH_VALUE")) + { + table_editor->setColumnCount(wk_file.ColCount - 1); + hasHashValue = true; + } + else + { + table_editor->setColumnCount(wk_file.ColCount); + } + table_editor->setRowCount(wk_file.size() - 1); + + // read columns name + for(uint i = 0; i < wk_file.ColCount; i++) + { + if(hasHashValue && i == 0) + { + // we don't show the column with hash value + } + else + { + QTableWidgetItem *col = new QTableWidgetItem(); + ucstring col_name = wk_file.getData(0, i); + col->setText(QString(col_name.toString().c_str())); + if(hasHashValue) + { + table_editor->setHorizontalHeaderItem(i - 1, col); + } + else + { + table_editor->setHorizontalHeaderItem(i, col); + } + } + } + + // read rows + for(unsigned int i = 1; i < wk_file.size(); i++) + { + for(unsigned int j = 0; j < wk_file.ColCount; j++) + { + if(hasHashValue && j == 0) + { + // we don't show the column with hash value + } + else + { + QTableWidgetItem *row = new QTableWidgetItem(); + ucstring row_value = wk_file.getData(i, j); + row->setText(QString::fromUtf8(row_value.toUtf8().c_str())); + if(hasHashValue) + { + table_editor->setItem(i - 1, j - 1, row); + } + else + { + table_editor->setItem(i - 1, j, row); + } + } + } + } + setCurrentFile(filename); + setAttribute(Qt::WA_DeleteOnClose); + setWidget(table_editor); + editor_type = Constants::ED_SHEET; + table_editor->resizeColumnsToContents(); + table_editor->resizeRowsToContents(); + // set editor signals + connect(table_editor, SIGNAL(itemChanged(QTableWidgetItem *) ), this, SLOT(worksheetEditorChanged(QTableWidgetItem *))); + connect(table_editor, SIGNAL(itemDoubleClicked(QTableWidgetItem *) ), this, SLOT(worksheetEditorCellEntered(QTableWidgetItem *))); + connect(table_editor,SIGNAL(customContextMenuRequested(const QPoint &)), this,SLOT(contextMenuEvent(QContextMenuEvent *))); + } + else + { + QErrorMessage error; + error.showMessage(tr("This file is not a worksheet file.")); + error.exec(); + } +} + + +void CEditorWorksheet::contextMenuEvent(QContextMenuEvent *e) +{ + QAction *insertRowAct = new QAction(tr("Insert new row"), this); + connect(insertRowAct, SIGNAL(triggered()), this, SLOT(insertRow())); + QAction *deleteRowAct = new QAction(tr("Delete row"), this); + connect(deleteRowAct, SIGNAL(triggered()), this, SLOT(deleteRow())); + + QMenu *contextMenu = new QMenu(this); + contextMenu->addAction(insertRowAct); + contextMenu->addAction(deleteRowAct); + contextMenu->exec( e->globalPos() ); + delete contextMenu; + contextMenu = NULL; +} + + +void CEditorWorksheet::activateWindow() +{ + showMaximized(); +} + +void CEditorWorksheet::save() +{ + saveAs(current_file); +} + +void CEditorWorksheet::saveAs(QString filename) +{ + STRING_MANAGER::TWorksheet new_file, wk_file; + loadExcelSheet(current_file.toStdString(), wk_file, true); + // set columns + new_file.resize(new_file.size() + 1); + for(unsigned int i = 0; i < wk_file.ColCount; i++) + { + ucstring col_name = wk_file.getData(0, i); + new_file.insertColumn(new_file.ColCount); + new_file.setData(0, new_file.ColCount - 1, col_name); + } + // read all the rows from table + uint rowIdx; + uint colIdx = 0; + bool hasHashValue = false; + if(wk_file.getData(0, 0) == ucstring("*HASH_VALUE")) + { + hasHashValue = true; + colIdx = 1; + } + for(int i = 0; i < table_editor->rowCount(); i++) + { + rowIdx = new_file.size(); + new_file.resize(new_file.size() + 1); + ucstring tvalue; + for(int j = 0; j < table_editor->columnCount(); j++) + { + QTableWidgetItem *item = table_editor->item(i, j); + tvalue.fromUtf8(std::string(item->text().toUtf8())); + new_file.setData(rowIdx, j + colIdx, tvalue); + } + } + if(hasHashValue) + { + // rewrite the hash codes + makeHashCode(wk_file, true); + } + ucstring s = prepareExcelSheet(new_file); + NLMISC::CI18N::writeTextFile(filename.toStdString(), s, false); + current_file = filename; + setCurrentFile(filename); +} + +void CEditorWorksheet::insertRow() +{ + int last_row = table_editor->rowCount(); + current_stack->push(new CUndoWorksheetNewCommand(table_editor, last_row)); +} + +void CEditorWorksheet::deleteRow() +{ + int selected_row = table_editor->currentRow(); + QMessageBox msgBox; + msgBox.setIcon(QMessageBox::Question); + msgBox.setText(tr("The row will be deleted.")); + msgBox.setInformativeText(tr("Do you want to delete the selected row ?")); + msgBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes); + msgBox.setDefaultButton(QMessageBox::No); + + int ret = msgBox.exec(); + if(ret == QMessageBox::Yes) + { + current_stack->push(new CUndoWorksheetDeleteCommand(table_editor, selected_row)); + } + table_editor->clearFocus(); + table_editor->clearSelection(); + return; +} + +void CEditorWorksheet::worksheetEditorCellEntered(QTableWidgetItem *item) +{ + temp_content = item->text(); + current_stack->push(new CUndoWorksheetCommand(table_editor, item, temp_content)); +} + +void CEditorWorksheet::worksheetEditorChanged(QTableWidgetItem *item) +{ + if(temp_content != item->text()) + { + //current_stack->push(new CUndoWorksheetCommand(table_editor, item, temp_content)); + } + + if(!isWindowModified()) + setWindowModified(true); +} + + +void CEditorWorksheet::extractBotNames(list filters, string level_design_path, NLLIGO::CLigoConfig ligoConfig) +{ + bool modified = false; + QList new_items; + + ExtractBotNames ebn; + ebn.setRequiredSettings(filters, level_design_path); + ebn.extractBotNamesFromPrimitives(ligoConfig); + // get SimpleNames + { + map SimpleNames = ebn.getSimpleNames(); + map::iterator it(SimpleNames.begin()), last(SimpleNames.end()); + + for (; it != last; ++it) + { + QList search_results = table_editor->findItems(QString(it->first.c_str()), Qt::MatchExactly); + if(search_results.size() == 0) + { + QList records; + records.push_back(QString(it->first.c_str())); + records.push_back(QString(it->first.c_str())); + records.push_back(QString(it->second.SheetName.c_str())); + insertTableRecords(records, new_items); + if(!modified) modified = true; + } + } + ebn.cleanSimpleNames(); + } + // get GenericNames + { + set GenericNames = ebn.getGenericNames(); + set::iterator it(GenericNames.begin()), last(GenericNames.end()); + for (; it != last; ++it) + { + string gnName = "gn_" + ebn.cleanupName(*it); + QList search_results = table_editor->findItems(QString((*it).c_str()), Qt::MatchExactly); + if(search_results.size() == 0) + { + QList records; + records.push_back(QString((*it).c_str())); + records.push_back(QString(gnName.c_str())); + records.push_back(" "); + insertTableRecords(records, new_items); + if(!modified) modified = true; + } + } + ebn.cleanGenericNames(); + } + + current_stack->push(new CUndoWorksheetExtraction(new_items, table_editor)); + if(modified) + { + setWindowModified(true); + table_editor->scrollToBottom(); + } + +} + +void CEditorWorksheet::extractWords(QString filename, QString columnId, IWordListBuilder &wordListBuilder) +{ + uint i; + + // **** Load the excel sheet + // load + STRING_MANAGER::TWorksheet workSheet; + if(!loadExcelSheet(filename.toStdString(), workSheet, true)) + { + nlwarning("Error reading '%s'. Aborted", filename.toStdString().c_str()); + return; + } + // get the key column index + uint keyColIndex = 0; + if(!workSheet.findCol(columnId.toStdString(), keyColIndex)) + { + nlwarning("Error: Don't find the column '%s'. '%s' Aborted", columnId.toStdString().c_str(), filename.toStdString().c_str()); + return; + } + // get the name column index + uint nameColIndex; + if(!workSheet.findCol(ucstring("name"), nameColIndex)) + { + nlwarning("Error: Don't find the column 'name'. '%s' Aborted", filename.toStdString().c_str()); + return; + } + + // **** List all words with the builder given + std::vector allWords; + if(!wordListBuilder.buildWordList(allWords, filename.toStdString())) + { + return; + } + bool modified = false; + QList new_items; + for(i = 0; i < allWords.size(); i++) + { + string keyName = allWords[i]; + QList search_results = table_editor->findItems(QString(keyName.c_str()), Qt::MatchExactly); + if(search_results.size() == 0) + { + int knPos = 0, nPos = 0; + if(workSheet.getData(0, 0) == ucstring("*HASH_VALUE")) + { + knPos = keyColIndex - 1; + nPos = nameColIndex - 1; + } + else + { + knPos = keyColIndex; + nPos = nameColIndex; + } + + QList records; + records.push_back(QString(keyName.c_str())); + records.push_back(QString("") + QString(keyName.c_str())); + insertTableRecords(records, new_items); + if(!modified) modified = true; + } + } + current_stack->push(new CUndoWorksheetExtraction(new_items, table_editor)); + if(modified) + { + setWindowModified(true); + table_editor->scrollToBottom(); + } +} + +void CEditorWorksheet::insertTableRecords(QList records, QList new_items) +{ + const int currentRow = table_editor->rowCount(); + table_editor->setRowCount(currentRow + 1); + int n = 0; + Q_FOREACH(QString record, records) + { + QTableWidgetItem *rec = new QTableWidgetItem(); + rec->setBackgroundColor(QColor("#F75D59")); + table_editor ->setItem(currentRow, n, rec); + CTableWidgetItemStore rec_s(rec, currentRow, n); + new_items.push_back(rec_s); + n++; + } +} + +bool CEditorWorksheet::compareWorksheetFile(QString filename) +{ + STRING_MANAGER::TWorksheet wk_file; + int colIndex = 0; + if(loadExcelSheet(filename.toStdString(), wk_file, true) == true) + { + if(wk_file.getData(0, 0) == ucstring("*HASH_VALUE")) + { + colIndex = 1; + } + if(wk_file.ColCount - colIndex != table_editor->columnCount()) + { + return false; + } + for(int i = 0; i < table_editor->columnCount(); i++) + { + QString item = table_editor->horizontalHeaderItem(i)->text(); + ucstring itemC = wk_file.getData(0, i+ colIndex); + if(item.toStdString() != itemC.toString()) + { + nlwarning(item.toStdString().c_str()); + nlwarning(itemC.toString().c_str()); + return false; + } + } + } + else + { + return false; + } + return true; +} + +void CEditorWorksheet::mergeWorksheetFile(QString filename) +{ + STRING_MANAGER::TWorksheet wk_file; + if(loadExcelSheet(filename.toStdString(), wk_file, true) == true) + { + bool hasHashValue = false; + int colIndex = 0; + if(wk_file.getData(0, 0) == ucstring("*HASH_VALUE")) + { + hasHashValue = true; + colIndex = 1; + } + // read rows + for(unsigned int i = 1; i < wk_file.size(); i++) + { + // search with the first column + ucstring rowId = wk_file.getData(i,colIndex); + QList search_results = table_editor->findItems(QString(rowId.toString().c_str()), Qt::MatchExactly); + if(search_results.size() == 0) + { + const int lastRow = table_editor->rowCount(); + table_editor->setRowCount(lastRow + 1); + for(int j = 0; j < table_editor->columnCount(); j++) + { + ucstring rowValue = wk_file.getData(i, j + colIndex); // get the value + QTableWidgetItem *row = new QTableWidgetItem(); + row->setText(QString(rowValue.toString().c_str())); // set the value in table item + table_editor->setItem(lastRow, j, row); + } + } + } + } + else + { + QErrorMessage error; + error.showMessage(tr("This file is not a worksheet file.")); + error.exec(); + } +} + +void CEditorWorksheet::closeEvent(QCloseEvent *event) +{ + if(isWindowModified()) + { + QMessageBox msgBox; + msgBox.setIcon(QMessageBox::Question); + msgBox.setText(tr("The document has been modified.")); + msgBox.setInformativeText(tr("Do you want to save your changes?")); + msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); + msgBox.setDefaultButton(QMessageBox::Save); + int ret = msgBox.exec(); + switch (ret) + { + case QMessageBox::Save: + save(); + break; + case QMessageBox::Discard: + break; + case QMessageBox::Cancel: + event->ignore(); + return; + } + } + event->accept(); + close(); +} + + +bool CEditorWorksheet::isBotNamesTable() +{ + bool status = true; + if(table_editor->horizontalHeaderItem(0)->text() != "bot name" + || table_editor->horizontalHeaderItem(1)->text() != "translated name" + || table_editor->horizontalHeaderItem(2)->text() != "sheet_name") + { + status = false; + } + return status; +} + +bool CEditorWorksheet::isSheetTable(QString type) +{ + QString column_name; + if(type.toAscii() == Constants::WK_ITEM) + { + column_name = "item ID"; + } + else if(type.toAscii() == Constants::WK_CREATURE) + { + column_name = "creature ID"; + } + else if(type.toAscii() == Constants::WK_SBRICK) + { + column_name = "sbrick ID"; + } + else if(type.toAscii() == Constants::WK_SPHRASE) + { + column_name = "sphrase ID"; + } + else if(type.toAscii() == Constants::WK_PLACE) + { + column_name = "placeId"; + } + bool status = true; + if(table_editor->horizontalHeaderItem(0)->text() != column_name + || table_editor->horizontalHeaderItem(1)->text() != "name") + { + status = false; + } + return status; +} + +} + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/editor_worksheet.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/editor_worksheet.h new file mode 100644 index 000000000..b60c7a534 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/editor_worksheet.h @@ -0,0 +1,216 @@ +// Translation Manager Plugin - OVQT Plugin +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Emanuel Costea +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef EDITOR_WORKSHEET_H +#define EDITOR_WORKSHEET_H + +// Project includes +#include "translation_manager_editor.h" +#include "extract_new_sheet_names.h" + +// Nel includes +#include "nel/misc/types_nl.h" +#include "nel/misc/sheet_id.h" +#include "nel/misc/path.h" +#include "nel/misc/diff_tool.h" +#include "nel/ligo/ligo_config.h" + +// Qt includes +#include +#include +#include +#include +#include +#include +#include + + +namespace TranslationManager +{ + +struct CTableWidgetItemStore +{ +public: + CTableWidgetItemStore(QTableWidgetItem *item, int row, int column) : + m_item(item), + m_row(row), + m_column(column) { } + + QTableWidgetItem *m_item; + int m_row; + int m_column; +}; + +class CEditorWorksheet : public CEditor +{ + Q_OBJECT + +public: + CEditorWorksheet(QMdiArea *parent) : CEditor(parent) {} + CEditorWorksheet() : CEditor() {} + QTableWidget *table_editor; + void open(QString filename); + void save(); + void saveAs(QString filename); + void activateWindow(); + void mergeWorksheetFile(QString filename); + bool compareWorksheetFile(QString filename); + void extractBotNames(std::list filters, std::string level_design_path, NLLIGO::CLigoConfig ligoConfig); + void extractWords(QString filename, QString columnId, IWordListBuilder &wordListBuilder); + void insertTableRecords(QList records, QList new_items); + bool isBotNamesTable(); + bool isSheetTable(QString type); + void closeEvent(QCloseEvent *event); + +private Q_SLOTS: + void worksheetEditorCellEntered(QTableWidgetItem *item); + void worksheetEditorChanged(QTableWidgetItem *item); + void insertRow(); + void deleteRow(); + void contextMenuEvent(QContextMenuEvent *e); + +private: + QString temp_content; +}; + +class CUndoWorksheetCommand : public QUndoCommand +{ +public: + CUndoWorksheetCommand(QTableWidget *table, QTableWidgetItem *item, const QString &ocontent, QUndoCommand *parent = 0) : QUndoCommand("Insert characters in cells", parent), m_table(table), m_item(item), m_ocontent(ocontent) + { + m_ccontent = m_ocontent; + } + + void redo() + { + if(m_item->text() == m_ocontent) + { + m_item->setText(m_ccontent); + } + } + void undo() + { + if(m_item->text() != m_ocontent) + { + m_ccontent = m_item->text(); + } + m_item->setText(m_ocontent); + } +private: + QTableWidget *m_table; + QTableWidgetItem *m_item; + QString m_ocontent; + QString m_ccontent; +}; + +class CUndoWorksheetNewCommand : public QUndoCommand +{ +public: + CUndoWorksheetNewCommand(QTableWidget *table, int rowID, QUndoCommand *parent = 0) : QUndoCommand("Insert a new row", parent), m_table(table), m_rowID(rowID) + { } + + void redo() + { + m_table->setRowCount(m_rowID + 1); + for(int j = 0; j < m_table->columnCount(); j++) + { + QTableWidgetItem *item = new QTableWidgetItem(); + m_table->setItem(m_rowID, j, item); + m_table->scrollToBottom(); + } + } + + void undo() + { + m_table->removeRow(m_rowID); + } + +private: + QTableWidget *m_table; + int m_rowID; +}; + +class CUndoWorksheetExtraction : public QUndoCommand +{ +public: + CUndoWorksheetExtraction(QList items, QTableWidget *table, QUndoCommand *parent = 0) : QUndoCommand("Word extraction", parent), + m_items(items), + m_table(table) + { } + + void redo() + { + Q_FOREACH(CTableWidgetItemStore is, m_items) + { + m_table->setItem(is.m_row, is.m_column, is.m_item); + } + } + + void undo() + { + Q_FOREACH(CTableWidgetItemStore is, m_items) + { + m_table->setItem(is.m_row, is.m_column, is.m_item); + m_table->takeItem(is.m_row, is.m_column); + } + } + +private: + QList m_items; + QTableWidget *m_table; +}; + +class CUndoWorksheetDeleteCommand : public QUndoCommand +{ +public: + CUndoWorksheetDeleteCommand(QTableWidget *table, int rowID, QUndoCommand *parent = 0) : QUndoCommand("Delete row", parent), m_table(table), m_rowID(rowID) + { } + + void redo() + { + for(int i = 0; i < m_table->columnCount(); i++) + { + QTableWidgetItem *item = new QTableWidgetItem(); + QTableWidgetItem *table_item = m_table->item(m_rowID, i); + item->setText(table_item->text()); + m_deletedItems.push_back(item); + } + m_table->removeRow(m_rowID); + } + + void undo() + { + int lastRow = m_table->rowCount(); + m_table->setRowCount(m_table->rowCount() + 1); + int i = 0; + Q_FOREACH(QTableWidgetItem* item, m_deletedItems) + { + m_table->setItem(lastRow, i, item); + i++; + } + m_deletedItems.clear(); + } + +private: + QList m_deletedItems; + QTableWidget *m_table; + int m_rowID; +}; + +} +#endif /* EDITOR_WORKSHEET_H */ + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/extract_bot_names.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/extract_bot_names.cpp new file mode 100644 index 000000000..ee65ca73c --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/extract_bot_names.cpp @@ -0,0 +1,366 @@ +// Translation Manager Plugin - OVQT Plugin +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Emanuel Costea +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "extract_bot_names.h" + +static bool RemoveOlds = false; + +namespace TranslationManager +{ + +TCreatureInfo *ExtractBotNames::getCreature(const std::string &sheetName) +{ + NLMISC::CSheetId id(sheetName+".creature"); + + if (Creatures.find(id) != Creatures.end()) + return &(Creatures.find(id)->second); + else + return NULL; +} + +std::string ExtractBotNames::cleanupName(const std::string &name) +{ + std::string ret; + + for (size_t i = 0; i < name.size(); ++i) + { + if (name[i] != ' ') + ret += name[i]; + else + ret += '_'; + } + return ret; +} + +ucstring ExtractBotNames::cleanupUcName(const ucstring &name) +{ + ucstring ret; + + for (size_t i = 0; i < name.size(); ++i) + { + if (name[i] != ' ') + ret += name[i]; + else + ret += '_'; + } + return ret; +} + + +/* + Removes first and last '$' +*/ +ucstring ExtractBotNames::makeGroupName(const ucstring &translationName) +{ + ucstring ret = translationName; + if (ret.size() >= 2) + { + if (*ret.begin() == ucchar('$')) + { + ret=ret.substr(1); + } + if (*ret.rbegin() == ucchar('$')) + { + ret = ret.substr(0, ret.size() - 1); + } + } + ret = cleanupUcName(ret); + return ret; +} + +std::set ExtractBotNames::getGenericNames() +{ + return GenericNames; +} + +std::map ExtractBotNames::getSimpleNames() +{ + return SimpleNames; +} + +void ExtractBotNames::cleanSimpleNames() +{ + SimpleNames.clear(); +} + +void ExtractBotNames::cleanGenericNames() +{ + GenericNames.clear(); +} + +std::string ExtractBotNames::removeAndStoreFunction(const std::string &fullName) +{ + std::string::size_type pos = fullName.find("$"); + if (pos == std::string::npos) + { + return fullName; + } + else + { + // extract and store the function name + std::string ret; + + ret = fullName.substr(0, pos); + std::string::size_type pos2 = fullName.find("$", pos+1); + + std::string fct = fullName.substr(pos + 1, pos2 - (pos + 1)); + + ret += fullName.substr(pos2 + 1); + + if (Functions.find(fct) == Functions.end()) + { + nldebug("Adding function '%s'", fct.c_str()); + Functions.insert(fct); + } + return ret; + } +} + +void ExtractBotNames::addGenericName(const std::string &name, const std::string &sheetName) +{ + TCreatureInfo *c = getCreature(sheetName); + if (!c || c->ForceSheetName || !c->DisplayName) + return; + + if (SimpleNames.find(name) != SimpleNames.end()) + { + nldebug("Name '%s' is now a generic name", name.c_str()); + GenericNames.insert(name); + SimpleNames.erase(name); + + } + else if (GenericNames.find(name) == GenericNames.end()) + { + nldebug("Adding generic name '%s'", name.c_str()); + GenericNames.insert(name); + } +} + +void ExtractBotNames::addSimpleName(const std::string &name, const std::string &sheetName) +{ + TCreatureInfo *c = getCreature(sheetName); + if (!c || c->ForceSheetName || !c->DisplayName) + return; + + if (SimpleNames.find(name) != SimpleNames.end()) + { + addGenericName(name, sheetName); + } + else if (GenericNames.find(name) != GenericNames.end()) + { + return; + } + else + { + nldebug("Adding simple name '%s'", name.c_str()); + + TEntryInfo ei; + ei.SheetName = sheetName; + + SimpleNames.insert(make_pair(name, ei)); + } +} + +void ExtractBotNames::setRequiredSettings(std::list filters, std::string level_design_path) +{ + for (std::list::iterator it = filters.begin(); it != filters.end(); ++it) + { + Filters.push_back(*it); + } + + //------------------------------------------------------------------- + // init the sheets + NLMISC::CSheetId::init(false); + const std::string PACKED_SHEETS_NAME = "bin/translation_tools_creature.packed_sheets"; + loadForm("creature", PACKED_SHEETS_NAME, Creatures, false, false); + + if (Creatures.empty()) + { + loadForm("creature", PACKED_SHEETS_NAME, Creatures, true); + } +} + +void ExtractBotNames::extractBotNamesFromPrimitives(NLLIGO::CLigoConfig ligoConfig) +{ + //------------------------------------------------------------------- + // ok, ready for the real work, + // first, read the primitives files and parse the primitives + std::vector files; + NLMISC::CPath::getFileList("primitive", files); + + for (uint i=0; i ps; + ps.buildSet(primDoc.RootNode, pred, result); + + for (uint i = 0; i < result.size(); ++i) + { + std::string name; + std::string countStr; + std::string sheetStr; + result[i]->getPropertyByName("name", name); + result[i]->getPropertyByName("count", countStr); + result[i]->getPropertyByName("bot_sheet_look", sheetStr); + + uint32 count; + NLMISC::fromString(countStr, count); + + if (count != 0) + { + if (sheetStr.empty()) + { + nlwarning("In '%s', empty sheet !", buildPrimPath(result[i]).c_str()); + } + else + { + addGenericName(removeAndStoreFunction(name), sheetStr); + } + } + } + } + // look for bot template + { + NLLIGO::TPrimitiveClassPredicate pred("bot_template_npc"); + NLLIGO::TPrimitiveSet result; + + NLLIGO::CPrimitiveSet ps; + ps.buildSet(primDoc.RootNode, pred, result); + + for (size_t i = 0; i < result.size(); ++i) + { + std::string name; + std::string sheetStr; + result[i]->getPropertyByName("name", name); + result[i]->getPropertyByName("sheet_look", sheetStr); + + if (sheetStr.empty()) + { + // take the sheet in the parent + result[i]->getParent()->getPropertyByName("bot_sheet_look", sheetStr); + } + + if (sheetStr.empty()) + { + nlwarning("In '%s', empty sheet !", buildPrimPath(result[i]).c_str()); + } + else + { + addGenericName(removeAndStoreFunction(name), sheetStr); + } + } + } + // look for npc_group + { + NLLIGO::TPrimitiveClassPredicate pred("npc_group"); + NLLIGO::TPrimitiveSet result; + + NLLIGO::CPrimitiveSet ps; + ps.buildSet(primDoc.RootNode, pred, result); + + for (size_t i = 0; i < result.size(); ++i) + { + std::string name; + std::string countStr; + std::string sheetStr; + result[i]->getPropertyByName("name", name); + result[i]->getPropertyByName("count", countStr); + result[i]->getPropertyByName("bot_sheet_client", sheetStr); + + uint32 count; + NLMISC::fromString(countStr, count); + + if (count > 0 && sheetStr.empty()) + { + nlwarning("In '%s', empty sheet !", buildPrimPath(result[i]).c_str()); + } + else + { + if (count == 1) + { + addSimpleName(removeAndStoreFunction(name), sheetStr); + } + else if (count > 1) + { + addGenericName(removeAndStoreFunction(name), sheetStr); + } + } + } + } + // look for bot + { + NLLIGO::TPrimitiveClassPredicate pred("npc_bot"); + NLLIGO::TPrimitiveSet result; + + NLLIGO::CPrimitiveSet ps; + ps.buildSet(primDoc.RootNode, pred, result); + + for (size_t i = 0; i < result.size(); ++i) + { + std::string name; + std::string sheetStr; + result[i]->getPropertyByName("name", name); + result[i]->getPropertyByName("sheet_client", sheetStr); + + if (sheetStr.empty()) + { + // take the sheet in the parent + result[i]->getParent()->getPropertyByName("bot_sheet_client", sheetStr); + } + + if (sheetStr.empty()) + { + nlwarning("In '%s', empty sheet !", buildPrimPath(result[i]).c_str()); + } + else + { + addSimpleName(removeAndStoreFunction(name), sheetStr); + } + } + } + } +} + +} \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/extract_bot_names.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/extract_bot_names.h new file mode 100644 index 000000000..208b4db5c --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/extract_bot_names.h @@ -0,0 +1,99 @@ +// Translation Manager Plugin - OVQT Plugin +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Emanuel Costea +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef EXTRACT_BOT_NAMES_H +#define EXTRACT_BOT_NAMES_H + +#include "nel/misc/types_nl.h" +#include "nel/misc/config_file.h" +#include "nel/misc/sheet_id.h" +#include "nel/misc/path.h" +#include "nel/misc/diff_tool.h" +#include "nel/georges/u_form.h" +#include "nel/georges/u_form_elm.h" +#include "nel/georges/load_form.h" +#include "nel/ligo/ligo_config.h" +#include "nel/ligo/primitive.h" +#include "nel/ligo/primitive_utils.h" + +namespace TranslationManager +{ + +struct TCreatureInfo +{ + NLMISC::CSheetId SheetId; + bool ForceSheetName; + bool DisplayName; + + void readGeorges(const NLMISC::CSmartPtr &form, const NLMISC::CSheetId &sheetId) + { + const NLGEORGES::UFormElm &item=form->getRootNode(); + + SheetId=sheetId; + item.getValueByName(ForceSheetName, "3d data.ForceDisplayCreatureName"); + item.getValueByName(DisplayName, "3d data.DisplayName"); + } + + void serial(NLMISC::IStream &f) + { + f.serial(SheetId); + f.serial(ForceSheetName); + f.serial(DisplayName); + } + + static uint getVersion () + { + return 1; + } + + void removed() + { + } +}; + +struct TEntryInfo +{ + std::string SheetName; +}; + +struct ExtractBotNames +{ +private: + std::vector Filters; + std::map Creatures; + std::set GenericNames; + std::map SimpleNames; + std::set Functions; +private: + TCreatureInfo *getCreature(const std::string &sheetName); + ucstring makeGroupName(const ucstring &translationName); + std::string removeAndStoreFunction(const std::string &fullName); + void addGenericName(const std::string &name, const std::string &sheetName); + void addSimpleName(const std::string &name, const std::string &sheetName); +public: + void extractBotNamesFromPrimitives(NLLIGO::CLigoConfig ligoConfig); + void setRequiredSettings(std::list filters, std::string level_design_path); + std::set getGenericNames(); + std::map getSimpleNames(); + std::string cleanupName(const std::string &name); + ucstring cleanupUcName(const ucstring &name); + void cleanSimpleNames(); + void cleanGenericNames(); +}; +} + +#endif /* EXTRACT_BOT_NAMES_H */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/extract_new_sheet_names.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/extract_new_sheet_names.cpp new file mode 100644 index 000000000..984f86d17 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/extract_new_sheet_names.cpp @@ -0,0 +1,150 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "extract_new_sheet_names.h" + +namespace TranslationManager +{ + +// *************************************************************************** +/* + * Specialisation of IWordListBuilder to list sheets in a directory + */ + +bool CSheetWordListBuilder::buildWordList(std::vector &allWords, std::string workSheetFileName) +{ + SheetExt = NLMISC::toLower(SheetExt); + // verify the directory is correct + if(!NLMISC::CFile::isDirectory(SheetPath)) + { + nlwarning("Error: Directory '%s' not found. '%s' Aborted", SheetPath.c_str(), workSheetFileName.c_str()); + return false; + } + + // list all files. + std::vector allFiles; + allFiles.reserve(100000); + NLMISC::CPath::getPathContent(SheetPath, true, false, true, allFiles, NULL); + + // Keep only the extension we want, and remove "_" (parent) + allWords.clear(); + allWords.reserve(allFiles.size()); + for(size_t i = 0; i < allFiles.size(); i++) + { + std::string fileNameWithoutExt = NLMISC::CFile::getFilenameWithoutExtension(allFiles[i]); + std::string extension = NLMISC::toLower(NLMISC::CFile::getExtension(allFiles[i])); + + // bad extension? + if(extension!=SheetExt) + continue; + + // parent? + if(fileNameWithoutExt.empty() || fileNameWithoutExt[0] == '_') + continue; + + // ok, add + allWords.push_back(NLMISC::toLower(fileNameWithoutExt)); + } + return true; +} + +// *************************************************************************** +/* + * Specialisation of IWordListBuilder to list new region/place name from .primitive + */ +bool CRegionPrimWordListBuilder::buildWordList(std::vector &allWords, std::string workSheetFileName) +{ + // verify the directory is correct + if(!NLMISC::CFile::isDirectory(PrimPath)) + { + nlwarning("Error: Directory '%s' not found. '%s' Aborted", PrimPath.c_str(), workSheetFileName.c_str()); + return false; + } + + // list all files. + std::vector allFiles; + allFiles.reserve(100000); + NLMISC::CPath::getPathContent(PrimPath, true, false, true, allFiles, NULL); + + // parse all primitive that match the filter + allWords.clear(); + allWords.reserve(100000); + // to avoid duplicate + std::set allWordSet; + for(size_t i = 0; i < allFiles.size(); i++) + { + std::string fileName = NLMISC::CFile::getFilename(allFiles[i]); + // filter don't match? + bool oneMatch= false; + for(size_t filter = 0; filter < PrimFilter.size(); filter++) + { + if(NLMISC::testWildCard(fileName, PrimFilter[filter])) + oneMatch= true; + } + if(!oneMatch) + continue; + + // ok, read the file + NLLIGO::CPrimitives PrimDoc; + NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = &PrimDoc; + if (!NLLIGO::loadXmlPrimitiveFile(PrimDoc, allFiles[i], LigoConfig)) + { + nlwarning("Error: cannot open file '%s'. '%s' Aborted", allFiles[i].c_str(), workSheetFileName.c_str()); + NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL; + return false; + } + NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL; + + // For all primitives of interest + const char *listClass[] = {"continent", "region", "place", "stable", + "teleport_destination", "room_template" + }; + + const char *listProp[] = {"name", "name", "name", "name", + "place_name", "place_name" + }; + + const uint numListClass= sizeof(listClass)/sizeof(listClass[0]); + const uint numListProp= sizeof(listProp)/sizeof(listProp[0]); + nlctassert(numListProp == numListClass); + for(uint cid = 0; cid < numListClass; cid++) + { + // parse the whole hierarchy + NLLIGO::TPrimitiveClassPredicate predCont(listClass[cid]); + NLLIGO::CPrimitiveSet setPlace; + NLLIGO::TPrimitiveSet placeRes; + setPlace.buildSet(PrimDoc.RootNode, predCont, placeRes); + + // for all found + for (size_t placeId = 0; placeId < placeRes.size(); ++placeId) + { + std::string primName; + if(placeRes[placeId]->getPropertyByName(listProp[cid], primName) && !primName.empty()) + { + primName = NLMISC::toLower(primName); + // avoid duplicate + if(allWordSet.insert(primName).second) + { + allWords.push_back(primName); + } + } + } + } + } + return true; +} + +} \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/extract_new_sheet_names.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/extract_new_sheet_names.h new file mode 100644 index 000000000..01d0f1a0a --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/extract_new_sheet_names.h @@ -0,0 +1,63 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef EXTRACT_NEW_SHEET_NAMES_H +#define EXTRACT_NEW_SHEET_NAMES_H + +#include "nel/misc/types_nl.h" +#include "nel/misc/config_file.h" +#include "nel/misc/sheet_id.h" +#include "nel/misc/path.h" +#include "nel/misc/diff_tool.h" +#include "nel/misc/algo.h" +#include "nel/georges/u_form.h" +#include "nel/georges/u_form_elm.h" +#include "nel/georges/load_form.h" +#include "nel/ligo/ligo_config.h" +#include "nel/ligo/primitive.h" +#include "nel/ligo/primitive_utils.h" + +namespace TranslationManager +{ + +// *************************************************************************** +/* + * Interface to build the whole list of words (key id) for a specific worksheet + */ +struct IWordListBuilder +{ + virtual bool buildWordList(std::vector &allWords, std::string workSheetFileName) =0; +}; + +struct CSheetWordListBuilder : public IWordListBuilder +{ + std::string SheetExt; + std::string SheetPath; + + virtual bool buildWordList(std::vector &allWords, std::string workSheetFileName); +}; + +struct CRegionPrimWordListBuilder : public IWordListBuilder +{ + std::string PrimPath; + std::vector PrimFilter; + NLLIGO::CLigoConfig LigoConfig; + virtual bool buildWordList(std::vector &allWords, std::string workSheetFileName); +}; + +} + +#endif /* EXTRACT_NEW_SHEET_NAMES_H */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/ftp_selection.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/ftp_selection.cpp new file mode 100644 index 000000000..876599b61 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/ftp_selection.cpp @@ -0,0 +1,216 @@ +// Translation Manager Plugin - OVQT Plugin +// Copyright (C) 2011 Emanuel Costea +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "ftp_selection.h" + +#include +#include + +namespace TranslationManager +{ +CFtpSelection::CFtpSelection(QWidget *parent): QDialog(parent) +{ + _ui.setupUi(this); + connect(_ui.connectButton, SIGNAL(clicked()), this, SLOT(ConnectButtonClicked())); + connect(_ui.doneButton, SIGNAL(clicked()), this, SLOT(DoneButtonClicked())); + connect(_ui.cdToParrent, SIGNAL(clicked()), this, SLOT(cdToParent())); + connect(_ui.cancelButton, SIGNAL(clicked()), this, SLOT(reject())); + + // file list + connect(_ui.fileList, SIGNAL(itemActivated(QTreeWidgetItem *,int)),this, SLOT(processItem(QTreeWidgetItem *,int))); + _ui.fileList->setEnabled(false); + _ui.fileList->setRootIsDecorated(false); + _ui.fileList->setHeaderLabels(QStringList() << tr("Name") << tr("Size") << tr("Owner") << tr("Group") << tr("Time")); + _ui.fileList->header()->setStretchLastSection(false); + + // buttons + _ui.cdToParrent->setEnabled(false); + _ui.doneButton->setEnabled(false); + + status = false; +} + +// Connection with the FTP Server. We retrieve the file list. +void CFtpSelection::ConnectButtonClicked() +{ + conn = new QFtp(this); + connect(conn, SIGNAL(commandFinished(int,bool)), this, SLOT(FtpCommandFinished(int,bool))); + connect(conn, SIGNAL(listInfo(QUrlInfo)), this, SLOT(AddToList(QUrlInfo))); + + setCursor(Qt::WaitCursor); + + QUrl url(_ui.url->text()); + if (!url.isValid() || url.scheme().toLower() != QLatin1String("ftp")) + { + conn->connectToHost(_ui.url->text(), 21); + conn->login(); + } + else + { + conn->connectToHost(url.host(), url.port(21)); + + if (!url.userName().isEmpty()) + conn->login(QUrl::fromPercentEncoding(url.userName().toLatin1()), url.password()); + else + conn->login(); + if (!url.path().isEmpty()) + conn->cd(url.path()); + } +} + +// Get the user action. +void CFtpSelection::FtpCommandFinished(int, bool error) +{ + setCursor(Qt::ArrowCursor); + + if (conn->currentCommand() == QFtp::ConnectToHost) + { + if (error) + { + QMessageBox::information(this, tr("FTP"), + tr("Unable to connect to the FTP server " + "at %1. Please check that the host " + "name is correct.") + .arg(_ui.url->text())); + return; + } + + return; + } + + if (conn->currentCommand() == QFtp::Login) + { + conn->list(); + } + + if (conn->currentCommand() == QFtp::Get) + { + if(error) + { + status = false; + file->close(); + file->remove(); + } + else + { + file->close(); + status = true; + } + _ui.cancelButton->setEnabled(true); + } + + if (conn->currentCommand() == QFtp::List) + { + if (isDirectory.isEmpty()) + { + _ui.fileList->addTopLevelItem(new QTreeWidgetItem(QStringList() << tr(""))); + _ui.fileList->setEnabled(false); + } + } +} +// Make the file list with directories and files +void CFtpSelection::AddToList(const QUrlInfo &urlInfo) +{ + QTreeWidgetItem *item = new QTreeWidgetItem; + item->setText(0, urlInfo.name()); + item->setText(1, QString::number(urlInfo.size())); + item->setText(2, urlInfo.owner()); + item->setText(3, urlInfo.group()); + item->setText(4, urlInfo.lastModified().toString("MMM dd yyyy")); + + QPixmap pixmap(urlInfo.isDir() ? ":/translationManager/images/dir.png" : ":/translationManager/images/file.png"); + item->setIcon(0, pixmap); + + isDirectory[urlInfo.name()] = urlInfo.isDir(); + _ui.fileList->addTopLevelItem(item); + if (!_ui.fileList->currentItem()) + { + _ui.fileList->setCurrentItem(_ui.fileList->topLevelItem(0)); + _ui.fileList->setEnabled(true); + } +} + +void CFtpSelection::processItem(QTreeWidgetItem *item, int) +{ + QString name = item->text(0); + if (isDirectory.value(name)) + { + _ui.fileList->clear(); + isDirectory.clear(); + currentPath += '/'; + currentPath += name; + conn->cd(name); + conn->list(); + + setCursor(Qt::WaitCursor); + return; + } + _ui.doneButton->setEnabled(true); +} + +// Exit from a directory +void CFtpSelection::cdToParent() +{ + setCursor(Qt::WaitCursor); + + _ui.fileList->clear(); + isDirectory.clear(); + currentPath = currentPath.left(currentPath.lastIndexOf('/')); + if (currentPath.isEmpty()) + { + _ui.cdToParrent->setEnabled(false); + conn->cd("/"); + } + else + { + conn->cd(currentPath); + } + conn->list(); +} + +// Done action +void CFtpSelection::DoneButtonClicked() +{ + QString fileName = _ui.fileList->currentItem()->text(0); + + if (QFile::exists(fileName)) + { + QMessageBox::information(this, tr("FTP"), + tr("There already exists a file called %1 in " + "the current directory.") + .arg(fileName)); + return; + } + + file = new QFile(fileName); + + setCursor(Qt::WaitCursor); + + if (!file->open(QIODevice::WriteOnly)) + { + QMessageBox::information(this, tr("FTP"), + tr("Unable to save the file %1: %2.") + .arg(fileName).arg(file->errorString())); + delete file; + return; + } + _ui.cancelButton->setEnabled(false); + conn->get(_ui.fileList->currentItem()->text(0), file); + + reject(); +} + +} diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/ftp_selection.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/ftp_selection.h new file mode 100644 index 000000000..9f8af85dd --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/ftp_selection.h @@ -0,0 +1,50 @@ +/* + * File: ftp_selection.h + * Author: cemycc + * + * Created on July 8, 2011, 4:03 PM + */ + +#ifndef FTP_SELECTION_H +#define FTP_SELECTION_H + +#include "ui_ftp_selection.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace TranslationManager +{ + +class CFtpSelection : public QDialog +{ + Q_OBJECT + +public: + CFtpSelection(QWidget *parent = 0); + ~CFtpSelection() {} + bool status; + QFile *file; + +private Q_SLOTS: + void cdToParent(); + void processItem(QTreeWidgetItem *,int); + void ConnectButtonClicked(); + void DoneButtonClicked(); + void FtpCommandFinished(int, bool error); + void AddToList(const QUrlInfo &urlInfo); + +private: + Ui::FtpSelectionDialog _ui; + QFtp *conn; + QHash isDirectory; + QString currentPath; +}; +} + +#endif /* FTP_SELECTION_H */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/ftp_selection.qrc b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/ftp_selection.qrc new file mode 100644 index 000000000..bd54366ed --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/ftp_selection.qrc @@ -0,0 +1,7 @@ + + + images/cdtoparent.png + images/dir.png + images/file.png + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/ftp_selection.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/ftp_selection.ui new file mode 100644 index 000000000..7b3041c04 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/ftp_selection.ui @@ -0,0 +1,120 @@ + + + FtpSelectionDialog + + + + 0 + 0 + 640 + 576 + + + + Dialog + + + + + + FTP Server informations + + + + + + + + Ftp server + + + + + + + + + + + + + + :/translationManager/images/cdtoparent.png:/translationManager/images/cdtoparent.png + + + + + + + Connect + + + + + + + + + Content + + + + + + Please select the file + + + + + + + + 1 + + + + + + + + Qt::Vertical + + + + 20 + 378 + + + + + + + + + + + + + Done + + + + + + + Cancel + + + + + + + + + + + + + + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/images/cdtoparent.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/images/cdtoparent.png new file mode 100644 index 000000000..24b618082 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/images/cdtoparent.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/images/dir.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/images/dir.png new file mode 100644 index 000000000..0ce5ae75f Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/images/dir.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/images/file.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/images/file.png new file mode 100644 index 000000000..be6c53089 Binary files /dev/null and b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/images/file.png differ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/ovqt_plugin_translation_manager.xml b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/ovqt_plugin_translation_manager.xml new file mode 100644 index 000000000..93a7f19bf --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/ovqt_plugin_translation_manager.xml @@ -0,0 +1,10 @@ + + ovqt_plugin_translation_manager + TranslationManager + 0.8 + Ryzom Core + Translation Manager plugin. + + + + \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/source_selection.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/source_selection.cpp new file mode 100644 index 000000000..518906db0 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/source_selection.cpp @@ -0,0 +1,60 @@ +// Translation Manager Plugin - OVQT Plugin +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Emanuel Costea +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "source_selection.h" + +#include + +namespace TranslationManager +{ + +CSourceDialog::CSourceDialog(QWidget *parent): QDialog(parent) +{ + _ui.setupUi(this); + + connect(_ui.ok_button, SIGNAL(clicked()), this, SLOT(OkButtonClicked())); + connect(_ui.cancel_button, SIGNAL(clicked()), this, SLOT(reject())); + + _ui.sourceSelectionListWidget->setSortingEnabled(false); + connect(_ui.sourceSelectionListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem *)), + this, SLOT(itemDoubleClicked(QListWidgetItem *))); +} + +// Insert options in the source dialog. Options like: from FTP Server, from Local directory etc. +void CSourceDialog::setSourceOptions(std::map &options) +{ + std::map::iterator it; + + for(it = options.begin(); it != options.end(); ++it) + { + _ui.sourceSelectionListWidget->addItem((*it).first); + } +} + +void CSourceDialog::OkButtonClicked() +{ + selected_item = _ui.sourceSelectionListWidget->currentItem(); + accept(); +} + +void CSourceDialog::itemDoubleClicked(QListWidgetItem *item) +{ + selected_item = item; + accept(); +} + +} \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/source_selection.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/source_selection.h new file mode 100644 index 000000000..7b6fc2cb9 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/source_selection.h @@ -0,0 +1,54 @@ +// Translation Manager Plugin - OVQT Plugin +// Copyright (C) 2011 Emanuel Costea +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef SOURCE_SELECTION_H +#define SOURCE_SELECTION_H + +#include "ui_source_selection.h" + +#include +#include +#include +#include + +#include + +namespace TranslationManager +{ + +class CSourceDialog : public QDialog +{ + Q_OBJECT + +public: + CSourceDialog(QWidget *parent = 0); + ~CSourceDialog() {} + void setSourceOptions(std::map &options); + QListWidgetItem *selected_item; + +private Q_SLOTS: + void OkButtonClicked(); + void itemDoubleClicked(QListWidgetItem *item); + +private: + Ui::SourceSelectionDialog _ui; +}; + +} + + +#endif /* SOURCE_SELECTION_H */ + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/source_selection.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/source_selection.ui new file mode 100644 index 000000000..e64ba78c4 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/source_selection.ui @@ -0,0 +1,60 @@ + + + SourceSelectionDialog + + + Qt::WindowModal + + + true + + + + 0 + 0 + 316 + 155 + + + + Dialog + + + true + + + + + + Select source for merge operation + + + + + + + + + + + OK + + + + + + + Cancel + + + + + + + + + + + + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_constants.h new file mode 100644 index 000000000..d72a2b223 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_constants.h @@ -0,0 +1,39 @@ +// Translation Manager Plugin - OVQT Plugin +// Copyright (C) 2011 Emanuel Costea +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef TRANSLATION_MANAGER_CONSTANTS_H +#define TRANSLATION_MANAGER_CONSTANTS_H + +namespace TranslationManager +{ +namespace Constants +{ +const int ED_SHEET = 1; +const int ED_PHRASE = 2; + +const char *const WK_BOTNAMES = "bot_names_wk.txt"; +const char *const WK_ITEM = "item_words_wk.txt"; +const char *const WK_CREATURE = "creature_words_wk.txt"; +const char *const WK_SBRICK = "sbrick_words_wk.txt"; +const char *const WK_SPHRASE = "sphrase_words_wk.txt"; +const char *const WK_PLACE = "place_words_wk.txt"; +const char *const WK_CONTINENT = "place_words_wk.txt"; +const char *const WK_STABLE = "place_words_wk.txt"; +} +} + +#endif /* TRANSLATION_MANAGER_CONSTANTS_H */ + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_editor.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_editor.h new file mode 100644 index 000000000..fd53ba863 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_editor.h @@ -0,0 +1,71 @@ +// Translation Manager Plugin - OVQT Plugin +// Copyright (C) 2011 Emanuel Costea +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef TRANSLATION_MANAGER_EDITOR_H +#define TRANSLATION_MANAGER_EDITOR_H + +#include +#include +#include +#include +#include +#include + +namespace TranslationManager +{ + +class CEditor : public QMdiSubWindow +{ + Q_OBJECT + +public: + CEditor(QMdiArea *parent) : QMdiSubWindow(parent) {} + CEditor() : QMdiSubWindow() {} + virtual void open(QString filename) =0; + virtual void save() =0; + virtual void saveAs(QString filename) =0; + virtual void activateWindow() =0; + + int eType() + { + return editor_type; + } + QString subWindowFilePath() + { + return current_file; + } + void setUndoStack(QUndoStack *stack) + { + current_stack = stack; + } + void setCurrentFile(QString filename) + { + QFileInfo *file = new QFileInfo(filename); + current_file = file->canonicalFilePath(); + setWindowModified(false); + setWindowTitle(file->fileName() + "[*]"); + setWindowFilePath(current_file); + } + +protected: + QUndoStack *current_stack; + QString current_file; + int editor_type; +}; + +} + +#endif /* TRANSLATION_MANAGER_EDITOR_H */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_main_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_main_window.cpp new file mode 100644 index 000000000..46a0dd99f --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_main_window.cpp @@ -0,0 +1,654 @@ +// Translation Manager Plugin - OVQT Plugin +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Emanuel Costea +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Plugin includes +#include "translation_manager_main_window.h" +#include "translation_manager_constants.h" +#include "ftp_selection.h" + +// Core includes +#include "../core/icore.h" +#include "../core/core_constants.h" +#include "../core/menu_manager.h" +#include "../../extension_system/iplugin_spec.h" + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace TranslationManager +{ + +CMainWindow::CMainWindow(QWidget *parent) + : QMainWindow(parent) +{ + _ui.setupUi(this); + + _ui.mdiArea->closeAllSubWindows(); + windowMapper = new QSignalMapper(this); + connect(windowMapper, SIGNAL(mapped(QWidget *)), this, SLOT(setActiveSubWindow(QWidget *))); + + initialize_settings["georges"] = false; + initialize_settings["ligo"] = false; + + connect(Core::ICore::instance(), SIGNAL(changeSettings()), this, SLOT(readSettings())); + readSettings(); + createToolbar(); + m_undoStack = new QUndoStack(this); + +} + +// Functions that will insert the plugin buttons +void CMainWindow::createToolbar() +{ + // File menu + openAct = new QAction(QIcon(Core::Constants::ICON_OPEN), "&Open file(s)...", this); + _ui.toolBar->addAction(openAct); + connect(openAct, SIGNAL(triggered()), this, SLOT(open())); + saveAct = new QAction(QIcon(Core::Constants::ICON_SAVE), "&Save...", this); + _ui.toolBar->addAction(saveAct); + connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); + saveAsAct = new QAction(QIcon(Core::Constants::ICON_SAVE_AS), "&Save as...", this); + _ui.toolBar->addAction(saveAsAct); + connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs())); + + // Tools menu + QMenu *wordsExtractionMenu = new QMenu("&Words extraction..."); + wordsExtractionMenu->setIcon(QIcon(Core::Constants::ICON_SETTINGS)); + _ui.toolBar->addAction(wordsExtractionMenu->menuAction()); + + // extract bot names + QAction *extractBotNamesAct = wordsExtractionMenu->addAction("&Extract bot names..."); + extractBotNamesAct->setStatusTip(tr("Extract bot names from primitives.")); + connect(extractBotNamesAct, SIGNAL(triggered()), this, SLOT(extractBotNames())); + + // Words extraction + QSignalMapper *wordsExtractionMapper = new QSignalMapper(this); + connect(wordsExtractionMapper, SIGNAL(mapped(QString)), this, SLOT(extractWords(QString))); + // extract item words + + QAction *extractItemWordsAct = wordsExtractionMenu->addAction("&Extract item words..."); + extractItemWordsAct->setStatusTip(tr("Extract item words")); + connect(extractItemWordsAct, SIGNAL(triggered()), wordsExtractionMapper, SLOT(map())); + wordsExtractionMapper->setMapping(extractItemWordsAct, QString(Constants::WK_ITEM)); + + // extract creature words + QAction *extractCreatureWordsAct = wordsExtractionMenu->addAction(tr("&Extract creature words...")); + extractCreatureWordsAct->setStatusTip(tr("Extract creature words")); + connect(extractCreatureWordsAct, SIGNAL(triggered()), wordsExtractionMapper, SLOT(map())); + wordsExtractionMapper->setMapping(extractCreatureWordsAct, QString(Constants::WK_CREATURE)); + + // extract sbrick words + QAction *extractSbrickWordsAct = wordsExtractionMenu->addAction("&Extract sbrick words..."); + extractSbrickWordsAct->setStatusTip(tr("Extract sbrick words")); + connect(extractSbrickWordsAct, SIGNAL(triggered()), wordsExtractionMapper, SLOT(map())); + wordsExtractionMapper->setMapping(extractSbrickWordsAct, QString(Constants::WK_SBRICK)); + + // extract sphrase words + QAction *extractSphraseWordsAct = wordsExtractionMenu->addAction("&Extract sphrase words..."); + extractSphraseWordsAct->setStatusTip(tr("Extract sphrase words")); + connect(extractSphraseWordsAct, SIGNAL(triggered()), wordsExtractionMapper, SLOT(map())); + wordsExtractionMapper->setMapping(extractSphraseWordsAct, QString(Constants::WK_SPHRASE)); + + // extract place and region names + QAction *extractPlaceNamesAct = wordsExtractionMenu->addAction("&Extract place names..."); + extractPlaceNamesAct->setStatusTip(tr("Extract place names from primitives")); + connect(extractPlaceNamesAct, SIGNAL(triggered()), wordsExtractionMapper, SLOT(map())); + wordsExtractionMapper->setMapping(extractPlaceNamesAct, QString(Constants::WK_PLACE)); + + // Merge options + QAction *mergeSingleFileAct = wordsExtractionMenu->addAction("&Merge worksheet file..."); + mergeSingleFileAct->setStatusTip(tr("Merge worksheet file from local or remote directory")); + connect(mergeSingleFileAct, SIGNAL(triggered()), this, SLOT(mergeSingleFile())); + + // Windows menu + Core::ICore *core = Core::ICore::instance(); + Core::MenuManager *menuManager = core->menuManager(); + windowMenu = menuManager->menuBar()->addMenu("Window"); + updateWindowsList(); + connect(windowMenu, SIGNAL(aboutToShow()), this, SLOT(updateWindowsList())); + + // Undo, Redo actions + QAction *undoAction = menuManager->action(Core::Constants::UNDO); + if (undoAction != 0) + _ui.toolBar->addAction(undoAction); + + QAction *redoAction = menuManager->action(Core::Constants::REDO); + if (redoAction != 0) + _ui.toolBar->addAction(redoAction); +} + +// Update the toolbar if the editor is worksheet +void CMainWindow::updateToolbar(QMdiSubWindow *window) +{ + if(_ui.mdiArea->subWindowList().size() > 0) + if(QString(window->widget()->metaObject()->className()) == "QTableWidget") // Sheet Editor + { + QAction *insertRowAct = new QAction(tr("Insert new row"), this); + connect(insertRowAct, SIGNAL(triggered()), window, SLOT(insertRow())); + windowMenu->addAction(insertRowAct); + QAction *deleteRowAct = new QAction(tr("Delete row"), this); + connect(deleteRowAct, SIGNAL(triggered()), window, SLOT(deleteRow())); + windowMenu->addAction(deleteRowAct); + } +} + +// Set the active subwindow +void CMainWindow::setActiveSubWindow(QWidget *window) +{ + if (!window) + return; + + QMdiSubWindow *mdiWindow = qobject_cast(window); + if (mdiWindow != 0) + _ui.mdiArea->setActiveSubWindow(mdiWindow); +} + +// Functions for updating the windows list +void CMainWindow::updateWindowsList() +{ + if(_ui.mdiArea->activeSubWindow()) + { + windowMenu->clear(); + QMdiSubWindow *current_window = _ui.mdiArea->activeSubWindow(); + QList subWindows = _ui.mdiArea->subWindowList(); + + updateToolbar(current_window); + + for(int i = 0; i < subWindows.size(); ++i) + { + QString window_file = QFileInfo(subWindows.at(i)->windowFilePath()).fileName(); + QString action_text; + if (i < 9) + { + action_text = QString("&%1 %2").arg(i + 1).arg(window_file); + } + else + { + action_text = QString("%1 %2").arg(i + 1).arg(window_file); + } + QAction *action = new QAction(action_text, this); + action->setCheckable(true); + action->setChecked(subWindows.at(i) == current_window); + connect(action, SIGNAL(triggered()), windowMapper, SLOT(map())); + windowMenu->addAction(action); + windowMapper->setMapping(action, subWindows.at(i)); + } + } + else + { + windowMenu->clear(); + } +} + +// Open signal +void CMainWindow::open() +{ + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup("translationmanager"); + QString lastOpenLocation = settings->value("lastOpenLocation").toString(); + QString file_name = QFileDialog::getOpenFileName(this, tr("Open translation file"), lastOpenLocation, tr("Translation files (*txt)")); + QFileInfo *file_info = new QFileInfo(file_name); + settings->setValue("lastOpenLocation", file_info->absolutePath()); + settings->endGroup(); + + if(!file_name.isEmpty()) + { + CEditor *editor = getEditorByWindowFilePath(file_name); + if(editor != NULL) + { + editor->activateWindow(); + return; + } + QApplication::setOverrideCursor(Qt::WaitCursor); + + // sheet editor + if(isWorksheetEditor(file_name)) + { + CEditorWorksheet *new_window = new CEditorWorksheet(_ui.mdiArea); + new_window->setUndoStack(m_undoStack); + new_window->open(file_name); + new_window->activateWindow(); + } + // phrase editor + if(isPhraseEditor(file_name)) + { + CEditorPhrase *new_window = new CEditorPhrase(_ui.mdiArea); + new_window->setUndoStack(m_undoStack); + new_window->open(file_name); + new_window->activateWindow(); + } + QApplication::restoreOverrideCursor(); + } +} + +// Open a work file. You can set the directory for work file in the settings dialog +void CMainWindow::openWorkFile(QString file) +{ + QFileInfo *file_path = new QFileInfo(QString("%1/%2").arg(work_path).arg(file)); + if(file_path->exists()) + { + if(isWorksheetEditor(file_path->filePath())) + { + CEditorWorksheet *new_window = new CEditorWorksheet(_ui.mdiArea); + new_window->open(file_path->filePath()); + new_window->activateWindow(); + } + } + else + { + QErrorMessage error; + error.showMessage(tr("The %1 file don't exists.").arg(file_path->fileName())); + error.exec(); + } +} + +void CMainWindow::save() +{ + if(_ui.mdiArea->subWindowList().size() > 0) + { + CEditor *current_window = qobject_cast(_ui.mdiArea->currentSubWindow()); + QApplication::setOverrideCursor(Qt::WaitCursor); + current_window->save(); + QApplication::restoreOverrideCursor(); + } +} + +void CMainWindow::saveAs() +{ + QString file_name; + if (_ui.mdiArea->isActiveWindow()) + { + file_name = QFileDialog::getSaveFileName(this); + } + if (!file_name.isEmpty()) + { + CEditor *current_window = qobject_cast(_ui.mdiArea->currentSubWindow()); + QApplication::setOverrideCursor(Qt::WaitCursor); + current_window->saveAs(file_name); + QApplication::restoreOverrideCursor(); + } +} + +// This function is needed by extraction. +void CMainWindow::initializeSettings(bool georges = false) +{ + if(georges == true && initialize_settings["georges"] == false) + { + NLMISC::CPath::addSearchPath(level_design_path.toStdString() + "/DFN", true, false); + NLMISC::CPath::addSearchPath(level_design_path.toStdString() + "/Game_elem/Creature", true, false); + initialize_settings["georges"] = true; + } + + if(initialize_settings["ligo"] == false) + { + try + { + // Search path of file world_editor_classes.xml + std::string ligoPath = NLMISC::CPath::lookup("world_editor_classes.xml"); + // Init LIGO + ligoConfig.readPrimitiveClass(ligoPath.c_str(), true); + NLLIGO::Register(); + NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig = &ligoConfig; + initialize_settings["ligo"] = true; + } + catch (NLMISC::Exception &e) + { + nlerror("Can't found path to world_editor_classes.xml"); + } + } +} + +// Extracting words +void CMainWindow::extractWords(QString typeq) +{ + if(verifySettings() == true) + { + CEditorWorksheet *editor_window = getEditorByWorksheetType(typeq); + if(editor_window != NULL) + { + editor_window->activateWindow(); + QString file_path = editor_window->windowFilePath(); + } + else + { + openWorkFile(typeq); + editor_window = getEditorByWorksheetType(typeq); + if(editor_window != NULL) + { + editor_window->activateWindow(); + QString file_path = editor_window->windowFilePath(); + } + else return; + } + + QString column_name; + // Sheet extraction + CSheetWordListBuilder builderS; + // Primitives extraction + CRegionPrimWordListBuilder builderP; + bool isSheet = false; + if(typeq.toAscii() == Constants::WK_ITEM) + { + column_name = "item ID"; + builderS.SheetExt = "sitem"; + builderS.SheetPath = level_design_path.append("/game_element/sitem").toStdString(); + isSheet = true; + } + else if(typeq.toAscii() == Constants::WK_CREATURE) + { + column_name = "creature ID"; + builderS.SheetExt = "creature"; + builderS.SheetPath = level_design_path.append("/Game_elem/Creature/fauna").toStdString(); + isSheet = true; + } + else if(typeq.toAscii() == Constants::WK_SBRICK) + { + column_name = "sbrick ID"; + builderS.SheetExt = "sbrick"; + builderS.SheetPath = level_design_path.append("/game_element/sbrick").toStdString(); + isSheet = true; + } + else if(typeq.toAscii() == Constants::WK_SPHRASE) + { + column_name = "sphrase ID"; + builderS.SheetExt = "sphrase"; + builderS.SheetPath = level_design_path.append("/game_element/sphrase").toStdString(); + isSheet = true; + } + else if(typeq.toAscii() == Constants::WK_PLACE) + { + column_name = "placeId"; + builderP.PrimPath = primitives_path.toStdString(); + builderP.PrimFilter.push_back("region_*.primitive"); + builderP.PrimFilter.push_back("indoors_*.primitive"); + isSheet = false; + } + QApplication::setOverrideCursor(Qt::WaitCursor); + if(isSheet) + { + editor_window->extractWords(editor_window->windowFilePath(), column_name, builderS); + } + else + { + initializeSettings(false); + editor_window->extractWords(editor_window->windowFilePath(), column_name, builderP); + } + QApplication::restoreOverrideCursor(); + } +} + +// Extract bot names from primitives +void CMainWindow::extractBotNames() +{ + if(verifySettings() == true) + { + CEditorWorksheet *editor_window = getEditorByWorksheetType(NULL); + if(editor_window != NULL) + { + editor_window->activateWindow(); + QString file_path = editor_window->windowFilePath(); + } + else + { + openWorkFile(Constants::WK_BOTNAMES); + editor_window = getEditorByWorksheetType(NULL); + if(editor_window != NULL) + { + editor_window->activateWindow(); + QString file_path = editor_window->windowFilePath(); + } + else return; + } + + QApplication::setOverrideCursor(Qt::WaitCursor); + initializeSettings(true); + editor_window->extractBotNames(convertQStringList(filters), level_design_path.toStdString(), ligoConfig); + QApplication::restoreOverrideCursor(); + } +} + +// Merge the content for 2 worksheet files +void CMainWindow::mergeSingleFile() +{ + CEditor *editor_window = qobject_cast(_ui.mdiArea->currentSubWindow()); + CSourceDialog *dialog = new CSourceDialog(this); + CFtpSelection *ftp_dialog; + map methods; + QString file_name; + + if (_ui.mdiArea->subWindowList().size() == 0) + { + QErrorMessage error; + error.showMessage(tr("Open a work file in editor for merge operation.")); + error.exec(); + return; + } + + if(editor_window->eType() != Constants::ED_SHEET) // Sheet Editor + { + QErrorMessage error; + error.showMessage(tr("Please open or activate the window with a sheet file.")); + error.exec(); + return; + } + + // create items + QListWidgetItem *local_item = new QListWidgetItem(); + local_item->setText("Local directory"); + methods[local_item] = 0; + QListWidgetItem *ftp_item = new QListWidgetItem(); + ftp_item->setText("From a FTP server"); + methods[ftp_item] = 1; + + dialog->setSourceOptions(methods); + dialog->show(); + dialog->exec(); + // get the file for merge + if(dialog->selected_item == local_item) // Local directory + { + file_name = QFileDialog::getOpenFileName(this); + } + else if(dialog->selected_item == ftp_item) // Ftp directory + { + CFtpSelection *ftp_dialog = new CFtpSelection(this); + ftp_dialog->show(); + + if(ftp_dialog->exec() && ftp_dialog->status == true) + file_name = ftp_dialog->file->fileName(); + + delete ftp_dialog; + } + else + return; + + // Make sure we retrieved a file name + if(file_name.isEmpty()) + return; + + editor_window->activateWindow(); + CEditorWorksheet *current_window = qobject_cast(editor_window); + if(current_window->windowFilePath() == file_name) + return; + if(current_window->compareWorksheetFile(file_name)) + { + current_window->mergeWorksheetFile(file_name); + } + else + { + QErrorMessage error; + error.showMessage(tr("The file: %1 has different columns from the current file in editor.").arg(file_name)); + error.exec(); + } + if(dialog->selected_item == ftp_item) + { + /* + // TODO: uninit ftp_dialog????? + if(!ftp_dialog->file->remove()) + { + QErrorMessage error; + error.showMessage(tr("Please remove the file from ftp server manually. The file is located on the same directory with OVQT application.")); + error.exec(); + } + */ + } +} + +// Read the settings from QSettings +void CMainWindow::readSettings() +{ + QSettings *settings = Core::ICore::instance()->settings(); + // translation manager settings + settings->beginGroup("translationmanager"); + filters = settings->value("filters").toStringList(); + languages = settings->value("trlanguages").toStringList(); + translation_path = settings->value("translation").toString(); + work_path = settings->value("work").toString(); + settings->endGroup(); + // core settings + settings->beginGroup(Core::Constants::DATA_PATH_SECTION); + level_design_path = settings->value(Core::Constants::LEVELDESIGN_PATH).toString(); + primitives_path = QString(Core::Constants::PRIMITIVES_PATH); //TODO + settings->endGroup(); +} + +// Verify the settings +bool CMainWindow::verifySettings() +{ + bool count_errors = false; + + if(level_design_path.isNull() || primitives_path.isNull() || work_path.isNull()) + { + QErrorMessage error_settings; + error_settings.showMessage(tr("Please write all the paths on the settings dialog.")); + error_settings.exec(); + count_errors = true; + } + return !count_errors; +} + +bool CCoreListener::closeMainWindow() const +{ + bool okToClose = true; + Q_FOREACH(QMdiSubWindow *subWindow, m_MainWindow->_ui.mdiArea->subWindowList()) + { + CEditor *currentEditor = qobject_cast(subWindow); + if(subWindow->isWindowModified()) + { + QMessageBox msgBox; + msgBox.setIcon(QMessageBox::Question); + msgBox.setText(tr("The document has been modified ( %1 ).").arg(currentEditor->windowFilePath())); + msgBox.setInformativeText(tr("Do you want to save your changes?")); + msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); + msgBox.setDefaultButton(QMessageBox::Save); + int ret = msgBox.exec(); + if(ret == QMessageBox::Save) + { + currentEditor->save(); + } + else if(ret == QMessageBox::Cancel) + { + okToClose = false; + break; + } + } + } + return okToClose; +} + + +// Helper functions +CEditor *CMainWindow::getEditorByWindowFilePath(const QString &fileName) +{ + Q_FOREACH(QMdiSubWindow *subWindow, _ui.mdiArea->subWindowList()) + { + CEditor *currentEditor = qobject_cast(subWindow); + if(currentEditor->subWindowFilePath() == fileName) + return currentEditor; + } + return NULL; +} + +CEditorWorksheet *CMainWindow::getEditorByWorksheetType(const QString &type) +{ + Q_FOREACH(QMdiSubWindow *subWindow, _ui.mdiArea->subWindowList()) + { + CEditor *currentEditor = qobject_cast(subWindow); + if(currentEditor->eType() == Constants::ED_SHEET) + { + CEditorWorksheet *editor = qobject_cast(currentEditor); + if(type != NULL) + { + if(editor->isSheetTable(type)) + { + return editor; + } + } + else + { + if(editor->isBotNamesTable()) + { + return editor; + } + } + } + } + return NULL; +} + +std::list CMainWindow::convertQStringList(QStringList listq) +{ + std::list stdlist; + + Q_FOREACH(QString text, listq) + { + stdlist.push_back(text.toStdString()); + } + return stdlist; +} + +bool CMainWindow::isWorksheetEditor(QString filename) +{ + STRING_MANAGER::TWorksheet wk_file; + if(loadExcelSheet(filename.toStdString(), wk_file, true) == true) + { + if(wk_file.ColCount > 1) + return true; + } + return false; +} + +bool CMainWindow::isPhraseEditor(QString filename) +{ + vector phrases; + return readPhraseFile(filename.toStdString(), phrases, false); +} + +} /* namespace TranslationManager */ + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_main_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_main_window.h new file mode 100644 index 000000000..c67f282e0 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_main_window.h @@ -0,0 +1,129 @@ +// Translation Manager Plugin - OVQT Plugin +// Copyright (C) 2011 Emanuel Costea +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef MAIN_WINDOW_H +#define MAIN_WINDOW_H + +// Project includes +#include "ui_translation_manager_main_window.h" +#include "translation_manager_editor.h" +#include "source_selection.h" +#include "editor_worksheet.h" +#include "editor_phrase.h" + +// Project system includes +#include "../core/icore_listener.h" + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include + +// STL includes +#include + +// Nel includes +#include "nel/misc/types_nl.h" +#include "nel/misc/sheet_id.h" +#include "nel/misc/path.h" +#include "nel/misc/diff_tool.h" +#include "nel/ligo/ligo_config.h" + +using namespace std; + +namespace TranslationManager +{ + +class CMainWindow : public QMainWindow +{ + Q_OBJECT + +public: + CMainWindow(QWidget *parent = 0); + virtual ~CMainWindow() {} + QUndoStack *m_undoStack; + +public: + Ui::CMainWindow _ui; + +private: + // actions + QAction *openAct; + QAction *saveAct; + QAction *saveAsAct; + QMenu *windowMenu; + QSignalMapper *windowMapper; + // config + QMap initialize_settings; + QList filters; + QList languages; + QString level_design_path; + QString primitives_path; + QString translation_path; + QString work_path; + NLLIGO::CLigoConfig ligoConfig; + +private Q_SLOTS: + void extractBotNames(); + void extractWords(QString typeq); + void open(); + void save(); + void saveAs(); + void setActiveSubWindow(QWidget *window); + void updateWindowsList(); + void mergeSingleFile(); + +private: + void openWorkFile(QString file); + void updateToolbar(QMdiSubWindow *window); + bool verifySettings(); + void readSettings(); + void createMenus(); + void createToolbar(); + void initializeSettings(bool georges); + std::list convertQStringList(QStringList listq); + CEditor *getEditorByWindowFilePath(const QString &fileName); + // Worksheet specific functions + CEditorWorksheet *getEditorByWorksheetType(const QString &type); + bool isWorksheetEditor(QString filename); + bool isPhraseEditor(QString filename); +}; + +class CCoreListener : public Core::ICoreListener +{ + Q_OBJECT + +public: + CCoreListener(CMainWindow *mainWindow, QObject *parent = 0): ICoreListener(parent) + { + m_MainWindow = mainWindow; + } + + virtual ~CCoreListener() {} + virtual bool closeMainWindow() const; + +public: + CMainWindow *m_MainWindow; +}; + +} // namespace TranslationManager + +#endif diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_main_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_main_window.ui new file mode 100644 index 000000000..6f2cd2815 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_main_window.ui @@ -0,0 +1,48 @@ + + + CMainWindow + + + + 0 + 0 + 883 + 576 + + + + MainWindow + + + + + + + + + QMdiArea::TabbedView + + + true + + + + + + + + + + toolBar + + + TopToolBarArea + + + false + + + + + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_plugin.cpp new file mode 100644 index 000000000..03aa06c87 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_plugin.cpp @@ -0,0 +1,89 @@ +// Translation Manager Plugin - OVQT Plugin +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Emanuel Costea +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Project includes +#include "translation_manager_plugin.h" +#include "translation_manager_settings_page.h" +#include "translation_manager_main_window.h" + +// Core includes +#include "../core/icore.h" +#include "../core/core_constants.h" +#include "../core/menu_manager.h" +#include "../../extension_system/iplugin_spec.h" + +// NeL includes +#include "nel/misc/debug.h" + +// Qt includes +#include +#include +#include +#include +#include +#include +#include + +namespace TranslationManager +{ +TranslationManagerPlugin::~TranslationManagerPlugin() +{ + Q_FOREACH(QObject *obj, _autoReleaseObjects) + { + _plugMan->removeObject(obj); + } + qDeleteAll(_autoReleaseObjects); + _autoReleaseObjects.clear(); +} + +bool TranslationManagerPlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString) +{ + Q_UNUSED(errorString); + _plugMan = pluginManager; + // create the mainwindow + CMainWindow *mainWindow = new CMainWindow(); + + addAutoReleasedObject(new CTranslationManagerSettingsPage(this)); + addAutoReleasedObject(new CTranslationManagerContext(mainWindow, this)); + addAutoReleasedObject(new CCoreListener(mainWindow, this)); + + return true; +} + +void TranslationManagerPlugin::extensionsInitialized() +{ +} + +void TranslationManagerPlugin::setNelContext(NLMISC::INelContext *nelContext) +{ +#ifdef NL_OS_WINDOWS + // Ensure that a context doesn't exist yet. + // This only applies to platforms without PIC, e.g. Windows. + nlassert(!NLMISC::INelContext::isContextInitialised()); +#endif // NL_OS_WINDOWS + _LibContext = new NLMISC::CLibraryContext(*nelContext); +} + +void TranslationManagerPlugin::addAutoReleasedObject(QObject *obj) +{ + _plugMan->addObject(obj); + _autoReleaseObjects.prepend(obj); +} + +} + +Q_EXPORT_PLUGIN(TranslationManager::TranslationManagerPlugin) \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_plugin.h new file mode 100644 index 000000000..fb03a49f1 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_plugin.h @@ -0,0 +1,113 @@ +// Translation Manager Plugin - OVQT Plugin +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Emanuel Costea +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef TRANSLATION_MANAGER_PLUGIN_H +#define TRANSLATION_MANAGER_PLUGIN_H + +// Project includes +#include "../../extension_system/iplugin.h" +#include "../core/icontext.h" +#include "translation_manager_main_window.h" + +// NeL includes +#include "nel/misc/app_context.h" + +// Qt includes +#include +#include + +using namespace std; + +namespace NLMISC +{ +class CLibraryContext; +} + +namespace ExtensionSystem +{ +class IPluginSpec; +} + +namespace TranslationManager +{ + +class CTranslationManagerContext; + +class TranslationManagerPlugin : public QObject, public ExtensionSystem::IPlugin +{ + Q_OBJECT + Q_INTERFACES(ExtensionSystem::IPlugin) +public: + virtual ~TranslationManagerPlugin(); + + bool initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString); + void extensionsInitialized(); + + void setNelContext(NLMISC::INelContext *nelContext); + void addAutoReleasedObject(QObject *obj); + +protected: + NLMISC::CLibraryContext *_LibContext; + +private: + ExtensionSystem::IPluginManager *_plugMan; + QList _autoReleaseObjects; +}; + +class CTranslationManagerContext: public Core::IContext +{ + Q_OBJECT + +public: + CTranslationManagerContext(CMainWindow *mainWindow, QObject *parent = 0): IContext(parent) + { + m_MainWindow = mainWindow; + } + + virtual ~CTranslationManagerContext() {} + + virtual QString id() const + { + return QLatin1String("TranslationManagerContext"); + } + virtual QString trName() const + { + return tr("Translation Manager"); + } + virtual QIcon icon() const + { + return QIcon(); + } + virtual QWidget *widget() + { + return m_MainWindow; + } + virtual QUndoStack *undoStack() + { + return m_MainWindow->m_undoStack; + } + virtual void open() + { + + } + + CMainWindow *m_MainWindow; +}; + +} + +#endif // TRANSLATION_MANAGER_PLUGIN_H \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_settings_page.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_settings_page.cpp new file mode 100644 index 000000000..e3dbd92df --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_settings_page.cpp @@ -0,0 +1,203 @@ +// Translation Manager Plugin - OVQT Plugin +// Copyright (C) 2011 Emanuel Costea +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "translation_manager_settings_page.h" + +// Core includes +#include "../core/icore.h" + +// Qt includes +#include +#include +#include +#include + +namespace TranslationManager +{ + +QString lastDir = "."; + +CTranslationManagerSettingsPage::CTranslationManagerSettingsPage(QObject *parent) + : IOptionsPage(parent), + _currentPage(NULL) +{ +} + +QString CTranslationManagerSettingsPage::id() const +{ + return QLatin1String("TranslationManagerPage"); +} + +QString CTranslationManagerSettingsPage::trName() const +{ + return tr("Translation Manager"); +} + +QString CTranslationManagerSettingsPage::category() const +{ + return QLatin1String("Translation Manager"); +} + +QString CTranslationManagerSettingsPage::trCategory() const +{ + return tr("Translation Manager"); +} + +QIcon CTranslationManagerSettingsPage::categoryIcon() const +{ + return QIcon(); +} + +QWidget *CTranslationManagerSettingsPage::createPage(QWidget *parent) +{ + _currentPage = new QWidget(parent); + _ui.setupUi(_currentPage); + readSettings(); + connect(_ui.filter_add, SIGNAL(clicked()), this, SLOT(filterAdd())); + connect(_ui.filter_del, SIGNAL(clicked()), this, SLOT(filterDel())); + connect(_ui.lang_add, SIGNAL(clicked()), this, SLOT(languageAdd())); + connect(_ui.lang_del, SIGNAL(clicked()), this, SLOT(languageDel())); + connect(_ui.translation_add, SIGNAL(clicked()), this, SLOT(translationAdd())); + connect(_ui.work_add, SIGNAL(clicked()), this, SLOT(workAdd())); + + return _currentPage; +} + +void CTranslationManagerSettingsPage::filterAdd() +{ + QString newValue = _ui.filter_edit->text(); + if (!newValue.isEmpty()) + { + QListWidgetItem *newItem = new QListWidgetItem; + newItem->setText(newValue); + newItem->setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable); + _ui.filter_list->addItem(newItem); + } +} + +void CTranslationManagerSettingsPage::filterDel() +{ + QListWidgetItem *removeItem = _ui.filter_list->takeItem(_ui.filter_list->currentRow()); + if (!removeItem) + delete removeItem; +} + +void CTranslationManagerSettingsPage::languageAdd() +{ + QString newValue = _ui.lang_edit->text(); + if (!newValue.isEmpty()) + { + QListWidgetItem *newItem = new QListWidgetItem; + newItem->setText(newValue); + newItem->setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable); + _ui.lang_list->addItem(newItem); + } +} + +void CTranslationManagerSettingsPage::languageDel() +{ + QListWidgetItem *removeItem = _ui.lang_list->takeItem(_ui.lang_list->currentRow()); + if (!removeItem) + delete removeItem; +} + +void CTranslationManagerSettingsPage::translationAdd() +{ + QString newPath = QFileDialog::getExistingDirectory(_currentPage, ""); + if (!newPath.isEmpty()) + { + _ui.translation_edit->setText(newPath); + } +} + +void CTranslationManagerSettingsPage::workAdd() +{ + QString newPath = QFileDialog::getExistingDirectory(_currentPage, ""); + if (!newPath.isEmpty()) + { + _ui.work_edit->setText(newPath); + } +} + +void CTranslationManagerSettingsPage::apply() +{ + writeSettings(); +} + +void CTranslationManagerSettingsPage::readSettings() +{ + QStringList filters, languages; + QString ligo, translation, work; + + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup("translationmanager"); + + filters = settings->value("filters").toStringList(); /* filters */ + languages = settings->value("trlanguages").toStringList(); /* languages */ + ligo = settings->value("ligo").toString(); + translation = settings->value("translation").toString(); + work = settings->value("work").toString(); + + settings->endGroup(); + // filter + Q_FOREACH(QString filter, filters) + { + QListWidgetItem *newItem = new QListWidgetItem; + newItem->setText(filter); + newItem->setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable); + _ui.filter_list->addItem(newItem); + } + // languages + Q_FOREACH(QString lang, languages) + { + QListWidgetItem *newItem = new QListWidgetItem; + newItem->setText(lang); + newItem->setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable); + _ui.lang_list->addItem(newItem); + } + // translation + _ui.translation_edit->setText(translation); + // work + _ui.work_edit->setText(work); + +} + +void CTranslationManagerSettingsPage::writeSettings() +{ + QStringList filters, languages; + QString ligo, translation, work; + // filters + for (int i = 0; i < _ui.filter_list->count(); ++i) + filters << _ui.filter_list->item(i)->text(); + // languages + for (int i = 0; i < _ui.lang_list->count(); ++i) + languages << _ui.lang_list->item(i)->text(); + // translations path + translation = _ui.translation_edit->text(); + // work path + work = _ui.work_edit->text(); + + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup("translationmanager"); + settings->setValue("filters", filters); + settings->setValue("trlanguages", languages); + settings->setValue("translation", translation); + settings->setValue("work", work); + settings->endGroup(); + settings->sync(); +} + +} \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_settings_page.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_settings_page.h new file mode 100644 index 000000000..9b34d87ba --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_settings_page.h @@ -0,0 +1,62 @@ +// Translation Manager Plugin - OVQT Plugin +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Emanuel Costea +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef TRANSLATION_MANAGER_SETTINGS_PAGE_H +#define TRANSLATION_MANAGER_SETTINGS_PAGE_H + +#include + +#include "../core/ioptions_page.h" + +#include "ui_translation_manager_settings_page.h" + +namespace TranslationManager +{ + +class CTranslationManagerSettingsPage : public Core::IOptionsPage +{ + Q_OBJECT +public: + CTranslationManagerSettingsPage(QObject *parent = 0); + virtual ~CTranslationManagerSettingsPage() {} + + virtual QString id() const; + virtual QString trName() const; + virtual QString category() const; + virtual QString trCategory() const; + virtual QIcon categoryIcon() const; + virtual QWidget *createPage(QWidget *parent); + + virtual void apply(); + virtual void finish() {} +private Q_SLOTS: + void filterAdd(); + void filterDel(); + void languageAdd(); + void languageDel(); + void translationAdd(); + void workAdd(); +private: + QWidget *_currentPage; + Ui::CTranslationManagerSettingsPage _ui; + void writeSettings(); + void readSettings(); +}; + +} + +#endif // TRANSLATION_MANAGER_SETTINGS_H \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_settings_page.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_settings_page.ui new file mode 100644 index 000000000..bd377b6b9 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_settings_page.ui @@ -0,0 +1,160 @@ + + + CTranslationManagerSettingsPage + + + + 0 + 0 + 589 + 490 + + + + Form + + + + + + Translation Manager Plugin + + + + + + + + Filters + + + + + + + + + + + + + + :/core/icons/ic_nel_add_item.png:/core/icons/ic_nel_add_item.png + + + true + + + + + + + + + + + :/core/icons/ic_nel_delete_item.png:/core/icons/ic_nel_delete_item.png + + + true + + + + + + + Languages + + + + + + + + + + + + + + :/core/icons/ic_nel_add_item.png:/core/icons/ic_nel_add_item.png + + + true + + + + + + + + + + + :/core/icons/ic_nel_delete_item.png:/core/icons/ic_nel_delete_item.png + + + true + + + + + + + + + + + + + + + + + Work directory + + + + + + + + + + ... + + + + + + + + + + + Translation directory + + + + + + + + + + ... + + + + + + + + + + + + + + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/ovqt_plugin_zone_painter.xml b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/ovqt_plugin_zone_painter.xml new file mode 100644 index 000000000..cf9e8afde --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/ovqt_plugin_zone_painter.xml @@ -0,0 +1,10 @@ + + ovqt_plugin_zone_painter + ZonePainter + 0.0 + Ryzom Core + Zone Painter Plugin + + + + \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_main_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_main_window.cpp index 01086f231..e0c2dab0c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_main_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_main_window.cpp @@ -11,7 +11,7 @@ #include "painter_dock_widget.h" #include "../core/icore.h" -#include "../core/imenu_manager.h" +#include "../core/menu_manager.h" #include "../core/core_constants.h" ZonePainterMainWindow::ZonePainterMainWindow(QWidget *parent) : @@ -145,6 +145,7 @@ void ZonePainterMainWindow::loadConfig() { QColor color; color = settings->value("BackgroundColor", QColor(80, 80, 80)).value(); + settings->endGroup(); m_nelWidget->setBackgroundColor(NLMISC::CRGBA(color.red(), color.green(), color.blue(), color.alpha())); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_model.cpp new file mode 100644 index 000000000..4ab93d62d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_model.cpp @@ -0,0 +1,40 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "zone_painter_model.h" + +// STL includes + +// Qt includes + +// NeL includes + +namespace Plugin +{ + +CZonePainterModel::CZonePainterModel() +{ + +} + +CZonePainterModel::~CZonePainterModel() +{ + +} + +} /* namespace Plugin */ + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_model.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_model.h new file mode 100644 index 000000000..259634b63 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_model.h @@ -0,0 +1,42 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef ZONE_PAINTER_MODEL_H +#define ZONE_PAINTER_MODEL_H + +// NeL includes +#include +#include +#include + +// Qt includes + +namespace Plugin +{ + +class CZonePainterModel +{ +public: + CZonePainterModel(); + virtual ~CZonePainterModel(); + +}; /* class CZonePainterModel */ + +} /* namespace Plugin */ + + +#endif // ZONE_PAINTER_MODEL_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_plugin.cpp index 9ccfb9053..37222cef2 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_plugin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_plugin.cpp @@ -3,7 +3,7 @@ #include "zone_painter_settings_page.h" #include "../core/icore.h" #include "../core/core_constants.h" -#include "../core/imenu_manager.h" +#include "../core/menu_manager.h" #include "../../extension_system/iplugin_spec.h" // NeL includes @@ -16,50 +16,58 @@ #include #include #include +#include namespace Plugin { - NLMISC_SAFE_SINGLETON_IMPL(CZoneManager) +// NLMISC_SAFE_SINGLETON_IMPL(CZoneManager) ZonePainterPlugin::~ZonePainterPlugin() { - Q_FOREACH(QObject *obj, _autoReleaseObjects) + Q_FOREACH(QObject *obj, m_autoReleaseObjects) { - _plugMan->removeObject(obj); + m_plugMan->removeObject(obj); } - qDeleteAll(_autoReleaseObjects); - _autoReleaseObjects.clear(); + qDeleteAll(m_autoReleaseObjects); + m_autoReleaseObjects.clear(); } bool ZonePainterPlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString) { Q_UNUSED(errorString); - _plugMan = pluginManager; + m_plugMan = pluginManager; addAutoReleasedObject(new CZonePainterSettingsPage(this)); addAutoReleasedObject(new CZonePainterContext(this)); //addAutoReleasedObject(new CCoreListener(this)); + return true; } void ZonePainterPlugin::extensionsInitialized() { Core::ICore *core = Core::ICore::instance(); - Core::IMenuManager *menuManager = core->menuManager(); - //menuManager = _plugMan->getObject(); - QAction *exampleAction1 = new QAction("Zone1", this); - QAction *exampleAction2 = new QAction("Zone2", this); - QAction *aboutQtAction = menuManager->action(Core::Constants::ABOUT_QT); - QMenu *helpMenu = menuManager->menu(Core::Constants::M_HELP); - helpMenu->insertAction(aboutQtAction, exampleAction1); - helpMenu->addSeparator(); - helpMenu->addAction(exampleAction2); - QMenu *zoneMenu = menuManager->menuBar()->addMenu("ZoneMenu"); - zoneMenu->insertAction(aboutQtAction, exampleAction1); - zoneMenu->addSeparator(); - zoneMenu->addAction(exampleAction2); + Core::MenuManager *menuManager = core->menuManager(); + QAction *loadZoneAction = new QAction("Load Zone", this); + QAction *saveZoneAction = new QAction("Save Zone", this); + + QMenu *toolsMenu = menuManager->menu(Core::Constants::M_TOOLS); + QMenu *zoneMenu = toolsMenu->addMenu("Zone Painter"); + zoneMenu->addAction(loadZoneAction); + connect(loadZoneAction, SIGNAL(triggered()), this, SLOT(clickLoadZoneAction())); + zoneMenu->addAction(saveZoneAction); } +/****** SLOTS ******/ +void ZonePainterPlugin::clickLoadZoneAction() { + QString zoneFile = QFileDialog::getOpenFileName(NULL, tr("Open Zone File"), ".", tr("Zone Files (*.zone);;")); +} + +void ZonePainterPlugin::clickSaveZoneAction() { + +} +/****** END SLOTS ******/ + void ZonePainterPlugin::setNelContext(NLMISC::INelContext *nelContext) { #ifdef NL_OS_WINDOWS @@ -67,57 +75,13 @@ void ZonePainterPlugin::setNelContext(NLMISC::INelContext *nelContext) // This only applies to platforms without PIC, e.g. Windows. nlassert(!NLMISC::INelContext::isContextInitialised()); #endif // NL_OS_WINDOWS - _LibContext = new NLMISC::CLibraryContext(*nelContext); -} - -QString ZonePainterPlugin::name() const -{ - return "ZonePainterPlugin"; -} - -QString ZonePainterPlugin::version() const -{ - return "0.2"; -} - -QString ZonePainterPlugin::vendor() const -{ - return "Ryzom Core"; -} - -QString ZonePainterPlugin::description() const -{ - return "Zone Painter Plugin"; -} - -QStringList ZonePainterPlugin::dependencies() const -{ - QStringList list; - list.append(Core::Constants::OVQT_CORE_PLUGIN); - //list.append("ObjectViewer"); - return list; + m_LibContext = new NLMISC::CLibraryContext(*nelContext); } void ZonePainterPlugin::addAutoReleasedObject(QObject *obj) { - _plugMan->addObject(obj); - _autoReleaseObjects.prepend(obj); -} - -QObject* ZonePainterPlugin::objectByName(const QString &name) const -{ - Q_FOREACH (QObject *qobj, _plugMan->allObjects()) - if (qobj->objectName() == name) - return qobj; - return 0; -} - -ExtensionSystem::IPluginSpec *ZonePainterPlugin::pluginByName(const QString &name) const -{ - Q_FOREACH (ExtensionSystem::IPluginSpec *spec, _plugMan->plugins()) - if (spec->name() == name) - return spec; - return 0; + m_plugMan->addObject(obj); + m_autoReleaseObjects.prepend(obj); } } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_plugin.h index 2c1dff53e..a3def41ba 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_plugin.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_plugin.h @@ -31,7 +31,7 @@ class IPluginSpec; namespace Plugin { - class CZoneManager +/* class CZoneManager { NLMISC_SAFE_SINGLETON_DECL(CZoneManager) public: @@ -41,7 +41,7 @@ namespace Plugin NL3D::CLandscapeModel *m_painterLandscape; NL3D::CZone *m_currentZone; }; - +*/ class ZonePainterPlugin : public QObject, public ExtensionSystem::IPlugin { Q_OBJECT @@ -52,28 +52,21 @@ public: bool initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString); void extensionsInitialized(); - void setNelContext(NLMISC::INelContext *nelContext); - QString name() const; - QString version() const; - QString vendor() const; - QString description() const; - QStringList dependencies() const; - void addAutoReleasedObject(QObject *obj); - QObject *objectByName(const QString &name) const; - ExtensionSystem::IPluginSpec *pluginByName(const QString &name) const; - - - +public Q_SLOTS: + void clickLoadZoneAction(); + void clickSaveZoneAction(); protected: - NLMISC::CLibraryContext *_LibContext; + NLMISC::CLibraryContext *m_LibContext; private: - ExtensionSystem::IPluginManager *_plugMan; - QList _autoReleaseObjects; + ExtensionSystem::IPluginManager *m_plugMan; + QList m_autoReleaseObjects; + + NL3D::CLandscapeModel *m_Landscape; }; class CZonePainterContext: public Core::IContext diff --git a/code/nel/tools/3d/panoply_maker/Makefile.am b/code/nel/tools/3d/panoply_maker/Makefile.am deleted file mode 100644 index d821ed109..000000000 --- a/code/nel/tools/3d/panoply_maker/Makefile.am +++ /dev/null @@ -1,24 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2002/05/13 15:44:57 valignat Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = panoply.cfg \ - panoply_maker.dsp - -bin_PROGRAMS = panoply_maker - -panoply_maker_SOURCES = color_modifier.cpp hls_bank_texture_info.cpp \ - panoply_maker.cpp - -noinst_HEADERS = color_mask.h \ - color_modifier.h - -AM_CXXFLAGS = -I$(top_srcdir)/src - -panoply_maker_LDADD = ../../../src/misc/libnelmisc.la - - -# End of Makefile.am - diff --git a/code/nel/tools/3d/plugin_max/nel_export/DllEntry.cpp b/code/nel/tools/3d/plugin_max/nel_export/DllEntry.cpp index 61337b328..7e6ded529 100644 --- a/code/nel/tools/3d/plugin_max/nel_export/DllEntry.cpp +++ b/code/nel/tools/3d/plugin_max/nel_export/DllEntry.cpp @@ -19,7 +19,7 @@ #include "nel/3d/register_3d.h" #include "nel/misc/app_context.h" #include "../nel_3dsmax_shared/nel_3dsmax_shared.h" - +#include extern ClassDesc2* GetCNelExportDesc(); @@ -42,7 +42,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved) if (!controlsInit) { controlsInit = TRUE; +#if MAX_VERSION_MAJOR < 14 InitCustomControls(hInstance); // Initialize MAX's custom controls +#endif InitCommonControls(); // Initialize Win95 controls } diff --git a/code/nel/tools/3d/plugin_max/nel_export/nel_export_script.cpp b/code/nel/tools/3d/plugin_max/nel_export/nel_export_script.cpp index 9218e73ce..d26af56ca 100644 --- a/code/nel/tools/3d/plugin_max/nel_export/nel_export_script.cpp +++ b/code/nel/tools/3d/plugin_max/nel_export/nel_export_script.cpp @@ -16,7 +16,12 @@ #include "std_afx.h" #include "nel_export.h" -#include +#include +#if MAX_VERSION_MAJOR >= 14 +# include +#else +# include +#endif #include "../nel_mesh_lib/export_nel.h" #include "../nel_mesh_lib/export_appdata.h" diff --git a/code/nel/tools/3d/plugin_max/nel_export/std_afx.h b/code/nel/tools/3d/plugin_max/nel_export/std_afx.h index 326c0b9c1..7d0ef0b2a 100644 --- a/code/nel/tools/3d/plugin_max/nel_export/std_afx.h +++ b/code/nel/tools/3d/plugin_max/nel_export/std_afx.h @@ -26,16 +26,29 @@ #include #include #undef STRICT -#include -#include -#include -#include -#include -#include -#include -#include +#include +#if MAX_VERSION_MAJOR >= 14 +# include +# include +# include +# include +# include +# include +# include +# include +# include +#else +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif #include -#include #include #ifdef min #undef min diff --git a/code/nel/tools/3d/plugin_max/nel_mesh_lib/StdAfx.h b/code/nel/tools/3d/plugin_max/nel_mesh_lib/StdAfx.h index 65b65651e..b3626b896 100644 --- a/code/nel/tools/3d/plugin_max/nel_mesh_lib/StdAfx.h +++ b/code/nel/tools/3d/plugin_max/nel_mesh_lib/StdAfx.h @@ -32,7 +32,12 @@ #include #include #include -#include +#include +#if MAX_VERSION_MAJOR >= 14 +# include +#else +# include +#endif //#include // Character Studio SDK include diff --git a/code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm.cpp b/code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm.cpp index e65b4ea56..e4bc7006a 100644 --- a/code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm.cpp +++ b/code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm.cpp @@ -281,13 +281,21 @@ void SLightBuild::convertFromMaxLight (INode *node,TimeValue tvTime) } #if (MAX_RELEASE < 4000) - // Convert exclusion list - NameTab& ntExclu = maxLight->GetExclusionList(); - for( sint i = 0; i < ntExclu.Count(); ++i ) - { - string tmp = *ntExclu.Addr(i); - this->setExclusion.insert( tmp ); - } + // Convert exclusion list + NameTab& ntExclu = maxLight->GetExclusionList(); + for (sint i = 0; i < ntExclu.Count(); ++i) + { + string tmp = *ntExclu.Addr(i); + this->setExclusion.insert(tmp); + } +#else // (MAX_RELEASE < 4000) + ExclList& exclusionList = maxLight->GetExclusionList(); + for (sint i = 0; i < exclusionList.Count(); ++i) + { + INode *exclNode = exclusionList[i]; + string tmp = exclNode->GetName(); + this->setExclusion.insert(tmp); + } #endif // (MAX_RELEASE < 4000) // Get Soft Shadow informations @@ -1999,11 +2007,12 @@ void CExportNel::deleteLM(INode& ZeNode) sprintf( tmp, "%d", i ); sSaveName += tmp; sSaveName += ".tga"; - FILE *file; - if( file = fopen(sSaveName.c_str(),"rb") ) + if (CFile::fileExists(sSaveName)) { - fclose( file ); - DeleteFile( sSaveName.c_str() ); + if (!CFile::deleteFile(sSaveName)) + { + nlwarning("Failed to delete file %s.", sSaveName.c_str()); + } } } } @@ -2576,11 +2585,13 @@ bool CExportNel::calculateLM( CMesh::CMeshBuild *pZeMeshBuild, CMeshBase::CMeshB for (i = 0; i < 256; ++i) { string sLMName = sBaseName + NLMISC::toString(i) + ".tga"; - CIFile ifi; - if (ifi.open(sLMName)) + if (CFile::fileExists(sLMName)) { - ifi.close (); - DeleteFile (sLMName.c_str()); + nlinfo("DELETE %s", sLMName.c_str()); + if (!CFile::deleteFile(sLMName)) + { + nlwarning("Failed to delete file %s", sLMName.c_str()); + } } } } @@ -2598,6 +2609,7 @@ bool CExportNel::calculateLM( CMesh::CMeshBuild *pZeMeshBuild, CMeshBase::CMeshB COFile f( sSaveName ); try { + nlinfo("SAVE %s", sSaveName.c_str()); if (lmcEnabled) { // In fact the output is 32 bits because we need the alpha channel diff --git a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_misc.cpp b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_misc.cpp index 0b2426758..a03beb000 100644 --- a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_misc.cpp +++ b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_misc.cpp @@ -260,7 +260,11 @@ Control* CExportNel::getControlerByName (Animatable& node, const char* sName) if (strcmp (paramDef.int_name, sName)==0) { // ok, return this subanim +#if MAX_VERSION_MAJOR >= 14 + return param->GetControllerByID(id); +#else return param->GetController(id); +#endif } } } diff --git a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_particle_system.cpp b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_particle_system.cpp index 4c6b6bc8b..e3504b324 100644 --- a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_particle_system.cpp +++ b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_particle_system.cpp @@ -36,7 +36,7 @@ IShape* CExportNel::buildParticleSystem(INode& node, TimeValue time) // if not found, get from the APP_DATAS shapeName = CExportNel::getNelObjectName(node); if (shapeName.empty()) return NULL; - shapeName = NLMISC::CPath::lookup("shapeName", false); + shapeName = NLMISC::CPath::lookup(shapeName, false); if (shapeName.empty()) return NULL; } diff --git a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_scene.cpp b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_scene.cpp index 4e7edea8a..2d0268a74 100644 --- a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_scene.cpp +++ b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_scene.cpp @@ -24,6 +24,7 @@ #include "../nel_patch_lib/rpo.h" #include "../../ig_lighter_lib/ig_lighter_lib.h" +#include "nel/misc/path.h" #include "nel/3d/scene_group.h" #include "nel/3d/scene.h" #include "nel/3d/shape_bank.h" @@ -418,12 +419,21 @@ CInstanceGroup* CExportNel::buildInstanceGroup(const vector& vectNode, v if (clid.PartA() == NEL_PARTICLE_SYSTEM_CLASS_ID) { // build the shape from the file name - std::string objName = CExportNel::getNelObjectName(*pNode); - if (!objName.empty()) + // std::string objName = CExportNel::getNelObjectName(*pNode); + std::string psFilePath; + // try to get the complete path + if (!CExportNel::getValueByNameUsingParamBlock2(*pNode, "ps_file_name", (ParamType2) TYPE_STRING, &psFilePath, 0)) + { + // if not found, get from the APP_DATAS + psFilePath = CExportNel::getNelObjectName(*pNode); + if (!psFilePath.empty()) + psFilePath = CPath::lookup(psFilePath, false); + } + if (!psFilePath.empty()) { NL3D::CShapeStream ss; NLMISC::CIFile iF; - if (iF.open(objName.c_str())) + if (iF.open(psFilePath.c_str())) { try { diff --git a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_script.cpp b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_script.cpp index 6f1713683..7fd0ad150 100644 --- a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_script.cpp +++ b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_script.cpp @@ -15,8 +15,14 @@ // along with this program. If not, see . #include "stdafx.h" -#include -#include +#include +#if MAX_VERSION_MAJOR >= 14 +# include +# include +#else +# include +# include +#endif #include "export_nel.h" #include "export_appdata.h" diff --git a/code/nel/tools/3d/plugin_max/nel_patch_converter/DllEntry.cpp b/code/nel/tools/3d/plugin_max/nel_patch_converter/DllEntry.cpp index 22ae76790..50f249c31 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_converter/DllEntry.cpp +++ b/code/nel/tools/3d/plugin_max/nel_patch_converter/DllEntry.cpp @@ -20,6 +20,7 @@ #include "nel/misc/debug.h" #include "nel/misc/app_context.h" #include "../nel_3dsmax_shared/nel_3dsmax_shared.h" +#include extern ClassDesc2* GetPO2RPODesc(); extern ClassDesc* GetRPODesc(); @@ -58,7 +59,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved) { // This method has been deprecated. controlsInit = TRUE; +#if MAX_VERSION_MAJOR < 14 InitCustomControls(hInstance); // Initialize MAX's custom controls +#endif InitCommonControls(); // Initialize Win95 controls } return (TRUE); diff --git a/code/nel/tools/3d/plugin_max/nel_patch_converter/script.cpp b/code/nel/tools/3d/plugin_max/nel_patch_converter/script.cpp index b324c2cc6..8433e5001 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_converter/script.cpp +++ b/code/nel/tools/3d/plugin_max/nel_patch_converter/script.cpp @@ -22,24 +22,38 @@ #define _CRT_SECURE_NO_DEPRECATE #include -#include -#include -// Various MAX and MXS includes -#include -#include -#include -#include -#include -#include +#include +#if MAX_VERSION_MAJOR >= 14 +# include +# include +# include +# include +# include +# include +# include +# include +# include +#else +# include +# include +// Various MAX and MXS includes +# include +# include +# include +# include +# include +# include +// define the new primitives using macros from SDK +# include +#endif + #include #include #include #include -// define the new primitives using macros from SDK -#include #undef _CRT_SECURE_NO_DEPRECATE @@ -109,9 +123,9 @@ def_visible_primitive( set_tile_bank, "NelSetTileBank"); def_visible_primitive( export_zone, "ExportRykolZone"); def_visible_primitive( import_zone, "NeLImportZone"); -/* permettre l'acces à auto/manual intrior edges +/* permettre l'acces Eauto/manual intrior edges faire une methode pour interfacer la fonction compute interior edge -donner un acces à tiledmode/patchmode (on/off) +donner un acces Etiledmode/patchmode (on/off) faire un getselectedvertex faire un getselectedpatch faire un getselectedtile */ diff --git a/code/nel/tools/3d/plugin_max/nel_patch_edit/np_mods.cpp b/code/nel/tools/3d/plugin_max/nel_patch_edit/np_mods.cpp index c2696674a..8d7467a62 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_edit/np_mods.cpp +++ b/code/nel/tools/3d/plugin_max/nel_patch_edit/np_mods.cpp @@ -17,6 +17,8 @@ #include #include "../nel_3dsmax_shared/nel_3dsmax_shared.h" +#include + HINSTANCE hInstance; int controlsInit = FALSE; @@ -42,7 +44,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved) controlsInit = TRUE; // jaguar controls +#if MAX_VERSION_MAJOR < 14 InitCustomControls(hInstance); +#endif #ifdef OLD3DCONTROLS // initialize 3D controls diff --git a/code/nel/tools/3d/plugin_max/nel_patch_lib/rpo2nel.cpp b/code/nel/tools/3d/plugin_max/nel_patch_lib/rpo2nel.cpp index edf2f77e6..d99dc0f98 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_lib/rpo2nel.cpp +++ b/code/nel/tools/3d/plugin_max/nel_patch_lib/rpo2nel.cpp @@ -18,7 +18,12 @@ // For MAX_RELEASE #include -#include +#include +#if MAX_VERSION_MAJOR >= 14 +# include +#else +# include +#endif #include "rpo.h" #include "nel/3d/zone.h" diff --git a/code/nel/tools/3d/plugin_max/nel_patch_paint/DllEntry.cpp b/code/nel/tools/3d/plugin_max/nel_patch_paint/DllEntry.cpp index a3578a0bc..b4b79da80 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_paint/DllEntry.cpp +++ b/code/nel/tools/3d/plugin_max/nel_patch_paint/DllEntry.cpp @@ -3,6 +3,7 @@ #include "nel/misc/debug.h" #include "nel/misc/app_context.h" #include "../nel_3dsmax_shared/nel_3dsmax_shared.h" +#include HINSTANCE hInstance; int controlsInit = FALSE; @@ -26,7 +27,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved) controlsInit = TRUE; // jaguar controls +#if MAX_VERSION_MAJOR < 14 InitCustomControls(hInstance); +#endif #ifdef OLD3DCONTROLS // initialize 3D controls diff --git a/code/nel/tools/3d/plugin_max/nel_patch_paint/nel_patch_paint.h b/code/nel/tools/3d/plugin_max/nel_patch_paint/nel_patch_paint.h index 944807aca..3563b4712 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_paint/nel_patch_paint.h +++ b/code/nel/tools/3d/plugin_max/nel_patch_paint/nel_patch_paint.h @@ -3,7 +3,12 @@ #include "resource.h" #include -#include +#include +#if MAX_VERSION_MAJOR >= 14 +# include +#else +# include +#endif #include "namesel.h" #include "nsclip.h" #include "sbmtlapi.h" diff --git a/code/nel/tools/3d/plugin_max/nel_vertex_tree_paint/dllmain.cpp b/code/nel/tools/3d/plugin_max/nel_vertex_tree_paint/dllmain.cpp index 4dc068eea..1f04fe088 100644 --- a/code/nel/tools/3d/plugin_max/nel_vertex_tree_paint/dllmain.cpp +++ b/code/nel/tools/3d/plugin_max/nel_vertex_tree_paint/dllmain.cpp @@ -1,6 +1,6 @@ #include "vertex_tree_paint.h" #include "../nel_3dsmax_shared/nel_3dsmax_shared.h" - +#include HINSTANCE hInstance; @@ -18,7 +18,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved) switch (fdwReason) { case DLL_PROCESS_ATTACH: +#if MAX_VERSION_MAJOR < 14 InitCustomControls(hInstance); // Initialize MAX's custom controls +#endif InitCommonControls(); // Initialize Win95 controls break; } diff --git a/code/nel/tools/3d/plugin_max/tile_utility/DllEntry.cpp b/code/nel/tools/3d/plugin_max/tile_utility/DllEntry.cpp index d1c6c7d6b..26e2d14f8 100644 --- a/code/nel/tools/3d/plugin_max/tile_utility/DllEntry.cpp +++ b/code/nel/tools/3d/plugin_max/tile_utility/DllEntry.cpp @@ -20,6 +20,7 @@ #include "nel/misc/app_context.h" #include "../nel_3dsmax_shared/nel_3dsmax_shared.h" #include +#include extern ClassDesc2* GetTile_utilityDesc(); extern ClassDesc* GetRGBAddDesc(); @@ -46,7 +47,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved) if (!controlsInit) { controlsInit = TRUE; +#if MAX_VERSION_MAJOR < 14 InitCustomControls(hInstance); // Initialize MAX's custom controls +#endif InitCommonControls(); // Initialize Win95 controls } diff --git a/code/nel/tools/3d/tile_edit_qt/tile_listwidgetitem.h b/code/nel/tools/3d/tile_edit_qt/tile_listwidgetitem.h index b12be6437..4cf6ee1ae 100644 --- a/code/nel/tools/3d/tile_edit_qt/tile_listwidgetitem.h +++ b/code/nel/tools/3d/tile_edit_qt/tile_listwidgetitem.h @@ -21,17 +21,17 @@ #include "ui_tile_widget_qt.h" class CTile_ListWidgetItem : public QListWidgetItem - { - public: - CTile_ListWidgetItem ( QListWidget * parent, int type = Type ):QListWidgetItem(parent,type){}; +{ +public: + CTile_ListWidgetItem ( QListWidget * parent, int type = Type ):QListWidgetItem(parent,type){} CTile_ListWidgetItem(QWidget *parent = 0); void initWidget(const QPixmap&, const QString&); - private: - Ui::TileWidget ui; +private: + Ui::TileWidget ui; // Qpixmap tilePixmap; // QString tileLabel; - }; +}; #endif \ No newline at end of file diff --git a/code/nel/tools/3d/zone_dependencies/Makefile.am b/code/nel/tools/3d/zone_dependencies/Makefile.am deleted file mode 100644 index 6563d9011..000000000 --- a/code/nel/tools/3d/zone_dependencies/Makefile.am +++ /dev/null @@ -1,22 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2002/05/13 15:44:57 valignat Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = zone_dependencies.dsp - -bin_PROGRAMS = zone_dependencies - -zone_dependencies_SOURCES = zone_dependencies.cpp - -AM_CXXFLAGS = -I$(top_srcdir)/src - -zone_dependencies_LDADD = ../../../src/misc/libnelmisc.la \ - ../../../src/3d/libnel3d.la \ - ../../../src/georges/libnelgeorges.la \ - ../zone_lib/libzone.la - - -# End of Makefile.am - diff --git a/code/nel/tools/3d/zone_ig_lighter/Makefile.am b/code/nel/tools/3d/zone_ig_lighter/Makefile.am deleted file mode 100644 index 79d13da15..000000000 --- a/code/nel/tools/3d/zone_ig_lighter/Makefile.am +++ /dev/null @@ -1,21 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2002/05/13 15:44:57 valignat Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = zone_ig_lighter.dsp - -bin_PROGRAMS = zone_ig_lighter - -zone_ig_lighter_SOURCES = zone_ig_lighter.cpp - -AM_CXXFLAGS = -I$(top_srcdir)/src - -zone_ig_lighter_LDADD = ../../../src/misc/libnelmisc.la \ - ../../../src/3d/libnel3d.la \ - ../zone_lib/libzone.la - - -# End of Makefile.am - diff --git a/code/nel/tools/3d/zone_lib/Makefile.am b/code/nel/tools/3d/zone_lib/Makefile.am deleted file mode 100644 index e3e6927a2..000000000 --- a/code/nel/tools/3d/zone_lib/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2002/05/13 15:44:57 valignat Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -noinst_LTLIBRARIES = libzone.la - -libzone_la_SOURCES = zone_utility.cpp - -noinst_HEADERS = zone_utility.h - -AM_CXXFLAGS = -I$(top_srcdir)/src - -libzone_la_LIBADD = ../../../src/misc/libnelmisc.la \ - ../../../src/3d/libnel3d.la - - -# End of Makefile.am - diff --git a/code/nel/tools/3d/zone_lighter/Makefile.am b/code/nel/tools/3d/zone_lighter/Makefile.am deleted file mode 100644 index 3d70c71b4..000000000 --- a/code/nel/tools/3d/zone_lighter/Makefile.am +++ /dev/null @@ -1,22 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2002/05/13 15:44:57 valignat Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = zone_lighter.dsp - -bin_PROGRAMS = zone_lighter - -zone_lighter_SOURCES = zone_lighter.cpp - -AM_CXXFLAGS = -I$(top_srcdir)/src - -zone_lighter_LDADD = ../../../src/misc/libnelmisc.la \ - ../../../src/3d/libnel3d.la \ - ../../../src/georges/libnelgeorges.la \ - ../zone_lib/libzone.la - - -# End of Makefile.am - diff --git a/code/nel/tools/3d/zone_welder/Makefile.am b/code/nel/tools/3d/zone_welder/Makefile.am deleted file mode 100644 index c405a7fa5..000000000 --- a/code/nel/tools/3d/zone_welder/Makefile.am +++ /dev/null @@ -1,22 +0,0 @@ -# -# $Id: Makefile.am,v 1.1 2002/05/13 15:44:58 valignat Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = zwelder.cfg \ - zone_welder.dsp - -bin_PROGRAMS = zone_welder - -zone_welder_SOURCES = internal_weld.cpp zone_welder.cpp - -AM_CXXFLAGS = -I$(top_srcdir)/src - -zone_welder_LDADD = ../../../src/misc/libnelmisc.la \ - ../../../src/3d/libnel3d.la \ - ../zone_lib/libzone.la - - -# End of Makefile.am - diff --git a/code/nel/tools/Makefile.am b/code/nel/tools/Makefile.am deleted file mode 100644 index 1dba72e96..000000000 --- a/code/nel/tools/Makefile.am +++ /dev/null @@ -1,11 +0,0 @@ -# -# $Id: Makefile.am,v 1.2 2002/05/14 13:33:59 valignat Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -SUBDIRS = 3d misc pacs - - -# End of Makefile.am - diff --git a/code/nel/tools/build_gamedata/0_setup.py b/code/nel/tools/build_gamedata/0_setup.py index d921d03f4..1fe084407 100644 --- a/code/nel/tools/build_gamedata/0_setup.py +++ b/code/nel/tools/build_gamedata/0_setup.py @@ -24,9 +24,27 @@ # along with this program. If not, see . # -import time, sys, os, shutil, subprocess, distutils.dir_util +import time, sys, os, shutil, subprocess, distutils.dir_util, argparse sys.path.append("configuration") +parser = argparse.ArgumentParser(description='Ryzom Core - Build Gamedata - Setup') +parser.add_argument('--noconf', '-nc', action='store_true') +parser.add_argument('--noverify', '-nv', action='store_true') +# parser.add_argument('--haltonerror', '-eh', action='store_true') +parser.add_argument('--includeproject', '-ipj', nargs='+') +parser.add_argument('--excludeproject', '-epj', nargs='+') +parser.add_argument('--includeprocess', '-ipc', nargs='+') +parser.add_argument('--excludeprocess', '-epc', nargs='+') +args = parser.parse_args() + +if not args.includeproject == None and not args.excludeproject == None: + print "ERROR --includeproject cannot be combined with --excludeproject, exit." + exit() + +if not args.includeprocess == None and not args.excludeprocess == None: + print "ERROR --includeprocess cannot be combined with --excludeprocess, exit." + exit() + if os.path.isfile("log.log"): os.remove("log.log") log = open("log.log", "w") @@ -35,221 +53,225 @@ try: from buildsite import * except ImportError: printLog(log, "*** FIRST RUN ***") + if args.noconf: + printLog(log, "ERROR --noconf is invalid on first run, exit.") + exit() from tools import * -try: - BuildQuality -except NameError: - BuildQuality = 1 -try: - ToolDirectories -except NameError: - ToolDirectories = [ 'R:/code/nel', 'R:/code/ryzom/tools' ] -try: - ToolSuffix -except NameError: - ToolSuffix = "_r.exe" -try: - ScriptDirectory -except NameError: - ScriptDirectory = "R:/code/nel/tools/build_gamedata" -try: - WorkspaceDirectory -except NameError: - WorkspaceDirectory = "R:/code/ryzom/tools/build_gamedata/workspace" -try: - DatabaseDirectory -except NameError: - DatabaseDirectory = "W:/database" -try: - ExportBuildDirectory -except NameError: - ExportBuildDirectory = "W:/export" -try: - InstallDirectory -except NameError: - InstallDirectory = "W:/install" -try: - DataShardDirectory -except NameError: - DataShardDirectory = "R:/code/ryzom/server/data_shard" -try: - ClientDevDirectory -except NameError: - ClientDevDirectory = "W:/client_dev" -try: - ClientPatchDirectory -except NameError: - ClientPatchDirectory = "W:/client_patch" -try: - ClientInstallDirectory -except NameError: - ClientInstallDirectory = "W:/client_install" -try: - LeveldesignDirectory -except NameError: - LeveldesignDirectory = "L:/leveldesign" -try: - LeveldesignDfnDirectory -except NameError: - LeveldesignDfnDirectory = "L:/leveldesign/dfn" -try: - LeveldesignWorldDirectory -except NameError: - LeveldesignWorldDirectory = "L:/leveldesign/world" -try: - PrimitivesDirectory -except NameError: - PrimitivesDirectory = "L:/primitives" -try: - GamedevDirectory -except NameError: - GamedevDirectory = "R:/code/ryzom/client/data/gamedev" -try: - DataCommonDirectory -except NameError: - DataCommonDirectory = "R:/code/ryzom/common/data_common" -try: - WindowsExeDllCfgDirectories -except NameError: - WindowsExeDllCfgDirectories = [ 'C:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/redist/x86', 'D:/source/external_local/bin/x86', 'D:/source/external_shared/bin/x86', 'R:/code/nel/lib', 'R:/code/ryzom/bin', 'R:/code/ryzom/client', 'R:/code/ryzom/tools/client/client_config/bin' ] -try: - MaxAvailable -except NameError: - MaxAvailable = 1 -try: - MaxDirectory -except NameError: - MaxDirectory = "C:/Program Files (x86)/Autodesk/3ds Max 2010" -try: - MaxUserDirectory -except NameError: - MaxUserDirectory = "C:/Users/Kaetemi/AppData/Local/Autodesk/3dsMax/2010 - 32bit/enu" -try: - MaxExecutable -except NameError: - MaxExecutable = "3dsmax.exe" +if not args.noconf: + try: + BuildQuality + except NameError: + BuildQuality = 1 + try: + ToolDirectories + except NameError: + ToolDirectories = [ 'R:/build/dev/bin/Release', 'D:/libraries/external/bin' ] + try: + ToolSuffix + except NameError: + ToolSuffix = ".exe" + try: + ScriptDirectory + except NameError: + ScriptDirectory = "R:/code/nel/tools/build_gamedata" + try: + WorkspaceDirectory + except NameError: + WorkspaceDirectory = "R:/code/ryzom/tools/build_gamedata/workspace" + try: + DatabaseDirectory + except NameError: + DatabaseDirectory = "W:/database" + try: + ExportBuildDirectory + except NameError: + ExportBuildDirectory = "W:/export" + try: + InstallDirectory + except NameError: + InstallDirectory = "W:/install" + try: + DataShardDirectory + except NameError: + DataShardDirectory = "R:/code/ryzom/server/data_shard" + try: + ClientDevDirectory + except NameError: + ClientDevDirectory = "W:/client_dev" + try: + ClientPatchDirectory + except NameError: + ClientPatchDirectory = "W:/client_patch" + try: + ClientInstallDirectory + except NameError: + ClientInstallDirectory = "W:/client_install" + try: + LeveldesignDirectory + except NameError: + LeveldesignDirectory = "L:/leveldesign" + try: + LeveldesignDfnDirectory + except NameError: + LeveldesignDfnDirectory = "L:/leveldesign/dfn" + try: + LeveldesignWorldDirectory + except NameError: + LeveldesignWorldDirectory = "L:/leveldesign/world" + try: + PrimitivesDirectory + except NameError: + PrimitivesDirectory = "L:/primitives" + try: + GamedevDirectory + except NameError: + GamedevDirectory = "R:/code/ryzom/client/data/gamedev" + try: + DataCommonDirectory + except NameError: + DataCommonDirectory = "R:/code/ryzom/common/data_common" + try: + WindowsExeDllCfgDirectories + except NameError: + WindowsExeDllCfgDirectories = [ 'C:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/redist/x86', 'D:/libraries/external/bin', 'R:/build/dev/bin/Release', 'R:/code/ryzom/client', 'R:/code/nel/lib', 'R:/code/ryzom/bin', 'R:/code/ryzom/tools/client/client_config/bin' ] + try: + MaxAvailable + except NameError: + MaxAvailable = 1 + try: + MaxDirectory + except NameError: + MaxDirectory = "C:/Program Files (x86)/Autodesk/3ds Max 2010" + try: + MaxUserDirectory + except NameError: + MaxUserDirectory = "C:/Users/Kaetemi/AppData/Local/Autodesk/3dsMax/2010 - 32bit/enu" + try: + MaxExecutable + except NameError: + MaxExecutable = "3dsmax.exe" -printLog(log, "") -printLog(log, "-------") -printLog(log, "--- Setup build site") -printLog(log, "-------") -printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) -printLog(log, "") -printLog(log, "This script will set up the buildsite configuration, and create needed directories.") -printLog(log, "To use the defaults, simply hit ENTER, else type in the new value.") -printLog(log, "Use -- if you need to insert an empty value.") -printLog(log, "") -BuildQuality = int(askVar(log, "Build Quality", str(BuildQuality))) -ToolDirectories[0] = askVar(log, "Primary Tool Directory", ToolDirectories[0]).replace("\\", "/") -ToolDirectories[1] = askVar(log, "Secondary Tool Directory", ToolDirectories[1]).replace("\\", "/") -ToolSuffix = askVar(log, "Tool Suffix", ToolSuffix) -ScriptDirectory = askVar(log, "Script Directory", os.getcwd().replace("\\", "/")).replace("\\", "/") -WorkspaceDirectory = askVar(log, "Workspace Directory", WorkspaceDirectory).replace("\\", "/") -DatabaseDirectory = askVar(log, "Database Directory", DatabaseDirectory).replace("\\", "/") -ExportBuildDirectory = askVar(log, "Export Build Directory", ExportBuildDirectory).replace("\\", "/") -InstallDirectory = askVar(log, "Install Directory", InstallDirectory).replace("\\", "/") -DataShardDirectory = askVar(log, "Data Shard Directory", DataShardDirectory).replace("\\", "/") -ClientDevDirectory = askVar(log, "Client Dev Directory", ClientDevDirectory).replace("\\", "/") -ClientPatchDirectory = askVar(log, "Client Patch Directory", ClientPatchDirectory).replace("\\", "/") -ClientInstallDirectory = askVar(log, "Client Install Directory", ClientInstallDirectory).replace("\\", "/") -LeveldesignDirectory = askVar(log, "Leveldesign Directory", LeveldesignDirectory).replace("\\", "/") -LeveldesignDfnDirectory = askVar(log, "Leveldesign DFN Directory", LeveldesignDfnDirectory).replace("\\", "/") -LeveldesignWorldDirectory = askVar(log, "Leveldesign World Directory", LeveldesignWorldDirectory).replace("\\", "/") -PrimitivesDirectory = askVar(log, "Primitives Directory", PrimitivesDirectory).replace("\\", "/") -GamedevDirectory = askVar(log, "Gamedev Directory", GamedevDirectory).replace("\\", "/") -DataCommonDirectory = askVar(log, "Data Common Directory", DataCommonDirectory).replace("\\", "/") -WindowsExeDllCfgDirectories[0] = askVar(log, "Primary Windows exe/dll/cfg Directory", WindowsExeDllCfgDirectories[0]).replace("\\", "/") -WindowsExeDllCfgDirectories[1] = askVar(log, "Secondary Windows exe/dll/cfg Directory", WindowsExeDllCfgDirectories[1]).replace("\\", "/") -WindowsExeDllCfgDirectories[2] = askVar(log, "Tertiary Windows exe/dll/cfg Directory", WindowsExeDllCfgDirectories[2]).replace("\\", "/") -WindowsExeDllCfgDirectories[3] = askVar(log, "Quaternary Windows exe/dll/cfg Directory", WindowsExeDllCfgDirectories[3]).replace("\\", "/") -WindowsExeDllCfgDirectories[4] = askVar(log, "Quinary Windows exe/dll/cfg Directory", WindowsExeDllCfgDirectories[4]).replace("\\", "/") -WindowsExeDllCfgDirectories[5] = askVar(log, "Senary Windows exe/dll/cfg Directory", WindowsExeDllCfgDirectories[5]).replace("\\", "/") -WindowsExeDllCfgDirectories[6] = askVar(log, "Septenary Windows exe/dll/cfg Directory", WindowsExeDllCfgDirectories[6]).replace("\\", "/") -MaxAvailable = int(askVar(log, "3dsMax Available", str(MaxAvailable))) -if MaxAvailable: - MaxDirectory = askVar(log, "3dsMax Directory", MaxDirectory).replace("\\", "/") - MaxUserDirectory = askVar(log, "3dsMax User Directory", MaxUserDirectory).replace("\\", "/") - MaxExecutable = askVar(log, "3dsMax Executable", MaxExecutable) -if os.path.isfile("configuration/buildsite.py"): - os.remove("configuration/buildsite.py") -sf = open("configuration/buildsite.py", "w") -sf.write("#!/usr/bin/python\n") -sf.write("# \n") -sf.write("# \\file site.py\n") -sf.write("# \\brief Site configuration\n") -sf.write("# \\date " + time.strftime("%Y-%m-%d-%H-%M-GMT", time.gmtime(time.time())) + "\n") -sf.write("# \\author Jan Boon (Kaetemi)\n") -sf.write("# Python port of game data build pipeline.\n") -sf.write("# Site configuration.\n") -sf.write("# \n") -sf.write("# NeL - MMORPG Framework \n") -sf.write("# Copyright (C) 2010 Winch Gate Property Limited\n") -sf.write("# \n") -sf.write("# This program is free software: you can redistribute it and/or modify\n") -sf.write("# it under the terms of the GNU Affero General Public License as\n") -sf.write("# published by the Free Software Foundation, either version 3 of the\n") -sf.write("# License, or (at your option) any later version.\n") -sf.write("# \n") -sf.write("# This program is distributed in the hope that it will be useful,\n") -sf.write("# but WITHOUT ANY WARRANTY; without even the implied warranty of\n") -sf.write("# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n") -sf.write("# GNU Affero General Public License for more details.\n") -sf.write("# \n") -sf.write("# You should have received a copy of the GNU Affero General Public License\n") -sf.write("# along with this program. If not, see .\n") -sf.write("# \n") -sf.write("\n") -sf.write("\n") -sf.write("# *** SITE INSTALLATION ***\n") -sf.write("\n") -sf.write("# Use '/' in path name, not '\'\n") -sf.write("# Don't put '/' at the end of a directory name\n") -sf.write("\n") -sf.write("\n") -sf.write("# Quality option for this site (1 for BEST, 0 for DRAFT)\n") -sf.write("BuildQuality = " + str(BuildQuality) + "\n") -sf.write("\n") -sf.write("ToolDirectories = " + str(ToolDirectories) + "\n") -sf.write("ToolSuffix = \"" + str(ToolSuffix) + "\"\n") -sf.write("\n") -sf.write("# Build script directory\n") -sf.write("ScriptDirectory = \"" + str(ScriptDirectory) + "\"\n") -sf.write("WorkspaceDirectory = \"" + str(WorkspaceDirectory) + "\"\n") -sf.write("\n") -sf.write("# Data build directories\n") -sf.write("DatabaseDirectory = \"" + str(DatabaseDirectory) + "\"\n") -sf.write("ExportBuildDirectory = \"" + str(ExportBuildDirectory) + "\"\n") -sf.write("\n") -sf.write("# Install directories\n") -sf.write("InstallDirectory = \"" + str(InstallDirectory) + "\"\n") -sf.write("DataShardDirectory = \"" + str(DataShardDirectory) + "\"\n") -sf.write("ClientDevDirectory = \"" + str(ClientDevDirectory) + "\"\n") -sf.write("ClientPatchDirectory = \"" + str(ClientPatchDirectory) + "\"\n") -sf.write("ClientInstallDirectory = \"" + str(ClientInstallDirectory) + "\"\n") -sf.write("\n") -sf.write("# TODO: NETWORK RECONNECT NOT IMPLEMENTED :)\n") -sf.write("\n") -sf.write("# Leveldesign directories\n") -sf.write("LeveldesignDirectory = \"" + str(LeveldesignDirectory) + "\"\n") -sf.write("LeveldesignDfnDirectory = \"" + str(LeveldesignDfnDirectory) + "\"\n") -sf.write("LeveldesignWorldDirectory = \"" + str(LeveldesignWorldDirectory) + "\"\n") -sf.write("PrimitivesDirectory = \"" + str(PrimitivesDirectory) + "\"\n") -sf.write("\n") -sf.write("# Misc data directories\n") -sf.write("GamedevDirectory = \"" + str(GamedevDirectory) + "\"\n") -sf.write("DataCommonDirectory = \"" + str(DataCommonDirectory) + "\"\n") -sf.write("WindowsExeDllCfgDirectories = " + str(WindowsExeDllCfgDirectories) + "\n") -sf.write("\n") -sf.write("# 3dsMax directives\n") -sf.write("MaxAvailable = " + str(MaxAvailable) + "\n") -sf.write("MaxDirectory = \"" + str(MaxDirectory) + "\"\n") -sf.write("MaxUserDirectory = \"" + str(MaxUserDirectory) + "\"\n") -sf.write("MaxExecutable = \"" + str(MaxExecutable) + "\"\n") -sf.write("\n") -sf.write("\n") -sf.write("# end of file\n") -sf.close() + printLog(log, "") + printLog(log, "-------") + printLog(log, "--- Setup build site") + printLog(log, "-------") + printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) + printLog(log, "") + printLog(log, "This script will set up the buildsite configuration, and create needed directories.") + printLog(log, "To use the defaults, simply hit ENTER, else type in the new value.") + printLog(log, "Use -- if you need to insert an empty value.") + printLog(log, "") + BuildQuality = int(askVar(log, "Build Quality", str(BuildQuality))) + ToolDirectories[0] = askVar(log, "Primary Tool Directory", ToolDirectories[0]).replace("\\", "/") + ToolDirectories[1] = askVar(log, "Secondary Tool Directory", ToolDirectories[1]).replace("\\", "/") + ToolSuffix = askVar(log, "Tool Suffix", ToolSuffix) + ScriptDirectory = askVar(log, "Script Directory", os.getcwd().replace("\\", "/")).replace("\\", "/") + WorkspaceDirectory = askVar(log, "Workspace Directory", WorkspaceDirectory).replace("\\", "/") + DatabaseDirectory = askVar(log, "Database Directory", DatabaseDirectory).replace("\\", "/") + ExportBuildDirectory = askVar(log, "Export Build Directory", ExportBuildDirectory).replace("\\", "/") + InstallDirectory = askVar(log, "Install Directory", InstallDirectory).replace("\\", "/") + DataShardDirectory = askVar(log, "Data Shard Directory", DataShardDirectory).replace("\\", "/") + ClientDevDirectory = askVar(log, "Client Dev Directory", ClientDevDirectory).replace("\\", "/") + ClientPatchDirectory = askVar(log, "Client Patch Directory", ClientPatchDirectory).replace("\\", "/") + ClientInstallDirectory = askVar(log, "Client Install Directory", ClientInstallDirectory).replace("\\", "/") + LeveldesignDirectory = askVar(log, "Leveldesign Directory", LeveldesignDirectory).replace("\\", "/") + LeveldesignDfnDirectory = askVar(log, "Leveldesign DFN Directory", LeveldesignDfnDirectory).replace("\\", "/") + LeveldesignWorldDirectory = askVar(log, "Leveldesign World Directory", LeveldesignWorldDirectory).replace("\\", "/") + PrimitivesDirectory = askVar(log, "Primitives Directory", PrimitivesDirectory).replace("\\", "/") + GamedevDirectory = askVar(log, "Gamedev Directory", GamedevDirectory).replace("\\", "/") + DataCommonDirectory = askVar(log, "Data Common Directory", DataCommonDirectory).replace("\\", "/") + WindowsExeDllCfgDirectories[0] = askVar(log, "Primary Windows exe/dll/cfg Directory", WindowsExeDllCfgDirectories[0]).replace("\\", "/") + WindowsExeDllCfgDirectories[1] = askVar(log, "Secondary Windows exe/dll/cfg Directory", WindowsExeDllCfgDirectories[1]).replace("\\", "/") + WindowsExeDllCfgDirectories[2] = askVar(log, "Tertiary Windows exe/dll/cfg Directory", WindowsExeDllCfgDirectories[2]).replace("\\", "/") + WindowsExeDllCfgDirectories[3] = askVar(log, "Quaternary Windows exe/dll/cfg Directory", WindowsExeDllCfgDirectories[3]).replace("\\", "/") + WindowsExeDllCfgDirectories[4] = askVar(log, "Quinary Windows exe/dll/cfg Directory", WindowsExeDllCfgDirectories[4]).replace("\\", "/") + WindowsExeDllCfgDirectories[5] = askVar(log, "Senary Windows exe/dll/cfg Directory", WindowsExeDllCfgDirectories[5]).replace("\\", "/") + WindowsExeDllCfgDirectories[6] = askVar(log, "Septenary Windows exe/dll/cfg Directory", WindowsExeDllCfgDirectories[6]).replace("\\", "/") + MaxAvailable = int(askVar(log, "3dsMax Available", str(MaxAvailable))) + if MaxAvailable: + MaxDirectory = askVar(log, "3dsMax Directory", MaxDirectory).replace("\\", "/") + MaxUserDirectory = askVar(log, "3dsMax User Directory", MaxUserDirectory).replace("\\", "/") + MaxExecutable = askVar(log, "3dsMax Executable", MaxExecutable) + if os.path.isfile("configuration/buildsite.py"): + os.remove("configuration/buildsite.py") + sf = open("configuration/buildsite.py", "w") + sf.write("#!/usr/bin/python\n") + sf.write("# \n") + sf.write("# \\file site.py\n") + sf.write("# \\brief Site configuration\n") + sf.write("# \\date " + time.strftime("%Y-%m-%d-%H-%M-GMT", time.gmtime(time.time())) + "\n") + sf.write("# \\author Jan Boon (Kaetemi)\n") + sf.write("# Python port of game data build pipeline.\n") + sf.write("# Site configuration.\n") + sf.write("# \n") + sf.write("# NeL - MMORPG Framework \n") + sf.write("# Copyright (C) 2010 Winch Gate Property Limited\n") + sf.write("# \n") + sf.write("# This program is free software: you can redistribute it and/or modify\n") + sf.write("# it under the terms of the GNU Affero General Public License as\n") + sf.write("# published by the Free Software Foundation, either version 3 of the\n") + sf.write("# License, or (at your option) any later version.\n") + sf.write("# \n") + sf.write("# This program is distributed in the hope that it will be useful,\n") + sf.write("# but WITHOUT ANY WARRANTY; without even the implied warranty of\n") + sf.write("# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n") + sf.write("# GNU Affero General Public License for more details.\n") + sf.write("# \n") + sf.write("# You should have received a copy of the GNU Affero General Public License\n") + sf.write("# along with this program. If not, see .\n") + sf.write("# \n") + sf.write("\n") + sf.write("\n") + sf.write("# *** SITE INSTALLATION ***\n") + sf.write("\n") + sf.write("# Use '/' in path name, not '\'\n") + sf.write("# Don't put '/' at the end of a directory name\n") + sf.write("\n") + sf.write("\n") + sf.write("# Quality option for this site (1 for BEST, 0 for DRAFT)\n") + sf.write("BuildQuality = " + str(BuildQuality) + "\n") + sf.write("\n") + sf.write("ToolDirectories = " + str(ToolDirectories) + "\n") + sf.write("ToolSuffix = \"" + str(ToolSuffix) + "\"\n") + sf.write("\n") + sf.write("# Build script directory\n") + sf.write("ScriptDirectory = \"" + str(ScriptDirectory) + "\"\n") + sf.write("WorkspaceDirectory = \"" + str(WorkspaceDirectory) + "\"\n") + sf.write("\n") + sf.write("# Data build directories\n") + sf.write("DatabaseDirectory = \"" + str(DatabaseDirectory) + "\"\n") + sf.write("ExportBuildDirectory = \"" + str(ExportBuildDirectory) + "\"\n") + sf.write("\n") + sf.write("# Install directories\n") + sf.write("InstallDirectory = \"" + str(InstallDirectory) + "\"\n") + sf.write("DataShardDirectory = \"" + str(DataShardDirectory) + "\"\n") + sf.write("ClientDevDirectory = \"" + str(ClientDevDirectory) + "\"\n") + sf.write("ClientPatchDirectory = \"" + str(ClientPatchDirectory) + "\"\n") + sf.write("ClientInstallDirectory = \"" + str(ClientInstallDirectory) + "\"\n") + sf.write("\n") + sf.write("# TODO: NETWORK RECONNECT NOT IMPLEMENTED :)\n") + sf.write("\n") + sf.write("# Leveldesign directories\n") + sf.write("LeveldesignDirectory = \"" + str(LeveldesignDirectory) + "\"\n") + sf.write("LeveldesignDfnDirectory = \"" + str(LeveldesignDfnDirectory) + "\"\n") + sf.write("LeveldesignWorldDirectory = \"" + str(LeveldesignWorldDirectory) + "\"\n") + sf.write("PrimitivesDirectory = \"" + str(PrimitivesDirectory) + "\"\n") + sf.write("\n") + sf.write("# Misc data directories\n") + sf.write("GamedevDirectory = \"" + str(GamedevDirectory) + "\"\n") + sf.write("DataCommonDirectory = \"" + str(DataCommonDirectory) + "\"\n") + sf.write("WindowsExeDllCfgDirectories = " + str(WindowsExeDllCfgDirectories) + "\n") + sf.write("\n") + sf.write("# 3dsMax directives\n") + sf.write("MaxAvailable = " + str(MaxAvailable) + "\n") + sf.write("MaxDirectory = \"" + str(MaxDirectory) + "\"\n") + sf.write("MaxUserDirectory = \"" + str(MaxUserDirectory) + "\"\n") + sf.write("MaxExecutable = \"" + str(MaxExecutable) + "\"\n") + sf.write("\n") + sf.write("\n") + sf.write("# end of file\n") + sf.close() sys.path.append(WorkspaceDirectory) from projects import * @@ -262,22 +284,83 @@ printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) printLog(log, "") # For each project for projectName in ProjectsToProcess: - os.putenv("NELBUILDACTIVEPROJECT", os.path.abspath(WorkspaceDirectory + "/" + projectName)) - os.chdir("processes") - try: - subprocess.call([ "python", "0_setup.py" ]) - except Exception, e: - printLog(log, "<" + projectName + "> " + str(e)) - os.chdir("..") - try: - projectLog = open("processes/log.log", "r") - projectLogData = projectLog.read() - projectLog.close() - log.write(projectLogData) - except Exception, e: - printLog(log, "<" + projectName + "> " + str(e)) + if ((args.includeproject == None or projectName in args.includeproject) and (args.excludeproject == None or not projectName in args.excludeproject)): + printLog(log, "PROJECT " + projectName) + os.putenv("NELBUILDACTIVEPROJECT", os.path.abspath(WorkspaceDirectory + "/" + projectName)) + os.chdir("processes") + try: + if not args.includeprocess == None: + subprocess.call([ "python", "0_setup.py", "--includeprocess" ] + args.includeprocess) + elif not args.excludeprocess == None: + subprocess.call([ "python", "0_setup.py", "--excludeprocess" ] + args.excludeprocess) + else: + subprocess.call([ "python", "0_setup.py" ]) + except Exception, e: + printLog(log, "<" + projectName + "> " + str(e)) + os.chdir("..") + try: + projectLog = open("processes/log.log", "r") + projectLogData = projectLog.read() + projectLog.close() + log.write(projectLogData) + except Exception, e: + printLog(log, "<" + projectName + "> " + str(e)) + else: + printLog(log, "IGNORE PROJECT " + projectName) printLog(log, "") +# Additional directories +printLog(log, ">>> Setup additional directories <<<") +mkPath(log, ClientDevDirectory) +mkPath(log, ClientPatchDirectory) +mkPath(log, ClientInstallDirectory) + +if not args.noverify: + printLog(log, "") + printLog(log, "-------") + printLog(log, "--- Verify tool paths") + printLog(log, "-------") + printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) + printLog(log, "") + if MaxAvailable: + findMax(log, MaxDirectory, MaxExecutable) + findTool(log, ToolDirectories, TgaToDdsTool, ToolSuffix) + findTool(log, ToolDirectories, BuildInterfaceTool, ToolSuffix) + findTool(log, ToolDirectories, ExecTimeoutTool, ToolSuffix) + findTool(log, ToolDirectories, BuildSmallbankTool, ToolSuffix) + findTool(log, ToolDirectories, BuildFarbankTool, ToolSuffix) + findTool(log, ToolDirectories, ZoneDependenciesTool, ToolSuffix) + findTool(log, ToolDirectories, ZoneWelderTool, ToolSuffix) + findTool(log, ToolDirectories, BuildRbankTool, ToolSuffix) + findTool(log, ToolDirectories, BuildIndoorRbankTool, ToolSuffix) + findTool(log, ToolDirectories, BuildIgBoxesTool, ToolSuffix) + findTool(log, ToolDirectories, GetNeighborsTool, ToolSuffix) + findTool(log, ToolDirectories, ZoneLighterTool, ToolSuffix) + findTool(log, ToolDirectories, ZoneIgLighterTool, ToolSuffix) + findTool(log, ToolDirectories, IgLighterTool, ToolSuffix) + findTool(log, ToolDirectories, AnimBuilderTool, ToolSuffix) + findTool(log, ToolDirectories, TileEditTool, ToolSuffix) + # findTool(log, ToolDirectories, BuildImagesetTool, ToolSuffix) # kaetemi stuff, ignore this + findTool(log, ToolDirectories, MakeSheetIdTool, ToolSuffix) + # findTool(log, ToolDirectories, BuildSheetsTool, ToolSuffix) # kaetemi stuff, ignore this + # findTool(log, ToolDirectories, BuildSoundTool, ToolSuffix) # kaetemi stuff, ignore this + findTool(log, ToolDirectories, BuildCoarseMeshTool, ToolSuffix) + findTool(log, ToolDirectories, LightmapOptimizerTool, ToolSuffix) + findTool(log, ToolDirectories, BuildClodtexTool, ToolSuffix) + findTool(log, ToolDirectories, BuildShadowSkinTool, ToolSuffix) + findTool(log, ToolDirectories, PanoplyMakerTool, ToolSuffix) + findTool(log, ToolDirectories, HlsBankMakerTool, ToolSuffix) + findTool(log, ToolDirectories, LandExportTool, ToolSuffix) + findTool(log, ToolDirectories, PrimExportTool, ToolSuffix) + findTool(log, ToolDirectories, IgElevationTool, ToolSuffix) + findTool(log, ToolDirectories, IgAddTool, ToolSuffix) + findTool(log, ToolDirectories, BuildClodBankTool, ToolSuffix) + findTool(log, ToolDirectories, SheetsPackerTool, ToolSuffix) + findTool(log, ToolDirectories, BnpMakeTool, ToolSuffix) + findTool(log, ToolDirectories, AiBuildWmapTool, ToolSuffix) + findTool(log, ToolDirectories, TgaCutTool, ToolSuffix) + findTool(log, ToolDirectories, PatchGenTool, ToolSuffix) + log.close() if os.path.isfile("0_setup.log"): os.remove("0_setup.log") diff --git a/code/nel/tools/build_gamedata/1_export.py b/code/nel/tools/build_gamedata/1_export.py index 0fb684592..6abe0a3a5 100644 --- a/code/nel/tools/build_gamedata/1_export.py +++ b/code/nel/tools/build_gamedata/1_export.py @@ -24,9 +24,25 @@ # along with this program. If not, see . # -import time, sys, os, shutil, subprocess, distutils.dir_util +import time, sys, os, shutil, subprocess, distutils.dir_util, argparse sys.path.append("configuration") +parser = argparse.ArgumentParser(description='Ryzom Core - Build Gamedata - Export') +# parser.add_argument('--haltonerror', '-eh', action='store_true') +parser.add_argument('--includeproject', '-ipj', nargs='+') +parser.add_argument('--excludeproject', '-epj', nargs='+') +parser.add_argument('--includeprocess', '-ipc', nargs='+') +parser.add_argument('--excludeprocess', '-epc', nargs='+') +args = parser.parse_args() + +if not args.includeproject == None and not args.excludeproject == None: + print "ERROR --includeproject cannot be combined with --excludeproject, exit." + exit() + +if not args.includeprocess == None and not args.excludeprocess == None: + print "ERROR --includeprocess cannot be combined with --excludeprocess, exit." + exit() + if os.path.isfile("log.log"): os.remove("log.log") log = open("log.log", "w") @@ -46,20 +62,29 @@ printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) printLog(log, "") # For each project for projectName in ProjectsToProcess: - os.putenv("NELBUILDACTIVEPROJECT", os.path.abspath(WorkspaceDirectory + "/" + projectName)) - os.chdir("processes") - try: - subprocess.call([ "python", "1_export.py" ]) - except Exception, e: - printLog(log, "<" + projectName + "> " + str(e)) - os.chdir("..") - try: - projectLog = open("processes/log.log", "r") - projectLogData = projectLog.read() - projectLog.close() - log.write(projectLogData) - except Exception, e: - printLog(log, "<" + projectName + "> " + str(e)) + if ((args.includeproject == None or projectName in args.includeproject) and (args.excludeproject == None or not projectName in args.excludeproject)): + printLog(log, "PROJECT " + projectName) + os.putenv("NELBUILDACTIVEPROJECT", os.path.abspath(WorkspaceDirectory + "/" + projectName)) + os.chdir("processes") + try: + if not args.includeprocess == None: + subprocess.call([ "python", "1_export.py", "--includeprocess" ] + args.includeprocess) + elif not args.excludeprocess == None: + subprocess.call([ "python", "1_export.py", "--excludeprocess" ] + args.excludeprocess) + else: + subprocess.call([ "python", "1_export.py" ]) + except Exception, e: + printLog(log, "<" + projectName + "> " + str(e)) + os.chdir("..") + try: + projectLog = open("processes/log.log", "r") + projectLogData = projectLog.read() + projectLog.close() + log.write(projectLogData) + except Exception, e: + printLog(log, "<" + projectName + "> " + str(e)) + else: + printLog(log, "IGNORE PROJECT " + projectName) printLog(log, "") log.close() diff --git a/code/nel/tools/build_gamedata/2_build.py b/code/nel/tools/build_gamedata/2_build.py index a6229c29c..36a171161 100644 --- a/code/nel/tools/build_gamedata/2_build.py +++ b/code/nel/tools/build_gamedata/2_build.py @@ -24,9 +24,25 @@ # along with this program. If not, see . # -import time, sys, os, shutil, subprocess, distutils.dir_util +import time, sys, os, shutil, subprocess, distutils.dir_util, argparse sys.path.append("configuration") +parser = argparse.ArgumentParser(description='Ryzom Core - Build Gamedata - Build') +# parser.add_argument('--haltonerror', '-eh', action='store_true') +parser.add_argument('--includeproject', '-ipj', nargs='+') +parser.add_argument('--excludeproject', '-epj', nargs='+') +parser.add_argument('--includeprocess', '-ipc', nargs='+') +parser.add_argument('--excludeprocess', '-epc', nargs='+') +args = parser.parse_args() + +if not args.includeproject == None and not args.excludeproject == None: + print "ERROR --includeproject cannot be combined with --excludeproject, exit." + exit() + +if not args.includeprocess == None and not args.excludeprocess == None: + print "ERROR --includeprocess cannot be combined with --excludeprocess, exit." + exit() + if os.path.isfile("log.log"): os.remove("log.log") log = open("log.log", "w") @@ -46,20 +62,29 @@ printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) printLog(log, "") # For each project for projectName in ProjectsToProcess: - os.putenv("NELBUILDACTIVEPROJECT", os.path.abspath(WorkspaceDirectory + "/" + projectName)) - os.chdir("processes") - try: - subprocess.call([ "python", "2_build.py" ]) - except Exception, e: - printLog(log, "<" + projectName + "> " + str(e)) - os.chdir("..") - try: - projectLog = open("processes/log.log", "r") - projectLogData = projectLog.read() - projectLog.close() - log.write(projectLogData) - except Exception, e: - printLog(log, "<" + projectName + "> " + str(e)) + if ((args.includeproject == None or projectName in args.includeproject) and (args.excludeproject == None or not projectName in args.excludeproject)): + printLog(log, "PROJECT " + projectName) + os.putenv("NELBUILDACTIVEPROJECT", os.path.abspath(WorkspaceDirectory + "/" + projectName)) + os.chdir("processes") + try: + if not args.includeprocess == None: + subprocess.call([ "python", "2_build.py", "--includeprocess" ] + args.includeprocess) + elif not args.excludeprocess == None: + subprocess.call([ "python", "2_build.py", "--excludeprocess" ] + args.excludeprocess) + else: + subprocess.call([ "python", "2_build.py" ]) + except Exception, e: + printLog(log, "<" + projectName + "> " + str(e)) + os.chdir("..") + try: + projectLog = open("processes/log.log", "r") + projectLogData = projectLog.read() + projectLog.close() + log.write(projectLogData) + except Exception, e: + printLog(log, "<" + projectName + "> " + str(e)) + else: + printLog(log, "IGNORE PROJECT " + projectName) printLog(log, "") log.close() diff --git a/code/nel/tools/build_gamedata/3_install.py b/code/nel/tools/build_gamedata/3_install.py index 70ece522b..39a19dea3 100644 --- a/code/nel/tools/build_gamedata/3_install.py +++ b/code/nel/tools/build_gamedata/3_install.py @@ -24,9 +24,25 @@ # along with this program. If not, see . # -import time, sys, os, shutil, subprocess, distutils.dir_util +import time, sys, os, shutil, subprocess, distutils.dir_util, argparse sys.path.append("configuration") +parser = argparse.ArgumentParser(description='Ryzom Core - Build Gamedata - Install') +# parser.add_argument('--haltonerror', '-eh', action='store_true') +parser.add_argument('--includeproject', '-ipj', nargs='+') +parser.add_argument('--excludeproject', '-epj', nargs='+') +parser.add_argument('--includeprocess', '-ipc', nargs='+') +parser.add_argument('--excludeprocess', '-epc', nargs='+') +args = parser.parse_args() + +if not args.includeproject == None and not args.excludeproject == None: + print "ERROR --includeproject cannot be combined with --excludeproject, exit." + exit() + +if not args.includeprocess == None and not args.excludeprocess == None: + print "ERROR --includeprocess cannot be combined with --excludeprocess, exit." + exit() + if os.path.isfile("log.log"): os.remove("log.log") log = open("log.log", "w") @@ -46,20 +62,29 @@ printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) printLog(log, "") # For each project for projectName in ProjectsToProcess: - os.putenv("NELBUILDACTIVEPROJECT", os.path.abspath(WorkspaceDirectory + "/" + projectName)) - os.chdir("processes") - try: - subprocess.call([ "python", "3_install.py" ]) - except Exception, e: - printLog(log, "<" + projectName + "> " + str(e)) - os.chdir("..") - try: - projectLog = open("processes/log.log", "r") - projectLogData = projectLog.read() - projectLog.close() - log.write(projectLogData) - except Exception, e: - printLog(log, "<" + projectName + "> " + str(e)) + if ((args.includeproject == None or projectName in args.includeproject) and (args.excludeproject == None or not projectName in args.excludeproject)): + printLog(log, "PROJECT " + projectName) + os.putenv("NELBUILDACTIVEPROJECT", os.path.abspath(WorkspaceDirectory + "/" + projectName)) + os.chdir("processes") + try: + if not args.includeprocess == None: + subprocess.call([ "python", "3_install.py", "--includeprocess" ] + args.includeprocess) + elif not args.excludeprocess == None: + subprocess.call([ "python", "3_install.py", "--excludeprocess" ] + args.excludeprocess) + else: + subprocess.call([ "python", "3_install.py" ]) + except Exception, e: + printLog(log, "<" + projectName + "> " + str(e)) + os.chdir("..") + try: + projectLog = open("processes/log.log", "r") + projectLogData = projectLog.read() + projectLog.close() + log.write(projectLogData) + except Exception, e: + printLog(log, "<" + projectName + "> " + str(e)) + else: + printLog(log, "IGNORE PROJECT " + projectName) printLog(log, "") log.close() diff --git a/code/nel/tools/build_gamedata/6_client_patch.py b/code/nel/tools/build_gamedata/6_client_patch.py index 7689cc404..c41312df3 100644 --- a/code/nel/tools/build_gamedata/6_client_patch.py +++ b/code/nel/tools/build_gamedata/6_client_patch.py @@ -24,9 +24,13 @@ # along with this program. If not, see . # -import time, sys, os, shutil, subprocess, distutils.dir_util +import time, sys, os, shutil, subprocess, distutils.dir_util, argparse sys.path.append("configuration") +parser = argparse.ArgumentParser(description='Ryzom Core - Build Gamedata - Client Patch') +parser.add_argument('--bnponly', '-bo', action='store_true') +args = parser.parse_args() + if os.path.isfile("log.log"): os.remove("log.log") log = open("log.log", "w") @@ -59,56 +63,57 @@ printLog(log, "") if BnpMake == "": toolLogFail(log, BnpMakeTool, ToolSuffix) -elif PatchGen == "": +elif PatchGen == "" and not args.bnponly: toolLogFail(log, PatchGenTool, ToolSuffix) -elif Lzma == "": +elif Lzma == "" and not args.bnponly: toolLogFail(log, "LZMA", ToolSuffix) -elif XDelta == "": +elif XDelta == "" and not args.bnponly: toolLogFail(log, "XDELTA", ToolSuffix) elif os.path.dirname(Lzma) != os.path.dirname(XDelta): printLog(log, "FAIL lzma.exe and xdelta.exe must be in the same directory") else: mkPath(log, ClientPatchDirectory) - productXml = ClientPatchDirectory + "/" + ProductName + ".xml" - if not os.path.isfile(productXml): - printLog(log, ">>> Create new product <<<") - subprocess.call([ PatchGen, "createNewProduct", productXml ]) - printLog(log, "") - printLog(log, ">>> Rewrite " + ProductName + ".xml <<<") # because we know better. - shutil.move(productXml, productXml + ".old") - oldCfg = open(productXml + ".old", "r") - cfg = open(productXml, "w") - inCategories = 0 - for line in oldCfg: - if not inCategories: - if line.strip() == "<_Categories>": - inCategories = 1 - cfg.write("\t<_Categories>\n") - for category in InstallClientData: - cfg.write("\t\t<_Category>\n") - cfg.write("\t\t\t<_Name type=\"STRING\" value=\"" + category["Name"] + "\"/>\n") - if category["UnpackTo"] != None: - if category["UnpackTo"] != "": - cfg.write("\t\t\t<_UnpackTo type=\"STRING\" value=\"./" + category["UnpackTo"] + "/\"/>\n") - else: - cfg.write("\t\t\t<_UnpackTo type=\"SINT32\" value=\"./\"/>\n") - cfg.write("\t\t\t<_IsOptional type=\"SINT32\" value=\"" + str(category["IsOptional"]) + "\"/>\n") - cfg.write("\t\t\t<_IsIncremental type=\"SINT32\" value=\"" + str(category["IsIncremental"]) + "\"/>\n") - for package in category["Packages"]: - if (len(package[1]) > 0): - cfg.write("\t\t\t<_Files type=\"STRING\" value=\"" + package[1][0] + "\"/>\n") - else: - cfg.write("\t\t\t<_Files type=\"STRING\" value=\"" + package[0] + ".bnp\"/>\n") - cfg.write("\t\t\n") - cfg.write("\t\n") + if not args.bnponly: + productXml = ClientPatchDirectory + "/" + ProductName + ".xml" + if not os.path.isfile(productXml): + printLog(log, ">>> Create new product <<<") + subprocess.call([ PatchGen, "createNewProduct", productXml ]) + printLog(log, "") + printLog(log, ">>> Rewrite " + ProductName + ".xml <<<") # because we know better. + shutil.move(productXml, productXml + ".old") + oldCfg = open(productXml + ".old", "r") + cfg = open(productXml, "w") + inCategories = 0 + for line in oldCfg: + if not inCategories: + if line.strip() == "<_Categories>": + inCategories = 1 + cfg.write("\t<_Categories>\n") + for category in InstallClientData: + cfg.write("\t\t<_Category>\n") + cfg.write("\t\t\t<_Name type=\"STRING\" value=\"" + category["Name"] + "\"/>\n") + if category["UnpackTo"] != None: + if category["UnpackTo"] != "": + cfg.write("\t\t\t<_UnpackTo type=\"STRING\" value=\"./" + category["UnpackTo"] + "/\"/>\n") + else: + cfg.write("\t\t\t<_UnpackTo type=\"SINT32\" value=\"./\"/>\n") + cfg.write("\t\t\t<_IsOptional type=\"SINT32\" value=\"" + str(category["IsOptional"]) + "\"/>\n") + cfg.write("\t\t\t<_IsIncremental type=\"SINT32\" value=\"" + str(category["IsIncremental"]) + "\"/>\n") + for package in category["Packages"]: + if (len(package[1]) > 0): + cfg.write("\t\t\t<_Files type=\"STRING\" value=\"" + package[1][0] + "\"/>\n") + else: + cfg.write("\t\t\t<_Files type=\"STRING\" value=\"" + package[0] + ".bnp\"/>\n") + cfg.write("\t\t\n") + cfg.write("\t\n") + else: + cfg.write(line) else: - cfg.write(line) - else: - if line.strip() == "": - inCategories = 0 - oldCfg.close() - cfg.close() - os.remove(productXml + ".old") + if line.strip() == "": + inCategories = 0 + oldCfg.close() + cfg.close() + os.remove(productXml + ".old") printLog(log, "") printLog(log, ">>> Make bnp <<<") targetPath = ClientPatchDirectory + "/bnp" @@ -133,13 +138,14 @@ else: else: printLog(log, "SKIP " + targetBnp) printLog(log, "") - printLog(log, ">>> Update product <<<") - cwDir = os.getcwd().replace("\\", "/") - toolDir = os.path.dirname(Lzma).replace("\\", "/") - os.chdir(toolDir) - subprocess.call([ PatchGen, "updateProduct", productXml ]) - os.chdir(cwDir) - printLog(log, "") + if not args.bnponly: + printLog(log, ">>> Update product <<<") + cwDir = os.getcwd().replace("\\", "/") + toolDir = os.path.dirname(Lzma).replace("\\", "/") + os.chdir(toolDir) + subprocess.call([ PatchGen, "updateProduct", productXml ]) + os.chdir(cwDir) + printLog(log, "") log.close() diff --git a/code/nel/tools/build_gamedata/7_client_install.py b/code/nel/tools/build_gamedata/7_client_install.py index b5a5bab1f..c4c1ab03c 100644 --- a/code/nel/tools/build_gamedata/7_client_install.py +++ b/code/nel/tools/build_gamedata/7_client_install.py @@ -45,45 +45,30 @@ printLog(log, "-------") printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) printLog(log, "") -# Find tools -BnpMake = findTool(log, ToolDirectories, BnpMakeTool, ToolSuffix) -printLog(log, "") - -if BnpMake == "": - toolLogFail(log, BnpMakeTool, ToolSuffix) -else: - for category in InstallClientData: - printLog(log, "CATEGORY " + category["Name"]) - if (category["UnpackTo"] != None): - targetPath = ClientInstallDirectory - if (category["UnpackTo"] != ""): - targetPath += "/" + category["UnpackTo"] - mkPath(log, targetPath) - for package in category["Packages"]: - printLog(log, "PACKAGE " + package[0]) - mkPath(log, InstallDirectory + "/" + package[0]) - copyFilesNoTreeIfNeeded(log, InstallDirectory + "/" + package[0], targetPath) - else: - targetPath = ClientInstallDirectory + "/data" - mkPath(log, targetPath) - for package in category["Packages"]: - printLog(log, "PACKAGE " + package[0]) - sourcePath = InstallDirectory + "/" + package[0] - mkPath(log, sourcePath) - targetBnp = targetPath + "/" + package[0] + ".bnp" - if (len(package[1]) > 0): - targetBnp = targetPath + "/" + package[1][0] - printLog(log, "TARGET " + package[1][0]) - needUpdateBnp = 1 - if (len(package) > 2): - needUpdateBnp = needUpdate(log, sourcePath + "/" + package[2], targetBnp) - else: - needUpdateBnp = needUpdateDirNoSubdirFile(log, sourcePath, targetBnp) - if (needUpdateBnp): - printLog(log, "BNP " + targetBnp) - subprocess.call([ BnpMake, "/p", sourcePath, targetPath ] + package[1]) - else: - printLog(log, "SKIP " + targetBnp) +for category in InstallClientData: + printLog(log, "CATEGORY " + category["Name"]) + if (category["UnpackTo"] != None): + targetPath = ClientInstallDirectory + if (category["UnpackTo"] != ""): + targetPath += "/" + category["UnpackTo"] + mkPath(log, targetPath) + for package in category["Packages"]: + printLog(log, "PACKAGE " + package[0]) + mkPath(log, InstallDirectory + "/" + package[0]) + copyFilesNoTreeIfNeeded(log, InstallDirectory + "/" + package[0], targetPath) + else: + sourcePath = ClientPatchDirectory + "/bnp" + targetPath = ClientInstallDirectory + "/data" + mkPath(log, targetPath) + for package in category["Packages"]: + printLog(log, "PACKAGE " + package[0]) + sourceBnp = sourcePath + "/" + package[0] + ".bnp" + targetBnp = targetPath + "/" + package[0] + ".bnp" + if (len(package[1]) > 0): + sourceBnp = sourcePath + "/" + package[1][0] + targetBnp = targetPath + "/" + package[1][0] + printLog(log, "TARGET " + package[1][0]) + copyFileIfNeeded(log, sourceBnp, targetBnp) printLog(log, "") log.close() diff --git a/code/nel/tools/build_gamedata/8_upload.py b/code/nel/tools/build_gamedata/8_upload.py new file mode 100644 index 000000000..1b60aad68 --- /dev/null +++ b/code/nel/tools/build_gamedata/8_upload.py @@ -0,0 +1,181 @@ +#!/usr/bin/python +# +# \file 8_upload.py +# \brief Upload data to servers +# \date 2009-02-18 16:19GMT +# \author Jan Boon (Kaetemi) +# Game data build pipeline. +# Upload data to servers +# +# NeL - MMORPG Framework +# Copyright (C) 2011 Kaetemi +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +import time, sys, os, shutil, subprocess, distutils.dir_util +sys.path.append("configuration") + +if os.path.isfile("log.log"): + os.remove("log.log") +log = open("log.log", "w") +from scripts import * +from buildsite import * +from tools import * + +try: + from upload import * +except ImportError: + # Not documenting this. Because we can. + printLog(log, "ERROR Upload not configured, bye.") + exit() + +sys.path.append(WorkspaceDirectory) +from projects import * + +# Log error +printLog(log, "") +printLog(log, "-------") +printLog(log, "--- Upload data to servers") +printLog(log, "-------") +printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) +printLog(log, "") + +# Find tools +# Not documenting this. Because we can. +Psftp = findFileMultiDir(log, ToolDirectories + WindowsExeDllCfgDirectories, UploadPsftpTool) +printLog(log, "PSFTP " + Psftp) + +def downloadVersionTag(server, user, sshkey, dir): + if os.path.isfile("upload.tag"): + os.remove("upload.tag") + if os.path.isfile("upload.batch"): + os.remove("upload.batch") + ub = open("upload.batch", "w") + ub.write("cd " + dir + "\n") + ub.write("get upload.tag upload.tag\n") + ub.write("quit\n") + ub.close() + subprocess.call([ Psftp, "-b", "upload.batch", "-i", sshkey, user + "@" + server ]) + os.remove("upload.batch") + if os.path.isfile("upload.tag"): + ft = open("upload.tag") + result = float(ft.read()) # float, really + ft.close() + os.remove("upload.tag") + printLog(log, "INFO Upload tag is " + str(result)) + return result + else: + printLog(log, "WARNING Upload tag not found, uploading everything") + return 0 + +def isDirectoryNeeded(ft, dir): + files = os.listdir(dir) + for fileName in files: + if isLegalFileName(fileName): + fileFull = dir + "/" + fileName + if os.path.isfile(fileFull): + nftf = os.stat(fileFull).st_mtime + if nftf > ft: + return True + elif os.path.isdir(fileFull): + if isDirectoryNeeded(ft, fileFull): + return True + elif not os.path.isdir(fileFull): + printLog(log, "isDirectoryNeeded: file not dir or file?!" + fileFull) + return False + +def listDirectoryUpload(ft, ub, udb, dir): + nft = 0 + files = os.listdir(dir) + for fileName in files: + if isLegalFileName(fileName): + fileFull = dir + "/" + fileName + if os.path.isfile(fileFull): + nftf = os.stat(fileFull).st_mtime + if nftf > ft: + ub.write("put " + fileFull + " " + fileName + "\n") + if nftf > nft: + nft = nftf + elif os.path.isdir(fileFull): + if isDirectoryNeeded(ft, fileFull): + udb.write("mkdir " + fileName + "\n") + ub.write("cd " + fileName + "\n") + udb.write("cd " + fileName + "\n") + nft2 = listDirectoryUpload(ft, ub, udb, fileFull) + if (nft2 > nft): + nft = nft2 + ub.write("cd ..\n") + udb.write("cd ..\n") + elif not os.path.isdir(fileFull): + printLog(log, "listDirectoryUpload: file not dir or file?!" + fileFull) + return nft + +def uploadSftp(server, user, sshkey, dir_to, dir_from, addcmd): + ft = downloadVersionTag(server, user, sshkey, dir_to) + if isDirectoryNeeded(ft, dir_from): + if os.path.isfile("upload_dir.batch"): + os.remove("upload_dir.batch") + if os.path.isfile("upload.batch"): + os.remove("upload.batch") + udb = open("upload_dir.batch", "w") + udb.write("cd " + dir_to + "\n") + ub = open("upload.batch", "w") + ub.write("cd " + dir_to + "\n") + for ac in addcmd: + ub.write(ac + "\n") + ftn = listDirectoryUpload(ft, ub, udb, dir_from) + if (ft > ftn): + ftn = ft + nft = open("upload.tag", "w") + nft.write(str(ftn)) + nft.close() + ub.write("put upload.tag upload.tag\n") + ub.write("quit\n") + ub.close() + udb.write("quit\n") + udb.close() + subprocess.call([ Psftp, "-be", "-b", "upload_dir.batch", "-i", sshkey, user + "@" + server ]) + subprocess.call([ Psftp, "-b", "upload.batch", "-i", sshkey, user + "@" + server ]) + os.remove("upload_dir.batch") + os.remove("upload.batch") + os.remove("upload.tag") + else: + printLog(log, "SKIP " + dir_to) + +printLog(log, ">>> Upload patch <<<") +for target in UploadPatch: + uploadSftp(target[0], target[1], target[2], target[3], ClientPatchDirectory + "/patch", [ ]) + +printLog(log, ">>> Upload data_shard <<<") +for target in UploadShard: + uploadSftp(target[0], target[1], target[2], target[3], DataShardDirectory, [ "rm *.packed_sheets", "rm primitive_cache/*.binprim" ]) + +printLog(log, ">>> Upload data_common <<<") +for target in UploadCommon: + uploadSftp(target[0], target[1], target[2], target[3], DataCommonDirectory, [ ]) + +printLog(log, ">>> Upload data_leveldesign/leveldesign <<<") +for target in UploadLeveldesign: + uploadSftp(target[0], target[1], target[2], target[3], LeveldesignDirectory, [ ]) + +printLog(log, ">>> Upload data_leveldesign/primitives <<<") +for target in UploadPrimitives: + uploadSftp(target[0], target[1], target[2], target[3], PrimitivesDirectory, [ ]) + +log.close() +if os.path.isfile("8_upload.log"): + os.remove("8_upload.log") +shutil.copy("log.log", time.strftime("%Y-%m-%d-%H-%M-GMT", time.gmtime(time.time())) + "_upload.log") +shutil.move("log.log", "8_upload.log") diff --git a/code/nel/tools/build_gamedata/configuration/tools.py b/code/nel/tools/build_gamedata/configuration/tools.py index e533270c1..5eff45977 100644 --- a/code/nel/tools/build_gamedata/configuration/tools.py +++ b/code/nel/tools/build_gamedata/configuration/tools.py @@ -69,10 +69,10 @@ ZoneIgLighterTool = "zone_ig_lighter" IgLighterTool = "ig_lighter" AnimBuilderTool = "anim_builder" TileEditTool = "tile_edit" -BuildImagesetTool = "th_build_imageset" +# BuildImagesetTool = "th_build_imageset" # kaetemi stuff, ignore this MakeSheetIdTool = "make_sheet_id" -BuildSheetsTool = "th_build_sheets" -BuildSoundTool = "th_build_sound" +# BuildSheetsTool = "th_build_sheets" # kaetemi stuff, ignore this +# BuildSoundTool = "th_build_sound" # kaetemi stuff, ignore this BuildCoarseMeshTool = "build_coarse_mesh" LightmapOptimizerTool = "lightmap_optimizer" BuildClodtexTool = "build_clodtex" diff --git a/code/nel/tools/build_gamedata/generators/max_exporter_scripts/pacs_prim.py b/code/nel/tools/build_gamedata/generators/max_exporter_scripts/pacs_prim.py index b1c3e5966..2e3f07ec9 100644 --- a/code/nel/tools/build_gamedata/generators/max_exporter_scripts/pacs_prim.py +++ b/code/nel/tools/build_gamedata/generators/max_exporter_scripts/pacs_prim.py @@ -1,16 +1,7 @@ -printLog(log, ">>> List %PreGenFileExtension% <<<") -outDirPacsPrim = ExportBuildDirectory + "/" + %PreGenExportDirectoryVariable% -mkPath(log, outDirPacsPrim) +# Remove bad file from previous script version listPath = ExportBuildDirectory + "/" + %PreGenExportDirectoryVariable% + "/landscape_col_prim_pacs_list.txt" if os.path.isfile(listPath): os.remove(listPath) -if WantLandscapeColPrimPacsList: - exportedPacsPrims = findFiles(log, outDirPacsPrim, "", ".%PreGenFileExtension%") - printLog(log, "WRITE " + listPath) - listFile = open(listPath, "w") - for exported in exportedPacsPrims: - listFile.write(exported + "\n") - listFile.close() diff --git a/code/nel/tools/build_gamedata/generators/max_exporter_scripts/shape.ms b/code/nel/tools/build_gamedata/generators/max_exporter_scripts/shape.ms index 0f8af5276..c1f4761ff 100644 --- a/code/nel/tools/build_gamedata/generators/max_exporter_scripts/shape.ms +++ b/code/nel/tools/build_gamedata/generators/max_exporter_scripts/shape.ms @@ -187,7 +187,7 @@ fn haveCoarseMesh node = return false ) -fn runNelMaxExport inputMaxFile = +fn runNelMaxExportSub inputMaxFile retryCount = ( tagThisFile = false @@ -354,8 +354,39 @@ fn runNelMaxExport inputMaxFile = ( -- Error nlerror("WARNING no shape exported from the file " + inputMaxFile) + if tagThisFile then + ( + if retryCount < 2 then + ( + nlerror("INFO retry this file") + + -- Free memory and file handles + gc() + heapfree + + -- Reset 3dsmax + resetMAXFile #noprompt + + if (loadMaxFile inputMaxFile quiet:true) == true then + ( + tagThisFile = runNelMaxExportSub inputMaxFile (retryCount + 1) + ) + else + ( + -- Error + nlerror("ERROR exporting '%PreGenFileExtension%': can't open the file " + inputMaxFile) + nlerror("FAIL Mysterious error occured") + NelForceQuitRightNow() + ) + ) + ) ) return tagThisFile ) +fn runNelMaxExport inputMaxFile = +( + return runNelMaxExportSub inputMaxFile 0 +) + diff --git a/code/nel/tools/build_gamedata/generators/tagged_max_exporter_template/export_footer.ms b/code/nel/tools/build_gamedata/generators/tagged_max_exporter_template/export_footer.ms index 5facf07e7..2db696b7f 100644 --- a/code/nel/tools/build_gamedata/generators/tagged_max_exporter_template/export_footer.ms +++ b/code/nel/tools/build_gamedata/generators/tagged_max_exporter_template/export_footer.ms @@ -90,7 +90,9 @@ try catch ( -- Error - nlerror("ERROR fatal error exporting '%PreGenFileExtension%' in folder %MaxSourceDirectory%") + nlerror("ERROR Fatal error exporting '%PreGenFileExtension%' in folder %MaxSourceDirectory%") + nlerror("FAIL Fatal error occured") + NelForceQuitRightNow() removeRunningTag = false ) diff --git a/code/nel/tools/build_gamedata/interface_dev.bat b/code/nel/tools/build_gamedata/interface_dev.bat new file mode 100644 index 000000000..1c5fa04eb --- /dev/null +++ b/code/nel/tools/build_gamedata/interface_dev.bat @@ -0,0 +1,4 @@ +1_export.py -ipj common/gamedev common/data_common common/exedll common/cfg common/interface common/sfx common/fonts common/outgame +2_build.py -ipj common/gamedev common/data_common common/exedll common/cfg common/interface common/sfx common/fonts common/outgame +3_install.py -ipj common/gamedev common/data_common common/exedll common/cfg common/interface common/sfx common/fonts common/outgame +5_client_dev.py diff --git a/code/nel/tools/build_gamedata/leveldesign_dev.bat b/code/nel/tools/build_gamedata/leveldesign_dev.bat new file mode 100644 index 000000000..fca3c1561 --- /dev/null +++ b/code/nel/tools/build_gamedata/leveldesign_dev.bat @@ -0,0 +1,4 @@ +1_export.py -ipj common/gamedev common/data_common common/leveldesign common/exedll common/cfg +2_build.py -ipj common/gamedev common/data_common common/leveldesign common/exedll common/cfg +3_install.py -ipj common/gamedev common/data_common common/leveldesign common/exedll common/cfg +5_client_dev.py diff --git a/code/nel/tools/build_gamedata/processes/0_setup.py b/code/nel/tools/build_gamedata/processes/0_setup.py index cb6de2abb..213158c92 100644 --- a/code/nel/tools/build_gamedata/processes/0_setup.py +++ b/code/nel/tools/build_gamedata/processes/0_setup.py @@ -24,8 +24,14 @@ # along with this program. If not, see . # -import time, sys, os, shutil, subprocess, distutils.dir_util +import time, sys, os, shutil, subprocess, distutils.dir_util, argparse sys.path.append("../configuration") + +parser = argparse.ArgumentParser() +parser.add_argument('--includeprocess', '-ipc', nargs='+') +parser.add_argument('--excludeprocess', '-epc', nargs='+') +args = parser.parse_args() + if os.path.isfile("log.log"): os.remove("log.log") log = open("log.log", "w") @@ -60,20 +66,24 @@ printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) printLog(log, "") # For each process for processName in ProcessToComplete: - os.chdir(processName) - try: - subprocess.call([ "python", "0_setup.py" ]) - except Exception, e: - printLog(log, "<" + processName + "> " + str(e)) - os.chdir("..") - try: - processLog = open(processName + "/log.log", "r") - processLogData = processLog.read() - processLog.close() - log.write(processLogData) - except Exception, e: - printLog(log, "<" + processName + "> " + str(e)) - # subprocess.call("idle.bat") + if ((args.includeprocess == None or processName in args.includeprocess) and (args.excludeprocess == None or not processName in args.excludeprocess)): + printLog(log, "PROCESS " + processName) + os.chdir(processName) + try: + subprocess.call([ "python", "0_setup.py" ]) + except Exception, e: + printLog(log, "<" + processName + "> " + str(e)) + os.chdir("..") + try: + processLog = open(processName + "/log.log", "r") + processLogData = processLog.read() + processLog.close() + log.write(processLogData) + except Exception, e: + printLog(log, "<" + processName + "> " + str(e)) + # subprocess.call("idle.bat") + else: + printLog(log, "IGNORE PROCESS " + processName) printLog(log, "") log.close() diff --git a/code/nel/tools/build_gamedata/processes/1_export.py b/code/nel/tools/build_gamedata/processes/1_export.py index fdd497720..766639f17 100644 --- a/code/nel/tools/build_gamedata/processes/1_export.py +++ b/code/nel/tools/build_gamedata/processes/1_export.py @@ -24,9 +24,14 @@ # along with this program. If not, see . # -import time, sys, os, shutil, subprocess, distutils.dir_util +import time, sys, os, shutil, subprocess, distutils.dir_util, argparse sys.path.append("../configuration") +parser = argparse.ArgumentParser() +parser.add_argument('--includeprocess', '-ipc', nargs='+') +parser.add_argument('--excludeprocess', '-epc', nargs='+') +args = parser.parse_args() + if os.path.isfile("log.log"): os.remove("log.log") log = open("log.log", "w") @@ -45,20 +50,24 @@ printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) printLog(log, "") # For each process for processName in ProcessToComplete: - os.chdir(processName) - try: - subprocess.call([ "python", "1_export.py" ]) - except Exception, e: - printLog(log, "<" + processName + "> " + str(e)) - os.chdir("..") - try: - processLog = open(processName + "/log.log", "r") - processLogData = processLog.read() - processLog.close() - log.write(processLogData) - except Exception, e: - printLog(log, "<" + processName + "> " + str(e)) - # subprocess.call("idle.bat") + if ((args.includeprocess == None or processName in args.includeprocess) and (args.excludeprocess == None or not processName in args.excludeprocess)): + printLog(log, "PROCESS " + processName) + os.chdir(processName) + try: + subprocess.call([ "python", "1_export.py" ]) + except Exception, e: + printLog(log, "<" + processName + "> " + str(e)) + os.chdir("..") + try: + processLog = open(processName + "/log.log", "r") + processLogData = processLog.read() + processLog.close() + log.write(processLogData) + except Exception, e: + printLog(log, "<" + processName + "> " + str(e)) + # subprocess.call("idle.bat") + else: + printLog(log, "IGNORE PROCESS " + processName) printLog(log, "") log.close() diff --git a/code/nel/tools/build_gamedata/processes/2_build.py b/code/nel/tools/build_gamedata/processes/2_build.py index 28ee3147c..4ad70b2f4 100644 --- a/code/nel/tools/build_gamedata/processes/2_build.py +++ b/code/nel/tools/build_gamedata/processes/2_build.py @@ -24,9 +24,14 @@ # along with this program. If not, see . # -import time, sys, os, shutil, subprocess, distutils.dir_util +import time, sys, os, shutil, subprocess, distutils.dir_util, argparse sys.path.append("../configuration") +parser = argparse.ArgumentParser() +parser.add_argument('--includeprocess', '-ipc', nargs='+') +parser.add_argument('--excludeprocess', '-epc', nargs='+') +args = parser.parse_args() + if os.path.isfile("log.log"): os.remove("log.log") log = open("log.log", "w") @@ -45,20 +50,24 @@ printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) printLog(log, "") # For each process for processName in ProcessToComplete: - os.chdir(processName) - try: - subprocess.call([ "python", "2_build.py" ]) - except Exception, e: - printLog(log, "<" + processName + "> " + str(e)) - os.chdir("..") - try: - processLog = open(processName + "/log.log", "r") - processLogData = processLog.read() - processLog.close() - log.write(processLogData) - except Exception, e: - printLog(log, "<" + processName + "> " + str(e)) - # subprocess.call("idle.bat") + if ((args.includeprocess == None or processName in args.includeprocess) and (args.excludeprocess == None or not processName in args.excludeprocess)): + printLog(log, "PROCESS " + processName) + os.chdir(processName) + try: + subprocess.call([ "python", "2_build.py" ]) + except Exception, e: + printLog(log, "<" + processName + "> " + str(e)) + os.chdir("..") + try: + processLog = open(processName + "/log.log", "r") + processLogData = processLog.read() + processLog.close() + log.write(processLogData) + except Exception, e: + printLog(log, "<" + processName + "> " + str(e)) + # subprocess.call("idle.bat") + else: + printLog(log, "IGNORE PROCESS " + processName) printLog(log, "") log.close() diff --git a/code/nel/tools/build_gamedata/processes/3_install.py b/code/nel/tools/build_gamedata/processes/3_install.py index fe51c0772..89bf53660 100644 --- a/code/nel/tools/build_gamedata/processes/3_install.py +++ b/code/nel/tools/build_gamedata/processes/3_install.py @@ -24,9 +24,14 @@ # along with this program. If not, see . # -import time, sys, os, shutil, subprocess, distutils.dir_util +import time, sys, os, shutil, subprocess, distutils.dir_util, argparse sys.path.append("../configuration") +parser = argparse.ArgumentParser() +parser.add_argument('--includeprocess', '-ipc', nargs='+') +parser.add_argument('--excludeprocess', '-epc', nargs='+') +args = parser.parse_args() + if os.path.isfile("log.log"): os.remove("log.log") log = open("log.log", "w") @@ -44,20 +49,24 @@ printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) printLog(log, "") # For each process for processName in ProcessToComplete: - os.chdir(processName) - try: - subprocess.call([ "python", "3_install.py" ]) - except Exception, e: - printLog(log, "<" + processName + "> " + str(e)) - os.chdir("..") - try: - processLog = open(processName + "/log.log", "r") - processLogData = processLog.read() - processLog.close() - log.write(processLogData) - except Exception, e: - printLog(log, "<" + processName + "> " + str(e)) - # subprocess.call("idle.bat") + if ((args.includeprocess == None or processName in args.includeprocess) and (args.excludeprocess == None or not processName in args.excludeprocess)): + printLog(log, "PROCESS " + processName) + os.chdir(processName) + try: + subprocess.call([ "python", "3_install.py" ]) + except Exception, e: + printLog(log, "<" + processName + "> " + str(e)) + os.chdir("..") + try: + processLog = open(processName + "/log.log", "r") + processLogData = processLog.read() + processLog.close() + log.write(processLogData) + except Exception, e: + printLog(log, "<" + processName + "> " + str(e)) + # subprocess.call("idle.bat") + else: + printLog(log, "IGNORE PROCESS " + processName) printLog(log, "") log.close() diff --git a/code/nel/tools/build_gamedata/processes/anim/1_export.py b/code/nel/tools/build_gamedata/processes/anim/1_export.py index 3bdd5e028..5d5fe4b84 100644 --- a/code/nel/tools/build_gamedata/processes/anim/1_export.py +++ b/code/nel/tools/build_gamedata/processes/anim/1_export.py @@ -6,7 +6,7 @@ # # \file 1_export.py # \brief Export anim -# \date 2010-09-26-08-38-GMT +# \date 2011-09-21-20-51-GMT # \author Jan Boon (Kaetemi) # Python port of game data build pipeline. # Export anim diff --git a/code/nel/tools/build_gamedata/processes/anim/maxscript/anim_export.ms b/code/nel/tools/build_gamedata/processes/anim/maxscript/anim_export.ms index 86d02fd15..7121e16d5 100644 --- a/code/nel/tools/build_gamedata/processes/anim/maxscript/anim_export.ms +++ b/code/nel/tools/build_gamedata/processes/anim/maxscript/anim_export.ms @@ -224,7 +224,9 @@ try catch ( -- Error - nlerror("ERROR fatal error exporting 'anim' in folder %MaxSourceDirectory%") + nlerror("ERROR Fatal error exporting 'anim' in folder %MaxSourceDirectory%") + nlerror("FAIL Fatal error occured") + NelForceQuitRightNow() removeRunningTag = false ) diff --git a/code/nel/tools/build_gamedata/processes/clodbank/1_export.py b/code/nel/tools/build_gamedata/processes/clodbank/1_export.py index a9f6cf7c1..183307e30 100644 --- a/code/nel/tools/build_gamedata/processes/clodbank/1_export.py +++ b/code/nel/tools/build_gamedata/processes/clodbank/1_export.py @@ -6,7 +6,7 @@ # # \file 1_export.py # \brief Export clodbank -# \date 2010-09-26-08-38-GMT +# \date 2011-09-21-20-51-GMT # \author Jan Boon (Kaetemi) # Python port of game data build pipeline. # Export clodbank diff --git a/code/nel/tools/build_gamedata/processes/clodbank/maxscript/clod_export.ms b/code/nel/tools/build_gamedata/processes/clodbank/maxscript/clod_export.ms index 1ab3ce7e2..f01a973e4 100644 --- a/code/nel/tools/build_gamedata/processes/clodbank/maxscript/clod_export.ms +++ b/code/nel/tools/build_gamedata/processes/clodbank/maxscript/clod_export.ms @@ -279,7 +279,9 @@ try catch ( -- Error - nlerror("ERROR fatal error exporting 'clod' in folder %MaxSourceDirectory%") + nlerror("ERROR Fatal error exporting 'clod' in folder %MaxSourceDirectory%") + nlerror("FAIL Fatal error occured") + NelForceQuitRightNow() removeRunningTag = false ) diff --git a/code/nel/tools/build_gamedata/processes/ig/maxscript/ig_export.ms b/code/nel/tools/build_gamedata/processes/ig/maxscript/ig_export.ms index 5618a68d9..526d06dc8 100644 --- a/code/nel/tools/build_gamedata/processes/ig/maxscript/ig_export.ms +++ b/code/nel/tools/build_gamedata/processes/ig/maxscript/ig_export.ms @@ -328,7 +328,9 @@ try catch ( -- Error - nlerror("ERROR fatal error exporting 'ig' in folder %MaxSourceDirectory%") + nlerror("ERROR Fatal error exporting 'ig' in folder %MaxSourceDirectory%") + nlerror("FAIL Fatal error occured") + NelForceQuitRightNow() removeRunningTag = false ) diff --git a/code/nel/tools/build_gamedata/processes/pacs_prim/1_export.py b/code/nel/tools/build_gamedata/processes/pacs_prim/1_export.py index 5779a8cd7..e21fb4fde 100644 --- a/code/nel/tools/build_gamedata/processes/pacs_prim/1_export.py +++ b/code/nel/tools/build_gamedata/processes/pacs_prim/1_export.py @@ -6,7 +6,7 @@ # # \file 1_export.py # \brief Export pacs_prim -# \date 2010-09-19-14-19-GMT +# \date 2011-09-28-07-42-GMT # \author Jan Boon (Kaetemi) # Python port of game data build pipeline. # Export pacs_prim @@ -92,19 +92,10 @@ if MaxAvailable: -printLog(log, ">>> List pacs_prim <<<") -outDirPacsPrim = ExportBuildDirectory + "/" + PacsPrimExportDirectory -mkPath(log, outDirPacsPrim) +# Remove bad file from previous script version listPath = ExportBuildDirectory + "/" + PacsPrimExportDirectory + "/landscape_col_prim_pacs_list.txt" if os.path.isfile(listPath): os.remove(listPath) -if WantLandscapeColPrimPacsList: - exportedPacsPrims = findFiles(log, outDirPacsPrim, "", ".pacs_prim") - printLog(log, "WRITE " + listPath) - listFile = open(listPath, "w") - for exported in exportedPacsPrims: - listFile.write(exported + "\n") - listFile.close() diff --git a/code/nel/tools/build_gamedata/processes/pacs_prim_list/0_setup.py b/code/nel/tools/build_gamedata/processes/pacs_prim_list/0_setup.py new file mode 100644 index 000000000..0fad037bb --- /dev/null +++ b/code/nel/tools/build_gamedata/processes/pacs_prim_list/0_setup.py @@ -0,0 +1,58 @@ +#!/usr/bin/python +# +# \file 0_setup.py +# \brief setup pacs_prim_list +# \date 2011-09-28 7:22GMT +# \author Jan Boon (Kaetemi) +# Python port of game data build pipeline. +# Setup pacs_prim_list +# +# NeL - MMORPG Framework +# Copyright (C) 2010 Winch Gate Property Limited +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +import time, sys, os, shutil, subprocess, distutils.dir_util +sys.path.append("../../configuration") + +if os.path.isfile("log.log"): + os.remove("log.log") +log = open("log.log", "w") +from scripts import * +from buildsite import * +from process import * +from tools import * +from directories import * + +printLog(log, "") +printLog(log, "-------") +printLog(log, "--- Setup pacs_prim_list") +printLog(log, "-------") +printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) +printLog(log, "") + +# Setup source directories +printLog(log, ">>> Setup source directories <<<") +for dir in PacsPrimExportSourceDirectories: + mkPath(log, ExportBuildDirectory + "/" + dir) + +# Setup build directories +printLog(log, ">>> Setup build directories <<<") +mkPath(log, DataCommonDirectory) # no choice + +log.close() + + +# end of file diff --git a/code/nel/tools/build_gamedata/processes/pacs_prim_list/1_export.py b/code/nel/tools/build_gamedata/processes/pacs_prim_list/1_export.py new file mode 100644 index 000000000..1126f23a1 --- /dev/null +++ b/code/nel/tools/build_gamedata/processes/pacs_prim_list/1_export.py @@ -0,0 +1,53 @@ +#!/usr/bin/python +# +# \file 1_export.py +# \brief Export pacs_prim_list +# \date 2011-09-28 7:22GMT +# \author Jan Boon (Kaetemi) +# Python port of game data build pipeline. +# Export pacs_prim_list +# +# NeL - MMORPG Framework +# Copyright (C) 2010 Winch Gate Property Limited +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +import time, sys, os, shutil, subprocess, distutils.dir_util +sys.path.append("../../configuration") + +if os.path.isfile("log.log"): + os.remove("log.log") +log = open("log.log", "w") +from scripts import * +from buildsite import * +from process import * +from tools import * +from directories import * + +printLog(log, "") +printLog(log, "-------") +printLog(log, "--- Export pacs_prim_list") +printLog(log, "-------") +printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) +printLog(log, "") + +printLog(log, ">>> Nothing to do! <<<") + +printLog(log, "") + +log.close() + + +# end of file diff --git a/code/nel/tools/build_gamedata/processes/pacs_prim_list/2_build.py b/code/nel/tools/build_gamedata/processes/pacs_prim_list/2_build.py new file mode 100644 index 000000000..9b5d52541 --- /dev/null +++ b/code/nel/tools/build_gamedata/processes/pacs_prim_list/2_build.py @@ -0,0 +1,63 @@ +#!/usr/bin/python +# +# \file 2_build.py +# \brief Build pacs_prim_list +# \date 2011-09-28 7:22GMT +# \author Jan Boon (Kaetemi) +# Python port of game data build pipeline. +# Build pacs_prim_list +# +# NeL - MMORPG Framework +# Copyright (C) 2010 Winch Gate Property Limited +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +import time, sys, os, shutil, subprocess, distutils.dir_util +sys.path.append("../../configuration") + +if os.path.isfile("log.log"): + os.remove("log.log") +log = open("log.log", "w") +from scripts import * +from buildsite import * +from process import * +from tools import * +from directories import * + +printLog(log, "") +printLog(log, "-------") +printLog(log, "--- Build pacs_prim_list") +printLog(log, "-------") +printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) +printLog(log, "") + +printLog(log, ">>> List pacs_prim <<<") +listPath = DataCommonDirectory + "/landscape_col_prim_pacs_list.txt" +if os.path.isfile(listPath): + os.remove(listPath) +listFile = open(listPath, "w") +printLog(log, "WRITE " + listPath) +for dir in PacsPrimExportSourceDirectories: + outDirPacsPrim = ExportBuildDirectory + "/" + dir + mkPath(log, outDirPacsPrim) + exportedPacsPrims = findFiles(log, outDirPacsPrim, "", ".pacs_prim") + for exported in exportedPacsPrims: + listFile.write(exported + "\n") +listFile.close() + +log.close() + + +# end of file diff --git a/code/nel/tools/build_gamedata/processes/pacs_prim_list/3_install.py b/code/nel/tools/build_gamedata/processes/pacs_prim_list/3_install.py new file mode 100644 index 000000000..076f92efa --- /dev/null +++ b/code/nel/tools/build_gamedata/processes/pacs_prim_list/3_install.py @@ -0,0 +1,52 @@ +#!/usr/bin/python +# +# \file 3_install.py +# \brief Install pacs_prim_list +# \date 2011-09-28 7:22GMT +# \author Jan Boon (Kaetemi) +# Python port of game data build pipeline. +# Install pacs_prim_list +# +# NeL - MMORPG Framework +# Copyright (C) 2010 Winch Gate Property Limited +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +import time, sys, os, shutil, subprocess, distutils.dir_util +sys.path.append("../../configuration") + +if os.path.isfile("log.log"): + os.remove("log.log") +log = open("log.log", "w") +from scripts import * +from buildsite import * +from process import * +from tools import * +from directories import * + +printLog(log, "") +printLog(log, "-------") +printLog(log, "--- Install pacs_prim_list") +printLog(log, "-------") +printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) +printLog(log, "") + +printLog(log, ">>> Nothing to do! <<<") + +printLog(log, "") +log.close() + + +# end of file diff --git a/code/nel/tools/build_gamedata/processes/rbank/1_export.py b/code/nel/tools/build_gamedata/processes/rbank/1_export.py index de32ae841..20c7aa54d 100644 --- a/code/nel/tools/build_gamedata/processes/rbank/1_export.py +++ b/code/nel/tools/build_gamedata/processes/rbank/1_export.py @@ -6,7 +6,7 @@ # # \file 1_export.py # \brief Export rbank -# \date 2010-09-26-08-38-GMT +# \date 2011-09-21-20-51-GMT # \author Jan Boon (Kaetemi) # Python port of game data build pipeline. # Export rbank diff --git a/code/nel/tools/build_gamedata/processes/rbank/maxscript/cmb_export.ms b/code/nel/tools/build_gamedata/processes/rbank/maxscript/cmb_export.ms index c60a675d0..74cf3a8dd 100644 --- a/code/nel/tools/build_gamedata/processes/rbank/maxscript/cmb_export.ms +++ b/code/nel/tools/build_gamedata/processes/rbank/maxscript/cmb_export.ms @@ -215,7 +215,9 @@ try catch ( -- Error - nlerror("ERROR fatal error exporting 'cmb' in folder %MaxSourceDirectory%") + nlerror("ERROR Fatal error exporting 'cmb' in folder %MaxSourceDirectory%") + nlerror("FAIL Fatal error occured") + NelForceQuitRightNow() removeRunningTag = false ) diff --git a/code/nel/tools/build_gamedata/processes/shape/maxscript/shape_export.ms b/code/nel/tools/build_gamedata/processes/shape/maxscript/shape_export.ms index 06a02bcbb..e979f6b0d 100644 --- a/code/nel/tools/build_gamedata/processes/shape/maxscript/shape_export.ms +++ b/code/nel/tools/build_gamedata/processes/shape/maxscript/shape_export.ms @@ -253,7 +253,7 @@ fn haveCoarseMesh node = return false ) -fn runNelMaxExport inputMaxFile = +fn runNelMaxExportSub inputMaxFile retryCount = ( tagThisFile = false @@ -420,11 +420,42 @@ fn runNelMaxExport inputMaxFile = ( -- Error nlerror("WARNING no shape exported from the file " + inputMaxFile) + if tagThisFile then + ( + if retryCount < 2 then + ( + nlerror("INFO retry this file") + + -- Free memory and file handles + gc() + heapfree + + -- Reset 3dsmax + resetMAXFile #noprompt + + if (loadMaxFile inputMaxFile quiet:true) == true then + ( + tagThisFile = runNelMaxExportSub inputMaxFile (retryCount + 1) + ) + else + ( + -- Error + nlerror("ERROR exporting 'shape': can't open the file " + inputMaxFile) + nlerror("FAIL Mysterious error occured") + NelForceQuitRightNow() + ) + ) + ) ) return tagThisFile ) +fn runNelMaxExport inputMaxFile = +( + return runNelMaxExportSub inputMaxFile 0 +) + removeRunningTag = true @@ -517,7 +548,9 @@ try catch ( -- Error - nlerror("ERROR fatal error exporting 'shape' in folder %MaxSourceDirectory%") + nlerror("ERROR Fatal error exporting 'shape' in folder %MaxSourceDirectory%") + nlerror("FAIL Fatal error occured") + NelForceQuitRightNow() removeRunningTag = false ) diff --git a/code/nel/tools/build_gamedata/processes/sheet_id/2_build.py b/code/nel/tools/build_gamedata/processes/sheet_id/2_build.py index f935a4500..64b46c91f 100644 --- a/code/nel/tools/build_gamedata/processes/sheet_id/2_build.py +++ b/code/nel/tools/build_gamedata/processes/sheet_id/2_build.py @@ -54,7 +54,7 @@ if MakeSheetId == "": else: mkPath(log, LeveldesignDirectory) mkPath(log, LeveldesignWorldDirectory) - subprocess.call([ MakeSheetId, "-o" + LeveldesignDirectory + "/game_elem/sheet_id.bin", LeveldesignDirectory + "/game_elem", LeveldesignDirectory + "/game_element", LeveldesignWorldDirectory ]) + subprocess.call([ MakeSheetId, "-o" + LeveldesignDirectory + "/game_elem/sheet_id.bin", LeveldesignDirectory + "/game_elem", LeveldesignDirectory + "/game_element", LeveldesignWorldDirectory, DataShardDirectory + "mirror_sheets" ]) printLog(log, "") log.close() diff --git a/code/nel/tools/build_gamedata/processes/sheets/2_build.py b/code/nel/tools/build_gamedata/processes/sheets/2_build.py index 511b05004..40d7774c3 100644 --- a/code/nel/tools/build_gamedata/processes/sheets/2_build.py +++ b/code/nel/tools/build_gamedata/processes/sheets/2_build.py @@ -77,6 +77,8 @@ else: cf.write("\n") cf.close() subprocess.call([ SheetsPacker ]) + copyFileIfNeeded(log, "visual_slot.tab", DataCommonDirectory + "/visual_slot.tab") + os.remove("visual_slot.tab") printLog(log, "") log.close() diff --git a/code/nel/tools/build_gamedata/processes/sheets/3_install.py b/code/nel/tools/build_gamedata/processes/sheets/3_install.py index 98b5cb825..f4093b12e 100644 --- a/code/nel/tools/build_gamedata/processes/sheets/3_install.py +++ b/code/nel/tools/build_gamedata/processes/sheets/3_install.py @@ -49,6 +49,7 @@ mkPath(log, installPath) printLog(log, ">>> Install sheets <<<") mkPath(log, ExportBuildDirectory + "/" + SheetsBuildDirectory) copyFilesExtNoTreeIfNeeded(log, ExportBuildDirectory + "/" + SheetsBuildDirectory, installPath, ".packed_sheets") +copyFilesExtNoTreeIfNeeded(log, ExportBuildDirectory + "/" + SheetsBuildDirectory, installPath, ".packed") printLog(log, "") log.close() diff --git a/code/nel/tools/build_gamedata/processes/skel/1_export.py b/code/nel/tools/build_gamedata/processes/skel/1_export.py index af73024c5..84e9ce931 100644 --- a/code/nel/tools/build_gamedata/processes/skel/1_export.py +++ b/code/nel/tools/build_gamedata/processes/skel/1_export.py @@ -6,7 +6,7 @@ # # \file 1_export.py # \brief Export skel -# \date 2010-09-19-14-19-GMT +# \date 2011-09-28-07-42-GMT # \author Jan Boon (Kaetemi) # Python port of game data build pipeline. # Export skel diff --git a/code/nel/tools/build_gamedata/processes/swt/1_export.py b/code/nel/tools/build_gamedata/processes/swt/1_export.py index 3b8da1d0f..6ad3c8f13 100644 --- a/code/nel/tools/build_gamedata/processes/swt/1_export.py +++ b/code/nel/tools/build_gamedata/processes/swt/1_export.py @@ -6,7 +6,7 @@ # # \file 1_export.py # \brief Export swt -# \date 2010-09-19-14-19-GMT +# \date 2011-09-28-07-42-GMT # \author Jan Boon (Kaetemi) # Python port of game data build pipeline. # Export swt diff --git a/code/nel/tools/build_gamedata/processes/veget/1_export.py b/code/nel/tools/build_gamedata/processes/veget/1_export.py index 61e33ea74..e6d2c53cc 100644 --- a/code/nel/tools/build_gamedata/processes/veget/1_export.py +++ b/code/nel/tools/build_gamedata/processes/veget/1_export.py @@ -6,7 +6,7 @@ # # \file 1_export.py # \brief Export veget -# \date 2010-09-26-08-38-GMT +# \date 2011-09-21-20-51-GMT # \author Jan Boon (Kaetemi) # Python port of game data build pipeline. # Export veget diff --git a/code/nel/tools/build_gamedata/processes/veget/maxscript/veget_export.ms b/code/nel/tools/build_gamedata/processes/veget/maxscript/veget_export.ms index 4390e5cca..828a78d42 100644 --- a/code/nel/tools/build_gamedata/processes/veget/maxscript/veget_export.ms +++ b/code/nel/tools/build_gamedata/processes/veget/maxscript/veget_export.ms @@ -269,7 +269,9 @@ try catch ( -- Error - nlerror("ERROR fatal error exporting 'veget' in folder %MaxSourceDirectory%") + nlerror("ERROR Fatal error exporting 'veget' in folder %MaxSourceDirectory%") + nlerror("FAIL Fatal error occured") + NelForceQuitRightNow() removeRunningTag = false ) diff --git a/code/nel/tools/build_gamedata/processes/zone/1_export.py b/code/nel/tools/build_gamedata/processes/zone/1_export.py index 8b34753c9..d464e3f31 100644 --- a/code/nel/tools/build_gamedata/processes/zone/1_export.py +++ b/code/nel/tools/build_gamedata/processes/zone/1_export.py @@ -6,7 +6,7 @@ # # \file 1_export.py # \brief Export zone -# \date 2010-09-19-14-19-GMT +# \date 2011-09-28-07-42-GMT # \author Jan Boon (Kaetemi) # Python port of game data build pipeline. # Export zone diff --git a/code/nel/tools/georges/georges2csv/georges2csv.cpp b/code/nel/tools/georges/georges2csv/georges2csv.cpp index e10d06bf5..da89cc9bc 100644 --- a/code/nel/tools/georges/georges2csv/georges2csv.cpp +++ b/code/nel/tools/georges/georges2csv/georges2csv.cpp @@ -289,7 +289,7 @@ void addQuotesRoundString (std::string &valueString) std::string hold=valueString; valueString.erase(); valueString='\"'; - for (unsigned i=0;i -#ifdef $macro - yo_header -#endif], - have_header="yes", - have_header="no") - - CPPFLAGS="$_CPPFLAGS" - - if test "$have_header" = "yes" - then - AC_MSG_RESULT(yes) - else - if test "$is_mandatory" = "yes" - then - AC_MSG_ERROR([$chk_message_obj must be installed (http://www.nevrax.org).]) - else - AC_MSG_RESULT(no) - fi - fi -fi - - -]) - - -# ========================================================================= -# MY_NEL_LIB_CHK : NeL library checking macros - -AC_DEFUN([MY_NEL_LIB_CHK], -[ AC_REQUIRE_CPP() - -chk_message_obj="$1" -nel_test_lib="$2" -is_mandatory="$3" - -if test $is_mandatory = "yes" -then - - AC_CHECK_LIB($nel_test_lib, main,,[AC_MSG_ERROR([$chk_message_obj must be installed (http://www.nevrax.org).])]) -fi -]) - - -# ========================================================================= -# AM_PATH_NEL : NeL checking macros -AC_DEFUN([AM_PATH_NEL], -[ AC_REQUIRE_CPP() - -AC_ARG_WITH( nel, - [ --with-nel= path to the NeL install files directory. - e.g. /usr/local/nel]) - -AC_ARG_WITH( nel-include, - [ --with-nel-include= - path to the NeL header files directory. - e.g. /usr/local/nel/include]) - -AC_ARG_WITH( nel-lib, - [ --with-nel-lib= - path to the NeL library files directory. - e.g. /usr/local/nel/lib]) - - -nelmisc_is_mandatory="$1" -nelnet_is_mandatory="$2" -nel3d_is_mandatory="$3" -nelpacs_is_mandatory="$4" -nelsound_is_mandatory="$5" -nelai_is_mandatory="$6" -nelgeorges_is_mandatory="$7" - -# Check for nel-config -AC_PATH_PROG(NEL_CONFIG, nel-config, no) - -# -# Configure options (--with-nel*) have precendence -# over nel-config only set variables if they are not -# specified -# -if test "$NEL_CONFIG" != "no" -then - if test -z "$with_nel" -a -z "$with_nel_include" - then - CXXFLAGS="$CXXFLAGS `nel-config --cflags`" - fi - - if test -z "$with_nel" -a -z "$with_nel_lib" - then - LDFLAGS="`nel-config --ldflags` $LDFLAGS" - fi -fi - -# -# Set nel_libraries and nel_includes according to -# user specification (--with-nel*) if any. -# --with-nel-include and --with-nel-lib have precendence -# over --with-nel -# -if test "$with_nel" = "no" -then - # The user explicitly disabled the use of the NeL - AC_MSG_ERROR([NeL is mandatory: do not specify --without-nel]) -else - if test "$with_nel" -a "$with_nel" != "yes" - then - nel_includes="$with_nel/include" - nel_libraries="$with_nel/lib" - fi -fi - -if test "$with_nel_include" -then - nel_includes="$with_nel_include" -fi - -if test "$with_nel_lib" -then - nel_libraries="$with_nel_lib" -fi - -# -# Set compilation variables -# -if test "$nel_includes" -then - CXXFLAGS="$CXXFLAGS -I$nel_includes" -fi - -if test "$nel_libraries" -then - LDFLAGS="-L$nel_libraries $LDFLAGS" -fi - -# -# Collect headers information and bark if missing and -# mandatory -# - -MY_NEL_HEADER_CHK([NeL Misc], [nel/misc/types_nl.h], [NL_TYPES_H], $nelmisc_is_mandatory) -MY_NEL_HEADER_CHK([NeL Network], [nel/net/sock.h], [NL_SOCK_H], $nelnet_is_mandatory) -MY_NEL_HEADER_CHK([NeL 3D], [nel/3d/u_camera.h], [NL_U_CAMERA_H], $nel3d_is_mandatory) -MY_NEL_HEADER_CHK([NeL PACS], [nel/pacs/u_global_position.h], [NL_U_GLOBAL_POSITION_H], $nelpacs_is_mandatory) -MY_NEL_HEADER_CHK([NeL Sound], [nel/sound/u_source.h], [NL_U_SOURCE_H], $nelsound_is_mandatory) -MY_NEL_HEADER_CHK([NeL AI], [nel/ai/nl_ai.h], [_IA_NEL_H], $nelai_is_mandatory) -MY_NEL_HEADER_CHK([NeL Georges], [nel/georges/common.h], [NLGEORGES_COMMON_H], $nelgeorges_is_mandatory) - -# -# Collect libraries information and bark if missing and -# mandatory -# - -MY_NEL_LIB_CHK([NeL Misc], [nelmisc], $nelmisc_is_mandatory) -MY_NEL_LIB_CHK([NeL Network], [nelnet], $nelnet_is_mandatory) -MY_NEL_LIB_CHK([NeL 3D], [nel3d], $nel3d_is_mandatory) -MY_NEL_LIB_CHK([NeL PACS], [nelpacs], $nelpacs_is_mandatory) -MY_NEL_LIB_CHK([NeL Sound], [nelsnd], $nelsound_is_mandatory) -MY_NEL_LIB_CHK([NeL AI], [nelai], $nelai_is_mandatory) -MY_NEL_LIB_CHK([NeL Georges], [nelgeorges], $nelgeorges_is_mandatory) - -]) - -# ========================================================================= -# AM_PATH_OPENGL : OpenGL checking macros - -AC_DEFUN([AM_PATH_OPENGL], -[ AC_MSG_CHECKING(for OpenGL headers and GL Version >= 1.2) - -is_mandatory="$1" - -AC_REQUIRE_CPP() - -AC_ARG_WITH( opengl, - [ --with-opengl= path to the OpenGL install files directory. - e.g. /usr/local]) - -AC_ARG_WITH( opengl-include, - [ --with-opengl-include= - path to the OpenGL header files directory. - e.g. /usr/local/include]) - -AC_ARG_WITH( opengl-lib, - [ --with-opengl-lib= - path to the OpenGL library files directory. - e.g. /usr/local/lib]) - -opengl_lib="GL" - -if test "$with_opengl" -then - opengl_includes="$with_opengl/include" - opengl_libraries="$with_opengl/lib" -fi - -if test "$with_opengl_include" -then - opengl_includes="$with_opengl_include" -fi - -if test "$with_opengl_lib" -then - opengl_libraries="$with_opengl_lib" -fi - -# Set OPENGL_CFLAGS -if test "$opengl_includes" -then - OPENGL_CFLAGS="-I$opengl_includes" -fi - -# Set OPENGL_LIBS -if test "$opengl_libraries" -then - OPENGL_LIBS="-L$opengl_libraries" -fi -OPENGL_LIBS="$OPENGL_LIBS -l$opengl_lib" - -# Test the headers -_CPPFLAGS="$CPPFLAGS" - -CPPFLAGS="$CXXFLAGS $OPENGL_CFLAGS" - -AC_EGREP_CPP( yo_opengl, -[#include -#if defined(GL_VERSION_1_2) - yo_opengl -#endif], - have_opengl_headers="yes", - have_opengl_headers="no" ) - -if test "$have_opengl_headers" = "yes" -then - if test "$opengl_includes" - then - AC_MSG_RESULT([$opengl_includes]) - else - AC_MSG_RESULT(yes) - fi -else - AC_MSG_RESULT(no) -fi - -# Checking the GLEXT version >= 7 -AC_MSG_CHECKING(for and GLEXT version >= 7) - -AC_EGREP_CPP( yo_glext_version, -[#include -#ifdef GL_GLEXT_VERSION -#if GL_GLEXT_VERSION >= 7 - yo_glext_version -#endif -#endif], - have_glext="yes", - have_glext="no" ) - -if test "$have_glext" = "yes" -then - AC_MSG_RESULT(yes) -else - AC_MSG_RESULT([no, can be downloaded from http://oss.sgi.com/projects/ogl-sample/ABI/]) -fi - -# Test the libraries -AC_MSG_CHECKING(for OpenGL libraries) - -CPPFLAGS="$CXXFLAGS $OPENGL_LIBS" - -AC_TRY_LINK( , , have_opengl_libraries="yes", have_opengl_libraries="no") - -CPPFLAGS="$_CPPFLAGS" - -if test "$have_opengl_libraries" = "yes" -then - if test "$opengl_libraries" - then - AC_MSG_RESULT([$opengl_libraries]) - else - AC_MSG_RESULT(yes) - fi -else - AC_MSG_RESULT(no) -fi - -opengl_libraries="$opengl_libraries" - -if test "$have_opengl_headers" = "yes" \ - -a "$have_glext" = "yes" \ - -a "$have_opengl_libraries" = "yes" -then - have_opengl="yes" -else - have_opengl="no" -fi - -if test "$have_opengl" = "no" -a "$is_mandatory" = "yes" -then - AC_MSG_ERROR([OpenGL >= 1.2 must be installed (http://www.mesa3d.org)]) -fi - -AC_SUBST(OPENGL_CFLAGS) -AC_SUBST(OPENGL_LIBS) - -]) - - -# ========================================================================= -# AM_PATH_FREETYPE : FreeType checking macros - -AC_DEFUN([AM_PATH_FREETYPE], -[ is_mandatory="$1" - -AC_REQUIRE_CPP() - -AC_ARG_WITH( freetype, - [ --with-freetype= path to the FreeType install files directory. - e.g. /usr/local/freetype]) - -AC_ARG_WITH( freetype-include, - [ --with-freetype-include= - path to the FreeType header files directory. - e.g. /usr/local/freetype/include]) - -AC_ARG_WITH( freetype-lib, - [ --with-freetype-lib= - path to the FreeType library files directory. - e.g. /usr/local/freetype/lib]) - -freetype_lib="freetype" - - -AC_PATH_PROG(FREETYPE_CONFIG, freetype-config, no) - -if test "$FREETYPE_CONFIG" = "no" -then - have_freetype_config="no" -else - FREETYPE_CFLAGS=`freetype-config --cflags` - FREETYPE_LIBS=`freetype-config --libs` - have_freetype_config="yes" -fi - -if test "$with_freetype" -then - freetype_includes="$with_freetype/include" - freetype_libraries="$with_freetype/lib" -fi - -if test "$with_freetype_include" -then - freetype_includes="$with_freetype_include" -fi - -if test "$with_freetype_lib" -then - freetype_libraries="$with_freetype_lib" -fi - -if test "$freetype_includes" -then - FREETYPE_CFLAGS="-I$freetype_includes" -fi - -# Checking the FreeType 2 instalation -_CPPFLAGS="$CPPFLAGS" -CPPFLAGS=" $FREETYPE_CFLAGS $CXXFLAGS" - -AC_MSG_CHECKING(for FreeType version = 2) - -AC_EGREP_CPP( yo_freetype2, -[#include -#if FREETYPE_MAJOR == 2 - yo_freetype2 -#endif], - have_freetype2="yes", - have_freetype2="no") - -if test "$have_freetype2" = "yes" -then - AC_MSG_RESULT(yes) -else - AC_MSG_RESULT(no) -fi - -# Test the libraries -AC_MSG_CHECKING(for FreeType libraries) - -if test $freetype_libraries -then - FREETYPE_LIBS="-L$freetype_libraries -l$freetype_lib" -fi - -CPPFLAGS="$FREETYPE_LIBS $CXXFLAGS" - -AC_TRY_LINK( , , have_freetype_libraries="yes", have_freetype_libraries="no") - -CPPFLAGS="$_CPPFLAGS" - -if test "$have_freetype_libraries" = "yes" -then - if test "$freetype_libraries" - then - AC_MSG_RESULT([$freetype_libraries]) - else - AC_MSG_RESULT(yes) - fi -else - AC_MSG_RESULT(no) -fi - -if test "$have_freetype2" = "yes" && test "$have_freetype_libraries" = "yes" -then - have_freetype="yes" -else - have_freetype="no" -fi - -if test "$have_freetype" = "no" && test "$is_mandatory" = "yes" -then - AC_MSG_ERROR([FreeType 2 must be installed (http://freetype.sourceforge.net)]) -fi - -AC_SUBST(FREETYPE_CFLAGS) -AC_SUBST(FREETYPE_LIBS) - -]) - - -# ========================================================================= -# AM_PATH_XF86VIDMODE : XF86VidMode checking macros - -AC_DEFUN([AM_PATH_XF86VIDMODE], -[ AC_MSG_CHECKING(for XF86VidMode extension) - -AC_REQUIRE_CPP() - -AC_ARG_WITH( xf86vidmode-lib, - [ --with-xf86vidmode-lib= - path to the XF86VidMode library. - e.g. /usr/X11R6/lib] ) - -xf86vidmode_lib="Xxf86vm" - -if test "$with_xf86vidmode_lib" = no -then - # The user explicitly disabled the use of XF86VidMode - have_xf86vidmode="disabled" - AC_MSG_RESULT(disabled) -else - if test "$with_xf86vidmode_lib" - then - xf86vidmode_libraries="$with_xf86vidmode_lib" - fi - - XF86VIDMODE_CFLAGS="-DXF86VIDMODE" -fi - -if test -z "$have_xf86vidmode" -# -a "$with_xf86vidmode_lib" -then - if test "$xf86vidmode_libraries" - then - XF86VIDMODE_LIBS="-L$xf86vidmode_libraries" - fi - - XF86VIDMODE_LIBS="$XF86VIDMODE_LIBS -l$xf86vidmode_lib" - - _CPPFLAGS="$CPPFLAGS" - - CPPFLAGS="$CXXFLAGS $XF86VIDMODE_LIBS" - - AC_TRY_LINK( , , have_xf86vidmode_libraries="yes", have_xf86vidmode_libraries="no") - - CPPFLAGS="$_CPPFLAGS" - - if test "$have_xf86vidmode_libraries" = "yes" - then - have_xf86vidmode="yes" - if test "$xf86vidmode_libraries" - then - AC_MSG_RESULT($xf86vidmode_libraries) - else - AC_MSG_RESULT(yes) - fi - else - have_xf86vidmode="no" - AC_MSG_RESULT(no, no fullscreen support available.) - fi - - xf86vidmode_libraries="$xf86vidmode_libraries" - -fi - -AC_SUBST(XF86VIDMODE_CFLAGS) -AC_SUBST(XF86VIDMODE_LIBS) - -]) - - -# ========================================================================= -# AM_PATH_OPENAL : OpenAL checking macros - -AC_DEFUN([AM_PATH_OPENAL], -[ is_mandatory="$1" - -AC_REQUIRE_CPP() - -# Get from the user option the path to the OpenAL files location -AC_ARG_WITH( openal, - [ --with-openal= path to the OpenAL install files directory. - e.g. /usr/local]) - -AC_ARG_WITH( openal-include, - [ --with-openal-include= - path to the OpenAL header files directory. - e.g. /usr/local/include]) - -AC_ARG_WITH( openal-lib, - [ --with-openal-lib= - path to the OpenAL library files directory. - e.g. /usr/local/lib]) - -openal_lib="openal" -alut_lib="alut" - -if test $with_openal -then - openal_includes="$with_openal/include" - openal_libraries="$with_openal/lib" -fi - -if test "$with_openal_include" -then - openal_includes="$with_openal_include" -fi - -if test "$with_openal_lib" -then - openal_libraries="$with_openal_lib" -fi - - -# Set OPENAL_CFLAGS -if test "$openal_includes" -then - OPENAL_CFLAGS="-I$openal_includes" -fi - -# Set OPENAL_LIBS -if test "$openal_libraries" -then - OPENAL_LIBS="-L$openal_libraries" -fi -OPENAL_LIBS="$OPENAL_LIBS -l$openal_lib -l$alut_lib" - -_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CXXFLAGS $OPENAL_CFLAGS" - -AC_MSG_CHECKING(for OpenAL headers) -AC_EGREP_CPP( yo_openal, -[#include -#include -#ifdef AL_VERSION - yo_openal -#endif], - have_openal_headers="yes", - have_openal_headers="no" ) - -if test "$have_openal_headers" = "yes" -then - if test "$openal_includes" - then - AC_MSG_RESULT([$openal_includes]) - else - AC_MSG_RESULT(yes) - fi -else - AC_MSG_RESULT(no) -fi - -# Test the libraries -AC_MSG_CHECKING(for OpenAL libraries) - -CPPFLAGS="$CXXFLAGS $OPENAL_LIBS" - -AC_TRY_LINK( , , have_openal_libraries="yes", have_openal_libraries="no") - -CPPFLAGS="$_CPPFLAGS" - -if test "$have_openal_libraries" = "yes" -then - if test "$openal_libraries" - then - AC_MSG_RESULT([$openal_libraries]) - else - AC_MSG_RESULT(yes) - fi -else - AC_MSG_RESULT(no) -fi - -openal_libraries="$openal_libraries" - -if test "$have_openal_headers" = "yes" \ - && test "$have_openal_libraries" = "yes" -then - have_openal="yes" -else - have_openal="no" -fi - -if test "$have_openal" = "no" -a "$is_mandatory" = "yes" -then - AC_MSG_ERROR([OpenAL is needed to compile NeL (http://www.openal.org).]) -fi - -AC_SUBST(OPENAL_CFLAGS) -AC_SUBST(OPENAL_LIBS) -AC_SUBST([have_openal]) - -]) - - -# ========================================================================= -# AM_PATH_PYTHON : Python checking macros - -AC_DEFUN([AM_PATH_PYTHON], -[ python_version_required="$1" - -is_mandatory="$2" - -AC_REQUIRE_CPP() - -# Get from the user option the path to the Python files location -AC_ARG_WITH( python, - [ --with-python= path to the Python prefix installation directory. - e.g. /usr/local], - [ PYTHON_PREFIX=$with_python ] -) - -AC_ARG_WITH( python-version, - [ --with-python-version= - Python version to use, e.g. 1.5], - [ PYTHON_VERSION=$with_python_version ] -) - -if test ! "$PYTHON_PREFIX" = "" -then - PATH="$PYTHON_PREFIX/bin:$PATH" -fi - -if test ! "$PYTHON_VERSION" = "" -then - PYTHON_EXEC="python$PYTHON_VERSION" -else - PYTHON_EXEC="python python2.1 python2.0 python1.5" -fi - -AC_PATH_PROGS(PYTHON, $PYTHON_EXEC, no, $PATH) - -if test "$PYTHON" != "no" -then - PYTHON_PREFIX=`$PYTHON -c 'import sys; print "%s" % (sys.prefix)'` - PYTHON_VERSION=`$PYTHON -c 'import sys; print "%s" % (sys.version[[:3]])'` - - is_python_version_enough=`expr $python_version_required \<= $PYTHON_VERSION` -fi - - -if test "$PYTHON" = "no" || test "$is_python_version_enough" != "1" -then - - if test "$is_mandatory" = "yes" - then - AC_MSG_ERROR([Python $python_version_required must be installed (http://www.python.org)]) - else - have_python="no" - fi - -else - - python_includes="$PYTHON_PREFIX/include/python$PYTHON_VERSION" - python_libraries="$PYTHON_PREFIX/lib/python$PYTHON_VERSION/config" - python_lib="python$PYTHON_VERSION" - - PYTHON_CFLAGS="-I$python_includes" - PYTHON_LIBS="-L$python_libraries -l$python_lib" - - _CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CXXFLAGS ${PYTHON_CFLAGS}" - - # Test the headers - AC_MSG_CHECKING(for Python headers) - - AC_EGREP_CPP( yo_python, - [#include - yo_python - ], - have_python_headers="yes", - have_python_headers="no" ) - - if test "$have_python_headers" = "yes" - then - AC_MSG_RESULT([$python_includes]) - else - AC_MSG_RESULT(no) - fi - - # Test the libraries - AC_MSG_CHECKING(for Python libraries) - - CPPFLAGS="$CXXFLAGS $PYTHON_CFLAGS" - - AC_TRY_LINK( , , have_python_libraries="yes", have_python_libraries="no") - - CPPFLAGS="$_CPPFLAGS" - - if test "$have_python_libraries" = "yes" - then - if test "$python_libraries" - then - AC_MSG_RESULT([$python_libraries]) - else - AC_MSG_RESULT(yes) - fi - else - AC_MSG_RESULT(no) - fi - - if test "$have_python_headers" = "yes" \ - && test "$have_python_libraries" = "yes" - then - have_python="yes" - else - have_python="no" - fi - - if test "$have_python" = "no" -a "$is_mandatory" = "yes" - then - AC_MSG_ERROR([Python is needed to compile NeL (http://www.python.org).]) - fi - - AC_SUBST(PYTHON_CFLAGS) - AC_SUBST(PYTHON_LIBS) - -fi - -]) - -# ========================================================================= -# AM_PATH_MYSQL : MySQL library - -# AM_PATH_MYSQL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) -# Test for MYSQL, and define MYSQL_CFLAGS and MYSQL_LIBS -# -AC_DEFUN([AM_PATH_MYSQL], -[# -# Get the cflags and libraries from the mysql_config script -# -AC_ARG_WITH(mysql-prefix,[ --with-mysql-prefix=PFX Prefix where MYSQL is installed (optional)], - mysql_prefix="$withval", mysql_prefix="") -AC_ARG_WITH(mysql-exec-prefix,[ --with-mysql-exec-prefix=PFX Exec prefix where MYSQL is installed (optional)], - mysql_exec_prefix="$withval", mysql_exec_prefix="") -AC_ARG_ENABLE(mysqltest, [ --disable-mysqltest Do not try to compile and run a test MYSQL program], - , enable_mysqltest=yes) - - if test x$mysql_exec_prefix != x ; then - mysql_args="$mysql_args --exec-prefix=$mysql_exec_prefix" - if test x${MYSQL_CONFIG+set} != xset ; then - MYSQL_CONFIG=$mysql_exec_prefix/bin/mysql_config - fi - fi - if test x$mysql_prefix != x ; then - mysql_args="$mysql_args --prefix=$mysql_prefix" - if test x${MYSQL_CONFIG+set} != xset ; then - MYSQL_CONFIG=$mysql_prefix/bin/mysql_config - fi - fi - - AC_REQUIRE([AC_CANONICAL_TARGET]) - AC_PATH_PROG(MYSQL_CONFIG, mysql_config, no) - min_mysql_version=ifelse([$1], ,0.11.0,$1) - AC_MSG_CHECKING(for MYSQL - version >= $min_mysql_version) - no_mysql="" - if test "$MYSQL_CONFIG" = "no" ; then - no_mysql=yes - else - MYSQL_CFLAGS=`$MYSQL_CONFIG $mysqlconf_args --cflags | sed -e "s/'//g"` - MYSQL_LIBS=`$MYSQL_CONFIG $mysqlconf_args --libs | sed -e "s/'//g"` - - mysql_major_version=`$MYSQL_CONFIG $mysql_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` - mysql_minor_version=`$MYSQL_CONFIG $mysql_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` - mysql_micro_version=`$MYSQL_CONFIG $mysql_config_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` - if test "x$enable_mysqltest" = "xyes" ; then - ac_save_CFLAGS="$CFLAGS" - ac_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $MYSQL_CFLAGS" - LIBS="$LIBS $MYSQL_LIBS" -# -# Now check if the installed MYSQL is sufficiently new. (Also sanity -# checks the results of mysql_config to some extent -# - rm -f conf.mysqltest - AC_TRY_RUN([ -#include -#include -#include -#include - -char* -my_strdup (char *str) -{ - char *new_str; - - if (str) - { - new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char)); - strcpy (new_str, str); - } - else - new_str = NULL; - - return new_str; -} - -int main (int argc, char *argv[]) -{ - int major, minor, micro; - char *tmp_version; - - /* This hangs on some systems (?) - system ("touch conf.mysqltest"); - */ - { FILE *fp = fopen("conf.mysqltest", "a"); if ( fp ) fclose(fp); } - - /* HP/UX 9 (%@#!) writes to sscanf strings */ - tmp_version = my_strdup("$min_mysql_version"); - if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { - printf("%s, bad version string\n", "$min_mysql_version"); - exit(1); - } - - if (($mysql_major_version > major) || - (($mysql_major_version == major) && ($mysql_minor_version > minor)) || - (($mysql_major_version == major) && ($mysql_minor_version == minor) && ($mysql_micro_version >= micro))) - { - return 0; - } - else - { - printf("\n*** 'mysql_config --version' returned %d.%d.%d, but the minimum version\n", $mysql_major_version, $mysql_minor_version, $mysql_micro_version); - printf("*** of MYSQL required is %d.%d.%d. If mysql_config is correct, then it is\n", major, minor, micro); - printf("*** best to upgrade to the required version.\n"); - printf("*** If mysql_config was wrong, set the environment variable MYSQL_CONFIG\n"); - printf("*** to point to the correct copy of mysql_config, and remove the file\n"); - printf("*** config.cache before re-running configure\n"); - return 1; - } -} - -],, no_mysql=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - fi - fi - if test "x$no_mysql" = x ; then - AC_MSG_RESULT(yes) - ifelse([$2], , :, [$2]) - else - AC_MSG_RESULT(no) - if test "$MYSQL_CONFIG" = "no" ; then - echo "*** The mysql_config script installed by MYSQL could not be found" - echo "*** If MYSQL was installed in PREFIX, make sure PREFIX/bin is in" - echo "*** your path, or set the MYSQL_CONFIG environment variable to the" - echo "*** full path to mysql_config." - else - if test -f conf.mysqltest ; then - : - else - echo "*** Could not run MYSQL test program, checking why..." - CFLAGS="$CFLAGS $MYSQL_CFLAGS" - LIBS="$LIBS $MYSQL_LIBS" - AC_TRY_LINK([ -#include -#include - -int main(int argc, char *argv[]) -{ return 0; } -#undef main -#define main K_and_R_C_main -], [ return 0; ], - [ echo "*** The test program compiled, but did not run. This usually means" - echo "*** that the run-time linker is not finding MYSQL or finding the wrong" - echo "*** version of MYSQL. If it is not finding MYSQL, you'll need to set your" - echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" - echo "*** to the installed location Also, make sure you have run ldconfig if that" - echo "*** is required on your system" - echo "***" - echo "*** If you have an old version installed, it is best to remove it, although" - echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], - [ echo "*** The test program failed to compile or link. See the file config.log for the" - echo "*** exact error that occured. This usually means MYSQL was incorrectly installed" - echo "*** or that you have moved MYSQL since it was installed. In the latter case, you" - echo "*** may want to edit the mysql_config script: $MYSQL_CONFIG" ]) - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - fi - fi - MYSQL_CFLAGS="" - MYSQL_LIBS="" - ifelse([$3], , :, [$3]) - fi - AC_SUBST(MYSQL_CFLAGS) - AC_SUBST(MYSQL_LIBS) - rm -f conf.mysqltest -]) - -# ========================================================================= -# AM_PATH_FMOD : FMOD checking macros - -AC_DEFUN([AM_PATH_FMOD], -[ is_mandatory="$1" - -AC_REQUIRE_CPP() - -# Get from the user option the path to the FMOD files location -AC_ARG_WITH( fmod, - [ --with-fmod= path to the FMOD install files directory. - e.g. /usr/local]) - -AC_ARG_WITH( fmod-include, - [ --with-fmod-include= - path to the FMOD header files directory. - e.g. /usr/local/include]) - -AC_ARG_WITH( fmod-lib, - [ --with-fmod-lib= - path to the FMOD library files directory. - e.g. /usr/local/lib]) - -fmod_lib="fmod" - -if test $with_fmod -then - fmod_includes="$with_fmod/include" - fmod_libraries="$with_fmod/lib" -fi - -if test "$with_fmod_include" -then - fmod_includes="$with_fmod_include" -fi - -if test "$with_fmod_lib" -then - fmod_libraries="$with_fmod_lib" -fi - - -# Set FMOD_CFLAGS -if test "$fmod_includes" -then - FMOD_CFLAGS="-I$fmod_includes" -fi - -# Set FMOD_LIBS -if test "$fmod_libraries" -then - FMOD_LIBS="-L$fmod_libraries" -fi -FMOD_LIBS="$FMOD_LIBS -l$fmod_lib" - -_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CXXFLAGS $FMOD_CFLAGS" - -AC_MSG_CHECKING(for FMOD headers) -AC_EGREP_CPP( yo_fmod, -[#include -#ifdef FMOD_VERSION - yo_fmod -#endif], - have_fmod_headers="yes", - have_fmod_headers="no" ) - -if test "$have_fmod_headers" = "yes" -then - if test "$fmod_includes" - then - AC_MSG_RESULT([$fmod_includes]) - else - AC_MSG_RESULT(yes) - fi -else - AC_MSG_RESULT(no) -fi - -# Test the libraries -AC_MSG_CHECKING(for FMOD libraries) - -CPPFLAGS="$CXXFLAGS $FMOD_LIBS" - -AC_TRY_LINK( , , have_fmod_libraries="yes", have_fmod_libraries="no") - -CPPFLAGS="$_CPPFLAGS" - -if test "$have_fmod_libraries" = "yes" -then - if test "$fmod_libraries" - then - AC_MSG_RESULT([$fmod_libraries]) - else - AC_MSG_RESULT(yes) - fi -else - AC_MSG_RESULT(no) -fi - -fmod_libraries="$fmod_libraries" - -if test "$have_fmod_headers" = "yes" \ - && test "$have_fmod_libraries" = "yes" -then - have_fmod="yes" -else - have_fmod="no" -fi - -if test "$have_fmod" = "no" -a "$is_mandatory" = "yes" -then - AC_MSG_ERROR([FMOD is needed to compile NeL (http://www.fmod.org).]) -fi - -AC_SUBST(FMOD_CFLAGS) -AC_SUBST(FMOD_LIBS) -AC_SUBST([have_fmod]) - -]) - -# ========================================================================= -# End of file - diff --git a/code/nelns/admin_executor_service/Makefile.am b/code/nelns/admin_executor_service/Makefile.am deleted file mode 100644 index aafee52b1..000000000 --- a/code/nelns/admin_executor_service/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# -# $Id: Makefile.am,v 1.8 2004/03/02 09:10:50 cado Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = admin_executor_service.cfg \ - admin_executor_service.dsp \ - admin_executor_service_8.vcproj \ - admin_executor_service.vcproj \ - log_report.h \ - common.cfg - -sbin_PROGRAMS = admin_executor_service - -admin_executor_servicedir = ${pkgsysconfdir} -admin_executor_service_DATA = admin_executor_service.cfg common.cfg - -AM_CXXFLAGS = -DNELNS_CONFIG="\"${pkgsysconfdir}\"" -DNELNS_STATE="\"${pkglocalstatedir}\"" -DNELNS_LOGS="\"${logdir}\"" - -admin_executor_service_SOURCES = admin_executor_service.cpp \ - log_report.cpp - -# End of Makefile.am - diff --git a/code/nelns/admin_executor_service/log_report.cpp b/code/nelns/admin_executor_service/log_report.cpp index eac5f83c3..7106fb9d1 100644 --- a/code/nelns/admin_executor_service/log_report.cpp +++ b/code/nelns/admin_executor_service/log_report.cpp @@ -1,580 +1,581 @@ -// NeLNS - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero 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 Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "log_report.h" -#include -#include "nel/misc/common.h" -#include "nel/misc/displayer.h" -#include "nel/misc/file.h" -#include "nel/misc/path.h" -#include "nel/misc/variable.h" - -using namespace NLMISC; -using namespace std; - - -CVariable LogPath( "LogReport","LogPath", "Path of the log files", ".", 0, true ); - -const uint MAX_LOG_LINE_SIZE = 1024; -//nlctassert(MAX_LOG_LINE_SIZE>0); - -enum TLogLineHeader { LHDate, LHTime, LHType, LHThread, LHService, LHCodeFile, LHCodeLine, LHSeparator, LH_NB_FIELDS }; - - -/// -bool isLogFile( const std::string& filename ) -{ - uint len = (uint)filename.size(); - return (len >= 4 ) && (filename.substr( len-4 ) == ".log"); -} - -/// -inline bool isNumberChar( char c ) -{ - return (c >= '0') && (c <= '9'); -} - -/// -void sortLogFiles( vector& filenames ) -{ - uint i; - for ( i=0; i!=filenames.size(); ++i ) - { - // Ensure that a log file without number comes *after* the ones with a number - string name = string(filenames[i]); - string::size_type dotpos = name.find_last_of('.'); - if ( (dotpos!=string::npos) && (dotpos > 2) ) - { - if ( ! (isNumberChar(name[dotpos-1]) && isNumberChar(name[dotpos-2]) && isNumberChar(name[dotpos-3])) ) - { - name = name.substr( 0, dotpos ) + "ZZZ" + name.substr( dotpos ); - filenames[i] = name.c_str(); - } - } - } - sort( filenames.begin(), filenames.end() ); - for ( i=0; i!=filenames.size(); ++i ) - { - // Set the original names back - string name = filenames[i]; - string::size_type tokenpos = name.find( "ZZZ." ); - if ( tokenpos != string::npos ) - { - name = name.substr( 0, tokenpos ) + name.substr( tokenpos + 3 ); - filenames[i] = name.c_str(); - } - } -} - -void CMakeLogTask::setLogPath(const std::string & logPath) -{ - _LogPaths.resize( 1 ); - _LogPaths[0] = logPath; -} - -void CMakeLogTask::setLogPaths(const std::vector& logPaths) -{ - _LogPaths = logPaths; -} - -void CMakeLogTask::setLogPathToDefault() -{ - setLogPath( LogPath.get() ); -} - -/* - * - */ -CMakeLogTask::~CMakeLogTask() -{ - if ( _Thread ) // implies && _OutputLogReport - { - if ( ! _Complete ) - { - pleaseStop(); - _Thread->wait(); - } - clear(); - } -} - - -/* - * - */ -void CMakeLogTask::start() -{ - if ( _Thread ) - { - if ( _Complete ) - clear(); - else - return; - } - _Stopping = false; - _Complete = false; - _Thread = NLMISC::IThread::create( this ); - _OutputLogReport = new CLogReport(); - _Thread->start(); -} - - -/* - * - */ -void CMakeLogTask::clear() -{ - if (_Thread) - { - delete _Thread; - _Thread = NULL; - } - if (_OutputLogReport) - { - delete _OutputLogReport; - _OutputLogReport = NULL; - } -} - -/* - * - */ -void CMakeLogTask::terminateTask() -{ - if (!_Thread) // _Thread _implies _OutputLogReport - return; - - pleaseStop(); - _Thread->wait(); - - clear(); -} - -// -bool isOfLogDotLogFamily( const std::string& filename ) -{ - return ((filename == "log.log") || - ((filename.size() == 10) && - (filename.substr( 0, 3 ) == "log") && - isNumberChar(filename[3]) && isNumberChar(filename[4]) && isNumberChar(filename[5]) && - (filename.substr( 6, 4 ) == ".log")) ); -} - - -enum TVersionTargetMode { TTMAll, TTMMatchAllV, TTMMatchExactV, TTMMatchGreaterV, TTMMatchLowerV } targetMode; -const uint CurrentVersion = std::numeric_limits::max(); - -// Return true and logVersion, or false if not a log with version -bool getLogVersion( const std::string& filename, uint& logVersion ) -{ - uint len = (uint)filename.size(); - if ( (len > 4) && (filename.substr( len-4 ) == ".log") ) - { - if ( filename.substr(0, 3) == "log" ) - { - if ( (len == 7) || - ((len == 10) && (isNumberChar(filename[3]) && isNumberChar(filename[4]) && isNumberChar(filename[5]))) ) - { - logVersion = CurrentVersion; - return true; - } - } - else if ( filename[0] == 'v' ) - { - string::size_type p = filename.find( "_", 1 ); - if ( p != string::npos ) - { - if ( (len == p + 8) || - ((len == p + 11) && (isNumberChar(filename[p+4]) && isNumberChar(filename[p+5]) && isNumberChar(filename[p+6]))) ) - { - NLMISC::fromString( filename.substr( 1, p-1 ), logVersion ); - return true; - } - } - } - } - return false; -} - -// Assumes filename is .log file -bool matchLogTarget( const std::string& filename, TVersionTargetMode targetMode, uint targetVersion ) -{ - if ( targetMode == TTMAll ) - return true; - - uint version; - - // Get version or exclude non-standard log files - if ( ! getLogVersion( filename, version ) ) - return false; - - // Exclude non-matching version - switch ( targetMode ) - { - case TTMMatchExactV: - return (version == targetVersion); // break; - case TTMMatchGreaterV: - return (version >= targetVersion); // break; - case TTMMatchLowerV: - return (version <= targetVersion); // break; - default: // TTMMatchAllV - return true; - } -} - -/* - * - */ -void CMakeLogTask::run() -{ - // Parse log target - uint targetVersion = CurrentVersion; - uint lts = (uint)_LogTarget.size(); - if ( _LogTarget.empty() || (_LogTarget == "v") ) - { - targetMode = TTMMatchExactV; - } - else if ( _LogTarget == "v*" ) - { - targetMode = TTMMatchAllV; - } - else if ( _LogTarget == "*" ) - { - targetMode = TTMAll; - } - else if ( (lts > 1) && (_LogTarget[0] == 'v') ) - { - uint additionalChars = 1; - if ( _LogTarget[lts-1] == '+' ) - targetMode = TTMMatchGreaterV; - else if ( _LogTarget[lts-1] == '-' ) - targetMode = TTMMatchLowerV; - else - { - targetMode = TTMMatchExactV; - additionalChars = 0; - } - - NLMISC::fromString( _LogTarget.substr( 1, lts-additionalChars-1 ), targetVersion ); - } - else - { - nlwarning( "Invalid log target argument: %s", _LogTarget.c_str() ); - _Complete = true; - return; - } - - // Get log files and sort them - vector filenames; - vector filenamesOfPath; - for ( vector::const_iterator ilf=_LogPaths.begin(); ilf!=_LogPaths.end(); ++ilf ) - { - string path = (*ilf); - if ( (! path.empty()) && (path[path.size()-1]!='/') ) - path += "/"; - filenamesOfPath.clear(); - CPath::getPathContent( path, false, false, true, filenamesOfPath, NULL, true ); - vector::iterator ilf2 = partition( filenamesOfPath.begin(), filenamesOfPath.end(), isLogFile ); - filenamesOfPath.erase( ilf2, filenamesOfPath.end() ); - sortLogFiles( filenamesOfPath ); - filenames.insert( filenames.end(), filenamesOfPath.begin(), filenamesOfPath.end() ); - } - - // Analyse log files - _OutputLogReport->reset(); - uint nbLines = 0; - char line [MAX_LOG_LINE_SIZE]; - - uint nbSkippedFiles = 0; - for ( vector::const_iterator ilf=filenames.begin(); ilf!=filenames.end(); ++ilf ) - { - string shortname = CFile::getFilename( *ilf ); - - // Filter log files based on filename before opening them - if ( ! matchLogTarget( shortname, targetMode, targetVersion ) ) - { - ++nbSkippedFiles; - continue; - } - - nlinfo( "Processing %s (%u/%u)", (*ilf).c_str(), ilf-filenames.begin(), filenames.size() ); - CIFile logfile; - if ( logfile.open( *ilf, true ) ) - { - _OutputLogReport->setProgress( (uint)(ilf-filenames.begin()), (uint)filenames.size() ); - while ( ! logfile.eof() ) - { - logfile.getline( line, MAX_LOG_LINE_SIZE ); - line[MAX_LOG_LINE_SIZE-1] = '\0'; // force valid end of line - _OutputLogReport->pushLine( line ); - ++nbLines; - - if ( isStopping() ) - return; - } - } - } - nlinfo( "%u lines processed", nbLines ); - if ( nbSkippedFiles != 0 ) - nlinfo( "%u log files skipped, not matching target %s", nbSkippedFiles, _LogTarget.c_str() ); - _Complete = true; -} - - -/* - * Add a log line to the report tree - */ -void CLogReport::pushLine( const std::string& line, NLMISC::CLog::TLogType onlyType, bool countOtherTypes ) -{ - // Ignore session title - if ( (line.size() > 14) && (line.substr( 0, 14 ) == "Log Starting [") ) - return; - - // Decode standard log line - vector lineTokens; - explode( line, string(" "), lineTokens ); - - if ( lineTokens.size() < LH_NB_FIELDS ) - return; - - // Filter log type - if ( onlyType != CLog::LOG_UNKNOWN ) - { - if ( lineTokens[LHType] != IDisplayer::logTypeToString( onlyType ) ) - { - if ( countOtherTypes ) - storeLine( lineTokens, true ); - return; - } - } - - // Store - storeLine( lineTokens, false ); -} - - -/* - * - */ -void CLogReportNode::storeLine( const std::vector& lineTokens, bool mainCountOnly ) -{ - // Get service name from "[machine/]serviceName-serviceId" - string service = lineTokens[LHService]; - string::size_type p = service.find( '/' ); - if ( p != string::npos ) - service = service.substr( p+1 ); - p = service.find( '-' ); - if ( p != string::npos ) - service = service.substr( 0, p ); - - // Store to appropriate child - CLogReportLeaf *child = getChild( service ); - if ( ! child ) - child = addChild( service ); - child->storeLine( lineTokens, mainCountOnly ); -} - - -/* - * - */ -void CLogReportLeaf::storeLine( const std::vector& lineTokens, bool mainCountOnly ) -{ - if ( ! mainCountOnly ) - { - // Build key from "codeFile codeLine" - string key = lineTokens[LHCodeFile] + ":" + lineTokens[LHCodeLine]; - _LogLineInfo[key].addAnOccurence( lineTokens ); - } - ++_Counts[lineTokens[LHType]]; - ++_TotalLines; -} - - -/* - * - */ -void CLogLineInfo::addAnOccurence( const std::vector& lineTokens ) -{ - if ( NbOccurences == 0 ) - { - for ( uint i=LH_NB_FIELDS; ireport( targetLog, true ); - } - else - { - targetLog->displayNL( "Nothing found for service %s", service.c_str() ); - } -} - - -/* - * Get results for a service (all distinct lines, sorted by occurence) - */ -void CLogReportLeaf::report( NLMISC::CLog *targetLog, bool ) -{ - // Sort it - typedef multimap< uint, pair< string, const CLogLineInfo * >, std::greater > CSortedByOccurenceLogLineInfoMap; - CSortedByOccurenceLogLineInfoMap sortedByOccurence; - for ( CLogLineInfoMap::const_iterator it=_LogLineInfo.begin(); it!=_LogLineInfo.end(); ++it ) - { - const string &key = (*it).first; - const CLogLineInfo& info = (*it).second; - sortedByOccurence.insert( make_pair( info.NbOccurences, make_pair( key, &info ) ) ); - } - - // Display it - for ( CSortedByOccurenceLogLineInfoMap::const_iterator iso=sortedByOccurence.begin(); iso!=sortedByOccurence.end(); ++iso ) - { - const string &key = (*iso).second.first; - const CLogLineInfo& info = *((*iso).second.second); - targetLog->displayRawNL( "%s %6u %s : %s", _Service.c_str(), info.NbOccurences, key.c_str(), info.SampleLogText.c_str() ); - } -} - - -/* - * Return the number of lines displayed - */ -uint CLogReportLeaf::reportPart( uint beginIndex, uint maxNbLines, NLMISC::CLog *targetLog ) -{ - uint i = 0; - CLogLineInfoMap::const_iterator it; - for ( it=_LogLineInfo.begin(); it!=_LogLineInfo.end(); ++it ) - { - if ( i >= beginIndex ) - { - if ( i >= maxNbLines ) - return i - beginIndex; - - const string &key = (*it).first; - const CLogLineInfo& info = (*it).second; - targetLog->displayRawNL( "%s %6u %s : %s", _Service.c_str(), info.NbOccurences, key.c_str(), info.SampleLogText.c_str() ); - } - ++i; - } - return i - beginIndex; -} - - -/* - * Get summary of results - */ -void CLogReportNode::report( NLMISC::CLog *targetLog, bool displayDetailsPerService ) -{ - uint nb1Sum=0, nb2Sum=0; - for ( std::vector::const_iterator it=_Children.begin(); it!=_Children.end(); ++it ) - { - CLogReportLeaf *pt = (*it); - - // Get distinct warnings - uint nb1 = pt->getNbDistinctLines(); - nb1Sum += nb1; - - // Get total warnings, info... but filter out lines with no header - uint sumTotalLinesNotUnknown = 0; - uint nbTotalLines [CLog::LOG_UNKNOWN]; - for ( uint i=CLog::LOG_ERROR; i!=CLog::LOG_UNKNOWN; ++i ) - { - nbTotalLines[i] = pt->getNbTotalLines( (CLog::TLogType)i ); - sumTotalLinesNotUnknown += nbTotalLines[i]; - } - if ( sumTotalLinesNotUnknown != 0 ) - { - targetLog->displayRawNL( "%s: \t%u distinct WRN, %u total WRN, %u INF, %u DBG, %u STT, %u AST, %u ERR, %u TOTAL", - pt->service().c_str(), nb1, nbTotalLines[CLog::LOG_WARNING], - nbTotalLines[CLog::LOG_INFO], nbTotalLines[CLog::LOG_DEBUG], - nbTotalLines[CLog::LOG_STAT], nbTotalLines[CLog::LOG_ASSERT], - nbTotalLines[CLog::LOG_ERROR], pt->getNbTotalLines( CLog::LOG_UNKNOWN ) ); - nb2Sum += nbTotalLines[CLog::LOG_WARNING]; - } - } - targetLog->displayRawNL( "=> %u distinct, %u total WRN (%u pages)", nb1Sum, nb2Sum, nb1Sum / NB_LINES_PER_PAGE + 1 ); - - if ( displayDetailsPerService ) - { - for ( std::vector::const_iterator it=_Children.begin(); it!=_Children.end(); ++it ) - { - (*it)->report( targetLog, true ); - } - } -} - - -/* - * Get partial results (pageNum>=1) - */ -void CLogReportNode::reportPage( uint pageNum, NLMISC::CLog *targetLog ) -{ - if ( _Children.empty() ) - { - targetLog->displayRawNL( "[END OF LOG]" ); - return; - } - - uint beginIndex = pageNum * NB_LINES_PER_PAGE; - uint lineCounter = 0, prevLineCounter; - for ( std::vector::const_iterator it=_Children.begin(); it!=_Children.end(); ++it ) - { - CLogReportLeaf *pt = (*it); - prevLineCounter = lineCounter; - lineCounter += pt->getNbDistinctLines(); - if ( lineCounter >= beginIndex ) - { - uint remainingLines = pageNum - (lineCounter - beginIndex ); - pt->reportPart( beginIndex - prevLineCounter, remainingLines, targetLog ); // - while ( remainingLines != 0 ) - { - ++it; - if ( it == _Children.end() ) - { - targetLog->displayRawNL( "[END OF LOG]" ); - return; - } - pt = (*it); - remainingLines -= pt->reportPart( 0, remainingLines, targetLog ); - } - return; - } - } -} +// NeLNS - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "log_report.h" +#include +#include +#include "nel/misc/common.h" +#include "nel/misc/displayer.h" +#include "nel/misc/file.h" +#include "nel/misc/path.h" +#include "nel/misc/variable.h" + +using namespace NLMISC; +using namespace std; + + +CVariable LogPath( "LogReport","LogPath", "Path of the log files", ".", 0, true ); + +const uint MAX_LOG_LINE_SIZE = 1024; +//nlctassert(MAX_LOG_LINE_SIZE>0); + +enum TLogLineHeader { LHDate, LHTime, LHType, LHThread, LHService, LHCodeFile, LHCodeLine, LHSeparator, LH_NB_FIELDS }; + + +/// +bool isLogFile( const std::string& filename ) +{ + uint len = (uint)filename.size(); + return (len >= 4 ) && (filename.substr( len-4 ) == ".log"); +} + +/// +inline bool isNumberChar( char c ) +{ + return (c >= '0') && (c <= '9'); +} + +/// +void sortLogFiles( vector& filenames ) +{ + uint i; + for ( i=0; i!=filenames.size(); ++i ) + { + // Ensure that a log file without number comes *after* the ones with a number + string name = string(filenames[i]); + string::size_type dotpos = name.find_last_of('.'); + if ( (dotpos!=string::npos) && (dotpos > 2) ) + { + if ( ! (isNumberChar(name[dotpos-1]) && isNumberChar(name[dotpos-2]) && isNumberChar(name[dotpos-3])) ) + { + name = name.substr( 0, dotpos ) + "ZZZ" + name.substr( dotpos ); + filenames[i] = name.c_str(); + } + } + } + sort( filenames.begin(), filenames.end() ); + for ( i=0; i!=filenames.size(); ++i ) + { + // Set the original names back + string name = filenames[i]; + string::size_type tokenpos = name.find( "ZZZ." ); + if ( tokenpos != string::npos ) + { + name = name.substr( 0, tokenpos ) + name.substr( tokenpos + 3 ); + filenames[i] = name.c_str(); + } + } +} + +void CMakeLogTask::setLogPath(const std::string & logPath) +{ + _LogPaths.resize( 1 ); + _LogPaths[0] = logPath; +} + +void CMakeLogTask::setLogPaths(const std::vector& logPaths) +{ + _LogPaths = logPaths; +} + +void CMakeLogTask::setLogPathToDefault() +{ + setLogPath( LogPath.get() ); +} + +/* + * + */ +CMakeLogTask::~CMakeLogTask() +{ + if ( _Thread ) // implies && _OutputLogReport + { + if ( ! _Complete ) + { + pleaseStop(); + _Thread->wait(); + } + clear(); + } +} + + +/* + * + */ +void CMakeLogTask::start() +{ + if ( _Thread ) + { + if ( _Complete ) + clear(); + else + return; + } + _Stopping = false; + _Complete = false; + _Thread = NLMISC::IThread::create( this ); + _OutputLogReport = new CLogReport(); + _Thread->start(); +} + + +/* + * + */ +void CMakeLogTask::clear() +{ + if (_Thread) + { + delete _Thread; + _Thread = NULL; + } + if (_OutputLogReport) + { + delete _OutputLogReport; + _OutputLogReport = NULL; + } +} + +/* + * + */ +void CMakeLogTask::terminateTask() +{ + if (!_Thread) // _Thread _implies _OutputLogReport + return; + + pleaseStop(); + _Thread->wait(); + + clear(); +} + +// +bool isOfLogDotLogFamily( const std::string& filename ) +{ + return ((filename == "log.log") || + ((filename.size() == 10) && + (filename.substr( 0, 3 ) == "log") && + isNumberChar(filename[3]) && isNumberChar(filename[4]) && isNumberChar(filename[5]) && + (filename.substr( 6, 4 ) == ".log")) ); +} + + +enum TVersionTargetMode { TTMAll, TTMMatchAllV, TTMMatchExactV, TTMMatchGreaterV, TTMMatchLowerV } targetMode; +const uint CurrentVersion = std::numeric_limits::max(); + +// Return true and logVersion, or false if not a log with version +bool getLogVersion( const std::string& filename, uint& logVersion ) +{ + uint len = (uint)filename.size(); + if ( (len > 4) && (filename.substr( len-4 ) == ".log") ) + { + if ( filename.substr(0, 3) == "log" ) + { + if ( (len == 7) || + ((len == 10) && (isNumberChar(filename[3]) && isNumberChar(filename[4]) && isNumberChar(filename[5]))) ) + { + logVersion = CurrentVersion; + return true; + } + } + else if ( filename[0] == 'v' ) + { + string::size_type p = filename.find( "_", 1 ); + if ( p != string::npos ) + { + if ( (len == p + 8) || + ((len == p + 11) && (isNumberChar(filename[p+4]) && isNumberChar(filename[p+5]) && isNumberChar(filename[p+6]))) ) + { + NLMISC::fromString( filename.substr( 1, p-1 ), logVersion ); + return true; + } + } + } + } + return false; +} + +// Assumes filename is .log file +bool matchLogTarget( const std::string& filename, TVersionTargetMode targetMode, uint targetVersion ) +{ + if ( targetMode == TTMAll ) + return true; + + uint version; + + // Get version or exclude non-standard log files + if ( ! getLogVersion( filename, version ) ) + return false; + + // Exclude non-matching version + switch ( targetMode ) + { + case TTMMatchExactV: + return (version == targetVersion); // break; + case TTMMatchGreaterV: + return (version >= targetVersion); // break; + case TTMMatchLowerV: + return (version <= targetVersion); // break; + default: // TTMMatchAllV + return true; + } +} + +/* + * + */ +void CMakeLogTask::run() +{ + // Parse log target + uint targetVersion = CurrentVersion; + uint lts = (uint)_LogTarget.size(); + if ( _LogTarget.empty() || (_LogTarget == "v") ) + { + targetMode = TTMMatchExactV; + } + else if ( _LogTarget == "v*" ) + { + targetMode = TTMMatchAllV; + } + else if ( _LogTarget == "*" ) + { + targetMode = TTMAll; + } + else if ( (lts > 1) && (_LogTarget[0] == 'v') ) + { + uint additionalChars = 1; + if ( _LogTarget[lts-1] == '+' ) + targetMode = TTMMatchGreaterV; + else if ( _LogTarget[lts-1] == '-' ) + targetMode = TTMMatchLowerV; + else + { + targetMode = TTMMatchExactV; + additionalChars = 0; + } + + NLMISC::fromString( _LogTarget.substr( 1, lts-additionalChars-1 ), targetVersion ); + } + else + { + nlwarning( "Invalid log target argument: %s", _LogTarget.c_str() ); + _Complete = true; + return; + } + + // Get log files and sort them + vector filenames; + vector filenamesOfPath; + for ( vector::const_iterator ilf=_LogPaths.begin(); ilf!=_LogPaths.end(); ++ilf ) + { + string path = (*ilf); + if ( (! path.empty()) && (path[path.size()-1]!='/') ) + path += "/"; + filenamesOfPath.clear(); + CPath::getPathContent( path, false, false, true, filenamesOfPath, NULL, true ); + vector::iterator ilf2 = partition( filenamesOfPath.begin(), filenamesOfPath.end(), isLogFile ); + filenamesOfPath.erase( ilf2, filenamesOfPath.end() ); + sortLogFiles( filenamesOfPath ); + filenames.insert( filenames.end(), filenamesOfPath.begin(), filenamesOfPath.end() ); + } + + // Analyse log files + _OutputLogReport->reset(); + uint nbLines = 0; + char line [MAX_LOG_LINE_SIZE]; + + uint nbSkippedFiles = 0; + for ( vector::const_iterator ilf=filenames.begin(); ilf!=filenames.end(); ++ilf ) + { + string shortname = CFile::getFilename( *ilf ); + + // Filter log files based on filename before opening them + if ( ! matchLogTarget( shortname, targetMode, targetVersion ) ) + { + ++nbSkippedFiles; + continue; + } + + nlinfo( "Processing %s (%u/%u)", (*ilf).c_str(), ilf-filenames.begin(), filenames.size() ); + CIFile logfile; + if ( logfile.open( *ilf, true ) ) + { + _OutputLogReport->setProgress( (uint)(ilf-filenames.begin()), (uint)filenames.size() ); + while ( ! logfile.eof() ) + { + logfile.getline( line, MAX_LOG_LINE_SIZE ); + line[MAX_LOG_LINE_SIZE-1] = '\0'; // force valid end of line + _OutputLogReport->pushLine( line ); + ++nbLines; + + if ( isStopping() ) + return; + } + } + } + nlinfo( "%u lines processed", nbLines ); + if ( nbSkippedFiles != 0 ) + nlinfo( "%u log files skipped, not matching target %s", nbSkippedFiles, _LogTarget.c_str() ); + _Complete = true; +} + + +/* + * Add a log line to the report tree + */ +void CLogReport::pushLine( const std::string& line, NLMISC::CLog::TLogType onlyType, bool countOtherTypes ) +{ + // Ignore session title + if ( (line.size() > 14) && (line.substr( 0, 14 ) == "Log Starting [") ) + return; + + // Decode standard log line + vector lineTokens; + explode( line, string(" "), lineTokens ); + + if ( lineTokens.size() < LH_NB_FIELDS ) + return; + + // Filter log type + if ( onlyType != CLog::LOG_UNKNOWN ) + { + if ( lineTokens[LHType] != IDisplayer::logTypeToString( onlyType ) ) + { + if ( countOtherTypes ) + storeLine( lineTokens, true ); + return; + } + } + + // Store + storeLine( lineTokens, false ); +} + + +/* + * + */ +void CLogReportNode::storeLine( const std::vector& lineTokens, bool mainCountOnly ) +{ + // Get service name from "[machine/]serviceName-serviceId" + string service = lineTokens[LHService]; + string::size_type p = service.find( '/' ); + if ( p != string::npos ) + service = service.substr( p+1 ); + p = service.find( '-' ); + if ( p != string::npos ) + service = service.substr( 0, p ); + + // Store to appropriate child + CLogReportLeaf *child = getChild( service ); + if ( ! child ) + child = addChild( service ); + child->storeLine( lineTokens, mainCountOnly ); +} + + +/* + * + */ +void CLogReportLeaf::storeLine( const std::vector& lineTokens, bool mainCountOnly ) +{ + if ( ! mainCountOnly ) + { + // Build key from "codeFile codeLine" + string key = lineTokens[LHCodeFile] + ":" + lineTokens[LHCodeLine]; + _LogLineInfo[key].addAnOccurence( lineTokens ); + } + ++_Counts[lineTokens[LHType]]; + ++_TotalLines; +} + + +/* + * + */ +void CLogLineInfo::addAnOccurence( const std::vector& lineTokens ) +{ + if ( NbOccurences == 0 ) + { + for ( uint i=LH_NB_FIELDS; ireport( targetLog, true ); + } + else + { + targetLog->displayNL( "Nothing found for service %s", service.c_str() ); + } +} + + +/* + * Get results for a service (all distinct lines, sorted by occurence) + */ +void CLogReportLeaf::report( NLMISC::CLog *targetLog, bool ) +{ + // Sort it + typedef multimap< uint, pair< string, const CLogLineInfo * >, std::greater > CSortedByOccurenceLogLineInfoMap; + CSortedByOccurenceLogLineInfoMap sortedByOccurence; + for ( CLogLineInfoMap::const_iterator it=_LogLineInfo.begin(); it!=_LogLineInfo.end(); ++it ) + { + const string &key = (*it).first; + const CLogLineInfo& info = (*it).second; + sortedByOccurence.insert( make_pair( info.NbOccurences, make_pair( key, &info ) ) ); + } + + // Display it + for ( CSortedByOccurenceLogLineInfoMap::const_iterator iso=sortedByOccurence.begin(); iso!=sortedByOccurence.end(); ++iso ) + { + const string &key = (*iso).second.first; + const CLogLineInfo& info = *((*iso).second.second); + targetLog->displayRawNL( "%s %6u %s : %s", _Service.c_str(), info.NbOccurences, key.c_str(), info.SampleLogText.c_str() ); + } +} + + +/* + * Return the number of lines displayed + */ +uint CLogReportLeaf::reportPart( uint beginIndex, uint maxNbLines, NLMISC::CLog *targetLog ) +{ + uint i = 0; + CLogLineInfoMap::const_iterator it; + for ( it=_LogLineInfo.begin(); it!=_LogLineInfo.end(); ++it ) + { + if ( i >= beginIndex ) + { + if ( i >= maxNbLines ) + return i - beginIndex; + + const string &key = (*it).first; + const CLogLineInfo& info = (*it).second; + targetLog->displayRawNL( "%s %6u %s : %s", _Service.c_str(), info.NbOccurences, key.c_str(), info.SampleLogText.c_str() ); + } + ++i; + } + return i - beginIndex; +} + + +/* + * Get summary of results + */ +void CLogReportNode::report( NLMISC::CLog *targetLog, bool displayDetailsPerService ) +{ + uint nb1Sum=0, nb2Sum=0; + for ( std::vector::const_iterator it=_Children.begin(); it!=_Children.end(); ++it ) + { + CLogReportLeaf *pt = (*it); + + // Get distinct warnings + uint nb1 = pt->getNbDistinctLines(); + nb1Sum += nb1; + + // Get total warnings, info... but filter out lines with no header + uint sumTotalLinesNotUnknown = 0; + uint nbTotalLines [CLog::LOG_UNKNOWN]; + for ( uint i=CLog::LOG_ERROR; i!=CLog::LOG_UNKNOWN; ++i ) + { + nbTotalLines[i] = pt->getNbTotalLines( (CLog::TLogType)i ); + sumTotalLinesNotUnknown += nbTotalLines[i]; + } + if ( sumTotalLinesNotUnknown != 0 ) + { + targetLog->displayRawNL( "%s: \t%u distinct WRN, %u total WRN, %u INF, %u DBG, %u STT, %u AST, %u ERR, %u TOTAL", + pt->service().c_str(), nb1, nbTotalLines[CLog::LOG_WARNING], + nbTotalLines[CLog::LOG_INFO], nbTotalLines[CLog::LOG_DEBUG], + nbTotalLines[CLog::LOG_STAT], nbTotalLines[CLog::LOG_ASSERT], + nbTotalLines[CLog::LOG_ERROR], pt->getNbTotalLines( CLog::LOG_UNKNOWN ) ); + nb2Sum += nbTotalLines[CLog::LOG_WARNING]; + } + } + targetLog->displayRawNL( "=> %u distinct, %u total WRN (%u pages)", nb1Sum, nb2Sum, nb1Sum / NB_LINES_PER_PAGE + 1 ); + + if ( displayDetailsPerService ) + { + for ( std::vector::const_iterator it=_Children.begin(); it!=_Children.end(); ++it ) + { + (*it)->report( targetLog, true ); + } + } +} + + +/* + * Get partial results (pageNum>=1) + */ +void CLogReportNode::reportPage( uint pageNum, NLMISC::CLog *targetLog ) +{ + if ( _Children.empty() ) + { + targetLog->displayRawNL( "[END OF LOG]" ); + return; + } + + uint beginIndex = pageNum * NB_LINES_PER_PAGE; + uint lineCounter = 0, prevLineCounter; + for ( std::vector::const_iterator it=_Children.begin(); it!=_Children.end(); ++it ) + { + CLogReportLeaf *pt = (*it); + prevLineCounter = lineCounter; + lineCounter += pt->getNbDistinctLines(); + if ( lineCounter >= beginIndex ) + { + uint remainingLines = pageNum - (lineCounter - beginIndex ); + pt->reportPart( beginIndex - prevLineCounter, remainingLines, targetLog ); // + while ( remainingLines != 0 ) + { + ++it; + if ( it == _Children.end() ) + { + targetLog->displayRawNL( "[END OF LOG]" ); + return; + } + pt = (*it); + remainingLines -= pt->reportPart( 0, remainingLines, targetLog ); + } + return; + } + } +} diff --git a/code/nelns/admin_service/Makefile.am b/code/nelns/admin_service/Makefile.am deleted file mode 100644 index 0513d968c..000000000 --- a/code/nelns/admin_service/Makefile.am +++ /dev/null @@ -1,24 +0,0 @@ -# -# $Id: Makefile.am,v 1.7 2002/11/13 16:59:55 coutelas Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = common.cfg \ - admin_service.cfg \ - admin_service.dsp \ - admin_service_8.vcproj \ - admin_service.vcproj - -sbin_PROGRAMS = admin_service - -admin_servicedir = ${pkgsysconfdir} -admin_service_DATA = admin_service.cfg common.cfg -admin_service_LDADD = @MYSQL_LDFLAGS@ - -AM_CXXFLAGS = -DNELNS_CONFIG="\"${pkgsysconfdir}\"" -DNELNS_STATE="\"${pkglocalstatedir}\"" -DNELNS_LOGS="\"${logdir}\"" @MYSQL_CFLAGS@ - -admin_service_SOURCES = admin_service.cpp connection_web.cpp - -# End of Makefile.am - diff --git a/code/nelns/autogen.sh b/code/nelns/autogen.sh deleted file mode 100755 index 426af8b39..000000000 --- a/code/nelns/autogen.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - - -WANT_AUTOMAKE="1.6" - -echo "Creating macros..." && \ -aclocal -I automacros/ && \ -echo "Creating library tools..." && \ -libtoolize --force && \ -echo "Creating header templates..." && \ -autoheader && \ -echo "Creating Makefile templates..." && \ -automake --gnu --add-missing && \ -echo "Creating 'configure'..." && \ -autoconf && \ -echo -e "\nRun: ./configure; make; make install\n" diff --git a/code/nelns/automacros/mysql.m4 b/code/nelns/automacros/mysql.m4 deleted file mode 100644 index 4d5adf3cd..000000000 --- a/code/nelns/automacros/mysql.m4 +++ /dev/null @@ -1,101 +0,0 @@ -AC_DEFUN([AX_LIB_MYSQL], -[ - AC_ARG_WITH([mysql], - AC_HELP_STRING([--with-mysql=@<:@ARG@:>@], - [use MySQL client library @<:@default=yes@:>@, optionally specify path to mysql_config] - ), - [ - if test "$withval" = "no"; then - want_mysql="no" - elif test "$withval" = "yes"; then - want_mysql="yes" - else - want_mysql="yes" - MYSQL_CONFIG="$withval" - fi - ], - [want_mysql="yes"] - ) - - MYSQL_CFLAGS="" - MYSQL_LDFLAGS="" - MYSQL_VERSION="" - - dnl - dnl Check MySQL libraries (libpq) - dnl - - if test "$want_mysql" = "yes"; then - - if test -z "$MYSQL_CONFIG" -o test; then - AC_PATH_PROG([MYSQL_CONFIG], [mysql_config], [no]) - fi - - if test "$MYSQL_CONFIG" != "no"; then - AC_MSG_CHECKING([for MySQL libraries]) - - MYSQL_CFLAGS="`$MYSQL_CONFIG --cflags`" - MYSQL_LDFLAGS="`$MYSQL_CONFIG --libs`" - - MYSQL_VERSION=`$MYSQL_CONFIG --version` - - AC_DEFINE([HAVE_MYSQL], [1], - [Define to 1 if MySQL libraries are available]) - - found_mysql="yes" - AC_MSG_RESULT([yes]) - else - found_mysql="no" - AC_MSG_RESULT([no]) - fi - fi - - dnl - dnl Check if required version of MySQL is available - dnl - - - mysql_version_req=ifelse([$1], [], [], [$1]) - - if test "$found_mysql" = "yes" -a -n "$mysql_version_req"; then - - AC_MSG_CHECKING([if MySQL version is >= $mysql_version_req]) - - dnl Decompose required version string of MySQL - dnl and calculate its number representation - mysql_version_req_major=`expr $mysql_version_req : '\([[0-9]]*\)'` - mysql_version_req_minor=`expr $mysql_version_req : '[[0-9]]*\.\([[0-9]]*\)'` - mysql_version_req_micro=`expr $mysql_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'` - if test "x$mysql_version_req_micro" = "x"; then - mysql_version_req_micro="0" - fi - - mysql_version_req_number=`expr $mysql_version_req_major \* 1000000 \ - \+ $mysql_version_req_minor \* 1000 \ - \+ $mysql_version_req_micro` - - dnl Decompose version string of installed MySQL - dnl and calculate its number representation - mysql_version_major=`expr $MYSQL_VERSION : '\([[0-9]]*\)'` - mysql_version_minor=`expr $MYSQL_VERSION : '[[0-9]]*\.\([[0-9]]*\)'` - mysql_version_micro=`expr $MYSQL_VERSION : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'` - if test "x$mysql_version_micro" = "x"; then - mysql_version_micro="0" - fi - - mysql_version_number=`expr $mysql_version_major \* 1000000 \ - \+ $mysql_version_minor \* 1000 \ - \+ $mysql_version_micro` - - mysql_version_check=`expr $mysql_version_number \>\= $mysql_version_req_number` - if test "$mysql_version_check" = "1"; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - fi - fi - - AC_SUBST([MYSQL_VERSION]) - AC_SUBST([MYSQL_CFLAGS]) - AC_SUBST([MYSQL_LDFLAGS]) -]) diff --git a/code/nelns/configure.ac b/code/nelns/configure.ac deleted file mode 100644 index ef7f65029..000000000 --- a/code/nelns/configure.ac +++ /dev/null @@ -1,186 +0,0 @@ -# ==================================================================== -# Configuration script for NeLNS -# ==================================================================== -# -# $Id: configure.ac,v 1.4 2005/01/07 18:29:56 distrib Exp $ -# - -# ==================================================================== -# Process this file with autoconf to produce a configure script. -# ==================================================================== - -# If you want to change the version, must must change AC_INIT -# *and* AC_SUBST(LIBTOOL_VERSION) - -AC_PREREQ(2.57) -AC_INIT([nelns],[0.5.0],[nel-all@nevrax.org]) - -AC_CANONICAL_TARGET - -AM_INIT_AUTOMAKE([tar-ustar]) - -AM_CONFIG_HEADER(config.h) - -AC_SUBST(LIBTOOL_VERSION, [0:5:0]) - -# ==================================================================== -# Checks for programs. -# ==================================================================== - - -AC_PROG_CXX -AC_PROG_CPP -AC_PROG_INSTALL -AC_PROG_LN_S -AC_PROG_MAKE_SET -AC_PROG_LIBTOOL -AM_PROG_LIBTOOL -AM_SANITY_CHECK - -AC_SYS_LARGEFILE - -AM_MAINTAINER_MODE - -# The following hack should ensure that configure doesn't add optimizing -# or debugging flags to CFLAGS or CXXFLAGS -CFLAGS="$CFLAGS " -CXXFLAGS="$CXXFLAGS " - -# Template needed to generate the config.h.in -#AH_TEMPLATE([NELNS_CONFIG],[Configuration files directory path]) -#AH_TEMPLATE([NELNS_LOGS],[Log files directory path]) -#AH_TEMPLATE([NELNS_STATE],[Local state files directory path]) -AH_TEMPLATE([HAVE_MYSQL],[Define to 1 if mysql was found]) - - -AX_LIB_MYSQL([3.23.40]) -#dnl AM_PATH_MYSQL(3.23.40,,AC_MSG_ERROR([MySQL 3.23.40 or higher must be installed])) - -AC_DEFINE(HAVE_MYSQL) - -CFLAGS="$CFLAGS $MYSQL_CFLAGS" -CXXFLAGS="$CXXFLAGS $MYSQL_CFLAGS" - -# prevent using GLIBC2.4 stuffs -CFLAGS="$CFLAGS -fno-stack-protector" -CXXFLAGS="$CXXFLAGS -fno-stack-protector" - -LIBS="$LIBS -lrt $MYSQL_LIBS" - - -# ==================================================================== -# Configure Settings -# ==================================================================== - -AC_LANG([C++]) - - -# ==================================================================== -# Debug/optimized compilation mode -# ==================================================================== - -AM_NEL_DEBUG - -# Set the gcc specific warning level -if test "X$CC" = "Xgcc"; -then - if test "$with_debug" != "no" - then - # - # When debugging variables are declared for the sole purpose of - # inspecting their content with a debugger. They are not used - # in the code itself and this is legitimate, hence the -Wno-unused - # - CXXFLAGS="$CXXFLAGS -Wall -Wno-multichar -Wno-unused" - else - CXXFLAGS="$CXXFLAGS -Wall -Wno-multichar" - fi -fi - -# ==================================================================== -# Checks for typedefs, structures, and compiler characteristics. -# ==================================================================== - -# Add the define _REENTRANT for a correct use of the threads -if test "X$CC" = "Xgcc"; -then - CXXFLAGS="$CXXFLAGS -D_REENTRANT" -fi - - -# ==================================================================== -# Checks for header files. -# ==================================================================== - -AC_HEADER_STDC([]) -AC_CHECK_HEADERS(fcntl.h unistd.h) - - -# ==================================================================== -# Checks for libraries. -# ==================================================================== - -AC_CHECK_LIB(crypt, crypt) - - -# ==================================================================== -# NeL - -# misc net 3d pacs sound ai georges -AM_PATH_NEL("yes", "yes", "no", "no", "no", "no", "no") - -# ==================================================================== -# Checks for library functions. -# ==================================================================== - -# ==================================================================== -# nelns configuration and logs file location -# ==================================================================== - -test "x$prefix" = xNONE && prefix=$ac_default_prefix - -AC_ARG_WITH(sysconfdir, - [ --with-sysconfdir[=DIR] - use DIR instead of the default sysconfdir/nelns], - [pkgsysconfdir=$withval], - [pkgsysconfdir='${sysconfdir}/nelns']) -AC_SUBST(pkgsysconfdir) - -#eval eval NELNS_CONFIG=\"$pkgsysconfdir/\" -#AC_DEFINE_UNQUOTED(NELNS_CONFIG, "$NELNS_CONFIG") - -AC_ARG_WITH(localstatedir, - [ --with-localstatedir[=DIR] - use DIR instead of the default localstatedir/game/nelns], - [pkglocalstatedir=$withval], - [pkglocalstatedir=${localstatedir}/game/nelns]) -AC_SUBST(pkglocalstatedir) - -#eval eval NELNS_STATE=\"$pkglocalstatedir/\" -#AC_DEFINE_UNQUOTED(NELNS_STATE, "$NELNS_STATE") - -AC_ARG_WITH(logdir, - [ --with-logdir[=DIR] - use DIR instead of the default localstatedir/log/nelns], - [logdir=$withval], - [logdir='${localstatedir}/log/nelns']) -AC_SUBST(logdir) - -#eval eval NELNS_LOGS=\"$logdir/\" -#AC_DEFINE_UNQUOTED(NELNS_LOGS, "$NELNS_LOGS") - -# ==================================================================== -# Output files to generate. -# ==================================================================== - -AC_CONFIG_FILES([Makefile \ - login_service/Makefile \ - naming_service/Makefile \ - admin_executor_service/Makefile \ - admin_service/Makefile \ - welcome_service/Makefile \ -]) -AC_OUTPUT - - -# End of configure.ac diff --git a/code/nelns/login_service/Makefile.am b/code/nelns/login_service/Makefile.am deleted file mode 100644 index 15a9eae6c..000000000 --- a/code/nelns/login_service/Makefile.am +++ /dev/null @@ -1,33 +0,0 @@ -# -# $Id: Makefile.am,v 1.8 2002-09-16 14:50:07 lecroart Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = login_service.cfg \ - login_service.dsp \ - login_service.vcproj \ - login_service_8.vcproj \ - common.cfg - -sbin_PROGRAMS = login_service - -login_servicedir = ${pkgsysconfdir} -login_service_DATA = login_service.cfg common.cfg -login_service_LDADD = @MYSQL_LDFLAGS@ - -AM_CXXFLAGS = -DNELNS_CONFIG="\"${pkgsysconfdir}\"" -DNELNS_STATE="\"${pkglocalstatedir}\"" -DNELNS_LOGS="\"${logdir}\"" @MYSQL_CFLAGS@ - -login_service_SOURCES = mysql_helper.cpp \ - mysql_helper.h \ - connection_client.cpp \ - connection_client.h \ - connection_web.cpp \ - connection_web.h \ - connection_ws.cpp \ - connection_ws.h \ - login_service.cpp \ - login_service.h - -# End of Makefile.am - diff --git a/code/nelns/login_service/mysql_helper.h b/code/nelns/login_service/mysql_helper.h index cc81f4647..7f6893b4a 100644 --- a/code/nelns/login_service/mysql_helper.h +++ b/code/nelns/login_service/mysql_helper.h @@ -70,7 +70,7 @@ public: private: //we don't want user to do a copy - CMysqlResult(const CMysqlResult &mysqlResult){}; + CMysqlResult(const CMysqlResult &mysqlResult){} MYSQL_RES *Result; }; diff --git a/code/nelns/login_system/nel_launcher_qt/CMakeLists.txt b/code/nelns/login_system/nel_launcher_qt/CMakeLists.txt index bf2096b9a..3bd503eef 100644 --- a/code/nelns/login_system/nel_launcher_qt/CMakeLists.txt +++ b/code/nelns/login_system/nel_launcher_qt/CMakeLists.txt @@ -1,37 +1,41 @@ -INCLUDE_DIRECTORIES( ${CMAKE_BINARY_DIR}/login_system/nel_launcher_qt/ ) -INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/login_system/nel_launcher_qt/ ) -INCLUDE( ${QT_USE_FILE} ) - -FILE(GLOB NEL_LAUNCHER_SRC *.cpp) -SET(NEL_LAUNCHER_HDR nel_launcher_dlg.h) -SET(NEL_LAUNCHER_UIS nel_launcher_dlg.ui) -SET(NEL_LAUNCHER_RCS ) - -SET( QT_USE_QT3SUPPORT TRUE) -SET( QT_USE_QTXML TRUE) - -QT4_ADD_RESOURCES( NEL_LAUNCHER_RC_SRCS ${NEL_LAUNCHER_RCS} ) -QT4_WRAP_UI( NEL_LAUNCHER_UI_HDRS ${NEL_LAUNCHER_UIS} ) -QT4_WRAP_CPP( NEL_LAUNCHER_MOC_SRCS ${NEL_LAUNCHER_HDR}) - -ADD_EXECUTABLE(nel_launcher_qt WIN32 ${NEL_LAUNCHER_SRC} ${NEL_LAUNCHER_MOC_SRCS} ${NEL_LAUNCHER_RC_SRCS} ${NEL_LAUNCHER_UI_HDRS}) - -INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR} ${QT_INCLUDES}) - -TARGET_LINK_LIBRARIES(nel_launcher_qt - ${LIBXML2_LIBRARIES} - ${QT_LIBRARIES} - nelmisc - nelnet) - -NL_DEFAULT_PROPS(nel_launcher_qt "NelNS, Launcher: NeL Launcher Qt") -NL_ADD_RUNTIME_FLAGS(nel_launcher_qt) - -ADD_DEFINITIONS(${LIBXML2_DEFINITIONS} ${QT_DEFINITIONS}) - -INSTALL(TARGETS nel_launcher_qt RUNTIME DESTINATION bin COMPONENT launcher) -IF(WIN32) - INSTALL(FILES nel_launcher.cfg DESTINATION bin COMPONENT launcher) -ELSE(WIN32) - INSTALL(FILES nel_launcher.cfg DESTINATION etc/nel/nelns COMPONENT launcher) -ENDIF(WIN32) \ No newline at end of file +INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} + ${LIBXML2_INCLUDE_DIR} + ${QT_INCLUDES}) + +INCLUDE( ${QT_USE_FILE} ) + +FILE(GLOB NEL_LAUNCHER_SRC *.cpp) +SET(NEL_LAUNCHER_HDR nel_launcher_dlg.h) +SET(NEL_LAUNCHER_UIS nel_launcher_dlg.ui) +SET(NEL_LAUNCHER_RCS ) + +SET( QT_USE_QT3SUPPORT TRUE) +SET( QT_USE_QTXML TRUE) + +QT4_ADD_RESOURCES( NEL_LAUNCHER_RC_SRCS ${NEL_LAUNCHER_RCS} ) +QT4_WRAP_UI( NEL_LAUNCHER_UI_HDRS ${NEL_LAUNCHER_UIS} ) +QT4_WRAP_CPP( NEL_LAUNCHER_MOC_SRCS ${NEL_LAUNCHER_HDR}) + +ADD_EXECUTABLE(nel_launcher_qt WIN32 ${NEL_LAUNCHER_SRC} ${NEL_LAUNCHER_MOC_SRCS} ${NEL_LAUNCHER_RC_SRCS} ${NEL_LAUNCHER_UI_HDRS}) + +INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR} ${QT_INCLUDES}) + +TARGET_LINK_LIBRARIES(nel_launcher_qt + ${LIBXML2_LIBRARIES} + ${QT_LIBRARIES} + ${QT_QTMAIN_LIBRARY} + nelmisc + nelnet) + +NL_DEFAULT_PROPS(nel_launcher_qt "NelNS, Launcher: NeL Launcher Qt") +NL_ADD_RUNTIME_FLAGS(nel_launcher_qt) + +ADD_DEFINITIONS(${LIBXML2_DEFINITIONS} ${QT_DEFINITIONS}) + +INSTALL(TARGETS nel_launcher_qt RUNTIME DESTINATION bin COMPONENT launcher) +IF(WIN32) + INSTALL(FILES nel_launcher.cfg DESTINATION bin COMPONENT launcher) +ELSE(WIN32) + INSTALL(FILES nel_launcher.cfg DESTINATION etc/nel/nelns COMPONENT launcher) +ENDIF(WIN32) diff --git a/code/nelns/login_system/nel_launcher_windows_ext/BarTabsWnd.h b/code/nelns/login_system/nel_launcher_windows_ext/BarTabsWnd.h index eefb93653..2437ae854 100644 --- a/code/nelns/login_system/nel_launcher_windows_ext/BarTabsWnd.h +++ b/code/nelns/login_system/nel_launcher_windows_ext/BarTabsWnd.h @@ -14,9 +14,9 @@ class CTabsObserver { public: - CTabsObserver() {}; + CTabsObserver() {} - virtual void OnTab(int iTab) {}; + virtual void OnTab(int iTab) {} }; class CBarTabsWnd : public CWnd diff --git a/code/nelns/naming_service/Makefile.am b/code/nelns/naming_service/Makefile.am deleted file mode 100644 index 95e510f7f..000000000 --- a/code/nelns/naming_service/Makefile.am +++ /dev/null @@ -1,22 +0,0 @@ -# -# $Id: Makefile.am,v 1.5 2002/06/12 10:22:28 lecroart Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = naming_service.cfg \ - naming_service.dsp \ - naming_service.vcproj \ - naming_service_8.vcproj \ - common.cfg - -sbin_PROGRAMS = naming_service - -naming_servicedir = ${pkgsysconfdir} -naming_service_DATA = naming_service.cfg common.cfg - -AM_CXXFLAGS = -DNELNS_CONFIG="\"${pkgsysconfdir}\"" -DNELNS_STATE="\"${pkglocalstatedir}\"" -DNELNS_LOGS="\"${logdir}\"" - -naming_service_SOURCES = naming_service.cpp - -# End of Makefile.am diff --git a/code/nelns/welcome_service/Makefile.am b/code/nelns/welcome_service/Makefile.am deleted file mode 100644 index 35b7d6eb5..000000000 --- a/code/nelns/welcome_service/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -# -# $Id: Makefile.am,v 1.7 2006/05/31 12:14:16 boucher Exp $ -# - -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = welcome_service.cfg \ - welcome_service.dsp \ - welcome_service.vcproj \ - welcome_service_8.vcproj \ - common.cfg - -sbin_PROGRAMS = welcome_service - -welcome_servicedir = ${pkgsysconfdir} -welcome_service_DATA = welcome_service.cfg common.cfg - -AM_CXXFLAGS = -DNELNS_CONFIG="\"${pkgsysconfdir}\"" -DNELNS_STATE="\"${pkglocalstatedir}\"" -DNELNS_LOGS="\"${logdir}\"" - -welcome_service_SOURCES = welcome_service.cpp \ - welcome_service_itf.cpp - -# End of Makefile.am diff --git a/code/revision.h.in b/code/revision.h.in new file mode 100644 index 000000000..6c5e9b8b1 --- /dev/null +++ b/code/revision.h.in @@ -0,0 +1,7 @@ +#ifndef REVISION_H +#define REVISION_H + +#cmakedefine REVISION "${REVISION}" +#cmakedefine BUILD_DATE "${BUILD_DATE}" + +#endif diff --git a/code/ryzom/CMakeLists.txt b/code/ryzom/CMakeLists.txt index 4202738c1..eb3d1c642 100644 --- a/code/ryzom/CMakeLists.txt +++ b/code/ryzom/CMakeLists.txt @@ -1,18 +1,7 @@ #----------------------------------------------------------------------------- #Platform specifics -IF(WITH_LUA51) - FIND_PACKAGE(Lua51 REQUIRED) -ELSE(WITH_LUA51) - FIND_PACKAGE(Lua50 REQUIRED) -ENDIF(WITH_LUA51) -FIND_PACKAGE(Luabind REQUIRED) -FIND_PACKAGE(CURL REQUIRED) -FIND_PACKAGE(Libwww REQUIRED) FIND_PACKAGE(ZLIB) -IF(NOT WIN32 AND NOT APPLE) - FIND_PACKAGE(X11) -ENDIF(NOT WIN32 AND NOT APPLE) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/common/src ) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/common ) @@ -30,6 +19,15 @@ ENDIF(WITH_STATIC) ADD_SUBDIRECTORY(common) IF(WITH_RYZOM_CLIENT) + IF(WITH_LUA51) + FIND_PACKAGE(Lua51 REQUIRED) + ELSE(WITH_LUA51) + FIND_PACKAGE(Lua50 REQUIRED) + ENDIF(WITH_LUA51) + FIND_PACKAGE(Luabind REQUIRED) + FIND_PACKAGE(CURL REQUIRED) + FIND_PACKAGE(Libwww REQUIRED) + ADD_SUBDIRECTORY(client) ENDIF(WITH_RYZOM_CLIENT) diff --git a/code/ryzom/Makefile b/code/ryzom/Makefile deleted file mode 100644 index 2a1850c35..000000000 --- a/code/ryzom/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -MAKE_NIGHT_ARGS=-j2 -MAKE_ALL_ARGS=-j2 -CXX=g++ -CC=g++ -BIN_DIR=$(RYZOM_PATH)/tools/scripts/linux - -night: - +make $(MAKE_NIGHT_ARGS) -k -C common night CXX=$(CXX) - +make $(MAKE_NIGHT_ARGS) -k -C server night CXX=$(CXX) - -all: - +make $(MAKE_ALL_ARGS) -C common all - +make $(MAKE_ALL_ARGS) -C server all - -mono: - +make -C common all - +make -C server all - -clean: - +make -C common clean - +make -C server clean - -distclean: - +make -C common distclean - +make -C server distclean - -cleansheets: - +make -C common cleansheets - +make -C server cleansheets - -update: - +make -C common update - +make -C server update - -touch: - +make -C common touch - +make -C server touch diff --git a/code/ryzom/Rules.mk b/code/ryzom/Rules.mk deleted file mode 100644 index 67bc3bc42..000000000 --- a/code/ryzom/Rules.mk +++ /dev/null @@ -1,64 +0,0 @@ -############################################################################# -# A few basic default rules and intrinsic rules - -# Load objects dependencies -ifeq (Dependencies.mk,$(wildcard Dependencies.mk)) -include Dependencies.mk -check-deps: - @echo - @echo Dependencies found [OK] - @echo -else -check-deps: - @echo - @echo "No dependencies found [ERROR]" - @echo "You should try 'make update' first" - @echo - @exit 1 -endif - -# Start off by over-riding the default build rules with our own intrinsics -.SUFFIXES: -.SUFFIXES: .cpp .o -.cpp.o: - $(CXX) -c $(CXXFLAGS) $< -o $@ - -# remove object files and core (if any) -clean: - find . -name "core*" -exec $(RM) {} \; - find . -name "*.o" -exec $(RM) {} \; - find . -name "*~" -exec $(RM) {} \; - find . -name "Dependencies.mk" -exec $(RM) {} \; - find . -name "Objects.mk" -exec $(RM) {} \; - -cleansheets: - find . -name "*.packed_sheets" -exec $(RM) {} \; - -# remove object files, core dump, and executable (if any) -distclean: - $(MAKE) clean - $(RM) $(TARGETS) - $(RM) $(TARGETS)_debug - -# make the thing again from scratch -again: - $(MAKE) distclean - $(MAKE) $(TARGETS) - -#UPDATE_OBJS=`cat $(DSP_TARGET) | grep SOURCE | sed -e 's/\r$$//' | grep "\.cpp$$" | cut -d\\\\ -f3- | tr '\n' ' ' | sed -e 's/=/..\\\\/g' | tr '\n' ' ' | sed -e 's/\\\\/\\//g' | sed -e 's/\.cpp /\.o /g'` - -#UPDATE_SRCS=`cat $(DSP_TARGET) | grep SOURCE | sed -e 's/\r$$//' | grep "\.cpp$$" | cut -d\\\\ -f3- | tr '\n' ' ' | sed -e 's/=/..\\\\/g' | tr '\n' ' ' | sed -e 's/\\\\/\\//g'` - -UPDATE_OBJS=`cat $(DSP_TARGET) | grep RelativePath | sed -e 's/\\"\r$$//' | grep "\.cpp$$" | cut -d\\\\ -f2- | tr '\n' ' ' | sed -e 's/\\\\/\\//g' | sed -e 's/\.cpp /\.o /g'` -UPDATE_SRCS=`cat $(DSP_TARGET) | grep RelativePath | sed -e 's/\\"\r$$//' | grep "\.cpp$$" | cut -d\\\\ -f2- | tr '\n' ' ' | sed -e 's/\\\\/\\//g'` - -dep: update - -update: -# ../gen_compile_flags.sh > RyzomCompilerFlags.mk - $(RYZOM_PATH)/gen_deps.sh $(CXX) $(CXXFLAGS) -- $(UPDATE_SRCS) > Dependencies.mk - echo "OBJS=$(UPDATE_OBJS)" > Objects.mk - -touch: - $(RM) $(TARGETS) - $(RM) $(TARGETS)_debug diff --git a/code/ryzom/Variables.mk b/code/ryzom/Variables.mk deleted file mode 100644 index a952922f0..000000000 --- a/code/ryzom/Variables.mk +++ /dev/null @@ -1,33 +0,0 @@ -############################################################################# -# Setting up the global compiler settings... - -# The names of the executables -CXX = c++ -RM = rm -f -MAKE = make - -DBG = off - -ifeq (RyzomCompilerFlags.mk,$(wildcard RyzomCompilerFlags.mk)) -include RyzomCompilerFlags.mk -endif - -FLAGS_CMN = -g -pipe -fno-stack-protector -fno-strict-aliasing -Wall -D_REENTRANT -D_GNU_SOURCE -DFINAL_VERSION=1 -LD_FLAGS_CMN = -rdynamic - -FLAGS_DBG_on = -O0 -finline-functions -DNL_DEBUG -FLAGS_DBG_off = -O3 -funroll-loops -DNL_RELEASE -DIR_DBG_on = debug -DIR_DBG_off = release - -PACK_SHEETS_FLAGS = -A$RYZOM_PATH/server -L$RYZOM_PATH/server -C$RYZOM_PATH//server/sheet_pack_cfg -Q --nons - - -NEL_PATH = $(RYZOM_PATH)/../../code/install/$(DIR_DBG_$(DBG)) - -NEL_INCLUDE = $(RYZOM_PATH)/../../code/nel/include -RYZOM_COMMON_SRC = $(RYZOM_PATH)/common/src - -ifeq (Objects.mk,$(wildcard Objects.mk)) -include Objects.mk -endif diff --git a/code/ryzom/client/CMakeLists.txt b/code/ryzom/client/CMakeLists.txt index db2ffce2a..36090be7b 100644 --- a/code/ryzom/client/CMakeLists.txt +++ b/code/ryzom/client/CMakeLists.txt @@ -1,6 +1,6 @@ ADD_SUBDIRECTORY(src) -ADD_SUBDIRECTORY(data) -ADD_SUBDIRECTORY(patcher) +#ADD_SUBDIRECTORY(data) +#ADD_SUBDIRECTORY(patcher) IF(UNIX AND NOT APPLE) ADD_SUBDIRECTORY(unix) diff --git a/code/ryzom/client/Makefile b/code/ryzom/client/Makefile deleted file mode 100644 index 11e58485a..000000000 --- a/code/ryzom/client/Makefile +++ /dev/null @@ -1,18 +0,0 @@ - -all: - +make $(MAKE_ALL_ARGS) -C src all - -mono: - +make -C src all - -clean: - +make -C src clean - -cleansheets: - +make -C src cleansheets - -update: - +make -C src update - -touch: - +make -C src touch diff --git a/code/ryzom/client/client_default.cfg b/code/ryzom/client/client_default.cfg index c29ca9b93..997699ca8 100644 --- a/code/ryzom/client/client_default.cfg +++ b/code/ryzom/client/client_default.cfg @@ -80,6 +80,9 @@ XMLOutGameInterfaceFiles = { "out_v2_keys.xml", }; +TexturesInterface = "texture_interfaces_v3"; +TexturesInterfaceDXTC = "texture_interfaces_dxtc"; + // The ligo primitive class file LigoPrimitiveClass = "world_editor_classes.xml"; @@ -351,8 +354,8 @@ SystemInfoColors = // NEW System Info Categories "SYS", "255 255 255 255 normal", // Default system messages -"BC", "255 255 255 255 center", // Broadcast messages -"TAGBC", "255 255 255 255 center", // Taged broadcast messages : color should remain white as some word are tagged +"BC", "255 255 255 255 centeraround", // Broadcast messages +"TAGBC", "255 255 255 255 centeraround", // Taged broadcast messages : color should remain white as some word are tagged "XP", "255 255 64 255 over", // XP Gain "SP", "255 255 64 255 over", // SP Gain "TTL", "255 255 64 255 over", // Title @@ -440,23 +443,24 @@ R2EDReloadFiles = { XMLInterfaceFiles = { "config.xml", "widgets.xml", + "webig_widgets.xml", "player.xml", "inventory.xml", "interaction.xml", - "phrase.xml", + "phrase.xml", "harvest.xml", "macros.xml", "info_player.xml", "outpost.xml", "guild.xml", "taskbar.xml", - "game_config.xml", + "game_config.xml", "game_context_menu.xml", "player_trade.xml", "bot_chat_v4.xml", "compass.xml", "map.xml", - "hierarchy.xml", + "hierarchy.xml", "reset.xml", "actions.xml", "help.xml", @@ -556,6 +560,15 @@ HelpPages = "de=http://forums.ryzom.com/forum/showthread.php?t=29131" }; +WebIgMainDomain = "atys.ryzom.com"; + +WebIgTrustedDomains = +{ + "atys.ryzom.com" +}; + +PatchletUrl = "http://atys.ryzom.com/start/app_patchlet.php?patch=preload"; + SelectedSlot = 0; BuildName = "RELEASE_HEAD"; diff --git a/code/ryzom/client/client_default.cfg.in b/code/ryzom/client/client_default.cfg.in index dad9e3ccb..41c3dd1de 100644 --- a/code/ryzom/client/client_default.cfg.in +++ b/code/ryzom/client/client_default.cfg.in @@ -80,6 +80,9 @@ XMLOutGameInterfaceFiles = { "out_v2_keys.xml", }; +TexturesInterface = "texture_interfaces_v3"; +TexturesInterfaceDXTC = "texture_interfaces_dxtc"; + // The ligo primitive class file LigoPrimitiveClass = "world_editor_classes.xml"; @@ -239,14 +242,14 @@ SkinNbMaxPoly_ps1 = 70000; SkinNbMaxPoly_ps2 = 100000; SkinNbMaxPoly_ps3 = 200000; -NbMaxSkeletonNotCLod = 50; +NbMaxSkeletonNotCLod = 125; NbMaxSkeletonNotCLod_min = 5; -NbMaxSkeletonNotCLod_max = 100; +NbMaxSkeletonNotCLod_max = 255; NbMaxSkeletonNotCLod_step = 5; NbMaxSkeletonNotCLod_ps0 = 10; -NbMaxSkeletonNotCLod_ps1 = 25; -NbMaxSkeletonNotCLod_ps2 = 50; -NbMaxSkeletonNotCLod_ps3 = 100; +NbMaxSkeletonNotCLod_ps1 = 50; +NbMaxSkeletonNotCLod_ps2 = 125; +NbMaxSkeletonNotCLod_ps3 = 255; CharacterFarClip = 200.0; CharacterFarClip_min = 50.0; @@ -352,8 +355,8 @@ SystemInfoColors = // NEW System Info Categories "SYS", "255 255 255 255 normal", // Default system messages -"BC", "255 255 255 255 center", // Broadcast messages -"TAGBC", "255 255 255 255 center", // Taged broadcast messages : color should remain white as some word are tagged +"BC", "255 255 255 255 centeraround", // Broadcast messages +"TAGBC", "255 255 255 255 centeraround", // Taged broadcast messages : color should remain white as some word are tagged "XP", "255 255 64 255 over", // XP Gain "SP", "255 255 64 255 over", // SP Gain "TTL", "255 255 64 255 over", // Title @@ -386,21 +389,21 @@ SystemInfoColors = }; PrintfCommands = { - "52", "15", "55 55 0 255", "28", "uiChapterIV", "624", + "52", "15", "55 55 0 255", "28", "uiChapterV", "624", "428", "0 0 0 255", "18", "", "624", "378", "0 0 0 255", "14", "", "644", "278", "0 0 0 255", "18", "", "52", "17", "255 255 255 255", "28", - "uiChapterIV", "622", "430", "255 255 255 255", "18", "", + "uiChapterV", "622", "430", "255 255 255 255", "18", "", "622", "380", "255 255 255 255", "14", "", "642", "280", "255 255 255 255", "18", "" }; PrintfCommandsFreeTrial = { - "52", "15", "55 55 0 255", "28", "uiChapterIV", "624", + "52", "15", "55 55 0 255", "28", "uiChapterV", "624", "428", "0 0 0 255", "18", "", "624", "378", "0 0 0 255", "14", "", "644", "278", "0 0 0 255", "18", "", "52", "17", "255 255 255 255", "28", - "uiChapterIV", "622", "430", "255 255 255 255", "18", "", + "uiChapterV", "622", "430", "255 255 255 255", "18", "", "622", "380", "255 255 255 255", "14", "", "642", "280", "255 255 255 255", "18", "" }; @@ -441,23 +444,24 @@ R2EDReloadFiles = { XMLInterfaceFiles = { "config.xml", "widgets.xml", + "webig_widgets.xml", "player.xml", "inventory.xml", "interaction.xml", - "phrase.xml", + "phrase.xml", "harvest.xml", "macros.xml", "info_player.xml", "outpost.xml", "guild.xml", "taskbar.xml", - "game_config.xml", + "game_config.xml", "game_context_menu.xml", "player_trade.xml", "bot_chat_v4.xml", "compass.xml", "map.xml", - "hierarchy.xml", + "hierarchy.xml", "reset.xml", "actions.xml", "help.xml", @@ -557,6 +561,15 @@ HelpPages = "de=http://forums.ryzom.com/forum/showthread.php?t=29131" }; +WebIgMainDomain = "atys.ryzom.com"; + +WebIgTrustedDomains = +{ + "atys.ryzom.com" +}; + +PatchletUrl = "http://atys.ryzom.com/start/app_patchlet.php?patch=preload"; + SelectedSlot = 0; BuildName = "RELEASE_HEAD"; diff --git a/code/ryzom/client/data/gamedev/adds/interfaces/new_texture_interfaces_dxtc.tga b/code/ryzom/client/data/gamedev/adds/interfaces/new_texture_interfaces_dxtc.tga index bbeeab27b..91e87e2e7 100644 Binary files a/code/ryzom/client/data/gamedev/adds/interfaces/new_texture_interfaces_dxtc.tga and b/code/ryzom/client/data/gamedev/adds/interfaces/new_texture_interfaces_dxtc.tga differ diff --git a/code/ryzom/client/data/gamedev/adds/interfaces/new_texture_interfaces_dxtc.txt b/code/ryzom/client/data/gamedev/adds/interfaces/new_texture_interfaces_dxtc.txt index ec1afb449..f35989e33 100644 --- a/code/ryzom/client/data/gamedev/adds/interfaces/new_texture_interfaces_dxtc.txt +++ b/code/ryzom/client/data/gamedev/adds/interfaces/new_texture_interfaces_dxtc.txt @@ -18,305 +18,305 @@ BK_goo.tga 0.156250000000 0.078125000000 0.195312500000 0.117187500000 bk_guild.tga 0.195312500000 0.078125000000 0.234375000000 0.117187500000 bk_horde.tga 0.000000000000 0.117187500000 0.039062500000 0.156250000000 bk_kami.tga 0.039062500000 0.117187500000 0.078125000000 0.156250000000 -bk_karavan.tga 0.078125000000 0.117187500000 0.117187500000 0.156250000000 -BK_matis.tga 0.117187500000 0.117187500000 0.156250000000 0.156250000000 -bk_mission.tga 0.156250000000 0.117187500000 0.195312500000 0.156250000000 -bk_mission2.tga 0.195312500000 0.117187500000 0.234375000000 0.156250000000 -BK_outpost.tga 0.000000000000 0.156250000000 0.039062500000 0.195312500000 -BK_primes.tga 0.039062500000 0.156250000000 0.078125000000 0.195312500000 -bk_service.tga 0.078125000000 0.156250000000 0.117187500000 0.195312500000 -bk_training.tga 0.117187500000 0.156250000000 0.156250000000 0.195312500000 -BK_tryker.tga 0.156250000000 0.156250000000 0.195312500000 0.195312500000 -BK_zorai.tga 0.195312500000 0.156250000000 0.234375000000 0.195312500000 -charge.tga 0.000000000000 0.195312500000 0.039062500000 0.234375000000 -clef.tga 0.039062500000 0.195312500000 0.078125000000 0.234375000000 -conso_branche.tga 0.078125000000 0.195312500000 0.117187500000 0.234375000000 -conso_branche_mask.tga 0.117187500000 0.195312500000 0.156250000000 0.234375000000 -conso_fleur.tga 0.156250000000 0.195312500000 0.195312500000 0.234375000000 -conso_fleur_mask.tga 0.195312500000 0.195312500000 0.234375000000 0.234375000000 -conso_grappe.tga 0.242187500000 0.000000000000 0.281250000000 0.039062500000 -conso_grappe_mask.tga 0.281250000000 0.000000000000 0.320312500000 0.039062500000 -conso_nectar.tga 0.320312500000 0.000000000000 0.359375000000 0.039062500000 -conso_nectar_mask.tga 0.359375000000 0.000000000000 0.398437500000 0.039062500000 -construction.tga 0.398437500000 0.000000000000 0.437500000000 0.039062500000 -cristal_ammo.tga 0.437500000000 0.000000000000 0.476562500000 0.039062500000 -cristal_spell.tga 0.238281250000 0.039062500000 0.277343750000 0.078125000000 -ge_mission_outpost_townhall.tga 0.277343750000 0.039062500000 0.316406250000 0.078125000000 -ico_amande.tga 0.316406250000 0.039062500000 0.355468750000 0.078125000000 -ico_cataliseur_xp.tga 0.355468750000 0.039062500000 0.394531250000 0.078125000000 -ico_consommable_over.tga 0.394531250000 0.039062500000 0.433593750000 0.078125000000 -ico_fleur_carac_1.tga 0.433593750000 0.039062500000 0.472656250000 0.078125000000 -ico_fleur_carac_1_mask.tga 0.234375000000 0.078125000000 0.273437500000 0.117187500000 -ico_fleur_carac_2.tga 0.273437500000 0.078125000000 0.312500000000 0.117187500000 -ico_fleur_carac_2_mask.tga 0.312500000000 0.078125000000 0.351562500000 0.117187500000 -ico_fleur_carac_3.tga 0.351562500000 0.078125000000 0.390625000000 0.117187500000 -ico_fleur_carac_3_mask.tga 0.390625000000 0.078125000000 0.429687500000 0.117187500000 -ico_foreuse.tga 0.429687500000 0.078125000000 0.468750000000 0.117187500000 -ico_haircolor.tga 0.234375000000 0.117187500000 0.273437500000 0.156250000000 -ico_haircut.tga 0.273437500000 0.117187500000 0.312500000000 0.156250000000 -ico_mission_art_fyros.tga 0.312500000000 0.117187500000 0.351562500000 0.156250000000 -ico_mission_art_matis.tga 0.351562500000 0.117187500000 0.390625000000 0.156250000000 -ico_mission_art_tryker.tga 0.390625000000 0.117187500000 0.429687500000 0.156250000000 -ico_mission_art_zorai.tga 0.429687500000 0.117187500000 0.468750000000 0.156250000000 -ico_mission_barrel.tga 0.234375000000 0.156250000000 0.273437500000 0.195312500000 -ico_mission_bottle.tga 0.273437500000 0.156250000000 0.312500000000 0.195312500000 -ico_mission_casket.tga 0.312500000000 0.156250000000 0.351562500000 0.195312500000 -ico_mission_medicine.tga 0.351562500000 0.156250000000 0.390625000000 0.195312500000 -ico_mission_message.tga 0.390625000000 0.156250000000 0.429687500000 0.195312500000 -ico_mission_package.tga 0.429687500000 0.156250000000 0.468750000000 0.195312500000 -ico_mission_pot.tga 0.234375000000 0.195312500000 0.273437500000 0.234375000000 -ico_mission_purse.tga 0.273437500000 0.195312500000 0.312500000000 0.234375000000 -ico_noix.tga 0.312500000000 0.195312500000 0.351562500000 0.234375000000 -ico_racine.tga 0.351562500000 0.195312500000 0.390625000000 0.234375000000 -ico_spores.tga 0.390625000000 0.195312500000 0.429687500000 0.234375000000 -ico_task_craft.tga 0.429687500000 0.195312500000 0.468750000000 0.234375000000 -ico_task_done.tga 0.000000000000 0.234375000000 0.039062500000 0.273437500000 -ico_task_failed.tga 0.039062500000 0.234375000000 0.078125000000 0.273437500000 -ico_task_fight.tga 0.078125000000 0.234375000000 0.117187500000 0.273437500000 -ico_task_forage.tga 0.117187500000 0.234375000000 0.156250000000 0.273437500000 -ico_task_generic.tga 0.156250000000 0.234375000000 0.195312500000 0.273437500000 -ico_task_generic_quart.tga 0.195312500000 0.234375000000 0.234375000000 0.273437500000 -ico_task_guild.tga 0.234375000000 0.234375000000 0.273437500000 0.273437500000 -ico_task_rite.tga 0.273437500000 0.234375000000 0.312500000000 0.273437500000 -ico_task_travel.tga 0.312500000000 0.234375000000 0.351562500000 0.273437500000 -ico_tatoo.tga 0.351562500000 0.234375000000 0.390625000000 0.273437500000 -ico_tourbe.tga 0.390625000000 0.234375000000 0.429687500000 0.273437500000 -improved_tool.tga 0.429687500000 0.234375000000 0.468750000000 0.273437500000 -item_default.tga 0.000000000000 0.273437500000 0.039062500000 0.312500000000 -item_plan_over.tga 0.039062500000 0.273437500000 0.078125000000 0.312500000000 -lucky_flower.tga 0.078125000000 0.273437500000 0.117187500000 0.312500000000 -mektoub_pack.tga 0.117187500000 0.273437500000 0.156250000000 0.312500000000 -mektoub_steed.tga 0.156250000000 0.273437500000 0.195312500000 0.312500000000 -mg_glove.tga 0.195312500000 0.273437500000 0.234375000000 0.312500000000 -mission_icon_0.tga 0.234375000000 0.273437500000 0.273437500000 0.312500000000 -mission_icon_1.tga 0.273437500000 0.273437500000 0.312500000000 0.312500000000 -mission_icon_2.tga 0.312500000000 0.273437500000 0.351562500000 0.312500000000 -mission_icon_3.tga 0.351562500000 0.273437500000 0.390625000000 0.312500000000 -mp_amber.tga 0.390625000000 0.273437500000 0.429687500000 0.312500000000 -mp_bark.tga 0.429687500000 0.273437500000 0.468750000000 0.312500000000 -mp_batiment_brique.tga 0.000000000000 0.312500000000 0.039062500000 0.351562500000 -mp_batiment_colonne.tga 0.039062500000 0.312500000000 0.078125000000 0.351562500000 -mp_batiment_colonne_justice.tga 0.078125000000 0.312500000000 0.117187500000 0.351562500000 -mp_batiment_comble.tga 0.117187500000 0.312500000000 0.156250000000 0.351562500000 -mp_batiment_noyau_maduk.tga 0.156250000000 0.312500000000 0.195312500000 0.351562500000 -mp_batiment_ornement.tga 0.195312500000 0.312500000000 0.234375000000 0.351562500000 -mp_batiment_revetement.tga 0.234375000000 0.312500000000 0.273437500000 0.351562500000 -mp_batiment_socle.tga 0.273437500000 0.312500000000 0.312500000000 0.351562500000 -mp_batiment_statue.tga 0.312500000000 0.312500000000 0.351562500000 0.351562500000 -mp_beak.tga 0.351562500000 0.312500000000 0.390625000000 0.351562500000 -mp_blood.tga 0.390625000000 0.312500000000 0.429687500000 0.351562500000 -mp_bone.tga 0.429687500000 0.312500000000 0.468750000000 0.351562500000 -mp_bud.tga 0.000000000000 0.351562500000 0.039062500000 0.390625000000 -mp_buterfly_blue.tga 0.039062500000 0.351562500000 0.078125000000 0.390625000000 -mp_buterfly_cocoon.tga 0.078125000000 0.351562500000 0.117187500000 0.390625000000 -mp_cereal.tga 0.117187500000 0.351562500000 0.156250000000 0.390625000000 -mp_claw.tga 0.156250000000 0.351562500000 0.195312500000 0.390625000000 -mp_dandelion.tga 0.195312500000 0.351562500000 0.234375000000 0.390625000000 -mp_dust.tga 0.234375000000 0.351562500000 0.273437500000 0.390625000000 -mp_egg.tga 0.273437500000 0.351562500000 0.312500000000 0.390625000000 -mp_eyes.tga 0.312500000000 0.351562500000 0.351562500000 0.390625000000 -mp_fang.tga 0.351562500000 0.351562500000 0.390625000000 0.390625000000 -mp_fiber.tga 0.390625000000 0.351562500000 0.429687500000 0.390625000000 -mp_filament.tga 0.429687500000 0.351562500000 0.468750000000 0.390625000000 -mp_firefly_abdomen.tga 0.000000000000 0.390625000000 0.039062500000 0.429687500000 -mp_fish_scale.tga 0.039062500000 0.390625000000 0.078125000000 0.429687500000 -mp_flowers.tga 0.078125000000 0.390625000000 0.117187500000 0.429687500000 -mp_fresh_loose_soil.tga 0.117187500000 0.390625000000 0.156250000000 0.429687500000 -mp_fruit.tga 0.156250000000 0.390625000000 0.195312500000 0.429687500000 -mp_generic.tga 0.195312500000 0.390625000000 0.234375000000 0.429687500000 -mp_generic_colorize.tga 0.234375000000 0.390625000000 0.273437500000 0.429687500000 -mp_gomme.tga 0.273437500000 0.390625000000 0.312500000000 0.429687500000 -mp_goo_residue.tga 0.312500000000 0.390625000000 0.351562500000 0.429687500000 -mp_hairs.tga 0.351562500000 0.390625000000 0.390625000000 0.429687500000 -mp_hoof.tga 0.390625000000 0.390625000000 0.429687500000 0.429687500000 -mp_horn.tga 0.429687500000 0.390625000000 0.468750000000 0.429687500000 -mp_horney.tga 0.000000000000 0.429687500000 0.039062500000 0.468750000000 -mp_insect_fossil.tga 0.039062500000 0.429687500000 0.078125000000 0.468750000000 -mp_kitinshell.tga 0.078125000000 0.429687500000 0.117187500000 0.468750000000 -mp_kitin_flesh.tga 0.117187500000 0.429687500000 0.156250000000 0.468750000000 -mp_kitin_secretion.tga 0.156250000000 0.429687500000 0.195312500000 0.468750000000 -mp_larva.tga 0.195312500000 0.429687500000 0.234375000000 0.468750000000 -mp_leaf.tga 0.234375000000 0.429687500000 0.273437500000 0.468750000000 -mp_leather.tga 0.273437500000 0.429687500000 0.312500000000 0.468750000000 -mp_liane.tga 0.312500000000 0.429687500000 0.351562500000 0.468750000000 -mp_lichen.tga 0.351562500000 0.429687500000 0.390625000000 0.468750000000 -mp_ligament.tga 0.390625000000 0.429687500000 0.429687500000 0.468750000000 -mp_mandible.tga 0.429687500000 0.429687500000 0.468750000000 0.468750000000 -mp_meat.tga 0.476562500000 0.000000000000 0.515625000000 0.039062500000 -mp_moss.tga 0.515625000000 0.000000000000 0.554687500000 0.039062500000 -mp_mushroom.tga 0.554687500000 0.000000000000 0.593750000000 0.039062500000 -mp_nail.tga 0.593750000000 0.000000000000 0.632812500000 0.039062500000 -mp_oil.tga 0.632812500000 0.000000000000 0.671875000000 0.039062500000 -mp_parasite.tga 0.671875000000 0.000000000000 0.710937500000 0.039062500000 -mp_pearl.tga 0.710937500000 0.000000000000 0.750000000000 0.039062500000 -mp_pelvis.tga 0.750000000000 0.000000000000 0.789062500000 0.039062500000 -mp_pigment.tga 0.789062500000 0.000000000000 0.828125000000 0.039062500000 -mp_pistil.tga 0.828125000000 0.000000000000 0.867187500000 0.039062500000 -mp_plant_fossil.tga 0.867187500000 0.000000000000 0.906250000000 0.039062500000 -mp_pollen.tga 0.906250000000 0.000000000000 0.945312500000 0.039062500000 -mp_resin.tga 0.945312500000 0.000000000000 0.984375000000 0.039062500000 -mp_ronce.tga 0.472656250000 0.039062500000 0.511718750000 0.078125000000 -mp_rostrum.tga 0.511718750000 0.039062500000 0.550781250000 0.078125000000 -mp_sap.tga 0.550781250000 0.039062500000 0.589843750000 0.078125000000 -mp_sawdust.tga 0.589843750000 0.039062500000 0.628906250000 0.078125000000 -mp_seed.tga 0.628906250000 0.039062500000 0.667968750000 0.078125000000 -mp_shell.tga 0.667968750000 0.039062500000 0.707031250000 0.078125000000 -mp_silk_worm.tga 0.707031250000 0.039062500000 0.746093750000 0.078125000000 -mp_skin.tga 0.746093750000 0.039062500000 0.785156250000 0.078125000000 -mp_skull.tga 0.785156250000 0.039062500000 0.824218750000 0.078125000000 -mp_spiders_web.tga 0.824218750000 0.039062500000 0.863281250000 0.078125000000 -mp_spine.tga 0.863281250000 0.039062500000 0.902343750000 0.078125000000 -mp_stem.tga 0.902343750000 0.039062500000 0.941406250000 0.078125000000 -mp_sting.tga 0.941406250000 0.039062500000 0.980468750000 0.078125000000 -mp_straw.tga 0.468750000000 0.078125000000 0.507812500000 0.117187500000 -mp_suc.tga 0.507812500000 0.078125000000 0.546875000000 0.117187500000 -mp_tail.tga 0.546875000000 0.078125000000 0.585937500000 0.117187500000 -mp_tooth.tga 0.585937500000 0.078125000000 0.625000000000 0.117187500000 -mp_trunk.tga 0.625000000000 0.078125000000 0.664062500000 0.117187500000 -mp_whiskers.tga 0.664062500000 0.078125000000 0.703125000000 0.117187500000 -mp_wing.tga 0.703125000000 0.078125000000 0.742187500000 0.117187500000 -mp_wood.tga 0.742187500000 0.078125000000 0.781250000000 0.117187500000 -mp_wood_node.tga 0.781250000000 0.078125000000 0.820312500000 0.117187500000 -MW_2h_axe.tga 0.820312500000 0.078125000000 0.859375000000 0.117187500000 -MW_2h_lance.tga 0.859375000000 0.078125000000 0.898437500000 0.117187500000 -MW_2h_mace.tga 0.898437500000 0.078125000000 0.937500000000 0.117187500000 -MW_2h_sword.tga 0.937500000000 0.078125000000 0.976562500000 0.117187500000 -MW_axe.tga 0.468750000000 0.117187500000 0.507812500000 0.156250000000 -MW_dagger.tga 0.507812500000 0.117187500000 0.546875000000 0.156250000000 -MW_lance.tga 0.546875000000 0.117187500000 0.585937500000 0.156250000000 -MW_mace.tga 0.585937500000 0.117187500000 0.625000000000 0.156250000000 -MW_staff.tga 0.625000000000 0.117187500000 0.664062500000 0.156250000000 -MW_sword.tga 0.664062500000 0.117187500000 0.703125000000 0.156250000000 -PA_anklet.tga 0.703125000000 0.117187500000 0.742187500000 0.156250000000 -PA_bracelet.tga 0.742187500000 0.117187500000 0.781250000000 0.156250000000 -PA_diadem.tga 0.781250000000 0.117187500000 0.820312500000 0.156250000000 -PA_earring.tga 0.820312500000 0.117187500000 0.859375000000 0.156250000000 -PA_pendant.tga 0.859375000000 0.117187500000 0.898437500000 0.156250000000 -PA_ring.tga 0.898437500000 0.117187500000 0.937500000000 0.156250000000 -protect_amber.tga 0.937500000000 0.117187500000 0.976562500000 0.156250000000 -pvp_aura.tga 0.468750000000 0.156250000000 0.507812500000 0.195312500000 -pvp_aura_mask.tga 0.507812500000 0.156250000000 0.546875000000 0.195312500000 -pvp_boost.tga 0.546875000000 0.156250000000 0.585937500000 0.195312500000 -pvp_boost_mask.tga 0.585937500000 0.156250000000 0.625000000000 0.195312500000 -pw_4.tga 0.625000000000 0.156250000000 0.664062500000 0.195312500000 -pw_5.tga 0.664062500000 0.156250000000 0.703125000000 0.195312500000 -pw_6.tga 0.703125000000 0.156250000000 0.742187500000 0.195312500000 -pw_7.tga 0.742187500000 0.156250000000 0.781250000000 0.195312500000 -PW_heavy.tga 0.781250000000 0.156250000000 0.820312500000 0.195312500000 -PW_light.tga 0.820312500000 0.156250000000 0.859375000000 0.195312500000 -PW_medium.tga 0.859375000000 0.156250000000 0.898437500000 0.195312500000 -quest_coeur.tga 0.898437500000 0.156250000000 0.937500000000 0.195312500000 -quest_foie.tga 0.937500000000 0.156250000000 0.976562500000 0.195312500000 -quest_jeton.tga 0.468750000000 0.195312500000 0.507812500000 0.234375000000 -quest_langue.tga 0.507812500000 0.195312500000 0.546875000000 0.234375000000 -quest_louche.tga 0.546875000000 0.195312500000 0.585937500000 0.234375000000 -quest_oreille.tga 0.585937500000 0.195312500000 0.625000000000 0.234375000000 -quest_patte.tga 0.625000000000 0.195312500000 0.664062500000 0.234375000000 -quest_poils.tga 0.664062500000 0.195312500000 0.703125000000 0.234375000000 -quest_queue.tga 0.703125000000 0.195312500000 0.742187500000 0.234375000000 -quest_ticket.tga 0.742187500000 0.195312500000 0.781250000000 0.234375000000 -AM_logo.tga 0.781250000000 0.195312500000 0.820312500000 0.234375000000 -AR_armpad.tga 0.820312500000 0.195312500000 0.859375000000 0.234375000000 -ar_armpad_mask.tga 0.859375000000 0.195312500000 0.898437500000 0.234375000000 -requirement.tga 0.898437500000 0.195312500000 0.937500000000 0.234375000000 -rm_f.tga 0.937500000000 0.195312500000 0.976562500000 0.234375000000 -rm_f_upgrade.tga 0.468750000000 0.234375000000 0.507812500000 0.273437500000 -rm_h.tga 0.507812500000 0.234375000000 0.546875000000 0.273437500000 -rm_h_upgrade.tga 0.546875000000 0.234375000000 0.585937500000 0.273437500000 -rm_m.tga 0.585937500000 0.234375000000 0.625000000000 0.273437500000 -rm_m_upgrade.tga 0.625000000000 0.234375000000 0.664062500000 0.273437500000 -rm_r.tga 0.664062500000 0.234375000000 0.703125000000 0.273437500000 -rm_r_upgrade.tga 0.703125000000 0.234375000000 0.742187500000 0.273437500000 -rpjobitem_200_a.tga 0.742187500000 0.234375000000 0.781250000000 0.273437500000 -rpjobitem_200_b.tga 0.781250000000 0.234375000000 0.820312500000 0.273437500000 -rpjobitem_200_c.tga 0.820312500000 0.234375000000 0.859375000000 0.273437500000 -rpjobitem_201_a.tga 0.859375000000 0.234375000000 0.898437500000 0.273437500000 -rpjobitem_201_b.tga 0.898437500000 0.234375000000 0.937500000000 0.273437500000 -rpjobitem_201_c.tga 0.937500000000 0.234375000000 0.976562500000 0.273437500000 -rpjobitem_202_a.tga 0.468750000000 0.273437500000 0.507812500000 0.312500000000 -rpjobitem_202_b.tga 0.507812500000 0.273437500000 0.546875000000 0.312500000000 -rpjobitem_202_c.tga 0.546875000000 0.273437500000 0.585937500000 0.312500000000 -rpjobitem_203_a.tga 0.585937500000 0.273437500000 0.625000000000 0.312500000000 -rpjobitem_203_b.tga 0.625000000000 0.273437500000 0.664062500000 0.312500000000 -rpjobitem_203_c.tga 0.664062500000 0.273437500000 0.703125000000 0.312500000000 -rpjobitem_204_a.tga 0.703125000000 0.273437500000 0.742187500000 0.312500000000 -rpjobitem_204_b.tga 0.742187500000 0.273437500000 0.781250000000 0.312500000000 -rpjobitem_204_c.tga 0.781250000000 0.273437500000 0.820312500000 0.312500000000 -rpjobitem_205_a.tga 0.820312500000 0.273437500000 0.859375000000 0.312500000000 -rpjobitem_205_b.tga 0.859375000000 0.273437500000 0.898437500000 0.312500000000 -rpjobitem_205_c.tga 0.898437500000 0.273437500000 0.937500000000 0.312500000000 -rpjobitem_206_a.tga 0.937500000000 0.273437500000 0.976562500000 0.312500000000 -rpjobitem_206_b.tga 0.468750000000 0.312500000000 0.507812500000 0.351562500000 -rpjobitem_206_c.tga 0.507812500000 0.312500000000 0.546875000000 0.351562500000 -rpjobitem_207_a.tga 0.546875000000 0.312500000000 0.585937500000 0.351562500000 -rpjobitem_207_b.tga 0.585937500000 0.312500000000 0.625000000000 0.351562500000 -rpjobitem_207_c.tga 0.625000000000 0.312500000000 0.664062500000 0.351562500000 -rpjobitem_certifications.tga 0.664062500000 0.312500000000 0.703125000000 0.351562500000 -rpjob_200.tga 0.703125000000 0.312500000000 0.742187500000 0.351562500000 -rpjob_201.tga 0.742187500000 0.312500000000 0.781250000000 0.351562500000 -rpjob_202.tga 0.781250000000 0.312500000000 0.820312500000 0.351562500000 -rpjob_203.tga 0.820312500000 0.312500000000 0.859375000000 0.351562500000 -rpjob_204.tga 0.859375000000 0.312500000000 0.898437500000 0.351562500000 -rpjob_205.tga 0.898437500000 0.312500000000 0.937500000000 0.351562500000 -rpjob_206.tga 0.937500000000 0.312500000000 0.976562500000 0.351562500000 -rpjob_207.tga 0.468750000000 0.351562500000 0.507812500000 0.390625000000 -rpjob_advanced.tga 0.507812500000 0.351562500000 0.546875000000 0.390625000000 -rpjob_elementary.tga 0.546875000000 0.351562500000 0.585937500000 0.390625000000 -rpjob_roleplay.tga 0.585937500000 0.351562500000 0.625000000000 0.390625000000 -rpjob_task.tga 0.625000000000 0.351562500000 0.664062500000 0.390625000000 -rpjob_task_certificats.tga 0.664062500000 0.351562500000 0.703125000000 0.390625000000 -rpjob_task_convert.tga 0.703125000000 0.351562500000 0.742187500000 0.390625000000 -rpjob_task_elementary.tga 0.742187500000 0.351562500000 0.781250000000 0.390625000000 -rpjob_task_generic.tga 0.781250000000 0.351562500000 0.820312500000 0.390625000000 -rpjob_task_upgrade.tga 0.820312500000 0.351562500000 0.859375000000 0.390625000000 -RW_autolaunch.tga 0.859375000000 0.351562500000 0.898437500000 0.390625000000 -RW_bowgun.tga 0.898437500000 0.351562500000 0.937500000000 0.390625000000 -RW_grenade.tga 0.937500000000 0.351562500000 0.976562500000 0.390625000000 -RW_harpoongun.tga 0.468750000000 0.390625000000 0.507812500000 0.429687500000 -RW_launcher.tga 0.507812500000 0.390625000000 0.546875000000 0.429687500000 -RW_pistol.tga 0.546875000000 0.390625000000 0.585937500000 0.429687500000 -RW_pistolarc.tga 0.585937500000 0.390625000000 0.625000000000 0.429687500000 -RW_rifle.tga 0.625000000000 0.390625000000 0.664062500000 0.429687500000 -SH_buckler.tga 0.664062500000 0.390625000000 0.703125000000 0.429687500000 -SH_large_shield.tga 0.703125000000 0.390625000000 0.742187500000 0.429687500000 -spe_beast.tga 0.742187500000 0.390625000000 0.781250000000 0.429687500000 -spe_com.tga 0.781250000000 0.390625000000 0.820312500000 0.429687500000 -spe_inventory.tga 0.820312500000 0.390625000000 0.859375000000 0.429687500000 -spe_labs.tga 0.859375000000 0.390625000000 0.898437500000 0.429687500000 -spe_memory.tga 0.898437500000 0.390625000000 0.937500000000 0.429687500000 -spe_options.tga 0.937500000000 0.390625000000 0.976562500000 0.429687500000 -spe_status.tga 0.468750000000 0.429687500000 0.507812500000 0.468750000000 -stimulating_water.tga 0.507812500000 0.429687500000 0.546875000000 0.468750000000 -tetekitin.tga 0.546875000000 0.429687500000 0.585937500000 0.468750000000 -to_ammo.tga 0.585937500000 0.429687500000 0.625000000000 0.468750000000 -to_armor.tga 0.625000000000 0.429687500000 0.664062500000 0.468750000000 -to_cooking_pot.tga 0.664062500000 0.429687500000 0.703125000000 0.468750000000 -to_fishing_rod.tga 0.703125000000 0.429687500000 0.742187500000 0.468750000000 -to_forage.tga 0.742187500000 0.429687500000 0.781250000000 0.468750000000 -to_hammer.tga 0.781250000000 0.429687500000 0.820312500000 0.468750000000 -to_jewelry_hammer.tga 0.820312500000 0.429687500000 0.859375000000 0.468750000000 -to_jewels.tga 0.859375000000 0.429687500000 0.898437500000 0.468750000000 -to_leathercutter.tga 0.898437500000 0.429687500000 0.937500000000 0.468750000000 -to_melee.tga 0.937500000000 0.429687500000 0.976562500000 0.468750000000 -to_needle.tga 0.000000000000 0.468750000000 0.039062500000 0.507812500000 -to_pestle.tga 0.039062500000 0.468750000000 0.078125000000 0.507812500000 -to_range.tga 0.078125000000 0.468750000000 0.117187500000 0.507812500000 -to_searake.tga 0.117187500000 0.468750000000 0.156250000000 0.507812500000 -to_spade.tga 0.156250000000 0.468750000000 0.195312500000 0.507812500000 -to_stick.tga 0.195312500000 0.468750000000 0.234375000000 0.507812500000 -to_tunneling_knife.tga 0.234375000000 0.468750000000 0.273437500000 0.507812500000 -to_whip.tga 0.273437500000 0.468750000000 0.312500000000 0.507812500000 -to_wrench.tga 0.312500000000 0.468750000000 0.351562500000 0.507812500000 -TP_caravane.tga 0.351562500000 0.468750000000 0.390625000000 0.507812500000 -TP_kami.tga 0.390625000000 0.468750000000 0.429687500000 0.507812500000 -W_AM_logo.tga 0.429687500000 0.468750000000 0.468750000000 0.507812500000 -w_pa_anklet.tga 0.468750000000 0.468750000000 0.507812500000 0.507812500000 -w_pa_bracelet.tga 0.507812500000 0.468750000000 0.546875000000 0.507812500000 -w_pa_diadem.tga 0.546875000000 0.468750000000 0.585937500000 0.507812500000 -w_pa_earring.tga 0.585937500000 0.468750000000 0.625000000000 0.507812500000 -w_pa_pendant.tga 0.625000000000 0.468750000000 0.664062500000 0.507812500000 -w_pa_ring.tga 0.664062500000 0.468750000000 0.703125000000 0.507812500000 -xp_cat_green.tga 0.703125000000 0.468750000000 0.742187500000 0.507812500000 +BK_matis.tga 0.078125000000 0.117187500000 0.117187500000 0.156250000000 +bk_mission.tga 0.117187500000 0.117187500000 0.156250000000 0.156250000000 +bk_mission2.tga 0.156250000000 0.117187500000 0.195312500000 0.156250000000 +BK_outpost.tga 0.195312500000 0.117187500000 0.234375000000 0.156250000000 +BK_primes.tga 0.000000000000 0.156250000000 0.039062500000 0.195312500000 +bk_service.tga 0.039062500000 0.156250000000 0.078125000000 0.195312500000 +bk_training.tga 0.078125000000 0.156250000000 0.117187500000 0.195312500000 +BK_tryker.tga 0.117187500000 0.156250000000 0.156250000000 0.195312500000 +BK_zorai.tga 0.156250000000 0.156250000000 0.195312500000 0.195312500000 +charge.tga 0.195312500000 0.156250000000 0.234375000000 0.195312500000 +clef.tga 0.000000000000 0.195312500000 0.039062500000 0.234375000000 +conso_branche.tga 0.039062500000 0.195312500000 0.078125000000 0.234375000000 +conso_branche_mask.tga 0.078125000000 0.195312500000 0.117187500000 0.234375000000 +conso_fleur.tga 0.117187500000 0.195312500000 0.156250000000 0.234375000000 +conso_fleur_mask.tga 0.156250000000 0.195312500000 0.195312500000 0.234375000000 +conso_grappe.tga 0.195312500000 0.195312500000 0.234375000000 0.234375000000 +conso_nectar.tga 0.242187500000 0.000000000000 0.281250000000 0.039062500000 +conso_nectar_mask.tga 0.281250000000 0.000000000000 0.320312500000 0.039062500000 +construction.tga 0.320312500000 0.000000000000 0.359375000000 0.039062500000 +cristal_ammo.tga 0.359375000000 0.000000000000 0.398437500000 0.039062500000 +cristal_spell.tga 0.398437500000 0.000000000000 0.437500000000 0.039062500000 +ico_haircolor.tga 0.437500000000 0.000000000000 0.476562500000 0.039062500000 +ico_haircut.tga 0.238281250000 0.039062500000 0.277343750000 0.078125000000 +bk_karavan.tga 0.277343750000 0.039062500000 0.316406250000 0.078125000000 +conso_grappe_mask.tga 0.316406250000 0.039062500000 0.355468750000 0.078125000000 +ico_foreuse.tga 0.355468750000 0.039062500000 0.394531250000 0.078125000000 +ico_noix.tga 0.394531250000 0.039062500000 0.433593750000 0.078125000000 +ico_spores.tga 0.433593750000 0.039062500000 0.472656250000 0.078125000000 +mektoub_pack.tga 0.234375000000 0.078125000000 0.273437500000 0.117187500000 +mp_beak.tga 0.273437500000 0.078125000000 0.312500000000 0.117187500000 +mp_fresh_loose_soil.tga 0.312500000000 0.078125000000 0.351562500000 0.117187500000 +mp_lichen.tga 0.351562500000 0.078125000000 0.390625000000 0.117187500000 +mp_sawdust.tga 0.390625000000 0.078125000000 0.429687500000 0.117187500000 +MW_2h_axe.tga 0.429687500000 0.078125000000 0.468750000000 0.117187500000 +PA_bracelet.tga 0.234375000000 0.117187500000 0.273437500000 0.156250000000 +pvp_aura_mask.tga 0.273437500000 0.117187500000 0.312500000000 0.156250000000 +quest_queue.tga 0.312500000000 0.117187500000 0.351562500000 0.156250000000 +rpjobitem_201_b.tga 0.351562500000 0.117187500000 0.390625000000 0.156250000000 +rpjobitem_207_a.tga 0.390625000000 0.117187500000 0.429687500000 0.156250000000 +rpjob_task_elementary.tga 0.429687500000 0.117187500000 0.468750000000 0.156250000000 +spe_options.tga 0.234375000000 0.156250000000 0.273437500000 0.195312500000 +to_range.tga 0.273437500000 0.156250000000 0.312500000000 0.195312500000 +w_pa_anklet.tga 0.312500000000 0.156250000000 0.351562500000 0.195312500000 +ico_task_craft.tga 0.351562500000 0.156250000000 0.390625000000 0.195312500000 +ico_task_done.tga 0.390625000000 0.156250000000 0.429687500000 0.195312500000 +ico_task_failed.tga 0.429687500000 0.156250000000 0.468750000000 0.195312500000 +ico_task_fight.tga 0.234375000000 0.195312500000 0.273437500000 0.234375000000 +ico_task_forage.tga 0.273437500000 0.195312500000 0.312500000000 0.234375000000 +ico_task_generic.tga 0.312500000000 0.195312500000 0.351562500000 0.234375000000 +ico_task_generic_quart.tga 0.351562500000 0.195312500000 0.390625000000 0.234375000000 +ico_task_guild.tga 0.390625000000 0.195312500000 0.429687500000 0.234375000000 +ico_task_rite.tga 0.429687500000 0.195312500000 0.468750000000 0.234375000000 +ico_task_travel.tga 0.000000000000 0.234375000000 0.039062500000 0.273437500000 +ico_tatoo.tga 0.039062500000 0.234375000000 0.078125000000 0.273437500000 +mektoub_steed.tga 0.078125000000 0.234375000000 0.117187500000 0.273437500000 +mg_glove.tga 0.117187500000 0.234375000000 0.156250000000 0.273437500000 +mission_icon_0.tga 0.156250000000 0.234375000000 0.195312500000 0.273437500000 +mission_icon_1.tga 0.195312500000 0.234375000000 0.234375000000 0.273437500000 +mission_icon_2.tga 0.234375000000 0.234375000000 0.273437500000 0.273437500000 +mission_icon_3.tga 0.273437500000 0.234375000000 0.312500000000 0.273437500000 +mp_amber.tga 0.312500000000 0.234375000000 0.351562500000 0.273437500000 +mp_bark.tga 0.351562500000 0.234375000000 0.390625000000 0.273437500000 +mp_batiment_brique.tga 0.390625000000 0.234375000000 0.429687500000 0.273437500000 +mp_batiment_colonne.tga 0.429687500000 0.234375000000 0.468750000000 0.273437500000 +mp_batiment_colonne_justice.tga 0.000000000000 0.273437500000 0.039062500000 0.312500000000 +mp_batiment_comble.tga 0.039062500000 0.273437500000 0.078125000000 0.312500000000 +mp_batiment_noyau_maduk.tga 0.078125000000 0.273437500000 0.117187500000 0.312500000000 +mp_batiment_ornement.tga 0.117187500000 0.273437500000 0.156250000000 0.312500000000 +mp_batiment_revetement.tga 0.156250000000 0.273437500000 0.195312500000 0.312500000000 +mp_batiment_socle.tga 0.195312500000 0.273437500000 0.234375000000 0.312500000000 +mp_batiment_statue.tga 0.234375000000 0.273437500000 0.273437500000 0.312500000000 +mp_blood.tga 0.273437500000 0.273437500000 0.312500000000 0.312500000000 +mp_bone.tga 0.312500000000 0.273437500000 0.351562500000 0.312500000000 +mp_bud.tga 0.351562500000 0.273437500000 0.390625000000 0.312500000000 +mp_buterfly_blue.tga 0.390625000000 0.273437500000 0.429687500000 0.312500000000 +mp_buterfly_cocoon.tga 0.429687500000 0.273437500000 0.468750000000 0.312500000000 +mp_cereal.tga 0.000000000000 0.312500000000 0.039062500000 0.351562500000 +mp_claw.tga 0.039062500000 0.312500000000 0.078125000000 0.351562500000 +mp_dandelion.tga 0.078125000000 0.312500000000 0.117187500000 0.351562500000 +mp_dust.tga 0.117187500000 0.312500000000 0.156250000000 0.351562500000 +mp_egg.tga 0.156250000000 0.312500000000 0.195312500000 0.351562500000 +mp_eyes.tga 0.195312500000 0.312500000000 0.234375000000 0.351562500000 +mp_fang.tga 0.234375000000 0.312500000000 0.273437500000 0.351562500000 +mp_fiber.tga 0.273437500000 0.312500000000 0.312500000000 0.351562500000 +mp_filament.tga 0.312500000000 0.312500000000 0.351562500000 0.351562500000 +mp_firefly_abdomen.tga 0.351562500000 0.312500000000 0.390625000000 0.351562500000 +mp_fish_scale.tga 0.390625000000 0.312500000000 0.429687500000 0.351562500000 +mp_flowers.tga 0.429687500000 0.312500000000 0.468750000000 0.351562500000 +mp_fruit.tga 0.000000000000 0.351562500000 0.039062500000 0.390625000000 +mp_generic.tga 0.039062500000 0.351562500000 0.078125000000 0.390625000000 +mp_generic_colorize.tga 0.078125000000 0.351562500000 0.117187500000 0.390625000000 +mp_gomme.tga 0.117187500000 0.351562500000 0.156250000000 0.390625000000 +mp_goo_residue.tga 0.156250000000 0.351562500000 0.195312500000 0.390625000000 +mp_hairs.tga 0.195312500000 0.351562500000 0.234375000000 0.390625000000 +mp_hoof.tga 0.234375000000 0.351562500000 0.273437500000 0.390625000000 +mp_horn.tga 0.273437500000 0.351562500000 0.312500000000 0.390625000000 +mp_horney.tga 0.312500000000 0.351562500000 0.351562500000 0.390625000000 +mp_insect_fossil.tga 0.351562500000 0.351562500000 0.390625000000 0.390625000000 +mp_kitinshell.tga 0.390625000000 0.351562500000 0.429687500000 0.390625000000 +mp_kitin_flesh.tga 0.429687500000 0.351562500000 0.468750000000 0.390625000000 +mp_kitin_secretion.tga 0.000000000000 0.390625000000 0.039062500000 0.429687500000 +mp_larva.tga 0.039062500000 0.390625000000 0.078125000000 0.429687500000 +mp_leaf.tga 0.078125000000 0.390625000000 0.117187500000 0.429687500000 +mp_leather.tga 0.117187500000 0.390625000000 0.156250000000 0.429687500000 +mp_liane.tga 0.156250000000 0.390625000000 0.195312500000 0.429687500000 +mp_ligament.tga 0.195312500000 0.390625000000 0.234375000000 0.429687500000 +mp_mandible.tga 0.234375000000 0.390625000000 0.273437500000 0.429687500000 +mp_meat.tga 0.273437500000 0.390625000000 0.312500000000 0.429687500000 +mp_moss.tga 0.312500000000 0.390625000000 0.351562500000 0.429687500000 +mp_mushroom.tga 0.351562500000 0.390625000000 0.390625000000 0.429687500000 +mp_nail.tga 0.390625000000 0.390625000000 0.429687500000 0.429687500000 +mp_oil.tga 0.429687500000 0.390625000000 0.468750000000 0.429687500000 +mp_parasite.tga 0.000000000000 0.429687500000 0.039062500000 0.468750000000 +mp_pearl.tga 0.039062500000 0.429687500000 0.078125000000 0.468750000000 +mp_pelvis.tga 0.078125000000 0.429687500000 0.117187500000 0.468750000000 +mp_pigment.tga 0.117187500000 0.429687500000 0.156250000000 0.468750000000 +mp_pistil.tga 0.156250000000 0.429687500000 0.195312500000 0.468750000000 +mp_plant_fossil.tga 0.195312500000 0.429687500000 0.234375000000 0.468750000000 +mp_pollen.tga 0.234375000000 0.429687500000 0.273437500000 0.468750000000 +mp_resin.tga 0.273437500000 0.429687500000 0.312500000000 0.468750000000 +mp_ronce.tga 0.312500000000 0.429687500000 0.351562500000 0.468750000000 +mp_rostrum.tga 0.351562500000 0.429687500000 0.390625000000 0.468750000000 +mp_sap.tga 0.390625000000 0.429687500000 0.429687500000 0.468750000000 +mp_seed.tga 0.429687500000 0.429687500000 0.468750000000 0.468750000000 +mp_shell.tga 0.476562500000 0.000000000000 0.515625000000 0.039062500000 +mp_silk_worm.tga 0.515625000000 0.000000000000 0.554687500000 0.039062500000 +mp_skin.tga 0.554687500000 0.000000000000 0.593750000000 0.039062500000 +mp_skull.tga 0.593750000000 0.000000000000 0.632812500000 0.039062500000 +mp_spiders_web.tga 0.632812500000 0.000000000000 0.671875000000 0.039062500000 +mp_spine.tga 0.671875000000 0.000000000000 0.710937500000 0.039062500000 +mp_stem.tga 0.710937500000 0.000000000000 0.750000000000 0.039062500000 +mp_sting.tga 0.750000000000 0.000000000000 0.789062500000 0.039062500000 +mp_straw.tga 0.789062500000 0.000000000000 0.828125000000 0.039062500000 +mp_suc.tga 0.828125000000 0.000000000000 0.867187500000 0.039062500000 +mp_tail.tga 0.867187500000 0.000000000000 0.906250000000 0.039062500000 +mp_tooth.tga 0.906250000000 0.000000000000 0.945312500000 0.039062500000 +mp_trunk.tga 0.945312500000 0.000000000000 0.984375000000 0.039062500000 +mp_whiskers.tga 0.472656250000 0.039062500000 0.511718750000 0.078125000000 +mp_wing.tga 0.511718750000 0.039062500000 0.550781250000 0.078125000000 +mp_wood.tga 0.550781250000 0.039062500000 0.589843750000 0.078125000000 +mp_wood_node.tga 0.589843750000 0.039062500000 0.628906250000 0.078125000000 +MW_2h_lance.tga 0.628906250000 0.039062500000 0.667968750000 0.078125000000 +MW_2h_mace.tga 0.667968750000 0.039062500000 0.707031250000 0.078125000000 +MW_2h_sword.tga 0.707031250000 0.039062500000 0.746093750000 0.078125000000 +MW_axe.tga 0.746093750000 0.039062500000 0.785156250000 0.078125000000 +MW_dagger.tga 0.785156250000 0.039062500000 0.824218750000 0.078125000000 +MW_lance.tga 0.824218750000 0.039062500000 0.863281250000 0.078125000000 +MW_mace.tga 0.863281250000 0.039062500000 0.902343750000 0.078125000000 +MW_staff.tga 0.902343750000 0.039062500000 0.941406250000 0.078125000000 +MW_sword.tga 0.941406250000 0.039062500000 0.980468750000 0.078125000000 +PA_anklet.tga 0.468750000000 0.078125000000 0.507812500000 0.117187500000 +pvp_boost.tga 0.507812500000 0.078125000000 0.546875000000 0.117187500000 +pvp_boost_mask.tga 0.546875000000 0.078125000000 0.585937500000 0.117187500000 +pw_4.tga 0.585937500000 0.078125000000 0.625000000000 0.117187500000 +pw_5.tga 0.625000000000 0.078125000000 0.664062500000 0.117187500000 +pw_6.tga 0.664062500000 0.078125000000 0.703125000000 0.117187500000 +pw_7.tga 0.703125000000 0.078125000000 0.742187500000 0.117187500000 +PW_heavy.tga 0.742187500000 0.078125000000 0.781250000000 0.117187500000 +PW_light.tga 0.781250000000 0.078125000000 0.820312500000 0.117187500000 +PW_medium.tga 0.820312500000 0.078125000000 0.859375000000 0.117187500000 +quest_coeur.tga 0.859375000000 0.078125000000 0.898437500000 0.117187500000 +quest_foie.tga 0.898437500000 0.078125000000 0.937500000000 0.117187500000 +quest_jeton.tga 0.937500000000 0.078125000000 0.976562500000 0.117187500000 +quest_langue.tga 0.468750000000 0.117187500000 0.507812500000 0.156250000000 +quest_louche.tga 0.507812500000 0.117187500000 0.546875000000 0.156250000000 +quest_oreille.tga 0.546875000000 0.117187500000 0.585937500000 0.156250000000 +quest_patte.tga 0.585937500000 0.117187500000 0.625000000000 0.156250000000 +quest_poils.tga 0.625000000000 0.117187500000 0.664062500000 0.156250000000 +quest_ticket.tga 0.664062500000 0.117187500000 0.703125000000 0.156250000000 +AM_logo.tga 0.703125000000 0.117187500000 0.742187500000 0.156250000000 +AR_armpad.tga 0.742187500000 0.117187500000 0.781250000000 0.156250000000 +ar_armpad_mask.tga 0.781250000000 0.117187500000 0.820312500000 0.156250000000 +requirement.tga 0.820312500000 0.117187500000 0.859375000000 0.156250000000 +rm_f.tga 0.859375000000 0.117187500000 0.898437500000 0.156250000000 +rm_f_upgrade.tga 0.898437500000 0.117187500000 0.937500000000 0.156250000000 +rm_h.tga 0.937500000000 0.117187500000 0.976562500000 0.156250000000 +rm_h_upgrade.tga 0.468750000000 0.156250000000 0.507812500000 0.195312500000 +rm_m.tga 0.507812500000 0.156250000000 0.546875000000 0.195312500000 +rm_m_upgrade.tga 0.546875000000 0.156250000000 0.585937500000 0.195312500000 +rm_r.tga 0.585937500000 0.156250000000 0.625000000000 0.195312500000 +rm_r_upgrade.tga 0.625000000000 0.156250000000 0.664062500000 0.195312500000 +rpjobitem_200_a.tga 0.664062500000 0.156250000000 0.703125000000 0.195312500000 +rpjobitem_200_b.tga 0.703125000000 0.156250000000 0.742187500000 0.195312500000 +rpjobitem_200_c.tga 0.742187500000 0.156250000000 0.781250000000 0.195312500000 +rpjobitem_201_a.tga 0.781250000000 0.156250000000 0.820312500000 0.195312500000 +rpjobitem_201_c.tga 0.820312500000 0.156250000000 0.859375000000 0.195312500000 +rpjobitem_202_a.tga 0.859375000000 0.156250000000 0.898437500000 0.195312500000 +rpjobitem_202_b.tga 0.898437500000 0.156250000000 0.937500000000 0.195312500000 +rpjobitem_202_c.tga 0.937500000000 0.156250000000 0.976562500000 0.195312500000 +rpjobitem_203_a.tga 0.468750000000 0.195312500000 0.507812500000 0.234375000000 +rpjobitem_203_b.tga 0.507812500000 0.195312500000 0.546875000000 0.234375000000 +rpjobitem_203_c.tga 0.546875000000 0.195312500000 0.585937500000 0.234375000000 +rpjobitem_204_a.tga 0.585937500000 0.195312500000 0.625000000000 0.234375000000 +rpjobitem_204_b.tga 0.625000000000 0.195312500000 0.664062500000 0.234375000000 +rpjobitem_204_c.tga 0.664062500000 0.195312500000 0.703125000000 0.234375000000 +rpjobitem_205_a.tga 0.703125000000 0.195312500000 0.742187500000 0.234375000000 +rpjobitem_205_b.tga 0.742187500000 0.195312500000 0.781250000000 0.234375000000 +rpjobitem_205_c.tga 0.781250000000 0.195312500000 0.820312500000 0.234375000000 +rpjobitem_206_a.tga 0.820312500000 0.195312500000 0.859375000000 0.234375000000 +rpjobitem_206_b.tga 0.859375000000 0.195312500000 0.898437500000 0.234375000000 +rpjobitem_206_c.tga 0.898437500000 0.195312500000 0.937500000000 0.234375000000 +rpjobitem_207_b.tga 0.937500000000 0.195312500000 0.976562500000 0.234375000000 +rpjobitem_207_c.tga 0.468750000000 0.234375000000 0.507812500000 0.273437500000 +rpjobitem_certifications.tga 0.507812500000 0.234375000000 0.546875000000 0.273437500000 +rpjob_200.tga 0.546875000000 0.234375000000 0.585937500000 0.273437500000 +rpjob_201.tga 0.585937500000 0.234375000000 0.625000000000 0.273437500000 +rpjob_202.tga 0.625000000000 0.234375000000 0.664062500000 0.273437500000 +rpjob_203.tga 0.664062500000 0.234375000000 0.703125000000 0.273437500000 +rpjob_204.tga 0.703125000000 0.234375000000 0.742187500000 0.273437500000 +rpjob_205.tga 0.742187500000 0.234375000000 0.781250000000 0.273437500000 +rpjob_206.tga 0.781250000000 0.234375000000 0.820312500000 0.273437500000 +rpjob_207.tga 0.820312500000 0.234375000000 0.859375000000 0.273437500000 +rpjob_advanced.tga 0.859375000000 0.234375000000 0.898437500000 0.273437500000 +rpjob_elementary.tga 0.898437500000 0.234375000000 0.937500000000 0.273437500000 +rpjob_roleplay.tga 0.937500000000 0.234375000000 0.976562500000 0.273437500000 +rpjob_task.tga 0.468750000000 0.273437500000 0.507812500000 0.312500000000 +rpjob_task_certificats.tga 0.507812500000 0.273437500000 0.546875000000 0.312500000000 +rpjob_task_convert.tga 0.546875000000 0.273437500000 0.585937500000 0.312500000000 +rpjob_task_generic.tga 0.585937500000 0.273437500000 0.625000000000 0.312500000000 +rpjob_task_upgrade.tga 0.625000000000 0.273437500000 0.664062500000 0.312500000000 +RW_autolaunch.tga 0.664062500000 0.273437500000 0.703125000000 0.312500000000 +RW_bowgun.tga 0.703125000000 0.273437500000 0.742187500000 0.312500000000 +RW_grenade.tga 0.742187500000 0.273437500000 0.781250000000 0.312500000000 +RW_harpoongun.tga 0.781250000000 0.273437500000 0.820312500000 0.312500000000 +RW_launcher.tga 0.820312500000 0.273437500000 0.859375000000 0.312500000000 +RW_pistol.tga 0.859375000000 0.273437500000 0.898437500000 0.312500000000 +RW_pistolarc.tga 0.898437500000 0.273437500000 0.937500000000 0.312500000000 +RW_rifle.tga 0.937500000000 0.273437500000 0.976562500000 0.312500000000 +SH_buckler.tga 0.468750000000 0.312500000000 0.507812500000 0.351562500000 +SH_large_shield.tga 0.507812500000 0.312500000000 0.546875000000 0.351562500000 +spe_beast.tga 0.546875000000 0.312500000000 0.585937500000 0.351562500000 +spe_com.tga 0.585937500000 0.312500000000 0.625000000000 0.351562500000 +spe_inventory.tga 0.625000000000 0.312500000000 0.664062500000 0.351562500000 +spe_labs.tga 0.664062500000 0.312500000000 0.703125000000 0.351562500000 +spe_memory.tga 0.703125000000 0.312500000000 0.742187500000 0.351562500000 +spe_status.tga 0.742187500000 0.312500000000 0.781250000000 0.351562500000 +stimulating_water.tga 0.781250000000 0.312500000000 0.820312500000 0.351562500000 +ico_cataliseur_xp.tga 0.820312500000 0.312500000000 0.859375000000 0.351562500000 +ico_consommable_over.tga 0.859375000000 0.312500000000 0.898437500000 0.351562500000 +ico_fleur_carac_1.tga 0.898437500000 0.312500000000 0.937500000000 0.351562500000 +ico_fleur_carac_1_mask.tga 0.937500000000 0.312500000000 0.976562500000 0.351562500000 +ico_fleur_carac_2.tga 0.468750000000 0.351562500000 0.507812500000 0.390625000000 +ico_fleur_carac_2_mask.tga 0.507812500000 0.351562500000 0.546875000000 0.390625000000 +ico_fleur_carac_3.tga 0.546875000000 0.351562500000 0.585937500000 0.390625000000 +ico_fleur_carac_3_mask.tga 0.585937500000 0.351562500000 0.625000000000 0.390625000000 +ico_mission_art_fyros.tga 0.625000000000 0.351562500000 0.664062500000 0.390625000000 +ico_mission_art_matis.tga 0.664062500000 0.351562500000 0.703125000000 0.390625000000 +ico_mission_art_tryker.tga 0.703125000000 0.351562500000 0.742187500000 0.390625000000 +ico_mission_art_zorai.tga 0.742187500000 0.351562500000 0.781250000000 0.390625000000 +ico_mission_barrel.tga 0.781250000000 0.351562500000 0.820312500000 0.390625000000 +ico_mission_bottle.tga 0.820312500000 0.351562500000 0.859375000000 0.390625000000 +ico_mission_casket.tga 0.859375000000 0.351562500000 0.898437500000 0.390625000000 +ico_mission_medicine.tga 0.898437500000 0.351562500000 0.937500000000 0.390625000000 +ico_mission_message.tga 0.937500000000 0.351562500000 0.976562500000 0.390625000000 +ico_mission_package.tga 0.468750000000 0.390625000000 0.507812500000 0.429687500000 +ico_mission_pot.tga 0.507812500000 0.390625000000 0.546875000000 0.429687500000 +ico_mission_purse.tga 0.546875000000 0.390625000000 0.585937500000 0.429687500000 +ico_racine.tga 0.585937500000 0.390625000000 0.625000000000 0.429687500000 +ge_mission_outpost_townhall.tga 0.625000000000 0.390625000000 0.664062500000 0.429687500000 +ico_amande.tga 0.664062500000 0.390625000000 0.703125000000 0.429687500000 +to_searake.tga 0.703125000000 0.390625000000 0.742187500000 0.429687500000 +to_spade.tga 0.742187500000 0.390625000000 0.781250000000 0.429687500000 +to_stick.tga 0.781250000000 0.390625000000 0.820312500000 0.429687500000 +to_tunneling_knife.tga 0.820312500000 0.390625000000 0.859375000000 0.429687500000 +to_whip.tga 0.859375000000 0.390625000000 0.898437500000 0.429687500000 +to_wrench.tga 0.898437500000 0.390625000000 0.937500000000 0.429687500000 +TP_caravane.tga 0.937500000000 0.390625000000 0.976562500000 0.429687500000 +TP_kami.tga 0.468750000000 0.429687500000 0.507812500000 0.468750000000 +tetekitin.tga 0.507812500000 0.429687500000 0.546875000000 0.468750000000 +to_ammo.tga 0.546875000000 0.429687500000 0.585937500000 0.468750000000 +to_armor.tga 0.585937500000 0.429687500000 0.625000000000 0.468750000000 +to_cooking_pot.tga 0.625000000000 0.429687500000 0.664062500000 0.468750000000 +to_fishing_rod.tga 0.664062500000 0.429687500000 0.703125000000 0.468750000000 +to_forage.tga 0.703125000000 0.429687500000 0.742187500000 0.468750000000 +to_hammer.tga 0.742187500000 0.429687500000 0.781250000000 0.468750000000 +to_jewelry_hammer.tga 0.781250000000 0.429687500000 0.820312500000 0.468750000000 +to_jewels.tga 0.820312500000 0.429687500000 0.859375000000 0.468750000000 +to_leathercutter.tga 0.859375000000 0.429687500000 0.898437500000 0.468750000000 +to_melee.tga 0.898437500000 0.429687500000 0.937500000000 0.468750000000 +to_needle.tga 0.937500000000 0.429687500000 0.976562500000 0.468750000000 +to_pestle.tga 0.000000000000 0.468750000000 0.039062500000 0.507812500000 +ico_tourbe.tga 0.039062500000 0.468750000000 0.078125000000 0.507812500000 +improved_tool.tga 0.078125000000 0.468750000000 0.117187500000 0.507812500000 +item_default.tga 0.117187500000 0.468750000000 0.156250000000 0.507812500000 +item_plan_over.tga 0.156250000000 0.468750000000 0.195312500000 0.507812500000 +lucky_flower.tga 0.195312500000 0.468750000000 0.234375000000 0.507812500000 +W_AM_logo.tga 0.234375000000 0.468750000000 0.273437500000 0.507812500000 +w_pa_bracelet.tga 0.273437500000 0.468750000000 0.312500000000 0.507812500000 +w_pa_diadem.tga 0.312500000000 0.468750000000 0.351562500000 0.507812500000 +w_pa_earring.tga 0.351562500000 0.468750000000 0.390625000000 0.507812500000 +w_pa_pendant.tga 0.390625000000 0.468750000000 0.429687500000 0.507812500000 +w_pa_ring.tga 0.429687500000 0.468750000000 0.468750000000 0.507812500000 +xp_cat_green.tga 0.468750000000 0.468750000000 0.507812500000 0.507812500000 +PA_diadem.tga 0.507812500000 0.468750000000 0.546875000000 0.507812500000 +PA_earring.tga 0.546875000000 0.468750000000 0.585937500000 0.507812500000 +PA_pendant.tga 0.585937500000 0.468750000000 0.625000000000 0.507812500000 +PA_ring.tga 0.625000000000 0.468750000000 0.664062500000 0.507812500000 +protect_amber.tga 0.664062500000 0.468750000000 0.703125000000 0.507812500000 +pvp_aura.tga 0.703125000000 0.468750000000 0.742187500000 0.507812500000 asc_exit.tga 0.742187500000 0.468750000000 0.773437500000 0.500000000000 asc_rolemastercraft.tga 0.773437500000 0.468750000000 0.804687500000 0.500000000000 asc_rolemasterfight.tga 0.804687500000 0.468750000000 0.835937500000 0.500000000000 @@ -324,340 +324,350 @@ asc_rolemasterharvest.tga 0.835937500000 0.468750000000 0.867187500000 0.5000000 asc_rolemastermagic.tga 0.867187500000 0.468750000000 0.898437500000 0.500000000000 asc_unknown.tga 0.898437500000 0.468750000000 0.929687500000 0.500000000000 mail.tga 0.929687500000 0.468750000000 0.960937500000 0.492187500000 -mp_back_curative.tga 0.976562500000 0.078125000000 1.000000000000 0.101562500000 -mp_back_offensive.tga 0.976562500000 0.101562500000 1.000000000000 0.125000000000 -mp_back_selfonly.tga 0.976562500000 0.125000000000 1.000000000000 0.148437500000 -building_state_24x24.tga 0.976562500000 0.148437500000 1.000000000000 0.171875000000 -ico_ammo_bullet.tga 0.976562500000 0.171875000000 1.000000000000 0.195312500000 -ico_ammo_jacket.tga 0.976562500000 0.195312500000 1.000000000000 0.218750000000 -ico_angle.tga 0.976562500000 0.218750000000 1.000000000000 0.242187500000 -ico_anti_magic_shield.tga 0.976562500000 0.242187500000 1.000000000000 0.265625000000 -ico_armor.tga 0.976562500000 0.265625000000 1.000000000000 0.289062500000 -ico_armor_clip.tga 0.976562500000 0.289062500000 1.000000000000 0.312500000000 -ico_armor_heavy.tga 0.976562500000 0.312500000000 1.000000000000 0.335937500000 -ico_armor_kitin.tga 0.976562500000 0.335937500000 1.000000000000 0.359375000000 -ico_armor_light.tga 0.976562500000 0.359375000000 1.000000000000 0.382812500000 -ico_armor_medium.tga 0.976562500000 0.382812500000 1.000000000000 0.406250000000 -ico_armor_penalty.tga 0.976562500000 0.406250000000 1.000000000000 0.429687500000 -ico_armor_shell.tga 0.976562500000 0.429687500000 1.000000000000 0.453125000000 -ico_atys.tga 0.976562500000 0.453125000000 1.000000000000 0.476562500000 -ico_atysian.tga 0.960937500000 0.476562500000 0.984375000000 0.500000000000 -ico_balance_hp.tga 0.929687500000 0.492187500000 0.953125000000 0.515625000000 -ico_barrel.tga 0.742187500000 0.500000000000 0.765625000000 0.523437500000 -ico_bash.tga 0.765625000000 0.500000000000 0.789062500000 0.523437500000 -ico_berserk.tga 0.789062500000 0.500000000000 0.812500000000 0.523437500000 -ico_blade.tga 0.812500000000 0.500000000000 0.835937500000 0.523437500000 -ico_bleeding.tga 0.835937500000 0.500000000000 0.859375000000 0.523437500000 -ico_blind.tga 0.859375000000 0.500000000000 0.882812500000 0.523437500000 -ico_blunt.tga 0.882812500000 0.500000000000 0.906250000000 0.523437500000 -ico_bomb.tga 0.906250000000 0.500000000000 0.929687500000 0.523437500000 -cb_main_nue.tga 0.953125000000 0.500000000000 0.976562500000 0.523437500000 -ico_celestial.tga 0.976562500000 0.500000000000 1.000000000000 0.523437500000 -ico_circular_attack.tga 0.000000000000 0.507812500000 0.023437500000 0.531250000000 -ico_clothes.tga 0.023437500000 0.507812500000 0.046875000000 0.531250000000 -ico_cold.tga 0.046875000000 0.507812500000 0.070312500000 0.531250000000 -ico_concentration.tga 0.070312500000 0.507812500000 0.093750000000 0.531250000000 -BK_matis_brick.tga 0.093750000000 0.507812500000 0.117187500000 0.531250000000 -ico_constitution.tga 0.117187500000 0.507812500000 0.140625000000 0.531250000000 -ico_counterweight.tga 0.140625000000 0.507812500000 0.164062500000 0.531250000000 -ico_craft_buff.tga 0.164062500000 0.507812500000 0.187500000000 0.531250000000 -ico_create_sapload.tga 0.187500000000 0.507812500000 0.210937500000 0.531250000000 -ico_curse.tga 0.210937500000 0.507812500000 0.234375000000 0.531250000000 -ico_debuff.tga 0.234375000000 0.507812500000 0.257812500000 0.531250000000 -ico_debuff_resist.tga 0.257812500000 0.507812500000 0.281250000000 0.531250000000 -ico_debuff_skill.tga 0.281250000000 0.507812500000 0.304687500000 0.531250000000 -ico_desert.tga 0.304687500000 0.507812500000 0.328125000000 0.531250000000 -ico_dexterity.tga 0.328125000000 0.507812500000 0.351562500000 0.531250000000 -ico_disarm.tga 0.351562500000 0.507812500000 0.375000000000 0.531250000000 -ico_dodge.tga 0.375000000000 0.507812500000 0.398437500000 0.531250000000 -ico_dot.tga 0.398437500000 0.507812500000 0.421875000000 0.531250000000 -ico_durability.tga 0.421875000000 0.507812500000 0.445312500000 0.531250000000 -ico_electric.tga 0.445312500000 0.507812500000 0.468750000000 0.531250000000 -ico_explosif.tga 0.468750000000 0.507812500000 0.492187500000 0.531250000000 -ico_extracting.tga 0.492187500000 0.507812500000 0.515625000000 0.531250000000 -ico_fear.tga 0.515625000000 0.507812500000 0.539062500000 0.531250000000 -ico_feint.tga 0.539062500000 0.507812500000 0.562500000000 0.531250000000 -ico_fire.tga 0.562500000000 0.507812500000 0.585937500000 0.531250000000 -ico_firing_pin.tga 0.585937500000 0.507812500000 0.609375000000 0.531250000000 -ch_back.tga 0.609375000000 0.507812500000 0.632812500000 0.531250000000 -BK_generic_brick.tga 0.632812500000 0.507812500000 0.656250000000 0.531250000000 -mp_over_link.tga 0.656250000000 0.507812500000 0.679687500000 0.531250000000 -bk_aura.tga 0.679687500000 0.507812500000 0.703125000000 0.531250000000 -bk_conso.tga 0.703125000000 0.507812500000 0.726562500000 0.531250000000 -bk_outpost_brick.tga 0.929687500000 0.515625000000 0.953125000000 0.539062500000 -bk_power.tga 0.726562500000 0.523437500000 0.750000000000 0.546875000000 -ico_focus.tga 0.750000000000 0.523437500000 0.773437500000 0.546875000000 -ico_forage_buff.tga 0.773437500000 0.523437500000 0.796875000000 0.546875000000 -ico_forbid_item.tga 0.796875000000 0.523437500000 0.820312500000 0.546875000000 -ico_forest.tga 0.820312500000 0.523437500000 0.843750000000 0.546875000000 -2h_over.tga 0.843750000000 0.523437500000 0.867187500000 0.546875000000 -ico_gardening.tga 0.867187500000 0.523437500000 0.890625000000 0.546875000000 -ico_gentle.tga 0.890625000000 0.523437500000 0.914062500000 0.546875000000 -ico_goo.tga 0.953125000000 0.523437500000 0.976562500000 0.546875000000 -ico_gripp.tga 0.976562500000 0.523437500000 1.000000000000 0.546875000000 -1h_over.tga 0.000000000000 0.531250000000 0.023437500000 0.554687500000 -BK_fyros_brick.tga 0.023437500000 0.531250000000 0.046875000000 0.554687500000 -ico_hammer.tga 0.046875000000 0.531250000000 0.070312500000 0.554687500000 -ico_harmful.tga 0.070312500000 0.531250000000 0.093750000000 0.554687500000 -ico_hatred.tga 0.093750000000 0.531250000000 0.117187500000 0.554687500000 -ico_heal.tga 0.117187500000 0.531250000000 0.140625000000 0.554687500000 -ico_hit_rate.tga 0.140625000000 0.531250000000 0.164062500000 0.554687500000 -ico_incapacity.tga 0.164062500000 0.531250000000 0.187500000000 0.554687500000 -ico_intelligence.tga 0.187500000000 0.531250000000 0.210937500000 0.554687500000 -ico_interrupt.tga 0.210937500000 0.531250000000 0.234375000000 0.554687500000 -ico_invulnerability.tga 0.234375000000 0.531250000000 0.257812500000 0.554687500000 -ico_jewel_stone.tga 0.257812500000 0.531250000000 0.281250000000 0.554687500000 -ico_jewel_stone_support.tga 0.281250000000 0.531250000000 0.304687500000 0.554687500000 -ico_jungle.tga 0.304687500000 0.531250000000 0.328125000000 0.554687500000 -ico_lacustre.tga 0.328125000000 0.531250000000 0.351562500000 0.554687500000 -ico_landmark_bonus.tga 0.351562500000 0.531250000000 0.375000000000 0.554687500000 -ico_level.tga 0.375000000000 0.531250000000 0.398437500000 0.554687500000 -ico_lining.tga 0.398437500000 0.531250000000 0.421875000000 0.554687500000 -ico_location.tga 0.421875000000 0.531250000000 0.445312500000 0.554687500000 -ico_madness.tga 0.445312500000 0.531250000000 0.468750000000 0.554687500000 -ico_magic.tga 0.468750000000 0.531250000000 0.492187500000 0.554687500000 -ico_magic_action_buff.tga 0.492187500000 0.531250000000 0.515625000000 0.554687500000 -ico_magic_focus.tga 0.515625000000 0.531250000000 0.539062500000 0.554687500000 -ico_magic_target_buff.tga 0.539062500000 0.531250000000 0.562500000000 0.554687500000 -ico_melee_action_buff.tga 0.562500000000 0.531250000000 0.585937500000 0.554687500000 -ico_melee_target_buff.tga 0.585937500000 0.531250000000 0.609375000000 0.554687500000 -ico_mental.tga 0.609375000000 0.531250000000 0.632812500000 0.554687500000 -no_action.tga 0.632812500000 0.531250000000 0.656250000000 0.554687500000 -op_back.tga 0.656250000000 0.531250000000 0.679687500000 0.554687500000 -op_over_break.tga 0.679687500000 0.531250000000 0.703125000000 0.554687500000 -op_over_less.tga 0.703125000000 0.531250000000 0.726562500000 0.554687500000 -op_over_more.tga 0.914062500000 0.539062500000 0.937500000000 0.562500000000 -ico_metabolism.tga 0.726562500000 0.546875000000 0.750000000000 0.570312500000 -pa_back.tga 0.750000000000 0.546875000000 0.773437500000 0.570312500000 -ico_mezz.tga 0.773437500000 0.546875000000 0.796875000000 0.570312500000 -ico_misfortune.tga 0.796875000000 0.546875000000 0.820312500000 0.570312500000 -BK_magie_noire_brick.tga 0.820312500000 0.546875000000 0.843750000000 0.570312500000 -pa_over_break.tga 0.843750000000 0.546875000000 0.867187500000 0.570312500000 -pa_over_less.tga 0.867187500000 0.546875000000 0.890625000000 0.570312500000 -pa_over_more.tga 0.890625000000 0.546875000000 0.914062500000 0.570312500000 -BK_tryker_brick.tga 0.937500000000 0.546875000000 0.960937500000 0.570312500000 -cp_back.tga 0.960937500000 0.546875000000 0.984375000000 0.570312500000 -cp_over_break.tga 0.000000000000 0.554687500000 0.023437500000 0.578125000000 -pvp_ally_0.tga 0.023437500000 0.554687500000 0.046875000000 0.578125000000 -pvp_ally_1.tga 0.046875000000 0.554687500000 0.070312500000 0.578125000000 -pvp_ally_2.tga 0.070312500000 0.554687500000 0.093750000000 0.578125000000 -pvp_ally_3.tga 0.093750000000 0.554687500000 0.117187500000 0.578125000000 -pvp_ally_4.tga 0.117187500000 0.554687500000 0.140625000000 0.578125000000 -pvp_ally_6.tga 0.140625000000 0.554687500000 0.164062500000 0.578125000000 -pvp_ally_primas.tga 0.164062500000 0.554687500000 0.187500000000 0.578125000000 -pvp_ally_ranger.tga 0.187500000000 0.554687500000 0.210937500000 0.578125000000 -cp_over_less.tga 0.210937500000 0.554687500000 0.234375000000 0.578125000000 -cp_over_more.tga 0.234375000000 0.554687500000 0.257812500000 0.578125000000 -cp_over_opening.tga 0.257812500000 0.554687500000 0.281250000000 0.578125000000 -cp_over_opening_2.tga 0.281250000000 0.554687500000 0.304687500000 0.578125000000 -pvp_enemy_0.tga 0.304687500000 0.554687500000 0.328125000000 0.578125000000 -pvp_enemy_1.tga 0.328125000000 0.554687500000 0.351562500000 0.578125000000 -pvp_enemy_2.tga 0.351562500000 0.554687500000 0.375000000000 0.578125000000 -pvp_enemy_3.tga 0.375000000000 0.554687500000 0.398437500000 0.578125000000 -pvp_enemy_4.tga 0.398437500000 0.554687500000 0.421875000000 0.578125000000 -pvp_enemy_6.tga 0.421875000000 0.554687500000 0.445312500000 0.578125000000 -pvp_enemy_marauder.tga 0.445312500000 0.554687500000 0.468750000000 0.578125000000 -pvp_enemy_trytonist.tga 0.468750000000 0.554687500000 0.492187500000 0.578125000000 -bg_downloader.tga 0.492187500000 0.554687500000 0.515625000000 0.578125000000 -BK_zorai_brick.tga 0.515625000000 0.554687500000 0.539062500000 0.578125000000 -ef_back.tga 0.539062500000 0.554687500000 0.562500000000 0.578125000000 -ef_over_break.tga 0.562500000000 0.554687500000 0.585937500000 0.578125000000 -ico_move.tga 0.585937500000 0.554687500000 0.609375000000 0.578125000000 -ico_multiple_spots.tga 0.609375000000 0.554687500000 0.632812500000 0.578125000000 -ico_multi_fight.tga 0.632812500000 0.554687500000 0.656250000000 0.578125000000 -ef_over_less.tga 0.656250000000 0.554687500000 0.679687500000 0.578125000000 -ico_opening_hit.tga 0.679687500000 0.554687500000 0.703125000000 0.578125000000 -ico_over_autumn.tga 0.703125000000 0.554687500000 0.726562500000 0.578125000000 -ico_over_degenerated.tga 0.914062500000 0.562500000000 0.937500000000 0.585937500000 -ico_over_fauna.tga 0.726562500000 0.570312500000 0.750000000000 0.593750000000 -ico_over_flora.tga 0.750000000000 0.570312500000 0.773437500000 0.593750000000 -ico_over_hit_arms.tga 0.773437500000 0.570312500000 0.796875000000 0.593750000000 -ico_over_hit_chest.tga 0.796875000000 0.570312500000 0.820312500000 0.593750000000 -ico_over_hit_feet.tga 0.820312500000 0.570312500000 0.843750000000 0.593750000000 -ico_over_hit_feet_hands.tga 0.843750000000 0.570312500000 0.867187500000 0.593750000000 -ico_over_hit_feet_head.tga 0.867187500000 0.570312500000 0.890625000000 0.593750000000 -ico_over_hit_feet_x2.tga 0.890625000000 0.570312500000 0.914062500000 0.593750000000 -ico_over_hit_feint_x3.tga 0.937500000000 0.570312500000 0.960937500000 0.593750000000 -ico_over_hit_hands.tga 0.960937500000 0.570312500000 0.984375000000 0.593750000000 -ico_over_hit_hands_chest.tga 0.000000000000 0.578125000000 0.023437500000 0.601562500000 -ico_over_hit_hands_head.tga 0.023437500000 0.578125000000 0.046875000000 0.601562500000 -ico_over_hit_head.tga 0.046875000000 0.578125000000 0.070312500000 0.601562500000 -ico_over_hit_head_x3.tga 0.070312500000 0.578125000000 0.093750000000 0.601562500000 -ico_over_hit_legs.tga 0.093750000000 0.578125000000 0.117187500000 0.601562500000 -ico_over_homin.tga 0.117187500000 0.578125000000 0.140625000000 0.601562500000 -ico_over_kitin.tga 0.140625000000 0.578125000000 0.164062500000 0.601562500000 -ico_over_magic.tga 0.164062500000 0.578125000000 0.187500000000 0.601562500000 -ico_over_melee.tga 0.187500000000 0.578125000000 0.210937500000 0.601562500000 -ico_over_racial.tga 0.210937500000 0.578125000000 0.234375000000 0.601562500000 -ico_over_range.tga 0.234375000000 0.578125000000 0.257812500000 0.601562500000 -ico_over_special.tga 0.257812500000 0.578125000000 0.281250000000 0.601562500000 -ico_over_spring.tga 0.281250000000 0.578125000000 0.304687500000 0.601562500000 -ico_over_summer.tga 0.304687500000 0.578125000000 0.328125000000 0.601562500000 -ico_over_winter.tga 0.328125000000 0.578125000000 0.351562500000 0.601562500000 -ico_parry.tga 0.351562500000 0.578125000000 0.375000000000 0.601562500000 -ico_piercing.tga 0.375000000000 0.578125000000 0.398437500000 0.601562500000 -ico_pointe.tga 0.398437500000 0.578125000000 0.421875000000 0.601562500000 -ico_poison.tga 0.421875000000 0.578125000000 0.445312500000 0.601562500000 -ico_power.tga 0.445312500000 0.578125000000 0.468750000000 0.601562500000 -ico_preservation.tga 0.468750000000 0.578125000000 0.492187500000 0.601562500000 -ico_primal.tga 0.492187500000 0.578125000000 0.515625000000 0.601562500000 -ico_prime_roots.tga 0.515625000000 0.578125000000 0.539062500000 0.601562500000 -ico_private.tga 0.539062500000 0.578125000000 0.562500000000 0.601562500000 -ico_prospecting.tga 0.562500000000 0.578125000000 0.585937500000 0.601562500000 -ico_quality.tga 0.585937500000 0.578125000000 0.609375000000 0.601562500000 -ef_over_more.tga 0.609375000000 0.578125000000 0.632812500000 0.601562500000 -ico_range.tga 0.632812500000 0.578125000000 0.656250000000 0.601562500000 -ico_range_action_buff.tga 0.656250000000 0.578125000000 0.679687500000 0.601562500000 -ico_range_target_buff.tga 0.679687500000 0.578125000000 0.703125000000 0.601562500000 -ico_ricochet.tga 0.703125000000 0.578125000000 0.726562500000 0.601562500000 -ico_root.tga 0.914062500000 0.585937500000 0.937500000000 0.609375000000 -ico_rot.tga 0.726562500000 0.593750000000 0.750000000000 0.617187500000 -ico_safe.tga 0.750000000000 0.593750000000 0.773437500000 0.617187500000 -ico_sap.tga 0.773437500000 0.593750000000 0.796875000000 0.617187500000 -ico_self_damage.tga 0.796875000000 0.593750000000 0.820312500000 0.617187500000 -ico_shaft.tga 0.820312500000 0.593750000000 0.843750000000 0.617187500000 -ico_shielding.tga 0.843750000000 0.593750000000 0.867187500000 0.617187500000 -ico_shield_buff.tga 0.867187500000 0.593750000000 0.890625000000 0.617187500000 -ico_shield_up.tga 0.890625000000 0.593750000000 0.914062500000 0.617187500000 -ico_shockwave.tga 0.937500000000 0.593750000000 0.960937500000 0.617187500000 -ico_sickness.tga 0.960937500000 0.593750000000 0.984375000000 0.617187500000 -ico_slashing.tga 0.000000000000 0.601562500000 0.023437500000 0.625000000000 -ico_slow.tga 0.023437500000 0.601562500000 0.046875000000 0.625000000000 -ico_soft_spot.tga 0.046875000000 0.601562500000 0.070312500000 0.625000000000 -ico_source_time.tga 0.070312500000 0.601562500000 0.093750000000 0.625000000000 -ico_speed.tga 0.093750000000 0.601562500000 0.117187500000 0.625000000000 -ico_speeding_up.tga 0.117187500000 0.601562500000 0.140625000000 0.625000000000 -ico_spell_break.tga 0.140625000000 0.601562500000 0.164062500000 0.625000000000 -fo_back.tga 0.164062500000 0.601562500000 0.187500000000 0.625000000000 -ico_spray.tga 0.187500000000 0.601562500000 0.210937500000 0.625000000000 -ico_spying.tga 0.210937500000 0.601562500000 0.234375000000 0.625000000000 -ico_stamina.tga 0.234375000000 0.601562500000 0.257812500000 0.625000000000 -ico_strength.tga 0.257812500000 0.601562500000 0.281250000000 0.625000000000 -ico_stuffing.tga 0.281250000000 0.601562500000 0.304687500000 0.625000000000 -ico_stunn.tga 0.304687500000 0.601562500000 0.328125000000 0.625000000000 -fo_over.tga 0.328125000000 0.601562500000 0.351562500000 0.625000000000 -fp_ammo.tga 0.351562500000 0.601562500000 0.375000000000 0.625000000000 -fp_armor.tga 0.375000000000 0.601562500000 0.398437500000 0.625000000000 -fp_building.tga 0.398437500000 0.601562500000 0.421875000000 0.625000000000 -fp_jewel.tga 0.421875000000 0.601562500000 0.445312500000 0.625000000000 -fp_melee.tga 0.445312500000 0.601562500000 0.468750000000 0.625000000000 -fp_over.tga 0.468750000000 0.601562500000 0.492187500000 0.625000000000 -fp_range.tga 0.492187500000 0.601562500000 0.515625000000 0.625000000000 -fp_shield.tga 0.515625000000 0.601562500000 0.539062500000 0.625000000000 -fp_tools.tga 0.539062500000 0.601562500000 0.562500000000 0.625000000000 -brick_default.tga 0.562500000000 0.601562500000 0.585937500000 0.625000000000 -ico_taunt.tga 0.585937500000 0.601562500000 0.609375000000 0.625000000000 -tb_action_attack.tga 0.609375000000 0.601562500000 0.632812500000 0.625000000000 -tb_action_config.tga 0.632812500000 0.601562500000 0.656250000000 0.625000000000 -tb_action_disband.tga 0.656250000000 0.601562500000 0.679687500000 0.625000000000 -tb_action_disengage.tga 0.679687500000 0.601562500000 0.703125000000 0.625000000000 -tb_action_extract.tga 0.703125000000 0.601562500000 0.726562500000 0.625000000000 -tb_action_invite.tga 0.914062500000 0.609375000000 0.937500000000 0.632812500000 -tb_action_kick.tga 0.726562500000 0.617187500000 0.750000000000 0.640625000000 -tb_action_move.tga 0.750000000000 0.617187500000 0.773437500000 0.640625000000 -tb_action_run.tga 0.773437500000 0.617187500000 0.796875000000 0.640625000000 -tb_action_sit.tga 0.796875000000 0.617187500000 0.820312500000 0.640625000000 -tb_action_stand.tga 0.820312500000 0.617187500000 0.843750000000 0.640625000000 -tb_action_stop.tga 0.843750000000 0.617187500000 0.867187500000 0.640625000000 -tb_action_talk.tga 0.867187500000 0.617187500000 0.890625000000 0.640625000000 -tb_action_walk.tga 0.890625000000 0.617187500000 0.914062500000 0.640625000000 -tb_animals.tga 0.937500000000 0.617187500000 0.960937500000 0.640625000000 -tb_config.tga 0.960937500000 0.617187500000 0.984375000000 0.640625000000 -tb_connection.tga 0.000000000000 0.625000000000 0.023437500000 0.648437500000 -tb_contacts.tga 0.023437500000 0.625000000000 0.046875000000 0.648437500000 -tb_desk_1.tga 0.046875000000 0.625000000000 0.070312500000 0.648437500000 -tb_desk_2.tga 0.070312500000 0.625000000000 0.093750000000 0.648437500000 -tb_desk_3.tga 0.093750000000 0.625000000000 0.117187500000 0.648437500000 -tb_desk_4.tga 0.117187500000 0.625000000000 0.140625000000 0.648437500000 -tb_faction.tga 0.140625000000 0.625000000000 0.164062500000 0.648437500000 -tb_forum.tga 0.164062500000 0.625000000000 0.187500000000 0.648437500000 -tb_guild.tga 0.187500000000 0.625000000000 0.210937500000 0.648437500000 -TB_help2.tga 0.210937500000 0.625000000000 0.234375000000 0.648437500000 -tb_keys.tga 0.234375000000 0.625000000000 0.257812500000 0.648437500000 -tb_macros.tga 0.257812500000 0.625000000000 0.281250000000 0.648437500000 -tb_mail.tga 0.281250000000 0.625000000000 0.304687500000 0.648437500000 -tb_mode_dodge.tga 0.304687500000 0.625000000000 0.328125000000 0.648437500000 -tb_mode_parry.tga 0.328125000000 0.625000000000 0.351562500000 0.648437500000 -tb_over.tga 0.351562500000 0.625000000000 0.375000000000 0.648437500000 -tb_support.tga 0.375000000000 0.625000000000 0.398437500000 0.648437500000 -tb_team.tga 0.398437500000 0.625000000000 0.421875000000 0.648437500000 -tb_windows.tga 0.421875000000 0.625000000000 0.445312500000 0.648437500000 -ico_time.tga 0.445312500000 0.625000000000 0.468750000000 0.648437500000 -ico_time_bonus.tga 0.468750000000 0.625000000000 0.492187500000 0.648437500000 -ico_absorb_damage.tga 0.492187500000 0.625000000000 0.515625000000 0.648437500000 -ico_trigger.tga 0.515625000000 0.625000000000 0.539062500000 0.648437500000 -ico_umbrella.tga 0.539062500000 0.625000000000 0.562500000000 0.648437500000 -ico_use_enchantement.tga 0.562500000000 0.625000000000 0.585937500000 0.648437500000 -ico_vampire.tga 0.585937500000 0.625000000000 0.609375000000 0.648437500000 -ico_visibility.tga 0.609375000000 0.625000000000 0.632812500000 0.648437500000 -ico_war_cry.tga 0.632812500000 0.625000000000 0.656250000000 0.648437500000 -ico_weight.tga 0.656250000000 0.625000000000 0.679687500000 0.648437500000 -ico_wellbalanced.tga 0.679687500000 0.625000000000 0.703125000000 0.648437500000 -ico_will.tga 0.703125000000 0.625000000000 0.726562500000 0.648437500000 -ico_windding.tga 0.914062500000 0.632812500000 0.937500000000 0.656250000000 -ico_wisdom.tga 0.726562500000 0.640625000000 0.750000000000 0.664062500000 -ico_accurate.tga 0.750000000000 0.640625000000 0.773437500000 0.664062500000 -ico_acid.tga 0.773437500000 0.640625000000 0.796875000000 0.664062500000 -ico_aim.tga 0.796875000000 0.640625000000 0.820312500000 0.664062500000 -ico_aim_bird_wings.tga 0.820312500000 0.640625000000 0.843750000000 0.664062500000 -ico_aim_flying_kitin_abdomen.tga 0.843750000000 0.640625000000 0.867187500000 0.664062500000 -ico_aim_homin_arms.tga 0.867187500000 0.640625000000 0.890625000000 0.664062500000 -ico_aim_homin_chest.tga 0.890625000000 0.640625000000 0.914062500000 0.664062500000 -mf_back.tga 0.937500000000 0.640625000000 0.960937500000 0.664062500000 -us_back_0.tga 0.960937500000 0.640625000000 0.984375000000 0.664062500000 -us_back_1.tga 0.000000000000 0.648437500000 0.023437500000 0.671875000000 -us_back_2.tga 0.023437500000 0.648437500000 0.046875000000 0.671875000000 -us_back_3.tga 0.046875000000 0.648437500000 0.070312500000 0.671875000000 -us_back_4.tga 0.070312500000 0.648437500000 0.093750000000 0.671875000000 -us_back_5.tga 0.093750000000 0.648437500000 0.117187500000 0.671875000000 -us_back_6.tga 0.117187500000 0.648437500000 0.140625000000 0.671875000000 -us_back_7.tga 0.140625000000 0.648437500000 0.164062500000 0.671875000000 -us_back_8.tga 0.164062500000 0.648437500000 0.187500000000 0.671875000000 -us_back_9.tga 0.187500000000 0.648437500000 0.210937500000 0.671875000000 -us_ico_0.tga 0.210937500000 0.648437500000 0.234375000000 0.671875000000 -us_ico_1.tga 0.234375000000 0.648437500000 0.257812500000 0.671875000000 -us_ico_2.tga 0.257812500000 0.648437500000 0.281250000000 0.671875000000 -us_ico_3.tga 0.281250000000 0.648437500000 0.304687500000 0.671875000000 -us_ico_4.tga 0.304687500000 0.648437500000 0.328125000000 0.671875000000 -us_ico_5.tga 0.328125000000 0.648437500000 0.351562500000 0.671875000000 -us_ico_6.tga 0.351562500000 0.648437500000 0.375000000000 0.671875000000 -us_ico_7.tga 0.375000000000 0.648437500000 0.398437500000 0.671875000000 -us_ico_8.tga 0.398437500000 0.648437500000 0.421875000000 0.671875000000 -us_ico_9.tga 0.421875000000 0.648437500000 0.445312500000 0.671875000000 -us_over_0.tga 0.445312500000 0.648437500000 0.468750000000 0.671875000000 -us_over_1.tga 0.468750000000 0.648437500000 0.492187500000 0.671875000000 -us_over_2.tga 0.492187500000 0.648437500000 0.515625000000 0.671875000000 -us_over_3.tga 0.515625000000 0.648437500000 0.539062500000 0.671875000000 -us_over_4.tga 0.539062500000 0.648437500000 0.562500000000 0.671875000000 -mf_over.tga 0.562500000000 0.648437500000 0.585937500000 0.671875000000 -ico_aim_homin_feet.tga 0.585937500000 0.648437500000 0.609375000000 0.671875000000 -ico_aim_homin_feint.tga 0.609375000000 0.648437500000 0.632812500000 0.671875000000 -ico_aim_homin_hands.tga 0.632812500000 0.648437500000 0.656250000000 0.671875000000 -ico_aim_homin_head.tga 0.656250000000 0.648437500000 0.679687500000 0.671875000000 -ico_aim_homin_legs.tga 0.679687500000 0.648437500000 0.703125000000 0.671875000000 -mp3.tga 0.703125000000 0.648437500000 0.726562500000 0.671875000000 -W_slot_shortcut_id0.tga 0.914062500000 0.656250000000 0.937500000000 0.679687500000 -W_slot_shortcut_id1.tga 0.726562500000 0.664062500000 0.750000000000 0.687500000000 -W_slot_shortcut_id2.tga 0.750000000000 0.664062500000 0.773437500000 0.687500000000 -W_slot_shortcut_id3.tga 0.773437500000 0.664062500000 0.796875000000 0.687500000000 -W_slot_shortcut_id4.tga 0.796875000000 0.664062500000 0.820312500000 0.687500000000 -W_slot_shortcut_id5.tga 0.820312500000 0.664062500000 0.843750000000 0.687500000000 -W_slot_shortcut_id6.tga 0.843750000000 0.664062500000 0.867187500000 0.687500000000 -W_slot_shortcut_id7.tga 0.867187500000 0.664062500000 0.890625000000 0.687500000000 -W_slot_shortcut_id8.tga 0.890625000000 0.664062500000 0.914062500000 0.687500000000 -W_slot_shortcut_id9.tga 0.937500000000 0.664062500000 0.960937500000 0.687500000000 -w_slot_shortcut_shift_id0.tga 0.960937500000 0.664062500000 0.984375000000 0.687500000000 -w_slot_shortcut_shift_id1.tga 0.000000000000 0.671875000000 0.023437500000 0.695312500000 -w_slot_shortcut_shift_id2.tga 0.023437500000 0.671875000000 0.046875000000 0.695312500000 -w_slot_shortcut_shift_id3.tga 0.046875000000 0.671875000000 0.070312500000 0.695312500000 -w_slot_shortcut_shift_id4.tga 0.070312500000 0.671875000000 0.093750000000 0.695312500000 -w_slot_shortcut_shift_id5.tga 0.093750000000 0.671875000000 0.117187500000 0.695312500000 -w_slot_shortcut_shift_id6.tga 0.117187500000 0.671875000000 0.140625000000 0.695312500000 -w_slot_shortcut_shift_id7.tga 0.140625000000 0.671875000000 0.164062500000 0.695312500000 -w_slot_shortcut_shift_id8.tga 0.164062500000 0.671875000000 0.187500000000 0.695312500000 -w_slot_shortcut_shift_id9.tga 0.187500000000 0.671875000000 0.210937500000 0.695312500000 -ico_aim_kitin_head.tga 0.210937500000 0.671875000000 0.234375000000 0.695312500000 -ico_source_knowledge.tga 0.234375000000 0.671875000000 0.255859375000 0.695312500000 +ico_taunt.tga 0.976562500000 0.078125000000 1.000000000000 0.101562500000 +BK_generic_brick.tga 0.976562500000 0.101562500000 1.000000000000 0.125000000000 +bk_aura.tga 0.976562500000 0.125000000000 1.000000000000 0.148437500000 +bk_outpost_brick.tga 0.976562500000 0.148437500000 1.000000000000 0.171875000000 +bk_power.tga 0.976562500000 0.171875000000 1.000000000000 0.195312500000 +no_action.tga 0.976562500000 0.195312500000 1.000000000000 0.218750000000 +no_pvp.tga 0.976562500000 0.218750000000 1.000000000000 0.242187500000 +op_back.tga 0.976562500000 0.242187500000 1.000000000000 0.265625000000 +op_over_break.tga 0.976562500000 0.265625000000 1.000000000000 0.289062500000 +op_over_less.tga 0.976562500000 0.289062500000 1.000000000000 0.312500000000 +op_over_more.tga 0.976562500000 0.312500000000 1.000000000000 0.335937500000 +bk_conso.tga 0.976562500000 0.335937500000 1.000000000000 0.359375000000 +pa_back.tga 0.976562500000 0.359375000000 1.000000000000 0.382812500000 +2h_over.tga 0.976562500000 0.382812500000 1.000000000000 0.406250000000 +1h_over.tga 0.976562500000 0.406250000000 1.000000000000 0.429687500000 +pvp_duel.tga 0.976562500000 0.429687500000 1.000000000000 0.453125000000 +pvp_enemy_0.tga 0.976562500000 0.453125000000 1.000000000000 0.476562500000 +pvp_enemy_1.tga 0.960937500000 0.476562500000 0.984375000000 0.500000000000 +pvp_enemy_2.tga 0.929687500000 0.492187500000 0.953125000000 0.515625000000 +pvp_enemy_3.tga 0.742187500000 0.500000000000 0.765625000000 0.523437500000 +pvp_enemy_4.tga 0.765625000000 0.500000000000 0.789062500000 0.523437500000 +pvp_enemy_6.tga 0.789062500000 0.500000000000 0.812500000000 0.523437500000 +pvp_enemy_flag.tga 0.812500000000 0.500000000000 0.835937500000 0.523437500000 +pvp_enemy_marauder.tga 0.835937500000 0.500000000000 0.859375000000 0.523437500000 +pvp_enemy_tag.tga 0.859375000000 0.500000000000 0.882812500000 0.523437500000 +tb_action_attack.tga 0.882812500000 0.500000000000 0.906250000000 0.523437500000 +tb_action_config.tga 0.906250000000 0.500000000000 0.929687500000 0.523437500000 +tb_action_disband.tga 0.953125000000 0.500000000000 0.976562500000 0.523437500000 +tb_action_disengage.tga 0.976562500000 0.500000000000 1.000000000000 0.523437500000 +tb_action_extract.tga 0.000000000000 0.507812500000 0.023437500000 0.531250000000 +tb_action_invite.tga 0.023437500000 0.507812500000 0.046875000000 0.531250000000 +tb_action_kick.tga 0.046875000000 0.507812500000 0.070312500000 0.531250000000 +tb_action_move.tga 0.070312500000 0.507812500000 0.093750000000 0.531250000000 +tb_action_run.tga 0.093750000000 0.507812500000 0.117187500000 0.531250000000 +tb_action_sit.tga 0.117187500000 0.507812500000 0.140625000000 0.531250000000 +tb_action_stand.tga 0.140625000000 0.507812500000 0.164062500000 0.531250000000 +tb_action_stop.tga 0.164062500000 0.507812500000 0.187500000000 0.531250000000 +tb_action_talk.tga 0.187500000000 0.507812500000 0.210937500000 0.531250000000 +tb_action_walk.tga 0.210937500000 0.507812500000 0.234375000000 0.531250000000 +ico_armor_penalty.tga 0.234375000000 0.507812500000 0.257812500000 0.531250000000 +ico_armor_shell.tga 0.257812500000 0.507812500000 0.281250000000 0.531250000000 +ico_atys.tga 0.281250000000 0.507812500000 0.304687500000 0.531250000000 +ico_atysian.tga 0.304687500000 0.507812500000 0.328125000000 0.531250000000 +ico_balance_hp.tga 0.328125000000 0.507812500000 0.351562500000 0.531250000000 +ico_barrel.tga 0.351562500000 0.507812500000 0.375000000000 0.531250000000 +ico_bash.tga 0.375000000000 0.507812500000 0.398437500000 0.531250000000 +ico_berserk.tga 0.398437500000 0.507812500000 0.421875000000 0.531250000000 +ico_blade.tga 0.421875000000 0.507812500000 0.445312500000 0.531250000000 +ico_bleeding.tga 0.445312500000 0.507812500000 0.468750000000 0.531250000000 +ico_blind.tga 0.468750000000 0.507812500000 0.492187500000 0.531250000000 +ico_blunt.tga 0.492187500000 0.507812500000 0.515625000000 0.531250000000 +ico_bomb.tga 0.515625000000 0.507812500000 0.539062500000 0.531250000000 +pvp_enemy_trytonist.tga 0.539062500000 0.507812500000 0.562500000000 0.531250000000 +ico_celestial.tga 0.562500000000 0.507812500000 0.585937500000 0.531250000000 +ico_circular_attack.tga 0.585937500000 0.507812500000 0.609375000000 0.531250000000 +ico_cold.tga 0.609375000000 0.507812500000 0.632812500000 0.531250000000 +ico_concentration.tga 0.632812500000 0.507812500000 0.656250000000 0.531250000000 +pvp_flag.tga 0.656250000000 0.507812500000 0.679687500000 0.531250000000 +ico_constitution.tga 0.679687500000 0.507812500000 0.703125000000 0.531250000000 +ico_counterweight.tga 0.703125000000 0.507812500000 0.726562500000 0.531250000000 +ico_craft_buff.tga 0.929687500000 0.515625000000 0.953125000000 0.539062500000 +ico_create_sapload.tga 0.726562500000 0.523437500000 0.750000000000 0.546875000000 +ico_curse.tga 0.750000000000 0.523437500000 0.773437500000 0.546875000000 +ico_debuff.tga 0.773437500000 0.523437500000 0.796875000000 0.546875000000 +ico_debuff_resist.tga 0.796875000000 0.523437500000 0.820312500000 0.546875000000 +ico_debuff_skill.tga 0.820312500000 0.523437500000 0.843750000000 0.546875000000 +ico_desert.tga 0.843750000000 0.523437500000 0.867187500000 0.546875000000 +ico_dexterity.tga 0.867187500000 0.523437500000 0.890625000000 0.546875000000 +ico_disarm.tga 0.890625000000 0.523437500000 0.914062500000 0.546875000000 +ico_dodge.tga 0.953125000000 0.523437500000 0.976562500000 0.546875000000 +ico_dot.tga 0.976562500000 0.523437500000 1.000000000000 0.546875000000 +ico_electric.tga 0.000000000000 0.531250000000 0.023437500000 0.554687500000 +ico_explosif.tga 0.023437500000 0.531250000000 0.046875000000 0.554687500000 +ico_extracting.tga 0.046875000000 0.531250000000 0.070312500000 0.554687500000 +ico_fear.tga 0.070312500000 0.531250000000 0.093750000000 0.554687500000 +ico_feint.tga 0.093750000000 0.531250000000 0.117187500000 0.554687500000 +ico_fire.tga 0.117187500000 0.531250000000 0.140625000000 0.554687500000 +ico_firing_pin.tga 0.140625000000 0.531250000000 0.164062500000 0.554687500000 +pvp_neutral.tga 0.164062500000 0.531250000000 0.187500000000 0.554687500000 +pvp_tag.tga 0.187500000000 0.531250000000 0.210937500000 0.554687500000 +BK_magie_noire_brick.tga 0.210937500000 0.531250000000 0.234375000000 0.554687500000 +cp_back.tga 0.234375000000 0.531250000000 0.257812500000 0.554687500000 +cp_over_break.tga 0.257812500000 0.531250000000 0.281250000000 0.554687500000 +cp_over_less.tga 0.281250000000 0.531250000000 0.304687500000 0.554687500000 +ico_focus.tga 0.304687500000 0.531250000000 0.328125000000 0.554687500000 +ico_forage_buff.tga 0.328125000000 0.531250000000 0.351562500000 0.554687500000 +ico_forbid_item.tga 0.351562500000 0.531250000000 0.375000000000 0.554687500000 +ico_forest.tga 0.375000000000 0.531250000000 0.398437500000 0.554687500000 +ico_jungle.tga 0.398437500000 0.531250000000 0.421875000000 0.554687500000 +ico_lacustre.tga 0.421875000000 0.531250000000 0.445312500000 0.554687500000 +ico_landmark_bonus.tga 0.445312500000 0.531250000000 0.468750000000 0.554687500000 +ico_level.tga 0.468750000000 0.531250000000 0.492187500000 0.554687500000 +ico_lining.tga 0.492187500000 0.531250000000 0.515625000000 0.554687500000 +ico_location.tga 0.515625000000 0.531250000000 0.539062500000 0.554687500000 +ico_madness.tga 0.539062500000 0.531250000000 0.562500000000 0.554687500000 +ico_magic.tga 0.562500000000 0.531250000000 0.585937500000 0.554687500000 +ico_magic_action_buff.tga 0.585937500000 0.531250000000 0.609375000000 0.554687500000 +ico_magic_focus.tga 0.609375000000 0.531250000000 0.632812500000 0.554687500000 +ico_magic_target_buff.tga 0.632812500000 0.531250000000 0.656250000000 0.554687500000 +ico_melee_action_buff.tga 0.656250000000 0.531250000000 0.679687500000 0.554687500000 +ico_melee_target_buff.tga 0.679687500000 0.531250000000 0.703125000000 0.554687500000 +ico_mental.tga 0.703125000000 0.531250000000 0.726562500000 0.554687500000 +ico_metabolism.tga 0.914062500000 0.539062500000 0.937500000000 0.562500000000 +ico_mezz.tga 0.726562500000 0.546875000000 0.750000000000 0.570312500000 +cp_over_more.tga 0.750000000000 0.546875000000 0.773437500000 0.570312500000 +cp_over_opening.tga 0.773437500000 0.546875000000 0.796875000000 0.570312500000 +tb_animals.tga 0.796875000000 0.546875000000 0.820312500000 0.570312500000 +cp_over_opening_2.tga 0.820312500000 0.546875000000 0.843750000000 0.570312500000 +us_back_9.tga 0.843750000000 0.546875000000 0.867187500000 0.570312500000 +BK_tryker_brick.tga 0.867187500000 0.546875000000 0.890625000000 0.570312500000 +ico_spray.tga 0.890625000000 0.546875000000 0.914062500000 0.570312500000 +ico_spying.tga 0.937500000000 0.546875000000 0.960937500000 0.570312500000 +ico_stamina.tga 0.960937500000 0.546875000000 0.984375000000 0.570312500000 +ico_strength.tga 0.000000000000 0.554687500000 0.023437500000 0.578125000000 +ico_stuffing.tga 0.023437500000 0.554687500000 0.046875000000 0.578125000000 +ico_stunn.tga 0.046875000000 0.554687500000 0.070312500000 0.578125000000 +ico_move.tga 0.070312500000 0.554687500000 0.093750000000 0.578125000000 +ico_multiple_spots.tga 0.093750000000 0.554687500000 0.117187500000 0.578125000000 +ico_multi_fight.tga 0.117187500000 0.554687500000 0.140625000000 0.578125000000 +ico_opening_hit.tga 0.140625000000 0.554687500000 0.164062500000 0.578125000000 +ico_over_autumn.tga 0.164062500000 0.554687500000 0.187500000000 0.578125000000 +ico_over_degenerated.tga 0.187500000000 0.554687500000 0.210937500000 0.578125000000 +ico_over_fauna.tga 0.210937500000 0.554687500000 0.234375000000 0.578125000000 +ico_over_flora.tga 0.234375000000 0.554687500000 0.257812500000 0.578125000000 +ico_over_hit_arms.tga 0.257812500000 0.554687500000 0.281250000000 0.578125000000 +ico_over_hit_chest.tga 0.281250000000 0.554687500000 0.304687500000 0.578125000000 +ico_over_hit_feet.tga 0.304687500000 0.554687500000 0.328125000000 0.578125000000 +ico_over_hit_feet_hands.tga 0.328125000000 0.554687500000 0.351562500000 0.578125000000 +ico_over_hit_feet_head.tga 0.351562500000 0.554687500000 0.375000000000 0.578125000000 +ico_over_hit_feet_x2.tga 0.375000000000 0.554687500000 0.398437500000 0.578125000000 +ico_over_hit_feint_x3.tga 0.398437500000 0.554687500000 0.421875000000 0.578125000000 +ico_over_hit_hands.tga 0.421875000000 0.554687500000 0.445312500000 0.578125000000 +ico_over_hit_hands_chest.tga 0.445312500000 0.554687500000 0.468750000000 0.578125000000 +ico_over_hit_hands_head.tga 0.468750000000 0.554687500000 0.492187500000 0.578125000000 +ico_over_hit_head.tga 0.492187500000 0.554687500000 0.515625000000 0.578125000000 +ico_over_hit_legs.tga 0.515625000000 0.554687500000 0.539062500000 0.578125000000 +ico_over_homin.tga 0.539062500000 0.554687500000 0.562500000000 0.578125000000 +ico_over_kitin.tga 0.562500000000 0.554687500000 0.585937500000 0.578125000000 +ico_over_magic.tga 0.585937500000 0.554687500000 0.609375000000 0.578125000000 +ico_over_melee.tga 0.609375000000 0.554687500000 0.632812500000 0.578125000000 +ico_over_racial.tga 0.632812500000 0.554687500000 0.656250000000 0.578125000000 +ico_over_range.tga 0.656250000000 0.554687500000 0.679687500000 0.578125000000 +ico_over_special.tga 0.679687500000 0.554687500000 0.703125000000 0.578125000000 +ico_over_spring.tga 0.703125000000 0.554687500000 0.726562500000 0.578125000000 +ico_over_summer.tga 0.914062500000 0.562500000000 0.937500000000 0.585937500000 +ico_over_winter.tga 0.726562500000 0.570312500000 0.750000000000 0.593750000000 +ico_parry.tga 0.750000000000 0.570312500000 0.773437500000 0.593750000000 +ico_piercing.tga 0.773437500000 0.570312500000 0.796875000000 0.593750000000 +ico_pointe.tga 0.796875000000 0.570312500000 0.820312500000 0.593750000000 +ico_poison.tga 0.820312500000 0.570312500000 0.843750000000 0.593750000000 +ico_power.tga 0.843750000000 0.570312500000 0.867187500000 0.593750000000 +ico_preservation.tga 0.867187500000 0.570312500000 0.890625000000 0.593750000000 +ico_prime_roots.tga 0.890625000000 0.570312500000 0.914062500000 0.593750000000 +ico_private.tga 0.937500000000 0.570312500000 0.960937500000 0.593750000000 +ico_prospecting.tga 0.960937500000 0.570312500000 0.984375000000 0.593750000000 +ico_quality.tga 0.000000000000 0.578125000000 0.023437500000 0.601562500000 +BK_fyros_brick.tga 0.023437500000 0.578125000000 0.046875000000 0.601562500000 +ico_range.tga 0.046875000000 0.578125000000 0.070312500000 0.601562500000 +ico_range_action_buff.tga 0.070312500000 0.578125000000 0.093750000000 0.601562500000 +ico_range_target_buff.tga 0.093750000000 0.578125000000 0.117187500000 0.601562500000 +ico_ricochet.tga 0.117187500000 0.578125000000 0.140625000000 0.601562500000 +ico_root.tga 0.140625000000 0.578125000000 0.164062500000 0.601562500000 +ico_rot.tga 0.164062500000 0.578125000000 0.187500000000 0.601562500000 +ico_safe.tga 0.187500000000 0.578125000000 0.210937500000 0.601562500000 +ico_sap.tga 0.210937500000 0.578125000000 0.234375000000 0.601562500000 +ico_self_damage.tga 0.234375000000 0.578125000000 0.257812500000 0.601562500000 +ico_shaft.tga 0.257812500000 0.578125000000 0.281250000000 0.601562500000 +ico_shielding.tga 0.281250000000 0.578125000000 0.304687500000 0.601562500000 +ico_shield_buff.tga 0.304687500000 0.578125000000 0.328125000000 0.601562500000 +ico_shield_up.tga 0.328125000000 0.578125000000 0.351562500000 0.601562500000 +ico_shockwave.tga 0.351562500000 0.578125000000 0.375000000000 0.601562500000 +ico_sickness.tga 0.375000000000 0.578125000000 0.398437500000 0.601562500000 +ico_slashing.tga 0.398437500000 0.578125000000 0.421875000000 0.601562500000 +ico_slow.tga 0.421875000000 0.578125000000 0.445312500000 0.601562500000 +ico_soft_spot.tga 0.445312500000 0.578125000000 0.468750000000 0.601562500000 +ico_source_time.tga 0.468750000000 0.578125000000 0.492187500000 0.601562500000 +ico_speed.tga 0.492187500000 0.578125000000 0.515625000000 0.601562500000 +ico_speeding_up.tga 0.515625000000 0.578125000000 0.539062500000 0.601562500000 +ico_spell_break.tga 0.539062500000 0.578125000000 0.562500000000 0.601562500000 +fp_armor.tga 0.562500000000 0.578125000000 0.585937500000 0.601562500000 +fp_building.tga 0.585937500000 0.578125000000 0.609375000000 0.601562500000 +fp_jewel.tga 0.609375000000 0.578125000000 0.632812500000 0.601562500000 +fp_melee.tga 0.632812500000 0.578125000000 0.656250000000 0.601562500000 +fp_over.tga 0.656250000000 0.578125000000 0.679687500000 0.601562500000 +fp_range.tga 0.679687500000 0.578125000000 0.703125000000 0.601562500000 +fp_shield.tga 0.703125000000 0.578125000000 0.726562500000 0.601562500000 +fp_tools.tga 0.914062500000 0.585937500000 0.937500000000 0.609375000000 +ef_back.tga 0.726562500000 0.593750000000 0.750000000000 0.617187500000 +ico_absorb_damage.tga 0.750000000000 0.593750000000 0.773437500000 0.617187500000 +ico_accurate.tga 0.773437500000 0.593750000000 0.796875000000 0.617187500000 +ico_acid.tga 0.796875000000 0.593750000000 0.820312500000 0.617187500000 +ico_aim.tga 0.820312500000 0.593750000000 0.843750000000 0.617187500000 +ico_aim_bird_wings.tga 0.843750000000 0.593750000000 0.867187500000 0.617187500000 +ico_aim_flying_kitin_abdomen.tga 0.867187500000 0.593750000000 0.890625000000 0.617187500000 +ico_aim_homin_arms.tga 0.890625000000 0.593750000000 0.914062500000 0.617187500000 +ico_aim_homin_chest.tga 0.937500000000 0.593750000000 0.960937500000 0.617187500000 +ico_aim_homin_feet.tga 0.960937500000 0.593750000000 0.984375000000 0.617187500000 +ico_aim_homin_feint.tga 0.000000000000 0.601562500000 0.023437500000 0.625000000000 +ico_aim_homin_hands.tga 0.023437500000 0.601562500000 0.046875000000 0.625000000000 +ico_aim_homin_head.tga 0.046875000000 0.601562500000 0.070312500000 0.625000000000 +ico_aim_homin_legs.tga 0.070312500000 0.601562500000 0.093750000000 0.625000000000 +ico_aim_kitin_head.tga 0.093750000000 0.601562500000 0.117187500000 0.625000000000 +ef_over_break.tga 0.117187500000 0.601562500000 0.140625000000 0.625000000000 +ico_ammo_bullet.tga 0.140625000000 0.601562500000 0.164062500000 0.625000000000 +ico_ammo_jacket.tga 0.164062500000 0.601562500000 0.187500000000 0.625000000000 +ico_angle.tga 0.187500000000 0.601562500000 0.210937500000 0.625000000000 +ico_anti_magic_shield.tga 0.210937500000 0.601562500000 0.234375000000 0.625000000000 +ico_armor.tga 0.234375000000 0.601562500000 0.257812500000 0.625000000000 +ico_armor_clip.tga 0.257812500000 0.601562500000 0.281250000000 0.625000000000 +ico_armor_heavy.tga 0.281250000000 0.601562500000 0.304687500000 0.625000000000 +ico_armor_kitin.tga 0.304687500000 0.601562500000 0.328125000000 0.625000000000 +ico_armor_light.tga 0.328125000000 0.601562500000 0.351562500000 0.625000000000 +ef_over_less.tga 0.351562500000 0.601562500000 0.375000000000 0.625000000000 +ef_over_more.tga 0.375000000000 0.601562500000 0.398437500000 0.625000000000 +fo_back.tga 0.398437500000 0.601562500000 0.421875000000 0.625000000000 +fo_over.tga 0.421875000000 0.601562500000 0.445312500000 0.625000000000 +ico_gardening.tga 0.445312500000 0.601562500000 0.468750000000 0.625000000000 +ico_gentle.tga 0.468750000000 0.601562500000 0.492187500000 0.625000000000 +mp_over_link.tga 0.492187500000 0.601562500000 0.515625000000 0.625000000000 +ico_goo.tga 0.515625000000 0.601562500000 0.539062500000 0.625000000000 +us_back_0.tga 0.539062500000 0.601562500000 0.562500000000 0.625000000000 +us_back_1.tga 0.562500000000 0.601562500000 0.585937500000 0.625000000000 +us_back_2.tga 0.585937500000 0.601562500000 0.609375000000 0.625000000000 +us_back_3.tga 0.609375000000 0.601562500000 0.632812500000 0.625000000000 +us_back_4.tga 0.632812500000 0.601562500000 0.656250000000 0.625000000000 +us_back_5.tga 0.656250000000 0.601562500000 0.679687500000 0.625000000000 +us_back_6.tga 0.679687500000 0.601562500000 0.703125000000 0.625000000000 +us_back_7.tga 0.703125000000 0.601562500000 0.726562500000 0.625000000000 +us_back_8.tga 0.914062500000 0.609375000000 0.937500000000 0.632812500000 +tb_config.tga 0.726562500000 0.617187500000 0.750000000000 0.640625000000 +tb_connection.tga 0.750000000000 0.617187500000 0.773437500000 0.640625000000 +tb_contacts.tga 0.773437500000 0.617187500000 0.796875000000 0.640625000000 +tb_desk_1.tga 0.796875000000 0.617187500000 0.820312500000 0.640625000000 +tb_desk_2.tga 0.820312500000 0.617187500000 0.843750000000 0.640625000000 +tb_desk_3.tga 0.843750000000 0.617187500000 0.867187500000 0.640625000000 +tb_desk_4.tga 0.867187500000 0.617187500000 0.890625000000 0.640625000000 +tb_faction.tga 0.890625000000 0.617187500000 0.914062500000 0.640625000000 +tb_forum.tga 0.937500000000 0.617187500000 0.960937500000 0.640625000000 +tb_guild.tga 0.960937500000 0.617187500000 0.984375000000 0.640625000000 +TB_help2.tga 0.000000000000 0.625000000000 0.023437500000 0.648437500000 +tb_keys.tga 0.023437500000 0.625000000000 0.046875000000 0.648437500000 +tb_macros.tga 0.046875000000 0.625000000000 0.070312500000 0.648437500000 +tb_mail.tga 0.070312500000 0.625000000000 0.093750000000 0.648437500000 +tb_mode_dodge.tga 0.093750000000 0.625000000000 0.117187500000 0.648437500000 +tb_mode_parry.tga 0.117187500000 0.625000000000 0.140625000000 0.648437500000 +tb_over.tga 0.140625000000 0.625000000000 0.164062500000 0.648437500000 +tb_support.tga 0.164062500000 0.625000000000 0.187500000000 0.648437500000 +tb_team.tga 0.187500000000 0.625000000000 0.210937500000 0.648437500000 +tb_windows.tga 0.210937500000 0.625000000000 0.234375000000 0.648437500000 +ico_gripp.tga 0.234375000000 0.625000000000 0.257812500000 0.648437500000 +BK_zorai_brick.tga 0.257812500000 0.625000000000 0.281250000000 0.648437500000 +mf_back.tga 0.281250000000 0.625000000000 0.304687500000 0.648437500000 +mf_over.tga 0.304687500000 0.625000000000 0.328125000000 0.648437500000 +brick_default.tga 0.328125000000 0.625000000000 0.351562500000 0.648437500000 +ico_hammer.tga 0.351562500000 0.625000000000 0.375000000000 0.648437500000 +ico_harmful.tga 0.375000000000 0.625000000000 0.398437500000 0.648437500000 +ico_hatred.tga 0.398437500000 0.625000000000 0.421875000000 0.648437500000 +ico_heal.tga 0.421875000000 0.625000000000 0.445312500000 0.648437500000 +mp3.tga 0.445312500000 0.625000000000 0.468750000000 0.648437500000 +ico_hit_rate.tga 0.468750000000 0.625000000000 0.492187500000 0.648437500000 +mp_back_curative.tga 0.492187500000 0.625000000000 0.515625000000 0.648437500000 +mp_back_offensive.tga 0.515625000000 0.625000000000 0.539062500000 0.648437500000 +ico_time.tga 0.539062500000 0.625000000000 0.562500000000 0.648437500000 +ico_time_bonus.tga 0.562500000000 0.625000000000 0.585937500000 0.648437500000 +mp_back_selfonly.tga 0.585937500000 0.625000000000 0.609375000000 0.648437500000 +ico_trigger.tga 0.609375000000 0.625000000000 0.632812500000 0.648437500000 +ico_umbrella.tga 0.632812500000 0.625000000000 0.656250000000 0.648437500000 +ico_use_enchantement.tga 0.656250000000 0.625000000000 0.679687500000 0.648437500000 +ico_vampire.tga 0.679687500000 0.625000000000 0.703125000000 0.648437500000 +ico_visibility.tga 0.703125000000 0.625000000000 0.726562500000 0.648437500000 +ico_war_cry.tga 0.914062500000 0.632812500000 0.937500000000 0.656250000000 +ico_weight.tga 0.726562500000 0.640625000000 0.750000000000 0.664062500000 +ico_wellbalanced.tga 0.750000000000 0.640625000000 0.773437500000 0.664062500000 +ico_will.tga 0.773437500000 0.640625000000 0.796875000000 0.664062500000 +ico_windding.tga 0.796875000000 0.640625000000 0.820312500000 0.664062500000 +ico_wisdom.tga 0.820312500000 0.640625000000 0.843750000000 0.664062500000 +ico_incapacity.tga 0.843750000000 0.640625000000 0.867187500000 0.664062500000 +ico_intelligence.tga 0.867187500000 0.640625000000 0.890625000000 0.664062500000 +ico_interrupt.tga 0.890625000000 0.640625000000 0.914062500000 0.664062500000 +ico_invulnerability.tga 0.937500000000 0.640625000000 0.960937500000 0.664062500000 +ico_jewel_stone.tga 0.960937500000 0.640625000000 0.984375000000 0.664062500000 +us_ico_0.tga 0.000000000000 0.648437500000 0.023437500000 0.671875000000 +us_ico_1.tga 0.023437500000 0.648437500000 0.046875000000 0.671875000000 +us_ico_2.tga 0.046875000000 0.648437500000 0.070312500000 0.671875000000 +us_ico_3.tga 0.070312500000 0.648437500000 0.093750000000 0.671875000000 +us_ico_4.tga 0.093750000000 0.648437500000 0.117187500000 0.671875000000 +us_ico_5.tga 0.117187500000 0.648437500000 0.140625000000 0.671875000000 +us_ico_6.tga 0.140625000000 0.648437500000 0.164062500000 0.671875000000 +us_ico_7.tga 0.164062500000 0.648437500000 0.187500000000 0.671875000000 +us_ico_8.tga 0.187500000000 0.648437500000 0.210937500000 0.671875000000 +us_ico_9.tga 0.210937500000 0.648437500000 0.234375000000 0.671875000000 +us_over_0.tga 0.234375000000 0.648437500000 0.257812500000 0.671875000000 +us_over_1.tga 0.257812500000 0.648437500000 0.281250000000 0.671875000000 +us_over_2.tga 0.281250000000 0.648437500000 0.304687500000 0.671875000000 +us_over_3.tga 0.304687500000 0.648437500000 0.328125000000 0.671875000000 +us_over_4.tga 0.328125000000 0.648437500000 0.351562500000 0.671875000000 +building_state_24x24.tga 0.351562500000 0.648437500000 0.375000000000 0.671875000000 +cb_main_nue.tga 0.375000000000 0.648437500000 0.398437500000 0.671875000000 +fp_ammo.tga 0.398437500000 0.648437500000 0.421875000000 0.671875000000 +ico_armor_medium.tga 0.421875000000 0.648437500000 0.445312500000 0.671875000000 +ico_clothes.tga 0.445312500000 0.648437500000 0.468750000000 0.671875000000 +ico_durability.tga 0.468750000000 0.648437500000 0.492187500000 0.671875000000 +W_slot_shortcut_id0.tga 0.492187500000 0.648437500000 0.515625000000 0.671875000000 +W_slot_shortcut_id1.tga 0.515625000000 0.648437500000 0.539062500000 0.671875000000 +W_slot_shortcut_id2.tga 0.539062500000 0.648437500000 0.562500000000 0.671875000000 +W_slot_shortcut_id3.tga 0.562500000000 0.648437500000 0.585937500000 0.671875000000 +W_slot_shortcut_id4.tga 0.585937500000 0.648437500000 0.609375000000 0.671875000000 +W_slot_shortcut_id5.tga 0.609375000000 0.648437500000 0.632812500000 0.671875000000 +W_slot_shortcut_id6.tga 0.632812500000 0.648437500000 0.656250000000 0.671875000000 +W_slot_shortcut_id7.tga 0.656250000000 0.648437500000 0.679687500000 0.671875000000 +W_slot_shortcut_id8.tga 0.679687500000 0.648437500000 0.703125000000 0.671875000000 +W_slot_shortcut_id9.tga 0.703125000000 0.648437500000 0.726562500000 0.671875000000 +w_slot_shortcut_shift_id0.tga 0.914062500000 0.656250000000 0.937500000000 0.679687500000 +w_slot_shortcut_shift_id1.tga 0.726562500000 0.664062500000 0.750000000000 0.687500000000 +w_slot_shortcut_shift_id2.tga 0.750000000000 0.664062500000 0.773437500000 0.687500000000 +w_slot_shortcut_shift_id3.tga 0.773437500000 0.664062500000 0.796875000000 0.687500000000 +w_slot_shortcut_shift_id4.tga 0.796875000000 0.664062500000 0.820312500000 0.687500000000 +w_slot_shortcut_shift_id5.tga 0.820312500000 0.664062500000 0.843750000000 0.687500000000 +w_slot_shortcut_shift_id6.tga 0.843750000000 0.664062500000 0.867187500000 0.687500000000 +w_slot_shortcut_shift_id7.tga 0.867187500000 0.664062500000 0.890625000000 0.687500000000 +w_slot_shortcut_shift_id8.tga 0.890625000000 0.664062500000 0.914062500000 0.687500000000 +w_slot_shortcut_shift_id9.tga 0.937500000000 0.664062500000 0.960937500000 0.687500000000 +BK_matis_brick.tga 0.960937500000 0.664062500000 0.984375000000 0.687500000000 +ico_jewel_stone_support.tga 0.000000000000 0.671875000000 0.023437500000 0.695312500000 +ico_misfortune.tga 0.023437500000 0.671875000000 0.046875000000 0.695312500000 +pa_over_break.tga 0.046875000000 0.671875000000 0.070312500000 0.695312500000 +pa_over_less.tga 0.070312500000 0.671875000000 0.093750000000 0.695312500000 +pa_over_more.tga 0.093750000000 0.671875000000 0.117187500000 0.695312500000 +ch_back.tga 0.117187500000 0.671875000000 0.140625000000 0.695312500000 +ico_over_hit_head_x3.tga 0.140625000000 0.671875000000 0.164062500000 0.695312500000 +ico_primal.tga 0.164062500000 0.671875000000 0.187500000000 0.695312500000 +pvp_ally_0.tga 0.187500000000 0.671875000000 0.210937500000 0.695312500000 +pvp_ally_1.tga 0.210937500000 0.671875000000 0.234375000000 0.695312500000 +pvp_ally_2.tga 0.234375000000 0.671875000000 0.257812500000 0.695312500000 +pvp_ally_3.tga 0.257812500000 0.671875000000 0.281250000000 0.695312500000 +pvp_ally_4.tga 0.281250000000 0.671875000000 0.304687500000 0.695312500000 +pvp_ally_6.tga 0.304687500000 0.671875000000 0.328125000000 0.695312500000 +pvp_ally_flag.tga 0.328125000000 0.671875000000 0.351562500000 0.695312500000 +pvp_ally_primas.tga 0.351562500000 0.671875000000 0.375000000000 0.695312500000 +pvp_ally_ranger.tga 0.375000000000 0.671875000000 0.398437500000 0.695312500000 +pvp_ally_tag.tga 0.398437500000 0.671875000000 0.421875000000 0.695312500000 +bg_downloader.tga 0.421875000000 0.671875000000 0.445312500000 0.695312500000 +ico_source_knowledge.tga 0.445312500000 0.671875000000 0.466796875000 0.695312500000 +filter_tp.tga 0.468750000000 0.671875000000 0.492187500000 0.687500000000 small_task_done.tga 0.984375000000 0.000000000000 1.000000000000 0.015625000000 small_task_failed.tga 0.984375000000 0.015625000000 1.000000000000 0.031250000000 small_task_fight.tga 0.984375000000 0.031250000000 1.000000000000 0.046875000000 @@ -669,6 +679,6 @@ small_task_travel.tga 0.914062500000 0.523437500000 0.929687500000 0.53906250000 small_task_craft.tga 0.984375000000 0.546875000000 1.000000000000 0.562500000000 num_slash.tga 0.984375000000 0.562500000000 0.996093750000 0.576171875000 W_leader.tga 0.984375000000 0.578125000000 0.997070312500 0.589843750000 -tb_mode.tga 0.984375000000 0.589843750000 0.996093750000 0.601562500000 -profile.tga 0.984375000000 0.601562500000 0.996093750000 0.613281250000 -w_major.tga 0.984375000000 0.613281250000 0.996093750000 0.625000000000 +w_major.tga 0.984375000000 0.589843750000 0.996093750000 0.601562500000 +tb_mode.tga 0.984375000000 0.601562500000 0.996093750000 0.613281250000 +profile.tga 0.984375000000 0.613281250000 0.996093750000 0.625000000000 diff --git a/code/ryzom/client/data/gamedev/adds/sfx/marauder_teleporter.ps b/code/ryzom/client/data/gamedev/adds/sfx/marauder_teleporter.ps new file mode 100644 index 000000000..cf6a508a9 Binary files /dev/null and b/code/ryzom/client/data/gamedev/adds/sfx/marauder_teleporter.ps differ diff --git a/code/ryzom/client/data/gamedev/adds/shapes/GE_HOF_caster_pvp_pantabottes.shape b/code/ryzom/client/data/gamedev/adds/shapes/GE_HOF_caster_pvp_pantabottes.shape new file mode 100644 index 000000000..713018df8 Binary files /dev/null and b/code/ryzom/client/data/gamedev/adds/shapes/GE_HOF_caster_pvp_pantabottes.shape differ diff --git a/code/ryzom/client/data/gamedev/adds/shapes/GE_HOM_caster_pvp_pantabottes.shape b/code/ryzom/client/data/gamedev/adds/shapes/GE_HOM_caster_pvp_pantabottes.shape new file mode 100644 index 000000000..b3fb8f6ca Binary files /dev/null and b/code/ryzom/client/data/gamedev/adds/shapes/GE_HOM_caster_pvp_pantabottes.shape differ diff --git a/code/ryzom/client/data/gamedev/adds/shapes/GE_pvp_big_shield.shape b/code/ryzom/client/data/gamedev/adds/shapes/GE_pvp_big_shield.shape new file mode 100644 index 000000000..c72f5304e Binary files /dev/null and b/code/ryzom/client/data/gamedev/adds/shapes/GE_pvp_big_shield.shape differ diff --git a/code/ryzom/client/data/gamedev/adds/shapes/tp_diamand.shape b/code/ryzom/client/data/gamedev/adds/shapes/tp_diamand.shape new file mode 100644 index 000000000..147ff3abb Binary files /dev/null and b/code/ryzom/client/data/gamedev/adds/shapes/tp_diamand.shape differ diff --git a/code/ryzom/client/data/gamedev/adds/shapes/tp_socle.shape b/code/ryzom/client/data/gamedev/adds/shapes/tp_socle.shape new file mode 100644 index 000000000..4a3eea639 Binary files /dev/null and b/code/ryzom/client/data/gamedev/adds/shapes/tp_socle.shape differ diff --git a/code/ryzom/client/data/gamedev/adds/textures/event_refday_yber.tga b/code/ryzom/client/data/gamedev/adds/textures/event_refday_yber.tga new file mode 100644 index 000000000..b8e05a831 Binary files /dev/null and b/code/ryzom/client/data/gamedev/adds/textures/event_refday_yber.tga differ diff --git a/code/ryzom/client/data/gamedev/adds/textures/gn_pvp_dress.tga b/code/ryzom/client/data/gamedev/adds/textures/gn_pvp_dress.tga new file mode 100644 index 000000000..026711a84 Binary files /dev/null and b/code/ryzom/client/data/gamedev/adds/textures/gn_pvp_dress.tga differ diff --git a/code/ryzom/client/data/gamedev/adds/textures/gn_pvp_dress_hof.tga b/code/ryzom/client/data/gamedev/adds/textures/gn_pvp_dress_hof.tga new file mode 100644 index 000000000..83f18a9b3 Binary files /dev/null and b/code/ryzom/client/data/gamedev/adds/textures/gn_pvp_dress_hof.tga differ diff --git a/code/ryzom/client/data/gamedev/adds/textures/ul_mission_hall_of_fame.dds b/code/ryzom/client/data/gamedev/adds/textures/ul_mission_hall_of_fame.dds new file mode 100644 index 000000000..03f9e0442 Binary files /dev/null and b/code/ryzom/client/data/gamedev/adds/textures/ul_mission_hall_of_fame.dds differ diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/commands.xml b/code/ryzom/client/data/gamedev/interfaces_v3/commands.xml index ca013f242..f0455028a 100644 --- a/code/ryzom/client/data/gamedev/interfaces_v3/commands.xml +++ b/code/ryzom/client/data/gamedev/interfaces_v3/commands.xml @@ -78,9 +78,18 @@ - + + + + + + + + + + diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/config.xml b/code/ryzom/client/data/gamedev/interfaces_v3/config.xml index 1d593ef06..9fb0dd958 100644 --- a/code/ryzom/client/data/gamedev/interfaces_v3/config.xml +++ b/code/ryzom/client/data/gamedev/interfaces_v3/config.xml @@ -258,6 +258,9 @@ + @@ -291,6 +294,9 @@ + @@ -327,6 +333,9 @@ + @@ -2797,6 +2806,9 @@ This MUST follow the Enum MISSION_DESC::TIconId + - + + + + + + + + @@ -3045,6 +3081,9 @@ This MUST follow the Enum MISSION_DESC::TIconId + @@ -3066,6 +3105,9 @@ This MUST follow the Enum MISSION_DESC::TIconId + @@ -3087,6 +3129,9 @@ This MUST follow the Enum MISSION_DESC::TIconId + @@ -3108,6 +3153,9 @@ This MUST follow the Enum MISSION_DESC::TIconId + @@ -3129,6 +3177,9 @@ This MUST follow the Enum MISSION_DESC::TIconId + @@ -3151,6 +3202,9 @@ This MUST follow the Enum MISSION_DESC::TIconId + @@ -3173,6 +3227,9 @@ This MUST follow the Enum MISSION_DESC::TIconId + + + diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/encyclopedia.xml b/code/ryzom/client/data/gamedev/interfaces_v3/encyclopedia.xml index b2db7ab26..30f2c34a0 100644 --- a/code/ryzom/client/data/gamedev/interfaces_v3/encyclopedia.xml +++ b/code/ryzom/client/data/gamedev/interfaces_v3/encyclopedia.xml @@ -11,7 +11,7 @@ - + + + + + +
+ +

spawn_mission

+ +

 

+ +

Properties:

+ +

 

+ +

name: Action name, only used by the +mission designer.

+ +

 

+ +

giver_name: The NPC that gives the mission.

+ +

 

+ +

guild (Boolean): This parameter is only for guild missions. .

+ + +

 

+ +

mission_name: The name of the mission to spawn.

+ +

 

+ + +
+ + + + diff --git a/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/world_editor_classes.xml b/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/world_editor_classes.xml index 1e4f9d723..5426361fa 100644 --- a/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/world_editor_classes.xml +++ b/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/world_editor_classes.xml @@ -688,8 +688,6 @@ - - @@ -709,6 +707,7 @@ + @@ -838,14 +837,6 @@ - - - - - - - - @@ -1108,8 +1099,6 @@ - - @@ -1122,10 +1111,6 @@ - - - - @@ -1135,45 +1120,28 @@ - - - - - - - - - + - - - - - - - - - @@ -1182,27 +1150,18 @@ - - - - - - - - - @@ -1212,9 +1171,6 @@ - - - @@ -1223,9 +1179,6 @@ - - - @@ -1233,9 +1186,6 @@ - - - @@ -1243,35 +1193,23 @@ - - - - - - - - - - - - @@ -1304,18 +1242,12 @@ - - - - - - diff --git a/code/ryzom/common/data_leveldesign/primitives/newbieland/guild_missions.primitive b/code/ryzom/common/data_leveldesign/primitives/newbieland/guild_missions.primitive new file mode 100644 index 000000000..568d89398 --- /dev/null +++ b/code/ryzom/common/data_leveldesign/primitives/newbieland/guild_missions.primitive @@ -0,0 +1,448 @@ + + + + + + + class + missions_editor + + + name + guild_missions + + + + audience + guild + + + auto_remove_from_journal + false + + + automatic + false + + + class + mission_tree + + + fail_if_inventory_is_full + false + + + giver_primitive + urban_newbieland.primitive + + + mission_category + Killing + + + mission_description + GUILD_MISSION_DESC + + + mission_giver + $givervar@fullname$ + + + mission_title + GUILD_MISSION_TITLE + + + mono_instance + false + + + name + GUILD_MISSION + + + need_validation + false + + + non_abandonnable + false + + + not_in_journal + false + + + not_proposed + false + + + replayable + true + + + run_only_once + false + + + + class + variables + + + name + variables + + + + class + var_npc + + + npc_function + fct_ranger_leader + + + npc_name + chiang_the_strong + + + var_name + givervar + + + + + + class + pre_requisite + + + name + pre_requisite + + + require_guild_grade + Leader + + + require_guild_membership + true + + + + + + class + alias + + + name + alias + + + + + class + step + + + name + step + + + + class + actions + + + name + pre_actions + + + + class + spawn_mission + + + giver_name + chiang_the_strong + + + guild + true + + + mission_name + SOLO_GUILD_MISSION + + + + + + class + mission_objectives + + + name + objectives + + + + class + do_mission + + + mission_names + SOLO_GUILD_MISSION 2 + + + overload_objective + MIS_DO_MISSION + + + + + class + kill + + + fauna/quantity + chdfa1 2 + + + name + kill chdfa1 2 + + + + + + class + actions + + + name + post_actions + + + + amount + 100 + + + class + recv_money + + + guild + true + + + name + recv_money 100 guild + + + + + amount + 50 + + + class + recv_money + + + + + + + + audience + solo + + + auto_remove_from_journal + false + + + automatic + false + + + class + mission_tree + + + fail_if_inventory_is_full + false + + + giver_primitive + urban_newbieland.primitive + + + mission_category + Killing + + + mission_description + SOLO_GUILD_MISSION_DESC + + + mission_giver + $givervar@fullname$ + + + mission_title + SOLO_GUILD_MISSION_TITLE + + + mono_instance + false + + + name + SOLO_GUILD_MISSION + + + need_validation + false + + + non_abandonnable + false + + + not_in_journal + false + + + not_proposed + true + + + replayable + true + + + run_only_once + false + + + + class + variables + + + name + variables + + + + class + var_npc + + + npc_function + fct_ranger_leader + + + npc_name + chiang_the_strong + + + var_name + givervar + + + + + + class + pre_requisite + + + name + pre_requisite + + + + + + class + alias + + + name + alias + + + + + class + step + + + name + step + + + + class + actions + + + name + pre_actions + + + + + class + mission_objectives + + + name + objectives + + + + class + kill + + + fauna/quantity + chdfa1 1 + + + name + kill chdfa1 1 + + + + + + class + actions + + + name + post_actions + + + + amount + 20 + + + class + recv_money + + + + + + + + diff --git a/code/ryzom/common/src/Makefile b/code/ryzom/common/src/Makefile deleted file mode 100644 index ef0bb500b..000000000 --- a/code/ryzom/common/src/Makefile +++ /dev/null @@ -1,36 +0,0 @@ - -BUILD_DIRS = game_share - -night: all - -all: $(foreach dir,$(BUILD_DIRS),$(dir)-all) - -%-all: - +make -k -C $* all - -clean: $(foreach dir,$(BUILD_DIRS),$(dir)-clean) - -%-clean: - +make -C $* clean - -distclean: $(foreach dir,$(BUILD_DIRS),$(dir)-distclean) - -%-distclean: - +make -C $* distclean - -cleansheets: $(foreach dir,$(BUILD_DIRS),$(dir)-cleansheets) - -%-cleansheets: - +make -C $* cleansheets - -update: $(foreach dir,$(BUILD_DIRS),$(dir)-update) - -%-update: - +make -C $* update - -touch: $(foreach dir,$(BUILD_DIRS),$(dir)-touch) - -%-touch: - +make -C $* touch - -.NOTPARALLEL: night all clean cleansheets update touch diff --git a/code/ryzom/common/src/game_share/CMakeLists.txt b/code/ryzom/common/src/game_share/CMakeLists.txt index 7883ce03d..61292431c 100644 --- a/code/ryzom/common/src/game_share/CMakeLists.txt +++ b/code/ryzom/common/src/game_share/CMakeLists.txt @@ -1,13 +1,32 @@ FILE(GLOB SRC *.cpp time_weather_season/*.cpp) FILE(GLOB PRIV_H *.h time_weather_season/*.h) -SOURCE_GROUP(headers FILES ${PRIV_H}) +FILE(GLOB R2 + dms.h dms.cpp + scenario.h scenario.cpp + user_connection_mgr.h user_connection_mgr.cpp + object.h object.cpp + server_animation_module.h server_animation_module.cpp + server_admin_module.h server_admin_module.cpp + server_edition_module.h server_edition_module.cpp + string_mgr_module.h string_mgr_module.cpp + scenario_entry_points.h scenario_entry_points.cpp + small_string_manager.h small_string_manager.cpp + ai_wrapper.h ai_wrapper.cpp + r2_*.h r2_*.cpp + ring_*.h ring_*.cpp) + +LIST(REMOVE_ITEM SRC R2) +LIST(REMOVE_ITEM PRIV_H R2) + +SOURCE_GROUP("" FILES ${SRC} ${PRIV_H}) +SOURCE_GROUP("R2" FILES ${R2}) # Filter out the source files not actually compiled. LIST(REMOVE_ITEM SRC ${CMAKE_CURRENT_SOURCE_DIR}/enum_template.cpp) LIST(REMOVE_ITEM PRIV_H ${CMAKE_CURRENT_SOURCE_DIR}/enum_template.h) -NL_TARGET_LIB(ryzom_gameshare ${PRIV_H} ${SRC}) +NL_TARGET_LIB(ryzom_gameshare ${PRIV_H} ${SRC} ${R2}) INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR} ${NEL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) @@ -22,5 +41,6 @@ IF(WITH_PCH) ADD_NATIVE_PRECOMPILED_HEADER(ryzom_gameshare ${CMAKE_CURRENT_SOURCE_DIR}/stdpch.h ${CMAKE_CURRENT_SOURCE_DIR}/stdpch.cpp) ENDIF(WITH_PCH) -INSTALL(TARGETS ryzom_gameshare LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries) - +IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) + INSTALL(TARGETS ryzom_gameshare LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries) +ENDIF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) diff --git a/code/ryzom/common/src/game_share/Makefile b/code/ryzom/common/src/game_share/Makefile deleted file mode 100644 index ac78fd835..000000000 --- a/code/ryzom/common/src/game_share/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -############################################################################# -# Simple make file for compiling GAME SHARE - -############################################################################# -# Setting up the compiler settings... - -# Global variables -include ../../../Variables.mk - -# The flags for the C++ compiler -CXXFLAGS = $(FLAGS_CMN) $(FLAGS_DBG_$(DBG)) \ - -I/usr/include/libxml2 \ - -I/usr/include/mysql \ - -I$(NEL_INCLUDE) \ - -I$(RYZOM_PATH)/common/src \ - -I./ \ - -I./character_structure \ - -I./egs_sheets \ - -I./entity_structure \ - -I./game_item_manager - -# The flags for the linker -LDFLAGS = $(LD_FLAGS_CMN) -L$(RYZOM_PATH)/install/$(DIR_DBG_$(DBG))/lib \ - -llibmysqlclient \ - -lnelnet \ - -lnelgeorges \ - -lnelpacs \ - -L/usr/lib \ - -L/usr/X11R6/lib \ - -lnelmisc \ - -lxml2 \ - -lstlport \ - -lpthread \ - -lld - -############################################################################# -# The bit that changes each time we cut paste and hack this file :o) - -# The list of targets to build -TARGETS = libgame_share.a -DSP_TARGET = game_share.vcproj - -# The default build rule -all: check-deps $(TARGETS) - - -#libgame_share.so: $(OBJS) -# $(CXX) -o $@ $(OBJS) -shared $(LDFLAGS) - -libgame_share.a: $(OBJS) - ar r libgame_share.a $(OBJS) - -############################################################################# -# Rules - -include ../../../Rules.mk diff --git a/code/ryzom/common/src/game_share/bot_chat_types.h b/code/ryzom/common/src/game_share/bot_chat_types.h index 779bc8ba3..19982f106 100644 --- a/code/ryzom/common/src/game_share/bot_chat_types.h +++ b/code/ryzom/common/src/game_share/bot_chat_types.h @@ -82,6 +82,8 @@ namespace BOTCHATTYPE ResaleKOBroken, // this item can't be sold because its Resold time has expired ResaleKONoTimeLeft, + // this item can't be sold because the owner has locked it (temporary hack to get around modifying database.xml) + ResaleKOLockedByOwner, NumBotChatResaleFlag }; diff --git a/code/ryzom/common/src/game_share/character_sync_itf.h b/code/ryzom/common/src/game_share/character_sync_itf.h index 459659732..5481045ed 100644 --- a/code/ryzom/common/src/game_share/character_sync_itf.h +++ b/code/ryzom/common/src/game_share/character_sync_itf.h @@ -1108,9 +1108,7 @@ namespace CHARSYNC void setResult(TCharacterNameResult value) { - _Result = value; - } // uint32 getUserId() const @@ -1120,9 +1118,7 @@ namespace CHARSYNC void setUserId(uint32 value) { - _UserId = value; - } // uint8 getCharIndex() const @@ -1132,9 +1128,7 @@ namespace CHARSYNC void setCharIndex(uint8 value) { - _CharIndex = value; - } // const ucstring& getFullName() const @@ -1144,9 +1138,7 @@ namespace CHARSYNC void setFullName(const ucstring &value) { - _FullName = value; - } bool operator == (const CValidateNameResult &other) const @@ -1161,7 +1153,6 @@ namespace CHARSYNC // constructor CValidateNameResult() { - } void serial(NLMISC::IStream &s) @@ -1170,7 +1161,6 @@ namespace CHARSYNC s.serial(_UserId); s.serial(_CharIndex); s.serial(_FullName); - } diff --git a/code/ryzom/common/src/game_share/data_set_base.h b/code/ryzom/common/src/game_share/data_set_base.h index 0db688aa5..54bd790ab 100644 --- a/code/ryzom/common/src/game_share/data_set_base.h +++ b/code/ryzom/common/src/game_share/data_set_base.h @@ -437,7 +437,7 @@ public: // PUBLIC because template friend classes are not supported /// Return the pointer to the property value template - void getPropPointerForList( TSharedListRow **ppt, TPropertyIndex propIndex, const TDataSetRow& entityIndex, T* typeHint ) const + void getPropPointerForList( TSharedListRow **ppt, TPropertyIndex propIndex, const TDataSetRow& entityIndex, T* /* typeHint */ ) const { #ifndef FAST_MIRROR nlassert( (propIndex != INVALID_PROPERTY_INDEX) && (propIndex < (TPropertyIndex)_PropertyContainer.PropertyValueArrays.size()) ); // Wrong property diff --git a/code/ryzom/common/src/game_share/deployment_configuration.cpp b/code/ryzom/common/src/game_share/deployment_configuration.cpp new file mode 100644 index 000000000..625600331 --- /dev/null +++ b/code/ryzom/common/src/game_share/deployment_configuration.cpp @@ -0,0 +1,1519 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +//----------------------------------------------------------------------------- +// include +//----------------------------------------------------------------------------- + +// pre compiled headers +#include "stdpch.h" + +// nel +#include "nel/misc/types_nl.h" +#include "nel/misc/common.h" +#include "nel/misc/time_nl.h" +#include "nel/misc/smart_ptr.h" +#include "nel/misc/singleton.h" +#include "nel/misc/command.h" +#include "nel/misc/file.h" + +// game share +#include "utils.h" +#include "deployment_configuration.h" + + +//----------------------------------------------------------------------------- +// namespaces +//----------------------------------------------------------------------------- + +using namespace std; +using namespace NLMISC; + + +//----------------------------------------------------------------------------- +// namespace DEPCFG +//----------------------------------------------------------------------------- + +namespace DEPCFG +{ + //----------------------------------------------------------------------------- + // forward class declarations + //----------------------------------------------------------------------------- + + struct SExeRecord; + class CInfoBlock; + class CInfoContainer; + class CDeploymentConfigurationImplementation; + + + //----------------------------------------------------------------------------- + // struct SExeRecord + //----------------------------------------------------------------------------- + + struct SExeRecord + { + typedef std::set TDataEntries; + typedef std::vector TCfgEntries; + + NLMISC::CSString FullName; + + NLMISC::CSString DomainName; + NLMISC::CSString ShardName; + NLMISC::CSString UniqueName; + NLMISC::CSString CmdLine; + NLMISC::CSString Host; + NLMISC::CSString StartOrder; + TDataEntries DataEntries; + TCfgEntries CfgEntries; + TCfgEntries CfgEntriesPost; + + // serial method + void serial(NLMISC::IStream& stream) + { + stream.serial(FullName); + stream.serial(DomainName); + stream.serial(ShardName); + stream.serial(UniqueName); + stream.serial(CmdLine); + stream.serial(Host); + stream.serialCont(DataEntries); + stream.serialCont(CfgEntries); + stream.serialCont(CfgEntriesPost); + } + }; + + + //----------------------------------------------------------------------------- + // class CInfoBlock + //----------------------------------------------------------------------------- + + class CInfoBlock: public NLMISC::CRefCount + { + public: + // ctors + CInfoBlock(const NLMISC::CSString& name=""); + + // write accessors + void setDomainName(const NLMISC::CSString& entry,const NLMISC::CSString& context,uint32& errors); + void setShardName(const NLMISC::CSString& entry,const NLMISC::CSString& context,uint32& errors); + void setUniqueName(const NLMISC::CSString& entry,const NLMISC::CSString& context,uint32& errors); + void setCmdLine(const NLMISC::CSString& entry,const NLMISC::CSString& context,uint32& errors); + void setHost(const NLMISC::CSString& entry,const NLMISC::CSString& context,uint32& errors); + void setStartOrder(const NLMISC::CSString& entry,const NLMISC::CSString& context,uint32& errors); + + void addUseEntry(const NLMISC::CSString& entry,const NLMISC::CSString& context,uint32& errors); + void addDataEntry(const NLMISC::CSString& entry,const NLMISC::CSString& context,uint32& errors); + + void addCfgEntry(const NLMISC::CSString& entry,const NLMISC::CSString& context,uint32& errors); + void addCfgEntryPost(const NLMISC::CSString& entry,const NLMISC::CSString& context,uint32& errors); + + void addCfgFile(const NLMISC::CSString& fileName,const NLMISC::CSString& context,uint32& errors); + void addCfgFilePost(const NLMISC::CSString& fileName,const NLMISC::CSString& context,uint32& errors); + + // direct read accessors + uint32 getNumParents() const; + const NLMISC::CSString& getName() const; + const NLMISC::CSString& getDomainName() const; + + // indirect read accessors + bool isDomain() const; + bool isShard() const; + + // setup the _Children vector from the _UseEntries vector + void setupChildren(CInfoContainer* container,uint32& errors); + + // traverse the tree of children, cumulating data on exes, and instantiating the exe records in 'container' + void buildExeSet(CInfoContainer* container,uint32& errors,const SExeRecord& parentExeRecord=SExeRecord()); + + // serial + void serial(NLMISC::IStream& stream); + + // display the contents of the container + void dump(NLMISC::CLog& log) const; + + private: + // data types + typedef std::set TUseEntries; + typedef std::set TDataEntries; + typedef std::vector TCfgEntries; + + typedef std::vector TChildren; + + // private methods + bool _haveCircularRef(CInfoBlock* other) const; + + // data (basics) + NLMISC::CSString _Name; + uint32 _NumParents; + TChildren _Children; + + // data extracted from input file + NLMISC::CSString _DomainName; + NLMISC::CSString _ShardName; + NLMISC::CSString _UniqueName; + NLMISC::CSString _CmdLine; + NLMISC::CSString _Host; + NLMISC::CSString _StartOrder; + TUseEntries _UseEntries; + TDataEntries _DataEntries; + TCfgEntries _CfgEntries; + TCfgEntries _CfgEntriesPost; + }; + + + //----------------------------------------------------------------------------- + // class CInfoContainer + //----------------------------------------------------------------------------- + + class CInfoContainer + { + public: + // public interface + void clear(); + bool empty() const; + + bool read(const NLMISC::CSString& fileName); + void serial(NLMISC::IStream& stream); + + void getHostNames(THostNames& result) const; + void getDomainNames(TDomainNames& result) const; + void getShardNames(const TDomainName& domainName,TShardNames& result) const; + void getAppNames(const THostName& hostName,const TDomainName& domainName,TAppNames& result) const; + void getAppNames(const THostName& hostName,const TDomainName& domainName,const TShardName& shardName,TAppNames& result) const; + + void getHost(const THostName& hostName,SHostDescription& result) const; + void getDomain(const TDomainName& domainName, SDomainDescription& result) const; + void getShard(const TDomainName& domainName,const TShardName& shardName,SShardDescription& result) const; + void getApp(const TDomainName& domainName,const TAppName& appName,SAppDescription& result) const; + + void dumpInfoBlocks(NLMISC::CLog& log) const; + void dumpDomains(NLMISC::CLog& log) const; + + // interface used by CInfoBlock methods + CInfoBlock* getInfoBlock(const NLMISC::CSString& name); + void addExe(const SExeRecord& exeRecord,uint32& errors); + + private: + // data types + typedef NLMISC::CSmartPtr TInfoBlockPtr; + typedef std::map< NLMISC::CSString,TInfoBlockPtr > TInfoBlocks; + typedef std::set< NLMISC::CSString > TFileNameSet; + typedef std::vector< SExeRecord > TExeRecords; + typedef std::vector TExeIdx; + typedef std::map TShardExes; + typedef std::map TDomainExes; + + // private methods + void _readFile(const NLMISC::CSString& fileName,uint32& errors,TFileNameSet& fileNameStack); + void _buildDomainTree(uint32& errors); + void _buildExeSet(uint32& errors); + + // data + TInfoBlockPtr _CurrentInfoBlock; + TInfoBlocks _InfoBlocks; + TExeRecords _ExeRecords; + TDomainExes _DomainExes; + }; + + + //----------------------------------------------------------------------------- + // class CDeploymentConfigurationImplementation + //----------------------------------------------------------------------------- + + class CDeploymentConfigurationImplementation: public CSingleton, public CDeploymentConfiguration + { + public: + bool read(const NLMISC::CSString& fileName); + void write(const NLMISC::CSString& fileName); + void serial(NLMISC::IStream& stream); + + void getHostNames(THostNames& result) const; + void getDomainNames(TDomainNames& result) const; + void getShardNames(const TDomainName& domainName,TShardNames& result) const; + void getAppNames(const THostName& hostName,const TDomainName& domainName,TAppNames& result) const; + void getAppNames(const THostName& hostName,const TDomainName& domainName,const TShardName& shardName,TAppNames& result) const; + + void getHost(const THostName& hostName,SHostDescription& result) const; + void getDomain(const TDomainName& domainName, SDomainDescription& result) const; + void getShard(const TDomainName& domainName,const TShardName& shardName,SShardDescription& result) const; + void getApp(const TDomainName& domainName,const TAppName& appName,SAppDescription& result) const; + + void dumpInfoBlocks(NLMISC::CLog& log) const; + void dumpDomains(NLMISC::CLog& log) const; + + private: + CInfoContainer _InfoContainer; + }; + + + //----------------------------------------------------------------------------- + // methods CInfoBlock + //----------------------------------------------------------------------------- + + CInfoBlock::CInfoBlock(const NLMISC::CSString& name) + { + _Name= name; + _NumParents= 0; + } + + void CInfoBlock::setDomainName(const NLMISC::CSString& entry,const NLMISC::CSString& context,uint32& errors) + { + DROP_IF(!_DomainName.empty(),context+"Attempting to set a domain name more than once for the same info block",++errors; return); + DROP_IF(entry.empty(),context+"Attempting to set an empty domain name",++errors; return); + _DomainName=entry; + } + + void CInfoBlock::setShardName(const NLMISC::CSString& entry,const NLMISC::CSString& context,uint32& errors) + { + DROP_IF(!_ShardName.empty(),context+"Attempting to set a shard name more than once for the same info block",++errors; return); + DROP_IF(entry.empty(),context+"Attempting to set an empty shard name",++errors; return); + _ShardName=entry; + } + + void CInfoBlock::setUniqueName(const NLMISC::CSString& entry,const NLMISC::CSString& context,uint32& errors) + { + DROP_IF(!_UniqueName.empty(),context+"Attempting to set a name more than once for the same info block",++errors; return); + DROP_IF(entry.empty(),context+"Attempting to set an empty name",++errors; return); + _UniqueName=entry; + } + + void CInfoBlock::setCmdLine(const NLMISC::CSString& entry,const NLMISC::CSString& context,uint32& errors) + { + DROP_IF(!_CmdLine.empty(),context+"Attempting to set a cmdLine more than once for the same info block",++errors; return); + DROP_IF(entry.empty(),context+"Attempting to set an empty cmdLine",++errors; return); + _CmdLine=entry; + } + + void CInfoBlock::setHost(const NLMISC::CSString& entry,const NLMISC::CSString& context,uint32& errors) + { + DROP_IF(!_Host.empty(),context+"Attempting to set a host more than once for the same info block",++errors; return); + DROP_IF(entry.empty(),context+"Attempting to set an empty host",++errors; return); + _Host=entry; + } + + void CInfoBlock::setStartOrder(const NLMISC::CSString& entry,const NLMISC::CSString& context,uint32& errors) + { + DROP_IF(!_StartOrder.empty(),context+"Attempting to set a startOrder more than once for the same info block",++errors; return); + DROP_IF(entry.empty(),context+"Attempting to set an empty startOrder",++errors; return); + _StartOrder=entry; + } + + void CInfoBlock::addUseEntry(const NLMISC::CSString& entry,const NLMISC::CSString& context,uint32& errors) + { + DROP_IF(_UseEntries.find(entry)!=_UseEntries.end(),context+"Ignoring duplicate refference to 'use' clause: "+entry,return); + _UseEntries.insert(entry); + } + + void CInfoBlock::addDataEntry(const NLMISC::CSString& entry,const NLMISC::CSString& context,uint32& errors) + { + DROP_IF(_DataEntries.find(entry)!=_DataEntries.end(),context+"Ignoring duplicate refference to 'data' clause: "+entry,return); + _DataEntries.insert(entry); + } + + void CInfoBlock::addCfgEntry(const NLMISC::CSString& entry,const NLMISC::CSString& context,uint32& errors) + { + _CfgEntries.push_back(entry); + } + + void CInfoBlock::addCfgEntryPost(const NLMISC::CSString& entry,const NLMISC::CSString& context,uint32& errors) + { + _CfgEntriesPost.push_back(entry); + } + + void CInfoBlock::addCfgFile(const NLMISC::CSString& fileName,const NLMISC::CSString& context,uint32& errors) + { + // make sure a file name is supplied + DROP_IF(fileName.empty(),context+"No file name found following 'cfgFile'", ++errors;return); + + // read in the src file + NLMISC::CSString fileContents; + fileContents.readFromFile(fileName); + DROP_IF(fileContents.empty(),"File not found: "+fileName, ++errors;return); + + // split the file contents into lines + NLMISC::CVectorSString lines; + fileContents.splitLines(lines); + + // append the lines to the '_CfgEntries' container + _CfgEntries.insert(_CfgEntries.end(),lines.begin(),lines.end()); + } + + void CInfoBlock::addCfgFilePost(const NLMISC::CSString& fileName,const NLMISC::CSString& context,uint32& errors) + { + // make sure a file name is supplied + DROP_IF(fileName.empty(),context+"No file name found following 'cfgFilePost'", ++errors;return); + + // read in the src file + NLMISC::CSString fileContents; + fileContents.readFromFile(fileName); + DROP_IF(fileContents.empty(),"File not found: "+fileName, ++errors;return); + + // split the file contents into lines + NLMISC::CVectorSString lines; + fileContents.splitLines(lines); + + // prepend the lines to the '_CfgEntriesPost' container + _CfgEntriesPost.insert(_CfgEntriesPost.begin(),lines.begin(),lines.end()); + } + + uint32 CInfoBlock::getNumParents() const + { + return _NumParents; + } + + const NLMISC::CSString& CInfoBlock::getName() const + { + return _Name; + } + + const NLMISC::CSString& CInfoBlock::getDomainName() const + { + return _DomainName; + } + + bool CInfoBlock::isDomain() const + { + return !_DomainName.empty(); + } + + bool CInfoBlock::isShard() const + { + return !_ShardName.empty(); + } + + void CInfoBlock::setupChildren(CInfoContainer* container,uint32& errors) + { + // start by clearing out the child vector that we're going to fill + _Children.clear(); + + // iterate over the the 'use' clauses + for (TUseEntries::iterator it= _UseEntries.begin(); it!= _UseEntries.end(); ++it) + { + const NLMISC::CSString& theEntry= *it; + + // try to get a pointer to the refferenced info block... + CInfoBlock* infoBlockPtr= container->getInfoBlock(theEntry); + DROP_IF(infoBlockPtr==NULL,"Failed to find block named '"+theEntry+"' while fixing up children of block: "+_Name, ++errors;continue); + + // make sure that this block doesn't figure amongst the children of the refferenced info block (to avoid circular refs) + DROP_IF(_haveCircularRef(infoBlockPtr),"Circular dependency found between definitions of '"+_Name+"' and '"+theEntry+"'", ++errors;continue); + + // add the info block to our children + _Children.push_back(infoBlockPtr); + ++(infoBlockPtr->_NumParents); + } + } + + void CInfoBlock::buildExeSet(CInfoContainer* container,uint32& errors,const SExeRecord& parentExeRecord) + { + // setup a record to accumulate data into as we traverse the tree, starting + // with a copy of the data passed in from parents + SExeRecord theExe= parentExeRecord; + + // add a chunk to the exe record's 'FullName' property + theExe.FullName+= (theExe.FullName.empty()?"":".")+ _Name; + + // make sure we don't have any field duplication... + DROP_IF(!_DomainName.empty() && !theExe.DomainName.empty(), "more than one domain found in: "+theExe.FullName, ++errors ); + DROP_IF(!_ShardName.empty() && !theExe.ShardName.empty(), "more than one shard found in: "+theExe.FullName, ++errors ); + DROP_IF(!_CmdLine.empty() && !theExe.CmdLine.empty(), "more than one cmdLine found in: "+theExe.FullName, ++errors ); + DROP_IF(!_Host.empty() && !theExe.Host.empty(), "more than one host found in: "+theExe.FullName, ++errors ); + WARN_IF(!_UniqueName.empty() && !theExe.UniqueName.empty(), "replacing name '"+theExe.UniqueName+"' with '"+_UniqueName+"' in: "+theExe.FullName); + + // fill our own data into the exe record + if (!_DomainName.empty()) theExe.DomainName = _DomainName; + if (!_ShardName.empty()) theExe.ShardName = _ShardName; + if (!_UniqueName.empty()) theExe.UniqueName = _UniqueName; + if (!_CmdLine.empty()) theExe.CmdLine = _CmdLine; + if (!_Host.empty()) theExe.Host = _Host; + if (!_StartOrder.empty()) theExe.StartOrder = _StartOrder; + // merge contents of 2 sets + theExe.DataEntries.insert( _DataEntries.begin(), _DataEntries.end() ); + // append or pre-pend contents of one vector to another + theExe.CfgEntries.insert( theExe.CfgEntries.end(), _CfgEntries.begin(), _CfgEntries.end() ); + theExe.CfgEntriesPost.insert( theExe.CfgEntriesPost.begin(), _CfgEntriesPost.begin(), _CfgEntriesPost.end() ); + + // if this is the node with the cmdLine then think about updating the unique name... + if (!_CmdLine.empty() && theExe.UniqueName.empty()) + { + theExe.UniqueName= _Name; + } + + // do something with the exe record depending on whetherwe're a tree branch or leaf + if (_Children.empty()) + { + // merge the cfg entries together to make a single block + theExe.CfgEntries.insert(theExe.CfgEntries.end(),theExe.CfgEntriesPost.begin(),theExe.CfgEntriesPost.end()); + theExe.CfgEntriesPost.clear(); + + // this is a leaf node (it has no children) so it must describe an executable + container->addExe(theExe,errors); + } + else + { + // this is a branch node so recurse into children + for (TChildren::iterator it=_Children.begin();it!=_Children.end();++it) + { + (*it)->buildExeSet(container,errors,theExe); + } + } + } + + void CInfoBlock::serial(NLMISC::IStream& stream) + { + if (stream.isReading()) + { + // if we're reading then we clear out the children vector - it'll be rebuilt at the end of the serial + _Children.clear(); + } + + stream.serial(_Name); + stream.serial(_NumParents); + stream.serial(_DomainName); + stream.serial(_ShardName); + stream.serial(_UniqueName); + stream.serial(_CmdLine); + stream.serial(_Host); + + stream.serialCont(_UseEntries); + stream.serialCont(_DataEntries); + stream.serialCont(_CfgEntries); + stream.serialCont(_CfgEntriesPost); + } + + void CInfoBlock::dump(NLMISC::CLog& log) const + { + //***************************** + // NOTE: + // This method is called to + // create a text save of the + // data that we contain - it + // must output ALL data that + // read() requires and in a + // read()-compatible format + //***************************** + + log.displayNL("define %s // refferenced by %u other defines",_Name.c_str(),_NumParents); + + if (!_DomainName.empty()) + { + log.displayNL("\tdomain\t%s",_DomainName.c_str()); + } + + if (!_ShardName.empty()) + { + log.displayNL("\tshard\t%s",_ShardName.c_str()); + } + + if (!_UniqueName.empty()) + { + log.displayNL("\tname\t%s",_UniqueName.c_str()); + } + + if (!_CmdLine.empty()) + { + log.displayNL("\tcmdLine\t%s",_CmdLine.c_str()); + } + + if (!_Host.empty()) + { + log.displayNL("\thost\t%s",_Host.c_str()); + } + + for (TUseEntries::const_iterator it=_UseEntries.begin(); it!=_UseEntries.end(); ++it) + { + log.displayNL("\tuse\t%s",it->c_str()); + } + + for (TDataEntries::const_iterator it=_DataEntries.begin(); it!=_DataEntries.end(); ++it) + { + log.displayNL("\tdata\t%s",it->c_str()); + } + + for (TCfgEntries::const_iterator it=_CfgEntries.begin(); it!=_CfgEntries.end(); ++it) + { + log.displayNL("\tcfg\t%s",it->c_str()); + } + + for (TCfgEntries::const_iterator it=_CfgEntriesPost.begin(); it!=_CfgEntriesPost.end(); ++it) + { + log.displayNL("\tcfgAfter\t%s",it->c_str()); + } + + log.displayNL(""); + } + + bool CInfoBlock::_haveCircularRef(CInfoBlock* other) const + { + // in the case of a circular refference we end up with the 'other'=='this' + if (this==other) + return true; + + // recurse into children looking for a deep circular ref + for (TChildren::const_iterator it= other->_Children.begin();it!=other->_Children.end();++it) + { + CInfoBlock* child= *it; + if (_haveCircularRef(child)) + return true; + } + + // no circular ref found so return false + return false; + } + + //----------------------------------------------------------------------------- + // methods CInfoContainer + //----------------------------------------------------------------------------- + + void CInfoContainer::clear() + { + _InfoBlocks.clear(); + _CurrentInfoBlock= NULL; + _ExeRecords.clear(); + _DomainExes.clear(); + } + + bool CInfoContainer::empty() const + { + return _InfoBlocks.empty(); + } + + bool CInfoContainer::read(const NLMISC::CSString& fileName) + { + // start by clearing out our contents... + clear(); + + // setup some basics + uint32 errors= 0; + TFileNameSet fileNameSet; + + // read in the src file + _readFile(fileName,errors,fileNameSet); + + // build the blocks into a tree + _buildDomainTree(errors); + + // build the set of executables from the tree + _buildExeSet(errors); + + // make sure that no errors were encountered... + DROP_IF(errors!=0,NLMISC::toString("%s: Parse Failed: %u errors found",fileName.c_str(),errors),clear(); return false); + + return true; + } + + void CInfoContainer::_readFile(const NLMISC::CSString& fileName,uint32& errors,TFileNameSet& fileNameSet) + { + // read in the src file + NLMISC::CSString fileContents; + fileContents.readFromFile(fileName); + DROP_IF(fileContents.empty(),"File not found: "+fileName, ++errors;return); + + // split the file into lines + NLMISC::CVectorSString lines; + fileContents.splitLines(lines); + + // process the lines one by one + for (uint32 i=0;i' but found: "+line, ++errors;continue); + + if (keyword=="domain") { _CurrentInfoBlock->setDomainName(args,context,errors); } + else if (keyword=="shard") { _CurrentInfoBlock->setShardName(args,context,errors); } + else if (keyword=="name") { _CurrentInfoBlock->setUniqueName(args,context,errors); } + else if (keyword=="cmdLine") { _CurrentInfoBlock->setCmdLine(args,context,errors); } + else if (keyword=="host") { _CurrentInfoBlock->setHost(args,context,errors); } + else if (keyword=="startOrder") { _CurrentInfoBlock->setStartOrder(args,context,errors); } + else if (keyword=="use") { _CurrentInfoBlock->addUseEntry(args,context,errors); } + else if (keyword=="data") { _CurrentInfoBlock->addDataEntry(args,context,errors); } + else if (keyword=="cfg") { _CurrentInfoBlock->addCfgEntry(rawArgs,context,errors); } + else if (keyword=="cfgAfter") { _CurrentInfoBlock->addCfgEntryPost(rawArgs,context,errors); } + else if (keyword=="cfgFile") { _CurrentInfoBlock->addCfgFile(args,context,errors); } + else if (keyword=="cfgFileAfter") { _CurrentInfoBlock->addCfgFilePost(args,context,errors); } + else { DROP(context+"Unrecognised keyword: "+line, ++errors;continue); } + } + } + } + + void CInfoContainer::_buildDomainTree(uint32& errors) + { + // iterate over the info block container, setting up 'child' vectors + for (TInfoBlocks::iterator it= _InfoBlocks.begin(); it!= _InfoBlocks.end(); ++it) + { + CInfoBlock& theInfoBlock= *it->second; + theInfoBlock.setupChildren(this,errors); + } + + // display the list of orphans + for (TInfoBlocks::iterator it= _InfoBlocks.begin(); it!= _InfoBlocks.end(); ++it) + { + CInfoBlock& theInfoBlock= *it->second; + WARN_IF(!theInfoBlock.isDomain() && theInfoBlock.getNumParents()==0,"Found unrefferenced info block: "+theInfoBlock.getName()); + } + } + + void CInfoContainer::_buildExeSet(uint32& errors) + { + // iterate over the info block container, looking for domains + for (TInfoBlocks::iterator it= _InfoBlocks.begin(); it!= _InfoBlocks.end(); ++it) + { + CInfoBlock& theInfoBlock= *it->second; + if (theInfoBlock.isDomain()) + { + const NLMISC::CSString& domainName= theInfoBlock.getDomainName(); + DROP_IF(_DomainExes.find(domainName)!=_DomainExes.end(),"Duplicate domain name found: "+domainName,++errors;continue); + nldebug("Building executable set for domain: %s",domainName.c_str()); + theInfoBlock.buildExeSet(this,errors); + } + + // fixup the names in the domain to make them unique + + // run through the exes a first time to determine which unique names are unique and which are not + std::map nameCounts; + for (TExeRecords::iterator it2= _ExeRecords.begin(); it2!=_ExeRecords.end(); ++it2) + { + // skip anything that's not from our domain + if (it2->DomainName!=theInfoBlock.getDomainName()) + continue; + + // get hold of the name + NLMISC::CSString& name= it2->UniqueName; + // yell if the name already looks like a 'fixed up' name + DROP_IF(name.right(3).left(1)=="_" && (name.right(2)=="00" || name.right(2).atoui()!=0),"Appending '_' to name ending in '_00' style format as this can clash with auto renumbering => "+name+'_',name+='_') + // compose a second version of the name with the shard name added + NLMISC::CSString name_with_shard= name+'_'+it2->ShardName; + // insert both versions of the name into the unique name counter + ++nameCounts[name]; + ++nameCounts[name_with_shard]; + } + + // run through the exes a second time to fix names that are not unique + std::map nameIdx; + for (TExeRecords::iterator it2= _ExeRecords.begin(); it2!=_ExeRecords.end(); ++it2) + { + // skip anything that's not from our domain + if (it2->DomainName!=theInfoBlock.getDomainName()) + continue; + + // get hold of the name + NLMISC::CSString& name= it2->UniqueName; + // if the name is unique then continue + if (nameCounts[name]==1) + continue; + + // compose a second version of the name with the shard name added + name+='_'; + name+=it2->ShardName; + // if the name is unique within the shard then continue + if (nameCounts[name]==1) + continue; + + // make the name name unique by appending a number to it + uint32 idx= ++nameIdx[name]; + name+=NLMISC::toString("_%02u",idx); + } + } + } + + void CInfoContainer::serial(NLMISC::IStream& stream) + { + if (stream.isReading()) + { + // start by clearing out our contents... + clear(); + + // get the number of info blocks from the stream + uint32 count; + stream.serial(count); + + // get the info blocks from the stream one by one + for (uint32 i=0;igetName()]= _CurrentInfoBlock; + } + + // setup an error accumulator + uint32 errors= 0; + + // build the blocks into a tree + _buildDomainTree(errors); + + // build the set of executables from the tree + _buildExeSet(errors); + + // make sure that no errors were encountered... + DROP_IF(errors!=0,NLMISC::toString("Serial Failed: %u errors found",errors), clear();return); + + // note - on exit, _CurrentInfoBlock refferences the last info block read + } + else + { + // put the number of info blocks to the stream + uint32 count= (uint32)_InfoBlocks.size(); + stream.serial(count); + // put the info blocks to the stream one by one + for (TInfoBlocks::iterator it= _InfoBlocks.begin(); it!=_InfoBlocks.end(); ++it) + { + stream.serial(*(it->second)); + } + } + } + + void CInfoContainer::getHostNames(THostNames& result) const + { + // clear out the result before we begin work... + result.clear(); + + // use a little set to avoid adding host names more than once + std::set namesFound; + + // fill the result in from our internal data + bool found= false; + for (TExeRecords::const_iterator it= _ExeRecords.begin(); it!=_ExeRecords.end(); ++it) + { + const SExeRecord& theApp= *it; + + // ignore exes that are on hosts that we've already dealt with + if (namesFound.find(theApp.Host)!=namesFound.end()) continue; + + // we've found a new host so add it to our result container + result.push_back(theApp.Host); + namesFound.insert(theApp.Host); + + found=true; + } + + if (!found) + { + // as a note - if we get here it is because the request has failed - no hosts were identified with the given domain + // this is not an error case so we just add a debug for info + nldebug("getHostNames failed - no hosts found"); + } + } + + void CInfoContainer::getDomainNames(TDomainNames& result) const + { + // clear out the result before we begin work... + result.clear(); + + // fill the result in from our internal data + for (TDomainExes::const_iterator dit= _DomainExes.begin(); dit!=_DomainExes.end(); ++dit) + { + const NLMISC::CSString& domainName= dit->first; + result.push_back(domainName); + } + + if (result.empty()) + { + // as a note - if we get here it is because the request has failed - no domains were found + // this is not an error case so we just add a debug for info + nldebug("getDomainNames failed - no domains found"); + } + } + + void CInfoContainer::getShardNames(const TDomainName& domainName,TShardNames& result) const + { + // clear out the result before we begin work... + result.clear(); + + // fill the result in from our internal data + bool found= false; + for (TDomainExes::const_iterator dit= _DomainExes.begin(); dit!=_DomainExes.end(); ++dit) + { + // ignore shards that aren't in the requested domain + const NLMISC::CSString& domName= dit->first; + if (domName!=domainName) continue; + + // run throught he shards for our chosen domain... + const TShardExes& shards= dit->second; + for (TShardExes::const_iterator sit= shards.begin(); sit!=shards.end(); ++sit) + { + const NLMISC::CSString shardName= sit->first; + result.push_back(shardName); + } + + found=true; + } + + if (!found) + { + // as a note - if we get here it is because the request has failed - no shards were identified with the given domain + // this is not an error case so we just add a debug for info + nldebug("getShardNames failed for domainName('%s')",domainName.c_str()); + } + } + + void CInfoContainer::getAppNames(const THostName& hostName,const TDomainName& domainName,TAppNames& result) const + { + // clear out the result before we begin work... + result.clear(); + + // fill the result in from our internal data + bool found= false; + for (TExeRecords::const_iterator it= _ExeRecords.begin(); it!=_ExeRecords.end(); ++it) + { + const SExeRecord& theApp= *it; + + // ignore exes that aren't in the requested domain + if (theApp.DomainName!=domainName) continue; + + // ignore exes that are on the wrong host + if (theApp.Host!=hostName) continue; + + // we've found a new host so add it to our result container + result.push_back(theApp.UniqueName); + + found=true; + } + + if (!found) + { + // as a note - if we get here it is because the request has failed - no apps were identified with the given host and domain + // this is not an error case so we just add a debug for info + nldebug("getAppNames failed for hostName('%s'), domainName('%s')",hostName.c_str(),domainName.c_str()); + } + } + + void CInfoContainer::getAppNames(const THostName& hostName,const TDomainName& domainName,const TShardName& shardName,TAppNames& result) const + { + // clear out the result before we begin work... + result.clear(); + + // fill the result in from our internal data + bool found= false; + for (TExeRecords::const_iterator it= _ExeRecords.begin(); it!=_ExeRecords.end(); ++it) + { + const SExeRecord& theApp= *it; + + // ignore exes that aren't in the requested domain + if (theApp.DomainName!=domainName) continue; + + // ignore exes that are on the wrong host + if (theApp.Host!=hostName) continue; + + // ignore exes that are on the shard host + if (theApp.ShardName!=shardName) continue; + + // we've found a new host so add it to our result container + result.push_back(theApp.UniqueName); + + found=true; + } + + if (!found) + { + // as a note - if we get here it is because the request has failed - no apps were identified with the given host, shard and domain + // this is not an error case so we just add a debug for info + nldebug("getAppNames failed for hostName('%s'), domainName('%s'), shardName('%s')",hostName.c_str(),domainName.c_str(),shardName.c_str()); + } + } + + void CInfoContainer::getHost(const THostName& hostName,SHostDescription& result) const + { + // clear out the result before we begin work... + result.clear(); + result.HostName= hostName; + + // use a set to buildup lists of unique host names + typedef std::set TNameSet; + TNameSet domainNames; + + // fill the result in from our internal data + bool found= false; + for (TExeRecords::const_iterator it= _ExeRecords.begin(); it!=_ExeRecords.end(); ++it) + { + const SExeRecord& theApp= *it; + + // ignore exes that aren't on the requested host + if (theApp.Host!=hostName) continue; + + // add this exe's domain to the domains set + domainNames.insert(theApp.DomainName); + + found=true; + } + + // copy the hosts set to the result record + for (TNameSet::const_iterator it= domainNames.begin(); it!=domainNames.end(); ++it) + { + result.Domains.push_back(*it); + } + + if (!found) + { + // as a note - if we get here it is because the request has failed - no host was identified with the given name + // this is not an error case so we just add a debug for info + nldebug("getHost failed for hostName('%s')",hostName.c_str()); + } + } + + void CInfoContainer::getDomain(const TDomainName& domainName, SDomainDescription& result) const + { + // clear out the result before we begin work... + result.clear(); + result.DomainName= domainName; + + // use a couple of sets to buildup lists of unique host and shard names + typedef std::set TNameSet; + TNameSet hostNames; + TNameSet shardNames; + + // fill the result in from our internal data + bool found= false; + for (TExeRecords::const_iterator it= _ExeRecords.begin(); it!=_ExeRecords.end(); ++it) + { + const SExeRecord& theApp= *it; + + // ignore exes that aren't in the requested domain + if (theApp.DomainName!=domainName) continue; + + // add this exe's shard to the shards set + shardNames.insert(theApp.ShardName); + + // add this exe's host to the hosts set + hostNames.insert(theApp.Host); + + // add this exe's unique name to the result apps record + result.Apps.push_back(theApp.UniqueName); + + found=true; + } + + // copy the hosts set to the result record + for (TNameSet::const_iterator it= hostNames.begin(); it!=hostNames.end(); ++it) + { + result.Hosts.push_back(*it); + } + + // copy the shards set to the result record + for (TNameSet::const_iterator it= shardNames.begin(); it!=shardNames.end(); ++it) + { + result.Shards.push_back(*it); + } + + if (!found) + { + // as a note - if we get here it is because the request has failed - no domain was identified with the given name + // this is not an error case so we just add a debug for info + nldebug("getDomain failed for domainName('%s')",domainName.c_str()); + } + } + + void CInfoContainer::getShard(const TDomainName& domainName,const TShardName& shardName,SShardDescription& result) const + { + // clear out the result before we begin work... + result.clear(); + result.DomainName= domainName; + result.ShardName= shardName; + + // use a set to buildup lists of unique host names + typedef std::set TNameSet; + TNameSet hostNames; + + // fill the result in from our internal data + bool found= false; + for (TExeRecords::const_iterator it= _ExeRecords.begin(); it!=_ExeRecords.end(); ++it) + { + const SExeRecord& theApp= *it; + + // ignore exes that aren't in the requested domain + if (theApp.DomainName!=domainName) continue; + + // ignore exes that aren't in the requested shard + if (theApp.ShardName!=shardName) continue; + + // add this exe's host to the hosts set + hostNames.insert(theApp.Host); + + // add this exe's unique name to the result apps record + result.Apps.push_back(theApp.UniqueName); + + found=true; + } + + // copy the hosts set to the result record + for (TNameSet::const_iterator it= hostNames.begin(); it!=hostNames.end(); ++it) + { + result.Hosts.push_back(*it); + } + + if (!found) + { + // as a note - if we get here it is because the request has failed - no shard was identified with the given name and domain + // this is not an error case so we just add a debug for info + nldebug("getShard failed for domainName('%s'), shardName('%s')",domainName.c_str(),shardName.c_str()); + } + } + + void CInfoContainer::getApp(const TDomainName& domainName,const TAppName& appName,SAppDescription& result) const + { + // clear out the result before we begin work... + result.clear(); + result.DomainName= domainName; + result.AppName= appName; + + // use a set to buildup lists of unique host names + typedef std::set TNameSet; + TNameSet domainNames; + + // fill the result in from our internal data + for (TExeRecords::const_iterator it= _ExeRecords.begin(); it!=_ExeRecords.end(); ++it) + { + const SExeRecord& theApp= *it; + + // skip exes that aren't in the requested domain + if (theApp.DomainName!=domainName) continue; + + // skip exes that don't have the correct name + if (theApp.UniqueName!=appName) continue; + + // we've found the exe so fill in the result record... + result.ShardName= theApp.ShardName; + result.HostName= theApp.Host; + result.StartOrder= theApp.StartOrder; + result.CmdLine= theApp.CmdLine; + + // setup the config file to start initialised with the app name for this app + result.CfgFile= + "// Auto generated config file\n" + "// Use with commandline: "+theApp.CmdLine+"\n" + "AESAliasName= \""+appName+"\";\n" + "\n"; + + // copy the cfg set to the result record (the cfgAfter set should have been merged in already) + for (SExeRecord::TCfgEntries::const_iterator cit= theApp.CfgEntries.begin(); cit!=theApp.CfgEntries.end(); ++cit) + { + result.CfgFile+=*cit; + result.CfgFile+='\n'; + } + + // copy the dataEntries set to the result record + for (SExeRecord::TDataEntries::const_iterator dit= theApp.DataEntries.begin(); dit!=theApp.DataEntries.end(); ++dit) + { + result.DataPacks.push_back(*dit); + } + + // we're all done so we can return merrily + return; + } + + // as a note - if we get here it is because the request has failed - no app was identified with the given name and domain + // this is not an error case so we just add a debug for info + nldebug("getApp failed for domainName('%s'), appName('%s')",domainName.c_str(),appName.c_str()); + } + + void CInfoContainer::dumpDomains(NLMISC::CLog& log) const + { + for (TDomainExes::const_iterator dit= _DomainExes.begin(); dit!=_DomainExes.end(); ++dit) + { + const NLMISC::CSString& domainName= dit->first; + const TShardExes& shards= dit->second; + log.displayNL("-- domain: %s",domainName.c_str()); + + for (TShardExes::const_iterator sit= shards.begin(); sit!=shards.end(); ++sit) + { + const NLMISC::CSString& shardName= sit->first; + const TExeIdx& exeIdx= sit->second; + log.displayNL(" -- shard: %s",shardName.c_str()); + + for (TExeIdx::const_iterator eit= exeIdx.begin(); eit!=exeIdx.end(); ++eit) + { + uint32 idx= *eit; + nlassert(idx<_ExeRecords.size()); + const SExeRecord& theExe= _ExeRecords[idx]; + log.displayNL(" -- %s:%s (%s)",theExe.Host.c_str(),theExe.CmdLine.c_str(),theExe.UniqueName.c_str()); + } + } + } + } + + void CInfoContainer::dumpInfoBlocks(NLMISC::CLog& log) const + { + log.displayNL("//------------------------------------------------------------------------------"); + log.displayNL("// Dump of cfg database file contents"); + log.displayNL("//------------------------------------------------------------------------------"); + for (TInfoBlocks::const_iterator it=_InfoBlocks.begin(); it!=_InfoBlocks.end(); ++it) + { + it->second->dump(log); + } + log.displayNL("//------------------------------------------------------------------------------"); + } + + CInfoBlock* CInfoContainer::getInfoBlock(const NLMISC::CSString& name) + { + TInfoBlocks::iterator it= _InfoBlocks.find(name); + return (it==_InfoBlocks.end())? NULL: it->second; + } + + void CInfoContainer::addExe(const SExeRecord& exeRecord,uint32& errors) + { + // nldebug("Adding CmdLine: %s",exeRecord.FullName.c_str()); + + // note: if we hit errors then we continue anyway to make sure we display a complete set of error messages + DROP_IF(exeRecord.DomainName.empty(), "No 'domain' property found in: "+exeRecord.FullName, ++errors ); + DROP_IF(exeRecord.ShardName.empty(), "No 'shard' property found in: "+exeRecord.FullName, ++errors ); + DROP_IF(exeRecord.CmdLine.empty(), "No 'cmdLine' property found in: "+exeRecord.FullName, ++errors ); + DROP_IF(exeRecord.Host.empty(), "No 'host' property found in: "+exeRecord.FullName, ++errors ); + DROP_IF(exeRecord.CfgEntries.empty(), "No 'cfg' entriesfound in: "+exeRecord.FullName, ++errors ); + + // add a refference from the domains' shard map to the exe... + _DomainExes[exeRecord.DomainName][exeRecord.ShardName].push_back((uint32)_ExeRecords.size()); + + // we may have hit errors but we go ahead anyway as in the case of errors the whole thing will be cleared out anyway + _ExeRecords.push_back(exeRecord); + } + + //----------------------------------------------------------------------------- + // methods CDeploymentConfigurationImplementation + //----------------------------------------------------------------------------- + + bool CDeploymentConfigurationImplementation::read(const NLMISC::CSString& fileName) + { + // setup a temp container to hold the version of the file that we're reading + CInfoContainer container; + + // do the reading and make sure we catch any possible execeptions (like for read in progress) + try + { + container.read(fileName); + } + catch(...) + { + container.clear(); + } + + // if the read failed for whatever reason then giveup + DROP_IF(container.empty(),"Failed to update deployment configuration from file: "+fileName,return false); + + // copy the temp container into our internal object + _InfoContainer= container; + + // display a funky victory message + nlinfo("Deployment configuration successfully updated from file: %s",fileName.c_str()); + + return true; + } + + void CDeploymentConfigurationImplementation::write(const NLMISC::CSString& fileName) + { + // create a displayer to gather the output of the command + class CStringDisplayer: public IDisplayer + { + public: + NLMISC::CSString Data; + void doDisplay( const CLog::TDisplayInfo& args, const char *message) + { + Data += message; + } + }; + + // instantiate the displayer and a log object and assign one to the other + CStringDisplayer stringDisplayer; + NLMISC::CLog myLog; + myLog.addDisplayer(&stringDisplayer); + + // dump the info blocks to our log object (accumulating the result as a string) + dumpInfoBlocks(myLog); + + // write the text accumulated in the log object to a text file + stringDisplayer.Data.writeToFile(fileName); + } + + void CDeploymentConfigurationImplementation::serial(NLMISC::IStream& stream) + { + // setup a temp container to hold the version of the file that we're reading (if we're reading) + // and fill the container in with our internal object just in case we're writing + CInfoContainer container= _InfoContainer; + + // do the serial and make sure we catch any possible execeptions (like for read in progress) + try + { + stream.serial(container); + } + catch(...) + { + container.clear(); + } + + // if the serial failed for whatever reason then giveup + DROP_IF(container.empty(),"Failed to serial deployment configuration: ",return); + + // copy the temp container into our internal object (incase this was a read operation) + _InfoContainer= container; + + // display a funky victory message + nlinfo("Deployment configuration successfully serialised"); + } + + void CDeploymentConfigurationImplementation::getDomainNames(TDomainNames& result) const + { + _InfoContainer.getDomainNames(result); + } + + void CDeploymentConfigurationImplementation::getShardNames(const TDomainName& domainName,TShardNames& result) const + { + _InfoContainer.getShardNames(domainName,result); + } + + void CDeploymentConfigurationImplementation::getHostNames(THostNames& result) const + { + _InfoContainer.getHostNames(result); + } + + void CDeploymentConfigurationImplementation::getAppNames(const THostName& hostName,const TDomainName& domainName,TAppNames& result) const + { + _InfoContainer.getAppNames(hostName,domainName,result); + } + + void CDeploymentConfigurationImplementation::getAppNames(const THostName& hostName,const TDomainName& domainName,const TShardName& shardName,TAppNames& result) const + { + _InfoContainer.getAppNames(hostName,domainName,shardName,result); + } + + void CDeploymentConfigurationImplementation::getHost(const THostName& hostName,SHostDescription& result) const + { + _InfoContainer.getHost(hostName,result); + } + + void CDeploymentConfigurationImplementation::getDomain(const TDomainName& domainName, SDomainDescription& result) const + { + _InfoContainer.getDomain(domainName,result); + } + + void CDeploymentConfigurationImplementation::getShard(const TDomainName& domainName,const TShardName& shardName,SShardDescription& result) const + { + _InfoContainer.getShard(domainName,shardName,result); + } + + void CDeploymentConfigurationImplementation::getApp(const TDomainName& domainName,const TAppName& appName,SAppDescription& result) const + { + _InfoContainer.getApp(domainName,appName,result); + } + + void CDeploymentConfigurationImplementation::dumpInfoBlocks(NLMISC::CLog& log) const + { + _InfoContainer.dumpInfoBlocks(log); + } + + void CDeploymentConfigurationImplementation::dumpDomains(NLMISC::CLog& log) const + { + _InfoContainer.dumpDomains(log); + } + + + //----------------------------------------------------------------------------- + // methods CDeploymentConfiguration + //----------------------------------------------------------------------------- + + CDeploymentConfiguration& CDeploymentConfiguration::getInstance() + { + return CSingleton::getInstance(); + } + +} // end of namespace + +//NLMISC_CATEGORISED_COMMAND(depcfg,readDepCfgFile,"(re)read the deployment cfg file","[=\"server_park_database.txt\"]") +//{ +// NLMISC::CSString fileName= defaultDeploymentConfigurationFileName; +// +// switch (args.size()) +// { +// case 1: +// fileName=args[0]; +// break; +// +// case 0: +// break; +// +// default: +// return false; +// } +// +// DEPCFG::CDeploymentConfiguration::getInstance().read(fileName); +// +// return true; +//} +// +//NLMISC_CATEGORISED_COMMAND(depcfg,writeDepCfgFile,"write the deployment cfg file","[=\"saved_server_park_database.txt\"]") +//{ +// NLMISC::CSString fileName= CSString("saved_") + defaultDeploymentConfigurationFileName; +// +// switch (args.size()) +// { +// case 1: +// fileName=args[0]; +// break; +// +// case 0: +// break; +// +// default: +// return false; +// } +// +// DEPCFG::CDeploymentConfiguration::getInstance().read(fileName); +// +// return true; +//} +// +//NLMISC_CATEGORISED_COMMAND(depcfg,saveDepCfgBinary,"write a binary version of the deployment file to disk","") +//{ +// if (args.size()!=1) +// return false; +// +// NLMISC::COFile outf(args[0]); +// outf.serial(DEPCFG::CDeploymentConfiguration::getInstance()); +// +// return true; +//} +// +//NLMISC_CATEGORISED_COMMAND(depcfg,loadDepCfgBinary,"read a binary version of the deployment file from disk","") +//{ +// if (args.size()!=1) +// return false; +// +// NLMISC::CIFile inf(args[0]); +// inf.serial(DEPCFG::CDeploymentConfiguration::getInstance()); +// +// return true; +//} + +NLMISC_CATEGORISED_COMMAND(depcfg,dumpDepCfgInfoBlocks,"dump the raw info blocks for the deployment config singleton","") +{ + if (args.size()!=0) + return false; + + DEPCFG::CDeploymentConfiguration::getInstance().dumpInfoBlocks(log); + + return true; +} + +NLMISC_CATEGORISED_COMMAND(depcfg,dumpDepCfgDomains,"dump the domain set for the deployment config singleton","") +{ + if (args.size()!=0) + return false; + + DEPCFG::CDeploymentConfiguration::getInstance().dumpDomains(log); + + return true; +} + +NLMISC_CATEGORISED_COMMAND(depcfg,dumpDepCfgHosts,"dump the host set for the deployment config singleton","") +{ + if (args.size()!=0) + return false; + + log.displayNL("--------------------------------------------"); + log.displayNL("Hosts"); + log.displayNL("--------------------------------------------"); + + DEPCFG::THostNames hostNames; + DEPCFG::CDeploymentConfiguration::getInstance().getHostNames(hostNames); + sort(hostNames.begin(),hostNames.end()); + for (DEPCFG::THostNames::iterator hit= hostNames.begin(); hit!=hostNames.end(); ++hit) + { + DEPCFG::SHostDescription host; + DEPCFG::CDeploymentConfiguration::getInstance().getHost(*hit,host); + log.displayNL("Host %s (%d domains)",host.HostName.c_str(),host.Domains.size()); + + for (DEPCFG::TDomainNames::iterator dit= host.Domains.begin(); dit!=host.Domains.end(); ++dit) + { + log.displayNL("-- Domain %s",dit->c_str()); + } + } + + return true; +} + +NLMISC_CATEGORISED_COMMAND(depcfg,dumpDepCfgShards,"dump the shard set for the deployment config singleton","") +{ + if (args.size()!=0) + return false; + + log.displayNL("--------------------------------------------"); + log.displayNL("Shards"); + log.displayNL("--------------------------------------------"); + + DEPCFG::TDomainNames domainNames; + DEPCFG::CDeploymentConfiguration::getInstance().getDomainNames(domainNames); + sort(domainNames.begin(),domainNames.end()); + for (DEPCFG::TDomainNames::iterator dit= domainNames.begin(); dit!=domainNames.end(); ++dit) + { + DEPCFG::SDomainDescription domain; + DEPCFG::CDeploymentConfiguration::getInstance().getDomain(*dit,domain); + log.displayNL("Domain %s (%d shards with %d apps on %d hosts)",domain.DomainName.c_str(),domain.Shards.size(),domain.Apps.size(),domain.Hosts.size()); + + DEPCFG::TShardNames shardNames; + DEPCFG::CDeploymentConfiguration::getInstance().getShardNames(*dit,shardNames); + nlassert(shardNames==domain.Shards); + for (DEPCFG::TShardNames::iterator sit= shardNames.begin(); sit!=shardNames.end(); ++sit) + { + DEPCFG::SShardDescription shard; + DEPCFG::CDeploymentConfiguration::getInstance().getShard(*dit,*sit,shard); + log.displayNL("-- Shard %s/%s (%d apps on %d hosts)",shard.DomainName.c_str(),shard.ShardName.c_str(),shard.Apps.size(),shard.Hosts.size()); + + for (DEPCFG::THostNames::iterator hit= shard.Hosts.begin(); hit!=shard.Hosts.end(); ++hit) + { + log.displayNL(" -- Host %s",hit->c_str()); + DEPCFG::TAppNames appNames; + DEPCFG::CDeploymentConfiguration::getInstance().getAppNames(*hit,*dit,*sit,appNames); + for (DEPCFG::TAppNames::iterator ait= appNames.begin(); ait!=appNames.end(); ++ait) + { + DEPCFG::SAppDescription app; + DEPCFG::CDeploymentConfiguration::getInstance().getApp(*dit,*ait,app); + uint32 cfgFileLines=app.CfgFile.countLines(); + uint32 numDataPacks= (uint32)app.DataPacks.size(); + log.displayNL(" -- App: %-20s: %s (cfg file length: %d lines, data packs used: %d)",app.AppName.c_str(),app.CmdLine.c_str(),cfgFileLines,numDataPacks); + } + } + } + } + + return true; +} diff --git a/code/ryzom/common/src/game_share/deployment_configuration.h b/code/ryzom/common/src/game_share/deployment_configuration.h new file mode 100644 index 000000000..457d6ee0b --- /dev/null +++ b/code/ryzom/common/src/game_share/deployment_configuration.h @@ -0,0 +1,265 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +#ifndef DEPLOYMENT_CONFIGURATION_H +#define DEPLOYMENT_CONFIGURATION_H + +//----------------------------------------------------------------------------- +// include +//----------------------------------------------------------------------------- + +// nel +#include "nel/misc/types_nl.h" +#include "nel/misc/common.h" +#include "nel/misc/sstring.h" + + +//----------------------------------------------------------------------------- +// namespace DEPCFG +//----------------------------------------------------------------------------- + +namespace DEPCFG +{ + //----------------------------------------------------------------------------- + // some handy constants + //----------------------------------------------------------------------------- + + #define defaultDeploymentConfigurationFileName "server_park_database.txt" + + + //----------------------------------------------------------------------------- + // some handy typedefs for identifiers, map keys, etc + //----------------------------------------------------------------------------- + + typedef NLMISC::CSString TDomainName; + typedef NLMISC::CSString TShardName; + typedef NLMISC::CSString THostName; + typedef NLMISC::CSString TAppName; + + typedef NLMISC::CVectorSString TDomainNames; + typedef NLMISC::CVectorSString TShardNames; + typedef NLMISC::CVectorSString THostNames; + typedef NLMISC::CVectorSString TAppNames; + + typedef NLMISC::CSString TCmdLine; + typedef NLMISC::CSString TCfgFile; + typedef NLMISC::CVectorSString TDataPacks; + + + //----------------------------------------------------------------------------- + // struct SDomainDescription + //----------------------------------------------------------------------------- + + struct SDomainDescription + { + //------------------------------------------------------------------------- + // identifying the domain + TDomainName DomainName; + //------------------------------------------------------------------------- + // the set of shards and apps belonging to this domain and their hosts + TShardNames Shards; + THostNames Hosts; + TAppNames Apps; + + //------------------------------------------------------------------------- + // a handy 'clear()' method + void clear() + { + DomainName.clear(); + Shards.clear(); + Hosts.clear(); + Apps.clear(); + } + }; + + + //----------------------------------------------------------------------------- + // struct SShardDescription + //----------------------------------------------------------------------------- + + struct SShardDescription + { + //------------------------------------------------------------------------- + // identifying the shard by name and domain + TDomainName DomainName; + TShardName ShardName; + //------------------------------------------------------------------------- + // the set of hosts and apps used by this shard + THostNames Hosts; + TAppNames Apps; + + //------------------------------------------------------------------------- + // a handy 'clear()' method + void clear() + { + DomainName.clear(); + ShardName.clear(); + Hosts.clear(); + Apps.clear(); + } + }; + + + //----------------------------------------------------------------------------- + // struct SHostDescription + //----------------------------------------------------------------------------- + + struct SHostDescription + { + //------------------------------------------------------------------------- + // identifying the host (machine's network name) + THostName HostName; + //------------------------------------------------------------------------- + // the set of domains that refference this host + TDomainNames Domains; + + //------------------------------------------------------------------------- + // a handy 'clear()' method + void clear() + { + HostName.clear(); + Domains.clear(); + } + }; + + + //----------------------------------------------------------------------------- + // struct SAppDescription + //----------------------------------------------------------------------------- + + struct SAppDescription + { + //------------------------------------------------------------------------- + // identifying the app, the shard it belongs to, machine it runs on, etc + TDomainName DomainName; + TShardName ShardName; + THostName HostName; + TAppName AppName; + NLMISC::CSString StartOrder; + + //------------------------------------------------------------------------- + // some real data + TCmdLine CmdLine; // the command line to execute the app + TCfgFile CfgFile; // the cfg file contents for the app + TDataPacks DataPacks; // the set of data packs for the app + + //------------------------------------------------------------------------- + // a handy 'clear()' method + void clear() + { + DomainName.clear(); + ShardName.clear(); + HostName.clear(); + AppName.clear(); + StartOrder.clear(); + CmdLine.clear(); + CfgFile.clear(); + DataPacks.clear(); + } + }; + + + //----------------------------------------------------------------------------- + // class CDeploymentConfiguration + //----------------------------------------------------------------------------- + + class CDeploymentConfiguration + { + public : + //------------------------------------------------------------------------- + // this is a singleton so we have a getInstance() method + // remaining methods are pure virtuals... + + // get hold of the instance of the singleton that derives from CDeploymentConfiguration + static CDeploymentConfiguration& getInstance(); + + + //------------------------------------------------------------------------- + // methods for reading / serialising deployment configuration + + // read the deployment configuration from a specified file + // + // file format is line base with the following format: + // '//'... comment to end of line + // 'define' // define a new block + // 'domain' // flag this block as a domain and give it a name + // 'shard' // flag this block as a shard and give it a name + // 'use' // add a child block to this block + // 'name' // set the unique name to use for the executables derived from this block + // 'cmdLine' // setup the command line to use for exes derived from this block + // 'host' // assign the exes derived from this block to a given host + // 'cfg' // add a line to be included in the cfg file of executables derived from this block + // 'cfgAfter' // as above but cfg lines appended at end of cfg file (not at start) + // 'data' // add dependency on a given data block to exes derived from this block + // + virtual bool read(const NLMISC::CSString& fileName) =0; + + // write the info blocks out to a file (in no particular order) + // the output file can be re-read via the 'read()' method + virtual void write(const NLMISC::CSString& fileName) =0; + + // serialise the deployment configuration, for dispatch to / reception from other apps + virtual void serial(NLMISC::IStream& stream) =0; + + + //------------------------------------------------------------------------- + // read accessors - getting sets of names + + // get the complete set of hosts (machines on which we have apps running) + virtual void getHostNames(THostNames& result) const =0; + + // get the complete set of domains + virtual void getDomainNames(TDomainNames& result) const =0; + + // get the shards for a given domain + virtual void getShardNames(const TDomainName& domainName,TShardNames& result) const =0; + + // get the apps for a given host and domain + virtual void getAppNames(const THostName& hostName,const TDomainName& domainName,TAppNames& result) const =0; + + // get the apps for a given host, domain and shard + virtual void getAppNames(const THostName& hostName,const TDomainName& domainName,const TShardName& shardName,TAppNames& result) const =0; + + + //------------------------------------------------------------------------- + // read accessors - getting info structure for a named object + + // get a named host + virtual void getHost(const THostName& hostName,SHostDescription& result) const =0; + + // get a named domains + virtual void getDomain(const TDomainName& domainName, SDomainDescription& result) const =0; + + // get a named shard for a given domain + virtual void getShard(const TDomainName& domainName,const TShardName& shardName,SShardDescription& result) const =0; + + // get a named app for a given domain + virtual void getApp(const TDomainName& domainName,const TAppName& appName,SAppDescription& result) const =0; + + + //------------------------------------------------------------------------- + // methods for dumping info to a given log + + // dump raw information (organised by info block, not by domain or host) + virtual void dumpInfoBlocks(NLMISC::CLog& log) const =0; + + // dump info organised by domain + virtual void dumpDomains(NLMISC::CLog& log) const =0; + }; + +} // end of namespace + +//----------------------------------------------------------------------------- +#endif diff --git a/code/ryzom/common/src/game_share/entity_types.h b/code/ryzom/common/src/game_share/entity_types.h index 3841f9a17..68b42e954 100644 --- a/code/ryzom/common/src/game_share/entity_types.h +++ b/code/ryzom/common/src/game_share/entity_types.h @@ -130,7 +130,7 @@ const TCoord THRESHOLD_BEHAVIOUR = 60000; // Name const TPropIndex PROPERTY_NAME_STRING_ID = 6; -const TCoord THRESHOLD_NAME_STRING_ID = 25000; +const TCoord THRESHOLD_NAME_STRING_ID = 100000; // Main target const TPropIndex PROPERTY_TARGET_ID = 7; diff --git a/code/ryzom/common/src/game_share/game_share.vcproj b/code/ryzom/common/src/game_share/game_share.vcproj deleted file mode 100644 index a8a8e2d4b..000000000 --- a/code/ryzom/common/src/game_share/game_share.vcproj +++ /dev/null @@ -1,1720 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/code/ryzom/common/src/game_share/generate_client_db.xslt b/code/ryzom/common/src/game_share/generate_client_db.xslt index d14903519..0680a3e39 100644 --- a/code/ryzom/common/src/game_share/generate_client_db.xslt +++ b/code/ryzom/common/src/game_share/generate_client_db.xslt @@ -297,13 +297,13 @@ inline void _getProp(const CCDBSynchronised &db, ICDBStructNode *node, NLMISC::C - + class { public: - + private: ICDBStructNode *_BranchNode; diff --git a/code/ryzom/common/src/game_share/inventories.h b/code/ryzom/common/src/game_share/inventories.h index 1fd1cab48..2dfbb85bf 100644 --- a/code/ryzom/common/src/game_share/inventories.h +++ b/code/ryzom/common/src/game_share/inventories.h @@ -349,7 +349,7 @@ namespace INVENTORIES /// Serial from/to bit stream template - void serialAll( NLMISC::CBitMemStream& bms, const CInventoryCategoryTemplate *templ=0 ) + void serialAll( NLMISC::CBitMemStream& bms, const CInventoryCategoryTemplate * /* templ */ =0 ) { bms.serial( _SlotIndex, CInventoryCategoryTemplate::SlotBitSize ); @@ -385,7 +385,7 @@ namespace INVENTORIES /// Serial from/to bit stream template - void serialOneProp( NLMISC::CBitMemStream& bms, const CInventoryCategoryTemplate *templ=0 ) + void serialOneProp( NLMISC::CBitMemStream& bms, const CInventoryCategoryTemplate * /* templ */ =0 ) { bms.serial( _SlotIndex, CInventoryCategoryTemplate::SlotBitSize ); bms.serial( _OneProp ); diff --git a/code/ryzom/common/src/game_share/item_infos.cpp b/code/ryzom/common/src/game_share/item_infos.cpp index a968ff8a4..af84c5d6c 100644 --- a/code/ryzom/common/src/game_share/item_infos.cpp +++ b/code/ryzom/common/src/game_share/item_infos.cpp @@ -73,6 +73,7 @@ CItemInfos::CItemInfos() LacustreMagicResistance = 0; JungleMagicResistance = 0; PrimaryRootMagicResistance = 0; + PetNumber = 0; // 1 based! } void CItemInfos::serial(NLMISC::IStream & s) @@ -130,5 +131,6 @@ void CItemInfos::serial(NLMISC::IStream & s) s.serial( CustomText ); s.serial( R2ItemDescription ); s.serial( R2ItemComment ); + s.serial( PetNumber ); } diff --git a/code/ryzom/common/src/game_share/item_infos.h b/code/ryzom/common/src/game_share/item_infos.h index ff34bfddc..3fd94444e 100644 --- a/code/ryzom/common/src/game_share/item_infos.h +++ b/code/ryzom/common/src/game_share/item_infos.h @@ -139,6 +139,7 @@ public: ucstring CustomText; ucstring R2ItemDescription; ucstring R2ItemComment; + uint8 PetNumber; // 1 based pet index //@} }; diff --git a/code/ryzom/common/src/game_share/mirror_prop_value.h b/code/ryzom/common/src/game_share/mirror_prop_value.h index 08e96761d..1bb4c7571 100644 --- a/code/ryzom/common/src/game_share/mirror_prop_value.h +++ b/code/ryzom/common/src/game_share/mirror_prop_value.h @@ -22,7 +22,7 @@ #include "nel/misc/types_nl.h" #include "nel/misc/stream.h" #include "mirrored_data_set.h" - +#include /** * Read-only handler of a value of a property. @@ -1318,4 +1318,4 @@ protected: #endif // NL_MIRROR_PROP_VALUE_H -/* End of mirror_prop_value.h */ \ No newline at end of file +/* End of mirror_prop_value.h */ diff --git a/code/ryzom/common/src/game_share/mirror_prop_value_inline.h b/code/ryzom/common/src/game_share/mirror_prop_value_inline.h index cd4c71f4a..2824977f3 100644 --- a/code/ryzom/common/src/game_share/mirror_prop_value_inline.h +++ b/code/ryzom/common/src/game_share/mirror_prop_value_inline.h @@ -25,6 +25,7 @@ #include "nel/misc/common.h" //#endif +#include /* * Activate this define if you want to set a value into the mirror only if it is different from the previous value @@ -937,7 +938,7 @@ CMirrorPropValueAlice& CMirrorPropValueAlicetempReassign( srcValue ); } return *this; } @@ -1005,7 +1006,7 @@ NLNET::TServiceId8 CMirrorPropValueAlice::getWriterSer if ( _InMirror ) return CMirrorPropValue::getWriterServiceId(); else - return ~0; + return NLNET::TServiceId8(std::numeric_limits::max()); } #endif diff --git a/code/ryzom/common/src/game_share/msg_ais_egs_gen.h b/code/ryzom/common/src/game_share/msg_ais_egs_gen.h index d7bfc39e7..e08716a4d 100644 --- a/code/ryzom/common/src/game_share/msg_ais_egs_gen.h +++ b/code/ryzom/common/src/game_share/msg_ais_egs_gen.h @@ -884,6 +884,7 @@ namespace RYMSG std::vector< NLMISC::CSheetId > _LootList; // NLMISC::CSheetId _Outpost; + uint32 _Organization; // float _MaxHitRangeForPC; // @@ -1336,6 +1337,21 @@ namespace RYMSG _Outpost = value; + } + + // + uint32 getOrganization() const + { + return _Organization; + } + + void setOrganization(uint32 value) + { + + + _Organization = value; + + } // float getMaxHitRangeForPC() const @@ -1431,6 +1447,7 @@ namespace RYMSG && _ContextOptions == other._ContextOptions && _LootList == other._LootList && _Outpost == other._Outpost + && _Organization == other._Organization && _MaxHitRangeForPC == other._MaxHitRangeForPC && _UserModelId == other._UserModelId && _CustomLootTableId == other._CustomLootTableId @@ -1489,6 +1506,7 @@ namespace RYMSG s.serialCont(_ContextOptions); s.serialCont(_LootList); s.serial(_Outpost); + s.serial(_Organization); s.serial(_MaxHitRangeForPC); s.serial(_UserModelId); s.serial(_CustomLootTableId); diff --git a/code/ryzom/common/src/game_share/persistent_data_inline.h b/code/ryzom/common/src/game_share/persistent_data_inline.h index 2500c524d..9a682afdb 100644 --- a/code/ryzom/common/src/game_share/persistent_data_inline.h +++ b/code/ryzom/common/src/game_share/persistent_data_inline.h @@ -420,7 +420,9 @@ inline const CPersistentDataRecord::CArg& CPersistentDataRecord::popNextArg(TTok inline void CPersistentDataRecord::popNextArg(TToken token,CPersistentDataRecord::CArg& result) { #ifdef NL_DEBUG - BOMB_IF(peekNextToken()!=token,"Error on read code - token requested doesn't match token found",return); + BOMB_IF(peekNextToken()!=token,"Error on read code - token requested doesn't match token found",return); + #else + nlunreferenced(token); #endif peekNextArg(result); @@ -445,7 +447,6 @@ inline void CPersistentDataRecord::popNextArg(TToken token,CPersistentDataRecord ++_ArgOffset; ++_TokenOffset; } - return; } //inline CPersistentDataRecord::CArg CPersistentDataRecord::popNextArg(TToken token) diff --git a/code/ryzom/common/src/game_share/persistent_data_template.h b/code/ryzom/common/src/game_share/persistent_data_template.h index ef76101cd..21cb2588d 100644 --- a/code/ryzom/common/src/game_share/persistent_data_template.h +++ b/code/ryzom/common/src/game_share/persistent_data_template.h @@ -175,18 +175,58 @@ #include "nel/misc/hierarchical_timer.h" inline uint32 saveGameCycleToSecond(NLMISC::TGameCycle tick) { + // Evaluate the UTC of this event (with the current date of save). Suppose that 1 second==10 tick + // NB: result should be positive since no event should have been launched before 1970! + if (tick < CTickEventHandler::getGameCycle()) + { + NLMISC::TGameCycle tick_dt = CTickEventHandler::getGameCycle() - tick; + uint32 s_dt = tick_dt / 10; + return NLMISC::CTime::getSecondsSince1970() - s_dt; + } + else + { + NLMISC::TGameCycle tick_dt = tick - CTickEventHandler::getGameCycle(); + uint32 s_dt = tick_dt / 10; + return NLMISC::CTime::getSecondsSince1970() + s_dt; + } +} +inline NLMISC::TGameCycle loadSecondToGameCycle(uint32 second) +{ + if (second < NLMISC::CTime::getSecondsSince1970()) + { + uint32 s_dt = NLMISC::CTime::getSecondsSince1970() - second; + NLMISC::TGameCycle tick_dt = s_dt * 10; + return CTickEventHandler::getGameCycle() - tick_dt; + } + else + { + uint32 s_dt = second - NLMISC::CTime::getSecondsSince1970(); + NLMISC::TGameCycle tick_dt = s_dt * 10; + return CTickEventHandler::getGameCycle() + tick_dt; + } +} + +/*inline uint32 saveGameCycleToSecond(NLMISC::TGameCycle tick) +{ + sint32 dt = CTickEventHandler::getGameCycle() - tick; + + // Evaluate the UTC of this event (with the current date of save). Suppose that 1 second==10 tick - return sint32(NLMISC::CTime::getSecondsSince1970()) + (sint32(tick) - sint32(CTickEventHandler::getGameCycle()))/10; + if (tick < CTickEventHandler::getGameCycle()) + return NLMISC::CTime::getSecondsSince1970(); + else + return NLMISC::CTime::getSecondsSince1970() + (tick - CTickEventHandler::getGameCycle())/10; // NB: result should be positive since no event should have been launched before 1970! } inline NLMISC::TGameCycle loadSecondToGameCycle(uint32 second) { + if (second < NLMISC::CTime::getSecondsSince1970()) + return 0; + // Convert UTC of the event to game cycle. Suppose that 1 second==10 tick - sint32 newTick= CTickEventHandler::getGameCycle() + (sint32(second) - sint32(NLMISC::CTime::getSecondsSince1970()))*10; - // If game cycle is loaded on a server where current game cycle is too young, we can have here negative values => avoid them - return std::max(newTick, sint32(0)); -} + return CTickEventHandler::getGameCycle() + (second - NLMISC::CTime::getSecondsSince1970())*10; +}*/ #endif // GameCycle property (saved as a UTC of the current game cycle, support server migration) diff --git a/code/ryzom/common/src/game_share/pvp_mode.cpp b/code/ryzom/common/src/game_share/pvp_mode.cpp index aa3ac1496..3e13fd428 100644 --- a/code/ryzom/common/src/game_share/pvp_mode.cpp +++ b/code/ryzom/common/src/game_share/pvp_mode.cpp @@ -35,6 +35,8 @@ namespace PVP_MODE NL_STRING_CONVERSION_TABLE_ENTRY(PvpZoneOutpost) NL_STRING_CONVERSION_TABLE_ENTRY(PvpFaction) NL_STRING_CONVERSION_TABLE_ENTRY(PvpFactionFlagged) + NL_STRING_CONVERSION_TABLE_ENTRY(PvpZoneSafe) + NL_STRING_CONVERSION_TABLE_ENTRY(PvpSafe) NL_END_STRING_CONVERSION_TABLE(TPVPMode, PVPModeConversion, Unknown) TPVPMode fromString(const std::string & str) diff --git a/code/ryzom/common/src/game_share/pvp_mode.h b/code/ryzom/common/src/game_share/pvp_mode.h index dd52f1fd6..0e654752f 100644 --- a/code/ryzom/common/src/game_share/pvp_mode.h +++ b/code/ryzom/common/src/game_share/pvp_mode.h @@ -32,10 +32,12 @@ namespace PVP_MODE PvpZoneOutpost = 32, PvpFaction = 64, PvpFactionFlagged = 128, + PvpZoneSafe = 256, + PvpSafe = 512, Unknown, NbModes = Unknown, - NbBits = 8 // number of bits needed to store all valid values + NbBits = 10 // number of bits needed to store all valid values }; diff --git a/code/ryzom/common/src/game_share/ryzom_mirror_properties.h b/code/ryzom/common/src/game_share/ryzom_mirror_properties.h index 0aab0b870..afd0ac892 100644 --- a/code/ryzom/common/src/game_share/ryzom_mirror_properties.h +++ b/code/ryzom/common/src/game_share/ryzom_mirror_properties.h @@ -138,7 +138,7 @@ void initRyzomVisualPropertyIndices( CMirroredDataSet& dataset ); #define TYPE_BOT_TRADE_SELECTOR2 uint64 #define TYPE_EVENT_FACTION_ID uint32 -#define TYPE_PVP_MODE uint8 +#define TYPE_PVP_MODE uint32 #define TYPE_PVP_CLAN uint32 #define TYPE_FUEL bool diff --git a/code/ryzom/common/src/game_share/send_chat.h b/code/ryzom/common/src/game_share/send_chat.h index cefb8bba0..1efa7acee 100644 --- a/code/ryzom/common/src/game_share/send_chat.h +++ b/code/ryzom/common/src/game_share/send_chat.h @@ -115,7 +115,7 @@ inline void npcChatToChannelEx(const TDataSetRow &senderId, CChatGroup::TGroupTy * Chat group can be constructed from CChatGroup class. * sentence is the sentence to be sent. */ -inline void npcChatToChannelSentence(const TDataSetRow &senderId, CChatGroup::TGroupType groupType, std::string& sentence) +inline void npcChatToChannelSentence(const TDataSetRow &senderId, CChatGroup::TGroupType groupType, ucstring& sentence) { NLNET::CMessage msgout("NPC_CHAT_SENTENCE"); msgout.serial(const_cast(senderId)); diff --git a/code/ryzom/common/src/game_share/singleton_registry.h b/code/ryzom/common/src/game_share/singleton_registry.h index 516417c32..7a9cc0253 100644 --- a/code/ryzom/common/src/game_share/singleton_registry.h +++ b/code/ryzom/common/src/game_share/singleton_registry.h @@ -58,6 +58,7 @@ protected: // protect from untrolled instantiation // this method registers the singleton with the singleton registry IServiceSingleton(); + virtual ~IServiceSingleton() {} private: // prohibit copy diff --git a/code/ryzom/common/src/game_share/sp_type.cpp b/code/ryzom/common/src/game_share/sp_type.cpp index 1ab59ed04..a05a8b554 100644 --- a/code/ryzom/common/src/game_share/sp_type.cpp +++ b/code/ryzom/common/src/game_share/sp_type.cpp @@ -51,4 +51,4 @@ std::map CSPType::_ValueMap; // End of static implementation of CSPType -} // End of EGSPD \ No newline at end of file +} // End of EGSPD diff --git a/code/ryzom/common/src/game_share/txt_command.h b/code/ryzom/common/src/game_share/txt_command.h new file mode 100644 index 000000000..054f1bc93 --- /dev/null +++ b/code/ryzom/common/src/game_share/txt_command.h @@ -0,0 +1,174 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +#ifndef TXT_COMMAND_H +#define TXT_COMMAND_H + + +//------------------------------------------------------------------------------------------------- +// includes +//------------------------------------------------------------------------------------------------- + +#include "nel/misc/types_nl.h" +#include "nel/misc/common.h" +#include "nel/misc/debug.h" +#include "nel/misc/sstring.h" + + +//------------------------------------------------------------------------------------------------- +// MACRO TXT_COMMAND_SET +//------------------------------------------------------------------------------------------------- + +#define TXT_COMMAND_SET(setName,CONTEXT_CLASS)\ +class __CTxtCommandSet_##setName: public ITxtCommandSet\ +{\ +public:\ + static __CTxtCommandSet_##setName* getInstance()\ + {\ + static __CTxtCommandSet_##setName *p=NULL;\ + if (p==NULL) p= new __CTxtCommandSet_##setName;\ + return p;\ + }\ +};\ +static CTxtCommandSetPtr<__CTxtCommandSet_##setName> setName; + + +//------------------------------------------------------------------------------------------------- +// MACRO TXT_COMMAND +//------------------------------------------------------------------------------------------------- + +#define TXT_COMMAND(cmdName,setName,CONTEXT_CLASS)\ +struct __CTxtCommand_##cmdName##CONTEXT_CLASS: public ITxtCommand\ +{\ + static __CTxtCommand_##cmdName##CONTEXT_CLASS* getInstance()\ + {\ + static __CTxtCommand_##cmdName##CONTEXT_CLASS *p=NULL;\ + if (p==NULL) p= new __CTxtCommand_##cmdName##CONTEXT_CLASS;\ + return p;\ + }\ + virtual const char* getName() const {return #cmdName;}\ + virtual CTxtCommandResult execute(CONTEXT_CLASS& context,const NLMISC::CVectorSString& args,const NLMISC::CSString& rawArgs,const NLMISC::CSString& fullCmdLine);\ +private:\ + __CTxtCommand_##cmdName##CONTEXT_CLASS() {}\ +};\ +static ITxtCommandRegisterer<__CTxtCommand_##cmdName##CONTEXT_CLASS,__CTxtCommandSet_##setName> __CTxtCommand_##cmdName##CONTEXT_CLASS##_Registerer;\ +CTxtCommandResult __CTxtCommand_##cmdName##CONTEXT_CLASS::execute(CONTEXT_CLASS& context,const NLMISC::CVectorSString& args,const NLMISC::CSString& rawArgs,const NLMISC::CSString& fullCmdLine) + + +//------------------------------------------------------------------------------------------------- +// class CTxtCommandResult +//------------------------------------------------------------------------------------------------- + +class CTxtCommandResult +{ +public: + enum TType + { + SUCCESS, // command execution was successful + SYNTAX_ERROR, // there was a syntax error in the command line + BAD_PERMISSION, // the user doesn't have the right to run the given command + UNKNOWN_COMMAND, // behave as if the command was not recognised + EXECUTION_ERROR // there was an error during execution of the command + }; + CTxtCommandResult(const bool& success): _Type(success?SUCCESS:SYNTAX_ERROR) {} + CTxtCommandResult(const TType& type): _Type(type) {} + CTxtCommandResult(const TType& type,const NLMISC::CSString& reason): _Type(type), _Reason(reason) {} + TType getType() const { return _Type; } + const NLMISC::CSString& getReason() const { return _Reason; } +private: + TType _Type; + NLMISC::CSString _Reason; +}; + + +//------------------------------------------------------------------------------------------------- +// class ITxtCommand +//------------------------------------------------------------------------------------------------- + +template class ITxtCommand +{ +public: + virtual const char* getName() const =0; + virtual CTxtCommandResult execute(CONTEXT_CLASS& context,const NLMISC::CVectorSString& args,const NLMISC::CSString& rawArgs,const NLMISC::CSString& fullCmdLine) =0; +}; + + +//------------------------------------------------------------------------------------------------- +// class ITxtCommandRegisterer +//------------------------------------------------------------------------------------------------- + +template struct ITxtCommandRegisterer +{ + ITxtCommandRegisterer() + { + SET::getInstance()->registerTxtCommand(CMD::getInstance()); + } +}; + + +//------------------------------------------------------------------------------------------------- +// class ITxtCommandSet +//------------------------------------------------------------------------------------------------- + +template class ITxtCommandSet +{ +public: + void registerTxtCommand(ITxtCommand* txtCommand) + { + nlassert(_TxtCommands.find(txtCommand->getName())==_TxtCommands.end()); + _TxtCommands[txtCommand->getName()]= txtCommand; + } + CTxtCommandResult execute(CONTEXT_CLASS& context,const NLMISC::CSString& cmdLine) + { + NLMISC::CSString cmdTail=cmdLine; + NLMISC::CSString keyword=cmdTail.firstWord(true); + typename TTxtCommands::iterator it= _TxtCommands.find(keyword); + if (it==_TxtCommands.end()) return CTxtCommandResult::UNKNOWN_COMMAND; + NLMISC::CVectorSString args; + cmdTail.splitWords(args); + return it->second->execute(context,args,cmdTail,cmdLine); + } +private: + typedef ITxtCommand TTxtCommand; + typedef std::map TTxtCommands; + TTxtCommands _TxtCommands; +}; + + +//------------------------------------------------------------------------------------------------- +// class ITxtCommandRegisterer +//------------------------------------------------------------------------------------------------- + +template struct CTxtCommandSetPtr +{ + CTxtCommandSetPtr() + { + SET::getInstance(); + } + + SET& operator*() + { + return *SET::getInstance(); + } + + SET* operator->() + { + return SET::getInstance(); + } +}; + + +//------------------------------------------------------------------------------------------------- +#endif diff --git a/code/ryzom/gen_deps.sh b/code/ryzom/gen_deps.sh deleted file mode 100755 index a6a286289..000000000 --- a/code/ryzom/gen_deps.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -command='' -sources='' -phase=0 -for arg in $* -do - if [ "$phase" == 0 ] && [ "$arg" == '--' ] - then - phase=1 - elif [ "$phase" == 0 ] - then - command="$command $arg" - elif [ "$phase" == 1 ] - then - sources="$sources $arg" - fi -done - -for src in $sources -do - obj=`echo $src | sed -e 's/.cpp$/.o/'` - $command -MT $obj -M $src -done diff --git a/code/ryzom/server/Makefile b/code/ryzom/server/Makefile deleted file mode 100644 index f76559463..000000000 --- a/code/ryzom/server/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -MAKE_NIGHT_ARGS=-j2 -MAKE_ALL_ARGS=-j2 -CXX=g++ -CC=g++ -BIN_DIR=$(RYZOM_PATH)/tools/scripts/linux - -night: - +make $(MAKE_NIGHT_ARGS) -k -C src night CXX=$(CXX) - -all: - +make $(MAKE_ALL_ARGS) -C src all - -mono: - +make -C src all - -clean: - +make -C src clean - -distclean: - +make -C src distclean - -cleansheets: - +make -C src cleansheets - -update: - +make -C src update - -touch: - +make -C src touch diff --git a/code/ryzom/server/data_shard/client_commands_privileges.txt b/code/ryzom/server/data_shard/client_commands_privileges.txt index c61537dfa..9b0e115d4 100644 --- a/code/ryzom/server/data_shard/client_commands_privileges.txt +++ b/code/ryzom/server/data_shard/client_commands_privileges.txt @@ -40,6 +40,9 @@ forceTargetToDie :DEV:SGM:GM:EM: // Force entity target to die getEventFaction :DEV:SGM:GM:EM: // Get the event faction of player: giveRespawnPoint :DEV:SGM:GM: // Give a respawn point to a player: guildInvite // Send a guild invite to a player character without distance constrainte +setLeague // Create a League +leagueInvite // Send a League invite to a Team Leader character without distance constrainte +leagueKick // Kick a player or team from league roomInvite // Send a room invite roomKick // Remove a room invite guildMOTD // Set the guild message of the day, command effective only for officer and more graded guild members @@ -72,8 +75,6 @@ renameGuild :DEV:SGM:GM:EM: // Rename a guild: renamePlayerForEvent :DEV:SGM:GM:EM:EG: // Rename a player temporarily for an event: resetPowerFlags :DEV:SGM:GM:EM: // Reset the ineffective aura and the power flags for given character -respawnAfterDeath // Respawn after death at re-spawn point name, it must be valid (validated by PC and usable): -resurrected // Another PC resurrect PC by giving some energy: root :DEV:SGM:GM:EM:VG:SG: // Root a player: