Merge branch 'master' into NonTableFields

Conflicts:
	apps/opencs/model/tools/tools.cpp
	apps/opencs/model/world/columnbase.cpp
	apps/opencs/model/world/commands.cpp
	apps/opencs/model/world/commands.hpp
	apps/opencs/model/world/idtable.hpp
	apps/opencs/model/world/refidadapter.cpp
	apps/opencs/model/world/refidadapter.hpp
	apps/opencs/view/world/dialoguesubview.hpp
test
cc9cii 10 years ago
commit 5eefcd862f

@ -39,6 +39,7 @@ Programmers
Eli2 Eli2
Emanuel Guével (potatoesmaster) Emanuel Guével (potatoesmaster)
eroen eroen
escondida
Evgeniy Mineev (sandstranger) Evgeniy Mineev (sandstranger)
Fil Krynicki (filkry) Fil Krynicki (filkry)
Gašper Sedej Gašper Sedej

@ -1,3 +1,42 @@
0.35.1
------
Bug #781: incorrect trajectory of the sun
Bug #1079: Wrong starting position in "Character Stuff Wonderland"
Bug #1443: Repetitive taking of a stolen object is repetitively considered as a crime
Bug #1533: Divine Intervention goes to the wrong place.
Bug #1714: No visual indicator for time passed during training
Bug #1916: Telekinesis does not allow safe opening of traps
Bug #2227: Editor: addon file name inconsistency
Bug #2271: Player can melee enemies from water with impunity
Bug #2275: Objects with bigger scale move further using Move script
Bug #2285: Aryon's Dominator enchantment does not work properly
Bug #2290: No punishment for stealing gold from owned containers
Bug #2328: Launcher does not respond to Ctrl+C
Bug #2334: Drag-and-drop on a content file in the launcher creates duplicate items
Bug #2338: Arrows reclaimed from corpses do not stack sometimes
Bug #2344: Launcher - Settings importer running correctly?
Bug #2346: Launcher - Importing plugins into content list screws up the load order
Bug #2348: Mod: H.E.L.L.U.V.A. Handy Holdables does not appear in the content list
Bug #2353: Detect Animal detects dead creatures
Bug #2354: Cmake does not respect LIB_SUFFIX
Bug #2356: Active magic set inactive when switching magic items
Bug #2361: ERROR: ESM Error: Previous record contains unread bytes
Bug #2382: Switching spells with "next spell" or "previous spell" while holding shift promps delete spell dialog
Bug #2388: Regression: Can't toggle map on/off
Bug #2392: MOD Shrines - Restore Health and Cancel Options adds 100 health points
Bug #2394: List of Data Files tab in openmw-laucher needs to show all content files.
Bug #2402: Editor: skills saved incorrectly
Bug #2408: Equipping a constant effect Restore Health/Magicka/Fatigue item will permanently boost the stat it's restoring
Bug #2415: It is now possible to fall off the prison ship into the water when starting a new game
Bug #2419: MOD MCA crash to desktop
Bug #2420: Game crashes when character enters a certain area
Bug #2421: infinite loop when using cycle weapon without having a weapon
Feature #2221: Cannot dress dead NPCs
Feature #2349: Check CMake sets correct MSVC compiler settings for release build.
Feature #2397: Set default values for global mandatory records.
Feature #2412: Basic joystick support
0.35.0 0.35.0
------ ------

@ -20,7 +20,7 @@ message(STATUS "Configuring OpenMW...")
set(OPENMW_VERSION_MAJOR 0) set(OPENMW_VERSION_MAJOR 0)
set(OPENMW_VERSION_MINOR 35) set(OPENMW_VERSION_MINOR 35)
set(OPENMW_VERSION_RELEASE 0) set(OPENMW_VERSION_RELEASE 1)
set(OPENMW_VERSION_COMMITHASH "") set(OPENMW_VERSION_COMMITHASH "")
set(OPENMW_VERSION_TAGHASH "") set(OPENMW_VERSION_TAGHASH "")
@ -97,43 +97,6 @@ endif()
# We probably support older versions than this. # We probably support older versions than this.
cmake_minimum_required(VERSION 2.6) cmake_minimum_required(VERSION 2.6)
# source directory: libs
set(LIBS_DIR ${CMAKE_SOURCE_DIR}/libs)
set(OENGINE_OGRE
${LIBS_DIR}/openengine/ogre/renderer.cpp
${LIBS_DIR}/openengine/ogre/lights.cpp
${LIBS_DIR}/openengine/ogre/selectionbuffer.cpp
${LIBS_DIR}/openengine/ogre/imagerotate.cpp
)
set(OENGINE_GUI
${LIBS_DIR}/openengine/gui/loglistener.cpp
${LIBS_DIR}/openengine/gui/manager.cpp
${LIBS_DIR}/openengine/gui/layout.cpp
)
set(OENGINE_BULLET
${LIBS_DIR}/openengine/bullet/BtOgre.cpp
${LIBS_DIR}/openengine/bullet/BtOgreExtras.h
${LIBS_DIR}/openengine/bullet/BtOgreGP.h
${LIBS_DIR}/openengine/bullet/BtOgrePG.h
${LIBS_DIR}/openengine/bullet/physic.cpp
${LIBS_DIR}/openengine/bullet/physic.hpp
${LIBS_DIR}/openengine/bullet/BulletShapeLoader.cpp
${LIBS_DIR}/openengine/bullet/BulletShapeLoader.h
${LIBS_DIR}/openengine/bullet/trace.cpp
${LIBS_DIR}/openengine/bullet/trace.h
)
set(OENGINE_ALL ${OENGINE_OGRE} ${OENGINE_GUI} ${OENGINE_BULLET})
source_group(libs\\openengine FILES ${OENGINE_ALL})
set(OPENMW_LIBS ${OENGINE_ALL})
set(OPENMW_LIBS_HEADER)
# Sound setup # Sound setup
set(FFmpeg_FIND_COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE SWRESAMPLE AVRESAMPLE) set(FFmpeg_FIND_COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE SWRESAMPLE AVRESAMPLE)
unset(FFMPEG_LIBRARIES CACHE) unset(FFMPEG_LIBRARIES CACHE)
@ -266,7 +229,8 @@ endif ()
endif(WIN32) endif(WIN32)
endif(OGRE_STATIC) endif(OGRE_STATIC)
include_directories("." include_directories("." ${LIBS_DIR}
SYSTEM
${OGRE_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Ogre ${OGRE_INCLUDE_DIR}/OGRE ${OGRE_INCLUDE_DIRS} ${OGRE_PLUGIN_INCLUDE_DIRS} ${OGRE_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Ogre ${OGRE_INCLUDE_DIR}/OGRE ${OGRE_INCLUDE_DIRS} ${OGRE_PLUGIN_INCLUDE_DIRS}
${OGRE_INCLUDE_DIR}/Overlay ${OGRE_Overlay_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Overlay ${OGRE_Overlay_INCLUDE_DIR}
${SDL2_INCLUDE_DIR} ${SDL2_INCLUDE_DIR}
@ -275,7 +239,7 @@ include_directories("."
${MYGUI_INCLUDE_DIRS} ${MYGUI_INCLUDE_DIRS}
${MYGUI_PLATFORM_INCLUDE_DIRS} ${MYGUI_PLATFORM_INCLUDE_DIRS}
${OPENAL_INCLUDE_DIR} ${OPENAL_INCLUDE_DIR}
${LIBS_DIR} ${BULLET_INCLUDE_DIRS}
) )
link_directories(${SDL2_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR} ${MYGUI_LIB_DIR}) link_directories(${SDL2_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR} ${MYGUI_LIB_DIR})
@ -385,22 +349,22 @@ if (NOT WIN32 AND NOT APPLE)
"${OpenMW_BINARY_DIR}/openmw-cs.desktop") "${OpenMW_BINARY_DIR}/openmw-cs.desktop")
endif() endif()
# Compiler settings # CXX Compiler settings
if (CMAKE_COMPILER_IS_GNUCC) if (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang)
set_property(GLOBAL APPEND_STRING PROPERTY COMPILE_FLAGS "-Wall -Wextra -Wno-unused-parameter -Wno-reorder -std=c++98 -pedantic -Wno-long-long") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unused-parameter -Wno-reorder -std=c++98 -pedantic -Wno-long-long")
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 (CMAKE_CXX_COMPILER_ID STREQUAL GNU AND "${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6)
set_property(GLOBAL APPEND_STRING PROPERTY COMPILE_FLAGS "-Wno-unused-but-set-parameter") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-but-set-parameter")
endif("${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6) endif(CMAKE_CXX_COMPILER_ID STREQUAL GNU AND "${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6)
elseif (MSVC) elseif (MSVC)
# Enable link-time code generation globally for all linking # Enable link-time code generation globally for all linking
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG") set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG") set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG")
set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} /LTCG") set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} /LTCG")
endif (CMAKE_COMPILER_IS_GNUCC) endif (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang)
IF(NOT WIN32 AND NOT APPLE) IF(NOT WIN32 AND NOT APPLE)
# Linux building # Linux building
@ -572,6 +536,10 @@ if(WIN32)
include(CPack) include(CPack)
endif(WIN32) endif(WIN32)
# Libs
include_directories(libs)
add_subdirectory(libs/openengine)
# Extern # Extern
add_subdirectory (extern/shiny) add_subdirectory (extern/shiny)
add_subdirectory (extern/ogre-ffmpeg-videoplayer) add_subdirectory (extern/ogre-ffmpeg-videoplayer)
@ -705,7 +673,7 @@ if (WIN32)
set(WARNINGS "${WARNINGS} /wd${d}") set(WARNINGS "${WARNINGS} /wd${d}")
endforeach(d) endforeach(d)
set_property(GLOBAL APPEND_STRING PROPERTY COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNINGS} ${MT_BUILD}")
# boost::wave has a few issues with signed / unsigned conversions, so we suppress those here # boost::wave has a few issues with signed / unsigned conversions, so we suppress those here
set(SHINY_WARNINGS "${WARNINGS} /wd4245") set(SHINY_WARNINGS "${WARNINGS} /wd4245")

@ -6,7 +6,7 @@ OpenMW
OpenMW is an attempt at recreating the engine for the popular role-playing game OpenMW is an attempt at recreating the engine for the popular role-playing game
Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work. Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work.
* Version: 0.35.0 * Version: 0.35.1
* License: GPL (see docs/license/GPL3.txt for more information) * License: GPL (see docs/license/GPL3.txt for more information)
* Website: http://www.openmw.org * Website: http://www.openmw.org
* IRC: #openmw on irc.freenode.net * IRC: #openmw on irc.freenode.net
@ -23,7 +23,7 @@ Getting Started
* [Testing the game](https://wiki.openmw.org/index.php?title=Testing) * [Testing the game](https://wiki.openmw.org/index.php?title=Testing)
* [How to contribute](https://wiki.openmw.org/index.php?title=Contribution_Wanted) * [How to contribute](https://wiki.openmw.org/index.php?title=Contribution_Wanted)
* [Report a bug](http://bugs.openmw.org/projects/openmw) - read the [guidelines](https://wiki.openmw.org/index.php?title=Bug_Reporting_Guidelines) before submitting your first bug! * [Report a bug](http://bugs.openmw.org/projects/openmw) - read the [guidelines](https://wiki.openmw.org/index.php?title=Bug_Reporting_Guidelines) before submitting your first bug!
* [Known issues] (http://bugs.openmw.org/projects/openmw/issues?utf8=%E2%9C%93&set_filter=1&f%5B%5D=status_id&op%5Bstatus_id%5D=%3D&v%5Bstatus_id%5D%5B%5D=7&f%5B%5D=tracker_id&op%5Btracker_id%5D=%3D&v%5Btracker_id%5D%5B%5D=1&f%5B%5D=&c%5B%5D=project&c%5B%5D=tracker&c%5B%5D=status&c%5B%5D=priority&c%5B%5D=subject&c%5B%5D=assigned_to&c%5B%5D=updated_on&group_by=tracker) * [Known issues](http://bugs.openmw.org/projects/openmw/issues?utf8=%E2%9C%93&set_filter=1&f%5B%5D=status_id&op%5Bstatus_id%5D=%3D&v%5Bstatus_id%5D%5B%5D=7&f%5B%5D=tracker_id&op%5Btracker_id%5D=%3D&v%5Btracker_id%5D%5B%5D=1&f%5B%5D=&c%5B%5D=project&c%5B%5D=tracker&c%5B%5D=status&c%5B%5D=priority&c%5B%5D=subject&c%5B%5D=assigned_to&c%5B%5D=updated_on&group_by=tracker)
The data path The data path
------------- -------------
@ -68,9 +68,9 @@ Command line options
of the blacklist is enabled) of the blacklist is enabled)
--script-blacklist-use [=arg(=1)] (=1) --script-blacklist-use [=arg(=1)] (=1)
enable script blacklisting enable script blacklisting
--load-savegame arg load a save game file on game startup --load-savegame arg load a save game file on game startup
(specify an absolute filename or a (specify an absolute filename or a
filename relative to the current filename relative to the current
working directory) working directory)
--skip-menu [=arg(=1)] (=0) skip main menu on game startup --skip-menu [=arg(=1)] (=0) skip main menu on game startup
--new-game [=arg(=1)] (=0) run new game sequence (ignored if --new-game [=arg(=1)] (=0) run new game sequence (ignored if

@ -460,7 +460,7 @@ int clone(Arguments& info)
for (Stats::iterator it = stats.begin(); it != stats.end(); ++it) for (Stats::iterator it = stats.begin(); it != stats.end(); ++it)
{ {
name.val = it->first; name.val = it->first;
float amount = it->second; int amount = it->second;
std::cout << std::setw(digitCount) << amount << " " << name.toString() << " "; std::cout << std::setw(digitCount) << amount << " " << name.toString() << " ";
if (++i % 3 == 0) if (++i % 3 == 0)

@ -6,6 +6,9 @@
#include <boost/format.hpp> #include <boost/format.hpp>
namespace
{
void printAIPackage(ESM::AIPackage p) void printAIPackage(ESM::AIPackage p)
{ {
std::cout << " AI Type: " << aiTypeLabel(p.mType) std::cout << " AI Type: " << aiTypeLabel(p.mType)
@ -16,7 +19,7 @@ void printAIPackage(ESM::AIPackage p)
std::cout << " Duration: " << p.mWander.mDuration << std::endl; std::cout << " Duration: " << p.mWander.mDuration << std::endl;
std::cout << " Time of Day: " << (int)p.mWander.mTimeOfDay << std::endl; std::cout << " Time of Day: " << (int)p.mWander.mTimeOfDay << std::endl;
if (p.mWander.mShouldRepeat != 1) if (p.mWander.mShouldRepeat != 1)
std::cout << " Should repeat: " << (bool)p.mWander.mShouldRepeat << std::endl; std::cout << " Should repeat: " << (bool)(p.mWander.mShouldRepeat != 0) << std::endl;
std::cout << " Idle: "; std::cout << " Idle: ";
for (int i = 0; i != 8; i++) for (int i = 0; i != 8; i++)
@ -149,6 +152,26 @@ void printEffectList(ESM::EffectList effects)
} }
} }
void printTransport(const std::vector<ESM::Transport::Dest>& transport)
{
std::vector<ESM::Transport::Dest>::const_iterator dit;
for (dit = transport.begin(); dit != transport.end(); ++dit)
{
std::cout << " Destination Position: "
<< boost::format("%12.3f") % dit->mPos.pos[0] << ","
<< boost::format("%12.3f") % dit->mPos.pos[1] << ","
<< boost::format("%12.3f") % dit->mPos.pos[2] << ")" << std::endl;
std::cout << " Destination Rotation: "
<< boost::format("%9.6f") % dit->mPos.rot[0] << ","
<< boost::format("%9.6f") % dit->mPos.rot[1] << ","
<< boost::format("%9.6f") % dit->mPos.rot[2] << ")" << std::endl;
if (dit->mCellName != "")
std::cout << " Destination Cell: " << dit->mCellName << std::endl;
}
}
}
namespace EsmTool { namespace EsmTool {
RecordBase * RecordBase *
@ -631,6 +654,8 @@ void Record<ESM::Creature>::print()
for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); ++sit) for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); ++sit)
std::cout << " Spell: " << *sit << std::endl; std::cout << " Spell: " << *sit << std::endl;
printTransport(mData.getTransport());
std::cout << " Artifical Intelligence: " << mData.mHasAI << std::endl; std::cout << " Artifical Intelligence: " << mData.mHasAI << std::endl;
std::cout << " AI Hello:" << (int)mData.mAiData.mHello << std::endl; std::cout << " AI Hello:" << (int)mData.mAiData.mHello << std::endl;
std::cout << " AI Fight:" << (int)mData.mAiData.mFight << std::endl; std::cout << " AI Fight:" << (int)mData.mAiData.mFight << std::endl;
@ -1042,20 +1067,7 @@ void Record<ESM::NPC>::print()
for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); ++sit) for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); ++sit)
std::cout << " Spell: " << *sit << std::endl; std::cout << " Spell: " << *sit << std::endl;
std::vector<ESM::NPC::Dest>::iterator dit; printTransport(mData.getTransport());
for (dit = mData.mTransport.begin(); dit != mData.mTransport.end(); ++dit)
{
std::cout << " Destination Position: "
<< boost::format("%12.3f") % dit->mPos.pos[0] << ","
<< boost::format("%12.3f") % dit->mPos.pos[1] << ","
<< boost::format("%12.3f") % dit->mPos.pos[2] << ")" << std::endl;
std::cout << " Destination Rotation: "
<< boost::format("%9.6f") % dit->mPos.rot[0] << ","
<< boost::format("%9.6f") % dit->mPos.rot[1] << ","
<< boost::format("%9.6f") % dit->mPos.rot[2] << ")" << std::endl;
if (dit->mCellName != "")
std::cout << " Destination Cell: " << dit->mCellName << std::endl;
}
std::cout << " Artifical Intelligence: " << mData.mHasAI << std::endl; std::cout << " Artifical Intelligence: " << mData.mHasAI << std::endl;
std::cout << " AI Hello:" << (int)mData.mAiData.mHello << std::endl; std::cout << " AI Hello:" << (int)mData.mAiData.mHello << std::endl;

@ -23,18 +23,18 @@ namespace ESSImport
} }
for (int i=0; i<8; ++i) for (int i=0; i<8; ++i)
{ {
cStats.mAttributes[i].mBase = acdt.mAttributes[i][1]; cStats.mAttributes[i].mBase = static_cast<int>(acdt.mAttributes[i][1]);
cStats.mAttributes[i].mMod = acdt.mAttributes[i][0]; cStats.mAttributes[i].mMod = static_cast<int>(acdt.mAttributes[i][0]);
cStats.mAttributes[i].mCurrent = acdt.mAttributes[i][0]; cStats.mAttributes[i].mCurrent = static_cast<int>(acdt.mAttributes[i][0]);
} }
cStats.mGoldPool = acdt.mGoldPool; cStats.mGoldPool = acdt.mGoldPool;
cStats.mTalkedTo = acdt.mFlags & TalkedToPlayer; cStats.mTalkedTo = (acdt.mFlags & TalkedToPlayer) != 0;
cStats.mAttacked = acdt.mFlags & Attacked; cStats.mAttacked = (acdt.mFlags & Attacked) != 0;
} }
void convertACSC (const ACSC& acsc, ESM::CreatureStats& cStats) void convertACSC (const ACSC& acsc, ESM::CreatureStats& cStats)
{ {
cStats.mDead = acsc.mFlags & Dead; cStats.mDead = (acsc.mFlags & Dead) != 0;
} }
void convertNpcData (const ActorData& actorData, ESM::NpcStats& npcStats) void convertNpcData (const ActorData& actorData, ESM::NpcStats& npcStats)

@ -553,7 +553,7 @@ public:
ESM::WeatherState weather; ESM::WeatherState weather;
weather.mCurrentWeather = toString(mGame.mGMDT.mCurrentWeather); weather.mCurrentWeather = toString(mGame.mGMDT.mCurrentWeather);
weather.mNextWeather = toString(mGame.mGMDT.mNextWeather); weather.mNextWeather = toString(mGame.mGMDT.mNextWeather);
weather.mRemainingTransitionTime = mGame.mGMDT.mWeatherTransition/100.f*(0.015*24*3600); weather.mRemainingTransitionTime = mGame.mGMDT.mWeatherTransition/100.f*(0.015f*24*3600);
weather.mHour = mContext->mHour; weather.mHour = mContext->mHour;
weather.mWindSpeed = 0.f; weather.mWindSpeed = 0.f;
weather.mTimePassed = 0.0; weather.mTimePassed = 0.0;

@ -43,7 +43,7 @@ namespace ESSImport
{ {
unsigned int deleted; unsigned int deleted;
esm.getHT(deleted); esm.getHT(deleted);
mDeleted = (deleted >> 24) & 0x2; // the other 3 bytes seem to be uninitialized garbage mDeleted = ((deleted >> 24) & 0x2) != 0; // the other 3 bytes seem to be uninitialized garbage
} }
if (esm.isNextSub("MVRF")) if (esm.isNextSub("MVRF"))

@ -903,4 +903,4 @@ std::time_t MwIniImporter::lastWriteTime(const boost::filesystem::path& filename
std::cout << "content file: " << filename << " not found" << std::endl; std::cout << "content file: " << filename << " not found" << std::endl;
} }
return writeTime; return writeTime;
} }

@ -110,7 +110,7 @@ int wmain(int argc, wchar_t *wargv[]) {
std::cerr << "cfg file does not exist" << std::endl; std::cerr << "cfg file does not exist" << std::endl;
MwIniImporter importer; MwIniImporter importer;
importer.setVerbose(vm.count("verbose")); importer.setVerbose(vm.count("verbose") != 0);
// Font encoding settings // Font encoding settings
std::string encoding(vm["encoding"].as<std::string>()); std::string encoding(vm["encoding"].as<std::string>());

@ -5,7 +5,7 @@ set (OPENCS_SRC main.cpp
opencs_units (. editor) opencs_units (. editor)
opencs_units (model/doc opencs_units (model/doc
document operation saving documentmanager loader runner document operation saving documentmanager loader runner operationholder
) )
opencs_units_noqt (model/doc opencs_units_noqt (model/doc
@ -166,7 +166,8 @@ qt4_wrap_ui(OPENCS_UI_HDR ${OPENCS_UI})
qt4_wrap_cpp(OPENCS_MOC_SRC ${OPENCS_HDR_QT}) qt4_wrap_cpp(OPENCS_MOC_SRC ${OPENCS_HDR_QT})
qt4_add_resources(OPENCS_RES_SRC ${OPENCS_RES}) qt4_add_resources(OPENCS_RES_SRC ${OPENCS_RES})
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${BULLET_INCLUDE_DIRS}) # for compiled .ui files
include_directories(${CMAKE_CURRENT_BINARY_DIR})
if(APPLE) if(APPLE)
set (OPENCS_MAC_ICON ${CMAKE_SOURCE_DIR}/files/mac/openmw-cs.icns) set (OPENCS_MAC_ICON ${CMAKE_SOURCE_DIR}/files/mac/openmw-cs.icns)
@ -176,7 +177,6 @@ endif(APPLE)
add_executable(openmw-cs add_executable(openmw-cs
MACOSX_BUNDLE MACOSX_BUNDLE
${OENGINE_BULLET}
${OPENCS_SRC} ${OPENCS_SRC}
${OPENCS_UI_HDR} ${OPENCS_UI_HDR}
${OPENCS_MOC_SRC} ${OPENCS_MOC_SRC}
@ -200,6 +200,7 @@ if(APPLE)
endif(APPLE) endif(APPLE)
target_link_libraries(openmw-cs target_link_libraries(openmw-cs
${OENGINE_LIBRARY}
${OGRE_LIBRARIES} ${OGRE_LIBRARIES}
${OGRE_Overlay_LIBRARIES} ${OGRE_Overlay_LIBRARIES}
${OGRE_STATIC_PLUGINS} ${OGRE_STATIC_PLUGINS}

@ -28,4 +28,4 @@ void CSMDoc::Blacklist::add (CSMWorld::UniversalId::Type type,
std::transform (ids.begin(), ids.end(), list.begin()+size, Misc::StringUtils::lowerCase); std::transform (ids.begin(), ids.end(), list.begin()+size, Misc::StringUtils::lowerCase);
std::sort (list.begin(), list.end()); std::sort (list.begin(), list.end());
} }

@ -2254,7 +2254,8 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
mTools (*this), mResDir(resDir), mTools (*this), mResDir(resDir),
mProjectPath ((configuration.getUserDataPath() / "projects") / mProjectPath ((configuration.getUserDataPath() / "projects") /
(savePath.filename().string() + ".project")), (savePath.filename().string() + ".project")),
mSaving (*this, mProjectPath, encoding), mSavingOperation (*this, mProjectPath, encoding),
mSaving (&mSavingOperation),
mRunner (mProjectPath), mPhysics(boost::shared_ptr<CSVWorld::PhysicsSystem>()) mRunner (mProjectPath), mPhysics(boost::shared_ptr<CSVWorld::PhysicsSystem>())
{ {
if (mContentFiles.empty()) if (mContentFiles.empty())

@ -20,6 +20,7 @@
#include "saving.hpp" #include "saving.hpp"
#include "blacklist.hpp" #include "blacklist.hpp"
#include "runner.hpp" #include "runner.hpp"
#include "operationholder.hpp"
class QAbstractItemModel; class QAbstractItemModel;
@ -32,7 +33,7 @@ namespace ESM
namespace Files namespace Files
{ {
class ConfigurationManager; struct ConfigurationManager;
} }
namespace CSMWorld namespace CSMWorld
@ -59,7 +60,8 @@ namespace CSMDoc
CSMWorld::Data mData; CSMWorld::Data mData;
CSMTools::Tools mTools; CSMTools::Tools mTools;
boost::filesystem::path mProjectPath; boost::filesystem::path mProjectPath;
Saving mSaving; Saving mSavingOperation;
OperationHolder mSaving;
boost::filesystem::path mResDir; boost::filesystem::path mResDir;
Blacklist mBlacklist; Blacklist mBlacklist;
Runner mRunner; Runner mRunner;

@ -107,4 +107,4 @@ void CSMDoc::DocumentManager::documentNotLoaded (Document *document, const std::
if (error.empty()) // do not remove the document yet, if we have an error if (error.empty()) // do not remove the document yet, if we have an error
removeDocument (document); removeDocument (document);
} }

@ -17,7 +17,7 @@
namespace Files namespace Files
{ {
class ConfigurationManager; struct ConfigurationManager;
} }
namespace CSMDoc namespace CSMDoc
@ -50,7 +50,7 @@ namespace CSMDoc
///< \param new_ Do not load the last content file in \a files and instead create in an ///< \param new_ Do not load the last content file in \a files and instead create in an
/// appropriate way. /// appropriate way.
void setResourceDir (const boost::filesystem::path& parResDir); void setResourceDir (const boost::filesystem::path& parResDir);
void setEncoding (ToUTF8::FromType encoding); void setEncoding (ToUTF8::FromType encoding);
@ -61,7 +61,7 @@ namespace CSMDoc
private: private:
boost::filesystem::path mResDir; boost::filesystem::path mResDir;
private slots: private slots:
@ -99,4 +99,4 @@ namespace CSMDoc
}; };
} }
#endif #endif

@ -25,4 +25,4 @@ CSMDoc::Messages::Iterator CSMDoc::Messages::begin() const
CSMDoc::Messages::Iterator CSMDoc::Messages::end() const CSMDoc::Messages::Iterator CSMDoc::Messages::end() const
{ {
return mMessages.end(); return mMessages.end();
} }

@ -29,9 +29,9 @@ void CSMDoc::Operation::prepareStages()
CSMDoc::Operation::Operation (int type, bool ordered, bool finalAlways) CSMDoc::Operation::Operation (int type, bool ordered, bool finalAlways)
: mType (type), mStages(std::vector<std::pair<Stage *, int> >()), mCurrentStage(mStages.begin()), : mType (type), mStages(std::vector<std::pair<Stage *, int> >()), mCurrentStage(mStages.begin()),
mCurrentStep(0), mCurrentStepTotal(0), mTotalSteps(0), mOrdered (ordered), mCurrentStep(0), mCurrentStepTotal(0), mTotalSteps(0), mOrdered (ordered),
mFinalAlways (finalAlways), mError(false) mFinalAlways (finalAlways), mError(false), mConnected (false)
{ {
connect (this, SIGNAL (finished()), this, SLOT (operationDone())); mTimer = new QTimer (this);
} }
CSMDoc::Operation::~Operation() CSMDoc::Operation::~Operation()
@ -42,15 +42,17 @@ CSMDoc::Operation::~Operation()
void CSMDoc::Operation::run() void CSMDoc::Operation::run()
{ {
mTimer->stop();
if (!mConnected)
{
connect (mTimer, SIGNAL (timeout()), this, SLOT (executeStage()));
mConnected = true;
}
prepareStages(); prepareStages();
QTimer timer; mTimer->start (0);
timer.connect (&timer, SIGNAL (timeout()), this, SLOT (executeStage()));
timer.start (0);
exec();
} }
void CSMDoc::Operation::appendStage (Stage *stage) void CSMDoc::Operation::appendStage (Stage *stage)
@ -65,7 +67,7 @@ bool CSMDoc::Operation::hasError() const
void CSMDoc::Operation::abort() void CSMDoc::Operation::abort()
{ {
if (!isRunning()) if (!mTimer->isActive())
return; return;
mError = true; mError = true;
@ -116,10 +118,11 @@ void CSMDoc::Operation::executeStage()
emit reportMessage (iter->mId, iter->mMessage, iter->mHint, mType); emit reportMessage (iter->mId, iter->mMessage, iter->mHint, mType);
if (mCurrentStage==mStages.end()) if (mCurrentStage==mStages.end())
exit(); operationDone();
} }
void CSMDoc::Operation::operationDone() void CSMDoc::Operation::operationDone()
{ {
mTimer->stop();
emit done (mType, mError); emit done (mType, mError);
} }

@ -3,7 +3,8 @@
#include <vector> #include <vector>
#include <QThread> #include <QObject>
#include <QTimer>
namespace CSMWorld namespace CSMWorld
{ {
@ -14,7 +15,7 @@ namespace CSMDoc
{ {
class Stage; class Stage;
class Operation : public QThread class Operation : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -27,6 +28,8 @@ namespace CSMDoc
int mOrdered; int mOrdered;
bool mFinalAlways; bool mFinalAlways;
bool mError; bool mError;
bool mConnected;
QTimer *mTimer;
void prepareStages(); void prepareStages();
@ -38,8 +41,6 @@ namespace CSMDoc
virtual ~Operation(); virtual ~Operation();
virtual void run();
void appendStage (Stage *stage); void appendStage (Stage *stage);
///< The ownership of \a stage is transferred to *this. ///< The ownership of \a stage is transferred to *this.
/// ///
@ -60,6 +61,8 @@ namespace CSMDoc
void abort(); void abort();
void run();
private slots: private slots:
void executeStage(); void executeStage();
@ -68,4 +71,4 @@ namespace CSMDoc
}; };
} }
#endif #endif

@ -0,0 +1,65 @@
#include "operationholder.hpp"
#include "operation.hpp"
CSMDoc::OperationHolder::OperationHolder (Operation *operation) : mRunning (false)
{
if (operation)
setOperation (operation);
}
void CSMDoc::OperationHolder::setOperation (Operation *operation)
{
mOperation = operation;
mOperation->moveToThread (&mThread);
connect (
mOperation, SIGNAL (progress (int, int, int)),
this, SIGNAL (progress (int, int, int)));
connect (
mOperation, SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)),
this, SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)));
connect (
mOperation, SIGNAL (done (int, bool)),
this, SLOT (doneSlot (int, bool)));
connect (this, SIGNAL (abortSignal()), mOperation, SLOT (abort()));
connect (&mThread, SIGNAL (started()), mOperation, SLOT (run()));
}
bool CSMDoc::OperationHolder::isRunning() const
{
return mRunning;
}
void CSMDoc::OperationHolder::start()
{
mRunning = true;
mThread.start();
}
void CSMDoc::OperationHolder::abort()
{
mRunning = false;
emit abortSignal();
}
void CSMDoc::OperationHolder::abortAndWait()
{
if (mRunning)
{
mThread.quit();
mThread.wait();
}
}
void CSMDoc::OperationHolder::doneSlot (int type, bool failed)
{
mRunning = false;
mThread.quit();
emit done (type, failed);
}

