mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-23 06:41:08 +00:00
Merge branch 'master' of https://github.com/OpenMW/openmw into osg
Conflicts: apps/opencs/CMakeLists.txt apps/opencs/main.cpp apps/openmw/mwworld/player.hpp
This commit is contained in:
commit
a5670b5133
@ -41,9 +41,9 @@ namespace ESSImport
|
|||||||
{
|
{
|
||||||
for (int i=0; i<ESM::Skill::Length; ++i)
|
for (int i=0; i<ESM::Skill::Length; ++i)
|
||||||
{
|
{
|
||||||
npcStats.mSkills[i].mRegular.mMod = actorData.mSkills[i][1];
|
npcStats.mSkills[i].mMod = actorData.mSkills[i][1];
|
||||||
npcStats.mSkills[i].mRegular.mCurrent = actorData.mSkills[i][1];
|
npcStats.mSkills[i].mCurrent = actorData.mSkills[i][1];
|
||||||
npcStats.mSkills[i].mRegular.mBase = actorData.mSkills[i][0];
|
npcStats.mSkills[i].mBase = actorData.mSkills[i][0];
|
||||||
}
|
}
|
||||||
|
|
||||||
npcStats.mTimeToStartDrowning = actorData.mACDT.mBreathMeter;
|
npcStats.mTimeToStartDrowning = actorData.mACDT.mBreathMeter;
|
||||||
|
@ -18,7 +18,7 @@ namespace ESSImport
|
|||||||
for (int i=0; i<8; ++i)
|
for (int i=0; i<8; ++i)
|
||||||
out.mObject.mNpcStats.mSkillIncrease[i] = pcdt.mPNAM.mSkillIncreases[i];
|
out.mObject.mNpcStats.mSkillIncrease[i] = pcdt.mPNAM.mSkillIncreases[i];
|
||||||
for (int i=0; i<27; ++i)
|
for (int i=0; i<27; ++i)
|
||||||
out.mObject.mNpcStats.mSkills[i].mRegular.mProgress = pcdt.mPNAM.mSkillProgress[i];
|
out.mObject.mNpcStats.mSkills[i].mProgress = pcdt.mPNAM.mSkillProgress[i];
|
||||||
out.mObject.mNpcStats.mLevelProgress = pcdt.mPNAM.mLevelProgress;
|
out.mObject.mNpcStats.mLevelProgress = pcdt.mPNAM.mLevelProgress;
|
||||||
|
|
||||||
if (pcdt.mPNAM.mDrawState & PCDT::DrawState_Weapon)
|
if (pcdt.mPNAM.mDrawState & PCDT::DrawState_Weapon)
|
||||||
|
@ -70,11 +70,12 @@ opencs_units (view/world
|
|||||||
opencs_units_noqt (view/world
|
opencs_units_noqt (view/world
|
||||||
subviews enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate
|
subviews enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate
|
||||||
scripthighlighter idvalidator dialoguecreator idcompletiondelegate
|
scripthighlighter idvalidator dialoguecreator idcompletiondelegate
|
||||||
|
colordelegate
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units (view/widget
|
opencs_units (view/widget
|
||||||
scenetoolbar scenetool scenetoolmode pushbutton scenetooltoggle scenetoolrun modebutton
|
scenetoolbar scenetool scenetoolmode pushbutton scenetooltoggle scenetoolrun modebutton
|
||||||
scenetooltoggle2 completerpopup
|
scenetooltoggle2 completerpopup coloreditor colorpickerpopup
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units (view/render
|
opencs_units (view/render
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QMetaType>
|
#include <QMetaType>
|
||||||
|
|
||||||
|
#include "model/doc/messages.hpp"
|
||||||
|
|
||||||
#include "model/world/universalid.hpp"
|
#include "model/world/universalid.hpp"
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
@ -51,6 +53,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
qRegisterMetaType<std::string> ("std::string");
|
qRegisterMetaType<std::string> ("std::string");
|
||||||
qRegisterMetaType<CSMWorld::UniversalId> ("CSMWorld::UniversalId");
|
qRegisterMetaType<CSMWorld::UniversalId> ("CSMWorld::UniversalId");
|
||||||
|
qRegisterMetaType<CSMDoc::Message> ("CSMDoc::Message");
|
||||||
|
|
||||||
Application application (argc, argv);
|
Application application (argc, argv);
|
||||||
|
|
||||||
|
@ -2302,8 +2302,8 @@ CSMDoc::Document::Document (const VFS::Manager* vfs, const Files::ConfigurationM
|
|||||||
connect (&mSaving, SIGNAL (done (int, bool)), this, SLOT (operationDone (int, bool)));
|
connect (&mSaving, SIGNAL (done (int, bool)), this, SLOT (operationDone (int, bool)));
|
||||||
|
|
||||||
connect (
|
connect (
|
||||||
&mSaving, SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)),
|
&mSaving, SIGNAL (reportMessage (const CSMDoc::Message&, int)),
|
||||||
this, SLOT (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)));
|
this, SLOT (reportMessage (const CSMDoc::Message&, int)));
|
||||||
|
|
||||||
connect (&mRunner, SIGNAL (runStateChanged()), this, SLOT (runStateChanged()));
|
connect (&mRunner, SIGNAL (runStateChanged()), this, SLOT (runStateChanged()));
|
||||||
}
|
}
|
||||||
@ -2404,11 +2404,10 @@ void CSMDoc::Document::modificationStateChanged (bool clean)
|
|||||||
emit stateChanged (getState(), this);
|
emit stateChanged (getState(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMDoc::Document::reportMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
void CSMDoc::Document::reportMessage (const CSMDoc::Message& message, int type)
|
||||||
const std::string& hint, int type)
|
|
||||||
{
|
{
|
||||||
/// \todo find a better way to get these messages to the user.
|
/// \todo find a better way to get these messages to the user.
|
||||||
std::cout << message << std::endl;
|
std::cout << message.mMessage << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMDoc::Document::operationDone (int type, bool failed)
|
void CSMDoc::Document::operationDone (int type, bool failed)
|
||||||
|
@ -160,8 +160,7 @@ namespace CSMDoc
|
|||||||
|
|
||||||
void modificationStateChanged (bool clean);
|
void modificationStateChanged (bool clean);
|
||||||
|
|
||||||
void reportMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
void reportMessage (const CSMDoc::Message& message, int type);
|
||||||
const std::string& hint, int type);
|
|
||||||
|
|
||||||
void operationDone (int type, bool failed);
|
void operationDone (int type, bool failed);
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ void CSMDoc::Loader::load()
|
|||||||
{
|
{
|
||||||
if (iter->second.mRecordsLeft)
|
if (iter->second.mRecordsLeft)
|
||||||
{
|
{
|
||||||
CSMDoc::Messages messages;
|
Messages messages (Message::Severity_Error);
|
||||||
for (int i=0; i<batchingSize; ++i) // do not flood the system with update signals
|
for (int i=0; i<batchingSize; ++i) // do not flood the system with update signals
|
||||||
if (document->getData().continueLoading (messages))
|
if (document->getData().continueLoading (messages))
|
||||||
{
|
{
|
||||||
@ -68,7 +68,7 @@ void CSMDoc::Loader::load()
|
|||||||
for (CSMDoc::Messages::Iterator iter (messages.begin());
|
for (CSMDoc::Messages::Iterator iter (messages.begin());
|
||||||
iter!=messages.end(); ++iter)
|
iter!=messages.end(); ++iter)
|
||||||
{
|
{
|
||||||
document->getReport (log)->add (iter->mId, iter->mMessage);
|
document->getReport (log)->add (*iter);
|
||||||
emit loadMessage (document, iter->mMessage);
|
emit loadMessage (document, iter->mMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,25 @@
|
|||||||
|
|
||||||
#include "messages.hpp"
|
#include "messages.hpp"
|
||||||
|
|
||||||
void CSMDoc::Messages::add (const CSMWorld::UniversalId& id, const std::string& message,
|
CSMDoc::Message::Message() {}
|
||||||
const std::string& hint)
|
|
||||||
{
|
|
||||||
Message data;
|
|
||||||
data.mId = id;
|
|
||||||
data.mMessage = message;
|
|
||||||
data.mHint = hint;
|
|
||||||
|
|
||||||
mMessages.push_back (data);
|
CSMDoc::Message::Message (const CSMWorld::UniversalId& id, const std::string& message,
|
||||||
|
const std::string& hint, Severity severity)
|
||||||
|
: mId (id), mMessage (message), mHint (hint), mSeverity (severity)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
CSMDoc::Messages::Messages (Message::Severity default_)
|
||||||
|
: mDefault (default_)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void CSMDoc::Messages::add (const CSMWorld::UniversalId& id, const std::string& message,
|
||||||
|
const std::string& hint, Message::Severity severity)
|
||||||
|
{
|
||||||
|
if (severity==Message::Severity_Default)
|
||||||
|
severity = mDefault;
|
||||||
|
|
||||||
|
mMessages.push_back (Message (id, message, hint, severity));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMDoc::Messages::push_back (const std::pair<CSMWorld::UniversalId, std::string>& data)
|
void CSMDoc::Messages::push_back (const std::pair<CSMWorld::UniversalId, std::string>& data)
|
||||||
|
@ -4,20 +4,41 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <QMetaType>
|
||||||
|
|
||||||
#include "../world/universalid.hpp"
|
#include "../world/universalid.hpp"
|
||||||
|
|
||||||
namespace CSMDoc
|
namespace CSMDoc
|
||||||
{
|
{
|
||||||
|
struct Message
|
||||||
|
{
|
||||||
|
enum Severity
|
||||||
|
{
|
||||||
|
Severity_Info = 0, // no problem
|
||||||
|
Severity_Warning = 1, // a potential problem, but we are probably fine
|
||||||
|
Severity_Error = 2, // an error; we are not fine
|
||||||
|
Severity_SeriousError = 3, // an error so bad we can't even be sure if we are
|
||||||
|
// reporting it correctly
|
||||||
|
Severity_Default = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
CSMWorld::UniversalId mId;
|
||||||
|
std::string mMessage;
|
||||||
|
std::string mHint;
|
||||||
|
Severity mSeverity;
|
||||||
|
|
||||||
|
Message();
|
||||||
|
|
||||||
|
Message (const CSMWorld::UniversalId& id, const std::string& message,
|
||||||
|
const std::string& hint, Severity severity);
|
||||||
|
};
|
||||||
|
|
||||||
class Messages
|
class Messages
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
struct Message
|
// \deprecated Use CSMDoc::Message directly instead.
|
||||||
{
|
typedef CSMDoc::Message Message;
|
||||||
CSMWorld::UniversalId mId;
|
|
||||||
std::string mMessage;
|
|
||||||
std::string mHint;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::vector<Message> Collection;
|
typedef std::vector<Message> Collection;
|
||||||
|
|
||||||
@ -26,11 +47,15 @@ namespace CSMDoc
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
Collection mMessages;
|
Collection mMessages;
|
||||||
|
Message::Severity mDefault;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
Messages (Message::Severity default_);
|
||||||
|
|
||||||
void add (const CSMWorld::UniversalId& id, const std::string& message,
|
void add (const CSMWorld::UniversalId& id, const std::string& message,
|
||||||
const std::string& hint = "");
|
const std::string& hint = "",
|
||||||
|
Message::Severity severity = Message::Severity_Default);
|
||||||
|
|
||||||
/// \deprecated Use add instead.
|
/// \deprecated Use add instead.
|
||||||
void push_back (const std::pair<CSMWorld::UniversalId, std::string>& data);
|
void push_back (const std::pair<CSMWorld::UniversalId, std::string>& data);
|
||||||
@ -41,4 +66,6 @@ namespace CSMDoc
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE (CSMDoc::Message)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
#include "../world/universalid.hpp"
|
#include "../world/universalid.hpp"
|
||||||
|
#include "../settings/usersettings.hpp"
|
||||||
|
|
||||||
#include "state.hpp"
|
#include "state.hpp"
|
||||||
#include "stage.hpp"
|
#include "stage.hpp"
|
||||||
@ -23,13 +24,17 @@ void CSMDoc::Operation::prepareStages()
|
|||||||
{
|
{
|
||||||
iter->second = iter->first->setup();
|
iter->second = iter->first->setup();
|
||||||
mTotalSteps += iter->second;
|
mTotalSteps += iter->second;
|
||||||
|
|
||||||
|
for (std::map<QString, QStringList>::const_iterator iter2 (mSettings.begin()); iter2!=mSettings.end(); ++iter2)
|
||||||
|
iter->first->updateUserSetting (iter2->first, iter2->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMDoc::Operation::Operation (int type, bool ordered, bool finalAlways)
|
CSMDoc::Operation::Operation (int type, bool ordered, bool finalAlways)
|
||||||
: mType (type), mStages(std::vector<std::pair<Stage *, int> >()), mCurrentStage(mStages.begin()),
|
: mType (type), mStages(std::vector<std::pair<Stage *, int> >()), mCurrentStage(mStages.begin()),
|
||||||
mCurrentStep(0), mCurrentStepTotal(0), mTotalSteps(0), mOrdered (ordered),
|
mCurrentStep(0), mCurrentStepTotal(0), mTotalSteps(0), mOrdered (ordered),
|
||||||
mFinalAlways (finalAlways), mError(false), mConnected (false)
|
mFinalAlways (finalAlways), mError(false), mConnected (false), mPrepared (false),
|
||||||
|
mDefaultSeverity (Message::Severity_Error)
|
||||||
{
|
{
|
||||||
mTimer = new QTimer (this);
|
mTimer = new QTimer (this);
|
||||||
}
|
}
|
||||||
@ -49,8 +54,8 @@ void CSMDoc::Operation::run()
|
|||||||
connect (mTimer, SIGNAL (timeout()), this, SLOT (executeStage()));
|
connect (mTimer, SIGNAL (timeout()), this, SLOT (executeStage()));
|
||||||
mConnected = true;
|
mConnected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareStages();
|
mPrepared = false;
|
||||||
|
|
||||||
mTimer->start (0);
|
mTimer->start (0);
|
||||||
}
|
}
|
||||||
@ -60,6 +65,19 @@ void CSMDoc::Operation::appendStage (Stage *stage)
|
|||||||
mStages.push_back (std::make_pair (stage, 0));
|
mStages.push_back (std::make_pair (stage, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSMDoc::Operation::configureSettings (const std::vector<QString>& settings)
|
||||||
|
{
|
||||||
|
for (std::vector<QString>::const_iterator iter (settings.begin()); iter!=settings.end(); ++iter)
|
||||||
|
{
|
||||||
|
mSettings.insert (std::make_pair (*iter, CSMSettings::UserSettings::instance().definitions (*iter)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMDoc::Operation::setDefaultSeverity (Message::Severity severity)
|
||||||
|
{
|
||||||
|
mDefaultSeverity = severity;
|
||||||
|
}
|
||||||
|
|
||||||
bool CSMDoc::Operation::hasError() const
|
bool CSMDoc::Operation::hasError() const
|
||||||
{
|
{
|
||||||
return mError;
|
return mError;
|
||||||
@ -84,9 +102,23 @@ void CSMDoc::Operation::abort()
|
|||||||
mCurrentStage = mStages.end();
|
mCurrentStage = mStages.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSMDoc::Operation::updateUserSetting (const QString& name, const QStringList& value)
|
||||||
|
{
|
||||||
|
std::map<QString, QStringList>::iterator iter = mSettings.find (name);
|
||||||
|
|
||||||
|
if (iter!=mSettings.end())
|
||||||
|
iter->second = value;
|
||||||
|
}
|
||||||
|
|
||||||
void CSMDoc::Operation::executeStage()
|
void CSMDoc::Operation::executeStage()
|
||||||
{
|
{
|
||||||
Messages messages;
|
if (!mPrepared)
|
||||||
|
{
|
||||||
|
prepareStages();
|
||||||
|
mPrepared = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Messages messages (mDefaultSeverity);
|
||||||
|
|
||||||
while (mCurrentStage!=mStages.end())
|
while (mCurrentStage!=mStages.end())
|
||||||
{
|
{
|
||||||
@ -103,7 +135,7 @@ void CSMDoc::Operation::executeStage()
|
|||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
emit reportMessage (CSMWorld::UniversalId(), e.what(), "", mType);
|
emit reportMessage (Message (CSMWorld::UniversalId(), e.what(), "", Message::Severity_SeriousError), mType);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +147,7 @@ void CSMDoc::Operation::executeStage()
|
|||||||
emit progress (mCurrentStepTotal, mTotalSteps ? mTotalSteps : 1, mType);
|
emit progress (mCurrentStepTotal, mTotalSteps ? mTotalSteps : 1, mType);
|
||||||
|
|
||||||
for (Messages::Iterator iter (messages.begin()); iter!=messages.end(); ++iter)
|
for (Messages::Iterator iter (messages.begin()); iter!=messages.end(); ++iter)
|
||||||
emit reportMessage (iter->mId, iter->mMessage, iter->mHint, mType);
|
emit reportMessage (*iter, mType);
|
||||||
|
|
||||||
if (mCurrentStage==mStages.end())
|
if (mCurrentStage==mStages.end())
|
||||||
operationDone();
|
operationDone();
|
||||||
|
@ -2,9 +2,13 @@
|
|||||||
#define CSM_DOC_OPERATION_H
|
#define CSM_DOC_OPERATION_H
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
#include "messages.hpp"
|
||||||
|
|
||||||
namespace CSMWorld
|
namespace CSMWorld
|
||||||
{
|
{
|
||||||
@ -30,6 +34,9 @@ namespace CSMDoc
|
|||||||
bool mError;
|
bool mError;
|
||||||
bool mConnected;
|
bool mConnected;
|
||||||
QTimer *mTimer;
|
QTimer *mTimer;
|
||||||
|
std::map<QString, QStringList> mSettings;
|
||||||
|
bool mPrepared;
|
||||||
|
Message::Severity mDefaultSeverity;
|
||||||
|
|
||||||
void prepareStages();
|
void prepareStages();
|
||||||
|
|
||||||
@ -46,14 +53,21 @@ namespace CSMDoc
|
|||||||
///
|
///
|
||||||
/// \attention Do no call this function while this Operation is running.
|
/// \attention Do no call this function while this Operation is running.
|
||||||
|
|
||||||
|
/// Specify settings to be passed on to stages.
|
||||||
|
///
|
||||||
|
/// \attention Do no call this function while this Operation is running.
|
||||||
|
void configureSettings (const std::vector<QString>& settings);
|
||||||
|
|
||||||
|
/// \attention Do no call this function while this Operation is running.
|
||||||
|
void setDefaultSeverity (Message::Severity severity);
|
||||||
|
|
||||||
bool hasError() const;
|
bool hasError() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void progress (int current, int max, int type);
|
void progress (int current, int max, int type);
|
||||||
|
|
||||||
void reportMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
void reportMessage (const CSMDoc::Message& message, int type);
|
||||||
const std::string& hint, int type);
|
|
||||||
|
|
||||||
void done (int type, bool failed);
|
void done (int type, bool failed);
|
||||||
|
|
||||||
@ -63,6 +77,8 @@ namespace CSMDoc
|
|||||||
|
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
|
void updateUserSetting (const QString& name, const QStringList& value);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void executeStage();
|
void executeStage();
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
|
||||||
#include "operationholder.hpp"
|
#include "operationholder.hpp"
|
||||||
|
|
||||||
|
#include "../settings/usersettings.hpp"
|
||||||
|
|
||||||
#include "operation.hpp"
|
#include "operation.hpp"
|
||||||
|
|
||||||
CSMDoc::OperationHolder::OperationHolder (Operation *operation) : mRunning (false)
|
CSMDoc::OperationHolder::OperationHolder (Operation *operation) : mRunning (false)
|
||||||
@ -19,8 +21,8 @@ void CSMDoc::OperationHolder::setOperation (Operation *operation)
|
|||||||
this, SIGNAL (progress (int, int, int)));
|
this, SIGNAL (progress (int, int, int)));
|
||||||
|
|
||||||
connect (
|
connect (
|
||||||
mOperation, SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)),
|
mOperation, SIGNAL (reportMessage (const CSMDoc::Message&, int)),
|
||||||
this, SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)));
|
this, SIGNAL (reportMessage (const CSMDoc::Message&, int)));
|
||||||
|
|
||||||
connect (
|
connect (
|
||||||
mOperation, SIGNAL (done (int, bool)),
|
mOperation, SIGNAL (done (int, bool)),
|
||||||
@ -29,6 +31,9 @@ void CSMDoc::OperationHolder::setOperation (Operation *operation)
|
|||||||
connect (this, SIGNAL (abortSignal()), mOperation, SLOT (abort()));
|
connect (this, SIGNAL (abortSignal()), mOperation, SLOT (abort()));
|
||||||
|
|
||||||
connect (&mThread, SIGNAL (started()), mOperation, SLOT (run()));
|
connect (&mThread, SIGNAL (started()), mOperation, SLOT (run()));
|
||||||
|
|
||||||
|
connect (&CSMSettings::UserSettings::instance(), SIGNAL (userSettingUpdated (const QString&, const QStringList&)),
|
||||||
|
mOperation, SLOT (updateUserSetting (const QString&, const QStringList&)));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSMDoc::OperationHolder::isRunning() const
|
bool CSMDoc::OperationHolder::isRunning() const
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
|
||||||
|
#include "messages.hpp"
|
||||||
|
|
||||||
namespace CSMWorld
|
namespace CSMWorld
|
||||||
{
|
{
|
||||||
class UniversalId;
|
class UniversalId;
|
||||||
@ -44,8 +46,7 @@ namespace CSMDoc
|
|||||||
|
|
||||||
void progress (int current, int max, int type);
|
void progress (int current, int max, int type);
|
||||||
|
|
||||||
void reportMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
void reportMessage (const CSMDoc::Message& message, int type);
|
||||||
const std::string& hint, int type);
|
|
||||||
|
|
||||||
void done (int type, bool failed);
|
void done (int type, bool failed);
|
||||||
|
|
||||||
|
@ -2,3 +2,5 @@
|
|||||||
#include "stage.hpp"
|
#include "stage.hpp"
|
||||||
|
|
||||||
CSMDoc::Stage::~Stage() {}
|
CSMDoc::Stage::~Stage() {}
|
||||||
|
|
||||||
|
void CSMDoc::Stage::updateUserSetting (const QString& name, const QStringList& value) {}
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
#include "messages.hpp"
|
#include "messages.hpp"
|
||||||
|
|
||||||
|
class QString;
|
||||||
|
|
||||||
namespace CSMDoc
|
namespace CSMDoc
|
||||||
{
|
{
|
||||||
class Stage
|
class Stage
|
||||||
@ -21,6 +23,9 @@ namespace CSMDoc
|
|||||||
|
|
||||||
virtual void perform (int stage, Messages& messages) = 0;
|
virtual void perform (int stage, Messages& messages) = 0;
|
||||||
///< Messages resulting from this stage will be appended to \a messages.
|
///< Messages resulting from this stage will be appended to \a messages.
|
||||||
|
|
||||||
|
/// Default-implementation: ignore
|
||||||
|
virtual void updateUserSetting (const QString& name, const QStringList& value);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,6 +217,47 @@ void CSMSettings::UserSettings::buildSettingModelDefaults()
|
|||||||
jumpToAdded->setDeclaredValues (jumpValues);
|
jumpToAdded->setDeclaredValues (jumpValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declareSection ("report-input", "Report Input");
|
||||||
|
{
|
||||||
|
QString none ("None");
|
||||||
|
QString edit ("Edit");
|
||||||
|
QString remove ("Remove");
|
||||||
|
QString editAndRemove ("Edit And Remove");
|
||||||
|
|
||||||
|
QStringList values;
|
||||||
|
values << none << edit << remove << editAndRemove;
|
||||||
|
|
||||||
|
QString toolTip = "<ul>"
|
||||||
|
"<li>None</li>"
|
||||||
|
"<li>Edit: Open a table or dialogue suitable for addressing the listed report</li>"
|
||||||
|
"<li>Remove: Remove the report from the report table</li>"
|
||||||
|
"<li>Edit and Remove: Open a table or dialogue suitable for addressing the listed report, then remove the report from the report table</li>"
|
||||||
|
"</ul>";
|
||||||
|
|
||||||
|
Setting *doubleClick = createSetting (Type_ComboBox, "double", "Double Click");
|
||||||
|
doubleClick->setDeclaredValues (values);
|
||||||
|
doubleClick->setDefaultValue (edit);
|
||||||
|
doubleClick->setToolTip ("Action on double click in report table:<p>" + toolTip);
|
||||||
|
|
||||||
|
Setting *shiftDoubleClick = createSetting (Type_ComboBox, "double-s",
|
||||||
|
"Shift Double Click");
|
||||||
|
shiftDoubleClick->setDeclaredValues (values);
|
||||||
|
shiftDoubleClick->setDefaultValue (remove);
|
||||||
|
shiftDoubleClick->setToolTip ("Action on shift double click in report table:<p>" + toolTip);
|
||||||
|
|
||||||
|
Setting *ctrlDoubleClick = createSetting (Type_ComboBox, "double-c",
|
||||||
|
"Control Double Click");
|
||||||
|
ctrlDoubleClick->setDeclaredValues (values);
|
||||||
|
ctrlDoubleClick->setDefaultValue (editAndRemove);
|
||||||
|
ctrlDoubleClick->setToolTip ("Action on control double click in report table:<p>" + toolTip);
|
||||||
|
|
||||||
|
Setting *shiftCtrlDoubleClick = createSetting (Type_ComboBox, "double-sc",
|
||||||
|
"Shift Control Double Click");
|
||||||
|
shiftCtrlDoubleClick->setDeclaredValues (values);
|
||||||
|
shiftCtrlDoubleClick->setDefaultValue (none);
|
||||||
|
shiftCtrlDoubleClick->setToolTip ("Action on shift control double click in report table:<p>" + toolTip);
|
||||||
|
}
|
||||||
|
|
||||||
declareSection ("search", "Search & Replace");
|
declareSection ("search", "Search & Replace");
|
||||||
{
|
{
|
||||||
Setting *before = createSetting (Type_SpinBox, "char-before",
|
Setting *before = createSetting (Type_SpinBox, "char-before",
|
||||||
@ -235,7 +276,7 @@ void CSMSettings::UserSettings::buildSettingModelDefaults()
|
|||||||
autoDelete->setDefaultValue ("true");
|
autoDelete->setDefaultValue ("true");
|
||||||
}
|
}
|
||||||
|
|
||||||
declareSection ("script-editor", "Script Editor");
|
declareSection ("script-editor", "Scripts");
|
||||||
{
|
{
|
||||||
Setting *lineNum = createSetting (Type_CheckBox, "show-linenum", "Show Line Numbers");
|
Setting *lineNum = createSetting (Type_CheckBox, "show-linenum", "Show Line Numbers");
|
||||||
lineNum->setDefaultValue ("true");
|
lineNum->setDefaultValue ("true");
|
||||||
@ -254,6 +295,21 @@ void CSMSettings::UserSettings::buildSettingModelDefaults()
|
|||||||
"\nA name from the list of colors defined in the list of SVG color keyword names."
|
"\nA name from the list of colors defined in the list of SVG color keyword names."
|
||||||
"\nX11 color names may also work.";
|
"\nX11 color names may also work.";
|
||||||
|
|
||||||
|
QString modeNormal ("Normal");
|
||||||
|
|
||||||
|
QStringList modes;
|
||||||
|
modes << "Ignore" << modeNormal << "Strict";
|
||||||
|
|
||||||
|
Setting *warnings = createSetting (Type_ComboBox, "warnings",
|
||||||
|
"Warning Mode");
|
||||||
|
warnings->setDeclaredValues (modes);
|
||||||
|
warnings->setDefaultValue (modeNormal);
|
||||||
|
warnings->setToolTip ("<ul>How to handle warning messages during compilation:<p>"
|
||||||
|
"<li>Ignore: Do not report warning</li>"
|
||||||
|
"<li>Normal: Report warning as a warning</li>"
|
||||||
|
"<li>Strict: Promote warning to an error</li>"
|
||||||
|
"</ul>");
|
||||||
|
|
||||||
Setting *formatInt = createSetting (Type_LineEdit, "colour-int", "Highlight Colour: Int");
|
Setting *formatInt = createSetting (Type_LineEdit, "colour-int", "Highlight Colour: Int");
|
||||||
formatInt->setDefaultValues (QStringList() << "Dark magenta");
|
formatInt->setDefaultValues (QStringList() << "Dark magenta");
|
||||||
formatInt->setToolTip ("(Default: Green) Use one of the following formats:" + tooltip);
|
formatInt->setToolTip ("(Default: Green) Use one of the following formats:" + tooltip);
|
||||||
|
@ -6,24 +6,18 @@
|
|||||||
|
|
||||||
#include "../world/columns.hpp"
|
#include "../world/columns.hpp"
|
||||||
|
|
||||||
CSMTools::ReportModel::Line::Line (const CSMWorld::UniversalId& id, const std::string& message,
|
CSMTools::ReportModel::ReportModel (bool fieldColumn, bool severityColumn)
|
||||||
const std::string& hint)
|
: mColumnField (-1), mColumnSeverity (-1)
|
||||||
: mId (id), mMessage (message), mHint (hint)
|
|
||||||
{}
|
|
||||||
|
|
||||||
CSMTools::ReportModel::ReportModel (bool fieldColumn)
|
|
||||||
{
|
{
|
||||||
if (fieldColumn)
|
int index = 3;
|
||||||
{
|
|
||||||
mColumnField = 3;
|
|
||||||
mColumnDescription = 4;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mColumnDescription = 3;
|
|
||||||
|
|
||||||
mColumnField = -1;
|
if (severityColumn)
|
||||||
}
|
mColumnSeverity = index++;
|
||||||
|
|
||||||
|
if (fieldColumn)
|
||||||
|
mColumnField = index++;
|
||||||
|
|
||||||
|
mColumnDescription = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CSMTools::ReportModel::rowCount (const QModelIndex & parent) const
|
int CSMTools::ReportModel::rowCount (const QModelIndex & parent) const
|
||||||
@ -88,6 +82,18 @@ QVariant CSMTools::ReportModel::data (const QModelIndex & index, int role) const
|
|||||||
|
|
||||||
return QString::fromUtf8 (field.c_str());
|
return QString::fromUtf8 (field.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (index.column()==mColumnSeverity)
|
||||||
|
{
|
||||||
|
switch (mRows.at (index.row()).mSeverity)
|
||||||
|
{
|
||||||
|
case CSMDoc::Message::Severity_Info: return "Information";
|
||||||
|
case CSMDoc::Message::Severity_Warning: return "Warning";
|
||||||
|
case CSMDoc::Message::Severity_Error: return "Error";
|
||||||
|
case CSMDoc::Message::Severity_SeriousError: return "Serious Error";
|
||||||
|
case CSMDoc::Message::Severity_Default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
@ -112,6 +118,9 @@ QVariant CSMTools::ReportModel::headerData (int section, Qt::Orientation orienta
|
|||||||
if (section==mColumnField)
|
if (section==mColumnField)
|
||||||
return "Field";
|
return "Field";
|
||||||
|
|
||||||
|
if (section==mColumnSeverity)
|
||||||
|
return "Severity";
|
||||||
|
|
||||||
return "-";
|
return "-";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,19 +141,18 @@ bool CSMTools::ReportModel::removeRows (int row, int count, const QModelIndex& p
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::ReportModel::add (const CSMWorld::UniversalId& id, const std::string& message,
|
void CSMTools::ReportModel::add (const CSMDoc::Message& message)
|
||||||
const std::string& hint)
|
|
||||||
{
|
{
|
||||||
beginInsertRows (QModelIndex(), mRows.size(), mRows.size());
|
beginInsertRows (QModelIndex(), mRows.size(), mRows.size());
|
||||||
|
|
||||||
mRows.push_back (Line (id, message, hint));
|
mRows.push_back (message);
|
||||||
|
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::ReportModel::flagAsReplaced (int index)
|
void CSMTools::ReportModel::flagAsReplaced (int index)
|
||||||
{
|
{
|
||||||
Line& line = mRows.at (index);
|
CSMDoc::Message& line = mRows.at (index);
|
||||||
std::string hint = line.mHint;
|
std::string hint = line.mHint;
|
||||||
|
|
||||||
if (hint.empty() || hint[0]!='R')
|
if (hint.empty() || hint[0]!='R')
|
||||||
@ -176,3 +184,16 @@ void CSMTools::ReportModel::clear()
|
|||||||
endRemoveRows();
|
endRemoveRows();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CSMTools::ReportModel::countErrors() const
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
for (std::vector<CSMDoc::Messages::Message>::const_iterator iter (mRows.begin());
|
||||||
|
iter!=mRows.end(); ++iter)
|
||||||
|
if (iter->mSeverity==CSMDoc::Message::Severity_Error ||
|
||||||
|
iter->mSeverity==CSMDoc::Message::Severity_SeriousError)
|
||||||
|
++count;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
#include <QAbstractTableModel>
|
#include <QAbstractTableModel>
|
||||||
|
|
||||||
|
#include "../doc/messages.hpp"
|
||||||
|
|
||||||
#include "../world/universalid.hpp"
|
#include "../world/universalid.hpp"
|
||||||
|
|
||||||
namespace CSMTools
|
namespace CSMTools
|
||||||
@ -14,17 +16,7 @@ namespace CSMTools
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
struct Line
|
std::vector<CSMDoc::Messages::Message> mRows;
|
||||||
{
|
|
||||||
Line (const CSMWorld::UniversalId& id, const std::string& message,
|
|
||||||
const std::string& hint);
|
|
||||||
|
|
||||||
CSMWorld::UniversalId mId;
|
|
||||||
std::string mMessage;
|
|
||||||
std::string mHint;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<Line> mRows;
|
|
||||||
|
|
||||||
// Fixed columns
|
// Fixed columns
|
||||||
enum Columns
|
enum Columns
|
||||||
@ -35,10 +27,11 @@ namespace CSMTools
|
|||||||
// Configurable columns
|
// Configurable columns
|
||||||
int mColumnDescription;
|
int mColumnDescription;
|
||||||
int mColumnField;
|
int mColumnField;
|
||||||
|
int mColumnSeverity;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ReportModel (bool fieldColumn = false);
|
ReportModel (bool fieldColumn = false, bool severityColumn = true);
|
||||||
|
|
||||||
virtual int rowCount (const QModelIndex & parent = QModelIndex()) const;
|
virtual int rowCount (const QModelIndex & parent = QModelIndex()) const;
|
||||||
|
|
||||||
@ -50,8 +43,7 @@ namespace CSMTools
|
|||||||
|
|
||||||
virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex());
|
virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex());
|
||||||
|
|
||||||
void add (const CSMWorld::UniversalId& id, const std::string& message,
|
void add (const CSMDoc::Message& message);
|
||||||
const std::string& hint = "");
|
|
||||||
|
|
||||||
void flagAsReplaced (int index);
|
void flagAsReplaced (int index);
|
||||||
|
|
||||||
@ -60,6 +52,9 @@ namespace CSMTools
|
|||||||
std::string getHint (int row) const;
|
std::string getHint (int row) const;
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
// Return number of messages with Error or SeriousError severity.
|
||||||
|
int countErrors() const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,17 @@
|
|||||||
|
|
||||||
#include "../world/data.hpp"
|
#include "../world/data.hpp"
|
||||||
|
|
||||||
|
CSMDoc::Message::Severity CSMTools::ScriptCheckStage::getSeverity (Type type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case WarningMessage: return CSMDoc::Message::Severity_Warning;
|
||||||
|
case ErrorMessage: return CSMDoc::Message::Severity_Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CSMDoc::Message::Severity_SeriousError;
|
||||||
|
}
|
||||||
|
|
||||||
void CSMTools::ScriptCheckStage::report (const std::string& message, const Compiler::TokenLoc& loc,
|
void CSMTools::ScriptCheckStage::report (const std::string& message, const Compiler::TokenLoc& loc,
|
||||||
Type type)
|
Type type)
|
||||||
{
|
{
|
||||||
@ -18,11 +29,6 @@ void CSMTools::ScriptCheckStage::report (const std::string& message, const Compi
|
|||||||
|
|
||||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Script, mId);
|
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Script, mId);
|
||||||
|
|
||||||
if (type==ErrorMessage)
|
|
||||||
stream << "error ";
|
|
||||||
else
|
|
||||||
stream << "warning ";
|
|
||||||
|
|
||||||
stream
|
stream
|
||||||
<< "script " << mFile
|
<< "script " << mFile
|
||||||
<< ", line " << loc.mLine << ", column " << loc.mColumn
|
<< ", line " << loc.mLine << ", column " << loc.mColumn
|
||||||
@ -32,19 +38,21 @@ void CSMTools::ScriptCheckStage::report (const std::string& message, const Compi
|
|||||||
|
|
||||||
hintStream << "l:" << loc.mLine << " " << loc.mColumn;
|
hintStream << "l:" << loc.mLine << " " << loc.mColumn;
|
||||||
|
|
||||||
mMessages->add (id, stream.str(), hintStream.str());
|
mMessages->add (id, stream.str(), hintStream.str(), getSeverity (type));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::ScriptCheckStage::report (const std::string& message, Type type)
|
void CSMTools::ScriptCheckStage::report (const std::string& message, Type type)
|
||||||
{
|
{
|
||||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Script, mId);
|
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Script, mId);
|
||||||
|
|
||||||
mMessages->push_back (std::make_pair (id,
|
std::ostringstream stream;
|
||||||
(type==ErrorMessage ? "error: " : "warning: ") + message));
|
stream << "script " << mFile << ": " << message;
|
||||||
|
|
||||||
|
mMessages->add (id, stream.str(), "", getSeverity (type));
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMTools::ScriptCheckStage::ScriptCheckStage (const CSMDoc::Document& document)
|
CSMTools::ScriptCheckStage::ScriptCheckStage (const CSMDoc::Document& document)
|
||||||
: mDocument (document), mContext (document.getData()), mMessages (0)
|
: mDocument (document), mContext (document.getData()), mMessages (0), mWarningMode (Mode_Ignore)
|
||||||
{
|
{
|
||||||
/// \todo add an option to configure warning mode
|
/// \todo add an option to configure warning mode
|
||||||
setWarningsMode (0);
|
setWarningsMode (0);
|
||||||
@ -58,6 +66,7 @@ int CSMTools::ScriptCheckStage::setup()
|
|||||||
mContext.clear();
|
mContext.clear();
|
||||||
mMessages = 0;
|
mMessages = 0;
|
||||||
mId.clear();
|
mId.clear();
|
||||||
|
Compiler::ErrorHandler::reset();
|
||||||
|
|
||||||
return mDocument.getData().getScripts().getSize();
|
return mDocument.getData().getScripts().getSize();
|
||||||
}
|
}
|
||||||
@ -72,6 +81,13 @@ void CSMTools::ScriptCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
|||||||
|
|
||||||
mMessages = &messages;
|
mMessages = &messages;
|
||||||
|
|
||||||
|
switch (mWarningMode)
|
||||||
|
{
|
||||||
|
case Mode_Ignore: setWarningsMode (0); break;
|
||||||
|
case Mode_Normal: setWarningsMode (1); break;
|
||||||
|
case Mode_Strict: setWarningsMode (2); break;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const CSMWorld::Data& data = mDocument.getData();
|
const CSMWorld::Data& data = mDocument.getData();
|
||||||
@ -93,9 +109,24 @@ void CSMTools::ScriptCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
|||||||
{
|
{
|
||||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Script, mId);
|
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Script, mId);
|
||||||
|
|
||||||
messages.push_back (std::make_pair (id,
|
std::ostringstream stream;
|
||||||
std::string ("Critical compile error: ") + error.what()));
|
stream << "script " << mFile << ": " << error.what();
|
||||||
|
|
||||||
|
messages.add (id, stream.str(), "", CSMDoc::Message::Severity_SeriousError);
|
||||||
}
|
}
|
||||||
|
|
||||||
mMessages = 0;
|
mMessages = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSMTools::ScriptCheckStage::updateUserSetting (const QString& name, const QStringList& value)
|
||||||
|
{
|
||||||
|
if (name=="script-editor/warnings")
|
||||||
|
{
|
||||||
|
if (value.at (0)=="Ignore")
|
||||||
|
mWarningMode = Mode_Ignore;
|
||||||
|
else if (value.at (0)=="Normal")
|
||||||
|
mWarningMode = Mode_Normal;
|
||||||
|
else if (value.at (0)=="Strict")
|
||||||
|
mWarningMode = Mode_Strict;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -18,13 +18,23 @@ namespace CSMTools
|
|||||||
/// \brief VerifyStage: make sure that scripts compile
|
/// \brief VerifyStage: make sure that scripts compile
|
||||||
class ScriptCheckStage : public CSMDoc::Stage, private Compiler::ErrorHandler
|
class ScriptCheckStage : public CSMDoc::Stage, private Compiler::ErrorHandler
|
||||||
{
|
{
|
||||||
|
enum WarningMode
|
||||||
|
{
|
||||||
|
Mode_Ignore,
|
||||||
|
Mode_Normal,
|
||||||
|
Mode_Strict
|
||||||
|
};
|
||||||
|
|
||||||
const CSMDoc::Document& mDocument;
|
const CSMDoc::Document& mDocument;
|
||||||
Compiler::Extensions mExtensions;
|
Compiler::Extensions mExtensions;
|
||||||
CSMWorld::ScriptContext mContext;
|
CSMWorld::ScriptContext mContext;
|
||||||
std::string mId;
|
std::string mId;
|
||||||
std::string mFile;
|
std::string mFile;
|
||||||
CSMDoc::Messages *mMessages;
|
CSMDoc::Messages *mMessages;
|
||||||
|
WarningMode mWarningMode;
|
||||||
|
|
||||||
|
CSMDoc::Message::Severity getSeverity (Type type);
|
||||||
|
|
||||||
virtual void report (const std::string& message, const Compiler::TokenLoc& loc, Type type);
|
virtual void report (const std::string& message, const Compiler::TokenLoc& loc, Type type);
|
||||||
///< Report error to the user.
|
///< Report error to the user.
|
||||||
|
|
||||||
@ -40,6 +50,8 @@ namespace CSMTools
|
|||||||
|
|
||||||
virtual void perform (int stage, CSMDoc::Messages& messages);
|
virtual void perform (int stage, CSMDoc::Messages& messages);
|
||||||
///< Messages resulting from this tage will be appended to \a messages.
|
///< Messages resulting from this tage will be appended to \a messages.
|
||||||
|
|
||||||
|
virtual void updateUserSetting (const QString& name, const QStringList& value);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +280,7 @@ void CSMTools::Search::replace (CSMDoc::Document& document, CSMWorld::IdTableBas
|
|||||||
bool CSMTools::Search::verify (CSMDoc::Document& document, CSMWorld::IdTableBase *model,
|
bool CSMTools::Search::verify (CSMDoc::Document& document, CSMWorld::IdTableBase *model,
|
||||||
const CSMWorld::UniversalId& id, const std::string& messageHint) const
|
const CSMWorld::UniversalId& id, const std::string& messageHint) const
|
||||||
{
|
{
|
||||||
CSMDoc::Messages messages;
|
CSMDoc::Messages messages (CSMDoc::Message::Severity_Info);
|
||||||
|
|
||||||
int row = model->getModelIndex (id.getId(),
|
int row = model->getModelIndex (id.getId(),
|
||||||
model->findColumnIndex (CSMWorld::Columns::ColumnId_Id)).row();
|
model->findColumnIndex (CSMWorld::Columns::ColumnId_Id)).row();
|
||||||
|
@ -21,6 +21,8 @@ CSMTools::SearchOperation::SearchOperation (CSMDoc::Document& document)
|
|||||||
iter!=types.end(); ++iter)
|
iter!=types.end(); ++iter)
|
||||||
appendStage (new SearchStage (&dynamic_cast<CSMWorld::IdTableBase&> (
|
appendStage (new SearchStage (&dynamic_cast<CSMWorld::IdTableBase&> (
|
||||||
*document.getData().getTableModel (*iter))));
|
*document.getData().getTableModel (*iter))));
|
||||||
|
|
||||||
|
setDefaultSeverity (CSMDoc::Message::Severity_Info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::SearchOperation::configure (const Search& search)
|
void CSMTools::SearchOperation::configure (const Search& search)
|
||||||
|
@ -51,11 +51,15 @@ CSMDoc::OperationHolder *CSMTools::Tools::getVerifier()
|
|||||||
{
|
{
|
||||||
mVerifierOperation = new CSMDoc::Operation (CSMDoc::State_Verifying, false);
|
mVerifierOperation = new CSMDoc::Operation (CSMDoc::State_Verifying, false);
|
||||||
|
|
||||||
|
std::vector<QString> settings;
|
||||||
|
settings.push_back ("script-editor/warnings");
|
||||||
|
|
||||||
|
mVerifierOperation->configureSettings (settings);
|
||||||
|
|
||||||
connect (&mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int)));
|
connect (&mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int)));
|
||||||
connect (&mVerifier, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool)));
|
connect (&mVerifier, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool)));
|
||||||
connect (&mVerifier,
|
connect (&mVerifier, SIGNAL (reportMessage (const CSMDoc::Message&, int)),
|
||||||
SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)),
|
this, SLOT (verifierMessage (const CSMDoc::Message&, int)));
|
||||||
this, SLOT (verifierMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)));
|
|
||||||
|
|
||||||
std::vector<std::string> mandatoryIds; // I want C++11, damn it!
|
std::vector<std::string> mandatoryIds; // I want C++11, damn it!
|
||||||
mandatoryIds.push_back ("Day");
|
mandatoryIds.push_back ("Day");
|
||||||
@ -120,9 +124,8 @@ CSMTools::Tools::Tools (CSMDoc::Document& document)
|
|||||||
|
|
||||||
connect (&mSearch, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int)));
|
connect (&mSearch, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int)));
|
||||||
connect (&mSearch, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool)));
|
connect (&mSearch, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool)));
|
||||||
connect (&mSearch,
|
connect (&mSearch, SIGNAL (reportMessage (const CSMDoc::Message&, int)),
|
||||||
SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)),
|
this, SLOT (verifierMessage (const CSMDoc::Message&, int)));
|
||||||
this, SLOT (verifierMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMTools::Tools::~Tools()
|
CSMTools::Tools::~Tools()
|
||||||
@ -155,7 +158,7 @@ CSMWorld::UniversalId CSMTools::Tools::runVerifier()
|
|||||||
|
|
||||||
CSMWorld::UniversalId CSMTools::Tools::newSearch()
|
CSMWorld::UniversalId CSMTools::Tools::newSearch()
|
||||||
{
|
{
|
||||||
mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel (true)));
|
mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel (true, false)));
|
||||||
|
|
||||||
return CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Search, mNextReportNumber-1);
|
return CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Search, mNextReportNumber-1);
|
||||||
}
|
}
|
||||||
@ -210,12 +213,11 @@ CSMTools::ReportModel *CSMTools::Tools::getReport (const CSMWorld::UniversalId&
|
|||||||
return mReports.at (id.getIndex());
|
return mReports.at (id.getIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::Tools::verifierMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
void CSMTools::Tools::verifierMessage (const CSMDoc::Message& message, int type)
|
||||||
const std::string& hint, int type)
|
|
||||||
{
|
{
|
||||||
std::map<int, int>::iterator iter = mActiveReports.find (type);
|
std::map<int, int>::iterator iter = mActiveReports.find (type);
|
||||||
|
|
||||||
if (iter!=mActiveReports.end())
|
if (iter!=mActiveReports.end())
|
||||||
mReports[iter->second]->add (id, message, hint);
|
mReports[iter->second]->add (message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,8 +75,7 @@ namespace CSMTools
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void verifierMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
void verifierMessage (const CSMDoc::Message& message, int type);
|
||||||
const std::string& hint, int type);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
@ -694,7 +694,7 @@ namespace CSMWorld
|
|||||||
|
|
||||||
QColor colour = data.value<QColor>();
|
QColor colour = data.value<QColor>();
|
||||||
|
|
||||||
record2.mMapColor = colour.rgb() & 0xffffff;
|
record2.mMapColor = (colour.blue() << 16) | (colour.green() << 8) | colour.red();
|
||||||
|
|
||||||
record.setModified (record2);
|
record.setModified (record2);
|
||||||
}
|
}
|
||||||
|
@ -933,7 +933,7 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages)
|
|||||||
{
|
{
|
||||||
// log an error and continue loading the refs to the last loaded cell
|
// log an error and continue loading the refs to the last loaded cell
|
||||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_None);
|
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_None);
|
||||||
messages.add (id, "Logic error: cell index out of bounds");
|
messages.add (id, "Logic error: cell index out of bounds", "", CSMDoc::Message::Severity_Error);
|
||||||
index = mCells.getSize()-1;
|
index = mCells.getSize()-1;
|
||||||
}
|
}
|
||||||
std::string cellId = Misc::StringUtils::lowerCase (mCells.getId (index));
|
std::string cellId = Misc::StringUtils::lowerCase (mCells.getId (index));
|
||||||
@ -994,7 +994,8 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
messages.add (UniversalId::Type_None,
|
messages.add (UniversalId::Type_None,
|
||||||
"Trying to delete dialogue record " + id + " which does not exist");
|
"Trying to delete dialogue record " + id + " which does not exist",
|
||||||
|
"", CSMDoc::Message::Severity_Warning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1011,7 +1012,7 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages)
|
|||||||
if (!mDialogue)
|
if (!mDialogue)
|
||||||
{
|
{
|
||||||
messages.add (UniversalId::Type_None,
|
messages.add (UniversalId::Type_None,
|
||||||
"Found info record not following a dialogue record");
|
"Found info record not following a dialogue record", "", CSMDoc::Message::Severity_Error);
|
||||||
|
|
||||||
mReader->skipRecord();
|
mReader->skipRecord();
|
||||||
break;
|
break;
|
||||||
@ -1054,7 +1055,8 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages)
|
|||||||
|
|
||||||
if (unhandledRecord)
|
if (unhandledRecord)
|
||||||
{
|
{
|
||||||
messages.add (UniversalId::Type_None, "Unsupported record type: " + n.toString());
|
messages.add (UniversalId::Type_None, "Unsupported record type: " + n.toString(), "",
|
||||||
|
CSMDoc::Message::Severity_Error);
|
||||||
|
|
||||||
mReader->skipRecord();
|
mReader->skipRecord();
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ namespace
|
|||||||
types[CSMWorld::ColumnBase::Display_Faction ] = CSMWorld::UniversalId::Type_Faction;
|
types[CSMWorld::ColumnBase::Display_Faction ] = CSMWorld::UniversalId::Type_Faction;
|
||||||
types[CSMWorld::ColumnBase::Display_GlobalVariable ] = CSMWorld::UniversalId::Type_Global;
|
types[CSMWorld::ColumnBase::Display_GlobalVariable ] = CSMWorld::UniversalId::Type_Global;
|
||||||
types[CSMWorld::ColumnBase::Display_Icon ] = CSMWorld::UniversalId::Type_Icon;
|
types[CSMWorld::ColumnBase::Display_Icon ] = CSMWorld::UniversalId::Type_Icon;
|
||||||
|
types[CSMWorld::ColumnBase::Display_Journal ] = CSMWorld::UniversalId::Type_Journal;
|
||||||
types[CSMWorld::ColumnBase::Display_Mesh ] = CSMWorld::UniversalId::Type_Mesh;
|
types[CSMWorld::ColumnBase::Display_Mesh ] = CSMWorld::UniversalId::Type_Mesh;
|
||||||
types[CSMWorld::ColumnBase::Display_Miscellaneous ] = CSMWorld::UniversalId::Type_Referenceable;
|
types[CSMWorld::ColumnBase::Display_Miscellaneous ] = CSMWorld::UniversalId::Type_Referenceable;
|
||||||
types[CSMWorld::ColumnBase::Display_Npc ] = CSMWorld::UniversalId::Type_Referenceable;
|
types[CSMWorld::ColumnBase::Display_Npc ] = CSMWorld::UniversalId::Type_Referenceable;
|
||||||
@ -37,6 +38,7 @@ namespace
|
|||||||
types[CSMWorld::ColumnBase::Display_Spell ] = CSMWorld::UniversalId::Type_Spell;
|
types[CSMWorld::ColumnBase::Display_Spell ] = CSMWorld::UniversalId::Type_Spell;
|
||||||
types[CSMWorld::ColumnBase::Display_Static ] = CSMWorld::UniversalId::Type_Referenceable;
|
types[CSMWorld::ColumnBase::Display_Static ] = CSMWorld::UniversalId::Type_Referenceable;
|
||||||
types[CSMWorld::ColumnBase::Display_Texture ] = CSMWorld::UniversalId::Type_Texture;
|
types[CSMWorld::ColumnBase::Display_Texture ] = CSMWorld::UniversalId::Type_Texture;
|
||||||
|
types[CSMWorld::ColumnBase::Display_Topic ] = CSMWorld::UniversalId::Type_Topic;
|
||||||
types[CSMWorld::ColumnBase::Display_Weapon ] = CSMWorld::UniversalId::Type_Referenceable;
|
types[CSMWorld::ColumnBase::Display_Weapon ] = CSMWorld::UniversalId::Type_Referenceable;
|
||||||
|
|
||||||
return types;
|
return types;
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "../world/recordstatusdelegate.hpp"
|
#include "../world/recordstatusdelegate.hpp"
|
||||||
#include "../world/idtypedelegate.hpp"
|
#include "../world/idtypedelegate.hpp"
|
||||||
#include "../world/idcompletiondelegate.hpp"
|
#include "../world/idcompletiondelegate.hpp"
|
||||||
|
#include "../world/colordelegate.hpp"
|
||||||
|
|
||||||
#include "../../model/settings/usersettings.hpp"
|
#include "../../model/settings/usersettings.hpp"
|
||||||
|
|
||||||
@ -61,6 +62,9 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager)
|
|||||||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_RefRecordType,
|
mDelegateFactories->add (CSMWorld::ColumnBase::Display_RefRecordType,
|
||||||
new CSVWorld::IdTypeDelegateFactory());
|
new CSVWorld::IdTypeDelegateFactory());
|
||||||
|
|
||||||
|
mDelegateFactories->add (CSMWorld::ColumnBase::Display_Colour,
|
||||||
|
new CSVWorld::ColorDelegateFactory());
|
||||||
|
|
||||||
std::vector<CSMWorld::ColumnBase::Display> idCompletionColumns = CSMWorld::IdCompletionManager::getDisplayTypes();
|
std::vector<CSMWorld::ColumnBase::Display> idCompletionColumns = CSMWorld::IdCompletionManager::getDisplayTypes();
|
||||||
for (std::vector<CSMWorld::ColumnBase::Display>::const_iterator current = idCompletionColumns.begin();
|
for (std::vector<CSMWorld::ColumnBase::Display>::const_iterator current = idCompletionColumns.begin();
|
||||||
current != idCompletionColumns.end();
|
current != idCompletionColumns.end();
|
||||||
|
@ -96,21 +96,35 @@ void CSVTools::ReportTable::mouseDoubleClickEvent (QMouseEvent *event)
|
|||||||
selectionModel()->select (index,
|
selectionModel()->select (index,
|
||||||
QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Rows);
|
QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Rows);
|
||||||
|
|
||||||
switch (modifiers)
|
std::map<Qt::KeyboardModifiers, DoubleClickAction>::iterator iter =
|
||||||
|
mDoubleClickActions.find (modifiers);
|
||||||
|
|
||||||
|
if (iter==mDoubleClickActions.end())
|
||||||
{
|
{
|
||||||
case 0:
|
event->accept();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (iter->second)
|
||||||
|
{
|
||||||
|
case Action_None:
|
||||||
|
|
||||||
|
event->accept();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Action_Edit:
|
||||||
|
|
||||||
event->accept();
|
event->accept();
|
||||||
showSelection();
|
showSelection();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::ShiftModifier:
|
case Action_Remove:
|
||||||
|
|
||||||
event->accept();
|
event->accept();
|
||||||
removeSelection();
|
removeSelection();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::ControlModifier:
|
case Action_EditAndRemove:
|
||||||
|
|
||||||
event->accept();
|
event->accept();
|
||||||
showSelection();
|
showSelection();
|
||||||
@ -155,7 +169,11 @@ CSVTools::ReportTable::ReportTable (CSMDoc::Document& document,
|
|||||||
|
|
||||||
mReplaceAction = new QAction (tr ("Replace"), this);
|
mReplaceAction = new QAction (tr ("Replace"), this);
|
||||||
connect (mReplaceAction, SIGNAL (triggered()), this, SIGNAL (replaceRequest()));
|
connect (mReplaceAction, SIGNAL (triggered()), this, SIGNAL (replaceRequest()));
|
||||||
addAction (mReplaceAction);
|
addAction (mReplaceAction);
|
||||||
|
|
||||||
|
mDoubleClickActions.insert (std::make_pair (Qt::NoModifier, Action_Edit));
|
||||||
|
mDoubleClickActions.insert (std::make_pair (Qt::ShiftModifier, Action_Remove));
|
||||||
|
mDoubleClickActions.insert (std::make_pair (Qt::ControlModifier, Action_EditAndRemove));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<CSMWorld::UniversalId> CSVTools::ReportTable::getDraggedRecords() const
|
std::vector<CSMWorld::UniversalId> CSVTools::ReportTable::getDraggedRecords() const
|
||||||
@ -176,6 +194,35 @@ std::vector<CSMWorld::UniversalId> CSVTools::ReportTable::getDraggedRecords() co
|
|||||||
void CSVTools::ReportTable::updateUserSetting (const QString& name, const QStringList& list)
|
void CSVTools::ReportTable::updateUserSetting (const QString& name, const QStringList& list)
|
||||||
{
|
{
|
||||||
mIdTypeDelegate->updateUserSetting (name, list);
|
mIdTypeDelegate->updateUserSetting (name, list);
|
||||||
|
|
||||||
|
QString base ("report-input/double");
|
||||||
|
if (name.startsWith (base))
|
||||||
|
{
|
||||||
|
QString modifierString = name.mid (base.size());
|
||||||
|
Qt::KeyboardModifiers modifiers = 0;
|
||||||
|
|
||||||
|
if (modifierString=="-s")
|
||||||
|
modifiers = Qt::ShiftModifier;
|
||||||
|
else if (modifierString=="-c")
|
||||||
|
modifiers = Qt::ControlModifier;
|
||||||
|
else if (modifierString=="-sc")
|
||||||
|
modifiers = Qt::ShiftModifier | Qt::ControlModifier;
|
||||||
|
|
||||||
|
DoubleClickAction action = Action_None;
|
||||||
|
|
||||||
|
QString value = list.at (0);
|
||||||
|
|
||||||
|
if (value=="Edit")
|
||||||
|
action = Action_Edit;
|
||||||
|
else if (value=="Remove")
|
||||||
|
action = Action_Remove;
|
||||||
|
else if (value=="Edit And Remove")
|
||||||
|
action = Action_EditAndRemove;
|
||||||
|
|
||||||
|
mDoubleClickActions[modifiers] = action;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int> CSVTools::ReportTable::getReplaceIndices (bool selection) const
|
std::vector<int> CSVTools::ReportTable::getReplaceIndices (bool selection) const
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#ifndef CSV_TOOLS_REPORTTABLE_H
|
#ifndef CSV_TOOLS_REPORTTABLE_H
|
||||||
#define CSV_TOOLS_REPORTTABLE_H
|
#define CSV_TOOLS_REPORTTABLE_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "../world/dragrecordtable.hpp"
|
#include "../world/dragrecordtable.hpp"
|
||||||
|
|
||||||
class QAction;
|
class QAction;
|
||||||
@ -21,11 +23,20 @@ namespace CSVTools
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
enum DoubleClickAction
|
||||||
|
{
|
||||||
|
Action_None,
|
||||||
|
Action_Edit,
|
||||||
|
Action_Remove,
|
||||||
|
Action_EditAndRemove
|
||||||
|
};
|
||||||
|
|
||||||
CSMTools::ReportModel *mModel;
|
CSMTools::ReportModel *mModel;
|
||||||
CSVWorld::CommandDelegate *mIdTypeDelegate;
|
CSVWorld::CommandDelegate *mIdTypeDelegate;
|
||||||
QAction *mShowAction;
|
QAction *mShowAction;
|
||||||
QAction *mRemoveAction;
|
QAction *mRemoveAction;
|
||||||
QAction *mReplaceAction;
|
QAction *mReplaceAction;
|
||||||
|
std::map<Qt::KeyboardModifiers, DoubleClickAction> mDoubleClickActions;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
113
apps/opencs/view/widget/coloreditor.cpp
Normal file
113
apps/opencs/view/widget/coloreditor.cpp
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
#include "coloreditor.hpp"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QColor>
|
||||||
|
#include <QColorDialog>
|
||||||
|
#include <QDesktopWidget>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QRect>
|
||||||
|
#include <QShowEvent>
|
||||||
|
|
||||||
|
#include "colorpickerpopup.hpp"
|
||||||
|
|
||||||
|
CSVWidget::ColorEditor::ColorEditor(const QColor &color, QWidget *parent, bool popupOnStart)
|
||||||
|
: QPushButton(parent),
|
||||||
|
mColor(color),
|
||||||
|
mColorPicker(new ColorPickerPopup(this)),
|
||||||
|
mPopupOnStart(popupOnStart)
|
||||||
|
{
|
||||||
|
setCheckable(true);
|
||||||
|
connect(this, SIGNAL(clicked()), this, SLOT(showPicker()));
|
||||||
|
connect(mColorPicker, SIGNAL(hid()), this, SLOT(pickerHid()));
|
||||||
|
connect(mColorPicker, SIGNAL(colorChanged(const QColor &)), this, SLOT(pickerColorChanged(const QColor &)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWidget::ColorEditor::paintEvent(QPaintEvent *event)
|
||||||
|
{
|
||||||
|
QPushButton::paintEvent(event);
|
||||||
|
|
||||||
|
QRect buttonRect = rect();
|
||||||
|
QRect coloredRect(buttonRect.x() + qRound(buttonRect.width() / 4.0),
|
||||||
|
buttonRect.y() + qRound(buttonRect.height() / 4.0),
|
||||||
|
buttonRect.width() / 2,
|
||||||
|
buttonRect.height() / 2);
|
||||||
|
QPainter painter(this);
|
||||||
|
painter.fillRect(coloredRect, mColor);
|
||||||
|
painter.setPen(Qt::black);
|
||||||
|
painter.drawRect(coloredRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWidget::ColorEditor::showEvent(QShowEvent *event)
|
||||||
|
{
|
||||||
|
QPushButton::showEvent(event);
|
||||||
|
if (isVisible() && mPopupOnStart)
|
||||||
|
{
|
||||||
|
setChecked(true);
|
||||||
|
showPicker();
|
||||||
|
mPopupOnStart = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor CSVWidget::ColorEditor::color() const
|
||||||
|
{
|
||||||
|
return mColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWidget::ColorEditor::setColor(const QColor &color)
|
||||||
|
{
|
||||||
|
mColor = color;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWidget::ColorEditor::showPicker()
|
||||||
|
{
|
||||||
|
if (isChecked())
|
||||||
|
{
|
||||||
|
mColorPicker->showPicker(calculatePopupPosition(), mColor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mColorPicker->hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWidget::ColorEditor::pickerHid()
|
||||||
|
{
|
||||||
|
setChecked(false);
|
||||||
|
emit pickingFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWidget::ColorEditor::pickerColorChanged(const QColor &color)
|
||||||
|
{
|
||||||
|
mColor = color;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
QPoint CSVWidget::ColorEditor::calculatePopupPosition()
|
||||||
|
{
|
||||||
|
QRect editorGeometry = geometry();
|
||||||
|
QRect popupGeometry = mColorPicker->geometry();
|
||||||
|
QRect screenGeometry = QApplication::desktop()->screenGeometry();
|
||||||
|
|
||||||
|
// Center the popup horizontally relative to the editor
|
||||||
|
int localPopupX = (editorGeometry.width() - popupGeometry.width()) / 2;
|
||||||
|
// Popup position need to be specified in global coords
|
||||||
|
QPoint popupPosition = mapToGlobal(QPoint(localPopupX, editorGeometry.height()));
|
||||||
|
|
||||||
|
// Make sure that the popup isn't out of the screen
|
||||||
|
if (popupPosition.x() < screenGeometry.left())
|
||||||
|
{
|
||||||
|
popupPosition.setX(screenGeometry.left() + 1);
|
||||||
|
}
|
||||||
|
else if (popupPosition.x() + popupGeometry.width() > screenGeometry.right())
|
||||||
|
{
|
||||||
|
popupPosition.setX(screenGeometry.right() - popupGeometry.width() - 1);
|
||||||
|
}
|
||||||
|
if (popupPosition.y() + popupGeometry.height() > screenGeometry.bottom())
|
||||||
|
{
|
||||||
|
// Place the popup above the editor
|
||||||
|
popupPosition.setY(popupPosition.y() - popupGeometry.height() - editorGeometry.height() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return popupPosition;
|
||||||
|
}
|
44
apps/opencs/view/widget/coloreditor.hpp
Normal file
44
apps/opencs/view/widget/coloreditor.hpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#ifndef CSV_WIDGET_COLOREDITOR_HPP
|
||||||
|
#define CSV_WIDGET_COLOREDITOR_HPP
|
||||||
|
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
|
class QColor;
|
||||||
|
class QPoint;
|
||||||
|
class QSize;
|
||||||
|
|
||||||
|
namespace CSVWidget
|
||||||
|
{
|
||||||
|
class ColorPickerPopup;
|
||||||
|
|
||||||
|
class ColorEditor : public QPushButton
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
QColor mColor;
|
||||||
|
ColorPickerPopup *mColorPicker;
|
||||||
|
bool mPopupOnStart;
|
||||||
|
|
||||||
|
QPoint calculatePopupPosition();
|
||||||
|
|
||||||
|
public:
|
||||||
|
ColorEditor(const QColor &color, QWidget *parent = 0, bool popupOnStart = false);
|
||||||
|
|
||||||
|
QColor color() const;
|
||||||
|
void setColor(const QColor &color);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void paintEvent(QPaintEvent *event);
|
||||||
|
virtual void showEvent(QShowEvent *event);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void showPicker();
|
||||||
|
void pickerHid();
|
||||||
|
void pickerColorChanged(const QColor &color);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void pickingFinished();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
86
apps/opencs/view/widget/colorpickerpopup.cpp
Normal file
86
apps/opencs/view/widget/colorpickerpopup.cpp
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
#include "colorpickerpopup.hpp"
|
||||||
|
|
||||||
|
#include <QColorDialog>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QEvent>
|
||||||
|
#include <QKeyEvent>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QLayout>
|
||||||
|
#include <QStyleOption>
|
||||||
|
|
||||||
|
CSVWidget::ColorPickerPopup::ColorPickerPopup(QWidget *parent)
|
||||||
|
: QFrame(parent)
|
||||||
|
{
|
||||||
|
setWindowFlags(Qt::Popup);
|
||||||
|
setFrameStyle(QFrame::Box | QFrame::Plain);
|
||||||
|
hide();
|
||||||
|
|
||||||
|
mColorPicker = new QColorDialog(this);
|
||||||
|
mColorPicker->setWindowFlags(Qt::Widget);
|
||||||
|
mColorPicker->setOptions(QColorDialog::NoButtons | QColorDialog::DontUseNativeDialog);
|
||||||
|
mColorPicker->installEventFilter(this);
|
||||||
|
mColorPicker->open();
|
||||||
|
connect(mColorPicker,
|
||||||
|
SIGNAL(currentColorChanged(const QColor &)),
|
||||||
|
this,
|
||||||
|
SIGNAL(colorChanged(const QColor &)));
|
||||||
|
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||||
|
layout->addWidget(mColorPicker);
|
||||||
|
layout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||||
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
setLayout(layout);
|
||||||
|
setFixedSize(mColorPicker->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWidget::ColorPickerPopup::showPicker(const QPoint &position, const QColor &initialColor)
|
||||||
|
{
|
||||||
|
QRect geometry = this->geometry();
|
||||||
|
geometry.moveTo(position);
|
||||||
|
setGeometry(geometry);
|
||||||
|
|
||||||
|
mColorPicker->setCurrentColor(initialColor);
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWidget::ColorPickerPopup::mousePressEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
QPushButton *button = qobject_cast<QPushButton *>(parentWidget());
|
||||||
|
if (button != NULL)
|
||||||
|
{
|
||||||
|
QStyleOptionButton option;
|
||||||
|
option.init(button);
|
||||||
|
QRect buttonRect = option.rect;
|
||||||
|
buttonRect.moveTo(button->mapToGlobal(buttonRect.topLeft()));
|
||||||
|
|
||||||
|
// If the mouse is pressed above the pop-up parent,
|
||||||
|
// the pop-up will be hidden and the pressed signal won't be repeated for the parent
|
||||||
|
if (buttonRect.contains(event->globalPos()) || buttonRect.contains(event->pos()))
|
||||||
|
{
|
||||||
|
setAttribute(Qt::WA_NoMouseReplay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QFrame::mousePressEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWidget::ColorPickerPopup::hideEvent(QHideEvent *event)
|
||||||
|
{
|
||||||
|
QFrame::hideEvent(event);
|
||||||
|
emit hid();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVWidget::ColorPickerPopup::eventFilter(QObject *object, QEvent *event)
|
||||||
|
{
|
||||||
|
if (object == mColorPicker && event->type() == QEvent::KeyPress)
|
||||||
|
{
|
||||||
|
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||||
|
// Prevent QColorDialog from closing when Escape is pressed.
|
||||||
|
// Instead, hide the popup.
|
||||||
|
if (keyEvent->key() == Qt::Key_Escape)
|
||||||
|
{
|
||||||
|
hide();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QFrame::eventFilter(object, event);
|
||||||
|
}
|
32
apps/opencs/view/widget/colorpickerpopup.hpp
Normal file
32
apps/opencs/view/widget/colorpickerpopup.hpp
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#ifndef CSVWIDGET_COLORPICKERPOPUP_HPP
|
||||||
|
#define CSVWIDGET_COLORPICKERPOPUP_HPP
|
||||||
|
|
||||||
|
#include <QFrame>
|
||||||
|
|
||||||
|
class QColorDialog;
|
||||||
|
|
||||||
|
namespace CSVWidget
|
||||||
|
{
|
||||||
|
class ColorPickerPopup : public QFrame
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
QColorDialog *mColorPicker;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ColorPickerPopup(QWidget *parent);
|
||||||
|
|
||||||
|
void showPicker(const QPoint &position, const QColor &initialColor);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void mousePressEvent(QMouseEvent *event);
|
||||||
|
virtual void hideEvent(QHideEvent *event);
|
||||||
|
virtual bool eventFilter(QObject *object, QEvent *event);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void hid();
|
||||||
|
void colorChanged(const QColor &color);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
36
apps/opencs/view/world/colordelegate.cpp
Normal file
36
apps/opencs/view/world/colordelegate.cpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#include "colordelegate.hpp"
|
||||||
|
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
|
#include "../widget/coloreditor.hpp"
|
||||||
|
|
||||||
|
CSVWorld::ColorDelegate::ColorDelegate(CSMWorld::CommandDispatcher *dispatcher,
|
||||||
|
CSMDoc::Document& document,
|
||||||
|
QObject *parent)
|
||||||
|
: CommandDelegate(dispatcher, document, parent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void CSVWorld::ColorDelegate::paint(QPainter *painter,
|
||||||
|
const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
QRect coloredRect(option.rect.x() + qRound(option.rect.width() / 4.0),
|
||||||
|
option.rect.y() + qRound(option.rect.height() / 4.0),
|
||||||
|
option.rect.width() / 2,
|
||||||
|
option.rect.height() / 2);
|
||||||
|
painter->save();
|
||||||
|
painter->fillRect(coloredRect, index.data().value<QColor>());
|
||||||
|
painter->setPen(Qt::black);
|
||||||
|
painter->drawRect(coloredRect);
|
||||||
|
painter->restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVWorld::CommandDelegate *CSVWorld::ColorDelegateFactory::makeDelegate(CSMWorld::CommandDispatcher *dispatcher,
|
||||||
|
CSMDoc::Document &document,
|
||||||
|
QObject *parent) const
|
||||||
|
{
|
||||||
|
return new ColorDelegate(dispatcher, document, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
37
apps/opencs/view/world/colordelegate.hpp
Normal file
37
apps/opencs/view/world/colordelegate.hpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#ifndef CSV_WORLD_COLORDELEGATE_HPP
|
||||||
|
#define CSV_WORLD_COLORDELEGATE_HPP
|
||||||
|
|
||||||
|
#include "util.hpp"
|
||||||
|
|
||||||
|
class QRect;
|
||||||
|
|
||||||
|
namespace CSVWidget
|
||||||
|
{
|
||||||
|
class ColorEditButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVWorld
|
||||||
|
{
|
||||||
|
class ColorDelegate : public CommandDelegate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ColorDelegate(CSMWorld::CommandDispatcher *dispatcher,
|
||||||
|
CSMDoc::Document& document,
|
||||||
|
QObject *parent);
|
||||||
|
|
||||||
|
virtual void paint(QPainter *painter,
|
||||||
|
const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ColorDelegateFactory : public CommandDelegateFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual CommandDelegate *makeDelegate(CSMWorld::CommandDispatcher *dispatcher,
|
||||||
|
CSMDoc::Document &document,
|
||||||
|
QObject *parent) const;
|
||||||
|
///< The ownership of the returned CommandDelegate is transferred to the caller.
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -15,8 +15,8 @@ void CSVWorld::Creator::setScope (unsigned int scope)
|
|||||||
CSVWorld::CreatorFactoryBase::~CreatorFactoryBase() {}
|
CSVWorld::CreatorFactoryBase::~CreatorFactoryBase() {}
|
||||||
|
|
||||||
|
|
||||||
CSVWorld::Creator *CSVWorld::NullCreatorFactory::makeCreator (CSMWorld::Data& data,
|
CSVWorld::Creator *CSVWorld::NullCreatorFactory::makeCreator (CSMDoc::Document& document,
|
||||||
QUndoStack& undoStack, const CSMWorld::UniversalId& id) const
|
const CSMWorld::UniversalId& id) const
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -5,16 +5,14 @@
|
|||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
#include "../../model/world/universalid.hpp"
|
#include "../../model/doc/document.hpp"
|
||||||
|
|
||||||
#include "../../model/world/scope.hpp"
|
#include "../../model/world/scope.hpp"
|
||||||
|
#include "../../model/world/universalid.hpp"
|
||||||
|
|
||||||
class QUndoStack;
|
namespace CSMDoc
|
||||||
|
|
||||||
namespace CSMWorld
|
|
||||||
{
|
{
|
||||||
class Data;
|
class Document;
|
||||||
class UniversalId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace CSVWorld
|
namespace CSVWorld
|
||||||
@ -59,8 +57,7 @@ namespace CSVWorld
|
|||||||
|
|
||||||
virtual ~CreatorFactoryBase();
|
virtual ~CreatorFactoryBase();
|
||||||
|
|
||||||
virtual Creator *makeCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
virtual Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const = 0;
|
||||||
const CSMWorld::UniversalId& id) const = 0;
|
|
||||||
///< The ownership of the returned Creator is transferred to the caller.
|
///< The ownership of the returned Creator is transferred to the caller.
|
||||||
///
|
///
|
||||||
/// \note The function can return a 0-pointer, which means no UI for creating/deleting
|
/// \note The function can return a 0-pointer, which means no UI for creating/deleting
|
||||||
@ -72,8 +69,7 @@ namespace CSVWorld
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual Creator *makeCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
virtual Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const;
|
||||||
const CSMWorld::UniversalId& id) const;
|
|
||||||
///< The ownership of the returned Creator is transferred to the caller.
|
///< The ownership of the returned Creator is transferred to the caller.
|
||||||
///
|
///
|
||||||
/// \note The function always returns 0.
|
/// \note The function always returns 0.
|
||||||
@ -84,8 +80,7 @@ namespace CSVWorld
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual Creator *makeCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
virtual Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const;
|
||||||
const CSMWorld::UniversalId& id) const;
|
|
||||||
///< The ownership of the returned Creator is transferred to the caller.
|
///< The ownership of the returned Creator is transferred to the caller.
|
||||||
///
|
///
|
||||||
/// \note The function can return a 0-pointer, which means no UI for creating/deleting
|
/// \note The function can return a 0-pointer, which means no UI for creating/deleting
|
||||||
@ -93,10 +88,10 @@ namespace CSVWorld
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<class CreatorT, unsigned int scope>
|
template<class CreatorT, unsigned int scope>
|
||||||
Creator *CreatorFactory<CreatorT, scope>::makeCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
Creator *CreatorFactory<CreatorT, scope>::makeCreator (CSMDoc::Document& document,
|
||||||
const CSMWorld::UniversalId& id) const
|
const CSMWorld::UniversalId& id) const
|
||||||
{
|
{
|
||||||
std::auto_ptr<CreatorT> creator (new CreatorT (data, undoStack, id));
|
std::auto_ptr<CreatorT> creator (new CreatorT (document.getData(), document.getUndoStack(), id));
|
||||||
|
|
||||||
creator->setScope (scope);
|
creator->setScope (scope);
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include <components/esm/loaddial.hpp>
|
#include <components/esm/loaddial.hpp>
|
||||||
|
|
||||||
|
#include "../../model/doc/document.hpp"
|
||||||
|
|
||||||
#include "../../model/world/data.hpp"
|
#include "../../model/world/data.hpp"
|
||||||
#include "../../model/world/commands.hpp"
|
#include "../../model/world/commands.hpp"
|
||||||
#include "../../model/world/columns.hpp"
|
#include "../../model/world/columns.hpp"
|
||||||
@ -22,14 +24,14 @@ CSVWorld::DialogueCreator::DialogueCreator (CSMWorld::Data& data, QUndoStack& un
|
|||||||
: GenericCreator (data, undoStack, id, true), mType (type)
|
: GenericCreator (data, undoStack, id, true), mType (type)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
CSVWorld::Creator *CSVWorld::TopicCreatorFactory::makeCreator (CSMWorld::Data& data,
|
CSVWorld::Creator *CSVWorld::TopicCreatorFactory::makeCreator (CSMDoc::Document& document,
|
||||||
QUndoStack& undoStack, const CSMWorld::UniversalId& id) const
|
const CSMWorld::UniversalId& id) const
|
||||||
{
|
{
|
||||||
return new DialogueCreator (data, undoStack, id, ESM::Dialogue::Topic);
|
return new DialogueCreator (document.getData(), document.getUndoStack(), id, ESM::Dialogue::Topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVWorld::Creator *CSVWorld::JournalCreatorFactory::makeCreator (CSMWorld::Data& data,
|
CSVWorld::Creator *CSVWorld::JournalCreatorFactory::makeCreator (CSMDoc::Document& document,
|
||||||
QUndoStack& undoStack, const CSMWorld::UniversalId& id) const
|
const CSMWorld::UniversalId& id) const
|
||||||
{
|
{
|
||||||
return new DialogueCreator (data, undoStack, id, ESM::Dialogue::Journal);
|
return new DialogueCreator (document.getData(), document.getUndoStack(), id, ESM::Dialogue::Journal);
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,7 @@ namespace CSVWorld
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual Creator *makeCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
virtual Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const;
|
||||||
const CSMWorld::UniversalId& id) const;
|
|
||||||
///< The ownership of the returned Creator is transferred to the caller.
|
///< The ownership of the returned Creator is transferred to the caller.
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -32,8 +31,7 @@ namespace CSVWorld
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual Creator *makeCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
virtual Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const;
|
||||||
const CSMWorld::UniversalId& id) const;
|
|
||||||
///< The ownership of the returned Creator is transferred to the caller.
|
///< The ownership of the returned Creator is transferred to the caller.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,8 @@
|
|||||||
#include "../../model/world/commands.hpp"
|
#include "../../model/world/commands.hpp"
|
||||||
#include "../../model/doc/document.hpp"
|
#include "../../model/doc/document.hpp"
|
||||||
|
|
||||||
|
#include "../widget/coloreditor.hpp"
|
||||||
|
|
||||||
#include "recordstatusdelegate.hpp"
|
#include "recordstatusdelegate.hpp"
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
#include "tablebottombox.hpp"
|
#include "tablebottombox.hpp"
|
||||||
@ -331,6 +333,10 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase::
|
|||||||
{
|
{
|
||||||
connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited()));
|
connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited()));
|
||||||
}
|
}
|
||||||
|
else if (qobject_cast<CSVWidget::ColorEditor *>(editor))
|
||||||
|
{
|
||||||
|
connect(editor, SIGNAL(pickingFinished()), proxy, SLOT(editorDataCommited()));
|
||||||
|
}
|
||||||
else // throw an exception because this is a coding error
|
else // throw an exception because this is a coding error
|
||||||
throw std::logic_error ("Dialogue editor type missing");
|
throw std::logic_error ("Dialogue editor type missing");
|
||||||
|
|
||||||
@ -679,8 +685,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM
|
|||||||
mMainLayout->addWidget(mEditWidget);
|
mMainLayout->addWidget(mEditWidget);
|
||||||
mEditWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
mEditWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
||||||
|
|
||||||
mMainLayout->addWidget (mBottom =
|
mMainLayout->addWidget (mBottom = new TableBottomBox (creatorFactory, document, id, this));
|
||||||
new TableBottomBox (creatorFactory, document.getData(), document.getUndoStack(), id, this));
|
|
||||||
|
|
||||||
mBottom->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
|
mBottom->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
|
||||||
|
|
||||||
|
@ -133,6 +133,15 @@ CSVWorld::GenericCreator::GenericCreator (CSMWorld::Data& data, QUndoStack& undo
|
|||||||
mClonedType (CSMWorld::UniversalId::Type_None), mScopes (CSMWorld::Scope_Content), mScope (0),
|
mClonedType (CSMWorld::UniversalId::Type_None), mScopes (CSMWorld::Scope_Content), mScope (0),
|
||||||
mScopeLabel (0), mCloneMode (false)
|
mScopeLabel (0), mCloneMode (false)
|
||||||
{
|
{
|
||||||
|
// If the collection ID has a parent type, use it instead.
|
||||||
|
// It will change IDs with Record/SubRecord class (used for creators in Dialogue subviews)
|
||||||
|
// to IDs with general RecordList class (used for creators in Table subviews).
|
||||||
|
CSMWorld::UniversalId::Type listParentType = CSMWorld::UniversalId::getParentType(mListId.getType());
|
||||||
|
if (listParentType != CSMWorld::UniversalId::Type_None)
|
||||||
|
{
|
||||||
|
mListId = listParentType;
|
||||||
|
}
|
||||||
|
|
||||||
mLayout = new QHBoxLayout;
|
mLayout = new QHBoxLayout;
|
||||||
mLayout->setContentsMargins (0, 0, 0, 0);
|
mLayout->setContentsMargins (0, 0, 0, 0);
|
||||||
|
|
||||||
|
@ -13,10 +13,12 @@ class QLineEdit;
|
|||||||
class QHBoxLayout;
|
class QHBoxLayout;
|
||||||
class QComboBox;
|
class QComboBox;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
|
class QUndoStack;
|
||||||
|
|
||||||
namespace CSMWorld
|
namespace CSMWorld
|
||||||
{
|
{
|
||||||
class CreateCommand;
|
class CreateCommand;
|
||||||
|
class Data;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace CSVWorld
|
namespace CSVWorld
|
||||||
|
@ -9,10 +9,13 @@
|
|||||||
|
|
||||||
#include <components/misc/stringops.hpp>
|
#include <components/misc/stringops.hpp>
|
||||||
|
|
||||||
|
#include "../../model/doc/document.hpp"
|
||||||
|
|
||||||
#include "../../model/world/data.hpp"
|
#include "../../model/world/data.hpp"
|
||||||
#include "../../model/world/commands.hpp"
|
#include "../../model/world/commands.hpp"
|
||||||
#include "../../model/world/columns.hpp"
|
#include "../../model/world/columns.hpp"
|
||||||
#include "../../model/world/idtable.hpp"
|
#include "../../model/world/idtable.hpp"
|
||||||
|
#include "../../model/world/idcompletionmanager.hpp"
|
||||||
|
|
||||||
std::string CSVWorld::InfoCreator::getId() const
|
std::string CSVWorld::InfoCreator::getId() const
|
||||||
{
|
{
|
||||||
@ -39,13 +42,19 @@ void CSVWorld::InfoCreator::configureCreateCommand (CSMWorld::CreateCommand& com
|
|||||||
}
|
}
|
||||||
|
|
||||||
CSVWorld::InfoCreator::InfoCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
CSVWorld::InfoCreator::InfoCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||||
const CSMWorld::UniversalId& id)
|
const CSMWorld::UniversalId& id, CSMWorld::IdCompletionManager& completionManager)
|
||||||
: GenericCreator (data, undoStack, id)
|
: GenericCreator (data, undoStack, id)
|
||||||
{
|
{
|
||||||
QLabel *label = new QLabel ("Topic", this);
|
QLabel *label = new QLabel ("Topic", this);
|
||||||
insertBeforeButtons (label, false);
|
insertBeforeButtons (label, false);
|
||||||
|
|
||||||
mTopic = new QLineEdit (this);
|
mTopic = new QLineEdit (this);
|
||||||
|
CSMWorld::ColumnBase::Display displayType = CSMWorld::ColumnBase::Display_Topic;
|
||||||
|
if (getCollectionId().getType() == CSMWorld::UniversalId::Type_JournalInfos)
|
||||||
|
{
|
||||||
|
displayType = CSMWorld::ColumnBase::Display_Journal;
|
||||||
|
}
|
||||||
|
mTopic->setCompleter(completionManager.getCompleter(displayType).get());
|
||||||
insertBeforeButtons (mTopic, true);
|
insertBeforeButtons (mTopic, true);
|
||||||
|
|
||||||
setManualEditing (false);
|
setManualEditing (false);
|
||||||
@ -100,3 +109,12 @@ void CSVWorld::InfoCreator::topicChanged()
|
|||||||
{
|
{
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CSVWorld::Creator *CSVWorld::InfoCreatorFactory::makeCreator(CSMDoc::Document& document,
|
||||||
|
const CSMWorld::UniversalId& id) const
|
||||||
|
{
|
||||||
|
return new InfoCreator(document.getData(),
|
||||||
|
document.getUndoStack(),
|
||||||
|
id,
|
||||||
|
document.getIdCompletionManager());
|
||||||
|
}
|
||||||
|
@ -8,6 +8,7 @@ class QLineEdit;
|
|||||||
namespace CSMWorld
|
namespace CSMWorld
|
||||||
{
|
{
|
||||||
class InfoCollection;
|
class InfoCollection;
|
||||||
|
class IdCompletionManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace CSVWorld
|
namespace CSVWorld
|
||||||
@ -25,7 +26,7 @@ namespace CSVWorld
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
InfoCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
InfoCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||||
const CSMWorld::UniversalId& id);
|
const CSMWorld::UniversalId& id, CSMWorld::IdCompletionManager& completionManager);
|
||||||
|
|
||||||
virtual void cloneMode (const std::string& originId,
|
virtual void cloneMode (const std::string& originId,
|
||||||
const CSMWorld::UniversalId::Type type);
|
const CSMWorld::UniversalId::Type type);
|
||||||
@ -43,6 +44,14 @@ namespace CSVWorld
|
|||||||
|
|
||||||
void topicChanged();
|
void topicChanged();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class InfoCreatorFactory : public CreatorFactoryBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const;
|
||||||
|
///< The ownership of the returned Creator is transferred to the caller.
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -4,10 +4,13 @@
|
|||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
|
|
||||||
|
#include "../../model/doc/document.hpp"
|
||||||
|
|
||||||
#include "../../model/world/data.hpp"
|
#include "../../model/world/data.hpp"
|
||||||
#include "../../model/world/commands.hpp"
|
#include "../../model/world/commands.hpp"
|
||||||
#include "../../model/world/columns.hpp"
|
#include "../../model/world/columns.hpp"
|
||||||
#include "../../model/world/idtable.hpp"
|
#include "../../model/world/idtable.hpp"
|
||||||
|
#include "../../model/world/idcompletionmanager.hpp"
|
||||||
|
|
||||||
std::string CSVWorld::ReferenceCreator::getId() const
|
std::string CSVWorld::ReferenceCreator::getId() const
|
||||||
{
|
{
|
||||||
@ -71,13 +74,14 @@ int CSVWorld::ReferenceCreator::getRefNumCount() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
CSVWorld::ReferenceCreator::ReferenceCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
CSVWorld::ReferenceCreator::ReferenceCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||||
const CSMWorld::UniversalId& id)
|
const CSMWorld::UniversalId& id, CSMWorld::IdCompletionManager &completionManager)
|
||||||
: GenericCreator (data, undoStack, id)
|
: GenericCreator (data, undoStack, id)
|
||||||
{
|
{
|
||||||
QLabel *label = new QLabel ("Cell", this);
|
QLabel *label = new QLabel ("Cell", this);
|
||||||
insertBeforeButtons (label, false);
|
insertBeforeButtons (label, false);
|
||||||
|
|
||||||
mCell = new QLineEdit (this);
|
mCell = new QLineEdit (this);
|
||||||
|
mCell->setCompleter(completionManager.getCompleter(CSMWorld::ColumnBase::Display_Cell).get());
|
||||||
insertBeforeButtons (mCell, true);
|
insertBeforeButtons (mCell, true);
|
||||||
|
|
||||||
setManualEditing (false);
|
setManualEditing (false);
|
||||||
@ -142,3 +146,12 @@ void CSVWorld::ReferenceCreator::cloneMode(const std::string& originId,
|
|||||||
CSVWorld::GenericCreator::cloneMode(originId, type);
|
CSVWorld::GenericCreator::cloneMode(originId, type);
|
||||||
cellChanged(); //otherwise ok button will remain disabled
|
cellChanged(); //otherwise ok button will remain disabled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CSVWorld::Creator *CSVWorld::ReferenceCreatorFactory::makeCreator (CSMDoc::Document& document,
|
||||||
|
const CSMWorld::UniversalId& id) const
|
||||||
|
{
|
||||||
|
return new ReferenceCreator(document.getData(),
|
||||||
|
document.getUndoStack(),
|
||||||
|
id,
|
||||||
|
document.getIdCompletionManager());
|
||||||
|
}
|
||||||
|
@ -5,8 +5,14 @@
|
|||||||
|
|
||||||
class QLineEdit;
|
class QLineEdit;
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
class IdCompletionManager;
|
||||||
|
}
|
||||||
|
|
||||||
namespace CSVWorld
|
namespace CSVWorld
|
||||||
{
|
{
|
||||||
|
|
||||||
class ReferenceCreator : public GenericCreator
|
class ReferenceCreator : public GenericCreator
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -28,7 +34,7 @@ namespace CSVWorld
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
ReferenceCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
ReferenceCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||||
const CSMWorld::UniversalId& id);
|
const CSMWorld::UniversalId& id, CSMWorld::IdCompletionManager &completionManager);
|
||||||
|
|
||||||
virtual void cloneMode(const std::string& originId,
|
virtual void cloneMode(const std::string& originId,
|
||||||
const CSMWorld::UniversalId::Type type);
|
const CSMWorld::UniversalId::Type type);
|
||||||
@ -46,6 +52,14 @@ namespace CSVWorld
|
|||||||
|
|
||||||
void cellChanged();
|
void cellChanged();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ReferenceCreatorFactory : public CreatorFactoryBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const;
|
||||||
|
///< The ownership of the returned Creator is transferred to the caller.
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -33,9 +33,7 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D
|
|||||||
|
|
||||||
layout->setContentsMargins (QMargins (0, 0, 0, 0));
|
layout->setContentsMargins (QMargins (0, 0, 0, 0));
|
||||||
|
|
||||||
layout->addWidget (mBottom =
|
layout->addWidget (mBottom = new TableBottomBox (NullCreatorFactory(), document, id, this), 0);
|
||||||
new TableBottomBox (NullCreatorFactory(), document.getData(), document.getUndoStack(), id,
|
|
||||||
this), 0);
|
|
||||||
|
|
||||||
mLayout->setContentsMargins (QMargins (0, 0, 0, 0));
|
mLayout->setContentsMargins (QMargins (0, 0, 0, 0));
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
|||||||
new CSVDoc::SubViewFactoryWithCreator<TableSubView, CreatorFactory<ReferenceableCreator> >);
|
new CSVDoc::SubViewFactoryWithCreator<TableSubView, CreatorFactory<ReferenceableCreator> >);
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_References,
|
manager.add (CSMWorld::UniversalId::Type_References,
|
||||||
new CSVDoc::SubViewFactoryWithCreator<TableSubView, CreatorFactory<ReferenceCreator> >);
|
new CSVDoc::SubViewFactoryWithCreator<TableSubView, ReferenceCreatorFactory>);
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_Topics,
|
manager.add (CSMWorld::UniversalId::Type_Topics,
|
||||||
new CSVDoc::SubViewFactoryWithCreator<TableSubView, TopicCreatorFactory>);
|
new CSVDoc::SubViewFactoryWithCreator<TableSubView, TopicCreatorFactory>);
|
||||||
@ -68,10 +68,10 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
|||||||
new CSVDoc::SubViewFactoryWithCreator<TableSubView, JournalCreatorFactory>);
|
new CSVDoc::SubViewFactoryWithCreator<TableSubView, JournalCreatorFactory>);
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_TopicInfos,
|
manager.add (CSMWorld::UniversalId::Type_TopicInfos,
|
||||||
new CSVDoc::SubViewFactoryWithCreator<TableSubView, CreatorFactory<InfoCreator> >);
|
new CSVDoc::SubViewFactoryWithCreator<TableSubView, InfoCreatorFactory>);
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_JournalInfos,
|
manager.add (CSMWorld::UniversalId::Type_JournalInfos,
|
||||||
new CSVDoc::SubViewFactoryWithCreator<TableSubView, CreatorFactory<InfoCreator> >);
|
new CSVDoc::SubViewFactoryWithCreator<TableSubView, InfoCreatorFactory>);
|
||||||
|
|
||||||
// Subviews for resources tables
|
// Subviews for resources tables
|
||||||
manager.add (CSMWorld::UniversalId::Type_Meshes,
|
manager.add (CSMWorld::UniversalId::Type_Meshes,
|
||||||
@ -147,16 +147,16 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
|||||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<ReferenceableCreator> > (false));
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<ReferenceableCreator> > (false));
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_Reference,
|
manager.add (CSMWorld::UniversalId::Type_Reference,
|
||||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<ReferenceCreator> > (false));
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, ReferenceCreatorFactory> (false));
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_Cell,
|
manager.add (CSMWorld::UniversalId::Type_Cell,
|
||||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<CellCreator> > (false));
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<CellCreator> > (false));
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_JournalInfo,
|
manager.add (CSMWorld::UniversalId::Type_JournalInfo,
|
||||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<InfoCreator> > (false));
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, InfoCreatorFactory> (false));
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_TopicInfo,
|
manager.add (CSMWorld::UniversalId::Type_TopicInfo,
|
||||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<InfoCreator> >(false));
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, InfoCreatorFactory>(false));
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_Topic,
|
manager.add (CSMWorld::UniversalId::Type_Topic,
|
||||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, TopicCreatorFactory> (false));
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, TopicCreatorFactory> (false));
|
||||||
|
@ -39,8 +39,10 @@ void CSVWorld::TableBottomBox::updateStatus()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVWorld::TableBottomBox::TableBottomBox (const CreatorFactoryBase& creatorFactory,
|
CSVWorld::TableBottomBox::TableBottomBox (const CreatorFactoryBase& creatorFactory,
|
||||||
CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id, QWidget *parent)
|
CSMDoc::Document& document,
|
||||||
|
const CSMWorld::UniversalId& id,
|
||||||
|
QWidget *parent)
|
||||||
: QWidget (parent), mShowStatusBar (false), mCreating (false)
|
: QWidget (parent), mShowStatusBar (false), mCreating (false)
|
||||||
{
|
{
|
||||||
for (int i=0; i<4; ++i)
|
for (int i=0; i<4; ++i)
|
||||||
@ -61,7 +63,7 @@ CSVWorld::TableBottomBox::TableBottomBox (const CreatorFactoryBase& creatorFacto
|
|||||||
|
|
||||||
setLayout (mLayout);
|
setLayout (mLayout);
|
||||||
|
|
||||||
mCreator = creatorFactory.makeCreator (data, undoStack, id);
|
mCreator = creatorFactory.makeCreator (document, id);
|
||||||
|
|
||||||
if (mCreator)
|
if (mCreator)
|
||||||
{
|
{
|
||||||
|
@ -9,10 +9,9 @@ class QStackedLayout;
|
|||||||
class QStatusBar;
|
class QStatusBar;
|
||||||
class QUndoStack;
|
class QUndoStack;
|
||||||
|
|
||||||
namespace CSMWorld
|
namespace CSMDoc
|
||||||
{
|
{
|
||||||
class Data;
|
class Document;
|
||||||
class UniversalId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace CSVWorld
|
namespace CSVWorld
|
||||||
@ -42,8 +41,10 @@ namespace CSVWorld
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TableBottomBox (const CreatorFactoryBase& creatorFactory, CSMWorld::Data& data,
|
TableBottomBox (const CreatorFactoryBase& creatorFactory,
|
||||||
QUndoStack& undoStack, const CSMWorld::UniversalId& id, QWidget *parent = 0);
|
CSMDoc::Document& document,
|
||||||
|
const CSMWorld::UniversalId& id,
|
||||||
|
QWidget *parent = 0);
|
||||||
|
|
||||||
virtual ~TableBottomBox();
|
virtual ~TableBottomBox();
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::D
|
|||||||
layout->setContentsMargins (QMargins (0, 0, 0, 0));
|
layout->setContentsMargins (QMargins (0, 0, 0, 0));
|
||||||
|
|
||||||
layout->addWidget (mBottom =
|
layout->addWidget (mBottom =
|
||||||
new TableBottomBox (creatorFactory, document.getData(), document.getUndoStack(), id, this), 0);
|
new TableBottomBox (creatorFactory, document, id, this), 0);
|
||||||
|
|
||||||
layout->insertWidget (0, mTable =
|
layout->insertWidget (0, mTable =
|
||||||
new Table (id, mBottom->canCreateAndDelete(), sorting, document), 2);
|
new Table (id, mBottom->canCreateAndDelete(), sorting, document), 2);
|
||||||
|
@ -17,6 +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 "../widget/coloreditor.hpp"
|
||||||
#include "dialoguespinbox.hpp"
|
#include "dialoguespinbox.hpp"
|
||||||
#include "scriptedit.hpp"
|
#include "scriptedit.hpp"
|
||||||
|
|
||||||
@ -123,10 +124,19 @@ void CSVWorld::CommandDelegate::setModelDataImp (QWidget *editor, QAbstractItemM
|
|||||||
if (!mCommandDispatcher)
|
if (!mCommandDispatcher)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
NastyTableModelHack hack (*model);
|
QVariant new_;
|
||||||
QStyledItemDelegate::setModelData (editor, &hack, index);
|
// Color columns use a custom editor, so we need explicitly extract a data from it
|
||||||
|
CSVWidget::ColorEditor *colorEditor = qobject_cast<CSVWidget::ColorEditor *>(editor);
|
||||||
QVariant new_ = hack.getData();
|
if (colorEditor != NULL)
|
||||||
|
{
|
||||||
|
new_ = colorEditor->color();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NastyTableModelHack hack (*model);
|
||||||
|
QStyledItemDelegate::setModelData (editor, &hack, index);
|
||||||
|
new_ = hack.getData();
|
||||||
|
}
|
||||||
|
|
||||||
if ((model->data (index)!=new_) && (model->flags(index) & Qt::ItemIsEditable))
|
if ((model->data (index)!=new_) && (model->flags(index) & Qt::ItemIsEditable))
|
||||||
mCommandDispatcher->executeModify (model, index, new_);
|
mCommandDispatcher->executeModify (model, index, new_);
|
||||||
@ -162,6 +172,12 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO
|
|||||||
{
|
{
|
||||||
return QStyledItemDelegate::createEditor(parent, option, index);
|
return QStyledItemDelegate::createEditor(parent, option, index);
|
||||||
}
|
}
|
||||||
|
// For tables the pop-up of the color editor should appear immediately after the editor creation
|
||||||
|
// (the third parameter of ColorEditor's constructor)
|
||||||
|
else if (display == CSMWorld::ColumnBase::Display_Colour)
|
||||||
|
{
|
||||||
|
return new CSVWidget::ColorEditor(index.data().value<QColor>(), parent, true);
|
||||||
|
}
|
||||||
return createEditor (parent, option, index, display);
|
return createEditor (parent, option, index, display);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +200,7 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO
|
|||||||
{
|
{
|
||||||
case CSMWorld::ColumnBase::Display_Colour:
|
case CSMWorld::ColumnBase::Display_Colour:
|
||||||
|
|
||||||
return new QLineEdit(parent);
|
return new CSVWidget::ColorEditor(index.data().value<QColor>(), parent);
|
||||||
|
|
||||||
case CSMWorld::ColumnBase::Display_Integer:
|
case CSMWorld::ColumnBase::Display_Integer:
|
||||||
{
|
{
|
||||||
@ -284,6 +300,14 @@ void CSVWorld::CommandDelegate::setEditorData (QWidget *editor, const QModelInde
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Color columns use a custom editor, so we need explicitly set a data for it
|
||||||
|
CSVWidget::ColorEditor *colorEditor = qobject_cast<CSVWidget::ColorEditor *>(editor);
|
||||||
|
if (colorEditor != NULL)
|
||||||
|
{
|
||||||
|
colorEditor->setColor(index.data().value<QColor>());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QByteArray n = editor->metaObject()->userProperty().name();
|
QByteArray n = editor->metaObject()->userProperty().name();
|
||||||
|
|
||||||
if (n == "dateTime") {
|
if (n == "dateTime") {
|
||||||
|
@ -641,9 +641,6 @@ namespace MWMechanics
|
|||||||
if (mAllowedNodes.empty())
|
if (mAllowedNodes.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (actor.getClass().isPureWaterCreature(actor))
|
|
||||||
return;
|
|
||||||
|
|
||||||
state.moveIn(new AiWanderStorage());
|
state.moveIn(new AiWanderStorage());
|
||||||
|
|
||||||
int index = Misc::Rng::rollDice(mAllowedNodes.size());
|
int index = Misc::Rng::rollDice(mAllowedNodes.size());
|
||||||
@ -690,7 +687,8 @@ namespace MWMechanics
|
|||||||
// actor can wander from the spawn position. AiWander assumes that
|
// actor can wander from the spawn position. AiWander assumes that
|
||||||
// pathgrid points are available, and uses them to randomly select wander
|
// pathgrid points are available, and uses them to randomly select wander
|
||||||
// destinations within the allowed set of pathgrid points (nodes).
|
// destinations within the allowed set of pathgrid points (nodes).
|
||||||
if(mDistance)
|
// ... pathgrids don't usually include water, so swimmers ignore them
|
||||||
|
if (mDistance && !actor.getClass().isPureWaterCreature(actor))
|
||||||
{
|
{
|
||||||
float cellXOffset = 0;
|
float cellXOffset = 0;
|
||||||
float cellYOffset = 0;
|
float cellYOffset = 0;
|
||||||
|
@ -20,7 +20,7 @@ namespace MWMechanics
|
|||||||
mKnockdown(false), mKnockdownOneFrame(false), mKnockdownOverOneFrame(false),
|
mKnockdown(false), mKnockdownOneFrame(false), mKnockdownOverOneFrame(false),
|
||||||
mHitRecovery(false), mBlock(false), mMovementFlags(0), mAttackStrength(0.f),
|
mHitRecovery(false), mBlock(false), mMovementFlags(0), mAttackStrength(0.f),
|
||||||
mFallHeight(0), mRecalcMagicka(false), mLastRestock(0,0), mGoldPool(0), mActorId(-1),
|
mFallHeight(0), mRecalcMagicka(false), mLastRestock(0,0), mGoldPool(0), mActorId(-1),
|
||||||
mDeathAnimation(0), mIsWerewolf(false), mLevel (0)
|
mDeathAnimation(0), mLevel (0)
|
||||||
{
|
{
|
||||||
for (int i=0; i<4; ++i)
|
for (int i=0; i<4; ++i)
|
||||||
mAiSettings[i] = 0;
|
mAiSettings[i] = 0;
|
||||||
@ -55,7 +55,7 @@ namespace MWMechanics
|
|||||||
if (index < 0 || index > 7) {
|
if (index < 0 || index > 7) {
|
||||||
throw std::runtime_error("attribute index is out of range");
|
throw std::runtime_error("attribute index is out of range");
|
||||||
}
|
}
|
||||||
return (!mIsWerewolf ? mAttributes[index] : mWerewolfAttributes[index]);
|
return mAttributes[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
const DynamicStat<float> &CreatureStats::getHealth() const
|
const DynamicStat<float> &CreatureStats::getHealth() const
|
||||||
@ -139,14 +139,11 @@ namespace MWMechanics
|
|||||||
throw std::runtime_error("attribute index is out of range");
|
throw std::runtime_error("attribute index is out of range");
|
||||||
}
|
}
|
||||||
|
|
||||||
const AttributeValue& currentValue = !mIsWerewolf ? mAttributes[index] : mWerewolfAttributes[index];
|
const AttributeValue& currentValue = mAttributes[index];
|
||||||
|
|
||||||
if (value != currentValue)
|
if (value != currentValue)
|
||||||
{
|
{
|
||||||
if(!mIsWerewolf)
|
mAttributes[index] = value;
|
||||||
mAttributes[index] = value;
|
|
||||||
else
|
|
||||||
mWerewolfAttributes[index] = value;
|
|
||||||
|
|
||||||
if (index == ESM::Attribute::Intelligence)
|
if (index == ESM::Attribute::Intelligence)
|
||||||
mRecalcMagicka = true;
|
mRecalcMagicka = true;
|
||||||
|
@ -77,10 +77,6 @@ namespace MWMechanics
|
|||||||
std::vector<int> mSummonGraveyard;
|
std::vector<int> mSummonGraveyard;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// These two are only set by NpcStats, but they are declared in CreatureStats to prevent using virtual methods.
|
|
||||||
bool mIsWerewolf;
|
|
||||||
AttributeValue mWerewolfAttributes[8];
|
|
||||||
|
|
||||||
int mLevel;
|
int mLevel;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -32,6 +32,7 @@ MWMechanics::NpcStats::NpcStats()
|
|||||||
, mWerewolfKills (0)
|
, mWerewolfKills (0)
|
||||||
, mLevelProgress(0)
|
, mLevelProgress(0)
|
||||||
, mTimeToStartDrowning(20.0)
|
, mTimeToStartDrowning(20.0)
|
||||||
|
, mIsWerewolf(false)
|
||||||
{
|
{
|
||||||
mSkillIncreases.resize (ESM::Attribute::Length, 0);
|
mSkillIncreases.resize (ESM::Attribute::Length, 0);
|
||||||
}
|
}
|
||||||
@ -51,7 +52,7 @@ const MWMechanics::SkillValue& MWMechanics::NpcStats::getSkill (int index) const
|
|||||||
if (index<0 || index>=ESM::Skill::Length)
|
if (index<0 || index>=ESM::Skill::Length)
|
||||||
throw std::runtime_error ("skill index out of range");
|
throw std::runtime_error ("skill index out of range");
|
||||||
|
|
||||||
return (!mIsWerewolf ? mSkill[index] : mWerewolfSkill[index]);
|
return mSkill[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
MWMechanics::SkillValue& MWMechanics::NpcStats::getSkill (int index)
|
MWMechanics::SkillValue& MWMechanics::NpcStats::getSkill (int index)
|
||||||
@ -59,7 +60,15 @@ MWMechanics::SkillValue& MWMechanics::NpcStats::getSkill (int index)
|
|||||||
if (index<0 || index>=ESM::Skill::Length)
|
if (index<0 || index>=ESM::Skill::Length)
|
||||||
throw std::runtime_error ("skill index out of range");
|
throw std::runtime_error ("skill index out of range");
|
||||||
|
|
||||||
return (!mIsWerewolf ? mSkill[index] : mWerewolfSkill[index]);
|
return mSkill[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void MWMechanics::NpcStats::setSkill(int index, const MWMechanics::SkillValue &value)
|
||||||
|
{
|
||||||
|
if (index<0 || index>=ESM::Skill::Length)
|
||||||
|
throw std::runtime_error ("skill index out of range");
|
||||||
|
|
||||||
|
mSkill[index] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<std::string, int>& MWMechanics::NpcStats::getFactionRanks() const
|
const std::map<std::string, int>& MWMechanics::NpcStats::getFactionRanks() const
|
||||||
@ -188,10 +197,6 @@ float MWMechanics::NpcStats::getSkillProgressRequirement (int skillIndex, const
|
|||||||
|
|
||||||
void MWMechanics::NpcStats::useSkill (int skillIndex, const ESM::Class& class_, int usageType, float extraFactor)
|
void MWMechanics::NpcStats::useSkill (int skillIndex, const ESM::Class& class_, int usageType, float extraFactor)
|
||||||
{
|
{
|
||||||
// Don't increase skills as a werewolf
|
|
||||||
if(mIsWerewolf)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const ESM::Skill *skill =
|
const ESM::Skill *skill =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Skill>().find (skillIndex);
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Skill>().find (skillIndex);
|
||||||
float skillGain = 1;
|
float skillGain = 1;
|
||||||
@ -403,34 +408,12 @@ bool MWMechanics::NpcStats::isWerewolf() const
|
|||||||
|
|
||||||
void MWMechanics::NpcStats::setWerewolf (bool set)
|
void MWMechanics::NpcStats::setWerewolf (bool set)
|
||||||
{
|
{
|
||||||
|
if (mIsWerewolf == set)
|
||||||
|
return;
|
||||||
|
|
||||||
if(set != false)
|
if(set != false)
|
||||||
{
|
{
|
||||||
const MWWorld::Store<ESM::GameSetting> &gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
|
||||||
|
|
||||||
mWerewolfKills = 0;
|
mWerewolfKills = 0;
|
||||||
|
|
||||||
for(size_t i = 0;i < ESM::Attribute::Length;i++)
|
|
||||||
{
|
|
||||||
mWerewolfAttributes[i] = getAttribute(i);
|
|
||||||
// Oh, Bethesda. It's "Intelligence".
|
|
||||||
std::string name = "fWerewolf"+((i==ESM::Attribute::Intelligence) ? std::string("Intellegence") :
|
|
||||||
ESM::Attribute::sAttributeNames[i]);
|
|
||||||
mWerewolfAttributes[i].setBase(int(gmst.find(name)->getFloat()));
|
|
||||||
}
|
|
||||||
|
|
||||||
for(size_t i = 0;i < ESM::Skill::Length;i++)
|
|
||||||
{
|
|
||||||
mWerewolfSkill[i] = getSkill(i);
|
|
||||||
|
|
||||||
// Acrobatics is set separately for some reason.
|
|
||||||
if(i == ESM::Skill::Acrobatics)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// "Mercantile"! >_<
|
|
||||||
std::string name = "fWerewolf"+((i==ESM::Skill::Mercantile) ? std::string("Merchantile") :
|
|
||||||
ESM::Skill::sSkillNames[i]);
|
|
||||||
mWerewolfSkill[i].setBase(int(gmst.find(name)->getFloat()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
mIsWerewolf = set;
|
mIsWerewolf = set;
|
||||||
}
|
}
|
||||||
@ -464,14 +447,8 @@ void MWMechanics::NpcStats::writeState (ESM::NpcStats& state) const
|
|||||||
state.mDisposition = mDisposition;
|
state.mDisposition = mDisposition;
|
||||||
|
|
||||||
for (int i=0; i<ESM::Skill::Length; ++i)
|
for (int i=0; i<ESM::Skill::Length; ++i)
|
||||||
{
|
mSkill[i].writeState (state.mSkills[i]);
|
||||||
mSkill[i].writeState (state.mSkills[i].mRegular);
|
|
||||||
mWerewolfSkill[i].writeState (state.mSkills[i].mWerewolf);
|
|
||||||
}
|
|
||||||
for (int i=0; i<ESM::Attribute::Length; ++i)
|
|
||||||
{
|
|
||||||
mWerewolfAttributes[i].writeState (state.mWerewolfAttributes[i]);
|
|
||||||
}
|
|
||||||
state.mIsWerewolf = mIsWerewolf;
|
state.mIsWerewolf = mIsWerewolf;
|
||||||
|
|
||||||
state.mCrimeId = mCrimeId;
|
state.mCrimeId = mCrimeId;
|
||||||
@ -519,14 +496,7 @@ void MWMechanics::NpcStats::readState (const ESM::NpcStats& state)
|
|||||||
mDisposition = state.mDisposition;
|
mDisposition = state.mDisposition;
|
||||||
|
|
||||||
for (int i=0; i<ESM::Skill::Length; ++i)
|
for (int i=0; i<ESM::Skill::Length; ++i)
|
||||||
{
|
mSkill[i].readState (state.mSkills[i]);
|
||||||
mSkill[i].readState (state.mSkills[i].mRegular);
|
|
||||||
mWerewolfSkill[i].readState (state.mSkills[i].mWerewolf);
|
|
||||||
}
|
|
||||||
for (int i=0; i<ESM::Attribute::Length; ++i)
|
|
||||||
{
|
|
||||||
mWerewolfAttributes[i].readState (state.mWerewolfAttributes[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
mIsWerewolf = state.mIsWerewolf;
|
mIsWerewolf = state.mIsWerewolf;
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ namespace MWMechanics
|
|||||||
{
|
{
|
||||||
int mDisposition;
|
int mDisposition;
|
||||||
SkillValue mSkill[ESM::Skill::Length]; // SkillValue.mProgress used by the player only
|
SkillValue mSkill[ESM::Skill::Length]; // SkillValue.mProgress used by the player only
|
||||||
SkillValue mWerewolfSkill[ESM::Skill::Length];
|
|
||||||
int mReputation;
|
int mReputation;
|
||||||
int mCrimeId;
|
int mCrimeId;
|
||||||
|
|
||||||
@ -41,6 +41,8 @@ namespace MWMechanics
|
|||||||
/// Countdown to getting damage while underwater
|
/// Countdown to getting damage while underwater
|
||||||
float mTimeToStartDrowning;
|
float mTimeToStartDrowning;
|
||||||
|
|
||||||
|
bool mIsWerewolf;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
NpcStats();
|
NpcStats();
|
||||||
@ -56,6 +58,7 @@ namespace MWMechanics
|
|||||||
|
|
||||||
const SkillValue& getSkill (int index) const;
|
const SkillValue& getSkill (int index) const;
|
||||||
SkillValue& getSkill (int index);
|
SkillValue& getSkill (int index);
|
||||||
|
void setSkill(int index, const SkillValue& value);
|
||||||
|
|
||||||
const std::map<std::string, int>& getFactionRanks() const;
|
const std::map<std::string, int>& getFactionRanks() const;
|
||||||
/// Increase the rank in this faction by 1, if such a rank exists.
|
/// Increase the rank in this faction by 1, if such a rank exists.
|
||||||
|
@ -48,6 +48,55 @@ namespace MWWorld
|
|||||||
mPlayer.mData.setPosition(playerPos);
|
mPlayer.mData.setPosition(playerPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::saveSkillsAttributes()
|
||||||
|
{
|
||||||
|
MWMechanics::NpcStats& stats = getPlayer().getClass().getNpcStats(getPlayer());
|
||||||
|
for (int i=0; i<ESM::Skill::Length; ++i)
|
||||||
|
mSaveSkills[i] = stats.getSkill(i);
|
||||||
|
for (int i=0; i<ESM::Attribute::Length; ++i)
|
||||||
|
mSaveAttributes[i] = stats.getAttribute(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::restoreSkillsAttributes()
|
||||||
|
{
|
||||||
|
MWMechanics::NpcStats& stats = getPlayer().getClass().getNpcStats(getPlayer());
|
||||||
|
for (int i=0; i<ESM::Skill::Length; ++i)
|
||||||
|
stats.setSkill(i, mSaveSkills[i]);
|
||||||
|
for (int i=0; i<ESM::Attribute::Length; ++i)
|
||||||
|
stats.setAttribute(i, mSaveAttributes[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::setWerewolfSkillsAttributes()
|
||||||
|
{
|
||||||
|
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
MWMechanics::NpcStats& stats = getPlayer().getClass().getNpcStats(getPlayer());
|
||||||
|
for(size_t i = 0;i < ESM::Attribute::Length;++i)
|
||||||
|
{
|
||||||
|
// Oh, Bethesda. It's "Intelligence".
|
||||||
|
std::string name = "fWerewolf"+((i==ESM::Attribute::Intelligence) ? std::string("Intellegence") :
|
||||||
|
ESM::Attribute::sAttributeNames[i]);
|
||||||
|
|
||||||
|
MWMechanics::AttributeValue value = stats.getAttribute(i);
|
||||||
|
value.setBase(int(gmst.find(name)->getFloat()));
|
||||||
|
stats.setAttribute(i, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t i = 0;i < ESM::Skill::Length;i++)
|
||||||
|
{
|
||||||
|
// Acrobatics is set separately for some reason.
|
||||||
|
if(i == ESM::Skill::Acrobatics)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// "Mercantile"! >_<
|
||||||
|
std::string name = "fWerewolf"+((i==ESM::Skill::Mercantile) ? std::string("Merchantile") :
|
||||||
|
ESM::Skill::sSkillNames[i]);
|
||||||
|
|
||||||
|
MWMechanics::SkillValue value = stats.getSkill(i);
|
||||||
|
value.setBase(int(gmst.find(name)->getFloat()));
|
||||||
|
stats.setSkill(i, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Player::set(const ESM::NPC *player)
|
void Player::set(const ESM::NPC *player)
|
||||||
{
|
{
|
||||||
mPlayer.mBase = player;
|
mPlayer.mBase = player;
|
||||||
@ -221,6 +270,11 @@ namespace MWWorld
|
|||||||
|
|
||||||
player.mAutoMove = mAutoMove ? 1 : 0;
|
player.mAutoMove = mAutoMove ? 1 : 0;
|
||||||
|
|
||||||
|
for (int i=0; i<ESM::Attribute::Length; ++i)
|
||||||
|
mSaveAttributes[i].writeState(player.mSaveAttributes[i]);
|
||||||
|
for (int i=0; i<ESM::Skill::Length; ++i)
|
||||||
|
mSaveSkills[i].writeState(player.mSaveSkills[i]);
|
||||||
|
|
||||||
writer.startRecord (ESM::REC_PLAY);
|
writer.startRecord (ESM::REC_PLAY);
|
||||||
player.save (writer);
|
player.save (writer);
|
||||||
writer.endRecord (ESM::REC_PLAY);
|
writer.endRecord (ESM::REC_PLAY);
|
||||||
@ -241,6 +295,17 @@ namespace MWWorld
|
|||||||
|
|
||||||
mPlayer.load (player.mObject);
|
mPlayer.load (player.mObject);
|
||||||
|
|
||||||
|
for (int i=0; i<ESM::Attribute::Length; ++i)
|
||||||
|
mSaveAttributes[i].readState(player.mSaveAttributes[i]);
|
||||||
|
for (int i=0; i<ESM::Skill::Length; ++i)
|
||||||
|
mSaveSkills[i].readState(player.mSaveSkills[i]);
|
||||||
|
|
||||||
|
if (player.mObject.mNpcStats.mWerewolfDeprecatedData && player.mObject.mNpcStats.mIsWerewolf)
|
||||||
|
{
|
||||||
|
saveSkillsAttributes();
|
||||||
|
setWerewolfSkillsAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
getPlayer().getClass().getCreatureStats(getPlayer()).getAiSequence().clear();
|
getPlayer().getClass().getCreatureStats(getPlayer()).getAiSequence().clear();
|
||||||
|
|
||||||
MWBase::World& world = *MWBase::Environment::get().getWorld();
|
MWBase::World& world = *MWBase::Environment::get().getWorld();
|
||||||
|
@ -5,6 +5,10 @@
|
|||||||
#include "../mwworld/livecellref.hpp"
|
#include "../mwworld/livecellref.hpp"
|
||||||
|
|
||||||
#include "../mwmechanics/drawstate.hpp"
|
#include "../mwmechanics/drawstate.hpp"
|
||||||
|
#include "../mwmechanics/stat.hpp"
|
||||||
|
|
||||||
|
#include <components/esm/loadskil.hpp>
|
||||||
|
#include <components/esm/attr.hpp>
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
@ -48,10 +52,18 @@ namespace MWWorld
|
|||||||
int mCurrentCrimeId; // the id assigned witnesses
|
int mCurrentCrimeId; // the id assigned witnesses
|
||||||
int mPaidCrimeId; // the last id paid off (0 bounty)
|
int mPaidCrimeId; // the last id paid off (0 bounty)
|
||||||
|
|
||||||
|
// Saved skills and attributes prior to becoming a werewolf
|
||||||
|
MWMechanics::SkillValue mSaveSkills[ESM::Skill::Length];
|
||||||
|
MWMechanics::AttributeValue mSaveAttributes[ESM::Attribute::Length];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Player(const ESM::NPC *player, const MWBase::World& world);
|
Player(const ESM::NPC *player, const MWBase::World& world);
|
||||||
|
|
||||||
|
void saveSkillsAttributes();
|
||||||
|
void restoreSkillsAttributes();
|
||||||
|
void setWerewolfSkillsAttributes();
|
||||||
|
|
||||||
// For mark/recall magic effects
|
// For mark/recall magic effects
|
||||||
void markPosition (CellStore* markedCell, ESM::Position markedPosition);
|
void markPosition (CellStore* markedCell, ESM::Position markedPosition);
|
||||||
void getMarkedPosition (CellStore*& markedCell, ESM::Position& markedPosition) const;
|
void getMarkedPosition (CellStore*& markedCell, ESM::Position& markedPosition) const;
|
||||||
|
@ -2432,6 +2432,17 @@ namespace MWWorld
|
|||||||
if (npcStats.isWerewolf() == werewolf)
|
if (npcStats.isWerewolf() == werewolf)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (actor == getPlayerPtr())
|
||||||
|
{
|
||||||
|
if (werewolf)
|
||||||
|
{
|
||||||
|
mPlayer->saveSkillsAttributes();
|
||||||
|
mPlayer->setWerewolfSkillsAttributes();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mPlayer->restoreSkillsAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
npcStats.setWerewolf(werewolf);
|
npcStats.setWerewolf(werewolf);
|
||||||
|
|
||||||
// This is a bit dangerous. Equipped items other than WerewolfRobe may reference
|
// This is a bit dangerous. Equipped items other than WerewolfRobe may reference
|
||||||
|
@ -176,6 +176,17 @@ bool ESMReader::isNextSub(const char* name)
|
|||||||
return !mCtx.subCached;
|
return !mCtx.subCached;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ESMReader::peekNextSub(const char *name)
|
||||||
|
{
|
||||||
|
if (!mCtx.leftRec)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
getSubName();
|
||||||
|
|
||||||
|
mCtx.subCached = true;
|
||||||
|
return mCtx.subName == name;
|
||||||
|
}
|
||||||
|
|
||||||
// Read subrecord name. This gets called a LOT, so I've optimized it
|
// Read subrecord name. This gets called a LOT, so I've optimized it
|
||||||
// slightly.
|
// slightly.
|
||||||
void ESMReader::getSubName()
|
void ESMReader::getSubName()
|
||||||
|
@ -183,6 +183,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool isNextSub(const char* name);
|
bool isNextSub(const char* name);
|
||||||
|
|
||||||
|
bool peekNextSub(const char* name);
|
||||||
|
|
||||||
// Read subrecord name. This gets called a LOT, so I've optimized it
|
// Read subrecord name. This gets called a LOT, so I've optimized it
|
||||||
// slightly.
|
// slightly.
|
||||||
void getSubName();
|
void getSubName();
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
#include "npcstats.hpp"
|
#include "npcstats.hpp"
|
||||||
|
|
||||||
#include "esmreader.hpp"
|
#include "esmreader.hpp"
|
||||||
@ -31,18 +30,43 @@ void ESM::NpcStats::load (ESMReader &esm)
|
|||||||
esm.getHNOT (mDisposition, "DISP");
|
esm.getHNOT (mDisposition, "DISP");
|
||||||
|
|
||||||
for (int i=0; i<27; ++i)
|
for (int i=0; i<27; ++i)
|
||||||
|
mSkills[i].load (esm);
|
||||||
|
|
||||||
|
if (esm.peekNextSub("STBA"))
|
||||||
{
|
{
|
||||||
mSkills[i].mRegular.load (esm);
|
// we have deprecated werewolf skills, stored interleaved
|
||||||
mSkills[i].mWerewolf.load (esm);
|
// Load into one big vector, then remove every 2nd value
|
||||||
|
mWerewolfDeprecatedData = true;
|
||||||
|
std::vector<ESM::StatState<int> > skills(mSkills, mSkills + sizeof(mSkills)/sizeof(mSkills[0]));
|
||||||
|
|
||||||
|
for (int i=0; i<27; ++i)
|
||||||
|
{
|
||||||
|
ESM::StatState<int> skill;
|
||||||
|
skill.load(esm);
|
||||||
|
skills.push_back(skill);
|
||||||
|
}
|
||||||
|
|
||||||
|
int i=0;
|
||||||
|
for (std::vector<ESM::StatState<int> >::iterator it = skills.begin(); it != skills.end(); ++i)
|
||||||
|
{
|
||||||
|
if (i%2 == 1)
|
||||||
|
it = skills.erase(it);
|
||||||
|
else
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
assert(skills.size() == 27);
|
||||||
|
std::copy(skills.begin(), skills.end(), mSkills);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No longer used
|
||||||
bool hasWerewolfAttributes = false;
|
bool hasWerewolfAttributes = false;
|
||||||
esm.getHNOT (hasWerewolfAttributes, "HWAT");
|
esm.getHNOT (hasWerewolfAttributes, "HWAT");
|
||||||
|
|
||||||
if (hasWerewolfAttributes)
|
if (hasWerewolfAttributes)
|
||||||
{
|
{
|
||||||
|
ESM::StatState<int> dummy;
|
||||||
for (int i=0; i<8; ++i)
|
for (int i=0; i<8; ++i)
|
||||||
mWerewolfAttributes[i].load (esm);
|
dummy.load(esm);
|
||||||
|
mWerewolfDeprecatedData = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
mIsWerewolf = false;
|
mIsWerewolf = false;
|
||||||
@ -112,14 +136,7 @@ void ESM::NpcStats::save (ESMWriter &esm) const
|
|||||||
esm.writeHNT ("DISP", mDisposition);
|
esm.writeHNT ("DISP", mDisposition);
|
||||||
|
|
||||||
for (int i=0; i<27; ++i)
|
for (int i=0; i<27; ++i)
|
||||||
{
|
mSkills[i].save (esm);
|
||||||
mSkills[i].mRegular.save (esm);
|
|
||||||
mSkills[i].mWerewolf.save (esm);
|
|
||||||
}
|
|
||||||
|
|
||||||
esm.writeHNT ("HWAT", true);
|
|
||||||
for (int i=0; i<8; ++i)
|
|
||||||
mWerewolfAttributes[i].save (esm);
|
|
||||||
|
|
||||||
if (mIsWerewolf)
|
if (mIsWerewolf)
|
||||||
esm.writeHNT ("WOLF", mIsWerewolf);
|
esm.writeHNT ("WOLF", mIsWerewolf);
|
||||||
@ -151,6 +168,7 @@ void ESM::NpcStats::save (ESMWriter &esm) const
|
|||||||
|
|
||||||
void ESM::NpcStats::blank()
|
void ESM::NpcStats::blank()
|
||||||
{
|
{
|
||||||
|
mWerewolfDeprecatedData = false;
|
||||||
mIsWerewolf = false;
|
mIsWerewolf = false;
|
||||||
mDisposition = 0;
|
mDisposition = 0;
|
||||||
mBounty = 0;
|
mBounty = 0;
|
||||||
|
@ -16,12 +16,6 @@ namespace ESM
|
|||||||
|
|
||||||
struct NpcStats
|
struct NpcStats
|
||||||
{
|
{
|
||||||
struct Skill
|
|
||||||
{
|
|
||||||
StatState<int> mRegular;
|
|
||||||
StatState<int> mWerewolf;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Faction
|
struct Faction
|
||||||
{
|
{
|
||||||
bool mExpelled;
|
bool mExpelled;
|
||||||
@ -31,12 +25,13 @@ namespace ESM
|
|||||||
Faction();
|
Faction();
|
||||||
};
|
};
|
||||||
|
|
||||||
StatState<int> mWerewolfAttributes[8];
|
|
||||||
bool mIsWerewolf;
|
bool mIsWerewolf;
|
||||||
|
|
||||||
|
bool mWerewolfDeprecatedData;
|
||||||
|
|
||||||
std::map<std::string, Faction> mFactions; // lower case IDs
|
std::map<std::string, Faction> mFactions; // lower case IDs
|
||||||
int mDisposition;
|
int mDisposition;
|
||||||
Skill mSkills[27];
|
StatState<int> mSkills[27];
|
||||||
int mBounty;
|
int mBounty;
|
||||||
int mReputation;
|
int mReputation;
|
||||||
int mWerewolfKills;
|
int mWerewolfKills;
|
||||||
|
@ -31,6 +31,14 @@ void ESM::Player::load (ESMReader &esm)
|
|||||||
esm.getHNOT (mCurrentCrimeId, "CURD");
|
esm.getHNOT (mCurrentCrimeId, "CURD");
|
||||||
mPaidCrimeId = -1;
|
mPaidCrimeId = -1;
|
||||||
esm.getHNOT (mPaidCrimeId, "PAYD");
|
esm.getHNOT (mPaidCrimeId, "PAYD");
|
||||||
|
|
||||||
|
if (esm.hasMoreSubs())
|
||||||
|
{
|
||||||
|
for (int i=0; i<ESM::Attribute::Length; ++i)
|
||||||
|
mSaveAttributes[i].load(esm);
|
||||||
|
for (int i=0; i<ESM::Skill::Length; ++i)
|
||||||
|
mSaveSkills[i].load(esm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESM::Player::save (ESMWriter &esm) const
|
void ESM::Player::save (ESMWriter &esm) const
|
||||||
@ -54,4 +62,9 @@ void ESM::Player::save (ESMWriter &esm) const
|
|||||||
|
|
||||||
esm.writeHNT ("CURD", mCurrentCrimeId);
|
esm.writeHNT ("CURD", mCurrentCrimeId);
|
||||||
esm.writeHNT ("PAYD", mPaidCrimeId);
|
esm.writeHNT ("PAYD", mPaidCrimeId);
|
||||||
|
|
||||||
|
for (int i=0; i<ESM::Attribute::Length; ++i)
|
||||||
|
mSaveAttributes[i].save(esm);
|
||||||
|
for (int i=0; i<ESM::Skill::Length; ++i)
|
||||||
|
mSaveSkills[i].save(esm);
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,9 @@
|
|||||||
#include "cellid.hpp"
|
#include "cellid.hpp"
|
||||||
#include "defs.hpp"
|
#include "defs.hpp"
|
||||||
|
|
||||||
|
#include "loadskil.hpp"
|
||||||
|
#include "attr.hpp"
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
class ESMReader;
|
class ESMReader;
|
||||||
@ -28,6 +31,9 @@ namespace ESM
|
|||||||
int mCurrentCrimeId;
|
int mCurrentCrimeId;
|
||||||
int mPaidCrimeId;
|
int mPaidCrimeId;
|
||||||
|
|
||||||
|
StatState<int> mSaveAttributes[ESM::Attribute::Length];
|
||||||
|
StatState<int> mSaveSkills[ESM::Skill::Length];
|
||||||
|
|
||||||
void load (ESMReader &esm);
|
void load (ESMReader &esm);
|
||||||
void save (ESMWriter &esm) const;
|
void save (ESMWriter &esm) const;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user