forked from mirror/openmw-tes3mp
Merge branch 'master' into HEAD
Conflicts: CMakeLists.txt apps/launcher/CMakeLists.txt
This commit is contained in:
commit
4fa303d7c4
952 changed files with 42465 additions and 25508 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -37,11 +37,12 @@ resources
|
|||
/omwlauncher
|
||||
/openmw
|
||||
/opencs
|
||||
/niftest
|
||||
|
||||
## generated objects
|
||||
apps/openmw/config.hpp
|
||||
components/version/version.hpp
|
||||
Docs/mainpage.hpp
|
||||
docs/mainpage.hpp
|
||||
moc_*.cxx
|
||||
*.cxx_parameters
|
||||
*qrc_launcher.cxx
|
||||
|
|
33
.travis.yml
33
.travis.yml
|
@ -1,38 +1,25 @@
|
|||
os:
|
||||
- linux
|
||||
- osx
|
||||
language: cpp
|
||||
compiler:
|
||||
- gcc
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- /openmw-.*$/
|
||||
before_install:
|
||||
- pwd
|
||||
- echo "yes" | sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu `lsb_release -sc` main universe restricted multiverse"
|
||||
- echo "yes" | sudo apt-add-repository ppa:openmw/openmw
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install -qq libboost-all-dev libgtest-dev google-mock
|
||||
- sudo apt-get install -qq libqt4-dev
|
||||
- sudo apt-get install -qq libopenal-dev
|
||||
- sudo apt-get install -qq libavcodec-dev libavformat-dev libavutil-dev libswscale-dev
|
||||
- sudo apt-get install -qq libbullet-dev libogre-1.9-dev libmygui-dev libsdl2-dev libunshield-dev
|
||||
- sudo mkdir /usr/src/gtest/build
|
||||
- cd /usr/src/gtest/build
|
||||
- sudo cmake .. -DBUILD_SHARED_LIBS=1
|
||||
- sudo make -j4
|
||||
- sudo ln -s /usr/src/gtest/build/libgtest.so /usr/lib/libgtest.so
|
||||
- sudo ln -s /usr/src/gtest/build/libgtest_main.so /usr/lib/libgtest_main.so
|
||||
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./CI/before_install.linux.sh; fi
|
||||
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then ./CI/before_install.osx.sh; fi
|
||||
before_script:
|
||||
- cd -
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake .. -DBUILD_WITH_CODE_COVERAGE=1 -DBUILD_UNITTESTS=1 -DBUILD_WITH_DPKG=1
|
||||
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./CI/before_script.linux.sh; fi
|
||||
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then ./CI/before_script.osx.sh; fi
|
||||
script:
|
||||
- cd ./build
|
||||
- make -j4
|
||||
after_script:
|
||||
- ./openmw_test_suite
|
||||
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi
|
||||
notifications:
|
||||
recipients:
|
||||
- lgromanowski+travis.ci@gmail.com
|
||||
- corrmage+travis-ci@gmail.com
|
||||
email:
|
||||
on_success: change
|
||||
on_failure: always
|
||||
|
|
18
CI/before_install.linux.sh
Executable file
18
CI/before_install.linux.sh
Executable file
|
@ -0,0 +1,18 @@
|
|||
#!/bin/sh
|
||||
|
||||
export CXX=g++
|
||||
export CC=gcc
|
||||
|
||||
echo "yes" | sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu `lsb_release -sc` main universe restricted multiverse"
|
||||
echo "yes" | sudo apt-add-repository ppa:openmw/openmw
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -qq libgtest-dev google-mock
|
||||
sudo apt-get install -qq libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-thread-dev libboost-wave-dev
|
||||
sudo apt-get install -qq libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libavresample-dev
|
||||
sudo apt-get install -qq libbullet-dev libogre-1.9-dev libmygui-dev libsdl2-dev libunshield-dev libtinyxml-dev libopenal-dev libqt4-dev
|
||||
sudo mkdir /usr/src/gtest/build
|
||||
cd /usr/src/gtest/build
|
||||
sudo cmake .. -DBUILD_SHARED_LIBS=1
|
||||
sudo make -j4
|
||||
sudo ln -s /usr/src/gtest/build/libgtest.so /usr/lib/libgtest.so
|
||||
sudo ln -s /usr/src/gtest/build/libgtest_main.so /usr/lib/libgtest_main.so
|
9
CI/before_install.osx.sh
Executable file
9
CI/before_install.osx.sh
Executable file
|
@ -0,0 +1,9 @@
|
|||
#!/bin/sh
|
||||
|
||||
export CXX=clang++
|
||||
export CC=clang
|
||||
|
||||
brew tap openmw/openmw
|
||||
brew update
|
||||
brew unlink boost
|
||||
brew install cmake openmw-mygui openmw-bullet openmw-sdl2 openmw-ffmpeg pkg-config qt unshield
|
5
CI/before_script.linux.sh
Executable file
5
CI/before_script.linux.sh
Executable file
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DBUILD_WITH_CODE_COVERAGE=1 -DBUILD_UNITTESTS=1 -DCMAKE_INSTALL_PREFIX=/usr -DBINDIR=/usr/games -DCMAKE_BUILD_TYPE="RelWithDebInfo" -DUSE_SYSTEM_TINYXML=TRUE
|
5
CI/before_script.osx.sh
Executable file
5
CI/before_script.osx.sh
Executable file
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_FRAMEWORK_PATH="/usr/local/lib/macosx/Release" -DCMAKE_EXE_LINKER_FLAGS="-F/usr/local/lib/macosx/Release" -DCMAKE_CXX_FLAGS="-stdlib=libstdc++" -DCMAKE_BUILD_TYPE=Debug -DBUILD_MYGUI_PLUGIN=OFF -G"Unix Makefiles" ..
|
359
CMakeLists.txt
359
CMakeLists.txt
|
@ -12,8 +12,8 @@ set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/)
|
|||
message(STATUS "Configuring OpenMW...")
|
||||
|
||||
set(OPENMW_VERSION_MAJOR 0)
|
||||
set(OPENMW_VERSION_MINOR 30)
|
||||
set(OPENMW_VERSION_RELEASE 0)
|
||||
set(OPENMW_VERSION_MINOR 33)
|
||||
set(OPENMW_VERSION_RELEASE 1)
|
||||
|
||||
set(OPENMW_VERSION_COMMITHASH "")
|
||||
set(OPENMW_VERSION_TAGHASH "")
|
||||
|
@ -54,9 +54,13 @@ endif(EXISTS ${PROJECT_SOURCE_DIR}/.git)
|
|||
# Macros
|
||||
include(OpenMWMacros)
|
||||
|
||||
if (ANDROID)
|
||||
set(CMAKE_FIND_ROOT_PATH ${OPENMW_DEPENDENCIES_DIR} "${CMAKE_FIND_ROOT_PATH}")
|
||||
endif (ANDROID)
|
||||
|
||||
# doxygen main page
|
||||
|
||||
configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp")
|
||||
configure_file ("${OpenMW_SOURCE_DIR}/docs/mainpage.hpp.cmake" "${OpenMW_BINARY_DIR}/docs/mainpage.hpp")
|
||||
|
||||
option(MYGUI_STATIC "Link static build of Mygui into the binaries" FALSE)
|
||||
option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binaries" FALSE)
|
||||
|
@ -66,38 +70,30 @@ option(SDL2_STATIC "Link static build of SDL into the binaries" FALSE)
|
|||
option(OPENMW_UNITY_BUILD "Use fewer compilation units to speed up compile time" FALSE)
|
||||
|
||||
# Apps and tools
|
||||
option(BUILD_BSATOOL "build BSA extractor" OFF)
|
||||
option(BUILD_BSATOOL "build BSA extractor" ON)
|
||||
option(BUILD_ESMTOOL "build ESM inspector" ON)
|
||||
option(BUILD_LAUNCHER "build Launcher" ON)
|
||||
option(BUILD_MWINIIMPORTER "build MWiniImporter" ON)
|
||||
option(BUILD_OPENCS "build OpenMW Construction Set" ON)
|
||||
option(BUILD_WIZARD "build Installation Wizard" ON)
|
||||
option(BUILD_WITH_CODE_COVERAGE "Enable code coverage with gconv" OFF)
|
||||
option(BUILD_UNITTESTS "Enable Unittests with Google C++ Unittest ang GMock frameworks" OFF)
|
||||
|
||||
# Sound source selection
|
||||
option(USE_FFMPEG "use ffmpeg for sound" ON)
|
||||
option(BUILD_UNITTESTS "Enable Unittests with Google C++ Unittest and GMock frameworks" OFF)
|
||||
option(BUILD_NIFTEST "build nif file tester" OFF)
|
||||
option(BUILD_MYGUI_PLUGIN "build MyGUI plugin for OpenMW resources, to use with MyGUI tools" ON)
|
||||
|
||||
# OS X deployment
|
||||
option(OPENMW_OSX_DEPLOYMENT OFF)
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
option(BUILD_WITH_DPKG "enable dpkg-based install for debian and debian derivatives" OFF)
|
||||
if(BUILD_WITH_DPKG)
|
||||
find_program(DPKG_PROGRAM dpkg DOC "dpkg program of Debian-based systems")
|
||||
endif(BUILD_WITH_DPKG)
|
||||
endif(UNIX AND NOT APPLE)
|
||||
|
||||
# Location of morrowind data files
|
||||
if (APPLE)
|
||||
set(MORROWIND_DATA_FILES "./data" CACHE PATH "location of Morrowind data files")
|
||||
set(MORROWIND_RESOURCE_FILES "./resources" CACHE PATH "location of OpenMW resources files")
|
||||
set(OPENMW_RESOURCE_FILES "./resources" CACHE PATH "location of OpenMW resources files")
|
||||
elseif(UNIX)
|
||||
set(MORROWIND_DATA_FILES "/usr/share/games/openmw/data/" CACHE PATH "location of Morrowind data files")
|
||||
set(MORROWIND_RESOURCE_FILES "/usr/share/games/openmw/resources/" CACHE PATH "location of OpenMW resources files")
|
||||
set(MORROWIND_DATA_FILES "${CMAKE_INSTALL_PREFIX}/share/games/openmw/data/" CACHE PATH "location of Morrowind data files")
|
||||
set(OPENMW_RESOURCE_FILES "${CMAKE_INSTALL_PREFIX}/share/games/openmw/resources/" CACHE PATH "location of OpenMW resources files")
|
||||
else()
|
||||
set(MORROWIND_DATA_FILES "data" CACHE PATH "location of Morrowind data files")
|
||||
set(MORROWIND_RESOURCE_FILES "resources" CACHE PATH "location of OpenMW resources files")
|
||||
set(OPENMW_RESOURCE_FILES "resources" CACHE PATH "location of OpenMW resources files")
|
||||
endif(APPLE)
|
||||
|
||||
if (WIN32)
|
||||
|
@ -109,33 +105,32 @@ cmake_minimum_required(VERSION 2.6)
|
|||
|
||||
# source directory: libs
|
||||
|
||||
set(LIBDIR ${CMAKE_SOURCE_DIR}/libs)
|
||||
set(LIBS_DIR ${CMAKE_SOURCE_DIR}/libs)
|
||||
|
||||
set(OENGINE_OGRE
|
||||
${LIBDIR}/openengine/ogre/renderer.cpp
|
||||
${LIBDIR}/openengine/ogre/fader.cpp
|
||||
${LIBDIR}/openengine/ogre/lights.cpp
|
||||
${LIBDIR}/openengine/ogre/selectionbuffer.cpp
|
||||
${LIBDIR}/openengine/ogre/imagerotate.cpp
|
||||
${LIBS_DIR}/openengine/ogre/renderer.cpp
|
||||
${LIBS_DIR}/openengine/ogre/lights.cpp
|
||||
${LIBS_DIR}/openengine/ogre/selectionbuffer.cpp
|
||||
${LIBS_DIR}/openengine/ogre/imagerotate.cpp
|
||||
)
|
||||
|
||||
set(OENGINE_GUI
|
||||
${LIBDIR}/openengine/gui/loglistener.cpp
|
||||
${LIBDIR}/openengine/gui/manager.cpp
|
||||
${LIBDIR}/openengine/gui/layout.hpp
|
||||
${LIBS_DIR}/openengine/gui/loglistener.cpp
|
||||
${LIBS_DIR}/openengine/gui/manager.cpp
|
||||
${LIBS_DIR}/openengine/gui/layout.hpp
|
||||
)
|
||||
|
||||
set(OENGINE_BULLET
|
||||
${LIBDIR}/openengine/bullet/BtOgre.cpp
|
||||
${LIBDIR}/openengine/bullet/BtOgreExtras.h
|
||||
${LIBDIR}/openengine/bullet/BtOgreGP.h
|
||||
${LIBDIR}/openengine/bullet/BtOgrePG.h
|
||||
${LIBDIR}/openengine/bullet/physic.cpp
|
||||
${LIBDIR}/openengine/bullet/physic.hpp
|
||||
${LIBDIR}/openengine/bullet/BulletShapeLoader.cpp
|
||||
${LIBDIR}/openengine/bullet/BulletShapeLoader.h
|
||||
${LIBDIR}/openengine/bullet/trace.cpp
|
||||
${LIBDIR}/openengine/bullet/trace.h
|
||||
${LIBS_DIR}/openengine/bullet/BtOgre.cpp
|
||||
${LIBS_DIR}/openengine/bullet/BtOgreExtras.h
|
||||
${LIBS_DIR}/openengine/bullet/BtOgreGP.h
|
||||
${LIBS_DIR}/openengine/bullet/BtOgrePG.h
|
||||
${LIBS_DIR}/openengine/bullet/physic.cpp
|
||||
${LIBS_DIR}/openengine/bullet/physic.hpp
|
||||
${LIBS_DIR}/openengine/bullet/BulletShapeLoader.cpp
|
||||
${LIBS_DIR}/openengine/bullet/BulletShapeLoader.h
|
||||
${LIBS_DIR}/openengine/bullet/trace.cpp
|
||||
${LIBS_DIR}/openengine/bullet/trace.h
|
||||
|
||||
)
|
||||
|
||||
|
@ -146,32 +141,24 @@ set(OPENMW_LIBS ${OENGINE_ALL})
|
|||
set(OPENMW_LIBS_HEADER)
|
||||
|
||||
# Sound setup
|
||||
set(GOT_SOUND_INPUT 0)
|
||||
set(SOUND_INPUT_INCLUDES "")
|
||||
set(SOUND_INPUT_LIBRARY "")
|
||||
set(SOUND_DEFINE "")
|
||||
if (USE_FFMPEG)
|
||||
set(FFmpeg_FIND_COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE)
|
||||
find_package(FFmpeg)
|
||||
if (FFMPEG_FOUND)
|
||||
set(SOUND_INPUT_INCLUDES ${SOUND_INPUT_INCLUDES} ${FFMPEG_INCLUDE_DIRS})
|
||||
set(SOUND_INPUT_LIBRARY ${SOUND_INPUT_LIBRARY} ${FFMPEG_LIBRARIES} ${SWSCALE_LIBRARIES})
|
||||
set(SOUND_DEFINE ${SOUND_DEFINE} -DOPENMW_USE_FFMPEG)
|
||||
set(GOT_SOUND_INPUT 1)
|
||||
endif (FFMPEG_FOUND)
|
||||
endif (USE_FFMPEG)
|
||||
|
||||
if (NOT GOT_SOUND_INPUT)
|
||||
message(WARNING "--------------------")
|
||||
message(WARNING "Failed to find any sound input packages")
|
||||
message(WARNING "--------------------")
|
||||
endif (NOT GOT_SOUND_INPUT)
|
||||
|
||||
if (NOT FFMPEG_FOUND)
|
||||
message(WARNING "--------------------")
|
||||
message(WARNING "FFmpeg not found, video playback will be disabled")
|
||||
message(WARNING "--------------------")
|
||||
endif (NOT FFMPEG_FOUND)
|
||||
set(FFmpeg_FIND_COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE SWRESAMPLE AVRESAMPLE)
|
||||
unset(FFMPEG_LIBRARIES CACHE)
|
||||
find_package(FFmpeg)
|
||||
if ( NOT AVCODEC_FOUND OR NOT AVFORMAT_FOUND OR NOT AVUTIL_FOUND OR NOT SWSCALE_FOUND )
|
||||
message(FATAL_ERROR "FFmpeg component required, but not found!")
|
||||
endif()
|
||||
set(SOUND_INPUT_INCLUDES ${FFMPEG_INCLUDE_DIRS})
|
||||
set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES} ${SWSCALE_LIBRARIES})
|
||||
if( SWRESAMPLE_FOUND )
|
||||
add_definitions(-DHAVE_LIBSWRESAMPLE)
|
||||
set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES} ${SWRESAMPLE_LIBRARIES})
|
||||
else()
|
||||
if( AVRESAMPLE_FOUND )
|
||||
set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES} ${AVRESAMPLE_LIBRARIES})
|
||||
else()
|
||||
message(FATAL_ERROR "Install either libswresample (FFmpeg) or libavresample (Libav).")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# TinyXML
|
||||
option(USE_SYSTEM_TINYXML "Use system TinyXML library instead of internal." OFF)
|
||||
|
@ -235,32 +222,74 @@ IF(BOOST_STATIC)
|
|||
endif()
|
||||
|
||||
find_package(OGRE REQUIRED)
|
||||
if (${OGRE_VERSION} VERSION_LESS "1.9")
|
||||
message(FATAL_ERROR "OpenMW requires Ogre 1.9 or later, please install the latest stable version from http://ogre3d.org")
|
||||
endif()
|
||||
|
||||
find_package(MyGUI REQUIRED)
|
||||
if (${MYGUI_VERSION} VERSION_LESS "3.2.1")
|
||||
message(FATAL_ERROR "OpenMW requires MyGUI 3.2.1 or later, please install the latest version from http://mygui.info")
|
||||
endif()
|
||||
|
||||
find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
|
||||
find_package(SDL2 REQUIRED)
|
||||
find_package(OpenAL REQUIRED)
|
||||
find_package(Bullet REQUIRED)
|
||||
IF(OGRE_STATIC)
|
||||
find_package(Cg)
|
||||
IF(WIN32)
|
||||
set(OGRE_PLUGIN_INCLUDE_DIRS ${OGRE_Plugin_CgProgramManager_INCLUDE_DIRS} ${OGRE_Plugin_OctreeSceneManager_INCLUDE_DIRS} ${OGRE_Plugin_ParticleFX_INCLUDE_DIRS} ${OGRE_RenderSystem_Direct3D9_INCLUDE_DIRS} ${OGRE_RenderSystem_GL_INCLUDE_DIRS})
|
||||
ELSE(WIN32)
|
||||
set(OGRE_PLUGIN_INCLUDE_DIRS ${OGRE_Plugin_CgProgramManager_INCLUDE_DIRS} ${OGRE_Plugin_OctreeSceneManager_INCLUDE_DIRS} ${OGRE_Plugin_ParticleFX_INCLUDE_DIRS} ${OGRE_RenderSystem_GL_INCLUDE_DIRS})
|
||||
ENDIF(WIN32)
|
||||
ENDIF(OGRE_STATIC)
|
||||
|
||||
set(OGRE_PLUGIN_INCLUDE_DIRS "")
|
||||
set(OGRE_STATIC_PLUGINS "")
|
||||
|
||||
macro(add_static_ogre_plugin PLUGIN)
|
||||
if(OGRE_${PLUGIN}_FOUND)
|
||||
# strip RenderSystem_ or Plugin_ prefix from plugin name
|
||||
string(REPLACE "RenderSystem_" "" PLUGIN_TEMP ${PLUGIN})
|
||||
string(REPLACE "Plugin_" "" PLUGIN_NAME ${PLUGIN_TEMP})
|
||||
add_definitions(-DENABLE_PLUGIN_${PLUGIN_NAME})
|
||||
|
||||
list(APPEND OGRE_PLUGIN_INCLUDE_DIRS ${OGRE_${PLUGIN}_INCLUDE_DIRS})
|
||||
list(APPEND OGRE_STATIC_PLUGINS ${OGRE_${PLUGIN}_LIBRARIES})
|
||||
endif(OGRE_${PLUGIN}_FOUND)
|
||||
endmacro(add_static_ogre_plugin)
|
||||
|
||||
if(OGRE_STATIC)
|
||||
# set up OGRE_PLUGIN_INCLUDE_DIRS and OGRE_STATIC_PLUGINS
|
||||
add_static_ogre_plugin(Plugin_OctreeSceneManager)
|
||||
add_static_ogre_plugin(Plugin_ParticleFX)
|
||||
find_package(Cg)
|
||||
if(Cg_FOUND)
|
||||
add_static_ogre_plugin(Plugin_CgProgramManager)
|
||||
list(APPEND OGRE_STATIC_PLUGINS ${Cg_LIBRARIES})
|
||||
endif(Cg_FOUND)
|
||||
|
||||
if (ANDROID)
|
||||
add_static_ogre_plugin(RenderSystem_GLES2)
|
||||
else ()
|
||||
add_static_ogre_plugin(RenderSystem_GL)
|
||||
endif ()
|
||||
|
||||
if(WIN32)
|
||||
add_static_ogre_plugin(RenderSystem_Direct3D9)
|
||||
endif(WIN32)
|
||||
endif(OGRE_STATIC)
|
||||
|
||||
include_directories("."
|
||||
${OGRE_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Ogre ${OGRE_INCLUDE_DIR}/OGRE ${OGRE_PLUGIN_INCLUDE_DIRS}
|
||||
${OGRE_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Ogre ${OGRE_INCLUDE_DIR}/OGRE ${OGRE_INCLUDE_DIRS} ${OGRE_PLUGIN_INCLUDE_DIRS}
|
||||
${OGRE_INCLUDE_DIR}/Overlay ${OGRE_Overlay_INCLUDE_DIR}
|
||||
${SDL2_INCLUDE_DIR}
|
||||
${Boost_INCLUDE_DIR}
|
||||
${PLATFORM_INCLUDE_DIR}
|
||||
${MYGUI_INCLUDE_DIRS}
|
||||
${MYGUI_PLATFORM_INCLUDE_DIRS}
|
||||
${OPENAL_INCLUDE_DIR}
|
||||
${LIBDIR}
|
||||
${LIBS_DIR}
|
||||
)
|
||||
|
||||
link_directories(${SDL2_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR} ${MYGUI_LIB_DIR})
|
||||
|
||||
if(MYGUI_STATIC)
|
||||
add_definitions(-DMYGUI_STATIC)
|
||||
endif (MYGUI_STATIC)
|
||||
|
||||
if (APPLE)
|
||||
# List used Ogre plugins
|
||||
SET(USED_OGRE_PLUGINS ${OGRE_RenderSystem_GL_LIBRARY_REL}
|
||||
|
@ -305,12 +334,14 @@ else ()
|
|||
add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="_d")
|
||||
endif()
|
||||
|
||||
add_definitions(-DOGRE_PLUGIN_DIR_REL="${OGRE_PLUGIN_DIR_REL}")
|
||||
add_definitions(-DOGRE_PLUGIN_DIR_DBG="${OGRE_PLUGIN_DIR_DBG}")
|
||||
if (APPLE AND OPENMW_OSX_DEPLOYMENT)
|
||||
# make it empty so plugin loading code can check this and try to find plugins inside app bundle
|
||||
add_definitions(-DOGRE_PLUGIN_DIR="")
|
||||
else()
|
||||
if (NOT DEFINED ${OGRE_PLUGIN_DIR})
|
||||
set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_REL})
|
||||
endif()
|
||||
|
||||
add_definitions(-DOGRE_PLUGIN_DIR="${OGRE_PLUGIN_DIR}")
|
||||
endif()
|
||||
|
||||
|
@ -322,8 +353,10 @@ add_subdirectory(files/mygui)
|
|||
|
||||
if (APPLE)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${APP_BUNDLE_DIR}/Contents/MacOS")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${APP_BUNDLE_DIR}/Contents/MacOS")
|
||||
else (APPLE)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${OpenMW_BINARY_DIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${OpenMW_BINARY_DIR}")
|
||||
endif (APPLE)
|
||||
|
||||
# Other files
|
||||
|
@ -357,9 +390,6 @@ endif()
|
|||
if (CMAKE_COMPILER_IS_GNUCC)
|
||||
SET(CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused-parameter -Wno-reorder -std=c++98 -pedantic -Wno-long-long ${CMAKE_CXX_FLAGS}")
|
||||
|
||||
# Silence warnings in OGRE headers. Remove once OGRE got fixed!
|
||||
SET(CMAKE_CXX_FLAGS "-Wno-ignored-qualifiers ${CMAKE_CXX_FLAGS}")
|
||||
|
||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
|
||||
OUTPUT_VARIABLE GCC_VERSION)
|
||||
if ("${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6)
|
||||
|
@ -368,50 +398,52 @@ if (CMAKE_COMPILER_IS_GNUCC)
|
|||
endif (CMAKE_COMPILER_IS_GNUCC)
|
||||
|
||||
IF(NOT WIN32 AND NOT APPLE)
|
||||
## Debian and non debian Linux building
|
||||
# Linux building
|
||||
# Paths
|
||||
IF (DPKG_PROGRAM)
|
||||
## Debian specific
|
||||
SET(CMAKE_INSTALL_PREFIX "/usr")
|
||||
SET(DATAROOTDIR "share" CACHE PATH "Sets the root of data directories to a non-default location")
|
||||
SET(DATADIR "share/games/openmw" CACHE PATH "Sets the openmw data directories to a non-default location")
|
||||
SET(ICONDIR "share/pixmaps" CACHE PATH "Set icon dir")
|
||||
SET(SYSCONFDIR "../etc/openmw" CACHE PATH "Set config dir")
|
||||
ELSE ()
|
||||
## Non debian specific
|
||||
SET(BINDIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Where to install binaries")
|
||||
SET(DATAROOTDIR "${CMAKE_INSTALL_PREFIX}/share" CACHE PATH "Sets the root of data directories to a non-default location")
|
||||
SET(DATADIR "${DATAROOTDIR}/games/openmw" CACHE PATH "Sets the openmw data directories to a non-default location")
|
||||
SET(ICONDIR "${DATAROOTDIR}/pixmaps" CACHE PATH "Set icon dir")
|
||||
SET(LICDIR "${DATAROOTDIR}/licenses/openmw" CACHE PATH "Sets the openmw license directory to a non-default location.")
|
||||
SET(SYSCONFDIR "/etc/openmw" CACHE PATH "Set config dir")
|
||||
SET(BINDIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Where to install binaries")
|
||||
SET(LIBDIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Where to install libraries")
|
||||
SET(DATAROOTDIR "${CMAKE_INSTALL_PREFIX}/share" CACHE PATH "Sets the root of data directories to a non-default location")
|
||||
SET(GLOBAL_DATA_PATH "${DATAROOTDIR}/games/" CACHE PATH "Set data path prefix")
|
||||
SET(DATADIR "${GLOBAL_DATA_PATH}/openmw" CACHE PATH "Sets the openmw data directories to a non-default location")
|
||||
SET(ICONDIR "${DATAROOTDIR}/pixmaps" CACHE PATH "Set icon dir")
|
||||
SET(LICDIR "${DATAROOTDIR}/licenses/openmw" CACHE PATH "Sets the openmw license directory to a non-default location.")
|
||||
IF("${CMAKE_INSTALL_PREFIX}" STREQUAL "/usr")
|
||||
SET(GLOBAL_CONFIG_PATH "/etc/" CACHE PATH "Set config dir prefix")
|
||||
ELSE()
|
||||
SET(GLOBAL_CONFIG_PATH "${CMAKE_INSTALL_PREFIX}/etc/" CACHE PATH "Set config dir prefix")
|
||||
ENDIF()
|
||||
SET(SYSCONFDIR "${GLOBAL_CONFIG_PATH}/openmw" CACHE PATH "Set config dir")
|
||||
|
||||
# Install binaries
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw" DESTINATION "${BINDIR}" )
|
||||
IF(BUILD_LAUNCHER)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/omwlauncher" DESTINATION "${BINDIR}" )
|
||||
ENDIF(BUILD_LAUNCHER)
|
||||
IF(BUILD_BSATOOL)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/bsatool" DESTINATION "${BINDIR}" )
|
||||
ENDIF(BUILD_BSATOOL)
|
||||
IF(BUILD_ESMTOOL)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/esmtool" DESTINATION "${BINDIR}" )
|
||||
ENDIF(BUILD_ESMTOOL)
|
||||
IF(BUILD_MWINIIMPORTER)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/mwiniimport" DESTINATION "${BINDIR}" )
|
||||
ENDIF(BUILD_MWINIIMPORTER)
|
||||
IF(BUILD_OPENCS)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/opencs" DESTINATION "${BINDIR}" )
|
||||
ENDIF(BUILD_OPENCS)
|
||||
IF(BUILD_WIZARD)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/wizard" DESTINATION "${BINDIR}" )
|
||||
ENDIF(BUILD_WIZARD)
|
||||
# Install binaries
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw" DESTINATION "${BINDIR}" )
|
||||
IF(BUILD_LAUNCHER)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/omwlauncher" DESTINATION "${BINDIR}" )
|
||||
ENDIF(BUILD_LAUNCHER)
|
||||
IF(BUILD_BSATOOL)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/bsatool" DESTINATION "${BINDIR}" )
|
||||
ENDIF(BUILD_BSATOOL)
|
||||
IF(BUILD_ESMTOOL)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/esmtool" DESTINATION "${BINDIR}" )
|
||||
ENDIF(BUILD_ESMTOOL)
|
||||
IF(BUILD_MWINIIMPORTER)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/mwiniimport" DESTINATION "${BINDIR}" )
|
||||
ENDIF(BUILD_MWINIIMPORTER)
|
||||
IF(BUILD_OPENCS)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/opencs" DESTINATION "${BINDIR}" )
|
||||
ENDIF(BUILD_OPENCS)
|
||||
IF(BUILD_NIFTEST)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/niftest" DESTINATION "${BINDIR}" )
|
||||
ENDIF(BUILD_NIFTEST)
|
||||
IF(BUILD_WIZARD)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/wizard" DESTINATION "${BINDIR}" )
|
||||
ENDIF(BUILD_WIZARD)
|
||||
if(BUILD_MYGUI_PLUGIN)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Plugin_MyGUI_OpenMW_Resources.so" DESTINATION "${LIBDIR}" )
|
||||
ENDIF(BUILD_MYGUI_PLUGIN)
|
||||
|
||||
|
||||
# Install licenses
|
||||
INSTALL(FILES "DejaVu Font License.txt" DESTINATION "${LICDIR}" )
|
||||
INSTALL(FILES "extern/shiny/License.txt" DESTINATION "${LICDIR}" RENAME "Shiny License.txt" )
|
||||
ENDIF (DPKG_PROGRAM)
|
||||
# Install licenses
|
||||
INSTALL(FILES "docs/license/DejaVu Font License.txt" DESTINATION "${LICDIR}" )
|
||||
INSTALL(FILES "extern/shiny/License.txt" DESTINATION "${LICDIR}" RENAME "Shiny License.txt" )
|
||||
|
||||
# Install icon and desktop file
|
||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.desktop" DESTINATION "${DATAROOTDIR}/applications" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
||||
|
@ -440,8 +472,8 @@ if(WIN32)
|
|||
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg")
|
||||
INSTALL(FILES
|
||||
"${OpenMW_SOURCE_DIR}/readme.txt"
|
||||
"${OpenMW_SOURCE_DIR}/GPL3.txt"
|
||||
"${OpenMW_SOURCE_DIR}/DejaVu Font License.txt"
|
||||
"${OpenMW_SOURCE_DIR}/Docs/license/GPL3.txt"
|
||||
"${OpenMW_SOURCE_DIR}/Docs/license/DejaVu Font License.txt"
|
||||
"${OpenMW_BINARY_DIR}/settings-default.cfg"
|
||||
"${OpenMW_BINARY_DIR}/transparency-overrides.cfg"
|
||||
"${OpenMW_BINARY_DIR}/Release/openmw.exe"
|
||||
|
@ -460,7 +492,9 @@ if(WIN32)
|
|||
IF(BUILD_WIZARD)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-wizard.exe" DESTINATION ".")
|
||||
ENDIF(BUILD_WIZARD)
|
||||
|
||||
if(BUILD_MYGUI_PLUGIN)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/Plugin_MyGUI_OpenMW_Resources.dll" DESTINATION ".")
|
||||
ENDIF(BUILD_MYGUI_PLUGIN)
|
||||
|
||||
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ".")
|
||||
|
||||
|
@ -493,8 +527,8 @@ if(WIN32)
|
|||
SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\www.openmw.org")
|
||||
SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\www.openmw.org")
|
||||
SET(CPACK_NSIS_INSTALLED_ICON_NAME "omwlauncher.exe")
|
||||
SET(CPACK_NSIS_MUI_ICON "${OpenMW_SOURCE_DIR}/files/launcher/images/openmw.ico")
|
||||
SET(CPACK_NSIS_MUI_UNIICON "${OpenMW_SOURCE_DIR}/files/launcher/images/openmw.ico")
|
||||
SET(CPACK_NSIS_MUI_ICON "${OpenMW_SOURCE_DIR}/files/windows/openmw.ico")
|
||||
SET(CPACK_NSIS_MUI_UNIICON "${OpenMW_SOURCE_DIR}/files/windows/openmw.ico")
|
||||
SET(CPACK_PACKAGE_ICON "${OpenMW_SOURCE_DIR}\\\\files\\\\openmw.bmp")
|
||||
|
||||
SET(VCREDIST32 "${OpenMW_BINARY_DIR}/vcredist_x86.exe")
|
||||
|
@ -525,12 +559,23 @@ endif(WIN32)
|
|||
|
||||
# Extern
|
||||
add_subdirectory (extern/shiny)
|
||||
add_subdirectory (extern/ogre-ffmpeg-videoplayer)
|
||||
add_subdirectory (extern/oics)
|
||||
add_subdirectory (extern/sdl4ogre)
|
||||
|
||||
# Components
|
||||
add_subdirectory (components)
|
||||
|
||||
# Plugins
|
||||
if (BUILD_MYGUI_PLUGIN)
|
||||
add_subdirectory(plugins/mygui_resource_plugin)
|
||||
endif()
|
||||
|
||||
#Testing
|
||||
if (BUILD_NIFTEST)
|
||||
add_subdirectory(components/nif/tests/)
|
||||
endif(BUILD_NIFTEST)
|
||||
|
||||
# Apps and tools
|
||||
add_subdirectory( apps/openmw )
|
||||
|
||||
|
@ -570,6 +615,16 @@ endif()
|
|||
|
||||
if (WIN32)
|
||||
if (MSVC)
|
||||
if (MULTITHREADED_BUILD)
|
||||
set( MT_BUILD "/MP")
|
||||
endif (MULTITHREADED_BUILD)
|
||||
|
||||
foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} )
|
||||
string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG )
|
||||
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "$(SolutionDir)$(Configuration)" )
|
||||
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "$(ProjectDir)$(Configuration)" )
|
||||
endforeach( OUTPUTCONFIG )
|
||||
|
||||
if (USE_DEBUG_CONSOLE)
|
||||
set_target_properties(openmw PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:CONSOLE")
|
||||
set_target_properties(openmw PROPERTIES LINK_FLAGS_RELWITHDEBINFO "/SUBSYSTEM:CONSOLE")
|
||||
|
@ -610,14 +665,19 @@ if (WIN32)
|
|||
4251 # class 'XXXX' needs to have dll-interface to be used by clients of class 'YYYY'
|
||||
4275 # non dll-interface struct 'XXXX' used as base for dll-interface class 'YYYY'
|
||||
|
||||
# caused by boost
|
||||
4191 # 'type cast' : unsafe conversion (1.56, thread_primitives.hpp, normally off)
|
||||
|
||||
# OpenMW specific warnings
|
||||
4099 # Type mismatch, declared class or struct is defined with other type
|
||||
4100 # Unreferenced formal parameter (-Wunused-parameter)
|
||||
4127 # Conditional expression is constant
|
||||
4242 # Storing value in a variable of a smaller type, possible loss of data
|
||||
4244 # Storing value of one type in variable of another (size_t in int, for example)
|
||||
4267 # Conversion from 'size_t' to 'int', possible loss of data
|
||||
4305 # Truncating value (double to float, for example)
|
||||
4309 # Variable overflow, trying to store 128 in a signed char for example
|
||||
4351 # New behavior: elements of array 'array' will be default initialized (desired behavior)
|
||||
4355 # Using 'this' in member initialization list
|
||||
4505 # Unreferenced local function has been removed
|
||||
4701 # Potentially uninitialized local variable used
|
||||
|
@ -631,31 +691,35 @@ if (WIN32)
|
|||
|
||||
# boost::wave has a few issues with signed / unsigned conversions, so we suppress those here
|
||||
set(SHINY_WARNINGS "${WARNINGS} /wd4245")
|
||||
set_target_properties(shiny PROPERTIES COMPILE_FLAGS ${SHINY_WARNINGS})
|
||||
set_target_properties(shiny PROPERTIES COMPILE_FLAGS "${SHINY_WARNINGS} ${MT_BUILD}")
|
||||
# there's an unreferenced local variable in the ogre platform, suppress it
|
||||
set(SHINY_OGRE_WARNINGS "${WARNINGS} /wd4101")
|
||||
set_target_properties(shiny.OgrePlatform PROPERTIES COMPILE_FLAGS ${SHINY_OGRE_WARNINGS})
|
||||
set_target_properties(sdl4ogre PROPERTIES COMPILE_FLAGS ${WARNINGS})
|
||||
set_target_properties(oics PROPERTIES COMPILE_FLAGS ${WARNINGS})
|
||||
set_target_properties(components PROPERTIES COMPILE_FLAGS ${WARNINGS})
|
||||
set_target_properties(shiny.OgrePlatform PROPERTIES COMPILE_FLAGS "${SHINY_OGRE_WARNINGS} ${MT_BUILD}")
|
||||
set_target_properties(sdl4ogre PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
# oics uses tinyxml, which has an initialized but unused variable
|
||||
set(OICS_WARNINGS "${WARNINGS} /wd4189")
|
||||
set_target_properties(oics PROPERTIES COMPILE_FLAGS "${OICS_WARNINGS} ${MT_BUILD}")
|
||||
set_target_properties(components PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
if (BUILD_LAUNCHER)
|
||||
set_target_properties(omwlauncher PROPERTIES COMPILE_FLAGS ${WARNINGS})
|
||||
set_target_properties(omwlauncher PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
endif (BUILD_LAUNCHER)
|
||||
set_target_properties(openmw PROPERTIES COMPILE_FLAGS ${WARNINGS})
|
||||
set_target_properties(openmw PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
if (BUILD_BSATOOL)
|
||||
set_target_properties(bsatool PROPERTIES COMPILE_FLAGS ${WARNINGS})
|
||||
set_target_properties(bsatool PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
endif (BUILD_BSATOOL)
|
||||
if (BUILD_ESMTOOL)
|
||||
set_target_properties(esmtool PROPERTIES COMPILE_FLAGS ${WARNINGS})
|
||||
set_target_properties(esmtool PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
endif (BUILD_ESMTOOL)
|
||||
if (BUILD_WIZARD)
|
||||
set_target_properties(openmw-wizard PROPERTIES COMPILE_FLAGS ${WARNINGS})
|
||||
endif (BUILD_WIZARD)
|
||||
if (BUILD_OPENCS)
|
||||
set_target_properties(opencs PROPERTIES COMPILE_FLAGS ${WARNINGS})
|
||||
# QT triggers an informational warning that the object layout may differ when compiled with /vd2
|
||||
set(OPENCS_WARNINGS "${WARNINGS} ${MT_BUILD} /wd4435")
|
||||
set_target_properties(opencs PROPERTIES COMPILE_FLAGS ${OPENCS_WARNINGS})
|
||||
endif (BUILD_OPENCS)
|
||||
if (BUILD_MWINIIMPORTER)
|
||||
set_target_properties(mwiniimport PROPERTIES COMPILE_FLAGS ${WARNINGS})
|
||||
set_target_properties(mwiniimport PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
endif (BUILD_MWINIIMPORTER)
|
||||
endif(MSVC)
|
||||
|
||||
|
@ -789,3 +853,26 @@ if (APPLE)
|
|||
include(CPack)
|
||||
endif (APPLE)
|
||||
|
||||
# Doxygen Target -- simply run 'make doc' or 'make doc_pages'
|
||||
# output directory for 'make doc' is "${OpenMW_BINARY_DIR}/docs/Doxygen"
|
||||
# output directory for 'make doc_pages' is "${DOXYGEN_PAGES_OUTPUT_DIR}" if defined
|
||||
# or "${OpenMW_BINARY_DIR}/docs/Pages" otherwise
|
||||
find_package(Doxygen)
|
||||
if (DOXYGEN_FOUND)
|
||||
# determine output directory for doc_pages
|
||||
if (NOT DEFINED DOXYGEN_PAGES_OUTPUT_DIR)
|
||||
set(DOXYGEN_PAGES_OUTPUT_DIR "${OpenMW_BINARY_DIR}/docs/Pages")
|
||||
endif ()
|
||||
configure_file(${OpenMW_SOURCE_DIR}/docs/Doxyfile.cmake ${OpenMW_BINARY_DIR}/docs/Doxyfile @ONLY)
|
||||
configure_file(${OpenMW_SOURCE_DIR}/docs/DoxyfilePages.cmake ${OpenMW_BINARY_DIR}/docs/DoxyfilePages @ONLY)
|
||||
add_custom_target(doc
|
||||
${DOXYGEN_EXECUTABLE} ${OpenMW_BINARY_DIR}/docs/Doxyfile
|
||||
WORKING_DIRECTORY ${OpenMW_BINARY_DIR}
|
||||
COMMENT "Generating Doxygen documentation at ${OpenMW_BINARY_DIR}/docs/Doxygen"
|
||||
VERBATIM)
|
||||
add_custom_target(doc_pages
|
||||
${DOXYGEN_EXECUTABLE} ${OpenMW_BINARY_DIR}/docs/DoxyfilePages
|
||||
WORKING_DIRECTORY ${OpenMW_BINARY_DIR}
|
||||
COMMENT "Generating documentation for the github-pages at ${DOXYGEN_PAGES_OUTPUT_DIR}" VERBATIM)
|
||||
endif ()
|
||||
|
||||
|
|
1543
Docs/Doxyfile
1543
Docs/Doxyfile
File diff suppressed because it is too large
Load diff
|
@ -51,7 +51,7 @@ bool parseOptions (int argc, char** argv, Arguments &info)
|
|||
("help,h", "print help message.")
|
||||
("version,v", "print version information and quit.")
|
||||
("long,l", "Include extra information in archive listing.")
|
||||
("full-path,f", "Create diretory hierarchy on file extraction "
|
||||
("full-path,f", "Create directory hierarchy on file extraction "
|
||||
"(always true for extractall).")
|
||||
;
|
||||
|
||||
|
|
|
@ -249,6 +249,9 @@ void loadCell(ESM::Cell &cell, ESM::ESMReader &esm, Arguments& info)
|
|||
std::cout << " Refnum: " << ref.mRefNum.mIndex << std::endl;
|
||||
std::cout << " ID: '" << ref.mRefID << "'\n";
|
||||
std::cout << " Owner: '" << ref.mOwner << "'\n";
|
||||
std::cout << " Global: '" << ref.mGlobalVariable << "'" << std::endl;
|
||||
std::cout << " Faction: '" << ref.mFaction << "'" << std::endl;
|
||||
std::cout << " Faction rank: '" << ref.mFactionRank << "'" << std::endl;
|
||||
std::cout << " Enchantment charge: '" << ref.mEnchantmentCharge << "'\n";
|
||||
std::cout << " Uses/health: '" << ref.mCharge << "'\n";
|
||||
std::cout << " Gold value: '" << ref.mGoldValue << "'\n";
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -412,7 +412,7 @@ void Record<ESM::Armor>::print()
|
|||
std::cout << " Armor: " << mData.mData.mArmor << std::endl;
|
||||
std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl;
|
||||
std::vector<ESM::PartReference>::iterator pit;
|
||||
for (pit = mData.mParts.mParts.begin(); pit != mData.mParts.mParts.end(); pit++)
|
||||
for (pit = mData.mParts.mParts.begin(); pit != mData.mParts.mParts.end(); ++pit)
|
||||
{
|
||||
std::cout << " Body Part: " << bodyPartLabel(pit->mPart)
|
||||
<< " (" << (int)(pit->mPart) << ")" << std::endl;
|
||||
|
@ -484,7 +484,7 @@ void Record<ESM::BirthSign>::print()
|
|||
std::cout << " Texture: " << mData.mTexture << std::endl;
|
||||
std::cout << " Description: " << mData.mDescription << std::endl;
|
||||
std::vector<std::string>::iterator pit;
|
||||
for (pit = mData.mPowers.mList.begin(); pit != mData.mPowers.mList.end(); pit++)
|
||||
for (pit = mData.mPowers.mList.begin(); pit != mData.mPowers.mList.end(); ++pit)
|
||||
std::cout << " Power: " << *pit << std::endl;
|
||||
}
|
||||
|
||||
|
@ -513,7 +513,7 @@ void Record<ESM::Cell>::print()
|
|||
else
|
||||
std::cout << " Map Color: " << boost::format("0x%08X") % mData.mMapColor << std::endl;
|
||||
std::cout << " Water Level Int: " << mData.mWaterInt << std::endl;
|
||||
std::cout << " NAM0: " << mData.mNAM0 << std::endl;
|
||||
std::cout << " RefId counter: " << mData.mRefNumCounter << std::endl;
|
||||
|
||||
}
|
||||
|
||||
|
@ -554,7 +554,7 @@ void Record<ESM::Clothing>::print()
|
|||
std::cout << " Value: " << mData.mData.mValue << std::endl;
|
||||
std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl;
|
||||
std::vector<ESM::PartReference>::iterator pit;
|
||||
for (pit = mData.mParts.mParts.begin(); pit != mData.mParts.mParts.end(); pit++)
|
||||
for (pit = mData.mParts.mParts.begin(); pit != mData.mParts.mParts.end(); ++pit)
|
||||
{
|
||||
std::cout << " Body Part: " << bodyPartLabel(pit->mPart)
|
||||
<< " (" << (int)(pit->mPart) << ")" << std::endl;
|
||||
|
@ -574,7 +574,7 @@ void Record<ESM::Container>::print()
|
|||
std::cout << " Flags: " << containerFlags(mData.mFlags) << std::endl;
|
||||
std::cout << " Weight: " << mData.mWeight << std::endl;
|
||||
std::vector<ESM::ContItem>::iterator cit;
|
||||
for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); cit++)
|
||||
for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); ++cit)
|
||||
std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount
|
||||
<< " Item: " << cit->mItem.toString() << std::endl;
|
||||
}
|
||||
|
@ -619,12 +619,12 @@ void Record<ESM::Creature>::print()
|
|||
std::cout << " Gold: " << mData.mData.mGold << std::endl;
|
||||
|
||||
std::vector<ESM::ContItem>::iterator cit;
|
||||
for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); cit++)
|
||||
for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); ++cit)
|
||||
std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount
|
||||
<< " Item: " << cit->mItem.toString() << std::endl;
|
||||
|
||||
std::vector<std::string>::iterator sit;
|
||||
for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); sit++)
|
||||
for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); ++sit)
|
||||
std::cout << " Spell: " << *sit << std::endl;
|
||||
|
||||
std::cout << " Artifical Intelligence: " << mData.mHasAI << std::endl;
|
||||
|
@ -639,7 +639,7 @@ void Record<ESM::Creature>::print()
|
|||
std::cout << " AI Services:" << boost::format("0x%08X") % mData.mAiData.mServices << std::endl;
|
||||
|
||||
std::vector<ESM::AIPackage>::iterator pit;
|
||||
for (pit = mData.mAiPackage.mList.begin(); pit != mData.mAiPackage.mList.end(); pit++)
|
||||
for (pit = mData.mAiPackage.mList.begin(); pit != mData.mAiPackage.mList.end(); ++pit)
|
||||
printAIPackage(*pit);
|
||||
}
|
||||
|
||||
|
@ -682,13 +682,11 @@ void Record<ESM::Faction>::print()
|
|||
{
|
||||
std::cout << " Name: " << mData.mName << std::endl;
|
||||
std::cout << " Hidden: " << mData.mData.mIsHidden << std::endl;
|
||||
if (mData.mData.mUnknown != -1)
|
||||
std::cout << " Unknown: " << mData.mData.mUnknown << std::endl;
|
||||
std::cout << " Attribute1: " << attributeLabel(mData.mData.mAttribute[0])
|
||||
<< " (" << mData.mData.mAttribute[0] << ")" << std::endl;
|
||||
std::cout << " Attribute2: " << attributeLabel(mData.mData.mAttribute[1])
|
||||
<< " (" << mData.mData.mAttribute[1] << ")" << std::endl;
|
||||
for (int i = 0; i != 6; i++)
|
||||
for (int i = 0; i < 7; i++)
|
||||
if (mData.mData.mSkills[i] != -1)
|
||||
std::cout << " Skill: " << skillLabel(mData.mData.mSkills[i])
|
||||
<< " (" << mData.mData.mSkills[i] << ")" << std::endl;
|
||||
|
@ -708,7 +706,7 @@ void Record<ESM::Faction>::print()
|
|||
<< mData.mData.mRankData[i].mFactReaction << std::endl;
|
||||
}
|
||||
std::map<std::string, int>::iterator rit;
|
||||
for (rit = mData.mReactions.begin(); rit != mData.mReactions.end(); rit++)
|
||||
for (rit = mData.mReactions.begin(); rit != mData.mReactions.end(); ++rit)
|
||||
std::cout << " Reaction: " << rit->second << " = " << rit->first << std::endl;
|
||||
}
|
||||
|
||||
|
@ -765,7 +763,7 @@ void Record<ESM::DialInfo>::print()
|
|||
std::cout << " Unknown2: " << (int)mData.mData.mUnknown2 << std::endl;
|
||||
|
||||
std::vector<ESM::DialInfo::SelectStruct>::iterator sit;
|
||||
for (sit = mData.mSelects.begin(); sit != mData.mSelects.end(); sit++)
|
||||
for (sit = mData.mSelects.begin(); sit != mData.mSelects.end(); ++sit)
|
||||
std::cout << " Select Rule: " << ruleString(*sit) << std::endl;
|
||||
|
||||
if (mData.mResultScript != "")
|
||||
|
@ -837,7 +835,7 @@ void Record<ESM::CreatureLevList>::print()
|
|||
std::cout << " Flags: " << creatureListFlags(mData.mFlags) << std::endl;
|
||||
std::cout << " Number of items: " << mData.mList.size() << std::endl;
|
||||
std::vector<ESM::LeveledListBase::LevelItem>::iterator iit;
|
||||
for (iit = mData.mList.begin(); iit != mData.mList.end(); iit++)
|
||||
for (iit = mData.mList.begin(); iit != mData.mList.end(); ++iit)
|
||||
std::cout << " Creature: Level: " << iit->mLevel
|
||||
<< " Creature: " << iit->mId << std::endl;
|
||||
}
|
||||
|
@ -849,7 +847,7 @@ void Record<ESM::ItemLevList>::print()
|
|||
std::cout << " Flags: " << itemListFlags(mData.mFlags) << std::endl;
|
||||
std::cout << " Number of items: " << mData.mList.size() << std::endl;
|
||||
std::vector<ESM::LeveledListBase::LevelItem>::iterator iit;
|
||||
for (iit = mData.mList.begin(); iit != mData.mList.end(); iit++)
|
||||
for (iit = mData.mList.begin(); iit != mData.mList.end(); ++iit)
|
||||
std::cout << " Inventory: Level: " << iit->mLevel
|
||||
<< " Item: " << iit->mId << std::endl;
|
||||
}
|
||||
|
@ -952,9 +950,9 @@ void Record<ESM::MagicEffect>::print()
|
|||
std::cout << " School: " << schoolLabel(mData.mData.mSchool)
|
||||
<< " (" << mData.mData.mSchool << ")" << std::endl;
|
||||
std::cout << " Base Cost: " << mData.mData.mBaseCost << std::endl;
|
||||
std::cout << " Unknown 1: " << mData.mData.mUnknown1 << std::endl;
|
||||
std::cout << " Speed: " << mData.mData.mSpeed << std::endl;
|
||||
std::cout << " Size: " << mData.mData.mSize << std::endl;
|
||||
std::cout << " Size Cap: " << mData.mData.mSizeCap << std::endl;
|
||||
std::cout << " Unknown 2: " << mData.mData.mUnknown2 << std::endl;
|
||||
std::cout << " RGB Color: " << "("
|
||||
<< mData.mData.mRed << ","
|
||||
<< mData.mData.mGreen << ","
|
||||
|
@ -994,7 +992,6 @@ void Record<ESM::NPC>::print()
|
|||
std::cout << " Level: " << mData.mNpdt12.mLevel << std::endl;
|
||||
std::cout << " Reputation: " << (int)mData.mNpdt12.mReputation << std::endl;
|
||||
std::cout << " Disposition: " << (int)mData.mNpdt12.mDisposition << std::endl;
|
||||
std::cout << " Faction: " << (int)mData.mNpdt52.mFactionID << std::endl;
|
||||
std::cout << " Rank: " << (int)mData.mNpdt12.mRank << std::endl;
|
||||
std::cout << " Unknown1: "
|
||||
<< (unsigned int)((unsigned char)mData.mNpdt12.mUnknown1) << std::endl;
|
||||
|
@ -1009,6 +1006,7 @@ void Record<ESM::NPC>::print()
|
|||
std::cout << " Reputation: " << (int)mData.mNpdt52.mReputation << std::endl;
|
||||
std::cout << " Disposition: " << (int)mData.mNpdt52.mDisposition << std::endl;
|
||||
std::cout << " Rank: " << (int)mData.mNpdt52.mRank << std::endl;
|
||||
std::cout << " FactionID: " << (int)mData.mNpdt52.mFactionID << std::endl;
|
||||
|
||||
std::cout << " Attributes:" << std::endl;
|
||||
std::cout << " Strength: " << (int)mData.mNpdt52.mStrength << std::endl;
|
||||
|
@ -1033,16 +1031,16 @@ void Record<ESM::NPC>::print()
|
|||
}
|
||||
|
||||
std::vector<ESM::ContItem>::iterator cit;
|
||||
for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); cit++)
|
||||
for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); ++cit)
|
||||
std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount
|
||||
<< " Item: " << cit->mItem.toString() << std::endl;
|
||||
|
||||
std::vector<std::string>::iterator sit;
|
||||
for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); sit++)
|
||||
for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); ++sit)
|
||||
std::cout << " Spell: " << *sit << std::endl;
|
||||
|
||||
std::vector<ESM::NPC::Dest>::iterator dit;
|
||||
for (dit = mData.mTransport.begin(); dit != mData.mTransport.end(); dit++)
|
||||
for (dit = mData.mTransport.begin(); dit != mData.mTransport.end(); ++dit)
|
||||
{
|
||||
std::cout << " Destination Position: "
|
||||
<< boost::format("%12.3f") % dit->mPos.pos[0] << ","
|
||||
|
@ -1068,7 +1066,7 @@ void Record<ESM::NPC>::print()
|
|||
std::cout << " AI Services:" << boost::format("0x%08X") % mData.mAiData.mServices << std::endl;
|
||||
|
||||
std::vector<ESM::AIPackage>::iterator pit;
|
||||
for (pit = mData.mAiPackage.mList.begin(); pit != mData.mAiPackage.mList.end(); pit++)
|
||||
for (pit = mData.mAiPackage.mList.begin(); pit != mData.mAiPackage.mList.end(); ++pit)
|
||||
printAIPackage(*pit);
|
||||
}
|
||||
|
||||
|
@ -1142,7 +1140,7 @@ void Record<ESM::Race>::print()
|
|||
<< mData.mData.mBonus[i].mBonus << std::endl;
|
||||
|
||||
std::vector<std::string>::iterator sit;
|
||||
for (sit = mData.mPowers.mList.begin(); sit != mData.mPowers.mList.end(); sit++)
|
||||
for (sit = mData.mPowers.mList.begin(); sit != mData.mPowers.mList.end(); ++sit)
|
||||
std::cout << " Power: " << *sit << std::endl;
|
||||
}
|
||||
|
||||
|
@ -1166,7 +1164,7 @@ void Record<ESM::Region>::print()
|
|||
if (mData.mSleepList != "")
|
||||
std::cout << " Sleep List: " << mData.mSleepList << std::endl;
|
||||
std::vector<ESM::Region::SoundRef>::iterator sit;
|
||||
for (sit = mData.mSoundList.begin(); sit != mData.mSoundList.end(); sit++)
|
||||
for (sit = mData.mSoundList.begin(); sit != mData.mSoundList.end(); ++sit)
|
||||
std::cout << " Sound: " << (int)sit->mChance << " = " << sit->mSound.toString() << std::endl;
|
||||
}
|
||||
|
||||
|
@ -1183,12 +1181,12 @@ void Record<ESM::Script>::print()
|
|||
|
||||
|
||||
std::vector<std::string>::iterator vit;
|
||||
for (vit = mData.mVarNames.begin(); vit != mData.mVarNames.end(); vit++)
|
||||
for (vit = mData.mVarNames.begin(); vit != mData.mVarNames.end(); ++vit)
|
||||
std::cout << " Variable: " << *vit << std::endl;
|
||||
|
||||
std::cout << " ByteCode: ";
|
||||
std::vector<unsigned char>::iterator cit;
|
||||
for (cit = mData.mScriptData.begin(); cit != mData.mScriptData.end(); cit++)
|
||||
for (cit = mData.mScriptData.begin(); cit != mData.mScriptData.end(); ++cit)
|
||||
std::cout << boost::format("%02X") % (int)(*cit);
|
||||
std::cout << std::endl;
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ set(LAUNCHER
|
|||
utils/textinputdialog.cpp
|
||||
utils/lineedit.cpp
|
||||
|
||||
${CMAKE_SOURCE_DIR}/files/launcher/launcher.rc
|
||||
${CMAKE_SOURCE_DIR}/files/windows/launcher.rc
|
||||
)
|
||||
|
||||
set(LAUNCHER_HEADER
|
||||
|
@ -74,19 +74,10 @@ QT4_WRAP_UI(UI_HDRS ${LAUNCHER_UI})
|
|||
include(${QT_USE_FILE})
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
if(NOT WIN32)
|
||||
include_directories(${LIBUNSHIELD_INCLUDE})
|
||||
include_directories(${LIBUNSHIELD_INCLUDE_DIR})
|
||||
endif(NOT WIN32)
|
||||
|
||||
# Main executable
|
||||
IF(OGRE_STATIC)
|
||||
IF(WIN32)
|
||||
ADD_DEFINITIONS(-DENABLE_PLUGIN_Direct3D9 -DENABLE_PLUGIN_GL)
|
||||
set(OGRE_STATIC_PLUGINS ${OGRE_RenderSystem_Direct3D9_LIBRARIES} ${OGRE_RenderSystem_GL_LIBRARIES})
|
||||
ELSE(WIN32)
|
||||
ADD_DEFINITIONS(-DENABLE_PLUGIN_GL)
|
||||
set(OGRE_STATIC_PLUGINS ${OGRE_RenderSystem_GL_LIBRARIES})
|
||||
ENDIF(WIN32)
|
||||
ENDIF(OGRE_STATIC)
|
||||
add_executable(omwlauncher
|
||||
${GUI_TYPE}
|
||||
${LAUNCHER}
|
||||
|
@ -100,16 +91,13 @@ target_link_libraries(omwlauncher
|
|||
${Boost_LIBRARIES}
|
||||
${OGRE_LIBRARIES}
|
||||
${OGRE_STATIC_PLUGINS}
|
||||
${SDL2_LIBRARY}
|
||||
${SDL2_LIBRARY_ONLY}
|
||||
${QT_LIBRARIES}
|
||||
components
|
||||
)
|
||||
|
||||
if(DPKG_PROGRAM)
|
||||
INSTALL(TARGETS omwlauncher RUNTIME DESTINATION games COMPONENT omwlauncher)
|
||||
endif()
|
||||
|
||||
if(BUILD_WITH_CODE_COVERAGE)
|
||||
if (BUILD_WITH_CODE_COVERAGE)
|
||||
add_definitions (--coverage)
|
||||
target_link_libraries(omwlauncher gcov)
|
||||
endif()
|
||||
|
|
|
@ -33,7 +33,11 @@ QString getAspect(int x, int y)
|
|||
}
|
||||
|
||||
Launcher::GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &graphicsSetting, QWidget *parent)
|
||||
: mCfgMgr(cfg)
|
||||
: mOgre(NULL)
|
||||
, mSelectedRenderSystem(NULL)
|
||||
, mOpenGLRenderSystem(NULL)
|
||||
, mDirect3DRenderSystem(NULL)
|
||||
, mCfgMgr(cfg)
|
||||
, mGraphicsSettings(graphicsSetting)
|
||||
, QWidget(parent)
|
||||
{
|
||||
|
|
|
@ -22,8 +22,3 @@ if (BUILD_WITH_CODE_COVERAGE)
|
|||
add_definitions (--coverage)
|
||||
target_link_libraries(mwiniimport gcov)
|
||||
endif()
|
||||
|
||||
if(DPKG_PROGRAM)
|
||||
INSTALL(TARGETS mwiniimport RUNTIME DESTINATION games COMPONENT mwiniimport)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace bfs = boost::filesystem;
|
|||
|
||||
MwIniImporter::MwIniImporter()
|
||||
: mVerbose(false)
|
||||
, mEncoding(ToUTF8::WINDOWS_1250)
|
||||
{
|
||||
const char *map[][2] =
|
||||
{
|
||||
|
@ -709,8 +710,7 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(const std::string& filenam
|
|||
continue;
|
||||
}
|
||||
|
||||
multistrmap::iterator it;
|
||||
if((it = map.find(key)) == map.end()) {
|
||||
if(map.find(key) == map.end()) {
|
||||
map.insert( std::make_pair (key, std::vector<std::string>() ) );
|
||||
}
|
||||
map[key].push_back(value);
|
||||
|
@ -746,8 +746,7 @@ MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const std::string& filenam
|
|||
std::string key(line.substr(0,pos));
|
||||
std::string value(line.substr(pos+1));
|
||||
|
||||
multistrmap::iterator it;
|
||||
if((it = map.find(key)) == map.end()) {
|
||||
if(map.find(key) == map.end()) {
|
||||
map.insert( std::make_pair (key, std::vector<std::string>() ) );
|
||||
}
|
||||
map[key].push_back(value);
|
||||
|
|
|
@ -37,6 +37,8 @@ public:
|
|||
char **get() const { return const_cast<char **>(argv); }
|
||||
|
||||
private:
|
||||
utf8argv(const utf8argv&);
|
||||
utf8argv& operator=(const utf8argv&);
|
||||
|
||||
const char **argv;
|
||||
std::vector<std::string> args;
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
set (OPENCS_SRC main.cpp)
|
||||
set (OPENCS_SRC main.cpp
|
||||
${CMAKE_SOURCE_DIR}/files/windows/opencs.rc
|
||||
)
|
||||
|
||||
opencs_units (. editor)
|
||||
|
||||
set (CMAKE_BUILD_TYPE DEBUG)
|
||||
|
||||
opencs_units (model/doc
|
||||
document operation saving documentmanager loader
|
||||
document operation saving documentmanager loader runner
|
||||
)
|
||||
|
||||
opencs_units_noqt (model/doc
|
||||
stage savingstate savingstages
|
||||
stage savingstate savingstages blacklist
|
||||
)
|
||||
|
||||
opencs_hdrs_noqt (model/doc
|
||||
|
@ -18,17 +20,18 @@ opencs_hdrs_noqt (model/doc
|
|||
|
||||
|
||||
opencs_units (model/world
|
||||
idtable idtableproxymodel regionmap data
|
||||
idtable idtableproxymodel regionmap data commanddispatcher idtablebase resourcetable
|
||||
)
|
||||
|
||||
|
||||
opencs_units_noqt (model/world
|
||||
universalid record commands columnbase scriptcontext cell refidcollection
|
||||
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection
|
||||
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope
|
||||
pathgrid landtexture land
|
||||
)
|
||||
|
||||
opencs_hdrs_noqt (model/world
|
||||
columnimp idcollection collection info
|
||||
columnimp idcollection collection info subcellcollection
|
||||
)
|
||||
|
||||
|
||||
|
@ -38,13 +41,13 @@ opencs_units (model/tools
|
|||
|
||||
opencs_units_noqt (model/tools
|
||||
mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck
|
||||
birthsigncheck spellcheck referenceablecheck scriptcheck
|
||||
birthsigncheck spellcheck referenceablecheck scriptcheck bodypartcheck
|
||||
)
|
||||
|
||||
|
||||
opencs_units (view/doc
|
||||
viewmanager view operations operation subview startup filedialog newgame
|
||||
filewidget adjusterwidget loader
|
||||
filewidget adjusterwidget loader globaldebugprofilemenu runlogsubview
|
||||
)
|
||||
|
||||
|
||||
|
@ -59,23 +62,31 @@ opencs_hdrs_noqt (view/doc
|
|||
|
||||
opencs_units (view/world
|
||||
table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator
|
||||
cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool
|
||||
scenetoolmode infocreator scriptedit dialoguesubview previewsubview regionmap dragrecordtable
|
||||
)
|
||||
|
||||
opencs_units (view/render
|
||||
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
|
||||
previewwidget
|
||||
)
|
||||
|
||||
opencs_units_noqt (view/render
|
||||
navigation navigation1st navigationfree navigationorbit lighting lightingday lightingnight
|
||||
lightingbright
|
||||
cellcreator referenceablecreator referencecreator scenesubview
|
||||
infocreator scriptedit dialoguesubview previewsubview regionmap dragrecordtable
|
||||
)
|
||||
|
||||
opencs_units_noqt (view/world
|
||||
subviews enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate
|
||||
scripthighlighter idvalidator dialoguecreator
|
||||
scripthighlighter idvalidator dialoguecreator physicssystem physicsmanager
|
||||
)
|
||||
|
||||
opencs_units (view/widget
|
||||
scenetoolbar scenetool scenetoolmode pushbutton scenetooltoggle scenetoolrun modebutton
|
||||
)
|
||||
|
||||
opencs_units (view/render
|
||||
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
|
||||
previewwidget editmode
|
||||
)
|
||||
|
||||
opencs_units_noqt (view/render
|
||||
navigation navigation1st navigationfree navigationorbit lighting lightingday lightingnight
|
||||
lightingbright object cell terrainstorage textoverlay overlaymask overlaysystem mousestate
|
||||
)
|
||||
|
||||
opencs_hdrs_noqt (view/render
|
||||
elements
|
||||
)
|
||||
|
||||
|
||||
|
@ -118,12 +129,8 @@ opencs_units_noqt (model/filter
|
|||
node unarynode narynode leafnode booleannode parser andnode ornode notnode textnode valuenode
|
||||
)
|
||||
|
||||
opencs_hdrs_noqt (model/filter
|
||||
filter
|
||||
)
|
||||
|
||||
opencs_units (view/filter
|
||||
filtercreator filterbox recordfilterbox editwidget
|
||||
filterbox recordfilterbox editwidget
|
||||
)
|
||||
|
||||
set (OPENCS_US
|
||||
|
@ -158,7 +165,7 @@ qt4_wrap_ui(OPENCS_UI_HDR ${OPENCS_UI})
|
|||
qt4_wrap_cpp(OPENCS_MOC_SRC ${OPENCS_HDR_QT})
|
||||
qt4_add_resources(OPENCS_RES_SRC ${OPENCS_RES})
|
||||
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${BULLET_INCLUDE_DIRS})
|
||||
|
||||
if(APPLE)
|
||||
set (OPENCS_MAC_ICON ${CMAKE_SOURCE_DIR}/files/mac/opencs.icns)
|
||||
|
@ -168,6 +175,7 @@ endif(APPLE)
|
|||
|
||||
add_executable(opencs
|
||||
MACOSX_BUNDLE
|
||||
${OENGINE_BULLET}
|
||||
${OPENCS_SRC}
|
||||
${OPENCS_UI_HDR}
|
||||
${OPENCS_MOC_SRC}
|
||||
|
@ -192,16 +200,15 @@ endif(APPLE)
|
|||
|
||||
target_link_libraries(opencs
|
||||
${OGRE_LIBRARIES}
|
||||
${OGRE_Overlay_LIBRARIES}
|
||||
${OGRE_STATIC_PLUGINS}
|
||||
${SHINY_LIBRARIES}
|
||||
${Boost_LIBRARIES}
|
||||
${BULLET_LIBRARIES}
|
||||
${QT_LIBRARIES}
|
||||
components
|
||||
)
|
||||
|
||||
if(DPKG_PROGRAM)
|
||||
INSTALL(TARGETS opencs RUNTIME DESTINATION games COMPONENT opencs)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
INSTALL(TARGETS opencs BUNDLE DESTINATION OpenMW COMPONENT BUNDLE)
|
||||
endif()
|
||||
|
|
|
@ -20,8 +20,9 @@
|
|||
#include "model/world/data.hpp"
|
||||
|
||||
CS::Editor::Editor (OgreInit::OgreInit& ogreInit)
|
||||
: mUserSettings (mCfgMgr), mDocumentManager (mCfgMgr), mViewManager (mDocumentManager),
|
||||
mIpcServerName ("org.openmw.OpenCS")
|
||||
: mUserSettings (mCfgMgr), mOverlaySystem (0), mDocumentManager (mCfgMgr),
|
||||
mViewManager (mDocumentManager), mPhysicsManager (0),
|
||||
mIpcServerName ("org.openmw.OpenCS"), mServer(NULL), mClientSocket(NULL)
|
||||
{
|
||||
std::pair<Files::PathContainer, std::vector<std::string> > config = readConfig();
|
||||
|
||||
|
@ -32,9 +33,14 @@ CS::Editor::Editor (OgreInit::OgreInit& ogreInit)
|
|||
|
||||
ogreInit.init ((mCfgMgr.getUserConfigPath() / "opencsOgre.log").string());
|
||||
|
||||
mOverlaySystem.reset (new CSVRender::OverlaySystem);
|
||||
mPhysicsManager.reset (new CSVWorld::PhysicsManager);
|
||||
|
||||
Bsa::registerResources (Files::Collections (config.first, !mFsStrict), config.second, true,
|
||||
mFsStrict);
|
||||
|
||||
mDocumentManager.listResources();
|
||||
|
||||
mNewGame.setLocalData (mLocal);
|
||||
mFileDialog.setLocalData (mLocal);
|
||||
|
||||
|
@ -63,6 +69,9 @@ CS::Editor::Editor (OgreInit::OgreInit& ogreInit)
|
|||
this, SLOT (createNewGame (const boost::filesystem::path&)));
|
||||
}
|
||||
|
||||
CS::Editor::~Editor ()
|
||||
{}
|
||||
|
||||
void CS::Editor::setupDataFiles (const Files::PathContainer& dataDirs)
|
||||
{
|
||||
for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter)
|
||||
|
@ -78,13 +87,17 @@ std::pair<Files::PathContainer, std::vector<std::string> > CS::Editor::readConfi
|
|||
boost::program_options::options_description desc("Syntax: opencs <options>\nAllowed options");
|
||||
|
||||
desc.add_options()
|
||||
("data", boost::program_options::value<Files::PathContainer>()->default_value(Files::PathContainer(), "data")->multitoken())
|
||||
("data", boost::program_options::value<Files::PathContainer>()->default_value(Files::PathContainer(), "data")->multitoken()->composing())
|
||||
("data-local", boost::program_options::value<std::string>()->default_value(""))
|
||||
("fs-strict", boost::program_options::value<bool>()->implicit_value(true)->default_value(false))
|
||||
("encoding", boost::program_options::value<std::string>()->default_value("win1252"))
|
||||
("resources", boost::program_options::value<std::string>()->default_value("resources"))
|
||||
("fallback-archive", boost::program_options::value<std::vector<std::string> >()->
|
||||
default_value(std::vector<std::string>(), "fallback-archive")->multitoken());
|
||||
default_value(std::vector<std::string>(), "fallback-archive")->multitoken())
|
||||
("script-blacklist", boost::program_options::value<std::vector<std::string> >()->default_value(std::vector<std::string>(), "")
|
||||
->multitoken(), "exclude specified script from the verifier (if the use of the blacklist is enabled)")
|
||||
("script-blacklist-use", boost::program_options::value<bool>()->implicit_value(true)
|
||||
->default_value(true), "enable script blacklisting");
|
||||
|
||||
boost::program_options::notify(variables);
|
||||
|
||||
|
@ -95,6 +108,10 @@ std::pair<Files::PathContainer, std::vector<std::string> > CS::Editor::readConfi
|
|||
|
||||
mDocumentManager.setResourceDir (mResources = variables["resources"].as<std::string>());
|
||||
|
||||
if (variables["script-blacklist-use"].as<bool>())
|
||||
mDocumentManager.setBlacklistedScripts (
|
||||
variables["script-blacklist"].as<std::vector<std::string> >());
|
||||
|
||||
mFsStrict = variables["fs-strict"].as<bool>();
|
||||
|
||||
Files::PathContainer dataDirs, dataLocal;
|
||||
|
@ -179,7 +196,7 @@ void CS::Editor::createNewFile (const boost::filesystem::path &savePath)
|
|||
files.push_back(path.toUtf8().constData());
|
||||
}
|
||||
|
||||
files.push_back(mFileDialog.filename().toUtf8().constData());
|
||||
files.push_back (savePath);
|
||||
|
||||
mDocumentManager.addDocument (files, savePath, true);
|
||||
|
||||
|
@ -249,26 +266,49 @@ int CS::Editor::run()
|
|||
|
||||
std::auto_ptr<sh::Factory> CS::Editor::setupGraphics()
|
||||
{
|
||||
// TODO: setting
|
||||
Ogre::Root::getSingleton().setRenderSystem(Ogre::Root::getSingleton().getRenderSystemByName("OpenGL Rendering Subsystem"));
|
||||
std::string renderer =
|
||||
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
|
||||
"Direct3D9 Rendering Subsystem";
|
||||
#else
|
||||
"OpenGL Rendering Subsystem";
|
||||
#endif
|
||||
std::string renderSystem = mUserSettings.setting("Video/render system", renderer.c_str()).toStdString();
|
||||
|
||||
Ogre::Root::getSingleton().setRenderSystem(Ogre::Root::getSingleton().getRenderSystemByName(renderSystem));
|
||||
|
||||
// Initialise Ogre::OverlaySystem after Ogre::Root but before initialisation
|
||||
mOverlaySystem.get();
|
||||
|
||||
Ogre::Root::getSingleton().initialise(false);
|
||||
|
||||
// Create a hidden background window to keep resources
|
||||
Ogre::NameValuePairList params;
|
||||
params.insert(std::make_pair("title", ""));
|
||||
params.insert(std::make_pair("FSAA", "0"));
|
||||
|
||||
std::string antialiasing = mUserSettings.settingValue("Video/antialiasing").toStdString();
|
||||
if(antialiasing == "MSAA 16") antialiasing = "16";
|
||||
else if(antialiasing == "MSAA 8") antialiasing = "8";
|
||||
else if(antialiasing == "MSAA 4") antialiasing = "4";
|
||||
else if(antialiasing == "MSAA 2") antialiasing = "2";
|
||||
else antialiasing = "0";
|
||||
params.insert(std::make_pair("FSAA", antialiasing));
|
||||
|
||||
params.insert(std::make_pair("vsync", "false"));
|
||||
params.insert(std::make_pair("hidden", "true"));
|
||||
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
|
||||
params.insert(std::make_pair("macAPI", "cocoa"));
|
||||
#endif
|
||||
// NOTE: fullscreen mode not supported (doesn't really make sense for opencs)
|
||||
Ogre::RenderWindow* hiddenWindow = Ogre::Root::getSingleton().createRenderWindow("InactiveHidden", 1, 1, false, ¶ms);
|
||||
hiddenWindow->setActive(false);
|
||||
|
||||
sh::OgrePlatform* platform =
|
||||
new sh::OgrePlatform ("General", (mResources / "materials").string());
|
||||
|
||||
// for font used in overlays
|
||||
Ogre::Root::getSingleton().addResourceLocation ((mResources / "mygui").string(),
|
||||
"FileSystem", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true);
|
||||
|
||||
if (!boost::filesystem::exists (mCfgMgr.getCachePath()))
|
||||
boost::filesystem::create_directories (mCfgMgr.getCachePath());
|
||||
|
||||
|
@ -276,7 +316,28 @@ std::auto_ptr<sh::Factory> CS::Editor::setupGraphics()
|
|||
|
||||
std::auto_ptr<sh::Factory> factory (new sh::Factory (platform));
|
||||
|
||||
factory->setCurrentLanguage (sh::Language_GLSL); /// \todo make this configurable
|
||||
QString shLang = mUserSettings.settingValue("General/shader mode");
|
||||
QString rend = renderSystem.c_str();
|
||||
bool openGL = rend.contains(QRegExp("^OpenGL", Qt::CaseInsensitive));
|
||||
bool glES = rend.contains(QRegExp("^OpenGL ES", Qt::CaseInsensitive));
|
||||
|
||||
// force shader language based on render system
|
||||
if(shLang == ""
|
||||
|| (openGL && shLang == "hlsl")
|
||||
|| (!openGL && shLang == "glsl")
|
||||
|| (glES && shLang != "glsles"))
|
||||
{
|
||||
shLang = openGL ? (glES ? "glsles" : "glsl") : "hlsl";
|
||||
//no group means "General" group in the "ini" file standard
|
||||
mUserSettings.setDefinitions("shader mode", (QStringList() << shLang));
|
||||
}
|
||||
enum sh::Language lang;
|
||||
if(shLang == "glsl") lang = sh::Language_GLSL;
|
||||
else if(shLang == "glsles") lang = sh::Language_GLSLES;
|
||||
else if(shLang == "hlsl") lang = sh::Language_HLSL;
|
||||
else lang = sh::Language_CG;
|
||||
|
||||
factory->setCurrentLanguage (lang);
|
||||
factory->setWriteSourceCache (true);
|
||||
factory->setReadSourceCache (true);
|
||||
factory->setReadMicrocodeCache (true);
|
||||
|
@ -284,16 +345,27 @@ std::auto_ptr<sh::Factory> CS::Editor::setupGraphics()
|
|||
|
||||
factory->loadAllFiles();
|
||||
|
||||
sh::Factory::getInstance().setGlobalSetting ("fog", "true");
|
||||
bool shaders = mUserSettings.setting("3d-render/shaders", QString("true")) == "true" ? true : false;
|
||||
sh::Factory::getInstance ().setShadersEnabled (shaders);
|
||||
|
||||
sh::Factory::getInstance().setGlobalSetting ("shadows", "false");
|
||||
sh::Factory::getInstance().setGlobalSetting ("shadows_pssm", "false");
|
||||
std::string fog = mUserSettings.setting("Shader/fog", QString("true")).toStdString();
|
||||
sh::Factory::getInstance().setGlobalSetting ("fog", fog);
|
||||
|
||||
sh::Factory::getInstance ().setGlobalSetting ("render_refraction", "false");
|
||||
|
||||
std::string shadows = mUserSettings.setting("Shader/shadows", QString("false")).toStdString();
|
||||
sh::Factory::getInstance().setGlobalSetting ("shadows", shadows);
|
||||
|
||||
std::string shadows_pssm = mUserSettings.setting("Shader/shadows_pssm", QString("false")).toStdString();
|
||||
sh::Factory::getInstance().setGlobalSetting ("shadows_pssm", shadows_pssm);
|
||||
|
||||
std::string render_refraction = mUserSettings.setting("Shader/render_refraction", QString("false")).toStdString();
|
||||
sh::Factory::getInstance ().setGlobalSetting ("render_refraction", render_refraction);
|
||||
|
||||
// internal setting - may be switched on or off by the use of shader configurations
|
||||
sh::Factory::getInstance ().setGlobalSetting ("viewproj_fix", "false");
|
||||
|
||||
sh::Factory::getInstance ().setGlobalSetting ("num_lights", "8");
|
||||
std::string num_lights = mUserSettings.setting("3d-render-adv/num_lights", QString("8")).toStdString();
|
||||
sh::Factory::getInstance ().setGlobalSetting ("num_lights", num_lights);
|
||||
|
||||
/// \todo add more configurable shiny settings
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
#include <components/files/multidircollection.hpp>
|
||||
|
||||
#include <components/nifcache/nifcache.hpp>
|
||||
|
||||
#include "model/settings/usersettings.hpp"
|
||||
#include "model/doc/documentmanager.hpp"
|
||||
|
||||
|
@ -25,6 +27,8 @@
|
|||
#include "view/doc/newgame.hpp"
|
||||
|
||||
#include "view/settings/dialog.hpp"
|
||||
#include "view/render/overlaysystem.hpp"
|
||||
#include "view/world/physicsmanager.hpp"
|
||||
|
||||
namespace OgreInit
|
||||
{
|
||||
|
@ -37,8 +41,11 @@ namespace CS
|
|||
{
|
||||
Q_OBJECT
|
||||
|
||||
Nif::Cache mNifCache;
|
||||
Files::ConfigurationManager mCfgMgr;
|
||||
CSMSettings::UserSettings mUserSettings;
|
||||
std::auto_ptr<CSVRender::OverlaySystem> mOverlaySystem;
|
||||
std::auto_ptr<CSVWorld::PhysicsManager> mPhysicsManager;
|
||||
CSMDoc::DocumentManager mDocumentManager;
|
||||
CSVDoc::ViewManager mViewManager;
|
||||
CSVDoc::StartupDialogue mStartup;
|
||||
|
@ -61,6 +68,7 @@ namespace CS
|
|||
public:
|
||||
|
||||
Editor (OgreInit::OgreInit& ogreInit);
|
||||
~Editor ();
|
||||
|
||||
bool makeIPCServer();
|
||||
void connectToIPCServer();
|
||||
|
|
31
apps/opencs/model/doc/blacklist.cpp
Normal file
31
apps/opencs/model/doc/blacklist.cpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
|
||||
#include "blacklist.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
bool CSMDoc::Blacklist::isBlacklisted (const CSMWorld::UniversalId& id) const
|
||||
{
|
||||
std::map<CSMWorld::UniversalId::Type, std::vector<std::string> >::const_iterator iter =
|
||||
mIds.find (id.getType());
|
||||
|
||||
if (iter==mIds.end())
|
||||
return false;
|
||||
|
||||
return std::binary_search (iter->second.begin(), iter->second.end(),
|
||||
Misc::StringUtils::lowerCase (id.getId()));
|
||||
}
|
||||
|
||||
void CSMDoc::Blacklist::add (CSMWorld::UniversalId::Type type,
|
||||
const std::vector<std::string>& ids)
|
||||
{
|
||||
std::vector<std::string>& list = mIds[type];
|
||||
|
||||
int size = list.size();
|
||||
|
||||
list.resize (size+ids.size());
|
||||
|
||||
std::transform (ids.begin(), ids.end(), list.begin()+size, Misc::StringUtils::lowerCase);
|
||||
std::sort (list.begin(), list.end());
|
||||
}
|
25
apps/opencs/model/doc/blacklist.hpp
Normal file
25
apps/opencs/model/doc/blacklist.hpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifndef CSM_DOC_BLACKLIST_H
|
||||
#define CSM_DOC_BLACKLIST_H
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "../world/universalid.hpp"
|
||||
|
||||
namespace CSMDoc
|
||||
{
|
||||
/// \brief ID blacklist sorted by UniversalId type
|
||||
class Blacklist
|
||||
{
|
||||
std::map<CSMWorld::UniversalId::Type, std::vector<std::string> > mIds;
|
||||
|
||||
public:
|
||||
|
||||
bool isBlacklisted (const CSMWorld::UniversalId& id) const;
|
||||
|
||||
void add (CSMWorld::UniversalId::Type type, const std::vector<std::string>& ids);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,6 +1,7 @@
|
|||
#include "document.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
|
@ -2022,6 +2023,7 @@ void CSMDoc::Document::addOptionalGmsts()
|
|||
{
|
||||
ESM::GameSetting gmst;
|
||||
gmst.mId = sFloats[i];
|
||||
gmst.blank();
|
||||
gmst.mValue.setType (ESM::VT_Float);
|
||||
addOptionalGmst (gmst);
|
||||
}
|
||||
|
@ -2030,6 +2032,7 @@ void CSMDoc::Document::addOptionalGmsts()
|
|||
{
|
||||
ESM::GameSetting gmst;
|
||||
gmst.mId = sIntegers[i];
|
||||
gmst.blank();
|
||||
gmst.mValue.setType (ESM::VT_Int);
|
||||
addOptionalGmst (gmst);
|
||||
}
|
||||
|
@ -2038,6 +2041,7 @@ void CSMDoc::Document::addOptionalGmsts()
|
|||
{
|
||||
ESM::GameSetting gmst;
|
||||
gmst.mId = sStrings[i];
|
||||
gmst.blank();
|
||||
gmst.mValue.setType (ESM::VT_String);
|
||||
gmst.mValue.setString ("<no text>");
|
||||
addOptionalGmst (gmst);
|
||||
|
@ -2058,6 +2062,7 @@ void CSMDoc::Document::addOptionalGlobals()
|
|||
{
|
||||
ESM::Global global;
|
||||
global.mId = sGlobals[i];
|
||||
global.blank();
|
||||
global.mValue.setType (ESM::VT_Long);
|
||||
|
||||
if (i==0)
|
||||
|
@ -2067,6 +2072,19 @@ void CSMDoc::Document::addOptionalGlobals()
|
|||
}
|
||||
}
|
||||
|
||||
void CSMDoc::Document::addOptionalMagicEffects()
|
||||
{
|
||||
for (int i=ESM::MagicEffect::SummonFabricant; i<=ESM::MagicEffect::SummonCreature05; ++i)
|
||||
{
|
||||
ESM::MagicEffect effect;
|
||||
effect.mIndex = i;
|
||||
effect.mId = ESM::MagicEffect::indexToId (i);
|
||||
effect.blank();
|
||||
|
||||
addOptionalMagicEffect (effect);
|
||||
}
|
||||
}
|
||||
|
||||
void CSMDoc::Document::addOptionalGmst (const ESM::GameSetting& gmst)
|
||||
{
|
||||
if (getData().getGmsts().searchId (gmst.mId)==-1)
|
||||
|
@ -2089,6 +2107,17 @@ void CSMDoc::Document::addOptionalGlobal (const ESM::Global& global)
|
|||
}
|
||||
}
|
||||
|
||||
void CSMDoc::Document::addOptionalMagicEffect (const ESM::MagicEffect& magicEffect)
|
||||
{
|
||||
if (getData().getMagicEffects().searchId (magicEffect.mId)==-1)
|
||||
{
|
||||
CSMWorld::Record<ESM::MagicEffect> record;
|
||||
record.mBase = magicEffect;
|
||||
record.mState = CSMWorld::RecordBase::State_BaseOnly;
|
||||
getData().getMagicEffects().appendRecord (record);
|
||||
}
|
||||
}
|
||||
|
||||
void CSMDoc::Document::createBase()
|
||||
{
|
||||
static const char *sGlobals[] =
|
||||
|
@ -2200,33 +2229,49 @@ void CSMDoc::Document::createBase()
|
|||
|
||||
getData().getTopics().add (record);
|
||||
}
|
||||
|
||||
for (int i=0; i<ESM::MagicEffect::Length; ++i)
|
||||
{
|
||||
ESM::MagicEffect record;
|
||||
|
||||
record.mIndex = i;
|
||||
record.mId = ESM::MagicEffect::indexToId (i);
|
||||
|
||||
record.blank();
|
||||
|
||||
getData().getMagicEffects().add (record);
|
||||
}
|
||||
}
|
||||
|
||||
CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
|
||||
const std::vector< boost::filesystem::path >& files, bool new_,
|
||||
const boost::filesystem::path& savePath, const boost::filesystem::path& resDir,
|
||||
ToUTF8::FromType encoding)
|
||||
: mSavePath (savePath), mContentFiles (files), mNew (new_), mData (encoding), mTools (mData),
|
||||
mResDir(resDir),
|
||||
ToUTF8::FromType encoding, const CSMWorld::ResourcesManager& resourcesManager,
|
||||
const std::vector<std::string>& blacklistedScripts)
|
||||
: mSavePath (savePath), mContentFiles (files), mNew (new_), mData (encoding, resourcesManager),
|
||||
mTools (*this), mResDir(resDir),
|
||||
mProjectPath ((configuration.getUserDataPath() / "projects") /
|
||||
(savePath.filename().string() + ".project")),
|
||||
mSaving (*this, mProjectPath, encoding)
|
||||
mSaving (*this, mProjectPath, encoding),
|
||||
mRunner (mProjectPath)
|
||||
{
|
||||
if (mContentFiles.empty())
|
||||
throw std::runtime_error ("Empty content file sequence");
|
||||
|
||||
if (!boost::filesystem::exists (mProjectPath))
|
||||
{
|
||||
boost::filesystem::path locCustomFiltersPath (configuration.getUserDataPath());
|
||||
locCustomFiltersPath /= "defaultfilters";
|
||||
boost::filesystem::path customFiltersPath (configuration.getUserDataPath());
|
||||
customFiltersPath /= "defaultfilters";
|
||||
|
||||
if (boost::filesystem::exists (locCustomFiltersPath))
|
||||
std::ofstream destination (mProjectPath.string().c_str(), std::ios::binary);
|
||||
|
||||
if (boost::filesystem::exists (customFiltersPath))
|
||||
{
|
||||
boost::filesystem::copy_file (locCustomFiltersPath, mProjectPath);
|
||||
destination << std::ifstream(customFiltersPath.c_str(), std::ios::binary).rdbuf();
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::filesystem::copy_file (mResDir / "defaultfilters", mProjectPath);
|
||||
destination << std::ifstream(std::string(mResDir.string() + "/defaultfilters").c_str(), std::ios::binary).rdbuf();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2239,20 +2284,25 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
|
|||
createBase();
|
||||
}
|
||||
|
||||
mBlacklist.add (CSMWorld::UniversalId::Type_Script, blacklistedScripts);
|
||||
|
||||
addOptionalGmsts();
|
||||
addOptionalGlobals();
|
||||
addOptionalMagicEffects();
|
||||
|
||||
connect (&mUndoStack, SIGNAL (cleanChanged (bool)), this, SLOT (modificationStateChanged (bool)));
|
||||
|
||||
connect (&mTools, SIGNAL (progress (int, int, int)), this, SLOT (progress (int, int, int)));
|
||||
connect (&mTools, SIGNAL (done (int)), this, SLOT (operationDone (int)));
|
||||
connect (&mTools, SIGNAL (done (int, bool)), this, SLOT (operationDone (int, bool)));
|
||||
|
||||
connect (&mSaving, SIGNAL (progress (int, int, int)), this, SLOT (progress (int, int, int)));
|
||||
connect (&mSaving, SIGNAL (done (int)), this, SLOT (operationDone (int)));
|
||||
connect (&mSaving, SIGNAL (done (int, bool)), this, SLOT (operationDone (int, bool)));
|
||||
|
||||
connect (
|
||||
&mSaving, SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, int)),
|
||||
this, SLOT (reportMessage (const CSMWorld::UniversalId&, const std::string&, int)));
|
||||
|
||||
connect (&mRunner, SIGNAL (runStateChanged()), this, SLOT (runStateChanged()));
|
||||
}
|
||||
|
||||
CSMDoc::Document::~Document()
|
||||
|
@ -2274,6 +2324,9 @@ int CSMDoc::Document::getState() const
|
|||
if (mSaving.isRunning())
|
||||
state |= State_Locked | State_Saving | State_Operation;
|
||||
|
||||
if (mRunner.isRunning())
|
||||
state |= State_Locked | State_Running;
|
||||
|
||||
if (int operations = mTools.getRunningOperations())
|
||||
state |= State_Locked | State_Operation | operations;
|
||||
|
||||
|
@ -2338,7 +2391,7 @@ void CSMDoc::Document::reportMessage (const CSMWorld::UniversalId& id, const std
|
|||
std::cout << message << std::endl;
|
||||
}
|
||||
|
||||
void CSMDoc::Document::operationDone (int type)
|
||||
void CSMDoc::Document::operationDone (int type, bool failed)
|
||||
{
|
||||
emit stateChanged (getState(), this);
|
||||
}
|
||||
|
@ -2358,6 +2411,55 @@ CSMTools::ReportModel *CSMDoc::Document::getReport (const CSMWorld::UniversalId&
|
|||
return mTools.getReport (id);
|
||||
}
|
||||
|
||||
bool CSMDoc::Document::isBlacklisted (const CSMWorld::UniversalId& id)
|
||||
const
|
||||
{
|
||||
return mBlacklist.isBlacklisted (id);
|
||||
}
|
||||
|
||||
void CSMDoc::Document::startRunning (const std::string& profile,
|
||||
const std::string& startupInstruction)
|
||||
{
|
||||
std::vector<std::string> contentFiles;
|
||||
|
||||
for (std::vector<boost::filesystem::path>::const_iterator iter (mContentFiles.begin());
|
||||
iter!=mContentFiles.end(); ++iter)
|
||||
contentFiles.push_back (iter->filename().string());
|
||||
|
||||
mRunner.configure (getData().getDebugProfiles().getRecord (profile).get(), contentFiles,
|
||||
startupInstruction);
|
||||
|
||||
int state = getState();
|
||||
|
||||
if (state & State_Modified)
|
||||
{
|
||||
// need to save first
|
||||
mRunner.start (true);
|
||||
|
||||
new SaveWatcher (&mRunner, &mSaving); // no, that is not a memory leak. Qt is weird.
|
||||
|
||||
if (!(state & State_Saving))
|
||||
save();
|
||||
}
|
||||
else
|
||||
mRunner.start();
|
||||
}
|
||||
|
||||
void CSMDoc::Document::stopRunning()
|
||||
{
|
||||
mRunner.stop();
|
||||
}
|
||||
|
||||
QTextDocument *CSMDoc::Document::getRunLog()
|
||||
{
|
||||
return mRunner.getLog();
|
||||
}
|
||||
|
||||
void CSMDoc::Document::runStateChanged()
|
||||
{
|
||||
emit stateChanged (getState(), this);
|
||||
}
|
||||
|
||||
void CSMDoc::Document::progress (int current, int max, int type)
|
||||
{
|
||||
emit progress (current, max, type, 1, this);
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
#include "state.hpp"
|
||||
#include "saving.hpp"
|
||||
#include "blacklist.hpp"
|
||||
#include "runner.hpp"
|
||||
|
||||
class QAbstractItemModel;
|
||||
|
||||
|
@ -24,6 +26,7 @@ namespace ESM
|
|||
{
|
||||
struct GameSetting;
|
||||
struct Global;
|
||||
struct MagicEffect;
|
||||
}
|
||||
|
||||
namespace Files
|
||||
|
@ -31,6 +34,11 @@ namespace Files
|
|||
class ConfigurationManager;
|
||||
}
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class ResourcesManager;
|
||||
}
|
||||
|
||||
namespace CSMDoc
|
||||
{
|
||||
class Document : public QObject
|
||||
|
@ -47,6 +55,8 @@ namespace CSMDoc
|
|||
boost::filesystem::path mProjectPath;
|
||||
Saving mSaving;
|
||||
boost::filesystem::path mResDir;
|
||||
Blacklist mBlacklist;
|
||||
Runner mRunner;
|
||||
|
||||
// It is important that the undo stack is declared last, because on desctruction it fires a signal, that is connected to a slot, that is
|
||||
// using other member variables. Unfortunately this connection is cut only in the QObject destructor, which is way too late.
|
||||
|
@ -64,16 +74,21 @@ namespace CSMDoc
|
|||
|
||||
void addOptionalGlobals();
|
||||
|
||||
void addOptionalMagicEffects();
|
||||
|
||||
void addOptionalGmst (const ESM::GameSetting& gmst);
|
||||
|
||||
void addOptionalGlobal (const ESM::Global& global);
|
||||
|
||||
void addOptionalMagicEffect (const ESM::MagicEffect& effect);
|
||||
|
||||
public:
|
||||
|
||||
Document (const Files::ConfigurationManager& configuration,
|
||||
const std::vector< boost::filesystem::path >& files, bool new_,
|
||||
const boost::filesystem::path& savePath, const boost::filesystem::path& resDir,
|
||||
ToUTF8::FromType encoding);
|
||||
ToUTF8::FromType encoding, const CSMWorld::ResourcesManager& resourcesManager,
|
||||
const std::vector<std::string>& blacklistedScripts);
|
||||
|
||||
~Document();
|
||||
|
||||
|
@ -105,6 +120,15 @@ namespace CSMDoc
|
|||
CSMTools::ReportModel *getReport (const CSMWorld::UniversalId& id);
|
||||
///< The ownership of the returned report is not transferred.
|
||||
|
||||
bool isBlacklisted (const CSMWorld::UniversalId& id) const;
|
||||
|
||||
void startRunning (const std::string& profile,
|
||||
const std::string& startupInstruction = "");
|
||||
|
||||
void stopRunning();
|
||||
|
||||
QTextDocument *getRunLog();
|
||||
|
||||
signals:
|
||||
|
||||
void stateChanged (int state, CSMDoc::Document *document);
|
||||
|
@ -118,7 +142,9 @@ namespace CSMDoc
|
|||
void reportMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
||||
int type);
|
||||
|
||||
void operationDone (int type);
|
||||
void operationDone (int type, bool failed);
|
||||
|
||||
void runStateChanged();
|
||||
|
||||
public slots:
|
||||
|
||||
|
|
|
@ -31,8 +31,8 @@ CSMDoc::DocumentManager::DocumentManager (const Files::ConfigurationManager& con
|
|||
&mLoader, SLOT (loadDocument (CSMDoc::Document *)));
|
||||
connect (&mLoader, SIGNAL (nextStage (CSMDoc::Document *, const std::string&, int)),
|
||||
this, SIGNAL (nextStage (CSMDoc::Document *, const std::string&, int)));
|
||||
connect (&mLoader, SIGNAL (nextRecord (CSMDoc::Document *)),
|
||||
this, SIGNAL (nextRecord (CSMDoc::Document *)));
|
||||
connect (&mLoader, SIGNAL (nextRecord (CSMDoc::Document *, int)),
|
||||
this, SIGNAL (nextRecord (CSMDoc::Document *, int)));
|
||||
connect (this, SIGNAL (cancelLoading (CSMDoc::Document *)),
|
||||
&mLoader, SLOT (abortLoading (CSMDoc::Document *)));
|
||||
connect (&mLoader, SIGNAL (loadMessage (CSMDoc::Document *, const std::string&)),
|
||||
|
@ -52,7 +52,7 @@ CSMDoc::DocumentManager::~DocumentManager()
|
|||
void CSMDoc::DocumentManager::addDocument (const std::vector<boost::filesystem::path>& files, const boost::filesystem::path& savePath,
|
||||
bool new_)
|
||||
{
|
||||
Document *document = new Document (mConfiguration, files, new_, savePath, mResDir, mEncoding);
|
||||
Document *document = new Document (mConfiguration, files, new_, savePath, mResDir, mEncoding, mResourcesManager, mBlacklistedScripts);
|
||||
|
||||
mDocuments.push_back (document);
|
||||
|
||||
|
@ -85,6 +85,16 @@ void CSMDoc::DocumentManager::setEncoding (ToUTF8::FromType encoding)
|
|||
mEncoding = encoding;
|
||||
}
|
||||
|
||||
void CSMDoc::DocumentManager::setBlacklistedScripts (const std::vector<std::string>& scriptIds)
|
||||
{
|
||||
mBlacklistedScripts = scriptIds;
|
||||
}
|
||||
|
||||
void CSMDoc::DocumentManager::listResources()
|
||||
{
|
||||
mResourcesManager.listResources();
|
||||
}
|
||||
|
||||
void CSMDoc::DocumentManager::documentLoaded (Document *document)
|
||||
{
|
||||
emit documentAdded (document);
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
#include <components/to_utf8/to_utf8.hpp>
|
||||
|
||||
#include "../world/resourcesmanager.hpp"
|
||||
|
||||
#include "loader.hpp"
|
||||
|
||||
namespace Files
|
||||
|
@ -31,6 +33,8 @@ namespace CSMDoc
|
|||
QThread mLoaderThread;
|
||||
Loader mLoader;
|
||||
ToUTF8::FromType mEncoding;
|
||||
CSMWorld::ResourcesManager mResourcesManager;
|
||||
std::vector<std::string> mBlacklistedScripts;
|
||||
|
||||
DocumentManager (const DocumentManager&);
|
||||
DocumentManager& operator= (const DocumentManager&);
|
||||
|
@ -50,6 +54,11 @@ namespace CSMDoc
|
|||
|
||||
void setEncoding (ToUTF8::FromType encoding);
|
||||
|
||||
void setBlacklistedScripts (const std::vector<std::string>& scriptIds);
|
||||
|
||||
/// Ask OGRE for a list of available resources.
|
||||
void listResources();
|
||||
|
||||
private:
|
||||
|
||||
boost::filesystem::path mResDir;
|
||||
|
@ -79,9 +88,10 @@ namespace CSMDoc
|
|||
void loadingStopped (CSMDoc::Document *document, bool completed,
|
||||
const std::string& error);
|
||||
|
||||
void nextStage (CSMDoc::Document *document, const std::string& name, int steps);
|
||||
void nextStage (CSMDoc::Document *document, const std::string& name,
|
||||
int totalRecords);
|
||||
|
||||
void nextRecord (CSMDoc::Document *document);
|
||||
void nextRecord (CSMDoc::Document *document, int records);
|
||||
|
||||
void cancelLoading (CSMDoc::Document *document);
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include "document.hpp"
|
||||
#include "state.hpp"
|
||||
|
||||
CSMDoc::Loader::Stage::Stage() : mFile (0), mRecordsLeft (false) {}
|
||||
CSMDoc::Loader::Stage::Stage() : mFile (0), mRecordsLoaded (0), mRecordsLeft (false) {}
|
||||
|
||||
|
||||
CSMDoc::Loader::Loader()
|
||||
|
@ -39,13 +39,14 @@ void CSMDoc::Loader::load()
|
|||
Document *document = iter->first;
|
||||
|
||||
int size = static_cast<int> (document->getContentFiles().size());
|
||||
int editedIndex = size-1; // index of the file to be edited/created
|
||||
|
||||
if (document->isNew())
|
||||
--size;
|
||||
|
||||
bool done = false;
|
||||
|
||||
const int batchingSize = 100;
|
||||
const int batchingSize = 50;
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -58,17 +59,21 @@ void CSMDoc::Loader::load()
|
|||
iter->second.mRecordsLeft = false;
|
||||
break;
|
||||
}
|
||||
else
|
||||
++(iter->second.mRecordsLoaded);
|
||||
|
||||
CSMWorld::UniversalId log (CSMWorld::UniversalId::Type_LoadErrorLog, 0);
|
||||
|
||||
{ // silence a g++ warning
|
||||
for (CSMDoc::Stage::Messages::const_iterator iter (messages.begin());
|
||||
iter!=messages.end(); ++iter)
|
||||
{
|
||||
document->getReport (log)->add (iter->first, iter->second);
|
||||
emit loadMessage (document, iter->second);
|
||||
}
|
||||
}
|
||||
|
||||
emit nextRecord (document);
|
||||
emit nextRecord (document, iter->second.mRecordsLoaded);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -77,17 +82,19 @@ void CSMDoc::Loader::load()
|
|||
{
|
||||
boost::filesystem::path path = document->getContentFiles()[iter->second.mFile];
|
||||
|
||||
int steps = document->getData().startLoading (path, iter->second.mFile<size-1, false);
|
||||
int steps = document->getData().startLoading (path, iter->second.mFile!=editedIndex, false);
|
||||
iter->second.mRecordsLeft = true;
|
||||
iter->second.mRecordsLoaded = 0;
|
||||
|
||||
emit nextStage (document, path.filename().string(), steps/batchingSize);
|
||||
emit nextStage (document, path.filename().string(), steps);
|
||||
}
|
||||
else if (iter->second.mFile==size)
|
||||
{
|
||||
int steps = document->getData().startLoading (document->getProjectPath(), false, true);
|
||||
iter->second.mRecordsLeft = true;
|
||||
iter->second.mRecordsLoaded = 0;
|
||||
|
||||
emit nextStage (document, "Project File", steps/batchingSize);
|
||||
emit nextStage (document, "Project File", steps);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace CSMDoc
|
|||
struct Stage
|
||||
{
|
||||
int mFile;
|
||||
int mRecordsLoaded;
|
||||
bool mRecordsLeft;
|
||||
|
||||
Stage();
|
||||
|
@ -56,9 +57,10 @@ namespace CSMDoc
|
|||
///< Document load has been interrupted either because of a call to abortLoading
|
||||
/// or a problem during loading). In the former case error will be an empty string.
|
||||
|
||||
void nextStage (CSMDoc::Document *document, const std::string& name, int steps);
|
||||
void nextStage (CSMDoc::Document *document, const std::string& name,
|
||||
int totalRecords);
|
||||
|
||||
void nextRecord (CSMDoc::Document *document);
|
||||
void nextRecord (CSMDoc::Document *document, int records);
|
||||
///< \note This signal is only given once per group of records. The group size is
|
||||
/// approximately the total number of records divided by the steps value of the
|
||||
/// previous nextStage signal.
|
||||
|
|
|
@ -27,7 +27,9 @@ void CSMDoc::Operation::prepareStages()
|
|||
}
|
||||
|
||||
CSMDoc::Operation::Operation (int type, bool ordered, bool finalAlways)
|
||||
: mType (type), mOrdered (ordered), mFinalAlways (finalAlways)
|
||||
: mType (type), mStages(std::vector<std::pair<Stage *, int> >()), mCurrentStage(mStages.begin()),
|
||||
mCurrentStep(0), mCurrentStepTotal(0), mTotalSteps(0), mOrdered (ordered),
|
||||
mFinalAlways (finalAlways), mError(false)
|
||||
{
|
||||
connect (this, SIGNAL (finished()), this, SLOT (operationDone()));
|
||||
}
|
||||
|
@ -119,5 +121,5 @@ void CSMDoc::Operation::executeStage()
|
|||
|
||||
void CSMDoc::Operation::operationDone()
|
||||
{
|
||||
emit done (mType);
|
||||
}
|
||||
emit done (mType, mError);
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace CSMDoc
|
|||
void reportMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
||||
int type);
|
||||
|
||||
void done (int type);
|
||||
void done (int type, bool failed);
|
||||
|
||||
public slots:
|
||||
|
||||
|
|
162
apps/opencs/model/doc/runner.cpp
Normal file
162
apps/opencs/model/doc/runner.cpp
Normal file
|
@ -0,0 +1,162 @@
|
|||
|
||||
#include "runner.hpp"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDir>
|
||||
#include <QTemporaryFile>
|
||||
#include <QTextStream>
|
||||
|
||||
#include "operation.hpp"
|
||||
|
||||
CSMDoc::Runner::Runner (const boost::filesystem::path& projectPath)
|
||||
: mRunning (false), mStartup (0), mProjectPath (projectPath)
|
||||
{
|
||||
connect (&mProcess, SIGNAL (finished (int, QProcess::ExitStatus)),
|
||||
this, SLOT (finished (int, QProcess::ExitStatus)));
|
||||
|
||||
connect (&mProcess, SIGNAL (readyReadStandardOutput()),
|
||||
this, SLOT (readyReadStandardOutput()));
|
||||
|
||||
mProcess.setProcessChannelMode (QProcess::MergedChannels);
|
||||
|
||||
mProfile.blank();
|
||||
}
|
||||
|
||||
CSMDoc::Runner::~Runner()
|
||||
{
|
||||
if (mRunning)
|
||||
{
|
||||
disconnect (&mProcess, 0, this, 0);
|
||||
mProcess.kill();
|
||||
mProcess.waitForFinished();
|
||||
}
|
||||
}
|
||||
|
||||
void CSMDoc::Runner::start (bool delayed)
|
||||
{
|
||||
if (mStartup)
|
||||
{
|
||||
delete mStartup;
|
||||
mStartup = 0;
|
||||
}
|
||||
|
||||
if (!delayed)
|
||||
{
|
||||
mLog.clear();
|
||||
|
||||
QString path = "openmw";
|
||||
#ifdef Q_OS_WIN
|
||||
path.append(QString(".exe"));
|
||||
#elif defined(Q_OS_MAC)
|
||||
QDir dir(QCoreApplication::applicationDirPath());
|
||||
dir.cdUp();
|
||||
dir.cdUp();
|
||||
dir.cdUp();
|
||||
path = dir.absoluteFilePath(path.prepend("OpenMW.app/Contents/MacOS/"));
|
||||
#else
|
||||
path.prepend(QString("./"));
|
||||
#endif
|
||||
|
||||
mStartup = new QTemporaryFile (this);
|
||||
mStartup->open();
|
||||
|
||||
{
|
||||
QTextStream stream (mStartup);
|
||||
|
||||
if (!mStartupInstruction.empty())
|
||||
stream << QString::fromUtf8 (mStartupInstruction.c_str()) << '\n';
|
||||
|
||||
stream << QString::fromUtf8 (mProfile.mScriptText.c_str());
|
||||
}
|
||||
|
||||
mStartup->close();
|
||||
|
||||
QStringList arguments;
|
||||
arguments << "--skip-menu";
|
||||
|
||||
if (mProfile.mFlags & ESM::DebugProfile::Flag_BypassNewGame)
|
||||
arguments << "--new-game=0";
|
||||
else
|
||||
arguments << "--new-game=1";
|
||||
|
||||
arguments << ("--script-run="+mStartup->fileName());;
|
||||
|
||||
arguments <<
|
||||
QString::fromUtf8 (("--data="+mProjectPath.parent_path().string()).c_str());
|
||||
|
||||
for (std::vector<std::string>::const_iterator iter (mContentFiles.begin());
|
||||
iter!=mContentFiles.end(); ++iter)
|
||||
{
|
||||
arguments << QString::fromUtf8 (("--content="+*iter).c_str());
|
||||
}
|
||||
|
||||
arguments
|
||||
<< QString::fromUtf8 (("--content="+mProjectPath.filename().string()).c_str());
|
||||
|
||||
mProcess.start (path, arguments);
|
||||
}
|
||||
|
||||
mRunning = true;
|
||||
emit runStateChanged();
|
||||
}
|
||||
|
||||
void CSMDoc::Runner::stop()
|
||||
{
|
||||
delete mStartup;
|
||||
mStartup = 0;
|
||||
|
||||
if (mProcess.state()==QProcess::NotRunning)
|
||||
{
|
||||
mRunning = false;
|
||||
emit runStateChanged();
|
||||
}
|
||||
else
|
||||
mProcess.kill();
|
||||
}
|
||||
|
||||
bool CSMDoc::Runner::isRunning() const
|
||||
{
|
||||
return mRunning;
|
||||
}
|
||||
|
||||
void CSMDoc::Runner::configure (const ESM::DebugProfile& profile,
|
||||
const std::vector<std::string>& contentFiles, const std::string& startupInstruction)
|
||||
{
|
||||
mProfile = profile;
|
||||
mContentFiles = contentFiles;
|
||||
mStartupInstruction = startupInstruction;
|
||||
}
|
||||
|
||||
void CSMDoc::Runner::finished (int exitCode, QProcess::ExitStatus exitStatus)
|
||||
{
|
||||
mRunning = false;
|
||||
emit runStateChanged();
|
||||
}
|
||||
|
||||
QTextDocument *CSMDoc::Runner::getLog()
|
||||
{
|
||||
return &mLog;
|
||||
}
|
||||
|
||||
void CSMDoc::Runner::readyReadStandardOutput()
|
||||
{
|
||||
mLog.setPlainText (
|
||||
mLog.toPlainText() + QString::fromUtf8 (mProcess.readAllStandardOutput()));
|
||||
}
|
||||
|
||||
|
||||
CSMDoc::SaveWatcher::SaveWatcher (Runner *runner, Operation *operation)
|
||||
: QObject (runner), mRunner (runner)
|
||||
{
|
||||
connect (operation, SIGNAL (done (int, bool)), this, SLOT (saveDone (int, bool)));
|
||||
}
|
||||
|
||||
void CSMDoc::SaveWatcher::saveDone (int type, bool failed)
|
||||
{
|
||||
if (failed)
|
||||
mRunner->stop();
|
||||
else
|
||||
mRunner->start();
|
||||
|
||||
deleteLater();
|
||||
}
|
85
apps/opencs/model/doc/runner.hpp
Normal file
85
apps/opencs/model/doc/runner.hpp
Normal file
|
@ -0,0 +1,85 @@
|
|||
#ifndef CSM_DOC_RUNNER_H
|
||||
#define CSM_DOC_RUNNER_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
#include <QObject>
|
||||
#include <QProcess>
|
||||
#include <QTextDocument>
|
||||
|
||||
#include <components/esm/debugprofile.hpp>
|
||||
|
||||
class QTemporaryFile;
|
||||
|
||||
namespace CSMDoc
|
||||
{
|
||||
class Runner : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
QProcess mProcess;
|
||||
bool mRunning;
|
||||
ESM::DebugProfile mProfile;
|
||||
std::vector<std::string> mContentFiles;
|
||||
std::string mStartupInstruction;
|
||||
QTemporaryFile *mStartup;
|
||||
QTextDocument mLog;
|
||||
boost::filesystem::path mProjectPath;
|
||||
|
||||
public:
|
||||
|
||||
Runner (const boost::filesystem::path& projectPath);
|
||||
|
||||
~Runner();
|
||||
|
||||
/// \param delayed Flag as running but do not start the OpenMW process yet (the
|
||||
/// process must be started by another call of start with delayed==false)
|
||||
void start (bool delayed = false);
|
||||
|
||||
void stop();
|
||||
|
||||
/// \note Running state is entered when the start function is called. This
|
||||
/// is not necessarily identical to the moment the child process is started.
|
||||
bool isRunning() const;
|
||||
|
||||
void configure (const ESM::DebugProfile& profile,
|
||||
const std::vector<std::string>& contentFiles,
|
||||
const std::string& startupInstruction);
|
||||
|
||||
QTextDocument *getLog();
|
||||
|
||||
signals:
|
||||
|
||||
void runStateChanged();
|
||||
|
||||
private slots:
|
||||
|
||||
void finished (int exitCode, QProcess::ExitStatus exitStatus);
|
||||
|
||||
void readyReadStandardOutput();
|
||||
};
|
||||
|
||||
class Operation;
|
||||
|
||||
/// \brief Watch for end of save operation and restart or stop runner
|
||||
class SaveWatcher : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Runner *mRunner;
|
||||
|
||||
public:
|
||||
|
||||
/// *this attaches itself to runner
|
||||
SaveWatcher (Runner *runner, Operation *operation);
|
||||
|
||||
private slots:
|
||||
|
||||
void saveDone (int type, bool failed);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -17,7 +17,14 @@ CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& proje
|
|||
|
||||
appendStage (new WriteHeaderStage (mDocument, mState, true));
|
||||
|
||||
appendStage (new WriteFilterStage (mDocument, mState, CSMFilter::Filter::Scope_Project));
|
||||
appendStage (new WriteCollectionStage<CSMWorld::IdCollection<ESM::Filter> > (
|
||||
mDocument.getData().getFilters(), mState, CSMWorld::Scope_Project));
|
||||
|
||||
appendStage (new WriteCollectionStage<CSMWorld::IdCollection<ESM::DebugProfile> > (
|
||||
mDocument.getData().getDebugProfiles(), mState, CSMWorld::Scope_Project));
|
||||
|
||||
appendStage (new WriteCollectionStage<CSMWorld::IdCollection<ESM::Script> > (
|
||||
mDocument.getData().getScripts(), mState, CSMWorld::Scope_Project));
|
||||
|
||||
appendStage (new CloseSaveStage (mState));
|
||||
|
||||
|
@ -59,13 +66,31 @@ CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& proje
|
|||
appendStage (new WriteCollectionStage<CSMWorld::IdCollection<ESM::Spell> >
|
||||
(mDocument.getData().getSpells(), mState));
|
||||
|
||||
appendStage (new WriteCollectionStage<CSMWorld::IdCollection<ESM::Enchantment> >
|
||||
(mDocument.getData().getEnchantments(), mState));
|
||||
|
||||
appendStage (new WriteCollectionStage<CSMWorld::IdCollection<ESM::BodyPart> >
|
||||
(mDocument.getData().getBodyParts(), mState));
|
||||
|
||||
appendStage (new WriteCollectionStage<CSMWorld::IdCollection<ESM::SoundGenerator> >
|
||||
(mDocument.getData().getSoundGens(), mState));
|
||||
|
||||
appendStage (new WriteCollectionStage<CSMWorld::IdCollection<ESM::MagicEffect> >
|
||||
(mDocument.getData().getMagicEffects(), mState));
|
||||
|
||||
appendStage (new WriteDialogueCollectionStage (mDocument, mState, false));
|
||||
|
||||
appendStage (new WriteDialogueCollectionStage (mDocument, mState, true));
|
||||
|
||||
appendStage (new WriteRefIdCollectionStage (mDocument, mState));
|
||||
|
||||
appendStage (new CollectionReferencesStage (mDocument, mState));
|
||||
|
||||
appendStage (new WriteCellCollectionStage (mDocument, mState));
|
||||
|
||||
appendStage (new WritePathgridCollectionStage (mDocument, mState));
|
||||
|
||||
// close file and clean up
|
||||
appendStage (new CloseSaveStage (mState));
|
||||
|
||||
appendStage (new FinalSavingStage (mDocument, mState));
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#include <components/esm/loaddial.hpp>
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
#include "../world/infocollection.hpp"
|
||||
|
||||
#include "document.hpp"
|
||||
|
@ -199,20 +201,155 @@ void CSMDoc::WriteRefIdCollectionStage::perform (int stage, Messages& messages)
|
|||
}
|
||||
|
||||
|
||||
CSMDoc::WriteFilterStage::WriteFilterStage (Document& document, SavingState& state,
|
||||
CSMFilter::Filter::Scope scope)
|
||||
: WriteCollectionStage<CSMWorld::IdCollection<CSMFilter::Filter> > (document.getData().getFilters(),
|
||||
state),
|
||||
mDocument (document), mScope (scope)
|
||||
CSMDoc::CollectionReferencesStage::CollectionReferencesStage (Document& document,
|
||||
SavingState& state)
|
||||
: mDocument (document), mState (state)
|
||||
{}
|
||||
|
||||
void CSMDoc::WriteFilterStage::perform (int stage, Messages& messages)
|
||||
int CSMDoc::CollectionReferencesStage::setup()
|
||||
{
|
||||
const CSMWorld::Record<CSMFilter::Filter>& record =
|
||||
mDocument.getData().getFilters().getRecord (stage);
|
||||
mState.getSubRecords().clear();
|
||||
|
||||
if (record.get().mScope==mScope)
|
||||
WriteCollectionStage<CSMWorld::IdCollection<CSMFilter::Filter> >::perform (stage, messages);
|
||||
int size = mDocument.getData().getReferences().getSize();
|
||||
|
||||
int steps = size/100;
|
||||
if (size%100) ++steps;
|
||||
|
||||
return steps;
|
||||
}
|
||||
|
||||
void CSMDoc::CollectionReferencesStage::perform (int stage, Messages& messages)
|
||||
{
|
||||
int size = mDocument.getData().getReferences().getSize();
|
||||
|
||||
for (int i=stage*100; i<stage*100+100 && i<size; ++i)
|
||||
{
|
||||
const CSMWorld::Record<CSMWorld::CellRef>& record =
|
||||
mDocument.getData().getReferences().getRecord (i);
|
||||
|
||||
if (record.mState==CSMWorld::RecordBase::State_Deleted ||
|
||||
record.mState==CSMWorld::RecordBase::State_Modified ||
|
||||
record.mState==CSMWorld::RecordBase::State_ModifiedOnly)
|
||||
{
|
||||
mState.getSubRecords()[Misc::StringUtils::lowerCase (record.get().mCell)]
|
||||
.push_back (i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CSMDoc::WriteCellCollectionStage::WriteCellCollectionStage (Document& document,
|
||||
SavingState& state)
|
||||
: mDocument (document), mState (state)
|
||||
{}
|
||||
|
||||
int CSMDoc::WriteCellCollectionStage::setup()
|
||||
{
|
||||
return mDocument.getData().getCells().getSize();
|
||||
}
|
||||
|
||||
void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages)
|
||||
{
|
||||
const CSMWorld::Record<CSMWorld::Cell>& cell =
|
||||
mDocument.getData().getCells().getRecord (stage);
|
||||
|
||||
std::map<std::string, std::vector<int> >::const_iterator references =
|
||||
mState.getSubRecords().find (Misc::StringUtils::lowerCase (cell.get().mId));
|
||||
|
||||
if (cell.mState==CSMWorld::RecordBase::State_Modified ||
|
||||
cell.mState==CSMWorld::RecordBase::State_ModifiedOnly ||
|
||||
references!=mState.getSubRecords().end())
|
||||
{
|
||||
bool interior = cell.get().mId.substr (0, 1)!="#";
|
||||
|
||||
// write cell data
|
||||
mState.getWriter().startRecord (cell.mModified.sRecordId);
|
||||
|
||||
mState.getWriter().writeHNOCString ("NAME", cell.get().mName);
|
||||
|
||||
ESM::Cell cell2 = cell.get();
|
||||
|
||||
if (interior)
|
||||
cell2.mData.mFlags |= ESM::Cell::Interior;
|
||||
else
|
||||
{
|
||||
cell2.mData.mFlags &= ~ESM::Cell::Interior;
|
||||
|
||||
std::istringstream stream (cell.get().mId.c_str());
|
||||
char ignore;
|
||||
stream >> ignore >> cell2.mData.mX >> cell2.mData.mY;
|
||||
}
|
||||
cell2.save (mState.getWriter());
|
||||
|
||||
// write references
|
||||
if (references!=mState.getSubRecords().end())
|
||||
{
|
||||
for (std::vector<int>::const_iterator iter (references->second.begin());
|
||||
iter!=references->second.end(); ++iter)
|
||||
{
|
||||
const CSMWorld::Record<CSMWorld::CellRef>& ref =
|
||||
mDocument.getData().getReferences().getRecord (*iter);
|
||||
|
||||
if (ref.mState==CSMWorld::RecordBase::State_Modified ||
|
||||
ref.mState==CSMWorld::RecordBase::State_ModifiedOnly)
|
||||
{
|
||||
ref.get().save (mState.getWriter());
|
||||
}
|
||||
else if (ref.mState==CSMWorld::RecordBase::State_Deleted)
|
||||
{
|
||||
/// \todo write record with delete flag
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mState.getWriter().endRecord (cell.mModified.sRecordId);
|
||||
}
|
||||
else if (cell.mState==CSMWorld::RecordBase::State_Deleted)
|
||||
{
|
||||
/// \todo write record with delete flag
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CSMDoc::WritePathgridCollectionStage::WritePathgridCollectionStage (Document& document,
|
||||
SavingState& state)
|
||||
: mDocument (document), mState (state)
|
||||
{}
|
||||
|
||||
int CSMDoc::WritePathgridCollectionStage::setup()
|
||||
{
|
||||
return mDocument.getData().getPathgrids().getSize();
|
||||
}
|
||||
|
||||
void CSMDoc::WritePathgridCollectionStage::perform (int stage, Messages& messages)
|
||||
{
|
||||
const CSMWorld::Record<CSMWorld::Pathgrid>& pathgrid =
|
||||
mDocument.getData().getPathgrids().getRecord (stage);
|
||||
|
||||
if (pathgrid.mState==CSMWorld::RecordBase::State_Modified ||
|
||||
pathgrid.mState==CSMWorld::RecordBase::State_ModifiedOnly)
|
||||
{
|
||||
CSMWorld::Pathgrid record = pathgrid.get();
|
||||
|
||||
if (record.mId.substr (0, 1)=="#")
|
||||
{
|
||||
std::istringstream stream (record.mId.c_str());
|
||||
char ignore;
|
||||
stream >> ignore >> record.mData.mX >> record.mData.mY;
|
||||
}
|
||||
else
|
||||
record.mCell = record.mId;
|
||||
|
||||
mState.getWriter().startRecord (record.sRecordId);
|
||||
|
||||
record.save (mState.getWriter());
|
||||
|
||||
mState.getWriter().endRecord (record.sRecordId);
|
||||
}
|
||||
else if (pathgrid.mState==CSMWorld::RecordBase::State_Deleted)
|
||||
{
|
||||
/// \todo write record with delete flag
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
|
||||
#include "../world/record.hpp"
|
||||
#include "../world/idcollection.hpp"
|
||||
|
||||
#include "../filter/filter.hpp"
|
||||
#include "../world/scope.hpp"
|
||||
|
||||
#include "savingstate.hpp"
|
||||
|
||||
|
@ -67,10 +66,12 @@ namespace CSMDoc
|
|||
{
|
||||
const CollectionT& mCollection;
|
||||
SavingState& mState;
|
||||
CSMWorld::Scope mScope;
|
||||
|
||||
public:
|
||||
|
||||
WriteCollectionStage (const CollectionT& collection, SavingState& state);
|
||||
WriteCollectionStage (const CollectionT& collection, SavingState& state,
|
||||
CSMWorld::Scope scope = CSMWorld::Scope_Content);
|
||||
|
||||
virtual int setup();
|
||||
///< \return number of steps
|
||||
|
@ -81,8 +82,8 @@ namespace CSMDoc
|
|||
|
||||
template<class CollectionT>
|
||||
WriteCollectionStage<CollectionT>::WriteCollectionStage (const CollectionT& collection,
|
||||
SavingState& state)
|
||||
: mCollection (collection), mState (state)
|
||||
SavingState& state, CSMWorld::Scope scope)
|
||||
: mCollection (collection), mState (state), mScope (scope)
|
||||
{}
|
||||
|
||||
template<class CollectionT>
|
||||
|
@ -94,16 +95,14 @@ namespace CSMDoc
|
|||
template<class CollectionT>
|
||||
void WriteCollectionStage<CollectionT>::perform (int stage, Messages& messages)
|
||||
{
|
||||
if (CSMWorld::getScopeFromId (mCollection.getRecord (stage).get().mId)!=mScope)
|
||||
return;
|
||||
|
||||
CSMWorld::RecordBase::State state = mCollection.getRecord (stage).mState;
|
||||
|
||||
if (state==CSMWorld::RecordBase::State_Modified ||
|
||||
state==CSMWorld::RecordBase::State_ModifiedOnly)
|
||||
{
|
||||
std::string type;
|
||||
for (int i=0; i<4; ++i)
|
||||
/// \todo make endianess agnostic (change ESMWriter interface?)
|
||||
type += reinterpret_cast<const char *> (&mCollection.getRecord (stage).mModified.sRecordId)[i];
|
||||
|
||||
mState.getWriter().startRecord (mCollection.getRecord (stage).mModified.sRecordId);
|
||||
mState.getWriter().writeHNCString ("NAME", mCollection.getId (stage));
|
||||
mCollection.getRecord (stage).mModified.save (mState.getWriter());
|
||||
|
@ -152,19 +151,54 @@ namespace CSMDoc
|
|||
};
|
||||
|
||||
|
||||
class WriteFilterStage : public WriteCollectionStage<CSMWorld::IdCollection<CSMFilter::Filter> >
|
||||
class CollectionReferencesStage : public Stage
|
||||
{
|
||||
Document& mDocument;
|
||||
CSMFilter::Filter::Scope mScope;
|
||||
SavingState& mState;
|
||||
|
||||
public:
|
||||
|
||||
WriteFilterStage (Document& document, SavingState& state, CSMFilter::Filter::Scope scope);
|
||||
CollectionReferencesStage (Document& document, SavingState& state);
|
||||
|
||||
virtual int setup();
|
||||
///< \return number of steps
|
||||
|
||||
virtual void perform (int stage, Messages& messages);
|
||||
///< Messages resulting from this stage will be appended to \a messages.
|
||||
};
|
||||
|
||||
class WriteCellCollectionStage : public Stage
|
||||
{
|
||||
Document& mDocument;
|
||||
SavingState& mState;
|
||||
|
||||
public:
|
||||
|
||||
WriteCellCollectionStage (Document& document, SavingState& state);
|
||||
|
||||
virtual int setup();
|
||||
///< \return number of steps
|
||||
|
||||
virtual void perform (int stage, Messages& messages);
|
||||
///< Messages resulting from this stage will be appended to \a messages.
|
||||
};
|
||||
|
||||
|
||||
class WritePathgridCollectionStage : public Stage
|
||||
{
|
||||
Document& mDocument;
|
||||
SavingState& mState;
|
||||
|
||||
public:
|
||||
|
||||
WritePathgridCollectionStage (Document& document, SavingState& state);
|
||||
|
||||
virtual int setup();
|
||||
///< \return number of steps
|
||||
|
||||
virtual void perform (int stage, Messages& messages);
|
||||
///< Messages resulting from this stage will be appended to \a messages.
|
||||
};
|
||||
|
||||
class CloseSaveStage : public Stage
|
||||
{
|
||||
|
|
|
@ -25,6 +25,8 @@ void CSMDoc::SavingState::start (Document& document, bool project)
|
|||
|
||||
mStream.clear();
|
||||
|
||||
mSubRecords.clear();
|
||||
|
||||
if (project)
|
||||
mPath = mProjectPath;
|
||||
else
|
||||
|
@ -61,3 +63,8 @@ bool CSMDoc::SavingState::isProjectFile() const
|
|||
{
|
||||
return mProjectFile;
|
||||
}
|
||||
|
||||
std::map<std::string, std::vector<int> >& CSMDoc::SavingState::getSubRecords()
|
||||
{
|
||||
return mSubRecords;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define CSM_DOC_SAVINGSTATE_H
|
||||
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
|
@ -25,6 +26,7 @@ namespace CSMDoc
|
|||
ESM::ESMWriter mWriter;
|
||||
boost::filesystem::path mProjectPath;
|
||||
bool mProjectFile;
|
||||
std::map<std::string, std::vector<int> > mSubRecords; // record ID, list of subrecords
|
||||
|
||||
public:
|
||||
|
||||
|
@ -46,6 +48,8 @@ namespace CSMDoc
|
|||
|
||||
bool isProjectFile() const;
|
||||
///< Currently saving project file? (instead of content file)
|
||||
|
||||
std::map<std::string, std::vector<int> >& getSubRecords();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -8,12 +8,13 @@ namespace CSMDoc
|
|||
State_Modified = 1,
|
||||
State_Locked = 2,
|
||||
State_Operation = 4,
|
||||
State_Running = 8,
|
||||
|
||||
State_Saving = 8,
|
||||
State_Verifying = 16,
|
||||
State_Compiling = 32, // not implemented yet
|
||||
State_Searching = 64, // not implemented yet
|
||||
State_Loading = 128 // pseudo-state; can not be encountered in a loaded document
|
||||
State_Saving = 16,
|
||||
State_Verifying = 32,
|
||||
State_Compiling = 64, // not implemented yet
|
||||
State_Searching = 128, // not implemented yet
|
||||
State_Loading = 256 // pseudo-state; can not be encountered in a loaded document
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ CSMFilter::AndNode::AndNode (const std::vector<boost::shared_ptr<Node> >& nodes)
|
|||
: NAryNode (nodes, "and")
|
||||
{}
|
||||
|
||||
bool CSMFilter::AndNode::test (const CSMWorld::IdTable& table, int row,
|
||||
bool CSMFilter::AndNode::test (const CSMWorld::IdTableBase& table, int row,
|
||||
const std::map<int, int>& columns) const
|
||||
{
|
||||
int size = getSize();
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace CSMFilter
|
|||
|
||||
AndNode (const std::vector<boost::shared_ptr<Node> >& nodes);
|
||||
|
||||
virtual bool test (const CSMWorld::IdTable& table, int row,
|
||||
virtual bool test (const CSMWorld::IdTableBase& table, int row,
|
||||
const std::map<int, int>& columns) const;
|
||||
///< \return Can the specified table row pass through to filter?
|
||||
/// \param columns column ID to column index mapping
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
CSMFilter::BooleanNode::BooleanNode (bool true_) : mTrue (true_) {}
|
||||
|
||||
bool CSMFilter::BooleanNode::test (const CSMWorld::IdTable& table, int row,
|
||||
bool CSMFilter::BooleanNode::test (const CSMWorld::IdTableBase& table, int row,
|
||||
const std::map<int, int>& columns) const
|
||||
{
|
||||
return mTrue;
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace CSMFilter
|
|||
|
||||
BooleanNode (bool true_);
|
||||
|
||||
virtual bool test (const CSMWorld::IdTable& table, int row,
|
||||
virtual bool test (const CSMWorld::IdTableBase& table, int row,
|
||||
const std::map<int, int>& columns) const;
|
||||
///< \return Can the specified table row pass through to filter?
|
||||
/// \param columns column ID to column index mapping
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
#ifndef CSM_FILTER_FILTER_H
|
||||
#define CSM_FILTER_FILTER_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <components/esm/filter.hpp>
|
||||
|
||||
namespace CSMFilter
|
||||
{
|
||||
/// \brief Wrapper for Filter record
|
||||
struct Filter : public ESM::Filter
|
||||
{
|
||||
enum Scope
|
||||
{
|
||||
Scope_Project = 0, // per project
|
||||
Scope_Session = 1, // exists only for one editing session; not saved
|
||||
Scope_Content = 2 // embedded in the edited content file
|
||||
};
|
||||
|
||||
Scope mScope;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class IdTable;
|
||||
class IdTableBase;
|
||||
}
|
||||
|
||||
namespace CSMFilter
|
||||
|
@ -32,7 +32,7 @@ namespace CSMFilter
|
|||
|
||||
virtual ~Node();
|
||||
|
||||
virtual bool test (const CSMWorld::IdTable& table, int row,
|
||||
virtual bool test (const CSMWorld::IdTableBase& table, int row,
|
||||
const std::map<int, int>& columns) const = 0;
|
||||
///< \return Can the specified table row pass through to filter?
|
||||
/// \param columns column ID to column index mapping
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
CSMFilter::NotNode::NotNode (boost::shared_ptr<Node> child) : UnaryNode (child, "not") {}
|
||||
|
||||
bool CSMFilter::NotNode::test (const CSMWorld::IdTable& table, int row,
|
||||
bool CSMFilter::NotNode::test (const CSMWorld::IdTableBase& table, int row,
|
||||
const std::map<int, int>& columns) const
|
||||
{
|
||||
return !getChild().test (table, row, columns);
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace CSMFilter
|
|||
|
||||
NotNode (boost::shared_ptr<Node> child);
|
||||
|
||||
virtual bool test (const CSMWorld::IdTable& table, int row,
|
||||
virtual bool test (const CSMWorld::IdTableBase& table, int row,
|
||||
const std::map<int, int>& columns) const;
|
||||
///< \return Can the specified table row pass through to filter?
|
||||
/// \param columns column ID to column index mapping
|
||||
|
|
|
@ -7,7 +7,7 @@ CSMFilter::OrNode::OrNode (const std::vector<boost::shared_ptr<Node> >& nodes)
|
|||
: NAryNode (nodes, "or")
|
||||
{}
|
||||
|
||||
bool CSMFilter::OrNode::test (const CSMWorld::IdTable& table, int row,
|
||||
bool CSMFilter::OrNode::test (const CSMWorld::IdTableBase& table, int row,
|
||||
const std::map<int, int>& columns) const
|
||||
{
|
||||
int size = getSize();
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace CSMFilter
|
|||
|
||||
OrNode (const std::vector<boost::shared_ptr<Node> >& nodes);
|
||||
|
||||
virtual bool test (const CSMWorld::IdTable& table, int row,
|
||||
virtual bool test (const CSMWorld::IdTableBase& table, int row,
|
||||
const std::map<int, int>& columns) const;
|
||||
///< \return Can the specified table row pass through to filter?
|
||||
/// \param columns column ID to column index mapping
|
||||
|
|
|
@ -550,7 +550,12 @@ bool CSMFilter::Parser::parse (const std::string& filter, bool allowPredefined)
|
|||
if (allowPredefined)
|
||||
token = getNextToken();
|
||||
|
||||
if (!allowPredefined || token==Token (Token::Type_OneShot))
|
||||
if (allowPredefined && token==Token (Token::Type_EOS))
|
||||
{
|
||||
mFilter.reset();
|
||||
return true;
|
||||
}
|
||||
else if (!allowPredefined || token==Token (Token::Type_OneShot))
|
||||
{
|
||||
boost::shared_ptr<Node> node = parseImp (true, token!=Token (Token::Type_OneShot));
|
||||
|
||||
|
@ -591,7 +596,7 @@ bool CSMFilter::Parser::parse (const std::string& filter, bool allowPredefined)
|
|||
return false;
|
||||
}
|
||||
|
||||
const CSMWorld::Record<CSMFilter::Filter>& record = mData.getFilters().getRecord (index);
|
||||
const CSMWorld::Record<ESM::Filter>& record = mData.getFilters().getRecord (index);
|
||||
|
||||
if (record.isDeleted())
|
||||
{
|
||||
|
|
|
@ -7,13 +7,13 @@
|
|||
#include <QRegExp>
|
||||
|
||||
#include "../world/columns.hpp"
|
||||
#include "../world/idtable.hpp"
|
||||
#include "../world/idtablebase.hpp"
|
||||
|
||||
CSMFilter::TextNode::TextNode (int columnId, const std::string& text)
|
||||
: mColumnId (columnId), mText (text)
|
||||
{}
|
||||
|
||||
bool CSMFilter::TextNode::test (const CSMWorld::IdTable& table, int row,
|
||||
bool CSMFilter::TextNode::test (const CSMWorld::IdTableBase& table, int row,
|
||||
const std::map<int, int>& columns) const
|
||||
{
|
||||
const std::map<int, int>::const_iterator iter = columns.find (mColumnId);
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace CSMFilter
|
|||
|
||||
TextNode (int columnId, const std::string& text);
|
||||
|
||||
virtual bool test (const CSMWorld::IdTable& table, int row,
|
||||
virtual bool test (const CSMWorld::IdTableBase& table, int row,
|
||||
const std::map<int, int>& columns) const;
|
||||
///< \return Can the specified table row pass through to filter?
|
||||
/// \param columns column ID to column index mapping
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
#include <stdexcept>
|
||||
|
||||
#include "../world/columns.hpp"
|
||||
#include "../world/idtable.hpp"
|
||||
#include "../world/idtablebase.hpp"
|
||||
|
||||
CSMFilter::ValueNode::ValueNode (int columnId, Type lowerType, Type upperType,
|
||||
double lower, double upper)
|
||||
: mColumnId (columnId), mLowerType (lowerType), mUpperType (upperType), mLower (lower), mUpper (upper){}
|
||||
|
||||
bool CSMFilter::ValueNode::test (const CSMWorld::IdTable& table, int row,
|
||||
bool CSMFilter::ValueNode::test (const CSMWorld::IdTableBase& table, int row,
|
||||
const std::map<int, int>& columns) const
|
||||
{
|
||||
const std::map<int, int>::const_iterator iter = columns.find (mColumnId);
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace CSMFilter
|
|||
|
||||
ValueNode (int columnId, Type lowerType, Type upperType, double lower, double upper);
|
||||
|
||||
virtual bool test (const CSMWorld::IdTable& table, int row,
|
||||
virtual bool test (const CSMWorld::IdTableBase& table, int row,
|
||||
const std::map<int, int>& columns) const;
|
||||
///< \return Can the specified table row pass through to filter?
|
||||
/// \param columns column ID to column index mapping
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
#include "support.hpp"
|
||||
|
||||
CSMSettings::Setting::Setting(SettingType typ, const QString &settingName,
|
||||
const QString &pageName)
|
||||
: mIsEditorSetting (false)
|
||||
const QString &pageName, const QString& label)
|
||||
: mIsEditorSetting (true)
|
||||
{
|
||||
buildDefaultSetting();
|
||||
|
||||
|
@ -17,6 +17,7 @@ CSMSettings::Setting::Setting(SettingType typ, const QString &settingName,
|
|||
setProperty (Property_SettingType, QVariant (settingType).toString());
|
||||
setProperty (Property_Page, pageName);
|
||||
setProperty (Property_Name, settingName);
|
||||
setProperty (Property_Label, label.isEmpty() ? settingName : label);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::buildDefaultSetting()
|
||||
|
@ -194,6 +195,16 @@ QString CSMSettings::Setting::page() const
|
|||
return property (Property_Page).at(0);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setStyleSheet (const QString &value)
|
||||
{
|
||||
setProperty (Property_StyleSheet, value);
|
||||
}
|
||||
|
||||
QString CSMSettings::Setting::styleSheet() const
|
||||
{
|
||||
return property (Property_StyleSheet).at(0);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setPrefix (const QString &value)
|
||||
{
|
||||
setProperty (Property_Prefix, value);
|
||||
|
@ -280,14 +291,16 @@ CSMSettings::SettingType CSMSettings::Setting::type() const
|
|||
Property_SettingType).at(0).toInt());
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setMaximum (int value)
|
||||
void CSMSettings::Setting::setRange (int min, int max)
|
||||
{
|
||||
setProperty (Property_Maximum, value);
|
||||
setProperty (Property_Minimum, min);
|
||||
setProperty (Property_Maximum, max);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setMaximum (double value)
|
||||
void CSMSettings::Setting::setRange (double min, double max)
|
||||
{
|
||||
setProperty (Property_Maximum, value);
|
||||
setProperty (Property_Minimum, min);
|
||||
setProperty (Property_Maximum, max);
|
||||
}
|
||||
|
||||
QString CSMSettings::Setting::maximum() const
|
||||
|
@ -295,16 +308,6 @@ QString CSMSettings::Setting::maximum() const
|
|||
return property (Property_Maximum).at(0);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setMinimum (int value)
|
||||
{
|
||||
setProperty (Property_Minimum, value);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setMinimum (double value)
|
||||
{
|
||||
setProperty (Property_Minimum, value);
|
||||
}
|
||||
|
||||
QString CSMSettings::Setting::minimum() const
|
||||
{
|
||||
return property (Property_Minimum).at(0);
|
||||
|
@ -362,6 +365,26 @@ bool CSMSettings::Setting::wrapping() const
|
|||
return (property (Property_Wrapping).at(0) == "true");
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setLabel (const QString& label)
|
||||
{
|
||||
setProperty (Property_Label, label);
|
||||
}
|
||||
|
||||
QString CSMSettings::Setting::getLabel() const
|
||||
{
|
||||
return property (Property_Label).at (0);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setToolTip (const QString& toolTip)
|
||||
{
|
||||
setProperty (Property_ToolTip, toolTip);
|
||||
}
|
||||
|
||||
QString CSMSettings::Setting::getToolTip() const
|
||||
{
|
||||
return property (Property_ToolTip).at (0);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setProperty (SettingProperty prop, bool value)
|
||||
{
|
||||
setProperty (prop, QStringList() << QVariant (value).toString());
|
||||
|
|
|
@ -29,8 +29,8 @@ namespace CSMSettings
|
|||
|
||||
public:
|
||||
|
||||
explicit Setting(SettingType typ, const QString &settingName,
|
||||
const QString &pageName);
|
||||
Setting(SettingType typ, const QString &settingName,
|
||||
const QString &pageName, const QString& label = "");
|
||||
|
||||
void addProxy (const Setting *setting, const QStringList &vals);
|
||||
void addProxy (const Setting *setting, const QList <QStringList> &list);
|
||||
|
@ -66,12 +66,11 @@ namespace CSMSettings
|
|||
void setMask (const QString &value);
|
||||
QString mask() const;
|
||||
|
||||
void setMaximum (int value);
|
||||
void setMaximum (double value);
|
||||
void setRange (int min, int max);
|
||||
void setRange (double min, double max);
|
||||
|
||||
QString maximum() const;
|
||||
|
||||
void setMinimum (int value);
|
||||
void setMinimum (double value);
|
||||
QString minimum() const;
|
||||
|
||||
void setName (const QString &value);
|
||||
|
@ -80,6 +79,9 @@ namespace CSMSettings
|
|||
void setPage (const QString &value);
|
||||
QString page() const;
|
||||
|
||||
void setStyleSheet (const QString &value);
|
||||
QString styleSheet() const;
|
||||
|
||||
void setPrefix (const QString &value);
|
||||
QString prefix() const;
|
||||
|
||||
|
@ -129,6 +131,13 @@ namespace CSMSettings
|
|||
void setWidgetWidth (int value);
|
||||
int widgetWidth() const;
|
||||
|
||||
/// This is the text the user gets to see.
|
||||
void setLabel (const QString& label);
|
||||
QString getLabel() const;
|
||||
|
||||
void setToolTip (const QString& toolTip);
|
||||
QString getToolTip() const;
|
||||
|
||||
///returns the specified property value
|
||||
QStringList property (SettingProperty prop) const;
|
||||
|
||||
|
|
|
@ -35,12 +35,15 @@ namespace CSMSettings
|
|||
Property_TickInterval = 19,
|
||||
Property_TicksAbove = 20,
|
||||
Property_TicksBelow = 21,
|
||||
Property_StyleSheet = 22,
|
||||
Property_Label = 23,
|
||||
Property_ToolTip = 24,
|
||||
|
||||
//Stringlists should always be the last items
|
||||
Property_DefaultValues = 22,
|
||||
Property_DeclaredValues = 23,
|
||||
Property_DefinedValues = 24,
|
||||
Property_Proxies = 25
|
||||
Property_DefaultValues = 25,
|
||||
Property_DeclaredValues = 26,
|
||||
Property_DefinedValues = 27,
|
||||
Property_Proxies = 28
|
||||
};
|
||||
|
||||
///Basic setting widget types.
|
||||
|
@ -106,7 +109,7 @@ namespace CSMSettings
|
|||
"is_multi_line", "widget_width", "view_row", "view_column", "delimiter",
|
||||
"is_serializable","column_span", "row_span", "minimum", "maximum",
|
||||
"special_value_text", "prefix", "suffix", "single_step", "wrapping",
|
||||
"tick_interval", "ticks_above", "ticks_below",
|
||||
"tick_interval", "ticks_above", "ticks_below", "stylesheet",
|
||||
"defaults", "declarations", "definitions", "proxies"
|
||||
};
|
||||
|
||||
|
@ -135,6 +138,7 @@ namespace CSMSettings
|
|||
"1", //tick interval
|
||||
"false", //ticks above
|
||||
"true", //ticks below
|
||||
"", //StyleSheet
|
||||
"", //default values
|
||||
"", //declared values
|
||||
"", //defined values
|
||||
|
|
|
@ -4,12 +4,16 @@
|
|||
#include <QFile>
|
||||
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
#include <components/settings/settings.hpp>
|
||||
#include <boost/version.hpp>
|
||||
|
||||
#include "setting.hpp"
|
||||
#include "support.hpp"
|
||||
#include <QTextCodec>
|
||||
#include <QDebug>
|
||||
|
||||
#include <extern/shiny/Main/Factory.hpp>
|
||||
|
||||
/**
|
||||
* Workaround for problems with whitespaces in paths in older versions of Boost library
|
||||
*/
|
||||
|
@ -26,81 +30,184 @@ namespace boost
|
|||
} /* namespace boost */
|
||||
#endif /* (BOOST_VERSION <= 104600) */
|
||||
|
||||
CSMSettings::UserSettings *CSMSettings::UserSettings::mUserSettingsInstance = 0;
|
||||
CSMSettings::UserSettings *CSMSettings::UserSettings::sUserSettingsInstance = 0;
|
||||
|
||||
CSMSettings::UserSettings::UserSettings (const Files::ConfigurationManager& configurationManager)
|
||||
: mCfgMgr (configurationManager)
|
||||
CSMSettings::UserSettings::UserSettings (const Files::ConfigurationManager& configurationManager)
|
||||
: mCfgMgr (configurationManager)
|
||||
, mSettingDefinitions(NULL)
|
||||
{
|
||||
assert(!mUserSettingsInstance);
|
||||
mUserSettingsInstance = this;
|
||||
|
||||
mSettingDefinitions = 0;
|
||||
assert(!sUserSettingsInstance);
|
||||
sUserSettingsInstance = this;
|
||||
|
||||
buildSettingModelDefaults();
|
||||
}
|
||||
|
||||
void CSMSettings::UserSettings::buildSettingModelDefaults()
|
||||
{
|
||||
QString section = "Window Size";
|
||||
QString section;
|
||||
|
||||
declareSection ("3d-render", "3D Rendering");
|
||||
{
|
||||
Setting *width = createSetting (Type_LineEdit, section, "Width");
|
||||
Setting *height = createSetting (Type_LineEdit, section, "Height");
|
||||
Setting *shaders = createSetting (Type_CheckBox, "shaders", "Enable Shaders");
|
||||
shaders->setDefaultValue ("true");
|
||||
|
||||
width->setWidgetWidth (5);
|
||||
height->setWidgetWidth (8);
|
||||
Setting *farClipDist = createSetting (Type_DoubleSpinBox, "far-clip-distance", "Far clipping distance");
|
||||
farClipDist->setDefaultValue (300000);
|
||||
farClipDist->setRange (0, 1000000);
|
||||
farClipDist->setToolTip ("The maximum distance objects are still rendered at.");
|
||||
|
||||
width->setDefaultValues (QStringList() << "1024");
|
||||
height->setDefaultValues (QStringList() << "768");
|
||||
|
||||
width->setEditorSetting (true);
|
||||
height->setEditorSetting (true);
|
||||
|
||||
height->setViewLocation (2,2);
|
||||
width->setViewLocation (2,1);
|
||||
|
||||
/*
|
||||
*Create the proxy setting for predefined values
|
||||
*/
|
||||
Setting *preDefined = createSetting (Type_ComboBox, section,
|
||||
"Pre-Defined");
|
||||
|
||||
preDefined->setDeclaredValues (QStringList() << "640 x 480"
|
||||
<< "800 x 600" << "1024 x 768" << "1440 x 900");
|
||||
|
||||
preDefined->setViewLocation (1, 1);
|
||||
preDefined->setWidgetWidth (10);
|
||||
preDefined->setColumnSpan (2);
|
||||
|
||||
preDefined->addProxy (width,
|
||||
QStringList() << "640" << "800" << "1024" << "1440"
|
||||
);
|
||||
|
||||
preDefined->addProxy (height,
|
||||
QStringList() << "480" << "600" << "768" << "900"
|
||||
);
|
||||
QString defaultValue = "None";
|
||||
Setting *antialiasing = createSetting (Type_ComboBox, "antialiasing", "Antialiasing");
|
||||
antialiasing->setDeclaredValues (QStringList()
|
||||
<< defaultValue << "MSAA 2" << "MSAA 4" << "MSAA 8" << "MSAA 16");
|
||||
antialiasing->setDefaultValue (defaultValue);
|
||||
}
|
||||
|
||||
section = "Display Format";
|
||||
declareSection ("3d-render-adv", "3D Rendering (Advanced)");
|
||||
{
|
||||
Setting *numLights = createSetting (Type_SpinBox, "num_lights",
|
||||
"Number of lights per pass");
|
||||
numLights->setDefaultValue (8);
|
||||
numLights->setRange (1, 100);
|
||||
}
|
||||
|
||||
declareSection ("scene-input", "Scene Input");
|
||||
{
|
||||
Setting *timer = createSetting (Type_SpinBox, "timer", "Input responsiveness");
|
||||
timer->setDefaultValue (20);
|
||||
timer->setRange (1, 100);
|
||||
timer->setToolTip ("The time between two checks for user input in milliseconds.<p>"
|
||||
"Lower value result in higher responsiveness.");
|
||||
|
||||
Setting *fastFactor = createSetting (Type_SpinBox, "fast-factor",
|
||||
"Fast movement factor");
|
||||
fastFactor->setDefaultValue (4);
|
||||
fastFactor->setRange (1, 100);
|
||||
fastFactor->setToolTip (
|
||||
"Factor by which movement is speed up while the shift key is held down.");
|
||||
}
|
||||
|
||||
declareSection ("window", "Window");
|
||||
{
|
||||
Setting *preDefined = createSetting (Type_ComboBox, "pre-defined",
|
||||
"Default window size");
|
||||
preDefined->setEditorSetting (false);
|
||||
preDefined->setDeclaredValues (
|
||||
QStringList() << "640 x 480" << "800 x 600" << "1024 x 768" << "1440 x 900");
|
||||
preDefined->setViewLocation (1, 1);
|
||||
preDefined->setColumnSpan (2);
|
||||
preDefined->setToolTip ("Newly opened top-level windows will open with this size "
|
||||
"(picked from a list of pre-defined values)");
|
||||
|
||||
Setting *width = createSetting (Type_LineEdit, "default-width",
|
||||
"Default window width");
|
||||
width->setDefaultValues (QStringList() << "1024");
|
||||
width->setViewLocation (2, 1);
|
||||
width->setColumnSpan (1);
|
||||
width->setToolTip ("Newly opened top-level windows will open with this width.");
|
||||
preDefined->addProxy (width, QStringList() << "640" << "800" << "1024" << "1440");
|
||||
|
||||
Setting *height = createSetting (Type_LineEdit, "default-height",
|
||||
"Default window height");
|
||||
height->setDefaultValues (QStringList() << "768");
|
||||
height->setViewLocation (2, 2);
|
||||
height->setColumnSpan (1);
|
||||
height->setToolTip ("Newly opened top-level windows will open with this height.");
|
||||
preDefined->addProxy (height, QStringList() << "480" << "600" << "768" << "900");
|
||||
|
||||
Setting *reuse = createSetting (Type_CheckBox, "reuse", "Reuse Subviews");
|
||||
reuse->setDefaultValue ("true");
|
||||
reuse->setToolTip ("When a new subview is requested and a matching subview already "
|
||||
" exist, do not open a new subview and use the existing one instead.");
|
||||
|
||||
Setting *statusBar = createSetting (Type_CheckBox, "show-statusbar", "Show Status Bar");
|
||||
statusBar->setDefaultValue ("true");
|
||||
statusBar->setToolTip ("If a newly open top level window is showing status bars or not. "
|
||||
" Note that this does not affect existing windows.");
|
||||
|
||||
Setting *maxSubView = createSetting (Type_SpinBox, "max-subviews",
|
||||
"Maximum number of subviews per top-level window");
|
||||
maxSubView->setDefaultValue (256);
|
||||
maxSubView->setRange (1, 256);
|
||||
maxSubView->setToolTip ("If the maximum number is reached and a new subview is opened "
|
||||
"it will be placed into a new top-level window.");
|
||||
|
||||
Setting *hide = createSetting (Type_CheckBox, "hide-subview", "Hide single subview");
|
||||
hide->setDefaultValue ("false");
|
||||
hide->setToolTip ("When a view contains only a single subview, hide the subview title "
|
||||
"bar and if this subview is closed also close the view (unless it is the last "
|
||||
"view for this document)");
|
||||
|
||||
Setting *minWidth = createSetting (Type_SpinBox, "minimum-width",
|
||||
"Minimum subview width");
|
||||
minWidth->setDefaultValue (325);
|
||||
minWidth->setRange (50, 10000);
|
||||
minWidth->setToolTip ("Minimum width of subviews.");
|
||||
}
|
||||
|
||||
declareSection ("records", "Records");
|
||||
{
|
||||
QString defaultValue = "Icon and Text";
|
||||
QStringList values = QStringList() << defaultValue << "Icon Only" << "Text Only";
|
||||
|
||||
QStringList values = QStringList()
|
||||
<< defaultValue << "Icon Only" << "Text Only";
|
||||
|
||||
Setting *rsd = createSetting (Type_RadioButton,
|
||||
section, "Record Status Display");
|
||||
|
||||
Setting *ritd = createSetting (Type_RadioButton,
|
||||
section, "Referenceable ID Type Display");
|
||||
|
||||
Setting *rsd = createSetting (Type_RadioButton, "status-format",
|
||||
"Modification status display format");
|
||||
rsd->setDefaultValue (defaultValue);
|
||||
rsd->setDeclaredValues (values);
|
||||
ritd->setDeclaredValues (values);
|
||||
|
||||
rsd->setEditorSetting (true);
|
||||
ritd->setEditorSetting (true);
|
||||
Setting *ritd = createSetting (Type_RadioButton, "type-format",
|
||||
"ID type display format");
|
||||
ritd->setDefaultValue (defaultValue);
|
||||
ritd->setDeclaredValues (values);
|
||||
}
|
||||
|
||||
declareSection ("table-input", "Table Input");
|
||||
{
|
||||
QString inPlaceEdit ("Edit in Place");
|
||||
QString editRecord ("Edit Record");
|
||||
QString view ("View");
|
||||
QString editRecordAndClose ("Edit Record and Close");
|
||||
|
||||
QStringList values;
|
||||
values
|
||||
<< "None" << inPlaceEdit << editRecord << view << "Revert" << "Delete"
|
||||
<< editRecordAndClose << "View and Close";
|
||||
|
||||
QString toolTip = "<ul>"
|
||||
"<li>None</li>"
|
||||
"<li>Edit in Place: Edit the clicked cell</li>"
|
||||
"<li>Edit Record: Open a dialogue subview for the clicked record</li>"
|
||||
"<li>View: Open a scene subview for the clicked record (not available everywhere)</li>"
|
||||
"<li>Revert: Revert record</li>"
|
||||
"<li>Delete: Delete recordy</li>"
|
||||
"<li>Edit Record and Close: Open a dialogue subview for the clicked record and close the table subview</li>"
|
||||
"<li>View And Close: Open a scene subview for the clicked record and close the table subview</li>"
|
||||
"</ul>";
|
||||
|
||||
Setting *doubleClick = createSetting (Type_ComboBox, "double", "Double Click");
|
||||
doubleClick->setDeclaredValues (values);
|
||||
doubleClick->setDefaultValue (inPlaceEdit);
|
||||
doubleClick->setToolTip ("Action on double click in table:<p>" + toolTip);
|
||||
|
||||
Setting *shiftDoubleClick = createSetting (Type_ComboBox, "double-s",
|
||||
"Shift Double Click");
|
||||
shiftDoubleClick->setDeclaredValues (values);
|
||||
shiftDoubleClick->setDefaultValue (editRecord);
|
||||
shiftDoubleClick->setToolTip ("Action on shift double click in table:<p>" + toolTip);
|
||||
|
||||
Setting *ctrlDoubleClick = createSetting (Type_ComboBox, "double-c",
|
||||
"Control Double Click");
|
||||
ctrlDoubleClick->setDeclaredValues (values);
|
||||
ctrlDoubleClick->setDefaultValue (view);
|
||||
ctrlDoubleClick->setToolTip ("Action on control double click in table:<p>" + toolTip);
|
||||
|
||||
Setting *shiftCtrlDoubleClick = createSetting (Type_ComboBox, "double-sc",
|
||||
"Shift Control Double Click");
|
||||
shiftCtrlDoubleClick->setDeclaredValues (values);
|
||||
shiftCtrlDoubleClick->setDefaultValue (editRecordAndClose);
|
||||
shiftCtrlDoubleClick->setToolTip ("Action on shift control double click in table:<p>" + toolTip);
|
||||
}
|
||||
|
||||
section = "Proxy Selection Test";
|
||||
{
|
||||
/******************************************************************
|
||||
* There are three types of values:
|
||||
|
@ -276,7 +383,7 @@ void CSMSettings::UserSettings::buildSettingModelDefaults()
|
|||
|
||||
CSMSettings::UserSettings::~UserSettings()
|
||||
{
|
||||
mUserSettingsInstance = 0;
|
||||
sUserSettingsInstance = 0;
|
||||
}
|
||||
|
||||
void CSMSettings::UserSettings::loadSettings (const QString &fileName)
|
||||
|
@ -307,8 +414,21 @@ void CSMSettings::UserSettings::loadSettings (const QString &fileName)
|
|||
(QSettings::IniFormat, QSettings::UserScope, "opencs", QString(), this);
|
||||
}
|
||||
|
||||
bool CSMSettings::UserSettings::hasSettingDefinitions
|
||||
(const QString &viewKey) const
|
||||
// if the key is not found create one with a default value
|
||||
QString CSMSettings::UserSettings::setting(const QString &viewKey, const QString &value)
|
||||
{
|
||||
if(mSettingDefinitions->contains(viewKey))
|
||||
return settingValue(viewKey);
|
||||
else if(value != QString())
|
||||
{
|
||||
mSettingDefinitions->setValue (viewKey, QStringList() << value);
|
||||
return value;
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
bool CSMSettings::UserSettings::hasSettingDefinitions (const QString &viewKey) const
|
||||
{
|
||||
return (mSettingDefinitions->contains (viewKey));
|
||||
}
|
||||
|
@ -326,10 +446,12 @@ void CSMSettings::UserSettings::saveDefinitions() const
|
|||
|
||||
QString CSMSettings::UserSettings::settingValue (const QString &settingKey)
|
||||
{
|
||||
QStringList defs;
|
||||
|
||||
if (!mSettingDefinitions->contains (settingKey))
|
||||
return QString();
|
||||
|
||||
QStringList defs = mSettingDefinitions->value (settingKey).toStringList();
|
||||
defs = mSettingDefinitions->value (settingKey).toStringList();
|
||||
|
||||
if (defs.isEmpty())
|
||||
return QString();
|
||||
|
@ -339,8 +461,8 @@ QString CSMSettings::UserSettings::settingValue (const QString &settingKey)
|
|||
|
||||
CSMSettings::UserSettings& CSMSettings::UserSettings::instance()
|
||||
{
|
||||
assert(mUserSettingsInstance);
|
||||
return *mUserSettingsInstance;
|
||||
assert(sUserSettingsInstance);
|
||||
return *sUserSettingsInstance;
|
||||
}
|
||||
|
||||
void CSMSettings::UserSettings::updateUserSetting(const QString &settingKey,
|
||||
|
@ -348,6 +470,15 @@ void CSMSettings::UserSettings::updateUserSetting(const QString &settingKey,
|
|||
{
|
||||
mSettingDefinitions->setValue (settingKey ,list);
|
||||
|
||||
if(settingKey == "3d-render-adv/num_lights" && !list.empty())
|
||||
{
|
||||
sh::Factory::getInstance ().setGlobalSetting ("num_lights", list.at(0).toStdString());
|
||||
}
|
||||
else if(settingKey == "3d-render/shaders" && !list.empty())
|
||||
{
|
||||
sh::Factory::getInstance ().setShadersEnabled (list.at(0).toStdString() == "true" ? true : false);
|
||||
}
|
||||
|
||||
emit userSettingUpdated (settingKey, list);
|
||||
}
|
||||
|
||||
|
@ -387,30 +518,62 @@ void CSMSettings::UserSettings::removeSetting
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
CSMSettings::SettingPageMap CSMSettings::UserSettings::settingPageMap() const
|
||||
{
|
||||
SettingPageMap pageMap;
|
||||
|
||||
foreach (Setting *setting, mSettings)
|
||||
pageMap[setting->page()].append (setting);
|
||||
{
|
||||
SettingPageMap::iterator iter = pageMap.find (setting->page());
|
||||
|
||||
if (iter==pageMap.end())
|
||||
{
|
||||
QPair<QString, QList <Setting *> > value;
|
||||
|
||||
std::map<QString, QString>::const_iterator iter2 =
|
||||
mSectionLabels.find (setting->page());
|
||||
|
||||
value.first = iter2!=mSectionLabels.end() ? iter2->second : "";
|
||||
|
||||
iter = pageMap.insert (setting->page(), value);
|
||||
}
|
||||
|
||||
iter->second.append (setting);
|
||||
}
|
||||
|
||||
return pageMap;
|
||||
}
|
||||
|
||||
CSMSettings::Setting *CSMSettings::UserSettings::createSetting
|
||||
(CSMSettings::SettingType typ, const QString &page, const QString &name)
|
||||
(CSMSettings::SettingType type, const QString &name, const QString& label)
|
||||
{
|
||||
//get list of all settings for the current setting name
|
||||
if (findSetting (page, name))
|
||||
{
|
||||
qWarning() << "Duplicate declaration encountered: "
|
||||
<< (name + '/' + page);
|
||||
return 0;
|
||||
}
|
||||
Setting *setting = new Setting (type, name, mSection, label);
|
||||
|
||||
Setting *setting = new Setting (typ, name, page);
|
||||
// set useful defaults
|
||||
int row = 1;
|
||||
|
||||
if (!mSettings.empty())
|
||||
row = mSettings.back()->viewRow()+1;
|
||||
|
||||
setting->setViewLocation (row, 1);
|
||||
|
||||
setting->setColumnSpan (3);
|
||||
|
||||
int width = 10;
|
||||
|
||||
if (type==Type_CheckBox)
|
||||
width = 40;
|
||||
|
||||
setting->setWidgetWidth (width);
|
||||
|
||||
if (type==Type_CheckBox)
|
||||
setting->setStyleSheet ("QGroupBox { border: 0px; }");
|
||||
|
||||
if (type==Type_CheckBox)
|
||||
setting->setDeclaredValues(QStringList() << "true" << "false");
|
||||
|
||||
if (type==Type_CheckBox)
|
||||
setting->setSpecialValueText (setting->getLabel());
|
||||
|
||||
//add declaration to the model
|
||||
mSettings.append (setting);
|
||||
|
@ -418,6 +581,12 @@ CSMSettings::Setting *CSMSettings::UserSettings::createSetting
|
|||
return setting;
|
||||
}
|
||||
|
||||
void CSMSettings::UserSettings::declareSection (const QString& page, const QString& label)
|
||||
{
|
||||
mSection = page;
|
||||
mSectionLabels[page] = label;
|
||||
}
|
||||
|
||||
QStringList CSMSettings::UserSettings::definitions (const QString &viewKey) const
|
||||
{
|
||||
if (mSettingDefinitions->contains (viewKey))
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
#ifndef USERSETTINGS_HPP
|
||||
#define USERSETTINGS_HPP
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <QList>
|
||||
#include <QStringList>
|
||||
#include <QString>
|
||||
#include <QMap>
|
||||
#include <QPair>
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include "support.hpp"
|
||||
|
@ -22,18 +25,20 @@ class QSettings;
|
|||
namespace CSMSettings {
|
||||
|
||||
class Setting;
|
||||
typedef QMap <QString, QList <Setting *> > SettingPageMap;
|
||||
typedef QMap <QString, QPair<QString, QList <Setting *> > > SettingPageMap;
|
||||
|
||||
class UserSettings: public QObject
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
static UserSettings *mUserSettingsInstance;
|
||||
static UserSettings *sUserSettingsInstance;
|
||||
const Files::ConfigurationManager& mCfgMgr;
|
||||
|
||||
QSettings *mSettingDefinitions;
|
||||
QList <Setting *> mSettings;
|
||||
QString mSection;
|
||||
std::map<QString, QString> mSectionLabels;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -62,7 +67,7 @@ namespace CSMSettings {
|
|||
void removeSetting
|
||||
(const QString &pageName, const QString &settingName);
|
||||
|
||||
///Retreive a map of the settings, keyed by page name
|
||||
///Retrieve a map of the settings, keyed by page name
|
||||
SettingPageMap settingPageMap() const;
|
||||
|
||||
///Returns a string list of defined vlaues for the specified setting
|
||||
|
@ -75,13 +80,20 @@ namespace CSMSettings {
|
|||
///Save any unsaved changes in the QSettings object
|
||||
void saveDefinitions() const;
|
||||
|
||||
QString setting(const QString &viewKey, const QString &value = QString());
|
||||
|
||||
private:
|
||||
|
||||
void buildSettingModelDefaults();
|
||||
|
||||
///add a new setting to the model and return it
|
||||
Setting *createSetting (CSMSettings::SettingType typ,
|
||||
const QString &page, const QString &name);
|
||||
Setting *createSetting (CSMSettings::SettingType type, const QString &name,
|
||||
const QString& label);
|
||||
|
||||
/// Set the section for createSetting calls.
|
||||
///
|
||||
/// Sections can be declared multiple times.
|
||||
void declareSection (const QString& page, const QString& label);
|
||||
|
||||
signals:
|
||||
|
||||
|
|
51
apps/opencs/model/tools/bodypartcheck.cpp
Normal file
51
apps/opencs/model/tools/bodypartcheck.cpp
Normal file
|
@ -0,0 +1,51 @@
|
|||
#include "bodypartcheck.hpp"
|
||||
|
||||
CSMTools::BodyPartCheckStage::BodyPartCheckStage(
|
||||
const CSMWorld::IdCollection<ESM::BodyPart> &bodyParts,
|
||||
const CSMWorld::Resources &meshes,
|
||||
const CSMWorld::IdCollection<ESM::Race> &races ) :
|
||||
mBodyParts(bodyParts),
|
||||
mMeshes(meshes),
|
||||
mRaces(races)
|
||||
{ }
|
||||
|
||||
int CSMTools::BodyPartCheckStage::setup()
|
||||
{
|
||||
return mBodyParts.getSize();
|
||||
}
|
||||
|
||||
void CSMTools::BodyPartCheckStage::perform ( int stage, Messages &messages )
|
||||
{
|
||||
const CSMWorld::Record<ESM::BodyPart> &record = mBodyParts.getRecord(stage);
|
||||
|
||||
if ( record.isDeleted() )
|
||||
return;
|
||||
|
||||
const ESM::BodyPart &bodyPart = record.get();
|
||||
|
||||
CSMWorld::UniversalId id( CSMWorld::UniversalId::Type_BodyPart, bodyPart.mId );
|
||||
|
||||
// Check BYDT
|
||||
if (bodyPart.mData.mPart > 14 )
|
||||
messages.push_back(std::make_pair( id, bodyPart.mId + " has out of range part value." ));
|
||||
|
||||
if (bodyPart.mData.mFlags > 3 )
|
||||
messages.push_back(std::make_pair( id, bodyPart.mId + " has out of range flags value." ));
|
||||
|
||||
if (bodyPart.mData.mType > 2 )
|
||||
messages.push_back(std::make_pair( id, bodyPart.mId + " has out of range type value." ));
|
||||
|
||||
// Check MODL
|
||||
|
||||
if ( bodyPart.mModel.empty() )
|
||||
messages.push_back(std::make_pair( id, bodyPart.mId + " has no model." ));
|
||||
else if ( mMeshes.searchId( bodyPart.mModel ) == -1 )
|
||||
messages.push_back(std::make_pair( id, bodyPart.mId + " has invalid model." ));
|
||||
|
||||
// Check FNAM
|
||||
|
||||
if ( bodyPart.mRace.empty() )
|
||||
messages.push_back(std::make_pair( id, bodyPart.mId + " has no race." ));
|
||||
else if ( mRaces.searchId( bodyPart.mRace ) == -1 )
|
||||
messages.push_back(std::make_pair( id, bodyPart.mId + " has invalid race." ));
|
||||
}
|
35
apps/opencs/model/tools/bodypartcheck.hpp
Normal file
35
apps/opencs/model/tools/bodypartcheck.hpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifndef CSM_TOOLS_BODYPARTCHECK_H
|
||||
#define CSM_TOOLS_BODYPARTCHECK_H
|
||||
|
||||
#include <components/esm/loadbody.hpp>
|
||||
#include <components/esm/loadrace.hpp>
|
||||
|
||||
#include "../world/resources.hpp"
|
||||
#include "../world/idcollection.hpp"
|
||||
|
||||
#include "../doc/stage.hpp"
|
||||
|
||||
namespace CSMTools
|
||||
{
|
||||
/// \brief VerifyStage: make sure that body part records are internally consistent
|
||||
class BodyPartCheckStage : public CSMDoc::Stage
|
||||
{
|
||||
const CSMWorld::IdCollection<ESM::BodyPart> &mBodyParts;
|
||||
const CSMWorld::Resources &mMeshes;
|
||||
const CSMWorld::IdCollection<ESM::Race> &mRaces;
|
||||
|
||||
public:
|
||||
BodyPartCheckStage(
|
||||
const CSMWorld::IdCollection<ESM::BodyPart> &bodyParts,
|
||||
const CSMWorld::Resources &meshes,
|
||||
const CSMWorld::IdCollection<ESM::Race> &races );
|
||||
|
||||
virtual int setup();
|
||||
///< \return number of steps
|
||||
|
||||
virtual void perform( int stage, Messages &messages );
|
||||
///< Messages resulting from this tage will be appended to \a messages.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -42,7 +42,7 @@ void CSMTools::FactionCheckStage::perform (int stage, Messages& messages)
|
|||
// test for non-unique skill
|
||||
std::map<int, int> skills; // ID, number of occurrences
|
||||
|
||||
for (int i=0; i<6; ++i)
|
||||
for (int i=0; i<7; ++i)
|
||||
if (faction.mData.mSkills[i]!=-1)
|
||||
++skills[faction.mData.mSkills[i]];
|
||||
|
||||
|
@ -54,4 +54,4 @@ void CSMTools::FactionCheckStage::perform (int stage, Messages& messages)
|
|||
}
|
||||
|
||||
/// \todo check data members that can't be edited in the table view
|
||||
}
|
||||
}
|
||||
|
|
|
@ -621,12 +621,6 @@ void CSMTools::ReferenceableCheckStage::npcCheck (
|
|||
}
|
||||
else
|
||||
{
|
||||
if (npc.mNpdt52.mMana < 0)
|
||||
messages.push_back (std::make_pair (id, npc.mId + " mana has negative value"));
|
||||
|
||||
if (npc.mNpdt52.mFatigue < 0)
|
||||
messages.push_back (std::make_pair (id, npc.mId + " fatigue has negative value"));
|
||||
|
||||
if (npc.mNpdt52.mAgility == 0)
|
||||
messages.push_back (std::make_pair (id, npc.mId + " agility has zero value"));
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include <components/compiler/exception.hpp>
|
||||
#include <components/compiler/extensions0.hpp>
|
||||
|
||||
#include "../doc/document.hpp"
|
||||
|
||||
#include "../world/data.hpp"
|
||||
|
||||
void CSMTools::ScriptCheckStage::report (const std::string& message, const Compiler::TokenLoc& loc,
|
||||
|
@ -37,8 +39,8 @@ void CSMTools::ScriptCheckStage::report (const std::string& message, Type type)
|
|||
(type==ErrorMessage ? "error: " : "warning: ") + message));
|
||||
}
|
||||
|
||||
CSMTools::ScriptCheckStage::ScriptCheckStage (const CSMWorld::Data& data)
|
||||
: mData (data), mContext (data), mMessages (0)
|
||||
CSMTools::ScriptCheckStage::ScriptCheckStage (const CSMDoc::Document& document)
|
||||
: mDocument (document), mContext (document.getData()), mMessages (0)
|
||||
{
|
||||
/// \todo add an option to configure warning mode
|
||||
setWarningsMode (0);
|
||||
|
@ -53,18 +55,25 @@ int CSMTools::ScriptCheckStage::setup()
|
|||
mMessages = 0;
|
||||
mId.clear();
|
||||
|
||||
return mData.getScripts().getSize();
|
||||
return mDocument.getData().getScripts().getSize();
|
||||
}
|
||||
|
||||
void CSMTools::ScriptCheckStage::perform (int stage, Messages& messages)
|
||||
{
|
||||
mId = mDocument.getData().getScripts().getId (stage);
|
||||
|
||||
if (mDocument.isBlacklisted (
|
||||
CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Script, mId)))
|
||||
return;
|
||||
|
||||
mMessages = &messages;
|
||||
mId = mData.getScripts().getId (stage);
|
||||
|
||||
try
|
||||
{
|
||||
mFile = mData.getScripts().getRecord (stage).get().mId;
|
||||
std::istringstream input (mData.getScripts().getRecord (stage).get().mScriptText);
|
||||
const CSMWorld::Data& data = mDocument.getData();
|
||||
|
||||
mFile = data.getScripts().getRecord (stage).get().mId;
|
||||
std::istringstream input (data.getScripts().getRecord (stage).get().mScriptText);
|
||||
|
||||
Compiler::Scanner scanner (*this, input, mContext.getExtensions());
|
||||
|
||||
|
|
|
@ -8,12 +8,17 @@
|
|||
|
||||
#include "../world/scriptcontext.hpp"
|
||||
|
||||
namespace CSMDoc
|
||||
{
|
||||
class Document;
|
||||
}
|
||||
|
||||
namespace CSMTools
|
||||
{
|
||||
/// \brief VerifyStage: make sure that scripts compile
|
||||
class ScriptCheckStage : public CSMDoc::Stage, private Compiler::ErrorHandler
|
||||
{
|
||||
const CSMWorld::Data& mData;
|
||||
const CSMDoc::Document& mDocument;
|
||||
Compiler::Extensions mExtensions;
|
||||
CSMWorld::ScriptContext mContext;
|
||||
std::string mId;
|
||||
|
@ -28,7 +33,7 @@ namespace CSMTools
|
|||
|
||||
public:
|
||||
|
||||
ScriptCheckStage (const CSMWorld::Data& data);
|
||||
ScriptCheckStage (const CSMDoc::Document& document);
|
||||
|
||||
virtual int setup();
|
||||
///< \return number of steps
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "../doc/state.hpp"
|
||||
#include "../doc/operation.hpp"
|
||||
#include "../doc/document.hpp"
|
||||
|
||||
#include "../world/data.hpp"
|
||||
#include "../world/universalid.hpp"
|
||||
|
@ -21,6 +22,7 @@
|
|||
#include "spellcheck.hpp"
|
||||
#include "referenceablecheck.hpp"
|
||||
#include "scriptcheck.hpp"
|
||||
#include "bodypartcheck.hpp"
|
||||
|
||||
CSMDoc::Operation *CSMTools::Tools::get (int type)
|
||||
{
|
||||
|
@ -44,7 +46,7 @@ CSMDoc::Operation *CSMTools::Tools::getVerifier()
|
|||
mVerifier = new CSMDoc::Operation (CSMDoc::State_Verifying, false);
|
||||
|
||||
connect (mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int)));
|
||||
connect (mVerifier, SIGNAL (done (int)), this, SIGNAL (done (int)));
|
||||
connect (mVerifier, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool)));
|
||||
connect (mVerifier,
|
||||
SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, int)),
|
||||
this, SLOT (verifierMessage (const CSMWorld::UniversalId&, const std::string&, int)));
|
||||
|
@ -78,15 +80,23 @@ CSMDoc::Operation *CSMTools::Tools::getVerifier()
|
|||
|
||||
mVerifier->appendStage (new SpellCheckStage (mData.getSpells()));
|
||||
|
||||
mVerifier->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions()));
|
||||
mVerifier->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions()));
|
||||
|
||||
mVerifier->appendStage (new ScriptCheckStage (mData));
|
||||
mVerifier->appendStage (new ScriptCheckStage (mDocument));
|
||||
|
||||
mVerifier->appendStage(
|
||||
new BodyPartCheckStage(
|
||||
mData.getBodyParts(),
|
||||
mData.getResources(
|
||||
CSMWorld::UniversalId( CSMWorld::UniversalId::Type_Meshes )),
|
||||
mData.getRaces() ));
|
||||
}
|
||||
|
||||
return mVerifier;
|
||||
}
|
||||
|
||||
CSMTools::Tools::Tools (CSMWorld::Data& data) : mData (data), mVerifier (0), mNextReportNumber (0)
|
||||
CSMTools::Tools::Tools (CSMDoc::Document& document)
|
||||
: mDocument (document), mData (document.getData()), mVerifier (0), mNextReportNumber (0)
|
||||
{
|
||||
// index 0: load error log
|
||||
mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel));
|
||||
|
|
|
@ -14,6 +14,7 @@ namespace CSMWorld
|
|||
namespace CSMDoc
|
||||
{
|
||||
class Operation;
|
||||
class Document;
|
||||
}
|
||||
|
||||
namespace CSMTools
|
||||
|
@ -24,6 +25,7 @@ namespace CSMTools
|
|||
{
|
||||
Q_OBJECT
|
||||
|
||||
CSMDoc::Document& mDocument;
|
||||
CSMWorld::Data& mData;
|
||||
CSMDoc::Operation *mVerifier;
|
||||
std::map<int, ReportModel *> mReports;
|
||||
|
@ -44,7 +46,7 @@ namespace CSMTools
|
|||
|
||||
public:
|
||||
|
||||
Tools (CSMWorld::Data& data);
|
||||
Tools (CSMDoc::Document& document);
|
||||
|
||||
virtual ~Tools();
|
||||
|
||||
|
@ -68,7 +70,7 @@ namespace CSMTools
|
|||
|
||||
void progress (int current, int max, int type);
|
||||
|
||||
void done (int type);
|
||||
void done (int type, bool failed);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -18,8 +18,3 @@ void CSMWorld::Cell::load (ESM::ESMReader &esm)
|
|||
mId = stream.str();
|
||||
}
|
||||
}
|
||||
|
||||
void CSMWorld::Cell::addRef (const std::string& id)
|
||||
{
|
||||
mRefs.push_back (std::make_pair (id, false));
|
||||
}
|
|
@ -15,12 +15,9 @@ namespace CSMWorld
|
|||
struct Cell : public ESM::Cell
|
||||
{
|
||||
std::string mId;
|
||||
std::vector<std::pair<std::string, bool> > mRefs; // ID, modified
|
||||
std::vector<std::string> mDeletedRefs;
|
||||
|
||||
void load (ESM::ESMReader &esm);
|
||||
|
||||
void addRef (const std::string& id);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ namespace CSMWorld
|
|||
Display_TopicInfo,
|
||||
Display_JournalInfo,
|
||||
Display_Scene,
|
||||
Display_GlobalVariable,
|
||||
//CONCRETE TYPES ENDS HERE
|
||||
|
||||
Display_Integer,
|
||||
|
@ -89,7 +90,20 @@ namespace CSMWorld
|
|||
Display_RefRecordType,
|
||||
Display_DialogueType,
|
||||
Display_QuestStatusType,
|
||||
Display_Gender
|
||||
Display_EnchantmentType,
|
||||
Display_BodyPartType,
|
||||
Display_MeshType,
|
||||
Display_Gender,
|
||||
Display_Mesh,
|
||||
Display_Icon,
|
||||
Display_Music,
|
||||
Display_SoundRes,
|
||||
Display_Texture,
|
||||
Display_Video,
|
||||
Display_Colour,
|
||||
Display_ScriptLines, // console context
|
||||
Display_SoundGeneratorType,
|
||||
Display_School
|
||||
};
|
||||
|
||||
int mColumnId;
|
||||
|
@ -113,8 +127,6 @@ namespace CSMWorld
|
|||
template<typename ESXRecordT>
|
||||
struct Column : public ColumnBase
|
||||
{
|
||||
int mFlags;
|
||||
|
||||
Column (int columnId, Display displayType, int flags = Flag_Table | Flag_Dialogue)
|
||||
: ColumnBase (columnId, displayType, flags) {}
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#ifndef CSM_WOLRD_COLUMNIMP_H
|
||||
#define CSM_WOLRD_COLUMNIMP_H
|
||||
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
|
@ -463,14 +465,21 @@ namespace CSMWorld
|
|||
struct FlagColumn : public Column<ESXRecordT>
|
||||
{
|
||||
int mMask;
|
||||
bool mInverted;
|
||||
|
||||
FlagColumn (int columnId, int mask)
|
||||
: Column<ESXRecordT> (columnId, ColumnBase::Display_Boolean), mMask (mask)
|
||||
FlagColumn (int columnId, int mask, bool inverted = false)
|
||||
: Column<ESXRecordT> (columnId, ColumnBase::Display_Boolean), mMask (mask),
|
||||
mInverted (inverted)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return (record.get().mData.mFlags & mMask)!=0;
|
||||
bool flag = (record.get().mData.mFlags & mMask)!=0;
|
||||
|
||||
if (mInverted)
|
||||
flag = !flag;
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
|
@ -479,7 +488,7 @@ namespace CSMWorld
|
|||
|
||||
int flags = record2.mData.mFlags & ~mMask;
|
||||
|
||||
if (data.toInt())
|
||||
if ((data.toInt()!=0)!=mInverted)
|
||||
flags |= mMask;
|
||||
|
||||
record2.mData.mFlags = flags;
|
||||
|
@ -493,6 +502,47 @@ namespace CSMWorld
|
|||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct FlagColumn2 : public Column<ESXRecordT>
|
||||
{
|
||||
int mMask;
|
||||
bool mInverted;
|
||||
|
||||
FlagColumn2 (int columnId, int mask, bool inverted = false)
|
||||
: Column<ESXRecordT> (columnId, ColumnBase::Display_Boolean), mMask (mask),
|
||||
mInverted (inverted)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
bool flag = (record.get().mFlags & mMask)!=0;
|
||||
|
||||
if (mInverted)
|
||||
flag = !flag;
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
int flags = record2.mFlags & ~mMask;
|
||||
|
||||
if ((data.toInt()!=0)!=mInverted)
|
||||
flags |= mMask;
|
||||
|
||||
record2.mFlags = flags;
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct WeightHeightColumn : public Column<ESXRecordT>
|
||||
{
|
||||
|
@ -597,7 +647,7 @@ namespace CSMWorld
|
|||
struct SoundFileColumn : public Column<ESXRecordT>
|
||||
{
|
||||
SoundFileColumn()
|
||||
: Column<ESXRecordT> (Columns::ColumnId_SoundFile, ColumnBase::Display_Sound)
|
||||
: Column<ESXRecordT> (Columns::ColumnId_SoundFile, ColumnBase::Display_SoundRes)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
|
@ -627,7 +677,7 @@ namespace CSMWorld
|
|||
{
|
||||
/// \todo Replace Display_Integer with something that displays the colour value more directly.
|
||||
MapColourColumn()
|
||||
: Column<ESXRecordT> (Columns::ColumnId_MapColour, ColumnBase::Display_Integer)
|
||||
: Column<ESXRecordT> (Columns::ColumnId_MapColour, ColumnBase::Display_Colour)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
|
@ -759,8 +809,18 @@ namespace CSMWorld
|
|||
template<typename ESXRecordT>
|
||||
struct ScriptColumn : public Column<ESXRecordT>
|
||||
{
|
||||
ScriptColumn()
|
||||
: Column<ESXRecordT> (Columns::ColumnId_ScriptText, ColumnBase::Display_Script, 0) {}
|
||||
enum Type
|
||||
{
|
||||
Type_File, // regular script record
|
||||
Type_Lines, // console context
|
||||
Type_Info // dialogue context (not implemented yet)
|
||||
};
|
||||
|
||||
ScriptColumn (Type type)
|
||||
: Column<ESXRecordT> (Columns::ColumnId_ScriptText,
|
||||
type==Type_File ? ColumnBase::Display_Script : ColumnBase::Display_ScriptLines,
|
||||
type==Type_File ? 0 : ColumnBase::Flag_Dialogue)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
|
@ -970,13 +1030,13 @@ namespace CSMWorld
|
|||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return record.get().mFactIndex;
|
||||
return record.get().mFactionRank;
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
record2.mFactIndex = data.toInt();
|
||||
record2.mFactionRank = data.toInt();
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
|
@ -1217,36 +1277,6 @@ namespace CSMWorld
|
|||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct ScopeColumn : public Column<ESXRecordT>
|
||||
{
|
||||
ScopeColumn()
|
||||
: Column<ESXRecordT> (Columns::ColumnId_Scope, ColumnBase::Display_Integer, 0)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return static_cast<int> (record.get().mScope);
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
record2.mScope = static_cast<CSMFilter::Filter::Scope> (data.toInt());
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool isUserEditable() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct PosColumn : public Column<ESXRecordT>
|
||||
|
@ -1269,7 +1299,7 @@ namespace CSMWorld
|
|||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
ESM::Position& position = record.get().*mPosition;
|
||||
ESM::Position& position = record2.*mPosition;
|
||||
|
||||
position.pos[mIndex] = data.toFloat();
|
||||
|
||||
|
@ -1303,7 +1333,7 @@ namespace CSMWorld
|
|||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
ESM::Position& position = record.get().*mPosition;
|
||||
ESM::Position& position = record2.*mPosition;
|
||||
|
||||
position.rot[mIndex] = data.toFloat();
|
||||
|
||||
|
@ -1682,6 +1712,559 @@ namespace CSMWorld
|
|||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct EnchantmentTypeColumn : public Column<ESXRecordT>
|
||||
{
|
||||
EnchantmentTypeColumn()
|
||||
: Column<ESXRecordT> (Columns::ColumnId_EnchantmentType, ColumnBase::Display_EnchantmentType)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return static_cast<int> (record.get().mData.mType);
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mData.mType = data.toInt();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct ChargesColumn2 : public Column<ESXRecordT>
|
||||
{
|
||||
ChargesColumn2() : Column<ESXRecordT> (Columns::ColumnId_Charges, ColumnBase::Display_Integer) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return record.get().mData.mCharge;
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
record2.mData.mCharge = data.toInt();
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct AutoCalcColumn : public Column<ESXRecordT>
|
||||
{
|
||||
AutoCalcColumn() : Column<ESXRecordT> (Columns::ColumnId_AutoCalc, ColumnBase::Display_Boolean)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return record.get().mData.mAutocalc!=0;
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mData.mAutocalc = data.toInt();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct ModelColumn : public Column<ESXRecordT>
|
||||
{
|
||||
ModelColumn() : Column<ESXRecordT> (Columns::ColumnId_Model, ColumnBase::Display_String) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return QString::fromUtf8 (record.get().mModel.c_str());
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mModel = data.toString().toUtf8().constData();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct VampireColumn : public Column<ESXRecordT>
|
||||
{
|
||||
VampireColumn() : Column<ESXRecordT> (Columns::ColumnId_Vampire, ColumnBase::Display_Boolean)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return record.get().mData.mVampire!=0;
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mData.mVampire = data.toInt();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct BodyPartTypeColumn : public Column<ESXRecordT>
|
||||
{
|
||||
BodyPartTypeColumn()
|
||||
: Column<ESXRecordT> (Columns::ColumnId_BodyPartType, ColumnBase::Display_BodyPartType)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return static_cast<int> (record.get().mData.mPart);
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mData.mPart = data.toInt();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct MeshTypeColumn : public Column<ESXRecordT>
|
||||
{
|
||||
MeshTypeColumn()
|
||||
: Column<ESXRecordT> (Columns::ColumnId_MeshType, ColumnBase::Display_MeshType)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return static_cast<int> (record.get().mData.mType);
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mData.mType = data.toInt();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct OwnerGlobalColumn : public Column<ESXRecordT>
|
||||
{
|
||||
OwnerGlobalColumn()
|
||||
: Column<ESXRecordT> (Columns::ColumnId_OwnerGlobal, ColumnBase::Display_GlobalVariable)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return QString::fromUtf8 (record.get().mGlobalVariable.c_str());
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mGlobalVariable = data.toString().toUtf8().constData();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct RefNumCounterColumn : public Column<ESXRecordT>
|
||||
{
|
||||
RefNumCounterColumn()
|
||||
: Column<ESXRecordT> (Columns::ColumnId_RefNumCounter, ColumnBase::Display_Integer, 0)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return static_cast<int> (record.get().mRefNumCounter);
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mRefNumCounter = data.toInt();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool isUserEditable() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct RefNumColumn : public Column<ESXRecordT>
|
||||
{
|
||||
RefNumColumn()
|
||||
: Column<ESXRecordT> (Columns::ColumnId_RefNum, ColumnBase::Display_Integer, 0)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return static_cast<int> (record.get().mRefNum.mIndex);
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mRefNum.mIndex = data.toInt();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool isUserEditable() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct SoundColumn : public Column<ESXRecordT>
|
||||
{
|
||||
SoundColumn()
|
||||
: Column<ESXRecordT> (Columns::ColumnId_Sound, ColumnBase::Display_Sound)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return QString::fromUtf8 (record.get().mSound.c_str());
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mSound = data.toString().toUtf8().constData();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct CreatureColumn : public Column<ESXRecordT>
|
||||
{
|
||||
CreatureColumn()
|
||||
: Column<ESXRecordT> (Columns::ColumnId_Creature, ColumnBase::Display_Creature)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return QString::fromUtf8 (record.get().mCreature.c_str());
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mCreature = data.toString().toUtf8().constData();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct SoundGeneratorTypeColumn : public Column<ESXRecordT>
|
||||
{
|
||||
SoundGeneratorTypeColumn()
|
||||
: Column<ESXRecordT> (Columns::ColumnId_SoundGeneratorType, ColumnBase::Display_SoundGeneratorType)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return static_cast<int> (record.get().mType);
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mType = data.toInt();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct BaseCostColumn : public Column<ESXRecordT>
|
||||
{
|
||||
BaseCostColumn() : Column<ESXRecordT> (Columns::ColumnId_BaseCost, ColumnBase::Display_Float) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return record.get().mData.mBaseCost;
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
record2.mData.mBaseCost = data.toFloat();
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct SchoolColumn : public Column<ESXRecordT>
|
||||
{
|
||||
SchoolColumn()
|
||||
: Column<ESXRecordT> (Columns::ColumnId_School, ColumnBase::Display_School)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return record.get().mData.mSchool;
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mData.mSchool = data.toInt();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct EffectTextureColumn : public Column<ESXRecordT>
|
||||
{
|
||||
EffectTextureColumn (Columns::ColumnId columnId)
|
||||
: Column<ESXRecordT> (columnId, ColumnBase::Display_Texture)
|
||||
{
|
||||
assert (this->mColumnId==Columns::ColumnId_Icon ||
|
||||
this->mColumnId==Columns::ColumnId_Particle);
|
||||
}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return QString::fromUtf8 (
|
||||
(this->mColumnId==Columns::ColumnId_Icon ?
|
||||
record.get().mIcon : record.get().mParticle).c_str());
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
(this->mColumnId==Columns::ColumnId_Icon ?
|
||||
record2.mIcon : record2.mParticle)
|
||||
= data.toString().toUtf8().constData();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct EffectObjectColumn : public Column<ESXRecordT>
|
||||
{
|
||||
EffectObjectColumn (Columns::ColumnId columnId)
|
||||
: Column<ESXRecordT> (columnId, columnId==Columns::ColumnId_BoltObject ? ColumnBase::Display_Weapon : ColumnBase::Display_Static)
|
||||
{
|
||||
assert (this->mColumnId==Columns::ColumnId_CastingObject ||
|
||||
this->mColumnId==Columns::ColumnId_HitObject ||
|
||||
this->mColumnId==Columns::ColumnId_AreaObject ||
|
||||
this->mColumnId==Columns::ColumnId_BoltObject);
|
||||
}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
const std::string *string = 0;
|
||||
|
||||
switch (this->mColumnId)
|
||||
{
|
||||
case Columns::ColumnId_CastingObject: string = &record.get().mCasting; break;
|
||||
case Columns::ColumnId_HitObject: string = &record.get().mHit; break;
|
||||
case Columns::ColumnId_AreaObject: string = &record.get().mArea; break;
|
||||
case Columns::ColumnId_BoltObject: string = &record.get().mBolt; break;
|
||||
}
|
||||
|
||||
if (!string)
|
||||
throw std::logic_error ("Unsupported column ID");
|
||||
|
||||
return QString::fromUtf8 (string->c_str());
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
std::string *string = 0;
|
||||
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
switch (this->mColumnId)
|
||||
{
|
||||
case Columns::ColumnId_CastingObject: string = &record2.mCasting; break;
|
||||
case Columns::ColumnId_HitObject: string = &record2.mHit; break;
|
||||
case Columns::ColumnId_AreaObject: string = &record2.mArea; break;
|
||||
case Columns::ColumnId_BoltObject: string = &record2.mBolt; break;
|
||||
}
|
||||
|
||||
if (!string)
|
||||
throw std::logic_error ("Unsupported column ID");
|
||||
|
||||
*string = data.toString().toUtf8().constData();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct EffectSoundColumn : public Column<ESXRecordT>
|
||||
{
|
||||
EffectSoundColumn (Columns::ColumnId columnId)
|
||||
: Column<ESXRecordT> (columnId, ColumnBase::Display_Sound)
|
||||
{
|
||||
assert (this->mColumnId==Columns::ColumnId_CastingSound ||
|
||||
this->mColumnId==Columns::ColumnId_HitSound ||
|
||||
this->mColumnId==Columns::ColumnId_AreaSound ||
|
||||
this->mColumnId==Columns::ColumnId_BoltSound);
|
||||
}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
const std::string *string = 0;
|
||||
|
||||
switch (this->mColumnId)
|
||||
{
|
||||
case Columns::ColumnId_CastingSound: string = &record.get().mCastSound; break;
|
||||
case Columns::ColumnId_HitSound: string = &record.get().mHitSound; break;
|
||||
case Columns::ColumnId_AreaSound: string = &record.get().mAreaSound; break;
|
||||
case Columns::ColumnId_BoltSound: string = &record.get().mBoltSound; break;
|
||||
}
|
||||
|
||||
if (!string)
|
||||
throw std::logic_error ("Unsupported column ID");
|
||||
|
||||
return QString::fromUtf8 (string->c_str());
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
std::string *string = 0;
|
||||
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
switch (this->mColumnId)
|
||||
{
|
||||
case Columns::ColumnId_CastingSound: string = &record2.mCastSound; break;
|
||||
case Columns::ColumnId_HitSound: string = &record2.mHitSound; break;
|
||||
case Columns::ColumnId_AreaSound: string = &record2.mAreaSound; break;
|
||||
case Columns::ColumnId_BoltSound: string = &record2.mBoltSound; break;
|
||||
}
|
||||
|
||||
if (!string)
|
||||
throw std::logic_error ("Unsupported column ID");
|
||||
|
||||
*string = data.toString().toUtf8().constData();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -172,8 +172,35 @@ namespace CSMWorld
|
|||
{ ColumnId_Rank, "Rank" },
|
||||
{ ColumnId_Gender, "Gender" },
|
||||
{ ColumnId_PcRank, "PC Rank" },
|
||||
{ ColumnId_Scope, "Scope" },
|
||||
{ ColumnId_ReferenceableId, "Referenceable ID" },
|
||||
{ ColumnId_CombatState, "Combat" },
|
||||
{ ColumnId_MagicState, "Magic" },
|
||||
{ ColumnId_StealthState, "Stealth" },
|
||||
{ ColumnId_EnchantmentType, "Enchantment Type" },
|
||||
{ ColumnId_Vampire, "Vampire" },
|
||||
{ ColumnId_BodyPartType, "Bodypart Type" },
|
||||
{ ColumnId_MeshType, "Mesh Type" },
|
||||
{ ColumnId_OwnerGlobal, "Owner Global" },
|
||||
{ ColumnId_DefaultProfile, "Default Profile" },
|
||||
{ ColumnId_BypassNewGame, "Bypass New Game" },
|
||||
{ ColumnId_GlobalProfile, "Global Profile" },
|
||||
{ ColumnId_RefNumCounter, "RefNum Counter" },
|
||||
{ ColumnId_RefNum, "RefNum" },
|
||||
{ ColumnId_Creature, "Creature" },
|
||||
{ ColumnId_SoundGeneratorType, "Sound Generator Type" },
|
||||
{ ColumnId_AllowSpellmaking, "Allow Spellmaking" },
|
||||
{ ColumnId_AllowEnchanting, "Allow Enchanting" },
|
||||
{ ColumnId_BaseCost, "Base Cost" },
|
||||
{ ColumnId_School, "School" },
|
||||
{ ColumnId_Particle, "Particle" },
|
||||
{ ColumnId_CastingObject, "Casting Object" },
|
||||
{ ColumnId_HitObject, "Hit Object" },
|
||||
{ ColumnId_AreaObject, "Area Object" },
|
||||
{ ColumnId_BoltObject, "Bolt Object" },
|
||||
{ ColumnId_CastingSound, "Casting Sound" },
|
||||
{ ColumnId_HitSound, "Hit Sound" },
|
||||
{ ColumnId_AreaSound, "Area Sound" },
|
||||
{ ColumnId_BoltSound, "Bolt Sound" },
|
||||
|
||||
{ ColumnId_UseValue1, "Use value 1" },
|
||||
{ ColumnId_UseValue2, "Use value 2" },
|
||||
|
@ -299,6 +326,33 @@ namespace
|
|||
"Male", "Female", 0
|
||||
};
|
||||
|
||||
static const char *sEnchantmentTypes[] =
|
||||
{
|
||||
"Cast Once", "When Strikes", "When Used", "Constant Effect", 0
|
||||
};
|
||||
|
||||
static const char *sBodyPartTypes[] =
|
||||
{
|
||||
"Head", "Hair", "Neck", "Chest", "Groin", "Hand", "Wrist", "Forearm", "Upper Arm",
|
||||
"Foot", "Ankle", "Knee", "Upper Leg", "Clavicle", "Tail", 0
|
||||
};
|
||||
|
||||
static const char *sMeshTypes[] =
|
||||
{
|
||||
"Skin", "Clothing", "Armour", 0
|
||||
};
|
||||
|
||||
static const char *sSoundGeneratorType[] =
|
||||
{
|
||||
"Left Foot", "Right Foot", "Swim Left", "Swim Right", "Moan", "Roar", "Scream",
|
||||
"Land", 0
|
||||
};
|
||||
|
||||
static const char *sSchools[] =
|
||||
{
|
||||
"Alteration", "Conjuration", "Destruction", "Illusion", "Mysticism", "Restoration", 0
|
||||
};
|
||||
|
||||
const char **getEnumNames (CSMWorld::Columns::ColumnId column)
|
||||
{
|
||||
switch (column)
|
||||
|
@ -316,6 +370,11 @@ namespace
|
|||
case CSMWorld::Columns::ColumnId_DialogueType: return sDialogueTypeEnums;
|
||||
case CSMWorld::Columns::ColumnId_QuestStatusType: return sQuestStatusTypes;
|
||||
case CSMWorld::Columns::ColumnId_Gender: return sGenderEnums;
|
||||
case CSMWorld::Columns::ColumnId_EnchantmentType: return sEnchantmentTypes;
|
||||
case CSMWorld::Columns::ColumnId_BodyPartType: return sBodyPartTypes;
|
||||
case CSMWorld::Columns::ColumnId_MeshType: return sMeshTypes;
|
||||
case CSMWorld::Columns::ColumnId_SoundGeneratorType: return sSoundGeneratorType;
|
||||
case CSMWorld::Columns::ColumnId_School: return sSchools;
|
||||
|
||||
default: return 0;
|
||||
}
|
||||
|
|
|
@ -165,9 +165,35 @@ namespace CSMWorld
|
|||
ColumnId_Rank = 152,
|
||||
ColumnId_Gender = 153,
|
||||
ColumnId_PcRank = 154,
|
||||
ColumnId_Scope = 155,
|
||||
ColumnId_ReferenceableId = 156,
|
||||
|
||||
ColumnId_CombatState = 157,
|
||||
ColumnId_MagicState = 158,
|
||||
ColumnId_StealthState = 159,
|
||||
ColumnId_EnchantmentType = 160,
|
||||
ColumnId_Vampire = 161,
|
||||
ColumnId_BodyPartType = 162,
|
||||
ColumnId_MeshType = 163,
|
||||
ColumnId_OwnerGlobal = 164,
|
||||
ColumnId_DefaultProfile = 165,
|
||||
ColumnId_BypassNewGame = 166,
|
||||
ColumnId_GlobalProfile = 167,
|
||||
ColumnId_RefNumCounter = 168,
|
||||
ColumnId_RefNum = 169,
|
||||
ColumnId_Creature = 170,
|
||||
ColumnId_SoundGeneratorType = 171,
|
||||
ColumnId_AllowSpellmaking = 172,
|
||||
ColumnId_AllowEnchanting = 173,
|
||||
ColumnId_BaseCost = 174,
|
||||
ColumnId_School = 175,
|
||||
ColumnId_Particle = 176,
|
||||
ColumnId_CastingObject = 177,
|
||||
ColumnId_HitObject = 178,
|
||||
ColumnId_AreaObject = 179,
|
||||
ColumnId_BoltObject = 180,
|
||||
ColumnId_CastingSound = 177,
|
||||
ColumnId_HitSound = 178,
|
||||
ColumnId_AreaSound = 179,
|
||||
ColumnId_BoltSound = 180,
|
||||
// Allocated to a separate value range, so we don't get a collision should we ever need
|
||||
// to extend the number of use values.
|
||||
ColumnId_UseValue1 = 0x10000,
|
||||
|
@ -212,7 +238,7 @@ namespace CSMWorld
|
|||
bool hasEnums (ColumnId column);
|
||||
|
||||
std::vector<std::string> getEnums (ColumnId column);
|
||||
///< Returns an empty vector, if \æ column isn't an enum type column.
|
||||
///< Returns an empty vector, if \a column isn't an enum type column.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
267
apps/opencs/model/world/commanddispatcher.cpp
Normal file
267
apps/opencs/model/world/commanddispatcher.cpp
Normal file
|
@ -0,0 +1,267 @@
|
|||
|
||||
#include "commanddispatcher.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
#include "../doc/document.hpp"
|
||||
|
||||
#include "idtable.hpp"
|
||||
#include "record.hpp"
|
||||
#include "commands.hpp"
|
||||
|
||||
std::vector<std::string> CSMWorld::CommandDispatcher::getDeletableRecords() const
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
|
||||
IdTable& model = dynamic_cast<IdTable&> (*mDocument.getData().getTableModel (mId));
|
||||
|
||||
int stateColumnIndex = model.findColumnIndex (Columns::ColumnId_Modification);
|
||||
|
||||
for (std::vector<std::string>::const_iterator iter (mSelection.begin());
|
||||
iter!=mSelection.end(); ++iter)
|
||||
{
|
||||
int row = model.getModelIndex (*iter, 0).row();
|
||||
|
||||
// check record state
|
||||
RecordBase::State state = static_cast<RecordBase::State> (
|
||||
model.data (model.index (row, stateColumnIndex)).toInt());
|
||||
|
||||
if (state==RecordBase::State_Deleted)
|
||||
continue;
|
||||
|
||||
// check other columns (only relevant for a subset of the tables)
|
||||
int dialogueTypeIndex = model.searchColumnIndex (Columns::ColumnId_DialogueType);
|
||||
|
||||
if (dialogueTypeIndex!=-1)
|
||||
{
|
||||
int type = model.data (model.index (row, dialogueTypeIndex)).toInt();
|
||||
|
||||
if (type!=ESM::Dialogue::Topic && type!=ESM::Dialogue::Journal)
|
||||
continue;
|
||||
}
|
||||
|
||||
result.push_back (*iter);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::string> CSMWorld::CommandDispatcher::getRevertableRecords() const
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
|
||||
IdTable& model = dynamic_cast<IdTable&> (*mDocument.getData().getTableModel (mId));
|
||||
|
||||
/// \todo Reverting temporarily disabled on tables that support reordering, because
|
||||
/// revert logic currently can not handle reordering.
|
||||
if (model.getFeatures() & IdTable::Feature_ReorderWithinTopic)
|
||||
return result;
|
||||
|
||||
int stateColumnIndex = model.findColumnIndex (Columns::ColumnId_Modification);
|
||||
|
||||
for (std::vector<std::string>::const_iterator iter (mSelection.begin());
|
||||
iter!=mSelection.end(); ++iter)
|
||||
{
|
||||
int row = model.getModelIndex (*iter, 0).row();
|
||||
|
||||
// check record state
|
||||
RecordBase::State state = static_cast<RecordBase::State> (
|
||||
model.data (model.index (row, stateColumnIndex)).toInt());
|
||||
|
||||
if (state==RecordBase::State_BaseOnly)
|
||||
continue;
|
||||
|
||||
result.push_back (*iter);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
CSMWorld::CommandDispatcher::CommandDispatcher (CSMDoc::Document& document,
|
||||
const CSMWorld::UniversalId& id, QObject *parent)
|
||||
: QObject (parent), mDocument (document), mId (id), mLocked (false)
|
||||
{}
|
||||
|
||||
void CSMWorld::CommandDispatcher::setEditLock (bool locked)
|
||||
{
|
||||
mLocked = locked;
|
||||
}
|
||||
|
||||
void CSMWorld::CommandDispatcher::setSelection (const std::vector<std::string>& selection)
|
||||
{
|
||||
mSelection = selection;
|
||||
std::for_each (mSelection.begin(), mSelection.end(), Misc::StringUtils::toLower);
|
||||
std::sort (mSelection.begin(), mSelection.end());
|
||||
}
|
||||
|
||||
void CSMWorld::CommandDispatcher::setExtendedTypes (const std::vector<UniversalId>& types)
|
||||
{
|
||||
mExtendedTypes = types;
|
||||
}
|
||||
|
||||
bool CSMWorld::CommandDispatcher::canDelete() const
|
||||
{
|
||||
if (mLocked)
|
||||
return false;
|
||||
|
||||
return getDeletableRecords().size()!=0;
|
||||
}
|
||||
|
||||
bool CSMWorld::CommandDispatcher::canRevert() const
|
||||
{
|
||||
if (mLocked)
|
||||
return false;
|
||||
|
||||
return getRevertableRecords().size()!=0;
|
||||
}
|
||||
|
||||
std::vector<CSMWorld::UniversalId> CSMWorld::CommandDispatcher::getExtendedTypes() const
|
||||
{
|
||||
std::vector<CSMWorld::UniversalId> tables;
|
||||
|
||||
if (mId==UniversalId::Type_Cells)
|
||||
{
|
||||
tables.push_back (mId);
|
||||
tables.push_back (UniversalId::Type_References);
|
||||
/// \todo add other cell-specific types
|
||||
}
|
||||
|
||||
return tables;
|
||||
}
|
||||
|
||||
void CSMWorld::CommandDispatcher::executeDelete()
|
||||
{
|
||||
if (mLocked)
|
||||
return;
|
||||
|
||||
std::vector<std::string> rows = getDeletableRecords();
|
||||
|
||||
if (rows.empty())
|
||||
return;
|
||||
|
||||
IdTable& model = dynamic_cast<IdTable&> (*mDocument.getData().getTableModel (mId));
|
||||
|
||||
int columnIndex = model.findColumnIndex (Columns::ColumnId_Id);
|
||||
|
||||
if (rows.size()>1)
|
||||
mDocument.getUndoStack().beginMacro (tr ("Delete multiple records"));
|
||||
|
||||
for (std::vector<std::string>::const_iterator iter (rows.begin()); iter!=rows.end(); ++iter)
|
||||
{
|
||||
std::string id = model.data (model.getModelIndex (*iter, columnIndex)).
|
||||
toString().toUtf8().constData();
|
||||
|
||||
mDocument.getUndoStack().push (new CSMWorld::DeleteCommand (model, id));
|
||||
}
|
||||
|
||||
if (rows.size()>1)
|
||||
mDocument.getUndoStack().endMacro();
|
||||
}
|
||||
|
||||
void CSMWorld::CommandDispatcher::executeRevert()
|
||||
{
|
||||
if (mLocked)
|
||||
return;
|
||||
|
||||
std::vector<std::string> rows = getRevertableRecords();
|
||||
|
||||
if (rows.empty())
|
||||
return;
|
||||
|
||||
IdTable& model = dynamic_cast<IdTable&> (*mDocument.getData().getTableModel (mId));
|
||||
|
||||
int columnIndex = model.findColumnIndex (Columns::ColumnId_Id);
|
||||
|
||||
if (rows.size()>1)
|
||||
mDocument.getUndoStack().beginMacro (tr ("Revert multiple records"));
|
||||
|
||||
for (std::vector<std::string>::const_iterator iter (rows.begin()); iter!=rows.end(); ++iter)
|
||||
{
|
||||
std::string id = model.data (model.getModelIndex (*iter, columnIndex)).
|
||||
toString().toUtf8().constData();
|
||||
|
||||
mDocument.getUndoStack().push (new CSMWorld::RevertCommand (model, id));
|
||||
}
|
||||
|
||||
if (rows.size()>1)
|
||||
mDocument.getUndoStack().endMacro();
|
||||
}
|
||||
|
||||
void CSMWorld::CommandDispatcher::executeExtendedDelete()
|
||||
{
|
||||
if (mExtendedTypes.size()>1)
|
||||
mDocument.getUndoStack().beginMacro (tr ("Extended delete of multiple records"));
|
||||
|
||||
for (std::vector<UniversalId>::const_iterator iter (mExtendedTypes.begin());
|
||||
iter!=mExtendedTypes.end(); ++iter)
|
||||
{
|
||||
if (*iter==mId)
|
||||
executeDelete();
|
||||
else if (*iter==UniversalId::Type_References)
|
||||
{
|
||||
IdTable& model = dynamic_cast<IdTable&> (
|
||||
*mDocument.getData().getTableModel (*iter));
|
||||
|
||||
const RefCollection& collection = mDocument.getData().getReferences();
|
||||
|
||||
int size = collection.getSize();
|
||||
|
||||
for (int i=size-1; i>=0; --i)
|
||||
{
|
||||
const Record<CellRef>& record = collection.getRecord (i);
|
||||
|
||||
if (record.mState==RecordBase::State_Deleted)
|
||||
continue;
|
||||
|
||||
if (!std::binary_search (mSelection.begin(), mSelection.end(),
|
||||
Misc::StringUtils::lowerCase (record.get().mCell)))
|
||||
continue;
|
||||
|
||||
mDocument.getUndoStack().push (
|
||||
new CSMWorld::DeleteCommand (model, record.get().mId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mExtendedTypes.size()>1)
|
||||
mDocument.getUndoStack().endMacro();
|
||||
}
|
||||
|
||||
void CSMWorld::CommandDispatcher::executeExtendedRevert()
|
||||
{
|
||||
if (mExtendedTypes.size()>1)
|
||||
mDocument.getUndoStack().beginMacro (tr ("Extended revert of multiple records"));
|
||||
|
||||
for (std::vector<UniversalId>::const_iterator iter (mExtendedTypes.begin());
|
||||
iter!=mExtendedTypes.end(); ++iter)
|
||||
{
|
||||
if (*iter==mId)
|
||||
executeRevert();
|
||||
else if (*iter==UniversalId::Type_References)
|
||||
{
|
||||
IdTable& model = dynamic_cast<IdTable&> (
|
||||
*mDocument.getData().getTableModel (*iter));
|
||||
|
||||
const RefCollection& collection = mDocument.getData().getReferences();
|
||||
|
||||
int size = collection.getSize();
|
||||
|
||||
for (int i=size-1; i>=0; --i)
|
||||
{
|
||||
const Record<CellRef>& record = collection.getRecord (i);
|
||||
|
||||
if (!std::binary_search (mSelection.begin(), mSelection.end(),
|
||||
Misc::StringUtils::lowerCase (record.get().mCell)))
|
||||
continue;
|
||||
|
||||
mDocument.getUndoStack().push (
|
||||
new CSMWorld::RevertCommand (model, record.get().mId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mExtendedTypes.size()>1)
|
||||
mDocument.getUndoStack().endMacro();
|
||||
}
|
69
apps/opencs/model/world/commanddispatcher.hpp
Normal file
69
apps/opencs/model/world/commanddispatcher.hpp
Normal file
|
@ -0,0 +1,69 @@
|
|||
#ifndef CSM_WOLRD_COMMANDDISPATCHER_H
|
||||
#define CSM_WOLRD_COMMANDDISPATCHER_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "universalid.hpp"
|
||||
|
||||
namespace CSMDoc
|
||||
{
|
||||
class Document;
|
||||
}
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class CommandDispatcher : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
bool mLocked;
|
||||
CSMDoc::Document& mDocument;
|
||||
UniversalId mId;
|
||||
std::vector<std::string> mSelection;
|
||||
std::vector<UniversalId> mExtendedTypes;
|
||||
|
||||
std::vector<std::string> getDeletableRecords() const;
|
||||
|
||||
std::vector<std::string> getRevertableRecords() const;
|
||||
|
||||
public:
|
||||
|
||||
CommandDispatcher (CSMDoc::Document& document, const CSMWorld::UniversalId& id,
|
||||
QObject *parent = 0);
|
||||
///< \param id ID of the table the commands should operate on primarily.
|
||||
|
||||
void setEditLock (bool locked);
|
||||
|
||||
void setSelection (const std::vector<std::string>& selection);
|
||||
|
||||
void setExtendedTypes (const std::vector<UniversalId>& types);
|
||||
///< Set record lists selected by the user for extended operations.
|
||||
|
||||
bool canDelete() const;
|
||||
|
||||
bool canRevert() const;
|
||||
|
||||
/// Return IDs of the record collection that can also be affected when
|
||||
/// operating on the record collection this dispatcher is used for.
|
||||
///
|
||||
/// \note The returned collection contains the ID of the record collection this
|
||||
/// dispatcher is used for. However if that record collection does not support
|
||||
/// the extended mode, the returned vector will be empty instead.
|
||||
std::vector<UniversalId> getExtendedTypes() const;
|
||||
|
||||
public slots:
|
||||
|
||||
void executeDelete();
|
||||
|
||||
void executeRevert();
|
||||
|
||||
void executeExtendedDelete();
|
||||
|
||||
void executeExtendedRevert();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -10,13 +10,12 @@ CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelI
|
|||
const QVariant& new_, QUndoCommand* parent)
|
||||
: QUndoCommand (parent), mModel (model), mIndex (index), mNew (new_)
|
||||
{
|
||||
mOld = mModel.data (mIndex, Qt::EditRole);
|
||||
|
||||
setText ("Modify " + mModel.headerData (mIndex.column(), Qt::Horizontal, Qt::DisplayRole).toString());
|
||||
}
|
||||
|
||||
void CSMWorld::ModifyCommand::redo()
|
||||
{
|
||||
mOld = mModel.data (mIndex, Qt::EditRole);
|
||||
mModel.setData (mIndex, mNew);
|
||||
}
|
||||
|
||||
|
@ -25,6 +24,13 @@ void CSMWorld::ModifyCommand::undo()
|
|||
mModel.setData (mIndex, mOld);
|
||||
}
|
||||
|
||||
|
||||
void CSMWorld::CreateCommand::applyModifications()
|
||||
{
|
||||
for (std::map<int, QVariant>::const_iterator iter (mValues.begin()); iter!=mValues.end(); ++iter)
|
||||
mModel.setData (mModel.getModelIndex (mId, iter->first), iter->second);
|
||||
}
|
||||
|
||||
CSMWorld::CreateCommand::CreateCommand (IdTable& model, const std::string& id, QUndoCommand* parent)
|
||||
: QUndoCommand (parent), mModel (model), mId (id), mType (UniversalId::Type_None)
|
||||
{
|
||||
|
@ -44,9 +50,7 @@ void CSMWorld::CreateCommand::setType (UniversalId::Type type)
|
|||
void CSMWorld::CreateCommand::redo()
|
||||
{
|
||||
mModel.addRecord (mId, mType);
|
||||
|
||||
for (std::map<int, QVariant>::const_iterator iter (mValues.begin()); iter!=mValues.end(); ++iter)
|
||||
mModel.setData (mModel.getModelIndex (mId, iter->first), iter->second);
|
||||
applyModifications();
|
||||
}
|
||||
|
||||
void CSMWorld::CreateCommand::undo()
|
||||
|
@ -148,27 +152,22 @@ void CSMWorld::ReorderRowsCommand::undo()
|
|||
|
||||
CSMWorld::CloneCommand::CloneCommand (CSMWorld::IdTable& model,
|
||||
const std::string& idOrigin,
|
||||
const std::string& IdDestination,
|
||||
const std::string& idDestination,
|
||||
const CSMWorld::UniversalId::Type type,
|
||||
QUndoCommand* parent) :
|
||||
QUndoCommand (parent),
|
||||
mModel (model),
|
||||
mIdOrigin (idOrigin),
|
||||
mIdDestination (Misc::StringUtils::lowerCase (IdDestination)),
|
||||
mType (type)
|
||||
QUndoCommand* parent)
|
||||
: CreateCommand (model, idDestination, parent), mIdOrigin (idOrigin)
|
||||
{
|
||||
setText ( ("Clone record " + idOrigin + " to the " + IdDestination).c_str());
|
||||
setType (type);
|
||||
setText ( ("Clone record " + idOrigin + " to the " + idDestination).c_str());
|
||||
}
|
||||
|
||||
void CSMWorld::CloneCommand::redo()
|
||||
{
|
||||
mModel.cloneRecord (mIdOrigin, mIdDestination, mType);
|
||||
|
||||
for (std::map<int, QVariant>::const_iterator iter (mValues.begin()); iter != mValues.end(); ++iter)
|
||||
mModel.setData (mModel.getModelIndex (mIdDestination, iter->first), iter->second);
|
||||
mModel.cloneRecord (mIdOrigin, mId, mType);
|
||||
applyModifications();
|
||||
}
|
||||
|
||||
void CSMWorld::CloneCommand::undo()
|
||||
{
|
||||
mModel.removeRow (mModel.getModelIndex (mIdDestination, 0).row());
|
||||
mModel.removeRow (mModel.getModelIndex (mId, 0).row());
|
||||
}
|
|
@ -39,32 +39,20 @@ namespace CSMWorld
|
|||
virtual void undo();
|
||||
};
|
||||
|
||||
class CloneCommand : public QUndoCommand
|
||||
{
|
||||
IdTable& mModel;
|
||||
std::string mIdOrigin;
|
||||
std::string mIdDestination;
|
||||
UniversalId::Type mType;
|
||||
std::map<int, QVariant> mValues;
|
||||
|
||||
public:
|
||||
|
||||
CloneCommand (IdTable& model, const std::string& idOrigin,
|
||||
const std::string& IdDestination,
|
||||
const UniversalId::Type type,
|
||||
QUndoCommand* parent = 0);
|
||||
|
||||
virtual void redo();
|
||||
|
||||
virtual void undo();
|
||||
};
|
||||
|
||||
class CreateCommand : public QUndoCommand
|
||||
{
|
||||
std::map<int, QVariant> mValues;
|
||||
|
||||
protected:
|
||||
|
||||
IdTable& mModel;
|
||||
std::string mId;
|
||||
UniversalId::Type mType;
|
||||
std::map<int, QVariant> mValues;
|
||||
|
||||
protected:
|
||||
|
||||
/// Apply modifications set via addValue.
|
||||
void applyModifications();
|
||||
|
||||
public:
|
||||
|
||||
|
@ -79,6 +67,22 @@ namespace CSMWorld
|
|||
virtual void undo();
|
||||
};
|
||||
|
||||
class CloneCommand : public CreateCommand
|
||||
{
|
||||
std::string mIdOrigin;
|
||||
|
||||
public:
|
||||
|
||||
CloneCommand (IdTable& model, const std::string& idOrigin,
|
||||
const std::string& IdDestination,
|
||||
const UniversalId::Type type,
|
||||
QUndoCommand* parent = 0);
|
||||
|
||||
virtual void redo();
|
||||
|
||||
virtual void undo();
|
||||
};
|
||||
|
||||
class RevertCommand : public QUndoCommand
|
||||
{
|
||||
IdTable& mModel;
|
||||
|
|
|
@ -15,12 +15,15 @@
|
|||
#include "columnimp.hpp"
|
||||
#include "regionmap.hpp"
|
||||
#include "columns.hpp"
|
||||
#include "resourcesmanager.hpp"
|
||||
#include "resourcetable.hpp"
|
||||
|
||||
void CSMWorld::Data::addModel (QAbstractItemModel *model, UniversalId::Type type1,
|
||||
UniversalId::Type type2, bool update)
|
||||
void CSMWorld::Data::addModel (QAbstractItemModel *model, UniversalId::Type type, bool update)
|
||||
{
|
||||
mModels.push_back (model);
|
||||
mModelIndex.insert (std::make_pair (type1, model));
|
||||
mModelIndex.insert (std::make_pair (type, model));
|
||||
|
||||
UniversalId::Type type2 = UniversalId::getParentType (type);
|
||||
|
||||
if (type2!=UniversalId::Type_None)
|
||||
mModelIndex.insert (std::make_pair (type2, model));
|
||||
|
@ -55,8 +58,9 @@ int CSMWorld::Data::count (RecordBase::State state, const CollectionBase& collec
|
|||
return number;
|
||||
}
|
||||
|
||||
CSMWorld::Data::Data (ToUTF8::FromType encoding)
|
||||
: mEncoder (encoding), mRefs (mCells), mReader (0), mDialogue (0)
|
||||
CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourcesManager)
|
||||
: mEncoder (encoding), mPathgrids (mCells), mRefs (mCells),
|
||||
mResourcesManager (resourcesManager), mReader (0), mDialogue (0), mReaderIndex(0)
|
||||
{
|
||||
mGlobals.addColumn (new StringIdColumn<ESM::Global>);
|
||||
mGlobals.addColumn (new RecordStateColumn<ESM::Global>);
|
||||
|
@ -67,7 +71,6 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding)
|
|||
mGmsts.addColumn (new StringIdColumn<ESM::GameSetting>);
|
||||
mGmsts.addColumn (new RecordStateColumn<ESM::GameSetting>);
|
||||
mGmsts.addColumn (new FixedRecordTypeColumn<ESM::GameSetting> (UniversalId::Type_Gmst));
|
||||
mGmsts.addColumn (new FixedRecordTypeColumn<ESM::GameSetting> (UniversalId::Type_Gmst));
|
||||
mGmsts.addColumn (new VarTypeColumn<ESM::GameSetting> (ColumnBase::Display_GmstVarType));
|
||||
mGmsts.addColumn (new VarValueColumn<ESM::GameSetting>);
|
||||
|
||||
|
@ -101,7 +104,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding)
|
|||
mFactions.addColumn (new AttributesColumn<ESM::Faction> (0));
|
||||
mFactions.addColumn (new AttributesColumn<ESM::Faction> (1));
|
||||
mFactions.addColumn (new HiddenColumn<ESM::Faction>);
|
||||
for (int i=0; i<6; ++i)
|
||||
for (int i=0; i<7; ++i)
|
||||
mFactions.addColumn (new SkillsColumn<ESM::Faction> (i));
|
||||
|
||||
mRaces.addColumn (new StringIdColumn<ESM::Race>);
|
||||
|
@ -127,7 +130,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding)
|
|||
mScripts.addColumn (new StringIdColumn<ESM::Script>);
|
||||
mScripts.addColumn (new RecordStateColumn<ESM::Script>);
|
||||
mScripts.addColumn (new FixedRecordTypeColumn<ESM::Script> (UniversalId::Type_Script));
|
||||
mScripts.addColumn (new ScriptColumn<ESM::Script>);
|
||||
mScripts.addColumn (new ScriptColumn<ESM::Script> (ScriptColumn<ESM::Script>::Type_File));
|
||||
|
||||
mRegions.addColumn (new StringIdColumn<ESM::Region>);
|
||||
mRegions.addColumn (new RecordStateColumn<ESM::Region>);
|
||||
|
@ -182,7 +185,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding)
|
|||
|
||||
mJournalInfos.addColumn (new StringIdColumn<Info> (true));
|
||||
mJournalInfos.addColumn (new RecordStateColumn<Info>);
|
||||
mJournalInfos.addColumn (new FixedRecordTypeColumn<Info> (UniversalId::Type_Journal));
|
||||
mJournalInfos.addColumn (new FixedRecordTypeColumn<Info> (UniversalId::Type_JournalInfo));
|
||||
mJournalInfos.addColumn (new TopicColumn<Info> (true));
|
||||
mJournalInfos.addColumn (new QuestStatusTypeColumn<Info>);
|
||||
mJournalInfos.addColumn (new QuestIndexColumn<Info>);
|
||||
|
@ -196,6 +199,60 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding)
|
|||
mCells.addColumn (new FlagColumn<Cell> (Columns::ColumnId_InteriorWater, ESM::Cell::HasWater));
|
||||
mCells.addColumn (new FlagColumn<Cell> (Columns::ColumnId_InteriorSky, ESM::Cell::QuasiEx));
|
||||
mCells.addColumn (new RegionColumn<Cell>);
|
||||
mCells.addColumn (new RefNumCounterColumn<Cell>);
|
||||
|
||||
mEnchantments.addColumn (new StringIdColumn<ESM::Enchantment>);
|
||||
mEnchantments.addColumn (new RecordStateColumn<ESM::Enchantment>);
|
||||
mEnchantments.addColumn (new FixedRecordTypeColumn<ESM::Enchantment> (UniversalId::Type_Enchantment));
|
||||
mEnchantments.addColumn (new EnchantmentTypeColumn<ESM::Enchantment>);
|
||||
mEnchantments.addColumn (new CostColumn<ESM::Enchantment>);
|
||||
mEnchantments.addColumn (new ChargesColumn2<ESM::Enchantment>);
|
||||
mEnchantments.addColumn (new AutoCalcColumn<ESM::Enchantment>);
|
||||
|
||||
mBodyParts.addColumn (new StringIdColumn<ESM::BodyPart>);
|
||||
mBodyParts.addColumn (new RecordStateColumn<ESM::BodyPart>);
|
||||
mBodyParts.addColumn (new FixedRecordTypeColumn<ESM::BodyPart> (UniversalId::Type_BodyPart));
|
||||
mBodyParts.addColumn (new BodyPartTypeColumn<ESM::BodyPart>);
|
||||
mBodyParts.addColumn (new VampireColumn<ESM::BodyPart>);
|
||||
mBodyParts.addColumn (new FlagColumn<ESM::BodyPart> (Columns::ColumnId_Female, ESM::BodyPart::BPF_Female));
|
||||
mBodyParts.addColumn (new FlagColumn<ESM::BodyPart> (Columns::ColumnId_Playable, ESM::BodyPart::BPF_NotPlayable, true));
|
||||
mBodyParts.addColumn (new MeshTypeColumn<ESM::BodyPart>);
|
||||
mBodyParts.addColumn (new ModelColumn<ESM::BodyPart>);
|
||||
mBodyParts.addColumn (new RaceColumn<ESM::BodyPart>);
|
||||
|
||||
mSoundGens.addColumn (new StringIdColumn<ESM::SoundGenerator>);
|
||||
mSoundGens.addColumn (new RecordStateColumn<ESM::SoundGenerator>);
|
||||
mSoundGens.addColumn (new FixedRecordTypeColumn<ESM::SoundGenerator> (UniversalId::Type_SoundGen));
|
||||
mSoundGens.addColumn (new CreatureColumn<ESM::SoundGenerator>);
|
||||
mSoundGens.addColumn (new SoundColumn<ESM::SoundGenerator>);
|
||||
mSoundGens.addColumn (new SoundGeneratorTypeColumn<ESM::SoundGenerator>);
|
||||
|
||||
mMagicEffects.addColumn (new StringIdColumn<ESM::MagicEffect>);
|
||||
mMagicEffects.addColumn (new RecordStateColumn<ESM::MagicEffect>);
|
||||
mMagicEffects.addColumn (new FixedRecordTypeColumn<ESM::MagicEffect> (UniversalId::Type_MagicEffect));
|
||||
mMagicEffects.addColumn (new SchoolColumn<ESM::MagicEffect>);
|
||||
mMagicEffects.addColumn (new BaseCostColumn<ESM::MagicEffect>);
|
||||
mMagicEffects.addColumn (new EffectTextureColumn<ESM::MagicEffect> (Columns::ColumnId_Icon));
|
||||
mMagicEffects.addColumn (new EffectTextureColumn<ESM::MagicEffect> (Columns::ColumnId_Particle));
|
||||
mMagicEffects.addColumn (new EffectObjectColumn<ESM::MagicEffect> (Columns::ColumnId_CastingObject));
|
||||
mMagicEffects.addColumn (new EffectObjectColumn<ESM::MagicEffect> (Columns::ColumnId_HitObject));
|
||||
mMagicEffects.addColumn (new EffectObjectColumn<ESM::MagicEffect> (Columns::ColumnId_AreaObject));
|
||||
mMagicEffects.addColumn (new EffectObjectColumn<ESM::MagicEffect> (Columns::ColumnId_BoltObject));
|
||||
mMagicEffects.addColumn (new EffectSoundColumn<ESM::MagicEffect> (Columns::ColumnId_CastingSound));
|
||||
mMagicEffects.addColumn (new EffectSoundColumn<ESM::MagicEffect> (Columns::ColumnId_HitSound));
|
||||
mMagicEffects.addColumn (new EffectSoundColumn<ESM::MagicEffect> (Columns::ColumnId_AreaSound));
|
||||
mMagicEffects.addColumn (new EffectSoundColumn<ESM::MagicEffect> (Columns::ColumnId_BoltSound));
|
||||
mMagicEffects.addColumn (new FlagColumn<ESM::MagicEffect> (
|
||||
Columns::ColumnId_AllowSpellmaking, ESM::MagicEffect::AllowSpellmaking));
|
||||
mMagicEffects.addColumn (new FlagColumn<ESM::MagicEffect> (
|
||||
Columns::ColumnId_AllowEnchanting, ESM::MagicEffect::AllowEnchanting));
|
||||
mMagicEffects.addColumn (new FlagColumn<ESM::MagicEffect> (
|
||||
Columns::ColumnId_NegativeLight, ESM::MagicEffect::NegativeLight));
|
||||
mMagicEffects.addColumn (new DescriptionColumn<ESM::MagicEffect>);
|
||||
|
||||
mPathgrids.addColumn (new StringIdColumn<Pathgrid>);
|
||||
mPathgrids.addColumn (new RecordStateColumn<Pathgrid>);
|
||||
mPathgrids.addColumn (new FixedRecordTypeColumn<Pathgrid> (UniversalId::Type_Pathgrid));
|
||||
|
||||
mRefs.addColumn (new StringIdColumn<CellRef> (true));
|
||||
mRefs.addColumn (new RecordStateColumn<CellRef>);
|
||||
|
@ -227,34 +284,66 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding)
|
|||
mRefs.addColumn (new LockLevelColumn<CellRef>);
|
||||
mRefs.addColumn (new KeyColumn<CellRef>);
|
||||
mRefs.addColumn (new TrapColumn<CellRef>);
|
||||
mRefs.addColumn (new OwnerGlobalColumn<CellRef>);
|
||||
mRefs.addColumn (new RefNumColumn<CellRef>);
|
||||
|
||||
mFilters.addColumn (new StringIdColumn<CSMFilter::Filter>);
|
||||
mFilters.addColumn (new RecordStateColumn<CSMFilter::Filter>);
|
||||
mFilters.addColumn (new FixedRecordTypeColumn<CSMFilter::Filter> (UniversalId::Type_Filter));
|
||||
mFilters.addColumn (new FilterColumn<CSMFilter::Filter>);
|
||||
mFilters.addColumn (new DescriptionColumn<CSMFilter::Filter>);
|
||||
mFilters.addColumn (new ScopeColumn<CSMFilter::Filter>);
|
||||
mFilters.addColumn (new StringIdColumn<ESM::Filter>);
|
||||
mFilters.addColumn (new RecordStateColumn<ESM::Filter>);
|
||||
mFilters.addColumn (new FixedRecordTypeColumn<ESM::Filter> (UniversalId::Type_Filter));
|
||||
mFilters.addColumn (new FilterColumn<ESM::Filter>);
|
||||
mFilters.addColumn (new DescriptionColumn<ESM::Filter>);
|
||||
|
||||
addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global);
|
||||
addModel (new IdTable (&mGmsts), UniversalId::Type_Gmsts, UniversalId::Type_Gmst);
|
||||
addModel (new IdTable (&mSkills), UniversalId::Type_Skills, UniversalId::Type_Skill, false);
|
||||
addModel (new IdTable (&mClasses), UniversalId::Type_Classes, UniversalId::Type_Class);
|
||||
addModel (new IdTable (&mFactions), UniversalId::Type_Factions, UniversalId::Type_Faction);
|
||||
addModel (new IdTable (&mRaces), UniversalId::Type_Races, UniversalId::Type_Race);
|
||||
addModel (new IdTable (&mSounds), UniversalId::Type_Sounds, UniversalId::Type_Sound);
|
||||
addModel (new IdTable (&mScripts), UniversalId::Type_Scripts, UniversalId::Type_Script);
|
||||
addModel (new IdTable (&mRegions), UniversalId::Type_Regions, UniversalId::Type_Region);
|
||||
addModel (new IdTable (&mBirthsigns), UniversalId::Type_Birthsigns, UniversalId::Type_Birthsign);
|
||||
addModel (new IdTable (&mSpells), UniversalId::Type_Spells, UniversalId::Type_Spell);
|
||||
addModel (new IdTable (&mTopics), UniversalId::Type_Topics, UniversalId::Type_Topic);
|
||||
addModel (new IdTable (&mJournals), UniversalId::Type_Journals, UniversalId::Type_Journal);
|
||||
addModel (new IdTable (&mTopicInfos, IdTable::Reordering_WithinTopic), UniversalId::Type_TopicInfos, UniversalId::Type_TopicInfo);
|
||||
addModel (new IdTable (&mJournalInfos, IdTable::Reordering_WithinTopic), UniversalId::Type_JournalInfos, UniversalId::Type_JournalInfo);
|
||||
addModel (new IdTable (&mCells, IdTable::Reordering_None, IdTable::Viewing_Id), UniversalId::Type_Cells, UniversalId::Type_Cell);
|
||||
addModel (new IdTable (&mReferenceables, IdTable::Reordering_None, IdTable::Viewing_None, true),
|
||||
UniversalId::Type_Referenceables, UniversalId::Type_Referenceable);
|
||||
addModel (new IdTable (&mRefs, IdTable::Reordering_None, IdTable::Viewing_Cell, true), UniversalId::Type_References, UniversalId::Type_Reference, false);
|
||||
addModel (new IdTable (&mFilters), UniversalId::Type_Filters, UniversalId::Type_Filter, false);
|
||||
mDebugProfiles.addColumn (new StringIdColumn<ESM::DebugProfile>);
|
||||
mDebugProfiles.addColumn (new RecordStateColumn<ESM::DebugProfile>);
|
||||
mDebugProfiles.addColumn (new FixedRecordTypeColumn<ESM::DebugProfile> (UniversalId::Type_DebugProfile));
|
||||
mDebugProfiles.addColumn (new FlagColumn2<ESM::DebugProfile> (
|
||||
Columns::ColumnId_DefaultProfile, ESM::DebugProfile::Flag_Default));
|
||||
mDebugProfiles.addColumn (new FlagColumn2<ESM::DebugProfile> (
|
||||
Columns::ColumnId_BypassNewGame, ESM::DebugProfile::Flag_BypassNewGame));
|
||||
mDebugProfiles.addColumn (new FlagColumn2<ESM::DebugProfile> (
|
||||
Columns::ColumnId_GlobalProfile, ESM::DebugProfile::Flag_Global));
|
||||
mDebugProfiles.addColumn (new DescriptionColumn<ESM::DebugProfile>);
|
||||
mDebugProfiles.addColumn (new ScriptColumn<ESM::DebugProfile> (
|
||||
ScriptColumn<ESM::DebugProfile>::Type_Lines));
|
||||
|
||||
addModel (new IdTable (&mGlobals), UniversalId::Type_Global);
|
||||
addModel (new IdTable (&mGmsts), UniversalId::Type_Gmst);
|
||||
addModel (new IdTable (&mSkills), UniversalId::Type_Skill);
|
||||
addModel (new IdTable (&mClasses), UniversalId::Type_Class);
|
||||
addModel (new IdTable (&mFactions), UniversalId::Type_Faction);
|
||||
addModel (new IdTable (&mRaces), UniversalId::Type_Race);
|
||||
addModel (new IdTable (&mSounds), UniversalId::Type_Sound);
|
||||
addModel (new IdTable (&mScripts), UniversalId::Type_Script);
|
||||
addModel (new IdTable (&mRegions), UniversalId::Type_Region);
|
||||
addModel (new IdTable (&mBirthsigns), UniversalId::Type_Birthsign);
|
||||
addModel (new IdTable (&mSpells), UniversalId::Type_Spell);
|
||||
addModel (new IdTable (&mTopics), UniversalId::Type_Topic);
|
||||
addModel (new IdTable (&mJournals), UniversalId::Type_Journal);
|
||||
addModel (new IdTable (&mTopicInfos, IdTable::Feature_ReorderWithinTopic), UniversalId::Type_TopicInfo);
|
||||
addModel (new IdTable (&mJournalInfos, IdTable::Feature_ReorderWithinTopic), UniversalId::Type_JournalInfo);
|
||||
addModel (new IdTable (&mCells, IdTable::Feature_ViewId), UniversalId::Type_Cell);
|
||||
addModel (new IdTable (&mEnchantments), UniversalId::Type_Enchantment);
|
||||
addModel (new IdTable (&mBodyParts), UniversalId::Type_BodyPart);
|
||||
addModel (new IdTable (&mSoundGens), UniversalId::Type_SoundGen);
|
||||
addModel (new IdTable (&mMagicEffects), UniversalId::Type_MagicEffect);
|
||||
addModel (new IdTable (&mPathgrids), UniversalId::Type_Pathgrid);
|
||||
addModel (new IdTable (&mReferenceables, IdTable::Feature_Preview),
|
||||
UniversalId::Type_Referenceable);
|
||||
addModel (new IdTable (&mRefs, IdTable::Feature_ViewCell | IdTable::Feature_Preview), UniversalId::Type_Reference);
|
||||
addModel (new IdTable (&mFilters), UniversalId::Type_Filter);
|
||||
addModel (new IdTable (&mDebugProfiles), UniversalId::Type_DebugProfile);
|
||||
addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Meshes)),
|
||||
UniversalId::Type_Mesh);
|
||||
addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Icons)),
|
||||
UniversalId::Type_Icon);
|
||||
addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Musics)),
|
||||
UniversalId::Type_Music);
|
||||
addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_SoundsRes)),
|
||||
UniversalId::Type_SoundRes);
|
||||
addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Textures)),
|
||||
UniversalId::Type_Texture);
|
||||
addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Videos)),
|
||||
UniversalId::Type_Video);
|
||||
}
|
||||
|
||||
CSMWorld::Data::~Data()
|
||||
|
@ -446,16 +535,91 @@ CSMWorld::RefCollection& CSMWorld::Data::getReferences()
|
|||
return mRefs;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<CSMFilter::Filter>& CSMWorld::Data::getFilters() const
|
||||
const CSMWorld::IdCollection<ESM::Filter>& CSMWorld::Data::getFilters() const
|
||||
{
|
||||
return mFilters;
|
||||
}
|
||||
|
||||
CSMWorld::IdCollection<CSMFilter::Filter>& CSMWorld::Data::getFilters()
|
||||
CSMWorld::IdCollection<ESM::Filter>& CSMWorld::Data::getFilters()
|
||||
{
|
||||
return mFilters;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<ESM::Enchantment>& CSMWorld::Data::getEnchantments() const
|
||||
{
|
||||
return mEnchantments;
|
||||
}
|
||||
|
||||
CSMWorld::IdCollection<ESM::Enchantment>& CSMWorld::Data::getEnchantments()
|
||||
{
|
||||
return mEnchantments;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<ESM::BodyPart>& CSMWorld::Data::getBodyParts() const
|
||||
{
|
||||
return mBodyParts;
|
||||
}
|
||||
|
||||
CSMWorld::IdCollection<ESM::BodyPart>& CSMWorld::Data::getBodyParts()
|
||||
{
|
||||
return mBodyParts;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<ESM::DebugProfile>& CSMWorld::Data::getDebugProfiles() const
|
||||
{
|
||||
return mDebugProfiles;
|
||||
}
|
||||
|
||||
CSMWorld::IdCollection<ESM::DebugProfile>& CSMWorld::Data::getDebugProfiles()
|
||||
{
|
||||
return mDebugProfiles;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<CSMWorld::Land>& CSMWorld::Data::getLand() const
|
||||
{
|
||||
return mLand;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<CSMWorld::LandTexture>& CSMWorld::Data::getLandTextures() const
|
||||
{
|
||||
return mLandTextures;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<ESM::SoundGenerator>& CSMWorld::Data::getSoundGens() const
|
||||
{
|
||||
return mSoundGens;
|
||||
}
|
||||
|
||||
CSMWorld::IdCollection<ESM::SoundGenerator>& CSMWorld::Data::getSoundGens()
|
||||
{
|
||||
return mSoundGens;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<ESM::MagicEffect>& CSMWorld::Data::getMagicEffects() const
|
||||
{
|
||||
return mMagicEffects;
|
||||
}
|
||||
|
||||
CSMWorld::IdCollection<ESM::MagicEffect>& CSMWorld::Data::getMagicEffects()
|
||||
{
|
||||
return mMagicEffects;
|
||||
}
|
||||
|
||||
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& CSMWorld::Data::getPathgrids() const
|
||||
{
|
||||
return mPathgrids;
|
||||
}
|
||||
|
||||
CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& CSMWorld::Data::getPathgrids()
|
||||
{
|
||||
return mPathgrids;
|
||||
}
|
||||
|
||||
const CSMWorld::Resources& CSMWorld::Data::getResources (const UniversalId& id) const
|
||||
{
|
||||
return mResourcesManager.get (id.getType());
|
||||
}
|
||||
|
||||
QAbstractItemModel *CSMWorld::Data::getTableModel (const CSMWorld::UniversalId& id)
|
||||
{
|
||||
std::map<UniversalId::Type, QAbstractItemModel *>::iterator iter = mModelIndex.find (id.getType());
|
||||
|
@ -469,8 +633,7 @@ QAbstractItemModel *CSMWorld::Data::getTableModel (const CSMWorld::UniversalId&
|
|||
if (id.getType()==UniversalId::Type_RegionMap)
|
||||
{
|
||||
RegionMap *table = 0;
|
||||
addModel (table = new RegionMap (*this), UniversalId::Type_RegionMap,
|
||||
UniversalId::Type_None, false);
|
||||
addModel (table = new RegionMap (*this), UniversalId::Type_RegionMap, false);
|
||||
return table;
|
||||
}
|
||||
throw std::logic_error ("No table model available for " + id.toString());
|
||||
|
@ -486,12 +649,17 @@ void CSMWorld::Data::merge()
|
|||
|
||||
int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base, bool project)
|
||||
{
|
||||
delete mReader;
|
||||
// Don't delete the Reader yet. Some record types store a reference to the Reader to handle on-demand loading
|
||||
boost::shared_ptr<ESM::ESMReader> ptr(mReader);
|
||||
mReaders.push_back(ptr);
|
||||
mReader = 0;
|
||||
|
||||
mDialogue = 0;
|
||||
mRefLoadCache.clear();
|
||||
|
||||
mReader = new ESM::ESMReader;
|
||||
mReader->setEncoder (&mEncoder);
|
||||
mReader->setIndex(mReaderIndex++);
|
||||
mReader->open (path.string());
|
||||
|
||||
mBase = base;
|
||||
|
@ -510,15 +678,21 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages)
|
|||
|
||||
if (!mReader->hasMoreRecs())
|
||||
{
|
||||
delete mReader;
|
||||
// Don't delete the Reader yet. Some record types store a reference to the Reader to handle on-demand loading
|
||||
boost::shared_ptr<ESM::ESMReader> ptr(mReader);
|
||||
mReaders.push_back(ptr);
|
||||
mReader = 0;
|
||||
|
||||
mDialogue = 0;
|
||||
mRefLoadCache.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
ESM::NAME n = mReader->getRecName();
|
||||
mReader->getRecHeader();
|
||||
|
||||
bool unhandledRecord = false;
|
||||
|
||||
switch (n.val)
|
||||
{
|
||||
case ESM::REC_GLOB: mGlobals.load (*mReader, mBase); break;
|
||||
|
@ -532,11 +706,22 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages)
|
|||
case ESM::REC_REGN: mRegions.load (*mReader, mBase); break;
|
||||
case ESM::REC_BSGN: mBirthsigns.load (*mReader, mBase); break;
|
||||
case ESM::REC_SPEL: mSpells.load (*mReader, mBase); break;
|
||||
case ESM::REC_ENCH: mEnchantments.load (*mReader, mBase); break;
|
||||
case ESM::REC_BODY: mBodyParts.load (*mReader, mBase); break;
|
||||
case ESM::REC_SNDG: mSoundGens.load (*mReader, mBase); break;
|
||||
case ESM::REC_MGEF: mMagicEffects.load (*mReader, mBase); break;
|
||||
case ESM::REC_PGRD: mPathgrids.load (*mReader, mBase); break;
|
||||
|
||||
case ESM::REC_LTEX: mLandTextures.load (*mReader, mBase); break;
|
||||
case ESM::REC_LAND: mLand.load(*mReader, mBase); break;
|
||||
|
||||
case ESM::REC_CELL:
|
||||
{
|
||||
mCells.load (*mReader, mBase);
|
||||
mRefs.load (*mReader, mCells.getSize()-1, mBase);
|
||||
std::string cellId = Misc::StringUtils::lowerCase (mCells.getId (mCells.getSize()-1));
|
||||
mRefs.load (*mReader, mCells.getSize()-1, mBase, mRefLoadCache[cellId], messages);
|
||||
break;
|
||||
}
|
||||
|
||||
case ESM::REC_ACTI: mReferenceables.load (*mReader, mBase, UniversalId::Type_Activator); break;
|
||||
case ESM::REC_ALCH: mReferenceables.load (*mReader, mBase, UniversalId::Type_Potion); break;
|
||||
|
@ -624,23 +809,37 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages)
|
|||
|
||||
case ESM::REC_FILT:
|
||||
|
||||
if (mProject)
|
||||
if (!mProject)
|
||||
{
|
||||
mFilters.load (*mReader, mBase);
|
||||
mFilters.setData (mFilters.getSize()-1,
|
||||
mFilters.findColumnIndex (CSMWorld::Columns::ColumnId_Scope),
|
||||
static_cast<int> (CSMFilter::Filter::Scope_Project));
|
||||
unhandledRecord = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// fall through (filter record in a content file is an error with format 0)
|
||||
mFilters.load (*mReader, mBase);
|
||||
break;
|
||||
|
||||
case ESM::REC_DBGP:
|
||||
|
||||
if (!mProject)
|
||||
{
|
||||
unhandledRecord = true;
|
||||
break;
|
||||
}
|
||||
|
||||
mDebugProfiles.load (*mReader, mBase);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
messages.push_back (std::make_pair (UniversalId::Type_None,
|
||||
"Unsupported record type: " + n.toString()));
|
||||
unhandledRecord = true;
|
||||
}
|
||||
|
||||
mReader->skipRecord();
|
||||
if (unhandledRecord)
|
||||
{
|
||||
messages.push_back (std::make_pair (UniversalId::Type_None,
|
||||
"Unsupported record type: " + n.toString()));
|
||||
|
||||
mReader->skipRecord();
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -663,6 +862,10 @@ bool CSMWorld::Data::hasId (const std::string& id) const
|
|||
getTopics().searchId (id)!=-1 ||
|
||||
getJournals().searchId (id)!=-1 ||
|
||||
getCells().searchId (id)!=-1 ||
|
||||
getEnchantments().searchId (id)!=-1 ||
|
||||
getBodyParts().searchId (id)!=-1 ||
|
||||
getSoundGens().searchId (id)!=-1 ||
|
||||
getMagicEffects().searchId (id)!=-1 ||
|
||||
getReferenceables().searchId (id)!=-1;
|
||||
}
|
||||
|
||||
|
@ -681,7 +884,14 @@ int CSMWorld::Data::count (RecordBase::State state) const
|
|||
count (state, mBirthsigns) +
|
||||
count (state, mSpells) +
|
||||
count (state, mCells) +
|
||||
count (state, mReferenceables);
|
||||
count (state, mEnchantments) +
|
||||
count (state, mBodyParts) +
|
||||
count (state, mLand) +
|
||||
count (state, mLandTextures) +
|
||||
count (state, mSoundGens) +
|
||||
count (state, mMagicEffects) +
|
||||
count (state, mReferenceables) +
|
||||
count (state, mPathgrids);
|
||||
}
|
||||
|
||||
void CSMWorld::Data::setDescription (const std::string& description)
|
||||
|
@ -721,6 +931,10 @@ std::vector<std::string> CSMWorld::Data::getIds (bool listDeleted) const
|
|||
appendIds (ids, mTopics, listDeleted);
|
||||
appendIds (ids, mJournals, listDeleted);
|
||||
appendIds (ids, mCells, listDeleted);
|
||||
appendIds (ids, mEnchantments, listDeleted);
|
||||
appendIds (ids, mBodyParts, listDeleted);
|
||||
appendIds (ids, mSoundGens, listDeleted);
|
||||
appendIds (ids, mMagicEffects, listDeleted);
|
||||
appendIds (ids, mReferenceables, listDeleted);
|
||||
|
||||
std::sort (ids.begin(), ids.end());
|
||||
|
@ -737,4 +951,4 @@ void CSMWorld::Data::dataChanged (const QModelIndex& topLeft, const QModelIndex&
|
|||
void CSMWorld::Data::rowsChanged (const QModelIndex& parent, int start, int end)
|
||||
{
|
||||
emit idListChanged();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,19 +21,27 @@
|
|||
#include <components/esm/loadbsgn.hpp>
|
||||
#include <components/esm/loadspel.hpp>
|
||||
#include <components/esm/loaddial.hpp>
|
||||
#include <components/esm/loadench.hpp>
|
||||
#include <components/esm/loadbody.hpp>
|
||||
#include <components/esm/loadsndg.hpp>
|
||||
#include <components/esm/loadmgef.hpp>
|
||||
#include <components/esm/debugprofile.hpp>
|
||||
#include <components/esm/filter.hpp>
|
||||
|
||||
#include <components/to_utf8/to_utf8.hpp>
|
||||
|
||||
#include "../filter/filter.hpp"
|
||||
|
||||
#include "../doc/stage.hpp"
|
||||
|
||||
#include "idcollection.hpp"
|
||||
#include "universalid.hpp"
|
||||
#include "cell.hpp"
|
||||
#include "land.hpp"
|
||||
#include "landtexture.hpp"
|
||||
#include "refidcollection.hpp"
|
||||
#include "refcollection.hpp"
|
||||
#include "infocollection.hpp"
|
||||
#include "pathgrid.hpp"
|
||||
#include "subcellcollection.hpp"
|
||||
|
||||
class QAbstractItemModel;
|
||||
|
||||
|
@ -45,6 +53,9 @@ namespace ESM
|
|||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class ResourcesManager;
|
||||
class Resources;
|
||||
|
||||
class Data : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -63,12 +74,21 @@ namespace CSMWorld
|
|||
IdCollection<ESM::Spell> mSpells;
|
||||
IdCollection<ESM::Dialogue> mTopics;
|
||||
IdCollection<ESM::Dialogue> mJournals;
|
||||
IdCollection<ESM::Enchantment> mEnchantments;
|
||||
IdCollection<ESM::BodyPart> mBodyParts;
|
||||
IdCollection<ESM::MagicEffect> mMagicEffects;
|
||||
SubCellCollection<Pathgrid> mPathgrids;
|
||||
IdCollection<ESM::DebugProfile> mDebugProfiles;
|
||||
IdCollection<ESM::SoundGenerator> mSoundGens;
|
||||
InfoCollection mTopicInfos;
|
||||
InfoCollection mJournalInfos;
|
||||
IdCollection<Cell> mCells;
|
||||
IdCollection<LandTexture> mLandTextures;
|
||||
IdCollection<Land> mLand;
|
||||
RefIdCollection mReferenceables;
|
||||
RefCollection mRefs;
|
||||
IdCollection<CSMFilter::Filter> mFilters;
|
||||
IdCollection<ESM::Filter> mFilters;
|
||||
const ResourcesManager& mResourcesManager;
|
||||
std::vector<QAbstractItemModel *> mModels;
|
||||
std::map<UniversalId::Type, QAbstractItemModel *> mModelIndex;
|
||||
std::string mAuthor;
|
||||
|
@ -77,13 +97,17 @@ namespace CSMWorld
|
|||
const ESM::Dialogue *mDialogue; // last loaded dialogue
|
||||
bool mBase;
|
||||
bool mProject;
|
||||
std::map<std::string, std::map<ESM::RefNum, std::string> > mRefLoadCache;
|
||||
int mReaderIndex;
|
||||
|
||||
std::vector<boost::shared_ptr<ESM::ESMReader> > mReaders;
|
||||
|
||||
// not implemented
|
||||
Data (const Data&);
|
||||
Data& operator= (const Data&);
|
||||
|
||||
void addModel (QAbstractItemModel *model, UniversalId::Type type1,
|
||||
UniversalId::Type type2 = UniversalId::Type_None, bool update = true);
|
||||
void addModel (QAbstractItemModel *model, UniversalId::Type type,
|
||||
bool update = true);
|
||||
|
||||
static void appendIds (std::vector<std::string>& ids, const CollectionBase& collection,
|
||||
bool listDeleted);
|
||||
|
@ -93,7 +117,7 @@ namespace CSMWorld
|
|||
|
||||
public:
|
||||
|
||||
Data (ToUTF8::FromType encoding);
|
||||
Data (ToUTF8::FromType encoding, const ResourcesManager& resourcesManager);
|
||||
|
||||
virtual ~Data();
|
||||
|
||||
|
@ -169,9 +193,40 @@ namespace CSMWorld
|
|||
|
||||
RefCollection& getReferences();
|
||||
|
||||
const IdCollection<CSMFilter::Filter>& getFilters() const;
|
||||
const IdCollection<ESM::Filter>& getFilters() const;
|
||||
|
||||
IdCollection<CSMFilter::Filter>& getFilters();
|
||||
IdCollection<ESM::Filter>& getFilters();
|
||||
|
||||
const IdCollection<ESM::Enchantment>& getEnchantments() const;
|
||||
|
||||
IdCollection<ESM::Enchantment>& getEnchantments();
|
||||
|
||||
const IdCollection<ESM::BodyPart>& getBodyParts() const;
|
||||
|
||||
IdCollection<ESM::BodyPart>& getBodyParts();
|
||||
|
||||
const IdCollection<ESM::DebugProfile>& getDebugProfiles() const;
|
||||
|
||||
IdCollection<ESM::DebugProfile>& getDebugProfiles();
|
||||
|
||||
const IdCollection<CSMWorld::Land>& getLand() const;
|
||||
|
||||
const IdCollection<CSMWorld::LandTexture>& getLandTextures() const;
|
||||
|
||||
const IdCollection<ESM::SoundGenerator>& getSoundGens() const;
|
||||
|
||||
IdCollection<ESM::SoundGenerator>& getSoundGens();
|
||||
|
||||
const IdCollection<ESM::MagicEffect>& getMagicEffects() const;
|
||||
|
||||
IdCollection<ESM::MagicEffect>& getMagicEffects();
|
||||
|
||||
const SubCellCollection<Pathgrid>& getPathgrids() const;
|
||||
|
||||
SubCellCollection<Pathgrid>& getPathgrids();
|
||||
|
||||
/// Throws an exception, if \a id does not match a resources list.
|
||||
const Resources& getResources (const UniversalId& id) const;
|
||||
|
||||
QAbstractItemModel *getTableModel (const UniversalId& id);
|
||||
///< If no table model is available for \a id, an exception is thrown.
|
||||
|
@ -222,4 +277,4 @@ namespace CSMWorld
|
|||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -11,11 +11,16 @@ namespace CSMWorld
|
|||
template<typename ESXRecordT, typename IdAccessorT = IdAccessor<ESXRecordT> >
|
||||
class IdCollection : public Collection<ESXRecordT, IdAccessorT>
|
||||
{
|
||||
virtual void loadRecord (ESXRecordT& record, ESM::ESMReader& reader);
|
||||
|
||||
public:
|
||||
|
||||
void load (ESM::ESMReader& reader, bool base);
|
||||
|
||||
void load (const ESXRecordT& record, bool base);
|
||||
/// \param index Index at which the record can be found.
|
||||
/// Special values: -2 index unknown, -1 record does not exist yet and therefore
|
||||
/// does not have an index
|
||||
void load (const ESXRecordT& record, bool base, int index = -2);
|
||||
|
||||
bool tryDelete (const std::string& id);
|
||||
///< Try deleting \a id. If the id does not exist or can't be deleted the call is ignored.
|
||||
|
@ -23,6 +28,13 @@ namespace CSMWorld
|
|||
/// \return Has the ID been deleted?
|
||||
};
|
||||
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
void IdCollection<ESXRecordT, IdAccessorT>::loadRecord (ESXRecordT& record,
|
||||
ESM::ESMReader& reader)
|
||||
{
|
||||
record.load (reader);
|
||||
}
|
||||
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
void IdCollection<ESXRecordT, IdAccessorT>::load (ESM::ESMReader& reader, bool base)
|
||||
{
|
||||
|
@ -56,17 +68,36 @@ namespace CSMWorld
|
|||
else
|
||||
{
|
||||
ESXRecordT record;
|
||||
IdAccessorT().getId (record) = id;
|
||||
record.load (reader);
|
||||
|
||||
load (record, base);
|
||||
int index = this->searchId (id);
|
||||
|
||||
if (index==-1)
|
||||
IdAccessorT().getId (record) = id;
|
||||
else
|
||||
{
|
||||
record = this->getRecord (index).get();
|
||||
}
|
||||
|
||||
loadRecord (record, reader);
|
||||
|
||||
if (index==-1)
|
||||
{
|
||||
std::string newId = IdAccessorT().getId(record);
|
||||
int newIndex = this->searchId(newId);
|
||||
if (newIndex != -1 && id != newId)
|
||||
index = newIndex;
|
||||
}
|
||||
|
||||
load (record, base, index);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
void IdCollection<ESXRecordT, IdAccessorT>::load (const ESXRecordT& record, bool base)
|
||||
void IdCollection<ESXRecordT, IdAccessorT>::load (const ESXRecordT& record, bool base,
|
||||
int index)
|
||||
{
|
||||
int index = this->searchId (IdAccessorT().getId (record));
|
||||
if (index==-2)
|
||||
index = this->searchId (IdAccessorT().getId (record));
|
||||
|
||||
if (index==-1)
|
||||
{
|
||||
|
|
|
@ -4,9 +4,8 @@
|
|||
#include "collectionbase.hpp"
|
||||
#include "columnbase.hpp"
|
||||
|
||||
CSMWorld::IdTable::IdTable (CollectionBase *idCollection, Reordering reordering,
|
||||
Viewing viewing, bool preview)
|
||||
: mIdCollection (idCollection), mReordering (reordering), mViewing (viewing), mPreview (preview)
|
||||
CSMWorld::IdTable::IdTable (CollectionBase *idCollection, unsigned int features)
|
||||
: IdTableBase (features), mIdCollection (idCollection)
|
||||
{}
|
||||
|
||||
CSMWorld::IdTable::~IdTable()
|
||||
|
@ -30,7 +29,7 @@ int CSMWorld::IdTable::columnCount (const QModelIndex & parent) const
|
|||
|
||||
QVariant CSMWorld::IdTable::data (const QModelIndex & index, int role) const
|
||||
{
|
||||
if (role!=Qt::DisplayRole && role!=Qt::EditRole)
|
||||
if ((role!=Qt::DisplayRole && role!=Qt::EditRole) || index.row() < 0 || index.column() < 0)
|
||||
return QVariant();
|
||||
|
||||
if (role==Qt::EditRole && !mIdCollection->getColumn (index.column()).isEditable())
|
||||
|
@ -186,27 +185,12 @@ void CSMWorld::IdTable::reorderRows (int baseIndex, const std::vector<int>& newO
|
|||
index (baseIndex+newOrder.size()-1, mIdCollection->getColumns()-1));
|
||||
}
|
||||
|
||||
CSMWorld::IdTable::Reordering CSMWorld::IdTable::getReordering() const
|
||||
{
|
||||
return mReordering;
|
||||
}
|
||||
|
||||
CSMWorld::IdTable::Viewing CSMWorld::IdTable::getViewing() const
|
||||
{
|
||||
return mViewing;
|
||||
}
|
||||
|
||||
bool CSMWorld::IdTable::hasPreview() const
|
||||
{
|
||||
return mPreview;
|
||||
}
|
||||
|
||||
std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row) const
|
||||
{
|
||||
std::string id;
|
||||
std::string hint;
|
||||
|
||||
if (mViewing==Viewing_Cell)
|
||||
if (getFeatures() & Feature_ViewCell)
|
||||
{
|
||||
int cellColumn = mIdCollection->searchColumnIndex (Columns::ColumnId_Cell);
|
||||
int idColumn = mIdCollection->searchColumnIndex (Columns::ColumnId_Id);
|
||||
|
@ -217,7 +201,7 @@ std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row)
|
|||
hint = "r:" + std::string (mIdCollection->getData (row, idColumn).toString().toUtf8().constData());
|
||||
}
|
||||
}
|
||||
else if (mViewing==Viewing_Id)
|
||||
else if (getFeatures() & Feature_ViewId)
|
||||
{
|
||||
int column = mIdCollection->searchColumnIndex (Columns::ColumnId_Id);
|
||||
|
||||
|
@ -237,7 +221,12 @@ std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row)
|
|||
return std::make_pair (UniversalId (UniversalId::Type_Scene, id), hint);
|
||||
}
|
||||
|
||||
bool CSMWorld::IdTable::isDeleted (const std::string& id) const
|
||||
{
|
||||
return getRecord (id).isDeleted();
|
||||
}
|
||||
|
||||
int CSMWorld::IdTable::getColumnId(int column) const
|
||||
{
|
||||
return mIdCollection->getColumn(column).getId();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
#include "idtablebase.hpp"
|
||||
#include "universalid.hpp"
|
||||
#include "columns.hpp"
|
||||
|
||||
|
@ -13,33 +12,13 @@ namespace CSMWorld
|
|||
class CollectionBase;
|
||||
class RecordBase;
|
||||
|
||||
class IdTable : public QAbstractItemModel
|
||||
class IdTable : public IdTableBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
enum Reordering
|
||||
{
|
||||
Reordering_None,
|
||||
Reordering_WithinTopic
|
||||
};
|
||||
|
||||
enum Viewing
|
||||
{
|
||||
Viewing_None,
|
||||
Viewing_Id, // use ID column to generate view request (ID is transformed into
|
||||
// worldspace and original ID is passed as hint with c: prefix)
|
||||
Viewing_Cell // use cell column to generate view request (cell ID is transformed
|
||||
// into worldspace and record ID is passed as hint with r: prefix)
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
CollectionBase *mIdCollection;
|
||||
Reordering mReordering;
|
||||
Viewing mViewing;
|
||||
bool mPreview;
|
||||
|
||||
// not implemented
|
||||
IdTable (const IdTable&);
|
||||
|
@ -47,8 +26,7 @@ namespace CSMWorld
|
|||
|
||||
public:
|
||||
|
||||
IdTable (CollectionBase *idCollection, Reordering reordering = Reordering_None,
|
||||
Viewing viewing = Viewing_None, bool preview = false);
|
||||
IdTable (CollectionBase *idCollection, unsigned int features = 0);
|
||||
///< The ownership of \a idCollection is not transferred.
|
||||
|
||||
virtual ~IdTable();
|
||||
|
@ -79,17 +57,17 @@ namespace CSMWorld
|
|||
const std::string& destination,
|
||||
UniversalId::Type type = UniversalId::Type_None);
|
||||
|
||||
QModelIndex getModelIndex (const std::string& id, int column) const;
|
||||
virtual QModelIndex getModelIndex (const std::string& id, int column) const;
|
||||
|
||||
void setRecord (const std::string& id, const RecordBase& record);
|
||||
///< Add record or overwrite existing recrod.
|
||||
|
||||
const RecordBase& getRecord (const std::string& id) const;
|
||||
|
||||
int searchColumnIndex (Columns::ColumnId id) const;
|
||||
virtual int searchColumnIndex (Columns::ColumnId id) const;
|
||||
///< Return index of column with the given \a id. If no such column exists, -1 is returned.
|
||||
|
||||
int findColumnIndex (Columns::ColumnId id) const;
|
||||
virtual int findColumnIndex (Columns::ColumnId id) const;
|
||||
///< Return index of column with the given \a id. If no such column exists, an exception is
|
||||
/// thrown.
|
||||
|
||||
|
@ -97,16 +75,13 @@ namespace CSMWorld
|
|||
///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices
|
||||
/// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex).
|
||||
|
||||
Reordering getReordering() const;
|
||||
|
||||
Viewing getViewing() const;
|
||||
|
||||
bool hasPreview() const;
|
||||
|
||||
std::pair<UniversalId, std::string> view (int row) const;
|
||||
virtual std::pair<UniversalId, std::string> view (int row) const;
|
||||
///< Return the UniversalId and the hint for viewing \a row. If viewing is not
|
||||
/// supported by this table, return (UniversalId::Type_None, "").
|
||||
|
||||
/// Is \a id flagged as deleted?
|
||||
virtual bool isDeleted (const std::string& id) const;
|
||||
|
||||
int getColumnId(int column) const;
|
||||
};
|
||||
}
|
||||
|
|
9
apps/opencs/model/world/idtablebase.cpp
Normal file
9
apps/opencs/model/world/idtablebase.cpp
Normal file
|
@ -0,0 +1,9 @@
|
|||
|
||||
#include "idtablebase.hpp"
|
||||
|
||||
CSMWorld::IdTableBase::IdTableBase (unsigned int features) : mFeatures (features) {}
|
||||
|
||||
unsigned int CSMWorld::IdTableBase::getFeatures() const
|
||||
{
|
||||
return mFeatures;
|
||||
}
|
67
apps/opencs/model/world/idtablebase.hpp
Normal file
67
apps/opencs/model/world/idtablebase.hpp
Normal file
|
@ -0,0 +1,67 @@
|
|||
#ifndef CSM_WOLRD_IDTABLEBASE_H
|
||||
#define CSM_WOLRD_IDTABLEBASE_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
#include "columns.hpp"
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class UniversalId;
|
||||
|
||||
class IdTableBase : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
enum Features
|
||||
{
|
||||
Feature_ReorderWithinTopic = 1,
|
||||
|
||||
/// Use ID column to generate view request (ID is transformed into
|
||||
/// worldspace and original ID is passed as hint with c: prefix).
|
||||
Feature_ViewId = 2,
|
||||
|
||||
/// Use cell column to generate view request (cell ID is transformed
|
||||
/// into worldspace and record ID is passed as hint with r: prefix).
|
||||
Feature_ViewCell = 4,
|
||||
|
||||
Feature_View = Feature_ViewId | Feature_ViewCell,
|
||||
|
||||
Feature_Preview = 8,
|
||||
|
||||
/// Table can not be modified through ordinary means.
|
||||
Feature_Constant = 16
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
unsigned int mFeatures;
|
||||
|
||||
public:
|
||||
|
||||
IdTableBase (unsigned int features);
|
||||
|
||||
virtual QModelIndex getModelIndex (const std::string& id, int column) const = 0;
|
||||
|
||||
/// Return index of column with the given \a id. If no such column exists, -1 is
|
||||
/// returned.
|
||||
virtual int searchColumnIndex (Columns::ColumnId id) const = 0;
|
||||
|
||||
/// Return index of column with the given \a id. If no such column exists, an
|
||||
/// exception is thrown.
|
||||
virtual int findColumnIndex (Columns::ColumnId id) const = 0;
|
||||
|
||||
/// Return the UniversalId and the hint for viewing \a row. If viewing is not
|
||||
/// supported by this table, return (UniversalId::Type_None, "").
|
||||
virtual std::pair<UniversalId, std::string> view (int row) const = 0;
|
||||
|
||||
/// Is \a id flagged as deleted?
|
||||
virtual bool isDeleted (const std::string& id) const = 0;
|
||||
|
||||
unsigned int getFeatures() const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include "idtable.hpp"
|
||||
#include "idtablebase.hpp"
|
||||
|
||||
void CSMWorld::IdTableProxyModel::updateColumnMap()
|
||||
{
|
||||
|
@ -13,7 +13,7 @@ void CSMWorld::IdTableProxyModel::updateColumnMap()
|
|||
{
|
||||
std::vector<int> columns = mFilter->getReferencedColumns();
|
||||
|
||||
const IdTable& table = dynamic_cast<const IdTable&> (*sourceModel());
|
||||
const IdTableBase& table = dynamic_cast<const IdTableBase&> (*sourceModel());
|
||||
|
||||
for (std::vector<int>::const_iterator iter (columns.begin()); iter!=columns.end(); ++iter)
|
||||
mColumnMap.insert (std::make_pair (*iter,
|
||||
|
@ -28,7 +28,7 @@ bool CSMWorld::IdTableProxyModel::filterAcceptsRow (int sourceRow, const QModelI
|
|||
return true;
|
||||
|
||||
return mFilter->test (
|
||||
dynamic_cast<IdTable&> (*sourceModel()), sourceRow, mColumnMap);
|
||||
dynamic_cast<IdTableBase&> (*sourceModel()), sourceRow, mColumnMap);
|
||||
}
|
||||
|
||||
CSMWorld::IdTableProxyModel::IdTableProxyModel (QObject *parent)
|
||||
|
@ -39,7 +39,7 @@ CSMWorld::IdTableProxyModel::IdTableProxyModel (QObject *parent)
|
|||
|
||||
QModelIndex CSMWorld::IdTableProxyModel::getModelIndex (const std::string& id, int column) const
|
||||
{
|
||||
return mapFromSource (dynamic_cast<IdTable&> (*sourceModel()).getModelIndex (id, column));
|
||||
return mapFromSource (dynamic_cast<IdTableBase&> (*sourceModel()).getModelIndex (id, column));
|
||||
}
|
||||
|
||||
void CSMWorld::IdTableProxyModel::setFilter (const boost::shared_ptr<CSMFilter::Node>& filter)
|
||||
|
@ -47,4 +47,9 @@ void CSMWorld::IdTableProxyModel::setFilter (const boost::shared_ptr<CSMFilter::
|
|||
mFilter = filter;
|
||||
updateColumnMap();
|
||||
invalidateFilter();
|
||||
}
|
||||
}
|
||||
|
||||
bool CSMWorld::IdTableProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
||||
{
|
||||
return QSortFilterProxyModel::lessThan(left, right);
|
||||
}
|
||||
|
|
|
@ -33,7 +33,11 @@ namespace CSMWorld
|
|||
virtual QModelIndex getModelIndex (const std::string& id, int column) const;
|
||||
|
||||
void setFilter (const boost::shared_ptr<CSMFilter::Node>& filter);
|
||||
|
||||
protected:
|
||||
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
28
apps/opencs/model/world/land.cpp
Normal file
28
apps/opencs/model/world/land.cpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#include "land.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
|
||||
Land::Land()
|
||||
{
|
||||
mLand.reset(new ESM::Land());
|
||||
}
|
||||
|
||||
void Land::load(ESM::ESMReader &esm)
|
||||
{
|
||||
mLand->load(esm);
|
||||
|
||||
std::ostringstream stream;
|
||||
stream << "#" << mLand->mX << " " << mLand->mY;
|
||||
|
||||
mId = stream.str();
|
||||
}
|
||||
|
||||
void Land::blank()
|
||||
{
|
||||
/// \todo
|
||||
}
|
||||
|
||||
}
|
29
apps/opencs/model/world/land.hpp
Normal file
29
apps/opencs/model/world/land.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef CSM_WORLD_LAND_H
|
||||
#define CSM_WORLD_LAND_H
|
||||
|
||||
#include <string>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <components/esm/loadland.hpp>
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
/// \brief Wrapper for Land record. Encodes X and Y cell index in the ID.
|
||||
///
|
||||
/// \todo Add worldspace support to the Land record.
|
||||
/// \todo Add a proper copy constructor (currently worked around using shared_ptr)
|
||||
struct Land
|
||||
{
|
||||
Land();
|
||||
|
||||
boost::shared_ptr<ESM::Land> mLand;
|
||||
|
||||
std::string mId;
|
||||
|
||||
/// Loads the metadata and ID
|
||||
void load (ESM::ESMReader &esm);
|
||||
|
||||
void blank();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
21
apps/opencs/model/world/landtexture.cpp
Normal file
21
apps/opencs/model/world/landtexture.cpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include "landtexture.hpp"
|
||||
|
||||
#include <components/esm/esmreader.hpp>
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
|
||||
void LandTexture::load(ESM::ESMReader &esm)
|
||||
{
|
||||
ESM::LandTexture::load(esm);
|
||||
|
||||
int plugin = esm.getIndex();
|
||||
|
||||
std::ostringstream stream;
|
||||
|
||||
stream << mIndex << "_" << plugin;
|
||||
|
||||
mId = stream.str();
|
||||
}
|
||||
|
||||
}
|
22
apps/opencs/model/world/landtexture.hpp
Normal file
22
apps/opencs/model/world/landtexture.hpp
Normal file
|
@ -0,0 +1,22 @@
|
|||
#ifndef CSM_WORLD_LANDTEXTURE_H
|
||||
#define CSM_WORLD_LANDTEXTURE_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <components/esm/loadltex.hpp>
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
/// \brief Wrapper for LandTexture record. Encodes mIndex and the plugin index (obtained from ESMReader)
|
||||
/// in the ID.
|
||||
///
|
||||
/// \attention The mId field of the ESM::LandTexture struct is not used.
|
||||
struct LandTexture : public ESM::LandTexture
|
||||
{
|
||||
std::string mId;
|
||||
|
||||
void load (ESM::ESMReader &esm);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
35
apps/opencs/model/world/pathgrid.cpp
Normal file
35
apps/opencs/model/world/pathgrid.cpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
|
||||
#include "pathgrid.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
void CSMWorld::Pathgrid::load (ESM::ESMReader &esm, const IdCollection<Cell>& cells)
|
||||
{
|
||||
load (esm);
|
||||
|
||||
// correct ID
|
||||
if (!mId.empty() && mId[0]!='#' && cells.searchId (mId)==-1)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
|
||||
stream << "#" << mData.mX << " " << mData.mY;
|
||||
|
||||
mId = stream.str();
|
||||
}
|
||||
}
|
||||
|
||||
void CSMWorld::Pathgrid::load (ESM::ESMReader &esm)
|
||||
{
|
||||
ESM::Pathgrid::load (esm);
|
||||
|
||||
if (mCell.empty())
|
||||
{
|
||||
std::ostringstream stream;
|
||||
|
||||
stream << "#" << mData.mX << " " << mData.mY;
|
||||
|
||||
mId = stream.str();
|
||||
}
|
||||
else
|
||||
mId = mCell;
|
||||
}
|
28
apps/opencs/model/world/pathgrid.hpp
Normal file
28
apps/opencs/model/world/pathgrid.hpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef CSM_WOLRD_PATHGRID_H
|
||||
#define CSM_WOLRD_PATHGRID_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <components/esm/loadpgrd.hpp>
|
||||
|
||||
#include "idcollection.hpp"
|
||||
#include "cell.hpp"
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
/// \brief Wrapper for Pathgrid record
|
||||
///
|
||||
/// \attention The mData.mX and mData.mY fields of the ESM::Pathgrid struct are not used.
|
||||
/// Exterior cell coordinates are encoded in the pathgrid ID.
|
||||
struct Pathgrid : public ESM::Pathgrid
|
||||
{
|
||||
std::string mId;
|
||||
|
||||
void load (ESM::ESMReader &esm, const IdCollection<Cell>& cells);
|
||||
|
||||
void load (ESM::ESMReader &esm);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,12 +1,8 @@
|
|||
|
||||
#include "ref.hpp"
|
||||
|
||||
#include "cell.hpp"
|
||||
|
||||
void CSMWorld::CellRef::load (ESM::ESMReader &esm, Cell& cell, const std::string& id)
|
||||
CSMWorld::CellRef::CellRef()
|
||||
{
|
||||
mId = id;
|
||||
mCell = cell.mId;
|
||||
|
||||
cell.addRef (mId);
|
||||
mRefNum.mIndex = 0;
|
||||
mRefNum.mContentFile = 0;
|
||||
}
|
|
@ -3,11 +3,6 @@
|
|||
|
||||
#include <components/esm/cellref.hpp>
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
class ESMReader;
|
||||
}
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class Cell;
|
||||
|
@ -18,8 +13,7 @@ namespace CSMWorld
|
|||
std::string mId;
|
||||
std::string mCell;
|
||||
|
||||
void load (ESM::ESMReader &esm, Cell& cell, const std::string& id);
|
||||
///< Load cell ref and register it with \a cell.
|
||||
CellRef();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -3,12 +3,15 @@
|
|||
|
||||
#include <sstream>
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
#include "ref.hpp"
|
||||
#include "cell.hpp"
|
||||
#include "universalid.hpp"
|
||||
#include "record.hpp"
|
||||
|
||||
void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool base)
|
||||
void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool base,
|
||||
std::map<ESM::RefNum, std::string>& cache, CSMDoc::Stage::Messages& messages)
|
||||
{
|
||||
Record<Cell> cell = mCells.getRecord (cellIndex);
|
||||
|
||||
|
@ -17,19 +20,73 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
|
|||
CellRef ref;
|
||||
|
||||
bool deleted = false;
|
||||
while (cell2.getNextRef (reader, ref, deleted))
|
||||
|
||||
while (ESM::Cell::getNextRef (reader, ref, deleted))
|
||||
{
|
||||
/// \todo handle deleted and moved references
|
||||
ref.load (reader, cell2, getNewId());
|
||||
ref.mCell = cell2.mId;
|
||||
|
||||
Record<CellRef> record2;
|
||||
record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
|
||||
(base ? record2.mBase : record2.mModified) = ref;
|
||||
/// \todo handle moved references
|
||||
|
||||
appendRecord (record2);
|
||||
std::map<ESM::RefNum, std::string>::iterator iter = cache.find (ref.mRefNum);
|
||||
|
||||
if (deleted)
|
||||
{
|
||||
if (iter==cache.end())
|
||||
{
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Cell,
|
||||
mCells.getId (cellIndex));
|
||||
|
||||
messages.push_back (std::make_pair (id,
|
||||
"Attempt to delete a non-existing reference"));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
int index = getIndex (iter->second);
|
||||
|
||||
Record<CellRef> record = getRecord (index);
|
||||
|
||||
if (record.mState==RecordBase::State_BaseOnly)
|
||||
{
|
||||
removeRows (index, 1);
|
||||
cache.erase (iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
record.mState = RecordBase::State_Deleted;
|
||||
setRecord (index, record);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (iter==cache.end())
|
||||
{
|
||||
// new reference
|
||||
ref.mId = getNewId();
|
||||
|
||||
Record<CellRef> record;
|
||||
record.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
|
||||
(base ? record.mBase : record.mModified) = ref;
|
||||
|
||||
appendRecord (record);
|
||||
|
||||
cache.insert (std::make_pair (ref.mRefNum, ref.mId));
|
||||
}
|
||||
else
|
||||
{
|
||||
// old reference -> merge
|
||||
ref.mId = iter->second;
|
||||
|
||||
int index = getIndex (ref.mId);
|
||||
|
||||
Record<CellRef> record = getRecord (index);
|
||||
record.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_Modified;
|
||||
(base ? record.mBase : record.mModified) = ref;
|
||||
|
||||
setRecord (index, record);
|
||||
}
|
||||
}
|
||||
|
||||
mCells.setRecord (cellIndex, cell);
|
||||
}
|
||||
|
||||
std::string CSMWorld::RefCollection::getNewId()
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#ifndef CSM_WOLRD_REFCOLLECTION_H
|
||||
#define CSM_WOLRD_REFCOLLECTION_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "../doc/stage.hpp"
|
||||
|
||||
#include "collection.hpp"
|
||||
#include "ref.hpp"
|
||||
#include "record.hpp"
|
||||
|
@ -22,7 +26,9 @@ namespace CSMWorld
|
|||
: mCells (cells), mNextId (0)
|
||||
{}
|
||||
|
||||
void load (ESM::ESMReader& reader, int cellIndex, bool base);
|
||||
void load (ESM::ESMReader& reader, int cellIndex, bool base,
|
||||
std::map<ESM::RefNum, std::string>& cache,
|
||||
CSMDoc::Stage::Messages& messages);
|
||||
///< Load a sequence of references.
|
||||
|
||||
std::string getNewId();
|
||||
|
|
|
@ -248,6 +248,15 @@ QVariant CSMWorld::CreatureRefIdAdapter::getData (const RefIdColumn *column, con
|
|||
if (column==mColumns.mOriginal)
|
||||
return QString::fromUtf8 (record.get().mOriginal.c_str());
|
||||
|
||||
if (column==mColumns.mCombat)
|
||||
return static_cast<int> (record.get().mData.mCombat);
|
||||
|
||||
if (column==mColumns.mMagic)
|
||||
return static_cast<int> (record.get().mData.mMagic);
|
||||
|
||||
if (column==mColumns.mStealth)
|
||||
return static_cast<int> (record.get().mData.mStealth);
|
||||
|
||||
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
||||
mColumns.mFlags.find (column);
|
||||
|
||||
|
@ -271,6 +280,12 @@ void CSMWorld::CreatureRefIdAdapter::setData (const RefIdColumn *column, RefIdDa
|
|||
record.get().mScale = value.toFloat();
|
||||
else if (column==mColumns.mOriginal)
|
||||
record.get().mOriginal = value.toString().toUtf8().constData();
|
||||
else if (column==mColumns.mCombat)
|
||||
record.get().mData.mCombat = value.toInt();
|
||||
else if (column==mColumns.mMagic)
|
||||
record.get().mData.mMagic = value.toInt();
|
||||
else if (column==mColumns.mStealth)
|
||||
record.get().mData.mStealth = value.toInt();
|
||||
else
|
||||
{
|
||||
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace CSMWorld
|
|||
BaseRefIdAdapter (UniversalId::Type type, const BaseColumns& base);
|
||||
|
||||
virtual std::string getId (const RecordBase& record) const;
|
||||
|
||||
|
||||
virtual void setId (RecordBase& record, const std::string& id);
|
||||
|
||||
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
|
||||
|
@ -57,7 +57,7 @@ namespace CSMWorld
|
|||
{
|
||||
(dynamic_cast<Record<RecordT>&> (record).get().mId) = id;
|
||||
}
|
||||
|
||||
|
||||
template<typename RecordT>
|
||||
std::string BaseRefIdAdapter<RecordT>::getId (const RecordBase& record) const
|
||||
{
|
||||
|
@ -631,6 +631,9 @@ namespace CSMWorld
|
|||
const RefIdColumn *mSoul;
|
||||
const RefIdColumn *mScale;
|
||||
const RefIdColumn *mOriginal;
|
||||
const RefIdColumn *mCombat;
|
||||
const RefIdColumn *mMagic;
|
||||
const RefIdColumn *mStealth;
|
||||
|
||||
CreatureColumns (const ActorColumns& actorColumns);
|
||||
};
|
||||
|
|
|
@ -44,7 +44,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false));
|
||||
baseColumns.mId = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Modification, ColumnBase::Display_RecordState,
|
||||
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false));
|
||||
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, true, false));
|
||||
baseColumns.mModified = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_RecordType, ColumnBase::Display_RefRecordType,
|
||||
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false));
|
||||
|
@ -52,7 +52,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||
|
||||
ModelColumns modelColumns (baseColumns);
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Model, ColumnBase::Display_String));
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Model, ColumnBase::Display_Mesh));
|
||||
modelColumns.mModel = &mColumns.back();
|
||||
|
||||
NameColumns nameColumns (modelColumns);
|
||||
|
@ -64,7 +64,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||
|
||||
InventoryColumns inventoryColumns (nameColumns);
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Icon, ColumnBase::Display_String));
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Icon, ColumnBase::Display_Icon));
|
||||
inventoryColumns.mIcon = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Weight, ColumnBase::Display_Float));
|
||||
inventoryColumns.mWeight = &mColumns.back();
|
||||
|
@ -175,6 +175,15 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||
creatureColumns.mScale = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_OriginalCreature, ColumnBase::Display_String));
|
||||
creatureColumns.mOriginal = &mColumns.back();
|
||||
mColumns.push_back (
|
||||
RefIdColumn (Columns::ColumnId_CombatState, ColumnBase::Display_Integer));
|
||||
creatureColumns.mCombat = &mColumns.back();
|
||||
mColumns.push_back (
|
||||
RefIdColumn (Columns::ColumnId_MagicState, ColumnBase::Display_Integer));
|
||||
creatureColumns.mMagic = &mColumns.back();
|
||||
mColumns.push_back (
|
||||
RefIdColumn (Columns::ColumnId_StealthState, ColumnBase::Display_Integer));
|
||||
creatureColumns.mStealth = &mColumns.back();
|
||||
|
||||
static const struct
|
||||
{
|
||||
|
@ -304,10 +313,17 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||
mColumns.push_back (RefIdColumn (Columns::ColumnId_WeaponReach, ColumnBase::Display_Float));
|
||||
weaponColumns.mReach = &mColumns.back();
|
||||
|
||||
for (int i=0; i<6; ++i)
|
||||
for (int i=0; i<3; ++i)
|
||||
{
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_MinChop + i, ColumnBase::Display_Integer));
|
||||
weaponColumns.mChop[i] = &mColumns.back();
|
||||
const RefIdColumn **column =
|
||||
i==0 ? weaponColumns.mChop : (i==1 ? weaponColumns.mSlash : weaponColumns.mThrust);
|
||||
|
||||
for (int j=0; j<2; ++j)
|
||||
{
|
||||
mColumns.push_back (
|
||||
RefIdColumn (Columns::ColumnId_MinChop+i*2+j, ColumnBase::Display_Integer));
|
||||
column[j] = &mColumns.back();
|
||||
}
|
||||
}
|
||||
|
||||
static const struct
|
||||
|
|
103
apps/opencs/model/world/resources.cpp
Normal file
103
apps/opencs/model/world/resources.cpp
Normal file
|
@ -0,0 +1,103 @@
|
|||
|
||||
#include "resources.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <OgreResourceGroupManager.h>
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
CSMWorld::Resources::Resources (const std::string& baseDirectory, UniversalId::Type type,
|
||||
const char * const *extensions)
|
||||
: mBaseDirectory (baseDirectory), mType (type)
|
||||
{
|
||||
int baseSize = mBaseDirectory.size();
|
||||
|
||||
Ogre::StringVector resourcesGroups =
|
||||
Ogre::ResourceGroupManager::getSingleton().getResourceGroups();
|
||||
|
||||
for (Ogre::StringVector::iterator iter (resourcesGroups.begin());
|
||||
iter!=resourcesGroups.end(); ++iter)
|
||||
{
|
||||
if (*iter=="General" || *iter=="Internal" || *iter=="Autodetect")
|
||||
continue;
|
||||
|
||||
Ogre::StringVectorPtr resources =
|
||||
Ogre::ResourceGroupManager::getSingleton().listResourceNames (*iter);
|
||||
|
||||
for (Ogre::StringVector::const_iterator iter (resources->begin());
|
||||
iter!=resources->end(); ++iter)
|
||||
{
|
||||
if (static_cast<int> (iter->size())<baseSize+1 ||
|
||||
iter->substr (0, baseSize)!=mBaseDirectory ||
|
||||
((*iter)[baseSize]!='/' && (*iter)[baseSize]!='\\'))
|
||||
continue;
|
||||
|
||||
if (extensions)
|
||||
{
|
||||
std::string::size_type index = iter->find_last_of ('.');
|
||||
|
||||
if (index==std::string::npos)
|
||||
continue;
|
||||
|
||||
std::string extension = iter->substr (index+1);
|
||||
|
||||
int i = 0;
|
||||
|
||||
for (; extensions[i]; ++i)
|
||||
if (extensions[i]==extension)
|
||||
break;
|
||||
|
||||
if (!extensions[i])
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string file = iter->substr (baseSize+1);
|
||||
mFiles.push_back (file);
|
||||
mIndex.insert (std::make_pair (file, static_cast<int> (mFiles.size())-1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int CSMWorld::Resources::getSize() const
|
||||
{
|
||||
return mFiles.size();
|
||||
}
|
||||
|
||||
std::string CSMWorld::Resources::getId (int index) const
|
||||
{
|
||||
return mFiles.at (index);
|
||||
}
|
||||
|
||||
int CSMWorld::Resources::getIndex (const std::string& id) const
|
||||
{
|
||||
int index = searchId (id);
|
||||
|
||||
if (index==-1)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << "Invalid resource: " << mBaseDirectory << '/' << id;
|
||||
|
||||
throw std::runtime_error (stream.str().c_str());
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
int CSMWorld::Resources::searchId (const std::string& id) const
|
||||
{
|
||||
std::string id2 = Misc::StringUtils::lowerCase (id);
|
||||
|
||||
std::map<std::string, int>::const_iterator iter = mIndex.find (id2);
|
||||
|
||||
if (iter==mIndex.end())
|
||||
return -1;
|
||||
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
CSMWorld::UniversalId::Type CSMWorld::Resources::getType() const
|
||||
{
|
||||
return mType;
|
||||
}
|
37
apps/opencs/model/world/resources.hpp
Normal file
37
apps/opencs/model/world/resources.hpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
#ifndef CSM_WOLRD_RESOURCES_H
|
||||
#define CSM_WOLRD_RESOURCES_H
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "universalid.hpp"
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class Resources
|
||||
{
|
||||
std::map<std::string, int> mIndex;
|
||||
std::vector<std::string> mFiles;
|
||||
std::string mBaseDirectory;
|
||||
UniversalId::Type mType;
|
||||
|
||||
public:
|
||||
|
||||
/// \param type Type of resources in this table.
|
||||
Resources (const std::string& baseDirectory, UniversalId::Type type,
|
||||
const char * const *extensions = 0);
|
||||
|
||||
int getSize() const;
|
||||
|
||||
std::string getId (int index) const;
|
||||
|
||||
int getIndex (const std::string& id) const;
|
||||
|
||||
int searchId (const std::string& id) const;
|
||||
|
||||
UniversalId::Type getType() const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue