mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-31 19:45:32 +00:00
Merge branch 'master' of https://github.com/zinnschlag/openmw
This commit is contained in:
commit
089a1d48c1
629 changed files with 37240 additions and 26089 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -17,3 +17,7 @@ data
|
|||
CMakeLists.txt.user
|
||||
*.swp
|
||||
*.swo
|
||||
*.kate-swp
|
||||
.cproject
|
||||
.project
|
||||
.settings/
|
||||
|
|
40
.travis.yml
Normal file
40
.travis.yml
Normal file
|
@ -0,0 +1,40 @@
|
|||
language: cpp
|
||||
compiler:
|
||||
- gcc
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- next
|
||||
before_install:
|
||||
- pwd
|
||||
- git submodule update --init --recursive
|
||||
- echo "yes" | sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu `lsb_release -sc` main universe restricted multiverse"
|
||||
- echo "yes" | sudo apt-add-repository ppa:openmw/deps
|
||||
- sudo apt-get update -qq
|
||||
- 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 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 libois-dev libbullet-dev libogre-static-dev libmygui-static-dev
|
||||
- sudo mkdir /usr/src/gtest/build
|
||||
- cd /usr/src/gtest/build
|
||||
- sudo cmake .. -DBUILD_SHARED_LIBS=1
|
||||
- sudo make -j4
|
||||
- sudo ln -s /usr/src/gtest/build/libgtest.so /usr/lib/libgtest.so
|
||||
- sudo ln -s /usr/src/gtest/build/libgtest_main.so /usr/lib/libgtest_main.so
|
||||
before_script:
|
||||
- cd -
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake .. -DOGRE_STATIC=1 -DMYGUI_STATIC=1 -DBUILD_WITH_CODE_COVERAGE=1 -DBUILD_UNITTESTS=1
|
||||
script:
|
||||
- make -j4
|
||||
after_script:
|
||||
- ./openmw_test_suite
|
||||
notifications:
|
||||
recipients:
|
||||
- lgromanowski+travis.ci@gmail.com
|
||||
email:
|
||||
on_success: change
|
||||
on_failure: always
|
|
@ -15,7 +15,7 @@ include (OpenMWMacros)
|
|||
# Version
|
||||
|
||||
set (OPENMW_VERSION_MAJOR 0)
|
||||
set (OPENMW_VERSION_MINOR 22)
|
||||
set (OPENMW_VERSION_MINOR 23)
|
||||
set (OPENMW_VERSION_RELEASE 0)
|
||||
|
||||
set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
|
||||
|
@ -75,6 +75,7 @@ set(LIBDIR ${CMAKE_SOURCE_DIR}/libs)
|
|||
set(OENGINE_OGRE
|
||||
${LIBDIR}/openengine/ogre/renderer.cpp
|
||||
${LIBDIR}/openengine/ogre/fader.cpp
|
||||
${LIBDIR}/openengine/ogre/particles.cpp
|
||||
${LIBDIR}/openengine/ogre/selectionbuffer.cpp
|
||||
)
|
||||
set(OENGINE_GUI
|
||||
|
@ -180,15 +181,8 @@ if (UNIX AND NOT APPLE)
|
|||
find_package (Threads)
|
||||
endif()
|
||||
|
||||
# find boost without components so we can use Boost_VERSION
|
||||
find_package(Boost REQUIRED)
|
||||
|
||||
set(BOOST_COMPONENTS system filesystem program_options thread date_time)
|
||||
|
||||
if (Boost_VERSION LESS 104900)
|
||||
set(SHINY_USE_WAVE_SYSTEM_INSTALL "TRUE")
|
||||
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} wave)
|
||||
endif()
|
||||
set(BOOST_COMPONENTS system filesystem program_options thread date_time wave)
|
||||
|
||||
IF(BOOST_STATIC)
|
||||
set(Boost_USE_STATIC_LIBS ON)
|
||||
|
@ -654,12 +648,12 @@ endif (APPLE)
|
|||
if (NOT WIN32 AND NOT DPKG_PROGRAM AND NOT APPLE)
|
||||
## Non Debian based Linux building
|
||||
# paths
|
||||
set(BINDIR "${CMAKE_INSTALL_PREFIX}/usr/bin" CACHE PATH "Where to install binaries")
|
||||
set(BINDIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Where to install binaries")
|
||||
set(DATAROOTDIR "${CMAKE_INSTALL_PREFIX}/share" CACHE PATH "Sets the root of data directories to a non-default location")
|
||||
set(DATADIR "${DATAROOTDIR}/openmw" CACHE PATH "Sets the openmw data directories to a non-default location")
|
||||
set(DATADIR "${DATAROOTDIR}/games/openmw" CACHE PATH "Sets the openmw data directories to a non-default location")
|
||||
set(DOCDIR "${DATAROOTDIR}/doc/openmw" CACHE PATH "Sets the doc directory to a non-default location.")
|
||||
set(MANDIR "${DATAROOTDIR}/man" CACHE PATH "Where to install manpages")
|
||||
set(SYSCONFDIR "${CMAKE_INSTALL_PREFIX}/etc/openmw" CACHE PATH "Set config dir")
|
||||
set(SYSCONFDIR "/etc/openmw" CACHE PATH "Set config dir")
|
||||
set(ICONDIR "${DATAROOTDIR}/pixmaps" CACHE PATH "Set icon dir")
|
||||
|
||||
# Install binaries
|
||||
|
@ -683,6 +677,10 @@ if (NOT WIN32 AND NOT DPKG_PROGRAM AND NOT APPLE)
|
|||
# Install icon and .desktop
|
||||
INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/launcher/images/openmw.png" DESTINATION "${ICONDIR}")
|
||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.desktop" DESTINATION "${DATAROOTDIR}/applications")
|
||||
IF(BUILD_OPENCS)
|
||||
INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/opencs/opencs.png" DESTINATION "${ICONDIR}")
|
||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/opencs.desktop" DESTINATION "${DATAROOTDIR}/applications")
|
||||
ENDIF(BUILD_OPENCS)
|
||||
|
||||
# Install global configuration files
|
||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "${SYSCONFDIR}" RENAME "openmw.cfg" )
|
||||
|
|
|
@ -23,8 +23,7 @@ struct ESMData
|
|||
std::string author;
|
||||
std::string description;
|
||||
int version;
|
||||
int type;
|
||||
ESM::ESMReader::MasterList masters;
|
||||
std::vector<ESM::Header::MasterData> masters;
|
||||
|
||||
std::deque<EsmTool::RecordBase *> mRecords;
|
||||
std::map<ESM::Cell *, std::deque<ESM::CellRef> > mCellRefs;
|
||||
|
@ -52,6 +51,7 @@ struct Arguments
|
|||
unsigned int raw_given;
|
||||
unsigned int quiet_given;
|
||||
unsigned int loadcells_given;
|
||||
bool plain_given;
|
||||
|
||||
std::string mode;
|
||||
std::string encoding;
|
||||
|
@ -78,6 +78,9 @@ bool parseOptions (int argc, char** argv, Arguments &info)
|
|||
("type,t", bpo::value< std::vector<std::string> >(),
|
||||
"Show only records of this type (four character record code). May "
|
||||
"be specified multiple times. Only affects dump mode.")
|
||||
("plain,p", "Print contents of dialogs, books and scripts. "
|
||||
"(skipped by default)"
|
||||
"Only affects dump mode.")
|
||||
("quiet,q", "Supress all record information. Useful for speed tests.")
|
||||
("loadcells,C", "Browse through contents of all cells.")
|
||||
|
||||
|
@ -162,6 +165,7 @@ bool parseOptions (int argc, char** argv, Arguments &info)
|
|||
info.raw_given = variables.count ("raw");
|
||||
info.quiet_given = variables.count ("quiet");
|
||||
info.loadcells_given = variables.count ("loadcells");
|
||||
info.plain_given = (variables.count("plain") > 0);
|
||||
|
||||
// Font encoding settings
|
||||
info.encoding = variables["encoding"].as<std::string>();
|
||||
|
@ -228,7 +232,10 @@ void loadCell(ESM::Cell &cell, ESM::ESMReader &esm, Arguments& info)
|
|||
std::cout << " Refnum: " << ref.mRefnum << std::endl;
|
||||
std::cout << " ID: '" << ref.mRefID << "'\n";
|
||||
std::cout << " Owner: '" << ref.mOwner << "'\n";
|
||||
std::cout << " INTV: " << ref.mIntv << " NAM9: " << ref.mIntv << std::endl;
|
||||
std::cout << " Enchantment charge: '" << ref.mEnchantmentCharge << "'\n";
|
||||
std::cout << " Uses/health: '" << ref.mCharge << "'\n";
|
||||
std::cout << " Gold value: '" << ref.mGoldValue << "'\n";
|
||||
std::cout << " Blocked: '" << static_cast<int>(ref.mReferenceBlocked) << "'" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -284,16 +291,13 @@ int load(Arguments& info)
|
|||
info.data.author = esm.getAuthor();
|
||||
info.data.description = esm.getDesc();
|
||||
info.data.masters = esm.getMasters();
|
||||
info.data.version = esm.getVer();
|
||||
info.data.type = esm.getType();
|
||||
|
||||
if (!quiet)
|
||||
{
|
||||
std::cout << "Author: " << esm.getAuthor() << std::endl
|
||||
<< "Description: " << esm.getDesc() << std::endl
|
||||
<< "File format version: " << esm.getFVer() << std::endl
|
||||
<< "Special flag: " << esm.getSpecial() << std::endl;
|
||||
ESM::ESMReader::MasterList m = esm.getMasters();
|
||||
<< "File format version: " << esm.getFVer() << std::endl;
|
||||
std::vector<ESM::Header::MasterData> m = esm.getMasters();
|
||||
if (!m.empty())
|
||||
{
|
||||
std::cout << "Masters:" << std::endl;
|
||||
|
@ -344,6 +348,7 @@ int load(Arguments& info)
|
|||
}
|
||||
record->setId(id);
|
||||
record->setFlags((int) flags);
|
||||
record->setPrintPlain(info.plain_given);
|
||||
record->load(esm);
|
||||
if (!quiet && interested) record->print();
|
||||
|
||||
|
@ -430,9 +435,9 @@ int clone(Arguments& info)
|
|||
esm.setAuthor(info.data.author);
|
||||
esm.setDescription(info.data.description);
|
||||
esm.setVersion(info.data.version);
|
||||
esm.setType(info.data.type);
|
||||
esm.setRecordCount (recordCount);
|
||||
|
||||
for (ESM::ESMReader::MasterList::iterator it = info.data.masters.begin(); it != info.data.masters.end(); ++it)
|
||||
for (std::vector<ESM::Header::MasterData>::iterator it = info.data.masters.begin(); it != info.data.masters.end(); ++it)
|
||||
esm.addMaster(it->name, it->size);
|
||||
|
||||
std::fstream save(info.outname.c_str(), std::fstream::out | std::fstream::binary);
|
||||
|
|
|
@ -627,10 +627,10 @@ std::string bodyPartFlags(int flags)
|
|||
std::string properties = "";
|
||||
if (flags == 0) properties += "[None] ";
|
||||
if (flags & ESM::BodyPart::BPF_Female) properties += "Female ";
|
||||
if (flags & ESM::BodyPart::BPF_Playable) properties += "Playable ";
|
||||
if (flags & ESM::BodyPart::BPF_NotPlayable) properties += "NotPlayable ";
|
||||
int unused = (0xFFFFFFFF ^
|
||||
(ESM::BodyPart::BPF_Female|
|
||||
ESM::BodyPart::BPF_Playable));
|
||||
ESM::BodyPart::BPF_NotPlayable));
|
||||
if (flags & unused) properties += "Invalid ";
|
||||
properties += str(boost::format("(0x%08X)") % flags);
|
||||
return properties;
|
||||
|
|
|
@ -275,7 +275,7 @@ RecordBase::create(ESM::NAME type)
|
|||
}
|
||||
case ESM::REC_LOCK:
|
||||
{
|
||||
record = new EsmTool::Record<ESM::Tool>;
|
||||
record = new EsmTool::Record<ESM::Lockpick>;
|
||||
break;
|
||||
}
|
||||
case ESM::REC_LTEX:
|
||||
|
@ -439,7 +439,7 @@ void Record<ESM::Apparatus>::print()
|
|||
template<>
|
||||
void Record<ESM::BodyPart>::print()
|
||||
{
|
||||
std::cout << " Name: " << mData.mName << std::endl;
|
||||
std::cout << " Race: " << mData.mRace << std::endl;
|
||||
std::cout << " Model: " << mData.mModel << std::endl;
|
||||
std::cout << " Type: " << meshTypeLabel(mData.mData.mType)
|
||||
<< " (" << (int)mData.mData.mType << ")" << std::endl;
|
||||
|
@ -464,12 +464,17 @@ void Record<ESM::Book>::print()
|
|||
std::cout << " IsScroll: " << mData.mData.mIsScroll << std::endl;
|
||||
std::cout << " SkillID: " << mData.mData.mSkillID << std::endl;
|
||||
std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl;
|
||||
std::cout << " Text: [skipped]" << std::endl;
|
||||
// Skip until multi-line fields is controllable by a command line option.
|
||||
// Mildly problematic because there are no parameter to print() currently.
|
||||
// std::cout << "-------------------------------------------" << std::endl;
|
||||
// std::cout << mData.mText << std::endl;
|
||||
// std::cout << "-------------------------------------------" << std::endl;
|
||||
if (mPrintPlain)
|
||||
{
|
||||
std::cout << " Text:" << std::endl;
|
||||
std::cout << "START--------------------------------------" << std::endl;
|
||||
std::cout << mData.mText << std::endl;
|
||||
std::cout << "END----------------------------------------" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << " Text: [skipped]" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
|
@ -679,14 +684,14 @@ void Record<ESM::Faction>::print()
|
|||
std::cout << " Hidden: " << mData.mData.mIsHidden << std::endl;
|
||||
if (mData.mData.mUnknown != -1)
|
||||
std::cout << " Unknown: " << mData.mData.mUnknown << std::endl;
|
||||
std::cout << " Attribute1: " << attributeLabel(mData.mData.mAttribute1)
|
||||
<< " (" << mData.mData.mAttribute1 << ")" << std::endl;
|
||||
std::cout << " Attribute2: " << attributeLabel(mData.mData.mAttribute2)
|
||||
<< " (" << mData.mData.mAttribute2 << ")" << std::endl;
|
||||
std::cout << " Attribute1: " << attributeLabel(mData.mData.mAttribute[0])
|
||||
<< " (" << mData.mData.mAttribute[0] << ")" << std::endl;
|
||||
std::cout << " Attribute2: " << attributeLabel(mData.mData.mAttribute[1])
|
||||
<< " (" << mData.mData.mAttribute[1] << ")" << std::endl;
|
||||
for (int i = 0; i != 6; i++)
|
||||
if (mData.mData.mSkillID[i] != -1)
|
||||
std::cout << " Skill: " << skillLabel(mData.mData.mSkillID[i])
|
||||
<< " (" << mData.mData.mSkillID[i] << ")" << std::endl;
|
||||
if (mData.mData.mSkills[i] != -1)
|
||||
std::cout << " Skill: " << skillLabel(mData.mData.mSkills[i])
|
||||
<< " (" << mData.mData.mSkills[i] << ")" << std::endl;
|
||||
for (int i = 0; i != 10; i++)
|
||||
if (mData.mRanks[i] != "")
|
||||
{
|
||||
|
@ -753,15 +758,6 @@ void Record<ESM::DialInfo>::print()
|
|||
if (mData.mSound != "")
|
||||
std::cout << " Sound File: " << mData.mSound << std::endl;
|
||||
|
||||
if (mData.mResultScript != "")
|
||||
{
|
||||
std::cout << " Result Script: [skipped]" << std::endl;
|
||||
// Skip until multi-line fields is controllable by a command line option.
|
||||
// Mildly problematic because there are no parameter to print() currently.
|
||||
// std::cout << "-------------------------------------------" << std::endl;
|
||||
// std::cout << mData.mResultScript << std::endl;
|
||||
// std::cout << "-------------------------------------------" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << " Quest Status: " << questStatusLabel(mData.mQuestStatus)
|
||||
<< " (" << mData.mQuestStatus << ")" << std::endl;
|
||||
|
@ -771,6 +767,21 @@ void Record<ESM::DialInfo>::print()
|
|||
std::vector<ESM::DialInfo::SelectStruct>::iterator sit;
|
||||
for (sit = mData.mSelects.begin(); sit != mData.mSelects.end(); sit++)
|
||||
std::cout << " Select Rule: " << ruleString(*sit) << std::endl;
|
||||
|
||||
if (mData.mResultScript != "")
|
||||
{
|
||||
if (mPrintPlain)
|
||||
{
|
||||
std::cout << " Result Script:" << std::endl;
|
||||
std::cout << "START--------------------------------------" << std::endl;
|
||||
std::cout << mData.mResultScript << std::endl;
|
||||
std::cout << "END----------------------------------------" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << " Result Script: [skipped]" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
|
@ -864,14 +875,13 @@ void Record<ESM::Light>::print()
|
|||
}
|
||||
|
||||
template<>
|
||||
void Record<ESM::Tool>::print()
|
||||
void Record<ESM::Lockpick>::print()
|
||||
{
|
||||
std::cout << " Name: " << mData.mName << std::endl;
|
||||
std::cout << " Model: " << mData.mModel << std::endl;
|
||||
std::cout << " Icon: " << mData.mIcon << std::endl;
|
||||
if (mData.mScript != "")
|
||||
std::cout << " Script: " << mData.mScript << std::endl;
|
||||
std::cout << " Type: " << mData.mType << std::endl;
|
||||
std::cout << " Weight: " << mData.mData.mWeight << std::endl;
|
||||
std::cout << " Value: " << mData.mData.mValue << std::endl;
|
||||
std::cout << " Quality: " << mData.mData.mQuality << std::endl;
|
||||
|
@ -886,8 +896,6 @@ void Record<ESM::Probe>::print()
|
|||
std::cout << " Icon: " << mData.mIcon << std::endl;
|
||||
if (mData.mScript != "")
|
||||
std::cout << " Script: " << mData.mScript << std::endl;
|
||||
// BUG? No Type Label?
|
||||
std::cout << " Type: " << mData.mType << std::endl;
|
||||
std::cout << " Weight: " << mData.mData.mWeight << std::endl;
|
||||
std::cout << " Value: " << mData.mData.mValue << std::endl;
|
||||
std::cout << " Quality: " << mData.mData.mQuality << std::endl;
|
||||
|
@ -902,7 +910,6 @@ void Record<ESM::Repair>::print()
|
|||
std::cout << " Icon: " << mData.mIcon << std::endl;
|
||||
if (mData.mScript != "")
|
||||
std::cout << " Script: " << mData.mScript << std::endl;
|
||||
std::cout << " Type: " << mData.mType << std::endl;
|
||||
std::cout << " Weight: " << mData.mData.mWeight << std::endl;
|
||||
std::cout << " Value: " << mData.mData.mValue << std::endl;
|
||||
std::cout << " Quality: " << mData.mData.mQuality << std::endl;
|
||||
|
@ -1103,53 +1110,29 @@ void Record<ESM::Pathgrid>::print()
|
|||
template<>
|
||||
void Record<ESM::Race>::print()
|
||||
{
|
||||
static const char *sAttributeNames[8] =
|
||||
{
|
||||
"Strength", "Intelligence", "Willpower", "Agility",
|
||||
"Speed", "Endurance", "Personality", "Luck"
|
||||
};
|
||||
|
||||
std::cout << " Name: " << mData.mName << std::endl;
|
||||
std::cout << " Description: " << mData.mDescription << std::endl;
|
||||
std::cout << " Flags: " << raceFlags(mData.mData.mFlags) << std::endl;
|
||||
|
||||
std::cout << " Male:" << std::endl;
|
||||
std::cout << " Strength: "
|
||||
<< mData.mData.mStrength.mMale << std::endl;
|
||||
std::cout << " Intelligence: "
|
||||
<< mData.mData.mIntelligence.mMale << std::endl;
|
||||
std::cout << " Willpower: "
|
||||
<< mData.mData.mWillpower.mMale << std::endl;
|
||||
std::cout << " Agility: "
|
||||
<< mData.mData.mAgility.mMale << std::endl;
|
||||
std::cout << " Speed: "
|
||||
<< mData.mData.mSpeed.mMale << std::endl;
|
||||
std::cout << " Endurance: "
|
||||
<< mData.mData.mEndurance.mMale << std::endl;
|
||||
std::cout << " Personality: "
|
||||
<< mData.mData.mPersonality.mMale << std::endl;
|
||||
std::cout << " Luck: "
|
||||
<< mData.mData.mLuck.mMale << std::endl;
|
||||
std::cout << " Height: "
|
||||
<< mData.mData.mHeight.mMale << std::endl;
|
||||
std::cout << " Weight: "
|
||||
<< mData.mData.mWeight.mMale << std::endl;
|
||||
for (int i=0; i<2; ++i)
|
||||
{
|
||||
bool male = i==0;
|
||||
|
||||
std::cout << " Female:" << std::endl;
|
||||
std::cout << " Strength: "
|
||||
<< mData.mData.mStrength.mFemale << std::endl;
|
||||
std::cout << " Intelligence: "
|
||||
<< mData.mData.mIntelligence.mFemale << std::endl;
|
||||
std::cout << " Willpower: "
|
||||
<< mData.mData.mWillpower.mFemale << std::endl;
|
||||
std::cout << " Agility: "
|
||||
<< mData.mData.mAgility.mFemale << std::endl;
|
||||
std::cout << " Speed: "
|
||||
<< mData.mData.mSpeed.mFemale << std::endl;
|
||||
std::cout << " Endurance: "
|
||||
<< mData.mData.mEndurance.mFemale << std::endl;
|
||||
std::cout << " Personality: "
|
||||
<< mData.mData.mPersonality.mFemale << std::endl;
|
||||
std::cout << " Luck: "
|
||||
<< mData.mData.mLuck.mFemale << std::endl;
|
||||
std::cout << " Height: "
|
||||
<< mData.mData.mHeight.mFemale << std::endl;
|
||||
std::cout << " Weight: "
|
||||
<< mData.mData.mWeight.mFemale << std::endl;
|
||||
std::cout << (male ? " Male:" : " Female:") << std::endl;
|
||||
|
||||
for (int i=0; i<8; ++i)
|
||||
std::cout << " " << sAttributeNames[i] << ": "
|
||||
<< mData.mData.mAttributeValues[i].getValue (male) << std::endl;
|
||||
|
||||
std::cout << " Height: " << mData.mData.mHeight.getValue (male) << std::endl;
|
||||
std::cout << " Weight: " << mData.mData.mWeight.getValue (male) << std::endl;
|
||||
}
|
||||
|
||||
for (int i = 0; i != 7; i++)
|
||||
// Not all races have 7 skills.
|
||||
|
@ -1199,21 +1182,28 @@ void Record<ESM::Script>::print()
|
|||
std::cout << " Script Data Size: " << mData.mData.mScriptDataSize << std::endl;
|
||||
std::cout << " Table Size: " << mData.mData.mStringTableSize << std::endl;
|
||||
|
||||
std::cout << " Script: [skipped]" << std::endl;
|
||||
// Skip until multi-line fields is controllable by a command line option.
|
||||
// Mildly problematic because there are no parameter to print() currently.
|
||||
// std::cout << "-------------------------------------------" << std::endl;
|
||||
// std::cout << s->scriptText << std::endl;
|
||||
// std::cout << "-------------------------------------------" << std::endl;
|
||||
|
||||
std::vector<std::string>::iterator vit;
|
||||
for (vit = mData.mVarNames.begin(); vit != mData.mVarNames.end(); vit++)
|
||||
std::cout << " Variable: " << *vit << std::endl;
|
||||
|
||||
std::cout << " ByteCode: ";
|
||||
std::vector<char>::iterator cit;
|
||||
std::vector<unsigned char>::iterator cit;
|
||||
for (cit = mData.mScriptData.begin(); cit != mData.mScriptData.end(); cit++)
|
||||
std::cout << boost::format("%02X") % (int)(*cit);
|
||||
std::cout << std::endl;
|
||||
|
||||
if (mPrintPlain)
|
||||
{
|
||||
std::cout << " Script:" << std::endl;
|
||||
std::cout << "START--------------------------------------" << std::endl;
|
||||
std::cout << mData.mScriptText << std::endl;
|
||||
std::cout << "END----------------------------------------" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << " Script: [skipped]" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
|
@ -21,9 +21,10 @@ namespace EsmTool
|
|||
std::string mId;
|
||||
int mFlags;
|
||||
ESM::NAME mType;
|
||||
bool mPrintPlain;
|
||||
|
||||
public:
|
||||
RecordBase () {}
|
||||
RecordBase () { mPrintPlain = false; }
|
||||
virtual ~RecordBase() {}
|
||||
|
||||
const std::string &getId() const {
|
||||
|
@ -46,6 +47,14 @@ namespace EsmTool
|
|||
return mType;
|
||||
}
|
||||
|
||||
bool getPrintPlain() const {
|
||||
return mPrintPlain;
|
||||
}
|
||||
|
||||
void setPrintPlain(bool plain) {
|
||||
mPrintPlain = plain;
|
||||
}
|
||||
|
||||
virtual void load(ESM::ESMReader &esm) = 0;
|
||||
virtual void save(ESM::ESMWriter &esm) = 0;
|
||||
virtual void print() = 0;
|
||||
|
@ -104,7 +113,7 @@ namespace EsmTool
|
|||
template<> void Record<ESM::CreatureLevList>::print();
|
||||
template<> void Record<ESM::ItemLevList>::print();
|
||||
template<> void Record<ESM::Light>::print();
|
||||
template<> void Record<ESM::Tool>::print();
|
||||
template<> void Record<ESM::Lockpick>::print();
|
||||
template<> void Record<ESM::Probe>::print();
|
||||
template<> void Record<ESM::Repair>::print();
|
||||
template<> void Record<ESM::LandTexture>::print();
|
||||
|
|
|
@ -102,3 +102,9 @@ if (BUILD_WITH_CODE_COVERAGE)
|
|||
add_definitions (--coverage)
|
||||
target_link_libraries(omwlauncher gcov)
|
||||
endif()
|
||||
|
||||
# Workaround for binutil => 2.23 problem when linking, should be fixed eventually upstream
|
||||
if (UNIX AND NOT APPLE)
|
||||
target_link_libraries(omwlauncher dl Xt)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
#define MAINDIALOG_H
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
#ifndef Q_MOC_RUN
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
|
||||
#endif
|
||||
#include "settings/gamesettings.hpp"
|
||||
#include "settings/graphicssettings.hpp"
|
||||
#include "settings/launchersettings.hpp"
|
||||
|
|
|
@ -96,15 +96,15 @@ bool GameSettings::readFile(QTextStream &stream)
|
|||
QRegExp keyRe("^([^=]+)\\s*=\\s*(.+)$");
|
||||
|
||||
while (!stream.atEnd()) {
|
||||
QString line = stream.readLine().simplified();
|
||||
QString line = stream.readLine();
|
||||
|
||||
if (line.isEmpty() || line.startsWith("#"))
|
||||
continue;
|
||||
|
||||
if (keyRe.indexIn(line) != -1) {
|
||||
|
||||
QString key = keyRe.cap(1).simplified();
|
||||
QString value = keyRe.cap(2).simplified();
|
||||
QString key = keyRe.cap(1);
|
||||
QString value = keyRe.cap(2);
|
||||
|
||||
// Don't remove existing data entries
|
||||
if (key != QLatin1String("data"))
|
||||
|
|
|
@ -53,7 +53,7 @@ public:
|
|||
QRegExp keyRe("^([^=]+)\\s*=\\s*(.+)$");
|
||||
|
||||
while (!stream.atEnd()) {
|
||||
QString line = stream.readLine().simplified();
|
||||
QString line = stream.readLine();
|
||||
|
||||
if (line.isEmpty() || line.startsWith("#"))
|
||||
continue;
|
||||
|
@ -66,8 +66,8 @@ public:
|
|||
|
||||
if (keyRe.indexIn(line) != -1) {
|
||||
|
||||
QString key = keyRe.cap(1).simplified();
|
||||
QString value = keyRe.cap(2).simplified();
|
||||
QString key = keyRe.cap(1);
|
||||
QString value = keyRe.cap(2);
|
||||
|
||||
if (!sectionPrefix.isEmpty())
|
||||
key.prepend(sectionPrefix);
|
||||
|
|
|
@ -22,3 +22,8 @@ if (BUILD_WITH_CODE_COVERAGE)
|
|||
add_definitions (--coverage)
|
||||
target_link_libraries(mwiniimport gcov)
|
||||
endif()
|
||||
|
||||
if(DPKG_PROGRAM)
|
||||
INSTALL(TARGETS mwiniimport RUNTIME DESTINATION games COMPONENT mwiniimport)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
set (OPENCS_SRC main.cpp)
|
||||
|
||||
opencs_units (. editor)
|
||||
|
@ -24,7 +23,8 @@ opencs_units (model/world
|
|||
|
||||
|
||||
opencs_units_noqt (model/world
|
||||
universalid data record idcollection commands columnbase
|
||||
universalid data record idcollection commands columnbase scriptcontext cell refidcollection
|
||||
refidadapter refiddata refidadapterimp
|
||||
)
|
||||
|
||||
opencs_hdrs_noqt (model/world
|
||||
|
@ -37,7 +37,8 @@ opencs_units (model/tools
|
|||
)
|
||||
|
||||
opencs_units_noqt (model/tools
|
||||
stage verifier mandatoryid
|
||||
stage verifier mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck
|
||||
birthsigncheck spellcheck
|
||||
)
|
||||
|
||||
|
||||
|
@ -56,11 +57,11 @@ opencs_hdrs_noqt (view/doc
|
|||
|
||||
|
||||
opencs_units (view/world
|
||||
table tablesubview
|
||||
table tablesubview scriptsubview
|
||||
)
|
||||
|
||||
opencs_units_noqt (view/world
|
||||
dialoguesubview util subviews enumdelegate vartypedelegate
|
||||
dialoguesubview util subviews enumdelegate vartypedelegate scripthighlighter
|
||||
)
|
||||
|
||||
|
||||
|
@ -72,27 +73,34 @@ opencs_units_noqt (view/tools
|
|||
subviews
|
||||
)
|
||||
|
||||
opencs_units (settings
|
||||
customblock
|
||||
proxyblock
|
||||
settingcontainer
|
||||
groupbox
|
||||
settingsitem
|
||||
opencs_units (view/settings
|
||||
abstractblock
|
||||
settingwidget
|
||||
itemblock
|
||||
groupblock
|
||||
toggleblock
|
||||
usersettingsdialog
|
||||
abstractpage
|
||||
proxyblock
|
||||
abstractwidget
|
||||
blankpage
|
||||
usersettingsdialog
|
||||
editorpage
|
||||
)
|
||||
|
||||
opencs_units_noqt (settings
|
||||
opencs_units_noqt (view/settings
|
||||
abstractpage
|
||||
blankpage
|
||||
groupblock
|
||||
customblock
|
||||
groupbox
|
||||
itemblock
|
||||
settingwidget
|
||||
toggleblock
|
||||
support
|
||||
)
|
||||
|
||||
opencs_units (model/settings
|
||||
usersettings
|
||||
settingcontainer
|
||||
)
|
||||
|
||||
opencs_units_noqt (model/settings
|
||||
support
|
||||
settingsitem
|
||||
)
|
||||
|
||||
set (OPENCS_US
|
||||
|
|
|
@ -113,5 +113,7 @@ int CS::Editor::run()
|
|||
{
|
||||
mStartup.show();
|
||||
|
||||
QApplication::setQuitOnLastWindowClosed (true);
|
||||
|
||||
return QApplication::exec();
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
#define CS_EDITOR_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#ifndef Q_MOC_RUN
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
|
||||
#endif
|
||||
#include "model/doc/documentmanager.hpp"
|
||||
|
||||
#include "view/doc/viewmanager.hpp"
|
||||
|
@ -23,7 +23,6 @@ namespace CS
|
|||
FileDialog mFileDialog;
|
||||
|
||||
Files::ConfigurationManager mCfgMgr;
|
||||
|
||||
void setupDataFiles();
|
||||
|
||||
// not implemented
|
||||
|
|
|
@ -151,6 +151,10 @@ void CSMDoc::Document::addOptionalGlobals()
|
|||
ESM::Global global;
|
||||
global.mId = sGlobals[i];
|
||||
global.mValue.setType (ESM::VT_Long);
|
||||
|
||||
if (i==0)
|
||||
global.mValue.setInteger (1); // dayspassed starts counting at 1
|
||||
|
||||
addOptionalGlobal (global);
|
||||
}
|
||||
}
|
||||
|
@ -190,15 +194,25 @@ void CSMDoc::Document::createBase()
|
|||
|
||||
record.mId = sGlobals[i];
|
||||
|
||||
record.mValue.setType (i==2 ? ESM::VT_Float : ESM::VT_Int);
|
||||
record.mValue.setType (i==2 ? ESM::VT_Float : ESM::VT_Long);
|
||||
|
||||
if (i==0)
|
||||
if (i==0 || i==1)
|
||||
record.mValue.setInteger (1);
|
||||
|
||||
getData().getGlobals().add (record);
|
||||
}
|
||||
|
||||
/// \todo add GMSTs
|
||||
|
||||
for (int i=0; i<27; ++i)
|
||||
{
|
||||
ESM::Skill record;
|
||||
record.mIndex = i;
|
||||
record.mId = ESM::Skill::indexToId (record.mIndex);
|
||||
record.blank();
|
||||
|
||||
getData().getSkills().add (record);
|
||||
}
|
||||
}
|
||||
|
||||
CSMDoc::Document::Document (const std::vector<boost::filesystem::path>& files, bool new_)
|
||||
|
@ -215,7 +229,7 @@ CSMDoc::Document::Document (const std::vector<boost::filesystem::path>& files, b
|
|||
|
||||
if (new_ && files.size()==1)
|
||||
createBase();
|
||||
else if (files.size()>1)
|
||||
else
|
||||
{
|
||||
std::vector<boost::filesystem::path>::const_iterator end = files.end();
|
||||
|
||||
|
@ -238,6 +252,9 @@ CSMDoc::Document::Document (const std::vector<boost::filesystem::path>& files, b
|
|||
connect (&mSaveTimer, SIGNAL(timeout()), this, SLOT (saving()));
|
||||
}
|
||||
|
||||
CSMDoc::Document::~Document()
|
||||
{}
|
||||
|
||||
QUndoStack& CSMDoc::Document::getUndoStack()
|
||||
{
|
||||
return mUndoStack;
|
||||
|
@ -291,11 +308,13 @@ void CSMDoc::Document::abortOperation (int type)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void CSMDoc::Document::modificationStateChanged (bool clean)
|
||||
{
|
||||
emit stateChanged (getState(), this);
|
||||
}
|
||||
|
||||
|
||||
void CSMDoc::Document::operationDone (int type)
|
||||
{
|
||||
emit stateChanged (getState(), this);
|
||||
|
@ -309,9 +328,12 @@ void CSMDoc::Document::saving()
|
|||
|
||||
if (mSaveCount>15)
|
||||
{
|
||||
//clear the stack before resetting the save state
|
||||
//to avoid emitting incorrect states
|
||||
mUndoStack.setClean();
|
||||
|
||||
mSaveCount = 0;
|
||||
mSaveTimer.stop();
|
||||
mUndoStack.setClean();
|
||||
emit stateChanged (getState(), this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,6 +63,7 @@ namespace CSMDoc
|
|||
public:
|
||||
|
||||
Document (const std::vector<boost::filesystem::path>& files, bool new_);
|
||||
~Document();
|
||||
|
||||
QUndoStack& getUndoStack();
|
||||
|
||||
|
|
|
@ -2,17 +2,17 @@
|
|||
|
||||
#include <QStringList>
|
||||
|
||||
CsSettings::SettingContainer::SettingContainer(QObject *parent) :
|
||||
CSMSettings::SettingContainer::SettingContainer(QObject *parent) :
|
||||
QObject(parent), mValue (0), mValues (0)
|
||||
{
|
||||
}
|
||||
|
||||
CsSettings::SettingContainer::SettingContainer(const QString &value, QObject *parent) :
|
||||
CSMSettings::SettingContainer::SettingContainer(const QString &value, QObject *parent) :
|
||||
QObject(parent), mValue (new QString (value)), mValues (0)
|
||||
{
|
||||
}
|
||||
|
||||
void CsSettings::SettingContainer::insert (const QString &value)
|
||||
void CSMSettings::SettingContainer::insert (const QString &value)
|
||||
{
|
||||
if (mValue)
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ void CsSettings::SettingContainer::insert (const QString &value)
|
|||
|
||||
}
|
||||
|
||||
void CsSettings::SettingContainer::update (const QString &value, int index)
|
||||
void CSMSettings::SettingContainer::update (const QString &value, int index)
|
||||
{
|
||||
if (isEmpty())
|
||||
mValue = new QString(value);
|
||||
|
@ -43,7 +43,7 @@ void CsSettings::SettingContainer::update (const QString &value, int index)
|
|||
mValues->replace(index, value);
|
||||
}
|
||||
|
||||
QString CsSettings::SettingContainer::getValue (int index) const
|
||||
QString CSMSettings::SettingContainer::getValue (int index) const
|
||||
{
|
||||
QString retVal("");
|
||||
|
||||
|
@ -66,7 +66,7 @@ QString CsSettings::SettingContainer::getValue (int index) const
|
|||
return retVal;
|
||||
}
|
||||
|
||||
int CsSettings::SettingContainer::count () const
|
||||
int CSMSettings::SettingContainer::count () const
|
||||
{
|
||||
int retVal = 0;
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
class QStringList;
|
||||
|
||||
namespace CsSettings
|
||||
namespace CSMSettings
|
||||
{
|
||||
class SettingContainer : public QObject
|
||||
{
|
|
@ -1,6 +1,6 @@
|
|||
#include "settingsitem.hpp"
|
||||
|
||||
bool CsSettings::SettingsItem::updateItem (const QStringList *values)
|
||||
bool CSMSettings::SettingsItem::updateItem (const QStringList *values)
|
||||
{
|
||||
QStringList::ConstIterator it = values->begin();
|
||||
|
||||
|
@ -30,7 +30,7 @@ bool CsSettings::SettingsItem::updateItem (const QStringList *values)
|
|||
return isValid;
|
||||
}
|
||||
|
||||
bool CsSettings::SettingsItem::updateItem (const QString &value)
|
||||
bool CSMSettings::SettingsItem::updateItem (const QString &value)
|
||||
{
|
||||
//takes a value or a SettingsContainer and updates itself accordingly
|
||||
//after validating the data against it's own definition
|
||||
|
@ -52,7 +52,7 @@ bool CsSettings::SettingsItem::updateItem (const QString &value)
|
|||
return success;
|
||||
}
|
||||
|
||||
bool CsSettings::SettingsItem::updateItem(int valueListIndex)
|
||||
bool CSMSettings::SettingsItem::updateItem(int valueListIndex)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
|
@ -64,7 +64,7 @@ bool CsSettings::SettingsItem::updateItem(int valueListIndex)
|
|||
return success;
|
||||
}
|
||||
|
||||
bool CsSettings::SettingsItem::validate (const QString &value)
|
||||
bool CSMSettings::SettingsItem::validate (const QString &value)
|
||||
{
|
||||
bool isValid = true;
|
||||
|
||||
|
@ -90,13 +90,13 @@ bool CsSettings::SettingsItem::validate (const QString &value)
|
|||
return isValid;
|
||||
}
|
||||
|
||||
void CsSettings::SettingsItem::setDefaultValue (const QString &value)
|
||||
void CSMSettings::SettingsItem::setDefaultValue (const QString &value)
|
||||
{
|
||||
mDefaultValue = value;
|
||||
update (value);
|
||||
}
|
||||
|
||||
QString CsSettings::SettingsItem::getDefaultValue() const
|
||||
QString CSMSettings::SettingsItem::getDefaultValue() const
|
||||
{
|
||||
return mDefaultValue;
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
#include "support.hpp"
|
||||
#include "settingcontainer.hpp"
|
||||
|
||||
namespace CsSettings
|
||||
namespace CSMSettings
|
||||
{
|
||||
class SettingsItem : public SettingContainer
|
||||
{
|
39
apps/opencs/model/settings/support.hpp
Normal file
39
apps/opencs/model/settings/support.hpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
#ifndef MODEL_SUPPORT_HPP
|
||||
#define MODEL_SUPPORT_HPP
|
||||
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
|
||||
class QLayout;
|
||||
class QWidget;
|
||||
class QListWidgetItem;
|
||||
|
||||
namespace CSMSettings
|
||||
{
|
||||
class SettingContainer;
|
||||
|
||||
typedef QList<SettingContainer *> SettingList;
|
||||
typedef QMap<QString, SettingContainer *> SettingMap;
|
||||
typedef QMap<QString, SettingMap *> SectionMap;
|
||||
|
||||
struct QStringPair
|
||||
{
|
||||
QStringPair(): left (""), right ("")
|
||||
{}
|
||||
|
||||
QStringPair (const QString &leftValue, const QString &rightValue)
|
||||
: left (leftValue), right(rightValue)
|
||||
{}
|
||||
|
||||
QStringPair (const QStringPair &pair)
|
||||
: left (pair.left), right (pair.right)
|
||||
{}
|
||||
|
||||
QString left;
|
||||
QString right;
|
||||
|
||||
bool isEmpty() const
|
||||
{ return (left.isEmpty() && right.isEmpty()); }
|
||||
};
|
||||
}
|
||||
#endif // MODEL_SUPPORT_HPP
|
|
@ -30,16 +30,16 @@ namespace boost
|
|||
#endif /* (BOOST_VERSION <= 104600) */
|
||||
|
||||
|
||||
CsSettings::UserSettings::UserSettings(Files::ConfigurationManager &cfg)
|
||||
: mCfgMgr(cfg)
|
||||
CSMSettings::UserSettings::UserSettings()
|
||||
{
|
||||
mUserSettingsInstance = this;
|
||||
}
|
||||
|
||||
CSMSettings::UserSettings::~UserSettings()
|
||||
{
|
||||
}
|
||||
|
||||
CsSettings::UserSettings::~UserSettings()
|
||||
{
|
||||
}
|
||||
|
||||
QFile *CsSettings::UserSettings::openFile (const QString &filename)
|
||||
QFile *CSMSettings::UserSettings::openFile (const QString &filename)
|
||||
{
|
||||
QFile *file = new QFile(filename);
|
||||
|
||||
|
@ -63,7 +63,7 @@ QFile *CsSettings::UserSettings::openFile (const QString &filename)
|
|||
return file;
|
||||
}
|
||||
|
||||
bool CsSettings::UserSettings::writeFile(QFile *file, QMap<QString, CsSettings::SettingList *> &settings)
|
||||
bool CSMSettings::UserSettings::writeFile(QFile *file, QMap<QString, CSMSettings::SettingList *> &settings)
|
||||
{
|
||||
if (!file)
|
||||
return false;
|
||||
|
@ -88,7 +88,7 @@ bool CsSettings::UserSettings::writeFile(QFile *file, QMap<QString, CsSettings::
|
|||
return true;
|
||||
}
|
||||
|
||||
void CsSettings::UserSettings::getSettings(QTextStream &stream, SectionMap §ions)
|
||||
void CSMSettings::UserSettings::getSettings(QTextStream &stream, SectionMap §ions)
|
||||
{
|
||||
//looks for a square bracket, "'\\["
|
||||
//that has one or more "not nothing" in it, "([^]]+)"
|
||||
|
@ -102,7 +102,7 @@ void CsSettings::UserSettings::getSettings(QTextStream &stream, SectionMap §
|
|||
|
||||
QRegExp keyRe("^([^=]+)\\s*=\\s*(.+)$");
|
||||
|
||||
CsSettings::SettingMap *settings = 0;
|
||||
CSMSettings::SettingMap *settings = 0;
|
||||
QString section = "none";
|
||||
|
||||
while (!stream.atEnd())
|
|
@ -15,20 +15,37 @@ namespace Files { typedef std::vector<boost::filesystem::path> PathContainer;
|
|||
|
||||
class QFile;
|
||||
|
||||
namespace CsSettings {
|
||||
namespace CSMSettings {
|
||||
|
||||
class UserSettings
|
||||
struct UserSettings: public QObject
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
UserSettings(Files::ConfigurationManager &cfg);
|
||||
~UserSettings();
|
||||
|
||||
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:
|
||||
Files::ConfigurationManager &mCfgMgr;
|
||||
|
||||
UserSettings *mUserSettingsInstance;
|
||||
UserSettings();
|
||||
~UserSettings();
|
||||
|
||||
UserSettings (UserSettings const &); //not implemented
|
||||
void operator= (UserSettings const &); //not implemented
|
||||
|
||||
signals:
|
||||
void signalUpdateEditorSetting (const QString &settingName, const QString &settingValue);
|
||||
|
||||
};
|
||||
}
|
39
apps/opencs/model/tools/birthsigncheck.cpp
Normal file
39
apps/opencs/model/tools/birthsigncheck.cpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
|
||||
#include "birthsigncheck.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
|
||||
#include <components/esm/loadbsgn.hpp>
|
||||
|
||||
#include "../world/universalid.hpp"
|
||||
|
||||
CSMTools::BirthsignCheckStage::BirthsignCheckStage (const CSMWorld::IdCollection<ESM::BirthSign>& birthsigns)
|
||||
: mBirthsigns (birthsigns)
|
||||
{}
|
||||
|
||||
int CSMTools::BirthsignCheckStage::setup()
|
||||
{
|
||||
return mBirthsigns.getSize();
|
||||
}
|
||||
|
||||
void CSMTools::BirthsignCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::BirthSign& birthsign = mBirthsigns.getRecord (stage).get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Birthsign, birthsign.mId);
|
||||
|
||||
// test for empty name, description and texture
|
||||
if (birthsign.mName.empty())
|
||||
messages.push_back (id.toString() + "|" + birthsign.mId + " has an empty name");
|
||||
|
||||
if (birthsign.mDescription.empty())
|
||||
messages.push_back (id.toString() + "|" + birthsign.mId + " has an empty description");
|
||||
|
||||
if (birthsign.mTexture.empty())
|
||||
messages.push_back (id.toString() + "|" + birthsign.mId + " is missing a texture");
|
||||
|
||||
/// \todo test if the texture exists
|
||||
|
||||
/// \todo check data members that can't be edited in the table view
|
||||
}
|
29
apps/opencs/model/tools/birthsigncheck.hpp
Normal file
29
apps/opencs/model/tools/birthsigncheck.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef CSM_TOOLS_BIRTHSIGNCHECK_H
|
||||
#define CSM_TOOLS_BIRTHSIGNCHECK_H
|
||||
|
||||
#include <components/esm/loadbsgn.hpp>
|
||||
|
||||
#include "../world/idcollection.hpp"
|
||||
|
||||
#include "stage.hpp"
|
||||
|
||||
namespace CSMTools
|
||||
{
|
||||
/// \brief VerifyStage: make sure that birthsign records are internally consistent
|
||||
class BirthsignCheckStage : public Stage
|
||||
{
|
||||
const CSMWorld::IdCollection<ESM::BirthSign>& mBirthsigns;
|
||||
|
||||
public:
|
||||
|
||||
BirthsignCheckStage (const CSMWorld::IdCollection<ESM::BirthSign>& birthsigns);
|
||||
|
||||
virtual int setup();
|
||||
///< \return number of steps
|
||||
|
||||
virtual void perform (int stage, std::vector<std::string>& messages);
|
||||
///< Messages resulting from this tage will be appended to \a messages.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
72
apps/opencs/model/tools/classcheck.cpp
Normal file
72
apps/opencs/model/tools/classcheck.cpp
Normal file
|
@ -0,0 +1,72 @@
|
|||
|
||||
#include "classcheck.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
|
||||
#include <components/esm/loadclas.hpp>
|
||||
#include <components/esm/loadskil.hpp>
|
||||
|
||||
#include "../world/universalid.hpp"
|
||||
|
||||
CSMTools::ClassCheckStage::ClassCheckStage (const CSMWorld::IdCollection<ESM::Class>& classes)
|
||||
: mClasses (classes)
|
||||
{}
|
||||
|
||||
int CSMTools::ClassCheckStage::setup()
|
||||
{
|
||||
return mClasses.getSize();
|
||||
}
|
||||
|
||||
void CSMTools::ClassCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::Class& class_= mClasses.getRecord (stage).get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Class, class_.mId);
|
||||
|
||||
// test for empty name and description
|
||||
if (class_.mName.empty())
|
||||
messages.push_back (id.toString() + "|" + class_.mId + " has an empty name");
|
||||
|
||||
if (class_.mDescription.empty())
|
||||
messages.push_back (id.toString() + "|" + class_.mId + " has an empty description");
|
||||
|
||||
// test for invalid attributes
|
||||
for (int i=0; i<2; ++i)
|
||||
if (class_.mData.mAttribute[i]==-1)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
|
||||
stream << id.toString() << "|Attribute #" << i << " of " << class_.mId << " is not set";
|
||||
|
||||
messages.push_back (stream.str());
|
||||
}
|
||||
|
||||
if (class_.mData.mAttribute[0]==class_.mData.mAttribute[1] && class_.mData.mAttribute[0]!=-1)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
|
||||
stream << id.toString() << "|Class lists same attribute twice";
|
||||
|
||||
messages.push_back (stream.str());
|
||||
}
|
||||
|
||||
// test for non-unique skill
|
||||
std::map<int, int> skills; // ID, number of occurrences
|
||||
|
||||
for (int i=0; i<5; ++i)
|
||||
for (int i2=0; i2<2; ++i2)
|
||||
++skills[class_.mData.mSkills[i][i2]];
|
||||
|
||||
for (std::map<int, int>::const_iterator iter (skills.begin()); iter!=skills.end(); ++iter)
|
||||
if (iter->second>1)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
|
||||
stream
|
||||
<< id.toString() << "|"
|
||||
<< ESM::Skill::indexToId (iter->first) << " is listed more than once";
|
||||
|
||||
messages.push_back (stream.str());
|
||||
}
|
||||
}
|
29
apps/opencs/model/tools/classcheck.hpp
Normal file
29
apps/opencs/model/tools/classcheck.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef CSM_TOOLS_CLASSCHECK_H
|
||||
#define CSM_TOOLS_CLASSCHECK_H
|
||||
|
||||
#include <components/esm/loadclas.hpp>
|
||||
|
||||
#include "../world/idcollection.hpp"
|
||||
|
||||
#include "stage.hpp"
|
||||
|
||||
namespace CSMTools
|
||||
{
|
||||
/// \brief VerifyStage: make sure that class records are internally consistent
|
||||
class ClassCheckStage : public Stage
|
||||
{
|
||||
const CSMWorld::IdCollection<ESM::Class>& mClasses;
|
||||
|
||||
public:
|
||||
|
||||
ClassCheckStage (const CSMWorld::IdCollection<ESM::Class>& classes);
|
||||
|
||||
virtual int setup();
|
||||
///< \return number of steps
|
||||
|
||||
virtual void perform (int stage, std::vector<std::string>& messages);
|
||||
///< Messages resulting from this tage will be appended to \a messages.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
61
apps/opencs/model/tools/factioncheck.cpp
Normal file
61
apps/opencs/model/tools/factioncheck.cpp
Normal file
|
@ -0,0 +1,61 @@
|
|||
|
||||
#include "factioncheck.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
|
||||
#include <components/esm/loadfact.hpp>
|
||||
#include <components/esm/loadskil.hpp>
|
||||
|
||||
#include "../world/universalid.hpp"
|
||||
|
||||
CSMTools::FactionCheckStage::FactionCheckStage (const CSMWorld::IdCollection<ESM::Faction>& factions)
|
||||
: mFactions (factions)
|
||||
{}
|
||||
|
||||
int CSMTools::FactionCheckStage::setup()
|
||||
{
|
||||
return mFactions.getSize();
|
||||
}
|
||||
|
||||
void CSMTools::FactionCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::Faction& faction = mFactions.getRecord (stage).get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Faction, faction.mId);
|
||||
|
||||
// test for empty name
|
||||
if (faction.mName.empty())
|
||||
messages.push_back (id.toString() + "|" + faction.mId + " has an empty name");
|
||||
|
||||
// test for invalid attributes
|
||||
if (faction.mData.mAttribute[0]==faction.mData.mAttribute[1] && faction.mData.mAttribute[0]!=-1)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
|
||||
stream << id.toString() << "|Faction lists same attribute twice";
|
||||
|
||||
messages.push_back (stream.str());
|
||||
}
|
||||
|
||||
// test for non-unique skill
|
||||
std::map<int, int> skills; // ID, number of occurrences
|
||||
|
||||
for (int i=0; i<6; ++i)
|
||||
if (faction.mData.mSkills[i]!=-1)
|
||||
++skills[faction.mData.mSkills[i]];
|
||||
|
||||
for (std::map<int, int>::const_iterator iter (skills.begin()); iter!=skills.end(); ++iter)
|
||||
if (iter->second>1)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
|
||||
stream
|
||||
<< id.toString() << "|"
|
||||
<< ESM::Skill::indexToId (iter->first) << " is listed more than once";
|
||||
|
||||
messages.push_back (stream.str());
|
||||
}
|
||||
|
||||
/// \todo check data members that can't be edited in the table view
|
||||
}
|
29
apps/opencs/model/tools/factioncheck.hpp
Normal file
29
apps/opencs/model/tools/factioncheck.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef CSM_TOOLS_FACTIONCHECK_H
|
||||
#define CSM_TOOLS_FACTIONCHECK_H
|
||||
|
||||
#include <components/esm/loadfact.hpp>
|
||||
|
||||
#include "../world/idcollection.hpp"
|
||||
|
||||
#include "stage.hpp"
|
||||
|
||||
namespace CSMTools
|
||||
{
|
||||
/// \brief VerifyStage: make sure that faction records are internally consistent
|
||||
class FactionCheckStage : public Stage
|
||||
{
|
||||
const CSMWorld::IdCollection<ESM::Faction>& mFactions;
|
||||
|
||||
public:
|
||||
|
||||
FactionCheckStage (const CSMWorld::IdCollection<ESM::Faction>& factions);
|
||||
|
||||
virtual int setup();
|
||||
///< \return number of steps
|
||||
|
||||
virtual void perform (int stage, std::vector<std::string>& messages);
|
||||
///< Messages resulting from this tage will be appended to \a messages.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
68
apps/opencs/model/tools/racecheck.cpp
Normal file
68
apps/opencs/model/tools/racecheck.cpp
Normal file
|
@ -0,0 +1,68 @@
|
|||
|
||||
#include "racecheck.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <components/esm/loadrace.hpp>
|
||||
|
||||
#include "../world/universalid.hpp"
|
||||
|
||||
void CSMTools::RaceCheckStage::performPerRecord (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::Race& race = mRaces.getRecord (stage).get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Race, race.mId);
|
||||
|
||||
// test for empty name and description
|
||||
if (race.mName.empty())
|
||||
messages.push_back (id.toString() + "|" + race.mId + " has an empty name");
|
||||
|
||||
if (race.mDescription.empty())
|
||||
messages.push_back (id.toString() + "|" + race.mId + " has an empty description");
|
||||
|
||||
// test for positive height
|
||||
if (race.mData.mHeight.mMale<=0)
|
||||
messages.push_back (id.toString() + "|male " + race.mId + " has non-positive height");
|
||||
|
||||
if (race.mData.mHeight.mFemale<=0)
|
||||
messages.push_back (id.toString() + "|female " + race.mId + " has non-positive height");
|
||||
|
||||
// test for non-negative weight
|
||||
if (race.mData.mWeight.mMale<0)
|
||||
messages.push_back (id.toString() + "|male " + race.mId + " has negative weight");
|
||||
|
||||
if (race.mData.mWeight.mFemale<0)
|
||||
messages.push_back (id.toString() + "|female " + race.mId + " has negative weight");
|
||||
|
||||
// remember playable flag
|
||||
if (race.mData.mFlags & 0x1)
|
||||
mPlayable = true;
|
||||
|
||||
/// \todo check data members that can't be edited in the table view
|
||||
}
|
||||
|
||||
void CSMTools::RaceCheckStage::performFinal (std::vector<std::string>& messages)
|
||||
{
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Races);
|
||||
|
||||
if (!mPlayable)
|
||||
messages.push_back (id.toString() + "|No playable race");
|
||||
}
|
||||
|
||||
CSMTools::RaceCheckStage::RaceCheckStage (const CSMWorld::IdCollection<ESM::Race>& races)
|
||||
: mRaces (races), mPlayable (false)
|
||||
{}
|
||||
|
||||
int CSMTools::RaceCheckStage::setup()
|
||||
{
|
||||
mPlayable = false;
|
||||
return mRaces.getSize()+1;
|
||||
}
|
||||
|
||||
void CSMTools::RaceCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
if (stage==mRaces.getSize())
|
||||
performFinal (messages);
|
||||
else
|
||||
performPerRecord (stage, messages);
|
||||
}
|
34
apps/opencs/model/tools/racecheck.hpp
Normal file
34
apps/opencs/model/tools/racecheck.hpp
Normal file
|
@ -0,0 +1,34 @@
|
|||
#ifndef CSM_TOOLS_RACECHECK_H
|
||||
#define CSM_TOOLS_RACECHECK_H
|
||||
|
||||
#include <components/esm/loadrace.hpp>
|
||||
|
||||
#include "../world/idcollection.hpp"
|
||||
|
||||
#include "stage.hpp"
|
||||
|
||||
namespace CSMTools
|
||||
{
|
||||
/// \brief VerifyStage: make sure that race records are internally consistent
|
||||
class RaceCheckStage : public Stage
|
||||
{
|
||||
const CSMWorld::IdCollection<ESM::Race>& mRaces;
|
||||
bool mPlayable;
|
||||
|
||||
void performPerRecord (int stage, std::vector<std::string>& messages);
|
||||
|
||||
void performFinal (std::vector<std::string>& messages);
|
||||
|
||||
public:
|
||||
|
||||
RaceCheckStage (const CSMWorld::IdCollection<ESM::Race>& races);
|
||||
|
||||
virtual int setup();
|
||||
///< \return number of steps
|
||||
|
||||
virtual void perform (int stage, std::vector<std::string>& messages);
|
||||
///< Messages resulting from this tage will be appended to \a messages.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
33
apps/opencs/model/tools/regioncheck.cpp
Normal file
33
apps/opencs/model/tools/regioncheck.cpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
|
||||
#include "regioncheck.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
|
||||
#include <components/esm/loadregn.hpp>
|
||||
|
||||
#include "../world/universalid.hpp"
|
||||
|
||||
CSMTools::RegionCheckStage::RegionCheckStage (const CSMWorld::IdCollection<ESM::Region>& regions)
|
||||
: mRegions (regions)
|
||||
{}
|
||||
|
||||
int CSMTools::RegionCheckStage::setup()
|
||||
{
|
||||
return mRegions.getSize();
|
||||
}
|
||||
|
||||
void CSMTools::RegionCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::Region& region = mRegions.getRecord (stage).get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Region, region.mId);
|
||||
|
||||
// test for empty name
|
||||
if (region.mName.empty())
|
||||
messages.push_back (id.toString() + "|" + region.mId + " has an empty name");
|
||||
|
||||
/// \todo test that the ID in mSleeplist exists
|
||||
|
||||
/// \todo check data members that can't be edited in the table view
|
||||
}
|
29
apps/opencs/model/tools/regioncheck.hpp
Normal file
29
apps/opencs/model/tools/regioncheck.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef CSM_TOOLS_REGIONCHECK_H
|
||||
#define CSM_TOOLS_REGIONCHECK_H
|
||||
|
||||
#include <components/esm/loadregn.hpp>
|
||||
|
||||
#include "../world/idcollection.hpp"
|
||||
|
||||
#include "stage.hpp"
|
||||
|
||||
namespace CSMTools
|
||||
{
|
||||
/// \brief VerifyStage: make sure that region records are internally consistent
|
||||
class RegionCheckStage : public Stage
|
||||
{
|
||||
const CSMWorld::IdCollection<ESM::Region>& mRegions;
|
||||
|
||||
public:
|
||||
|
||||
RegionCheckStage (const CSMWorld::IdCollection<ESM::Region>& regions);
|
||||
|
||||
virtual int setup();
|
||||
///< \return number of steps
|
||||
|
||||
virtual void perform (int stage, std::vector<std::string>& messages);
|
||||
///< Messages resulting from this tage will be appended to \a messages.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
37
apps/opencs/model/tools/skillcheck.cpp
Normal file
37
apps/opencs/model/tools/skillcheck.cpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
|
||||
#include "skillcheck.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <components/esm/loadskil.hpp>
|
||||
|
||||
#include "../world/universalid.hpp"
|
||||
|
||||
CSMTools::SkillCheckStage::SkillCheckStage (const CSMWorld::IdCollection<ESM::Skill>& skills)
|
||||
: mSkills (skills)
|
||||
{}
|
||||
|
||||
int CSMTools::SkillCheckStage::setup()
|
||||
{
|
||||
return mSkills.getSize();
|
||||
}
|
||||
|
||||
void CSMTools::SkillCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::Skill& skill = mSkills.getRecord (stage).get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Skill, skill.mId);
|
||||
|
||||
for (int i=0; i<4; ++i)
|
||||
if (skill.mData.mUseValue[i]<0)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
|
||||
stream << id.toString() << "|Use value #" << i << " of " << skill.mId << " is negative";
|
||||
|
||||
messages.push_back (stream.str());
|
||||
}
|
||||
|
||||
if (skill.mDescription.empty())
|
||||
messages.push_back (id.toString() + "|" + skill.mId + " has an empty description");
|
||||
}
|
29
apps/opencs/model/tools/skillcheck.hpp
Normal file
29
apps/opencs/model/tools/skillcheck.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef CSM_TOOLS_SKILLCHECK_H
|
||||
#define CSM_TOOLS_SKILLCHECK_H
|
||||
|
||||
#include <components/esm/loadskil.hpp>
|
||||
|
||||
#include "../world/idcollection.hpp"
|
||||
|
||||
#include "stage.hpp"
|
||||
|
||||
namespace CSMTools
|
||||
{
|
||||
/// \brief VerifyStage: make sure that skill records are internally consistent
|
||||
class SkillCheckStage : public Stage
|
||||
{
|
||||
const CSMWorld::IdCollection<ESM::Skill>& mSkills;
|
||||
|
||||
public:
|
||||
|
||||
SkillCheckStage (const CSMWorld::IdCollection<ESM::Skill>& skills);
|
||||
|
||||
virtual int setup();
|
||||
///< \return number of steps
|
||||
|
||||
virtual void perform (int stage, std::vector<std::string>& messages);
|
||||
///< Messages resulting from this tage will be appended to \a messages.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
29
apps/opencs/model/tools/soundcheck.cpp
Normal file
29
apps/opencs/model/tools/soundcheck.cpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
|
||||
#include "soundcheck.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <components/esm/loadskil.hpp>
|
||||
|
||||
#include "../world/universalid.hpp"
|
||||
|
||||
CSMTools::SoundCheckStage::SoundCheckStage (const CSMWorld::IdCollection<ESM::Sound>& sounds)
|
||||
: mSounds (sounds)
|
||||
{}
|
||||
|
||||
int CSMTools::SoundCheckStage::setup()
|
||||
{
|
||||
return mSounds.getSize();
|
||||
}
|
||||
|
||||
void CSMTools::SoundCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::Sound& sound = mSounds.getRecord (stage).get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Sound, sound.mId);
|
||||
|
||||
if (sound.mData.mMinRange>sound.mData.mMaxRange)
|
||||
messages.push_back (id.toString() + "|Maximum range larger than minimum range");
|
||||
|
||||
/// \todo check, if the sound file exists
|
||||
}
|
29
apps/opencs/model/tools/soundcheck.hpp
Normal file
29
apps/opencs/model/tools/soundcheck.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef CSM_TOOLS_SOUNDCHECK_H
|
||||
#define CSM_TOOLS_SOUNDCHECK_H
|
||||
|
||||
#include <components/esm/loadsoun.hpp>
|
||||
|
||||
#include "../world/idcollection.hpp"
|
||||
|
||||
#include "stage.hpp"
|
||||
|
||||
namespace CSMTools
|
||||
{
|
||||
/// \brief VerifyStage: make sure that sound records are internally consistent
|
||||
class SoundCheckStage : public Stage
|
||||
{
|
||||
const CSMWorld::IdCollection<ESM::Sound>& mSounds;
|
||||
|
||||
public:
|
||||
|
||||
SoundCheckStage (const CSMWorld::IdCollection<ESM::Sound>& sounds);
|
||||
|
||||
virtual int setup();
|
||||
///< \return number of steps
|
||||
|
||||
virtual void perform (int stage, std::vector<std::string>& messages);
|
||||
///< Messages resulting from this tage will be appended to \a messages.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
35
apps/opencs/model/tools/spellcheck.cpp
Normal file
35
apps/opencs/model/tools/spellcheck.cpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
|
||||
#include "spellcheck.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
|
||||
#include <components/esm/loadspel.hpp>
|
||||
|
||||
#include "../world/universalid.hpp"
|
||||
|
||||
CSMTools::SpellCheckStage::SpellCheckStage (const CSMWorld::IdCollection<ESM::Spell>& spells)
|
||||
: mSpells (spells)
|
||||
{}
|
||||
|
||||
int CSMTools::SpellCheckStage::setup()
|
||||
{
|
||||
return mSpells.getSize();
|
||||
}
|
||||
|
||||
void CSMTools::SpellCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::Spell& spell = mSpells.getRecord (stage).get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Spell, spell.mId);
|
||||
|
||||
// test for empty name and description
|
||||
if (spell.mName.empty())
|
||||
messages.push_back (id.toString() + "|" + spell.mId + " has an empty name");
|
||||
|
||||
// test for invalid cost values
|
||||
if (spell.mData.mCost<0)
|
||||
messages.push_back (id.toString() + "|" + spell.mId + " has a negative spell costs");
|
||||
|
||||
/// \todo check data members that can't be edited in the table view
|
||||
}
|
29
apps/opencs/model/tools/spellcheck.hpp
Normal file
29
apps/opencs/model/tools/spellcheck.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef CSM_TOOLS_SPELLCHECK_H
|
||||
#define CSM_TOOLS_SPELLCHECK_H
|
||||
|
||||
#include <components/esm/loadspel.hpp>
|
||||
|
||||
#include "../world/idcollection.hpp"
|
||||
|
||||
#include "stage.hpp"
|
||||
|
||||
namespace CSMTools
|
||||
{
|
||||
/// \brief VerifyStage: make sure that spell records are internally consistent
|
||||
class SpellCheckStage : public Stage
|
||||
{
|
||||
const CSMWorld::IdCollection<ESM::Spell>& mSpells;
|
||||
|
||||
public:
|
||||
|
||||
SpellCheckStage (const CSMWorld::IdCollection<ESM::Spell>& spells);
|
||||
|
||||
virtual int setup();
|
||||
///< \return number of steps
|
||||
|
||||
virtual void perform (int stage, std::vector<std::string>& messages);
|
||||
///< Messages resulting from this tage will be appended to \a messages.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -12,6 +12,14 @@
|
|||
|
||||
#include "reportmodel.hpp"
|
||||
#include "mandatoryid.hpp"
|
||||
#include "skillcheck.hpp"
|
||||
#include "classcheck.hpp"
|
||||
#include "factioncheck.hpp"
|
||||
#include "racecheck.hpp"
|
||||
#include "soundcheck.hpp"
|
||||
#include "regioncheck.hpp"
|
||||
#include "birthsigncheck.hpp"
|
||||
#include "spellcheck.hpp"
|
||||
|
||||
CSMTools::Operation *CSMTools::Tools::get (int type)
|
||||
{
|
||||
|
@ -51,6 +59,22 @@ CSMTools::Verifier *CSMTools::Tools::getVerifier()
|
|||
|
||||
mVerifier->appendStage (new MandatoryIdStage (mData.getGlobals(),
|
||||
CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Globals), mandatoryIds));
|
||||
|
||||
mVerifier->appendStage (new SkillCheckStage (mData.getSkills()));
|
||||
|
||||
mVerifier->appendStage (new ClassCheckStage (mData.getClasses()));
|
||||
|
||||
mVerifier->appendStage (new FactionCheckStage (mData.getFactions()));
|
||||
|
||||
mVerifier->appendStage (new RaceCheckStage (mData.getRaces()));
|
||||
|
||||
mVerifier->appendStage (new SoundCheckStage (mData.getSounds()));
|
||||
|
||||
mVerifier->appendStage (new RegionCheckStage (mData.getRegions()));
|
||||
|
||||
mVerifier->appendStage (new BirthsignCheckStage (mData.getBirthsigns()));
|
||||
|
||||
mVerifier->appendStage (new SpellCheckStage (mData.getSpells()));
|
||||
}
|
||||
|
||||
return mVerifier;
|
||||
|
|
20
apps/opencs/model/world/cell.cpp
Normal file
20
apps/opencs/model/world/cell.cpp
Normal file
|
@ -0,0 +1,20 @@
|
|||
|
||||
#include "cell.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
void CSMWorld::Cell::load (ESM::ESMReader &esm)
|
||||
{
|
||||
mName = mId;
|
||||
|
||||
ESM::Cell::load (esm, true); /// \todo set this to false, once the bug in ESM::Cell::load is fixed
|
||||
|
||||
if (!(mData.mFlags & Interior))
|
||||
{
|
||||
std::ostringstream stream;
|
||||
|
||||
stream << "#" << mData.mX << " " << mData.mY;
|
||||
|
||||
mId = stream.str();
|
||||
}
|
||||
}
|
17
apps/opencs/model/world/cell.hpp
Normal file
17
apps/opencs/model/world/cell.hpp
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef CSM_WOLRD_CELL_H
|
||||
#define CSM_WOLRD_CELL_H
|
||||
|
||||
#include <components/esm/loadcell.hpp>
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
/// \brief Wrapper for Cell record
|
||||
struct Cell : public ESM::Cell
|
||||
{
|
||||
std::string mId;
|
||||
|
||||
void load (ESM::ESMReader &esm);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -31,7 +31,17 @@ namespace CSMWorld
|
|||
Display_Float,
|
||||
Display_Var,
|
||||
Display_GmstVarType,
|
||||
Display_GlobalVarType
|
||||
Display_GlobalVarType,
|
||||
Display_Specialisation,
|
||||
Display_Attribute,
|
||||
Display_Boolean,
|
||||
Display_SpellType,
|
||||
Display_Script,
|
||||
Display_ApparatusType,
|
||||
Display_ArmorType,
|
||||
Display_ClothingType,
|
||||
Display_CreatureType,
|
||||
Display_WeaponType
|
||||
};
|
||||
|
||||
std::string mTitle;
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
#ifndef CSM_WOLRD_COLUMNS_H
|
||||
#define CSM_WOLRD_COLUMNS_H
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <QColor>
|
||||
|
||||
#include "columnbase.hpp"
|
||||
|
||||
namespace CSMWorld
|
||||
|
@ -35,7 +41,7 @@ namespace CSMWorld
|
|||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return record.get().mId.c_str();
|
||||
return QString::fromUtf8 (record.get().mId.c_str());
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
|
@ -127,17 +133,17 @@ namespace CSMWorld
|
|||
{
|
||||
case ESM::VT_String:
|
||||
|
||||
return record.get().mValue.getString().c_str(); break;
|
||||
return QString::fromUtf8 (record.get().mValue.getString().c_str());
|
||||
|
||||
case ESM::VT_Int:
|
||||
case ESM::VT_Short:
|
||||
case ESM::VT_Long:
|
||||
|
||||
return record.get().mValue.getInteger(); break;
|
||||
return record.get().mValue.getInteger();
|
||||
|
||||
case ESM::VT_Float:
|
||||
|
||||
return record.get().mValue.getFloat(); break;
|
||||
return record.get().mValue.getFloat();
|
||||
|
||||
default: return QVariant();
|
||||
}
|
||||
|
@ -177,6 +183,596 @@ namespace CSMWorld
|
|||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct DescriptionColumn : public Column<ESXRecordT>
|
||||
{
|
||||
DescriptionColumn() : Column<ESXRecordT> ("Description", ColumnBase::Display_String) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return QString::fromUtf8 (record.get().mDescription.c_str());
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mDescription = data.toString().toUtf8().constData();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct SpecialisationColumn : public Column<ESXRecordT>
|
||||
{
|
||||
SpecialisationColumn() : Column<ESXRecordT> ("Specialisation", ColumnBase::Display_Specialisation) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return record.get().mData.mSpecialization;
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mData.mSpecialization = data.toInt();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct UseValueColumn : public Column<ESXRecordT>
|
||||
{
|
||||
int mIndex;
|
||||
|
||||
UseValueColumn (int index)
|
||||
: Column<ESXRecordT> ("Use value #" + boost::lexical_cast<std::string> (index),
|
||||
ColumnBase::Display_Float), mIndex (index)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return record.get().mData.mUseValue[mIndex];
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mData.mUseValue[mIndex] = data.toInt();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct AttributeColumn : public Column<ESXRecordT>
|
||||
{
|
||||
AttributeColumn() : Column<ESXRecordT> ("Attribute", ColumnBase::Display_Attribute) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return record.get().mData.mAttribute;
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mData.mAttribute = data.toInt();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct NameColumn : public Column<ESXRecordT>
|
||||
{
|
||||
NameColumn() : Column<ESXRecordT> ("Name", ColumnBase::Display_String) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return QString::fromUtf8 (record.get().mName.c_str());
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mName = data.toString().toUtf8().constData();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct AttributesColumn : public Column<ESXRecordT>
|
||||
{
|
||||
int mIndex;
|
||||
|
||||
AttributesColumn (int index)
|
||||
: Column<ESXRecordT> ("Attribute #" + boost::lexical_cast<std::string> (index),
|
||||
ColumnBase::Display_Attribute), mIndex (index) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return record.get().mData.mAttribute[mIndex];
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mData.mAttribute[mIndex] = data.toInt();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct SkillsColumn : public Column<ESXRecordT>
|
||||
{
|
||||
int mIndex;
|
||||
bool mMajor;
|
||||
|
||||
SkillsColumn (int index, bool typePrefix = false, bool major = false)
|
||||
: Column<ESXRecordT> ((typePrefix ? (major ? "Major Skill #" : "Minor Skill #") : "Skill #")+
|
||||
boost::lexical_cast<std::string> (index), ColumnBase::Display_String),
|
||||
mIndex (index), mMajor (major)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
int skill = record.get().mData.getSkill (mIndex, mMajor);
|
||||
|
||||
return QString::fromUtf8 (ESM::Skill::indexToId (skill).c_str());
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
std::istringstream stream (data.toString().toUtf8().constData());
|
||||
|
||||
int index = -1;
|
||||
char c;
|
||||
|
||||
stream >> c >> index;
|
||||
|
||||
if (index!=-1)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mData.getSkill (mIndex, mMajor) = index;
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct PlayableColumn : public Column<ESXRecordT>
|
||||
{
|
||||
PlayableColumn() : Column<ESXRecordT> ("Playable", ColumnBase::Display_Boolean) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return record.get().mData.mIsPlayable!=0;
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mData.mIsPlayable = data.toInt();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct HiddenColumn : public Column<ESXRecordT>
|
||||
{
|
||||
HiddenColumn() : Column<ESXRecordT> ("Hidden", ColumnBase::Display_Boolean) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return record.get().mData.mIsHidden!=0;
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mData.mIsHidden = data.toInt();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct FlagColumn : public Column<ESXRecordT>
|
||||
{
|
||||
int mMask;
|
||||
|
||||
FlagColumn (const std::string& name, int mask)
|
||||
: Column<ESXRecordT> (name, ColumnBase::Display_Boolean), mMask (mask)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return (record.get().mData.mFlags & mMask)!=0;
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
int flags = record2.mData.mFlags & ~mMask;
|
||||
|
||||
if (data.toInt())
|
||||
flags |= mMask;
|
||||
|
||||
record2.mData.mFlags = flags;
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct WeightHeightColumn : public Column<ESXRecordT>
|
||||
{
|
||||
bool mMale;
|
||||
bool mWeight;
|
||||
|
||||
WeightHeightColumn (bool male, bool weight)
|
||||
: Column<ESXRecordT> (male ? (weight ? "Male Weight" : "Male Height") :
|
||||
(weight ? "Female Weight" : "Female Height"), ColumnBase::Display_Float),
|
||||
mMale (male), mWeight (weight)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
const ESM::Race::MaleFemaleF& value =
|
||||
mWeight ? record.get().mData.mWeight : record.get().mData.mHeight;
|
||||
|
||||
return mMale ? value.mMale : value.mFemale;
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
ESM::Race::MaleFemaleF& value =
|
||||
mWeight ? record2.mData.mWeight : record2.mData.mHeight;
|
||||
|
||||
(mMale ? value.mMale : value.mFemale) = data.toFloat();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct SoundParamColumn : public Column<ESXRecordT>
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Type_Volume,
|
||||
Type_MinRange,
|
||||
Type_MaxRange
|
||||
};
|
||||
|
||||
Type mType;
|
||||
|
||||
SoundParamColumn (Type type)
|
||||
: Column<ESXRecordT> (
|
||||
type==Type_Volume ? "Volume" : (type==Type_MinRange ? "Min Range" : "Max Range"),
|
||||
ColumnBase::Display_Integer),
|
||||
mType (type)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
int value = 0;
|
||||
|
||||
switch (mType)
|
||||
{
|
||||
case Type_Volume: value = record.get().mData.mVolume; break;
|
||||
case Type_MinRange: value = record.get().mData.mMinRange; break;
|
||||
case Type_MaxRange: value = record.get().mData.mMaxRange; break;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
int value = data.toInt();
|
||||
|
||||
if (value<0)
|
||||
value = 0;
|
||||
else if (value>255)
|
||||
value = 255;
|
||||
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
switch (mType)
|
||||
{
|
||||
case Type_Volume: record2.mData.mVolume = static_cast<unsigned char> (value); break;
|
||||
case Type_MinRange: record2.mData.mMinRange = static_cast<unsigned char> (value); break;
|
||||
case Type_MaxRange: record2.mData.mMaxRange = static_cast<unsigned char> (value); break;
|
||||
}
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct SoundFileColumn : public Column<ESXRecordT>
|
||||
{
|
||||
SoundFileColumn() : Column<ESXRecordT> ("Sound File", ColumnBase::Display_String) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return QString::fromUtf8 (record.get().mSound.c_str());
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mSound = data.toString().toUtf8().constData();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/// \todo QColor is a GUI class and should not be in model. Need to think of an alternative
|
||||
/// solution.
|
||||
template<typename ESXRecordT>
|
||||
struct MapColourColumn : public Column<ESXRecordT>
|
||||
{
|
||||
/// \todo Replace Display_Integer with something that displays the colour value more directly.
|
||||
MapColourColumn() : Column<ESXRecordT> ("Map Colour", ColumnBase::Display_Integer) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
int colour = record.get().mMapColor;
|
||||
|
||||
return QColor (colour & 0xff, (colour>>8) & 0xff, (colour>>16) & 0xff);
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
QColor colour = data.value<QColor>();
|
||||
|
||||
record2.mMapColor = colour.rgb() & 0xffffff;
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct SleepListColumn : public Column<ESXRecordT>
|
||||
{
|
||||
SleepListColumn() : Column<ESXRecordT> ("Sleep Encounter", ColumnBase::Display_String) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return QString::fromUtf8 (record.get().mSleepList.c_str());
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mSleepList = data.toString().toUtf8().constData();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct TextureColumn : public Column<ESXRecordT>
|
||||
{
|
||||
TextureColumn() : Column<ESXRecordT> ("Texture", ColumnBase::Display_String) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return QString::fromUtf8 (record.get().mTexture.c_str());
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mTexture = data.toString().toUtf8().constData();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct SpellTypeColumn : public Column<ESXRecordT>
|
||||
{
|
||||
SpellTypeColumn() : Column<ESXRecordT> ("Type", ColumnBase::Display_SpellType) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return record.get().mData.mType;
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mData.mType = data.toInt();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct CostColumn : public Column<ESXRecordT>
|
||||
{
|
||||
CostColumn() : Column<ESXRecordT> ("Cost", ColumnBase::Display_Integer) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return record.get().mData.mCost;
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
record2.mData.mCost = data.toInt();
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct ScriptColumn : public Column<ESXRecordT>
|
||||
{
|
||||
ScriptColumn() : Column<ESXRecordT> ("Script", ColumnBase::Display_Script, 0) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return QString::fromUtf8 (record.get().mScriptText.c_str());
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mScriptText = data.toString().toUtf8().constData();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct RegionColumn : public Column<ESXRecordT>
|
||||
{
|
||||
RegionColumn() : Column<ESXRecordT> ("Region", ColumnBase::Display_String) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return QString::fromUtf8 (record.get().mRegion.c_str());
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mRegion = data.toString().toUtf8().constData();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
#include "commands.hpp"
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
#include "idtableproxymodel.hpp"
|
||||
#include "idtable.hpp"
|
||||
|
@ -71,7 +71,7 @@ void CSMWorld::RevertCommand::redo()
|
|||
|
||||
void CSMWorld::RevertCommand::undo()
|
||||
{
|
||||
mModel.setRecord (*mOld);
|
||||
mModel.setRecord (mId, *mOld);
|
||||
}
|
||||
|
||||
CSMWorld::DeleteCommand::DeleteCommand (IdTable& model, const std::string& id, QUndoCommand *parent)
|
||||
|
@ -104,5 +104,5 @@ void CSMWorld::DeleteCommand::redo()
|
|||
|
||||
void CSMWorld::DeleteCommand::undo()
|
||||
{
|
||||
mModel.setRecord (*mOld);
|
||||
mModel.setRecord (mId, *mOld);
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <stdexcept>
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
#include <components/esm/esmreader.hpp>
|
||||
#include <components/esm/defs.hpp>
|
||||
|
@ -12,7 +12,7 @@
|
|||
#include "idtable.hpp"
|
||||
#include "columns.hpp"
|
||||
|
||||
void CSMWorld::Data::addModel (QAbstractTableModel *model, UniversalId::Type type1,
|
||||
void CSMWorld::Data::addModel (QAbstractItemModel *model, UniversalId::Type type1,
|
||||
UniversalId::Type type2)
|
||||
{
|
||||
mModels.push_back (model);
|
||||
|
@ -33,16 +33,120 @@ CSMWorld::Data::Data()
|
|||
mGmsts.addColumn (new StringIdColumn<ESM::GameSetting>);
|
||||
mGmsts.addColumn (new RecordStateColumn<ESM::GameSetting>);
|
||||
mGmsts.addColumn (new FixedRecordTypeColumn<ESM::GameSetting> (UniversalId::Type_Gmst));
|
||||
mGmsts.addColumn (new FixedRecordTypeColumn<ESM::GameSetting> (UniversalId::Type_Gmst));
|
||||
mGmsts.addColumn (new VarTypeColumn<ESM::GameSetting> (ColumnBase::Display_GmstVarType));
|
||||
mGmsts.addColumn (new VarValueColumn<ESM::GameSetting>);
|
||||
|
||||
mSkills.addColumn (new StringIdColumn<ESM::Skill>);
|
||||
mSkills.addColumn (new RecordStateColumn<ESM::Skill>);
|
||||
mSkills.addColumn (new FixedRecordTypeColumn<ESM::Skill> (UniversalId::Type_Skill));
|
||||
mSkills.addColumn (new AttributeColumn<ESM::Skill>);
|
||||
mSkills.addColumn (new SpecialisationColumn<ESM::Skill>);
|
||||
for (int i=0; i<4; ++i)
|
||||
mSkills.addColumn (new UseValueColumn<ESM::Skill> (i));
|
||||
mSkills.addColumn (new DescriptionColumn<ESM::Skill>);
|
||||
|
||||
mClasses.addColumn (new StringIdColumn<ESM::Class>);
|
||||
mClasses.addColumn (new RecordStateColumn<ESM::Class>);
|
||||
mClasses.addColumn (new FixedRecordTypeColumn<ESM::Class> (UniversalId::Type_Class));
|
||||
mClasses.addColumn (new NameColumn<ESM::Class>);
|
||||
mClasses.addColumn (new AttributesColumn<ESM::Class> (0));
|
||||
mClasses.addColumn (new AttributesColumn<ESM::Class> (1));
|
||||
mClasses.addColumn (new SpecialisationColumn<ESM::Class>);
|
||||
for (int i=0; i<5; ++i)
|
||||
mClasses.addColumn (new SkillsColumn<ESM::Class> (i, true, true));
|
||||
for (int i=0; i<5; ++i)
|
||||
mClasses.addColumn (new SkillsColumn<ESM::Class> (i, true, false));
|
||||
mClasses.addColumn (new PlayableColumn<ESM::Class>);
|
||||
mClasses.addColumn (new DescriptionColumn<ESM::Class>);
|
||||
|
||||
mFactions.addColumn (new StringIdColumn<ESM::Faction>);
|
||||
mFactions.addColumn (new RecordStateColumn<ESM::Faction>);
|
||||
mFactions.addColumn (new FixedRecordTypeColumn<ESM::Faction> (UniversalId::Type_Faction));
|
||||
mFactions.addColumn (new NameColumn<ESM::Faction>);
|
||||
mFactions.addColumn (new AttributesColumn<ESM::Faction> (0));
|
||||
mFactions.addColumn (new AttributesColumn<ESM::Faction> (1));
|
||||
mFactions.addColumn (new HiddenColumn<ESM::Faction>);
|
||||
for (int i=0; i<6; ++i)
|
||||
mFactions.addColumn (new SkillsColumn<ESM::Faction> (i));
|
||||
|
||||
mRaces.addColumn (new StringIdColumn<ESM::Race>);
|
||||
mRaces.addColumn (new RecordStateColumn<ESM::Race>);
|
||||
mRaces.addColumn (new FixedRecordTypeColumn<ESM::Race> (UniversalId::Type_Race));
|
||||
mRaces.addColumn (new NameColumn<ESM::Race>);
|
||||
mRaces.addColumn (new DescriptionColumn<ESM::Race>);
|
||||
mRaces.addColumn (new FlagColumn<ESM::Race> ("Playable", 0x1));
|
||||
mRaces.addColumn (new FlagColumn<ESM::Race> ("Beast Race", 0x2));
|
||||
mRaces.addColumn (new WeightHeightColumn<ESM::Race> (true, true));
|
||||
mRaces.addColumn (new WeightHeightColumn<ESM::Race> (true, false));
|
||||
mRaces.addColumn (new WeightHeightColumn<ESM::Race> (false, true));
|
||||
mRaces.addColumn (new WeightHeightColumn<ESM::Race> (false, false));
|
||||
|
||||
mSounds.addColumn (new StringIdColumn<ESM::Sound>);
|
||||
mSounds.addColumn (new RecordStateColumn<ESM::Sound>);
|
||||
mSounds.addColumn (new FixedRecordTypeColumn<ESM::Sound> (UniversalId::Type_Sound));
|
||||
mSounds.addColumn (new SoundParamColumn<ESM::Sound> (SoundParamColumn<ESM::Sound>::Type_Volume));
|
||||
mSounds.addColumn (new SoundParamColumn<ESM::Sound> (SoundParamColumn<ESM::Sound>::Type_MinRange));
|
||||
mSounds.addColumn (new SoundParamColumn<ESM::Sound> (SoundParamColumn<ESM::Sound>::Type_MaxRange));
|
||||
mSounds.addColumn (new SoundFileColumn<ESM::Sound>);
|
||||
|
||||
mScripts.addColumn (new StringIdColumn<ESM::Script>);
|
||||
mScripts.addColumn (new RecordStateColumn<ESM::Script>);
|
||||
mScripts.addColumn (new FixedRecordTypeColumn<ESM::Script> (UniversalId::Type_Script));
|
||||
mScripts.addColumn (new ScriptColumn<ESM::Script>);
|
||||
|
||||
mRegions.addColumn (new StringIdColumn<ESM::Region>);
|
||||
mRegions.addColumn (new RecordStateColumn<ESM::Region>);
|
||||
mRegions.addColumn (new FixedRecordTypeColumn<ESM::Region> (UniversalId::Type_Region));
|
||||
mRegions.addColumn (new NameColumn<ESM::Region>);
|
||||
mRegions.addColumn (new MapColourColumn<ESM::Region>);
|
||||
mRegions.addColumn (new SleepListColumn<ESM::Region>);
|
||||
|
||||
mBirthsigns.addColumn (new StringIdColumn<ESM::BirthSign>);
|
||||
mBirthsigns.addColumn (new RecordStateColumn<ESM::BirthSign>);
|
||||
mBirthsigns.addColumn (new FixedRecordTypeColumn<ESM::BirthSign> (UniversalId::Type_Birthsign));
|
||||
mBirthsigns.addColumn (new NameColumn<ESM::BirthSign>);
|
||||
mBirthsigns.addColumn (new TextureColumn<ESM::BirthSign>);
|
||||
mBirthsigns.addColumn (new DescriptionColumn<ESM::BirthSign>);
|
||||
|
||||
mSpells.addColumn (new StringIdColumn<ESM::Spell>);
|
||||
mSpells.addColumn (new RecordStateColumn<ESM::Spell>);
|
||||
mSpells.addColumn (new FixedRecordTypeColumn<ESM::Spell> (UniversalId::Type_Spell));
|
||||
mSpells.addColumn (new NameColumn<ESM::Spell>);
|
||||
mSpells.addColumn (new SpellTypeColumn<ESM::Spell>);
|
||||
mSpells.addColumn (new CostColumn<ESM::Spell>);
|
||||
mSpells.addColumn (new FlagColumn<ESM::Spell> ("Autocalc", 0x1));
|
||||
mSpells.addColumn (new FlagColumn<ESM::Spell> ("Starter Spell", 0x2));
|
||||
mSpells.addColumn (new FlagColumn<ESM::Spell> ("Always Succeeds", 0x4));
|
||||
|
||||
mCells.addColumn (new StringIdColumn<Cell>);
|
||||
mCells.addColumn (new RecordStateColumn<Cell>);
|
||||
mCells.addColumn (new FixedRecordTypeColumn<Cell> (UniversalId::Type_Cell));
|
||||
mCells.addColumn (new NameColumn<Cell>);
|
||||
mCells.addColumn (new FlagColumn<Cell> ("Sleep forbidden", ESM::Cell::NoSleep));
|
||||
mCells.addColumn (new FlagColumn<Cell> ("Interior Water", ESM::Cell::HasWater));
|
||||
mCells.addColumn (new FlagColumn<Cell> ("Interior Sky", ESM::Cell::QuasiEx));
|
||||
mCells.addColumn (new RegionColumn<Cell>);
|
||||
|
||||
addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global);
|
||||
addModel (new IdTable (&mGmsts), UniversalId::Type_Gmsts, UniversalId::Type_Gmst);
|
||||
addModel (new IdTable (&mSkills), UniversalId::Type_Skills, UniversalId::Type_Skill);
|
||||
addModel (new IdTable (&mClasses), UniversalId::Type_Classes, UniversalId::Type_Class);
|
||||
addModel (new IdTable (&mFactions), UniversalId::Type_Factions, UniversalId::Type_Faction);
|
||||
addModel (new IdTable (&mRaces), UniversalId::Type_Races, UniversalId::Type_Race);
|
||||
addModel (new IdTable (&mSounds), UniversalId::Type_Sounds, UniversalId::Type_Sound);
|
||||
addModel (new IdTable (&mScripts), UniversalId::Type_Scripts, UniversalId::Type_Script);
|
||||
addModel (new IdTable (&mRegions), UniversalId::Type_Regions, UniversalId::Type_Region);
|
||||
addModel (new IdTable (&mBirthsigns), UniversalId::Type_Birthsigns, UniversalId::Type_Birthsign);
|
||||
addModel (new IdTable (&mSpells), UniversalId::Type_Spells, UniversalId::Type_Spell);
|
||||
addModel (new IdTable (&mCells), UniversalId::Type_Cells, UniversalId::Type_Cell);
|
||||
addModel (new IdTable (&mReferenceables), UniversalId::Type_Referenceables,
|
||||
UniversalId::Type_Referenceable);
|
||||
}
|
||||
|
||||
CSMWorld::Data::~Data()
|
||||
{
|
||||
for (std::vector<QAbstractTableModel *>::iterator iter (mModels.begin()); iter!=mModels.end(); ++iter)
|
||||
for (std::vector<QAbstractItemModel *>::iterator iter (mModels.begin()); iter!=mModels.end(); ++iter)
|
||||
delete *iter;
|
||||
}
|
||||
|
||||
|
@ -66,9 +170,119 @@ CSMWorld::IdCollection<ESM::GameSetting>& CSMWorld::Data::getGmsts()
|
|||
return mGmsts;
|
||||
}
|
||||
|
||||
QAbstractTableModel *CSMWorld::Data::getTableModel (const UniversalId& id)
|
||||
const CSMWorld::IdCollection<ESM::Skill>& CSMWorld::Data::getSkills() const
|
||||
{
|
||||
std::map<UniversalId::Type, QAbstractTableModel *>::iterator iter = mModelIndex.find (id.getType());
|
||||
return mSkills;
|
||||
}
|
||||
|
||||
CSMWorld::IdCollection<ESM::Skill>& CSMWorld::Data::getSkills()
|
||||
{
|
||||
return mSkills;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<ESM::Class>& CSMWorld::Data::getClasses() const
|
||||
{
|
||||
return mClasses;
|
||||
}
|
||||
|
||||
CSMWorld::IdCollection<ESM::Class>& CSMWorld::Data::getClasses()
|
||||
{
|
||||
return mClasses;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<ESM::Faction>& CSMWorld::Data::getFactions() const
|
||||
{
|
||||
return mFactions;
|
||||
}
|
||||
|
||||
CSMWorld::IdCollection<ESM::Faction>& CSMWorld::Data::getFactions()
|
||||
{
|
||||
return mFactions;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<ESM::Race>& CSMWorld::Data::getRaces() const
|
||||
{
|
||||
return mRaces;
|
||||
}
|
||||
|
||||
CSMWorld::IdCollection<ESM::Race>& CSMWorld::Data::getRaces()
|
||||
{
|
||||
return mRaces;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<ESM::Sound>& CSMWorld::Data::getSounds() const
|
||||
{
|
||||
return mSounds;
|
||||
}
|
||||
|
||||
CSMWorld::IdCollection<ESM::Sound>& CSMWorld::Data::getSounds()
|
||||
{
|
||||
return mSounds;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<ESM::Script>& CSMWorld::Data::getScripts() const
|
||||
{
|
||||
return mScripts;
|
||||
}
|
||||
|
||||
CSMWorld::IdCollection<ESM::Script>& CSMWorld::Data::getScripts()
|
||||
{
|
||||
return mScripts;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<ESM::Region>& CSMWorld::Data::getRegions() const
|
||||
{
|
||||
return mRegions;
|
||||
}
|
||||
|
||||
CSMWorld::IdCollection<ESM::Region>& CSMWorld::Data::getRegions()
|
||||
{
|
||||
return mRegions;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<ESM::BirthSign>& CSMWorld::Data::getBirthsigns() const
|
||||
{
|
||||
return mBirthsigns;
|
||||
}
|
||||
|
||||
CSMWorld::IdCollection<ESM::BirthSign>& CSMWorld::Data::getBirthsigns()
|
||||
{
|
||||
return mBirthsigns;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<ESM::Spell>& CSMWorld::Data::getSpells() const
|
||||
{
|
||||
return mSpells;
|
||||
}
|
||||
|
||||
CSMWorld::IdCollection<ESM::Spell>& CSMWorld::Data::getSpells()
|
||||
{
|
||||
return mSpells;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<CSMWorld::Cell>& CSMWorld::Data::getCells() const
|
||||
{
|
||||
return mCells;
|
||||
}
|
||||
|
||||
CSMWorld::IdCollection<CSMWorld::Cell>& CSMWorld::Data::getCells()
|
||||
{
|
||||
return mCells;
|
||||
}
|
||||
|
||||
const CSMWorld::RefIdCollection& CSMWorld::Data::getReferenceables() const
|
||||
{
|
||||
return mReferenceables;
|
||||
}
|
||||
|
||||
CSMWorld::RefIdCollection& CSMWorld::Data::getReferenceables()
|
||||
{
|
||||
return mReferenceables;
|
||||
}
|
||||
|
||||
QAbstractItemModel *CSMWorld::Data::getTableModel (const UniversalId& id)
|
||||
{
|
||||
std::map<UniversalId::Type, QAbstractItemModel *>::iterator iter = mModelIndex.find (id.getType());
|
||||
|
||||
if (iter==mModelIndex.end())
|
||||
throw std::logic_error ("No table model available for " + id.toString());
|
||||
|
@ -102,7 +316,40 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base)
|
|||
{
|
||||
case ESM::REC_GLOB: mGlobals.load (reader, base); break;
|
||||
case ESM::REC_GMST: mGmsts.load (reader, base); break;
|
||||
case ESM::REC_SKIL: mSkills.load (reader, base); break;
|
||||
case ESM::REC_CLAS: mClasses.load (reader, base); break;
|
||||
case ESM::REC_FACT: mFactions.load (reader, base); break;
|
||||
case ESM::REC_RACE: mRaces.load (reader, base); break;
|
||||
case ESM::REC_SOUN: mSounds.load (reader, base); break;
|
||||
case ESM::REC_SCPT: mScripts.load (reader, base); break;
|
||||
case ESM::REC_REGN: mRegions.load (reader, base); break;
|
||||
case ESM::REC_BSGN: mBirthsigns.load (reader, base); break;
|
||||
case ESM::REC_SPEL: mSpells.load (reader, base); break;
|
||||
case ESM::REC_CELL: mCells.load (reader, base); break;
|
||||
|
||||
case ESM::REC_ACTI: mReferenceables.load (reader, base, UniversalId::Type_Activator); break;
|
||||
case ESM::REC_ALCH: mReferenceables.load (reader, base, UniversalId::Type_Potion); break;
|
||||
case ESM::REC_APPA: mReferenceables.load (reader, base, UniversalId::Type_Apparatus); break;
|
||||
case ESM::REC_ARMO: mReferenceables.load (reader, base, UniversalId::Type_Armor); break;
|
||||
case ESM::REC_BOOK: mReferenceables.load (reader, base, UniversalId::Type_Book); break;
|
||||
case ESM::REC_CLOT: mReferenceables.load (reader, base, UniversalId::Type_Clothing); break;
|
||||
case ESM::REC_CONT: mReferenceables.load (reader, base, UniversalId::Type_Container); break;
|
||||
case ESM::REC_CREA: mReferenceables.load (reader, base, UniversalId::Type_Creature); break;
|
||||
case ESM::REC_DOOR: mReferenceables.load (reader, base, UniversalId::Type_Door); break;
|
||||
case ESM::REC_INGR: mReferenceables.load (reader, base, UniversalId::Type_Ingredient); break;
|
||||
case ESM::REC_LEVC:
|
||||
mReferenceables.load (reader, base, UniversalId::Type_CreatureLevelledList); break;
|
||||
case ESM::REC_LEVI:
|
||||
mReferenceables.load (reader, base, UniversalId::Type_ItemLevelledList); break;
|
||||
case ESM::REC_LIGH: mReferenceables.load (reader, base, UniversalId::Type_Light); break;
|
||||
case ESM::REC_LOCK: mReferenceables.load (reader, base, UniversalId::Type_Lockpick); break;
|
||||
case ESM::REC_MISC:
|
||||
mReferenceables.load (reader, base, UniversalId::Type_Miscellaneous); break;
|
||||
case ESM::REC_NPC_: mReferenceables.load (reader, base, UniversalId::Type_Npc); break;
|
||||
case ESM::REC_PROB: mReferenceables.load (reader, base, UniversalId::Type_Probe); break;
|
||||
case ESM::REC_REPA: mReferenceables.load (reader, base, UniversalId::Type_Repair); break;
|
||||
case ESM::REC_STAT: mReferenceables.load (reader, base, UniversalId::Type_Static); break;
|
||||
case ESM::REC_WEAP: mReferenceables.load (reader, base, UniversalId::Type_Weapon); break;
|
||||
|
||||
default:
|
||||
|
||||
|
|
|
@ -8,11 +8,22 @@
|
|||
|
||||
#include <components/esm/loadglob.hpp>
|
||||
#include <components/esm/loadgmst.hpp>
|
||||
#include <components/esm/loadskil.hpp>
|
||||
#include <components/esm/loadclas.hpp>
|
||||
#include <components/esm/loadfact.hpp>
|
||||
#include <components/esm/loadrace.hpp>
|
||||
#include <components/esm/loadsoun.hpp>
|
||||
#include <components/esm/loadscpt.hpp>
|
||||
#include <components/esm/loadregn.hpp>
|
||||
#include <components/esm/loadbsgn.hpp>
|
||||
#include <components/esm/loadspel.hpp>
|
||||
|
||||
#include "idcollection.hpp"
|
||||
#include "universalid.hpp"
|
||||
#include "cell.hpp"
|
||||
#include "refidcollection.hpp"
|
||||
|
||||
class QAbstractTableModel;
|
||||
class QAbstractItemModel;
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
|
@ -20,14 +31,25 @@ namespace CSMWorld
|
|||
{
|
||||
IdCollection<ESM::Global> mGlobals;
|
||||
IdCollection<ESM::GameSetting> mGmsts;
|
||||
std::vector<QAbstractTableModel *> mModels;
|
||||
std::map<UniversalId::Type, QAbstractTableModel *> mModelIndex;
|
||||
IdCollection<ESM::Skill> mSkills;
|
||||
IdCollection<ESM::Class> mClasses;
|
||||
IdCollection<ESM::Faction> mFactions;
|
||||
IdCollection<ESM::Race> mRaces;
|
||||
IdCollection<ESM::Sound> mSounds;
|
||||
IdCollection<ESM::Script> mScripts;
|
||||
IdCollection<ESM::Region> mRegions;
|
||||
IdCollection<ESM::BirthSign> mBirthsigns;
|
||||
IdCollection<ESM::Spell> mSpells;
|
||||
IdCollection<Cell> mCells;
|
||||
RefIdCollection mReferenceables;
|
||||
std::vector<QAbstractItemModel *> mModels;
|
||||
std::map<UniversalId::Type, QAbstractItemModel *> mModelIndex;
|
||||
|
||||
// not implemented
|
||||
Data (const Data&);
|
||||
Data& operator= (const Data&);
|
||||
|
||||
void addModel (QAbstractTableModel *model, UniversalId::Type type1,
|
||||
void addModel (QAbstractItemModel *model, UniversalId::Type type1,
|
||||
UniversalId::Type type2 = UniversalId::Type_None);
|
||||
|
||||
public:
|
||||
|
@ -44,7 +66,51 @@ namespace CSMWorld
|
|||
|
||||
IdCollection<ESM::GameSetting>& getGmsts();
|
||||
|
||||
QAbstractTableModel *getTableModel (const UniversalId& id);
|
||||
const IdCollection<ESM::Skill>& getSkills() const;
|
||||
|
||||
IdCollection<ESM::Skill>& getSkills();
|
||||
|
||||
const IdCollection<ESM::Class>& getClasses() const;
|
||||
|
||||
IdCollection<ESM::Class>& getClasses();
|
||||
|
||||
const IdCollection<ESM::Faction>& getFactions() const;
|
||||
|
||||
IdCollection<ESM::Faction>& getFactions();
|
||||
|
||||
const IdCollection<ESM::Race>& getRaces() const;
|
||||
|
||||
IdCollection<ESM::Race>& getRaces();
|
||||
|
||||
const IdCollection<ESM::Sound>& getSounds() const;
|
||||
|
||||
IdCollection<ESM::Sound>& getSounds();
|
||||
|
||||
const IdCollection<ESM::Script>& getScripts() const;
|
||||
|
||||
IdCollection<ESM::Script>& getScripts();
|
||||
|
||||
const IdCollection<ESM::Region>& getRegions() const;
|
||||
|
||||
IdCollection<ESM::Region>& getRegions();
|
||||
|
||||
const IdCollection<ESM::BirthSign>& getBirthsigns() const;
|
||||
|
||||
IdCollection<ESM::BirthSign>& getBirthsigns();
|
||||
|
||||
const IdCollection<ESM::Spell>& getSpells() const;
|
||||
|
||||
IdCollection<ESM::Spell>& getSpells();
|
||||
|
||||
const IdCollection<Cell>& getCells() const;
|
||||
|
||||
IdCollection<Cell>& getCells();
|
||||
|
||||
const RefIdCollection& getReferenceables() const;
|
||||
|
||||
RefIdCollection& getReferenceables();
|
||||
|
||||
QAbstractItemModel *getTableModel (const UniversalId& id);
|
||||
///< If no table model is available for \a id, an exception is thrown.
|
||||
///
|
||||
/// \note The returned table may either be the model for the ID itself or the model that
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <components/misc/stringops.hpp>
|
||||
|
||||
#include "columnbase.hpp"
|
||||
#include "universalid.hpp"
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
|
@ -45,15 +46,19 @@ namespace CSMWorld
|
|||
|
||||
virtual void setData (int index, int column, const QVariant& data) = 0;
|
||||
|
||||
virtual void merge() = 0;
|
||||
// Not in use. Temporarily removed so that the implementation of RefIdCollection can continue without
|
||||
// these functions for now.
|
||||
// virtual void merge() = 0;
|
||||
///< Merge modified into base.
|
||||
|
||||
virtual void purge() = 0;
|
||||
// virtual void purge() = 0;
|
||||
///< Remove records that are flagged as erased.
|
||||
|
||||
virtual void removeRows (int index, int count) = 0;
|
||||
|
||||
virtual void appendBlankRecord (const std::string& id) = 0;
|
||||
virtual void appendBlankRecord (const std::string& id,
|
||||
UniversalId::Type type = UniversalId::Type_None) = 0;
|
||||
///< \param type Will be ignored, unless the collection supports multiple record types
|
||||
|
||||
virtual int searchId (const std::string& id) const = 0;
|
||||
////< Search record with \a id.
|
||||
|
@ -63,22 +68,47 @@ namespace CSMWorld
|
|||
///< If the record type does not match, an exception is thrown.
|
||||
///
|
||||
/// \attention \a record must not change the ID.
|
||||
///< \param type Will be ignored, unless the collection supports multiple record types
|
||||
|
||||
virtual void appendRecord (const RecordBase& record) = 0;
|
||||
virtual void appendRecord (const RecordBase& record,
|
||||
UniversalId::Type type = UniversalId::Type_None) = 0;
|
||||
///< If the record type does not match, an exception is thrown.
|
||||
|
||||
virtual std::string getId (const RecordBase& record) const = 0;
|
||||
///< Return ID for \a record.
|
||||
///
|
||||
/// \attention Throws an exception, if the type of \a record does not match.
|
||||
|
||||
virtual const RecordBase& getRecord (const std::string& id) const = 0;
|
||||
|
||||
virtual void load (ESM::ESMReader& reader, bool base) = 0;
|
||||
virtual const RecordBase& getRecord (int index) const = 0;
|
||||
|
||||
virtual void load (ESM::ESMReader& reader, bool base,
|
||||
UniversalId::Type type = UniversalId::Type_None) = 0;
|
||||
///< \param type Will be ignored, unless the collection supports multiple record types
|
||||
|
||||
virtual int getAppendIndex (UniversalId::Type type = UniversalId::Type_None) const = 0;
|
||||
///< \param type Will be ignored, unless the collection supports multiple record types
|
||||
};
|
||||
|
||||
///< \brief Collection of ID-based records
|
||||
///< \brief Access to ID field in records
|
||||
template<typename ESXRecordT>
|
||||
struct IdAccessor
|
||||
{
|
||||
std::string& getId (ESXRecordT& record);
|
||||
|
||||
const std::string getId (const ESXRecordT& record) const;
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
std::string& IdAccessor<ESXRecordT>::getId (ESXRecordT& record)
|
||||
{
|
||||
return record.mId;
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
const std::string IdAccessor<ESXRecordT>::getId (const ESXRecordT& record) const
|
||||
{
|
||||
return record.mId;
|
||||
}
|
||||
|
||||
///< \brief Collection of ID-based records
|
||||
template<typename ESXRecordT, typename IdAccessorT = IdAccessor<ESXRecordT> >
|
||||
class IdCollection : public IdCollectionBase
|
||||
{
|
||||
std::vector<Record<ESXRecordT> > mRecords;
|
||||
|
@ -120,7 +150,9 @@ namespace CSMWorld
|
|||
|
||||
virtual void removeRows (int index, int count) ;
|
||||
|
||||
virtual void appendBlankRecord (const std::string& id);
|
||||
virtual void appendBlankRecord (const std::string& id,
|
||||
UniversalId::Type type = UniversalId::Type_None);
|
||||
///< \param type Will be ignored, unless the collection supports multiple record types
|
||||
|
||||
virtual int searchId (const std::string& id) const;
|
||||
////< Search record with \a id.
|
||||
|
@ -131,36 +163,40 @@ namespace CSMWorld
|
|||
///
|
||||
/// \attention \a record must not change the ID.
|
||||
|
||||
virtual void appendRecord (const RecordBase& record);
|
||||
virtual void appendRecord (const RecordBase& record,
|
||||
UniversalId::Type type = UniversalId::Type_None);
|
||||
///< If the record type does not match, an exception is thrown.
|
||||
///< \param type Will be ignored, unless the collection supports multiple record types
|
||||
|
||||
virtual std::string getId (const RecordBase& record) const;
|
||||
///< Return ID for \a record.
|
||||
///
|
||||
/// \attention Throw san exception, if the type of \a record does not match.
|
||||
virtual const Record<ESXRecordT>& getRecord (const std::string& id) const;
|
||||
|
||||
virtual const RecordBase& getRecord (const std::string& id) const;
|
||||
virtual const Record<ESXRecordT>& getRecord (int index) const;
|
||||
|
||||
virtual void load (ESM::ESMReader& reader, bool base);
|
||||
virtual void load (ESM::ESMReader& reader, bool base,
|
||||
UniversalId::Type type = UniversalId::Type_None);
|
||||
///< \param type Will be ignored, unless the collection supports multiple record types
|
||||
|
||||
virtual int getAppendIndex (UniversalId::Type type = UniversalId::Type_None) const;
|
||||
///< \param type Will be ignored, unless the collection supports multiple record types
|
||||
|
||||
void addColumn (Column<ESXRecordT> *column);
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
IdCollection<ESXRecordT>::IdCollection()
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
IdCollection<ESXRecordT, IdAccessorT>::IdCollection()
|
||||
{}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
IdCollection<ESXRecordT>::~IdCollection()
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
IdCollection<ESXRecordT, IdAccessorT>::~IdCollection()
|
||||
{
|
||||
for (typename std::vector<Column<ESXRecordT> *>::iterator iter (mColumns.begin()); iter!=mColumns.end(); ++iter)
|
||||
delete *iter;
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
void IdCollection<ESXRecordT>::add (const ESXRecordT& record)
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
void IdCollection<ESXRecordT, IdAccessorT>::add (const ESXRecordT& record)
|
||||
{
|
||||
std::string id = Misc::StringUtils::lowerCase(record.mId);
|
||||
std::string id = Misc::StringUtils::lowerCase (IdAccessorT().getId (record));
|
||||
|
||||
std::map<std::string, int>::iterator iter = mIndex.find (id);
|
||||
|
||||
|
@ -179,20 +215,20 @@ namespace CSMWorld
|
|||
}
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
int IdCollection<ESXRecordT>::getSize() const
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
int IdCollection<ESXRecordT, IdAccessorT>::getSize() const
|
||||
{
|
||||
return mRecords.size();
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
std::string IdCollection<ESXRecordT>::getId (int index) const
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
std::string IdCollection<ESXRecordT, IdAccessorT>::getId (int index) const
|
||||
{
|
||||
return mRecords.at (index).get().mId;
|
||||
return IdAccessorT().getId (mRecords.at (index).get());
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
int IdCollection<ESXRecordT>::getIndex (const std::string& id) const
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
int IdCollection<ESXRecordT, IdAccessorT>::getIndex (const std::string& id) const
|
||||
{
|
||||
int index = searchId (id);
|
||||
|
||||
|
@ -202,38 +238,38 @@ namespace CSMWorld
|
|||
return index;
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
int IdCollection<ESXRecordT>::getColumns() const
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
int IdCollection<ESXRecordT, IdAccessorT>::getColumns() const
|
||||
{
|
||||
return mColumns.size();
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
QVariant IdCollection<ESXRecordT>::getData (int index, int column) const
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
QVariant IdCollection<ESXRecordT, IdAccessorT>::getData (int index, int column) const
|
||||
{
|
||||
return mColumns.at (column)->get (mRecords.at (index));
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
void IdCollection<ESXRecordT>::setData (int index, int column, const QVariant& data)
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
void IdCollection<ESXRecordT, IdAccessorT>::setData (int index, int column, const QVariant& data)
|
||||
{
|
||||
return mColumns.at (column)->set (mRecords.at (index), data);
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
const ColumnBase& IdCollection<ESXRecordT>::getColumn (int column) const
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
const ColumnBase& IdCollection<ESXRecordT, IdAccessorT>::getColumn (int column) const
|
||||
{
|
||||
return *mColumns.at (column);
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
void IdCollection<ESXRecordT>::addColumn (Column<ESXRecordT> *column)
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
void IdCollection<ESXRecordT, IdAccessorT>::addColumn (Column<ESXRecordT> *column)
|
||||
{
|
||||
mColumns.push_back (column);
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
void IdCollection<ESXRecordT>::merge()
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
void IdCollection<ESXRecordT, IdAccessorT>::merge()
|
||||
{
|
||||
for (typename std::vector<Record<ESXRecordT> >::iterator iter (mRecords.begin()); iter!=mRecords.end(); ++iter)
|
||||
iter->merge();
|
||||
|
@ -241,16 +277,22 @@ namespace CSMWorld
|
|||
purge();
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
void IdCollection<ESXRecordT>::purge()
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
void IdCollection<ESXRecordT, IdAccessorT>::purge()
|
||||
{
|
||||
mRecords.erase (std::remove_if (mRecords.begin(), mRecords.end(),
|
||||
std::mem_fun_ref (&Record<ESXRecordT>::isErased) // I want lambda :(
|
||||
), mRecords.end());
|
||||
int i = 0;
|
||||
|
||||
while (i<static_cast<int> (mRecords.size()))
|
||||
{
|
||||
if (mRecords[i].isErased())
|
||||
removeRows (i, 1);
|
||||
else
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
void IdCollection<ESXRecordT>::removeRows (int index, int count)
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
void IdCollection<ESXRecordT, IdAccessorT>::removeRows (int index, int count)
|
||||
{
|
||||
mRecords.erase (mRecords.begin()+index, mRecords.begin()+index+count);
|
||||
|
||||
|
@ -274,17 +316,18 @@ namespace CSMWorld
|
|||
}
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
void IdCollection<ESXRecordT>::appendBlankRecord (const std::string& id)
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
void IdCollection<ESXRecordT, IdAccessorT>::appendBlankRecord (const std::string& id,
|
||||
UniversalId::Type type)
|
||||
{
|
||||
ESXRecordT record;
|
||||
record.mId = id;
|
||||
IdAccessorT().getId (record) = id;
|
||||
record.blank();
|
||||
add (record);
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
int IdCollection<ESXRecordT>::searchId (const std::string& id) const
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
int IdCollection<ESXRecordT, IdAccessorT>::searchId (const std::string& id) const
|
||||
{
|
||||
std::string id2 = Misc::StringUtils::lowerCase(id);
|
||||
|
||||
|
@ -296,35 +339,32 @@ namespace CSMWorld
|
|||
return iter->second;
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
void IdCollection<ESXRecordT>::replace (int index, const RecordBase& record)
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
void IdCollection<ESXRecordT, IdAccessorT>::replace (int index, const RecordBase& record)
|
||||
{
|
||||
mRecords.at (index) = dynamic_cast<const Record<ESXRecordT>&> (record);
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
void IdCollection<ESXRecordT>::appendRecord (const RecordBase& record)
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
void IdCollection<ESXRecordT, IdAccessorT>::appendRecord (const RecordBase& record,
|
||||
UniversalId::Type type)
|
||||
{
|
||||
mRecords.push_back (dynamic_cast<const Record<ESXRecordT>&> (record));
|
||||
mIndex.insert (std::make_pair (Misc::StringUtils::lowerCase (getId (record)), mRecords.size()-1));
|
||||
mIndex.insert (std::make_pair (Misc::StringUtils::lowerCase (IdAccessorT().getId (
|
||||
dynamic_cast<const Record<ESXRecordT>&> (record).get())),
|
||||
mRecords.size()-1));
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
std::string IdCollection<ESXRecordT>::getId (const RecordBase& record) const
|
||||
{
|
||||
const Record<ESXRecordT>& record2 = dynamic_cast<const Record<ESXRecordT>&> (record);
|
||||
return (record2.isModified() ? record2.mModified : record2.mBase).mId;
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
void IdCollection<ESXRecordT>::load (ESM::ESMReader& reader, bool base)
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
void IdCollection<ESXRecordT, IdAccessorT>::load (ESM::ESMReader& reader, bool base,
|
||||
UniversalId::Type type)
|
||||
{
|
||||
std::string id = reader.getHNOString ("NAME");
|
||||
|
||||
int index = searchId (id);
|
||||
|
||||
if (reader.isNextSub ("DELE"))
|
||||
{
|
||||
int index = searchId (id);
|
||||
|
||||
reader.skipRecord();
|
||||
|
||||
if (index==-1)
|
||||
|
@ -347,9 +387,11 @@ namespace CSMWorld
|
|||
else
|
||||
{
|
||||
ESXRecordT record;
|
||||
record.mId = id;
|
||||
IdAccessorT().getId (record) = id;
|
||||
record.load (reader);
|
||||
|
||||
int index = searchId (IdAccessorT().getId (record));
|
||||
|
||||
if (index==-1)
|
||||
{
|
||||
// new record
|
||||
|
@ -372,12 +414,25 @@ namespace CSMWorld
|
|||
}
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
const RecordBase& IdCollection<ESXRecordT>::getRecord (const std::string& id) const
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
int IdCollection<ESXRecordT, IdAccessorT>::getAppendIndex (UniversalId::Type type) const
|
||||
{
|
||||
return static_cast<int> (mRecords.size());
|
||||
}
|
||||
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
const Record<ESXRecordT>& IdCollection<ESXRecordT, IdAccessorT>::getRecord (const std::string& id) const
|
||||
{
|
||||
int index = getIndex (id);
|
||||
return mRecords.at (index);
|
||||
}
|
||||
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
const Record<ESXRecordT>& IdCollection<ESXRecordT, IdAccessorT>::getRecord (int index) const
|
||||
{
|
||||
return mRecords.at (index);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -96,9 +96,28 @@ bool CSMWorld::IdTable::removeRows (int row, int count, const QModelIndex& paren
|
|||
return true;
|
||||
}
|
||||
|
||||
QModelIndex CSMWorld::IdTable::index (int row, int column, const QModelIndex& parent) const
|
||||
{
|
||||
if (parent.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
if (row<0 || row>=mIdCollection->getSize())
|
||||
return QModelIndex();
|
||||
|
||||
if (column<0 || column>=mIdCollection->getColumns())
|
||||
return QModelIndex();
|
||||
|
||||
return createIndex (row, column);
|
||||
}
|
||||
|
||||
QModelIndex CSMWorld::IdTable::parent (const QModelIndex& index) const
|
||||
{
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
void CSMWorld::IdTable::addRecord (const std::string& id)
|
||||
{
|
||||
int index = mIdCollection->getSize();
|
||||
int index = mIdCollection->getAppendIndex();
|
||||
|
||||
beginInsertRows (QModelIndex(), index, index);
|
||||
|
||||
|
@ -112,13 +131,13 @@ QModelIndex CSMWorld::IdTable::getModelIndex (const std::string& id, int column)
|
|||
return index (mIdCollection->getIndex (id), column);
|
||||
}
|
||||
|
||||
void CSMWorld::IdTable::setRecord (const RecordBase& record)
|
||||
void CSMWorld::IdTable::setRecord (const std::string& id, const RecordBase& record)
|
||||
{
|
||||
int index = mIdCollection->searchId (mIdCollection->getId (record));
|
||||
int index = mIdCollection->searchId (id);
|
||||
|
||||
if (index==-1)
|
||||
{
|
||||
int index = mIdCollection->getSize();
|
||||
int index = mIdCollection->getAppendIndex();
|
||||
|
||||
beginInsertRows (QModelIndex(), index, index);
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
#ifndef CSM_WOLRD_IDTABLE_H
|
||||
#define CSM_WOLRD_IDTABLE_H
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class IdCollectionBase;
|
||||
class RecordBase;
|
||||
|
||||
class IdTable : public QAbstractTableModel
|
||||
class IdTable : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -39,11 +39,16 @@ namespace CSMWorld
|
|||
|
||||
virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex());
|
||||
|
||||
virtual QModelIndex index (int row, int column, const QModelIndex& parent = QModelIndex())
|
||||
const;
|
||||
|
||||
virtual QModelIndex parent (const QModelIndex& index) const;
|
||||
|
||||
void addRecord (const std::string& id);
|
||||
|
||||
QModelIndex getModelIndex (const std::string& id, int column) const;
|
||||
|
||||
void setRecord (const RecordBase& record);
|
||||
void setRecord (const std::string& id, const RecordBase& record);
|
||||
///< Add record or overwrite existing recrod.
|
||||
|
||||
const RecordBase& getRecord (const std::string& id) const;
|
||||
|
|
|
@ -22,6 +22,9 @@ namespace CSMWorld
|
|||
|
||||
virtual RecordBase *clone() const = 0;
|
||||
|
||||
virtual void assign (const RecordBase& record) = 0;
|
||||
///< Will throw an exception if the types don't match.
|
||||
|
||||
bool isDeleted() const;
|
||||
|
||||
bool isErased() const;
|
||||
|
@ -37,9 +40,14 @@ namespace CSMWorld
|
|||
|
||||
virtual RecordBase *clone() const;
|
||||
|
||||
virtual void assign (const RecordBase& record);
|
||||
|
||||
const ESXRecordT& get() const;
|
||||
///< Throws an exception, if the record is deleted.
|
||||
|
||||
ESXRecordT& get();
|
||||
///< Throws an exception, if the record is deleted.
|
||||
|
||||
const ESXRecordT& getBase() const;
|
||||
///< Throws an exception, if the record is deleted. Returns modified, if there is no base.
|
||||
|
||||
|
@ -56,13 +64,28 @@ namespace CSMWorld
|
|||
return new Record<ESXRecordT> (*this);
|
||||
}
|
||||
|
||||
template <typename ESXRecordT>
|
||||
void Record<ESXRecordT>::assign (const RecordBase& record)
|
||||
{
|
||||
*this = dynamic_cast<const Record<ESXRecordT>& > (record);
|
||||
}
|
||||
|
||||
template <typename ESXRecordT>
|
||||
const ESXRecordT& Record<ESXRecordT>::get() const
|
||||
{
|
||||
if (mState==State_Erased)
|
||||
throw std::logic_error ("attempt to access a deleted record");
|
||||
|
||||
return mState==State_BaseOnly ? mBase : mModified;
|
||||
return mState==State_BaseOnly || mState==State_Deleted ? mBase : mModified;
|
||||
}
|
||||
|
||||
template <typename ESXRecordT>
|
||||
ESXRecordT& Record<ESXRecordT>::get()
|
||||
{
|
||||
if (mState==State_Erased)
|
||||
throw std::logic_error ("attempt to access a deleted record");
|
||||
|
||||
return mState==State_BaseOnly || mState==State_Deleted ? mBase : mModified;
|
||||
}
|
||||
|
||||
template <typename ESXRecordT>
|
||||
|
@ -83,7 +106,7 @@ namespace CSMWorld
|
|||
mModified = modified;
|
||||
|
||||
if (mState!=State_ModifiedOnly)
|
||||
mState = mBase==mModified ? State_BaseOnly : State_Modified;
|
||||
mState = State_Modified;
|
||||
}
|
||||
|
||||
template <typename ESXRecordT>
|
||||
|
|
6
apps/opencs/model/world/refidadapter.cpp
Normal file
6
apps/opencs/model/world/refidadapter.cpp
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
#include "refidadapter.hpp"
|
||||
|
||||
CSMWorld::RefIdAdapter::RefIdAdapter() {}
|
||||
|
||||
CSMWorld::RefIdAdapter::~RefIdAdapter() {}
|
37
apps/opencs/model/world/refidadapter.hpp
Normal file
37
apps/opencs/model/world/refidadapter.hpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
#ifndef CSM_WOLRD_REFIDADAPTER_H
|
||||
#define CSM_WOLRD_REFIDADAPTER_H
|
||||
|
||||
#include <string>
|
||||
|
||||
class QVariant;
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class RefIdColumn;
|
||||
class RefIdData;
|
||||
class RecordBase;
|
||||
|
||||
class RefIdAdapter
|
||||
{
|
||||
// not implemented
|
||||
RefIdAdapter (const RefIdAdapter&);
|
||||
RefIdAdapter& operator= (const RefIdAdapter&);
|
||||
|
||||
public:
|
||||
|
||||
RefIdAdapter();
|
||||
|
||||
virtual ~RefIdAdapter();
|
||||
|
||||
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int idnex)
|
||||
const = 0;
|
||||
|
||||
virtual void setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const = 0;
|
||||
///< If the data type does not match an exception is thrown.
|
||||
|
||||
virtual std::string getId (const RecordBase& record) const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
575
apps/opencs/model/world/refidadapterimp.cpp
Normal file
575
apps/opencs/model/world/refidadapterimp.cpp
Normal file
|
@ -0,0 +1,575 @@
|
|||
|
||||
#include "refidadapterimp.hpp"
|
||||
|
||||
CSMWorld::PotionRefIdAdapter::PotionRefIdAdapter (const InventoryColumns& columns,
|
||||
const RefIdColumn *autoCalc)
|
||||
: InventoryRefIdAdapter<ESM::Potion> (UniversalId::Type_Potion, columns),
|
||||
mAutoCalc (autoCalc)
|
||||
{}
|
||||
|
||||
QVariant CSMWorld::PotionRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data,
|
||||
int index) const
|
||||
{
|
||||
const Record<ESM::Potion>& record = static_cast<const Record<ESM::Potion>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Potion)));
|
||||
|
||||
if (column==mAutoCalc)
|
||||
return record.get().mData.mAutoCalc!=0;
|
||||
|
||||
return InventoryRefIdAdapter<ESM::Potion>::getData (column, data, index);
|
||||
}
|
||||
|
||||
void CSMWorld::PotionRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const
|
||||
{
|
||||
Record<ESM::Potion>& record = static_cast<Record<ESM::Potion>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Potion)));
|
||||
|
||||
if (column==mAutoCalc)
|
||||
record.get().mData.mAutoCalc = value.toInt();
|
||||
else
|
||||
InventoryRefIdAdapter<ESM::Potion>::setData (column, data, index, value);
|
||||
}
|
||||
|
||||
|
||||
CSMWorld::ApparatusRefIdAdapter::ApparatusRefIdAdapter (const InventoryColumns& columns,
|
||||
const RefIdColumn *type, const RefIdColumn *quality)
|
||||
: InventoryRefIdAdapter<ESM::Apparatus> (UniversalId::Type_Apparatus, columns),
|
||||
mType (type), mQuality (quality)
|
||||
{}
|
||||
|
||||
QVariant CSMWorld::ApparatusRefIdAdapter::getData (const RefIdColumn *column,
|
||||
const RefIdData& data, int index) const
|
||||
{
|
||||
const Record<ESM::Apparatus>& record = static_cast<const Record<ESM::Apparatus>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Apparatus)));
|
||||
|
||||
if (column==mType)
|
||||
return record.get().mData.mType;
|
||||
|
||||
if (column==mQuality)
|
||||
return record.get().mData.mQuality;
|
||||
|
||||
return InventoryRefIdAdapter<ESM::Apparatus>::getData (column, data, index);
|
||||
}
|
||||
|
||||
void CSMWorld::ApparatusRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const
|
||||
{
|
||||
Record<ESM::Apparatus>& record = static_cast<Record<ESM::Apparatus>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Apparatus)));
|
||||
|
||||
if (column==mType)
|
||||
record.get().mData.mType = value.toInt();
|
||||
else if (column==mQuality)
|
||||
record.get().mData.mQuality = value.toFloat();
|
||||
else
|
||||
InventoryRefIdAdapter<ESM::Apparatus>::setData (column, data, index, value);
|
||||
}
|
||||
|
||||
|
||||
CSMWorld::ArmorRefIdAdapter::ArmorRefIdAdapter (const EnchantableColumns& columns,
|
||||
const RefIdColumn *type, const RefIdColumn *health, const RefIdColumn *armor)
|
||||
: EnchantableRefIdAdapter<ESM::Armor> (UniversalId::Type_Armor, columns),
|
||||
mType (type), mHealth (health), mArmor (armor)
|
||||
{}
|
||||
|
||||
QVariant CSMWorld::ArmorRefIdAdapter::getData (const RefIdColumn *column,
|
||||
const RefIdData& data, int index) const
|
||||
{
|
||||
const Record<ESM::Armor>& record = static_cast<const Record<ESM::Armor>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Armor)));
|
||||
|
||||
if (column==mType)
|
||||
return record.get().mData.mType;
|
||||
|
||||
if (column==mHealth)
|
||||
return record.get().mData.mHealth;
|
||||
|
||||
if (column==mArmor)
|
||||
return record.get().mData.mArmor;
|
||||
|
||||
return EnchantableRefIdAdapter<ESM::Armor>::getData (column, data, index);
|
||||
}
|
||||
|
||||
void CSMWorld::ArmorRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const
|
||||
{
|
||||
Record<ESM::Armor>& record = static_cast<Record<ESM::Armor>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Armor)));
|
||||
|
||||
if (column==mType)
|
||||
record.get().mData.mType = value.toInt();
|
||||
else if (column==mHealth)
|
||||
record.get().mData.mHealth = value.toInt();
|
||||
else if (column==mArmor)
|
||||
record.get().mData.mArmor = value.toInt();
|
||||
else
|
||||
EnchantableRefIdAdapter<ESM::Armor>::setData (column, data, index, value);
|
||||
}
|
||||
|
||||
CSMWorld::BookRefIdAdapter::BookRefIdAdapter (const EnchantableColumns& columns,
|
||||
const RefIdColumn *scroll, const RefIdColumn *skill)
|
||||
: EnchantableRefIdAdapter<ESM::Book> (UniversalId::Type_Book, columns),
|
||||
mScroll (scroll), mSkill (skill)
|
||||
{}
|
||||
|
||||
QVariant CSMWorld::BookRefIdAdapter::getData (const RefIdColumn *column,
|
||||
const RefIdData& data, int index) const
|
||||
{
|
||||
const Record<ESM::Book>& record = static_cast<const Record<ESM::Book>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Book)));
|
||||
|
||||
if (column==mScroll)
|
||||
return record.get().mData.mIsScroll!=0;
|
||||
|
||||
if (column==mSkill)
|
||||
return record.get().mData.mSkillID;
|
||||
|
||||
return EnchantableRefIdAdapter<ESM::Book>::getData (column, data, index);
|
||||
}
|
||||
|
||||
void CSMWorld::BookRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const
|
||||
{
|
||||
Record<ESM::Book>& record = static_cast<Record<ESM::Book>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Book)));
|
||||
|
||||
if (column==mScroll)
|
||||
record.get().mData.mIsScroll = value.toInt();
|
||||
else if (column==mSkill)
|
||||
record.get().mData.mSkillID = value.toInt();
|
||||
else
|
||||
EnchantableRefIdAdapter<ESM::Book>::setData (column, data, index, value);
|
||||
}
|
||||
|
||||
CSMWorld::ClothingRefIdAdapter::ClothingRefIdAdapter (const EnchantableColumns& columns,
|
||||
const RefIdColumn *type)
|
||||
: EnchantableRefIdAdapter<ESM::Clothing> (UniversalId::Type_Clothing, columns), mType (type)
|
||||
{}
|
||||
|
||||
QVariant CSMWorld::ClothingRefIdAdapter::getData (const RefIdColumn *column,
|
||||
const RefIdData& data, int index) const
|
||||
{
|
||||
const Record<ESM::Clothing>& record = static_cast<const Record<ESM::Clothing>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Clothing)));
|
||||
|
||||
if (column==mType)
|
||||
return record.get().mData.mType;
|
||||
|
||||
return EnchantableRefIdAdapter<ESM::Clothing>::getData (column, data, index);
|
||||
}
|
||||
|
||||
void CSMWorld::ClothingRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const
|
||||
{
|
||||
Record<ESM::Clothing>& record = static_cast<Record<ESM::Clothing>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Clothing)));
|
||||
|
||||
if (column==mType)
|
||||
record.get().mData.mType = value.toInt();
|
||||
else
|
||||
EnchantableRefIdAdapter<ESM::Clothing>::setData (column, data, index, value);
|
||||
}
|
||||
|
||||
CSMWorld::ContainerRefIdAdapter::ContainerRefIdAdapter (const NameColumns& columns,
|
||||
const RefIdColumn *weight, const RefIdColumn *organic, const RefIdColumn *respawn)
|
||||
: NameRefIdAdapter<ESM::Container> (UniversalId::Type_Container, columns), mWeight (weight),
|
||||
mOrganic (organic), mRespawn (respawn)
|
||||
{}
|
||||
|
||||
QVariant CSMWorld::ContainerRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data,
|
||||
int index) const
|
||||
{
|
||||
const Record<ESM::Container>& record = static_cast<const Record<ESM::Container>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container)));
|
||||
|
||||
if (column==mWeight)
|
||||
return record.get().mWeight;
|
||||
|
||||
if (column==mOrganic)
|
||||
return (record.get().mFlags & ESM::Container::Organic)!=0;
|
||||
|
||||
if (column==mRespawn)
|
||||
return (record.get().mFlags & ESM::Container::Respawn)!=0;
|
||||
|
||||
return NameRefIdAdapter<ESM::Container>::getData (column, data, index);
|
||||
}
|
||||
|
||||
void CSMWorld::ContainerRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const
|
||||
{
|
||||
Record<ESM::Container>& record = static_cast<Record<ESM::Container>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container)));
|
||||
|
||||
if (column==mWeight)
|
||||
record.get().mWeight = value.toFloat();
|
||||
else if (column==mOrganic)
|
||||
{
|
||||
if (value.toInt())
|
||||
record.get().mFlags |= ESM::Container::Organic;
|
||||
else
|
||||
record.get().mFlags &= ~ESM::Container::Organic;
|
||||
}
|
||||
else if (column==mRespawn)
|
||||
{
|
||||
if (value.toInt())
|
||||
record.get().mFlags |= ESM::Container::Respawn;
|
||||
else
|
||||
record.get().mFlags &= ~ESM::Container::Respawn;
|
||||
}
|
||||
else
|
||||
NameRefIdAdapter<ESM::Container>::setData (column, data, index, value);
|
||||
}
|
||||
|
||||
CSMWorld::CreatureColumns::CreatureColumns (const ActorColumns& actorColumns)
|
||||
: ActorColumns (actorColumns)
|
||||
{}
|
||||
|
||||
CSMWorld::CreatureRefIdAdapter::CreatureRefIdAdapter (const CreatureColumns& columns)
|
||||
: ActorRefIdAdapter<ESM::Creature> (UniversalId::Type_Creature, columns), mColumns (columns)
|
||||
{}
|
||||
|
||||
QVariant CSMWorld::CreatureRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data,
|
||||
int index) const
|
||||
{
|
||||
const Record<ESM::Creature>& record = static_cast<const Record<ESM::Creature>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature)));
|
||||
|
||||
if (column==mColumns.mType)
|
||||
return record.get().mData.mType;
|
||||
|
||||
if (column==mColumns.mSoul)
|
||||
return record.get().mData.mSoul;
|
||||
|
||||
if (column==mColumns.mScale)
|
||||
return record.get().mScale;
|
||||
|
||||
if (column==mColumns.mOriginal)
|
||||
return QString::fromUtf8 (record.get().mOriginal.c_str());
|
||||
|
||||
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
||||
mColumns.mFlags.find (column);
|
||||
|
||||
if (iter!=mColumns.mFlags.end())
|
||||
return (record.get().mFlags & iter->second)!=0;
|
||||
|
||||
return ActorRefIdAdapter<ESM::Creature>::getData (column, data, index);
|
||||
}
|
||||
|
||||
void CSMWorld::CreatureRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const
|
||||
{
|
||||
Record<ESM::Creature>& record = static_cast<Record<ESM::Creature>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature)));
|
||||
|
||||
if (column==mColumns.mType)
|
||||
record.get().mData.mType = value.toInt();
|
||||
else if (column==mColumns.mSoul)
|
||||
record.get().mData.mSoul = value.toInt();
|
||||
else if (column==mColumns.mScale)
|
||||
record.get().mScale = value.toFloat();
|
||||
else if (column==mColumns.mOriginal)
|
||||
record.get().mOriginal = value.toString().toUtf8().constData();
|
||||
else
|
||||
{
|
||||
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
||||
mColumns.mFlags.find (column);
|
||||
|
||||
if (iter!=mColumns.mFlags.end())
|
||||
{
|
||||
if (value.toInt()!=0)
|
||||
record.get().mFlags |= iter->second;
|
||||
else
|
||||
record.get().mFlags &= ~iter->second;
|
||||
}
|
||||
else
|
||||
ActorRefIdAdapter<ESM::Creature>::setData (column, data, index, value);
|
||||
}
|
||||
}
|
||||
|
||||
CSMWorld::DoorRefIdAdapter::DoorRefIdAdapter (const NameColumns& columns,
|
||||
const RefIdColumn *openSound, const RefIdColumn *closeSound)
|
||||
: NameRefIdAdapter<ESM::Door> (UniversalId::Type_Door, columns), mOpenSound (openSound),
|
||||
mCloseSound (closeSound)
|
||||
{}
|
||||
|
||||
QVariant CSMWorld::DoorRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data,
|
||||
int index) const
|
||||
{
|
||||
const Record<ESM::Door>& record = static_cast<const Record<ESM::Door>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Door)));
|
||||
|
||||
if (column==mOpenSound)
|
||||
return QString::fromUtf8 (record.get().mOpenSound.c_str());
|
||||
|
||||
if (column==mCloseSound)
|
||||
return QString::fromUtf8 (record.get().mCloseSound.c_str());
|
||||
|
||||
return NameRefIdAdapter<ESM::Door>::getData (column, data, index);
|
||||
}
|
||||
|
||||
void CSMWorld::DoorRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const
|
||||
{
|
||||
Record<ESM::Door>& record = static_cast<Record<ESM::Door>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Door)));
|
||||
|
||||
if (column==mOpenSound)
|
||||
record.get().mOpenSound = value.toString().toUtf8().constData();
|
||||
else if (column==mCloseSound)
|
||||
record.get().mCloseSound = value.toString().toUtf8().constData();
|
||||
else
|
||||
NameRefIdAdapter<ESM::Door>::setData (column, data, index, value);
|
||||
}
|
||||
|
||||
CSMWorld::LightColumns::LightColumns (const InventoryColumns& columns)
|
||||
: InventoryColumns (columns) {}
|
||||
|
||||
CSMWorld::LightRefIdAdapter::LightRefIdAdapter (const LightColumns& columns)
|
||||
: InventoryRefIdAdapter<ESM::Light> (UniversalId::Type_Light, columns), mColumns (columns)
|
||||
{}
|
||||
|
||||
QVariant CSMWorld::LightRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data,
|
||||
int index) const
|
||||
{
|
||||
const Record<ESM::Light>& record = static_cast<const Record<ESM::Light>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Light)));
|
||||
|
||||
if (column==mColumns.mTime)
|
||||
return record.get().mData.mTime;
|
||||
|
||||
if (column==mColumns.mRadius)
|
||||
return record.get().mData.mRadius;
|
||||
|
||||
if (column==mColumns.mColor)
|
||||
return record.get().mData.mColor;
|
||||
|
||||
if (column==mColumns.mSound)
|
||||
return QString::fromUtf8 (record.get().mSound.c_str());
|
||||
|
||||
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
||||
mColumns.mFlags.find (column);
|
||||
|
||||
if (iter!=mColumns.mFlags.end())
|
||||
return (record.get().mData.mFlags & iter->second)!=0;
|
||||
|
||||
return InventoryRefIdAdapter<ESM::Light>::getData (column, data, index);
|
||||
}
|
||||
|
||||
void CSMWorld::LightRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const
|
||||
{
|
||||
Record<ESM::Light>& record = static_cast<Record<ESM::Light>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Light)));
|
||||
|
||||
if (column==mColumns.mTime)
|
||||
record.get().mData.mTime = value.toInt();
|
||||
else if (column==mColumns.mRadius)
|
||||
record.get().mData.mRadius = value.toInt();
|
||||
else if (column==mColumns.mColor)
|
||||
record.get().mData.mColor = value.toInt();
|
||||
else if (column==mColumns.mSound)
|
||||
record.get().mSound = value.toString().toUtf8().constData();
|
||||
else
|
||||
{
|
||||
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
||||
mColumns.mFlags.find (column);
|
||||
|
||||
if (iter!=mColumns.mFlags.end())
|
||||
{
|
||||
if (value.toInt()!=0)
|
||||
record.get().mData.mFlags |= iter->second;
|
||||
else
|
||||
record.get().mData.mFlags &= ~iter->second;
|
||||
}
|
||||
else
|
||||
InventoryRefIdAdapter<ESM::Light>::setData (column, data, index, value);
|
||||
}
|
||||
}
|
||||
|
||||
CSMWorld::MiscRefIdAdapter::MiscRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *key)
|
||||
: InventoryRefIdAdapter<ESM::Miscellaneous> (UniversalId::Type_Miscellaneous, columns), mKey (key)
|
||||
{}
|
||||
|
||||
QVariant CSMWorld::MiscRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data,
|
||||
int index) const
|
||||
{
|
||||
const Record<ESM::Miscellaneous>& record = static_cast<const Record<ESM::Miscellaneous>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Miscellaneous)));
|
||||
|
||||
if (column==mKey)
|
||||
return record.get().mData.mIsKey!=0;
|
||||
|
||||
return InventoryRefIdAdapter<ESM::Miscellaneous>::getData (column, data, index);
|
||||
}
|
||||
|
||||
void CSMWorld::MiscRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const
|
||||
{
|
||||
Record<ESM::Miscellaneous>& record = static_cast<Record<ESM::Miscellaneous>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Miscellaneous)));
|
||||
|
||||
if (column==mKey)
|
||||
record.get().mData.mIsKey = value.toInt();
|
||||
else
|
||||
InventoryRefIdAdapter<ESM::Miscellaneous>::setData (column, data, index, value);
|
||||
}
|
||||
|
||||
CSMWorld::NpcColumns::NpcColumns (const ActorColumns& actorColumns) : ActorColumns (actorColumns) {}
|
||||
|
||||
CSMWorld::NpcRefIdAdapter::NpcRefIdAdapter (const NpcColumns& columns)
|
||||
: ActorRefIdAdapter<ESM::NPC> (UniversalId::Type_Npc, columns), mColumns (columns)
|
||||
{}
|
||||
|
||||
QVariant CSMWorld::NpcRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, int index)
|
||||
const
|
||||
{
|
||||
const Record<ESM::NPC>& record = static_cast<const Record<ESM::NPC>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc)));
|
||||
|
||||
if (column==mColumns.mRace)
|
||||
return QString::fromUtf8 (record.get().mRace.c_str());
|
||||
|
||||
if (column==mColumns.mClass)
|
||||
return QString::fromUtf8 (record.get().mClass.c_str());
|
||||
|
||||
if (column==mColumns.mFaction)
|
||||
return QString::fromUtf8 (record.get().mFaction.c_str());
|
||||
|
||||
if (column==mColumns.mHair)
|
||||
return QString::fromUtf8 (record.get().mHair.c_str());
|
||||
|
||||
if (column==mColumns.mHead)
|
||||
return QString::fromUtf8 (record.get().mHead.c_str());
|
||||
|
||||
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
||||
mColumns.mFlags.find (column);
|
||||
|
||||
if (iter!=mColumns.mFlags.end())
|
||||
return (record.get().mFlags & iter->second)!=0;
|
||||
|
||||
return ActorRefIdAdapter<ESM::NPC>::getData (column, data, index);
|
||||
}
|
||||
|
||||
void CSMWorld::NpcRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const
|
||||
{
|
||||
Record<ESM::NPC>& record = static_cast<Record<ESM::NPC>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc)));
|
||||
|
||||
if (column==mColumns.mRace)
|
||||
record.get().mRace = value.toString().toUtf8().constData();
|
||||
else if (column==mColumns.mClass)
|
||||
record.get().mClass = value.toString().toUtf8().constData();
|
||||
else if (column==mColumns.mFaction)
|
||||
record.get().mFaction = value.toString().toUtf8().constData();
|
||||
else if (column==mColumns.mHair)
|
||||
record.get().mHair = value.toString().toUtf8().constData();
|
||||
else if (column==mColumns.mHead)
|
||||
record.get().mHead = value.toString().toUtf8().constData();
|
||||
else
|
||||
{
|
||||
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
||||
mColumns.mFlags.find (column);
|
||||
|
||||
if (iter!=mColumns.mFlags.end())
|
||||
{
|
||||
if (value.toInt()!=0)
|
||||
record.get().mFlags |= iter->second;
|
||||
else
|
||||
record.get().mFlags &= ~iter->second;
|
||||
}
|
||||
else
|
||||
ActorRefIdAdapter<ESM::NPC>::setData (column, data, index, value);
|
||||
}
|
||||
}
|
||||
|
||||
CSMWorld::WeaponColumns::WeaponColumns (const EnchantableColumns& columns)
|
||||
: EnchantableColumns (columns) {}
|
||||
|
||||
CSMWorld::WeaponRefIdAdapter::WeaponRefIdAdapter (const WeaponColumns& columns)
|
||||
: EnchantableRefIdAdapter<ESM::Weapon> (UniversalId::Type_Weapon, columns), mColumns (columns)
|
||||
{}
|
||||
|
||||
QVariant CSMWorld::WeaponRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data,
|
||||
int index) const
|
||||
{
|
||||
const Record<ESM::Weapon>& record = static_cast<const Record<ESM::Weapon>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Weapon)));
|
||||
|
||||
if (column==mColumns.mType)
|
||||
return record.get().mData.mType;
|
||||
|
||||
if (column==mColumns.mHealth)
|
||||
return record.get().mData.mHealth;
|
||||
|
||||
if (column==mColumns.mSpeed)
|
||||
return record.get().mData.mSpeed;
|
||||
|
||||
if (column==mColumns.mReach)
|
||||
return record.get().mData.mReach;
|
||||
|
||||
for (int i=0; i<2; ++i)
|
||||
{
|
||||
if (column==mColumns.mChop[i])
|
||||
return record.get().mData.mChop[i];
|
||||
|
||||
if (column==mColumns.mSlash[i])
|
||||
return record.get().mData.mSlash[i];
|
||||
|
||||
if (column==mColumns.mThrust[i])
|
||||
return record.get().mData.mThrust[i];
|
||||
}
|
||||
|
||||
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
||||
mColumns.mFlags.find (column);
|
||||
|
||||
if (iter!=mColumns.mFlags.end())
|
||||
return (record.get().mData.mFlags & iter->second)!=0;
|
||||
|
||||
return EnchantableRefIdAdapter<ESM::Weapon>::getData (column, data, index);
|
||||
}
|
||||
|
||||
void CSMWorld::WeaponRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const
|
||||
{
|
||||
Record<ESM::Weapon>& record = static_cast<Record<ESM::Weapon>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Weapon)));
|
||||
|
||||
if (column==mColumns.mType)
|
||||
record.get().mData.mType = value.toInt();
|
||||
else if (column==mColumns.mHealth)
|
||||
record.get().mData.mHealth = value.toInt();
|
||||
else if (column==mColumns.mSpeed)
|
||||
record.get().mData.mSpeed = value.toFloat();
|
||||
else if (column==mColumns.mReach)
|
||||
record.get().mData.mReach = value.toFloat();
|
||||
else if (column==mColumns.mChop[0])
|
||||
record.get().mData.mChop[0] = value.toInt();
|
||||
else if (column==mColumns.mChop[1])
|
||||
record.get().mData.mChop[1] = value.toInt();
|
||||
else if (column==mColumns.mSlash[0])
|
||||
record.get().mData.mSlash[0] = value.toInt();
|
||||
else if (column==mColumns.mSlash[1])
|
||||
record.get().mData.mSlash[1] = value.toInt();
|
||||
else if (column==mColumns.mThrust[0])
|
||||
record.get().mData.mThrust[0] = value.toInt();
|
||||
else if (column==mColumns.mThrust[1])
|
||||
record.get().mData.mThrust[1] = value.toInt();
|
||||
else
|
||||
{
|
||||
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
||||
mColumns.mFlags.find (column);
|
||||
|
||||
if (iter!=mColumns.mFlags.end())
|
||||
{
|
||||
if (value.toInt()!=0)
|
||||
record.get().mData.mFlags |= iter->second;
|
||||
else
|
||||
record.get().mData.mFlags &= ~iter->second;
|
||||
}
|
||||
else
|
||||
EnchantableRefIdAdapter<ESM::Weapon>::setData (column, data, index, value);
|
||||
}
|
||||
}
|
766
apps/opencs/model/world/refidadapterimp.hpp
Normal file
766
apps/opencs/model/world/refidadapterimp.hpp
Normal file
|
@ -0,0 +1,766 @@
|
|||
#ifndef CSM_WOLRD_REFIDADAPTERIMP_H
|
||||
#define CSM_WOLRD_REFIDADAPTERIMP_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
#include <components/esm/loadalch.hpp>
|
||||
#include <components/esm/loadappa.hpp>
|
||||
|
||||
#include "record.hpp"
|
||||
#include "refiddata.hpp"
|
||||
#include "universalid.hpp"
|
||||
#include "refidadapter.hpp"
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
struct BaseColumns
|
||||
{
|
||||
const RefIdColumn *mId;
|
||||
const RefIdColumn *mModified;
|
||||
const RefIdColumn *mType;
|
||||
};
|
||||
|
||||
/// \brief Base adapter for all refereceable record types
|
||||
template<typename RecordT>
|
||||
class BaseRefIdAdapter : public RefIdAdapter
|
||||
{
|
||||
UniversalId::Type mType;
|
||||
BaseColumns mBase;
|
||||
|
||||
public:
|
||||
|
||||
BaseRefIdAdapter (UniversalId::Type type, const BaseColumns& base);
|
||||
|
||||
virtual std::string getId (const RecordBase& record) const;
|
||||
|
||||
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
|
||||
const;
|
||||
|
||||
virtual void setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const;
|
||||
///< If the data type does not match an exception is thrown.
|
||||
|
||||
UniversalId::Type getType() const;
|
||||
};
|
||||
|
||||
template<typename RecordT>
|
||||
BaseRefIdAdapter<RecordT>::BaseRefIdAdapter (UniversalId::Type type, const BaseColumns& base)
|
||||
: mType (type), mBase (base)
|
||||
{}
|
||||
|
||||
template<typename RecordT>
|
||||
std::string BaseRefIdAdapter<RecordT>::getId (const RecordBase& record) const
|
||||
{
|
||||
return dynamic_cast<const Record<RecordT>&> (record).get().mId;
|
||||
}
|
||||
|
||||
template<typename RecordT>
|
||||
QVariant BaseRefIdAdapter<RecordT>::getData (const RefIdColumn *column, const RefIdData& data,
|
||||
int index) const
|
||||
{
|
||||
const Record<RecordT>& record = static_cast<const Record<RecordT>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, mType)));
|
||||
|
||||
if (column==mBase.mId)
|
||||
return QString::fromUtf8 (record.get().mId.c_str());
|
||||
|
||||
if (column==mBase.mModified)
|
||||
{
|
||||
if (record.mState==Record<RecordT>::State_Erased)
|
||||
return static_cast<int> (Record<RecordT>::State_Deleted);
|
||||
|
||||
return static_cast<int> (record.mState);
|
||||
}
|
||||
|
||||
if (column==mBase.mType)
|
||||
return static_cast<int> (mType);
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
template<typename RecordT>
|
||||
void BaseRefIdAdapter<RecordT>::setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const
|
||||
{
|
||||
Record<RecordT>& record = static_cast<Record<RecordT>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, mType)));
|
||||
|
||||
if (column==mBase.mModified)
|
||||
record.mState = static_cast<RecordBase::State> (value.toInt());
|
||||
}
|
||||
|
||||
template<typename RecordT>
|
||||
UniversalId::Type BaseRefIdAdapter<RecordT>::getType() const
|
||||
{
|
||||
return mType;
|
||||
}
|
||||
|
||||
|
||||
struct ModelColumns : public BaseColumns
|
||||
{
|
||||
const RefIdColumn *mModel;
|
||||
|
||||
ModelColumns (const BaseColumns& base) : BaseColumns (base) {}
|
||||
};
|
||||
|
||||
/// \brief Adapter for IDs with models (all but levelled lists)
|
||||
template<typename RecordT>
|
||||
class ModelRefIdAdapter : public BaseRefIdAdapter<RecordT>
|
||||
{
|
||||
ModelColumns mModel;
|
||||
|
||||
public:
|
||||
|
||||
ModelRefIdAdapter (UniversalId::Type type, const ModelColumns& columns);
|
||||
|
||||
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
|
||||
const;
|
||||
|
||||
virtual void setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const;
|
||||
///< If the data type does not match an exception is thrown.
|
||||
};
|
||||
|
||||
template<typename RecordT>
|
||||
ModelRefIdAdapter<RecordT>::ModelRefIdAdapter (UniversalId::Type type, const ModelColumns& columns)
|
||||
: BaseRefIdAdapter<RecordT> (type, columns), mModel (columns)
|
||||
{}
|
||||
|
||||
template<typename RecordT>
|
||||
QVariant ModelRefIdAdapter<RecordT>::getData (const RefIdColumn *column, const RefIdData& data,
|
||||
int index) const
|
||||
{
|
||||
const Record<RecordT>& record = static_cast<const Record<RecordT>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType())));
|
||||
|
||||
if (column==mModel.mModel)
|
||||
return QString::fromUtf8 (record.get().mModel.c_str());
|
||||
|
||||
return BaseRefIdAdapter<RecordT>::getData (column, data, index);
|
||||
}
|
||||
|
||||
template<typename RecordT>
|
||||
void ModelRefIdAdapter<RecordT>::setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const
|
||||
{
|
||||
Record<RecordT>& record = static_cast<Record<RecordT>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType())));
|
||||
|
||||
if (column==mModel.mModel)
|
||||
record.get().mModel = value.toString().toUtf8().constData();
|
||||
else
|
||||
BaseRefIdAdapter<RecordT>::setData (column, data, index, value);
|
||||
}
|
||||
|
||||
struct NameColumns : public ModelColumns
|
||||
{
|
||||
const RefIdColumn *mName;
|
||||
const RefIdColumn *mScript;
|
||||
|
||||
NameColumns (const ModelColumns& base) : ModelColumns (base) {}
|
||||
};
|
||||
|
||||
/// \brief Adapter for IDs with names (all but levelled lists and statics)
|
||||
template<typename RecordT>
|
||||
class NameRefIdAdapter : public ModelRefIdAdapter<RecordT>
|
||||
{
|
||||
NameColumns mName;
|
||||
|
||||
public:
|
||||
|
||||
NameRefIdAdapter (UniversalId::Type type, const NameColumns& columns);
|
||||
|
||||
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
|
||||
const;
|
||||
|
||||
virtual void setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const;
|
||||
///< If the data type does not match an exception is thrown.
|
||||
};
|
||||
|
||||
template<typename RecordT>
|
||||
NameRefIdAdapter<RecordT>::NameRefIdAdapter (UniversalId::Type type, const NameColumns& columns)
|
||||
: ModelRefIdAdapter<RecordT> (type, columns), mName (columns)
|
||||
{}
|
||||
|
||||
template<typename RecordT>
|
||||
QVariant NameRefIdAdapter<RecordT>::getData (const RefIdColumn *column, const RefIdData& data,
|
||||
int index) const
|
||||
{
|
||||
const Record<RecordT>& record = static_cast<const Record<RecordT>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType())));
|
||||
|
||||
if (column==mName.mName)
|
||||
return QString::fromUtf8 (record.get().mName.c_str());
|
||||
|
||||
if (column==mName.mScript)
|
||||
return QString::fromUtf8 (record.get().mScript.c_str());
|
||||
|
||||
return ModelRefIdAdapter<RecordT>::getData (column, data, index);
|
||||
}
|
||||
|
||||
template<typename RecordT>
|
||||
void NameRefIdAdapter<RecordT>::setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const
|
||||
{
|
||||
Record<RecordT>& record = static_cast<Record<RecordT>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType())));
|
||||
|
||||
if (column==mName.mName)
|
||||
record.get().mName = value.toString().toUtf8().constData();
|
||||
else if (column==mName.mScript)
|
||||
record.get().mScript = value.toString().toUtf8().constData();
|
||||
else
|
||||
ModelRefIdAdapter<RecordT>::setData (column, data, index, value);
|
||||
}
|
||||
|
||||
struct InventoryColumns : public NameColumns
|
||||
{
|
||||
const RefIdColumn *mIcon;
|
||||
const RefIdColumn *mWeight;
|
||||
const RefIdColumn *mValue;
|
||||
|
||||
InventoryColumns (const NameColumns& base) : NameColumns (base) {}
|
||||
};
|
||||
|
||||
/// \brief Adapter for IDs that can go into an inventory
|
||||
template<typename RecordT>
|
||||
class InventoryRefIdAdapter : public NameRefIdAdapter<RecordT>
|
||||
{
|
||||
InventoryColumns mInventory;
|
||||
|
||||
public:
|
||||
|
||||
InventoryRefIdAdapter (UniversalId::Type type, const InventoryColumns& columns);
|
||||
|
||||
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
|
||||
const;
|
||||
|
||||
virtual void setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const;
|
||||
///< If the data type does not match an exception is thrown.
|
||||
};
|
||||
|
||||
template<typename RecordT>
|
||||
InventoryRefIdAdapter<RecordT>::InventoryRefIdAdapter (UniversalId::Type type,
|
||||
const InventoryColumns& columns)
|
||||
: NameRefIdAdapter<RecordT> (type, columns), mInventory (columns)
|
||||
{}
|
||||
|
||||
template<typename RecordT>
|
||||
QVariant InventoryRefIdAdapter<RecordT>::getData (const RefIdColumn *column, const RefIdData& data,
|
||||
int index) const
|
||||
{
|
||||
const Record<RecordT>& record = static_cast<const Record<RecordT>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType())));
|
||||
|
||||
if (column==mInventory.mIcon)
|
||||
return QString::fromUtf8 (record.get().mIcon.c_str());
|
||||
|
||||
if (column==mInventory.mWeight)
|
||||
return record.get().mData.mWeight;
|
||||
|
||||
if (column==mInventory.mValue)
|
||||
return record.get().mData.mValue;
|
||||
|
||||
return NameRefIdAdapter<RecordT>::getData (column, data, index);
|
||||
}
|
||||
|
||||
template<typename RecordT>
|
||||
void InventoryRefIdAdapter<RecordT>::setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const
|
||||
{
|
||||
Record<RecordT>& record = static_cast<Record<RecordT>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType())));
|
||||
|
||||
if (column==mInventory.mIcon)
|
||||
record.get().mIcon = value.toString().toUtf8().constData();
|
||||
else if (column==mInventory.mWeight)
|
||||
record.get().mData.mWeight = value.toFloat();
|
||||
else if (column==mInventory.mValue)
|
||||
record.get().mData.mValue = value.toInt();
|
||||
else
|
||||
NameRefIdAdapter<RecordT>::setData (column, data, index, value);
|
||||
}
|
||||
|
||||
class PotionRefIdAdapter : public InventoryRefIdAdapter<ESM::Potion>
|
||||
{
|
||||
const RefIdColumn *mAutoCalc;
|
||||
|
||||
public:
|
||||
|
||||
PotionRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *autoCalc);
|
||||
|
||||
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
|
||||
const;
|
||||
|
||||
virtual void setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const;
|
||||
///< If the data type does not match an exception is thrown.
|
||||
};
|
||||
|
||||
struct EnchantableColumns : public InventoryColumns
|
||||
{
|
||||
const RefIdColumn *mEnchantment;
|
||||
const RefIdColumn *mEnchantmentPoints;
|
||||
|
||||
EnchantableColumns (const InventoryColumns& base) : InventoryColumns (base) {}
|
||||
};
|
||||
|
||||
/// \brief Adapter for enchantable IDs
|
||||
template<typename RecordT>
|
||||
class EnchantableRefIdAdapter : public InventoryRefIdAdapter<RecordT>
|
||||
{
|
||||
EnchantableColumns mEnchantable;
|
||||
|
||||
public:
|
||||
|
||||
EnchantableRefIdAdapter (UniversalId::Type type, const EnchantableColumns& columns);
|
||||
|
||||
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
|
||||
const;
|
||||
|
||||
virtual void setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const;
|
||||
///< If the data type does not match an exception is thrown.
|
||||
};
|
||||
|
||||
template<typename RecordT>
|
||||
EnchantableRefIdAdapter<RecordT>::EnchantableRefIdAdapter (UniversalId::Type type,
|
||||
const EnchantableColumns& columns)
|
||||
: InventoryRefIdAdapter<RecordT> (type, columns), mEnchantable (columns)
|
||||
{}
|
||||
|
||||
template<typename RecordT>
|
||||
QVariant EnchantableRefIdAdapter<RecordT>::getData (const RefIdColumn *column, const RefIdData& data,
|
||||
int index) const
|
||||
{
|
||||
const Record<RecordT>& record = static_cast<const Record<RecordT>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType())));
|
||||
|
||||
if (column==mEnchantable.mEnchantment)
|
||||
return QString::fromUtf8 (record.get().mEnchant.c_str());
|
||||
|
||||
if (column==mEnchantable.mEnchantmentPoints)
|
||||
return static_cast<int> (record.get().mData.mEnchant);
|
||||
|
||||
return InventoryRefIdAdapter<RecordT>::getData (column, data, index);
|
||||
}
|
||||
|
||||
template<typename RecordT>
|
||||
void EnchantableRefIdAdapter<RecordT>::setData (const RefIdColumn *column, RefIdData& data,
|
||||
int index, const QVariant& value) const
|
||||
{
|
||||
Record<RecordT>& record = static_cast<Record<RecordT>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType())));
|
||||
|
||||
if (column==mEnchantable.mEnchantment)
|
||||
record.get().mEnchant = value.toString().toUtf8().constData();
|
||||
else if (column==mEnchantable.mEnchantmentPoints)
|
||||
record.get().mData.mEnchant = value.toInt();
|
||||
else
|
||||
InventoryRefIdAdapter<RecordT>::setData (column, data, index, value);
|
||||
}
|
||||
|
||||
struct ToolColumns : public InventoryColumns
|
||||
{
|
||||
const RefIdColumn *mQuality;
|
||||
const RefIdColumn *mUses;
|
||||
|
||||
ToolColumns (const InventoryColumns& base) : InventoryColumns (base) {}
|
||||
};
|
||||
|
||||
/// \brief Adapter for tools with limited uses IDs (lockpick, repair, probes)
|
||||
template<typename RecordT>
|
||||
class ToolRefIdAdapter : public InventoryRefIdAdapter<RecordT>
|
||||
{
|
||||
ToolColumns mTools;
|
||||
|
||||
public:
|
||||
|
||||
ToolRefIdAdapter (UniversalId::Type type, const ToolColumns& columns);
|
||||
|
||||
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
|
||||
const;
|
||||
|
||||
virtual void setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const;
|
||||
///< If the data type does not match an exception is thrown.
|
||||
};
|
||||
|
||||
template<typename RecordT>
|
||||
ToolRefIdAdapter<RecordT>::ToolRefIdAdapter (UniversalId::Type type, const ToolColumns& columns)
|
||||
: InventoryRefIdAdapter<RecordT> (type, columns), mTools (columns)
|
||||
{}
|
||||
|
||||
template<typename RecordT>
|
||||
QVariant ToolRefIdAdapter<RecordT>::getData (const RefIdColumn *column, const RefIdData& data,
|
||||
int index) const
|
||||
{
|
||||
const Record<RecordT>& record = static_cast<const Record<RecordT>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType())));
|
||||
|
||||
if (column==mTools.mQuality)
|
||||
return record.get().mData.mQuality;
|
||||
|
||||
if (column==mTools.mUses)
|
||||
return record.get().mData.mUses;
|
||||
|
||||
return InventoryRefIdAdapter<RecordT>::getData (column, data, index);
|
||||
}
|
||||
|
||||
template<typename RecordT>
|
||||
void ToolRefIdAdapter<RecordT>::setData (const RefIdColumn *column, RefIdData& data,
|
||||
int index, const QVariant& value) const
|
||||
{
|
||||
Record<RecordT>& record = static_cast<Record<RecordT>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType())));
|
||||
|
||||
if (column==mTools.mQuality)
|
||||
record.get().mData.mQuality = value.toFloat();
|
||||
else if (column==mTools.mUses)
|
||||
record.get().mData.mUses = value.toInt();
|
||||
else
|
||||
InventoryRefIdAdapter<RecordT>::setData (column, data, index, value);
|
||||
}
|
||||
|
||||
struct ActorColumns : public NameColumns
|
||||
{
|
||||
const RefIdColumn *mHasAi;
|
||||
const RefIdColumn *mHello;
|
||||
const RefIdColumn *mFlee;
|
||||
const RefIdColumn *mFight;
|
||||
const RefIdColumn *mAlarm;
|
||||
std::map<const RefIdColumn *, unsigned int> mServices;
|
||||
|
||||
ActorColumns (const NameColumns& base) : NameColumns (base) {}
|
||||
};
|
||||
|
||||
/// \brief Adapter for actor IDs (handles common AI functionality)
|
||||
template<typename RecordT>
|
||||
class ActorRefIdAdapter : public NameRefIdAdapter<RecordT>
|
||||
{
|
||||
ActorColumns mActors;
|
||||
|
||||
public:
|
||||
|
||||
ActorRefIdAdapter (UniversalId::Type type, const ActorColumns& columns);
|
||||
|
||||
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
|
||||
const;
|
||||
|
||||
virtual void setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const;
|
||||
///< If the data type does not match an exception is thrown.
|
||||
};
|
||||
|
||||
template<typename RecordT>
|
||||
ActorRefIdAdapter<RecordT>::ActorRefIdAdapter (UniversalId::Type type,
|
||||
const ActorColumns& columns)
|
||||
: NameRefIdAdapter<RecordT> (type, columns), mActors (columns)
|
||||
{}
|
||||
|
||||
template<typename RecordT>
|
||||
QVariant ActorRefIdAdapter<RecordT>::getData (const RefIdColumn *column, const RefIdData& data,
|
||||
int index) const
|
||||
{
|
||||
const Record<RecordT>& record = static_cast<const Record<RecordT>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType())));
|
||||
|
||||
if (column==mActors.mHasAi)
|
||||
return record.get().mHasAI!=0;
|
||||
|
||||
if (column==mActors.mHello)
|
||||
return record.get().mAiData.mHello;
|
||||
|
||||
if (column==mActors.mFlee)
|
||||
return record.get().mAiData.mFlee;
|
||||
|
||||
if (column==mActors.mFight)
|
||||
return record.get().mAiData.mFight;
|
||||
|
||||
if (column==mActors.mAlarm)
|
||||
return record.get().mAiData.mAlarm;
|
||||
|
||||
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
||||
mActors.mServices.find (column);
|
||||
|
||||
if (iter!=mActors.mServices.end())
|
||||
return (record.get().mAiData.mServices & iter->second)!=0;
|
||||
|
||||
return NameRefIdAdapter<RecordT>::getData (column, data, index);
|
||||
}
|
||||
|
||||
template<typename RecordT>
|
||||
void ActorRefIdAdapter<RecordT>::setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const
|
||||
{
|
||||
Record<RecordT>& record = static_cast<Record<RecordT>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType())));
|
||||
|
||||
if (column==mActors.mHasAi)
|
||||
record.get().mHasAI = value.toInt();
|
||||
else if (column==mActors.mHello)
|
||||
record.get().mAiData.mHello = value.toInt();
|
||||
else if (column==mActors.mFlee)
|
||||
record.get().mAiData.mFlee = value.toInt();
|
||||
else if (column==mActors.mFight)
|
||||
record.get().mAiData.mFight = value.toInt();
|
||||
else if (column==mActors.mAlarm)
|
||||
record.get().mAiData.mAlarm = value.toInt();
|
||||
else
|
||||
{
|
||||
typename std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
||||
mActors.mServices.find (column);
|
||||
if (iter!=mActors.mServices.end())
|
||||
{
|
||||
if (value.toInt()!=0)
|
||||
record.get().mAiData.mServices |= iter->second;
|
||||
else
|
||||
record.get().mAiData.mServices &= ~iter->second;
|
||||
}
|
||||
else
|
||||
NameRefIdAdapter<RecordT>::setData (column, data, index, value);
|
||||
}
|
||||
}
|
||||
|
||||
class ApparatusRefIdAdapter : public InventoryRefIdAdapter<ESM::Apparatus>
|
||||
{
|
||||
const RefIdColumn *mType;
|
||||
const RefIdColumn *mQuality;
|
||||
|
||||
public:
|
||||
|
||||
ApparatusRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *type,
|
||||
const RefIdColumn *quality);
|
||||
|
||||
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
|
||||
const;
|
||||
|
||||
virtual void setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const;
|
||||
///< If the data type does not match an exception is thrown.
|
||||
};
|
||||
|
||||
class ArmorRefIdAdapter : public EnchantableRefIdAdapter<ESM::Armor>
|
||||
{
|
||||
const RefIdColumn *mType;
|
||||
const RefIdColumn *mHealth;
|
||||
const RefIdColumn *mArmor;
|
||||
|
||||
public:
|
||||
|
||||
ArmorRefIdAdapter (const EnchantableColumns& columns, const RefIdColumn *type,
|
||||
const RefIdColumn *health, const RefIdColumn *armor);
|
||||
|
||||
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
|
||||
const;
|
||||
|
||||
virtual void setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const;
|
||||
///< If the data type does not match an exception is thrown.
|
||||
};
|
||||
|
||||
class BookRefIdAdapter : public EnchantableRefIdAdapter<ESM::Book>
|
||||
{
|
||||
const RefIdColumn *mScroll;
|
||||
const RefIdColumn *mSkill;
|
||||
|
||||
public:
|
||||
|
||||
BookRefIdAdapter (const EnchantableColumns& columns, const RefIdColumn *scroll,
|
||||
const RefIdColumn *skill);
|
||||
|
||||
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
|
||||
const;
|
||||
|
||||
virtual void setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const;
|
||||
///< If the data type does not match an exception is thrown.
|
||||
};
|
||||
|
||||
class ClothingRefIdAdapter : public EnchantableRefIdAdapter<ESM::Clothing>
|
||||
{
|
||||
const RefIdColumn *mType;
|
||||
|
||||
public:
|
||||
|
||||
ClothingRefIdAdapter (const EnchantableColumns& columns, const RefIdColumn *type);
|
||||
|
||||
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
|
||||
const;
|
||||
|
||||
virtual void setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const;
|
||||
///< If the data type does not match an exception is thrown.
|
||||
};
|
||||
|
||||
class ContainerRefIdAdapter : public NameRefIdAdapter<ESM::Container>
|
||||
{
|
||||
const RefIdColumn *mWeight;
|
||||
const RefIdColumn *mOrganic;
|
||||
const RefIdColumn *mRespawn;
|
||||
|
||||
public:
|
||||
|
||||
ContainerRefIdAdapter (const NameColumns& columns, const RefIdColumn *weight,
|
||||
const RefIdColumn *organic, const RefIdColumn *respawn);
|
||||
|
||||
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
|
||||
const;
|
||||
|
||||
virtual void setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const;
|
||||
///< If the data type does not match an exception is thrown.
|
||||
};
|
||||
|
||||
struct CreatureColumns : public ActorColumns
|
||||
{
|
||||
std::map<const RefIdColumn *, unsigned int> mFlags;
|
||||
const RefIdColumn *mType;
|
||||
const RefIdColumn *mSoul;
|
||||
const RefIdColumn *mScale;
|
||||
const RefIdColumn *mOriginal;
|
||||
|
||||
CreatureColumns (const ActorColumns& actorColumns);
|
||||
};
|
||||
|
||||
class CreatureRefIdAdapter : public ActorRefIdAdapter<ESM::Creature>
|
||||
{
|
||||
CreatureColumns mColumns;
|
||||
|
||||
public:
|
||||
|
||||
CreatureRefIdAdapter (const CreatureColumns& columns);
|
||||
|
||||
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
|
||||
const;
|
||||
|
||||
virtual void setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const;
|
||||
///< If the data type does not match an exception is thrown.
|
||||
};
|
||||
|
||||
class DoorRefIdAdapter : public NameRefIdAdapter<ESM::Door>
|
||||
{
|
||||
const RefIdColumn *mOpenSound;
|
||||
const RefIdColumn *mCloseSound;
|
||||
|
||||
public:
|
||||
|
||||
DoorRefIdAdapter (const NameColumns& columns, const RefIdColumn *openSound,
|
||||
const RefIdColumn *closeSound);
|
||||
|
||||
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
|
||||
const;
|
||||
|
||||
virtual void setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const;
|
||||
///< If the data type does not match an exception is thrown.
|
||||
};
|
||||
|
||||
struct LightColumns : public InventoryColumns
|
||||
{
|
||||
const RefIdColumn *mTime;
|
||||
const RefIdColumn *mRadius;
|
||||
const RefIdColumn *mColor;
|
||||
const RefIdColumn *mSound;
|
||||
std::map<const RefIdColumn *, unsigned int> mFlags;
|
||||
|
||||
LightColumns (const InventoryColumns& columns);
|
||||
};
|
||||
|
||||
class LightRefIdAdapter : public InventoryRefIdAdapter<ESM::Light>
|
||||
{
|
||||
LightColumns mColumns;
|
||||
|
||||
public:
|
||||
|
||||
LightRefIdAdapter (const LightColumns& columns);
|
||||
|
||||
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
|
||||
const;
|
||||
|
||||
virtual void setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const;
|
||||
///< If the data type does not match an exception is thrown.
|
||||
};
|
||||
|
||||
class MiscRefIdAdapter : public InventoryRefIdAdapter<ESM::Miscellaneous>
|
||||
{
|
||||
const RefIdColumn *mKey;
|
||||
|
||||
public:
|
||||
|
||||
MiscRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *key);
|
||||
|
||||
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
|
||||
const;
|
||||
|
||||
virtual void setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const;
|
||||
///< If the data type does not match an exception is thrown.
|
||||
};
|
||||
|
||||
struct NpcColumns : public ActorColumns
|
||||
{
|
||||
std::map<const RefIdColumn *, unsigned int> mFlags;
|
||||
const RefIdColumn *mRace;
|
||||
const RefIdColumn *mClass;
|
||||
const RefIdColumn *mFaction;
|
||||
const RefIdColumn *mHair;
|
||||
const RefIdColumn *mHead;
|
||||
|
||||
NpcColumns (const ActorColumns& actorColumns);
|
||||
};
|
||||
|
||||
class NpcRefIdAdapter : public ActorRefIdAdapter<ESM::NPC>
|
||||
{
|
||||
NpcColumns mColumns;
|
||||
|
||||
public:
|
||||
|
||||
NpcRefIdAdapter (const NpcColumns& columns);
|
||||
|
||||
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
|
||||
const;
|
||||
|
||||
virtual void setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const;
|
||||
///< If the data type does not match an exception is thrown.
|
||||
};
|
||||
|
||||
struct WeaponColumns : public EnchantableColumns
|
||||
{
|
||||
const RefIdColumn *mType;
|
||||
const RefIdColumn *mHealth;
|
||||
const RefIdColumn *mSpeed;
|
||||
const RefIdColumn *mReach;
|
||||
const RefIdColumn *mChop[2];
|
||||
const RefIdColumn *mSlash[2];
|
||||
const RefIdColumn *mThrust[2];
|
||||
std::map<const RefIdColumn *, unsigned int> mFlags;
|
||||
|
||||
WeaponColumns (const EnchantableColumns& columns);
|
||||
};
|
||||
|
||||
class WeaponRefIdAdapter : public EnchantableRefIdAdapter<ESM::Weapon>
|
||||
{
|
||||
WeaponColumns mColumns;
|
||||
|
||||
public:
|
||||
|
||||
WeaponRefIdAdapter (const WeaponColumns& columns);
|
||||
|
||||
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
|
||||
const;
|
||||
|
||||
virtual void setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||
const QVariant& value) const;
|
||||
///< If the data type does not match an exception is thrown.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
540
apps/opencs/model/world/refidcollection.cpp
Normal file
540
apps/opencs/model/world/refidcollection.cpp
Normal file
|
@ -0,0 +1,540 @@
|
|||
|
||||
#include "refidcollection.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "refidadapter.hpp"
|
||||
#include "refidadapterimp.hpp"
|
||||
|
||||
CSMWorld::RefIdColumn::RefIdColumn (const std::string& title, Display displayType, int flag,
|
||||
bool editable, bool userEditable)
|
||||
: ColumnBase (title, displayType, flag), mEditable (editable), mUserEditable (userEditable)
|
||||
{}
|
||||
|
||||
bool CSMWorld::RefIdColumn::isEditable() const
|
||||
{
|
||||
return mEditable;
|
||||
}
|
||||
|
||||
bool CSMWorld::RefIdColumn::isUserEditable() const
|
||||
{
|
||||
return mUserEditable;
|
||||
}
|
||||
|
||||
|
||||
const CSMWorld::RefIdAdapter& CSMWorld::RefIdCollection::findAdaptor (UniversalId::Type type) const
|
||||
{
|
||||
std::map<UniversalId::Type, RefIdAdapter *>::const_iterator iter = mAdapters.find (type);
|
||||
|
||||
if (iter==mAdapters.end())
|
||||
throw std::logic_error ("unsupported type in RefIdCollection");
|
||||
|
||||
return *iter->second;
|
||||
}
|
||||
|
||||
CSMWorld::RefIdCollection::RefIdCollection()
|
||||
{
|
||||
BaseColumns baseColumns;
|
||||
|
||||
mColumns.push_back (RefIdColumn ("ID", ColumnBase::Display_String,
|
||||
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false));
|
||||
baseColumns.mId = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn ("*", ColumnBase::Display_Integer,
|
||||
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false));
|
||||
baseColumns.mModified = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn ("Type", ColumnBase::Display_Integer,
|
||||
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false));
|
||||
baseColumns.mType = &mColumns.back();
|
||||
|
||||
ModelColumns modelColumns (baseColumns);
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Model", ColumnBase::Display_String));
|
||||
modelColumns.mModel = &mColumns.back();
|
||||
|
||||
NameColumns nameColumns (modelColumns);
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Name", ColumnBase::Display_String));
|
||||
nameColumns.mName = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn ("Script", ColumnBase::Display_String));
|
||||
nameColumns.mScript = &mColumns.back();
|
||||
|
||||
InventoryColumns inventoryColumns (nameColumns);
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Icon", ColumnBase::Display_String));
|
||||
inventoryColumns.mIcon = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn ("Weight", ColumnBase::Display_Float));
|
||||
inventoryColumns.mWeight = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn ("Value", ColumnBase::Display_Integer));
|
||||
inventoryColumns.mValue = &mColumns.back();
|
||||
|
||||
EnchantableColumns enchantableColumns (inventoryColumns);
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Enchantment", ColumnBase::Display_String));
|
||||
enchantableColumns.mEnchantment = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn ("Enchantment Points", ColumnBase::Display_Integer));
|
||||
enchantableColumns.mEnchantmentPoints = &mColumns.back();
|
||||
|
||||
ToolColumns toolsColumns (inventoryColumns);
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Quality", ColumnBase::Display_Float));
|
||||
toolsColumns.mQuality = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn ("Uses", ColumnBase::Display_Integer));
|
||||
toolsColumns.mUses = &mColumns.back();
|
||||
|
||||
ActorColumns actorsColumns (nameColumns);
|
||||
|
||||
mColumns.push_back (RefIdColumn ("AI", ColumnBase::Display_Boolean));
|
||||
actorsColumns.mHasAi = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn ("AI Hello", ColumnBase::Display_Integer));
|
||||
actorsColumns.mHello = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn ("AI Flee", ColumnBase::Display_Integer));
|
||||
actorsColumns.mFlee = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn ("AI Fight", ColumnBase::Display_Integer));
|
||||
actorsColumns.mFight = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn ("AI Alarm", ColumnBase::Display_Integer));
|
||||
actorsColumns.mAlarm = &mColumns.back();
|
||||
|
||||
static const struct
|
||||
{
|
||||
const char *mName;
|
||||
unsigned int mFlag;
|
||||
} sServiceTable[] =
|
||||
{
|
||||
{ "Buys Weapons", ESM::NPC::Weapon},
|
||||
{ "Buys Armor", ESM::NPC::Armor},
|
||||
{ "Buys Clothing", ESM::NPC::Clothing},
|
||||
{ "Buys Books", ESM::NPC::Books},
|
||||
{ "Buys Ingredients", ESM::NPC::Ingredients},
|
||||
{ "Buys Lockpicks", ESM::NPC::Picks},
|
||||
{ "Buys Probes", ESM::NPC::Probes},
|
||||
{ "Buys Lights", ESM::NPC::Lights},
|
||||
{ "Buys Apparati", ESM::NPC::Apparatus},
|
||||
{ "Buys Repair Items", ESM::NPC::RepairItem},
|
||||
{ "Buys Misc Items", ESM::NPC::Misc},
|
||||
{ "Buys Potions", ESM::NPC::Potions},
|
||||
{ "Buys Magic Items", ESM::NPC::MagicItems},
|
||||
{ "Sells Spells", ESM::NPC::Spells},
|
||||
{ "Trainer", ESM::NPC::Training},
|
||||
{ "Spellmaking", ESM::NPC::Spellmaking},
|
||||
{ "Enchanting Service", ESM::NPC::Enchanting},
|
||||
{ "Repair Serivce", ESM::NPC::Repair},
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
for (int i=0; sServiceTable[i].mName; ++i)
|
||||
{
|
||||
mColumns.push_back (RefIdColumn (sServiceTable[i].mName, ColumnBase::Display_Boolean));
|
||||
actorsColumns.mServices.insert (std::make_pair (&mColumns.back(), sServiceTable[i].mFlag));
|
||||
}
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Auto Calc", ColumnBase::Display_Boolean));
|
||||
const RefIdColumn *autoCalc = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Apparatus Type", ColumnBase::Display_ApparatusType));
|
||||
const RefIdColumn *apparatusType = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Armor Type", ColumnBase::Display_ArmorType));
|
||||
const RefIdColumn *armorType = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Health", ColumnBase::Display_Integer));
|
||||
const RefIdColumn *health = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Armor Value", ColumnBase::Display_Integer));
|
||||
const RefIdColumn *armor = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Scroll", ColumnBase::Display_Boolean));
|
||||
const RefIdColumn *scroll = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Attribute", ColumnBase::Display_Attribute));
|
||||
const RefIdColumn *attribute = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Clothing Type", ColumnBase::Display_ClothingType));
|
||||
const RefIdColumn *clothingType = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Weight Capacity", ColumnBase::Display_Float));
|
||||
const RefIdColumn *weightCapacity = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Organic Container", ColumnBase::Display_Boolean));
|
||||
const RefIdColumn *organic = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Respawn", ColumnBase::Display_Boolean));
|
||||
const RefIdColumn *respawn = &mColumns.back();
|
||||
|
||||
CreatureColumns creatureColumns (actorsColumns);
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Creature Type", ColumnBase::Display_CreatureType));
|
||||
creatureColumns.mType = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn ("Soul Points", ColumnBase::Display_Integer));
|
||||
creatureColumns.mSoul = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn ("Scale", ColumnBase::Display_Float));
|
||||
creatureColumns.mScale = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn ("Original Creature", ColumnBase::Display_String));
|
||||
creatureColumns.mOriginal = &mColumns.back();
|
||||
|
||||
static const struct
|
||||
{
|
||||
const char *mName;
|
||||
unsigned int mFlag;
|
||||
} sCreatureFlagTable[] =
|
||||
{
|
||||
{ "Biped", ESM::Creature::Biped },
|
||||
{ "Has Weapon", ESM::Creature::Weapon },
|
||||
{ "No Movement", ESM::Creature::None },
|
||||
{ "Swims", ESM::Creature::Swims },
|
||||
{ "Flies", ESM::Creature::Flies },
|
||||
{ "Walks", ESM::Creature::Walks },
|
||||
{ "Essential", ESM::Creature::Essential },
|
||||
{ "Skeleton Blood", ESM::Creature::Skeleton },
|
||||
{ "Metal Blood", ESM::Creature::Metal },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
// for re-use in NPC records
|
||||
const RefIdColumn *essential = 0;
|
||||
const RefIdColumn *skeletonBlood = 0;
|
||||
const RefIdColumn *metalBlood = 0;
|
||||
|
||||
for (int i=0; sCreatureFlagTable[i].mName; ++i)
|
||||
{
|
||||
mColumns.push_back (RefIdColumn (sCreatureFlagTable[i].mName, ColumnBase::Display_Boolean));
|
||||
creatureColumns.mFlags.insert (std::make_pair (&mColumns.back(), sCreatureFlagTable[i].mFlag));
|
||||
|
||||
switch (sCreatureFlagTable[i].mFlag)
|
||||
{
|
||||
case ESM::Creature::Essential: essential = &mColumns.back(); break;
|
||||
case ESM::Creature::Skeleton: skeletonBlood = &mColumns.back(); break;
|
||||
case ESM::Creature::Metal: metalBlood = &mColumns.back(); break;
|
||||
}
|
||||
}
|
||||
|
||||
creatureColumns.mFlags.insert (std::make_pair (respawn, ESM::Creature::Respawn));
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Open Sound", ColumnBase::Display_String));
|
||||
const RefIdColumn *openSound = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Close Sound", ColumnBase::Display_String));
|
||||
const RefIdColumn *closeSound = &mColumns.back();
|
||||
|
||||
LightColumns lightColumns (inventoryColumns);
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Duration", ColumnBase::Display_Integer));
|
||||
lightColumns.mTime = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Radius", ColumnBase::Display_Integer));
|
||||
lightColumns.mRadius = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Colour", ColumnBase::Display_Integer));
|
||||
lightColumns.mColor = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Sound", ColumnBase::Display_String));
|
||||
lightColumns.mSound = &mColumns.back();
|
||||
|
||||
static const struct
|
||||
{
|
||||
const char *mName;
|
||||
unsigned int mFlag;
|
||||
} sLightFlagTable[] =
|
||||
{
|
||||
{ "Dynamic", ESM::Light::Dynamic },
|
||||
{ "Portable", ESM::Light::Carry },
|
||||
{ "Negative Light", ESM::Light::Negative },
|
||||
{ "Flickering", ESM::Light::Flicker },
|
||||
{ "Slow Flickering", ESM::Light::Flicker },
|
||||
{ "Pulsing", ESM::Light::Pulse },
|
||||
{ "Slow Pulsing", ESM::Light::PulseSlow },
|
||||
{ "Fire", ESM::Light::Fire },
|
||||
{ "Off by default", ESM::Light::OffDefault },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
for (int i=0; sLightFlagTable[i].mName; ++i)
|
||||
{
|
||||
mColumns.push_back (RefIdColumn (sLightFlagTable[i].mName, ColumnBase::Display_Boolean));
|
||||
lightColumns.mFlags.insert (std::make_pair (&mColumns.back(), sLightFlagTable[i].mFlag));
|
||||
}
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Key", ColumnBase::Display_Boolean));
|
||||
const RefIdColumn *key = &mColumns.back();
|
||||
|
||||
NpcColumns npcColumns (actorsColumns);
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Race", ColumnBase::Display_String));
|
||||
npcColumns.mRace = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Class", ColumnBase::Display_String));
|
||||
npcColumns.mClass = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Faction", ColumnBase::Display_String));
|
||||
npcColumns.mFaction = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Hair", ColumnBase::Display_String));
|
||||
npcColumns.mHair = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Head", ColumnBase::Display_String));
|
||||
npcColumns.mHead = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Female", ColumnBase::Display_Boolean));
|
||||
npcColumns.mFlags.insert (std::make_pair (&mColumns.back(), ESM::NPC::Female));
|
||||
|
||||
npcColumns.mFlags.insert (std::make_pair (essential, ESM::NPC::Essential));
|
||||
|
||||
npcColumns.mFlags.insert (std::make_pair (respawn, ESM::NPC::Respawn));
|
||||
|
||||
npcColumns.mFlags.insert (std::make_pair (autoCalc, ESM::NPC::Autocalc));
|
||||
|
||||
npcColumns.mFlags.insert (std::make_pair (skeletonBlood, ESM::NPC::Skeleton));
|
||||
|
||||
npcColumns.mFlags.insert (std::make_pair (metalBlood, ESM::NPC::Metal));
|
||||
|
||||
WeaponColumns weaponColumns (enchantableColumns);
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Weapon Type", ColumnBase::Display_WeaponType));
|
||||
weaponColumns.mType = &mColumns.back();
|
||||
|
||||
weaponColumns.mHealth = health;
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Weapon Speed", ColumnBase::Display_Float));
|
||||
weaponColumns.mSpeed = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Weapon Reach", ColumnBase::Display_Float));
|
||||
weaponColumns.mReach = &mColumns.back();
|
||||
|
||||
for (int i=0; i<2; ++i)
|
||||
{
|
||||
std::string suffix = i==0 ? "Min " : "Max ";
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Chop" + suffix, ColumnBase::Display_Integer));
|
||||
weaponColumns.mChop[i] = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Slash" + suffix, ColumnBase::Display_Integer));
|
||||
weaponColumns.mSlash[i] = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn ("Thrust" + suffix, ColumnBase::Display_Integer));
|
||||
weaponColumns.mThrust[i] = &mColumns.back();
|
||||
}
|
||||
|
||||
static const struct
|
||||
{
|
||||
const char *mName;
|
||||
unsigned int mFlag;
|
||||
} sWeaponFlagTable[] =
|
||||
{
|
||||
{ "Magical", ESM::Weapon::Magical },
|
||||
{ "Silver", ESM::Weapon::Silver },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
for (int i=0; sWeaponFlagTable[i].mName; ++i)
|
||||
{
|
||||
mColumns.push_back (RefIdColumn (sWeaponFlagTable[i].mName, ColumnBase::Display_Boolean));
|
||||
weaponColumns.mFlags.insert (std::make_pair (&mColumns.back(), sWeaponFlagTable[i].mFlag));
|
||||
}
|
||||
|
||||
mAdapters.insert (std::make_pair (UniversalId::Type_Activator,
|
||||
new NameRefIdAdapter<ESM::Activator> (UniversalId::Type_Activator, nameColumns)));
|
||||
mAdapters.insert (std::make_pair (UniversalId::Type_Potion,
|
||||
new PotionRefIdAdapter (inventoryColumns, autoCalc)));
|
||||
mAdapters.insert (std::make_pair (UniversalId::Type_Apparatus,
|
||||
new ApparatusRefIdAdapter (inventoryColumns, apparatusType, toolsColumns.mQuality)));
|
||||
mAdapters.insert (std::make_pair (UniversalId::Type_Armor,
|
||||
new ArmorRefIdAdapter (enchantableColumns, armorType, health, armor)));
|
||||
mAdapters.insert (std::make_pair (UniversalId::Type_Book,
|
||||
new BookRefIdAdapter (enchantableColumns, scroll, attribute)));
|
||||
mAdapters.insert (std::make_pair (UniversalId::Type_Clothing,
|
||||
new ClothingRefIdAdapter (enchantableColumns, clothingType)));
|
||||
mAdapters.insert (std::make_pair (UniversalId::Type_Container,
|
||||
new ContainerRefIdAdapter (nameColumns, weightCapacity, organic, respawn)));
|
||||
mAdapters.insert (std::make_pair (UniversalId::Type_Creature,
|
||||
new CreatureRefIdAdapter (creatureColumns)));
|
||||
mAdapters.insert (std::make_pair (UniversalId::Type_Door,
|
||||
new DoorRefIdAdapter (nameColumns, openSound, closeSound)));
|
||||
mAdapters.insert (std::make_pair (UniversalId::Type_Ingredient,
|
||||
new InventoryRefIdAdapter<ESM::Ingredient> (UniversalId::Type_Ingredient, inventoryColumns)));
|
||||
mAdapters.insert (std::make_pair (UniversalId::Type_CreatureLevelledList,
|
||||
new BaseRefIdAdapter<ESM::CreatureLevList> (
|
||||
UniversalId::Type_CreatureLevelledList, baseColumns)));
|
||||
mAdapters.insert (std::make_pair (UniversalId::Type_ItemLevelledList,
|
||||
new BaseRefIdAdapter<ESM::ItemLevList> (UniversalId::Type_ItemLevelledList, baseColumns)));
|
||||
mAdapters.insert (std::make_pair (UniversalId::Type_Light,
|
||||
new LightRefIdAdapter (lightColumns)));
|
||||
mAdapters.insert (std::make_pair (UniversalId::Type_Lockpick,
|
||||
new ToolRefIdAdapter<ESM::Lockpick> (UniversalId::Type_Lockpick, toolsColumns)));
|
||||
mAdapters.insert (std::make_pair (UniversalId::Type_Miscellaneous,
|
||||
new MiscRefIdAdapter (inventoryColumns, key)));
|
||||
mAdapters.insert (std::make_pair (UniversalId::Type_Npc,
|
||||
new NpcRefIdAdapter (npcColumns)));
|
||||
mAdapters.insert (std::make_pair (UniversalId::Type_Probe,
|
||||
new ToolRefIdAdapter<ESM::Probe> (UniversalId::Type_Probe, toolsColumns)));
|
||||
mAdapters.insert (std::make_pair (UniversalId::Type_Repair,
|
||||
new ToolRefIdAdapter<ESM::Repair> (UniversalId::Type_Repair, toolsColumns)));
|
||||
mAdapters.insert (std::make_pair (UniversalId::Type_Static,
|
||||
new ModelRefIdAdapter<ESM::Static> (UniversalId::Type_Static, modelColumns)));
|
||||
mAdapters.insert (std::make_pair (UniversalId::Type_Weapon,
|
||||
new WeaponRefIdAdapter (weaponColumns)));
|
||||
}
|
||||
|
||||
CSMWorld::RefIdCollection::~RefIdCollection()
|
||||
{
|
||||
for (std::map<UniversalId::Type, RefIdAdapter *>::iterator iter (mAdapters.begin());
|
||||
iter!=mAdapters.end(); ++iter)
|
||||
delete iter->second;
|
||||
}
|
||||
|
||||
int CSMWorld::RefIdCollection::getSize() const
|
||||
{
|
||||
return mData.getSize();
|
||||
}
|
||||
|
||||
std::string CSMWorld::RefIdCollection::getId (int index) const
|
||||
{
|
||||
return getData (index, 0).toString().toUtf8().constData();
|
||||
}
|
||||
|
||||
int CSMWorld::RefIdCollection::getIndex (const std::string& id) const
|
||||
{
|
||||
int index = searchId (id);
|
||||
|
||||
if (index==-1)
|
||||
throw std::runtime_error ("invalid ID: " + id);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
int CSMWorld::RefIdCollection::getColumns() const
|
||||
{
|
||||
return mColumns.size();
|
||||
}
|
||||
|
||||
const CSMWorld::ColumnBase& CSMWorld::RefIdCollection::getColumn (int column) const
|
||||
{
|
||||
return mColumns.at (column);
|
||||
}
|
||||
|
||||
QVariant CSMWorld::RefIdCollection::getData (int index, int column) const
|
||||
{
|
||||
RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (index);
|
||||
|
||||
const RefIdAdapter& adaptor = findAdaptor (localIndex.second);
|
||||
|
||||
return adaptor.getData (&mColumns.at (column), mData, localIndex.first);
|
||||
}
|
||||
|
||||
void CSMWorld::RefIdCollection::setData (int index, int column, const QVariant& data)
|
||||
{
|
||||
RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (index);
|
||||
|
||||
const RefIdAdapter& adaptor = findAdaptor (localIndex.second);
|
||||
|
||||
adaptor.setData (&mColumns.at (column), mData, localIndex.first, data);
|
||||
}
|
||||
|
||||
void CSMWorld::RefIdCollection::removeRows (int index, int count)
|
||||
{
|
||||
mData.erase (index, count);
|
||||
}
|
||||
|
||||
void CSMWorld::RefIdCollection::appendBlankRecord (const std::string& id, UniversalId::Type type)
|
||||
{
|
||||
mData.appendRecord (type, id);
|
||||
}
|
||||
|
||||
int CSMWorld::RefIdCollection::searchId (const std::string& id) const
|
||||
{
|
||||
RefIdData::LocalIndex localIndex = mData.searchId (id);
|
||||
|
||||
if (localIndex.first==-1)
|
||||
return -1;
|
||||
|
||||
return mData.localToGlobalIndex (localIndex);
|
||||
}
|
||||
|
||||
void CSMWorld::RefIdCollection::replace (int index, const RecordBase& record)
|
||||
{
|
||||
mData.getRecord (mData.globalToLocalIndex (index)).assign (record);
|
||||
}
|
||||
|
||||
void CSMWorld::RefIdCollection::appendRecord (const RecordBase& record,
|
||||
UniversalId::Type type)
|
||||
{
|
||||
std::string id = findAdaptor (type).getId (record);
|
||||
|
||||
int index = mData.getAppendIndex (type);
|
||||
|
||||
mData.appendRecord (type, id);
|
||||
|
||||
mData.getRecord (mData.globalToLocalIndex (index)).assign (record);
|
||||
}
|
||||
|
||||
const CSMWorld::RecordBase& CSMWorld::RefIdCollection::getRecord (const std::string& id) const
|
||||
{
|
||||
return mData.getRecord (mData.searchId (id));
|
||||
}
|
||||
|
||||
const CSMWorld::RecordBase& CSMWorld::RefIdCollection::getRecord (int index) const
|
||||
{
|
||||
return mData.getRecord (mData.globalToLocalIndex (index));
|
||||
}
|
||||
|
||||
void CSMWorld::RefIdCollection::load (ESM::ESMReader& reader, bool base, UniversalId::Type type)
|
||||
{
|
||||
std::string id = reader.getHNOString ("NAME");
|
||||
|
||||
int index = searchId (id);
|
||||
|
||||
if (reader.isNextSub ("DELE"))
|
||||
{
|
||||
reader.skipRecord();
|
||||
|
||||
if (index==-1)
|
||||
{
|
||||
// deleting a record that does not exist
|
||||
|
||||
// ignore it for now
|
||||
|
||||
/// \todo report the problem to the user
|
||||
}
|
||||
else if (base)
|
||||
{
|
||||
mData.erase (index, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
mData.getRecord (mData.globalToLocalIndex (index)).mState = RecordBase::State_Deleted;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (index==-1)
|
||||
{
|
||||
// new record
|
||||
int index = mData.getAppendIndex (type);
|
||||
mData.appendRecord (type, id);
|
||||
|
||||
RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (index);
|
||||
|
||||
mData.load (localIndex, reader, base);
|
||||
|
||||
mData.getRecord (localIndex).mState =
|
||||
base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
|
||||
}
|
||||
else
|
||||
{
|
||||
// old record
|
||||
RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (index);
|
||||
|
||||
if (!base)
|
||||
if (mData.getRecord (localIndex).mState==RecordBase::State_Erased)
|
||||
throw std::logic_error ("attempt to access a deleted record");
|
||||
|
||||
mData.load (localIndex, reader, base);
|
||||
|
||||
if (!base)
|
||||
mData.getRecord (localIndex).mState = RecordBase::State_Modified;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int CSMWorld::RefIdCollection::getAppendIndex (UniversalId::Type type) const
|
||||
{
|
||||
return mData.getAppendIndex (type);
|
||||
}
|
95
apps/opencs/model/world/refidcollection.hpp
Normal file
95
apps/opencs/model/world/refidcollection.hpp
Normal file
|
@ -0,0 +1,95 @@
|
|||
#ifndef CSM_WOLRD_REFIDCOLLECTION_H
|
||||
#define CSM_WOLRD_REFIDCOLLECTION_H
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <deque>
|
||||
|
||||
#include "columnbase.hpp"
|
||||
#include "idcollection.hpp"
|
||||
#include "refiddata.hpp"
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class RefIdAdapter;
|
||||
|
||||
class RefIdColumn : public ColumnBase
|
||||
{
|
||||
bool mEditable;
|
||||
bool mUserEditable;
|
||||
|
||||
public:
|
||||
|
||||
RefIdColumn (const std::string& title, Display displayType,
|
||||
int flag = Flag_Table | Flag_Dialogue, bool editable = true,
|
||||
bool userEditable = true);
|
||||
|
||||
virtual bool isEditable() const;
|
||||
|
||||
virtual bool isUserEditable() const;
|
||||
};
|
||||
|
||||
class RefIdCollection : public IdCollectionBase
|
||||
{
|
||||
private:
|
||||
|
||||
RefIdData mData;
|
||||
std::deque<RefIdColumn> mColumns;
|
||||
std::map<UniversalId::Type, RefIdAdapter *> mAdapters;
|
||||
|
||||
private:
|
||||
|
||||
const RefIdAdapter& findAdaptor (UniversalId::Type) const;
|
||||
///< Throws an exception if no adaptor for \a Type can be found.
|
||||
|
||||
public:
|
||||
|
||||
RefIdCollection();
|
||||
|
||||
virtual ~RefIdCollection();
|
||||
|
||||
virtual int getSize() const;
|
||||
|
||||
virtual std::string getId (int index) const;
|
||||
|
||||
virtual int getIndex (const std::string& id) const;
|
||||
|
||||
virtual int getColumns() const;
|
||||
|
||||
virtual const ColumnBase& getColumn (int column) const;
|
||||
|
||||
virtual QVariant getData (int index, int column) const;
|
||||
|
||||
virtual void setData (int index, int column, const QVariant& data);
|
||||
|
||||
virtual void removeRows (int index, int count);
|
||||
|
||||
virtual void appendBlankRecord (const std::string& id, UniversalId::Type type);
|
||||
///< \param type Will be ignored, unless the collection supports multiple record types
|
||||
|
||||
virtual int searchId (const std::string& id) const;
|
||||
////< Search record with \a id.
|
||||
/// \return index of record (if found) or -1 (not found)
|
||||
|
||||
virtual void replace (int index, const RecordBase& record);
|
||||
///< If the record type does not match, an exception is thrown.
|
||||
///
|
||||
/// \attention \a record must not change the ID.
|
||||
|
||||
virtual void appendRecord (const RecordBase& record, UniversalId::Type type);
|
||||
///< If the record type does not match, an exception is thrown.
|
||||
///
|
||||
///< \param type Will be ignored, unless the collection supports multiple record types
|
||||
|
||||
virtual const RecordBase& getRecord (const std::string& id) const;
|
||||
|
||||
virtual const RecordBase& getRecord (int index) const;
|
||||
|
||||
virtual void load (ESM::ESMReader& reader, bool base, UniversalId::Type type);
|
||||
|
||||
virtual int getAppendIndex (UniversalId::Type type) const;
|
||||
///< \param type Will be ignored, unless the collection supports multiple record types
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
198
apps/opencs/model/world/refiddata.cpp
Normal file
198
apps/opencs/model/world/refiddata.cpp
Normal file
|
@ -0,0 +1,198 @@
|
|||
|
||||
#include "refiddata.hpp"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
CSMWorld::RefIdDataContainerBase::~RefIdDataContainerBase() {}
|
||||
|
||||
CSMWorld::RefIdData::RefIdData()
|
||||
{
|
||||
mRecordContainers.insert (std::make_pair (UniversalId::Type_Activator, &mActivators));
|
||||
mRecordContainers.insert (std::make_pair (UniversalId::Type_Potion, &mPotions));
|
||||
mRecordContainers.insert (std::make_pair (UniversalId::Type_Apparatus, &mApparati));
|
||||
mRecordContainers.insert (std::make_pair (UniversalId::Type_Armor, &mArmors));
|
||||
mRecordContainers.insert (std::make_pair (UniversalId::Type_Book, &mBooks));
|
||||
mRecordContainers.insert (std::make_pair (UniversalId::Type_Clothing, &mClothing));
|
||||
mRecordContainers.insert (std::make_pair (UniversalId::Type_Container, &mContainers));
|
||||
mRecordContainers.insert (std::make_pair (UniversalId::Type_Creature, &mCreatures));
|
||||
mRecordContainers.insert (std::make_pair (UniversalId::Type_Door, &mDoors));
|
||||
mRecordContainers.insert (std::make_pair (UniversalId::Type_Ingredient, &mIngredients));
|
||||
mRecordContainers.insert (std::make_pair (UniversalId::Type_CreatureLevelledList,
|
||||
&mCreatureLevelledLists));
|
||||
mRecordContainers.insert (std::make_pair (UniversalId::Type_ItemLevelledList, &mItemLevelledLists));
|
||||
mRecordContainers.insert (std::make_pair (UniversalId::Type_Light, &mLights));
|
||||
mRecordContainers.insert (std::make_pair (UniversalId::Type_Lockpick, &mLockpicks));
|
||||
mRecordContainers.insert (std::make_pair (UniversalId::Type_Miscellaneous, &mMiscellaneous));
|
||||
mRecordContainers.insert (std::make_pair (UniversalId::Type_Npc, &mNpcs));
|
||||
mRecordContainers.insert (std::make_pair (UniversalId::Type_Probe, &mProbes));
|
||||
mRecordContainers.insert (std::make_pair (UniversalId::Type_Repair, &mRepairs));
|
||||
mRecordContainers.insert (std::make_pair (UniversalId::Type_Static, &mStatics));
|
||||
mRecordContainers.insert (std::make_pair (UniversalId::Type_Weapon, &mWeapons));
|
||||
}
|
||||
|
||||
CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::globalToLocalIndex (int index) const
|
||||
{
|
||||
for (std::map<UniversalId::Type, RefIdDataContainerBase *>::const_iterator iter (
|
||||
mRecordContainers.begin()); iter!=mRecordContainers.end(); ++iter)
|
||||
{
|
||||
if (index<iter->second->getSize())
|
||||
return LocalIndex (index, iter->first);
|
||||
|
||||
index -= iter->second->getSize();
|
||||
}
|
||||
|
||||
throw std::runtime_error ("RefIdData index out of range");
|
||||
}
|
||||
|
||||
int CSMWorld::RefIdData::localToGlobalIndex (const LocalIndex& index)
|
||||
const
|
||||
{
|
||||
std::map<UniversalId::Type, RefIdDataContainerBase *>::const_iterator end =
|
||||
mRecordContainers.find (index.second);
|
||||
|
||||
if (end==mRecordContainers.end())
|
||||
throw std::logic_error ("invalid local index type");
|
||||
|
||||
int globalIndex = index.first;
|
||||
|
||||
for (std::map<UniversalId::Type, RefIdDataContainerBase *>::const_iterator iter (
|
||||
mRecordContainers.begin()); iter!=end; ++iter)
|
||||
globalIndex += iter->second->getSize();
|
||||
|
||||
return globalIndex;
|
||||
}
|
||||
|
||||
CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::searchId (
|
||||
const std::string& id) const
|
||||
{
|
||||
std::string id2 = Misc::StringUtils::lowerCase (id);
|
||||
|
||||
std::map<std::string, std::pair<int, UniversalId::Type> >::const_iterator iter = mIndex.find (id2);
|
||||
|
||||
if (iter==mIndex.end())
|
||||
return std::make_pair (-1, CSMWorld::UniversalId::Type_None);
|
||||
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
void CSMWorld::RefIdData::erase (int index, int count)
|
||||
{
|
||||
LocalIndex localIndex = globalToLocalIndex (index);
|
||||
|
||||
std::map<UniversalId::Type, RefIdDataContainerBase *>::const_iterator iter =
|
||||
mRecordContainers.find (localIndex.second);
|
||||
|
||||
while (count>0 && iter!=mRecordContainers.end())
|
||||
{
|
||||
int size = iter->second->getSize();
|
||||
|
||||
if (localIndex.first+count>size)
|
||||
{
|
||||
erase (localIndex, size-localIndex.first);
|
||||
count -= size-localIndex.first;
|
||||
|
||||
++iter;
|
||||
|
||||
if (iter==mRecordContainers.end())
|
||||
throw std::runtime_error ("invalid count value for erase operation");
|
||||
|
||||
localIndex.first = 0;
|
||||
localIndex.second = iter->first;
|
||||
}
|
||||
else
|
||||
{
|
||||
erase (localIndex, count);
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const CSMWorld::RecordBase& CSMWorld::RefIdData::getRecord (const LocalIndex& index) const
|
||||
{
|
||||
std::map<UniversalId::Type, RefIdDataContainerBase *>::const_iterator iter =
|
||||
mRecordContainers.find (index.second);
|
||||
|
||||
if (iter==mRecordContainers.end())
|
||||
throw std::logic_error ("invalid local index type");
|
||||
|
||||
return iter->second->getRecord (index.first);
|
||||
}
|
||||
|
||||
CSMWorld::RecordBase& CSMWorld::RefIdData::getRecord (const LocalIndex& index)
|
||||
{
|
||||
std::map<UniversalId::Type, RefIdDataContainerBase *>::iterator iter =
|
||||
mRecordContainers.find (index.second);
|
||||
|
||||
if (iter==mRecordContainers.end())
|
||||
throw std::logic_error ("invalid local index type");
|
||||
|
||||
return iter->second->getRecord (index.first);
|
||||
}
|
||||
|
||||
void CSMWorld::RefIdData::appendRecord (UniversalId::Type type, const std::string& id)
|
||||
{
|
||||
std::map<UniversalId::Type, RefIdDataContainerBase *>::iterator iter =
|
||||
mRecordContainers.find (type);
|
||||
|
||||
if (iter==mRecordContainers.end())
|
||||
throw std::logic_error ("invalid local index type");
|
||||
|
||||
iter->second->appendRecord (id);
|
||||
|
||||
mIndex.insert (std::make_pair (Misc::StringUtils::lowerCase (id),
|
||||
LocalIndex (iter->second->getSize()-1, type)));
|
||||
}
|
||||
|
||||
int CSMWorld::RefIdData::getAppendIndex (UniversalId::Type type) const
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
for (std::map<UniversalId::Type, RefIdDataContainerBase *>::const_iterator iter (
|
||||
mRecordContainers.begin()); iter!=mRecordContainers.end(); ++iter)
|
||||
{
|
||||
index += iter->second->getSize();
|
||||
|
||||
if (type==iter->first)
|
||||
break;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
void CSMWorld::RefIdData::load (const LocalIndex& index, ESM::ESMReader& reader, bool base)
|
||||
{
|
||||
std::map<UniversalId::Type, RefIdDataContainerBase *>::iterator iter =
|
||||
mRecordContainers.find (index.second);
|
||||
|
||||
if (iter==mRecordContainers.end())
|
||||
throw std::logic_error ("invalid local index type");
|
||||
|
||||
iter->second->load (index.first, reader, base);
|
||||
}
|
||||
|
||||
void CSMWorld::RefIdData::erase (const LocalIndex& index, int count)
|
||||
{
|
||||
std::map<UniversalId::Type, RefIdDataContainerBase *>::iterator iter =
|
||||
mRecordContainers.find (index.second);
|
||||
|
||||
if (iter==mRecordContainers.end())
|
||||
throw std::logic_error ("invalid local index type");
|
||||
|
||||
for (int i=index.first; i<index.first+count; ++i)
|
||||
{
|
||||
std::map<std::string, LocalIndex>::iterator result =
|
||||
mIndex.find (Misc::StringUtils::lowerCase (iter->second->getId (i)));
|
||||
|
||||
if (result!=mIndex.end())
|
||||
mIndex.erase (result);
|
||||
}
|
||||
|
||||
iter->second->erase (index.first, count);
|
||||
}
|
||||
|
||||
int CSMWorld::RefIdData::getSize() const
|
||||
{
|
||||
return mIndex.size();
|
||||
}
|
188
apps/opencs/model/world/refiddata.hpp
Normal file
188
apps/opencs/model/world/refiddata.hpp
Normal file
|
@ -0,0 +1,188 @@
|
|||
#ifndef CSM_WOLRD_REFIDDATA_H
|
||||
#define CSM_WOLRD_REFIDDATA_H
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <components/esm/loadacti.hpp>
|
||||
#include <components/esm/loadalch.hpp>
|
||||
#include <components/esm/loadappa.hpp>
|
||||
#include <components/esm/loadarmo.hpp>
|
||||
#include <components/esm/loadbook.hpp>
|
||||
#include <components/esm/loadclot.hpp>
|
||||
#include <components/esm/loadcont.hpp>
|
||||
#include <components/esm/loadcrea.hpp>
|
||||
#include <components/esm/loaddoor.hpp>
|
||||
#include <components/esm/loadingr.hpp>
|
||||
#include <components/esm/loadlevlist.hpp>
|
||||
#include <components/esm/loadligh.hpp>
|
||||
#include <components/esm/loadlock.hpp>
|
||||
#include <components/esm/loadprob.hpp>
|
||||
#include <components/esm/loadrepa.hpp>
|
||||
#include <components/esm/loadstat.hpp>
|
||||
#include <components/esm/loadweap.hpp>
|
||||
#include <components/esm/loadnpc.hpp>
|
||||
#include <components/esm/loadmisc.hpp>
|
||||
|
||||
#include "record.hpp"
|
||||
#include "universalid.hpp"
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
class ESMReader;
|
||||
}
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
struct RefIdDataContainerBase
|
||||
{
|
||||
virtual ~RefIdDataContainerBase();
|
||||
|
||||
virtual int getSize() const = 0;
|
||||
|
||||
virtual const RecordBase& getRecord (int index) const = 0;
|
||||
|
||||
virtual RecordBase& getRecord (int index)= 0;
|
||||
|
||||
virtual void appendRecord (const std::string& id) = 0;
|
||||
|
||||
virtual void load (int index, ESM::ESMReader& reader, bool base) = 0;
|
||||
|
||||
virtual void erase (int index, int count) = 0;
|
||||
|
||||
virtual std::string getId (int index) const = 0;
|
||||
};
|
||||
|
||||
template<typename RecordT>
|
||||
struct RefIdDataContainer : public RefIdDataContainerBase
|
||||
{
|
||||
std::vector<Record<RecordT> > mContainer;
|
||||
|
||||
virtual int getSize() const;
|
||||
|
||||
virtual const RecordBase& getRecord (int index) const;
|
||||
|
||||
virtual RecordBase& getRecord (int index);
|
||||
|
||||
virtual void appendRecord (const std::string& id);
|
||||
|
||||
virtual void load (int index, ESM::ESMReader& reader, bool base);
|
||||
|
||||
virtual void erase (int index, int count);
|
||||
|
||||
virtual std::string getId (int index) const;
|
||||
};
|
||||
|
||||
template<typename RecordT>
|
||||
int RefIdDataContainer<RecordT>::getSize() const
|
||||
{
|
||||
return static_cast<int> (mContainer.size());
|
||||
}
|
||||
|
||||
template<typename RecordT>
|
||||
const RecordBase& RefIdDataContainer<RecordT>::getRecord (int index) const
|
||||
{
|
||||
return mContainer.at (index);
|
||||
}
|
||||
|
||||
template<typename RecordT>
|
||||
RecordBase& RefIdDataContainer<RecordT>::getRecord (int index)
|
||||
{
|
||||
return mContainer.at (index);
|
||||
}
|
||||
|
||||
template<typename RecordT>
|
||||
void RefIdDataContainer<RecordT>::appendRecord (const std::string& id)
|
||||
{
|
||||
Record<RecordT> record;
|
||||
record.mModified.mId = id;
|
||||
record.mModified.blank();
|
||||
record.mState = RecordBase::State_ModifiedOnly;
|
||||
|
||||
mContainer.push_back (record);
|
||||
}
|
||||
|
||||
template<typename RecordT>
|
||||
void RefIdDataContainer<RecordT>::load (int index, ESM::ESMReader& reader, bool base)
|
||||
{
|
||||
(base ? mContainer.at (index).mBase : mContainer.at (index).mModified).load (reader);
|
||||
}
|
||||
|
||||
template<typename RecordT>
|
||||
void RefIdDataContainer<RecordT>::erase (int index, int count)
|
||||
{
|
||||
if (index<0 || index+count>=getSize())
|
||||
throw std::runtime_error ("invalid RefIdDataContainer index");
|
||||
|
||||
mContainer.erase (mContainer.begin()+index, mContainer.begin()+index+count);
|
||||
}
|
||||
|
||||
template<typename RecordT>
|
||||
std::string RefIdDataContainer<RecordT>::getId (int index) const
|
||||
{
|
||||
return mContainer.at (index).get().mId;
|
||||
}
|
||||
|
||||
class RefIdData
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::pair<int, UniversalId::Type> LocalIndex;
|
||||
|
||||
private:
|
||||
|
||||
RefIdDataContainer<ESM::Activator> mActivators;
|
||||
RefIdDataContainer<ESM::Potion> mPotions;
|
||||
RefIdDataContainer<ESM::Apparatus> mApparati;
|
||||
RefIdDataContainer<ESM::Armor> mArmors;
|
||||
RefIdDataContainer<ESM::Book> mBooks;
|
||||
RefIdDataContainer<ESM::Clothing> mClothing;
|
||||
RefIdDataContainer<ESM::Container> mContainers;
|
||||
RefIdDataContainer<ESM::Creature> mCreatures;
|
||||
RefIdDataContainer<ESM::Door> mDoors;
|
||||
RefIdDataContainer<ESM::Ingredient> mIngredients;
|
||||
RefIdDataContainer<ESM::CreatureLevList> mCreatureLevelledLists;
|
||||
RefIdDataContainer<ESM::ItemLevList> mItemLevelledLists;
|
||||
RefIdDataContainer<ESM::Light> mLights;
|
||||
RefIdDataContainer<ESM::Lockpick> mLockpicks;
|
||||
RefIdDataContainer<ESM::Miscellaneous> mMiscellaneous;
|
||||
RefIdDataContainer<ESM::NPC> mNpcs;
|
||||
RefIdDataContainer<ESM::Probe> mProbes;
|
||||
RefIdDataContainer<ESM::Repair> mRepairs;
|
||||
RefIdDataContainer<ESM::Static> mStatics;
|
||||
RefIdDataContainer<ESM::Weapon> mWeapons;
|
||||
|
||||
std::map<std::string, LocalIndex> mIndex;
|
||||
|
||||
std::map<UniversalId::Type, RefIdDataContainerBase *> mRecordContainers;
|
||||
|
||||
void erase (const LocalIndex& index, int count);
|
||||
///< Must not spill over into another type.
|
||||
|
||||
public:
|
||||
|
||||
RefIdData();
|
||||
|
||||
LocalIndex globalToLocalIndex (int index) const;
|
||||
|
||||
int localToGlobalIndex (const LocalIndex& index) const;
|
||||
|
||||
LocalIndex searchId (const std::string& id) const;
|
||||
|
||||
void erase (int index, int count);
|
||||
|
||||
const RecordBase& getRecord (const LocalIndex& index) const;
|
||||
|
||||
RecordBase& getRecord (const LocalIndex& index);
|
||||
|
||||
void appendRecord (UniversalId::Type type, const std::string& id);
|
||||
|
||||
int getAppendIndex (UniversalId::Type type) const;
|
||||
|
||||
void load (const LocalIndex& index, ESM::ESMReader& reader, bool base);
|
||||
|
||||
int getSize() const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
22
apps/opencs/model/world/scriptcontext.cpp
Normal file
22
apps/opencs/model/world/scriptcontext.cpp
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
#include "scriptcontext.hpp"
|
||||
|
||||
bool CSMWorld::ScriptContext::canDeclareLocals() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char CSMWorld::ScriptContext::getGlobalType (const std::string& name) const
|
||||
{
|
||||
return ' ';
|
||||
}
|
||||
|
||||
char CSMWorld::ScriptContext::getMemberType (const std::string& name, const std::string& id) const
|
||||
{
|
||||
return ' ';
|
||||
}
|
||||
|
||||
bool CSMWorld::ScriptContext::isId (const std::string& name) const
|
||||
{
|
||||
return false;
|
||||
}
|
26
apps/opencs/model/world/scriptcontext.hpp
Normal file
26
apps/opencs/model/world/scriptcontext.hpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef CSM_WORLD_SCRIPTCONTEXT_H
|
||||
#define CSM_WORLD_SCRIPTCONTEXT_H
|
||||
|
||||
#include <components/compiler/context.hpp>
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class ScriptContext : public Compiler::Context
|
||||
{
|
||||
public:
|
||||
|
||||
virtual bool canDeclareLocals() const;
|
||||
///< Is the compiler allowed to declare local variables?
|
||||
|
||||
virtual char getGlobalType (const std::string& name) const;
|
||||
///< 'l: long, 's': short, 'f': float, ' ': does not exist.
|
||||
|
||||
virtual char getMemberType (const std::string& name, const std::string& id) const;
|
||||
///< 'l: long, 's': short, 'f': float, ' ': does not exist.
|
||||
|
||||
virtual bool isId (const std::string& name) const;
|
||||
///< Does \a name match an ID, that can be referenced?
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -19,6 +19,18 @@ namespace
|
|||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, "empty" },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Globals, "Global Variables" },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Gmsts, "Game Settings" },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Skills, "Skills" },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Classes, "Classes" },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Factions, "Factions" },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Races, "Races" },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Sounds, "Sounds" },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Scripts, "Scripts" },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Regions, "Regions" },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Birthsigns, "Birthsigns" },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Spells, "Spells" },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Cells, "Cells" },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Referenceables,
|
||||
"Referenceables" },
|
||||
|
||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
|
||||
};
|
||||
|
@ -27,6 +39,40 @@ namespace
|
|||
{
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Gmst, "Game Setting" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Skill, "Skill" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Class, "Class" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Faction, "Faction" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Race, "Race" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Sound, "Sound" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Script, "Script" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Region, "Region" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Birthsign, "Birthsign" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Spell, "Spell" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell, "Cell" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Referenceable, "Referenceables" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Activator, "Activator" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Potion, "Potion" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Apparatus, "Apparatus" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Armor, "Armor" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Book, "Book" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Clothing, "Clothing" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Container, "Container" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Creature, "Creature" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Door, "Door" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Ingredient, "Ingredient" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_CreatureLevelledList,
|
||||
"Creature Levelled List" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_ItemLevelledList,
|
||||
"Item Levelled List" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Light, "Light" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Lockpick, "Lockpick" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Miscellaneous,
|
||||
"Miscellaneous" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Npc, "NPC" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Probe, "Probe" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Repair, "Repair" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Static, "Static" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Weapon, "Weapon" },
|
||||
|
||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
|
||||
};
|
||||
|
@ -43,48 +89,45 @@ CSMWorld::UniversalId::UniversalId (const std::string& universalId)
|
|||
{
|
||||
std::string::size_type index = universalId.find (':');
|
||||
|
||||
if (index==std::string::npos)
|
||||
if (index!=std::string::npos)
|
||||
{
|
||||
std::string type = universalId.substr (0, index);
|
||||
|
||||
if (index==std::string::npos)
|
||||
{
|
||||
for (int i=0; sNoArg[i].mName; ++i)
|
||||
if (type==sNoArg[i].mName)
|
||||
{
|
||||
mArgumentType = ArgumentType_None;
|
||||
mType = sNoArg[i].mType;
|
||||
mClass = sNoArg[i].mClass;
|
||||
for (int i=0; sIdArg[i].mName; ++i)
|
||||
if (type==sIdArg[i].mName)
|
||||
{
|
||||
mArgumentType = ArgumentType_Id;
|
||||
mType = sIdArg[i].mType;
|
||||
mClass = sIdArg[i].mClass;
|
||||
mId = universalId.substr (index+2);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i=0; sIndexArg[i].mName; ++i)
|
||||
if (type==sIndexArg[i].mName)
|
||||
{
|
||||
mArgumentType = ArgumentType_Index;
|
||||
mType = sIndexArg[i].mType;
|
||||
mClass = sIndexArg[i].mClass;
|
||||
|
||||
std::istringstream stream (universalId.substr (index+2));
|
||||
|
||||
if (stream >> mIndex)
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i=0; sIdArg[i].mName; ++i)
|
||||
if (type==sIdArg[i].mName)
|
||||
{
|
||||
mArgumentType = ArgumentType_Id;
|
||||
mType = sIdArg[i].mType;
|
||||
mClass = sIdArg[i].mClass;
|
||||
mId = universalId.substr (0, index);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i=0; sIndexArg[i].mName; ++i)
|
||||
if (type==sIndexArg[i].mName)
|
||||
{
|
||||
mArgumentType = ArgumentType_Index;
|
||||
mType = sIndexArg[i].mType;
|
||||
mClass = sIndexArg[i].mClass;
|
||||
|
||||
std::istringstream stream (universalId.substr (0, index));
|
||||
|
||||
if (stream >> mIndex)
|
||||
return;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i=0; sNoArg[i].mName; ++i)
|
||||
if (universalId==sNoArg[i].mName)
|
||||
{
|
||||
mArgumentType = ArgumentType_None;
|
||||
mType = sNoArg[i].mType;
|
||||
mClass = sNoArg[i].mClass;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw std::runtime_error ("invalid UniversalId: " + universalId);
|
||||
|
|
|
@ -37,7 +37,49 @@ namespace CSMWorld
|
|||
Type_Global,
|
||||
Type_VerificationResults,
|
||||
Type_Gmsts,
|
||||
Type_Gmst
|
||||
Type_Gmst,
|
||||
Type_Skills,
|
||||
Type_Skill,
|
||||
Type_Classes,
|
||||
Type_Class,
|
||||
Type_Factions,
|
||||
Type_Faction,
|
||||
Type_Races,
|
||||
Type_Race,
|
||||
Type_Sounds,
|
||||
Type_Sound,
|
||||
Type_Scripts,
|
||||
Type_Script,
|
||||
Type_Regions,
|
||||
Type_Region,
|
||||
Type_Birthsigns,
|
||||
Type_Birthsign,
|
||||
Type_Spells,
|
||||
Type_Spell,
|
||||
Type_Cells,
|
||||
Type_Cell,
|
||||
Type_Referenceables,
|
||||
Type_Referenceable,
|
||||
Type_Activator,
|
||||
Type_Potion,
|
||||
Type_Apparatus,
|
||||
Type_Armor,
|
||||
Type_Book,
|
||||
Type_Clothing,
|
||||
Type_Container,
|
||||
Type_Creature,
|
||||
Type_Door,
|
||||
Type_Ingredient,
|
||||
Type_CreatureLevelledList,
|
||||
Type_ItemLevelledList,
|
||||
Type_Light,
|
||||
Type_Lockpick,
|
||||
Type_Miscellaneous,
|
||||
Type_Npc,
|
||||
Type_Probe,
|
||||
Type_Repair,
|
||||
Type_Static,
|
||||
Type_Weapon
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>UserSettingsDialog</class>
|
||||
<widget class="QDialog" name="UserSettingsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>638</width>
|
||||
<height>478</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>440</y>
|
||||
<width>621</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close</set>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>UserSettingsDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>UserSettingsDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
|
@ -56,7 +56,7 @@ void CSVDoc::Operations::quitOperation (int type)
|
|||
|
||||
mLayout->removeItem ((*iter)->getLayout());
|
||||
|
||||
delete *iter;
|
||||
(*iter)->deleteLater();
|
||||
mOperations.erase (iter);
|
||||
|
||||
if (oldCount > 1)
|
||||
|
|
|
@ -7,17 +7,16 @@
|
|||
#include <QMenuBar>
|
||||
#include <QMdiArea>
|
||||
#include <QDockWidget>
|
||||
#include <QtGui/QApplication>
|
||||
|
||||
#include "../../model/doc/document.hpp"
|
||||
#include "../world/subviews.hpp"
|
||||
#include "../tools/subviews.hpp"
|
||||
#include "../../settings/usersettingsdialog.hpp"
|
||||
#include "../settings/usersettingsdialog.hpp"
|
||||
#include "viewmanager.hpp"
|
||||
#include "operations.hpp"
|
||||
#include "subview.hpp"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
void CSVDoc::View::closeEvent (QCloseEvent *event)
|
||||
{
|
||||
if (!mViewManager.closeRequest (this))
|
||||
|
@ -39,6 +38,20 @@ void CSVDoc::View::setupFileMenu()
|
|||
mSave = new QAction (tr ("&Save"), this);
|
||||
connect (mSave, SIGNAL (triggered()), this, SLOT (save()));
|
||||
file->addAction (mSave);
|
||||
|
||||
mVerify = new QAction (tr ("&Verify"), this);
|
||||
connect (mVerify, SIGNAL (triggered()), this, SLOT (verify()));
|
||||
file->addAction (mVerify);
|
||||
|
||||
QAction *close = new QAction (tr ("&Close"), this);
|
||||
connect (close, SIGNAL (triggered()), this, SLOT (close()));
|
||||
file->addAction(close);
|
||||
|
||||
QAction *exit = new QAction (tr ("&Exit"), this);
|
||||
connect (exit, SIGNAL (triggered()), this, SLOT (exit()));
|
||||
connect (this, SIGNAL(exitApplicationRequest(CSVDoc::View *)), &mViewManager, SLOT(exitApplication(CSVDoc::View *)));
|
||||
|
||||
file->addAction(exit);
|
||||
}
|
||||
|
||||
void CSVDoc::View::setupEditMenu()
|
||||
|
@ -52,6 +65,10 @@ void CSVDoc::View::setupEditMenu()
|
|||
mRedo= mDocument->getUndoStack().createRedoAction (this, tr("&Redo"));
|
||||
mRedo->setShortcuts (QKeySequence::Redo);
|
||||
edit->addAction (mRedo);
|
||||
|
||||
QAction *userSettings = new QAction (tr ("&Preferences"), this);
|
||||
connect (userSettings, SIGNAL (triggered()), this, SLOT (showUserSettings()));
|
||||
edit->addAction (userSettings);
|
||||
}
|
||||
|
||||
void CSVDoc::View::setupViewMenu()
|
||||
|
@ -75,18 +92,49 @@ void CSVDoc::View::setupWorldMenu()
|
|||
connect (gmsts, SIGNAL (triggered()), this, SLOT (addGmstsSubView()));
|
||||
world->addAction (gmsts);
|
||||
|
||||
mVerify = new QAction (tr ("&Verify"), this);
|
||||
connect (mVerify, SIGNAL (triggered()), this, SLOT (verify()));
|
||||
world->addAction (mVerify);
|
||||
}
|
||||
QAction *skills = new QAction (tr ("Skills"), this);
|
||||
connect (skills, SIGNAL (triggered()), this, SLOT (addSkillsSubView()));
|
||||
world->addAction (skills);
|
||||
|
||||
void CSVDoc::View::setupSettingsMenu()
|
||||
{
|
||||
QMenu *settings = menuBar()->addMenu( (tr ("&Settings")));
|
||||
QAction *classes = new QAction (tr ("Classes"), this);
|
||||
connect (classes, SIGNAL (triggered()), this, SLOT (addClassesSubView()));
|
||||
world->addAction (classes);
|
||||
|
||||
QAction *userSettings = new QAction (tr ("User Settings"), this);
|
||||
connect (userSettings, SIGNAL (triggered()), this, SLOT (showUserSettings()));
|
||||
settings->addAction (userSettings);
|
||||
QAction *factions = new QAction (tr ("Factions"), this);
|
||||
connect (factions, SIGNAL (triggered()), this, SLOT (addFactionsSubView()));
|
||||
world->addAction (factions);
|
||||
|
||||
QAction *races = new QAction (tr ("Races"), this);
|
||||
connect (races, SIGNAL (triggered()), this, SLOT (addRacesSubView()));
|
||||
world->addAction (races);
|
||||
|
||||
QAction *sounds = new QAction (tr ("Sounds"), this);
|
||||
connect (sounds, SIGNAL (triggered()), this, SLOT (addSoundsSubView()));
|
||||
world->addAction (sounds);
|
||||
|
||||
QAction *scripts = new QAction (tr ("Scripts"), this);
|
||||
connect (scripts, SIGNAL (triggered()), this, SLOT (addScriptsSubView()));
|
||||
world->addAction (scripts);
|
||||
|
||||
QAction *regions = new QAction (tr ("Regions"), this);
|
||||
connect (regions, SIGNAL (triggered()), this, SLOT (addRegionsSubView()));
|
||||
world->addAction (regions);
|
||||
|
||||
QAction *birthsigns = new QAction (tr ("Birthsigns"), this);
|
||||
connect (birthsigns, SIGNAL (triggered()), this, SLOT (addBirthsignsSubView()));
|
||||
world->addAction (birthsigns);
|
||||
|
||||
QAction *spells = new QAction (tr ("Spells"), this);
|
||||
connect (spells, SIGNAL (triggered()), this, SLOT (addSpellsSubView()));
|
||||
world->addAction (spells);
|
||||
|
||||
QAction *cells = new QAction (tr ("Cells"), this);
|
||||
connect (cells, SIGNAL (triggered()), this, SLOT (addCellsSubView()));
|
||||
world->addAction (cells);
|
||||
|
||||
QAction *referenceables = new QAction (tr ("Referenceables"), this);
|
||||
connect (referenceables, SIGNAL (triggered()), this, SLOT (addReferenceablesSubView()));
|
||||
world->addAction (referenceables);
|
||||
|
||||
}
|
||||
|
||||
|
@ -96,7 +144,6 @@ void CSVDoc::View::setupUi()
|
|||
setupEditMenu();
|
||||
setupViewMenu();
|
||||
setupWorldMenu();
|
||||
setupSettingsMenu();
|
||||
}
|
||||
|
||||
void CSVDoc::View::updateTitle()
|
||||
|
@ -128,15 +175,15 @@ void CSVDoc::View::updateActions()
|
|||
mVerify->setEnabled (!(mDocument->getState() & CSMDoc::State_Verifying));
|
||||
}
|
||||
|
||||
CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews, QMainWindow *viewParent)
|
||||
: mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1), mViewTotal (totalViews), QMainWindow (viewParent)
|
||||
CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews)
|
||||
: mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1),
|
||||
mViewTotal (totalViews)
|
||||
{
|
||||
setDockOptions (QMainWindow::AllowNestedDocks);
|
||||
|
||||
resize (300, 300); /// \todo get default size from settings and set reasonable minimal size
|
||||
|
||||
mSubViewWindow = new QMainWindow();
|
||||
setCentralWidget (mSubViewWindow);
|
||||
mSubViewWindow.setDockOptions (QMainWindow::AllowNestedDocks);
|
||||
|
||||
setCentralWidget (&mSubViewWindow);
|
||||
|
||||
mOperations = new Operations;
|
||||
addDockWidget (Qt::BottomDockWidgetArea, mOperations);
|
||||
|
@ -211,7 +258,7 @@ 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)
|
||||
|
||||
SubView *view = mSubViewFactory.makeSubView (id, *mDocument);
|
||||
mSubViewWindow->addDockWidget (Qt::TopDockWidgetArea, view);
|
||||
mSubViewWindow.addDockWidget (Qt::TopDockWidgetArea, view);
|
||||
|
||||
connect (view, SIGNAL (focusId (const CSMWorld::UniversalId&)), this,
|
||||
SLOT (addSubView (const CSMWorld::UniversalId&)));
|
||||
|
@ -244,22 +291,82 @@ void CSVDoc::View::addGmstsSubView()
|
|||
addSubView (CSMWorld::UniversalId::Type_Gmsts);
|
||||
}
|
||||
|
||||
void CSVDoc::View::addSkillsSubView()
|
||||
{
|
||||
addSubView (CSMWorld::UniversalId::Type_Skills);
|
||||
}
|
||||
|
||||
void CSVDoc::View::addClassesSubView()
|
||||
{
|
||||
addSubView (CSMWorld::UniversalId::Type_Classes);
|
||||
}
|
||||
|
||||
void CSVDoc::View::addFactionsSubView()
|
||||
{
|
||||
addSubView (CSMWorld::UniversalId::Type_Factions);
|
||||
}
|
||||
|
||||
void CSVDoc::View::addRacesSubView()
|
||||
{
|
||||
addSubView (CSMWorld::UniversalId::Type_Races);
|
||||
}
|
||||
|
||||
void CSVDoc::View::addSoundsSubView()
|
||||
{
|
||||
addSubView (CSMWorld::UniversalId::Type_Sounds);
|
||||
}
|
||||
|
||||
void CSVDoc::View::addScriptsSubView()
|
||||
{
|
||||
addSubView (CSMWorld::UniversalId::Type_Scripts);
|
||||
}
|
||||
|
||||
void CSVDoc::View::addRegionsSubView()
|
||||
{
|
||||
addSubView (CSMWorld::UniversalId::Type_Regions);
|
||||
}
|
||||
|
||||
void CSVDoc::View::addBirthsignsSubView()
|
||||
{
|
||||
addSubView (CSMWorld::UniversalId::Type_Birthsigns);
|
||||
}
|
||||
|
||||
void CSVDoc::View::addSpellsSubView()
|
||||
{
|
||||
addSubView (CSMWorld::UniversalId::Type_Spells);
|
||||
}
|
||||
|
||||
void CSVDoc::View::addCellsSubView()
|
||||
{
|
||||
addSubView (CSMWorld::UniversalId::Type_Cells);
|
||||
}
|
||||
|
||||
void CSVDoc::View::addReferenceablesSubView()
|
||||
{
|
||||
addSubView (CSMWorld::UniversalId::Type_Referenceables);
|
||||
}
|
||||
|
||||
void CSVDoc::View::abortOperation (int type)
|
||||
{
|
||||
mDocument->abortOperation (type);
|
||||
updateActions();
|
||||
}
|
||||
|
||||
QDockWidget *CSVDoc::View::getOperations() const
|
||||
CSVDoc::Operations *CSVDoc::View::getOperations() const
|
||||
{
|
||||
return mOperations;
|
||||
}
|
||||
|
||||
void CSVDoc::View::exit()
|
||||
{
|
||||
emit exitApplicationRequest (this);
|
||||
}
|
||||
|
||||
void CSVDoc::View::showUserSettings()
|
||||
{
|
||||
CsSettings::UserSettingsDialog *settingsDialog = new CsSettings::UserSettingsDialog(this);
|
||||
CSVSettings::UserSettingsDialog *settingsDialog = new CSVSettings::UserSettingsDialog(this);
|
||||
|
||||
connect (settingsDialog, SIGNAL (signalUpdateEditorSetting (const QString &, const QString &)),
|
||||
connect (&(CSMSettings::UserSettings::instance()), SIGNAL (signalUpdateEditorSetting (const QString &, const QString &)),
|
||||
this, SLOT (slotUpdateEditorSetting (const QString &, const QString &)) );
|
||||
|
||||
settingsDialog->show();
|
||||
|
@ -271,11 +378,7 @@ void CSVDoc::View::slotUpdateEditorSetting(const QString &settingName, const QSt
|
|||
|
||||
if (lastValue != settingValue)
|
||||
{
|
||||
if (settingName == "Undo Stack Size");
|
||||
|
||||
if (settingName == "Top-Level Window Count");
|
||||
|
||||
if (settingName == "Reuse Subwindows");
|
||||
//evaluate settingName against tokens to determine which function to call to update Editor application.
|
||||
|
||||
lastValue = settingValue;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,8 @@ namespace CSVDoc
|
|||
std::vector<QAction *> mEditingActions;
|
||||
Operations *mOperations;
|
||||
SubViewFactoryManager mSubViewFactory;
|
||||
QMainWindow* mSubViewWindow;
|
||||
QMainWindow mSubViewWindow;
|
||||
|
||||
|
||||
// not implemented
|
||||
View (const View&);
|
||||
|
@ -59,17 +60,18 @@ namespace CSVDoc
|
|||
|
||||
void setupWorldMenu();
|
||||
|
||||
void setupSettingsMenu();
|
||||
|
||||
void setupUi();
|
||||
|
||||
void updateTitle();
|
||||
|
||||
void updateActions();
|
||||
|
||||
void exitApplication();
|
||||
|
||||
public:
|
||||
|
||||
View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews, QMainWindow *viewParent);
|
||||
View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews);
|
||||
|
||||
///< The ownership of \a document is not transferred to *this.
|
||||
|
||||
virtual ~View();
|
||||
|
@ -84,7 +86,7 @@ namespace CSVDoc
|
|||
|
||||
void updateProgress (int current, int max, int type, int threads);
|
||||
|
||||
QDockWidget *getOperations() const;
|
||||
Operations *getOperations() const;
|
||||
|
||||
signals:
|
||||
|
||||
|
@ -92,10 +94,14 @@ namespace CSVDoc
|
|||
|
||||
void loadDocumentRequest();
|
||||
|
||||
void exitApplicationRequest (CSVDoc::View *view);
|
||||
|
||||
public slots:
|
||||
|
||||
void addSubView (const CSMWorld::UniversalId& id);
|
||||
|
||||
void abortOperation (int type);
|
||||
|
||||
void slotUpdateEditorSetting (const QString &settingName, const QString &settingValue);
|
||||
|
||||
private slots:
|
||||
|
@ -104,13 +110,35 @@ namespace CSVDoc
|
|||
|
||||
void save();
|
||||
|
||||
void exit();
|
||||
|
||||
void verify();
|
||||
|
||||
void addGlobalsSubView();
|
||||
|
||||
void addGmstsSubView();
|
||||
|
||||
void abortOperation (int type);
|
||||
void addSkillsSubView();
|
||||
|
||||
void addClassesSubView();
|
||||
|
||||
void addFactionsSubView();
|
||||
|
||||
void addRacesSubView();
|
||||
|
||||
void addSoundsSubView();
|
||||
|
||||
void addScriptsSubView();
|
||||
|
||||
void addRegionsSubView();
|
||||
|
||||
void addBirthsignsSubView();
|
||||
|
||||
void addSpellsSubView();
|
||||
|
||||
void addCellsSubView();
|
||||
|
||||
void addReferenceablesSubView();
|
||||
|
||||
void showUserSettings();
|
||||
};
|
||||
|
|
|
@ -15,6 +15,11 @@
|
|||
|
||||
#include "view.hpp"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QtGui/QApplication>
|
||||
#include <QDebug>
|
||||
|
||||
void CSVDoc::ViewManager::updateIndices()
|
||||
{
|
||||
std::map<CSMDoc::Document *, std::pair<int, int> > documents;
|
||||
|
@ -34,8 +39,53 @@ void CSVDoc::ViewManager::updateIndices()
|
|||
}
|
||||
|
||||
CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager)
|
||||
: mDocumentManager (documentManager)
|
||||
: mDocumentManager (documentManager), mExitOnSaveStateChange(false), mUserWarned(false)
|
||||
{
|
||||
static const char *sSpecialisations[] =
|
||||
{
|
||||
"Combat", "Magic", "Stealth", 0
|
||||
};
|
||||
|
||||
static const char *sAttributes[] =
|
||||
{
|
||||
"Strength", "Intelligence", "Willpower", "Agility", "Speed", "Endurance", "Personality",
|
||||
"Luck", 0
|
||||
};
|
||||
|
||||
static const char *sSpellTypes[] =
|
||||
{
|
||||
"Spell", "Ability", "Blight", "Disease", "Curse", "Power", 0
|
||||
};
|
||||
|
||||
static const char *sApparatusTypes[] =
|
||||
{
|
||||
"Mortar & Pestle", "Albemic", "Calcinator", "Retort", 0
|
||||
};
|
||||
|
||||
static const char *sArmorTypes[] =
|
||||
{
|
||||
"Helmet", "Cuirass", "Left Pauldron", "Right Pauldron", "Greaves", "Boots", "Left Gauntlet",
|
||||
"Right Gauntlet", "Shield", "Left Bracer", "Right Bracer", 0
|
||||
};
|
||||
|
||||
static const char *sClothingTypes[] =
|
||||
{
|
||||
"Pants", "Shoes", "Shirt", "Belt", "Robe", "Right Glove", "Left Glove", "Skirt", "Ring",
|
||||
"Amulet", 0
|
||||
};
|
||||
|
||||
static const char *sCreatureTypes[] =
|
||||
{
|
||||
"Creature", "Deadra", "Undead", "Humanoid", 0
|
||||
};
|
||||
|
||||
static const char *sWeaponTypes[] =
|
||||
{
|
||||
"Short Blade 1H", "Long Blade 1H", "Long Blade 2H", "Blunt 1H", "Blunt 2H Close",
|
||||
"Blunt 2H Wide", "Spear 2H", "Axe 1H", "Axe 2H", "Bow", "Crossbow", "Thrown", "Arrow",
|
||||
"Bolt", 0
|
||||
};
|
||||
|
||||
mDelegateFactories = new CSVWorld::CommandDelegateFactoryCollection;
|
||||
|
||||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_GmstVarType,
|
||||
|
@ -44,6 +94,29 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager)
|
|||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_GlobalVarType,
|
||||
new CSVWorld::VarTypeDelegateFactory (ESM::VT_Short, ESM::VT_Long, ESM::VT_Float));
|
||||
|
||||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_Specialisation,
|
||||
new CSVWorld::EnumDelegateFactory (sSpecialisations));
|
||||
|
||||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_Attribute,
|
||||
new CSVWorld::EnumDelegateFactory (sAttributes, true));
|
||||
|
||||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_SpellType,
|
||||
new CSVWorld::EnumDelegateFactory (sSpellTypes));
|
||||
|
||||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_ApparatusType,
|
||||
new CSVWorld::EnumDelegateFactory (sApparatusTypes));
|
||||
|
||||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_ArmorType,
|
||||
new CSVWorld::EnumDelegateFactory (sArmorTypes));
|
||||
|
||||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_ClothingType,
|
||||
new CSVWorld::EnumDelegateFactory (sClothingTypes));
|
||||
|
||||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_CreatureType,
|
||||
new CSVWorld::EnumDelegateFactory (sCreatureTypes));
|
||||
|
||||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_WeaponType,
|
||||
new CSVWorld::EnumDelegateFactory (sWeaponTypes));
|
||||
}
|
||||
|
||||
CSVDoc::ViewManager::~ViewManager()
|
||||
|
@ -66,18 +139,11 @@ CSVDoc::View *CSVDoc::ViewManager::addView (CSMDoc::Document *document)
|
|||
this, SLOT (progress (int, int, int, int, CSMDoc::Document *)));
|
||||
}
|
||||
|
||||
QMainWindow *mainWindow = new QMainWindow;
|
||||
View *view = new View (*this, document, countViews (document)+1);
|
||||
|
||||
View *view = new View (*this, document, countViews (document)+1, mainWindow);
|
||||
|
||||
mViews.push_back (view);
|
||||
|
||||
if (mViews.size()==1)
|
||||
{
|
||||
QRect scr = QApplication::desktop()->screenGeometry();
|
||||
QRect rect = view->geometry();
|
||||
view->move (scr.center().x() - rect.center().x(), scr.center().y() - rect.center().y());
|
||||
}
|
||||
view->show();
|
||||
|
||||
connect (view, SIGNAL (newDocumentRequest ()), this, SIGNAL (newDocumentRequest()));
|
||||
|
@ -103,23 +169,143 @@ bool CSVDoc::ViewManager::closeRequest (View *view)
|
|||
{
|
||||
std::vector<View *>::iterator iter = std::find (mViews.begin(), mViews.end(), view);
|
||||
|
||||
bool continueWithClose = true;
|
||||
|
||||
if (iter!=mViews.end())
|
||||
{
|
||||
bool last = countViews (view->getDocument())<=1;
|
||||
|
||||
/// \todo check if save is in progress -> warn user about possible data loss
|
||||
/// \todo check if document has not been saved -> return false and start close dialogue
|
||||
|
||||
mViews.erase (iter);
|
||||
view->deleteLater();
|
||||
|
||||
if (last)
|
||||
mDocumentManager.removeDocument (view->getDocument());
|
||||
continueWithClose = notifySaveOnClose (view);
|
||||
else
|
||||
{
|
||||
(*iter)->deleteLater();
|
||||
mViews.erase (iter);
|
||||
|
||||
updateIndices();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return continueWithClose;
|
||||
}
|
||||
|
||||
bool CSVDoc::ViewManager::notifySaveOnClose (CSVDoc::View *view)
|
||||
{
|
||||
bool result = true;
|
||||
CSMDoc::Document *document = view->getDocument();
|
||||
|
||||
//notify user of saving in progress
|
||||
if ( (document->getState() & CSMDoc::State_Saving) )
|
||||
result = showSaveInProgressMessageBox (view);
|
||||
|
||||
//notify user of unsaved changes and process response
|
||||
else if ( document->getState() & CSMDoc::State_Modified)
|
||||
result = showModifiedDocumentMessageBox (view);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CSVDoc::ViewManager::showModifiedDocumentMessageBox (CSVDoc::View *view)
|
||||
{
|
||||
QMessageBox messageBox;
|
||||
CSMDoc::Document *document = view->getDocument();
|
||||
|
||||
messageBox.setText ("The document has been modified.");
|
||||
messageBox.setInformativeText ("Do you want to save your changes?");
|
||||
messageBox.setStandardButtons (QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
|
||||
messageBox.setDefaultButton (QMessageBox::Save);
|
||||
|
||||
bool retVal = true;
|
||||
|
||||
connect (this, SIGNAL (closeMessageBox()), &messageBox, SLOT (close()));
|
||||
|
||||
connect (document, SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *)));
|
||||
|
||||
mUserWarned = true;
|
||||
int response = messageBox.exec();
|
||||
mUserWarned = false;
|
||||
|
||||
switch (response)
|
||||
{
|
||||
case QMessageBox::Save:
|
||||
|
||||
document->save();
|
||||
mExitOnSaveStateChange = true;
|
||||
retVal = false;
|
||||
break;
|
||||
|
||||
case QMessageBox::Discard:
|
||||
|
||||
disconnect (document, SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *)));
|
||||
break;
|
||||
|
||||
case QMessageBox::Cancel:
|
||||
|
||||
//disconnect to prevent unintended view closures
|
||||
disconnect (document, SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *)));
|
||||
retVal = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool CSVDoc::ViewManager::showSaveInProgressMessageBox (CSVDoc::View *view)
|
||||
{
|
||||
QMessageBox messageBox;
|
||||
CSMDoc::Document *document = view->getDocument();
|
||||
|
||||
messageBox.setText ("The document is currently being saved.");
|
||||
messageBox.setInformativeText("Do you want to close now and abort saving, or wait until saving has completed?");
|
||||
|
||||
QPushButton* waitButton = messageBox.addButton (tr("Wait"), QMessageBox::YesRole);
|
||||
QPushButton* closeButton = messageBox.addButton (tr("Close Now"), QMessageBox::RejectRole);
|
||||
QPushButton* cancelButton = messageBox.addButton (tr("Cancel"), QMessageBox::NoRole);
|
||||
|
||||
messageBox.setDefaultButton (waitButton);
|
||||
|
||||
bool retVal = true;
|
||||
|
||||
//Connections shut down message box if operation ends before user makes a decision.
|
||||
connect (document, SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *)));
|
||||
connect (this, SIGNAL (closeMessageBox()), &messageBox, SLOT (close()));
|
||||
|
||||
//set / clear the user warned flag to indicate whether or not the message box is currently active.
|
||||
mUserWarned = true;
|
||||
messageBox.exec();
|
||||
mUserWarned = false;
|
||||
|
||||
//if closed by the warning handler, defaults to the RejectRole button (closeButton)
|
||||
if (messageBox.clickedButton() == waitButton)
|
||||
{
|
||||
//save the View iterator for shutdown after the save operation ends
|
||||
mExitOnSaveStateChange = true;
|
||||
retVal = false;
|
||||
}
|
||||
|
||||
else if (messageBox.clickedButton() == closeButton)
|
||||
{
|
||||
//disconnect to avoid segmentation fault
|
||||
disconnect (document, SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *)));
|
||||
|
||||
view->abortOperation(CSMDoc::State_Saving);
|
||||
mExitOnSaveStateChange = true;
|
||||
}
|
||||
|
||||
else if (messageBox.clickedButton() == cancelButton)
|
||||
{
|
||||
//abort shutdown, allow save to complete
|
||||
//disconnection to prevent unintended view closures
|
||||
mExitOnSaveStateChange = false;
|
||||
disconnect (document, SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *)));
|
||||
retVal = false;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void CSVDoc::ViewManager::documentStateChanged (int state, CSMDoc::Document *document)
|
||||
|
@ -135,3 +321,25 @@ void CSVDoc::ViewManager::progress (int current, int max, int type, int threads,
|
|||
if ((*iter)->getDocument()==document)
|
||||
(*iter)->updateProgress (current, max, type, threads);
|
||||
}
|
||||
|
||||
void CSVDoc::ViewManager::onExitWarningHandler (int state, CSMDoc::Document *document)
|
||||
{
|
||||
if ( !(state & CSMDoc::State_Saving) )
|
||||
{
|
||||
//if the user is being warned (message box is active), shut down the message box,
|
||||
//as there is no save operation currently running
|
||||
if ( mUserWarned )
|
||||
emit closeMessageBox();
|
||||
|
||||
//otherwise, the user has closed the message box before the save operation ended.
|
||||
//exit the application
|
||||
else if (mExitOnSaveStateChange)
|
||||
QApplication::instance()->exit();
|
||||
}
|
||||
}
|
||||
|
||||
void CSVDoc::ViewManager::exitApplication (CSVDoc::View *view)
|
||||
{
|
||||
if (notifySaveOnClose (view))
|
||||
QApplication::instance()->exit();
|
||||
}
|
||||
|
|
|
@ -27,12 +27,17 @@ namespace CSVDoc
|
|||
CSMDoc::DocumentManager& mDocumentManager;
|
||||
std::vector<View *> mViews;
|
||||
CSVWorld::CommandDelegateFactoryCollection *mDelegateFactories;
|
||||
bool mExitOnSaveStateChange;
|
||||
bool mUserWarned;
|
||||
|
||||
// not implemented
|
||||
ViewManager (const ViewManager&);
|
||||
ViewManager& operator= (const ViewManager&);
|
||||
|
||||
void updateIndices();
|
||||
bool notifySaveOnClose (View *view = 0);
|
||||
bool showModifiedDocumentMessageBox (View *view);
|
||||
bool showSaveInProgressMessageBox (View *view);
|
||||
|
||||
public:
|
||||
|
||||
|
@ -54,13 +59,21 @@ namespace CSVDoc
|
|||
|
||||
void loadDocumentRequest();
|
||||
|
||||
void closeMessageBox();
|
||||
|
||||
public slots:
|
||||
|
||||
void exitApplication (CSVDoc::View *view);
|
||||
|
||||
private slots:
|
||||
|
||||
void documentStateChanged (int state, CSMDoc::Document *document);
|
||||
|
||||
void progress (int current, int max, int type, int threads, CSMDoc::Document *document);
|
||||
|
||||
void onExitWarningHandler(int state, CSMDoc::Document* document);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
#include "abstractblock.hpp"
|
||||
|
||||
CsSettings::AbstractBlock::AbstractBlock(QWidget* parent)
|
||||
CSVSettings::AbstractBlock::AbstractBlock(QWidget* parent)
|
||||
: QObject (parent), mBox ( new GroupBox (parent) ), mWidgetParent (parent)
|
||||
{}
|
||||
|
||||
CsSettings::AbstractBlock::AbstractBlock(bool isVisible, QWidget* parent)
|
||||
CSVSettings::AbstractBlock::AbstractBlock(bool isVisible, QWidget* parent)
|
||||
: QObject (parent), mBox ( new GroupBox (isVisible, parent)), mWidgetParent (parent)
|
||||
{}
|
||||
|
||||
QLayout *CsSettings::AbstractBlock::createLayout (OcsWidgetOrientation direction, bool isZeroMargin, QWidget* parent)
|
||||
QLayout *CSVSettings::AbstractBlock::createLayout (Orientation direction,
|
||||
bool isZeroMargin, QWidget* parent)
|
||||
{
|
||||
QLayout *layout = 0;
|
||||
|
||||
if (direction == OCS_VERTICAL)
|
||||
if (direction == Orient_Vertical)
|
||||
layout = new QVBoxLayout (parent);
|
||||
else
|
||||
layout = new QHBoxLayout (parent);
|
||||
|
@ -23,40 +24,40 @@ QLayout *CsSettings::AbstractBlock::createLayout (OcsWidgetOrientation direction
|
|||
return layout;
|
||||
}
|
||||
|
||||
QGroupBox *CsSettings::AbstractBlock::getGroupBox()
|
||||
QGroupBox *CSVSettings::AbstractBlock::getGroupBox()
|
||||
{
|
||||
return mBox;
|
||||
}
|
||||
|
||||
CsSettings::AbstractWidget *CsSettings::AbstractBlock::buildWidget (const QString& widgetName, WidgetDef &def,
|
||||
QLayout *layout, bool isConnected) const
|
||||
CSVSettings::AbstractWidget *CSVSettings::AbstractBlock::buildWidget (const QString& widgetName, WidgetDef &def,
|
||||
QLayout *layout, bool isConnected) const
|
||||
{
|
||||
AbstractWidget *widg = 0;
|
||||
|
||||
switch (def.type)
|
||||
{
|
||||
|
||||
case OCS_RADIO_WIDGET:
|
||||
case Widget_RadioButton:
|
||||
widg = createSettingWidget<QRadioButton> (def, layout);
|
||||
break;
|
||||
|
||||
case OCS_SPIN_WIDGET:
|
||||
case Widget_SpinBox:
|
||||
widg = createSettingWidget<QSpinBox> (def, layout);
|
||||
break;
|
||||
|
||||
case OCS_CHECK_WIDGET:
|
||||
case Widget_CheckBox:
|
||||
widg = createSettingWidget<QCheckBox> (def, layout);
|
||||
break;
|
||||
|
||||
case OCS_TEXT_WIDGET:
|
||||
case Widget_LineEdit:
|
||||
widg = createSettingWidget<QLineEdit> (def, layout);
|
||||
break;
|
||||
|
||||
case OCS_LIST_WIDGET:
|
||||
case Widget_ListBox:
|
||||
widg = createSettingWidget<QListWidget> (def, layout);
|
||||
break;
|
||||
|
||||
case OCS_COMBO_WIDGET:
|
||||
case Widget_ComboBox:
|
||||
widg = createSettingWidget<QComboBox> (def, layout);
|
||||
break;
|
||||
|
||||
|
@ -76,32 +77,32 @@ CsSettings::AbstractWidget *CsSettings::AbstractBlock::buildWidget (const QStrin
|
|||
return widg;
|
||||
}
|
||||
|
||||
void CsSettings::AbstractBlock::setVisible (bool isVisible)
|
||||
void CSVSettings::AbstractBlock::setVisible (bool isVisible)
|
||||
{
|
||||
mBox->setBorderVisibility (isVisible);
|
||||
}
|
||||
|
||||
bool CsSettings::AbstractBlock::isVisible () const
|
||||
bool CSVSettings::AbstractBlock::isVisible () const
|
||||
{
|
||||
return mBox->borderVisibile();
|
||||
}
|
||||
|
||||
QWidget *CsSettings::AbstractBlock::getParent() const
|
||||
QWidget *CSVSettings::AbstractBlock::getParent() const
|
||||
{
|
||||
return mWidgetParent;
|
||||
}
|
||||
|
||||
void CsSettings::AbstractBlock::slotUpdate (const QString &value)
|
||||
void CSVSettings::AbstractBlock::slotUpdate (const QString &value)
|
||||
{
|
||||
slotUpdateSetting (objectName(), value);
|
||||
}
|
||||
|
||||
void CsSettings::AbstractBlock::slotSetEnabled(bool value)
|
||||
void CSVSettings::AbstractBlock::slotSetEnabled(bool value)
|
||||
{
|
||||
mBox->setEnabled(value);
|
||||
}
|
||||
|
||||
void CsSettings::AbstractBlock::slotUpdateSetting (const QString &settingName, const QString &settingValue)
|
||||
void CSVSettings::AbstractBlock::slotUpdateSetting (const QString &settingName, const QString &settingValue)
|
||||
{
|
||||
bool doEmit = true;
|
||||
updateBySignal (settingName, settingValue, doEmit);
|
|
@ -5,10 +5,10 @@
|
|||
#include <QList>
|
||||
|
||||
#include "settingwidget.hpp"
|
||||
#include "settingsitem.hpp"
|
||||
#include "../../model/settings/settingsitem.hpp"
|
||||
#include "groupbox.hpp"
|
||||
|
||||
namespace CsSettings
|
||||
namespace CSVSettings
|
||||
{
|
||||
|
||||
class AbstractBlock : public QObject
|
||||
|
@ -17,7 +17,7 @@ namespace CsSettings
|
|||
|
||||
protected:
|
||||
|
||||
typedef QMap<QString, SettingsItem*> SettingsItemMap;
|
||||
typedef QMap<QString, CSMSettings::SettingsItem*> SettingsItemMap;
|
||||
GroupBox *mBox;
|
||||
QWidget *mWidgetParent;
|
||||
|
||||
|
@ -30,14 +30,14 @@ namespace CsSettings
|
|||
void setVisible (bool isVisible);
|
||||
bool isVisible() const;
|
||||
|
||||
virtual SettingList *getSettings() = 0;
|
||||
virtual bool updateSettings (const SettingMap &settings) = 0;
|
||||
virtual CSMSettings::SettingList *getSettings() = 0;
|
||||
virtual bool updateSettings (const CSMSettings::SettingMap &settings) = 0;
|
||||
virtual bool updateBySignal (const QString &name, const QString &value, bool &doEmit)
|
||||
{ return false; }
|
||||
|
||||
protected:
|
||||
|
||||
QLayout *createLayout (OcsWidgetOrientation direction, bool isZeroMargin, QWidget* parent = 0);
|
||||
QLayout *createLayout (Orientation direction, bool isZeroMargin, QWidget* parent = 0);
|
||||
AbstractWidget *buildWidget (const QString &widgetName, WidgetDef &wDef,
|
||||
QLayout *layout = 0, bool isConnected = true) const;
|
||||
|
|
@ -10,28 +10,28 @@
|
|||
#include <QLineEdit>
|
||||
#include <QMargins>
|
||||
|
||||
CsSettings::AbstractPage::AbstractPage(QWidget *parent):
|
||||
CSVSettings::AbstractPage::AbstractPage(QWidget *parent):
|
||||
QWidget(parent)
|
||||
{
|
||||
}
|
||||
|
||||
CsSettings::AbstractPage::AbstractPage(const QString &pageName, QWidget *parent):
|
||||
CSVSettings::AbstractPage::AbstractPage(const QString &pageName, QWidget *parent):
|
||||
QWidget(parent)
|
||||
{
|
||||
QWidget::setObjectName (pageName);
|
||||
}
|
||||
|
||||
CsSettings::AbstractPage::~AbstractPage()
|
||||
CSVSettings::AbstractPage::~AbstractPage()
|
||||
{
|
||||
}
|
||||
|
||||
CsSettings::SettingList *CsSettings::AbstractPage::getSettings()
|
||||
CSMSettings::SettingList *CSVSettings::AbstractPage::getSettings()
|
||||
{
|
||||
SettingList *settings = new SettingList();
|
||||
CSMSettings::SettingList *settings = new CSMSettings::SettingList();
|
||||
|
||||
foreach (AbstractBlock *block, mAbstractBlocks)
|
||||
{
|
||||
SettingList *groupSettings = block->getSettings();
|
||||
CSMSettings::SettingList *groupSettings = block->getSettings();
|
||||
settings->append (*groupSettings);
|
||||
}
|
||||
|
|
@ -10,15 +10,13 @@
|
|||
class SettingMap;
|
||||
class SettingList;
|
||||
|
||||
namespace CsSettings {
|
||||
namespace CSVSettings {
|
||||
|
||||
typedef QList<AbstractBlock *> AbstractBlockList;
|
||||
|
||||
class AbstractPage: public QWidget
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
|
||||
AbstractBlockList mAbstractBlocks;
|
||||
|
@ -32,9 +30,9 @@ namespace CsSettings {
|
|||
|
||||
virtual void setupUi()=0;
|
||||
|
||||
virtual void initializeWidgets (const SettingMap &settings) = 0;
|
||||
virtual void initializeWidgets (const CSMSettings::SettingMap &settings) = 0;
|
||||
|
||||
SettingList *getSettings();
|
||||
CSMSettings::SettingList *getSettings();
|
||||
|
||||
void setObjectName();
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
#include <QLayout>
|
||||
#include <QLabel>
|
||||
|
||||
void CsSettings::AbstractWidget::build(QWidget *widget, WidgetDef &def, bool noLabel)
|
||||
void CSVSettings::AbstractWidget::build(QWidget *widget, WidgetDef &def, bool noLabel)
|
||||
{
|
||||
if (!mLayout)
|
||||
createLayout(def.orientation, true);
|
||||
|
@ -12,7 +12,7 @@ void CsSettings::AbstractWidget::build(QWidget *widget, WidgetDef &def, bool noL
|
|||
|
||||
}
|
||||
|
||||
void CsSettings::AbstractWidget::buildLabelAndWidget (QWidget *widget, WidgetDef &def, bool noLabel)
|
||||
void CSVSettings::AbstractWidget::buildLabelAndWidget (QWidget *widget, WidgetDef &def, bool noLabel)
|
||||
{
|
||||
if (def.widgetWidth > -1)
|
||||
widget->setFixedWidth (def.widgetWidth);
|
||||
|
@ -31,10 +31,10 @@ void CsSettings::AbstractWidget::buildLabelAndWidget (QWidget *widget, WidgetDef
|
|||
mLayout->setAlignment (widget, getAlignment (def.widgetAlignment));
|
||||
}
|
||||
|
||||
void CsSettings::AbstractWidget::createLayout
|
||||
(OcsWidgetOrientation direction, bool isZeroMargin)
|
||||
void CSVSettings::AbstractWidget::createLayout
|
||||
(Orientation direction, bool isZeroMargin)
|
||||
{
|
||||
if (direction == OCS_VERTICAL)
|
||||
if (direction == Orient_Vertical)
|
||||
mLayout = new QVBoxLayout ();
|
||||
else
|
||||
mLayout = new QHBoxLayout ();
|
||||
|
@ -43,36 +43,36 @@ void CsSettings::AbstractWidget::createLayout
|
|||
mLayout->setContentsMargins(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
QFlags<Qt::AlignmentFlag> CsSettings::AbstractWidget::getAlignment (CsSettings::OcsAlignment flag)
|
||||
QFlags<Qt::AlignmentFlag> CSVSettings::AbstractWidget::getAlignment (CSVSettings::Alignment flag)
|
||||
{
|
||||
return QFlags<Qt::AlignmentFlag>(static_cast<int>(flag));
|
||||
}
|
||||
|
||||
QLayout *CsSettings::AbstractWidget::getLayout()
|
||||
QLayout *CSVSettings::AbstractWidget::getLayout()
|
||||
{
|
||||
return mLayout;
|
||||
}
|
||||
|
||||
void CsSettings::AbstractWidget::slotUpdateWidget (const QString &value)
|
||||
void CSVSettings::AbstractWidget::slotUpdateWidget (const QString &value)
|
||||
{
|
||||
updateWidget (value);
|
||||
}
|
||||
|
||||
void CsSettings::AbstractWidget::slotUpdateItem(const QString &value)
|
||||
void CSVSettings::AbstractWidget::slotUpdateItem(const QString &value)
|
||||
{
|
||||
emit signalUpdateItem (value);
|
||||
}
|
||||
|
||||
void CsSettings::AbstractWidget::slotUpdateItem(bool value)
|
||||
void CSVSettings::AbstractWidget::slotUpdateItem(bool value)
|
||||
{
|
||||
if (value)
|
||||
emit signalUpdateItem (widget()->objectName());
|
||||
}
|
||||
|
||||
void CsSettings::AbstractWidget::slotUpdateItem(int value)
|
||||
void CSVSettings::AbstractWidget::slotUpdateItem(int value)
|
||||
{
|
||||
emit signalUpdateItem (QString::number(value));
|
||||
}
|
||||
|
||||
void CsSettings::AbstractWidget::slotUpdateItem (QListWidgetItem* current, QListWidgetItem* previous)
|
||||
void CSVSettings::AbstractWidget::slotUpdateItem (QListWidgetItem* current, QListWidgetItem* previous)
|
||||
{}
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
class QLayout;
|
||||
|
||||
namespace CsSettings
|
||||
namespace CSVSettings
|
||||
{
|
||||
class AbstractWidget : public QObject
|
||||
{
|
||||
|
@ -35,12 +35,12 @@ namespace CsSettings
|
|||
virtual void updateWidget (const QString &value) = 0;
|
||||
|
||||
//converts user-defined enum to Qt equivalents
|
||||
QFlags<Qt::AlignmentFlag> getAlignment (CsSettings::OcsAlignment flag);
|
||||
QFlags<Qt::AlignmentFlag> getAlignment (Alignment flag);
|
||||
|
||||
private:
|
||||
|
||||
//widget initialization utilities
|
||||
void createLayout (CsSettings::OcsWidgetOrientation direction, bool isZeroMargin);
|
||||
void createLayout (Orientation direction, bool isZeroMargin);
|
||||
void buildLabelAndWidget (QWidget *widget, WidgetDef &def, bool noLabel);
|
||||
|
||||
|
|
@ -13,23 +13,23 @@
|
|||
#include <QPlastiqueStyle>
|
||||
#endif
|
||||
|
||||
#include "usersettings.hpp"
|
||||
#include "../../model/settings/usersettings.hpp"
|
||||
#include "groupblock.hpp"
|
||||
#include "toggleblock.hpp"
|
||||
|
||||
CsSettings::BlankPage::BlankPage(QWidget *parent):
|
||||
CSVSettings::BlankPage::BlankPage(QWidget *parent):
|
||||
AbstractPage("Blank", parent)
|
||||
{
|
||||
initPage();
|
||||
}
|
||||
|
||||
CsSettings::BlankPage::BlankPage(const QString &title, QWidget *parent):
|
||||
CSVSettings::BlankPage::BlankPage(const QString &title, QWidget *parent):
|
||||
AbstractPage(title, parent)
|
||||
{
|
||||
initPage();
|
||||
}
|
||||
|
||||
void CsSettings::BlankPage::initPage()
|
||||
void CSVSettings::BlankPage::initPage()
|
||||
{
|
||||
// Hacks to get the stylesheet look properly
|
||||
#ifdef Q_OS_MAC
|
||||
|
@ -40,7 +40,7 @@ void CsSettings::BlankPage::initPage()
|
|||
setupUi();
|
||||
}
|
||||
|
||||
void CsSettings::BlankPage::setupUi()
|
||||
void CSVSettings::BlankPage::setupUi()
|
||||
{
|
||||
QGroupBox *pageBox = new QGroupBox(this);
|
||||
QLayout* pageLayout = new QVBoxLayout();
|
||||
|
@ -49,7 +49,7 @@ void CsSettings::BlankPage::setupUi()
|
|||
pageLayout->addWidget(pageBox);
|
||||
}
|
||||
|
||||
void CsSettings::BlankPage::initializeWidgets (const SettingMap &settings)
|
||||
void CSVSettings::BlankPage::initializeWidgets (const CSMSettings::SettingMap &settings)
|
||||
{
|
||||
//iterate each item in each blocks in this section
|
||||
//validate the corresponding setting against the defined valuelist if any.
|
|
@ -5,14 +5,13 @@
|
|||
|
||||
class QGroupBox;
|
||||
|
||||
namespace CsSettings {
|
||||
namespace CSVSettings {
|
||||
|
||||
class UserSettings;
|
||||
class AbstractBlock;
|
||||
|
||||
class BlankPage : public AbstractPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
|
@ -20,7 +19,7 @@ namespace CsSettings {
|
|||
BlankPage (const QString &title, QWidget *parent);
|
||||
|
||||
void setupUi();
|
||||
void initializeWidgets (const SettingMap &settings);
|
||||
void initializeWidgets (const CSMSettings::SettingMap &settings);
|
||||
|
||||
private:
|
||||
void initPage();
|
|
@ -3,11 +3,11 @@
|
|||
#include "itemblock.hpp"
|
||||
#include "proxyblock.hpp"
|
||||
|
||||
CsSettings::CustomBlock::CustomBlock (QWidget *parent) : AbstractBlock (parent)
|
||||
CSVSettings::CustomBlock::CustomBlock (QWidget *parent) : AbstractBlock (parent)
|
||||
{
|
||||
}
|
||||
|
||||
int CsSettings::CustomBlock::build(GroupBlockDefList &defList, GroupBlockDefList::iterator *it)
|
||||
int CSVSettings::CustomBlock::build(GroupBlockDefList &defList, GroupBlockDefList::iterator *it)
|
||||
{
|
||||
int retVal = 0;
|
||||
|
||||
|
@ -37,7 +37,7 @@ int CsSettings::CustomBlock::build(GroupBlockDefList &defList, GroupBlockDefList
|
|||
return retVal;
|
||||
}
|
||||
|
||||
CsSettings::GroupBox *CsSettings::CustomBlock::buildGroupBox (CsSettings::OcsWidgetOrientation orientation)
|
||||
CSVSettings::GroupBox *CSVSettings::CustomBlock::buildGroupBox (Orientation orientation)
|
||||
{
|
||||
GroupBox *box = new GroupBox (false, mBox);
|
||||
QLayout *layout = createLayout (orientation, true, box);
|
||||
|
@ -45,7 +45,7 @@ CsSettings::GroupBox *CsSettings::CustomBlock::buildGroupBox (CsSettings::OcsWid
|
|||
return box;
|
||||
}
|
||||
|
||||
int CsSettings::CustomBlock::buildGroupBlock(GroupBlockDef &def)
|
||||
int CSVSettings::CustomBlock::buildGroupBlock(GroupBlockDef &def)
|
||||
{
|
||||
GroupBlock *block = new GroupBlock (getParent());
|
||||
|
||||
|
@ -57,7 +57,7 @@ int CsSettings::CustomBlock::buildGroupBlock(GroupBlockDef &def)
|
|||
return block->build(def);
|
||||
}
|
||||
|
||||
int CsSettings::CustomBlock::buildProxyBlock(GroupBlockDef& def, ProxyBlock *block)
|
||||
int CSVSettings::CustomBlock::buildProxyBlock(GroupBlockDef& def, ProxyBlock *block)
|
||||
{
|
||||
if (def.properties.size() != 1)
|
||||
return -1;
|
||||
|
@ -91,13 +91,13 @@ int CsSettings::CustomBlock::buildProxyBlock(GroupBlockDef& def, ProxyBlock *blo
|
|||
return 0;
|
||||
}
|
||||
|
||||
CsSettings::SettingList *CsSettings::CustomBlock::getSettings()
|
||||
CSMSettings::SettingList *CSVSettings::CustomBlock::getSettings()
|
||||
{
|
||||
SettingList *settings = new SettingList();
|
||||
CSMSettings::SettingList *settings = new CSMSettings::SettingList();
|
||||
|
||||
foreach (GroupBlock *block, mGroupList)
|
||||
{
|
||||
SettingList *groupSettings = block->getSettings();
|
||||
CSMSettings::SettingList *groupSettings = block->getSettings();
|
||||
|
||||
if (groupSettings)
|
||||
settings->append(*groupSettings);
|
||||
|
@ -106,7 +106,7 @@ CsSettings::SettingList *CsSettings::CustomBlock::getSettings()
|
|||
return settings;
|
||||
}
|
||||
|
||||
bool CsSettings::CustomBlock::updateSettings (const SettingMap &settings)
|
||||
bool CSVSettings::CustomBlock::updateSettings (const CSMSettings::SettingMap &settings)
|
||||
{
|
||||
bool success = true;
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "abstractblock.hpp"
|
||||
|
||||
namespace CsSettings
|
||||
namespace CSVSettings
|
||||
{
|
||||
|
||||
class ProxyBlock;
|
||||
|
@ -19,13 +19,13 @@ namespace CsSettings
|
|||
|
||||
explicit CustomBlock (QWidget *parent = 0);
|
||||
|
||||
bool updateSettings (const SettingMap &settings);
|
||||
SettingList *getSettings();
|
||||
bool updateSettings (const CSMSettings::SettingMap &settings);
|
||||
CSMSettings::SettingList *getSettings();
|
||||
int build (GroupBlockDefList &defList, GroupBlockDefList::Iterator *it = 0);
|
||||
|
||||
protected:
|
||||
|
||||
GroupBox *buildGroupBox (OcsWidgetOrientation orientation);
|
||||
GroupBox *buildGroupBox (Orientation orientation);
|
||||
|
||||
private:
|
||||
|
|
@ -13,11 +13,11 @@
|
|||
#include <QPlastiqueStyle>
|
||||
#endif
|
||||
|
||||
#include "usersettings.hpp"
|
||||
#include "../../model/settings/usersettings.hpp"
|
||||
#include "groupblock.hpp"
|
||||
#include "toggleblock.hpp"
|
||||
|
||||
CsSettings::EditorPage::EditorPage(QWidget *parent):
|
||||
CSVSettings::EditorPage::EditorPage(QWidget *parent):
|
||||
AbstractPage("Editor", parent)
|
||||
{
|
||||
// Hacks to get the stylesheet look properly
|
||||
|
@ -29,7 +29,7 @@ CsSettings::EditorPage::EditorPage(QWidget *parent):
|
|||
setupUi();
|
||||
}
|
||||
|
||||
void CsSettings::EditorPage::setupUi()
|
||||
void CSVSettings::EditorPage::setupUi()
|
||||
{
|
||||
GroupBlockDef undoStack (QString("Undo Stack Size"));
|
||||
GroupBlockDef topLevelWindowCount (QString("Maximum Top-Level Window Count"));
|
||||
|
@ -48,7 +48,7 @@ void CsSettings::EditorPage::setupUi()
|
|||
undoStackItem->minMax.left = "0";
|
||||
undoStackItem->minMax.right = "64";
|
||||
|
||||
WidgetDef stackWidget (OCS_SPIN_WIDGET);
|
||||
WidgetDef stackWidget (Widget_SpinBox);
|
||||
stackWidget.minMax = &(undoStackItem->minMax);
|
||||
stackWidget.widgetWidth = 50;
|
||||
|
||||
|
@ -63,7 +63,7 @@ void CsSettings::EditorPage::setupUi()
|
|||
topLevelItem->minMax.left = "1";
|
||||
topLevelItem->minMax.right = "256";
|
||||
|
||||
WidgetDef topLvlWinWidget (OCS_SPIN_WIDGET);
|
||||
WidgetDef topLvlWinWidget (Widget_SpinBox);
|
||||
topLvlWinWidget.minMax = &(topLevelItem->minMax);
|
||||
topLvlWinWidget.widgetWidth = 50;
|
||||
|
||||
|
@ -76,9 +76,9 @@ void CsSettings::EditorPage::setupUi()
|
|||
SettingsItemDef *reuseSubItem = new SettingsItemDef (reuseSubwindow.title, "Reuse Subwindows");
|
||||
*(reuseSubItem->valueList) << "None" << "Top-Level" << "Document-Level";
|
||||
|
||||
WidgetDef reuseSubWidget (OCS_RADIO_WIDGET);
|
||||
WidgetDef reuseSubWidget (Widget_RadioButton);
|
||||
reuseSubWidget.valueList = (reuseSubItem->valueList);
|
||||
reuseSubWidget.widgetAlignment = OCS_LEFT;
|
||||
reuseSubWidget.widgetAlignment = Align_Left;
|
||||
|
||||
reuseSubwindow.properties << reuseSubItem;
|
||||
reuseSubItem->widget = reuseSubWidget;
|
||||
|
@ -89,23 +89,23 @@ void CsSettings::EditorPage::setupUi()
|
|||
|
||||
//custom width
|
||||
SettingsItemDef *widthItem = new SettingsItemDef ("Window Width", "640");
|
||||
widthItem->widget = WidgetDef (OCS_TEXT_WIDGET);
|
||||
widthItem->widget = WidgetDef (Widget_LineEdit);
|
||||
widthItem->widget.widgetWidth = 45;
|
||||
|
||||
//custom height
|
||||
SettingsItemDef *heightItem = new SettingsItemDef ("Window Height", "480");
|
||||
heightItem->widget = WidgetDef (OCS_TEXT_WIDGET);
|
||||
heightItem->widget = WidgetDef (Widget_LineEdit);
|
||||
heightItem->widget.widgetWidth = 45;
|
||||
heightItem->widget.caption = "x";
|
||||
|
||||
customWindowSize.properties << widthItem << heightItem;
|
||||
customWindowSize.widgetOrientation = OCS_HORIZONTAL;
|
||||
customWindowSize.widgetOrientation = Orient_Horizontal;
|
||||
customWindowSize.isVisible = false;
|
||||
|
||||
|
||||
//pre-defined
|
||||
SettingsItemDef *widthByHeightItem = new SettingsItemDef ("Window Size", "640x480");
|
||||
WidgetDef widthByHeightWidget = WidgetDef (OCS_COMBO_WIDGET);
|
||||
WidgetDef widthByHeightWidget = WidgetDef (Widget_ComboBox);
|
||||
widthByHeightWidget.widgetWidth = 90;
|
||||
*(widthByHeightItem->valueList) << "640x480" << "800x600" << "1024x768";
|
||||
|
||||
|
@ -125,12 +125,12 @@ void CsSettings::EditorPage::setupUi()
|
|||
|
||||
// window size toggle
|
||||
windowSizeToggle.captions << "Pre-Defined" << "Custom";
|
||||
windowSizeToggle.widgetOrientation = OCS_VERTICAL;
|
||||
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 (OCS_RADIO_WIDGET);
|
||||
windowSizeToggle.widgets << new WidgetDef (Widget_RadioButton);
|
||||
|
||||
windowSizeToggle.widgets.at(0)->isDefault = false;
|
||||
|
||||
|
@ -153,7 +153,7 @@ void CsSettings::EditorPage::setupUi()
|
|||
}
|
||||
}
|
||||
|
||||
void CsSettings::EditorPage::initializeWidgets (const SettingMap &settings)
|
||||
void CSVSettings::EditorPage::initializeWidgets (const CSMSettings::SettingMap &settings)
|
||||
{
|
||||
//iterate each item in each blocks in this section
|
||||
//validate the corresponding setting against the defined valuelist if any.
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
class QGroupBox;
|
||||
|
||||
namespace CsSettings {
|
||||
namespace CSVSettings {
|
||||
|
||||
class UserSettings;
|
||||
class AbstractBlock;
|
||||
|
@ -19,7 +19,7 @@ namespace CsSettings {
|
|||
EditorPage(QWidget *parent = 0);
|
||||
|
||||
void setupUi();
|
||||
void initializeWidgets (const SettingMap &settings);
|
||||
void initializeWidgets (const CSMSettings::SettingMap &settings);
|
||||
|
||||
signals:
|
||||
void signalUpdateEditorSetting (const QString &settingName, const QString &settingValue);
|
|
@ -1,15 +1,15 @@
|
|||
#include "groupblock.hpp"
|
||||
#include "itemblock.hpp"
|
||||
|
||||
CsSettings::GroupBlock::GroupBlock (QWidget* parent)
|
||||
CSVSettings::GroupBlock::GroupBlock (QWidget* parent)
|
||||
: AbstractBlock (parent)
|
||||
{}
|
||||
|
||||
CsSettings::GroupBlock::GroupBlock (bool isVisible, QWidget *parent)
|
||||
CSVSettings::GroupBlock::GroupBlock (bool isVisible, QWidget *parent)
|
||||
: AbstractBlock (isVisible, parent)
|
||||
{}
|
||||
|
||||
int CsSettings::GroupBlock::build (GroupBlockDef &def)
|
||||
int CSVSettings::GroupBlock::build (GroupBlockDef &def)
|
||||
{
|
||||
|
||||
if (def.properties.size() == 0)
|
||||
|
@ -44,14 +44,14 @@ int CsSettings::GroupBlock::build (GroupBlockDef &def)
|
|||
return retVal;
|
||||
}
|
||||
|
||||
CsSettings::SettingList *CsSettings::GroupBlock::getSettings()
|
||||
CSMSettings::SettingList *CSVSettings::GroupBlock::getSettings()
|
||||
{
|
||||
SettingList *settings = 0;
|
||||
CSMSettings::SettingList *settings = 0;
|
||||
|
||||
foreach (ItemBlock *block, mItemBlockList)
|
||||
{
|
||||
if (!settings)
|
||||
settings = new SettingList();
|
||||
settings = new CSMSettings::SettingList();
|
||||
|
||||
settings->append(*(block->getSettings ()));
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ CsSettings::SettingList *CsSettings::GroupBlock::getSettings()
|
|||
return settings;
|
||||
}
|
||||
|
||||
CsSettings::ItemBlock *CsSettings::GroupBlock::getItemBlock (const QString &name, ItemBlockList *blockList)
|
||||
CSVSettings::ItemBlock *CSVSettings::GroupBlock::getItemBlock (const QString &name, ItemBlockList *blockList)
|
||||
{
|
||||
ItemBlock *retBlock = 0;
|
||||
|
||||
|
@ -78,7 +78,7 @@ CsSettings::ItemBlock *CsSettings::GroupBlock::getItemBlock (const QString &name
|
|||
return retBlock;
|
||||
}
|
||||
|
||||
CsSettings::ItemBlock *CsSettings::GroupBlock::getItemBlock (int index)
|
||||
CSVSettings::ItemBlock *CSVSettings::GroupBlock::getItemBlock (int index)
|
||||
{
|
||||
ItemBlock *retBlock = 0;
|
||||
|
||||
|
@ -88,14 +88,14 @@ CsSettings::ItemBlock *CsSettings::GroupBlock::getItemBlock (int index)
|
|||
return retBlock;
|
||||
}
|
||||
|
||||
bool CsSettings::GroupBlock::updateSettings (const SettingMap &settings)
|
||||
bool CSVSettings::GroupBlock::updateSettings (const CSMSettings::SettingMap &settings)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
//update all non-proxy settings
|
||||
foreach (ItemBlock *block, mItemBlockList)
|
||||
{
|
||||
SettingContainer *setting = settings[block->objectName()];
|
||||
CSMSettings::SettingContainer *setting = settings[block->objectName()];
|
||||
|
||||
if (setting)
|
||||
{
|
|
@ -4,7 +4,7 @@
|
|||
#include <QList>
|
||||
#include "abstractblock.hpp"
|
||||
|
||||
namespace CsSettings
|
||||
namespace CSVSettings
|
||||
{
|
||||
class ItemBlock;
|
||||
|
||||
|
@ -18,9 +18,9 @@ namespace CsSettings
|
|||
|
||||
int build (GroupBlockDef &def);
|
||||
|
||||
bool updateSettings (const SettingMap &settings);
|
||||
bool updateSettings (const CSMSettings::SettingMap &settings);
|
||||
|
||||
SettingList *getSettings();
|
||||
CSMSettings::SettingList *getSettings();
|
||||
ItemBlock *getItemBlock (const QString &name, ItemBlockList *blockList = 0);
|
||||
ItemBlock *getItemBlock (int index);
|
||||
|
|
@ -1,21 +1,21 @@
|
|||
#include "groupbox.hpp"
|
||||
|
||||
const QString CsSettings::GroupBox::INVISIBLE_BOX_STYLE =
|
||||
const QString CSVSettings::GroupBox::INVISIBLE_BOX_STYLE =
|
||||
QString::fromUtf8("QGroupBox { border: 0px; padding 0px; margin: 0px;}");
|
||||
|
||||
CsSettings::GroupBox::GroupBox(QWidget *parent) :
|
||||
CSVSettings::GroupBox::GroupBox(QWidget *parent) :
|
||||
QGroupBox (parent)
|
||||
{
|
||||
initBox();
|
||||
}
|
||||
|
||||
CsSettings::GroupBox::GroupBox (bool isVisible, QWidget *parent) :
|
||||
CSVSettings::GroupBox::GroupBox (bool isVisible, QWidget *parent) :
|
||||
QGroupBox (parent)
|
||||
{
|
||||
initBox(isVisible);
|
||||
}
|
||||
|
||||
void CsSettings::GroupBox::initBox(bool isVisible)
|
||||
void CSVSettings::GroupBox::initBox(bool isVisible)
|
||||
{
|
||||
setFlat (true);
|
||||
VISIBLE_BOX_STYLE = styleSheet();
|
||||
|
@ -24,12 +24,12 @@ void CsSettings::GroupBox::initBox(bool isVisible)
|
|||
setStyleSheet (INVISIBLE_BOX_STYLE);
|
||||
}
|
||||
|
||||
bool CsSettings::GroupBox::borderVisibile() const
|
||||
bool CSVSettings::GroupBox::borderVisibile() const
|
||||
{
|
||||
return (styleSheet() != INVISIBLE_BOX_STYLE);
|
||||
}
|
||||
|
||||
void CsSettings::GroupBox::setTitle (const QString &title)
|
||||
void CSVSettings::GroupBox::setTitle (const QString &title)
|
||||
{
|
||||
if (borderVisibile() )
|
||||
{
|
||||
|
@ -38,7 +38,7 @@ void CsSettings::GroupBox::setTitle (const QString &title)
|
|||
}
|
||||
}
|
||||
|
||||
void CsSettings::GroupBox::setBorderVisibility (bool value)
|
||||
void CSVSettings::GroupBox::setBorderVisibility (bool value)
|
||||
{
|
||||
if (value)
|
||||
setStyleSheet(VISIBLE_BOX_STYLE);
|
||||
|
@ -46,7 +46,7 @@ void CsSettings::GroupBox::setBorderVisibility (bool value)
|
|||
setStyleSheet(INVISIBLE_BOX_STYLE);
|
||||
}
|
||||
|
||||
void CsSettings::GroupBox::setMinimumWidth()
|
||||
void CSVSettings::GroupBox::setMinimumWidth()
|
||||
{
|
||||
//set minimum width to accommodate title, if needed
|
||||
//1.5 multiplier to account for bold title.
|
|
@ -3,12 +3,10 @@
|
|||
|
||||
#include <QGroupBox>
|
||||
|
||||
namespace CsSettings
|
||||
namespace CSVSettings
|
||||
{
|
||||
class GroupBox : public QGroupBox
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
static const QString INVISIBLE_BOX_STYLE;
|
||||
QString VISIBLE_BOX_STYLE; //not a const...
|
||||
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
#include <QFontMetrics>
|
||||
|
||||
CsSettings::ItemBlock::ItemBlock (QWidget* parent)
|
||||
CSVSettings::ItemBlock::ItemBlock (QWidget* parent)
|
||||
: mSetting (0), AbstractBlock (false, parent)
|
||||
{
|
||||
}
|
||||
|
||||
int CsSettings::ItemBlock::build(SettingsItemDef &iDef)
|
||||
int CSVSettings::ItemBlock::build(SettingsItemDef &iDef)
|
||||
{
|
||||
buildItemBlock (iDef);
|
||||
buildItemBlockWidgets (iDef);
|
||||
|
@ -15,7 +15,7 @@ int CsSettings::ItemBlock::build(SettingsItemDef &iDef)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void CsSettings::ItemBlock::buildItemBlockWidgets (SettingsItemDef &iDef)
|
||||
void CSVSettings::ItemBlock::buildItemBlockWidgets (SettingsItemDef &iDef)
|
||||
{
|
||||
WidgetDef wDef = iDef.widget;
|
||||
QLayout *blockLayout = 0;
|
||||
|
@ -24,8 +24,8 @@ void CsSettings::ItemBlock::buildItemBlockWidgets (SettingsItemDef &iDef)
|
|||
switch (wDef.type)
|
||||
{
|
||||
|
||||
case OCS_CHECK_WIDGET:
|
||||
case OCS_RADIO_WIDGET:
|
||||
case Widget_CheckBox:
|
||||
case Widget_RadioButton:
|
||||
|
||||
foreach (QString item, *(iDef.valueList))
|
||||
{
|
||||
|
@ -37,8 +37,8 @@ void CsSettings::ItemBlock::buildItemBlockWidgets (SettingsItemDef &iDef)
|
|||
|
||||
break;
|
||||
|
||||
case OCS_COMBO_WIDGET:
|
||||
case OCS_LIST_WIDGET:
|
||||
case Widget_ComboBox:
|
||||
case Widget_ListBox:
|
||||
|
||||
//assign the item's value list to the widget's value list.
|
||||
//pass through to default to finish widget construction.
|
||||
|
@ -56,13 +56,13 @@ void CsSettings::ItemBlock::buildItemBlockWidgets (SettingsItemDef &iDef)
|
|||
}
|
||||
}
|
||||
|
||||
void CsSettings::ItemBlock::buildItemBlock (SettingsItemDef &iDef)
|
||||
void CSVSettings::ItemBlock::buildItemBlock (SettingsItemDef &iDef)
|
||||
{
|
||||
QString defaultValue = iDef.defaultValue;
|
||||
|
||||
setObjectName(iDef.name);
|
||||
|
||||
mSetting = new SettingsItem (objectName(),
|
||||
mSetting = new CSMSettings::SettingsItem (objectName(),
|
||||
iDef.hasMultipleValues, iDef.defaultValue,
|
||||
parent());
|
||||
|
||||
|
@ -74,7 +74,7 @@ void CsSettings::ItemBlock::buildItemBlock (SettingsItemDef &iDef)
|
|||
}
|
||||
|
||||
|
||||
bool CsSettings::ItemBlock::update (const QString &value)
|
||||
bool CSVSettings::ItemBlock::update (const QString &value)
|
||||
{
|
||||
bool success = updateItem (value);
|
||||
|
||||
|
@ -85,13 +85,13 @@ bool CsSettings::ItemBlock::update (const QString &value)
|
|||
}
|
||||
|
||||
|
||||
bool CsSettings::ItemBlock::updateItem (const QString &value)
|
||||
bool CSVSettings::ItemBlock::updateItem (const QString &value)
|
||||
{
|
||||
return mSetting->updateItem(value);
|
||||
}
|
||||
|
||||
|
||||
bool CsSettings::ItemBlock::updateBySignal(const QString &name, const QString &value, bool &doEmit)
|
||||
bool CSVSettings::ItemBlock::updateBySignal(const QString &name, const QString &value, bool &doEmit)
|
||||
{
|
||||
bool success = (mSetting->getValue() != value);
|
||||
|
||||
|
@ -101,15 +101,15 @@ bool CsSettings::ItemBlock::updateBySignal(const QString &name, const QString &v
|
|||
return success;
|
||||
}
|
||||
|
||||
CsSettings::SettingList *CsSettings::ItemBlock::getSettings ()
|
||||
CSMSettings::SettingList *CSVSettings::ItemBlock::getSettings ()
|
||||
{
|
||||
SettingList *list = new SettingList();
|
||||
CSMSettings::SettingList *list = new CSMSettings::SettingList();
|
||||
list->push_back(mSetting);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
QString CsSettings::ItemBlock::getValue() const
|
||||
QString CSVSettings::ItemBlock::getValue() const
|
||||
{
|
||||
return mSetting->getValue();
|
||||
}
|
|
@ -3,21 +3,21 @@
|
|||
|
||||
#include "abstractblock.hpp"
|
||||
|
||||
namespace CsSettings
|
||||
namespace CSVSettings
|
||||
{
|
||||
|
||||
class ItemBlock : public AbstractBlock
|
||||
{
|
||||
SettingsItem *mSetting;
|
||||
CSMSettings::SettingsItem *mSetting;
|
||||
WidgetList mWidgetList;
|
||||
|
||||
public:
|
||||
|
||||
ItemBlock (QWidget* parent = 0);
|
||||
|
||||
bool updateSettings (const SettingMap &settings) { return false; }
|
||||
bool updateSettings (const CSMSettings::SettingMap &settings) { return false; }
|
||||
|
||||
SettingList *getSettings ();
|
||||
CSMSettings::SettingList *getSettings ();
|
||||
QString getValue () const;
|
||||
|
||||
int getSettingCount();
|
|
@ -1,11 +1,11 @@
|
|||
#include "proxyblock.hpp"
|
||||
#include "itemblock.hpp"
|
||||
|
||||
CsSettings::ProxyBlock::ProxyBlock (QWidget *parent)
|
||||
CSVSettings::ProxyBlock::ProxyBlock (QWidget *parent)
|
||||
: GroupBlock (parent)
|
||||
{
|
||||
}
|
||||
int CsSettings::ProxyBlock::build (GroupBlockDef &proxyDef)
|
||||
int CSVSettings::ProxyBlock::build (GroupBlockDef &proxyDef)
|
||||
{
|
||||
//get the list of pre-defined values for the proxy
|
||||
mValueList = proxyDef.properties.at(0)->valueList;
|
||||
|
@ -19,7 +19,7 @@ int CsSettings::ProxyBlock::build (GroupBlockDef &proxyDef)
|
|||
return success;
|
||||
}
|
||||
|
||||
void CsSettings::ProxyBlock::addSetting (ItemBlock *settingBlock, QStringList *proxyList)
|
||||
void CSVSettings::ProxyBlock::addSetting (ItemBlock *settingBlock, QStringList *proxyList)
|
||||
{
|
||||
//connect the item block of the proxied seting to the generic update slot
|
||||
connect (settingBlock, SIGNAL (signalUpdateSetting(const QString &, const QString &)),
|
||||
|
@ -29,23 +29,23 @@ void CsSettings::ProxyBlock::addSetting (ItemBlock *settingBlock, QStringList *p
|
|||
mProxyList << proxyList;
|
||||
}
|
||||
|
||||
bool CsSettings::ProxyBlock::updateSettings (const SettingMap &settings)
|
||||
bool CSVSettings::ProxyBlock::updateSettings (const CSMSettings::SettingMap &settings)
|
||||
{
|
||||
return updateByProxiedSettings(&settings);
|
||||
}
|
||||
|
||||
bool CsSettings::ProxyBlock::updateBySignal(const QString &name, const QString &value, bool &doEmit)
|
||||
bool CSVSettings::ProxyBlock::updateBySignal(const QString &name, const QString &value, bool &doEmit)
|
||||
{
|
||||
doEmit = false;
|
||||
return updateProxiedSettings();
|
||||
}
|
||||
|
||||
void CsSettings::ProxyBlock::slotUpdateProxySetting (const QString &name, const QString &value)
|
||||
void CSVSettings::ProxyBlock::slotUpdateProxySetting (const QString &name, const QString &value)
|
||||
{
|
||||
updateByProxiedSettings();
|
||||
}
|
||||
|
||||
bool CsSettings::ProxyBlock::updateProxiedSettings()
|
||||
bool CSVSettings::ProxyBlock::updateProxiedSettings()
|
||||
{
|
||||
foreach (ItemBlock *block, mProxiedItemBlockList)
|
||||
{
|
||||
|
@ -74,7 +74,7 @@ bool CsSettings::ProxyBlock::updateProxiedSettings()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CsSettings::ProxyBlock::updateByProxiedSettings(const SettingMap *settings)
|
||||
bool CSVSettings::ProxyBlock::updateByProxiedSettings(const CSMSettings::SettingMap *settings)
|
||||
{
|
||||
bool success = false;
|
||||
int commonIndex = -1;
|
||||
|
@ -143,7 +143,7 @@ bool CsSettings::ProxyBlock::updateByProxiedSettings(const SettingMap *settings)
|
|||
return success;
|
||||
}
|
||||
|
||||
CsSettings::ItemBlock *CsSettings::ProxyBlock::getProxiedItemBlock (const QString &name)
|
||||
CSVSettings::ItemBlock *CSVSettings::ProxyBlock::getProxiedItemBlock (const QString &name)
|
||||
{
|
||||
return getItemBlock (name, &mProxiedItemBlockList);
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "groupblock.hpp"
|
||||
|
||||
namespace CsSettings
|
||||
namespace CSVSettings
|
||||
{
|
||||
class ProxyBlock : public GroupBlock
|
||||
{
|
||||
|
@ -23,14 +23,14 @@ namespace CsSettings
|
|||
void addSetting (ItemBlock* settingBlock, QStringList *proxyList);
|
||||
int build (GroupBlockDef &def);
|
||||
|
||||
SettingList *getSettings() { return 0; }
|
||||
bool updateSettings (const SettingMap &settings);
|
||||
CSMSettings::SettingList *getSettings() { return 0; }
|
||||
bool updateSettings (const CSMSettings::SettingMap &settings);
|
||||
bool updateBySignal (const QString &name, const QString &value, bool &doEmit);
|
||||
|
||||
private:
|
||||
|
||||
ItemBlock *getProxiedItemBlock (const QString &name);
|
||||
bool updateByProxiedSettings(const SettingMap *settings = 0);
|
||||
bool updateByProxiedSettings(const CSMSettings::SettingMap *settings = 0);
|
||||
bool updateProxiedSettings();
|
||||
|
||||
private slots:
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include "abstractwidget.hpp"
|
||||
|
||||
namespace CsSettings
|
||||
namespace CSVSettings
|
||||
{
|
||||
//VALID FOR RADIOBUTTON / CHECKBOX (or other toggle widget with it's own label)
|
||||
template <typename T1>
|
||||
|
@ -25,7 +25,7 @@ namespace CsSettings
|
|||
|
||||
public:
|
||||
|
||||
explicit SettingWidget(WidgetDef &def, QLayout *layout, QWidget* parent = 0)
|
||||
explicit SettingWidget (WidgetDef &def, QLayout *layout, QWidget* parent = 0)
|
||||
: AbstractWidget (layout, parent), mWidget (new T1 (parent))
|
||||
{
|
||||
mWidget->setText(def.caption);
|
||||
|
@ -55,7 +55,7 @@ namespace CsSettings
|
|||
|
||||
public:
|
||||
|
||||
SettingWidget(WidgetDef &def, QLayout *layout, QWidget *parent = 0)
|
||||
SettingWidget (WidgetDef &def, QLayout *layout, QWidget *parent = 0)
|
||||
: AbstractWidget (layout, parent), mWidget (new QSpinBox (parent))
|
||||
{
|
||||
def.caption += tr(" (%1 to %2)").arg(def.minMax->left).arg(def.minMax->right);
|
||||
|
@ -91,7 +91,7 @@ namespace CsSettings
|
|||
};
|
||||
|
||||
template <>
|
||||
class SettingWidget <QComboBox>: public CsSettings::AbstractWidget
|
||||
class SettingWidget <QComboBox>: public CSVSettings::AbstractWidget
|
||||
{
|
||||
|
||||
QComboBox *mWidget;
|
||||
|
@ -143,7 +143,7 @@ namespace CsSettings
|
|||
};
|
||||
|
||||
template <>
|
||||
class SettingWidget <QLineEdit>: public CsSettings::AbstractWidget
|
||||
class SettingWidget <QLineEdit>: public CSVSettings::AbstractWidget
|
||||
{
|
||||
|
||||
QLineEdit *mWidget;
|
||||
|
@ -176,7 +176,7 @@ namespace CsSettings
|
|||
};
|
||||
|
||||
template <>
|
||||
class SettingWidget <QListWidget>: public CsSettings::AbstractWidget
|
||||
class SettingWidget <QListWidget>: public CSVSettings::AbstractWidget
|
||||
{
|
||||
|
||||
QListWidget *mWidget;
|
1
apps/opencs/view/settings/support.cpp
Normal file
1
apps/opencs/view/settings/support.cpp
Normal file
|
@ -0,0 +1 @@
|
|||
#include "support.hpp"
|
|
@ -1,17 +1,13 @@
|
|||
#ifndef SUPPORT_HPP
|
||||
#define SUPPORT_HPP
|
||||
#ifndef VIEW_SUPPORT_HPP
|
||||
#define VIEW_SUPPORT_HPP
|
||||
|
||||
#include <QObject>
|
||||
#include <QList>
|
||||
#include <QStringList>
|
||||
|
||||
class QLayout;
|
||||
class QWidget;
|
||||
class QListWidgetItem;
|
||||
#include "../../model/settings/support.hpp"
|
||||
|
||||
namespace CsSettings
|
||||
namespace CSVSettings
|
||||
{
|
||||
|
||||
class SettingContainer;
|
||||
struct WidgetDef;
|
||||
class ItemBlock;
|
||||
class GroupBlock;
|
||||
|
@ -20,86 +16,63 @@ namespace CsSettings
|
|||
typedef QList<GroupBlockDef *> GroupBlockDefList;
|
||||
typedef QList<GroupBlock *> GroupBlockList;
|
||||
typedef QList<ItemBlock *> ItemBlockList;
|
||||
typedef QList<SettingContainer *> SettingList;
|
||||
typedef QMap<QString, SettingContainer *> SettingMap;
|
||||
typedef QMap<QString, SettingMap *> SectionMap;
|
||||
typedef QList<QStringList *> ProxyList;
|
||||
typedef QList<WidgetDef *> WidgetList;
|
||||
typedef QMap<QString, ItemBlock *> ItemBlockMap;
|
||||
|
||||
enum OcsWidgetOrientation
|
||||
enum Orientation
|
||||
{
|
||||
OCS_HORIZONTAL,
|
||||
OCS_VERTICAL
|
||||
Orient_Horizontal,
|
||||
Orient_Vertical
|
||||
};
|
||||
|
||||
enum OcsWidgetType
|
||||
enum WidgetType
|
||||
{
|
||||
OCS_CHECK_WIDGET,
|
||||
OCS_COMBO_WIDGET,
|
||||
OCS_TEXT_WIDGET,
|
||||
OCS_LIST_WIDGET,
|
||||
OCS_RADIO_WIDGET,
|
||||
OCS_SPIN_WIDGET,
|
||||
OCS_UNDEFINED_WIDGET
|
||||
Widget_CheckBox,
|
||||
Widget_ComboBox,
|
||||
Widget_LineEdit,
|
||||
Widget_ListBox,
|
||||
Widget_RadioButton,
|
||||
Widget_SpinBox,
|
||||
Widget_Undefined
|
||||
};
|
||||
|
||||
enum OcsAlignment
|
||||
enum Alignment
|
||||
{
|
||||
OCS_LEFT = Qt::AlignLeft,
|
||||
OCS_CENTER = Qt::AlignHCenter,
|
||||
OCS_RIGHT = Qt::AlignRight
|
||||
};
|
||||
|
||||
struct QStringPair
|
||||
{
|
||||
QStringPair(): left (""), right ("")
|
||||
{}
|
||||
|
||||
QStringPair (const QString &leftValue, const QString &rightValue)
|
||||
: left (leftValue), right(rightValue)
|
||||
{}
|
||||
|
||||
QStringPair (const QStringPair &pair)
|
||||
: left (pair.left), right (pair.right)
|
||||
{}
|
||||
|
||||
QString left;
|
||||
QString right;
|
||||
|
||||
bool isEmpty()
|
||||
{ return (left.isEmpty() && right.isEmpty()); }
|
||||
Align_Left = Qt::AlignLeft,
|
||||
Align_Center = Qt::AlignHCenter,
|
||||
Align_Right = Qt::AlignRight
|
||||
};
|
||||
|
||||
//template for defining the widget of a property.
|
||||
struct WidgetDef
|
||||
{
|
||||
OcsWidgetType type; //type of widget providing input
|
||||
WidgetType type; //type of widget providing input
|
||||
int labelWidth; //width of caption label
|
||||
int widgetWidth; //width of input widget
|
||||
OcsWidgetOrientation orientation; //label / widget orientation (horizontal / vertical)
|
||||
Orientation orientation; //label / widget orientation (horizontal / vertical)
|
||||
QString inputMask; //input mask (line edit)
|
||||
QString caption; //label caption. Leave empty for multiple items. See BlockDef::captionList
|
||||
QString value; //widget value. Leave empty for multiple items. See BlockDef::valueList
|
||||
QStringPair *minMax; //Min/Max QString value pair. If empty, assigned to property item value pair.
|
||||
CSMSettings::QStringPair *minMax; //Min/Max QString value pair. If empty, assigned to property item value pair.
|
||||
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.
|
||||
OcsAlignment valueAlignment; //left / center / right-justify text in widget
|
||||
OcsAlignment widgetAlignment; //left / center / right-justify widget in group box
|
||||
Alignment valueAlignment; //left / center / right-justify text in widget
|
||||
Alignment widgetAlignment; //left / center / right-justify widget in group box
|
||||
|
||||
|
||||
WidgetDef() : labelWidth (-1), widgetWidth (-1),
|
||||
orientation (OCS_HORIZONTAL),
|
||||
isDefault (true), valueAlignment (OCS_CENTER),
|
||||
widgetAlignment (OCS_RIGHT),
|
||||
orientation (Orient_Horizontal),
|
||||
isDefault (true), valueAlignment (Align_Center),
|
||||
widgetAlignment (Align_Right),
|
||||
inputMask (""), value (""),
|
||||
caption (""), valueList (0)
|
||||
{}
|
||||
|
||||
WidgetDef (OcsWidgetType widgType)
|
||||
: type (widgType), orientation (OCS_HORIZONTAL),
|
||||
caption (""), value (""), valueAlignment (OCS_CENTER),
|
||||
widgetAlignment (OCS_RIGHT),
|
||||
WidgetDef (WidgetType widgType)
|
||||
: type (widgType), orientation (Orient_Horizontal),
|
||||
caption (""), value (""), valueAlignment (Align_Center),
|
||||
widgetAlignment (Align_Right),
|
||||
labelWidth (-1), widgetWidth (-1),
|
||||
valueList (0), isDefault (true)
|
||||
{}
|
||||
|
@ -116,15 +89,15 @@ namespace CsSettings
|
|||
//Used to populate option widget captions or list widget item lists (see WidgetDef::caption / value)
|
||||
QString defaultValue;
|
||||
bool hasMultipleValues;
|
||||
QStringPair minMax; //minimum / maximum value pair
|
||||
CSMSettings::QStringPair minMax; //minimum / maximum value pair
|
||||
WidgetDef widget; //definition of the input widget for this setting
|
||||
OcsWidgetOrientation orientation; //general orientation of the widget / label for this property
|
||||
Orientation orientation; //general orientation of the widget / label for this property
|
||||
ProxyList *proxyList; //list of property and corresponding default values for proxy widget
|
||||
|
||||
SettingsItemDef() : name (""), defaultValue (""), orientation (OCS_VERTICAL), hasMultipleValues (false)
|
||||
SettingsItemDef() : name (""), defaultValue (""), orientation (Orient_Vertical), hasMultipleValues (false)
|
||||
{}
|
||||
|
||||
SettingsItemDef (QString propName, QString propDefault, OcsWidgetOrientation propOrient = OCS_VERTICAL)
|
||||
SettingsItemDef (QString propName, QString propDefault, Orientation propOrient = Orient_Vertical)
|
||||
: name (propName), defaultValue (propDefault), orientation (propOrient),
|
||||
hasMultipleValues(false), valueList (new QStringList), proxyList ( new ProxyList)
|
||||
{}
|
||||
|
@ -139,16 +112,16 @@ namespace CsSettings
|
|||
QStringList captions; //list of captions for widgets at the block level (not associated with any particular property)
|
||||
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.
|
||||
OcsWidgetOrientation widgetOrientation; //general orientation of widgets in group block
|
||||
Orientation widgetOrientation; //general orientation of widgets in group block
|
||||
bool isVisible; //determines whether or not box border/title are visible
|
||||
bool isProxy; //indicates whether or not this block defines a proxy block
|
||||
QString defaultValue; //generic default value attribute
|
||||
|
||||
GroupBlockDef (): title(""), widgetOrientation (OCS_VERTICAL), isVisible (true), isProxy (false), defaultValue ("")
|
||||
GroupBlockDef (): title(""), widgetOrientation (Orient_Vertical), isVisible (true), isProxy (false), defaultValue ("")
|
||||
{}
|
||||
|
||||
GroupBlockDef (QString blockTitle)
|
||||
: title (blockTitle), widgetOrientation (OCS_VERTICAL), isProxy (false), isVisible (true), defaultValue ("")
|
||||
: title (blockTitle), widgetOrientation (Orient_Vertical), isProxy (false), isVisible (true), defaultValue ("")
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -157,14 +130,15 @@ namespace CsSettings
|
|||
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
|
||||
OcsWidgetOrientation blockOrientation;
|
||||
Orientation blockOrientation;
|
||||
|
||||
CustomBlockDef (): title (""), defaultValue (""), blockOrientation (OCS_HORIZONTAL)
|
||||
CustomBlockDef (): title (""), defaultValue (""), blockOrientation (Orient_Horizontal)
|
||||
{}
|
||||
|
||||
CustomBlockDef (const QString &blockTitle)
|
||||
: title (blockTitle), defaultValue (""), blockOrientation (OCS_HORIZONTAL)
|
||||
: title (blockTitle), defaultValue (""), blockOrientation (Orient_Horizontal)
|
||||
{}
|
||||
};
|
||||
}
|
||||
#endif // SUPPORT_HPP
|
||||
|
||||
#endif // VIEW_SUPPORT_HPP
|
|
@ -3,11 +3,11 @@
|
|||
#include "groupbox.hpp"
|
||||
#include "itemblock.hpp"
|
||||
|
||||
CsSettings::ToggleBlock::ToggleBlock(QWidget *parent) :
|
||||
CSVSettings::ToggleBlock::ToggleBlock(QWidget *parent) :
|
||||
CustomBlock(parent)
|
||||
{}
|
||||
|
||||
int CsSettings::ToggleBlock::build(CustomBlockDef &def)
|
||||
int CSVSettings::ToggleBlock::build(CustomBlockDef &def)
|
||||
{
|
||||
if (def.blockDefList.size()==0)
|
||||
return -1;
|
||||
|
@ -49,7 +49,7 @@ int CsSettings::ToggleBlock::build(CustomBlockDef &def)
|
|||
return 0;
|
||||
}
|
||||
|
||||
CsSettings::GroupBox *CsSettings::ToggleBlock::buildToggleWidgets (GroupBlockDef &def, QString &defaultToggle)
|
||||
CSVSettings::GroupBox *CSVSettings::ToggleBlock::buildToggleWidgets (GroupBlockDef &def, QString &defaultToggle)
|
||||
{
|
||||
GroupBox *box = new GroupBox (false, getParent());
|
||||
|
||||
|
@ -61,7 +61,7 @@ CsSettings::GroupBox *CsSettings::ToggleBlock::buildToggleWidgets (GroupBlockDef
|
|||
WidgetDef *wDef = def.widgets.at(i);
|
||||
|
||||
wDef->caption = caption;
|
||||
wDef->widgetAlignment = OCS_LEFT;
|
||||
wDef->widgetAlignment = Align_Left;
|
||||
|
||||
AbstractWidget *widg = buildWidget (caption, *wDef, layout, false);
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include "customblock.hpp"
|
||||
|
||||
namespace CsSettings
|
||||
namespace CSVSettings
|
||||
{
|
||||
class GroupBlock;
|
||||
class GroupBox;
|
|
@ -12,13 +12,13 @@
|
|||
|
||||
#include "blankpage.hpp"
|
||||
#include "editorpage.hpp"
|
||||
#include "support.hpp"
|
||||
#include "../../model/settings/support.hpp"
|
||||
|
||||
#include "settingwidget.hpp"
|
||||
#include <QDebug>
|
||||
|
||||
CsSettings::UserSettingsDialog::UserSettingsDialog(QMainWindow *parent) :
|
||||
QMainWindow (parent), mUserSettings (mCfgMgr), mStackedWidget (0)
|
||||
CSVSettings::UserSettingsDialog::UserSettingsDialog(QMainWindow *parent) :
|
||||
QMainWindow (parent), mStackedWidget (0)
|
||||
{
|
||||
setWindowTitle(QString::fromUtf8 ("User Settings"));
|
||||
buildPages();
|
||||
|
@ -31,22 +31,22 @@ CsSettings::UserSettingsDialog::UserSettingsDialog(QMainWindow *parent) :
|
|||
SLOT (slotChangePage (QListWidgetItem*, QListWidgetItem*)));
|
||||
}
|
||||
|
||||
CsSettings::UserSettingsDialog::~UserSettingsDialog()
|
||||
CSVSettings::UserSettingsDialog::~UserSettingsDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void CsSettings::UserSettingsDialog::closeEvent (QCloseEvent *event)
|
||||
void CSVSettings::UserSettingsDialog::closeEvent (QCloseEvent *event)
|
||||
{
|
||||
writeSettings();
|
||||
}
|
||||
|
||||
void CsSettings::UserSettingsDialog::setWidgetStates (SectionMap settingsMap)
|
||||
void CSVSettings::UserSettingsDialog::setWidgetStates (CSMSettings::SectionMap settingsMap)
|
||||
{
|
||||
//iterate the tabWidget's pages (sections)
|
||||
for (int i = 0; i < mStackedWidget->count(); i++)
|
||||
{
|
||||
//get the settings defined for the entire section
|
||||
CsSettings::SettingMap *settings = settingsMap [mStackedWidget->widget(i)->objectName()];
|
||||
CSMSettings::SettingMap *settings = settingsMap [mStackedWidget->widget(i)->objectName()];
|
||||
|
||||
//if found, initialize the page's widgets
|
||||
if (settings)
|
||||
|
@ -57,7 +57,7 @@ void CsSettings::UserSettingsDialog::setWidgetStates (SectionMap settingsMap)
|
|||
}
|
||||
}
|
||||
|
||||
void CsSettings::UserSettingsDialog::buildPages()
|
||||
void CSVSettings::UserSettingsDialog::buildPages()
|
||||
{
|
||||
//craete central widget with it's layout and immediate children
|
||||
QWidget *centralWidget = new QWidget (this);
|
||||
|
@ -81,21 +81,21 @@ void CsSettings::UserSettingsDialog::buildPages()
|
|||
createPage<BlankPage>("Page3");
|
||||
}
|
||||
|
||||
void CsSettings::UserSettingsDialog::createSamplePage()
|
||||
void CSVSettings::UserSettingsDialog::createSamplePage()
|
||||
{
|
||||
//add pages to stackedwidget and items to listwidget
|
||||
CsSettings::AbstractPage *page
|
||||
= new CsSettings::EditorPage(this);
|
||||
CSVSettings::AbstractPage *page
|
||||
= new CSVSettings::EditorPage(this);
|
||||
|
||||
mStackedWidget->addWidget (page);
|
||||
|
||||
new QListWidgetItem (page->objectName(), mListWidget);
|
||||
|
||||
connect ( page, SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &)),
|
||||
this, SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &)));
|
||||
&(CSMSettings::UserSettings::instance()), SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &)));
|
||||
}
|
||||
|
||||
void CsSettings::UserSettingsDialog::positionWindow ()
|
||||
void CSVSettings::UserSettingsDialog::positionWindow ()
|
||||
{
|
||||
QRect scr = QApplication::desktop()->screenGeometry();
|
||||
|
||||
|
@ -103,14 +103,14 @@ void CsSettings::UserSettingsDialog::positionWindow ()
|
|||
|
||||
}
|
||||
|
||||
CsSettings::SectionMap CsSettings::UserSettingsDialog::loadSettings ()
|
||||
CSMSettings::SectionMap CSVSettings::UserSettingsDialog::loadSettings ()
|
||||
{
|
||||
QString userPath = QString::fromStdString(mCfgMgr.getUserPath().string());
|
||||
|
||||
mPaths.append(QString("opencs.cfg"));
|
||||
mPaths.append(userPath + QString("opencs.cfg"));
|
||||
|
||||
SectionMap settingsMap;
|
||||
CSMSettings::SectionMap settingsMap;
|
||||
|
||||
foreach (const QString &path, mPaths)
|
||||
{
|
||||
|
@ -135,7 +135,7 @@ CsSettings::SectionMap CsSettings::UserSettingsDialog::loadSettings ()
|
|||
QTextStream stream(&file);
|
||||
stream.setCodec(QTextCodec::codecForName("UTF-8"));
|
||||
|
||||
mUserSettings.getSettings(stream, settingsMap);
|
||||
CSMSettings::UserSettings::instance().getSettings(stream, settingsMap);
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
@ -144,9 +144,9 @@ CsSettings::SectionMap CsSettings::UserSettingsDialog::loadSettings ()
|
|||
return settingsMap;
|
||||
}
|
||||
|
||||
void CsSettings::UserSettingsDialog::writeSettings()
|
||||
void CSVSettings::UserSettingsDialog::writeSettings()
|
||||
{
|
||||
QMap<QString, SettingList *> settings;
|
||||
QMap<QString, CSMSettings::SettingList *> settings;
|
||||
|
||||
for (int i = 0; i < mStackedWidget->count(); ++i)
|
||||
{
|
||||
|
@ -154,16 +154,16 @@ void CsSettings::UserSettingsDialog::writeSettings()
|
|||
settings [page->objectName()] = page->getSettings();
|
||||
}
|
||||
|
||||
mUserSettings.writeFile(mUserSettings.openFile(mPaths.back()), settings);
|
||||
CSMSettings::UserSettings::instance().writeFile(CSMSettings::UserSettings::instance().openFile(mPaths.back()), settings);
|
||||
|
||||
}
|
||||
|
||||
CsSettings::AbstractPage *CsSettings::UserSettingsDialog::getAbstractPage (int index)
|
||||
CSVSettings::AbstractPage *CSVSettings::UserSettingsDialog::getAbstractPage (int index)
|
||||
{
|
||||
return dynamic_cast<AbstractPage *>(mStackedWidget->widget(index));
|
||||
}
|
||||
|
||||
void CsSettings::UserSettingsDialog::slotChangePage(QListWidgetItem *current, QListWidgetItem *previous)
|
||||
void CSVSettings::UserSettingsDialog::slotChangePage(QListWidgetItem *current, QListWidgetItem *previous)
|
||||
{
|
||||
if (!current)
|
||||
current = previous;
|
|
@ -5,18 +5,22 @@
|
|||
#include <QStackedWidget>
|
||||
#include <QListWidgetItem>
|
||||
|
||||
#ifndef Q_MOC_RUN
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
#include "usersettings.hpp"
|
||||
#include "support.hpp"
|
||||
#endif
|
||||
|
||||
#include "../../model/settings/usersettings.hpp"
|
||||
#include "../../model/settings/support.hpp"
|
||||
|
||||
class QHBoxLayout;
|
||||
class AbstractWidget;
|
||||
class QStackedWidget;
|
||||
class QListWidget;
|
||||
|
||||
namespace CsSettings {
|
||||
namespace CSVSettings {
|
||||
|
||||
class AbstractPage;
|
||||
|
||||
class UserSettingsDialog : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -24,7 +28,6 @@ namespace CsSettings {
|
|||
QStringList mPaths;
|
||||
QListWidget *mListWidget;
|
||||
QStackedWidget *mStackedWidget;
|
||||
UserSettings mUserSettings;
|
||||
Files::ConfigurationManager mCfgMgr;
|
||||
|
||||
public:
|
||||
|
@ -35,10 +38,10 @@ namespace CsSettings {
|
|||
|
||||
void closeEvent (QCloseEvent *event);
|
||||
AbstractPage *getAbstractPage (int index);
|
||||
void setWidgetStates (SectionMap settingsMap);
|
||||
void setWidgetStates (CSMSettings::SectionMap settingsMap);
|
||||
void buildPages();
|
||||
void positionWindow ();
|
||||
SectionMap loadSettings();
|
||||
CSMSettings::SectionMap loadSettings();
|
||||
void writeSettings();
|
||||
void createSamplePage();
|
||||
|
||||
|
@ -61,9 +64,6 @@ namespace CsSettings {
|
|||
resize (mStackedWidget->sizeHint());
|
||||
}
|
||||
|
||||
signals:
|
||||
void signalUpdateEditorSetting (const QString &settingName, const QString &settingValue);
|
||||
|
||||
public slots:
|
||||
void slotChangePage (QListWidgetItem*, QListWidgetItem*);
|
||||
};
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QAbstractTableModel>
|
||||
#include <QAbstractItemModel>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QSpinBox>
|
||||
#include <QLineEdit>
|
||||
|
@ -24,7 +24,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM
|
|||
|
||||
widget->setLayout (layout);
|
||||
|
||||
QAbstractTableModel *model = document.getData().getTableModel (id);
|
||||
QAbstractItemModel *model = document.getData().getTableModel (id);
|
||||
|
||||
int columns = model->columnCount();
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue