forked from mirror/openmw-tes3mp
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
67 changed files with 1069 additions and 250 deletions
apps
essimporter
opencs
CMakeLists.txtmain.cpp
model
doc
document.cppdocument.hpploader.cppmessages.cppmessages.hppoperation.cppoperation.hppoperationholder.cppoperationholder.hppstage.cppstage.hpp
settings
tools
reportmodel.cppreportmodel.hppscriptcheck.cppscriptcheck.hppsearch.cppsearchoperation.cpptools.cpptools.hpp
world
view
doc
tools
widget
world
colordelegate.cppcolordelegate.hppcreator.cppcreator.hppdialoguecreator.cppdialoguecreator.hppdialoguesubview.cppgenericcreator.cppgenericcreator.hppinfocreator.cppinfocreator.hppreferencecreator.cppreferencecreator.hppscenesubview.cppsubviews.cpptablebottombox.cpptablebottombox.hpptablesubview.cpputil.cpp
openmw
components/esm
|
@ -41,9 +41,9 @@ namespace ESSImport
|
|||
{
|
||||
for (int i=0; i<ESM::Skill::Length; ++i)
|
||||
{
|
||||
npcStats.mSkills[i].mRegular.mMod = actorData.mSkills[i][1];
|
||||
npcStats.mSkills[i].mRegular.mCurrent = actorData.mSkills[i][1];
|
||||
npcStats.mSkills[i].mRegular.mBase = actorData.mSkills[i][0];
|
||||
npcStats.mSkills[i].mMod = actorData.mSkills[i][1];
|
||||
npcStats.mSkills[i].mCurrent = actorData.mSkills[i][1];
|
||||
npcStats.mSkills[i].mBase = actorData.mSkills[i][0];
|
||||
}
|
||||
|
||||
npcStats.mTimeToStartDrowning = actorData.mACDT.mBreathMeter;
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace ESSImport
|
|||
for (int i=0; i<8; ++i)
|
||||
out.mObject.mNpcStats.mSkillIncrease[i] = pcdt.mPNAM.mSkillIncreases[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;
|
||||
|
||||
if (pcdt.mPNAM.mDrawState & PCDT::DrawState_Weapon)
|
||||
|
|
|
@ -70,11 +70,12 @@ opencs_units (view/world
|
|||
opencs_units_noqt (view/world
|
||||
subviews enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate
|
||||
scripthighlighter idvalidator dialoguecreator idcompletiondelegate
|
||||
colordelegate
|
||||
)
|
||||
|
||||
opencs_units (view/widget
|
||||
scenetoolbar scenetool scenetoolmode pushbutton scenetooltoggle scenetoolrun modebutton
|
||||
scenetooltoggle2 completerpopup
|
||||
scenetooltoggle2 completerpopup coloreditor colorpickerpopup
|
||||
)
|
||||
|
||||
opencs_units (view/render
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include <QIcon>
|
||||
#include <QMetaType>
|
||||
|
||||
#include "model/doc/messages.hpp"
|
||||
|
||||
#include "model/world/universalid.hpp"
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
|
@ -51,6 +53,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
qRegisterMetaType<std::string> ("std::string");
|
||||
qRegisterMetaType<CSMWorld::UniversalId> ("CSMWorld::UniversalId");
|
||||
qRegisterMetaType<CSMDoc::Message> ("CSMDoc::Message");
|
||||
|
||||
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 (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)),
|
||||
this, SLOT (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)));
|
||||
&mSaving, SIGNAL (reportMessage (const CSMDoc::Message&, int)),
|
||||
this, SLOT (reportMessage (const CSMDoc::Message&, int)));
|
||||
|
||||
connect (&mRunner, SIGNAL (runStateChanged()), this, SLOT (runStateChanged()));
|
||||
}
|
||||
|
@ -2404,11 +2404,10 @@ void CSMDoc::Document::modificationStateChanged (bool clean)
|
|||
emit stateChanged (getState(), this);
|
||||
}
|
||||
|
||||
void CSMDoc::Document::reportMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
||||
const std::string& hint, int type)
|
||||
void CSMDoc::Document::reportMessage (const CSMDoc::Message& message, int type)
|
||||
{
|
||||
/// \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)
|
||||
|
|
|
@ -160,8 +160,7 @@ namespace CSMDoc
|
|||
|
||||
void modificationStateChanged (bool clean);
|
||||
|
||||
void reportMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
||||
const std::string& hint, int type);
|
||||
void reportMessage (const CSMDoc::Message& message, int type);
|
||||
|
||||
void operationDone (int type, bool failed);
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ void CSMDoc::Loader::load()
|
|||
{
|
||||
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
|
||||
if (document->getData().continueLoading (messages))
|
||||
{
|
||||
|
@ -68,7 +68,7 @@ void CSMDoc::Loader::load()
|
|||
for (CSMDoc::Messages::Iterator iter (messages.begin());
|
||||
iter!=messages.end(); ++iter)
|
||||
{
|
||||
document->getReport (log)->add (iter->mId, iter->mMessage);
|
||||
document->getReport (log)->add (*iter);
|
||||
emit loadMessage (document, iter->mMessage);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,25 @@
|
|||
|
||||
#include "messages.hpp"
|
||||
|
||||
void CSMDoc::Messages::add (const CSMWorld::UniversalId& id, const std::string& message,
|
||||
const std::string& hint)
|
||||
{
|
||||
Message data;
|
||||
data.mId = id;
|
||||
data.mMessage = message;
|
||||
data.mHint = hint;
|
||||
CSMDoc::Message::Message() {}
|
||||
|
||||
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)
|
||||
|
|
|
@ -4,20 +4,41 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <QMetaType>
|
||||
|
||||
#include "../world/universalid.hpp"
|
||||
|
||||
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
|
||||
{
|
||||
public:
|
||||
|
||||
struct Message
|
||||
{
|
||||
CSMWorld::UniversalId mId;
|
||||
std::string mMessage;
|
||||
std::string mHint;
|
||||
};
|
||||
// \deprecated Use CSMDoc::Message directly instead.
|
||||
typedef CSMDoc::Message Message;
|
||||
|
||||
typedef std::vector<Message> Collection;
|
||||
|
||||
|
@ -26,11 +47,15 @@ namespace CSMDoc
|
|||
private:
|
||||
|
||||
Collection mMessages;
|
||||
Message::Severity mDefault;
|
||||
|
||||
public:
|
||||
|
||||
Messages (Message::Severity default_);
|
||||
|
||||
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.
|
||||
void push_back (const std::pair<CSMWorld::UniversalId, std::string>& data);
|
||||
|
@ -41,4 +66,6 @@ namespace CSMDoc
|
|||
};
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE (CSMDoc::Message)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <QTimer>
|
||||
|
||||
#include "../world/universalid.hpp"
|
||||
#include "../settings/usersettings.hpp"
|
||||
|
||||
#include "state.hpp"
|
||||
#include "stage.hpp"
|
||||
|
@ -23,13 +24,17 @@ void CSMDoc::Operation::prepareStages()
|
|||
{
|
||||
iter->second = iter->first->setup();
|
||||
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)
|
||||
: mType (type), mStages(std::vector<std::pair<Stage *, int> >()), mCurrentStage(mStages.begin()),
|
||||
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);
|
||||
}
|
||||
|
@ -49,8 +54,8 @@ void CSMDoc::Operation::run()
|
|||
connect (mTimer, SIGNAL (timeout()), this, SLOT (executeStage()));
|
||||
mConnected = true;
|
||||
}
|
||||
|
||||
prepareStages();
|
||||
|
||||
mPrepared = false;
|
||||
|
||||
mTimer->start (0);
|
||||
}
|
||||
|
@ -60,6 +65,19 @@ void CSMDoc::Operation::appendStage (Stage *stage)
|
|||
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
|
||||
{
|
||||
return mError;
|
||||
|
@ -84,9 +102,23 @@ void CSMDoc::Operation::abort()
|
|||
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()
|
||||
{
|
||||
Messages messages;
|
||||
if (!mPrepared)
|
||||
{
|
||||
prepareStages();
|
||||
mPrepared = true;
|
||||
}
|
||||
|
||||
Messages messages (mDefaultSeverity);
|
||||
|
||||
while (mCurrentStage!=mStages.end())
|
||||
{
|
||||
|
@ -103,7 +135,7 @@ void CSMDoc::Operation::executeStage()
|
|||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
emit reportMessage (CSMWorld::UniversalId(), e.what(), "", mType);
|
||||
emit reportMessage (Message (CSMWorld::UniversalId(), e.what(), "", Message::Severity_SeriousError), mType);
|
||||
abort();
|
||||
}
|
||||
|
||||
|
@ -115,7 +147,7 @@ void CSMDoc::Operation::executeStage()
|
|||
emit progress (mCurrentStepTotal, mTotalSteps ? mTotalSteps : 1, mType);
|
||||
|
||||
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())
|
||||
operationDone();
|
||||
|
|
|
@ -2,9 +2,13 @@
|
|||
#define CSM_DOC_OPERATION_H
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
#include <QStringList>
|
||||
|
||||
#include "messages.hpp"
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
|
@ -30,6 +34,9 @@ namespace CSMDoc
|
|||
bool mError;
|
||||
bool mConnected;
|
||||
QTimer *mTimer;
|
||||
std::map<QString, QStringList> mSettings;
|
||||
bool mPrepared;
|
||||
Message::Severity mDefaultSeverity;
|
||||
|
||||
void prepareStages();
|
||||
|
||||
|
@ -46,14 +53,21 @@ namespace CSMDoc
|
|||
///
|
||||
/// \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;
|
||||
|
||||
signals:
|
||||
|
||||
void progress (int current, int max, int type);
|
||||
|
||||
void reportMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
||||
const std::string& hint, int type);
|
||||
void reportMessage (const CSMDoc::Message& message, int type);
|
||||
|
||||
void done (int type, bool failed);
|
||||
|
||||
|
@ -63,6 +77,8 @@ namespace CSMDoc
|
|||
|
||||
void run();
|
||||
|
||||
void updateUserSetting (const QString& name, const QStringList& value);
|
||||
|
||||
private slots:
|
||||
|
||||
void executeStage();
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
|
||||
#include "operationholder.hpp"
|
||||
|
||||
#include "../settings/usersettings.hpp"
|
||||
|
||||
#include "operation.hpp"
|
||||
|
||||
CSMDoc::OperationHolder::OperationHolder (Operation *operation) : mRunning (false)
|
||||
|
@ -19,8 +21,8 @@ void CSMDoc::OperationHolder::setOperation (Operation *operation)
|
|||
this, SIGNAL (progress (int, int, int)));
|
||||
|
||||
connect (
|
||||
mOperation, SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)),
|
||||
this, SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)));
|
||||
mOperation, SIGNAL (reportMessage (const CSMDoc::Message&, int)),
|
||||
this, SIGNAL (reportMessage (const CSMDoc::Message&, int)));
|
||||
|
||||
connect (
|
||||
mOperation, SIGNAL (done (int, bool)),
|
||||
|
@ -29,6 +31,9 @@ void CSMDoc::OperationHolder::setOperation (Operation *operation)
|
|||
connect (this, SIGNAL (abortSignal()), mOperation, SLOT (abort()));
|
||||
|
||||
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
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include <QObject>
|
||||
#include <QThread>
|
||||
|
||||
#include "messages.hpp"
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class UniversalId;
|
||||
|
@ -44,8 +46,7 @@ namespace CSMDoc
|
|||
|
||||
void progress (int current, int max, int type);
|
||||
|
||||
void reportMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
||||
const std::string& hint, int type);
|
||||
void reportMessage (const CSMDoc::Message& message, int type);
|
||||
|
||||
void done (int type, bool failed);
|
||||
|
||||
|
|
|
@ -2,3 +2,5 @@
|
|||
#include "stage.hpp"
|
||||
|
||||
CSMDoc::Stage::~Stage() {}
|
||||
|
||||
void CSMDoc::Stage::updateUserSetting (const QString& name, const QStringList& value) {}
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include "messages.hpp"
|
||||
|
||||
class QString;
|
||||
|
||||
namespace CSMDoc
|
||||
{
|
||||
class Stage
|
||||
|
@ -21,6 +23,9 @@ namespace CSMDoc
|
|||
|
||||
virtual void perform (int stage, Messages& messages) = 0;
|
||||
///< 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);
|
||||
}
|
||||
|
||||
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");
|
||||
{
|
||||
Setting *before = createSetting (Type_SpinBox, "char-before",
|
||||
|
@ -235,7 +276,7 @@ void CSMSettings::UserSettings::buildSettingModelDefaults()
|
|||
autoDelete->setDefaultValue ("true");
|
||||
}
|
||||
|
||||
declareSection ("script-editor", "Script Editor");
|
||||
declareSection ("script-editor", "Scripts");
|
||||
{
|
||||
Setting *lineNum = createSetting (Type_CheckBox, "show-linenum", "Show Line Numbers");
|
||||
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."
|
||||
"\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");
|
||||
formatInt->setDefaultValues (QStringList() << "Dark magenta");
|
||||
formatInt->setToolTip ("(Default: Green) Use one of the following formats:" + tooltip);
|
||||
|
|
|
@ -6,24 +6,18 @@
|
|||
|
||||
#include "../world/columns.hpp"
|
||||
|
||||
CSMTools::ReportModel::Line::Line (const CSMWorld::UniversalId& id, const std::string& message,
|
||||
const std::string& hint)
|
||||
: mId (id), mMessage (message), mHint (hint)
|
||||
{}
|
||||
|
||||
CSMTools::ReportModel::ReportModel (bool fieldColumn)
|
||||
CSMTools::ReportModel::ReportModel (bool fieldColumn, bool severityColumn)
|
||||
: mColumnField (-1), mColumnSeverity (-1)
|
||||
{
|
||||
if (fieldColumn)
|
||||
{
|
||||
mColumnField = 3;
|
||||
mColumnDescription = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
mColumnDescription = 3;
|
||||
int index = 3;
|
||||
|
||||
mColumnField = -1;
|
||||
}
|
||||
if (severityColumn)
|
||||
mColumnSeverity = index++;
|
||||
|
||||
if (fieldColumn)
|
||||
mColumnField = index++;
|
||||
|
||||
mColumnDescription = index;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
@ -112,6 +118,9 @@ QVariant CSMTools::ReportModel::headerData (int section, Qt::Orientation orienta
|
|||
if (section==mColumnField)
|
||||
return "Field";
|
||||
|
||||
if (section==mColumnSeverity)
|
||||
return "Severity";
|
||||
|
||||
return "-";
|
||||
}
|
||||
|
||||
|
@ -132,19 +141,18 @@ bool CSMTools::ReportModel::removeRows (int row, int count, const QModelIndex& p
|
|||
return true;
|
||||
}
|
||||
|
||||
void CSMTools::ReportModel::add (const CSMWorld::UniversalId& id, const std::string& message,
|
||||
const std::string& hint)
|
||||
void CSMTools::ReportModel::add (const CSMDoc::Message& message)
|
||||
{
|
||||
beginInsertRows (QModelIndex(), mRows.size(), mRows.size());
|
||||
|
||||
mRows.push_back (Line (id, message, hint));
|
||||
mRows.push_back (message);
|
||||
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
void CSMTools::ReportModel::flagAsReplaced (int index)
|
||||
{
|
||||
Line& line = mRows.at (index);
|
||||
CSMDoc::Message& line = mRows.at (index);
|
||||
std::string hint = line.mHint;
|
||||
|
||||
if (hint.empty() || hint[0]!='R')
|
||||
|
@ -176,3 +184,16 @@ void CSMTools::ReportModel::clear()
|
|||
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 "../doc/messages.hpp"
|
||||
|
||||
#include "../world/universalid.hpp"
|
||||
|
||||
namespace CSMTools
|
||||
|
@ -14,17 +16,7 @@ namespace CSMTools
|
|||
{
|
||||
Q_OBJECT
|
||||
|
||||
struct Line
|
||||
{
|
||||
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;
|
||||
std::vector<CSMDoc::Messages::Message> mRows;
|
||||
|
||||
// Fixed columns
|
||||
enum Columns
|
||||
|
@ -35,10 +27,11 @@ namespace CSMTools
|
|||
// Configurable columns
|
||||
int mColumnDescription;
|
||||
int mColumnField;
|
||||
int mColumnSeverity;
|
||||
|
||||
public:
|
||||
|
||||
ReportModel (bool fieldColumn = false);
|
||||
ReportModel (bool fieldColumn = false, bool severityColumn = true);
|
||||
|
||||
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());
|
||||
|
||||
void add (const CSMWorld::UniversalId& id, const std::string& message,
|
||||
const std::string& hint = "");
|
||||
void add (const CSMDoc::Message& message);
|
||||
|
||||
void flagAsReplaced (int index);
|
||||
|
||||
|
@ -60,6 +52,9 @@ namespace CSMTools
|
|||
std::string getHint (int row) const;
|
||||
|
||||
void clear();
|
||||
|
||||
// Return number of messages with Error or SeriousError severity.
|
||||
int countErrors() const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,17 @@
|
|||
|
||||
#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,
|
||||
Type type)
|
||||
{
|
||||
|
@ -18,11 +29,6 @@ void CSMTools::ScriptCheckStage::report (const std::string& message, const Compi
|
|||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Script, mId);
|
||||
|
||||
if (type==ErrorMessage)
|
||||
stream << "error ";
|
||||
else
|
||||
stream << "warning ";
|
||||
|
||||
stream
|
||||
<< "script " << mFile
|
||||
<< ", 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;
|
||||
|
||||
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)
|
||||
{
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Script, mId);
|
||||
|
||||
mMessages->push_back (std::make_pair (id,
|
||||
(type==ErrorMessage ? "error: " : "warning: ") + message));
|
||||
std::ostringstream stream;
|
||||
stream << "script " << mFile << ": " << message;
|
||||
|
||||
mMessages->add (id, stream.str(), "", getSeverity (type));
|
||||
}
|
||||
|
||||
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
|
||||
setWarningsMode (0);
|
||||
|
@ -58,6 +66,7 @@ int CSMTools::ScriptCheckStage::setup()
|
|||
mContext.clear();
|
||||
mMessages = 0;
|
||||
mId.clear();
|
||||
Compiler::ErrorHandler::reset();
|
||||
|
||||
return mDocument.getData().getScripts().getSize();
|
||||
}
|
||||
|
@ -72,6 +81,13 @@ void CSMTools::ScriptCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
|||
|
||||
mMessages = &messages;
|
||||
|
||||
switch (mWarningMode)
|
||||
{
|
||||
case Mode_Ignore: setWarningsMode (0); break;
|
||||
case Mode_Normal: setWarningsMode (1); break;
|
||||
case Mode_Strict: setWarningsMode (2); break;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
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);
|
||||
|
||||
messages.push_back (std::make_pair (id,
|
||||
std::string ("Critical compile error: ") + error.what()));
|
||||
std::ostringstream stream;
|
||||
stream << "script " << mFile << ": " << error.what();
|
||||
|
||||
messages.add (id, stream.str(), "", CSMDoc::Message::Severity_SeriousError);
|
||||
}
|
||||
|
||||
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
|
||||
class ScriptCheckStage : public CSMDoc::Stage, private Compiler::ErrorHandler
|
||||
{
|
||||
enum WarningMode
|
||||
{
|
||||
Mode_Ignore,
|
||||
Mode_Normal,
|
||||
Mode_Strict
|
||||
};
|
||||
|
||||
const CSMDoc::Document& mDocument;
|
||||
Compiler::Extensions mExtensions;
|
||||
CSMWorld::ScriptContext mContext;
|
||||
std::string mId;
|
||||
std::string mFile;
|
||||
CSMDoc::Messages *mMessages;
|
||||
WarningMode mWarningMode;
|
||||
|
||||
CSMDoc::Message::Severity getSeverity (Type type);
|
||||
|
||||
virtual void report (const std::string& message, const Compiler::TokenLoc& loc, Type type);
|
||||
///< Report error to the user.
|
||||
|
||||
|
@ -40,6 +50,8 @@ namespace CSMTools
|
|||
|
||||
virtual void perform (int stage, CSMDoc::Messages& 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,
|
||||
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(),
|
||||
model->findColumnIndex (CSMWorld::Columns::ColumnId_Id)).row();
|
||||
|
|
|
@ -21,6 +21,8 @@ CSMTools::SearchOperation::SearchOperation (CSMDoc::Document& document)
|
|||
iter!=types.end(); ++iter)
|
||||
appendStage (new SearchStage (&dynamic_cast<CSMWorld::IdTableBase&> (
|
||||
*document.getData().getTableModel (*iter))));
|
||||
|
||||
setDefaultSeverity (CSMDoc::Message::Severity_Info);
|
||||
}
|
||||
|
||||
void CSMTools::SearchOperation::configure (const Search& search)
|
||||
|
|
|
@ -51,11 +51,15 @@ CSMDoc::OperationHolder *CSMTools::Tools::getVerifier()
|
|||
{
|
||||
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 (done (int, bool)), this, SIGNAL (done (int, bool)));
|
||||
connect (&mVerifier,
|
||||
SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)),
|
||||
this, SLOT (verifierMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)));
|
||||
connect (&mVerifier, SIGNAL (reportMessage (const CSMDoc::Message&, int)),
|
||||
this, SLOT (verifierMessage (const CSMDoc::Message&, int)));
|
||||
|
||||
std::vector<std::string> mandatoryIds; // I want C++11, damn it!
|
||||
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 (done (int, bool)), this, SIGNAL (done (int, bool)));
|
||||
connect (&mSearch,
|
||||
SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)),
|
||||
this, SLOT (verifierMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)));
|
||||
connect (&mSearch, SIGNAL (reportMessage (const CSMDoc::Message&, int)),
|
||||
this, SLOT (verifierMessage (const CSMDoc::Message&, int)));
|
||||
}
|
||||
|
||||
CSMTools::Tools::~Tools()
|
||||
|
@ -155,7 +158,7 @@ CSMWorld::UniversalId CSMTools::Tools::runVerifier()
|
|||
|
||||
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);
|
||||
}
|
||||
|
@ -210,12 +213,11 @@ CSMTools::ReportModel *CSMTools::Tools::getReport (const CSMWorld::UniversalId&
|
|||
return mReports.at (id.getIndex());
|
||||
}
|
||||
|
||||
void CSMTools::Tools::verifierMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
||||
const std::string& hint, int type)
|
||||
void CSMTools::Tools::verifierMessage (const CSMDoc::Message& message, int type)
|
||||
{
|
||||
std::map<int, int>::iterator iter = mActiveReports.find (type);
|
||||
|
||||
if (iter!=mActiveReports.end())
|
||||
mReports[iter->second]->add (id, message, hint);
|
||||
mReports[iter->second]->add (message);
|
||||
}
|
||||
|
||||
|
|
|
@ -75,8 +75,7 @@ namespace CSMTools
|
|||
|
||||
private slots:
|
||||
|
||||
void verifierMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
||||
const std::string& hint, int type);
|
||||
void verifierMessage (const CSMDoc::Message& message, int type);
|
||||
|
||||
signals:
|
||||
|
||||
|
|
|
@ -694,7 +694,7 @@ namespace CSMWorld
|
|||
|
||||
QColor colour = data.value<QColor>();
|
||||
|
||||
record2.mMapColor = colour.rgb() & 0xffffff;
|
||||
record2.mMapColor = (colour.blue() << 16) | (colour.green() << 8) | colour.red();
|
||||
|
||||
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
|
||||
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;
|
||||
}
|
||||
std::string cellId = Misc::StringUtils::lowerCase (mCells.getId (index));
|
||||
|
@ -994,7 +994,8 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages)
|
|||
else
|
||||
{
|
||||
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
|
||||
|
@ -1011,7 +1012,7 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages)
|
|||
if (!mDialogue)
|
||||
{
|
||||
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();
|
||||
break;
|
||||
|
@ -1054,7 +1055,8 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages)
|
|||
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ namespace
|
|||
types[CSMWorld::ColumnBase::Display_Faction ] = CSMWorld::UniversalId::Type_Faction;
|
||||
types[CSMWorld::ColumnBase::Display_GlobalVariable ] = CSMWorld::UniversalId::Type_Global;
|
||||
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_Miscellaneous ] = 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_Static ] = CSMWorld::UniversalId::Type_Referenceable;
|
||||
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;
|
||||
|
||||
return types;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "../world/recordstatusdelegate.hpp"
|
||||
#include "../world/idtypedelegate.hpp"
|
||||
#include "../world/idcompletiondelegate.hpp"
|
||||
#include "../world/colordelegate.hpp"
|
||||
|
||||
#include "../../model/settings/usersettings.hpp"
|
||||
|
||||
|
@ -61,6 +62,9 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager)
|
|||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_RefRecordType,
|
||||
new CSVWorld::IdTypeDelegateFactory());
|
||||
|
||||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_Colour,
|
||||
new CSVWorld::ColorDelegateFactory());
|
||||
|
||||
std::vector<CSMWorld::ColumnBase::Display> idCompletionColumns = CSMWorld::IdCompletionManager::getDisplayTypes();
|
||||
for (std::vector<CSMWorld::ColumnBase::Display>::const_iterator current = idCompletionColumns.begin();
|
||||
current != idCompletionColumns.end();
|
||||
|
|
|
@ -96,21 +96,35 @@ void CSVTools::ReportTable::mouseDoubleClickEvent (QMouseEvent *event)
|
|||
selectionModel()->select (index,
|
||||
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();
|
||||
showSelection();
|
||||
break;
|
||||
|
||||
case Qt::ShiftModifier:
|
||||
case Action_Remove:
|
||||
|
||||
event->accept();
|
||||
removeSelection();
|
||||
break;
|
||||
|
||||
case Qt::ControlModifier:
|
||||
case Action_EditAndRemove:
|
||||
|
||||
event->accept();
|
||||
showSelection();
|
||||
|
@ -155,7 +169,11 @@ CSVTools::ReportTable::ReportTable (CSMDoc::Document& document,
|
|||
|
||||
mReplaceAction = new QAction (tr ("Replace"), this);
|
||||
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
|
||||
|
@ -176,6 +194,35 @@ std::vector<CSMWorld::UniversalId> CSVTools::ReportTable::getDraggedRecords() co
|
|||
void CSVTools::ReportTable::updateUserSetting (const QString& name, const QStringList& 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
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef CSV_TOOLS_REPORTTABLE_H
|
||||
#define CSV_TOOLS_REPORTTABLE_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "../world/dragrecordtable.hpp"
|
||||
|
||||
class QAction;
|
||||
|
@ -21,11 +23,20 @@ namespace CSVTools
|
|||
{
|
||||
Q_OBJECT
|
||||
|
||||
enum DoubleClickAction
|
||||
{
|
||||
Action_None,
|
||||
Action_Edit,
|
||||
Action_Remove,
|
||||
Action_EditAndRemove
|
||||
};
|
||||
|
||||
CSMTools::ReportModel *mModel;
|
||||
CSVWorld::CommandDelegate *mIdTypeDelegate;
|
||||
QAction *mShowAction;
|
||||
QAction *mRemoveAction;
|
||||
QAction *mReplaceAction;
|
||||
std::map<Qt::KeyboardModifiers, DoubleClickAction> mDoubleClickActions;
|
||||
|
||||
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::Creator *CSVWorld::NullCreatorFactory::makeCreator (CSMWorld::Data& data,
|
||||
QUndoStack& undoStack, const CSMWorld::UniversalId& id) const
|
||||
CSVWorld::Creator *CSVWorld::NullCreatorFactory::makeCreator (CSMDoc::Document& document,
|
||||
const CSMWorld::UniversalId& id) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -5,16 +5,14 @@
|
|||
|
||||
#include <QWidget>
|
||||
|
||||
#include "../../model/world/universalid.hpp"
|
||||
#include "../../model/doc/document.hpp"
|
||||
|
||||
#include "../../model/world/scope.hpp"
|
||||
#include "../../model/world/universalid.hpp"
|
||||
|
||||
class QUndoStack;
|
||||
|
||||
namespace CSMWorld
|
||||
namespace CSMDoc
|
||||
{
|
||||
class Data;
|
||||
class UniversalId;
|
||||
class Document;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
|
@ -59,8 +57,7 @@ namespace CSVWorld
|
|||
|
||||
virtual ~CreatorFactoryBase();
|
||||
|
||||
virtual Creator *makeCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||
const CSMWorld::UniversalId& id) const = 0;
|
||||
virtual Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const = 0;
|
||||
///< 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
|
||||
|
@ -72,8 +69,7 @@ namespace CSVWorld
|
|||
{
|
||||
public:
|
||||
|
||||
virtual Creator *makeCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||
const CSMWorld::UniversalId& id) const;
|
||||
virtual Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const;
|
||||
///< The ownership of the returned Creator is transferred to the caller.
|
||||
///
|
||||
/// \note The function always returns 0.
|
||||
|
@ -84,8 +80,7 @@ namespace CSVWorld
|
|||
{
|
||||
public:
|
||||
|
||||
virtual Creator *makeCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||
const CSMWorld::UniversalId& id) const;
|
||||
virtual Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const;
|
||||
///< 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
|
||||
|
@ -93,10 +88,10 @@ namespace CSVWorld
|
|||
};
|
||||
|
||||
template<class CreatorT, unsigned int scope>
|
||||
Creator *CreatorFactory<CreatorT, scope>::makeCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||
const CSMWorld::UniversalId& id) const
|
||||
Creator *CreatorFactory<CreatorT, scope>::makeCreator (CSMDoc::Document& document,
|
||||
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);
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include <components/esm/loaddial.hpp>
|
||||
|
||||
#include "../../model/doc/document.hpp"
|
||||
|
||||
#include "../../model/world/data.hpp"
|
||||
#include "../../model/world/commands.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)
|
||||
{}
|
||||
|
||||
CSVWorld::Creator *CSVWorld::TopicCreatorFactory::makeCreator (CSMWorld::Data& data,
|
||||
QUndoStack& undoStack, const CSMWorld::UniversalId& id) const
|
||||
CSVWorld::Creator *CSVWorld::TopicCreatorFactory::makeCreator (CSMDoc::Document& document,
|
||||
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,
|
||||
QUndoStack& undoStack, const CSMWorld::UniversalId& id) const
|
||||
CSVWorld::Creator *CSVWorld::JournalCreatorFactory::makeCreator (CSMDoc::Document& document,
|
||||
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:
|
||||
|
||||
virtual Creator *makeCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||
const CSMWorld::UniversalId& id) const;
|
||||
virtual Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const;
|
||||
///< The ownership of the returned Creator is transferred to the caller.
|
||||
};
|
||||
|
||||
|
@ -32,8 +31,7 @@ namespace CSVWorld
|
|||
{
|
||||
public:
|
||||
|
||||
virtual Creator *makeCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||
const CSMWorld::UniversalId& id) const;
|
||||
virtual Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const;
|
||||
///< The ownership of the returned Creator is transferred to the caller.
|
||||
};
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#include "../../model/world/commands.hpp"
|
||||
#include "../../model/doc/document.hpp"
|
||||
|
||||
#include "../widget/coloreditor.hpp"
|
||||
|
||||
#include "recordstatusdelegate.hpp"
|
||||
#include "util.hpp"
|
||||
#include "tablebottombox.hpp"
|
||||
|
@ -331,6 +333,10 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase::
|
|||
{
|
||||
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
|
||||
throw std::logic_error ("Dialogue editor type missing");
|
||||
|
||||
|
@ -679,8 +685,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM
|
|||
mMainLayout->addWidget(mEditWidget);
|
||||
mEditWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
||||
|
||||
mMainLayout->addWidget (mBottom =
|
||||
new TableBottomBox (creatorFactory, document.getData(), document.getUndoStack(), id, this));
|
||||
mMainLayout->addWidget (mBottom = new TableBottomBox (creatorFactory, document, id, this));
|
||||
|
||||
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),
|
||||
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->setContentsMargins (0, 0, 0, 0);
|
||||
|
||||
|
|
|
@ -13,10 +13,12 @@ class QLineEdit;
|
|||
class QHBoxLayout;
|
||||
class QComboBox;
|
||||
class QLabel;
|
||||
class QUndoStack;
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class CreateCommand;
|
||||
class Data;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
|
|
|
@ -9,10 +9,13 @@
|
|||
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
#include "../../model/doc/document.hpp"
|
||||
|
||||
#include "../../model/world/data.hpp"
|
||||
#include "../../model/world/commands.hpp"
|
||||
#include "../../model/world/columns.hpp"
|
||||
#include "../../model/world/idtable.hpp"
|
||||
#include "../../model/world/idcompletionmanager.hpp"
|
||||
|
||||
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,
|
||||
const CSMWorld::UniversalId& id)
|
||||
const CSMWorld::UniversalId& id, CSMWorld::IdCompletionManager& completionManager)
|
||||
: GenericCreator (data, undoStack, id)
|
||||
{
|
||||
QLabel *label = new QLabel ("Topic", this);
|
||||
insertBeforeButtons (label, false);
|
||||
|
||||
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);
|
||||
|
||||
setManualEditing (false);
|
||||
|
@ -100,3 +109,12 @@ void CSVWorld::InfoCreator::topicChanged()
|
|||
{
|
||||
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
|
||||
{
|
||||
class InfoCollection;
|
||||
class IdCompletionManager;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
|
@ -25,7 +26,7 @@ namespace CSVWorld
|
|||
public:
|
||||
|
||||
InfoCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||
const CSMWorld::UniversalId& id);
|
||||
const CSMWorld::UniversalId& id, CSMWorld::IdCompletionManager& completionManager);
|
||||
|
||||
virtual void cloneMode (const std::string& originId,
|
||||
const CSMWorld::UniversalId::Type type);
|
||||
|
@ -43,6 +44,14 @@ namespace CSVWorld
|
|||
|
||||
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
|
||||
|
|
|
@ -4,10 +4,13 @@
|
|||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
|
||||
#include "../../model/doc/document.hpp"
|
||||
|
||||
#include "../../model/world/data.hpp"
|
||||
#include "../../model/world/commands.hpp"
|
||||
#include "../../model/world/columns.hpp"
|
||||
#include "../../model/world/idtable.hpp"
|
||||
#include "../../model/world/idcompletionmanager.hpp"
|
||||
|
||||
std::string CSVWorld::ReferenceCreator::getId() const
|
||||
{
|
||||
|
@ -71,13 +74,14 @@ int CSVWorld::ReferenceCreator::getRefNumCount() const
|
|||
}
|
||||
|
||||
CSVWorld::ReferenceCreator::ReferenceCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||
const CSMWorld::UniversalId& id)
|
||||
const CSMWorld::UniversalId& id, CSMWorld::IdCompletionManager &completionManager)
|
||||
: GenericCreator (data, undoStack, id)
|
||||
{
|
||||
QLabel *label = new QLabel ("Cell", this);
|
||||
insertBeforeButtons (label, false);
|
||||
|
||||
mCell = new QLineEdit (this);
|
||||
mCell->setCompleter(completionManager.getCompleter(CSMWorld::ColumnBase::Display_Cell).get());
|
||||
insertBeforeButtons (mCell, true);
|
||||
|
||||
setManualEditing (false);
|
||||
|
@ -142,3 +146,12 @@ void CSVWorld::ReferenceCreator::cloneMode(const std::string& originId,
|
|||
CSVWorld::GenericCreator::cloneMode(originId, type);
|
||||
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;
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class IdCompletionManager;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
|
||||
class ReferenceCreator : public GenericCreator
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -28,7 +34,7 @@ namespace CSVWorld
|
|||
public:
|
||||
|
||||
ReferenceCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||
const CSMWorld::UniversalId& id);
|
||||
const CSMWorld::UniversalId& id, CSMWorld::IdCompletionManager &completionManager);
|
||||
|
||||
virtual void cloneMode(const std::string& originId,
|
||||
const CSMWorld::UniversalId::Type type);
|
||||
|
@ -46,6 +52,14 @@ namespace CSVWorld
|
|||
|
||||
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
|
||||
|
|
|
@ -33,9 +33,7 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D
|
|||
|
||||
layout->setContentsMargins (QMargins (0, 0, 0, 0));
|
||||
|
||||
layout->addWidget (mBottom =
|
||||
new TableBottomBox (NullCreatorFactory(), document.getData(), document.getUndoStack(), id,
|
||||
this), 0);
|
||||
layout->addWidget (mBottom = new TableBottomBox (NullCreatorFactory(), document, id, this), 0);
|
||||
|
||||
mLayout->setContentsMargins (QMargins (0, 0, 0, 0));
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
|||
new CSVDoc::SubViewFactoryWithCreator<TableSubView, CreatorFactory<ReferenceableCreator> >);
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_References,
|
||||
new CSVDoc::SubViewFactoryWithCreator<TableSubView, CreatorFactory<ReferenceCreator> >);
|
||||
new CSVDoc::SubViewFactoryWithCreator<TableSubView, ReferenceCreatorFactory>);
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_Topics,
|
||||
new CSVDoc::SubViewFactoryWithCreator<TableSubView, TopicCreatorFactory>);
|
||||
|
@ -68,10 +68,10 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
|||
new CSVDoc::SubViewFactoryWithCreator<TableSubView, JournalCreatorFactory>);
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_TopicInfos,
|
||||
new CSVDoc::SubViewFactoryWithCreator<TableSubView, CreatorFactory<InfoCreator> >);
|
||||
new CSVDoc::SubViewFactoryWithCreator<TableSubView, InfoCreatorFactory>);
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_JournalInfos,
|
||||
new CSVDoc::SubViewFactoryWithCreator<TableSubView, CreatorFactory<InfoCreator> >);
|
||||
new CSVDoc::SubViewFactoryWithCreator<TableSubView, InfoCreatorFactory>);
|
||||
|
||||
// Subviews for resources tables
|
||||
manager.add (CSMWorld::UniversalId::Type_Meshes,
|
||||
|
@ -147,16 +147,16 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
|||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<ReferenceableCreator> > (false));
|
||||
|
||||
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,
|
||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<CellCreator> > (false));
|
||||
|
||||
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,
|
||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<InfoCreator> >(false));
|
||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, InfoCreatorFactory>(false));
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_Topic,
|
||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, TopicCreatorFactory> (false));
|
||||
|
|
|
@ -39,8 +39,10 @@ void CSVWorld::TableBottomBox::updateStatus()
|
|||
}
|
||||
}
|
||||
|
||||
CSVWorld::TableBottomBox::TableBottomBox (const CreatorFactoryBase& creatorFactory,
|
||||
CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id, QWidget *parent)
|
||||
CSVWorld::TableBottomBox::TableBottomBox (const CreatorFactoryBase& creatorFactory,
|
||||
CSMDoc::Document& document,
|
||||
const CSMWorld::UniversalId& id,
|
||||
QWidget *parent)
|
||||
: QWidget (parent), mShowStatusBar (false), mCreating (false)
|
||||
{
|
||||
for (int i=0; i<4; ++i)
|
||||
|
@ -61,7 +63,7 @@ CSVWorld::TableBottomBox::TableBottomBox (const CreatorFactoryBase& creatorFacto
|
|||
|
||||
setLayout (mLayout);
|
||||
|
||||
mCreator = creatorFactory.makeCreator (data, undoStack, id);
|
||||
mCreator = creatorFactory.makeCreator (document, id);
|
||||
|
||||
if (mCreator)
|
||||
{
|
||||
|
|
|
@ -9,10 +9,9 @@ class QStackedLayout;
|
|||
class QStatusBar;
|
||||
class QUndoStack;
|
||||
|
||||
namespace CSMWorld
|
||||
namespace CSMDoc
|
||||
{
|
||||
class Data;
|
||||
class UniversalId;
|
||||
class Document;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
|
@ -42,8 +41,10 @@ namespace CSVWorld
|
|||
|
||||
public:
|
||||
|
||||
TableBottomBox (const CreatorFactoryBase& creatorFactory, CSMWorld::Data& data,
|
||||
QUndoStack& undoStack, const CSMWorld::UniversalId& id, QWidget *parent = 0);
|
||||
TableBottomBox (const CreatorFactoryBase& creatorFactory,
|
||||
CSMDoc::Document& document,
|
||||
const CSMWorld::UniversalId& id,
|
||||
QWidget *parent = 0);
|
||||
|
||||
virtual ~TableBottomBox();
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::D
|
|||
layout->setContentsMargins (QMargins (0, 0, 0, 0));
|
||||
|
||||
layout->addWidget (mBottom =
|
||||
new TableBottomBox (creatorFactory, document.getData(), document.getUndoStack(), id, this), 0);
|
||||
new TableBottomBox (creatorFactory, document, id, this), 0);
|
||||
|
||||
layout->insertWidget (0, mTable =
|
||||
new Table (id, mBottom->canCreateAndDelete(), sorting, document), 2);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "../../model/world/commands.hpp"
|
||||
#include "../../model/world/tablemimedata.hpp"
|
||||
#include "../../model/world/commanddispatcher.hpp"
|
||||
#include "../widget/coloreditor.hpp"
|
||||
#include "dialoguespinbox.hpp"
|
||||
#include "scriptedit.hpp"
|
||||
|
||||
|
@ -123,10 +124,19 @@ void CSVWorld::CommandDelegate::setModelDataImp (QWidget *editor, QAbstractItemM
|
|||
if (!mCommandDispatcher)
|
||||
return;
|
||||
|
||||
NastyTableModelHack hack (*model);
|
||||
QStyledItemDelegate::setModelData (editor, &hack, index);
|
||||
|
||||
QVariant new_ = hack.getData();
|
||||
QVariant new_;
|
||||
// Color columns use a custom editor, so we need explicitly extract a data from it
|
||||
CSVWidget::ColorEditor *colorEditor = qobject_cast<CSVWidget::ColorEditor *>(editor);
|
||||
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))
|
||||
mCommandDispatcher->executeModify (model, index, new_);
|
||||
|
@ -162,6 +172,12 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO
|
|||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -184,7 +200,7 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO
|
|||
{
|
||||
case CSMWorld::ColumnBase::Display_Colour:
|
||||
|
||||
return new QLineEdit(parent);
|
||||
return new CSVWidget::ColorEditor(index.data().value<QColor>(), parent);
|
||||
|
||||
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();
|
||||
|
||||
if (n == "dateTime") {
|
||||
|
|
|
@ -641,9 +641,6 @@ namespace MWMechanics
|
|||
if (mAllowedNodes.empty())
|
||||
return;
|
||||
|
||||
if (actor.getClass().isPureWaterCreature(actor))
|
||||
return;
|
||||
|
||||
state.moveIn(new AiWanderStorage());
|
||||
|
||||
int index = Misc::Rng::rollDice(mAllowedNodes.size());
|
||||
|
@ -690,7 +687,8 @@ namespace MWMechanics
|
|||
// actor can wander from the spawn position. AiWander assumes that
|
||||
// pathgrid points are available, and uses them to randomly select wander
|
||||
// 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 cellYOffset = 0;
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace MWMechanics
|
|||
mKnockdown(false), mKnockdownOneFrame(false), mKnockdownOverOneFrame(false),
|
||||
mHitRecovery(false), mBlock(false), mMovementFlags(0), mAttackStrength(0.f),
|
||||
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)
|
||||
mAiSettings[i] = 0;
|
||||
|
@ -55,7 +55,7 @@ namespace MWMechanics
|
|||
if (index < 0 || index > 7) {
|
||||
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
|
||||
|
@ -139,14 +139,11 @@ namespace MWMechanics
|
|||
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(!mIsWerewolf)
|
||||
mAttributes[index] = value;
|
||||
else
|
||||
mWerewolfAttributes[index] = value;
|
||||
mAttributes[index] = value;
|
||||
|
||||
if (index == ESM::Attribute::Intelligence)
|
||||
mRecalcMagicka = true;
|
||||
|
|
|
@ -77,10 +77,6 @@ namespace MWMechanics
|
|||
std::vector<int> mSummonGraveyard;
|
||||
|
||||
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;
|
||||
|
||||
public:
|
||||
|
|
|
@ -32,6 +32,7 @@ MWMechanics::NpcStats::NpcStats()
|
|||
, mWerewolfKills (0)
|
||||
, mLevelProgress(0)
|
||||
, mTimeToStartDrowning(20.0)
|
||||
, mIsWerewolf(false)
|
||||
{
|
||||
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)
|
||||
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)
|
||||
|
@ -59,7 +60,15 @@ MWMechanics::SkillValue& MWMechanics::NpcStats::getSkill (int index)
|
|||
if (index<0 || index>=ESM::Skill::Length)
|
||||
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
|
||||
|
@ -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)
|
||||
{
|
||||
// Don't increase skills as a werewolf
|
||||
if(mIsWerewolf)
|
||||
return;
|
||||
|
||||
const ESM::Skill *skill =
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Skill>().find (skillIndex);
|
||||
float skillGain = 1;
|
||||
|
@ -403,34 +408,12 @@ bool MWMechanics::NpcStats::isWerewolf() const
|
|||
|
||||
void MWMechanics::NpcStats::setWerewolf (bool set)
|
||||
{
|
||||
if (mIsWerewolf == set)
|
||||
return;
|
||||
|
||||
if(set != false)
|
||||
{
|
||||
const MWWorld::Store<ESM::GameSetting> &gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -464,14 +447,8 @@ void MWMechanics::NpcStats::writeState (ESM::NpcStats& state) const
|
|||
state.mDisposition = mDisposition;
|
||||
|
||||
for (int i=0; i<ESM::Skill::Length; ++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]);
|
||||
}
|
||||
mSkill[i].writeState (state.mSkills[i]);
|
||||
|
||||
state.mIsWerewolf = mIsWerewolf;
|
||||
|
||||
state.mCrimeId = mCrimeId;
|
||||
|
@ -519,14 +496,7 @@ void MWMechanics::NpcStats::readState (const ESM::NpcStats& state)
|
|||
mDisposition = state.mDisposition;
|
||||
|
||||
for (int i=0; i<ESM::Skill::Length; ++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]);
|
||||
}
|
||||
mSkill[i].readState (state.mSkills[i]);
|
||||
|
||||
mIsWerewolf = state.mIsWerewolf;
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace MWMechanics
|
|||
{
|
||||
int mDisposition;
|
||||
SkillValue mSkill[ESM::Skill::Length]; // SkillValue.mProgress used by the player only
|
||||
SkillValue mWerewolfSkill[ESM::Skill::Length];
|
||||
|
||||
int mReputation;
|
||||
int mCrimeId;
|
||||
|
||||
|
@ -41,6 +41,8 @@ namespace MWMechanics
|
|||
/// Countdown to getting damage while underwater
|
||||
float mTimeToStartDrowning;
|
||||
|
||||
bool mIsWerewolf;
|
||||
|
||||
public:
|
||||
|
||||
NpcStats();
|
||||
|
@ -56,6 +58,7 @@ namespace MWMechanics
|
|||
|
||||
const SkillValue& getSkill (int index) const;
|
||||
SkillValue& getSkill (int index);
|
||||
void setSkill(int index, const SkillValue& value);
|
||||
|
||||
const std::map<std::string, int>& getFactionRanks() const;
|
||||
/// Increase the rank in this faction by 1, if such a rank exists.
|
||||
|
|
|
@ -48,6 +48,55 @@ namespace MWWorld
|
|||
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)
|
||||
{
|
||||
mPlayer.mBase = player;
|
||||
|
@ -221,6 +270,11 @@ namespace MWWorld
|
|||
|
||||
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);
|
||||
player.save (writer);
|
||||
writer.endRecord (ESM::REC_PLAY);
|
||||
|
@ -241,6 +295,17 @@ namespace MWWorld
|
|||
|
||||
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();
|
||||
|
||||
MWBase::World& world = *MWBase::Environment::get().getWorld();
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
#include "../mwworld/livecellref.hpp"
|
||||
|
||||
#include "../mwmechanics/drawstate.hpp"
|
||||
#include "../mwmechanics/stat.hpp"
|
||||
|
||||
#include <components/esm/loadskil.hpp>
|
||||
#include <components/esm/attr.hpp>
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
|
@ -48,10 +52,18 @@ namespace MWWorld
|
|||
int mCurrentCrimeId; // the id assigned witnesses
|
||||
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:
|
||||
|
||||
Player(const ESM::NPC *player, const MWBase::World& world);
|
||||
|
||||
void saveSkillsAttributes();
|
||||
void restoreSkillsAttributes();
|
||||
void setWerewolfSkillsAttributes();
|
||||
|
||||
// For mark/recall magic effects
|
||||
void markPosition (CellStore* markedCell, ESM::Position markedPosition);
|
||||
void getMarkedPosition (CellStore*& markedCell, ESM::Position& markedPosition) const;
|
||||
|
|
|
@ -2432,6 +2432,17 @@ namespace MWWorld
|
|||
if (npcStats.isWerewolf() == werewolf)
|
||||
return;
|
||||
|
||||
if (actor == getPlayerPtr())
|
||||
{
|
||||
if (werewolf)
|
||||
{
|
||||
mPlayer->saveSkillsAttributes();
|
||||
mPlayer->setWerewolfSkillsAttributes();
|
||||
}
|
||||
else
|
||||
mPlayer->restoreSkillsAttributes();
|
||||
}
|
||||
|
||||
npcStats.setWerewolf(werewolf);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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
|
||||
// slightly.
|
||||
void ESMReader::getSubName()
|
||||
|
|
|
@ -183,6 +183,8 @@ public:
|
|||
*/
|
||||
bool isNextSub(const char* name);
|
||||
|
||||
bool peekNextSub(const char* name);
|
||||
|
||||
// Read subrecord name. This gets called a LOT, so I've optimized it
|
||||
// slightly.
|
||||
void getSubName();
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
#include "npcstats.hpp"
|
||||
|
||||
#include "esmreader.hpp"
|
||||
|
@ -31,18 +30,43 @@ void ESM::NpcStats::load (ESMReader &esm)
|
|||
esm.getHNOT (mDisposition, "DISP");
|
||||
|
||||
for (int i=0; i<27; ++i)
|
||||
mSkills[i].load (esm);
|
||||
|
||||
if (esm.peekNextSub("STBA"))
|
||||
{
|
||||
mSkills[i].mRegular.load (esm);
|
||||
mSkills[i].mWerewolf.load (esm);
|
||||
// we have deprecated werewolf skills, stored interleaved
|
||||
// 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;
|
||||
esm.getHNOT (hasWerewolfAttributes, "HWAT");
|
||||
|
||||
if (hasWerewolfAttributes)
|
||||
{
|
||||
ESM::StatState<int> dummy;
|
||||
for (int i=0; i<8; ++i)
|
||||
mWerewolfAttributes[i].load (esm);
|
||||
dummy.load(esm);
|
||||
mWerewolfDeprecatedData = true;
|
||||
}
|
||||
|
||||
mIsWerewolf = false;
|
||||
|
@ -112,14 +136,7 @@ void ESM::NpcStats::save (ESMWriter &esm) const
|
|||
esm.writeHNT ("DISP", mDisposition);
|
||||
|
||||
for (int i=0; i<27; ++i)
|
||||
{
|
||||
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);
|
||||
mSkills[i].save (esm);
|
||||
|
||||
if (mIsWerewolf)
|
||||
esm.writeHNT ("WOLF", mIsWerewolf);
|
||||
|
@ -151,6 +168,7 @@ void ESM::NpcStats::save (ESMWriter &esm) const
|
|||
|
||||
void ESM::NpcStats::blank()
|
||||
{
|
||||
mWerewolfDeprecatedData = false;
|
||||
mIsWerewolf = false;
|
||||
mDisposition = 0;
|
||||
mBounty = 0;
|
||||
|
|
|
@ -16,12 +16,6 @@ namespace ESM
|
|||
|
||||
struct NpcStats
|
||||
{
|
||||
struct Skill
|
||||
{
|
||||
StatState<int> mRegular;
|
||||
StatState<int> mWerewolf;
|
||||
};
|
||||
|
||||
struct Faction
|
||||
{
|
||||
bool mExpelled;
|
||||
|
@ -31,12 +25,13 @@ namespace ESM
|
|||
Faction();
|
||||
};
|
||||
|
||||
StatState<int> mWerewolfAttributes[8];
|
||||
bool mIsWerewolf;
|
||||
|
||||
bool mWerewolfDeprecatedData;
|
||||
|
||||
std::map<std::string, Faction> mFactions; // lower case IDs
|
||||
int mDisposition;
|
||||
Skill mSkills[27];
|
||||
StatState<int> mSkills[27];
|
||||
int mBounty;
|
||||
int mReputation;
|
||||
int mWerewolfKills;
|
||||
|
|
|
@ -31,6 +31,14 @@ void ESM::Player::load (ESMReader &esm)
|
|||
esm.getHNOT (mCurrentCrimeId, "CURD");
|
||||
mPaidCrimeId = -1;
|
||||
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
|
||||
|
@ -54,4 +62,9 @@ void ESM::Player::save (ESMWriter &esm) const
|
|||
|
||||
esm.writeHNT ("CURD", mCurrentCrimeId);
|
||||
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 "defs.hpp"
|
||||
|
||||
#include "loadskil.hpp"
|
||||
#include "attr.hpp"
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
class ESMReader;
|
||||
|
@ -28,6 +31,9 @@ namespace ESM
|
|||
int mCurrentCrimeId;
|
||||
int mPaidCrimeId;
|
||||
|
||||
StatState<int> mSaveAttributes[ESM::Attribute::Length];
|
||||
StatState<int> mSaveSkills[ESM::Skill::Length];
|
||||
|
||||
void load (ESMReader &esm);
|
||||
void save (ESMWriter &esm) const;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue