1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-24 11:23:50 +00:00

Merge branch 'master' into jump-to-modified

This commit is contained in:
cc9cii 2015-05-30 09:27:08 +10:00
commit 76feca6974
150 changed files with 2343 additions and 563 deletions

View file

@ -98,6 +98,7 @@ Programmers
Sebastian Wick (swick) Sebastian Wick (swick)
Sergey Shambir Sergey Shambir
sir_herrbatka sir_herrbatka
smbas
Stefan Galowicz (bogglez) Stefan Galowicz (bogglez)
Stanislav Bobrov (Jiub) Stanislav Bobrov (Jiub)
Sylvain Thesnieres (Garvek) Sylvain Thesnieres (Garvek)
@ -109,6 +110,13 @@ Programmers
Vincent Heuken Vincent Heuken
vocollapse vocollapse
Manual
------
Bodillium
Cramal
sir_herrbatka
Packagers Packagers
--------- ---------

View file

@ -3,6 +3,7 @@
Bug #923: Editor: Operations-Multithreading is broken Bug #923: Editor: Operations-Multithreading is broken
Bug #1317: Erene Llenim in Seyda Neen does not walk around Bug #1317: Erene Llenim in Seyda Neen does not walk around
Bug #1405: Water rendering glitch near Seyda Neen lighthouse
Bug #1621: "Error Detecting Morrowind Installation" in the default directory Bug #1621: "Error Detecting Morrowind Installation" in the default directory
Bug #2216: Creating a clone of the player stops you moving. Bug #2216: Creating a clone of the player stops you moving.
Bug #2387: Casting bound weapon spell doesn't switch to "ready weapon" mode Bug #2387: Casting bound weapon spell doesn't switch to "ready weapon" mode
@ -23,6 +24,11 @@
Bug #2475: cumulative stacks of 100 point fortify skill speechcraft boosts do not apply correctly Bug #2475: cumulative stacks of 100 point fortify skill speechcraft boosts do not apply correctly
Bug #2498: Editor: crash when issuing undo command after the table subview is closed Bug #2498: Editor: crash when issuing undo command after the table subview is closed
Bug #2500: Editor: object table - can't undo delete record Bug #2500: Editor: object table - can't undo delete record
Bug #2518: OpenMW detect spell returns false positives
Bug #2521: NPCs don't react to stealing when inventory menu is open.
Bug #2525: Can't click on red dialogue choice [rise of house telvanni][60fffec]
Bug #2530: GetSpellEffects not working as in vanilla
Bug #2557: Crash on first launch after choosing "Run installation wizard"
Feature #139: Editor: Global Search & Replace Feature #139: Editor: Global Search & Replace
Feature #1219: Editor: Add dialogue mode only columns Feature #1219: Editor: Add dialogue mode only columns
Feature #2024: Hotkey for hand to hand (i.e. unequip any weapon) Feature #2024: Hotkey for hand to hand (i.e. unequip any weapon)
@ -34,6 +40,7 @@
Feature #2505: Editor: optionally show a line number column in the script editor Feature #2505: Editor: optionally show a line number column in the script editor
Feature #2512: Editor: Offer use of monospace fonts in the script editor as an option Feature #2512: Editor: Offer use of monospace fonts in the script editor as an option
Feature #2514: Editor: focus on ID input field on clone/add Feature #2514: Editor: focus on ID input field on clone/add
Feature #2519: it is not possible to change icons that appear on the map after casting the Detect <animal | enchantment | key> spells
Task #2460: OS X: Use Application Support directory as user data path Task #2460: OS X: Use Application Support directory as user data path
Task #2516: Editor: Change References / Referenceables terminology Task #2516: Editor: Change References / Referenceables terminology

View file

@ -351,7 +351,7 @@ endif()
# CXX Compiler settings # CXX Compiler settings
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang) if (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unused-parameter -Wno-reorder -std=c++98 -pedantic -Wno-long-long") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unused-parameter -std=c++98 -pedantic -Wno-long-long")
if (CMAKE_CXX_COMPILER_ID STREQUAL Clang AND NOT APPLE) if (CMAKE_CXX_COMPILER_ID STREQUAL Clang AND NOT APPLE)
execute_process(COMMAND ${CMAKE_C_COMPILER} --version OUTPUT_VARIABLE CLANG_VERSION) execute_process(COMMAND ${CMAKE_C_COMPILER} --version OUTPUT_VARIABLE CLANG_VERSION)

View file

@ -36,13 +36,13 @@ QString getAspect(int x, int y)
} }
Launcher::GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &graphicsSetting, QWidget *parent) Launcher::GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &graphicsSetting, QWidget *parent)
: mOgre(NULL) : QWidget(parent)
, mOgre(NULL)
, mSelectedRenderSystem(NULL) , mSelectedRenderSystem(NULL)
, mOpenGLRenderSystem(NULL) , mOpenGLRenderSystem(NULL)
, mDirect3DRenderSystem(NULL) , mDirect3DRenderSystem(NULL)
, mCfgMgr(cfg) , mCfgMgr(cfg)
, mGraphicsSettings(graphicsSetting) , mGraphicsSettings(graphicsSetting)
, QWidget(parent)
{ {
setObjectName ("GraphicsPage"); setObjectName ("GraphicsPage");
setupUi(this); setupUi(this);

View file

@ -59,13 +59,15 @@ int main(int argc, char *argv[])
Launcher::MainDialog mainWin; Launcher::MainDialog mainWin;
if (!mainWin.showFirstRunDialog()) Launcher::FirstRunDialogResult result = mainWin.showFirstRunDialog();
if (result == Launcher::FirstRunDialogResultFailure)
return 0; return 0;
// if (!mainWin.setup()) { // if (!mainWin.setup()) {
// return 0; // return 0;
// } // }
if (result == Launcher::FirstRunDialogResultContinue)
mainWin.show(); mainWin.show();
int returnValue = app.exec(); int returnValue = app.exec();

View file

@ -148,10 +148,10 @@ void Launcher::MainDialog::createPages()
} }
bool Launcher::MainDialog::showFirstRunDialog() Launcher::FirstRunDialogResult Launcher::MainDialog::showFirstRunDialog()
{ {
if (!setupLauncherSettings()) if (!setupLauncherSettings())
return false; return FirstRunDialogResultFailure;
if (mLauncherSettings.value(QString("General/firstrun"), QString("true")) == QLatin1String("true")) if (mLauncherSettings.value(QString("General/firstrun"), QString("true")) == QLatin1String("true"))
{ {
@ -176,14 +176,14 @@ bool Launcher::MainDialog::showFirstRunDialog()
if (msgBox.clickedButton() == wizardButton) if (msgBox.clickedButton() == wizardButton)
{ {
if (!mWizardInvoker->startProcess(QLatin1String("openmw-wizard"), false)) { if (!mWizardInvoker->startProcess(QLatin1String("openmw-wizard"), false)) {
return false; return FirstRunDialogResultFailure;
} else { } else {
return true; return FirstRunDialogResultWizard;
} }
} }
} }
return setup(); return setup() ? FirstRunDialogResultContinue : FirstRunDialogResultFailure;
} }
bool Launcher::MainDialog::setup() bool Launcher::MainDialog::setup()

View file

@ -31,6 +31,13 @@ namespace Launcher
class UnshieldThread; class UnshieldThread;
class SettingsPage; class SettingsPage;
enum FirstRunDialogResult
{
FirstRunDialogResultFailure,
FirstRunDialogResultContinue,
FirstRunDialogResultWizard
};
#ifndef WIN32 #ifndef WIN32
bool expansions(Launcher::UnshieldThread& cd); bool expansions(Launcher::UnshieldThread& cd);
#endif #endif
@ -44,7 +51,7 @@ namespace Launcher
~MainDialog(); ~MainDialog();
bool setup(); bool setup();
bool showFirstRunDialog(); FirstRunDialogResult showFirstRunDialog();
bool reloadSettings(); bool reloadSettings();
bool writeSettings(); bool writeSettings();

View file

@ -18,10 +18,10 @@ using namespace Process;
Launcher::SettingsPage::SettingsPage(Files::ConfigurationManager &cfg, Launcher::SettingsPage::SettingsPage(Files::ConfigurationManager &cfg,
Config::GameSettings &gameSettings, Config::GameSettings &gameSettings,
Config::LauncherSettings &launcherSettings, MainDialog *parent) Config::LauncherSettings &launcherSettings, MainDialog *parent)
: mCfgMgr(cfg) : QWidget(parent)
, mCfgMgr(cfg)
, mGameSettings(gameSettings) , mGameSettings(gameSettings)
, mLauncherSettings(launcherSettings) , mLauncherSettings(launcherSettings)
, QWidget(parent)
, mMain(parent) , mMain(parent)
{ {
setupUi(this); setupUi(this);

View file

@ -40,13 +40,13 @@ opencs_units (model/tools
opencs_units_noqt (model/tools opencs_units_noqt (model/tools
mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck
birthsigncheck spellcheck referencecheck referenceablecheck scriptcheck bodypartcheck birthsigncheck spellcheck referencecheck referenceablecheck scriptcheck bodypartcheck
startscriptcheck search searchoperation searchstage startscriptcheck search searchoperation searchstage pathgridcheck
) )
opencs_units (view/doc opencs_units (view/doc
viewmanager view operations operation subview startup filedialog newgame viewmanager view operations operation subview startup filedialog newgame
filewidget adjusterwidget loader globaldebugprofilemenu runlogsubview filewidget adjusterwidget loader globaldebugprofilemenu runlogsubview sizehint
) )
@ -63,6 +63,7 @@ opencs_units (view/world
table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator
cellcreator referenceablecreator referencecreator scenesubview cellcreator referenceablecreator referencecreator scenesubview
infocreator scriptedit dialoguesubview previewsubview regionmap dragrecordtable nestedtable infocreator scriptedit dialoguesubview previewsubview regionmap dragrecordtable nestedtable
dialoguespinbox
) )
opencs_units_noqt (view/world opencs_units_noqt (view/world

View file

@ -23,8 +23,8 @@
CS::Editor::Editor (OgreInit::OgreInit& ogreInit) CS::Editor::Editor (OgreInit::OgreInit& ogreInit)
: mUserSettings (mCfgMgr), mOverlaySystem (0), mDocumentManager (mCfgMgr), : mUserSettings (mCfgMgr), mOverlaySystem (0), mDocumentManager (mCfgMgr),
mViewManager (mDocumentManager), mViewManager (mDocumentManager), mPid(""),
mIpcServerName ("org.openmw.OpenCS"), mServer(NULL), mClientSocket(NULL), mPid(""), mLock() mLock(), mIpcServerName ("org.openmw.OpenCS"), mServer(NULL), mClientSocket(NULL)
{ {
std::pair<Files::PathContainer, std::vector<std::string> > config = readConfig(); std::pair<Files::PathContainer, std::vector<std::string> > config = readConfig();

View file

@ -2251,11 +2251,12 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
ToUTF8::FromType encoding, const CSMWorld::ResourcesManager& resourcesManager, ToUTF8::FromType encoding, const CSMWorld::ResourcesManager& resourcesManager,
const std::vector<std::string>& blacklistedScripts) const std::vector<std::string>& blacklistedScripts)
: mSavePath (savePath), mContentFiles (files), mNew (new_), mData (encoding, resourcesManager), : mSavePath (savePath), mContentFiles (files), mNew (new_), mData (encoding, resourcesManager),
mTools (*this), mResDir(resDir), mTools (*this),
mProjectPath ((configuration.getUserDataPath() / "projects") / mProjectPath ((configuration.getUserDataPath() / "projects") /
(savePath.filename().string() + ".project")), (savePath.filename().string() + ".project")),
mSavingOperation (*this, mProjectPath, encoding), mSavingOperation (*this, mProjectPath, encoding),
mSaving (&mSavingOperation), mSaving (&mSavingOperation),
mResDir(resDir),
mRunner (mProjectPath), mPhysics(boost::shared_ptr<CSVWorld::PhysicsSystem>()) mRunner (mProjectPath), mPhysics(boost::shared_ptr<CSVWorld::PhysicsSystem>())
{ {
if (mContentFiles.empty()) if (mContentFiles.empty())

View file

@ -9,7 +9,7 @@
CSMFilter::ValueNode::ValueNode (int columnId, Type lowerType, Type upperType, CSMFilter::ValueNode::ValueNode (int columnId, Type lowerType, Type upperType,
double lower, double upper) double lower, double upper)
: mColumnId (columnId), mLowerType (lowerType), mUpperType (upperType), mLower (lower), mUpper (upper){} : mColumnId (columnId), mLower (lower), mUpper (upper), mLowerType (lowerType), mUpperType (upperType){}
bool CSMFilter::ValueNode::test (const CSMWorld::IdTableBase& table, int row, bool CSMFilter::ValueNode::test (const CSMWorld::IdTableBase& table, int row,
const std::map<int, int>& columns) const const std::map<int, int>& columns) const

View file

@ -4,7 +4,7 @@
CSMSettings::Connector::Connector(CSVSettings::View *master, CSMSettings::Connector::Connector(CSVSettings::View *master,
QObject *parent) QObject *parent)
: mMasterView (master), QObject(parent) : QObject(parent), mMasterView (master)
{} {}
void CSMSettings::Connector::addSlaveView (CSVSettings::View *view, void CSMSettings::Connector::addSlaveView (CSVSettings::View *view,

View file

@ -143,6 +143,24 @@ void CSMSettings::UserSettings::buildSettingModelDefaults()
minWidth->setDefaultValue (325); minWidth->setDefaultValue (325);
minWidth->setRange (50, 10000); minWidth->setRange (50, 10000);
minWidth->setToolTip ("Minimum width of subviews."); minWidth->setToolTip ("Minimum width of subviews.");
QString defaultScroll = "Scrollbar Only";
QStringList scrollValues = QStringList() << defaultScroll << "Grow Only" << "Grow then Scroll";
Setting *mainwinScroll = createSetting (Type_RadioButton, "mainwindow-scrollbar",
"Add a horizontal scrollbar to the main view window.");
mainwinScroll->setDefaultValue (defaultScroll);
mainwinScroll->setDeclaredValues (scrollValues);
mainwinScroll->setToolTip ("Scrollbar Only: Simple addition of scrollbars, the view window does not grow"
" automatically.\n"
"Grow Only: Original Editor behaviour. The view window grows as subviews are added. No scrollbars.\n"
"Grow then Scroll: The view window grows. The scrollbar appears once it cannot grow any further.");
Setting *grow = createSetting (Type_CheckBox, "grow-limit", "Grow Limit Screen");
grow->setDefaultValue ("false");
grow->setToolTip ("When \"Grow then Scroll\" option is selected, the window size grows to"
" the width of the virtual desktop. \nIf this option is selected the the window growth"
"is limited to the current screen.");
} }
declareSection ("records", "Records"); declareSection ("records", "Records");

View file

@ -0,0 +1,161 @@
#include "pathgridcheck.hpp"
#include <sstream>
#include <algorithm>
#include "../world/universalid.hpp"
#include "../world/idcollection.hpp"
#include "../world/subcellcollection.hpp"
#include "../world/pathgrid.hpp"
namespace
{
struct Point
{
unsigned char mConnectionNum;
std::vector<int> mOtherIndex;
Point() : mConnectionNum(0), mOtherIndex(0) {}
};
}
CSMTools::PathgridCheckStage::PathgridCheckStage (const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids)
: mPathgrids (pathgrids)
{}
int CSMTools::PathgridCheckStage::setup()
{
return mPathgrids.getSize();
}
void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& messages)
{
const CSMWorld::Record<CSMWorld::Pathgrid>& record = mPathgrids.getRecord (stage);
if (record.isDeleted())
return;
const CSMWorld::Pathgrid& pathgrid = record.get();
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Pathgrid, pathgrid.mId);
// check the number of pathgrid points
if (pathgrid.mData.mS2 > static_cast<int>(pathgrid.mPoints.size()))
messages.push_back (std::make_pair (id, pathgrid.mId + " has less points than expected"));
else if (pathgrid.mData.mS2 > static_cast<int>(pathgrid.mPoints.size()))
messages.push_back (std::make_pair (id, pathgrid.mId + " has more points than expected"));
std::vector<Point> pointList(pathgrid.mPoints.size());
std::vector<int> duplList;
for (unsigned int i = 0; i < pathgrid.mEdges.size(); ++i)
{
if (pathgrid.mEdges[i].mV0 < static_cast<int>(pathgrid.mPoints.size()) && pathgrid.mEdges[i].mV0 >= 0)
{
pointList[pathgrid.mEdges[i].mV0].mConnectionNum++;
// first check for duplicate edges
unsigned int j = 0;
for (; j < pointList[pathgrid.mEdges[i].mV0].mOtherIndex.size(); ++j)
{
if (pointList[pathgrid.mEdges[i].mV0].mOtherIndex[j] == pathgrid.mEdges[i].mV1)
{
std::ostringstream ss;
ss << "has a duplicate edge between points" << pathgrid.mEdges[i].mV0
<< " and " << pathgrid.mEdges[i].mV1;
messages.push_back (std::make_pair (id, pathgrid.mId + ss.str()));
break;
}
}
// only add if not a duplicate
if (j == pointList[pathgrid.mEdges[i].mV0].mOtherIndex.size())
pointList[pathgrid.mEdges[i].mV0].mOtherIndex.push_back(pathgrid.mEdges[i].mV1);
}
else
{
std::ostringstream ss;
ss << " has an edge connecting a non-existent point " << pathgrid.mEdges[i].mV0;
messages.push_back (std::make_pair (id, pathgrid.mId + ss.str()));
}
}
for (unsigned int i = 0; i < pathgrid.mPoints.size(); ++i)
{
// check the connection number for each point matches the edge connections
if (pathgrid.mPoints[i].mConnectionNum > pointList[i].mConnectionNum)
{
std::ostringstream ss;
ss << " has has less edges than expected for point " << i;
messages.push_back (std::make_pair (id, pathgrid.mId + ss.str()));
}
else if (pathgrid.mPoints[i].mConnectionNum < pointList[i].mConnectionNum)
{
std::ostringstream ss;
ss << " has has more edges than expected for point " << i;
messages.push_back (std::make_pair (id, pathgrid.mId + ss.str()));
}
// check that edges are bidirectional
bool foundReverse = false;
for (unsigned int j = 0; j < pointList[i].mOtherIndex.size(); ++j)
{
for (unsigned int k = 0; k < pointList[pointList[i].mOtherIndex[j]].mOtherIndex.size(); ++k)
{
if (pointList[pointList[i].mOtherIndex[j]].mOtherIndex[k] == static_cast<int>(i))
{
foundReverse = true;
break;
}
}
if (!foundReverse)
{
std::ostringstream ss;
ss << " has a missing edge between points " << i << " and " << pointList[i].mOtherIndex[j];
messages.push_back (std::make_pair (id, pathgrid.mId + ss.str()));
}
}
// check duplicate points
// FIXME: how to do this efficiently?
for (unsigned int j = 0; j < pathgrid.mPoints.size(); ++j)
{
if (j == i)
continue;
if (pathgrid.mPoints[i].mX == pathgrid.mPoints[j].mX &&
pathgrid.mPoints[i].mY == pathgrid.mPoints[j].mY &&
pathgrid.mPoints[i].mZ == pathgrid.mPoints[j].mZ)
{
std::vector<int>::const_iterator it = find(duplList.begin(), duplList.end(), i);
if (it == duplList.end())
{
std::ostringstream ss;
ss << " has a duplicated point (" << i
<< ") x=" << pathgrid.mPoints[i].mX
<< ", y=" << pathgrid.mPoints[i].mY
<< ", z=" << pathgrid.mPoints[i].mZ;
messages.push_back (std::make_pair (id, pathgrid.mId + ss.str()));
duplList.push_back(i);
break;
}
}
}
}
// check pathgrid points that are not connected to anything
for (unsigned int i = 0; i < pointList.size(); ++i)
{
if (pointList[i].mConnectionNum == 0)
{
std::ostringstream ss;
ss << " has an orphaned point (" << i
<< ") x=" << pathgrid.mPoints[i].mX
<< ", y=" << pathgrid.mPoints[i].mY
<< ", z=" << pathgrid.mPoints[i].mZ;
messages.push_back (std::make_pair (id, pathgrid.mId + ss.str()));
}
}
// TODO: check whether there are disconnected graphs
}

View file

@ -0,0 +1,31 @@
#ifndef CSM_TOOLS_PATHGRIDCHECK_H
#define CSM_TOOLS_PATHGRIDCHECK_H
#include "../world/collection.hpp"
#include "../doc/stage.hpp"
namespace CSMWorld
{
struct Pathgrid;
template<typename T, typename AT>
class SubCellCollection;
}
namespace CSMTools
{
class PathgridCheckStage : public CSMDoc::Stage
{
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid, CSMWorld::IdAccessor<CSMWorld::Pathgrid> >& mPathgrids;
public:
PathgridCheckStage (const CSMWorld::SubCellCollection<CSMWorld::Pathgrid, CSMWorld::IdAccessor<CSMWorld::Pathgrid> >& pathgrids);
virtual int setup();
virtual void perform (int stage, CSMDoc::Messages& messages);
};
}
#endif // CSM_TOOLS_PATHGRIDCHECK_H

View file

@ -8,12 +8,14 @@
CSMTools::ReferenceableCheckStage::ReferenceableCheckStage( CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(
const CSMWorld::RefIdData& referenceable, const CSMWorld::IdCollection<ESM::Race >& races, const CSMWorld::RefIdData& referenceable, const CSMWorld::IdCollection<ESM::Race >& races,
const CSMWorld::IdCollection<ESM::Class>& classes, const CSMWorld::IdCollection<ESM::Class>& classes,
const CSMWorld::IdCollection<ESM::Faction>& faction) const CSMWorld::IdCollection<ESM::Faction>& faction,
const CSMWorld::IdCollection<ESM::Script>& scripts)
: :
mReferencables(referenceable), mReferencables(referenceable),
mClasses(classes),
mRaces(races), mRaces(races),
mClasses(classes),
mFactions(faction), mFactions(faction),
mScripts(scripts),
mPlayerPresent(false) mPlayerPresent(false)
{ {
} }
@ -245,6 +247,9 @@ void CSMTools::ReferenceableCheckStage::bookCheck(
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Book, book.mId); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Book, book.mId);
inventoryItemCheck<ESM::Book>(book, messages, id.toString(), true); inventoryItemCheck<ESM::Book>(book, messages, id.toString(), true);
// Check that mentioned scripts exist
scriptCheck<ESM::Book>(book, messages, id.toString());
} }
void CSMTools::ReferenceableCheckStage::activatorCheck( void CSMTools::ReferenceableCheckStage::activatorCheck(
@ -265,6 +270,9 @@ void CSMTools::ReferenceableCheckStage::activatorCheck(
//Checking for model, IIRC all activators should have a model //Checking for model, IIRC all activators should have a model
if (activator.mModel.empty()) if (activator.mModel.empty())
messages.push_back (std::make_pair (id, activator.mId + " has no model")); messages.push_back (std::make_pair (id, activator.mId + " has no model"));
// Check that mentioned scripts exist
scriptCheck<ESM::Activator>(activator, messages, id.toString());
} }
void CSMTools::ReferenceableCheckStage::potionCheck( void CSMTools::ReferenceableCheckStage::potionCheck(
@ -284,6 +292,9 @@ void CSMTools::ReferenceableCheckStage::potionCheck(
inventoryItemCheck<ESM::Potion>(potion, messages, id.toString()); inventoryItemCheck<ESM::Potion>(potion, messages, id.toString());
//IIRC potion can have empty effects list just fine. //IIRC potion can have empty effects list just fine.
// Check that mentioned scripts exist
scriptCheck<ESM::Potion>(potion, messages, id.toString());
} }
@ -305,6 +316,9 @@ void CSMTools::ReferenceableCheckStage::apparatusCheck(
inventoryItemCheck<ESM::Apparatus>(apparatus, messages, id.toString()); inventoryItemCheck<ESM::Apparatus>(apparatus, messages, id.toString());
toolCheck<ESM::Apparatus>(apparatus, messages, id.toString()); toolCheck<ESM::Apparatus>(apparatus, messages, id.toString());
// Check that mentioned scripts exist
scriptCheck<ESM::Apparatus>(apparatus, messages, id.toString());
} }
void CSMTools::ReferenceableCheckStage::armorCheck( void CSMTools::ReferenceableCheckStage::armorCheck(
@ -331,6 +345,9 @@ void CSMTools::ReferenceableCheckStage::armorCheck(
//checking for health. Only positive numbers are allowed, or 0 is illegal //checking for health. Only positive numbers are allowed, or 0 is illegal
if (armor.mData.mHealth <= 0) if (armor.mData.mHealth <= 0)
messages.push_back (std::make_pair (id, armor.mId + " has non positive health")); messages.push_back (std::make_pair (id, armor.mId + " has non positive health"));
// Check that mentioned scripts exist
scriptCheck<ESM::Armor>(armor, messages, id.toString());
} }
void CSMTools::ReferenceableCheckStage::clothingCheck( void CSMTools::ReferenceableCheckStage::clothingCheck(
@ -348,6 +365,9 @@ void CSMTools::ReferenceableCheckStage::clothingCheck(
const ESM::Clothing& clothing = (dynamic_cast<const CSMWorld::Record<ESM::Clothing>& >(baseRecord)).get(); const ESM::Clothing& clothing = (dynamic_cast<const CSMWorld::Record<ESM::Clothing>& >(baseRecord)).get();
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Clothing, clothing.mId); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Clothing, clothing.mId);
inventoryItemCheck<ESM::Clothing>(clothing, messages, id.toString(), true); inventoryItemCheck<ESM::Clothing>(clothing, messages, id.toString(), true);
// Check that mentioned scripts exist
scriptCheck<ESM::Clothing>(clothing, messages, id.toString());
} }
void CSMTools::ReferenceableCheckStage::containerCheck( void CSMTools::ReferenceableCheckStage::containerCheck(
@ -377,6 +397,9 @@ void CSMTools::ReferenceableCheckStage::containerCheck(
//checking for name //checking for name
if (container.mName.empty()) if (container.mName.empty())
messages.push_back (std::make_pair (id, container.mId + " has an empty name")); messages.push_back (std::make_pair (id, container.mId + " has an empty name"));
// Check that mentioned scripts exist
scriptCheck<ESM::Container>(container, messages, id.toString());
} }
void CSMTools::ReferenceableCheckStage::creatureCheck ( void CSMTools::ReferenceableCheckStage::creatureCheck (
@ -444,6 +467,9 @@ void CSMTools::ReferenceableCheckStage::creatureCheck (
//TODO, find meaning of other values //TODO, find meaning of other values
if (creature.mData.mGold < 0) //It seems that this is for gold in merchant creatures if (creature.mData.mGold < 0) //It seems that this is for gold in merchant creatures
messages.push_back (std::make_pair (id, creature.mId + " has negative gold ")); messages.push_back (std::make_pair (id, creature.mId + " has negative gold "));
// Check that mentioned scripts exist
scriptCheck<ESM::Creature>(creature, messages, id.toString());
} }
void CSMTools::ReferenceableCheckStage::doorCheck( void CSMTools::ReferenceableCheckStage::doorCheck(
@ -455,15 +481,18 @@ void CSMTools::ReferenceableCheckStage::doorCheck(
if (baseRecord.isDeleted()) if (baseRecord.isDeleted())
return; return;
const ESM::Door& Door = (dynamic_cast<const CSMWorld::Record<ESM::Door>&>(baseRecord)).get(); const ESM::Door& door = (dynamic_cast<const CSMWorld::Record<ESM::Door>&>(baseRecord)).get();
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Door, Door.mId); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Door, door.mId);
//usual, name or model //usual, name or model
if (Door.mName.empty()) if (door.mName.empty())
messages.push_back (std::make_pair (id, Door.mId + " has an empty name")); messages.push_back (std::make_pair (id, door.mId + " has an empty name"));
if (Door.mModel.empty()) if (door.mModel.empty())
messages.push_back (std::make_pair (id, Door.mId + " has no model")); messages.push_back (std::make_pair (id, door.mId + " has no model"));
// Check that mentioned scripts exist
scriptCheck<ESM::Door>(door, messages, id.toString());
} }
void CSMTools::ReferenceableCheckStage::ingredientCheck( void CSMTools::ReferenceableCheckStage::ingredientCheck(
@ -478,10 +507,13 @@ void CSMTools::ReferenceableCheckStage::ingredientCheck(
return; return;
} }
const ESM::Ingredient& Ingredient = (dynamic_cast<const CSMWorld::Record<ESM::Ingredient>& >(baseRecord)).get(); const ESM::Ingredient& ingredient = (dynamic_cast<const CSMWorld::Record<ESM::Ingredient>& >(baseRecord)).get();
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Ingredient, Ingredient.mId); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Ingredient, ingredient.mId);
inventoryItemCheck<ESM::Ingredient>(Ingredient, messages, id.toString()); inventoryItemCheck<ESM::Ingredient>(ingredient, messages, id.toString());
// Check that mentioned scripts exist
scriptCheck<ESM::Ingredient>(ingredient, messages, id.toString());
} }
void CSMTools::ReferenceableCheckStage::creaturesLevListCheck( void CSMTools::ReferenceableCheckStage::creaturesLevListCheck(
@ -542,6 +574,9 @@ void CSMTools::ReferenceableCheckStage::lightCheck(
if (light.mData.mTime == 0) if (light.mData.mTime == 0)
messages.push_back (std::make_pair (id, light.mId + " has zero duration")); messages.push_back (std::make_pair (id, light.mId + " has zero duration"));
} }
// Check that mentioned scripts exist
scriptCheck<ESM::Light>(light, messages, id.toString());
} }
void CSMTools::ReferenceableCheckStage::lockpickCheck( void CSMTools::ReferenceableCheckStage::lockpickCheck(
@ -562,6 +597,9 @@ void CSMTools::ReferenceableCheckStage::lockpickCheck(
inventoryItemCheck<ESM::Lockpick>(lockpick, messages, id.toString()); inventoryItemCheck<ESM::Lockpick>(lockpick, messages, id.toString());
toolCheck<ESM::Lockpick>(lockpick, messages, id.toString(), true); toolCheck<ESM::Lockpick>(lockpick, messages, id.toString(), true);
// Check that mentioned scripts exist
scriptCheck<ESM::Lockpick>(lockpick, messages, id.toString());
} }
void CSMTools::ReferenceableCheckStage::miscCheck( void CSMTools::ReferenceableCheckStage::miscCheck(
@ -580,6 +618,9 @@ void CSMTools::ReferenceableCheckStage::miscCheck(
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Miscellaneous, miscellaneous.mId); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Miscellaneous, miscellaneous.mId);
inventoryItemCheck<ESM::Miscellaneous>(miscellaneous, messages, id.toString()); inventoryItemCheck<ESM::Miscellaneous>(miscellaneous, messages, id.toString());
// Check that mentioned scripts exist
scriptCheck<ESM::Miscellaneous>(miscellaneous, messages, id.toString());
} }
void CSMTools::ReferenceableCheckStage::npcCheck ( void CSMTools::ReferenceableCheckStage::npcCheck (
@ -697,6 +738,9 @@ void CSMTools::ReferenceableCheckStage::npcCheck (
messages.push_back (std::make_pair (id, npc.mId + " has no hair")); messages.push_back (std::make_pair (id, npc.mId + " has no hair"));
//TODO: reputation, Disposition, rank, everything else //TODO: reputation, Disposition, rank, everything else
// Check that mentioned scripts exist
scriptCheck<ESM::NPC>(npc, messages, id.toString());
} }
void CSMTools::ReferenceableCheckStage::weaponCheck( void CSMTools::ReferenceableCheckStage::weaponCheck(
@ -773,6 +817,9 @@ void CSMTools::ReferenceableCheckStage::weaponCheck(
messages.push_back (std::make_pair (id, weapon.mId + " has negative reach")); messages.push_back (std::make_pair (id, weapon.mId + " has negative reach"));
} }
} }
// Check that mentioned scripts exist
scriptCheck<ESM::Weapon>(weapon, messages, id.toString());
} }
void CSMTools::ReferenceableCheckStage::probeCheck( void CSMTools::ReferenceableCheckStage::probeCheck(
@ -792,6 +839,9 @@ void CSMTools::ReferenceableCheckStage::probeCheck(
inventoryItemCheck<ESM::Probe>(probe, messages, id.toString()); inventoryItemCheck<ESM::Probe>(probe, messages, id.toString());
toolCheck<ESM::Probe>(probe, messages, id.toString(), true); toolCheck<ESM::Probe>(probe, messages, id.toString(), true);
// Check that mentioned scripts exist
scriptCheck<ESM::Probe>(probe, messages, id.toString());
} }
void CSMTools::ReferenceableCheckStage::repairCheck ( void CSMTools::ReferenceableCheckStage::repairCheck (
@ -808,6 +858,9 @@ void CSMTools::ReferenceableCheckStage::repairCheck (
inventoryItemCheck<ESM::Repair> (repair, messages, id.toString()); inventoryItemCheck<ESM::Repair> (repair, messages, id.toString());
toolCheck<ESM::Repair> (repair, messages, id.toString(), true); toolCheck<ESM::Repair> (repair, messages, id.toString(), true);
// Check that mentioned scripts exist
scriptCheck<ESM::Repair>(repair, messages, id.toString());
} }
void CSMTools::ReferenceableCheckStage::staticCheck ( void CSMTools::ReferenceableCheckStage::staticCheck (
@ -919,3 +972,13 @@ template<typename List> void CSMTools::ReferenceableCheckStage::listCheck (
someList.mId + " contains item with non-positive level")); someList.mId + " contains item with non-positive level"));
} }
} }
template<typename Tool> void CSMTools::ReferenceableCheckStage::scriptCheck (
const Tool& someTool, CSMDoc::Messages& messages, const std::string& someID)
{
if (!someTool.mScript.empty())
{
if (mScripts.searchId(someTool.mScript) == -1)
messages.push_back (std::make_pair (someID, someTool.mId + " refers to an unknown script \""+someTool.mScript+"\""));
}
}

View file

@ -15,7 +15,8 @@ namespace CSMTools
ReferenceableCheckStage (const CSMWorld::RefIdData& referenceable, ReferenceableCheckStage (const CSMWorld::RefIdData& referenceable,
const CSMWorld::IdCollection<ESM::Race>& races, const CSMWorld::IdCollection<ESM::Race>& races,
const CSMWorld::IdCollection<ESM::Class>& classes, const CSMWorld::IdCollection<ESM::Class>& classes,
const CSMWorld::IdCollection<ESM::Faction>& factions); const CSMWorld::IdCollection<ESM::Faction>& factions,
const CSMWorld::IdCollection<ESM::Script>& scripts);
virtual void perform(int stage, CSMDoc::Messages& messages); virtual void perform(int stage, CSMDoc::Messages& messages);
virtual int setup(); virtual int setup();
@ -69,10 +70,15 @@ namespace CSMTools
CSMDoc::Messages& messages, CSMDoc::Messages& messages,
const std::string& someID); const std::string& someID);
template<typename TOOL> void scriptCheck(const TOOL& someTool,
CSMDoc::Messages& messages,
const std::string& someID);
const CSMWorld::RefIdData& mReferencables; const CSMWorld::RefIdData& mReferencables;
const CSMWorld::IdCollection<ESM::Race>& mRaces; const CSMWorld::IdCollection<ESM::Race>& mRaces;
const CSMWorld::IdCollection<ESM::Class>& mClasses; const CSMWorld::IdCollection<ESM::Class>& mClasses;
const CSMWorld::IdCollection<ESM::Faction>& mFactions; const CSMWorld::IdCollection<ESM::Faction>& mFactions;
const CSMWorld::IdCollection<ESM::Script>& mScripts;
bool mPlayerPresent; bool mPlayerPresent;
}; };
} }

View file

@ -26,6 +26,7 @@
#include "referencecheck.hpp" #include "referencecheck.hpp"
#include "startscriptcheck.hpp" #include "startscriptcheck.hpp"
#include "searchoperation.hpp" #include "searchoperation.hpp"
#include "pathgridcheck.hpp"
CSMDoc::OperationHolder *CSMTools::Tools::get (int type) CSMDoc::OperationHolder *CSMTools::Tools::get (int type)
{ {
@ -81,7 +82,7 @@ CSMDoc::OperationHolder *CSMTools::Tools::getVerifier()
mVerifierOperation->appendStage (new SpellCheckStage (mData.getSpells())); mVerifierOperation->appendStage (new SpellCheckStage (mData.getSpells()));
mVerifierOperation->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions())); mVerifierOperation->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions(), mData.getScripts()));
mVerifierOperation->appendStage (new ReferenceCheckStage(mData.getReferences(), mData.getReferenceables(), mData.getCells(), mData.getFactions())); mVerifierOperation->appendStage (new ReferenceCheckStage(mData.getReferences(), mData.getReferenceables(), mData.getCells(), mData.getFactions()));
@ -96,6 +97,8 @@ CSMDoc::OperationHolder *CSMTools::Tools::getVerifier()
CSMWorld::UniversalId( CSMWorld::UniversalId::Type_Meshes )), CSMWorld::UniversalId( CSMWorld::UniversalId::Type_Meshes )),
mData.getRaces() )); mData.getRaces() ));
mVerifierOperation->appendStage (new PathgridCheckStage (mData.getPathgrids()));
mVerifier.setOperation (mVerifierOperation); mVerifier.setOperation (mVerifierOperation);
} }
@ -103,8 +106,8 @@ CSMDoc::OperationHolder *CSMTools::Tools::getVerifier()
} }
CSMTools::Tools::Tools (CSMDoc::Document& document) CSMTools::Tools::Tools (CSMDoc::Document& document)
: mDocument (document), mData (document.getData()), mVerifierOperation (0), mNextReportNumber (0), : mDocument (document), mData (document.getData()), mVerifierOperation (0),
mSearchOperation (0) mSearchOperation (0), mNextReportNumber (0)
{ {
// index 0: load error log // index 0: load error log
mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel)); mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel));

View file

@ -3,7 +3,7 @@
#include "columns.hpp" #include "columns.hpp"
CSMWorld::ColumnBase::ColumnBase (int columnId, Display displayType, int flags) CSMWorld::ColumnBase::ColumnBase (int columnId, Display displayType, int flags)
: mColumnId (columnId), mDisplayType (displayType), mFlags (flags) : mColumnId (columnId), mFlags (flags), mDisplayType (displayType)
{} {}
CSMWorld::ColumnBase::~ColumnBase() {} CSMWorld::ColumnBase::~ColumnBase() {}
@ -84,6 +84,7 @@ bool CSMWorld::ColumnBase::isId (Display display)
Display_InfoCondFunc, Display_InfoCondFunc,
Display_InfoCondVar, Display_InfoCondVar,
Display_InfoCondComp, Display_InfoCondComp,
Display_RaceSkill,
Display_None Display_None
}; };
@ -137,8 +138,8 @@ bool CSMWorld::NestableColumn::hasChildren() const
} }
CSMWorld::NestedChildColumn::NestedChildColumn (int id, CSMWorld::NestedChildColumn::NestedChildColumn (int id,
CSMWorld::ColumnBase::Display display, bool isEditable) CSMWorld::ColumnBase::Display display, int flags, bool isEditable)
: NestableColumn (id, display, CSMWorld::ColumnBase::Flag_Dialogue) , mIsEditable(isEditable) : NestableColumn (id, display, flags) , mIsEditable(isEditable)
{} {}
bool CSMWorld::NestedChildColumn::isEditable () const bool CSMWorld::NestedChildColumn::isEditable () const

View file

@ -25,7 +25,8 @@ namespace CSMWorld
{ {
Flag_Table = 1, // column should be displayed in table view Flag_Table = 1, // column should be displayed in table view
Flag_Dialogue = 2, // column should be displayed in dialogue view Flag_Dialogue = 2, // column should be displayed in dialogue view
Flag_Dialogue_List = 4 // column should be diaplyed in dialogue view Flag_Dialogue_List = 4, // column should be diaplyed in dialogue view
Flag_Dialogue_Refresh = 8 // refresh dialogue view if this column is modified
}; };
enum Display enum Display
@ -119,6 +120,7 @@ namespace CSMWorld
Display_InfoCondFunc, Display_InfoCondFunc,
Display_InfoCondVar, Display_InfoCondVar,
Display_InfoCondComp, Display_InfoCondComp,
Display_RaceSkill,
//top level columns that nest other columns //top level columns that nest other columns
Display_NestedHeader Display_NestedHeader
@ -199,7 +201,8 @@ namespace CSMWorld
struct NestedChildColumn : public NestableColumn struct NestedChildColumn : public NestableColumn
{ {
NestedChildColumn (int id, Display display, bool isEditable = true); NestedChildColumn (int id,
Display display, int flags = ColumnBase::Flag_Dialogue, bool isEditable = true);
virtual bool isEditable() const; virtual bool isEditable() const;

View file

@ -467,8 +467,9 @@ namespace CSMWorld
int mMask; int mMask;
bool mInverted; bool mInverted;
FlagColumn (int columnId, int mask, bool inverted = false) FlagColumn (int columnId, int mask,
: Column<ESXRecordT> (columnId, ColumnBase::Display_Boolean), mMask (mask), int flags = ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, bool inverted = false)
: Column<ESXRecordT> (columnId, ColumnBase::Display_Boolean, flags), mMask (mask),
mInverted (inverted) mInverted (inverted)
{} {}

View file

@ -176,7 +176,7 @@ namespace CSMWorld
{ ColumnId_ContainerContent, "Content" }, { ColumnId_ContainerContent, "Content" },
{ ColumnId_ItemCount, "Count" }, { ColumnId_ItemCount, "Count" },
{ ColumnId_InventoryItemId, "ID"}, { ColumnId_InventoryItemId, "Item ID"},
{ ColumnId_CombatState, "Combat" }, { ColumnId_CombatState, "Combat" },
{ ColumnId_MagicState, "Magic" }, { ColumnId_MagicState, "Magic" },
@ -188,10 +188,10 @@ namespace CSMWorld
{ ColumnId_ActorInventory, "Inventory" }, { ColumnId_ActorInventory, "Inventory" },
{ ColumnId_SpellList, "Spells" }, { ColumnId_SpellList, "Spells" },
{ ColumnId_SpellId, "ID"}, { ColumnId_SpellId, "Spell ID"},
{ ColumnId_NpcDestinations, "Destinations" }, { ColumnId_NpcDestinations, "Destinations" },
{ ColumnId_DestinationCell, "Cell"}, { ColumnId_DestinationCell, "Dest Cell"},
{ ColumnId_PosX, "Dest X"}, { ColumnId_PosX, "Dest X"},
{ ColumnId_PosY, "Dest Y"}, { ColumnId_PosY, "Dest Y"},
{ ColumnId_PosZ, "Dest Z"}, { ColumnId_PosZ, "Dest Z"},
@ -224,17 +224,17 @@ namespace CSMWorld
{ ColumnId_BoltSound, "Bolt Sound" }, { ColumnId_BoltSound, "Bolt Sound" },
{ ColumnId_PathgridPoints, "Points" }, { ColumnId_PathgridPoints, "Points" },
{ ColumnId_PathgridIndex, "Index" }, { ColumnId_PathgridIndex, "pIndex" },
{ ColumnId_PathgridPosX, "X" }, { ColumnId_PathgridPosX, "X" },
{ ColumnId_PathgridPosY, "Y" }, { ColumnId_PathgridPosY, "Y" },
{ ColumnId_PathgridPosZ, "Z" }, { ColumnId_PathgridPosZ, "Z" },
{ ColumnId_PathgridEdges, "Edges" }, { ColumnId_PathgridEdges, "Edges" },
{ ColumnId_PathgridEdgeIndex, "Index" }, { ColumnId_PathgridEdgeIndex, "eIndex" },
{ ColumnId_PathgridEdge0, "Point 0" }, { ColumnId_PathgridEdge0, "Point 0" },
{ ColumnId_PathgridEdge1, "Point 1" }, { ColumnId_PathgridEdge1, "Point 1" },
{ ColumnId_RegionSounds, "Sounds" }, { ColumnId_RegionSounds, "Sounds" },
{ ColumnId_SoundName, "Name" }, { ColumnId_SoundName, "Sound Name" },
{ ColumnId_SoundChance, "Chance" }, { ColumnId_SoundChance, "Chance" },
{ ColumnId_FactionReactions, "Reactions" }, { ColumnId_FactionReactions, "Reactions" },
@ -250,7 +250,7 @@ namespace CSMWorld
{ ColumnId_AiPackageList, "Ai Packages" }, { ColumnId_AiPackageList, "Ai Packages" },
{ ColumnId_AiPackageType, "Package" }, { ColumnId_AiPackageType, "Package" },
{ ColumnId_AiWanderDist, "Wander Dist" }, { ColumnId_AiWanderDist, "Wander Dist" },
{ ColumnId_AiDuration, "Duration" }, { ColumnId_AiDuration, "Ai Duration" },
{ ColumnId_AiWanderToD, "Wander ToD" }, { ColumnId_AiWanderToD, "Wander ToD" },
{ ColumnId_AiWanderIdle, "Wander Idle" }, { ColumnId_AiWanderIdle, "Wander Idle" },
{ ColumnId_AiWanderRepeat, "Wander Repeat" }, { ColumnId_AiWanderRepeat, "Wander Repeat" },
@ -260,11 +260,11 @@ namespace CSMWorld
{ ColumnId_PartRefList, "Part Reference" }, { ColumnId_PartRefList, "Part Reference" },
{ ColumnId_PartRefType, "Type" }, { ColumnId_PartRefType, "Type" },
{ ColumnId_PartRefMale, "Male" }, { ColumnId_PartRefMale, "Male Part" },
{ ColumnId_PartRefFemale, "Female" }, { ColumnId_PartRefFemale, "Female Part" },
{ ColumnId_LevelledList,"Levelled List" }, { ColumnId_LevelledList,"Levelled List" },
{ ColumnId_LevelledItemId,"Item ID" }, { ColumnId_LevelledItemId,"Levelled Item" },
{ ColumnId_LevelledItemLevel,"Level" }, { ColumnId_LevelledItemLevel,"Level" },
{ ColumnId_LevelledItemType, "Calculate all levels <= player" }, { ColumnId_LevelledItemType, "Calculate all levels <= player" },
{ ColumnId_LevelledItemTypeEach, "Select a new item each instance" }, { ColumnId_LevelledItemTypeEach, "Select a new item each instance" },
@ -278,9 +278,39 @@ namespace CSMWorld
{ ColumnId_InfoCondFunc, "Function" }, { ColumnId_InfoCondFunc, "Function" },
{ ColumnId_InfoCondVar, "Func/Variable" }, { ColumnId_InfoCondVar, "Func/Variable" },
{ ColumnId_InfoCondComp, "Comp" }, { ColumnId_InfoCondComp, "Comp" },
{ ColumnId_InfoCondValue, "Value" }, { ColumnId_InfoCondValue, "Values" },
{ ColumnId_OriginalCell, "Original Cell" }, { ColumnId_OriginalCell, "Original Cell" },
{ ColumnId_NpcAttributes, "Attributes" },
{ ColumnId_NpcSkills, "Skills" },
{ ColumnId_UChar, "Value [0..255]" },
{ ColumnId_NpcMisc, "Misc" },
{ ColumnId_NpcLevel, "Level" },
{ ColumnId_NpcFactionID, "Faction ID" },
{ ColumnId_NpcHealth, "Health" },
{ ColumnId_NpcMana, "Mana" },
{ ColumnId_NpcFatigue, "Fatigue" },
{ ColumnId_NpcDisposition, "Disposition" },
{ ColumnId_NpcReputation, "Reputation" },
{ ColumnId_NpcRank, "Rank" },
{ ColumnId_NpcGold, "Gold" },
{ ColumnId_NpcPersistence, "Persistent" },
{ ColumnId_RaceAttributes, "Attributes" },
{ ColumnId_RaceMaleValue, "Male" },
{ ColumnId_RaceFemaleValue, "Female" },
{ ColumnId_RaceSkillBonus, "Skill Bonus" },
{ ColumnId_RaceSkill, "Skills" },
{ ColumnId_RaceBonus, "Bonus" },
{ ColumnId_Interior, "Interior" },
{ ColumnId_Ambient, "Ambient" },
{ ColumnId_Sunlight, "Sunlight" },
{ ColumnId_Fog, "Fog" },
{ ColumnId_FogDensity, "Fog Density" },
{ ColumnId_WaterLevel, "Water Level" },
{ ColumnId_MapColor, "Map Color" },
{ ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue1, "Use value 1" },
{ ColumnId_UseValue2, "Use value 2" }, { ColumnId_UseValue2, "Use value 2" },
{ ColumnId_UseValue3, "Use value 3" }, { ColumnId_UseValue3, "Use value 3" },
@ -551,6 +581,7 @@ namespace
// FIXME: don't have dynamic value enum delegate, use Display_String for now // FIXME: don't have dynamic value enum delegate, use Display_String for now
//case CSMWorld::Columns::ColumnId_InfoCond: return sInfoCond; //case CSMWorld::Columns::ColumnId_InfoCond: return sInfoCond;
case CSMWorld::Columns::ColumnId_InfoCondComp: return sInfoCondComp; case CSMWorld::Columns::ColumnId_InfoCondComp: return sInfoCondComp;
case CSMWorld::Columns::ColumnId_RaceSkill: return sSkills;
default: return 0; default: return 0;
} }

View file

@ -272,6 +272,36 @@ namespace CSMWorld
ColumnId_OriginalCell = 247, ColumnId_OriginalCell = 247,
ColumnId_NpcAttributes = 248,
ColumnId_NpcSkills = 249,
ColumnId_UChar = 250,
ColumnId_NpcMisc = 251,
ColumnId_NpcLevel = 252,
ColumnId_NpcFactionID = 253,
ColumnId_NpcHealth = 254,
ColumnId_NpcMana = 255,
ColumnId_NpcFatigue = 256,
ColumnId_NpcDisposition = 257,
ColumnId_NpcReputation = 258,
ColumnId_NpcRank = 259,
ColumnId_NpcGold = 260,
ColumnId_NpcPersistence = 261,
ColumnId_RaceAttributes = 262,
ColumnId_RaceMaleValue = 263,
ColumnId_RaceFemaleValue = 264,
ColumnId_RaceSkillBonus = 265,
ColumnId_RaceSkill = 266,
ColumnId_RaceBonus = 267,
ColumnId_Interior = 268,
ColumnId_Ambient = 269,
ColumnId_Sunlight = 270,
ColumnId_Fog = 271,
ColumnId_FogDensity = 272,
ColumnId_WaterLevel = 273,
ColumnId_MapColor = 274,
// Allocated to a separate value range, so we don't get a collision should we ever need // Allocated to a separate value range, so we don't get a collision should we ever need
// to extend the number of use values. // to extend the number of use values.
ColumnId_UseValue1 = 0x10000, ColumnId_UseValue1 = 0x10000,

View file

@ -83,7 +83,7 @@ std::vector<std::string> CSMWorld::CommandDispatcher::getRevertableRecords() con
CSMWorld::CommandDispatcher::CommandDispatcher (CSMDoc::Document& document, CSMWorld::CommandDispatcher::CommandDispatcher (CSMDoc::Document& document,
const CSMWorld::UniversalId& id, QObject *parent) const CSMWorld::UniversalId& id, QObject *parent)
: QObject (parent), mDocument (document), mId (id), mLocked (false) : QObject (parent), mLocked (false), mDocument (document), mId (id)
{} {}
void CSMWorld::CommandDispatcher::setEditLock (bool locked) void CSMWorld::CommandDispatcher::setEditLock (bool locked)

View file

@ -14,7 +14,7 @@
CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelIndex& index, CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelIndex& index,
const QVariant& new_, QUndoCommand* parent) const QVariant& new_, QUndoCommand* parent)
: QUndoCommand (parent), mModel (&model), mIndex (index), mNew (new_) : QUndoCommand (parent), mModel (&model), mIndex (index), mNew (new_), mHasRecordState(false)
{ {
if (QAbstractProxyModel *proxy = dynamic_cast<QAbstractProxyModel *> (&model)) if (QAbstractProxyModel *proxy = dynamic_cast<QAbstractProxyModel *> (&model))
{ {
@ -27,6 +27,15 @@ CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelI
} }
else else
setText ("Modify " + mModel->headerData (mIndex.column(), Qt::Horizontal, Qt::DisplayRole).toString()); setText ("Modify " + mModel->headerData (mIndex.column(), Qt::Horizontal, Qt::DisplayRole).toString());
// Remember record state before the modification
if (CSMWorld::IdTable *table = dynamic_cast<IdTable *>(mModel))
{
mHasRecordState = true;
int stateColumnIndex = table->findColumnIndex(Columns::ColumnId_Modification);
mRecordStateIndex = table->index(mIndex.row(), stateColumnIndex);
mOldRecordState = static_cast<CSMWorld::RecordBase::State>(table->data(mRecordStateIndex).toInt());
}
} }
void CSMWorld::ModifyCommand::redo() void CSMWorld::ModifyCommand::redo()
@ -38,6 +47,10 @@ void CSMWorld::ModifyCommand::redo()
void CSMWorld::ModifyCommand::undo() void CSMWorld::ModifyCommand::undo()
{ {
mModel->setData (mIndex, mOld); mModel->setData (mIndex, mOld);
if (mHasRecordState)
{
mModel->setData(mRecordStateIndex, mOldRecordState);
}
} }
@ -235,12 +248,12 @@ CSMWorld::DeleteNestedCommand::DeleteNestedCommand (IdTree& model,
int nestedRow, int nestedRow,
int parentColumn, int parentColumn,
QUndoCommand* parent) : QUndoCommand* parent) :
mId(id),
mModel(model),
mParentColumn(parentColumn),
QUndoCommand(parent), QUndoCommand(parent),
mNestedRow(nestedRow), NestedTableStoring(model, id, parentColumn),
NestedTableStoring(model, id, parentColumn) mModel(model),
mId(id),
mParentColumn(parentColumn),
mNestedRow(nestedRow)
{ {
std::string title = std::string title =
model.headerData(parentColumn, Qt::Horizontal, Qt::DisplayRole).toString().toUtf8().constData(); model.headerData(parentColumn, Qt::Horizontal, Qt::DisplayRole).toString().toUtf8().constData();
@ -263,12 +276,12 @@ void CSMWorld::DeleteNestedCommand::undo()
} }
CSMWorld::AddNestedCommand::AddNestedCommand(IdTree& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent) CSMWorld::AddNestedCommand::AddNestedCommand(IdTree& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent)
: mModel(model), : QUndoCommand(parent),
NestedTableStoring(model, id, parentColumn),
mModel(model),
mId(id), mId(id),
mNewRow(nestedRow), mNewRow(nestedRow),
mParentColumn(parentColumn), mParentColumn(parentColumn)
QUndoCommand(parent),
NestedTableStoring(model, id, parentColumn)
{ {
std::string title = std::string title =
model.headerData(parentColumn, Qt::Horizontal, Qt::DisplayRole).toString().toUtf8().constData(); model.headerData(parentColumn, Qt::Horizontal, Qt::DisplayRole).toString().toUtf8().constData();

View file

@ -31,6 +31,10 @@ namespace CSMWorld
QVariant mNew; QVariant mNew;
QVariant mOld; QVariant mOld;
bool mHasRecordState;
QModelIndex mRecordStateIndex;
CSMWorld::RecordBase::State mOldRecordState;
public: public:
ModifyCommand (QAbstractItemModel& model, const QModelIndex& index, const QVariant& new_, ModifyCommand (QAbstractItemModel& model, const QModelIndex& index, const QVariant& new_,

View file

@ -136,6 +136,25 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
mRaces.addAdapter (std::make_pair(&mRaces.getColumn(index), new SpellListAdapter<ESM::Race> ())); mRaces.addAdapter (std::make_pair(&mRaces.getColumn(index), new SpellListAdapter<ESM::Race> ()));
mRaces.getNestableColumn(index)->addColumn( mRaces.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_SpellId, ColumnBase::Display_String)); new NestedChildColumn (Columns::ColumnId_SpellId, ColumnBase::Display_String));
// Race attributes
mRaces.addColumn (new NestedParentColumn<ESM::Race> (Columns::ColumnId_RaceAttributes));
index = mRaces.getColumns()-1;
mRaces.addAdapter (std::make_pair(&mRaces.getColumn(index), new RaceAttributeAdapter()));
mRaces.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_RaceAttributes, ColumnBase::Display_String,
ColumnBase::Flag_Dialogue, false));
mRaces.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_RaceMaleValue, ColumnBase::Display_Integer));
mRaces.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_RaceFemaleValue, ColumnBase::Display_Integer));
// Race skill bonus
mRaces.addColumn (new NestedParentColumn<ESM::Race> (Columns::ColumnId_RaceSkillBonus));
index = mRaces.getColumns()-1;
mRaces.addAdapter (std::make_pair(&mRaces.getColumn(index), new RaceSkillsBonusAdapter()));
mRaces.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_RaceSkill, ColumnBase::Display_RaceSkill));
mRaces.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_RaceBonus, ColumnBase::Display_Integer));
mSounds.addColumn (new StringIdColumn<ESM::Sound>); mSounds.addColumn (new StringIdColumn<ESM::Sound>);
mSounds.addColumn (new RecordStateColumn<ESM::Sound>); mSounds.addColumn (new RecordStateColumn<ESM::Sound>);
@ -269,10 +288,32 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
mCells.addColumn (new FixedRecordTypeColumn<Cell> (UniversalId::Type_Cell)); mCells.addColumn (new FixedRecordTypeColumn<Cell> (UniversalId::Type_Cell));
mCells.addColumn (new NameColumn<Cell>); mCells.addColumn (new NameColumn<Cell>);
mCells.addColumn (new FlagColumn<Cell> (Columns::ColumnId_SleepForbidden, ESM::Cell::NoSleep)); mCells.addColumn (new FlagColumn<Cell> (Columns::ColumnId_SleepForbidden, ESM::Cell::NoSleep));
mCells.addColumn (new FlagColumn<Cell> (Columns::ColumnId_InteriorWater, ESM::Cell::HasWater)); mCells.addColumn (new FlagColumn<Cell> (Columns::ColumnId_InteriorWater, ESM::Cell::HasWater,
mCells.addColumn (new FlagColumn<Cell> (Columns::ColumnId_InteriorSky, ESM::Cell::QuasiEx)); ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh));
mCells.addColumn (new FlagColumn<Cell> (Columns::ColumnId_InteriorSky, ESM::Cell::QuasiEx,
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh));
mCells.addColumn (new RegionColumn<Cell>); mCells.addColumn (new RegionColumn<Cell>);
mCells.addColumn (new RefNumCounterColumn<Cell>); mCells.addColumn (new RefNumCounterColumn<Cell>);
// Misc Cell data
mCells.addColumn (new NestedParentColumn<Cell> (Columns::ColumnId_Cell,
ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List));
index = mCells.getColumns()-1;
mCells.addAdapter (std::make_pair(&mCells.getColumn(index), new CellListAdapter ()));
mCells.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_Interior, ColumnBase::Display_Boolean,
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh));
mCells.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_Ambient, ColumnBase::Display_Integer));
mCells.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_Sunlight, ColumnBase::Display_Integer));
mCells.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_Fog, ColumnBase::Display_Integer));
mCells.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_FogDensity, ColumnBase::Display_Float));
mCells.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_WaterLevel, ColumnBase::Display_Float));
mCells.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_MapColor, ColumnBase::Display_Integer));
mEnchantments.addColumn (new StringIdColumn<ESM::Enchantment>); mEnchantments.addColumn (new StringIdColumn<ESM::Enchantment>);
mEnchantments.addColumn (new RecordStateColumn<ESM::Enchantment>); mEnchantments.addColumn (new RecordStateColumn<ESM::Enchantment>);
@ -309,7 +350,8 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
mBodyParts.addColumn (new BodyPartTypeColumn<ESM::BodyPart>); mBodyParts.addColumn (new BodyPartTypeColumn<ESM::BodyPart>);
mBodyParts.addColumn (new VampireColumn<ESM::BodyPart>); mBodyParts.addColumn (new VampireColumn<ESM::BodyPart>);
mBodyParts.addColumn (new FlagColumn<ESM::BodyPart> (Columns::ColumnId_Female, ESM::BodyPart::BPF_Female)); mBodyParts.addColumn (new FlagColumn<ESM::BodyPart> (Columns::ColumnId_Female, ESM::BodyPart::BPF_Female));
mBodyParts.addColumn (new FlagColumn<ESM::BodyPart> (Columns::ColumnId_Playable, ESM::BodyPart::BPF_NotPlayable, true)); mBodyParts.addColumn (new FlagColumn<ESM::BodyPart> (Columns::ColumnId_Playable,
ESM::BodyPart::BPF_NotPlayable, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, true));
mBodyParts.addColumn (new MeshTypeColumn<ESM::BodyPart>); mBodyParts.addColumn (new MeshTypeColumn<ESM::BodyPart>);
mBodyParts.addColumn (new ModelColumn<ESM::BodyPart>); mBodyParts.addColumn (new ModelColumn<ESM::BodyPart>);
mBodyParts.addColumn (new RaceColumn<ESM::BodyPart>); mBodyParts.addColumn (new RaceColumn<ESM::BodyPart>);
@ -356,7 +398,8 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
// new objects deleted in dtor of NestableColumn // new objects deleted in dtor of NestableColumn
// WARNING: The order of the columns below are assumed in PathgridPointListAdapter // WARNING: The order of the columns below are assumed in PathgridPointListAdapter
mPathgrids.getNestableColumn(index)->addColumn( mPathgrids.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_PathgridIndex, ColumnBase::Display_Integer, false)); new NestedChildColumn (Columns::ColumnId_PathgridIndex, ColumnBase::Display_Integer,
ColumnBase::Flag_Dialogue, false));
mPathgrids.getNestableColumn(index)->addColumn( mPathgrids.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_PathgridPosX, ColumnBase::Display_Integer)); new NestedChildColumn (Columns::ColumnId_PathgridPosX, ColumnBase::Display_Integer));
mPathgrids.getNestableColumn(index)->addColumn( mPathgrids.getNestableColumn(index)->addColumn(
@ -368,7 +411,8 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
index = mPathgrids.getColumns()-1; index = mPathgrids.getColumns()-1;
mPathgrids.addAdapter (std::make_pair(&mPathgrids.getColumn(index), new PathgridEdgeListAdapter ())); mPathgrids.addAdapter (std::make_pair(&mPathgrids.getColumn(index), new PathgridEdgeListAdapter ()));
mPathgrids.getNestableColumn(index)->addColumn( mPathgrids.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_PathgridEdgeIndex, ColumnBase::Display_Integer, false)); new NestedChildColumn (Columns::ColumnId_PathgridEdgeIndex, ColumnBase::Display_Integer,
ColumnBase::Flag_Dialogue, false));
mPathgrids.getNestableColumn(index)->addColumn( mPathgrids.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_PathgridEdge0, ColumnBase::Display_Integer)); new NestedChildColumn (Columns::ColumnId_PathgridEdge0, ColumnBase::Display_Integer));
mPathgrids.getNestableColumn(index)->addColumn( mPathgrids.getNestableColumn(index)->addColumn(
@ -447,7 +491,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
addModel (new IdTree (&mTopicInfos, &mTopicInfos, IdTable::Feature_ReorderWithinTopic), addModel (new IdTree (&mTopicInfos, &mTopicInfos, IdTable::Feature_ReorderWithinTopic),
UniversalId::Type_TopicInfo); UniversalId::Type_TopicInfo);
addModel (new IdTable (&mJournalInfos, IdTable::Feature_ReorderWithinTopic), UniversalId::Type_JournalInfo); addModel (new IdTable (&mJournalInfos, IdTable::Feature_ReorderWithinTopic), UniversalId::Type_JournalInfo);
addModel (new IdTable (&mCells, IdTable::Feature_ViewId), UniversalId::Type_Cell); addModel (new IdTree (&mCells, &mCells, IdTable::Feature_ViewId), UniversalId::Type_Cell);
addModel (new IdTree (&mEnchantments, &mEnchantments), UniversalId::Type_Enchantment); addModel (new IdTree (&mEnchantments, &mEnchantments), UniversalId::Type_Enchantment);
addModel (new IdTable (&mBodyParts), UniversalId::Type_BodyPart); addModel (new IdTable (&mBodyParts), UniversalId::Type_BodyPart);
addModel (new IdTable (&mSoundGens), UniversalId::Type_SoundGen); addModel (new IdTable (&mSoundGens), UniversalId::Type_SoundGen);

View file

@ -88,7 +88,7 @@ namespace CSMWorld
IdCollection<ESM::StartScript> mStartScripts; IdCollection<ESM::StartScript> mStartScripts;
NestedInfoCollection mTopicInfos; NestedInfoCollection mTopicInfos;
InfoCollection mJournalInfos; InfoCollection mJournalInfos;
IdCollection<Cell> mCells; NestedIdCollection<Cell> mCells;
IdCollection<LandTexture> mLandTextures; IdCollection<LandTexture> mLandTextures;
IdCollection<Land> mLand; IdCollection<Land> mLand;
RefIdCollection mReferenceables; RefIdCollection mReferenceables;

View file

@ -74,8 +74,7 @@ bool CSMWorld::IdTable::setData (const QModelIndex &index, const QVariant &value
{ {
mIdCollection->setData (index.row(), index.column(), value); mIdCollection->setData (index.row(), index.column(), value);
emit dataChanged (CSMWorld::IdTable::index (index.row(), 0), emit dataChanged (index, index);
CSMWorld::IdTable::index (index.row(), mIdCollection->getColumns()-1));
return true; return true;
} }
@ -160,7 +159,7 @@ void CSMWorld::IdTable::setRecord (const std::string& id, const RecordBase& reco
if (index==-1) if (index==-1)
{ {
int index = mIdCollection->getAppendIndex (id); int index = mIdCollection->getAppendIndex (id, type);
beginInsertRows (QModelIndex(), index, index); beginInsertRows (QModelIndex(), index, index);

View file

@ -46,10 +46,16 @@ void CSMWorld::IdTableProxyModel::setFilter (const boost::shared_ptr<CSMFilter::
{ {
mFilter = filter; mFilter = filter;
updateColumnMap(); updateColumnMap();
invalidateFilter(); reset();
} }
bool CSMWorld::IdTableProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const bool CSMWorld::IdTableProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
{ {
return QSortFilterProxyModel::lessThan(left, right); return QSortFilterProxyModel::lessThan(left, right);
} }
void CSMWorld::IdTableProxyModel::refreshFilter()
{
updateColumnMap();
invalidateFilter();
}

View file

@ -34,6 +34,8 @@ namespace CSMWorld
void setFilter (const boost::shared_ptr<CSMFilter::Node>& filter); void setFilter (const boost::shared_ptr<CSMFilter::Node>& filter);
void refreshFilter();
protected: protected:
bool lessThan(const QModelIndex &left, const QModelIndex &right) const; bool lessThan(const QModelIndex &left, const QModelIndex &right) const;

View file

@ -74,7 +74,7 @@ QVariant CSMWorld::IdTree::nestedHeaderData(int section, int subSection, Qt::Ori
return tr(parentColumn->nestedColumn(subSection).getTitle().c_str()); return tr(parentColumn->nestedColumn(subSection).getTitle().c_str());
if (role==ColumnBase::Role_Flags) if (role==ColumnBase::Role_Flags)
return idCollection()->getColumn (section).mFlags; return parentColumn->nestedColumn(subSection).mFlags;
if (role==ColumnBase::Role_Display) if (role==ColumnBase::Role_Display)
return parentColumn->nestedColumn(subSection).mDisplayType; return parentColumn->nestedColumn(subSection).mDisplayType;
@ -92,8 +92,8 @@ bool CSMWorld::IdTree::setData (const QModelIndex &index, const QVariant &value,
mNestedCollection->setNestedData(parentAddress.first, parentAddress.second, value, index.row(), index.column()); mNestedCollection->setNestedData(parentAddress.first, parentAddress.second, value, index.row(), index.column());
emit dataChanged (CSMWorld::IdTree::index (parentAddress.first, 0), emit dataChanged (index, index);
CSMWorld::IdTree::index (parentAddress.first, idCollection()->getColumns()-1));
return true; return true;
} }
else else

View file

@ -173,6 +173,17 @@ CSMWorld::InfoCollection::Range CSMWorld::InfoCollection::getTopicRange (const s
RecordConstIterator begin = getRecords().begin()+iter->second; RecordConstIterator begin = getRecords().begin()+iter->second;
while (begin != getRecords().begin())
{
if (!Misc::StringUtils::ciEqual(begin->get().mTopicId, topic2))
{
// we've gone one too far, go back
++begin;
break;
}
--begin;
}
// Find end // Find end
RecordConstIterator end = begin; RecordConstIterator end = begin;

View file

@ -481,7 +481,7 @@ namespace CSMWorld
void InfoListAdapter::removeRow(Record<Info>& record, int rowToRemove) const void InfoListAdapter::removeRow(Record<Info>& record, int rowToRemove) const
{ {
throw std::logic_error ("cannot add a row to a fixed table"); throw std::logic_error ("cannot remove a row to a fixed table");
} }
void InfoListAdapter::setTable(Record<Info>& record, void InfoListAdapter::setTable(Record<Info>& record,
@ -880,4 +880,315 @@ namespace CSMWorld
{ {
return static_cast<int>(record.get().mSelects.size()); return static_cast<int>(record.get().mSelects.size());
} }
RaceAttributeAdapter::RaceAttributeAdapter () {}
void RaceAttributeAdapter::addRow(Record<ESM::Race>& record, int position) const
{
// Do nothing, this table cannot be changed by the user
}
void RaceAttributeAdapter::removeRow(Record<ESM::Race>& record, int rowToRemove) const
{
// Do nothing, this table cannot be changed by the user
}
void RaceAttributeAdapter::setTable(Record<ESM::Race>& record,
const NestedTableWrapperBase& nestedTable) const
{
ESM::Race race = record.get();
race.mData =
static_cast<const NestedTableWrapper<std::vector<ESM::Race::RADTstruct> >&>(nestedTable).mNestedTable.at(0);
record.setModified (race);
}
NestedTableWrapperBase* RaceAttributeAdapter::table(const Record<ESM::Race>& record) const
{
std::vector<typename ESM::Race::RADTstruct> wrap;
wrap.push_back(record.get().mData);
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<std::vector<ESM::Race::RADTstruct> >(wrap);
}
QVariant RaceAttributeAdapter::getData(const Record<ESM::Race>& record,
int subRowIndex, int subColIndex) const
{
ESM::Race race = record.get();
if (subRowIndex < 0 || subRowIndex >= ESM::Attribute::Length)
throw std::runtime_error ("index out of range");
switch (subColIndex)
{
case 0: return QString(ESM::Attribute::sAttributeNames[subRowIndex].c_str());
case 1: return race.mData.mAttributeValues[subRowIndex].mMale;
case 2: return race.mData.mAttributeValues[subRowIndex].mFemale;
default: throw std::runtime_error("Race Attribute subcolumn index out of range");
}
}
void RaceAttributeAdapter::setData(Record<ESM::Race>& record,
const QVariant& value, int subRowIndex, int subColIndex) const
{
ESM::Race race = record.get();
if (subRowIndex < 0 || subRowIndex >= ESM::Attribute::Length)
throw std::runtime_error ("index out of range");
switch (subColIndex)
{
case 0: return; // throw an exception here?
case 1: race.mData.mAttributeValues[subRowIndex].mMale = value.toInt(); break;
case 2: race.mData.mAttributeValues[subRowIndex].mFemale = value.toInt(); break;
default: throw std::runtime_error("Race Attribute subcolumn index out of range");
}
record.setModified (race);
}
int RaceAttributeAdapter::getColumnsCount(const Record<ESM::Race>& record) const
{
return 3; // attrib, male, female
}
int RaceAttributeAdapter::getRowsCount(const Record<ESM::Race>& record) const
{
return ESM::Attribute::Length; // there are 8 attributes
}
RaceSkillsBonusAdapter::RaceSkillsBonusAdapter () {}
void RaceSkillsBonusAdapter::addRow(Record<ESM::Race>& record, int position) const
{
// Do nothing, this table cannot be changed by the user
}
void RaceSkillsBonusAdapter::removeRow(Record<ESM::Race>& record, int rowToRemove) const
{
// Do nothing, this table cannot be changed by the user
}
void RaceSkillsBonusAdapter::setTable(Record<ESM::Race>& record,
const NestedTableWrapperBase& nestedTable) const
{
ESM::Race race = record.get();
race.mData =
static_cast<const NestedTableWrapper<std::vector<ESM::Race::RADTstruct> >&>(nestedTable).mNestedTable.at(0);
record.setModified (race);
}
NestedTableWrapperBase* RaceSkillsBonusAdapter::table(const Record<ESM::Race>& record) const
{
std::vector<typename ESM::Race::RADTstruct> wrap;
wrap.push_back(record.get().mData);
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<std::vector<ESM::Race::RADTstruct> >(wrap);
}
QVariant RaceSkillsBonusAdapter::getData(const Record<ESM::Race>& record,
int subRowIndex, int subColIndex) const
{
ESM::Race race = record.get();
if (subRowIndex < 0 || subRowIndex >= static_cast<int>(sizeof(race.mData.mBonus)/sizeof(race.mData.mBonus[0])))
throw std::runtime_error ("index out of range");
switch (subColIndex)
{
case 0: return race.mData.mBonus[subRowIndex].mSkill; // can be -1
case 1: return race.mData.mBonus[subRowIndex].mBonus;
default: throw std::runtime_error("Race skill bonus subcolumn index out of range");
}
}
void RaceSkillsBonusAdapter::setData(Record<ESM::Race>& record,
const QVariant& value, int subRowIndex, int subColIndex) const
{
ESM::Race race = record.get();
if (subRowIndex < 0 || subRowIndex >= static_cast<int>(sizeof(race.mData.mBonus)/sizeof(race.mData.mBonus[0])))
throw std::runtime_error ("index out of range");
switch (subColIndex)
{
case 0: race.mData.mBonus[subRowIndex].mSkill = value.toInt(); break; // can be -1
case 1: race.mData.mBonus[subRowIndex].mBonus = value.toInt(); break;
default: throw std::runtime_error("Race skill bonus subcolumn index out of range");
}
record.setModified (race);
}
int RaceSkillsBonusAdapter::getColumnsCount(const Record<ESM::Race>& record) const
{
return 2; // skill, bonus
}
int RaceSkillsBonusAdapter::getRowsCount(const Record<ESM::Race>& record) const
{
// there are 7 skill bonuses
return static_cast<int>(sizeof(record.get().mData.mBonus)/sizeof(record.get().mData.mBonus[0]));
}
CellListAdapter::CellListAdapter () {}
void CellListAdapter::addRow(Record<CSMWorld::Cell>& record, int position) const
{
throw std::logic_error ("cannot add a row to a fixed table");
}
void CellListAdapter::removeRow(Record<CSMWorld::Cell>& record, int rowToRemove) const
{
throw std::logic_error ("cannot remove a row to a fixed table");
}
void CellListAdapter::setTable(Record<CSMWorld::Cell>& record,
const NestedTableWrapperBase& nestedTable) const
{
throw std::logic_error ("table operation not supported");
}
NestedTableWrapperBase* CellListAdapter::table(const Record<CSMWorld::Cell>& record) const
{
throw std::logic_error ("table operation not supported");
}
QVariant CellListAdapter::getData(const Record<CSMWorld::Cell>& record,
int subRowIndex, int subColIndex) const
{
CSMWorld::Cell cell = record.get();
bool isInterior = (cell.mData.mFlags & ESM::Cell::Interior) != 0;
bool behaveLikeExterior = (cell.mData.mFlags & ESM::Cell::QuasiEx) != 0;
bool interiorWater = (cell.mData.mFlags & ESM::Cell::HasWater) != 0;
switch (subColIndex)
{
case 0: return isInterior;
case 1: return (isInterior && !behaveLikeExterior) ?
cell.mAmbi.mAmbient : QVariant(QVariant::UserType);
case 2: return (isInterior && !behaveLikeExterior) ?
cell.mAmbi.mSunlight : QVariant(QVariant::UserType);
case 3: return (isInterior && !behaveLikeExterior) ?
cell.mAmbi.mFog : QVariant(QVariant::UserType);
case 4: return (isInterior && !behaveLikeExterior) ?
cell.mAmbi.mFogDensity : QVariant(QVariant::UserType);
case 5:
{
if (isInterior && !behaveLikeExterior && interiorWater)
return cell.mWater;
else
return QVariant(QVariant::UserType);
}
case 6: return isInterior ?
QVariant(QVariant::UserType) : cell.mMapColor; // TODO: how to select?
//case 7: return isInterior ?
//behaveLikeExterior : QVariant(QVariant::UserType);
default: throw std::runtime_error("Cell subcolumn index out of range");
}
}
void CellListAdapter::setData(Record<CSMWorld::Cell>& record,
const QVariant& value, int subRowIndex, int subColIndex) const
{
CSMWorld::Cell cell = record.get();
bool isInterior = (cell.mData.mFlags & ESM::Cell::Interior) != 0;
bool behaveLikeExterior = (cell.mData.mFlags & ESM::Cell::QuasiEx) != 0;
bool interiorWater = (cell.mData.mFlags & ESM::Cell::HasWater) != 0;
switch (subColIndex)
{
case 0:
{
if (value.toBool())
cell.mData.mFlags |= ESM::Cell::Interior;
else
cell.mData.mFlags &= ~ESM::Cell::Interior;
break;
}
case 1:
{
if (isInterior && !behaveLikeExterior)
cell.mAmbi.mAmbient = static_cast<int32_t>(value.toInt());
else
return; // return without saving
break;
}
case 2:
{
if (isInterior && !behaveLikeExterior)
cell.mAmbi.mSunlight = static_cast<int32_t>(value.toInt());
else
return; // return without saving
break;
}
case 3:
{
if (isInterior && !behaveLikeExterior)
cell.mAmbi.mFog = static_cast<int32_t>(value.toInt());
else
return; // return without saving
break;
}
case 4:
{
if (isInterior && !behaveLikeExterior)
cell.mAmbi.mFogDensity = value.toFloat();
else
return; // return without saving
break;
}
case 5:
{
if (isInterior && !behaveLikeExterior && interiorWater)
cell.mWater = value.toFloat();
else
return; // return without saving
break;
}
case 6:
{
if (!isInterior)
cell.mMapColor = value.toInt();
else
return; // return without saving
break;
}
#if 0
// redundant since this flag is shown in the main table as "Interior Sky"
// keep here for documenting the logic based on vanilla
case 7:
{
if (isInterior)
{
if (value.toBool())
cell.mData.mFlags |= ESM::Cell::QuasiEx;
else
cell.mData.mFlags &= ~ESM::Cell::QuasiEx;
}
else
return; // return without saving
break;
}
#endif
default: throw std::runtime_error("Cell subcolumn index out of range");
}
record.setModified (cell);
}
int CellListAdapter::getColumnsCount(const Record<CSMWorld::Cell>& record) const
{
return 7;
}
int CellListAdapter::getRowsCount(const Record<CSMWorld::Cell>& record) const
{
return 1; // fixed at size 1
}
} }

View file

@ -8,9 +8,11 @@
#include <components/esm/loadmgef.hpp> // for converting magic effect id to string & back #include <components/esm/loadmgef.hpp> // for converting magic effect id to string & back
#include <components/esm/loadskil.hpp> // for converting skill names #include <components/esm/loadskil.hpp> // for converting skill names
#include <components/esm/attr.hpp> // for converting attributes #include <components/esm/attr.hpp> // for converting attributes
#include <components/esm/loadrace.hpp>
#include "nestedcolumnadapter.hpp" #include "nestedcolumnadapter.hpp"
#include "nestedtablewrapper.hpp" #include "nestedtablewrapper.hpp"
#include "cell.hpp"
namespace ESM namespace ESM
{ {
@ -437,6 +439,81 @@ namespace CSMWorld
virtual int getRowsCount(const Record<Info>& record) const; virtual int getRowsCount(const Record<Info>& record) const;
}; };
class RaceAttributeAdapter : public NestedColumnAdapter<ESM::Race>
{
public:
RaceAttributeAdapter ();
virtual void addRow(Record<ESM::Race>& record, int position) const;
virtual void removeRow(Record<ESM::Race>& record, int rowToRemove) const;
virtual void setTable(Record<ESM::Race>& record,
const NestedTableWrapperBase& nestedTable) const;
virtual NestedTableWrapperBase* table(const Record<ESM::Race>& record) const;
virtual QVariant getData(const Record<ESM::Race>& record,
int subRowIndex, int subColIndex) const;
virtual void setData(Record<ESM::Race>& record,
const QVariant& value, int subRowIndex, int subColIndex) const;
virtual int getColumnsCount(const Record<ESM::Race>& record) const;
virtual int getRowsCount(const Record<ESM::Race>& record) const;
};
class RaceSkillsBonusAdapter : public NestedColumnAdapter<ESM::Race>
{
public:
RaceSkillsBonusAdapter ();
virtual void addRow(Record<ESM::Race>& record, int position) const;
virtual void removeRow(Record<ESM::Race>& record, int rowToRemove) const;
virtual void setTable(Record<ESM::Race>& record,
const NestedTableWrapperBase& nestedTable) const;
virtual NestedTableWrapperBase* table(const Record<ESM::Race>& record) const;
virtual QVariant getData(const Record<ESM::Race>& record,
int subRowIndex, int subColIndex) const;
virtual void setData(Record<ESM::Race>& record,
const QVariant& value, int subRowIndex, int subColIndex) const;
virtual int getColumnsCount(const Record<ESM::Race>& record) const;
virtual int getRowsCount(const Record<ESM::Race>& record) const;
};
class CellListAdapter : public NestedColumnAdapter<CSMWorld::Cell>
{
public:
CellListAdapter ();
virtual void addRow(Record<CSMWorld::Cell>& record, int position) const;
virtual void removeRow(Record<CSMWorld::Cell>& record, int rowToRemove) const;
virtual void setTable(Record<CSMWorld::Cell>& record,
const NestedTableWrapperBase& nestedTable) const;
virtual NestedTableWrapperBase* table(const Record<CSMWorld::Cell>& record) const;
virtual QVariant getData(const Record<CSMWorld::Cell>& record,
int subRowIndex, int subColIndex) const;
virtual void setData(Record<CSMWorld::Cell>& record,
const QVariant& value, int subRowIndex, int subColIndex) const;
virtual int getColumnsCount(const Record<CSMWorld::Cell>& record) const;
virtual int getRowsCount(const Record<CSMWorld::Cell>& record) const;
};
} }
#endif // CSM_WOLRD_NESTEDCOLADAPTERIMP_H #endif // CSM_WOLRD_NESTEDCOLADAPTERIMP_H

View file

@ -13,7 +13,7 @@ CSMWorld::PotionColumns::PotionColumns (const InventoryColumns& columns)
CSMWorld::PotionRefIdAdapter::PotionRefIdAdapter (const PotionColumns& columns, CSMWorld::PotionRefIdAdapter::PotionRefIdAdapter (const PotionColumns& columns,
const RefIdColumn *autoCalc) const RefIdColumn *autoCalc)
: InventoryRefIdAdapter<ESM::Potion> (UniversalId::Type_Potion, columns), : InventoryRefIdAdapter<ESM::Potion> (UniversalId::Type_Potion, columns),
mAutoCalc (autoCalc), mColumns(columns) mColumns(columns), mAutoCalc (autoCalc)
{} {}
QVariant CSMWorld::PotionRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, QVariant CSMWorld::PotionRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data,
@ -468,7 +468,10 @@ CSMWorld::NpcColumns::NpcColumns (const ActorColumns& actorColumns)
mClass(NULL), mClass(NULL),
mFaction(NULL), mFaction(NULL),
mHair(NULL), mHair(NULL),
mHead(NULL) mHead(NULL),
mAttributes(NULL),
mSkills(NULL),
mMisc(NULL)
{} {}
CSMWorld::NpcRefIdAdapter::NpcRefIdAdapter (const NpcColumns& columns) CSMWorld::NpcRefIdAdapter::NpcRefIdAdapter (const NpcColumns& columns)
@ -496,6 +499,17 @@ QVariant CSMWorld::NpcRefIdAdapter::getData (const RefIdColumn *column, const Re
if (column==mColumns.mHead) if (column==mColumns.mHead)
return QString::fromUtf8 (record.get().mHead.c_str()); return QString::fromUtf8 (record.get().mHead.c_str());
if (column==mColumns.mAttributes || column==mColumns.mSkills)
{
if ((record.get().mFlags & ESM::NPC::Autocalc) != 0)
return QVariant(QVariant::UserType);
else
return true;
}
if (column==mColumns.mMisc)
return true;
std::map<const RefIdColumn *, unsigned int>::const_iterator iter = std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
mColumns.mFlags.find (column); mColumns.mFlags.find (column);
@ -538,6 +552,338 @@ void CSMWorld::NpcRefIdAdapter::setData (const RefIdColumn *column, RefIdData& d
} }
} }
CSMWorld::NpcAttributesRefIdAdapter::NpcAttributesRefIdAdapter ()
{}
void CSMWorld::NpcAttributesRefIdAdapter::addNestedRow (const RefIdColumn *column,
RefIdData& data, int index, int position) const
{
// Do nothing, this table cannot be changed by the user
}
void CSMWorld::NpcAttributesRefIdAdapter::removeNestedRow (const RefIdColumn *column,
RefIdData& data, int index, int rowToRemove) const
{
// Do nothing, this table cannot be changed by the user
}
void CSMWorld::NpcAttributesRefIdAdapter::setNestedTable (const RefIdColumn* column,
RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const
{
Record<ESM::NPC>& record =
static_cast<Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc)));
ESM::NPC npc = record.get();
// store the whole struct
npc.mNpdt52 =
static_cast<const NestedTableWrapper<std::vector<typename ESM::NPC::NPDTstruct52> > &>(nestedTable).mNestedTable.at(0);
record.setModified (npc);
}
CSMWorld::NestedTableWrapperBase* CSMWorld::NpcAttributesRefIdAdapter::nestedTable (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)));
// return the whole struct
std::vector<typename ESM::NPC::NPDTstruct52> wrap;
wrap.push_back(record.get().mNpdt52);
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<std::vector<typename ESM::NPC::NPDTstruct52> >(wrap);
}
QVariant CSMWorld::NpcAttributesRefIdAdapter::getNestedData (const RefIdColumn *column,
const RefIdData& data, int index, int subRowIndex, int subColIndex) const
{
const Record<ESM::NPC>& record =
static_cast<const Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc)));
const ESM::NPC::NPDTstruct52& npcStruct = record.get().mNpdt52;
if (subColIndex == 0)
switch (subRowIndex)
{
case 0: return QString("Strength");
case 1: return QString("Intelligence");
case 2: return QString("Willpower");
case 3: return QString("Agility");
case 4: return QString("Speed");
case 5: return QString("Endurance");
case 6: return QString("Personality");
case 7: return QString("Luck");
default: return QVariant(); // throw an exception here?
}
else if (subColIndex == 1)
switch (subRowIndex)
{
case 0: return static_cast<int>(npcStruct.mStrength);
case 1: return static_cast<int>(npcStruct.mIntelligence);
case 2: return static_cast<int>(npcStruct.mWillpower);
case 3: return static_cast<int>(npcStruct.mAgility);
case 4: return static_cast<int>(npcStruct.mSpeed);
case 5: return static_cast<int>(npcStruct.mEndurance);
case 6: return static_cast<int>(npcStruct.mPersonality);
case 7: return static_cast<int>(npcStruct.mLuck);
default: return QVariant(); // throw an exception here?
}
else
return QVariant(); // throw an exception here?
}
void CSMWorld::NpcAttributesRefIdAdapter::setNestedData (const RefIdColumn *column,
RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const
{
Record<ESM::NPC>& record =
static_cast<Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (row, UniversalId::Type_Npc)));
ESM::NPC npc = record.get();
ESM::NPC::NPDTstruct52& npcStruct = npc.mNpdt52;
if (subColIndex == 1)
switch(subRowIndex)
{
case 0: npcStruct.mStrength = static_cast<unsigned char>(value.toInt()); break;
case 1: npcStruct.mIntelligence = static_cast<unsigned char>(value.toInt()); break;
case 2: npcStruct.mWillpower = static_cast<unsigned char>(value.toInt()); break;
case 3: npcStruct.mAgility = static_cast<unsigned char>(value.toInt()); break;
case 4: npcStruct.mSpeed = static_cast<unsigned char>(value.toInt()); break;
case 5: npcStruct.mEndurance = static_cast<unsigned char>(value.toInt()); break;
case 6: npcStruct.mPersonality = static_cast<unsigned char>(value.toInt()); break;
case 7: npcStruct.mLuck = static_cast<unsigned char>(value.toInt()); break;
default: return; // throw an exception here?
}
else
return; // throw an exception here?
record.setModified (npc);
}
int CSMWorld::NpcAttributesRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const
{
return 2;
}
int CSMWorld::NpcAttributesRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const
{
// There are 8 attributes
return 8;
}
CSMWorld::NpcSkillsRefIdAdapter::NpcSkillsRefIdAdapter ()
{}
void CSMWorld::NpcSkillsRefIdAdapter::addNestedRow (const RefIdColumn *column,
RefIdData& data, int index, int position) const
{
// Do nothing, this table cannot be changed by the user
}
void CSMWorld::NpcSkillsRefIdAdapter::removeNestedRow (const RefIdColumn *column,
RefIdData& data, int index, int rowToRemove) const
{
// Do nothing, this table cannot be changed by the user
}
void CSMWorld::NpcSkillsRefIdAdapter::setNestedTable (const RefIdColumn* column,
RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const
{
Record<ESM::NPC>& record =
static_cast<Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc)));
ESM::NPC npc = record.get();
// store the whole struct
npc.mNpdt52 =
static_cast<const NestedTableWrapper<std::vector<typename ESM::NPC::NPDTstruct52> > &>(nestedTable).mNestedTable.at(0);
record.setModified (npc);
}
CSMWorld::NestedTableWrapperBase* CSMWorld::NpcSkillsRefIdAdapter::nestedTable (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)));
// return the whole struct
std::vector<typename ESM::NPC::NPDTstruct52> wrap;
wrap.push_back(record.get().mNpdt52);
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<std::vector<typename ESM::NPC::NPDTstruct52> >(wrap);
}
QVariant CSMWorld::NpcSkillsRefIdAdapter::getNestedData (const RefIdColumn *column,
const RefIdData& data, int index, int subRowIndex, int subColIndex) const
{
const Record<ESM::NPC>& record =
static_cast<const Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc)));
const ESM::NPC::NPDTstruct52& npcStruct = record.get().mNpdt52;
if (subRowIndex < 0 || subRowIndex >= ESM::Skill::Length)
throw std::runtime_error ("index out of range");
if (subColIndex == 0)
return QString(ESM::Skill::sSkillNames[subRowIndex].c_str());
else if (subColIndex == 1)
return static_cast<int>(npcStruct.mSkills[subRowIndex]);
else
return QVariant(); // throw an exception here?
}
void CSMWorld::NpcSkillsRefIdAdapter::setNestedData (const RefIdColumn *column,
RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const
{
Record<ESM::NPC>& record =
static_cast<Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (row, UniversalId::Type_Npc)));
ESM::NPC npc = record.get();
ESM::NPC::NPDTstruct52& npcStruct = npc.mNpdt52;
if (subRowIndex < 0 || subRowIndex >= ESM::Skill::Length)
throw std::runtime_error ("index out of range");
if (subColIndex == 1)
npcStruct.mSkills[subRowIndex] = static_cast<unsigned char>(value.toInt());
else
return; // throw an exception here?
record.setModified (npc);
}
int CSMWorld::NpcSkillsRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const
{
return 2;
}
int CSMWorld::NpcSkillsRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const
{
// There are 27 skills
return ESM::Skill::Length;
}
CSMWorld::NpcMiscRefIdAdapter::NpcMiscRefIdAdapter ()
{}
CSMWorld::NpcMiscRefIdAdapter::~NpcMiscRefIdAdapter()
{}
void CSMWorld::NpcMiscRefIdAdapter::addNestedRow (const RefIdColumn *column,
RefIdData& data, int index, int position) const
{
throw std::logic_error ("cannot add a row to a fixed table");
}
void CSMWorld::NpcMiscRefIdAdapter::removeNestedRow (const RefIdColumn *column,
RefIdData& data, int index, int rowToRemove) const
{
throw std::logic_error ("cannot remove a row to a fixed table");
}
void CSMWorld::NpcMiscRefIdAdapter::setNestedTable (const RefIdColumn* column,
RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const
{
throw std::logic_error ("table operation not supported");
}
CSMWorld::NestedTableWrapperBase* CSMWorld::NpcMiscRefIdAdapter::nestedTable (const RefIdColumn* column,
const RefIdData& data, int index) const
{
throw std::logic_error ("table operation not supported");
}
QVariant CSMWorld::NpcMiscRefIdAdapter::getNestedData (const RefIdColumn *column,
const RefIdData& data, int index, int subRowIndex, int subColIndex) const
{
const Record<ESM::NPC>& record =
static_cast<const Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc)));
bool autoCalc = (record.get().mFlags & ESM::NPC::Autocalc) != 0;
if (autoCalc)
switch (subColIndex)
{
case 0: return static_cast<int>(record.get().mNpdt12.mLevel);
case 1: return QVariant(QVariant::UserType);
case 2: return QVariant(QVariant::UserType);
case 3: return QVariant(QVariant::UserType);
case 4: return QVariant(QVariant::UserType);
case 5: return static_cast<int>(record.get().mNpdt12.mDisposition);
case 6: return static_cast<int>(record.get().mNpdt12.mReputation);
case 7: return static_cast<int>(record.get().mNpdt12.mRank);
case 8: return record.get().mNpdt12.mGold;
case 9: return record.get().mPersistent == true;
default: return QVariant(); // throw an exception here?
}
else
switch (subColIndex)
{
case 0: return static_cast<int>(record.get().mNpdt52.mLevel);
case 1: return static_cast<int>(record.get().mNpdt52.mFactionID);
case 2: return static_cast<int>(record.get().mNpdt52.mHealth);
case 3: return static_cast<int>(record.get().mNpdt52.mMana);
case 4: return static_cast<int>(record.get().mNpdt52.mFatigue);
case 5: return static_cast<int>(record.get().mNpdt52.mDisposition);
case 6: return static_cast<int>(record.get().mNpdt52.mReputation);
case 7: return static_cast<int>(record.get().mNpdt52.mRank);
case 8: return record.get().mNpdt52.mGold;
case 9: return record.get().mPersistent == true;
default: return QVariant(); // throw an exception here?
}
}
void CSMWorld::NpcMiscRefIdAdapter::setNestedData (const RefIdColumn *column,
RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const
{
Record<ESM::NPC>& record =
static_cast<Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (row, UniversalId::Type_Npc)));
ESM::NPC npc = record.get();
bool autoCalc = (record.get().mFlags & ESM::NPC::Autocalc) != 0;
if (autoCalc)
switch(subColIndex)
{
case 0: npc.mNpdt12.mLevel = static_cast<short>(value.toInt()); break;
case 1: return;
case 2: return;
case 3: return;
case 4: return;
case 5: npc.mNpdt12.mDisposition = static_cast<signed char>(value.toInt()); break;
case 6: npc.mNpdt12.mReputation = static_cast<signed char>(value.toInt()); break;
case 7: npc.mNpdt12.mRank = static_cast<signed char>(value.toInt()); break;
case 8: npc.mNpdt12.mGold = value.toInt(); break;
case 9: npc.mPersistent = value.toBool(); break;
default: return; // throw an exception here?
}
else
switch(subColIndex)
{
case 0: npc.mNpdt52.mLevel = static_cast<short>(value.toInt()); break;
case 1: npc.mNpdt52.mFactionID = static_cast<char>(value.toInt()); break;
case 2: npc.mNpdt52.mHealth = static_cast<unsigned short>(value.toInt()); break;
case 3: npc.mNpdt52.mMana = static_cast<unsigned short>(value.toInt()); break;
case 4: npc.mNpdt52.mFatigue = static_cast<unsigned short>(value.toInt()); break;
case 5: npc.mNpdt52.mDisposition = static_cast<signed char>(value.toInt()); break;
case 6: npc.mNpdt52.mReputation = static_cast<signed char>(value.toInt()); break;
case 7: npc.mNpdt52.mRank = static_cast<signed char>(value.toInt()); break;
case 8: npc.mNpdt52.mGold = value.toInt(); break;
case 9: npc.mPersistent = value.toBool(); break;
default: return; // throw an exception here?
}
record.setModified (npc);
}
int CSMWorld::NpcMiscRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const
{
return 10; // Level, FactionID, Health, Mana, Fatigue, Disposition, Reputation, Rank, Gold, Persist
}
int CSMWorld::NpcMiscRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const
{
return 1; // fixed at size 1
}
CSMWorld::WeaponColumns::WeaponColumns (const EnchantableColumns& columns) CSMWorld::WeaponColumns::WeaponColumns (const EnchantableColumns& columns)
: EnchantableColumns (columns) {} : EnchantableColumns (columns) {}

View file

@ -792,6 +792,9 @@ namespace CSMWorld
const RefIdColumn *mFaction; const RefIdColumn *mFaction;
const RefIdColumn *mHair; const RefIdColumn *mHair;
const RefIdColumn *mHead; const RefIdColumn *mHead;
const RefIdColumn *mAttributes; // depends on npc type
const RefIdColumn *mSkills; // depends on npc type
const RefIdColumn *mMisc; // may depend on npc type, e.g. FactionID
NpcColumns (const ActorColumns& actorColumns); NpcColumns (const ActorColumns& actorColumns);
}; };
@ -842,8 +845,100 @@ namespace CSMWorld
///< If the data type does not match an exception is thrown. ///< If the data type does not match an exception is thrown.
}; };
class NestedRefIdAdapterBase; class NestedRefIdAdapterBase;
class NpcAttributesRefIdAdapter : public NestedRefIdAdapterBase
{
public:
NpcAttributesRefIdAdapter ();
virtual void addNestedRow (const RefIdColumn *column,
RefIdData& data, int index, int position) const;
virtual void removeNestedRow (const RefIdColumn *column,
RefIdData& data, int index, int rowToRemove) const;
virtual void setNestedTable (const RefIdColumn* column,
RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const;
virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column,
const RefIdData& data, int index) const;
virtual QVariant getNestedData (const RefIdColumn *column,
const RefIdData& data, int index, int subRowIndex, int subColIndex) const;
virtual void setNestedData (const RefIdColumn *column,
RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const;
virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const;
virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const;
};
class NpcSkillsRefIdAdapter : public NestedRefIdAdapterBase
{
public:
NpcSkillsRefIdAdapter ();
virtual void addNestedRow (const RefIdColumn *column,
RefIdData& data, int index, int position) const;
virtual void removeNestedRow (const RefIdColumn *column,
RefIdData& data, int index, int rowToRemove) const;
virtual void setNestedTable (const RefIdColumn* column,
RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const;
virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column,
const RefIdData& data, int index) const;
virtual QVariant getNestedData (const RefIdColumn *column,
const RefIdData& data, int index, int subRowIndex, int subColIndex) const;
virtual void setNestedData (const RefIdColumn *column,
RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const;
virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const;
virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const;
};
class NpcMiscRefIdAdapter : public NestedRefIdAdapterBase
{
NpcMiscRefIdAdapter (const NpcMiscRefIdAdapter&);
NpcMiscRefIdAdapter& operator= (const NpcMiscRefIdAdapter&);
public:
NpcMiscRefIdAdapter ();
virtual ~NpcMiscRefIdAdapter();
virtual void addNestedRow (const RefIdColumn *column,
RefIdData& data, int index, int position) const;
virtual void removeNestedRow (const RefIdColumn *column,
RefIdData& data, int index, int rowToRemove) const;
virtual void setNestedTable (const RefIdColumn* column,
RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const;
virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column,
const RefIdData& data, int index) const;
virtual QVariant getNestedData (const RefIdColumn *column,
const RefIdData& data, int index, int subRowIndex, int subColIndex) const;
virtual void setNestedData (const RefIdColumn *column,
RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const;
virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const;
virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const;
};
template<typename ESXRecordT> template<typename ESXRecordT>
class EffectsListAdapter; class EffectsListAdapter;
@ -1881,7 +1976,7 @@ namespace CSMWorld
{ {
switch (subColIndex) switch (subColIndex)
{ {
case 0: return QVariant(); // don't allow checkbox editor to be created case 0: return QVariant(); // disable the checkbox editor
case 1: return record.get().mFlags & ESM::CreatureLevList::AllLevels; case 1: return record.get().mFlags & ESM::CreatureLevList::AllLevels;
case 2: return static_cast<int> (record.get().mChanceNone); case 2: return static_cast<int> (record.get().mChanceNone);
default: default:

View file

@ -245,7 +245,8 @@ CSMWorld::RefIdCollection::RefIdCollection()
actorsColumns.mServices.insert (std::make_pair (&mColumns.back(), sServiceTable[i].mFlag)); actorsColumns.mServices.insert (std::make_pair (&mColumns.back(), sServiceTable[i].mFlag));
} }
mColumns.push_back (RefIdColumn (Columns::ColumnId_AutoCalc, ColumnBase::Display_Boolean)); mColumns.push_back (RefIdColumn (Columns::ColumnId_AutoCalc, ColumnBase::Display_Boolean,
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh));
const RefIdColumn *autoCalc = &mColumns.back(); const RefIdColumn *autoCalc = &mColumns.back();
mColumns.push_back (RefIdColumn (Columns::ColumnId_ApparatusType, mColumns.push_back (RefIdColumn (Columns::ColumnId_ApparatusType,
@ -427,6 +428,62 @@ CSMWorld::RefIdCollection::RefIdCollection()
npcColumns.mFlags.insert (std::make_pair (metalBlood, ESM::NPC::Metal)); npcColumns.mFlags.insert (std::make_pair (metalBlood, ESM::NPC::Metal));
// Need a way to add a table of stats and values (rather than adding a long list of
// entries in the dialogue subview) E.g. attributes+stats(health, mana, fatigue), skills
// These needs to be driven from the autocalculated setting.
// Nested table
mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcAttributes,
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue));
npcColumns.mAttributes = &mColumns.back();
std::map<UniversalId::Type, NestedRefIdAdapterBase*> attrMap;
attrMap.insert(std::make_pair(UniversalId::Type_Npc, new NpcAttributesRefIdAdapter()));
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), attrMap));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_NpcAttributes, CSMWorld::ColumnBase::Display_String, false, false));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_UChar, CSMWorld::ColumnBase::Display_Integer));
// Nested table
mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcSkills,
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue));
npcColumns.mSkills = &mColumns.back();
std::map<UniversalId::Type, NestedRefIdAdapterBase*> skillsMap;
skillsMap.insert(std::make_pair(UniversalId::Type_Npc, new NpcSkillsRefIdAdapter()));
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), skillsMap));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_NpcSkills, CSMWorld::ColumnBase::Display_String, false, false));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_UChar, CSMWorld::ColumnBase::Display_Integer));
// Nested list
mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcMisc,
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List));
npcColumns.mMisc = &mColumns.back();
std::map<UniversalId::Type, NestedRefIdAdapterBase*> miscMap;
miscMap.insert(std::make_pair(UniversalId::Type_Npc, new NpcMiscRefIdAdapter()));
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), miscMap));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_NpcLevel, CSMWorld::ColumnBase::Display_Integer));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_NpcFactionID, CSMWorld::ColumnBase::Display_Integer));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_NpcHealth, CSMWorld::ColumnBase::Display_Integer));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_NpcMana, CSMWorld::ColumnBase::Display_Integer));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_NpcFatigue, CSMWorld::ColumnBase::Display_Integer));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_NpcDisposition, CSMWorld::ColumnBase::Display_Integer));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_NpcReputation, CSMWorld::ColumnBase::Display_Integer));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_NpcRank, CSMWorld::ColumnBase::Display_Integer));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_NpcGold, CSMWorld::ColumnBase::Display_Integer));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_NpcPersistence, CSMWorld::ColumnBase::Display_Boolean));
WeaponColumns weaponColumns (enchantableColumns); WeaponColumns weaponColumns (enchantableColumns);
mColumns.push_back (RefIdColumn (Columns::ColumnId_WeaponType, ColumnBase::Display_WeaponType)); mColumns.push_back (RefIdColumn (Columns::ColumnId_WeaponType, ColumnBase::Display_WeaponType));

View file

@ -176,7 +176,6 @@ void CSMWorld::RefIdData::erase (const LocalIndex& index, int count)
{ {
std::map<UniversalId::Type, RefIdDataContainerBase *>::iterator iter = std::map<UniversalId::Type, RefIdDataContainerBase *>::iterator iter =
mRecordContainers.find (index.second); mRecordContainers.find (index.second);
if (iter==mRecordContainers.end()) if (iter==mRecordContainers.end())
throw std::logic_error ("invalid local index type"); throw std::logic_error ("invalid local index type");
@ -189,6 +188,20 @@ void CSMWorld::RefIdData::erase (const LocalIndex& index, int count)
mIndex.erase (result); mIndex.erase (result);
} }
// Adjust the local indexes to avoid gaps between them after removal of records
int recordIndex = index.first + count;
int recordCount = iter->second->getSize();
while (recordIndex < recordCount)
{
std::map<std::string, LocalIndex>::iterator recordIndexFound =
mIndex.find(Misc::StringUtils::lowerCase(iter->second->getId(recordIndex)));
if (recordIndexFound != mIndex.end())
{
recordIndexFound->second.first -= count;
}
++recordIndex;
}
iter->second->erase (index.first, count); iter->second->erase (index.first, count);
} }

View file

@ -18,7 +18,7 @@
#include "adjusterwidget.hpp" #include "adjusterwidget.hpp"
CSVDoc::FileDialog::FileDialog(QWidget *parent) : CSVDoc::FileDialog::FileDialog(QWidget *parent) :
QDialog(parent), mSelector (0), mFileWidget (0), mAdjusterWidget (0), mDialogBuilt(false), mAction(ContentAction_Undefined) QDialog(parent), mSelector (0), mAction(ContentAction_Undefined), mFileWidget (0), mAdjusterWidget (0), mDialogBuilt(false)
{ {
ui.setupUi (this); ui.setupUi (this);
resize(400, 400); resize(400, 400);

View file

@ -0,0 +1,17 @@
#include "sizehint.hpp"
CSVDoc::SizeHintWidget::SizeHintWidget(QWidget *parent) : QWidget(parent)
{}
CSVDoc::SizeHintWidget::~SizeHintWidget()
{}
QSize CSVDoc::SizeHintWidget::sizeHint() const
{
return mSize;
}
void CSVDoc::SizeHintWidget::setSizeHint(const QSize &size)
{
mSize = size;
}

View file

@ -0,0 +1,22 @@
#ifndef CSV_DOC_SIZEHINT_H
#define CSV_DOC_SIZEHINT_H
#include <QWidget>
#include <QSize>
namespace CSVDoc
{
class SizeHintWidget : public QWidget
{
QSize mSize;
public:
SizeHintWidget(QWidget *parent = 0);
~SizeHintWidget();
virtual QSize sizeHint() const;
void setSizeHint(const QSize &size);
};
}
#endif // CSV_DOC_SIZEHINT_H

View file

@ -2,6 +2,24 @@
#include "view.hpp" #include "view.hpp"
#include <QShortcut>
#include <QEvent>
#include <QKeyEvent>
bool CSVDoc::SubView::event (QEvent *event)
{
if (event->type()==QEvent::ShortcutOverride)
{
QKeyEvent *keyEvent = static_cast<QKeyEvent *> (event);
if (keyEvent->key()==Qt::Key_W && keyEvent->modifiers()==(Qt::ShiftModifier | Qt::ControlModifier))
emit closeRequest();
return true;
}
return QDockWidget::event (event);
}
CSVDoc::SubView::SubView (const CSMWorld::UniversalId& id) CSVDoc::SubView::SubView (const CSMWorld::UniversalId& id)
: mUniversalId (id) : mUniversalId (id)
{ {

View file

@ -34,6 +34,8 @@ namespace CSVDoc
void setUniversalId(const CSMWorld::UniversalId& id); void setUniversalId(const CSMWorld::UniversalId& id);
bool event (QEvent *event);
public: public:
SubView (const CSMWorld::UniversalId& id); SubView (const CSMWorld::UniversalId& id);

View file

@ -9,6 +9,10 @@
#include <QDockWidget> #include <QDockWidget>
#include <QtGui/QApplication> #include <QtGui/QApplication>
#include <QDesktopWidget> #include <QDesktopWidget>
#include <QScrollArea>
#include <QHBoxLayout>
#include <QDesktopWidget>
#include <QScrollBar>
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
#include "../../model/settings/usersettings.hpp" #include "../../model/settings/usersettings.hpp"
@ -16,6 +20,7 @@
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "../world/subviews.hpp" #include "../world/subviews.hpp"
#include "../world/tablesubview.hpp"
#include "../tools/subviews.hpp" #include "../tools/subviews.hpp"
@ -334,8 +339,15 @@ void CSVDoc::View::updateTitle()
void CSVDoc::View::updateSubViewIndicies(SubView *view) void CSVDoc::View::updateSubViewIndicies(SubView *view)
{ {
if(view && mSubViews.contains(view)) if(view && mSubViews.contains(view))
{
mSubViews.removeOne(view); mSubViews.removeOne(view);
// adjust (reduce) the scroll area (even floating), except when it is "Scrollbar Only"
CSMSettings::UserSettings &settings = CSMSettings::UserSettings::instance();
if(settings.settingValue ("window/mainwindow-scrollbar") == "Grow then Scroll")
updateScrollbar();
}
CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance(); CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance();
bool hideTitle = userSettings.setting ("window/hide-subview", QString ("false"))=="true" && bool hideTitle = userSettings.setting ("window/hide-subview", QString ("false"))=="true" &&
@ -381,7 +393,7 @@ void CSVDoc::View::updateActions()
CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews) CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews)
: mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1), : mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1),
mViewTotal (totalViews) mViewTotal (totalViews), mScroll(0), mScrollbarOnly(false)
{ {
int width = CSMSettings::UserSettings::instance().settingValue int width = CSMSettings::UserSettings::instance().settingValue
("window/default-width").toInt(); ("window/default-width").toInt();
@ -400,7 +412,18 @@ CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int to
mSubViewWindow.setDockOptions (QMainWindow::AllowNestedDocks); mSubViewWindow.setDockOptions (QMainWindow::AllowNestedDocks);
CSMSettings::UserSettings &settings = CSMSettings::UserSettings::instance();
if(settings.settingValue ("window/mainwindow-scrollbar") == "Grow Only")
{
setCentralWidget (&mSubViewWindow); setCentralWidget (&mSubViewWindow);
}
else
{
mScroll = new QScrollArea(this);
mScroll->setWidgetResizable(true);
mScroll->setWidget(&mSubViewWindow);
setCentralWidget(mScroll);
}
mOperations = new Operations; mOperations = new Operations;
addDockWidget (Qt::BottomDockWidgetArea, mOperations); addDockWidget (Qt::BottomDockWidgetArea, mOperations);
@ -527,6 +550,54 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin
view->setStatusBar (mShowStatusBar->isChecked()); view->setStatusBar (mShowStatusBar->isChecked());
// Work out how to deal with additional subviews
//
// Policy for "Grow then Scroll":
//
// - Increase the horizontal width of the mainwindow until it becomes greater than or equal
// to the screen (monitor) width.
// - Move the mainwindow position sideways if necessary to fit within the screen.
// - Any more additions increases the size of the mSubViewWindow (horizontal scrollbar
// should become visible)
// - Move the scroll bar to the newly added subview
//
CSMSettings::UserSettings &settings = CSMSettings::UserSettings::instance();
QString mainwinScroll = settings.settingValue ("window/mainwindow-scrollbar");
mScrollbarOnly = mainwinScroll.isEmpty() || mainwinScroll == "Scrollbar Only";
QDesktopWidget *dw = QApplication::desktop();
QRect rect;
if(settings.settingValue ("window/grow-limit") == "true")
rect = dw->screenGeometry(this);
else
rect = dw->screenGeometry(dw->screen(dw->screenNumber(this)));
if (!mScrollbarOnly && mScroll && mSubViews.size() > 1)
{
int newWidth = width()+minWidth;
int frameWidth = frameGeometry().width() - width();
if (newWidth+frameWidth <= rect.width())
{
resize(newWidth, height());
// WARNING: below code assumes that new subviews are added to the right
if (x() > rect.width()-(newWidth+frameWidth))
move(rect.width()-(newWidth+frameWidth), y()); // shift left to stay within the screen
}
else
{
// full width
resize(rect.width()-frameWidth, height());
mSubViewWindow.setMinimumWidth(mSubViewWindow.width()+minWidth);
move(0, y());
}
// Make the new subview visible, setFocus() or raise() don't seem to work
// On Ubuntu the scrollbar does not go right to the end, even if using
// mScroll->horizontalScrollBar()->setValue(mScroll->horizontalScrollBar()->maximum());
if (mSubViewWindow.width() > rect.width())
mScroll->horizontalScrollBar()->setValue(mSubViewWindow.width());
}
mSubViewWindow.addDockWidget (Qt::TopDockWidgetArea, view); mSubViewWindow.addDockWidget (Qt::TopDockWidgetArea, view);
updateSubViewIndicies(); updateSubViewIndicies();
@ -774,6 +845,48 @@ void CSVDoc::View::updateUserSetting (const QString &name, const QStringList &li
{ {
subView->updateUserSetting (name, list); subView->updateUserSetting (name, list);
} }
if (name=="window/mainwindow-scrollbar")
{
if(list.at(0) != "Grow Only")
{
if (mScroll)
{
if (list.at(0).isEmpty() || list.at(0) == "Scrollbar Only")
{
mScrollbarOnly = true;
mSubViewWindow.setMinimumWidth(0);
}
else
{
if(!mScrollbarOnly)
return;
mScrollbarOnly = false;
updateScrollbar();
}
}
else
{
mScroll = new QScrollArea(this);
mScroll->setWidgetResizable(true);
mScroll->setWidget(&mSubViewWindow);
setCentralWidget(mScroll);
}
}
else
{
if (mScroll)
{
mScroll->takeWidget();
setCentralWidget (&mSubViewWindow);
mScroll->deleteLater();
mScroll = 0;
}
else
return;
}
}
} }
void CSVDoc::View::toggleShowStatusBar (bool show) void CSVDoc::View::toggleShowStatusBar (bool show)
@ -811,7 +924,33 @@ void CSVDoc::View::closeRequest (SubView *subView)
if (mSubViews.size()>1 || mViewTotal<=1 || if (mSubViews.size()>1 || mViewTotal<=1 ||
userSettings.setting ("window/hide-subview", QString ("false"))!="true") userSettings.setting ("window/hide-subview", QString ("false"))!="true")
{
subView->deleteLater(); subView->deleteLater();
mSubViews.removeOne (subView);
}
else if (mViewManager.closeRequest (this)) else if (mViewManager.closeRequest (this))
mViewManager.removeDocAndView (mDocument); mViewManager.removeDocAndView (mDocument);
} }
void CSVDoc::View::updateScrollbar()
{
QRect rect;
QWidget *topLevel = QApplication::topLevelAt(pos());
if (topLevel)
rect = topLevel->rect();
else
rect = this->rect();
int newWidth = 0;
for (int i = 0; i < mSubViews.size(); ++i)
{
newWidth += mSubViews[i]->width();
}
int frameWidth = frameGeometry().width() - width();
if ((newWidth+frameWidth) >= rect.width())
mSubViewWindow.setMinimumWidth(newWidth);
else
mSubViewWindow.setMinimumWidth(0);
}

View file

@ -10,6 +10,7 @@
class QAction; class QAction;
class QDockWidget; class QDockWidget;
class QScrollArea;
namespace CSMDoc namespace CSMDoc
{ {
@ -47,6 +48,8 @@ namespace CSVDoc
SubViewFactoryManager mSubViewFactory; SubViewFactoryManager mSubViewFactory;
QMainWindow mSubViewWindow; QMainWindow mSubViewWindow;
GlobalDebugProfileMenu *mGlobalDebugProfileMenu; GlobalDebugProfileMenu *mGlobalDebugProfileMenu;
QScrollArea *mScroll;
bool mScrollbarOnly;
// not implemented // not implemented
@ -87,6 +90,8 @@ namespace CSVDoc
/// User preference function /// User preference function
void resizeViewHeight (int height); void resizeViewHeight (int height);
void updateScrollbar();
public: public:
View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews); View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews);

View file

@ -92,7 +92,8 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager)
{ CSMWorld::ColumnBase::Display_AiPackageType, CSMWorld::Columns::ColumnId_AiPackageType, false }, { CSMWorld::ColumnBase::Display_AiPackageType, CSMWorld::Columns::ColumnId_AiPackageType, false },
{ CSMWorld::ColumnBase::Display_YesNo, CSMWorld::Columns::ColumnId_AiWanderRepeat, false }, { CSMWorld::ColumnBase::Display_YesNo, CSMWorld::Columns::ColumnId_AiWanderRepeat, false },
{ CSMWorld::ColumnBase::Display_InfoCondFunc, CSMWorld::Columns::ColumnId_InfoCondFunc, false }, { CSMWorld::ColumnBase::Display_InfoCondFunc, CSMWorld::Columns::ColumnId_InfoCondFunc, false },
{ CSMWorld::ColumnBase::Display_InfoCondComp, CSMWorld::Columns::ColumnId_InfoCondComp, false } { CSMWorld::ColumnBase::Display_InfoCondComp, CSMWorld::Columns::ColumnId_InfoCondComp, false },
{ CSMWorld::ColumnBase::Display_RaceSkill, CSMWorld::Columns::ColumnId_RaceSkill, true },
}; };
for (std::size_t i=0; i<sizeof (sMapping)/sizeof (Mapping); ++i) for (std::size_t i=0; i<sizeof (sMapping)/sizeof (Mapping); ++i)

View file

@ -55,7 +55,7 @@ bool CSVRender::Cell::addObjects (int start, int end)
CSVRender::Cell::Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager, CSVRender::Cell::Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager,
const std::string& id, boost::shared_ptr<CSVWorld::PhysicsSystem> physics, const Ogre::Vector3& origin) const std::string& id, boost::shared_ptr<CSVWorld::PhysicsSystem> physics, const Ogre::Vector3& origin)
: mData (data), mId (Misc::StringUtils::lowerCase (id)), mSceneMgr(sceneManager), mPhysics(physics), mX(0), mY(0) : mData (data), mId (Misc::StringUtils::lowerCase (id)), mPhysics(physics), mSceneMgr(sceneManager), mX(0), mY(0)
{ {
mCellNode = sceneManager->getRootSceneNode()->createChildSceneNode(); mCellNode = sceneManager->getRootSceneNode()->createChildSceneNode();
mCellNode->setPosition (origin); mCellNode->setPosition (origin);

View file

@ -56,11 +56,11 @@ namespace CSVRender
// //
MouseState::MouseState(WorldspaceWidget *parent) MouseState::MouseState(WorldspaceWidget *parent)
: mParent(parent), mPhysics(parent->mDocument.getPhysics()), mSceneManager(parent->getSceneManager()) : mMouseState(Mouse_Default), mParent(parent), mPhysics(parent->mDocument.getPhysics())
, mCurrentObj(""), mMouseState(Mouse_Default), mOldPos(0,0), mMouseEventTimer(0), mPlane(0) , mSceneManager(parent->getSceneManager()), mOldPos(0,0), mCurrentObj(""), mGrabbedSceneNode("")
, mGrabbedSceneNode(""), mOrigObjPos(Ogre::Vector3()), mOrigMousePos(Ogre::Vector3()) , mMouseEventTimer(0), mPlane(0), mOrigObjPos(Ogre::Vector3()), mOrigMousePos(Ogre::Vector3())
, mCurrentMousePos(Ogre::Vector3()), mOffset(0.0f) , mCurrentMousePos(Ogre::Vector3()), mOffset(0.0f), mIdTableModel(0), mColIndexPosX(0)
, mColIndexPosX(0), mColIndexPosY(0), mColIndexPosZ(0), mIdTableModel(0) , mColIndexPosY(0), mColIndexPosZ(0)
{ {
const CSMWorld::RefCollection& references = mParent->mDocument.getData().getReferences(); const CSMWorld::RefCollection& references = mParent->mDocument.getData().getReferences();

View file

@ -27,8 +27,8 @@ namespace CSVRender
// http://www.ogre3d.org/tikiwiki/Creating+dynamic+textures // http://www.ogre3d.org/tikiwiki/Creating+dynamic+textures
// http://www.ogre3d.org/tikiwiki/ManualObject // http://www.ogre3d.org/tikiwiki/ManualObject
TextOverlay::TextOverlay(const Ogre::MovableObject* obj, const Ogre::Camera* camera, const Ogre::String& id) TextOverlay::TextOverlay(const Ogre::MovableObject* obj, const Ogre::Camera* camera, const Ogre::String& id)
: mOverlay(0), mCaption(""), mDesc(""), mEnabled(true), mCamera(camera), mObj(obj), mId(id) : mOverlay(0), mCaption(""), mDesc(""), mObj(obj), mCamera(camera), mFontHeight(16), mId(id)
, mOnScreen(false) , mInstance(0), mFontHeight(16) // FIXME: make font height configurable , mEnabled(true), mOnScreen(false), mInstance(0) // FIXME: make font height configurable
{ {
if(id == "" || !camera || !obj) if(id == "" || !camera || !obj)
throw std::runtime_error("TextOverlay could not be created."); throw std::runtime_error("TextOverlay could not be created.");

View file

@ -22,7 +22,7 @@
#include "editmode.hpp" #include "editmode.hpp"
CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent) CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent)
: SceneWidget (parent), mDocument(document), mSceneElements(0), mRun(0), mPhysics(boost::shared_ptr<CSVWorld::PhysicsSystem>()), mMouse(0), : SceneWidget (parent), mSceneElements(0), mRun(0), mDocument(document), mPhysics(boost::shared_ptr<CSVWorld::PhysicsSystem>()), mMouse(0),
mInteractionMask (0) mInteractionMask (0)
{ {
setAcceptDrops(true); setAcceptDrops(true);

View file

@ -12,7 +12,7 @@
CSVSettings::BooleanView::BooleanView (CSMSettings::Setting *setting, CSVSettings::BooleanView::BooleanView (CSMSettings::Setting *setting,
Page *parent) Page *parent)
: mType(setting->type()), View (setting, parent) : View (setting, parent), mType(setting->type())
{ {
foreach (const QString &value, setting->declaredValues()) foreach (const QString &value, setting->declaredValues())
{ {

View file

@ -23,7 +23,7 @@
#include <QStandardItem> #include <QStandardItem>
CSVSettings::Dialog::Dialog(QMainWindow *parent) CSVSettings::Dialog::Dialog(QMainWindow *parent)
: mStackedWidget (0), mDebugMode (false), SettingWindow (parent) : SettingWindow (parent), mStackedWidget (0), mDebugMode (false)
{ {
setWindowTitle(QString::fromUtf8 ("User Settings")); setWindowTitle(QString::fromUtf8 ("User Settings"));

View file

@ -7,8 +7,8 @@ const QString CSVSettings::Frame::sInvisibleBoxStyle =
CSVSettings::Frame::Frame (bool isVisible, const QString &title, CSVSettings::Frame::Frame (bool isVisible, const QString &title,
QWidget *parent) QWidget *parent)
: mIsHorizontal (true), mLayout (new SettingLayout()), : QGroupBox (title, parent), mIsHorizontal (true),
QGroupBox (title, parent) mLayout (new SettingLayout())
{ {
setFlat (true); setFlat (true);
mVisibleBoxStyle = styleSheet(); mVisibleBoxStyle = styleSheet();

View file

@ -7,7 +7,7 @@
CSVSettings::ListView::ListView(CSMSettings::Setting *setting, CSVSettings::ListView::ListView(CSMSettings::Setting *setting,
Page *parent) Page *parent)
: mComboBox (0), mAbstractItemView (0), View(setting, parent) : View(setting, parent), mAbstractItemView (0), mComboBox (0)
{ {
QWidget *widget = QWidget *widget =
buildWidget(setting->isMultiLine(), setting->widgetWidth()); buildWidget(setting->isMultiLine(), setting->widgetWidth());

View file

@ -19,7 +19,7 @@ QMap <CSVSettings::ViewType, CSVSettings::IViewFactory *>
CSVSettings::Page::Page (const QString &pageName, QList <CSMSettings::Setting *> settingList, CSVSettings::Page::Page (const QString &pageName, QList <CSMSettings::Setting *> settingList,
SettingWindow *parent, const QString& label) SettingWindow *parent, const QString& label)
: mParent(parent), mIsEditorPage (false), Frame(false, "", parent), mLabel (label) : Frame(false, "", parent), mParent(parent), mIsEditorPage (false), mLabel (label)
{ {
setObjectName (pageName); setObjectName (pageName);

View file

@ -3,7 +3,7 @@
#include <QLineEdit> #include <QLineEdit>
CSVSettings::SpinBox::SpinBox(QWidget *parent) CSVSettings::SpinBox::SpinBox(QWidget *parent)
: mValueList(QStringList()), QSpinBox(parent) : QSpinBox(parent), mValueList(QStringList())
{ {
setRange (0, 0); setRange (0, 0);
} }

View file

@ -12,12 +12,12 @@
CSVSettings::View::View(CSMSettings::Setting *setting, CSVSettings::View::View(CSMSettings::Setting *setting,
Page *parent) Page *parent)
: mDataModel(0), mParentPage (parent), : Frame(true, setting->getLabel(), parent),
mParentPage (parent), mDataModel(0),
mHasFixedValues (!setting->declaredValues().isEmpty()), mHasFixedValues (!setting->declaredValues().isEmpty()),
mIsMultiValue (setting->isMultiValue()), mIsMultiValue (setting->isMultiValue()),
mViewKey (setting->page() + '/' + setting->name()), mViewKey (setting->page() + '/' + setting->name()),
mSerializable (setting->serializable()), mSerializable (setting->serializable())
Frame(true, setting->getLabel(), parent)
{ {
if (!setting->getToolTip().isEmpty()) if (!setting->getToolTip().isEmpty())
setToolTip (setting->getToolTip()); setToolTip (setting->getToolTip());

View file

@ -0,0 +1,53 @@
#include "dialoguespinbox.hpp"
#include <QWheelEvent>
CSVWorld::DialogueSpinBox::DialogueSpinBox(QWidget *parent) : QSpinBox(parent)
{
setFocusPolicy(Qt::StrongFocus);
}
void CSVWorld::DialogueSpinBox::focusInEvent(QFocusEvent *event)
{
setFocusPolicy(Qt::WheelFocus);
QSpinBox::focusInEvent(event);
}
void CSVWorld::DialogueSpinBox::focusOutEvent(QFocusEvent *event)
{
setFocusPolicy(Qt::StrongFocus);
QSpinBox::focusOutEvent(event);
}
void CSVWorld::DialogueSpinBox::wheelEvent(QWheelEvent *event)
{
if (!hasFocus())
event->ignore();
else
QSpinBox::wheelEvent(event);
}
CSVWorld::DialogueDoubleSpinBox::DialogueDoubleSpinBox(QWidget *parent) : QDoubleSpinBox(parent)
{
setFocusPolicy(Qt::StrongFocus);
}
void CSVWorld::DialogueDoubleSpinBox::focusInEvent(QFocusEvent *event)
{
setFocusPolicy(Qt::WheelFocus);
QDoubleSpinBox::focusInEvent(event);
}
void CSVWorld::DialogueDoubleSpinBox::focusOutEvent(QFocusEvent *event)
{
setFocusPolicy(Qt::StrongFocus);
QDoubleSpinBox::focusOutEvent(event);
}
void CSVWorld::DialogueDoubleSpinBox::wheelEvent(QWheelEvent *event)
{
if (!hasFocus())
event->ignore();
else
QDoubleSpinBox::wheelEvent(event);
}

View file

@ -0,0 +1,40 @@
#ifndef CSV_WORLD_DIALOGUESPINBOX_H
#define CSV_WORLD_DIALOGUESPINBOX_H
#include <QSpinBox>
#include <QDoubleSpinBox>
namespace CSVWorld
{
class DialogueSpinBox : public QSpinBox
{
Q_OBJECT
public:
DialogueSpinBox (QWidget *parent = 0);
protected:
virtual void focusInEvent(QFocusEvent *event);
virtual void focusOutEvent(QFocusEvent *event);
virtual void wheelEvent(QWheelEvent *event);
};
class DialogueDoubleSpinBox : public QDoubleSpinBox
{
Q_OBJECT
public:
DialogueDoubleSpinBox (QWidget *parent = 0);
protected:
virtual void focusInEvent(QFocusEvent *event);
virtual void focusOutEvent(QFocusEvent *event);
virtual void wheelEvent(QWheelEvent *event);
};
}
#endif // CSV_WORLD_DIALOGUESPINBOX_H

View file

@ -20,6 +20,7 @@
#include <QPushButton> #include <QPushButton>
#include <QToolButton> #include <QToolButton>
#include <QHeaderView> #include <QHeaderView>
#include <QScrollBar>
#include "../../model/world/nestedtableproxymodel.hpp" #include "../../model/world/nestedtableproxymodel.hpp"
#include "../../model/world/columnbase.hpp" #include "../../model/world/columnbase.hpp"
@ -210,8 +211,17 @@ void CSVWorld::DialogueDelegateDispatcher::editorDataCommited(QWidget* editor,
void CSVWorld::DialogueDelegateDispatcher::setEditorData (QWidget* editor, const QModelIndex& index) const void CSVWorld::DialogueDelegateDispatcher::setEditorData (QWidget* editor, const QModelIndex& index) const
{ {
CSMWorld::ColumnBase::Display display = static_cast<CSMWorld::ColumnBase::Display> CSMWorld::ColumnBase::Display display = CSMWorld::ColumnBase::Display_None;
if (index.parent().isValid())
{
display = static_cast<CSMWorld::ColumnBase::Display>
(static_cast<CSMWorld::IdTree *>(mTable)->nestedHeaderData (index.parent().column(), index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt());
}
else
{
display = static_cast<CSMWorld::ColumnBase::Display>
(mTable->headerData (index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); (mTable->headerData (index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt());
}
QLabel* label = qobject_cast<QLabel*>(editor); QLabel* label = qobject_cast<QLabel*>(editor);
if(label) if(label)
@ -347,62 +357,66 @@ CSVWorld::DialogueDelegateDispatcher::~DialogueDelegateDispatcher()
CSVWorld::EditWidget::~EditWidget() CSVWorld::EditWidget::~EditWidget()
{ {
for (unsigned i = 0; i < mNestedModels.size(); ++i) for (unsigned i = 0; i < mNestedModels.size(); ++i)
{
delete mNestedModels[i]; delete mNestedModels[i];
}
if (mDispatcher)
delete mDispatcher;
if (mNestedTableDispatcher)
delete mNestedTableDispatcher; delete mNestedTableDispatcher;
} }
CSVWorld::EditWidget::EditWidget(QWidget *parent, CSVWorld::EditWidget::EditWidget(QWidget *parent,
int row, CSMWorld::IdTable* table, CSMWorld::CommandDispatcher& commandDispatcher, int row, CSMWorld::IdTable* table, CSMWorld::CommandDispatcher& commandDispatcher,
CSMDoc::Document& document, bool createAndDelete) : CSMDoc::Document& document, bool createAndDelete) :
mDispatcher(this, table, commandDispatcher, document),
mNestedTableDispatcher(NULL),
QScrollArea(parent), QScrollArea(parent),
mWidgetMapper(NULL), mWidgetMapper(NULL),
mNestedTableMapper(NULL), mNestedTableMapper(NULL),
mDispatcher(NULL),
mNestedTableDispatcher(NULL),
mMainWidget(NULL), mMainWidget(NULL),
mTable(table),
mCommandDispatcher (commandDispatcher), mCommandDispatcher (commandDispatcher),
mDocument (document), mDocument (document)
mTable(table)
{ {
remake (row); remake (row);
connect(&mDispatcher, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), connect(mDispatcher, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)),
this, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*))); this, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)));
} }
void CSVWorld::EditWidget::remake(int row) void CSVWorld::EditWidget::remake(int row)
{ {
for (unsigned i = 0; i < mNestedModels.size(); ++i)
{
delete mNestedModels[i];
}
mNestedModels.clear();
delete mNestedTableDispatcher;
if (mMainWidget) if (mMainWidget)
{ {
delete mMainWidget; QWidget *del = this->takeWidget();
mMainWidget = 0; del->deleteLater();
} }
mMainWidget = new QWidget (this); mMainWidget = new QWidget (this);
for (unsigned i = 0; i < mNestedModels.size(); ++i)
delete mNestedModels[i];
mNestedModels.clear();
if (mDispatcher)
delete mDispatcher;
mDispatcher = new DialogueDelegateDispatcher(0/*this*/, mTable, mCommandDispatcher, mDocument);
if (mNestedTableDispatcher)
delete mNestedTableDispatcher;
//not sure if widget mapper can handle deleting the widgets that were mapped //not sure if widget mapper can handle deleting the widgets that were mapped
if (mWidgetMapper) if (mWidgetMapper)
{
delete mWidgetMapper; delete mWidgetMapper;
mWidgetMapper = 0;
}
if (mNestedTableMapper)
{
delete mNestedTableMapper;
mNestedTableMapper = 0;
}
mWidgetMapper = new QDataWidgetMapper (this);
mWidgetMapper = new QDataWidgetMapper (this);
mWidgetMapper->setModel(mTable); mWidgetMapper->setModel(mTable);
mWidgetMapper->setItemDelegate(&mDispatcher); mWidgetMapper->setItemDelegate(mDispatcher);
if (mNestedTableMapper)
delete mNestedTableMapper;
QFrame* line = new QFrame(mMainWidget); QFrame* line = new QFrame(mMainWidget);
line->setObjectName(QString::fromUtf8("line")); line->setObjectName(QString::fromUtf8("line"));
@ -457,6 +471,13 @@ void CSVWorld::EditWidget::remake(int row)
NestedTable* table = new NestedTable(mDocument, id, mNestedModels.back(), this); NestedTable* table = new NestedTable(mDocument, id, mNestedModels.back(), this);
// FIXME: does not work well when enum delegates are used // FIXME: does not work well when enum delegates are used
//table->resizeColumnsToContents(); //table->resizeColumnsToContents();
if(mTable->index(row, i).data().type() == QVariant::UserType)
{
table->setEditTriggers(QAbstractItemView::NoEditTriggers);
table->setEnabled(false);
}
else
table->setEditTriggers(QAbstractItemView::SelectedClicked | QAbstractItemView::CurrentChanged); table->setEditTriggers(QAbstractItemView::SelectedClicked | QAbstractItemView::CurrentChanged);
int rows = mTable->rowCount(mTable->index(row, i)); int rows = mTable->rowCount(mTable->index(row, i));
@ -469,14 +490,16 @@ void CSVWorld::EditWidget::remake(int row)
new QLabel (mTable->headerData (i, Qt::Horizontal, Qt::DisplayRole).toString(), mMainWidget); new QLabel (mTable->headerData (i, Qt::Horizontal, Qt::DisplayRole).toString(), mMainWidget);
label->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed); label->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed);
if(mTable->index(row, i).data().type() == QVariant::UserType)
label->setEnabled(false);
tablesLayout->addWidget(label); tablesLayout->addWidget(label);
tablesLayout->addWidget(table); tablesLayout->addWidget(table);
} }
else if (!(flags & CSMWorld::ColumnBase::Flag_Dialogue_List)) else if (!(flags & CSMWorld::ColumnBase::Flag_Dialogue_List))
{ {
mDispatcher.makeDelegate (display); mDispatcher->makeDelegate (display);
QWidget* editor = mDispatcher.makeEditor (display, (mTable->index (row, i))); QWidget* editor = mDispatcher->makeEditor (display, (mTable->index (row, i)));
if (editor) if (editor)
{ {
@ -499,26 +522,30 @@ void CSVWorld::EditWidget::remake(int row)
unlockedLayout->addWidget (editor, unlocked, 1); unlockedLayout->addWidget (editor, unlocked, 1);
++unlocked; ++unlocked;
} }
if(mTable->index(row, i).data().type() == QVariant::UserType)
{
editor->setEnabled(false);
label->setEnabled(false);
}
} }
} }
else else
{ {
mNestedModels.push_back(new CSMWorld::NestedTableProxyModel ( CSMWorld::IdTree *tree = static_cast<CSMWorld::IdTree *>(mTable);
static_cast<CSMWorld::IdTree *>(mTable)->index(row, i),
display, static_cast<CSMWorld::IdTree *>(mTable)));
mNestedTableMapper = new QDataWidgetMapper (this); mNestedTableMapper = new QDataWidgetMapper (this);
mNestedTableMapper->setModel(mNestedModels.back()); mNestedTableMapper->setModel(tree);
// FIXME: lack MIME support? // FIXME: lack MIME support?
mNestedTableDispatcher = mNestedTableDispatcher =
new DialogueDelegateDispatcher (this, mTable, mCommandDispatcher, mDocument, mNestedModels.back()); new DialogueDelegateDispatcher (0/*this*/, mTable, mCommandDispatcher, mDocument, tree);
mNestedTableMapper->setRootIndex (tree->index(row, i));
mNestedTableMapper->setItemDelegate(mNestedTableDispatcher); mNestedTableMapper->setItemDelegate(mNestedTableDispatcher);
int columnCount = int columnCount = tree->columnCount(tree->index(row, i));
mTable->columnCount(mTable->getModelIndex (mNestedModels.back()->getParentId(), i));
for (int col = 0; col < columnCount; ++col) for (int col = 0; col < columnCount; ++col)
{ {
int displayRole = mNestedModels.back()->headerData (col, int displayRole = tree->nestedHeaderData (i, col,
Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt(); Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt();
CSMWorld::ColumnBase::Display display = CSMWorld::ColumnBase::Display display =
@ -528,16 +555,16 @@ void CSVWorld::EditWidget::remake(int row)
// FIXME: assumed all columns are editable // FIXME: assumed all columns are editable
QWidget* editor = QWidget* editor =
mNestedTableDispatcher->makeEditor (display, mNestedModels.back()->index (0, col)); mNestedTableDispatcher->makeEditor (display, tree->index (0, col, tree->index(row, i)));
if (editor) if (editor)
{ {
mNestedTableMapper->addMapping (editor, col); mNestedTableMapper->addMapping (editor, col);
std::string disString = mNestedModels.back()->headerData (col, std::string disString = tree->nestedHeaderData (i, col,
Qt::Horizontal, Qt::DisplayRole).toString().toStdString(); Qt::Horizontal, Qt::DisplayRole).toString().toStdString();
// Need ot use Qt::DisplayRole in order to get the correct string // Need to use Qt::DisplayRole in order to get the correct string
// from CSMWorld::Columns // from CSMWorld::Columns
QLabel* label = new QLabel (mNestedModels.back()->headerData (col, QLabel* label = new QLabel (tree->nestedHeaderData (i, col,
Qt::Horizontal, Qt::DisplayRole).toString(), mMainWidget); Qt::Horizontal, Qt::DisplayRole).toString(), mMainWidget);
label->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed); label->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed);
@ -546,9 +573,15 @@ void CSVWorld::EditWidget::remake(int row)
unlockedLayout->addWidget (label, unlocked, 0); unlockedLayout->addWidget (label, unlocked, 0);
unlockedLayout->addWidget (editor, unlocked, 1); unlockedLayout->addWidget (editor, unlocked, 1);
++unlocked; ++unlocked;
if(tree->index(0, col, tree->index(row, i)).data().type() == QVariant::UserType)
{
editor->setEnabled(false);
label->setEnabled(false);
} }
} }
mNestedTableMapper->setCurrentModelIndex(mNestedModels.back()->index(0, 0)); }
mNestedTableMapper->setCurrentModelIndex(tree->index(0, 0, tree->index(row, i)));
} }
} }
} }
@ -571,13 +604,14 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM
SubView (id), SubView (id),
mEditWidget(0), mEditWidget(0),
mMainLayout(NULL), mMainLayout(NULL),
mUndoStack(document.getUndoStack()),
mTable(dynamic_cast<CSMWorld::IdTable*>(document.getData().getTableModel(id))), mTable(dynamic_cast<CSMWorld::IdTable*>(document.getData().getTableModel(id))),
mUndoStack(document.getUndoStack()),
mLocked(false), mLocked(false),
mDocument(document), mDocument(document),
mCommandDispatcher (document, CSMWorld::UniversalId::getParentType (id.getType())) mCommandDispatcher (document, CSMWorld::UniversalId::getParentType (id.getType()))
{ {
connect(mTable, SIGNAL(dataChanged (const QModelIndex&, const QModelIndex&)), this, SLOT(dataChanged(const QModelIndex&))); connect(mTable, SIGNAL(dataChanged (const QModelIndex&, const QModelIndex&)), this, SLOT(dataChanged(const QModelIndex&)));
connect(mTable, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)), this, SLOT(rowsAboutToBeRemoved(const QModelIndex&, int, int)));
changeCurrentId(id.getId()); changeCurrentId(id.getId());
@ -740,6 +774,9 @@ void CSVWorld::DialogueSubView::nextId ()
void CSVWorld::DialogueSubView::setEditLock (bool locked) void CSVWorld::DialogueSubView::setEditLock (bool locked)
{ {
if (!mEditWidget) // hack to indicate that mCurrentId is no longer valid
return;
mLocked = locked; mLocked = locked;
QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0));
@ -758,11 +795,47 @@ void CSVWorld::DialogueSubView::dataChanged (const QModelIndex & index)
{ {
QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0));
if (currentIndex.isValid() && index.row() == currentIndex.row()) if (currentIndex.isValid() &&
(index.parent().isValid() ? index.parent().row() : index.row()) == currentIndex.row())
{ {
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State>(mTable->data (mTable->index (currentIndex.row(), 1)).toInt()); CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State>(mTable->data (mTable->index (currentIndex.row(), 1)).toInt());
mEditWidget->setDisabled (state==CSMWorld::RecordBase::State_Deleted || mLocked); mEditWidget->setDisabled (state==CSMWorld::RecordBase::State_Deleted || mLocked);
// Check if the changed data should force refresh (rebuild) the dialogue subview
int flags = 0;
if (index.parent().isValid()) // TODO: check that index is topLeft
{
flags = static_cast<CSMWorld::IdTree *>(mTable)->nestedHeaderData (index.parent().column(),
index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt();
}
else
{
flags = mTable->headerData (index.column(),
Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt();
}
if (flags & CSMWorld::ColumnBase::Flag_Dialogue_Refresh)
{
int y = mEditWidget->verticalScrollBar()->value();
mEditWidget->remake (index.parent().isValid() ? index.parent().row() : index.row());
mEditWidget->verticalScrollBar()->setValue(y);
}
}
}
void CSVWorld::DialogueSubView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
{
QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0));
if (currentIndex.isValid() && currentIndex.row() >= start && currentIndex.row() <= end)
{
if(mEditWidget)
{
delete mEditWidget;
mEditWidget = 0;
}
emit closeRequest(this);
} }
} }

View file

@ -165,7 +165,7 @@ namespace CSVWorld
Q_OBJECT Q_OBJECT
QDataWidgetMapper *mWidgetMapper; QDataWidgetMapper *mWidgetMapper;
QDataWidgetMapper *mNestedTableMapper; QDataWidgetMapper *mNestedTableMapper;
DialogueDelegateDispatcher mDispatcher; DialogueDelegateDispatcher *mDispatcher;
DialogueDelegateDispatcher *mNestedTableDispatcher; DialogueDelegateDispatcher *mNestedTableDispatcher;
QWidget* mMainWidget; QWidget* mMainWidget;
CSMWorld::IdTable* mTable; CSMWorld::IdTable* mTable;
@ -235,6 +235,8 @@ namespace CSVWorld
const CSMDoc::Document* document); const CSMDoc::Document* document);
void requestFocus (const std::string& id); void requestFocus (const std::string& id);
void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
}; };
} }

View file

@ -17,8 +17,8 @@ void CSVWorld::DragRecordTable::startDragFromTable (const CSVWorld::DragRecordTa
} }
CSVWorld::DragRecordTable::DragRecordTable (CSMDoc::Document& document, QWidget* parent) : CSVWorld::DragRecordTable::DragRecordTable (CSMDoc::Document& document, QWidget* parent) :
mDocument(document),
QTableView(parent), QTableView(parent),
mDocument(document),
mEditLock(false) mEditLock(false)
{} {}

View file

@ -129,9 +129,9 @@ void CSVWorld::GenericCreator::addScope (const QString& name, CSMWorld::Scope sc
CSVWorld::GenericCreator::GenericCreator (CSMWorld::Data& data, QUndoStack& undoStack, CSVWorld::GenericCreator::GenericCreator (CSMWorld::Data& data, QUndoStack& undoStack,
const CSMWorld::UniversalId& id, bool relaxedIdRules) const CSMWorld::UniversalId& id, bool relaxedIdRules)
: mData (data), mUndoStack (undoStack), mListId (id), mLocked (false), mCloneMode (false), : mData (data), mUndoStack (undoStack), mListId (id), mLocked (false),
mClonedType (CSMWorld::UniversalId::Type_None), mScopes (CSMWorld::Scope_Content), mScope (0), mClonedType (CSMWorld::UniversalId::Type_None), mScopes (CSMWorld::Scope_Content), mScope (0),
mScopeLabel (0) mScopeLabel (0), mCloneMode (false)
{ {
mLayout = new QHBoxLayout; mLayout = new QHBoxLayout;
mLayout->setContentsMargins (0, 0, 0, 0); mLayout->setContentsMargins (0, 0, 0, 0);

View file

@ -27,7 +27,7 @@
#include "creator.hpp" #include "creator.hpp"
CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document)
: SubView (id), mLayout(new QHBoxLayout), mDocument(document), mScene(NULL), mToolbar(NULL) : SubView (id), mScene(NULL), mLayout(new QHBoxLayout), mDocument(document), mToolbar(NULL)
{ {
QVBoxLayout *layout = new QVBoxLayout; QVBoxLayout *layout = new QVBoxLayout;

View file

@ -25,17 +25,31 @@ CSVWorld::ScriptEdit::ChangeLock::~ChangeLock()
--mEdit.mChangeLocked; --mEdit.mChangeLocked;
} }
bool CSVWorld::ScriptEdit::event (QEvent *event)
{
// ignore undo and redo shortcuts
if (event->type()==QEvent::ShortcutOverride)
{
QKeyEvent *keyEvent = static_cast<QKeyEvent *> (event);
if (keyEvent->matches (QKeySequence::Undo) || keyEvent->matches (QKeySequence::Redo))
return true;
}
return QPlainTextEdit::event (event);
}
CSVWorld::ScriptEdit::ScriptEdit (const CSMDoc::Document& document, ScriptHighlighter::Mode mode, CSVWorld::ScriptEdit::ScriptEdit (const CSMDoc::Document& document, ScriptHighlighter::Mode mode,
QWidget* parent) QWidget* parent)
: QPlainTextEdit (parent), : QPlainTextEdit (parent),
mDocument (document),
mWhiteListQoutes("^[a-z|_]{1}[a-z|0-9|_]{0,}$", Qt::CaseInsensitive),
mChangeLocked (0), mChangeLocked (0),
mLineNumberArea(0),
mShowLineNum(false), mShowLineNum(false),
mLineNumberArea(0),
mDefaultFont(font()), mDefaultFont(font()),
mMonoFont(QFont("Monospace")) mMonoFont(QFont("Monospace")),
mDocument (document),
mWhiteListQoutes("^[a-z|_]{1}[a-z|0-9|_]{0,}$", Qt::CaseInsensitive)
{ {
// setAcceptRichText (false); // setAcceptRichText (false);
setLineWrapMode (QPlainTextEdit::NoWrap); setLineWrapMode (QPlainTextEdit::NoWrap);

View file

@ -53,6 +53,10 @@ namespace CSVWorld
QFont mDefaultFont; QFont mDefaultFont;
QFont mMonoFont; QFont mMonoFont;
protected:
bool event (QEvent *event);
public: public:
ScriptEdit (const CSMDoc::Document& document, ScriptHighlighter::Mode mode, ScriptEdit (const CSMDoc::Document& document, ScriptHighlighter::Mode mode,

View file

@ -253,8 +253,8 @@ void CSVWorld::Table::mouseDoubleClickEvent (QMouseEvent *event)
CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
bool createAndDelete, bool sorting, CSMDoc::Document& document) bool createAndDelete, bool sorting, CSMDoc::Document& document)
: mCreateAction (0), mCloneAction(0), mRecordStatusDisplay (0), : DragRecordTable(document), mCreateAction (0),
DragRecordTable(document) mCloneAction(0),mRecordStatusDisplay (0)
{ {
CSMSettings::UserSettings &settings = CSMSettings::UserSettings::instance(); CSMSettings::UserSettings &settings = CSMSettings::UserSettings::instance();
QString jumpSetting = settings.settingValue ("table-input/jump-to-added"); QString jumpSetting = settings.settingValue ("table-input/jump-to-added");
@ -653,6 +653,10 @@ void CSVWorld::Table::tableSizeUpdate()
} }
emit tableSizeChanged (size, deleted, modified); emit tableSizeChanged (size, deleted, modified);
// not really related to tableSizeUpdate() but placed here for convenience rather than
// creating a bunch of extra connections & slot
mProxyModel->refreshFilter();
} }
void CSVWorld::Table::selectionSizeUpdate() void CSVWorld::Table::selectionSizeUpdate()

View file

@ -3,10 +3,14 @@
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QEvent> #include <QEvent>
#include <QHeaderView>
#include <QApplication>
#include <QDesktopWidget>
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
#include "../../model/world/tablemimedata.hpp" #include "../../model/world/tablemimedata.hpp"
#include "../doc/sizehint.hpp"
#include "../filter/filterbox.hpp" #include "../filter/filterbox.hpp"
#include "table.hpp" #include "table.hpp"
#include "tablebottombox.hpp" #include "tablebottombox.hpp"
@ -30,11 +34,18 @@ CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::D
layout->insertWidget (0, mFilterBox); layout->insertWidget (0, mFilterBox);
QWidget *widget = new QWidget; CSVDoc::SizeHintWidget *widget = new CSVDoc::SizeHintWidget;
widget->setLayout (layout); widget->setLayout (layout);
setWidget (widget); setWidget (widget);
// prefer height of the screen and full width of the table
const QRect rect = QApplication::desktop()->screenGeometry(this);
int frameHeight = 40; // set a reasonable default
QWidget *topLevel = QApplication::topLevelAt(pos());
if (topLevel)
frameHeight = topLevel->frameGeometry().height() - topLevel->height();
widget->setSizeHint(QSize(mTable->horizontalHeader()->length(), rect.height()-frameHeight));
connect (mTable, SIGNAL (editRequest (const CSMWorld::UniversalId&, const std::string&)), connect (mTable, SIGNAL (editRequest (const CSMWorld::UniversalId&, const std::string&)),
this, SLOT (editRequest (const CSMWorld::UniversalId&, const std::string&))); this, SLOT (editRequest (const CSMWorld::UniversalId&, const std::string&)));

View file

@ -9,8 +9,6 @@
#include <QMetaProperty> #include <QMetaProperty>
#include <QStyledItemDelegate> #include <QStyledItemDelegate>
#include <QLineEdit> #include <QLineEdit>
#include <QSpinBox>
#include <QDoubleSpinBox>
#include <QComboBox> #include <QComboBox>
#include <QCheckBox> #include <QCheckBox>
#include <QPlainTextEdit> #include <QPlainTextEdit>
@ -19,7 +17,7 @@
#include "../../model/world/commands.hpp" #include "../../model/world/commands.hpp"
#include "../../model/world/tablemimedata.hpp" #include "../../model/world/tablemimedata.hpp"
#include "../../model/world/commanddispatcher.hpp" #include "../../model/world/commanddispatcher.hpp"
#include "dialoguespinbox.hpp"
#include "scriptedit.hpp" #include "scriptedit.hpp"
CSVWorld::NastyTableModelHack::NastyTableModelHack (QAbstractItemModel& model) CSVWorld::NastyTableModelHack::NastyTableModelHack (QAbstractItemModel& model)
@ -174,7 +172,7 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO
case CSMWorld::ColumnBase::Display_Integer: case CSMWorld::ColumnBase::Display_Integer:
{ {
QSpinBox *sb = new QSpinBox(parent); DialogueSpinBox *sb = new DialogueSpinBox(parent);
sb->setRange(INT_MIN, INT_MAX); sb->setRange(INT_MIN, INT_MAX);
return sb; return sb;
} }
@ -185,7 +183,7 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO
case CSMWorld::ColumnBase::Display_Float: case CSMWorld::ColumnBase::Display_Float:
{ {
QDoubleSpinBox *dsb = new QDoubleSpinBox(parent); DialogueDoubleSpinBox *dsb = new DialogueDoubleSpinBox(parent);
dsb->setRange(-FLT_MAX, FLT_MAX); dsb->setRange(-FLT_MAX, FLT_MAX);
dsb->setSingleStep(0.01f); dsb->setSingleStep(0.01f);
dsb->setDecimals(3); dsb->setDecimals(3);

View file

@ -17,8 +17,8 @@ MWBase::Environment *MWBase::Environment::sThis = 0;
MWBase::Environment::Environment() MWBase::Environment::Environment()
: mWorld (0), mSoundManager (0), mScriptManager (0), mWindowManager (0), : mWorld (0), mSoundManager (0), mScriptManager (0), mWindowManager (0),
mMechanicsManager (0), mDialogueManager (0), mJournal (0), mInputManager (0), mFrameDuration (0), mMechanicsManager (0), mDialogueManager (0), mJournal (0), mInputManager (0), mStateManager (0),
mStateManager (0) mFrameDuration (0)
{ {
assert (!sThis); assert (!sThis);
sThis = this; sThis = this;

View file

@ -286,8 +286,8 @@ namespace MWBase
virtual MWWorld::Ptr moveObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0; virtual MWWorld::Ptr moveObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0;
///< @return an updated Ptr in case the Ptr's cell changes ///< @return an updated Ptr in case the Ptr's cell changes
virtual void virtual MWWorld::Ptr moveObject(const MWWorld::Ptr &ptr, MWWorld::CellStore* newCell, float x, float y, float z) = 0;
moveObject(const MWWorld::Ptr &ptr, MWWorld::CellStore* newCell, float x, float y, float z) = 0; ///< @return an updated Ptr
virtual void scaleObject (const MWWorld::Ptr& ptr, float scale) = 0; virtual void scaleObject (const MWWorld::Ptr& ptr, float scale) = 0;

View file

@ -251,7 +251,7 @@ namespace MWClass
float hitchance = MWMechanics::getHitChance(ptr, victim, ref->mBase->mData.mCombat); float hitchance = MWMechanics::getHitChance(ptr, victim, ref->mBase->mData.mCombat);
if(OEngine::Misc::Rng::rollProbability() >= hitchance/100.0f) if(OEngine::Misc::Rng::roll0to99() >= hitchance)
{ {
victim.getClass().onHit(victim, 0.0f, false, MWWorld::Ptr(), ptr, false); victim.getClass().onHit(victim, 0.0f, false, MWWorld::Ptr(), ptr, false);
MWMechanics::reduceWeaponCondition(0.f, false, weapon, ptr); MWMechanics::reduceWeaponCondition(0.f, false, weapon, ptr);

View file

@ -515,7 +515,7 @@ namespace MWClass
float hitchance = MWMechanics::getHitChance(ptr, victim, ptr.getClass().getSkill(ptr, weapskill)); float hitchance = MWMechanics::getHitChance(ptr, victim, ptr.getClass().getSkill(ptr, weapskill));
if (OEngine::Misc::Rng::rollProbability() >= hitchance / 100.0f) if (OEngine::Misc::Rng::roll0to99() >= hitchance)
{ {
othercls.onHit(victim, 0.0f, false, weapon, ptr, false); othercls.onHit(victim, 0.0f, false, weapon, ptr, false);
MWMechanics::reduceWeaponCondition(0.f, false, weapon, ptr); MWMechanics::reduceWeaponCondition(0.f, false, weapon, ptr);

View file

@ -48,12 +48,15 @@
namespace MWDialogue namespace MWDialogue
{ {
DialogueManager::DialogueManager (const Compiler::Extensions& extensions, bool scriptVerbose, Translation::Storage& translationDataStorage) : DialogueManager::DialogueManager (const Compiler::Extensions& extensions, bool scriptVerbose, Translation::Storage& translationDataStorage) :
mCompilerContext (MWScript::CompilerContext::Type_Dialogue), mTranslationDataStorage(translationDataStorage)
mErrorStream(std::cout.rdbuf()),mErrorHandler(mErrorStream) , mCompilerContext (MWScript::CompilerContext::Type_Dialogue)
, mTemporaryDispositionChange(0.f) , mErrorStream(std::cout.rdbuf())
, mPermanentDispositionChange(0.f), mScriptVerbose (scriptVerbose) , mErrorHandler(mErrorStream)
, mTranslationDataStorage(translationDataStorage)
, mTalkedTo(false) , mTalkedTo(false)
, mTemporaryDispositionChange(0.f)
, mPermanentDispositionChange(0.f)
, mScriptVerbose (scriptVerbose)
{ {
mChoice = -1; mChoice = -1;
mIsInChoice = false; mIsInChoice = false;
@ -485,6 +488,12 @@ namespace MWDialogue
executeScript (info->mResultScript); executeScript (info->mResultScript);
} }
else
{
mChoice = -1;
mIsInChoice = false;
MWBase::Environment::get().getWindowManager()->getDialogueWindow()->clearChoices();
}
} }
} }

View file

@ -26,10 +26,10 @@ namespace MWGui
{ {
AlchemyWindow::AlchemyWindow() AlchemyWindow::AlchemyWindow()
: WindowBase("openmw_alchemy_window.layout") : WindowBase("openmw_alchemy_window.layout")
, mApparatus (4)
, mIngredients (4)
, mSortModel(NULL) , mSortModel(NULL)
, mAlchemy(new MWMechanics::Alchemy()) , mAlchemy(new MWMechanics::Alchemy())
, mApparatus (4)
, mIngredients (4)
{ {
getWidget(mCreateButton, "CreateButton"); getWidget(mCreateButton, "CreateButton");
getWidget(mCancelButton, "CancelButton"); getWidget(mCancelButton, "CancelButton");

View file

@ -228,8 +228,8 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
Typesetter (size_t width, size_t height) : Typesetter (size_t width, size_t height) :
mPageWidth (width), mPageHeight(height), mPageWidth (width), mPageHeight(height),
mSection (NULL), mLine (NULL), mRun (NULL), mSection (NULL), mLine (NULL), mRun (NULL),
mCurrentAlignment (AlignLeft), mCurrentContent (NULL),
mCurrentContent (NULL) mCurrentAlignment (AlignLeft)
{ {
mBook = boost::make_shared <Book> (); mBook = boost::make_shared <Book> ();
} }
@ -697,10 +697,10 @@ namespace
GlyphStream (MyGUI::IFont* font, float left, float top, float Z, GlyphStream (MyGUI::IFont* font, float left, float top, float Z,
MyGUI::Vertex* vertices, RenderXform const & renderXform) : MyGUI::Vertex* vertices, RenderXform const & renderXform) :
mZ(Z), mOrigin (left, top), mZ(Z),
mFont (font), mVertices (vertices), mC(0), mFont (font), mOrigin (left, top),
mRenderXform (renderXform), mVertices (vertices),
mC(0) mRenderXform (renderXform)
{ {
mVertexColourType = MyGUI::RenderManager::getInstance().getVertexFormat(); mVertexColourType = MyGUI::RenderManager::getInstance().getVertexFormat();
} }
@ -801,10 +801,10 @@ protected:
TextFormat (MyGUI::IFont* id, PageDisplay * display) : TextFormat (MyGUI::IFont* id, PageDisplay * display) :
mFont (id), mFont (id),
mCountVertex (0),
mTexture (NULL), mTexture (NULL),
mRenderItem (NULL), mRenderItem (NULL),
mDisplay (display), mDisplay (display)
mCountVertex (0)
{ {
} }

View file

@ -18,9 +18,9 @@ namespace MWGui
BookWindow::BookWindow () BookWindow::BookWindow ()
: WindowBase("openmw_book.layout") : WindowBase("openmw_book.layout")
, mCurrentPage(0)
, mTakeButtonShow(true) , mTakeButtonShow(true)
, mTakeButtonAllowed(true) , mTakeButtonAllowed(true)
, mCurrentPage(0)
{ {
getWidget(mCloseButton, "CloseButton"); getWidget(mCloseButton, "CloseButton");
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onCloseButtonClicked); mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onCloseButtonClicked);

View file

@ -37,11 +37,11 @@ namespace MWGui
CompanionWindow::CompanionWindow(DragAndDrop *dragAndDrop, MessageBoxManager* manager) CompanionWindow::CompanionWindow(DragAndDrop *dragAndDrop, MessageBoxManager* manager)
: WindowBase("openmw_companion_window.layout") : WindowBase("openmw_companion_window.layout")
, mSortModel(NULL)
, mModel(NULL)
, mSelectedItem(-1)
, mDragAndDrop(dragAndDrop) , mDragAndDrop(dragAndDrop)
, mMessageBoxManager(manager) , mMessageBoxManager(manager)
, mSelectedItem(-1)
, mModel(NULL)
, mSortModel(NULL)
{ {
getWidget(mCloseButton, "CloseButton"); getWidget(mCloseButton, "CloseButton");
getWidget(mProfitLabel, "ProfitLabel"); getWidget(mProfitLabel, "ProfitLabel");

View file

@ -33,10 +33,10 @@ namespace MWGui
ContainerWindow::ContainerWindow(DragAndDrop* dragAndDrop) ContainerWindow::ContainerWindow(DragAndDrop* dragAndDrop)
: WindowBase("openmw_container_window.layout") : WindowBase("openmw_container_window.layout")
, mDragAndDrop(dragAndDrop) , mDragAndDrop(dragAndDrop)
, mSelectedItem(-1)
, mModel(NULL)
, mSortModel(NULL)
, mPickpocketDetected(false) , mPickpocketDetected(false)
, mSortModel(NULL)
, mModel(NULL)
, mSelectedItem(-1)
{ {
getWidget(mDisposeCorpseButton, "DisposeCorpseButton"); getWidget(mDisposeCorpseButton, "DisposeCorpseButton");
getWidget(mTakeButton, "TakeButton"); getWidget(mTakeButton, "TakeButton");

View file

@ -248,10 +248,10 @@ namespace MWGui
DialogueWindow::DialogueWindow() DialogueWindow::DialogueWindow()
: WindowBase("openmw_dialogue_window.layout") : WindowBase("openmw_dialogue_window.layout")
, mPersuasionDialog()
, mEnabled(false)
, mServices(0) , mServices(0)
, mEnabled(false)
, mGoodbye(false) , mGoodbye(false)
, mPersuasionDialog()
{ {
// Centre dialog // Centre dialog
center(); center();

View file

@ -20,12 +20,12 @@ namespace MWGui
DragAndDrop::DragAndDrop() DragAndDrop::DragAndDrop()
: mDraggedWidget(NULL) : mIsOnDragAndDrop(false)
, mDraggedCount(0) , mDraggedWidget(NULL)
, mSourceModel(NULL) , mSourceModel(NULL)
, mSourceView(NULL) , mSourceView(NULL)
, mSourceSortModel(NULL) , mSourceSortModel(NULL)
, mIsOnDragAndDrop(false) , mDraggedCount(0)
{ {
} }

View file

@ -50,17 +50,17 @@ namespace MWGui
InventoryWindow::InventoryWindow(DragAndDrop* dragAndDrop) InventoryWindow::InventoryWindow(DragAndDrop* dragAndDrop)
: WindowPinnableBase("openmw_inventory_window.layout") : WindowPinnableBase("openmw_inventory_window.layout")
, mTrading(false) , mDragAndDrop(dragAndDrop)
, mPreviewDirty(true)
, mPreviewResize(true)
, mSelectedItem(-1)
, mSortModel(NULL)
, mTradeModel(NULL)
, mGuiMode(GM_Inventory)
, mLastXSize(0) , mLastXSize(0)
, mLastYSize(0) , mLastYSize(0)
, mPreview(new MWRender::InventoryPreview(MWBase::Environment::get().getWorld ()->getPlayerPtr())) , mPreview(new MWRender::InventoryPreview(MWBase::Environment::get().getWorld ()->getPlayerPtr()))
, mPreviewDirty(true) , mTrading(false)
, mPreviewResize(true)
, mDragAndDrop(dragAndDrop)
, mSortModel(NULL)
, mTradeModel(NULL)
, mSelectedItem(-1)
, mGuiMode(GM_Inventory)
{ {
mMainWidget->castType<MyGUI::Window>()->eventWindowChangeCoord += MyGUI::newDelegate(this, &InventoryWindow::onWindowResize); mMainWidget->castType<MyGUI::Window>()->eventWindowChangeCoord += MyGUI::newDelegate(this, &InventoryWindow::onWindowResize);
@ -594,6 +594,8 @@ namespace MWGui
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
MWBase::Environment::get().getWorld()->breakInvisibility(player); MWBase::Environment::get().getWorld()->breakInvisibility(player);
MWBase::Environment::get().getMechanicsManager()->itemTaken(player, object, MWWorld::Ptr(), count);
// add to player inventory // add to player inventory
// can't use ActionTake here because we need an MWWorld::Ptr to the newly inserted object // can't use ActionTake here because we need an MWWorld::Ptr to the newly inserted object
MWWorld::Ptr newObject = *player.getClass().getContainerStore (player).add (object, object.getRefData().getCount(), player); MWWorld::Ptr newObject = *player.getClass().getContainerStore (player).add (object, object.getRefData().getCount(), player);
@ -612,8 +614,6 @@ namespace MWGui
throw std::runtime_error("Added item not found"); throw std::runtime_error("Added item not found");
mDragAndDrop->startDrag(i, mSortModel, mTradeModel, mItemView, count); mDragAndDrop->startDrag(i, mSortModel, mTradeModel, mItemView, count);
MWBase::Environment::get().getMechanicsManager()->itemTaken(player, newObject, MWWorld::Ptr(), count);
MWBase::Environment::get().getWindowManager()->updateSpellWindow(); MWBase::Environment::get().getWindowManager()->updateSpellWindow();
} }

View file

@ -14,10 +14,10 @@ namespace MWGui
{ {
ItemStack::ItemStack(const MWWorld::Ptr &base, ItemModel *creator, size_t count) ItemStack::ItemStack(const MWWorld::Ptr &base, ItemModel *creator, size_t count)
: mCreator(creator) : mType(Type_Normal)
, mCount(count)
, mFlags(0) , mFlags(0)
, mType(Type_Normal) , mCreator(creator)
, mCount(count)
, mBase(base) , mBase(base)
{ {
if (base.getClass().getEnchantment(base) != "") if (base.getClass().getEnchantment(base) != "")
@ -59,10 +59,10 @@ namespace MWGui
} }
ItemStack::ItemStack() ItemStack::ItemStack()
: mCreator(NULL) : mType(Type_Normal)
, mCount(0)
, mFlags(0) , mFlags(0)
, mType(Type_Normal) , mCreator(NULL)
, mCount(0)
{ {
} }

View file

@ -19,9 +19,9 @@ namespace MWGui
{ {
JailScreen::JailScreen() JailScreen::JailScreen()
: WindowBase("openmw_jail_screen.layout"), : WindowBase("openmw_jail_screen.layout"),
mTimeAdvancer(0.01f),
mDays(1), mDays(1),
mFadeTimeRemaining(0) mFadeTimeRemaining(0),
mTimeAdvancer(0.01f)
{ {
getWidget(mProgressBar, "ProgressBar"); getWidget(mProgressBar, "ProgressBar");

View file

@ -68,8 +68,8 @@ namespace
AddJournalEntry (MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* body_style, AddJournalEntry (MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* body_style,
MWGui::BookTypesetter::Style* header_style, bool add_header) : MWGui::BookTypesetter::Style* header_style, bool add_header) :
AddEntry (typesetter, body_style), AddEntry (typesetter, body_style),
mHeaderStyle (header_style), mAddHeader (add_header),
mAddHeader (add_header) mHeaderStyle (header_style)
{ {
} }
@ -94,7 +94,7 @@ namespace
AddTopicEntry (MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* body_style, AddTopicEntry (MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* body_style,
MWGui::BookTypesetter::Style* header_style, intptr_t contentId) : MWGui::BookTypesetter::Style* header_style, intptr_t contentId) :
AddEntry (typesetter, body_style), mHeaderStyle (header_style), mContentId (contentId) AddEntry (typesetter, body_style), mContentId (contentId), mHeaderStyle (header_style)
{ {
} }

View file

@ -92,7 +92,7 @@ struct JournalViewModelImpl : JournalViewModel
JournalViewModelImpl const * mModel; JournalViewModelImpl const * mModel;
BaseEntry (JournalViewModelImpl const * model, iterator_t itr) : BaseEntry (JournalViewModelImpl const * model, iterator_t itr) :
mModel (model), itr (itr), loaded (false) itr (itr), mModel (model), loaded (false)
{} {}
virtual ~BaseEntry () {} virtual ~BaseEntry () {}

View file

@ -32,11 +32,11 @@ namespace MWGui
{ {
LoadingScreen::LoadingScreen(Ogre::SceneManager* sceneMgr, Ogre::RenderWindow* rw) LoadingScreen::LoadingScreen(Ogre::SceneManager* sceneMgr, Ogre::RenderWindow* rw)
: mSceneMgr(sceneMgr) : WindowBase("openmw_loading_screen.layout")
, mSceneMgr(sceneMgr)
, mWindow(rw) , mWindow(rw)
, WindowBase("openmw_loading_screen.layout")
, mLastRenderTime(0)
, mLastWallpaperChangeTime(0) , mLastWallpaperChangeTime(0)
, mLastRenderTime(0)
, mProgress(0) , mProgress(0)
, mVSyncWasEnabled(false) , mVSyncWasEnabled(false)
{ {

View file

@ -144,16 +144,16 @@ namespace MWGui
: mCurX(0) : mCurX(0)
, mCurY(0) , mCurY(0)
, mInterior(false) , mInterior(false)
, mFogOfWar(true)
, mLocalMap(NULL) , mLocalMap(NULL)
, mCompass(NULL)
, mPrefix() , mPrefix()
, mChanged(true) , mChanged(true)
, mFogOfWar(true)
, mMapWidgetSize(0)
, mCustomMarkers(markers)
, mMarkerUpdateTimer(0.0f)
, mLastDirectionX(0.0f) , mLastDirectionX(0.0f)
, mLastDirectionY(0.0f) , mLastDirectionY(0.0f)
, mCompass(NULL)
, mMarkerUpdateTimer(0.0f)
, mCustomMarkers(markers)
, mMapWidgetSize(0)
{ {
mCustomMarkers.eventMarkersChanged += MyGUI::newDelegate(this, &LocalMapBase::updateCustomMarkers); mCustomMarkers.eventMarkersChanged += MyGUI::newDelegate(this, &LocalMapBase::updateCustomMarkers);
} }
@ -300,17 +300,17 @@ namespace MWGui
MarkerUserData markerPos; MarkerUserData markerPos;
MyGUI::IntPoint widgetPos = getMarkerPosition(marker.mWorldX, marker.mWorldY, markerPos); MyGUI::IntPoint widgetPos = getMarkerPosition(marker.mWorldX, marker.mWorldY, markerPos);
MyGUI::IntCoord widgetCoord(widgetPos.left - 4, MyGUI::IntCoord widgetCoord(widgetPos.left - 8,
widgetPos.top - 4, widgetPos.top - 8,
8, 8); 16, 16);
MarkerWidget* markerWidget = mLocalMap->createWidget<MarkerWidget>("MarkerButton", MarkerWidget* markerWidget = mLocalMap->createWidget<MarkerWidget>("CustomMarkerButton",
widgetCoord, MyGUI::Align::Default); widgetCoord, MyGUI::Align::Default);
markerWidget->setDepth(Local_MarkerAboveFogLayer); markerWidget->setDepth(Local_MarkerAboveFogLayer);
markerWidget->setUserString("ToolTipType", "Layout"); markerWidget->setUserString("ToolTipType", "Layout");
markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine"); markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
markerWidget->setUserString("Caption_TextOneLine", MyGUI::TextIterator::toTagsString(marker.mNote)); markerWidget->setUserString("Caption_TextOneLine", MyGUI::TextIterator::toTagsString(marker.mNote));
markerWidget->setNormalColour(MyGUI::Colour(1.0f, 0.3f, 0.3f)); markerWidget->setNormalColour(MyGUI::Colour(0.6f, 0.6f, 0.6f));
markerWidget->setHoverColour(MyGUI::Colour(1.0f, 0.5f, 0.5f)); markerWidget->setHoverColour(MyGUI::Colour(1.0f, 1.0f, 1.0f));
markerWidget->setUserData(marker); markerWidget->setUserData(marker);
markerWidget->setNeedMouseFocus(true); markerWidget->setNeedMouseFocus(true);
customMarkerCreated(markerWidget); customMarkerCreated(markerWidget);
@ -468,21 +468,17 @@ namespace MWGui
return; return;
std::string markerTexture; std::string markerTexture;
MyGUI::Colour markerColour;
if (type == MWBase::World::Detect_Creature) if (type == MWBase::World::Detect_Creature)
{ {
markerTexture = "textures\\menu_map_dcreature.dds"; markerTexture = "textures\\detect_animal_icon.dds";
markerColour = MyGUI::Colour(1,0,0,1);
} }
if (type == MWBase::World::Detect_Key) if (type == MWBase::World::Detect_Key)
{ {
markerTexture = "textures\\menu_map_dkey.dds"; markerTexture = "textures\\detect_key_icon.dds";
markerColour = MyGUI::Colour(0,1,0,1);
} }
if (type == MWBase::World::Detect_Enchantment) if (type == MWBase::World::Detect_Enchantment)
{ {
markerTexture = "textures\\menu_map_dmagic.dds"; markerTexture = "textures\\detect_enchantment_icon.dds";
markerColour = MyGUI::Colour(0,0,1,1);
} }
int counter = 0; int counter = 0;
@ -499,7 +495,7 @@ namespace MWGui
widgetCoord, MyGUI::Align::Default); widgetCoord, MyGUI::Align::Default);
markerWidget->setDepth(Local_MarkerAboveFogLayer); markerWidget->setDepth(Local_MarkerAboveFogLayer);
markerWidget->setImageTexture(markerTexture); markerWidget->setImageTexture(markerTexture);
markerWidget->setColour(markerColour); markerWidget->setImageCoord(MyGUI::IntCoord(0,0,8,8));
markerWidget->setNeedMouseFocus(false); markerWidget->setNeedMouseFocus(false);
mMagicMarkerWidgets.push_back(markerWidget); mMagicMarkerWidgets.push_back(markerWidget);
} }
@ -554,16 +550,16 @@ namespace MWGui
MapWindow::MapWindow(CustomMarkerCollection &customMarkers, DragAndDrop* drag, const std::string& cacheDir) MapWindow::MapWindow(CustomMarkerCollection &customMarkers, DragAndDrop* drag, const std::string& cacheDir)
: WindowPinnableBase("openmw_map_window.layout") : WindowPinnableBase("openmw_map_window.layout")
, NoDrop(drag, mMainWidget)
, LocalMapBase(customMarkers) , LocalMapBase(customMarkers)
, mGlobal(false) , NoDrop(drag, mMainWidget)
, mGlobalMap(0) , mGlobalMap(0)
, mGlobalMapRender(0)
, mEditNoteDialog()
, mEventBoxGlobal(NULL)
, mEventBoxLocal(NULL)
, mGlobalMapImage(NULL) , mGlobalMapImage(NULL)
, mGlobalMapOverlay(NULL) , mGlobalMapOverlay(NULL)
, mGlobal(false)
, mEventBoxGlobal(NULL)
, mEventBoxLocal(NULL)
, mGlobalMapRender(0)
, mEditNoteDialog()
{ {
static bool registered = false; static bool registered = false;
if (!registered) if (!registered)

View file

@ -161,10 +161,10 @@ namespace MWGui
MessageBox::MessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message) MessageBox::MessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message)
: Layout("openmw_messagebox.layout") : Layout("openmw_messagebox.layout")
, mMessageBoxManager(parMessageBoxManager)
, mMessage(message)
, mCurrentTime(0) , mCurrentTime(0)
, mMaxTime(0) , mMaxTime(0)
, mMessageBoxManager(parMessageBoxManager)
, mMessage(message)
{ {
// defines // defines
mBottomPadding = 48; mBottomPadding = 48;
@ -195,8 +195,8 @@ namespace MWGui
InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message, const std::vector<std::string>& buttons) InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message, const std::vector<std::string>& buttons)
: WindowModal("openmw_interactive_messagebox.layout") : WindowModal("openmw_interactive_messagebox.layout")
, mMessageBoxManager(parMessageBoxManager) , mMessageBoxManager(parMessageBoxManager)
, mButtonPressed(-1)
, mTextButtonPadding(0) , mTextButtonPadding(0)
, mButtonPressed(-1)
{ {
WindowModal::open(); WindowModal::open();

View file

@ -20,7 +20,7 @@ namespace MWGui
{ {
for (size_t i = 0; i<mSourceModel->getItemCount(); ++i) for (size_t i = 0; i<mSourceModel->getItemCount(); ++i)
{ {
if (chance <= OEngine::Misc::Rng::roll0to99()) if (OEngine::Misc::Rng::roll0to99() > chance)
mHiddenItems.push_back(mSourceModel->getItem(i)); mHiddenItems.push_back(mSourceModel->getItem(i));
} }
} }

View file

@ -70,9 +70,9 @@ namespace MWGui
SortFilterItemModel::SortFilterItemModel(ItemModel *sourceModel) SortFilterItemModel::SortFilterItemModel(ItemModel *sourceModel)
: mCategory(Category_All) : mCategory(Category_All)
, mFilter(0)
, mShowEquipped(true) , mShowEquipped(true)
, mSortByType(true) , mSortByType(true)
, mFilter(0)
{ {
mSourceModel = sourceModel; mSourceModel = sourceModel;
} }

View file

@ -23,8 +23,8 @@ namespace MWGui
SpellBuyingWindow::SpellBuyingWindow() : SpellBuyingWindow::SpellBuyingWindow() :
WindowBase("openmw_spell_buying_window.layout") WindowBase("openmw_spell_buying_window.layout")
, mCurrentY(0)
, mLastPos(0) , mLastPos(0)
, mCurrentY(0)
{ {
setCoord(0, 0, 450, 300); setCoord(0, 0, 450, 300);
@ -127,13 +127,7 @@ namespace MWGui
bool SpellBuyingWindow::playerHasSpell(const std::string &id) bool SpellBuyingWindow::playerHasSpell(const std::string &id)
{ {
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
MWMechanics::Spells& playerSpells = player.getClass().getCreatureStats (player).getSpells(); return player.getClass().getCreatureStats(player).getSpells().hasSpell(id);
for (MWMechanics::Spells::TIterator it = playerSpells.begin(); it != playerSpells.end(); ++it)
{
if (Misc::StringUtils::ciEqual(id, it->first))
return true;
}
return false;
} }
void SpellBuyingWindow::onSpellButtonClick(MyGUI::Widget* _sender) void SpellBuyingWindow::onSpellButtonClick(MyGUI::Widget* _sender)

View file

@ -483,15 +483,15 @@ namespace MWGui
EffectEditorBase::EffectEditorBase(Type type) EffectEditorBase::EffectEditorBase(Type type)
: mAddEffectDialog() : mAvailableEffectsList(NULL)
, mAvailableEffectsList(NULL)
, mUsedEffectsView(NULL) , mUsedEffectsView(NULL)
, mAddEffectDialog()
, mSelectAttributeDialog(NULL) , mSelectAttributeDialog(NULL)
, mSelectSkillDialog(NULL) , mSelectSkillDialog(NULL)
, mSelectedEffect(0) , mSelectedEffect(0)
, mSelectedKnownEffectId(0) , mSelectedKnownEffectId(0)
, mType(type)
, mConstantEffect(false) , mConstantEffect(false)
, mType(type)
{ {
mAddEffectDialog.eventEffectAdded += MyGUI::newDelegate(this, &EffectEditorBase::onEffectAdded); mAddEffectDialog.eventEffectAdded += MyGUI::newDelegate(this, &EffectEditorBase::onEffectAdded);
mAddEffectDialog.eventEffectModified += MyGUI::newDelegate(this, &EffectEditorBase::onEffectModified); mAddEffectDialog.eventEffectModified += MyGUI::newDelegate(this, &EffectEditorBase::onEffectModified);

View file

@ -30,15 +30,15 @@ namespace MWGui
ToolTips::ToolTips() : ToolTips::ToolTips() :
Layout("openmw_tooltips.layout") Layout("openmw_tooltips.layout")
, mFullHelp(false)
, mEnabled(true)
, mFocusToolTipX(0.0) , mFocusToolTipX(0.0)
, mFocusToolTipY(0.0) , mFocusToolTipY(0.0)
, mHorizontalScrollIndex(0)
, mDelay(0.0) , mDelay(0.0)
, mRemainingDelay(0.0) , mRemainingDelay(0.0)
, mLastMouseX(0) , mLastMouseX(0)
, mLastMouseY(0) , mLastMouseY(0)
, mHorizontalScrollIndex(0) , mEnabled(true)
, mFullHelp(false)
{ {
getWidget(mDynamicToolTipBox, "DynamicToolTipBox"); getWidget(mDynamicToolTipBox, "DynamicToolTipBox");

View file

@ -50,13 +50,13 @@ namespace MWGui
WaitDialog::WaitDialog() WaitDialog::WaitDialog()
: WindowBase("openmw_wait_dialog.layout") : WindowBase("openmw_wait_dialog.layout")
, mProgressBar()
, mTimeAdvancer(0.05f) , mTimeAdvancer(0.05f)
, mSleeping(false) , mSleeping(false)
, mHours(1) , mHours(1)
, mManualHours(1) , mManualHours(1)
, mFadeTimeRemaining(0) , mFadeTimeRemaining(0)
, mInterruptAt(-1) , mInterruptAt(-1)
, mProgressBar()
{ {
getWidget(mDateTimeText, "DateTimeText"); getWidget(mDateTimeText, "DateTimeText");
getWidget(mRestText, "RestText"); getWidget(mRestText, "RestText");
@ -155,8 +155,9 @@ namespace MWGui
if (!region->mSleepList.empty()) if (!region->mSleepList.empty())
{ {
// figure out if player will be woken while sleeping // figure out if player will be woken while sleeping
int x = OEngine::Misc::Rng::rollDice(hoursToWait);
float fSleepRandMod = world->getStore().get<ESM::GameSetting>().find("fSleepRandMod")->getFloat(); float fSleepRandMod = world->getStore().get<ESM::GameSetting>().find("fSleepRandMod")->getFloat();
if (OEngine::Misc::Rng::rollProbability() > fSleepRandMod) if (x < fSleepRandMod * hoursToWait)
{ {
float fSleepRestMod = world->getStore().get<ESM::GameSetting>().find("fSleepRestMod")->getFloat(); float fSleepRestMod = world->getStore().get<ESM::GameSetting>().find("fSleepRestMod")->getFloat();
mInterruptAt = hoursToWait - int(fSleepRestMod * hoursToWait); mInterruptAt = hoursToWait - int(fSleepRestMod * hoursToWait);

View file

@ -78,7 +78,7 @@ void WindowModal::close()
} }
NoDrop::NoDrop(DragAndDrop *drag, MyGUI::Widget *widget) NoDrop::NoDrop(DragAndDrop *drag, MyGUI::Widget *widget)
: mDrag(drag), mWidget(widget), mTransparent(false) : mWidget(widget), mDrag(drag), mTransparent(false)
{ {
if (!mWidget) if (!mWidget)
throw std::runtime_error("NoDrop needs a non-NULL widget!"); throw std::runtime_error("NoDrop needs a non-NULL widget!");

View file

@ -13,7 +13,7 @@
#include "steering.hpp" #include "steering.hpp"
MWMechanics::AiAvoidDoor::AiAvoidDoor(const MWWorld::Ptr& doorPtr) MWMechanics::AiAvoidDoor::AiAvoidDoor(const MWWorld::Ptr& doorPtr)
: AiPackage(), mDoorPtr(doorPtr), mDuration(1), mAdjAngle(0) : AiPackage(), mDuration(1), mDoorPtr(doorPtr), mAdjAngle(0)
{ {
} }

View file

@ -111,17 +111,17 @@ namespace MWMechanics
mTimerAttack(0), mTimerAttack(0),
mTimerReact(0), mTimerReact(0),
mTimerCombatMove(0), mTimerCombatMove(0),
mReadyToAttack(false),
mAttack(false), mAttack(false),
mFollowTarget(false), mFollowTarget(false),
mCombatMove(false), mCombatMove(false),
mReadyToAttack(false), mLastTargetPos(0,0,0),
mForceNoShortcut(false),
mCell(NULL), mCell(NULL),
mCurrentAction(), mCurrentAction(),
mActionCooldown(0), mActionCooldown(0),
mStrength(), mStrength(),
mMinMaxAttackDurationInitialised(false), mMinMaxAttackDurationInitialised(false),
mLastTargetPos(0,0,0), mForceNoShortcut(false),
mLastActorPos(0,0,0), mLastActorPos(0,0,0),
mMovement(){} mMovement(){}
}; };

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