mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-26 14:56:39 +00:00 
			
		
		
		
	Merge branch 'master' of https://github.com/OpenMW/openmw into osg
Conflicts: apps/opencs/CMakeLists.txt apps/opencs/main.cpp apps/openmw/mwworld/player.hpp
This commit is contained in:
		
						commit
						a5670b5133
					
				
					 67 changed files with 1069 additions and 250 deletions
				
			
		|  | @ -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