@ -0,0 +1,56 @@
#ifndef CSM_DOC_OPERATIONHOLDER_H
#define CSM_DOC_OPERATIONHOLDER_H
#include <QObject>
#include <QThread>
namespace CSMWorld
{
class UniversalId;
}
namespace CSMDoc
{
class Operation;
class OperationHolder : public QObject
{
Q_OBJECT
QThread mThread;
Operation *mOperation;
bool mRunning;
public:
OperationHolder (Operation *operation = 0);
void setOperation (Operation *operation);
bool isRunning() const;
void start();
void abort();
// Abort and wait until thread has finished.
void abortAndWait();
private slots:
void doneSlot (int type, bool failed);
signals:
void progress (int current, int max, int type);
void reportMessage (const CSMWorld::UniversalId& id, const std::string& message,
const std::string& hint, int type);
void done (int type, bool failed);
void abortSignal();
};
}
#endif

@ -6,7 +6,7 @@
#include <QTemporaryFile> #include <QTemporaryFile>
#include <QTextStream> #include <QTextStream>
#include "operation.hpp" #include "operationholder.hpp"
CSMDoc::Runner::Runner (const boost::filesystem::path& projectPath) CSMDoc::Runner::Runner (const boost::filesystem::path& projectPath)
: mRunning (false), mStartup (0), mProjectPath (projectPath) : mRunning (false), mStartup (0), mProjectPath (projectPath)
@ -145,7 +145,7 @@ void CSMDoc::Runner::readyReadStandardOutput()
} }
CSMDoc::SaveWatcher::SaveWatcher (Runner *runner, Operation *operation) CSMDoc::SaveWatcher::SaveWatcher (Runner *runner, OperationHolder *operation)
: QObject (runner), mRunner (runner) : QObject (runner), mRunner (runner)
{ {
connect (operation, SIGNAL (done (int, bool)), this, SLOT (saveDone (int, bool))); connect (operation, SIGNAL (done (int, bool)), this, SLOT (saveDone (int, bool)));

@ -16,6 +16,8 @@ class QTemporaryFile;
namespace CSMDoc namespace CSMDoc
{ {
class OperationHolder;
class Runner : public QObject class Runner : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -74,7 +76,7 @@ namespace CSMDoc
public: public:
/// *this attaches itself to runner /// *this attaches itself to runner
SaveWatcher (Runner *runner, Operation *operation); SaveWatcher (Runner *runner, OperationHolder *operation);
private slots: private slots:

@ -93,8 +93,12 @@ CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& proje
appendStage (new WritePathgridCollectionStage (mDocument, mState)); appendStage (new WritePathgridCollectionStage (mDocument, mState));
appendStage (new WriteLandCollectionStage (mDocument, mState));
appendStage (new WriteLandTextureCollectionStage (mDocument, mState));
// close file and clean up // close file and clean up
appendStage (new CloseSaveStage (mState)); appendStage (new CloseSaveStage (mState));
appendStage (new FinalSavingStage (mDocument, mState)); appendStage (new FinalSavingStage (mDocument, mState));
} }

@ -90,7 +90,7 @@ void CSMDoc::WriteHeaderStage::perform (int stage, Messages& messages)
CSMDoc::WriteDialogueCollectionStage::WriteDialogueCollectionStage (Document& document, CSMDoc::WriteDialogueCollectionStage::WriteDialogueCollectionStage (Document& document,
SavingState& state, bool journal) SavingState& state, bool journal)
: mDocument (document), mState (state), : mState (state),
mTopics (journal ? document.getData().getJournals() : document.getData().getTopics()), mTopics (journal ? document.getData().getJournals() : document.getData().getTopics()),
mInfos (journal ? document.getData().getJournalInfos() : document.getData().getTopicInfos()) mInfos (journal ? document.getData().getJournalInfos() : document.getData().getTopicInfos())
{} {}
@ -353,6 +353,74 @@ void CSMDoc::WritePathgridCollectionStage::perform (int stage, Messages& message
} }
CSMDoc::WriteLandCollectionStage::WriteLandCollectionStage (Document& document,
SavingState& state)
: mDocument (document), mState (state)
{}
int CSMDoc::WriteLandCollectionStage::setup()
{
return mDocument.getData().getLand().getSize();
}
void CSMDoc::WriteLandCollectionStage::perform (int stage, Messages& messages)
{
const CSMWorld::Record<CSMWorld::Land>& land =
mDocument.getData().getLand().getRecord (stage);
if (land.mState==CSMWorld::RecordBase::State_Modified ||
land.mState==CSMWorld::RecordBase::State_ModifiedOnly)
{
CSMWorld::Land record = land.get();
mState.getWriter().startRecord (record.mLand->sRecordId);
record.mLand->save (mState.getWriter());
if(record.mLand->mLandData)
record.mLand->mLandData->save (mState.getWriter());
mState.getWriter().endRecord (record.mLand->sRecordId);
}
else if (land.mState==CSMWorld::RecordBase::State_Deleted)
{
/// \todo write record with delete flag
}
}
CSMDoc::WriteLandTextureCollectionStage::WriteLandTextureCollectionStage (Document& document,
SavingState& state)
: mDocument (document), mState (state)
{}
int CSMDoc::WriteLandTextureCollectionStage::setup()
{
return mDocument.getData().getLandTextures().getSize();
}
void CSMDoc::WriteLandTextureCollectionStage::perform (int stage, Messages& messages)
{
const CSMWorld::Record<CSMWorld::LandTexture>& landTexture =
mDocument.getData().getLandTextures().getRecord (stage);
if (landTexture.mState==CSMWorld::RecordBase::State_Modified ||
landTexture.mState==CSMWorld::RecordBase::State_ModifiedOnly)
{
CSMWorld::LandTexture record = landTexture.get();
mState.getWriter().startRecord (record.sRecordId);
record.save (mState.getWriter());
mState.getWriter().endRecord (record.sRecordId);
}
else if (landTexture.mState==CSMWorld::RecordBase::State_Deleted)
{
/// \todo write record with delete flag
}
}
CSMDoc::CloseSaveStage::CloseSaveStage (SavingState& state) CSMDoc::CloseSaveStage::CloseSaveStage (SavingState& state)
: mState (state) : mState (state)
{} {}

@ -126,7 +126,6 @@ namespace CSMDoc
class WriteDialogueCollectionStage : public Stage class WriteDialogueCollectionStage : public Stage
{ {
Document& mDocument;
SavingState& mState; SavingState& mState;
const CSMWorld::IdCollection<ESM::Dialogue>& mTopics; const CSMWorld::IdCollection<ESM::Dialogue>& mTopics;
CSMWorld::InfoCollection& mInfos; CSMWorld::InfoCollection& mInfos;
@ -209,6 +208,40 @@ namespace CSMDoc
///< Messages resulting from this stage will be appended to \a messages. ///< Messages resulting from this stage will be appended to \a messages.
}; };
class WriteLandCollectionStage : public Stage
{
Document& mDocument;
SavingState& mState;
public:
WriteLandCollectionStage (Document& document, SavingState& state);
virtual int setup();
///< \return number of steps
virtual void perform (int stage, Messages& messages);
///< Messages resulting from this stage will be appended to \a messages.
};
class WriteLandTextureCollectionStage : public Stage
{
Document& mDocument;
SavingState& mState;
public:
WriteLandTextureCollectionStage (Document& document, SavingState& state);
virtual int setup();
///< \return number of steps
virtual void perform (int stage, Messages& messages);
///< Messages resulting from this stage will be appended to \a messages.
};
class CloseSaveStage : public Stage class CloseSaveStage : public Stage
{ {
SavingState& mState; SavingState& mState;

@ -1,4 +1,4 @@
#include "stage.hpp" #include "stage.hpp"
CSMDoc::Stage::~Stage() {} CSMDoc::Stage::~Stage() {}

@ -12,4 +12,4 @@ bool CSMFilter::BooleanNode::test (const CSMWorld::IdTableBase& table, int row,
std::string CSMFilter::BooleanNode::toString (bool numericColumns) const std::string CSMFilter::BooleanNode::toString (bool numericColumns) const
{ {
return mTrue ? "true" : "false"; return mTrue ? "true" : "false";
} }

@ -26,4 +26,4 @@ namespace CSMFilter
}; };
} }
#endif #endif

@ -3,4 +3,4 @@
CSMFilter::Node::Node() {} CSMFilter::Node::Node() {}
CSMFilter::Node::~Node() {} CSMFilter::Node::~Node() {}

@ -7,4 +7,4 @@ bool CSMFilter::NotNode::test (const CSMWorld::IdTableBase& table, int row,
const std::map<int, int>& columns) const const std::map<int, int>& columns) const
{ {
return !getChild().test (table, row, columns); return !getChild().test (table, row, columns);
} }

@ -82,4 +82,4 @@ std::string CSMFilter::TextNode::toString (bool numericColumns) const
stream << ", \"" << mText << "\")"; stream << ", \"" << mText << "\")";
return stream.str(); return stream.str();
} }

@ -23,4 +23,4 @@ std::vector<int> CSMFilter::UnaryNode::getReferencedColumns() const
std::string CSMFilter::UnaryNode::toString (bool numericColumns) const std::string CSMFilter::UnaryNode::toString (bool numericColumns) const
{ {
return mName + " " + mChild->toString (numericColumns); return mName + " " + mChild->toString (numericColumns);
} }

@ -94,4 +94,4 @@ std::string CSMFilter::ValueNode::toString (bool numericColumns) const
stream << ")"; stream << ")";
return stream.str(); return stream.str();
} }

@ -41,4 +41,4 @@ void CSMTools::BirthsignCheckStage::perform (int stage, CSMDoc::Messages& messag
/// \todo test if the texture exists /// \todo test if the texture exists
/// \todo check data members that can't be edited in the table view /// \todo check data members that can't be edited in the table view
} }

@ -32,4 +32,4 @@ namespace CSMTools
}; };
} }
#endif #endif

@ -65,4 +65,4 @@ void CSMTools::ClassCheckStage::perform (int stage, CSMDoc::Messages& messages)
messages.push_back (std::make_pair (id, messages.push_back (std::make_pair (id,
ESM::Skill::indexToId (iter->first) + " is listed more than once")); ESM::Skill::indexToId (iter->first) + " is listed more than once"));
} }
} }

@ -20,4 +20,4 @@ void CSMTools::MandatoryIdStage::perform (int stage, CSMDoc::Messages& messages)
if (mIdCollection.searchId (mIds.at (stage))==-1 || if (mIdCollection.searchId (mIds.at (stage))==-1 ||
mIdCollection.getRecord (mIds.at (stage)).isDeleted()) mIdCollection.getRecord (mIds.at (stage)).isDeleted())
messages.add (mCollectionId, "Missing mandatory record: " + mIds.at (stage)); messages.add (mCollectionId, "Missing mandatory record: " + mIds.at (stage));
} }

@ -70,4 +70,4 @@ void CSMTools::RaceCheckStage::perform (int stage, CSMDoc::Messages& messages)
performFinal (messages); performFinal (messages);
else else
performPerRecord (stage, messages); performPerRecord (stage, messages);
} }

@ -26,4 +26,4 @@ namespace CSMTools
}; };
} }
#endif // CSM_TOOLS_REFERENCECHECK_H #endif // CSM_TOOLS_REFERENCECHECK_H

@ -35,4 +35,4 @@ void CSMTools::RegionCheckStage::perform (int stage, CSMDoc::Messages& messages)
/// \todo test that the ID in mSleeplist exists /// \todo test that the ID in mSleeplist exists
/// \todo check data members that can't be edited in the table view /// \todo check data members that can't be edited in the table view
} }

@ -78,4 +78,4 @@ const CSMWorld::UniversalId& CSMTools::ReportModel::getUniversalId (int row) con
std::string CSMTools::ReportModel::getHint (int row) const std::string CSMTools::ReportModel::getHint (int row) const
{ {
return mRows.at (row).second.second; return mRows.at (row).second.second;
} }

@ -98,4 +98,4 @@ void CSMTools::ScriptCheckStage::perform (int stage, CSMDoc::Messages& messages)
} }
mMessages = 0; mMessages = 0;
} }

@ -39,4 +39,4 @@ void CSMTools::SkillCheckStage::perform (int stage, CSMDoc::Messages& messages)
if (skill.mDescription.empty()) if (skill.mDescription.empty())
messages.push_back (std::make_pair (id, skill.mId + " has an empty description")); messages.push_back (std::make_pair (id, skill.mId + " has an empty description"));
} }

@ -31,4 +31,4 @@ void CSMTools::SoundCheckStage::perform (int stage, CSMDoc::Messages& messages)
messages.push_back (std::make_pair (id, "Maximum range larger than minimum range")); messages.push_back (std::make_pair (id, "Maximum range larger than minimum range"));
/// \todo check, if the sound file exists /// \todo check, if the sound file exists
} }

@ -37,4 +37,4 @@ void CSMTools::SpellCheckStage::perform (int stage, CSMDoc::Messages& messages)
messages.push_back (std::make_pair (id, spell.mId + " has a negative spell costs")); messages.push_back (std::make_pair (id, spell.mId + " has a negative spell costs"));
/// \todo check data members that can't be edited in the table view /// \todo check data members that can't be edited in the table view
} }

@ -26,30 +26,30 @@
#include "referencecheck.hpp" #include "referencecheck.hpp"
#include "startscriptcheck.hpp" #include "startscriptcheck.hpp"
CSMDoc::Operation *CSMTools::Tools::get (int type) CSMDoc::OperationHolder *CSMTools::Tools::get (int type)
{ {
switch (type) switch (type)
{ {
case CSMDoc::State_Verifying: return mVerifier; case CSMDoc::State_Verifying: return &mVerifier;
} }
return 0; return 0;
} }
const CSMDoc::Operation *CSMTools::Tools::get (int type) const const CSMDoc::OperationHolder *CSMTools::Tools::get (int type) const
{ {
return const_cast<Tools *> (this)->get (type); return const_cast<Tools *> (this)->get (type);
} }
CSMDoc::Operation *CSMTools::Tools::getVerifier() CSMDoc::OperationHolder *CSMTools::Tools::getVerifier()
{ {
if (!mVerifier) if (!mVerifierOperation)
{ {
mVerifier = new CSMDoc::Operation (CSMDoc::State_Verifying, false); mVerifierOperation = new CSMDoc::Operation (CSMDoc::State_Verifying, false);
connect (mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int))); connect (&mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int)));
connect (mVerifier, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool))); connect (&mVerifier, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool)));
connect (mVerifier, connect (&mVerifier,
SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)), SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)),
this, SLOT (verifierMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int))); this, SLOT (verifierMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)));
@ -60,46 +60,48 @@ CSMDoc::Operation *CSMTools::Tools::getVerifier()
mandatoryIds.push_back ("Month"); mandatoryIds.push_back ("Month");
mandatoryIds.push_back ("PCRace"); mandatoryIds.push_back ("PCRace");
mVerifier->appendStage (new MandatoryIdStage (mData.getGlobals(), mVerifierOperation->appendStage (new MandatoryIdStage (mData.getGlobals(),
CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Globals), mandatoryIds)); CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Globals), mandatoryIds));
mVerifier->appendStage (new SkillCheckStage (mData.getSkills())); mVerifierOperation->appendStage (new SkillCheckStage (mData.getSkills()));
mVerifier->appendStage (new ClassCheckStage (mData.getClasses())); mVerifierOperation->appendStage (new ClassCheckStage (mData.getClasses()));
mVerifier->appendStage (new FactionCheckStage (mData.getFactions())); mVerifierOperation->appendStage (new FactionCheckStage (mData.getFactions()));
mVerifier->appendStage (new RaceCheckStage (mData.getRaces())); mVerifierOperation->appendStage (new RaceCheckStage (mData.getRaces()));
mVerifier->appendStage (new SoundCheckStage (mData.getSounds())); mVerifierOperation->appendStage (new SoundCheckStage (mData.getSounds()));
mVerifier->appendStage (new RegionCheckStage (mData.getRegions())); mVerifierOperation->appendStage (new RegionCheckStage (mData.getRegions()));
mVerifier->appendStage (new BirthsignCheckStage (mData.getBirthsigns())); mVerifierOperation->appendStage (new BirthsignCheckStage (mData.getBirthsigns()));
mVerifier->appendStage (new SpellCheckStage (mData.getSpells())); mVerifierOperation->appendStage (new SpellCheckStage (mData.getSpells()));
mVerifier->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions())); mVerifierOperation->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions()));
mVerifier->appendStage (new ReferenceCheckStage(mData.getReferences(), mData.getReferenceables(), mData.getCells(), mData.getFactions())); mVerifierOperation->appendStage (new ReferenceCheckStage(mData.getReferences(), mData.getReferenceables(), mData.getCells(), mData.getFactions()));
mVerifier->appendStage (new ScriptCheckStage (mDocument)); mVerifierOperation->appendStage (new ScriptCheckStage (mDocument));
mVerifier->appendStage (new StartScriptCheckStage (mData.getStartScripts(), mData.getScripts())); mVerifierOperation->appendStage (new StartScriptCheckStage (mData.getStartScripts(), mData.getScripts()));
mVerifier->appendStage( mVerifierOperation->appendStage(
new BodyPartCheckStage( new BodyPartCheckStage(
mData.getBodyParts(), mData.getBodyParts(),
mData.getResources( mData.getResources(
CSMWorld::UniversalId( CSMWorld::UniversalId::Type_Meshes )), CSMWorld::UniversalId( CSMWorld::UniversalId::Type_Meshes )),
mData.getRaces() )); mData.getRaces() ));
mVerifier.setOperation (mVerifierOperation);
} }
return mVerifier; return &mVerifier;
} }
CSMTools::Tools::Tools (CSMDoc::Document& document) CSMTools::Tools::Tools (CSMDoc::Document& document)
: mDocument (document), mData (document.getData()), mVerifier (0), mNextReportNumber (0) : mDocument (document), mData (document.getData()), mVerifierOperation (0), mNextReportNumber (0)
{ {
// index 0: load error log // index 0: load error log
mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel)); mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel));
@ -108,7 +110,11 @@ CSMTools::Tools::Tools (CSMDoc::Document& document)
CSMTools::Tools::~Tools() CSMTools::Tools::~Tools()
{ {
delete mVerifier; if (mVerifierOperation)
{
mVerifier.abortAndWait();
delete mVerifierOperation;
}
for (std::map<int, ReportModel *>::iterator iter (mReports.begin()); iter!=mReports.end(); ++iter) for (std::map<int, ReportModel *>::iterator iter (mReports.begin()); iter!=mReports.end(); ++iter)
delete iter->second; delete iter->second;
@ -126,7 +132,7 @@ CSMWorld::UniversalId CSMTools::Tools::runVerifier()
void CSMTools::Tools::abortOperation (int type) void CSMTools::Tools::abortOperation (int type)
{ {
if (CSMDoc::Operation *operation = get (type)) if (CSMDoc::OperationHolder *operation = get (type))
operation->abort(); operation->abort();
} }
@ -141,7 +147,7 @@ int CSMTools::Tools::getRunningOperations() const
int result = 0; int result = 0;
for (int i=0; sOperations[i]!=-1; ++i) for (int i=0; sOperations[i]!=-1; ++i)
if (const CSMDoc::Operation *operation = get (sOperations[i])) if (const CSMDoc::OperationHolder *operation = get (sOperations[i]))
if (operation->isRunning()) if (operation->isRunning())
result |= sOperations[i]; result |= sOperations[i];

@ -5,6 +5,8 @@
#include <map> #include <map>
#include "../doc/operationholder.hpp"
namespace CSMWorld namespace CSMWorld
{ {
class Data; class Data;
@ -27,7 +29,8 @@ namespace CSMTools
CSMDoc::Document& mDocument; CSMDoc::Document& mDocument;
CSMWorld::Data& mData; CSMWorld::Data& mData;
CSMDoc::Operation *mVerifier; CSMDoc::Operation *mVerifierOperation;
CSMDoc::OperationHolder mVerifier;
std::map<int, ReportModel *> mReports; std::map<int, ReportModel *> mReports;
int mNextReportNumber; int mNextReportNumber;
std::map<int, int> mActiveReports; // type, report number std::map<int, int> mActiveReports; // type, report number
@ -36,12 +39,12 @@ namespace CSMTools
Tools (const Tools&); Tools (const Tools&);
Tools& operator= (const Tools&); Tools& operator= (const Tools&);
CSMDoc::Operation *getVerifier(); CSMDoc::OperationHolder *getVerifier();
CSMDoc::Operation *get (int type); CSMDoc::OperationHolder *get (int type);
///< Returns a 0-pointer, if operation hasn't been used yet. ///< Returns a 0-pointer, if operation hasn't been used yet.
const CSMDoc::Operation *get (int type) const; const CSMDoc::OperationHolder *get (int type) const;
///< Returns a 0-pointer, if operation hasn't been used yet. ///< Returns a 0-pointer, if operation hasn't been used yet.
public: public:

@ -21,4 +21,4 @@ namespace CSMWorld
}; };
} }
#endif #endif

@ -28,4 +28,4 @@ int CSMWorld::CollectionBase::findColumnIndex (Columns::ColumnId id) const
throw std::logic_error ("invalid column index"); throw std::logic_error ("invalid column index");
return index; return index;
} }

@ -264,4 +264,4 @@ void CSMWorld::CommandDispatcher::executeExtendedRevert()
if (mExtendedTypes.size()>1) if (mExtendedTypes.size()>1)
mDocument.getUndoStack().endMacro(); mDocument.getUndoStack().endMacro();
} }

@ -22,7 +22,7 @@ namespace CSMWorld
{ {
class IdTable; class IdTable;
class IdTable; class IdTable;
class RecordBase; struct RecordBase;
class NestedTableWrapperBase; class NestedTableWrapperBase;
class ModifyCommand : public QUndoCommand class ModifyCommand : public QUndoCommand

@ -745,7 +745,7 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages)
if (index!=-1 && !mBase) if (index!=-1 && !mBase)
mLand.getRecord (index).mModified.mLand->loadData ( mLand.getRecord (index).mModified.mLand->loadData (
ESM::Land::DATA_VHGT | ESM::Land::DATA_VNML | ESM::Land::DATA_VCLR | ESM::Land::DATA_VHGT | ESM::Land::DATA_VNML | ESM::Land::DATA_VCLR |
ESM::Land::DATA_VTEX); ESM::Land::DATA_VTEX | ESM::Land::DATA_WNAM);
break; break;
} }

