mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-26 18:35:20 +00:00
Merge branch 'master' into ref
This commit is contained in:
commit
4986b7d65d
@ -14,9 +14,8 @@ before_install:
|
|||||||
- sudo apt-get install -qq libboost-all-dev libgtest-dev google-mock libzzip-dev
|
- sudo apt-get install -qq libboost-all-dev libgtest-dev google-mock libzzip-dev
|
||||||
- sudo apt-get install -qq libqt4-dev libxaw7-dev libxrandr-dev libfreeimage-dev libpng-dev
|
- sudo apt-get install -qq libqt4-dev libxaw7-dev libxrandr-dev libfreeimage-dev libpng-dev
|
||||||
- sudo apt-get install -qq libopenal-dev libmpg123-dev libsndfile1-dev
|
- sudo apt-get install -qq libopenal-dev libmpg123-dev libsndfile1-dev
|
||||||
- sudo apt-get install -qq libcg nvidia-cg-toolkit
|
|
||||||
- sudo apt-get install -qq libavcodec-dev libavformat-dev libavdevice-dev libavutil-dev libswscale-dev libpostproc-dev
|
- sudo apt-get install -qq libavcodec-dev libavformat-dev libavdevice-dev libavutil-dev libswscale-dev libpostproc-dev
|
||||||
- sudo apt-get install -qq libois-dev libbullet-dev libogre-static-dev libmygui-static-dev
|
- sudo apt-get install -qq libbullet-dev libogre-static-dev libmygui-static-dev libsdl2-static-dev
|
||||||
- sudo mkdir /usr/src/gtest/build
|
- sudo mkdir /usr/src/gtest/build
|
||||||
- cd /usr/src/gtest/build
|
- cd /usr/src/gtest/build
|
||||||
- sudo cmake .. -DBUILD_SHARED_LIBS=1
|
- sudo cmake .. -DBUILD_SHARED_LIBS=1
|
||||||
@ -27,7 +26,7 @@ before_script:
|
|||||||
- cd -
|
- cd -
|
||||||
- mkdir build
|
- mkdir build
|
||||||
- cd build
|
- cd build
|
||||||
- cmake .. -DOGRE_STATIC=1 -DMYGUI_STATIC=1 -DBUILD_WITH_CODE_COVERAGE=1 -DBUILD_UNITTESTS=1
|
- cmake .. -DOGRE_STATIC=1 -DMYGUI_STATIC=1 -DBOOST_STATIC=1 -DSDL2_STATIC=1 -DBUILD_WITH_CODE_COVERAGE=1 -DBUILD_UNITTESTS=1
|
||||||
script:
|
script:
|
||||||
- make -j4
|
- make -j4
|
||||||
after_script:
|
after_script:
|
||||||
|
@ -4,6 +4,10 @@ if (APPLE)
|
|||||||
set(APP_BUNDLE_NAME "${CMAKE_PROJECT_NAME}.app")
|
set(APP_BUNDLE_NAME "${CMAKE_PROJECT_NAME}.app")
|
||||||
|
|
||||||
set(APP_BUNDLE_DIR "${OpenMW_BINARY_DIR}/${APP_BUNDLE_NAME}")
|
set(APP_BUNDLE_DIR "${OpenMW_BINARY_DIR}/${APP_BUNDLE_NAME}")
|
||||||
|
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "-F /Library/Frameworks")
|
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS "-F /Library/Frameworks")
|
||||||
|
set(CMAKE_MODULE_LINKER_FLAGS "-F /Library/Frameworks")
|
||||||
endif (APPLE)
|
endif (APPLE)
|
||||||
|
|
||||||
# Macros
|
# Macros
|
||||||
@ -15,7 +19,7 @@ include (OpenMWMacros)
|
|||||||
# Version
|
# Version
|
||||||
|
|
||||||
set (OPENMW_VERSION_MAJOR 0)
|
set (OPENMW_VERSION_MAJOR 0)
|
||||||
set (OPENMW_VERSION_MINOR 23)
|
set (OPENMW_VERSION_MINOR 24)
|
||||||
set (OPENMW_VERSION_RELEASE 0)
|
set (OPENMW_VERSION_RELEASE 0)
|
||||||
|
|
||||||
set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
|
set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
|
||||||
@ -27,6 +31,7 @@ configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_
|
|||||||
option(MYGUI_STATIC "Link static build of Mygui into the binaries" FALSE)
|
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)
|
option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binaries" FALSE)
|
||||||
option(BOOST_STATIC "Link static build of Boost into the binaries" FALSE)
|
option(BOOST_STATIC "Link static build of Boost into the binaries" FALSE)
|
||||||
|
option(SDL2_STATIC "Link static build of SDL into the binaries" FALSE)
|
||||||
|
|
||||||
# Apps and tools
|
# Apps and tools
|
||||||
option(BUILD_BSATOOL "build BSA extractor" OFF)
|
option(BUILD_BSATOOL "build BSA extractor" OFF)
|
||||||
@ -77,7 +82,13 @@ set(OENGINE_OGRE
|
|||||||
${LIBDIR}/openengine/ogre/fader.cpp
|
${LIBDIR}/openengine/ogre/fader.cpp
|
||||||
${LIBDIR}/openengine/ogre/particles.cpp
|
${LIBDIR}/openengine/ogre/particles.cpp
|
||||||
${LIBDIR}/openengine/ogre/selectionbuffer.cpp
|
${LIBDIR}/openengine/ogre/selectionbuffer.cpp
|
||||||
|
${LIBDIR}/openengine/ogre/imagerotate.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
set(OENGINE_OGRE ${OENGINE_OGRE} ${LIBDIR}/openengine/ogre/osx_utils.mm)
|
||||||
|
endif ()
|
||||||
|
|
||||||
set(OENGINE_GUI
|
set(OENGINE_GUI
|
||||||
${LIBDIR}/openengine/gui/manager.cpp
|
${LIBDIR}/openengine/gui/manager.cpp
|
||||||
)
|
)
|
||||||
@ -181,6 +192,12 @@ if (UNIX AND NOT APPLE)
|
|||||||
find_package (Threads)
|
find_package (Threads)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
include (CheckIncludeFileCXX)
|
||||||
|
check_include_file_cxx(unordered_map HAVE_UNORDERED_MAP)
|
||||||
|
if (HAVE_UNORDERED_MAP)
|
||||||
|
add_definitions(-DHAVE_UNORDERED_MAP)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
|
||||||
set(BOOST_COMPONENTS system filesystem program_options thread date_time wave)
|
set(BOOST_COMPONENTS system filesystem program_options thread date_time wave)
|
||||||
|
|
||||||
@ -191,7 +208,7 @@ endif()
|
|||||||
find_package(OGRE REQUIRED)
|
find_package(OGRE REQUIRED)
|
||||||
find_package(MyGUI REQUIRED)
|
find_package(MyGUI REQUIRED)
|
||||||
find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
|
find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
|
||||||
find_package(OIS REQUIRED)
|
find_package(SDL2 REQUIRED)
|
||||||
find_package(OpenAL REQUIRED)
|
find_package(OpenAL REQUIRED)
|
||||||
find_package(Bullet REQUIRED)
|
find_package(Bullet REQUIRED)
|
||||||
IF(OGRE_STATIC)
|
IF(OGRE_STATIC)
|
||||||
@ -205,7 +222,8 @@ ENDIF(OGRE_STATIC)
|
|||||||
include_directories("."
|
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_PLUGIN_INCLUDE_DIRS}
|
||||||
${OGRE_Terrain_INCLUDE_DIR}
|
${OGRE_Terrain_INCLUDE_DIR}
|
||||||
${OIS_INCLUDE_DIRS} ${Boost_INCLUDE_DIR}
|
${SDL2_INCLUDE_DIR}
|
||||||
|
${Boost_INCLUDE_DIR}
|
||||||
${PLATFORM_INCLUDE_DIR}
|
${PLATFORM_INCLUDE_DIR}
|
||||||
${MYGUI_INCLUDE_DIRS}
|
${MYGUI_INCLUDE_DIRS}
|
||||||
${MYGUI_PLATFORM_INCLUDE_DIRS}
|
${MYGUI_PLATFORM_INCLUDE_DIRS}
|
||||||
@ -214,7 +232,7 @@ include_directories("."
|
|||||||
${LIBDIR}
|
${LIBDIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
link_directories(${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR} ${MYGUI_LIB_DIR})
|
link_directories(${SDL2_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR} ${MYGUI_LIB_DIR})
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
# List used Ogre plugins
|
# List used Ogre plugins
|
||||||
@ -287,9 +305,12 @@ configure_file(${OpenMW_SOURCE_DIR}/files/transparency-overrides.cfg
|
|||||||
|
|
||||||
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local
|
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local
|
||||||
"${OpenMW_BINARY_DIR}/openmw.cfg")
|
"${OpenMW_BINARY_DIR}/openmw.cfg")
|
||||||
|
|
||||||
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg
|
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg
|
||||||
"${OpenMW_BINARY_DIR}/openmw.cfg.install")
|
"${OpenMW_BINARY_DIR}/openmw.cfg.install")
|
||||||
|
|
||||||
|
configure_file(${OpenMW_SOURCE_DIR}/files/opencs.cfg
|
||||||
|
"${OpenMW_BINARY_DIR}/opencs.cfg")
|
||||||
|
|
||||||
if (NOT WIN32 AND NOT APPLE)
|
if (NOT WIN32 AND NOT APPLE)
|
||||||
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.desktop
|
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.desktop
|
||||||
@ -300,15 +321,15 @@ endif()
|
|||||||
|
|
||||||
# Compiler settings
|
# Compiler settings
|
||||||
if (CMAKE_COMPILER_IS_GNUCC)
|
if (CMAKE_COMPILER_IS_GNUCC)
|
||||||
add_definitions (-Wall -Wextra -Wno-unused-parameter -Wno-reorder -std=c++98 -pedantic -Wno-long-long)
|
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!
|
# Silence warnings in OGRE headers. Remove once OGRE got fixed!
|
||||||
add_definitions (-Wno-ignored-qualifiers)
|
SET(CMAKE_CXX_FLAGS "-Wno-ignored-qualifiers ${CMAKE_CXX_FLAGS}")
|
||||||
|
|
||||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
|
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
|
||||||
OUTPUT_VARIABLE GCC_VERSION)
|
OUTPUT_VARIABLE GCC_VERSION)
|
||||||
if ("${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6)
|
if ("${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6)
|
||||||
add_definitions (-Wno-unused-but-set-parameter)
|
SET(CMAKE_CXX_FLAGS "-Wno-unused-but-set-parameter ${CMAKE_CXX_FLAGS}")
|
||||||
endif("${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6)
|
endif("${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6)
|
||||||
endif (CMAKE_COMPILER_IS_GNUCC)
|
endif (CMAKE_COMPILER_IS_GNUCC)
|
||||||
|
|
||||||
@ -334,6 +355,7 @@ if(DPKG_PROGRAM)
|
|||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "../etc/openmw/" RENAME "openmw.cfg" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "../etc/openmw/" RENAME "openmw.cfg" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
||||||
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/opencs.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
||||||
|
|
||||||
#Install resources
|
#Install resources
|
||||||
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "share/games/openmw/" FILE_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ COMPONENT "Resources")
|
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "share/games/openmw/" FILE_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ COMPONENT "Resources")
|
||||||
@ -349,8 +371,8 @@ if(DPKG_PROGRAM)
|
|||||||
Data files from the original game is required to run it.")
|
Data files from the original game is required to run it.")
|
||||||
SET(CPACK_DEBIAN_PACKAGE_NAME "openmw")
|
SET(CPACK_DEBIAN_PACKAGE_NAME "openmw")
|
||||||
SET(CPACK_DEBIAN_PACKAGE_VERSION "${VERSION_STRING}")
|
SET(CPACK_DEBIAN_PACKAGE_VERSION "${VERSION_STRING}")
|
||||||
SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW bsatool;Bsatool esmtool;Esmtool omwlauncher;OMWLauncher mwiniimporter;MWiniImporter")
|
SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW bsatool;Bsatool esmtool;Esmtool omwlauncher;OMWLauncher mwiniimporter;MWiniImporter")
|
||||||
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.11.2), libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libmpg123-0 (>= 1.12.1), libois-1.3.0 (>= 1.3.0), libopenal1 (>= 1:1.12.854), libsndfile1 (>= 1.0.23), libstdc++6 (>= 4.4.5), libuuid1 (>= 2.17.2), libqtgui4 (>= 4.7.0)")
|
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.11.2), libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libmpg123-0 (>= 1.12.1), libopenal1 (>= 1:1.12.854), libsndfile1 (>= 1.0.23), libstdc++6 (>= 4.4.5), libuuid1 (>= 2.17.2), libqtgui4 (>= 4.7.0)")
|
||||||
|
|
||||||
SET(CPACK_DEBIAN_PACKAGE_SECTION "Games")
|
SET(CPACK_DEBIAN_PACKAGE_SECTION "Games")
|
||||||
|
|
||||||
@ -437,6 +459,7 @@ endif(WIN32)
|
|||||||
# Extern
|
# Extern
|
||||||
add_subdirectory (extern/shiny)
|
add_subdirectory (extern/shiny)
|
||||||
add_subdirectory (extern/oics)
|
add_subdirectory (extern/oics)
|
||||||
|
add_subdirectory (extern/sdl4ogre)
|
||||||
|
|
||||||
# Components
|
# Components
|
||||||
add_subdirectory (components)
|
add_subdirectory (components)
|
||||||
@ -572,6 +595,7 @@ if (APPLE)
|
|||||||
install(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" RENAME "openmw.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
install(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" RENAME "openmw.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||||
install(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
install(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||||
install(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
install(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||||
|
install(FILES "${OpenMW_BINARY_DIR}/opencs.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||||
|
|
||||||
set(CPACK_GENERATOR "DragNDrop")
|
set(CPACK_GENERATOR "DragNDrop")
|
||||||
set(CPACK_PACKAGE_VERSION ${OPENMW_VERSION})
|
set(CPACK_PACKAGE_VERSION ${OPENMW_VERSION})
|
||||||
@ -687,6 +711,7 @@ if (NOT WIN32 AND NOT DPKG_PROGRAM AND NOT APPLE)
|
|||||||
#INSTALL(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "${SYSCONFDIR}" )
|
#INSTALL(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "${SYSCONFDIR}" )
|
||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${SYSCONFDIR}" )
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${SYSCONFDIR}" )
|
||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "${SYSCONFDIR}" )
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "${SYSCONFDIR}" )
|
||||||
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/opencs.cfg" DESTINATION "${SYSCONFDIR}" )
|
||||||
|
|
||||||
# Install resources
|
# Install resources
|
||||||
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${DATADIR}" )
|
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${DATADIR}" )
|
||||||
|
@ -17,11 +17,6 @@ target_link_libraries(esmtool
|
|||||||
components
|
components
|
||||||
)
|
)
|
||||||
|
|
||||||
#if (APPLE)
|
|
||||||
# find_library(CARBON_FRAMEWORK Carbon)
|
|
||||||
# target_link_libraries(openmw ${CARBON_FRAMEWORK})
|
|
||||||
#endif (APPLE)
|
|
||||||
|
|
||||||
if (BUILD_WITH_CODE_COVERAGE)
|
if (BUILD_WITH_CODE_COVERAGE)
|
||||||
add_definitions (--coverage)
|
add_definitions (--coverage)
|
||||||
target_link_libraries(esmtool gcov)
|
target_link_libraries(esmtool gcov)
|
||||||
|
@ -108,11 +108,26 @@ bool parseOptions (int argc, char** argv, Arguments &info)
|
|||||||
// there might be a better way to do this
|
// there might be a better way to do this
|
||||||
bpo::options_description all;
|
bpo::options_description all;
|
||||||
all.add(desc).add(hidden);
|
all.add(desc).add(hidden);
|
||||||
bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv)
|
|
||||||
.options(all).positional(p).run();
|
|
||||||
|
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
bpo::store(valid_opts, variables);
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv)
|
||||||
|
.options(all).positional(p).run();
|
||||||
|
|
||||||
|
bpo::store(valid_opts, variables);
|
||||||
|
}
|
||||||
|
catch(boost::program_options::unknown_option & x)
|
||||||
|
{
|
||||||
|
std::cerr << "ERROR: " << x.what() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch(boost::program_options::invalid_command_line_syntax & x)
|
||||||
|
{
|
||||||
|
std::cerr << "ERROR: " << x.what() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bpo::notify(variables);
|
bpo::notify(variables);
|
||||||
|
|
||||||
if (variables.count ("help"))
|
if (variables.count ("help"))
|
||||||
|
@ -90,6 +90,7 @@ target_link_libraries(omwlauncher
|
|||||||
${Boost_LIBRARIES}
|
${Boost_LIBRARIES}
|
||||||
${OGRE_LIBRARIES}
|
${OGRE_LIBRARIES}
|
||||||
${OGRE_STATIC_PLUGINS}
|
${OGRE_STATIC_PLUGINS}
|
||||||
|
${SDL2_LIBRARY}
|
||||||
${QT_LIBRARIES}
|
${QT_LIBRARIES}
|
||||||
components
|
components
|
||||||
)
|
)
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
@ -35,13 +36,14 @@ GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &g
|
|||||||
setupUi(this);
|
setupUi(this);
|
||||||
|
|
||||||
// Set the maximum res we can set in windowed mode
|
// Set the maximum res we can set in windowed mode
|
||||||
QRect res = QApplication::desktop()->screenGeometry();
|
QRect res = getMaximumResolution();
|
||||||
customWidthSpinBox->setMaximum(res.width());
|
customWidthSpinBox->setMaximum(res.width());
|
||||||
customHeightSpinBox->setMaximum(res.height());
|
customHeightSpinBox->setMaximum(res.height());
|
||||||
|
|
||||||
connect(rendererComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(rendererChanged(const QString&)));
|
connect(rendererComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(rendererChanged(const QString&)));
|
||||||
connect(fullScreenCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotFullScreenChanged(int)));
|
connect(fullScreenCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotFullScreenChanged(int)));
|
||||||
connect(standardRadioButton, SIGNAL(toggled(bool)), this, SLOT(slotStandardToggled(bool)));
|
connect(standardRadioButton, SIGNAL(toggled(bool)), this, SLOT(slotStandardToggled(bool)));
|
||||||
|
connect(screenComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(screenChanged(int)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,17 +146,41 @@ bool GraphicsPage::setupOgre()
|
|||||||
}
|
}
|
||||||
|
|
||||||
antiAliasingComboBox->clear();
|
antiAliasingComboBox->clear();
|
||||||
resolutionComboBox->clear();
|
|
||||||
antiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem));
|
antiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem));
|
||||||
resolutionComboBox->addItems(getAvailableResolutions(mSelectedRenderSystem));
|
|
||||||
|
|
||||||
// Load the rest of the values
|
|
||||||
loadSettings();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsPage::loadSettings()
|
bool GraphicsPage::setupSDL()
|
||||||
{
|
{
|
||||||
|
int displays = SDL_GetNumVideoDisplays();
|
||||||
|
|
||||||
|
if (displays < 0)
|
||||||
|
{
|
||||||
|
QMessageBox msgBox;
|
||||||
|
msgBox.setWindowTitle(tr("Error receiving number of screens"));
|
||||||
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
|
msgBox.setText(tr("<br><b>SDL_GetNumDisplayModes failed:</b><br><br>") + QString::fromStdString(SDL_GetError()) + "<br>");
|
||||||
|
msgBox.exec();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < displays; i++)
|
||||||
|
{
|
||||||
|
screenComboBox->addItem(QString(tr("Screen ")) + QString::number(i + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GraphicsPage::loadSettings()
|
||||||
|
{
|
||||||
|
if (!setupSDL())
|
||||||
|
return false;
|
||||||
|
if (!setupOgre())
|
||||||
|
return false;
|
||||||
|
|
||||||
if (mGraphicsSettings.value(QString("Video/vsync")) == QLatin1String("true"))
|
if (mGraphicsSettings.value(QString("Video/vsync")) == QLatin1String("true"))
|
||||||
vSyncCheckBox->setCheckState(Qt::Checked);
|
vSyncCheckBox->setCheckState(Qt::Checked);
|
||||||
|
|
||||||
@ -168,6 +194,9 @@ void GraphicsPage::loadSettings()
|
|||||||
QString width = mGraphicsSettings.value(QString("Video/resolution x"));
|
QString width = mGraphicsSettings.value(QString("Video/resolution x"));
|
||||||
QString height = mGraphicsSettings.value(QString("Video/resolution y"));
|
QString height = mGraphicsSettings.value(QString("Video/resolution y"));
|
||||||
QString resolution = width + QString(" x ") + height;
|
QString resolution = width + QString(" x ") + height;
|
||||||
|
QString screen = mGraphicsSettings.value(QString("Video/screen"));
|
||||||
|
|
||||||
|
screenComboBox->setCurrentIndex(screen.toInt());
|
||||||
|
|
||||||
int resIndex = resolutionComboBox->findText(resolution, Qt::MatchStartsWith);
|
int resIndex = resolutionComboBox->findText(resolution, Qt::MatchStartsWith);
|
||||||
|
|
||||||
@ -180,6 +209,8 @@ void GraphicsPage::loadSettings()
|
|||||||
customHeightSpinBox->setValue(height.toInt());
|
customHeightSpinBox->setValue(height.toInt());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsPage::saveSettings()
|
void GraphicsPage::saveSettings()
|
||||||
@ -205,6 +236,8 @@ void GraphicsPage::saveSettings()
|
|||||||
mGraphicsSettings.setValue(QString("Video/resolution x"), QString::number(customWidthSpinBox->value()));
|
mGraphicsSettings.setValue(QString("Video/resolution x"), QString::number(customWidthSpinBox->value()));
|
||||||
mGraphicsSettings.setValue(QString("Video/resolution y"), QString::number(customHeightSpinBox->value()));
|
mGraphicsSettings.setValue(QString("Video/resolution y"), QString::number(customHeightSpinBox->value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mGraphicsSettings.setValue(QString("Video/screen"), QString::number(screenComboBox->currentIndex()));
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer)
|
QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer)
|
||||||
@ -240,64 +273,83 @@ QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSy
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList GraphicsPage::getAvailableResolutions(Ogre::RenderSystem *renderer)
|
QStringList GraphicsPage::getAvailableResolutions(int screen)
|
||||||
{
|
{
|
||||||
QString key("Video Mode");
|
|
||||||
QStringList result;
|
QStringList result;
|
||||||
|
SDL_DisplayMode mode;
|
||||||
|
int modeIndex, modes = SDL_GetNumDisplayModes(screen);
|
||||||
|
|
||||||
uint row = 0;
|
if (modes < 0)
|
||||||
Ogre::ConfigOptionMap options = renderer->getConfigOptions();
|
|
||||||
|
|
||||||
for (Ogre::ConfigOptionMap::iterator i = options.begin (); i != options.end (); i++, row++)
|
|
||||||
{
|
{
|
||||||
if (key.toStdString() != i->first)
|
QMessageBox msgBox;
|
||||||
continue;
|
msgBox.setWindowTitle(tr("Error receiving resolutions"));
|
||||||
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
Ogre::StringVector::iterator opt_it;
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
uint idx = 0;
|
msgBox.setText(tr("<br><b>SDL_GetNumDisplayModes failed:</b><br><br>") + QString::fromStdString(SDL_GetError()) + "<br>");
|
||||||
|
msgBox.exec();
|
||||||
for (opt_it = i->second.possibleValues.begin ();
|
return result;
|
||||||
opt_it != i->second.possibleValues.end (); opt_it++, idx++)
|
|
||||||
{
|
|
||||||
QRegExp resolutionRe(QString("(\\d+) x (\\d+).*"));
|
|
||||||
QString resolution = QString::fromStdString(*opt_it).simplified();
|
|
||||||
|
|
||||||
if (resolutionRe.exactMatch(resolution)) {
|
|
||||||
|
|
||||||
int width = resolutionRe.cap(1).toInt();
|
|
||||||
int height = resolutionRe.cap(2).toInt();
|
|
||||||
|
|
||||||
QString aspect = getAspect(width, height);
|
|
||||||
QString cleanRes = resolutionRe.cap(1) + QString(" x ") + resolutionRe.cap(2);
|
|
||||||
|
|
||||||
if (aspect == QLatin1String("16:9") || aspect == QLatin1String("16:10")) {
|
|
||||||
cleanRes.append(tr("\t(Wide ") + aspect + ")");
|
|
||||||
|
|
||||||
} else if (aspect == QLatin1String("4:3")) {
|
|
||||||
cleanRes.append(tr("\t(Standard 4:3)"));
|
|
||||||
}
|
|
||||||
// do not add duplicate resolutions
|
|
||||||
if (!result.contains(cleanRes))
|
|
||||||
result.append(cleanRes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort the resolutions in descending order
|
for (modeIndex = 0; modeIndex < modes; modeIndex++)
|
||||||
qSort(result.begin(), result.end(), naturalSortGreaterThanCI);
|
{
|
||||||
|
if (SDL_GetDisplayMode(screen, modeIndex, &mode) < 0)
|
||||||
|
{
|
||||||
|
QMessageBox msgBox;
|
||||||
|
msgBox.setWindowTitle(tr("Error receiving resolutions"));
|
||||||
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
|
msgBox.setText(tr("<br><b>SDL_GetDisplayMode failed:</b><br><br>") + QString::fromStdString(SDL_GetError()) + "<br>");
|
||||||
|
msgBox.exec();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString aspect = getAspect(mode.w, mode.h);
|
||||||
|
QString resolution = QString::number(mode.w) + QString(" x ") + QString::number(mode.h);
|
||||||
|
|
||||||
|
if (aspect == QLatin1String("16:9") || aspect == QLatin1String("16:10")) {
|
||||||
|
resolution.append(tr("\t(Wide ") + aspect + ")");
|
||||||
|
|
||||||
|
} else if (aspect == QLatin1String("4:3")) {
|
||||||
|
resolution.append(tr("\t(Standard 4:3)"));
|
||||||
|
}
|
||||||
|
|
||||||
|
result.append(resolution);
|
||||||
|
}
|
||||||
|
|
||||||
|
result.removeDuplicates();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRect GraphicsPage::getMaximumResolution()
|
||||||
|
{
|
||||||
|
QRect max;
|
||||||
|
int screens = QApplication::desktop()->screenCount();
|
||||||
|
for (int i = 0; i < screens; ++i)
|
||||||
|
{
|
||||||
|
QRect res = QApplication::desktop()->screenGeometry(i);
|
||||||
|
if (res.width() > max.width())
|
||||||
|
max.setWidth(res.width());
|
||||||
|
if (res.height() > max.height())
|
||||||
|
max.setHeight(res.height());
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
void GraphicsPage::rendererChanged(const QString &renderer)
|
void GraphicsPage::rendererChanged(const QString &renderer)
|
||||||
{
|
{
|
||||||
mSelectedRenderSystem = mOgre->getRenderSystemByName(renderer.toStdString());
|
mSelectedRenderSystem = mOgre->getRenderSystemByName(renderer.toStdString());
|
||||||
|
|
||||||
antiAliasingComboBox->clear();
|
antiAliasingComboBox->clear();
|
||||||
resolutionComboBox->clear();
|
|
||||||
|
|
||||||
antiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem));
|
antiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem));
|
||||||
resolutionComboBox->addItems(getAvailableResolutions(mSelectedRenderSystem));
|
}
|
||||||
|
|
||||||
|
void GraphicsPage::screenChanged(int screen)
|
||||||
|
{
|
||||||
|
if (screen >= 0) {
|
||||||
|
resolutionComboBox->clear();
|
||||||
|
resolutionComboBox->addItems(getAvailableResolutions(screen));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsPage::slotFullScreenChanged(int state)
|
void GraphicsPage::slotFullScreenChanged(int state)
|
||||||
|
@ -30,10 +30,11 @@ public:
|
|||||||
GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &graphicsSettings, QWidget *parent = 0);
|
GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &graphicsSettings, QWidget *parent = 0);
|
||||||
|
|
||||||
void saveSettings();
|
void saveSettings();
|
||||||
bool setupOgre();
|
bool loadSettings();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void rendererChanged(const QString &renderer);
|
void rendererChanged(const QString &renderer);
|
||||||
|
void screenChanged(int screen);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void slotFullScreenChanged(int state);
|
void slotFullScreenChanged(int state);
|
||||||
@ -55,10 +56,11 @@ private:
|
|||||||
GraphicsSettings &mGraphicsSettings;
|
GraphicsSettings &mGraphicsSettings;
|
||||||
|
|
||||||
QStringList getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer);
|
QStringList getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer);
|
||||||
QStringList getAvailableResolutions(Ogre::RenderSystem *renderer);
|
QStringList getAvailableResolutions(int screen);
|
||||||
|
QRect getMaximumResolution();
|
||||||
void loadSettings();
|
|
||||||
|
|
||||||
|
bool setupOgre();
|
||||||
|
bool setupSDL();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,11 +1,23 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QTextCodec>
|
#include <QTextCodec>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
#include "maindialog.hpp"
|
#include "maindialog.hpp"
|
||||||
|
// SDL workaround
|
||||||
|
#include "graphicspage.hpp"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software");
|
||||||
|
if (SDL_Init(SDL_INIT_VIDEO) != 0)
|
||||||
|
{
|
||||||
|
qDebug() << "SDL_Init failed: " << QString::fromStdString(SDL_GetError());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
// Now we make sure the current dir is set to application path
|
// Now we make sure the current dir is set to application path
|
||||||
@ -41,6 +53,8 @@ int main(int argc, char *argv[])
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return app.exec();
|
int returnValue = app.exec();
|
||||||
|
SDL_Quit();
|
||||||
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,8 +292,8 @@ bool MainDialog::setup()
|
|||||||
// Now create the pages as they need the settings
|
// Now create the pages as they need the settings
|
||||||
createPages();
|
createPages();
|
||||||
|
|
||||||
// Call this so we can exit on Ogre errors before mainwindow is shown
|
// Call this so we can exit on Ogre/SDL errors before mainwindow is shown
|
||||||
if (!mGraphicsPage->setupOgre())
|
if (!mGraphicsPage->loadSettings())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
loadSettings();
|
loadSettings();
|
||||||
@ -310,6 +310,8 @@ void MainDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous)
|
|||||||
|
|
||||||
bool MainDialog::setupLauncherSettings()
|
bool MainDialog::setupLauncherSettings()
|
||||||
{
|
{
|
||||||
|
mLauncherSettings.setMultiValueEnabled(true);
|
||||||
|
|
||||||
QString userPath = QString::fromStdString(mCfgMgr.getUserPath().string());
|
QString userPath = QString::fromStdString(mCfgMgr.getUserPath().string());
|
||||||
|
|
||||||
QStringList paths;
|
QStringList paths;
|
||||||
@ -427,6 +429,8 @@ bool MainDialog::setupGameSettings()
|
|||||||
|
|
||||||
bool MainDialog::setupGraphicsSettings()
|
bool MainDialog::setupGraphicsSettings()
|
||||||
{
|
{
|
||||||
|
mGraphicsSettings.setMultiValueEnabled(false);
|
||||||
|
|
||||||
QString userPath = QString::fromStdString(mCfgMgr.getUserPath().string());
|
QString userPath = QString::fromStdString(mCfgMgr.getUserPath().string());
|
||||||
QString globalPath = QString::fromStdString(mCfgMgr.getGlobalPath().string());
|
QString globalPath = QString::fromStdString(mCfgMgr.getGlobalPath().string());
|
||||||
|
|
||||||
@ -608,8 +612,21 @@ void MainDialog::closeEvent(QCloseEvent *event)
|
|||||||
|
|
||||||
void MainDialog::play()
|
void MainDialog::play()
|
||||||
{
|
{
|
||||||
if (!writeSettings())
|
if (!writeSettings()) {
|
||||||
qApp->quit();
|
qApp->quit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!mGameSettings.hasMaster()) {
|
||||||
|
QMessageBox msgBox;
|
||||||
|
msgBox.setWindowTitle(tr("No master file selected"));
|
||||||
|
msgBox.setIcon(QMessageBox::Warning);
|
||||||
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
|
msgBox.setText(tr("<br><b>You do not have any master files selected.</b><br><br> \
|
||||||
|
OpenMW will not start without a master file selected.<br>"));
|
||||||
|
msgBox.exec();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Launch the game detached
|
// Launch the game detached
|
||||||
startProgram(QString("openmw"), true);
|
startProgram(QString("openmw"), true);
|
||||||
|
@ -6,8 +6,6 @@
|
|||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
#include <components/files/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
|
||||||
#include <boost/version.hpp>
|
#include <boost/version.hpp>
|
||||||
@ -103,8 +101,8 @@ bool GameSettings::readFile(QTextStream &stream)
|
|||||||
|
|
||||||
if (keyRe.indexIn(line) != -1) {
|
if (keyRe.indexIn(line) != -1) {
|
||||||
|
|
||||||
QString key = keyRe.cap(1);
|
QString key = keyRe.cap(1).trimmed();
|
||||||
QString value = keyRe.cap(2);
|
QString value = keyRe.cap(2).trimmed();
|
||||||
|
|
||||||
// Don't remove existing data entries
|
// Don't remove existing data entries
|
||||||
if (key != QLatin1String("data"))
|
if (key != QLatin1String("data"))
|
||||||
|
@ -43,6 +43,7 @@ public:
|
|||||||
inline QStringList getDataDirs() { return mDataDirs; }
|
inline QStringList getDataDirs() { return mDataDirs; }
|
||||||
inline void addDataDir(const QString &dir) { if(!dir.isEmpty()) mDataDirs.append(dir); }
|
inline void addDataDir(const QString &dir) { if(!dir.isEmpty()) mDataDirs.append(dir); }
|
||||||
inline QString getDataLocal() {return mDataLocal; }
|
inline QString getDataLocal() {return mDataLocal; }
|
||||||
|
inline bool hasMaster() { return mSettings.count(QString("master")) > 0; }
|
||||||
|
|
||||||
QStringList values(const QString &key, const QStringList &defaultValues = QStringList());
|
QStringList values(const QString &key, const QStringList &defaultValues = QStringList());
|
||||||
bool readFile(QTextStream &stream);
|
bool readFile(QTextStream &stream);
|
||||||
|
@ -7,14 +7,12 @@
|
|||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
template <class Map>
|
template <class Map>
|
||||||
class SettingsBase
|
class SettingsBase
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SettingsBase() {}
|
SettingsBase() { mMultiValue = false; }
|
||||||
~SettingsBase() {}
|
~SettingsBase() {}
|
||||||
|
|
||||||
inline QString value(const QString &key, const QString &defaultValue = QString())
|
inline QString value(const QString &key, const QString &defaultValue = QString())
|
||||||
@ -36,6 +34,11 @@ public:
|
|||||||
mSettings.insertMulti(key, value);
|
mSettings.insertMulti(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void setMultiValueEnabled(bool enable)
|
||||||
|
{
|
||||||
|
mMultiValue = enable;
|
||||||
|
}
|
||||||
|
|
||||||
inline void remove(const QString &key)
|
inline void remove(const QString &key)
|
||||||
{
|
{
|
||||||
mSettings.remove(key);
|
mSettings.remove(key);
|
||||||
@ -66,8 +69,8 @@ public:
|
|||||||
|
|
||||||
if (keyRe.indexIn(line) != -1) {
|
if (keyRe.indexIn(line) != -1) {
|
||||||
|
|
||||||
QString key = keyRe.cap(1);
|
QString key = keyRe.cap(1).trimmed();
|
||||||
QString value = keyRe.cap(2);
|
QString value = keyRe.cap(2).trimmed();
|
||||||
|
|
||||||
if (!sectionPrefix.isEmpty())
|
if (!sectionPrefix.isEmpty())
|
||||||
key.prepend(sectionPrefix);
|
key.prepend(sectionPrefix);
|
||||||
@ -75,8 +78,13 @@ public:
|
|||||||
mSettings.remove(key);
|
mSettings.remove(key);
|
||||||
|
|
||||||
QStringList values = mCache.values(key);
|
QStringList values = mCache.values(key);
|
||||||
|
|
||||||
if (!values.contains(value)) {
|
if (!values.contains(value)) {
|
||||||
mCache.insertMulti(key, value);
|
if (mMultiValue) {
|
||||||
|
mCache.insertMulti(key, value);
|
||||||
|
} else {
|
||||||
|
mCache.insert(key, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,6 +102,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
Map mSettings;
|
Map mSettings;
|
||||||
Map mCache;
|
Map mCache;
|
||||||
|
|
||||||
|
bool mMultiValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SETTINGSBASE_HPP
|
#endif // SETTINGSBASE_HPP
|
||||||
|
@ -645,7 +645,7 @@ std::string MwIniImporter::numberToString(int n) {
|
|||||||
return str.str();
|
return str.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
MwIniImporter::multistrmap MwIniImporter::loadIniFile(std::string filename) {
|
MwIniImporter::multistrmap MwIniImporter::loadIniFile(const std::string& filename) const {
|
||||||
std::cout << "load ini file: " << filename << std::endl;
|
std::cout << "load ini file: " << filename << std::endl;
|
||||||
|
|
||||||
std::string section("");
|
std::string section("");
|
||||||
@ -701,7 +701,7 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(std::string filename) {
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
MwIniImporter::multistrmap MwIniImporter::loadCfgFile(std::string filename) {
|
MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const std::string& filename) {
|
||||||
std::cout << "load cfg file: " << filename << std::endl;
|
std::cout << "load cfg file: " << filename << std::endl;
|
||||||
|
|
||||||
MwIniImporter::multistrmap map;
|
MwIniImporter::multistrmap map;
|
||||||
@ -738,12 +738,11 @@ MwIniImporter::multistrmap MwIniImporter::loadCfgFile(std::string filename) {
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MwIniImporter::merge(multistrmap &cfg, multistrmap &ini) {
|
void MwIniImporter::merge(multistrmap &cfg, const multistrmap &ini) const {
|
||||||
multistrmap::iterator cfgIt;
|
multistrmap::const_iterator iniIt;
|
||||||
multistrmap::iterator iniIt;
|
for(strmap::const_iterator it=mMergeMap.begin(); it!=mMergeMap.end(); ++it) {
|
||||||
for(strmap::iterator it=mMergeMap.begin(); it!=mMergeMap.end(); ++it) {
|
|
||||||
if((iniIt = ini.find(it->second)) != ini.end()) {
|
if((iniIt = ini.find(it->second)) != ini.end()) {
|
||||||
for(std::vector<std::string>::iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); ++vc) {
|
for(std::vector<std::string>::const_iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); ++vc) {
|
||||||
cfg.erase(it->first);
|
cfg.erase(it->first);
|
||||||
insertMultistrmap(cfg, it->first, *vc);
|
insertMultistrmap(cfg, it->first, *vc);
|
||||||
}
|
}
|
||||||
@ -751,14 +750,13 @@ void MwIniImporter::merge(multistrmap &cfg, multistrmap &ini) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MwIniImporter::mergeFallback(multistrmap &cfg, multistrmap &ini) {
|
void MwIniImporter::mergeFallback(multistrmap &cfg, const multistrmap &ini) const {
|
||||||
cfg.erase("fallback");
|
cfg.erase("fallback");
|
||||||
|
|
||||||
multistrmap::iterator cfgIt;
|
multistrmap::const_iterator iniIt;
|
||||||
multistrmap::iterator iniIt;
|
for(std::vector<std::string>::const_iterator it=mMergeFallback.begin(); it!=mMergeFallback.end(); ++it) {
|
||||||
for(std::vector<std::string>::iterator it=mMergeFallback.begin(); it!=mMergeFallback.end(); ++it) {
|
|
||||||
if((iniIt = ini.find(*it)) != ini.end()) {
|
if((iniIt = ini.find(*it)) != ini.end()) {
|
||||||
for(std::vector<std::string>::iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); ++vc) {
|
for(std::vector<std::string>::const_iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); ++vc) {
|
||||||
std::string value(*it);
|
std::string value(*it);
|
||||||
std::replace( value.begin(), value.end(), ' ', '_' );
|
std::replace( value.begin(), value.end(), ' ', '_' );
|
||||||
std::replace( value.begin(), value.end(), ':', '_' );
|
std::replace( value.begin(), value.end(), ':', '_' );
|
||||||
@ -769,21 +767,21 @@ void MwIniImporter::mergeFallback(multistrmap &cfg, multistrmap &ini) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MwIniImporter::insertMultistrmap(multistrmap &cfg, std::string key, std::string value) {
|
void MwIniImporter::insertMultistrmap(multistrmap &cfg, const std::string& key, const std::string& value) {
|
||||||
multistrmap::iterator it = cfg.find(key);
|
const multistrmap::const_iterator it = cfg.find(key);
|
||||||
if(it == cfg.end()) {
|
if(it == cfg.end()) {
|
||||||
cfg.insert(std::make_pair (key, std::vector<std::string>() ));
|
cfg.insert(std::make_pair (key, std::vector<std::string>() ));
|
||||||
}
|
}
|
||||||
cfg[key].push_back(value);
|
cfg[key].push_back(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MwIniImporter::importArchives(multistrmap &cfg, multistrmap &ini) {
|
void MwIniImporter::importArchives(multistrmap &cfg, const multistrmap &ini) const {
|
||||||
std::vector<std::string> archives;
|
std::vector<std::string> archives;
|
||||||
std::string baseArchive("Archives:Archive ");
|
std::string baseArchive("Archives:Archive ");
|
||||||
std::string archive;
|
std::string archive;
|
||||||
|
|
||||||
// Search archives listed in ini file
|
// Search archives listed in ini file
|
||||||
multistrmap::iterator it = ini.begin();
|
multistrmap::const_iterator it = ini.begin();
|
||||||
for(int i=0; it != ini.end(); i++) {
|
for(int i=0; it != ini.end(); i++) {
|
||||||
archive = baseArchive;
|
archive = baseArchive;
|
||||||
archive.append(this->numberToString(i));
|
archive.append(this->numberToString(i));
|
||||||
@ -793,7 +791,7 @@ void MwIniImporter::importArchives(multistrmap &cfg, multistrmap &ini) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(std::vector<std::string>::iterator entry = it->second.begin(); entry!=it->second.end(); ++entry) {
|
for(std::vector<std::string>::const_iterator entry = it->second.begin(); entry!=it->second.end(); ++entry) {
|
||||||
archives.push_back(*entry);
|
archives.push_back(*entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -805,18 +803,18 @@ void MwIniImporter::importArchives(multistrmap &cfg, multistrmap &ini) {
|
|||||||
// does not appears in the ini file
|
// does not appears in the ini file
|
||||||
cfg["fallback-archive"].push_back("Morrowind.bsa");
|
cfg["fallback-archive"].push_back("Morrowind.bsa");
|
||||||
|
|
||||||
for(std::vector<std::string>::iterator it=archives.begin(); it!=archives.end(); ++it) {
|
for(std::vector<std::string>::const_iterator it=archives.begin(); it!=archives.end(); ++it) {
|
||||||
cfg["fallback-archive"].push_back(*it);
|
cfg["fallback-archive"].push_back(*it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MwIniImporter::importGameFiles(multistrmap &cfg, multistrmap &ini) {
|
void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini) const {
|
||||||
std::vector<std::string> esmFiles;
|
std::vector<std::string> esmFiles;
|
||||||
std::vector<std::string> espFiles;
|
std::vector<std::string> espFiles;
|
||||||
std::string baseGameFile("Game Files:GameFile");
|
std::string baseGameFile("Game Files:GameFile");
|
||||||
std::string gameFile("");
|
std::string gameFile("");
|
||||||
|
|
||||||
multistrmap::iterator it = ini.begin();
|
multistrmap::const_iterator it = ini.begin();
|
||||||
for(int i=0; it != ini.end(); i++) {
|
for(int i=0; it != ini.end(); i++) {
|
||||||
gameFile = baseGameFile;
|
gameFile = baseGameFile;
|
||||||
gameFile.append(this->numberToString(i));
|
gameFile.append(this->numberToString(i));
|
||||||
@ -826,7 +824,7 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, multistrmap &ini) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(std::vector<std::string>::iterator entry = it->second.begin(); entry!=it->second.end(); ++entry) {
|
for(std::vector<std::string>::const_iterator entry = it->second.begin(); entry!=it->second.end(); ++entry) {
|
||||||
std::string filetype(entry->substr(entry->length()-3));
|
std::string filetype(entry->substr(entry->length()-3));
|
||||||
Misc::StringUtils::toLower(filetype);
|
Misc::StringUtils::toLower(filetype);
|
||||||
|
|
||||||
@ -844,22 +842,22 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, multistrmap &ini) {
|
|||||||
cfg.erase("master");
|
cfg.erase("master");
|
||||||
cfg.insert( std::make_pair<std::string, std::vector<std::string> > ("master", std::vector<std::string>() ) );
|
cfg.insert( std::make_pair<std::string, std::vector<std::string> > ("master", std::vector<std::string>() ) );
|
||||||
|
|
||||||
for(std::vector<std::string>::iterator it=esmFiles.begin(); it!=esmFiles.end(); ++it) {
|
for(std::vector<std::string>::const_iterator it=esmFiles.begin(); it!=esmFiles.end(); ++it) {
|
||||||
cfg["master"].push_back(*it);
|
cfg["master"].push_back(*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.erase("plugin");
|
cfg.erase("plugin");
|
||||||
cfg.insert( std::make_pair<std::string, std::vector<std::string> > ("plugin", std::vector<std::string>() ) );
|
cfg.insert( std::make_pair<std::string, std::vector<std::string> > ("plugin", std::vector<std::string>() ) );
|
||||||
|
|
||||||
for(std::vector<std::string>::iterator it=espFiles.begin(); it!=espFiles.end(); ++it) {
|
for(std::vector<std::string>::const_iterator it=espFiles.begin(); it!=espFiles.end(); ++it) {
|
||||||
cfg["plugin"].push_back(*it);
|
cfg["plugin"].push_back(*it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MwIniImporter::writeToFile(boost::iostreams::stream<boost::iostreams::file_sink> &out, multistrmap &cfg) {
|
void MwIniImporter::writeToFile(boost::iostreams::stream<boost::iostreams::file_sink> &out, const multistrmap &cfg) {
|
||||||
|
|
||||||
for(multistrmap::iterator it=cfg.begin(); it != cfg.end(); ++it) {
|
for(multistrmap::const_iterator it=cfg.begin(); it != cfg.end(); ++it) {
|
||||||
for(std::vector<std::string>::iterator entry=it->second.begin(); entry != it->second.end(); ++entry) {
|
for(std::vector<std::string>::const_iterator entry=it->second.begin(); entry != it->second.end(); ++entry) {
|
||||||
out << (it->first) << "=" << (*entry) << std::endl;
|
out << (it->first) << "=" << (*entry) << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,18 +18,17 @@ class MwIniImporter {
|
|||||||
MwIniImporter();
|
MwIniImporter();
|
||||||
void setInputEncoding(const ToUTF8::FromType& encoding);
|
void setInputEncoding(const ToUTF8::FromType& encoding);
|
||||||
void setVerbose(bool verbose);
|
void setVerbose(bool verbose);
|
||||||
multistrmap loadIniFile(std::string filename);
|
multistrmap loadIniFile(const std::string& filename) const;
|
||||||
multistrmap loadCfgFile(std::string filename);
|
static multistrmap loadCfgFile(const std::string& filename);
|
||||||
void merge(multistrmap &cfg, multistrmap &ini);
|
void merge(multistrmap &cfg, const multistrmap &ini) const;
|
||||||
void mergeFallback(multistrmap &cfg, multistrmap &ini);
|
void mergeFallback(multistrmap &cfg, const multistrmap &ini) const;
|
||||||
void importGameFiles(multistrmap &cfg, multistrmap &ini);
|
void importGameFiles(multistrmap &cfg, const multistrmap &ini) const;
|
||||||
void importArchives(multistrmap &cfg, multistrmap &ini);
|
void importArchives(multistrmap &cfg, const multistrmap &ini) const;
|
||||||
void writeToFile(boost::iostreams::stream<boost::iostreams::file_sink> &out, multistrmap &cfg);
|
static void writeToFile(boost::iostreams::stream<boost::iostreams::file_sink> &out, const multistrmap &cfg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void insertMultistrmap(multistrmap &cfg, std::string key, std::string value);
|
static void insertMultistrmap(multistrmap &cfg, const std::string& key, const std::string& value);
|
||||||
std::string numberToString(int n);
|
static std::string numberToString(int n);
|
||||||
std::string toUTF8(const std::string &str);
|
|
||||||
bool mVerbose;
|
bool mVerbose;
|
||||||
strmap mMergeMap;
|
strmap mMergeMap;
|
||||||
std::vector<std::string> mMergeFallback;
|
std::vector<std::string> mMergeFallback;
|
||||||
|
@ -28,12 +28,26 @@ int main(int argc, char *argv[]) {
|
|||||||
p_desc.add("ini", 1).add("cfg", 1);
|
p_desc.add("ini", 1).add("cfg", 1);
|
||||||
|
|
||||||
bpo::variables_map vm;
|
bpo::variables_map vm;
|
||||||
bpo::parsed_options parsed = bpo::command_line_parser(argc, argv)
|
|
||||||
.options(desc)
|
|
||||||
.positional(p_desc)
|
|
||||||
.run();
|
|
||||||
|
|
||||||
bpo::store(parsed, vm);
|
try
|
||||||
|
{
|
||||||
|
bpo::parsed_options parsed = bpo::command_line_parser(argc, argv)
|
||||||
|
.options(desc)
|
||||||
|
.positional(p_desc)
|
||||||
|
.run();
|
||||||
|
|
||||||
|
bpo::store(parsed, vm);
|
||||||
|
}
|
||||||
|
catch(boost::program_options::unknown_option & x)
|
||||||
|
{
|
||||||
|
std::cerr << "ERROR: " << x.what() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch(boost::program_options::invalid_command_line_syntax & x)
|
||||||
|
{
|
||||||
|
std::cerr << "ERROR: " << x.what() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(vm.count("help") || !vm.count("ini") || !vm.count("cfg")) {
|
if(vm.count("help") || !vm.count("ini") || !vm.count("cfg")) {
|
||||||
std::cout << desc;
|
std::cout << desc;
|
||||||
@ -55,10 +69,8 @@ int main(int argc, char *argv[]) {
|
|||||||
std::cerr << "ini file does not exist" << std::endl;
|
std::cerr << "ini file does not exist" << std::endl;
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
if(!boost::filesystem::exists(cfgFile)) {
|
if(!boost::filesystem::exists(cfgFile))
|
||||||
std::cerr << "cfg file does not exist" << std::endl;
|
std::cerr << "cfg file does not exist" << std::endl;
|
||||||
return -4;
|
|
||||||
}
|
|
||||||
|
|
||||||
MwIniImporter importer;
|
MwIniImporter importer;
|
||||||
importer.setVerbose(vm.count("verbose"));
|
importer.setVerbose(vm.count("verbose"));
|
||||||
|
@ -57,11 +57,11 @@ opencs_hdrs_noqt (view/doc
|
|||||||
|
|
||||||
|
|
||||||
opencs_units (view/world
|
opencs_units (view/world
|
||||||
table tablesubview scriptsubview
|
table tablesubview scriptsubview util
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units_noqt (view/world
|
opencs_units_noqt (view/world
|
||||||
dialoguesubview util subviews enumdelegate vartypedelegate scripthighlighter
|
dialoguesubview subviews enumdelegate vartypedelegate scripthighlighter recordstatusdelegate
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -79,6 +79,7 @@ opencs_units (view/settings
|
|||||||
abstractwidget
|
abstractwidget
|
||||||
usersettingsdialog
|
usersettingsdialog
|
||||||
editorpage
|
editorpage
|
||||||
|
windowpage
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units_noqt (view/settings
|
opencs_units_noqt (view/settings
|
||||||
|
@ -61,6 +61,11 @@ void CS::Editor::setupDataFiles()
|
|||||||
QString path = QString::fromStdString(iter->string());
|
QString path = QString::fromStdString(iter->string());
|
||||||
mFileDialog.addFiles(path);
|
mFileDialog.addFiles(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//load the settings into the userSettings instance.
|
||||||
|
const QString settingFileName = "opencs.cfg";
|
||||||
|
CSMSettings::UserSettings::instance().loadSettings(settingFileName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CS::Editor::createDocument()
|
void CS::Editor::createDocument()
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "view/doc/viewmanager.hpp"
|
#include "view/doc/viewmanager.hpp"
|
||||||
#include "view/doc/startup.hpp"
|
#include "view/doc/startup.hpp"
|
||||||
#include "view/doc/filedialog.hpp"
|
#include "view/doc/filedialog.hpp"
|
||||||
|
#include "model/settings/usersettings.hpp"
|
||||||
|
|
||||||
namespace CS
|
namespace CS
|
||||||
{
|
{
|
||||||
@ -17,6 +18,7 @@ namespace CS
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
CSMSettings::UserSettings mUserSettings;
|
||||||
CSMDoc::DocumentManager mDocumentManager;
|
CSMDoc::DocumentManager mDocumentManager;
|
||||||
CSVDoc::ViewManager mViewManager;
|
CSVDoc::ViewManager mViewManager;
|
||||||
CSVDoc::StartupDialogue mStartup;
|
CSVDoc::StartupDialogue mStartup;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -52,6 +52,8 @@ namespace CSMDoc
|
|||||||
|
|
||||||
void createBase();
|
void createBase();
|
||||||
|
|
||||||
|
void addGmsts();
|
||||||
|
|
||||||
void addOptionalGmsts();
|
void addOptionalGmsts();
|
||||||
|
|
||||||
void addOptionalGlobals();
|
void addOptionalGlobals();
|
||||||
|
@ -15,21 +15,31 @@ namespace CSMSettings
|
|||||||
QStringList *mValues;
|
QStringList *mValues;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
explicit SettingContainer (QObject *parent = 0);
|
explicit SettingContainer (QObject *parent = 0);
|
||||||
explicit SettingContainer (const QString &value, QObject *parent = 0);
|
explicit SettingContainer (const QString &value, QObject *parent = 0);
|
||||||
|
|
||||||
virtual QString getName() const {return "";}
|
/// add a value to the container
|
||||||
|
/// multiple values supported
|
||||||
void insert (const QString &value);
|
void insert (const QString &value);
|
||||||
|
|
||||||
|
/// update an existing value
|
||||||
|
/// index specifies multiple values
|
||||||
void update (const QString &value, int index = 0);
|
void update (const QString &value, int index = 0);
|
||||||
|
|
||||||
|
/// return value at specified index
|
||||||
QString getValue (int index = -1) const;
|
QString getValue (int index = -1) const;
|
||||||
|
|
||||||
|
/// retrieve list of all values
|
||||||
inline QStringList *getValues() const { return mValues; }
|
inline QStringList *getValues() const { return mValues; }
|
||||||
|
|
||||||
|
/// return size of list
|
||||||
int count() const;
|
int count() const;
|
||||||
|
|
||||||
//test for empty container
|
/// test for empty container
|
||||||
//useful for default-constructed containers returned by QMap when invalid key is passed
|
/// useful for default-constructed containers returned by QMap when invalid key is passed
|
||||||
inline bool isEmpty() const { return (!mValue && !mValues); }
|
inline bool isEmpty() const { return (!mValue && !mValues); }
|
||||||
|
|
||||||
inline bool isMultiValue() const { return (mValues); }
|
inline bool isMultiValue() const { return (mValues); }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "settingsitem.hpp"
|
#include "settingsitem.hpp"
|
||||||
|
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
bool CSMSettings::SettingsItem::updateItem (const QStringList *values)
|
bool CSMSettings::SettingsItem::updateItem (const QStringList *values)
|
||||||
{
|
{
|
||||||
QStringList::ConstIterator it = values->begin();
|
QStringList::ConstIterator it = values->begin();
|
||||||
@ -66,21 +68,21 @@ bool CSMSettings::SettingsItem::updateItem(int valueListIndex)
|
|||||||
|
|
||||||
bool CSMSettings::SettingsItem::validate (const QString &value)
|
bool CSMSettings::SettingsItem::validate (const QString &value)
|
||||||
{
|
{
|
||||||
bool isValid = true;
|
//if there is no value list or value pair, there is no validation to do
|
||||||
|
bool isValid = !(!mValueList->isEmpty() || mValuePair);
|
||||||
|
|
||||||
//validation required only if a value list or min/max value pair has been provided
|
if (!isValid && !mValueList->isEmpty())
|
||||||
if (mValueList->size()>0)
|
|
||||||
{
|
{
|
||||||
for (QStringList::ConstIterator it = mValueList->begin(); it !=mValueList->end(); ++it)
|
for (QStringList::Iterator it = mValueList->begin(); it != mValueList->end(); ++it)
|
||||||
|
// foreach (QString listItem, *mValueList)
|
||||||
{
|
{
|
||||||
isValid = ( value == *it);
|
isValid = (value == *it);
|
||||||
|
|
||||||
if (isValid)
|
if (isValid)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (!isValid && mValuePair)
|
||||||
else if (mValuePair)
|
|
||||||
{
|
{
|
||||||
int numVal = value.toInt();
|
int numVal = value.toInt();
|
||||||
|
|
||||||
|
@ -7,12 +7,13 @@
|
|||||||
|
|
||||||
namespace CSMSettings
|
namespace CSMSettings
|
||||||
{
|
{
|
||||||
|
/// Represents a setting including metadata
|
||||||
|
/// (valid values, ranges, defaults, and multivalue status
|
||||||
class SettingsItem : public SettingContainer
|
class SettingsItem : public SettingContainer
|
||||||
{
|
{
|
||||||
QStringPair *mValuePair;
|
QStringPair *mValuePair;
|
||||||
QStringList *mValueList;
|
QStringList *mValueList;
|
||||||
bool mIsMultiValue;
|
bool mIsMultiValue;
|
||||||
QString mName;
|
|
||||||
QString mDefaultValue;
|
QString mDefaultValue;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -20,26 +21,41 @@ namespace CSMSettings
|
|||||||
const QString& defaultValue, QObject *parent = 0)
|
const QString& defaultValue, QObject *parent = 0)
|
||||||
: SettingContainer(defaultValue, parent),
|
: SettingContainer(defaultValue, parent),
|
||||||
mIsMultiValue (isMultiValue), mValueList (0),
|
mIsMultiValue (isMultiValue), mValueList (0),
|
||||||
mName (name), mValuePair (0), mDefaultValue (defaultValue)
|
mValuePair (0), mDefaultValue (defaultValue)
|
||||||
{}
|
{
|
||||||
|
QObject::setObjectName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// updateItem overloads for updating setting value
|
||||||
|
/// provided a list of values (multi-valued),
|
||||||
|
/// a specific value
|
||||||
|
/// or an index value corresponding to the mValueList
|
||||||
bool updateItem (const QStringList *values);
|
bool updateItem (const QStringList *values);
|
||||||
bool updateItem (const QString &value);
|
bool updateItem (const QString &value);
|
||||||
bool updateItem (int valueListIndex);
|
bool updateItem (int valueListIndex);
|
||||||
|
|
||||||
|
/// retroeve list of valid values for setting
|
||||||
inline QStringList *getValueList() { return mValueList; }
|
inline QStringList *getValueList() { return mValueList; }
|
||||||
|
|
||||||
|
/// write list of valid values for setting
|
||||||
inline void setValueList (QStringList *valueList) { mValueList = valueList; }
|
inline void setValueList (QStringList *valueList) { mValueList = valueList; }
|
||||||
|
|
||||||
|
/// valuePair used for spin boxes (max / min)
|
||||||
inline QStringPair *getValuePair() { return mValuePair; }
|
inline QStringPair *getValuePair() { return mValuePair; }
|
||||||
|
|
||||||
|
/// set value range (spinbox / integer use)
|
||||||
inline void setValuePair (QStringPair valuePair) { mValuePair = new QStringPair(valuePair); }
|
inline void setValuePair (QStringPair valuePair) { mValuePair = new QStringPair(valuePair); }
|
||||||
|
|
||||||
inline QString getName () const { return mName; }
|
|
||||||
inline bool isMultivalue () { return mIsMultiValue; }
|
inline bool isMultivalue () { return mIsMultiValue; }
|
||||||
|
|
||||||
void setDefaultValue (const QString &value);
|
void setDefaultValue (const QString &value);
|
||||||
QString getDefaultValue () const;
|
QString getDefaultValue () const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
/// Verifies that the supplied value is one of the following:
|
||||||
|
/// 1. Within the limits of the value pair (min / max)
|
||||||
|
/// 2. One of the values indicated in the value list
|
||||||
bool validate (const QString &value);
|
bool validate (const QString &value);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,13 @@
|
|||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QTextCodec>
|
#include <QTextCodec>
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
#include <components/files/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
|
||||||
#include "settingcontainer.hpp"
|
#include "settingcontainer.hpp"
|
||||||
|
|
||||||
#include <boost/version.hpp>
|
#include <boost/version.hpp>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Workaround for problems with whitespaces in paths in older versions of Boost library
|
* Workaround for problems with whitespaces in paths in older versions of Boost library
|
||||||
*/
|
*/
|
||||||
@ -29,109 +31,236 @@ namespace boost
|
|||||||
} /* namespace boost */
|
} /* namespace boost */
|
||||||
#endif /* (BOOST_VERSION <= 104600) */
|
#endif /* (BOOST_VERSION <= 104600) */
|
||||||
|
|
||||||
|
CSMSettings::UserSettings *CSMSettings::UserSettings::mUserSettingsInstance = 0;
|
||||||
|
|
||||||
CSMSettings::UserSettings::UserSettings()
|
CSMSettings::UserSettings::UserSettings()
|
||||||
{
|
{
|
||||||
|
assert(!mUserSettingsInstance);
|
||||||
mUserSettingsInstance = this;
|
mUserSettingsInstance = this;
|
||||||
|
|
||||||
|
mReadWriteMessage = QObject::tr("<br><b>Could not open or create file for writing</b><br><br> \
|
||||||
|
Please make sure you have the right permissions and try again.<br>");
|
||||||
|
|
||||||
|
mReadOnlyMessage = QObject::tr("<br><b>Could not open file for reading</b><br><br> \
|
||||||
|
Please make sure you have the right permissions and try again.<br>");
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMSettings::UserSettings::~UserSettings()
|
CSMSettings::UserSettings::~UserSettings()
|
||||||
{
|
{
|
||||||
|
mUserSettingsInstance = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
QFile *CSMSettings::UserSettings::openFile (const QString &filename)
|
QTextStream *CSMSettings::UserSettings::openFileStream (const QString &filePath, bool isReadOnly) const
|
||||||
{
|
{
|
||||||
QFile *file = new QFile(filename);
|
QIODevice::OpenMode openFlags = QIODevice::Text;
|
||||||
|
|
||||||
bool success = (file->open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)) ;
|
if (isReadOnly)
|
||||||
|
openFlags = QIODevice::ReadOnly | openFlags;
|
||||||
|
else
|
||||||
|
openFlags = QIODevice::ReadWrite | QIODevice::Truncate | openFlags;
|
||||||
|
|
||||||
if (!success)
|
QFile *file = new QFile(filePath);
|
||||||
|
QTextStream *stream = 0;
|
||||||
|
|
||||||
|
if (file->open(openFlags))
|
||||||
{
|
{
|
||||||
// File cannot be opened or created
|
stream = new QTextStream(file);
|
||||||
QMessageBox msgBox;
|
stream->setCodec(QTextCodec::codecForName("UTF-8"));
|
||||||
msgBox.setWindowTitle(QObject::tr("Error writing OpenMW configuration file"));
|
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
|
||||||
msgBox.setText(QObject::tr("<br><b>Could not open or create %0 for writing</b><br><br> \
|
|
||||||
Please make sure you have the right permissions \
|
|
||||||
and try again.<br>").arg(file->fileName()));
|
|
||||||
msgBox.exec();
|
|
||||||
delete file;
|
|
||||||
file = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return file;
|
return stream;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSMSettings::UserSettings::writeFile(QFile *file, QMap<QString, CSMSettings::SettingList *> &settings)
|
bool CSMSettings::UserSettings::writeSettings(QMap<QString, CSMSettings::SettingList *> &settings)
|
||||||
{
|
{
|
||||||
if (!file)
|
QTextStream *stream = openFileStream(mUserFilePath);
|
||||||
|
|
||||||
|
bool success = (stream);
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
QList<QString> keyList = settings.keys();
|
||||||
|
|
||||||
|
foreach (QString key, keyList)
|
||||||
|
{
|
||||||
|
SettingList *sectionSettings = settings[key];
|
||||||
|
|
||||||
|
*stream << "[" << key << "]" << '\n';
|
||||||
|
|
||||||
|
foreach (SettingContainer *item, *sectionSettings)
|
||||||
|
*stream << item->objectName() << " = " << item->getValue() << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
stream->device()->close();
|
||||||
|
delete stream;
|
||||||
|
stream = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
displayFileErrorMessage(mReadWriteMessage, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (success);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const CSMSettings::SectionMap &CSMSettings::UserSettings::getSettings() const
|
||||||
|
{
|
||||||
|
return mSectionSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSMSettings::UserSettings::loadFromFile(const QString &filePath)
|
||||||
|
{
|
||||||
|
if (filePath.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
QTextStream stream(file);
|
mSectionSettings.clear();
|
||||||
stream.setCodec(QTextCodec::codecForName("UTF-8"));
|
|
||||||
|
|
||||||
QList<QString> keyList = settings.keys();
|
QTextStream *stream = openFileStream (filePath, true);
|
||||||
|
|
||||||
foreach (QString key, keyList)
|
bool success = (stream);
|
||||||
|
|
||||||
|
if (success)
|
||||||
{
|
{
|
||||||
SettingList *sectionSettings = settings[key];
|
//looks for a square bracket, "'\\["
|
||||||
|
//that has one or more "not nothing" in it, "([^]]+)"
|
||||||
|
//and is closed with a square bracket, "\\]"
|
||||||
|
|
||||||
stream << "[" << key << "]" << '\n';
|
QRegExp sectionRe("^\\[([^]]+)\\]");
|
||||||
|
|
||||||
foreach (SettingContainer *item, *sectionSettings)
|
//Find any character(s) that is/are not equal sign(s), "[^=]+"
|
||||||
stream << item->getName() << " = " << item->getValue() << '\n';
|
//followed by an optional whitespace, an equal sign, and another optional whitespace, "\\s*=\\s*"
|
||||||
|
//and one or more periods, "(.+)"
|
||||||
|
|
||||||
|
QRegExp keyRe("^([^=]+)\\s*=\\s*(.+)$");
|
||||||
|
|
||||||
|
CSMSettings::SettingMap *settings = 0;
|
||||||
|
QString section = "none";
|
||||||
|
|
||||||
|
while (!stream->atEnd())
|
||||||
|
{
|
||||||
|
QString line = stream->readLine().simplified();
|
||||||
|
|
||||||
|
if (line.isEmpty() || line.startsWith("#"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
//if a section is found, push it onto a new QStringList
|
||||||
|
//and push the QStringList onto
|
||||||
|
if (sectionRe.exactMatch(line))
|
||||||
|
{
|
||||||
|
//add the previous section's settings to the member map
|
||||||
|
if (settings)
|
||||||
|
mSectionSettings.insert(section, settings);
|
||||||
|
|
||||||
|
//save new section and create a new list
|
||||||
|
section = sectionRe.cap(1);
|
||||||
|
settings = new SettingMap;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyRe.indexIn(line) != -1)
|
||||||
|
{
|
||||||
|
SettingContainer *sc = new SettingContainer (keyRe.cap(2).simplified());
|
||||||
|
sc->setObjectName(keyRe.cap(1).simplified());
|
||||||
|
(*settings)[keyRe.cap(1).simplified()] = sc;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
mSectionSettings.insert(section, settings);
|
||||||
|
|
||||||
|
stream->device()->close();
|
||||||
|
delete stream;
|
||||||
|
stream = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
file->close();
|
return success;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMSettings::UserSettings::getSettings(QTextStream &stream, SectionMap §ions)
|
void CSMSettings::UserSettings::loadSettings (const QString &fileName)
|
||||||
{
|
{
|
||||||
//looks for a square bracket, "'\\["
|
//global
|
||||||
//that has one or more "not nothing" in it, "([^]]+)"
|
QString globalFilePath = QString::fromStdString(mCfgMgr.getGlobalPath().string()) + fileName;
|
||||||
//and is closed with a square bracket, "\\]"
|
bool globalOk = loadFromFile(globalFilePath);
|
||||||
|
|
||||||
QRegExp sectionRe("^\\[([^]]+)\\]");
|
|
||||||
|
|
||||||
//Find any character(s) that is/are not equal sign(s), "[^=]+"
|
//local
|
||||||
//followed by an optional whitespace, an equal sign, and another optional whirespace, "\\s*=\\s*"
|
QString localFilePath = QString::fromStdString(mCfgMgr.getLocalPath().string()) + fileName;
|
||||||
//and one or more periods, "(.+)"
|
bool localOk = loadFromFile(localFilePath);
|
||||||
|
|
||||||
QRegExp keyRe("^([^=]+)\\s*=\\s*(.+)$");
|
//user
|
||||||
|
mUserFilePath = QString::fromStdString(mCfgMgr.getUserPath().string()) + fileName;
|
||||||
|
loadFromFile(mUserFilePath);
|
||||||
|
|
||||||
CSMSettings::SettingMap *settings = 0;
|
if (!(localOk || globalOk))
|
||||||
QString section = "none";
|
|
||||||
|
|
||||||
while (!stream.atEnd())
|
|
||||||
{
|
{
|
||||||
QString line = stream.readLine().simplified();
|
QString message = QObject::tr("<br><b>Could not open user settings files for reading</b><br><br> \
|
||||||
|
Global and local settings files could not be read.\
|
||||||
|
You may have incorrect file permissions or the OpenCS installation may be corrupted.<br>");
|
||||||
|
|
||||||
if (line.isEmpty() || line.startsWith("#"))
|
message += QObject::tr("<br>Global filepath: ") + globalFilePath;
|
||||||
continue;
|
message += QObject::tr("<br>Local filepath: ") + localFilePath;
|
||||||
|
|
||||||
//if a section is found, push it onto a new QStringList
|
|
||||||
//and push the QStringList onto
|
|
||||||
if (sectionRe.exactMatch(line))
|
|
||||||
{
|
|
||||||
//add the previous section's settings to the member map
|
|
||||||
if (settings)
|
|
||||||
sections.insert(section, settings);
|
|
||||||
|
|
||||||
//save new section and create a new list
|
|
||||||
section = sectionRe.cap(1);
|
|
||||||
settings = new SettingMap;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keyRe.indexIn(line) != -1)
|
|
||||||
{
|
|
||||||
SettingContainer *sc = new SettingContainer (keyRe.cap(2).simplified());
|
|
||||||
(*settings)[keyRe.cap(1).simplified()] = sc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
displayFileErrorMessage ( message, true);
|
||||||
}
|
}
|
||||||
sections.insert(section, settings);
|
}
|
||||||
|
|
||||||
|
void CSMSettings::UserSettings::updateSettings (const QString §ionName, const QString &settingName)
|
||||||
|
{
|
||||||
|
if (mSectionSettings.find(sectionName) == mSectionSettings.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
SettingMap *settings = mSectionSettings.value(sectionName);
|
||||||
|
|
||||||
|
if (settingName.isEmpty())
|
||||||
|
{
|
||||||
|
foreach (const SettingContainer *setting, *settings)
|
||||||
|
emit signalUpdateEditorSetting (setting->objectName(), setting->getValue());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (settings->find(settingName) != settings->end())
|
||||||
|
{
|
||||||
|
const SettingContainer *setting = settings->value(settingName);
|
||||||
|
emit signalUpdateEditorSetting (setting->objectName(), setting->getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CSMSettings::UserSettings::getSetting (const QString §ion, const QString &setting) const
|
||||||
|
{
|
||||||
|
QString retVal = "";
|
||||||
|
|
||||||
|
if (mSectionSettings.find(section) != mSectionSettings.end())
|
||||||
|
{
|
||||||
|
CSMSettings::SettingMap *settings = mSectionSettings.value(section);
|
||||||
|
|
||||||
|
if (settings->find(setting) != settings->end())
|
||||||
|
retVal = settings->value(setting)->getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMSettings::UserSettings& CSMSettings::UserSettings::instance()
|
||||||
|
{
|
||||||
|
assert(mUserSettingsInstance);
|
||||||
|
return *mUserSettingsInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMSettings::UserSettings::displayFileErrorMessage(const QString &message, bool isReadOnly)
|
||||||
|
{
|
||||||
|
// File cannot be opened or created
|
||||||
|
QMessageBox msgBox;
|
||||||
|
msgBox.setWindowTitle(QObject::tr("OpenCS configuration file I/O error"));
|
||||||
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
|
|
||||||
|
if (!isReadOnly)
|
||||||
|
msgBox.setText (mReadWriteMessage + message);
|
||||||
|
else
|
||||||
|
msgBox.setText (message);
|
||||||
|
|
||||||
|
msgBox.exec();
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,10 @@
|
|||||||
|
|
||||||
#include "support.hpp"
|
#include "support.hpp"
|
||||||
|
|
||||||
|
#ifndef Q_MOC_RUN
|
||||||
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Files { typedef std::vector<boost::filesystem::path> PathContainer;
|
namespace Files { typedef std::vector<boost::filesystem::path> PathContainer;
|
||||||
struct ConfigurationManager;}
|
struct ConfigurationManager;}
|
||||||
|
|
||||||
@ -22,29 +26,56 @@ namespace CSMSettings {
|
|||||||
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
SectionMap mSectionSettings;
|
||||||
|
static UserSettings *mUserSettingsInstance;
|
||||||
|
QString mUserFilePath;
|
||||||
|
Files::ConfigurationManager mCfgMgr;
|
||||||
|
QString mReadOnlyMessage;
|
||||||
|
QString mReadWriteMessage;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static UserSettings &instance()
|
/// Singleton implementation
|
||||||
{
|
static UserSettings& instance();
|
||||||
static UserSettings instance;
|
|
||||||
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFile *openFile (const QString &);
|
|
||||||
bool writeFile(QFile *file, QMap<QString, SettingList *> §ions);
|
|
||||||
void getSettings (QTextStream &stream, SectionMap &settings);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
UserSettings *mUserSettingsInstance;
|
|
||||||
UserSettings();
|
UserSettings();
|
||||||
~UserSettings();
|
~UserSettings();
|
||||||
|
|
||||||
UserSettings (UserSettings const &); //not implemented
|
UserSettings (UserSettings const &); //not implemented
|
||||||
void operator= (UserSettings const &); //not implemented
|
void operator= (UserSettings const &); //not implemented
|
||||||
|
|
||||||
|
/// Writes settings to the last loaded settings file
|
||||||
|
bool writeSettings(QMap<QString, SettingList *> §ions);
|
||||||
|
|
||||||
|
/// Called from editor to trigger signal to update the specified setting.
|
||||||
|
/// If no setting name is specified, all settings found in the specified section are updated.
|
||||||
|
void updateSettings (const QString §ionName, const QString &settingName = "");
|
||||||
|
|
||||||
|
/// Retrieves the settings file at all three levels (global, local and user).
|
||||||
|
|
||||||
|
/// \todo Multi-valued settings are not fully implemented. Setting values
|
||||||
|
/// \todo loaded in later files will always overwrite previously loaded values.
|
||||||
|
void loadSettings (const QString &fileName);
|
||||||
|
|
||||||
|
/// Returns the entire map of settings across all sections
|
||||||
|
const SectionMap &getSettings () const;
|
||||||
|
|
||||||
|
/// Retrieves the value as a QString of the specified setting in the specified section
|
||||||
|
QString getSetting(const QString §ion, const QString &setting) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
/// Opens a QTextStream from the provided path as read-only or read-write.
|
||||||
|
QTextStream *openFileStream (const QString &filePath, bool isReadOnly = false) const;
|
||||||
|
|
||||||
|
/// Parses a setting file specified in filePath from the provided text stream.
|
||||||
|
bool loadFromFile (const QString &filePath = "");
|
||||||
|
|
||||||
|
void displayFileErrorMessage(const QString &message, bool isReadOnly);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void signalUpdateEditorSetting (const QString &settingName, const QString &settingValue);
|
void signalUpdateEditorSetting (const QString &settingName, const QString &settingValue);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -41,7 +41,8 @@ namespace CSMWorld
|
|||||||
Display_ArmorType,
|
Display_ArmorType,
|
||||||
Display_ClothingType,
|
Display_ClothingType,
|
||||||
Display_CreatureType,
|
Display_CreatureType,
|
||||||
Display_WeaponType
|
Display_WeaponType,
|
||||||
|
Display_RecordState
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string mTitle;
|
std::string mTitle;
|
||||||
|
@ -53,7 +53,7 @@ namespace CSMWorld
|
|||||||
template<typename ESXRecordT>
|
template<typename ESXRecordT>
|
||||||
struct RecordStateColumn : public Column<ESXRecordT>
|
struct RecordStateColumn : public Column<ESXRecordT>
|
||||||
{
|
{
|
||||||
RecordStateColumn() : Column<ESXRecordT> ("*", ColumnBase::Display_Integer) {}
|
RecordStateColumn() : Column<ESXRecordT> ("*", ColumnBase::Display_RecordState) {}
|
||||||
|
|
||||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||||
{
|
{
|
||||||
@ -1148,4 +1148,4 @@ namespace CSMWorld
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -41,7 +41,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||||||
mColumns.push_back (RefIdColumn ("ID", ColumnBase::Display_String,
|
mColumns.push_back (RefIdColumn ("ID", ColumnBase::Display_String,
|
||||||
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false));
|
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false));
|
||||||
baseColumns.mId = &mColumns.back();
|
baseColumns.mId = &mColumns.back();
|
||||||
mColumns.push_back (RefIdColumn ("*", ColumnBase::Display_Integer,
|
mColumns.push_back (RefIdColumn ("*", ColumnBase::Display_RecordState,
|
||||||
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false));
|
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false));
|
||||||
baseColumns.mModified = &mColumns.back();
|
baseColumns.mModified = &mColumns.back();
|
||||||
mColumns.push_back (RefIdColumn ("Type", ColumnBase::Display_Integer,
|
mColumns.push_back (RefIdColumn ("Type", ColumnBase::Display_Integer,
|
||||||
@ -539,4 +539,4 @@ void CSMWorld::RefIdCollection::load (ESM::ESMReader& reader, bool base, Univers
|
|||||||
int CSMWorld::RefIdCollection::getAppendIndex (UniversalId::Type type) const
|
int CSMWorld::RefIdCollection::getAppendIndex (UniversalId::Type type) const
|
||||||
{
|
{
|
||||||
return mData.getAppendIndex (type);
|
return mData.getAppendIndex (type);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "subview.hpp"
|
#include "subview.hpp"
|
||||||
|
|
||||||
|
|
||||||
CSVDoc::SubView::SubView (const CSMWorld::UniversalId& id) : mUniversalId (id)
|
CSVDoc::SubView::SubView (const CSMWorld::UniversalId& id) : mUniversalId (id)
|
||||||
{
|
{
|
||||||
/// \todo add a button to the title bar that clones this sub view
|
/// \todo add a button to the title bar that clones this sub view
|
||||||
@ -15,3 +16,7 @@ CSMWorld::UniversalId CSVDoc::SubView::getUniversalId() const
|
|||||||
{
|
{
|
||||||
return mUniversalId;
|
return mUniversalId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVDoc::SubView::updateEditorSetting (const QString &settingName, const QString &settingValue)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
@ -35,6 +35,7 @@ namespace CSVDoc
|
|||||||
CSMWorld::UniversalId getUniversalId() const;
|
CSMWorld::UniversalId getUniversalId() const;
|
||||||
|
|
||||||
virtual void setEditLock (bool locked) = 0;
|
virtual void setEditLock (bool locked) = 0;
|
||||||
|
virtual void updateEditorSetting (const QString &, const QString &);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
@ -42,4 +43,4 @@ namespace CSVDoc
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -182,7 +182,13 @@ CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int to
|
|||||||
: mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1),
|
: mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1),
|
||||||
mViewTotal (totalViews)
|
mViewTotal (totalViews)
|
||||||
{
|
{
|
||||||
resize (300, 300); /// \todo get default size from settings and set reasonable minimal size
|
QString width = CSMSettings::UserSettings::instance().getSetting(QString("Window Size"), QString("Width"));
|
||||||
|
QString height = CSMSettings::UserSettings::instance().getSetting(QString("Window Size"), QString("Height"));
|
||||||
|
|
||||||
|
if(width==QString() || height==QString())
|
||||||
|
resize(800, 600);
|
||||||
|
else
|
||||||
|
resize (width.toInt(), height.toInt());
|
||||||
|
|
||||||
mSubViewWindow.setDockOptions (QMainWindow::AllowNestedDocks);
|
mSubViewWindow.setDockOptions (QMainWindow::AllowNestedDocks);
|
||||||
|
|
||||||
@ -261,11 +267,14 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id)
|
|||||||
/// \todo add an user setting to reuse sub views (on a per document basis or on a per top level view basis)
|
/// \todo add an user setting to reuse sub views (on a per document basis or on a per top level view basis)
|
||||||
|
|
||||||
SubView *view = mSubViewFactory.makeSubView (id, *mDocument);
|
SubView *view = mSubViewFactory.makeSubView (id, *mDocument);
|
||||||
|
view->setObjectName ("subview");
|
||||||
mSubViewWindow.addDockWidget (Qt::TopDockWidgetArea, view);
|
mSubViewWindow.addDockWidget (Qt::TopDockWidgetArea, view);
|
||||||
|
|
||||||
connect (view, SIGNAL (focusId (const CSMWorld::UniversalId&)), this,
|
connect (view, SIGNAL (focusId (const CSMWorld::UniversalId&)), this,
|
||||||
SLOT (addSubView (const CSMWorld::UniversalId&)));
|
SLOT (addSubView (const CSMWorld::UniversalId&)));
|
||||||
|
|
||||||
|
CSMSettings::UserSettings::instance().updateSettings("Editor", "Record Status Display");
|
||||||
|
|
||||||
view->show();
|
view->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,20 +383,34 @@ void CSVDoc::View::showUserSettings()
|
|||||||
{
|
{
|
||||||
CSVSettings::UserSettingsDialog *settingsDialog = new CSVSettings::UserSettingsDialog(this);
|
CSVSettings::UserSettingsDialog *settingsDialog = new CSVSettings::UserSettingsDialog(this);
|
||||||
|
|
||||||
connect (&(CSMSettings::UserSettings::instance()), SIGNAL (signalUpdateEditorSetting (const QString &, const QString &)),
|
|
||||||
this, SLOT (slotUpdateEditorSetting (const QString &, const QString &)) );
|
|
||||||
|
|
||||||
settingsDialog->show();
|
settingsDialog->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVDoc::View::slotUpdateEditorSetting(const QString &settingName, const QString &settingValue)
|
void CSVDoc::View::resizeViewWidth (int width)
|
||||||
{
|
{
|
||||||
static QString lastValue = "";
|
if (width >= 0)
|
||||||
|
resize (width, geometry().height());
|
||||||
if (lastValue != settingValue)
|
}
|
||||||
{
|
|
||||||
//evaluate settingName against tokens to determine which function to call to update Editor application.
|
void CSVDoc::View::resizeViewHeight (int height)
|
||||||
|
{
|
||||||
lastValue = settingValue;
|
if (height >= 0)
|
||||||
}
|
resize (geometry().width(), height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVDoc::View::updateEditorSetting (const QString &settingName, const QString &settingValue)
|
||||||
|
{
|
||||||
|
if (settingName == "Record Status Display")
|
||||||
|
{
|
||||||
|
foreach (QObject *view, mSubViewWindow.children())
|
||||||
|
{
|
||||||
|
if (view->objectName() == "subview")
|
||||||
|
dynamic_cast<CSVDoc::SubView *>(view)->updateEditorSetting (settingName, settingValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (settingName == "Width")
|
||||||
|
resizeViewWidth (settingValue.toInt());
|
||||||
|
|
||||||
|
else if (settingName == "Height")
|
||||||
|
resizeViewHeight (settingValue.toInt());
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,14 @@ namespace CSVDoc
|
|||||||
|
|
||||||
void exitApplication();
|
void exitApplication();
|
||||||
|
|
||||||
|
void loadUserSettings();
|
||||||
|
|
||||||
|
/// User preference function
|
||||||
|
void resizeViewWidth (int width);
|
||||||
|
|
||||||
|
/// User preference function
|
||||||
|
void resizeViewHeight (int height);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews);
|
View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews);
|
||||||
@ -88,6 +96,9 @@ namespace CSVDoc
|
|||||||
|
|
||||||
Operations *getOperations() const;
|
Operations *getOperations() const;
|
||||||
|
|
||||||
|
/// Function called by view manager when user preferences are updated
|
||||||
|
void updateEditorSetting (const QString &, const QString &);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void newDocumentRequest();
|
void newDocumentRequest();
|
||||||
@ -102,8 +113,6 @@ namespace CSVDoc
|
|||||||
|
|
||||||
void abortOperation (int type);
|
void abortOperation (int type);
|
||||||
|
|
||||||
void slotUpdateEditorSetting (const QString &settingName, const QString &settingValue);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void newView();
|
void newView();
|
||||||
|
@ -12,13 +12,14 @@
|
|||||||
#include "../world/util.hpp"
|
#include "../world/util.hpp"
|
||||||
#include "../world/enumdelegate.hpp"
|
#include "../world/enumdelegate.hpp"
|
||||||
#include "../world/vartypedelegate.hpp"
|
#include "../world/vartypedelegate.hpp"
|
||||||
|
#include "../world/recordstatusdelegate.hpp"
|
||||||
|
#include "../settings/usersettingsdialog.hpp"
|
||||||
|
|
||||||
#include "view.hpp"
|
#include "view.hpp"
|
||||||
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QtGui/QApplication>
|
#include <QtGui/QApplication>
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
void CSVDoc::ViewManager::updateIndices()
|
void CSVDoc::ViewManager::updateIndices()
|
||||||
{
|
{
|
||||||
@ -117,6 +118,12 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager)
|
|||||||
|
|
||||||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_WeaponType,
|
mDelegateFactories->add (CSMWorld::ColumnBase::Display_WeaponType,
|
||||||
new CSVWorld::EnumDelegateFactory (sWeaponTypes));
|
new CSVWorld::EnumDelegateFactory (sWeaponTypes));
|
||||||
|
|
||||||
|
mDelegateFactories->add (CSMWorld::ColumnBase::Display_RecordState,
|
||||||
|
new CSVWorld::RecordStatusDelegateFactory() );
|
||||||
|
|
||||||
|
connect (&CSMSettings::UserSettings::instance(), SIGNAL (signalUpdateEditorSetting (const QString &, const QString &)),
|
||||||
|
this, SLOT (slotUpdateEditorSetting (const QString &, const QString &)));
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVDoc::ViewManager::~ViewManager()
|
CSVDoc::ViewManager::~ViewManager()
|
||||||
@ -343,3 +350,13 @@ void CSVDoc::ViewManager::exitApplication (CSVDoc::View *view)
|
|||||||
if (notifySaveOnClose (view))
|
if (notifySaveOnClose (view))
|
||||||
QApplication::instance()->exit();
|
QApplication::instance()->exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVDoc::ViewManager::slotUpdateEditorSetting (const QString &settingName, const QString &settingValue)
|
||||||
|
{
|
||||||
|
if (settingName == "Record Status Display" ||
|
||||||
|
settingName == "Width" || settingName == "Height")
|
||||||
|
{
|
||||||
|
foreach (CSVDoc::View *view, mViews)
|
||||||
|
view->updateEditorSetting (settingName, settingValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -72,6 +72,9 @@ namespace CSVDoc
|
|||||||
void progress (int current, int max, int type, int threads, CSMDoc::Document *document);
|
void progress (int current, int max, int type, int threads, CSMDoc::Document *document);
|
||||||
|
|
||||||
void onExitWarningHandler(int state, CSMDoc::Document* document);
|
void onExitWarningHandler(int state, CSMDoc::Document* document);
|
||||||
|
|
||||||
|
/// connected to update signal in UserSettings
|
||||||
|
void slotUpdateEditorSetting (const QString &, const QString &);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -38,27 +38,27 @@ CSVSettings::AbstractWidget *CSVSettings::AbstractBlock::buildWidget (const QStr
|
|||||||
{
|
{
|
||||||
|
|
||||||
case Widget_RadioButton:
|
case Widget_RadioButton:
|
||||||
widg = createSettingWidget<QRadioButton> (def, layout);
|
widg = new SettingWidget<QRadioButton> (def, layout, mBox);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Widget_SpinBox:
|
case Widget_SpinBox:
|
||||||
widg = createSettingWidget<QSpinBox> (def, layout);
|
widg = new SettingWidget<QSpinBox> (def, layout, mBox);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Widget_CheckBox:
|
case Widget_CheckBox:
|
||||||
widg = createSettingWidget<QCheckBox> (def, layout);
|
widg = new SettingWidget<QCheckBox> (def, layout, mBox);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Widget_LineEdit:
|
case Widget_LineEdit:
|
||||||
widg = createSettingWidget<QLineEdit> (def, layout);
|
widg = new SettingWidget<QLineEdit> (def, layout, mBox);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Widget_ListBox:
|
case Widget_ListBox:
|
||||||
widg = createSettingWidget<QListWidget> (def, layout);
|
widg = new SettingWidget<QListWidget> (def, layout, mBox);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Widget_ComboBox:
|
case Widget_ComboBox:
|
||||||
widg = createSettingWidget<QComboBox> (def, layout);
|
widg = new SettingWidget<QComboBox> (def, layout, mBox);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
namespace CSVSettings
|
namespace CSVSettings
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/// Abstract base class for all blocks
|
||||||
class AbstractBlock : public QObject
|
class AbstractBlock : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -31,40 +32,50 @@ namespace CSVSettings
|
|||||||
bool isVisible() const;
|
bool isVisible() const;
|
||||||
|
|
||||||
virtual CSMSettings::SettingList *getSettings() = 0;
|
virtual CSMSettings::SettingList *getSettings() = 0;
|
||||||
|
|
||||||
|
/// update settings found in the passed map and are encapsulated by the block
|
||||||
virtual bool updateSettings (const CSMSettings::SettingMap &settings) = 0;
|
virtual bool updateSettings (const CSMSettings::SettingMap &settings) = 0;
|
||||||
|
|
||||||
|
/// update callback function called from update slot
|
||||||
|
/// used for updating application-level settings in the editor
|
||||||
virtual bool updateBySignal (const QString &name, const QString &value, bool &doEmit)
|
virtual bool updateBySignal (const QString &name, const QString &value, bool &doEmit)
|
||||||
{ return false; }
|
{ return false; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
/// Creates the layout which for the blocks QGroupBox
|
||||||
QLayout *createLayout (Orientation direction, bool isZeroMargin, QWidget* parent = 0);
|
QLayout *createLayout (Orientation direction, bool isZeroMargin, QWidget* parent = 0);
|
||||||
|
|
||||||
|
/// Creates widgets that exist as direct children of the block
|
||||||
AbstractWidget *buildWidget (const QString &widgetName, WidgetDef &wDef,
|
AbstractWidget *buildWidget (const QString &widgetName, WidgetDef &wDef,
|
||||||
QLayout *layout = 0, bool isConnected = true) const;
|
QLayout *layout = 0, bool isConnected = true) const;
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
AbstractWidget *createSettingWidget (WidgetDef &wDef, QLayout *layout) const
|
|
||||||
{
|
|
||||||
return new SettingWidget<T> (wDef, layout, mBox);
|
|
||||||
}
|
|
||||||
|
|
||||||
QWidget *getParent() const;
|
QWidget *getParent() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
|
/// enables / disables block-level widgets based on signals from other widgets
|
||||||
|
/// used in ToggleBlock
|
||||||
void slotSetEnabled (bool value);
|
void slotSetEnabled (bool value);
|
||||||
|
|
||||||
|
/// receives updates to applicaion-level settings in the Editor
|
||||||
void slotUpdateSetting (const QString &settingName, const QString &settingValue);
|
void slotUpdateSetting (const QString &settingName, const QString &settingValue);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
|
/// receives updates to a setting in the block pushed from the application level
|
||||||
void slotUpdate (const QString &value);
|
void slotUpdate (const QString &value);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
//signal to functions outside the settings tab widget
|
/// signal to UserSettings instance
|
||||||
void signalUpdateSetting (const QString &propertyName, const QString &propertyValue);
|
void signalUpdateSetting (const QString &propertyName, const QString &propertyValue);
|
||||||
|
|
||||||
|
/// signal to widget for updating widget value
|
||||||
void signalUpdateWidget (const QString & value);
|
void signalUpdateWidget (const QString & value);
|
||||||
|
|
||||||
//propertyName and propertyValue are for properties for which the updated setting acts as a proxy
|
/// ProxyBlock use only.
|
||||||
|
/// Name and value correspond to settings for which the block is a proxy.
|
||||||
void signalUpdateProxySetting (const QString &propertyName, const QString &propertyValue);
|
void signalUpdateProxySetting (const QString &propertyName, const QString &propertyValue);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -13,12 +13,17 @@
|
|||||||
CSVSettings::AbstractPage::AbstractPage(QWidget *parent):
|
CSVSettings::AbstractPage::AbstractPage(QWidget *parent):
|
||||||
QWidget(parent)
|
QWidget(parent)
|
||||||
{
|
{
|
||||||
|
QGridLayout *pageLayout = new QGridLayout(this);
|
||||||
|
setLayout (pageLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVSettings::AbstractPage::AbstractPage(const QString &pageName, QWidget *parent):
|
CSVSettings::AbstractPage::AbstractPage(const QString &pageName, QWidget *parent):
|
||||||
QWidget(parent)
|
QWidget(parent)
|
||||||
{
|
{
|
||||||
QWidget::setObjectName (pageName);
|
QWidget::setObjectName (pageName);
|
||||||
|
|
||||||
|
QGridLayout *pageLayout = new QGridLayout(this);
|
||||||
|
setLayout (pageLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVSettings::AbstractPage::~AbstractPage()
|
CSVSettings::AbstractPage::~AbstractPage()
|
||||||
|
@ -14,6 +14,11 @@ namespace CSVSettings {
|
|||||||
|
|
||||||
typedef QList<AbstractBlock *> AbstractBlockList;
|
typedef QList<AbstractBlock *> AbstractBlockList;
|
||||||
|
|
||||||
|
/// Abstract base class for all setting pages in the dialog
|
||||||
|
|
||||||
|
/// \todo Scripted implementation of settings should eliminate the need
|
||||||
|
/// \todo derive page classes.
|
||||||
|
/// \todo AbstractPage should be replaced with a general page construction class.
|
||||||
class AbstractPage: public QWidget
|
class AbstractPage: public QWidget
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -28,18 +33,24 @@ namespace CSVSettings {
|
|||||||
|
|
||||||
~AbstractPage();
|
~AbstractPage();
|
||||||
|
|
||||||
virtual void setupUi()=0;
|
virtual void setupUi() = 0;
|
||||||
|
|
||||||
|
/// triggers widgiet initialization at the page level. All widgets updated to
|
||||||
|
/// current setting values
|
||||||
virtual void initializeWidgets (const CSMSettings::SettingMap &settings) = 0;
|
virtual void initializeWidgets (const CSMSettings::SettingMap &settings) = 0;
|
||||||
|
|
||||||
|
/// retrieve the list of settings local to the page.
|
||||||
CSMSettings::SettingList *getSettings();
|
CSMSettings::SettingList *getSettings();
|
||||||
|
|
||||||
void setObjectName();
|
void setObjectName();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
/// Create a block for the page.
|
||||||
|
/// Block is constructed using passed definition struct
|
||||||
|
/// Page level-layout is created and assigned
|
||||||
template <typename S, typename T>
|
template <typename S, typename T>
|
||||||
AbstractBlock *buildBlock (T &def)
|
AbstractBlock *buildBlock (T *def)
|
||||||
{
|
{
|
||||||
S *block = new S (this);
|
S *block = new S (this);
|
||||||
int ret = block->build (def);
|
int ret = block->build (def);
|
||||||
@ -47,12 +58,12 @@ namespace CSVSettings {
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
QWidget::layout()->addWidget (block->getGroupBox());
|
QGroupBox *box = block->getGroupBox();
|
||||||
|
QWidget::layout()->addWidget (box);
|
||||||
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ class QLayout;
|
|||||||
|
|
||||||
namespace CSVSettings
|
namespace CSVSettings
|
||||||
{
|
{
|
||||||
|
/// Abstract base class for widgets which are used in user preferences dialog
|
||||||
class AbstractWidget : public QObject
|
class AbstractWidget : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -16,45 +17,49 @@ namespace CSVSettings
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// Passed layout is assigned the constructed widget.
|
||||||
|
/// if no layout is passed, one is created.
|
||||||
explicit AbstractWidget (QLayout *layout = 0, QWidget* parent = 0)
|
explicit AbstractWidget (QLayout *layout = 0, QWidget* parent = 0)
|
||||||
: QObject (parent), mLayout (layout)
|
: QObject (parent), mLayout (layout)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//retrieve layout for insertion into itemblock
|
/// retrieve layout for insertion into itemblock
|
||||||
QLayout *getLayout();
|
QLayout *getLayout();
|
||||||
|
|
||||||
//create the derived widget instance
|
/// create the derived widget instance
|
||||||
void build (QWidget* widget, WidgetDef &def, bool noLabel = false);
|
void build (QWidget* widget, WidgetDef &def, bool noLabel = false);
|
||||||
|
|
||||||
//reference to the derived widget instance
|
/// reference to the derived widget instance
|
||||||
virtual QWidget *widget() = 0;
|
virtual QWidget *widget() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
//called by inbound signal for type-specific widget udpates
|
/// Callback called by receiving slot for widget udpates
|
||||||
virtual void updateWidget (const QString &value) = 0;
|
virtual void updateWidget (const QString &value) = 0;
|
||||||
|
|
||||||
//converts user-defined enum to Qt equivalents
|
/// Converts user-defined enum to Qt equivalents
|
||||||
QFlags<Qt::AlignmentFlag> getAlignment (Alignment flag);
|
QFlags<Qt::AlignmentFlag> getAlignment (Alignment flag);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//widget initialization utilities
|
/// Creates layout and assigns label and widget as appropriate
|
||||||
void createLayout (Orientation direction, bool isZeroMargin);
|
void createLayout (Orientation direction, bool isZeroMargin);
|
||||||
|
|
||||||
|
/// Creates label and widget according to passed definition
|
||||||
void buildLabelAndWidget (QWidget *widget, WidgetDef &def, bool noLabel);
|
void buildLabelAndWidget (QWidget *widget, WidgetDef &def, bool noLabel);
|
||||||
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
//outbound update
|
/// outbound update signal
|
||||||
void signalUpdateItem (const QString &value);
|
void signalUpdateItem (const QString &value);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
//inbound updates
|
/// receives inbound updates
|
||||||
void slotUpdateWidget (const QString &value);
|
void slotUpdateWidget (const QString &value);
|
||||||
|
|
||||||
//Outbound updates from derived widget signal
|
/// Overloads for outbound updates from derived widget signal
|
||||||
void slotUpdateItem (const QString &value);
|
void slotUpdateItem (const QString &value);
|
||||||
void slotUpdateItem (bool value);
|
void slotUpdateItem (bool value);
|
||||||
void slotUpdateItem (int value);
|
void slotUpdateItem (int value);
|
||||||
|
@ -20,16 +20,11 @@
|
|||||||
CSVSettings::BlankPage::BlankPage(QWidget *parent):
|
CSVSettings::BlankPage::BlankPage(QWidget *parent):
|
||||||
AbstractPage("Blank", parent)
|
AbstractPage("Blank", parent)
|
||||||
{
|
{
|
||||||
initPage();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVSettings::BlankPage::BlankPage(const QString &title, QWidget *parent):
|
CSVSettings::BlankPage::BlankPage(const QString &title, QWidget *parent):
|
||||||
AbstractPage(title, parent)
|
AbstractPage(title, parent)
|
||||||
{
|
|
||||||
initPage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSVSettings::BlankPage::initPage()
|
|
||||||
{
|
{
|
||||||
// Hacks to get the stylesheet look properly
|
// Hacks to get the stylesheet look properly
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
@ -43,10 +38,7 @@ void CSVSettings::BlankPage::initPage()
|
|||||||
void CSVSettings::BlankPage::setupUi()
|
void CSVSettings::BlankPage::setupUi()
|
||||||
{
|
{
|
||||||
QGroupBox *pageBox = new QGroupBox(this);
|
QGroupBox *pageBox = new QGroupBox(this);
|
||||||
QLayout* pageLayout = new QVBoxLayout();
|
layout()->addWidget(pageBox);
|
||||||
|
|
||||||
setLayout(pageLayout);
|
|
||||||
pageLayout->addWidget(pageBox);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVSettings::BlankPage::initializeWidgets (const CSMSettings::SettingMap &settings)
|
void CSVSettings::BlankPage::initializeWidgets (const CSMSettings::SettingMap &settings)
|
||||||
|
@ -10,6 +10,8 @@ namespace CSVSettings {
|
|||||||
class UserSettings;
|
class UserSettings;
|
||||||
class AbstractBlock;
|
class AbstractBlock;
|
||||||
|
|
||||||
|
/// Derived page with no widgets
|
||||||
|
/// Reference use only.
|
||||||
class BlankPage : public AbstractPage
|
class BlankPage : public AbstractPage
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -20,9 +22,6 @@ namespace CSVSettings {
|
|||||||
|
|
||||||
void setupUi();
|
void setupUi();
|
||||||
void initializeWidgets (const CSMSettings::SettingMap &settings);
|
void initializeWidgets (const CSMSettings::SettingMap &settings);
|
||||||
|
|
||||||
private:
|
|
||||||
void initPage();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ int CSVSettings::CustomBlock::build(GroupBlockDefList &defList, GroupBlockDefLis
|
|||||||
for (; listIt != defList.end(); ++listIt)
|
for (; listIt != defList.end(); ++listIt)
|
||||||
{
|
{
|
||||||
if (!(*listIt)->isProxy)
|
if (!(*listIt)->isProxy)
|
||||||
retVal = buildGroupBlock (*(*listIt));
|
retVal = buildGroupBlock (*listIt);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mGroupList << proxyBlock;
|
mGroupList << proxyBlock;
|
||||||
@ -32,7 +32,7 @@ int CSVSettings::CustomBlock::build(GroupBlockDefList &defList, GroupBlockDefLis
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (proxyIt != defaultIt)
|
if (proxyIt != defaultIt)
|
||||||
retVal = buildProxyBlock (*(*proxyIt), proxyBlock);
|
retVal = buildProxyBlock (*proxyIt, proxyBlock);
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
@ -40,12 +40,12 @@ int CSVSettings::CustomBlock::build(GroupBlockDefList &defList, GroupBlockDefLis
|
|||||||
CSVSettings::GroupBox *CSVSettings::CustomBlock::buildGroupBox (Orientation orientation)
|
CSVSettings::GroupBox *CSVSettings::CustomBlock::buildGroupBox (Orientation orientation)
|
||||||
{
|
{
|
||||||
GroupBox *box = new GroupBox (false, mBox);
|
GroupBox *box = new GroupBox (false, mBox);
|
||||||
QLayout *layout = createLayout (orientation, true, box);
|
createLayout (orientation, true, box);
|
||||||
|
|
||||||
return box;
|
return box;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CSVSettings::CustomBlock::buildGroupBlock(GroupBlockDef &def)
|
int CSVSettings::CustomBlock::buildGroupBlock(GroupBlockDef *def)
|
||||||
{
|
{
|
||||||
GroupBlock *block = new GroupBlock (getParent());
|
GroupBlock *block = new GroupBlock (getParent());
|
||||||
|
|
||||||
@ -57,9 +57,9 @@ int CSVSettings::CustomBlock::buildGroupBlock(GroupBlockDef &def)
|
|||||||
return block->build(def);
|
return block->build(def);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CSVSettings::CustomBlock::buildProxyBlock(GroupBlockDef& def, ProxyBlock *block)
|
int CSVSettings::CustomBlock::buildProxyBlock(GroupBlockDef *def, ProxyBlock *block)
|
||||||
{
|
{
|
||||||
if (def.properties.size() != 1)
|
if (def->settingItems.size() != 1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
int retVal = block->build(def);
|
int retVal = block->build(def);
|
||||||
@ -67,7 +67,8 @@ int CSVSettings::CustomBlock::buildProxyBlock(GroupBlockDef& def, ProxyBlock *bl
|
|||||||
if (retVal != 0)
|
if (retVal != 0)
|
||||||
return retVal;
|
return retVal;
|
||||||
|
|
||||||
foreach (QStringList *list, *(def.properties.at(0)->proxyList))
|
// The first settingItem is the proxy setting, containing the list of settings bound to it.
|
||||||
|
foreach (QStringList *list, *(def->settingItems.at(0)->proxyList))
|
||||||
{
|
{
|
||||||
QString proxiedBlockName = list->at(0);
|
QString proxiedBlockName = list->at(0);
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@ namespace CSVSettings
|
|||||||
|
|
||||||
class ProxyBlock;
|
class ProxyBlock;
|
||||||
|
|
||||||
|
/// Base class for customized user preference setting blocks
|
||||||
|
/// Special block classes should be derived from CustomBlock
|
||||||
class CustomBlock : public AbstractBlock
|
class CustomBlock : public AbstractBlock
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -19,18 +21,27 @@ namespace CSVSettings
|
|||||||
|
|
||||||
explicit CustomBlock (QWidget *parent = 0);
|
explicit CustomBlock (QWidget *parent = 0);
|
||||||
|
|
||||||
|
/// Update settings local to the block
|
||||||
bool updateSettings (const CSMSettings::SettingMap &settings);
|
bool updateSettings (const CSMSettings::SettingMap &settings);
|
||||||
|
|
||||||
|
/// Retrieve settings local to the block
|
||||||
CSMSettings::SettingList *getSettings();
|
CSMSettings::SettingList *getSettings();
|
||||||
|
|
||||||
|
/// construct the block using the passed definition
|
||||||
int build (GroupBlockDefList &defList, GroupBlockDefList::Iterator *it = 0);
|
int build (GroupBlockDefList &defList, GroupBlockDefList::Iterator *it = 0);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
/// construct the block groupbox
|
||||||
GroupBox *buildGroupBox (Orientation orientation);
|
GroupBox *buildGroupBox (Orientation orientation);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
int buildGroupBlock(GroupBlockDef &def);
|
/// Construction function for creating a standard GroupBlock child
|
||||||
int buildProxyBlock(GroupBlockDef &def, ProxyBlock *block);
|
int buildGroupBlock(GroupBlockDef *def);
|
||||||
|
|
||||||
|
/// Construction function for creating a standard ProxyBlock child
|
||||||
|
int buildProxyBlock(GroupBlockDef *def, ProxyBlock *block);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif // CUSTOMBLOCK_HPP
|
#endif // CUSTOMBLOCK_HPP
|
||||||
|
@ -1,156 +1,46 @@
|
|||||||
#include "editorpage.hpp"
|
#include "editorpage.hpp"
|
||||||
|
|
||||||
#include <QList>
|
|
||||||
#include <QListView>
|
|
||||||
#include <QGroupBox>
|
|
||||||
#include <QRadioButton>
|
|
||||||
#include <QDockWidget>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <QGridLayout>
|
|
||||||
#include <QStyle>
|
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
|
||||||
#include <QPlastiqueStyle>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "../../model/settings/usersettings.hpp"
|
|
||||||
#include "groupblock.hpp"
|
#include "groupblock.hpp"
|
||||||
#include "toggleblock.hpp"
|
#include "../../model/settings/usersettings.hpp"
|
||||||
|
|
||||||
CSVSettings::EditorPage::EditorPage(QWidget *parent):
|
CSVSettings::EditorPage::EditorPage(QWidget* parent) :
|
||||||
AbstractPage("Editor", parent)
|
AbstractPage("Display Format", parent)
|
||||||
{
|
{
|
||||||
// Hacks to get the stylesheet look properly
|
|
||||||
#ifdef Q_OS_MAC
|
|
||||||
QPlastiqueStyle *style = new QPlastiqueStyle;
|
|
||||||
//profilesComboBox->setStyle(style);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
setupUi();
|
setupUi();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CSVSettings::GroupBlockDef *CSVSettings::EditorPage::setupRecordStatusDisplay()
|
||||||
|
{
|
||||||
|
GroupBlockDef *statusBlock = new GroupBlockDef(QString("Record Status Display"));
|
||||||
|
|
||||||
|
SettingsItemDef *statusItem = new SettingsItemDef (statusBlock->title, "Icon and Text");
|
||||||
|
*(statusItem->valueList) << QString("Icon and Text") << QString("Icon Only") << QString("Text Only");
|
||||||
|
|
||||||
|
WidgetDef statusWidget (Widget_RadioButton);
|
||||||
|
statusWidget.valueList = statusItem->valueList;
|
||||||
|
|
||||||
|
statusItem->widget = statusWidget;
|
||||||
|
|
||||||
|
statusBlock->settingItems << statusItem;
|
||||||
|
|
||||||
|
return statusBlock;
|
||||||
|
}
|
||||||
|
|
||||||
void CSVSettings::EditorPage::setupUi()
|
void CSVSettings::EditorPage::setupUi()
|
||||||
{
|
{
|
||||||
GroupBlockDef undoStack (QString("Undo Stack Size"));
|
|
||||||
GroupBlockDef topLevelWindowCount (QString("Maximum Top-Level Window Count"));
|
|
||||||
GroupBlockDef reuseSubwindow (QString("Reuse Subwindows"));
|
|
||||||
GroupBlockDef customWindowSize (QString ("Custom Window Size"));
|
|
||||||
GroupBlockDef definedWindowSize (QString ("Pre-Defined Window Size"));
|
|
||||||
GroupBlockDef windowSizeToggle (QString ("Window Size"));
|
|
||||||
CustomBlockDef windowSize (QString ("Window Size"));
|
|
||||||
|
|
||||||
////////////////////////////
|
mAbstractBlocks << buildBlock<GroupBlock>(setupRecordStatusDisplay());
|
||||||
//undo stack size property
|
|
||||||
///////////////////////////
|
|
||||||
|
|
||||||
SettingsItemDef *undoStackItem = new SettingsItemDef (undoStack.title, "32");
|
|
||||||
undoStack.properties << undoStackItem;
|
|
||||||
undoStackItem->minMax.left = "0";
|
|
||||||
undoStackItem->minMax.right = "64";
|
|
||||||
|
|
||||||
WidgetDef stackWidget (Widget_SpinBox);
|
|
||||||
stackWidget.minMax = &(undoStackItem->minMax);
|
|
||||||
stackWidget.widgetWidth = 50;
|
|
||||||
|
|
||||||
undoStackItem->widget = stackWidget;
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
//number of top level windows property
|
|
||||||
/////////////////////////////////////
|
|
||||||
|
|
||||||
SettingsItemDef *topLevelItem = new SettingsItemDef (topLevelWindowCount.title, "100");
|
|
||||||
topLevelWindowCount.properties << topLevelItem;
|
|
||||||
topLevelItem->minMax.left = "1";
|
|
||||||
topLevelItem->minMax.right = "256";
|
|
||||||
|
|
||||||
WidgetDef topLvlWinWidget (Widget_SpinBox);
|
|
||||||
topLvlWinWidget.minMax = &(topLevelItem->minMax);
|
|
||||||
topLvlWinWidget.widgetWidth = 50;
|
|
||||||
|
|
||||||
topLevelItem->widget = topLvlWinWidget;
|
|
||||||
|
|
||||||
///////////////////////////
|
|
||||||
//reuse subwindows property
|
|
||||||
////////////////////////////
|
|
||||||
|
|
||||||
SettingsItemDef *reuseSubItem = new SettingsItemDef (reuseSubwindow.title, "Reuse Subwindows");
|
|
||||||
*(reuseSubItem->valueList) << "None" << "Top-Level" << "Document-Level";
|
|
||||||
|
|
||||||
WidgetDef reuseSubWidget (Widget_RadioButton);
|
|
||||||
reuseSubWidget.valueList = (reuseSubItem->valueList);
|
|
||||||
reuseSubWidget.widgetAlignment = Align_Left;
|
|
||||||
|
|
||||||
reuseSubwindow.properties << reuseSubItem;
|
|
||||||
reuseSubItem->widget = reuseSubWidget;
|
|
||||||
|
|
||||||
///////////////////////////////
|
|
||||||
//custom window size properties
|
|
||||||
///////////////////////////////
|
|
||||||
|
|
||||||
//custom width
|
|
||||||
SettingsItemDef *widthItem = new SettingsItemDef ("Window Width", "640");
|
|
||||||
widthItem->widget = WidgetDef (Widget_LineEdit);
|
|
||||||
widthItem->widget.widgetWidth = 45;
|
|
||||||
|
|
||||||
//custom height
|
|
||||||
SettingsItemDef *heightItem = new SettingsItemDef ("Window Height", "480");
|
|
||||||
heightItem->widget = WidgetDef (Widget_LineEdit);
|
|
||||||
heightItem->widget.widgetWidth = 45;
|
|
||||||
heightItem->widget.caption = "x";
|
|
||||||
|
|
||||||
customWindowSize.properties << widthItem << heightItem;
|
|
||||||
customWindowSize.widgetOrientation = Orient_Horizontal;
|
|
||||||
customWindowSize.isVisible = false;
|
|
||||||
|
|
||||||
|
|
||||||
//pre-defined
|
|
||||||
SettingsItemDef *widthByHeightItem = new SettingsItemDef ("Window Size", "640x480");
|
|
||||||
WidgetDef widthByHeightWidget = WidgetDef (Widget_ComboBox);
|
|
||||||
widthByHeightWidget.widgetWidth = 90;
|
|
||||||
*(widthByHeightItem->valueList) << "640x480" << "800x600" << "1024x768";
|
|
||||||
|
|
||||||
QStringList *widthProxy = new QStringList;
|
|
||||||
QStringList *heightProxy = new QStringList;
|
|
||||||
|
|
||||||
(*widthProxy) << "Window Width" << "640" << "800" << "1024";
|
|
||||||
(*heightProxy) << "Window Height" << "480" << "600" << "768";
|
|
||||||
|
|
||||||
*(widthByHeightItem->proxyList) << widthProxy << heightProxy;
|
|
||||||
|
|
||||||
widthByHeightItem->widget = widthByHeightWidget;
|
|
||||||
|
|
||||||
definedWindowSize.properties << widthByHeightItem;
|
|
||||||
definedWindowSize.isProxy = true;
|
|
||||||
definedWindowSize.isVisible = false;
|
|
||||||
|
|
||||||
// window size toggle
|
|
||||||
windowSizeToggle.captions << "Pre-Defined" << "Custom";
|
|
||||||
windowSizeToggle.widgetOrientation = Orient_Vertical;
|
|
||||||
windowSizeToggle.isVisible = false;
|
|
||||||
|
|
||||||
//define a widget for each group in the toggle
|
|
||||||
for (int i = 0; i < 2; i++)
|
|
||||||
windowSizeToggle.widgets << new WidgetDef (Widget_RadioButton);
|
|
||||||
|
|
||||||
windowSizeToggle.widgets.at(0)->isDefault = false;
|
|
||||||
|
|
||||||
windowSize.blockDefList << &windowSizeToggle << &definedWindowSize << &customWindowSize;
|
|
||||||
windowSize.defaultValue = "Custom";
|
|
||||||
|
|
||||||
QGridLayout *pageLayout = new QGridLayout(this);
|
|
||||||
|
|
||||||
setLayout (pageLayout);
|
|
||||||
|
|
||||||
mAbstractBlocks << buildBlock<GroupBlock> (topLevelWindowCount)
|
|
||||||
<< buildBlock<GroupBlock> (reuseSubwindow)
|
|
||||||
<< buildBlock<ToggleBlock> (windowSize)
|
|
||||||
<< buildBlock<GroupBlock> (undoStack);
|
|
||||||
|
|
||||||
foreach (AbstractBlock *block, mAbstractBlocks)
|
foreach (AbstractBlock *block, mAbstractBlocks)
|
||||||
{
|
{
|
||||||
connect (block, SIGNAL (signalUpdateSetting (const QString &, const QString &)),
|
connect (block, SIGNAL (signalUpdateSetting (const QString &, const QString &)),
|
||||||
this, SIGNAL (signalUpdateEditorSetting (const QString &, const QString &)) );
|
this, SIGNAL (signalUpdateEditorSetting (const QString &, const QString &)) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connect ( this,
|
||||||
|
SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &)),
|
||||||
|
&(CSMSettings::UserSettings::instance()),
|
||||||
|
SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVSettings::EditorPage::initializeWidgets (const CSMSettings::SettingMap &settings)
|
void CSVSettings::EditorPage::initializeWidgets (const CSMSettings::SettingMap &settings)
|
||||||
|
@ -1,28 +1,33 @@
|
|||||||
#ifndef EDITORPAGE_H
|
#ifndef EDITORPAGE_HPP
|
||||||
#define EDITORPAGE_H
|
#define EDITORPAGE_HPP
|
||||||
|
|
||||||
|
#include "support.hpp"
|
||||||
#include "abstractpage.hpp"
|
#include "abstractpage.hpp"
|
||||||
|
|
||||||
class QGroupBox;
|
namespace CSVSettings
|
||||||
|
{
|
||||||
namespace CSVSettings {
|
|
||||||
|
|
||||||
class UserSettings;
|
|
||||||
class AbstractBlock;
|
|
||||||
|
|
||||||
class EditorPage : public AbstractPage
|
class EditorPage : public AbstractPage
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
explicit EditorPage(QWidget *parent = 0);
|
||||||
|
|
||||||
EditorPage(QWidget *parent = 0);
|
|
||||||
|
|
||||||
void setupUi();
|
|
||||||
void initializeWidgets (const CSMSettings::SettingMap &settings);
|
void initializeWidgets (const CSMSettings::SettingMap &settings);
|
||||||
|
void setupUi();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/// User preference view of the record status delegate's icon / text setting
|
||||||
|
GroupBlockDef *setupRecordStatusDisplay();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
/// Signals up for changes to editor application-level settings
|
||||||
void signalUpdateEditorSetting (const QString &settingName, const QString &settingValue);
|
void signalUpdateEditorSetting (const QString &settingName, const QString &settingValue);
|
||||||
|
|
||||||
|
public slots:
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif //EDITORPAGE_H
|
|
||||||
|
#endif // EDITORPAGE_HPP
|
||||||
|
@ -9,22 +9,22 @@ CSVSettings::GroupBlock::GroupBlock (bool isVisible, QWidget *parent)
|
|||||||
: AbstractBlock (isVisible, parent)
|
: AbstractBlock (isVisible, parent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
int CSVSettings::GroupBlock::build (GroupBlockDef &def)
|
int CSVSettings::GroupBlock::build (GroupBlockDef *def)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (def.properties.size() == 0)
|
if (def->settingItems.size() == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
int retVal = 0;
|
int retVal = 0;
|
||||||
|
|
||||||
setVisible (def.isVisible);
|
setVisible (def->isVisible);
|
||||||
|
|
||||||
mBox->setLayout(createLayout (def.widgetOrientation, true));
|
mBox->setLayout(createLayout (def->widgetOrientation, true));
|
||||||
|
|
||||||
setObjectName (def.title);
|
setObjectName (def->title);
|
||||||
mBox->setTitle (def.title);
|
mBox->setTitle (def->title);
|
||||||
|
|
||||||
foreach (SettingsItemDef *itemDef, def.properties)
|
foreach (SettingsItemDef *itemDef, def->settingItems)
|
||||||
{
|
{
|
||||||
ItemBlock *block = new ItemBlock (mBox);
|
ItemBlock *block = new ItemBlock (mBox);
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@ namespace CSVSettings
|
|||||||
{
|
{
|
||||||
class ItemBlock;
|
class ItemBlock;
|
||||||
|
|
||||||
|
/// Base class for group blocks.
|
||||||
|
/// Derived block classes should use CustomBlock
|
||||||
class GroupBlock : public AbstractBlock
|
class GroupBlock : public AbstractBlock
|
||||||
{
|
{
|
||||||
ItemBlockList mItemBlockList;
|
ItemBlockList mItemBlockList;
|
||||||
@ -16,15 +18,24 @@ namespace CSVSettings
|
|||||||
GroupBlock (QWidget* parent = 0);
|
GroupBlock (QWidget* parent = 0);
|
||||||
GroupBlock (bool isVisible, QWidget *parent = 0);
|
GroupBlock (bool isVisible, QWidget *parent = 0);
|
||||||
|
|
||||||
int build (GroupBlockDef &def);
|
/// build the gorup block based on passed definition
|
||||||
|
int build (GroupBlockDef *def);
|
||||||
|
|
||||||
|
/// update settings local to the group block
|
||||||
bool updateSettings (const CSMSettings::SettingMap &settings);
|
bool updateSettings (const CSMSettings::SettingMap &settings);
|
||||||
|
|
||||||
|
/// retrieve setting list local to the group block
|
||||||
CSMSettings::SettingList *getSettings();
|
CSMSettings::SettingList *getSettings();
|
||||||
|
|
||||||
|
/// retrieve item block by name from the passed list or local list
|
||||||
ItemBlock *getItemBlock (const QString &name, ItemBlockList *blockList = 0);
|
ItemBlock *getItemBlock (const QString &name, ItemBlockList *blockList = 0);
|
||||||
|
|
||||||
|
/// retrieve the item block by index from the local list
|
||||||
ItemBlock *getItemBlock (int index);
|
ItemBlock *getItemBlock (int index);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
/// create block layout based on passed definition
|
||||||
int buildLayout (GroupBlockDef &def);
|
int buildLayout (GroupBlockDef &def);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
namespace CSVSettings
|
namespace CSVSettings
|
||||||
{
|
{
|
||||||
|
/// Custom implementation of QGroupBox to be used with block classes
|
||||||
class GroupBox : public QGroupBox
|
class GroupBox : public QGroupBox
|
||||||
{
|
{
|
||||||
static const QString INVISIBLE_BOX_STYLE;
|
static const QString INVISIBLE_BOX_STYLE;
|
||||||
|
@ -15,22 +15,32 @@ namespace CSVSettings
|
|||||||
|
|
||||||
ItemBlock (QWidget* parent = 0);
|
ItemBlock (QWidget* parent = 0);
|
||||||
|
|
||||||
|
/// pure virtual function not implemneted
|
||||||
bool updateSettings (const CSMSettings::SettingMap &settings) { return false; }
|
bool updateSettings (const CSMSettings::SettingMap &settings) { return false; }
|
||||||
|
|
||||||
CSMSettings::SettingList *getSettings ();
|
CSMSettings::SettingList *getSettings ();
|
||||||
|
|
||||||
QString getValue () const;
|
QString getValue () const;
|
||||||
|
|
||||||
|
/// item blocks encapsulate only one setting
|
||||||
int getSettingCount();
|
int getSettingCount();
|
||||||
|
|
||||||
|
/// update setting value and corresponding widget
|
||||||
bool update (const QString &value);
|
bool update (const QString &value);
|
||||||
|
|
||||||
|
/// virtual construction function
|
||||||
int build(SettingsItemDef &iDef);
|
int build(SettingsItemDef &iDef);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
/// custom construction function
|
||||||
void buildItemBlock (SettingsItemDef& iDef);
|
void buildItemBlock (SettingsItemDef& iDef);
|
||||||
void buildItemBlockWidgets (SettingsItemDef& iDef);
|
void buildItemBlockWidgets (SettingsItemDef& iDef);
|
||||||
|
|
||||||
|
/// update the setting value
|
||||||
bool updateItem (const QString &);
|
bool updateItem (const QString &);
|
||||||
|
|
||||||
|
/// callback function triggered when update to application level is signalled
|
||||||
bool updateBySignal (const QString &name, const QString &value, bool &doEmit);
|
bool updateBySignal (const QString &name, const QString &value, bool &doEmit);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,10 @@ CSVSettings::ProxyBlock::ProxyBlock (QWidget *parent)
|
|||||||
: GroupBlock (parent)
|
: GroupBlock (parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
int CSVSettings::ProxyBlock::build (GroupBlockDef &proxyDef)
|
int CSVSettings::ProxyBlock::build (GroupBlockDef *proxyDef)
|
||||||
{
|
{
|
||||||
//get the list of pre-defined values for the proxy
|
//get the list of pre-defined values for the proxy
|
||||||
mValueList = proxyDef.properties.at(0)->valueList;
|
mValueList = proxyDef->settingItems.at(0)->valueList;
|
||||||
|
|
||||||
bool success = GroupBlock::build(proxyDef);
|
bool success = GroupBlock::build(proxyDef);
|
||||||
|
|
||||||
@ -53,6 +53,8 @@ bool CSVSettings::ProxyBlock::updateProxiedSettings()
|
|||||||
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
//find the value index of the selected value in the proxy setting
|
||||||
for (; i < mValueList->size(); ++i)
|
for (; i < mValueList->size(); ++i)
|
||||||
{
|
{
|
||||||
success = (value == mValueList->at(i));
|
success = (value == mValueList->at(i));
|
||||||
@ -64,6 +66,7 @@ bool CSVSettings::ProxyBlock::updateProxiedSettings()
|
|||||||
if (!success)
|
if (!success)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// update the containing the proxied item's name
|
||||||
foreach (QStringList *list, mProxyList)
|
foreach (QStringList *list, mProxyList)
|
||||||
{
|
{
|
||||||
if ( list->at(0) == block->objectName())
|
if ( list->at(0) == block->objectName())
|
||||||
|
@ -9,8 +9,7 @@ namespace CSVSettings
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
//NOTE: mProxyItemBlockList and mProxyList
|
/// TODO: Combine mProxyItemBlockList and mProxyList.
|
||||||
//should be combined into a value pair and stored in one list.
|
|
||||||
ItemBlockList mProxiedItemBlockList;
|
ItemBlockList mProxiedItemBlockList;
|
||||||
ProxyList mProxyList;
|
ProxyList mProxyList;
|
||||||
QStringList *mValueList;
|
QStringList *mValueList;
|
||||||
@ -20,17 +19,28 @@ namespace CSVSettings
|
|||||||
explicit ProxyBlock (QWidget *parent = 0);
|
explicit ProxyBlock (QWidget *parent = 0);
|
||||||
explicit ProxyBlock (ItemBlock *proxyItemBlock, QWidget *parent = 0);
|
explicit ProxyBlock (ItemBlock *proxyItemBlock, QWidget *parent = 0);
|
||||||
|
|
||||||
|
/// Add a block that contains a proxied setting to the proxy block.
|
||||||
void addSetting (ItemBlock* settingBlock, QStringList *proxyList);
|
void addSetting (ItemBlock* settingBlock, QStringList *proxyList);
|
||||||
int build (GroupBlockDef &def);
|
|
||||||
|
int build (GroupBlockDef *def);
|
||||||
|
|
||||||
CSMSettings::SettingList *getSettings() { return 0; }
|
CSMSettings::SettingList *getSettings() { return 0; }
|
||||||
|
|
||||||
|
/// Update settings local to the proxy block pushed from application level
|
||||||
bool updateSettings (const CSMSettings::SettingMap &settings);
|
bool updateSettings (const CSMSettings::SettingMap &settings);
|
||||||
|
|
||||||
|
/// callback function triggered when update to the application level is signaled.
|
||||||
bool updateBySignal (const QString &name, const QString &value, bool &doEmit);
|
bool updateBySignal (const QString &name, const QString &value, bool &doEmit);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
/// return the item block of a proxied setting
|
||||||
ItemBlock *getProxiedItemBlock (const QString &name);
|
ItemBlock *getProxiedItemBlock (const QString &name);
|
||||||
|
|
||||||
|
/// update the proxy setting with data from the proxied settings
|
||||||
bool updateByProxiedSettings(const CSMSettings::SettingMap *settings = 0);
|
bool updateByProxiedSettings(const CSMSettings::SettingMap *settings = 0);
|
||||||
|
|
||||||
|
/// update proxied settings with data from the proxy setting
|
||||||
bool updateProxiedSettings();
|
bool updateProxiedSettings();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
@ -16,7 +16,8 @@
|
|||||||
|
|
||||||
namespace CSVSettings
|
namespace CSVSettings
|
||||||
{
|
{
|
||||||
//VALID FOR RADIOBUTTON / CHECKBOX (or other toggle widget with it's own label)
|
|
||||||
|
/// Generic template for radiobuttons / checkboxes
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
class SettingWidget : public AbstractWidget
|
class SettingWidget : public AbstractWidget
|
||||||
{
|
{
|
||||||
@ -47,6 +48,7 @@ namespace CSVSettings
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// spin box template
|
||||||
template <>
|
template <>
|
||||||
class SettingWidget <QSpinBox>: public AbstractWidget
|
class SettingWidget <QSpinBox>: public AbstractWidget
|
||||||
{
|
{
|
||||||
@ -90,6 +92,7 @@ namespace CSVSettings
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// combo box template
|
||||||
template <>
|
template <>
|
||||||
class SettingWidget <QComboBox>: public CSVSettings::AbstractWidget
|
class SettingWidget <QComboBox>: public CSVSettings::AbstractWidget
|
||||||
{
|
{
|
||||||
@ -142,6 +145,7 @@ namespace CSVSettings
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// line edit template
|
||||||
template <>
|
template <>
|
||||||
class SettingWidget <QLineEdit>: public CSVSettings::AbstractWidget
|
class SettingWidget <QLineEdit>: public CSVSettings::AbstractWidget
|
||||||
{
|
{
|
||||||
@ -175,6 +179,8 @@ namespace CSVSettings
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// list widget template
|
||||||
|
/// \todo Not fully implemented. Only widget supporting multi-valued settings
|
||||||
template <>
|
template <>
|
||||||
class SettingWidget <QListWidget>: public CSVSettings::AbstractWidget
|
class SettingWidget <QListWidget>: public CSVSettings::AbstractWidget
|
||||||
{
|
{
|
||||||
|
@ -44,21 +44,44 @@ namespace CSVSettings
|
|||||||
Align_Right = Qt::AlignRight
|
Align_Right = Qt::AlignRight
|
||||||
};
|
};
|
||||||
|
|
||||||
//template for defining the widget of a property.
|
/// definition struct for widgets
|
||||||
struct WidgetDef
|
struct WidgetDef
|
||||||
{
|
{
|
||||||
WidgetType type; //type of widget providing input
|
/// type of widget providing input
|
||||||
int labelWidth; //width of caption label
|
WidgetType type;
|
||||||
int widgetWidth; //width of input widget
|
|
||||||
Orientation orientation; //label / widget orientation (horizontal / vertical)
|
/// width of caption label
|
||||||
QString inputMask; //input mask (line edit)
|
int labelWidth;
|
||||||
QString caption; //label caption. Leave empty for multiple items. See BlockDef::captionList
|
|
||||||
QString value; //widget value. Leave empty for multiple items. See BlockDef::valueList
|
/// width of input widget
|
||||||
CSMSettings::QStringPair *minMax; //Min/Max QString value pair. If empty, assigned to property item value pair.
|
int widgetWidth;
|
||||||
QStringList *valueList; //value list for list widgets. If left empty, is assigned to property item value list during block build().
|
|
||||||
bool isDefault; //isDefault - determined at runtime.
|
/// label / widget orientation (horizontal / vertical)
|
||||||
Alignment valueAlignment; //left / center / right-justify text in widget
|
Orientation orientation;
|
||||||
Alignment widgetAlignment; //left / center / right-justify widget in group box
|
|
||||||
|
/// input mask (line edit only)
|
||||||
|
QString inputMask;
|
||||||
|
|
||||||
|
/// label caption. Leave empty for multiple items. See BlockDef::captionList
|
||||||
|
QString caption;
|
||||||
|
|
||||||
|
/// widget value. Leave empty for multiple items. See BlockDef::valueList
|
||||||
|
QString value;
|
||||||
|
|
||||||
|
/// Min/Max QString value pair. If empty, assigned to property item value pair.
|
||||||
|
CSMSettings::QStringPair *minMax;
|
||||||
|
|
||||||
|
/// value list for list widgets. If left empty, is assigned to property item value list during block build().
|
||||||
|
QStringList *valueList;
|
||||||
|
|
||||||
|
/// determined at runtime
|
||||||
|
bool isDefault;
|
||||||
|
|
||||||
|
/// left / center / right-justify text in widget
|
||||||
|
Alignment valueAlignment;
|
||||||
|
|
||||||
|
/// left / center / right-justify widget in group box
|
||||||
|
Alignment widgetAlignment;
|
||||||
|
|
||||||
|
|
||||||
WidgetDef() : labelWidth (-1), widgetWidth (-1),
|
WidgetDef() : labelWidth (-1), widgetWidth (-1),
|
||||||
@ -79,20 +102,34 @@ namespace CSVSettings
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Defines the attributes of the property as it is represented in the config file
|
/// Defines the attributes of the setting as it is represented in the config file
|
||||||
//as well as the UI elements (group box and widget) that serve it.
|
/// as well as the UI elements (group box and widget) that serve it.
|
||||||
//Only one widget may serve as the input widget for the property.
|
/// Only one widget may serve as the input widget for the setting.
|
||||||
struct SettingsItemDef
|
struct SettingsItemDef
|
||||||
{
|
{
|
||||||
QString name; //property name
|
/// setting name
|
||||||
QStringList *valueList; //list of valid values for the property.
|
QString name;
|
||||||
//Used to populate option widget captions or list widget item lists (see WidgetDef::caption / value)
|
|
||||||
|
/// list of valid values for the setting
|
||||||
|
QStringList *valueList;
|
||||||
|
|
||||||
|
/// Used to populate option widget captions or list widget item lists (see WidgetDef::caption / value)
|
||||||
QString defaultValue;
|
QString defaultValue;
|
||||||
|
|
||||||
|
/// flag indicating multi-valued setting
|
||||||
bool hasMultipleValues;
|
bool hasMultipleValues;
|
||||||
CSMSettings::QStringPair minMax; //minimum / maximum value pair
|
|
||||||
WidgetDef widget; //definition of the input widget for this setting
|
/// minimum / maximum value pair
|
||||||
Orientation orientation; //general orientation of the widget / label for this property
|
CSMSettings::QStringPair minMax;
|
||||||
ProxyList *proxyList; //list of property and corresponding default values for proxy widget
|
|
||||||
|
/// definition of the input widget for this setting
|
||||||
|
WidgetDef widget;
|
||||||
|
|
||||||
|
/// general orientation of the widget / label for this setting
|
||||||
|
Orientation orientation;
|
||||||
|
|
||||||
|
/// list of settings and corresponding default values for proxy widget
|
||||||
|
ProxyList *proxyList;
|
||||||
|
|
||||||
SettingsItemDef() : name (""), defaultValue (""), orientation (Orient_Vertical), hasMultipleValues (false)
|
SettingsItemDef() : name (""), defaultValue (""), orientation (Orient_Vertical), hasMultipleValues (false)
|
||||||
{}
|
{}
|
||||||
@ -104,18 +141,32 @@ namespace CSVSettings
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//Hierarchically, this is a "sub-section" of properties within a section, solely for UI organization.
|
/// Generic container block
|
||||||
//Does not correlate to config file structure.
|
|
||||||
struct GroupBlockDef
|
struct GroupBlockDef
|
||||||
{
|
{
|
||||||
QString title; //title of the block containing the property or properties of this sub-section
|
/// block title
|
||||||
QStringList captions; //list of captions for widgets at the block level (not associated with any particular property)
|
QString title;
|
||||||
WidgetList widgets; //list of widgets at the block level (not associated with any particular property)
|
|
||||||
QList<SettingsItemDef *> properties; //list of the property(ies) which are subordinate to the property block.
|
/// list of captions for widgets at the block level (not associated with any particular setting)
|
||||||
Orientation widgetOrientation; //general orientation of widgets in group block
|
QStringList captions;
|
||||||
bool isVisible; //determines whether or not box border/title are visible
|
|
||||||
bool isProxy; //indicates whether or not this block defines a proxy block
|
/// list of widgets at the block level (not associated with any particular setting)
|
||||||
QString defaultValue; //generic default value attribute
|
WidgetList widgets;
|
||||||
|
|
||||||
|
/// list of the settings which are subordinate to the setting block.
|
||||||
|
QList<SettingsItemDef *> settingItems;
|
||||||
|
|
||||||
|
/// general orientation of widgets in group block
|
||||||
|
Orientation widgetOrientation;
|
||||||
|
|
||||||
|
/// determines whether or not box border/title are visible
|
||||||
|
bool isVisible;
|
||||||
|
|
||||||
|
/// indicates whether or not this block defines a proxy block
|
||||||
|
bool isProxy;
|
||||||
|
|
||||||
|
/// generic default value attribute
|
||||||
|
QString defaultValue;
|
||||||
|
|
||||||
GroupBlockDef (): title(""), widgetOrientation (Orient_Vertical), isVisible (true), isProxy (false), defaultValue ("")
|
GroupBlockDef (): title(""), widgetOrientation (Orient_Vertical), isVisible (true), isProxy (false), defaultValue ("")
|
||||||
{}
|
{}
|
||||||
@ -125,11 +176,19 @@ namespace CSVSettings
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// used to create unique, complex blocks
|
||||||
struct CustomBlockDef
|
struct CustomBlockDef
|
||||||
{
|
{
|
||||||
|
/// block title
|
||||||
QString title;
|
QString title;
|
||||||
QString defaultValue; //default value for widgets unique to the custom block
|
|
||||||
GroupBlockDefList blockDefList; //list of settings groups that comprise the settings within the custom block
|
/// default value for widgets unique to the custom block
|
||||||
|
QString defaultValue;
|
||||||
|
|
||||||
|
/// list of settings groups that comprise the settings within the custom block
|
||||||
|
GroupBlockDefList blockDefList;
|
||||||
|
|
||||||
|
/// orientation of the widgets within the block
|
||||||
Orientation blockOrientation;
|
Orientation blockOrientation;
|
||||||
|
|
||||||
CustomBlockDef (): title (""), defaultValue (""), blockOrientation (Orient_Horizontal)
|
CustomBlockDef (): title (""), defaultValue (""), blockOrientation (Orient_Horizontal)
|
||||||
|
@ -7,24 +7,24 @@ CSVSettings::ToggleBlock::ToggleBlock(QWidget *parent) :
|
|||||||
CustomBlock(parent)
|
CustomBlock(parent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
int CSVSettings::ToggleBlock::build(CustomBlockDef &def)
|
int CSVSettings::ToggleBlock::build(CustomBlockDef *def)
|
||||||
{
|
{
|
||||||
if (def.blockDefList.size()==0)
|
if (def->blockDefList.size()==0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
QList<GroupBlockDef *>::Iterator it = def.blockDefList.begin();
|
QList<GroupBlockDef *>::Iterator it = def->blockDefList.begin();
|
||||||
|
|
||||||
//first def in the list is the def for the toggle block
|
//first def in the list is the def for the toggle block
|
||||||
GroupBlockDef *toggleDef = *it++;
|
GroupBlockDef *toggleDef = *it++;
|
||||||
|
|
||||||
if (toggleDef->captions.size() != def.blockDefList.size()-1 )
|
if (toggleDef->captions.size() != def->blockDefList.size()-1 )
|
||||||
return -2;
|
return -2;
|
||||||
|
|
||||||
if (toggleDef->widgets.size() == 0)
|
if (toggleDef->widgets.size() == 0)
|
||||||
return -3;
|
return -3;
|
||||||
|
|
||||||
//create the toogle block UI structure
|
//create the toogle block UI structure
|
||||||
QLayout *blockLayout = createLayout (def.blockOrientation, true);
|
QLayout *blockLayout = createLayout (def->blockOrientation, true);
|
||||||
GroupBox *propertyBox = buildGroupBox (toggleDef->widgetOrientation);
|
GroupBox *propertyBox = buildGroupBox (toggleDef->widgetOrientation);
|
||||||
|
|
||||||
mBox->setLayout(blockLayout);
|
mBox->setLayout(blockLayout);
|
||||||
@ -34,13 +34,13 @@ int CSVSettings::ToggleBlock::build(CustomBlockDef &def)
|
|||||||
//this manages proxy block construction.
|
//this manages proxy block construction.
|
||||||
//Any settings managed by the proxy setting
|
//Any settings managed by the proxy setting
|
||||||
//must be included in the blocks defined in the list.
|
//must be included in the blocks defined in the list.
|
||||||
CustomBlock::build (def.blockDefList, &it);
|
CustomBlock::build (def->blockDefList, &it);
|
||||||
|
|
||||||
for (GroupBlockList::iterator it = mGroupList.begin(); it != mGroupList.end(); ++it)
|
for (GroupBlockList::iterator it = mGroupList.begin(); it != mGroupList.end(); ++it)
|
||||||
propertyBox->layout()->addWidget ((*it)->getGroupBox());
|
propertyBox->layout()->addWidget ((*it)->getGroupBox());
|
||||||
|
|
||||||
//build togle widgets, linking them to the settings
|
//build togle widgets, linking them to the settings
|
||||||
GroupBox *toggleBox = buildToggleWidgets (*toggleDef, def.defaultValue);
|
GroupBox *toggleBox = buildToggleWidgets (toggleDef, def->defaultValue);
|
||||||
|
|
||||||
blockLayout->addWidget(toggleBox);
|
blockLayout->addWidget(toggleBox);
|
||||||
blockLayout->addWidget(propertyBox);
|
blockLayout->addWidget(propertyBox);
|
||||||
@ -49,16 +49,16 @@ int CSVSettings::ToggleBlock::build(CustomBlockDef &def)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVSettings::GroupBox *CSVSettings::ToggleBlock::buildToggleWidgets (GroupBlockDef &def, QString &defaultToggle)
|
CSVSettings::GroupBox *CSVSettings::ToggleBlock::buildToggleWidgets (GroupBlockDef *def, QString &defaultToggle)
|
||||||
{
|
{
|
||||||
GroupBox *box = new GroupBox (false, getParent());
|
GroupBox *box = new GroupBox (false, getParent());
|
||||||
|
|
||||||
QLayout *layout = createLayout (def.widgetOrientation, true, static_cast<QWidget *>(box));
|
QLayout *layout = createLayout (def->widgetOrientation, true, static_cast<QWidget *>(box));
|
||||||
|
|
||||||
for (int i = 0; i < def.widgets.size(); ++i)
|
for (int i = 0; i < def->widgets.size(); ++i)
|
||||||
{
|
{
|
||||||
QString caption = def.captions.at(i);
|
QString caption = def->captions.at(i);
|
||||||
WidgetDef *wDef = def.widgets.at(i);
|
WidgetDef *wDef = def->widgets.at(i);
|
||||||
|
|
||||||
wDef->caption = caption;
|
wDef->caption = caption;
|
||||||
wDef->widgetAlignment = Align_Left;
|
wDef->widgetAlignment = Align_Left;
|
||||||
|
@ -18,10 +18,12 @@ namespace CSVSettings
|
|||||||
public:
|
public:
|
||||||
explicit ToggleBlock(QWidget *parent = 0);
|
explicit ToggleBlock(QWidget *parent = 0);
|
||||||
|
|
||||||
int build (CustomBlockDef &def);
|
int build (CustomBlockDef *def);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GroupBox *buildToggleWidgets (GroupBlockDef &def, QString &defaultToggle);
|
/// Constructor for toggle widgets that are specific to toggle block
|
||||||
|
/// Widgets are not a part of the user preference settings
|
||||||
|
GroupBox *buildToggleWidgets (GroupBlockDef *def, QString &defaultToggle);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif // TOGGLEBLOCK_HPP
|
#endif // TOGGLEBLOCK_HPP
|
||||||
|
@ -10,25 +10,26 @@
|
|||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QDockWidget>
|
#include <QDockWidget>
|
||||||
|
|
||||||
#include "blankpage.hpp"
|
#include <QGridLayout>
|
||||||
#include "editorpage.hpp"
|
|
||||||
#include "../../model/settings/support.hpp"
|
|
||||||
|
|
||||||
|
#include "editorpage.hpp"
|
||||||
|
#include "windowpage.hpp"
|
||||||
|
|
||||||
|
#include "../../model/settings/support.hpp"
|
||||||
|
#include <boost/filesystem/path.hpp>
|
||||||
#include "settingwidget.hpp"
|
#include "settingwidget.hpp"
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
CSVSettings::UserSettingsDialog::UserSettingsDialog(QMainWindow *parent) :
|
CSVSettings::UserSettingsDialog::UserSettingsDialog(QMainWindow *parent) :
|
||||||
QMainWindow (parent), mStackedWidget (0)
|
QMainWindow (parent), mStackedWidget (0)
|
||||||
{
|
{
|
||||||
setWindowTitle(QString::fromUtf8 ("User Settings"));
|
setWindowTitle(QString::fromUtf8 ("User Settings"));
|
||||||
buildPages();
|
buildPages();
|
||||||
setWidgetStates (loadSettings());
|
setWidgetStates ();
|
||||||
positionWindow ();
|
|
||||||
|
|
||||||
connect (mListWidget,
|
connect (mListWidget,
|
||||||
SIGNAL (currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
|
SIGNAL (currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
|
||||||
this,
|
this,
|
||||||
SLOT (slotChangePage (QListWidgetItem*, QListWidgetItem*)));
|
SLOT (slotChangePage (QListWidgetItem*, QListWidgetItem*)));
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVSettings::UserSettingsDialog::~UserSettingsDialog()
|
CSVSettings::UserSettingsDialog::~UserSettingsDialog()
|
||||||
@ -40,17 +41,21 @@ void CSVSettings::UserSettingsDialog::closeEvent (QCloseEvent *event)
|
|||||||
writeSettings();
|
writeSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVSettings::UserSettingsDialog::setWidgetStates (CSMSettings::SectionMap settingsMap)
|
void CSVSettings::UserSettingsDialog::setWidgetStates ()
|
||||||
{
|
{
|
||||||
|
CSMSettings::UserSettings::instance().loadSettings("opencs.cfg");
|
||||||
|
const CSMSettings::SectionMap §ionSettings = CSMSettings::UserSettings::instance().getSettings();
|
||||||
|
|
||||||
//iterate the tabWidget's pages (sections)
|
//iterate the tabWidget's pages (sections)
|
||||||
for (int i = 0; i < mStackedWidget->count(); i++)
|
for (int i = 0; i < mStackedWidget->count(); i++)
|
||||||
{
|
{
|
||||||
//get the settings defined for the entire section
|
//get the settings defined for the entire section
|
||||||
CSMSettings::SettingMap *settings = settingsMap [mStackedWidget->widget(i)->objectName()];
|
//and update widget
|
||||||
|
QString pageName = mStackedWidget->widget(i)->objectName();
|
||||||
|
|
||||||
//if found, initialize the page's widgets
|
if (sectionSettings.find(pageName) != sectionSettings.end())
|
||||||
if (settings)
|
|
||||||
{
|
{
|
||||||
|
CSMSettings::SettingMap *settings = sectionSettings.value(pageName);
|
||||||
AbstractPage *page = getAbstractPage (i);
|
AbstractPage *page = getAbstractPage (i);
|
||||||
page->initializeWidgets(*settings);
|
page->initializeWidgets(*settings);
|
||||||
}
|
}
|
||||||
@ -65,83 +70,24 @@ void CSVSettings::UserSettingsDialog::buildPages()
|
|||||||
mListWidget = new QListWidget (centralWidget);
|
mListWidget = new QListWidget (centralWidget);
|
||||||
mStackedWidget = new QStackedWidget (centralWidget);
|
mStackedWidget = new QStackedWidget (centralWidget);
|
||||||
|
|
||||||
QLayout* dialogLayout = new QHBoxLayout();
|
QGridLayout* dialogLayout = new QGridLayout();
|
||||||
|
|
||||||
dialogLayout->addWidget (mListWidget);
|
mListWidget->setMinimumWidth(0);
|
||||||
dialogLayout->addWidget (mStackedWidget);
|
mListWidget->setSizePolicy (QSizePolicy::Preferred, QSizePolicy::Expanding);
|
||||||
|
|
||||||
|
mStackedWidget->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||||
|
|
||||||
|
dialogLayout->addWidget (mListWidget,0,0);
|
||||||
|
dialogLayout->addWidget (mStackedWidget,0,1, Qt::AlignTop);
|
||||||
|
|
||||||
centralWidget->setLayout (dialogLayout);
|
centralWidget->setLayout (dialogLayout);
|
||||||
|
|
||||||
setCentralWidget (centralWidget);
|
setCentralWidget (centralWidget);
|
||||||
setDockOptions (QMainWindow::AllowNestedDocks);
|
setDockOptions (QMainWindow::AllowNestedDocks);
|
||||||
//uncomment to test with sample editor page.
|
|
||||||
//createSamplePage();
|
|
||||||
createPage<BlankPage>("Page1");
|
|
||||||
createPage<BlankPage>("Page2");
|
|
||||||
createPage<BlankPage>("Page3");
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSVSettings::UserSettingsDialog::createSamplePage()
|
createPage<WindowPage>();
|
||||||
{
|
createPage<EditorPage>();
|
||||||
//add pages to stackedwidget and items to listwidget
|
|
||||||
CSVSettings::AbstractPage *page
|
|
||||||
= new CSVSettings::EditorPage(this);
|
|
||||||
|
|
||||||
mStackedWidget->addWidget (page);
|
|
||||||
|
|
||||||
new QListWidgetItem (page->objectName(), mListWidget);
|
|
||||||
|
|
||||||
connect ( page, SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &)),
|
|
||||||
&(CSMSettings::UserSettings::instance()), SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSVSettings::UserSettingsDialog::positionWindow ()
|
|
||||||
{
|
|
||||||
QRect scr = QApplication::desktop()->screenGeometry();
|
|
||||||
|
|
||||||
move(scr.center().x() - (width() / 2), scr.center().y() - (height() / 2));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
CSMSettings::SectionMap CSVSettings::UserSettingsDialog::loadSettings ()
|
|
||||||
{
|
|
||||||
QString userPath = QString::fromStdString(mCfgMgr.getUserPath().string());
|
|
||||||
|
|
||||||
mPaths.append(QString("opencs.cfg"));
|
|
||||||
mPaths.append(userPath + QString("opencs.cfg"));
|
|
||||||
|
|
||||||
CSMSettings::SectionMap settingsMap;
|
|
||||||
|
|
||||||
foreach (const QString &path, mPaths)
|
|
||||||
{
|
|
||||||
qDebug() << "Loading config file:" << qPrintable(path);
|
|
||||||
QFile file(path);
|
|
||||||
|
|
||||||
if (file.exists())
|
|
||||||
{
|
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
|
||||||
{
|
|
||||||
QMessageBox msgBox;
|
|
||||||
msgBox.setWindowTitle(tr("Error opening OpenCS configuration file"));
|
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
|
||||||
msgBox.setText(QObject::tr("<br><b>Could not open %0 for reading</b><br><br> \
|
|
||||||
Please make sure you have the right permissions \
|
|
||||||
and try again.<br>").arg(file.fileName()));
|
|
||||||
msgBox.exec();
|
|
||||||
return settingsMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
QTextStream stream(&file);
|
|
||||||
stream.setCodec(QTextCodec::codecForName("UTF-8"));
|
|
||||||
|
|
||||||
CSMSettings::UserSettings::instance().getSettings(stream, settingsMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return settingsMap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVSettings::UserSettingsDialog::writeSettings()
|
void CSVSettings::UserSettingsDialog::writeSettings()
|
||||||
@ -153,9 +99,7 @@ void CSVSettings::UserSettingsDialog::writeSettings()
|
|||||||
AbstractPage *page = getAbstractPage (i);
|
AbstractPage *page = getAbstractPage (i);
|
||||||
settings [page->objectName()] = page->getSettings();
|
settings [page->objectName()] = page->getSettings();
|
||||||
}
|
}
|
||||||
|
CSMSettings::UserSettings::instance().writeSettings(settings);
|
||||||
CSMSettings::UserSettings::instance().writeFile(CSMSettings::UserSettings::instance().openFile(mPaths.back()), settings);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVSettings::AbstractPage *CSVSettings::UserSettingsDialog::getAbstractPage (int index)
|
CSVSettings::AbstractPage *CSVSettings::UserSettingsDialog::getAbstractPage (int index)
|
||||||
|
@ -4,14 +4,13 @@
|
|||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QStackedWidget>
|
#include <QStackedWidget>
|
||||||
#include <QListWidgetItem>
|
#include <QListWidgetItem>
|
||||||
|
#include <QApplication>
|
||||||
#ifndef Q_MOC_RUN
|
|
||||||
#include <components/files/configurationmanager.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "../../model/settings/usersettings.hpp"
|
#include "../../model/settings/usersettings.hpp"
|
||||||
#include "../../model/settings/support.hpp"
|
#include "../../model/settings/support.hpp"
|
||||||
|
|
||||||
|
#include "editorpage.hpp"
|
||||||
|
|
||||||
class QHBoxLayout;
|
class QHBoxLayout;
|
||||||
class AbstractWidget;
|
class AbstractWidget;
|
||||||
class QStackedWidget;
|
class QStackedWidget;
|
||||||
@ -25,10 +24,8 @@ namespace CSVSettings {
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
QStringList mPaths;
|
|
||||||
QListWidget *mListWidget;
|
QListWidget *mListWidget;
|
||||||
QStackedWidget *mStackedWidget;
|
QStackedWidget *mStackedWidget;
|
||||||
Files::ConfigurationManager mCfgMgr;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UserSettingsDialog(QMainWindow *parent = 0);
|
UserSettingsDialog(QMainWindow *parent = 0);
|
||||||
@ -36,35 +33,39 @@ namespace CSVSettings {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
/// Settings are written on close
|
||||||
void closeEvent (QCloseEvent *event);
|
void closeEvent (QCloseEvent *event);
|
||||||
AbstractPage *getAbstractPage (int index);
|
|
||||||
void setWidgetStates (CSMSettings::SectionMap settingsMap);
|
|
||||||
void buildPages();
|
|
||||||
void positionWindow ();
|
|
||||||
CSMSettings::SectionMap loadSettings();
|
|
||||||
void writeSettings();
|
|
||||||
void createSamplePage();
|
|
||||||
|
|
||||||
|
/// return the setting page by name
|
||||||
|
/// performs dynamic cast to AbstractPage *
|
||||||
|
AbstractPage *getAbstractPage (int index);
|
||||||
|
void setWidgetStates ();
|
||||||
|
void buildPages();
|
||||||
|
void writeSettings();
|
||||||
|
|
||||||
|
/// Templated function to create a custom user preference page
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void createPage (const QString &title)
|
void createPage ()
|
||||||
{
|
{
|
||||||
T *page = new T(title, this);
|
T *page = new T(mStackedWidget);
|
||||||
|
|
||||||
mStackedWidget->addWidget (dynamic_cast<QWidget *>(page));
|
mStackedWidget->addWidget (dynamic_cast<QWidget *>(page));
|
||||||
|
|
||||||
new QListWidgetItem (page->objectName(), mListWidget);
|
new QListWidgetItem (page->objectName(), mListWidget);
|
||||||
|
|
||||||
//finishing touches
|
//finishing touches
|
||||||
if (mStackedWidget->sizeHint().width() < 640)
|
QFontMetrics fm (QApplication::font());
|
||||||
mStackedWidget->sizeHint().setWidth(640);
|
int textWidth = fm.width(page->objectName());
|
||||||
|
|
||||||
if (mStackedWidget->sizeHint().height() < 480)
|
if ((textWidth + 50) > mListWidget->minimumWidth())
|
||||||
mStackedWidget->sizeHint().setHeight(480);
|
mListWidget->setMinimumWidth(textWidth + 50);
|
||||||
|
|
||||||
resize (mStackedWidget->sizeHint());
|
resize (mStackedWidget->sizeHint());
|
||||||
}
|
}
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
|
/// Called when a different page is selected in the left-hand list widget
|
||||||
void slotChangePage (QListWidgetItem*, QListWidgetItem*);
|
void slotChangePage (QListWidgetItem*, QListWidgetItem*);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
144
apps/opencs/view/settings/windowpage.cpp
Normal file
144
apps/opencs/view/settings/windowpage.cpp
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
#include "windowpage.hpp"
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
|
#include <QListView>
|
||||||
|
#include <QGroupBox>
|
||||||
|
#include <QRadioButton>
|
||||||
|
#include <QDockWidget>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QStyle>
|
||||||
|
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
#include <QPlastiqueStyle>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../../model/settings/usersettings.hpp"
|
||||||
|
#include "groupblock.hpp"
|
||||||
|
#include "toggleblock.hpp"
|
||||||
|
#include "../../view/settings/abstractblock.hpp"
|
||||||
|
|
||||||
|
CSVSettings::WindowPage::WindowPage(QWidget *parent):
|
||||||
|
AbstractPage("Window", parent)
|
||||||
|
{
|
||||||
|
// Hacks to get the stylesheet look properly
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
QPlastiqueStyle *style = new QPlastiqueStyle;
|
||||||
|
//profilesComboBox->setStyle(style);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
setupUi();
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVSettings::GroupBlockDef * CSVSettings::WindowPage::buildDefinedWindowSize()
|
||||||
|
{
|
||||||
|
GroupBlockDef *block = new GroupBlockDef ( "Defined Size");
|
||||||
|
|
||||||
|
SettingsItemDef *widthByHeightItem = new SettingsItemDef ("Window Size", "640x480");
|
||||||
|
WidgetDef widthByHeightWidget = WidgetDef (Widget_ComboBox);
|
||||||
|
widthByHeightWidget.widgetWidth = 90;
|
||||||
|
*(widthByHeightItem->valueList) << "640x480" << "800x600" << "1024x768" << "1440x900";
|
||||||
|
|
||||||
|
QStringList *widthProxy = new QStringList;
|
||||||
|
QStringList *heightProxy = new QStringList;
|
||||||
|
|
||||||
|
(*widthProxy) << "Width" << "640" << "800" << "1024" << "1440";
|
||||||
|
(*heightProxy) << "Height" << "480" << "600" << "768" << "900";
|
||||||
|
|
||||||
|
*(widthByHeightItem->proxyList) << widthProxy << heightProxy;
|
||||||
|
|
||||||
|
widthByHeightItem->widget = widthByHeightWidget;
|
||||||
|
|
||||||
|
block->settingItems << widthByHeightItem;
|
||||||
|
block->isProxy = true;
|
||||||
|
block->isVisible = false;
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVSettings::GroupBlockDef *CSVSettings::WindowPage::buildCustomWindowSize()
|
||||||
|
{
|
||||||
|
GroupBlockDef *block = new GroupBlockDef ("Custom Size");
|
||||||
|
|
||||||
|
//custom width
|
||||||
|
SettingsItemDef *widthItem = new SettingsItemDef ("Width", "640");
|
||||||
|
widthItem->widget = WidgetDef (Widget_LineEdit);
|
||||||
|
widthItem->widget.widgetWidth = 45;
|
||||||
|
widthItem->widget.inputMask = "9999";
|
||||||
|
|
||||||
|
//custom height
|
||||||
|
SettingsItemDef *heightItem = new SettingsItemDef ("Height", "480");
|
||||||
|
heightItem->widget = WidgetDef (Widget_LineEdit);
|
||||||
|
heightItem->widget.widgetWidth = 45;
|
||||||
|
heightItem->widget.caption = "x";
|
||||||
|
heightItem->widget.inputMask = "9999";
|
||||||
|
|
||||||
|
block->settingItems << widthItem << heightItem;
|
||||||
|
block->widgetOrientation = Orient_Horizontal;
|
||||||
|
block->isVisible = false;
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVSettings::GroupBlockDef *CSVSettings::WindowPage::buildWindowSizeToggle()
|
||||||
|
{
|
||||||
|
GroupBlockDef *block = new GroupBlockDef ("Window Size");
|
||||||
|
|
||||||
|
// window size toggle
|
||||||
|
block->captions << "Pre-Defined" << "Custom";
|
||||||
|
block->widgetOrientation = Orient_Vertical;
|
||||||
|
block->isVisible = false;
|
||||||
|
|
||||||
|
//define a widget for each group in the toggle
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
block->widgets << new WidgetDef (Widget_RadioButton);
|
||||||
|
|
||||||
|
block->widgets.at(0)->isDefault = false;
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVSettings::CustomBlockDef *CSVSettings::WindowPage::buildWindowSize(GroupBlockDef *toggle_def,
|
||||||
|
GroupBlockDef *defined_def,
|
||||||
|
GroupBlockDef *custom_def)
|
||||||
|
{
|
||||||
|
CustomBlockDef *block = new CustomBlockDef(QString ("Window Size"));
|
||||||
|
|
||||||
|
block->blockDefList << toggle_def << defined_def << custom_def;
|
||||||
|
block->defaultValue = "Custom";
|
||||||
|
|
||||||
|
return block;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::WindowPage::setupUi()
|
||||||
|
{
|
||||||
|
CustomBlockDef *windowSize = buildWindowSize(buildWindowSizeToggle(),
|
||||||
|
buildDefinedWindowSize(),
|
||||||
|
buildCustomWindowSize()
|
||||||
|
);
|
||||||
|
|
||||||
|
mAbstractBlocks << buildBlock<ToggleBlock> (windowSize);
|
||||||
|
|
||||||
|
foreach (AbstractBlock *block, mAbstractBlocks)
|
||||||
|
{
|
||||||
|
connect (block, SIGNAL (signalUpdateSetting (const QString &, const QString &)),
|
||||||
|
this, SIGNAL (signalUpdateEditorSetting (const QString &, const QString &)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
connect ( this,
|
||||||
|
SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &)),
|
||||||
|
&(CSMSettings::UserSettings::instance()),
|
||||||
|
SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &)));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CSVSettings::WindowPage::initializeWidgets (const CSMSettings::SettingMap &settings)
|
||||||
|
{
|
||||||
|
//iterate each item in each blocks in this section
|
||||||
|
//validate the corresponding setting against the defined valuelist if any.
|
||||||
|
for (AbstractBlockList::Iterator it_block = mAbstractBlocks.begin();
|
||||||
|
it_block != mAbstractBlocks.end(); ++it_block)
|
||||||
|
(*it_block)->updateSettings (settings);
|
||||||
|
}
|
34
apps/opencs/view/settings/windowpage.hpp
Normal file
34
apps/opencs/view/settings/windowpage.hpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#ifndef WINDOWPAGE_H
|
||||||
|
#define WINDOWPAGE_H
|
||||||
|
|
||||||
|
#include "abstractpage.hpp"
|
||||||
|
|
||||||
|
class QGroupBox;
|
||||||
|
|
||||||
|
namespace CSVSettings {
|
||||||
|
|
||||||
|
class UserSettings;
|
||||||
|
class AbstractBlock;
|
||||||
|
|
||||||
|
class WindowPage : public AbstractPage
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
WindowPage(QWidget *parent = 0);
|
||||||
|
|
||||||
|
void setupUi();
|
||||||
|
void initializeWidgets (const CSMSettings::SettingMap &settings);
|
||||||
|
|
||||||
|
///
|
||||||
|
GroupBlockDef *buildCustomWindowSize();
|
||||||
|
GroupBlockDef *buildDefinedWindowSize();
|
||||||
|
GroupBlockDef *buildWindowSizeToggle();
|
||||||
|
CustomBlockDef *buildWindowSize (GroupBlockDef *, GroupBlockDef *, GroupBlockDef *);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void signalUpdateEditorSetting (const QString &settingName, const QString &settingValue);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif //WINDOWPAGE_H
|
122
apps/opencs/view/world/recordstatusdelegate.cpp
Normal file
122
apps/opencs/view/world/recordstatusdelegate.cpp
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
#include "recordstatusdelegate.hpp"
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QUndoStack>
|
||||||
|
#include "../../model/settings/usersettings.hpp"
|
||||||
|
|
||||||
|
CSVWorld::RecordStatusDelegate::RecordStatusDelegate(QUndoStack &undoStack, QObject *parent)
|
||||||
|
: CommandDelegate (undoStack, parent)
|
||||||
|
{
|
||||||
|
mModifiedIcon = new QIcon (":./modified.png");
|
||||||
|
mAddedIcon = new QIcon (":./added.png");
|
||||||
|
mDeletedIcon = new QIcon (":./removed.png");
|
||||||
|
mBaseIcon = new QIcon (":./base.png");
|
||||||
|
mIconSize = 16;
|
||||||
|
|
||||||
|
//Offset values are most likely device-dependent.
|
||||||
|
//Need to replace with device-independent references.
|
||||||
|
mTextLeftOffset = 3;
|
||||||
|
mIconTopOffset = -3;
|
||||||
|
|
||||||
|
mStatusDisplay = 0; //icons and text by default. Remove when implemented as a user preference
|
||||||
|
|
||||||
|
mFont = QApplication::font();
|
||||||
|
mFont.setPointSize(10);
|
||||||
|
|
||||||
|
mFontMetrics = new QFontMetrics(mFont);
|
||||||
|
|
||||||
|
mTextAlignment.setAlignment (Qt::AlignLeft | Qt::AlignVCenter );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::RecordStatusDelegate::paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
painter->save();
|
||||||
|
|
||||||
|
QString text = "";
|
||||||
|
QIcon *icon = 0;
|
||||||
|
|
||||||
|
switch (index.data().toInt())
|
||||||
|
{
|
||||||
|
case 0: // State_BaseOnly
|
||||||
|
text = "Base";
|
||||||
|
icon = mBaseIcon;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: // State_Modified
|
||||||
|
text = "Modified";
|
||||||
|
icon = mModifiedIcon;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: // State_Modified_Only
|
||||||
|
text = "Added";
|
||||||
|
icon = mAddedIcon;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3: // State_Deleted
|
||||||
|
|
||||||
|
case 4: // State_Erased
|
||||||
|
text = "Deleted";
|
||||||
|
icon = mDeletedIcon;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect textRect = option.rect;
|
||||||
|
QRect iconRect = option.rect;
|
||||||
|
|
||||||
|
//for icon-only (1), default option.rect centers icon left-to-right
|
||||||
|
//otherwise, size option.rect to fit the icon, forcing left-alignment with text
|
||||||
|
iconRect.setTop (iconRect.top() + mIconTopOffset);
|
||||||
|
iconRect.setBottom (iconRect.top() + mIconSize);
|
||||||
|
|
||||||
|
if (mStatusDisplay == 0 && (icon) )
|
||||||
|
{
|
||||||
|
iconRect.setRight (iconRect.left()+ mIconSize*2);
|
||||||
|
textRect.setLeft (iconRect.right() + mTextLeftOffset *1.25);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
textRect.setLeft (textRect.left() + mTextLeftOffset );
|
||||||
|
|
||||||
|
if ( (mStatusDisplay == 0 || mStatusDisplay == 1) && (icon) )
|
||||||
|
painter->drawPixmap(iconRect.center().x()-10,iconRect.center().y()+2, icon->pixmap(mIconSize, mIconSize));
|
||||||
|
|
||||||
|
// icon + text or text only, or force text if no icon exists for status
|
||||||
|
if (mStatusDisplay == 0 || mStatusDisplay == 2 || !(icon) )
|
||||||
|
{
|
||||||
|
painter->setFont(mFont);
|
||||||
|
painter->drawText(textRect, text, mTextAlignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
painter->restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize CSVWorld::RecordStatusDelegate::sizeHint (const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
return QSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVWorld::CommandDelegate *CSVWorld::RecordStatusDelegateFactory::makeDelegate (QUndoStack& undoStack,
|
||||||
|
QObject *parent) const
|
||||||
|
{
|
||||||
|
return new RecordStatusDelegate (undoStack, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::RecordStatusDelegate::updateEditorSetting (const QString &settingName, const QString &settingValue)
|
||||||
|
{
|
||||||
|
if (settingName == "Record Status Display")
|
||||||
|
{
|
||||||
|
if (settingValue == "Icon and Text")
|
||||||
|
mStatusDisplay = 0;
|
||||||
|
|
||||||
|
else if (settingValue == "Icon Only")
|
||||||
|
mStatusDisplay = 1;
|
||||||
|
|
||||||
|
else if (settingValue == "Text Only")
|
||||||
|
mStatusDisplay = 2;
|
||||||
|
|
||||||
|
else
|
||||||
|
mStatusDisplay = 0;
|
||||||
|
}
|
||||||
|
}
|
53
apps/opencs/view/world/recordstatusdelegate.hpp
Normal file
53
apps/opencs/view/world/recordstatusdelegate.hpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#ifndef RECORDSTATUSDELEGATE_H
|
||||||
|
#define RECORDSTATUSDELEGATE_H
|
||||||
|
|
||||||
|
#include "util.hpp"
|
||||||
|
#include <QTextOption>
|
||||||
|
#include <QFont>
|
||||||
|
|
||||||
|
class QIcon;
|
||||||
|
class QFont;
|
||||||
|
class QFontMetrics;
|
||||||
|
|
||||||
|
namespace CSVWorld
|
||||||
|
{
|
||||||
|
class RecordStatusDelegate : public CommandDelegate
|
||||||
|
{
|
||||||
|
QFont mFont;
|
||||||
|
QFontMetrics *mFontMetrics;
|
||||||
|
|
||||||
|
QTextOption mTextAlignment;
|
||||||
|
|
||||||
|
QIcon *mModifiedIcon;
|
||||||
|
QIcon *mAddedIcon;
|
||||||
|
QIcon *mDeletedIcon;
|
||||||
|
QIcon *mBaseIcon;
|
||||||
|
|
||||||
|
int mStatusDisplay;
|
||||||
|
|
||||||
|
int mIconSize;
|
||||||
|
int mIconTopOffset;
|
||||||
|
int mTextLeftOffset;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit RecordStatusDelegate(QUndoStack& undoStack, QObject *parent = 0);
|
||||||
|
|
||||||
|
void paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||||
|
|
||||||
|
QSize sizeHint (const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||||
|
|
||||||
|
void updateEditorSetting (const QString &settingName, const QString &settingValue);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class RecordStatusDelegateFactory : public CommandDelegateFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual CommandDelegate *makeDelegate (QUndoStack& undoStack, QObject *parent) const;
|
||||||
|
///< The ownership of the returned CommandDelegate is transferred to the caller.
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif // RECORDSTATUSDELEGATE_H
|
||||||
|
|
@ -12,6 +12,7 @@
|
|||||||
#include "../../model/world/idtableproxymodel.hpp"
|
#include "../../model/world/idtableproxymodel.hpp"
|
||||||
#include "../../model/world/idtable.hpp"
|
#include "../../model/world/idtable.hpp"
|
||||||
#include "../../model/world/record.hpp"
|
#include "../../model/world/record.hpp"
|
||||||
|
#include "recordstatusdelegate.hpp"
|
||||||
|
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
|
|
||||||
@ -80,7 +81,7 @@ std::vector<std::string> CSVWorld::Table::listDeletableSelectedIds() const
|
|||||||
|
|
||||||
CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack,
|
CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack,
|
||||||
bool createAndDelete)
|
bool createAndDelete)
|
||||||
: mUndoStack (undoStack), mCreateAction (0), mEditLock (false)
|
: mUndoStack (undoStack), mCreateAction (0), mEditLock (false), mRecordStatusDisplay (0)
|
||||||
{
|
{
|
||||||
mModel = &dynamic_cast<CSMWorld::IdTable&> (*data.getTableModel (id));
|
mModel = &dynamic_cast<CSMWorld::IdTable&> (*data.getTableModel (id));
|
||||||
|
|
||||||
@ -161,6 +162,7 @@ void CSVWorld::Table::createRecord()
|
|||||||
|
|
||||||
mUndoStack.push (new CSMWorld::CreateCommand (*mProxyModel, stream.str()));
|
mUndoStack.push (new CSMWorld::CreateCommand (*mProxyModel, stream.str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVWorld::Table::revertRecord()
|
void CSVWorld::Table::revertRecord()
|
||||||
@ -201,4 +203,13 @@ void CSVWorld::Table::deleteRecord()
|
|||||||
mUndoStack.endMacro();
|
mUndoStack.endMacro();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVWorld::Table::updateEditorSetting (const QString &settingName, const QString &settingValue)
|
||||||
|
{
|
||||||
|
if (settingName == "Record Status Display")
|
||||||
|
{
|
||||||
|
dynamic_cast<CSVWorld::RecordStatusDelegate *>(this->itemDelegateForColumn(1))->updateEditorSetting (settingName, settingValue);
|
||||||
|
emit dataChanged(mModel->index(0,1), mModel->index(mModel->rowCount()-1, 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -34,6 +34,7 @@ namespace CSVWorld
|
|||||||
CSMWorld::IdTableProxyModel *mProxyModel;
|
CSMWorld::IdTableProxyModel *mProxyModel;
|
||||||
CSMWorld::IdTable *mModel;
|
CSMWorld::IdTable *mModel;
|
||||||
bool mEditLock;
|
bool mEditLock;
|
||||||
|
int mRecordStatusDisplay;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -52,6 +53,8 @@ namespace CSVWorld
|
|||||||
|
|
||||||
CSMWorld::UniversalId getUniversalId (int row) const;
|
CSMWorld::UniversalId getUniversalId (int row) const;
|
||||||
|
|
||||||
|
void updateEditorSetting (const QString &settingName, const QString &settingValue);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void createRecord();
|
void createRecord();
|
||||||
|
@ -22,4 +22,11 @@ void CSVWorld::TableSubView::setEditLock (bool locked)
|
|||||||
void CSVWorld::TableSubView::rowActivated (const QModelIndex& index)
|
void CSVWorld::TableSubView::rowActivated (const QModelIndex& index)
|
||||||
{
|
{
|
||||||
focusId (mTable->getUniversalId (index.row()));
|
focusId (mTable->getUniversalId (index.row()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVWorld::TableSubView::updateEditorSetting(const QString &settingName, const QString &settingValue)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (settingName == "Record Status Display")
|
||||||
|
mTable->updateEditorSetting(settingName, settingValue);
|
||||||
|
}
|
||||||
|
@ -23,8 +23,8 @@ namespace CSVWorld
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
TableSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete);
|
TableSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete);
|
||||||
|
|
||||||
virtual void setEditLock (bool locked);
|
virtual void setEditLock (bool locked);
|
||||||
|
void updateEditorSetting (const QString &, const QString &);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
@ -32,4 +32,4 @@ namespace CSVWorld
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -82,6 +82,8 @@ namespace CSVWorld
|
|||||||
///< \brief Use commands instead of manipulating the model directly
|
///< \brief Use commands instead of manipulating the model directly
|
||||||
class CommandDelegate : public QStyledItemDelegate
|
class CommandDelegate : public QStyledItemDelegate
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
QUndoStack& mUndoStack;
|
QUndoStack& mUndoStack;
|
||||||
bool mEditLock;
|
bool mEditLock;
|
||||||
|
|
||||||
@ -105,6 +107,10 @@ namespace CSVWorld
|
|||||||
void setEditLock (bool locked);
|
void setEditLock (bool locked);
|
||||||
|
|
||||||
bool isEditLocked() const;
|
bool isEditLocked() const;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
virtual void slotUpdateEditorSetting (const QString &settingName, const QString &settingValue) {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ add_openmw_dir (mwgui
|
|||||||
enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor spellicons
|
enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor spellicons
|
||||||
merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks
|
merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks
|
||||||
keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview
|
keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview
|
||||||
tradeitemmodel companionitemmodel pickpocketitemmodel
|
tradeitemmodel companionitemmodel pickpocketitemmodel fontloader controllers
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwdialogue
|
add_openmw_dir (mwdialogue
|
||||||
@ -106,19 +106,23 @@ target_link_libraries(openmw
|
|||||||
${OGRE_LIBRARIES}
|
${OGRE_LIBRARIES}
|
||||||
${OGRE_Terrain_LIBRARY}
|
${OGRE_Terrain_LIBRARY}
|
||||||
${OGRE_STATIC_PLUGINS}
|
${OGRE_STATIC_PLUGINS}
|
||||||
${OIS_LIBRARIES}
|
|
||||||
${Boost_LIBRARIES}
|
${Boost_LIBRARIES}
|
||||||
${OPENAL_LIBRARY}
|
${OPENAL_LIBRARY}
|
||||||
${SOUND_INPUT_LIBRARY}
|
${SOUND_INPUT_LIBRARY}
|
||||||
${BULLET_LIBRARIES}
|
${BULLET_LIBRARIES}
|
||||||
${MYGUI_LIBRARIES}
|
${MYGUI_LIBRARIES}
|
||||||
|
${SDL2_LIBRARY}
|
||||||
${MYGUI_PLATFORM_LIBRARIES}
|
${MYGUI_PLATFORM_LIBRARIES}
|
||||||
"shiny"
|
${SHINY_LIBRARIES}
|
||||||
"shiny.OgrePlatform"
|
|
||||||
"oics"
|
"oics"
|
||||||
|
"sdl4ogre"
|
||||||
components
|
components
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (NOT UNIX)
|
||||||
|
target_link_libraries(openmw ${SDL2MAIN_LIBRARY})
|
||||||
|
endif()
|
||||||
|
|
||||||
# Fix for not visible pthreads functions for linker with glibc 2.15
|
# Fix for not visible pthreads functions for linker with glibc 2.15
|
||||||
if (UNIX AND NOT APPLE)
|
if (UNIX AND NOT APPLE)
|
||||||
target_link_libraries(openmw ${CMAKE_THREAD_LIBS_INIT})
|
target_link_libraries(openmw ${CMAKE_THREAD_LIBS_INIT})
|
||||||
@ -131,10 +135,9 @@ endif()
|
|||||||
|
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
find_library(CARBON_FRAMEWORK Carbon)
|
|
||||||
find_library(COCOA_FRAMEWORK Cocoa)
|
find_library(COCOA_FRAMEWORK Cocoa)
|
||||||
find_library(IOKIT_FRAMEWORK IOKit)
|
find_library(IOKIT_FRAMEWORK IOKit)
|
||||||
target_link_libraries(openmw ${CARBON_FRAMEWORK} ${COCOA_FRAMEWORK} ${IOKIT_FRAMEWORK})
|
target_link_libraries(openmw ${COCOA_FRAMEWORK} ${IOKIT_FRAMEWORK})
|
||||||
|
|
||||||
if (FFMPEG_FOUND)
|
if (FFMPEG_FOUND)
|
||||||
find_library(COREVIDEO_FRAMEWORK CoreVideo)
|
find_library(COREVIDEO_FRAMEWORK CoreVideo)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "engine.hpp"
|
#include "engine.hpp"
|
||||||
|
|
||||||
#include "components/esm/loadcell.hpp"
|
#include "components/esm/loadcell.hpp"
|
||||||
|
|
||||||
#include <OgreRoot.h>
|
#include <OgreRoot.h>
|
||||||
@ -37,6 +38,8 @@
|
|||||||
#include "mwmechanics/mechanicsmanagerimp.hpp"
|
#include "mwmechanics/mechanicsmanagerimp.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
void OMW::Engine::executeLocalScripts()
|
void OMW::Engine::executeLocalScripts()
|
||||||
{
|
{
|
||||||
MWWorld::LocalScripts& localScripts = MWBase::Environment::get().getWorld()->getLocalScripts();
|
MWWorld::LocalScripts& localScripts = MWBase::Environment::get().getWorld()->getLocalScripts();
|
||||||
@ -75,7 +78,8 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
float frametime = std::min(evt.timeSinceLastFrame, 0.2f);
|
float frametime = std::min(evt.timeSinceLastFrame, 0.2f);
|
||||||
mEnvironment.setFrameDuration(frametime);
|
|
||||||
|
mEnvironment.setFrameDuration (frametime);
|
||||||
|
|
||||||
// update input
|
// update input
|
||||||
MWBase::Environment::get().getInputManager()->update(frametime, false);
|
MWBase::Environment::get().getInputManager()->update(frametime, false);
|
||||||
@ -129,7 +133,6 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
|
|||||||
OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
|
OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
|
||||||
: mOgre (0)
|
: mOgre (0)
|
||||||
, mFpsLevel(0)
|
, mFpsLevel(0)
|
||||||
, mDebug (false)
|
|
||||||
, mVerboseScripts (false)
|
, mVerboseScripts (false)
|
||||||
, mNewGame (false)
|
, mNewGame (false)
|
||||||
, mUseSound (true)
|
, mUseSound (true)
|
||||||
@ -141,6 +144,18 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
|
|||||||
{
|
{
|
||||||
std::srand ( std::time(NULL) );
|
std::srand ( std::time(NULL) );
|
||||||
MWClass::registerClasses();
|
MWClass::registerClasses();
|
||||||
|
|
||||||
|
Uint32 flags = SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE;
|
||||||
|
if(SDL_WasInit(flags) == 0)
|
||||||
|
{
|
||||||
|
//kindly ask SDL not to trash our OGL context
|
||||||
|
//might this be related to http://bugzilla.libsdl.org/show_bug.cgi?id=748 ?
|
||||||
|
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software");
|
||||||
|
if(SDL_Init(flags) != 0)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Could not initialize SDL! " + std::string(SDL_GetError()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OMW::Engine::~Engine()
|
OMW::Engine::~Engine()
|
||||||
@ -148,6 +163,7 @@ OMW::Engine::~Engine()
|
|||||||
mEnvironment.cleanup();
|
mEnvironment.cleanup();
|
||||||
delete mScriptContext;
|
delete mScriptContext;
|
||||||
delete mOgre;
|
delete mOgre;
|
||||||
|
SDL_Quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load BSA files
|
// Load BSA files
|
||||||
@ -268,11 +284,6 @@ void OMW::Engine::addPlugin (const std::string& plugin)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OMW::Engine::setDebugMode(bool debugMode)
|
|
||||||
{
|
|
||||||
mDebug = debugMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OMW::Engine::setScriptsVerbosity(bool scriptsVerbosity)
|
void OMW::Engine::setScriptsVerbosity(bool scriptsVerbosity)
|
||||||
{
|
{
|
||||||
mVerboseScripts = scriptsVerbosity;
|
mVerboseScripts = scriptsVerbosity;
|
||||||
@ -315,6 +326,8 @@ std::string OMW::Engine::loadSettings (Settings::Manager & settings)
|
|||||||
else if (boost::filesystem::exists(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg"))
|
else if (boost::filesystem::exists(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg"))
|
||||||
nifOverrides.loadTransparencyOverrides(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg");
|
nifOverrides.loadTransparencyOverrides(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg");
|
||||||
|
|
||||||
|
settings.setBool("hardware cursors", "GUI", true);
|
||||||
|
|
||||||
return settingspath;
|
return settingspath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,14 +365,16 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
|||||||
addResourcesDirectory(mResDir / "shadows");
|
addResourcesDirectory(mResDir / "shadows");
|
||||||
addZipResource(mResDir / "mygui" / "Obliviontt.zip");
|
addZipResource(mResDir / "mygui" / "Obliviontt.zip");
|
||||||
|
|
||||||
// Create the window
|
|
||||||
OEngine::Render::WindowSettings windowSettings;
|
OEngine::Render::WindowSettings windowSettings;
|
||||||
windowSettings.fullscreen = settings.getBool("fullscreen", "Video");
|
windowSettings.fullscreen = settings.getBool("fullscreen", "Video");
|
||||||
windowSettings.window_x = settings.getInt("resolution x", "Video");
|
windowSettings.window_x = settings.getInt("resolution x", "Video");
|
||||||
windowSettings.window_y = settings.getInt("resolution y", "Video");
|
windowSettings.window_y = settings.getInt("resolution y", "Video");
|
||||||
|
windowSettings.screen = settings.getInt("screen", "Video");
|
||||||
windowSettings.vsync = settings.getBool("vsync", "Video");
|
windowSettings.vsync = settings.getBool("vsync", "Video");
|
||||||
|
windowSettings.icon = "openmw.png";
|
||||||
std::string aa = settings.getString("antialiasing", "Video");
|
std::string aa = settings.getString("antialiasing", "Video");
|
||||||
windowSettings.fsaa = (aa.substr(0, 4) == "MSAA") ? aa.substr(5, aa.size()-5) : "0";
|
windowSettings.fsaa = (aa.substr(0, 4) == "MSAA") ? aa.substr(5, aa.size()-5) : "0";
|
||||||
|
|
||||||
mOgre->createWindow("OpenMW", windowSettings);
|
mOgre->createWindow("OpenMW", windowSettings);
|
||||||
|
|
||||||
loadBSA();
|
loadBSA();
|
||||||
@ -380,7 +395,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
|||||||
|
|
||||||
mEnvironment.setWindowManager (new MWGui::WindowManager(
|
mEnvironment.setWindowManager (new MWGui::WindowManager(
|
||||||
mExtensions, mFpsLevel, mOgre, mCfgMgr.getLogPath().string() + std::string("/"),
|
mExtensions, mFpsLevel, mOgre, mCfgMgr.getLogPath().string() + std::string("/"),
|
||||||
mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage));
|
mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage, mEncoding));
|
||||||
if (mNewGame)
|
if (mNewGame)
|
||||||
mEnvironment.getWindowManager()->setNewGame(true);
|
mEnvironment.getWindowManager()->setNewGame(true);
|
||||||
|
|
||||||
@ -409,7 +424,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
|||||||
|
|
||||||
mEnvironment.setInputManager (new MWInput::InputManager (*mOgre,
|
mEnvironment.setInputManager (new MWInput::InputManager (*mOgre,
|
||||||
MWBase::Environment::get().getWorld()->getPlayer(),
|
MWBase::Environment::get().getWorld()->getPlayer(),
|
||||||
*MWBase::Environment::get().getWindowManager(), mDebug, *this, keybinderUser, keybinderUserExists));
|
*MWBase::Environment::get().getWindowManager(), *this, keybinderUser, keybinderUserExists));
|
||||||
|
|
||||||
mEnvironment.getWorld()->renderPlayer();
|
mEnvironment.getWorld()->renderPlayer();
|
||||||
|
|
||||||
|
@ -71,7 +71,6 @@ namespace OMW
|
|||||||
std::vector<std::string> mMaster;
|
std::vector<std::string> mMaster;
|
||||||
std::vector<std::string> mPlugins;
|
std::vector<std::string> mPlugins;
|
||||||
int mFpsLevel;
|
int mFpsLevel;
|
||||||
bool mDebug;
|
|
||||||
bool mVerboseScripts;
|
bool mVerboseScripts;
|
||||||
bool mNewGame;
|
bool mNewGame;
|
||||||
bool mUseSound;
|
bool mUseSound;
|
||||||
@ -147,10 +146,6 @@ namespace OMW
|
|||||||
/// Enable fps counter
|
/// Enable fps counter
|
||||||
void showFPS(int level);
|
void showFPS(int level);
|
||||||
|
|
||||||
/// Enable debug mode:
|
|
||||||
/// - non-exclusive input
|
|
||||||
void setDebugMode(bool debugMode);
|
|
||||||
|
|
||||||
/// Enable or disable verbose script output
|
/// Enable or disable verbose script output
|
||||||
void setScriptsVerbosity(bool scriptsVerbosity);
|
void setScriptsVerbosity(bool scriptsVerbosity);
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <components/files/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
|
||||||
|
#include <SDL_main.h>
|
||||||
#include "engine.hpp"
|
#include "engine.hpp"
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(_CONSOLE)
|
#if defined(_WIN32) && !defined(_CONSOLE)
|
||||||
@ -118,9 +119,6 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
|||||||
("anim-verbose", bpo::value<bool>()->implicit_value(true)
|
("anim-verbose", bpo::value<bool>()->implicit_value(true)
|
||||||
->default_value(false), "output animation indices files")
|
->default_value(false), "output animation indices files")
|
||||||
|
|
||||||
("debug", bpo::value<bool>()->implicit_value(true)
|
|
||||||
->default_value(false), "debug mode")
|
|
||||||
|
|
||||||
("nosound", bpo::value<bool>()->implicit_value(true)
|
("nosound", bpo::value<bool>()->implicit_value(true)
|
||||||
->default_value(false), "disable all sounds")
|
->default_value(false), "disable all sounds")
|
||||||
|
|
||||||
@ -217,8 +215,8 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
|||||||
StringsVector master = variables["master"].as<StringsVector>();
|
StringsVector master = variables["master"].as<StringsVector>();
|
||||||
if (master.empty())
|
if (master.empty())
|
||||||
{
|
{
|
||||||
std::cout << "No master file given. Assuming Morrowind.esm" << std::endl;
|
std::cout << "No master file given. Aborting...\n";
|
||||||
master.push_back("Morrowind");
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringsVector plugin = variables["plugin"].as<StringsVector>();
|
StringsVector plugin = variables["plugin"].as<StringsVector>();
|
||||||
@ -243,7 +241,6 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
|||||||
engine.setNewGame(variables["new-game"].as<bool>());
|
engine.setNewGame(variables["new-game"].as<bool>());
|
||||||
|
|
||||||
// other settings
|
// other settings
|
||||||
engine.setDebugMode(variables["debug"].as<bool>());
|
|
||||||
engine.setSoundUsage(!variables["nosound"].as<bool>());
|
engine.setSoundUsage(!variables["nosound"].as<bool>());
|
||||||
engine.setScriptsVerbosity(variables["script-verbose"].as<bool>());
|
engine.setScriptsVerbosity(variables["script-verbose"].as<bool>());
|
||||||
engine.setCompileAll(variables["script-all"].as<bool>());
|
engine.setCompileAll(variables["script-all"].as<bool>());
|
||||||
|
@ -112,6 +112,8 @@ namespace MWBase
|
|||||||
virtual void skipAnimation(const MWWorld::Ptr& ptr) = 0;
|
virtual void skipAnimation(const MWWorld::Ptr& ptr) = 0;
|
||||||
///< Skip the animation for the given MW-reference for one frame. Calls to this function for
|
///< Skip the animation for the given MW-reference for one frame. Calls to this function for
|
||||||
/// references that are currently not in the scene should be ignored.
|
/// references that are currently not in the scene should be ignored.
|
||||||
|
|
||||||
|
virtual bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +55,11 @@ namespace MWGui
|
|||||||
class DialogueWindow;
|
class DialogueWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace SFO
|
||||||
|
{
|
||||||
|
class CursorManager;
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWBase
|
namespace MWBase
|
||||||
{
|
{
|
||||||
/// \brief Interface for widnow manager (implemented in MWGui)
|
/// \brief Interface for widnow manager (implemented in MWGui)
|
||||||
@ -92,6 +97,7 @@ namespace MWBase
|
|||||||
virtual void updatePlayer() = 0;
|
virtual void updatePlayer() = 0;
|
||||||
|
|
||||||
virtual MWGui::GuiMode getMode() const = 0;
|
virtual MWGui::GuiMode getMode() const = 0;
|
||||||
|
virtual bool containsMode(MWGui::GuiMode) const = 0;
|
||||||
|
|
||||||
virtual bool isGuiMode() const = 0;
|
virtual bool isGuiMode() const = 0;
|
||||||
|
|
||||||
@ -159,7 +165,7 @@ namespace MWBase
|
|||||||
virtual void setFocusObject(const MWWorld::Ptr& focus) = 0;
|
virtual void setFocusObject(const MWWorld::Ptr& focus) = 0;
|
||||||
virtual void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y) = 0;
|
virtual void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y) = 0;
|
||||||
|
|
||||||
virtual void setMouseVisible(bool visible) = 0;
|
virtual void setCursorVisible(bool visible) = 0;
|
||||||
virtual void getMousePosition(int &x, int &y) = 0;
|
virtual void getMousePosition(int &x, int &y) = 0;
|
||||||
virtual void getMousePosition(float &x, float &y) = 0;
|
virtual void getMousePosition(float &x, float &y) = 0;
|
||||||
virtual void setDragDrop(bool dragDrop) = 0;
|
virtual void setDragDrop(bool dragDrop) = 0;
|
||||||
@ -258,6 +264,8 @@ namespace MWBase
|
|||||||
virtual void changePointer (const std::string& name) = 0;
|
virtual void changePointer (const std::string& name) = 0;
|
||||||
|
|
||||||
virtual const Translation::Storage& getTranslationDataStorage() const = 0;
|
virtual const Translation::Storage& getTranslationDataStorage() const = 0;
|
||||||
|
|
||||||
|
virtual void setKeyFocusWidget (MyGUI::Widget* widget) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,6 +342,10 @@ namespace MWBase
|
|||||||
|
|
||||||
virtual void getContainersOwnedBy (const MWWorld::Ptr& npc, std::vector<MWWorld::Ptr>& out) = 0;
|
virtual void getContainersOwnedBy (const MWWorld::Ptr& npc, std::vector<MWWorld::Ptr>& out) = 0;
|
||||||
///< get all containers in active cells owned by this Npc
|
///< get all containers in active cells owned by this Npc
|
||||||
|
virtual void getItemsOwnedBy (const MWWorld::Ptr& npc, std::vector<MWWorld::Ptr>& out) = 0;
|
||||||
|
///< get all items in active cells owned by this Npc
|
||||||
|
|
||||||
|
virtual void enableActorCollision(const MWWorld::Ptr& actor, bool enable) = 0;
|
||||||
|
|
||||||
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0;
|
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0;
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "../mwmechanics/creaturestats.hpp"
|
#include "../mwmechanics/creaturestats.hpp"
|
||||||
#include "../mwmechanics/magiceffects.hpp"
|
#include "../mwmechanics/magiceffects.hpp"
|
||||||
|
#include "../mwmechanics/movement.hpp"
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/mechanicsmanager.hpp"
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
@ -29,6 +30,7 @@ namespace
|
|||||||
{
|
{
|
||||||
MWMechanics::CreatureStats mCreatureStats;
|
MWMechanics::CreatureStats mCreatureStats;
|
||||||
MWWorld::ContainerStore mContainerStore;
|
MWWorld::ContainerStore mContainerStore;
|
||||||
|
MWMechanics::Movement mMovement;
|
||||||
|
|
||||||
virtual MWWorld::CustomData *clone() const;
|
virtual MWWorld::CustomData *clone() const;
|
||||||
};
|
};
|
||||||
@ -47,6 +49,18 @@ namespace MWClass
|
|||||||
{
|
{
|
||||||
std::auto_ptr<CustomData> data (new CustomData);
|
std::auto_ptr<CustomData> data (new CustomData);
|
||||||
|
|
||||||
|
static bool inited = false;
|
||||||
|
if(!inited)
|
||||||
|
{
|
||||||
|
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
|
const MWWorld::Store<ESM::GameSetting> &gmst = world->getStore().get<ESM::GameSetting>();
|
||||||
|
|
||||||
|
fMinWalkSpeedCreature = gmst.find("fMinWalkSpeedCreature");
|
||||||
|
fMaxWalkSpeedCreature = gmst.find("fMaxWalkSpeedCreature");
|
||||||
|
|
||||||
|
inited = true;
|
||||||
|
}
|
||||||
|
|
||||||
MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
|
MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
|
||||||
|
|
||||||
// creature stats
|
// creature stats
|
||||||
@ -181,6 +195,42 @@ namespace MWClass
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float Creature::getSpeed(const MWWorld::Ptr &ptr) const
|
||||||
|
{
|
||||||
|
MWMechanics::CreatureStats& stats = getCreatureStats(ptr);
|
||||||
|
float walkSpeed = fMinWalkSpeedCreature->getFloat() + 0.01 * stats.getAttribute(ESM::Attribute::Speed).getModified()
|
||||||
|
* (fMaxWalkSpeedCreature->getFloat() - fMinWalkSpeedCreature->getFloat());
|
||||||
|
/// \todo what about the rest?
|
||||||
|
return walkSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
MWMechanics::Movement& Creature::getMovementSettings (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
ensureCustomData (ptr);
|
||||||
|
|
||||||
|
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mMovement;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ogre::Vector3 Creature::getMovementVector (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
MWMechanics::Movement &movement = getMovementSettings(ptr);
|
||||||
|
Ogre::Vector3 vec(movement.mPosition);
|
||||||
|
movement.mPosition[0] = 0.0f;
|
||||||
|
movement.mPosition[1] = 0.0f;
|
||||||
|
movement.mPosition[2] = 0.0f;
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ogre::Vector3 Creature::getRotationVector (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
MWMechanics::Movement &movement = getMovementSettings(ptr);
|
||||||
|
Ogre::Vector3 vec(movement.mRotation);
|
||||||
|
movement.mRotation[0] = 0.0f;
|
||||||
|
movement.mRotation[1] = 0.0f;
|
||||||
|
movement.mRotation[2] = 0.0f;
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
MWGui::ToolTipInfo Creature::getToolTipInfo (const MWWorld::Ptr& ptr) const
|
MWGui::ToolTipInfo Creature::getToolTipInfo (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
MWWorld::LiveCellRef<ESM::Creature> *ref =
|
MWWorld::LiveCellRef<ESM::Creature> *ref =
|
||||||
@ -249,4 +299,7 @@ namespace MWClass
|
|||||||
|
|
||||||
return MWWorld::Ptr(&cell.mCreatures.insert(*ref), &cell);
|
return MWWorld::Ptr(&cell.mCreatures.insert(*ref), &cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ESM::GameSetting* Creature::fMinWalkSpeedCreature;
|
||||||
|
const ESM::GameSetting* Creature::fMaxWalkSpeedCreature;
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,9 @@ namespace MWClass
|
|||||||
virtual MWWorld::Ptr
|
virtual MWWorld::Ptr
|
||||||
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
|
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
|
||||||
|
|
||||||
|
static const ESM::GameSetting *fMinWalkSpeedCreature;
|
||||||
|
static const ESM::GameSetting *fMaxWalkSpeedCreature;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual std::string getId (const MWWorld::Ptr& ptr) const;
|
virtual std::string getId (const MWWorld::Ptr& ptr) const;
|
||||||
@ -66,6 +69,18 @@ namespace MWClass
|
|||||||
|
|
||||||
virtual bool isPersistent (const MWWorld::Ptr& ptr) const;
|
virtual bool isPersistent (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
|
virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const;
|
||||||
|
///< Return desired movement.
|
||||||
|
|
||||||
|
virtual Ogre::Vector3 getMovementVector (const MWWorld::Ptr& ptr) const;
|
||||||
|
///< Return desired movement vector (determined based on movement settings,
|
||||||
|
/// stance and stats).
|
||||||
|
|
||||||
|
virtual Ogre::Vector3 getRotationVector (const MWWorld::Ptr& ptr) const;
|
||||||
|
///< Return desired rotations, as euler angles.
|
||||||
|
|
||||||
|
float getSpeed (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
static void registerSelf();
|
static void registerSelf();
|
||||||
|
|
||||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||||
|
@ -223,6 +223,9 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
|
|||||||
|
|
||||||
Style * createStyle (char const * fontName, Colour fontColour)
|
Style * createStyle (char const * fontName, Colour fontColour)
|
||||||
{
|
{
|
||||||
|
if (strcmp(fontName, "") == 0)
|
||||||
|
return createStyle(MyGUI::FontManager::getInstance().getDefaultFont().c_str(), fontColour);
|
||||||
|
|
||||||
for (Styles::iterator i = mBook->mStyles.begin (); i != mBook->mStyles.end (); ++i)
|
for (Styles::iterator i = mBook->mStyles.begin (); i != mBook->mStyles.end (); ++i)
|
||||||
if (i->match (fontName, fontColour, fontColour, fontColour, 0))
|
if (i->match (fontName, fontColour, fontColour, fontColour, 0))
|
||||||
return &*i;
|
return &*i;
|
||||||
@ -405,7 +408,8 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
|
|||||||
while (!stream.eof () && !ucsLineBreak (stream.peek ()) && ucsBreakingSpace (stream.peek ()))
|
while (!stream.eof () && !ucsLineBreak (stream.peek ()) && ucsBreakingSpace (stream.peek ()))
|
||||||
{
|
{
|
||||||
MyGUI::GlyphInfo* gi = style->mFont->getGlyphInfo (stream.peek ());
|
MyGUI::GlyphInfo* gi = style->mFont->getGlyphInfo (stream.peek ());
|
||||||
space_width += gi->advance;
|
if (gi)
|
||||||
|
space_width += gi->advance + gi->bearingX;
|
||||||
stream.consume ();
|
stream.consume ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,7 +418,8 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
|
|||||||
while (!stream.eof () && !ucsLineBreak (stream.peek ()) && !ucsBreakingSpace (stream.peek ()))
|
while (!stream.eof () && !ucsLineBreak (stream.peek ()) && !ucsBreakingSpace (stream.peek ()))
|
||||||
{
|
{
|
||||||
MyGUI::GlyphInfo* gi = style->mFont->getGlyphInfo (stream.peek ());
|
MyGUI::GlyphInfo* gi = style->mFont->getGlyphInfo (stream.peek ());
|
||||||
word_width += gi->advance + gi->bearingX;
|
if (gi)
|
||||||
|
word_width += gi->advance + gi->bearingX;
|
||||||
word_height = line_height;
|
word_height = line_height;
|
||||||
++character_count;
|
++character_count;
|
||||||
stream.consume ();
|
stream.consume ();
|
||||||
@ -628,6 +633,9 @@ namespace
|
|||||||
{
|
{
|
||||||
MyGUI::GlyphInfo* gi = mFont->getGlyphInfo (ch);
|
MyGUI::GlyphInfo* gi = mFont->getGlyphInfo (ch);
|
||||||
|
|
||||||
|
if (!gi)
|
||||||
|
return;
|
||||||
|
|
||||||
MyGUI::FloatRect vr;
|
MyGUI::FloatRect vr;
|
||||||
|
|
||||||
vr.left = mCursor.left + gi->bearingX;
|
vr.left = mCursor.left + gi->bearingX;
|
||||||
@ -647,7 +655,8 @@ namespace
|
|||||||
{
|
{
|
||||||
MyGUI::GlyphInfo* gi = mFont->getGlyphInfo (ch);
|
MyGUI::GlyphInfo* gi = mFont->getGlyphInfo (ch);
|
||||||
|
|
||||||
mCursor.left += gi->bearingX + gi->advance;
|
if (gi)
|
||||||
|
mCursor.left += gi->bearingX + gi->advance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -130,26 +130,12 @@ namespace MWGui
|
|||||||
|
|
||||||
void BookWindow::onNextPageButtonClicked (MyGUI::Widget* sender)
|
void BookWindow::onNextPageButtonClicked (MyGUI::Widget* sender)
|
||||||
{
|
{
|
||||||
if ((mCurrentPage+1)*2 < mPages.size())
|
nextPage();
|
||||||
{
|
|
||||||
MWBase::Environment::get().getSoundManager()->playSound ("book page2", 1.0, 1.0);
|
|
||||||
|
|
||||||
++mCurrentPage;
|
|
||||||
|
|
||||||
updatePages();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BookWindow::onPrevPageButtonClicked (MyGUI::Widget* sender)
|
void BookWindow::onPrevPageButtonClicked (MyGUI::Widget* sender)
|
||||||
{
|
{
|
||||||
if (mCurrentPage > 0)
|
prevPage();
|
||||||
{
|
|
||||||
MWBase::Environment::get().getSoundManager()->playSound ("book page", 1.0, 1.0);
|
|
||||||
|
|
||||||
--mCurrentPage;
|
|
||||||
|
|
||||||
updatePages();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BookWindow::updatePages()
|
void BookWindow::updatePages()
|
||||||
@ -194,5 +180,28 @@ namespace MWGui
|
|||||||
if (button->getAlign().isRight())
|
if (button->getAlign().isRight())
|
||||||
button->setPosition(button->getPosition() + MyGUI::IntPoint(diff.width,0));
|
button->setPosition(button->getPosition() + MyGUI::IntPoint(diff.width,0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BookWindow::nextPage()
|
||||||
|
{
|
||||||
|
if ((mCurrentPage+1)*2 < mPages.size())
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getSoundManager()->playSound ("book page2", 1.0, 1.0);
|
||||||
|
|
||||||
|
++mCurrentPage;
|
||||||
|
|
||||||
|
updatePages();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void BookWindow::prevPage()
|
||||||
|
{
|
||||||
|
if (mCurrentPage > 0)
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getSoundManager()->playSound ("book page", 1.0, 1.0);
|
||||||
|
|
||||||
|
--mCurrentPage;
|
||||||
|
|
||||||
|
updatePages();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,8 @@ namespace MWGui
|
|||||||
|
|
||||||
void open(MWWorld::Ptr book);
|
void open(MWWorld::Ptr book);
|
||||||
void setTakeButtonShow(bool show);
|
void setTakeButtonShow(bool show);
|
||||||
|
void nextPage();
|
||||||
|
void prevPage();
|
||||||
void setInventoryAllowed(bool allowed);
|
void setInventoryAllowed(bool allowed);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -238,6 +238,12 @@ namespace MWGui
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CharacterCreation::doRenderUpdate()
|
||||||
|
{
|
||||||
|
if (mRaceDialog)
|
||||||
|
mRaceDialog->doRenderUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
void CharacterCreation::setPlayerHealth (const MWMechanics::DynamicStat<float>& value)
|
void CharacterCreation::setPlayerHealth (const MWMechanics::DynamicStat<float>& value)
|
||||||
{
|
{
|
||||||
mPlayerHealth = value;
|
mPlayerHealth = value;
|
||||||
|
@ -41,6 +41,7 @@ namespace MWGui
|
|||||||
void setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value);
|
void setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value);
|
||||||
void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value);
|
void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value);
|
||||||
void configureSkills (const SkillList& major, const SkillList& minor);
|
void configureSkills (const SkillList& major, const SkillList& minor);
|
||||||
|
void doRenderUpdate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//Dialogs
|
//Dialogs
|
||||||
|
@ -407,7 +407,7 @@ namespace MWGui
|
|||||||
getWidget(mEditName, "EditName");
|
getWidget(mEditName, "EditName");
|
||||||
|
|
||||||
// Make sure the edit box has focus
|
// Make sure the edit box has focus
|
||||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(mEditName);
|
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mEditName);
|
||||||
|
|
||||||
MyGUI::Button* descriptionButton;
|
MyGUI::Button* descriptionButton;
|
||||||
getWidget(descriptionButton, "DescriptionButton");
|
getWidget(descriptionButton, "DescriptionButton");
|
||||||
@ -866,7 +866,7 @@ namespace MWGui
|
|||||||
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sInputMenu1", ""));
|
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sInputMenu1", ""));
|
||||||
|
|
||||||
// Make sure the edit box has focus
|
// Make sure the edit box has focus
|
||||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit);
|
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTextEdit);
|
||||||
}
|
}
|
||||||
|
|
||||||
DescriptionDialog::~DescriptionDialog()
|
DescriptionDialog::~DescriptionDialog()
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "../mwscript/extensions.hpp"
|
#include "../mwscript/extensions.hpp"
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
@ -131,16 +132,12 @@ namespace MWGui
|
|||||||
|
|
||||||
// Give keyboard focus to the combo box whenever the console is
|
// Give keyboard focus to the combo box whenever the console is
|
||||||
// turned on
|
// turned on
|
||||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(command);
|
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::disable()
|
void Console::disable()
|
||||||
{
|
{
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
setSelectedObject(MWWorld::Ptr());
|
|
||||||
// Remove keyboard focus from the console input whenever the
|
|
||||||
// console is turned off
|
|
||||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::setFont(const std::string &fntName)
|
void Console::setFont(const std::string &fntName)
|
||||||
@ -415,7 +412,7 @@ namespace MWGui
|
|||||||
setTitle("#{sConsoleTitle}");
|
setTitle("#{sConsoleTitle}");
|
||||||
mPtr = MWWorld::Ptr();
|
mPtr = MWWorld::Ptr();
|
||||||
}
|
}
|
||||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(command);
|
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::onReferenceUnavailable()
|
void Console::onReferenceUnavailable()
|
||||||
|
@ -3,11 +3,39 @@
|
|||||||
#include "../mwworld/containerstore.hpp"
|
#include "../mwworld/containerstore.hpp"
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
|
#include "../mwbase/world.hpp"
|
||||||
|
#include "../mwbase/environment.hpp"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
bool stacks (const MWWorld::Ptr& left, const MWWorld::Ptr& right)
|
||||||
|
{
|
||||||
|
if (left == right)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure
|
||||||
|
if (left.getContainerStore() && right.getContainerStore())
|
||||||
|
return left.getContainerStore()->stacks(left, right)
|
||||||
|
&& right.getContainerStore()->stacks(left, right);
|
||||||
|
|
||||||
|
if (left.getContainerStore())
|
||||||
|
return left.getContainerStore()->stacks(left, right);
|
||||||
|
if (right.getContainerStore())
|
||||||
|
return right.getContainerStore()->stacks(left, right);
|
||||||
|
|
||||||
|
MWWorld::ContainerStore store;
|
||||||
|
return store.stacks(left, right);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
|
|
||||||
ContainerItemModel::ContainerItemModel(const std::vector<MWWorld::Ptr>& itemSources)
|
ContainerItemModel::ContainerItemModel(const std::vector<MWWorld::Ptr>& itemSources, const std::vector<MWWorld::Ptr>& worldItems)
|
||||||
: mItemSources(itemSources)
|
: mItemSources(itemSources)
|
||||||
|
, mWorldItems(worldItems)
|
||||||
{
|
{
|
||||||
assert (mItemSources.size());
|
assert (mItemSources.size());
|
||||||
}
|
}
|
||||||
@ -65,8 +93,7 @@ void ContainerItemModel::removeItem (const ItemStack& item, size_t count)
|
|||||||
|
|
||||||
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
||||||
{
|
{
|
||||||
// If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure
|
if (stacks(*it, item.mBase))
|
||||||
if (*it == item.mBase || (store.stacks(*it, item.mBase) && item.mBase.getContainerStore()->stacks(*it, item.mBase)))
|
|
||||||
{
|
{
|
||||||
int refCount = it->getRefData().getCount();
|
int refCount = it->getRefData().getCount();
|
||||||
it->getRefData().setCount(std::max(0, refCount - toRemove));
|
it->getRefData().setCount(std::max(0, refCount - toRemove));
|
||||||
@ -76,6 +103,21 @@ void ContainerItemModel::removeItem (const ItemStack& item, size_t count)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (std::vector<MWWorld::Ptr>::iterator source = mWorldItems.begin(); source != mWorldItems.end(); ++source)
|
||||||
|
{
|
||||||
|
if (stacks(*source, item.mBase))
|
||||||
|
{
|
||||||
|
int refCount = source->getRefData().getCount();
|
||||||
|
if (refCount - toRemove <= 0)
|
||||||
|
MWBase::Environment::get().getWorld()->deleteObject(*source);
|
||||||
|
else
|
||||||
|
source->getRefData().setCount(std::max(0, refCount - toRemove));
|
||||||
|
toRemove -= refCount;
|
||||||
|
if (toRemove <= 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
throw std::runtime_error("Not enough items to remove could be found");
|
throw std::runtime_error("Not enough items to remove could be found");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,8 +133,7 @@ void ContainerItemModel::update()
|
|||||||
std::vector<ItemStack>::iterator itemStack = mItems.begin();
|
std::vector<ItemStack>::iterator itemStack = mItems.begin();
|
||||||
for (; itemStack != mItems.end(); ++itemStack)
|
for (; itemStack != mItems.end(); ++itemStack)
|
||||||
{
|
{
|
||||||
// If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure
|
if (stacks(*it, itemStack->mBase))
|
||||||
if (store.stacks(itemStack->mBase, *it) && it->getContainerStore()->stacks(itemStack->mBase, *it))
|
|
||||||
{
|
{
|
||||||
// we already have an item stack of this kind, add to it
|
// we already have an item stack of this kind, add to it
|
||||||
itemStack->mCount += it->getRefData().getCount();
|
itemStack->mCount += it->getRefData().getCount();
|
||||||
@ -108,6 +149,26 @@ void ContainerItemModel::update()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (std::vector<MWWorld::Ptr>::iterator source = mWorldItems.begin(); source != mWorldItems.end(); ++source)
|
||||||
|
{
|
||||||
|
std::vector<ItemStack>::iterator itemStack = mItems.begin();
|
||||||
|
for (; itemStack != mItems.end(); ++itemStack)
|
||||||
|
{
|
||||||
|
if (stacks(*source, itemStack->mBase))
|
||||||
|
{
|
||||||
|
// we already have an item stack of this kind, add to it
|
||||||
|
itemStack->mCount += source->getRefData().getCount();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemStack == mItems.end())
|
||||||
|
{
|
||||||
|
// no stack yet, create one
|
||||||
|
ItemStack newItem (*source, this, source->getRefData().getCount());
|
||||||
|
mItems.push_back(newItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ namespace MWGui
|
|||||||
class ContainerItemModel : public ItemModel
|
class ContainerItemModel : public ItemModel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ContainerItemModel (const std::vector<MWWorld::Ptr>& itemSources);
|
ContainerItemModel (const std::vector<MWWorld::Ptr>& itemSources, const std::vector<MWWorld::Ptr>& worldItems);
|
||||||
///< @note The order of elements \a itemSources matters here. The first element has the highest priority for removal,
|
///< @note The order of elements \a itemSources matters here. The first element has the highest priority for removal,
|
||||||
/// while the last element will be used to add new items to.
|
/// while the last element will be used to add new items to.
|
||||||
|
|
||||||
@ -28,6 +28,7 @@ namespace MWGui
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<MWWorld::Ptr> mItemSources;
|
std::vector<MWWorld::Ptr> mItemSources;
|
||||||
|
std::vector<MWWorld::Ptr> mWorldItems;
|
||||||
|
|
||||||
std::vector<ItemStack> mItems;
|
std::vector<ItemStack> mItems;
|
||||||
};
|
};
|
||||||
|
54
apps/openmw/mwgui/controllers.cpp
Normal file
54
apps/openmw/mwgui/controllers.cpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#include "controllers.hpp"
|
||||||
|
|
||||||
|
namespace MWGui
|
||||||
|
{
|
||||||
|
namespace Controllers
|
||||||
|
{
|
||||||
|
|
||||||
|
ControllerRepeatClick::ControllerRepeatClick() :
|
||||||
|
mInit(0.5),
|
||||||
|
mStep(0.1),
|
||||||
|
mEnabled(true),
|
||||||
|
mTimeLeft(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ControllerRepeatClick::~ControllerRepeatClick()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ControllerRepeatClick::addTime(MyGUI::Widget* _widget, float _time)
|
||||||
|
{
|
||||||
|
if(mTimeLeft == 0)
|
||||||
|
mTimeLeft = mInit;
|
||||||
|
|
||||||
|
mTimeLeft -= _time;
|
||||||
|
while (mTimeLeft <= 0)
|
||||||
|
{
|
||||||
|
mTimeLeft += mStep;
|
||||||
|
eventRepeatClick(_widget, this);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ControllerRepeatClick::setRepeat(float init, float step)
|
||||||
|
{
|
||||||
|
mInit = init;
|
||||||
|
mStep = step;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ControllerRepeatClick::setEnabled(bool enable)
|
||||||
|
{
|
||||||
|
mEnabled = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ControllerRepeatClick::setProperty(const std::string& _key, const std::string& _value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ControllerRepeatClick::prepareItem(MyGUI::Widget* _widget)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
46
apps/openmw/mwgui/controllers.hpp
Normal file
46
apps/openmw/mwgui/controllers.hpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#ifndef MWGUI_CONTROLLERS_H
|
||||||
|
#define MWGUI_CONTROLLERS_H
|
||||||
|
|
||||||
|
#include <MyGUI_Widget.h>
|
||||||
|
#include <MyGUI_ControllerItem.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace MWGui
|
||||||
|
{
|
||||||
|
namespace Controllers
|
||||||
|
{
|
||||||
|
class ControllerRepeatClick :
|
||||||
|
public MyGUI::ControllerItem
|
||||||
|
{
|
||||||
|
MYGUI_RTTI_DERIVED( ControllerRepeatClick )
|
||||||
|
|
||||||
|
public:
|
||||||
|
ControllerRepeatClick();
|
||||||
|
virtual ~ControllerRepeatClick();
|
||||||
|
|
||||||
|
void setRepeat(float init, float step);
|
||||||
|
void setEnabled(bool enable);
|
||||||
|
virtual void setProperty(const std::string& _key, const std::string& _value);
|
||||||
|
|
||||||
|
// Events
|
||||||
|
typedef MyGUI::delegates::CMultiDelegate2<MyGUI::Widget*, MyGUI::ControllerItem*> EventHandle_RepeatClickVoid;
|
||||||
|
|
||||||
|
/** Event : Repeat Click.\n
|
||||||
|
signature : void method(MyGUI::Widget* _sender, MyGUI::ControllerItem *_controller)\n
|
||||||
|
*/
|
||||||
|
EventHandle_RepeatClickVoid eventRepeatClick;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool addTime(MyGUI::Widget* _widget, float _time);
|
||||||
|
void prepareItem(MyGUI::Widget* _widget);
|
||||||
|
|
||||||
|
private:
|
||||||
|
float mInit;
|
||||||
|
float mStep;
|
||||||
|
bool mEnabled;
|
||||||
|
float mTimeLeft;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
|
#include "../mwbase/environment.hpp"
|
||||||
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
CountDialog::CountDialog() :
|
CountDialog::CountDialog() :
|
||||||
@ -40,7 +43,7 @@ namespace MWGui
|
|||||||
mMainWidget->getHeight());
|
mMainWidget->getHeight());
|
||||||
|
|
||||||
// by default, the text edit field has the focus of the keyboard
|
// by default, the text edit field has the focus of the keyboard
|
||||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(mItemEdit);
|
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mItemEdit);
|
||||||
|
|
||||||
mSlider->setScrollPosition(maxCount-1);
|
mSlider->setScrollPosition(maxCount-1);
|
||||||
mItemEdit->setCaption(boost::lexical_cast<std::string>(maxCount));
|
mItemEdit->setCaption(boost::lexical_cast<std::string>(maxCount));
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
#include "../mwbase/mechanicsmanager.hpp"
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
#include "../mwbase/soundmanager.hpp"
|
||||||
|
|
||||||
#include "../mwmechanics/npcstats.hpp"
|
#include "../mwmechanics/npcstats.hpp"
|
||||||
|
|
||||||
@ -115,7 +116,7 @@ namespace MWGui
|
|||||||
|
|
||||||
void Response::write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, std::map<std::string, Link*>& topicLinks) const
|
void Response::write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, std::map<std::string, Link*>& topicLinks) const
|
||||||
{
|
{
|
||||||
BookTypesetter::Style* title = typesetter->createStyle("EB Garamond", MyGUI::Colour(223/255.f, 201/255.f, 159/255.f));
|
BookTypesetter::Style* title = typesetter->createStyle("", MyGUI::Colour(223/255.f, 201/255.f, 159/255.f));
|
||||||
typesetter->sectionBreak(9);
|
typesetter->sectionBreak(9);
|
||||||
if (mTitle != "")
|
if (mTitle != "")
|
||||||
typesetter->write(title, to_utf8_span(mTitle.c_str()));
|
typesetter->write(title, to_utf8_span(mTitle.c_str()));
|
||||||
@ -159,7 +160,7 @@ namespace MWGui
|
|||||||
|
|
||||||
if (hyperLinks.size() && MWBase::Environment::get().getWindowManager()->getTranslationDataStorage().hasTranslation())
|
if (hyperLinks.size() && MWBase::Environment::get().getWindowManager()->getTranslationDataStorage().hasTranslation())
|
||||||
{
|
{
|
||||||
BookTypesetter::Style* style = typesetter->createStyle("EB Garamond", MyGUI::Colour(202/255.f, 165/255.f, 96/255.f));
|
BookTypesetter::Style* style = typesetter->createStyle("", MyGUI::Colour(202/255.f, 165/255.f, 96/255.f));
|
||||||
size_t formatted = 0; // points to the first character that is not laid out yet
|
size_t formatted = 0; // points to the first character that is not laid out yet
|
||||||
for (std::map<Range, intptr_t>::iterator it = hyperLinks.begin(); it != hyperLinks.end(); ++it)
|
for (std::map<Range, intptr_t>::iterator it = hyperLinks.begin(); it != hyperLinks.end(); ++it)
|
||||||
{
|
{
|
||||||
@ -197,7 +198,7 @@ namespace MWGui
|
|||||||
|
|
||||||
void Response::addTopicLink(BookTypesetter::Ptr typesetter, intptr_t topicId, size_t begin, size_t end) const
|
void Response::addTopicLink(BookTypesetter::Ptr typesetter, intptr_t topicId, size_t begin, size_t end) const
|
||||||
{
|
{
|
||||||
BookTypesetter::Style* style = typesetter->createStyle("EB Garamond", MyGUI::Colour(202/255.f, 165/255.f, 96/255.f));
|
BookTypesetter::Style* style = typesetter->createStyle("", MyGUI::Colour(202/255.f, 165/255.f, 96/255.f));
|
||||||
|
|
||||||
const MyGUI::Colour linkHot (143/255.f, 155/255.f, 218/255.f);
|
const MyGUI::Colour linkHot (143/255.f, 155/255.f, 218/255.f);
|
||||||
const MyGUI::Colour linkNormal (112/255.f, 126/255.f, 207/255.f);
|
const MyGUI::Colour linkNormal (112/255.f, 126/255.f, 207/255.f);
|
||||||
@ -215,7 +216,7 @@ namespace MWGui
|
|||||||
|
|
||||||
void Message::write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, std::map<std::string, Link*>& topicLinks) const
|
void Message::write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, std::map<std::string, Link*>& topicLinks) const
|
||||||
{
|
{
|
||||||
BookTypesetter::Style* title = typesetter->createStyle("EB Garamond", MyGUI::Colour(223/255.f, 201/255.f, 159/255.f));
|
BookTypesetter::Style* title = typesetter->createStyle("", MyGUI::Colour(223/255.f, 201/255.f, 159/255.f));
|
||||||
typesetter->sectionBreak(9);
|
typesetter->sectionBreak(9);
|
||||||
typesetter->write(title, to_utf8_span(mText.c_str()));
|
typesetter->write(title, to_utf8_span(mText.c_str()));
|
||||||
}
|
}
|
||||||
@ -224,16 +225,22 @@ namespace MWGui
|
|||||||
|
|
||||||
void Choice::activated()
|
void Choice::activated()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.0, 1.0);
|
||||||
MWBase::Environment::get().getDialogueManager()->questionAnswered(mChoiceId);
|
MWBase::Environment::get().getDialogueManager()->questionAnswered(mChoiceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Topic::activated()
|
void Topic::activated()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f);
|
||||||
MWBase::Environment::get().getDialogueManager()->keywordSelected(Misc::StringUtils::lowerCase(mTopicId));
|
MWBase::Environment::get().getDialogueManager()->keywordSelected(Misc::StringUtils::lowerCase(mTopicId));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Goodbye::activated()
|
void Goodbye::activated()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f);
|
||||||
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
|
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,13 +472,14 @@ namespace MWGui
|
|||||||
(*it)->write(typesetter, &mKeywordSearch, mTopicLinks);
|
(*it)->write(typesetter, &mKeywordSearch, mTopicLinks);
|
||||||
|
|
||||||
|
|
||||||
BookTypesetter::Style* body = typesetter->createStyle("EB Garamond", MyGUI::Colour::White);
|
BookTypesetter::Style* body = typesetter->createStyle("", MyGUI::Colour::White);
|
||||||
|
|
||||||
|
typesetter->sectionBreak(9);
|
||||||
// choices
|
// choices
|
||||||
const MyGUI::Colour linkHot (223/255.f, 201/255.f, 159/255.f);
|
const MyGUI::Colour linkHot (223/255.f, 201/255.f, 159/255.f);
|
||||||
const MyGUI::Colour linkNormal (150/255.f, 50/255.f, 30/255.f);
|
const MyGUI::Colour linkNormal (150/255.f, 50/255.f, 30/255.f);
|
||||||
const MyGUI::Colour linkActive (243/255.f, 237/255.f, 221/255.f);
|
const MyGUI::Colour linkActive (243/255.f, 237/255.f, 221/255.f);
|
||||||
for (std::map<std::string, int>::iterator it = mChoices.begin(); it != mChoices.end(); ++it)
|
for (std::map<std::string, int>::reverse_iterator it = mChoices.rbegin(); it != mChoices.rend(); ++it)
|
||||||
{
|
{
|
||||||
Choice* link = new Choice(it->second);
|
Choice* link = new Choice(it->second);
|
||||||
mLinks.push_back(link);
|
mLinks.push_back(link);
|
||||||
|
@ -61,30 +61,32 @@ namespace MWGui
|
|||||||
void EnchantingDialog::updateLabels()
|
void EnchantingDialog::updateLabels()
|
||||||
{
|
{
|
||||||
std::stringstream enchantCost;
|
std::stringstream enchantCost;
|
||||||
enchantCost << std::setprecision(1) << std::fixed << mEnchanting.getEnchantCost();
|
enchantCost << std::setprecision(1) << std::fixed << mEnchanting.getEnchantPoints();
|
||||||
mEnchantmentPoints->setCaption(enchantCost.str() + " / " + boost::lexical_cast<std::string>(mEnchanting.getMaxEnchantValue()));
|
mEnchantmentPoints->setCaption(enchantCost.str() + " / " + boost::lexical_cast<std::string>(mEnchanting.getMaxEnchantValue()));
|
||||||
|
|
||||||
mCharge->setCaption(boost::lexical_cast<std::string>(mEnchanting.getGemCharge()));
|
mCharge->setCaption(boost::lexical_cast<std::string>(mEnchanting.getGemCharge()));
|
||||||
|
|
||||||
mCastCost->setCaption(boost::lexical_cast<std::string>(mEnchanting.getEnchantCost()));
|
std::stringstream castCost;
|
||||||
|
castCost << std::setprecision(1) << std::fixed << mEnchanting.getCastCost();
|
||||||
|
mCastCost->setCaption(boost::lexical_cast<std::string>(castCost.str()));
|
||||||
|
|
||||||
mPrice->setCaption(boost::lexical_cast<std::string>(mEnchanting.getEnchantPrice()));
|
mPrice->setCaption(boost::lexical_cast<std::string>(mEnchanting.getEnchantPrice()));
|
||||||
|
|
||||||
switch(mEnchanting.getEnchantType())
|
switch(mEnchanting.getCastStyle())
|
||||||
{
|
{
|
||||||
case 0:
|
case ESM::Enchantment::CastOnce:
|
||||||
mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastOnce","Cast Once"));
|
mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastOnce","Cast Once"));
|
||||||
mAddEffectDialog.constantEffect=false;
|
mAddEffectDialog.constantEffect=false;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case ESM::Enchantment::WhenStrikes:
|
||||||
mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastWhenStrikes", "When Strikes"));
|
mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastWhenStrikes", "When Strikes"));
|
||||||
mAddEffectDialog.constantEffect=false;
|
mAddEffectDialog.constantEffect=false;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case ESM::Enchantment::WhenUsed:
|
||||||
mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastWhenUsed", "When Used"));
|
mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastWhenUsed", "When Used"));
|
||||||
mAddEffectDialog.constantEffect=false;
|
mAddEffectDialog.constantEffect=false;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case ESM::Enchantment::ConstantEffect:
|
||||||
mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastConstant", "Cast Constant"));
|
mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastConstant", "Cast Constant"));
|
||||||
mAddEffectDialog.constantEffect=true;
|
mAddEffectDialog.constantEffect=true;
|
||||||
break;
|
break;
|
||||||
@ -169,7 +171,7 @@ namespace MWGui
|
|||||||
image->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onRemoveItem);
|
image->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onRemoveItem);
|
||||||
|
|
||||||
mEnchanting.setOldItem(item);
|
mEnchanting.setOldItem(item);
|
||||||
mEnchanting.nextEnchantType();
|
mEnchanting.nextCastStyle();
|
||||||
updateLabels();
|
updateLabels();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,7 +250,7 @@ namespace MWGui
|
|||||||
|
|
||||||
void EnchantingDialog::onTypeButtonClicked(MyGUI::Widget* sender)
|
void EnchantingDialog::onTypeButtonClicked(MyGUI::Widget* sender)
|
||||||
{
|
{
|
||||||
mEnchanting.nextEnchantType();
|
mEnchanting.nextCastStyle();
|
||||||
updateLabels();
|
updateLabels();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,7 +280,7 @@ namespace MWGui
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mEnchanting.getEnchantCost() > mEnchanting.getMaxEnchantValue())
|
if (mEnchanting.getEnchantPoints() > mEnchanting.getMaxEnchantValue())
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage29}");
|
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage29}");
|
||||||
return;
|
return;
|
||||||
|
238
apps/openmw/mwgui/fontloader.cpp
Normal file
238
apps/openmw/mwgui/fontloader.cpp
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
#include "fontloader.hpp"
|
||||||
|
|
||||||
|
#include <OgreResourceGroupManager.h>
|
||||||
|
#include <OgreTextureManager.h>
|
||||||
|
|
||||||
|
#include <MyGUI_ResourceManager.h>
|
||||||
|
#include <MyGUI_FontManager.h>
|
||||||
|
#include <MyGUI_ResourceManualFont.h>
|
||||||
|
#include <MyGUI_XmlDocument.h>
|
||||||
|
#include <MyGUI_FactoryManager.h>
|
||||||
|
|
||||||
|
#include <components/misc/stringops.hpp>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
unsigned long utf8ToUnicode(const std::string& utf8)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
unsigned long unicode;
|
||||||
|
size_t todo;
|
||||||
|
unsigned char ch = utf8[i++];
|
||||||
|
if (ch <= 0x7F)
|
||||||
|
{
|
||||||
|
unicode = ch;
|
||||||
|
todo = 0;
|
||||||
|
}
|
||||||
|
else if (ch <= 0xBF)
|
||||||
|
{
|
||||||
|
throw std::logic_error("not a UTF-8 string");
|
||||||
|
}
|
||||||
|
else if (ch <= 0xDF)
|
||||||
|
{
|
||||||
|
unicode = ch&0x1F;
|
||||||
|
todo = 1;
|
||||||
|
}
|
||||||
|
else if (ch <= 0xEF)
|
||||||
|
{
|
||||||
|
unicode = ch&0x0F;
|
||||||
|
todo = 2;
|
||||||
|
}
|
||||||
|
else if (ch <= 0xF7)
|
||||||
|
{
|
||||||
|
unicode = ch&0x07;
|
||||||
|
todo = 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::logic_error("not a UTF-8 string");
|
||||||
|
}
|
||||||
|
for (size_t j = 0; j < todo; ++j)
|
||||||
|
{
|
||||||
|
unsigned char ch = utf8[i++];
|
||||||
|
if (ch < 0x80 || ch > 0xBF)
|
||||||
|
throw std::logic_error("not a UTF-8 string");
|
||||||
|
unicode <<= 6;
|
||||||
|
unicode += ch & 0x3F;
|
||||||
|
}
|
||||||
|
if (unicode >= 0xD800 && unicode <= 0xDFFF)
|
||||||
|
throw std::logic_error("not a UTF-8 string");
|
||||||
|
if (unicode > 0x10FFFF)
|
||||||
|
throw std::logic_error("not a UTF-8 string");
|
||||||
|
|
||||||
|
return unicode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace MWGui
|
||||||
|
{
|
||||||
|
|
||||||
|
FontLoader::FontLoader(ToUTF8::FromType encoding)
|
||||||
|
{
|
||||||
|
if (encoding == ToUTF8::WINDOWS_1252)
|
||||||
|
mEncoding = ToUTF8::CP437;
|
||||||
|
else
|
||||||
|
mEncoding = encoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FontLoader::loadAllFonts()
|
||||||
|
{
|
||||||
|
Ogre::StringVector groups = Ogre::ResourceGroupManager::getSingleton().getResourceGroups ();
|
||||||
|
for (Ogre::StringVector::iterator it = groups.begin(); it != groups.end(); ++it)
|
||||||
|
{
|
||||||
|
Ogre::StringVectorPtr resourcesInThisGroup = Ogre::ResourceGroupManager::getSingleton ().findResourceNames (*it, "*.fnt");
|
||||||
|
for (Ogre::StringVector::iterator resource = resourcesInThisGroup->begin(); resource != resourcesInThisGroup->end(); ++resource)
|
||||||
|
{
|
||||||
|
loadFont(*resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
} Point;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
float u1; // appears unused, always 0
|
||||||
|
Point top_left;
|
||||||
|
Point top_right;
|
||||||
|
Point bottom_left;
|
||||||
|
Point bottom_right;
|
||||||
|
float width;
|
||||||
|
float height;
|
||||||
|
float u2; // appears unused, always 0
|
||||||
|
float kerning;
|
||||||
|
float ascent;
|
||||||
|
} GlyphInfo;
|
||||||
|
|
||||||
|
void FontLoader::loadFont(const std::string &fileName)
|
||||||
|
{
|
||||||
|
Ogre::DataStreamPtr file = Ogre::ResourceGroupManager::getSingleton().openResource(fileName);
|
||||||
|
|
||||||
|
float fontSize;
|
||||||
|
int one;
|
||||||
|
file->read(&fontSize, sizeof(fontSize));
|
||||||
|
|
||||||
|
file->read(&one, sizeof(int));
|
||||||
|
assert(one == 1);
|
||||||
|
file->read(&one, sizeof(int));
|
||||||
|
assert(one == 1);
|
||||||
|
|
||||||
|
char name_[284];
|
||||||
|
file->read(name_, sizeof(name_));
|
||||||
|
std::string name(name_);
|
||||||
|
|
||||||
|
GlyphInfo data[256];
|
||||||
|
file->read(data, sizeof(data));
|
||||||
|
file->close();
|
||||||
|
|
||||||
|
// Create the font texture
|
||||||
|
std::string bitmapFilename = "Fonts/" + std::string(name) + ".tex";
|
||||||
|
Ogre::DataStreamPtr bitmapFile = Ogre::ResourceGroupManager::getSingleton().openResource(bitmapFilename);
|
||||||
|
|
||||||
|
int width, height;
|
||||||
|
bitmapFile->read(&width, sizeof(int));
|
||||||
|
bitmapFile->read(&height, sizeof(int));
|
||||||
|
|
||||||
|
std::vector<Ogre::uchar> textureData;
|
||||||
|
textureData.resize(width*height*4);
|
||||||
|
bitmapFile->read(&textureData[0], width*height*4);
|
||||||
|
bitmapFile->close();
|
||||||
|
|
||||||
|
std::string textureName = name;
|
||||||
|
Ogre::Image image;
|
||||||
|
image.loadDynamicImage(&textureData[0], width, height, Ogre::PF_BYTE_RGBA);
|
||||||
|
Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().createManual(textureName,
|
||||||
|
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||||
|
Ogre::TEX_TYPE_2D,
|
||||||
|
width, height, 0, Ogre::PF_BYTE_RGBA);
|
||||||
|
texture->loadImage(image);
|
||||||
|
|
||||||
|
// Register the font with MyGUI
|
||||||
|
MyGUI::ResourceManualFont* font = static_cast<MyGUI::ResourceManualFont*>(
|
||||||
|
MyGUI::FactoryManager::getInstance().createObject("Resource", "ResourceManualFont"));
|
||||||
|
// We need to emulate loading from XML because the data members are private as of mygui 3.2.0
|
||||||
|
MyGUI::xml::Document xmlDocument;
|
||||||
|
MyGUI::xml::ElementPtr root = xmlDocument.createRoot("ResourceManualFont");
|
||||||
|
|
||||||
|
if (name.size() >= 5 && Misc::StringUtils::ciEqual(name.substr(0, 5), "magic"))
|
||||||
|
root->addAttribute("name", "Magic Cards");
|
||||||
|
else if (name.size() >= 7 && Misc::StringUtils::ciEqual(name.substr(0, 7), "century"))
|
||||||
|
root->addAttribute("name", "Century Gothic");
|
||||||
|
else if (name.size() >= 7 && Misc::StringUtils::ciEqual(name.substr(0, 7), "daedric"))
|
||||||
|
root->addAttribute("name", "Daedric");
|
||||||
|
else
|
||||||
|
return; // no point in loading it, since there is no way of using additional fonts
|
||||||
|
|
||||||
|
MyGUI::xml::ElementPtr defaultHeight = root->createChild("Property");
|
||||||
|
defaultHeight->addAttribute("key", "DefaultHeight");
|
||||||
|
defaultHeight->addAttribute("value", fontSize);
|
||||||
|
MyGUI::xml::ElementPtr source = root->createChild("Property");
|
||||||
|
source->addAttribute("key", "Source");
|
||||||
|
source->addAttribute("value", std::string(textureName));
|
||||||
|
MyGUI::xml::ElementPtr codes = root->createChild("Codes");
|
||||||
|
|
||||||
|
for(int i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
int x1 = data[i].top_left.x*width;
|
||||||
|
int y1 = data[i].top_left.y*height;
|
||||||
|
int w = data[i].top_right.x*width - x1;
|
||||||
|
int h = data[i].bottom_left.y*height - y1;
|
||||||
|
|
||||||
|
ToUTF8::Utf8Encoder encoder(mEncoding);
|
||||||
|
unsigned long unicodeVal = utf8ToUnicode(encoder.getUtf8(std::string(1, (unsigned char)(i))));
|
||||||
|
|
||||||
|
MyGUI::xml::ElementPtr code = codes->createChild("Code");
|
||||||
|
code->addAttribute("index", unicodeVal);
|
||||||
|
code->addAttribute("coord", MyGUI::utility::toString(x1) + " "
|
||||||
|
+ MyGUI::utility::toString(y1) + " "
|
||||||
|
+ MyGUI::utility::toString(w) + " "
|
||||||
|
+ MyGUI::utility::toString(h));
|
||||||
|
code->addAttribute("advance", data[i].width);
|
||||||
|
code->addAttribute("bearing", MyGUI::utility::toString(data[i].kerning) + " "
|
||||||
|
+ MyGUI::utility::toString((fontSize-data[i].ascent)));
|
||||||
|
|
||||||
|
// ASCII vertical bar, use this as text input cursor
|
||||||
|
if (i == 124)
|
||||||
|
{
|
||||||
|
MyGUI::xml::ElementPtr cursorCode = codes->createChild("Code");
|
||||||
|
cursorCode->addAttribute("index", MyGUI::FontCodeType::Cursor);
|
||||||
|
cursorCode->addAttribute("coord", MyGUI::utility::toString(x1) + " "
|
||||||
|
+ MyGUI::utility::toString(y1) + " "
|
||||||
|
+ MyGUI::utility::toString(w) + " "
|
||||||
|
+ MyGUI::utility::toString(h));
|
||||||
|
cursorCode->addAttribute("advance", data[i].width);
|
||||||
|
cursorCode->addAttribute("bearing", MyGUI::utility::toString(data[i].kerning) + " "
|
||||||
|
+ MyGUI::utility::toString((fontSize-data[i].ascent)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// These are required as well, but the fonts don't provide them
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
{
|
||||||
|
MyGUI::FontCodeType::Enum type;
|
||||||
|
if(i == 0)
|
||||||
|
type = MyGUI::FontCodeType::Selected;
|
||||||
|
else if (i == 1)
|
||||||
|
type = MyGUI::FontCodeType::SelectedBack;
|
||||||
|
else if (i == 2)
|
||||||
|
type = MyGUI::FontCodeType::NotDefined;
|
||||||
|
|
||||||
|
MyGUI::xml::ElementPtr cursorCode = codes->createChild("Code");
|
||||||
|
cursorCode->addAttribute("index", type);
|
||||||
|
cursorCode->addAttribute("coord", "0 0 0 0");
|
||||||
|
cursorCode->addAttribute("advance", "0");
|
||||||
|
cursorCode->addAttribute("bearing", "0 0");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
font->deserialization(root, MyGUI::Version(3,2,0));
|
||||||
|
|
||||||
|
MyGUI::ResourceManager::getInstance().addResource(font);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
25
apps/openmw/mwgui/fontloader.hpp
Normal file
25
apps/openmw/mwgui/fontloader.hpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef MWGUI_FONTLOADER_H
|
||||||
|
#define MWGUI_FONTLOADER_H
|
||||||
|
|
||||||
|
#include <components/to_utf8/to_utf8.hpp>
|
||||||
|
|
||||||
|
namespace MWGui
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/// @brief loads Morrowind's .fnt/.tex fonts for use with MyGUI and Ogre
|
||||||
|
class FontLoader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FontLoader (ToUTF8::FromType encoding);
|
||||||
|
void loadAllFonts ();
|
||||||
|
|
||||||
|
private:
|
||||||
|
ToUTF8::FromType mEncoding;
|
||||||
|
|
||||||
|
void loadFont (const std::string& fileName);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -202,14 +202,14 @@ namespace MWGui
|
|||||||
|
|
||||||
float BookTextParser::widthForCharGlyph(unsigned unicodeChar) const
|
float BookTextParser::widthForCharGlyph(unsigned unicodeChar) const
|
||||||
{
|
{
|
||||||
std::string fontName(mTextStyle.mFont == "Default" ? "EB Garamond" : mTextStyle.mFont);
|
std::string fontName(mTextStyle.mFont == "Default" ? MyGUI::FontManager::getInstance().getDefaultFont() : mTextStyle.mFont);
|
||||||
return MyGUI::FontManager::getInstance().getByName(fontName)
|
return MyGUI::FontManager::getInstance().getByName(fontName)
|
||||||
->getGlyphInfo(unicodeChar)->width;
|
->getGlyphInfo(unicodeChar)->width;
|
||||||
}
|
}
|
||||||
|
|
||||||
float BookTextParser::currentFontHeight() const
|
float BookTextParser::currentFontHeight() const
|
||||||
{
|
{
|
||||||
std::string fontName(mTextStyle.mFont == "Default" ? "EB Garamond" : mTextStyle.mFont);
|
std::string fontName(mTextStyle.mFont == "Default" ? MyGUI::FontManager::getInstance().getDefaultFont() : mTextStyle.mFont);
|
||||||
return MyGUI::FontManager::getInstance().getByName(fontName)->getDefaultHeight();
|
return MyGUI::FontManager::getInstance().getByName(fontName)->getDefaultHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,10 +251,8 @@ namespace MWGui
|
|||||||
MyGUI::Gui::getInstance().destroyWidget(mParent->getChildAt(0));
|
MyGUI::Gui::getInstance().destroyWidget(mParent->getChildAt(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::algorithm::replace_all(text, "\n", "\n");
|
boost::algorithm::replace_all(text, "<BR>", "\n");
|
||||||
boost::algorithm::replace_all(text, "\r", "\r");
|
boost::algorithm::replace_all(text, "<P>", "\n\n");
|
||||||
boost::algorithm::replace_all(text, "<BR>", "\n\n");
|
|
||||||
boost::algorithm::replace_all(text, "<P>", "\n\n"); // tweaking by adding another newline to see if that spaces out better
|
|
||||||
boost::algorithm::trim_left(text);
|
boost::algorithm::trim_left(text);
|
||||||
|
|
||||||
// remove trailing "
|
// remove trailing "
|
||||||
|
@ -13,8 +13,6 @@ namespace MWGui
|
|||||||
, mType(Type_Normal)
|
, mType(Type_Normal)
|
||||||
, mBase(base)
|
, mBase(base)
|
||||||
{
|
{
|
||||||
assert(base.getContainerStore());
|
|
||||||
|
|
||||||
if (MWWorld::Class::get(base).getEnchantment(base) != "")
|
if (MWWorld::Class::get(base).getEnchantment(base) != "")
|
||||||
mFlags |= Flag_Enchanted;
|
mFlags |= Flag_Enchanted;
|
||||||
}
|
}
|
||||||
@ -31,18 +29,42 @@ namespace MWGui
|
|||||||
{
|
{
|
||||||
if(mBase == other.mBase)
|
if(mBase == other.mBase)
|
||||||
return true;
|
return true;
|
||||||
return mBase.getContainerStore()->stacks(mBase, other.mBase)
|
|
||||||
&& other.mBase.getContainerStore()->stacks(mBase, other.mBase);
|
// If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure
|
||||||
|
if (mBase.getContainerStore() && other.mBase.getContainerStore())
|
||||||
|
return mBase.getContainerStore()->stacks(mBase, other.mBase)
|
||||||
|
&& other.mBase.getContainerStore()->stacks(mBase, other.mBase);
|
||||||
|
|
||||||
|
if (mBase.getContainerStore())
|
||||||
|
return mBase.getContainerStore()->stacks(mBase, other.mBase);
|
||||||
|
if (other.mBase.getContainerStore())
|
||||||
|
return other.mBase.getContainerStore()->stacks(mBase, other.mBase);
|
||||||
|
|
||||||
|
MWWorld::ContainerStore store;
|
||||||
|
return store.stacks(mBase, other.mBase);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator == (const ItemStack& left, const ItemStack& right)
|
bool operator == (const ItemStack& left, const ItemStack& right)
|
||||||
{
|
{
|
||||||
if (left.mType != right.mType)
|
if (left.mType != right.mType)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(left.mBase == right.mBase)
|
if(left.mBase == right.mBase)
|
||||||
return true;
|
return true;
|
||||||
return left.mBase.getContainerStore()->stacks(left.mBase, right.mBase)
|
|
||||||
&& right.mBase.getContainerStore()->stacks(left.mBase, right.mBase);
|
// If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure
|
||||||
|
if (left.mBase.getContainerStore() && right.mBase.getContainerStore())
|
||||||
|
return left.mBase.getContainerStore()->stacks(left.mBase, right.mBase)
|
||||||
|
&& right.mBase.getContainerStore()->stacks(left.mBase, right.mBase);
|
||||||
|
|
||||||
|
if (left.mBase.getContainerStore())
|
||||||
|
return left.mBase.getContainerStore()->stacks(left.mBase, right.mBase);
|
||||||
|
if (right.mBase.getContainerStore())
|
||||||
|
return right.mBase.getContainerStore()->stacks(left.mBase, right.mBase);
|
||||||
|
|
||||||
|
MWWorld::ContainerStore store;
|
||||||
|
return store.stacks(left.mBase, right.mBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemModel::ItemModel()
|
ItemModel::ItemModel()
|
||||||
|
@ -189,14 +189,14 @@ book JournalBooks::createEmptyJournalBook ()
|
|||||||
{
|
{
|
||||||
BookTypesetter::Ptr typesetter = createTypesetter ();
|
BookTypesetter::Ptr typesetter = createTypesetter ();
|
||||||
|
|
||||||
BookTypesetter::Style* header = typesetter->createStyle ("EB Garamond", MyGUI::Colour (0.60f, 0.00f, 0.00f));
|
BookTypesetter::Style* header = typesetter->createStyle ("", MyGUI::Colour (0.60f, 0.00f, 0.00f));
|
||||||
BookTypesetter::Style* body = typesetter->createStyle ("EB Garamond", MyGUI::Colour::Black);
|
BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black);
|
||||||
|
|
||||||
typesetter->write (header, to_utf8_span ("You have no journal entries!"));
|
typesetter->write (header, to_utf8_span ("You have no journal entries!"));
|
||||||
typesetter->lineBreak ();
|
typesetter->lineBreak ();
|
||||||
typesetter->write (body, to_utf8_span ("You should have gone though the starting quest and got an initial quest."));
|
typesetter->write (body, to_utf8_span ("You should have gone though the starting quest and got an initial quest."));
|
||||||
|
|
||||||
BookTypesetter::Style* big = typesetter->createStyle ("EB Garamond 24", MyGUI::Colour::Black);
|
BookTypesetter::Style* big = typesetter->createStyle ("", MyGUI::Colour::Black);
|
||||||
BookTypesetter::Style* test = typesetter->createStyle ("MonoFont", MyGUI::Colour::Blue);
|
BookTypesetter::Style* test = typesetter->createStyle ("MonoFont", MyGUI::Colour::Blue);
|
||||||
|
|
||||||
typesetter->sectionBreak (20);
|
typesetter->sectionBreak (20);
|
||||||
@ -231,8 +231,8 @@ book JournalBooks::createJournalBook ()
|
|||||||
{
|
{
|
||||||
BookTypesetter::Ptr typesetter = createTypesetter ();
|
BookTypesetter::Ptr typesetter = createTypesetter ();
|
||||||
|
|
||||||
BookTypesetter::Style* header = typesetter->createStyle ("EB Garamond", MyGUI::Colour (0.60f, 0.00f, 0.00f));
|
BookTypesetter::Style* header = typesetter->createStyle ("", MyGUI::Colour (0.60f, 0.00f, 0.00f));
|
||||||
BookTypesetter::Style* body = typesetter->createStyle ("EB Garamond", MyGUI::Colour::Black);
|
BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black);
|
||||||
|
|
||||||
mModel->visitJournalEntries (0, AddJournalEntry (typesetter, body, header, true));
|
mModel->visitJournalEntries (0, AddJournalEntry (typesetter, body, header, true));
|
||||||
|
|
||||||
@ -243,8 +243,8 @@ book JournalBooks::createTopicBook (uintptr_t topicId)
|
|||||||
{
|
{
|
||||||
BookTypesetter::Ptr typesetter = createTypesetter ();
|
BookTypesetter::Ptr typesetter = createTypesetter ();
|
||||||
|
|
||||||
BookTypesetter::Style* header = typesetter->createStyle ("EB Garamond", MyGUI::Colour (0.60f, 0.00f, 0.00f));
|
BookTypesetter::Style* header = typesetter->createStyle ("", MyGUI::Colour (0.60f, 0.00f, 0.00f));
|
||||||
BookTypesetter::Style* body = typesetter->createStyle ("EB Garamond", MyGUI::Colour::Black);
|
BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black);
|
||||||
|
|
||||||
mModel->visitTopicName (topicId, AddTopicName (typesetter, header));
|
mModel->visitTopicName (topicId, AddTopicName (typesetter, header));
|
||||||
|
|
||||||
@ -259,8 +259,8 @@ book JournalBooks::createQuestBook (uintptr_t questId)
|
|||||||
{
|
{
|
||||||
BookTypesetter::Ptr typesetter = createTypesetter ();
|
BookTypesetter::Ptr typesetter = createTypesetter ();
|
||||||
|
|
||||||
BookTypesetter::Style* header = typesetter->createStyle ("EB Garamond", MyGUI::Colour (0.60f, 0.00f, 0.00f));
|
BookTypesetter::Style* header = typesetter->createStyle ("", MyGUI::Colour (0.60f, 0.00f, 0.00f));
|
||||||
BookTypesetter::Style* body = typesetter->createStyle ("EB Garamond", MyGUI::Colour::Black);
|
BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black);
|
||||||
|
|
||||||
mModel->visitQuestName (questId, AddQuestName (typesetter, header));
|
mModel->visitQuestName (questId, AddQuestName (typesetter, header));
|
||||||
|
|
||||||
@ -275,7 +275,7 @@ book JournalBooks::createTopicIndexBook ()
|
|||||||
|
|
||||||
typesetter->setSectionAlignment (BookTypesetter::AlignCenter);
|
typesetter->setSectionAlignment (BookTypesetter::AlignCenter);
|
||||||
|
|
||||||
BookTypesetter::Style* body = typesetter->createStyle ("EB Garamond", MyGUI::Colour::Black);
|
BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black);
|
||||||
|
|
||||||
for (int i = 0; i < 26; ++i)
|
for (int i = 0; i < 26; ++i)
|
||||||
{
|
{
|
||||||
@ -300,7 +300,7 @@ book JournalBooks::createTopicIndexBook ()
|
|||||||
book JournalBooks::createTopicIndexBook (char character)
|
book JournalBooks::createTopicIndexBook (char character)
|
||||||
{
|
{
|
||||||
BookTypesetter::Ptr typesetter = BookTypesetter::create (0x7FFFFFFF, 0x7FFFFFFF);
|
BookTypesetter::Ptr typesetter = BookTypesetter::create (0x7FFFFFFF, 0x7FFFFFFF);
|
||||||
BookTypesetter::Style* style = typesetter->createStyle ("EB Garamond", MyGUI::Colour::Black);
|
BookTypesetter::Style* style = typesetter->createStyle ("", MyGUI::Colour::Black);
|
||||||
|
|
||||||
mModel->visitTopicNamesStartingWith (character, AddTopicLink (typesetter, style));
|
mModel->visitTopicNamesStartingWith (character, AddTopicLink (typesetter, style));
|
||||||
|
|
||||||
@ -310,7 +310,7 @@ book JournalBooks::createTopicIndexBook (char character)
|
|||||||
book JournalBooks::createQuestIndexBook (bool activeOnly)
|
book JournalBooks::createQuestIndexBook (bool activeOnly)
|
||||||
{
|
{
|
||||||
BookTypesetter::Ptr typesetter = BookTypesetter::create (0x7FFFFFFF, 0x7FFFFFFF);
|
BookTypesetter::Ptr typesetter = BookTypesetter::create (0x7FFFFFFF, 0x7FFFFFFF);
|
||||||
BookTypesetter::Style* base = typesetter->createStyle ("EB Garamond", MyGUI::Colour::Black);
|
BookTypesetter::Style* base = typesetter->createStyle ("", MyGUI::Colour::Black);
|
||||||
|
|
||||||
mModel->visitQuestNames (activeOnly, AddQuestLink (typesetter, base));
|
mModel->visitQuestNames (activeOnly, AddQuestLink (typesetter, base));
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ namespace
|
|||||||
if (!MWBase::Environment::get().getWindowManager ()->getJournalAllowed ())
|
if (!MWBase::Environment::get().getWindowManager ()->getJournalAllowed ())
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWindowManager()->popGuiMode ();
|
MWBase::Environment::get().getWindowManager()->popGuiMode ();
|
||||||
}
|
}
|
||||||
mModel->load ();
|
mModel->load ();
|
||||||
|
|
||||||
setBookMode ();
|
setBookMode ();
|
||||||
@ -433,7 +433,6 @@ namespace
|
|||||||
void notifyClose(MyGUI::Widget* _sender)
|
void notifyClose(MyGUI::Widget* _sender)
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0);
|
MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0);
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager ()->popGuiMode ();
|
MWBase::Environment::get().getWindowManager ()->popGuiMode ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
#include "../mwbase/inputmanager.hpp"
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
@ -126,7 +127,7 @@ namespace MWGui
|
|||||||
|
|
||||||
// always update input before rendering something, otherwise mygui goes crazy when something was entered in the frame before
|
// always update input before rendering something, otherwise mygui goes crazy when something was entered in the frame before
|
||||||
// (e.g. when using "coc" console command, it would enter an infinite loop and crash due to overflow)
|
// (e.g. when using "coc" console command, it would enter an infinite loop and crash due to overflow)
|
||||||
//MWBase::Environment::get().getInputManager()->update(0, true);
|
MWBase::Environment::get().getInputManager()->update(0, true);
|
||||||
|
|
||||||
Ogre::CompositorChain* chain = Ogre::CompositorManager::getSingleton().getCompositorChain(mWindow->getViewport(0));
|
Ogre::CompositorChain* chain = Ogre::CompositorManager::getSingleton().getCompositorChain(mWindow->getViewport(0));
|
||||||
|
|
||||||
|
@ -34,6 +34,10 @@ namespace MWGui
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LocalMapBase::~LocalMapBase()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void LocalMapBase::init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, OEngine::GUI::Layout* layout, bool mapDragAndDrop)
|
void LocalMapBase::init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, OEngine::GUI::Layout* layout, bool mapDragAndDrop)
|
||||||
{
|
{
|
||||||
mLocalMap = widget;
|
mLocalMap = widget;
|
||||||
|
@ -14,6 +14,7 @@ namespace MWGui
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LocalMapBase();
|
LocalMapBase();
|
||||||
|
virtual ~LocalMapBase();
|
||||||
void init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, OEngine::GUI::Layout* layout, bool mapDragAndDrop=false);
|
void init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, OEngine::GUI::Layout* layout, bool mapDragAndDrop=false);
|
||||||
|
|
||||||
void setCellPrefix(const std::string& prefix);
|
void setCellPrefix(const std::string& prefix);
|
||||||
|
@ -32,6 +32,7 @@ namespace MWGui
|
|||||||
, mFaceIndex(0)
|
, mFaceIndex(0)
|
||||||
, mHairIndex(0)
|
, mHairIndex(0)
|
||||||
, mCurrentAngle(0)
|
, mCurrentAngle(0)
|
||||||
|
, mPreviewDirty(true)
|
||||||
{
|
{
|
||||||
// Centre dialog
|
// Centre dialog
|
||||||
center();
|
center();
|
||||||
@ -126,6 +127,8 @@ namespace MWGui
|
|||||||
mHairIndex = boost::lexical_cast<int>(index) - 1;
|
mHairIndex = boost::lexical_cast<int>(index) - 1;
|
||||||
|
|
||||||
mPreviewImage->setImageTexture ("CharacterHeadPreview");
|
mPreviewImage->setImageTexture ("CharacterHeadPreview");
|
||||||
|
|
||||||
|
mPreviewDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -174,6 +177,7 @@ namespace MWGui
|
|||||||
float angle = (float(_position) / 49.f - 0.5) * 3.14 * 2;
|
float angle = (float(_position) / 49.f - 0.5) * 3.14 * 2;
|
||||||
float diff = angle - mCurrentAngle;
|
float diff = angle - mCurrentAngle;
|
||||||
mPreview->update (diff);
|
mPreview->update (diff);
|
||||||
|
mPreviewDirty = true;
|
||||||
mCurrentAngle += diff;
|
mCurrentAngle += diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,6 +290,16 @@ namespace MWGui
|
|||||||
record.mHair = mAvailableHairs[mHairIndex];
|
record.mHair = mAvailableHairs[mHairIndex];
|
||||||
|
|
||||||
mPreview->setPrototype(record);
|
mPreview->setPrototype(record);
|
||||||
|
mPreviewDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RaceDialog::doRenderUpdate()
|
||||||
|
{
|
||||||
|
if (mPreviewDirty)
|
||||||
|
{
|
||||||
|
mPreview->render();
|
||||||
|
mPreviewDirty = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RaceDialog::updateRaces()
|
void RaceDialog::updateRaces()
|
||||||
|
@ -52,6 +52,8 @@ namespace MWGui
|
|||||||
*/
|
*/
|
||||||
EventHandle_Void eventBack;
|
EventHandle_Void eventBack;
|
||||||
|
|
||||||
|
void doRenderUpdate();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onHeadRotate(MyGUI::ScrollBar* _sender, size_t _position);
|
void onHeadRotate(MyGUI::ScrollBar* _sender, size_t _position);
|
||||||
|
|
||||||
@ -98,6 +100,8 @@ namespace MWGui
|
|||||||
float mCurrentAngle;
|
float mCurrentAngle;
|
||||||
|
|
||||||
MWRender::RaceSelectionPreview* mPreview;
|
MWRender::RaceSelectionPreview* mPreview;
|
||||||
|
|
||||||
|
bool mPreviewDirty;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user