@ -10,7 +10,7 @@
/*! \brief /*! \brief
* Clas for holding the model. Uses typical qt table abstraction/interface for granting access to the individiual fields of the records, * Clas for holding the model. Uses typical qt table abstraction/interface for granting access to the individiual fields of the records,
* Some records are holding nested data (for instance inventory list of the npc). In casses like this, table model offers interface * Some records are holding nested data (for instance inventory list of the npc). In casses like this, table model offers interface
* to access nested data in the qt way that is specify parent. Since some of those nested data require multiple columns to * to access nested data in the qt way that is specify parent. Since some of those nested data require multiple columns to
* represent informations, single int (default way to index model in the qmodelindex) is not sufficiant. Therefore tablemodelindex class * represent informations, single int (default way to index model in the qmodelindex) is not sufficiant. Therefore tablemodelindex class
* can hold two ints for the sake of indexing two dimensions of the table. This model does not support multiple levels of the nested * can hold two ints for the sake of indexing two dimensions of the table. This model does not support multiple levels of the nested
* data. Vast majority of methods makes sense only for the top level data. * data. Vast majority of methods makes sense only for the top level data.
@ -19,7 +19,7 @@
namespace CSMWorld namespace CSMWorld
{ {
class CollectionBase; class CollectionBase;
class RecordBase; struct RecordBase;
class NestedTableWrapperBase; class NestedTableWrapperBase;
class IdTable : public IdTableBase class IdTable : public IdTableBase

@ -6,4 +6,4 @@ CSMWorld::IdTableBase::IdTableBase (unsigned int features) : mFeatures (features
unsigned int CSMWorld::IdTableBase::getFeatures() const unsigned int CSMWorld::IdTableBase::getFeatures() const
{ {
return mFeatures; return mFeatures;
} }

@ -26,7 +26,7 @@ void CSMWorld::InfoCollection::load (const Info& record, bool base)
if (!record2.get().mPrev.empty()) if (!record2.get().mPrev.empty())
{ {
index = getIndex (record2.get().mPrev, topic); index = getInfoIndex (record2.get().mPrev, topic);
if (index!=-1) if (index!=-1)
++index; ++index;
@ -34,7 +34,7 @@ void CSMWorld::InfoCollection::load (const Info& record, bool base)
if (index==-1 && !record2.get().mNext.empty()) if (index==-1 && !record2.get().mNext.empty())
{ {
index = getIndex (record2.get().mNext, topic); index = getInfoIndex (record2.get().mNext, topic);
} }
if (index==-1) if (index==-1)
@ -60,7 +60,7 @@ void CSMWorld::InfoCollection::load (const Info& record, bool base)
} }
} }
int CSMWorld::InfoCollection::getIndex (const std::string& id, const std::string& topic) const int CSMWorld::InfoCollection::getInfoIndex (const std::string& id, const std::string& topic) const
{ {
std::string fullId = Misc::StringUtils::lowerCase (topic) + "#" + id; std::string fullId = Misc::StringUtils::lowerCase (topic) + "#" + id;

@ -6,7 +6,7 @@
namespace ESM namespace ESM
{ {
class Dialogue; struct Dialogue;
} }
namespace CSMWorld namespace CSMWorld
@ -22,7 +22,7 @@ namespace CSMWorld
void load (const Info& record, bool base); void load (const Info& record, bool base);
int getIndex (const std::string& id, const std::string& topic) const; int getInfoIndex (const std::string& id, const std::string& topic) const;
///< Return index for record \a id or -1 (if not present; deleted records are considered) ///< Return index for record \a id or -1 (if not present; deleted records are considered)
/// ///
/// \param id info ID without topic prefix /// \param id info ID without topic prefix
@ -47,4 +47,4 @@ namespace CSMWorld
}; };
} }
#endif #endif

@ -26,4 +26,4 @@ namespace CSMWorld
}; };
} }
#endif #endif

@ -18,4 +18,4 @@ bool CSMWorld::RecordBase::isErased() const
bool CSMWorld::RecordBase::isModified() const bool CSMWorld::RecordBase::isModified() const
{ {
return mState==State_Modified || mState==State_ModifiedOnly; return mState==State_Modified || mState==State_ModifiedOnly;
} }

@ -22,6 +22,8 @@ namespace CSMWorld
virtual RecordBase *clone() const = 0; virtual RecordBase *clone() const = 0;
virtual RecordBase *modifiedCopy() const = 0;
virtual void assign (const RecordBase& record) = 0; virtual void assign (const RecordBase& record) = 0;
///< Will throw an exception if the types don't match. ///< Will throw an exception if the types don't match.
@ -38,8 +40,15 @@ namespace CSMWorld
ESXRecordT mBase; ESXRecordT mBase;
ESXRecordT mModified; ESXRecordT mModified;
Record();
Record(State state,
const ESXRecordT *base = 0, const ESXRecordT *modified = 0);
virtual RecordBase *clone() const; virtual RecordBase *clone() const;
virtual RecordBase *modifiedCopy() const;
virtual void assign (const RecordBase& record); virtual void assign (const RecordBase& record);
const ESXRecordT& get() const; const ESXRecordT& get() const;
@ -58,6 +67,29 @@ namespace CSMWorld
///< Merge modified into base. ///< Merge modified into base.
}; };
template <typename ESXRecordT>
Record<ESXRecordT>::Record()
: mBase(), mModified()
{ }
template <typename ESXRecordT>
Record<ESXRecordT>::Record(State state, const ESXRecordT *base, const ESXRecordT *modified)
{
if(base)
mBase = *base;
if(modified)
mModified = *modified;
this->mState = state;
}
template <typename ESXRecordT>
RecordBase *Record<ESXRecordT>::modifiedCopy() const
{
return new Record<ESXRecordT> (State_ModifiedOnly, 0, &(this->get()));
}
template <typename ESXRecordT> template <typename ESXRecordT>
RecordBase *Record<ESXRecordT>::clone() const RecordBase *Record<ESXRecordT>::clone() const
{ {

@ -5,4 +5,4 @@ CSMWorld::CellRef::CellRef()
{ {
mRefNum.mIndex = 0; mRefNum.mIndex = 0;
mRefNum.mContentFile = 0; mRefNum.mContentFile = 0;
} }

@ -5,8 +5,6 @@
namespace CSMWorld namespace CSMWorld
{ {
class Cell;
/// \brief Wrapper for CellRef sub record /// \brief Wrapper for CellRef sub record
struct CellRef : public ESM::CellRef struct CellRef : public ESM::CellRef
{ {

@ -12,7 +12,7 @@
namespace CSMWorld namespace CSMWorld
{ {
struct Cell; struct Cell;
struct UniversalId; class UniversalId;
/// \brief References in cells /// \brief References in cells
class RefCollection : public Collection<CellRef> class RefCollection : public Collection<CellRef>

@ -18,7 +18,7 @@ namespace CSMWorld
{ {
class RefIdColumn; class RefIdColumn;
class RefIdData; class RefIdData;
class RecordBase; struct RecordBase;
class NestedTableWrapperBase; class NestedTableWrapperBase;
class HelperBase; class HelperBase;

@ -160,10 +160,16 @@ namespace CSMWorld
Record<RecordT>& record = static_cast<Record<RecordT>&> ( Record<RecordT>& record = static_cast<Record<RecordT>&> (
data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType()))); data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType())));
RecordT record2 = record.get();
if (column==mModel.mModel) if (column==mModel.mModel)
record.get().mModel = value.toString().toUtf8().constData(); record2.mModel = value.toString().toUtf8().constData();
else else
{
BaseRefIdAdapter<RecordT>::setData (column, data, index, value); BaseRefIdAdapter<RecordT>::setData (column, data, index, value);
return;
}
record.setModified(record2);
} }
struct NameColumns : public ModelColumns struct NameColumns : public ModelColumns
@ -220,12 +226,18 @@ namespace CSMWorld
Record<RecordT>& record = static_cast<Record<RecordT>&> ( Record<RecordT>& record = static_cast<Record<RecordT>&> (
data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType()))); data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType())));
RecordT record2 = record.get();
if (column==mName.mName) if (column==mName.mName)
record.get().mName = value.toString().toUtf8().constData(); record2.mName = value.toString().toUtf8().constData();
else if (column==mName.mScript) else if (column==mName.mScript)
record.get().mScript = value.toString().toUtf8().constData(); record2.mScript = value.toString().toUtf8().constData();
else else
{
ModelRefIdAdapter<RecordT>::setData (column, data, index, value); ModelRefIdAdapter<RecordT>::setData (column, data, index, value);
return;
}
record.setModified(record2);
} }
struct InventoryColumns : public NameColumns struct InventoryColumns : public NameColumns
@ -287,14 +299,20 @@ namespace CSMWorld
Record<RecordT>& record = static_cast<Record<RecordT>&> ( Record<RecordT>& record = static_cast<Record<RecordT>&> (
data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType()))); data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType())));
RecordT record2 = record.get();
if (column==mInventory.mIcon) if (column==mInventory.mIcon)
record.get().mIcon = value.toString().toUtf8().constData(); record2.mIcon = value.toString().toUtf8().constData();
else if (column==mInventory.mWeight) else if (column==mInventory.mWeight)
record.get().mData.mWeight = value.toFloat(); record2.mData.mWeight = value.toFloat();
else if (column==mInventory.mValue) else if (column==mInventory.mValue)
record.get().mData.mValue = value.toInt(); record2.mData.mValue = value.toInt();
else else
{
NameRefIdAdapter<RecordT>::setData (column, data, index, value); NameRefIdAdapter<RecordT>::setData (column, data, index, value);
return;
}
record.setModified(record2);
} }
class PotionRefIdAdapter : public InventoryRefIdAdapter<ESM::Potion> class PotionRefIdAdapter : public InventoryRefIdAdapter<ESM::Potion>
@ -368,12 +386,18 @@ namespace CSMWorld
Record<RecordT>& record = static_cast<Record<RecordT>&> ( Record<RecordT>& record = static_cast<Record<RecordT>&> (
data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType()))); data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType())));
RecordT record2 = record.get();
if (column==mEnchantable.mEnchantment) if (column==mEnchantable.mEnchantment)
record.get().mEnchant = value.toString().toUtf8().constData(); record2.mEnchant = value.toString().toUtf8().constData();
else if (column==mEnchantable.mEnchantmentPoints) else if (column==mEnchantable.mEnchantmentPoints)
record.get().mData.mEnchant = value.toInt(); record2.mData.mEnchant = value.toInt();
else else
{
InventoryRefIdAdapter<RecordT>::setData (column, data, index, value); InventoryRefIdAdapter<RecordT>::setData (column, data, index, value);
return;
}
record.setModified(record2);
} }
struct ToolColumns : public InventoryColumns struct ToolColumns : public InventoryColumns
@ -430,12 +454,18 @@ namespace CSMWorld
Record<RecordT>& record = static_cast<Record<RecordT>&> ( Record<RecordT>& record = static_cast<Record<RecordT>&> (
data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType()))); data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType())));
RecordT record2 = record.get();
if (column==mTools.mQuality) if (column==mTools.mQuality)
record.get().mData.mQuality = value.toFloat(); record2.mData.mQuality = value.toFloat();
else if (column==mTools.mUses) else if (column==mTools.mUses)
record.get().mData.mUses = value.toInt(); record2.mData.mUses = value.toInt();
else else
{
InventoryRefIdAdapter<RecordT>::setData (column, data, index, value); InventoryRefIdAdapter<RecordT>::setData (column, data, index, value);
return;
}
record.setModified(record2);
} }
struct ActorColumns : public NameColumns struct ActorColumns : public NameColumns
@ -527,16 +557,17 @@ namespace CSMWorld
Record<RecordT>& record = static_cast<Record<RecordT>&> ( Record<RecordT>& record = static_cast<Record<RecordT>&> (
data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType()))); data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType())));
RecordT record2 = record.get();
if (column==mActors.mHasAi) if (column==mActors.mHasAi)
record.get().mHasAI = value.toInt(); record2.mHasAI = value.toInt();
else if (column==mActors.mHello) else if (column==mActors.mHello)
record.get().mAiData.mHello = value.toInt(); record2.mAiData.mHello = value.toInt();
else if (column==mActors.mFlee) else if (column==mActors.mFlee)
record.get().mAiData.mFlee = value.toInt(); record2.mAiData.mFlee = value.toInt();
else if (column==mActors.mFight) else if (column==mActors.mFight)
record.get().mAiData.mFight = value.toInt(); record2.mAiData.mFight = value.toInt();
else if (column==mActors.mAlarm) else if (column==mActors.mAlarm)
record.get().mAiData.mAlarm = value.toInt(); record2.mAiData.mAlarm = value.toInt();
else else
{ {
typename std::map<const RefIdColumn *, unsigned int>::const_iterator iter = typename std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
@ -544,13 +575,18 @@ namespace CSMWorld
if (iter!=mActors.mServices.end()) if (iter!=mActors.mServices.end())
{ {
if (value.toInt()!=0) if (value.toInt()!=0)
record.get().mAiData.mServices |= iter->second; record2.mAiData.mServices |= iter->second;
else else
record.get().mAiData.mServices &= ~iter->second; record2.mAiData.mServices &= ~iter->second;
} }
else else
{
NameRefIdAdapter<RecordT>::setData (column, data, index, value); NameRefIdAdapter<RecordT>::setData (column, data, index, value);
return;
}
} }
record.setModified(record2);
} }
class ApparatusRefIdAdapter : public InventoryRefIdAdapter<ESM::Apparatus> class ApparatusRefIdAdapter : public InventoryRefIdAdapter<ESM::Apparatus>

@ -522,8 +522,7 @@ void CSMWorld::RefIdCollection::cloneRecord(const std::string& origin,
const std::string& destination, const std::string& destination,
const CSMWorld::UniversalId::Type type) const CSMWorld::UniversalId::Type type)
{ {
std::auto_ptr<RecordBase> newRecord(mData.getRecord(mData.searchId(origin)).clone()); std::auto_ptr<RecordBase> newRecord(mData.getRecord(mData.searchId(origin)).modifiedCopy());
newRecord->mState = RecordBase::State_ModifiedOnly;
mAdapters.find(type)->second->setId(*newRecord, destination); mAdapters.find(type)->second->setId(*newRecord, destination);
mData.insertRecord(*newRecord, type, destination); mData.insertRecord(*newRecord, type, destination);
} }

@ -503,4 +503,4 @@ void CSMWorld::RegionMap::cellsChanged (const QModelIndex& topLeft, const QModel
// columns we are interested in. If not we can exit the function here and avoid all updating. // columns we are interested in. If not we can exit the function here and avoid all updating.
addCells (topLeft.row(), bottomRight.row()); addCells (topLeft.row(), bottomRight.row());
} }

@ -105,4 +105,4 @@ int CSMWorld::Resources::searchId (const std::string& id) const
CSMWorld::UniversalId::Type CSMWorld::Resources::getType() const CSMWorld::UniversalId::Type CSMWorld::Resources::getType() const
{ {
return mType; return mType;
} }

@ -30,4 +30,4 @@ const CSMWorld::Resources& CSMWorld::ResourcesManager::get (UniversalId::Type ty
throw std::logic_error ("Unknown resource type"); throw std::logic_error ("Unknown resource type");
return iter->second; return iter->second;
} }

@ -25,4 +25,4 @@ namespace CSMWorld
}; };
} }
#endif #endif

@ -143,4 +143,4 @@ std::pair<CSMWorld::UniversalId, std::string> CSMWorld::ResourceTable::view (int
bool CSMWorld::ResourceTable::isDeleted (const std::string& id) const bool CSMWorld::ResourceTable::isDeleted (const std::string& id) const
{ {
return false; return false;
} }

@ -22,4 +22,4 @@ CSMWorld::Scope CSMWorld::getScopeFromId (const std::string& id)
return Scope_Session; return Scope_Session;
return Scope_Content; return Scope_Content;
} }

@ -120,4 +120,4 @@ void CSMWorld::ScriptContext::clear()
mIds.clear(); mIds.clear();
mIdsUpdated = false; mIdsUpdated = false;
mLocals.clear(); mLocals.clear();
} }

@ -90,4 +90,4 @@ void CSVDoc::GlobalDebugProfileMenu::profileChanged (const QModelIndex& topLeft,
void CSVDoc::GlobalDebugProfileMenu::actionTriggered (QAction *action) void CSVDoc::GlobalDebugProfileMenu::actionTriggered (QAction *action)
{ {
emit triggered (std::string (action->text().toUtf8().constData())); emit triggered (std::string (action->text().toUtf8().constData()));
} }

@ -17,4 +17,4 @@ CSVDoc::RunLogSubView::RunLogSubView (const CSMWorld::UniversalId& id,
void CSVDoc::RunLogSubView::setEditLock (bool locked) void CSVDoc::RunLogSubView::setEditLock (bool locked)
{ {
// ignored since this SubView does not have editing // ignored since this SubView does not have editing
} }

@ -35,4 +35,4 @@ CSVDoc::SubView *CSVDoc::SubViewFactoryManager::makeSubView (const CSMWorld::Uni
throw std::runtime_error ("Failed to create a sub view for: " + id.toString()); throw std::runtime_error ("Failed to create a sub view for: " + id.toString());
return iter->second->makeSubView (id, document); return iter->second->makeSubView (id, document);
} }

@ -48,4 +48,4 @@ namespace CSVDoc
} }
} }
#endif #endif

@ -193,4 +193,4 @@ std::string CSVFilter::EditWidget::generateFilter (std::pair< std::string, std::
} }
return ss.str(); return ss.str();
} }

@ -43,4 +43,4 @@ namespace CSVFilter
} }
#endif #endif

@ -16,4 +16,4 @@ unsigned int CSVRender::EditMode::getInteractionMask() const
void CSVRender::EditMode::activate (CSVWidget::SceneToolbar *toolbar) void CSVRender::EditMode::activate (CSVWidget::SceneToolbar *toolbar)
{ {
mWorldspaceWidget->setInteractionMask (mMask); mWorldspaceWidget->setInteractionMask (mMask);
} }

@ -1,4 +1,4 @@
#include "lighting.hpp" #include "lighting.hpp"
CSVRender::Lighting::~Lighting() {} CSVRender::Lighting::~Lighting() {}

@ -27,4 +27,4 @@ void CSVRender::LightingBright::deactivate()
} }
} }
void CSVRender::LightingBright::setDefaultAmbient (const Ogre::ColourValue& colour) {} void CSVRender::LightingBright::setDefaultAmbient (const Ogre::ColourValue& colour) {}

@ -33,4 +33,4 @@ void CSVRender::LightingDay::deactivate()
void CSVRender::LightingDay::setDefaultAmbient (const Ogre::ColourValue& colour) void CSVRender::LightingDay::setDefaultAmbient (const Ogre::ColourValue& colour)
{ {
mSceneManager->setAmbientLight (colour); mSceneManager->setAmbientLight (colour);
} }

@ -33,4 +33,4 @@ void CSVRender::LightingNight::deactivate()
void CSVRender::LightingNight::setDefaultAmbient (const Ogre::ColourValue& colour) void CSVRender::LightingNight::setDefaultAmbient (const Ogre::ColourValue& colour)
{ {
mSceneManager->setAmbientLight (colour); mSceneManager->setAmbientLight (colour);
} }

@ -97,4 +97,4 @@ bool CSVRender::NavigationOrbit::handleRollKeys (int delta)
{ {
mCamera->roll (Ogre::Degree (getFactor (false) * delta)); mCamera->roll (Ogre::Degree (getFactor (false) * delta));
return true; return true;
} }

@ -17,7 +17,7 @@ namespace Ogre
namespace CSMWorld namespace CSMWorld
{ {
class Data; class Data;
class CellRef; struct CellRef;
} }
namespace CSVWorld namespace CSVWorld

@ -30,7 +30,7 @@ void CSVTools::ReportTable::contextMenuEvent (QContextMenuEvent *event)
void CSVTools::ReportTable::mouseMoveEvent (QMouseEvent *event) void CSVTools::ReportTable::mouseMoveEvent (QMouseEvent *event)
{ {
if (event->buttons() & Qt::LeftButton) if (event->buttons() & Qt::LeftButton)
startDrag (*this); startDragFromTable (*this);
} }
void CSVTools::ReportTable::mouseDoubleClickEvent (QMouseEvent *event) void CSVTools::ReportTable::mouseDoubleClickEvent (QMouseEvent *event)
@ -133,4 +133,4 @@ void CSVTools::ReportTable::removeSelection()
mModel->removeRows (iter->row(), 1); mModel->removeRows (iter->row(), 1);
selectionModel()->clear(); selectionModel()->clear();
} }

@ -11,4 +11,4 @@ void CSVTools::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
new CSVDoc::SubViewFactory<ReportSubView>); new CSVDoc::SubViewFactory<ReportSubView>);
manager.add (CSMWorld::UniversalId::Type_LoadErrorLog, manager.add (CSMWorld::UniversalId::Type_LoadErrorLog,
new CSVDoc::SubViewFactory<ReportSubView>); new CSVDoc::SubViewFactory<ReportSubView>);
} }

@ -106,4 +106,4 @@ CSVWidget::PushButton::Type CSVWidget::PushButton::getType() const
void CSVWidget::PushButton::checkedStateChanged (bool checked) void CSVWidget::PushButton::checkedStateChanged (bool checked)
{ {
setExtendedToolTip(); setExtendedToolTip();
} }

@ -100,4 +100,4 @@ void CSVWidget::SceneToolMode::selected()
emit modeChanged (iter->second); emit modeChanged (iter->second);
} }
} }

@ -148,4 +148,4 @@ void CSVWidget::SceneToolRun::clicked (const QModelIndex& index)
removeProfile (*iter); removeProfile (*iter);
updatePanel(); updatePanel();
} }
} }

@ -19,4 +19,4 @@ CSVWorld::Creator *CSVWorld::NullCreatorFactory::makeCreator (CSMWorld::Data& da
QUndoStack& undoStack, const CSMWorld::UniversalId& id) const QUndoStack& undoStack, const CSMWorld::UniversalId& id) const
{ {
return 0; return 0;
} }

@ -101,4 +101,4 @@ namespace CSVWorld
} }
} }
#endif #endif

@ -32,4 +32,4 @@ CSVWorld::Creator *CSVWorld::JournalCreatorFactory::makeCreator (CSMWorld::Data&
QUndoStack& undoStack, const CSMWorld::UniversalId& id) const QUndoStack& undoStack, const CSMWorld::UniversalId& id) const
{ {
return new DialogueCreator (data, undoStack, id, ESM::Dialogue::Journal); return new DialogueCreator (data, undoStack, id, ESM::Dialogue::Journal);
} }

@ -2,6 +2,7 @@
#include <utility> #include <utility>
#include <memory> #include <memory>
#include <stdexcept>
#include <QGridLayout> #include <QGridLayout>
#include <QLabel> #include <QLabel>
@ -42,8 +43,12 @@ QAbstractItemDelegate(parent),
mTable(table) mTable(table)
{} {}
void CSVWorld::NotEditableSubDelegate::setEditorData (QLabel* editor, const QModelIndex& index) const void CSVWorld::NotEditableSubDelegate::setEditorData (QWidget* editor, const QModelIndex& index) const
{ {
QLabel* label = qobject_cast<QLabel*>(editor);
if(!label)
return;
QVariant v = index.data(Qt::EditRole); QVariant v = index.data(Qt::EditRole);
if (!v.isValid()) if (!v.isValid())
{ {
@ -56,16 +61,17 @@ void CSVWorld::NotEditableSubDelegate::setEditorData (QLabel* editor, const QMod
if (QVariant::String == v.type()) if (QVariant::String == v.type())
{ {
editor->setText(v.toString()); label->setText(v.toString());
} else //else we are facing enums }
else //else we are facing enums
{ {
int data = v.toInt(); int data = v.toInt();
std::vector<std::string> enumNames (CSMWorld::Columns::getEnums (static_cast<CSMWorld::Columns::ColumnId> (mTable->getColumnId (index.column())))); std::vector<std::string> enumNames (CSMWorld::Columns::getEnums (static_cast<CSMWorld::Columns::ColumnId> (mTable->getColumnId (index.column()))));
editor->setText(QString::fromUtf8(enumNames.at(data).c_str())); label->setText(QString::fromUtf8(enumNames.at(data).c_str()));
} }
} }
void CSVWorld::NotEditableSubDelegate::setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const void CSVWorld::NotEditableSubDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
{ {
//not editable widgets will not save model data //not editable widgets will not save model data
} }
@ -82,8 +88,7 @@ QSize CSVWorld::NotEditableSubDelegate::sizeHint (const QStyleOptionViewItem& op
QWidget* CSVWorld::NotEditableSubDelegate::createEditor (QWidget *parent, QWidget* CSVWorld::NotEditableSubDelegate::createEditor (QWidget *parent,
const QStyleOptionViewItem& option, const QStyleOptionViewItem& option,
const QModelIndex& index, const QModelIndex& index) const
CSMWorld::ColumnBase::Display display) const
{ {
return new QLabel(parent); return new QLabel(parent);
} }
@ -226,6 +231,11 @@ void CSVWorld::DialogueDelegateDispatcher::setEditorData (QWidget* editor, const
} }
} }
void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
{
setModelData(editor, model, index, CSMWorld::ColumnBase::Display_None);
}
void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const
{ {
std::map<int, CommandDelegate*>::const_iterator delegateIt(mDelegates.find(display)); std::map<int, CommandDelegate*>::const_iterator delegateIt(mDelegates.find(display));
@ -260,7 +270,7 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase::
QWidget* editor = NULL; QWidget* editor = NULL;
if (! (mTable->flags (index) & Qt::ItemIsEditable)) if (! (mTable->flags (index) & Qt::ItemIsEditable))
{ {
return mNotEditableDelegate.createEditor(qobject_cast<QWidget*>(mParent), QStyleOptionViewItem(), index, display); return mNotEditableDelegate.createEditor(qobject_cast<QWidget*>(mParent), QStyleOptionViewItem(), index);
} }
std::map<int, CommandDelegate*>::iterator delegateIt(mDelegates.find(display)); std::map<int, CommandDelegate*>::iterator delegateIt(mDelegates.find(display));
@ -271,6 +281,8 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase::
DialogueDelegateDispatcherProxy* proxy = new DialogueDelegateDispatcherProxy(editor, display); DialogueDelegateDispatcherProxy* proxy = new DialogueDelegateDispatcherProxy(editor, display);
// NOTE: For each entry in CSVWorld::CommandDelegate::createEditor() a corresponding entry
// is required here
if (qobject_cast<DropLineEdit*>(editor)) if (qobject_cast<DropLineEdit*>(editor))
{ {
connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited())); connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited()));
@ -295,10 +307,12 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase::
{ {
connect(editor, SIGNAL(currentIndexChanged (int)), proxy, SLOT(editorDataCommited())); connect(editor, SIGNAL(currentIndexChanged (int)), proxy, SLOT(editorDataCommited()));
} }
else if (qobject_cast<QAbstractSpinBox*>(editor)) else if (qobject_cast<QAbstractSpinBox*>(editor) || qobject_cast<QLineEdit*>(editor))
{ {
connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited())); connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited()));
} }
else // throw an exception because this is a coding error
throw std::logic_error ("Dialogue editor type missing");
connect(proxy, SIGNAL(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display)), connect(proxy, SIGNAL(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display)),
this, SLOT(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display))); this, SLOT(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display)));

@ -42,12 +42,9 @@ namespace CSVWorld
NotEditableSubDelegate(const CSMWorld::IdTable* table, NotEditableSubDelegate(const CSMWorld::IdTable* table,
QObject * parent = 0); QObject * parent = 0);
virtual void setEditorData (QLabel* editor, virtual void setEditorData (QWidget* editor, const QModelIndex& index) const;
const QModelIndex& index) const;
virtual void setModelData (QWidget* editor, QAbstractItemModel* model, virtual void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const;
const QModelIndex& index,
CSMWorld::ColumnBase::Display display) const;
virtual void paint (QPainter* painter, virtual void paint (QPainter* painter,
const QStyleOptionViewItem& option, const QStyleOptionViewItem& option,
@ -60,8 +57,7 @@ namespace CSVWorld
virtual QWidget *createEditor (QWidget *parent, virtual QWidget *createEditor (QWidget *parent,
const QStyleOptionViewItem& option, const QStyleOptionViewItem& option,
const QModelIndex& index, const QModelIndex& index) const;
CSMWorld::ColumnBase::Display display = CSMWorld::ColumnBase::Display_None) const;
}; };
//this can't be nested into the DialogueDelegateDispatcher, because it needs to emit signals //this can't be nested into the DialogueDelegateDispatcher, because it needs to emit signals
@ -136,10 +132,9 @@ namespace CSVWorld
virtual void setEditorData (QWidget* editor, virtual void setEditorData (QWidget* editor,
const QModelIndex& index) const; const QModelIndex& index) const;
virtual void setModelData (QWidget* editor, virtual void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const;
QAbstractItemModel* model,
const QModelIndex& index, virtual void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const;
CSMWorld::ColumnBase::Display display) const;
virtual void paint (QPainter* painter, virtual void paint (QPainter* painter,
const QStyleOptionViewItem& option, const QStyleOptionViewItem& option,

@ -3,7 +3,7 @@
#include "../../model/world/tablemimedata.hpp" #include "../../model/world/tablemimedata.hpp"
#include "dragrecordtable.hpp" #include "dragrecordtable.hpp"
void CSVWorld::DragRecordTable::startDrag (const CSVWorld::DragRecordTable& table) void CSVWorld::DragRecordTable::startDragFromTable (const CSVWorld::DragRecordTable& table)
{ {
CSMWorld::TableMimeData* mime = new CSMWorld::TableMimeData (table.getDraggedRecords(), mDocument); CSMWorld::TableMimeData* mime = new CSMWorld::TableMimeData (table.getDraggedRecords(), mDocument);

@ -33,7 +33,7 @@ namespace CSVWorld
void setEditLock(bool locked); void setEditLock(bool locked);
protected: protected:
void startDrag(const DragRecordTable& table); void startDragFromTable(const DragRecordTable& table);
void dragEnterEvent(QDragEnterEvent *event); void dragEnterEvent(QDragEnterEvent *event);

@ -46,7 +46,6 @@ QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent,
const QModelIndex& index) const const QModelIndex& index) const
{ {
return createEditor(parent, option, index, CSMWorld::ColumnBase::Display_None); return createEditor(parent, option, index, CSMWorld::ColumnBase::Display_None);
//overloading virtual functions is HARD
} }
QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem& option, QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem& option,

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save